minimal-agent 0.8.2 → 0.10.0

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 (484) hide show
  1. package/README.md +14 -12
  2. package/package.json +34 -1
  3. package/plugins/cron-runner/.claude-plugin/plugin.json +5 -0
  4. package/plugins/cron-runner/commands/cron.md +26 -0
  5. package/plugins/cron-runner/commands/crons.md +7 -0
  6. package/plugins/cron-runner/plugin.js +34 -0
  7. package/plugins/cron-runner/src/commands.js +348 -0
  8. package/plugins/cron-runner/src/cronTime.js +148 -0
  9. package/plugins/cron-runner/src/lock.js +68 -0
  10. package/plugins/cron-runner/src/runs.js +89 -0
  11. package/plugins/cron-runner/src/scheduleEngine.js +72 -0
  12. package/plugins/cron-runner/src/scheduler.js +355 -0
  13. package/plugins/cron-runner/src/schema.js +140 -0
  14. package/plugins/cron-runner/src/service.js +167 -0
  15. package/plugins/cron-runner/src/store.js +298 -0
  16. package/plugins/cron-runner/src/types.js +1 -0
  17. package/plugins/workflow-runner/commands/workflow.md +4 -4
  18. package/plugins/workflow-runner/commands/workflows.md +1 -1
  19. package/plugins/workflow-runner/plugin.js +3 -1
  20. package/plugins/workflow-runner/src/agentCommon.js +249 -51
  21. package/plugins/workflow-runner/src/dslManifest.js +72 -0
  22. package/plugins/workflow-runner/src/expressions.js +198 -15
  23. package/plugins/workflow-runner/src/index.js +40 -8
  24. package/plugins/workflow-runner/src/jsonPayload.js +1 -1
  25. package/plugins/workflow-runner/src/loader.js +286 -72
  26. package/plugins/workflow-runner/src/multimodal.js +37 -0
  27. package/plugins/workflow-runner/src/recovery.js +49 -39
  28. package/plugins/workflow-runner/src/runner.js +802 -287
  29. package/plugins/workflow-runner/src/stepExecutors/agent.js +157 -39
  30. package/plugins/workflow-runner/src/stepExecutors/assert.js +16 -3
  31. package/plugins/workflow-runner/src/stepExecutors/llm.js +60 -111
  32. package/plugins/workflow-runner/src/stepExecutors/skill.js +47 -47
  33. package/plugins/workflow-runner/src/stepExecutors/tool.js +76 -10
  34. package/plugins/workflow-runner/src/stepExecutors/verify.js +27 -10
  35. package/plugins/workflow-runner/src/taskIdentity.js +296 -0
  36. package/plugins/workflow-runner/src/types.js +19 -9
  37. package/plugins/workflow-runner/src/workflowState.js +516 -33
  38. package/skills/adversarial-review/SKILL.md +0 -1
  39. package/skills/ai-image/SKILL.md +89 -0
  40. package/skills/ai-image/scripts/generate.mjs +497 -0
  41. package/skills/ai-image/scripts/generate_from_plan.mjs +469 -0
  42. package/skills/ai-image/scripts/generate_from_plan_test.mjs +223 -0
  43. package/skills/ai-image/scripts/generate_test.mjs +74 -0
  44. package/skills/browser-automation/SKILL.md +47 -0
  45. package/skills/docx/SKILL.md +25 -3
  46. package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
  47. package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
  48. package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
  49. package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
  50. package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
  51. package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
  52. package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
  53. package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
  54. package/skills/docx/scripts/opc_check.py +253 -0
  55. package/skills/image-gen-openrouter/SKILL.md +10 -2
  56. package/skills/image-stats/SKILL.md +65 -0
  57. package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
  58. package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
  59. package/skills/image-stats/scripts/image_stats.py +368 -0
  60. package/skills/image-stats/scripts/image_stats_test.py +181 -0
  61. package/skills/pptx/SKILL.md +123 -95
  62. package/skills/pptx/design.md +82 -0
  63. package/skills/pptx/examples/README.md +29 -0
  64. package/skills/pptx/examples/hybrid_example.mjs +107 -0
  65. package/skills/pptx/examples/hybrid_example.pptx +0 -0
  66. package/skills/pptx/pptxgenjs.md +41 -0
  67. package/skills/pptx/scripts/deck_helpers.mjs +224 -0
  68. package/skills/pptx/scripts/layout_lint.py +293 -0
  69. package/skills/pptx/scripts/layout_lint_test.py +160 -0
  70. package/skills/pptx/scripts/opc_check.py +339 -0
  71. package/skills/pptx/scripts/svg_fallback.mjs +145 -0
  72. package/skills/pptx/svg.md +67 -0
  73. package/skills/tts-zh/SKILL.md +19 -2
  74. package/skills/ui-design/SKILL.md +158 -0
  75. package/skills/ui-design/claude_design.md +309 -0
  76. package/skills/ui-design/evals/evals.json +254 -0
  77. package/skills/ui-design/references/aesthetic-direction.md +83 -0
  78. package/skills/ui-design/references/claude-design-protocol.md +36 -0
  79. package/skills/ui-design/references/design-context.md +53 -0
  80. package/skills/ui-design/references/design-execution-playbook.md +82 -0
  81. package/skills/ui-design/references/export-pptx.md +124 -0
  82. package/skills/ui-design/references/layout-composition.md +654 -0
  83. package/skills/ui-design/references/preview-feedback.md +37 -0
  84. package/skills/ui-design/references/source-image-layout.md +189 -0
  85. package/skills/ui-design/references/starter-components.md +78 -0
  86. package/skills/ui-design/references/vi-aegis-vector.md +144 -0
  87. package/skills/ui-design/references/vi-amber-prism.md +133 -0
  88. package/skills/ui-design/references/vi-aqua-glass.md +200 -0
  89. package/skills/ui-design/references/vi-comfort-vision.md +147 -0
  90. package/skills/ui-design/references/vi-ember-prism.md +140 -0
  91. package/skills/ui-design/references/vi-nebula-console.md +151 -0
  92. package/skills/ui-design/references/vi-obsidian-optics.md +139 -0
  93. package/skills/ui-design/references/vi-obsidian-xui.md +143 -0
  94. package/skills/ui-design/references/vi-precision-horizon-dark.md +117 -0
  95. package/skills/ui-design/references/vi-precision-horizon.md +215 -0
  96. package/skills/ui-design/references/vi-solar-relay.md +130 -0
  97. package/skills/ui-design/references/vi-template-workflow.md +48 -0
  98. package/skills/ui-design/references/vi-verdant-grid.md +141 -0
  99. package/skills/ui-design/references/vi-violet-meridian.md +172 -0
  100. package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
  101. package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
  102. package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
  103. package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
  104. package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
  105. package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
  106. package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
  107. package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
  108. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
  109. package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
  110. package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
  111. package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
  112. package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
  113. package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
  114. package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
  115. package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
  116. package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
  117. package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
  118. package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
  119. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
  120. package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
  121. package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
  122. package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
  123. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
  124. package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
  125. package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
  126. package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
  127. package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
  128. package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
  129. package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
  130. package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
  131. package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
  132. package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
  133. package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
  134. package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
  135. package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
  136. package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
  137. package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
  138. package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
  139. package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
  140. package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
  141. package/skills/ui-design/scripts/assemble_material.py +217 -0
  142. package/skills/ui-design/scripts/assemble_material_test.py +149 -0
  143. package/skills/ui-design/scripts/browser_check_ui_artifact.mjs +221 -0
  144. package/skills/ui-design/scripts/chart_sanity_check.py +261 -0
  145. package/skills/ui-design/scripts/chart_sanity_check_test.py +165 -0
  146. package/skills/ui-design/scripts/check_language_policy.py +351 -0
  147. package/skills/ui-design/scripts/check_ui_artifact.py +435 -0
  148. package/skills/ui-design/scripts/check_ui_artifact_pptx_test.py +251 -0
  149. package/skills/ui-design/scripts/deck_pages_check.py +158 -0
  150. package/skills/ui-design/scripts/deck_pages_check_test.py +134 -0
  151. package/skills/ui-design/scripts/deck_visual_style_check.py +767 -0
  152. package/skills/ui-design/scripts/deck_visual_style_check_test.py +713 -0
  153. package/skills/ui-design/scripts/design_budget_check.py +271 -0
  154. package/skills/ui-design/scripts/design_budget_check_test.py +183 -0
  155. package/skills/ui-design/scripts/design_repair_hints.py +162 -0
  156. package/skills/ui-design/scripts/design_repair_hints_test.py +54 -0
  157. package/skills/ui-design/scripts/design_style_check.py +397 -0
  158. package/skills/ui-design/scripts/design_style_check_test.py +233 -0
  159. package/skills/ui-design/scripts/draft_coverage_check.py +184 -0
  160. package/skills/ui-design/scripts/draft_coverage_check_test.py +131 -0
  161. package/skills/ui-design/scripts/export_pptx_from_html.mjs +2367 -0
  162. package/skills/ui-design/scripts/extract_source_assets.py +607 -0
  163. package/skills/ui-design/scripts/extract_source_assets_test.py +256 -0
  164. package/skills/ui-design/scripts/generated_image_review_collect.py +206 -0
  165. package/skills/ui-design/scripts/generated_image_review_collect_test.py +91 -0
  166. package/skills/ui-design/scripts/image_plan_lint.py +571 -0
  167. package/skills/ui-design/scripts/image_plan_lint_test.py +515 -0
  168. package/skills/ui-design/scripts/image_prompt_rewrite.py +713 -0
  169. package/skills/ui-design/scripts/image_prompt_rewrite_test.py +966 -0
  170. package/skills/ui-design/scripts/layout_balance.py +881 -0
  171. package/skills/ui-design/scripts/layout_balance_test.py +927 -0
  172. package/skills/ui-design/scripts/normalize_design_json.py +272 -0
  173. package/skills/ui-design/scripts/normalize_design_json_test.py +119 -0
  174. package/skills/ui-design/scripts/plan_source_layout.py +1450 -0
  175. package/skills/ui-design/scripts/plan_source_layout_test.py +1136 -0
  176. package/skills/ui-design/scripts/resolve_source_input.py +270 -0
  177. package/skills/ui-design/scripts/resolve_source_input_test.py +98 -0
  178. package/skills/ui-design/scripts/scaffold_ui_artifact.py +377 -0
  179. package/skills/ui-design/scripts/source_usage_check.py +581 -0
  180. package/skills/ui-design/scripts/source_usage_check_test.py +427 -0
  181. package/skills/ui-design/scripts/text_readability_pixel.py +340 -0
  182. package/skills/ui-design/scripts/text_readability_pixel_test.py +219 -0
  183. package/skills/ui-design/scripts/visual_quality_gate.py +301 -0
  184. package/skills/ui-design/scripts/visual_quality_gate_test.py +233 -0
  185. package/skills/ui-design/tests/e2e/prompts/deck.md +19 -0
  186. package/skills/ui-design/tests/e2e/prompts/webpage.md +17 -0
  187. package/skills/ui-design/tests/e2e/render_check.mjs +101 -0
  188. package/skills/ui-design/tests/e2e/rubric.json +54 -0
  189. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/browser-check.json +49 -0
  190. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/language-check.txt +12 -0
  191. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/checks/static-check.txt +15 -0
  192. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/outputs/index.html +837 -0
  193. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/prompt.md +12 -0
  194. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/review.md +21 -0
  195. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/screenshots/desktop.png +0 -0
  196. package/skills/ui-design/tests/e2e/runs/aegis-vector-preview-1/screenshots/mobile.png +0 -0
  197. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/outputs/homepage.html +373 -0
  198. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/outputs/platform.html +378 -0
  199. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/prompt.md +13 -0
  200. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/review.md +26 -0
  201. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/browser-check.json +49 -0
  202. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/desktop.png +0 -0
  203. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/homepage/mobile.png +0 -0
  204. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/browser-check.json +49 -0
  205. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/desktop.png +0 -0
  206. package/skills/ui-design/tests/e2e/runs/amber-prism-screenshot-check-1/screenshots/platform/mobile.png +0 -0
  207. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/checks/static-check.txt +2 -0
  208. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/outputs/index.html +656 -0
  209. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/prompt.md +12 -0
  210. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-1/render_check.mjs +67 -0
  211. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/checks/static-check.txt +2 -0
  212. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/outputs/index.html +587 -0
  213. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/prompt.md +12 -0
  214. package/skills/ui-design/tests/e2e/runs/aqua-glass-iteration-2/review.md +36 -0
  215. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/browser-check.json +49 -0
  216. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/language-check.txt +8 -0
  217. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/checks/static-check.txt +16 -0
  218. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/outputs/index.html +739 -0
  219. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/prompt.md +11 -0
  220. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/review.md +22 -0
  221. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/screenshots/desktop.png +0 -0
  222. package/skills/ui-design/tests/e2e/runs/aqua-glass-volcano-refresh-1/screenshots/mobile.png +0 -0
  223. package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/checks/browser-check.json +52 -0
  224. package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/outputs/index.html +641 -0
  225. package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/screenshots/desktop.png +0 -0
  226. package/skills/ui-design/tests/e2e/runs/comfort-vision-preview-1/screenshots/mobile.png +0 -0
  227. package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/outputs/index.html +467 -0
  228. package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/browser-check.json +49 -0
  229. package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/desktop.png +0 -0
  230. package/skills/ui-design/tests/e2e/runs/ember-prism-red-preview-1/screenshots/mobile.png +0 -0
  231. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/outputs/homepage.html +373 -0
  232. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/outputs/platform.html +378 -0
  233. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/prompt.md +13 -0
  234. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/review.md +26 -0
  235. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/browser-check.json +49 -0
  236. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/desktop.png +0 -0
  237. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/homepage/mobile.png +0 -0
  238. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/browser-check.json +49 -0
  239. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/desktop.png +0 -0
  240. package/skills/ui-design/tests/e2e/runs/ember-prism-screenshot-check-1/screenshots/platform/mobile.png +0 -0
  241. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/browser-check.json +49 -0
  242. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/language-check.txt +4 -0
  243. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/checks/static-check.txt +2 -0
  244. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/execution_notes.md +10 -0
  245. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/outputs/index.html +587 -0
  246. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/prompt.md +14 -0
  247. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/review.md +13 -0
  248. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/screenshots/desktop.png +0 -0
  249. package/skills/ui-design/tests/e2e/runs/empty-agent-protocol-check/screenshots/mobile.png +0 -0
  250. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/checks/browser-check.json +24 -0
  251. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/checks/static-check.txt +2 -0
  252. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/execution_notes.md +21 -0
  253. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/outputs/deck.html +451 -0
  254. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/screenshots/slide-01.png +0 -0
  255. package/skills/ui-design/tests/e2e/runs/iteration-1/deck/screenshots/slide-02.png +0 -0
  256. package/skills/ui-design/tests/e2e/runs/iteration-1/review.md +79 -0
  257. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/checks/browser-check.json +26 -0
  258. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/checks/static-check.txt +2 -0
  259. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/execution_notes.md +20 -0
  260. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/outputs/index.html +534 -0
  261. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/screenshots/desktop.png +0 -0
  262. package/skills/ui-design/tests/e2e/runs/iteration-1/webpage/screenshots/mobile.png +0 -0
  263. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/browser-check.json +64 -0
  264. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/language-check.txt +7 -0
  265. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/quick-validate.txt +1 -0
  266. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/static-console.txt +2 -0
  267. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/checks/static-homepage.txt +2 -0
  268. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/outputs/console.html +600 -0
  269. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/outputs/homepage.html +556 -0
  270. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/prompt.md +29 -0
  271. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/review.md +57 -0
  272. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/console-desktop.png +0 -0
  273. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/console-mobile.png +0 -0
  274. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/homepage-desktop.png +0 -0
  275. package/skills/ui-design/tests/e2e/runs/nebula-console-iteration-1/screenshots/homepage-mobile.png +0 -0
  276. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/browser-check.json +33 -0
  277. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/language-check.txt +6 -0
  278. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/quick-validate.txt +1 -0
  279. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/checks/static-check.txt +2 -0
  280. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/outputs/index.html +682 -0
  281. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/prompt.md +13 -0
  282. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/review.md +59 -0
  283. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/screenshots/desktop.png +0 -0
  284. package/skills/ui-design/tests/e2e/runs/obsidian-optics-iteration-1/screenshots/mobile.png +0 -0
  285. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/outputs/page-01.html +466 -0
  286. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/outputs/page-02.html +433 -0
  287. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/prompt.md +13 -0
  288. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/browser-check.json +49 -0
  289. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/desktop.png +0 -0
  290. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-01/mobile.png +0 -0
  291. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/browser-check.json +49 -0
  292. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/desktop.png +0 -0
  293. package/skills/ui-design/tests/e2e/runs/obsidian-xui-screenshot-check-1/screenshots/page-02/mobile.png +0 -0
  294. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/browser-check.json +49 -0
  295. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/language-check.txt +3 -0
  296. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/checks/static-check.txt +2 -0
  297. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/execution_notes.md +24 -0
  298. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/outputs/index.html +723 -0
  299. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/prompt.md +15 -0
  300. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/review.md +26 -0
  301. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/screenshots/desktop.png +0 -0
  302. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-1/screenshots/mobile.png +0 -0
  303. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/browser-dark.json +49 -0
  304. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/browser-light.json +49 -0
  305. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/language-check.txt +11 -0
  306. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/static-dark.txt +2 -0
  307. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/checks/static-light.txt +3 -0
  308. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/execution_notes.md +23 -0
  309. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/outputs/dark.html +392 -0
  310. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/outputs/light.html +476 -0
  311. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/prompt.md +23 -0
  312. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/review.md +41 -0
  313. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/dark/desktop.png +0 -0
  314. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/dark/mobile.png +0 -0
  315. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/light/desktop.png +0 -0
  316. package/skills/ui-design/tests/e2e/runs/precision-horizon-iteration-2/screenshots/light/mobile.png +0 -0
  317. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/browser-check.json +54 -0
  318. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/language-check.txt +5 -0
  319. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/quick-validate.txt +1 -0
  320. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/checks/static-check.txt +2 -0
  321. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/outputs/index.html +765 -0
  322. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/prompt.md +15 -0
  323. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/review.md +59 -0
  324. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/screenshots/desktop.png +0 -0
  325. package/skills/ui-design/tests/e2e/runs/solar-relay-iteration-1/screenshots/mobile.png +0 -0
  326. package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/outputs/index.html +508 -0
  327. package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/browser-check.json +49 -0
  328. package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/desktop.png +0 -0
  329. package/skills/ui-design/tests/e2e/runs/verdant-grid-preview-1/screenshots/mobile.png +0 -0
  330. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/browser-check.json +54 -0
  331. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/language-check.txt +6 -0
  332. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/quick-validate.txt +1 -0
  333. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/checks/static-check.txt +2 -0
  334. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/outputs/index.html +788 -0
  335. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/prompt.md +14 -0
  336. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/review.md +60 -0
  337. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/screenshots/desktop.png +0 -0
  338. package/skills/ui-design/tests/e2e/runs/violet-meridian-iteration-1/screenshots/mobile.png +0 -0
  339. package/skills/video-compose/SKILL.md +8 -1
  340. package/skills/web-crawler/SKILL.md +70 -0
  341. package/skills/web-crawler/scripts/crawl.mjs +538 -0
  342. package/skills/web-crawler/scripts/crawl.test.mjs +204 -0
  343. package/skills/xlsx/SKILL.md +12 -0
  344. package/skills/xlsx/scripts/opc_check.py +253 -0
  345. package/src/advisorState.js +22 -0
  346. package/src/askBridge.js +97 -3
  347. package/src/bootstrap/workingDir.js +12 -1
  348. package/src/cli/args.js +17 -1
  349. package/src/cli/configMenu.js +236 -0
  350. package/src/cli/configWizard.js +7 -5
  351. package/src/cli/print.js +37 -4
  352. package/src/cli/streamJson.js +77 -24
  353. package/src/cli/wizards/advisorWizard.js +147 -0
  354. package/src/cli/wizards/fieldForm.js +149 -0
  355. package/src/cli/wizards/imageWizard.js +60 -0
  356. package/src/cli/wizards/openRouterWizard.js +23 -0
  357. package/src/cli/wizards/providerPresets.js +95 -0
  358. package/src/cli/wizards/providerWizard.js +219 -0
  359. package/src/cli/wizards/searchWizard.js +23 -0
  360. package/src/cli/wizards/ttsWizard.js +34 -0
  361. package/src/config/configFile.js +441 -83
  362. package/src/config/configService.js +446 -0
  363. package/src/config.js +24 -64
  364. package/src/context/agentHome.js +9 -0
  365. package/src/context/archive.js +7 -2
  366. package/src/context/compact.js +8 -5
  367. package/src/context/contextLock.js +81 -0
  368. package/src/context/persistContext.js +30 -11
  369. package/src/context/reactiveCompact.js +4 -2
  370. package/src/context/recentDirs.js +21 -61
  371. package/src/context/sessionPath.js +97 -23
  372. package/src/context/sessionRegistry.js +303 -24
  373. package/src/context/tokenCounter.js +18 -0
  374. package/src/context/workspaceIndex.js +731 -0
  375. package/src/infra/verification.js +28 -15
  376. package/src/llm/client.js +394 -159
  377. package/src/llm/providers/anthropicFormat.js +241 -0
  378. package/src/llm/providers/openaiFormat.js +190 -0
  379. package/src/loop.js +219 -32
  380. package/src/main.js +61 -11
  381. package/src/messageQueue.js +97 -0
  382. package/src/multimodal.js +203 -0
  383. package/src/plugin-sdk.js +15 -0
  384. package/src/plugins/commandRouter.js +3 -0
  385. package/src/plugins/hookEngine.js +5 -1
  386. package/src/plugins/pluginLifecycle.js +28 -0
  387. package/src/plugins/pluginLoader.js +2 -1
  388. package/src/plugins/pluginRunner.js +49 -21
  389. package/src/plugins/transcript.js +4 -3
  390. package/src/prompts/pluginList.js +5 -5
  391. package/src/prompts/projectInstructions.js +3 -3
  392. package/src/prompts/promptAssembly.js +133 -144
  393. package/src/prompts/skillList.js +12 -22
  394. package/src/prompts/system.js +0 -1
  395. package/src/session/runAgentTurn.js +70 -0
  396. package/src/session/runTurn.js +41 -6
  397. package/src/toolGate.js +17 -0
  398. package/src/tools/advisor/advisor.js +379 -0
  399. package/src/tools/agent/agent.js +555 -0
  400. package/src/tools/agent/agentTypes.js +59 -0
  401. package/src/tools/agent/coordinator.js +93 -0
  402. package/src/tools/agent/worktree.js +270 -0
  403. package/src/tools/ask/ask.js +7 -2
  404. package/src/tools/bash/bash.js +112 -18
  405. package/src/tools/download/download.js +144 -0
  406. package/src/tools/edit/edit.js +1 -0
  407. package/src/tools/edit/multi-edit.js +1 -0
  408. package/src/tools/genimage/genimage.js +242 -0
  409. package/src/tools/genspeech/genspeech.js +67 -0
  410. package/src/tools/glob/glob.js +1 -0
  411. package/src/tools/grep/grep.js +3 -0
  412. package/src/tools/grep/rgPath.js +2 -0
  413. package/src/tools/index.js +25 -2
  414. package/src/tools/read/read.js +1 -0
  415. package/src/tools/shared/killTree.js +52 -0
  416. package/src/tools/toolProgressBridge.js +48 -0
  417. package/src/tools/webbrowser/agentBrowserPath.js +258 -0
  418. package/src/tools/webbrowser/browser.js +59 -42
  419. package/src/tools/webbrowser/browserControl.js +118 -0
  420. package/src/tools/webbrowser/browserDaemon.js +97 -0
  421. package/src/tools/webbrowser/browserService.js +27 -0
  422. package/src/tools/webbrowser/browserStream.js +119 -0
  423. package/src/tools/webbrowser/webbrowser.js +699 -130
  424. package/src/tools/webfetch/webfetch.js +1 -0
  425. package/src/tools/websearch/websearch.js +134 -51
  426. package/src/tools/write/write.js +1 -0
  427. package/src/ui/App.js +249 -22
  428. package/src/ui/AskQuestion.js +29 -10
  429. package/src/ui/InputBox.js +104 -12
  430. package/src/ui/LiveArea.js +112 -19
  431. package/src/ui/MessageList.js +100 -14
  432. package/src/ui/ModelPicker.js +56 -0
  433. package/src/ui/QueuedMessagesBanner.js +14 -0
  434. package/src/ui/Root.js +18 -10
  435. package/src/ui/SessionPicker.js +102 -0
  436. package/src/ui/StatusLine.js +13 -4
  437. package/src/ui/WorkspacePicker.js +55 -0
  438. package/src/ui/figures.js +44 -0
  439. package/src/ui/hooks/askSlot.js +82 -0
  440. package/src/ui/hooks/useChat.js +358 -64
  441. package/src/ui/hooks/usePasteHandler.js +11 -1
  442. package/src/ui/hooks/useTextBuffer.js +1 -3
  443. package/src/ui/liveViewport.js +5 -1
  444. package/src/ui/markdown.js +206 -0
  445. package/src/ui/textBuffer.js +0 -7
  446. package/src/ui/theme.js +32 -0
  447. package/src/utils/debugLog.js +0 -4
  448. package/src/utils/resourcePaths.js +2 -2
  449. package/src/utils/stripThink.js +50 -0
  450. package/src/web/browserBridge.js +447 -0
  451. package/src/web/protocol.js +19 -0
  452. package/workflows/adaptive-research.yaml +13 -5
  453. package/workflows/book-review-short.yaml +36 -10
  454. package/workflows/e2e-write-greet.yaml +6 -2
  455. package/workflows/illustrate.yaml +227 -0
  456. package/workflows/plan.yaml +460 -179
  457. package/workflows/ppt.yaml +1659 -0
  458. package/workflows/ralph-loop.yaml +199 -0
  459. package/workflows/schema.json +81 -23
  460. package/workflows/webppt.yaml +496 -0
  461. package/workflows/word.yaml +710 -0
  462. package/workflows/youtube-shorts.yaml +46 -15
  463. package/MINIMAL-TRACE.md +0 -77
  464. package/plugins/HOW-TO-WRITE-A-PLUGIN.md +0 -186
  465. package/plugins/ralph-wiggum/.claude-plugin/plugin.json +0 -9
  466. package/plugins/ralph-wiggum/README.md +0 -197
  467. package/plugins/ralph-wiggum/commands/cancel-ralph.md +0 -18
  468. package/plugins/ralph-wiggum/commands/help.md +0 -137
  469. package/plugins/ralph-wiggum/commands/ralph-loop.md +0 -85
  470. package/plugins/ralph-wiggum/hooks/hooks.json +0 -15
  471. package/plugins/ralph-wiggum/hooks/stop-hook.sh +0 -191
  472. package/plugins/ralph-wiggum/plugin.js +0 -280
  473. package/plugins/ralph-wiggum/src/goalState.js +0 -258
  474. package/plugins/ralph-wiggum/src/sentinels.js +0 -76
  475. package/plugins/ralph-wiggum/src/stopHookRunner.js +0 -104
  476. package/plugins/ralph-wiggum/src/verificationGate.js +0 -202
  477. package/plugins/workflow-runner/src/miniReAct.js +0 -223
  478. package/plugins/workflow-runner/src/voteHelpers.js +0 -110
  479. package/skills/config/SKILL.md +0 -123
  480. package/skills/frontend-design/LICENSE.txt +0 -177
  481. package/skills/frontend-design/SKILL.md +0 -42
  482. package/src/ui/ProgressPanel.js +0 -54
  483. package/src/ui/StreamingBlock.js +0 -11
  484. package/src/ui/ToolStatus.js +0 -11
