@kenkaiiii/ggcoder 4.3.232 → 4.3.233

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 (348) hide show
  1. package/README.md +1 -2
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +7 -89
  4. package/dist/cli.js.map +1 -1
  5. package/dist/core/agent-session.d.ts.map +1 -1
  6. package/dist/core/agent-session.js +2 -2
  7. package/dist/core/agent-session.js.map +1 -1
  8. package/dist/core/prompt-commands.d.ts.map +1 -1
  9. package/dist/core/prompt-commands.js +8 -16
  10. package/dist/core/prompt-commands.js.map +1 -1
  11. package/dist/core/prompt-commands.test.js +14 -44
  12. package/dist/core/prompt-commands.test.js.map +1 -1
  13. package/dist/core/runtime-mode.d.ts +0 -11
  14. package/dist/core/runtime-mode.d.ts.map +1 -1
  15. package/dist/core/runtime-mode.js +0 -9
  16. package/dist/core/runtime-mode.js.map +1 -1
  17. package/dist/core/session-restore-display.test.js +4 -110
  18. package/dist/core/session-restore-display.test.js.map +1 -1
  19. package/dist/interactive.d.ts.map +1 -1
  20. package/dist/interactive.js +1 -1
  21. package/dist/interactive.js.map +1 -1
  22. package/dist/system-prompt.d.ts +1 -2
  23. package/dist/system-prompt.d.ts.map +1 -1
  24. package/dist/system-prompt.js +11 -58
  25. package/dist/system-prompt.js.map +1 -1
  26. package/dist/system-prompt.test.js +3 -158
  27. package/dist/system-prompt.test.js.map +1 -1
  28. package/dist/tools/bash.d.ts +1 -4
  29. package/dist/tools/bash.d.ts.map +1 -1
  30. package/dist/tools/bash.js +3 -12
  31. package/dist/tools/bash.js.map +1 -1
  32. package/dist/tools/checkpoint-hook.test.js +3 -3
  33. package/dist/tools/checkpoint-hook.test.js.map +1 -1
  34. package/dist/tools/edit.d.ts +1 -4
  35. package/dist/tools/edit.d.ts.map +1 -1
  36. package/dist/tools/edit.js +5 -13
  37. package/dist/tools/edit.js.map +1 -1
  38. package/dist/tools/enter-plan.js +1 -1
  39. package/dist/tools/enter-plan.js.map +1 -1
  40. package/dist/tools/index.d.ts +0 -9
  41. package/dist/tools/index.d.ts.map +1 -1
  42. package/dist/tools/index.js +4 -8
  43. package/dist/tools/index.js.map +1 -1
  44. package/dist/tools/prompt-hints.d.ts.map +1 -1
  45. package/dist/tools/prompt-hints.js +0 -2
  46. package/dist/tools/prompt-hints.js.map +1 -1
  47. package/dist/tools/screenshot.d.ts +1 -1
  48. package/dist/tools/subagent.d.ts +1 -4
  49. package/dist/tools/subagent.d.ts.map +1 -1
  50. package/dist/tools/subagent.js +2 -5
  51. package/dist/tools/subagent.js.map +1 -1
  52. package/dist/tools/write.d.ts +1 -4
  53. package/dist/tools/write.d.ts.map +1 -1
  54. package/dist/tools/write.js +5 -13
  55. package/dist/tools/write.js.map +1 -1
  56. package/dist/ui/App.d.ts +5 -20
  57. package/dist/ui/App.d.ts.map +1 -1
  58. package/dist/ui/App.js +71 -309
  59. package/dist/ui/App.js.map +1 -1
  60. package/dist/ui/app-items.d.ts +23 -25
  61. package/dist/ui/app-items.d.ts.map +1 -1
  62. package/dist/ui/app-items.js +37 -0
  63. package/dist/ui/app-items.js.map +1 -1
  64. package/dist/ui/app-items.test.d.ts +2 -0
  65. package/dist/ui/app-items.test.d.ts.map +1 -0
  66. package/dist/ui/app-items.test.js +38 -0
  67. package/dist/ui/app-items.test.js.map +1 -0
  68. package/dist/ui/app-state-persistence.test.js +14 -318
  69. package/dist/ui/app-state-persistence.test.js.map +1 -1
  70. package/dist/ui/chat-layout-pinning.test.js +74 -4
  71. package/dist/ui/chat-layout-pinning.test.js.map +1 -1
  72. package/dist/ui/components/AssistantMessage.test.js +6 -9
  73. package/dist/ui/components/AssistantMessage.test.js.map +1 -1
  74. package/dist/ui/components/Banner.js +1 -1
  75. package/dist/ui/components/Banner.js.map +1 -1
  76. package/dist/ui/components/ChatFooterPane.d.ts +1 -5
  77. package/dist/ui/components/ChatFooterPane.d.ts.map +1 -1
  78. package/dist/ui/components/ChatFooterPane.js +3 -4
  79. package/dist/ui/components/ChatFooterPane.js.map +1 -1
  80. package/dist/ui/components/ChatInputStack.d.ts +3 -1
  81. package/dist/ui/components/ChatInputStack.d.ts.map +1 -1
  82. package/dist/ui/components/ChatInputStack.js +4 -3
  83. package/dist/ui/components/ChatInputStack.js.map +1 -1
  84. package/dist/ui/components/ChatScreen.d.ts +3 -16
  85. package/dist/ui/components/ChatScreen.d.ts.map +1 -1
  86. package/dist/ui/components/ChatScreen.js +2 -3
  87. package/dist/ui/components/ChatScreen.js.map +1 -1
  88. package/dist/ui/components/Footer.d.ts +3 -8
  89. package/dist/ui/components/Footer.d.ts.map +1 -1
  90. package/dist/ui/components/Footer.js +5 -25
  91. package/dist/ui/components/Footer.js.map +1 -1
  92. package/dist/ui/components/InputArea.d.ts +1 -9
  93. package/dist/ui/components/InputArea.d.ts.map +1 -1
  94. package/dist/ui/components/InputArea.js +2 -44
  95. package/dist/ui/components/InputArea.js.map +1 -1
  96. package/dist/ui/components/LiveToolPanel.d.ts +30 -0
  97. package/dist/ui/components/LiveToolPanel.d.ts.map +1 -0
  98. package/dist/ui/components/LiveToolPanel.js +66 -0
  99. package/dist/ui/components/LiveToolPanel.js.map +1 -0
  100. package/dist/ui/components/ToolExecution.js +0 -2
  101. package/dist/ui/components/ToolExecution.js.map +1 -1
  102. package/dist/ui/components/TranscriptViewport.d.ts +1 -1
  103. package/dist/ui/components/TranscriptViewport.js +1 -1
  104. package/dist/ui/footer-jump-regression.test.js +12 -2
  105. package/dist/ui/footer-jump-regression.test.js.map +1 -1
  106. package/dist/ui/footer-status-layout.test.js +4 -12
  107. package/dist/ui/footer-status-layout.test.js.map +1 -1
  108. package/dist/ui/hooks/useChatLayoutMeasurements.d.ts +3 -4
  109. package/dist/ui/hooks/useChatLayoutMeasurements.d.ts.map +1 -1
  110. package/dist/ui/hooks/useChatLayoutMeasurements.js +26 -4
  111. package/dist/ui/hooks/useChatLayoutMeasurements.js.map +1 -1
  112. package/dist/ui/hooks/useModeState.d.ts +4 -19
  113. package/dist/ui/hooks/useModeState.d.ts.map +1 -1
  114. package/dist/ui/hooks/useModeState.js +5 -45
  115. package/dist/ui/hooks/useModeState.js.map +1 -1
  116. package/dist/ui/hooks/usePixelFixFlow.js +2 -2
  117. package/dist/ui/layout-decisions.d.ts +11 -34
  118. package/dist/ui/layout-decisions.d.ts.map +1 -1
  119. package/dist/ui/layout-decisions.js +15 -42
  120. package/dist/ui/layout-decisions.js.map +1 -1
  121. package/dist/ui/live-area-height.d.ts.map +1 -1
  122. package/dist/ui/live-area-height.js +6 -1
  123. package/dist/ui/live-area-height.js.map +1 -1
  124. package/dist/ui/live-frame-height.test.js +26 -1
  125. package/dist/ui/live-frame-height.test.js.map +1 -1
  126. package/dist/ui/plan-overlay.test.js +1 -1
  127. package/dist/ui/plan-overlay.test.js.map +1 -1
  128. package/dist/ui/prompt-routing.d.ts +1 -19
  129. package/dist/ui/prompt-routing.d.ts.map +1 -1
  130. package/dist/ui/prompt-routing.js +1 -79
  131. package/dist/ui/prompt-routing.js.map +1 -1
  132. package/dist/ui/render.d.ts +3 -18
  133. package/dist/ui/render.d.ts.map +1 -1
  134. package/dist/ui/render.js +0 -10
  135. package/dist/ui/render.js.map +1 -1
  136. package/dist/ui/scroll-stabilization.test.js +1 -7
  137. package/dist/ui/scroll-stabilization.test.js.map +1 -1
  138. package/dist/ui/slash-command-images.test.js +11 -86
  139. package/dist/ui/slash-command-images.test.js.map +1 -1
  140. package/dist/ui/streaming-flush-bounce.test.d.ts +2 -0
  141. package/dist/ui/streaming-flush-bounce.test.d.ts.map +1 -0
  142. package/dist/ui/streaming-flush-bounce.test.js +156 -0
  143. package/dist/ui/streaming-flush-bounce.test.js.map +1 -0
  144. package/dist/ui/submit-prompt-command.d.ts +1 -16
  145. package/dist/ui/submit-prompt-command.d.ts.map +1 -1
  146. package/dist/ui/submit-prompt-command.js +4 -54
  147. package/dist/ui/submit-prompt-command.js.map +1 -1
  148. package/dist/ui/submit-slash-commands.d.ts +0 -1
  149. package/dist/ui/submit-slash-commands.d.ts.map +1 -1
  150. package/dist/ui/submit-slash-commands.js +0 -4
  151. package/dist/ui/submit-slash-commands.js.map +1 -1
  152. package/dist/ui/terminal-history-status-renderers.d.ts +0 -1
  153. package/dist/ui/terminal-history-status-renderers.d.ts.map +1 -1
  154. package/dist/ui/terminal-history-status-renderers.js +0 -3
  155. package/dist/ui/terminal-history-status-renderers.js.map +1 -1
  156. package/dist/ui/terminal-history.d.ts.map +1 -1
  157. package/dist/ui/terminal-history.js +11 -56
  158. package/dist/ui/terminal-history.js.map +1 -1
  159. package/dist/ui/terminal-history.test.js +6 -33
  160. package/dist/ui/terminal-history.test.js.map +1 -1
  161. package/dist/ui/tool-line-summary.d.ts +29 -0
  162. package/dist/ui/tool-line-summary.d.ts.map +1 -0
  163. package/dist/ui/tool-line-summary.js +153 -0
  164. package/dist/ui/tool-line-summary.js.map +1 -0
  165. package/dist/ui/transcript/TranscriptRenderer.d.ts +1 -1
  166. package/dist/ui/transcript/TranscriptRenderer.d.ts.map +1 -1
  167. package/dist/ui/transcript/TranscriptRenderer.js +18 -12
  168. package/dist/ui/transcript/TranscriptRenderer.js.map +1 -1
  169. package/dist/ui/transcript/presentation.d.ts +1 -17
  170. package/dist/ui/transcript/presentation.d.ts.map +1 -1
  171. package/dist/ui/transcript/presentation.js +0 -26
  172. package/dist/ui/transcript/presentation.js.map +1 -1
  173. package/dist/ui/transcript/spacing.d.ts +2 -2
  174. package/dist/ui/transcript/spacing.d.ts.map +1 -1
  175. package/dist/ui/transcript/spacing.js +14 -9
  176. package/dist/ui/transcript/spacing.js.map +1 -1
  177. package/dist/ui/transcript/spacing.test.js +5 -8
  178. package/dist/ui/transcript/spacing.test.js.map +1 -1
  179. package/dist/ui/transcript/tool-presentation.js +1 -1
  180. package/dist/ui/transcript/tool-presentation.js.map +1 -1
  181. package/dist/ui/transcript/transcript-lines.d.ts.map +1 -1
  182. package/dist/ui/transcript/transcript-lines.js +4 -0
  183. package/dist/ui/transcript/transcript-lines.js.map +1 -1
  184. package/dist/ui/tui-history-parity.test.js +0 -47
  185. package/dist/ui/tui-history-parity.test.js.map +1 -1
  186. package/dist/ui/tui-simulation.test.js +2 -1
  187. package/dist/ui/tui-simulation.test.js.map +1 -1
  188. package/package.json +4 -4
  189. package/dist/core/goal-controller.d.ts +0 -82
  190. package/dist/core/goal-controller.d.ts.map +0 -1
  191. package/dist/core/goal-controller.js +0 -838
  192. package/dist/core/goal-controller.js.map +0 -1
  193. package/dist/core/goal-controller.test.d.ts +0 -2
  194. package/dist/core/goal-controller.test.d.ts.map +0 -1
  195. package/dist/core/goal-controller.test.js +0 -1279
  196. package/dist/core/goal-controller.test.js.map +0 -1
  197. package/dist/core/goal-engine.d.ts +0 -61
  198. package/dist/core/goal-engine.d.ts.map +0 -1
  199. package/dist/core/goal-engine.js +0 -123
  200. package/dist/core/goal-engine.js.map +0 -1
  201. package/dist/core/goal-engine.test.d.ts +0 -2
  202. package/dist/core/goal-engine.test.d.ts.map +0 -1
  203. package/dist/core/goal-engine.test.js +0 -295
  204. package/dist/core/goal-engine.test.js.map +0 -1
  205. package/dist/core/goal-integration.d.ts +0 -80
  206. package/dist/core/goal-integration.d.ts.map +0 -1
  207. package/dist/core/goal-integration.js +0 -296
  208. package/dist/core/goal-integration.js.map +0 -1
  209. package/dist/core/goal-integration.test.d.ts +0 -2
  210. package/dist/core/goal-integration.test.d.ts.map +0 -1
  211. package/dist/core/goal-integration.test.js +0 -369
  212. package/dist/core/goal-integration.test.js.map +0 -1
  213. package/dist/core/goal-lifecycle-smoke.test.d.ts +0 -2
  214. package/dist/core/goal-lifecycle-smoke.test.d.ts.map +0 -1
  215. package/dist/core/goal-lifecycle-smoke.test.js +0 -248
  216. package/dist/core/goal-lifecycle-smoke.test.js.map +0 -1
  217. package/dist/core/goal-overhead-harness.d.ts +0 -33
  218. package/dist/core/goal-overhead-harness.d.ts.map +0 -1
  219. package/dist/core/goal-overhead-harness.js +0 -268
  220. package/dist/core/goal-overhead-harness.js.map +0 -1
  221. package/dist/core/goal-prerequisites.d.ts +0 -23
  222. package/dist/core/goal-prerequisites.d.ts.map +0 -1
  223. package/dist/core/goal-prerequisites.js +0 -114
  224. package/dist/core/goal-prerequisites.js.map +0 -1
  225. package/dist/core/goal-prerequisites.test.d.ts +0 -2
  226. package/dist/core/goal-prerequisites.test.d.ts.map +0 -1
  227. package/dist/core/goal-prerequisites.test.js +0 -154
  228. package/dist/core/goal-prerequisites.test.js.map +0 -1
  229. package/dist/core/goal-references.d.ts +0 -14
  230. package/dist/core/goal-references.d.ts.map +0 -1
  231. package/dist/core/goal-references.js +0 -153
  232. package/dist/core/goal-references.js.map +0 -1
  233. package/dist/core/goal-references.test.d.ts +0 -2
  234. package/dist/core/goal-references.test.d.ts.map +0 -1
  235. package/dist/core/goal-references.test.js +0 -77
  236. package/dist/core/goal-references.test.js.map +0 -1
  237. package/dist/core/goal-store.d.ts +0 -289
  238. package/dist/core/goal-store.d.ts.map +0 -1
  239. package/dist/core/goal-store.js +0 -1156
  240. package/dist/core/goal-store.js.map +0 -1
  241. package/dist/core/goal-store.test.d.ts +0 -2
  242. package/dist/core/goal-store.test.d.ts.map +0 -1
  243. package/dist/core/goal-store.test.js +0 -530
  244. package/dist/core/goal-store.test.js.map +0 -1
  245. package/dist/core/goal-verifier.d.ts +0 -17
  246. package/dist/core/goal-verifier.d.ts.map +0 -1
  247. package/dist/core/goal-verifier.js +0 -87
  248. package/dist/core/goal-verifier.js.map +0 -1
  249. package/dist/core/goal-verifier.test.d.ts +0 -2
  250. package/dist/core/goal-verifier.test.d.ts.map +0 -1
  251. package/dist/core/goal-verifier.test.js +0 -131
  252. package/dist/core/goal-verifier.test.js.map +0 -1
  253. package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts +0 -2
  254. package/dist/core/goal-worker-dev-server-lifecycle.test.d.ts.map +0 -1
  255. package/dist/core/goal-worker-dev-server-lifecycle.test.js +0 -68
  256. package/dist/core/goal-worker-dev-server-lifecycle.test.js.map +0 -1
  257. package/dist/core/goal-worker.d.ts +0 -61
  258. package/dist/core/goal-worker.d.ts.map +0 -1
  259. package/dist/core/goal-worker.js +0 -467
  260. package/dist/core/goal-worker.js.map +0 -1
  261. package/dist/core/goal-worker.test.d.ts +0 -2
  262. package/dist/core/goal-worker.test.d.ts.map +0 -1
  263. package/dist/core/goal-worker.test.js +0 -493
  264. package/dist/core/goal-worker.test.js.map +0 -1
  265. package/dist/core/goal-worktree.d.ts +0 -108
  266. package/dist/core/goal-worktree.d.ts.map +0 -1
  267. package/dist/core/goal-worktree.js +0 -300
  268. package/dist/core/goal-worktree.js.map +0 -1
  269. package/dist/core/goal-worktree.test.d.ts +0 -2
  270. package/dist/core/goal-worktree.test.d.ts.map +0 -1
  271. package/dist/core/goal-worktree.test.js +0 -448
  272. package/dist/core/goal-worktree.test.js.map +0 -1
  273. package/dist/tools/goal-mode.test.d.ts +0 -2
  274. package/dist/tools/goal-mode.test.d.ts.map +0 -1
  275. package/dist/tools/goal-mode.test.js +0 -121
  276. package/dist/tools/goal-mode.test.js.map +0 -1
  277. package/dist/tools/goals.d.ts +0 -143
  278. package/dist/tools/goals.d.ts.map +0 -1
  279. package/dist/tools/goals.js +0 -1038
  280. package/dist/tools/goals.js.map +0 -1
  281. package/dist/tools/goals.test.d.ts +0 -2
  282. package/dist/tools/goals.test.d.ts.map +0 -1
  283. package/dist/tools/goals.test.js +0 -1444
  284. package/dist/tools/goals.test.js.map +0 -1
  285. package/dist/ui/components/GoalOverlay.d.ts +0 -83
  286. package/dist/ui/components/GoalOverlay.d.ts.map +0 -1
  287. package/dist/ui/components/GoalOverlay.js +0 -710
  288. package/dist/ui/components/GoalOverlay.js.map +0 -1
  289. package/dist/ui/components/GoalPickerMenu.d.ts +0 -9
  290. package/dist/ui/components/GoalPickerMenu.d.ts.map +0 -1
  291. package/dist/ui/components/GoalPickerMenu.js +0 -37
  292. package/dist/ui/components/GoalPickerMenu.js.map +0 -1
  293. package/dist/ui/components/GoalStatusBar.d.ts +0 -26
  294. package/dist/ui/components/GoalStatusBar.d.ts.map +0 -1
  295. package/dist/ui/components/GoalStatusBar.js +0 -130
  296. package/dist/ui/components/GoalStatusBar.js.map +0 -1
  297. package/dist/ui/components/GoalStatusBar.test.d.ts +0 -2
  298. package/dist/ui/components/GoalStatusBar.test.d.ts.map +0 -1
  299. package/dist/ui/components/GoalStatusBar.test.js +0 -17
  300. package/dist/ui/components/GoalStatusBar.test.js.map +0 -1
  301. package/dist/ui/goal-events.d.ts +0 -125
  302. package/dist/ui/goal-events.d.ts.map +0 -1
  303. package/dist/ui/goal-events.js +0 -407
  304. package/dist/ui/goal-events.js.map +0 -1
  305. package/dist/ui/goal-events.test.d.ts +0 -2
  306. package/dist/ui/goal-events.test.d.ts.map +0 -1
  307. package/dist/ui/goal-events.test.js +0 -416
  308. package/dist/ui/goal-events.test.js.map +0 -1
  309. package/dist/ui/goal-lifecycle-orchestration.test.d.ts +0 -2
  310. package/dist/ui/goal-lifecycle-orchestration.test.d.ts.map +0 -1
  311. package/dist/ui/goal-lifecycle-orchestration.test.js +0 -555
  312. package/dist/ui/goal-lifecycle-orchestration.test.js.map +0 -1
  313. package/dist/ui/goal-overlay.test.d.ts +0 -2
  314. package/dist/ui/goal-overlay.test.d.ts.map +0 -1
  315. package/dist/ui/goal-overlay.test.js +0 -384
  316. package/dist/ui/goal-overlay.test.js.map +0 -1
  317. package/dist/ui/goal-progress.d.ts +0 -31
  318. package/dist/ui/goal-progress.d.ts.map +0 -1
  319. package/dist/ui/goal-progress.js +0 -149
  320. package/dist/ui/goal-progress.js.map +0 -1
  321. package/dist/ui/goal-run-helpers.d.ts +0 -12
  322. package/dist/ui/goal-run-helpers.d.ts.map +0 -1
  323. package/dist/ui/goal-run-helpers.js +0 -42
  324. package/dist/ui/goal-run-helpers.js.map +0 -1
  325. package/dist/ui/goal-status-bar.test.d.ts +0 -2
  326. package/dist/ui/goal-status-bar.test.d.ts.map +0 -1
  327. package/dist/ui/goal-status-bar.test.js +0 -174
  328. package/dist/ui/goal-status-bar.test.js.map +0 -1
  329. package/dist/ui/goal-summary.d.ts +0 -14
  330. package/dist/ui/goal-summary.d.ts.map +0 -1
  331. package/dist/ui/goal-summary.js +0 -194
  332. package/dist/ui/goal-summary.js.map +0 -1
  333. package/dist/ui/hooks/useGoalOrchestration.d.ts +0 -82
  334. package/dist/ui/hooks/useGoalOrchestration.d.ts.map +0 -1
  335. package/dist/ui/hooks/useGoalOrchestration.js +0 -863
  336. package/dist/ui/hooks/useGoalOrchestration.js.map +0 -1
  337. package/dist/ui/hooks/useGoalPickerController.d.ts +0 -22
  338. package/dist/ui/hooks/useGoalPickerController.d.ts.map +0 -1
  339. package/dist/ui/hooks/useGoalPickerController.js +0 -35
  340. package/dist/ui/hooks/useGoalPickerController.js.map +0 -1
  341. package/dist/ui/prompt-routing.test.d.ts +0 -2
  342. package/dist/ui/prompt-routing.test.d.ts.map +0 -1
  343. package/dist/ui/prompt-routing.test.js +0 -48
  344. package/dist/ui/prompt-routing.test.js.map +0 -1
  345. package/dist/ui/transcript/GoalRows.d.ts +0 -10
  346. package/dist/ui/transcript/GoalRows.d.ts.map +0 -1
  347. package/dist/ui/transcript/GoalRows.js +0 -35
  348. package/dist/ui/transcript/GoalRows.js.map +0 -1
