@xopcai/xopc 0.0.87 → 0.0.89

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 (282) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  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/agents-B6PJB07W.js +222 -0
  6. package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +1 -0
  7. package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +1 -0
  8. package/dist/gateway/static/root/assets/{channels-status-swr-BSHqqCF1.js → channels-status-swr-DaHGkRF1.js} +1 -1
  9. package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +1 -0
  10. package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +1 -0
  11. package/dist/gateway/static/root/assets/{dist-Cmjp2APP.js → dist-6LecgDx5.js} +1 -1
  12. package/dist/gateway/static/root/assets/{extension-debug-page-CFa9z_1N.js → extension-debug-page-CtuKJ9tE.js} +1 -1
  13. package/dist/gateway/static/root/assets/{extension-page-BI8eaTPq.js → extension-page-ykzjOkR5.js} +1 -1
  14. package/dist/gateway/static/root/assets/extension-settings-page-Ce2qrdpO.js +1 -0
  15. package/dist/gateway/static/root/assets/{fetch-DRqwef_Q.js → fetch-C9FFJjuH.js} +1 -1
  16. package/dist/gateway/static/root/assets/{field-primitives-BiNHBo2Y.js → field-primitives-BFcrNeTU.js} +1 -1
  17. package/dist/gateway/static/root/assets/{heartbeat-config-api-ZRb8qhuz.js → heartbeat-config-api-CEg4Vr9R.js} +1 -1
  18. package/dist/gateway/static/root/assets/{index-Cu7bKuUi.js → index-CZfy9oxs.js} +85 -85
  19. package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +1 -0
  20. package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +1 -0
  21. package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +1 -0
  22. package/dist/gateway/static/root/assets/{settings-form-section-DiqqVs6m.js → settings-form-section-BqdzA28u.js} +1 -1
  23. package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +3 -0
  24. package/dist/gateway/static/root/assets/{share-preview-page-n1Gprylk.js → share-preview-page-Di5Bzh4g.js} +1 -1
  25. package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +2 -0
  26. package/dist/gateway/static/root/assets/{theme-store-CZOh1nT3.js → theme-store-CNqbmTNV.js} +1 -1
  27. package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +7 -0
  28. package/dist/gateway/static/root/assets/{utils-CkWBfxs4.js → utils-BWm2tG2w.js} +1 -1
  29. package/dist/gateway/static/root/assets/voice-api-key-field-X2UfnHeq.js +1 -0
  30. package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +27 -0
  31. package/dist/gateway/static/root/index.html +5 -5
  32. package/dist/package.js +1 -1
  33. package/dist/src/agent/agent-manager.d.ts +2 -0
  34. package/dist/src/agent/agent-manager.js +1 -0
  35. package/dist/src/agent/agent-manager.js.map +1 -1
  36. package/dist/src/agent/child-agent-factory.d.ts +15 -0
  37. package/dist/src/agent/child-agent-factory.js +35 -2
  38. package/dist/src/agent/child-agent-factory.js.map +1 -1
  39. package/dist/src/agent/client-error-format.d.ts +20 -0
  40. package/dist/src/agent/client-error-format.js +97 -0
  41. package/dist/src/agent/client-error-format.js.map +1 -0
  42. package/dist/src/agent/embedded/run-turn.js +23 -4
  43. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  44. package/dist/src/agent/goals/goal-locale.d.ts +1 -1
  45. package/dist/src/agent/inbound/turn-dispatcher.js +1 -1
  46. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  47. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
  48. package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
  49. package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
  50. package/dist/src/agent/service/process-direct-streaming.js +19 -3
  51. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  52. package/dist/src/agent/service/webchat-tts.d.ts +1 -2
  53. package/dist/src/agent/service/webchat-tts.js +1 -1
  54. package/dist/src/agent/service/webchat-tts.js.map +1 -1
  55. package/dist/src/agent/service.js +2 -1
  56. package/dist/src/agent/service.js.map +1 -1
  57. package/dist/src/agent/service.types.d.ts +3 -1
  58. package/dist/src/agent/tools/cronjob-tool.js +2 -1
  59. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  60. package/dist/src/agent/tools/factory.d.ts +3 -0
  61. package/dist/src/agent/tools/factory.js +2 -23
  62. package/dist/src/agent/tools/factory.js.map +1 -1
  63. package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
  64. package/dist/src/agent/tools/workflow-tool.js +61 -213
  65. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  66. package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
  67. package/dist/src/agent/workflow/agent-progress.js +65 -0
  68. package/dist/src/agent/workflow/agent-progress.js.map +1 -0
  69. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
  70. package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
  71. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
  72. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  73. package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
  74. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  75. package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
  76. package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
  77. package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
  78. package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
  79. package/dist/src/agent/workflow/builtins/index.js +11 -1
  80. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  81. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
  82. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
  83. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
  84. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  85. package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
  86. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  87. package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
  88. package/dist/src/agent/workflow/builtins/release-check.js +165 -0
  89. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
  90. package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
  91. package/dist/src/agent/workflow/builtins/research.js +14 -0
  92. package/dist/src/agent/workflow/builtins/research.js.map +1 -1
  93. package/dist/src/agent/workflow/index.d.ts +2 -1
  94. package/dist/src/agent/workflow/index.js +3 -2
  95. package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
  96. package/dist/src/agent/workflow/meta-locale.js +62 -0
  97. package/dist/src/agent/workflow/meta-locale.js.map +1 -0
  98. package/dist/src/agent/workflow/parser.js +3 -0
  99. package/dist/src/agent/workflow/parser.js.map +1 -1
  100. package/dist/src/agent/workflow/runtime.d.ts +2 -2
  101. package/dist/src/agent/workflow/runtime.js +21 -14
  102. package/dist/src/agent/workflow/runtime.js.map +1 -1
  103. package/dist/src/agent/workflow/snapshot.js +2 -12
  104. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  105. package/dist/src/agent/workflow/step-labels.d.ts +8 -0
  106. package/dist/src/agent/workflow/step-labels.js +48 -0
  107. package/dist/src/agent/workflow/step-labels.js.map +1 -0
  108. package/dist/src/agent/workflow/subagent-runner.js +46 -1
  109. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  110. package/dist/src/agent/workflow/types.d.ts +74 -1
  111. package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
  112. package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
  113. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
  114. package/dist/src/auth/credentials.d.ts +19 -2
  115. package/dist/src/auth/credentials.js +47 -13
  116. package/dist/src/auth/credentials.js.map +1 -1
  117. package/dist/src/auth/oauth/types.d.ts +16 -0
  118. package/dist/src/cli/commands/auth.js +6 -0
  119. package/dist/src/cli/commands/auth.js.map +1 -1
  120. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  121. package/dist/src/cli/commands/onboard/model.js +6 -0
  122. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  123. package/dist/src/config/agent-typed-models.d.ts +18 -0
  124. package/dist/src/config/agent-typed-models.js +53 -0
  125. package/dist/src/config/agent-typed-models.js.map +1 -0
  126. package/dist/src/config/index.js +2 -2
  127. package/dist/src/config/schema.d.ts +52 -0
  128. package/dist/src/config/schema.js +39 -3
  129. package/dist/src/config/schema.js.map +1 -1
  130. package/dist/src/config/voice.d.ts +3 -28
  131. package/dist/src/config/voice.js +27 -261
  132. package/dist/src/config/voice.js.map +1 -1
  133. package/dist/src/cron/executor.d.ts +2 -0
  134. package/dist/src/cron/executor.js +59 -5
  135. package/dist/src/cron/executor.js.map +1 -1
  136. package/dist/src/cron/job-content.js +2 -1
  137. package/dist/src/cron/job-content.js.map +1 -1
  138. package/dist/src/cron/types.d.ts +21 -1
  139. package/dist/src/cron/validation.d.ts +76 -0
  140. package/dist/src/cron/validation.js +26 -1
  141. package/dist/src/cron/validation.js.map +1 -1
  142. package/dist/src/gateway/agents-admin.d.ts +9 -0
  143. package/dist/src/gateway/agents-admin.js +16 -0
  144. package/dist/src/gateway/agents-admin.js.map +1 -1
  145. package/dist/src/gateway/config-tools-web.js +3 -2
  146. package/dist/src/gateway/config-tools-web.js.map +1 -1
  147. package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
  148. package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
  149. package/dist/src/gateway/hono/lib/agent-model.d.ts +7 -0
  150. package/dist/src/gateway/hono/lib/agent-model.js +36 -1
  151. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  152. package/dist/src/gateway/hono/lib/config-payload.js +28 -5
  153. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  154. package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
  155. package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
  156. package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
  157. package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
  158. package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
  159. package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
  160. package/dist/src/gateway/hono/lib/safe-voice-config.js +2 -1
  161. package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
  162. package/dist/src/gateway/hono/oauth-async.js +40 -15
  163. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  164. package/dist/src/gateway/hono/oauth.js +31 -6
  165. package/dist/src/gateway/hono/oauth.js.map +1 -1
  166. package/dist/src/gateway/hono/routes/agents.js +1 -1
  167. package/dist/src/gateway/hono/routes/config-patch/agents.js +8 -2
  168. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  169. package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
  170. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  171. package/dist/src/gateway/hono/routes/config-patch/misc.js +7 -2
  172. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  173. package/dist/src/gateway/hono/routes/config.js +59 -0
  174. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  175. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  176. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  177. package/dist/src/gateway/hono/routes/models.js +84 -15
  178. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  179. package/dist/src/gateway/hono/routes/voice.js +75 -0
  180. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  181. package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
  182. package/dist/src/gateway/hono/routes/workflows.js +226 -0
  183. package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
  184. package/dist/src/gateway/service/run-gateway-agent.js +2 -20
  185. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  186. package/dist/src/gateway/service.d.ts +8 -0
  187. package/dist/src/gateway/service.js +28 -2
  188. package/dist/src/gateway/service.js.map +1 -1
  189. package/dist/src/mcp/channel-bridge.js +1 -1
  190. package/dist/src/providers/index.d.ts +8 -0
  191. package/dist/src/providers/index.js +51 -12
  192. package/dist/src/providers/index.js.map +1 -1
  193. package/dist/src/share/site-share-config.d.ts +3 -2
  194. package/dist/src/share/site-share-config.js.map +1 -1
  195. package/dist/src/tui/tui-agent-events.js +2 -1
  196. package/dist/src/tui/tui-agent-events.js.map +1 -1
  197. package/dist/src/voice/metadata/builtin.d.ts +2 -0
  198. package/dist/src/voice/metadata/builtin.js +420 -0
  199. package/dist/src/voice/metadata/builtin.js.map +1 -0
  200. package/dist/src/voice/metadata/index.d.ts +4 -0
  201. package/dist/src/voice/metadata/index.js +3 -0
  202. package/dist/src/voice/metadata/registry.d.ts +5 -0
  203. package/dist/src/voice/metadata/registry.js +34 -0
  204. package/dist/src/voice/metadata/registry.js.map +1 -0
  205. package/dist/src/voice/metadata/types.d.ts +41 -0
  206. package/dist/src/voice/metadata/types.js +1 -0
  207. package/dist/src/voice/stt/list-providers.d.ts +3 -3
  208. package/dist/src/voice/stt/list-providers.js +41 -6
  209. package/dist/src/voice/stt/list-providers.js.map +1 -1
  210. package/dist/src/voice/tts/list-providers.d.ts +3 -3
  211. package/dist/src/voice/tts/list-providers.js +41 -6
  212. package/dist/src/voice/tts/list-providers.js.map +1 -1
  213. package/dist/src/workflows/domain/command.d.ts +19 -0
  214. package/dist/src/workflows/domain/command.js +1 -0
  215. package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
  216. package/dist/src/workflows/domain/definition-utils.js +50 -0
  217. package/dist/src/workflows/domain/definition-utils.js.map +1 -0
  218. package/dist/src/workflows/domain/definition.d.ts +62 -0
  219. package/dist/src/workflows/domain/definition.js +1 -0
  220. package/dist/src/workflows/domain/event.d.ts +67 -0
  221. package/dist/src/workflows/domain/event.js +1 -0
  222. package/dist/src/workflows/domain/index.d.ts +7 -0
  223. package/dist/src/workflows/domain/index.js +4 -0
  224. package/dist/src/workflows/domain/result.d.ts +65 -0
  225. package/dist/src/workflows/domain/result.js +1 -0
  226. package/dist/src/workflows/domain/run.d.ts +177 -0
  227. package/dist/src/workflows/domain/run.js +14 -0
  228. package/dist/src/workflows/domain/run.js.map +1 -0
  229. package/dist/src/workflows/domain/validation.d.ts +19 -0
  230. package/dist/src/workflows/domain/validation.js +66 -0
  231. package/dist/src/workflows/domain/validation.js.map +1 -0
  232. package/dist/src/workflows/engine/index.d.ts +2 -0
  233. package/dist/src/workflows/engine/index.js +3 -0
  234. package/dist/src/workflows/engine/projector.d.ts +3 -0
  235. package/dist/src/workflows/engine/projector.js +205 -0
  236. package/dist/src/workflows/engine/projector.js.map +1 -0
  237. package/dist/src/workflows/engine/workflow-engine.d.ts +32 -0
  238. package/dist/src/workflows/engine/workflow-engine.js +189 -0
  239. package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
  240. package/dist/src/workflows/index.d.ts +10 -0
  241. package/dist/src/workflows/index.js +18 -0
  242. package/dist/src/workflows/runtime/index.d.ts +1 -0
  243. package/dist/src/workflows/runtime/index.js +4 -0
  244. package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
  245. package/dist/src/workflows/runtime/script-runtime.js +3 -0
  246. package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
  247. package/dist/src/workflows/service/run-view-to-snapshot.js +61 -0
  248. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
  249. package/dist/src/workflows/service/workflow-run-service.d.ts +36 -0
  250. package/dist/src/workflows/service/workflow-run-service.js +279 -0
  251. package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
  252. package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
  253. package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
  254. package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
  255. package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
  256. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
  257. package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
  258. package/dist/src/workflows/service/workflow-session-key.js +21 -0
  259. package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
  260. package/dist/src/workflows/store/event-store.d.ts +17 -0
  261. package/dist/src/workflows/store/event-store.js +83 -0
  262. package/dist/src/workflows/store/event-store.js.map +1 -0
  263. package/dist/src/workflows/store/paths.d.ts +7 -0
  264. package/dist/src/workflows/store/paths.js +26 -0
  265. package/dist/src/workflows/store/paths.js.map +1 -0
  266. package/dist/src/workflows/store/run-store.d.ts +13 -0
  267. package/dist/src/workflows/store/run-store.js +69 -0
  268. package/dist/src/workflows/store/run-store.js.map +1 -0
  269. package/package.json +5 -5
  270. package/dist/gateway/static/root/assets/agents-BEAbXpuP.js +0 -222
  271. package/dist/gateway/static/root/assets/apps-page-Dg8R-Szf.js +0 -1
  272. package/dist/gateway/static/root/assets/channels-settings-yohw9YSu.js +0 -1
  273. package/dist/gateway/static/root/assets/cron-api-0h_QT8U3.js +0 -1
  274. package/dist/gateway/static/root/assets/cron-page-BkfKFfFk.js +0 -1
  275. package/dist/gateway/static/root/assets/extension-settings-page-x4BB7q1X.js +0 -1
  276. package/dist/gateway/static/root/assets/index-a5gWIdZQ.css +0 -1
  277. package/dist/gateway/static/root/assets/logs-page-BFZ8GgCv.js +0 -1
  278. package/dist/gateway/static/root/assets/sessions-page-CD7AfB-2.js +0 -1
  279. package/dist/gateway/static/root/assets/settings-page-BBOjEQW3.js +0 -3
  280. package/dist/gateway/static/root/assets/skills-page-CcN_gj--.js +0 -2
  281. package/dist/gateway/static/root/assets/url-Dd8Q7kZZ.js +0 -3
  282. package/dist/gateway/static/root/assets/voice-api-key-field-O6awz9hi.js +0 -1