@@ -0,0 +1,555 @@
1
+ /**
2
+ * ============================================================
3
+ * src/tools/agent/agent.ts —— Agent 工具(fork 子 agent / 多 agent 并行)
4
+ * ------------------------------------------------------------
5
+ * 借鉴 Claude Code 官方 AgentTool/ForkAgent 的核心思想,按 minimal-agent
6
+ * 内核架构做同步等效实现:
7
+ * - 官方 fork = 「隔离 context 嵌套跑同一主循环 + 摘要回传(完整历史不进
8
+ * 父上下文)」。我们不需要它的后台任务队列/AsyncLocalStorage 身份追踪
9
+ * (那是为 Ink UI 后台任务服务的)——本工具同步 await 一个嵌套 runQuery,
10
+ * 声明 isConcurrencySafe:true 后,模型在同一轮发出 N 个 Agent 调用时,
11
+ * loop.ts 现成的并行 worker 队列自动把它们并发执行。这就是并行的全部来源。
12
+ * - 同轮混入任一非并发安全工具(如 Edit)会整轮退化串行——这是想要的安全
13
+ * 语义(写操作与并行 fork 不该交错)。
14
+ *
15
+ * 已知限制(如实声明):
16
+ * - 子 agent 的 LoopEvent 不外泄:-p / stream-json 宿主只看到本工具的一对
17
+ * tool_start/tool_end;步内进度通过 ToolCallContext.reportProgress 回到宿主。
18
+ * - llm/client.ts 的网络退避档位是进程级共享:N 个并行分身同时失败会交错
19
+ * 抬档、任一成功清零(同 provider 拥塞场景下方向正确,本轮不隔离)。
20
+ *
21
+ * ⚠️ 循环依赖纪律:本文件与 loop.ts / tools/index.ts 构成模块环
22
+ * (tools/index → agent → loop → tools/index)。环内模块的**值**一律走下面的
23
+ * loadCore() 动态 import 懒加载——静态 import 防不住「agent.ts 自身作为环入口」
24
+ * 的方向(测试/消费者直接 import 本文件时,tools/index 的 ALL_TOOLS 数组求值
25
+ * 早于本文件完成初始化,撞 TDZ ReferenceError,已真实发生)。type-only import
26
+ * 编译期擦除,不受此限。loop.ts 侧的 TOOLS_SCHEMA_TOKENS 懒化是同一纪律的配合。
27
+ * ============================================================
28
+ */
29
+ import { randomUUID } from 'node:crypto';
30
+ import { withAskSource } from '../../askBridge.js';
31
+ import { isAbsolute, relative, resolve, sep } from 'node:path';
32
+ import { z } from 'zod';
33
+ import { getWorkingDir, withWorkingDir } from '../../bootstrap/workingDir.js';
34
+ import { createSessionState } from '../../session/sessionState.js';
35
+ import { assembleBasePrompt } from '../../prompts/promptAssembly.js';
36
+ import { stripThinkBlocks } from '../../utils/stripThink.js';
37
+ import { toToolParameters } from '../../utils/zodToJson.js';
38
+ import { DEFAULT_MAX_RESULT_SIZE_CHARS } from '../types.js';
39
+ import { SUBAGENT_EXCLUDED_TOOLS, resolveAgentType } from './agentTypes.js';
40
+ import { acquireSubagentLease, normalizeWriteScopes } from './coordinator.js';
41
+ import { commitWorktreeChanges, createAgentWorktree, hasWorktreeChanges, removeAgentWorktree, worktreeChangedFiles, worktreeDiffStat, } from './worktree.js';
42
+ let corePromise = null;
43
+ /** 首次调用时才真正加载 loop/tools——此刻模块图早已初始化完毕,环安全。 */
44
+ function loadCore() {
45
+ if (!corePromise) {
46
+ corePromise = Promise.all([import('../../loop.js'), import('../index.js')]).then(([loop, tools]) => ({
47
+ runQuery: loop.runQuery,
48
+ ALL_TOOLS: tools.ALL_TOOLS,
49
+ executeTool: tools.executeTool,
50
+ }));
51
+ }
52
+ return corePromise;
53
+ }
54
+ // ---------------- 1. Zod 输入 schema ----------------
55
+ const inputSchema = z.object({
56
+ description: z
57
+ .string()
58
+ .min(1)
59
+ .max(60, 'description 太长(>60 字符)——它是进度显示用的短标签')
60
+ .describe('子任务短标签(3-8 个词,进度显示用,如「检索路由实现」)'),
61
+ prompt: z
62
+ .string()
63
+ .min(1)
64
+ .describe('完整自包含的任务书。子 agent 是无状态的、看不到当前对话——' +
65
+ '所有背景、涉及的文件路径、期望的产出格式都必须写进来'),
66
+ agent_type: z
67
+ .enum(['explore', 'general'])
68
+ .optional()
69
+ .describe('explore=只读收集调研(默认,可并行放心用);general=可读写执行'),
70
+ isolation: z
71
+ .enum(['none', 'worktree'])
72
+ .optional()
73
+ .describe('worktree=在独立 git worktree 分支中执行(仅 general 生效;并行写同一批文件时用,' +
74
+ '完成后主 agent 审阅并合并分支)'),
75
+ write_scopes: z
76
+ .array(z.string().min(1))
77
+ .max(32)
78
+ .optional()
79
+ .describe('general 预计修改的工作目录相对路径。范围互不重叠时可并行;缺省时按整个工作目录串行。explore 不需要。'),
80
+ });
81
+ const parameters = toToolParameters(inputSchema);
82
+ // ---------------- 2. Description(给 LLM 看的工具说明) ----------------
83
+ // 借鉴官方 AgentTool prompt 文案(任务书自包含 / 同轮并行 / 何时不用)。
84
+ const description = `- Launches a stateless sub-agent with a fresh, isolated context to execute one self-contained subtask; returns only its final report text (its full working history never enters this conversation).
85
+ - The sub-agent CANNOT see this conversation. The \`prompt\` must be fully self-contained: background, exact file paths, what to look for / do, and the expected output format.
86
+ - **To parallelize, emit multiple Agent calls in ONE assistant message** — they run concurrently. This is the main value of this tool.
87
+ - Use for: exploring/researching several independent areas of a codebase at once, parallel information gathering from multiple sources, independent analyses that will be synthesized afterwards, and (with agent_type:'general') genuinely parallelizable write/execute work.
88
+ - Do NOT use for: single targeted lookups that one or two direct tool calls would answer (a fork starts cold and re-derives context — slower and costlier), or strictly sequential work. Only general execution agents may ask the user, and only when genuinely blocked.
89
+ - agent_type: 'explore' (default) = strictly read-only research; 'general' = read-write execution. For direct writes, declare relative write_scopes; disjoint scopes may run concurrently, overlapping or omitted scopes are serialized.
90
+ - isolation:'worktree' (general only): the sub-agent sees the repo's last COMMITTED state (uncommitted changes are invisible — commit first if it needs them). On completion its changes are auto-committed to a temp branch and the report tail tells you the branch name; review the diff, merge (e.g. \`git merge --squash <branch>\`), then clean up.
91
+ - After sub-agents return you MUST synthesize: cross-check contradictions between reports, integrate into one conclusion — never just forward raw reports. A failed/timed-out fork is not a blocker: proceed with what you have and state the gap.`;
92
+ // ---------------- 3. 子 agent 系统提示词(memoize,提示词缓存友好) ----------------
93
+ /** 通用附加段:所有 agent_type 共享(拼在 assembleBasePrompt 之后)。 */
94
+ const SUBAGENT_COMMON_APPENDIX = `# 你是子 agent(fork 分身)
95
+ 你是主 agent 派生出的子 agent,正在执行一个自包含的子任务:
96
+ - 你看不到主对话;任务书(用户消息)就是你的全部输入。
97
+ - explore 子任务不能向用户提问;general 仅在缺少关键输入或高风险取舍时使用 AskUserQuestion,最多两次。
98
+ - 你的**最后一条回复就是唯一回传主 agent 的报告**,必须自包含:结论 + 关键证据(文件路径/行号)+ 未尽事项。
99
+ 不要输出「我完成了」这类无信息量收尾,也不要在报告里向主 agent 提问——它不会回复你。`;
100
+ /**
101
+ * 提示词缓存友好:同回合 N 个同类型并行分身必须拿到**逐字节相同**的 system
102
+ * 消息,OpenAI 兼容 provider 的自动前缀缓存才吃得到(Layer 1 含日期、Layer 3
103
+ * 技能目录实时扫描——不 memoize 的话并行的多次求值可能产生字节差异,打散前缀)。
104
+ * 任务差异只落在末尾的 user 消息(任务书)——这是官方 fork「占位符字节一致」
105
+ * 技巧在自动前缀缓存下的原则等价物。
106
+ */
107
+ const PROMPT_CACHE_TTL_MS = 60_000;
108
+ const promptCache = new Map();
109
+ async function buildSubSystemPrompt(cwd, def, allTools) {
110
+ const key = `${cwd}::${def.type}`;
111
+ const hit = promptCache.get(key);
112
+ if (hit && Date.now() - hit.at < PROMPT_CACHE_TTL_MS)
113
+ return hit.value;
114
+ const allowedNames = def.resolveAllowedTools(allTools.map((t) => t.name));
115
+ const subTools = allTools.filter((t) => allowedNames.includes(t.name));
116
+ const base = await assembleBasePrompt({
117
+ cwd,
118
+ tools: subTools,
119
+ includeProjectInstructions: true, // 子 agent 在同一仓库干活,项目约定必须继承
120
+ includePlugins: false, // 插件是宿主命令面,子 agent 不该被引去激活插件
121
+ });
122
+ const value = [base, SUBAGENT_COMMON_APPENDIX, def.promptAppendix].join('\n\n');
123
+ promptCache.set(key, { value, at: Date.now() });
124
+ return value;
125
+ }
126
+ function positiveInt(value) {
127
+ const n = Number.parseInt(value ?? '', 10);
128
+ return Number.isFinite(n) && n > 0 ? n : undefined;
129
+ }
130
+ /** worktree 收尾:无改动清理;有改动代提交 + 生成给主 agent 的收口指引尾巴。 */
131
+ async function finalizeWorktree(wt, label) {
132
+ const changed = await hasWorktreeChanges(wt.path, wt.baseSha);
133
+ if (!changed) {
134
+ await removeAgentWorktree(wt.path, wt.branch, wt.gitRoot);
135
+ return '';
136
+ }
137
+ const commit = await commitWorktreeChanges(wt.path, `agent fork: ${label}`);
138
+ const stat = await worktreeDiffStat(wt.path, wt.baseSha);
139
+ return [
140
+ '',
141
+ '———',
142
+ '⚠️ 子任务在独立 worktree 分支产生了改动(尚未合并回主工作区):',
143
+ `- 分支:${wt.branch}`,
144
+ `- 隔离任务:${wt.branch.replace(/^agent\//, '')}`,
145
+ commit.ok ? '' : `- ⚠️ 自动提交失败(${commit.error}),改动仍留在 worktree 工作区未入分支`,
146
+ stat ? `- 改动摘要:\n${stat}` : '',
147
+ '主 agent 收口步骤:',
148
+ `1. 审阅改动:\`git diff ${wt.baseSha.slice(0, 12)} ${wt.branch}\`;`,
149
+ `2. 确认后在主工作区合并:\`git merge --squash ${wt.branch}\` 后提交(或按需 cherry-pick);`,
150
+ '3. 在 KakadeAI 子任务卡中应用或放弃该隔离变更。',
151
+ ]
152
+ .filter(Boolean)
153
+ .join('\n');
154
+ }
155
+ /**
156
+ * 真正的执行逻辑:在隔离的 history + 独立 sessionState 上嵌套跑一个完整
157
+ * runQuery 子循环,把最终报告文本作为 ToolResult 回传。
158
+ *
159
+ * 刻意**不走 runTurn/runAgentTurn**:它们会 acquireContextLock(非重入锁,
160
+ * 主 turn 全程持锁 → 同 sessionFile 必死锁)并 saveContext 落盘——子 agent
161
+ * 应该零磁盘足迹、用完即弃。
162
+ */
163
+ export async function runAgentTask(input, signal, ctx, deps = {}) {
164
+ const startedAt = Date.now();
165
+ // ---- 前置检查 ----
166
+ if (!ctx.provider) {
167
+ return {
168
+ ok: false,
169
+ error: '子任务功能不可用(内核未透传 provider),请自己直接执行该任务。',
170
+ };
171
+ }
172
+ if (ctx.agentCalls && ctx.agentCalls.used >= ctx.agentCalls.max) {
173
+ return {
174
+ ok: false,
175
+ error: `本回合子任务派生已达上限(${ctx.agentCalls.max} 次),剩余工作请自己直接完成。`,
176
+ };
177
+ }
178
+ if (ctx.agentCalls)
179
+ ctx.agentCalls.used++;
180
+ const { runQuery, ALL_TOOLS, executeTool } = await loadCore();
181
+ const def = resolveAgentType(input.agent_type);
182
+ // 轮数上限:AGENT_TOOL_MAX_TURNS 可统一覆盖两种类型(默认 explore 50 / general 100)。
183
+ const maxTurns = positiveInt(process.env.AGENT_TOOL_MAX_TURNS)
184
+ ?? (def.type === 'explore' ? ctx.subagentConfig?.exploreMaxTurns : ctx.subagentConfig?.generalMaxTurns)
185
+ ?? def.maxTurns;
186
+ // allowedTools 只裁「下发给模型的清单」;guardedExecute 是真正的硬防线(见下)。
187
+ const allowedTools = def.resolveAllowedTools(ALL_TOOLS.map((t) => t.name));
188
+ // ---- worktree 隔离(仅 general 显式要求时) ----
189
+ let wt = null;
190
+ const isolation = input.isolation ?? ctx.subagentConfig?.defaultWriteIsolation ?? 'none';
191
+ if (def.type === 'general' && isolation === 'worktree') {
192
+ const created = await createAgentWorktree(`fork-${randomUUID().slice(0, 8)}`);
193
+ if (!created.ok) {
194
+ return {
195
+ ok: false,
196
+ error: `worktree 隔离创建失败:${created.error}。可改用 isolation:'none'(确保各子任务写不相交的文件)或自己串行执行。`,
197
+ };
198
+ }
199
+ wt = created;
200
+ }
201
+ const cwd = wt?.path ?? getWorkingDir();
202
+ let writeScopes;
203
+ try {
204
+ writeScopes = def.type === 'general'
205
+ ? await normalizeWriteScopes(cwd, wt ? ['.'] : input.write_scopes)
206
+ : [];
207
+ }
208
+ catch (error) {
209
+ if (wt)
210
+ await removeAgentWorktree(wt.path, wt.branch, wt.gitRoot);
211
+ return { ok: false, error: error.message };
212
+ }
213
+ const rootScope = await normalizeWriteScopes(cwd, undefined);
214
+ let lastPublishAt = 0;
215
+ const label = input.description;
216
+ const publish = (line, detail, force = false) => {
217
+ const now = Date.now();
218
+ if (!force && now - lastPublishAt < 200)
219
+ return;
220
+ lastPublishAt = now;
221
+ ctx.reportProgress?.(line, detail);
222
+ };
223
+ // ---- 子 history:一条 system(压缩按 role 定位,必须存在)+ runQuery 自己 push 任务书 ----
224
+ const history = [
225
+ { role: 'system', content: await buildSubSystemPrompt(cwd, def, ALL_TOOLS) },
226
+ ];
227
+ const historyLenBefore = history.length;
228
+ const maxConcurrent = positiveInt(process.env.AGENT_TOOL_MAX_CONCURRENT) ?? ctx.subagentConfig?.maxConcurrent ?? 3;
229
+ let releaseLease = null;
230
+ try {
231
+ releaseLease = await acquireSubagentLease(cwd, def.type === 'general' ? writeScopes : [`__read__/${randomUUID()}`], maxConcurrent, {
232
+ signal,
233
+ onStatus: (status) => {
234
+ if (status.phase === 'queued') {
235
+ publish(`排队中${status.queuePosition ? ` · 第 ${status.queuePosition} 位` : ''}`, {
236
+ kind: 'subagent',
237
+ phase: 'queued',
238
+ queuePosition: status.queuePosition,
239
+ activeCount: status.activeCount,
240
+ maxConcurrent: status.maxConcurrent,
241
+ }, true);
242
+ }
243
+ else {
244
+ publish('准备上下文', {
245
+ kind: 'subagent', phase: 'preparing', activeCount: status.activeCount, maxConcurrent: status.maxConcurrent,
246
+ }, true);
247
+ }
248
+ },
249
+ });
250
+ }
251
+ catch (error) {
252
+ if (error.name === 'AbortError')
253
+ return { ok: false, error: 'aborted' };
254
+ return { ok: false, error: `子任务「${label}」进入执行队列失败:${error.message}` };
255
+ }
256
+ // ---- 超时兜底(仿 Advisor 模式;默认 30 分钟——50/100 轮的真实审计/执行型
257
+ // 子任务 10 分钟跑不完,超时是兜底不是预期时长,env 可调低) ----
258
+ const timeoutMs = positiveInt(process.env.AGENT_TOOL_TIMEOUT_MS) ?? ctx.subagentConfig?.timeoutMs ?? 1_800_000;
259
+ const timeoutController = new AbortController();
260
+ const ownerCancelController = new AbortController();
261
+ let remainingTimeoutMs = timeoutMs;
262
+ let timerStartedAt = 0;
263
+ let timer = null;
264
+ const armTimeout = () => {
265
+ if (timer || timeoutController.signal.aborted)
266
+ return;
267
+ if (remainingTimeoutMs <= 0) {
268
+ timeoutController.abort(new Error('agent-task-timeout'));
269
+ return;
270
+ }
271
+ timerStartedAt = Date.now();
272
+ timer = setTimeout(() => {
273
+ timer = null;
274
+ remainingTimeoutMs = 0;
275
+ timeoutController.abort(new Error('agent-task-timeout'));
276
+ }, remainingTimeoutMs);
277
+ };
278
+ const pauseTimeout = () => {
279
+ if (!timer)
280
+ return;
281
+ clearTimeout(timer);
282
+ timer = null;
283
+ remainingTimeoutMs = Math.max(0, remainingTimeoutMs - (Date.now() - timerStartedAt));
284
+ };
285
+ const resumeTimeout = () => {
286
+ if (!ownerCancelController.signal.aborted)
287
+ armTimeout();
288
+ };
289
+ const stopTimeout = () => {
290
+ if (timer)
291
+ clearTimeout(timer);
292
+ timer = null;
293
+ };
294
+ armTimeout();
295
+ const combinedSignal = signal
296
+ ? AbortSignal.any([signal, timeoutController.signal, ownerCancelController.signal])
297
+ : AbortSignal.any([timeoutController.signal, ownerCancelController.signal]);
298
+ // ---- 递归硬防线:allowedTools 只影响模型可见清单,不拦 executeTool 的
299
+ // 全局调度口(loop.ts 注释明示);这里把排除工具在执行层直接拒绝。 ----
300
+ const baseExecute = deps.executeTool ?? executeTool;
301
+ const changedFiles = new Set();
302
+ let askCalls = 0;
303
+ const guardedExecute = async (name, args, s, c) => {
304
+ if (!allowedTools.includes(name) || SUBAGENT_EXCLUDED_TOOLS.includes(name)) {
305
+ return { ok: false, error: `子 agent 类型 ${def.type} 不允许调用 ${name}。` };
306
+ }
307
+ if (name === 'AskUserQuestion') {
308
+ askCalls++;
309
+ if (def.type !== 'general') {
310
+ return { ok: false, error: 'explore 子 agent 不能向用户提问,请在报告中记录假设和信息缺口。' };
311
+ }
312
+ if (askCalls > 2) {
313
+ return { ok: false, error: '当前子任务最多向用户提问两次,请基于已有回答完成任务或在报告中说明剩余缺口。' };
314
+ }
315
+ }
316
+ let parsed = {};
317
+ try {
318
+ parsed = JSON.parse(args);
319
+ }
320
+ catch { /* executeTool will report malformed input */ }
321
+ const rawPath = typeof parsed.file_path === 'string' ? parsed.file_path : typeof parsed.path === 'string' ? parsed.path : undefined;
322
+ if (def.type === 'general' && !wt && name === 'Bash' && writeScopes[0] !== rootScope[0]) {
323
+ return { ok: false, error: '声明了局部 write_scopes 时禁止 Bash:无法可靠证明命令只写入批准范围。请改用文件工具或使用整个工作目录范围。' };
324
+ }
325
+ if (def.type === 'general' && rawPath) {
326
+ if (isAbsolute(rawPath))
327
+ return { ok: false, error: `${name} 必须使用工作目录相对路径:${rawPath}` };
328
+ let physical;
329
+ try {
330
+ physical = (await normalizeWriteScopes(cwd, [rawPath]))[0];
331
+ }
332
+ catch {
333
+ return { ok: false, error: `${name} 路径越过工作目录或符号链接边界:${rawPath}` };
334
+ }
335
+ const inside = writeScopes.some((scope) => physical === scope || physical.startsWith(`${scope}${sep}`));
336
+ if (!inside)
337
+ return { ok: false, error: `${name} 路径超出 write_scopes:${rawPath}` };
338
+ if (['Edit', 'MultiEdit', 'Write', 'Download'].includes(name)) {
339
+ changedFiles.add(relative(cwd, resolve(cwd, rawPath)).split(sep).join('/'));
340
+ }
341
+ }
342
+ return baseExecute(name, args, s, c);
343
+ };
344
+ // ---- 事件消费:子 LoopEvent 一律不外泄,折算成统计 + 步内进度 ----
345
+ let turns = 0;
346
+ let toolOk = 0;
347
+ let toolFail = 0;
348
+ let textChars = 0;
349
+ let sawLlmError = false;
350
+ let llmErrorDetail = '';
351
+ let sawMaxTurns = false;
352
+ const consumeRun = async () => {
353
+ publish('正在分析任务', { kind: 'subagent', phase: 'analyzing' }, true);
354
+ const events = runQuery(input.prompt, {
355
+ provider: ctx.provider,
356
+ history,
357
+ maxTurns,
358
+ allowedTools,
359
+ signal: combinedSignal,
360
+ sessionState: createSessionState(), // 独立会话态,不与主循环/其他分身串扰
361
+ toolGate: ctx.toolGate, // 继承主循环审批策略(不给可写子 agent 开审批后门)
362
+ chat: deps.chat,
363
+ executeTool: guardedExecute,
364
+ // 受监督宿主(Desktop)下把「监督位」透传给子 agent:子 agent 的浏览器 challenge(验证码/登录)
365
+ // 仍可由用户在可见浏览器里处理,与主 agent 行为一致;非监督(CLI/-p/TUI)不传 → 子 agent 同样
366
+ // 非阻塞、绝不挂起。conversationKey 留空以维持子 agent「不认领独立标签页」的既有行为。
367
+ ...(ctx.browserRun?.supervised
368
+ ? { browserRun: { conversationKey: '', runId: randomUUID(), supervised: true } }
369
+ : {}),
370
+ // 不传 transientContext:任务书必须自包含,父回合的瞬时上下文不该隐式泄入
371
+ });
372
+ for await (const ev of events) {
373
+ switch (ev.type) {
374
+ case 'assistant_message':
375
+ turns++;
376
+ break;
377
+ case 'tool_start':
378
+ publish(`正在执行 · ${ev.argsFriendly ?? ev.toolName}`, {
379
+ kind: 'subagent',
380
+ phase: 'using_tool',
381
+ turn: Math.max(turns, 1),
382
+ toolName: ev.toolName,
383
+ toolDescription: ev.argsFriendly,
384
+ }, true);
385
+ break;
386
+ case 'tool_end':
387
+ if (ev.ok)
388
+ toolOk++;
389
+ else
390
+ toolFail++;
391
+ break;
392
+ case 'text':
393
+ textChars += ev.delta.length;
394
+ publish(`正在整理结论 · ${textChars} 字`, {
395
+ kind: 'subagent', phase: 'drafting', turn: Math.max(turns, 1), outputChars: textChars,
396
+ });
397
+ break;
398
+ case 'error':
399
+ // 中断(code:'aborted')不在这里判——结局映射直接查 signal 状态更可靠
400
+ // (中断在 loop 里有三种浮出形态:入口 error / AbortError catch / interrupted 事件)。
401
+ if (ev.code === 'llm_error') {
402
+ sawLlmError = true;
403
+ llmErrorDetail = ev.error;
404
+ }
405
+ else if (ev.code === 'max_turns')
406
+ sawMaxTurns = true;
407
+ // compact_failed 非致命:loop 自己会硬上,这里无需处理
408
+ break;
409
+ default:
410
+ break; // 其余事件(text 流/压缩/context_usage…)对父层不可见
411
+ }
412
+ }
413
+ };
414
+ try {
415
+ // worktree 模式下整个子执行在 ALS 作用域内以 worktree 为 cwd(相对路径
416
+ // 工具全部落进隔离目录);并行的多个分身各自的 ALS 作用域互不干扰。
417
+ const execute = () => withAskSource({ kind: 'subagent', parentToolCallId: ctx.toolCallId, description: label }, {
418
+ onWaitStart: () => {
419
+ pauseTimeout();
420
+ publish('等待你的回答', { kind: 'subagent', phase: 'waiting_owner' }, true);
421
+ },
422
+ onWaitEnd: () => {
423
+ resumeTimeout();
424
+ publish('已回答,继续分析', { kind: 'subagent', phase: 'analyzing' }, true);
425
+ },
426
+ onCancel: () => ownerCancelController.abort(new Error('owner-cancelled-subagent')),
427
+ }, consumeRun);
428
+ if (wt)
429
+ await withWorkingDir(wt.path, execute);
430
+ else
431
+ await execute();
432
+ }
433
+ catch (e) {
434
+ stopTimeout();
435
+ if (wt)
436
+ await finalizeWorktree(wt, label); // fail-closed:有改动会保留分支
437
+ if (ownerCancelController.signal.aborted) {
438
+ return { ok: false, error: `子任务「${label}」已由 Agent 所有者取消。` };
439
+ }
440
+ if (e.name === 'AbortError' || signal?.aborted) {
441
+ return { ok: false, error: 'aborted' };
442
+ }
443
+ return { ok: false, error: `子任务「${label}」执行异常:${e.message}` };
444
+ }
445
+ finally {
446
+ stopTimeout();
447
+ releaseLease?.();
448
+ }
449
+ // ---- 结局映射(直接查 signal 状态,不依赖事件旗标) ----
450
+ if (ownerCancelController.signal.aborted) {
451
+ if (wt)
452
+ await finalizeWorktree(wt, label);
453
+ return { ok: false, error: `子任务「${label}」已由 Agent 所有者取消。` };
454
+ }
455
+ // 用户中断:回传 loop 认识的字面量 'aborted'(它据此把整轮判为 interrupted)。
456
+ if (signal?.aborted) {
457
+ if (wt)
458
+ await finalizeWorktree(wt, label);
459
+ return { ok: false, error: 'aborted' };
460
+ }
461
+ // 超时(timeoutController 触发而非用户中断)
462
+ if (timeoutController.signal.aborted) {
463
+ const wtTail = wt ? await finalizeWorktree(wt, label) : '';
464
+ return {
465
+ ok: false,
466
+ error: `子任务「${label}」超过 ${Math.round(timeoutMs / 1000)}s 未完成,已终止。` +
467
+ `可缩小任务范围重试,或自己直接执行。${wtTail}`,
468
+ };
469
+ }
470
+ // ---- 产出提取:history 尾部倒扫最后一条非空 assistant 文本(剥 <think>) ----
471
+ let report = '';
472
+ for (let i = history.length - 1; i >= historyLenBefore; i--) {
473
+ const msg = history[i];
474
+ if (msg.role !== 'assistant' || !msg.content)
475
+ continue;
476
+ const cleaned = stripThinkBlocks(msg.content);
477
+ if (cleaned) {
478
+ report = cleaned;
479
+ break;
480
+ }
481
+ }
482
+ if (!report && sawLlmError) {
483
+ const wtTail = wt ? await finalizeWorktree(wt, label) : '';
484
+ return { ok: false, error: `子任务「${label}」LLM 调用失败:${llmErrorDetail}${wtTail}` };
485
+ }
486
+ if (!report && sawMaxTurns) {
487
+ const wtTail = wt ? await finalizeWorktree(wt, label) : '';
488
+ return {
489
+ ok: false,
490
+ error: `子任务「${label}」达到轮数上限(${maxTurns} 轮)被截断且没有产出。可把任务拆得更小重试。${wtTail}`,
491
+ };
492
+ }
493
+ if (!report) {
494
+ const wtTail = wt ? await finalizeWorktree(wt, label) : '';
495
+ return { ok: false, error: `子任务「${label}」没有产出任何文本。${wtTail}` };
496
+ }
497
+ if (sawMaxTurns) {
498
+ report = `⚠️ 子任务达到轮数上限(${maxTurns} 轮)被截断,以下是截断时的最后输出(可能不完整):\n\n${report}`;
499
+ }
500
+ // ---- 统计尾巴:主 agent 收口时评估报告可信度用 ----
501
+ const toolTotal = toolOk + toolFail;
502
+ report += `\n\n———\n(子任务「${label}」[${def.type}]:${turns} 轮 · ${toolTotal} 次工具调用${toolFail > 0 ? `,${toolFail} 次失败` : ''})`;
503
+ if (wt) {
504
+ for (const path of await worktreeChangedFiles(wt.path, wt.baseSha))
505
+ changedFiles.add(path);
506
+ report += await finalizeWorktree(wt, label);
507
+ }
508
+ if (report.length > DEFAULT_MAX_RESULT_SIZE_CHARS) {
509
+ report =
510
+ report.slice(0, DEFAULT_MAX_RESULT_SIZE_CHARS) +
511
+ `\n\n... (报告超过 ${DEFAULT_MAX_RESULT_SIZE_CHARS} 字符,已截断)`;
512
+ }
513
+ return {
514
+ ok: true,
515
+ content: report,
516
+ metadata: {
517
+ kind: 'agent',
518
+ agentType: def.type,
519
+ description: label,
520
+ isolation: wt ? 'worktree' : 'none',
521
+ turns,
522
+ toolCalls: toolTotal,
523
+ failedToolCalls: toolFail,
524
+ durationMs: Date.now() - startedAt,
525
+ changedFiles: [...changedFiles].sort(),
526
+ ...(wt && changedFiles.size > 0 ? {
527
+ worktree: {
528
+ id: wt.branch.replace(/^agent\//, ''),
529
+ branch: wt.branch,
530
+ baseSha: wt.baseSha,
531
+ status: 'ready',
532
+ },
533
+ } : {}),
534
+ },
535
+ };
536
+ }
537
+ // 无宿主上下文的裸 call:拿不到 provider,走统一的缺失错误路径。
538
+ async function call(input, signal) {
539
+ return runAgentTask(input, signal, {});
540
+ }
541
+ // ---------------- 5. 导出 ----------------
542
+ export const agentTool = {
543
+ name: 'Agent',
544
+ description,
545
+ inputSchema,
546
+ parameters,
547
+ // isReadOnly=false:general 分身可写盘。isConcurrencySafe=true 是并行的全部
548
+ // 来源——同轮多个 Agent 调用走 loop.ts 的并行 worker 队列。
549
+ isReadOnly: false,
550
+ isConcurrencySafe: true,
551
+ maxResultSizeChars: DEFAULT_MAX_RESULT_SIZE_CHARS,
552
+ interruptBehavior: () => 'block',
553
+ call,
554
+ callWithContext: runAgentTask,
555
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ============================================================
3
+ * src/tools/agent/agentTypes.ts —— 内置子 agent 类型(类型即数据)
4
+ * ------------------------------------------------------------
5
+ * 借鉴 Claude Code 官方 builtInAgents.ts 的「agent 定义 = 一段提示词附加段
6
+ * + 工具白名单 + 轮数上限」模式,按 minimal-agent 减法原则只保留两种:
7
+ *
8
+ * - explore(默认):严格只读收集调研,不包含任何会写盘的工具。
9
+ * - general:可读写执行(松权限裁决:写工具全放开)。并行时各子任务
10
+ * 必须写互不相交的文件,或经 isolation:'worktree' 走独立分支。
11
+ *
12
+ * 不做 plan 类型:explore + 任务书里一句「最后列出关键文件清单」即可表达
13
+ * (两次规则:真实需要出现两次再议)。
14
+ * ============================================================
15
+ */
16
+ /**
17
+ * 任何 agent_type 都排除的工具:
18
+ * - Agent:防递归 fork(子 agent 再 fork 子 agent,深度失控)。
19
+ * - Advisor:每个子 runQuery 有独立的 advisorCalls 预算({used:0,max:2}),
20
+ * N 个并行分身 = 最多 2N 次顾问调用,成本失控;两次规则后再议。
21
+ */
22
+ export const SUBAGENT_EXCLUDED_TOOLS = [
23
+ 'Agent',
24
+ 'Advisor',
25
+ ];
26
+ /** explore 白名单(显式列名,可预期):严格只读。 */
27
+ export const EXPLORE_ALLOWED_TOOLS = [
28
+ 'Read',
29
+ 'Glob',
30
+ 'Grep',
31
+ 'WebSearch',
32
+ 'WebFetch',
33
+ 'WebBrowser',
34
+ ];
35
+ /** 借鉴官方 EXPLORE_AGENT「READ-ONLY MODE」文案中文化。 */
36
+ const EXPLORE_APPENDIX = `# 本次子任务类型:只读调研(explore)
37
+ 这是一次只读探索任务:你没有 Edit/Write/Bash/Download 等写工具,严禁尝试创建、修改或删除项目文件。
38
+ 你的产出就是调研报告文本本身——
39
+ 把结论、关键证据(文件路径 + 行号)、以及没查到的缺口写清楚。`;
40
+ const GENERAL_APPENDIX = `# 本次子任务类型:读写执行(general)
41
+ 你可以读写文件、执行命令。写盘前照常先 Read(内核有覆盖保护)。
42
+ 只有在关键输入缺失、高风险取舍或无法安全继续时才使用 AskUserQuestion;能从代码、上下文或合理默认值判断时不要打断用户。每个子任务最多提问两次。
43
+ 只做任务书里交代的事,不要顺手扩大改动范围;改完在报告里列出动过的每个文件。`;
44
+ const EXPLORE_DEF = {
45
+ type: 'explore',
46
+ resolveAllowedTools: (all) => all.filter((n) => EXPLORE_ALLOWED_TOOLS.includes(n)),
47
+ maxTurns: 50,
48
+ promptAppendix: EXPLORE_APPENDIX,
49
+ };
50
+ const GENERAL_DEF = {
51
+ type: 'general',
52
+ resolveAllowedTools: (all) => all.filter((n) => !SUBAGENT_EXCLUDED_TOOLS.includes(n)),
53
+ maxTurns: 100,
54
+ promptAppendix: GENERAL_APPENDIX,
55
+ };
56
+ /** 未知/缺省一律回落 explore(最安全的默认:只读)。 */
57
+ export function resolveAgentType(name) {
58
+ return name === 'general' ? GENERAL_DEF : EXPLORE_DEF;
59
+ }