@gajae-code/coding-agent 0.17.2 → 0.17.4

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 (349) hide show
  1. package/CHANGELOG.md +194 -0
  2. package/dist/types/cli/daemon-cli.d.ts +3 -1
  3. package/dist/types/cli/github-release.d.ts +17 -0
  4. package/dist/types/cli/public-command-entry.d.ts +56 -0
  5. package/dist/types/cli/public-command-errors.d.ts +126 -0
  6. package/dist/types/cli/public-command-evidence.d.ts +99 -0
  7. package/dist/types/cli/public-command-help.d.ts +65 -0
  8. package/dist/types/cli/public-command-registry.d.ts +69 -0
  9. package/dist/types/cli/session-picker.d.ts +1 -1
  10. package/dist/types/cli/setup-cli.d.ts +1 -0
  11. package/dist/types/cli/skills-cli.d.ts +5 -0
  12. package/dist/types/cli.d.ts +3 -0
  13. package/dist/types/commands/daemon.d.ts +4 -50
  14. package/dist/types/commands/sdk.d.ts +20 -37
  15. package/dist/types/commands/setup.d.ts +3 -0
  16. package/dist/types/commands/skills.d.ts +9 -0
  17. package/dist/types/config/autorouting-tier-map.d.ts +18 -0
  18. package/dist/types/config/file-lock.d.ts +9 -1
  19. package/dist/types/config/model-profile-activation.d.ts +45 -1
  20. package/dist/types/config/model-registry.d.ts +11 -2
  21. package/dist/types/config/settings-schema.d.ts +11 -0
  22. package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
  23. package/dist/types/daemon/operator-contract.d.ts +5 -1
  24. package/dist/types/eval/js/worker-protocol.d.ts +2 -0
  25. package/dist/types/extensibility/extensions/types.d.ts +12 -0
  26. package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
  27. package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
  28. package/dist/types/extensibility/shared-events.d.ts +3 -1
  29. package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
  30. package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
  31. package/dist/types/internal-urls/index.d.ts +1 -0
  32. package/dist/types/internal-urls/parse.d.ts +9 -1
  33. package/dist/types/main.d.ts +22 -0
  34. package/dist/types/modes/acp/acp-agent.d.ts +55 -1
  35. package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
  36. package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
  37. package/dist/types/modes/components/session-selector.d.ts +5 -2
  38. package/dist/types/modes/components/user-message-selector.d.ts +5 -2
  39. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  40. package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
  41. package/dist/types/modes/interactive-mode.d.ts +1 -1
  42. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
  43. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
  44. package/dist/types/modes/types.d.ts +2 -2
  45. package/dist/types/runtime/process-lifecycle.d.ts +2 -0
  46. package/dist/types/runtime-mcp/manager.d.ts +56 -0
  47. package/dist/types/runtime-mcp/pool.d.ts +17 -0
  48. package/dist/types/runtime-mcp/redaction.d.ts +20 -0
  49. package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
  50. package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
  51. package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
  52. package/dist/types/sdk/broker/broker.d.ts +13 -2
  53. package/dist/types/sdk/broker/identity.d.ts +3 -1
  54. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
  55. package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
  56. package/dist/types/sdk/broker/runtime.d.ts +1 -1
  57. package/dist/types/sdk/broker/session-index.d.ts +22 -3
  58. package/dist/types/sdk/broker/spawn-authority.d.ts +4 -0
  59. package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
  60. package/dist/types/sdk/bus/index.d.ts +19 -0
  61. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +3 -1
  62. package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
  63. package/dist/types/sdk/cli/master-cli.d.ts +6 -10
  64. package/dist/types/sdk/cli/rows.d.ts +19 -1
  65. package/dist/types/sdk/cli/session-cli.d.ts +22 -5
  66. package/dist/types/sdk/client/client.d.ts +2 -0
  67. package/dist/types/sdk/guides/cli.d.ts +3 -4
  68. package/dist/types/sdk/guides/verify.d.ts +2 -0
  69. package/dist/types/sdk/host/host.d.ts +9 -0
  70. package/dist/types/sdk/host/session-runtime.d.ts +31 -0
  71. package/dist/types/sdk/host/types.d.ts +10 -0
  72. package/dist/types/sdk/index.d.ts +1 -0
  73. package/dist/types/sdk/prompt-deadline-flush.d.ts +83 -0
  74. package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
  75. package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
  76. package/dist/types/sdk/router/session-router.d.ts +2 -0
  77. package/dist/types/sdk/startup-capability.d.ts +2 -0
  78. package/dist/types/sdk/transport/relay.d.ts +1 -0
  79. package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
  80. package/dist/types/sdk/transport/stdio.d.ts +5 -1
  81. package/dist/types/session/agent-session.d.ts +168 -21
  82. package/dist/types/session/fallback-chain-controller.d.ts +6 -6
  83. package/dist/types/session/fold-coordinator.d.ts +17 -3
  84. package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
  85. package/dist/types/session/session-manager.d.ts +64 -1
  86. package/dist/types/session/session-work-lease.d.ts +14 -0
  87. package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
  88. package/dist/types/setup/provider-onboarding.d.ts +81 -1
  89. package/dist/types/tools/bash.d.ts +37 -11
  90. package/dist/types/tools/job.d.ts +1 -1
  91. package/dist/types/tools/steer-fold.d.ts +31 -0
  92. package/dist/types/utils/git.d.ts +28 -2
  93. package/dist/types/utils/mupdf-embedded.d.ts +2 -0
  94. package/dist/types/utils/mupdf.d.ts +4 -0
  95. package/dist/types/utils/session-title-generation.d.ts +6 -0
  96. package/dist/types/utils/title-generator.d.ts +11 -2
  97. package/dist/types/web/scrapers/types.d.ts +3 -0
  98. package/package.json +18 -10
  99. package/scripts/build-binary.ts +9 -3
  100. package/scripts/compile-args.ts +0 -9
  101. package/scripts/embed-mupdf.ts +52 -0
  102. package/scripts/generate-sdk-operation-inventory.ts +31 -1
  103. package/scripts/vendor-markit.ts +196 -0
  104. package/src/async/job-manager.ts +22 -1
  105. package/src/cli/daemon-cli.ts +53 -18
  106. package/src/cli/github-release.ts +87 -5
  107. package/src/cli/mcp-cli.ts +38 -4
  108. package/src/cli/public-command-entry.ts +450 -0
  109. package/src/cli/public-command-errors.ts +581 -0
  110. package/src/cli/public-command-evidence.ts +717 -0
  111. package/src/cli/public-command-help.ts +360 -0
  112. package/src/cli/public-command-registry.ts +535 -0
  113. package/src/cli/session-picker.ts +2 -1
  114. package/src/cli/setup-cli.ts +9 -1
  115. package/src/cli/skills-cli.ts +46 -2
  116. package/src/cli.ts +61 -1
  117. package/src/commands/daemon.ts +65 -69
  118. package/src/commands/sdk.ts +175 -117
  119. package/src/commands/setup.ts +2 -0
  120. package/src/commands/skills.ts +11 -0
  121. package/src/config/autorouting-tier-map.ts +14 -0
  122. package/src/config/file-lock.ts +147 -51
  123. package/src/config/model-profile-activation.ts +334 -43
  124. package/src/config/model-registry.ts +183 -25
  125. package/src/config/settings-schema.ts +26 -2
  126. package/src/coordinator-mcp/policy.ts +10 -5
  127. package/src/coordinator-mcp/question-gate-codec.ts +17 -0
  128. package/src/coordinator-mcp/question-state.ts +175 -8
  129. package/src/coordinator-mcp/server.ts +507 -81
  130. package/src/coordinator-mcp/session-reaper.ts +6 -4
  131. package/src/crash/record-loader.ts +6 -2
  132. package/src/daemon/operator-contract.ts +26 -12
  133. package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
  134. package/src/eval/js/context-manager.ts +8 -8
  135. package/src/eval/js/worker-core.ts +9 -4
  136. package/src/eval/js/worker-protocol.ts +2 -0
  137. package/src/extensibility/extensions/runner.ts +52 -4
  138. package/src/extensibility/extensions/types.ts +10 -0
  139. package/src/extensibility/gjc-plugins/registry.ts +196 -37
  140. package/src/extensibility/runtime-skill-discovery.ts +61 -3
  141. package/src/extensibility/shared-events.ts +3 -1
  142. package/src/gjc-runtime/session-state-lock.ts +165 -24
  143. package/src/gjc-runtime/ultragoal-succession.ts +31 -3
  144. package/src/internal-urls/docs-index.generated.ts +20 -19
  145. package/src/internal-urls/embedded-protocol.ts +83 -0
  146. package/src/internal-urls/index.ts +1 -0
  147. package/src/internal-urls/parse.ts +21 -1
  148. package/src/internal-urls/router.ts +4 -2
  149. package/src/main.ts +123 -55
  150. package/src/modes/acp/acp-agent.ts +408 -35
  151. package/src/modes/acp/startup-provenance.ts +59 -0
  152. package/src/modes/components/custom-provider-wizard.ts +308 -7
  153. package/src/modes/components/oauth-selector.ts +9 -0
  154. package/src/modes/components/session-selector.ts +47 -4
  155. package/src/modes/components/user-message-selector.ts +57 -15
  156. package/src/modes/controllers/command-controller.ts +58 -32
  157. package/src/modes/controllers/extension-ui-controller.ts +33 -7
  158. package/src/modes/controllers/input-controller.ts +4 -0
  159. package/src/modes/controllers/selector-controller.ts +161 -15
  160. package/src/modes/interactive-mode.ts +21 -7
  161. package/src/modes/runtime-init.ts +1 -0
  162. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
  163. package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
  164. package/src/modes/types.ts +2 -2
  165. package/src/prompts/agent-fragments/browser-aside.md +1 -0
  166. package/src/prompts/system/title-system.md +1 -1
  167. package/src/prompts/tools/bash.md +1 -1
  168. package/src/prompts/tools/job.md +1 -1
  169. package/src/prompts/tools/read.md +2 -0
  170. package/src/runtime/network-prewarm-service.test.ts +36 -1
  171. package/src/runtime/network-prewarm-service.ts +28 -3
  172. package/src/runtime/process-lifecycle.ts +22 -11
  173. package/src/runtime-mcp/config.ts +16 -1
  174. package/src/runtime-mcp/manager.ts +689 -55
  175. package/src/runtime-mcp/pool.test.ts +31 -0
  176. package/src/runtime-mcp/pool.ts +304 -28
  177. package/src/runtime-mcp/redaction.ts +42 -0
  178. package/src/runtime-mcp/startup-policy.ts +7 -0
  179. package/src/runtime-mcp/tool-bridge.ts +71 -0
  180. package/src/runtime-mcp/transports/http.ts +108 -25
  181. package/src/sdk/acp/adapter.ts +27 -8
  182. package/src/sdk/broker/broker.ts +378 -52
  183. package/src/sdk/broker/identity.ts +9 -1
  184. package/src/sdk/broker/lifecycle-ledger.ts +95 -31
  185. package/src/sdk/broker/lifecycle.ts +690 -141
  186. package/src/sdk/broker/runtime.ts +1 -1
  187. package/src/sdk/broker/session-index.ts +97 -4
  188. package/src/sdk/broker/spawn-authority.ts +35 -7
  189. package/src/sdk/broker/stderr-drainer.ts +59 -0
  190. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  191. package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
  192. package/src/sdk/bus/index.ts +690 -80
  193. package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
  194. package/src/sdk/bus/telegram-daemon-contract.ts +3 -1
  195. package/src/sdk/bus/telegram-daemon.ts +10 -3
  196. package/src/sdk/cli/master-cli.ts +47 -36
  197. package/src/sdk/cli/rows.ts +30 -7
  198. package/src/sdk/cli/session-cli.ts +687 -184
  199. package/src/sdk/client/client.ts +18 -0
  200. package/src/sdk/guides/catalog.ts +2 -2
  201. package/src/sdk/guides/cli.ts +20 -62
  202. package/src/sdk/guides/verify.ts +14 -0
  203. package/src/sdk/host/host.ts +49 -5
  204. package/src/sdk/host/session-runtime.test.ts +138 -2
  205. package/src/sdk/host/session-runtime.ts +311 -97
  206. package/src/sdk/host/types.ts +12 -1
  207. package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
  208. package/src/sdk/host/websocket-transport.ts +40 -6
  209. package/src/sdk/index.ts +11 -0
  210. package/src/sdk/prompt-deadline-flush.ts +334 -0
  211. package/src/sdk/prompt-deadline-manager.ts +133 -1
  212. package/src/sdk/prompt-tool-boundary.ts +121 -0
  213. package/src/sdk/protocol/operation-inventory.generated.json +106 -0
  214. package/src/sdk/router/session-router.ts +9 -1
  215. package/src/sdk/session.ts +182 -7
  216. package/src/sdk/startup-capability.ts +1 -1
  217. package/src/sdk/transport/relay.ts +71 -6
  218. package/src/sdk/transport/serve-cli.ts +397 -42
  219. package/src/sdk/transport/socket.ts +12 -11
  220. package/src/sdk/transport/stdio.ts +7 -3
  221. package/src/session/agent-session.ts +2437 -400
  222. package/src/session/fallback-chain-controller.ts +6 -7
  223. package/src/session/fold-coordinator.ts +24 -5
  224. package/src/session/internal/managed-session-scope.ts +58 -18
  225. package/src/session/internal/managed-session-storage.ts +304 -11
  226. package/src/session/session-manager.ts +382 -44
  227. package/src/session/session-work-lease.ts +34 -0
  228. package/src/setup/model-onboarding-guidance.ts +1 -1
  229. package/src/setup/provider-onboarding.ts +397 -24
  230. package/src/slash-commands/builtin-registry.ts +258 -14
  231. package/src/task/index.ts +14 -2
  232. package/src/tools/bash.ts +98 -78
  233. package/src/tools/fetch.ts +119 -20
  234. package/src/tools/job.ts +151 -25
  235. package/src/tools/output-meta.ts +15 -2
  236. package/src/tools/path-utils.ts +27 -3
  237. package/src/tools/read.ts +3 -3
  238. package/src/tools/steer-fold.ts +107 -0
  239. package/src/tools/tool-catalog.generated.ts +29 -2
  240. package/src/tools/tool-errors.ts +4 -0
  241. package/src/utils/git.ts +53 -3
  242. package/src/utils/markit.ts +55 -41
  243. package/src/utils/mupdf-assets.d.ts +4 -0
  244. package/src/utils/mupdf-embedded.ts +4 -0
  245. package/src/utils/mupdf.ts +129 -0
  246. package/src/utils/session-title-generation.ts +29 -0
  247. package/src/utils/title-generator.ts +46 -2
  248. package/src/web/scrapers/types.ts +24 -3
  249. package/vendor/markit-ai/LICENSE +21 -0
  250. package/vendor/markit-ai/MANIFEST.json +412 -0
  251. package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
  252. package/vendor/markit-ai/dist/commands/config.js +139 -0
  253. package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
  254. package/vendor/markit-ai/dist/commands/convert.js +113 -0
  255. package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
  256. package/vendor/markit-ai/dist/commands/formats.js +92 -0
  257. package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
  258. package/vendor/markit-ai/dist/commands/init.js +29 -0
  259. package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
  260. package/vendor/markit-ai/dist/commands/onboard.js +61 -0
  261. package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
  262. package/vendor/markit-ai/dist/commands/plugin.js +58 -0
  263. package/vendor/markit-ai/dist/config.d.ts +26 -0
  264. package/vendor/markit-ai/dist/config.js +42 -0
  265. package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
  266. package/vendor/markit-ai/dist/converters/audio.js +104 -0
  267. package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
  268. package/vendor/markit-ai/dist/converters/csv.js +83 -0
  269. package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
  270. package/vendor/markit-ai/dist/converters/docx.js +57 -0
  271. package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
  272. package/vendor/markit-ai/dist/converters/epub.js +128 -0
  273. package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
  274. package/vendor/markit-ai/dist/converters/github.js +148 -0
  275. package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
  276. package/vendor/markit-ai/dist/converters/html.js +30 -0
  277. package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
  278. package/vendor/markit-ai/dist/converters/image.js +124 -0
  279. package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
  280. package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
  281. package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
  282. package/vendor/markit-ai/dist/converters/iwork.js +391 -0
  283. package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
  284. package/vendor/markit-ai/dist/converters/json.js +21 -0
  285. package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
  286. package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
  287. package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
  288. package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
  289. package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
  290. package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
  291. package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
  292. package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
  293. package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
  294. package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
  295. package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
  296. package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
  297. package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
  298. package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
  299. package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
  300. package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
  301. package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
  302. package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
  303. package/vendor/markit-ai/dist/converters/pptx.js +289 -0
  304. package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
  305. package/vendor/markit-ai/dist/converters/rss.js +138 -0
  306. package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
  307. package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
  308. package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
  309. package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
  310. package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
  311. package/vendor/markit-ai/dist/converters/xml.js +18 -0
  312. package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
  313. package/vendor/markit-ai/dist/converters/yaml.js +17 -0
  314. package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
  315. package/vendor/markit-ai/dist/converters/zip.js +57 -0
  316. package/vendor/markit-ai/dist/index.d.ts +30 -0
  317. package/vendor/markit-ai/dist/index.js +26 -0
  318. package/vendor/markit-ai/dist/main.d.ts +2 -0
  319. package/vendor/markit-ai/dist/main.js +191 -0
  320. package/vendor/markit-ai/dist/markit.d.ts +45 -0
  321. package/vendor/markit-ai/dist/markit.js +267 -0
  322. package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
  323. package/vendor/markit-ai/dist/plugins/api.js +42 -0
  324. package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
  325. package/vendor/markit-ai/dist/plugins/index.js +3 -0
  326. package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
  327. package/vendor/markit-ai/dist/plugins/installer.js +176 -0
  328. package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
  329. package/vendor/markit-ai/dist/plugins/loader.js +61 -0
  330. package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
  331. package/vendor/markit-ai/dist/plugins/types.js +1 -0
  332. package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
  333. package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
  334. package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
  335. package/vendor/markit-ai/dist/providers/index.js +56 -0
  336. package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
  337. package/vendor/markit-ai/dist/providers/openai.js +76 -0
  338. package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
  339. package/vendor/markit-ai/dist/providers/types.js +1 -0
  340. package/vendor/markit-ai/dist/types.d.ts +36 -0
  341. package/vendor/markit-ai/dist/types.js +1 -0
  342. package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
  343. package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
  344. package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
  345. package/vendor/markit-ai/dist/utils/output.js +31 -0
  346. package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
  347. package/vendor/markit-ai/dist/utils/turndown.js +70 -0
  348. package/vendor/markit-ai/package.json +74 -0
  349. package/vendor/markit-ai.patch +49 -0