@@ -0,0 +1,65 @@
1
+ import { workflowStepLabel } from "./step-labels.js";
2
+ //#region src/agent/workflow/agent-progress.ts
3
+ const MAX_STEPS = 50;
4
+ const MAX_STREAM_TEXT = 32e3;
5
+ function applySubagentProgress(agent, event) {
6
+ switch (event.type) {
7
+ case "tool_start": {
8
+ if (!agent.steps) agent.steps = [];
9
+ const { label, detail } = workflowStepLabel(event.toolName, event.args);
10
+ const step = {
11
+ id: event.toolCallId,
12
+ kind: "tool",
13
+ toolName: event.toolName,
14
+ label,
15
+ detail,
16
+ status: "running",
17
+ startedAtMs: Date.now()
18
+ };
19
+ agent.steps.push(step);
20
+ trimSteps(agent);
21
+ agent.currentStep = formatCurrentStep(step);
22
+ return true;
23
+ }
24
+ case "tool_end": {
25
+ const step = findStep(agent, event.toolCallId);
26
+ if (!step) return false;
27
+ step.status = event.isError ? "error" : "done";
28
+ if (step.startedAtMs != null) step.durationMs = Date.now() - step.startedAtMs;
29
+ if (agent.currentStep === formatCurrentStep(step)) agent.currentStep = void 0;
30
+ return true;
31
+ }
32
+ case "iteration":
33
+ agent.iteration = event.count;
34
+ agent.maxIterations = event.max;
35
+ return true;
36
+ case "text_delta":
37
+ if (!event.delta) return false;
38
+ agent.streamText = appendStreamText(agent.streamText, event.delta);
39
+ return true;
40
+ case "thinking_delta":
41
+ if (!event.delta) return false;
42
+ agent.streamText = appendStreamText(agent.streamText, event.delta);
43
+ return true;
44
+ default: return false;
45
+ }
46
+ }
47
+ function findStep(agent, id) {
48
+ return agent.steps?.find((s) => s.id === id);
49
+ }
50
+ function formatCurrentStep(step) {
51
+ return step.detail ? `${step.label}: ${step.detail}` : step.label;
52
+ }
53
+ function trimSteps(agent) {
54
+ if (!agent.steps || agent.steps.length <= MAX_STEPS) return;
55
+ agent.steps = agent.steps.slice(-MAX_STEPS);
56
+ }
57
+ function appendStreamText(existing, delta) {
58
+ const next = (existing ?? "") + delta;
59
+ if (next.length <= MAX_STREAM_TEXT) return next;
60
+ return next.slice(-MAX_STREAM_TEXT);
61
+ }
62
+ //#endregion
63
+ export { applySubagentProgress };
64
+
65
+ //# sourceMappingURL=agent-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-progress.js","names":[],"sources":["../../../../src/agent/workflow/agent-progress.ts"],"sourcesContent":["/**\n * Apply live subagent progress events onto a {@link WorkflowAgentSnapshot}.\n */\n\nimport type {\n SubagentProgressEvent,\n WorkflowAgentSnapshot,\n WorkflowAgentStep,\n} from './types.js';\nimport { workflowStepLabel } from './step-labels.js';\n\nconst MAX_STEPS = 50;\nconst MAX_STREAM_TEXT = 32_000;\n\nexport function applySubagentProgress(\n agent: WorkflowAgentSnapshot,\n event: SubagentProgressEvent,\n): boolean {\n switch (event.type) {\n case 'tool_start': {\n if (!agent.steps) agent.steps = [];\n const { label, detail } = workflowStepLabel(event.toolName, event.args);\n const step: WorkflowAgentStep = {\n id: event.toolCallId,\n kind: 'tool',\n toolName: event.toolName,\n label,\n detail,\n status: 'running',\n startedAtMs: Date.now(),\n };\n agent.steps.push(step);\n trimSteps(agent);\n agent.currentStep = formatCurrentStep(step);\n return true;\n }\n case 'tool_end': {\n const step = findStep(agent, event.toolCallId);\n if (!step) return false;\n step.status = event.isError ? 'error' : 'done';\n if (step.startedAtMs != null) step.durationMs = Date.now() - step.startedAtMs;\n if (agent.currentStep === formatCurrentStep(step)) {\n agent.currentStep = undefined;\n }\n return true;\n }\n case 'iteration': {\n agent.iteration = event.count;\n agent.maxIterations = event.max;\n return true;\n }\n case 'text_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n case 'thinking_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n default:\n return false;\n }\n}\n\nfunction findStep(agent: WorkflowAgentSnapshot, id: string): WorkflowAgentStep | undefined {\n return agent.steps?.find((s) => s.id === id);\n}\n\nfunction formatCurrentStep(step: WorkflowAgentStep): string {\n return step.detail ? `${step.label}: ${step.detail}` : step.label;\n}\n\nfunction trimSteps(agent: WorkflowAgentSnapshot): void {\n if (!agent.steps || agent.steps.length <= MAX_STEPS) return;\n agent.steps = agent.steps.slice(-MAX_STEPS);\n}\n\nfunction appendStreamText(existing: string | undefined, delta: string): string {\n const next = (existing ?? '') + delta;\n if (next.length <= MAX_STREAM_TEXT) return next;\n return next.slice(-MAX_STREAM_TEXT);\n}\n"],"mappings":";;AAWA,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAExB,SAAgB,sBACd,OACA,OACS;AACT,SAAQ,MAAM,MAAd;EACE,KAAK,cAAc;AACjB,OAAI,CAAC,MAAM,MAAO,OAAM,QAAQ,EAAE;GAClC,MAAM,EAAE,OAAO,WAAW,kBAAkB,MAAM,UAAU,MAAM,KAAK;GACvE,MAAM,OAA0B;IAC9B,IAAI,MAAM;IACV,MAAM;IACN,UAAU,MAAM;IAChB;IACA;IACA,QAAQ;IACR,aAAa,KAAK,KAAK;IACxB;AACD,SAAM,MAAM,KAAK,KAAK;AACtB,aAAU,MAAM;AAChB,SAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAO;;EAET,KAAK,YAAY;GACf,MAAM,OAAO,SAAS,OAAO,MAAM,WAAW;AAC9C,OAAI,CAAC,KAAM,QAAO;AAClB,QAAK,SAAS,MAAM,UAAU,UAAU;AACxC,OAAI,KAAK,eAAe,KAAM,MAAK,aAAa,KAAK,KAAK,GAAG,KAAK;AAClE,OAAI,MAAM,gBAAgB,kBAAkB,KAAK,CAC/C,OAAM,cAAc,KAAA;AAEtB,UAAO;;EAET,KAAK;AACH,SAAM,YAAY,MAAM;AACxB,SAAM,gBAAgB,MAAM;AAC5B,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,QACE,QAAO;;;AAIb,SAAS,SAAS,OAA8B,IAA2C;AACzF,QAAO,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;;AAG9C,SAAS,kBAAkB,MAAiC;AAC1D,QAAO,KAAK,SAAS,GAAG,KAAK,MAAM,IAAI,KAAK,WAAW,KAAK;;AAG9D,SAAS,UAAU,OAAoC;AACrD,KAAI,CAAC,MAAM,SAAS,MAAM,MAAM,UAAU,UAAW;AACrD,OAAM,QAAQ,MAAM,MAAM,MAAM,CAAC,UAAU;;AAG7C,SAAS,iBAAiB,UAA8B,OAAuB;CAC7E,MAAM,QAAQ,YAAY,MAAM;AAChC,KAAI,KAAK,UAAU,gBAAiB,QAAO;AAC3C,QAAO,KAAK,MAAM,CAAC,gBAAgB"}
@@ -10,4 +10,4 @@
10
10
  * - scope: subdirectory to focus on (default '.')
