minimal-agent 0.13.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 (470) hide show
  1. package/README.md +6 -5
  2. package/package.json +60 -4
  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 +197 -206
  16. package/plugins/workflow-runner/src/index.ts +248 -249
  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 +400 -489
  28. package/plugins/workflow-runner/src/runner.ts +488 -560
  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 +151 -307
  54. package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
  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 -211
  58. package/plugins/workflow-runner/src/types.ts +154 -623
  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 +474 -802
  68. package/plugins/workflow-runner/src/workflowState.ts +575 -970
  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/ui-design/SKILL.md +5 -2
  92. package/skills/ui-design/references/layout-composition.md +1 -1
  93. package/skills/workflow-creator/SKILL.md +344 -0
  94. package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
  95. package/skills/workflow-creator/references/api.md +216 -0
  96. package/skills/workflow-creator/references/migration.md +103 -0
  97. package/skills/workflow-creator/references/patterns.md +779 -0
  98. package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
  99. package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
  100. package/skills/workflow-creator/scripts/validate.mjs +275 -0
  101. package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
  102. package/src/advisor/advisorCoordinator.js +503 -0
  103. package/src/advisor/advisorCoordinator.ts +657 -0
  104. package/src/cli/configMenu.tsx +0 -1
  105. package/src/cli/print.js +27 -6
  106. package/src/cli/print.ts +48 -4
  107. package/src/cli/streamJson.js +5 -6
  108. package/src/cli/streamJson.ts +8 -4
  109. package/src/cli/wizards/advisorWizard.js +4 -2
  110. package/src/cli/wizards/advisorWizard.tsx +8 -2
  111. package/src/cli/wizards/contextAdvisorWizard.js +5 -4
  112. package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
  113. package/src/collaboration/taskFlow.js +115 -0
  114. package/src/collaboration/taskFlow.ts +169 -0
  115. package/src/config/configDefaults.js +41 -1
  116. package/src/config/configDefaults.ts +43 -1
  117. package/src/config/configDiagnostics.ts +2 -2
  118. package/src/config/configFile.js +40 -9
  119. package/src/config/configFile.ts +60 -11
  120. package/src/config/configService.js +419 -74
  121. package/src/config/configService.ts +703 -145
  122. package/src/config/numericLimits.js +22 -0
  123. package/src/config/numericLimits.ts +24 -0
  124. package/src/config.js +1 -0
  125. package/src/config.ts +3 -2
  126. package/src/context/budgetPlan.js +1 -1
  127. package/src/context/budgetPlan.ts +1 -1
  128. package/src/context/compact.js +7 -2
  129. package/src/context/compact.ts +9 -2
  130. package/src/context/microCompactLite.js +212 -13
  131. package/src/context/microCompactLite.ts +261 -12
  132. package/src/context/sessionRegistry.js +8 -1
  133. package/src/context/sessionRegistry.ts +18 -5
  134. package/src/context/toolResultArchive.js +72 -0
  135. package/src/context/toolResultArchive.ts +95 -0
  136. package/src/goal/errors.js +8 -0
  137. package/src/goal/errors.ts +18 -0
  138. package/src/goal/goalRuntime.js +344 -0
  139. package/src/goal/goalRuntime.ts +466 -0
  140. package/src/goal/goalStore.js +200 -0
  141. package/src/goal/goalStore.ts +219 -0
  142. package/src/goal/index.js +4 -0
  143. package/src/goal/index.ts +4 -0
  144. package/src/goal/statusMapping.js +71 -0
  145. package/src/goal/statusMapping.ts +95 -0
  146. package/src/goal/types.js +7 -0
  147. package/src/goal/types.ts +179 -0
  148. package/src/goal/workflowController.js +306 -0
  149. package/src/goal/workflowController.ts +360 -0
  150. package/src/harness/evidenceLedger.js +2 -0
  151. package/src/harness/evidenceLedger.ts +1 -0
  152. package/src/harness/stallGuard.js +9 -3
  153. package/src/harness/stallGuard.ts +7 -3
  154. package/src/images/imageResolver.js +161 -0
  155. package/src/images/imageResolver.ts +189 -0
  156. package/src/infra/verification.js +34 -5
  157. package/src/infra/verification.ts +39 -4
  158. package/src/llm/client.js +79 -21
  159. package/src/llm/client.ts +182 -35
  160. package/src/llm/gatewayClient.js +201 -0
  161. package/src/llm/gatewayClient.ts +299 -0
  162. package/src/llm/messageProvenance.js +46 -0
  163. package/src/llm/messageProvenance.ts +58 -0
  164. package/src/llm/modelProvider.js +1 -0
  165. package/src/llm/modelProvider.ts +22 -0
  166. package/src/llm/providers/anthropicFormat.js +108 -1
  167. package/src/llm/providers/anthropicFormat.ts +115 -4
  168. package/src/llm/providers/openaiFormat.js +9 -0
  169. package/src/llm/providers/openaiFormat.ts +12 -3
  170. package/src/loop.js +319 -54
  171. package/src/loop.ts +373 -57
  172. package/src/main.js +4 -1
  173. package/src/main.tsx +4 -1
  174. package/src/managedExecution/index.js +2 -0
  175. package/src/managedExecution/index.ts +2 -0
  176. package/src/managedExecution/registry.js +15 -0
  177. package/src/managedExecution/registry.ts +20 -0
  178. package/src/managedExecution/types.js +1 -0
  179. package/src/managedExecution/types.ts +86 -0
  180. package/src/modelRef.js +9 -0
  181. package/src/modelRef.ts +31 -0
  182. package/src/multimodal.js +14 -28
  183. package/src/multimodal.ts +17 -33
  184. package/src/net/lanDiscovery.js +65 -0
  185. package/src/net/lanDiscovery.ts +82 -0
  186. package/src/plugin-sdk.js +28 -3
  187. package/src/plugin-sdk.ts +39 -6
  188. package/src/plugins/pluginApi.ts +16 -1
  189. package/src/plugins/pluginLoader.js +4 -0
  190. package/src/plugins/pluginLoader.ts +6 -0
  191. package/src/plugins/pluginRunner.js +139 -7
  192. package/src/plugins/pluginRunner.ts +173 -9
  193. package/src/plugins/slashFallback.js +113 -0
  194. package/src/plugins/slashFallback.ts +137 -0
  195. package/src/prompts/policyRegistry.js +12 -32
  196. package/src/prompts/policyRegistry.ts +15 -32
  197. package/src/prompts/promptAssembly.js +103 -12
  198. package/src/prompts/promptAssembly.ts +114 -12
  199. package/src/prompts/skillList.js +21 -3
  200. package/src/prompts/skillList.ts +27 -2
  201. package/src/prompts/stableSystemPrompt.js +18 -0
  202. package/src/prompts/stableSystemPrompt.ts +33 -0
  203. package/src/runtime/agentRuntimeContext.js +8 -2
  204. package/src/runtime/agentRuntimeContext.ts +17 -4
  205. package/src/session/runAgentTurn.js +78 -12
  206. package/src/session/runAgentTurn.ts +105 -23
  207. package/src/session/runTurn.js +10 -9
  208. package/src/session/runTurn.ts +17 -8
  209. package/src/session/sessionState.ts +2 -0
  210. package/src/team/auth.js +186 -0
  211. package/src/team/auth.ts +298 -0
  212. package/src/team/cli.js +105 -0
  213. package/src/team/cli.ts +122 -0
  214. package/src/team/onlineToolContract.js +64 -0
  215. package/src/team/onlineToolContract.ts +109 -0
  216. package/src/team/toolPolicy.js +36 -0
  217. package/src/team/toolPolicy.ts +75 -0
  218. package/src/tools/advisor/advisor.js +90 -46
  219. package/src/tools/advisor/advisor.ts +100 -47
  220. package/src/tools/advisor/advisorDecision.js +71 -0
  221. package/src/tools/advisor/advisorDecision.ts +85 -0
  222. package/src/tools/agent/agent.js +18 -5
  223. package/src/tools/agent/agent.ts +21 -7
  224. package/src/tools/agent/agentControl.js +246 -0
  225. package/src/tools/agent/agentControl.ts +284 -0
  226. package/src/tools/agent/agentTaskService.js +40 -1
  227. package/src/tools/agent/agentTaskService.ts +44 -1
  228. package/src/tools/agent/agentTypes.js +14 -2
  229. package/src/tools/agent/agentTypes.ts +15 -2
  230. package/src/tools/applypatch/applyPatch.js +362 -0
  231. package/src/tools/applypatch/applyPatch.ts +428 -0
  232. package/src/tools/bash/bash.js +22 -15
  233. package/src/tools/bash/bash.ts +23 -17
  234. package/src/tools/capabilities.js +10 -5
  235. package/src/tools/capabilities.ts +10 -5
  236. package/src/tools/computeruse/computerIntent.js +32 -0
  237. package/src/tools/computeruse/computerIntent.ts +46 -0
  238. package/src/tools/computeruse/telemetryLog.js +12 -0
  239. package/src/tools/computeruse/telemetryLog.ts +16 -0
  240. package/src/tools/computeruse/vision/telemetry.js +1 -0
  241. package/src/tools/computeruse/vision/telemetry.ts +1 -0
  242. package/src/tools/effectiveToolSet.js +4 -0
  243. package/src/tools/effectiveToolSet.ts +4 -0
  244. package/src/tools/index.js +21 -2
  245. package/src/tools/index.ts +33 -2
  246. package/src/tools/presentresult/presentresult.js +6 -15
  247. package/src/tools/presentresult/presentresult.ts +6 -15
  248. package/src/tools/read/read.js +62 -9
  249. package/src/tools/read/read.ts +63 -9
  250. package/src/tools/shared/fileUtils.js +1 -2
  251. package/src/tools/shared/fileUtils.ts +1 -2
  252. package/src/tools/shared/toolOutputStore.js +23 -1
  253. package/src/tools/shared/toolOutputStore.ts +22 -1
  254. package/src/tools/skill/skill.js +9 -3
  255. package/src/tools/skill/skill.ts +8 -4
  256. package/src/tools/toolPromptGuides.js +117 -0
  257. package/src/tools/toolPromptGuides.ts +137 -0
  258. package/src/tools/webbrowser/agentBrowserPath.js +19 -9
  259. package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
  260. package/src/tools/webbrowser/browser.js +27 -11
  261. package/src/tools/webbrowser/browser.ts +68 -24
  262. package/src/tools/webbrowser/browserAutomation.js +329 -0
  263. package/src/tools/webbrowser/browserAutomation.ts +467 -0
  264. package/src/tools/webbrowser/browserAxState.js +97 -0
  265. package/src/tools/webbrowser/browserAxState.ts +142 -0
  266. package/src/tools/webbrowser/browserBatch.js +1578 -0
  267. package/src/tools/webbrowser/browserBatch.ts +2382 -0
  268. package/src/tools/webbrowser/browserCdp.js +208 -0
  269. package/src/tools/webbrowser/browserCdp.ts +255 -0
  270. package/src/tools/webbrowser/browserConditions.js +24 -0
  271. package/src/tools/webbrowser/browserConditions.ts +45 -0
  272. package/src/tools/webbrowser/browserContent.js +281 -0
  273. package/src/tools/webbrowser/browserContent.ts +438 -0
  274. package/src/tools/webbrowser/browserControl.js +131 -34
  275. package/src/tools/webbrowser/browserControl.ts +210 -56
  276. package/src/tools/webbrowser/browserDaemon.js +22 -14
  277. package/src/tools/webbrowser/browserDaemon.ts +54 -21
  278. package/src/tools/webbrowser/browserFrames.js +47 -0
  279. package/src/tools/webbrowser/browserFrames.ts +54 -0
  280. package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
  281. package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
  282. package/src/tools/webbrowser/browserLocator.js +140 -0
  283. package/src/tools/webbrowser/browserLocator.ts +194 -0
  284. package/src/tools/webbrowser/browserOutcome.js +10 -17
  285. package/src/tools/webbrowser/browserOutcome.ts +48 -31
  286. package/src/tools/webbrowser/browserRecovery.js +58 -0
  287. package/src/tools/webbrowser/browserRecovery.ts +83 -0
  288. package/src/tools/webbrowser/browserRunRegistry.js +35 -3
  289. package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
  290. package/src/tools/webbrowser/browserService.js +28 -2
  291. package/src/tools/webbrowser/browserService.ts +49 -9
  292. package/src/tools/webbrowser/browserStream.js +132 -33
  293. package/src/tools/webbrowser/browserStream.ts +224 -50
  294. package/src/tools/webbrowser/browserTabs.js +48 -15
  295. package/src/tools/webbrowser/browserTabs.ts +178 -96
  296. package/src/tools/webbrowser/webbrowser.js +679 -144
  297. package/src/tools/webbrowser/webbrowser.ts +975 -236
  298. package/src/tools/webfetch/preapproved.js +0 -2
  299. package/src/tools/webfetch/preapproved.ts +0 -2
  300. package/src/tools/websearch/websearch.js +129 -8
  301. package/src/tools/websearch/websearch.ts +138 -6
  302. package/src/types.ts +440 -38
  303. package/src/ui/App.js +377 -58
  304. package/src/ui/App.tsx +576 -111
  305. package/src/ui/LiveArea.js +14 -8
  306. package/src/ui/LiveArea.tsx +14 -10
  307. package/src/ui/MessageList.js +63 -20
  308. package/src/ui/MessageList.tsx +101 -16
  309. package/src/ui/ModelPicker.js +7 -4
  310. package/src/ui/ModelPicker.tsx +55 -8
  311. package/src/ui/hooks/useChat.js +152 -163
  312. package/src/ui/hooks/useChat.ts +396 -334
  313. package/src/ui/loginCommand.js +56 -0
  314. package/src/ui/loginCommand.ts +63 -0
  315. package/src/ui/toolProgress.js +41 -0
  316. package/src/ui/toolProgress.ts +44 -0
  317. package/src/web/browserBridge.js +20 -2
  318. package/src/web/browserBridge.ts +20 -2
  319. package/src/web/protocol.ts +1897 -194
  320. package/workflows/adaptive-research/workflow.mjs +86 -0
  321. package/workflows/e2e-capabilities/workflow.mjs +102 -0
  322. package/workflows/e2e-llm/workflow.mjs +52 -0
  323. package/workflows/e2e-smoke/workflow.mjs +59 -0
  324. package/workflows/e2e-vision-schema/README.md +48 -0
  325. package/workflows/e2e-vision-schema/workflow.mjs +149 -0
  326. package/workflows/e2e-write-greet/workflow.mjs +37 -0
  327. package/workflows/file-census/README.md +14 -0
  328. package/workflows/file-census/scripts/.gitkeep +2 -0
  329. package/workflows/file-census/workflow.mjs +110 -0
  330. package/workflows/goal/README.md +166 -0
  331. package/workflows/goal/prompts/audit.md +57 -0
  332. package/workflows/goal/prompts/contract.md +56 -0
  333. package/workflows/goal/prompts/iterate.md +37 -0
  334. package/workflows/goal/workflow.mjs +501 -0
  335. package/workflows/illustrate/README.md +90 -0
  336. package/workflows/illustrate/assets/engines.json +20 -0
  337. package/workflows/illustrate/assets/extract-baidu.js +21 -0
  338. package/workflows/illustrate/assets/extract-bing.js +33 -0
  339. package/workflows/illustrate/assets/extract-google.js +31 -0
  340. package/workflows/illustrate/workflow.mjs +301 -0
  341. package/workflows/plan/workflow.mjs +389 -0
  342. package/workflows/question-crops/README.md +35 -0
  343. package/workflows/question-crops/prompts/inventory.md +23 -0
  344. package/workflows/question-crops/scripts/image-ops.mjs +305 -0
  345. package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
  346. package/workflows/question-crops/workflow.mjs +172 -0
  347. package/workflows/ralph-loop/workflow.mjs +162 -0
  348. package/workflows/research/README.md +74 -0
  349. package/workflows/research/prompts/s0-goal.md +43 -0
  350. package/workflows/research/prompts/s1-early-exit.md +22 -0
  351. package/workflows/research/prompts/s1-map.md +58 -0
  352. package/workflows/research/prompts/s2-options.md +53 -0
  353. package/workflows/research/prompts/s3-deep-dive.md +56 -0
  354. package/workflows/research/prompts/s4-verify.md +74 -0
  355. package/workflows/research/prompts/s5-synthesis.md +81 -0
  356. package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
  357. package/workflows/research/prompts/s6-package.md +32 -0
  358. package/workflows/research/scripts/build-report.mjs +98 -0
  359. package/workflows/research/workflow.mjs +288 -0
  360. package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
  361. package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
  362. package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
  363. package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
  364. package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
  365. package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
  366. package/workflows/wechat-reading-shots/workflow.mjs +266 -0
  367. package/workflows/wrong-question-docx/README.md +55 -0
  368. package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
  369. package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
  370. package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
  371. package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
  372. package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
  373. package/workflows/wrong-question-docx/workflow.mjs +485 -0
  374. package/plugins/workflow-runner/src/agentCommon.js +0 -354
  375. package/plugins/workflow-runner/src/agentCommon.ts +0 -435
  376. package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
  377. package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
  378. package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
  379. package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
  380. package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
  381. package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
  382. package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
  383. package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
  384. package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
  385. package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
  386. package/plugins/workflow-runner/src/dslManifest.js +0 -72
  387. package/plugins/workflow-runner/src/dslManifest.ts +0 -127
  388. package/plugins/workflow-runner/src/expressions.js +0 -639
  389. package/plugins/workflow-runner/src/expressions.ts +0 -640
  390. package/plugins/workflow-runner/src/loader.js +0 -573
  391. package/plugins/workflow-runner/src/loader.ts +0 -721
  392. package/plugins/workflow-runner/src/multimodal.js +0 -38
  393. package/plugins/workflow-runner/src/multimodal.ts +0 -64
  394. package/plugins/workflow-runner/src/recovery.js +0 -126
  395. package/plugins/workflow-runner/src/recovery.ts +0 -156
  396. package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
  397. package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
  398. package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
  399. package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
  400. package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
  401. package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
  402. package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
  403. package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
  404. package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
  405. package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
  406. package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
  407. package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
  408. package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
  409. package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
  410. package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
  411. package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
  412. package/plugins/workflow-runner/src/stepPipeline.js +0 -277
  413. package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
  414. package/plugins/workflow-runner/test/agent.test.ts +0 -587
  415. package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
  416. package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
  417. package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
  418. package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
  419. package/plugins/workflow-runner/test/context-files.test.ts +0 -320
  420. package/plugins/workflow-runner/test/e2e.test.ts +0 -370
  421. package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
  422. package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
  423. package/plugins/workflow-runner/test/expressions.test.ts +0 -439
  424. package/plugins/workflow-runner/test/foundation.test.ts +0 -126
  425. package/plugins/workflow-runner/test/graceful.test.ts +0 -139
  426. package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
  427. package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
  428. package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
  429. package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
  430. package/plugins/workflow-runner/test/loader.test.ts +0 -617
  431. package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
  432. package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
  433. package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
  434. package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
  435. package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
  436. package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
  437. package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
  438. package/plugins/workflow-runner/test/recovery.test.ts +0 -265
  439. package/plugins/workflow-runner/test/research.load.test.ts +0 -328
  440. package/plugins/workflow-runner/test/runner.test.ts +0 -911
  441. package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
  442. package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
  443. package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
  444. package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
  445. package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
  446. package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
  447. package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
  448. package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
  449. package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
  450. package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
  451. package/plugins/workflow-runner/test/word.load.test.ts +0 -208
  452. package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
  453. package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
  454. package/src/advisorState.js +0 -22
  455. package/src/cli/configWizard.js +0 -293
  456. package/src/tools/toolProgressBridge.js +0 -48
  457. package/workflows/adaptive-research.yaml +0 -50
  458. package/workflows/book-review-short.yaml +0 -125
  459. package/workflows/e2e-write-greet.yaml +0 -31
  460. package/workflows/illustrate.yaml +0 -227
  461. package/workflows/plan.yaml +0 -470
  462. package/workflows/ppt.yaml +0 -1670
  463. package/workflows/ralph-loop.yaml +0 -201
  464. package/workflows/research.yaml +0 -873
  465. package/workflows/schema.json +0 -176
  466. package/workflows/webppt.yaml +0 -496
  467. package/workflows/wechat-reading-shots.yaml +0 -315
  468. package/workflows/word.yaml +0 -720
  469. package/workflows/youtube-shorts.yaml +0 -202
  470. /package/workflows/{research.md → research/DESIGN.md} +0 -0
