frizz 0.2.0 → 0.4.0
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/README.md +25 -20
- package/dist/claude-agent-broker.js +72 -27
- package/dist/dev-child.js +8302 -4628
- package/dist/frizz.js +1302 -701
- package/package.json +10 -4
- package/runtime/cc-worker/.claude-plugin/plugin.json +1 -1
- package/runtime/cc-worker/DECISIONS.md +81 -4
- package/runtime/cc-worker/bin/frizz-mcp.mjs +472 -58
- package/runtime/cc-worker/hooks/agent-dispatch.mjs +1 -1
- package/runtime/cc-worker/hooks/deny-plan.mjs +1 -1
- package/runtime/cc-worker/hooks/hooks.json +0 -7
- package/runtime/cc-worker/hooks/precompact-instructions.mjs +39 -28
- package/runtime/cc-worker/hooks/scratchpad.mjs +142 -169
- package/runtime/cc-worker/hooks/session-seed.mjs +16 -15
- package/runtime/cc-worker/skills/waits/SKILL.md +2 -2
- package/web-dist/apple-touch-icon.png +0 -0
- package/web-dist/assets/{TerminalPane-ROKHp1ib.js → TerminalPane-sd3XXjx5.js} +2 -2
- package/web-dist/assets/{abnfDiagram-VRR7QNED-DcpdhBs3.js → abnfDiagram-VRR7QNED-Bry_FIqg.js} +1 -1
- package/web-dist/assets/architecture-TIHT7OUA-CoMJQ5Ya.js +1 -0
- package/web-dist/assets/{architectureDiagram-ZJ3FMSHR-CUAKf0mn.js → architectureDiagram-ZJ3FMSHR-Baok4OeI.js} +1 -1
- package/web-dist/assets/{blockDiagram-677ZJIJ3-BPwpJIzx.js → blockDiagram-677ZJIJ3-BgHIO9lI.js} +1 -1
- package/web-dist/assets/{c4Diagram-LMCZKHZV-1lptuHzZ.js → c4Diagram-LMCZKHZV-rfj9Z17Z.js} +1 -1
- package/web-dist/assets/channel-D6uS1y7I.js +1 -0
- package/web-dist/assets/{chunk-32BRIVSS-CFR9AKjY.js → chunk-32BRIVSS-BwaHfK1Y.js} +1 -1
- package/web-dist/assets/{chunk-52WLFC77-CM9uct7m.js → chunk-52WLFC77-BmdQDZOA.js} +1 -1
- package/web-dist/assets/{chunk-C7G6YPKG-DiveJARw.js → chunk-C7G6YPKG-ByQFjoZe.js} +1 -1
- package/web-dist/assets/{chunk-EX3LRPZG-BE1CBw8F.js → chunk-EX3LRPZG-DQFudBKr.js} +1 -1
- package/web-dist/assets/{chunk-FWX5IMBZ-DL42uXiO.js → chunk-FWX5IMBZ-OW9qEPiq.js} +2 -2
- package/web-dist/assets/{chunk-HOUHSVGY-DPhJWgDw.js → chunk-HOUHSVGY-BdKLF8nO.js} +1 -1
- package/web-dist/assets/{chunk-ICXQ74PX-CwYy-6AP.js → chunk-ICXQ74PX-C1roqKR1.js} +1 -1
- package/web-dist/assets/{chunk-MOJQB5TN-Ds5I9wxq.js → chunk-MOJQB5TN-Cx0u1ZDK.js} +1 -1
- package/web-dist/assets/{chunk-OGEWGWER-DHiZJwQD.js → chunk-OGEWGWER-rxv9xtNR.js} +1 -1
- package/web-dist/assets/{chunk-PUDLZKDR-B-eyQTsF.js → chunk-PUDLZKDR-BXWPPPPi.js} +1 -1
- package/web-dist/assets/{chunk-Q4XR5HBZ-DK7dB3Ti.js → chunk-Q4XR5HBZ-CpqbD101.js} +1 -1
- package/web-dist/assets/{chunk-V7JOEXUC-Dn59m74L.js → chunk-V7JOEXUC-CP8_3qVt.js} +1 -1
- package/web-dist/assets/{chunk-VAUOI2AC-DK7x36hd.js → chunk-VAUOI2AC-Dl7xahpk.js} +1 -1
- package/web-dist/assets/{chunk-VR4S4FIN-D7-CI3Yl.js → chunk-VR4S4FIN-BKtMX64l.js} +1 -1
- package/web-dist/assets/{chunk-WYO6CB5R-B3l-mLCs.js → chunk-WYO6CB5R-DmLOdJcu.js} +1 -1
- package/web-dist/assets/{chunk-ZGVPDNZ5-Dobxlxie.js → chunk-ZGVPDNZ5-5wN7eXvS.js} +1 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-BW5YiBf4.js +1 -0
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-BW5YiBf4.js +1 -0
- package/web-dist/assets/{cynefin-VYW2F7L2-Dh7RuEUJ.js → cynefin-VYW2F7L2-DUYahBXb.js} +1 -1
- package/web-dist/assets/{cynefinDiagram-TSTJHNR4-ClPi2mZZ.js → cynefinDiagram-TSTJHNR4-Rm0i30nE.js} +1 -1
- package/web-dist/assets/{dagre-VKFMJZFB-52_WP1QV.js → dagre-VKFMJZFB-3uhsB-W3.js} +1 -1
- package/web-dist/assets/{diagram-FQU43EPY-D_1zVsTL.js → diagram-FQU43EPY-BUvflNRQ.js} +1 -1
- package/web-dist/assets/{diagram-G47NLZAW-CdZxuGUy.js → diagram-G47NLZAW-DUluIZel.js} +1 -1
- package/web-dist/assets/{diagram-NH7WQ7WH-C8pSFu0P.js → diagram-NH7WQ7WH-BBrwsbed.js} +1 -1
- package/web-dist/assets/{diagram-OA4YK3LP-C5bjZLre.js → diagram-OA4YK3LP-DWnTQBw4.js} +1 -1
- package/web-dist/assets/{diagram-WEI45ONY-Bxzhiuzn.js → diagram-WEI45ONY-BjEavoC0.js} +1 -1
- package/web-dist/assets/{ebnfDiagram-CCIWWBDH-g-Z0J2wP.js → ebnfDiagram-CCIWWBDH-CW4xZAZH.js} +1 -1
- package/web-dist/assets/{erDiagram-Q63AITRT-DVNkgIHp.js → erDiagram-Q63AITRT-BemQ1R4B.js} +1 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-BF5KB7ja.js +1 -0
- package/web-dist/assets/flowDiagram-23GEKE2U-BYo4Eytx.js +1 -0
- package/web-dist/assets/{ganttDiagram-NO4QXBWP-_71pQYEK.js → ganttDiagram-NO4QXBWP-lDdG5I_z.js} +1 -1
- package/web-dist/assets/{gitGraph-TEB2WS4Q-ChIZiGZS.js → gitGraph-TEB2WS4Q-Bw87a_Se.js} +1 -1
- package/web-dist/assets/{gitGraphDiagram-IHSO6WYX-DCHAFI0l.js → gitGraphDiagram-IHSO6WYX-B762r0yi.js} +1 -1
- package/web-dist/assets/index-B3QArXu2.css +1 -0
- package/web-dist/assets/index-CAapfhMv.js +365 -0
- package/web-dist/assets/{info-DKCQHKI2-BW-n_T1j.js → info-DKCQHKI2-DGOv6Gx0.js} +1 -1
- package/web-dist/assets/{infoDiagram-FWYZ7A6U-CgDYsKi9.js → infoDiagram-FWYZ7A6U-DL92kAzf.js} +1 -1
- package/web-dist/assets/{ishikawaDiagram-FXEZZL3T-ClzGNt9N.js → ishikawaDiagram-FXEZZL3T-CFYd4OtU.js} +1 -1
- package/web-dist/assets/{journeyDiagram-5HDEW3XC-DSCQxkHC.js → journeyDiagram-5HDEW3XC-QHuYL5zq.js} +1 -1
- package/web-dist/assets/{kanban-definition-HUTT4EX6-CdrdX9N8.js → kanban-definition-HUTT4EX6-DwmMluQ8.js} +1 -1
- package/web-dist/assets/{line-ha38Dc-1.js → line-Je_PFFHm.js} +1 -1
- package/web-dist/assets/{mermaid-parser.core-Z4uMcpip.js → mermaid-parser.core-BeiGWsn3.js} +3 -3
- package/web-dist/assets/{mermaid.core-iZRq3hbu.js → mermaid.core-BP8JrW48.js} +3 -3
- package/web-dist/assets/{mindmap-definition-LN4V7U3C-DmhInJO_.js → mindmap-definition-LN4V7U3C-BsmjCIrM.js} +1 -1
- package/web-dist/assets/{packet-7NZHBO7P-DBPB36Kl.js → packet-7NZHBO7P-D6ekYYGJ.js} +1 -1
- package/web-dist/assets/{pegDiagram-2B236MQR-CAH3ljfj.js → pegDiagram-2B236MQR-CQc2Kt0u.js} +1 -1
- package/web-dist/assets/{pie-RZYD4A2V-_h_eX4Ca.js → pie-RZYD4A2V-C_45fO8J.js} +1 -1
- package/web-dist/assets/{pieDiagram-ENE6RG2P-DFBPus8j.js → pieDiagram-ENE6RG2P-Dg5z6iWt.js} +1 -1
- package/web-dist/assets/{quadrantDiagram-ABIIQ3AL-DMvOCjt8.js → quadrantDiagram-ABIIQ3AL-c7gZxuCX.js} +1 -1
- package/web-dist/assets/{radar-I7S5WNFK-2EzoPHEZ.js → radar-I7S5WNFK-D80XNJQq.js} +1 -1
- package/web-dist/assets/{railroad-3IZDKUUU-BPJnn-hm.js → railroad-3IZDKUUU-Brz7eZQ0.js} +1 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-D44pcGhJ.js +1 -0
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-CiWVH5SP.js +1 -0
- package/web-dist/assets/railroad-peg-LSFZ7HO6-Cy1B6-pN.js +1 -0
- package/web-dist/assets/{railroadDiagram-RFXS5EU6-DKq5FagA.js → railroadDiagram-RFXS5EU6-Db9K7bty.js} +1 -1
- package/web-dist/assets/{requirementDiagram-TGXJPOKE-BJ5tGazp.js → requirementDiagram-TGXJPOKE-m1ipMrDe.js} +1 -1
- package/web-dist/assets/{sankeyDiagram-HTMAVEWB-XSJjcBhX.js → sankeyDiagram-HTMAVEWB-4Zz9ry0k.js} +1 -1
- package/web-dist/assets/{sequenceDiagram-DBY2YBRQ-CBb8emSe.js → sequenceDiagram-DBY2YBRQ-CZeGHw4X.js} +1 -1
- package/web-dist/assets/{stateDiagram-2N3HPSRC-DDfRW94V.js → stateDiagram-2N3HPSRC-rLUVs1Pg.js} +1 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-w7QDFEvx.js +1 -0
- package/web-dist/assets/{swimlanes-5IMT3BWC-DvRYbkZi.js → swimlanes-5IMT3BWC-BAeBdscz.js} +1 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-UhdgWpNZ.js +8 -0
- package/web-dist/assets/{timeline-definition-FHXFAJF6-BNUa_DwI.js → timeline-definition-FHXFAJF6-DL0eWMF-.js} +1 -1
- package/web-dist/assets/{treeView-QDETBFTQ-I6-IW6nJ.js → treeView-QDETBFTQ-gEtzLMA8.js} +1 -1
- package/web-dist/assets/{treemap-6X3UGDF4-CWWmEUYJ.js → treemap-6X3UGDF4-CCym1Gz6.js} +1 -1
- package/web-dist/assets/{vennDiagram-L72KCM5P-DTDrPGLk.js → vennDiagram-L72KCM5P-cF97-nb5.js} +1 -1
- package/web-dist/assets/{wardley-OPB4EBWU-CNsdgXXA.js → wardley-OPB4EBWU-DQJHCGbM.js} +1 -1
- package/web-dist/assets/{wardleyDiagram-EHGQE667-YE0tq3Kh.js → wardleyDiagram-EHGQE667-0CnHzXLX.js} +1 -1
- package/web-dist/assets/{xychartDiagram-FW5EYKEG-D0ofMX8C.js → xychartDiagram-FW5EYKEG-9YDOp4m5.js} +1 -1
- package/web-dist/favicon-16.png +0 -0
- package/web-dist/favicon-32.png +0 -0
- package/web-dist/favicon.svg +17 -61
- package/web-dist/icon-192.png +0 -0
- package/web-dist/icon-512.png +0 -0
- package/web-dist/icon-maskable-512.png +0 -0
- package/web-dist/index.html +19 -8
- package/web-dist/manifest.webmanifest +3 -3
- package/runtime/cc-worker/hooks/scratchpad-stop.mjs +0 -125
- package/runtime/cc-worker/skills/handoff/SKILL.md +0 -209
- package/web-dist/assets/architecture-TIHT7OUA-CAviNivx.js +0 -1
- package/web-dist/assets/channel-CqKDIFQF.js +0 -1
- package/web-dist/assets/classDiagram-OUVF2IWQ-B_-6iXYY.js +0 -1
- package/web-dist/assets/classDiagram-v2-EOCWNBFH-B_-6iXYY.js +0 -1
- package/web-dist/assets/eventmodeling-45OFAUF4-MpmeH5YZ.js +0 -1
- package/web-dist/assets/flowDiagram-23GEKE2U-D-QgjjhF.js +0 -1
- package/web-dist/assets/index-w4v-GZEc.js +0 -358
- package/web-dist/assets/index-zyi22LPz.css +0 -1
- package/web-dist/assets/railroad-abnf-AHOZXSZD-YeUoiySk.js +0 -1
- package/web-dist/assets/railroad-ebnf-EBAXGLYW-Ddw1SuGG.js +0 -1
- package/web-dist/assets/railroad-peg-LSFZ7HO6-Dd8BOGeW.js +0 -1
- package/web-dist/assets/stateDiagram-v2-6OUMAXLB-hc41W5Lx.js +0 -1
- package/web-dist/assets/swimlanesDiagram-G3AALYLV-BZyGdgSG.js +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frizz",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A local web UI for running many coding agents at once",
|
|
6
6
|
"keywords": [
|
|
@@ -38,21 +38,27 @@
|
|
|
38
38
|
"frizz-dev:uninstall": "nub scripts/install-global-cli.mjs --uninstall",
|
|
39
39
|
"install:global": "nub scripts/install-global-cli.mjs",
|
|
40
40
|
"typecheck": "tsc -b packages/shared packages/rpc packages/server . && pnpm --filter @frizz/web typecheck",
|
|
41
|
-
"test": "nub
|
|
41
|
+
"test": "nub scripts/run-tests.mjs",
|
|
42
42
|
"prepack": "node ./scripts/prepare-package.mjs && node ./scripts/build-package.mjs && node ./scripts/publish-manifest.mjs --strip",
|
|
43
|
-
"postpack": "node ./scripts/publish-manifest.mjs --restore"
|
|
43
|
+
"postpack": "node ./scripts/publish-manifest.mjs --restore && node ./scripts/prepare-package.mjs --clean"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@parcel/watcher": "^2.5",
|
|
47
|
-
"node-pty": "^1.1"
|
|
47
|
+
"node-pty": "^1.1",
|
|
48
|
+
"qrcode-generator": "^2.0.4"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
51
|
"@types/node": "^24",
|
|
51
52
|
"esbuild": "^0.25.0",
|
|
53
|
+
"jsqr": "^1.4.0",
|
|
52
54
|
"puppeteer": "^25.3.0",
|
|
53
55
|
"typescript": "^5.7"
|
|
54
56
|
},
|
|
55
57
|
"pnpm": {
|
|
58
|
+
"overrides": {
|
|
59
|
+
"react": "19.2.7",
|
|
60
|
+
"react-dom": "19.2.7"
|
|
61
|
+
},
|
|
56
62
|
"onlyBuiltDependencies": [
|
|
57
63
|
"node-pty",
|
|
58
64
|
"@parcel/watcher",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frizz",
|
|
3
|
-
"description": "Worker-side frizz plugin for frizz-spawned sessions. Each session is a WORKER driving ONE effort (slug via env FRIZZ_THREAD): it SIGNALS through its final message (done, human/timer awaiting, question), keeps automatable waits active with Claude wait tools, and
|
|
3
|
+
"description": "Worker-side frizz plugin for frizz-spawned sessions. Each session is a WORKER driving ONE effort (slug via env FRIZZ_THREAD): it SIGNALS through its final message (done, human/timer awaiting, question), keeps automatable waits active with Claude wait tools, and keeps its own free-form scratch directory (.frizz/threads/<session-id>/). Supplies the frizz:<model>-<effort> sub-agent profiles (dispatch as frizz:opus-high, frizz:sonnet-medium, frizz:haiku, …), the on-demand frizz:gh skill, and hooks that seed the worker contract, enforce background/name-stripped sub-agent dispatch, and deny the interactive question/plan prompts (deny-ask, deny-plan) that would hang a dashboard worker. Hooks are inert unless FRIZZ_THREAD is set.",
|
|
4
4
|
"version": "0.1.10",
|
|
5
5
|
"author": { "name": "Colin McDonnell" },
|
|
6
6
|
"homepage": "https://github.com/colinhacks/frizz",
|
|
@@ -30,8 +30,8 @@ what was ported from the orchestrator `cc/` plugin, what was dropped, and why.
|
|
|
30
30
|
| Hook | Event | Ported from | What it does for a worker |
|
|
31
31
|
| --- | --- | --- | --- |
|
|
32
32
|
| `session-seed.mjs` | SessionStart (startup/resume/clear/compact) | cc `session-seed.mjs` | Injects the single-thread worker contract + the bound slug + its file path; re-grounds on compact. Also writes cc's `off` sentinel defensively (see interplay). |
|
|
33
|
-
| `precompact-instructions.mjs` | PreCompact (auto/manual) | new — no cc equivalent | Steers WHAT SURVIVES compaction: emits an editorial brief asking the summarizer to preserve the high-level approach (plan, alternatives rejected, rationale) at high fidelity, plus a closing "Re-grounding before continuing:" section naming the
|
|
34
|
-
| `scratchpad.mjs` | SessionStart (startup/resume/clear/compact) + PreCompact (auto/manual) + UserPromptSubmit + PostToolUse | new — no cc equivalent | Keeps
|
|
33
|
+
| `precompact-instructions.mjs` | PreCompact (auto/manual) | new — no cc equivalent | Steers WHAT SURVIVES compaction: emits an editorial brief asking the summarizer to preserve the high-level approach (plan, alternatives rejected, rationale) at high fidelity, plus a closing "Re-grounding before continuing:" section naming the thread's scratch-directory path and the files to re-read. **PLAIN STDOUT is the channel** — cc's usual `hookSpecificOutput` JSON would be handed to the summarizer as its literal instructions. Skips sub-agent contexts (the derived scratch-directory path is only guaranteed for the top-level worker). |
|
|
34
|
+
| `scratchpad.mjs` | SessionStart (startup/resume/clear/compact) + PreCompact (auto/manual) + UserPromptSubmit + PostToolUse | new — no cc equivalent | Keeps a worker aware of its per-thread scratch DIRECTORY (`.frizz/threads/<sid>/`). `--mode=session-start` NAMES the files in it on the context-losing sources (compact/resume/clear) — a listing, never their content — and otherwise teaches the arrangement (write a doc, then arm `post_compaction`); `--mode=precompact` (**plain stdout**) tells the summarizer those files exist so it carries their paths forward; `--mode=nudge` fires on BOTH UserPromptSubmit and PostToolUse (mid-turn — the one that matters for long autonomous turns) once context has grown past `STALE_TOKENS` since the last write. Both nudge channels share one state file, so mid-turn firing does not multiply reminders. NOT gated on `FRIZZ_THREAD`; `--via=project` marks the repo-local registration and defers to this one inside a frizz worker. |
|
|
35
35
|
| `agent-dispatch.mjs` | PreToolUse(Agent) | cc `agent-dispatch.mjs` | Enforces `run_in_background:true`, strips `name`/`team_name`, appends a worker-flavored orchestration epilogue. |
|
|
36
36
|
| `bash-background.mjs` | PreToolUse(Bash) | new | Denies a local shell job that escapes through `&` without a later `wait` or EXIT trap, including one hidden inside a command-position `bash -c '…'`. Shell job control bypasses Claude's task registry, so Frizz cannot track or wake it; self-contained probe concurrency, and a wrapper handed to another program (`ssh`/`docker run`/`limactl shell`), remain allowed. |
|
|
37
37
|
| `agent-bind.mjs` | PostToolUse(Agent) | cc `agent-bind.mjs` (verbatim behavior) | Records `agentId → thread` into `.frizz/.agent-bindings.jsonl` in cc's exact format, so a worker's THREAD-tagged helper renders on the frizz board's per-thread liveness. |
|
|
@@ -125,6 +125,23 @@ decision, not an artifact-portability implementation detail. A future isolation
|
|
|
125
125
|
which settings/auth surfaces are preserved before adding `--settings`, a config-home override, or a
|
|
126
126
|
global-plugin disable mechanism.
|
|
127
127
|
|
|
128
|
+
**2026-08-16 — the SDK broker had drifted off this policy, and is back on it.** The tmux transport
|
|
129
|
+
spawned a plain `claude`, which reads all three settings scopes, so the policy above held by default.
|
|
130
|
+
The Agent-SDK broker takes an explicit `settingSources` and the SDK's own default is `[]` — nothing at
|
|
131
|
+
all — so when the broker became the default Claude transport it read no config whatsoever. The
|
|
132
|
+
2026-07-26 fix restored `project` + `local` (the repo's `CLAUDE.md` / `AGENTS.md` / `.claude/skills`)
|
|
133
|
+
and left `user` out, on a rationale written into the code — "the operator's personal `~/.claude` config
|
|
134
|
+
is theirs, not something a dispatched worker should silently inherit" — that this record had already
|
|
135
|
+
rejected. The gap was invisible because everything it withheld fails QUIETLY: the operator's `env`
|
|
136
|
+
block (which is where an API-proxy front-end writes its base-URL/token pair, so a broker session
|
|
137
|
+
authenticates differently from the CLI in the same shell), `autoCompactWindow` (so sessions compacted
|
|
138
|
+
at the default threshold, not the configured one), `permissions`, `hooks` and `enabledPlugins`.
|
|
139
|
+
Measured against the maintainer's real config, one variable, observed through a project-scope hook:
|
|
140
|
+
`--setting-sources=project,local` reported their `env` block UNSET, `user,project,local` reported it
|
|
141
|
+
applied, both sessions exiting 0 with empty stderr. The default is now all three scopes — the same
|
|
142
|
+
thing a plain `claude` in the same cwd reads. A frizz thread is the operator's own session on their own
|
|
143
|
+
machine, so the surprising behavior was the divergence, not the inheritance.
|
|
144
|
+
|
|
128
145
|
## 2026-07-02: Stop hook removed
|
|
129
146
|
stop-flush.mjs is no longer wired (script kept for reference). User call: under frizz the
|
|
130
147
|
tailer/board already surface worker state live, and the block-until-file-edited nag forced even
|
|
@@ -273,10 +290,22 @@ defect, and arguably correct: an explicit human rule should beat a blanket polic
|
|
|
273
290
|
|
|
274
291
|
MARKER: `<stateDir>/perm-requests/<slug>.json` now carries `decision` / `rule` / `reason` / `command`
|
|
275
292
|
alongside the original fields. The tailer treats ONLY a deferred request as a human block (an
|
|
276
|
-
auto-resolved one must never card as "Needs you"), and surfaces the last
|
|
277
|
-
the only durable record an approval leaves anywhere, since allows are never written to the transcript.
|
|
293
|
+
auto-resolved one must never card as "Needs you"), and surfaces the last DENIAL as `permPolicy`.
|
|
278
294
|
A marker with no `decision` (an older plugin build) still blocks exactly as before.
|
|
279
295
|
|
|
296
|
+
APPROVALS ARE NOT SURFACED — reversed 2026-08-07. The tailer originally retained allows too, on the
|
|
297
|
+
reasoning that an approval leaves no other durable record (Claude Code renders "Allowed by
|
|
298
|
+
PermissionRequest hook" in the pane and writes nothing to the transcript), and Chat rendered them as
|
|
299
|
+
one quiet `Auto-approved <command> · rule <name>` line. The flaw was that `permPolicy` has no CLEAR:
|
|
300
|
+
the line stuck to the bottom of the thread permanently, so one routine `git status --short` read as
|
|
301
|
+
the thread's standing condition long after the turn that ran it (maintainer: *"This message just
|
|
302
|
+
showed up randomly, and now it's stuck showing up in the thread forever … it's fucking useless"*).
|
|
303
|
+
Nothing was blocked and nobody was waiting, so the visibility it bought was worth less than the
|
|
304
|
+
permanent noise. Denials keep the card: they are rare, they changed what the worker could do, and the
|
|
305
|
+
refusal also lands in the transcript, so the card is a pointer to something real rather than the only
|
|
306
|
+
copy of it. If approval visibility is ever wanted again it needs an EXPIRY (or a per-turn scope) —
|
|
307
|
+
re-adding the sticky line is not the fix.
|
|
308
|
+
|
|
280
309
|
VERIFICATION: `scripts/verify-perm-marker.mjs` runs the REAL hook the way Claude Code does and
|
|
281
310
|
asserts every branch. The allow path was additionally driven against a REAL interactive `claude` (it
|
|
282
311
|
cannot be exercised under `claude -p`, where PermissionRequest hooks do not fire).
|
|
@@ -1023,3 +1052,51 @@ The rule now LEADS both child-facing epilogues, with the collection paragraph ke
|
|
|
1023
1052
|
This is a PROMPT-level default, deliberately NOT the hook-level depth-2 DENY rejected on 2026-07-31 as too blunt: a dispatcher that genuinely wants a prong fanned out says so in the prompt and the child dispatches, unmodified. Also left alone: `workerPrompt.ts` — the root contract already authorizes fan-out *"when work genuinely decomposes"*, and the root is the one agent whose fan-out is wanted.
|
|
1024
1053
|
|
|
1025
1054
|
Pinned by a new test in `agent-dispatch-hook.test.ts` (the lead-with-the-default wording plus the re-hinged conditional) and one in `scratchpad-hook.test.ts` (the codex block).
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
## 2026-08-06: the canonical scratchpad is DELETED — a free scratch directory, and compaction recovery moves to the recurring prompt
|
|
1058
|
+
|
|
1059
|
+
Frizz provisioned one canonical `scratch.md` per thread and a `SessionStart` hook spliced its HEAD into
|
|
1060
|
+
the context window after every compaction. The argument for the injection was sound and is worth
|
|
1061
|
+
restating, because it is what any replacement has to answer: a bare "remember to read your scratchpad"
|
|
1062
|
+
routes recovery through a decision the model can skip, which is exactly the failure the pad existed to
|
|
1063
|
+
prevent.
|
|
1064
|
+
|
|
1065
|
+
It still lost, on three counts. It made a MAINTAINED FILE the price of admission for every worker,
|
|
1066
|
+
including the ones whose whole task was one edit. It needed a merge-only contract per backend to stop
|
|
1067
|
+
sub-agents clobbering the one document — an epilogue in `agent-dispatch.mjs`, a `--mode=subagent-start`
|
|
1068
|
+
epilogue for codex, a legend line in every provisioned pad, and a paragraph of the worker contract, all
|
|
1069
|
+
of it policing a hazard rather than removing it. And the injection was INVISIBLE to the operator, who
|
|
1070
|
+
could neither see what their worker would be handed nor change it.
|
|
1071
|
+
|
|
1072
|
+
**What replaced it, maintainer's design:** the thread gets `.frizz/threads/<session-id>/` as a free-form
|
|
1073
|
+
scratch DIRECTORY — nothing provisioned into it, no reserved filename, no format — and compaction
|
|
1074
|
+
recovery moves to `mcp__frizz__recurring_prompt`'s new POST-COMPACTION trigger (scheduler SOURCE 7,
|
|
1075
|
+
landed the same day). The worker writes whatever doc it likes and LINKS it in the prompt; frizz re-sends
|
|
1076
|
+
that text the instant the context is summarized away. Durable in SQLite, visible and editable in the
|
|
1077
|
+
thread footer, and the worker chooses what it gets back.
|
|
1078
|
+
|
|
1079
|
+
The sub-agent story falls out for free: **one file per writer**. There is nothing to merge, so there is
|
|
1080
|
+
nothing to clobber, and the entire merge contract is deleted rather than reworded. Both child epilogues
|
|
1081
|
+
now say "write your OWN file; never edit or delete a file another agent wrote". The delegated-authority
|
|
1082
|
+
carve-out ("write only <path>" must not forbid the child's own coordination file) MOVED out of the
|
|
1083
|
+
worker contract and into the two epilogues that actually reach a child — it is pinned in
|
|
1084
|
+
`agent-dispatch-hook.test.ts` and `scratchpad-hook.test.ts` rather than in the contract goldens.
|
|
1085
|
+
|
|
1086
|
+
**The accepted cost, stated plainly rather than engineered around.** The maintainer chose this over a
|
|
1087
|
+
hybrid that kept a canonical doc, knowing compaction recovery degrades from a guaranteed injection to a
|
|
1088
|
+
pointer the model can skip. So the hook now NAMES the files in the directory and never their content
|
|
1089
|
+
(`scratchpad-hook.test.ts` pins that a body written into a scratch file does not appear in the
|
|
1090
|
+
injection). Re-growing that listing back into a content injection would restore exactly what was
|
|
1091
|
+
removed. The guaranteed channel is the arming, and every surface that mentions the directory also
|
|
1092
|
+
mentions `post_compaction: true`, because a folder nothing ever reads back is a folder of notes nobody
|
|
1093
|
+
opens.
|
|
1094
|
+
|
|
1095
|
+
**Two migrations that cost nothing.** `discover.ts`'s transcript-recovery sentinel shortened from
|
|
1096
|
+
`threads/<id>/scratch.md` to `threads/<id>/` — the new string is a PREFIX of the old one, so every
|
|
1097
|
+
transcript written before today still matches and no live thread lost its recovery path (pinned by
|
|
1098
|
+
`discover.test.ts`). And the Doc tab now renders the directory: files concatenated under a heading
|
|
1099
|
+
each, newest first, dotfiles excluded (frizz's own `.scratchpad-state.json` is not the worker's notes),
|
|
1100
|
+
binaries named rather than inlined, with per-file and total caps that say when they truncated. It is
|
|
1101
|
+
gated on the directory being NON-EMPTY rather than merely present, since dispatch now creates it empty
|
|
1102
|
+
and "exists" stopped meaning "the worker wrote something".
|