11
11
  * - dimensions: subset of dimension keys, e.g. ['security', 'bugs']
12
12
  */
13
- export declare const AUDIT_REPO_SCRIPT = "export const meta = {\n name: 'audit_repo',\n description: 'Fan-out repository audit across multiple dimensions, then synthesize a structured report.',\n whenToUse: 'User asks for a thorough / multi-dimension code review of the whole repo or a major subsystem.',\n tags: ['code-review', 'audit'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Inventory' },\n { title: 'Review' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nconst ALL_DIMENSIONS = [\n { key: 'bugs', focus: 'Correctness bugs, null-safety, error handling, race conditions, off-by-one, dead code.' },\n { key: 'perf', focus: 'Performance issues, hot paths, N+1 patterns, accidental quadratic loops, sync I/O, missing caching.' },\n { key: 'security', focus: 'Auth/authz, input validation, secret handling, injection sinks, unsafe deserialization, SSRF.' },\n { key: 'tests', focus: 'Test coverage gaps, brittle tests, integration vs unit gaps, missing regression cases.' },\n { key: 'style', focus: 'Inconsistent conventions, naming, unused exports, duplication, layering violations.' },\n]\n\nlet dimensions = ALL_DIMENSIONS\nif (args && typeof args === 'object' && Array.isArray(args.dimensions) && args.dimensions.length) {\n const keys = new Set(args.dimensions.map((d) => String(d)))\n dimensions = ALL_DIMENSIONS.filter((d) => keys.has(d.key))\n if (!dimensions.length) dimensions = ALL_DIMENSIONS\n}\n\nphase('Inventory')\nconst inventory = await agent(\n 'Produce a compact map of this repository scope: ' + scope + '. ' +\n 'Cover layout, main modules, the 5\u201310 most important files, and obvious entry points. Be terse and structured.',\n { label: 'repo inventory', toolset: READ_ONLY_TOOLS },\n)\n\nphase('Review')\nconst findings = await parallel(\n dimensions.map((d) => () =>\n agent(\n 'Review scope \"' + scope + '\" through the ' + d.key + ' lens.\\n' +\n 'Focus: ' + d.focus + '\\n\\n' +\n 'Inventory for orientation:\\n' + inventory + '\\n\\n' +\n 'Return findings: file paths, line numbers when known, severity (low/med/high), a one-sentence why, a one-sentence fix.',\n {\n label: d.key + ' review',\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 line: { type: ['number', 'string'] },\n severity: { type: 'string', enum: ['low', 'med', 'high'] },\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('Synthesize')\nconst live = findings.filter(Boolean)\nif (!live.length) {\n return { ok: true, scope, summary: 'No findings.', byDimension: {}, priorityActions: [] }\n}\nconst byDimension = {}\nfor (let i = 0; i < dimensions.length; i++) {\n byDimension[dimensions[i].key] = live[i]?.findings ?? []\n}\n\nconst summary = await agent(\n 'Synthesize a compact report from these per-dimension findings. Deduplicate near-identical items. ' +\n 'Order by severity (high \u2192 low). Cap topFindings at 20. ' +\n 'Also return priorityActions: the top 5 fixes ranked by impact, each with effort (S|M|L).\\n\\n' +\n JSON.stringify(byDimension, null, 2),\n {\n label: 'report synthesis',\n schema: {\n type: 'object',\n properties: {\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n dimension: { type: 'string' },\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['dimension', 'file', 'severity', 'title'],\n },\n },\n priorityActions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n effort: { type: 'string', enum: ['S', 'M', 'L'] },\n },\n required: ['file', 'severity', 'title', 'effort'],\n },\n },\n summary: { type: 'string' },\n },\n required: ['topFindings', 'priorityActions', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n scope,\n dimensions: dimensions.map((d) => d.key),\n ...(summary ?? { topFindings: [], priorityActions: [], summary: 'synthesis failed' }),\n byDimension,\n}\n";
13
+ export declare const AUDIT_REPO_SCRIPT = "export const meta = {\n name: 'audit_repo',\n description: 'Fan-out repository audit across multiple dimensions, then synthesize a structured report.',\n whenToUse: 'User asks for a thorough / multi-dimension code review of the whole repo or a major subsystem.',\n examplePrompts: [\n { field: 'goal', text: 'Run a thorough audit of this repository' },\n { field: 'goal', text: 'Review code quality across the whole codebase' },\n ],\n i18n: {\n zh: {\n description: '\u591A\u7EF4\u5EA6\u5E76\u884C\u5BA1\u67E5\u6574\u4E2A\u4ED3\u5E93\uFF0C\u5E76\u6C47\u603B\u4E3A\u7ED3\u6784\u5316\u62A5\u544A\u3002',\n whenToUse: '\u7528\u6237\u9700\u8981\u5BF9\u6574\u5E93\u6216\u4E3B\u8981\u5B50\u7CFB\u7EDF\u505A\u5168\u9762\u3001\u591A\u7EF4\u5EA6\u7684\u4EE3\u7801\u5BA1\u67E5\u65F6\u3002',\n examplePrompts: [\n { field: 'goal', text: '\u5BF9\u6574\u4E2A\u4ED3\u5E93\u505A\u4E00\u6B21\u5168\u9762\u5BA1\u67E5' },\n { field: 'goal', text: '\u4ECE\u4EE3\u7801\u8D28\u91CF\u7EF4\u5EA6\u5BA1\u67E5\u6574\u4E2A\u4EE3\u7801\u5E93' },\n ],\n },\n },\n tags: ['code-review', 'audit'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Inventory' },\n { title: 'Review' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nconst ALL_DIMENSIONS = [\n { key: 'bugs', focus: 'Correctness bugs, null-safety, error handling, race conditions, off-by-one, dead code.' },\n { key: 'perf', focus: 'Performance issues, hot paths, N+1 patterns, accidental quadratic loops, sync I/O, missing caching.' },\n { key: 'security', focus: 'Auth/authz, input validation, secret handling, injection sinks, unsafe deserialization, SSRF.' },\n { key: 'tests', focus: 'Test coverage gaps, brittle tests, integration vs unit gaps, missing regression cases.' },\n { key: 'style', focus: 'Inconsistent conventions, naming, unused exports, duplication, layering violations.' },\n]\n\nlet dimensions = ALL_DIMENSIONS\nif (args && typeof args === 'object' && Array.isArray(args.dimensions) && args.dimensions.length) {\n const keys = new Set(args.dimensions.map((d) => String(d)))\n dimensions = ALL_DIMENSIONS.filter((d) => keys.has(d.key))\n if (!dimensions.length) dimensions = ALL_DIMENSIONS\n}\n\nphase('Inventory')\nconst inventory = await agent(\n 'Produce a compact map of this repository scope: ' + scope + '. ' +\n 'Cover layout, main modules, the 5\u201310 most important files, and obvious entry points. Be terse and structured.',\n { label: 'repo inventory', toolset: READ_ONLY_TOOLS },\n)\n\nphase('Review')\nconst findings = await parallel(\n dimensions.map((d) => () =>\n agent(\n 'Review scope \"' + scope + '\" through the ' + d.key + ' lens.\\n' +\n 'Focus: ' + d.focus + '\\n\\n' +\n 'Inventory for orientation:\\n' + inventory + '\\n\\n' +\n 'Return findings: file paths, line numbers when known, severity (low/med/high), a one-sentence why, a one-sentence fix.',\n {\n label: d.key + ' review',\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 line: { type: ['number', 'string'] },\n severity: { type: 'string', enum: ['low', 'med', 'high'] },\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('Synthesize')\nconst live = findings.filter(Boolean)\nif (!live.length) {\n return { ok: true, scope, summary: 'No findings.', byDimension: {}, priorityActions: [] }\n}\nconst byDimension = {}\nfor (let i = 0; i < dimensions.length; i++) {\n byDimension[dimensions[i].key] = live[i]?.findings ?? []\n}\n\nconst summary = await agent(\n 'Synthesize a compact report from these per-dimension findings. Deduplicate near-identical items. ' +\n 'Order by severity (high \u2192 low). Cap topFindings at 20. ' +\n 'Also return priorityActions: the top 5 fixes ranked by impact, each with effort (S|M|L).\\n\\n' +\n JSON.stringify(byDimension, null, 2),\n {\n label: 'report synthesis',\n schema: {\n type: 'object',\n properties: {\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n dimension: { type: 'string' },\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['dimension', 'file', 'severity', 'title'],\n },\n },\n priorityActions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n effort: { type: 'string', enum: ['S', 'M', 'L'] },\n },\n required: ['file', 'severity', 'title', 'effort'],\n },\n },\n summary: { type: 'string' },\n },\n required: ['topFindings', 'priorityActions', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n scope,\n dimensions: dimensions.map((d) => d.key),\n ...(summary ?? { topFindings: [], priorityActions: [], summary: 'synthesis failed' }),\n byDimension,\n}\n";
@@ -15,6 +15,20 @@ const AUDIT_REPO_SCRIPT = `export const meta = {
15
15
  name: 'audit_repo',
16
16
  description: 'Fan-out repository audit across multiple dimensions, then synthesize a structured report.',
17
17
  whenToUse: 'User asks for a thorough / multi-dimension code review of the whole repo or a major subsystem.',
18
+ examplePrompts: [
19
+ { field: 'goal', text: 'Run a thorough audit of this repository' },
20
+ { field: 'goal', text: 'Review code quality across the whole codebase' },
21
+ ],
22
+ i18n: {
23
+ zh: {
24
+ description: '多维度并行审查整个仓库,并汇总为结构化报告。',
25
+ whenToUse: '用户需要对整库或主要子系统做全面、多维度的代码审查时。',
26
+ examplePrompts: [
27
+ { field: 'goal', text: '对整个仓库做一次全面审查' },
28
+ { field: 'goal', text: '从代码质量维度审查整个代码库' },
29
+ ],
30
+ },
31
+ },
18
32
  tags: ['code-review', 'audit'],
19
33
  estimatedAgents: { min: 7, max: 7 },
20
34
  phases: [
@@ -1 +1 @@
1
- {"version":3,"file":"audit-repo.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/audit-repo.ts"],"sourcesContent":["/**\n * Built-in workflow: `audit_repo`\n *\n * Fan-out repo audit. Phase 1 inventories the repo; phase 2 spawns N reviewers\n * in parallel, one per dimension (bugs / perf / security / tests / style);\n * phase 3 synthesises into a structured report. The script is kept readable so\n * users can copy it into `~/.xopc/workflows/` as a starting point.\n *\n * Args:\n * - scope: subdirectory to focus on (default '.')\n * - dimensions: subset of dimension keys, e.g. ['security', 'bugs']\n */\n\nexport const AUDIT_REPO_SCRIPT = `export const meta = {\n name: 'audit_repo',\n description: 'Fan-out repository audit across multiple dimensions, then synthesize a structured report.',\n whenToUse: 'User asks for a thorough / multi-dimension code review of the whole repo or a major subsystem.',\n tags: ['code-review', 'audit'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Inventory' },\n { title: 'Review' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nconst ALL_DIMENSIONS = [\n { key: 'bugs', focus: 'Correctness bugs, null-safety, error handling, race conditions, off-by-one, dead code.' },\n { key: 'perf', focus: 'Performance issues, hot paths, N+1 patterns, accidental quadratic loops, sync I/O, missing caching.' },\n { key: 'security', focus: 'Auth/authz, input validation, secret handling, injection sinks, unsafe deserialization, SSRF.' },\n { key: 'tests', focus: 'Test coverage gaps, brittle tests, integration vs unit gaps, missing regression cases.' },\n { key: 'style', focus: 'Inconsistent conventions, naming, unused exports, duplication, layering violations.' },\n]\n\nlet dimensions = ALL_DIMENSIONS\nif (args && typeof args === 'object' && Array.isArray(args.dimensions) && args.dimensions.length) {\n const keys = new Set(args.dimensions.map((d) => String(d)))\n dimensions = ALL_DIMENSIONS.filter((d) => keys.has(d.key))\n if (!dimensions.length) dimensions = ALL_DIMENSIONS\n}\n\nphase('Inventory')\nconst inventory = await agent(\n 'Produce a compact map of this repository scope: ' + scope + '. ' +\n 'Cover layout, main modules, the 5–10 most important files, and obvious entry points. Be terse and structured.',\n { label: 'repo inventory', toolset: READ_ONLY_TOOLS },\n)\n\nphase('Review')\nconst findings = await parallel(\n dimensions.map((d) => () =>\n agent(\n 'Review scope \"' + scope + '\" through the ' + d.key + ' lens.\\\\n' +\n 'Focus: ' + d.focus + '\\\\n\\\\n' +\n 'Inventory for orientation:\\\\n' + inventory + '\\\\n\\\\n' +\n 'Return findings: file paths, line numbers when known, severity (low/med/high), a one-sentence why, a one-sentence fix.',\n {\n label: d.key + ' review',\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 line: { type: ['number', 'string'] },\n severity: { type: 'string', enum: ['low', 'med', 'high'] },\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('Synthesize')\nconst live = findings.filter(Boolean)\nif (!live.length) {\n return { ok: true, scope, summary: 'No findings.', byDimension: {}, priorityActions: [] }\n}\nconst byDimension = {}\nfor (let i = 0; i < dimensions.length; i++) {\n byDimension[dimensions[i].key] = live[i]?.findings ?? []\n}\n\nconst summary = await agent(\n 'Synthesize a compact report from these per-dimension findings. Deduplicate near-identical items. ' +\n 'Order by severity (high → low). Cap topFindings at 20. ' +\n 'Also return priorityActions: the top 5 fixes ranked by impact, each with effort (S|M|L).\\\\n\\\\n' +\n JSON.stringify(byDimension, null, 2),\n {\n label: 'report synthesis',\n schema: {\n type: 'object',\n properties: {\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n dimension: { type: 'string' },\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['dimension', 'file', 'severity', 'title'],\n },\n },\n priorityActions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n effort: { type: 'string', enum: ['S', 'M', 'L'] },\n },\n required: ['file', 'severity', 'title', 'effort'],\n },\n },\n summary: { type: 'string' },\n },\n required: ['topFindings', 'priorityActions', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n scope,\n dimensions: dimensions.map((d) => d.key),\n ...(summary ?? { topFindings: [], priorityActions: [], summary: 'synthesis failed' }),\n byDimension,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,oBAAoB"}
1
+ {"version":3,"file":"audit-repo.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/audit-repo.ts"],"sourcesContent":["/**\n * Built-in workflow: `audit_repo`\n *\n * Fan-out repo audit. Phase 1 inventories the repo; phase 2 spawns N reviewers\n * in parallel, one per dimension (bugs / perf / security / tests / style);\n * phase 3 synthesises into a structured report. The script is kept readable so\n * users can copy it into `~/.xopc/workflows/` as a starting point.\n *\n * Args:\n * - scope: subdirectory to focus on (default '.')\n * - dimensions: subset of dimension keys, e.g. ['security', 'bugs']\n */\n\nexport const AUDIT_REPO_SCRIPT = `export const meta = {\n name: 'audit_repo',\n description: 'Fan-out repository audit across multiple dimensions, then synthesize a structured report.',\n whenToUse: 'User asks for a thorough / multi-dimension code review of the whole repo or a major subsystem.',\n examplePrompts: [\n { field: 'goal', text: 'Run a thorough audit of this repository' },\n { field: 'goal', text: 'Review code quality across the whole codebase' },\n ],\n i18n: {\n zh: {\n description: '多维度并行审查整个仓库,并汇总为结构化报告。',\n whenToUse: '用户需要对整库或主要子系统做全面、多维度的代码审查时。',\n examplePrompts: [\n { field: 'goal', text: '对整个仓库做一次全面审查' },\n { field: 'goal', text: '从代码质量维度审查整个代码库' },\n ],\n },\n },\n tags: ['code-review', 'audit'],\n estimatedAgents: { min: 7, max: 7 },\n phases: [\n { title: 'Inventory' },\n { title: 'Review' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nconst ALL_DIMENSIONS = [\n { key: 'bugs', focus: 'Correctness bugs, null-safety, error handling, race conditions, off-by-one, dead code.' },\n { key: 'perf', focus: 'Performance issues, hot paths, N+1 patterns, accidental quadratic loops, sync I/O, missing caching.' },\n { key: 'security', focus: 'Auth/authz, input validation, secret handling, injection sinks, unsafe deserialization, SSRF.' },\n { key: 'tests', focus: 'Test coverage gaps, brittle tests, integration vs unit gaps, missing regression cases.' },\n { key: 'style', focus: 'Inconsistent conventions, naming, unused exports, duplication, layering violations.' },\n]\n\nlet dimensions = ALL_DIMENSIONS\nif (args && typeof args === 'object' && Array.isArray(args.dimensions) && args.dimensions.length) {\n const keys = new Set(args.dimensions.map((d) => String(d)))\n dimensions = ALL_DIMENSIONS.filter((d) => keys.has(d.key))\n if (!dimensions.length) dimensions = ALL_DIMENSIONS\n}\n\nphase('Inventory')\nconst inventory = await agent(\n 'Produce a compact map of this repository scope: ' + scope + '. ' +\n 'Cover layout, main modules, the 5–10 most important files, and obvious entry points. Be terse and structured.',\n { label: 'repo inventory', toolset: READ_ONLY_TOOLS },\n)\n\nphase('Review')\nconst findings = await parallel(\n dimensions.map((d) => () =>\n agent(\n 'Review scope \"' + scope + '\" through the ' + d.key + ' lens.\\\\n' +\n 'Focus: ' + d.focus + '\\\\n\\\\n' +\n 'Inventory for orientation:\\\\n' + inventory + '\\\\n\\\\n' +\n 'Return findings: file paths, line numbers when known, severity (low/med/high), a one-sentence why, a one-sentence fix.',\n {\n label: d.key + ' review',\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 line: { type: ['number', 'string'] },\n severity: { type: 'string', enum: ['low', 'med', 'high'] },\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('Synthesize')\nconst live = findings.filter(Boolean)\nif (!live.length) {\n return { ok: true, scope, summary: 'No findings.', byDimension: {}, priorityActions: [] }\n}\nconst byDimension = {}\nfor (let i = 0; i < dimensions.length; i++) {\n byDimension[dimensions[i].key] = live[i]?.findings ?? []\n}\n\nconst summary = await agent(\n 'Synthesize a compact report from these per-dimension findings. Deduplicate near-identical items. ' +\n 'Order by severity (high → low). Cap topFindings at 20. ' +\n 'Also return priorityActions: the top 5 fixes ranked by impact, each with effort (S|M|L).\\\\n\\\\n' +\n JSON.stringify(byDimension, null, 2),\n {\n label: 'report synthesis',\n schema: {\n type: 'object',\n properties: {\n topFindings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n dimension: { type: 'string' },\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n fix: { type: 'string' },\n },\n required: ['dimension', 'file', 'severity', 'title'],\n },\n },\n priorityActions: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n severity: { type: 'string' },\n title: { type: 'string' },\n effort: { type: 'string', enum: ['S', 'M', 'L'] },\n },\n required: ['file', 'severity', 'title', 'effort'],\n },\n },\n summary: { type: 'string' },\n },\n required: ['topFindings', 'priorityActions', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n scope,\n dimensions: dimensions.map((d) => d.key),\n ...(summary ?? { topFindings: [], priorityActions: [], summary: 'synthesis failed' }),\n byDimension,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,oBAAoB"}
@@ -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 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\nreturn {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\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', '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\nreturn {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\n";
@@ -15,6 +15,20 @@ const DEBUG_INCIDENT_SCRIPT = `export const meta = {
15
15
  name: 'debug_incident',
16
16
  description: 'Triage an error or log snippet with parallel hypotheses and ranked root-cause analysis.',
17
17
  whenToUse: 'User reports a bug, crash, error message, or unexpected behavior and wants systematic triage.',
18
+ examplePrompts: [
19
+ { field: 'error', text: 'Triage this stack trace from production' },
20
+ { field: 'error', text: 'Why does the gateway return 502 after deploy?' },
21
+ ],
22
+ i18n: {
23
+ zh: {
24
+ description: '对错误或日志片段做并行假设推演,并排序根因与验证步骤。',
25
+ whenToUse: '用户报告 bug、崩溃、报错或异常行为,需要系统化排查时。',
26
+ examplePrompts: [
27
+ { field: 'error', text: '排查生产环境这条堆栈' },
28
+ { field: 'error', text: '部署后网关返回 502,可能是什么原因?' },
29
+ ],
30
+ },
31
+ },
18
32
  tags: ['debug', 'incident', 'troubleshooting'],
19
33
  estimatedAgents: { min: 7, max: 7 },
20
34
  phases: [
@@ -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 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\nreturn {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\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', '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\nreturn {\n ok: true,\n triage,\n ...(ranking ?? { topCauses: [], summary: 'ranking failed', immediateActions: [] }),\n byHypothesis,\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,wBAAwB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Built-in workflow: `implementation_plan`
3
+ *
4
+ * Turns a feature or refactor request into an actionable implementation plan.
5
+ * It first frames the goal, then explores relevant code areas in parallel, and
6
+ * finally synthesizes phased tasks with risks and validation steps.
7
+ *
8
+ * Args:
9
+ * - request: feature, bugfix, or refactor request
10
+ * - scope: optional repo path or subsystem hint
11
+ */
12
+ export declare const IMPLEMENTATION_PLAN_SCRIPT = "export const meta = {\n name: 'implementation_plan',\n description: 'Create an actionable implementation plan from a feature, refactor, or bugfix request.',\n whenToUse: 'User wants a technical plan before coding, especially for multi-file or unfamiliar code changes.',\n examplePrompts: [\n { field: 'request', text: 'Plan a refactor of the session store' },\n { field: 'request', text: 'Design implementation steps for OAuth login' },\n ],\n i18n: {\n zh: {\n description: '\u5C06\u529F\u80FD\u3001\u91CD\u6784\u6216\u4FEE\u590D\u9700\u6C42\u8F6C\u5316\u4E3A\u53EF\u6267\u884C\u7684\u5B9E\u73B0\u8BA1\u5212\u3002',\n whenToUse: '\u7528\u6237\u60F3\u5728\u52A8\u624B\u5199\u4EE3\u7801\u524D\u62FF\u5230\u6280\u672F\u65B9\u6848\uFF0C\u5C24\u5176\u662F\u591A\u6587\u4EF6\u6216\u4E0D\u719F\u6089\u4EE3\u7801\u7684\u6539\u52A8\u3002',\n examplePrompts: [\n { field: 'request', text: '\u89C4\u5212 session store \u7684\u91CD\u6784\u6B65\u9AA4' },\n { field: 'request', text: '\u8BBE\u8BA1 OAuth \u767B\u5F55\u7684\u5B9E\u73B0\u6B65\u9AA4' },\n ],\n },\n },\n tags: ['planning', 'implementation', 'architecture'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Frame' },\n { title: 'Explore' },\n { title: 'Plan' },\n { title: 'Validate' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst request = args && typeof args === 'object' && args.request\n ? String(args.request)\n : 'Infer the implementation request from the current conversation context.'\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this implementation request. Identify the desired outcome, non-goals, likely affected domains, and open questions. Be concrete and avoid generic advice.\\n\\n' +\n 'REQUEST:\\n' + request + '\\n\\nSCOPE HINT:\\n' + scope,\n {\n label: 'request framing',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n outcome: { type: 'string' },\n nonGoals: { type: 'array', items: { type: 'string' } },\n affectedDomains: { type: 'array', items: { type: 'string' } },\n openQuestions: { type: 'array', items: { type: 'string' } },\n },\n required: ['outcome', 'affectedDomains'],\n },\n },\n)\n\nconst AREAS = [\n { key: 'entrypoints', focus: 'Routes, commands, UI pages, public APIs, and user-facing surfaces that must change.' },\n { key: 'domain', focus: 'Core domain model, state transitions, stores, services, and invariants.' },\n { key: 'integration', focus: 'Cross-module dependencies, config, events, async jobs, persistence, and external APIs.' },\n { key: 'validation', focus: 'Existing tests, missing regression tests, build/type/lint commands, and release validation.' },\n]\n\nphase('Explore')\nconst explorations = await parallel(\n AREAS.map((area) => () =>\n agent(\n 'Explore the repository for this implementation plan through the ' + area.key + ' lens.\\n' +\n 'Focus: ' + area.focus + '\\n\\n' +\n 'REQUEST:\\n' + request + '\\n\\n' +\n 'FRAME:\\n' + JSON.stringify(frame, null, 2) + '\\n\\n' +\n 'Return concrete files/functions/modules to inspect or modify, existing patterns to follow, and constraints that affect the plan.',\n {\n label: area.key + ' exploration',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n targets: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n reason: { type: 'string' },\n },\n required: ['path', 'reason'],\n },\n },\n patterns: { type: 'array', items: { type: 'string' } },\n constraints: { type: 'array', items: { type: 'string' } },\n },\n required: ['targets', 'constraints'],\n },\n },\n ),\n ),\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Synthesize an implementation plan from the framing and explorations. Make it executable by an engineer or coding agent. ' +\n 'Use phased tasks, name the concrete files/modules, include sequencing/dependencies, and call out decisions that need user confirmation.\\n\\n' +\n JSON.stringify({ request, scope, frame, explorations }, null, 2),\n {\n label: 'plan synthesis',\n schema: {\n type: 'object',\n properties: {\n summary: { type: 'string' },\n phases: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n tasks: { type: 'array', items: { type: 'string' } },\n files: { type: 'array', items: { type: 'string' } },\n },\n required: ['title', 'tasks'],\n },\n },\n decisions: { type: 'array', items: { type: 'string' } },\n risks: { type: 'array', items: { type: 'string' } },\n },\n required: ['summary', 'phases', 'risks'],\n },\n },\n)\n\nphase('Validate')\nconst validation = await agent(\n 'Create a validation checklist for this implementation plan. Include targeted tests, full commands, manual UI/API checks if relevant, and rollback/recovery notes.\\n\\n' +\n JSON.stringify({ request, plan }, null, 2),\n {\n label: 'validation checklist',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n testCommands: { type: 'array', items: { type: 'string' } },\n manualChecks: { type: 'array', items: { type: 'string' } },\n rollbackNotes: { type: 'array', items: { type: 'string' } },\n },\n required: ['testCommands', 'manualChecks'],\n },\n },\n)\n\nreturn {\n ok: true,\n request,\n scope,\n ...(plan ?? { summary: 'plan synthesis failed', phases: [], decisions: [], risks: [] }),\n validation: validation ?? { testCommands: [], manualChecks: [], rollbackNotes: [] },\n}\n";
@@ -0,0 +1,175 @@
1
+ //#region src/agent/workflow/builtins/implementation-plan.ts
2
+ /**
3
+ * Built-in workflow: `implementation_plan`
4
+ *
5
+ * Turns a feature or refactor request into an actionable implementation plan.
6
+ * It first frames the goal, then explores relevant code areas in parallel, and
7
+ * finally synthesizes phased tasks with risks and validation steps.
8
+ *
9
+ * Args:
10
+ * - request: feature, bugfix, or refactor request
11
+ * - scope: optional repo path or subsystem hint
12
+ */
13
+ const IMPLEMENTATION_PLAN_SCRIPT = `export const meta = {
14
+ name: 'implementation_plan',
15
+ description: 'Create an actionable implementation plan from a feature, refactor, or bugfix request.',
16
+ whenToUse: 'User wants a technical plan before coding, especially for multi-file or unfamiliar code changes.',
17
+ examplePrompts: [
18
+ { field: 'request', text: 'Plan a refactor of the session store' },
19
+ { field: 'request', text: 'Design implementation steps for OAuth login' },
20
+ ],
21
+ i18n: {
22
+ zh: {
23
+ description: '将功能、重构或修复需求转化为可执行的实现计划。',
24
+ whenToUse: '用户想在动手写代码前拿到技术方案,尤其是多文件或不熟悉代码的改动。',
25
+ examplePrompts: [
26
+ { field: 'request', text: '规划 session store 的重构步骤' },
27
+ { field: 'request', text: '设计 OAuth 登录的实现步骤' },
28
+ ],
29
+ },
30
+ },
31
+ tags: ['planning', 'implementation', 'architecture'],
32
+ estimatedAgents: { min: 5, max: 6 },
33
+ phases: [
34
+ { title: 'Frame' },
35
+ { title: 'Explore' },
36
+ { title: 'Plan' },
37
+ { title: 'Validate' },
38
+ ],
39
+ }
40
+
41
+ const READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']
42
+
43
+ const request = args && typeof args === 'object' && args.request
44
+ ? String(args.request)
45
+ : 'Infer the implementation request from the current conversation context.'
46
+
47
+ const scope = args && typeof args === 'object' && args.scope
48
+ ? String(args.scope)
49
+ : '.'
50
+
51
+ phase('Frame')
52
+ const frame = await agent(
53
+ 'Frame this implementation request. Identify the desired outcome, non-goals, likely affected domains, and open questions. Be concrete and avoid generic advice.\\n\\n' +
54
+ 'REQUEST:\\n' + request + '\\n\\nSCOPE HINT:\\n' + scope,
55
+ {
56
+ label: 'request framing',
57
+ toolset: READ_ONLY_TOOLS,
58
+ schema: {
59
+ type: 'object',
60
+ properties: {
61
+ outcome: { type: 'string' },
62
+ nonGoals: { type: 'array', items: { type: 'string' } },
63
+ affectedDomains: { type: 'array', items: { type: 'string' } },
64
+ openQuestions: { type: 'array', items: { type: 'string' } },
65
+ },
66
+ required: ['outcome', 'affectedDomains'],
67
+ },
68
+ },
69
+ )
70
+
71
+ const AREAS = [
72
+ { key: 'entrypoints', focus: 'Routes, commands, UI pages, public APIs, and user-facing surfaces that must change.' },
73
+ { key: 'domain', focus: 'Core domain model, state transitions, stores, services, and invariants.' },
74
+ { key: 'integration', focus: 'Cross-module dependencies, config, events, async jobs, persistence, and external APIs.' },
75
+ { key: 'validation', focus: 'Existing tests, missing regression tests, build/type/lint commands, and release validation.' },
76
+ ]
77
+
78
+ phase('Explore')
79
+ const explorations = await parallel(
80
+ AREAS.map((area) => () =>
81
+ agent(
82
+ 'Explore the repository for this implementation plan through the ' + area.key + ' lens.\\n' +
83
+ 'Focus: ' + area.focus + '\\n\\n' +
84
+ 'REQUEST:\\n' + request + '\\n\\n' +
85
+ 'FRAME:\\n' + JSON.stringify(frame, null, 2) + '\\n\\n' +
86
+ 'Return concrete files/functions/modules to inspect or modify, existing patterns to follow, and constraints that affect the plan.',
87
+ {
88
+ label: area.key + ' exploration',
89
+ toolset: READ_ONLY_TOOLS,
90
+ schema: {
91
+ type: 'object',
92
+ properties: {
93
+ targets: {
94
+ type: 'array',
95
+ items: {
96
+ type: 'object',
97
+ properties: {
98
+ path: { type: 'string' },
99
+ reason: { type: 'string' },
100
+ },
101
+ required: ['path', 'reason'],
102
+ },
103
+ },
104
+ patterns: { type: 'array', items: { type: 'string' } },
105
+ constraints: { type: 'array', items: { type: 'string' } },
106
+ },
107
+ required: ['targets', 'constraints'],
108
+ },
109
+ },
110
+ ),
111
+ ),
112
+ )
113
+
114
+ phase('Plan')
115
+ const plan = await agent(
116
+ 'Synthesize an implementation plan from the framing and explorations. Make it executable by an engineer or coding agent. ' +
117
+ 'Use phased tasks, name the concrete files/modules, include sequencing/dependencies, and call out decisions that need user confirmation.\\n\\n' +
118
+ JSON.stringify({ request, scope, frame, explorations }, null, 2),
119
+ {
120
+ label: 'plan synthesis',
121
+ schema: {
122
+ type: 'object',
123
+ properties: {
124
+ summary: { type: 'string' },
125
+ phases: {
126
+ type: 'array',
127
+ items: {
128
+ type: 'object',
129
+ properties: {
130
+ title: { type: 'string' },
131
+ tasks: { type: 'array', items: { type: 'string' } },
132
+ files: { type: 'array', items: { type: 'string' } },
133
+ },
134
+ required: ['title', 'tasks'],
135
+ },
136
+ },
137
+ decisions: { type: 'array', items: { type: 'string' } },
138
+ risks: { type: 'array', items: { type: 'string' } },
139
+ },
140
+ required: ['summary', 'phases', 'risks'],
141
+ },
142
+ },
143
+ )
144
+
145
+ phase('Validate')
146
+ const validation = await agent(
147
+ 'Create a validation checklist for this implementation plan. Include targeted tests, full commands, manual UI/API checks if relevant, and rollback/recovery notes.\\n\\n' +
148
+ JSON.stringify({ request, plan }, null, 2),
149
+ {
150
+ label: 'validation checklist',
151
+ toolset: READ_ONLY_TOOLS,
152
+ schema: {
153
+ type: 'object',
154
+ properties: {
155
+ testCommands: { type: 'array', items: { type: 'string' } },
156
+ manualChecks: { type: 'array', items: { type: 'string' } },
157
+ rollbackNotes: { type: 'array', items: { type: 'string' } },
158
+ },
159
+ required: ['testCommands', 'manualChecks'],
160
+ },
161
+ },
162
+ )
163
+
164
+ return {
165
+ ok: true,
166
+ request,
167
+ scope,
168
+ ...(plan ?? { summary: 'plan synthesis failed', phases: [], decisions: [], risks: [] }),
169
+ validation: validation ?? { testCommands: [], manualChecks: [], rollbackNotes: [] },
170
+ }
171
+ `;
172
+ //#endregion
173
+ export { IMPLEMENTATION_PLAN_SCRIPT };
174
+
175
+ //# sourceMappingURL=implementation-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implementation-plan.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/implementation-plan.ts"],"sourcesContent":["/**\n * Built-in workflow: `implementation_plan`\n *\n * Turns a feature or refactor request into an actionable implementation plan.\n * It first frames the goal, then explores relevant code areas in parallel, and\n * finally synthesizes phased tasks with risks and validation steps.\n *\n * Args:\n * - request: feature, bugfix, or refactor request\n * - scope: optional repo path or subsystem hint\n */\n\nexport const IMPLEMENTATION_PLAN_SCRIPT = `export const meta = {\n name: 'implementation_plan',\n description: 'Create an actionable implementation plan from a feature, refactor, or bugfix request.',\n whenToUse: 'User wants a technical plan before coding, especially for multi-file or unfamiliar code changes.',\n examplePrompts: [\n { field: 'request', text: 'Plan a refactor of the session store' },\n { field: 'request', text: 'Design implementation steps for OAuth login' },\n ],\n i18n: {\n zh: {\n description: '将功能、重构或修复需求转化为可执行的实现计划。',\n whenToUse: '用户想在动手写代码前拿到技术方案,尤其是多文件或不熟悉代码的改动。',\n examplePrompts: [\n { field: 'request', text: '规划 session store 的重构步骤' },\n { field: 'request', text: '设计 OAuth 登录的实现步骤' },\n ],\n },\n },\n tags: ['planning', 'implementation', 'architecture'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Frame' },\n { title: 'Explore' },\n { title: 'Plan' },\n { title: 'Validate' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst request = args && typeof args === 'object' && args.request\n ? String(args.request)\n : 'Infer the implementation request from the current conversation context.'\n\nconst scope = args && typeof args === 'object' && args.scope\n ? String(args.scope)\n : '.'\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this implementation request. Identify the desired outcome, non-goals, likely affected domains, and open questions. Be concrete and avoid generic advice.\\\\n\\\\n' +\n 'REQUEST:\\\\n' + request + '\\\\n\\\\nSCOPE HINT:\\\\n' + scope,\n {\n label: 'request framing',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n outcome: { type: 'string' },\n nonGoals: { type: 'array', items: { type: 'string' } },\n affectedDomains: { type: 'array', items: { type: 'string' } },\n openQuestions: { type: 'array', items: { type: 'string' } },\n },\n required: ['outcome', 'affectedDomains'],\n },\n },\n)\n\nconst AREAS = [\n { key: 'entrypoints', focus: 'Routes, commands, UI pages, public APIs, and user-facing surfaces that must change.' },\n { key: 'domain', focus: 'Core domain model, state transitions, stores, services, and invariants.' },\n { key: 'integration', focus: 'Cross-module dependencies, config, events, async jobs, persistence, and external APIs.' },\n { key: 'validation', focus: 'Existing tests, missing regression tests, build/type/lint commands, and release validation.' },\n]\n\nphase('Explore')\nconst explorations = await parallel(\n AREAS.map((area) => () =>\n agent(\n 'Explore the repository for this implementation plan through the ' + area.key + ' lens.\\\\n' +\n 'Focus: ' + area.focus + '\\\\n\\\\n' +\n 'REQUEST:\\\\n' + request + '\\\\n\\\\n' +\n 'FRAME:\\\\n' + JSON.stringify(frame, null, 2) + '\\\\n\\\\n' +\n 'Return concrete files/functions/modules to inspect or modify, existing patterns to follow, and constraints that affect the plan.',\n {\n label: area.key + ' exploration',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n targets: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n path: { type: 'string' },\n reason: { type: 'string' },\n },\n required: ['path', 'reason'],\n },\n },\n patterns: { type: 'array', items: { type: 'string' } },\n constraints: { type: 'array', items: { type: 'string' } },\n },\n required: ['targets', 'constraints'],\n },\n },\n ),\n ),\n)\n\nphase('Plan')\nconst plan = await agent(\n 'Synthesize an implementation plan from the framing and explorations. Make it executable by an engineer or coding agent. ' +\n 'Use phased tasks, name the concrete files/modules, include sequencing/dependencies, and call out decisions that need user confirmation.\\\\n\\\\n' +\n JSON.stringify({ request, scope, frame, explorations }, null, 2),\n {\n label: 'plan synthesis',\n schema: {\n type: 'object',\n properties: {\n summary: { type: 'string' },\n phases: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n tasks: { type: 'array', items: { type: 'string' } },\n files: { type: 'array', items: { type: 'string' } },\n },\n required: ['title', 'tasks'],\n },\n },\n decisions: { type: 'array', items: { type: 'string' } },\n risks: { type: 'array', items: { type: 'string' } },\n },\n required: ['summary', 'phases', 'risks'],\n },\n },\n)\n\nphase('Validate')\nconst validation = await agent(\n 'Create a validation checklist for this implementation plan. Include targeted tests, full commands, manual UI/API checks if relevant, and rollback/recovery notes.\\\\n\\\\n' +\n JSON.stringify({ request, plan }, null, 2),\n {\n label: 'validation checklist',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n testCommands: { type: 'array', items: { type: 'string' } },\n manualChecks: { type: 'array', items: { type: 'string' } },\n rollbackNotes: { type: 'array', items: { type: 'string' } },\n },\n required: ['testCommands', 'manualChecks'],\n },\n },\n)\n\nreturn {\n ok: true,\n request,\n scope,\n ...(plan ?? { summary: 'plan synthesis failed', phases: [], decisions: [], risks: [] }),\n validation: validation ?? { testCommands: [], manualChecks: [], rollbackNotes: [] },\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,6BAA6B"}
@@ -6,12 +6,14 @@
6
6
  */
7
7
  import { AUDIT_REPO_SCRIPT } from './audit-repo.js';
8
8
  import { DEBUG_INCIDENT_SCRIPT } from './debug-incident.js';
9
+ import { IMPLEMENTATION_PLAN_SCRIPT } from './implementation-plan.js';
9
10
  import { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';
10
11
  import { PR_REVIEW_SCRIPT } from './pr-review.js';
12
+ import { RELEASE_CHECK_SCRIPT } from './release-check.js';
11
13
  import { RESEARCH_SCRIPT } from './research.js';
12
14
  export interface BuiltinWorkflow {
13
15
  name: string;
14
16
  script: string;
15
17
  }
16
18
  export declare const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[];
17
- export { AUDIT_REPO_SCRIPT, DEBUG_INCIDENT_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RESEARCH_SCRIPT, };
19
+ export { AUDIT_REPO_SCRIPT, DEBUG_INCIDENT_SCRIPT, IMPLEMENTATION_PLAN_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RELEASE_CHECK_SCRIPT, RESEARCH_SCRIPT, };
@@ -1,7 +1,9 @@
1
1
  import { AUDIT_REPO_SCRIPT } from "./audit-repo.js";
2
2
  import { DEBUG_INCIDENT_SCRIPT } from "./debug-incident.js";
3
+ import { IMPLEMENTATION_PLAN_SCRIPT } from "./implementation-plan.js";
3
4
  import { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from "./multi-perspective-review.js";
4
5
  import { PR_REVIEW_SCRIPT } from "./pr-review.js";
6
+ import { RELEASE_CHECK_SCRIPT } from "./release-check.js";
5
7
  import { RESEARCH_SCRIPT } from "./research.js";
6
8
  //#region src/agent/workflow/builtins/index.ts
7
9
  /**
@@ -19,6 +21,10 @@ const BUILTIN_WORKFLOWS = Object.freeze([
19
21
  name: "debug_incident",
20
22
  script: DEBUG_INCIDENT_SCRIPT
21
23
  },
24
+ {
25
+ name: "implementation_plan",
26
+ script: IMPLEMENTATION_PLAN_SCRIPT
27
+ },
22
28
  {
23
29
  name: "multi_perspective_review",
24
30
  script: MULTI_PERSPECTIVE_REVIEW_SCRIPT
@@ -27,12 +33,16 @@ const BUILTIN_WORKFLOWS = Object.freeze([
27
33
  name: "pr_review",
28
34
  script: PR_REVIEW_SCRIPT
29
35
  },
36
+ {
37
+ name: "release_check",
38
+ script: RELEASE_CHECK_SCRIPT
39
+ },
30
40
  {
31
41
  name: "research",
32
42
  script: RESEARCH_SCRIPT
33
43
  }
34
44
  ]);
35
45
  //#endregion
36
- export { AUDIT_REPO_SCRIPT, BUILTIN_WORKFLOWS, DEBUG_INCIDENT_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RESEARCH_SCRIPT };
46
+ export { AUDIT_REPO_SCRIPT, BUILTIN_WORKFLOWS, DEBUG_INCIDENT_SCRIPT, IMPLEMENTATION_PLAN_SCRIPT, MULTI_PERSPECTIVE_REVIEW_SCRIPT, PR_REVIEW_SCRIPT, RELEASE_CHECK_SCRIPT, RESEARCH_SCRIPT };
37
47
 
38
48
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/index.ts"],"sourcesContent":["/**\n * Bundled workflow templates. These are shipped with xopc and discoverable\n * via the catalog alongside user workflows in `~/.xopc/workflows/`. A user\n * workflow with the same `name` always wins — built-ins are starting points,\n * not authority.\n */\n\nimport { AUDIT_REPO_SCRIPT } from './audit-repo.js';\nimport { DEBUG_INCIDENT_SCRIPT } from './debug-incident.js';\nimport { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';\nimport { PR_REVIEW_SCRIPT } from './pr-review.js';\nimport { RESEARCH_SCRIPT } from './research.js';\n\nexport interface BuiltinWorkflow {\n name: string;\n script: string;\n}\n\nexport const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[] = Object.freeze([\n { name: 'audit_repo', script: AUDIT_REPO_SCRIPT },\n { name: 'debug_incident', script: DEBUG_INCIDENT_SCRIPT },\n { name: 'multi_perspective_review', script: MULTI_PERSPECTIVE_REVIEW_SCRIPT },\n { name: 'pr_review', script: PR_REVIEW_SCRIPT },\n { name: 'research', script: RESEARCH_SCRIPT },\n]);\n\nexport {\n AUDIT_REPO_SCRIPT,\n DEBUG_INCIDENT_SCRIPT,\n MULTI_PERSPECTIVE_REVIEW_SCRIPT,\n PR_REVIEW_SCRIPT,\n RESEARCH_SCRIPT,\n};\n"],"mappings":";;;;;;;;;;;;AAkBA,MAAa,oBAAgD,OAAO,OAAO;CACzE;EAAE,MAAM;EAAc,QAAQ;EAAmB;CACjD;EAAE,MAAM;EAAkB,QAAQ;EAAuB;CACzD;EAAE,MAAM;EAA4B,QAAQ;EAAiC;CAC7E;EAAE,MAAM;EAAa,QAAQ;EAAkB;CAC/C;EAAE,MAAM;EAAY,QAAQ;EAAiB;CAC9C,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/index.ts"],"sourcesContent":["/**\n * Bundled workflow templates. These are shipped with xopc and discoverable\n * via the catalog alongside user workflows in `~/.xopc/workflows/`. A user\n * workflow with the same `name` always wins — built-ins are starting points,\n * not authority.\n */\n\nimport { AUDIT_REPO_SCRIPT } from './audit-repo.js';\nimport { DEBUG_INCIDENT_SCRIPT } from './debug-incident.js';\nimport { IMPLEMENTATION_PLAN_SCRIPT } from './implementation-plan.js';\nimport { MULTI_PERSPECTIVE_REVIEW_SCRIPT } from './multi-perspective-review.js';\nimport { PR_REVIEW_SCRIPT } from './pr-review.js';\nimport { RELEASE_CHECK_SCRIPT } from './release-check.js';\nimport { RESEARCH_SCRIPT } from './research.js';\n\nexport interface BuiltinWorkflow {\n name: string;\n script: string;\n}\n\nexport const BUILTIN_WORKFLOWS: readonly BuiltinWorkflow[] = Object.freeze([\n { name: 'audit_repo', script: AUDIT_REPO_SCRIPT },\n { name: 'debug_incident', script: DEBUG_INCIDENT_SCRIPT },\n { name: 'implementation_plan', script: IMPLEMENTATION_PLAN_SCRIPT },\n { name: 'multi_perspective_review', script: MULTI_PERSPECTIVE_REVIEW_SCRIPT },\n { name: 'pr_review', script: PR_REVIEW_SCRIPT },\n { name: 'release_check', script: RELEASE_CHECK_SCRIPT },\n { name: 'research', script: RESEARCH_SCRIPT },\n]);\n\nexport {\n AUDIT_REPO_SCRIPT,\n DEBUG_INCIDENT_SCRIPT,\n IMPLEMENTATION_PLAN_SCRIPT,\n MULTI_PERSPECTIVE_REVIEW_SCRIPT,\n PR_REVIEW_SCRIPT,\n RELEASE_CHECK_SCRIPT,\n RESEARCH_SCRIPT,\n};\n"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAa,oBAAgD,OAAO,OAAO;CACzE;EAAE,MAAM;EAAc,QAAQ;EAAmB;CACjD;EAAE,MAAM;EAAkB,QAAQ;EAAuB;CACzD;EAAE,MAAM;EAAuB,QAAQ;EAA4B;CACnE;EAAE,MAAM;EAA4B,QAAQ;EAAiC;CAC7E;EAAE,MAAM;EAAa,QAAQ;EAAkB;CAC/C;EAAE,MAAM;EAAiB,QAAQ;EAAsB;CACvD;EAAE,MAAM;EAAY,QAAQ;EAAiB;CAC9C,CAAC"}
@@ -11,4 +11,4 @@
11
11
  * - lenses: optional array of { name, angle } to override default lenses
12
12
  * - skipAdversarial: when true, skip the adversarial judge phase
13
13
  */
14
- export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\n' +\n 'Lens focus: ' + l.angle + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'Return 3\u20137 concrete observations. Each entry: title (5\u201310 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nreturn {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\n";
14
+ export declare const MULTI_PERSPECTIVE_REVIEW_SCRIPT = "export const meta = {\n name: 'multi_perspective_review',\n description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',\n whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',\n examplePrompts: [\n { field: 'target', text: 'Stress-test this API redesign before we ship' },\n { field: 'target', text: 'Review the migration plan from multiple angles' },\n ],\n i18n: {\n zh: {\n description: '\u4ECE\u591A\u4E2A\u72EC\u7ACB\u89C6\u89D2\u8BC4\u5BA1\u76EE\u6807\uFF0C\u5E76\u7531\u5BF9\u6297\u6027\u8BC4\u5BA1\u5224\u65AD\u5B9E\u9645\u4F1A\u51FA\u4EC0\u4E48\u95EE\u9898\u3002',\n whenToUse: '\u7528\u6237\u60F3\u5728\u843D\u5730\u524D\u5BF9\u8BBE\u8BA1\u3001\u65B9\u6848\u3001PR \u6216\u63D0\u6848\u505A\u538B\u529B\u6D4B\u8BD5\u65F6\u3002',\n examplePrompts: [\n { field: 'target', text: '\u4E0A\u7EBF\u524D\u4ECE\u591A\u89D2\u5EA6\u538B\u529B\u6D4B\u8BD5\u8FD9\u4E2A API redesign' },\n { field: 'target', text: '\u4ECE\u591A\u4E2A\u89C6\u89D2\u8BC4\u5BA1\u8FD9\u4EFD\u8FC1\u79FB\u65B9\u6848' },\n ],\n },\n },\n tags: ['review', 'planning', 'decision'],\n estimatedAgents: { min: 5, max: 6 },\n phases: [\n { title: 'Lenses' },\n { title: 'Adversarial' },\n { title: 'Synthesize' },\n ],\n}\n\nconst READ_ONLY_TOOLS = ['read_file', 'grep', 'find', 'list_dir']\n\nconst target = args && typeof args === 'object' && args.target\n ? String(args.target)\n : 'No explicit target was provided. Treat the currently focused file or recent context as the target.'\n\nconst skipAdversarial = Boolean(args && typeof args === 'object' && args.skipAdversarial)\n\nconst DEFAULT_LENSES = [\n { name: 'User', angle: 'How a real user experiences this. Friction, confusion, surprise paths, accessibility.' },\n { name: 'Operator', angle: 'How an on-call engineer experiences this in production. Failure modes, observability, rollback.' },\n { name: 'Skeptic', angle: 'Hidden assumptions. What is being implied but not stated. What would break under load or weird input.' },\n { name: 'Maintainer', angle: 'Six-month-later view. Clarity, naming, layering, ease of changing nearby code.' },\n]\n\nlet lenses = DEFAULT_LENSES\nif (args && typeof args === 'object' && Array.isArray(args.lenses) && args.lenses.length) {\n lenses = args.lenses\n .filter((l) => l && typeof l === 'object' && l.name && l.angle)\n .map((l) => ({ name: String(l.name), angle: String(l.angle) }))\n if (!lenses.length) lenses = DEFAULT_LENSES\n}\n\nphase('Lenses')\nconst lensViews = await parallel(\n lenses.map((l) => () =>\n agent(\n 'Review the following target through the ' + l.name + ' lens.\\n' +\n 'Lens focus: ' + l.angle + '\\n\\n' +\n 'TARGET:\\n' + target + '\\n\\n' +\n 'Return 3\u20137 concrete observations. Each entry: title (5\u201310 words), why-it-matters (1 sentence), risk (low/med/high).',\n {\n label: l.name + ' lens',\n toolset: READ_ONLY_TOOLS,\n schema: {\n type: 'object',\n properties: {\n observations: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n why: { type: 'string' },\n risk: { type: 'string', enum: ['low', 'med', 'high'] },\n },\n required: ['title', 'why', 'risk'],\n },\n },\n },\n required: ['observations'],\n },\n },\n ),\n ),\n)\n\nconst valid = lensViews.filter(Boolean)\nconst allObs = valid.flatMap((v, i) =>\n (v?.observations ?? []).map((o) => ({ lens: lenses[i].name, ...o })),\n)\n\nlet verdict = null\nif (!skipAdversarial) {\n phase('Adversarial')\n verdict = await agent(\n 'You are an adversarial judge. Given these multi-lens observations of a target, decide which would actually cause real harm if shipped as-is. ' +\n 'Default to realRisk=false unless an observation has clear, mechanism-level evidence. ' +\n 'Rate evidenceStrength as weak | moderate | strong.\\n\\n' +\n JSON.stringify(allObs, null, 2),\n {\n label: 'adversarial verdict',\n schema: {\n type: 'object',\n properties: {\n verdicts: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n lens: { type: 'string' },\n realRisk: { type: 'boolean' },\n evidenceStrength: { type: 'string', enum: ['weak', 'moderate', 'strong'] },\n reason: { type: 'string' },\n },\n required: ['title', 'lens', 'realRisk', 'evidenceStrength', 'reason'],\n },\n },\n },\n required: ['verdicts'],\n },\n },\n )\n}\n\nphase('Synthesize')\nconst confirmed = (verdict?.verdicts ?? []).filter((v) => v.realRisk)\nconst goNoGo = skipAdversarial\n ? (allObs.some((o) => o.risk === 'high') ? 'fix_first' : 'ship')\n : confirmed.some((v) => v.evidenceStrength === 'strong')\n ? 'fix_first'\n : confirmed.length\n ? 'fix_first'\n : 'ship'\n\nreturn {\n ok: true,\n target,\n lenses: lenses.map((l) => l.name),\n skipAdversarial,\n observationCount: allObs.length,\n confirmedRiskCount: confirmed.length,\n goNoGo,\n topRisks: confirmed.slice(0, 10),\n allVerdicts: verdict?.verdicts ?? [],\n}\n";
@@ -16,6 +16,20 @@ const MULTI_PERSPECTIVE_REVIEW_SCRIPT = `export const meta = {
16
16
  name: 'multi_perspective_review',
17
17
  description: 'Review a target from N independent perspectives, then adversarially judge what would actually break.',
18
18
  whenToUse: 'User wants a stress-test of a design, plan, PR, or proposal before committing to it.',
19
+ examplePrompts: [
20
+ { field: 'target', text: 'Stress-test this API redesign before we ship' },
21
+ { field: 'target', text: 'Review the migration plan from multiple angles' },
22
+ ],
23
+ i18n: {
24
+ zh: {
25
+ description: '从多个独立视角评审目标,并由对抗性评审判断实际会出什么问题。',
26
+ whenToUse: '用户想在落地前对设计、方案、PR 或提案做压力测试时。',
27
+ examplePrompts: [
28
+ { field: 'target', text: '上线前从多角度压力测试这个 API redesign' },
29
+ { field: 'target', text: '从多个视角评审这份迁移方案' },
30
+ ],
31
+ },
32
+ },
19
33
  tags: ['review', 'planning', 'decision'],
20
34
  estimatedAgents: { min: 5, max: 6 },
21
35
  phases: [