@junghanacs/entwurf 0.12.2 → 0.12.3

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.
Files changed (37) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +24 -0
  3. package/README.md +3 -5
  4. package/VERIFY.md +4 -4
  5. package/demo/README.md +5 -5
  6. package/demo/demo-baseline.sh +2 -2
  7. package/demo/demo.sh +3 -3
  8. package/docs/setup-clean-host.md +5 -5
  9. package/package.json +9 -9
  10. package/pi/entwurf-targets.json +3 -6
  11. package/pi-extensions/lib/acp/acp-client.ts +2 -2
  12. package/pi-extensions/lib/acp/models.ts +7 -9
  13. package/run.sh +21 -21
  14. package/scripts/check-acp-backend-preflight.ts +1 -1
  15. package/scripts/check-acp-config.ts +3 -3
  16. package/scripts/check-acp-event-mapper.ts +1 -1
  17. package/scripts/check-acp-provider-surface.ts +1 -1
  18. package/scripts/check-acp-sdk-surface.ts +22 -22
  19. package/scripts/check-acp-session-reuse.ts +3 -3
  20. package/scripts/check-acp-session-store.ts +6 -6
  21. package/scripts/check-acp-tool-surface.ts +2 -2
  22. package/scripts/check-entwurf-session-identity.ts +9 -9
  23. package/scripts/check-model-lock.ts +2 -2
  24. package/scripts/check-package-source-routing.ts +4 -4
  25. package/scripts/meta-bridge-doctor.sh +1 -1
  26. package/scripts/meta-bridge-state.py +2 -0
  27. package/scripts/resolve-acp-bridge.ts +1 -1
  28. package/scripts/smoke-acp-bundled-mcp-live.ts +1 -1
  29. package/scripts/smoke-acp-carrier-augment-live.ts +1 -1
  30. package/scripts/smoke-acp-mcp-live.ts +1 -1
  31. package/scripts/smoke-acp-memory-containment-live.ts +8 -9
  32. package/scripts/smoke-acp-overlay-live.ts +8 -9
  33. package/scripts/smoke-acp-provider-live.ts +1 -1
  34. package/scripts/smoke-acp-raw-turn-live.ts +12 -11
  35. package/scripts/smoke-acp-session-reuse-live.ts +24 -9
  36. package/scripts/smoke-acp-skill-live.ts +1 -1
  37. package/scripts/smoke-meta-install-state.sh +3 -3
package/AGENTS.md CHANGED
@@ -217,8 +217,8 @@ Code-level invariants pinned at the same time:
217
217
 
218
218
  ## Runtime Dependencies
219
219
 
220
- - `@modelcontextprotocol/sdk` and `zod` are the substrate runtime deps. With the Claude-first ACP plugin shipped, the Claude/ACP backend deps are pinned alongside them: `@agentclientprotocol/claude-agent-acp` (`0.50.0`), `@agentclientprotocol/sdk` (`0.29.0`), `@anthropic-ai/sdk` (`0.100.1`). The Codex/Gemini ACP packages stay out of scope (native already reaches Codex; Gemini/major tools use native).
221
- - `pi` (`@earendil-works/pi-ai`) on PATH at the pinned range (`>= 0.80.2 < 0.81` — devDep exact `0.80.2` + next-minor ceiling). Mismatches are caught by `check-dep-versions` / `check-pi-runtime-version`. 0.80 moved the standalone root `getModels()` to the deprecated `@earendil-works/pi-ai/compat` entrypoint; the curated Claude surface (`pi-extensions/lib/acp/models.ts`) imports `getModels` from `/compat` — the single subpath allowlisted in `check-pi-import-surface`. NOT the 0.80 provider-factory `providers/anthropic` subpath: although it typechecks, pi's extension loader (jiti alias map in pi-coding-agent `core/extensions/loader.ts`) resolves only the bare root, `/compat`, and `/oauth` for extensions — a `providers/*` import resolves to the unresolvable `dist/compat.js/providers/…` and crashes extension load (caught live by `smoke-resident-garden-guard`, not by static typecheck). This `/compat` use is an **extension-loader compatibility shim** chosen by loader constraint, not a preference for a deprecated API — the `<0.81` ceiling guards it; when 0.81 changes `compat` or the loader alias map, re-evaluate against whatever root/loader surface 0.81 then exposes.
220
+ - `@modelcontextprotocol/sdk` and `zod` are the substrate runtime deps. With the Claude-first ACP plugin shipped, the Claude/ACP backend deps are pinned alongside them: `@agentclientprotocol/claude-agent-acp` (`0.54.1`), `@agentclientprotocol/sdk` (`1.1.0`), `@anthropic-ai/sdk` (`0.100.1`). The Codex/Gemini ACP packages stay out of scope (native already reaches Codex; Gemini/major tools use native).
221
+ - `pi` (`@earendil-works/pi-ai`) on PATH at the pinned range (`>= 0.80.3 < 0.81` — devDep exact `0.80.3` + next-minor ceiling). Mismatches are caught by `check-dep-versions` / `check-pi-runtime-version`. 0.80 moved the standalone root `getModels()` to the deprecated `@earendil-works/pi-ai/compat` entrypoint; the curated Claude surface (`pi-extensions/lib/acp/models.ts`) imports `getModels` from `/compat` — the single subpath allowlisted in `check-pi-import-surface`. NOT the 0.80 provider-factory `providers/anthropic` subpath: although it typechecks, pi's extension loader (jiti alias map in pi-coding-agent `core/extensions/loader.ts`) resolves only the bare root, `/compat`, and `/oauth` for extensions — a `providers/*` import resolves to the unresolvable `dist/compat.js/providers/…` and crashes extension load (caught live by `smoke-resident-garden-guard`, not by static typecheck). This `/compat` use is an **extension-loader compatibility shim** chosen by loader constraint, not a preference for a deprecated API — the `<0.81` ceiling guards it; when 0.81 changes `compat` or the loader alias map, re-evaluate against whatever root/loader surface 0.81 then exposes.
222
222
 
223
223
  ## Working Style