@@ -0,0 +1,581 @@
1
+ import { sanitizeDisplayLine } from "@gajae-code/utils";
2
+ import type { DaemonOperationResult, DaemonRecovery, DaemonStatus } from "../daemon/control-types";
3
+ import {
4
+ type EvidenceClassification,
5
+ type EvidenceContinuation,
6
+ type EvidenceReference,
7
+ type EvidenceReferenceKind,
8
+ type EvidenceUnavailableReason,
9
+ publishCommandEvidence,
10
+ } from "./public-command-evidence";
11
+
12
+ export type PublicFailureKind =
13
+ | "usage"
14
+ | "invalid_json"
15
+ | "unavailable"
16
+ | "broker_unavailable"
17
+ | "endpoint_stale"
18
+ | "broker_restarting"
19
+ | "authorization_denied"
20
+ | "timeout"
21
+ | "wait_timeout"
22
+ | "uncertain_after_send"
23
+ | "daemon_unhealthy"
24
+ | "daemon_stale"
25
+ | "daemon_mixed"
26
+ | "operation_failed"
27
+ | "internal";
28
+ export type PublicEffectProof = "pre-send" | "pre-effect" | "accepted" | "completed" | "sent" | "unknown";
29
+ export interface PublicDaemonTargetOutcome {
30
+ kind: "telegram" | "discord" | "slack";
31
+ outcome: "not-applied" | "applied" | "unknown";
32
+ }
33
+ export interface PublicCommandFailureInput {
34
+ kind: PublicFailureKind;
35
+ proof?: PublicEffectProof;
36
+ references?: readonly EvidenceReference[];
37
+ daemonKind?: "telegram" | "discord" | "slack";
38
+ restartJustified?: boolean;
39
+ targets?: readonly PublicDaemonTargetOutcome[];
40
+ partialStatuses?: readonly DaemonStatus[];
41
+ /**
42
+ * Operation results already completed before a later target failed. Without them
43
+ * a `daemon_mixed` failure tells the caller not to repeat applied mutations but
44
+ * withholds the resulting state it would have to reconcile against.
45
+ */
46
+ partialResults?: readonly DaemonOperationResult[];
47
+ diagnostics?: readonly PublicCommandDiagnosticCode[];
48
+ }
49
+ export class PublicCommandFailure extends Error {
50
+ readonly input: PublicCommandFailureInput;
51
+ constructor(input: PublicCommandFailureInput) {
52
+ super("Public command failed");
53
+ this.name = "PublicCommandFailure";
54
+ this.input = input;
55
+ }
56
+ }
57
+ export interface PublicRecoveryStep {
58
+ description: string;
59
+ disruption: "none" | "interrupts-work" | "force-kill";
60
+ requiresConfirmation: boolean;
61
+ executable?: "gjc";
62
+ argv?: string[];
63
+ }
64
+ export interface ClassifiedPublicCommandFailure extends EvidenceClassification {
65
+ message: string;
66
+ references: EvidenceReference[];
67
+ nextSteps: PublicRecoveryStep[];
68
+ partialStatuses?: DaemonStatus[];
69
+ partialResults?: PublicDaemonOperationResult[];
70
+ exitCode: 1 | 2;
71
+ }
72
+ /** Bounded projection of a completed daemon operation result for failure envelopes. */
73
+ export interface PublicDaemonOperationResult {
74
+ kind: "telegram" | "discord" | "slack";
75
+ action: DaemonOperationResult["action"];
76
+ ok: boolean;
77
+ before?: DaemonStatus;
78
+ after?: DaemonStatus;
79
+ /**
80
+ * Typed allowlisted recovery category only. The failure envelope never echoes
81
+ * controller-supplied free text, so the message, warnings, and remediation
82
+ * strings of a completed operation stay out of it.
83
+ */
84
+ recovery?: { reason: DaemonRecovery["reason"] };
85
+ }
86
+ export const EVIDENCE_UNAVAILABLE_WARNING =
87
+ "Necessary reconciliation evidence could not be retained; no lossless continuation is available. Do not blindly retry the original operation.";
88
+ export type PublicEvidenceStatus =
89
+ | { status: "inline" }
90
+ | { status: "retained"; id: string; sha256: string; bytes: number; expiresAt: string }
91
+ | {
92
+ status: "unavailable";
93
+ reason: EvidenceUnavailableReason;
94
+ requiredBytes: number | null;
95
+ missingKinds: string[];
96
+ warning: typeof EVIDENCE_UNAVAILABLE_WARNING;
97
+ };
98
+ export const PUBLIC_COMMAND_DIAGNOSTICS = {
99
+ macos_nofile_limit_low:
100
+ "The macOS open-file limit is below the recommended minimum; increase it before starting additional concurrent work.",
101
+ router_cleanup_failed: "SDK session Router cleanup failed.",
102
+ broker_cleanup_failed: "SDK broker client cleanup failed.",
103
+ usage_transport_exclusive: "Specify exactly one of --stdio or --socket <path>.",
104
+ usage_duplicate_option: "Each option on this command may occur at most once.",
105
+ usage_unknown_argument: "An unrecognized argument was supplied; re-read the command help for its accepted grammar.",
106
+ usage_missing_value: "An option that requires a value was supplied without one.",
107
+ usage_invalid_option_value: "An option value is invalid; re-read the command help for its accepted values.",
108
+ } as const;
109
+ export type PublicCommandDiagnosticCode = keyof typeof PUBLIC_COMMAND_DIAGNOSTICS;
110
+ export interface PublicCommandDiagnostic {
111
+ code: PublicCommandDiagnosticCode;
112
+ message: string;
113
+ }
114
+ export interface PublicCommandErrorEnvelope {
115
+ schema: "gjc.command-error";
116
+ version: 1;
117
+ ok: false;
118
+ command: string[];
119
+ error: Omit<ClassifiedPublicCommandFailure, "exitCode">;
120
+ diagnostics?: PublicCommandDiagnostic[];
121
+ omittedOptional: { path: string; reason: string }[];
122
+ complete: boolean;
123
+ evidence: PublicEvidenceStatus;
124
+ continuation: EvidenceContinuation | null;
125
+ }
126
+ export interface RenderPublicCommandFailureOptions {
127
+ command: readonly string[];
128
+ json?: boolean;
129
+ agentDir?: string;
130
+ scopeAgentDir?: string;
131
+ diagnostics?: readonly PublicCommandDiagnosticCode[];
132
+ }
133
+ export interface RenderedPublicCommandFailure {
134
+ stdout: string;
135
+ stderr: string;
136
+ exitCode: 1 | 2;
137
+ envelope: PublicCommandErrorEnvelope;
138
+ }
139
+
140
+ const referenceKinds = new Set<EvidenceReferenceKind>([
141
+ "sessionId",
142
+ "operationRef",
143
+ "idempotencyKey",
144
+ "claimId",
145
+ "commandId",
146
+ "turnId",
147
+ ]);
148
+ const messages: Record<PublicFailureKind, string> = {
149
+ usage: "The command arguments are invalid.",
150
+ invalid_json: "The command JSON input is invalid.",
151
+ unavailable: "The requested service is unavailable.",
152
+ broker_unavailable: "The SDK broker is unavailable.",
153
+ endpoint_stale: "The SDK endpoint is stale or unavailable.",
154
+ broker_restarting: "The SDK broker is restarting. Do not initiate another restart.",
155
+ authorization_denied: "The operation was denied by authorization policy.",
156
+ timeout: "The operation timed out; its outcome requires reconciliation.",
157
+ wait_timeout: "Waiting timed out after the operation was accepted. Do not replay it.",
158
+ uncertain_after_send: "The request was sent but its outcome is uncertain. Reconcile before any replay.",
159
+ daemon_unhealthy: "The selected daemon is unhealthy.",
160
+ daemon_stale: "The selected daemon has stale runtime state.",
161
+ daemon_mixed: "Some daemon targets failed. Do not repeat mutations that already succeeded.",
162
+ operation_failed: "The operation failed. Its outcome could not be established.",
163
+ internal: "The command encountered an internal failure.",
164
+ };
165
+ function commandPath(command: readonly string[]): string[] {
166
+ if (
167
+ command.length > 0 &&
168
+ command.length <= 5 &&
169
+ ["sdk", "daemon"].includes(command[0]!) &&
170
+ command.every(token => /^[a-z][a-z-]{0,31}$/.test(token))
171
+ )
172
+ return [...command];
173
+ return [command[0] === "daemon" ? "daemon" : "sdk"];
174
+ }
175
+ function safeReferences(references: readonly EvidenceReference[] | undefined): EvidenceReference[] {
176
+ if (!Array.isArray(references)) return [];
177
+ return references
178
+ .filter(ref => ref && referenceKinds.has(ref.kind) && typeof ref.value === "string")
179
+ .map(ref => ({ kind: ref.kind, value: ref.value }));
180
+ }
181
+ const DAEMON_STATUS_TEXT_BYTES = 128;
182
+ const DAEMON_KINDS = ["telegram", "discord", "slack"] as const;
183
+ const DAEMON_HEALTHS = ["not_configured", "stopped", "running", "stale", "stopping", "error"] as const;
184
+
185
+ function boundedUtf8(value: string, maxBytes: number): string {
186
+ if (Buffer.byteLength(value, "utf8") <= maxBytes) return value;
187
+ let end = Math.min(value.length, maxBytes);
188
+ while (end > 0 && Buffer.byteLength(value.slice(0, end), "utf8") > maxBytes) end--;
189
+ return value.slice(0, end);
190
+ }
191
+ function boundedDaemonText(value: string): string {
192
+ return boundedUtf8(sanitizeDisplayLine(value).replaceAll(/[\u2028\u2029]/gu, " "), DAEMON_STATUS_TEXT_BYTES);
193
+ }
194
+
195
+ function boundedDaemonStatuses(statuses: readonly DaemonStatus[] | undefined): DaemonStatus[] {
196
+ if (!Array.isArray(statuses)) return [];
197
+ return statuses.slice(0, 3).map(status => ({
198
+ kind: DAEMON_KINDS.includes(status.kind) ? status.kind : "telegram",
199
+ configured: status.configured === true,
200
+ health: DAEMON_HEALTHS.includes(status.health) ? status.health : "error",
201
+ ...(Number.isSafeInteger(status.pid) && status.pid > 0 ? { pid: status.pid } : {}),
202
+ ...(typeof status.ownerId === "string" ? { ownerId: boundedDaemonText(status.ownerId) } : {}),
203
+ ...(Number.isSafeInteger(status.rootCount) && status.rootCount >= 0 ? { rootCount: status.rootCount } : {}),
204
+ runtime: {
205
+ mode: status.runtime.mode === "compiled" ? "compiled" : "source",
206
+ execPath: boundedDaemonText(status.runtime.execPath),
207
+ reloadPicksUpSourceEdits: status.runtime.reloadPicksUpSourceEdits === true,
208
+ ...(typeof status.runtime.warning === "string" ? { warning: boundedDaemonText(status.runtime.warning) } : {}),
209
+ },
210
+ ...(typeof status.detail === "string" ? { detail: boundedDaemonText(status.detail) } : {}),
211
+ }));
212
+ }
213
+
214
+ const DAEMON_RESULT_ACTIONS = ["status", "stop", "restart", "reload"] as const;
215
+
216
+ /** Bounded projection: only allowlisted identity, typed outcome, and structured state survive. */
217
+ function boundedDaemonResults(results: readonly DaemonOperationResult[] | undefined): PublicDaemonOperationResult[] {
218
+ if (!Array.isArray(results)) return [];
219
+ return results.slice(0, 3).map(result => ({
220
+ kind: DAEMON_KINDS.includes(result.kind) ? result.kind : "telegram",
221
+ action: DAEMON_RESULT_ACTIONS.includes(result.action) ? result.action : "restart",
222
+ ok: result.ok === true,
223
+ ...(result.before === undefined ? {} : { before: boundedDaemonStatuses([result.before])[0]! }),
224
+ ...(result.after === undefined ? {} : { after: boundedDaemonStatuses([result.after])[0]! }),
225
+ ...(result.recovery === undefined ? {} : { recovery: { reason: result.recovery.reason } }),
226
+ }));
227
+ }
228
+ export function normalizePublicCommandFailure(error: unknown): PublicCommandFailure {
229
+ if (error instanceof PublicCommandFailure && error.input && Object.hasOwn(messages, error.input.kind)) return error;
230
+ return new PublicCommandFailure({ kind: "operation_failed" });
231
+ }
232
+ function step(
233
+ description: string,
234
+ argv?: string[],
235
+ disruption: PublicRecoveryStep["disruption"] = "none",
236
+ ): PublicRecoveryStep {
237
+ return {
238
+ description,
239
+ disruption,
240
+ requiresConfirmation: disruption !== "none",
241
+ ...(argv ? { executable: "gjc" as const, argv } : {}),
242
+ };
243
+ }
244
+ export function classifyPublicCommandFailure(
245
+ error: unknown,
246
+ command: readonly string[],
247
+ ): ClassifiedPublicCommandFailure {
248
+ const input = normalizePublicCommandFailure(error).input;
249
+ const kind = input.kind;
250
+ const references = safeReferences(input.references);
251
+ const canonical = commandPath(command);
252
+ const beforeEffect = input.proof === "pre-send" || input.proof === "pre-effect";
253
+ let outcomeCertainty: EvidenceClassification["outcomeCertainty"] = beforeEffect
254
+ ? "not-applied"
255
+ : input.proof === "accepted" || input.proof === "completed"
256
+ ? "applied"
257
+ : "unknown";
258
+ let retryability: EvidenceClassification["retryability"] = "unknown";
259
+ let category: EvidenceClassification["category"] = "operation";
260
+ const nextSteps: PublicRecoveryStep[] = [];
261
+ const usage = kind === "usage" || kind === "invalid_json";
262
+ if (usage) {
263
+ category = "usage";
264
+ outcomeCertainty = "not-applied";
265
+ retryability = "no";
266
+ nextSteps.push(step("Read the exact command help and correct the input.", [...canonical, "--help"]));
267
+ } else if (kind === "authorization_denied") {
268
+ category = "authorization";
269
+ retryability = "no";
270
+ nextSteps.push(step("Use the authorized caller and required master context. Do not print or share credentials."));
271
+ } else if (kind === "wait_timeout") {
272
+ category = "timeout";
273
+ outcomeCertainty = "applied";
274
+ retryability = "no";
275
+ } else if (kind === "timeout") category = "timeout";
276
+ else if (kind === "uncertain_after_send") {
277
+ category = "uncertain";
278
+ outcomeCertainty = "unknown";
279
+ } else if (
280
+ [
281
+ "unavailable",
282
+ "broker_unavailable",
283
+ "endpoint_stale",
284
+ "broker_restarting",
285
+ "daemon_unhealthy",
286
+ "daemon_stale",
287
+ ].includes(kind)
288
+ )
289
+ category = "unavailable";
290
+ else if (kind === "internal") category = "internal";
291
+ if (kind === "daemon_mixed") {
292
+ const targets = input.targets;
293
+ outcomeCertainty =
294
+ targets?.length && targets.every(target => target.outcome === "applied")
295
+ ? "applied"
296
+ : targets?.length && targets.every(target => target.outcome === "not-applied")
297
+ ? "not-applied"
298
+ : "unknown";
299
+ // Only the bounded allowlisted target identity and typed outcome are rendered.
300
+ for (const daemonKind of ["telegram", "discord", "slack"] as const) {
301
+ const matches = targets?.filter(target => target.kind === daemonKind);
302
+ if (!matches?.length) continue;
303
+ const outcome = matches.every(target => target.outcome === "applied")
304
+ ? "applied"
305
+ : matches.every(target => target.outcome === "not-applied")
306
+ ? "not-applied"
307
+ : "unknown";
308
+ nextSteps.push(
309
+ step(`${daemonKind}: outcome ${outcome}. Inspect this target; do not replay a successful mutation.`, [
310
+ "daemon",
311
+ "status",
312
+ daemonKind,
313
+ ]),
314
+ );
315
+ }
316
+ }
317
+ if (!usage) {
318
+ if (kind === "broker_restarting")
319
+ nextSteps.push(step("Wait for the existing restart to finish, then inspect status; do not restart again."));
320
+ const session = references.find(ref => ref.kind === "sessionId");
321
+ const operation = references.find(ref => ref.kind === "operationRef");
322
+ if (
323
+ canonical[0] === "sdk" &&
324
+ session &&
325
+ operation &&
326
+ executableValue(session.value) &&
327
+ executableValue(operation.value)
328
+ ) {
329
+ nextSteps.push(
330
+ step(
331
+ "Reconcile the existing operation by its complete session and operation references before any replay.",
332
+ ["sdk", "session", "status", session.value, operation.value],
333
+ ),
334
+ );
335
+ } else if (canonical[0] === "sdk" && kind !== "authorization_denied") {
336
+ nextSteps.push(
337
+ step("Inspect existing session state before deciding whether another operation is safe.", [
338
+ "sdk",
339
+ "session",
340
+ "list",
341
+ ]),
342
+ );
343
+ }
344
+ if (
345
+ canonical[0] === "daemon" &&
346
+ input.daemonKind &&
347
+ ["telegram", "discord", "slack"].includes(input.daemonKind)
348
+ ) {
349
+ nextSteps.push(step("Inspect only the affected daemon target.", ["daemon", "status", input.daemonKind]));
350
+ if ((kind === "daemon_unhealthy" || kind === "daemon_stale") && input.restartJustified === true)
351
+ nextSteps.push(
352
+ step(
353
+ "Restart only this diagnosed daemon after confirming interruption of its work is acceptable.",
354
+ ["daemon", "restart", input.daemonKind],
355
+ "interrupts-work",
356
+ ),
357
+ );
358
+ }
359
+ if (outcomeCertainty === "unknown")
360
+ nextSteps.push(
361
+ step("The operation outcome is unknown. Reconcile available evidence and do not blindly retry."),
362
+ );
363
+ }
364
+ return {
365
+ code: kind,
366
+ category,
367
+ message: messages[kind],
368
+ retryability,
369
+ outcomeCertainty,
370
+ references,
371
+ nextSteps,
372
+ ...(input.partialStatuses === undefined ? {} : { partialStatuses: boundedDaemonStatuses(input.partialStatuses) }),
373
+ ...(input.partialResults === undefined ? {} : { partialResults: boundedDaemonResults(input.partialResults) }),
374
+ exitCode: usage ? 2 : 1,
375
+ };
376
+ }
377
+ function executableValue(value: string): boolean {
378
+ return value.length > 0 && value.length <= 1024 && !value.startsWith("-") && !/[\x00-\x1f\x7f]/.test(value);
379
+ }
380
+ function serialize(envelope: PublicCommandErrorEnvelope, json: boolean): string {
381
+ if (json) return `${JSON.stringify(envelope)}\n`;
382
+ // JSON quoting escapes terminal controls and preserves complete values. Display
383
+ // strings are not shell commands: executable suggestions remain argv arrays.
384
+ return `COMMAND ${JSON.stringify(envelope.command)}\nERROR ${JSON.stringify(envelope.error)}\n${envelope.diagnostics ? `DIAGNOSTICS ${JSON.stringify(envelope.diagnostics)}\n` : ""}COMPLETE ${envelope.complete}\nEVIDENCE ${JSON.stringify(envelope.evidence)}\nOMITTED_OPTIONAL ${JSON.stringify(envelope.omittedOptional)}\nCONTINUATION ${JSON.stringify(envelope.continuation)}\n`.replace(
385
+ /[\x7f-\x9f\u2028\u2029]/g,
386
+ character => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`,
387
+ );
388
+ }
389
+ function fits(envelope: PublicCommandErrorEnvelope, json: boolean): boolean {
390
+ return Buffer.byteLength(serialize(envelope, json)) <= 8192;
391
+ }
392
+ function trimSteps(envelope: PublicCommandErrorEnvelope, json: boolean): void {
393
+ while (!fits(envelope, json) && envelope.error.nextSteps.length) {
394
+ envelope.error.nextSteps.pop();
395
+ if (!envelope.omittedOptional.some(item => item.path === "error.nextSteps"))
396
+ envelope.omittedOptional.push({ path: "error.nextSteps", reason: "output_budget" });
397
+ }
398
+ }
399
+ function omitPartialStatusesForBudget(envelope: PublicCommandErrorEnvelope, json: boolean): void {
400
+ // Completed operation results are the reconciliation payload; the status view is
401
+ // redundant beside them, so the status view is dropped first under budget pressure.
402
+ for (const path of ["error.partialStatuses", "error.partialResults"] as const) {
403
+ const present =
404
+ path === "error.partialStatuses"
405
+ ? envelope.error.partialStatuses !== undefined
406
+ : envelope.error.partialResults !== undefined;
407
+ if (!present || fits(envelope, json)) continue;
408
+ if (path === "error.partialStatuses") delete envelope.error.partialStatuses;
409
+ else delete envelope.error.partialResults;
410
+ if (!envelope.omittedOptional.some(item => item.path === path))
411
+ envelope.omittedOptional.push({ path, reason: "output_budget" });
412
+ }
413
+ }
414
+
415
+ function reserveDiagnostics(
416
+ envelope: PublicCommandErrorEnvelope,
417
+ options: RenderPublicCommandFailureOptions,
418
+ failureDiagnostics?: readonly PublicCommandDiagnosticCode[],
419
+ ): PublicCommandDiagnostic[] {
420
+ // Iterate the static allowlist, not caller-sized input; messages are never caller supplied.
421
+ const diagnostics = (Object.keys(PUBLIC_COMMAND_DIAGNOSTICS) as PublicCommandDiagnosticCode[])
422
+ .filter(code => options.diagnostics?.includes(code) || failureDiagnostics?.includes(code))
423
+ .map(code => ({ code, message: PUBLIC_COMMAND_DIAGNOSTICS[code] }));
424
+ if (diagnostics.length) envelope.omittedOptional.push({ path: "diagnostics", reason: "output_budget" });
425
+ return diagnostics;
426
+ }
427
+
428
+ function includeDiagnostics(
429
+ envelope: PublicCommandErrorEnvelope,
430
+ diagnostics: PublicCommandDiagnostic[],
431
+ json: boolean,
432
+ ): void {
433
+ if (!diagnostics.length) return;
434
+ const omissions = envelope.omittedOptional;
435
+ envelope.omittedOptional = omissions.filter(item => item.path !== "diagnostics");
436
+ envelope.diagnostics = diagnostics;
437
+ if (!fits(envelope, json)) {
438
+ delete envelope.diagnostics;
439
+ envelope.omittedOptional = omissions;
440
+ }
441
+ }
442
+ export async function renderPublicCommandFailure(
443
+ error: unknown,
444
+ options: RenderPublicCommandFailureOptions,
445
+ ): Promise<RenderedPublicCommandFailure> {
446
+ const classified = classifyPublicCommandFailure(error, options.command);
447
+ const { exitCode, ...safeError } = classified;
448
+ const references = safeError.references;
449
+ const json = options.json === true;
450
+ if (options.scopeAgentDir !== undefined) {
451
+ for (const recovery of safeError.nextSteps) {
452
+ if (recovery.argv?.[0] !== "sdk" || recovery.argv.at(-1) === "--help") continue;
453
+ if (options.scopeAgentDir.length <= 1024 && !/[\x00-\x1f\x7f-\x9f\u2028\u2029]/.test(options.scopeAgentDir))
454
+ recovery.argv.push(`--agent-dir=${options.scopeAgentDir}`);
455
+ else {
456
+ delete recovery.executable;
457
+ delete recovery.argv;
458
+ }
459
+ }
460
+ }
461
+ const envelope: PublicCommandErrorEnvelope = {
462
+ schema: "gjc.command-error",
463
+ version: 1,
464
+ ok: false,
465
+ command: commandPath(options.command),
466
+ error: { ...safeError, references: [] },
467
+ omittedOptional: [],
468
+ complete: true,
469
+ evidence: { status: "inline" },
470
+ continuation: null,
471
+ };
472
+ const diagnostics = reserveDiagnostics(envelope, options, normalizePublicCommandFailure(error).input.diagnostics);
473
+ // Avoid serializing a caller-sized reference merely to discover it cannot fit.
474
+ let overflow = false;
475
+ for (const reference of references) {
476
+ if (reference.value.length > 8192) {
477
+ overflow = true;
478
+ continue;
479
+ }
480
+ envelope.error.references.push(reference);
481
+ if (!fits(envelope, json)) trimSteps(envelope, json);
482
+ if (!fits(envelope, json)) {
483
+ envelope.error.references.pop();
484
+ overflow = true;
485
+ }
486
+ }
487
+ trimSteps(envelope, json);
488
+ if (overflow) {
489
+ envelope.complete = false;
490
+ const retained =
491
+ options.agentDir === undefined
492
+ ? { status: "unavailable" as const, reason: "io_error" as const, requiredBytes: null }
493
+ : await publishCommandEvidence(
494
+ { agentDir: options.agentDir, command: envelope.command, error: classified, references },
495
+ { family: envelope.command[0] as "sdk" | "daemon", scopeAgentDir: options.scopeAgentDir, json },
496
+ );
497
+ if (retained.status === "retained") {
498
+ envelope.evidence = {
499
+ status: "retained",
500
+ id: retained.id,
501
+ sha256: retained.sha256,
502
+ bytes: retained.bytes,
503
+ expiresAt: retained.expiresAt,
504
+ };
505
+ envelope.continuation = retained.continuation;
506
+ } else {
507
+ envelope.evidence = {
508
+ status: "unavailable",
509
+ reason: retained.reason,
510
+ requiredBytes: retained.requiredBytes,
511
+ missingKinds: [...new Set(references.map(ref => ref.kind))],
512
+ warning: EVIDENCE_UNAVAILABLE_WARNING,
513
+ };
514
+ }
515
+ trimSteps(envelope, json);
516
+ omitPartialStatusesForBudget(envelope, json);
517
+ while (!fits(envelope, json) && envelope.error.references.length) envelope.error.references.pop();
518
+ if (envelope.evidence.status === "unavailable") {
519
+ const included = new Set(envelope.error.references);
520
+ envelope.evidence.missingKinds = [
521
+ ...new Set(references.filter(ref => !included.has(ref)).map(ref => ref.kind)),
522
+ ];
523
+ }
524
+ }
525
+ // Text control escaping can expand a locator beyond its JSON admission size.
526
+ // Never advertise a continuation that cannot be represented within this mode.
527
+ if (!fits(envelope, json)) {
528
+ envelope.complete = false;
529
+ envelope.continuation = null;
530
+ envelope.evidence = {
531
+ status: "unavailable",
532
+ reason: "locator_too_large",
533
+ requiredBytes: envelope.evidence.status === "retained" ? envelope.evidence.bytes : null,
534
+ missingKinds: [...new Set(references.map(ref => ref.kind))],
535
+ warning: EVIDENCE_UNAVAILABLE_WARNING,
536
+ };
537
+ trimSteps(envelope, json);
538
+ while (!fits(envelope, json) && envelope.error.references.length) envelope.error.references.pop();
539
+ }
540
+ includeDiagnostics(envelope, diagnostics, json);
541
+ omitPartialStatusesForBudget(envelope, json);
542
+ const output = serialize(envelope, json);
543
+ return { stdout: json ? output : "", stderr: json ? "" : output, exitCode, envelope };
544
+ }
545
+
546
+ /** Retrieval failures never recursively publish evidence or replay an operation. */
547
+ export function renderPublicEvidenceUnavailable(
548
+ unavailable: { reason: EvidenceUnavailableReason; requiredBytes: number | null },
549
+ options: RenderPublicCommandFailureOptions,
550
+ ): RenderedPublicCommandFailure {
551
+ const { exitCode: _exitCode, ...error } = classifyPublicCommandFailure(
552
+ new PublicCommandFailure({ kind: "operation_failed", proof: "pre-effect" }),
553
+ options.command,
554
+ );
555
+ const envelope: PublicCommandErrorEnvelope = {
556
+ schema: "gjc.command-error",
557
+ version: 1,
558
+ ok: false,
559
+ command: commandPath(options.command),
560
+ error: {
561
+ ...error,
562
+ code: "evidence_unavailable",
563
+ message: "Retained command evidence is unavailable; do not replay the original operation.",
564
+ },
565
+ omittedOptional: [],
566
+ complete: false,
567
+ evidence: {
568
+ status: "unavailable",
569
+ reason: unavailable.reason,
570
+ requiredBytes: unavailable.requiredBytes,
571
+ missingKinds: [],
572
+ warning: EVIDENCE_UNAVAILABLE_WARNING,
573
+ },
574
+ continuation: null,
575
+ };
576
+ const diagnostics = reserveDiagnostics(envelope, options);
577
+ trimSteps(envelope, options.json === true);
578
+ includeDiagnostics(envelope, diagnostics, options.json === true);
579
+ const output = serialize(envelope, options.json === true);
580
+ return { stdout: options.json ? output : "", stderr: options.json ? "" : output, exitCode: 1, envelope };
581
+ }