@junghanacs/entwurf 0.12.6 → 0.12.7
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/AGENTS.md +31 -17
- package/BASELINE.md +42 -8
- package/CHANGELOG.md +22 -0
- package/DELIVERY.md +71 -14
- package/README.md +77 -45
- package/VERIFY.md +18 -13
- package/docs/setup-clean-host.md +80 -22
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +90 -66
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/acp-client.js +54 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +153 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +436 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/context.js +157 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/engraving.js +105 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +90 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +194 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +153 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-deliverability.js +42 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +49 -13
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +104 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +30 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-native-push.js +57 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +10 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-release.js +9 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +21 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +5 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +17 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +125 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/adapter.js +158 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/register.js +61 -0
- package/mcp/entwurf-bridge/dist/scripts/agy-imprint.js +166 -0
- package/mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js +130 -0
- package/mcp/entwurf-bridge/dist/scripts/meta-bridge-prune.js +178 -0
- package/mcp/entwurf-bridge/dist/scripts/new-session-id.js +24 -0
- package/mcp/entwurf-bridge/src/index.ts +101 -67
- package/mcp/entwurf-bridge/test.sh +1 -1
- package/mcp/entwurf-bridge/tsconfig.build.json +23 -3
- package/package.json +10 -5
- package/pi-extensions/lib/entwurf-deliverability.ts +62 -9
- package/pi-extensions/lib/entwurf-self-address.ts +58 -15
- package/pi-extensions/lib/entwurf-v2-contract.ts +120 -12
- package/pi-extensions/lib/entwurf-v2-decider.ts +60 -0
- package/pi-extensions/lib/entwurf-v2-native-push.ts +86 -0
- package/pi-extensions/lib/entwurf-v2-production.ts +20 -0
- package/pi-extensions/lib/entwurf-v2-release.ts +9 -0
- package/pi-extensions/lib/entwurf-v2-runner.ts +29 -1
- package/pi-extensions/lib/entwurf-v2-send.ts +7 -0
- package/pi-extensions/lib/entwurf-v2-surface.ts +17 -0
- package/pi-extensions/lib/meta-sender-identity.ts +154 -0
- package/pi-extensions/lib/native-push/adapter.ts +255 -0
- package/pi-extensions/lib/native-push/register.ts +99 -0
- package/run.sh +756 -214
- package/scripts/agy-bridge-config.py +446 -0
- package/scripts/agy-bridge.sh +359 -0
- package/scripts/agy-hooks-bridge.sh +193 -0
- package/scripts/agy-hooks-config.py +257 -0
- package/scripts/agy-imprint.sh +28 -0
- package/scripts/agy-imprint.ts +193 -0
- package/scripts/agy-statusline-bridge.sh +176 -0
- package/scripts/agy-statusline-config.py +213 -0
- package/scripts/agy-statusline.sh +256 -0
- package/scripts/build-bridge.sh +20 -0
- package/scripts/check-agy-sender-identity.ts +364 -0
- package/scripts/check-entwurf-bridge-boot.ts +8 -2
- package/scripts/check-entwurf-deliverability.ts +34 -0
- package/scripts/check-entwurf-self-address.ts +78 -11
- package/scripts/check-entwurf-v2-contract.ts +136 -1
- package/scripts/check-entwurf-v2-decider.ts +95 -1
- package/scripts/check-entwurf-v2-matrix.ts +14 -3
- package/scripts/check-entwurf-v2-native-push.ts +193 -0
- package/scripts/check-entwurf-v2-production.ts +68 -1
- package/scripts/check-entwurf-v2-runner.ts +58 -0
- package/scripts/check-entwurf-v2-surface.ts +35 -0
- package/scripts/check-install-surface.ts +357 -0
- package/scripts/check-native-push-adapter.ts +319 -0
- package/scripts/check-native-push-register.ts +130 -0
- package/scripts/dev-bin.sh +195 -0
- package/scripts/doctor-pi-provider.ts +140 -0
- package/scripts/meta-bridge-doctor.sh +36 -2
- package/scripts/register-pi-package.py +37 -3
- package/scripts/register-pi-provider.py +287 -0
- package/scripts/smoke-agy-hooks-state.sh +172 -0
- package/scripts/smoke-agy-install-state.sh +660 -0
- package/scripts/smoke-agy-native-push-live.ts +243 -0
- package/scripts/smoke-agy-statusline-state.sh +300 -0
- package/scripts/smoke-meta-async-drift.sh +9 -2
- package/scripts/smoke-meta-install-state.sh +20 -0
- package/scripts/smoke-pi-provider-state.sh +182 -0
- package/scripts/smoke-user-scope-citizen.sh +62 -0
- package/scripts/with-dist-lock.sh +81 -0
- package/scripts/__pycache__/meta-bridge-state.cpython-312.pyc +0 -0
- package/scripts/__pycache__/meta-bridge-state.cpython-313.pyc +0 -0
- package/scripts/__pycache__/register-pi-package.cpython-313.pyc +0 -0
package/README.md
CHANGED
|
@@ -10,7 +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
|
-
> **Repository shape.** This repo is **entwurf-core (v2 dispatch) +
|
|
13
|
+
> **Repository shape.** This repo is **entwurf-core (v2 dispatch) + native-harness bridges + 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 as a mailbox-backed meta-session; Antigravity (`agy`) is shipped as a native-push citizen with automatic `PreInvocation` birth, ambient garden-id status, and a managed MCP/permission install surface. Codex has a launch-mode-specific verified delivery probe documented in [DELIVERY.md](./DELIVERY.md), but no managed native-citizen install lane yet. The ACP plugin is Claude-first; Cortex/vendor-governed ACP backends are future lanes.
|
|
14
14
|
|
|
15
15
|
<details>
|
|
16
16
|
<summary>Watch archived pre-0.12 demo (2131×1142 GIF, click to expand)</summary>
|
|
@@ -25,10 +25,10 @@ Legacy package: [`@junghanacs/pi-shell-acp`](https://www.npmjs.com/package/@jung
|
|
|
25
25
|
Claude Code / Codex / agy / pi
|
|
26
26
|
→ garden id
|
|
27
27
|
→ entwurf_v2
|
|
28
|
-
→ control-socket | spawn-bg resume | meta-mailbox
|
|
28
|
+
→ control-socket | spawn-bg resume | meta-mailbox | native-push
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
[`entwurf_v2`](#entwurf_v2--canonical-dispatch-verb) is the canonical dispatch surface over *existing* garden citizens — live control-socket send (including record-less socket-only pi sessions), spawn-bg resume,
|
|
31
|
+
[`entwurf_v2`](#entwurf_v2--canonical-dispatch-verb) is the canonical dispatch surface over *existing* garden citizens — live control-socket send (including record-less socket-only pi sessions), spawn-bg resume, meta-mailbox enqueue, and native-push into a live Antigravity conversation. The v1 entwurf verbs are gone. Fresh sibling minting and non-Claude ACP backends are deferred lanes.
|
|
32
32
|
|
|
33
33
|
**Garden id is deliberate vocabulary.** It is not a decorative synonym for session id, worker, delegate, or subagent. The unfamiliar word is a guard: each harness keeps its own identity and transcript, while `entwurf` supplies a narrow addressable surface between siblings.
|
|
34
34
|
|
|
@@ -43,17 +43,26 @@ pi --entwurf-control
|
|
|
43
43
|
→ Claude backend under the operator's local auth
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
**
|
|
46
|
+
**Native bridges reach beyond ACP transport.** A global `SessionStart` hook registers native Claude Code sessions as **garden-native meta-sessions** with a garden id, a mailbox, and a trusted sender marker. That makes an already-running Claude Code terminal addressable through `entwurf_v2` (the mailbox path), self-identifying through `entwurf_self`, and replyable by garden id — without turning pi into a second harness or importing Claude's transcript.
|
|
47
47
|
|
|
48
48
|
```text
|
|
49
49
|
native Claude Code
|
|
50
50
|
→ SessionStart hook
|
|
51
|
-
→ meta-session <garden-id>
|
|
51
|
+
→ mailbox-backed meta-session <garden-id>
|
|
52
52
|
→ entwurf-bridge MCP
|
|
53
53
|
→ entwurf_self | entwurf_v2 | entwurf_inbox_read
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Antigravity uses a separate shipped rail. Its `PreInvocation` hook births or re-attaches the conversation by native `conversationId`, writes a record-backed sender marker, and leaves delivery to the live native LS gRPC route. There is no mailbox or receiver marker on this rail: `entwurf_v2` probes the conversation and direct-injects with native-push.
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
native Antigravity / agy
|
|
60
|
+
→ PreInvocation imprint → meta-session <garden-id>
|
|
61
|
+
→ entwurf-bridge MCP sender identity
|
|
62
|
+
↔ entwurf_v2 native-push
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Claude's `install-meta-bridge` and agy's `install-agy-{bridge,statusline,hooks}` are distinct managed install surfaces because their lifecycle and delivery transports are genuinely different. Codex remains verified probe evidence, not a shipped managed native-citizen lane; see [DELIVERY.md](./DELIVERY.md).
|
|
57
66
|
|
|
58
67
|
> **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.
|
|
59
68
|
|
|
@@ -68,7 +77,7 @@ This meta-bridge installer/doctor is **Claude Code only** in the current shipped
|
|
|
68
77
|
A few words that look unusual for a coding tool.
|
|
69
78
|
|
|
70
79
|
- **Entwurf** (기투, projection-of-self) — sibling sessions with their own runtime boundary. Not "delegate," not "worker," not "sub-agent." Spawn, resume, and live peer messaging are first-class.
|
|
71
|
-
- **Garden / garden id** — the garden is the shared address space where independent harness sessions become citizens without losing their own runtime or transcript. A garden id is the stable address of one such citizen (for pi, a garden-native session id like `YYYYMMDDTHHMMSS-<6hex>`; for native harnesses, a meta-session id minted
|
|
80
|
+
- **Garden / garden id** — the garden is the shared address space where independent harness sessions become citizens without losing their own runtime or transcript. A garden id is the stable address of one such citizen (for pi, a garden-native session id like `YYYYMMDDTHHMMSS-<6hex>`; for native harnesses, a meta-session id minted from an authoritative lifecycle hook — Claude `SessionStart`, agy `PreInvocation`). It is not a worker name and not proof that pi owns the session. The same-looking id may name a live control socket, a dormant pi record, a mailbox-backed native session, or a native-push conversation, so callers discover facts with `entwurf_peers` and deliver with `entwurf_v2` instead of choosing a transport by hand.
|
|
72
81
|
- **Engraving** — optional short operator text delivered through each backend's native identity carrier. Not a giant hidden prompt, not a tool catalog.
|
|
73
82
|
- **MCP** — in this repo, MCP is just the transport by which ACP-backed sessions receive pi capabilities that native pi exposes directly as extensions. It is not a general MCP platform. Explicit `entwurfProvider.mcpServers` only; no ambient `~/.mcp.json` scanning, no automatic retrieval. The same `entwurf-bridge` entry can also be wired into another host's MCP catalog (Claude Code, Codex, Antigravity, …) when the operator chooses. `entwurf_self` returns an authoritative pi-session or trusted meta-session identity envelope; `entwurf_v2` can deliver from plain external MCP hosts, but only pi-session and trusted meta-session senders are replyable.
|
|
74
83
|
- **Session persistence** — re-attaches pi to the same remote ACP session. Does not hydrate backend transcripts into pi history.
|
|
@@ -80,15 +89,19 @@ A few words that look unusual for a coding tool.
|
|
|
80
89
|
adapter that hosts the ACP plugin and live control-socket surface, but the base
|
|
81
90
|
install is **not** `pi install npm:...` anymore.
|
|
82
91
|
|
|
83
|
-
The package exposes
|
|
92
|
+
The package exposes five bins:
|
|
84
93
|
|
|
85
|
-
- `entwurf` → `run.sh` (installer, checks,
|
|
94
|
+
- `entwurf` → `run.sh` (installer, checks, native-bridge doctors/installers)
|
|
86
95
|
- `entwurf-bridge` → the MCP stdio launcher (`mcp/entwurf-bridge/start.sh`)
|
|
87
|
-
- `entwurf-statusline` → the Claude Code statusline renderer (`scripts/meta-bridge-statusline.sh`)
|
|
96
|
+
- `entwurf-statusline` → the Claude Code statusline renderer (`scripts/meta-bridge-statusline.sh`)
|
|
97
|
+
- `entwurf-agy-statusline` → the Antigravity garden-id statusline renderer (`scripts/agy-statusline.sh`)
|
|
98
|
+
- `entwurf-agy-imprint` → the Antigravity `PreInvocation` birth/sender hook (`scripts/agy-imprint.sh`)
|
|
88
99
|
|
|
89
|
-
The bridge
|
|
100
|
+
The bridge/renderers/hook use stable bin names so package upgrades do not bake versioned package-store paths into native-harness settings.
|
|
101
|
+
|
|
102
|
+
The bridge does not provide backend credentials, tokens, or subscription access,
|
|
90
103
|
and does not bypass any backend auth. Whatever the operator's local `claude` /
|
|
91
|
-
`codex` / pi runtime already trusts is what entwurf can use.
|
|
104
|
+
`codex` / `agy` / pi runtime already trusts is what entwurf can use.
|
|
92
105
|
|
|
93
106
|
### From npm — user/global install
|
|
94
107
|
|
|
@@ -188,12 +201,21 @@ raw `.ts` helpers under `node_modules`. If the doctor reports
|
|
|
188
201
|
`ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`, reinstall a current package before
|
|
189
202
|
trusting the floor result.
|
|
190
203
|
|
|
191
|
-
After upgrading a globally installed package,
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
204
|
+
After upgrading a globally installed package, reinstall the native-harness surface you use before trusting it:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
entwurf install-meta-bridge
|
|
208
|
+
entwurf doctor-meta-bridge
|
|
209
|
+
|
|
210
|
+
entwurf install-agy-bridge
|
|
211
|
+
entwurf install-agy-statusline
|
|
212
|
+
entwurf install-agy-hooks
|
|
213
|
+
entwurf doctor-agy-bridge
|
|
214
|
+
entwurf doctor-agy-statusline
|
|
215
|
+
entwurf doctor-agy-hooks
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
The installed entries use stable bin shims, but Claude's plugin bundle/cache still has to be re-materialized and agy's three ownership records must be refreshed by their idempotent installers. Restart existing Claude Code and agy processes after reinstall.
|
|
197
219
|
|
|
198
220
|
For manual configuration, [`pi/settings.reference.json`](./pi/settings.reference.json)
|
|
199
221
|
shows the pi adapter settings shape, and the external-host examples below show
|
|
@@ -273,11 +295,11 @@ Reference shape lives in [`pi/settings.reference.json`](./pi/settings.reference.
|
|
|
273
295
|
`entwurf-bridge` can also be registered in a separate MCP-aware harness (Claude Code, Codex CLI, Antigravity/`agy`, …). That host does **not** become a pi session and does **not** need to be ACP-backed. There are now two honest cases:
|
|
274
296
|
|
|
275
297
|
- **plain external MCP host**: no garden meta-record / sender marker. It can call tools, but its sender envelope is external/non-replyable.
|
|
276
|
-
- **garden-native
|
|
298
|
+
- **garden-native native session**: a trusted lifecycle hook minted a garden id and sender marker — `SessionStart` for Claude Code, `PreInvocation` for agy. It is not a pi control-socket session, but it can be replyable by garden id when its own mailbox/probe rail says so.
|
|
277
299
|
|
|
278
|
-
**Which verb an external agent should reach for:** to deliver to / reply to a garden id, use **`entwurf_v2`** — it is the canonical delivery surface and the only one that reads the target
|
|
300
|
+
**Which verb an external agent should reach for:** to deliver to / reply to a garden id, use **`entwurf_v2`** — it is the canonical delivery surface and the only one that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly. Discover targets with `entwurf_peers`, confirm your own identity with `entwurf_self`, drain a mailbox with `entwurf_inbox_read`, and use `entwurf_register_native` only as the explicit/manual fallback for binding an already-running agy conversation (normal agy birth is automatic through the installed hook). Fresh sibling creation from nothing is a deferred lane. (The old v1 verbs `entwurf` / `entwurf_resume` / `entwurf_send` are gone.)
|
|
279
301
|
|
|
280
|
-
Observed: Claude Code, Codex CLI, and Antigravity CLI all reach garden citizens through this MCP bridge from a plain external host
|
|
302
|
+
Observed: Claude Code, Codex CLI, and Antigravity CLI all reach garden citizens through this MCP bridge from a plain external host. Claude becomes symmetric/replyable through its mailbox-backed meta-session; agy becomes symmetric/replyable through its record-backed sender marker plus live native-push probe. Codex remains a plain external/probe lane until it has a managed citizen lifecycle.
|
|
281
303
|
|
|
282
304
|
Prerequisites on the host running the external MCP client:
|
|
283
305
|
|
|
@@ -359,29 +381,27 @@ command = "/absolute/path/to/entwurf/mcp/entwurf-bridge/start.sh"
|
|
|
359
381
|
|
|
360
382
|
#### Antigravity CLI (`agy`)
|
|
361
383
|
|
|
362
|
-
|
|
384
|
+
Use the managed install surface rather than editing agy's files by hand:
|
|
363
385
|
|
|
364
|
-
```
|
|
365
|
-
|
|
386
|
+
```bash
|
|
387
|
+
entwurf install-agy-bridge
|
|
388
|
+
entwurf install-agy-statusline
|
|
389
|
+
entwurf install-agy-hooks
|
|
390
|
+
|
|
391
|
+
entwurf doctor-agy-bridge
|
|
392
|
+
entwurf doctor-agy-statusline
|
|
393
|
+
entwurf doctor-agy-hooks
|
|
366
394
|
```
|
|
367
395
|
|
|
368
|
-
|
|
396
|
+
The three adapters deliberately own different atoms:
|
|
369
397
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
398
|
+
- bridge: one `entwurf-bridge` server in `~/.gemini/config/mcp_config.json`, plus exactly one permission string — `mcp(entwurf-bridge/entwurf_v2)` — in `~/.gemini/antigravity-cli/settings.json`;
|
|
399
|
+
- statusline: the complete `statusLine` subtree pointing at the bare stable bin `entwurf-agy-statusline`;
|
|
400
|
+
- hooks: one named `PreInvocation` hook pointing at the bare stable bin `entwurf-agy-imprint`.
|
|
373
401
|
|
|
374
|
-
|
|
402
|
+
Unrelated servers, permissions, settings, and hooks are preserved; every adapter has a state-backed honest inverse and refuses symlink-owned SSOTs. The installer never grants broad `command(*)`, `unsandboxed(*)`, or other YOLO policy — those remain operator decisions.
|
|
375
403
|
|
|
376
|
-
|
|
377
|
-
{
|
|
378
|
-
"mcpServers": {
|
|
379
|
-
"entwurf-bridge": {
|
|
380
|
-
"command": "/absolute/path/to/entwurf/mcp/entwurf-bridge/start.sh"
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
```
|
|
404
|
+
The **global** MCP config live agy reads is `~/.gemini/config/mcp_config.json`. `~/.gemini/antigravity-cli/mcp_config.json` is not the global MCP root; the bridge installer one-way cleans only a stale entwurf-owned entry there. After the first model invocation, the imprint hook binds the native `conversationId` to a garden id, the statusline shows `🪛 <garden-id> agy`, and sends from that MCP child carry `agentId=meta-session/antigravity` with `replyable:true` only when the record exists and the live native-push probe succeeds.
|
|
385
405
|
|
|
386
406
|
#### External-host skills and commands
|
|
387
407
|
|
|
@@ -397,6 +417,8 @@ The Claude ACP backend keeps its native model / API / tools; entwurf shapes only
|
|
|
397
417
|
|
|
398
418
|
(Codex is *not* an ACP backend here — it reaches the garden natively. Vendor / governed CLIs are a later ACP backend lane.)
|
|
399
419
|
|
|
420
|
+
Antigravity is also not an ACP backend. It is a native-push citizen: `PreInvocation` supplies birth/sender identity, `entwurf_v2` probes and direct-injects replies into the live conversation, and no mailbox/receiver marker is involved.
|
|
421
|
+
|
|
400
422
|
Pi is the canonical memory authority (semantic-memory + Denote llmlog); Claude's native memory layer is pinned off.
|
|
401
423
|
|
|
402
424
|
## Smoke commands
|
|
@@ -404,6 +426,13 @@ Pi is the canonical memory authority (semantic-memory + Denote llmlog); Claude's
|
|
|
404
426
|
```bash
|
|
405
427
|
pnpm check # full deterministic floor (all check-* gates, incl. check-acp-*)
|
|
406
428
|
./run.sh check-bridge # entwurf-bridge direct MCP smoke (no backend auth)
|
|
429
|
+
./run.sh smoke-agy-install-state # agy MCP + exact permission ownership (120 checks)
|
|
430
|
+
./run.sh smoke-agy-statusline-state # agy ambient garden-id install surface (62 checks)
|
|
431
|
+
./run.sh smoke-agy-hooks-state # agy PreInvocation birth hook (37 checks)
|
|
432
|
+
./run.sh check-agy-sender-identity # record-backed pid/start-key sender identity (28 checks)
|
|
433
|
+
|
|
434
|
+
# agy LIVE acceptance — requires an already-running conversation:
|
|
435
|
+
LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live
|
|
407
436
|
|
|
408
437
|
# ACP plugin LIVE acceptance — need the operator's local Claude auth/credit:
|
|
409
438
|
LIVE=1 ./run.sh smoke-acp-socket-citizen-live # turn-free socket citizenship (S1)
|
|
@@ -449,9 +478,9 @@ For a real consumer arranging many skills, see [agent-config](https://github.com
|
|
|
449
478
|
|
|
450
479
|
## Entwurf orchestration
|
|
451
480
|
|
|
452
|
-
**Entwurf is
|
|
481
|
+
**Entwurf is one dispatch capability with native-pi and MCP surfaces.** Native pi exposes it directly as extension tools; ACP-backed and external native-harness sessions reach it through `entwurf-bridge`. The purpose is not to invent a different sub-agent system, but to preserve the same sibling-based model across harnesses.
|
|
453
482
|
|
|
454
|
-
A sibling has its own runtime boundary and its own provider/model identity — not a worker, delegate, or sub-agent. Minting a brand-new sibling from nothing is a deferred v2 lane (`spawn-fresh`); today every transport targets an *existing* garden citizen. `entwurf_v2`
|
|
483
|
+
A sibling has its own runtime boundary and its own provider/model identity — not a worker, delegate, or sub-agent. Minting a brand-new sibling from nothing is a deferred v2 lane (`spawn-fresh`); today every transport targets an *existing* garden citizen. `entwurf_v2` routes from rail-specific liveness + intent: live pi fire-and-forget → control socket; dormant pi owned-outcome → spawn-bg resume; active self-fetch → meta-mailbox; probe-alive agy → native-push. Pi paths use the per-target lock; mailbox/native-push use their own deliverability evidence and remain lock-free.
|
|
455
484
|
|
|
456
485
|
A two-pane recording covers the surface end-to-end — sibling resume, cross-process MCP dispatch across a different cwd, and a live peer greeting:
|
|
457
486
|
|
|
@@ -464,11 +493,11 @@ A two-pane recording covers the surface end-to-end — sibling resume, cross-pro
|
|
|
464
493
|
|
|
465
494
|
Live peer messaging carries a sender envelope `{ sessionId, agentId, cwd, timestamp }`; `entwurf_self` returns that authoritative envelope for the current pi session or trusted meta-session. Plain external MCP hosts are non-replyable; garden-native meta-sessions carry a trusted `meta-session` envelope and are replyable by garden id. `wants_reply` is an etiquette marker rendered as a `(wants reply)` badge — not a transport contract, no wait, no polling — and is rejected only from non-replyable external senders.
|
|
466
495
|
|
|
467
|
-
In ACP-backed sessions,
|
|
496
|
+
In ACP-backed and external native-harness sessions, `entwurf-bridge` exposes five tools: `entwurf_v2`, `entwurf_peers`, `entwurf_self`, `entwurf_inbox_read`, and the explicit/manual `entwurf_register_native` fallback. Native pi exposes the shared capability directly through the extension surface (`entwurf_v2`, `entwurf_peers` tools + `/entwurf-sessions`, `/gnew` commands). **For garden-id delivery/reply use `entwurf_v2`** — the canonical surface that classifies the target and routes to live-pi / dormant-resume / Claude-Code-meta-mailbox / Antigravity-native-push. Fresh sibling creation from nothing is a deferred lane. (The v1 verbs `entwurf` / `entwurf_resume` / `entwurf_send` are gone.) Garden-native operator commands require `--entwurf-control`. The spawn target allowlist is [`pi/entwurf-targets.json`](./pi/entwurf-targets.json).
|
|
468
497
|
|
|
469
498
|
### `entwurf_v2` — canonical dispatch verb
|
|
470
499
|
|
|
471
|
-
`entwurf_v2` / `runEntwurfV2` is the canonical v2 dispatch verb over **existing** garden targets — record-backed citizens plus live socket-only `pi` endpoints (a record-less but live `pi --entwurf-control` peer is a *target*, intentionally **not** an owned citizen). You give a target garden id plus an intent (`fire-and-forget` or `owned-outcome`); one decider reads the target's liveness as a fact
|
|
500
|
+
`entwurf_v2` / `runEntwurfV2` is the canonical v2 dispatch verb over **existing** garden targets — record-backed citizens plus live socket-only `pi` endpoints (a record-less but live `pi --entwurf-control` peer is a *target*, intentionally **not** an owned citizen). You give a target garden id plus an intent (`fire-and-forget` or `owned-outcome`); one decider reads the target's liveness as a fact and picks the transport from a frozen table keyed on **both** the target's state **and** the intent — never on state alone — then reports one outcome under the v2 lock policy. Pi control-socket and spawn-bg paths take a per-target lock; mailbox and native-push are lock-free, with deliverability guarded by their own receiver/probe evidence:
|
|
472
501
|
|
|
473
502
|
| target state | intent | transport |
|
|
474
503
|
|---|---|---|
|
|
@@ -479,10 +508,13 @@ In ACP-backed sessions, agent tools (`entwurf_v2`, `entwurf_peers`, `entwurf_sel
|
|
|
479
508
|
| active self-fetch receiver | fire-and-forget | meta-mailbox enqueue + doorbell |
|
|
480
509
|
| inactive / terminated self-fetch receiver | fire-and-forget | **reject** (`mailbox-undeliverable` — no `.msg`, no doorbell) |
|
|
481
510
|
| self-fetch | owned-outcome | **reject** (no owned result over a mailbox) |
|
|
511
|
+
| live native-push conversation | fire-and-forget | native-push direct injection |
|
|
512
|
+
| dead / indeterminate native-push conversation | fire-and-forget | **reject** (`native-push-target-dead` / `native-push-probe-indeterminate`) |
|
|
513
|
+
| native-push | owned-outcome | **reject** (`native-push-no-resume-authority`) |
|
|
482
514
|
|
|
483
|
-
**`entwurf_v2` is the canonical surface for garden-id delivery.** When you have a garden id and want to reach whoever it names — message, reply, or hand-off — `entwurf_v2` is the one surface that reads whether the target is
|
|
515
|
+
**`entwurf_v2` is the canonical surface for garden-id delivery.** When you have a garden id and want to reach whoever it names — message, reply, or hand-off — `entwurf_v2` is the one surface that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly; *when unsure which transport, use `entwurf_v2`*. This prevents callers from guessing a rail from the shape of an id.
|
|
484
516
|
|
|
485
|
-
What v2 provides is a **deterministic dispatch substrate** that moves the "which transport?" decision out of the fallible caller/model and into the decider,
|
|
517
|
+
What v2 provides is a **deterministic dispatch substrate** that moves the "which transport?" decision out of the fallible caller/model and into the decider, with transport-appropriate locking and an honest reject (no `✓ delivered`, no `.msg` garbage) when a target cannot receive. What it does **not** do is **fresh sibling creation** — minting a brand-new sibling from a provider/model/prompt is a deferred lane (the `dormant pi → spawn-bg resume` row above resumes an *already-identified* citizen, it does not mint one). The meta-mailbox row requires an **active** self-fetch receiver; native-push requires a record-backed, probe-alive native conversation and never borrows mailbox state. Claude↔Claude / Claude tmux-live transport is a later lane (the contract enum names `tmux-live` but no production path executes it).
|
|
486
518
|
|
|
487
519
|
A live pi target is addressed by its **control socket**, so a record-less but live `pi --entwurf-control` session (an operator-greeted peer with no meta-record) is accepted as a `fire-and-forget` control-send target, matching what `entwurf_peers` lists as alive. An `owned-outcome` resume, however, needs a record-backed citizen (its cwd/launch authority); a record-less endpoint is a socket-only fire-and-forget target only — record-less dormant resume is a later lane.
|
|
488
520
|
|
|
@@ -524,7 +556,7 @@ Enforcement (no uuid / back-compat path): a `--entwurf-control` session whose id
|
|
|
524
556
|
|
|
525
557
|
The human-greeted 담당자 pattern is first-class: the operator opens a entwurf session in repo B, greets it directly, then passes that `sessionId` to another session, which reaches it via `entwurf_v2`. Resumed citizens and human-opened peers share the same messaging semantics; only how they came to exist differs.
|
|
526
558
|
|
|
527
|
-
**Mitsein over MCP** (공존) — the cross-harness counterpart. Pi may collaborate with an external interactive coding session (Claude Code, Codex, Antigravity used as a human terminal) without spawning it. A plain external host is one-directional in shape:
|
|
559
|
+
**Mitsein over MCP** (공존) — the cross-harness counterpart. Pi may collaborate with an external interactive coding session (Claude Code, Codex, Antigravity used as a human terminal) without spawning it. A plain external host is one-directional in shape: inbound `external → pi` returns through this bridge's `entwurf_v2`, but the host has no reply address. A garden-native native session closes that gap on its own rail: Claude Code through mailbox self-fetch, agy through probe-alive native-push. `wants_reply` is allowed only when the sender marker and rail-specific evidence prove replyability. Async `owned-outcome` still needs a dormant pi citizen with spawn authority; neither mailbox nor native-push has it. This is still not a second harness — no control daemon and no transcript scraping are introduced.
|
|
528
560
|
|
|
529
561
|
After a session is anchored, entwurf locks its model identity: switches that touch `entwurf` are reverted; native-to-native and pre-turn selection remain free. `ensureBridgeSession` refuses direct reuse-path mismatches before backend handoff.
|
|
530
562
|
|
package/VERIFY.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# VERIFY.md
|
|
2
2
|
|
|
3
|
-
Agent-driven verification guide for `entwurf`
|
|
3
|
+
Agent-driven verification guide for the current `entwurf` 0.12.x surface.
|
|
4
4
|
|
|
5
|
-
> **Current surface.** The
|
|
5
|
+
> **Current surface.** The bundled MCP server, `entwurf-bridge`, exposes five tools: `entwurf_v2`, `entwurf_peers`, `entwurf_self`, `entwurf_inbox_read`, and `entwurf_register_native` (an explicit/manual fallback for binding an already-running native conversation). The shipped ACP backend is **Claude**. Antigravity (`agy`) is a separate shipped **native-push citizen** lane, not an ACP backend: automatic `PreInvocation` birth + sender identity + live probe/direct injection. Codex is pi-native by default and has native delivery probe evidence; Gemini is a non-goal/historical ACP probe on 0.12. The 0.4.x `session-bridge` adapter, the 0.11.0 fat-bridge (`acp-bridge.ts` / `ensureBridgeSession`), and the v1 `entwurf` / `entwurf_resume` / `entwurf_send` verbs are **retired** — rows mentioning them survive in CHANGELOG/git as historical baseline, never as a runnable recipe.
|
|
6
6
|
|
|
7
7
|
This is a **working document, not a metrics document**. The deterministic and live gates carry the machine-checkable invariants; this file carries only what a gate cannot judge — the human/agent reading of *whether the bridge is honestly itself*. Where a former manual procedure is now a gate, it is named as a pointer rather than re-spelled as a runnable script.
|
|
8
8
|
|
|
@@ -39,12 +39,15 @@ Verification here is not a benchmark. In production we exchange short turns and
|
|
|
39
39
|
- **BEHAVIOR tier** (advisory, non-blocking): the resident-garden-guard positive (a model-in-loop `entwurf_self` turn). A BEHAVIOR FAIL is surfaced with its artifact path but **never blocks the cut**.
|
|
40
40
|
- LIVE-gated MUST steps honest-skip when `LIVE!=1`; a real cut needs `LIVE=1` with `SKIP=0`. A green MUST gate is **necessary, not sufficient** — GLG authorizes the cut.
|
|
41
41
|
|
|
42
|
-
> The
|
|
42
|
+
> The aggregate release gate does not own a live agy conversation id, so agy's real native-push round trip is a separate acceptance axis: three fail-loud doctors plus `LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live`, followed by a fresh-conversation sender/reply check after package install. Its deterministic install/sender gates are already inside `pnpm check`; do not misreport the aggregate gate as live agy evidence.
|
|
43
|
+
>
|
|
44
|
+
> The authoritative per-cut counts live in BASELINE.md's HISTORY and CHANGELOG/git, not inline here (they drift against `run.sh`). Most recent recorded aggregate floor: **2026-06-27 — MUST 17/0/0 + BEHAVIOR 1/0**.
|
|
43
45
|
|
|
44
46
|
### Verifying the two capabilities a gate cannot fully judge
|
|
45
47
|
|
|
46
|
-
- **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2` with the correct intent — `fire-and-forget` for
|
|
48
|
+
- **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2` with the correct intent — `fire-and-forget` for live pi, mailbox-backed meta, or native-push targets; `owned-outcome` only to wake a dormant record-backed pi citizen. Picking the wrong intent is rejected, never auto-fixed.
|
|
47
49
|
- **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.
|
|
50
|
+
- **agy citizenship:** in a fresh agy conversation, the first `PreInvocation` must yield a garden id, `entwurf_self` must report `agentId=meta-session/antigravity` and `replyable:true` only while the native probe is alive, and a reply to that same garden id must direct-inject into the same conversation. No mailbox/receiver-marker evidence counts on this rail.
|
|
48
51
|
|
|
49
52
|
### What NOT to do — bypassing the operational path
|
|
50
53
|
|
|
@@ -92,8 +95,9 @@ The goal is not merely "invoke Claude Code." We want:
|
|
|
92
95
|
|
|
93
96
|
1. `pnpm install` — bundles pi (a dev/peer dependency; no separate `pi install` step) and builds the bridge
|
|
94
97
|
2. project wiring → `<project>/.pi/settings.json` `entwurfProvider.mcpServers.entwurf-bridge`
|
|
95
|
-
3. meta-bridge global plugin — only when
|
|
96
|
-
4.
|
|
98
|
+
3. Claude meta-bridge global plugin — only when `claude` is on PATH; otherwise skipped cleanly
|
|
99
|
+
4. agy bridge + exact permission + statusline + `PreInvocation` hook — only when `agy` is on PATH; each adapter is idempotent and independently doctorable
|
|
100
|
+
5. `entwurf-bridge` install smoke (`validate_entwurf_bridge`)
|
|
97
101
|
|
|
98
102
|
```bash
|
|
99
103
|
git clone https://github.com/junghan0611/entwurf /path/to/entwurf && cd $_
|
|
@@ -101,7 +105,7 @@ git clone https://github.com/junghan0611/entwurf /path/to/entwurf && cd $_
|
|
|
101
105
|
# re-run the SAME command any time to repair a broken install
|
|
102
106
|
```
|
|
103
107
|
|
|
104
|
-
Expected tail: `DONE: entwurf setup (pi
|
|
108
|
+
Expected tail: `DONE: entwurf setup (pi adapter + detected native bridges + v2 install smoke) green.` On a host with `claude`, verify `./run.sh doctor-meta-bridge`. On a host with `agy`, verify all three: `doctor-agy-bridge`, `doctor-agy-statusline`, and `doctor-agy-hooks`. Setup keeps optional-harness failures non-fatal so pi/Claude hosts are not bricked; the doctors are the fail-loud acceptance surface.
|
|
105
109
|
|
|
106
110
|
The wiring / meta-bridge / smoke steps are internal building blocks of `setup` (`install_local_package`, `scripts/meta-bridge-install.sh`, `validate_entwurf_bridge`) — call `setup`, never the parts. Consumers who `npm install @junghanacs/entwurf` get the obvious npm surface; that path is not the developer concern here.
|
|
107
111
|
|
|
@@ -120,11 +124,11 @@ LIVE=1 ./run.sh release-gate /path/to/consumer-project
|
|
|
120
124
|
pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only" # one-turn smoke
|
|
121
125
|
```
|
|
122
126
|
|
|
123
|
-
`setup` runs `pnpm install` +
|
|
127
|
+
`setup` runs `pnpm install` + project/user-scope install + detected native-harness wiring (Claude and/or agy) + the v2 install smoke. A green setup proves the required core path and reports optional-harness degradation; it does **not** replace the native-harness doctors. The full aggregate live floor is still `LIVE=1 ./run.sh release-gate`, with agy's conversation-id-gated round trip verified separately.
|
|
124
128
|
|
|
125
129
|
### 1.4 Cross-install / cross-backend parity (optional, high-value)
|
|
126
130
|
|
|
127
|
-
Compare a fresh self-awareness report across axes: (1) same backend, different install path — answer must be path-invariant; (2) same backend, different machine — identical native tool list + MCP server/tool set; (3) different backend, same bridge — same
|
|
131
|
+
Compare a fresh self-awareness report across axes: (1) same backend, different install path — answer must be path-invariant; (2) same backend, different machine — identical native tool list + MCP server/tool set; (3) different backend, same bridge — same garden capability but **different** native tool surface (a Claude session reporting another backend's native tools is a fail); (4) native pi routing vs ACP-bridged, same model — the native target reports no `entwurf-bridge` MCP (capability via pi's extension surface), while the ACP target reports it as the single MCP server. Honest "native: I cannot tell" hedging is PASS on the native side. Claude axes 1–4 are closed. agy is graded by the separate native-citizen checklist above, not by pretending it has Claude's ACP overlay. Gemini remains probe-only on 0.12.
|
|
128
132
|
|
|
129
133
|
---
|
|
130
134
|
|
|
@@ -147,7 +151,7 @@ Pass (carrier honesty): the subject distinguishes engraving from pi-context-augm
|
|
|
147
151
|
|
|
148
152
|
- **Layer 0 — self-awareness:** ask environment self-awareness / MCP visibility / upstream-instruction awareness, guessing prohibited. Pass: recognizes native tool family, says "I don't know" honestly, answers MCP visibility only as configured, describes upstream instruction type without reproducing internal prompts. Fail: claims a nonexistent tool, conflates pi-custom and native tools, hallucinates MCP visibility, or conflates the two carriers (§1A.0).
|
|
149
153
|
- **Layer 1 — native tool use:** throw file-reading / structure-analysis / regression-hunting tasks. Pass: Read/Edit/Bash/Grep/Glob selection is natural; no detour through MCP or recursive `pi`. Fail: strange detours for simple reads; speaks from memory without reading.
|
|
150
|
-
- **Layer 2 — MCP boundary:** by default the
|
|
154
|
+
- **Layer 2 — MCP boundary:** by default the five entwurf MCP tools are not visible (they appear only when `entwurf-bridge` is registered). Pass: says invisible tools are not visible; explains the native-vs-MCP boundary; treats `entwurf_register_native` as binding an already-running conversation, never as fresh spawn. Fail: pretends to use an unseen tool; mimics entwurf via recursive `pi`.
|
|
151
155
|
- **Layer 3 — focus across turns:** inject a fact, then accumulate turns mixing retrieval/exploration. Pass (post-0.4.1): after **8 turns** holds **3+ early facts** incl. **one verbatim string injected before turn 5**; no repeated exploration, no self-contradiction, no tool-strategy drift. Fail: forgets early reads; paraphrases instead of returning the verbatim string. Note: entwurf exposes no user-facing compaction; use the backend's `usage_update` footer as an overflow-risk signal (it follows the ACP backend's `used/size`, not pi's visible-transcript estimate).
|
|
152
156
|
- **Layer 4 — vs direct Claude Code:** requires a verifier holding **both** the `entwurf` and a direct path (human-in-loop, or both transport handles). Compare latency / native tool accuracy / detours / boundary confusion / quality around turns 10–15. Repeated tool confusion, long-turn forgetting, or boundary workarounds are a fail.
|
|
153
157
|
|
|
@@ -215,10 +219,11 @@ The minimum passing bar:
|
|
|
215
219
|
|
|
216
220
|
1. **Deterministic floor green:** `pnpm check` passes (lint + typecheck + the `check-*` gate set + `check-pack`).
|
|
217
221
|
2. **Live floor MUST green:** `LIVE=1 ./run.sh release-gate <dir>` reports `MUST PASS=N FAIL=0 SKIP=0`; a BEHAVIOR FAIL is advisory, not blocking.
|
|
218
|
-
3. **Honest self-recognition:** the bridged model identifies
|
|
222
|
+
3. **Honest self-recognition:** the bridged model identifies its actual harness/backend, lists `entwurf-bridge` as the single MCP server with its five current tools, and presents a backend-native (not normalized) tool surface.
|
|
219
223
|
4. **Carrier separation honored:** engraving vs pi-context-augment kept distinct (§1A.0); no bridge-identity narrative attributed to the engraving carrier.
|
|
220
|
-
5. **
|
|
221
|
-
6. **
|
|
224
|
+
5. **agy shipped lane accepted:** all three agy doctors are green; automatic birth/statusline/sender identity and same-gid native-push reply are confirmed in a fresh conversation. `agentId=meta-session/antigravity` is correct; model display is not part of that contract. Same-pid concurrent conversation invocation is not claimed.
|
|
225
|
+
6. **Boundary preservation across backends/machines:** for every shipped or explicitly probed backend, regardless of install path or host, no cross-backend tool-surface contamination and no confabulation about pi internals.
|
|
226
|
+
7. **Hygiene:** no orphan ACP children; no unexpected persisted session garbage (a turn-scoped `cwd:` fallback is never a persisted reuse).
|
|
222
227
|
|
|
223
228
|
Passing establishes a **release verification floor**, not an 8-hour/day operational guarantee. The floor says: gates hold, the agent honestly recognizes its environment, no tool surface is normalized away, no identity leaks, no orphans. It does **not** say a real-day workload (50–100+ turns, tool bursts, partial MCP failures, auth/version drift) survives — that needs L3–L5 evidence (appendix).
|
|
224
229
|
|
package/docs/setup-clean-host.md
CHANGED
|
@@ -4,11 +4,12 @@ End-to-end install of **entwurf** on a host with only `git` available — no
|
|
|
4
4
|
node, no npm package, no pi binary, no dotfiles. The point is to validate the
|
|
5
5
|
public install surface as an outside user would experience it.
|
|
6
6
|
|
|
7
|
-
> **Scope.** This is the entwurf 0.12.
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
>
|
|
11
|
-
> bridge, doctor, or
|
|
7
|
+
> **Scope.** This is the current entwurf 0.12.x install recipe, including the
|
|
8
|
+
> 0.12.7 Antigravity (`agy`) citizen surface. The base package install is
|
|
9
|
+
> **neutral npm**, not `pi install npm:...`. Pi is an optional adapter lane for
|
|
10
|
+
> the ACP provider / control-socket runtime. Installed packages under
|
|
11
|
+
> `node_modules` must not run raw `.ts` bridge, doctor, or native-hook helpers
|
|
12
|
+
> through Node strip-types.
|
|
12
13
|
|
|
13
14
|
`entwurf` is a garden-citizen dispatch substrate and meta-bridge. It does not
|
|
14
15
|
provide, copy, or mediate backend credentials — it lets the official backend CLI
|
|
@@ -21,7 +22,7 @@ Written against a clean Ubuntu / Debian / macOS host reachable via SSH, here
|
|
|
21
22
|
called `cleanhost`. `nvm` keeps the path identical across them.
|
|
22
23
|
|
|
23
24
|
```bash
|
|
24
|
-
ssh cleanhost 'uname -a; whoami; which git node npm pi claude 2>/dev/null'
|
|
25
|
+
ssh cleanhost 'uname -a; whoami; which git node npm pi claude agy 2>/dev/null'
|
|
25
26
|
# expect on a fully clean host: git present, node/npm/pi/claude absent
|
|
26
27
|
```
|
|
27
28
|
|
|
@@ -31,8 +32,9 @@ ssh cleanhost 'uname -a; whoami; which git node npm pi claude 2>/dev/null'
|
|
|
31
32
|
|---|---|---|
|
|
32
33
|
| Node | **24** recommended; `>=22.6.0` minimum | `engines.node` (Node strip-types / ESM runtime) |
|
|
33
34
|
| npm | bundled with Node 24 | public package install path |
|
|
34
|
-
| entwurf | `@junghanacs/entwurf` | neutral npm package; exposes `entwurf`, `entwurf-bridge`,
|
|
35
|
+
| entwurf | `@junghanacs/entwurf` | neutral npm package; exposes `entwurf`, `entwurf-bridge`, `entwurf-statusline`, `entwurf-agy-statusline`, and `entwurf-agy-imprint` bins |
|
|
35
36
|
| 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 |
|
|
37
|
+
| Antigravity `agy` | **optional**, operator-installed/authenticated native CLI | needed only for the shipped native-push citizen lane; entwurf never moves its auth |
|
|
36
38
|
|
|
37
39
|
## Stage 0 — Node 24 via nvm
|
|
38
40
|
|
|
@@ -65,6 +67,8 @@ npm install -g @junghanacs/entwurf
|
|
|
65
67
|
which entwurf
|
|
66
68
|
which entwurf-bridge
|
|
67
69
|
which entwurf-statusline
|
|
70
|
+
which entwurf-agy-statusline
|
|
71
|
+
which entwurf-agy-imprint
|
|
68
72
|
entwurf --help | head -5
|
|
69
73
|
```
|
|
70
74
|
|
|
@@ -78,11 +82,12 @@ Prove the installed MCP server answers `tools/list` from inside `node_modules`.
|
|
|
78
82
|
This is the first `node_modules` strip-types regression fixed in 0.12.0: Node
|
|
79
83
|
refuses `--experimental-strip-types` for `.ts` under `node_modules`, so the
|
|
80
84
|
installed package must boot the prebuilt JS under `mcp/entwurf-bridge/dist/`.
|
|
81
|
-
The same installed-vs-dev split
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
`dist/
|
|
85
|
-
tsc-emitted JS on
|
|
85
|
+
The same installed-vs-dev split closes every shipped `.ts`-at-runtime surface on
|
|
86
|
+
that fence: the `doctor-meta-bridge` store-scan helper (0.12.4), the Claude plugin
|
|
87
|
+
hook (0.12.5, compiled `dist/pi-extensions/meta-bridge-hook.js`), and the agy
|
|
88
|
+
`PreInvocation` imprint (0.12.7, compiled `dist/scripts/agy-imprint.js`). Installed
|
|
89
|
+
packages run tsc-emitted JS on these paths; dev clones keep transparent `.ts`
|
|
90
|
+
source execution.
|
|
86
91
|
|
|
87
92
|
```bash
|
|
88
93
|
node --input-type=module <<'JS'
|
|
@@ -96,7 +101,7 @@ child.stdout.on('data', d => {
|
|
|
96
101
|
try {
|
|
97
102
|
const msg = JSON.parse(out.trim());
|
|
98
103
|
const names = (msg.result?.tools ?? []).map(t => t.name).sort();
|
|
99
|
-
for (const n of ['entwurf_v2','entwurf_peers','entwurf_self','entwurf_inbox_read']) {
|
|
104
|
+
for (const n of ['entwurf_v2','entwurf_peers','entwurf_self','entwurf_inbox_read','entwurf_register_native']) {
|
|
100
105
|
if (!names.includes(n)) throw new Error(`missing ${n}: ${names.join(',')}`);
|
|
101
106
|
}
|
|
102
107
|
clearTimeout(timer);
|
|
@@ -108,8 +113,9 @@ child.stdin.write(JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }
|
|
|
108
113
|
JS
|
|
109
114
|
```
|
|
110
115
|
|
|
111
|
-
Expected: a comma-separated tool list containing all
|
|
112
|
-
exit code 0, no backend auth required.
|
|
116
|
+
Expected: a comma-separated tool list containing all five current `entwurf_*`
|
|
117
|
+
tools, exit code 0, no backend auth required. `entwurf_register_native` binds an
|
|
118
|
+
already-running native conversation; it is not a fresh-spawn verb.
|
|
113
119
|
|
|
114
120
|
## Stage 3 — wire a project for the pi adapter / ACP plugin (optional)
|
|
115
121
|
|
|
@@ -178,7 +184,54 @@ A plain external MCP host can call tools but is non-replyable. A garden-native
|
|
|
178
184
|
meta-session has a garden id, a mailbox, and a trusted sender marker; it can call
|
|
179
185
|
`entwurf_self`, receive mailbox wakeups, and be replied to by garden id.
|
|
180
186
|
|
|
181
|
-
## Stage 5 —
|
|
187
|
+
## Stage 5 — Antigravity native citizen (optional)
|
|
188
|
+
|
|
189
|
+
If `agy` is already installed and authenticated by the operator, wire the three
|
|
190
|
+
separate ownership atoms. Entwurf does not install agy or copy its auth.
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
which agy
|
|
194
|
+
|
|
195
|
+
entwurf install-agy-bridge
|
|
196
|
+
entwurf install-agy-statusline
|
|
197
|
+
entwurf install-agy-hooks
|
|
198
|
+
|
|
199
|
+
entwurf doctor-agy-bridge
|
|
200
|
+
entwurf doctor-agy-statusline
|
|
201
|
+
entwurf doctor-agy-hooks
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
What these commands own:
|
|
205
|
+
|
|
206
|
+
- `install-agy-bridge`: one MCP server in `~/.gemini/config/mcp_config.json`
|
|
207
|
+
and exactly `mcp(entwurf-bridge/entwurf_v2)` in
|
|
208
|
+
`~/.gemini/antigravity-cli/settings.json`'s permission allow-list;
|
|
209
|
+
- `install-agy-statusline`: the `statusLine` subtree only, pointing at
|
|
210
|
+
`entwurf-agy-statusline`;
|
|
211
|
+
- `install-agy-hooks`: one named plugin `PreInvocation` hook pointing at
|
|
212
|
+
`entwurf-agy-imprint`.
|
|
213
|
+
|
|
214
|
+
They preserve unrelated user state, record independent install-state under
|
|
215
|
+
`$XDG_DATA_HOME/entwurf/`, and refuse symlink-owned config instead of writing
|
|
216
|
+
through someone else's SSOT. Broad YOLO rules such as `command(*)` and
|
|
217
|
+
`unsandboxed(*)` are operator policy and are never granted by this package.
|
|
218
|
+
|
|
219
|
+
Restart agy, open a **fresh conversation**, and make one model invocation. The
|
|
220
|
+
hook's first `PreInvocation` births/attaches the conversation by native
|
|
221
|
+
`conversationId`; after that, the statusline should show `🪛 <garden-id> agy`.
|
|
222
|
+
Verify:
|
|
223
|
+
|
|
224
|
+
1. `entwurf_self` reports that gid with `agentId=meta-session/antigravity` and
|
|
225
|
+
`replyable:true` while the native route probes alive;
|
|
226
|
+
2. an `entwurf_v2` send from agy reaches a sibling with that sender gid;
|
|
227
|
+
3. a sibling's `entwurf_v2(..., intent=fire-and-forget)` reply to the same gid
|
|
228
|
+
direct-injects into the same agy conversation.
|
|
229
|
+
|
|
230
|
+
This rail has no mailbox/receiver marker and no `owned-outcome` authority.
|
|
231
|
+
Same-pid concurrent conversation invocation is not supported; separate agy
|
|
232
|
+
processes have separate pid/start-key sender markers.
|
|
233
|
+
|
|
234
|
+
## Stage 6 — backend auth and live ACP runtime smoke
|
|
182
235
|
|
|
183
236
|
Backend authentication is the operator's responsibility and lives entirely
|
|
184
237
|
outside entwurf. For the Claude ACP lane:
|
|
@@ -196,7 +249,7 @@ pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only"
|
|
|
196
249
|
If the backend CLI fails directly (`claude -p "ping"`), fix that upstream first.
|
|
197
250
|
`entwurf` surfaces missing auth; it does not repair it.
|
|
198
251
|
|
|
199
|
-
## Stage
|
|
252
|
+
## Stage 7 — garden/control-socket surface (optional)
|
|
200
253
|
|
|
201
254
|
To address a long-lived pi session from another session or an external MCP host,
|
|
202
255
|
open it with `--entwurf-control`. A garden-native `--session-id` is required —
|
|
@@ -210,7 +263,8 @@ pi --session-id "$(entwurf new-session-id)" \
|
|
|
210
263
|
|
|
211
264
|
Use `entwurf_peers` to discover citizens and `entwurf_v2` to deliver by garden
|
|
212
265
|
id. Do not choose the transport by hand: the same-looking id may name a live pi
|
|
213
|
-
socket, a dormant pi record,
|
|
266
|
+
socket, a dormant pi record, a mailbox-backed Claude session, or a native-push
|
|
267
|
+
Antigravity conversation.
|
|
214
268
|
|
|
215
269
|
## Teardown
|
|
216
270
|
|
|
@@ -218,8 +272,11 @@ socket, a dormant pi record, or a mailbox-backed native session.
|
|
|
218
272
|
# project wiring
|
|
219
273
|
rm -rf ~/entwurf-smoke/.pi
|
|
220
274
|
|
|
221
|
-
#
|
|
275
|
+
# native-harness surfaces (if installed)
|
|
222
276
|
entwurf uninstall-meta-bridge 2>/dev/null || true
|
|
277
|
+
entwurf uninstall-agy-hooks 2>/dev/null || true
|
|
278
|
+
entwurf uninstall-agy-statusline 2>/dev/null || true
|
|
279
|
+
entwurf uninstall-agy-bridge 2>/dev/null || true
|
|
223
280
|
|
|
224
281
|
# package and optional pi binary
|
|
225
282
|
npm uninstall -g @junghanacs/entwurf
|
|
@@ -231,6 +288,7 @@ rm -rf ~/.nvm
|
|
|
231
288
|
```
|
|
232
289
|
|
|
233
290
|
This walk-through is a verification floor underneath release cuts: neutral npm
|
|
234
|
-
install, installed bridge boot, optional pi adapter registration,
|
|
235
|
-
|
|
236
|
-
|
|
291
|
+
install, installed bridge boot, optional pi adapter registration, Claude
|
|
292
|
+
meta-bridge verification where used, all three agy doctors plus a fresh native
|
|
293
|
+
round trip where used, and at least one authenticated ACP runtime smoke. GLG owns
|
|
294
|
+
the publish/tag decision.
|