@orion-agents/orion-code 0.1.9 → 0.2.2

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 (757) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +142 -323
  3. package/README.zh-CN.md +118 -578
  4. package/dist/cli.js +65 -84
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/context-commands.d.ts.map +1 -1
  7. package/dist/commands/context-commands.js +14 -7
  8. package/dist/commands/context-commands.js.map +1 -1
  9. package/dist/commands/context-tool-command-handlers.d.ts +4 -5
  10. package/dist/commands/context-tool-command-handlers.d.ts.map +1 -1
  11. package/dist/commands/context-tool-command-handlers.js +132 -208
  12. package/dist/commands/context-tool-command-handlers.js.map +1 -1
  13. package/dist/commands/core-command-handlers.d.ts +3 -6
  14. package/dist/commands/core-command-handlers.d.ts.map +1 -1
  15. package/dist/commands/core-command-handlers.js +66 -664
  16. package/dist/commands/core-command-handlers.js.map +1 -1
  17. package/dist/commands/diagnostic-command-handlers.d.ts +1 -2
  18. package/dist/commands/diagnostic-command-handlers.d.ts.map +1 -1
  19. package/dist/commands/diagnostic-command-handlers.js +3 -17
  20. package/dist/commands/diagnostic-command-handlers.js.map +1 -1
  21. package/dist/commands/diagnostic-commands.d.ts.map +1 -1
  22. package/dist/commands/diagnostic-commands.js +0 -45
  23. package/dist/commands/diagnostic-commands.js.map +1 -1
  24. package/dist/commands/index.d.ts +1 -1
  25. package/dist/commands/index.d.ts.map +1 -1
  26. package/dist/commands/index.js +2 -7
  27. package/dist/commands/index.js.map +1 -1
  28. package/dist/commands/model-command-handlers.d.ts +1 -1
  29. package/dist/commands/model-command-handlers.js +2 -2
  30. package/dist/commands/model-command-handlers.js.map +1 -1
  31. package/dist/commands/model-commands.d.ts.map +1 -1
  32. package/dist/commands/model-commands.js +0 -11
  33. package/dist/commands/model-commands.js.map +1 -1
  34. package/dist/commands/registry.d.ts.map +1 -1
  35. package/dist/commands/registry.js +1 -139
  36. package/dist/commands/registry.js.map +1 -1
  37. package/dist/commands/session-command-handlers.d.ts +1 -1
  38. package/dist/commands/session-command-handlers.d.ts.map +1 -1
  39. package/dist/commands/session-command-handlers.js +52 -214
  40. package/dist/commands/session-command-handlers.js.map +1 -1
  41. package/dist/commands/session-commands.d.ts.map +1 -1
  42. package/dist/commands/session-commands.js +0 -48
  43. package/dist/commands/session-commands.js.map +1 -1
  44. package/dist/commands/target-command.d.ts +9 -15
  45. package/dist/commands/target-command.d.ts.map +1 -1
  46. package/dist/commands/target-command.js +16 -130
  47. package/dist/commands/target-command.js.map +1 -1
  48. package/dist/commands/tool-commands.d.ts.map +1 -1
  49. package/dist/commands/tool-commands.js +0 -10
  50. package/dist/commands/tool-commands.js.map +1 -1
  51. package/dist/commands/types.d.ts +10 -14
  52. package/dist/commands/types.d.ts.map +1 -1
  53. package/dist/commands/types.js +1 -1
  54. package/dist/commands/types.js.map +1 -1
  55. package/dist/commands/workflow-command-handlers.d.ts.map +1 -1
  56. package/dist/commands/workflow-command-handlers.js +1 -3
  57. package/dist/commands/workflow-command-handlers.js.map +1 -1
  58. package/dist/commands/workflow-commands.d.ts.map +1 -1
  59. package/dist/commands/workflow-commands.js +2 -24
  60. package/dist/commands/workflow-commands.js.map +1 -1
  61. package/dist/framework/agent-mode.d.ts +2 -3
  62. package/dist/framework/agent-mode.d.ts.map +1 -1
  63. package/dist/framework/agent-mode.js +8 -31
  64. package/dist/framework/agent-mode.js.map +1 -1
  65. package/dist/framework/index.d.ts +3 -3
  66. package/dist/framework/index.d.ts.map +1 -1
  67. package/dist/framework/index.js +6 -9
  68. package/dist/framework/index.js.map +1 -1
  69. package/dist/framework/loop-budget-contract.d.ts +20 -0
  70. package/dist/framework/loop-budget-contract.d.ts.map +1 -0
  71. package/dist/framework/loop-budget-contract.js +13 -0
  72. package/dist/framework/loop-budget-contract.js.map +1 -0
  73. package/dist/framework/prompt.d.ts.map +1 -1
  74. package/dist/framework/prompt.js +5 -4
  75. package/dist/framework/prompt.js.map +1 -1
  76. package/dist/framework/query.d.ts +45 -22
  77. package/dist/framework/query.d.ts.map +1 -1
  78. package/dist/framework/query.js +64 -52
  79. package/dist/framework/query.js.map +1 -1
  80. package/dist/framework/store.d.ts +4 -2
  81. package/dist/framework/store.d.ts.map +1 -1
  82. package/dist/framework/store.js +1 -0
  83. package/dist/framework/store.js.map +1 -1
  84. package/dist/framework/tool-call-orchestrator.d.ts +80 -0
  85. package/dist/framework/tool-call-orchestrator.d.ts.map +1 -0
  86. package/dist/framework/tool-call-orchestrator.js +192 -0
  87. package/dist/framework/tool-call-orchestrator.js.map +1 -0
  88. package/dist/framework/tool-state.d.ts +12 -11
  89. package/dist/framework/tool-state.d.ts.map +1 -1
  90. package/dist/framework/tool-state.js +36 -28
  91. package/dist/framework/tool-state.js.map +1 -1
  92. package/dist/framework/tool.d.ts +0 -9
  93. package/dist/framework/tool.d.ts.map +1 -1
  94. package/dist/framework/tool.js.map +1 -1
  95. package/dist/index.d.ts +70 -26
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +64 -65
  98. package/dist/index.js.map +1 -1
  99. package/dist/print-ui/launch.d.ts.map +1 -1
  100. package/dist/print-ui/launch.js +9 -2
  101. package/dist/print-ui/launch.js.map +1 -1
  102. package/dist/product/paths.d.ts +7 -0
  103. package/dist/product/paths.d.ts.map +1 -1
  104. package/dist/product/paths.js +19 -0
  105. package/dist/product/paths.js.map +1 -1
  106. package/dist/runtime/agent-loop.d.ts +80 -0
  107. package/dist/runtime/agent-loop.d.ts.map +1 -0
  108. package/dist/runtime/agent-loop.js +419 -0
  109. package/dist/runtime/agent-loop.js.map +1 -0
  110. package/dist/runtime/agent-runtime-controller.d.ts +10 -57
  111. package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
  112. package/dist/runtime/agent-runtime-controller.js +270 -1216
  113. package/dist/runtime/agent-runtime-controller.js.map +1 -1
  114. package/dist/runtime/agent-runtime-protocol.d.ts +4 -5
  115. package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
  116. package/dist/runtime/agent-runtime-protocol.js.map +1 -1
  117. package/dist/runtime/agent-runtime-runner.d.ts +36 -0
  118. package/dist/runtime/agent-runtime-runner.d.ts.map +1 -0
  119. package/dist/runtime/agent-runtime-runner.js +3 -0
  120. package/dist/runtime/agent-runtime-runner.js.map +1 -0
  121. package/dist/runtime/batch-read-service.d.ts +29 -0
  122. package/dist/runtime/batch-read-service.d.ts.map +1 -0
  123. package/dist/runtime/batch-read-service.js +212 -0
  124. package/dist/runtime/batch-read-service.js.map +1 -0
  125. package/dist/runtime/builtin-tool-provider.d.ts +30 -0
  126. package/dist/runtime/builtin-tool-provider.d.ts.map +1 -0
  127. package/dist/runtime/builtin-tool-provider.js +233 -0
  128. package/dist/runtime/builtin-tool-provider.js.map +1 -0
  129. package/dist/runtime/capabilities/compiler.d.ts +11 -0
  130. package/dist/runtime/capabilities/compiler.d.ts.map +1 -0
  131. package/dist/runtime/capabilities/compiler.js +719 -0
  132. package/dist/runtime/capabilities/compiler.js.map +1 -0
  133. package/dist/runtime/capabilities/index.d.ts +3 -0
  134. package/dist/runtime/capabilities/index.d.ts.map +1 -0
  135. package/dist/runtime/capabilities/index.js +9 -0
  136. package/dist/runtime/capabilities/index.js.map +1 -0
  137. package/dist/runtime/capabilities/types.d.ts +175 -0
  138. package/dist/runtime/capabilities/types.d.ts.map +1 -0
  139. package/dist/runtime/capabilities/types.js +3 -0
  140. package/dist/runtime/capabilities/types.js.map +1 -0
  141. package/dist/runtime/capability-receipt-journal.d.ts +29 -0
  142. package/dist/runtime/capability-receipt-journal.d.ts.map +1 -0
  143. package/dist/runtime/capability-receipt-journal.js +264 -0
  144. package/dist/runtime/capability-receipt-journal.js.map +1 -0
  145. package/dist/runtime/capability-step-factory.d.ts +73 -0
  146. package/dist/runtime/capability-step-factory.d.ts.map +1 -0
  147. package/dist/runtime/capability-step-factory.js +302 -0
  148. package/dist/runtime/capability-step-factory.js.map +1 -0
  149. package/dist/runtime/compact-transaction.d.ts +225 -0
  150. package/dist/runtime/compact-transaction.d.ts.map +1 -0
  151. package/dist/runtime/compact-transaction.js +622 -0
  152. package/dist/runtime/compact-transaction.js.map +1 -0
  153. package/dist/runtime/composer/buffer.d.ts +3 -4
  154. package/dist/runtime/composer/buffer.d.ts.map +1 -1
  155. package/dist/runtime/composer/buffer.js +3 -4
  156. package/dist/runtime/composer/buffer.js.map +1 -1
  157. package/dist/runtime/composer/grapheme.d.ts +2 -4
  158. package/dist/runtime/composer/grapheme.d.ts.map +1 -1
  159. package/dist/runtime/composer/grapheme.js +2 -4
  160. package/dist/runtime/composer/grapheme.js.map +1 -1
  161. package/dist/runtime/composer/layout.d.ts +1 -3
  162. package/dist/runtime/composer/layout.d.ts.map +1 -1
  163. package/dist/runtime/composer/layout.js +1 -3
  164. package/dist/runtime/composer/layout.js.map +1 -1
  165. package/dist/runtime/core-tools/descriptors.d.ts +17 -0
  166. package/dist/runtime/core-tools/descriptors.d.ts.map +1 -0
  167. package/dist/runtime/core-tools/descriptors.js +185 -0
  168. package/dist/runtime/core-tools/descriptors.js.map +1 -0
  169. package/dist/runtime/first-party-core-provider.d.ts +55 -0
  170. package/dist/runtime/first-party-core-provider.d.ts.map +1 -0
  171. package/dist/runtime/first-party-core-provider.js +197 -0
  172. package/dist/runtime/first-party-core-provider.js.map +1 -0
  173. package/dist/runtime/first-party-long-tail-provider.d.ts +57 -0
  174. package/dist/runtime/first-party-long-tail-provider.d.ts.map +1 -0
  175. package/dist/runtime/first-party-long-tail-provider.js +238 -0
  176. package/dist/runtime/first-party-long-tail-provider.js.map +1 -0
  177. package/dist/runtime/first-party-tool-services.d.ts +43 -0
  178. package/dist/runtime/first-party-tool-services.d.ts.map +1 -0
  179. package/dist/runtime/first-party-tool-services.js +200 -0
  180. package/dist/runtime/first-party-tool-services.js.map +1 -0
  181. package/dist/runtime/first-party-tool-universe.d.ts +14 -0
  182. package/dist/runtime/first-party-tool-universe.d.ts.map +1 -0
  183. package/dist/runtime/first-party-tool-universe.js +20 -0
  184. package/dist/runtime/first-party-tool-universe.js.map +1 -0
  185. package/dist/runtime/goal-lifecycle-v2.d.ts +63 -0
  186. package/dist/runtime/goal-lifecycle-v2.d.ts.map +1 -0
  187. package/dist/runtime/goal-lifecycle-v2.js +253 -0
  188. package/dist/runtime/goal-lifecycle-v2.js.map +1 -0
  189. package/dist/runtime/goal-runtime-coordinator.d.ts +111 -0
  190. package/dist/runtime/goal-runtime-coordinator.d.ts.map +1 -0
  191. package/dist/runtime/goal-runtime-coordinator.js +511 -0
  192. package/dist/runtime/goal-runtime-coordinator.js.map +1 -0
  193. package/dist/runtime/harness-confluence.d.ts +165 -0
  194. package/dist/runtime/harness-confluence.d.ts.map +1 -0
  195. package/dist/runtime/harness-confluence.js +807 -0
  196. package/dist/runtime/harness-confluence.js.map +1 -0
  197. package/dist/runtime/harness-eval.d.ts +96 -0
  198. package/dist/runtime/harness-eval.d.ts.map +1 -0
  199. package/dist/runtime/harness-eval.js +181 -0
  200. package/dist/runtime/harness-eval.js.map +1 -0
  201. package/dist/runtime/harness-metrics.d.ts +202 -0
  202. package/dist/runtime/harness-metrics.d.ts.map +1 -0
  203. package/dist/runtime/harness-metrics.js +415 -0
  204. package/dist/runtime/harness-metrics.js.map +1 -0
  205. package/dist/runtime/legacy-session-importer.d.ts +99 -0
  206. package/dist/runtime/legacy-session-importer.d.ts.map +1 -0
  207. package/dist/runtime/legacy-session-importer.js +455 -0
  208. package/dist/runtime/legacy-session-importer.js.map +1 -0
  209. package/dist/runtime/legacy-thread-materializer.d.ts +72 -0
  210. package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -0
  211. package/dist/runtime/legacy-thread-materializer.js +553 -0
  212. package/dist/runtime/legacy-thread-materializer.js.map +1 -0
  213. package/dist/runtime/long-tail-tools/descriptors.d.ts +23 -0
  214. package/dist/runtime/long-tail-tools/descriptors.d.ts.map +1 -0
  215. package/dist/runtime/long-tail-tools/descriptors.js +423 -0
  216. package/dist/runtime/long-tail-tools/descriptors.js.map +1 -0
  217. package/dist/runtime/loop-budget.d.ts +1 -1
  218. package/dist/runtime/loop-budget.d.ts.map +1 -1
  219. package/dist/runtime/loop-budget.js +2 -2
  220. package/dist/runtime/loop-budget.js.map +1 -1
  221. package/dist/runtime/mcp/first-party-mcp-adapter.d.ts +75 -0
  222. package/dist/runtime/mcp/first-party-mcp-adapter.d.ts.map +1 -0
  223. package/dist/runtime/mcp/first-party-mcp-adapter.js +484 -0
  224. package/dist/runtime/mcp/first-party-mcp-adapter.js.map +1 -0
  225. package/dist/runtime/mcp/first-party-mcp-config.d.ts +13 -0
  226. package/dist/runtime/mcp/first-party-mcp-config.d.ts.map +1 -0
  227. package/dist/runtime/mcp/first-party-mcp-config.js +139 -0
  228. package/dist/runtime/mcp/first-party-mcp-config.js.map +1 -0
  229. package/dist/runtime/mcp/index.d.ts +5 -0
  230. package/dist/runtime/mcp/index.d.ts.map +1 -0
  231. package/dist/{skills → runtime/mcp}/index.js +3 -9
  232. package/dist/runtime/mcp/index.js.map +1 -0
  233. package/dist/runtime/mcp/lazy-mcp-runtime.d.ts +95 -0
  234. package/dist/runtime/mcp/lazy-mcp-runtime.d.ts.map +1 -0
  235. package/dist/runtime/mcp/lazy-mcp-runtime.js +854 -0
  236. package/dist/runtime/mcp/lazy-mcp-runtime.js.map +1 -0
  237. package/dist/runtime/mcp/types.d.ts +128 -0
  238. package/dist/runtime/mcp/types.d.ts.map +1 -0
  239. package/dist/runtime/mcp/types.js +5 -0
  240. package/dist/runtime/mcp/types.js.map +1 -0
  241. package/dist/runtime/orion-runtime-v1.d.ts +322 -0
  242. package/dist/runtime/orion-runtime-v1.d.ts.map +1 -0
  243. package/dist/runtime/orion-runtime-v1.js +959 -0
  244. package/dist/runtime/orion-runtime-v1.js.map +1 -0
  245. package/dist/runtime/orion-session-runner.d.ts +38 -0
  246. package/dist/runtime/orion-session-runner.d.ts.map +1 -0
  247. package/dist/runtime/orion-session-runner.js +168 -0
  248. package/dist/runtime/orion-session-runner.js.map +1 -0
  249. package/dist/runtime/product-orion-runtime.d.ts +35 -0
  250. package/dist/runtime/product-orion-runtime.d.ts.map +1 -0
  251. package/dist/runtime/product-orion-runtime.js +1047 -0
  252. package/dist/runtime/product-orion-runtime.js.map +1 -0
  253. package/dist/runtime/prompts/index.d.ts +3 -0
  254. package/dist/runtime/prompts/index.d.ts.map +1 -0
  255. package/dist/{ink-ui/types.js → runtime/prompts/index.js} +3 -2
  256. package/dist/runtime/prompts/index.js.map +1 -0
  257. package/dist/runtime/prompts/prompt-registry.d.ts +22 -0
  258. package/dist/runtime/prompts/prompt-registry.d.ts.map +1 -0
  259. package/dist/runtime/prompts/prompt-registry.js +356 -0
  260. package/dist/runtime/prompts/prompt-registry.js.map +1 -0
  261. package/dist/runtime/prompts/types.d.ts +111 -0
  262. package/dist/runtime/prompts/types.d.ts.map +1 -0
  263. package/dist/runtime/prompts/types.js +5 -0
  264. package/dist/runtime/prompts/types.js.map +1 -0
  265. package/dist/runtime/protocol/canonical.d.ts +3 -0
  266. package/dist/runtime/protocol/canonical.d.ts.map +1 -0
  267. package/dist/runtime/protocol/canonical.js +21 -0
  268. package/dist/runtime/protocol/canonical.js.map +1 -0
  269. package/dist/runtime/protocol/index.d.ts +4 -0
  270. package/dist/runtime/protocol/index.d.ts.map +1 -0
  271. package/dist/runtime/protocol/index.js +16 -0
  272. package/dist/runtime/protocol/index.js.map +1 -0
  273. package/dist/runtime/protocol/runtime-protocol-v1.d.ts +671 -0
  274. package/dist/runtime/protocol/runtime-protocol-v1.d.ts.map +1 -0
  275. package/dist/runtime/protocol/runtime-protocol-v1.js +557 -0
  276. package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -0
  277. package/dist/runtime/release-receipts.d.ts +110 -0
  278. package/dist/runtime/release-receipts.d.ts.map +1 -0
  279. package/dist/runtime/release-receipts.js +305 -0
  280. package/dist/runtime/release-receipts.js.map +1 -0
  281. package/dist/runtime/resource-scope.d.ts +123 -0
  282. package/dist/runtime/resource-scope.d.ts.map +1 -0
  283. package/dist/runtime/resource-scope.js +363 -0
  284. package/dist/runtime/resource-scope.js.map +1 -0
  285. package/dist/runtime/runtime-event-buffer.d.ts +78 -0
  286. package/dist/runtime/runtime-event-buffer.d.ts.map +1 -0
  287. package/dist/runtime/runtime-event-buffer.js +237 -0
  288. package/dist/runtime/runtime-event-buffer.js.map +1 -0
  289. package/dist/runtime/runtime-services.d.ts +87 -0
  290. package/dist/runtime/runtime-services.d.ts.map +1 -0
  291. package/dist/runtime/runtime-services.js +180 -0
  292. package/dist/runtime/runtime-services.js.map +1 -0
  293. package/dist/runtime/session-history-recovery.d.ts +19 -0
  294. package/dist/runtime/session-history-recovery.d.ts.map +1 -0
  295. package/dist/runtime/session-history-recovery.js +45 -0
  296. package/dist/runtime/session-history-recovery.js.map +1 -0
  297. package/dist/runtime/skills/bounded-lru-cache.d.ts +34 -0
  298. package/dist/runtime/skills/bounded-lru-cache.d.ts.map +1 -0
  299. package/dist/runtime/skills/bounded-lru-cache.js +100 -0
  300. package/dist/runtime/skills/bounded-lru-cache.js.map +1 -0
  301. package/dist/runtime/skills/filesystem-skill-provider.d.ts +96 -0
  302. package/dist/runtime/skills/filesystem-skill-provider.d.ts.map +1 -0
  303. package/dist/runtime/skills/filesystem-skill-provider.js +829 -0
  304. package/dist/runtime/skills/filesystem-skill-provider.js.map +1 -0
  305. package/dist/runtime/skills/index.d.ts +5 -0
  306. package/dist/runtime/skills/index.d.ts.map +1 -0
  307. package/dist/{ink-ui/controllers/chat-controller.js → runtime/skills/index.js} +5 -2
  308. package/dist/runtime/skills/index.js.map +1 -0
  309. package/dist/runtime/skills/lazy-skill-runtime.d.ts +77 -0
  310. package/dist/runtime/skills/lazy-skill-runtime.d.ts.map +1 -0
  311. package/dist/runtime/skills/lazy-skill-runtime.js +673 -0
  312. package/dist/runtime/skills/lazy-skill-runtime.js.map +1 -0
  313. package/dist/runtime/skills/types.d.ts +137 -0
  314. package/dist/runtime/skills/types.d.ts.map +1 -0
  315. package/dist/runtime/skills/types.js +13 -0
  316. package/dist/runtime/skills/types.js.map +1 -0
  317. package/dist/runtime/step-snapshot.d.ts +183 -0
  318. package/dist/runtime/step-snapshot.d.ts.map +1 -0
  319. package/dist/runtime/step-snapshot.js +286 -0
  320. package/dist/runtime/step-snapshot.js.map +1 -0
  321. package/dist/runtime/subagent-thread-runtime.d.ts +239 -0
  322. package/dist/runtime/subagent-thread-runtime.d.ts.map +1 -0
  323. package/dist/runtime/subagent-thread-runtime.js +876 -0
  324. package/dist/runtime/subagent-thread-runtime.js.map +1 -0
  325. package/dist/runtime/subagents/index.d.ts +4 -1
  326. package/dist/runtime/subagents/index.d.ts.map +1 -1
  327. package/dist/runtime/subagents/index.js +10 -2
  328. package/dist/runtime/subagents/index.js.map +1 -1
  329. package/dist/runtime/subagents/parent-step-fork.d.ts +36 -0
  330. package/dist/runtime/subagents/parent-step-fork.d.ts.map +1 -0
  331. package/dist/runtime/subagents/parent-step-fork.js +83 -0
  332. package/dist/runtime/subagents/parent-step-fork.js.map +1 -0
  333. package/dist/runtime/subagents/production.d.ts +65 -46
  334. package/dist/runtime/subagents/production.d.ts.map +1 -1
  335. package/dist/runtime/subagents/production.js +494 -170
  336. package/dist/runtime/subagents/production.js.map +1 -1
  337. package/dist/runtime/subagents/receipt-journal.d.ts +20 -0
  338. package/dist/runtime/subagents/receipt-journal.d.ts.map +1 -0
  339. package/dist/runtime/subagents/receipt-journal.js +74 -0
  340. package/dist/runtime/subagents/receipt-journal.js.map +1 -0
  341. package/dist/runtime/subagents/runtime-contract.d.ts +29 -0
  342. package/dist/runtime/subagents/runtime-contract.d.ts.map +1 -0
  343. package/dist/runtime/subagents/runtime-contract.js +3 -0
  344. package/dist/runtime/subagents/runtime-contract.js.map +1 -0
  345. package/dist/runtime/subagents/runtime-integration.d.ts +41 -56
  346. package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
  347. package/dist/runtime/subagents/runtime-integration.js +34 -198
  348. package/dist/runtime/subagents/runtime-integration.js.map +1 -1
  349. package/dist/runtime/subagents/supervisor.d.ts +19 -7
  350. package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
  351. package/dist/runtime/subagents/supervisor.js +83 -40
  352. package/dist/runtime/subagents/supervisor.js.map +1 -1
  353. package/dist/runtime/subagents/types.d.ts +1 -1
  354. package/dist/runtime/subagents/types.js +1 -1
  355. package/dist/runtime/task-context-service.d.ts +91 -0
  356. package/dist/runtime/task-context-service.d.ts.map +1 -0
  357. package/dist/runtime/task-context-service.js +122 -0
  358. package/dist/runtime/task-context-service.js.map +1 -0
  359. package/dist/runtime/thread-admission.d.ts +130 -0
  360. package/dist/runtime/thread-admission.d.ts.map +1 -0
  361. package/dist/runtime/thread-admission.js +276 -0
  362. package/dist/runtime/thread-admission.js.map +1 -0
  363. package/dist/runtime/thread-compact-persistence.d.ts +50 -0
  364. package/dist/runtime/thread-compact-persistence.d.ts.map +1 -0
  365. package/dist/runtime/thread-compact-persistence.js +176 -0
  366. package/dist/runtime/thread-compact-persistence.js.map +1 -0
  367. package/dist/runtime/thread-event-store.d.ts +98 -0
  368. package/dist/runtime/thread-event-store.d.ts.map +1 -0
  369. package/dist/runtime/thread-event-store.js +737 -0
  370. package/dist/runtime/thread-event-store.js.map +1 -0
  371. package/dist/runtime/thread-projection.d.ts +91 -0
  372. package/dist/runtime/thread-projection.d.ts.map +1 -0
  373. package/dist/runtime/thread-projection.js +407 -0
  374. package/dist/runtime/thread-projection.js.map +1 -0
  375. package/dist/runtime/thread-runtime.d.ts +165 -0
  376. package/dist/runtime/thread-runtime.d.ts.map +1 -0
  377. package/dist/runtime/thread-runtime.js +704 -0
  378. package/dist/runtime/thread-runtime.js.map +1 -0
  379. package/dist/runtime/thread-session-view.d.ts +45 -0
  380. package/dist/runtime/thread-session-view.d.ts.map +1 -0
  381. package/dist/runtime/thread-session-view.js +264 -0
  382. package/dist/runtime/thread-session-view.js.map +1 -0
  383. package/dist/runtime/thread-tool-journal.d.ts +11 -0
  384. package/dist/runtime/thread-tool-journal.d.ts.map +1 -0
  385. package/dist/runtime/thread-tool-journal.js +131 -0
  386. package/dist/runtime/thread-tool-journal.js.map +1 -0
  387. package/dist/runtime/thread-ui-adapter.d.ts +87 -0
  388. package/dist/runtime/thread-ui-adapter.d.ts.map +1 -0
  389. package/dist/runtime/thread-ui-adapter.js +580 -0
  390. package/dist/runtime/thread-ui-adapter.js.map +1 -0
  391. package/dist/runtime/tool-gateway.d.ts +159 -0
  392. package/dist/runtime/tool-gateway.d.ts.map +1 -0
  393. package/dist/runtime/tool-gateway.js +311 -0
  394. package/dist/runtime/tool-gateway.js.map +1 -0
  395. package/dist/runtime/turn-commit.d.ts +103 -0
  396. package/dist/runtime/turn-commit.d.ts.map +1 -0
  397. package/dist/runtime/turn-commit.js +321 -0
  398. package/dist/runtime/turn-commit.js.map +1 -0
  399. package/dist/runtime/ui-events.d.ts +15 -5
  400. package/dist/runtime/ui-events.d.ts.map +1 -1
  401. package/dist/runtime/ui-events.js +0 -1
  402. package/dist/runtime/ui-events.js.map +1 -1
  403. package/dist/runtime/ui-view-model.d.ts +2 -1
  404. package/dist/runtime/ui-view-model.d.ts.map +1 -1
  405. package/dist/runtime/ui-view-model.js +6 -5
  406. package/dist/runtime/ui-view-model.js.map +1 -1
  407. package/dist/services/config-dir.d.ts +1 -1
  408. package/dist/services/config-dir.d.ts.map +1 -1
  409. package/dist/services/config-dir.js +2 -1
  410. package/dist/services/config-dir.js.map +1 -1
  411. package/dist/services/config.d.ts +2 -16
  412. package/dist/services/config.d.ts.map +1 -1
  413. package/dist/services/config.js +2 -29
  414. package/dist/services/config.js.map +1 -1
  415. package/dist/services/doctor.d.ts +0 -2
  416. package/dist/services/doctor.d.ts.map +1 -1
  417. package/dist/services/doctor.js +39 -64
  418. package/dist/services/doctor.js.map +1 -1
  419. package/dist/services/file-lock.d.ts.map +1 -1
  420. package/dist/services/file-lock.js +42 -17
  421. package/dist/services/file-lock.js.map +1 -1
  422. package/dist/services/global-config.d.ts +2 -2
  423. package/dist/services/global-config.d.ts.map +1 -1
  424. package/dist/services/session-storage.d.ts +8 -0
  425. package/dist/services/session-storage.d.ts.map +1 -1
  426. package/dist/services/session-storage.js +76 -12
  427. package/dist/services/session-storage.js.map +1 -1
  428. package/dist/skills/builtin/code-review/SKILL.md +51 -0
  429. package/dist/skills/builtin/security-check/SKILL.md +54 -0
  430. package/dist/skills/builtin/test-gen/SKILL.md +49 -0
  431. package/dist/terminal-ui/launch.d.ts +3 -1
  432. package/dist/terminal-ui/launch.d.ts.map +1 -1
  433. package/dist/terminal-ui/launch.js +21 -3
  434. package/dist/terminal-ui/launch.js.map +1 -1
  435. package/dist/tools/core/common.d.ts +34 -0
  436. package/dist/tools/core/common.d.ts.map +1 -0
  437. package/dist/tools/core/common.js +164 -0
  438. package/dist/tools/core/common.js.map +1 -0
  439. package/dist/tools/core/edit-file.d.ts +10 -0
  440. package/dist/tools/core/edit-file.d.ts.map +1 -0
  441. package/dist/tools/core/edit-file.js +301 -0
  442. package/dist/tools/core/edit-file.js.map +1 -0
  443. package/dist/tools/core/exec-command.d.ts +2 -0
  444. package/dist/tools/core/exec-command.d.ts.map +1 -0
  445. package/dist/tools/core/exec-command.js +347 -0
  446. package/dist/tools/core/exec-command.js.map +1 -0
  447. package/dist/tools/core/glob.d.ts +2 -0
  448. package/dist/tools/core/glob.d.ts.map +1 -0
  449. package/dist/tools/core/glob.js +133 -0
  450. package/dist/tools/core/glob.js.map +1 -0
  451. package/dist/tools/core/grep.d.ts +12 -0
  452. package/dist/tools/core/grep.d.ts.map +1 -0
  453. package/dist/tools/core/grep.js +223 -0
  454. package/dist/tools/core/grep.js.map +1 -0
  455. package/dist/tools/core/index.d.ts +15 -0
  456. package/dist/tools/core/index.d.ts.map +1 -0
  457. package/dist/tools/core/index.js +31 -0
  458. package/dist/tools/core/index.js.map +1 -0
  459. package/dist/tools/core/list-files.d.ts +2 -0
  460. package/dist/tools/core/list-files.d.ts.map +1 -0
  461. package/dist/tools/core/list-files.js +87 -0
  462. package/dist/tools/core/list-files.js.map +1 -0
  463. package/dist/tools/core/read-file.d.ts +2 -0
  464. package/dist/tools/core/read-file.d.ts.map +1 -0
  465. package/dist/tools/core/read-file.js +129 -0
  466. package/dist/tools/core/read-file.js.map +1 -0
  467. package/dist/tools/core/write-file.d.ts +2 -0
  468. package/dist/tools/core/write-file.d.ts.map +1 -0
  469. package/dist/tools/core/write-file.js +65 -0
  470. package/dist/tools/core/write-file.js.map +1 -0
  471. package/dist/tools/todo.d.ts +3 -4
  472. package/dist/tools/todo.d.ts.map +1 -1
  473. package/dist/tools/todo.js +80 -79
  474. package/dist/tools/todo.js.map +1 -1
  475. package/dist/tools/web.js +1 -1
  476. package/dist/tools/web.js.map +1 -1
  477. package/dist/tui-ui/chrome-view-model.d.ts.map +1 -1
  478. package/dist/tui-ui/chrome-view-model.js +22 -8
  479. package/dist/tui-ui/chrome-view-model.js.map +1 -1
  480. package/dist/tui-ui/launch.d.ts.map +1 -1
  481. package/dist/tui-ui/launch.js +13 -0
  482. package/dist/tui-ui/launch.js.map +1 -1
  483. package/dist/tui-ui/layout.js +1 -1
  484. package/dist/tui-ui/layout.js.map +1 -1
  485. package/dist/tui-ui/state.d.ts.map +1 -1
  486. package/dist/tui-ui/state.js +2 -0
  487. package/dist/tui-ui/state.js.map +1 -1
  488. package/docs/migration/v0.1.9-to-v0.2.0.md +98 -0
  489. package/docs/orion.example.json +79 -0
  490. package/docs/plan/v0.2.0-dsh-harness-redesign-plan.md +1234 -0
  491. package/docs/plan/v0.2.0-release-checklist.md +91 -0
  492. package/docs/readme.md +8 -8
  493. package/npm-shrinkwrap.json +45 -450
  494. package/package.json +17 -13
  495. package/dist/agents/coder.d.ts +0 -12
  496. package/dist/agents/coder.d.ts.map +0 -1
  497. package/dist/agents/coder.js +0 -48
  498. package/dist/agents/coder.js.map +0 -1
  499. package/dist/agents/coordinator.d.ts +0 -86
  500. package/dist/agents/coordinator.d.ts.map +0 -1
  501. package/dist/agents/coordinator.js +0 -291
  502. package/dist/agents/coordinator.js.map +0 -1
  503. package/dist/agents/fork.d.ts +0 -73
  504. package/dist/agents/fork.d.ts.map +0 -1
  505. package/dist/agents/fork.js +0 -163
  506. package/dist/agents/fork.js.map +0 -1
  507. package/dist/agents/leader.d.ts +0 -12
  508. package/dist/agents/leader.d.ts.map +0 -1
  509. package/dist/agents/leader.js +0 -49
  510. package/dist/agents/leader.js.map +0 -1
  511. package/dist/agents/router.d.ts +0 -59
  512. package/dist/agents/router.d.ts.map +0 -1
  513. package/dist/agents/router.js +0 -193
  514. package/dist/agents/router.js.map +0 -1
  515. package/dist/agents/worker-pool.d.ts +0 -72
  516. package/dist/agents/worker-pool.d.ts.map +0 -1
  517. package/dist/agents/worker-pool.js +0 -229
  518. package/dist/agents/worker-pool.js.map +0 -1
  519. package/dist/commands/legacy-commands.d.ts +0 -4
  520. package/dist/commands/legacy-commands.d.ts.map +0 -1
  521. package/dist/commands/legacy-commands.js +0 -44
  522. package/dist/commands/legacy-commands.js.map +0 -1
  523. package/dist/core/agent.d.ts +0 -84
  524. package/dist/core/agent.d.ts.map +0 -1
  525. package/dist/core/agent.js +0 -58
  526. package/dist/core/agent.js.map +0 -1
  527. package/dist/core/brain.d.ts +0 -50
  528. package/dist/core/brain.d.ts.map +0 -1
  529. package/dist/core/brain.js +0 -95
  530. package/dist/core/brain.js.map +0 -1
  531. package/dist/framework/tool-scheduler.d.ts +0 -191
  532. package/dist/framework/tool-scheduler.d.ts.map +0 -1
  533. package/dist/framework/tool-scheduler.js +0 -573
  534. package/dist/framework/tool-scheduler.js.map +0 -1
  535. package/dist/harness/harness.d.ts +0 -58
  536. package/dist/harness/harness.d.ts.map +0 -1
  537. package/dist/harness/harness.js +0 -195
  538. package/dist/harness/harness.js.map +0 -1
  539. package/dist/harness/safety.d.ts +0 -101
  540. package/dist/harness/safety.d.ts.map +0 -1
  541. package/dist/harness/safety.js +0 -322
  542. package/dist/harness/safety.js.map +0 -1
  543. package/dist/init.d.ts +0 -108
  544. package/dist/init.d.ts.map +0 -1
  545. package/dist/init.js +0 -393
  546. package/dist/init.js.map +0 -1
  547. package/dist/ink-ui/App.d.ts +0 -9
  548. package/dist/ink-ui/App.d.ts.map +0 -1
  549. package/dist/ink-ui/App.js +0 -12
  550. package/dist/ink-ui/App.js.map +0 -1
  551. package/dist/ink-ui/components/Markdown.d.ts +0 -10
  552. package/dist/ink-ui/components/Markdown.d.ts.map +0 -1
  553. package/dist/ink-ui/components/Markdown.js +0 -210
  554. package/dist/ink-ui/components/Markdown.js.map +0 -1
  555. package/dist/ink-ui/components/NativeCursor.d.ts +0 -12
  556. package/dist/ink-ui/components/NativeCursor.d.ts.map +0 -1
  557. package/dist/ink-ui/components/NativeCursor.js +0 -35
  558. package/dist/ink-ui/components/NativeCursor.js.map +0 -1
  559. package/dist/ink-ui/components/PixelHorseBanner.d.ts +0 -8
  560. package/dist/ink-ui/components/PixelHorseBanner.d.ts.map +0 -1
  561. package/dist/ink-ui/components/PixelHorseBanner.js +0 -97
  562. package/dist/ink-ui/components/PixelHorseBanner.js.map +0 -1
  563. package/dist/ink-ui/components/PromptInput.d.ts +0 -13
  564. package/dist/ink-ui/components/PromptInput.d.ts.map +0 -1
  565. package/dist/ink-ui/components/PromptInput.js +0 -30
  566. package/dist/ink-ui/components/PromptInput.js.map +0 -1
  567. package/dist/ink-ui/components/RunningHorseIndicator.d.ts +0 -13
  568. package/dist/ink-ui/components/RunningHorseIndicator.d.ts.map +0 -1
  569. package/dist/ink-ui/components/RunningHorseIndicator.js +0 -53
  570. package/dist/ink-ui/components/RunningHorseIndicator.js.map +0 -1
  571. package/dist/ink-ui/components/SelectList.d.ts +0 -16
  572. package/dist/ink-ui/components/SelectList.d.ts.map +0 -1
  573. package/dist/ink-ui/components/SelectList.js +0 -60
  574. package/dist/ink-ui/components/SelectList.js.map +0 -1
  575. package/dist/ink-ui/components/StatusLine.d.ts +0 -11
  576. package/dist/ink-ui/components/StatusLine.d.ts.map +0 -1
  577. package/dist/ink-ui/components/StatusLine.js +0 -70
  578. package/dist/ink-ui/components/StatusLine.js.map +0 -1
  579. package/dist/ink-ui/components/ToolActivity.d.ts +0 -19
  580. package/dist/ink-ui/components/ToolActivity.d.ts.map +0 -1
  581. package/dist/ink-ui/components/ToolActivity.js +0 -134
  582. package/dist/ink-ui/components/ToolActivity.js.map +0 -1
  583. package/dist/ink-ui/components/Transcript.d.ts +0 -14
  584. package/dist/ink-ui/components/Transcript.d.ts.map +0 -1
  585. package/dist/ink-ui/components/Transcript.js +0 -66
  586. package/dist/ink-ui/components/Transcript.js.map +0 -1
  587. package/dist/ink-ui/controllers/chat-controller.d.ts +0 -2
  588. package/dist/ink-ui/controllers/chat-controller.d.ts.map +0 -1
  589. package/dist/ink-ui/controllers/chat-controller.js.map +0 -1
  590. package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts +0 -6
  591. package/dist/ink-ui/hooks/use-raw-input-bridge.d.ts.map +0 -1
  592. package/dist/ink-ui/hooks/use-raw-input-bridge.js +0 -27
  593. package/dist/ink-ui/hooks/use-raw-input-bridge.js.map +0 -1
  594. package/dist/ink-ui/hooks/use-terminal-size.d.ts +0 -7
  595. package/dist/ink-ui/hooks/use-terminal-size.d.ts.map +0 -1
  596. package/dist/ink-ui/hooks/use-terminal-size.js +0 -34
  597. package/dist/ink-ui/hooks/use-terminal-size.js.map +0 -1
  598. package/dist/ink-ui/launch.d.ts +0 -9
  599. package/dist/ink-ui/launch.d.ts.map +0 -1
  600. package/dist/ink-ui/launch.js +0 -101
  601. package/dist/ink-ui/launch.js.map +0 -1
  602. package/dist/ink-ui/runtime/grapheme.d.ts +0 -10
  603. package/dist/ink-ui/runtime/grapheme.d.ts.map +0 -1
  604. package/dist/ink-ui/runtime/grapheme.js +0 -17
  605. package/dist/ink-ui/runtime/grapheme.js.map +0 -1
  606. package/dist/ink-ui/runtime/input-buffer.d.ts +0 -10
  607. package/dist/ink-ui/runtime/input-buffer.d.ts.map +0 -1
  608. package/dist/ink-ui/runtime/input-buffer.js +0 -18
  609. package/dist/ink-ui/runtime/input-buffer.js.map +0 -1
  610. package/dist/ink-ui/runtime/layout-budget.d.ts +0 -13
  611. package/dist/ink-ui/runtime/layout-budget.d.ts.map +0 -1
  612. package/dist/ink-ui/runtime/layout-budget.js +0 -25
  613. package/dist/ink-ui/runtime/layout-budget.js.map +0 -1
  614. package/dist/ink-ui/runtime/native-cursor.d.ts +0 -62
  615. package/dist/ink-ui/runtime/native-cursor.d.ts.map +0 -1
  616. package/dist/ink-ui/runtime/native-cursor.js +0 -398
  617. package/dist/ink-ui/runtime/native-cursor.js.map +0 -1
  618. package/dist/ink-ui/runtime/prompt-layout.d.ts +0 -10
  619. package/dist/ink-ui/runtime/prompt-layout.d.ts.map +0 -1
  620. package/dist/ink-ui/runtime/prompt-layout.js +0 -21
  621. package/dist/ink-ui/runtime/prompt-layout.js.map +0 -1
  622. package/dist/ink-ui/runtime/raw-input.d.ts +0 -4
  623. package/dist/ink-ui/runtime/raw-input.d.ts.map +0 -1
  624. package/dist/ink-ui/runtime/raw-input.js +0 -15
  625. package/dist/ink-ui/runtime/raw-input.js.map +0 -1
  626. package/dist/ink-ui/runtime/transcript-state.d.ts +0 -37
  627. package/dist/ink-ui/runtime/transcript-state.d.ts.map +0 -1
  628. package/dist/ink-ui/runtime/transcript-state.js +0 -91
  629. package/dist/ink-ui/runtime/transcript-state.js.map +0 -1
  630. package/dist/ink-ui/screens/ReplScreen.d.ts +0 -27
  631. package/dist/ink-ui/screens/ReplScreen.d.ts.map +0 -1
  632. package/dist/ink-ui/screens/ReplScreen.js +0 -781
  633. package/dist/ink-ui/screens/ReplScreen.js.map +0 -1
  634. package/dist/ink-ui/types.d.ts +0 -2
  635. package/dist/ink-ui/types.d.ts.map +0 -1
  636. package/dist/ink-ui/types.js.map +0 -1
  637. package/dist/runtime/chat-checkpoint.d.ts +0 -17
  638. package/dist/runtime/chat-checkpoint.d.ts.map +0 -1
  639. package/dist/runtime/chat-checkpoint.js +0 -105
  640. package/dist/runtime/chat-checkpoint.js.map +0 -1
  641. package/dist/runtime/chat-command-scope.d.ts +0 -5
  642. package/dist/runtime/chat-command-scope.d.ts.map +0 -1
  643. package/dist/runtime/chat-command-scope.js +0 -22
  644. package/dist/runtime/chat-command-scope.js.map +0 -1
  645. package/dist/runtime/chat-compact.d.ts +0 -26
  646. package/dist/runtime/chat-compact.d.ts.map +0 -1
  647. package/dist/runtime/chat-compact.js +0 -132
  648. package/dist/runtime/chat-compact.js.map +0 -1
  649. package/dist/runtime/chat-controller.d.ts +0 -62
  650. package/dist/runtime/chat-controller.d.ts.map +0 -1
  651. package/dist/runtime/chat-controller.js +0 -1620
  652. package/dist/runtime/chat-controller.js.map +0 -1
  653. package/dist/runtime/chat-effort.d.ts +0 -5
  654. package/dist/runtime/chat-effort.d.ts.map +0 -1
  655. package/dist/runtime/chat-effort.js +0 -47
  656. package/dist/runtime/chat-effort.js.map +0 -1
  657. package/dist/runtime/chat-presentation.d.ts +0 -63
  658. package/dist/runtime/chat-presentation.d.ts.map +0 -1
  659. package/dist/runtime/chat-presentation.js +0 -561
  660. package/dist/runtime/chat-presentation.js.map +0 -1
  661. package/dist/runtime/chat-trace.d.ts +0 -52
  662. package/dist/runtime/chat-trace.d.ts.map +0 -1
  663. package/dist/runtime/chat-trace.js +0 -234
  664. package/dist/runtime/chat-trace.js.map +0 -1
  665. package/dist/runtime/chat-workspace.d.ts +0 -22
  666. package/dist/runtime/chat-workspace.d.ts.map +0 -1
  667. package/dist/runtime/chat-workspace.js +0 -154
  668. package/dist/runtime/chat-workspace.js.map +0 -1
  669. package/dist/runtime/goals/accounting.d.ts +0 -45
  670. package/dist/runtime/goals/accounting.d.ts.map +0 -1
  671. package/dist/runtime/goals/accounting.js +0 -114
  672. package/dist/runtime/goals/accounting.js.map +0 -1
  673. package/dist/runtime/goals/coordinator.d.ts +0 -92
  674. package/dist/runtime/goals/coordinator.d.ts.map +0 -1
  675. package/dist/runtime/goals/coordinator.js +0 -1471
  676. package/dist/runtime/goals/coordinator.js.map +0 -1
  677. package/dist/runtime/goals/lifecycle.d.ts +0 -13
  678. package/dist/runtime/goals/lifecycle.d.ts.map +0 -1
  679. package/dist/runtime/goals/lifecycle.js +0 -46
  680. package/dist/runtime/goals/lifecycle.js.map +0 -1
  681. package/dist/runtime/goals/prompt.d.ts +0 -16
  682. package/dist/runtime/goals/prompt.d.ts.map +0 -1
  683. package/dist/runtime/goals/prompt.js +0 -88
  684. package/dist/runtime/goals/prompt.js.map +0 -1
  685. package/dist/runtime/goals/stop-policy.d.ts +0 -9
  686. package/dist/runtime/goals/stop-policy.d.ts.map +0 -1
  687. package/dist/runtime/goals/stop-policy.js +0 -83
  688. package/dist/runtime/goals/stop-policy.js.map +0 -1
  689. package/dist/runtime/goals/tools.d.ts +0 -61
  690. package/dist/runtime/goals/tools.d.ts.map +0 -1
  691. package/dist/runtime/goals/tools.js +0 -568
  692. package/dist/runtime/goals/tools.js.map +0 -1
  693. package/dist/sdk/index.d.ts +0 -10
  694. package/dist/sdk/index.d.ts.map +0 -1
  695. package/dist/sdk/index.js +0 -23
  696. package/dist/sdk/index.js.map +0 -1
  697. package/dist/sdk/init.d.ts +0 -24
  698. package/dist/sdk/init.d.ts.map +0 -1
  699. package/dist/sdk/init.js +0 -48
  700. package/dist/sdk/init.js.map +0 -1
  701. package/dist/sdk/query.d.ts +0 -19
  702. package/dist/sdk/query.d.ts.map +0 -1
  703. package/dist/sdk/query.js +0 -42
  704. package/dist/sdk/query.js.map +0 -1
  705. package/dist/sdk/sessions.d.ts +0 -19
  706. package/dist/sdk/sessions.d.ts.map +0 -1
  707. package/dist/sdk/sessions.js +0 -57
  708. package/dist/sdk/sessions.js.map +0 -1
  709. package/dist/sdk/types.d.ts +0 -47
  710. package/dist/sdk/types.d.ts.map +0 -1
  711. package/dist/sdk/types.js +0 -8
  712. package/dist/sdk/types.js.map +0 -1
  713. package/dist/services/agent-runner.d.ts +0 -71
  714. package/dist/services/agent-runner.d.ts.map +0 -1
  715. package/dist/services/agent-runner.js +0 -185
  716. package/dist/services/agent-runner.js.map +0 -1
  717. package/dist/services/task-manager.d.ts +0 -161
  718. package/dist/services/task-manager.d.ts.map +0 -1
  719. package/dist/services/task-manager.js +0 -315
  720. package/dist/services/task-manager.js.map +0 -1
  721. package/dist/skills/discovery.d.ts +0 -22
  722. package/dist/skills/discovery.d.ts.map +0 -1
  723. package/dist/skills/discovery.js +0 -75
  724. package/dist/skills/discovery.js.map +0 -1
  725. package/dist/skills/index.d.ts +0 -11
  726. package/dist/skills/index.d.ts.map +0 -1
  727. package/dist/skills/index.js.map +0 -1
  728. package/dist/skills/loader.d.ts +0 -53
  729. package/dist/skills/loader.d.ts.map +0 -1
  730. package/dist/skills/loader.js +0 -421
  731. package/dist/skills/loader.js.map +0 -1
  732. package/dist/skills/registry.d.ts +0 -41
  733. package/dist/skills/registry.d.ts.map +0 -1
  734. package/dist/skills/registry.js +0 -157
  735. package/dist/skills/registry.js.map +0 -1
  736. package/dist/skills/runtime.d.ts +0 -46
  737. package/dist/skills/runtime.d.ts.map +0 -1
  738. package/dist/skills/runtime.js +0 -363
  739. package/dist/skills/runtime.js.map +0 -1
  740. package/dist/skills/types.d.ts +0 -112
  741. package/dist/skills/types.d.ts.map +0 -1
  742. package/dist/skills/types.js +0 -24
  743. package/dist/skills/types.js.map +0 -1
  744. package/dist/tools/index.d.ts +0 -52
  745. package/dist/tools/index.d.ts.map +0 -1
  746. package/dist/tools/index.js +0 -2268
  747. package/dist/tools/index.js.map +0 -1
  748. package/dist/tools/mcp.d.ts +0 -99
  749. package/dist/tools/mcp.d.ts.map +0 -1
  750. package/dist/tools/mcp.js +0 -695
  751. package/dist/tools/mcp.js.map +0 -1
  752. package/dist/tools/plan.d.ts +0 -17
  753. package/dist/tools/plan.d.ts.map +0 -1
  754. package/dist/tools/plan.js +0 -84
  755. package/dist/tools/plan.js.map +0 -1
  756. package/docs/migration/v0.1.8-to-v0.1.9.md +0 -60
  757. package/docs/plan/v0.1.9-release-checklist.md +0 -64
