minimal-agent 0.12.0 → 0.14.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 (472) hide show
  1. package/README.md +6 -5
  2. package/package.json +62 -5
  3. package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
  4. package/plugins/cron-runner/src/commands.js +4 -4
  5. package/plugins/cron-runner/src/commands.ts +4 -4
  6. package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
  7. package/plugins/workflow-runner/commands/workflow.md +57 -90
  8. package/plugins/workflow-runner/commands/workflows.md +4 -4
  9. package/plugins/workflow-runner/plugin.js +24 -13
  10. package/plugins/workflow-runner/plugin.ts +28 -13
  11. package/plugins/workflow-runner/src/discovery.js +160 -0
  12. package/plugins/workflow-runner/src/discovery.ts +194 -0
  13. package/plugins/workflow-runner/src/goalAnchor.js +53 -0
  14. package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
  15. package/plugins/workflow-runner/src/index.js +204 -185
  16. package/plugins/workflow-runner/src/index.ts +249 -224
  17. package/plugins/workflow-runner/src/inputCoercion.js +40 -0
  18. package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
  19. package/plugins/workflow-runner/src/journal.js +224 -0
  20. package/plugins/workflow-runner/src/journal.ts +274 -0
  21. package/plugins/workflow-runner/src/jsonSchema.js +132 -0
  22. package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
  23. package/plugins/workflow-runner/src/moduleResolution.js +64 -0
  24. package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
  25. package/plugins/workflow-runner/src/resourceInputs.js +220 -0
  26. package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
  27. package/plugins/workflow-runner/src/runner.js +404 -467
  28. package/plugins/workflow-runner/src/runner.ts +491 -535
  29. package/plugins/workflow-runner/src/runtime/config.js +46 -0
  30. package/plugins/workflow-runner/src/runtime/config.ts +69 -0
  31. package/plugins/workflow-runner/src/runtime/context.js +1304 -0
  32. package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
  33. package/plugins/workflow-runner/src/runtime/exec.js +34 -0
  34. package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
  35. package/plugins/workflow-runner/src/runtime/flow.js +8 -0
  36. package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
  37. package/plugins/workflow-runner/src/runtime/fs.js +27 -0
  38. package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
  39. package/plugins/workflow-runner/src/runtime/model.js +6 -0
  40. package/plugins/workflow-runner/src/runtime/model.ts +8 -0
  41. package/plugins/workflow-runner/src/runtime/output.js +7 -0
  42. package/plugins/workflow-runner/src/runtime/output.ts +21 -0
  43. package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
  44. package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
  45. package/plugins/workflow-runner/src/runtime/state.js +16 -0
  46. package/plugins/workflow-runner/src/runtime/state.ts +19 -0
  47. package/plugins/workflow-runner/src/runtime/tools.js +3 -0
  48. package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
  49. package/plugins/workflow-runner/src/sandbox.js +141 -0
  50. package/plugins/workflow-runner/src/sandbox.ts +182 -0
  51. package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
  52. package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
  53. package/plugins/workflow-runner/src/taskIdentity.js +172 -152
  54. package/plugins/workflow-runner/src/taskIdentity.ts +233 -200
  55. package/plugins/workflow-runner/src/toolRuntime.js +29 -8
  56. package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
  57. package/plugins/workflow-runner/src/types.js +7 -105
  58. package/plugins/workflow-runner/src/types.ts +155 -520
  59. package/plugins/workflow-runner/src/util.js +47 -0
  60. package/plugins/workflow-runner/src/util.ts +51 -0
  61. package/plugins/workflow-runner/src/workflowContext.js +20 -0
  62. package/plugins/workflow-runner/src/workflowContext.ts +58 -0
  63. package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
  64. package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
  65. package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
  66. package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
  67. package/plugins/workflow-runner/src/workflowState.js +542 -469
  68. package/plugins/workflow-runner/src/workflowState.ts +639 -589
  69. package/plugins/workflow-runner/test/api.test.ts +223 -0
  70. package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
  71. package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
  72. package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
  73. package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
  74. package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
  75. package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
  76. package/plugins/workflow-runner/test/discovery.test.ts +234 -0
  77. package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
  78. package/plugins/workflow-runner/test/goalController.test.ts +317 -0
  79. package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
  80. package/plugins/workflow-runner/test/listResources.test.ts +106 -0
  81. package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
  82. package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
  83. package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
  84. package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
  85. package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
  86. package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
  87. package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
  88. package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
  89. package/skills/pptx/examples/assets/cover-bg.svg +23 -0
  90. package/skills/pptx/examples/assets/icon-spark.svg +5 -0
  91. package/skills/skill-creator/scripts/run_eval.py +3 -2
  92. package/skills/ui-design/SKILL.md +5 -2
  93. package/skills/ui-design/references/layout-composition.md +1 -1
  94. package/skills/workflow-creator/SKILL.md +344 -0
  95. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  96. package/skills/workflow-creator/references/api.md +216 -0
  97. package/skills/workflow-creator/references/migration.md +103 -0
  98. package/skills/workflow-creator/references/patterns.md +779 -0
  99. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  100. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  101. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  102. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  103. package/src/advisor/advisorCoordinator.js +503 -0
  104. package/src/advisor/advisorCoordinator.ts +657 -0
  105. package/src/cli/configMenu.tsx +0 -1
  106. package/src/cli/print.js +44 -6
  107. package/src/cli/print.ts +73 -4
  108. package/src/cli/streamJson.js +5 -6
  109. package/src/cli/streamJson.ts +8 -4
  110. package/src/cli/wizards/advisorWizard.js +4 -2
  111. package/src/cli/wizards/advisorWizard.tsx +8 -2
  112. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  113. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  114. package/src/collaboration/taskFlow.js +115 -0
  115. package/src/collaboration/taskFlow.ts +169 -0
  116. package/src/config/configDefaults.js +41 -1
  117. package/src/config/configDefaults.ts +43 -1
  118. package/src/config/configDiagnostics.ts +2 -2
  119. package/src/config/configFile.js +40 -9
  120. package/src/config/configFile.ts +60 -11
  121. package/src/config/configService.js +443 -74
  122. package/src/config/configService.ts +723 -142
  123. package/src/config/numericLimits.js +22 -0
  124. package/src/config/numericLimits.ts +24 -0
  125. package/src/config.js +1 -0
  126. package/src/config.ts +3 -2
  127. package/src/context/budgetPlan.js +1 -1
  128. package/src/context/budgetPlan.ts +1 -1
  129. package/src/context/compact.js +7 -2
  130. package/src/context/compact.ts +9 -2
  131. package/src/context/microCompactLite.js +212 -13
  132. package/src/context/microCompactLite.ts +261 -12
  133. package/src/context/sessionRegistry.js +8 -1
  134. package/src/context/sessionRegistry.ts +18 -5
  135. package/src/context/toolResultArchive.js +72 -0
  136. package/src/context/toolResultArchive.ts +95 -0
  137. package/src/goal/errors.js +8 -0
  138. package/src/goal/errors.ts +18 -0
  139. package/src/goal/goalRuntime.js +344 -0
  140. package/src/goal/goalRuntime.ts +466 -0
  141. package/src/goal/goalStore.js +200 -0
  142. package/src/goal/goalStore.ts +219 -0
  143. package/src/goal/index.js +4 -0
  144. package/src/goal/index.ts +4 -0
  145. package/src/goal/statusMapping.js +71 -0
  146. package/src/goal/statusMapping.ts +95 -0
  147. package/src/goal/types.js +7 -0
  148. package/src/goal/types.ts +179 -0
  149. package/src/goal/workflowController.js +306 -0
  150. package/src/goal/workflowController.ts +360 -0
  151. package/src/harness/evidenceLedger.js +2 -0
  152. package/src/harness/evidenceLedger.ts +1 -0
  153. package/src/harness/stallGuard.js +9 -3
  154. package/src/harness/stallGuard.ts +7 -3
  155. package/src/images/imageResolver.js +161 -0
  156. package/src/images/imageResolver.ts +189 -0
  157. package/src/infra/verification.js +56 -20
  158. package/src/infra/verification.ts +87 -20
  159. package/src/llm/client.js +79 -21
  160. package/src/llm/client.ts +182 -35
  161. package/src/llm/gatewayClient.js +201 -0
  162. package/src/llm/gatewayClient.ts +299 -0
  163. package/src/llm/messageProvenance.js +46 -0
  164. package/src/llm/messageProvenance.ts +58 -0
  165. package/src/llm/modelProvider.js +1 -0
  166. package/src/llm/modelProvider.ts +22 -0
  167. package/src/llm/providers/anthropicFormat.js +108 -1
  168. package/src/llm/providers/anthropicFormat.ts +115 -4
  169. package/src/llm/providers/openaiFormat.js +9 -0
  170. package/src/llm/providers/openaiFormat.ts +12 -3
  171. package/src/loop.js +319 -54
  172. package/src/loop.ts +373 -57
  173. package/src/main.js +4 -1
  174. package/src/main.tsx +4 -1
  175. package/src/managedExecution/index.js +2 -0
  176. package/src/managedExecution/index.ts +2 -0
  177. package/src/managedExecution/registry.js +15 -0
  178. package/src/managedExecution/registry.ts +20 -0
  179. package/src/managedExecution/types.js +1 -0
  180. package/src/managedExecution/types.ts +86 -0
  181. package/src/modelRef.js +9 -0
  182. package/src/modelRef.ts +31 -0
  183. package/src/multimodal.js +14 -28
  184. package/src/multimodal.ts +17 -33
  185. package/src/net/lanDiscovery.js +65 -0
  186. package/src/net/lanDiscovery.ts +82 -0
  187. package/src/plugin-sdk.js +28 -3
  188. package/src/plugin-sdk.ts +39 -6
  189. package/src/plugins/pluginApi.ts +16 -1
  190. package/src/plugins/pluginLoader.js +4 -0
  191. package/src/plugins/pluginLoader.ts +6 -0
  192. package/src/plugins/pluginRunner.js +152 -9
  193. package/src/plugins/pluginRunner.ts +186 -8
  194. package/src/plugins/slashFallback.js +113 -0
  195. package/src/plugins/slashFallback.ts +137 -0
  196. package/src/prompts/policyRegistry.js +15 -8
  197. package/src/prompts/policyRegistry.ts +18 -8
  198. package/src/prompts/promptAssembly.js +103 -12
  199. package/src/prompts/promptAssembly.ts +114 -12
  200. package/src/prompts/skillList.js +21 -3
  201. package/src/prompts/skillList.ts +27 -2
  202. package/src/prompts/stableSystemPrompt.js +18 -0
  203. package/src/prompts/stableSystemPrompt.ts +33 -0
  204. package/src/runtime/agentRuntimeContext.js +8 -2
  205. package/src/runtime/agentRuntimeContext.ts +17 -4
  206. package/src/session/runAgentTurn.js +78 -12
  207. package/src/session/runAgentTurn.ts +105 -23
  208. package/src/session/runTurn.js +10 -9
  209. package/src/session/runTurn.ts +17 -8
  210. package/src/session/sessionState.ts +2 -0
  211. package/src/team/auth.js +186 -0
  212. package/src/team/auth.ts +298 -0
  213. package/src/team/cli.js +105 -0
  214. package/src/team/cli.ts +122 -0
  215. package/src/team/onlineToolContract.js +64 -0
  216. package/src/team/onlineToolContract.ts +109 -0
  217. package/src/team/toolPolicy.js +36 -0
  218. package/src/team/toolPolicy.ts +75 -0
  219. package/src/tools/advisor/advisor.js +148 -37
  220. package/src/tools/advisor/advisor.ts +161 -38
  221. package/src/tools/advisor/advisorDecision.js +71 -0
  222. package/src/tools/advisor/advisorDecision.ts +85 -0
  223. package/src/tools/agent/agent.js +18 -5
  224. package/src/tools/agent/agent.ts +21 -7
  225. package/src/tools/agent/agentControl.js +246 -0
  226. package/src/tools/agent/agentControl.ts +284 -0
  227. package/src/tools/agent/agentTaskService.js +40 -1
  228. package/src/tools/agent/agentTaskService.ts +44 -1
  229. package/src/tools/agent/agentTypes.js +14 -2
  230. package/src/tools/agent/agentTypes.ts +15 -2
  231. package/src/tools/applypatch/applyPatch.js +362 -0
  232. package/src/tools/applypatch/applyPatch.ts +428 -0
  233. package/src/tools/bash/bash.js +70 -18
  234. package/src/tools/bash/bash.ts +75 -20
  235. package/src/tools/capabilities.js +10 -5
  236. package/src/tools/capabilities.ts +10 -5
  237. package/src/tools/computeruse/computerIntent.js +32 -0
  238. package/src/tools/computeruse/computerIntent.ts +46 -0
  239. package/src/tools/computeruse/telemetryLog.js +12 -0
  240. package/src/tools/computeruse/telemetryLog.ts +16 -0
  241. package/src/tools/computeruse/vision/telemetry.js +1 -0
  242. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  243. package/src/tools/effectiveToolSet.js +4 -0
  244. package/src/tools/effectiveToolSet.ts +4 -0
  245. package/src/tools/index.js +21 -2
  246. package/src/tools/index.ts +33 -2
  247. package/src/tools/powershell/powershell.js +18 -1
  248. package/src/tools/powershell/powershell.ts +18 -2
  249. package/src/tools/presentresult/presentresult.js +6 -15
  250. package/src/tools/presentresult/presentresult.ts +6 -15
  251. package/src/tools/read/read.js +69 -11
  252. package/src/tools/read/read.ts +70 -11
  253. package/src/tools/shared/fileUtils.js +1 -2
  254. package/src/tools/shared/fileUtils.ts +1 -2
  255. package/src/tools/shared/permanentDeleteGuard.js +34 -3
  256. package/src/tools/shared/permanentDeleteGuard.ts +43 -6
  257. package/src/tools/shared/toolOutputStore.js +23 -1
  258. package/src/tools/shared/toolOutputStore.ts +22 -1
  259. package/src/tools/skill/skill.js +9 -3
  260. package/src/tools/skill/skill.ts +8 -4
  261. package/src/tools/toolPromptGuides.js +117 -0
  262. package/src/tools/toolPromptGuides.ts +137 -0
  263. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  264. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  265. package/src/tools/webbrowser/browser.js +27 -11
  266. package/src/tools/webbrowser/browser.ts +68 -24
  267. package/src/tools/webbrowser/browserAutomation.js +329 -0
  268. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  269. package/src/tools/webbrowser/browserAxState.js +97 -0
  270. package/src/tools/webbrowser/browserAxState.ts +142 -0
  271. package/src/tools/webbrowser/browserBatch.js +1578 -0
  272. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  273. package/src/tools/webbrowser/browserCdp.js +208 -0
  274. package/src/tools/webbrowser/browserCdp.ts +255 -0
  275. package/src/tools/webbrowser/browserConditions.js +24 -0
  276. package/src/tools/webbrowser/browserConditions.ts +45 -0
  277. package/src/tools/webbrowser/browserContent.js +281 -0
  278. package/src/tools/webbrowser/browserContent.ts +438 -0
  279. package/src/tools/webbrowser/browserControl.js +131 -30
  280. package/src/tools/webbrowser/browserControl.ts +210 -50
  281. package/src/tools/webbrowser/browserDaemon.js +22 -14
  282. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  283. package/src/tools/webbrowser/browserFrames.js +47 -0
  284. package/src/tools/webbrowser/browserFrames.ts +54 -0
  285. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  286. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  287. package/src/tools/webbrowser/browserLocator.js +140 -0
  288. package/src/tools/webbrowser/browserLocator.ts +194 -0
  289. package/src/tools/webbrowser/browserOutcome.js +10 -17
  290. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  291. package/src/tools/webbrowser/browserRecovery.js +58 -0
  292. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  293. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  294. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  295. package/src/tools/webbrowser/browserService.js +28 -2
  296. package/src/tools/webbrowser/browserService.ts +49 -9
  297. package/src/tools/webbrowser/browserStream.js +132 -33
  298. package/src/tools/webbrowser/browserStream.ts +224 -50
  299. package/src/tools/webbrowser/browserTabs.js +48 -15
  300. package/src/tools/webbrowser/browserTabs.ts +178 -96
  301. package/src/tools/webbrowser/webbrowser.js +683 -144
  302. package/src/tools/webbrowser/webbrowser.ts +979 -236
  303. package/src/tools/webfetch/preapproved.js +0 -2
  304. package/src/tools/webfetch/preapproved.ts +0 -2
  305. package/src/tools/websearch/websearch.js +129 -8
  306. package/src/tools/websearch/websearch.ts +138 -6
  307. package/src/types.ts +450 -42
  308. package/src/ui/App.js +377 -58
  309. package/src/ui/App.tsx +576 -111
  310. package/src/ui/LiveArea.js +14 -8
  311. package/src/ui/LiveArea.tsx +14 -10
  312. package/src/ui/MessageList.js +63 -20
  313. package/src/ui/MessageList.tsx +101 -16
  314. package/src/ui/ModelPicker.js +7 -4
  315. package/src/ui/ModelPicker.tsx +55 -8
  316. package/src/ui/hooks/useChat.js +152 -163
  317. package/src/ui/hooks/useChat.ts +396 -334
  318. package/src/ui/loginCommand.js +56 -0
  319. package/src/ui/loginCommand.ts +63 -0
  320. package/src/ui/toolProgress.js +41 -0
  321. package/src/ui/toolProgress.ts +44 -0
  322. package/src/web/browserBridge.js +20 -2
  323. package/src/web/browserBridge.ts +20 -2
  324. package/src/web/protocol.ts +1897 -194
  325. package/workflows/adaptive-research/workflow.mjs +86 -0
  326. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  327. package/workflows/e2e-llm/workflow.mjs +52 -0
  328. package/workflows/e2e-smoke/workflow.mjs +59 -0
  329. package/workflows/e2e-vision-schema/README.md +48 -0
  330. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  331. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  332. package/workflows/file-census/README.md +14 -0
  333. package/workflows/file-census/scripts/.gitkeep +2 -0
  334. package/workflows/file-census/workflow.mjs +110 -0
  335. package/workflows/goal/README.md +166 -0
  336. package/workflows/goal/prompts/audit.md +57 -0
  337. package/workflows/goal/prompts/contract.md +56 -0
  338. package/workflows/goal/prompts/iterate.md +37 -0
  339. package/workflows/goal/workflow.mjs +501 -0
  340. package/workflows/illustrate/README.md +90 -0
  341. package/workflows/illustrate/assets/engines.json +20 -0
  342. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  343. package/workflows/illustrate/assets/extract-bing.js +33 -0
  344. package/workflows/illustrate/assets/extract-google.js +31 -0
  345. package/workflows/illustrate/workflow.mjs +301 -0
  346. package/workflows/plan/workflow.mjs +389 -0
  347. package/workflows/question-crops/README.md +35 -0
  348. package/workflows/question-crops/prompts/inventory.md +23 -0
  349. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  350. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  351. package/workflows/question-crops/workflow.mjs +172 -0
  352. package/workflows/ralph-loop/workflow.mjs +162 -0
  353. package/workflows/research/DESIGN.md +449 -0
  354. package/workflows/research/README.md +74 -0
  355. package/workflows/research/prompts/s0-goal.md +43 -0
  356. package/workflows/research/prompts/s1-early-exit.md +22 -0
  357. package/workflows/research/prompts/s1-map.md +58 -0
  358. package/workflows/research/prompts/s2-options.md +53 -0
  359. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  360. package/workflows/research/prompts/s4-verify.md +74 -0
  361. package/workflows/research/prompts/s5-synthesis.md +81 -0
  362. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  363. package/workflows/research/prompts/s6-package.md +32 -0
  364. package/workflows/research/scripts/build-report.mjs +98 -0
  365. package/workflows/research/workflow.mjs +288 -0
  366. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  367. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  368. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  369. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  370. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  371. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  372. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  373. package/workflows/wrong-question-docx/README.md +55 -0
  374. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  375. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  376. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  377. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  378. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  379. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  380. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  381. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  382. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  383. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  384. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  385. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  386. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  387. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  388. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  389. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  390. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  391. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  392. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  393. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  394. package/plugins/workflow-runner/src/expressions.js +0 -618
  395. package/plugins/workflow-runner/src/expressions.ts +0 -622
  396. package/plugins/workflow-runner/src/loader.js +0 -573
  397. package/plugins/workflow-runner/src/loader.ts +0 -721
  398. package/plugins/workflow-runner/src/multimodal.js +0 -38
  399. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  400. package/plugins/workflow-runner/src/recovery.js +0 -119
  401. package/plugins/workflow-runner/src/recovery.ts +0 -149
  402. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  403. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  404. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -41
  405. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -50
  406. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  407. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  408. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  409. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  410. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  411. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  412. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  413. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  414. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -208
  415. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -256
  416. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -58
  417. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -68
  418. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  419. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  420. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  421. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  422. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  423. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  424. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -147
  425. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  426. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  427. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -226
  428. package/plugins/workflow-runner/test/expressions.test.ts +0 -397
  429. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  430. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  431. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  432. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  433. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  434. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  435. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  436. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  437. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  438. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  439. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -87
  440. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  441. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  442. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -220
  443. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  444. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  445. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -379
  446. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  447. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -150
  448. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  449. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -338
  450. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -270
  451. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  452. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  453. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  454. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  455. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  456. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  457. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  458. package/src/advisorState.js +0 -22
  459. package/src/cli/configWizard.js +0 -293
  460. package/src/tools/toolProgressBridge.js +0 -48
  461. package/workflows/adaptive-research.yaml +0 -50
  462. package/workflows/book-review-short.yaml +0 -125
  463. package/workflows/e2e-write-greet.yaml +0 -31
  464. package/workflows/illustrate.yaml +0 -227
  465. package/workflows/plan.yaml +0 -470
  466. package/workflows/ppt.yaml +0 -1670
  467. package/workflows/ralph-loop.yaml +0 -199
  468. package/workflows/schema.json +0 -176
  469. package/workflows/webppt.yaml +0 -496
  470. package/workflows/wechat-reading-shots.yaml +0 -315
  471. package/workflows/word.yaml +0 -720
  472. package/workflows/youtube-shorts.yaml +0 -202
