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
|
@@ -39,9 +39,9 @@ import { spawn } from 'node:child_process';
|
|
|
39
39
|
import { chmodSync, existsSync } from 'node:fs';
|
|
40
40
|
import { dirname, isAbsolute, resolve, win32 } from 'node:path';
|
|
41
41
|
|
|
42
|
+
import { sanitizeCredentialEnv } from '../../config/configService.js';
|
|
42
43
|
import { execSiblingDir } from '../../utils/greenRoot.js';
|
|
43
44
|
import { findPackageRoot } from '../../utils/packageRoot.js';
|
|
44
|
-
import { sanitizeCredentialEnv } from '../../config/configService.js';
|
|
45
45
|
|
|
46
46
|
/** 可注入依赖(默认走真实实现,单测注入假实现)。 */
|
|
47
47
|
export interface ResolveDeps {
|
|
@@ -104,7 +104,11 @@ export function _resetAgentBrowserCache(): void {
|
|
|
104
104
|
* 经 CLI 调 agent-browser 的 skill/bash 走 agent-browser 自身的自动探测/在线安装。
|
|
105
105
|
*/
|
|
106
106
|
export async function ensureAgentBrowserOnPath(): Promise<void> {
|
|
107
|
-
applyBinToPath(
|
|
107
|
+
applyBinToPath(
|
|
108
|
+
await resolveAgentBrowserPath(),
|
|
109
|
+
process.env,
|
|
110
|
+
process.platform,
|
|
111
|
+
);
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
/** 纯函数:把 bin 所在目录前置进 env.PATH(已含则跳过;非绝对路径/null 不动)。 */
|
|
@@ -124,7 +128,9 @@ export function applyBinToPath(
|
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
/** 纯解析(可注入依赖):按 ①→⑤ 优先级返回 agent-browser 二进制路径或 null。 */
|
|
127
|
-
export async function detectAgentBrowser(
|
|
131
|
+
export async function detectAgentBrowser(
|
|
132
|
+
deps: ResolveDeps,
|
|
133
|
+
): Promise<string | null> {
|
|
128
134
|
const sub = subdir(deps);
|
|
129
135
|
const bin = binName(deps);
|
|
130
136
|
|
|
@@ -143,7 +149,13 @@ export async function detectAgentBrowser(deps: ResolveDeps): Promise<string | nu
|
|
|
143
149
|
}
|
|
144
150
|
|
|
145
151
|
// ③ 绿色版 exe 同级
|
|
146
|
-
const sibling = resolve(
|
|
152
|
+
const sibling = resolve(
|
|
153
|
+
deps.siblingDir(),
|
|
154
|
+
'vendor',
|
|
155
|
+
'agent-browser',
|
|
156
|
+
sub,
|
|
157
|
+
bin,
|
|
158
|
+
);
|
|
147
159
|
if (deps.exists(sibling)) {
|
|
148
160
|
ensureExecutable(sibling, deps.platform);
|
|
149
161
|
return sibling;
|
|
@@ -163,9 +175,13 @@ export async function detectAgentBrowser(deps: ResolveDeps): Promise<string | nu
|
|
|
163
175
|
* 约定布局:vendor/chromium/<arch>-<platform>/ 下放该平台 chromium,可执行名按平台
|
|
164
176
|
* 探测一组常见相对路径(不同 chromium 构建解包名不一,宁可多探几个)。
|
|
165
177
|
*/
|
|
166
|
-
export function resolveBundledChromium(
|
|
178
|
+
export function resolveBundledChromium(
|
|
179
|
+
deps: ResolveDeps = realDeps(),
|
|
180
|
+
): string | null {
|
|
167
181
|
const sub = subdir(deps);
|
|
168
|
-
const roots: string[] = [
|
|
182
|
+
const roots: string[] = [
|
|
183
|
+
resolve(deps.siblingDir(), 'vendor', 'chromium', sub),
|
|
184
|
+
];
|
|
169
185
|
const root = deps.packageRoot();
|
|
170
186
|
if (root) roots.push(resolve(root, 'vendor', 'chromium', sub));
|
|
171
187
|
|
|
@@ -186,33 +202,59 @@ export function resolveBundledChromium(deps: ResolveDeps = realDeps()): string |
|
|
|
186
202
|
* own profile directory. This improves site compatibility without touching
|
|
187
203
|
* the user's normal Chrome profile or attempting fingerprint evasion.
|
|
188
204
|
*/
|
|
189
|
-
export function resolveSystemBrowser(
|
|
190
|
-
|
|
191
|
-
|
|
205
|
+
export function resolveSystemBrowser(
|
|
206
|
+
deps: ResolveDeps = realDeps(),
|
|
207
|
+
): string | null {
|
|
208
|
+
const explicit =
|
|
209
|
+
deps.env.MINIMAL_AGENT_BROWSER_EXECUTABLE_PATH ??
|
|
210
|
+
deps.env.AGENT_BROWSER_EXECUTABLE_PATH;
|
|
192
211
|
if (explicit && deps.exists(explicit)) return explicit;
|
|
193
212
|
|
|
194
213
|
const home = deps.env.HOME ?? deps.env.USERPROFILE ?? '';
|
|
195
|
-
const candidates =
|
|
196
|
-
|
|
197
|
-
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
198
|
-
'/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
|
|
199
|
-
'/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
200
|
-
home ? resolve(home, 'Applications/Google Chrome.app/Contents/MacOS/Google Chrome') : '',
|
|
201
|
-
]
|
|
202
|
-
: deps.platform === 'win32'
|
|
214
|
+
const candidates =
|
|
215
|
+
deps.platform === 'darwin'
|
|
203
216
|
? [
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
217
|
+
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
218
|
+
'/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',
|
|
219
|
+
'/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
220
|
+
home
|
|
221
|
+
? resolve(
|
|
222
|
+
home,
|
|
223
|
+
'Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
|
|
224
|
+
)
|
|
225
|
+
: '',
|
|
207
226
|
]
|
|
208
|
-
:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
227
|
+
: deps.platform === 'win32'
|
|
228
|
+
? [
|
|
229
|
+
deps.env.PROGRAMFILES
|
|
230
|
+
? resolve(
|
|
231
|
+
deps.env.PROGRAMFILES,
|
|
232
|
+
'Google/Chrome/Application/chrome.exe',
|
|
233
|
+
)
|
|
234
|
+
: '',
|
|
235
|
+
deps.env['PROGRAMFILES(X86)']
|
|
236
|
+
? resolve(
|
|
237
|
+
deps.env['PROGRAMFILES(X86)'],
|
|
238
|
+
'Microsoft/Edge/Application/msedge.exe',
|
|
239
|
+
)
|
|
240
|
+
: '',
|
|
241
|
+
deps.env.LOCALAPPDATA
|
|
242
|
+
? resolve(
|
|
243
|
+
deps.env.LOCALAPPDATA,
|
|
244
|
+
'Google/Chrome/Application/chrome.exe',
|
|
245
|
+
)
|
|
246
|
+
: '',
|
|
247
|
+
]
|
|
248
|
+
: [
|
|
249
|
+
'/usr/bin/google-chrome-stable',
|
|
250
|
+
'/usr/bin/google-chrome',
|
|
251
|
+
'/usr/bin/microsoft-edge-stable',
|
|
252
|
+
'/usr/bin/chromium',
|
|
253
|
+
'/usr/bin/chromium-browser',
|
|
254
|
+
];
|
|
255
|
+
return (
|
|
256
|
+
candidates.find((candidate) => candidate && deps.exists(candidate)) ?? null
|
|
257
|
+
);
|
|
216
258
|
}
|
|
217
259
|
|
|
218
260
|
/** vendor 子目录名 = <arch>-<platform>(对齐 rgPath.ts / build-green.ts 的 vendor 约定)。 */
|
|
@@ -15,7 +15,7 @@ import { chmod, mkdir, readdir, realpath, rm, stat } from 'node:fs/promises';
|
|
|
15
15
|
import os from 'node:os';
|
|
16
16
|
import path from 'node:path';
|
|
17
17
|
import { sanitizeCredentialEnv } from '../../config/configService.js';
|
|
18
|
-
import {
|
|
18
|
+
import { pathContainedByAny, pathContains } from '../../utils/pathContains.js';
|
|
19
19
|
/**
|
|
20
20
|
* minimal-agent 进程级固定 session 名:隔离机器上其它 agent-browser 用法,
|
|
21
21
|
* 同时让本进程多次调用复用同一浏览器(与原 playwright「一 session 一 page」语义一致)。
|
|
@@ -38,7 +38,11 @@ export async function ensureBrowserProfile(profileId = 'default') {
|
|
|
38
38
|
return profile;
|
|
39
39
|
}
|
|
40
40
|
export async function browserGlobalArgs(sessionName = BROWSER_SESSION, profileId = 'default') {
|
|
41
|
-
return [
|
|
41
|
+
return [
|
|
42
|
+
...sessionArgs(sessionName),
|
|
43
|
+
'--profile',
|
|
44
|
+
await ensureBrowserProfile(profileId),
|
|
45
|
+
];
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
44
48
|
* 默认 spawn 运行器:收集 stdout/stderr 后结算;spawn 抛错也 resolve 成失败。
|
|
@@ -83,13 +87,21 @@ export const spawnRunner = (bin, args, signal) => new Promise((resolveP) => {
|
|
|
83
87
|
});
|
|
84
88
|
}
|
|
85
89
|
catch (e) {
|
|
86
|
-
resolveP({
|
|
90
|
+
resolveP({
|
|
91
|
+
code: -1,
|
|
92
|
+
stdout: '',
|
|
93
|
+
stderr: e instanceof Error ? e.message : String(e),
|
|
94
|
+
});
|
|
87
95
|
return;
|
|
88
96
|
}
|
|
89
97
|
child.stdout?.setEncoding('utf8');
|
|
90
|
-
child.stdout?.on('data', (c) =>
|
|
98
|
+
child.stdout?.on('data', (c) => {
|
|
99
|
+
stdout += c;
|
|
100
|
+
});
|
|
91
101
|
child.stderr?.setEncoding('utf8');
|
|
92
|
-
child.stderr?.on('data', (c) =>
|
|
102
|
+
child.stderr?.on('data', (c) => {
|
|
103
|
+
stderr += c;
|
|
104
|
+
});
|
|
93
105
|
child.on('error', (e) => finish(-1, e instanceof Error ? e.message : String(e)));
|
|
94
106
|
// 正常路径:'close' 紧随 'exit'(pipe 关闭)→ 以完整输出立即结算,并清掉宽限计时器。
|
|
95
107
|
child.on('close', (code) => finish(code));
|
|
@@ -169,10 +181,14 @@ async function pruneStaleArtifacts(dir) {
|
|
|
169
181
|
if (info.mtimeMs < cutoff)
|
|
170
182
|
await rm(target, { force: true, recursive: true });
|
|
171
183
|
}
|
|
172
|
-
catch {
|
|
184
|
+
catch {
|
|
185
|
+
/* 单个文件清不掉不影响其它 */
|
|
186
|
+
}
|
|
173
187
|
}));
|
|
174
188
|
}
|
|
175
|
-
catch {
|
|
189
|
+
catch {
|
|
190
|
+
/* 目录不存在或不可读:没什么可清的 */
|
|
191
|
+
}
|
|
176
192
|
}
|
|
177
193
|
/**
|
|
178
194
|
* 生成一个托管的产物输出路径,并确保目录存在、旧产物已清理。
|
|
@@ -216,7 +232,9 @@ const ALLOWED_URL_SCHEMES = new Set(['http', 'https', 'about', 'file']);
|
|
|
216
232
|
* 而不是替调用方创建——凭一个路径参数就造目录树同样是越权。
|
|
217
233
|
*/
|
|
218
234
|
export async function validateArtifactOutputPath(candidate, allowedRoots) {
|
|
219
|
-
const absolute = path.isAbsolute(candidate)
|
|
235
|
+
const absolute = path.isAbsolute(candidate)
|
|
236
|
+
? candidate
|
|
237
|
+
: path.resolve(candidate);
|
|
220
238
|
const parent = path.dirname(absolute);
|
|
221
239
|
let realParent;
|
|
222
240
|
try {
|
|
@@ -236,9 +254,7 @@ export async function validateArtifactOutputPath(candidate, allowedRoots) {
|
|
|
236
254
|
if (!pathContainedByAny(roots, realParent)) {
|
|
237
255
|
return {
|
|
238
256
|
ok: false,
|
|
239
|
-
error: `输出路径超出允许范围:${absolute}\n
|
|
240
|
-
+ `允许写入:${roots.join('、')}\n`
|
|
241
|
-
+ '省略 path 参数即可写到托管的临时目录。',
|
|
257
|
+
error: `输出路径超出允许范围:${absolute}\n允许写入:${roots.join('、')}\n省略 path 参数即可写到托管的临时目录。`,
|
|
242
258
|
};
|
|
243
259
|
}
|
|
244
260
|
const managed = await realpath(browserArtifactDir()).catch(() => browserArtifactDir());
|
|
@@ -17,7 +17,7 @@ import os from 'node:os';
|
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
|
|
19
19
|
import { sanitizeCredentialEnv } from '../../config/configService.js';
|
|
20
|
-
import {
|
|
20
|
+
import { pathContainedByAny, pathContains } from '../../utils/pathContains.js';
|
|
21
21
|
|
|
22
22
|
export interface AgentBrowserRun {
|
|
23
23
|
code: number;
|
|
@@ -46,18 +46,34 @@ export function sessionArgs(sessionName = BROWSER_SESSION): string[] {
|
|
|
46
46
|
/** KakadeAI-owned persistent browser profile. It is never the user's system Chrome profile. */
|
|
47
47
|
export function browserProfilePath(profileId = 'default'): string {
|
|
48
48
|
const safe = /^[a-zA-Z0-9._-]+$/.test(profileId) ? profileId : 'default';
|
|
49
|
-
return path.join(
|
|
49
|
+
return path.join(
|
|
50
|
+
process.env.MINIMAL_AGENT_HOME ?? os.homedir(),
|
|
51
|
+
'.minimal-agent',
|
|
52
|
+
'browser',
|
|
53
|
+
'profiles',
|
|
54
|
+
safe,
|
|
55
|
+
);
|
|
50
56
|
}
|
|
51
57
|
|
|
52
|
-
export async function ensureBrowserProfile(
|
|
58
|
+
export async function ensureBrowserProfile(
|
|
59
|
+
profileId = 'default',
|
|
60
|
+
): Promise<string> {
|
|
53
61
|
const profile = browserProfilePath(profileId);
|
|
54
62
|
await mkdir(profile, { recursive: true, mode: 0o700 });
|
|
55
|
-
if (process.platform !== 'win32')
|
|
63
|
+
if (process.platform !== 'win32')
|
|
64
|
+
await chmod(profile, 0o700).catch(() => undefined);
|
|
56
65
|
return profile;
|
|
57
66
|
}
|
|
58
67
|
|
|
59
|
-
export async function browserGlobalArgs(
|
|
60
|
-
|
|
68
|
+
export async function browserGlobalArgs(
|
|
69
|
+
sessionName = BROWSER_SESSION,
|
|
70
|
+
profileId = 'default',
|
|
71
|
+
): Promise<string[]> {
|
|
72
|
+
return [
|
|
73
|
+
...sessionArgs(sessionName),
|
|
74
|
+
'--profile',
|
|
75
|
+
await ensureBrowserProfile(profileId),
|
|
76
|
+
];
|
|
61
77
|
}
|
|
62
78
|
|
|
63
79
|
/**
|
|
@@ -83,8 +99,12 @@ export const spawnRunner: AgentBrowserRunner = (bin, args, signal) =>
|
|
|
83
99
|
settled = true;
|
|
84
100
|
if (graceTimer) clearTimeout(graceTimer);
|
|
85
101
|
// 主动释放父侧 pipe 读端(daemon 攥着写端、我们已拿到结果,不再依赖它关闭)。
|
|
86
|
-
try {
|
|
87
|
-
|
|
102
|
+
try {
|
|
103
|
+
child?.stdout?.destroy();
|
|
104
|
+
} catch {}
|
|
105
|
+
try {
|
|
106
|
+
child?.stderr?.destroy();
|
|
107
|
+
} catch {}
|
|
88
108
|
resolveP({ code: code ?? -1, stdout, stderr: stderr || errMsg || '' });
|
|
89
109
|
};
|
|
90
110
|
try {
|
|
@@ -95,14 +115,24 @@ export const spawnRunner: AgentBrowserRunner = (bin, args, signal) =>
|
|
|
95
115
|
signal,
|
|
96
116
|
});
|
|
97
117
|
} catch (e) {
|
|
98
|
-
resolveP({
|
|
118
|
+
resolveP({
|
|
119
|
+
code: -1,
|
|
120
|
+
stdout: '',
|
|
121
|
+
stderr: e instanceof Error ? e.message : String(e),
|
|
122
|
+
});
|
|
99
123
|
return;
|
|
100
124
|
}
|
|
101
125
|
child.stdout?.setEncoding('utf8');
|
|
102
|
-
child.stdout?.on('data', (c) =>
|
|
126
|
+
child.stdout?.on('data', (c) => {
|
|
127
|
+
stdout += c;
|
|
128
|
+
});
|
|
103
129
|
child.stderr?.setEncoding('utf8');
|
|
104
|
-
child.stderr?.on('data', (c) =>
|
|
105
|
-
|
|
130
|
+
child.stderr?.on('data', (c) => {
|
|
131
|
+
stderr += c;
|
|
132
|
+
});
|
|
133
|
+
child.on('error', (e) =>
|
|
134
|
+
finish(-1, e instanceof Error ? e.message : String(e)),
|
|
135
|
+
);
|
|
106
136
|
// 正常路径:'close' 紧随 'exit'(pipe 关闭)→ 以完整输出立即结算,并清掉宽限计时器。
|
|
107
137
|
child.on('close', (code) => finish(code));
|
|
108
138
|
// 拉 daemon 的命令:daemon 继承 pipe → 'close' 永不来。以 'exit' 为准,给一小段宽限等 'close'
|
|
@@ -184,11 +214,16 @@ async function pruneStaleArtifacts(dir: string): Promise<void> {
|
|
|
184
214
|
const target = path.join(dir, name);
|
|
185
215
|
try {
|
|
186
216
|
const info = await stat(target);
|
|
187
|
-
if (info.mtimeMs < cutoff)
|
|
188
|
-
|
|
217
|
+
if (info.mtimeMs < cutoff)
|
|
218
|
+
await rm(target, { force: true, recursive: true });
|
|
219
|
+
} catch {
|
|
220
|
+
/* 单个文件清不掉不影响其它 */
|
|
221
|
+
}
|
|
189
222
|
}),
|
|
190
223
|
);
|
|
191
|
-
} catch {
|
|
224
|
+
} catch {
|
|
225
|
+
/* 目录不存在或不可读:没什么可清的 */
|
|
226
|
+
}
|
|
192
227
|
}
|
|
193
228
|
|
|
194
229
|
/**
|
|
@@ -197,10 +232,14 @@ async function pruneStaleArtifacts(dir: string): Promise<void> {
|
|
|
197
232
|
* 文件名带 pid + 随机数:`Date.now()` 单独用会在同一毫秒内两次调用时撞名
|
|
198
233
|
* (两个并发截图互相覆盖,症状是「截出来的图不是那一刻的画面」)。
|
|
199
234
|
*/
|
|
200
|
-
export async function createArtifactPath(
|
|
235
|
+
export async function createArtifactPath(
|
|
236
|
+
prefix = 'browser',
|
|
237
|
+
ext = 'png',
|
|
238
|
+
): Promise<string> {
|
|
201
239
|
const dir = browserArtifactDir();
|
|
202
240
|
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
203
|
-
if (process.platform !== 'win32')
|
|
241
|
+
if (process.platform !== 'win32')
|
|
242
|
+
await chmod(dir, 0o700).catch(() => undefined);
|
|
204
243
|
await pruneStaleArtifacts(dir);
|
|
205
244
|
const unique = `${Date.now()}-${process.pid}-${randomUUID().slice(0, 8)}`;
|
|
206
245
|
return path.join(dir, `${prefix}-${unique}.${ext}`);
|
|
@@ -237,7 +276,9 @@ export async function validateArtifactOutputPath(
|
|
|
237
276
|
candidate: string,
|
|
238
277
|
allowedRoots: string[],
|
|
239
278
|
): Promise<{ ok: true; path: string } | { ok: false; error: string }> {
|
|
240
|
-
const absolute = path.isAbsolute(candidate)
|
|
279
|
+
const absolute = path.isAbsolute(candidate)
|
|
280
|
+
? candidate
|
|
281
|
+
: path.resolve(candidate);
|
|
241
282
|
const parent = path.dirname(absolute);
|
|
242
283
|
let realParent: string;
|
|
243
284
|
try {
|
|
@@ -247,19 +288,22 @@ export async function validateArtifactOutputPath(
|
|
|
247
288
|
}
|
|
248
289
|
const roots = await Promise.all(
|
|
249
290
|
allowedRoots.map(async (root) => {
|
|
250
|
-
try {
|
|
291
|
+
try {
|
|
292
|
+
return await realpath(root);
|
|
293
|
+
} catch {
|
|
294
|
+
return path.resolve(root);
|
|
295
|
+
}
|
|
251
296
|
}),
|
|
252
297
|
);
|
|
253
298
|
if (!pathContainedByAny(roots, realParent)) {
|
|
254
299
|
return {
|
|
255
300
|
ok: false,
|
|
256
|
-
error:
|
|
257
|
-
`输出路径超出允许范围:${absolute}\n`
|
|
258
|
-
+ `允许写入:${roots.join('、')}\n`
|
|
259
|
-
+ '省略 path 参数即可写到托管的临时目录。',
|
|
301
|
+
error: `输出路径超出允许范围:${absolute}\n允许写入:${roots.join('、')}\n省略 path 参数即可写到托管的临时目录。`,
|
|
260
302
|
};
|
|
261
303
|
}
|
|
262
|
-
const managed = await realpath(browserArtifactDir()).catch(() =>
|
|
304
|
+
const managed = await realpath(browserArtifactDir()).catch(() =>
|
|
305
|
+
browserArtifactDir(),
|
|
306
|
+
);
|
|
263
307
|
if (!pathContains(managed, realParent)) {
|
|
264
308
|
const exists = await stat(path.join(realParent, path.basename(absolute)))
|
|
265
309
|
.then(() => true)
|