@gajae-code/coding-agent 0.11.11 → 0.12.1

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 (344) hide show
  1. package/CHANGELOG.md +131 -4
  2. package/dist/types/async/job-manager.d.ts +17 -3
  3. package/dist/types/cli/read-cli.d.ts +1 -0
  4. package/dist/types/commands/deep-interview.d.ts +9 -0
  5. package/dist/types/commands/harness.d.ts +22 -0
  6. package/dist/types/commands/read.d.ts +6 -0
  7. package/dist/types/config/model-registry.d.ts +4 -0
  8. package/dist/types/config/provider-auth-health.d.ts +14 -0
  9. package/dist/types/config/provider-ranking.d.ts +59 -0
  10. package/dist/types/config/settings-schema.d.ts +83 -1
  11. package/dist/types/config/settings.d.ts +2 -0
  12. package/dist/types/exa/mcp-client.d.ts +10 -1
  13. package/dist/types/exec/bash-executor.d.ts +45 -12
  14. package/dist/types/extensibility/extensions/types.d.ts +38 -4
  15. package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
  16. package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
  17. package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
  18. package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
  19. package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
  20. package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
  21. package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
  22. package/dist/types/extensibility/shared-events.d.ts +6 -0
  23. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
  24. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
  25. package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
  26. package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
  27. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  28. package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
  29. package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
  30. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +70 -1
  31. package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
  32. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  33. package/dist/types/gjc-runtime/team-runtime.d.ts +27 -1
  34. package/dist/types/gjc-runtime/team-store.d.ts +12 -0
  35. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
  36. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
  37. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +17 -0
  38. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
  39. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +31 -80
  40. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
  41. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  42. package/dist/types/main.d.ts +1 -1
  43. package/dist/types/memories/index.d.ts +2 -0
  44. package/dist/types/modes/acp/acp-agent.d.ts +10 -19
  45. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  46. package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
  47. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  48. package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
  49. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  50. package/dist/types/modes/components/session-observer-overlay.d.ts +22 -0
  51. package/dist/types/modes/components/settings-selector.d.ts +11 -0
  52. package/dist/types/modes/components/status-line/gh.d.ts +5 -0
  53. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  54. package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
  55. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  56. package/dist/types/modes/interactive-mode.d.ts +2 -0
  57. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  58. package/dist/types/modes/types.d.ts +2 -0
  59. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  60. package/dist/types/reminders/star-reminder.d.ts +3 -13
  61. package/dist/types/runtime-mcp/manager.d.ts +1 -0
  62. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  63. package/dist/types/sdk/acp/adapter.d.ts +3 -1
  64. package/dist/types/sdk/broker/lifecycle.d.ts +5 -0
  65. package/dist/types/sdk/broker/transport.d.ts +2 -0
  66. package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
  67. package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -1
  68. package/dist/types/sdk/bus/config.d.ts +6 -2
  69. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  70. package/dist/types/sdk/bus/index.d.ts +44 -1
  71. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +44 -0
  72. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
  73. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
  74. package/dist/types/sdk/bus/reconciliation-store.d.ts +69 -0
  75. package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
  76. package/dist/types/sdk/bus/rich-render.d.ts +2 -0
  77. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
  78. package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
  79. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +11 -4
  80. package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
  81. package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
  82. package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
  83. package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
  84. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  85. package/dist/types/sdk/host/host.d.ts +2 -0
  86. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  87. package/dist/types/sdk/host/query/revision-store.d.ts +2 -0
  88. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  89. package/dist/types/sdk/prompt-status.d.ts +23 -3
  90. package/dist/types/sdk/session.d.ts +6 -0
  91. package/dist/types/session/agent-session.d.ts +82 -12
  92. package/dist/types/session/artifacts.d.ts +8 -0
  93. package/dist/types/session/blob-store.d.ts +57 -4
  94. package/dist/types/session/internal/managed-session-storage.d.ts +8 -1
  95. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  96. package/dist/types/session/session-manager.d.ts +48 -19
  97. package/dist/types/session/session-storage.d.ts +4 -0
  98. package/dist/types/session/streaming-output.d.ts +96 -12
  99. package/dist/types/setup/credential-import.d.ts +12 -0
  100. package/dist/types/skill-state/active-state.d.ts +12 -4
  101. package/dist/types/skill-state/workflow-hud.d.ts +9 -0
  102. package/dist/types/task/executor.d.ts +3 -2
  103. package/dist/types/task/index.d.ts +3 -1
  104. package/dist/types/task/provider-retry-status.d.ts +8 -0
  105. package/dist/types/task/receipt.d.ts +7 -1
  106. package/dist/types/task/types.d.ts +23 -0
  107. package/dist/types/tools/ask-answer-registry.d.ts +2 -2
  108. package/dist/types/tools/bash-interactive.d.ts +4 -1
  109. package/dist/types/tools/bash.d.ts +3 -1
  110. package/dist/types/tools/browser/launch.d.ts +7 -0
  111. package/dist/types/tools/fetch.d.ts +17 -1
  112. package/dist/types/tools/image-gen.d.ts +4 -0
  113. package/dist/types/tools/index.d.ts +4 -0
  114. package/dist/types/tools/output-meta.d.ts +44 -3
  115. package/dist/types/tools/path-utils.d.ts +1 -0
  116. package/dist/types/tools/read-internals.d.ts +12 -0
  117. package/dist/types/tools/read.d.ts +45 -7
  118. package/dist/types/tools/resource-gc.d.ts +4 -0
  119. package/dist/types/tools/review.d.ts +5 -7
  120. package/dist/types/tools/subagent.d.ts +2 -0
  121. package/dist/types/tools/tool-result.d.ts +7 -1
  122. package/dist/types/utils/gh.d.ts +13 -0
  123. package/dist/types/utils/image-resize.d.ts +1 -0
  124. package/dist/types/web/search/providers/kimi.d.ts +2 -0
  125. package/dist/types/web/search/providers/searxng.d.ts +7 -0
  126. package/dist/types/web/search/providers/xai.d.ts +2 -0
  127. package/package.json +11 -13
  128. package/scripts/acp-conformance-agent.ts +218 -0
  129. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  130. package/scripts/capture-gjc-bundle-settings.ts +306 -0
  131. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  132. package/scripts/generate-sdk-operation-inventory.ts +5 -0
  133. package/scripts/resident-memory-bench.ts +1341 -0
  134. package/scripts/run-acp-conformance.ts +285 -0
  135. package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
  136. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  137. package/src/async/job-manager.ts +78 -20
  138. package/src/capability/index.ts +8 -0
  139. package/src/cli/fast-help.ts +1 -1
  140. package/src/cli/plugin-cli.ts +176 -18
  141. package/src/cli/read-cli.ts +2 -1
  142. package/src/cli.ts +1 -0
  143. package/src/commands/deep-interview.ts +29 -9
  144. package/src/commands/harness.ts +35 -12
  145. package/src/commands/read.ts +11 -2
  146. package/src/commands/team.ts +20 -2
  147. package/src/config/file-lock.ts +11 -2
  148. package/src/config/model-registry.ts +21 -2
  149. package/src/config/provider-auth-health.ts +42 -0
  150. package/src/config/provider-ranking.ts +119 -0
  151. package/src/config/settings-schema.ts +74 -1
  152. package/src/config/settings.ts +246 -108
  153. package/src/coordinator-mcp/question-gate-codec.ts +1 -1
  154. package/src/coordinator-mcp/server.ts +5 -12
  155. package/src/defaults/gjc/skills/deep-interview/SKILL.md +230 -82
  156. package/src/defaults/gjc/skills/ralplan/SKILL.md +77 -41
  157. package/src/defaults/gjc/skills/team/SKILL.md +3 -1
  158. package/src/defaults/gjc/skills/ultragoal/SKILL.md +62 -39
  159. package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
  160. package/src/defaults/gjc-defaults.ts +4 -4
  161. package/src/eval/py/executor.ts +7 -2
  162. package/src/exa/mcp-client.ts +12 -3
  163. package/src/exec/bash-executor.ts +144 -27
  164. package/src/extensibility/extensions/runner.ts +15 -0
  165. package/src/extensibility/extensions/types.ts +46 -5
  166. package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
  167. package/src/extensibility/gjc-plugins/index.ts +19 -2
  168. package/src/extensibility/gjc-plugins/installer.ts +189 -50
  169. package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
  170. package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
  171. package/src/extensibility/gjc-plugins/observability.ts +3 -3
  172. package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
  173. package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
  174. package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
  175. package/src/extensibility/gjc-plugins/schema.ts +84 -12
  176. package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
  177. package/src/extensibility/gjc-plugins/types.ts +141 -0
  178. package/src/extensibility/gjc-plugins/validation.ts +9 -0
  179. package/src/extensibility/shared-events.ts +5 -0
  180. package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -82
  181. package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
  182. package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
  183. package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
  184. package/src/gjc-runtime/deep-interview-state.ts +12 -943
  185. package/src/gjc-runtime/gc-render.ts +1 -0
  186. package/src/gjc-runtime/gc-runtime.ts +11 -1
  187. package/src/gjc-runtime/launch-tmux.ts +25 -6
  188. package/src/gjc-runtime/managed-owner-admission.ts +1 -1
  189. package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
  190. package/src/gjc-runtime/ralplan-runtime.ts +1149 -98
  191. package/src/gjc-runtime/state-runtime.ts +2 -1
  192. package/src/gjc-runtime/state-writer.ts +70 -222
  193. package/src/gjc-runtime/team-launch.ts +42 -5
  194. package/src/gjc-runtime/team-runtime.ts +1085 -40
  195. package/src/gjc-runtime/team-store.ts +32 -0
  196. package/src/gjc-runtime/team-worker-heartbeat.ts +149 -0
  197. package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
  198. package/src/gjc-runtime/team-workers.ts +1 -0
  199. package/src/gjc-runtime/tmux-owner-isolation.ts +28 -0
  200. package/src/gjc-runtime/tmux-sessions.ts +58 -13
  201. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
  202. package/src/gjc-runtime/ultragoal-runtime.ts +414 -618
  203. package/src/gjc-runtime/workflow-manifest.generated.json +105 -449
  204. package/src/gjc-runtime/workflow-manifest.ts +38 -247
  205. package/src/hooks/native-skill-hook.ts +17 -4
  206. package/src/hooks/skill-state.ts +1 -23
  207. package/src/internal-urls/docs-index.generated.ts +21 -22
  208. package/src/internal-urls/local-root-gc.ts +127 -0
  209. package/src/main.ts +9 -5
  210. package/src/memories/index.ts +10 -0
  211. package/src/modes/DESIGN.md +98 -0
  212. package/src/modes/acp/acp-agent.ts +339 -191
  213. package/src/modes/acp/acp-event-mapper.ts +14 -7
  214. package/src/modes/acp/acp-mode.ts +39 -3
  215. package/src/modes/components/assistant-message.ts +123 -22
  216. package/src/modes/components/gjc-bundle-settings.ts +508 -0
  217. package/src/modes/components/irc-sidebar.ts +176 -62
  218. package/src/modes/components/model-selector.ts +61 -4
  219. package/src/modes/components/notifications-settings-editor.ts +12 -1
  220. package/src/modes/components/oauth-selector.ts +96 -28
  221. package/src/modes/components/read-tool-group.ts +82 -14
  222. package/src/modes/components/session-observer-overlay.ts +457 -83
  223. package/src/modes/components/settings-selector.ts +116 -23
  224. package/src/modes/components/status-line/gh.ts +16 -0
  225. package/src/modes/components/tool-execution.ts +138 -27
  226. package/src/modes/components/tool-status-header.ts +3 -14
  227. package/src/modes/components/transcript-viewer-overlay.ts +99 -24
  228. package/src/modes/controllers/command-controller.ts +4 -0
  229. package/src/modes/controllers/event-controller.ts +109 -27
  230. package/src/modes/controllers/extension-ui-controller.ts +26 -2
  231. package/src/modes/controllers/input-controller.ts +18 -3
  232. package/src/modes/controllers/selector-controller.ts +127 -36
  233. package/src/modes/interactive-mode.ts +62 -3
  234. package/src/modes/irc-observation-ledger.ts +71 -15
  235. package/src/modes/runtime-init.ts +22 -2
  236. package/src/modes/types.ts +2 -0
  237. package/src/modes/utils/ui-helpers.ts +94 -1
  238. package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
  239. package/src/prompts/agents/architect.md +9 -1
  240. package/src/prompts/agents/critic.md +9 -0
  241. package/src/prompts/system/eager-todo.md +8 -4
  242. package/src/prompts/system/system-prompt.md +11 -5
  243. package/src/prompts/tools/bash.md +5 -5
  244. package/src/prompts/tools/read.md +4 -2
  245. package/src/prompts/tools/search-tool-bm25.md +5 -0
  246. package/src/prompts/tools/task.md +1 -1
  247. package/src/reminders/star-reminder.ts +4 -42
  248. package/src/runtime-mcp/manager.ts +19 -4
  249. package/src/runtime-mcp/smithery-auth.ts +17 -2
  250. package/src/runtime-mcp/smithery-connect.ts +11 -1
  251. package/src/sdk/acp/adapter.ts +22 -6
  252. package/src/sdk/broker/lifecycle.ts +25 -6
  253. package/src/sdk/broker/transport.ts +35 -3
  254. package/src/sdk/bus/attachment-registry.ts +5 -1
  255. package/src/sdk/bus/chat-daemon-cli.ts +4 -39
  256. package/src/sdk/bus/chat-daemon-control.ts +6 -3
  257. package/src/sdk/bus/config.ts +18 -2
  258. package/src/sdk/bus/control-drain-lease.ts +104 -0
  259. package/src/sdk/bus/index.ts +984 -146
  260. package/src/sdk/bus/kind-aware-reconciliation.ts +317 -0
  261. package/src/sdk/bus/lifecycle-commands.ts +4 -1
  262. package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
  263. package/src/sdk/bus/prompt-reconciliation.ts +2 -1
  264. package/src/sdk/bus/reconciliation-store.ts +303 -0
  265. package/src/sdk/bus/rich-draft.ts +1 -1
  266. package/src/sdk/bus/rich-render.ts +2 -2
  267. package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
  268. package/src/sdk/bus/telegram-cli.ts +33 -8
  269. package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
  270. package/src/sdk/bus/telegram-daemon-contract.ts +11 -4
  271. package/src/sdk/bus/telegram-daemon.ts +916 -23
  272. package/src/sdk/bus/telegram-reference.ts +40 -3
  273. package/src/sdk/bus/threaded-render.ts +48 -3
  274. package/src/sdk/bus/topic-registry.ts +20 -0
  275. package/src/sdk/host/control/dispatch.ts +5 -1
  276. package/src/sdk/host/control/operations.ts +1 -1
  277. package/src/sdk/host/host.ts +23 -1
  278. package/src/sdk/host/query/handlers.ts +55 -0
  279. package/src/sdk/host/query/revision-store.ts +36 -2
  280. package/src/sdk/host/reverse-leases.ts +44 -7
  281. package/src/sdk/mcp/server.ts +46 -18
  282. package/src/sdk/prompt-status.ts +16 -3
  283. package/src/sdk/protocol/operation-inventory.generated.json +51 -0
  284. package/src/sdk/protocol/operation-registry.ts +7 -2
  285. package/src/sdk/session.ts +101 -10
  286. package/src/session/agent-session.ts +1286 -220
  287. package/src/session/artifacts.ts +22 -0
  288. package/src/session/auth-broker-config.ts +10 -3
  289. package/src/session/blob-store.ts +915 -24
  290. package/src/session/internal/managed-session-scope.ts +44 -6
  291. package/src/session/internal/managed-session-storage.ts +48 -6
  292. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  293. package/src/session/session-manager.ts +2364 -438
  294. package/src/session/session-storage.ts +9 -1
  295. package/src/session/streaming-output.ts +500 -111
  296. package/src/setup/credential-import.ts +75 -13
  297. package/src/setup/provider-onboarding.ts +19 -4
  298. package/src/skill-state/active-state.ts +32 -10
  299. package/src/skill-state/workflow-hud.ts +42 -2
  300. package/src/skill-state/workflow-mutation-guard.ts +560 -8
  301. package/src/task/executor.ts +122 -39
  302. package/src/task/index.ts +23 -14
  303. package/src/task/provider-retry-status.ts +16 -0
  304. package/src/task/receipt.ts +23 -7
  305. package/src/task/render.ts +6 -2
  306. package/src/task/types.ts +108 -0
  307. package/src/tools/ask-answer-registry.ts +12 -6
  308. package/src/tools/ask.ts +169 -118
  309. package/src/tools/ast-edit.ts +1 -0
  310. package/src/tools/ast-grep.ts +1 -0
  311. package/src/tools/bash-interactive.ts +8 -3
  312. package/src/tools/bash.ts +503 -60
  313. package/src/tools/browser/launch.ts +41 -6
  314. package/src/tools/fetch.ts +114 -23
  315. package/src/tools/find.ts +1 -0
  316. package/src/tools/image-gen.ts +29 -5
  317. package/src/tools/index.ts +4 -0
  318. package/src/tools/output-meta.ts +281 -20
  319. package/src/tools/path-utils.ts +8 -3
  320. package/src/tools/read-internals.ts +44 -0
  321. package/src/tools/read.ts +1560 -310
  322. package/src/tools/resource-gc.ts +182 -18
  323. package/src/tools/review.ts +5 -7
  324. package/src/tools/search.ts +1 -0
  325. package/src/tools/subagent-render.ts +6 -2
  326. package/src/tools/subagent.ts +6 -0
  327. package/src/tools/telegram-send.ts +6 -3
  328. package/src/tools/tool-result.ts +14 -1
  329. package/src/utils/gh.ts +39 -0
  330. package/src/utils/image-resize.ts +3 -0
  331. package/src/web/search/providers/anthropic.ts +4 -4
  332. package/src/web/search/providers/codex.ts +1 -1
  333. package/src/web/search/providers/kimi.ts +15 -5
  334. package/src/web/search/providers/searxng.ts +47 -4
  335. package/src/web/search/providers/xai.ts +7 -2
  336. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
  337. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
  338. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
  339. package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
  340. package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
  341. package/src/gjc-runtime/deep-interview-draft.ts +0 -843
  342. package/src/gjc-runtime/deep-interview-payload.ts +0 -262
  343. package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
  344. package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Kind-aware invocation reconciliation (prompt | skill) with optional durable store.
