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
@@ -22,7 +22,8 @@
22
22
  * interp := '${' EXPR '}' // 取 EXPR 的"值"(任意类型,不字符串化)
23
23
  * string := "…" | '…' // 内嵌 ${EXPR} 走 template-literal 插值
24
24
  *
25
- * 白名单函数:fileExists / length / lower / upper
25
+ * 白名单函数:fileExists / readJson / parseJson / asArray / length / lower / upper / includes /
26
+ * startsWith / endsWith / match / split / extract / join / json
26
27
  *
27
28
  * ★ P2 根治:表达式上下文(when/condition/over/assert/vote.input)直接 evalExpr,
28
29
  * 不再"先 interpolate 再 eval"(旧双求值的 footgun 源头)。四种写法都 OK:
@@ -36,11 +37,11 @@
36
37
  * 把 EXPR 求值后 toString 替换;对象/数组用 JSON.stringify。interpolateDeep 递归处理对象/数组/字符串。
37
38
  * ============================================================
38
39
  */
39
- import { existsSync } from 'node:fs';
40
+ import { existsSync, readFileSync } from 'node:fs';
40
41
  import { join, isAbsolute } from 'node:path';
41
42
  import { getWorkingDir } from '../../../src/plugin-sdk.js';
42
43
  const PUNCT2 = new Set(['==', '!=', '>=', '<=', '&&', '||']);
