@junghanacs/entwurf 0.41.2 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/AGENTS.md +4 -2
  2. package/BASELINE.md +110 -1
  3. package/CHANGELOG.md +328 -0
  4. package/CONTRIBUTING.md +1 -1
  5. package/ENTWURF-CLI.json +1229 -0
  6. package/ENTWURF.json +284 -0
  7. package/FAQ.md +4 -4
  8. package/README.md +125 -184
  9. package/VERIFY.md +2 -2
  10. package/docs/external-mcp-host.md +3 -3
  11. package/docs/setup-clean-host.md +37 -12
  12. package/mcp/entwurf-bridge/dist/ENTWURF.json +284 -0
  13. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +46 -196
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/agent-guidance.js +299 -0
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +21 -25
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +498 -29
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-dispatch.js +47 -10
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +613 -33
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-resume-call.js +497 -0
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +3 -1
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +23 -20
  22. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +68 -21
  23. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +7 -1
  24. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-location.js +347 -0
  25. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-owner-fence.js +1132 -0
  26. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +1 -0
  27. package/mcp/entwurf-bridge/dist/pi-extensions/lib/remote-pair-send.js +7 -4
  28. package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +18 -11
  29. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +53 -60
  30. package/mcp/entwurf-bridge/dist/scripts/herdr-rails.mjs +40 -7
  31. package/mcp/entwurf-bridge/dist/scripts/meta-bridge-fresh-cut.js +1 -27
  32. package/mcp/entwurf-bridge/dist/scripts/meta-bridge-prune.js +1 -1
  33. package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +1 -1
  34. package/mcp/entwurf-bridge/dist/scripts/peer-facts.js +1 -1
  35. package/mcp/entwurf-bridge/src/index.ts +149 -327
  36. package/mcp/entwurf-bridge/tsconfig.build.json +7 -1
  37. package/native/win32-x64/manifest.json +1 -1
  38. package/package.json +8 -4
  39. package/pi/pi-durable/bootstrap.mjs +179 -6
  40. package/pi/pi-durable/carrier/runtime.js +108 -9
  41. package/pi/pi-durable/carrier/session-name.js +11 -0
  42. package/pi/pi-durable/carrier/sessions.js +96 -20
  43. package/pi/pi-durable/overlay/upstream-pin.json +11 -5
  44. package/pi-extensions/lib/agent-guidance.ts +341 -0
  45. package/pi-extensions/lib/entwurf-v2-surface.ts +25 -31
  46. package/pi-extensions/lib/entwurf-v2-visible-resume.ts +725 -54
  47. package/pi-extensions/lib/fresh-call-dispatch.ts +64 -12
  48. package/pi-extensions/lib/herdr-fresh-call.ts +919 -40
  49. package/pi-extensions/lib/herdr-resume-call.ts +810 -0
  50. package/pi-extensions/lib/meta-session.ts +13 -8
  51. package/pi-extensions/lib/mux-fresh-call.ts +23 -26
  52. package/pi-extensions/lib/mux-resume-call.ts +95 -23
  53. package/pi-extensions/lib/pi-durable-fresh-preflight.ts +9 -2
  54. package/pi-extensions/lib/pi-durable-location.ts +446 -0
  55. package/pi-extensions/lib/pi-durable-owner-fence.ts +1461 -0
  56. package/pi-extensions/lib/pi-durable-runtime.ts +4 -0
  57. package/pi-extensions/lib/remote-pair-send.ts +7 -4
  58. package/pi-extensions/lib/resume-launch-identity.ts +31 -12
  59. package/pi-extensions/meta-bridge-pi-durable.ts +52 -79
  60. package/run.sh +417 -654
  61. package/scripts/build-bridge.sh +10 -0
  62. package/scripts/check-capability-bundle-reach.ts +86 -0
  63. package/scripts/check-claude-launch.ts +341 -0
  64. package/scripts/check-entwurf-self-address.ts +3 -3
  65. package/scripts/check-entwurf-v2-surface.ts +94 -98
  66. package/scripts/check-fresh-call-dispatch.ts +70 -9
  67. package/scripts/check-fresh-cut-gate.sh +23 -9
  68. package/scripts/check-gate-qualification.ts +24 -17
  69. package/scripts/check-herdr-activation.ts +301 -23
  70. package/scripts/check-herdr-fresh-call.ts +161 -25
  71. package/scripts/check-herdr-plugin-build.ts +173 -1
  72. package/scripts/check-herdr-plugin.ts +28 -2
  73. package/scripts/check-herdr-runtime-bootstrap.ts +136 -0
  74. package/scripts/check-install-surface.ts +1236 -6
  75. package/scripts/check-meta-doctor-oracle.sh +1 -1
  76. package/scripts/check-meta-facts.ts +20 -1
  77. package/scripts/check-mux-resume-call.ts +48 -3
  78. package/scripts/check-peer-facts.ts +39 -2
  79. package/scripts/cli-help.mjs +222 -0
  80. package/scripts/dev-bin.sh +39 -2
  81. package/scripts/herdr-activation.mjs +28 -6
  82. package/scripts/herdr-operator-link.mjs +389 -0
  83. package/scripts/herdr-plugin-activate.mjs +5 -0
  84. package/scripts/herdr-plugin-deactivate.mjs +18 -5
  85. package/scripts/herdr-rails.mjs +43 -7
  86. package/scripts/herdr-runtime.mjs +27 -0
  87. package/scripts/meta-bridge-fresh-cut.ts +1 -27
  88. package/scripts/meta-bridge-prune.ts +1 -1
  89. package/scripts/meta-facts.ts +1 -1
  90. package/scripts/mutants/agent-guidance.json +160 -0
  91. package/scripts/mutants/bridge-boot-resume.json +6 -8
  92. package/scripts/mutants/capability-bundle-reach.json +124 -0
  93. package/scripts/mutants/claude-launch.json +142 -0
  94. package/scripts/mutants/cli-help-source.json +420 -0
  95. package/scripts/mutants/control-send-receipt.json +21 -4
  96. package/scripts/mutants/dev-gate-dispatch.json +109 -0
  97. package/scripts/mutants/fresh-call-dispatch.json +38 -2
  98. package/scripts/mutants/fresh-cut.json +15 -0
  99. package/scripts/mutants/herdr-activation.json +128 -0
  100. package/scripts/mutants/herdr-fresh-call.json +278 -5
  101. package/scripts/mutants/herdr-operator-link.json +318 -0
  102. package/scripts/mutants/herdr-plugin-build.json +55 -0
  103. package/scripts/mutants/herdr-plugin.json +17 -0
  104. package/scripts/mutants/herdr-resume-call.json +288 -0
  105. package/scripts/mutants/herdr-runtime-bootstrap.json +48 -0
  106. package/scripts/mutants/meta-facts.json +15 -0
  107. package/scripts/mutants/mux-fresh-call.json +14 -3
  108. package/scripts/mutants/mux-resume-call.json +89 -3
  109. package/scripts/mutants/peer-facts.json +15 -0
  110. package/scripts/mutants/pi-durable.json +996 -6
  111. package/scripts/mutants/remote-pair-send.json +21 -2
  112. package/scripts/mutants/self-address.json +10 -10
  113. package/scripts/mutants/source-install.json +35 -0
  114. package/scripts/mutants/v2-surface.json +50 -64
  115. package/scripts/mutants/v2-visible-resume.json +266 -6
  116. package/scripts/peer-facts.ts +1 -1
  117. package/scripts/smoke-agy-install-state.sh +66 -0
  118. package/scripts/smoke-meta-prune.sh +23 -0
  119. package/scripts/smoke-omp-fresh-live.ts +12 -3
  120. package/scripts/smoke-omp-receive-live.ts +7 -1
  121. package/scripts/smoke-pi-durable-fresh-live.ts +12 -2
  122. package/team.json.example +39 -0
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * fresh-call-dispatch — the ONE place that decides which rail opens a sibling, and the only module
3
- * allowed to know that there are two.
3
+ * allowed to know that there are two. Since #157 G1a that rail choice is shared by the two visible
4
+ * lifecycle verbs, fresh call and same-id visible resume, through two separate entry points; each
5
+ * verb keeps its own lifecycle policy, and only the rail choice is common.
4
6
  *
