Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
47c80f2
fix: byg paa macos-15, aerlige forgrunds-loefter, fremmed-mac som ægt…
Sep 28, 2026
dcf361a
vejledning: spørg når du er blokeret, giv ikke op - tre ting er menne…
Sep 28, 2026
6a5868f
docs: regenerer npm-README efter forgrunds-loefte-rettelsen (holder c…
Sep 28, 2026
d1c5cfe
haerdning M1: programlaasen fejler LUKKET ved infra-fejl (ikke aaben)
Sep 28, 2026
b5d0953
haerdning M4: giv aldrig forgrunden fra et menneske der lige skiftede
Sep 28, 2026
4f9c98c
test(mutant): opdater M4-mutanten til den nye give-tilbage-kode
Sep 28, 2026
c063058
doer (slice 1): computer_open - aabn en apps egen indgang bagfra, sik…
Sep 28, 2026
35fbb6a
doer (slice 1) doc-sync: computer_open paa alle flader, tal 30->31
Sep 28, 2026
259c9fb
review-fund (Astra+Fable luknings-review): ret overclaims + dør-timeo…
Sep 29, 2026
03e6f46
oprydning (review-loose-ends): fjern død claude-scheme fra dørens all…
Sep 29, 2026
08641e6
positionér på universaliteten: kører i ENHVER MCP-klient, ikke én app
Sep 29, 2026
226d5fd
distribution: MCPB-bundle-recept (Smithery + selv-install), valideret
Sep 29, 2026
afa2786
vejledning: ret usandt løfte om ask_user (Fable-review) - den bruger …
Sep 29, 2026
7680067
type naegter kodeordsfelter - ogsaa naar fokus flytter derind undervejs
Sep 29, 2026
bf2349b
samtykke-porten viser HELE handlingen foer ja - intet tavst klip
Sep 29, 2026
ce87b6f
samtykke-porten: bevis at den fejler lukket og kommer igen
Sep 29, 2026
8876557
computer_ask_user virker i baggrund - spoergsmaalet venter i menulinj…
Sep 29, 2026
c8672bf
sende-porten: en besked til et rigtigt menneske spoerger hver gang
Sep 30, 2026
74d7e55
skaerm-laanet: mennesket laaner én agent skaermen i ikonet - og tager…
Sep 30, 2026
65f3ef4
B6: computer_permissions siger hvor porten kan gaas udenom
Sep 30, 2026
0ec8013
B7: portenes mutationsbevis koerer paa den fremmede Mac ved hver aend…
Sep 30, 2026
1bf6ceb
ikonets menu maales: --dump-question viser praecis hvad mennesket ser
Sep 30, 2026
736fab4
runde 1-rettelser (lån + samtykke): R1 R2 R8 R9 R12 R13
Sep 30, 2026
297df8a
runde 1-rettelser (sende-port m.m.): R3 R4 R5 R6 R7 R10 R11 R14 R15
Sep 30, 2026
3648aa0
runde 2-rettelser (laan + samtykke): Q1 Q5 Q6 + smaat
Sep 30, 2026
2485a66
runde 2-rettelser (sende-port, kodeord, omveje, instrumenter): Q2 Q3 …
Sep 30, 2026
9370f0d
runde 3-rettelser: kodeordsvagt i alle skriveveje, laan-binding, send…
Sep 30, 2026
b626996
CI 2485a66 roed: browserens «ulaeselig titel = chat» ramte klik-ejer;…
Sep 30, 2026
95470f2
runde 4-rettelser: laan fra kaldets start, Send-bindingens tre omveje…
Sep 30, 2026
f51a1af
runde 5-rettelser: laanets generation, ulaeseligt kontrolvindue, past…
Sep 30, 2026
199612d
paste-stop synkront: SIGUSR1 blokeres og laeses med sigpending() foer…
Sep 30, 2026
6475104
efterkontrol 2: Astra GODKENDT - traad-forudsaetningen for paste-stop…
Sep 30, 2026
37f2c15
udgivelse: npm-jobbet bundet til miljoeet «udgivelse» (Gustav eneste …
Sep 30, 2026
7138e4a
omveje: kun regler der tillader hvad som helst taeller (live-proeven …
Sep 30, 2026
4a7ee8d
proeverne rydder deres midlertidige mapper, naar de er bestaaet (3,4 …
Sep 30, 2026
2ed9b7c
ikonet: boksen siger at et spoergsmaal venter og flytter hen til menn…
Sep 30, 2026
2a14d1b
proeve: 5/10/15 agenter samtidig i baggrunden + film af hver use case…
Oct 1, 2026
b5eb755
parallel-proeven: TextEdit uden aabne-panel + tilstand til egen Mac m…
Oct 1, 2026
7dcc791
porten: et menupunkt der lukker spoerger paa alle sprog - genvejen af…
Oct 1, 2026
5089e22
giv-tilbage river ikke menneskets skift tilbage + maaleren laeser mac…
Oct 1, 2026
2b2682f
mutationsbevis for de 7 skrivende/beskyttende vaerktoejer der ikke ha…
Oct 1, 2026
92834ca
send-porten i rigtig WhatsApp: feltet og modtageren findes (W, 1/10)
Oct 1, 2026
6b44c96
rettelser efter GitHubs Mac (koersel 36859187191): forgrund via AX-fo…
Oct 1, 2026
69d67f5
README: Claude Codes auto-mode afviser skaerm-vaerktoejerne (maalt 1/…
Oct 1, 2026
bd277f0
revisionsloggen: launch uden background siger nu den rigtige grund (A…
Oct 1, 2026
5901f43
giv-tilbage: skrivning er ikke et programskift + proeven lukker sine …
Oct 1, 2026
9903395
knapper der sletter eller rydder spoerger - som README lover (1/10, s…
Oct 1, 2026
fae1055
parallel-prøven: ret falske fejl fra koersel 36869119105 - for streng…
Oct 1, 2026
84a4bed
parallel-prøven: ret tePid-gaetning der inverterede 5.1b-doemmelsen (…
Oct 1, 2026
8d46981
skaerm-koe trin 1+8: skaerm-anmodninger venter 5 min (loft 20), ikke …
Oct 1, 2026
9594feb
parallel-prøven: SIGKILL + bekraeft TextEdit vaek mellem runder (koer…
Oct 1, 2026
6953d8e
parallel-prøven: slaa TextEdits Resume fra - SIGKILL alene genskabte …
Oct 1, 2026
a132053
parallel-prøven: 5.2 bygger nu paa hjaelperens EGEN verified-bekraeft…
Oct 1, 2026
48b3227
giv-tilbage: ny sag 5 beviser at et RIGTIGT tastetryk ikke blokerer e…
Oct 1, 2026
258f7c0
giv-tilbage sag 5: maal den PRAECISE menneskeRoerteNetop-signatur, ik…
Oct 1, 2026
07a4a8f
skaerm-koe trin 2: gater Allow i stedet for at afvise med «optaget»
Oct 2, 2026
2d8ba00
A6: macOS-matrix til Fremmed Mac - Intel + Apple Silicon, begge GA-ve…
Oct 2, 2026
e4b92ef
B3: kontaktark - ét billede pr. use case (før/efter) i en HTML-rapport
Oct 2, 2026
f22496a
sikkerhed: et blindt koordinat-klik fejlede ÅBENT i stedet for lukket
Oct 2, 2026
a3483c5
D3: følg-panelets "Show me where" - peger på agentens mål uden selv a…
Oct 2, 2026
391d958
vejledning: canvas-blinde apps rapporterer tilbage, gætter ikke selv
Oct 2, 2026
a46c6a3
sync-tal.py: FORBEHOLD-linjeskiftet forsvandt efter lukkemarkøren
Oct 2, 2026
ac7da21
sikkerhed: knapErFarlig var for bred - almindelige klik begyndte at s…
Oct 2, 2026
0ff9db6
CMCP_FILM_PYNT: ren optagelse til forsiden, uden at røre et eneste tjek
Oct 2, 2026
2aece3d
bevis.sh: "ikke skubbet" målte mod origin/main, ikke husets egen PR-gren
Oct 2, 2026
46e3cdc
sikkerhed: fjern targetBundleId-undtagelsen - den genåbnede Opus' fund
Oct 2, 2026
2ba02e6
rettet mutationsbevis: navnSender's klik-gren var en kopi af kanVaere…
Oct 2, 2026
420b998
udgivelse: ret to konkrete fejl fundet af Astra+Opus panelet 2/10
Oct 2, 2026
b184854
mutant Q9-navnloes-gruppe-er-send: anker peger ikke paa levende kode …
Oct 2, 2026
0e62745
udgivelse: ret tre fejl i faerdiggoer-udgivelsen.sh (Astra+Opus 2/10)
Oct 2, 2026
f460c15
udgivelse: release.sh skubbede altid forgæves eller forkert til prote…
Oct 2, 2026
77ba8b6
sikkerhed F5: computer_press delte klikkets gamle fail-open-fejl
Oct 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: "Something did not work"
description: "An agent tried something on your Mac and it failed, or it took your screen when it should not have."
title: "Bug: <what happened in one line>"
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Nothing is sent from your Mac on its own. Paste only what you are happy to share:
the audit log hashes typed text and never stores what was on screen, but app names
and window titles are in it.
- type: textarea
id: what
attributes:
label: What the agent tried, and what actually happened
validations:
required: true
- type: textarea
id: audit
attributes:
label: The last few lines of the audit log
description: "Ask the agent for `computer_audit` with limit 10, or copy from ~/.local/state/computer-mcp/audit.jsonl."
render: json
- type: textarea
id: learning
attributes:
label: Anything it wrote with computer_learning
description: "~/.local/state/computer-mcp/learnings.jsonl - numbers and email addresses are already masked."
- type: input
id: versions
attributes:
label: macOS version and computer-mcp version
placeholder: "macOS 26.4.1 · computer-mcp 0.2.1"
validations:
required: true
69 changes: 55 additions & 14 deletions .github/mutant-giv-tilbage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,69 @@
set -u
fejl=0
mut() {
local navn="$1" fra="$2" til="$3" d="$RUNNER_TEMP/mut-$1"
local navn="$1" fra="$2" til="$3" d="$RUNNER_TEMP/mut-$1" maal="${MUT_MAAL:-cmcp-helper}"
# Uden byggemappen: den baerer faste stier til originalen (koersel 3 kunne ikke bygge).
mkdir -p "$d" && cp -R helper/Package.swift helper/Sources "$d"/
[ -f helper/Package.resolved ] && cp helper/Package.resolved "$d"/
python3 - "$d/Sources/cmcp-helper/${MUT_FIL:-Skaerm.swift}" "$fra" "$til" <<'PY'
# ⛔ 30/9 (Astra R2 7): et anker der ikke fandtes, stoppede ikke noget - scriptet
# byggede den UMUTEREDE kode og kaldte resultatet et bevis. Nu er det en fejl.
if ! python3 - "$d/Sources/$maal/${MUT_FIL:-Skaerm.swift}" "$fra" "$til" <<'PY2'
import sys
p, a, b = sys.argv[1:4]
s = open(p).read()
assert s.count(a) == 1, a
open(p, 'w').write(s.replace(a, b))
PY
(cd "$d" && swift build -c release 2>&1 | tail -5) ; [ -x "$d/.build/release/cmcp-helper" ] || { echo "::error::$navn kunne ikke bygges"; fejl=1; return; }
if CMCP_HELPER="$d/.build/release/cmcp-helper" node test/giv-tilbage.mjs; then
echo "::error::mutanten $navn overlevede - proeven maaler ikke"; fejl=1
else
echo "mutanten $navn er roed"
fi
PY2
then echo "::error::$navn: ankeret findes ikke praecis én gang"; fejl=1; return; fi
(cd "$d" && swift build -c release 2>&1 | tail -5) ; [ -x "$d/.build/release/$maal" ] || { echo "::error::$navn kunne ikke bygges"; fejl=1; return; }
local ud rc
ud=$(CMCP_HELPER="$d/.build/release/cmcp-helper" CMCP_STATUS_BIN="$d/.build/release/cmcp-status" node "${PROEVE:-test/giv-tilbage.mjs}" 2>&1); rc=$?
# Roed = exit 1 OG en DUMP-linje. Exit 0 = overlevede. Alt andet = instrumentet svarede ikke.
if [ $rc -eq 0 ]; then echo "::error::mutanten $navn overlevede - proeven maaler ikke"; fejl=1
# Runde 3 (Astra 6): KUN den prove mutanten er skrevet til taeller (FORVENTET), ikke en vilkaarlig anden.
# Runde 5 (Astra): hele det forventede praefiks skal staa FORREST paa en DUMP-linje.
elif [ $rc -eq 1 ] && printf '%s\n' "$ud" | awk -v p="DUMP ${FORVENTET:-}" 'index($0, p) == 1 { f = 1 } END { exit !f }'; then echo "mutanten $navn er roed ($(printf '%s\n' "$ud" | awk -v p="DUMP ${FORVENTET:-}" 'index($0, p) == 1 { print; exit }' | cut -c1-90))"
else echo "::error::$navn: instrumentet svarede ikke (rc=$rc) - det er ikke et bevis"; fejl=1; fi
}
mut M1-giver-ikke-tilbage 'NSRunningApplication(processIdentifier: foer.forrestPid)?.activate(options: [])' ''
mut M2-maaler-ikke 'guard foer.forrestPid > 0, efter.forrestPid != foer.forrestPid else { return ["took_screen": false] }' 'return ["took_screen": false]'
FORVENTET=2b mut M1-giver-ikke-tilbage 'NSRunningApplication(processIdentifier: foer.forrestPid)?.activate(options: [])' ''
FORVENTET='2 et tryk' mut M2-maaler-ikke 'guard foer.forrestPid > 0, efter.forrestPid != foer.forrestPid else { return ["took_screen": false] }' 'return ["took_screen": false]'
# M3: launch giver ikke forgrunden tilbage (main.swift)
MUT_FIL=main.swift mut M3-launch-giver-ikke-tilbage 'if (g["took_screen"] as? Bool) == true { for (k, v) in g { ls[k] = v } }' 'if false { for (k, v) in g { ls[k] = v } }'
# M4: kun et skift til maalprogrammet gives tilbage (reglen foer koersel 10)
mut M4-kun-maalprogrammet 'efter.forrestPid == maal || !menneskeRoerteNetop()' 'efter.forrestPid == maal'
FORVENTET='3 et program' MUT_FIL=main.swift mut M3-launch-giver-ikke-tilbage 'if (g["took_screen"] as? Bool) == true || g["observed"] != nil { for (k, v) in g { ls[k] = v } }' 'if false { for (k, v) in g { ls[k] = v } }'
# M4 (28/9): menneske-tjekket maa ikke spurioest blokere give-tilbage. Paa en
# maskine UDEN menneske skal forgrunden stadig gives tilbage - saa hvis nogen
# faar menneske-grenen til altid at fyre (og dermed altid lade forgrunden staa),
# SKAL proeven blive roed.
FORVENTET=2b mut M4-menneske-tjek-blokerer 'if menneskeRoerteNetop() {' 'if true {'
# M5-M6 (29/9, panelet): kodeordsfelter faar heller ikke tastetryk fra `type`.
# M5: fokus-opslaget siger altid «ikke sikkert» -> proeve 3/3k/3b skal blive roed.
# M6: tjekket kun foer foerste tegn -> fokus der flytter undervejs (3c) skal blive roed.
FORVENTET='3 et kodeordsfelt' PROEVE=test/skriv-ankommer.mjs MUT_FIL=Accessibility.swift mut M5-type-i-kodeordsfelt \
'static func sikkerStatus(_ el: AXUIElement, kendtRolle: String? = nil) -> Bool? {' \
'static func sikkerStatus(_ el: AXUIElement, kendtRolle: String? = nil) -> Bool? {
if true { return false }'
FORVENTET=3c PROEVE=test/skriv-ankommer.mjs MUT_FIL=Input.swift mut M6-kun-tjek-ved-start \
'if let stop, stop() { return sendt }' 'if let stop, sendt == 0, stop() { return sendt }'
# M7-M8 (30/9, runde 5): paste stopper foer Cmd+V naar laanet slutter.
# M7: det foerste stop (foer udklipsholderen roeres) er vaek -> «before anything changed» maa ikke kunne naas.
FORVENTET='1 SIGUSR1' PROEVE=test/paste-stop.mjs MUT_FIL=Accessibility.swift mut M7-paste-roerer-udklip-foer-stop \
' if pasteStop { return (false, "stopped before anything changed: the screen loan ended", false) }' ''
# M8: stoppet laeses aldrig -> paste fortsaetter til Cmd+V (kun paa en fremmed maskine).
FORVENTET='1 SIGUSR1' PROEVE=test/paste-stop.mjs MUT_FIL=Accessibility.swift mut M8-paste-hoerer-ikke-stop \
' return sigismember(&s, SIGUSR1) == 1' ' return false'
# M9 (30/9, live-proeven): boksen naevner ikke det ventende spoergsmaal -> 3c skal blive roed.
FORVENTET=3c PROEVE=test/ikon-menu.mjs MUT_MAAL=cmcp-status MUT_FIL=Tekst.swift mut M9-boksen-tier-om-spoergsmaalet \
'[antal == 1 ? "Needs you: click the orange menu bar icon"' '[antal == 1 ? "Computer MCP"'
# M10 (1/10, konsulent-panelet): giv-tilbage river igen ethvert program tilbage -
# ogsaa et der koerte i forvejen (= mennesket der skiftede skrivebord) -> 4 skal blive roed.
FORVENTET='4 et program der koerte' mut M10-river-menneskets-skift-tilbage \
'if !egen {' 'if false {'
# M11 (1/10, GitHubs Mac 36863990504 - retarget 36901238860): almindelig skrivning
# taeller igen som et menneskeligt skift -> et rigtigt tastetryk ville fejlagtigt
# blokere en legitim tilbagegivelse. Oprindeligt bevist via parallel.mjs's
# menneske-simulation, som siden skriver via tilgaengeligheds-laget (ingen rigtig
# keyDown postes der laengere - den mutant blev umaalelig af parallel.mjs selv).
# giv-tilbage.mjs's sag 5 sender et AEGTE globalt tastetryk med vilje og maaler
# praecis dette.
FORVENTET='5 et rigtigt tastetryk' mut M11-skrivning-er-et-skift \
'[.flagsChanged, .leftMouseDown' '[.keyDown, .flagsChanged, .leftMouseDown'
exit $fejl
43 changes: 43 additions & 0 deletions .github/mutant-porte.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
# Mutationsbevis for portene (29/9, B7 - MANDAT: «hver vagt skal kunne blive roed»).
# Hver mutant i mutanter-porte.json bygger én fejl ind i en vagt; dens proeve SKAL
# blive roed. Filen gendannes ALTID fra en kopi taget lige foer - aldrig fra git,
# for filen kan baere ucommittet arbejde (30/9: `git checkout` tog en hel funktion).
import hashlib, json, os, subprocess, sys
ROD = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
os.chdir(ROD)
overlevede, fejl = [], []
for m in json.load(open('.github/mutanter-porte.json', encoding='utf-8')):
orig = open(m['fil'], encoding='utf-8').read()
h = hashlib.sha256(orig.encode()).hexdigest()
par = m.get('par') or [[m['fra'], m['til']]]
tael = [orig.count(a) for a, _ in par]
if any(t != 1 for t in tael):
fejl.append(f"{m['navn']}: ankrene findes {tael} gange"); continue
muteret = orig
for a, b in par: muteret = muteret.replace(a, b)
try:
open(m['fil'], 'w', encoding='utf-8').write(muteret)
try:
k = subprocess.run(['node', m['proeve']], capture_output=True, text=True, timeout=600)
rc, ud = k.returncode, k.stdout
except subprocess.TimeoutExpired:
rc, ud = 'timeout', ''
finally:
open(m['fil'], 'w', encoding='utf-8').write(orig)
if hashlib.sha256(open(m['fil'], encoding='utf-8').read().encode()).hexdigest() != h:
fejl.append(f"{m['navn']}: {m['fil']} blev IKKE gendannet"); break
# ⛔ Runde 1 30/9 (Astra 9): enhver ikke-nul exit talte som «roed» - ogsaa en
# prove der crashede for foerste assertion. Roed = rc 1 OG en DUMP-linje.
# ⛔ Runde 2 (Astra 7): en tilfaeldig ANDEN DUMP-linje var ogsaa «bevis». Nu skal
# den prove mutanten er skrevet til (`forventet`), vaere en af de roede.
doemt = [l for l in ud.splitlines() if l.startswith('DUMP ' + m.get('forventet', ''))]
if rc == 0:
overlevede.append(m['navn']); print(f"::error::mutanten {m['navn']} overlevede - {m['proeve']} maaler ikke")
elif rc == 1 and doemt:
print(f"mutanten {m['navn']} er roed ({m['proeve']}: {doemt[0][:90]})")
else:
fejl.append(f"{m['navn']}: instrumentet svarede ikke (rc={rc}, {len(doemt)} DUMP-linjer) - det er ikke et bevis")
for f in fejl: print(f"::error::{f}")
print(f"{len(overlevede)} overlevede, {len(fejl)} fejl")
sys.exit(1 if overlevede or fejl else 0)
Loading
Loading