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.
- package/README.md +6 -5
- package/package.json +60 -4
- package/plugins/computer_use/.claude-plugin/plugin.json +1 -1
- package/plugins/cron-runner/src/commands.js +4 -4
- package/plugins/cron-runner/src/commands.ts +4 -4
- package/plugins/workflow-runner/.claude-plugin/plugin.json +2 -2
- package/plugins/workflow-runner/commands/workflow.md +57 -90
- package/plugins/workflow-runner/commands/workflows.md +4 -4
- package/plugins/workflow-runner/plugin.js +24 -13
- package/plugins/workflow-runner/plugin.ts +28 -13
- package/plugins/workflow-runner/src/discovery.js +160 -0
- package/plugins/workflow-runner/src/discovery.ts +194 -0
- package/plugins/workflow-runner/src/goalAnchor.js +53 -0
- package/plugins/workflow-runner/src/goalAnchor.ts +59 -0
- package/plugins/workflow-runner/src/index.js +197 -206
- package/plugins/workflow-runner/src/index.ts +248 -249
- package/plugins/workflow-runner/src/inputCoercion.js +40 -0
- package/plugins/workflow-runner/src/inputCoercion.ts +43 -0
- package/plugins/workflow-runner/src/journal.js +224 -0
- package/plugins/workflow-runner/src/journal.ts +274 -0
- package/plugins/workflow-runner/src/jsonSchema.js +132 -0
- package/plugins/workflow-runner/src/jsonSchema.ts +162 -0
- package/plugins/workflow-runner/src/moduleResolution.js +64 -0
- package/plugins/workflow-runner/src/moduleResolution.ts +71 -0
- package/plugins/workflow-runner/src/resourceInputs.js +220 -0
- package/plugins/workflow-runner/src/resourceInputs.ts +300 -0
- package/plugins/workflow-runner/src/runner.js +400 -489
- package/plugins/workflow-runner/src/runner.ts +488 -560
- package/plugins/workflow-runner/src/runtime/config.js +46 -0
- package/plugins/workflow-runner/src/runtime/config.ts +69 -0
- package/plugins/workflow-runner/src/runtime/context.js +1304 -0
- package/plugins/workflow-runner/src/runtime/context.ts +1786 -0
- package/plugins/workflow-runner/src/runtime/exec.js +34 -0
- package/plugins/workflow-runner/src/runtime/exec.ts +53 -0
- package/plugins/workflow-runner/src/runtime/flow.js +8 -0
- package/plugins/workflow-runner/src/runtime/flow.ts +12 -0
- package/plugins/workflow-runner/src/runtime/fs.js +27 -0
- package/plugins/workflow-runner/src/runtime/fs.ts +41 -0
- package/plugins/workflow-runner/src/runtime/model.js +6 -0
- package/plugins/workflow-runner/src/runtime/model.ts +8 -0
- package/plugins/workflow-runner/src/runtime/output.js +7 -0
- package/plugins/workflow-runner/src/runtime/output.ts +21 -0
- package/plugins/workflow-runner/src/runtime/scheduler.js +141 -0
- package/plugins/workflow-runner/src/runtime/scheduler.ts +166 -0
- package/plugins/workflow-runner/src/runtime/state.js +16 -0
- package/plugins/workflow-runner/src/runtime/state.ts +19 -0
- package/plugins/workflow-runner/src/runtime/tools.js +3 -0
- package/plugins/workflow-runner/src/runtime/tools.ts +6 -0
- package/plugins/workflow-runner/src/sandbox.js +141 -0
- package/plugins/workflow-runner/src/sandbox.ts +182 -0
- package/plugins/workflow-runner/src/scriptGuard.d.mts +38 -0
- package/plugins/workflow-runner/src/scriptGuard.mjs +449 -0
- package/plugins/workflow-runner/src/taskIdentity.js +151 -307
- package/plugins/workflow-runner/src/taskIdentity.ts +207 -355
- package/plugins/workflow-runner/src/toolRuntime.js +29 -8
- package/plugins/workflow-runner/src/toolRuntime.ts +36 -11
- package/plugins/workflow-runner/src/types.js +7 -211
- package/plugins/workflow-runner/src/types.ts +154 -623
- package/plugins/workflow-runner/src/util.js +47 -0
- package/plugins/workflow-runner/src/util.ts +51 -0
- package/plugins/workflow-runner/src/workflowContext.js +20 -0
- package/plugins/workflow-runner/src/workflowContext.ts +58 -0
- package/plugins/workflow-runner/src/workflowDependencies.js +36 -0
- package/plugins/workflow-runner/src/workflowDependencies.ts +59 -0
- package/plugins/workflow-runner/src/workflowFingerprint.js +118 -0
- package/plugins/workflow-runner/src/workflowFingerprint.ts +122 -0
- package/plugins/workflow-runner/src/workflowState.js +474 -802
- package/plugins/workflow-runner/src/workflowState.ts +575 -970
- package/plugins/workflow-runner/test/api.test.ts +223 -0
- package/plugins/workflow-runner/test/apiCapabilities.test.ts +614 -0
- package/plugins/workflow-runner/test/apiConcurrencyGate.test.ts +104 -0
- package/plugins/workflow-runner/test/apiEcho.test.ts +210 -0
- package/plugins/workflow-runner/test/apiReadText.test.ts +178 -0
- package/plugins/workflow-runner/test/apiResourceLedger.test.ts +184 -0
- package/plugins/workflow-runner/test/childWorkflow.test.ts +304 -0
- package/plugins/workflow-runner/test/discovery.test.ts +234 -0
- package/plugins/workflow-runner/test/goalAnchor.test.ts +106 -0
- package/plugins/workflow-runner/test/goalController.test.ts +317 -0
- package/plugins/workflow-runner/test/journalLanes.test.ts +198 -0
- package/plugins/workflow-runner/test/listResources.test.ts +106 -0
- package/plugins/workflow-runner/test/resourceInputs.test.ts +294 -0
- package/plugins/workflow-runner/test/sandbox.test.ts +126 -0
- package/plugins/workflow-runner/test/scheduler.test.ts +70 -0
- package/plugins/workflow-runner/test/scriptGuard.test.ts +276 -0
- package/plugins/workflow-runner/test/skillDocSync.test.ts +78 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +288 -179
- package/plugins/workflow-runner/test/workflowFingerprint.test.ts +106 -0
- package/plugins/workflow-runner/test/workflowState.test.ts +429 -0
- package/skills/pptx/examples/assets/cover-bg.svg +23 -0
- package/skills/pptx/examples/assets/icon-spark.svg +5 -0
- package/skills/ui-design/SKILL.md +5 -2
- package/skills/ui-design/references/layout-composition.md +1 -1
- package/skills/workflow-creator/SKILL.md +344 -0
- package/skills/workflow-creator/assets/template/workflow.mjs +48 -0
- package/skills/workflow-creator/references/api.md +216 -0
- package/skills/workflow-creator/references/migration.md +103 -0
- package/skills/workflow-creator/references/patterns.md +779 -0
- package/skills/workflow-creator/scripts/list-resources.mjs +205 -0
- package/skills/workflow-creator/scripts/scaffold.mjs +148 -0
- package/skills/workflow-creator/scripts/validate.mjs +275 -0
- package/skills/workflow-creator/scripts/workflow-creator.test.mjs +82 -0
- package/src/advisor/advisorCoordinator.js +503 -0
- package/src/advisor/advisorCoordinator.ts +657 -0
- package/src/cli/configMenu.tsx +0 -1
- package/src/cli/print.js +27 -6
- package/src/cli/print.ts +48 -4
- package/src/cli/streamJson.js +5 -6
- package/src/cli/streamJson.ts +8 -4
- package/src/cli/wizards/advisorWizard.js +4 -2
- package/src/cli/wizards/advisorWizard.tsx +8 -2
- package/src/cli/wizards/contextAdvisorWizard.js +5 -4
- package/src/cli/wizards/contextAdvisorWizard.tsx +7 -6
- package/src/collaboration/taskFlow.js +115 -0
- package/src/collaboration/taskFlow.ts +169 -0
- package/src/config/configDefaults.js +41 -1
- package/src/config/configDefaults.ts +43 -1
- package/src/config/configDiagnostics.ts +2 -2
- package/src/config/configFile.js +40 -9
- package/src/config/configFile.ts +60 -11
- package/src/config/configService.js +419 -74
- package/src/config/configService.ts +703 -145
- package/src/config/numericLimits.js +22 -0
- package/src/config/numericLimits.ts +24 -0
- package/src/config.js +1 -0
- package/src/config.ts +3 -2
- package/src/context/budgetPlan.js +1 -1
- package/src/context/budgetPlan.ts +1 -1
- package/src/context/compact.js +7 -2
- package/src/context/compact.ts +9 -2
- package/src/context/microCompactLite.js +212 -13
- package/src/context/microCompactLite.ts +261 -12
- package/src/context/sessionRegistry.js +8 -1
- package/src/context/sessionRegistry.ts +18 -5
- package/src/context/toolResultArchive.js +72 -0
- package/src/context/toolResultArchive.ts +95 -0
- package/src/goal/errors.js +8 -0
- package/src/goal/errors.ts +18 -0
- package/src/goal/goalRuntime.js +344 -0
- package/src/goal/goalRuntime.ts +466 -0
- package/src/goal/goalStore.js +200 -0
- package/src/goal/goalStore.ts +219 -0
- package/src/goal/index.js +4 -0
- package/src/goal/index.ts +4 -0
- package/src/goal/statusMapping.js +71 -0
- package/src/goal/statusMapping.ts +95 -0
- package/src/goal/types.js +7 -0
- package/src/goal/types.ts +179 -0
- package/src/goal/workflowController.js +306 -0
- package/src/goal/workflowController.ts +360 -0
- package/src/harness/evidenceLedger.js +2 -0
- package/src/harness/evidenceLedger.ts +1 -0
- package/src/harness/stallGuard.js +9 -3
- package/src/harness/stallGuard.ts +7 -3
- package/src/images/imageResolver.js +161 -0
- package/src/images/imageResolver.ts +189 -0
- package/src/infra/verification.js +34 -5
- package/src/infra/verification.ts +39 -4
- package/src/llm/client.js +79 -21
- package/src/llm/client.ts +182 -35
- package/src/llm/gatewayClient.js +201 -0
- package/src/llm/gatewayClient.ts +299 -0
- package/src/llm/messageProvenance.js +46 -0
- package/src/llm/messageProvenance.ts +58 -0
- package/src/llm/modelProvider.js +1 -0
- package/src/llm/modelProvider.ts +22 -0
- package/src/llm/providers/anthropicFormat.js +108 -1
- package/src/llm/providers/anthropicFormat.ts +115 -4
- package/src/llm/providers/openaiFormat.js +9 -0
- package/src/llm/providers/openaiFormat.ts +12 -3
- package/src/loop.js +319 -54
- package/src/loop.ts +373 -57
- package/src/main.js +4 -1
- package/src/main.tsx +4 -1
- package/src/managedExecution/index.js +2 -0
- package/src/managedExecution/index.ts +2 -0
- package/src/managedExecution/registry.js +15 -0
- package/src/managedExecution/registry.ts +20 -0
- package/src/managedExecution/types.js +1 -0
- package/src/managedExecution/types.ts +86 -0
- package/src/modelRef.js +9 -0
- package/src/modelRef.ts +31 -0
- package/src/multimodal.js +14 -28
- package/src/multimodal.ts +17 -33
- package/src/net/lanDiscovery.js +65 -0
- package/src/net/lanDiscovery.ts +82 -0
- package/src/plugin-sdk.js +28 -3
- package/src/plugin-sdk.ts +39 -6
- package/src/plugins/pluginApi.ts +16 -1
- package/src/plugins/pluginLoader.js +4 -0
- package/src/plugins/pluginLoader.ts +6 -0
- package/src/plugins/pluginRunner.js +139 -7
- package/src/plugins/pluginRunner.ts +173 -9
- package/src/plugins/slashFallback.js +113 -0
- package/src/plugins/slashFallback.ts +137 -0
- package/src/prompts/policyRegistry.js +12 -32
- package/src/prompts/policyRegistry.ts +15 -32
- package/src/prompts/promptAssembly.js +103 -12
- package/src/prompts/promptAssembly.ts +114 -12
- package/src/prompts/skillList.js +21 -3
- package/src/prompts/skillList.ts +27 -2
- package/src/prompts/stableSystemPrompt.js +18 -0
- package/src/prompts/stableSystemPrompt.ts +33 -0
- package/src/runtime/agentRuntimeContext.js +8 -2
- package/src/runtime/agentRuntimeContext.ts +17 -4
- package/src/session/runAgentTurn.js +78 -12
- package/src/session/runAgentTurn.ts +105 -23
- package/src/session/runTurn.js +10 -9
- package/src/session/runTurn.ts +17 -8
- package/src/session/sessionState.ts +2 -0
- package/src/team/auth.js +186 -0
- package/src/team/auth.ts +298 -0
- package/src/team/cli.js +105 -0
- package/src/team/cli.ts +122 -0
- package/src/team/onlineToolContract.js +64 -0
- package/src/team/onlineToolContract.ts +109 -0
- package/src/team/toolPolicy.js +36 -0
- package/src/team/toolPolicy.ts +75 -0
- package/src/tools/advisor/advisor.js +90 -46
- package/src/tools/advisor/advisor.ts +100 -47
- package/src/tools/advisor/advisorDecision.js +71 -0
- package/src/tools/advisor/advisorDecision.ts +85 -0
- package/src/tools/agent/agent.js +18 -5
- package/src/tools/agent/agent.ts +21 -7
- package/src/tools/agent/agentControl.js +246 -0
- package/src/tools/agent/agentControl.ts +284 -0
- package/src/tools/agent/agentTaskService.js +40 -1
- package/src/tools/agent/agentTaskService.ts +44 -1
- package/src/tools/agent/agentTypes.js +14 -2
- package/src/tools/agent/agentTypes.ts +15 -2
- package/src/tools/applypatch/applyPatch.js +362 -0
- package/src/tools/applypatch/applyPatch.ts +428 -0
- package/src/tools/bash/bash.js +22 -15
- package/src/tools/bash/bash.ts +23 -17
- package/src/tools/capabilities.js +10 -5
- package/src/tools/capabilities.ts +10 -5
- package/src/tools/computeruse/computerIntent.js +32 -0
- package/src/tools/computeruse/computerIntent.ts +46 -0
- package/src/tools/computeruse/telemetryLog.js +12 -0
- package/src/tools/computeruse/telemetryLog.ts +16 -0
- package/src/tools/computeruse/vision/telemetry.js +1 -0
- package/src/tools/computeruse/vision/telemetry.ts +1 -0
- package/src/tools/effectiveToolSet.js +4 -0
- package/src/tools/effectiveToolSet.ts +4 -0
- package/src/tools/index.js +21 -2
- package/src/tools/index.ts +33 -2
- package/src/tools/presentresult/presentresult.js +6 -15
- package/src/tools/presentresult/presentresult.ts +6 -15
- package/src/tools/read/read.js +62 -9
- package/src/tools/read/read.ts +63 -9
- package/src/tools/shared/fileUtils.js +1 -2
- package/src/tools/shared/fileUtils.ts +1 -2
- package/src/tools/shared/toolOutputStore.js +23 -1
- package/src/tools/shared/toolOutputStore.ts +22 -1
- package/src/tools/skill/skill.js +9 -3
- package/src/tools/skill/skill.ts +8 -4
- package/src/tools/toolPromptGuides.js +117 -0
- package/src/tools/toolPromptGuides.ts +137 -0
- package/src/tools/webbrowser/agentBrowserPath.js +19 -9
- package/src/tools/webbrowser/agentBrowserPath.ts +70 -28
- package/src/tools/webbrowser/browser.js +27 -11
- package/src/tools/webbrowser/browser.ts +68 -24
- package/src/tools/webbrowser/browserAutomation.js +329 -0
- package/src/tools/webbrowser/browserAutomation.ts +467 -0
- package/src/tools/webbrowser/browserAxState.js +97 -0
- package/src/tools/webbrowser/browserAxState.ts +142 -0
- package/src/tools/webbrowser/browserBatch.js +1578 -0
- package/src/tools/webbrowser/browserBatch.ts +2382 -0
- package/src/tools/webbrowser/browserCdp.js +208 -0
- package/src/tools/webbrowser/browserCdp.ts +255 -0
- package/src/tools/webbrowser/browserConditions.js +24 -0
- package/src/tools/webbrowser/browserConditions.ts +45 -0
- package/src/tools/webbrowser/browserContent.js +281 -0
- package/src/tools/webbrowser/browserContent.ts +438 -0
- package/src/tools/webbrowser/browserControl.js +131 -34
- package/src/tools/webbrowser/browserControl.ts +210 -56
- package/src/tools/webbrowser/browserDaemon.js +22 -14
- package/src/tools/webbrowser/browserDaemon.ts +54 -21
- package/src/tools/webbrowser/browserFrames.js +47 -0
- package/src/tools/webbrowser/browserFrames.ts +54 -0
- package/src/tools/webbrowser/browserInteractionResolver.js +17 -0
- package/src/tools/webbrowser/browserInteractionResolver.ts +40 -0
- package/src/tools/webbrowser/browserLocator.js +140 -0
- package/src/tools/webbrowser/browserLocator.ts +194 -0
- package/src/tools/webbrowser/browserOutcome.js +10 -17
- package/src/tools/webbrowser/browserOutcome.ts +48 -31
- package/src/tools/webbrowser/browserRecovery.js +58 -0
- package/src/tools/webbrowser/browserRecovery.ts +83 -0
- package/src/tools/webbrowser/browserRunRegistry.js +35 -3
- package/src/tools/webbrowser/browserRunRegistry.ts +91 -15
- package/src/tools/webbrowser/browserService.js +28 -2
- package/src/tools/webbrowser/browserService.ts +49 -9
- package/src/tools/webbrowser/browserStream.js +132 -33
- package/src/tools/webbrowser/browserStream.ts +224 -50
- package/src/tools/webbrowser/browserTabs.js +48 -15
- package/src/tools/webbrowser/browserTabs.ts +178 -96
- package/src/tools/webbrowser/webbrowser.js +679 -144
- package/src/tools/webbrowser/webbrowser.ts +975 -236
- package/src/tools/webfetch/preapproved.js +0 -2
- package/src/tools/webfetch/preapproved.ts +0 -2
- package/src/tools/websearch/websearch.js +129 -8
- package/src/tools/websearch/websearch.ts +138 -6
- package/src/types.ts +440 -38
- package/src/ui/App.js +377 -58
- package/src/ui/App.tsx +576 -111
- package/src/ui/LiveArea.js +14 -8
- package/src/ui/LiveArea.tsx +14 -10
- package/src/ui/MessageList.js +63 -20
- package/src/ui/MessageList.tsx +101 -16
- package/src/ui/ModelPicker.js +7 -4
- package/src/ui/ModelPicker.tsx +55 -8
- package/src/ui/hooks/useChat.js +152 -163
- package/src/ui/hooks/useChat.ts +396 -334
- package/src/ui/loginCommand.js +56 -0
- package/src/ui/loginCommand.ts +63 -0
- package/src/ui/toolProgress.js +41 -0
- package/src/ui/toolProgress.ts +44 -0
- package/src/web/browserBridge.js +20 -2
- package/src/web/browserBridge.ts +20 -2
- package/src/web/protocol.ts +1897 -194
- package/workflows/adaptive-research/workflow.mjs +86 -0
- package/workflows/e2e-capabilities/workflow.mjs +102 -0
- package/workflows/e2e-llm/workflow.mjs +52 -0
- package/workflows/e2e-smoke/workflow.mjs +59 -0
- package/workflows/e2e-vision-schema/README.md +48 -0
- package/workflows/e2e-vision-schema/workflow.mjs +149 -0
- package/workflows/e2e-write-greet/workflow.mjs +37 -0
- package/workflows/file-census/README.md +14 -0
- package/workflows/file-census/scripts/.gitkeep +2 -0
- package/workflows/file-census/workflow.mjs +110 -0
- package/workflows/goal/README.md +166 -0
- package/workflows/goal/prompts/audit.md +57 -0
- package/workflows/goal/prompts/contract.md +56 -0
- package/workflows/goal/prompts/iterate.md +37 -0
- package/workflows/goal/workflow.mjs +501 -0
- package/workflows/illustrate/README.md +90 -0
- package/workflows/illustrate/assets/engines.json +20 -0
- package/workflows/illustrate/assets/extract-baidu.js +21 -0
- package/workflows/illustrate/assets/extract-bing.js +33 -0
- package/workflows/illustrate/assets/extract-google.js +31 -0
- package/workflows/illustrate/workflow.mjs +301 -0
- package/workflows/plan/workflow.mjs +389 -0
- package/workflows/question-crops/README.md +35 -0
- package/workflows/question-crops/prompts/inventory.md +23 -0
- package/workflows/question-crops/scripts/image-ops.mjs +305 -0
- package/workflows/question-crops/scripts/image-ops.test.mjs +95 -0
- package/workflows/question-crops/workflow.mjs +172 -0
- package/workflows/ralph-loop/workflow.mjs +162 -0
- package/workflows/research/README.md +74 -0
- package/workflows/research/prompts/s0-goal.md +43 -0
- package/workflows/research/prompts/s1-early-exit.md +22 -0
- package/workflows/research/prompts/s1-map.md +58 -0
- package/workflows/research/prompts/s2-options.md +53 -0
- package/workflows/research/prompts/s3-deep-dive.md +56 -0
- package/workflows/research/prompts/s4-verify.md +74 -0
- package/workflows/research/prompts/s5-synthesis.md +81 -0
- package/workflows/research/prompts/s5b-fill-gaps.md +32 -0
- package/workflows/research/prompts/s6-package.md +32 -0
- package/workflows/research/scripts/build-report.mjs +98 -0
- package/workflows/research/workflow.mjs +288 -0
- package/workflows/wechat-reading-shots/prompts/collect-params.md +16 -0
- package/workflows/wechat-reading-shots/prompts/evaluate.md +20 -0
- package/workflows/wechat-reading-shots/prompts/open-book.md +28 -0
- package/workflows/wechat-reading-shots/prompts/read-page.md +13 -0
- package/workflows/wechat-reading-shots/prompts/turn-batch.md +24 -0
- package/workflows/wechat-reading-shots/test/control-flow.test.ts +329 -0
- package/workflows/wechat-reading-shots/workflow.mjs +266 -0
- package/workflows/wrong-question-docx/README.md +55 -0
- package/workflows/wrong-question-docx/prompts/figure-qa.md +8 -0
- package/workflows/wrong-question-docx/prompts/transcribe.md +25 -0
- package/workflows/wrong-question-docx/scripts/workbook.mjs +857 -0
- package/workflows/wrong-question-docx/test/control-flow.test.ts +165 -0
- package/workflows/wrong-question-docx/test/workbook.test.mjs +303 -0
- package/workflows/wrong-question-docx/workflow.mjs +485 -0
- package/plugins/workflow-runner/src/agentCommon.js +0 -354
- package/plugins/workflow-runner/src/agentCommon.ts +0 -435
- package/plugins/workflow-runner/src/controlFlow/branch.js +0 -40
- package/plugins/workflow-runner/src/controlFlow/branch.ts +0 -46
- package/plugins/workflow-runner/src/controlFlow/loop.js +0 -211
- package/plugins/workflow-runner/src/controlFlow/loop.ts +0 -248
- package/plugins/workflow-runner/src/controlFlow/pause.js +0 -129
- package/plugins/workflow-runner/src/controlFlow/pause.ts +0 -141
- package/plugins/workflow-runner/src/controlFlow/signal.js +0 -21
- package/plugins/workflow-runner/src/controlFlow/signal.ts +0 -29
- package/plugins/workflow-runner/src/controlFlow/types.js +0 -18
- package/plugins/workflow-runner/src/controlFlow/types.ts +0 -63
- package/plugins/workflow-runner/src/dslManifest.js +0 -72
- package/plugins/workflow-runner/src/dslManifest.ts +0 -127
- package/plugins/workflow-runner/src/expressions.js +0 -639
- package/plugins/workflow-runner/src/expressions.ts +0 -640
- package/plugins/workflow-runner/src/loader.js +0 -573
- package/plugins/workflow-runner/src/loader.ts +0 -721
- package/plugins/workflow-runner/src/multimodal.js +0 -38
- package/plugins/workflow-runner/src/multimodal.ts +0 -64
- package/plugins/workflow-runner/src/recovery.js +0 -126
- package/plugins/workflow-runner/src/recovery.ts +0 -156
- package/plugins/workflow-runner/src/stepExecutors/agent.js +0 -173
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +0 -234
- package/plugins/workflow-runner/src/stepExecutors/assert.js +0 -42
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +0 -52
- package/plugins/workflow-runner/src/stepExecutors/echo.js +0 -31
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +0 -38
- package/plugins/workflow-runner/src/stepExecutors/llm.js +0 -99
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +0 -133
- package/plugins/workflow-runner/src/stepExecutors/set.js +0 -49
- package/plugins/workflow-runner/src/stepExecutors/set.ts +0 -56
- package/plugins/workflow-runner/src/stepExecutors/skill.js +0 -111
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +0 -140
- package/plugins/workflow-runner/src/stepExecutors/tool.js +0 -227
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +0 -274
- package/plugins/workflow-runner/src/stepExecutors/verify.js +0 -61
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +0 -72
- package/plugins/workflow-runner/src/stepPipeline.js +0 -277
- package/plugins/workflow-runner/src/stepPipeline.ts +0 -366
- package/plugins/workflow-runner/test/agent.test.ts +0 -587
- package/plugins/workflow-runner/test/agentLlmError.test.ts +0 -373
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +0 -65
- package/plugins/workflow-runner/test/captureMisbind.test.ts +0 -99
- package/plugins/workflow-runner/test/cli.e2e.test.ts +0 -167
- package/plugins/workflow-runner/test/context-files.test.ts +0 -320
- package/plugins/workflow-runner/test/e2e.test.ts +0 -370
- package/plugins/workflow-runner/test/e2eNewLayout.test.ts +0 -314
- package/plugins/workflow-runner/test/engineRobustness.test.ts +0 -234
- package/plugins/workflow-runner/test/expressions.test.ts +0 -439
- package/plugins/workflow-runner/test/foundation.test.ts +0 -126
- package/plugins/workflow-runner/test/graceful.test.ts +0 -139
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +0 -47
- package/plugins/workflow-runner/test/hostCapability.test.ts +0 -108
- package/plugins/workflow-runner/test/illustrate.load.test.ts +0 -183
- package/plugins/workflow-runner/test/jsonPayload.test.ts +0 -83
- package/plugins/workflow-runner/test/loader.test.ts +0 -617
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +0 -33
- package/plugins/workflow-runner/test/multimodal.test.ts +0 -342
- package/plugins/workflow-runner/test/output-schema.test.ts +0 -213
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +0 -106
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +0 -269
- package/plugins/workflow-runner/test/ppt.load.test.ts +0 -1220
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +0 -221
- package/plugins/workflow-runner/test/recovery.test.ts +0 -265
- package/plugins/workflow-runner/test/research.load.test.ts +0 -328
- package/plugins/workflow-runner/test/runner.test.ts +0 -911
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +0 -436
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +0 -71
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +0 -198
- package/plugins/workflow-runner/test/stepPipeline.test.ts +0 -114
- package/plugins/workflow-runner/test/taskArbitration.test.ts +0 -354
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +0 -324
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +0 -221
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +0 -29
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +0 -168
- package/plugins/workflow-runner/test/webppt.load.test.ts +0 -250
- package/plugins/workflow-runner/test/word.load.test.ts +0 -208
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +0 -76
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +0 -207
- package/src/advisorState.js +0 -22
- package/src/cli/configWizard.js +0 -293
- package/src/tools/toolProgressBridge.js +0 -48
- package/workflows/adaptive-research.yaml +0 -50
- package/workflows/book-review-short.yaml +0 -125
- package/workflows/e2e-write-greet.yaml +0 -31
- package/workflows/illustrate.yaml +0 -227
- package/workflows/plan.yaml +0 -470
- package/workflows/ppt.yaml +0 -1670
- package/workflows/ralph-loop.yaml +0 -201
- package/workflows/research.yaml +0 -873
- package/workflows/schema.json +0 -176
- package/workflows/webppt.yaml +0 -496
- package/workflows/wechat-reading-shots.yaml +0 -315
- package/workflows/word.yaml +0 -720
- package/workflows/youtube-shorts.yaml +0 -202
- /package/workflows/{research.md → research/DESIGN.md} +0 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugins/workflow-runner/test/workflowState.test.ts —— 任务状态持久化
|
|
3
|
+
*
|
|
4
|
+
* 三条事故换来的语义,删任何一条之前先读 workflowState.ts 头注:
|
|
5
|
+
* ① **先归档再清理**:new-task 清理旧产物必须先 rename 进 `.trash/`,rm 只作兜底。
|
|
6
|
+
* 直接 rm 曾造成不可找回的损失(仲裁误判 new-task,11 个声明产物静默消失)。
|
|
7
|
+
* ② **归档失败不谎报位置**:一个文件都没成功移走就不能返回 archivedTo,
|
|
8
|
+
* 否则用户会去回收站找一个空目录 —— 比一开始就说「已删除」更糟。
|
|
9
|
+
* ③ **脚本变了断点作废**:同 taskId 但脚本内容改过 → 旧 journal 的调用序号
|
|
10
|
+
* 对不上新控制流,必须明示原因后全新开始,不能静默续跑到错误的位置。
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { afterEach, describe, expect, test } from 'bun:test';
|
|
14
|
+
import {
|
|
15
|
+
existsSync,
|
|
16
|
+
mkdirSync,
|
|
17
|
+
mkdtempSync,
|
|
18
|
+
rmSync,
|
|
19
|
+
writeFileSync,
|
|
20
|
+
} from 'node:fs';
|
|
21
|
+
import { tmpdir } from 'node:os';
|
|
22
|
+
import { join } from 'node:path';
|
|
23
|
+
|
|
24
|
+
import type { TaskArbitrator } from '../src/taskIdentity.js';
|
|
25
|
+
import { WorkflowState } from '../src/workflowState.js';
|
|
26
|
+
|
|
27
|
+
const dirs: string[] = [];
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
for (const d of dirs.splice(0)) {
|
|
30
|
+
// Windows 偶发 EBUSY,重试并吞掉 —— 否则会把上一条已通过的用例标红。
|
|
31
|
+
try {
|
|
32
|
+
rmSync(d, { recursive: true, force: true, maxRetries: 3 });
|
|
33
|
+
} catch {
|
|
34
|
+
/* 清理失败不影响断言 */
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
function workdir(): string {
|
|
40
|
+
const d = mkdtempSync(join(tmpdir(), 'wf-state-'));
|
|
41
|
+
dirs.push(d);
|
|
42
|
+
return d;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** 在工作目录里造一个产物文件。 */
|
|
46
|
+
function artifact(wd: string, rel: string, content = 'x'): string {
|
|
47
|
+
const abs = join(wd, rel);
|
|
48
|
+
mkdirSync(join(abs, '..'), { recursive: true });
|
|
49
|
+
writeFileSync(abs, content, 'utf8');
|
|
50
|
+
return abs;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const HASH = 'script-hash-v1';
|
|
54
|
+
|
|
55
|
+
describe('四态判定', () => {
|
|
56
|
+
test('资源和参数变化不通过语义仲裁回到旧断点或旧成品', async () => {
|
|
57
|
+
const wd = workdir();
|
|
58
|
+
const defs = [
|
|
59
|
+
{ name: 'source', type: 'resource' as const },
|
|
60
|
+
{ name: 'range' },
|
|
61
|
+
];
|
|
62
|
+
const inputs = {
|
|
63
|
+
source: '/image.png',
|
|
64
|
+
requestText: '转换',
|
|
65
|
+
__resource_fingerprint: 'bytes',
|
|
66
|
+
range: '1',
|
|
67
|
+
};
|
|
68
|
+
const first = new WorkflowState(wd, 'converter', 'session', defs);
|
|
69
|
+
await first.init(inputs, HASH, []);
|
|
70
|
+
let asked = false;
|
|
71
|
+
const next = new WorkflowState(wd, 'converter', 'session', defs);
|
|
72
|
+
const result = await next.init(
|
|
73
|
+
{ ...inputs, range: '2' },
|
|
74
|
+
HASH,
|
|
75
|
+
[],
|
|
76
|
+
async () => {
|
|
77
|
+
asked = true;
|
|
78
|
+
return 'resume';
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
expect(result.mode).toBe('new-task');
|
|
82
|
+
expect(asked).toBe(false);
|
|
83
|
+
expect(next.taskId).not.toBe(first.taskId);
|
|
84
|
+
await first.markDone([]);
|
|
85
|
+
await first.archive();
|
|
86
|
+
expect(
|
|
87
|
+
(
|
|
88
|
+
await new WorkflowState(wd, 'converter', 'session', defs).init(
|
|
89
|
+
{ ...inputs, range: '3' },
|
|
90
|
+
HASH,
|
|
91
|
+
[],
|
|
92
|
+
)
|
|
93
|
+
).mode,
|
|
94
|
+
).not.toBe('completed');
|
|
95
|
+
});
|
|
96
|
+
for (const completed of [false, true]) {
|
|
97
|
+
test(`dependency change retires the real journal and dynamic outputs (${completed ? 'completed' : 'failed'})`, async () => {
|
|
98
|
+
const wd = workdir();
|
|
99
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
100
|
+
const inputs = { goal: 'same target' };
|
|
101
|
+
await st.init(inputs, HASH, []);
|
|
102
|
+
artifact(wd, 'out/dynamic.png', 'old image bytes');
|
|
103
|
+
writeFileSync(
|
|
104
|
+
st.journalPath,
|
|
105
|
+
'{"seq":1,"kind":"tool","fp":"old","result":"stale"}\n',
|
|
106
|
+
);
|
|
107
|
+
if (completed) {
|
|
108
|
+
await st.markDone(['out/dynamic.png']);
|
|
109
|
+
await st.archive();
|
|
110
|
+
} else await st.recordFailure('network', ['out/dynamic.png']);
|
|
111
|
+
const next = new WorkflowState(wd, 'demo', 's1');
|
|
112
|
+
const info = await next.init(inputs, 'changed-bundle', []);
|
|
113
|
+
expect(info.scriptChanged).toBe(true);
|
|
114
|
+
expect(existsSync(next.journalPath)).toBe(false);
|
|
115
|
+
expect(existsSync(join(wd, 'out/dynamic.png'))).toBe(false);
|
|
116
|
+
expect(existsSync(join(wd, info.archivedTo!, 'out/dynamic.png'))).toBe(
|
|
117
|
+
true,
|
|
118
|
+
);
|
|
119
|
+
expect(
|
|
120
|
+
existsSync(join(wd, info.archivedTo!, 'state/journal.jsonl')),
|
|
121
|
+
).toBe(true);
|
|
122
|
+
// The retired .done must not shadow the new, unfinished attempt.
|
|
123
|
+
expect(
|
|
124
|
+
(
|
|
125
|
+
await new WorkflowState(wd, 'demo', 's1').init(
|
|
126
|
+
inputs,
|
|
127
|
+
'changed-bundle',
|
|
128
|
+
[],
|
|
129
|
+
)
|
|
130
|
+
).mode,
|
|
131
|
+
).toBe('resume');
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
test('首次运行 → fresh,实例目录与 current.json 建好', async () => {
|
|
136
|
+
const wd = workdir();
|
|
137
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
138
|
+
const r = await st.init({ goal: '目标 A' }, HASH, []);
|
|
139
|
+
|
|
140
|
+
expect(r.mode).toBe('fresh');
|
|
141
|
+
expect(st.taskId).toHaveLength(16);
|
|
142
|
+
expect(existsSync(join(st.dir, 'current.json'))).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('同任务未完成 → resume', async () => {
|
|
146
|
+
const wd = workdir();
|
|
147
|
+
const inputs = { goal: '目标 A' };
|
|
148
|
+
await new WorkflowState(wd, 'demo', 's1').init(inputs, HASH, []);
|
|
149
|
+
|
|
150
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(inputs, HASH, []);
|
|
151
|
+
expect(r.mode).toBe('resume');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('同任务已完成 → completed,只报磁盘上实际存在的产物', async () => {
|
|
155
|
+
const wd = workdir();
|
|
156
|
+
const inputs = { goal: '目标 A' };
|
|
157
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
158
|
+
await st.init(inputs, HASH, ['out/real.md', 'out/never-made.md']);
|
|
159
|
+
artifact(wd, 'out/real.md');
|
|
160
|
+
await st.markDone();
|
|
161
|
+
await st.archive();
|
|
162
|
+
|
|
163
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(inputs, HASH, [
|
|
164
|
+
'out/real.md',
|
|
165
|
+
'out/never-made.md',
|
|
166
|
+
]);
|
|
167
|
+
expect(r.mode).toBe('completed');
|
|
168
|
+
expect(r.artifacts).toEqual(['out/real.md']); // 声明了但没产出的不许报
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('★ 同任务但脚本内容变了 → new-task + scriptChanged,断点作废且明示原因', async () => {
|
|
172
|
+
const wd = workdir();
|
|
173
|
+
const inputs = { goal: '目标 A' };
|
|
174
|
+
await new WorkflowState(wd, 'demo', 's1').init(inputs, HASH, []);
|
|
175
|
+
|
|
176
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
177
|
+
inputs,
|
|
178
|
+
'script-hash-v2',
|
|
179
|
+
[],
|
|
180
|
+
);
|
|
181
|
+
expect(r.mode).toBe('new-task');
|
|
182
|
+
expect(r.scriptChanged).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('★ 已完成 + 脚本改过 → 不许报 completed,必须按新脚本重跑', async () => {
|
|
186
|
+
// 端到端实跑抓到的:改完工作流重跑同一目标,1 秒返回「此前已完成」+ 旧产物。
|
|
187
|
+
// 那份结论是**另一份脚本**产出的 —— 作者刚改完逻辑,最想要的正是重跑一遍。
|
|
188
|
+
// 报 completed 等于静默给错答案。
|
|
189
|
+
const wd = workdir();
|
|
190
|
+
const inputs = { goal: '目标 A' };
|
|
191
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
192
|
+
await st.init(inputs, HASH, []);
|
|
193
|
+
await st.markDone();
|
|
194
|
+
await st.archive();
|
|
195
|
+
|
|
196
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
197
|
+
inputs,
|
|
198
|
+
'script-hash-v2',
|
|
199
|
+
[],
|
|
200
|
+
);
|
|
201
|
+
expect(r.mode).toBe('new-task');
|
|
202
|
+
expect(r.scriptChanged).toBe(true);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test('★ 运行时 declareArtifact 登记的产物必须落盘,否则下次 completed 报 0 产物', async () => {
|
|
206
|
+
// meta.artifacts 是静态字面量,写不出 `out/${session}/page-3.png` 这种带下标的
|
|
207
|
+
// 路径 —— 循环体里的逐迭代产物只能靠运行时登记。不落盘就静默漏档:
|
|
208
|
+
// completed 少报、new-task 清理也漏掉。端到端实跑抓到过。
|
|
209
|
+
const wd = workdir();
|
|
210
|
+
const inputs = { goal: '目标 A' };
|
|
211
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
212
|
+
await st.init(inputs, HASH, []); // 静态声明为空
|
|
213
|
+
artifact(wd, 'out/runtime-declared.md');
|
|
214
|
+
await st.markDone(['out/runtime-declared.md']); // 运行时登记的
|
|
215
|
+
await st.archive();
|
|
216
|
+
|
|
217
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(inputs, HASH, []);
|
|
218
|
+
expect(r.mode).toBe('completed');
|
|
219
|
+
expect(r.artifacts).toEqual(['out/runtime-declared.md']);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('★ 同 session 换主题 → 各自独立实例,互不干扰', async () => {
|
|
223
|
+
const wd = workdir();
|
|
224
|
+
const a = new WorkflowState(wd, 'demo', 's1');
|
|
225
|
+
await a.init({ goal: '调研 A' }, HASH, []);
|
|
226
|
+
const b = new WorkflowState(wd, 'demo', 's1');
|
|
227
|
+
await b.init({ goal: '调研 B' }, HASH, [], async () => 'new');
|
|
228
|
+
|
|
229
|
+
expect(a.dir).not.toBe(b.dir);
|
|
230
|
+
expect(existsSync(join(a.dir, 'current.json'))).toBe(true);
|
|
231
|
+
expect(existsSync(join(b.dir, 'current.json'))).toBe(true);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
describe('语义仲裁接入', () => {
|
|
236
|
+
const resumeArb: TaskArbitrator = async () => 'resume';
|
|
237
|
+
const newArb: TaskArbitrator = async () => 'new';
|
|
238
|
+
|
|
239
|
+
test('★ 仲裁判 resume → 采纳旧实例目录,新输入降级成补充要求', async () => {
|
|
240
|
+
const wd = workdir();
|
|
241
|
+
const first = new WorkflowState(wd, 'demo', 's1');
|
|
242
|
+
await first.init({ goal: '调研 A 主题' }, HASH, []);
|
|
243
|
+
|
|
244
|
+
const second = new WorkflowState(wd, 'demo', 's1');
|
|
245
|
+
const r = await second.init({ goal: '继续' }, HASH, [], resumeArb);
|
|
246
|
+
|
|
247
|
+
expect(r.mode).toBe('resume');
|
|
248
|
+
expect(second.dir).toBe(first.dir); // 用的是旧实例,不是新建一个
|
|
249
|
+
// 目标锚必须指向旧目标 —— 拿「继续」当目标会让后续每次调用都跑偏
|
|
250
|
+
expect(r.prevGoal).toBe('调研 A 主题');
|
|
251
|
+
expect(r.supplementaryGoal).toBe('继续');
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('仲裁判 new → 建新实例,旧的原样留着', async () => {
|
|
255
|
+
const wd = workdir();
|
|
256
|
+
const first = new WorkflowState(wd, 'demo', 's1');
|
|
257
|
+
await first.init({ goal: '调研 A 主题' }, HASH, []);
|
|
258
|
+
|
|
259
|
+
const second = new WorkflowState(wd, 'demo', 's1');
|
|
260
|
+
const r = await second.init({ goal: '完全不同的事' }, HASH, [], newArb);
|
|
261
|
+
|
|
262
|
+
expect(r.mode).toBe('new-task');
|
|
263
|
+
expect(second.dir).not.toBe(first.dir);
|
|
264
|
+
expect(existsSync(join(first.dir, 'current.json'))).toBe(true);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
test('没有未完成的兄弟任务时不调用仲裁(省一次 LLM)', async () => {
|
|
268
|
+
const wd = workdir();
|
|
269
|
+
let called = false;
|
|
270
|
+
await new WorkflowState(wd, 'demo', 's1').init(
|
|
271
|
+
{ goal: 'x' },
|
|
272
|
+
HASH,
|
|
273
|
+
[],
|
|
274
|
+
async () => {
|
|
275
|
+
called = true;
|
|
276
|
+
return 'new';
|
|
277
|
+
},
|
|
278
|
+
);
|
|
279
|
+
expect(called).toBe(false);
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('声明产物的先归档再清理', () => {
|
|
284
|
+
test('★ 旧产物被 move 进 .trash 而不是直接删掉', async () => {
|
|
285
|
+
const wd = workdir();
|
|
286
|
+
await new WorkflowState(wd, 'demo', 's1').init({ goal: 'A' }, HASH, [
|
|
287
|
+
'out/report.md',
|
|
288
|
+
]);
|
|
289
|
+
artifact(wd, 'out/report.md', '重要成果');
|
|
290
|
+
|
|
291
|
+
const second = new WorkflowState(wd, 'demo', 's1');
|
|
292
|
+
const r = await second.init(
|
|
293
|
+
{ goal: 'B' },
|
|
294
|
+
HASH,
|
|
295
|
+
['out/report.md'],
|
|
296
|
+
async () => 'new',
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
expect(r.mode).toBe('new-task');
|
|
300
|
+
expect(existsSync(join(wd, 'out/report.md'))).toBe(false); // 已从工作目录移走
|
|
301
|
+
expect(r.archivedTo).toBeDefined();
|
|
302
|
+
// 而且真的能在回收目录里找回来
|
|
303
|
+
expect(existsSync(join(wd, r.archivedTo as string, 'out/report.md'))).toBe(
|
|
304
|
+
true,
|
|
305
|
+
);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
test('★ 没有任何产物可归档时不填 archivedTo(不谎报位置)', async () => {
|
|
309
|
+
const wd = workdir();
|
|
310
|
+
await new WorkflowState(wd, 'demo', 's1').init({ goal: 'A' }, HASH, [
|
|
311
|
+
'out/never.md',
|
|
312
|
+
]);
|
|
313
|
+
|
|
314
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
315
|
+
{ goal: 'B' },
|
|
316
|
+
HASH,
|
|
317
|
+
['out/never.md'],
|
|
318
|
+
async () => 'new',
|
|
319
|
+
);
|
|
320
|
+
expect(r.archivedTo).toBeUndefined();
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test('glob 声明按实际匹配展开', async () => {
|
|
324
|
+
const wd = workdir();
|
|
325
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
326
|
+
await st.init({ goal: 'A' }, HASH, ['research/*.md']);
|
|
327
|
+
// ⚠️ 产物必须在 init **之后**造:fresh 启动会把已存在的声明产物残留
|
|
328
|
+
// 归档清理掉(`/new` 之后的孤儿文件靠这条),init 之前造等于自己清掉自己。
|
|
329
|
+
artifact(wd, 'research/01-a.md');
|
|
330
|
+
artifact(wd, 'research/02-b.md');
|
|
331
|
+
artifact(wd, 'research/notes.txt');
|
|
332
|
+
await st.markDone();
|
|
333
|
+
await st.archive();
|
|
334
|
+
|
|
335
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
336
|
+
{ goal: 'A' },
|
|
337
|
+
HASH,
|
|
338
|
+
['research/*.md'],
|
|
339
|
+
);
|
|
340
|
+
expect(r.artifacts?.sort()).toEqual([
|
|
341
|
+
'research/01-a.md',
|
|
342
|
+
'research/02-b.md',
|
|
343
|
+
]);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
test('★ 越界路径 fail-closed —— 声明 ../ 跳出 cwd 的产物一律无视', async () => {
|
|
347
|
+
const wd = workdir();
|
|
348
|
+
const outside = join(wd, '..', 'outside-victim.md');
|
|
349
|
+
writeFileSync(outside, '别人的文件', 'utf8');
|
|
350
|
+
try {
|
|
351
|
+
await new WorkflowState(wd, 'demo', 's1').init({ goal: 'A' }, HASH, [
|
|
352
|
+
'../outside-victim.md',
|
|
353
|
+
]);
|
|
354
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
355
|
+
{ goal: 'B' },
|
|
356
|
+
HASH,
|
|
357
|
+
['../outside-victim.md'],
|
|
358
|
+
async () => 'new',
|
|
359
|
+
);
|
|
360
|
+
expect(r.cleanedArtifacts ?? []).toEqual([]);
|
|
361
|
+
expect(existsSync(outside)).toBe(true); // 一根汗毛都没动
|
|
362
|
+
} finally {
|
|
363
|
+
rmSync(outside, { force: true });
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
describe('补充要求持久化', () => {
|
|
369
|
+
test('追加后可读回,跨实例(跨进程)不丢', async () => {
|
|
370
|
+
const wd = workdir();
|
|
371
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
372
|
+
await st.init({ goal: 'A' }, HASH, []);
|
|
373
|
+
await st.appendSupplement('改成 12 页');
|
|
374
|
+
|
|
375
|
+
const again = new WorkflowState(wd, 'demo', 's1');
|
|
376
|
+
await again.init({ goal: 'A' }, HASH, []);
|
|
377
|
+
expect(await again.readSupplements()).toEqual(['改成 12 页']);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
test('重复内容不重复追加(否则每次 resume 都会翻倍)', async () => {
|
|
381
|
+
const wd = workdir();
|
|
382
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
383
|
+
await st.init({ goal: 'A' }, HASH, []);
|
|
384
|
+
await st.appendSupplement('改成 12 页');
|
|
385
|
+
await st.appendSupplement('改成 12 页');
|
|
386
|
+
expect(await st.readSupplements()).toHaveLength(1);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
test('空白内容被忽略', async () => {
|
|
390
|
+
const wd = workdir();
|
|
391
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
392
|
+
await st.init({ goal: 'A' }, HASH, []);
|
|
393
|
+
await st.appendSupplement(' ');
|
|
394
|
+
expect(await st.readSupplements()).toEqual([]);
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
describe('归档与失败记录', () => {
|
|
399
|
+
test('archive() 把实例目录改名成 .done', async () => {
|
|
400
|
+
const wd = workdir();
|
|
401
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
402
|
+
await st.init({ goal: 'A' }, HASH, []);
|
|
403
|
+
const before = st.dir;
|
|
404
|
+
await st.markDone();
|
|
405
|
+
await st.archive();
|
|
406
|
+
expect(st.dir).toBe(`${before}.done`);
|
|
407
|
+
expect(existsSync(before)).toBe(false);
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
test('recordFailure 的原因在下次 resume 时读得到', async () => {
|
|
411
|
+
const wd = workdir();
|
|
412
|
+
const st = new WorkflowState(wd, 'demo', 's1');
|
|
413
|
+
await st.init({ goal: 'A' }, HASH, []);
|
|
414
|
+
await st.recordFailure('provider 返回 429');
|
|
415
|
+
|
|
416
|
+
const r = await new WorkflowState(wd, 'demo', 's1').init(
|
|
417
|
+
{ goal: 'A' },
|
|
418
|
+
HASH,
|
|
419
|
+
[],
|
|
420
|
+
);
|
|
421
|
+
expect(r.lastError).toBe('provider 返回 429');
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
test('progress 日志写失败不该让任务挂掉', async () => {
|
|
425
|
+
const st = new WorkflowState(workdir(), 'demo', 's1');
|
|
426
|
+
// 没 init,dir 为空 → 写盘必失败;但不许抛
|
|
427
|
+
await expect(st.appendProgress('一行')).resolves.toBeUndefined();
|
|
428
|
+
});
|
|
429
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1330 750">
|
|
2
|
+
<!-- 封面满铺美术背景:渐变 + 有机色块 + 一条流线。
|
|
3
|
+
注意:标题文字不写在 SVG 里 —— 留给 pptx 原生文字层(可编辑、可重排)。
|
|
4
|
+
每个语义元素用独立 <g>,PowerPoint「转换为形状」后即得干净可编辑形状。 -->
|
|
5
|
+
<defs>
|
|
6
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
7
|
+
<stop offset="0" stop-color="#0F172A"/>
|
|
8
|
+
<stop offset="0.55" stop-color="#1E2761"/>
|
|
9
|
+
<stop offset="1" stop-color="#024E5B"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<radialGradient id="glow" cx="0.5" cy="0.5" r="0.5">
|
|
12
|
+
<stop offset="0" stop-color="#00A896" stop-opacity="0.55"/>
|
|
13
|
+
<stop offset="1" stop-color="#00A896" stop-opacity="0"/>
|
|
14
|
+
</radialGradient>
|
|
15
|
+
</defs>
|
|
16
|
+
<g id="background"><rect width="1330" height="750" fill="url(#bg)"/></g>
|
|
17
|
+
<g id="glow-orb"><circle cx="1020" cy="250" r="320" fill="url(#glow)"/></g>
|
|
18
|
+
<g id="ice-disc"><circle cx="1080" cy="200" r="150" fill="#CADCFC" opacity="0.9"/></g>
|
|
19
|
+
<g id="flow-line">
|
|
20
|
+
<path d="M0 600 Q 360 470 700 560 T 1330 470" stroke="#FFFFFF" stroke-width="3" fill="none" opacity="0.6"/>
|
|
21
|
+
</g>
|
|
22
|
+
<g id="accent-bar"><rect x="80" y="300" width="70" height="8" rx="4" fill="#00A896"/></g>
|
|
23
|
+
</svg>
|
|
@@ -13,7 +13,10 @@ description: 高质量「样式与视觉设计」的统一入口,覆盖 web
|
|
|
13
13
|
|
|
14
14
|
本技能同时服务两类产物、规则差异很大——**先认领路径,别读错规则带偏构图**:
|
|
15
15
|
|
|
16
|
-
- 🅰 **deck / PPT
|
|
16
|
+
- 🅰 **deck / PPT 导出**(最常见):目标是**静态、可编辑的 PPTX**。
|
|
17
|
+
> ⚠️ 曾经有一条 `/workflow ppt` 把下面这套脚本按序串起来,它随 yaml DSL 一并**下线**了
|
|
18
|
+
> (脚本与本技能都还在,只是没有现成编排了)。捞回旧编排:`git show ffbb313:workflows/ppt.yaml`,
|
|
19
|
+
> 重写成代码形态见 `skills/workflow-creator/references/migration.md`。在那之前,按下面的流程手动走。
|
|
17
20
|
- **只读** `references/layout-composition.md`(grid 结构化构图 + 0.6 每页内容预算 + 图文混排)+ `references/export-pptx.md`(背景/前景/文本三层**自动分层**,标注可选)。
|
|
18
21
|
- **流程**:按 archetype 用 CSS grid **大胆把画布填满**地排 `deck.html`(分层自动,正常写语义化 HTML 即可)→ `check_ui_artifact.py --for-pptx-export` 拦截坏 HTML(重复 head/body、裸 CSS、结构错误)→ `export_pptx_from_html.mjs --measure-only` 量几何 → `layout_balance.py` 判(硬门=**真重叠**、**截图夹带 HTML/SVG 文本**、**整页无内容**;软门=空半、挤角、空心卡片、覆盖率偏低等构图警告)→ 出现错误时按"问题+归一化坐标"改 HTML 重判直到通过 → `--mode hybrid` 导出一次 → `opc_check.py` 校验。
|
|
19
22
|
- **以下网页规则对 deck 不适用**(下文看到请直接跳过):`claude_design.md`、Tweaks/EDITMODE、localStorage/postMessage、React/Babel、JS 视口缩放、翻页 nav、`browser_check`(deck 走 `layout_balance` 闸门,不走 browser_check)。
|
|
@@ -147,7 +150,7 @@ description: 高质量「样式与视觉设计」的统一入口,覆盖 web
|
|
|
147
150
|
- `--catastrophic-only`:**只**报「内容不可见灾难」(严重越界 + 无真实视觉的空页),**抑制**重叠/占空族噪声——供导出阶段做**回归安全的几何硬门**(不误伤只有良性相邻/嵌套重叠的干净 deck)。治本仍在 `layout-composition.md` §0.7 的 `min-width:0` 骨架。
|
|
148
151
|
- `--ppt-strict`(2026-07-02,ppt 视觉门专用、默认关 = webppt 行为不变):①重叠**去噪**——剔行盒贴边/膨胀父盒包含/行盒尾部(纵横)四类 box 模型伪象,只留真碰撞(真机 57 条→9 条全真);②任何越界(含「超出下边缘」)升 ERROR;③**大空卡**(≥15% 页面、填充 <10%、且没被媒体块盖住 ≥70%——需 measure 产物带 mediaRects)升【空心大卡】ERROR;④(2026-07-03)**R6 导出加宽框幻影剔除**——重叠框按原点匹配回原始 textRuns 行盒重算,交叠归零的整条剔除(副标题导出框 h 达真实 2×、凭空压到下方卡片的假 ERROR);⑤**R5 媒体卡内文字降 WARNING**——文字 ≥85% 落在含媒体前景卡内(caption/图内说明字,fgParent 断链才漏成重叠)降【媒体卡内文字】WARNING,可读性交像素门裁决;非媒体卡包含/骑边/text⊃fg 仍 ERROR(裸 `<img>` 自身作前景块时 hasMedia 恒 false,靠 fgRects 加性 `tag` 字段识别)。
|
|
149
152
|
|
|
150
|
-
**ppt
|
|
153
|
+
**ppt 专属脚本(原 `/workflow ppt` 按序调用;该工作流已随 yaml DSL 下线,现按下面的顺序手动走,细节 `--help`)**:
|
|
151
154
|
- 素材摄取:`resolve_source_input.py` → `extract_source_assets.py` → `assemble_material.py` → `plan_source_layout.py`(每张客户图确定性算定 route/模板/文字落区/是否图生图)。
|
|
152
155
|
- 设计文档(design.json):`normalize_design_json.py`(归一化字段)→ `design_budget_check.py`(每页要点数/字数预算防溢出,纯文本层)→ `design_style_check.py` / `deck_visual_style_check.py`(构图风格枚举 / 卡片墙·表格墙倾向 / **视觉优先内容形状**:max_visible_words 对账 + 影像叙事页 ≤3 条短语 + 文章化倾向 WARNING——治「文本阅读型页面」;`speaker_notes` 讲稿字段不计上屏、不参与倾向扫描,经 deck 的 `<aside class="speaker-notes" hidden>` 导出进 PPT 备注栏)→ `design_repair_hints.py`(有 ERROR 时收敛成小批修复提示)。
|
|
153
156
|
- 配图:`image_prompt_rewrite.py`(t2i 提示词**唯一生产/净化点**:绑定页面锚点,且与 image_plan_lint **共享黑名单词表**——design 字段/原 prompt 里的结构词·坏审美词在拼接前被剥掉或触发安全重组,产出保证过 lint。**2026-07-03 背景层去内容化**:背景 t2i/i2i 提示词不再拼 `Slide title:/Core message:` 字面正文与图表描述——Seedream 类文字渲染型模型会照着画出整版烘字假幻灯片(ai_p9 事故),页面绑定只靠去数字化/去句子碎片的场景名词锚)→ `image_plan_lint.py`(兜底验证;ppt 链路只扫 img_plan prompt 不带 `--outline`,webppt 仍扫 note;新增 slide_copy 检查:背景 t2i prompt 含页标题/正文标记/图表词 → ERROR)/ `generated_image_review_collect.py`(生成图语义复核汇总——**已屏蔽**:2026-07-02 用户裁决验证只走确定性脚本,ppt.yaml 阶段14-16 when:"false",恢复方法见该处注释;生成图带字风险由前述提示词去内容化+lint 从源头拦)。
|
|
@@ -413,7 +413,7 @@ PPT 不是每页都要浮动卡片。先根据内容和素材选择**整页视
|
|
|
413
413
|
|
|
414
414
|
### 2.2.1 `composition_style` 机器枚举(design.json 必填)
|
|
415
415
|
|
|
416
|
-
|
|
416
|
+
ppt 链路的 `design.json` 每页必须写 `composition_style`,构建时按它落地,不再只靠 `archetype/composition` 猜:
|
|
417
417
|
|
|
418
418
|
| composition_style | 首选用途 | 视觉重量 | 禁用项 |
|
|
419
419
|
|---|---|---:|---|
|