agentbox-app 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +176 -0
- package/bin/agentbox.mjs +103 -0
- package/briefs/adhd-mode.md +5 -0
- package/briefs/message-rules.md +95 -0
- package/briefs/worker.md +230 -0
- package/briefs/writing-rules.md +336 -0
- package/main/account-discovery.mjs +145 -0
- package/main/account-tooling.mjs +261 -0
- package/main/agent-activity.mjs +56 -0
- package/main/agent-files.mjs +422 -0
- package/main/agent-schedule.mjs +254 -0
- package/main/agent-sessions.mjs +435 -0
- package/main/agents.mjs +1095 -0
- package/main/analytics.mjs +206 -0
- package/main/answer-modes.mjs +206 -0
- package/main/approval-prompt-server.mjs +160 -0
- package/main/approvals.mjs +487 -0
- package/main/artifact-path.mjs +144 -0
- package/main/claude-bin.mjs +311 -0
- package/main/claude-input.mjs +117 -0
- package/main/claude-models.mjs +244 -0
- package/main/claude-plan.mjs +148 -0
- package/main/claude-usage.mjs +149 -0
- package/main/code-change.mjs +383 -0
- package/main/code-file.mjs +116 -0
- package/main/codex-account.mjs +146 -0
- package/main/codex-app-server.mjs +796 -0
- package/main/codex-approvals.mjs +712 -0
- package/main/codex-bin.mjs +261 -0
- package/main/codex-compaction.mjs +49 -0
- package/main/codex-models.mjs +194 -0
- package/main/codex-session.mjs +797 -0
- package/main/codex-threads.mjs +268 -0
- package/main/codex-usage-file.mjs +192 -0
- package/main/codex-usage.mjs +149 -0
- package/main/codex-watch.mjs +35 -0
- package/main/codex.mjs +757 -0
- package/main/config.mjs +345 -0
- package/main/copy-selection.mjs +55 -0
- package/main/crash-report.mjs +158 -0
- package/main/demo.mjs +254 -0
- package/main/dev-window.mjs +103 -0
- package/main/doc-file.mjs +99 -0
- package/main/doc-scheme.mjs +126 -0
- package/main/first-run.mjs +190 -0
- package/main/folders.mjs +91 -0
- package/main/fresh-user.mjs +120 -0
- package/main/git-change.mjs +323 -0
- package/main/img-scheme.mjs +90 -0
- package/main/instruction-settings.mjs +205 -0
- package/main/ipc.mjs +1558 -0
- package/main/live-replies.mjs +77 -0
- package/main/machine.mjs +113 -0
- package/main/main.mjs +972 -0
- package/main/menu.mjs +177 -0
- package/main/notify.mjs +155 -0
- package/main/open-source-file.mjs +8 -0
- package/main/project-identity.mjs +149 -0
- package/main/provider-commands.mjs +32 -0
- package/main/rail-note.mjs +74 -0
- package/main/repeats.mjs +261 -0
- package/main/row-label.mjs +185 -0
- package/main/screen-detail.mjs +44 -0
- package/main/serve.mjs +262 -0
- package/main/settings.mjs +912 -0
- package/main/staleness.mjs +76 -0
- package/main/store/chats.mjs +188 -0
- package/main/store/home.mjs +383 -0
- package/main/store/migrate.mjs +40 -0
- package/main/store/paths.mjs +82 -0
- package/main/store/pending-writes.mjs +122 -0
- package/main/store/project-lock.mjs +200 -0
- package/main/store/project.mjs +523 -0
- package/main/store/queues.mjs +31 -0
- package/main/store/work-items.mjs +299 -0
- package/main/store/write-queue.mjs +14 -0
- package/main/store-modules.mjs +23 -0
- package/main/store.mjs +1269 -0
- package/main/supervisor.mjs +6875 -0
- package/main/task-commands.mjs +161 -0
- package/main/task-folders-offthread.mjs +84 -0
- package/main/task-folders-thread.mjs +13 -0
- package/main/task-folders.mjs +409 -0
- package/main/task-remote-control.mjs +65 -0
- package/main/task-terminals.mjs +169 -0
- package/main/terminal-access.mjs +6 -0
- package/main/updater.mjs +240 -0
- package/main/zoom-keys.mjs +54 -0
- package/main/zoom-readout.mjs +20 -0
- package/mcp/agentbox-mcp.sh +34 -0
- package/mcp/core/account.mjs +77 -0
- package/mcp/core/chat.mjs +61 -0
- package/mcp/core/documents.mjs +238 -0
- package/mcp/core/page.mjs +152 -0
- package/mcp/core/products.mjs +110 -0
- package/mcp/core/skills.mjs +126 -0
- package/mcp/core/work.mjs +377 -0
- package/mcp/stdio.mjs +70 -0
- package/mcp/tools.mjs +257 -0
- package/package.json +186 -0
- package/renderer/dist/assets/Geist-Variable-Bj2R_7yk.woff2 +0 -0
- package/renderer/dist/assets/GeistMono-Variable-Dispecij.woff2 +0 -0
- package/renderer/dist/assets/addon-fit-YJmn1quW.js +12 -0
- package/renderer/dist/assets/addon-serialize-CsFQTvP_.js +13 -0
- package/renderer/dist/assets/cel-dusk-CS5I7kJS.webp +0 -0
- package/renderer/dist/assets/cel-dusk-DUslqS6B.webp +0 -0
- package/renderer/dist/assets/cel-dusk-Jt_xVGxp.webp +0 -0
- package/renderer/dist/assets/cel-dusk-sm-BBkV-tWT.webp +0 -0
- package/renderer/dist/assets/frost-haze-CxPSOBEg.webp +0 -0
- package/renderer/dist/assets/frost-haze-sm-C_w21qgd.webp +0 -0
- package/renderer/dist/assets/gouache-valley-ChSu14-t.webp +0 -0
- package/renderer/dist/assets/gouache-valley-d9qasI6k.webp +0 -0
- package/renderer/dist/assets/gouache-valley-sm-CdLjT5Ec.webp +0 -0
- package/renderer/dist/assets/ice-BC8luINc.webp +0 -0
- package/renderer/dist/assets/ice-CP9PrKHo.webp +0 -0
- package/renderer/dist/assets/ice-river-D6ziOhLY.webp +0 -0
- package/renderer/dist/assets/ice-river-UVM2-JY_.webp +0 -0
- package/renderer/dist/assets/ice-river-bErJwYWW.webp +0 -0
- package/renderer/dist/assets/ice-river-sm-Bg1U-SIj.webp +0 -0
- package/renderer/dist/assets/ice-sm-CbVcg3_D.webp +0 -0
- package/renderer/dist/assets/index-CwiDv5bL.css +32 -0
- package/renderer/dist/assets/index-D9hCAVPl.js +684 -0
- package/renderer/dist/assets/lake-C0WaW-6E.webp +0 -0
- package/renderer/dist/assets/lake-CSKjLC5K.webp +0 -0
- package/renderer/dist/assets/lake-ETGcOb25.webp +0 -0
- package/renderer/dist/assets/lake-harbour-BCQRbrHb.webp +0 -0
- package/renderer/dist/assets/lake-harbour-B_wfXTmE.webp +0 -0
- package/renderer/dist/assets/lake-harbour-Te1pEvBh.webp +0 -0
- package/renderer/dist/assets/lake-harbour-sm-Cme_ShEg.webp +0 -0
- package/renderer/dist/assets/lake-sm-CbG72Hbv.webp +0 -0
- package/renderer/dist/assets/lino-coast-CUZHcucI.webp +0 -0
- package/renderer/dist/assets/lino-coast-DP4J7cgd.webp +0 -0
- package/renderer/dist/assets/lino-coast-kOIAffr_.webp +0 -0
- package/renderer/dist/assets/lino-coast-sm-C1Mdbgit.webp +0 -0
- package/renderer/dist/assets/moon-pines-BskgnnXR.webp +0 -0
- package/renderer/dist/assets/moon-pines-CFSIIwt0.webp +0 -0
- package/renderer/dist/assets/moon-pines-PNhdOYww.webp +0 -0
- package/renderer/dist/assets/moon-pines-sm-C6K1NomK.webp +0 -0
- package/renderer/dist/assets/orbit-rings-2XV36Ch3.webp +0 -0
- package/renderer/dist/assets/orbit-rings-C4NrcYGQ.webp +0 -0
- package/renderer/dist/assets/orbit-rings-DGLk07dT.webp +0 -0
- package/renderer/dist/assets/orbit-rings-sm-Dky3YdvL.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-C6f7xnWw.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-sm-Dj_Ez_Sb.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-DQjqMROg.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-Dw71H_bc.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-kOZfm-GM.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-sm-Dturjuky.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C296JVMO.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C4oMRDSx.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-CqVmQ4eh.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-sm-CHagC_nO.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-C6LYu6uE.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-CIUCEESs.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-sm-BnE0F_w-.webp +0 -0
- package/renderer/dist/assets/riso-hills-7heKVtry.webp +0 -0
- package/renderer/dist/assets/riso-hills-CIjAL3J6.webp +0 -0
- package/renderer/dist/assets/riso-hills-sm-DHsnbCfP.webp +0 -0
- package/renderer/dist/assets/slate-haze-BPWdkNsw.webp +0 -0
- package/renderer/dist/assets/slate-haze-sm-B0Cb5a2W.webp +0 -0
- package/renderer/dist/assets/source-sans-3-cyrillic-ext-wght-normal-DzyfIafT.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-cyrillic-wght-normal-BMDVbyM7.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-greek-ext-wght-normal-BWSLJLk6.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-greek-wght-normal-C9H9m1vD.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-latin-ext-wght-normal-C8iNium2.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-latin-wght-normal-BqRLTx4X.woff2 +0 -0
- package/renderer/dist/assets/source-sans-3-vietnamese-wght-normal-C1uRvKPU.woff2 +0 -0
- package/renderer/dist/assets/valley-haze-BDHPqoJy.webp +0 -0
- package/renderer/dist/assets/valley-haze-sm-CTyjmPAG.webp +0 -0
- package/renderer/dist/assets/vector-dunes-DzzWLdKo.webp +0 -0
- package/renderer/dist/assets/vector-dunes-Yr9NBQUy.webp +0 -0
- package/renderer/dist/assets/vector-dunes-sm-D8MYY6ms.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BCGKN4u4.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BF-jk5MC.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-sm-Ds1xzTw9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-B1um67Z9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-DKQdYs32.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-sm-BJzNq8xh.webp +0 -0
- package/renderer/dist/assets/xterm-BT7tBf8A.js +27 -0
- package/renderer/dist/emulator/audio-rules.mjs +74 -0
- package/renderer/dist/emulator/data/compression/README.md +11 -0
- package/renderer/dist/emulator/data/compression/extract7z.js +1 -0
- package/renderer/dist/emulator/data/compression/extractzip.js +1 -0
- package/renderer/dist/emulator/data/compression/libunrar.js +519 -0
- package/renderer/dist/emulator/data/compression/libunrar.wasm +0 -0
- package/renderer/dist/emulator/data/cores/README.md +22 -0
- package/renderer/dist/emulator/data/cores/mgba-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/package.json +65 -0
- package/renderer/dist/emulator/data/cores/reports/mgba.json +1 -0
- package/renderer/dist/emulator/data/emulator.css +1614 -0
- package/renderer/dist/emulator/data/loader.js +170 -0
- package/renderer/dist/emulator/data/localization/README.md +63 -0
- package/renderer/dist/emulator/data/localization/af-FR.json +339 -0
- package/renderer/dist/emulator/data/localization/ar-AR.json +301 -0
- package/renderer/dist/emulator/data/localization/ben-BEN.json +301 -0
- package/renderer/dist/emulator/data/localization/de-GER.json +301 -0
- package/renderer/dist/emulator/data/localization/el-GR.json +301 -0
- package/renderer/dist/emulator/data/localization/en-US.json +339 -0
- package/renderer/dist/emulator/data/localization/es-ES.json +310 -0
- package/renderer/dist/emulator/data/localization/fa-AF.json +310 -0
- package/renderer/dist/emulator/data/localization/hi-HI.json +301 -0
- package/renderer/dist/emulator/data/localization/it-IT.json +302 -0
- package/renderer/dist/emulator/data/localization/ja-JA.json +301 -0
- package/renderer/dist/emulator/data/localization/jv-JV.json +301 -0
- package/renderer/dist/emulator/data/localization/ko-KO.json +336 -0
- package/renderer/dist/emulator/data/localization/pt-BR.json +361 -0
- package/renderer/dist/emulator/data/localization/retroarch.json +617 -0
- package/renderer/dist/emulator/data/localization/ro-RO.json +310 -0
- package/renderer/dist/emulator/data/localization/ru-RU.json +301 -0
- package/renderer/dist/emulator/data/localization/tr-TR.json +310 -0
- package/renderer/dist/emulator/data/localization/vi-VN.json +302 -0
- package/renderer/dist/emulator/data/localization/zh-CN.json +351 -0
- package/renderer/dist/emulator/data/src/GameManager.js +464 -0
- package/renderer/dist/emulator/data/src/compression.js +142 -0
- package/renderer/dist/emulator/data/src/emulator.js +6158 -0
- package/renderer/dist/emulator/data/src/gamepad.js +167 -0
- package/renderer/dist/emulator/data/src/nipplejs.js +1 -0
- package/renderer/dist/emulator/data/src/shaders.js +236 -0
- package/renderer/dist/emulator/data/src/socket.io.min.js +7 -0
- package/renderer/dist/emulator/data/src/storage.js +125 -0
- package/renderer/dist/emulator/data/version.json +5 -0
- package/renderer/dist/emulator/host.js +299 -0
- package/renderer/dist/emulator/index.html +28 -0
- package/renderer/dist/emulator/provenance.json +6 -0
- package/renderer/dist/fixtures/onboard/designs/w-n13/the-first-row.html +1 -0
- package/renderer/dist/index.html +13 -0
- package/scripts/after-install.mjs +59 -0
- package/scripts/approval-server.sh +43 -0
- package/scripts/before-publish.mjs +133 -0
- package/shared/agent-import.d.mts +13 -0
- package/shared/agent-import.mjs +252 -0
- package/shared/agents.d.mts +190 -0
- package/shared/agents.mjs +937 -0
- package/shared/analytics-events.mjs +63 -0
- package/shared/answers.d.mts +12 -0
- package/shared/answers.mjs +80 -0
- package/shared/artifact-keys.d.mts +28 -0
- package/shared/artifact-keys.mjs +140 -0
- package/shared/bridge-map.mjs +128 -0
- package/shared/claude-commands.d.mts +20 -0
- package/shared/claude-commands.generated.mjs +149 -0
- package/shared/claude-commands.mjs +131 -0
- package/shared/claude-models.generated.d.mts +15 -0
- package/shared/claude-models.generated.mjs +26 -0
- package/shared/claude-usage.d.mts +16 -0
- package/shared/claude-usage.mjs +172 -0
- package/shared/codex-commands.d.mts +4 -0
- package/shared/codex-commands.mjs +17 -0
- package/shared/codex-import.d.mts +38 -0
- package/shared/codex-import.mjs +232 -0
- package/shared/codex-modes.mjs +159 -0
- package/shared/codex-usage.mjs +180 -0
- package/shared/contracts.mjs +412 -0
- package/shared/crash-scrub.mjs +182 -0
- package/shared/dashboard.mjs +481 -0
- package/shared/dead-run-trace.mjs +127 -0
- package/shared/demo-world.mjs +415 -0
- package/shared/effort-levels.d.mts +15 -0
- package/shared/effort-levels.mjs +76 -0
- package/shared/engines.d.mts +62 -0
- package/shared/engines.mjs +389 -0
- package/shared/first-run-examples.mjs +60 -0
- package/shared/first-run-line.mjs +149 -0
- package/shared/first-run-practice.d.mts +32 -0
- package/shared/first-run-practice.mjs +254 -0
- package/shared/first-run-shape.mjs +100 -0
- package/shared/fresh-user-home.mjs +189 -0
- package/shared/hook-failure.mjs +22 -0
- package/shared/install-id.mjs +39 -0
- package/shared/instruction-defaults.json +5 -0
- package/shared/library-folder.mjs +28 -0
- package/shared/notify-rules.mjs +120 -0
- package/shared/product-name.d.mts +6 -0
- package/shared/product-name.mjs +144 -0
- package/shared/project-folder-check.d.mts +22 -0
- package/shared/project-folder-check.mjs +152 -0
- package/shared/provider-commands.d.mts +8 -0
- package/shared/provider-commands.mjs +58 -0
- package/shared/rank.d.mts +19 -0
- package/shared/rank.mjs +146 -0
- package/shared/recovery.mjs +26 -0
- package/shared/referenced-files.d.mts +11 -0
- package/shared/referenced-files.mjs +122 -0
- package/shared/repeats.d.mts +45 -0
- package/shared/repeats.mjs +193 -0
- package/shared/schemes.mjs +33 -0
- package/shared/settings-terminal.d.mts +1 -0
- package/shared/settings-terminal.mjs +14 -0
- package/shared/side-build.mjs +57 -0
- package/shared/spawn-trouble.d.mts +8 -0
- package/shared/spawn-trouble.mjs +599 -0
- package/shared/terminal-state.d.mts +1 -0
- package/shared/terminal-state.mjs +58 -0
- package/shared/usage.d.mts +53 -0
- package/shared/usage.mjs +319 -0
- package/shared/work-items.mjs +561 -0
- package/shared/work-lines.mjs +360 -0
- package/worker-permissions.json +6 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
// PURE. WHAT A TOOL CALL SAYS ON HER SCREEN —, 2026-08-20.
|
|
2
|
+
//
|
|
3
|
+
// WHAT MESSY ACTUALLY WAS, measured over her seven live imported sessions on
|
|
4
|
+
// 2026-08-20, off the drawn screen and not off the source:
|
|
5
|
+
//
|
|
6
|
+
// 535 work lines in 162 runs 328 of them (61%) ran past the end of their box
|
|
7
|
+
// and were cut by the ellipsis, so she could not read them at all 368 of them
|
|
8
|
+
// (69%) were over sixty characters the six worst showed 2% to 4% of
|
|
9
|
+
// themselves; every one of those was `cd /Users/you/Desktop/dev/... &&
|
|
10
|
+
// python3 - <<'PY' ...` 18 distinct raw tool names were printed as verbs, the
|
|
11
|
+
// worst being `mcp__plugin_paper-desktop_paper__write_html`, 31 times in one
|
|
12
|
+
// thread the longest unbroken run was 20 lines, and that happened three times
|
|
13
|
+
//
|
|
14
|
+
// So there are three separate defects wearing one word, and this file is the
|
|
15
|
+
// three answers.
|
|
16
|
+
//
|
|
17
|
+
// ONE. THE INTERESTING PART OF A COMMAND IS NEVER AT THE FRONT. Every one of
|
|
18
|
+
// the six worst lines was a real command hiding behind a `cd` into an absolute
|
|
19
|
+
// path, or an `export PATH=` prelude, or both. Truncating from the right, which
|
|
20
|
+
// is what an ellipsis does, therefore threw away the only part she wanted and
|
|
21
|
+
// kept the part every line shares. `plainCommand` drops the prelude instead, so
|
|
22
|
+
// the line STARTS at the thing that ran.
|
|
23
|
+
//
|
|
24
|
+
// TWO. A PATH IS SHOWN FROM THE END. `/Users/you/Desktop/dev/zero/
|
|
25
|
+
// renderer/src/components/Tweaks.tsx` is 63 characters of which the last 11 are
|
|
26
|
+
// the answer. Under the session's own folder it becomes
|
|
27
|
+
// `renderer/src/components/Tweaks.tsx`; deeper than that it keeps the last
|
|
28
|
+
// three segments behind a leading ellipsis. Nothing is invented and nothing is
|
|
29
|
+
// silently dropped: the whole string is one press away on the line itself.
|
|
30
|
+
//
|
|
31
|
+
// THREE. A RUN AGGREGATES, WHICH IS THE WORD SHE USED. Consecutive tool calls
|
|
32
|
+
// fold into one line that says how many and what kind. The threshold is three
|
|
33
|
+
// and it is measured, not chosen: her run-length histogram is
|
|
34
|
+
// {1:38, 2:42, 3:36, 4:18, 5:6, 6:6, 7:8, 8:2, 11:2, 13:1, 20:3}. Folding at
|
|
35
|
+
// two takes the screen down 70% and folding at three takes it down 62%, so the
|
|
36
|
+
// last eight points cost her the 42 pairs, and a pair read as two short clean
|
|
37
|
+
// lines says more than "2 things it ran" does. Three is where a wall starts.
|
|
38
|
+
//
|
|
39
|
+
// NOTHING HERE HIDES A FAILURE. A folded run says on its own line that
|
|
40
|
+
// something in it failed, in the same words and the same colour a single line
|
|
41
|
+
// would, because a fold she has to open to find bad news in is worse than the
|
|
42
|
+
// wall it replaced.
|
|
43
|
+
|
|
44
|
+
/* ------------------------------ WHAT IT DID ------------------------------- */
|
|
45
|
+
// HER WORDS AND NOT OUR TOOL NAMES. The design law forbids jargon in UI copy,
|
|
46
|
+
// so "Bash" and "Glob" are ours, not hers.
|
|
47
|
+
const VERBS = {
|
|
48
|
+
Bash: 'ran',
|
|
49
|
+
Read: 'read',
|
|
50
|
+
Write: 'wrote',
|
|
51
|
+
Edit: 'edited',
|
|
52
|
+
MultiEdit: 'edited',
|
|
53
|
+
NotebookEdit: 'edited',
|
|
54
|
+
Glob: 'looked for',
|
|
55
|
+
Grep: 'searched for',
|
|
56
|
+
WebFetch: 'fetched',
|
|
57
|
+
WebSearch: 'searched the web for',
|
|
58
|
+
Task: 'sent off a helper',
|
|
59
|
+
TodoWrite: 'kept its list',
|
|
60
|
+
ListAgents: 'listed the other sessions',
|
|
61
|
+
SendMessage: 'messaged',
|
|
62
|
+
ToolSearch: 'looked up a tool',
|
|
63
|
+
// Measured in her own threads on 2026-08-20 and printed raw until now:
|
|
64
|
+
// `skill` 3 times and `askuserquestion` twice, both as bare lowercase names.
|
|
65
|
+
Skill: 'used a skill',
|
|
66
|
+
AskUserQuestion: 'asked a question',
|
|
67
|
+
BashOutput: 'checked on a command',
|
|
68
|
+
KillShell: 'stopped a command',
|
|
69
|
+
ExitPlanMode: 'finished planning',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// THE PREFIX STRIP WAS BROKEN AND HER LONGEST THREAD IS WHERE IT SHOWED. The
|
|
73
|
+
// old pattern was `^mcp__[^_]+__`, which needs the server's name to hold no
|
|
74
|
+
// underscore. `mcp__plugin_paper-desktop_paper__write_html` went through
|
|
75
|
+
// untouched and she read that string 31 times in one afternoon. An MCP name is
|
|
76
|
+
// `mcp__<server>__<tool>` and a server may contain anything, so the tool is
|
|
77
|
+
// what follows the LAST double underscore.
|
|
78
|
+
export function workVerb(name) {
|
|
79
|
+
const n = String(name ?? '').trim();
|
|
80
|
+
if (!n) return 'did something';
|
|
81
|
+
if (VERBS[n]) return VERBS[n];
|
|
82
|
+
const mcp = n.startsWith('mcp__') ? n.slice(n.lastIndexOf('__') + 2) : n;
|
|
83
|
+
// Underscores are how a machine spells a space. She reads the result, so it
|
|
84
|
+
// gets the space: `list_work_items` is jargon and `list work items` is a
|
|
85
|
+
// name, which is all this line has ever claimed to be.
|
|
86
|
+
return mcp.replace(/_+/g, ' ').trim().toLowerCase() || 'did something';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* ------------------------------ A PATH, SHORT ----------------------------- */
|
|
90
|
+
// From the END, because that is where the answer is. Three segments is the
|
|
91
|
+
// budget: measured over her 535 lines, three segments holds the whole of every
|
|
92
|
+
// path that sits inside a repo and the meaningful tail of every scratch path.
|
|
93
|
+
const PATH_SEGMENTS = 3;
|
|
94
|
+
|
|
95
|
+
// `home` IS THE MACHINE'S, AND IT HAS NO DEFAULT. It used to default to
|
|
96
|
+
// `/Users/you`, which meant every path this shortened was shortened correctly
|
|
97
|
+
// on exactly one Mac in the world. Agentbox is downloaded now: on anybody
|
|
98
|
+
// else's, `~/notes.md` came out as `/Users/leon/notes.md`, which is the
|
|
99
|
+
// prefix-only line this whole file exists to stop. Nothing is guessed when
|
|
100
|
+
// nobody says whose Mac it is; the path is shown whole, which is worse than a
|
|
101
|
+
// tilde and is at least true.
|
|
102
|
+
export function shortPath(raw, cwd = '', home = '') {
|
|
103
|
+
const s = String(raw ?? '').trim();
|
|
104
|
+
if (!s) return '';
|
|
105
|
+
if (!s.startsWith('/') && !s.startsWith('~')) return s;
|
|
106
|
+
|
|
107
|
+
let p = s;
|
|
108
|
+
// `/private/tmp` and `/tmp` are the same folder on a Mac and she has never
|
|
109
|
+
// typed either. Saying `/private` first is the filesystem talking.
|
|
110
|
+
p = p.replace(/^\/private\/tmp\//, '/tmp/');
|
|
111
|
+
|
|
112
|
+
// Inside the folder this session is running in, a path is what she would
|
|
113
|
+
// type: relative, with nothing above it.
|
|
114
|
+
const base = String(cwd ?? '').replace(/^\/private\/tmp\//, '/tmp/').replace(/\/+$/, '');
|
|
115
|
+
if (base && (p === base || p.startsWith(`${base}/`))) {
|
|
116
|
+
const rel = p === base ? '' : p.slice(base.length + 1);
|
|
117
|
+
return rel ? trimSegments(rel) : './';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const h = String(home ?? '').replace(/\/+$/, '');
|
|
121
|
+
if (h && p.startsWith(`${h}/`)) p = `~/${p.slice(h.length + 1)}`;
|
|
122
|
+
|
|
123
|
+
return trimSegments(p);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Keep the last few segments and say, with an ellipsis, that there were more.
|
|
127
|
+
// The leading `…/` is the whole of the honesty here: a bare `components/
|
|
128
|
+
// Tweaks.tsx` would read as a path from the root of something.
|
|
129
|
+
function trimSegments(p) {
|
|
130
|
+
// The lead is kept whole when nothing is trimmed, because `/x/store.mjs` and
|
|
131
|
+
// `x/store.mjs` are two different files and dropping the slash would be this
|
|
132
|
+
// function quietly saying the wrong one.
|
|
133
|
+
const lead = p.startsWith('~/') ? '~/' : p.startsWith('/') ? '/' : '';
|
|
134
|
+
const body = p.slice(lead.length);
|
|
135
|
+
const parts = body.split('/').filter(Boolean);
|
|
136
|
+
if (parts.length <= PATH_SEGMENTS) return lead + parts.join('/');
|
|
137
|
+
return `…/${parts.slice(-PATH_SEGMENTS).join('/')}`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* --------------------------- A COMMAND, PLAIN ----------------------------- */
|
|
141
|
+
// THE PRELUDE COMES OFF THE FRONT. Every shape below was counted in her own
|
|
142
|
+
// sessions on 2026-08-20; none of it is hypothetical.
|
|
143
|
+
//
|
|
144
|
+
// `cd /Users/you/Desktop/dev/zero && …` the commonest by far
|
|
145
|
+
// `export PATH="$HOME/.nvm/versions/node/…" ; …` 29 times in one thread
|
|
146
|
+
// `SP=/private/tmp/claude-501/-Users-…/… ; …` a bare assignment
|
|
147
|
+
// `source ~/.zshrc && …`
|
|
148
|
+
//
|
|
149
|
+
// Each is scaffolding that says nothing about what the agent was doing, and
|
|
150
|
+
// each is long enough on its own to fill the line. They come off one at a time
|
|
151
|
+
// until what is left is a command.
|
|
152
|
+
//
|
|
153
|
+
// WHAT IT NEVER DOES IS INVENT. If stripping leaves nothing, the original
|
|
154
|
+
// stands: an agent that genuinely only ran `cd somewhere` did that, and a line
|
|
155
|
+
// reading empty would be this function lying about it.
|
|
156
|
+
const PRELUDE = [
|
|
157
|
+
// cd <path> && |; | \n
|
|
158
|
+
/^cd\s+(?:"[^"]*"|'[^']*'|[^\s;&|]+)\s*(?:&&|;|\n)\s*/,
|
|
159
|
+
// export NAME=<value> && |; | \n (value may be quoted and may hold; or &)
|
|
160
|
+
/^export\s+[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s;&]*)\s*(?:&&|;|\n)\s*/,
|
|
161
|
+
// NAME=<value> && |; | \n (a bare assignment, same shapes)
|
|
162
|
+
/^[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s;&]*)\s*(?:&&|;|\n)\s*/,
|
|
163
|
+
// source|. <file> && |; | \n
|
|
164
|
+
/^(?:source|\.)\s+(?:"[^"]*"|'[^']*'|[^\s;&|]+)\s*(?:&&|;|\n)\s*/,
|
|
165
|
+
// echo "=== a banner ===" && |; | \n
|
|
166
|
+
//
|
|
167
|
+
// ONLY A BANNER, and the `===` or `---` is what makes it one. An agent
|
|
168
|
+
// labelling its own terminal output is talking to itself, and four of the 31
|
|
169
|
+
// worst lines left on her screen after the preludes came off were exactly
|
|
170
|
+
// this. A plain `echo something` is a real command and is left alone, because
|
|
171
|
+
// it may be the whole of what ran.
|
|
172
|
+
/^echo\s+(?:"[^"]*(?:===|---)[^"]*"|'[^']*(?:===|---)[^']*')\s*(?:&&|;|\n)\s*/,
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
// A heredoc is a whole script pretending to be an argument. The longest in her
|
|
176
|
+
// sessions was 84 lines of python inside one `ran`. Everything from the marker
|
|
177
|
+
// onward becomes an ellipsis, so the line says which program was fed a script
|
|
178
|
+
// without printing the script.
|
|
179
|
+
const HEREDOC = /<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1([\s\S]*)$/;
|
|
180
|
+
|
|
181
|
+
// EXCEPT WHEN THE PROGRAM IS THE WHOLE OF WHAT IS LEFT. Drawn over her own
|
|
182
|
+
// thread on 2026-08-20 the first cut put three `python3 - …` lines in a row
|
|
183
|
+
// inside one fold, which distinguishes nothing. In every one of those the file
|
|
184
|
+
// being worked on was named on the script's FIRST line, so when the command in
|
|
185
|
+
// front of the marker is this short the first line comes with it.
|
|
186
|
+
const HEREDOC_HEAD = 12;
|
|
187
|
+
|
|
188
|
+
function firstScriptLine(body, marker) {
|
|
189
|
+
for (const line of String(body ?? '').split('\n')) {
|
|
190
|
+
const t = line.trim();
|
|
191
|
+
// The marker itself closes the heredoc and is not a line of the script.
|
|
192
|
+
// Matched exactly, because a one-word line of script looks just like one.
|
|
193
|
+
if (!t || t === marker) continue;
|
|
194
|
+
if (t.startsWith('#') || t.startsWith('//')) continue;
|
|
195
|
+
return t;
|
|
196
|
+
}
|
|
197
|
+
return '';
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function plainCommand(raw) {
|
|
201
|
+
let s = String(raw ?? '').trim();
|
|
202
|
+
if (!s) return '';
|
|
203
|
+
const whole = s;
|
|
204
|
+
|
|
205
|
+
// Peel the scaffolding, repeatedly: `cd x && export Y=z && npm test` is all
|
|
206
|
+
// three of these in a row.
|
|
207
|
+
for (let i = 0; i < 6; i += 1) {
|
|
208
|
+
const before = s;
|
|
209
|
+
for (const re of PRELUDE) s = s.replace(re, '');
|
|
210
|
+
if (s === before) break;
|
|
211
|
+
}
|
|
212
|
+
const doc = s.match(HEREDOC);
|
|
213
|
+
if (doc) {
|
|
214
|
+
const head = s.slice(0, doc.index).trim();
|
|
215
|
+
const first = head.length <= HEREDOC_HEAD ? firstScriptLine(doc[3], doc[2]) : '';
|
|
216
|
+
s = first ? `${head} … ${first}` : `${head} …`;
|
|
217
|
+
}
|
|
218
|
+
s = s.replace(/\s+/g, ' ').trim();
|
|
219
|
+
return s || whole.replace(/\s+/g, ' ').trim();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ------------------------------- THE SUBJECT ------------------------------ */
|
|
223
|
+
// WHICH ONE THIS WAS, in as few characters as the truth allows. `cwd` is the
|
|
224
|
+
// folder the session is running in, which is what makes a path relative; it is
|
|
225
|
+
// optional so that nothing that calls this without one gets worse than before.
|
|
226
|
+
export function workSubject(input, cwd = '', home = '') {
|
|
227
|
+
const i = input ?? {};
|
|
228
|
+
if (i.command != null && String(i.command).trim()) {
|
|
229
|
+
return plainCommand(i.command);
|
|
230
|
+
}
|
|
231
|
+
const path = i.file_path ?? i.path ?? i.notebook_path;
|
|
232
|
+
if (path != null && String(path).trim()) return shortPath(path, cwd, home);
|
|
233
|
+
const raw = i.pattern ?? i.query ?? i.to ?? i.url ?? i.prompt ?? '';
|
|
234
|
+
return String(raw).replace(/\s+/g, ' ').trim();
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// THE WHOLE OF IT, for the line she opened. Nothing this file shortens is
|
|
238
|
+
// lost: the full string goes back on the screen above the output, and this is
|
|
239
|
+
// the function that says whether there is anything to put there.
|
|
240
|
+
export function fullSubject(input) {
|
|
241
|
+
const i = input ?? {};
|
|
242
|
+
const raw = i.command ?? i.file_path ?? i.path ?? i.notebook_path
|
|
243
|
+
?? i.pattern ?? i.query ?? i.to ?? i.url ?? i.prompt ?? '';
|
|
244
|
+
return String(raw).replace(/\s+$/, '');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/* -------------------------------- THE RUN --------------------------------- */
|
|
248
|
+
// AGGREGATE, HER WORD. Three or more consecutive tool calls fold into one line.
|
|
249
|
+
// Two do not, because two clean lines say more than a fold does and 42 of her
|
|
250
|
+
// 162 runs are exactly two.
|
|
251
|
+
export const RUN_MIN = 3;
|
|
252
|
+
|
|
253
|
+
export function groupWork(events, { min = RUN_MIN } = {}) {
|
|
254
|
+
const out = [];
|
|
255
|
+
let run = [];
|
|
256
|
+
const flush = () => {
|
|
257
|
+
if (!run.length) return;
|
|
258
|
+
if (run.length >= min) out.push({ kind: 'run', at: run[0].at ?? 0, items: run });
|
|
259
|
+
else out.push(...run);
|
|
260
|
+
run = [];
|
|
261
|
+
};
|
|
262
|
+
for (const e of events ?? []) {
|
|
263
|
+
if (e && e.kind === 'work') { run.push(e); continue; }
|
|
264
|
+
flush();
|
|
265
|
+
out.push(e);
|
|
266
|
+
}
|
|
267
|
+
flush();
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// WHAT THE FOLDED LINE SAYS. It says the number first, because the number is
|
|
272
|
+
// the thing a fold owes her: her standing objection to every cap in this
|
|
273
|
+
// codebase is a total that was rounded off without saying so.
|
|
274
|
+
//
|
|
275
|
+
// one verb, and one we have a plain word for `20 things it ran`
|
|
276
|
+
// one verb we do not `31 things it did · write html 31`
|
|
277
|
+
// several `24 things it did · ran 18 · read 4 · edited 2`
|
|
278
|
+
//
|
|
279
|
+
// Three verbs is the tally's budget; past that the rest is one more count, so
|
|
280
|
+
// the line never grows past what fits.
|
|
281
|
+
//
|
|
282
|
+
// A COUNT OF ONE IS NOT PRINTED. Drawn over her own threads on 2026-08-20 the
|
|
283
|
+
// first cut read `8 things it did · ran 5 · read 2 · asked a question 1`, and
|
|
284
|
+
// that trailing 1 reads as part of the name rather than as a number. A bare
|
|
285
|
+
// verb already says once.
|
|
286
|
+
const PLAIN = new Set(['ran', 'read', 'wrote', 'edited', 'looked for', 'searched for', 'fetched', 'messaged']);
|
|
287
|
+
const TALLY_VERBS = 3;
|
|
288
|
+
|
|
289
|
+
export function runSummary(items) {
|
|
290
|
+
const list = (items ?? []).filter(Boolean);
|
|
291
|
+
if (!list.length) return '';
|
|
292
|
+
const counts = new Map();
|
|
293
|
+
for (const e of list) counts.set(e.verb, (counts.get(e.verb) ?? 0) + 1);
|
|
294
|
+
const byCount = [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
|
|
295
|
+
|
|
296
|
+
if (byCount.length === 1 && PLAIN.has(byCount[0][0])) {
|
|
297
|
+
return `${list.length} thing${list.length === 1 ? '' : 's'} it ${byCount[0][0]}`;
|
|
298
|
+
}
|
|
299
|
+
const shown = byCount.slice(0, TALLY_VERBS).map(([v, n]) => (n === 1 ? v : `${v} ${n}`));
|
|
300
|
+
const rest = byCount.slice(TALLY_VERBS).reduce((s, [, n]) => s + n, 0);
|
|
301
|
+
if (rest) shown.push(`${rest} more`);
|
|
302
|
+
return `${list.length} things it did · ${shown.join(' · ')}`;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// THE BAD NEWS IS NEVER BEHIND THE FOLD. Said in her words on the closed line,
|
|
306
|
+
// in the one colour this surface uses.
|
|
307
|
+
export function runFailures(items) {
|
|
308
|
+
const bad = (items ?? []).filter((e) => e && e.failed).length;
|
|
309
|
+
if (!bad) return '';
|
|
310
|
+
return `${bad} failed`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* --------------------------- THE FILE IT CHANGED -------------------------- */
|
|
314
|
+
// A WORK LINE THAT SAYS IT CHANGED A FILE HANDS THE FILE OVER, so the thread
|
|
315
|
+
// can make it a chip.
|
|
316
|
+
//
|
|
317
|
+
// The same four tools main/code-change.mjs reads, and they have to stay the
|
|
318
|
+
// same four: one list saying which calls become a diff and another saying which
|
|
319
|
+
// lines become a chip is two lists that drift, and the symptom of the drift is
|
|
320
|
+
// a chip that opens onto a file the change does not hold.
|
|
321
|
+
export const CHANGES_A_FILE = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The path a tool call changed, whole and unshortened, or '' when it changed
|
|
325
|
+
* nothing. Whole because it is matched against the change's own list, and the
|
|
326
|
+
* shortened form on screen has had its front thrown away.
|
|
327
|
+
*/
|
|
328
|
+
export function changedFile(name, input) {
|
|
329
|
+
if (!CHANGES_A_FILE.has(String(name ?? ''))) return '';
|
|
330
|
+
const i = input ?? {};
|
|
331
|
+
return String(i.file_path ?? i.notebook_path ?? '').trim();
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Which entry of a change a path on a work line is, or null.
|
|
336
|
+
*
|
|
337
|
+
* A transcript records the ABSOLUTE path it wrote; a change records the path
|
|
338
|
+
* relative to one of the run's roots when it sits under one, and the absolute
|
|
339
|
+
* path when it does not (main/code-change.mjs). So the two shapes have to meet,
|
|
340
|
+
* and matching on the tail is what makes them: the change's key is either the
|
|
341
|
+
* whole string or a suffix of it at a segment boundary.
|
|
342
|
+
*
|
|
343
|
+
* The LONGEST match wins. `src/a.ts` and `renderer/src/a.ts` are different
|
|
344
|
+
* files and both are suffixes of the second one's absolute path; taking the
|
|
345
|
+
* first match would open whichever the change happened to list first.
|
|
346
|
+
*/
|
|
347
|
+
export function fileInChange(paths, raw) {
|
|
348
|
+
const p = String(raw ?? '').trim().replace(/^\/private\/tmp\//, '/tmp/');
|
|
349
|
+
if (!p) return null;
|
|
350
|
+
let best = null;
|
|
351
|
+
for (const key of paths ?? []) {
|
|
352
|
+
const k = String(key ?? '').trim();
|
|
353
|
+
if (!k) continue;
|
|
354
|
+
const hit = k === p || p.endsWith(`/${k}`)
|
|
355
|
+
|| k.replace(/^\/private\/tmp\//, '/tmp/') === p;
|
|
356
|
+
if (!hit) continue;
|
|
357
|
+
if (!best || k.length > best.length) best = key;
|
|
358
|
+
}
|
|
359
|
+
return best;
|
|
360
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"//": "Worker settings, passed per-spawn via --settings. It carries NO permission rules of our own, on purpose: workers run on Claude Code's own defaults for whatever mode they are in, the way Codex workers run on the Codex app's own posture (main/codex-session.mjs). Her words, w-6ade63e1aa, 2026-09-27: 'We just want to match Claude Code's and Codex's default settings. We typically don't want to have our own settings for things like this.' This used to ship allow Bash plus a 28-entry ask list. In auto mode Claude Code drops a blanket Bash allow and still forces a prompt on every ask rule, so the list did nothing but add cards: on w-60f57bec36, 10 of 10 cards in nine minutes were `vercel` commands it named. additionalDirectories is EMPTY ON PURPOSE and is filled in at spawn time by Supervisor.writeWorkerSettings with this person's own store root: it used to name one developer's home folder, which shipped inside the download and granted every stranger's agents a directory that does not exist on their Mac (w-24fa146714, 2026-08-23).",
|
|
3
|
+
"permissions": {
|
|
4
|
+
"additionalDirectories": []
|
|
5
|
+
}
|
|
6
|
+
}
|