@xopcai/xopc 0.0.122 → 0.0.124

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 (273) hide show
  1. package/README.md +28 -11
  2. package/README.zh-CN.md +28 -11
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CK3s5cJo.js → agent-avatar-dicebear-B5uSVAyJ.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-BjIxt67Z.js +2 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CWsNHtTs.js → app-management-settings-panel-CYCONLIL.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-C4b8y6iZ.js → appearance-settings-Clw3ryKg.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-QICTeGjX.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-DAtNW3Ia.js → archive-plugin-CXUGRp2i.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Dm-RY54y.js → attachment-load-Cmiub3Wg.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automation-suggestion-card-BKHewSVT.js → automation-suggestion-card-CU0-4nQ-.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-page-Car-jtiz.js +1 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-BG6Xnk71.js → binary-plugins-0Izz-N3p.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-DfndiO3h.js → block-editor-C1Kv0IkJ.js} +28 -28
  16. package/dist/gateway/static/root/assets/browser-settings-page-CMeBJzlS.js +8 -0
  17. package/dist/gateway/static/root/assets/{capability-presets-api-Cx93GLdw.js → capability-presets-api-BmQTM9Il.js} +1 -1
  18. package/dist/gateway/static/root/assets/capability-presets-settings-panel-DZEJEoCF.js +1 -0
  19. package/dist/gateway/static/root/assets/{channel-recipient-api-DdPTtEs8.js → channel-recipient-api-BeA2aVor.js} +1 -1
  20. package/dist/gateway/static/root/assets/channels-settings-kkW-xFau.js +1 -0
  21. package/dist/gateway/static/root/assets/connectors-page-BvaQvO5F.js +2 -0
  22. package/dist/gateway/static/root/assets/{directory-picker-path-field-D835EHJd.js → directory-picker-path-field-2rjzUu57.js} +1 -1
  23. package/dist/gateway/static/root/assets/{dreaming-settings-CCa1F7Fg.js → dreaming-settings-DnHO686d.js} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-debug-page-W2ITCPSA.js → extension-debug-page-BGLRuWVN.js} +1 -1
  25. package/dist/gateway/static/root/assets/{extension-page-DrvUytvn.js → extension-page-D978ePp9.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-settings-page-qM8aLT5u.js → extension-settings-page-B6Ih4Swx.js} +1 -1
  27. package/dist/gateway/static/root/assets/{fetch-ovkvM8KQ.js → fetch-BU5S0Sn7.js} +1 -1
  28. package/dist/gateway/static/root/assets/{gateway-config-api-BB3biuD0.js → gateway-config-api-BIPGwrl1.js} +1 -1
  29. package/dist/gateway/static/root/assets/gateway-settings-CMEA3r5u.js +1 -0
  30. package/dist/gateway/static/root/assets/{gateway-startup-retry-CanQ8UcR.js → gateway-startup-retry-Cd0Zz30N.js} +1 -1
  31. package/dist/gateway/static/root/assets/{goal-create-dialog-CNqNdEkQ.js → goal-create-dialog-B-KHKeXN.js} +1 -1
  32. package/dist/gateway/static/root/assets/goal-detail-page-BxrSoWdj.js +1 -0
  33. package/dist/gateway/static/root/assets/{goals-config-api-BBOX6mUl.js → goals-config-api-B95KdGMj.js} +1 -1
  34. package/dist/gateway/static/root/assets/{goals-page-BP1kfvWv.js → goals-page-BTJzIl28.js} +2 -2
  35. package/dist/gateway/static/root/assets/{goals-settings-Bh3A7OZV.js → goals-settings-BJyEuLLm.js} +1 -1
  36. package/dist/gateway/static/root/assets/heartbeat-settings-wkOjYNQT.js +1 -0
  37. package/dist/gateway/static/root/assets/index-BLaXr6Ev.css +1 -0
  38. package/dist/gateway/static/root/assets/index-c_9TVr_C.js +191 -0
  39. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-B4TKJHla.js → keyboard-shortcuts-settings-BT8T4DyC.js} +1 -1
  40. package/dist/gateway/static/root/assets/logs-page-CrxBJUgI.js +2 -0
  41. package/dist/gateway/static/root/assets/{markdown-split-DcFtdLci.js → markdown-split-Dv66bO2b.js} +1 -1
  42. package/dist/gateway/static/root/assets/{media-plugins-B6SmeLVB.js → media-plugins-BhIQU5yS.js} +1 -1
  43. package/dist/gateway/static/root/assets/messages-O6TAtdFC.js +3 -0
  44. package/dist/gateway/static/root/assets/models-hub-panel-DOOpz6y1.js +2 -0
  45. package/dist/gateway/static/root/assets/notes-page-Br16pK9v.js +1 -0
  46. package/dist/gateway/static/root/assets/notes-workbench-PSJAi0ZC.js +2 -0
  47. package/dist/gateway/static/root/assets/{preview-open-alternatives-C29O19s7.js → preview-open-alternatives-DGzet1d7.js} +1 -1
  48. package/dist/gateway/static/root/assets/project-detail-page-CIGGgKuw.js +1 -0
  49. package/dist/gateway/static/root/assets/projects-page-B2grhsBt.js +1 -0
  50. package/dist/gateway/static/root/assets/remote-access-hub-CXMORxBD.js +1 -0
  51. package/dist/gateway/static/root/assets/{save-bar-controls-B4ad9GfB.js → save-bar-controls-Cqgb-jqa.js} +1 -1
  52. package/dist/gateway/static/root/assets/{schedule-field-DdYncfLR.js → schedule-field-DVZcI8Yt.js} +1 -1
  53. package/dist/gateway/static/root/assets/{schema-form-BMTrDE-7.js → schema-form-Bj7sOxC8.js} +1 -1
  54. package/dist/gateway/static/root/assets/sessions-page-Bi2wkBzU.js +1 -0
  55. package/dist/gateway/static/root/assets/settings-advanced-gate-B1L3G4IA.js +1 -0
  56. package/dist/gateway/static/root/assets/{settings-collapsible-section-MwTW2eK4.js → settings-collapsible-section-BmXn-8N6.js} +1 -1
  57. package/dist/gateway/static/root/assets/{settings-form-section-Dg6LBbcr.js → settings-form-section-BnqYMWHR.js} +1 -1
  58. package/dist/gateway/static/root/assets/settings-page-BfRSHJmO.js +1 -0
  59. package/dist/gateway/static/root/assets/{settings-page-layout-BX4T-OLF.js → settings-page-layout-CdWZU1hd.js} +1 -1
  60. package/dist/gateway/static/root/assets/{setup-status-panel-Ce1pcFtR.js → setup-status-panel-CWtPM7RK.js} +1 -1
  61. package/dist/gateway/static/root/assets/{share-preview-page-DWE-dUFh.js → share-preview-page-IB1v8i86.js} +1 -1
  62. package/dist/gateway/static/root/assets/shares-settings-ngbsBgij.js +1 -0
  63. package/dist/gateway/static/root/assets/skill-reload-api-BIe442Gv.js +1 -0
  64. package/dist/gateway/static/root/assets/skills-page-BfchZRVa.js +2 -0
  65. package/dist/gateway/static/root/assets/{system-settings-panel-Dd6Y35Cm.js → system-settings-panel-BxQ384RC.js} +1 -1
  66. package/dist/gateway/static/root/assets/{typed-models-lib-Cx6XV5A2.js → typed-models-lib-BkcpvFYO.js} +1 -1
  67. package/dist/gateway/static/root/assets/{use-channel-catalog-D4sMbmy7.js → use-channel-catalog-Cd0FaEQ4.js} +1 -1
  68. package/dist/gateway/static/root/assets/{user-profile-settings-panel-Bx-hjMQc.js → user-profile-settings-panel-DQ7NnRSY.js} +1 -1
  69. package/dist/gateway/static/root/assets/{utils-D7b_vZnv.js → utils-YKhVf7Ka.js} +1 -1
  70. package/dist/gateway/static/root/assets/voice-api-key-field-C5Ov8Uk_.js +1 -0
  71. package/dist/gateway/static/root/assets/{workflow-run-setup-panel--TdohF5N.js → workflow-run-setup-panel-BYD9BtOq.js} +2 -2
  72. package/dist/gateway/static/root/assets/{workflow-start-dialog-B0lavx_o.js → workflow-start-dialog-BNJVCWoS.js} +1 -1
  73. package/dist/gateway/static/root/assets/workflows-page-BYF29ANm.js +18 -0
  74. package/dist/gateway/static/root/index.html +5 -5
  75. package/dist/package.js +1 -1
  76. package/dist/src/agent/agent-manager.d.ts +6 -1
  77. package/dist/src/agent/agent-manager.js +28 -12
  78. package/dist/src/agent/agent-manager.js.map +1 -1
  79. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  80. package/dist/src/agent/embedded/xopc-tools-bridge.js +11 -7
  81. package/dist/src/agent/embedded/xopc-tools-bridge.js.map +1 -1
  82. package/dist/src/agent/lifecycle/progress.js +3 -1
  83. package/dist/src/agent/lifecycle/progress.js.map +1 -1
  84. package/dist/src/agent/lifecycle/timeout-wrapper.d.ts +2 -2
  85. package/dist/src/agent/lifecycle/timeout-wrapper.js +4 -4
  86. package/dist/src/agent/lifecycle/timeout-wrapper.js.map +1 -1
  87. package/dist/src/agent/memory/summary-generator.d.ts +1 -1
  88. package/dist/src/agent/memory/summary-generator.js +1 -2
  89. package/dist/src/agent/memory/summary-generator.js.map +1 -1
  90. package/dist/src/agent/middleware/index.d.ts +1 -1
  91. package/dist/src/agent/middleware/self-verify.d.ts +44 -14
  92. package/dist/src/agent/middleware/self-verify.js +214 -44
  93. package/dist/src/agent/middleware/self-verify.js.map +1 -1
  94. package/dist/src/agent/orchestration/agent-event-handler.js +57 -15
  95. package/dist/src/agent/orchestration/agent-event-handler.js.map +1 -1
  96. package/dist/src/agent/prompt/sections/tooling.js +18 -13
  97. package/dist/src/agent/prompt/sections/tooling.js.map +1 -1
  98. package/dist/src/agent/prompt/system-reminder.js +2 -2
  99. package/dist/src/agent/prompt/system-reminder.js.map +1 -1
  100. package/dist/src/agent/sandbox/sanitize-env-vars.d.ts +2 -2
  101. package/dist/src/agent/sandbox/sanitize-env-vars.js +2 -2
  102. package/dist/src/agent/sandbox/sanitize-env-vars.js.map +1 -1
  103. package/dist/src/agent/sandbox/types.d.ts +2 -2
  104. package/dist/src/agent/sandbox/types.js.map +1 -1
  105. package/dist/src/agent/service/btw-query.js +1 -1
  106. package/dist/src/agent/service/btw-query.js.map +1 -1
  107. package/dist/src/agent/service/process-direct-one-shot.js +6 -2
  108. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  109. package/dist/src/agent/service/process-direct-streaming.js +12 -7
  110. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  111. package/dist/src/agent/service.js +2 -1
  112. package/dist/src/agent/service.js.map +1 -1
  113. package/dist/src/agent/skills/skill-tool-gating.js +1 -1
  114. package/dist/src/agent/skills/skill-tool-gating.js.map +1 -1
  115. package/dist/src/agent/starter-agents.js +9 -9
  116. package/dist/src/agent/starter-agents.js.map +1 -1
  117. package/dist/src/agent/tools/apply-patch.d.ts +25 -0
  118. package/dist/src/agent/tools/apply-patch.js +256 -0
  119. package/dist/src/agent/tools/apply-patch.js.map +1 -0
  120. package/dist/src/agent/tools/delegate-tool.d.ts +1 -1
  121. package/dist/src/agent/tools/delegate-tool.js +3 -3
  122. package/dist/src/agent/tools/delegate-tool.js.map +1 -1
  123. package/dist/src/agent/tools/exec-command.d.ts +30 -0
  124. package/dist/src/agent/tools/exec-command.js +224 -0
  125. package/dist/src/agent/tools/exec-command.js.map +1 -0
  126. package/dist/src/agent/tools/execute-code-tool.js +7 -4
  127. package/dist/src/agent/tools/execute-code-tool.js.map +1 -1
  128. package/dist/src/agent/tools/factory.d.ts +3 -3
  129. package/dist/src/agent/tools/factory.js +8 -9
  130. package/dist/src/agent/tools/factory.js.map +1 -1
  131. package/dist/src/agent/tools/goal-tool.d.ts +5 -1
  132. package/dist/src/agent/tools/goal-tool.js +8 -2
  133. package/dist/src/agent/tools/goal-tool.js.map +1 -1
  134. package/dist/src/agent/tools/index.d.ts +4 -3
  135. package/dist/src/agent/tools/index.js +5 -4
  136. package/dist/src/agent/tools/skills-tools.d.ts +1 -1
  137. package/dist/src/agent/tools/skills-tools.js.map +1 -1
  138. package/dist/src/agent/tools/update-plan-tool.d.ts +11 -0
  139. package/dist/src/agent/tools/update-plan-tool.js +72 -0
  140. package/dist/src/agent/tools/update-plan-tool.js.map +1 -0
  141. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  142. package/dist/src/agent/workflow/builtins/debug-incident.js +1 -1
  143. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  144. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  145. package/dist/src/agent/workflow/builtins/pr-review.js +1 -1
  146. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  147. package/dist/src/agent/workflow/builtins/release-check.d.ts +1 -1
  148. package/dist/src/agent/workflow/builtins/release-check.js +1 -1
  149. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -1
  150. package/dist/src/agent/workflow/step-labels.js +7 -3
  151. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  152. package/dist/src/chat-commands/agent-edit.js +1 -1
  153. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  154. package/dist/src/chat-commands/builtins/goal.js +4 -1
  155. package/dist/src/chat-commands/builtins/goal.js.map +1 -1
  156. package/dist/src/chat-commands/builtins/review.d.ts +1 -0
  157. package/dist/src/chat-commands/builtins/review.js +167 -0
  158. package/dist/src/chat-commands/builtins/review.js.map +1 -0
  159. package/dist/src/chat-commands/index.d.ts +1 -0
  160. package/dist/src/chat-commands/index.js +3 -1
  161. package/dist/src/chat-commands/index.js.map +1 -1
  162. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  163. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  164. package/dist/src/config/agent-profile.js +1 -1
  165. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  166. package/dist/src/gateway/agent-builtin-tools.js +3 -2
  167. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  168. package/dist/src/gateway/agents-admin.js +1 -1
  169. package/dist/src/gateway/chat-stream/mapper.d.ts +6 -0
  170. package/dist/src/gateway/chat-stream/mapper.js +149 -6
  171. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  172. package/dist/src/gateway/chat-stream/protocol.d.ts +51 -1
  173. package/dist/src/gateway/hono/routes/commands-skills.js +21 -0
  174. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  175. package/dist/src/gateway/hono/routes/index.js +2 -0
  176. package/dist/src/gateway/hono/routes/index.js.map +1 -1
  177. package/dist/src/gateway/hono/routes/lazy-bundles.js +1 -0
  178. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  179. package/dist/src/gateway/hono/routes/projects.js +136 -14
  180. package/dist/src/gateway/hono/routes/projects.js.map +1 -1
  181. package/dist/src/gateway/hono/routes/search.d.ts +3 -0
  182. package/dist/src/gateway/hono/routes/search.js +47 -0
  183. package/dist/src/gateway/hono/routes/search.js.map +1 -0
  184. package/dist/src/gateway/security/dangerous-tools.js +1 -1
  185. package/dist/src/gateway/security/dangerous-tools.js.map +1 -1
  186. package/dist/src/infra/update-restart.js +1 -1
  187. package/dist/src/projects/index.d.ts +3 -0
  188. package/dist/src/projects/index.js +4 -1
  189. package/dist/src/projects/project-agent-suggestion.d.ts +14 -0
  190. package/dist/src/projects/project-agent-suggestion.js +19 -0
  191. package/dist/src/projects/project-agent-suggestion.js.map +1 -0
  192. package/dist/src/projects/project-kind.d.ts +13 -0
  193. package/dist/src/projects/project-kind.js +147 -0
  194. package/dist/src/projects/project-kind.js.map +1 -0
  195. package/dist/src/projects/project-service.d.ts +15 -0
  196. package/dist/src/projects/project-service.js +96 -3
  197. package/dist/src/projects/project-service.js.map +1 -1
  198. package/dist/src/projects/project-store.js +32 -8
  199. package/dist/src/projects/project-store.js.map +1 -1
  200. package/dist/src/projects/types.d.ts +4 -1
  201. package/dist/src/projects/workspace-project.d.ts +22 -0
  202. package/dist/src/projects/workspace-project.js +143 -0
  203. package/dist/src/projects/workspace-project.js.map +1 -0
  204. package/dist/src/review/review-git.d.ts +48 -0
  205. package/dist/src/review/review-git.js +333 -0
  206. package/dist/src/review/review-git.js.map +1 -0
  207. package/dist/src/review/review-types.d.ts +22 -0
  208. package/dist/src/review/review-types.js +29 -0
  209. package/dist/src/review/review-types.js.map +1 -0
  210. package/dist/src/session/session-context-for-llm.js +151 -0
  211. package/dist/src/session/session-context-for-llm.js.map +1 -1
  212. package/dist/src/storage/sqlite/migrations/021_projects_fts.sql +21 -0
  213. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  214. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  215. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  216. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  217. package/dist/src/storage/sqlite/schema.js +1 -1
  218. package/dist/src/tui/backends/embedded-backend.d.ts +8 -1
  219. package/dist/src/tui/backends/embedded-backend.js +60 -1
  220. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  221. package/dist/src/tui/backends/gateway-sse-backend.d.ts +9 -1
  222. package/dist/src/tui/backends/gateway-sse-backend.js +29 -0
  223. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  224. package/dist/src/tui/components/assistant-message.js +35 -0
  225. package/dist/src/tui/components/assistant-message.js.map +1 -1
  226. package/dist/src/tui/tui-agent-events.js +25 -0
  227. package/dist/src/tui/tui-agent-events.js.map +1 -1
  228. package/dist/src/tui/tui-backend.d.ts +20 -0
  229. package/dist/src/tui/tui-commands.d.ts +1 -0
  230. package/dist/src/tui/tui-commands.js +110 -4
  231. package/dist/src/tui/tui-commands.js.map +1 -1
  232. package/dist/src/tui/tui-picker-overlay.d.ts +2 -0
  233. package/dist/src/tui/tui-picker-overlay.js +153 -1
  234. package/dist/src/tui/tui-picker-overlay.js.map +1 -1
  235. package/dist/src/tui/tui.js +36 -2
  236. package/dist/src/tui/tui.js.map +1 -1
  237. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  238. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  239. package/package.json +1 -1
  240. package/dist/gateway/static/root/assets/agents-SsQrj9B-.js +0 -2
  241. package/dist/gateway/static/root/assets/apps-page-CYb6fame.js +0 -1
  242. package/dist/gateway/static/root/assets/automations-page-DpOOq1nk.js +0 -1
  243. package/dist/gateway/static/root/assets/browser-settings-page-9nXxgh4u.js +0 -8
  244. package/dist/gateway/static/root/assets/capability-presets-settings-panel-D528_YFy.js +0 -1
  245. package/dist/gateway/static/root/assets/channels-settings-Ck-3h5lI.js +0 -1
  246. package/dist/gateway/static/root/assets/connectors-page-DL-fAqE_.js +0 -2
  247. package/dist/gateway/static/root/assets/gateway-settings-mmmnIH27.js +0 -1
  248. package/dist/gateway/static/root/assets/goal-detail-page-Ceu5zrN6.js +0 -1
  249. package/dist/gateway/static/root/assets/heartbeat-settings-YoYgKlfX.js +0 -1
  250. package/dist/gateway/static/root/assets/index-DdqSO9R2.js +0 -191
  251. package/dist/gateway/static/root/assets/index-jGB-2nI-.css +0 -1
  252. package/dist/gateway/static/root/assets/logs-page-BgVk5DvZ.js +0 -2
  253. package/dist/gateway/static/root/assets/messages-B5O4OIEo.js +0 -3
  254. package/dist/gateway/static/root/assets/models-hub-panel-BU0x8PGP.js +0 -2
  255. package/dist/gateway/static/root/assets/notes-page-D6JYVP4I.js +0 -1
  256. package/dist/gateway/static/root/assets/notes-workbench-mqRJYnJS.js +0 -2
  257. package/dist/gateway/static/root/assets/project-detail-page-DOTgzoeh.js +0 -1
  258. package/dist/gateway/static/root/assets/projects-page-DGUIb4y5.js +0 -1
  259. package/dist/gateway/static/root/assets/remote-access-hub-DVKKUj3u.js +0 -1
  260. package/dist/gateway/static/root/assets/sessions-page-BVbzUWxW.js +0 -1
  261. package/dist/gateway/static/root/assets/settings-advanced-gate-DrNNoSqE.js +0 -1
  262. package/dist/gateway/static/root/assets/settings-page-CMDqgeMR.js +0 -1
  263. package/dist/gateway/static/root/assets/shares-settings-aKSraR8l.js +0 -1
  264. package/dist/gateway/static/root/assets/skill-reload-api-CS-FU_B-.js +0 -1
  265. package/dist/gateway/static/root/assets/skills-page-BaF3u0LA.js +0 -2
  266. package/dist/gateway/static/root/assets/voice-api-key-field-CkhbRt1q.js +0 -1
  267. package/dist/gateway/static/root/assets/workflows-page-CZR05Bu_.js +0 -18
  268. package/dist/src/agent/tools/edit.d.ts +0 -14
  269. package/dist/src/agent/tools/edit.js +0 -132
  270. package/dist/src/agent/tools/edit.js.map +0 -1
  271. package/dist/src/agent/tools/shell.d.ts +0 -15
  272. package/dist/src/agent/tools/shell.js +0 -158
  273. package/dist/src/agent/tools/shell.js.map +0 -1
