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
@@ -1,104 +0,0 @@
1
- /**
2
- * ============================================================
3
- * plugins/ralph-wiggum/src/stopHookRunner.ts
4
- * ------------------------------------------------------------
5
- * ralph-wiggum 私用的 stop-hook 执行器。读 hooks/hooks.json 里 Stop 事件
6
- * 的命令清单,stdin 传 transcript 文本,stdout 收 JSON 决策。
7
- *
8
- * 在 minimal-agent 里 stop-hook 是"咨询式"信号:
9
- * - 返回 block → driver 把 reason 注入下一轮 prompt
10
- * - pass / 错误 / Windows 缺 bash → 不影响循环继续
11
- *
12
- * 与框架级 hookEngine 的关系:hookEngine 服务于 UserPromptSubmit /
13
- * PreToolUse / PostToolUse 等框架事件;ralph 的 Stop 是插件领域内
14
- * 特有的循环-反馈机制,故而独立执行,不污染框架 hookTable。
15
- * ============================================================
16
- */
17
- import { readFile } from 'node:fs/promises';
18
- import { join } from 'node:path';
19
- import { spawn } from 'node:child_process';
20
- async function loadStopHookConfig(pluginRoot) {
21
- const hooksJsonPath = join(pluginRoot, 'hooks', 'hooks.json');
22
- try {
23
- const raw = await readFile(hooksJsonPath, 'utf8');
24
- const parsed = JSON.parse(raw);
25
- const stopEntries = parsed?.hooks?.Stop;
26
- if (!Array.isArray(stopEntries))
27
- return [];
28
- const commands = [];
29
- for (const entry of stopEntries) {
30
- const hooks = entry.hooks;
31
- if (Array.isArray(hooks)) {
32
- for (const h of hooks) {
33
- if (h.type === 'command' && h.command) {
34
- commands.push(h);
35
- }
36
- }
37
- }
38
- }
39
- return commands;
40
- }
41
- catch {
42
- return [];
43
- }
44
- }
45
- export async function executeStopHook(pluginRoot, transcriptText) {
46
- // Windows 上 bash 通常缺失,hook 链路降级为 pass(咨询式信号不影响循环)
47
- if (process.platform === 'win32') {
48
- return { decision: 'pass' };
49
- }
50
- const hookConfigs = await loadStopHookConfig(pluginRoot);
51
- for (const hookConfig of hookConfigs) {
52
- const result = await runSingleStopHook(hookConfig, pluginRoot, transcriptText);
53
- if (result.decision === 'block') {
54
- return result;
55
- }
56
- }
57
- return { decision: 'pass' };
58
- }
59
- function runSingleStopHook(hookConfig, pluginRoot, transcriptText) {
60
- const resolvedCommand = hookConfig.command.replaceAll('${CLAUDE_PLUGIN_ROOT}', pluginRoot);
61
- return new Promise((resolve) => {
62
- const child = spawn('bash', [resolvedCommand], {
63
- env: {
64
- ...process.env,
65
- CLAUDE_PLUGIN_ROOT: pluginRoot,
66
- },
67
- });
68
- let stdout = '';
69
- child.stdout.on('data', (data) => {
70
- stdout += data.toString();
71
- });
72
- child.on('error', () => {
73
- resolve({ decision: 'pass' });
74
- });
75
- child.on('close', (code) => {
76
- if (code !== 0) {
77
- resolve({ decision: 'pass' });
78
- return;
79
- }
80
- const trimmed = stdout.trim();
81
- if (!trimmed) {
82
- resolve({ decision: 'pass' });
83
- return;
84
- }
85
- try {
86
- const parsed = JSON.parse(trimmed);
87
- if (parsed.decision === 'block') {
88
- resolve({
89
- decision: 'block',
90
- reason: typeof parsed.reason === 'string' ? parsed.reason : undefined,
91
- systemMessage: typeof parsed.systemMessage === 'string' ? parsed.systemMessage : undefined,
92
- });
93
- return;
94
- }
95
- resolve({ decision: 'pass' });
96
- }
97
- catch {
98
- resolve({ decision: 'pass' });
99
- }
100
- });
101
- child.stdin.write(transcriptText);
102
- child.stdin.end();
103
- });
104
- }
@@ -1,202 +0,0 @@
1
- /**
2
- * ============================================================
3
- * src/plugins/verificationGate.ts —— ralph-loop 的"完成验证门"
4
- * ------------------------------------------------------------
5
- * Agent 输出 <promise>DONE</promise> 哨兵后,pluginRunner 跑这里的
6
- * checks。全部通过才真正退出循环;任一未通过则回 BUILD 继续干。
7
- *
8
- * 支持四种 check:
9
- * - shell:<cmd> 跨平台 spawn(Windows 走 cmd /c, 其余 bash -c)
10
- * - file_exists:<path> fs.existsSync
11
- * - file_contains:<file>:<re> 正则匹配文件内容
12
- * - test_count:<min> 跑 `bun test`,从 stdout 解析 "N pass"
13
- *
14
- * 工作目录隔离:所有相对路径以 getWorkingDir() 为锚,子进程 cwd 也用它,
15
- * 确保并行 session 不会互相串台。
16
- * ============================================================
17
- */
18
- import { existsSync, readFileSync } from 'node:fs';
19
- import { spawn } from 'node:child_process';
20
- function parseVerifyArg(arg) {
21
- const colonIdx = arg.indexOf(':');
22
- if (colonIdx < 0)
23
- return null;
24
- const type = arg.slice(0, colonIdx).trim().toLowerCase();
25
- const value = arg.slice(colonIdx + 1).trim();
26
- switch (type) {
27
- case 'shell':
28
- return { type: 'shell', command: value, timeout: 30_000 };
29
- case 'file_exists':
30
- return { type: 'file_exists', file: value };
31
- case 'file_contains': {
32
- const sep = value.indexOf(':');
33
- if (sep < 0)
34
- return null;
35
- return {
36
- type: 'file_contains',
37
- file: value.slice(0, sep),
38
- pattern: value.slice(sep + 1),
39
- };
40
- }
41
- case 'test_count': {
42
- const count = parseInt(value, 10);
43
- if (isNaN(count) || count < 0)
44
- return null;
45
- return { type: 'test_count', minCount: count };
46
- }
47
- default:
48
- return null;
49
- }
50
- }
51
- export function parseVerifyArgs(args) {
52
- const checks = [];
53
- const regex = /--verify\s+("[^"]*"|\S+)/gi;
54
- let match;
55
- while ((match = regex.exec(args)) !== null) {
56
- const raw = match[1].replace(/^"|"$/g, '');
57
- const check = parseVerifyArg(raw);
58
- if (check)
59
- checks.push(check);
60
- }
61
- return checks;
62
- }
63
- function runShell(command, timeout) {
64
- return new Promise((resolve) => {
65
- const isWin = process.platform === 'win32';
66
- // 不显式传 cwd —— 继承 process.cwd(),main.tsx 已 chdir 到 workingDir,
67
- // 而测试里直接用 process.cwd(),避免依赖 mock 的 getWorkingDir 造成串台
68
- const child = isWin
69
- ? spawn('cmd', ['/c', command], { timeout, env: process.env })
70
- : spawn('bash', ['-c', command], { timeout, env: process.env });
71
- let stdout = '';
72
- let stderr = '';
73
- child.stdout.on('data', (d) => {
74
- stdout += d.toString();
75
- });
76
- child.stderr.on('data', (d) => {
77
- stderr += d.toString();
78
- });
79
- child.on('error', () => {
80
- resolve({ exitCode: null, stdout, stderr, errored: true });
81
- });
82
- child.on('close', (code) => {
83
- resolve({ exitCode: code, stdout, stderr, errored: false });
84
- });
85
- });
86
- }
87
- export async function verifyShell(command, timeout) {
88
- const r = await runShell(command, timeout);
89
- if (r.errored) {
90
- return {
91
- check: { type: 'shell', command },
92
- passed: false,
93
- output: `执行失败`,
94
- };
95
- }
96
- return {
97
- check: { type: 'shell', command },
98
- passed: r.exitCode === 0,
99
- output: r.stdout.trim() || r.stderr.trim() || `exit code ${r.exitCode}`,
100
- };
101
- }
102
- export function verifyFileExists(file) {
103
- const exists = existsSync(file);
104
- return {
105
- check: { type: 'file_exists', file },
106
- passed: exists,
107
- output: exists ? '文件存在' : `文件不存在: ${file}`,
108
- };
109
- }
110
- export function verifyFileContains(file, pattern) {
111
- try {
112
- const content = readFileSync(file, 'utf8');
113
- const regex = new RegExp(pattern);
114
- const matched = regex.test(content);
115
- return {
116
- check: { type: 'file_contains', file, pattern },
117
- passed: matched,
118
- output: matched ? `文件包含 "${pattern}"` : `文件不包含 "${pattern}"`,
119
- };
120
- }
121
- catch {
122
- return {
123
- check: { type: 'file_contains', file, pattern },
124
- passed: false,
125
- output: `无法读取文件: ${file}`,
126
- };
127
- }
128
- }
129
- async function verifyTestCount(minCount) {
130
- const r = await runShell(`bun test`, 60_000);
131
- // bun test 把进度打在 stderr,最终统计也常在 stderr,所以合并解析
132
- const combined = `${r.stdout}\n${r.stderr}`;
133
- if (r.errored) {
134
- return {
135
- check: { type: 'test_count', minCount },
136
- passed: false,
137
- output: '无法执行 bun test',
138
- };
139
- }
140
- const matches = [...combined.matchAll(/(\d+)\s+pass/gi)];
141
- const count = matches.length > 0 ? parseInt(matches[matches.length - 1][1], 10) : 0;
142
- const passed = count >= minCount;
143
- return {
144
- check: { type: 'test_count', minCount },
145
- passed,
146
- output: `${count} pass (需要 >=${minCount})`,
147
- };
148
- }
149
- export async function runVerification(checks) {
150
- if (checks.length === 0) {
151
- return { passed: true, details: [], summary: '无验证项' };
152
- }
153
- const results = [];
154
- for (const check of checks) {
155
- let result;
156
- switch (check.type) {
157
- case 'shell':
158
- result = await verifyShell(check.command ?? '', check.timeout ?? 30_000);
159
- break;
160
- case 'file_exists':
161
- result = verifyFileExists(check.file ?? '');
162
- break;
163
- case 'file_contains':
164
- result = verifyFileContains(check.file ?? '', check.pattern ?? '');
165
- break;
166
- case 'test_count':
167
- result = await verifyTestCount(check.minCount ?? 0);
168
- break;
169
- default:
170
- result = {
171
- check,
172
- passed: false,
173
- output: `未知验证类型: ${check.type}`,
174
- };
175
- }
176
- results.push(result);
177
- }
178
- const allPassed = results.every((r) => r.passed);
179
- const failedNames = results.filter((r) => !r.passed).map((r) => formatCheckName(r.check));
180
- let summary;
181
- if (allPassed) {
182
- summary = `✅ 全部通过 (${results.length}/${results.length})`;
183
- }
184
- else {
185
- summary = `❌ 验证未通过: ${failedNames.join(', ')}`;
186
- }
187
- return { passed: allPassed, details: results, summary };
188
- }
189
- function formatCheckName(check) {
190
- switch (check.type) {
191
- case 'shell':
192
- return `shell(${(check.command ?? '').slice(0, 40)})`;
193
- case 'file_exists':
194
- return `exists(${check.file})`;
195
- case 'file_contains':
196
- return `contains(${check.file}:${check.pattern})`;
197
- case 'test_count':
198
- return `tests(>=${check.minCount})`;
199
- default:
200
- return check.type;
201
- }
202
- }
@@ -1,223 +0,0 @@
1
- /**
2
- * ============================================================
3
- * plugins/workflow-runner/src/miniReAct.ts —— 简化版 ReAct 子循环
4
- * ------------------------------------------------------------
5
- * 本循环只做最纯净的 ReAct:调 LLM → 执行 tool_call → 喂回 → 再调 → 直到模型
6
- * 不再调工具或达到 maxTurns。**有三个调用方**(都要「有界、白名单、不污染主
7
- * history、直接拿 StepResult」):
8
- * - execLlmStep 的 context_files 分支(llm.ts,maxTurns 默认 10)
9
- * - agent: 节点(stepExecutors/agent.ts,默认 12)
10
- * - onError:'recover' 恢复 agent(recovery.ts,默认 12)
11
- *
12
- * **流式**:本循环边跑边 yield UI 事件——text(答案)/ reasoning(思维链)/
13
- * tool_start/tool_end(工具)/ **stage_change(thinking→streaming→tool_executing,
14
- * 对齐 src/loop.ts::runQuery)**。stage_change 是 TUI LiveArea 显示的开关(idle 时
15
- * LiveArea 整块隐藏),没有它则上述内层事件在 TUI 上发了也看不见。output_schema
16
- * 模式下**仍切 stage、但不回显 text**(避免把 JSON 原文当答案刷屏,对齐 llm.ts)。
17
- *
18
- * 为什么不复用 src/loop.ts::runQuery?
19
- * - runQuery 依赖太重:history 持久化、自动压缩、反应式压缩自救、
20
- * microCompact、reasoning 累积、sessionState 注入、SIGINT 标记消息等
21
- * - workflow 子步骤是"短小内嵌",不需要这些工程化保障
22
- * - 独立实现可以精准控制:只用白名单工具、强 schema、重复调用 halt
23
- *
24
- * 关键决策:
25
- * 1. **每轮都传 responseFormat**(如果有 output_schema)。OpenAI 兼容
26
- * provider 对 tool_calls + json_schema 混用通常允许:tool_calls 走 function
27
- * 协议,最终 assistant 的 text 是 JSON。这样比"双轮探测"简单可靠。
28
- * 2. **重复工具调用检测**:同 name 同 args 出现 3 次直接 halt,避免模型卡死。
29
- * 3. **executeTool 自带 Zod 校验和错误包装**,本循环只需透传 tool_call_id 配对。
30
- * 4. **maxTurns 默认 10**(vs runQuery 的 50),workflow 子步骤天生该收敛快。
31
- * ============================================================
32
- */
33
- import { chat, executeTool, } from '../../../src/plugin-sdk.js';
34
- import { extractJsonPayload } from './jsonPayload.js';
35
- /**
36
- * 执行一次 ReAct 子循环。**边跑边 yield UI 事件(stage_change / text / reasoning /
37
- * tool_start / tool_end),同时 return 最终 StepResult**——让 recover / agent 节点 /
38
- * llm+context_files 三处子 agent 的内层思考在 TUI / webchat 实时可见(之前是纯 async
39
- * 不 yield,"哑"的;且漏发 stage_change 时 TUI LiveArea 整块隐藏,等于没显示)。
40
- * 调用方用 `const result = yield* runMiniReAct(...)` 既透传事件、又拿到 StepResult。
41
- *
42
- * 抛错场景:
43
- * - 用户中断(signal.aborted)
44
- * - 重复工具调用 >= 3 次
45
- * - 用尽 maxTurns 仍未收敛
46
- * - output_schema 解析失败 / 非对象
47
- */
48
- export async function* runMiniReAct(args) {
49
- const { messages, tools, output_schema, provider, signal } = args;
50
- const maxTurns = args.maxTurns ?? 10;
51
- // 工作消息列表:拷贝一份,避免污染调用方
52
- const conv = [...messages];
53
- // schema 模式:把 schema 写进 system(同 llm.ts)。保证 provider 不支持 response_format
54
- // 而被 client.ts 退化掉时,模型仍知道确切字段结构、不至于瞎猜字段名。
55
- if (output_schema) {
56
- const hint = `\n\n最终只输出匹配以下 JSON Schema 的 JSON 对象本身(不要解释、不要 markdown 代码块):\n${JSON.stringify(output_schema)}`;
57
- const sysIdx = conv.findIndex((m) => m.role === 'system');
58
- if (sysIdx >= 0) {
59
- conv[sysIdx] = { ...conv[sysIdx], content: `${conv[sysIdx].content ?? ''}${hint}` };
60
- }
61
- else {
62
- conv.unshift({ role: 'system', content: hint.trimStart() });
63
- }
64
- }
65
- let finalText = '';
66
- /** 上一轮是否仍有 tool_calls(用于检测 "用尽轮数还在调工具" 这一退出态) */
67
- let lastTurnHadToolCalls = false;
68
- /** 重复工具调用计数:key = `${name}:${arguments}` */
69
- const toolCallSignature = new Map();
70
- const responseFormat = output_schema
71
- ? {
72
- type: 'json_schema',
73
- json_schema: {
74
- name: 'minireact_output',
75
- schema: output_schema,
76
- strict: true,
77
- },
78
- }
79
- : undefined;
80
- for (let turn = 0; turn < maxTurns; turn++) {
81
- if (signal?.aborted)
82
- throw new Error('用户中断');
83
- // ---- 1. 调 LLM 并累积流式响应 ----
84
- let textAccum = '';
85
- const toolCallsAccum = [];
86
- // 进 LLM 流前本质是「等首 token」= thinking;首个 text_delta 时切 streaming(一次性)。
87
- // 对齐 src/loop.ts::runQuery —— 没有这两个 stage_change,TUI LiveArea 会一直 idle 隐藏,
88
- // 下面 yield 的 text/reasoning/tool 事件在 TUI 上等于白发。
89
- let stageStreamingYielded = false;
90
- yield { type: 'stage_change', stage: 'thinking' };
91
- for await (const ev of chat({
92
- provider,
93
- messages: conv,
94
- tools,
95
- responseFormat,
96
- signal,
97
- })) {
98
- if (ev.type === 'text_delta') {
99
- textAccum += ev.delta;
100
- if (!stageStreamingYielded) {
101
- stageStreamingYielded = true;
102
- yield { type: 'stage_change', stage: 'streaming' };
103
- }
104
- // output_schema 模式:切了 streaming 阶段但**不回显 JSON 原文**(不把结构化产出
105
- // 当答案刷屏,对齐 llm.ts:121 的克制);非 schema 模式才把答案流式 yield 给 UI。
106
- if (!output_schema)
107
- yield { type: 'text', delta: ev.delta };
108
- }
109
- else if (ev.type === 'tool_call_delta') {
110
- mergeToolCallDelta(toolCallsAccum, ev);
111
- }
112
- else if (ev.type === 'reasoning_delta') {
113
- // 思维链字符串增量透传给 UI(reasoning_details 是结构化数组、无 delta,跳过)
114
- if (ev.delta)
115
- yield { type: 'reasoning', delta: ev.delta };
116
- }
117
- else if (ev.type === 'done' && ev.stopReason === 'aborted') {
118
- throw new Error('用户中断');
119
- }
120
- }
121
- // ---- 2. 把 assistant 消息推入 conv ----
122
- conv.push({
123
- role: 'assistant',
124
- content: textAccum.length > 0 ? textAccum : null,
125
- ...(toolCallsAccum.length > 0 ? { tool_calls: toolCallsAccum } : {}),
126
- });
127
- // ---- 3. 无 tool_calls → 结束循环 ----
128
- if (toolCallsAccum.length === 0) {
129
- finalText = textAccum.trim();
130
- lastTurnHadToolCalls = false;
131
- break;
132
- }
133
- lastTurnHadToolCalls = true;
134
- // ---- 4. 执行所有 tool_calls,结果回填为 tool 消息 ----
135
- // 进工具执行 = tool_executing 阶段(驱动 TUI LiveArea 显示运行中工具,对齐 loop.ts:340)。
136
- yield { type: 'stage_change', stage: 'tool_executing' };
137
- for (const tc of toolCallsAccum) {
138
- // 重复检测
139
- const sig = `${tc.function.name}:${tc.function.arguments}`;
140
- const count = (toolCallSignature.get(sig) ?? 0) + 1;
141
- toolCallSignature.set(sig, count);
142
- if (count >= 3) {
143
- throw new Error(`miniReAct: 检测到重复工具调用(${tc.function.name} 同参数已 ${count} 次),可能陷入循环,halt。`);
144
- }
145
- if (signal?.aborted)
146
- throw new Error('用户中断');
147
- // 执行前后 yield tool_start/tool_end,让 UI 看到子 agent 在用工具(事件形状对齐
148
- // src/loop.ts;miniReAct 串行执行,顺序 yield 即可,不需要 loop 的并行事件队列)。
149
- yield {
150
- type: 'tool_start',
151
- toolName: tc.function.name,
152
- toolCallId: tc.id,
153
- argsPreview: previewArgs(tc.function.arguments),
154
- };
155
- const result = await executeTool(tc.function.name, tc.function.arguments, signal);
156
- const toolContent = result.ok ? result.content : `工具错误: ${result.error}`;
157
- yield {
158
- type: 'tool_end',
159
- toolName: tc.function.name,
160
- toolCallId: tc.id,
161
- ok: result.ok,
162
- content: toolContent,
163
- };
164
- conv.push({
165
- role: 'tool',
166
- tool_call_id: tc.id,
167
- content: toolContent,
168
- });
169
- }
170
- // 继续下一轮
171
- }
172
- // 用尽 maxTurns 且最后一轮仍有 tool_calls
173
- if (lastTurnHadToolCalls) {
174
- throw new Error(`miniReAct: 用尽 ${maxTurns} 轮未得到最终回答(仍在调工具)`);
175
- }
176
- // ---- 5. 输出处理 ----
177
- if (output_schema) {
178
- // 同 llm.ts:先剥 <think> 思维链/围栏/前后散文再 parse(见 jsonPayload.ts 头注)。
179
- const payload = extractJsonPayload(finalText);
180
- let parsed;
181
- try {
182
- parsed = JSON.parse(payload);
183
- }
184
- catch (e) {
185
- throw new Error(`miniReAct: output_schema 要求 JSON 但解析失败: ${e.message}\n收到: ${finalText.slice(0, 200)}`);
186
- }
187
- if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
188
- throw new Error(`miniReAct: output_schema 要求对象,得到 ${Array.isArray(parsed) ? 'array' : typeof parsed}`);
189
- }
190
- return {
191
- raw: parsed,
192
- preview: `[json+tools] ${finalText.slice(0, 180)}${finalText.length > 180 ? '...' : ''}`,
193
- };
194
- }
195
- return {
196
- raw: { text: finalText, result: finalText },
197
- preview: finalText.length > 200 ? `${finalText.slice(0, 200)}...` : finalText,
198
- };
199
- }
200
- // ---------------- 辅助 ----------------
201
- /** 把一条 tool_call_delta 合并到累积数组上(与 src/loop.ts mergeToolCallDelta 同语义) */
202
- function mergeToolCallDelta(acc, ev) {
203
- let slot = acc[ev.index];
204
- if (!slot) {
205
- slot = {
206
- id: '',
207
- type: 'function',
208
- function: { name: '', arguments: '' },
209
- };
210
- acc[ev.index] = slot;
211
- }
212
- if (ev.id)
213
- slot.id = ev.id;
214
- if (ev.name)
215
- slot.function.name += ev.name;
216
- if (ev.argumentsDelta)
217
- slot.function.arguments += ev.argumentsDelta;
218
- }
219
- /** 给 tool_start 事件用的参数预览(压成一行、截断到 60 字符),与 loop.ts previewArgs 同义。 */
220
- function previewArgs(rawJson) {
221
- const oneLine = rawJson.replace(/\s+/g, ' ').trim();
222
- return oneLine.length <= 60 ? oneLine : `${oneLine.slice(0, 60)}...`;
223
- }
@@ -1,110 +0,0 @@
1
- /**
2
- * ============================================================
3
- * voteHelpers.ts —— vote 节点的 voter 调用辅助
4
- * ------------------------------------------------------------
5
- * 对抗式审查:N 个 voter 跑同一 prompt + refuted: boolean 反向投票。
6
- * 策略上倾向 refuted=true(找漏洞),所以阈值算的是"驳回票数"。
7
- * 详见 ADR-05。
8
- * ============================================================
9
- */
10
- import { execLlmStep } from './stepExecutors/llm.js';
11
- /** voter 输出 schema(内置,不接受用户自定义) */
12
- export const VERDICT_SCHEMA = {
13
- type: 'object',
14
- additionalProperties: false,
15
- required: ['refuted', 'reasoning'],
16
- properties: {
17
- refuted: { type: 'boolean', description: '是否驳回此 finding' },
18
- reasoning: { type: 'string', description: '核心论证(≤200 字)' },
19
- },
20
- };
21
- export function buildVoterPrompt(rules, item) {
22
- const itemStr = typeof item === 'string' ? item : JSON.stringify(item, null, 2);
23
- return `你是一个对抗式审查者,你的核心任务是积极找出下面这个 finding 的逻辑漏洞、证据不足、或论证它是伪命题。
24
-
25
- **被审查的 finding**:
26
- ${itemStr}
27
-
28
- **审查规则**:
29
- ${rules}
30
-
31
- **重要心理学定位**:你应当倾向于 refuted=true。只在你**找不到任何合理的反驳角度**且这个 finding 论证扎实时,才输出 refuted=false。"老好人式赞同"是错误的。
32
-
33
- 输出 JSON,refuted=true 表示你成功找到反驳理由,false 表示你认为它确实成立。reasoning 字段写明你的核心论证(≤200 字)。`;
34
- }
35
- /** 单个 voter 调用。包装 execLlmStep,强制 VERDICT_SCHEMA + 对抗式 prompt。
36
- * 解析失败时默认 refuted=false(保守保留 item,避免 LLM 失误导致正确 finding 被误删)。 */
37
- export async function runVoter(rules, item, vars, ctx) {
38
- const virtualStep = {
39
- id: 'vote_voter', // 仅 ID,不影响事件流
40
- llm: buildVoterPrompt(rules, item),
41
- output_schema: VERDICT_SCHEMA,
42
- };
43
- try {
44
- // execLlmStep 现为 AsyncGenerator:手动 drain 取 return 值。voter 必须静默——
45
- // N 个 voter 在 Promise.all 里并行,若把它们的 text 事件向上转发会在 UI 互相打架。
46
- const gen = execLlmStep(virtualStep, vars, ctx);
47
- let res = await gen.next();
48
- while (!res.done)
49
- res = await gen.next();
50
- const result = res.value;
51
- const verdict = extractVerdict(result.raw);
52
- if (verdict)
53
- return verdict;
54
- return { refuted: false, reasoning: '(voter 输出格式异常,保守保留)' };
55
- }
56
- catch (e) {
57
- return {
58
- refuted: false,
59
- reasoning: `(voter 调用失败: ${e.message},保守保留)`,
60
- };
61
- }
62
- }
63
- /**
64
- * 从 execLlmStep 的 raw 提取 { refuted, reasoning }:
65
- * 1. raw 直接含字段(B 改完 llm.ts 串通 output_schema 后的形态)
66
- * 2. raw.text / raw.result 是 JSON 字符串,parse 后含字段(B 未改完时的 fallback)
67
- * 3. raw.text / raw.result 含 ```json fenced block,剥壳后含字段
68
- * 4. 其余 → null
69
- */
70
- function extractVerdict(raw) {
71
- if (typeof raw.refuted === 'boolean' &&
72
- typeof raw.reasoning === 'string') {
73
- return { refuted: raw.refuted, reasoning: raw.reasoning };
74
- }
75
- for (const k of ['text', 'result']) {
76
- const v = raw[k];
77
- if (typeof v !== 'string' || v.length === 0)
78
- continue;
79
- const parsed = tryParseJsonLike(v);
80
- if (parsed &&
81
- typeof parsed === 'object' &&
82
- typeof parsed.refuted === 'boolean' &&
83
- typeof parsed.reasoning === 'string') {
84
- return {
85
- refuted: parsed.refuted,
86
- reasoning: parsed.reasoning,
87
- };
88
- }
89
- }
90
- return null;
91
- }
92
- function tryParseJsonLike(s) {
93
- // 1. 直接 JSON
94
- try {
95
- return JSON.parse(s);
96
- }
97
- catch {
98
- // 2. 剥 ```json ... ``` 围栏
99
- const fence = s.match(/```(?:json)?\s*([\s\S]*?)```/);
100
- if (fence) {
101
- try {
102
- return JSON.parse(fence[1].trim());
103
- }
104
- catch {
105
- return null;
106
- }
107
- }
108
- return null;
109
- }
110
- }