@@ -1,250 +0,0 @@
1
- /**
2
- * test/webppt.load.test.ts
3
- * ------------------------------------------------------------
4
- * 锁定 workflows/webppt.yaml(网页设计驱动版)的「可解析 + 关键骨架」:
5
- * - loader 校验通过(含 type:loop while 模式 + do[] + break 嵌套)
6
- * - 11 个顶层步、title 分母 /11、inputs 含 topic(greedy)/style/mode/illustrations/out
7
- * - 新流程三段:设计文档(design.json/md+img_plan) → 对抗评审 → 分批生成 loop(deck_pages_check 收口)
8
- * - 复用段衔接正确:img_route_gate 吃 design.json、生图先于闸门、export 只查重叠+每页≤3次+页数兜底
9
- * - 所有 ${} 表达式可被引擎解析(防 bash 参数扩展等畸形语法)
10
- *
11
- * 定位法:packageRoot/workflows/webppt.yaml + parseWorkflowFile。
12
- * 注意:webppt(topic 驱动)与 ppt(文档素材驱动,见 ppt.load.test.ts)是**两个并列的独立工作流**,
13
- * 内部 name 分别为 webppt / ppt,互不影响——改 ppt 时绝不动 webppt(用户红线)。
14
- */
15
-
16
- import { describe, expect, it } from 'bun:test';
17
- import { join } from 'node:path';
18
-
19
- import { interpolate } from '../src/expressions.js';
20
- import { parseWorkflowFile } from '../src/loader.js';
21
- import { VarStack } from '../src/types.js';
22
- import type { StepDef } from '../src/types.js';
23
-
24
- const webpptPath = join(
25
- import.meta.dir.replace(/[/\\]test$/, ''), // plugins/workflow-runner
26
- '..', // plugins
27
- '..', // 仓库根
28
- 'workflows',
29
- 'webppt.yaml',
30
- );
31
-
32
- describe('workflows/webppt.yaml', () => {
33
- it('解析通过且 11 步骨架正确', async () => {
34
- const def = await parseWorkflowFile(webpptPath);
35
-
36
- expect(def.name).toBe('webppt');
37
- expect(typeof def.description).toBe('string');
38
-
39
- // inputs:topic(greedy, 首位) + 高级覆盖项
40
- const inputNames = (def.inputs ?? []).map((i) => i.name);
41
- expect(inputNames).toEqual(
42
- expect.arrayContaining(['topic', 'illustrations', 'style', 'mode', 'out', 'image_intensity']),
43
- );
44
- expect(inputNames[0]).toBe('topic');
45
- // AI 生图积极性配置(2026-06-19):enum minimal/balanced/rich,默认 balanced
46
- const intensity = (def.inputs ?? []).find((i) => i.name === 'image_intensity');
47
- expect(intensity?.default).toBe('balanced');
48
- expect((def.inputs ?? []).find((i) => i.name === 'topic')?.greedy).toBe(true);
49
- expect(inputNames).not.toContain('pages'); // 页数内容驱动,不是输入
50
-
51
- // 11 个顶层步 + title 分母 /11
52
- const ids = def.steps.map((s) => s.id);
53
- for (const id of [
54
- 'stage0_clarify',
55
- 'stage_research',
56
- 'stage_design_doc',
57
- 'stage_design_review',
58
- 'stage_build_loop',
59
- 'stage_img_route_gate',
60
- 'stage_gen_images',
61
- 'stage_export',
62
- 'verify_output',
63
- 'cleanup_intermediates',
64
- 'final_report',
65
- ]) {
66
- expect(ids).toContain(id);
67
- }
68
- expect(def.steps.length).toBe(11);
69
- for (const s of def.steps) {
70
- expect(String(s.title)).toContain('/11');
71
- }
72
-
73
- // 收尾报告 echo;artifacts 只列最终交付物、不在被 rm 的 ./build 下
74
- expect(def.steps.find((s) => s.id === 'final_report')?.type).toBe('echo');
75
- const declared = def.artifacts ?? [];
76
- expect(declared).toContain('./out/deck.pptx');
77
- for (const a of declared) expect(a.startsWith('./build')).toBe(false);
78
- });
79
-
80
- it('需求分析步:style 为空时必问视觉样式(VI 选项 + 自定义输入),AskUserQuestion 可用', async () => {
81
- const def = await parseWorkflowFile(webpptPath);
82
- const s0 = def.steps.find((s) => s.id === 'stage0_clarify');
83
- expect(s0?.allowed_tools).toContain('AskUserQuestion');
84
- const a = String(s0?.agent);
85
- // 样式问是「必做」的强约束(防回归:弱模型曾跳过样式题直接进下一步)。
86
- expect(a).toContain('必须调用一次 AskUserQuestion');
87
- expect(a).toContain('style 为空');
88
- expect(a).toContain('替用户拍板样式');
89
- // 仍提供几个最贴合主题的 VI 选项 + 自定义输入。
90
- expect(a).toContain('最贴合本主题');
91
- expect(a).toContain('自定义');
92
- });
93
-
94
- it('设计文档步:产 design.md/json + img_plan,含构图法/渲染决策/呼应提示词/背景变化', async () => {
95
- const def = await parseWorkflowFile(webpptPath);
96
- const dd = def.steps.find((s) => s.id === 'stage_design_doc');
97
- expect(typeof dd?.agent).toBe('string');
98
- const a = String(dd?.agent);
99
- expect(a).toContain('design.md');
100
- expect(a).toContain('design.json');
101
- expect(a).toContain('img_plan.json');
102
- expect(a).toContain('composition'); // 空间构图法
103
- expect(a).toContain('render'); // 元素级渲染决策
104
- expect(a).toContain('呼应'); // 生图提示词与文案呼应(治"搬文案")
105
- expect(a).toContain('背景'); // 页面级背景变化
106
- expect(a).toContain('每页 ≥1 视觉元素'); // 区别于 Word
107
- // 配色解耦(用户裁决):VI 管底,图表分类色 + 插图内容色
108
- expect(a).toContain('配色解耦');
109
- expect(a).toContain('分类色');
110
- // 保留 visual.{route,note} 字段名 → 下游 image_plan_lint 兼容
111
- expect(a).toContain('visual');
112
- expect(a).toContain('route');
113
- // AI 生图积极性配置接入设计步(2026-06-19)
114
- expect(a).toContain('${inputs.image_intensity}'); // 积极性配置驱动配图分流
115
- expect(a).toContain('积极性');
116
- // design.json 紧凑单行(治 doubao 推理模型写大 JSON 尾部截断 Unterminated string)
117
- expect(a).toContain('紧凑单行');
118
- expect(String(dd?.done_when)).toContain('design.json');
119
- // 编辑式最高标准(第三轮·webppt 也转编辑式,用户授权覆盖红线):强制默认 + 每页背景层 + cards 罕见例外
120
- expect(a).toContain('编辑式最高标准·强制默认');
121
- expect(a).toContain('每个内容页都必须有背景层');
122
- expect(a).toContain('卡片墙 / 网格 / 表格 = 罕见例外');
123
- expect(a).toContain('`cards` 已降为罕见例外、默认别选');
124
- // 第五轮:AI 背景默认(渐变只作失败兜底)+ 动笔前三问/苹果式精炼
125
- expect(a).toContain('默认高清 AI 图,渐变只作失败兜底');
126
- expect(a).toContain('优先配高清 AI 全幅底图');
127
- expect(a).toContain('动笔前三问');
128
- expect(a).toContain('MacBook Pro');
129
- });
130
-
131
- it('对抗评审步:回顾原始需求挑刺并修订定稿(全自动、无人工 pause)', async () => {
132
- const def = await parseWorkflowFile(webpptPath);
133
- const rv = def.steps.find((s) => s.id === 'stage_design_review');
134
- expect(typeof rv?.agent).toBe('string');
135
- const a = String(rv?.agent);
136
- expect(a).toContain('对抗');
137
- expect(a).toContain('原始需求');
138
- expect(a).toContain('修订');
139
- // 稀疏页标准(用户裁决):不再一律禁「一句话占一页」,而是 ≤20% 且必须配图/底图避免简陋。
140
- expect(a).toContain('20%');
141
- expect(a).toContain('简陋');
142
- // 配色解耦 + 字号可读性评审子项(用户裁决)
143
- expect(a).toContain('分类色'); // 图表数据系列可区分
144
- expect(a).toContain('38px'); // 正文放映级可读(≈1.5×)
145
- // 新增评审子项(2026-06-19):封面对比 / 真实 DOM 文本 / 稀疏页满画布
146
- expect(a).toContain('对比度'); // 封面/章节文字在浅底图上对比达标
147
- expect(a).toContain('DOM 文本'); // 文字皆真实 DOM 文本(无伪元素/烧图文字)
148
- expect(a).toContain('占满画布'); // list/目录满宽不留空半
149
- // 改 design 文档(Edit/Write),不是只读评审
150
- expect(rv?.allowed_tools).toContain('Edit');
151
- // 不是 pause(webppt 定位=自动产出,无人工打断)
152
- expect(rv?.type).not.toBe('pause');
153
- });
154
-
155
- it('分批生成 loop:while + fresh_context + deck_pages_check 收口(防大 deck 烂尾)', async () => {
156
- const def = await parseWorkflowFile(webpptPath);
157
- const loop = def.steps.find((s) => s.id === 'stage_build_loop');
158
- expect(loop?.type).toBe('loop');
159
- expect(loop?.fresh_context).toBe(true); // 每轮重置 history 防膨胀
160
- expect(loop?.over).toBeUndefined(); // while 模式(非 for-each)
161
- expect(typeof loop?.max_iterations === 'number' || typeof loop?.max_iterations === 'string').toBe(true);
162
- const dos = (loop?.do ?? []) as StepDef[];
163
- const batch = dos.find((s) => s.id === 'build_batch');
164
- const brk = dos.find((s) => s.id === 'build_done');
165
- // 生成步:跑 deck_pages_check 自查 + ≤5 页 + 每页视觉元素 + COMPLETE 标记
166
- expect(typeof batch?.agent).toBe('string');
167
- expect(String(batch?.agent)).toContain('deck_pages_check.py');
168
- expect(String(batch?.agent)).toContain('WEBPPT_BUILD_COMPLETE');
169
- expect(String(batch?.agent)).toContain('5 页'); // 每轮最多 5 页
170
- // 字号阶梯(放映级正文 ≈1.5×)+ 配色解耦(图表分类色)注入生成步
171
- expect(String(batch?.agent)).toContain('38px'); // 正文/卡片正文放映级下限(≈1.5×)
172
- expect(String(batch?.agent)).toContain('分类色'); // 图表数据系列分类色
173
- // 文本必须真实 DOM(禁伪元素/烧图)+ 封面对比 + 稀疏页满画布(2026-06-19)
174
- expect(String(batch?.agent)).toContain('真实 DOM 文本'); // 禁 ::before/::after / 禁烧进图
175
- expect(String(batch?.agent)).toContain('::before/::after'); // 明示禁用伪元素文字
176
- expect(String(batch?.agent)).toContain('对比度铁律'); // 封面浅底图深字+浅板
177
- expect(String(batch?.agent)).toContain('占满整宽'); // list/目录满宽不留空半
178
- // 递归切图:可拖结构离散 HTML + 卡片填实/不溢出(2026-06-19)
179
- expect(String(batch?.agent)).toContain('可拖结构'); // 离散 HTML 元素、递归切成各自可拖对象
180
- expect(String(batch?.agent)).toContain('递归切'); // 导出递归切
181
- expect(String(batch?.agent)).toContain('卡片/分组填充不足'); // 填实/不溢出 WARNING 提示
182
- // 对比度铁律 + 文案精炼说人话 + 排不下自救(2026-06-19 第三轮)
183
- expect(String(batch?.agent)).toContain('文字对比度铁律'); // 深底白字、绝不深底深字
184
- expect(String(batch?.agent)).toContain('说人话'); // 文案精炼·类比/例子
185
- expect(String(batch?.agent)).toContain('两列'); // 排不下改 grid 两列
186
- // deck 纵向流式(人可滚动审阅,不再各页叠在一起)
187
- expect(String(batch?.agent)).toContain('流式'); // 纵向流式版式
188
- expect(String(batch?.agent)).toContain('position:relative'); // 每页 position:relative 排开
189
- expect(batch?.capture).toBeTruthy();
190
- // break:页数 COMPLETE 时跳出循环
191
- expect(brk?.type).toBe('break');
192
- expect(String(brk?.when)).toContain('WEBPPT_BUILD_COMPLETE');
193
- });
194
-
195
- it('衔接:img_route_gate 吃 design.json、生图先于闸门、export 只查重叠+每页≤3次+页数兜底', async () => {
196
- const def = await parseWorkflowFile(webpptPath);
197
- const ids = def.steps.map((s) => s.id);
198
-
199
- // 配图分流闸门:image_plan_lint 的 --outline 直接吃 design.json
200
- const gate = def.steps.find((s) => s.id === 'stage_img_route_gate');
201
- expect(String(gate?.agent)).toContain('image_plan_lint.py');
202
- expect(String(gate?.agent)).toContain('--outline ./build/design.json');
203
- expect(String(gate?.done_when)).toContain('img_route_ok');
204
- // 顺序:build_loop → img_route_gate → gen_images
205
- expect(ids.indexOf('stage_img_route_gate')).toBeGreaterThan(ids.indexOf('stage_build_loop'));
206
- expect(ids.indexOf('stage_img_route_gate')).toBeLessThan(ids.indexOf('stage_gen_images'));
207
- // 生图先于构图闸门(闸门量含图成品)——分层/时序不变量
208
- expect(ids.indexOf('stage_gen_images')).toBeLessThan(ids.indexOf('stage_export'));
209
-
210
- // 导出步:页数兜底 + measure-only 渲染含图成品 + 只查重叠 + 修法序(移动>精炼>缩字≤20%) + 每页≤3次配额 + 哨兵
211
- const exp = def.steps.find((s) => s.id === 'stage_export');
212
- expect(String(exp?.agent)).toContain('deck_pages_check.py'); // 页数兜底
213
- expect(String(exp?.agent)).toContain('layout_balance.py');
214
- expect(String(exp?.agent)).toContain('--measure-only'); // 渲染真实 deck 量含图成品
215
- expect(String(exp?.agent)).toContain('重叠'); // 不可妥协硬门之一
216
- expect(String(exp?.agent)).toContain('截图夹带文本'); // 底图/切图绝不能带 HTML 文字(硬门,2026-06-19)
217
- // 改 deck.html 只准用 Edit、禁 Bash 文本替换(治弱模型 type/findstr/PowerShell 把 HTML 改崩→halt,2026-06-19 第三轮)
218
- expect(String(exp?.agent)).toContain('只准用 Edit');
219
- expect(String(exp?.agent)).toContain('编码损坏');
220
- expect(String(exp?.agent)).toContain('移动'); // 修重叠优先移动/重排(不是一味缩字)
221
- expect(String(exp?.agent)).toContain('20%'); // 缩字单次封顶 20%
222
- expect(String(exp?.agent)).toContain('3 次'); // 每页最多修 3 次
223
- expect(String(exp?.agent)).toContain('放行'); // 第 3 次后必放行
224
- expect(String(exp?.done_when)).toContain('layout_ok');
225
- expect(String(exp?.done_when)).toContain('inputs.out');
226
- expect(exp?.maxTurns).toBe(200);
227
- });
228
-
229
- it('所有 ${} 表达式都能被引擎解析(不含畸形语法)', async () => {
230
- const def = await parseWorkflowFile(webpptPath);
231
- const vars = new VarStack();
232
- const inputsObj: Record<string, unknown> = {};
233
- for (const inp of def.inputs ?? []) inputsObj[inp.name] = inp.default ?? '';
234
- vars.setGlobal('inputs', inputsObj);
235
-
236
- const strings: string[] = [];
237
- const walk = (v: unknown): void => {
238
- if (typeof v === 'string') strings.push(v);
239
- else if (Array.isArray(v)) for (const x of v) walk(x);
240
- else if (v && typeof v === 'object')
241
- for (const x of Object.values(v as Record<string, unknown>)) walk(x);
242
- };
243
- walk(def);
244
- expect(strings.length).toBeGreaterThan(10);
245
- for (const s of strings) {
246
- if (!s.includes('${')) continue;
247
- expect(() => interpolate(s, vars)).not.toThrow();
248
- }
249
- });
250
- });
@@ -1,208 +0,0 @@
1
- /**
2
- * test/word.load.test.ts
3
- * ------------------------------------------------------------
4
- * 锁定 workflows/word.yaml(素材驱动知乎深度长文 Word 工作流)的
5
- * 「可解析 + 关键骨架」:
6
- * - name=word,最终产物是 ./out/article.docx
7
- * - inputs 支持 topic(greedy) / source / out / image_intensity / quality / debug_keep_build
8
- * - Markdown-first:material → outline → article.md → image_map/img_plan → docx skill → OPC
9
- * - 客户图必须使用;需要解释型视觉时积极文生图,提示词必须结合上下文
10
- * - 不引入 PPT 专属 deck.html / design.json / 构图门 / PPTX 导出链路
11
- */
12
-
13
- import { describe, expect, it } from 'bun:test';
14
- import { join } from 'node:path';
15
-
16
- import { parseWorkflowFile } from '../src/loader.js';
17
-
18
- const wordPath = join(
19
- import.meta.dir.replace(/[/\\]test$/, ''), // plugins/workflow-runner
20
- '..', // plugins
21
- '..', // minimal-agent 根
22
- 'workflows',
23
- 'word.yaml',
24
- );
25
-
26
- describe('workflows/word.yaml(素材驱动·知乎深度长文 Word)', () => {
27
- it('解析通过且 name/artifacts/inputs 骨架正确', async () => {
28
- const def = await parseWorkflowFile(wordPath);
29
-
30
- expect(def.name).toBe('word');
31
- expect(typeof def.description).toBe('string');
32
- expect(def.description).toContain('知乎深度文章');
33
-
34
- const declared = def.artifacts ?? [];
35
- expect(declared).toContain('./out/article.docx');
36
- for (const a of declared) expect(a.startsWith('./build')).toBe(false);
37
-
38
- const inputNames = (def.inputs ?? []).map((i) => i.name);
39
- expect(inputNames).toEqual(
40
- expect.arrayContaining([
41
- 'topic',
42
- 'source',
43
- 'out',
44
- 'image_intensity',
45
- 'quality',
46
- 'debug_keep_build',
47
- ]),
48
- );
49
- expect(inputNames[0]).toBe('topic');
50
- expect((def.inputs ?? []).find((i) => i.name === 'topic')?.greedy).toBe(true);
51
- expect((def.inputs ?? []).find((i) => i.name === 'out')?.default).toBe(
52
- './out/article.docx',
53
- );
54
- });
55
-
56
- it('步骤骨架包含素材、识图、长文、图文混排、docx 导出与校验', async () => {
57
- const def = await parseWorkflowFile(wordPath);
58
- const ids = def.steps.map((s) => s.id);
59
-
60
- for (const id of [
61
- 'stage0_analyze',
62
- 'stage_extract',
63
- 'stage_vision_loop',
64
- 'stage_assemble_material',
65
- 'stage_outline',
66
- 'stage_write_article',
67
- 'stage_img_plan',
68
- 'stage_gen_images',
69
- 'stage_generated_image_gate',
70
- 'stage_finalize_markdown',
71
- 'stage_topic_image_gate',
72
- 'stage_customer_image_gate',
73
- 'stage_export_docx',
74
- 'stage_verify_docx',
75
- 'final_report',
76
- ]) {
77
- expect(ids).toContain(id);
78
- }
79
-
80
- expect(def.steps.find((s) => s.id === 'stage_export_docx')?.skill).toBe(
81
- 'docx',
82
- );
83
- expect(def.steps.find((s) => s.id === 'stage_verify_docx')?.tool).toBe(
84
- 'Bash',
85
- );
86
- expect(def.steps.find((s) => s.id === 'final_report')?.type).toBe('echo');
87
- });
88
-
89
- it('锁定 Word 核心约束:知乎长文、客户图全用、上下文生图、docx OPC', async () => {
90
- const def = await parseWorkflowFile(wordPath);
91
- const all = JSON.stringify(def, null, 2);
92
-
93
- for (const needle of [
94
- '知乎深度文章',
95
- '总结',
96
- '扩写',
97
- '观点',
98
- '论证',
99
- '图文混排',
100
- '所有客户图',
101
- '必须使用',
102
- 'source_file',
103
- 'final_file',
104
- 'article_section',
105
- 'material.md',
106
- 'article.md',
107
- 'skill: docx',
108
- 'markdown-implicit_figures',
109
- 'implicit_figures',
110
- 'OPC',
111
- 'opc_check.py',
112
- 'WORD_DOCX_PNG_CONTENT_TYPE_ADDED',
113
- '无客户图',
114
- '纯 topic',
115
- '至少 3',
116
- '至少 5',
117
- '不得为空',
118
- 'text-to-image',
119
- ]) {
120
- expect(all).toContain(needle);
121
- }
122
-
123
- expect(all).toContain('现代科技风');
124
- expect(all).toContain('知乎配图');
125
- expect(all).toContain('抽象背景');
126
- expect(all).toContain('禁止空泛');
127
- expect(all).toContain('避免 Markdown 图片 alt 文本被渲染成额外可见图注');
128
- });
129
-
130
- it('纯 topic 模式:无客户图也必须按 image_intensity 生成文生图并闸门校验', async () => {
131
- const def = await parseWorkflowFile(wordPath);
132
- const gate = def.steps.find((s) => s.id === 'stage_topic_image_gate');
133
- const all = JSON.stringify(def, null, 2);
134
- const gateText = JSON.stringify(gate, null, 2);
135
- const gateCommand = String(gate?.args?.command ?? '');
136
-
137
- expect(gate?.tool).toBe('Bash');
138
- expect(gateText).toContain('pure topic mode');
139
- expect(gateText).toContain('WORD_TOPIC_IMAGE_GATE_FAILED');
140
- expect(gateCommand).toContain('"minimal": 1');
141
- expect(gateCommand).toContain('"balanced": 3');
142
- expect(gateCommand).toContain('"rich": 5');
143
- expect(gateText).toContain('img_plan.json');
144
- expect(gateText).toContain('image_map.json');
145
- expect(gateText).toContain('article.md');
146
- expect(gateText).toContain('text-to-image');
147
-
148
- for (const needle of [
149
- 'img_plan.json` 不得为空',
150
- '`minimal`:至少 1 张',
151
- '`balanced`:至少 3 张',
152
- '`rich`:至少 5 张',
153
- '`file`、`mode`、`aspect`、`prompt`',
154
- '`mode` 必须是 `text-to-image`',
155
- '章节观点、上下文、场景和图注意图',
156
- ]) {
157
- expect(all).toContain(needle);
158
- }
159
- });
160
-
161
- it('stage_extract 清理旧素材残留,纯 topic 不会误读上次 source/assets', async () => {
162
- const def = await parseWorkflowFile(wordPath);
163
- const extract = def.steps.find((s) => s.id === 'stage_extract');
164
- const command = String(extract?.args?.command ?? '');
165
-
166
- expect(command).toContain('./build/source.md');
167
- expect(command).toContain('rm -rf ./build/assets');
168
- expect(command).toContain('mkdir -p ./build/assets');
169
- expect(command).toContain('./build/word_topic_image_gate.json');
170
- expect(command).toContain('./build/word_topic_image_gate.md');
171
- });
172
-
173
- it('生成配图失败时会在导出前硬失败,不会把渐变占位图交付进 Word', async () => {
174
- const def = await parseWorkflowFile(wordPath);
175
- const gate = def.steps.find((s) => s.id === 'stage_generated_image_gate');
176
- const command = String(gate?.args?.command ?? '');
177
-
178
- expect(gate?.tool).toBe('Bash');
179
- expect(gate?.onError).toBe('halt');
180
- expect(String(gate?.when)).toContain('image_generation_report.json');
181
- expect(command).toContain('qualityOk');
182
- expect(command).toContain('8192');
183
- expect(command).toContain('WORD_GENERATED_IMAGE_GATE_FAILED');
184
- });
185
-
186
- it('不包含 PPT 专属固定画布 / HTML deck / PPTX 导出链路', async () => {
187
- const def = await parseWorkflowFile(wordPath);
188
- const all = JSON.stringify(def, null, 2);
189
- const ids = def.steps.map((s) => s.id);
190
-
191
- for (const forbiddenId of [
192
- 'stage_design_doc',
193
- 'stage_build_loop',
194
- 'visual_quality_gate',
195
- 'stage_export_pptx',
196
- ]) {
197
- expect(ids).not.toContain(forbiddenId);
198
- }
199
- for (const forbidden of [
200
- 'deck.html',
201
- 'design.json',
202
- 'export_pptx',
203
- 'visual_quality_gate',
204
- ]) {
205
- expect(all).not.toContain(forbidden);
206
- }
207
- });
208
- });
@@ -1,76 +0,0 @@
1
- /**
2
- * ============================================================
3
- * test/workflows.smoke.test.ts
4
- * ------------------------------------------------------------
5
- * 内置工作流「解析+校验」冒烟测试 —— 守护「引擎对所有 workflows/*.yaml 的通用支持」。
6
- *
7
- * 为什么需要它(真实缺口):
8
- * `listWorkflows()` 对损坏 yaml 是**静默跳过**(loader.ts catch→warn→continue),
9
- * 而既有 loader 单测只显式校验了 book-review-short.yaml 一个内置工作流。
10
- * 于是若某次引擎/loader/schema 改动破坏了 plan / youtube-shorts / adaptive-research /
11
- * e2e-write-greet 等的结构,**没有任何测试会失败**——它只会被悄悄忽略。
12
- * 本文件把「每个内置工作流都能 parse + validate 通过」锁成不变量:任一被改坏即红。
13
- *
14
- * 隔离性(同 loader.test.ts 的教训):
15
- * 直接定位 packageRoot 的 workflows 目录 + `parseWorkflowFile()` 逐个解析,
16
- * **零依赖 getWorkingDir() 全局状态**,避免其它测试文件经 mock.module 留下的污染。
17
- * ============================================================
18
- */
19
-
20
- import { describe, expect, it } from 'bun:test';
21
- import { readdirSync } from 'node:fs';
22
- import { join } from 'node:path';
23
-
24
- import { parseWorkflowFile } from '../src/loader.js';
25
-
26
- // packageRoot 下的 workflows 目录(不依赖 getWorkingDir)。
27
- // import.meta.dir = plugins/workflow-runner/test;向上三级到 minimal-agent 根。
28
- // 兼容 Windows:用 [/\\] 同时匹配两种路径分隔符(同 loader.test.ts:94 的教训)。
29
- const WORKFLOWS_DIR = join(
30
- import.meta.dir.replace(/[/\\]test$/, ''), // plugins/workflow-runner
31
- '..', // plugins
32
- '..', // minimal-agent 根
33
- 'workflows',
34
- );
35
-
36
- // 内置工作流的「全集快照」:意外删除/改名任一个即红(防止悄悄少掉一个工作流)。
37
- const EXPECTED_WORKFLOWS = [
38
- 'adaptive-research',
39
- 'book-review-short',
40
- 'e2e-write-greet',
41
- 'plan',
42
- 'ppt',
43
- 'ralph-loop',
44
- 'webppt',
45
- 'word',
46
- 'youtube-shorts',
47
- ].sort();
48
-
49
- function yamlFiles(): string[] {
50
- return readdirSync(WORKFLOWS_DIR)
51
- .filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))
52
- .sort();
53
- }
54
-
55
- describe('内置 workflows/*.yaml 解析+校验冒烟', () => {
56
- // 逐个文件成测:哪个被改坏,失败信息直接点名是哪个工作流。
57
- for (const file of yamlFiles()) {
58
- it(`${file} 能被 parseWorkflowFile 解析且通过校验`, async () => {
59
- const def = await parseWorkflowFile(join(WORKFLOWS_DIR, file));
60
- expect(typeof def.name).toBe('string');
61
- expect(def.name.length).toBeGreaterThan(0);
62
- expect(def.description.length).toBeGreaterThan(0);
63
- expect(def.steps.length).toBeGreaterThan(0);
64
- });
65
- }
66
-
67
- it('内置工作流全集齐全(没有被悄悄删除/改名)', async () => {
68
- const defs = await Promise.all(
69
- yamlFiles().map((f) => parseWorkflowFile(join(WORKFLOWS_DIR, f))),
70
- );
71
- const names = defs.map((d) => d.name).sort();
72
- for (const expected of EXPECTED_WORKFLOWS) {
73
- expect(names).toContain(expected);
74
- }
75
- });
76
- });