@@ -1,60 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AgentRuntimeController = void 0;
4
- exports.goalProviderError = goalProviderError;
5
- exports.goalTurnMadeProgress = goalTurnMadeProgress;
6
4
  const commands_1 = require("../commands");
7
5
  const parser_1 = require("../commands/parser");
8
6
  const target_command_1 = require("../commands/target-command");
9
7
  const agent_runtime_protocol_1 = require("./agent-runtime-protocol");
10
8
  const agent_status_1 = require("./agent-status");
11
- const chat_controller_1 = require("./chat-controller");
12
9
  const ui_events_1 = require("./ui-events");
13
10
  const turn_controller_1 = require("./turn-controller");
14
- const tools_1 = require("./goals/tools");
15
- const accounting_1 = require("./goals/accounting");
16
- const crypto_1 = require("crypto");
17
- const workspace_state_1 = require("../services/workspace-state");
18
- const redaction_1 = require("../services/redaction");
19
- const evidence_1 = require("./goals/evidence");
20
- const session_storage_1 = require("../services/session-storage");
21
- const external_assertion_1 = require("../framework/external-assertion");
22
11
  const global_config_1 = require("../services/global-config");
23
12
  const tool_allowlist_1 = require("../services/tool-allowlist");
24
13
  const agent_mode_1 = require("../framework/agent-mode");