5
7
  * WHY A COMPOSITION ROOT AND NOT A BRANCH IN EACH SURFACE. Two surfaces once registered
6
8
  * `entwurf_fresh_call`: pi's own extension and the MCP bridge. Before this file each of them
@@ -21,14 +23,16 @@
21
23
  * somewhere the operator cannot see from where they are standing, and the receipt would look fine.
22
24
  *
23
25
  * WHAT THIS MODULE DOES NOT DO: it never reads the record store, never resolves a garden id, and
24
- * never turns the direct herdr witness into a second public address. The nonce callback remains
25
- * the one address path, on both rails.
26
+ * never turns the direct herdr witness into a second public address. For a FRESH call the nonce
27
+ * callback remains the one address path, on both rails. A visible resume has no nonce: its address
28
+ * is the record the v2 composition already resolved, and this module only picks where it reopens.
26
29
  */
27
30
  import { spawn as spawnChildProcess } from "node:child_process";
28
31
  import { ACP_MODEL_NOT_CURATED, isCuratedAcpModelId, PROVIDER_ID } from "./acp/model-ids.js";
29
32
  import { codexCallerFreshPreflight, codexFreshPreflight } from "./codex-fresh-preflight.js";
30
33
  import { isSafeFreshCallModel, mintNonce } from "./fresh-call-composition.js";
31
34
  import { createHerdrRunner, herdrFreshCall, renderHerdrFreshCall, resolveHerdrContext, } from "./herdr-fresh-call.js";
35
+ import { launchHerdrResume } from "./herdr-resume-call.js";
32
36
  import { freshCall, renderFreshCall } from "./mux-fresh-call.js";
33
37
  import { splitPiDurableModel } from "./pi-durable-fresh-preflight.js";