@@ -1,1038 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { z } from "zod";
3
- import { log } from "../core/logger.js";
4
- import { canCompleteGoalRun, decideGoalNextAction, hasFreshGoalCompletionAudit, } from "../core/goal-controller.js";
5
- import { runGoalPrerequisiteCheckCommand } from "../core/goal-prerequisites.js";
6
- import { appendGoalBlockers, appendGoalDecision, appendGoalEvidence, createGoalEvidence, foldGoalTaskIntegration, formatGoalBlockingPrerequisiteList, formatGoalBlockingPrerequisites, getActiveGoalRun, getGoalRun, goalHasBlockingPrerequisites, loadGoalRuns, upsertGoalRun, updateGoalTask, } from "../core/goal-store.js";
7
- import { removeGoalRunWorktrees } from "../core/goal-worktree.js";
8
- import { referencesRequiringAcknowledgement } from "../core/goal-references.js";
9
- import { getActiveGoalMode } from "../core/runtime-mode.js";
10
- const PrerequisiteInput = z.object({
11
- id: z.string().optional().describe("Stable prerequisite id"),
12
- label: z.string().describe("Human-readable prerequisite label"),
13
- status: z.enum(["unknown", "met", "missing"]).optional(),
14
- kind: z
15
- .enum(["local", "external"])
16
- .optional()
17
- .describe("'local' = agent can satisfy it locally (default when check_command is set); 'external' = genuinely user-supplied input (paid creds, secrets, approvals, devices) that blocks the Goal. Reserve 'external' for true user prerequisites."),
18
- check_command: z.string().optional().describe("Optional command used to check this prerequisite"),
19
- instructions: z.string().optional().describe("What the user must provide when missing"),
20
- evidence: z.string().optional().describe("Short evidence, never secret values"),
21
- });
22
- const HarnessInput = z.object({
23
- id: z.string().optional().describe("Stable harness item id"),
24
- label: z.string().describe("Harness/diagnostic label"),
25
- command: z.string().optional().describe("Command that runs this harness item"),
26
- path: z.string().optional().describe("File path for a harness artifact"),
27
- description: z.string().optional().describe("What this harness observes or verifies"),
28
- });
29
- const EvidencePlanInput = z.object({
30
- id: z.string().optional().describe("Stable evidence-plan item id"),
31
- label: z.string().describe("Short evidence path label"),
32
- mechanism: z
33
- .enum([
34
- "command",
35
- "test",
36
- "script",
37
- "fixture",
38
- "log",
39
- "screenshot",
40
- "video",
41
- "browser",
42
- "device",
43
- "source",
44
- "file",
45
- "manual",
46
- ])
47
- .describe("How this proof will be gathered"),
48
- description: z.string().describe("What this evidence proves"),
49
- status: z.enum(["planned", "ready", "blocked"]).optional(),
50
- command: z.string().optional().describe("Runnable command when available"),
51
- path: z.string().optional().describe("Artifact path when available"),
52
- instructions: z.string().optional().describe("Exact user instructions when blocked"),
53
- evidence: z.string().optional().describe("Observed evidence summary when ready"),
54
- });
55
- const GoalsParams = z.object({
56
- action: z
57
- .enum([
58
- "create",
59
- "prerequisite",
60
- "task",
61
- "evidence",
62
- "evidence_plan",
63
- "verify",
64
- "audit",
65
- "status",
66
- "pause",
67
- "resume",
68
- "complete",
69
- ])
70
- .describe("Goal action to perform"),
71
- run_id: z.string().optional().describe("Goal run id; omitted actions use the active/latest run"),
72
- title: z.string().optional().describe("Goal or task title"),
73
- goal: z.string().optional().describe("Original user objective for create"),
74
- success_criteria: z
75
- .array(z.string())
76
- .optional()
77
- .describe("Concrete criteria that must be proven before completion"),
78
- prerequisites: z
79
- .array(PrerequisiteInput)
80
- .optional()
81
- .describe("Prerequisites that must be met before launching workers"),
82
- prerequisite_id: z.string().optional().describe("Prerequisite id to update"),
83
- prerequisite_status: z
84
- .enum(["unknown", "met", "missing"])
85
- .optional()
86
- .describe("Updated prerequisite status"),
87
- prerequisite_label: z.string().optional().describe("Label for an added/updated prerequisite"),
88
- instructions: z.string().optional().describe("User-facing instructions for missing prerequisite"),
89
- harness: z.array(HarnessInput).optional().describe("Harness/diagnostic commands and files"),
90
- evidence_plan: z
91
- .array(EvidencePlanInput)
92
- .optional()
93
- .describe("Planned proof paths for end-to-end verification"),
94
- evidence_plan_item_id: z.string().optional().describe("Evidence-plan item id to update"),
95
- evidence_plan_status: z
96
- .enum(["planned", "ready", "blocked"])
97
- .optional()
98
- .describe("Updated evidence-plan item status"),
99
- evidence: z.string().optional().describe("Observed evidence summary for an evidence-plan update"),
100
- path: z.string().optional().describe("Artifact path for an evidence-plan update"),
101
- verifier_command: z.string().optional().describe("Command that verifies the goal end-to-end"),
102
- verifier_description: z.string().optional().describe("Natural-language verifier description"),
103
- verifier_cwd: z
104
- .string()
105
- .optional()
106
- .describe("Working directory for the verifier command; use a worker worktree path only when the verifier artifact lives there"),
107
- task_id: z.string().optional().describe("Goal task id to update"),
108
- task_title: z.string().optional().describe("Short worker task title"),
109
- task_prompt: z
110
- .string()
111
- .optional()
112
- .describe("Standalone prompt for a disposable Goal worker in this same project"),
113
- task_status: z
114
- .enum(["pending", "running", "verifying", "done", "failed", "blocked"])
115
- .optional()
116
- .describe("Goal task status"),
117
- depends_on: z
118
- .array(z.string())
119
- .optional()
120
- .describe("Task ids that must be done before this task can start"),
121
- parallel_group: z
122
- .string()
123
- .optional()
124
- .describe("Coordinator-defined batch/group for tasks that may run in parallel"),
125
- expected_changed_scope: z
126
- .array(z.string())
127
- .optional()
128
- .describe("Expected file paths or globs this task is allowed or expected to change"),
129
- integration: z
130
- .enum(["candidate", "manual"])
131
- .optional()
132
- .describe("Whether this task's committed candidate should be auto-integrated into main or handled manually"),
133
- merge_strategy: z
134
- .enum(["parallel_candidate", "after_dependencies", "serial", "manual"])
135
- .optional()
136
- .describe("Deprecated legacy integration field; use integration='candidate' or integration='manual'. Legacy non-manual values fold to candidate."),
137
- worker_id: z.string().optional().describe("Worker id associated with a task"),
138
- attempts: z.number().int().min(0).optional().describe("Task attempt count"),
139
- summary: z
140
- .string()
141
- .optional()
142
- .describe("Short summary or verification note. For action='audit' with verification_status='pass', just describe in plain prose which durable artifacts you compared and reference any mandatory non-prompt Goal references: the system auto-stamps FINAL_AUDIT_PASS and verifier_checked_at and fills output_path from the recorded verifier run, so do NOT transcribe the timestamp yourself. Any remaining contract gaps are returned all at once."),
143
- evidence_kind: z
144
- .enum(["log", "command", "screenshot", "file", "summary"])
145
- .optional()
146
- .describe("Evidence kind"),
147
- evidence_label: z.string().optional().describe("Evidence label"),
148
- evidence_path: z.string().optional().describe("Evidence file/log/screenshot path"),
149
- evidence_content: z.string().optional().describe("Short evidence content"),
150
- verification_status: z
151
- .enum(["pass", "fail", "unknown"])
152
- .optional()
153
- .describe("Verifier result status"),
154
- exit_code: z.number().int().optional().describe("Verifier command exit code"),
155
- output_path: z.string().optional().describe("Path to verifier output/log"),
156
- blockers: z.array(z.string()).optional().describe("Current blockers"),
157
- });
158
- function asPrerequisiteStatus(value) {
159
- if (value === "met" || value === "missing" || value === "unknown")
160
- return value;
161
- return "unknown";
162
- }
163
- function requiresPrerequisiteCheck(status, evidence) {
164
- return status === "unknown" || (status === "met" && !evidence?.trim());
165
- }
166
- function uncheckedPrerequisiteInstructions(label) {
167
- return `Check ${label} locally and record non-secret evidence before workers can start.`;
168
- }
169
- async function normalizePrerequisiteInput(cwd, item) {
170
- const requestedStatus = asPrerequisiteStatus(item.status);
171
- const id = item.id ?? randomUUID();
172
- const kindField = item.kind ? { kind: item.kind } : {};
173
- if (item.check_command && requiresPrerequisiteCheck(requestedStatus, item.evidence)) {
174
- const result = await runGoalPrerequisiteCheckCommand({ cwd, command: item.check_command });
175
- return {
176
- id,
177
- label: item.label,
178
- status: result.status,
179
- ...kindField,
180
- checkCommand: item.check_command,
181
- evidence: result.evidence,
182
- ...(result.status === "missing" || item.instructions
183
- ? { instructions: item.instructions ?? `Make \`${item.check_command}\` pass locally.` }
184
- : {}),
185
- };
186
- }
187
- return {
188
- id,
189
- label: item.label,
190
- status: requestedStatus,
191
- ...kindField,
192
- ...(item.check_command ? { checkCommand: item.check_command } : {}),
193
- ...(item.instructions ? { instructions: item.instructions } : {}),
194
- ...(item.evidence ? { evidence: item.evidence } : {}),
195
- ...(requiresPrerequisiteCheck(requestedStatus, item.evidence) && !item.instructions
196
- ? { instructions: uncheckedPrerequisiteInstructions(item.label) }
197
- : {}),
198
- };
199
- }
200
- function asTaskStatus(value) {
201
- if (value === "pending" ||
202
- value === "running" ||
203
- value === "verifying" ||
204
- value === "done" ||
205
- value === "failed" ||
206
- value === "blocked") {
207
- return value;
208
- }
209
- return "pending";
210
- }
211
- function asTaskIntegration(integration, legacyMergeStrategy) {
212
- if (integration === "candidate" || integration === "manual")
213
- return integration;
214
- if (legacyMergeStrategy === "parallel_candidate" ||
215
- legacyMergeStrategy === "after_dependencies" ||
216
- legacyMergeStrategy === "serial" ||
217
- legacyMergeStrategy === "manual") {
218
- return foldGoalTaskIntegration(legacyMergeStrategy);
219
- }
220
- return undefined;
221
- }
222
- function asEvidenceKind(value) {
223
- if (value === "log" ||
224
- value === "command" ||
225
- value === "screenshot" ||
226
- value === "file" ||
227
- value === "summary") {
228
- return value;
229
- }
230
- return "summary";
231
- }
232
- function asEvidencePlanStatus(value) {
233
- if (value === "ready" || value === "blocked" || value === "planned")
234
- return value;
235
- return "planned";
236
- }
237
- function asEvidenceMechanism(value) {
238
- if (value === "command" ||
239
- value === "test" ||
240
- value === "script" ||
241
- value === "fixture" ||
242
- value === "log" ||
243
- value === "screenshot" ||
244
- value === "video" ||
245
- value === "browser" ||
246
- value === "device" ||
247
- value === "source" ||
248
- value === "file" ||
249
- value === "manual") {
250
- return value;
251
- }
252
- return "command";
253
- }
254
- function asVerificationStatus(value) {
255
- if (value === "pass" || value === "fail" || value === "unknown")
256
- return value;
257
- return "unknown";
258
- }
259
- function formatRun(run) {
260
- const prereqs = run.prerequisites.length
261
- ? `${run.prerequisites.filter((item) => item.status === "met").length}/${run.prerequisites.length} prereqs met`
262
- : "no prereqs";
263
- const tasks = run.tasks.length
264
- ? `${run.tasks.filter((item) => item.status === "done").length}/${run.tasks.length} tasks done`
265
- : "no tasks";
266
- const verifier = run.verifier?.lastResult
267
- ? `verifier ${run.verifier.lastResult.status}`
268
- : run.verifier?.command
269
- ? "verifier configured"
270
- : "no verifier";
271
- const refs = run.references?.length ? `, ${run.references.length} reference(s)` : "";
272
- const audit = run.completionAudit
273
- ? `, final audit ${run.completionAudit.status}`
274
- : run.verifier?.lastResult?.status === "pass"
275
- ? ", final audit missing"
276
- : "";
277
- const blocker = goalHasBlockingPrerequisites(run)
278
- ? `\nUser prerequisites: ${formatGoalBlockingPrerequisites(run)}`
279
- : "";
280
- return `[${run.status}] ${run.title} (id: ${run.id.slice(0, 8)}) — ${prereqs}, ${tasks}, ${verifier}${refs}${audit}${blocker}`;
281
- }
282
- function recoverableTaskStatus(status) {
283
- return status === "pending" || status === "failed";
284
- }
285
- function statusAfterTaskPatch(run, status) {
286
- if ((run.status !== "failed" && run.status !== "passed") || !recoverableTaskStatus(status)) {
287
- return run.status;
288
- }
289
- return goalHasBlockingPrerequisites(run) ? "blocked" : "ready";
290
- }
291
- function resolveTaskDependencyIds(run, dependencies, currentTaskId) {
292
- if (!dependencies)
293
- return { ok: true, value: [] };
294
- const resolved = [];
295
- for (const dependency of dependencies) {
296
- const trimmed = dependency.trim();
297
- if (!trimmed)
298
- continue;
299
- const matches = run.tasks.filter((task) => task.id !== currentTaskId &&
300
- (task.id === trimmed || task.id.startsWith(trimmed) || task.title === trimmed));
301
- if (matches.length === 0) {
302
- return {
303
- ok: false,
304
- error: `depends_on entry "${trimmed}" does not match an existing task id, id prefix, or exact title. Add the dependency task first (its id is returned when you add it), then reference that id or its exact title — not a parallel_group name.`,
305
- };
306
- }
307
- if (matches.length > 1) {
308
- return {
309
- ok: false,
310
- error: `depends_on entry "${trimmed}" is ambiguous; use a full task id.`,
311
- };
312
- }
313
- const id = matches[0]?.id;
314
- if (id && !resolved.includes(id))
315
- resolved.push(id);
316
- }
317
- return { ok: true, value: resolved };
318
- }
319
- const SETUP_BLOCKER_PREFIX = "Goal setup incomplete:";
320
- function referenceMentionTokens(reference) {
321
- return [reference.id, reference.label, reference.value, reference.path]
322
- .filter((token) => !!token?.trim())
323
- .map((token) => token.toLowerCase());
324
- }
325
- function unacknowledgedReferences(references, fields) {
326
- const haystack = fields.join("\n").toLowerCase();
327
- return referencesRequiringAcknowledgement(references ?? []).filter((reference) => !referenceMentionTokens(reference).some((token) => haystack.includes(token)));
328
- }
329
- function referencesAcknowledged(references, fields) {
330
- return unacknowledgedReferences(references, fields).length === 0;
331
- }
332
- function hasOriginalGoalPromptReference(references) {
333
- return (references ?? []).some((reference) => reference.id === "original-goal-prompt" &&
334
- reference.kind === "prompt" &&
335
- reference.content?.trim());
336
- }
337
- function setupBlockersForRun(run) {
338
- const blockers = [];
339
- const contractFields = [
340
- run.goal ?? "",
341
- ...run.successCriteria,
342
- ...(run.references ?? []).map((reference) => `${reference.id} ${reference.label} ${reference.content ?? ""}`),
343
- ...(run.evidence ?? []).map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
344
- ].join("\n");
345
- const requiresReliabilityContract = /GOAL_PLAN/.test(contractFields);
346
- if (requiresReliabilityContract && !hasOriginalGoalPromptReference(run.references)) {
347
- blockers.push(`${SETUP_BLOCKER_PREFIX} durable [original-goal-prompt] reference is required.`);
348
- }
349
- const plannerFields = [
350
- run.goal ?? "",
351
- ...(run.evidence ?? []).map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
352
- ].join("\n");
353
- if (requiresReliabilityContract &&
354
- (!/GOAL_PLAN/.test(plannerFields) ||
355
- !/research=/.test(plannerFields) ||
356
- !/success=/.test(plannerFields))) {
357
- blockers.push(`${SETUP_BLOCKER_PREFIX} durable planner GOAL_PLAN evidence/state is required.`);
358
- }
359
- if (run.successCriteria.length === 0)
360
- blockers.push(`${SETUP_BLOCKER_PREFIX} success criteria are required.`);
361
- if (run.evidencePlan.length === 0)
362
- blockers.push(`${SETUP_BLOCKER_PREFIX} evidence_plan is required.`);
363
- if (!run.verifier?.command)
364
- blockers.push(`${SETUP_BLOCKER_PREFIX} verifier_command is required.`);
365
- const referenceFields = [
366
- ...run.successCriteria,
367
- ...run.evidencePlan.map((item) => `${item.id} ${item.label} ${item.description} ${item.command ?? ""} ${item.path ?? ""} ${item.evidence ?? ""}`),
368
- ...run.tasks.map((task) => `${task.title} ${task.prompt}`),
369
- run.verifier?.description ?? "",
370
- run.verifier?.command ?? "",
371
- ];
372
- const missingReferences = unacknowledgedReferences(run.references, referenceFields);
373
- if (missingReferences.length > 0) {
374
- blockers.push(`${SETUP_BLOCKER_PREFIX} every non-prompt Goal reference must be named in success criteria, task prompts, evidence_plan, or verifier metadata. Missing: ${missingReferences.map((reference) => reference.id).join(", ")}.`);
375
- }
376
- return blockers;
377
- }
378
- function blockersAfterSetupCheck(run, setupBlockers) {
379
- if (run.status !== "draft")
380
- return run.blockers;
381
- return Array.from(new Set([
382
- ...run.blockers.filter((blocker) => !blocker.startsWith(SETUP_BLOCKER_PREFIX)),
383
- ...setupBlockers,
384
- ]));
385
- }
386
- function statusAfterSetupCheck(run, setupBlockers) {
387
- if (run.status !== "draft")
388
- return run.status;
389
- if (setupBlockers.length > 0)
390
- return "draft";
391
- return goalHasBlockingPrerequisites(run) ? "blocked" : "ready";
392
- }
393
- /**
394
- * Stamp the structured tokens the system already owns into a pass-audit summary
395
- * so the agent never has to transcribe them: an explicit FINAL_AUDIT_PASS marker
396
- * and the exact verifier_checked_at timestamp from the recorded verifier run.
397
- */
398
- function normalizePassAuditSummary(verifierCheckedAt, summary) {
399
- let next = summary.trim() || "Final completion audit passed.";
400
- if (!next.startsWith("FINAL_AUDIT_PASS"))
401
- next = `FINAL_AUDIT_PASS ${next}`;
402
- if (!next.includes(`verifier_checked_at=${verifierCheckedAt}`)) {
403
- next = `${next} verifier_checked_at=${verifierCheckedAt}`;
404
- }
405
- return next;
406
- }
407
- /**
408
- * Validate a pass-audit summary against the completion contract. Returns every
409
- * unmet requirement at once (not one at a time) so the caller can fix them in a
410
- * single follow-up instead of round-tripping per rule. Expects the summary to
411
- * already be normalized via {@link normalizePassAuditSummary}, so in practice
412
- * only the semantic requirements (reference acknowledgement, GOAL_PLAN) remain.
413
- */
414
- function validatePassAuditContract(run, summary, outputPath) {
415
- const verifier = run.verifier?.lastResult;
416
- if (!verifier)
417
- return "cannot audit completion before a verifier result exists.";
418
- const violations = [];
419
- if (!summary.startsWith("FINAL_AUDIT_PASS")) {
420
- violations.push("summary must start with FINAL_AUDIT_PASS");
421
- }
422
- if (!summary.includes(`verifier_checked_at=${verifier.checkedAt}`)) {
423
- violations.push(`summary must include verifier_checked_at=${verifier.checkedAt}`);
424
- }
425
- if (!outputPath && !summary.match(/(?:output|artifact|log|path)=\S+/)) {
426
- violations.push("provide output_path, or reference an output/artifact/log/path in the summary");
427
- }
428
- const contractFields = [
429
- run.goal,
430
- ...run.successCriteria,
431
- ...(run.references ?? []).map((reference) => `${reference.id} ${reference.label} ${reference.content ?? ""}`),
432
- ...run.evidence.map((item) => `${item.label}\n${item.path ?? ""}\n${item.content ?? ""}`),
433
- ].join("\n");
434
- const requiresReliabilityContract = /GOAL_PLAN/.test(contractFields);
435
- if (requiresReliabilityContract && !summary.includes("original-goal-prompt")) {
436
- violations.push("summary must explicitly reference original-goal-prompt");
437
- }
438
- if (requiresReliabilityContract && !summary.includes("GOAL_PLAN")) {
439
- violations.push("summary must explicitly reference durable GOAL_PLAN evidence");
440
- }
441
- if (!referencesAcknowledged(run.references, [summary, outputPath ?? ""])) {
442
- violations.push("summary or output_path must explicitly reference every non-prompt Goal reference id, label, URL, or path");
443
- }
444
- if (violations.length === 0)
445
- return undefined;
446
- return violations.map((violation, index) => `(${index + 1}) ${violation}`).join("; ");
447
- }
448
- async function resolveRun(cwd, id) {
449
- if (id)
450
- return getGoalRun(cwd, id);
451
- return getActiveGoalRun(cwd);
452
- }
453
- function goalStorageCwd(cwd) {
454
- return process.env.GG_GOAL_PROJECT_PATH || cwd;
455
- }
456
- export function createGoalsTool(cwd, goalModeRef, getGoalReferences) {
457
- const storageCwd = goalStorageCwd(cwd);
458
- return {
459
- name: "goals",
460
- description: "Manage durable Goal runs for /goal and Ctrl+G workflows. Use this instead of tasks when the user wants a programmatic goal loop: define success criteria first, check prerequisites before launching workers, persist harness/diagnostics/evidence, add standalone worker tasks, record final completion audits, and only mark the goal complete when verifier plus final-audit evidence proves the original objective. Do not require paid services or signups without recording a blocker and asking the user for the missing prerequisite.",
461
- parameters: GoalsParams,
462
- executionMode: "sequential",
463
- async execute(args) {
464
- if (getActiveGoalMode(goalModeRef) === "planner") {
465
- return "Error: goals is restricted in Goal planner mode. Emit a compact GOAL_PLAN block only; setup creates durable Goal state.";
466
- }
467
- switch (args.action) {
468
- case "create": {
469
- if (!args.title)
470
- return "Error: title is required for create.";
471
- if (!args.goal)
472
- return "Error: goal is required for create.";
473
- const existing = args.run_id ? await getGoalRun(storageCwd, args.run_id) : null;
474
- const prerequisites = args.prerequisites
475
- ? await Promise.all(args.prerequisites.map((item) => normalizePrerequisiteInput(storageCwd, item)))
476
- : undefined;
477
- const harness = args.harness?.map((item) => ({
478
- id: item.id ?? randomUUID(),
479
- label: item.label,
480
- ...(item.command ? { command: item.command } : {}),
481
- ...(item.path ? { path: item.path } : {}),
482
- ...(item.description ? { description: item.description } : {}),
483
- }));
484
- const evidencePlan = args.evidence_plan?.map((item) => ({
485
- id: item.id ?? randomUUID(),
486
- label: item.label,
487
- mechanism: asEvidenceMechanism(item.mechanism),
488
- description: item.description,
489
- status: item.status ?? "planned",
490
- ...(item.command ? { command: item.command } : {}),
491
- ...(item.path ? { path: item.path } : {}),
492
- ...(item.instructions ? { instructions: item.instructions } : {}),
493
- ...(item.evidence ? { evidence: item.evidence } : {}),
494
- }));
495
- const verifier = args.verifier_command || args.verifier_description || args.verifier_cwd
496
- ? {
497
- description: args.verifier_description ?? existing?.verifier?.description ?? "Goal verifier",
498
- ...((args.verifier_command ?? existing?.verifier?.command)
499
- ? { command: args.verifier_command ?? existing?.verifier?.command }
500
- : {}),
501
- ...((args.verifier_cwd ?? existing?.verifier?.cwd)
502
- ? { cwd: args.verifier_cwd ?? existing?.verifier?.cwd }
503
- : {}),
504
- ...(existing?.verifier?.lastResult
505
- ? { lastResult: existing.verifier.lastResult }
506
- : {}),
507
- }
508
- : existing?.verifier;
509
- const nextPrerequisites = prerequisites ?? existing?.prerequisites ?? [];
510
- const missingPrerequisites = formatGoalBlockingPrerequisiteList(nextPrerequisites);
511
- const hasBlockingPrerequisites = missingPrerequisites !== "Goal has no missing user prerequisites.";
512
- const references = [...(getGoalReferences?.() ?? existing?.references ?? [])];
513
- const plannerEvidence = args.summary?.includes("GOAL_PLAN")
514
- ? [
515
- createGoalEvidence({
516
- kind: "summary",
517
- label: "Planner GOAL_PLAN",
518
- content: args.summary,
519
- }),
520
- ]
521
- : undefined;
522
- const draftProbe = {
523
- goal: args.goal,
524
- successCriteria: args.success_criteria ?? existing?.successCriteria ?? [],
525
- evidencePlan: evidencePlan ?? existing?.evidencePlan ?? [],
526
- references,
527
- tasks: existing?.tasks ?? [],
528
- evidence: plannerEvidence ?? existing?.evidence ?? [],
529
- verifier,
530
- };
531
- const setupBlockers = setupBlockersForRun(draftProbe);
532
- const priorBlockers = (args.blockers ?? existing?.blockers ?? []).filter((blocker) => !blocker.startsWith(SETUP_BLOCKER_PREFIX));
533
- const blockers = Array.from(new Set([
534
- ...priorBlockers,
535
- ...(hasBlockingPrerequisites ? [missingPrerequisites] : []),
536
- ...setupBlockers,
537
- ]));
538
- const run = await upsertGoalRun(storageCwd, {
539
- ...(args.run_id ? { id: args.run_id } : {}),
540
- title: args.title,
541
- goal: args.goal,
542
- status: setupBlockers.length > 0
543
- ? "draft"
544
- : hasBlockingPrerequisites
545
- ? "blocked"
546
- : existing?.status === "draft"
547
- ? "ready"
548
- : (existing?.status ?? "ready"),
549
- successCriteria: draftProbe.successCriteria,
550
- prerequisites: nextPrerequisites,
551
- harness: harness ?? existing?.harness ?? [],
552
- evidencePlan: draftProbe.evidencePlan,
553
- references: draftProbe.references,
554
- ...(plannerEvidence
555
- ? { evidence: [...(existing?.evidence ?? []), ...plannerEvidence] }
556
- : {}),
557
- ...(verifier ? { verifier } : {}),
558
- blockers,
559
- });
560
- await appendGoalDecision(storageCwd, run.id, {
561
- kind: args.run_id ? "update" : "create",
562
- reason: `criteria=${run.successCriteria.length}; prerequisites=${run.prerequisites.length}; harness=${run.harness.length}; evidence_plan=${run.evidencePlan.length}; references=${run.references?.length ?? 0}; verifier=${run.verifier?.command ? "configured" : "missing"}`,
563
- });
564
- log("INFO", "goals", `Goal created: ${run.title}`, { id: run.id, status: run.status });
565
- const setupMessage = setupBlockers.length > 0 ? ` Setup blockers: ${setupBlockers.join(" ")}` : "";
566
- return goalHasBlockingPrerequisites(run)
567
- ? `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}). User prerequisites: ${formatGoalBlockingPrerequisites(run)}${setupMessage}`
568
- : `Goal ${args.run_id ? "updated" : "created"}: "${run.title}" (id: ${run.id.slice(0, 8)}, ${run.status}).${setupMessage}`;
569
- }
570
- case "status": {
571
- if (args.run_id) {
572
- const run = await getGoalRun(storageCwd, args.run_id);
573
- return run ? formatRun(run) : `Error: no goal found matching id "${args.run_id}".`;
574
- }
575
- const runs = await loadGoalRuns(storageCwd);
576
- if (runs.length === 0)
577
- return "No goals.";
578
- return runs.map(formatRun).join("\n");
579
- }
580
- case "prerequisite": {
581
- const run = await resolveRun(storageCwd, args.run_id);
582
- if (!run)
583
- return "Error: no active goal run found.";
584
- const prereqId = args.prerequisite_id;
585
- if (!prereqId && !args.prerequisite_label) {
586
- return "Error: prerequisite_id or prerequisite_label is required.";
587
- }
588
- const prerequisites = [...run.prerequisites];
589
- const index = prereqId
590
- ? prerequisites.findIndex((item) => item.id === prereqId || item.id.startsWith(prereqId))
591
- : -1;
592
- const existingPrerequisite = index >= 0 ? prerequisites[index] : undefined;
593
- const patch = {
594
- id: prereqId ?? randomUUID(),
595
- label: args.prerequisite_label ?? existingPrerequisite?.label ?? prereqId ?? "Prerequisite",
596
- status: asPrerequisiteStatus(args.prerequisite_status),
597
- ...(args.instructions ? { instructions: args.instructions } : {}),
598
- ...(args.summary ? { evidence: args.summary } : {}),
599
- ...(asPrerequisiteStatus(args.prerequisite_status) === "met" && !args.summary
600
- ? {
601
- instructions: args.instructions ??
602
- uncheckedPrerequisiteInstructions(args.prerequisite_label ??
603
- existingPrerequisite?.label ??
604
- prereqId ??
605
- "Prerequisite"),
606
- }
607
- : {}),
608
- };
609
- if (index >= 0) {
610
- prerequisites[index] = {
611
- ...prerequisites[index],
612
- ...patch,
613
- id: prerequisites[index].id,
614
- };
615
- }
616
- else {
617
- prerequisites.push(patch);
618
- }
619
- const prerequisiteRun = {
620
- ...run,
621
- prerequisites,
622
- status: goalHasBlockingPrerequisites({ ...run, prerequisites }) ? "blocked" : "ready",
623
- blockers: goalHasBlockingPrerequisites({ ...run, prerequisites }) ? run.blockers : [],
624
- };
625
- const setupBlockers = setupBlockersForRun(prerequisiteRun);
626
- const updated = await upsertGoalRun(storageCwd, {
627
- ...prerequisiteRun,
628
- status: statusAfterSetupCheck(prerequisiteRun, setupBlockers),
629
- blockers: blockersAfterSetupCheck(prerequisiteRun, setupBlockers),
630
- });
631
- await appendGoalDecision(storageCwd, updated.id, {
632
- kind: "prerequisites",
633
- reason: `Prerequisite ${patch.label} is ${patch.status}; run is ${updated.status}.`,
634
- });
635
- return goalHasBlockingPrerequisites(updated)
636
- ? `Prerequisite updated for "${updated.title}" (${updated.status}). User prerequisites: ${formatGoalBlockingPrerequisites(updated)}`
637
- : `User prerequisites complete for "${updated.title}". Goal is ready to run.`;
638
- }
639
- case "task": {
640
- const run = await resolveRun(storageCwd, args.run_id);
641
- if (!run)
642
- return "Error: no active goal run found.";
643
- if (!args.task_id && (!args.task_title || !args.task_prompt)) {
644
- return "Error: task_title and task_prompt are required when adding a task.";
645
- }
646
- const taskId = args.task_id ?? randomUUID();
647
- const existingTask = run.tasks.find((task) => task.id === taskId || task.id.startsWith(taskId));
648
- const taskExisted = existingTask !== undefined;
649
- if (!taskExisted && (!args.task_title || !args.task_prompt)) {
650
- return "Error: task_title and task_prompt are required when adding a task.";
651
- }
652
- if (!taskExisted) {
653
- const missingReferences = unacknowledgedReferences(run.references, [
654
- args.task_title ?? "",
655
- args.task_prompt ?? "",
656
- ]);
657
- if (missingReferences.length > 0) {
658
- return `Error: task_prompt must explicitly include each non-prompt Goal reference id, label, URL, or path so workers cannot silently ignore the user's references. Missing: ${missingReferences.map((reference) => reference.id).join(", ")}.`;
659
- }
660
- }
661
- const taskStatus = asTaskStatus(args.task_status);
662
- const taskIntegration = asTaskIntegration(args.integration, args.merge_strategy);
663
- const resolvedDependencies = resolveTaskDependencyIds(run, args.depends_on, taskId);
664
- if (!resolvedDependencies.ok)
665
- return `Error: ${resolvedDependencies.error}`;
666
- const updated = await updateGoalTask(storageCwd, run.id, taskId, {
667
- id: taskId,
668
- ...(args.task_title ? { title: args.task_title } : {}),
669
- ...(args.task_prompt ? { prompt: args.task_prompt } : {}),
670
- status: taskStatus,
671
- ...(args.worker_id ? { workerId: args.worker_id } : {}),
672
- ...(args.attempts !== undefined ? { attempts: args.attempts } : {}),
673
- ...(args.depends_on ? { dependsOn: resolvedDependencies.value } : {}),
674
- ...(args.parallel_group ? { parallelGroup: args.parallel_group } : {}),
675
- ...(args.expected_changed_scope
676
- ? { expectedChangedScope: args.expected_changed_scope }
677
- : {}),
678
- ...(taskIntegration ? { integration: taskIntegration } : {}),
679
- ...(args.summary ? { lastSummary: args.summary } : {}),
680
- });
681
- const recovered = updated
682
- ? await (async () => {
683
- const taskPatchedRun = {
684
- ...updated,
685
- status: statusAfterTaskPatch(updated, taskStatus),
686
- };
687
- const setupBlockers = setupBlockersForRun(taskPatchedRun);
688
- return upsertGoalRun(updated.projectPath, {
689
- ...taskPatchedRun,
690
- status: statusAfterSetupCheck(taskPatchedRun, setupBlockers),
691
- blockers: blockersAfterSetupCheck(taskPatchedRun, setupBlockers),
692
- });
693
- })()
694
- : null;
695
- if (!recovered)
696
- return `Error: no task found matching id "${taskId}".`;
697
- const updatedTask = recovered.tasks.find((task) => task.id === existingTask?.id || task.id === taskId || task.id.startsWith(taskId));
698
- return `Goal task ${taskExisted ? "updated" : "added"}: "${updatedTask?.title ?? args.task_title ?? taskId}" (id: ${updatedTask?.id ?? taskId}). Reference this id (or the exact title) in another task's depends_on.`;
699
- }
700
- case "evidence": {
701
- const run = await resolveRun(storageCwd, args.run_id);
702
- if (!run)
703
- return "Error: no active goal run found.";
704
- if (!args.evidence_label && !args.summary)
705
- return "Error: evidence_label or summary is required.";
706
- const updated = await appendGoalEvidence(storageCwd, run.id, {
707
- kind: asEvidenceKind(args.evidence_kind),
708
- label: args.evidence_label ?? "Evidence",
709
- ...(args.evidence_path ? { path: args.evidence_path } : {}),
710
- ...(args.evidence_content || args.summary
711
- ? { content: args.evidence_content ?? args.summary }
712
- : {}),
713
- });
714
- if (!updated)
715
- return "Error: failed to append evidence.";
716
- return `Evidence added to "${updated.title}".`;
717
- }
718
- case "evidence_plan": {
719
- const run = await resolveRun(storageCwd, args.run_id);
720
- if (!run)
721
- return "Error: no active goal run found.";
722
- const evidencePlan = [...run.evidencePlan];
723
- if (args.evidence_plan?.length) {
724
- let added = 0;
725
- let updatedCount = 0;
726
- for (const item of args.evidence_plan) {
727
- const itemId = item.id ?? randomUUID();
728
- const nextItem = {
729
- id: itemId,
730
- label: item.label,
731
- mechanism: asEvidenceMechanism(item.mechanism),
732
- description: item.description,
733
- status: item.status ?? "planned",
734
- ...(item.command ? { command: item.command } : {}),
735
- ...(item.path ? { path: item.path } : {}),
736
- ...(item.instructions ? { instructions: item.instructions } : {}),
737
- ...(item.evidence ? { evidence: item.evidence } : {}),
738
- };
739
- const index = evidencePlan.findIndex((existing) => existing.id === itemId || existing.id.startsWith(itemId));
740
- if (index >= 0) {
741
- evidencePlan[index] = nextItem;
742
- updatedCount += 1;
743
- }
744
- else {
745
- evidencePlan.push(nextItem);
746
- added += 1;
747
- }
748
- }
749
- const evidencePlanRun = { ...run, evidencePlan };
750
- const setupBlockers = setupBlockersForRun(evidencePlanRun);
751
- const updated = await upsertGoalRun(storageCwd, {
752
- ...evidencePlanRun,
753
- status: statusAfterSetupCheck(evidencePlanRun, setupBlockers),
754
- blockers: blockersAfterSetupCheck(evidencePlanRun, setupBlockers),
755
- });
756
- await appendGoalDecision(storageCwd, updated.id, {
757
- kind: "evidence_plan",
758
- reason: `Evidence-plan items upserted: ${added} added, ${updatedCount} updated.`,
759
- });
760
- if (args.evidence_plan.length === 1) {
761
- const item = args.evidence_plan[0];
762
- return `Evidence-plan item ${added === 1 ? "added" : "updated"} for "${updated.title}": "${item?.label ?? "Evidence"}".`;
763
- }
764
- return `Evidence-plan items upserted for "${updated.title}": ${added} added, ${updatedCount} updated.`;
765
- }
766
- const evidencePlanItemId = args.evidence_plan_item_id;
767
- if (!evidencePlanItemId)
768
- return "Error: evidence_plan_item_id or evidence_plan is required.";
769
- const index = evidencePlan.findIndex((item) => item.id === evidencePlanItemId || item.id.startsWith(evidencePlanItemId));
770
- if (index < 0) {
771
- return `Error: no evidence-plan item found matching id "${args.evidence_plan_item_id}".`;
772
- }
773
- const existing = evidencePlan[index];
774
- const status = asEvidencePlanStatus(args.evidence_plan_status);
775
- const evidence = args.evidence ?? args.evidence_content ?? args.summary;
776
- const path = args.path ?? args.evidence_path;
777
- evidencePlan[index] = {
778
- ...existing,
779
- status,
780
- ...(args.instructions ? { instructions: args.instructions } : {}),
781
- ...(evidence ? { evidence } : {}),
782
- ...(path ? { path } : {}),
783
- };
784
- const canRecoverBlockedRun = run.status === "blocked" && status === "ready" && !goalHasBlockingPrerequisites(run);
785
- const evidencePlanRun = {
786
- ...run,
787
- evidencePlan,
788
- status: canRecoverBlockedRun ? "ready" : run.status,
789
- blockers: canRecoverBlockedRun ? [] : run.blockers,
790
- };
791
- const setupBlockers = setupBlockersForRun(evidencePlanRun);
792
- const updated = await upsertGoalRun(storageCwd, {
793
- ...evidencePlanRun,
794
- status: statusAfterSetupCheck(evidencePlanRun, setupBlockers),
795
- blockers: blockersAfterSetupCheck(evidencePlanRun, setupBlockers),
796
- });
797
- await appendGoalDecision(storageCwd, updated.id, {
798
- kind: "evidence_plan",
799
- reason: `Evidence-plan item ${existing.label} is ${status}.`,
800
- });
801
- return `Evidence-plan item updated for "${updated.title}": "${existing.label}" is ${status}.`;
802
- }
803
- case "verify": {
804
- const run = await resolveRun(storageCwd, args.run_id);
805
- if (!run)
806
- return "Error: no active goal run found.";
807
- const result = {
808
- status: asVerificationStatus(args.verification_status),
809
- summary: args.summary ?? "Verifier recorded.",
810
- ...((args.verifier_command ?? run.verifier?.command)
811
- ? { command: args.verifier_command ?? run.verifier?.command }
812
- : {}),
813
- ...(args.exit_code !== undefined ? { exitCode: args.exit_code } : {}),
814
- ...(args.output_path ? { outputPath: args.output_path } : {}),
815
- checkedAt: new Date().toISOString(),
816
- };
817
- const runWithVerifier = {
818
- ...run,
819
- verifier: {
820
- description: args.verifier_description ?? run.verifier?.description ?? "Goal verifier",
821
- ...((args.verifier_command ?? run.verifier?.command)
822
- ? { command: args.verifier_command ?? run.verifier?.command }
823
- : {}),
824
- ...((args.verifier_cwd ?? run.verifier?.cwd)
825
- ? { cwd: args.verifier_cwd ?? run.verifier?.cwd }
826
- : {}),
827
- lastResult: result,
828
- },
829
- ...(result.status === "pass"
830
- ? {
831
- completionAudit: {
832
- status: "unknown",
833
- summary: "Final completion audit pending for latest verifier result.",
834
- checkedAt: result.checkedAt,
835
- verifierCheckedAt: result.checkedAt,
836
- ...(result.outputPath ? { outputPath: result.outputPath } : {}),
837
- },
838
- }
839
- : {}),
840
- evidence: [
841
- ...run.evidence,
842
- createGoalEvidence({
843
- kind: "command",
844
- label: "Verifier result",
845
- content: result.summary,
846
- ...(result.outputPath ? { path: result.outputPath } : {}),
847
- }),
848
- ],
849
- };
850
- const completion = canCompleteGoalRun(runWithVerifier);
851
- const updated = await upsertGoalRun(storageCwd, {
852
- ...runWithVerifier,
853
- status: result.status === "pass" && completion.ok
854
- ? "passed"
855
- : result.status === "pass"
856
- ? goalHasBlockingPrerequisites(runWithVerifier)
857
- ? "blocked"
858
- : "ready"
859
- : result.status === "fail"
860
- ? goalHasBlockingPrerequisites(runWithVerifier)
861
- ? "blocked"
862
- : "ready"
863
- : "verifying",
864
- blockers: result.status === "pass" ? [] : run.blockers,
865
- activeWorkerId: undefined,
866
- });
867
- return `Verifier recorded for "${updated.title}": ${result.status}.`;
868
- }
869
- case "audit": {
870
- const run = await resolveRun(storageCwd, args.run_id);
871
- if (!run)
872
- return "Error: no active goal run found.";
873
- const verifierResult = run.verifier?.lastResult;
874
- if (!verifierResult || verifierResult.status !== "pass") {
875
- return "Error: cannot audit completion before a passing verifier result exists.";
876
- }
877
- const auditStatus = asVerificationStatus(args.verification_status);
878
- const auditOutputPath = args.output_path ?? verifierResult.outputPath;
879
- let auditSummary = args.summary ?? "Final completion audit recorded.";
880
- if (auditStatus === "pass") {
881
- // Auto-stamp the tokens the system already owns, then report any
882
- // remaining contract gaps all at once instead of one per call.
883
- auditSummary = normalizePassAuditSummary(verifierResult.checkedAt, auditSummary);
884
- const contractError = validatePassAuditContract(run, auditSummary, auditOutputPath);
885
- if (contractError) {
886
- return `Error: final completion audit pass is missing required proof: ${contractError}.`;
887
- }
888
- }
889
- const completionAudit = {
890
- status: auditStatus,
891
- summary: auditSummary,
892
- checkedAt: new Date().toISOString(),
893
- verifierCheckedAt: verifierResult.checkedAt,
894
- ...(auditOutputPath ? { outputPath: auditOutputPath } : {}),
895
- };
896
- const runWithAudit = {
897
- ...run,
898
- completionAudit,
899
- evidence: [
900
- ...run.evidence,
901
- createGoalEvidence({
902
- kind: "summary",
903
- label: `Final completion audit ${completionAudit.status}`,
904
- content: completionAudit.summary,
905
- ...(completionAudit.outputPath ? { path: completionAudit.outputPath } : {}),
906
- }),
907
- ],
908
- };
909
- const auditCheck = hasFreshGoalCompletionAudit(runWithAudit);
910
- const completion = canCompleteGoalRun(runWithAudit);
911
- const updated = await upsertGoalRun(storageCwd, {
912
- ...runWithAudit,
913
- status: completionAudit.status === "pass" && auditCheck.ok && completion.ok
914
- ? "passed"
915
- : goalHasBlockingPrerequisites(runWithAudit)
916
- ? "blocked"
917
- : "ready",
918
- blockers: completionAudit.status === "pass" && auditCheck.ok ? [] : run.blockers,
919
- activeWorkerId: undefined,
920
- });
921
- await appendGoalDecision(storageCwd, updated.id, {
922
- kind: "completion_audit",
923
- reason: auditCheck.reason,
924
- content: `status=${completionAudit.status}; verifierCheckedAt=${completionAudit.verifierCheckedAt ?? ""}; outputPath=${completionAudit.outputPath ?? ""}`,
925
- });
926
- return `Completion audit recorded for "${updated.title}": ${completionAudit.status}.`;
927
- }
928
- case "pause":
929
- case "resume":
930
- case "complete": {
931
- const run = await resolveRun(storageCwd, args.run_id);
932
- if (!run)
933
- return "Error: no active goal run found.";
934
- let status;
935
- if (args.action === "pause") {
936
- if (run.activeWorkerId || run.tasks.some((task) => task.status === "running")) {
937
- return `Error: cannot pause goal while worker ${run.activeWorkerId ?? "task"} is active. Stop the worker first or wait for it to finish.`;
938
- }
939
- status = "paused";
940
- }
941
- else if (args.action === "resume") {
942
- const missing = goalHasBlockingPrerequisites(run)
943
- ? formatGoalBlockingPrerequisites(run)
944
- : "";
945
- if (missing) {
946
- const updated = await upsertGoalRun(storageCwd, {
947
- ...run,
948
- status: "blocked",
949
- blockers: appendGoalBlockers(run.blockers, missing),
950
- evidence: [
951
- ...run.evidence,
952
- createGoalEvidence({
953
- kind: "summary",
954
- label: "Goal resume blocked",
955
- content: missing,
956
- }),
957
- ],
958
- });
959
- return `Goal "${updated.title}" resume blocked: ${missing}`;
960
- }
961
- const requestedAt = new Date().toISOString();
962
- const resumed = {
963
- ...run,
964
- status: run.status === "running" || run.status === "verifying" ? run.status : "ready",
965
- continueRequestedAt: requestedAt,
966
- evidence: [
967
- ...run.evidence,
968
- createGoalEvidence({
969
- kind: "summary",
970
- label: "Goal resume requested",
971
- content: "Continuation requested; the next eligible Goal action will run automatically when no worker/verifier is active.",
972
- createdAt: requestedAt,
973
- }),
974
- ],
975
- };
976
- const decision = decideGoalNextAction(resumed);
977
- const blockedReason = decision.kind === "blocked" ? decision.reason : undefined;
978
- const updated = await upsertGoalRun(storageCwd, {
979
- ...resumed,
980
- ...(blockedReason
981
- ? {
982
- status: "blocked",
983
- continueRequestedAt: undefined,
984
- blockers: appendGoalBlockers(run.blockers, blockedReason),
985
- evidence: [
986
- ...resumed.evidence,
987
- createGoalEvidence({
988
- kind: "summary",
989
- label: "Goal resume blocked",
990
- content: blockedReason,
991
- }),
992
- ],
993
- }
994
- : {}),
995
- });
996
- await appendGoalDecision(storageCwd, updated.id, {
997
- kind: "resume",
998
- reason: decision.kind === "wait" ||
999
- decision.kind === "blocked" ||
1000
- decision.kind === "terminal" ||
1001
- decision.kind === "complete" ||
1002
- decision.kind === "create_task" ||
1003
- decision.kind === "start_worker" ||
1004
- decision.kind === "run_verifier"
1005
- ? decision.reason
1006
- : "Resume decision queued.",
1007
- content: `next=${decision.kind}`,
1008
- });
1009
- if (decision.kind === "wait") {
1010
- return `Goal "${updated.title}" resume queued: ${decision.reason}`;
1011
- }
1012
- if (decision.kind === "blocked") {
1013
- return `Goal "${updated.title}" resume blocked: ${decision.reason}`;
1014
- }
1015
- return `Goal "${updated.title}" resume requested; next action: ${decision.kind}.`;
1016
- }
1017
- else {
1018
- const completion = canCompleteGoalRun(run);
1019
- if (!completion.ok)
1020
- return `Error: cannot complete goal: ${completion.reason}`;
1021
- status = "passed";
1022
- }
1023
- const updated = await upsertGoalRun(storageCwd, { ...run, status });
1024
- if (status === "passed") {
1025
- try {
1026
- await removeGoalRunWorktrees(storageCwd, updated);
1027
- }
1028
- catch {
1029
- // Worktree cleanup is best-effort hygiene; never block completion.
1030
- }
1031
- }
1032
- return `Goal "${updated.title}" is now ${updated.status}.`;
1033
- }
1034
- }
1035
- },
1036
- };
1037
- }
1038
- //# sourceMappingURL=goals.js.map