3
+ * Preserves Q26 admit/first-terminal/capacity/TTL semantics; indexes and caps are per-kind.
4
+ */
5
+ import type { PromptReconciliationStatus, SdkPromptTerminalOutcome, TurnPromptReconciliation } from "../prompt-status";
6
+ import {
7
+ PROMPT_RECONCILIATION_ACTIVE_CAPACITY,
8
+ PROMPT_RECONCILIATION_TERMINAL_CAPACITY,
9
+ PROMPT_RECONCILIATION_TERMINAL_TTL_MS,
10
+ type PromptCorrelation,
11
+ sanitizePromptFailure,
12
+ } from "./prompt-reconciliation";
13
+ import type { DurableReconciliationRecord, ReconciliationKind, ReconciliationStore } from "./reconciliation-store";
14
+
15
+ export type { ReconciliationKind };
16
+
17
+ export interface KindCorrelation extends PromptCorrelation {
18
+ kind: ReconciliationKind;
19
+ }
20
+
21
+ export interface KindAwareReconciliation {
22
+ admit(kind: ReconciliationKind, clientRef?: string): void;
23
+ releaseAdmission(kind: ReconciliationKind, clientRef?: string): void;
24
+ noteAccepted(
25
+ kind: ReconciliationKind,
26
+ correlation: PromptCorrelation,
27
+ clientRef?: string,
28
+ extra?: { skillName?: string },
29
+ ): Promise<void>;
30
+ noteTransition(
31
+ kind: ReconciliationKind,
32
+ correlation: PromptCorrelation | undefined,
33
+ frame: { type: "agent_start" | "agent_end" } | { type: "agent_failed"; error: unknown },
34
+ ): Promise<void>;
35
+ claimPendingOutcome(
36
+ correlation: PromptCorrelation,
37
+ outcome: SdkPromptTerminalOutcome,
38
+ ): Promise<SdkPromptTerminalOutcome>;
39
+ finalizePromptOutcome(
40
+ correlation: PromptCorrelation,
41
+ outcome?: SdkPromptTerminalOutcome,
42
+ recordError?: { code: string; message: string },
43
+ ): Promise<void>;
44
+ peekPendingOutcome(correlation: PromptCorrelation): SdkPromptTerminalOutcome | undefined;
45
+ lookup(
46
+ kind: ReconciliationKind,
47
+ selector: { commandId?: string; turnId?: string; clientRef?: string },
48
+ ): TurnPromptReconciliation;
49
+ cleanup(): void;
50
+ activeCount(kind: ReconciliationKind): number;
51
+ /** Hydrate from durable store (call once at session host start). */
52
+ hydrateFromStore(): Promise<void>;
53
+ }
54
+
55
+ export function createKindAwareReconciliation(
56
+ options: { now?: () => number; store?: ReconciliationStore | null } = {},
57
+ ): KindAwareReconciliation {
58
+ const now = options.now ?? Date.now;
59
+ const store = options.store ?? null;
60
+ let records = new Map<string, DurableReconciliationRecord>();
61
+ let clientRefIndex = new Map<string, string>();
62
+ const reservedClientRefs = new Map<ReconciliationKind, Set<string>>();
63
+ const reservations: Array<{ kind: ReconciliationKind; clientRef?: string }> = [];
64
+ let mutationChain: Promise<void> = Promise.resolve();
65
+
66
+ const keyOf = (kind: ReconciliationKind, correlation: PromptCorrelation) =>
67
+ `${kind}:${correlation.commandId}:${correlation.turnId}`;
68
+ const refKey = (kind: ReconciliationKind, clientRef: string) => `${kind}\0${clientRef}`;
69
+
70
+ const indexRecords = (source: Map<string, DurableReconciliationRecord>) => {
71
+ const index = new Map<string, string>();
72
+ for (const [key, record] of source)
73
+ if (record.clientRef !== undefined) index.set(refKey(record.kind, record.clientRef), key);
74
+ return index;
75
+ };
76
+
77
+ const cleanupRecords = (source: Map<string, DurableReconciliationRecord>) => {
78
+ const at = now();
79
+ for (const [key, record] of source)
80
+ if (record.terminalAt !== undefined && record.terminalAt + PROMPT_RECONCILIATION_TERMINAL_TTL_MS <= at)
81
+ source.delete(key);
82
+ for (const kind of ["prompt", "skill"] as const) {
83
+ const terminalEntries = [...source.entries()].filter(
84
+ ([, record]) => record.kind === kind && record.terminalAt !== undefined,
85
+ );
86
+ if (terminalEntries.length <= PROMPT_RECONCILIATION_TERMINAL_CAPACITY) continue;
87
+ terminalEntries.sort((a, b) => (a[1].terminalAt as number) - (b[1].terminalAt as number));
88
+ for (const [key] of terminalEntries.slice(0, terminalEntries.length - PROMPT_RECONCILIATION_TERMINAL_CAPACITY))
89
+ source.delete(key);
90
+ }
91
+ };
92
+
93
+ const queueMutation = async <T>(
94
+ mutate: (candidate: Map<string, DurableReconciliationRecord>) => { value: T; changed: boolean },
95
+ ): Promise<T> => {
96
+ const run = async () => {
97
+ const candidate = new Map([...records].map(([key, record]) => [key, { ...record }]));
98
+ const result = mutate(candidate);
99
+ if (!result.changed) return result.value;
100
+ const candidateIndex = indexRecords(candidate);
101
+ if (store) await store.transact(() => [...candidate.values()].map(record => ({ ...record })));
102
+ records = candidate;
103
+ clientRefIndex = candidateIndex;
104
+ return result.value;
105
+ };
106
+ const pending = mutationChain.then(run, run);
107
+ mutationChain = pending.then(
108
+ () => undefined,
109
+ () => undefined,
110
+ );
111
+ return await pending;
112
+ };
113
+
114
+ const reservedFor = (kind: ReconciliationKind) => {
115
+ let set = reservedClientRefs.get(kind);
116
+ if (!set) {
117
+ set = new Set();
118
+ reservedClientRefs.set(kind, set);
119
+ }
120
+ return set;
121
+ };
122
+
123
+ const cleanup = () => {
124
+ cleanupRecords(records);
125
+ clientRefIndex = indexRecords(records);
126
+ };
127
+
128
+ const activeCount = (kind: ReconciliationKind) => {
129
+ let count = 0;
130
+ for (const record of records.values()) if (record.kind === kind && record.terminalAt === undefined) count++;
131
+ return count;
132
+ };
133
+
134
+ const reservationCount = (kind: ReconciliationKind) => reservations.filter(record => record.kind === kind).length;
135
+
136
+ const consumeReservation = (kind: ReconciliationKind, clientRef?: string) => {
137
+ const index = reservations.findIndex(record => record.kind === kind && record.clientRef === clientRef);
138
+ if (index === -1) return;
139
+ reservations.splice(index, 1);
140
+ if (
141
+ clientRef !== undefined &&
142
+ !reservations.some(record => record.kind === kind && record.clientRef === clientRef)
143
+ )
144
+ reservedFor(kind).delete(clientRef);
145
+ };
146
+
147
+ const admit = (kind: ReconciliationKind, clientRef?: string) => {
148
+ cleanup();
149
+ const reserved = reservedFor(kind);
150
+ if (clientRef !== undefined && (clientRefIndex.has(refKey(kind, clientRef)) || reserved.has(clientRef)))
151
+ throw Object.assign(
152
+ new Error("A submission with this clientRef is already retained; never reuse a clientRef for retry."),
153
+ { code: "client_ref_conflict" },
154
+ );
155
+ if (activeCount(kind) + reservationCount(kind) >= PROMPT_RECONCILIATION_ACTIVE_CAPACITY)
156
+ throw Object.assign(new Error("Too many active submissions; reconcile or await terminal state."), {
157
+ code: "reconciliation_capacity",
158
+ });
159
+ reservations.push({ kind, clientRef });
160
+ if (clientRef !== undefined) reserved.add(clientRef);
161
+ };
162
+
163
+ const releaseAdmission = (kind: ReconciliationKind, clientRef?: string) => {
164
+ consumeReservation(kind, clientRef);
165
+ };
166
+
167
+ const noteAccepted = async (
168
+ kind: ReconciliationKind,
169
+ correlation: PromptCorrelation,
170
+ clientRef?: string,
171
+ extra?: { skillName?: string },
172
+ ) => {
173
+ await queueMutation(candidate => {
174
+ cleanupRecords(candidate);
175
+ candidate.set(keyOf(kind, correlation), {
176
+ kind,
177
+ commandId: correlation.commandId,
178
+ turnId: correlation.turnId,
179
+ ...(clientRef !== undefined ? { clientRef } : {}),
180
+ status: "accepted",
181
+ acceptedAt: now(),
182
+ ...(extra?.skillName ? { skillName: extra.skillName } : {}),
183
+ });
184
+ return { value: undefined, changed: true };
185
+ });
186
+ consumeReservation(kind, clientRef);
187
+ };
188
+
189
+ const noteTransition = async (
190
+ kind: ReconciliationKind,
191
+ correlation: PromptCorrelation | undefined,
192
+ frame: { type: "agent_start" | "agent_end" } | { type: "agent_failed"; error: unknown },
193
+ ) => {
194
+ if (!correlation) return;
195
+ await queueMutation(candidate => {
196
+ const record = candidate.get(keyOf(kind, correlation));
197
+ if (!record || record.terminalAt !== undefined) return { value: undefined, changed: false };
198
+ if (frame.type === "agent_start") {
199
+ if (record.status !== "accepted") return { value: undefined, changed: false };
200
+ record.status = "in_flight";
201
+ record.startedAt = now();
202
+ return { value: undefined, changed: true };
203
+ }
204
+ record.terminalAt = now();
205
+ if (frame.type === "agent_failed") {
206
+ record.status = "failed";
207
+ record.error = sanitizePromptFailure(frame.error);
208
+ } else record.status = "terminal_ok";
209
+ cleanupRecords(candidate);
210
+ return { value: undefined, changed: true };
211
+ });
212
+ };
213
+
214
+ const claimPendingOutcome = async (
215
+ correlation: PromptCorrelation,
216
+ outcome: SdkPromptTerminalOutcome,
217
+ ): Promise<SdkPromptTerminalOutcome> =>
218
+ await queueMutation(candidate => {
219
+ const record = candidate.get(keyOf("prompt", correlation));
220
+ if (!record || record.terminalAt !== undefined || record.kind !== "prompt")
221
+ return { value: outcome, changed: false };
222
+ if (record.pendingOutcome !== undefined) return { value: record.pendingOutcome, changed: false };
223
+ record.pendingOutcome = outcome;
224
+ return { value: outcome, changed: true };
225
+ });
226
+
227
+ const finalizePromptOutcome = async (
228
+ correlation: PromptCorrelation,
229
+ outcome?: SdkPromptTerminalOutcome,
230
+ recordError?: { code: string; message: string },
231
+ ) => {
232
+ await queueMutation(candidate => {
233
+ const record = candidate.get(keyOf("prompt", correlation));
234
+ if (!record || record.terminalAt !== undefined || record.kind !== "prompt")
235
+ return { value: undefined, changed: false };
236
+ const finalOutcome = outcome ?? record.pendingOutcome;
237
+ record.terminalAt = now();
238
+ if (finalOutcome?.kind === "failed") {
239
+ record.status = "failed";
240
+ record.error = recordError ?? { code: finalOutcome.code, message: finalOutcome.message };
241
+ } else record.status = "terminal_ok";
242
+ record.outcome = finalOutcome;
243
+ record.pendingOutcome = undefined;
244
+ cleanupRecords(candidate);
245
+ return { value: undefined, changed: true };
246
+ });
247
+ };
248
+
249
+ const peekPendingOutcome = (correlation: PromptCorrelation) =>
250
+ records.get(keyOf("prompt", correlation))?.pendingOutcome;
251
+
252
+ const lookup = (
253
+ kind: ReconciliationKind,
254
+ selector: { commandId?: string; turnId?: string; clientRef?: string },
255
+ ): TurnPromptReconciliation => {
256
+ cleanup();
257
+ const key =
258
+ selector.clientRef !== undefined
259
+ ? clientRefIndex.get(refKey(kind, selector.clientRef))
260
+ : selector.commandId !== undefined && selector.turnId !== undefined
261
+ ? keyOf(kind, { commandId: selector.commandId, turnId: selector.turnId })
262
+ : undefined;
263
+ const record = key === undefined ? undefined : records.get(key);
264
+ if (!record) return { status: "unknown" };
265
+ const identity = {
266
+ commandId: record.commandId,
267
+ turnId: record.turnId,
268
+ ...(record.clientRef !== undefined ? { clientRef: record.clientRef } : {}),
269
+ acceptedAt: record.acceptedAt,
270
+ };
271
+ if (record.status === "accepted") return { status: "accepted", ...identity };
272
+ if (record.status === "in_flight")
273
+ return { status: "in_flight", ...identity, startedAt: record.startedAt as number };
274
+ const terminal = {
275
+ ...identity,
276
+ ...(record.startedAt !== undefined ? { startedAt: record.startedAt } : {}),
277
+ terminalAt: record.terminalAt as number,
278
+ ...(record.outcome !== undefined ? { outcome: record.outcome } : {}),
279
+ };
280
+ if (record.status === "terminal_ok") return { status: "terminal_ok", ...terminal };
281
+ return { status: "failed", ...terminal, error: record.error ?? sanitizePromptFailure(undefined) };
282
+ };
283
+
284
+ const hydrateFromStore = async () => {
285
+ if (!store) return;
286
+ const run = async () => {
287
+ const loaded = await store.load();
288
+ const candidate = new Map(loaded.map(record => [keyOf(record.kind, record), { ...record }] as const));
289
+ const candidateIndex = indexRecords(candidate);
290
+ await store.transact(() => [...candidate.values()].map(record => ({ ...record })));
291
+ records = candidate;
292
+ clientRefIndex = candidateIndex;
293
+ };
294
+ const pending = mutationChain.then(run, run);
295
+ mutationChain = pending.then(
296
+ () => undefined,
297
+ () => undefined,
298
+ );
299
+ await pending;
300
+ };
301
+
302
+ return {
303
+ admit,
304
+ releaseAdmission,
305
+ noteAccepted,
306
+ noteTransition,
307
+ claimPendingOutcome,
308
+ finalizePromptOutcome,
309
+ peekPendingOutcome,
310
+ lookup,
311
+ cleanup,
312
+ activeCount,
313
+ hydrateFromStore,
314
+ };
315
+ }
316
+
317
+ export type { PromptReconciliationStatus };
@@ -270,7 +270,10 @@ function isSafePath(value: string): boolean {
270
270
  // relative are both allowed (full-trust chat), but not injection shapes.
271
271
  if (value.length === 0 || value.length > 4096) return false;
272
272
  if (/[\n\r\0]/.test(value)) return false;
273
- return !/[;&|`$(){}<>*?!\\"']/.test(value);
273
+ // Backslash is a shell escape on POSIX but the native path separator on
274
+ // Windows; allow it there so absolute Windows paths validate correctly.
275
+ const metachars = process.platform === "win32" ? /[;&|`$(){}<>*?!"']/ : /[;&|`$(){}<>*?!\\"']/;
276
+ return !metachars.test(value);
274
277
  }
275
278
 
276
279
  function isSafeBranch(value: string): boolean {