From 9828cf2cbc20252f3edcacba6ed11e9f7186c802 Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Fri, 30 Oct 2026 11:52:07 +0100 Subject: [PATCH 01/14] fix: 0.4.1 - baggrundsboksen lover ikke at kodeordsprogrammer spoerger (C19), stille-vej giver scroll et punkt, LICENSE med i pakken MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - policy.js:623: i baggrund afvises adgangskode-programmer (maaIkke) - boksen sagde «still always ask». :632 (forgrund) er sand. ikon-godkend D2 fanger loeftet; mutationsbevist (gammel tekst -> 1 DUMPET, ny -> 60 OK). - stille-vej.mjs:293: hjaelperen kraever et punkt sammen med --app siden ed09c85 (main.swift:1020) - midten af forreste vindue, som index.js:1325-1328. Gjorde Fremmed Mac roed paa 0.4. - mcp-server/LICENSE + "LICENSE" i files: MIT-teksten fulgte hverken npm- eller MCPB-pakken. Co-Authored-By: Claude Opus 5.5 --- mcp-server/LICENSE | 21 +++++++++++++++++++++ mcp-server/policy.js | 3 ++- test/ikon-godkend.mjs | 1 + test/stille-vej.mjs | 6 +++++- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 mcp-server/LICENSE diff --git a/mcp-server/LICENSE b/mcp-server/LICENSE new file mode 100644 index 00000000..d5cab333 --- /dev/null +++ b/mcp-server/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Agent360 Group ApS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mcp-server/policy.js b/mcp-server/policy.js index 788b3572..86efef63 100644 --- a/mcp-server/policy.js +++ b/mcp-server/policy.js @@ -620,7 +620,8 @@ export async function decide({ tier, targetBundleId, describe, alwaysAsk = false if (sessionGranted) return { allow: true, reason: 'this session already has consent', asked: false }; if (baggrund()) { - const v = await viaIkonet({ omfang: 'If you allow it, the agent may click and type for the rest of this session. Password apps still always ask.' }); + // 0.4.1 (C19, panel R1 24/10): i baggrund afvises adgangskode-programmer (maaIkke) - de spoerger ikke. :631 (forgrund) er sand. + const v = await viaIkonet({ omfang: 'If you allow it, the agent may click and type for the rest of this session. Password apps stay refused while it works in the background.' }); if (v.allow) sessionGranted = true; return v; } diff --git a/test/ikon-godkend.mjs b/test/ikon-godkend.mjs index f7bab639..75b1f266 100644 --- a/test/ikon-godkend.mjs +++ b/test/ikon-godkend.mjs @@ -419,6 +419,7 @@ const d2a = await D2.rpc('tools/call', { name: 'computer_type', arguments: { app const d2b = await D2.rpc('tools/call', { name: 'computer_type', arguments: { app: 'Finder', text: 'def' } }); check('D2 ask: foerste skrivning godkendt fra ikonet', !d2a.result.isError, d2a.result.content[0].text.slice(0, 70)); check('D2 ...ikonet fik omfanget «resten af sessionen»', /rest of this session/.test(ikonD.modtaget[foerD2]?.scope || ''), ikonD.modtaget[foerD2]?.scope); +check('D2 ...og omfanget lover ikke at adgangskode-programmer spoerger (i baggrund afvises de, policy.js maaIkke)', !/password (apps?|managers?)[^.]*\b(always\s+)?asks?\b/i.test(ikonD.modtaget[foerD2]?.scope || '') && /refused/i.test(ikonD.modtaget[foerD2]?.scope || ''), ikonD.modtaget[foerD2]?.scope); check('D2 ...og anden skrivning spurgte ikke igen', !d2b.result.isError && ikonD.modtaget.length === foerD2 + 1, `${ikonD.modtaget.length - foerD2} spoergsmaal`); D2.srv.kill(); ikonD.srv.close(); process.env.CMCP_MODE = 'allow'; diff --git a/test/stille-vej.mjs b/test/stille-vej.mjs index 696e1b2d..d4ba477c 100644 --- a/test/stille-vej.mjs +++ b/test/stille-vej.mjs @@ -290,7 +290,11 @@ try { if (!FREMMED_MASKINE) { sprang('leverer vi i det program mennesket SIDDER i, indroemmer den det', ROER_GRUND); } else if (forrestNavn) { - const eget = koer('scroll', '--dx', '0', '--dy', '0', '--app', forrestNavn); + // 0.4.1: siden ed09c85 (10/10) kraever hjaelperen et punkt sammen med --app (main.swift:1020) - samme punkt som + // serveren selv giver (index.js:1325-1328): midten af programmets forreste vindue. + const vf = (koer('windows', '--app', forrestNavn).windows || [])[0]?.frame; + const eget = vf ? koer('scroll', '--dx', '0', '--dy', '0', '--app', forrestNavn, '--x', String(vf.x + vf.w / 2), '--y', String(vf.y + vf.h / 2)) + : { took_screen: null, error: `${forrestNavn} har intet vindue at rulle i` }; check('leverer vi i det program mennesket SIDDER i, indroemmer den det', eget.took_screen === true, `${forrestNavn}: ${JSON.stringify(eget)}`); } else { From d411a01e7fb906cea615d3012e8beb10f7c0e9f8 Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Fri, 30 Oct 2026 11:52:08 +0100 Subject: [PATCH 02/14] deps: SDK-gulv ^1.32.1 + laasefilen paa rettede underpakker (npm audit 5 -> 0) SDK'en selv uaendret (1.32.1). zod 4.6.7, body-parser 2.4.0, @hono/node-server 2.1.5, fast-uri 3.1.9, qs 6.17.1 - samme versioner som en frisk npx-installation faar i dag, saa proeverne maaler det brugerne koerer (som f808150). Gulvet holder 1.30.x (1 hoej advarsel) ude af en cachet installation. "LICENSE" i files, saa MCPB-bundtet faar den. Co-Authored-By: Claude Opus 5.5 --- mcp-server/package-lock.json | 40 ++++++++++++++++++------------------ mcp-server/package.json | 3 ++- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json index d96e39ec..c00b0792 100644 --- a/mcp-server/package-lock.json +++ b/mcp-server/package-lock.json @@ -9,7 +9,7 @@ "version": "0.4.0", "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.0" + "@modelcontextprotocol/sdk": "^1.32.1" }, "bin": { "computer-mcp": "bin/cli.js" @@ -19,15 +19,15 @@ } }, "node_modules/@hono/node-server": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.1.tgz", - "integrity": "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.5.tgz", + "integrity": "sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==", "license": "MIT", "engines": { "node": ">=20" }, "peerDependencies": { - "hono": "^4" + "hono": "^4 || ^5.0.0-0" } }, "node_modules/@modelcontextprotocol/sdk": { @@ -117,18 +117,18 @@ } }, "node_modules/body-parser": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", - "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.4.0.tgz", + "integrity": "sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", - "content-type": "^2.0.0", + "content-type": "^2.1.0", "debug": "^4.4.3", "http-errors": "^2.0.1", - "iconv-lite": "^0.7.2", + "iconv-lite": "^0.7.3", "on-finished": "^2.4.1", - "qs": "^6.15.2", + "qs": "^6.16.1", "raw-body": "^3.0.2", "type-is": "^2.1.0" }, @@ -452,9 +452,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz", - "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", "funding": [ { "type": "github", @@ -881,9 +881,9 @@ } }, "node_modules/qs": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", - "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.17.1.tgz", + "integrity": "sha512-jd3COkaKVgGUW+ZHyEHCG9bH7RoaaiWuMgzsIBjUMVjLAaWGWpoUAVwljVvBHxRu/2qEHnadLGZrkutYUBPQJA==", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", @@ -1188,9 +1188,9 @@ "license": "ISC" }, "node_modules/zod": { - "version": "4.6.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.5.tgz", - "integrity": "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==", + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/mcp-server/package.json b/mcp-server/package.json index 993e08b6..21441000 100644 --- a/mcp-server/package.json +++ b/mcp-server/package.json @@ -9,6 +9,7 @@ "computer-mcp": "bin/cli.js" }, "files": [ + "LICENSE", "index.js", "tools.js", "policy.js", @@ -62,6 +63,6 @@ "security" ], "dependencies": { - "@modelcontextprotocol/sdk": "^1.0.0" + "@modelcontextprotocol/sdk": "^1.32.1" } } From e083e0236a76eb67c7b2f764506c8a20848b9d8c Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Fri, 30 Oct 2026 12:06:57 +0100 Subject: [PATCH 03/14] ci: mutationsporten viser halen af en proeve der er roed uden mutation 0.4.1-LISTE #4: baggrund-mus og stop-alle var roede umuteret paa Fremmed Mac (39986282787), men groenne alene lokalt - porten smed outputtet vaek, saa aarsagen kunne ikke ses. Proevet med en roed og en groen attrap-proeve. Co-Authored-By: Claude Opus 5.5 --- .github/mutant-porte.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/mutant-porte.py b/.github/mutant-porte.py index e17a659f..f8ccc593 100644 --- a/.github/mutant-porte.py +++ b/.github/mutant-porte.py @@ -18,10 +18,14 @@ k = subprocess.run(['node', proeve], capture_output=True, text=True, timeout=600, env={**os.environ, 'TMPDIR': tmp + '/'}) groen[proeve] = k.returncode == 0 except subprocess.TimeoutExpired: - groen[proeve] = False + groen[proeve] = False; k = None finally: shutil.rmtree(tmp, ignore_errors=True) - if not groen[proeve]: print(f"::error::proeven {proeve} er ROED uden mutation - dens mutanter er ikke bevist") + if not groen[proeve]: + print(f"::error::proeven {proeve} er ROED uden mutation - dens mutanter er ikke bevist") + # 30/10 (0.4.1-LISTE #4): uden hvorfor kunne ingen se, at baggrund-mus/stop-alle kun var roede her - vis halen. + ud = ((k.stdout or '') + (k.stderr or '')).splitlines() if k else ['timeout efter 600 s'] + print(f"::group::{proeve} umuteret - de sidste linjer"); print('\n'.join(ud[-40:])); print("::endgroup::") for m in MUTANTER: if not groen.get(m['proeve']): fejl.append(f"{m['navn']}: proeven {m['proeve']} er roed uden mutation"); continue From 764b941898d58bca747e5ea6d27e47ccbb3c1a4a Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Fri, 30 Oct 2026 16:05:02 +0100 Subject: [PATCH 04/14] test: stille-vej-kommentaren naevner ikke index.js - tilstand-isoleret laeste den som serverstartende MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fremmed Mac 41045721377: tilstand-isoleret DUMP «stille-vej.mjs» - maaleren kalder en fil serverstartende ved spawn( + index.js, og 9828cf2's kommentar «index.js:1325-1328» udloeste den. Foer: 1 DUMP, efter: alle tjek bestaaet (lokalt). Co-Authored-By: Claude Opus 5.5 --- test/stille-vej.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stille-vej.mjs b/test/stille-vej.mjs index d4ba477c..022b5925 100644 --- a/test/stille-vej.mjs +++ b/test/stille-vej.mjs @@ -291,7 +291,7 @@ try { sprang('leverer vi i det program mennesket SIDDER i, indroemmer den det', ROER_GRUND); } else if (forrestNavn) { // 0.4.1: siden ed09c85 (10/10) kraever hjaelperen et punkt sammen med --app (main.swift:1020) - samme punkt som - // serveren selv giver (index.js:1325-1328): midten af programmets forreste vindue. + // serveren selv giver (computer_scroll i mcp-server, linje 1325-1328): midten af programmets forreste vindue. const vf = (koer('windows', '--app', forrestNavn).windows || [])[0]?.frame; const eget = vf ? koer('scroll', '--dx', '0', '--dy', '0', '--app', forrestNavn, '--x', String(vf.x + vf.w / 2), '--y', String(vf.y + vf.h / 2)) : { took_screen: null, error: `${forrestNavn} har intet vindue at rulle i` }; From f3367cd9dcde29d8cb4ee7818373a3c41d674728 Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sat, 31 Oct 2026 23:36:19 +0100 Subject: [PATCH 05/14] 0.4.1: version og CHANGELOG Versionen 0.4.1 i package.json, server.json (x2), bundle/manifest.json, gemini-extension.json og HELPER_VERSION. README-loggen genereret med scripts/log-uddrag.mjs (test/readme-log.mjs groen). CHANGELOG: samtykketeksten (D2), LICENSE, underpakkerne (audit 5 -> 0), flere agenter paa macOS 15.8 (Finder kom kort frem i 2 af 5 koersler, som forsidens optagelse viser; skrivningen foran holdt i alle) og proeverettelserne. claims-offline + tjek-forside groenne lokalt. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ README.md | 10 +++++----- bundle/manifest.json | 2 +- gemini-extension.json | 2 +- helper/Sources/cmcp-helper/main.swift | 2 +- mcp-server/README.md | 10 +++++----- mcp-server/package-lock.json | 4 ++-- mcp-server/package.json | 2 +- server.json | 4 ++-- test/fixtures/audit-readme.jsonl | 14 +++++++------- 10 files changed, 51 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19c072e1..9f685795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,32 @@ Dates are the day the version was tagged. Everything here was measured before it was written down; where a claim has a test, the test is named. +## 0.4.1 (in progress) + +**The consent box no longer says password apps ask while the agent works in the +background.** In the background they are refused outright, but the box said +"Password apps still always ask". It now says "Password apps stay refused while +it works in the background." The text shown in the foreground was already true. +`test/ikon-godkend.mjs` D2 checks the wording, and fails with the old text. + +**The MIT license ships with the package.** Neither the npm package nor the MCPB +bundle carried `LICENSE`; both do now. + +**Patched dependencies.** The MCP SDK now has to be at least 1.32.1, and the +lockfile uses the patched versions of zod, body-parser, @hono/node-server, +fast-uri and qs - the ones a fresh `npx` install gets today. +`npm audit --omit=dev` went from 5 findings to 0. + +**Several agents at once, on GitHub's macOS 15.8 runner.** In 2 of 5 runs with +10 or 15 agents working in the background, Finder came forward for a moment +during a step that used Finder or the wallpaper setting - the same thing the +recording on the front page shows. It is not fixed in this version. The test +that types in front kept every word in those runs. + +**Tests.** `test/stille-vej.mjs` gives `scroll --app` a point, as 0.4.0's helper +requires; on a foreign Mac that check had failed on 0.4.0. The +mutation gate now prints why a test failed before anything was mutated. + ## 0.4.0 (in progress) **A stop lets go of the mouse button and starts nothing new.** A drag holds the diff --git a/README.md b/README.md index e8a14efd..1b219823 100644 --- a/README.md +++ b/README.md @@ -133,11 +133,11 @@ and that its chain holds. ```jsonl -{"ts":"2026-10-20T18:52:45.701Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"1b330dc3a979","salted":true},"text":{"length":37,"sha256_12":"51f664abcb74","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"e02a3d1b3560ea17"} -{"ts":"2026-10-20T18:52:45.705Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"c1e763106513c3e7"} -{"ts":"2026-10-20T18:52:46.112Z","session":"fabb2663","call":"746fffee","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"b053781eb3511c4d"} -{"ts":"2026-10-20T18:52:47.761Z","session":"fabb2663","call":"88f2d9ae","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"0771e2f86fa0","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.0","icon":"0.4.0","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"9b82d6ae5a36942d"} -{"ts":"2026-10-20T18:52:48.229Z","session":"fabb2663","call":"0ba79155","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"84b5a01fae6a","salted":true},"text":{"length":7,"sha256_12":"b56e1d9fbfd2","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"1be981d7eeaf7445"} +{"ts":"2026-10-31T22:35:10.230Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"78743a52a54c","salted":true},"text":{"length":37,"sha256_12":"cdde26c85cca","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"4fb5f61a6e442962"} +{"ts":"2026-10-31T22:35:10.231Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"13cd03c71bfb3b38"} +{"ts":"2026-10-31T22:35:10.321Z","session":"56f00545","call":"02bc741b","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"79696176e8603981"} +{"ts":"2026-10-31T22:35:11.481Z","session":"56f00545","call":"ac33c074","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"2c65732d0d4e","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.1","icon":"0.4.1","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"ad20dddb1195fa7a"} +{"ts":"2026-10-31T22:35:11.578Z","session":"56f00545","call":"5b15b900","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"ac0afc1b1e97","salted":true},"text":{"length":7,"sha256_12":"f0b579393774","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"2332aa9606dd896e"} ``` diff --git a/bundle/manifest.json b/bundle/manifest.json index e7eb8798..8d2f2313 100644 --- a/bundle/manifest.json +++ b/bundle/manifest.json @@ -2,7 +2,7 @@ "manifest_version": "0.3", "name": "computer-mcp", "display_name": "Computer MCP", - "version": "0.4.0", + "version": "0.4.1", "description": "macOS computer use you can leave running: it stays behind your window and never touches passwords.", "long_description": "A macOS computer-use MCP server built for the hours you are not watching. It acts in windows behind the one you are in and leaves your pointer alone, it says so when something fails, several can run at once, and it will not go near your password manager. Every action is written to an append-only audit log. Runs in any MCP client, macOS, MIT, no account.", "author": { diff --git a/gemini-extension.json b/gemini-extension.json index 6805b233..c78cae35 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "computer-mcp", - "version": "0.4.0", + "version": "0.4.1", "description": "Drive macOS from any MCP client with the guardrails on by default: password fields blacked out in memory before the screenshot is written, password managers that are refused and terminals that ask once per session, and a log the server only appends to that never stores typed text in clear. 32 tools, 14 read-only. No API key, MIT.", "mcpServers": { "computer": { diff --git a/helper/Sources/cmcp-helper/main.swift b/helper/Sources/cmcp-helper/main.swift index 70b6f38f..15ef87d7 100644 --- a/helper/Sources/cmcp-helper/main.swift +++ b/helper/Sources/cmcp-helper/main.swift @@ -22,7 +22,7 @@ func modtager(_ args: Args) -> pid_t? { } -let HELPER_VERSION = "0.4.0" +let HELPER_VERSION = "0.4.1" /// ⛔ 9/10 (F1 paa Gustavs Mac): `--app` blev sammenlignet med programnavne paa /// tyve steder hver for sig (find, vinduer, skaermbilleder, sloering, levering). diff --git a/mcp-server/README.md b/mcp-server/README.md index 5008e47c..4db9f3e3 100644 --- a/mcp-server/README.md +++ b/mcp-server/README.md @@ -131,11 +131,11 @@ and that its chain holds. ```jsonl -{"ts":"2026-10-20T18:52:45.701Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"1b330dc3a979","salted":true},"text":{"length":37,"sha256_12":"51f664abcb74","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"e02a3d1b3560ea17"} -{"ts":"2026-10-20T18:52:45.705Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"c1e763106513c3e7"} -{"ts":"2026-10-20T18:52:46.112Z","session":"fabb2663","call":"746fffee","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"b053781eb3511c4d"} -{"ts":"2026-10-20T18:52:47.761Z","session":"fabb2663","call":"88f2d9ae","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"0771e2f86fa0","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.0","icon":"0.4.0","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"9b82d6ae5a36942d"} -{"ts":"2026-10-20T18:52:48.229Z","session":"fabb2663","call":"0ba79155","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"84b5a01fae6a","salted":true},"text":{"length":7,"sha256_12":"b56e1d9fbfd2","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"1be981d7eeaf7445"} +{"ts":"2026-10-31T22:35:10.230Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"78743a52a54c","salted":true},"text":{"length":37,"sha256_12":"cdde26c85cca","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"4fb5f61a6e442962"} +{"ts":"2026-10-31T22:35:10.231Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"13cd03c71bfb3b38"} +{"ts":"2026-10-31T22:35:10.321Z","session":"56f00545","call":"02bc741b","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"79696176e8603981"} +{"ts":"2026-10-31T22:35:11.481Z","session":"56f00545","call":"ac33c074","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"2c65732d0d4e","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.1","icon":"0.4.1","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"ad20dddb1195fa7a"} +{"ts":"2026-10-31T22:35:11.578Z","session":"56f00545","call":"5b15b900","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"ac0afc1b1e97","salted":true},"text":{"length":7,"sha256_12":"f0b579393774","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"2332aa9606dd896e"} ``` diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json index c00b0792..1ba98a52 100644 --- a/mcp-server/package-lock.json +++ b/mcp-server/package-lock.json @@ -1,12 +1,12 @@ { "name": "@agent360/computer-mcp", - "version": "0.4.0", + "version": "0.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@agent360/computer-mcp", - "version": "0.4.0", + "version": "0.4.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.32.1" diff --git a/mcp-server/package.json b/mcp-server/package.json index 21441000..7379713f 100644 --- a/mcp-server/package.json +++ b/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "@agent360/computer-mcp", - "version": "0.4.0", + "version": "0.4.1", "mcpName": "io.github.Agent360dk/computer-mcp", "description": "Computer use you can actually leave running. It works in windows behind the one you are in and leaves your pointer alone, it says so when something fails instead of pretending, several can run at once, and it will not go near your password manager. Everything is logged. macOS, MIT, no account.", "type": "module", diff --git a/server.json b/server.json index 180e7f63..b60c1a4f 100644 --- a/server.json +++ b/server.json @@ -7,13 +7,13 @@ "url": "https://github.com/Agent360dk/computerMCP", "source": "github" }, - "version": "0.4.0", + "version": "0.4.1", "websiteUrl": "https://computermcp.dev", "packages": [ { "registryType": "npm", "identifier": "@agent360/computer-mcp", - "version": "0.4.0", + "version": "0.4.1", "transport": { "type": "stdio" }, diff --git a/test/fixtures/audit-readme.jsonl b/test/fixtures/audit-readme.jsonl index f40fea94..b3e33785 100644 --- a/test/fixtures/audit-readme.jsonl +++ b/test/fixtures/audit-readme.jsonl @@ -1,7 +1,7 @@ -{"ts":"2026-10-20T18:52:44.507Z","session":"fabb2663","call":"13634812","tool":"computer_apps","tier":"read","args":{},"target":null,"mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"read-only action","l":1,"kaede":"ad0c114e049b146c"} -{"ts":"2026-10-20T18:52:45.180Z","session":"fabb2663","call":"13634812","tool":"computer_apps","outcome":"ok","l":1,"kaede":"3028db917a702ec3"} -{"ts":"2026-10-20T18:52:45.701Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"1b330dc3a979","salted":true},"text":{"length":37,"sha256_12":"51f664abcb74","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"e02a3d1b3560ea17"} -{"ts":"2026-10-20T18:52:45.705Z","session":"fabb2663","call":"746fffee","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"c1e763106513c3e7"} -{"ts":"2026-10-20T18:52:46.112Z","session":"fabb2663","call":"746fffee","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"b053781eb3511c4d"} -{"ts":"2026-10-20T18:52:47.761Z","session":"fabb2663","call":"88f2d9ae","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"0771e2f86fa0","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.0","icon":"0.4.0","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"9b82d6ae5a36942d"} -{"ts":"2026-10-20T18:52:48.229Z","session":"fabb2663","call":"0ba79155","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"84b5a01fae6a","salted":true},"text":{"length":7,"sha256_12":"b56e1d9fbfd2","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"1be981d7eeaf7445"} +{"ts":"2026-10-31T22:35:09.449Z","session":"56f00545","call":"7fb6f0ce","tool":"computer_apps","tier":"read","args":{},"target":null,"mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"read-only action","l":1,"kaede":"97f43c51a40454c5"} +{"ts":"2026-10-31T22:35:10.129Z","session":"56f00545","call":"7fb6f0ce","tool":"computer_apps","outcome":"ok","l":1,"kaede":"f547259cf8faa803"} +{"ts":"2026-10-31T22:35:10.230Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","args":{"app":{"length":8,"sha256_12":"78743a52a54c","salted":true},"text":{"length":37,"sha256_12":"cdde26c85cca","salted":true}},"target":"com.apple.TextEdit","mode":"allow","asker":"custom","decision":"allowed","asked":false,"reason":"CMCP_MODE=allow","l":1,"kaede":"4fb5f61a6e442962"} +{"ts":"2026-10-31T22:35:10.231Z","session":"56f00545","call":"02bc741b","tool":"computer_type","tier":"write","target":"com.apple.TextEdit","phase":"executing","l":1,"kaede":"13cd03c71bfb3b38"} +{"ts":"2026-10-31T22:35:10.321Z","session":"56f00545","call":"02bc741b","tool":"computer_type","outcome":"ok","effect":"sent","l":1,"kaede":"79696176e8603981"} +{"ts":"2026-10-31T22:35:11.481Z","session":"56f00545","call":"ac33c074","tool":"computer_menu","tier":"write","args":{"app":{"length":6,"sha256_12":"2c65732d0d4e","salted":true},"path":"File > Move to Trash"},"target":"com.apple.finder","mode":"allow","asker":"menubar","presence":{"idle_at_ask":600,"idle_at_end":600,"server":"0.4.1","icon":"0.4.1","box":"on","sessions":1,"surface_derived":"box+menu"},"decision":"denied","asked":true,"reason":"background mode: nobody answered in the menu bar in time","l":1,"kaede":"ad20dddb1195fa7a"} +{"ts":"2026-10-31T22:35:11.578Z","session":"56f00545","call":"5b15b900","tool":"computer_type","tier":"write","args":{"app":{"length":9,"sha256_12":"ac0afc1b1e97","salted":true},"text":{"length":7,"sha256_12":"f0b579393774","salted":true}},"target":"com.1password.1password","mode":"allow","asker":"custom","decision":"denied","asked":false,"reason":"background mode: this would need a dialog, and a dialog takes the screen (a password app can never be approved from the menu bar)","l":1,"kaede":"2332aa9606dd896e"} From 187f60b62ce2f0f4e7fe2ac7982e9ae318d910be Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:05:10 +0100 Subject: [PATCH 06/14] test/ci: vaernet mod fejltilskrivning ogsaa paa GitHubs Mac, release.sh ser 100 CI-koersler, laasefilen = en frisk npx-installation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panel R1 1/11 (Astra + Opus, efterproevet): - parallel.mjs: menneskeArbejder var EGEN, saa paa GitHubs Mac fik et rent laesende scenarie skylden for Finder-momentet (41128683401: «101 laese Finder 1», kun computer_windows + computer_find, Finder foer -> TextEdit efter). - release.sh:163 saa kun de seneste 20 CI-koersler; 627b710 er nr. 7 - 13 koersler paa en anden gren afviste udgivelsen. - package-lock.json = en frisk opløsning af package.json i dag (SDK 1.32.2, express 5.3.0 ...): npx har ingen laasefil, saa proeverne skal koere det brugerne faar. npm audit --omit=dev: 0. Co-Authored-By: Claude Opus 5.5 --- mcp-server/package-lock.json | 87 ++++++++++++++++++++++-------------- scripts/release.sh | 2 +- test/parallel.mjs | 4 +- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/mcp-server/package-lock.json b/mcp-server/package-lock.json index 1ba98a52..91af9a44 100644 --- a/mcp-server/package-lock.json +++ b/mcp-server/package-lock.json @@ -31,9 +31,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz", - "integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==", + "version": "1.32.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.2.tgz", + "integrity": "sha512-SWsVtH/0vULSQStoZ6xxH2K09Li8fXYTMC64ZeogCdpZ3XSi1eCPOByV1OpuJxuI3OcmHhosDWYyii07tpPsLw==", "license": "MIT", "dependencies": { "@hono/node-server": "^1.19.9 || ^2.0.5", @@ -192,9 +192,9 @@ } }, "node_modules/content-disposition": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", - "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-2.0.1.tgz", + "integrity": "sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==", "license": "MIT", "engines": { "node": ">=18" @@ -309,12 +309,16 @@ "license": "MIT" }, "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.1.tgz", + "integrity": "sha512-Ev/hIyePLZtpL98x562lvPtenrUfGr0lfaf44HFZ+hDEwso7ccV9QAZrEVLg0hxNAzygaAFxy2dYaAKKM0G06A==", "license": "MIT", "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/es-define-property": { @@ -384,15 +388,15 @@ } }, "node_modules/express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.3.0.tgz", + "integrity": "sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", + "body-parser": "^2.3.0", + "content-disposition": "^2.0.1", + "content-type": "^2.0.0", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", @@ -408,14 +412,14 @@ "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", + "proxy-addr": "^2.0.8", + "qs": "^6.16.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", - "type-is": "^2.0.1", + "type-is": "^2.1.0", "vary": "^1.1.2" }, "engines": { @@ -427,9 +431,9 @@ } }, "node_modules/express-rate-limit": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz", - "integrity": "sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==", + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.2.tgz", + "integrity": "sha512-U1ScocxDD9WI09LaBVypvNkOtNR5yWAmZLkuKJdAzIchA4YKFYF6GT5IKER7epG58oXtjvGlV0/6ii0F83EyZg==", "license": "MIT", "dependencies": { "debug": "^4.4.3", @@ -445,6 +449,19 @@ "express": ">= 4.11" } }, + "node_modules/express/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -589,9 +606,9 @@ } }, "node_modules/hono": { - "version": "4.13.13", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.13.tgz", - "integrity": "sha512-CQ46U0ZkAGmbT/4UxdzzGJpacP2IeKgY4a5/tOI9AABbpOMfK739wfDXmv1usCk+3RkKj1hQy4/fjhiwa2xlrA==", + "version": "4.13.15", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.15.tgz", + "integrity": "sha512-BTUf5VVhV+eb9owxdzdfQBV6b7Uvh7oDPMMHOmpa9hRe9/fKUI5b3TsGiDro2R3hPl3cPT5FuGmb32H3MqReug==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -640,9 +657,9 @@ "license": "ISC" }, "node_modules/ip-address": { - "version": "10.7.4", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.4.tgz", - "integrity": "sha512-DWBMKyeM25D70nrIiTkgQth59/G+naKOTep6huF9j+GmeK3DMD60Zvxg5d5qQnz+38AHgou6ean2LECX+lrKDg==", + "version": "10.7.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.5.tgz", + "integrity": "sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==", "license": "MIT", "engines": { "node": ">= 12" @@ -670,9 +687,9 @@ "license": "ISC" }, "node_modules/jose": { - "version": "6.2.12", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", - "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==", + "version": "6.2.14", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.14.tgz", + "integrity": "sha512-3JasLuki1NRLQvY4wCoC37KZk4qxoBx2k2aFqLxT84IezqW0bkJKnNtxnZj/Fu1xsQivoc/lytxaRHJoGLjJ1A==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -806,15 +823,19 @@ } }, "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.2.tgz", + "integrity": "sha512-ATWUv387i+nLD49EiDoOft5scf32Vsdz3ktrQJG9bi7jRFmaXTssvyvj1EmeKVVgvesbqUtvQQvaS2TpTukAZQ==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/once": { diff --git a/scripts/release.sh b/scripts/release.sh index 21d6efba..666f7aa1 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -160,7 +160,7 @@ echo "== 2b/7 CI skal vaere groen paa den commit der udgives ==" HEADSHA=$(git rev-parse HEAD) # ⛔ 7/10 (panel R8, E): en fejlet forespoergsel (net, GitHub-timeout) blev under # set -e enten et tavst stop eller laest som «CI har ikke koert». Den er UKENDT. -if ! CIDOM=$(gh run list -R Agent360dk/computerMCP -w CI --limit 20 \ +if ! CIDOM=$(gh run list -R Agent360dk/computerMCP -w CI --limit 100 \ --json headSha,conclusion,status \ -q "[.[] | select(.headSha==\"$HEADSHA\")] | .[0].conclusion" 2>/dev/null); then echo "⛔ CI-status kunne ikke laeses fra GitHub (net eller timeout) - den er UKENDT, ikke «ikke koert»." diff --git a/test/parallel.mjs b/test/parallel.mjs index 8967e699..6092f15f 100644 --- a/test/parallel.mjs +++ b/test/parallel.mjs @@ -194,7 +194,9 @@ for (const n of NIVEAUER) { const t0 = Date.now(); // Én delt state-mappe pr. runde: programlaas og revisionskaede deles, som paa en rigtig Mac. const delt = mkdtempSync(join(tmpdir(), 'cmcp-parallel-state-')); - const res = await Promise.all(hold.map(s => koerScenarie(s, { film: false, menneskeArbejder: EGEN, stateDir: delt }))); + // 1/11 (panel R1, Opus): paa GitHubs Mac skriver en proeve ogsaa i TextEdit, saa et skift TILBAGE til TextEdit er + // menneskets program, ikke scenariets. Uden vaernet fik et rent laesende scenarie skylden for Finder-momentet. + const res = await Promise.all(hold.map(s => koerScenarie(s, { film: false, menneskeArbejder: FREMMED || EGEN, stateDir: delt }))); const sek = ((Date.now() - t0) / 1000).toFixed(1); await vent(2500); // et program kan hente sig selv frem sekunder efter (Kontakter, 27/9) const maaling = await vagt.stop(); From ebf174256ab1df171dca4e7054ae3f3423ea05fc Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:05:10 +0100 Subject: [PATCH 07/14] 0.4.1: CHANGELOG efter panel R1 + installationssiderne siger 0.4.1 (sync-tal.py) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Underpakker: beskriver vores laasefil, ikke brugerens (npx opløser selv; de 5 fund var kun i vores trae). - Flere agenter: Finder kommer frem to gange paa hvert niveau i alle seks koersler, 15.7 og 15.8, op til 2,8 s - ikke «2 af 5». - LICENSE: npm maalt, MCPB via samme filliste. Mutationsporten «viser de sidste linjer», ikke «hvorfor». - Rettet: 0.2.1-saetningen «Password managers ask every single time, in every mode». Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 47 ++++++++++++++------- docs/docs/install-claude-code/index.html | 2 +- docs/docs/install-claude-desktop/index.html | 2 +- docs/docs/install-codex/index.html | 2 +- docs/docs/install-copilot/index.html | 2 +- docs/docs/install-cursor/index.html | 2 +- docs/docs/install-vscode/index.html | 2 +- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f685795..b42f3904 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,23 +11,37 @@ background.** In the background they are refused outright, but the box said it works in the background." The text shown in the foreground was already true. `test/ikon-godkend.mjs` D2 checks the wording, and fails with the old text. -**The MIT license ships with the package.** Neither the npm package nor the MCPB -bundle carried `LICENSE`; both do now. - -**Patched dependencies.** The MCP SDK now has to be at least 1.32.1, and the -lockfile uses the patched versions of zod, body-parser, @hono/node-server, -fast-uri and qs - the ones a fresh `npx` install gets today. -`npm audit --omit=dev` went from 5 findings to 0. - -**Several agents at once, on GitHub's macOS 15.8 runner.** In 2 of 5 runs with -10 or 15 agents working in the background, Finder came forward for a moment -during a step that used Finder or the wallpaper setting - the same thing the -recording on the front page shows. It is not fixed in this version. The test -that types in front kept every word in those runs. +**The MIT license ships with the package.** The npm package did not carry +`LICENSE`; it does now (`npm pack` lists it), and the MCPB bundle copies the same +file list. + +**The tests run the dependencies an `npx` user gets.** An `npx` install has no +lockfile and resolves the newest versions in range - today MCP SDK 1.32.2, with +no `npm audit` findings. Our lockfile, which the tests and the MCPB bundle +install from, was older: SDK 1.32.1 and five audit findings (zod, body-parser, +@hono/node-server, fast-uri, qs). It is now the same set a fresh install +resolves. The SDK also has to be at least 1.32.1. + +**Several agents at once.** In the test where 5, 10 and 15 agents work in the +background while another test types into TextEdit, an agent that opens a Finder +window brings Finder forward for a moment, twice at every level, and the front +is handed straight back - the longest such moment measured was 2.8 seconds. It +happened in all six runs on GitHub's Mac, on macOS 15.7 and 15.8 alike, and the +recording on the front page shows the same thing. It is not fixed in this +version. Every word the typing test sent into TextEdit was verified by the +helper (2,663 of 2,663); whether keys typed by hand during such a moment land in +Finder is not measured. The test used to blame whichever agent happened to +start during the moment - even one that only reads - and now judges it on +GitHub's Mac the way it already did on a person's own Mac. **Tests.** `test/stille-vej.mjs` gives `scroll --app` a point, as 0.4.0's helper -requires; on a foreign Mac that check had failed on 0.4.0. The -mutation gate now prints why a test failed before anything was mutated. +requires; on a foreign Mac that check had failed on 0.4.0. The mutation gate now +prints the last lines of a test that fails before anything is mutated. +`scripts/release.sh` looks for the CI run in the last 100 runs, not 20. + +**Corrected.** The 0.2.1 notes below said "Password managers ask every single +time, in every mode." In background mode they are refused, not asked; in the +foreground they ask every time. ## 0.4.0 (in progress) @@ -473,7 +487,8 @@ that it is leaving and the helper finishes the file on its own. A server killed anything. Needs macOS 15. **Consent, as it actually works.** `allow` is the default, so an agent can be -left running. Password managers ask every single time, in every mode. Terminals +left running. Password managers ask every single time, in every mode (corrected +in 0.4.1: in background mode they are refused). Terminals and editors ask once per app per session. Quitting, closing a window, switching Space and destructive-looking menu items ask every time. Several pages said otherwise; they now match the code, and a test derives the forbidden phrasings diff --git a/docs/docs/install-claude-code/index.html b/docs/docs/install-claude-code/index.html index 72f0a00b..53b6b42c 100644 --- a/docs/docs/install-claude-code/index.html +++ b/docs/docs/install-claude-code/index.html @@ -182,7 +182,7 @@

Install Computer MCP for Claude Code

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

diff --git a/docs/docs/install-claude-desktop/index.html b/docs/docs/install-claude-desktop/index.html index ff9754e6..ca07cb9f 100644 --- a/docs/docs/install-claude-desktop/index.html +++ b/docs/docs/install-claude-desktop/index.html @@ -182,7 +182,7 @@

Install Computer MCP for Claude Desktop

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

diff --git a/docs/docs/install-codex/index.html b/docs/docs/install-codex/index.html index a1c7638e..49cd6302 100644 --- a/docs/docs/install-codex/index.html +++ b/docs/docs/install-codex/index.html @@ -182,7 +182,7 @@

Install Computer MCP for OpenAI Codex

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

diff --git a/docs/docs/install-copilot/index.html b/docs/docs/install-copilot/index.html index 17d2856d..ead17a43 100644 --- a/docs/docs/install-copilot/index.html +++ b/docs/docs/install-copilot/index.html @@ -182,7 +182,7 @@

Install Computer MCP for GitHub Copilot

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

diff --git a/docs/docs/install-cursor/index.html b/docs/docs/install-cursor/index.html index dd68e070..fbb5335e 100644 --- a/docs/docs/install-cursor/index.html +++ b/docs/docs/install-cursor/index.html @@ -182,7 +182,7 @@

Install Computer MCP for Cursor

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

diff --git a/docs/docs/install-vscode/index.html b/docs/docs/install-vscode/index.html index 6a3cc578..95a3e983 100644 --- a/docs/docs/install-vscode/index.html +++ b/docs/docs/install-vscode/index.html @@ -182,7 +182,7 @@

Install Computer MCP for VS Code

access, window control, moving windows between screens, pasting, opening and quitting apps, waiting for something to appear, writing into a field behind another window, and asking you for a password without the model ever seeing it. -Those ship with 0.4.0, which is built and tested but not published yet.

+Those ship with 0.4.1, which is built and tested but not published yet.

Everything else on this page works with what you install today. If you want all of them now, build from source: about thirty-five seconds, and nothing to download.

From 8d851c2f9232cfc9ae25b5f0e7361bb5c41107ad Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:44:15 +0100 Subject: [PATCH 08/14] =?UTF-8?q?ci:=20fremmed-mac=20-=20=C2=ABMange=20age?= =?UTF-8?q?nter=C2=BB=20faar=2060=20min,=20og=20mutationsporten=20starter?= =?UTF-8?q?=20med=20Script=20Editor=20forrest=20som=20suiten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panel R2 1/11: et svar der aldrig kom braendte 5,5 t (41077418047 forsoeg 1). baggrund-mus bestaar i suiten (Script Editor forrest) men ikke i portens baseline (Finder forrest efter «Mange agenter»): samme udgangspunkt afgoer om det er tilstanden. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fremmed-mac.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/fremmed-mac.yml b/.github/workflows/fremmed-mac.yml index 1116c052..134713b9 100644 --- a/.github/workflows/fremmed-mac.yml +++ b/.github/workflows/fremmed-mac.yml @@ -167,6 +167,8 @@ jobs: - name: Mange agenter samtidig id: par continue-on-error: true + # 1/11 (panel R2): et svar der aldrig kom, brændte 5,5 t af jobbets 6 (41077418047 forsøg 1) - porten naaede aldrig at skrive. + timeout-minutes: 60 run: | killall Chess Calculator Contacts "System Settings" "Activity Monitor" Notes Safari "Script Editor" 2>/dev/null || true CMCP_FILM="$RUNNER_TEMP/film" CMCP_PARALLEL_RAPPORT="$RUNNER_TEMP/parallel.json" node test/parallel.mjs @@ -223,6 +225,9 @@ jobs: # skal kunne blive roed. bash -e: uden «|| rc» stoppede trinnet ved foerste. run: | rc=0 + # 1/11 (panel R2): «Mange agenter» lukker Script Editor og TextEdit, saa Finder staar forrest her; i suiten + # (Script Editor forrest) bestaar baggrund-mus, i portens baseline ikke. Samme udgangspunkt som suiten. + open -a "Script Editor"; sleep 4 bash .github/mutant-giv-tilbage.sh || rc=1 python3 .github/mutant-porte.py || rc=1 exit $rc From 1003f8987d41e520fe4299c40b9061f51bf173ce Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:44:15 +0100 Subject: [PATCH 09/14] 0.4.1: teksterne efter panel R2 - give-back virker ikke altid, laasefilen dateret, kendte graenser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README/npm-README/forside/kapabilitetsmatrix: «handed straight back» faar maalingen med: 1 af 65 momenter (41266330474) kunne ikke gives tilbage, svaret sagde gave_back:false. - CHANGELOG: hovedet lovede datoer der ikke staar der; laasefilen beskrevet som fornyet 1/11 (ikke varig lighed med npx); mange agenter med alle fire udfald; kendte graenser: baggrund-mus/38 mutanter, F2b 3 af 11 (F2 bestod i alle). Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 35 ++++++++++++++++++-------- README.md | 8 +++--- docs/docs/capability-matrix/index.html | 2 +- docs/index.html | 2 +- mcp-server/README.md | 8 +++--- 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b42f3904..cbf58e7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog -Dates are the day the version was tagged. Everything here was measured before it -was written down; where a claim has a test, the test is named. +Newest first. Where a claim has a test, the test is named; what is not measured +says so. ## 0.4.1 (in progress) @@ -15,20 +15,25 @@ it works in the background." The text shown in the foreground was already true. `LICENSE`; it does now (`npm pack` lists it), and the MCPB bundle copies the same file list. -**The tests run the dependencies an `npx` user gets.** An `npx` install has no -lockfile and resolves the newest versions in range - today MCP SDK 1.32.2, with -no `npm audit` findings. Our lockfile, which the tests and the MCPB bundle -install from, was older: SDK 1.32.1 and five audit findings (zod, body-parser, -@hono/node-server, fast-uri, qs). It is now the same set a fresh install -resolves. The SDK also has to be at least 1.32.1. +**The lockfile was renewed on 1 November.** An `npx` install has no lockfile and +resolves the newest versions in range; on 1 November that was MCP SDK 1.32.2, +with no `npm audit` findings. 0.4.0's lockfile, which the tests and the MCPB +bundle install from, had SDK 1.32.1 and five audit findings (zod, body-parser, +@hono/node-server, fast-uri, qs). It was replaced that day by a fresh +resolution of this version's `package.json`; newer releases in range can +appear after it. The SDK also has to be at least 1.32.1. **Several agents at once.** In the test where 5, 10 and 15 agents work in the background while another test types into TextEdit, an agent that opens a Finder window brings Finder forward for a moment, twice at every level, and the front is handed straight back - the longest such moment measured was 2.8 seconds. It -happened in all six runs on GitHub's Mac, on macOS 15.7 and 15.8 alike, and the -recording on the front page shows the same thing. It is not fixed in this -version. Every word the typing test sent into TextEdit was verified by the +happened in all six completed runs on GitHub's Mac counted for this note, on +macOS 15.7 and 15.8 alike, and the recording on the front page shows the same +thing. In one of 65 such moments across eleven runs the front could not be +handed back: Finder stayed in front, and the reply said so (`gave_back: +false`). Under load an agent can also stop and wait when it cannot tell which +app the person is in - it then does nothing - and one run hung until GitHub's +time limit. None of this is fixed in this version. Every word the typing test sent into TextEdit was verified by the helper (2,663 of 2,663); whether keys typed by hand during such a moment land in Finder is not measured. The test used to blame whichever agent happened to start during the moment - even one that only reads - and now judges it on @@ -39,6 +44,14 @@ requires; on a foreign Mac that check had failed on 0.4.0. The mutation gate now prints the last lines of a test that fails before anything is mutated. `scripts/release.sh` looks for the CI run in the last 100 runs, not 20. +**Known limits found while measuring 0.4.1.** In the mutation gate on GitHub's +Mac, `test/baggrund-mus.mjs` runs after the many-agents test, with Finder in +front; there a menu opened by a click behind was not closed again +(`menu_closed: false` in the reply), though the same test passes in the suite. +Its 38 mutants are therefore not proven on a foreign Mac. The check that the +helper process ends within 500 ms of a stop failed in 3 of 11 runs (524-546 ms), +on 0.4.0 and 0.4.1 alike; the mouse button was released in all of them (F2). + **Corrected.** The 0.2.1 notes below said "Password managers ask every single time, in every mode." In background mode they are refused, not asked; in the foreground they ask every time. diff --git a/README.md b/README.md index 1b219823..0b8400f6 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ in the hours you are not watching. - **It does not take over your Mac.** It presses buttons and fills fields in windows that stay behind the one you are in, and it leaves your pointer where you put it. When an app pulls itself to the front as it opens, the front is - handed straight back and the reply says so - nothing is left stealing what you - are typing. + handed straight back and the reply says so. In one of 65 measured moments like + it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: + false`): until you click back, what you type goes to that app. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. @@ -237,7 +238,8 @@ the same way - including when the call failed halfway, because a half-done write that took the screen must not be the one line that stays silent. `press` and `menu` carry it too: an app can bring itself forward in response (measured: File > New Finder Window did), and when it does, the answer says so -and the front is handed straight back to the app you were in (`gave_back`). +and the front is handed straight back to the app you were in - `gave_back` +says whether that worked. `set_value`, `drag`, `paste` and `move` do not carry the field yet. `computer_launch` joins them with `background: true`: the app starts behind diff --git a/docs/docs/capability-matrix/index.html b/docs/docs/capability-matrix/index.html index 5a709556..bd014bc0 100644 --- a/docs/docs/capability-matrix/index.html +++ b/docs/docs/capability-matrix/index.html @@ -221,7 +221,7 @@

Walls we clear partly, and say so

- + diff --git a/docs/index.html b/docs/index.html index bf272930..d267710b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -751,7 +751,7 @@

Install in two minutes

Have your agent run computer_permissions. It tells you what is missing.

Want to look before it can touch? Start it with CMCP_MODE=readonly. No tool takes - your screen by default; CMCP_BACKGROUND=0 adds the seven that do. An app that pulls itself forward is handed back, and the reply says so. + your screen by default; CMCP_BACKGROUND=0 adds the seven that do. An app that pulls itself forward is handed back, and the reply says whether that worked. Guides: Claude Code, Codex, Cursor, Copilot, Claude Desktop, VS Code.

diff --git a/mcp-server/README.md b/mcp-server/README.md index 4db9f3e3..6e12ba9a 100644 --- a/mcp-server/README.md +++ b/mcp-server/README.md @@ -11,8 +11,9 @@ in the hours you are not watching. - **It does not take over your Mac.** It presses buttons and fills fields in windows that stay behind the one you are in, and it leaves your pointer where you put it. When an app pulls itself to the front as it opens, the front is - handed straight back and the reply says so - nothing is left stealing what you - are typing. + handed straight back and the reply says so. In one of 65 measured moments like + it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: + false`): until you click back, what you type goes to that app. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. @@ -235,7 +236,8 @@ the same way - including when the call failed halfway, because a half-done write that took the screen must not be the one line that stays silent. `press` and `menu` carry it too: an app can bring itself forward in response (measured: File > New Finder Window did), and when it does, the answer says so -and the front is handed straight back to the app you were in (`gave_back`). +and the front is handed straight back to the app you were in - `gave_back` +says whether that worked. `set_value`, `drag`, `paste` and `move` do not carry the field yet. `computer_launch` joins them with `background: true`: the app starts behind From 3de50a51f5df91d56f6f22310cb679d0ee6aedc0 Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:58:41 +0100 Subject: [PATCH 10/14] ci: fremmed-mac - Script Editor lige foer mutationsporten (ikke foer giv-tilbage-mutanterne), trinfrist 30 min Panel R3 1/11 (Opus): giv-tilbage-mutanterne koerer foer baggrund-mus' baseline og efterlader Finder forrest; i suiten koerer giv-tilbage efter baggrund-mus (run-all.sh:134/140). Kommentaren om haenget rettet (Astra R3): mutationsbeviset blev sprunget over, og slutporten afviste koerslen. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fremmed-mac.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/fremmed-mac.yml b/.github/workflows/fremmed-mac.yml index 134713b9..415c62d7 100644 --- a/.github/workflows/fremmed-mac.yml +++ b/.github/workflows/fremmed-mac.yml @@ -167,8 +167,9 @@ jobs: - name: Mange agenter samtidig id: par continue-on-error: true - # 1/11 (panel R2): et svar der aldrig kom, brændte 5,5 t af jobbets 6 (41077418047 forsøg 1) - porten naaede aldrig at skrive. - timeout-minutes: 60 + # 1/11 (panel R2-R3): parallelproeven hang til jobfristen (41077418047 forsoeg 1); mutationsbeviset blev sprunget + # over, og slutporten afviste koerslen. Et normalt trin tager ~4 min. + timeout-minutes: 30 run: | killall Chess Calculator Contacts "System Settings" "Activity Monitor" Notes Safari "Script Editor" 2>/dev/null || true CMCP_FILM="$RUNNER_TEMP/film" CMCP_PARALLEL_RAPPORT="$RUNNER_TEMP/parallel.json" node test/parallel.mjs @@ -225,10 +226,10 @@ jobs: # skal kunne blive roed. bash -e: uden «|| rc» stoppede trinnet ved foerste. run: | rc=0 - # 1/11 (panel R2): «Mange agenter» lukker Script Editor og TextEdit, saa Finder staar forrest her; i suiten - # (Script Editor forrest) bestaar baggrund-mus, i portens baseline ikke. Samme udgangspunkt som suiten. - open -a "Script Editor"; sleep 4 bash .github/mutant-giv-tilbage.sh || rc=1 + # 1/11 (panel R2-R3): «Mange agenter» og giv-tilbage-mutanterne efterlader Finder forrest; i suiten (Script Editor + # forrest) bestaar baggrund-mus' menu-tjek, i portens baseline ikke. Lige foer porten, saa baggrund-mus starter som i suiten. + open -a "Script Editor"; sleep 4 python3 .github/mutant-porte.py || rc=1 exit $rc From 605c70eb156b10fef3139fb6db4124c9195499fd Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 04:58:41 +0100 Subject: [PATCH 11/14] 0.4.1: teksterne efter panel R3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - «longest such moment» -> «longest one that was handed back» (det ikke-tilbagegivne varede mindst 40 s); elleve koersler hele vejen (32 af 33 niveauer, 4.939/4.939); haenget: aarsag ikke fundet; proeverne navngivet. - Kendte graenser i datid (porten er aendret) og «these menu checks», ikke hele proeven. - README/npm-README: give-back lader forgrunden staa efter klik, rul eller en tast som Shift inden for 1,5 s (Skaerm.swift menneskeRoerteNetop); launch-saetningen og matrixens launch-saetning melder gave_back. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 47 ++++++++++++++------------ README.md | 6 ++-- docs/docs/capability-matrix/index.html | 2 +- mcp-server/README.md | 6 ++-- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbf58e7b..0d44e3d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,34 +23,37 @@ bundle install from, had SDK 1.32.1 and five audit findings (zod, body-parser, resolution of this version's `package.json`; newer releases in range can appear after it. The SDK also has to be at least 1.32.1. -**Several agents at once.** In the test where 5, 10 and 15 agents work in the -background while another test types into TextEdit, an agent that opens a Finder -window brings Finder forward for a moment, twice at every level, and the front -is handed straight back - the longest such moment measured was 2.8 seconds. It -happened in all six completed runs on GitHub's Mac counted for this note, on -macOS 15.7 and 15.8 alike, and the recording on the front page shows the same -thing. In one of 65 such moments across eleven runs the front could not be -handed back: Finder stayed in front, and the reply said so (`gave_back: -false`). Under load an agent can also stop and wait when it cannot tell which -app the person is in - it then does nothing - and one run hung until GitHub's -time limit. None of this is fixed in this version. Every word the typing test sent into TextEdit was verified by the -helper (2,663 of 2,663); whether keys typed by hand during such a moment land in -Finder is not measured. The test used to blame whichever agent happened to -start during the moment - even one that only reads - and now judges it on -GitHub's Mac the way it already did on a person's own Mac. +**Several agents at once.** In `test/parallel.mjs`, 5, 10 and 15 agents work in +the background while another test types into TextEdit. An agent that opens a +Finder window brings Finder forward for a moment, and the front is handed +straight back - the longest one that was handed back lasted 2.8 seconds. In +eleven runs on GitHub's Mac, on macOS 15.7 and 15.8 alike, it happened twice at +32 of 33 levels; the recording on the front page shows the same thing. In one +of 65 such moments the front could not be handed back: Finder stayed in front +for the rest of that round (at least 40 seconds), and the reply said so +(`gave_back: false`). Under load an agent can also stop and wait when it cannot +tell which app the person is in - it then does nothing - and one run hung until +GitHub's time limit; the cause of the hang is not found. None of this is fixed +in this version. Every word the typing test sent into TextEdit was verified by +the helper (4,939 of 4,939 across the eleven runs); whether keys typed by hand +during such a moment land in Finder is not measured. The test used to blame +whichever agent happened to start during the moment - even one that only +reads - and now judges it on GitHub's Mac the way it already did on a person's +own Mac. **Tests.** `test/stille-vej.mjs` gives `scroll --app` a point, as 0.4.0's helper requires; on a foreign Mac that check had failed on 0.4.0. The mutation gate now prints the last lines of a test that fails before anything is mutated. `scripts/release.sh` looks for the CI run in the last 100 runs, not 20. -**Known limits found while measuring 0.4.1.** In the mutation gate on GitHub's -Mac, `test/baggrund-mus.mjs` runs after the many-agents test, with Finder in -front; there a menu opened by a click behind was not closed again -(`menu_closed: false` in the reply), though the same test passes in the suite. -Its 38 mutants are therefore not proven on a foreign Mac. The check that the -helper process ends within 500 ms of a stop failed in 3 of 11 runs (524-546 ms), -on 0.4.0 and 0.4.1 alike; the mouse button was released in all of them (F2). +**Known limits found while measuring 0.4.1.** Up to 1 November, the mutation +gate on GitHub's Mac ran `test/baggrund-mus.mjs` after the many-agents test, +with Finder in front, and there a menu opened by a click behind was not closed +again (`menu_closed: false` in the reply), though these menu checks pass in the +suite. Its 38 mutants were therefore not proven on a foreign Mac. In +`test/sikker-frigivelse.mjs`, the check that the helper process ends within +500 ms of a stop (F2b) failed in 3 of 11 runs (524-546 ms), on 0.4.0 and 0.4.1 +alike; the mouse button was released in all of them (F2). **Corrected.** The 0.2.1 notes below said "Password managers ask every single time, in every mode." In background mode they are refused, not asked; in the diff --git a/README.md b/README.md index 0b8400f6..91e7a0cc 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,9 @@ in the hours you are not watching. you put it. When an app pulls itself to the front as it opens, the front is handed straight back and the reply says so. In one of 65 measured moments like it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: - false`): until you click back, what you type goes to that app. + false`): until you click back, what you type goes to that app. It also leaves + the front alone when you clicked, scrolled or pressed a key such as Shift in + the last 1.5 seconds - that is taken to be you. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. @@ -245,7 +247,7 @@ says whether that worked. `computer_launch` joins them with `background: true`: the app starts behind what you are doing. Many apps bring themselves forward as they start - six of eight did on a clean Mac - and when one does, the front is handed straight back -and the answer says `took_screen` and `gave_back`. It is a moment, not nothing. Seven are still held back: +and the answer says `took_screen`, and in `gave_back` whether that worked. It is a moment, not nothing. Seven are still held back: `move`, `activate`, `quit`, `space`, `window`, `drag` and `paste` - until you lend the screen: `computer_request_screen` asks you in the box in the corner of your screen (and in the menu bar), one agent at a time, approved with Touch ID, for at diff --git a/docs/docs/capability-matrix/index.html b/docs/docs/capability-matrix/index.html index bd014bc0..4276e6de 100644 --- a/docs/docs/capability-matrix/index.html +++ b/docs/docs/capability-matrix/index.html @@ -221,7 +221,7 @@

Walls we clear partly, and say so

WallWhat actually happens
Redacting secretsmeasuredOnly what macOS marks as secure is painted out. Measured on a real web page: a password input carries role AXTextField with subrole AXSecureTextField and is redacted; a plain text field is not. A password in a text editor, or a token printed in a terminal, carries no marker and will not be hidden. Use readonly when the screen holds something the system cannot know about.
Working without taking over the screenmeasuredThree kinds, and the difference is how the action is delivered, not what the tool is called. Quiet by delivery: computer_press, computer_set_value and computer_menu fire the element's own accessibility action, so they work on a window behind the one you are in and never touch your pointer. The app can still bring itself forward in response - measured: File > New Finder Window did - and then press and menu answer took_screen and hand the front straight back. Quiet when you name the app: computer_click, computer_type, computer_key and computer_scroll are delivered into that app's own event queue - measured: the text arrived, the pointer stayed where it was left, and the front window did not change. computer_launch joins them with background: true - measured on a clean Mac, six of eight apps brought themselves forward as they started, and the front is handed straight back. Without an app they go through the system input tap and land wherever your keyboard focus is, so in background mode they are refused. One measured limit: keystrokes do not land in a Chromium window that is not focused, so for anything Chromium-based use computer_press and computer_set_value. Held back in background mode: computer_move, computer_drag, computer_paste, computer_activate, computer_quit, computer_space and computer_window. Each either moves your pointer, brings something to the front, or changes what you see - a window moved on a screen you are looking at is a quiet channel with a very visible result. computer_ask_user left this list on 29 September: in background mode its question waits in the menu bar icon instead of a dialog. And the held-back seven are no longer out of reach: computer_request_screen asks you to lend this one agent the screen, approved with Touch ID in the menu bar, for at most 15 minutes. While it has it, each step waits while you are using the keyboard or mouse (a step already running finishes), and one click in the menu takes the screen back and stops a step still running. Set CMCP_BACKGROUND and nothing can borrow it.
Working without taking over the screenmeasuredThree kinds, and the difference is how the action is delivered, not what the tool is called. Quiet by delivery: computer_press, computer_set_value and computer_menu fire the element's own accessibility action, so they work on a window behind the one you are in and never touch your pointer. The app can still bring itself forward in response - measured: File > New Finder Window did - and then press and menu answer took_screen and hand the front straight back - gave_back says whether that worked (once in 65 moments on GitHub’s Mac it did not). Quiet when you name the app: computer_click, computer_type, computer_key and computer_scroll are delivered into that app's own event queue - measured: the text arrived, the pointer stayed where it was left, and the front window did not change. computer_launch joins them with background: true - measured on a clean Mac, six of eight apps brought themselves forward as they started, and the front is handed straight back. Without an app they go through the system input tap and land wherever your keyboard focus is, so in background mode they are refused. One measured limit: keystrokes do not land in a Chromium window that is not focused, so for anything Chromium-based use computer_press and computer_set_value. Held back in background mode: computer_move, computer_drag, computer_paste, computer_activate, computer_quit, computer_space and computer_window. Each either moves your pointer, brings something to the front, or changes what you see - a window moved on a screen you are looking at is a quiet channel with a very visible result. computer_ask_user left this list on 29 September: in background mode its question waits in the menu bar icon instead of a dialog. And the held-back seven are no longer out of reach: computer_request_screen asks you to lend this one agent the screen, approved with Touch ID in the menu bar, for at most 15 minutes. While it has it, each step waits while you are using the keyboard or mouse (a step already running finishes), and one click in the menu takes the screen back and stops a step still running. Set CMCP_BACKGROUND and nothing can borrow it.
Several agents at oncemeasuredEach MCP client runs its own server. Measured: two servers, 50 interleaved writes, zero torn lines, and every line carries a session mark. Writes in the same app take turns: each holds a lock for that app, so keys and clicks never interleave within an action. Between actions they still share one pointer and one focused window; give background work to computer_press.
Knowing where the cursor ismeasuredcomputer_focused reports the focused element and whether it is secure. The system-wide lookup alone returns nothing - measured - so it goes through the focused application, then the frontmost app.
A Save / Don't Save sheetmeasuredThe sheet you meet every time you close something with unsaved work. Measured: the sheet is found as AXSheet, all three buttons come back with a center and a pressable flag, and computer_find with contains: "Don't Save" returns exactly that one button - an agent looks for the words, not for a position. It is also the clearest case for the gate: a sheet can throw away work on your behalf, so in read-only mode pressing it is refused and nothing reaches the machine. Measured against a sheet the test puts up itself, in a fully transparent window, so proving it costs nobody their screen.
- + diff --git a/mcp-server/README.md b/mcp-server/README.md index 6e12ba9a..a1f0479c 100644 --- a/mcp-server/README.md +++ b/mcp-server/README.md @@ -13,7 +13,9 @@ in the hours you are not watching. you put it. When an app pulls itself to the front as it opens, the front is handed straight back and the reply says so. In one of 65 measured moments like it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: - false`): until you click back, what you type goes to that app. + false`): until you click back, what you type goes to that app. It also leaves + the front alone when you clicked, scrolled or pressed a key such as Shift in + the last 1.5 seconds - that is taken to be you. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. @@ -243,7 +245,7 @@ says whether that worked. `computer_launch` joins them with `background: true`: the app starts behind what you are doing. Many apps bring themselves forward as they start - six of eight did on a clean Mac - and when one does, the front is handed straight back -and the answer says `took_screen` and `gave_back`. It is a moment, not nothing. Seven are still held back: +and the answer says `took_screen`, and in `gave_back` whether that worked. It is a moment, not nothing. Seven are still held back: `move`, `activate`, `quit`, `space`, `window`, `drag` and `paste` - until you lend the screen: `computer_request_screen` asks you in the box in the corner of your screen (and in the menu bar), one agent at a time, approved with Touch ID, for at From 83983f6830c5f67ffe8246309f5799d97910352f Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 05:05:26 +0100 Subject: [PATCH 12/14] 0.4.1: panel R4's to valgfri praeciseringer (modifier key, completed runs) - begge GODKENDT b og c Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- README.md | 4 ++-- mcp-server/README.md | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d44e3d9..0b830952 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ appear after it. The SDK also has to be at least 1.32.1. the background while another test types into TextEdit. An agent that opens a Finder window brings Finder forward for a moment, and the front is handed straight back - the longest one that was handed back lasted 2.8 seconds. In -eleven runs on GitHub's Mac, on macOS 15.7 and 15.8 alike, it happened twice at +eleven completed runs on GitHub's Mac, on macOS 15.7 and 15.8 alike, it happened twice at 32 of 33 levels; the recording on the front page shows the same thing. In one of 65 such moments the front could not be handed back: Finder stayed in front for the rest of that round (at least 40 seconds), and the reply said so diff --git a/README.md b/README.md index 91e7a0cc..3bee9215 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ in the hours you are not watching. handed straight back and the reply says so. In one of 65 measured moments like it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: false`): until you click back, what you type goes to that app. It also leaves - the front alone when you clicked, scrolled or pressed a key such as Shift in - the last 1.5 seconds - that is taken to be you. + the front alone when you clicked, scrolled or pressed a modifier key such as + Shift in the last 1.5 seconds - that is taken to be you. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. diff --git a/mcp-server/README.md b/mcp-server/README.md index a1f0479c..94d89db2 100644 --- a/mcp-server/README.md +++ b/mcp-server/README.md @@ -14,8 +14,8 @@ in the hours you are not watching. handed straight back and the reply says so. In one of 65 measured moments like it (GitHub's Mac, many agents at once) it could not be, and the reply said that too (`gave_back: false`): until you click back, what you type goes to that app. It also leaves - the front alone when you clicked, scrolled or pressed a key such as Shift in - the last 1.5 seconds - that is taken to be you. + the front alone when you clicked, scrolled or pressed a modifier key such as + Shift in the last 1.5 seconds - that is taken to be you. - **It does not pretend.** When something is refused or fails, it says so and says why. The most common complaint about agents driving a computer is that they carry on as if it worked. From 0178a669feaf3ec8dad1f8273ee67e9c01be5db1 Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 11:25:38 +0100 Subject: [PATCH 13/14] 0.4.1: baggrund-mus-hypotesen falsificeret - aarsag ikke fundet; Script Editor-linjen fjernet; rettelse af 0.4.0's menu-loefte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fremmed Mac 41270352704 (1003f89): portens baseline havde Script Editor forrest (5c «Script Editor -> Script Editor») og 5a/5b/5g fejlede alligevel. «Finder forrest» var ikke aarsagen (panel R2 B). Linjen gjorde ingen forskel og er fjernet. CHANGELOG: kendt graense uden aarsag, F2b 4 af 12 (517-546 ms, F2 uden DUMP), Corrected-note til «A click behind never leaves a menu over your work». Co-Authored-By: Claude Opus 5.5 --- .github/workflows/fremmed-mac.yml | 3 --- CHANGELOG.md | 17 ++++++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/fremmed-mac.yml b/.github/workflows/fremmed-mac.yml index 415c62d7..5aa45490 100644 --- a/.github/workflows/fremmed-mac.yml +++ b/.github/workflows/fremmed-mac.yml @@ -227,9 +227,6 @@ jobs: run: | rc=0 bash .github/mutant-giv-tilbage.sh || rc=1 - # 1/11 (panel R2-R3): «Mange agenter» og giv-tilbage-mutanterne efterlader Finder forrest; i suiten (Script Editor - # forrest) bestaar baggrund-mus' menu-tjek, i portens baseline ikke. Lige foer porten, saa baggrund-mus starter som i suiten. - open -a "Script Editor"; sleep 4 python3 .github/mutant-porte.py || rc=1 exit $rc diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b830952..1eb07596 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,16 +48,19 @@ prints the last lines of a test that fails before anything is mutated. **Known limits found while measuring 0.4.1.** Up to 1 November, the mutation gate on GitHub's Mac ran `test/baggrund-mus.mjs` after the many-agents test, -with Finder in front, and there a menu opened by a click behind was not closed -again (`menu_closed: false` in the reply), though these menu checks pass in the -suite. Its 38 mutants were therefore not proven on a foreign Mac. In -`test/sikker-frigivelse.mjs`, the check that the helper process ends within -500 ms of a stop (F2b) failed in 3 of 11 runs (524-546 ms), on 0.4.0 and 0.4.1 -alike; the mouse button was released in all of them (F2). +and there a menu opened by a click behind was not closed again (`menu_closed: +false` in the reply) - with Finder in front, and in a run that started Script +Editor first, with Script Editor in front - though these menu checks pass in +the suite. The cause is not found. Its 38 mutants were therefore not proven on +a foreign Mac. In `test/sikker-frigivelse.mjs`, the check that the helper +process ends within 500 ms of a stop (F2b) failed in 4 of 12 runs (517-546 ms), +on 0.4.0 and 0.4.1 alike; the mouse button was released in all of them (F2). **Corrected.** The 0.2.1 notes below said "Password managers ask every single time, in every mode." In background mode they are refused, not asked; in the -foreground they ask every time. +foreground they ask every time. The 0.4.0 notes say "A click behind never leaves +a menu over your work." In the mutation gate on GitHub's Mac a menu opened by a +click behind was left open, and the reply said so (`menu_closed: false`). ## 0.4.0 (in progress) From f6b4348fe1457d0050eea5abcb3d4df4924e5b6f Mon Sep 17 00:00:00 2001 From: Gustav Louv Date: Sun, 1 Nov 2026 11:37:05 +0100 Subject: [PATCH 14/14] 0.4.1: kendt graense efter 605c70e - Script Editor forrest ogsaa lige foer porten (2. falsifikation), F2b 4 af 13, nutid Fremmed Mac 41271247500 (605c70e): suiten groen, mange agenter groen; portens baseline for baggrund-mus stadig roed med Script Editor forrest (2c/5c). Placeringen betyder intet; linjens fjernelse i 0178a66 staar. Tal genoptalt fra 13 logs. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eb07596..36f5abb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,15 +46,16 @@ requires; on a foreign Mac that check had failed on 0.4.0. The mutation gate now prints the last lines of a test that fails before anything is mutated. `scripts/release.sh` looks for the CI run in the last 100 runs, not 20. -**Known limits found while measuring 0.4.1.** Up to 1 November, the mutation -gate on GitHub's Mac ran `test/baggrund-mus.mjs` after the many-agents test, -and there a menu opened by a click behind was not closed again (`menu_closed: -false` in the reply) - with Finder in front, and in a run that started Script -Editor first, with Script Editor in front - though these menu checks pass in -the suite. The cause is not found. Its 38 mutants were therefore not proven on -a foreign Mac. In `test/sikker-frigivelse.mjs`, the check that the helper -process ends within 500 ms of a stop (F2b) failed in 4 of 12 runs (517-546 ms), -on 0.4.0 and 0.4.1 alike; the mouse button was released in all of them (F2). +**Known limits found while measuring 0.4.1.** The mutation gate on GitHub's Mac +runs `test/baggrund-mus.mjs` after the many-agents test, and there a menu +opened by a click behind is not closed again (`menu_closed: false` in the +reply) - with Finder in front, and in two runs that put Script Editor in front +first, with Script Editor in front - though these menu checks pass in the +suite. The cause is not found. Its 38 mutants are therefore not proven on a +foreign Mac. In `test/sikker-frigivelse.mjs`, the check that the helper process +ends within 500 ms of a stop (F2b) failed in 4 of 13 completed runs by +1 November (517-546 ms), on 0.4.0 and 0.4.1 alike; the mouse button was +released in all of them (F2). **Corrected.** The 0.2.1 notes below said "Password managers ask every single time, in every mode." In background mode they are refused, not asked; in the
WallWhat actually happens
Redacting secretsmeasuredOnly what macOS marks as secure is painted out. Measured on a real web page: a password input carries role AXTextField with subrole AXSecureTextField and is redacted; a plain text field is not. A password in a text editor, or a token printed in a terminal, carries no marker and will not be hidden. Use readonly when the screen holds something the system cannot know about.
Working without taking over the screenmeasuredThree kinds, and the difference is how the action is delivered, not what the tool is called. Quiet by delivery: computer_press, computer_set_value and computer_menu fire the element's own accessibility action, so they work on a window behind the one you are in and never touch your pointer. The app can still bring itself forward in response - measured: File > New Finder Window did - and then press and menu answer took_screen and hand the front straight back - gave_back says whether that worked (once in 65 moments on GitHub’s Mac it did not). Quiet when you name the app: computer_click, computer_type, computer_key and computer_scroll are delivered into that app's own event queue - measured: the text arrived, the pointer stayed where it was left, and the front window did not change. computer_launch joins them with background: true - measured on a clean Mac, six of eight apps brought themselves forward as they started, and the front is handed straight back. Without an app they go through the system input tap and land wherever your keyboard focus is, so in background mode they are refused. One measured limit: keystrokes do not land in a Chromium window that is not focused, so for anything Chromium-based use computer_press and computer_set_value. Held back in background mode: computer_move, computer_drag, computer_paste, computer_activate, computer_quit, computer_space and computer_window. Each either moves your pointer, brings something to the front, or changes what you see - a window moved on a screen you are looking at is a quiet channel with a very visible result. computer_ask_user left this list on 29 September: in background mode its question waits in the menu bar icon instead of a dialog. And the held-back seven are no longer out of reach: computer_request_screen asks you to lend this one agent the screen, approved with Touch ID in the menu bar, for at most 15 minutes. While it has it, each step waits while you are using the keyboard or mouse (a step already running finishes), and one click in the menu takes the screen back and stops a step still running. Set CMCP_BACKGROUND and nothing can borrow it.
Working without taking over the screenmeasuredThree kinds, and the difference is how the action is delivered, not what the tool is called. Quiet by delivery: computer_press, computer_set_value and computer_menu fire the element's own accessibility action, so they work on a window behind the one you are in and never touch your pointer. The app can still bring itself forward in response - measured: File > New Finder Window did - and then press and menu answer took_screen and hand the front straight back - gave_back says whether that worked (once in 65 moments on GitHub’s Mac it did not). Quiet when you name the app: computer_click, computer_type, computer_key and computer_scroll are delivered into that app's own event queue - measured: the text arrived, the pointer stayed where it was left, and the front window did not change. computer_launch joins them with background: true - measured on a clean Mac, six of eight apps brought themselves forward as they started, and the front is handed straight back - gave_back says whether that worked. Without an app they go through the system input tap and land wherever your keyboard focus is, so in background mode they are refused. One measured limit: keystrokes do not land in a Chromium window that is not focused, so for anything Chromium-based use computer_press and computer_set_value. Held back in background mode: computer_move, computer_drag, computer_paste, computer_activate, computer_quit, computer_space and computer_window. Each either moves your pointer, brings something to the front, or changes what you see - a window moved on a screen you are looking at is a quiet channel with a very visible result. computer_ask_user left this list on 29 September: in background mode its question waits in the menu bar icon instead of a dialog. And the held-back seven are no longer out of reach: computer_request_screen asks you to lend this one agent the screen, approved with Touch ID in the menu bar, for at most 15 minutes. While it has it, each step waits while you are using the keyboard or mouse (a step already running finishes), and one click in the menu takes the screen back and stops a step still running. Set CMCP_BACKGROUND and nothing can borrow it.
Several agents at oncemeasuredEach MCP client runs its own server. Measured: two servers, 50 interleaved writes, zero torn lines, and every line carries a session mark. Writes in the same app take turns: each holds a lock for that app, so keys and clicks never interleave within an action. Between actions they still share one pointer and one focused window; give background work to computer_press.
Knowing where the cursor ismeasuredcomputer_focused reports the focused element and whether it is secure. The system-wide lookup alone returns nothing - measured - so it goes through the focused application, then the frontmost app.
A Save / Don't Save sheetmeasuredThe sheet you meet every time you close something with unsaved work. Measured: the sheet is found as AXSheet, all three buttons come back with a center and a pressable flag, and computer_find with contains: "Don't Save" returns exactly that one button - an agent looks for the words, not for a position. It is also the clearest case for the gate: a sheet can throw away work on your behalf, so in read-only mode pressing it is refused and nothing reaches the machine. Measured against a sheet the test puts up itself, in a fully transparent window, so proving it costs nobody their screen.