34
38
  /** herdr's own marker, read for its EXACT value. `[측정 2026-09-14]` herdr exports `HERDR_ENV=1`
@@ -98,12 +102,13 @@ export function isUncuratedEntwurfPiModel(backend, model) {
98
102
  * backend there, so running a Codex preflight would ask an irrelevant question and could fail for
99
103
  * a reason that has nothing to do with why the call is impossible.
100
104
  *
101
- * THE TWO CODEX CALLER INPUTS ARE TMUX-RAIL FACTS and stop at this boundary. #95 lane B/C measured
102
- * both against a tmux pane and an app-server-hosted bridge: a pane title is what carries the
103
- * caller's thread-id, and a record cwd exists as an input because THAT process's directory is the
104
- * app-server's. Inside herdr the tab is created by herdr, there is no pane title to anchor to, and
105
- * neither fact has been measured — so the herdr rail is handed the request without consulting
106
- * them rather than inheriting a rule from a topology it does not share.
105
+ * THE CODEX CALLER'S THREAD ID IS A TMUX-RAIL FACT and stops at this boundary. #95 lane B measured
106
+ * it against a tmux pane: a pane title is what carries the caller's thread-id, and inside herdr the
107
+ * tab is created by herdr, with no pane title to anchor to. The herdr rail therefore receives only a
108
+ * boolean saying the caller IS a record-backed Codex citizen, plus that citizen's record cwd (#95
109
+ * lane C: an app-server-hosted bridge's own directory is the app-server's). Both herdr branches read
110
+ * them (layout since #157 A-L1, agent start since A-L1x), to choose a cwd without falling back to
111
+ * this process's; this is not a Codex-in-herdr placement certification.
107
112
  */
108
113
  export async function dispatchFreshCall(request, env = process.env, spawn, nonce = mintNonce()) {
109
114
  // Before either rail is asked anything: both would open a pane on a provider nobody chose.
@@ -127,7 +132,20 @@ export async function dispatchFreshCall(request, env = process.env, spawn, nonce
127
132
  return { rail: "herdr", result: { ok: false, reason: context.reason } };
128
133
  }
129
134
  const run = createHerdrRunner(context.context.bin, env, spawn ?? spawnChildProcess);
130
- return { rail: "herdr", result: await herdrFreshCall(request, run, env, nonce) };
135
+ // #157 A-L1: an explicit field list, not `...request`, so the Codex thread id STOPS here — it is
136
+ // a tmux seat input. The herdr rail learns only WHETHER the caller is a record-backed Codex
137
+ // citizen (one boolean) and that citizen's record cwd; the tmux request below is untouched.
138
+ const herdrRequest = {
139
+ backend: request.backend,
140
+ model: request.model,
141
+ task: request.task,
142
+ ...(request.cwd === undefined ? {} : { cwd: request.cwd }),
143
+ ...(request.placement === undefined ? {} : { placement: request.placement }),
144
+ callerGardenId: request.callerGardenId,
145
+ ...(request.callerCwd === undefined ? {} : { callerCwd: request.callerCwd }),
146
+ callerIsCodex: request.callerNativeSessionId !== undefined,
147
+ };
148
+ return { rail: "herdr", result: await herdrFreshCall(herdrRequest, run, env, nonce) };
131
149
  }
132
150
  // TWO capability axes, in this order, both pre-mutation and neither standing in for the
133
151
  // other. The TARGET axis first — "entwurf cannot open a Codex sibling here at all" is the
@@ -166,3 +184,22 @@ export async function dispatchFreshCall(request, env = process.env, spawn, nonce
166
184
  export function renderDispatchedFreshCall(dispatched) {
167
185
  return dispatched.rail === "herdr" ? renderHerdrFreshCall(dispatched.result) : renderFreshCall(dispatched.result);
168
186
  }
187
+ /**
188
+ * #157 G1a: pick the rail a same-id visible resume reopens on — the SAME capability fact fresh
189
+ * call reads, through the same `selectFreshCallRail`, never a parameter and never a fallback either
190
+ * way. This entry point owns that choice and nothing else:
191
+ *
192
+ * the v2 composition record, dormancy proof, lock, identity, observation — it calls the surface's
193
+ * launcher and never learns that there are rails
194
+ * the surface supplies the fixed tmux launch mapping as `tmuxLaunch`; it reads no rail fact
195
+ * herdr-resume-call owns the herdr behaviour, including refusing a non-pi target before anything
196
+ * is created
197
+ *
198
+ * Inside herdr the tmux mapping is never called, so a refused or failed herdr launch stays a herdr
199
+ * answer. Outside herdr the tmux mapping keeps its own herdr guard for any direct caller.
200
+ */
201
+ export function dispatchResumeLaunch(input, tmuxLaunch, env = process.env, spawn) {
202
+ if (selectFreshCallRail(env) !== "herdr")
203
+ return tmuxLaunch(input);
204
+ return launchHerdrResume(input, env, spawn ?? spawnChildProcess);
205
+ }