43
- const PUNCT1 = new Set(['(', ')', '[', ']', ',', '.', '!', '>', '<', '+']);
44
+ const PUNCT1 = new Set(['(', ')', '[', ']', ',', '.', '!', '>', '<', '+', '?', ':']);
44
45
  function tokenize(src) {
45
46
  const out = [];
46
47
  let i = 0;
@@ -158,12 +159,140 @@ const BUILTINS = {
158
159
  return Object.keys(v).length;
159
160
  return 0;
160
161
  },
162
+ // 把可选 JSON 数组标准化为 for-each loop 可消费的数组。用于
163
+ // over: "${asArray(readJson('manifest.json', 'images'))}" 这类场景:
164
+ // 缺文件/缺字段/null 表示 0 轮;但对象/字符串等结构错误要响亮失败,
165
+ // 避免把坏 manifest 静默吞掉。
166
+ asArray(args) {
167
+ const v = args[0];
168
+ if (Array.isArray(v))
169
+ return v;
170
+ if (v === null || v === undefined)
171
+ return [];
172
+ throw new Error(`asArray 期望数组/null/undefined,得到 ${Array.isArray(v) ? 'array' : typeof v}`);
173
+ },
161
174
  lower(args) {
162
175
  return String(args[0] ?? '').toLowerCase();
163
176
  },
164
177
  upper(args) {
165
178
  return String(args[0] ?? '').toUpperCase();
166
179
  },
180
+ includes(args) {
181
+ const haystack = String(args[0] ?? '');
182
+ const needle = String(args[1] ?? '');
183
+ return haystack.includes(needle);
184
+ },
185
+ startsWith(args) {
186
+ const s = String(args[0] ?? '');
187
+ const prefix = String(args[1] ?? '');
188
+ return s.startsWith(prefix);
189
+ },
190
+ endsWith(args) {
191
+ const s = String(args[0] ?? '');
192
+ const suffix = String(args[1] ?? '');
193
+ return s.endsWith(suffix);
194
+ },
195
+ match(args) {
196
+ const s = String(args[0] ?? '');
197
+ const pattern = String(args[1] ?? '');
198
+ try {
199
+ const re = new RegExp(pattern);
200
+ return re.test(s);
201
+ }
202
+ catch {
203
+ return false; // 非法正则 → 不匹配
204
+ }
205
+ },
206
+ split(args) {
207
+ const s = String(args[0] ?? '');
208
+ const delim = args[1] !== undefined ? String(args[1]) : ',';
209
+ return s.split(delim);
210
+ },
211
+ // 全局正则提取:返回匹配数组。有捕获组取 group 1(典型:提取 <tag>(.*?)</tag> 内容),
212
+ // 否则取全匹配。flags 固定 gs(跨行 . 匹配);非法正则返回 [](与 match 同哲学:不抛)。
213
+ // 动机:从 agent/llm 输出里确定性抽取协议标签(如 <learning>…</learning>),
214
+ // 替代「再开一个 LLM 步去提取」的幻觉/改写风险。
215
+ extract(args) {
216
+ const s = String(args[0] ?? '');
217
+ const pattern = String(args[1] ?? '');
218
+ if (!pattern)
219
+ return [];
220
+ try {
221
+ const re = new RegExp(pattern, 'gs');
222
+ const out = [];
223
+ for (const m of s.matchAll(re)) {
224
+ out.push(m[1] !== undefined ? m[1] : m[0]);
225
+ }
226
+ return out;
227
+ }
228
+ catch {
229
+ return [];
230
+ }
231
+ },
232
+ // 数组拼接成字符串;非数组按 stringify 兜底。与 extract 配对使用。
233
+ join(args) {
234
+ const v = args[0];
235
+ const sep = args[1] !== undefined ? String(args[1]) : ',';
236
+ if (Array.isArray(v))
237
+ return v.map((x) => stringify(x)).join(sep);
238
+ return stringify(v);
239
+ },
240
+ // JSON.stringify 安全嵌入:值含引号/换行时拼 JSON 文件不产坏文档
241
+ // (模板里写 "k": ${json(v)},外层引号由 json() 自己生成)。
242
+ json(args) {
243
+ try {
244
+ return JSON.stringify(args[0] ?? null);
245
+ }
246
+ catch {
247
+ return 'null';
248
+ }
249
+ },
250
+ // 读磁盘 JSON 文件并取值:path 相对 getWorkingDir()(绝对路径原样);给了 key
251
+ // 则返回顶层 obj[key],否则返回整值。缺文件 / 坏 JSON / 键不存在 → null
252
+ //(与 match/extract 同「不抛」哲学)。动机:让确定性脚本产出的 manifest
253
+ //(如 source_assets.json)直接驱动工作流 for-each / branch —— 填补「磁盘
254
+ // 结构化数据 → 控制流」的空白(与 fileExists 平级的基础能力)。
255
+ readJson(args) {
256
+ const p = String(args[0] ?? '');
257
+ if (!p)
258
+ return null;
259
+ const abs = isAbsolute(p) ? p : join(getWorkingDir(), p);
260
+ try {
261
+ // 剥前导 BOM:某些工具/重定向写出的 JSON 带 BOM,JSON.parse 会因此抛错。
262
+ let raw = readFileSync(abs, 'utf8');
263
+ if (raw.charCodeAt(0) === 0xfeff)
264
+ raw = raw.slice(1);
265
+ const val = JSON.parse(raw);
266
+ if (args.length >= 2) {
267
+ const key = String(args[1] ?? '');
268
+ return val != null && typeof val === 'object' ? (val[key] ?? null) : null;
269
+ }
270
+ return val;
271
+ }
272
+ catch {
273
+ return null;
274
+ }
275
+ },
276
+ // 解析 JSON 字符串成值(与 readJson 平级,但源是**字符串**而非文件):剥前导 BOM、
277
+ // trim、JSON.parse;非字符串 / 空 / 坏 JSON → null(同 match/extract/readJson「不抛」哲学)。
278
+ // 动机:把 WebBrowser eval / agent / 工具 capture 到的 JSON 文本变成数组/对象,
279
+ // 直接驱动 loop over / branch —— 填补「字符串结构化数据 → 控制流」的空白
280
+ //(配 asArray 用:over: "${asArray(parseJson(urls_json))}")。
281
+ parseJson(args) {
282
+ const v = args[0];
283
+ if (typeof v !== 'string')
284
+ return null;
285
+ let raw = v.charCodeAt(0) === 0xfeff ? v.slice(1) : v;
286
+ raw = raw.trim();
287
+ if (!raw)
288
+ return null;
289
+ try {
290
+ return JSON.parse(raw);
291
+ }
292
+ catch {
293
+ return null;
294
+ }
295
+ },
167
296
  };
168
297
  function parseOr(c, vars) {
169
298
  let left = parseAnd(c, vars);
@@ -174,6 +303,21 @@ function parseOr(c, vars) {
174
303
  }
175
304
  return left;
176
305
  }
