minimal-agent 0.10.0 → 0.12.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 +11 -3
- package/package.json +52 -5
- package/plugins/computer_use/.claude-plugin/plugin.json +6 -0
- package/plugins/computer_use/README.md +94 -0
- package/plugins/computer_use/app/_template.md +142 -0
- package/plugins/computer_use/app/chrome.md +165 -0
- package/plugins/computer_use/app/finder.md +76 -0
- package/plugins/computer_use/app/macos-system-settings.md +81 -0
- package/plugins/computer_use/app/microsoft-excel.md +80 -0
- package/plugins/computer_use/app/microsoft-powerpoint.md +80 -0
- package/plugins/computer_use/app/microsoft-word.md +79 -0
- package/plugins/computer_use/app/wechat.md +413 -0
- package/plugins/computer_use/app/weread.md +319 -0
- package/plugins/computer_use/commands/computeruse.md +25 -0
- package/plugins/computer_use/commands/cu.md +9 -0
- package/plugins/computer_use/plugin.js +26 -0
- package/plugins/computer_use/plugin.ts +30 -0
- package/plugins/computer_use/src/capture.js +90 -0
- package/plugins/computer_use/src/capture.ts +104 -0
- package/plugins/computer_use/src/commands.js +91 -0
- package/plugins/computer_use/src/commands.ts +103 -0
- package/plugins/computer_use/src/daemon.js +134 -0
- package/plugins/computer_use/src/daemon.ts +161 -0
- package/plugins/computer_use/src/manuals.js +135 -0
- package/plugins/computer_use/src/manuals.ts +159 -0
- package/plugins/computer_use/src/verify.js +168 -0
- package/plugins/computer_use/src/verify.ts +219 -0
- package/plugins/computer_use/test/commands.test.ts +73 -0
- package/plugins/cron-runner/plugin.ts +38 -0
- package/plugins/cron-runner/src/commands.ts +373 -0
- package/plugins/cron-runner/src/cronTime.ts +155 -0
- package/plugins/cron-runner/src/lock.ts +79 -0
- package/plugins/cron-runner/src/runs.ts +99 -0
- package/plugins/cron-runner/src/scheduleEngine.ts +76 -0
- package/plugins/cron-runner/src/scheduler.ts +376 -0
- package/plugins/cron-runner/src/schema.ts +139 -0
- package/plugins/cron-runner/src/service.ts +193 -0
- package/plugins/cron-runner/src/store.ts +333 -0
- package/plugins/cron-runner/src/types.ts +141 -0
- package/plugins/cron-runner/test/cronTime.test.ts +41 -0
- package/plugins/cron-runner/test/plugin-integration.test.ts +47 -0
- package/plugins/cron-runner/test/scheduleEngine.test.ts +41 -0
- package/plugins/cron-runner/test/service.test.ts +76 -0
- package/plugins/cron-runner/test/store-and-scheduler.test.ts +501 -0
- package/plugins/workflow-runner/plugin.js +56 -2
- package/plugins/workflow-runner/plugin.ts +113 -0
- package/plugins/workflow-runner/src/agentCommon.js +43 -4
- package/plugins/workflow-runner/src/agentCommon.ts +435 -0
- package/plugins/workflow-runner/src/controlFlow/branch.js +40 -0
- package/plugins/workflow-runner/src/controlFlow/branch.ts +46 -0
- package/plugins/workflow-runner/src/controlFlow/loop.js +211 -0
- package/plugins/workflow-runner/src/controlFlow/loop.ts +248 -0
- package/plugins/workflow-runner/src/controlFlow/pause.js +129 -0
- package/plugins/workflow-runner/src/controlFlow/pause.ts +141 -0
- package/plugins/workflow-runner/src/controlFlow/signal.js +21 -0
- package/plugins/workflow-runner/src/controlFlow/signal.ts +29 -0
- package/plugins/workflow-runner/src/controlFlow/types.js +18 -0
- package/plugins/workflow-runner/src/controlFlow/types.ts +63 -0
- package/plugins/workflow-runner/src/dslManifest.ts +127 -0
- package/plugins/workflow-runner/src/expressions.ts +622 -0
- package/plugins/workflow-runner/src/index.js +13 -4
- package/plugins/workflow-runner/src/index.ts +338 -0
- package/plugins/workflow-runner/src/jsonPayload.ts +84 -0
- package/plugins/workflow-runner/src/loader.js +23 -0
- package/plugins/workflow-runner/src/loader.ts +721 -0
- package/plugins/workflow-runner/src/multimodal.js +2 -1
- package/plugins/workflow-runner/src/multimodal.ts +64 -0
- package/plugins/workflow-runner/src/recovery.ts +149 -0
- package/plugins/workflow-runner/src/runner.js +75 -659
- package/plugins/workflow-runner/src/runner.ts +604 -0
- package/plugins/workflow-runner/src/stepExecutors/agent.ts +234 -0
- package/plugins/workflow-runner/src/stepExecutors/assert.ts +50 -0
- package/plugins/workflow-runner/src/stepExecutors/echo.js +31 -0
- package/plugins/workflow-runner/src/stepExecutors/echo.ts +38 -0
- package/plugins/workflow-runner/src/stepExecutors/llm.ts +133 -0
- package/plugins/workflow-runner/src/stepExecutors/set.js +49 -0
- package/plugins/workflow-runner/src/stepExecutors/set.ts +56 -0
- package/plugins/workflow-runner/src/stepExecutors/skill.js +5 -6
- package/plugins/workflow-runner/src/stepExecutors/skill.ts +140 -0
- package/plugins/workflow-runner/src/stepExecutors/tool.js +80 -8
- package/plugins/workflow-runner/src/stepExecutors/tool.ts +256 -0
- package/plugins/workflow-runner/src/stepExecutors/verify.ts +68 -0
- package/plugins/workflow-runner/src/stepPipeline.js +277 -0
- package/plugins/workflow-runner/src/stepPipeline.ts +366 -0
- package/plugins/workflow-runner/src/taskIdentity.ts +405 -0
- package/plugins/workflow-runner/src/toolRuntime.js +48 -0
- package/plugins/workflow-runner/src/toolRuntime.ts +64 -0
- package/plugins/workflow-runner/src/types.js +37 -1
- package/plugins/workflow-runner/src/types.ts +602 -0
- package/plugins/workflow-runner/src/workflowState.ts +733 -0
- package/plugins/workflow-runner/test/agent.test.ts +587 -0
- package/plugins/workflow-runner/test/agentLlmError.test.ts +373 -0
- package/plugins/workflow-runner/test/bashBlacklist.sweep.test.ts +65 -0
- package/plugins/workflow-runner/test/captureMisbind.test.ts +99 -0
- package/plugins/workflow-runner/test/cli.e2e.test.ts +147 -0
- package/plugins/workflow-runner/test/context-files.test.ts +320 -0
- package/plugins/workflow-runner/test/e2e.test.ts +370 -0
- package/plugins/workflow-runner/test/engineRobustness.test.ts +226 -0
- package/plugins/workflow-runner/test/expressions.test.ts +397 -0
- package/plugins/workflow-runner/test/foundation.test.ts +126 -0
- package/plugins/workflow-runner/test/graceful.test.ts +139 -0
- package/plugins/workflow-runner/test/greedyInputs.load.test.ts +47 -0
- package/plugins/workflow-runner/test/hostCapability.test.ts +108 -0
- package/plugins/workflow-runner/test/illustrate.load.test.ts +183 -0
- package/plugins/workflow-runner/test/jsonPayload.test.ts +83 -0
- package/plugins/workflow-runner/test/loader.test.ts +617 -0
- package/plugins/workflow-runner/test/maxTurnsRetryDelay.test.ts +33 -0
- package/plugins/workflow-runner/test/multimodal.test.ts +342 -0
- package/plugins/workflow-runner/test/output-schema.test.ts +213 -0
- package/plugins/workflow-runner/test/parseWorkflowArgs.test.ts +87 -0
- package/plugins/workflow-runner/test/pluginRunner.isolation.test.ts +269 -0
- package/plugins/workflow-runner/test/ppt.load.test.ts +1220 -0
- package/plugins/workflow-runner/test/ralphLoop.e2e.test.ts +220 -0
- package/plugins/workflow-runner/test/recovery.test.ts +265 -0
- package/plugins/workflow-runner/test/runner.test.ts +911 -0
- package/plugins/workflow-runner/test/runnerPreflight.test.ts +379 -0
- package/plugins/workflow-runner/test/skillTurnDone.test.ts +71 -0
- package/plugins/workflow-runner/test/stateLifecycle.test.ts +150 -0
- package/plugins/workflow-runner/test/stepPipeline.test.ts +114 -0
- package/plugins/workflow-runner/test/taskArbitration.test.ts +338 -0
- package/plugins/workflow-runner/test/taskIdentity.test.ts +237 -0
- package/plugins/workflow-runner/test/taskLifecycle.test.ts +270 -0
- package/plugins/workflow-runner/test/toolArtifactOverwrite.test.ts +221 -0
- package/plugins/workflow-runner/test/toolCapabilityBoundary.test.ts +29 -0
- package/plugins/workflow-runner/test/toolRuntimeIntegration.test.ts +168 -0
- package/plugins/workflow-runner/test/webppt.load.test.ts +250 -0
- package/plugins/workflow-runner/test/word.load.test.ts +208 -0
- package/plugins/workflow-runner/test/workflows.smoke.test.ts +76 -0
- package/plugins/workflow-runner/test/yamlGuardConditions.test.ts +207 -0
- package/skills/browser-automation/SKILL.md +9 -19
- package/skills/web-crawler/SKILL.md +9 -11
- package/src/askBridge.ts +249 -0
- package/src/bootstrap/cwdArg.js +10 -3
- package/src/bootstrap/cwdArg.ts +31 -0
- package/src/bootstrap/workingDir.ts +48 -0
- package/src/cli/args.js +70 -7
- package/src/cli/args.ts +146 -0
- package/src/cli/computerUse.js +185 -0
- package/src/cli/computerUse.ts +221 -0
- package/src/cli/configMenu.js +274 -202
- package/src/cli/configMenu.tsx +521 -0
- package/src/cli/memoryAccess.js +45 -0
- package/src/cli/memoryAccess.ts +53 -0
- package/src/cli/print.js +119 -5
- package/src/cli/print.ts +597 -0
- package/src/cli/quickModelSetup.js +60 -0
- package/src/cli/quickModelSetup.tsx +96 -0
- package/src/cli/streamJson.js +80 -4
- package/src/cli/streamJson.ts +433 -0
- package/src/cli/wizards/advisorWizard.js +1 -0
- package/src/cli/wizards/advisorWizard.tsx +195 -0
- package/src/cli/wizards/agentRuntimeWizard.js +84 -0
- package/src/cli/wizards/agentRuntimeWizard.tsx +134 -0
- package/src/cli/wizards/browserWizard.js +55 -0
- package/src/cli/wizards/browserWizard.tsx +77 -0
- package/src/cli/wizards/contextAdvisorWizard.js +84 -0
- package/src/cli/wizards/contextAdvisorWizard.tsx +124 -0
- package/src/cli/wizards/fieldForm.js +7 -4
- package/src/cli/wizards/fieldForm.tsx +250 -0
- package/src/cli/wizards/imageWizard.js +4 -5
- package/src/cli/wizards/imageWizard.tsx +96 -0
- package/src/cli/wizards/openRouterWizard.tsx +48 -0
- package/src/cli/wizards/providerPresets.js +1 -8
- package/src/cli/wizards/providerPresets.ts +106 -0
- package/src/cli/wizards/providerWizard.js +152 -205
- package/src/cli/wizards/providerWizard.tsx +266 -0
- package/src/cli/wizards/searchWizard.tsx +47 -0
- package/src/cli/wizards/ttsWizard.js +4 -3
- package/src/cli/wizards/ttsWizard.tsx +61 -0
- package/src/config/configDefaults.js +25 -0
- package/src/config/configDefaults.ts +33 -0
- package/src/config/configDiagnostics.js +117 -0
- package/src/config/configDiagnostics.ts +166 -0
- package/src/config/configFile.js +52 -32
- package/src/config/configFile.ts +633 -0
- package/src/config/configManagement.js +126 -0
- package/src/config/configManagement.ts +159 -0
- package/src/config/configService.js +66 -11
- package/src/config/configService.ts +554 -0
- package/src/config/numericLimits.js +61 -0
- package/src/config/numericLimits.ts +80 -0
- package/src/config.ts +109 -0
- package/src/context/agentHome.ts +11 -0
- package/src/context/archive.ts +144 -0
- package/src/context/budgetPlan.js +54 -0
- package/src/context/budgetPlan.ts +88 -0
- package/src/context/compact.js +179 -106
- package/src/context/compact.ts +584 -0
- package/src/context/contextBundle.js +119 -0
- package/src/context/contextBundle.ts +176 -0
- package/src/context/contextLock.ts +84 -0
- package/src/context/microCompactLite.ts +218 -0
- package/src/context/persistContext.ts +177 -0
- package/src/context/reactiveCompact.js +19 -4
- package/src/context/reactiveCompact.ts +240 -0
- package/src/context/recentDirs.ts +42 -0
- package/src/context/sessionPath.ts +206 -0
- package/src/context/sessionRegistry.js +8 -2
- package/src/context/sessionRegistry.ts +414 -0
- package/src/context/snipCompact.ts +163 -0
- package/src/context/tokenCounter.ts +106 -0
- package/src/context/workspaceIndex.js +2 -2
- package/src/context/workspaceIndex.ts +751 -0
- package/src/entry.compiled.tsx +20 -0
- package/src/harness/claimValidation.js +9 -0
- package/src/harness/claimValidation.ts +22 -0
- package/src/harness/evidenceLedger.js +92 -0
- package/src/harness/evidenceLedger.ts +96 -0
- package/src/harness/stallGuard.js +60 -0
- package/src/harness/stallGuard.ts +81 -0
- package/src/humanIntervention.js +129 -0
- package/src/humanIntervention.ts +216 -0
- package/src/infra/verification.ts +295 -0
- package/src/irreversible/rules.js +216 -0
- package/src/irreversible/rules.ts +261 -0
- package/src/llm/client.js +40 -3
- package/src/llm/client.ts +621 -0
- package/src/llm/promptCache.js +27 -0
- package/src/llm/promptCache.ts +41 -0
- package/src/llm/providers/anthropicFormat.js +41 -5
- package/src/llm/providers/anthropicFormat.ts +290 -0
- package/src/llm/providers/openaiFormat.js +186 -8
- package/src/llm/providers/openaiFormat.ts +428 -0
- package/src/loop.js +614 -63
- package/src/loop.ts +1454 -0
- package/src/main.js +67 -10
- package/src/main.tsx +344 -0
- package/src/memory/codec.js +204 -0
- package/src/memory/codec.ts +249 -0
- package/src/memory/constants.js +34 -0
- package/src/memory/constants.ts +50 -0
- package/src/memory/episodicMemory.js +684 -0
- package/src/memory/episodicMemory.ts +815 -0
- package/src/memory/fileStore.js +148 -0
- package/src/memory/fileStore.ts +184 -0
- package/src/memory/memoryService.js +570 -0
- package/src/memory/memoryService.ts +859 -0
- package/src/memory/migration.js +128 -0
- package/src/memory/migration.ts +160 -0
- package/src/memory/repository.js +789 -0
- package/src/memory/repository.ts +893 -0
- package/src/memory/retrieval.js +108 -0
- package/src/memory/retrieval.ts +145 -0
- package/src/memory/searchIndex.js +107 -0
- package/src/memory/searchIndex.ts +153 -0
- package/src/memory/topicView.js +82 -0
- package/src/memory/topicView.ts +95 -0
- package/src/memory/turnJournal.js +95 -0
- package/src/memory/turnJournal.ts +120 -0
- package/src/memory/types.js +2 -0
- package/src/memory/types.ts +186 -0
- package/src/messageQueue.ts +123 -0
- package/src/multimodal.js +128 -46
- package/src/multimodal.ts +349 -0
- package/src/plugin-sdk.js +21 -1
- package/src/plugin-sdk.ts +134 -0
- package/src/plugins/builtinPluginIds.js +47 -0
- package/src/plugins/builtinPluginIds.ts +51 -0
- package/src/plugins/builtinRegistry.ts +43 -0
- package/src/plugins/commandRouter.js +40 -26
- package/src/plugins/commandRouter.ts +261 -0
- package/src/plugins/hookEngine.ts +341 -0
- package/src/plugins/pluginApi.ts +133 -0
- package/src/plugins/pluginLifecycle.ts +34 -0
- package/src/plugins/pluginLoader.ts +147 -0
- package/src/plugins/pluginManifest.js +127 -0
- package/src/plugins/pluginManifest.ts +152 -0
- package/src/plugins/pluginRunner.js +47 -2
- package/src/plugins/pluginRunner.ts +207 -0
- package/src/plugins/transcript.ts +208 -0
- package/src/prompts/lint.js +169 -0
- package/src/prompts/lint.ts +220 -0
- package/src/prompts/pluginList.js +32 -16
- package/src/prompts/pluginList.ts +86 -0
- package/src/prompts/policyRegistry.js +318 -0
- package/src/prompts/policyRegistry.ts +358 -0
- package/src/prompts/projectInstructions.js +24 -0
- package/src/prompts/projectInstructions.ts +81 -0
- package/src/prompts/promptAssembly.js +311 -202
- package/src/prompts/promptAssembly.ts +510 -0
- package/src/prompts/skillList.js +106 -45
- package/src/prompts/skillList.ts +198 -0
- package/src/prompts/system.js +31 -6
- package/src/prompts/system.ts +81 -0
- package/src/runtime/agentRuntimeContext.js +53 -0
- package/src/runtime/agentRuntimeContext.ts +112 -0
- package/src/session/runAgentTurn.js +71 -12
- package/src/session/runAgentTurn.ts +181 -0
- package/src/session/runTurn.js +29 -0
- package/src/session/runTurn.ts +160 -0
- package/src/session/runtimeStore.js +149 -0
- package/src/session/runtimeStore.ts +197 -0
- package/src/session/sessionState.js +79 -3
- package/src/session/sessionState.ts +134 -0
- package/src/toolGate.ts +50 -0
- package/src/tools/advisor/advisor.js +76 -15
- package/src/tools/advisor/advisor.ts +512 -0
- package/src/tools/agent/agent.js +245 -29
- package/src/tools/agent/agent.ts +837 -0
- package/src/tools/agent/agentTaskService.js +60 -0
- package/src/tools/agent/agentTaskService.ts +113 -0
- package/src/tools/agent/agentTypes.js +20 -8
- package/src/tools/agent/agentTypes.ts +94 -0
- package/src/tools/agent/coordinator.ts +111 -0
- package/src/tools/agent/worktree.ts +296 -0
- package/src/tools/ask/ask.js +17 -0
- package/src/tools/ask/ask.ts +122 -0
- package/src/tools/bash/attachImage.js +223 -0
- package/src/tools/bash/attachImage.ts +281 -0
- package/src/tools/bash/bash.js +132 -14
- package/src/tools/bash/bash.ts +642 -0
- package/src/tools/bash/semantics.ts +103 -0
- package/src/tools/bash/warnings.js +17 -11
- package/src/tools/bash/warnings.ts +117 -0
- package/src/tools/capabilities.js +42 -0
- package/src/tools/capabilities.ts +69 -0
- package/src/tools/computeruse/accessibilityPermission.js +261 -0
- package/src/tools/computeruse/accessibilityPermission.ts +294 -0
- package/src/tools/computeruse/axSearch.js +96 -0
- package/src/tools/computeruse/axSearch.ts +120 -0
- package/src/tools/computeruse/axSnap.js +272 -0
- package/src/tools/computeruse/axSnap.ts +349 -0
- package/src/tools/computeruse/capabilityLabels.js +95 -0
- package/src/tools/computeruse/capabilityLabels.ts +115 -0
- package/src/tools/computeruse/computerUseService.js +2235 -0
- package/src/tools/computeruse/computerUseService.ts +2686 -0
- package/src/tools/computeruse/computeruse.js +2742 -0
- package/src/tools/computeruse/computeruse.ts +3265 -0
- package/src/tools/computeruse/diagnosticTrace.js +154 -0
- package/src/tools/computeruse/diagnosticTrace.ts +195 -0
- package/src/tools/computeruse/diagnostics.js +369 -0
- package/src/tools/computeruse/diagnostics.ts +453 -0
- package/src/tools/computeruse/grants.js +53 -0
- package/src/tools/computeruse/grants.ts +70 -0
- package/src/tools/computeruse/humanBoundary.js +159 -0
- package/src/tools/computeruse/humanBoundary.ts +199 -0
- package/src/tools/computeruse/intervention.js +77 -0
- package/src/tools/computeruse/intervention.ts +110 -0
- package/src/tools/computeruse/manualSchema.js +709 -0
- package/src/tools/computeruse/manualSchema.ts +916 -0
- package/src/tools/computeruse/observationImages.js +705 -0
- package/src/tools/computeruse/observationImages.ts +889 -0
- package/src/tools/computeruse/protocol.js +60 -0
- package/src/tools/computeruse/protocol.ts +515 -0
- package/src/tools/computeruse/telemetryLog.js +57 -0
- package/src/tools/computeruse/telemetryLog.ts +67 -0
- package/src/tools/computeruse/vision/appGuide.js +325 -0
- package/src/tools/computeruse/vision/appGuide.ts +482 -0
- package/src/tools/computeruse/vision/focus.js +291 -0
- package/src/tools/computeruse/vision/focus.ts +382 -0
- package/src/tools/computeruse/vision/frames.js +248 -0
- package/src/tools/computeruse/vision/frames.ts +329 -0
- package/src/tools/computeruse/vision/geometry.js +131 -0
- package/src/tools/computeruse/vision/geometry.ts +163 -0
- package/src/tools/computeruse/vision/imaging.js +201 -0
- package/src/tools/computeruse/vision/imaging.ts +281 -0
- package/src/tools/computeruse/vision/png.js +274 -0
- package/src/tools/computeruse/vision/png.ts +317 -0
- package/src/tools/computeruse/vision/raster.js +320 -0
- package/src/tools/computeruse/vision/raster.ts +408 -0
- package/src/tools/computeruse/vision/settle.js +131 -0
- package/src/tools/computeruse/vision/settle.ts +220 -0
- package/src/tools/computeruse/vision/telemetry.js +196 -0
- package/src/tools/computeruse/vision/telemetry.ts +241 -0
- package/src/tools/computeruse/visionOcr.js +115 -0
- package/src/tools/computeruse/visionOcr.ts +128 -0
- package/src/tools/computeruse/waitFor.js +237 -0
- package/src/tools/computeruse/waitFor.ts +291 -0
- package/src/tools/download/download.js +10 -6
- package/src/tools/download/download.ts +187 -0
- package/src/tools/edit/edit.js +30 -18
- package/src/tools/edit/edit.ts +349 -0
- package/src/tools/edit/multi-edit.js +25 -14
- package/src/tools/edit/multi-edit.ts +223 -0
- package/src/tools/effectiveToolSet.js +73 -0
- package/src/tools/effectiveToolSet.ts +91 -0
- package/src/tools/genimage/genimage.ts +257 -0
- package/src/tools/genspeech/genspeech.ts +83 -0
- package/src/tools/glob/glob.js +176 -29
- package/src/tools/glob/glob.ts +283 -0
- package/src/tools/grep/grep.js +61 -19
- package/src/tools/grep/grep.ts +239 -0
- package/src/tools/grep/rgPath.ts +206 -0
- package/src/tools/index.js +99 -5
- package/src/tools/index.ts +293 -0
- package/src/tools/lsp/config.js +113 -0
- package/src/tools/lsp/config.ts +113 -0
- package/src/tools/lsp/lsp.js +256 -0
- package/src/tools/lsp/lsp.ts +274 -0
- package/src/tools/lsp/service.js +303 -0
- package/src/tools/lsp/service.ts +296 -0
- package/src/tools/memory/memory.js +520 -0
- package/src/tools/memory/memory.ts +625 -0
- package/src/tools/memory/policy.js +53 -0
- package/src/tools/memory/policy.ts +72 -0
- package/src/tools/notebook/notebookEdit.js +114 -0
- package/src/tools/notebook/notebookEdit.ts +126 -0
- package/src/tools/powershell/powershell.js +210 -0
- package/src/tools/powershell/powershell.ts +239 -0
- package/src/tools/presentresult/presentresult.js +145 -0
- package/src/tools/presentresult/presentresult.ts +156 -0
- package/src/tools/read/read.js +371 -163
- package/src/tools/read/read.ts +558 -0
- package/src/tools/shared/diffSummary.js +44 -0
- package/src/tools/shared/diffSummary.ts +63 -0
- package/src/tools/shared/fileActivity.js +51 -0
- package/src/tools/shared/fileActivity.ts +66 -0
- package/src/tools/shared/fileMutationBus.js +13 -0
- package/src/tools/shared/fileMutationBus.ts +14 -0
- package/src/tools/shared/fileState.js +73 -65
- package/src/tools/shared/fileState.ts +145 -0
- package/src/tools/shared/fileUtils.js +81 -4
- package/src/tools/shared/fileUtils.ts +504 -0
- package/src/tools/shared/killTree.ts +50 -0
- package/src/tools/shared/permanentDeleteGuard.js +26 -0
- package/src/tools/shared/permanentDeleteGuard.ts +34 -0
- package/src/tools/shared/schemas.ts +20 -0
- package/src/tools/shared/toolOutputStore.js +97 -0
- package/src/tools/shared/toolOutputStore.ts +110 -0
- package/src/tools/skill/skill.js +86 -0
- package/src/tools/skill/skill.ts +94 -0
- package/src/tools/snip/snip.js +67 -0
- package/src/tools/snip/snip.ts +80 -0
- package/src/tools/tasks/backgroundTaskService.js +275 -0
- package/src/tools/tasks/backgroundTaskService.ts +369 -0
- package/src/tools/tasks/processEvidence.js +24 -0
- package/src/tools/tasks/processEvidence.ts +34 -0
- package/src/tools/tasks/taskManagement.js +163 -0
- package/src/tools/tasks/taskManagement.ts +180 -0
- package/src/tools/tasks/taskOutput.js +113 -0
- package/src/tools/tasks/taskOutput.ts +145 -0
- package/src/tools/tasks/taskStop.js +74 -0
- package/src/tools/tasks/taskStop.ts +99 -0
- package/src/tools/tasks/taskStore.js +46 -0
- package/src/tools/tasks/taskStore.ts +77 -0
- package/src/tools/terminal/terminalCapture.js +167 -0
- package/src/tools/terminal/terminalCapture.ts +179 -0
- package/src/tools/trash/trash.js +233 -0
- package/src/tools/trash/trash.ts +283 -0
- package/src/tools/types.js +1 -1
- package/src/tools/types.ts +24 -0
- package/src/tools/webbrowser/agentBrowserPath.ts +286 -0
- package/src/tools/webbrowser/browser.js +214 -11
- package/src/tools/webbrowser/browser.ts +293 -0
- package/src/tools/webbrowser/browserControl.js +153 -48
- package/src/tools/webbrowser/browserControl.ts +262 -0
- package/src/tools/webbrowser/browserDaemon.js +147 -39
- package/src/tools/webbrowser/browserDaemon.ts +270 -0
- package/src/tools/webbrowser/browserOutcome.js +273 -0
- package/src/tools/webbrowser/browserOutcome.ts +306 -0
- package/src/tools/webbrowser/browserRunRegistry.js +150 -0
- package/src/tools/webbrowser/browserRunRegistry.ts +179 -0
- package/src/tools/webbrowser/browserService.js +20 -6
- package/src/tools/webbrowser/browserService.ts +56 -0
- package/src/tools/webbrowser/browserStream.js +30 -1
- package/src/tools/webbrowser/browserStream.ts +216 -0
- package/src/tools/webbrowser/browserTabs.js +143 -0
- package/src/tools/webbrowser/browserTabs.ts +210 -0
- package/src/tools/webbrowser/webbrowser.js +831 -150
- package/src/tools/webbrowser/webbrowser.ts +1537 -0
- package/src/tools/webfetch/preapproved.ts +274 -0
- package/src/tools/webfetch/webfetch.js +24 -23
- package/src/tools/webfetch/webfetch.ts +383 -0
- package/src/tools/websearch/websearch.js +12 -11
- package/src/tools/websearch/websearch.ts +292 -0
- package/src/tools/worktree/sessionWorktree.js +128 -0
- package/src/tools/worktree/sessionWorktree.ts +158 -0
- package/src/tools/write/write.js +27 -44
- package/src/tools/write/write.ts +136 -0
- package/src/types.ts +960 -0
- package/src/ui/App.js +216 -12
- package/src/ui/App.tsx +879 -0
- package/src/ui/AskQuestion.tsx +300 -0
- package/src/ui/InputBox.js +77 -1
- package/src/ui/InputBox.tsx +567 -0
- package/src/ui/LiveArea.tsx +344 -0
- package/src/ui/MessageList.js +27 -6
- package/src/ui/MessageList.tsx +559 -0
- package/src/ui/ModelPicker.tsx +107 -0
- package/src/ui/QueuedMessagesBanner.tsx +51 -0
- package/src/ui/Root.js +6 -8
- package/src/ui/Root.tsx +100 -0
- package/src/ui/SessionPicker.tsx +169 -0
- package/src/ui/StatusLine.js +22 -1
- package/src/ui/StatusLine.tsx +145 -0
- package/src/ui/WorkspacePicker.tsx +84 -0
- package/src/ui/advisorCommand.js +54 -0
- package/src/ui/advisorCommand.ts +63 -0
- package/src/ui/computerCommand.js +19 -0
- package/src/ui/computerCommand.ts +35 -0
- package/src/ui/figures.ts +45 -0
- package/src/ui/hooks/askSlot.ts +112 -0
- package/src/ui/hooks/useChat.js +271 -7
- package/src/ui/hooks/useChat.ts +1578 -0
- package/src/ui/hooks/useInputHistory.ts +235 -0
- package/src/ui/hooks/usePasteHandler.ts +220 -0
- package/src/ui/hooks/useTerminalSize.ts +41 -0
- package/src/ui/hooks/useTextBuffer.ts +108 -0
- package/src/ui/hooks/useTokenUsage.ts +44 -0
- package/src/ui/liveViewport.ts +189 -0
- package/src/ui/markdown.ts +230 -0
- package/src/ui/textBuffer.ts +239 -0
- package/src/ui/theme.ts +35 -0
- package/src/utils/clipboardImage.js +358 -0
- package/src/utils/clipboardImage.ts +420 -0
- package/src/utils/debugLog.ts +50 -0
- package/src/utils/greenRoot.ts +35 -0
- package/src/utils/packageRoot.ts +40 -0
- package/src/utils/pathContains.js +28 -0
- package/src/utils/pathContains.ts +31 -0
- package/src/utils/resourcePaths.ts +71 -0
- package/src/utils/stripThink.ts +49 -0
- package/src/utils/zodToJson.ts +73 -0
- package/src/web/browserBridge.js +365 -66
- package/src/web/browserBridge.ts +672 -0
- package/src/web/protocol.ts +1804 -0
- package/vendor/computer-use/arm64-darwin/cu-helperd +0 -0
- package/workflows/ppt.yaml +13 -2
- package/workflows/wechat-reading-shots.yaml +315 -0
- package/workflows/word.yaml +11 -1
- package/skills/docx/scripts/office/helpers/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/merge_runs.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/helpers/__pycache__/simplify_redlines.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/docx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/pptx.cpython-314.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/redlining.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/__pycache__/image_stats.cpython-314.pyc +0 -0
- package/skills/image-stats/scripts/__pycache__/image_stats_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/assemble_material_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/chart_sanity_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_language_policy.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/check_ui_artifact_pptx_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_pages_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/deck_visual_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_budget_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_repair_hints_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/design_style_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/draft_coverage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/extract_source_assets_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/generated_image_review_collect_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_plan_lint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/image_prompt_rewrite_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/layout_balance_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/normalize_design_json_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/plan_source_layout_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_hint_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/resolve_source_input_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/scaffold_ui_artifact.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/source_usage_check_test.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/text_readability_pixel.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate.cpython-314.pyc +0 -0
- package/skills/ui-design/scripts/__pycache__/visual_quality_gate_test.cpython-314.pyc +0 -0
- /package/skills/ai-image/scripts/{generate_test.mjs → generate.selftest.mjs} +0 -0
- /package/skills/ai-image/scripts/{generate_from_plan_test.mjs → generate_from_plan.selftest.mjs} +0 -0
package/src/prompts/skillList.js
CHANGED
|
@@ -8,47 +8,57 @@
|
|
|
8
8
|
* → 不加载完整 SKILL.md(省 token,按需加载)
|
|
9
9
|
* 2. LLM 决定使用某个 skill 时,用 Read 工具读取对应 SKILL.md
|
|
10
10
|
* → 类似 lazy loading:知道存在 → 需要时才加载详情
|
|
11
|
-
* 3. 格式简洁:每个 skill
|
|
11
|
+
* 3. 格式简洁:每个 skill 固定一行目录项
|
|
12
12
|
* 4. 仅依赖 frontmatter 的 name / description 字段,
|
|
13
13
|
* 不依赖 triggers(并非所有 skill 都声明触发词)。
|
|
14
14
|
* ============================================================
|
|
15
15
|
*/
|
|
16
16
|
import { readFile, readdir } from 'node:fs/promises';
|
|
17
17
|
import { join } from 'node:path';
|
|
18
|
+
import { parse } from 'yaml';
|
|
18
19
|
import { getResourceSearchPaths } from '../utils/resourcePaths.js';
|
|
19
|
-
function stripQuotes(s) {
|
|
20
|
-
const trimmed = s.trim();
|
|
21
|
-
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
22
|
-
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
23
|
-
return trimmed.slice(1, -1);
|
|
24
|
-
}
|
|
25
|
-
return trimmed;
|
|
26
|
-
}
|
|
27
20
|
function parseFrontmatter(content, sourceDir) {
|
|
28
21
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
29
22
|
if (!match)
|
|
30
23
|
return null;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
try {
|
|
25
|
+
const frontmatter = parse(match[1]);
|
|
26
|
+
if (!frontmatter || typeof frontmatter.name !== 'string' || typeof frontmatter.description !== 'string') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const metadata = frontmatter.metadata && typeof frontmatter.metadata === 'object'
|
|
30
|
+
? frontmatter.metadata
|
|
31
|
+
: null;
|
|
32
|
+
const requiresTools = Array.isArray(metadata?.requiresTools)
|
|
33
|
+
? metadata.requiresTools.filter((item) => typeof item === 'string')
|
|
34
|
+
: [];
|
|
35
|
+
return {
|
|
36
|
+
name: frontmatter.name.trim(),
|
|
37
|
+
description: frontmatter.description.trim().replace(/\s+/g, ' '),
|
|
38
|
+
type: typeof frontmatter.type === 'string' ? frontmatter.type.trim() : undefined,
|
|
39
|
+
...(requiresTools.length > 0 ? { requiresTools } : {}),
|
|
40
|
+
sourceDir,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
36
44
|
return null;
|
|
37
|
-
|
|
38
|
-
name: stripQuotes(nameMatch[1]),
|
|
39
|
-
description: stripQuotes(descMatch[1]),
|
|
40
|
-
type: typeMatch ? stripQuotes(typeMatch[1]) : undefined,
|
|
41
|
-
sourceDir,
|
|
42
|
-
};
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
|
-
export async function getSkillList() {
|
|
47
|
+
export async function getSkillList(workingDir, availableTools) {
|
|
45
48
|
const skills = [];
|
|
46
49
|
const seenNames = new Set();
|
|
47
50
|
// 双源扫描:cwd 优先 + packageRoot fallback;按数组顺序处理,已注册 name 跳过
|
|
48
|
-
const searchPaths = getResourceSearchPaths('skills', import.meta.url);
|
|
51
|
+
const searchPaths = getResourceSearchPaths('skills', import.meta.url, workingDir);
|
|
49
52
|
for (const root of searchPaths) {
|
|
50
53
|
try {
|
|
51
54
|
const entries = await readdir(root, { withFileTypes: true });
|
|
55
|
+
// ★ 提示词缓存前提:本函数的输出必须**逐字节可复现**。
|
|
56
|
+
// readdir 的返回顺序由文件系统决定(APFS/ext4/NTFS 各不相同,同一目录在增删
|
|
57
|
+
// 文件后也可能重排),不排序的话同一份 skills 目录会生成字节不同的 system
|
|
58
|
+
// prompt —— 前缀一变,provider 的自动前缀缓存全部失配。
|
|
59
|
+
// 按目录名排序把顺序钉死;对已有行为的唯一影响是同源内的呈现次序变为字典序,
|
|
60
|
+
// 双源覆盖语义(cwd 优先、同名跳过)由外层 searchPaths 顺序决定,不受影响。
|
|
61
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
52
62
|
for (const entry of entries) {
|
|
53
63
|
if (!entry.isDirectory())
|
|
54
64
|
continue;
|
|
@@ -57,7 +67,10 @@ export async function getSkillList() {
|
|
|
57
67
|
try {
|
|
58
68
|
const content = await readFile(skillPath, 'utf8');
|
|
59
69
|
const meta = parseFrontmatter(content, sourceDir);
|
|
60
|
-
|
|
70
|
+
const toolsAvailable = !meta?.requiresTools?.length
|
|
71
|
+
|| availableTools === undefined
|
|
72
|
+
|| meta.requiresTools.every((name) => availableTools.has(name));
|
|
73
|
+
if (meta && toolsAvailable && !seenNames.has(meta.name)) {
|
|
61
74
|
seenNames.add(meta.name);
|
|
62
75
|
skills.push(meta);
|
|
63
76
|
}
|
|
@@ -74,15 +87,14 @@ export async function getSkillList() {
|
|
|
74
87
|
/**
|
|
75
88
|
* 生成 skill 列表提示词。
|
|
76
89
|
*
|
|
77
|
-
* 输出格式(每个 skill
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* - **技能目录**: 绝对路径(`技能目录` 字段名是跨模块契约,
|
|
90
|
+
* 输出格式(每个 skill 一行):
|
|
91
|
+
* - **skill-name**: 功能描述;**技能目录**: 绝对路径
|
|
92
|
+
* `技能目录` 字段名是跨模块契约,
|
|
81
93
|
* workflow-runner 的 foundation/isolation 测试锁定,勿改)
|
|
82
94
|
*
|
|
83
95
|
* 关键设计决策:
|
|
84
96
|
* - 不加载 SKILL.md 全文(节省 ~1500+ tokens/skill)
|
|
85
|
-
* - 只输出 name + description
|
|
97
|
+
* - 只输出 name + description + 按需读取路径
|
|
86
98
|
* - 不依赖 triggers 字段(并非所有 skill 都声明触发词)
|
|
87
99
|
* - LLM 根据 description 语义匹配决定是否使用(不是斜杠激活)
|
|
88
100
|
*/
|
|
@@ -90,22 +102,71 @@ export function formatSkillHint(skills) {
|
|
|
90
102
|
if (skills.length === 0) {
|
|
91
103
|
return '';
|
|
92
104
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
const header = [
|
|
106
|
+
'# Skills',
|
|
107
|
+
'需求匹配或用户显式写 `@skill(name)` 时,先 Read 对应 SKILL.md,再按其中流程执行。项目 Skill 同名时覆盖内置 Skill。',
|
|
108
|
+
];
|
|
109
|
+
const catalogBudget = MAX_HINT_CHARS - header.join('\n').length - 1;
|
|
110
|
+
return [...header, ...renderSkillCatalog(skills, catalogBudget)].join('\n');
|
|
111
|
+
}
|
|
112
|
+
const MAX_DESCRIPTION = 180;
|
|
113
|
+
const MAX_HINT_CHARS = 8_000;
|
|
114
|
+
const MAX_OMITTED_NAMES = 8;
|
|
115
|
+
function skillLine(skill, withDescription) {
|
|
116
|
+
const type = skill.type ? ` [${skill.type}]` : '';
|
|
117
|
+
const description = withDescription ? ` — ${skill.description.slice(0, MAX_DESCRIPTION)}` : '';
|
|
118
|
+
return `- ${skill.name}${type}${description} — **技能目录**: \`${skill.sourceDir}\``;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 预算内的确定性降级阶梯。**先丢描述、再丢条目**——这个顺序是有理由的:
|
|
122
|
+
* 本目录的全部意义是「让模型知道某个 skill **存在**,需要时再 Read 全文」,
|
|
123
|
+
* 一个只有名字和路径的条目仍然完成了这个使命,而整条丢弃则让该 skill 彻底隐身。
|
|
124
|
+
* 旧实现直接从超限处截断并写「其余已省略」,装了很多 skill 的用户会有一批技能
|
|
125
|
+
* 对模型永久不可见,且看不出丢了哪些。
|
|
126
|
+
*
|
|
127
|
+
* 三级:① 全量(名称+描述+目录)② 全量但去掉描述 ③ 去描述后仍超限则截断,
|
|
128
|
+
* 并**如实报出被丢弃的条数与有限名称预览**(不静默截断,也不让提示本身突破预算)。
|
|
129
|
+
*/
|
|
130
|
+
function omittedNotice(skills, withPreview = true) {
|
|
131
|
+
const preview = withPreview
|
|
132
|
+
? skills.slice(0, MAX_OMITTED_NAMES).map((skill) => skill.name).join('、')
|
|
133
|
+
: '';
|
|
134
|
+
return `- (另有 ${skills.length} 个 Skill 未列出${preview ? `,例如:${preview}` : ''}。)`;
|
|
135
|
+
}
|
|
136
|
+
function renderSkillCatalog(skills, budget) {
|
|
137
|
+
const full = skills.map((skill) => skillLine(skill, true));
|
|
138
|
+
if (full.join('\n').length <= budget)
|
|
139
|
+
return full;
|
|
140
|
+
const compact = skills.map((skill) => skillLine(skill, false));
|
|
141
|
+
const notice = '- (Skill 数量较多,此处只列名称与目录;需要时 Read 对应 SKILL.md 获取完整说明。)';
|
|
142
|
+
if ([notice, ...compact].join('\n').length <= budget)
|
|
143
|
+
return [notice, ...compact];
|
|
144
|
+
const kept = [];
|
|
145
|
+
for (let index = 0; index < compact.length; index += 1) {
|
|
146
|
+
const remaining = skills.slice(index + 1);
|
|
147
|
+
const candidate = [
|
|
148
|
+
notice,
|
|
149
|
+
...kept,
|
|
150
|
+
compact[index],
|
|
151
|
+
...(remaining.length > 0 ? [omittedNotice(remaining)] : []),
|
|
152
|
+
].join('\n');
|
|
153
|
+
if (candidate.length > budget)
|
|
154
|
+
break;
|
|
155
|
+
kept.push(compact[index]);
|
|
156
|
+
}
|
|
157
|
+
const dropped = skills.slice(kept.length);
|
|
158
|
+
let result = [
|
|
159
|
+
notice,
|
|
160
|
+
...kept,
|
|
161
|
+
...(dropped.length > 0 ? [omittedNotice(dropped)] : []),
|
|
162
|
+
];
|
|
163
|
+
if (result.join('\n').length > budget && dropped.length > 0) {
|
|
164
|
+
result = [notice, ...kept, omittedNotice(dropped, false)];
|
|
165
|
+
}
|
|
166
|
+
while (result.join('\n').length > budget && kept.length > 0) {
|
|
167
|
+
kept.pop();
|
|
168
|
+
const remaining = skills.slice(kept.length);
|
|
169
|
+
result = [notice, ...kept, omittedNotice(remaining, false)];
|
|
108
170
|
}
|
|
109
|
-
|
|
110
|
-
return lines.join('\n');
|
|
171
|
+
return result;
|
|
111
172
|
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* src/prompts/skillList.ts —— Skill 列表生成
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
* 设计原则:
|
|
6
|
+
* 1. System Prompt 里只注入 frontmatter 元数据轻量列表
|
|
7
|
+
* → 让 LLM 知道"有哪些技能可用 + 功能是什么"
|
|
8
|
+
* → 不加载完整 SKILL.md(省 token,按需加载)
|
|
9
|
+
* 2. LLM 决定使用某个 skill 时,用 Read 工具读取对应 SKILL.md
|
|
10
|
+
* → 类似 lazy loading:知道存在 → 需要时才加载详情
|
|
11
|
+
* 3. 格式简洁:每个 skill 固定一行目录项
|
|
12
|
+
* 4. 仅依赖 frontmatter 的 name / description 字段,
|
|
13
|
+
* 不依赖 triggers(并非所有 skill 都声明触发词)。
|
|
14
|
+
* ============================================================
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { parse } from 'yaml';
|
|
20
|
+
|
|
21
|
+
import { getResourceSearchPaths } from '../utils/resourcePaths.js';
|
|
22
|
+
|
|
23
|
+
export interface SkillMeta {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
/** Hide a Skill when its required model-visible tools are unavailable. */
|
|
28
|
+
requiresTools?: string[];
|
|
29
|
+
/** Skill 所在目录的绝对路径(cwd 来源 vs packageRoot 来源都用绝对路径) */
|
|
30
|
+
sourceDir: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseFrontmatter(content: string, sourceDir: string): SkillMeta | null {
|
|
34
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
35
|
+
if (!match) return null;
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const frontmatter = parse(match[1]) as Record<string, unknown> | null;
|
|
39
|
+
if (!frontmatter || typeof frontmatter.name !== 'string' || typeof frontmatter.description !== 'string') {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const metadata = frontmatter.metadata && typeof frontmatter.metadata === 'object'
|
|
43
|
+
? frontmatter.metadata as Record<string, unknown>
|
|
44
|
+
: null;
|
|
45
|
+
const requiresTools = Array.isArray(metadata?.requiresTools)
|
|
46
|
+
? metadata.requiresTools.filter((item): item is string => typeof item === 'string')
|
|
47
|
+
: [];
|
|
48
|
+
return {
|
|
49
|
+
name: frontmatter.name.trim(),
|
|
50
|
+
description: frontmatter.description.trim().replace(/\s+/g, ' '),
|
|
51
|
+
type: typeof frontmatter.type === 'string' ? frontmatter.type.trim() : undefined,
|
|
52
|
+
...(requiresTools.length > 0 ? { requiresTools } : {}),
|
|
53
|
+
sourceDir,
|
|
54
|
+
};
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export async function getSkillList(
|
|
61
|
+
workingDir?: string,
|
|
62
|
+
availableTools?: ReadonlySet<string>,
|
|
63
|
+
): Promise<SkillMeta[]> {
|
|
64
|
+
const skills: SkillMeta[] = [];
|
|
65
|
+
const seenNames = new Set<string>();
|
|
66
|
+
|
|
67
|
+
// 双源扫描:cwd 优先 + packageRoot fallback;按数组顺序处理,已注册 name 跳过
|
|
68
|
+
const searchPaths = getResourceSearchPaths('skills', import.meta.url, workingDir);
|
|
69
|
+
|
|
70
|
+
for (const root of searchPaths) {
|
|
71
|
+
try {
|
|
72
|
+
const entries = await readdir(root, { withFileTypes: true });
|
|
73
|
+
// ★ 提示词缓存前提:本函数的输出必须**逐字节可复现**。
|
|
74
|
+
// readdir 的返回顺序由文件系统决定(APFS/ext4/NTFS 各不相同,同一目录在增删
|
|
75
|
+
// 文件后也可能重排),不排序的话同一份 skills 目录会生成字节不同的 system
|
|
76
|
+
// prompt —— 前缀一变,provider 的自动前缀缓存全部失配。
|
|
77
|
+
// 按目录名排序把顺序钉死;对已有行为的唯一影响是同源内的呈现次序变为字典序,
|
|
78
|
+
// 双源覆盖语义(cwd 优先、同名跳过)由外层 searchPaths 顺序决定,不受影响。
|
|
79
|
+
entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
80
|
+
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
if (!entry.isDirectory()) continue;
|
|
83
|
+
|
|
84
|
+
const sourceDir = join(root, entry.name);
|
|
85
|
+
const skillPath = join(sourceDir, 'SKILL.md');
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const content = await readFile(skillPath, 'utf8');
|
|
89
|
+
const meta = parseFrontmatter(content, sourceDir);
|
|
90
|
+
|
|
91
|
+
const toolsAvailable = !meta?.requiresTools?.length
|
|
92
|
+
|| availableTools === undefined
|
|
93
|
+
|| meta.requiresTools.every((name) => availableTools.has(name));
|
|
94
|
+
if (meta && toolsAvailable && !seenNames.has(meta.name)) {
|
|
95
|
+
seenNames.add(meta.name);
|
|
96
|
+
skills.push(meta);
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return skills;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 生成 skill 列表提示词。
|
|
110
|
+
*
|
|
111
|
+
* 输出格式(每个 skill 一行):
|
|
112
|
+
* - **skill-name**: 功能描述;**技能目录**: 绝对路径
|
|
113
|
+
* `技能目录` 字段名是跨模块契约,
|
|
114
|
+
* workflow-runner 的 foundation/isolation 测试锁定,勿改)
|
|
115
|
+
*
|
|
116
|
+
* 关键设计决策:
|
|
117
|
+
* - 不加载 SKILL.md 全文(节省 ~1500+ tokens/skill)
|
|
118
|
+
* - 只输出 name + description + 按需读取路径
|
|
119
|
+
* - 不依赖 triggers 字段(并非所有 skill 都声明触发词)
|
|
120
|
+
* - LLM 根据 description 语义匹配决定是否使用(不是斜杠激活)
|
|
121
|
+
*/
|
|
122
|
+
export function formatSkillHint(skills: SkillMeta[]): string {
|
|
123
|
+
if (skills.length === 0) {
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const header = [
|
|
128
|
+
'# Skills',
|
|
129
|
+
'需求匹配或用户显式写 `@skill(name)` 时,先 Read 对应 SKILL.md,再按其中流程执行。项目 Skill 同名时覆盖内置 Skill。',
|
|
130
|
+
];
|
|
131
|
+
const catalogBudget = MAX_HINT_CHARS - header.join('\n').length - 1;
|
|
132
|
+
return [...header, ...renderSkillCatalog(skills, catalogBudget)].join('\n');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const MAX_DESCRIPTION = 180;
|
|
136
|
+
const MAX_HINT_CHARS = 8_000;
|
|
137
|
+
const MAX_OMITTED_NAMES = 8;
|
|
138
|
+
|
|
139
|
+
function skillLine(skill: SkillMeta, withDescription: boolean): string {
|
|
140
|
+
const type = skill.type ? ` [${skill.type}]` : '';
|
|
141
|
+
const description = withDescription ? ` — ${skill.description.slice(0, MAX_DESCRIPTION)}` : '';
|
|
142
|
+
return `- ${skill.name}${type}${description} — **技能目录**: \`${skill.sourceDir}\``;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 预算内的确定性降级阶梯。**先丢描述、再丢条目**——这个顺序是有理由的:
|
|
147
|
+
* 本目录的全部意义是「让模型知道某个 skill **存在**,需要时再 Read 全文」,
|
|
148
|
+
* 一个只有名字和路径的条目仍然完成了这个使命,而整条丢弃则让该 skill 彻底隐身。
|
|
149
|
+
* 旧实现直接从超限处截断并写「其余已省略」,装了很多 skill 的用户会有一批技能
|
|
150
|
+
* 对模型永久不可见,且看不出丢了哪些。
|
|
151
|
+
*
|
|
152
|
+
* 三级:① 全量(名称+描述+目录)② 全量但去掉描述 ③ 去描述后仍超限则截断,
|
|
153
|
+
* 并**如实报出被丢弃的条数与有限名称预览**(不静默截断,也不让提示本身突破预算)。
|
|
154
|
+
*/
|
|
155
|
+
function omittedNotice(skills: SkillMeta[], withPreview = true): string {
|
|
156
|
+
const preview = withPreview
|
|
157
|
+
? skills.slice(0, MAX_OMITTED_NAMES).map((skill) => skill.name).join('、')
|
|
158
|
+
: '';
|
|
159
|
+
return `- (另有 ${skills.length} 个 Skill 未列出${preview ? `,例如:${preview}` : ''}。)`;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function renderSkillCatalog(skills: SkillMeta[], budget: number): string[] {
|
|
163
|
+
const full = skills.map((skill) => skillLine(skill, true));
|
|
164
|
+
if (full.join('\n').length <= budget) return full;
|
|
165
|
+
|
|
166
|
+
const compact = skills.map((skill) => skillLine(skill, false));
|
|
167
|
+
const notice = '- (Skill 数量较多,此处只列名称与目录;需要时 Read 对应 SKILL.md 获取完整说明。)';
|
|
168
|
+
if ([notice, ...compact].join('\n').length <= budget) return [notice, ...compact];
|
|
169
|
+
|
|
170
|
+
const kept: string[] = [];
|
|
171
|
+
for (let index = 0; index < compact.length; index += 1) {
|
|
172
|
+
const remaining = skills.slice(index + 1);
|
|
173
|
+
const candidate = [
|
|
174
|
+
notice,
|
|
175
|
+
...kept,
|
|
176
|
+
compact[index]!,
|
|
177
|
+
...(remaining.length > 0 ? [omittedNotice(remaining)] : []),
|
|
178
|
+
].join('\n');
|
|
179
|
+
if (candidate.length > budget) break;
|
|
180
|
+
kept.push(compact[index]!);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const dropped = skills.slice(kept.length);
|
|
184
|
+
let result = [
|
|
185
|
+
notice,
|
|
186
|
+
...kept,
|
|
187
|
+
...(dropped.length > 0 ? [omittedNotice(dropped)] : []),
|
|
188
|
+
];
|
|
189
|
+
if (result.join('\n').length > budget && dropped.length > 0) {
|
|
190
|
+
result = [notice, ...kept, omittedNotice(dropped, false)];
|
|
191
|
+
}
|
|
192
|
+
while (result.join('\n').length > budget && kept.length > 0) {
|
|
193
|
+
kept.pop();
|
|
194
|
+
const remaining = skills.slice(kept.length);
|
|
195
|
+
result = [notice, ...kept, omittedNotice(remaining, false)];
|
|
196
|
+
}
|
|
197
|
+
return result;
|
|
198
|
+
}
|
package/src/prompts/system.js
CHANGED
|
@@ -7,19 +7,44 @@
|
|
|
7
7
|
* 本文件保留为向后兼容的委托壳,现有调用方无需改动。
|
|
8
8
|
*
|
|
9
9
|
* 新代码请直接使用:
|
|
10
|
-
* - assembleBasePrompt() →
|
|
10
|
+
* - assembleBasePrompt() → 按 Profile 和实际工具组装基础内核
|
|
11
11
|
* ============================================================
|
|
12
12
|
*/
|
|
13
|
-
import { assembleBasePrompt } from './promptAssembly.js';
|
|
13
|
+
import { assembleBasePrompt, assemblePromptEnvelope, assembleStablePrompt, } from './promptAssembly.js';
|
|
14
|
+
export { buildTransientBundle, buildTransientContext, buildTransientLayer, buildTransientPromptBundle } from './promptAssembly.js';
|
|
15
|
+
/**
|
|
16
|
+
* 只取**稳定层**作为 system 消息内容 —— 提示词缓存的主入口。
|
|
17
|
+
*
|
|
18
|
+
* `buildFullSystemPrompt` 是历史兼容名称,目前同样只返回稳定层。宿主应当:
|
|
19
|
+
* 1. 用本函数拿 base 建 history[0](每会话一次)
|
|
20
|
+
* 2. 每回合另调 buildTransientContext() 拿易变层,经 RunQueryOptions.transientContext 下传
|
|
21
|
+
* (loop 会把它附加到本轮用户消息的模型副本,不污染历史)
|
|
22
|
+
*/
|
|
23
|
+
export async function buildBaseSystemPrompt(cwd, tools, profile = 'main') {
|
|
24
|
+
return assembleStablePrompt({
|
|
25
|
+
cwd,
|
|
26
|
+
tools,
|
|
27
|
+
profile,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
14
30
|
/**
|
|
15
31
|
* @deprecated 新代码请直接用 assembleBasePrompt()
|
|
16
32
|
*/
|
|
17
|
-
export async function getSystemPrompt(cwd, tools) {
|
|
18
|
-
return assembleBasePrompt({ cwd, tools });
|
|
33
|
+
export async function getSystemPrompt(cwd, tools, profile = 'main') {
|
|
34
|
+
return assembleBasePrompt({ cwd, tools, profile });
|
|
19
35
|
}
|
|
20
36
|
/**
|
|
21
37
|
* @deprecated 新代码请直接用 assembleBasePrompt({ includeProjectInstructions: true })
|
|
22
38
|
*/
|
|
23
|
-
export async function buildFullSystemPrompt(cwd, tools) {
|
|
24
|
-
return assembleBasePrompt({ cwd, tools, includeProjectInstructions: true });
|
|
39
|
+
export async function buildFullSystemPrompt(cwd, tools, profile = 'main') {
|
|
40
|
+
return assembleBasePrompt({ cwd, tools, profile, includeProjectInstructions: true });
|
|
41
|
+
}
|
|
42
|
+
export async function buildSystemPromptEnvelope(cwd, tools, runtime, profile = 'main') {
|
|
43
|
+
return assemblePromptEnvelope({
|
|
44
|
+
cwd,
|
|
45
|
+
tools,
|
|
46
|
+
profile,
|
|
47
|
+
includeProjectInstructions: true,
|
|
48
|
+
runtime,
|
|
49
|
+
});
|
|
25
50
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================
|
|
3
|
+
* src/prompts/system.ts —— 系统提示词(向后兼容壳)
|
|
4
|
+
* ------------------------------------------------------------
|
|
5
|
+
*
|
|
6
|
+
* 所有提示词组装逻辑已迁移到 promptAssembly.ts。
|
|
7
|
+
* 本文件保留为向后兼容的委托壳,现有调用方无需改动。
|
|
8
|
+
*
|
|
9
|
+
* 新代码请直接使用:
|
|
10
|
+
* - assembleBasePrompt() → 按 Profile 和实际工具组装基础内核
|
|
11
|
+
* ============================================================
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import type { Tool } from '../types.js';
|
|
15
|
+
import {
|
|
16
|
+
assembleBasePrompt,
|
|
17
|
+
assemblePromptEnvelope,
|
|
18
|
+
assembleStablePrompt,
|
|
19
|
+
type PromptEnvelope,
|
|
20
|
+
type PromptProfile,
|
|
21
|
+
type PromptRuntimeContext,
|
|
22
|
+
} from './promptAssembly.js';
|
|
23
|
+
|
|
24
|
+
export { buildTransientBundle, buildTransientContext, buildTransientLayer, buildTransientPromptBundle } from './promptAssembly.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 只取**稳定层**作为 system 消息内容 —— 提示词缓存的主入口。
|
|
28
|
+
*
|
|
29
|
+
* `buildFullSystemPrompt` 是历史兼容名称,目前同样只返回稳定层。宿主应当:
|
|
30
|
+
* 1. 用本函数拿 base 建 history[0](每会话一次)
|
|
31
|
+
* 2. 每回合另调 buildTransientContext() 拿易变层,经 RunQueryOptions.transientContext 下传
|
|
32
|
+
* (loop 会把它附加到本轮用户消息的模型副本,不污染历史)
|
|
33
|
+
*/
|
|
34
|
+
export async function buildBaseSystemPrompt(
|
|
35
|
+
cwd: string,
|
|
36
|
+
tools: Tool[],
|
|
37
|
+
profile: PromptProfile = 'main',
|
|
38
|
+
): Promise<string> {
|
|
39
|
+
return assembleStablePrompt({
|
|
40
|
+
cwd,
|
|
41
|
+
tools,
|
|
42
|
+
profile,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated 新代码请直接用 assembleBasePrompt()
|
|
48
|
+
*/
|
|
49
|
+
export async function getSystemPrompt(
|
|
50
|
+
cwd: string,
|
|
51
|
+
tools: Tool[],
|
|
52
|
+
profile: PromptProfile = 'main',
|
|
53
|
+
): Promise<string> {
|
|
54
|
+
return assembleBasePrompt({ cwd, tools, profile });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated 新代码请直接用 assembleBasePrompt({ includeProjectInstructions: true })
|
|
59
|
+
*/
|
|
60
|
+
export async function buildFullSystemPrompt(
|
|
61
|
+
cwd: string,
|
|
62
|
+
tools: Tool[],
|
|
63
|
+
profile: PromptProfile = 'main',
|
|
64
|
+
): Promise<string> {
|
|
65
|
+
return assembleBasePrompt({ cwd, tools, profile, includeProjectInstructions: true });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export async function buildSystemPromptEnvelope(
|
|
69
|
+
cwd: string,
|
|
70
|
+
tools: Tool[],
|
|
71
|
+
runtime: Partial<PromptRuntimeContext>,
|
|
72
|
+
profile: PromptProfile = 'main',
|
|
73
|
+
): Promise<PromptEnvelope> {
|
|
74
|
+
return assemblePromptEnvelope({
|
|
75
|
+
cwd,
|
|
76
|
+
tools,
|
|
77
|
+
profile,
|
|
78
|
+
includeProjectInstructions: true,
|
|
79
|
+
runtime,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { isMemoryToolName } from '../tools/capabilities.js';
|
|
2
|
+
export function normalizeMemoryAccess(access) {
|
|
3
|
+
return access === 'local-owner' ? 'read-write' : access ?? 'denied';
|
|
4
|
+
}
|
|
5
|
+
/** Only a local owner can receive memory access; untrusted hosts are always denied. */
|
|
6
|
+
export function createAgentRuntimeContext(input) {
|
|
7
|
+
const owner = input.owner ?? 'untrusted';
|
|
8
|
+
const memoryAccess = owner === 'local-owner'
|
|
9
|
+
? normalizeMemoryAccess(input.memoryAccess)
|
|
10
|
+
: 'denied';
|
|
11
|
+
return Object.freeze({
|
|
12
|
+
...input,
|
|
13
|
+
owner,
|
|
14
|
+
memoryAccess,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export function filterToolsForRuntime(tools, runtime, resolvedAvailability) {
|
|
18
|
+
return tools.filter((tool) => (resolvedAvailability?.get(tool)?.available
|
|
19
|
+
?? tool.resolveAvailability?.(runtime).available
|
|
20
|
+
?? true)
|
|
21
|
+
&& (memoryToolAllowed(tool.name, runtime.memoryAccess))
|
|
22
|
+
&& (tool.name !== 'WebBrowser' || webBrowserAllowed(runtime))
|
|
23
|
+
&& (tool.name !== 'ComputerUse' || runtime.computer !== undefined));
|
|
24
|
+
}
|
|
25
|
+
/** WebBrowser is the Desktop main Agent's visible, human-supervised automation surface. */
|
|
26
|
+
export function webBrowserAllowed(runtime) {
|
|
27
|
+
return runtime.surface === 'desktop'
|
|
28
|
+
&& runtime.profile === 'main'
|
|
29
|
+
&& runtime.browser?.supervised === true;
|
|
30
|
+
}
|
|
31
|
+
const READ_ONLY_MEMORY_TOOLS = new Set([
|
|
32
|
+
'RecallMemory',
|
|
33
|
+
'ListMemories',
|
|
34
|
+
'ReviewMemories',
|
|
35
|
+
'SearchConversations',
|
|
36
|
+
]);
|
|
37
|
+
export function memoryToolAllowed(name, access) {
|
|
38
|
+
if (!isMemoryToolName(name))
|
|
39
|
+
return true;
|
|
40
|
+
if (access === 'read-write')
|
|
41
|
+
return true;
|
|
42
|
+
return access === 'read-only' && READ_ONLY_MEMORY_TOOLS.has(name);
|
|
43
|
+
}
|
|
44
|
+
export function isMemoryTool(name) {
|
|
45
|
+
return isMemoryToolName(name);
|
|
46
|
+
}
|
|
47
|
+
export function memoryContextFromRuntime(runtime) {
|
|
48
|
+
return {
|
|
49
|
+
access: runtime.memoryAccess,
|
|
50
|
+
...(runtime.workspaceId ? { workspaceId: runtime.workspaceId } : {}),
|
|
51
|
+
...(runtime.sessionId ? { sessionId: runtime.sessionId } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|