@jini-ai/agent-runtime 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/README.md +34 -17
  3. package/dist/acp-model-probe.d.ts +6 -4
  4. package/dist/acp-model-probe.js +3 -3
  5. package/dist/agent-protocol/acp/account-failure.d.ts +4 -2
  6. package/dist/agent-protocol/acp/account-failure.js +1 -1
  7. package/dist/agent-protocol/acp/json.d.ts +6 -6
  8. package/dist/agent-protocol/acp/json.js +3 -3
  9. package/dist/agent-protocol/acp/models.d.ts +10 -5
  10. package/dist/agent-protocol/acp/models.js +32 -31
  11. package/dist/agent-protocol/acp/session-params.d.ts +3 -1
  12. package/dist/agent-protocol/acp/session-params.js +2 -1
  13. package/dist/agent-protocol/acp/session.d.ts +28 -22
  14. package/dist/agent-protocol/acp/session.js +181 -147
  15. package/dist/agent-protocol/acp/text-suppression.d.ts +1 -1
  16. package/dist/agent-protocol/acp/text-suppression.js +1 -1
  17. package/dist/agent-protocol/acp/types.d.ts +3 -2
  18. package/dist/agent-protocol/acp/updates.d.ts +11 -11
  19. package/dist/agent-protocol/acp/updates.js +2 -2
  20. package/dist/agent-protocol/core/json-line-stream.d.ts +24 -8
  21. package/dist/agent-protocol/core/json-line-stream.js +8 -8
  22. package/dist/agent-protocol/pi-rpc/events.d.ts +5 -1
  23. package/dist/agent-protocol/pi-rpc/events.js +36 -36
  24. package/dist/agent-protocol/pi-rpc/internal.d.ts +4 -1
  25. package/dist/agent-protocol/pi-rpc/models.d.ts +3 -1
  26. package/dist/agent-protocol/pi-rpc/models.js +1 -1
  27. package/dist/agent-protocol/pi-rpc/session.d.ts +1 -1
  28. package/dist/agent-protocol/pi-rpc/session.js +33 -32
  29. package/dist/amr-model-cache.d.ts +12 -4
  30. package/dist/amr-model-cache.js +17 -21
  31. package/dist/amr-profile-resolver.d.ts +3 -1
  32. package/dist/anthropic-live-models.js +0 -0
  33. package/dist/artifact-taxonomy.d.ts +6 -2
  34. package/dist/auth.d.ts +52 -15
  35. package/dist/auth.js +36 -36
  36. package/dist/claude-code-models.js +2 -2
  37. package/dist/claude-stream.d.ts +22 -3
  38. package/dist/claude-stream.js +24 -8
  39. package/dist/copilot-stream.d.ts +7 -3
  40. package/dist/copilot-stream.js +3 -3
  41. package/dist/defs/aider.d.ts +8 -1
  42. package/dist/defs/aider.js +2 -2
  43. package/dist/defs/amp.d.ts +8 -1
  44. package/dist/defs/amp.js +2 -2
  45. package/dist/defs/amr.d.ts +22 -6
  46. package/dist/defs/amr.js +23 -23
  47. package/dist/defs/antigravity.d.ts +15 -4
  48. package/dist/defs/antigravity.js +9 -8
  49. package/dist/defs/auggie.d.ts +4 -1
  50. package/dist/defs/auggie.js +1 -1
  51. package/dist/defs/claude.d.ts +16 -2
  52. package/dist/defs/claude.js +22 -4
  53. package/dist/defs/cline.d.ts +4 -1
  54. package/dist/defs/cline.js +1 -1
  55. package/dist/defs/codebuddy.d.ts +8 -1
  56. package/dist/defs/codebuddy.js +2 -2
  57. package/dist/defs/codex.d.ts +18 -4
  58. package/dist/defs/codex.js +7 -7
  59. package/dist/defs/copilot.d.ts +8 -1
  60. package/dist/defs/copilot.js +2 -2
  61. package/dist/defs/crush.d.ts +8 -1
  62. package/dist/defs/crush.js +1 -1
  63. package/dist/defs/cursor-agent.d.ts +14 -3
  64. package/dist/defs/cursor-agent.js +5 -5
  65. package/dist/defs/deepseek.d.ts +8 -1
  66. package/dist/defs/deepseek.js +2 -2
  67. package/dist/defs/devin.d.ts +12 -2
  68. package/dist/defs/devin.js +3 -3
  69. package/dist/defs/droid.d.ts +8 -1
  70. package/dist/defs/droid.js +1 -1
  71. package/dist/defs/gemini.d.ts +8 -1
  72. package/dist/defs/gemini.js +1 -1
  73. package/dist/defs/goose.d.ts +4 -1
  74. package/dist/defs/goose.js +1 -1
  75. package/dist/defs/grok-build.d.ts +11 -2
  76. package/dist/defs/grok-build.js +3 -3
  77. package/dist/defs/hermes.d.ts +4 -1
  78. package/dist/defs/hermes.js +2 -2
  79. package/dist/defs/kilo.d.ts +4 -1
  80. package/dist/defs/kilo.js +2 -2
  81. package/dist/defs/kimi.d.ts +4 -1
  82. package/dist/defs/kimi.js +2 -2
  83. package/dist/defs/kiro.d.ts +4 -1
  84. package/dist/defs/kiro.js +2 -2
  85. package/dist/defs/mimo.d.ts +8 -1
  86. package/dist/defs/mimo.js +2 -2
  87. package/dist/defs/opencode.d.ts +9 -2
  88. package/dist/defs/opencode.js +2 -2
  89. package/dist/defs/pi.d.ts +12 -2
  90. package/dist/defs/pi.js +9 -9
  91. package/dist/defs/qoder.d.ts +8 -1
  92. package/dist/defs/qoder.js +2 -2
  93. package/dist/defs/qwen.d.ts +8 -1
  94. package/dist/defs/qwen.js +2 -2
  95. package/dist/defs/reasonix.d.ts +4 -1
  96. package/dist/defs/reasonix.js +3 -3
  97. package/dist/defs/shared.d.ts +4 -2
  98. package/dist/defs/shared.js +2 -2
  99. package/dist/defs/trae-cli.d.ts +12 -2
  100. package/dist/defs/trae-cli.js +3 -3
  101. package/dist/defs/vibe.d.ts +4 -1
  102. package/dist/defs/vibe.js +2 -2
  103. package/dist/detection.d.ts +38 -3
  104. package/dist/detection.js +77 -37
  105. package/dist/diagnostics.d.ts +14 -3
  106. package/dist/diagnostics.js +5 -5
  107. package/dist/env.d.ts +16 -4
  108. package/dist/env.js +7 -7
  109. package/dist/executables.d.ts +24 -8
  110. package/dist/executables.js +13 -13
  111. package/dist/index.d.ts +228 -4
  112. package/dist/index.js +230 -6
  113. package/dist/invocation.d.ts +6 -1
  114. package/dist/invocation.js +2 -2
  115. package/dist/json-event-stream.d.ts +7 -2
  116. package/dist/json-event-stream.js +3 -3
  117. package/dist/launch.d.ts +12 -2
  118. package/dist/launch.js +3 -3
  119. package/dist/log-file.d.ts +4 -1
  120. package/dist/log-file.js +2 -2
  121. package/dist/mcp.d.ts +6 -3
  122. package/dist/mcp.js +1 -1
  123. package/dist/metadata.d.ts +7 -3
  124. package/dist/metadata.js +1 -1
  125. package/dist/mmd-routes.d.ts +22 -6
  126. package/dist/mmd-routes.js +14 -14
  127. package/dist/model-catalog-cache.d.ts +50 -0
  128. package/dist/model-catalog-cache.js +61 -0
  129. package/dist/model-loading-state.d.ts +10 -0
  130. package/dist/model-loading-state.js +23 -0
  131. package/dist/model-registry.d.ts +28 -7
  132. package/dist/model-registry.js +11 -8
  133. package/dist/models.d.ts +31 -6
  134. package/dist/models.js +6 -6
  135. package/dist/opencode-log.d.ts +12 -4
  136. package/dist/opencode-log.js +8 -8
  137. package/dist/paths.d.ts +6 -2
  138. package/dist/paths.js +3 -3
  139. package/dist/pi-models.d.ts +3 -1
  140. package/dist/pi-models.js +2 -2
  141. package/dist/prompt-budget.d.ts +17 -4
  142. package/dist/prompt-budget.js +3 -3
  143. package/dist/prompt-file.d.ts +5 -1
  144. package/dist/prompt-file.js +1 -1
  145. package/dist/providers/aihubmix.d.ts +34 -9
  146. package/dist/providers/aihubmix.js +26 -26
  147. package/dist/providers/anthropic-messages.d.ts +77 -20
  148. package/dist/providers/anthropic-messages.js +53 -50
  149. package/dist/providers/azure-chat.d.ts +21 -7
  150. package/dist/providers/azure-chat.js +18 -16
  151. package/dist/providers/connection-guard.d.ts +45 -31
  152. package/dist/providers/connection-guard.js +40 -143
  153. package/dist/providers/connection-test.d.ts +1 -1
  154. package/dist/providers/connection-test.js +13 -30
  155. package/dist/providers/elevenlabs.d.ts +7 -2
  156. package/dist/providers/elevenlabs.js +4 -4
  157. package/dist/providers/google-messages.d.ts +44 -10
  158. package/dist/providers/google-messages.js +36 -34
  159. package/dist/providers/google-schema.d.ts +26 -0
  160. package/dist/providers/google-schema.js +253 -0
  161. package/dist/providers/google.d.ts +21 -6
  162. package/dist/providers/google.js +10 -10
  163. package/dist/providers/index.d.ts +3 -2
  164. package/dist/providers/index.js +3 -2
  165. package/dist/providers/model-catalog.d.ts +1 -1
  166. package/dist/providers/model-catalog.js +14 -27
  167. package/dist/providers/oauth-callback-server.d.ts +1 -1
  168. package/dist/providers/oauth-callback-server.js +3 -2
  169. package/dist/providers/oauth-credentials.d.ts +7 -1
  170. package/dist/providers/oauth-credentials.js +5 -5
  171. package/dist/providers/oauth-provider.d.ts +2 -2
  172. package/dist/providers/oauth-provider.js +20 -25
  173. package/dist/providers/oauth-tokens.d.ts +26 -6
  174. package/dist/providers/oauth-tokens.js +9 -9
  175. package/dist/providers/ollama-chat.d.ts +66 -31
  176. package/dist/providers/ollama-chat.js +64 -61
  177. package/dist/providers/openai-chat.d.ts +77 -22
  178. package/dist/providers/openai-chat.js +71 -67
  179. package/dist/providers/pkce.d.ts +33 -20
  180. package/dist/providers/pkce.js +75 -146
  181. package/dist/providers/sse-decode.d.ts +3 -1
  182. package/dist/providers/sse-decode.js +1 -1
  183. package/dist/providers/token-params.d.ts +16 -5
  184. package/dist/providers/token-params.js +6 -6
  185. package/dist/providers/tool-turn-types.d.ts +89 -0
  186. package/dist/providers/tool-turn-types.js +2 -0
  187. package/dist/providers/tool-turn.d.ts +10 -0
  188. package/dist/providers/tool-turn.js +252 -0
  189. package/dist/qoder-stream.d.ts +7 -3
  190. package/dist/qoder-stream.js +3 -3
  191. package/dist/registry.d.ts +6 -2
  192. package/dist/registry.js +4 -4
  193. package/dist/resolution.d.ts +5 -1
  194. package/dist/resolution.js +3 -3
  195. package/dist/role-marker-guard.d.ts +9 -5
  196. package/dist/role-marker-guard.js +5 -5
  197. package/dist/terminal-launch.d.ts +6 -1
  198. package/dist/terminal-launch.js +2 -2
  199. package/dist/types.d.ts +37 -6
  200. package/package.json +43 -4
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * @module @jini-ai/agent-runtime
3
3
  *