25
- const lifecycle_1 = require("./goals/lifecycle");
14
+ const style_1 = require("../tui-core/style");
26
15
  function isExitInput(input) {
27
16
  const parsed = (0, parser_1.parseInput)(input.trim());
28
17
  return parsed.isCommand && ['exit', 'quit', 'q'].includes(parsed.name);
29
18
  }
30
- function goalProviderError(finishReason, errorType) {
31
- if (finishReason !== 'failed' || !errorType)
32
- return undefined;
33
- switch (errorType) {
34
- case 'quota_or_credit_exhausted':
35
- return { kind: 'usage_limit', retryable: false };
36
- case 'rate_limit':
37
- return { kind: 'rate_limit', retryable: true };
38
- case 'provider_busy':
39
- return { kind: 'provider_busy', retryable: true };
40
- case 'auth_failed':
41
- return { kind: 'auth', retryable: false };
42
- case 'connect_timeout':
43
- case 'read_timeout':
44
- case 'connection_reset':
45
- case 'network_error':
46
- return { kind: 'network', retryable: true };
47
- default:
48
- return { kind: 'unknown', retryable: false };
49
- }
50
- }
51
- function goalTurnMadeProgress(input) {
52
- const passedEvidence = input.evidenceRecords?.some(record => record.result === 'passed') ?? false;
53
- const workspaceChanged = Boolean(input.workspaceFingerprintBefore &&
54
- input.workspaceFingerprintAfter &&
55
- input.workspaceFingerprintBefore !== input.workspaceFingerprintAfter);
56
- return passedEvidence || workspaceChanged;
57
- }
58
19
  function submittedEntry(input) {
59
20
  const parsed = (0, parser_1.parseInput)(input.trim());
60
21
  return {
@@ -81,31 +42,17 @@ function resumeSessionInput(sessionId, allProjects) {
81
42
  * these results and events instead of reimplementing the turn lifecycle.
82
43
  */
83
44
  class AgentRuntimeController {
84
- /** v0.2.24: set the goal coordinator for /target mode. */
85
- setGoalCoordinator(coord) {
86
- this.goalCoordinator = coord;
87
- this.goalCoordinatorSessionId = coord.boundSessionId;
88
- // Wire goal prompt injection into the chat controller.
89
- if ('setGoalCoordinator' in this.runner) {
90
- this.runner.setGoalCoordinator(coord);
91
- }
92
- }
93
45
  constructor(options) {
94
46
  this.options = options;
95
47
  this.pendingPermissions = new Map();
96
48
  this.activeRun = null;
49
+ this.goalControlRuns = new Set();
97
50
  this.stopping = false;
98
- this.continuationScheduleEpoch = 0;
99
- /** Conservative reservations for every provider attempt in the current root turn. */
100
- this.goalProviderReservedTokens = 0;
101
51
  this.nextPermissionRequestId = 1;
102
52
  this.queuedCommands = [];
103
53
  this.followupQueue = [];
104
54
  this.followupQueueLimit = 16;
105
55
  this.nextFollowupId = 1;
106
- /** v0.2.24: optional goal coordinator for /target mode. */
107
- this.goalCoordinator = null;
108
- this.goalCoordinatorSessionId = null;
109
56
  if (!options.events && !options.eventSink) {
110
57
  throw new Error('AgentRuntimeController requires either events or eventSink');
111
58
  }
@@ -113,14 +60,12 @@ class AgentRuntimeController {
113
60
  const downstream = options.eventSink ?? (0, agent_runtime_protocol_1.createAgentRuntimeEventSinkFromUiEvents)(options.events);
114
61
  this.eventSink = {
115
62
  emit: event => {
116
- this.captureGoalEvidence(event);
117
63
  const result = downstream.emit(event);
118
64
  if (event.type === 'session_restored') {
119
65
  if (this.followupQueue.length > 0) {
120
66
  this.followupQueue.splice(0);
121
67
  this.emitFollowupQueue();
122
68
  }
123
- this.restoreGoalForSession(event.event.sessionId, event.event.projectPath);
124
69
  }
125
70
  return result;
126
71
  },
@@ -132,7 +77,11 @@ class AgentRuntimeController {
132
77
  });
133
78
  const events = (0, agent_runtime_protocol_1.createUiEventSinkFromAgentRuntimeEvents)(this.eventSink);
134
79
  this.runner =
135
- options.runner ?? new chat_controller_1.AgentChatController(options.runtime, events, this.createChatOptions());
80
+ options.runner ??
81
+ options.runtime.createAgentRunner?.(events, {
82
+ approvalHandler: request => this.requestToolPermission(request),
83
+ }) ??
84
+ createUnavailableRunner();
136
85
  this.emitAgentModeSnapshot();
137
86
  }
138
87
  hasActiveTurn() {
@@ -141,208 +90,36 @@ class AgentRuntimeController {
141
90
  getFollowupQueue() {
142
91
  return this.followupQueue;
143
92
  }
144
- /** v0.1.1: shared /target command handling for all renderers. */
93
+ /** Thin /goal control surface; GoalRuntimeCoordinatorV2 owns every mutation. */
145
94
  handleTargetInput(rawInput) {
146
- if (/^\/target(?:\s|$)/iu.test(rawInput.trim())) {
147
- const command = (0, commands_1.findCommand)('goal');
148
- if (command) {
149
- this.emitAppend({
150
- role: 'system',
151
- title: '/target deprecated',
152
- content: '/target is deprecated; use /goal. It will be removed in v0.3.0.',
153
- statusTone: 'warning',
154
- command: {
155
- id: command.id,
156
- name: command.name,
157
- source: command.source,
158
- success: true,
159
- },
160
- });
161
- }
162
- }
163
95
  const parsed = (0, target_command_1.parseTargetCommand)(rawInput);
164
96
  if (!parsed.ok) {
165
97
  this.emitAppend({
166
98
  role: 'error',
167
- title: 'target',
99
+ title: 'goal',
168
100
  content: parsed.error,
169
101
  errorLayer: 'runtime',
170
102
  });
103
+ this.emitStatus(parsed.error);
171
104
  return {
172
105
  handled: true,
173
106
  statusText: parsed.error,
174
107
  runtimeResult: { type: 'command_handled' },
175
108
  };
176
109
  }
177
- const input = parsed.input;
178
- const coord = this.ensureGoalCoordinator(input.action !== 'show');
179
- if (!coord) {
180
- const statusText = 'Target unavailable: no active session.';
181
- this.emitAppend({
182
- role: 'error',
183
- title: 'target',
184
- content: statusText,
185
- errorLayer: 'session',
186
- });
187
- return { handled: true, statusText, runtimeResult: { type: 'command_handled' } };
188
- }
189
- if (this.turnController.hasActiveTurn() && !['pause', 'show', 'clear'].includes(input.action)) {
190
- const statusText = 'Target command ignored while the agent is running. Use /target pause or interrupt first.';
191
- this.emitStatus(statusText);
192
- return { handled: true, statusText, runtimeResult: { type: 'command_ignored' } };
193
- }
194
- let success = true;
195
- let error;
196
- let executionRevoked = false;
197
- const previousGoalId = coord.goal?.goalId;
198
- try {
199
- switch (input.action) {
200
- case 'show':
201
- break;
202
- case 'create': {
203
- const result = coord.create(input.payload?.objective ?? '');
204
- success = result.ok;
205
- if (!result.ok)
206
- error = result.error;
207
- break;
208
- }
209
- case 'pause':
210
- if (coord.isActive) {
211
- this.abortGoalOwnedExecution();
212
- executionRevoked = true;
213
- }
214
- success = coord.pause();
215
- if (!success)
216
- error = 'Target is not active.';
217
- break;
218
- case 'resume':
219
- success = coord.resume({
220
- confirmBoundary: true,
221
- expectedGoalId: coord.goal?.goalId,
222
- expectedRevision: coord.goal?.revision,
223
- });
224
- if (!success)
225
- error = 'Target cannot be resumed from its current state.';
226
- break;
227
- case 'confirm':
228
- success = coord.confirmCriterion(input.payload?.criterionId ?? '');
229
- if (!success) {
230
- error = 'Criterion cannot be confirmed. It must exist and require user evidence.';
231
- }
232
- break;
233
- case 'edit':
234
- success = coord.edit(input.payload?.objective ?? '');
235
- if (!success)
236
- error = 'Target objective could not be updated.';
237
- break;
238
- case 'replace':
239
- success = coord.replace(input.payload?.objective ?? '');
240
- if (!success) {
241
- error = 'Target could not be replaced.';
242
- if (input.payload?.objective?.trim()) {
243
- error = this.failClosedGoalMutation(coord, input.action, new Error(error), executionRevoked, previousGoalId);
244
- executionRevoked = true;
245
- }
246
- }
247
- break;
248
- case 'set_budget':
249
- success = coord.setBudget(input.payload?.tokenBudget ?? null);
250
- if (!success)
251
- error = 'Create or resume a target before setting a budget.';
252
- break;
253
- case 'clear':
254
- if (!input.payload?.confirmed) {
255
- success = false;
256
- error = 'Removing a Goal requires explicit authorization: /goal exit';
257
- }
258
- else {
259
- const hadGoal = coord.goal !== null;
260
- if (hadGoal) {
261
- this.abortGoalOwnedExecution();
262
- executionRevoked = true;
263
- }
264
- success = (0, lifecycle_1.clearGoalLifecycle)(coord) !== null;
265
- if (success && this.followupQueue.length > 0) {
266
- this.followupQueue.splice(0);
267
- this.emitFollowupQueue();
268
- }
269
- if (hadGoal && !success) {
270
- error = this.failClosedGoalMutation(coord, input.action, new Error('Target clear did not remove the active Goal.'), executionRevoked, previousGoalId);
271
- }
272
- if (!success && !hadGoal)
273
- error = 'No target exists to clear.';
274
- }
275
- break;
276
- }
277
- }
278
- catch (cause) {
279
- success = false;
280
- error =
281
- input.action === 'show'
282
- ? cause instanceof Error
283
- ? cause.message
284
- : String(cause)
285
- : this.failClosedGoalMutation(coord, input.action, cause, executionRevoked, previousGoalId);
286
- }
287
- if (!success && error) {
288
- this.emitAppend({ role: 'error', title: 'target', content: error, errorLayer: 'runtime' });
289
- }
290
- if (success &&
291
- input.action === 'resume' &&
292
- coord.goal?.status === 'active' &&
293
- coord.goal.tokenBudget !== undefined) {
294
- const resumedBudget = (0, accounting_1.budgetPreflight)(coord.goal.tokensUsed, coord.goal.tokenBudget, 0);
295
- if (!resumedBudget.available) {
296
- try {
297
- coord.limitBudget(resumedBudget.reason ?? 'Token budget unavailable after resuming the target.');
298
- }
299
- catch (cause) {
300
- success = false;
301
- error = this.failClosedGoalMutation(coord, 'resume_budget_stop', cause, executionRevoked, previousGoalId);
302
- this.emitGoalMutationError(error);
303
- }
304
- }
305
- }
306
- if (success && input.action !== 'clear') {
307
- const { updateSessionGoalBinding } = require('../services/session-storage');
308
- updateSessionGoalBinding(coord.boundSessionId, coord.goal);
309
- const snapshot = coord.snapshot();
310
- if (snapshot) {
311
- this.emitGoalEvent({
312
- type: 'goal_updated',
313
- goal: snapshot,
314
- reason: `target_${input.action}`,
315
- });
316
- }
317
- }
318
- if (success && input.action === 'clear' && previousGoalId) {
319
- this.emitGoalEvent({ type: 'goal_cleared', goalId: previousGoalId, reason: 'user_clear' });
320
- }
321
- const statusText = this.formatTargetStatus(coord);
322
- this.emitAppend({ role: 'system', title: 'target', content: statusText });
323
- if (success &&
324
- (input.action === 'create' || input.action === 'resume' || input.action === 'replace') &&
325
- coord.isActive) {
326
- const req = coord.buildContinuationRequest();
327
- if (req) {
328
- const runtimeResult = this.submitGoalContinuation(req, `target_${input.action}`, true);
329
- return { handled: true, statusText, runtimeResult };
330
- }
331
- }
332
- return { handled: true, statusText, runtimeResult: { type: 'command_handled' } };
110
+ return {
111
+ handled: true,
112
+ runtimeResult: this.startGoalControl(parsed.input),
113
+ };
333
114
  }
334
- /** v0.1.1: shared /target intercept check for all renderers. */
115
+ /** Goal controls remain available while a turn is active only when they can stop or inspect it. */
335
116
  canInterceptTargetCommand(input, duringActiveTurn) {
336
117
  if (!(0, target_command_1.isTargetCommand)(input))
337
118
  return false;
338
119
  const parsed = (0, target_command_1.parseTargetCommand)(input);
339
- if (!parsed.ok)
340
- return true; // intercept to show error
341
- // During active turn, only allow non-mutating actions.
342
- if (duringActiveTurn) {
343
- return ['pause', 'show', 'clear'].includes(parsed.input.action);
344
- }
345
- return true;
120
+ if (!parsed.ok || !duringActiveTurn)
121
+ return true;
122
+ return ['status', 'pause', 'clear'].includes(parsed.input.action);
346
123
  }
347
124
  /** v0.1.1: emit clear_view event through the renderer protocol. */
348
125
  emitClearView() {
@@ -350,7 +127,7 @@ class AgentRuntimeController {
350
127
  }
351
128
  /** v0.1.1: emit shutdown_requested event through the renderer protocol. */
352
129
  emitShutdownRequested(reason) {
353
- this.deferGoalContinuation(reason ?? 'shutdown requested', true);
130
+ this.runner.interrupt?.(reason ?? 'shutdown requested');
354
131
  this.eventSink.emit({ type: 'shutdown_requested', reason });
355
132
  }
356
133
  setVerificationState(state) {
@@ -380,7 +157,7 @@ class AgentRuntimeController {
380
157
  this.clearExitIntent();
381
158
  return { type: 'exit_intent_cleared' };
382
159
  case 'goal_control':
383
- return this.handleGoalControl(input);
160
+ return this.startGoalControl(input);
384
161
  case 'permission_mode_change':
385
162
  return this.applyPermissionModeChange(input.value);
386
163
  case 'cycle_agent_mode':
@@ -435,28 +212,27 @@ class AgentRuntimeController {
435
212
  if ((0, target_command_1.isTargetCommand)(submitted)) {
436
213
  return this.handleTargetInput(submitted).runtimeResult;
437
214
  }
438
- const activeSession = this.options.runtime.getSession();
439
- const activeGoalCoordinator = this.ensureGoalCoordinator(false);
440
- if (activeSession && activeGoalCoordinator?.goal) {
441
- const abandonment = (0, tools_1.authorizeGoalAbandonment)({
442
- inputKind: 'user',
443
- text: submitted,
444
- sessionId: activeSession.id,
445
- persistAsUserMessage: true,
446
- echoToTranscript: true,
447
- generation: activeGoalCoordinator.generation,
448
- });
449
- if (abandonment.authorized) {
450
- this.emitAppend(submittedEntry(submitted));
451
- return this.handleTargetInput('/goal exit').runtimeResult;
452
- }
453
- }
454
215
  const parsedInput = (0, parser_1.parseInput)(submitted);
455
216
  if (parsedInput.isCommand && parsedInput.name === 'clear') {
456
217
  this.emitClearView();
457
218
  this.emitStatus('View cleared. Conversation context is preserved.');
458
219
  return { type: 'command_handled' };
459
220
  }
221
+ if (parsedInput.isCommand && !(0, commands_1.findCommand)(parsedInput.name)) {
222
+ const message = `Unknown command /${parsedInput.name}. Use /help to list supported commands.`;
223
+ this.emitAppend({ role: 'error', title: 'unknown command', content: message });
224
+ this.emitStatus(message);
225
+ return { type: 'command_handled' };
226
+ }
227
+ if (parsedInput.isCommand) {
228
+ const command = (0, commands_1.findCommand)(parsedInput.name);
229
+ this.activeRun = this.runCommand(command, parsedInput.args)
230
+ .catch(error => this.handleRunLoopError(error))
231
+ .finally(() => {
232
+ this.activeRun = null;
233
+ });
234
+ return { type: 'command_handled' };
235
+ }
460
236
  if (this.turnController.hasActiveTurn()) {
461
237
  const parsed = (0, parser_1.parseInput)(submitted);
462
238
  if (parsed.isCommand) {
@@ -482,51 +258,26 @@ class AgentRuntimeController {
482
258
  this.emitStatus(`Queued /${command.name}; it will apply after the active logical request.`);
483
259
  return { type: 'command_queued', commandId: command.id };
484
260
  }
485
- // v0.2.26: user steering input during active goal — update constraints
486
- // without replacing the root objective.
487
- const gc = this.goalCoordinator;
488
- if (gc?.goal && !(0, target_command_1.isTargetCommand)(submitted)) {
489
- const steeringGoalId = gc.goal.goalId;
490
- try {
491
- gc.addConstraint(submitted);
492
- }
493
- catch (cause) {
494
- const message = this.failClosedGoalMutation(gc, 'steering', cause, false, steeringGoalId);
495
- this.emitAppend({
496
- role: 'error',
497
- title: 'target steering',
498
- content: message,
499
- errorLayer: 'runtime',
500
- });
501
- this.emitStatus(message);
502
- return { type: 'command_ignored' };
503
- }
504
- }
505
261
  this.turnController.clearExitIntent();
506
262
  this.turnController.requestRevision(submitted);
507
263
  // v0.1.3 (G1): echo the incremental input to the transcript immediately,
508
264
  // so the user sees their correction without waiting for the turn to abort.
509
- this.emitAppend(submittedEntry(submitted));
265
+ // A runtime-owned durable transcript disables this optimistic projection
266
+ // and emits the revision from its authoritative user item instead.
267
+ if (this.options.echoSubmittedInput ?? true) {
268
+ this.emitAppend(submittedEntry(submitted));
269
+ }
510
270
  this.emitStatus(this.options.revisionStatus ?? '已接收补充,正在中断当前轮…');
511
271
  return { type: 'revision_requested' };
512
272
  }
513
273
  const session = this.options.runtime.getSession() ?? this.options.runtime.ensureSession();
514
- const coord = this.ensureGoalCoordinator(false);
515
- const goal = coord?.goal?.status === 'active' ? coord.goal : undefined;
516
274
  const request = {
517
275
  inputKind: 'user',
518
276
  text: submitted,
519
277
  sessionId: session?.id ?? 'pending-session',
520
- goal: goal
521
- ? {
522
- goalId: goal.goalId,
523
- revision: goal.revision,
524
- continuationIndex: goal.continuationCount,
525
- }
526
- : undefined,
527
278
  persistAsUserMessage: true,
528
279
  echoToTranscript: true,
529
- generation: coord?.generation ?? 0,
280
+ generation: 0,
530
281
  };
531
282
  return this.submitTurnRequest(request);
532
283
  }
@@ -559,390 +310,123 @@ class AgentRuntimeController {
559
310
  }
560
311
  this.emitStatus(`/${name} acknowledged; active turn continues.`);
561
312
  }
562
- submitTurnRequest(request) {
563
- if (this.turnController.hasActiveTurn())
564
- return { type: 'command_ignored' };
565
- if (!this.requestIsCurrent(request))
566
- return { type: 'command_ignored' };
567
- this.activeRun = this.runTurn(request)
568
- .catch(error => {
569
- this.handleRunLoopError(error);
570
- })
571
- .finally(() => {
572
- this.activeRun = null;
573
- // v0.2.26: schedule goal continuation after turn completes.
574
- this.scheduleGoalContinuation();
575
- });
576
- return { type: 'started' };
577
- }
578
- submitGoalContinuation(request, reason, emitScheduled) {
579
- const goalId = request.goal?.goalId;
580
- if (emitScheduled && goalId) {
581
- this.emitGoalEvent({ type: 'goal_continuation', goalId, phase: 'scheduled', reason });
582
- }
583
- const result = this.submitTurnRequest(request);
584
- if (goalId) {
585
- this.emitGoalEvent({
586
- type: 'goal_continuation',
587
- goalId,
588
- phase: result.type === 'started' ? 'started' : 'deferred',
589
- reason: result.type === 'started' ? reason : `request rejected: ${reason}`,
590
- });
591
- }
592
- return result;
593
- }
594
- // --- v0.2.26: goal continuation scheduling ---
595
- scheduleGoalContinuation() {
596
- const coord = this.goalCoordinator;
597
- if (!coord || !coord.isActive || coord.goal?.status !== 'active')
598
- return;
599
- if (!coord.canContinue) {
600
- this.emitGoalEvent({
601
- type: 'goal_continuation',
602
- goalId: coord.goal.goalId,
603
- phase: 'deferred',
604
- reason: 'coordinator is not eligible to continue',
313
+ async runCommand(command, args) {
314
+ const renderer = this.options.uiRenderer ?? this.options.runtime.config.ui?.renderer ?? 'terminal';
315
+ if (command.rendererScope && !command.rendererScope.includes(renderer)) {
316
+ this.emitAppend({
317
+ role: 'error',
318
+ title: `/${command.name} unavailable`,
319
+ content: `/${command.name} is not available in the ${renderer} renderer. Supported renderers: ${command.rendererScope.join(', ')}.`,
320
+ errorLayer: 'runtime',
321
+ command: commandIdentity(command, false),
605
322
  });
606
323
  return;
607
324
  }
608
- const scheduleEpoch = ++this.continuationScheduleEpoch;
609
- const scheduledGoalId = coord.goal.goalId;
610
- // Defer to next tick to let the current turn's events settle.
611
- setImmediate(() => {
612
- if (scheduleEpoch !== this.continuationScheduleEpoch) {
613
- this.emitGoalEvent({
614
- type: 'goal_continuation',
615
- goalId: scheduledGoalId,
616
- phase: 'deferred',
617
- reason: 'scheduled continuation was invalidated',
618
- });
619
- return;
620
- }
621
- if (this.stopping ||
622
- this.turnController.hasActiveTurn() ||
623
- this.pendingPermissions.size > 0) {
624
- this.emitGoalEvent({
625
- type: 'goal_continuation',
626
- goalId: scheduledGoalId,
627
- phase: 'deferred',
628
- reason: this.stopping
629
- ? 'runtime is stopping'
630
- : this.pendingPermissions.size > 0
631
- ? 'tool permission is pending'
632
- : 'another turn is active',
633
- });
634
- return;
635
- }
636
- if (!coord.isActive || coord.goal?.status !== 'active') {
637
- this.emitGoalEvent({
638
- type: 'goal_continuation',
639
- goalId: scheduledGoalId,
640
- phase: 'deferred',
641
- reason: 'goal is no longer active',
642
- });
643
- return;
644
- }
645
- const req = coord.buildContinuationRequest();
646
- if (req) {
647
- const projected = coord.goal?.lastTurn?.totalTokens ?? 0;
648
- const preflight = (0, accounting_1.budgetPreflight)(coord.goal?.tokensUsed ?? 0, coord.goal?.tokenBudget, projected);
649
- if (!preflight.available) {
650
- try {
651
- coord.limitBudget(preflight.reason ?? 'Token budget unavailable for another turn.');
652
- }
653
- catch (cause) {
654
- const message = this.failClosedGoalMutation(coord, 'budget_stop', cause, false, scheduledGoalId);
655
- this.emitGoalMutationError(message);
656
- return;
657
- }
658
- this.emitGoalEvent({
659
- type: 'goal_continuation',
660
- goalId: coord.goal.goalId,
661
- phase: 'stopped',
662
- reason: preflight.reason ?? 'budget preflight failed',
663
- });
664
- return;
665
- }
666
- this.submitGoalContinuation(req, `continuation ${req.goal.continuationIndex}`, true);
667
- }
668
- else {
669
- this.emitGoalEvent({
670
- type: 'goal_continuation',
671
- goalId: scheduledGoalId,
672
- phase: 'deferred',
673
- reason: 'coordinator did not produce a continuation request',
674
- });
675
- }
676
- });
677
- }
678
- /** v0.2.26: finalize goal turn with usage data from the last loop. */
679
- finalizeGoalTurn(turnId, request, toolContext, startedAt, workspaceFingerprintBefore, turnAborted) {
680
- const coord = this.goalCoordinator;
681
- const requestGoal = request.goal;
682
- const currentSessionId = this.options.runtime.getSession()?.id;
683
- if (!coord?.goal ||
684
- !requestGoal ||
685
- currentSessionId !== request.sessionId ||
686
- coord.boundSessionId !== request.sessionId ||
687
- coord.generation !== request.generation ||
688
- coord.goal.goalId !== requestGoal.goalId) {
689
- if (request.inputKind === 'goal_continuation' && requestGoal) {
690
- this.emitGoalEvent({
691
- type: 'goal_continuation',
692
- goalId: requestGoal.goalId,
693
- phase: 'deferred',
694
- reason: 'turn outcome rejected because its session, goal, revision, or generation is stale',
695
- });
696
- }
697
- return;
325
+ const context = this.createCommandContext();
326
+ const { result, output } = await captureCommandOutput(() => command.execute(context, args));
327
+ const commandMeta = commandIdentity(command, result.success);
328
+ if (output) {
329
+ this.emitAppend({
330
+ role: result.success ? 'system' : 'error',
331
+ title: `/${command.name}`,
332
+ content: output,
333
+ command: commandMeta,
334
+ });
698
335
  }
699
- const usage = this.options.runtime.store.getSnapshot().tokenUsage;
700
- const loopStats = this.options.runtime.store.getSnapshot().lastLoopStats;
701
- const subagentPromptTokens = loopStats?.subagentPromptTokens ?? 0;
702
- const subagentCompletionTokens = loopStats?.subagentCompletionTokens ?? 0;
703
- const subagentTokens = loopStats?.subagentTotalTokens ?? 0;
704
- const workspaceFingerprintAfter = (0, workspace_state_1.captureWorkspaceFingerprint)(this.activeProjectPath());
705
- const workspaceChanged = Boolean(workspaceFingerprintBefore &&
706
- workspaceFingerprintAfter &&
707
- workspaceFingerprintBefore !== workspaceFingerprintAfter);
708
- const usageAccountingComplete = loopStats
709
- ?.usageAccountingComplete !== false;
710
- const outcome = {
711
- turnId: String(turnId),
712
- inputKind: request.inputKind,
713
- sessionId: request.sessionId,
714
- goalId: requestGoal.goalId,
715
- goalRevision: requestGoal.revision,
716
- goalGeneration: request.generation,
717
- startedAt,
718
- endedAt: Date.now(),
719
- finishReason: loopStats?.finishReason ?? 'unknown',
720
- usage: {
721
- promptTokens: Math.max(0, (usage?.promptTokens ?? 0) - subagentPromptTokens),
722
- completionTokens: Math.max(0, (usage?.completionTokens ?? 0) - subagentCompletionTokens),
723
- subagentTokens,
724
- totalTokens: usage !== null
725
- ? (usage?.promptTokens ?? 0) + (usage?.completionTokens ?? 0)
726
- : subagentTokens,
727
- },
728
- madeProgress: goalTurnMadeProgress({
729
- evidenceRecords: toolContext?.evidenceRecords,
730
- pendingPlanUpdate: toolContext?.pendingPlanUpdate,
731
- workspaceFingerprintBefore,
732
- workspaceFingerprintAfter,
733
- }),
734
- workspaceChanged,
735
- providerError: goalProviderError(loopStats?.finishReason, loopStats?.providerLastRetryErrorType),
736
- blocker: toolContext?.pendingBlocker,
737
- pendingTerminalRequest: toolContext?.pendingTerminalRequest,
738
- pendingPlanUpdate: toolContext?.pendingPlanUpdate,
739
- evidenceRecords: toolContext?.evidenceRecords,
740
- workspaceFingerprint: workspaceFingerprintAfter,
741
- evidenceRefs: toolContext?.evidenceRecords.map(record => record.id),
742
- verificationSummary: this.verificationSummary(loopStats),
743
- usageComplete: usageAccountingComplete &&
744
- usage !== null &&
745
- loopStats?.finishReason !== 'failed' &&
746
- (loopStats?.providerRetryCount ?? 0) === 0 &&
747
- (loopStats?.providerFallbackCount ?? 0) === 0,
748
- };
749
- const semanticOutcomeIsCurrent = coord.goal.status === 'active' &&
750
- !turnAborted &&
751
- coord.goal.revision === requestGoal.revision;
752
- if (!semanticOutcomeIsCurrent) {
753
- const accountingOnlyEligible = turnAborted || coord.goal.status === 'paused' || coord.goal.revision > requestGoal.revision;
754
- if (!accountingOnlyEligible) {
755
- if (request.inputKind === 'goal_continuation') {
756
- this.emitGoalEvent({
757
- type: 'goal_continuation',
758
- goalId: requestGoal.goalId,
759
- phase: 'deferred',
760
- reason: 'turn outcome rejected because the Goal lifecycle no longer accepts this turn',
761
- });
762
- }
763
- return;
764
- }
765
- // accountStaleTurn is the coordinator's accounting-only, idempotent
766
- // entry point. An interrupt can leave the Goal revision unchanged, so
767
- // freeze this outcome immediately before the current revision without
768
- // admitting any semantic payload from the cancelled turn.
769
- const accountingOutcome = {
770
- ...outcome,
771
- goalRevision: Math.min(outcome.goalRevision ?? requestGoal.revision, coord.goal.revision - 1),
772
- };
773
- let accounted = false;
774
- try {
775
- const alreadyAccounted = coord.goal.lastTurn?.turnId === String(turnId);
776
- accounted = alreadyAccounted ? false : coord.accountStaleTurn(accountingOutcome);
777
- // Missing/partial provider usage is fail-closed. Known lower-bound
778
- // tokens have already been retained by accountStaleTurn.
779
- if (outcome.usageComplete === false && coord.goal?.status === 'active') {
780
- coord.pause();
781
- }
782
- }
783
- catch (error) {
784
- this.failClosedGoalPersistence(coord, requestGoal.goalId, error, 'stale_accounting');
785
- return;
786
- }
787
- const snapshot = coord.snapshot();
788
- if (accounted && snapshot) {
789
- this.emitGoalEvent({
790
- type: 'goal_updated',
791
- goal: snapshot,
792
- reason: 'interrupted or stale turn usage accounted without semantic finalization',
793
- });
794
- this.recordGoalTraceState(turnId, request, snapshot);
795
- }
796
- if (request.inputKind === 'goal_continuation') {
797
- this.emitGoalEvent({
798
- type: 'goal_continuation',
799
- goalId: requestGoal.goalId,
800
- phase: 'deferred',
801
- reason: 'turn semantic outcome rejected; incurred usage was accounted without continuation',
802
- });
803
- }
804
- return;
336
+ if (result.output) {
337
+ this.emitAppend({
338
+ role: result.success ? 'system' : 'error',
339
+ title: `/${command.name}`,
340
+ content: result.output,
341
+ command: commandMeta,
342
+ });
805
343
  }
806
- // Live steering intentionally bumps the Goal revision before the aborted
807
- // provider turn settles. The semantic payload is stale, but the provider
808
- // usage and elapsed time were still incurred and must be counted once.
809
- const planRevisionBefore = coord.goal.contract?.planSnapshot?.revision;
810
- try {
811
- coord.finalizeTurn(outcome);
344
+ if (result.error) {
345
+ this.emitAppend({
346
+ role: 'error',
347
+ title: `/${command.name}`,
348
+ content: result.error,
349
+ errorLayer: 'runtime',
350
+ command: commandMeta,
351
+ });
812
352
  }
813
- catch (error) {
814
- this.failClosedGoalPersistence(coord, requestGoal.goalId, error, 'turn_finalize');
815
- return;
353
+ if (result.sessionPicker) {
354
+ this.eventSink.emit({ type: 'session_picker_requested', request: result.sessionPicker });
816
355
  }
817
- const snapshot = coord.snapshot();
818
- if (snapshot) {
819
- this.recordGoalTraceState(turnId, request, snapshot);
820
- if (coord.goal?.contract?.planSnapshot &&
821
- coord.goal.contract.planSnapshot.revision !== planRevisionBefore) {
822
- const plan = coord.goal.contract.planSnapshot;
823
- this.emitGoalEvent({
824
- type: 'goal_plan_updated',
825
- goalId: snapshot.goalId,
826
- planRevision: plan.revision,
827
- phase: plan.phase,
828
- nextAction: plan.nextAction,
829
- });
830
- }
831
- let terminalEvent;
832
- if (snapshot.status === 'complete' && coord.goal?.completionAudit) {
833
- terminalEvent = {
834
- type: 'goal_completed',
835
- goal: snapshot,
836
- audit: coord.goal.completionAudit,
837
- };
838
- }
839
- else if (coord.goal?.completionAudit && !coord.goal.completionAudit.passed) {
840
- terminalEvent = {
841
- type: 'goal_audit_failed',
842
- goalId: snapshot.goalId,
843
- audit: 'completion',
844
- summary: coord.goal.completionAudit.remainingRequirements.join(' '),
845
- };
846
- }
847
- else if (toolContext?.pendingTerminalRequest?.requestedStatus === 'blocked' &&
848
- snapshot.status !== 'blocked') {
849
- const blocker = coord.goal?.blocker;
850
- terminalEvent = {
851
- type: 'goal_audit_failed',
852
- goalId: snapshot.goalId,
853
- audit: 'blocked',
854
- summary: blocker
855
- ? `Blocker is not terminal: ${blocker.consecutiveTurns}/3 consecutive turns; no-progress ${coord.goal?.noProgressCount ?? 0}/3.`
856
- : 'Blocked request did not include a valid non-retryable user, permission, or external-state blocker.',
857
- };
858
- }
859
- // Project the fresh snapshot first, then the specific audit/completion
860
- // event. This keeps renderer state current without a generic update
861
- // overwriting the user-facing terminal result.
862
- this.emitGoalEvent({ type: 'goal_updated', goal: snapshot, reason: 'turn_finalized' });
863
- if (terminalEvent)
864
- this.emitGoalEvent(terminalEvent);
865
- if (terminalEvent?.type === 'goal_completed') {
866
- this.autoExitCompletedGoal(coord, snapshot.goalId, 'completion_auto_exit');
867
- }
356
+ if (result.modelPicker) {
357
+ this.eventSink.emit({ type: 'model_picker_requested', request: result.modelPicker });
868
358
  }
869
- }
870
- /**
871
- * Leave Goal mode after a passed completion audit while retaining the
872
- * terminal sidecar as the durable completion receipt. The conditional
873
- * session mutation prevents a stale completion from clearing a newer Goal.
874
- */
875
- autoExitCompletedGoal(coord, goalId, reason) {
876
- if (coord.goal?.goalId !== goalId ||
877
- coord.goal.status !== 'complete' ||
878
- coord.goal.completionAudit?.passed !== true) {
879
- return false;
359
+ if (result.editPreview) {
360
+ this.eventSink.emit({ type: 'edit_preview_requested', request: result.editPreview });
880
361
  }
881
- try {
882
- const { clearSessionGoalBinding } = require('../services/session-storage');
883
- const session = clearSessionGoalBinding(coord.boundSessionId, goalId);
884
- if (!session) {
885
- throw new Error(`Session ${coord.boundSessionId} was not found while clearing Goal mode.`);
886
- }
887
- if (!coord.detachCompletedReceipt(goalId)) {
888
- throw new Error(`Completed Goal ${goalId} could not be detached from the live runtime.`);
889
- }
362
+ if (result.effortEvent) {
363
+ this.eventSink.emit({ type: 'effort_event', event: result.effortEvent });
890
364
  }
891
- catch (cause) {
892
- const detail = (0, redaction_1.redactTraceText)(cause instanceof Error ? cause.message : String(cause)).slice(0, 600);
893
- const message = `Goal completed, but automatic Goal-mode exit could not clear the session binding. The completed Goal remains terminal and will be reconciled on restore. ${detail}`;
894
- this.emitAppend({
895
- role: 'error',
896
- title: 'goal auto-exit',
897
- content: message,
898
- errorLayer: 'session',
365
+ if (result.continueAsChat) {
366
+ const session = this.options.runtime.getSession() ?? this.options.runtime.ensureSession();
367
+ await this.runTurn({
368
+ inputKind: 'user',
369
+ text: result.chatInput ?? args,
370
+ sessionId: session?.id ?? 'pending-session',
371
+ persistAsUserMessage: true,
372
+ echoToTranscript: true,
373
+ generation: 0,
899
374
  });
900
- this.emitStatus(message);
901
- return false;
902
- }
903
- this.continuationScheduleEpoch += 1;
904
- this.rejectPendingPermissions();
905
- if (this.followupQueue.length > 0) {
906
- this.followupQueue.splice(0);
907
- this.emitFollowupQueue();
908
375
  }
909
- this.emitGoalEvent({ type: 'goal_cleared', goalId, reason });
910
- return true;
911
376
  }
912
- failClosedGoalPersistence(coord, goalId, error, operation) {
913
- const message = this.failClosedGoalMutation(coord, operation, error, false, goalId);
914
- this.emitAppend({
915
- role: 'error',
916
- title: 'goal persistence',
917
- content: message,
918
- errorLayer: 'session',
919
- });
920
- this.emitStatus(message);
377
+ createCommandContext() {
378
+ const renderer = this.options.uiRenderer ?? this.options.runtime.config.ui?.renderer ?? 'terminal';
379
+ return {
380
+ cwd: this.options.runtime.cwd,
381
+ config: this.options.runtime.config,
382
+ store: this.options.runtime.store,
383
+ llm: this.options.runtime.llm,
384
+ compactCoordinator: this.options.runtime.compactCoordinator,
385
+ modelCoordinator: this.options.runtime.modelCoordinator,
386
+ sessionId: this.options.runtime.getSession()?.id,
387
+ ensureSession: this.options.runtime.ensureSession,
388
+ setSession: session => this.options.runtime.setSession(session),
389
+ restoreSessionRuntime: this.runner.restoreSession
390
+ ? () => this.runner.restoreSession()
391
+ : undefined,
392
+ sessionRestored: event => this.eventSink.emit({ type: 'session_restored', event }),
393
+ getSession: this.options.runtime.getSession,
394
+ writeOutput: text => {
395
+ if (text.trim())
396
+ this.emitAppend({ role: 'system', content: text });
397
+ },
398
+ writeLine: text => {
399
+ if (text?.trim())
400
+ this.emitAppend({ role: 'system', content: text });
401
+ },
402
+ clearView: () => this.emitClearView(),
403
+ requestShutdown: reason => this.emitShutdownRequested(reason),
404
+ uiRenderer: renderer,
405
+ uiCapabilities: (0, ui_events_1.resolveUiRendererCapabilities)(this.options.uiCapabilities, renderer),
406
+ agentModeLifecycle: this.agentModeLifecycle,
407
+ getHarnessDiagnostics: this.options.runtime.getHarnessDiagnostics,
408
+ compact: this.runner.compact ? input => this.runner.compact(input) : undefined,
409
+ };
921
410
  }
922
- recordGoalTraceState(turnId, request, snapshot) {
923
- if (!request.goal)
924
- return;
925
- const trace = (0, session_storage_1.appendSessionTraceEvent)(request.sessionId, {
926
- turnId: String(turnId),
927
- type: 'goal_state',
928
- goalId: request.goal.goalId,
929
- goalRevision: request.goal.revision,
930
- goalInputKind: request.inputKind,
931
- goalStopReason: snapshot.stopReason ?? (snapshot.status === 'complete' ? 'completed' : 'continue'),
932
- note: `status=${snapshot.status}; snapshotRevision=${snapshot.revision}`,
411
+ submitTurnRequest(request) {
412
+ if (this.turnController.hasActiveTurn())
413
+ return { type: 'command_ignored' };
414
+ if (!this.requestIsCurrent(request))
415
+ return { type: 'command_ignored' };
416
+ this.activeRun = this.runTurn(request)
417
+ .catch(error => {
418
+ this.handleRunLoopError(error);
419
+ })
420
+ .finally(() => {
421
+ this.activeRun = null;
933
422
  });
934
- if (trace)
935
- this.eventSink.emit({ type: 'trace_event_recorded', event: trace });
423
+ return { type: 'started' };
936
424
  }
937
425
  interrupt() {
938
- // v0.2.26: pause active goal on interrupt to prevent immediate restart.
939
- this.deferGoalContinuation('user interrupt', true);
940
- // Register after any synchronous persistence recovery. A lock wait can be
941
- // longer than the confirmation window, but must not consume the user's
942
- // first Ctrl+C before this call even returns.
943
426
  const shouldExit = this.turnController.registerExitIntent();
944
- if (this.turnController.hasActiveTurn()) {
427
+ if (this.turnController.hasActiveTurn() || this.goalControlRuns.size > 0) {
945
428
  this.turnController.interruptActiveTurn();
429
+ this.runner.interrupt?.('user interrupted');
946
430
  if (shouldExit)
947
431
  return { type: 'exit_requested' };
948
432
  this.emitStatus(this.options.interruptedStatus ?? 'Interrupted. Press Ctrl+C again to exit.');
@@ -955,110 +439,24 @@ class AgentRuntimeController {
955
439
  }
956
440
  async stopActiveTurn() {
957
441
  this.stopping = true;
958
- this.deferGoalContinuation('runtime stopping');
959
442
  this.turnController.interruptActiveTurn();
443
+ this.runner.interrupt?.('runtime stopping');
960
444
  this.rejectPendingPermissions();
961
- if (this.activeRun) {
962
- await this.activeRun.catch(() => undefined);
963
- }
445
+ await this.waitForIdle().catch(() => undefined);
964
446
  // Reset stopping flag so subsequent turns can execute.
965
447
  this.stopping = false;
966
448
  }
967
- deferGoalContinuation(reason, preserveExitIntent = false) {
968
- this.continuationScheduleEpoch += 1;
969
- const coord = this.goalCoordinator;
970
- const goalId = coord?.goal?.status === 'active' ? coord.goal.goalId : undefined;
971
- if (!coord || !goalId)
972
- return;
973
- try {
974
- coord.deferContinuation();
975
- }
976
- catch (cause) {
977
- const message = this.failClosedGoalMutation(coord, 'pause', cause, false, goalId, preserveExitIntent);
978
- this.emitGoalMutationError(message);
979
- return;
980
- }
981
- this.emitGoalEvent({
982
- type: 'goal_continuation',
983
- goalId,
984
- phase: 'deferred',
985
- reason,
986
- });
987
- }
988
- /** Revoke all Goal-owned execution before mutating a lifecycle boundary. */
989
- abortGoalOwnedExecution(preserveExitIntent = false) {
990
- this.continuationScheduleEpoch += 1;
991
- if (!preserveExitIntent)
992
- this.turnController.clearExitIntent();
993
- this.turnController.interruptActiveTurn();
994
- this.rejectPendingPermissions();
995
- }
996
- /**
997
- * Contain a failed Goal mutation without writing the restored disk state back.
998
- * The coordinator advances its generation so every in-flight request becomes
999
- * stale, then preserves complete or deleted disk authority as-is.
1000
- */
1001
- failClosedGoalMutation(coord, operation, cause, executionAlreadyRevoked = false, goalIdBeforeMutation, preserveExitIntent = false) {
1002
- if (!executionAlreadyRevoked)
1003
- this.abortGoalOwnedExecution(preserveExitIntent);
1004
- const detail = (0, redaction_1.redactTraceText)(cause instanceof Error ? cause.message : String(cause)).slice(0, 600);
1005
- const operationSubject = operation === 'steering'
1006
- ? 'Steering'
1007
- : operation === 'turn_finalize'
1008
- ? 'Goal turn finalization'
1009
- : operation === 'stale_accounting'
1010
- ? 'Stale Goal accounting'
1011
- : `Target ${operation}`;
1012
- const goalIdBeforeRecovery = coord.goal?.goalId ?? goalIdBeforeMutation;
1013
- const failureReason = `${operationSubject} was not saved; Goal-owned execution was revoked fail-closed. ${detail}`;
1014
- coord.failClosedAfterPersistenceError(failureReason);
1015
- const snapshot = coord.snapshot();
1016
- const message = !snapshot
1017
- ? `${operationSubject} was not saved; disk authority reports that the Goal was deleted. No continuation was started. ${detail}`
1018
- : coord.goal?.status === 'complete'
1019
- ? `${operationSubject} was not saved; the restored completed Goal remains terminal. No continuation was started. ${detail}`
1020
- : `${operationSubject} was not saved; execution was paused fail-closed. Resolve the storage error, then use /target resume. ${detail}`;
1021
- if (snapshot) {
1022
- this.emitGoalEvent({
1023
- type: 'goal_updated',
1024
- goal: snapshot,
1025
- reason: coord.goal?.status === 'complete'
1026
- ? `target_${operation} persistence failed; completed disk authority preserved`
1027
- : `target_${operation} persistence failed; continuation paused fail-closed`,
1028
- });
1029
- }
1030
- else if (goalIdBeforeRecovery) {
1031
- this.emitGoalEvent({
1032
- type: 'goal_cleared',
1033
- goalId: goalIdBeforeRecovery,
1034
- reason: `target_${operation} failed after the Goal was deleted`,
1035
- });
1036
- }
1037
- const deferredGoalId = snapshot?.goalId ?? goalIdBeforeRecovery;
1038
- if (deferredGoalId) {
1039
- this.emitGoalEvent({
1040
- type: 'goal_continuation',
1041
- goalId: deferredGoalId,
1042
- phase: 'deferred',
1043
- reason: `target_${operation} persistence failed`,
1044
- });
1045
- }
1046
- return message;
1047
- }
1048
- waitForIdle() {
1049
- return this.activeRun ?? Promise.resolve();
449
+ async waitForIdle() {
450
+ await Promise.all([this.activeRun ?? Promise.resolve(), ...this.goalControlRuns]);
1050
451
  }
1051
452
  async runTurn(firstRequest) {
1052
453
  let nextRequest = firstRequest;
1053
- let preserveTerminalGoalStatus = false;
1054
454
  while (nextRequest && !this.stopping) {
1055
- this.goalProviderReservedTokens = 0;
1056
455
  if (!this.requestIsCurrent(nextRequest))
1057
456
  break;
1058
457
  const request = nextRequest;
1059
458
  const planCompletionBeforeRequest = this.agentModeLifecycle.completionRevision();
1060
- const nextInput = request.text?.trim() ||
1061
- 'Continue pursuing the active goal from its persisted plan and evidence.';
459
+ const nextInput = request.text?.trim() || 'Continue from the latest durable context.';
1062
460
  if ((this.options.echoSubmittedInput ?? true) &&
1063
461
  request.echoToTranscript &&
1064
462
  !request.alreadyEchoed) {
@@ -1066,44 +464,31 @@ class AgentRuntimeController {
1066
464
  }
1067
465
  this.options.beforeTurn?.(nextInput);
1068
466
  const turn = this.turnController.beginTurn(nextInput);
1069
- const startedAt = Date.now();
1070
- const workspaceFingerprintBefore = (0, workspace_state_1.captureWorkspaceFingerprint)(this.activeProjectPath());
1071
- const coord = this.ensureGoalCoordinator(false);
1072
- const toolContext = coord
1073
- ? { coordinator: coord, request, turnId: String(turn.id), evidenceRecords: [] }
1074
- : undefined;
1075
467
  this.options.runtime.store.setProcessing(true);
1076
468
  this.emitProcessing(true);
1077
469
  const runningStatus = statusText(this.options.runningStatus, nextInput);
1078
470
  if (runningStatus)
1079
471
  this.emitStatus(runningStatus);
1080
472
  try {
1081
- const execute = () => {
1082
- if (this.runner.runRequest) {
1083
- return this.runner.runRequest(request, {
1084
- abortSignal: turn.abortSignal,
1085
- turnId: turn.id,
1086
- });
1087
- }
1088
- return this.runner.runInput(nextInput, {
473
+ if (this.runner.runRequest) {
474
+ await this.runner.runRequest(request, {
1089
475
  abortSignal: turn.abortSignal,
1090
476
  turnId: turn.id,
1091
- persistAsUserMessage: request.persistAsUserMessage,
1092
- inputKind: request.inputKind,
1093
477
  });
1094
- };
1095
- if (toolContext) {
1096
- await (0, tools_1.runWithGoalToolContext)(toolContext, execute);
1097
478
  }
1098
479
  else {
1099
- await execute();
480
+ await this.runner.runInput(nextInput, {
481
+ abortSignal: turn.abortSignal,
482
+ turnId: turn.id,
483
+ persistAsUserMessage: request.persistAsUserMessage,
484
+ inputKind: request.inputKind,
485
+ });
1100
486
  }
1101
487
  }
1102
488
  catch (error) {
1103
489
  if (!turn.abortSignal.aborted) {
1104
- if (this.options.onTurnError) {
490
+ if (this.options.onTurnError)
1105
491
  this.options.onTurnError(error);
1106
- }
1107
492
  else {
1108
493
  const message = error instanceof Error ? error.message : String(error);
1109
494
  this.emitAppend({ role: 'error', content: `Error: ${message}` });
@@ -1112,64 +497,29 @@ class AgentRuntimeController {
1112
497
  }
1113
498
  finally {
1114
499
  const revision = this.turnController.finishTurn(turn.id);
1115
- // v0.2.26: finalize goal turn with usage data.
1116
- this.finalizeGoalTurn(turn.id, request, toolContext, startedAt, workspaceFingerprintBefore, turn.abortSignal.aborted);
1117
- const finalizedGoal = request.goal ? this.goalCoordinator?.goal : undefined;
1118
- preserveTerminalGoalStatus = Boolean(finalizedGoal?.completionAudit ||
1119
- (toolContext?.pendingTerminalRequest?.requestedStatus === 'blocked' &&
1120
- finalizedGoal?.status !== 'blocked'));
1121
500
  const completedPlan = this.agentModeLifecycle.completedPlanSince(planCompletionBeforeRequest) ?? undefined;
1122
- // A shortcut pressed during the turn affects the next logical request,
1123
- // never the permissions or tools of the request that just completed.
1124
- // exit_plan_mode consumes a pending next mode while saving the plan;
1125
- // every other request applies it here at the same boundary.
1126
501
  if (!completedPlan)
1127
502
  this.agentModeLifecycle.applyPending();
1128
503
  if (revision?.trim()) {
1129
- const currentCoord = this.ensureGoalCoordinator(false);
1130
- const currentGoal = currentCoord?.goal?.status === 'active' ? currentCoord.goal : undefined;
1131
- if (request.goal && currentCoord?.goal && !currentGoal) {
1132
- this.emitStatus('Latest instruction was saved, but the Goal is paused because usage accounting is incomplete. Use /target resume after reviewing the budget.');
1133
- nextRequest = undefined;
1134
- }
1135
- else {
1136
- this.emitStatus(this.options.restartingStatus ?? '根据补充调整方向中…');
1137
- nextRequest = {
1138
- inputKind: 'revision',
1139
- text: revision,
1140
- sessionId: this.options.runtime.getSession()?.id ?? request.sessionId,
1141
- goal: currentGoal
1142
- ? {
1143
- goalId: currentGoal.goalId,
1144
- revision: currentGoal.revision,
1145
- continuationIndex: currentGoal.continuationCount,
1146
- }
1147
- : undefined,
1148
- persistAsUserMessage: true,
1149
- echoToTranscript: true,
1150
- // v0.1.3 (G1): the revision was already echoed at submission time.
1151
- alreadyEchoed: true,
1152
- generation: currentCoord?.generation ?? 0,
1153
- };
1154
- }
504
+ this.emitStatus(this.options.restartingStatus ?? '根据补充调整方向中…');
505
+ nextRequest = {
506
+ inputKind: 'revision',
507
+ text: revision,
508
+ sessionId: this.options.runtime.getSession()?.id ?? request.sessionId,
509
+ persistAsUserMessage: true,
510
+ echoToTranscript: true,
511
+ alreadyEchoed: true,
512
+ generation: 0,
513
+ };
1155
514
  }
1156
515
  else if (completedPlan) {
1157
- const currentCoord = this.ensureGoalCoordinator(false);
1158
- const currentGoal = currentCoord?.goal?.status === 'active' ? currentCoord.goal : undefined;
1159
516
  nextRequest = {
1160
517
  inputKind: 'plan_execution',
1161
518
  text: `Execute the saved plan now. Continue autonomously from the plan and verify the result.\n\n${completedPlan}`,
1162
519
  sessionId: this.options.runtime.getSession()?.id ?? request.sessionId,
1163
- goal: currentGoal
1164
- ? {
1165
- goalId: currentGoal.goalId,
1166
- revision: currentGoal.revision,
1167
- continuationIndex: currentGoal.continuationCount,
1168
- }
1169
- : undefined,
1170
520
  persistAsUserMessage: false,
1171
521
  echoToTranscript: false,
1172
- generation: currentCoord?.generation ?? 0,
522
+ generation: 0,
1173
523
  };
1174
524
  this.emitStatus('Plan saved · starting execution in the selected mode.');
1175
525
  }
@@ -1187,7 +537,7 @@ class AgentRuntimeController {
1187
537
  persistAsUserMessage: true,
1188
538
  echoToTranscript: false,
1189
539
  alreadyEchoed: true,
1190
- generation: this.goalCoordinator?.generation ?? 0,
540
+ generation: 0,
1191
541
  }
1192
542
  : undefined;
1193
543
  }
@@ -1199,10 +549,7 @@ class AgentRuntimeController {
1199
549
  const readyStatus = typeof this.options.readyStatus === 'function'
1200
550
  ? this.options.readyStatus()
1201
551
  : this.options.readyStatus;
1202
- // A completion/blocked audit is the authoritative terminal result of the
1203
- // turn. Keep it visible instead of immediately replacing it with the
1204
- // renderer's generic ready snapshot.
1205
- if (readyStatus && !preserveTerminalGoalStatus)
552
+ if (readyStatus)
1206
553
  this.emitStatus(readyStatus);
1207
554
  this.options.afterTurnLoop?.();
1208
555
  }
@@ -1258,154 +605,9 @@ class AgentRuntimeController {
1258
605
  appliesFrom: deferred ? 'next-logical-request' : 'immediate',
1259
606
  };
1260
607
  }
1261
- emitGoalEvent(event) {
1262
- this.eventSink.emit({ type: 'goal_event', event });
1263
- }
1264
608
  requestIsCurrent(request) {
1265
609
  const activeSessionId = this.options.runtime.getSession()?.id;
1266
- if (activeSessionId && request.sessionId !== activeSessionId)
1267
- return false;
1268
- if (!request.goal)
1269
- return true;
1270
- const coord = this.goalCoordinator;
1271
- const goal = coord?.goal;
1272
- return Boolean(coord &&
1273
- goal &&
1274
- coord.boundSessionId === request.sessionId &&
1275
- coord.generation === request.generation &&
1276
- goal.goalId === request.goal.goalId &&
1277
- goal.revision === request.goal.revision &&
1278
- goal.status === 'active');
1279
- }
1280
- verificationSummary(loopStats) {
1281
- if (!loopStats)
1282
- return 'No loop statistics were recorded.';
1283
- const passed = loopStats.verificationPassedCommands ?? [];
1284
- const failed = loopStats.verificationFailedCommands ?? [];
1285
- const missing = loopStats.verificationMissingCommands ?? [];
1286
- return [
1287
- `finish=${loopStats.finishReason}`,
1288
- passed.length ? `passed=${passed.join(', ')}` : '',
1289
- failed.length ? `failed=${failed.join(', ')}` : '',
1290
- missing.length ? `missing=${missing.join(', ')}` : '',
1291
- ]
1292
- .filter(Boolean)
1293
- .join('; ');
1294
- }
1295
- captureGoalEvidence(event) {
1296
- if (event.type !== 'tool_finished')
1297
- return;
1298
- const context = (0, tools_1.currentGoalToolContext)();
1299
- const goal = context?.coordinator.goal;
1300
- if (!context || !goal || goal.status !== 'active')
1301
- return;
1302
- const capturedAt = Date.now();
1303
- const claimedAssertion = event.event.externalAssertion;
1304
- const assertion = claimedAssertion &&
1305
- (0, external_assertion_1.externalAssertionMatchesInvocation)({
1306
- assertion: claimedAssertion,
1307
- name: event.event.name,
1308
- args: event.event.args,
1309
- success: event.event.success,
1310
- skipped: event.event.skipped,
1311
- now: capturedAt,
1312
- })
1313
- ? claimedAssertion
1314
- : undefined;
1315
- const kind = claimedAssertion
1316
- ? 'external'
1317
- : (0, evidence_1.classifyGoalEvidenceKind)(event.event.name, event.event.args);
1318
- if (!kind)
1319
- return;
1320
- const classifiedResult = (0, evidence_1.classifyGoalEvidenceResult)({
1321
- kind,
1322
- success: event.event.success,
1323
- skipped: event.event.skipped,
1324
- summary: event.event.summary,
1325
- error: event.event.error,
1326
- });
1327
- // A successful transport plus display text is never sufficient proof of
1328
- // an external mutation/state. Only runtime-derived typed assertions may
1329
- // promote successful external tool output to passed evidence. Explicit
1330
- // tool failures remain failed so the ledger still records negative proof.
1331
- const result = assertion
1332
- ? assertion.status
1333
- : kind === 'external' && classifiedResult === 'passed'
1334
- ? 'inconclusive'
1335
- : classifiedResult;
1336
- const assertionSubject = assertion
1337
- ? [
1338
- `external ${assertion.action} ${assertion.status}`,
1339
- `provider=${assertion.provider}`,
1340
- `target=${assertion.target}`,
1341
- assertion.observedValue ? `observed=${assertion.observedValue}` : '',
1342
- ]
1343
- .filter(Boolean)
1344
- .join(' ')
1345
- : undefined;
1346
- const goalRuntimeSubject = (0, evidence_1.describeGoalRuntimeEvidence)({
1347
- name: event.event.name,
1348
- success: event.event.success,
1349
- error: event.event.error,
1350
- });
1351
- const record = {
1352
- id: `evidence:${(0, crypto_1.randomUUID)()}`,
1353
- goalId: goal.goalId,
1354
- goalRevision: goal.revision,
1355
- objectiveRevision: goal.contract?.objectiveRevision ?? 0,
1356
- turnId: context.turnId,
1357
- kind,
1358
- subject: (0, redaction_1.redactTraceText)(assertionSubject ||
1359
- goalRuntimeSubject ||
1360
- event.event.summary ||
1361
- event.event.error ||
1362
- event.event.name).slice(0, 512),
1363
- result,
1364
- sourceRef: `tool:${event.event.callId}:${event.event.name}`,
1365
- capturedAt,
1366
- workspaceFingerprint: (0, workspace_state_1.captureWorkspaceFingerprint)(this.activeProjectPath()),
1367
- expiresAt: kind === 'external' ? capturedAt + 5 * 60000 : undefined,
1368
- ...(assertion ? { externalAssertion: assertion } : {}),
1369
- redacted: true,
1370
- };
1371
- context.evidenceRecords.push(record);
1372
- this.emitGoalEvent({
1373
- type: 'goal_evidence_recorded',
1374
- goalId: goal.goalId,
1375
- evidence: {
1376
- id: record.id,
1377
- kind: record.kind,
1378
- result: record.result,
1379
- subject: record.subject,
1380
- },
1381
- });
1382
- }
1383
- restoreGoalForSession(sessionId, projectPath) {
1384
- // A continuation queued by the previously active session must not survive a
1385
- // session switch. It captured the old coordinator and would otherwise be
1386
- // able to start after /resume has rebound the runtime.
1387
- this.continuationScheduleEpoch += 1;
1388
- this.goalCoordinator = null;
1389
- this.goalCoordinatorSessionId = null;
1390
- const coord = this.bindGoalCoordinator(sessionId, true, projectPath, true);
1391
- const snapshot = coord?.snapshot();
1392
- if (!snapshot)
1393
- return;
1394
- if (snapshot.status === 'complete' && coord.goal?.completionAudit?.passed === true) {
1395
- // A completed sidecar with no active binding is a historical receipt,
1396
- // not an active Goal to restore. Only replay the completion lifecycle
1397
- // when recovering the crash window between the terminal write and the
1398
- // conditional binding clear.
1399
- this.emitGoalEvent({ type: 'goal_restored', goal: snapshot });
1400
- this.emitGoalEvent({
1401
- type: 'goal_completed',
1402
- goal: snapshot,
1403
- audit: coord.goal.completionAudit,
1404
- });
1405
- this.autoExitCompletedGoal(coord, snapshot.goalId, 'completion_recovery_auto_exit');
1406
- return;
1407
- }
1408
- this.emitGoalEvent({ type: 'goal_restored', goal: snapshot });
610
+ return !activeSessionId || request.sessionId === activeSessionId;
1409
611
  }
1410
612
  async requestToolPermission(request) {
1411
613
  if (request.abortSignal?.aborted || this.stopping)
@@ -1431,178 +633,49 @@ class AgentRuntimeController {
1431
633
  this.eventSink.emit({ type: 'permission_requested', request: runtimeRequest });
1432
634
  });
1433
635
  }
1434
- // --- v0.2.24: Goal control ---
1435
- handleGoalControl(input) {
1436
- const coord = this.goalCoordinator;
1437
- if (!coord)
1438
- return { type: 'empty' };
1439
- let executionRevoked = false;
1440
- const goalIdBeforeMutation = coord.goal?.goalId;
1441
- try {
1442
- switch (input.action) {
1443
- case 'show':
1444
- // Just shows status — already handled by the renderer format function.
1445
- return { type: 'empty' };
1446
- case 'create': {
1447
- const obj = input.payload?.objective;
1448
- if (!obj)
1449
- return { type: 'empty' };
1450
- const result = coord.create(obj);
1451
- return { type: result.ok ? 'interrupted' : 'empty' };
1452
- }
1453
- case 'pause':
1454
- if (coord.isActive) {
1455
- this.abortGoalOwnedExecution();
1456
- executionRevoked = true;
1457
- }
1458
- return { type: coord.pause() ? 'interrupted' : 'empty' };
1459
- case 'resume':
1460
- return { type: coord.resume() ? 'interrupted' : 'empty' };
1461
- case 'confirm':
1462
- coord.confirmCriterion(input.payload?.criterionId ?? '');
1463
- return { type: 'interrupted' };
1464
- case 'edit': {
1465
- const obj = input.payload?.objective;
1466
- if (obj)
1467
- coord.edit(obj);
1468
- return { type: 'interrupted' };
1469
- }
1470
- case 'replace': {
1471
- const obj = input.payload?.objective;
1472
- if (obj && !coord.replace(obj)) {
1473
- const message = this.failClosedGoalMutation(coord, input.action, new Error('Target could not be replaced.'), executionRevoked, goalIdBeforeMutation);
1474
- this.emitGoalMutationError(message);
1475
- }
1476
- return { type: 'interrupted' };
1477
- }
1478
- case 'set_budget':
1479
- coord.setBudget(input.payload?.tokenBudget ?? null);
1480
- return { type: 'interrupted' };
1481
- case 'clear':
1482
- if (input.payload?.confirmed && coord.goal !== null) {
1483
- this.abortGoalOwnedExecution();
1484
- executionRevoked = true;
1485
- if (!(0, lifecycle_1.clearGoalLifecycle)(coord)) {
1486
- const message = this.failClosedGoalMutation(coord, input.action, new Error('Target clear did not remove the active Goal.'), executionRevoked, goalIdBeforeMutation);
1487
- this.emitGoalMutationError(message);
1488
- }
1489
- }
1490
- return { type: 'interrupted' };
1491
- default:
1492
- return { type: 'empty' };
1493
- }
636
+ startGoalControl(control) {
637
+ const goalControl = normalizeGoalRuntimeControl(control);
638
+ if (!this.runner.controlGoal) {
639
+ const message = 'Goal runtime is unavailable for the active product session.';
640
+ this.emitAppend({ role: 'error', title: 'goal', content: message, errorLayer: 'runtime' });
641
+ this.emitStatus(message);
642
+ return { type: 'command_handled' };
1494
643
  }
1495
- catch (cause) {
1496
- const message = this.failClosedGoalMutation(coord, input.action, cause, executionRevoked, goalIdBeforeMutation);
1497
- this.emitGoalMutationError(message);
1498
- return { type: 'interrupted' };
644
+ if ((this.turnController.hasActiveTurn() || this.goalControlRuns.size > 0) &&
645
+ (goalControl.action === 'create' || goalControl.action === 'resume')) {
646
+ const message = `/goal ${goalControl.action} is unavailable while Goal work is running; use /goal pause or /goal clear first.`;
647
+ this.emitStatus(message);
648
+ return { type: 'command_ignored' };
1499
649
  }
650
+ if (goalControl.action === 'pause' || goalControl.action === 'clear') {
651
+ this.turnController.clearExitIntent();
652
+ this.turnController.interruptActiveTurn();
653
+ this.runner.interrupt?.(`goal ${goalControl.action}`);
654
+ this.rejectPendingPermissions();
655
+ }
656
+ const run = this.runner
657
+ .controlGoal(goalControl)
658
+ .then(result => this.renderGoalControl(result))
659
+ .catch(error => {
660
+ const message = error instanceof Error ? error.message : String(error);
661
+ this.emitAppend({ role: 'error', title: 'goal', content: message, errorLayer: 'runtime' });
662
+ this.emitStatus(message);
663
+ })
664
+ .finally(() => {
665
+ this.goalControlRuns.delete(run);
666
+ });
667
+ this.goalControlRuns.add(run);
668
+ return { type: 'started' };
1500
669
  }
1501
- emitGoalMutationError(message) {
670
+ renderGoalControl(result) {
671
+ const summary = formatGoalRuntimeStatus(result);
1502
672
  this.emitAppend({
1503
- role: 'error',
1504
- title: 'target',
1505
- content: message,
1506
- errorLayer: 'runtime',
673
+ role: result.accepted ? 'system' : 'error',
674
+ title: 'goal',
675
+ content: summary,
676
+ ...(result.accepted ? {} : { errorLayer: 'runtime' }),
1507
677
  });
1508
- this.emitStatus(message);
1509
- }
1510
- ensureGoalCoordinator(ensureSession) {
1511
- if (ensureSession) {
1512
- this.options.runtime.ensureSession();
1513
- }
1514
- const session = this.options.runtime.getSession();
1515
- const sessionId = session?.id;
1516
- if (!sessionId)
1517
- return this.goalCoordinator;
1518
- if (this.goalCoordinator && this.goalCoordinatorSessionId === sessionId) {
1519
- return this.goalCoordinator;
1520
- }
1521
- return this.bindGoalCoordinator(sessionId, true, session.projectPath || this.options.runtime.cwd);
1522
- }
1523
- bindGoalCoordinator(sessionId, recoverActive, projectPath, restoreMissingBinding = false) {
1524
- const { GoalCoordinator } = require('./goals/coordinator');
1525
- const coord = new GoalCoordinator(projectPath, sessionId);
1526
- coord.load(recoverActive);
1527
- if (coord.goal) {
1528
- const { loadSessionMeta, restoreSessionGoalBinding } = require('../services/session-storage');
1529
- const session = loadSessionMeta(sessionId);
1530
- if (coord.goal.status === 'complete' &&
1531
- coord.goal.completionAudit?.passed === true &&
1532
- session?.activeGoalId !== coord.goal.goalId) {
1533
- coord.detachCompletedReceipt(coord.goal.goalId);
1534
- }
1535
- else if (restoreMissingBinding && !session?.activeGoalId) {
1536
- try {
1537
- const restored = session
1538
- ? restoreSessionGoalBinding(sessionId, coord.goal, session.updatedAt ?? session.startTime)
1539
- : null;
1540
- if (!restored) {
1541
- throw new Error(`Session ${sessionId} was not found while restoring its Goal binding.`);
1542
- }
1543
- }
1544
- catch (cause) {
1545
- this.emitAppend({
1546
- role: 'error',
1547
- title: 'target recovery',
1548
- content: `Goal sidecar ${coord.goal.goalId} remains paused, but its session binding could not be restored safely. ${(0, redaction_1.redactTraceText)(cause instanceof Error ? cause.message : String(cause))}`,
1549
- errorLayer: 'session',
1550
- });
1551
- }
1552
- }
1553
- }
1554
- if (coord.lastLoadIssue) {
1555
- this.emitAppend({
1556
- role: 'error',
1557
- title: 'target recovery',
1558
- content: `${coord.lastLoadIssue.code}: ${coord.lastLoadIssue.message}. Run orion doctor for recovery guidance.`,
1559
- errorLayer: 'runtime',
1560
- });
1561
- }
1562
- this.goalCoordinator = coord;
1563
- this.goalCoordinatorSessionId = sessionId;
1564
- if ('setGoalCoordinator' in this.runner) {
1565
- this.runner.setGoalCoordinator(coord);
1566
- }
1567
- return coord;
1568
- }
1569
- activeProjectPath() {
1570
- return this.options.runtime.getSession()?.projectPath || this.options.runtime.cwd;
1571
- }
1572
- formatTargetStatus(coord) {
1573
- const goal = coord.goal;
1574
- if (!goal) {
1575
- return 'Target: no active goal. Use /target <objective> to create one.';
1576
- }
1577
- const objective = goal.objective.length > 60 ? `${goal.objective.slice(0, 57)}...` : goal.objective;
1578
- const tokens = goal.tokensUsed >= 1000 ? `${(goal.tokensUsed / 1000).toFixed(1)}K` : String(goal.tokensUsed);
1579
- const lines = [
1580
- `Target: [${goal.status}] ${objective} | ${goal.continuationCount} turns | ${tokens} tokens${goal.tokenBudget ? ` | budget ${tokens}/${goal.tokenBudget}` : ''}`,
1581
- ];
1582
- const contract = goal.contract;
1583
- const plan = contract?.planSnapshot;
1584
- if (plan) {
1585
- lines.push(`Plan: r${plan.revision} ${plan.phase}${plan.nextAction ? ` | next: ${plan.nextAction}` : ''}`);
1586
- }
1587
- if (contract?.successCriteria.length) {
1588
- const passed = contract.successCriteria.filter(criterion => criterion.status === 'passed').length;
1589
- const failed = contract.successCriteria.filter(criterion => criterion.status === 'failed').length;
1590
- const stale = contract.successCriteria.filter(criterion => criterion.status === 'stale').length;
1591
- const pending = contract.successCriteria.length - passed - failed - stale;
1592
- lines.push(`Criteria: ${pending} pending | ${passed}/${contract.successCriteria.length} passed | ${failed} failed | ${stale} stale`);
1593
- }
1594
- if (goal.completionAudit?.remainingRequirements.length) {
1595
- lines.push(`Audit: ${goal.completionAudit.remainingRequirements.slice(0, 3).join(' | ')}`);
1596
- }
1597
- if (goal.stopReason)
1598
- lines.push(`Resume: ${goal.stopReason.message}`);
1599
- const recentEvidence = (goal.evidenceLedger ?? []).slice(-3);
1600
- if (recentEvidence.length > 0) {
1601
- lines.push(`Evidence: ${recentEvidence
1602
- .map(item => `${item.id} ${item.kind}/${item.result} ${item.subject}`)
1603
- .join(' | ')}`);
1604
- }
1605
- return lines.join('\n');
678
+ this.emitStatus(summary);
1606
679
  }
1607
680
  recordPermissionDecision(requestId, approved, scope = 'once') {
1608
681
  const pending = this.pendingPermissions.get(requestId);
@@ -1656,93 +729,74 @@ class AgentRuntimeController {
1656
729
  entry.finish(false);
1657
730
  }
1658
731
  }
1659
- createChatOptions() {
1660
- const resolvedRenderer = this.options.chatOptions?.uiRenderer ?? this.options.uiRenderer;
1661
- const uiCapabilities = {
1662
- ...(0, ui_events_1.resolveUiRendererCapabilities)(undefined, resolvedRenderer),
1663
- ...(this.options.uiCapabilities ?? {}),
1664
- ...(this.options.chatOptions?.uiCapabilities ?? {}),
1665
- };
1666
- const chatOptions = {
1667
- uiCapabilities,
1668
- uiRenderer: resolvedRenderer,
1669
- agentModeLifecycle: this.agentModeLifecycle,
1670
- onVerificationStateChange: state => this.turnController.setVerificationState(state),
1671
- ...(this.options.chatOptions ?? {}),
732
+ }
733
+ exports.AgentRuntimeController = AgentRuntimeController;
734
+ function formatGoalRuntimeStatus(result) {
735
+ const state = result.state;
736
+ if (!state)
737
+ return result.message;
738
+ const objective = state.objective.length > 80 ? `${state.objective.slice(0, 77)}...` : state.objective;
739
+ return [
740
+ result.message,
741
+ `Goal: [${state.status}] ${objective}`,
742
+ `Progress: ${state.continuationCount} turns · ${state.tokensUsed}/${state.budget.maxTokens} tokens · ${state.elapsedMs}/${state.budget.maxElapsedMs}ms`,
743
+ ].join('\n');
744
+ }
745
+ function normalizeGoalRuntimeControl(control) {
746
+ if (control.action === 'create') {
747
+ return {
748
+ action: 'create',
749
+ objective: control.objective,
750
+ ...(control.budget ? { budget: control.budget } : {}),
1672
751
  };
1673
- chatOptions.uiCapabilities = uiCapabilities;
1674
- chatOptions.uiRenderer = chatOptions.uiRenderer ?? resolvedRenderer;
1675
- chatOptions.onVerificationStateChange =
1676
- chatOptions.onVerificationStateChange ??
1677
- (state => this.turnController.setVerificationState(state));
1678
- if (this.options.useRuntimeToolPermissions && !chatOptions.confirmToolUse) {
1679
- chatOptions.confirmToolUse = request => this.requestToolPermission(request);
1680
- }
1681
- // R6: wire live permission state so the subagent policy gate can prevent
1682
- // background delegation while the user is deciding a tool permission.
1683
- if (!chatOptions.hasPendingPermission) {
1684
- chatOptions.hasPendingPermission = () => this.pendingPermissions.size > 0;
1685
- }
1686
- // R6: wire child usage callback so CostTracker records subagent token
1687
- // consumption, making /cost complete and honest about child agent spend.
1688
- if (!chatOptions.onChildUsage) {
1689
- chatOptions.onChildUsage = (taskId, _role, usage, modelLabel) => {
1690
- const costTracker = this.options.runtime.store.getSnapshot().costTracker;
1691
- costTracker.record({
1692
- promptTokens: usage.promptTokens,
1693
- completionTokens: usage.completionTokens,
1694
- ...(usage.costUsd !== undefined ? { costUsd: usage.costUsd } : {}),
1695
- requestId: `subagent:${taskId}`,
1696
- }, {
1697
- model: modelLabel ?? 'unknown',
1698
- agentId: 'subagent',
1699
- taskId,
1700
- requestKind: 'subagent',
1701
- });
1702
- };
1703
- }
1704
- const configuredPreflight = chatOptions.beforeProviderRequest;
1705
- chatOptions.beforeProviderRequest = async (context) => {
1706
- if (configuredPreflight) {
1707
- const configuredDecision = await configuredPreflight(context);
1708
- if (!configuredDecision.available)
1709
- return configuredDecision;
1710
- }
1711
- const coord = this.goalCoordinator;
1712
- const goal = coord?.goal;
1713
- if (!coord || !goal || goal.status !== 'active' || !goal.tokenBudget) {
1714
- return { available: true };
752
+ }
753
+ return { action: control.action };
754
+ }
755
+ function commandIdentity(command, success) {
756
+ return {
757
+ id: command.id,
758
+ name: command.name,
759
+ source: command.source,
760
+ success,
761
+ };
762
+ }
763
+ async function captureCommandOutput(execute) {
764
+ const lines = [];
765
+ const originalLog = console.log;
766
+ const originalError = console.error;
767
+ const originalWarn = console.warn;
768
+ const capture = (...values) => {
769
+ const line = values
770
+ .map(value => {
771
+ if (typeof value === 'string')
772
+ return value;
773
+ try {
774
+ return JSON.stringify(value);
1715
775
  }
1716
- const projectedTokens = Math.max(1, context.estimatedPromptTokens, goal.lastTurn?.totalTokens ?? 0);
1717
- const decision = (0, accounting_1.budgetPreflight)(goal.tokensUsed + this.goalProviderReservedTokens, goal.tokenBudget, projectedTokens);
1718
- if (!decision.available) {
1719
- try {
1720
- coord.limitBudget(decision.reason ?? 'Token budget unavailable for provider request.');
1721
- }
1722
- catch (cause) {
1723
- const message = this.failClosedGoalMutation(coord, 'provider_budget_stop', cause, false, goal.goalId);
1724
- this.emitGoalMutationError(message);
1725
- return { available: false, reason: message };
1726
- }
1727
- const snapshot = coord.snapshot();
1728
- if (snapshot) {
1729
- this.emitGoalEvent({
1730
- type: 'goal_updated',
1731
- goal: snapshot,
1732
- reason: `provider request ${context.operation} attempt ${context.attempt} rejected by token budget`,
1733
- });
1734
- }
1735
- return decision;
776
+ catch {
777
+ return String(value);
1736
778
  }
1737
- // Reserve the projected cost before the network call. Failed retries and
1738
- // fallbacks keep their reservation because providers may charge attempts
1739
- // that fail before returning usage. Actual successful usage is persisted
1740
- // at turn finalization; reservations reset only when the next root turn starts.
1741
- this.goalProviderReservedTokens += projectedTokens;
1742
- return decision;
1743
- };
1744
- return Object.keys(chatOptions).length > 0 ? chatOptions : undefined;
779
+ })
780
+ .join(' ');
781
+ lines.push((0, style_1.sanitizeTerminalText)(line));
782
+ };
783
+ console.log = capture;
784
+ console.error = capture;
785
+ console.warn = capture;
786
+ try {
787
+ return { result: await execute(), output: lines.join('\n').trim() };
788
+ }
789
+ finally {
790
+ console.log = originalLog;
791
+ console.error = originalError;
792
+ console.warn = originalWarn;
1745
793
  }
1746
794
  }
1747
- exports.AgentRuntimeController = AgentRuntimeController;
795
+ function createUnavailableRunner() {
796
+ return {
797
+ async runInput() {
798
+ throw new Error('No OrionRuntimeV1 runner is configured. Initialize the product runtime before submitting a turn.');
799
+ },
800
+ };
801
+ }
1748
802
  //# sourceMappingURL=agent-runtime-controller.js.map