224
224
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,30 @@ All notable changes to this project will be documented here. Format follows [Kee
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.12.3 — 2026-07-01
8
+
9
+ ### Changed
10
+
11
+ - **Claude ACP dependency lane refreshed for Sonnet 5.** The ACP runtime pins now use `@agentclientprotocol/claude-agent-acp@0.54.1` with `@agentclientprotocol/sdk@1.1.0`, while keeping the direct `@anthropic-ai/sdk@0.100.1` peer-resolution pin. The pi adapter floor is now `@earendil-works/pi-* >=0.80.3 <0.81`, matching the runtime catalog that exposes `claude-sonnet-5`.
12
+ - **Curated Claude surface moves from Sonnet 4.6 to Sonnet 5.** `claude-sonnet-5` replaces `claude-sonnet-4-6` across the ACP provider, demo/default smoke targets, pi target registry, and release docs. The Sonnet-specific 200K cap was removed; Sonnet 5 now surfaces the verified 1M context window like the Opus anchor, with a 1M ceiling guard to prevent silent future inflation.
13
+ - **Release and backend docs are version-neutral where the repo shape is stable.** The README now describes the durable repository shape instead of a point-in-time `0.12.x` state, and the clean-host/demo/verification docs reflect the current pi floor and Sonnet 5 defaults.
14
+ - **Cortex and fresh-spawn planning docs realigned to the 0.12 substrate.** The ACP backend rail documentation and NEXT/ROADMAP planning notes now describe the as-built adapter seam and the mux-visible fresh-sibling lane without re-centering old v1/fat-bridge assumptions.
15
+
16
+ ### Fixed
17
+
18
+ - **Live ACP smoke timeout cleanup no longer leaves stale timers after PASS.** Raw-turn, overlay, memory-containment, and session-reuse live smokes now clear their timeout handles when the awaited operation wins, so a successful live check exits promptly instead of lingering until the old timeout expires.
19
+ - **Session-reuse live smoke now preserves its success evidence.** The two-turn reuse smoke no longer calls `process.exit(0)` on success, allowing the turn-2/PASS log and cleanup to drain naturally while the retained ACP child is still handled by the backend exit cleanup.
20
+ - **Claude Code meta-bridge install state also disables workflow surfaces.** `enableWorkflows` and `workflowKeywordTriggerEnabled` are now managed false alongside the existing auto-memory, compaction, prompt-suggestion, progress, and auto-mode settings.
21
+ - **Unsupported ACP Codex targets are not advertised.** The target registry keeps Codex on the native `openai-codex` provider only; `entwurf/gpt-5.4` and `entwurf/gpt-5.5` are removed until an ACP Codex backend exists.
22
+
23
+ ### Verification
24
+
25
+ - `pnpm check` passed on 2026-07-01 after the dependency/model/doc updates; prep log `/tmp/pi-tmux-entwurf-prep-check-0123.log` ended with `EXIT=0`.
26
+ - `LIVE=1 ./run.sh smoke-acp-raw-turn-live` passed with `claude-sonnet-5` and exited promptly after PASS.
27
+ - `LIVE=1 ./run.sh smoke-acp-provider-live` passed with `claude-sonnet-5` through the pi provider path.
28
+ - `LIVE=1 ./run.sh smoke-acp-session-reuse-live` passed with a two-turn reused ACP child; turn 2 recalled the turn-1 codeword from delta-only prompt scope.
29
+ - `LIVE=1 ./run.sh release-gate /tmp/psa-release-gate-0.12.3.ZcRc8w` passed on 2026-07-01 with `MUST: PASS=17 FAIL=0 SKIP=0` and `BEHAVIOR: PASS=1 FAIL=0`; log `/tmp/pi-tmux-entwurf-release-gate-0123.log`.
30
+
7
31
  ## 0.12.2 — 2026-06-29
8
32
 
9
33
  ### Fixed
package/README.md CHANGED
@@ -10,9 +10,7 @@ npm package: <https://www.npmjs.com/package/@junghanacs/entwurf>
10
10
 
11
11
  Legacy package: [`@junghanacs/pi-shell-acp`](https://www.npmjs.com/package/@junghanacs/pi-shell-acp). `entwurf` is its 0.12+ successor line: the same work renamed around the garden-citizen dispatch substrate rather than the pi adapter.
12
12
 
13
- > **Public, active development.** Real working code, still young. Verify it in your own workflow before relying on it all day. Evidence calibration: [VERIFY.md](./VERIFY.md); native async-delivery capability levels: [DELIVERY.md](./DELIVERY.md).
14
-
15
- > **Current state for 0.12.1.** This repo is **entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an ACP plugin**. Pi is one supported harness adapter — important because it supplies control sockets and hosts the ACP plugin today — but it is not the project subject. Claude Code is shipped through the meta-bridge; pi is shipped through the control-socket adapter; Codex and Antigravity (`agy`) reach the garden with verified delivery probes, documented per launch mode in [DELIVERY.md](./DELIVERY.md), with shipped adapter/install lanes landing after the 0.12.0 doc cut. The ACP plugin is Claude-first; Cortex/vendor-governed ACP backends are future lanes.
13
+ > **Repository shape.** This repo is **entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an ACP plugin**. Pi is one supported harness adapter — important because it supplies control sockets and hosts the ACP plugin today — but it is not the project subject. Claude Code is shipped through the meta-bridge; pi is shipped through the control-socket adapter. Codex and Antigravity (`agy`) have verified delivery probes documented per launch mode in [DELIVERY.md](./DELIVERY.md); shipped adapter/install lanes are tracked separately. The ACP plugin is Claude-first; Cortex/vendor-governed ACP backends are future lanes.
16
14
 
17
15
  <details>
18
16
  <summary>Watch archived pre-0.12 demo (2131×1142 GIF, click to expand)</summary>
@@ -55,7 +53,7 @@ native Claude Code
55
53
  → entwurf_self | entwurf_v2 | entwurf_inbox_read
56
54
  ```
57
55
 
58
- This meta-bridge installer/doctor is **Claude Code only** in the shipped 0.12.0 surface. Codex and Antigravity delivery probes are recorded in [DELIVERY.md](./DELIVERY.md) as verified adapter evidence, not yet shipped install surfaces.
56
+ This meta-bridge installer/doctor is **Claude Code only** in the current shipped surface. Codex and Antigravity delivery probes are recorded in [DELIVERY.md](./DELIVERY.md) as verified adapter evidence, not yet shipped install surfaces.
59
57
 
60
58
  > **Direction.** Inverse of [`pi-acp`](https://github.com/svkozak/pi-acp). `pi-acp` lets external ACP clients talk *to* pi; `entwurf` lets garden citizens talk across harness boundaries — with pi as one adapter, not the center.
61
59
 
@@ -147,7 +145,7 @@ because Node refuses to strip `.ts` files under `node_modules`.
147
145
  ### Pi adapter / ACP plugin lane
148
146
 
149
147
  To use the `entwurf` provider inside pi, install a compatible pi binary
150
- separately (`@earendil-works/pi-coding-agent >=0.80.2 <0.81`). Then point pi at
148
+ separately (`@earendil-works/pi-coding-agent >=0.80.3 <0.81`). Then point pi at
151
149
  the npm-installed package or development clone:
152
150
 
153
151
  ```bash
package/VERIFY.md CHANGED
@@ -44,7 +44,7 @@ Verification here is not a benchmark. In production we exchange short turns and
44
44
  ### Verifying the two capabilities a gate cannot fully judge
45
45
 
46
46
  - **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2` with the correct intent — `fire-and-forget` for a live/replyable or meta-session target, `owned-outcome` only to wake a dormant record-backed pi citizen. Picking the wrong intent is rejected, never auto-fixed.
47
- - **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-4-6` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
47
+ - **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-5` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
48
48
 
49
49
  ### What NOT to do — bypassing the operational path
50
50
 
@@ -102,7 +102,7 @@ pi install git:github.com/junghan0611/entwurf # pi auto-clones + instal
102
102
  cd /path/to/consumer-project
103
103
  ~/.pi/agent/git/github.com/junghan0611/entwurf/run.sh install . # wire bundled mcpServers
104
104
  pi --list-models entwurf # curated model surface
105
- pi --provider entwurf --model claude-sonnet-4-6 -p "reply with ok only" # one-turn smoke
105
+ pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only" # one-turn smoke
106
106
  ```
107
107
 
108
108
  Expected: the package appears under pi's `User packages`; `install .` logs `added entwurfProvider.mcpServers.entwurf-bridge` + `updated <project>/.pi/settings.json`; the smoke returns a one-word reply (full bootstrap → ACP session → bridge → clean shutdown). Note: `~/.pi/agent/git/.../entwurf` is pi-managed — do not edit it (a `pi update` overwrites). Step 2 is still required after `pi install git:…`.
@@ -115,7 +115,7 @@ pnpm install # pnpm is the pinned packageManag
115
115
  pi install ./
116
116
  ./run.sh install /path/to/consumer-project
117
117
  pnpm check # full deterministic floor
118
- pi --provider entwurf --model claude-sonnet-4-6 -p "reply with ok only"
118
+ pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only"
119
119
  LIVE=1 ./run.sh release-gate /path/to/consumer-project
120
120
  ```
121
121
 
@@ -140,7 +140,7 @@ Compare a fresh self-awareness report across axes: (1) same backend, different i
140
140
 
141
141
  ## 1A. Main Agent Evaluation — Is `entwurf` Claude strong enough?
142
142
 
143
- Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-4-6` via a direct `pi --provider entwurf` turn (or a live ACP session); accumulate turns by re-prompting the same target.
143
+ Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-5` via a direct `pi --provider entwurf` turn (or a live ACP session); accumulate turns by re-prompting the same target.
144
144
 
145
145
  ### 1A.0 Two carrier surfaces — engraving vs pi-context-augment (load-bearing)
146
146
 
package/demo/README.md CHANGED
@@ -17,7 +17,7 @@ Historical pre-0.12 demo, still linked from the top-level `README.md` as archive
17
17
  tools, names the carrier surface for each cited piece of
18
18
  information, and admits unknowns instead of fabricating.
19
19
  2. **Entwurf surface** — the same pane spawns a sibling via the
20
- `entwurf` tool (`mode=sync`, cross-model — driver `claude-sonnet-4-6`,
20
+ `entwurf` tool (`mode=sync`, cross-model — driver `claude-sonnet-5`,
21
21
  sibling `gpt-5.4`), prints the Session ID, and quotes the sibling's
22
22
  one-line reply verbatim.
23
23
 
@@ -81,7 +81,7 @@ grep -E '(entwurf|model-switch)' demo/sender-debug.log
81
81
  | Var | Default | Meaning |
82
82
  |---|---|---|
83
83
  | `PEER_MODEL` | `entwurf/gpt-5.4` (≡ `piat`) | top pane backend (receives greeting) |
84
- | `SENDER_MODEL` | `entwurf/claude-sonnet-4-6` (≡ `pias`) | bottom pane backend (drives scenes) |
84
+ | `SENDER_MODEL` | `entwurf/claude-sonnet-5` (≡ `pias`) | bottom pane backend (drives scenes) |
85
85
  | `SCENE_DELAY` | `25` | seconds to wait for each scene's agent work |
86
86
  | `WARMUP` | `3` | seconds to wait for both pi banners |
87
87
  | `FINAL_PAUSE` | `5` | extra wait after scene 3 (peer reply lag) |
@@ -93,7 +93,7 @@ grep -E '(entwurf|model-switch)' demo/sender-debug.log
93
93
 
94
94
  | Var | Default | Meaning |
95
95
  |---|---|---|
96
- | `DRIVER_MODEL` | `entwurf/claude-sonnet-4-6` (≡ `pias`) | the driven pane — answers Q-B0 and spawns the sibling |
96
+ | `DRIVER_MODEL` | `entwurf/claude-sonnet-5` (≡ `pias`) | the driven pane — answers Q-B0 and spawns the sibling |
97
97
  | `SIBLING_MODEL` | `entwurf/gpt-5.4` (≡ `piat`) | cross-backend sibling spawned in scene 2 |
98
98
  | `SIBLING_CWD` | repo root | cwd passed to the entwurf sibling (drives `<project-context>` injection) |
99
99
  | `SCENE1_DELAY` | `60` | seconds for the long English baseline answer |
@@ -114,7 +114,7 @@ The demo launch lines correspond to your shell aliases:
114
114
  | Alias | Model id | Use as |
115
115
  |---|---|---|
116
116
  | `piao` | `entwurf/claude-opus-4-8` | `SENDER_MODEL` (precision scenes) |
117
- | `pias` | `entwurf/claude-sonnet-4-6` | `SENDER_MODEL` (default) |
117
+ | `pias` | `entwurf/claude-sonnet-5` | `SENDER_MODEL` (default) |
118
118
  | `piat` | `entwurf/gpt-5.4` | `PEER_MODEL` (default) |
119
119
  | `piat5` | `entwurf/gpt-5.5` | either |
120
120
  | `piag` | `entwurf/gemini-3.1-pro-preview` | either |
@@ -137,7 +137,7 @@ SCENE_DELAY=30 FINAL_PAUSE=10 bash demo.sh
137
137
 
138
138
  ## Prerequisites
139
139
 
140
- - `pi` on PATH (current floor 0.80.2)
140
+ - `pi` on PATH (current floor 0.80.3)
141
141
  - `entwurf` provider configured + auth ready for the selected sender/peer models
142
142
  - `asciinema` installed
143
143
  - `agg` installed (optional — only for GIF conversion)
@@ -8,7 +8,7 @@
8
8
  # reply in the same pane (cross-model, mode=sync).
9
9
  #
10
10
  # Layout (tmux, 220x50):
11
- # pane 0 (single) — driven pi (claude-sonnet-4-6) — receives both prompts.
11
+ # pane 0 (single) — driven pi (claude-sonnet-5) — receives both prompts.
12
12
  #
13
13
  # Recording: asciinema → baseline.cast → agg → baseline.gif
14
14
 
@@ -30,7 +30,7 @@ GIF="$PUBLISH_DIR/entwurf-demo.gif"
30
30
  DRIVER_LOG="$OUTDIR/baseline-debug.log"
31
31
 
32
32
  # Driven pi runs the bridge surface and answers both prompts.
33
- DRIVER_MODEL=${DRIVER_MODEL:-entwurf/claude-sonnet-4-6} # pias
33
+ DRIVER_MODEL=${DRIVER_MODEL:-entwurf/claude-sonnet-5} # pias
34
34
  # Sibling spawned via entwurf in scene 2 — different backend for contrast.
35
35
  SIBLING_MODEL=${SIBLING_MODEL:-entwurf/gpt-5.4} # piat
36
36
  SIBLING_CWD=${SIBLING_CWD:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}
package/demo/demo.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  #
4
4
  # Layout (tmux, 220x50):
5
5
  # pane 0 (top) — peer pi (codex, gpt-5.4) — idle, waits for greeting
6
- # pane 1 (bottom) — sender pi (claude-sonnet-4-6) — driven by send-keys
6
+ # pane 1 (bottom) — sender pi (claude-sonnet-5) — driven by send-keys
7
7
  #
8
8
  # Scenes (driven into sender pane):
9
9
  # 1. Spawn a sonnet sibling, store one fact.
@@ -32,7 +32,7 @@ SENDER_LOG="$OUTDIR/sender-debug.log"
32
32
 
33
33
  # Models match the user's piat / pias aliases.
34
34
  PEER_MODEL=${PEER_MODEL:-entwurf/gpt-5.4} # piat
35
- SENDER_MODEL=${SENDER_MODEL:-entwurf/claude-sonnet-4-6} # pias
35
+ SENDER_MODEL=${SENDER_MODEL:-entwurf/claude-sonnet-5} # pias
36
36
 
37
37
  # Pacing in seconds. Tuned from real runs: each scene's actual agent work
38
38
  # completes in ~5–15 s (Scene 1 sibling cold-spawn is the slowest; resume +
@@ -134,7 +134,7 @@ sleep "$WARMUP"
134
134
  # window/pane base-index configs.
135
135
  drive() {
136
136
  # Scene 1 — spawn + memory write
137
- tmux send-keys -t "$SENDER_PANE" -l 'Demo scene 1. Spawn a claude-sonnet-4-6 sibling via the entwurf tool. provider: entwurf, model: claude-sonnet-4-6, cwd: /home/junghan/repos/gh/entwurf, mode: sync. Task body: "You are a sibling for a recorded demo. Remember one fact only — my favorite forge color is tempered indigo. Reply with one short sentence acknowledging. No tool calls, no repo exploration." After it returns, print only the Session ID line so I can see it.'
137
+ tmux send-keys -t "$SENDER_PANE" -l 'Demo scene 1. Spawn a claude-sonnet-5 sibling via the entwurf tool. provider: entwurf, model: claude-sonnet-5, cwd: /home/junghan/repos/gh/entwurf, mode: sync. Task body: "You are a sibling for a recorded demo. Remember one fact only — my favorite forge color is tempered indigo. Reply with one short sentence acknowledging. No tool calls, no repo exploration." After it returns, print only the Session ID line so I can see it.'
138
138
  tmux send-keys -t "$SENDER_PANE" Enter
139
139
  sleep "$SCENE_DELAY"
140
140
 
@@ -30,7 +30,7 @@ ssh cleanhost 'uname -a; whoami; which git node npm pi claude 2>/dev/null'
30
30
  | Node | **24** recommended; `>=22.6.0` minimum | `engines.node` (Node strip-types / ESM runtime) |
31
31
  | npm | bundled with Node 24 | public package install path |
32
32
  | entwurf | `@junghanacs/entwurf` | neutral npm package; exposes `entwurf` and `entwurf-bridge` bins |
33
- | pi binary | **optional**, `@earendil-works/pi-coding-agent >=0.80.2 <0.81` | needed only for the pi adapter / ACP provider / spawn-bg resume lane |
33
+ | pi binary | **optional**, `@earendil-works/pi-coding-agent >=0.80.3 <0.81` | needed only for the pi adapter / ACP provider / spawn-bg resume lane |
34
34
 
35
35
  ## Stage 0 — Node 24 via nvm
36
36
 
@@ -109,7 +109,7 @@ If the host will run pi sessions or the Claude ACP provider through pi, install
109
109
  a compatible pi binary separately and wire the target project.
110
110
 
111
111
  ```bash
112
- npm install -g @earendil-works/pi-coding-agent@0.80.2
112
+ npm install -g @earendil-works/pi-coding-agent@0.80.3
113
113
  pi --version
114
114
 
115
115
  mkdir -p ~/entwurf-smoke
@@ -126,7 +126,7 @@ Drift points:
126
126
  `entwurf-bridge`, and links `~/.pi/agent/entwurf-targets.json` to the package's
127
127
  `pi/entwurf-targets.json`.
128
128
  - Older pi versions may silently miss the provider/extension surface. Use the
129
- pinned floor (`>=0.80.2 <0.81`) for release verification.
129
+ pinned floor (`>=0.80.3 <0.81`) for release verification.
130
130
  - A host that only uses the external MCP bridge can skip this stage until it
131
131
  needs `owned-outcome` spawn-bg resume or pi-native control sockets.
132
132
 
@@ -157,7 +157,7 @@ source ~/.bashrc
157
157
  claude login
158
158
 
159
159
  cd ~/entwurf-smoke
160
- pi --provider entwurf --model claude-sonnet-4-6 -p "reply with ok only"
160
+ pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only"
161
161
  ```
162
162
 
163
163
  If the backend CLI fails directly (`claude -p "ping"`), fix that upstream first.
@@ -171,7 +171,7 @@ a raw pi-assigned uuid hard-exits before any model turn.
171
171
 
172
172
  ```bash
173
173
  pi --session-id "$(entwurf new-session-id)" \
174
- --entwurf-control --provider entwurf --model claude-sonnet-4-6
174
+ --entwurf-control --provider entwurf --model claude-sonnet-5
175
175
  # control socket: ~/.pi/entwurf-control/<garden-id>.sock
176
176
  ```
177
177
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@junghanacs/entwurf",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "Garden-citizen dispatch substrate and meta-bridge for Claude Code, Codex, Antigravity, and pi harnesses.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -67,23 +67,23 @@
67
67
  },
68
68
  "packageManager": "pnpm@10.33.0",
69
69
  "dependencies": {
70
- "@agentclientprotocol/claude-agent-acp": "0.50.0",
71
- "@agentclientprotocol/sdk": "0.29.0",
70
+ "@agentclientprotocol/claude-agent-acp": "0.54.1",
71
+ "@agentclientprotocol/sdk": "1.1.0",
72
72
  "@anthropic-ai/sdk": "0.100.1",
73
73
  "@modelcontextprotocol/sdk": "^1.12.1",
74
74
  "zod": "^3.25.0 || ^4.0.0"
75
75
  },
76
76
  "peerDependencies": {
77
- "@earendil-works/pi-ai": ">=0.80.2 <0.81",
78
- "@earendil-works/pi-coding-agent": ">=0.80.2 <0.81",
79
- "@earendil-works/pi-tui": ">=0.80.2 <0.81",
77
+ "@earendil-works/pi-ai": ">=0.80.3 <0.81",
78
+ "@earendil-works/pi-coding-agent": ">=0.80.3 <0.81",
79
+ "@earendil-works/pi-tui": ">=0.80.3 <0.81",
80
80
  "typebox": "*"
81
81
  },
82
82
  "devDependencies": {
83
83
  "@biomejs/biome": "^2.4.13",
84
- "@earendil-works/pi-ai": "0.80.2",
85
- "@earendil-works/pi-coding-agent": "0.80.2",
86
- "@earendil-works/pi-tui": "0.80.2",
84
+ "@earendil-works/pi-ai": "0.80.3",
85
+ "@earendil-works/pi-coding-agent": "0.80.3",
86
+ "@earendil-works/pi-tui": "0.80.3",
87
87
  "@types/node": "^24.3.0",
88
88
  "husky": "^9.1.7",
89
89
  "typescript": "^6.0.2"
@@ -1,20 +1,17 @@
1
1
  {
2
2
  "$comment": "Entwurf Target Registry — exact (provider, model) allowlist. SSOT for what can be spawned via entwurf. See entwurf/AGENTS.md Entwurf Orchestration. Resume path intentionally bypasses this registry per Identity Preservation Rule.",
3
3
  "$notes": {
4
- "gpt-5.5": "High-end frontier target with 400K native codex context. Cost: ~$5 input / $30 output per 1M tokens on this tier — ~6x gpt-5.4. Do not make it the default. Use explicitly for long-context / high-quality work only. ACP-routed entries are `explicitOnly`: caller must pass provider=entwurf to route through the ACP bridge, otherwise bare `gpt-5.5` resolves to native openai-codex.",
5
- "bareResolution": "Each bare model id resolves unambiguously because only the native openai-codex entry is non-explicitOnly. Bare `gpt-5.5` -> openai-codex/gpt-5.5. ACP route requires explicit provider.",
4
+ "gpt-5.5": "High-end frontier target with 400K native codex context. Cost: ~$5 input / $30 output per 1M tokens on this tier — ~6x gpt-5.4. Do not make it the default. Use explicitly for long-context / high-quality work only.",
5
+ "bareResolution": "Each bare Codex model id resolves through the native openai-codex provider. Bare `gpt-5.5` -> openai-codex/gpt-5.5. ACP Codex is not on this surface until the ACP backend is implemented.",
6
6
  "gemini": "Gemini ACP targets are routed exclusively through entwurf's `gemini --acp` backend; the host pi removed its built-in google provider in v0.71.0. ACP entries are `explicitOnly` to keep the entwurf surface honest — there is currently no native pi alternative to disambiguate against, but the flag keeps the policy stable if pi reintroduces a google provider later. 3.1 Pro is the subscription-backed high-quality ACP target. Flash / 2.5 routing through ACP is intentionally not on this surface."
7
7
  },
8
8
  "entwurfTargets": [
9
- { "provider": "entwurf", "model": "claude-sonnet-4-6", "enabled": true },
9
+ { "provider": "entwurf", "model": "claude-sonnet-5", "enabled": true },
10
10
  { "provider": "entwurf", "model": "claude-opus-4-8", "enabled": true },
11
11
 
12
12
  { "provider": "openai-codex", "model": "gpt-5.4", "enabled": true },
13
13
  { "provider": "openai-codex", "model": "gpt-5.5", "enabled": true },
14
14
 
15
- { "provider": "entwurf", "model": "gpt-5.4", "enabled": true, "explicitOnly": true },
16
- { "provider": "entwurf", "model": "gpt-5.5", "enabled": true, "explicitOnly": true },
17
-
18
15
  { "provider": "entwurf", "model": "gemini-3.1-pro-preview", "enabled": true, "explicitOnly": true }
19
16
  ]
20
17
  }
@@ -1,5 +1,5 @@
1
1
  // ACP client adapter — the ONE place that touches the @agentclientprotocol/sdk
2
- // 0.29 fluent surface (`client({ name }).connect(stream)`).
2
+ // 1.1 fluent surface (`client({ name }).connect(stream)`).
3
3
  //
4
4
  // The wire SDK deprecated the `new ClientSideConnection(toClient, stream)`
5
5
  // constructor in favour of the fluent `client()` builder. The two have
@@ -52,7 +52,7 @@ export interface AcpClientHandlers {
52
52
  }
53
53
 
54
54
  /**
55
- * Production factory — wrap the SDK 0.29 fluent `client()` into the
55
+ * Production factory — wrap the SDK 1.1 fluent `client()` into the
56
56
  * `AcpConnectionLike` seam the backend (and the live smokes) drive.
57
57
  *
58
58
  * Client-side handlers register by ACP method name; agent-side calls go through
@@ -50,18 +50,17 @@ export const ENTWURF_ACP_NO_AUTH_SENTINEL = "entwurf-no-auth";
50
50
  // both axes (protocol smoke + agent interview) — do not extend casually.
51
51
  // Exported so the claude backend adapter (backend-adapter.ts) can answer
52
52
  // `routeModel` without re-deriving the set from curatedClaudeModels().
53
- export const SUPPORTED_ANTHROPIC_MODEL_IDS = ["claude-sonnet-4-6", "claude-opus-4-8"] as const;
53
+ export const SUPPORTED_ANTHROPIC_MODEL_IDS = ["claude-sonnet-5", "claude-opus-4-8"] as const;
54
54
 
55
55
  /** The anchor model whose absence is a hard registry regression, not a soft skip. */
56
56
  export const CURATED_ANCHOR_MODEL_ID = "claude-opus-4-8";
57
57
 
58
- // Anthropic's registry reports 1M for Claude 4.6+ models, but the public
59
- // entwurf surface deliberately distinguishes Sonnet vs Opus: Sonnet stays
60
- // at 200K, Opus surfaces at 1M. (The 0.11.0 ENTWURF_ACP_CLAUDE_CONTEXT env
61
- // override is a behavior-oracle nicety deferred past S0 the loader/fence
62
- // slice only needs the anchor present and registered.)
58
+ // Anthropic's registry reports 1M for both Sonnet 5 and Opus 4.8, and the
59
+ // entwurf surface now exposes the full 1M for BOTH. Sonnet 5's 1M window is the
60
+ // whole point of the 0.12.3 bump — it is the compact-free long-context floor the
61
+ // earlier 200K Sonnet cap could not provide. We still clamp to a 1M ceiling so a
62
+ // future registry value can't silently inflate the surface past what we verify.
63
63
  const CLAUDE_CONTEXT_DEFAULT = 1_000_000;
64
- const CLAUDE_SONNET_DEFAULT = 200_000;
65
64
 
66
65
  // `getModels("anthropic")` reads the static builtin model catalog only — no env
67
66
  // read, no credential access, no network — preserving the #26 auth-boundary
@@ -79,8 +78,7 @@ function requireRegistryModel(models: readonly RegistryModel[], id: string): Reg
79
78
  }
80
79
 
81
80
  function claudeContextWindow(model: { id: string; contextWindow: number }): number {
82
- const cap = model.id === "claude-sonnet-4-6" ? CLAUDE_SONNET_DEFAULT : CLAUDE_CONTEXT_DEFAULT;
83
- return Math.min(model.contextWindow, cap);
81
+ return Math.min(model.contextWindow, CLAUDE_CONTEXT_DEFAULT);
84
82
  }
85
83
 
86
84
  /**
package/run.sh CHANGED
@@ -2,10 +2,10 @@
2
2
  #
3
3
  # Model id convention (see AGENTS.md Hard Rule #1):
4
4
  # - User-facing examples use the qualified form `entwurf/<backend-model>`
5
- # (e.g. `entwurf/claude-sonnet-4-6`); the prefix routes to this provider
5
+ # (e.g. `entwurf/claude-sonnet-5`); the prefix routes to this provider
6
6
  # so `--provider` is redundant and is dropped in docs.
7
7
  # - Smoke helpers that feed `ensureBridgeSession({modelId})` directly (cancel,
8
- # model-switch) pass BARE backend ids (`claude-sonnet-4-6`, `gpt-5.4`)
8
+ # model-switch) pass BARE backend ids (`claude-sonnet-5`, `gpt-5.4`)
9
9
  # because the bridge library contract is bare. Smoke helpers that invoke pi
10
10
  # via the CLI still pin `--provider entwurf` and can accept either
11
11
  # bare or qualified model, but we keep bare here to match the bridge-level
@@ -32,7 +32,7 @@ TARGET_PROJECT_DIR=${2:-$PROJECT_DIR_DEFAULT}
32
32
  # and install path against the same scope for traceability.
33
33
  PACKAGE_NAME="@junghanacs/entwurf"
34
34
  # Runtime provider id — DO NOT change. Embedded in model strings
35
- # (`entwurf/claude-sonnet-4-6`), settings keys (`entwurfProvider`),
35
+ # (`entwurf/claude-sonnet-5`), settings keys (`entwurfProvider`),
36
36
  # log prefixes (`[entwurf:bootstrap]`), and the `--provider entwurf`
37
37
  # CLI surface. Renaming this would break every consumer transcript and every
38
38
  # saved session anchor.
@@ -908,7 +908,7 @@ smoke_acp_raw_turn_live() {
908
908
  # plus captured raw NDJSON bytes. NO provider/overlay/streamSimple/_meta — the
909
909
  # raw backend pipe only. Launch source must be the package bin (PATH fallback
910
910
  # fails acceptance unless ENTWURF_ACP_RAW_TURN_ALLOW_PATH_FALLBACK=1, debug).
911
- # Model override: ENTWURF_ACP_RAW_TURN_MODEL (default claude-sonnet-4-6).
911
+ # Model override: ENTWURF_ACP_RAW_TURN_MODEL (default claude-sonnet-5).
912
912
  # LIVE=1 ./run.sh smoke-acp-raw-turn-live
913
913
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-raw-turn-live.ts)
914
914
  }
@@ -926,7 +926,7 @@ smoke_acp_overlay_live() {
926
926
  # meta-store for mailbox absence (flaky — concurrent sessions); the honest
927
927
  # claim is overlay-supplies-hooks:{}. Launch must be the package bin (PATH
928
928
  # fallback fails acceptance unless ENTWURF_ACP_OVERLAY_ALLOW_PATH_FALLBACK=1).
929
- # Model override: ENTWURF_ACP_OVERLAY_MODEL (default claude-sonnet-4-6).
929
+ # Model override: ENTWURF_ACP_OVERLAY_MODEL (default claude-sonnet-5).
930
930
  # LIVE=1 ./run.sh smoke-acp-overlay-live
931
931
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-overlay-live.ts)
932
932
  }
@@ -941,7 +941,7 @@ smoke_acp_memory_containment_live() {
941
941
  # can stop a memory write is the lever — not us. Fails loud if engraving.md is
942
942
  # empty (carrier OFF = no containment). Launch must be the package bin (PATH
943
943
  # fallback fails acceptance unless ENTWURF_ACP_MEMORY_ALLOW_PATH_FALLBACK=1).
944
- # Model override: ENTWURF_ACP_MEMORY_MODEL (default claude-sonnet-4-6).
944
+ # Model override: ENTWURF_ACP_MEMORY_MODEL (default claude-sonnet-5).
945
945
  # LIVE=1 ./run.sh smoke-acp-memory-containment-live
946
946
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-memory-containment-live.ts)
947
947
  }
@@ -956,7 +956,7 @@ smoke_acp_provider_live() {
956
956
  # assistant reply (live model proof) + the removed S0 stub error never appears
957
957
  # (provider path actually opened) + pi exits 0. Tool-free prompt; the
958
958
  # event-mapper gate owns the tool→notice contract.
959
- # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-4-6).
959
+ # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-5).
960
960
  # LIVE=1 ./run.sh smoke-acp-provider-live
961
961
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-provider-live.ts)
962
962
  }
@@ -970,7 +970,7 @@ smoke_acp_session_reuse_live() {
970
970
  # was reused and the live ACP session kept turn-1 history (a respawn-per-turn
971
971
  # backend would forget it). The one-shot exit0 half is owned by
972
972
  # smoke-acp-provider-live.
973
- # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-4-6).
973
+ # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-5).
974
974
  # LIVE=1 ./run.sh smoke-acp-session-reuse-live
975
975
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-session-reuse-live.ts)
976
976
  }
@@ -982,7 +982,7 @@ smoke_acp_carrier_augment_live() {
982
982
  # secret (the augment rode the wire to the model) and the EMPTY default carrier
983
983
  # must bill clean (exit 0, no HTTP-400 canary — 핀1 live). Optional tiny carrier
984
984
  # check via SMOKE_ACP_CARRIER_PRESENT=1 (non-blocking).
985
- # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-4-6).
985
+ # Model override: ENTWURF_ACP_PROVIDER_MODEL (default claude-sonnet-5).
986
986
  # LIVE=1 ./run.sh smoke-acp-carrier-augment-live
987
987
  (cd "$REPO_DIR" && node --experimental-strip-types scripts/smoke-acp-carrier-augment-live.ts)
988
988
  }
@@ -1040,9 +1040,9 @@ smoke_acp_rgg_live() {
1040
1040
  # surface (plugin stays lightweight, no ambient MCP — S2b/S2d boundary). To
1041
1041
  # observe that boundary directly, run the shared runner with SMOKE_RGG_POSITIVE=1
1042
1042
  # and ENTWURF_LIVE_TARGET set (T3 will report N/A, not a real failure).
1043
- # Target override: ENTWURF_RGG_TARGET (default entwurf/claude-sonnet-4-6).
1043
+ # Target override: ENTWURF_RGG_TARGET (default entwurf/claude-sonnet-5).
1044
1044
  # ./run.sh smoke-acp-rgg-live
1045
- local target="${ENTWURF_RGG_TARGET:-entwurf/claude-sonnet-4-6}"
1045
+ local target="${ENTWURF_RGG_TARGET:-entwurf/claude-sonnet-5}"
1046
1046
  (cd "$REPO_DIR" && ENTWURF_LIVE_TARGET="$target" SMOKE_RGG_POSITIVE=0 bash scripts/smoke-resident-garden-guard.sh)
1047
1047
  }
1048
1048
 
@@ -1280,7 +1280,7 @@ assert.equal(peerTui, piAi,
1280
1280
  // pi moves its public surface every minor (the 0.79→0.80 getModels→provider-
1281
1281
  // factory churn is exactly this), so an open `>=` floor is exactly how the next
1282
1282
  // installer re-acquires the drift. Expected
1283
- // shape: `>=<devDep> <0.<minor+1>` (e.g. `>=0.80.2 <0.81`).
1283
+ // shape: `>=<devDep> <0.<minor+1>` (e.g. `>=0.80.3 <0.81`).
1284
1284
  const [piMaj, piMin] = piAi.split('.').map(Number);
1285
1285
  assert.equal(piMaj, 0,
1286
1286
  `pi pin major must stay 0 for the next-minor ceiling rule (got ${piAi}); revisit check-dep-versions when pi reaches 1.x`);
@@ -1375,7 +1375,7 @@ check_pi_runtime_version() {
1375
1375
  # never statically import a floor-only symbol here, or this guard would crash
1376
1376
  # before it can fail loud.
1377
1377
  (cd "$REPO_DIR" && node --input-type=module <<'EOF'
1378
- const FLOOR = '0.80.2';
1378
+ const FLOOR = '0.80.3';
1379
1379
  const cmp = (a, b) => {
1380
1380
  const pa = a.split('.').map(Number), pb = b.split('.').map(Number);
1381
1381
  for (let i = 0; i < 3; i++) { if ((pa[i] || 0) !== (pb[i] || 0)) return (pa[i] || 0) - (pb[i] || 0); }
@@ -1393,7 +1393,7 @@ if (typeof VERSION !== 'string') {
1393
1393
  process.exit(1);
1394
1394
  }
1395
1395
  if (cmp(VERSION, FLOOR) < 0) {
1396
- console.error(`[check-pi-runtime-version] FAIL: pi VERSION ${VERSION} < ${FLOOR} — the bridge is built and tested against the 0.80.2 public/runtime surface (trust exports hasTrustRequiringProjectResources + ProjectTrustStore nearest-ancestor get, the 0.80 model-catalog API getModels reached via the deprecated /compat entrypoint — 0.80 moved the standalone root getModels there, and the extension loader resolves only /compat, NOT the providers/* factory subpath — provider registration surface, compaction semantics) that older pi lacks or behaves differently on. Bump @earendil-works/pi-*.`);
1396
+ console.error(`[check-pi-runtime-version] FAIL: pi VERSION ${VERSION} < ${FLOOR} — the bridge is built and tested against the 0.80.3 public/runtime surface (trust exports hasTrustRequiringProjectResources + ProjectTrustStore nearest-ancestor get, the 0.80 model-catalog API getModels reached via the deprecated /compat entrypoint — 0.80 moved the standalone root getModels there, and the extension loader resolves only /compat, NOT the providers/* factory subpath — provider registration surface, compaction semantics) that older pi lacks or behaves differently on. Bump @earendil-works/pi-*.`);
1397
1397
  process.exit(1);
1398
1398
  }
1399
1399
  console.log(`[check-pi-runtime-version] ok — pi VERSION ${VERSION} >= ${FLOOR}`);
@@ -1536,8 +1536,8 @@ check_acp_provider_surface() {
1536
1536
 
1537
1537
  check_acp_sdk_surface() {
1538
1538
  # Deterministic gate for the S2a ACP SDK dependency surface. Pins the three
1539
- # ACP runtime deps to the 0.11.0 oracle versions (@agentclientprotocol/sdk
1540
- # 0.22.1 + claude-agent-acp 0.39.0 + @anthropic-ai/sdk 0.100.1), locks the
1539
+ # ACP runtime deps to the current oracle versions (@agentclientprotocol/sdk
1540
+ # 1.1.0 + claude-agent-acp 0.54.1 + @anthropic-ai/sdk 0.100.1), locks the
1541
1541
  # peer-resolution that keeps claude-agent-sdk satisfiable (0.100.1, not the
1542
1542
  # stale 0.91.1), asserts the wire SDK still value-exports the symbols the raw
1543
1543
  # turn needs (silent-rename gate), and forbids any source-level anthropic SDK
@@ -1946,9 +1946,9 @@ check_pack_install() {
1946
1946
  local install_log
1947
1947
  install_log=$(cd "$tmp" && pnpm add \
1948
1948
  "$tgz_path" \
1949
- "@earendil-works/pi-ai@0.80.2" \
1950
- "@earendil-works/pi-coding-agent@0.80.2" \
1951
- "@earendil-works/pi-tui@0.80.2" \
1949
+ "@earendil-works/pi-ai@0.80.3" \
1950
+ "@earendil-works/pi-coding-agent@0.80.3" \
1951
+ "@earendil-works/pi-tui@0.80.3" \
1952
1952
  "typebox@latest" \
1953
1953
  --ignore-workspace --ignore-scripts 2>&1) || {
1954
1954
  fail "[check-pack-install] pnpm add failed:"
@@ -2000,14 +2000,14 @@ check_pack_install() {
2000
2000
  # opus anchor (CURATED_ANCHOR_MODEL_ID in lib/acp/models.ts — the model whose
2001
2001
  # absence is a hard registry regression). Checking only one would let half the
2002
2002
  # surface drop silently.
2003
- for anchor in "claude-sonnet-4-6" "claude-opus-4-8"; do
2003
+ for anchor in "claude-sonnet-5" "claude-opus-4-8"; do
2004
2004
  if ! grep -q "$anchor" <<<"$loader_out"; then
2005
2005
  fail "[check-pack-install] pi loader output missing curated Claude model $anchor:"
2006
2006
  echo "$loader_out" | tail -10 | sed 's/^/ /' >&2
2007
2007
  return 1
2008
2008
  fi
2009
2009
  done
2010
- echo "[check-pack-install] pi loader smoke pass (entwurf registered, claude-sonnet-4-6 + claude-opus-4-8 anchor)"
2010
+ echo "[check-pack-install] pi loader smoke pass (entwurf registered, claude-sonnet-5 + claude-opus-4-8 anchor)"
2011
2011
 
2012
2012
  # npm-managed neutral install regression — the README's PRIMARY install path is
2013
2013
  # now `npm install @junghanacs/entwurf` (NOT `pi install npm:...`). This layout
@@ -21,7 +21,7 @@ import { resolve } from "node:path";
21
21
  import { pathToFileURL } from "node:url";
22
22
  import type { Api, AssistantMessageEvent, Context, Model } from "@earendil-works/pi-ai";
23
23
 
24
- const model = { id: "claude-sonnet-4-6" } as unknown as Model<Api>;
24
+ const model = { id: "claude-sonnet-5" } as unknown as Model<Api>;
25
25
 
26
26
  // Declared tools exclude `read`, but the Claude child always exposes Read →
27
27
  // declared != actual → the preflight must reject before spawning.
@@ -58,7 +58,7 @@ function settings(name: string, block: unknown): string {
58
58
  function resolveWith(globalPath: string, projectPath: string, adapter: AcpBackendAdapter = claudeLikeFake) {
59
59
  return resolveProviderConfig({
60
60
  cwd: root,
61
- modelId: "claude-sonnet-4-6",
61
+ modelId: "claude-sonnet-5",
62
62
  adapter,
63
63
  globalSettingsPath: globalPath,
64
64
  projectSettingsPath: projectPath,
@@ -291,11 +291,11 @@ try {
291
291
  weather: { type: "http", url: "https://w.test" },
292
292
  other: { command: "x" },
293
293
  }).servers;
294
- const enriched = enrichMcpServersWithEnvelope(servers, { modelId: "claude-sonnet-4-6", piSessionId: "LIVE-1" });
294
+ const enriched = enrichMcpServersWithEnvelope(servers, { modelId: "claude-sonnet-5", piSessionId: "LIVE-1" });
295
295
  const bridge = enriched.find((s) => s.name === "entwurf-bridge") as Extract<AcpMcpServer, { command: string }>;
296
296
  const env = Object.fromEntries(bridge.env.map((e) => [e.name, e.value]));
297
297
  assert.equal(env.PI_SESSION_ID, "LIVE-1", "live PI_SESSION_ID wins over the stale operator value");
298
- assert.equal(env.PI_AGENT_ID, "entwurf/claude-sonnet-4-6", "PI_AGENT_ID injected from the model id");
298
+ assert.equal(env.PI_AGENT_ID, "entwurf/claude-sonnet-5", "PI_AGENT_ID injected from the model id");
299
299
  assert.equal(env.FOO, "bar", "operator env preserved");
300
300
  const weather = enriched.find((s) => s.name === "weather");
301
301
  assert.ok(!("env" in (weather ?? {})), "http server not enriched (no env carrier)");
@@ -21,7 +21,7 @@ import {
21
21
  finalizeAcpStreamState,
22
22
  } from "../pi-extensions/lib/acp/event-mapper.ts";
23
23
 
24
- const IDENTITY = { api: "entwurf", provider: "entwurf", model: "claude-sonnet-4-6" };
24
+ const IDENTITY = { api: "entwurf", provider: "entwurf", model: "claude-sonnet-5" };
25
25
 
26
26
  // Drive a set of synthetic updates through a fresh mapper and collect every
27
27
  // emitted event (push is synchronous; the terminal done drains the queue).
@@ -117,7 +117,7 @@ try {
117
117
  assert.equal(cap.cfg.apiKey, ENTWURF_ACP_NO_AUTH_SENTINEL, "entry apiKey is not the no-auth sentinel");
118
118
  assert.equal(cap.cfg.api, "entwurf", "entry api field drifted");
119
119
  const capIds = (cap.cfg.models ?? []).map((m) => m.id);
120
- for (const want of ["claude-sonnet-4-6", CURATED_ANCHOR_MODEL_ID]) {
120
+ for (const want of ["claude-sonnet-5", CURATED_ANCHOR_MODEL_ID]) {
121
121
  assert.ok(capIds.includes(want), `entry model surface missing ${want} (got: ${capIds.join(", ") || "none"})`);
122
122
  }
123
123
  assert.equal(typeof cap.cfg.streamSimple, "function", "entry streamSimple must be a function");