4
4
  * Public barrel. See `ADS-memory/reports/jini-port/extraction-plan.md` for the target
5
- * architecture and `source-map.md` for full provenance.
5
+ * architecture and `archived provenance ledger` for full provenance.
6
6
  *
7
7
  * This barrel merges two independently-ported trees:
8
8
  * - the flat `runtimes/` -> agent-runtime TypeScript source (`src/*.ts` +
@@ -14,8 +14,231 @@
14
14
  *
15
15
  * Two names are exported by both ported trees under the same identifier
16
16
  * and are aliased below to avoid a duplicate-export error; see
17
- * source-map.md's "Barrel merge (2026-07-18)" section for the full
17
+ * archived provenance ledger's "Barrel merge (2026-07-18)" section for the full
18
18
  * rationale.
19
+
20
+ * Archived provenance rationale:
21
+ * ### Design decisions (judgment calls)
22
+ *
23
+ * **1. The ACP subprocess transport (1744 lines) and pi-rpc transport (684 lines) are out of
24
+ * scope — `AcpModelProbe` is a fourth port beyond the anticipated trio + vela import.** The
25
+ * task brief named the coupled trio (PromptAugmenter/ArtifactTaxonomy/TelemetrySink) plus the
26
+ * single vela import in `detection.ts` as "the only real judgment-call work". In practice,
27
+ * `defs/shared.ts` also imports `detectAcpModels` from OD's top-level ACP transport module —
28
+ * the full ACP JSON-RPC handshake protocol (session/new, session/list_models, …), used by 8 of
29
+ * the 24 def literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) as their
30
+ * `fetchModels` implementation. `r1-daemon.md` itself classifies OD's `agent-protocol/` (the
31
+ * ACP + pi-rpc subprocess layer, 17 files) as its OWN separate GENERIC-ENGINE extraction
32
+ * target, not part of `runtimes/`'s file scope — porting 2400+ lines of a distinct subsystem
33
+ * into this task would have blown "harvest wholesale" far past what was asked. So
34
+ * `detectAcpModels` becomes `AcpModelProbe` (interface + no-op default + module-level
35
+ * `setAcpModelProbe()` installer), mirroring the `AmrProfileResolver` pattern the brief already
36
+ * asked for. Every ACP-based def's `fetchModels` keeps calling `detectAcpModels(...)` unchanged
37
+ * (via `defs/shared.ts`'s re-export) — with the no-op probe installed, they degrade to "no live
38
+ * models" and fall back to `fallbackModels`, exactly like a real vela/ACP timeout would. Proven
39
+ * wired end-to-end in `ports.test.ts` (`setAcpModelProbe(stub)` then calling
40
+ * `devinAgentDef.fetchModels(...)` directly and asserting the stub was reached).
41
+ *
42
+ * **2. `env.ts` needed the same port treatment as the coupled trio, despite being listed as a
43
+ * "supporting generic file".** The real `runtimes/env/env.ts` reads OD's `app-config.js` (for
44
+ * an installation-id analytics identity env var, gated on a telemetry-consent flag), OD's
45
+ * `sandbox-mode.ts`, and a vela-specific profile-forwarding module, and hardcodes the origin
46
+ * product's own identity string as an `AMR_CLIENT_SOURCE` env value plus a product-prefixed
47
+ * data-dir-derived temp-home path. None of that is generic. `spawnEnvForAgent` keeps its real,
48
+ * generic behavior (proxy-aware merge via `@jini/platform`, OpenCode/MiMo
49
+ * project-config-discovery disabling, AMR's `HOME`/`VELA_OPENCODE_BIN` backfill) and gains two
50
+ * optional hooks — `perAgentEnv` and `sandboxOverlay` — so a host can re-attach its own
51
+ * vela/sandbox-specific behavior without this package needing to import OD's
52
+ * app-config/sandbox-mode/vela-profile modules. OD's AMR trace-env helper (a small function
53
+ * whose whole purpose was emitting a product-prefixed trace-correlation env triad) is dropped
54
+ * entirely, not ported — it is inherently OD/vela-adapter-owned and has no generic equivalent
55
+ * to keep.
56
+ *
57
+ * **3. `reasonix.ts`'s design-instructions constant is a real strip, not a comment reword.**
58
+ * Unlike every other def literal (pure declarative CLI-adapter config), OD's `reasonix.ts`
59
+ * injected a hardcoded system-prompt block via `env.REASONIX_ACP_SYSTEM_APPEND` that literally
60
+ * told the model it was running inside the host product and instructed it to wrap output in
61
+ * that product's own artifact-tag convention. That is genuine product-specific prompt content
62
+ * smuggled into what the task brief assumed was a pure literal. It is dropped; a host wanting
63
+ * equivalent behavior should compose it via `PromptAugmenter.systemOverlay` and merge the result
64
+ * into this def's `env.REASONIX_ACP_SYSTEM_APPEND` itself (the engine has no generic mechanism
65
+ * to know a given def has an env-based system-prompt hook — that's inherently a reasonix-specific
66
+ * integration detail the host must wire).
67
+ *
68
+ * **4. `registry/local-profiles.ts` (the user-configurable local-agent-profile-file loader) is
69
+ * deliberately not ported.** The task's own scope description for `registry.ts` names only
70
+ * "`BASE_AGENT_DEFS` array + dup-id guard + `getAgentDef(id)`" — it does not mention
71
+ * local-profile merging. The real file also turned out to be far more coupled than a
72
+ * "supporting generic file" would suggest: it reads a product-prefixed config-path override env
73
+ * var, falls back to a product-branded default path under the user's home directory, reads a
74
+ * product-prefixed data-dir env var, and depends on OD's daemon-level `sandbox-mode.ts`
75
+ * subsystem entirely outside this package's charter. Rather than either violate the explicit
76
+ * scope or half-port a coupled file, it's left out; `AGENT_DEFS` here is exactly
77
+ * `BASE_AGENT_DEFS`. Flagged as a real follow-up: a future task could reintroduce a de-branded,
78
+ * sandbox-free local-profile loader as an injected port (e.g. a `LocalProfileSource` interface)
79
+ * if a consumer needs runtime-configurable custom agent defs.
80
+ *
81
+ * **5. `amr/amr-model-probe.ts` (the other file in OD's `runtimes/amr/` subdir) is not ported;
82
+ * only `amr/amr-model-cache.ts` is.** `amr-model-probe.ts`'s `resolveAmrModelProbe` composes
83
+ * `launch`/`env`/`registry` (all in-scope) with OD's `app-config.js` (`readAppConfig`,
84
+ * persisted settings) and a vela-integration module's credential-revision reader (both
85
+ * out-of-scope OD subsystems) to build a cache key + spawn env for probing AMR's live model
86
+ * catalog. This is daemon-level composition glue, not a pure CLI-adapter concern, and the task
87
+ * brief never named `runtimes/amr/` in its explicit scope. `AmrModelLoadingCache` (the reusable
88
+ * generic caching *pattern*) is kept; the OD-app-config-coupled probe-composition function is
89
+ * not. A host wiring AMR needs to build its own equivalent of `resolveAmrModelProbe` using its
90
+ * own config/credential ports plus this package's `AmrModelLoadingCache` + `resolveAgentLaunch`
91
+ * + `spawnEnvForAgent`.
92
+ *
93
+ * **6. `chat-prompt-inputs.ts` is entirely OD-product prompt content, not partially generic —
94
+ * confirmed after reading the full 938-line file.** Beyond the design-system-selection
95
+ * functions r1b explicitly named (`resolveEffectiveDesignSystemSelection`,
96
+ * `designSystemIdFromPluginSnapshot`, `formatDesignFilesWorkspaceHint`), the file also contains
97
+ * comment-attachment rendering (OD's "attached preview comments" annotation feature), Codex
98
+ * image-generation prompt overrides (OD's media-generation feature), and a research-command-
99
+ * contract composer (OD's "research" feature) — every one of them product-specific, none of
100
+ * them a generic prompt-composition mechanism. Per the task's explicit instruction ("do NOT
101
+ * lift the OD logic itself"), none of it is ported; `PromptAugmenter` is the injection seam in
102
+ * full.
103
+ *
104
+ * ### Product-neutral seams (design decisions)
105
+ *
106
+ * The task brief identified four real OD coupling points to port-inject; a fifth (literal `promoted_by` strings) and a build-config note surfaced during the coverage-driven pass. Each below follows this codebase's existing DI/port convention (`packages/core/src/pack.ts`'s small explicit interfaces, `packages/daemon/archived provenance ledger`'s injected-collaborator framing) — a small named interface, a default no-op implementation, injected via caller options, not a kitchen-sink object.
107
+ *
108
+ * **1. `AccountFailureClassifier` (`acp/account-failure.ts`).** OD's `acp/updates.ts` imported `classifyAmrAccountFailure`/`amrAccountFailureDetails` directly from `../../integrations/vela-errors.js` — a real AMR/vela-branded text classifier with a hardcoded `https://open-design.ai/amr/wallet?source=open_design` recharge URL literal (read in full from `/tmp/od-source`). That URL alone makes the file impossible to port verbatim. The replacement is a two-method-shaped port (`AccountFailureClassifier.classify(text): AccountFailure | null`) with fields named generically (`code`/`message`/`action`/`actionUrl`, not AMR's field names) so any provider's classifier can satisfy it. `promotedAmrRetryStatusPayload`/`promotedAmrStderrPayload` (kept their AMR-referencing names, per the task brief's own framing of "the two call sites are `promotedAmrRetryStatusPayload(update)` and `promotedAmrStderrPayload(chunk)`" — AMR is a routing/vendor concept the task treated as out of scope to rename, unlike the literal `'open-design'` string) now take a `classifier` parameter defaulting to `noopAccountFailureClassifier` (always returns `null`). This reproduces "the feature doesn't exist" for any caller that doesn't inject a real classifier — verified by dedicated tests exercising both the no-op default and an injected matching classifier in `acp/updates.test.ts` and `acp/session.test.ts`. A future OD adapter package (not this task) would implement the real vela-backed classifier and inject it.
109
+ *
110
+ * **2. `ExecutionProfile` inlined (`acp/types.ts`).** OD's `acp/session.ts` imported `type ExecutionProfile from '@open-design/contracts'`. The real type, read from `/tmp/od-source/packages/contracts/src/execution-profile.ts`, is `export type ExecutionProfile = 'filesystem' | 'text_artifact';` plus one small helper function this port does not need (`executionProfileFromStreamFormat`, an OD-stream-format-specific mapper not used by `acp/session.ts` itself). Importing an entire external package for a two-value literal union would be the tail wagging the dog, so it's inlined as a local exported type instead.
111
+ *
112
+ * **3. Client-name / env-var de-branding.** Two literal `'open-design'`-prefixed defaults (`acp/session.ts`'s `clientName = 'open-design'` → `'agent-runtime'`; `acp/models.ts`'s `clientName = 'open-design-detect'` → `'agent-runtime-detect'`) and one hardcoded env var name (`acp/json.ts`'s `resolveAcpTimeoutMs` reading `env.OD_ACP_TIMEOUT_MS` → an optional `envVarName` parameter, default `'AGENT_RUNTIME_ACP_TIMEOUT_MS'`). All three are harmless-to-rename ACP protocol/runtime details (a handshake `clientInfo.name` value, a timeout knob), not behavior changes. **Extended beyond the task brief's explicit list**: three `promoted_by: 'open_design_acp...'` marker-string *values* (not just doc comments) found in `acp/rpc.ts` and `acp/updates.ts` during the audit — these don't match the literal grep patterns the task specified (`open-design` has a hyphen; the marker strings use an underscore, `open_design_acp`), but are clearly the same class of product-identity leak in spirit, so they were renamed too (`agent_runtime_acp`, `agent_runtime_acp_retry_status`, `agent_runtime_acp_stderr_retry_status`) and called out explicitly here rather than silently fixed.
113
+ *
114
+ * **4. `resolveAcpTimeoutMs`'s env var name.** Covered under seam 3 above; listed separately in the task brief as its own numbered item, so cross-referenced here for clarity.
115
+ *
116
+ * **5. Doc-comment / prose rewording.** "Open Design", `OD_ACP_STAGE_TIMEOUT_MS`, `OD_ACP_TIMEOUT_MS`, and `server.ts` (an OD-specific file path with no Jini equivalent) references in JSDoc/inline comments across `acp/constants.ts`, `acp/json.ts`, `acp/rpc.ts`, `acp/updates.ts`, and `acp/session.ts` were reworded to generic language (e.g., "a structured error object", "a host application may resolve its own branded environment variable"). The `text-suppression.ts` port additionally needed this treatment in its own new `@module` docblock (see next item) and one internal comment referencing this skill's coverage-discipline convention by a path that itself contains the substring `open-design` (`ADS-memory/reports/jini-port/skills/fixing-open-design.md`) — reworded to avoid the literal path.
117
+ *
118
+ * **6. `text-suppression.ts`'s two dropped dead functions.** `possibleDsmlArtifactOpenStart` and `possibleArtifactCloseStart` are declared in the origin file but never called anywhere in it (confirmed by `grep -n` across the full origin file — zero call sites, not exported). The task brief said "port this file verbatim," but keeping genuinely dead, unreachable, unexported code would force a choice between a contrived test asserting nothing real, or a coverage-suppression comment — both of which `ADS-memory/reports/jini-port/skills/fixing-open-design.md`'s Phase 6.5 explicitly rules out ("a hard-to-cover branch is a refactor signal, not something to suppress"). Dropped instead; this is the one deliberate "not quite verbatim" deviation in an otherwise byte-for-byte port of that file.
119
+ *
120
+ * **7. Four dead-branch removals in `acp/session.ts` and one in `core/json-line-stream.ts`'s `flush()`, plus three `noUncheckedIndexedAccess`-guard-to-non-null-assertion conversions across `core/json-line-stream.ts`, `pi-rpc/models.ts`, and `pi-rpc/session.ts`.** These surfaced only during the coverage-driven pass (Phase 6.5), not from the OD-coupling analysis — each is a genuinely unreachable branch given the *current* call graph, not a speculative "this could never happen" guess:
121
+ * - `core/json-line-stream.ts`'s `flush()` had a defensive re-emit-and-clear on a leftover `pendingJson` candidate; proven dead because `pendingJson` is only ever retained when `classifyJsonCandidate` most recently judged it `'incomplete'`, and a 200,000-trial fuzz (random truncated valid-JSON fragments) found zero cases where `classifyJsonCandidate` says `'incomplete'` while `JSON.parse` on the identical string would actually succeed — so a bare re-attempt at end-of-stream could never succeed either.
122
+ * - `core/json-line-stream.ts`'s `closeFrame` helper carried a `!current || current.kind !== kind` mismatch guard; proven dead because every one of its 4 call sites is already nested inside a branch that established the popped frame's kind, confirmed by a 2,000,000-trial adversarial fuzz (malformed bracket sequences) finding zero mismatches.
123
+ * - `acp/session.ts`'s `failWithPayload` and `finishCleanPrompt` each carried their own `if (finished) return;` re-entry guard; both have call sites entirely nested inside the parser callback's own `if (aborted || finished) return;` at that callback's top, or (for the stderr-promotion call site) the stderr handler's own equivalent guard — so neither function can actually be invoked a second time once `finished` is true. **Contrast**: `fail()`'s own `if (finished) return;` guard was *kept*, because it has two call sites (`child.on('error', ...)` and `stdin.on('error', ...)`) with no pre-check of their own — genuinely reachable, and a real test (`acp/session.test.ts`) exercises it by emitting a stdin error followed by a child-process error.
124
+ * - `acp/session.ts`'s parser callback had a second, inline `if (finished) return;` inside its RPC-error-handling block, fully redundant with the same callback's own top-of-function check three lines earlier (nothing between them can flip `finished`) — removed.
125
+ * - `acp/session.ts`'s `emitVisibleTextDelta` carried an `if (!delta) return;` guard; all three call sites already guard against an empty delta before calling it (`if (flushedText) {...}`, `if (outputDelta) {...}`, and the plain-else branch which is only reached after an earlier `if (!toolCallStrippedDelta) return;` already ruled out emptiness).
126
+ * - `pi-rpc/models.ts` (`if (line === undefined) continue;`, `if (provider === undefined || modelId === undefined) continue;`) and `pi-rpc/session.ts` (`changed[0]?.path ?? null`) each had a `noUncheckedIndexedAccess`-driven guard around an array index that the enclosing loop bound / length check already guarantees is defined — converted to a documented non-null assertion (`fixing-open-design.md` Phase 6.5's fourth classification bucket: "TS-required fallback with no real runtime path").
127
+ *
128
+ * Every removal is accompanied by an inline comment in the source explaining the reachability proof, and none change observable behavior for any input reachable through the public API — verified by re-running the full test suite (450 tests) after each change.
129
+ *
130
+ * ## Barrel merge (2026-07-18)
131
+ *
132
+ * `packages/agent-runtime/` was independently built out from an empty stub on
133
+ * two separate branches: `port/agent-runtime-from-runtimes` (merged to `main`
134
+ * as PR #24, the "runtimes/" section above) and
135
+ * `port/agent-protocol-toolexecutor-daemoncore` (this PR, the
136
+ * "agent-protocol/" section above). Merging `main` into the latter conflicted
137
+ * on the shared package scaffolding (`package.json`, this file, `src/index.ts`,
138
+ * `tsconfig.json`, `vitest.config.ts`) since both branches independently
139
+ * created it — not on either side's actual ported content, which is disjoint
140
+ * (`src/agent-protocol/**` vs. everything else under `src/`).
141
+ *
142
+ * **`package.json`**: merged `dependencies` (`@jini/platform`, from the
143
+ * `runtimes/` port's `invocation.ts`/`executables.ts`/`env.ts`) and
144
+ * `devDependencies` (`@vitest/coverage-v8`, from the `agent-protocol/` port)
145
+ * into one list; kept the `runtimes/` port's `test:coverage` script.
146
+ *
147
+ * **`tsconfig.json`** / **`vitest.config.ts`**: both sides independently
148
+ * excluded `src/skills/**` (needed — one skill,
149
+ * `chat-motion-overlay`, ships a self-contained Remotion template with its own
150
+ * `.ts`/`.tsx` files that aren't part of this package's own compilation/test
151
+ * surface); only the `runtimes/` side also excluded `src/craft/**` (a no-op
152
+ * today since `craft/` is markdown-only, but kept for explicitness as content
153
+ * grows). Merged to exclude both directories in both files. `vitest.config.ts`
154
+ * also merged `include` (`src/**`, the broader of the two — the
155
+ * `agent-protocol/`-scoped `src/agent-protocol/**` from this PR was a subset)
156
+ * and merged the type-only-file coverage carve-outs (`src/types.ts` from the
157
+ * `runtimes/` port, `src/agent-protocol/acp/types.ts` from this PR) into one
158
+ * `exclude` list. Coverage `thresholds` differed (this PR: 99/99/99/99; the
159
+ * `runtimes/` port: 99.9/99.9/99.9/99.9) — set to 99 on all four metrics,
160
+ * matching the documented floor in `ADS-memory/reports/jini-port/skills/fixing-open-design.md`
161
+ * Phase 6.5 (">=99% ... 100% as the actual goal"), and verified against the
162
+ * actual merged coverage run (see this package's own CI/PR validation output
163
+ * for the authoritative merged numbers, same as the `runtimes/` section's own
164
+ * "Independent re-verification pass" above).
165
+ *
166
+ * **`src/index.ts`**: merged both barrels' export statements. Two real name
167
+ * collisions were found between the two ported trees (verified via a
168
+ * top-level `export (function|const|class|interface|type) <name>` scan across
169
+ * both trees, not just an alphabetical-ordering artifact of the merge) and
170
+ * resolved by aliasing rather than dropping either side:
171
+ *
172
+ * 1. **`detectAcpModels`.** This PR's `src/agent-protocol/acp/models.ts`
173
+ * exports the REAL ACP subprocess transport: it spawns the CLI and performs
174
+ * the actual `initialize` + `session/new` JSON-RPC handshake to fetch live
175
+ * models. The `runtimes/` port's `src/acp-model-probe.ts` (see that
176
+ * section's Design decision 1) *also* exports a function named
177
+ * `detectAcpModels` — but it is an injectable, no-op-by-default seam
178
+ * (`AcpModelProbe.detectModels`) that `defs/shared.ts` re-exports and 8 def
179
+ * literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) call
180
+ * as their `fetchModels` implementation, because at the time that branch
181
+ * was written the real ACP transport did not yet exist in this package (it
182
+ * was a separate, not-yet-ported subsystem — see that section's Design
183
+ * decision 1). Now that the real transport IS present, both are kept:
184
+ * the plain `detectAcpModels` name is bound to the real transport (from
185
+ * `agent-protocol/`, arguably the more generally useful public name for an
186
+ * external consumer), and `acp-model-probe.ts`'s seam function is
187
+ * re-exported as `probeAcpModels` instead. **Not touched**: `defs/shared.ts`
188
+ * still imports its own `detectAcpModels` directly from
189
+ * `./acp-model-probe.js` (a same-package file import, unaffected by the
190
+ * barrel-level alias) — the 8 ACP-based def literals' `fetchModels` still
191
+ * resolve to the no-op-by-default seam exactly as before this merge. Wiring
192
+ * those defs' `fetchModels` to the real transport instead (i.e., calling
193
+ * `setAcpModelProbe()` with an adapter over `agent-protocol`'s
194
+ * `detectAcpModels`) is a real, valuable follow-up this merge deliberately
195
+ * does not attempt — it is new integration work, not a conflict-resolution
196
+ * choice, and needs its own scoped task with its own tests (the two
197
+ * functions' request/response shapes are structurally similar but not
198
+ * identical: `AcpModelProbeRequest`/`RuntimeModelOption` vs.
199
+ * `DetectAcpModelsOptions`/`ModelOption`).
200
+ * 2. **`parsePiModels`.** Both ports independently lifted the identical OD
201
+ * origin function (`apps/daemon/src/pi-rpc.ts#parsePiModels`, a pure
202
+ * string-parsing function with no transport dependency) into two different
203
+ * files: the `runtimes/` port's standalone `src/pi-models.ts` (used
204
+ * internally by `defs/shared.ts` for the `pi` CLI's own model listing) and
205
+ * this PR's `src/agent-protocol/pi-rpc/models.ts` (part of the
206
+ * patch-mirrored `agent-protocol/` subtree, used internally by
207
+ * `pi-rpc/session.ts`). Confirmed byte-for-logic-identical (same
208
+ * line-parsing algorithm, same `DEFAULT_MODEL_OPTION` shape, same
209
+ * dedup-by-`provider/modelId` behavior; only cosmetic differences — return
210
+ * type name `PiModelOption` vs. `RuntimeModelOption`, and
211
+ * non-null-assertion vs. `undefined`-check style for the
212
+ * `noUncheckedIndexedAccess` guard). `pi-models.ts`'s copy keeps the plain
213
+ * `parsePiModels` name (it is the one with real internal consumers reached
214
+ * through this package's own barrel-adjacent re-export chain); the
215
+ * `agent-protocol/pi-rpc` copy is re-exported as `parsePiRpcModels`
216
+ * instead. Neither internal consumer (`defs/shared.ts`, `pi-rpc/session.ts`)
217
+ * was touched — both import their own local copy by direct file path, not
218
+ * through the package barrel, so the alias only affects the barrel's public
219
+ * surface, not either port's internal behavior.
220
+ * `src/index.test.ts` was extended (not just left as the pre-merge,
221
+ * `agent-protocol/`-only assertions) to prove both aliases resolve to two
222
+ * distinct, real functions (`not.toBe`) and that the two independent
223
+ * `parsePiModels`/`parsePiRpcModels` ports still agree on output for the
224
+ * same input, backing up the "verified byte-for-logic-identical" claim
225
+ * above with an executable assertion rather than only a source-reading one.
226
+ *
227
+ * No other export names collided (`ModelOption` vs. `RuntimeModelOption`,
228
+ * `AttachAcpSessionOptions`, `AccountFailure`/`AccountFailureClassifier`, the
229
+ * 24 `*AgentDef` def-literal exports, etc. are all distinctly named across the
230
+ * two trees).
231
+ *
232
+ * **`packages/platform/src/index.ts`**: the two sides added disjoint modules
233
+ * (this PR's `home-expansion.ts`/`sandbox-env.ts`/`resource-paths.ts`/
234
+ * `terminal.ts`, from the "flat generic daemon primitives" part of this PR's
235
+ * scope, vs. `main`'s unrelated `download.ts` from a different, already-merged
236
+ * PR) — no name collisions; both sides' export blocks and module-doc bullet
237
+ * list entries were concatenated as-is.
238
+ *
239
+ * **`pnpm-lock.yaml`**: not hand-merged; `origin/main`'s version was accepted
240
+ * to resolve the conflict marker, then `CI=true pnpm install` was run from the
241
+ * repo root to regenerate it from the merged `package.json` files.
19
242
  */
20
243
  export * from './types.js';
21
244
  export * from './paths.js';
@@ -39,6 +262,7 @@ export * from './prompt-budget.js';
39
262
  export * from './prompt-file.js';
40
263
  export * from './log-file.js';
41
264
  export * from './amr-model-cache.js';
265
+ export * from './model-catalog-cache.js';
42
266
  export * from './registry.js';
43
267
  export * from './defs/index.js';
44
268
  export * from './model-registry.js';
@@ -56,10 +280,10 @@ export * from './providers/index.js';
56
280
  /** @jini-ai/agent-runtime — public barrel (agent-protocol/ half).
57
281
  * Re-exports the agent-protocol/ capability barrel's public surface (ACP +
58
282
  * pi-rpc subprocess protocol adapters over a shared JSON-line-stream core).
59
- * See src/agent-protocol/README.md and source-map.md for provenance.
283
+ * See src/agent-protocol/README.md and archived provenance ledger for provenance.
60
284
  *
61
285
  * Two of this barrel's exports collide by name with the `runtimes/`-ported
62
- * modules above and are aliased here (see source-map.md's "Barrel merge"
286
+ * modules above and are aliased here (see archived provenance ledger's "Barrel merge"
63
287
  * section for the full reasoning):
64
288
  * - `detectAcpModels` — the REAL ACP subprocess transport (spawns the CLI,
65
289
  * performs the `initialize` + `session/new` JSON-RPC handshake). Kept
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * @module @jini-ai/agent-runtime
3
3
  *
4
4
  * Public barrel. See `ADS-memory/reports/jini-port/extraction-plan.md` for the target
5
- * architecture and `source-map.md` for full provenance.
5
+ * architecture and `archived provenance ledger` for full provenance.
6
6
  *
7
7
  * This barrel merges two independently-ported trees:
8
8
  * - the flat `runtimes/` -> agent-runtime TypeScript source (`src/*.ts` +
@@ -14,8 +14,231 @@
14
14
  *
15
15
  * Two names are exported by both ported trees under the same identifier
16
16
  * and are aliased below to avoid a duplicate-export error; see
17
- * source-map.md's "Barrel merge (2026-07-18)" section for the full
17
+ * archived provenance ledger's "Barrel merge (2026-07-18)" section for the full
18
18
  * rationale.
19
+
20
+ * Archived provenance rationale:
21
+ * ### Design decisions (judgment calls)
22
+ *
23
+ * **1. The ACP subprocess transport (1744 lines) and pi-rpc transport (684 lines) are out of
24
+ * scope — `AcpModelProbe` is a fourth port beyond the anticipated trio + vela import.** The
25
+ * task brief named the coupled trio (PromptAugmenter/ArtifactTaxonomy/TelemetrySink) plus the
26
+ * single vela import in `detection.ts` as "the only real judgment-call work". In practice,
27
+ * `defs/shared.ts` also imports `detectAcpModels` from OD's top-level ACP transport module —
28
+ * the full ACP JSON-RPC handshake protocol (session/new, session/list_models, …), used by 8 of
29
+ * the 24 def literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) as their
30
+ * `fetchModels` implementation. `r1-daemon.md` itself classifies OD's `agent-protocol/` (the
31
+ * ACP + pi-rpc subprocess layer, 17 files) as its OWN separate GENERIC-ENGINE extraction
32
+ * target, not part of `runtimes/`'s file scope — porting 2400+ lines of a distinct subsystem
33
+ * into this task would have blown "harvest wholesale" far past what was asked. So
34
+ * `detectAcpModels` becomes `AcpModelProbe` (interface + no-op default + module-level
35
+ * `setAcpModelProbe()` installer), mirroring the `AmrProfileResolver` pattern the brief already
36
+ * asked for. Every ACP-based def's `fetchModels` keeps calling `detectAcpModels(...)` unchanged
37
+ * (via `defs/shared.ts`'s re-export) — with the no-op probe installed, they degrade to "no live
38
+ * models" and fall back to `fallbackModels`, exactly like a real vela/ACP timeout would. Proven
39
+ * wired end-to-end in `ports.test.ts` (`setAcpModelProbe(stub)` then calling
40
+ * `devinAgentDef.fetchModels(...)` directly and asserting the stub was reached).
41
+ *
42
+ * **2. `env.ts` needed the same port treatment as the coupled trio, despite being listed as a
43
+ * "supporting generic file".** The real `runtimes/env/env.ts` reads OD's `app-config.js` (for
44
+ * an installation-id analytics identity env var, gated on a telemetry-consent flag), OD's
45
+ * `sandbox-mode.ts`, and a vela-specific profile-forwarding module, and hardcodes the origin
46
+ * product's own identity string as an `AMR_CLIENT_SOURCE` env value plus a product-prefixed
47
+ * data-dir-derived temp-home path. None of that is generic. `spawnEnvForAgent` keeps its real,
48
+ * generic behavior (proxy-aware merge via `@jini/platform`, OpenCode/MiMo
49
+ * project-config-discovery disabling, AMR's `HOME`/`VELA_OPENCODE_BIN` backfill) and gains two
50
+ * optional hooks — `perAgentEnv` and `sandboxOverlay` — so a host can re-attach its own
51
+ * vela/sandbox-specific behavior without this package needing to import OD's
52
+ * app-config/sandbox-mode/vela-profile modules. OD's AMR trace-env helper (a small function
53
+ * whose whole purpose was emitting a product-prefixed trace-correlation env triad) is dropped
54
+ * entirely, not ported — it is inherently OD/vela-adapter-owned and has no generic equivalent
55
+ * to keep.
56
+ *
57
+ * **3. `reasonix.ts`'s design-instructions constant is a real strip, not a comment reword.**
58
+ * Unlike every other def literal (pure declarative CLI-adapter config), OD's `reasonix.ts`
59
+ * injected a hardcoded system-prompt block via `env.REASONIX_ACP_SYSTEM_APPEND` that literally
60
+ * told the model it was running inside the host product and instructed it to wrap output in
61
+ * that product's own artifact-tag convention. That is genuine product-specific prompt content
62
+ * smuggled into what the task brief assumed was a pure literal. It is dropped; a host wanting
63
+ * equivalent behavior should compose it via `PromptAugmenter.systemOverlay` and merge the result
64
+ * into this def's `env.REASONIX_ACP_SYSTEM_APPEND` itself (the engine has no generic mechanism
65
+ * to know a given def has an env-based system-prompt hook — that's inherently a reasonix-specific
66
+ * integration detail the host must wire).
67
+ *
68
+ * **4. `registry/local-profiles.ts` (the user-configurable local-agent-profile-file loader) is
69
+ * deliberately not ported.** The task's own scope description for `registry.ts` names only
70
+ * "`BASE_AGENT_DEFS` array + dup-id guard + `getAgentDef(id)`" — it does not mention
71
+ * local-profile merging. The real file also turned out to be far more coupled than a
72
+ * "supporting generic file" would suggest: it reads a product-prefixed config-path override env
73
+ * var, falls back to a product-branded default path under the user's home directory, reads a
74
+ * product-prefixed data-dir env var, and depends on OD's daemon-level `sandbox-mode.ts`
75
+ * subsystem entirely outside this package's charter. Rather than either violate the explicit
76
+ * scope or half-port a coupled file, it's left out; `AGENT_DEFS` here is exactly
77
+ * `BASE_AGENT_DEFS`. Flagged as a real follow-up: a future task could reintroduce a de-branded,
78
+ * sandbox-free local-profile loader as an injected port (e.g. a `LocalProfileSource` interface)
79
+ * if a consumer needs runtime-configurable custom agent defs.
80
+ *
81
+ * **5. `amr/amr-model-probe.ts` (the other file in OD's `runtimes/amr/` subdir) is not ported;
82
+ * only `amr/amr-model-cache.ts` is.** `amr-model-probe.ts`'s `resolveAmrModelProbe` composes
83
+ * `launch`/`env`/`registry` (all in-scope) with OD's `app-config.js` (`readAppConfig`,
84
+ * persisted settings) and a vela-integration module's credential-revision reader (both
85
+ * out-of-scope OD subsystems) to build a cache key + spawn env for probing AMR's live model
86
+ * catalog. This is daemon-level composition glue, not a pure CLI-adapter concern, and the task
87
+ * brief never named `runtimes/amr/` in its explicit scope. `AmrModelLoadingCache` (the reusable
88
+ * generic caching *pattern*) is kept; the OD-app-config-coupled probe-composition function is
89
+ * not. A host wiring AMR needs to build its own equivalent of `resolveAmrModelProbe` using its
90
+ * own config/credential ports plus this package's `AmrModelLoadingCache` + `resolveAgentLaunch`
91
+ * + `spawnEnvForAgent`.
92
+ *
93
+ * **6. `chat-prompt-inputs.ts` is entirely OD-product prompt content, not partially generic —
94
+ * confirmed after reading the full 938-line file.** Beyond the design-system-selection
95
+ * functions r1b explicitly named (`resolveEffectiveDesignSystemSelection`,
96
+ * `designSystemIdFromPluginSnapshot`, `formatDesignFilesWorkspaceHint`), the file also contains
97
+ * comment-attachment rendering (OD's "attached preview comments" annotation feature), Codex
98
+ * image-generation prompt overrides (OD's media-generation feature), and a research-command-
99
+ * contract composer (OD's "research" feature) — every one of them product-specific, none of
100
+ * them a generic prompt-composition mechanism. Per the task's explicit instruction ("do NOT
101
+ * lift the OD logic itself"), none of it is ported; `PromptAugmenter` is the injection seam in
102
+ * full.
103
+ *
104
+ * ### Product-neutral seams (design decisions)
105
+ *
106
+ * The task brief identified four real OD coupling points to port-inject; a fifth (literal `promoted_by` strings) and a build-config note surfaced during the coverage-driven pass. Each below follows this codebase's existing DI/port convention (`packages/core/src/pack.ts`'s small explicit interfaces, `packages/daemon/archived provenance ledger`'s injected-collaborator framing) — a small named interface, a default no-op implementation, injected via caller options, not a kitchen-sink object.
107
+ *
108
+ * **1. `AccountFailureClassifier` (`acp/account-failure.ts`).** OD's `acp/updates.ts` imported `classifyAmrAccountFailure`/`amrAccountFailureDetails` directly from `../../integrations/vela-errors.js` — a real AMR/vela-branded text classifier with a hardcoded `https://open-design.ai/amr/wallet?source=open_design` recharge URL literal (read in full from `/tmp/od-source`). That URL alone makes the file impossible to port verbatim. The replacement is a two-method-shaped port (`AccountFailureClassifier.classify(text): AccountFailure | null`) with fields named generically (`code`/`message`/`action`/`actionUrl`, not AMR's field names) so any provider's classifier can satisfy it. `promotedAmrRetryStatusPayload`/`promotedAmrStderrPayload` (kept their AMR-referencing names, per the task brief's own framing of "the two call sites are `promotedAmrRetryStatusPayload(update)` and `promotedAmrStderrPayload(chunk)`" — AMR is a routing/vendor concept the task treated as out of scope to rename, unlike the literal `'open-design'` string) now take a `classifier` parameter defaulting to `noopAccountFailureClassifier` (always returns `null`). This reproduces "the feature doesn't exist" for any caller that doesn't inject a real classifier — verified by dedicated tests exercising both the no-op default and an injected matching classifier in `acp/updates.test.ts` and `acp/session.test.ts`. A future OD adapter package (not this task) would implement the real vela-backed classifier and inject it.
109
+ *
110
+ * **2. `ExecutionProfile` inlined (`acp/types.ts`).** OD's `acp/session.ts` imported `type ExecutionProfile from '@open-design/contracts'`. The real type, read from `/tmp/od-source/packages/contracts/src/execution-profile.ts`, is `export type ExecutionProfile = 'filesystem' | 'text_artifact';` plus one small helper function this port does not need (`executionProfileFromStreamFormat`, an OD-stream-format-specific mapper not used by `acp/session.ts` itself). Importing an entire external package for a two-value literal union would be the tail wagging the dog, so it's inlined as a local exported type instead.
111
+ *
112
+ * **3. Client-name / env-var de-branding.** Two literal `'open-design'`-prefixed defaults (`acp/session.ts`'s `clientName = 'open-design'` → `'agent-runtime'`; `acp/models.ts`'s `clientName = 'open-design-detect'` → `'agent-runtime-detect'`) and one hardcoded env var name (`acp/json.ts`'s `resolveAcpTimeoutMs` reading `env.OD_ACP_TIMEOUT_MS` → an optional `envVarName` parameter, default `'AGENT_RUNTIME_ACP_TIMEOUT_MS'`). All three are harmless-to-rename ACP protocol/runtime details (a handshake `clientInfo.name` value, a timeout knob), not behavior changes. **Extended beyond the task brief's explicit list**: three `promoted_by: 'open_design_acp...'` marker-string *values* (not just doc comments) found in `acp/rpc.ts` and `acp/updates.ts` during the audit — these don't match the literal grep patterns the task specified (`open-design` has a hyphen; the marker strings use an underscore, `open_design_acp`), but are clearly the same class of product-identity leak in spirit, so they were renamed too (`agent_runtime_acp`, `agent_runtime_acp_retry_status`, `agent_runtime_acp_stderr_retry_status`) and called out explicitly here rather than silently fixed.
113
+ *
114
+ * **4. `resolveAcpTimeoutMs`'s env var name.** Covered under seam 3 above; listed separately in the task brief as its own numbered item, so cross-referenced here for clarity.
115
+ *
116
+ * **5. Doc-comment / prose rewording.** "Open Design", `OD_ACP_STAGE_TIMEOUT_MS`, `OD_ACP_TIMEOUT_MS`, and `server.ts` (an OD-specific file path with no Jini equivalent) references in JSDoc/inline comments across `acp/constants.ts`, `acp/json.ts`, `acp/rpc.ts`, `acp/updates.ts`, and `acp/session.ts` were reworded to generic language (e.g., "a structured error object", "a host application may resolve its own branded environment variable"). The `text-suppression.ts` port additionally needed this treatment in its own new `@module` docblock (see next item) and one internal comment referencing this skill's coverage-discipline convention by a path that itself contains the substring `open-design` (`ADS-memory/reports/jini-port/skills/fixing-open-design.md`) — reworded to avoid the literal path.
117
+ *
118
+ * **6. `text-suppression.ts`'s two dropped dead functions.** `possibleDsmlArtifactOpenStart` and `possibleArtifactCloseStart` are declared in the origin file but never called anywhere in it (confirmed by `grep -n` across the full origin file — zero call sites, not exported). The task brief said "port this file verbatim," but keeping genuinely dead, unreachable, unexported code would force a choice between a contrived test asserting nothing real, or a coverage-suppression comment — both of which `ADS-memory/reports/jini-port/skills/fixing-open-design.md`'s Phase 6.5 explicitly rules out ("a hard-to-cover branch is a refactor signal, not something to suppress"). Dropped instead; this is the one deliberate "not quite verbatim" deviation in an otherwise byte-for-byte port of that file.
119
+ *
120
+ * **7. Four dead-branch removals in `acp/session.ts` and one in `core/json-line-stream.ts`'s `flush()`, plus three `noUncheckedIndexedAccess`-guard-to-non-null-assertion conversions across `core/json-line-stream.ts`, `pi-rpc/models.ts`, and `pi-rpc/session.ts`.** These surfaced only during the coverage-driven pass (Phase 6.5), not from the OD-coupling analysis — each is a genuinely unreachable branch given the *current* call graph, not a speculative "this could never happen" guess:
121
+ * - `core/json-line-stream.ts`'s `flush()` had a defensive re-emit-and-clear on a leftover `pendingJson` candidate; proven dead because `pendingJson` is only ever retained when `classifyJsonCandidate` most recently judged it `'incomplete'`, and a 200,000-trial fuzz (random truncated valid-JSON fragments) found zero cases where `classifyJsonCandidate` says `'incomplete'` while `JSON.parse` on the identical string would actually succeed — so a bare re-attempt at end-of-stream could never succeed either.
122
+ * - `core/json-line-stream.ts`'s `closeFrame` helper carried a `!current || current.kind !== kind` mismatch guard; proven dead because every one of its 4 call sites is already nested inside a branch that established the popped frame's kind, confirmed by a 2,000,000-trial adversarial fuzz (malformed bracket sequences) finding zero mismatches.
123
+ * - `acp/session.ts`'s `failWithPayload` and `finishCleanPrompt` each carried their own `if (finished) return;` re-entry guard; both have call sites entirely nested inside the parser callback's own `if (aborted || finished) return;` at that callback's top, or (for the stderr-promotion call site) the stderr handler's own equivalent guard — so neither function can actually be invoked a second time once `finished` is true. **Contrast**: `fail()`'s own `if (finished) return;` guard was *kept*, because it has two call sites (`child.on('error', ...)` and `stdin.on('error', ...)`) with no pre-check of their own — genuinely reachable, and a real test (`acp/session.test.ts`) exercises it by emitting a stdin error followed by a child-process error.
124
+ * - `acp/session.ts`'s parser callback had a second, inline `if (finished) return;` inside its RPC-error-handling block, fully redundant with the same callback's own top-of-function check three lines earlier (nothing between them can flip `finished`) — removed.
125
+ * - `acp/session.ts`'s `emitVisibleTextDelta` carried an `if (!delta) return;` guard; all three call sites already guard against an empty delta before calling it (`if (flushedText) {...}`, `if (outputDelta) {...}`, and the plain-else branch which is only reached after an earlier `if (!toolCallStrippedDelta) return;` already ruled out emptiness).
126
+ * - `pi-rpc/models.ts` (`if (line === undefined) continue;`, `if (provider === undefined || modelId === undefined) continue;`) and `pi-rpc/session.ts` (`changed[0]?.path ?? null`) each had a `noUncheckedIndexedAccess`-driven guard around an array index that the enclosing loop bound / length check already guarantees is defined — converted to a documented non-null assertion (`fixing-open-design.md` Phase 6.5's fourth classification bucket: "TS-required fallback with no real runtime path").
127
+ *
128
+ * Every removal is accompanied by an inline comment in the source explaining the reachability proof, and none change observable behavior for any input reachable through the public API — verified by re-running the full test suite (450 tests) after each change.
129
+ *
130
+ * ## Barrel merge (2026-07-18)
131
+ *
132
+ * `packages/agent-runtime/` was independently built out from an empty stub on
133
+ * two separate branches: `port/agent-runtime-from-runtimes` (merged to `main`
134
+ * as PR #24, the "runtimes/" section above) and
135
+ * `port/agent-protocol-toolexecutor-daemoncore` (this PR, the
136
+ * "agent-protocol/" section above). Merging `main` into the latter conflicted
137
+ * on the shared package scaffolding (`package.json`, this file, `src/index.ts`,
138
+ * `tsconfig.json`, `vitest.config.ts`) since both branches independently
139
+ * created it — not on either side's actual ported content, which is disjoint
140
+ * (`src/agent-protocol/**` vs. everything else under `src/`).
141
+ *
142
+ * **`package.json`**: merged `dependencies` (`@jini/platform`, from the
143
+ * `runtimes/` port's `invocation.ts`/`executables.ts`/`env.ts`) and
144
+ * `devDependencies` (`@vitest/coverage-v8`, from the `agent-protocol/` port)
145
+ * into one list; kept the `runtimes/` port's `test:coverage` script.
146
+ *
147
+ * **`tsconfig.json`** / **`vitest.config.ts`**: both sides independently
148
+ * excluded `src/skills/**` (needed — one skill,
149
+ * `chat-motion-overlay`, ships a self-contained Remotion template with its own
150
+ * `.ts`/`.tsx` files that aren't part of this package's own compilation/test
151
+ * surface); only the `runtimes/` side also excluded `src/craft/**` (a no-op
152
+ * today since `craft/` is markdown-only, but kept for explicitness as content
153
+ * grows). Merged to exclude both directories in both files. `vitest.config.ts`
154
+ * also merged `include` (`src/**`, the broader of the two — the
155
+ * `agent-protocol/`-scoped `src/agent-protocol/**` from this PR was a subset)
156
+ * and merged the type-only-file coverage carve-outs (`src/types.ts` from the
157
+ * `runtimes/` port, `src/agent-protocol/acp/types.ts` from this PR) into one
158
+ * `exclude` list. Coverage `thresholds` differed (this PR: 99/99/99/99; the
159
+ * `runtimes/` port: 99.9/99.9/99.9/99.9) — set to 99 on all four metrics,
160
+ * matching the documented floor in `ADS-memory/reports/jini-port/skills/fixing-open-design.md`
161
+ * Phase 6.5 (">=99% ... 100% as the actual goal"), and verified against the
162
+ * actual merged coverage run (see this package's own CI/PR validation output
163
+ * for the authoritative merged numbers, same as the `runtimes/` section's own
164
+ * "Independent re-verification pass" above).
165
+ *
166
+ * **`src/index.ts`**: merged both barrels' export statements. Two real name
167
+ * collisions were found between the two ported trees (verified via a
168
+ * top-level `export (function|const|class|interface|type) <name>` scan across
169
+ * both trees, not just an alphabetical-ordering artifact of the merge) and
170
+ * resolved by aliasing rather than dropping either side:
171
+ *
172
+ * 1. **`detectAcpModels`.** This PR's `src/agent-protocol/acp/models.ts`
173
+ * exports the REAL ACP subprocess transport: it spawns the CLI and performs
174
+ * the actual `initialize` + `session/new` JSON-RPC handshake to fetch live
175
+ * models. The `runtimes/` port's `src/acp-model-probe.ts` (see that
176
+ * section's Design decision 1) *also* exports a function named
177
+ * `detectAcpModels` — but it is an injectable, no-op-by-default seam
178
+ * (`AcpModelProbe.detectModels`) that `defs/shared.ts` re-exports and 8 def
179
+ * literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) call
180
+ * as their `fetchModels` implementation, because at the time that branch
181
+ * was written the real ACP transport did not yet exist in this package (it
182
+ * was a separate, not-yet-ported subsystem — see that section's Design
183
+ * decision 1). Now that the real transport IS present, both are kept:
184
+ * the plain `detectAcpModels` name is bound to the real transport (from
185
+ * `agent-protocol/`, arguably the more generally useful public name for an
186
+ * external consumer), and `acp-model-probe.ts`'s seam function is
187
+ * re-exported as `probeAcpModels` instead. **Not touched**: `defs/shared.ts`
188
+ * still imports its own `detectAcpModels` directly from
189
+ * `./acp-model-probe.js` (a same-package file import, unaffected by the
190
+ * barrel-level alias) — the 8 ACP-based def literals' `fetchModels` still
191
+ * resolve to the no-op-by-default seam exactly as before this merge. Wiring
192
+ * those defs' `fetchModels` to the real transport instead (i.e., calling
193
+ * `setAcpModelProbe()` with an adapter over `agent-protocol`'s
194
+ * `detectAcpModels`) is a real, valuable follow-up this merge deliberately
195
+ * does not attempt — it is new integration work, not a conflict-resolution
196
+ * choice, and needs its own scoped task with its own tests (the two
197
+ * functions' request/response shapes are structurally similar but not
198
+ * identical: `AcpModelProbeRequest`/`RuntimeModelOption` vs.
199
+ * `DetectAcpModelsOptions`/`ModelOption`).
200
+ * 2. **`parsePiModels`.** Both ports independently lifted the identical OD
201
+ * origin function (`apps/daemon/src/pi-rpc.ts#parsePiModels`, a pure
202
+ * string-parsing function with no transport dependency) into two different
203
+ * files: the `runtimes/` port's standalone `src/pi-models.ts` (used
204
+ * internally by `defs/shared.ts` for the `pi` CLI's own model listing) and
205
+ * this PR's `src/agent-protocol/pi-rpc/models.ts` (part of the
206
+ * patch-mirrored `agent-protocol/` subtree, used internally by
207
+ * `pi-rpc/session.ts`). Confirmed byte-for-logic-identical (same
208
+ * line-parsing algorithm, same `DEFAULT_MODEL_OPTION` shape, same
209
+ * dedup-by-`provider/modelId` behavior; only cosmetic differences — return
210
+ * type name `PiModelOption` vs. `RuntimeModelOption`, and
211
+ * non-null-assertion vs. `undefined`-check style for the
212
+ * `noUncheckedIndexedAccess` guard). `pi-models.ts`'s copy keeps the plain
213
+ * `parsePiModels` name (it is the one with real internal consumers reached
214
+ * through this package's own barrel-adjacent re-export chain); the
215
+ * `agent-protocol/pi-rpc` copy is re-exported as `parsePiRpcModels`
216
+ * instead. Neither internal consumer (`defs/shared.ts`, `pi-rpc/session.ts`)
217
+ * was touched — both import their own local copy by direct file path, not
218
+ * through the package barrel, so the alias only affects the barrel's public
219
+ * surface, not either port's internal behavior.
220
+ * `src/index.test.ts` was extended (not just left as the pre-merge,
221
+ * `agent-protocol/`-only assertions) to prove both aliases resolve to two
222
+ * distinct, real functions (`not.toBe`) and that the two independent
223
+ * `parsePiModels`/`parsePiRpcModels` ports still agree on output for the
224
+ * same input, backing up the "verified byte-for-logic-identical" claim
225
+ * above with an executable assertion rather than only a source-reading one.
226
+ *
227
+ * No other export names collided (`ModelOption` vs. `RuntimeModelOption`,
228
+ * `AttachAcpSessionOptions`, `AccountFailure`/`AccountFailureClassifier`, the
229
+ * 24 `*AgentDef` def-literal exports, etc. are all distinctly named across the
230
+ * two trees).
231
+ *
232
+ * **`packages/platform/src/index.ts`**: the two sides added disjoint modules
233
+ * (this PR's `home-expansion.ts`/`sandbox-env.ts`/`resource-paths.ts`/
234
+ * `terminal.ts`, from the "flat generic daemon primitives" part of this PR's
235
+ * scope, vs. `main`'s unrelated `download.ts` from a different, already-merged
236
+ * PR) — no name collisions; both sides' export blocks and module-doc bullet
237
+ * list entries were concatenated as-is.
238
+ *
239
+ * **`pnpm-lock.yaml`**: not hand-merged; `origin/main`'s version was accepted
240
+ * to resolve the conflict marker, then `CI=true pnpm install` was run from the
241
+ * repo root to regenerate it from the merged `package.json` files.
19
242
  */
20
243
  // Core contract + vendored diagnostic types.
21
244
  export * from './types.js';
@@ -41,6 +264,7 @@ export * from './prompt-budget.js';
41
264
  export * from './prompt-file.js';
42
265
  export * from './log-file.js';
43
266
  export * from './amr-model-cache.js';
267
+ export * from './model-catalog-cache.js';
44
268
  // Registry + defs.
45
269
  export * from './registry.js';
46
270
  export * from './defs/index.js';
@@ -54,7 +278,7 @@ export * from './defs/index.js';
54
278
  // from `./types.js` rather than redefining a second, looser copy; its own
55
279
  // `ModelOption` is exported here as `ModelCatalogOption` since the plain
56
280
  // `ModelOption` name is already owned by `agent-protocol/acp/models.ts`'s
57
- // narrower ACP-probe shape re-exported below. See source-map.md.
281
+ // narrower ACP-probe shape re-exported below. See archived provenance ledger.
58
282
  export * from './model-registry.js';
59
283
  // Stream parsers. Each handler's event union is exported alongside it — previously only
60
284
  // `Record<string, unknown>` was visible to a consumer outside this package, which is how a real
@@ -74,7 +298,7 @@ export * from './amr-profile-resolver.js';
74
298
  // is a no-op-by-default injectable seam (used internally by
75
299
  // `defs/shared.ts` for 8 ACP-based def literals so they don't need to
76
300
  // depend on the full ACP transport) — aliased to `probeAcpModels` here so
77
- // the real transport keeps the plain name. See source-map.md.
301
+ // the real transport keeps the plain name. See archived provenance ledger.
78
302
  export { noopAcpModelProbe, setAcpModelProbe, detectAcpModels as probeAcpModels, } from './acp-model-probe.js';
79
303
  // `parsePiModels` is exported under its plain name from this standalone
80
304
  // module (it has real internal consumers in this package: `defs/shared.ts`
@@ -90,10 +314,10 @@ export * from './providers/index.js';
90
314
  /** @jini-ai/agent-runtime — public barrel (agent-protocol/ half).
91
315
  * Re-exports the agent-protocol/ capability barrel's public surface (ACP +
92
316
  * pi-rpc subprocess protocol adapters over a shared JSON-line-stream core).
93
- * See src/agent-protocol/README.md and source-map.md for provenance.
317
+ * See src/agent-protocol/README.md and archived provenance ledger for provenance.
94
318
  *
95
319
  * Two of this barrel's exports collide by name with the `runtimes/`-ported
96
- * modules above and are aliased here (see source-map.md's "Barrel merge"
320
+ * modules above and are aliased here (see archived provenance ledger's "Barrel merge"
97
321
  * section for the full reasoning):
98
322
  * - `detectAcpModels` — the REAL ACP subprocess transport (spawns the CLI,
99
323
  * performs the `initialize` + `session/new` JSON-RPC handshake). Kept
@@ -1,5 +1,10 @@
1
1
  import type { RuntimeExecOptions } from './types.js';
2
- export declare function execAgentFile(command: string, args: string[], options?: RuntimeExecOptions): import("child_process").PromiseWithChild<{
2
+ export declare function execAgentFile({ command, args }: {
3
+ command: string;
4
+ args: string[];
5
+ }, { options }?: {
6
+ options?: RuntimeExecOptions;
7
+ }): import("child_process").PromiseWithChild<{
3
8
  stdout: string | NonSharedBuffer;
4
9
  stderr: string | NonSharedBuffer;
5
10
  }>;
@@ -7,7 +7,7 @@
7
7
  * `createCommandInvocation` now comes from `@jini-ai/platform` instead of the
8
8
  * OD workspace package it originally shipped from — the two are the same
9
9
  * function (platform was already verbatim-lifted into `@jini-ai/platform`,
10
- * see its `source-map.md`).
10
+ * see its `archived provenance ledger`).
11
11
  */
12
12
  import { execFile } from 'node:child_process';
13
13
  import os from 'node:os';
@@ -27,7 +27,7 @@ const execFileP = promisify(execFile);
27
27
  // running dev server. A probe writing a stray lockfile under the OS temp
28
28
  // dir is harmless. Actual agent runs spawn elsewhere with an explicit
29
29
  // project cwd and are unaffected.
30
- export function execAgentFile(command, args, options = {}) {
30
+ export function execAgentFile({ command, args }, { options = {} } = {}) {
31
31
  const invocation = createCommandInvocation(options.env
32
32
  ? {
33
33
  command,
@@ -1,8 +1,13 @@
1
1
  type StreamEvent = Record<string, unknown>;
2
2
  type StreamEventHandler = (event: StreamEvent) => void;
3
3
  type ParserKind = string;
4
- export declare function createJsonEventStreamHandler(kind: ParserKind, onEvent: StreamEventHandler): {
5
- feed: (chunk: string) => void;
4
+ export declare function createJsonEventStreamHandler({ kind, onEvent }: {
5
+ kind: ParserKind;
6
+ onEvent: StreamEventHandler;
7
+ }): {
8
+ feed: ({ chunk }: {
9
+ chunk: string;
10
+ }) => void;
6
11
  flush: () => void;
7
12
  };
8
13
  export {};