@@ -0,0 +1,449 @@
1
+ /**
2
+ * ============================================================
3
+ * plugins/workflow-runner/src/scriptGuard.mjs —— 编排脚本静态守卫
4
+ * ------------------------------------------------------------
5
+ * 本文件保持纯 JS、零依赖,因此作者期校验与运行期校验可以直接共享。
6
+ * 它有两个消费方,各自的加载方式完全不同:
7
+ * - 引擎(TypeScript)`import` 它 —— 走 Bun/Node 的 ESM
8
+ * - 创建 skill 的 `scripts/validate.mjs` 用 `node` **直接 spawn** 它
9
+ * 这就是它是 `.mjs` 而不是 `.ts` 的**全部理由**:`.ts` 在 npm 形态(宿主是
10
+ * `node dist/main.js`)和绿色版(SDK 焊在 exe 里、磁盘没有)下都加载不了。
11
+ * 工作流自身是真实 ESM,可以正常 import;这里只约束校验器自己的可移植性。
12
+ *
13
+ * ------------------------------------------------------------
14
+ * 诚实的能力边界(对齐 `src/irreversible/rules.ts` 的写法):
15
+ * 这是**防作者手滑**的守卫,不是对抗恶意脚本的沙箱。绕过方式一抓一把 ——
16
+ * `globalThis['Dat'+'e'].now()`、`Function('return Date.now()')()`、
17
+ * `this.constructor.constructor(...)`。不去堵这些是有意的:脚本作者就是项目
18
+ * 自己人,真正的价值在于「把不确定性挡在 journal 重放之外」这个**提醒**,
19
+ * 而不是构筑一道假的安全边界。
20
+ * ============================================================
21
+ */
22
+
23
+ /**
24
+ * 宿主引擎自身的 npm 包名(对应 `package.json::name`)。
25
+ *
26
+ * ⚠️ 硬编码、人工同步,不做运行时读取——`workflowFingerprint.ts` 那份同名常量
27
+ * 在绿色版 `bun --compile` 编译后 `import.meta.url` 会变成虚拟路径,届时靠相对
28
+ * 路径去读磁盘上的 `package.json` 会复现 CLAUDE.md 反复警告过的那类绿色版地雷;
29
+ * `scriptGuard.mjs` 还必须兼容"裸 node 直接 spawn"这条加载方式,同样不适合引入
30
+ * 文件系统依赖。改包名时两处一起改,这与 `moduleResolution.ts` 头注里
31
+ * "STATIC_IMPORT/packageName 人工同步"是同一个尺度。
32
+ */
33
+ const HOST_PACKAGE_NAME = 'minimal-agent';
34
+
35
+ /** 禁用的不确定性 API —— 它们会让 journal 重放失去意义(见 journal.ts)。 */
36
+ const NONDETERMINISTIC = [
37
+ {
38
+ re: /\bDate\s*\.\s*now\s*\(/g,
39
+ name: 'Date.now()',
40
+ why: '每次调用返回不同值,会让 resume 时的调用指纹永远失配',
41
+ },
42
+ {
43
+ re: /\bMath\s*\.\s*random\s*\(/g,
44
+ name: 'Math.random()',
45
+ why: '同上;需要变化时请让 args 或循环下标参与,而不是取随机数',
46
+ },
47
+ {
48
+ re: /\bnew\s+Date\s*\(\s*\)/g,
49
+ name: 'new Date()(无参)',
50
+ why: '同上;带参数的 new Date(x) 是确定性的,不在禁用之列',
51
+ },
52
+ ];
53
+
54
+ /**
55
+ * 把源码里**字符串字面量与注释的内容**替换成等长空格,保留其余字节与全部换行。
56
+ *
57
+ * 为什么必须做这一步:编排脚本正文里全是自然语言 prompt,随便一句
58
+ * `agent('把配置 import 进来')` 就会让裸正则误判成「用了 import 语句」。
59
+ * 误报一旦频繁,作者第一反应是绕开守卫而不是修脚本 —— 守卫就废了。
60
+ *
61
+ * 等长替换(不是删除)是为了让报错里的行号/列号仍然指向真实位置。
62
+ *
63
+ * 模板串的 `${...}` 内部是**真代码**,故不抹除 —— 里面调 Date.now() 一样该被抓到。
64
+ *
65
+ * 正则字面量与除号的歧义用「前一个有意义字符」启发式区分:若前一个非空白字符
66
+ * 属于 `(,=:[!&|?{};+-*%~^<>` 或紧跟 return/typeof 等关键词,则 `/` 开启正则。
67
+ * 判错的代价是可能多报一条错(响亮、可改),不会漏报 —— 这个方向是有意选的。
68
+ */
69
+ export function blankLiteralsAndComments(source) {
70
+ const out = source.split('');
71
+ const n = source.length;
72
+ let i = 0;
73
+ /** 最近一个有意义(非空白、非注释)的字符,用于正则/除号消歧。 */
74
+ let prevSignificant = '';
75
+ /** 模板串嵌套栈:进入 `${` 时压栈,遇到配对 `}` 时回到模板串状态。 */
76
+ const templateStack = [];
77
+
78
+ /** 把 [from, to) 区间抹成空格,但保留换行(行号不能错位)。 */
79
+ const blank = (from, to) => {
80
+ for (let k = from; k < to && k < n; k++) {
81
+ if (out[k] !== '\n' && out[k] !== '\r') out[k] = ' ';
82
+ }
83
+ };
84
+
85
+ const REGEX_PRECEDERS = '(,=:[!&|?{};+-*%~^<>';
86
+
87
+ while (i < n) {
88
+ const c = source[i];
89
+
90
+ // ---- 注释 ----
91
+ if (c === '/' && source[i + 1] === '/') {
92
+ let j = i + 2;
93
+ while (j < n && source[j] !== '\n') j++;
94
+ blank(i, j);
95
+ i = j;
96
+ continue;
97
+ }
98
+ if (c === '/' && source[i + 1] === '*') {
99
+ let j = i + 2;
100
+ while (j < n && !(source[j] === '*' && source[j + 1] === '/')) j++;
101
+ blank(i, Math.min(j + 2, n));
102
+ i = Math.min(j + 2, n);
103
+ continue;
104
+ }
105
+
106
+ // ---- 单/双引号字符串 ----
107
+ if (c === "'" || c === '"') {
108
+ const quote = c;
109
+ let j = i + 1;
110
+ while (j < n) {
111
+ if (source[j] === '\\') {
112
+ j += 2;
113
+ continue;
114
+ }
115
+ if (source[j] === quote || source[j] === '\n') break;
116
+ j++;
117
+ }
118
+ blank(i + 1, j); // 保留引号本身,只抹内容
119
+ prevSignificant = quote;
120
+ i = Math.min(j + 1, n);
121
+ continue;
122
+ }
123
+
124
+ // ---- 模板串 ----
125
+ if (c === '`') {
126
+ let j = i + 1;
127
+ const segStart = j;
128
+ while (j < n) {
129
+ if (source[j] === '\\') {
130
+ j += 2;
131
+ continue;
132
+ }
133
+ if (source[j] === '`') break;
134
+ if (source[j] === '$' && source[j + 1] === '{') {
135
+ blank(segStart, j); // 抹掉这一段纯文本
136
+ templateStack.push('template');
137
+ j += 2;
138
+ prevSignificant = '{';
139
+ i = j;
140
+ break; // 回主循环,把 ${...} 内部当普通代码处理
141
+ }
142
+ j++;
143
+ }
144
+ if (templateStack.length > 0 && i === j) continue; // 已进入 ${}
145
+ blank(segStart, j);
146
+ prevSignificant = '`';
147
+ i = Math.min(j + 1, n);
148
+ continue;
149
+ }
150
+ if (c === '}' && templateStack.length > 0) {
151
+ // 退出 ${},回到模板串文本段
152
+ templateStack.pop();
153
+ let j = i + 1;
154
+ const segStart = j;
155
+ while (j < n) {
156
+ if (source[j] === '\\') {
157
+ j += 2;
158
+ continue;
159
+ }
160
+ if (source[j] === '`') break;
161
+ if (source[j] === '$' && source[j + 1] === '{') {
162
+ blank(segStart, j);
163
+ templateStack.push('template');
164
+ i = j + 2;
165
+ prevSignificant = '{';
166
+ break;
167
+ }
168
+ j++;
169
+ }
170
+ if (templateStack.length > 0 && i > j) continue;
171
+ blank(segStart, j);
172
+ prevSignificant = '`';
173
+ i = Math.min(j + 1, n);
174
+ continue;
175
+ }
176
+
177
+ // ---- 正则字面量(与除号消歧)----
178
+ if (c === '/') {
179
+ const isRegex =
180
+ prevSignificant === '' ||
181
+ REGEX_PRECEDERS.includes(prevSignificant) ||
182
+ /\b(return|typeof|case|in|of|new|delete|void|instanceof)$/.test(
183
+ source.slice(Math.max(0, i - 12), i).trimEnd(),
184
+ );
185
+ if (isRegex) {
186
+ let j = i + 1;
187
+ let inClass = false;
188
+ while (j < n) {
189
+ if (source[j] === '\\') {
190
+ j += 2;
191
+ continue;
192
+ }
193
+ if (source[j] === '[') inClass = true;
194
+ else if (source[j] === ']') inClass = false;
195
+ else if (source[j] === '/' && !inClass) break;
196
+ else if (source[j] === '\n') break; // 未闭合,放弃当正则处理
197
+ j++;
198
+ }
199
+ if (j < n && source[j] === '/') {
200
+ blank(i + 1, j);
201
+ prevSignificant = '/';
202
+ i = j + 1;
203
+ while (i < n && /[a-z]/.test(source[i])) i++; // 跳过 flags
204
+ continue;
205
+ }
206
+ }
207
+ }
208
+
209
+ if (!/\s/.test(c)) prevSignificant = c;
210
+ i++;
211
+ }
212
+
213
+ return out.join('');
214
+ }
215
+
216
+ /**
217
+ * 收集一个全局正则在文本中的全部命中起点。
218
+ *
219
+ * 用 `matchAll` 而不是 `while ((m = re.exec(s)))` 有两个实际好处,不只是风格:
220
+ * ① 上面那几条规则的正则是**模块级共享对象**,`exec` 会在它们身上留下 `lastIndex`。
221
+ * 忘了重置(或中途 return)就会让下一次校验从半路开始扫,表现为「同样的脚本,
222
+ * 第二次校验少报了一条」。`matchAll` 按规范内部克隆正则,源对象一个字节不动。
223
+ * ② 零宽匹配的死循环由 `matchAll` 自己处理,不必手写 `lastIndex++` 兜底。
224
+ */
225
+ function matchIndices(re, text) {
226
+ const out = [];
227
+ for (const m of text.matchAll(re)) out.push(m.index ?? 0);
228
+ return out;
229
+ }
230
+
231
+ /** 由 offset 求 1-based 行号。 */
232
+ function lineOf(source, offset) {
233
+ let line = 1;
234
+ for (let i = 0; i < offset && i < source.length; i++) {
235
+ if (source[i] === '\n') line++;
236
+ }
237
+ return line;
238
+ }
239
+
240
+ /**
241
+ * 定位开头的 `export const meta = {...}`,返回字面量文本与其后的正文起点。
242
+ *
243
+ * 要求它是**开头第一个语句**(允许前置注释/空行):meta 要在执行前被静态读出来
244
+ * (命令补全、/workflows 列表、inputs 映射都在真正跑脚本之前就需要它),
245
+ * 所以它不能依赖任何运行时状态。位置固定也让扫描逻辑不必解析整个文件。
246
+ */
247
+ export function extractMetaLiteral(source) {
248
+ const blanked = blankLiteralsAndComments(source);
249
+ const m = /^[\s]*export\s+const\s+meta\s*=\s*\{/.exec(blanked);
250
+ if (!m) {
251
+ return {
252
+ ok: false,
253
+ error:
254
+ '脚本必须以 `export const meta = { ... }` 开头(前面可以有注释)。meta 会在执行前被静态读出,用于 /workflows 列表与 inputs 映射。',
255
+ };
256
+ }
257
+ const braceStart = m[0].length - 1; // 指向 '{'
258
+ let depth = 0;
259
+ let end = -1;
260
+ for (let i = braceStart; i < blanked.length; i++) {
261
+ const ch = blanked[i];
262
+ if (ch === '{') depth++;
263
+ else if (ch === '}') {
264
+ depth--;
265
+ if (depth === 0) {
266
+ end = i + 1;
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ if (end === -1) {
272
+ return { ok: false, error: '`export const meta = {` 的花括号没有闭合。' };
273
+ }
274
+ return {
275
+ ok: true,
276
+ literal: source.slice(braceStart, end),
277
+ bodyOffset: end,
278
+ metaStart: braceStart,
279
+ };
280
+ }
281
+
282
+ /**
283
+ * 把 meta 字面量求值成对象。
284
+ *
285
+ * 要求它是**纯字面量** —— 不许出现标识符引用、函数调用、模板插值、扩展运算符。
286
+ * 判据是先在抹除字符串后的文本上扫可疑构造,再用一个不带任何自由变量的
287
+ * `Function` 求值(求值前已确认没有标识符,所以这一步拿不到外部作用域)。
288
+ */
289
+ export function evaluateMetaLiteral(literal) {
290
+ const blanked = blankLiteralsAndComments(literal);
291
+ const suspicious = [
292
+ { re: /\.\.\./, what: '扩展运算符 ...' },
293
+ { re: /`/, what: '模板串(meta 必须是纯字面量)' },
294
+ { re: /\w\s*\(/, what: '函数调用' },
295
+ { re: /=>/, what: '箭头函数' },
296
+ ];
297
+ for (const s of suspicious) {
298
+ if (s.re.test(blanked)) {
299
+ return {
300
+ ok: false,
301
+ error: `meta 必须是纯字面量,但发现了${s.what}。meta 在执行前被静态读取,此时没有任何运行时值可用。`,
302
+ };
303
+ }
304
+ }
305
+ try {
306
+ // 这里的 new Function 是安全的:上面已逐条排除了函数调用/标识符引用/模板插值,
307
+ // 到这一步 literal 只可能是纯数据字面量;且构造出的函数不接受任何参数,
308
+ // 拿不到本模块或调用方的任何自由变量。
309
+ const value = new Function(`"use strict";return (${literal});`)();
310
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
311
+ return { ok: false, error: 'meta 必须是一个对象字面量。' };
312
+ }
313
+ return { ok: true, value };
314
+ } catch (e) {
315
+ return {
316
+ ok: false,
317
+ error: `meta 字面量解析失败:${e instanceof Error ? e.message : String(e)}`,
318
+ };
319
+ }
320
+ }
321
+
322
+ /**
323
+ * 全量校验一个编排脚本。
324
+ *
325
+ * @param {string} source workflow.mjs 全文
326
+ * @param {{ filename?: string }} [opts]
327
+ * @returns {{ ok: boolean, errors: string[], meta?: Record<string, unknown>, bodyOffset?: number }}
328
+ */
329
+ export function validateScript(source, opts = {}) {
330
+ const where = opts.filename ? `${opts.filename}: ` : '';
331
+ const errors = [];
332
+
333
+ const extracted = extractMetaLiteral(source);
334
+ if (!extracted.ok) {
335
+ return { ok: false, errors: [where + extracted.error] };
336
+ }
337
+
338
+ const evaluated = evaluateMetaLiteral(extracted.literal);
339
+ if (!evaluated.ok) {
340
+ return { ok: false, errors: [where + evaluated.error] };
341
+ }
342
+ const meta = evaluated.value;
343
+
344
+ if (meta.apiVersion !== 2) {
345
+ errors.push(`${where}meta.apiVersion 必须为 2。V2 工作流是真实 ESM 模块。`);
346
+ }
347
+
348
+ if (typeof meta.description !== 'string' || meta.description.trim() === '') {
349
+ errors.push(
350
+ `${where}meta.description 必填(一句话说明这个工作流做什么,会显示在 /workflows 列表里)。`,
351
+ );
352
+ }
353
+ // name 不从 meta 取:目录名即工作流名,单一真值,避免两处漂移。
354
+ if ('name' in meta) {
355
+ errors.push(
356
+ `${where}meta 不接受 name 字段:工作流名恒等于所在目录名(单一真值)。请改目录名。`,
357
+ );
358
+ }
359
+ if (meta.inputs !== undefined && !Array.isArray(meta.inputs)) {
360
+ errors.push(`${where}meta.inputs 必须是数组。`);
361
+ }
362
+ if (meta.artifacts !== undefined && !Array.isArray(meta.artifacts)) {
363
+ errors.push(`${where}meta.artifacts 必须是数组。`);
364
+ }
365
+ if (
366
+ meta.dependencies !== undefined &&
367
+ (!Array.isArray(meta.dependencies) ||
368
+ meta.dependencies.some(
369
+ (n) => typeof n !== 'string' || !/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(n),
370
+ ) ||
371
+ new Set(meta.dependencies).size !== meta.dependencies.length)
372
+ ) {
373
+ errors.push(`${where}meta.dependencies 必须是不重复的工作流目录名数组。`);
374
+ }
375
+ if (
376
+ meta.packages !== undefined &&
377
+ (!Array.isArray(meta.packages) ||
378
+ meta.packages.some((n) => typeof n !== 'string' || !/^(?:@[a-zA-Z0-9._-]+\/)?[a-zA-Z0-9._-]+$/.test(n)) ||
379
+ new Set(meta.packages).size !== meta.packages.length)
380
+ ) {
381
+ errors.push(`${where}meta.packages 必须是不重复的 npm 包名数组。`);
382
+ }
383
+
384
+ const importedPackages = new Set();
385
+ const imports = /(?:^|[;\n])\s*(?:import|export)\s+(?:[^'";]*?\s+from\s+)?['"]([^'"]+)['"]/gm;
386
+ for (const match of source.matchAll(imports)) {
387
+ const specifier = match[1];
388
+ if (specifier.startsWith('.') || specifier.startsWith('node:')) continue;
389
+ if (specifier.startsWith('/') || specifier.startsWith('file:')) {
390
+ errors.push(`${where}ESM import 不得使用绝对路径:${specifier}`);
391
+ continue;
392
+ }
393
+ const packageName = specifier.startsWith('@')
394
+ ? specifier.split('/').slice(0, 2).join('/')
395
+ : specifier.split('/')[0];
396
+ // 宿主引擎自身:Node/Bun 的包自引用 + package.json::exports 的 "./src/*"/
397
+ // "./plugins/*" 通配符会让 `minimal-agent/src/xxx` 解析到真实内核文件,
398
+ // 完全绕开 wf 分组能力对象对调度/记账/心跳/预算的管控。这不是"没声明"的
399
+ // 问题——即使声明进 meta.packages 也要拒绝,所以单独报错、不进
400
+ // importedPackages(避免作者看到"必须声明"后真的把它加进去,反而踩得更深)。
401
+ if (packageName === HOST_PACKAGE_NAME) {
402
+ errors.push(
403
+ `${where}禁止 import 宿主引擎自身(${specifier}):\`${HOST_PACKAGE_NAME}\` ` +
404
+ `就是正在编排这个工作流的内核,一切对内核的访问必须经 wf 分组能力对象` +
405
+ `(wf.model/wf.tools/wf.exec/wf.fs/...),直接 import 会绕开调度排队、` +
406
+ `断点续跑记账、心跳与预算闸,且可能反向重入正在执行它的内核本身。`,
407
+ );
408
+ continue;
409
+ }
410
+ importedPackages.add(packageName);
411
+ }
412
+ for (const name of importedPackages) {
413
+ if (!meta.packages?.includes(name)) {
414
+ errors.push(`${where}运行时包 ${name} 必须声明在 meta.packages 中。`);
415
+ }
416
+ }
417
+ if (/\bimport\s*\(/.test(blankLiteralsAndComments(source).slice(extracted.bodyOffset))) {
418
+ errors.push(`${where}不允许动态 import():依赖图无法静态指纹化,请改用静态 import。`);
419
+ }
420
+
421
+ // 正文(meta 之后)的禁用构造扫描,全部在抹除字符串/注释后的文本上做。
422
+ const blanked = blankLiteralsAndComments(source);
423
+ const bodyBlanked = blanked.slice(extracted.bodyOffset);
424
+ const bodyBase = extracted.bodyOffset;
425
+
426
+ for (const index of matchIndices(/\brequire\s*\(/g, bodyBlanked)) {
427
+ const line = lineOf(source, bodyBase + index);
428
+ errors.push(
429
+ `${where}第 ${line} 行不允许 require():V2 工作流是 ESM,请改用静态 import。`,
430
+ );
431
+ }
432
+
433
+ for (const rule of NONDETERMINISTIC) {
434
+ for (const index of matchIndices(rule.re, bodyBlanked)) {
435
+ const line = lineOf(source, bodyBase + index);
436
+ errors.push(`${where}第 ${line} 行禁止使用 ${rule.name} —— ${rule.why}`);
437
+ }
438
+ }
439
+
440
+ if (!/\bexport\s+default\s+async\s+function\s+run\s*\(\s*wf\s*\)/.test(bodyBlanked)) {
441
+ errors.push(
442
+ `${where}必须导出入口:\`export default async function run(wf) { ... }\`。`,
443
+ );
444
+ }
445
+
446
+ return errors.length > 0
447
+ ? { ok: false, errors, meta, bodyOffset: extracted.bodyOffset }
448
+ : { ok: true, errors: [], meta, bodyOffset: extracted.bodyOffset };
449
+ }