@@ -1,5 +1,7 @@
1
1
  import { GoalService } from "../../goals/goal-service.js";
2
2
  import "../../goals/index.js";
3
+ import { getSessionMetadata } from "../../storage/sqlite/session-repository.js";
4
+ import "../../storage/sqlite/index.js";
3
5
  import { Type } from "@sinclair/typebox";
4
6
  //#region src/agent/tools/goal-tool.ts
5
7
  const GoalToolSchema = Type.Object({
@@ -34,6 +36,7 @@ const GoalToolSchema = Type.Object({
34
36
  judgeModelRef: Type.Optional(Type.String()),
35
37
  agentId: Type.Optional(Type.String()),
36
38
  sessionKey: Type.Optional(Type.String()),
39
+ projectId: Type.Optional(Type.String()),
37
40
  limit: Type.Optional(Type.Number({
38
41
  minimum: 1,
39
42
  maximum: 100
@@ -48,7 +51,7 @@ function textResult(text) {
48
51
  details: {}
49
52
  };
50
53
  }
51
- function createGoalTool() {
54
+ function createGoalTool(options = {}) {
52
55
  return {
53
56
  name: "goal",
54
57
  label: "Goal",
@@ -64,11 +67,14 @@ function createGoalTool() {
64
67
  if (params.action === "create") {
65
68
  const title = params.title?.trim();
66
69
  if (!title) return textResult("Error: title is required.");
70
+ const sessionKey = params.sessionKey?.trim() || options.getCurrentSessionKey?.()?.trim();
71
+ const projectId = params.projectId?.trim() || (sessionKey ? getSessionMetadata(sessionKey)?.projectId : void 0);
67
72
  const goal = goals.create({
68
73
  title,
69
74
  description: params.description,
70
75
  agentId: params.agentId,
71
- sessionKey: params.sessionKey,
76
+ sessionKey,
77
+ projectId,
72
78
  priority: params.priority,
73
79
  deadlineAt: params.deadlineAt,
74
80
  judgeModelRef: params.judgeModelRef,
@@ -1 +1 @@
1
- {"version":3,"file":"goal-tool.js","names":[],"sources":["../../../../src/agent/tools/goal-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport { GoalService, type GoalPriority, type GoalStatus } from '../../goals/index.js';\n\nconst GoalToolSchema = Type.Object({\n action: Type.Union([\n Type.Literal('list'),\n Type.Literal('create'),\n Type.Literal('update'),\n ]),\n goalId: Type.Optional(Type.String({ description: 'Goal id for update.' })),\n title: Type.Optional(Type.String({ description: 'Goal title for create/update.' })),\n description: Type.Optional(Type.String({ description: 'Goal description.' })),\n status: Type.Optional(Type.Union([\n Type.Literal('active'),\n Type.Literal('paused'),\n Type.Literal('blocked'),\n Type.Literal('needs_input'),\n Type.Literal('done'),\n Type.Literal('archived'),\n ])),\n priority: Type.Optional(Type.Union([\n Type.Literal('low'),\n Type.Literal('normal'),\n Type.Literal('high'),\n ])),\n maxTurns: Type.Optional(Type.Number({ minimum: 1, maximum: 500 })),\n deadlineAt: Type.Optional(Type.Number({ description: 'Unix timestamp in milliseconds.' })),\n nextAction: Type.Optional(Type.String()),\n blockedReason: Type.Optional(Type.String()),\n judgeModelRef: Type.Optional(Type.String()),\n agentId: Type.Optional(Type.String()),\n sessionKey: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100 })),\n});\n\ntype GoalToolParams = {\n action: 'list' | 'create' | 'update';\n goalId?: string;\n title?: string;\n description?: string;\n status?: GoalStatus;\n priority?: GoalPriority;\n maxTurns?: number;\n deadlineAt?: number;\n nextAction?: string;\n blockedReason?: string;\n judgeModelRef?: string;\n agentId?: string;\n sessionKey?: string;\n limit?: number;\n};\n\nfunction textResult(text: string) {\n return { content: [{ type: 'text' as const, text }], details: {} };\n}\n\nexport function createGoalTool(): AgentTool<typeof GoalToolSchema, {}> {\n return {\n name: 'goal',\n label: 'Goal',\n description:\n 'Create, list, or update durable goals. Use this from workflows when work should become a tracked long-running goal.',\n parameters: GoalToolSchema,\n async execute(_toolCallId, params: GoalToolParams) {\n const goals = new GoalService();\n if (params.action === 'list') {\n const rows = goals.list({ limit: Math.max(1, Math.min(100, Math.floor(params.limit ?? 20))) });\n if (!rows.length) return textResult('No goals.');\n return textResult(rows.map((g) => `${g.id} [${g.status}] ${g.title}`).join('\\n'));\n }\n\n if (params.action === 'create') {\n const title = params.title?.trim();\n if (!title) return textResult('Error: title is required.');\n const goal = goals.create({\n title,\n description: params.description,\n agentId: params.agentId,\n sessionKey: params.sessionKey,\n priority: params.priority,\n deadlineAt: params.deadlineAt,\n judgeModelRef: params.judgeModelRef,\n maxTurns: params.maxTurns,\n source: 'workflow',\n });\n return textResult(`Created goal ${goal.id}\\n${goal.title}`);\n }\n\n const goalId = params.goalId?.trim();\n if (!goalId) return textResult('Error: goalId is required.');\n let goal = goals.update(goalId, {\n ...(params.title !== undefined ? { title: params.title } : {}),\n ...(params.description !== undefined ? { description: params.description } : {}),\n ...(params.priority !== undefined ? { priority: params.priority } : {}),\n ...(params.deadlineAt !== undefined ? { deadlineAt: params.deadlineAt } : {}),\n ...(params.maxTurns !== undefined ? { maxTurns: params.maxTurns } : {}),\n ...(params.nextAction !== undefined ? { nextAction: params.nextAction } : {}),\n ...(params.blockedReason !== undefined ? { blockedReason: params.blockedReason } : {}),\n ...(params.judgeModelRef !== undefined ? { judgeModelRef: params.judgeModelRef } : {}),\n });\n if (!goal) return textResult(`Goal not found: ${goalId}`);\n if (params.status) {\n goal = goals.setStatus(goalId, params.status, { reason: params.blockedReason });\n }\n return textResult(`Updated goal ${goalId}\\n${goal?.title ?? ''}`);\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"goal-tool.js","names":[],"sources":["../../../../src/agent/tools/goal-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool } from '@earendil-works/pi-agent-core';\n\nimport { GoalService, type GoalPriority, type GoalStatus } from '../../goals/index.js';\nimport { getSessionMetadata } from '../../storage/sqlite/index.js';\n\nconst GoalToolSchema = Type.Object({\n action: Type.Union([\n Type.Literal('list'),\n Type.Literal('create'),\n Type.Literal('update'),\n ]),\n goalId: Type.Optional(Type.String({ description: 'Goal id for update.' })),\n title: Type.Optional(Type.String({ description: 'Goal title for create/update.' })),\n description: Type.Optional(Type.String({ description: 'Goal description.' })),\n status: Type.Optional(Type.Union([\n Type.Literal('active'),\n Type.Literal('paused'),\n Type.Literal('blocked'),\n Type.Literal('needs_input'),\n Type.Literal('done'),\n Type.Literal('archived'),\n ])),\n priority: Type.Optional(Type.Union([\n Type.Literal('low'),\n Type.Literal('normal'),\n Type.Literal('high'),\n ])),\n maxTurns: Type.Optional(Type.Number({ minimum: 1, maximum: 500 })),\n deadlineAt: Type.Optional(Type.Number({ description: 'Unix timestamp in milliseconds.' })),\n nextAction: Type.Optional(Type.String()),\n blockedReason: Type.Optional(Type.String()),\n judgeModelRef: Type.Optional(Type.String()),\n agentId: Type.Optional(Type.String()),\n sessionKey: Type.Optional(Type.String()),\n projectId: Type.Optional(Type.String()),\n limit: Type.Optional(Type.Number({ minimum: 1, maximum: 100 })),\n});\n\ntype GoalToolParams = {\n action: 'list' | 'create' | 'update';\n goalId?: string;\n title?: string;\n description?: string;\n status?: GoalStatus;\n priority?: GoalPriority;\n maxTurns?: number;\n deadlineAt?: number;\n nextAction?: string;\n blockedReason?: string;\n judgeModelRef?: string;\n agentId?: string;\n sessionKey?: string;\n projectId?: string;\n limit?: number;\n};\n\nexport interface GoalToolOptions {\n getCurrentSessionKey?: () => string | undefined;\n}\n\nfunction textResult(text: string) {\n return { content: [{ type: 'text' as const, text }], details: {} };\n}\n\nexport function createGoalTool(options: GoalToolOptions = {}): AgentTool<typeof GoalToolSchema, {}> {\n return {\n name: 'goal',\n label: 'Goal',\n description:\n 'Create, list, or update durable goals. Use this from workflows when work should become a tracked long-running goal.',\n parameters: GoalToolSchema,\n async execute(_toolCallId, params: GoalToolParams) {\n const goals = new GoalService();\n if (params.action === 'list') {\n const rows = goals.list({ limit: Math.max(1, Math.min(100, Math.floor(params.limit ?? 20))) });\n if (!rows.length) return textResult('No goals.');\n return textResult(rows.map((g) => `${g.id} [${g.status}] ${g.title}`).join('\\n'));\n }\n\n if (params.action === 'create') {\n const title = params.title?.trim();\n if (!title) return textResult('Error: title is required.');\n const sessionKey = params.sessionKey?.trim() || options.getCurrentSessionKey?.()?.trim();\n const projectId = params.projectId?.trim() || (sessionKey ? getSessionMetadata(sessionKey)?.projectId : undefined);\n const goal = goals.create({\n title,\n description: params.description,\n agentId: params.agentId,\n sessionKey,\n projectId,\n priority: params.priority,\n deadlineAt: params.deadlineAt,\n judgeModelRef: params.judgeModelRef,\n maxTurns: params.maxTurns,\n source: 'workflow',\n });\n return textResult(`Created goal ${goal.id}\\n${goal.title}`);\n }\n\n const goalId = params.goalId?.trim();\n if (!goalId) return textResult('Error: goalId is required.');\n let goal = goals.update(goalId, {\n ...(params.title !== undefined ? { title: params.title } : {}),\n ...(params.description !== undefined ? { description: params.description } : {}),\n ...(params.priority !== undefined ? { priority: params.priority } : {}),\n ...(params.deadlineAt !== undefined ? { deadlineAt: params.deadlineAt } : {}),\n ...(params.maxTurns !== undefined ? { maxTurns: params.maxTurns } : {}),\n ...(params.nextAction !== undefined ? { nextAction: params.nextAction } : {}),\n ...(params.blockedReason !== undefined ? { blockedReason: params.blockedReason } : {}),\n ...(params.judgeModelRef !== undefined ? { judgeModelRef: params.judgeModelRef } : {}),\n });\n if (!goal) return textResult(`Goal not found: ${goalId}`);\n if (params.status) {\n goal = goals.setStatus(goalId, params.status, { reason: params.blockedReason });\n }\n return textResult(`Updated goal ${goalId}\\n${goal?.title ?? ''}`);\n },\n };\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  export { createReadFileTool, type CreateReadFileToolOptions } from './read.js';
2
2
  export { createWriteFileTool, writeFileTool } from './write.js';
3
- export { createEditFileTool, editFileTool, type EditToolDetails } from './edit.js';
4
3
  export { createListDirTool, listDirTool } from './list-dir.js';
5
- export { createShellTool } from './shell.js';
4
+ export { createExecCommandTool, type ExecCommandDetails, type ExecCommandUpdateDetails, } from './exec-command.js';
5
+ export { createApplyPatchTool, type AppliedPatchChange, type ApplyPatchDetails, } from './apply-patch.js';
6
6
  export { createMemorySearchTool, createMemoryGetTool, type MemoryToolOptions, } from './memory-tool.js';
7
7
  export { createCuratedMemoryTool } from './curated-memory-tool.js';
8
8
  export { createSessionSearchTool } from './session-search-tool.js';
@@ -16,6 +16,7 @@ export { createSendMediaTool } from './send-media.js';
16
16
  export { createReadMediaTool } from './media-read-tool.js';
17
17
  export { createCreateShareTool, isShareToolAvailable, type CreateShareToolDeps, } from './create-share-tool.js';
18
18
  export { createTodoTool, TodoStore, type TodoItem, type TodoStatus } from './todo-tool.js';
19
+ export { createUpdatePlanTool, type TurnPlanDetails, type TurnPlanStatus, type TurnPlanStep, } from './update-plan-tool.js';
19
20
  export { createSessionStatusTool } from './session-status-tool.js';
20
21
  export { createDreamingTool, type DreamingToolDeps } from './dreaming-tool.js';
21
22
  export { createClarifyTool, type ClarifyRequestPayload, type GatewayClarifyRequestFn, } from './clarify-tool.js';
@@ -24,7 +25,7 @@ export { createDelegateTool, DEFAULT_DELEGATE_TOOLS, DELEGATE_BLOCKED_TOOLS, } f
24
25
  export { createWorkflowTool, type WorkflowToolDeps, type WorkflowToolInput } from './workflow-tool.js';
25
26
  export { createExecuteCodeTool, buildSandboxToolMap, SANDBOX_ALLOWED_TOOLS, } from './execute-code-tool.js';
26
27
  export { createAutomationTool, type AutomationToolDeps } from './automation-tool.js';
27
- export { createGoalTool } from './goal-tool.js';
28
+ export { createGoalTool, type GoalToolOptions } from './goal-tool.js';
28
29
  export { createSkillsListTool, createSkillViewTool, type SkillsToolsDeps } from './skills-tools.js';
29
30
  export { createSkillManageTool, type SkillManageToolDeps } from './skill-manage-tool.js';
30
31
  export { createToolManualTool } from './tool-manual-tool.js';
@@ -1,10 +1,10 @@
1
1
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, GREP_MAX_LINE_LENGTH, formatSize, truncateHead, truncateLine, truncateTail } from "./truncate.js";
2
2
  import { createReadFileTool } from "./read.js";
3
3
  import { createWriteFileTool, writeFileTool } from "./write.js";
4
- import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom } from "./edit-diff.js";
5
- import { createEditFileTool, editFileTool } from "./edit.js";
6
4
  import { createListDirTool, listDirTool } from "./list-dir.js";
7
- import { createShellTool } from "./shell.js";
5
+ import { createExecCommandTool } from "./exec-command.js";
6
+ import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom } from "./edit-diff.js";
7
+ import { createApplyPatchTool } from "./apply-patch.js";
8
8
  import { createMemoryGetTool, createMemorySearchTool } from "./memory-tool.js";
9
9
  import { createCuratedMemoryTool } from "./curated-memory-tool.js";
10
10
  import { createSessionSearchTool } from "./session-search-tool.js";
@@ -18,6 +18,7 @@ import { createSendMediaTool } from "./send-media.js";
18
18
  import { createReadMediaTool } from "./media-read-tool.js";
19
19
  import { createCreateShareTool, isShareToolAvailable } from "./create-share-tool.js";
20
20
  import { TodoStore, createTodoTool } from "./todo-tool.js";
21
+ import { createUpdatePlanTool } from "./update-plan-tool.js";
21
22
  import { createSessionStatusTool } from "./session-status-tool.js";
22
23
  import { createDreamingTool } from "./dreaming-tool.js";
23
24
  import { createClarifyTool } from "./clarify-tool.js";
@@ -35,4 +36,4 @@ import { createToolManualTool } from "./tool-manual-tool.js";
35
36
  import { resolveImageModelConfigForTool } from "../image/tool-model-config.js";
36
37
  import { createImageTool } from "./image-tool.js";
37
38
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
38
- export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createEditFileTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createShellTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, editFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
39
+ export { BrowserManager, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, SANDBOX_ALLOWED_TOOLS, TodoStore, assertBrowserUrlAllowed, buildSandboxToolMap, createApplyPatchTool, createAutomationTool, createClarifyTool, createComposioExecuteTool, createCreateShareTool, createCuratedMemoryTool, createDelegateTool, createDreamingTool, createExecCommandTool, createExecuteCodeTool, createFindTool, createGoalTool, createGrepTool, createImageGenerateTool, createImageTool, createListDirTool, createMemoryGetTool, createMemorySearchTool, createMessageTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionSearchTool, createSessionStatusTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, findTool, formatSize, fuzzyFindText, generateDiffString, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -6,7 +6,7 @@ export interface SkillsToolsDeps {
6
6
  registeredToolNames: string[];
7
7
  skillAllowlist?: string[];
8
8
  } | undefined;
9
- /** Register declared env var names for shell / tool passthrough (values never exposed). */
9
+ /** Register declared env var names for command/tool passthrough (values never exposed). */
10
10
  registerSkillEnvPassthrough?: (names: string[]) => void;
11
11
  }
12
12
  export declare function createSkillsListTool(deps: SkillsToolsDeps): AgentTool;
@@ -1 +1 @@
1
- {"version":3,"file":"skills-tools.js","names":[],"sources":["../../../../src/agent/tools/skills-tools.ts"],"sourcesContent":["import { readFileSync, statSync } from 'fs';\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport { resolveStateDir } from '../../config/paths.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from '../skills/config.js';\nimport { resolveSkillReadablePath } from '../skills/skill-view-path.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { truncateHead, formatSize, DEFAULT_MAX_BYTES } from './truncate.js';\n\nconst DEFAULT_MAX_LINES = 500;\nconst DEFAULT_MAX_SKILL_FILE_BYTES = 1_048_576;\n\nconst SkillsListSchema = Type.Object({\n query: Type.Optional(\n Type.String({\n description: 'Optional case-insensitive substring filter on skill name and description',\n }),\n ),\n});\n\nconst SkillViewSchema = Type.Object({\n name: Type.String({ description: 'Skill name (as in <available_skills> / skills_list)' }),\n path: Type.Optional(\n Type.String({\n description:\n 'Relative path inside the skill dir: omit for SKILL.md, or e.g. references/doc.md (only references/, templates/, scripts/, assets/)',\n }),\n ),\n limit: Type.Optional(\n Type.Number({ description: 'Max lines to return (default 500, like read_file)' }),\n ),\n});\n\nexport interface SkillsToolsDeps {\n getSkillManager: () => SkillManager | undefined;\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** Register declared env var names for shell / tool passthrough (values never exposed). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nfunction maxSkillBytes(): number {\n const lim = createSkillConfigManager(resolveStateDir()).load().limits?.maxSkillFileBytes;\n return typeof lim === 'number' && lim > 0 ? lim : DEFAULT_MAX_SKILL_FILE_BYTES;\n}\n\nexport function createSkillsListTool(deps: SkillsToolsDeps): AgentTool {\n return {\n name: 'skills_list',\n label: '📚 Skills',\n description:\n 'List available skills (name and description only). Use skill_view(name) to load SKILL.md or a file under references/, templates/, scripts/, or assets/.',\n parameters: SkillsListSchema,\n async execute(\n _toolCallId: string,\n params: any,\n ): Promise<AgentToolResult<{}>> {\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return {\n content: [{ type: 'text', text: 'Skills are not available in this runtime context.' }],\n details: {},\n };\n }\n\n const idx = deps.getSkillIndexingContext?.();\n let skills = mgr.getEnabledSkillsForAgentSession({\n skillAllowlist: idx?.skillAllowlist,\n registeredToolNames: idx?.registeredToolNames,\n });\n const q = (params as { query?: string }).query?.trim().toLowerCase();\n if (q) {\n skills = skills.filter(\n (s) =>\n s.name.toLowerCase().includes(q) || s.description.toLowerCase().includes(q),\n );\n }\n\n const payload = {\n skills: skills.map((s) => ({\n name: s.name,\n description: s.description,\n source: s.source,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }],\n details: {},\n };\n },\n } as any;\n}\n\nexport function createSkillViewTool(deps: SkillsToolsDeps): AgentTool {\n return {\n name: 'skill_view',\n label: '📖 Skill',\n description:\n 'Load a skill\\'s SKILL.md (default) or a supporting file under references/, templates/, scripts/, or assets/.',\n parameters: SkillViewSchema,\n async execute(\n _toolCallId: string,\n params: any,\n ): Promise<AgentToolResult<{}>> {\n const p = params as { name: string; path?: string; limit?: number };\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return {\n content: [{ type: 'text', text: 'Skills are not available in this runtime context.' }],\n details: {},\n };\n }\n\n const skill = mgr.findSkill(p.name.trim());\n if (!skill) {\n return {\n content: [\n {\n type: 'text',\n text: `Skill \"${p.name}\" was not found. It may not be installed. Open the Skills library to install it, or use skills_list to see available names.`,\n },\n ],\n details: { errorCode: 'skill_not_found', skillName: p.name },\n };\n }\n\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const skillConfig = resolveSkillConfig(skill, skillsConfig);\n if (skillConfig.enabled === false) {\n return {\n content: [\n {\n type: 'text',\n text: `Skill \"${skill.name}\" is installed but disabled. Enable it in Skills settings before using it.`,\n },\n ],\n details: { errorCode: 'skill_disabled', skillName: skill.name },\n };\n }\n if (skill.disableModelInvocation) {\n return {\n content: [{ type: 'text', text: `Skill \"${skill.name}\" is installed, but it is not available for model invocation.` }],\n details: { errorCode: 'skill_model_invocation_disabled', skillName: skill.name },\n };\n }\n if (!isSkillEnabled(skill, skillsConfig)) {\n return {\n content: [{ type: 'text', text: `Skill \"${skill.name}\" is installed, but its requirements are not met.` }],\n details: { errorCode: 'skill_requirements_unmet', skillName: skill.name },\n };\n }\n\n const idx = deps.getSkillIndexingContext?.();\n const visible = mgr.getEnabledSkillsForAgentSession({\n skillAllowlist: idx?.skillAllowlist,\n registeredToolNames: idx?.registeredToolNames,\n });\n if (!visible.some((s) => s.name === skill.name)) {\n return {\n content: [\n {\n type: 'text',\n text: `The current agent cannot use skill \"${skill.name}\". It is installed, but it is not in this agent's skill allowlist or is hidden by tool gating. Enable it in Agent settings → Skills before using it.`,\n },\n ],\n details: { errorCode: 'skill_agent_denied', skillName: skill.name },\n };\n }\n\n const resolved = resolveSkillReadablePath(skill, p.path);\n if (resolved.ok === false) {\n return { content: [{ type: 'text', text: resolved.error }], details: {} };\n }\n\n const maxBytes = maxSkillBytes();\n try {\n const st = statSync(resolved.absolutePath);\n if (st.size > maxBytes) {\n return {\n content: [\n {\n type: 'text',\n text: `File too large: ${formatSize(st.size)} (limit ${formatSize(maxBytes)})`,\n },\n ],\n details: {},\n };\n }\n\n const raw = readFileSync(resolved.absolutePath, 'utf-8');\n const truncation = truncateHead(raw, {\n maxLines: p.limit ?? DEFAULT_MAX_LINES,\n maxBytes: DEFAULT_MAX_BYTES,\n });\n\n let outputText = truncation.content;\n if (truncation.truncated) {\n if (truncation.firstLineExceedsLimit) {\n outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;\n } else {\n outputText += `\\n\\n[${truncation.outputLines}/${truncation.totalLines} lines]`;\n }\n }\n\n const envNames = skill.requiredEnvVarNames;\n if (envNames?.length && deps.registerSkillEnvPassthrough) {\n deps.registerSkillEnvPassthrough(envNames);\n const setNow = envNames.filter((k) => process.env[k] !== undefined).length;\n outputText += `\\n\\n[skill env passthrough] Registered ${envNames.length} declared variable name(s) for this session; ${setNow} are currently defined in the process (values are never shown).`;\n }\n\n return { content: [{ type: 'text', text: outputText }], details: {} };\n } catch (e) {\n return {\n content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }],\n details: {},\n };\n }\n },\n } as any;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"skills-tools.js","names":[],"sources":["../../../../src/agent/tools/skills-tools.ts"],"sourcesContent":["import { readFileSync, statSync } from 'fs';\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nimport { resolveStateDir } from '../../config/paths.js';\nimport { createSkillConfigManager, isSkillEnabled, resolveSkillConfig } from '../skills/config.js';\nimport { resolveSkillReadablePath } from '../skills/skill-view-path.js';\nimport type { SkillManager } from '../skills/skill-manager.js';\nimport { truncateHead, formatSize, DEFAULT_MAX_BYTES } from './truncate.js';\n\nconst DEFAULT_MAX_LINES = 500;\nconst DEFAULT_MAX_SKILL_FILE_BYTES = 1_048_576;\n\nconst SkillsListSchema = Type.Object({\n query: Type.Optional(\n Type.String({\n description: 'Optional case-insensitive substring filter on skill name and description',\n }),\n ),\n});\n\nconst SkillViewSchema = Type.Object({\n name: Type.String({ description: 'Skill name (as in <available_skills> / skills_list)' }),\n path: Type.Optional(\n Type.String({\n description:\n 'Relative path inside the skill dir: omit for SKILL.md, or e.g. references/doc.md (only references/, templates/, scripts/, assets/)',\n }),\n ),\n limit: Type.Optional(\n Type.Number({ description: 'Max lines to return (default 500, like read_file)' }),\n ),\n});\n\nexport interface SkillsToolsDeps {\n getSkillManager: () => SkillManager | undefined;\n getSkillIndexingContext?: () =>\n | { registeredToolNames: string[]; skillAllowlist?: string[] }\n | undefined;\n /** Register declared env var names for command/tool passthrough (values never exposed). */\n registerSkillEnvPassthrough?: (names: string[]) => void;\n}\n\nfunction maxSkillBytes(): number {\n const lim = createSkillConfigManager(resolveStateDir()).load().limits?.maxSkillFileBytes;\n return typeof lim === 'number' && lim > 0 ? lim : DEFAULT_MAX_SKILL_FILE_BYTES;\n}\n\nexport function createSkillsListTool(deps: SkillsToolsDeps): AgentTool {\n return {\n name: 'skills_list',\n label: '📚 Skills',\n description:\n 'List available skills (name and description only). Use skill_view(name) to load SKILL.md or a file under references/, templates/, scripts/, or assets/.',\n parameters: SkillsListSchema,\n async execute(\n _toolCallId: string,\n params: any,\n ): Promise<AgentToolResult<{}>> {\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return {\n content: [{ type: 'text', text: 'Skills are not available in this runtime context.' }],\n details: {},\n };\n }\n\n const idx = deps.getSkillIndexingContext?.();\n let skills = mgr.getEnabledSkillsForAgentSession({\n skillAllowlist: idx?.skillAllowlist,\n registeredToolNames: idx?.registeredToolNames,\n });\n const q = (params as { query?: string }).query?.trim().toLowerCase();\n if (q) {\n skills = skills.filter(\n (s) =>\n s.name.toLowerCase().includes(q) || s.description.toLowerCase().includes(q),\n );\n }\n\n const payload = {\n skills: skills.map((s) => ({\n name: s.name,\n description: s.description,\n source: s.source,\n })),\n };\n\n return {\n content: [{ type: 'text', text: JSON.stringify(payload, null, 2) }],\n details: {},\n };\n },\n } as any;\n}\n\nexport function createSkillViewTool(deps: SkillsToolsDeps): AgentTool {\n return {\n name: 'skill_view',\n label: '📖 Skill',\n description:\n 'Load a skill\\'s SKILL.md (default) or a supporting file under references/, templates/, scripts/, or assets/.',\n parameters: SkillViewSchema,\n async execute(\n _toolCallId: string,\n params: any,\n ): Promise<AgentToolResult<{}>> {\n const p = params as { name: string; path?: string; limit?: number };\n const mgr = deps.getSkillManager();\n if (!mgr) {\n return {\n content: [{ type: 'text', text: 'Skills are not available in this runtime context.' }],\n details: {},\n };\n }\n\n const skill = mgr.findSkill(p.name.trim());\n if (!skill) {\n return {\n content: [\n {\n type: 'text',\n text: `Skill \"${p.name}\" was not found. It may not be installed. Open the Skills library to install it, or use skills_list to see available names.`,\n },\n ],\n details: { errorCode: 'skill_not_found', skillName: p.name },\n };\n }\n\n const skillsConfig = createSkillConfigManager(resolveStateDir()).load();\n const skillConfig = resolveSkillConfig(skill, skillsConfig);\n if (skillConfig.enabled === false) {\n return {\n content: [\n {\n type: 'text',\n text: `Skill \"${skill.name}\" is installed but disabled. Enable it in Skills settings before using it.`,\n },\n ],\n details: { errorCode: 'skill_disabled', skillName: skill.name },\n };\n }\n if (skill.disableModelInvocation) {\n return {\n content: [{ type: 'text', text: `Skill \"${skill.name}\" is installed, but it is not available for model invocation.` }],\n details: { errorCode: 'skill_model_invocation_disabled', skillName: skill.name },\n };\n }\n if (!isSkillEnabled(skill, skillsConfig)) {\n return {\n content: [{ type: 'text', text: `Skill \"${skill.name}\" is installed, but its requirements are not met.` }],\n details: { errorCode: 'skill_requirements_unmet', skillName: skill.name },\n };\n }\n\n const idx = deps.getSkillIndexingContext?.();\n const visible = mgr.getEnabledSkillsForAgentSession({\n skillAllowlist: idx?.skillAllowlist,\n registeredToolNames: idx?.registeredToolNames,\n });\n if (!visible.some((s) => s.name === skill.name)) {\n return {\n content: [\n {\n type: 'text',\n text: `The current agent cannot use skill \"${skill.name}\". It is installed, but it is not in this agent's skill allowlist or is hidden by tool gating. Enable it in Agent settings → Skills before using it.`,\n },\n ],\n details: { errorCode: 'skill_agent_denied', skillName: skill.name },\n };\n }\n\n const resolved = resolveSkillReadablePath(skill, p.path);\n if (resolved.ok === false) {\n return { content: [{ type: 'text', text: resolved.error }], details: {} };\n }\n\n const maxBytes = maxSkillBytes();\n try {\n const st = statSync(resolved.absolutePath);\n if (st.size > maxBytes) {\n return {\n content: [\n {\n type: 'text',\n text: `File too large: ${formatSize(st.size)} (limit ${formatSize(maxBytes)})`,\n },\n ],\n details: {},\n };\n }\n\n const raw = readFileSync(resolved.absolutePath, 'utf-8');\n const truncation = truncateHead(raw, {\n maxLines: p.limit ?? DEFAULT_MAX_LINES,\n maxBytes: DEFAULT_MAX_BYTES,\n });\n\n let outputText = truncation.content;\n if (truncation.truncated) {\n if (truncation.firstLineExceedsLimit) {\n outputText = `(Line exceeds ${formatSize(DEFAULT_MAX_BYTES)})`;\n } else {\n outputText += `\\n\\n[${truncation.outputLines}/${truncation.totalLines} lines]`;\n }\n }\n\n const envNames = skill.requiredEnvVarNames;\n if (envNames?.length && deps.registerSkillEnvPassthrough) {\n deps.registerSkillEnvPassthrough(envNames);\n const setNow = envNames.filter((k) => process.env[k] !== undefined).length;\n outputText += `\\n\\n[skill env passthrough] Registered ${envNames.length} declared variable name(s) for this session; ${setNow} are currently defined in the process (values are never shown).`;\n }\n\n return { content: [{ type: 'text', text: outputText }], details: {} };\n } catch (e) {\n return {\n content: [{ type: 'text', text: `Error: ${e instanceof Error ? e.message : String(e)}` }],\n details: {},\n };\n }\n },\n } as any;\n}\n"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { AgentTool } from '@earendil-works/pi-agent-core';
2
+ export type TurnPlanStatus = 'pending' | 'in_progress' | 'completed';
3
+ export interface TurnPlanStep {
4
+ step: string;
5
+ status: TurnPlanStatus;
6
+ }
7
+ export interface TurnPlanDetails {
8
+ explanation?: string;
9
+ plan: TurnPlanStep[];
10
+ }
11
+ export declare function createUpdatePlanTool(): AgentTool;
@@ -0,0 +1,72 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ //#region src/agent/tools/update-plan-tool.ts
3
+ const VALID_STATUSES = new Set([
4
+ "pending",
5
+ "in_progress",
6
+ "completed"
7
+ ]);
8
+ const PlanStepSchema = Type.Object({
9
+ step: Type.String({
10
+ minLength: 1,
11
+ description: "Short task step"
12
+ }),
13
+ status: Type.Union([
14
+ Type.Literal("pending"),
15
+ Type.Literal("in_progress"),
16
+ Type.Literal("completed")
17
+ ])
18
+ });
19
+ const UpdatePlanSchema = Type.Object({
20
+ explanation: Type.Optional(Type.String({ description: "Short reason for this plan update" })),
21
+ plan: Type.Array(PlanStepSchema, {
22
+ minItems: 1,
23
+ maxItems: 8,
24
+ description: "Full current plan. Exactly zero or one step may be in_progress."
25
+ })
26
+ });
27
+ function normalizePlan(raw) {
28
+ if (!Array.isArray(raw)) throw new Error("plan must be an array");
29
+ const plan = raw.map((item) => {
30
+ const rec = item && typeof item === "object" ? item : {};
31
+ const step = String(rec.step ?? "").trim();
32
+ const statusRaw = String(rec.status ?? "").trim();
33
+ if (!step) throw new Error("each plan item must include a non-empty step");
34
+ if (!VALID_STATUSES.has(statusRaw)) throw new Error(`invalid plan status: ${statusRaw || "(empty)"}`);
35
+ return {
36
+ step,
37
+ status: statusRaw
38
+ };
39
+ });
40
+ if (plan.filter((item) => item.status === "in_progress").length > 1) throw new Error("at most one plan item may be in_progress");
41
+ return plan;
42
+ }
43
+ function formatPlan(details) {
44
+ const lines = details.plan.map((item) => `- [${item.status}] ${item.step}`);
45
+ return [details.explanation?.trim(), ...lines].filter(Boolean).join("\n");
46
+ }
47
+ function createUpdatePlanTool() {
48
+ return {
49
+ name: "update_plan",
50
+ label: "Update Plan",
51
+ description: "Update the current coding-task plan. Use for multi-step implementation, review, or debugging work. Keep the full plan current, with at most one step marked in_progress.",
52
+ parameters: UpdatePlanSchema,
53
+ async execute(_toolCallId, params) {
54
+ const rec = params;
55
+ const details = {
56
+ explanation: typeof rec.explanation === "string" && rec.explanation.trim() ? rec.explanation.trim() : void 0,
57
+ plan: normalizePlan(rec.plan)
58
+ };
59
+ return {
60
+ content: [{
61
+ type: "text",
62
+ text: formatPlan(details)
63
+ }],
64
+ details
65
+ };
66
+ }
67
+ };
68
+ }
69
+ //#endregion
70
+ export { createUpdatePlanTool };
71
+
72
+ //# sourceMappingURL=update-plan-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-plan-tool.js","names":[],"sources":["../../../../src/agent/tools/update-plan-tool.ts"],"sourcesContent":["import { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\n\nexport type TurnPlanStatus = 'pending' | 'in_progress' | 'completed';\n\nexport interface TurnPlanStep {\n step: string;\n status: TurnPlanStatus;\n}\n\nexport interface TurnPlanDetails {\n explanation?: string;\n plan: TurnPlanStep[];\n}\n\nconst VALID_STATUSES = new Set<TurnPlanStatus>(['pending', 'in_progress', 'completed']);\n\nconst PlanStepSchema = Type.Object({\n step: Type.String({ minLength: 1, description: 'Short task step' }),\n status: Type.Union([\n Type.Literal('pending'),\n Type.Literal('in_progress'),\n Type.Literal('completed'),\n ]),\n});\n\nconst UpdatePlanSchema = Type.Object({\n explanation: Type.Optional(Type.String({ description: 'Short reason for this plan update' })),\n plan: Type.Array(PlanStepSchema, {\n minItems: 1,\n maxItems: 8,\n description: 'Full current plan. Exactly zero or one step may be in_progress.',\n }),\n});\n\nfunction normalizePlan(raw: unknown): TurnPlanStep[] {\n if (!Array.isArray(raw)) {\n throw new Error('plan must be an array');\n }\n const plan = raw.map((item) => {\n const rec = item && typeof item === 'object' ? item as Record<string, unknown> : {};\n const step = String(rec.step ?? '').trim();\n const statusRaw = String(rec.status ?? '').trim();\n if (!step) {\n throw new Error('each plan item must include a non-empty step');\n }\n if (!VALID_STATUSES.has(statusRaw as TurnPlanStatus)) {\n throw new Error(`invalid plan status: ${statusRaw || '(empty)'}`);\n }\n return { step, status: statusRaw as TurnPlanStatus };\n });\n\n const active = plan.filter((item) => item.status === 'in_progress');\n if (active.length > 1) {\n throw new Error('at most one plan item may be in_progress');\n }\n return plan;\n}\n\nfunction formatPlan(details: TurnPlanDetails): string {\n const lines = details.plan.map((item) => `- [${item.status}] ${item.step}`);\n return [details.explanation?.trim(), ...lines].filter(Boolean).join('\\n');\n}\n\nexport function createUpdatePlanTool(): AgentTool {\n return {\n name: 'update_plan',\n label: 'Update Plan',\n description:\n 'Update the current coding-task plan. Use for multi-step implementation, review, or debugging work. ' +\n 'Keep the full plan current, with at most one step marked in_progress.',\n parameters: UpdatePlanSchema,\n async execute(_toolCallId, params): Promise<AgentToolResult<TurnPlanDetails>> {\n const rec = params as Record<string, unknown>;\n const details: TurnPlanDetails = {\n explanation: typeof rec.explanation === 'string' && rec.explanation.trim()\n ? rec.explanation.trim()\n : undefined,\n plan: normalizePlan(rec.plan),\n };\n return {\n content: [{ type: 'text', text: formatPlan(details) }],\n details,\n };\n },\n };\n}\n"],"mappings":";;AAeA,MAAM,iBAAiB,IAAI,IAAoB;CAAC;CAAW;CAAe;CAAY,CAAC;AAEvF,MAAM,iBAAiB,KAAK,OAAO;CACjC,MAAM,KAAK,OAAO;EAAE,WAAW;EAAG,aAAa;EAAmB,CAAC;CACnE,QAAQ,KAAK,MAAM;EACjB,KAAK,QAAQ,UAAU;EACvB,KAAK,QAAQ,cAAc;EAC3B,KAAK,QAAQ,YAAY;EAC1B,CAAC;CACH,CAAC;AAEF,MAAM,mBAAmB,KAAK,OAAO;CACnC,aAAa,KAAK,SAAS,KAAK,OAAO,EAAE,aAAa,qCAAqC,CAAC,CAAC;CAC7F,MAAM,KAAK,MAAM,gBAAgB;EAC/B,UAAU;EACV,UAAU;EACV,aAAa;EACd,CAAC;CACH,CAAC;AAEF,SAAS,cAAc,KAA8B;AACnD,KAAI,CAAC,MAAM,QAAQ,IAAI,CACrB,OAAM,IAAI,MAAM,wBAAwB;CAE1C,MAAM,OAAO,IAAI,KAAK,SAAS;EAC7B,MAAM,MAAM,QAAQ,OAAO,SAAS,WAAW,OAAkC,EAAE;EACnF,MAAM,OAAO,OAAO,IAAI,QAAQ,GAAG,CAAC,MAAM;EAC1C,MAAM,YAAY,OAAO,IAAI,UAAU,GAAG,CAAC,MAAM;AACjD,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,+CAA+C;AAEjE,MAAI,CAAC,eAAe,IAAI,UAA4B,CAClD,OAAM,IAAI,MAAM,wBAAwB,aAAa,YAAY;AAEnE,SAAO;GAAE;GAAM,QAAQ;GAA6B;GACpD;AAGF,KADe,KAAK,QAAQ,SAAS,KAAK,WAAW,cAC3C,CAAC,SAAS,EAClB,OAAM,IAAI,MAAM,2CAA2C;AAE7D,QAAO;;AAGT,SAAS,WAAW,SAAkC;CACpD,MAAM,QAAQ,QAAQ,KAAK,KAAK,SAAS,MAAM,KAAK,OAAO,IAAI,KAAK,OAAO;AAC3E,QAAO,CAAC,QAAQ,aAAa,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK;;AAG3E,SAAgB,uBAAkC;AAChD,QAAO;EACL,MAAM;EACN,OAAO;EACP,aACE;EAEF,YAAY;EACZ,MAAM,QAAQ,aAAa,QAAmD;GAC5E,MAAM,MAAM;GACZ,MAAM,UAA2B;IAC/B,aAAa,OAAO,IAAI,gBAAgB,YAAY,IAAI,YAAY,MAAM,GACtE,IAAI,YAAY,MAAM,GACtB,KAAA;IACJ,MAAM,cAAc,IAAI,KAAK;IAC9B;AACD,UAAO;IACL,SAAS,CAAC;KAAE,MAAM;KAAQ,MAAM,WAAW,QAAQ;KAAE,CAAC;IACtD;IACD;;EAEJ"}
@@ -10,4 +10,4 @@
10
10
  * - logs: optional log excerpt
11
11
  * - context: optional extra context (what changed, when it started)
12
12
  */
13
- export declare const DEBUG_INCIDENT_SCRIPT = "export const meta = {\n name: 'debug_incident',\n description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',\n whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',\n examplePrompts: [\n { field: 'error', text: 'Triage this stack trace from production' },\n { field: 'error', text: 'Why does the gateway return 502 after deploy?' },\n ],\n i18n: {\n zh: {\n description: '\u5BF9\u9519\u8BEF\u6216\u65E5\u5FD7\u7247\u6BB5\u505A\u5E76\u884C\u5047\u8BBE\u63A8\u6F14\uFF0C\u5E76\u6392\u5E8F\u6839\u56E0\u4E0E\u9A8C\u8BC1\u6B65\u9AA4\u3002',\n whenToUse: '\u7528\u6237\u62A5\u544A bug\u3001\u5D29\u6E83\u3001\u62A5\u9519\u6216\u5F02\u5E38\u884C\u4E3A\uFF0C\u9700\u8981\u7CFB\u7EDF\u5316\u6392\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'error', text: '\u6392\u67E5\u751F\u4EA7\u73AF\u5883\u8FD9\u6761\u5806\u6808' },\n { field: 'error', text: '\u90E8\u7F72\u540E\u7F51\u5173\u8FD4\u56DE 502\uFF0C\u53EF\u80FD\u662F\u4EC0\u4E48\u539F\u56E0\uFF1F' },\n ],\n },\n },\n tags: ['debug', 'incident', 'troubleshooting'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Triage' },\n { title: 'Hypotheses' },\n { title: 'Rank' },\n ],\n}\n\nconst READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst error = args && typeof args === 'object' && args.error\n ? String(args.error)\n : 'Infer the primary error from the most recent user message or conversation context.'\n\nconst logs = args && typeof args === 'object' && args.logs\n ? String(args.logs)\n : ''\n\nconst context = args && typeof args === 'object' && args.context\n ? String(args.context)\n : ''\n\nphase('Triage')\nconst triage = await agent(\n 'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2\u20133 key facts from logs.\\n\\n' +\n 'ERROR:\\n' + error + '\\n\\n' +\n (logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +\n (context ? 'CONTEXT:\\n' + context + '\\n\\n' : '') +\n 'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',\n {\n label: 'incident triage',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n errorType: { type: 'string' },\n subsystem: { type: 'string' },\n affectedPaths: { type: 'array', items: { type: 'string' } },\n keyFacts: { type: 'array', items: { type: 'string' } },\n },\n required: ['errorType', 'keyFacts'],\n },\n },\n)\n\nconst HYPOTHESES = [\n { key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },\n { key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },\n { key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },\n { key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },\n { key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },\n]\n\nphase('Hypotheses')\nconst hypothesisReports = await parallel(\n HYPOTHESES.map((h) => () =>\n agent(\n 'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\n\\n' +\n 'HYPOTHESIS: ' + h.key + ' \u2014 ' + h.angle + '\\n\\n' +\n 'TRIAGE:\\n' + JSON.stringify(triage, null, 2) + '\\n\\n' +\n 'ERROR:\\n' + error + '\\n\\n' +\n (logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +\n 'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',\n {\n label: h.key + ' hypothesis',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n evidence: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n note: { type: 'string' },\n },\n required: ['path', 'note'],\n },\n },\n verificationStep: { type: 'string' },\n },\n required: ['likelihood', 'evidence', 'verificationStep'],\n },\n },\n ),\n ),\n)\n\nphase('Rank')\nconst live = hypothesisReports.filter(Boolean)\nconst byHypothesis = {}\nfor (let i = 0; i < HYPOTHESES.length; i++) {\n byHypothesis[HYPOTHESES[i].key] = live[i] ?? null\n}\n\nconst ranking = await agent(\n 'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\n\\n' +\n JSON.stringify({ triage, byHypothesis }, null, 2),\n {\n label: 'root cause ranking',\n schema: {\n type: 'object',\n properties: {\n topCauses: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n hypothesis: { type: 'string' },\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n summary: { type: 'string' },\n nextStep: { type: 'string' },\n },\n required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],\n },\n },\n immediateActions: { type: 'array', items: { type: 'string' } },\n summary: { type: 'string' },\n },\n required: ['topCauses', 'summary'],\n },\n },\n)\n\nconst output = {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Top causes', items: output.topCauses.map((item) => ({ title: item.hypothesis, severity: item.likelihood, detail: item.summary, mitigation: item.nextStep })) },\n { kind: 'questions', title: 'Immediate actions', items: output.immediateActions ?? [] },\n ],\n structuredOutput: output,\n}\n";
13
+ export declare const DEBUG_INCIDENT_SCRIPT = "export const meta = {\n name: 'debug_incident',\n description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',\n whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',\n examplePrompts: [\n { field: 'error', text: 'Triage this stack trace from production' },\n { field: 'error', text: 'Why does the gateway return 502 after deploy?' },\n ],\n i18n: {\n zh: {\n description: '\u5BF9\u9519\u8BEF\u6216\u65E5\u5FD7\u7247\u6BB5\u505A\u5E76\u884C\u5047\u8BBE\u63A8\u6F14\uFF0C\u5E76\u6392\u5E8F\u6839\u56E0\u4E0E\u9A8C\u8BC1\u6B65\u9AA4\u3002',\n whenToUse: '\u7528\u6237\u62A5\u544A bug\u3001\u5D29\u6E83\u3001\u62A5\u9519\u6216\u5F02\u5E38\u884C\u4E3A\uFF0C\u9700\u8981\u7CFB\u7EDF\u5316\u6392\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'error', text: '\u6392\u67E5\u751F\u4EA7\u73AF\u5883\u8FD9\u6761\u5806\u6808' },\n { field: 'error', text: '\u90E8\u7F72\u540E\u7F51\u5173\u8FD4\u56DE 502\uFF0C\u53EF\u80FD\u662F\u4EC0\u4E48\u539F\u56E0\uFF1F' },\n ],\n },\n },\n tags: ['debug', 'incident', 'troubleshooting'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Triage' },\n { title: 'Hypotheses' },\n { title: 'Rank' },\n ],\n}\n\nconst READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst error = args && typeof args === 'object' && args.error\n ? String(args.error)\n : 'Infer the primary error from the most recent user message or conversation context.'\n\nconst logs = args && typeof args === 'object' && args.logs\n ? String(args.logs)\n : ''\n\nconst context = args && typeof args === 'object' && args.context\n ? String(args.context)\n : ''\n\nphase('Triage')\nconst triage = await agent(\n 'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2\u20133 key facts from logs.\\n\\n' +\n 'ERROR:\\n' + error + '\\n\\n' +\n (logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +\n (context ? 'CONTEXT:\\n' + context + '\\n\\n' : '') +\n 'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',\n {\n label: 'incident triage',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n errorType: { type: 'string' },\n subsystem: { type: 'string' },\n affectedPaths: { type: 'array', items: { type: 'string' } },\n keyFacts: { type: 'array', items: { type: 'string' } },\n },\n required: ['errorType', 'keyFacts'],\n },\n },\n)\n\nconst HYPOTHESES = [\n { key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },\n { key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },\n { key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },\n { key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },\n { key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },\n]\n\nphase('Hypotheses')\nconst hypothesisReports = await parallel(\n HYPOTHESES.map((h) => () =>\n agent(\n 'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\n\\n' +\n 'HYPOTHESIS: ' + h.key + ' \u2014 ' + h.angle + '\\n\\n' +\n 'TRIAGE:\\n' + JSON.stringify(triage, null, 2) + '\\n\\n' +\n 'ERROR:\\n' + error + '\\n\\n' +\n (logs ? 'LOGS:\\n' + logs + '\\n\\n' : '') +\n 'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',\n {\n label: h.key + ' hypothesis',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n evidence: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n note: { type: 'string' },\n },\n required: ['path', 'note'],\n },\n },\n verificationStep: { type: 'string' },\n },\n required: ['likelihood', 'evidence', 'verificationStep'],\n },\n },\n ),\n ),\n)\n\nphase('Rank')\nconst live = hypothesisReports.filter(Boolean)\nconst byHypothesis = {}\nfor (let i = 0; i < HYPOTHESES.length; i++) {\n byHypothesis[HYPOTHESES[i].key] = live[i] ?? null\n}\n\nconst ranking = await agent(\n 'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\n\\n' +\n JSON.stringify({ triage, byHypothesis }, null, 2),\n {\n label: 'root cause ranking',\n schema: {\n type: 'object',\n properties: {\n topCauses: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n hypothesis: { type: 'string' },\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n summary: { type: 'string' },\n nextStep: { type: 'string' },\n },\n required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],\n },\n },\n immediateActions: { type: 'array', items: { type: 'string' } },\n summary: { type: 'string' },\n },\n required: ['topCauses', 'summary'],\n },\n },\n)\n\nconst output = {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Top causes', items: output.topCauses.map((item) => ({ title: item.hypothesis, severity: item.likelihood, detail: item.summary, mitigation: item.nextStep })) },\n { kind: 'questions', title: 'Immediate actions', items: output.immediateActions ?? [] },\n ],\n structuredOutput: output,\n}\n";
@@ -38,7 +38,7 @@ const DEBUG_INCIDENT_SCRIPT = `export const meta = {
38
38
  ],
39
39
  }
40
40
 
41
- const READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
41
+ const READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']
42
42
 
43
43
  const error = args && typeof args === 'object' && args.error
44
44
  ? String(args.error)
@@ -1 +1 @@
1
- {"version":3,"file":"debug-incident.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/debug-incident.ts"],"sourcesContent":["/**\n * Built-in workflow: `debug_incident`\n *\n * Triage an error, stack trace, or log snippet. Parses the signal, fans out\n * parallel hypotheses (config, race, dependency, data, environment), then\n * ranks likely root causes with verification steps.\n *\n * Args:\n * - error: error message or stack trace\n * - logs: optional log excerpt\n * - context: optional extra context (what changed, when it started)\n */\n\nexport const DEBUG_INCIDENT_SCRIPT = `export const meta = {\n name: 'debug_incident',\n description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',\n whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',\n examplePrompts: [\n { field: 'error', text: 'Triage this stack trace from production' },\n { field: 'error', text: 'Why does the gateway return 502 after deploy?' },\n ],\n i18n: {\n zh: {\n description: '对错误或日志片段做并行假设推演,并排序根因与验证步骤。',\n whenToUse: '用户报告 bug、崩溃、报错或异常行为,需要系统化排查时。',\n examplePrompts: [\n { field: 'error', text: '排查生产环境这条堆栈' },\n { field: 'error', text: '部署后网关返回 502,可能是什么原因?' },\n ],\n },\n },\n tags: ['debug', 'incident', 'troubleshooting'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Triage' },\n { title: 'Hypotheses' },\n { title: 'Rank' },\n ],\n}\n\nconst READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst error = args && typeof args === 'object' && args.error\n ? String(args.error)\n : 'Infer the primary error from the most recent user message or conversation context.'\n\nconst logs = args && typeof args === 'object' && args.logs\n ? String(args.logs)\n : ''\n\nconst context = args && typeof args === 'object' && args.context\n ? String(args.context)\n : ''\n\nphase('Triage')\nconst triage = await agent(\n 'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2–3 key facts from logs.\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n (context ? 'CONTEXT:\\\\n' + context + '\\\\n\\\\n' : '') +\n 'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',\n {\n label: 'incident triage',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n errorType: { type: 'string' },\n subsystem: { type: 'string' },\n affectedPaths: { type: 'array', items: { type: 'string' } },\n keyFacts: { type: 'array', items: { type: 'string' } },\n },\n required: ['errorType', 'keyFacts'],\n },\n },\n)\n\nconst HYPOTHESES = [\n { key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },\n { key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },\n { key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },\n { key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },\n { key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },\n]\n\nphase('Hypotheses')\nconst hypothesisReports = await parallel(\n HYPOTHESES.map((h) => () =>\n agent(\n 'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\\\n\\\\n' +\n 'HYPOTHESIS: ' + h.key + ' — ' + h.angle + '\\\\n\\\\n' +\n 'TRIAGE:\\\\n' + JSON.stringify(triage, null, 2) + '\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n 'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',\n {\n label: h.key + ' hypothesis',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n evidence: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n note: { type: 'string' },\n },\n required: ['path', 'note'],\n },\n },\n verificationStep: { type: 'string' },\n },\n required: ['likelihood', 'evidence', 'verificationStep'],\n },\n },\n ),\n ),\n)\n\nphase('Rank')\nconst live = hypothesisReports.filter(Boolean)\nconst byHypothesis = {}\nfor (let i = 0; i < HYPOTHESES.length; i++) {\n byHypothesis[HYPOTHESES[i].key] = live[i] ?? null\n}\n\nconst ranking = await agent(\n 'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\\\n\\\\n' +\n JSON.stringify({ triage, byHypothesis }, null, 2),\n {\n label: 'root cause ranking',\n schema: {\n type: 'object',\n properties: {\n topCauses: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n hypothesis: { type: 'string' },\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n summary: { type: 'string' },\n nextStep: { type: 'string' },\n },\n required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],\n },\n },\n immediateActions: { type: 'array', items: { type: 'string' } },\n summary: { type: 'string' },\n },\n required: ['topCauses', 'summary'],\n },\n },\n)\n\nconst output = {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Top causes', items: output.topCauses.map((item) => ({ title: item.hypothesis, severity: item.likelihood, detail: item.summary, mitigation: item.nextStep })) },\n { kind: 'questions', title: 'Immediate actions', items: output.immediateActions ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,wBAAwB"}
1
+ {"version":3,"file":"debug-incident.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/debug-incident.ts"],"sourcesContent":["/**\n * Built-in workflow: `debug_incident`\n *\n * Triage an error, stack trace, or log snippet. Parses the signal, fans out\n * parallel hypotheses (config, race, dependency, data, environment), then\n * ranks likely root causes with verification steps.\n *\n * Args:\n * - error: error message or stack trace\n * - logs: optional log excerpt\n * - context: optional extra context (what changed, when it started)\n */\n\nexport const DEBUG_INCIDENT_SCRIPT = `export const meta = {\n name: 'debug_incident',\n description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',\n whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',\n examplePrompts: [\n { field: 'error', text: 'Triage this stack trace from production' },\n { field: 'error', text: 'Why does the gateway return 502 after deploy?' },\n ],\n i18n: {\n zh: {\n description: '对错误或日志片段做并行假设推演,并排序根因与验证步骤。',\n whenToUse: '用户报告 bug、崩溃、报错或异常行为,需要系统化排查时。',\n examplePrompts: [\n { field: 'error', text: '排查生产环境这条堆栈' },\n { field: 'error', text: '部署后网关返回 502,可能是什么原因?' },\n ],\n },\n },\n tags: ['debug', 'incident', 'troubleshooting'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Triage' },\n { title: 'Hypotheses' },\n { title: 'Rank' },\n ],\n}\n\nconst READ_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst error = args && typeof args === 'object' && args.error\n ? String(args.error)\n : 'Infer the primary error from the most recent user message or conversation context.'\n\nconst logs = args && typeof args === 'object' && args.logs\n ? String(args.logs)\n : ''\n\nconst context = args && typeof args === 'object' && args.context\n ? String(args.context)\n : ''\n\nphase('Triage')\nconst triage = await agent(\n 'Parse this incident signal. Extract: error type, likely subsystem, affected files/modules if identifiable, and 2–3 key facts from logs.\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n (context ? 'CONTEXT:\\\\n' + context + '\\\\n\\\\n' : '') +\n 'Use read/grep tools to locate relevant code if the workspace may contain the failing path.',\n {\n label: 'incident triage',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n errorType: { type: 'string' },\n subsystem: { type: 'string' },\n affectedPaths: { type: 'array', items: { type: 'string' } },\n keyFacts: { type: 'array', items: { type: 'string' } },\n },\n required: ['errorType', 'keyFacts'],\n },\n },\n)\n\nconst HYPOTHESES = [\n { key: 'config', angle: 'Misconfiguration, missing env vars, wrong defaults, feature flags, stale config cache.' },\n { key: 'race', angle: 'Concurrency, timing, ordering, partial failure under load, missing locks or awaits.' },\n { key: 'dependency', angle: 'Version mismatch, breaking upstream change, network/API failure, timeout, auth expiry.' },\n { key: 'data', angle: 'Bad input, schema drift, null/empty edge case, corrupt state, migration gap.' },\n { key: 'environment', angle: 'OS, permissions, disk, memory, container/network isolation, platform-specific behavior.' },\n]\n\nphase('Hypotheses')\nconst hypothesisReports = await parallel(\n HYPOTHESES.map((h) => () =>\n agent(\n 'Evaluate whether this hypothesis explains the incident. Search the codebase for supporting or refuting evidence.\\\\n\\\\n' +\n 'HYPOTHESIS: ' + h.key + ' — ' + h.angle + '\\\\n\\\\n' +\n 'TRIAGE:\\\\n' + JSON.stringify(triage, null, 2) + '\\\\n\\\\n' +\n 'ERROR:\\\\n' + error + '\\\\n\\\\n' +\n (logs ? 'LOGS:\\\\n' + logs + '\\\\n\\\\n' : '') +\n 'Return: likelihood (low/med/high), evidence (file paths + brief notes), and one verification step.',\n {\n label: h.key + ' hypothesis',\n toolset: READ_TOOLS,\n schema: {\n type: 'object',\n properties: {\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n evidence: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n note: { type: 'string' },\n },\n required: ['path', 'note'],\n },\n },\n verificationStep: { type: 'string' },\n },\n required: ['likelihood', 'evidence', 'verificationStep'],\n },\n },\n ),\n ),\n)\n\nphase('Rank')\nconst live = hypothesisReports.filter(Boolean)\nconst byHypothesis = {}\nfor (let i = 0; i < HYPOTHESES.length; i++) {\n byHypothesis[HYPOTHESES[i].key] = live[i] ?? null\n}\n\nconst ranking = await agent(\n 'Rank root causes by likelihood. Pick the top 3 with confidence and concrete next steps to confirm or fix.\\\\n\\\\n' +\n JSON.stringify({ triage, byHypothesis }, null, 2),\n {\n label: 'root cause ranking',\n schema: {\n type: 'object',\n properties: {\n topCauses: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n hypothesis: { type: 'string' },\n likelihood: { type: 'string', enum: ['low', 'med', 'high'] },\n summary: { type: 'string' },\n nextStep: { type: 'string' },\n },\n required: ['hypothesis', 'likelihood', 'summary', 'nextStep'],\n },\n },\n immediateActions: { type: 'array', items: { type: 'string' } },\n summary: { type: 'string' },\n },\n required: ['topCauses', 'summary'],\n },\n },\n)\n\nconst output = {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Top causes', items: output.topCauses.map((item) => ({ title: item.hypothesis, severity: item.likelihood, detail: item.summary, mitigation: item.nextStep })) },\n { kind: 'questions', title: 'Immediate actions', items: output.immediateActions ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,wBAAwB"}
@@ -9,4 +9,4 @@
9
9
  * - target: PR description, diff, commit range, or file list
10
10
  * - diff: alias for target
11
11
  */
12
- export declare const PR_REVIEW_SCRIPT = "export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u805A\u7126\u5BA1\u67E5 PR\u3001diff \u6216\u63D0\u4EA4\u8303\u56F4\uFF0C\u5E76\u7ED9\u51FA\u53EF\u5408\u5E76/\u5E94\u62E6\u622A\u7684\u7ED3\u8BBA\u3002',\n whenToUse: '\u7528\u6237\u8981\u5BA1\u67E5 PR\u3001diff\u3001\u7279\u5B9A\u6539\u52A8\u6216\u63D0\u4EA4\u8303\u56F4\uFF08\u800C\u975E\u6574\u5E93\uFF09\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u5BA1\u67E5\u5F53\u524D\u5206\u652F\u4E0A\u7684\u6539\u52A8' },\n { field: 'target', text: '\u5BA1\u67E5 PR #42\uFF0C\u7ED9\u51FA\u662F\u5426\u53EF\u5408\u5E76\u7684\u7ED3\u8BBA' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\n' +\n 'Focus: ' + r.focus + '\\n\\n' +\n 'TARGET:\\n' + reviewTarget + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n";
12
+ export declare const PR_REVIEW_SCRIPT = "export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u805A\u7126\u5BA1\u67E5 PR\u3001diff \u6216\u63D0\u4EA4\u8303\u56F4\uFF0C\u5E76\u7ED9\u51FA\u53EF\u5408\u5E76/\u5E94\u62E6\u622A\u7684\u7ED3\u8BBA\u3002',\n whenToUse: '\u7528\u6237\u8981\u5BA1\u67E5 PR\u3001diff\u3001\u7279\u5B9A\u6539\u52A8\u6216\u63D0\u4EA4\u8303\u56F4\uFF08\u800C\u975E\u6574\u5E93\uFF09\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u5BA1\u67E5\u5F53\u524D\u5206\u652F\u4E0A\u7684\u6539\u52A8' },\n { field: 'target', text: '\u5BA1\u67E5 PR #42\uFF0C\u7ED9\u51FA\u662F\u5426\u53EF\u5408\u5E76\u7684\u7ED3\u8BBA' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\n\\nTARGET:\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\n' +\n 'Focus: ' + r.focus + '\\n\\n' +\n 'TARGET:\\n' + reviewTarget + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\n\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n";
@@ -37,7 +37,7 @@ const PR_REVIEW_SCRIPT = `export const meta = {
37
37
  ],
38
38
  }
39
39
 
40
- const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
40
+ const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']
41
41
 
42
42
  const target = args && typeof args === 'object'
43
43
  ? String(args.target ?? args.diff ?? '')
@@ -1 +1 @@
1
- {"version":3,"file":"pr-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/pr-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `pr_review`\n *\n * Focused review of a PR, diff, or commit range — lighter than full repo audit.\n * Parallel reviewers cover correctness, security, tests, API compat, and perf;\n * final phase produces a ship/block verdict with blockers vs suggestions.\n *\n * Args:\n * - target: PR description, diff, commit range, or file list\n * - diff: alias for target\n */\n\nexport const PR_REVIEW_SCRIPT = `export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '并行聚焦审查 PR、diff 或提交范围,并给出可合并/应拦截的结论。',\n whenToUse: '用户要审查 PR、diff、特定改动或提交范围(而非整库)时。',\n examplePrompts: [\n { field: 'target', text: '审查当前分支上的改动' },\n { field: 'target', text: '审查 PR #42,给出是否可合并的结论' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\\\n\\\\nTARGET:\\\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\\\n' +\n 'Focus: ' + r.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + reviewTarget + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\\\n\\\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,mBAAmB"}
1
+ {"version":3,"file":"pr-review.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/pr-review.ts"],"sourcesContent":["/**\n * Built-in workflow: `pr_review`\n *\n * Focused review of a PR, diff, or commit range — lighter than full repo audit.\n * Parallel reviewers cover correctness, security, tests, API compat, and perf;\n * final phase produces a ship/block verdict with blockers vs suggestions.\n *\n * Args:\n * - target: PR description, diff, commit range, or file list\n * - diff: alias for target\n */\n\nexport const PR_REVIEW_SCRIPT = `export const meta = {\n name: 'pr_review',\n description: 'Review a PR/diff/commit range with parallel focused reviewers and a ship/block verdict.',\n whenToUse: 'User asks to review a PR, diff, specific changes, or commit range (not the whole repo).',\n examplePrompts: [\n { field: 'target', text: 'Review the changes on this branch' },\n { field: 'target', text: 'Review PR #42 for ship/block verdict' },\n ],\n i18n: {\n zh: {\n description: '并行聚焦审查 PR、diff 或提交范围,并给出可合并/应拦截的结论。',\n whenToUse: '用户要审查 PR、diff、特定改动或提交范围(而非整库)时。',\n examplePrompts: [\n { field: 'target', text: '审查当前分支上的改动' },\n { field: 'target', text: '审查 PR #42,给出是否可合并的结论' },\n ],\n },\n },\n tags: ['code-review', 'pr'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Review' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst target = args && typeof args === 'object'\n ? String(args.target ?? args.diff ?? '')\n : ''\nconst reviewTarget = target.trim()\n ? target\n : 'Recent changes in the working tree or the diff/context from the current conversation.'\n\nconst REVIEWERS = [\n { key: 'correctness', focus: 'Logic bugs, edge cases, error handling, null safety, race conditions in changed code.' },\n { key: 'security', focus: 'Auth/authz regressions, input validation, secret exposure, injection, unsafe deserialization in the diff.' },\n { key: 'tests', focus: 'Missing tests for changed behavior, brittle assertions, untested edge cases introduced by this change.' },\n { key: 'api_compat', focus: 'Breaking public API changes, schema migrations, backward compatibility, deprecation handling.' },\n { key: 'perf', focus: 'Regressions in hot paths, accidental N+1, sync I/O, unbounded loops or allocations in changed code.' },\n]\n\nphase('Scope')\nconst scope = await agent(\n 'Identify what changed for this review target. List changed files, blast radius (what depends on them), and the apparent intent of the change. Be concise.\\\\n\\\\nTARGET:\\\\n' +\n reviewTarget,\n {\n label: 'change scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedFiles: { type: 'array', items: { type: 'string' } },\n intent: { type: 'string' },\n blastRadius: { type: 'string' },\n },\n required: ['changedFiles', 'intent'],\n },\n },\n)\n\nphase('Review')\nconst reviews = await parallel(\n REVIEWERS.map((r) => () =>\n agent(\n 'Review these changes through the ' + r.key + ' lens.\\\\n' +\n 'Focus: ' + r.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + reviewTarget + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return findings: file, severity (low/med/high/blocker), title, fix suggestion. Blocker = must fix before merge.',\n {\n label: r.key,\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string', enum: ['low', 'med', 'high', 'blocker'] },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'severity', 'title', 'fix'],\n },\n },\n },\n required: ['findings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst live = reviews.filter(Boolean)\nconst byReviewer = {}\nfor (let i = 0; i < REVIEWERS.length; i++) {\n byReviewer[REVIEWERS[i].key] = live[i]?.findings ?? []\n}\n\nconst verdict = await agent(\n 'Synthesize a PR review verdict. Separate blockers from suggestions. Deduplicate. Recommend ship | fix_first | block.\\\\n\\\\n' +\n JSON.stringify(byReviewer, null, 2),\n {\n label: 'verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship', 'fix_first', 'block'] },\n summary: { type: 'string' },\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n suggestions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n },\n required: ['file', 'title'],\n },\n },\n },\n required: ['recommendation', 'summary', 'blockers'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target: reviewTarget,\n scope,\n ...(verdict ?? { recommendation: 'fix_first', summary: 'verdict failed', blockers: [], suggestions: [] }),\n byReviewer,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'findings', title: 'Blockers', items: output.blockers.map((item) => ({ title: item.title, severity: 'high', file: item.file, detail: item.fix })) },\n { kind: 'findings', title: 'Suggestions', items: output.suggestions.map((item) => ({ title: item.title, severity: item.severity, file: item.file })) },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,mBAAmB"}
@@ -8,4 +8,4 @@
8
8
  * - target: release candidate, branch, commit range, or feature summary
9
9
  * - checks: optional subset of check keys
10
10
  */
11
- export declare const RELEASE_CHECK_SCRIPT = "export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u68C0\u67E5\u53D1\u5E03\u98CE\u9669\uFF0C\u5224\u65AD\u53D8\u66F4\u662F\u5426\u8FBE\u5230\u53EF\u53D1\u5E03\u6807\u51C6\u3002',\n whenToUse: '\u7528\u6237\u63A5\u8FD1\u5F00\u53D1\u5C3E\u58F0\uFF0C\u60F3\u5728\u53D1\u5E03\u524D\u505A\u53D1\u5E03\u8D28\u91CF/\u5C31\u7EEA\u68C0\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u8FD9\u4E2A\u4ED3\u5E93\u662F\u5426\u51C6\u5907\u597D\u53D1\u5E03 v1.2\uFF1F' },\n { field: 'target', text: '\u5BF9\u5F53\u524D\u5206\u652F\u505A\u53D1\u5E03\u524D\u5C31\u7EEA\u68C0\u67E5' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\n\\n' +\n 'TARGET:\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\n' +\n 'Focus: ' + check.focus + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\n\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n";
11
+ export declare const RELEASE_CHECK_SCRIPT = "export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u68C0\u67E5\u53D1\u5E03\u98CE\u9669\uFF0C\u5224\u65AD\u53D8\u66F4\u662F\u5426\u8FBE\u5230\u53EF\u53D1\u5E03\u6807\u51C6\u3002',\n whenToUse: '\u7528\u6237\u63A5\u8FD1\u5F00\u53D1\u5C3E\u58F0\uFF0C\u60F3\u5728\u53D1\u5E03\u524D\u505A\u53D1\u5E03\u8D28\u91CF/\u5C31\u7EEA\u68C0\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u8FD9\u4E2A\u4ED3\u5E93\u662F\u5426\u51C6\u5907\u597D\u53D1\u5E03 v1.2\uFF1F' },\n { field: 'target', text: '\u5BF9\u5F53\u524D\u5206\u652F\u505A\u53D1\u5E03\u524D\u5C31\u7EEA\u68C0\u67E5' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\n\\n' +\n 'TARGET:\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\n' +\n 'Focus: ' + check.focus + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'SCOPE:\\n' + JSON.stringify(scope, null, 2) + '\\n\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\n\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n";
@@ -36,7 +36,7 @@ const RELEASE_CHECK_SCRIPT = `export const meta = {
36
36
  ],
37
37
  }
38
38
 
39
- const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']
39
+ const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']
40
40
 
41
41
  const target = args && typeof args === 'object' && args.target
42
42
  ? String(args.target)
@@ -1 +1 @@
1
- {"version":3,"file":"release-check.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/release-check.ts"],"sourcesContent":["/**\n * Built-in workflow: `release_check`\n *\n * Runs a release-readiness review for a finished change. It inspects the diff,\n * validates risk areas in parallel, and produces a go/no-go checklist.\n *\n * Args:\n * - target: release candidate, branch, commit range, or feature summary\n * - checks: optional subset of check keys\n */\n\nexport const RELEASE_CHECK_SCRIPT = `export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '并行检查发布风险,判断变更是否达到可发布标准。',\n whenToUse: '用户接近开发尾声,想在发布前做发布质量/就绪检查时。',\n examplePrompts: [\n { field: 'target', text: '这个仓库是否准备好发布 v1.2?' },\n { field: 'target', text: '对当前分支做发布前就绪检查' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'shell']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\\\n\\\\n' +\n 'TARGET:\\\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\\\n' +\n 'Focus: ' + check.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\\\n\\\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,uBAAuB"}
1
+ {"version":3,"file":"release-check.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/release-check.ts"],"sourcesContent":["/**\n * Built-in workflow: `release_check`\n *\n * Runs a release-readiness review for a finished change. It inspects the diff,\n * validates risk areas in parallel, and produces a go/no-go checklist.\n *\n * Args:\n * - target: release candidate, branch, commit range, or feature summary\n * - checks: optional subset of check keys\n */\n\nexport const RELEASE_CHECK_SCRIPT = `export const meta = {\n name: 'release_check',\n description: 'Assess whether a change is ready to release with parallel risk checks and a go/no-go verdict.',\n whenToUse: 'User is near the end of implementation and wants a release-quality readiness check before shipping.',\n examplePrompts: [\n { field: 'target', text: 'Is this repo ready to release v1.2?' },\n { field: 'target', text: 'Pre-release readiness check for the current branch' },\n ],\n i18n: {\n zh: {\n description: '并行检查发布风险,判断变更是否达到可发布标准。',\n whenToUse: '用户接近开发尾声,想在发布前做发布质量/就绪检查时。',\n examplePrompts: [\n { field: 'target', text: '这个仓库是否准备好发布 v1.2?' },\n { field: 'target', text: '对当前分支做发布前就绪检查' },\n ],\n },\n },\n tags: ['release', 'quality', 'validation'],\n estimatedAgents: { min: 6, max: 7 },\n phases: [\n { title: 'Scope' },\n { title: 'Checks' },\n { title: 'Verdict' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir', 'exec_command']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'Current working tree or release candidate from the conversation context.'\n\nconst ALL_CHECKS = [\n { key: 'regression', focus: 'Behavior changes, compatibility breaks, edge cases, and accidental scope creep.' },\n { key: 'tests', focus: 'Relevant automated tests, missing regression cases, flaky or weak assertions, and manual coverage gaps.' },\n { key: 'build', focus: 'Typecheck, lint, build, packaging, lazy imports, generated assets, and dependency correctness.' },\n { key: 'security', focus: 'Secrets, auth/authz, input validation, unsafe shell/file/network access, and data exposure.' },\n { key: 'ops', focus: 'Logging, observability, migrations, persistence, rollback, failure modes, and supportability.' },\n]\n\nlet checks = ALL_CHECKS\nif (args && typeof args === 'object' && Array.isArray(args.checks) && args.checks.length) {\n const selected = new Set(args.checks.map((check) => String(check)))\n checks = ALL_CHECKS.filter((check) => selected.has(check.key))\n if (!checks.length) checks = ALL_CHECKS\n}\n\nphase('Scope')\nconst scope = await agent(\n 'Identify the release candidate scope. Inspect the working tree or target if useful. Return changed areas, user-visible behavior, and likely blast radius.\\\\n\\\\n' +\n 'TARGET:\\\\n' + target,\n {\n label: 'release scope',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n changedAreas: { type: 'array', items: { type: 'string' } },\n userVisibleChanges: { type: 'array', items: { type: 'string' } },\n blastRadius: { type: 'string' },\n },\n required: ['changedAreas', 'blastRadius'],\n },\n },\n)\n\nphase('Checks')\nconst reports = await parallel(\n checks.map((check) => () =>\n agent(\n 'Run a release-readiness check through the ' + check.key + ' lens.\\\\n' +\n 'Focus: ' + check.focus + '\\\\n\\\\n' +\n 'TARGET:\\\\n' + target + '\\\\n\\\\n' +\n 'SCOPE:\\\\n' + JSON.stringify(scope, null, 2) + '\\\\n\\\\n' +\n 'Return blockers, warnings, evidence, and concrete fixes. Prefer specific files/commands over generic statements.',\n {\n label: check.key + ' check',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n blockers: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence', 'fix'],\n },\n },\n warnings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n evidence: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['title', 'evidence'],\n },\n },\n recommendedCommands: { type: 'array', items: { type: 'string' } },\n },\n required: ['blockers', 'warnings'],\n },\n },\n ),\n ),\n)\n\nphase('Verdict')\nconst byCheck = {}\nfor (let i = 0; i < checks.length; i++) {\n byCheck[checks[i].key] = reports[i] ?? { blockers: [], warnings: [], recommendedCommands: [] }\n}\n\nconst verdict = await agent(\n 'Synthesize a release go/no-go verdict. Block if any credible blocker remains. If not blocked, distinguish ship_now from ship_after_checks. ' +\n 'Deduplicate issues and produce the shortest checklist that would make this release safe.\\\\n\\\\n' +\n JSON.stringify({ target, scope, byCheck }, null, 2),\n {\n label: 'release verdict',\n schema: {\n type: 'object',\n properties: {\n recommendation: { type: 'string', enum: ['ship_now', 'ship_after_checks', 'block'] },\n summary: { type: 'string' },\n blockers: { type: 'array', items: { type: 'string' } },\n finalChecklist: { type: 'array', items: { type: 'string' } },\n commandsToRun: { type: 'array', items: { type: 'string' } },\n },\n required: ['recommendation', 'summary', 'blockers', 'finalChecklist'],\n },\n },\n)\n\nconst output = {\n ok: true,\n target,\n checks: checks.map((check) => check.key),\n scope,\n ...(verdict ?? { recommendation: 'ship_after_checks', summary: 'verdict failed', blockers: [], finalChecklist: [] }),\n byCheck,\n}\nreturn {\n summary: output.summary,\n sections: [\n { kind: 'risks', title: 'Blockers', items: output.blockers.map((title) => ({ title, severity: 'high' })) },\n { kind: 'questions', title: 'Final checklist', items: output.finalChecklist },\n { kind: 'questions', title: 'Commands to run', items: output.commandsToRun ?? [] },\n ],\n structuredOutput: output,\n}\n`\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,uBAAuB"}