306
+ // 三元表达式:cond ? true_expr : false_expr
307
+ // 优先级低于 ||(即先算完 || 再判断 ? :)
308
+ // 右结合:a ? b ? c : d : e 等价于 a ? (b ? c : d) : e
309
+ function parseTernary(c, vars) {
310
+ const cond = parseOr(c, vars);
311
+ if (!isPunct(c, '?'))
312
+ return cond;
313
+ eat(c); // 吃掉 '?'
314
+ const consequent = parseTernary(c, vars); // 右结合:true 分支可以是嵌套三元
315
+ if (!isPunct(c, ':'))
316
+ throw new Error("三元表达式缺少 ':'");
317
+ eat(c); // 吃掉 ':'
318
+ const alternate = parseTernary(c, vars); // 右结合:false 分支也可以是嵌套三元
319
+ return truthy(cond) ? consequent : alternate;
320
+ }
177
321
  function parseAnd(c, vars) {
178
322
  let left = parseNot(c, vars);
179
323
  while (isPunct(c, '&&')) {
@@ -238,7 +382,8 @@ function parsePrimary(c, vars) {
238
382
  throw new Error('表达式意外结束');
239
383
  if (t.kind === 'punct' && t.value === '(') {
240
384
  eat(c);
241
- const v = parseOr(c, vars);
385
+ // 括号内是完整表达式(含三元)——曾只递归 parseOr,(a ? b : c) 报「缺少 ')'」
386
+ const v = parseTernary(c, vars);
242
387
  if (!isPunct(c, ')'))
243
388
  throw new Error("缺少 ')'");
244
389
  eat(c);
@@ -248,10 +393,10 @@ function parsePrimary(c, vars) {
248
393
  eat(c);
249
394
  const arr = [];
250
395
  if (!isPunct(c, ']')) {
251
- arr.push(parseOr(c, vars));
396
+ arr.push(parseTernary(c, vars));
252
397
  while (isPunct(c, ',')) {
253
398
  eat(c);
254
- arr.push(parseOr(c, vars));
399
+ arr.push(parseTernary(c, vars));
255
400
  }
256
401
  }
257
402
  if (!isPunct(c, ']'))
@@ -282,10 +427,10 @@ function parsePrimary(c, vars) {
282
427
  eat(c);
283
428
  const argv = [];
284
429
  if (!isPunct(c, ')')) {
285
- argv.push(parseOr(c, vars));
430
+ argv.push(parseTernary(c, vars));
286
431
  while (isPunct(c, ',')) {
287
432
  eat(c);
288
- argv.push(parseOr(c, vars));
433
+ argv.push(parseTernary(c, vars));
289
434
  }
290
435
  }
291
436
  if (!isPunct(c, ')'))
@@ -349,7 +494,7 @@ export function evalExpr(expr, vars) {
349
494
  if (toks.length === 0)
350
495
  return undefined;
351
496
  const cursor = { toks, pos: 0 };
352
- const v = parseOr(cursor, vars);
497
+ const v = parseTernary(cursor, vars);
353
498
  if (cursor.pos !== toks.length) {
354
499
  throw new Error(`表达式多余 token: "${expr}"`);
355
500
  }
@@ -362,7 +507,7 @@ export function evalExpr(expr, vars) {
362
507
  *
363
508
  * 转义:`\$` → 字面 $,跳过插值。
364
509
  */
365
- export function interpolate(template, vars) {
510
+ export function interpolate(template, vars, opts) {
366
511
  let out = '';
367
512
  let i = 0;
368
513
  while (i < template.length) {
@@ -391,6 +536,8 @@ export function interpolate(template, vars) {
391
536
  }
392
537
  const expr = template.slice(i + 2, j);
393
538
  const v = evalExpr(expr, vars);
539
+ if (v === undefined)
540
+ opts?.onMissing?.(expr);
394
541
  out += stringify(v);
395
542
  i = j + 1;
396
543
  continue;
@@ -400,6 +547,42 @@ export function interpolate(template, vars) {
400
547
  }
401
548
  return out;
402
549
  }
550
+ /**
551
+ * 类型保留插值:模板整串恰好是单一 "${EXPR}" 时直接返回 EXPR 的值
552
+ * (布尔/数字/数组原样,不字符串化);多片段模板退回普通 interpolate。
553
+ * 非字符串值原样透传(与 interpolateDeep 对非字符串的行为一致)。
554
+ *
555
+ * 动机:set 步写 `flag: "${qualified}"` 曾被字符串化成 "true",逼出下游
556
+ * 满篇 `== true || == 'true'` 防御——单表达式赋值就该保住类型。
557
+ */
558
+ export function interpolateTyped(value, vars, opts) {
559
+ if (typeof value !== 'string')
560
+ return value;
561
+ const expr = singleExprOf(value);
562
+ if (expr === null)
563
+ return interpolate(value, vars, opts);
564
+ const v = evalExpr(expr, vars);
565
+ if (v === undefined)
566
+ opts?.onMissing?.(expr);
567
+ return v;
568
+ }
569
+ /** 整串恰好是一个 "${EXPR}"(括号配对到串尾)时返回内层 EXPR,否则 null。 */
570
+ function singleExprOf(template) {
571
+ if (!template.startsWith('${') || !template.endsWith('}'))
572
+ return null;
573
+ let depth = 1;
574
+ for (let j = 2; j < template.length; j++) {
575
+ if (template[j] === '{')
576
+ depth++;
577
+ else if (template[j] === '}') {
578
+ depth--;
579
+ // 提前归零 = 中途闭合(如 "${a}-${b}"),不是单一表达式
580
+ if (depth === 0)
581
+ return j === template.length - 1 ? template.slice(2, j) : null;
582
+ }
583
+ }
584
+ return null;
585
+ }
403
586
  function stringify(v) {
404
587
  if (v === null || v === undefined)
405
588
  return '';
@@ -415,19 +598,19 @@ function stringify(v) {
415
598
  }
416
599
  }
417
600
  /** 递归对对象/数组/字符串做插值;其它原样返回。 */
418
- export function interpolateDeep(value, vars) {
601
+ export function interpolateDeep(value, vars, opts) {
419
602
  if (typeof value === 'string') {
420
- return interpolate(value, vars);
603
+ return interpolate(value, vars, opts);
421
604
  }
422
605
  if (Array.isArray(value)) {
423
- return value.map((v) => interpolateDeep(v, vars));
606
+ return value.map((v) => interpolateDeep(v, vars, opts));
424
607
  }
425
608
  if (value && typeof value === 'object') {
426
609
  const out = {};
427
610
  for (const [k, v] of Object.entries(value)) {
428
611
  // 注意:key 也插值(loop 里 `hook_${idx}` 这种),但只对字符串 key 有意义
429
- const newKey = interpolate(k, vars);
430
- out[newKey] = interpolateDeep(v, vars);
612
+ const newKey = interpolate(k, vars, opts);
613
+ out[newKey] = interpolateDeep(v, vars, opts);
431
614
  }
432
615
  return out;
433
616
  }
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { findWorkflowByName, listWorkflows } from './loader.js';
14
14
  import { runWorkflow } from './runner.js';
15
+ import { buildFullSystemPrompt, } from '../../../src/plugin-sdk.js';
15
16
  /**
16
17
  * 把 "/workflow <name> [pos1 pos2 ...] [--input k=v ...]" 拆成 name + 显式 inputs + 位置参数。
17
18
  * 简单解析器(不依赖第三方):
@@ -124,6 +125,18 @@ function coerceInputs(raw, defs) {
124
125
  }
125
126
  return out;
126
127
  }
128
+ async function refreshWorkflowSystemPrompt(history, cwd, tools) {
129
+ const content = await buildFullSystemPrompt(cwd, tools);
130
+ const systemIndex = history.findIndex((m) => m.role === 'system' && !m._ephemeral);
131
+ const fresh = { role: 'system', content };
132
+ if (systemIndex === 0) {
133
+ history[0] = fresh;
134
+ return;
135
+ }
136
+ if (systemIndex > 0)
137
+ history.splice(systemIndex, 1);
138
+ history.unshift(fresh);
139
+ }
127
140
  /** /workflow <name> [pos...] [--input k=v] —— 主入口,由 pluginRunner 调用。 */
128
141
  export async function* runWorkflowFromCommand(rawArgs, opts) {
129
142
  const { name, inputs: rawInputs, positional } = parseWorkflowArgs(rawArgs);
@@ -142,11 +155,29 @@ export async function* runWorkflowFromCommand(rawArgs, opts) {
142
155
  };
143
156
  return;
144
157
  }
145
- // 位置参数严格按"第 i 个位置参数 ↔ def.inputs[i]"对应。
146
- // --input k=v 显式优先:已显式的 input 不被位置参数覆盖(对应的位置参数被丢弃,会 warn)。
147
- // 多余的位置参数(超过 def.inputs 数量)也被丢弃(会 warn)。
158
+ const cwd = opts.cwd ?? process.cwd();
159
+ const tools = opts.tools ?? [];
160
+ await refreshWorkflowSystemPrompt(opts.history, cwd, tools);
161
+ // 位置参数映射,两种模式:
162
+ // - 贪婪首参(def.inputs[0].greedy===true):把【全部】位置参数用空格 join 成整句写进
163
+ // 首个 input(自然语言 brief 不被空格拆碎、也不会撞上后面的 number/enum 输入),
164
+ // 其余 input 只走 --input。用户「打一句话」即可(见 webppt.yaml::topic)。
165
+ // - 默认:严格按"第 i 个位置参数 ↔ def.inputs[i]"对应。
166
+ // --input k=v 显式优先:已显式的 input 不被位置参数覆盖(对应位置参数被丢弃,会 warn)。
148
167
  const overriddenByKV = [];
149
- if (positional.length > 0 && def.inputs) {
168
+ const greedyFirst = def.inputs?.[0]?.greedy === true;
169
+ if (greedyFirst && def.inputs && positional.length > 0) {
170
+ const greedyName = def.inputs[0].name;
171
+ if (greedyName in rawInputs) {
172
+ // 首参已被 --input 占位 → 整串位置参数被忽略
173
+ overriddenByKV.push(`${greedyName}=${JSON.stringify(rawInputs[greedyName])} (位置参数 ${JSON.stringify(positional.join(' '))} 被忽略)`);
174
+ }
175
+ else {
176
+ // 贪婪吸收:整句进首参(空格 join 还原用户原话,不逐位拆映射)
177
+ rawInputs[greedyName] = positional.join(' ');
178
+ }
179
+ }
180
+ else if (positional.length > 0 && def.inputs) {
150
181
  const max = Math.min(positional.length, def.inputs.length);
151
182
  for (let i = 0; i < max; i++) {
152
183
  const inputDef = def.inputs[i];
@@ -161,8 +192,8 @@ export async function* runWorkflowFromCommand(rawArgs, opts) {
161
192
  }
162
193
  }
163
194
  }
164
- // warn:超量位置参数(用户写多了,提示一下)
165
- if (def.inputs && positional.length > def.inputs.length) {
195
+ // warn:超量位置参数(仅非 greedy 模式;greedy 全部吸收进首参,不算多余)
196
+ if (!greedyFirst && def.inputs && positional.length > def.inputs.length) {
166
197
  const dropped = positional.slice(def.inputs.length);
167
198
  yield {
168
199
  type: 'warning',
@@ -188,8 +219,9 @@ export async function* runWorkflowFromCommand(rawArgs, opts) {
188
219
  provider: opts.provider,
189
220
  signal: opts.signal,
190
221
  history: opts.history,
191
- cwd: opts.cwd ?? process.cwd(),
192
- tools: opts.tools ?? [],
222
+ sessionState: opts.sessionState,
223
+ cwd,
224
+ tools,
193
225
  };
194
226
  // 透传 runWorkflow 的事件,并观察是否出现终结事件(error / interrupted = 失败或中断,
195
227
  // 与 gateway broker 的 TERMINAL 判定同一套逻辑)。成功(没见到终结事件)则在末尾补一条
@@ -10,7 +10,7 @@
10
10
  * 破坏主循环。剥离必须发生在「契约要求纯 JSON」的边界,也就是 workflow 的
11
11
  * output_schema 解析处。本模块就是那个边界的唯一实现,被两个解析点共享:
12
12
  * - stepExecutors/llm.ts(llm + output_schema 单轮)
13
- * - miniReAct.ts(agent 节点 / llm+context_files / onError:recover 三处子循环)
13
+ * - stepExecutors/llm.ts(output_schema 解析处)
14
14
  * 放一处、两边 import,杜绝"只修一个解析点、另一个继续炸"的漂移。
15
15
  *
16
16
  * 处理顺序(保守、纯函数、可单测):