@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1
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 +13 -10
- package/dist/agent/agent-definition-registry.d.ts +21 -3
- package/dist/agent/agent-definition-registry.js +49 -18
- package/dist/agent/agent-definition.d.ts +32 -0
- package/dist/agent/agent-definition.js +49 -4
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +47 -6
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -51
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +41 -0
- package/dist/automation/cron-expr.js +169 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +84 -0
- package/dist/automation/runner.js +92 -0
- package/dist/automation/scheduler.d.ts +194 -0
- package/dist/automation/scheduler.js +623 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +122 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +64 -0
- package/dist/capability-control/overlay.js +116 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
- package/dist/cc-orchestrator/agent-adapter.js +133 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
- package/dist/cc-orchestrator/cc-capability.js +53 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
- package/dist/cc-orchestrator/codex-session-history.js +187 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +214 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
- package/dist/cc-orchestrator/external-agent-driver.js +69 -0
- package/dist/cc-orchestrator/index.d.ts +8 -0
- package/dist/cc-orchestrator/index.js +8 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
- package/dist/cc-orchestrator/relevance-judge.js +29 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
- package/dist/cc-orchestrator/session-discovery.js +125 -0
- package/dist/cc-orchestrator/session-history.d.ts +19 -0
- package/dist/cc-orchestrator/session-history.js +67 -0
- package/dist/cli/agent-server-stdio.d.ts +26 -1
- package/dist/cli/agent-server-stdio.js +221 -28
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +134 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.d.ts +56 -0
- package/dist/context/compaction.js +209 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +25 -41
- package/dist/cost-tracker.js +5 -61
- package/dist/credentials/cipher.d.ts +49 -0
- package/dist/credentials/cipher.js +45 -0
- package/dist/credentials/cookie-jar.d.ts +24 -0
- package/dist/credentials/cookie-jar.js +40 -0
- package/dist/credentials/index.d.ts +7 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/inject-credential-tool.d.ts +20 -0
- package/dist/credentials/inject-credential-tool.js +130 -0
- package/dist/credentials/store.d.ts +72 -0
- package/dist/credentials/store.js +184 -0
- package/dist/credentials/types.d.ts +56 -0
- package/dist/credentials/use-credential-tool.d.ts +29 -0
- package/dist/credentials/use-credential-tool.js +205 -0
- package/dist/credentials/use-gate.d.ts +56 -0
- package/dist/credentials/use-gate.js +52 -0
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/model-metadata.d.ts +77 -0
- package/dist/data/model-metadata.js +56 -0
- package/dist/data/model-metadata.json +216 -0
- package/dist/data/openrouter-models.d.ts +18 -7
- package/dist/data/openrouter-models.js +35 -8
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/aux-key.d.ts +10 -0
- package/dist/engine/aux-key.js +11 -0
- package/dist/engine/dynamic-tool-defs.d.ts +19 -0
- package/dist/engine/dynamic-tool-defs.js +36 -0
- package/dist/engine/engine.d.ts +431 -108
- package/dist/engine/engine.js +1630 -279
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +187 -0
- package/dist/engine/goal.js +196 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +165 -0
- package/dist/engine/image-policy.js +189 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +66 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +25 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.js +9 -1
- package/dist/engine/sandbox-cache-key.d.ts +10 -0
- package/dist/engine/sandbox-cache-key.js +9 -0
- package/dist/engine/sandbox-config.d.ts +31 -0
- package/dist/engine/sandbox-config.js +38 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/session-usage.d.ts +19 -0
- package/dist/engine/session-usage.js +25 -0
- package/dist/engine/steer-queue.d.ts +32 -0
- package/dist/engine/steer-queue.js +26 -0
- package/dist/engine/streaming-tool-queue.d.ts +12 -0
- package/dist/engine/streaming-tool-queue.js +50 -10
- package/dist/engine/turn-loop.d.ts +94 -9
- package/dist/engine/turn-loop.js +775 -342
- package/dist/engine/types.d.ts +175 -0
- package/dist/engine/types.js +13 -0
- package/dist/external-agents/config.d.ts +2 -0
- package/dist/external-agents/config.js +15 -0
- package/dist/external-agents/types.d.ts +31 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +62 -26
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +111 -20
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +58 -0
- package/dist/hooks/goal-stop-hook.js +279 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +57 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +48 -18
- package/dist/index.d.ts +79 -11
- package/dist/index.js +89 -6
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +37 -3
- package/dist/llm/capabilities/types.d.ts +32 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +69 -5
- package/dist/llm/client-base.js +185 -25
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +29 -11
- package/dist/llm/model-pool.js +36 -20
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +6 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +207 -18
- package/dist/llm/providers/openai.d.ts +47 -2
- package/dist/llm/providers/openai.js +478 -71
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +40 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +9 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +112 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +42 -11
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +407 -0
- package/dist/model-catalog/gen-connections.d.ts +20 -0
- package/dist/model-catalog/gen-connections.js +28 -0
- package/dist/model-catalog/index.d.ts +41 -0
- package/dist/model-catalog/index.js +90 -0
- package/dist/model-catalog/params.d.ts +20 -0
- package/dist/model-catalog/params.js +45 -0
- package/dist/model-catalog/resolve.d.ts +48 -0
- package/dist/model-catalog/resolve.js +33 -0
- package/dist/model-catalog/save-entry.d.ts +32 -0
- package/dist/model-catalog/save-entry.js +104 -0
- package/dist/model-catalog/types.d.ts +561 -0
- package/dist/model-catalog/types.js +93 -0
- package/dist/model-catalog/upsert.d.ts +9 -0
- package/dist/model-catalog/upsert.js +8 -0
- package/dist/onboarding.d.ts +12 -82
- package/dist/onboarding.js +75 -333
- package/dist/plugins/gitOps.d.ts +53 -0
- package/dist/plugins/gitOps.js +130 -5
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -0
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
- package/dist/plugins/installer/codex/convertCommands.js +46 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
- package/dist/plugins/installer/codex/convertMcp.js +85 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +123 -0
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +51 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +27 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
- package/dist/plugins/installer/loadPluginMcp.js +107 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +52 -0
- package/dist/plugins/installer/types.js +28 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +18 -0
- package/dist/plugins/installer/unzip.d.ts +14 -0
- package/dist/plugins/installer/unzip.js +82 -0
- package/dist/plugins/installer/update.d.ts +28 -0
- package/dist/plugins/installer/update.js +97 -0
- package/dist/plugins/loadPluginHooks.d.ts +54 -1
- package/dist/plugins/loadPluginHooks.js +83 -1
- package/dist/plugins/marketplaceManager.d.ts +15 -1
- package/dist/plugins/marketplaceManager.js +58 -4
- package/dist/plugins/pluginCommandHook.js +34 -14
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +34 -0
- package/dist/plugins/pluginInstaller.js +168 -35
- package/dist/plugins/schemas.js +41 -6
- package/dist/plugins/types.d.ts +10 -0
- package/dist/preset/index.d.ts +7 -1
- package/dist/preset/index.js +112 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +31 -0
- package/dist/prompt/composer.js +95 -25
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +1 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +15 -2
- package/dist/protocol/chat-session-manager.js +46 -0
- package/dist/protocol/chat-session.d.ts +82 -0
- package/dist/protocol/chat-session.js +121 -1
- package/dist/protocol/client.d.ts +27 -0
- package/dist/protocol/client.js +38 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +153 -2
- package/dist/protocol/server.js +807 -39
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +69 -0
- package/dist/protocol/types.js +22 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +155 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +40 -11
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +86 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +8 -1
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +495 -0
- package/dist/runtime/output-clean.d.ts +24 -0
- package/dist/runtime/output-clean.js +41 -0
- package/dist/runtime/ring-file.d.ts +64 -0
- package/dist/runtime/ring-file.js +174 -0
- package/dist/runtime/safe-spawn.js +15 -34
- package/dist/runtime/spawn-common.d.ts +148 -0
- package/dist/runtime/spawn-common.js +303 -0
- package/dist/runtime/truncate-output.d.ts +22 -0
- package/dist/runtime/truncate-output.js +49 -0
- package/dist/runtime/utf8-cut.d.ts +11 -0
- package/dist/runtime/utf8-cut.js +23 -0
- package/dist/services/auto-dream.d.ts +4 -0
- package/dist/services/auto-dream.js +26 -26
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/extract-memories.d.ts +14 -1
- package/dist/services/extract-memories.js +45 -6
- package/dist/services/memory-orchestrator.d.ts +21 -0
- package/dist/services/memory-orchestrator.js +125 -32
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +30 -19
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +232 -9
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +63 -1
- package/dist/session/session-manager.js +186 -5
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +25 -1
- package/dist/session/transcript.js +35 -2
- package/dist/session/undo-target.d.ts +67 -0
- package/dist/session/undo-target.js +144 -0
- package/dist/settings/disk-defaults.d.ts +42 -0
- package/dist/settings/disk-defaults.js +33 -0
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +101 -1
- package/dist/settings/manager.js +345 -15
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1827 -396
- package/dist/settings/schema.js +361 -81
- package/dist/skills/scanner.d.ts +9 -0
- package/dist/skills/scanner.js +30 -2
- package/dist/stt/resolve-transcribe.d.ts +31 -0
- package/dist/stt/resolve-transcribe.js +108 -0
- package/dist/stt/transcribe.d.ts +51 -0
- package/dist/stt/transcribe.js +65 -0
- package/dist/tool-system/browser-bridge.d.ts +226 -0
- package/dist/tool-system/browser-bridge.js +163 -0
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
- package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
- package/dist/tool-system/builtin/agent-notifications.js +9 -3
- package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
- package/dist/tool-system/builtin/agent-output-file.js +72 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
- package/dist/tool-system/builtin/agent-registry.js +16 -4
- package/dist/tool-system/builtin/agent.d.ts +50 -11
- package/dist/tool-system/builtin/agent.js +576 -73
- package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
- package/dist/tool-system/builtin/apply-patch/index.js +7 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
- package/dist/tool-system/builtin/background-jobs.js +124 -0
- package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
- package/dist/tool-system/builtin/background-shell-tools.js +108 -0
- package/dist/tool-system/builtin/background-work.d.ts +67 -0
- package/dist/tool-system/builtin/background-work.js +86 -0
- package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
- package/dist/tool-system/builtin/bash-output-style.js +40 -0
- package/dist/tool-system/builtin/bash.d.ts +5 -2
- package/dist/tool-system/builtin/bash.js +98 -62
- package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
- package/dist/tool-system/builtin/browser-tools.js +312 -0
- package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
- package/dist/tool-system/builtin/cancel-goal.js +64 -0
- package/dist/tool-system/builtin/check-quota.d.ts +15 -0
- package/dist/tool-system/builtin/check-quota.js +34 -0
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +105 -9
- package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
- package/dist/tool-system/builtin/drive-claude-code.js +157 -0
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +21 -12
- package/dist/tool-system/builtin/eol.d.ts +29 -0
- package/dist/tool-system/builtin/eol.js +37 -0
- package/dist/tool-system/builtin/file-cache.d.ts +6 -0
- package/dist/tool-system/builtin/file-cache.js +8 -0
- package/dist/tool-system/builtin/generate-image.d.ts +60 -0
- package/dist/tool-system/builtin/generate-image.js +374 -0
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +361 -0
- package/dist/tool-system/builtin/grep.js +6 -2
- package/dist/tool-system/builtin/image-providers.d.ts +86 -0
- package/dist/tool-system/builtin/image-providers.js +190 -0
- package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
- package/dist/tool-system/builtin/image-uploader.js +74 -0
- package/dist/tool-system/builtin/index.d.ts +24 -1
- package/dist/tool-system/builtin/index.js +310 -25
- package/dist/tool-system/builtin/mcp-tools.js +23 -3
- package/dist/tool-system/builtin/memory.js +45 -7
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +1 -1
- package/dist/tool-system/builtin/powershell.js +4 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +11 -3
- package/dist/tool-system/builtin/repl.js +4 -1
- package/dist/tool-system/builtin/skill.js +9 -0
- package/dist/tool-system/builtin/sleep.js +12 -5
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/tool-search.js +25 -7
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/video-providers.d.ts +154 -0
- package/dist/tool-system/builtin/video-providers.js +235 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +57 -10
- package/dist/tool-system/builtin/worktree.d.ts +2 -1
- package/dist/tool-system/builtin/worktree.js +31 -4
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +1 -1
- package/dist/tool-system/context.d.ts +166 -6
- package/dist/tool-system/executor.d.ts +3 -2
- package/dist/tool-system/executor.js +197 -119
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +20 -4
- package/dist/tool-system/mcp-manager.d.ts +78 -16
- package/dist/tool-system/mcp-manager.js +357 -28
- package/dist/tool-system/path-policy.d.ts +99 -0
- package/dist/tool-system/path-policy.js +578 -0
- package/dist/tool-system/permission.d.ts +36 -1
- package/dist/tool-system/permission.js +322 -117
- package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
- package/dist/tool-system/plan-mode-allowlist.js +65 -0
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +26 -1
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +301 -15
- package/dist/updater.js +20 -9
- package/dist/utils/envUtils.d.ts +0 -9
- package/dist/utils/envUtils.js +3 -28
- package/dist/utils/exec.d.ts +40 -0
- package/dist/utils/exec.js +144 -0
- package/dist/utils/format.js +4 -2
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +7 -1
- package/dist/utils/theme.js +5 -3
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +14 -7
- package/dist/agent/coordinator.d.ts +0 -49
- package/dist/agent/coordinator.js +0 -77
- package/dist/settings/manager.test.js +0 -73
- package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
- package/dist/tool-system/builtin/remote-trigger.js +0 -54
- package/dist/tool-system/builtin/send-message.d.ts +0 -6
- package/dist/tool-system/builtin/send-message.js +0 -47
- /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
|
@@ -1,17 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cron tools — CronCreate, CronDelete, CronList.
|
|
3
3
|
*/
|
|
4
|
-
import { cronScheduler } from "../../
|
|
4
|
+
import { cronScheduler } from "../../automation/scheduler.js";
|
|
5
|
+
import { getCurrentSid } from "../../logging/logger.js";
|
|
6
|
+
let cronChangedSink = null;
|
|
7
|
+
export function setCronChangedSink(sink) {
|
|
8
|
+
cronChangedSink = sink;
|
|
9
|
+
}
|
|
10
|
+
function fireCronChanged() {
|
|
11
|
+
try {
|
|
12
|
+
cronChangedSink?.();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Notifying the host is best-effort; never break the tool on it.
|
|
16
|
+
}
|
|
17
|
+
}
|
|
5
18
|
export const cronCreateToolDef = {
|
|
6
19
|
name: "CronCreate",
|
|
7
|
-
description: "Create a scheduled
|
|
8
|
-
"
|
|
20
|
+
description: "Create a scheduled automation job that runs a prompt on a recurring schedule. " +
|
|
21
|
+
"Use this when the user asks to set up a recurring/automated/scheduled task " +
|
|
22
|
+
"(monitoring, daily reports, periodic checks, etc.).\n\n" +
|
|
23
|
+
"Translate the user's natural-language timing into the `schedule` field. Two forms:\n" +
|
|
24
|
+
" • Interval: '30s', '5m', '1h', '1d' (runs every N from creation).\n" +
|
|
25
|
+
" • Cron expression (5 fields: minute hour day-of-month month day-of-week) for " +
|
|
26
|
+
"calendar times. Examples: '0 9 * * 1-5' = 9am every weekday; '0 */6 * * *' = every 6 hours; " +
|
|
27
|
+
"'30 8 * * 1' = 8:30am every Monday. Day-of-week: 0=Sunday..6=Saturday.\n\n" +
|
|
28
|
+
"For calendar schedules, set `timezone` to the user's IANA zone (e.g. 'Asia/Shanghai', " +
|
|
29
|
+
"'America/New_York'); ask the user if unknown. Set `cwd` to the project the job operates on. " +
|
|
30
|
+
"Leave `permissionLevel` as 'read-only' unless the user explicitly wants the job to modify code.",
|
|
9
31
|
inputSchema: {
|
|
10
32
|
type: "object",
|
|
11
33
|
properties: {
|
|
12
|
-
name: { type: "string", description: "
|
|
13
|
-
schedule: {
|
|
14
|
-
|
|
34
|
+
name: { type: "string", description: "Short human-readable name for the job (e.g. '工作日晨间简报')" },
|
|
35
|
+
schedule: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Interval ('5m','1h','1d') or a 5-field cron expression ('0 9 * * 1-5'). " +
|
|
38
|
+
"Derive this from the user's described timing.",
|
|
39
|
+
},
|
|
40
|
+
prompt: { type: "string", description: "The task prompt the agent runs on each execution" },
|
|
41
|
+
timezone: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "IANA timezone for cron-expression schedules (e.g. 'Asia/Shanghai'). Optional; defaults to the host system's timezone.",
|
|
44
|
+
},
|
|
45
|
+
cwd: { type: "string", description: "Working directory / project the job runs in. Optional." },
|
|
46
|
+
permissionLevel: {
|
|
47
|
+
type: "string",
|
|
48
|
+
enum: ["read-only", "workspace-write", "full"],
|
|
49
|
+
description: "What the job may do: 'read-only' (monitoring; default), 'workspace-write' (edit files), " +
|
|
50
|
+
"'full' (edit + run git/gh to open PRs). Use the least privilege the task needs.",
|
|
51
|
+
},
|
|
52
|
+
once: {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
description: "true = one-shot: run once at the scheduled time, then auto-delete (for 'in N minutes / " +
|
|
55
|
+
"at <time>, do X once' reminders or tasks). Default false = recurring per `schedule`. " +
|
|
56
|
+
"A one-shot still uses `schedule` for its time: interval '10m' = 10 minutes from now; " +
|
|
57
|
+
"cron '0 7 25 6 *' = once at 07:00 on June 25.",
|
|
58
|
+
},
|
|
59
|
+
continueInSession: {
|
|
60
|
+
type: "boolean",
|
|
61
|
+
description: "true = when the job fires, CONTINUE THE CURRENT conversation: the prompt is appended as " +
|
|
62
|
+
"a new user turn to THIS chat session (restored from disk if needed), carrying its full " +
|
|
63
|
+
"transcript / goal / context. Set this when the user says things like '一小时后接着做 / " +
|
|
64
|
+
"继续 / in this conversation'. Default false = a fresh standalone session per run (right " +
|
|
65
|
+
"for independent recurring tasks like daily reports). The current session id is resolved " +
|
|
66
|
+
"automatically — you do NOT supply it.",
|
|
67
|
+
},
|
|
15
68
|
},
|
|
16
69
|
required: ["name", "schedule", "prompt"],
|
|
17
70
|
},
|
|
@@ -22,8 +75,48 @@ export async function cronCreateTool(args) {
|
|
|
22
75
|
const prompt = args.prompt;
|
|
23
76
|
if (!name || !schedule || !prompt)
|
|
24
77
|
return "Error: name, schedule, and prompt are required";
|
|
25
|
-
const
|
|
26
|
-
|
|
78
|
+
const timezone = typeof args.timezone === "string"
|
|
79
|
+
? args.timezone
|
|
80
|
+
: (() => {
|
|
81
|
+
try {
|
|
82
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || undefined;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
})();
|
|
88
|
+
const cwd = typeof args.cwd === "string" ? args.cwd : undefined;
|
|
89
|
+
const once = args.once === true;
|
|
90
|
+
const permissionLevel = args.permissionLevel === "read-only" ||
|
|
91
|
+
args.permissionLevel === "workspace-write" ||
|
|
92
|
+
args.permissionLevel === "full"
|
|
93
|
+
? args.permissionLevel
|
|
94
|
+
: undefined;
|
|
95
|
+
// Resolve "continue this conversation" to the current session id at create
|
|
96
|
+
// time (the model never supplies it — getCurrentSid() reads the running
|
|
97
|
+
// Engine's ALS context). Empty/unknown sid → treat as standalone.
|
|
98
|
+
const resumeSessionId = args.continueInSession === true && getCurrentSid() ? getCurrentSid() : undefined;
|
|
99
|
+
let job;
|
|
100
|
+
try {
|
|
101
|
+
job = cronScheduler.create(name, schedule, prompt, {
|
|
102
|
+
...(timezone !== undefined ? { timezone } : {}),
|
|
103
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
104
|
+
...(permissionLevel !== undefined ? { permissionLevel } : {}),
|
|
105
|
+
...(once ? { once: true } : {}),
|
|
106
|
+
...(resumeSessionId !== undefined ? { resumeSessionId } : {}),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
return `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
111
|
+
}
|
|
112
|
+
fireCronChanged();
|
|
113
|
+
const tz = job.timezone ? ` (${job.timezone})` : "";
|
|
114
|
+
const next = job.nextRun ? new Date(job.nextRun).toLocaleString() : "n/a";
|
|
115
|
+
const cont = job.resumeSessionId ? "(到点续接当前对话,带上下文)" : "";
|
|
116
|
+
if (job.once) {
|
|
117
|
+
return `一次性任务 #${job.id} "${job.name}" 已创建${cont}。将于 ${next}${tz} 执行一次后自动删除。`;
|
|
118
|
+
}
|
|
119
|
+
return `Cron job #${job.id} "${job.name}" created${cont}. Schedule: ${job.schedule}${tz}. Next run: ${next}.`;
|
|
27
120
|
}
|
|
28
121
|
export const cronDeleteToolDef = {
|
|
29
122
|
name: "CronDelete",
|
|
@@ -41,6 +134,8 @@ export async function cronDeleteTool(args) {
|
|
|
41
134
|
if (!id)
|
|
42
135
|
return "Error: jobId is required";
|
|
43
136
|
const deleted = cronScheduler.delete(id);
|
|
137
|
+
if (deleted)
|
|
138
|
+
fireCronChanged();
|
|
44
139
|
return deleted ? `Cron job #${id} deleted.` : `Cron job #${id} not found.`;
|
|
45
140
|
}
|
|
46
141
|
export const cronListToolDef = {
|
|
@@ -55,7 +150,8 @@ export async function cronListTool(_args) {
|
|
|
55
150
|
const lines = jobs.map((j) => {
|
|
56
151
|
const status = j.enabled ? "active" : "paused";
|
|
57
152
|
const lastRun = j.lastRun ? new Date(j.lastRun).toLocaleString() : "never";
|
|
58
|
-
|
|
153
|
+
const tz = j.timezone ? ` ${j.timezone}` : "";
|
|
154
|
+
return ` #${j.id} "${j.name}" [${status}] ${j.schedule}${tz} | runs: ${j.runCount} | last: ${lastRun}`;
|
|
59
155
|
});
|
|
60
156
|
return `Cron Jobs (${jobs.length}):\n${lines.join("\n")}`;
|
|
61
157
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../../types.js";
|
|
2
|
+
import type { AgentRunResult } from "../../cc-orchestrator/external-agent-driver.js";
|
|
3
|
+
import type { ToolContext } from "../context.js";
|
|
4
|
+
export type DriveCli = "claude" | "codex";
|
|
5
|
+
export declare const driveAgentToolDef: ToolDefinition;
|
|
6
|
+
type PermMode = "default" | "acceptEdits" | "bypassPermissions";
|
|
7
|
+
type Runner = (opts: {
|
|
8
|
+
cli: DriveCli;
|
|
9
|
+
prompt: string;
|
|
10
|
+
resumeSessionId?: string;
|
|
11
|
+
cwd: string;
|
|
12
|
+
permissionMode?: PermMode;
|
|
13
|
+
}) => Promise<AgentRunResult>;
|
|
14
|
+
/** Factory so tests can inject a fake runner. `fixedCli` (back-compat) forces a
|
|
15
|
+
* cli and hides the `cli` arg — that's how DriveClaudeCode stays a thin alias. */
|
|
16
|
+
export declare function makeDriveAgentTool(runner?: Runner, fixedCli?: DriveCli): (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
|
|
17
|
+
export declare const driveAgentTool: (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
|
|
18
|
+
export declare const driveClaudeCodeToolDef: ToolDefinition;
|
|
19
|
+
/** Back-compat factory: a DriveAgent pinned to cli:"claude" with the `cli` arg
|
|
20
|
+
* hidden. The injected `runner` here keeps the old shape (no `cli` field); we
|
|
21
|
+
* adapt it to the generic Runner so existing tests' fakes still work. */
|
|
22
|
+
type LegacyRunner = (opts: {
|
|
23
|
+
prompt: string;
|
|
24
|
+
resumeSessionId?: string;
|
|
25
|
+
cwd: string;
|
|
26
|
+
permissionMode?: PermMode;
|
|
27
|
+
}) => Promise<AgentRunResult>;
|
|
28
|
+
export declare function makeDriveClaudeCodeTool(runner?: LegacyRunner): (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
|
|
29
|
+
export declare const driveClaudeCodeTool: (args: Record<string, unknown>, ctx?: ToolContext) => Promise<string>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { runAgentOnce } from "../../cc-orchestrator/external-agent-driver.js";
|
|
2
|
+
import { claudeAdapter, codexAdapter } from "../../cc-orchestrator/agent-adapter.js";
|
|
3
|
+
import { backgroundJobRegistry } from "./background-jobs.js";
|
|
4
|
+
import { readExternalChangedFiles } from "../../cc-orchestrator/external-agent-changes.js";
|
|
5
|
+
import { notificationQueue } from "./agent-notifications.js";
|
|
6
|
+
const CLI_ADAPTERS = {
|
|
7
|
+
claude: { adapter: claudeAdapter, command: "claude" },
|
|
8
|
+
codex: { adapter: codexAdapter, command: "codex" },
|
|
9
|
+
};
|
|
10
|
+
export const driveAgentToolDef = {
|
|
11
|
+
name: "DriveAgent",
|
|
12
|
+
description: "Delegate a task to an external coding-agent CLI — drives `claude` (Claude Code) or `codex` " +
|
|
13
|
+
"(OpenAI Codex) for one turn. Pick with `cli` (defaults to claude). Use to hand a coding/" +
|
|
14
|
+
"research task to the agent, or continue an existing session of it. " +
|
|
15
|
+
"Runs in the BACKGROUND by default — these tasks are typically long (minutes to hours), so this " +
|
|
16
|
+
"returns immediately and the result is delivered to you later via a completion notification " +
|
|
17
|
+
"that wakes you. Do NOT sleep-poll for it; just continue or end your turn — you'll be woken " +
|
|
18
|
+
"with the result. For a quick task where you want the answer inline, pass background:false. " +
|
|
19
|
+
"It has NO time concept of its own: for 'in N minutes' / 'every N' / looping, use CronCreate " +
|
|
20
|
+
"instead (never sleep). A scheduled CronCreate job runs one codeshell turn whose prompt can " +
|
|
21
|
+
"instruct it to call DriveAgent; to continue a prior session across runs, have that turn pass " +
|
|
22
|
+
"the sessionId this tool returned as resumeSessionId (same cli). To make the single turn work " +
|
|
23
|
+
"longer/deeper, write that into `prompt` (e.g. 'keep working until done'). " +
|
|
24
|
+
"Pass `resumeSessionId` to continue a prior session of the SAME cli (keeps context); omit to start fresh.\n" +
|
|
25
|
+
"SCOPE & BUDGET (read before fanning out): each driven agent consumes a large, SHARED token budget. " +
|
|
26
|
+
"Do NOT launch many agents at once to 'cover more ground' — that burns the budget and leaves every " +
|
|
27
|
+
"task half-done. Default to ONE agent at a time; only run a few in parallel when the work TRULY splits " +
|
|
28
|
+
"into independent pieces, and even then keep the count small (≈2-3). Prefer finishing one task before " +
|
|
29
|
+
"starting the next. " +
|
|
30
|
+
"Make each `prompt` a COMPLETE, self-contained task that instructs the agent to finish the whole thing " +
|
|
31
|
+
"end-to-end and verify its own work before returning — never a vague 'start looking into X'. " +
|
|
32
|
+
"Give it a concrete definition of done and, for open-ended work, a bound (files/scope/steps) so it " +
|
|
33
|
+
"doesn't sprawl. If a big job must be split, split it into a SEQUENCE you drive one at a time (resume " +
|
|
34
|
+
"the same session), not a swarm launched simultaneously.",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
prompt: { type: "string", description: "The task for the agent. Make it COMPLETE and self-contained: state the goal, a concrete definition of done, and (for open-ended work) an explicit scope bound so it finishes end-to-end and verifies its own work rather than sprawling or stopping half-way." },
|
|
39
|
+
cli: { type: "string", enum: ["claude", "codex"], description: "Which external CLI to drive. 'claude' = Claude Code (default), 'codex' = OpenAI Codex. resumeSessionId is only valid against the same cli that produced it." },
|
|
40
|
+
resumeSessionId: { type: "string", description: "Existing session id to resume (keeps context). Must come from a prior run of the SAME cli. Omit for a fresh session." },
|
|
41
|
+
cwd: { type: "string", description: "Working directory the run operates in." },
|
|
42
|
+
permissionMode: { type: "string", enum: ["default", "acceptEdits", "bypassPermissions"], description: "Permission/sandbox level. Defaults to 'bypassPermissions' (full auto — needed so the agent's tools run unattended; there is no interactive approval loop here). For codex: default→read-only sandbox, acceptEdits→workspace-write, bypassPermissions→no sandbox. Pass 'default'/'acceptEdits' to gate." },
|
|
43
|
+
background: { type: "boolean", description: "Defaults to TRUE: run in the background and notify you on completion (right for long tasks). Pass false to run in the foreground and get the result inline (only for quick tasks)." },
|
|
44
|
+
},
|
|
45
|
+
required: ["prompt", "cwd"],
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const defaultRunner = (opts) => {
|
|
49
|
+
const { adapter, command } = CLI_ADAPTERS[opts.cli];
|
|
50
|
+
return runAgentOnce(adapter, { command, prompt: opts.prompt, resumeSessionId: opts.resumeSessionId, cwd: opts.cwd, permissionMode: opts.permissionMode ?? "default" });
|
|
51
|
+
};
|
|
52
|
+
/** Factory so tests can inject a fake runner. `fixedCli` (back-compat) forces a
|
|
53
|
+
* cli and hides the `cli` arg — that's how DriveClaudeCode stays a thin alias. */
|
|
54
|
+
export function makeDriveAgentTool(runner = defaultRunner, fixedCli) {
|
|
55
|
+
return async (args, ctx) => {
|
|
56
|
+
const prompt = typeof args.prompt === "string" ? args.prompt : "";
|
|
57
|
+
const cwd = typeof args.cwd === "string" ? args.cwd : process.cwd();
|
|
58
|
+
if (!prompt)
|
|
59
|
+
return "Error: prompt is required";
|
|
60
|
+
const cli = fixedCli ?? (args.cli === "codex" ? "codex" : args.cli === "claude" || args.cli === undefined ? "claude" : "invalid");
|
|
61
|
+
if (cli === "invalid")
|
|
62
|
+
return `Error: unknown cli "${String(args.cli)}" (expected "claude" or "codex")`;
|
|
63
|
+
const resumeSessionId = typeof args.resumeSessionId === "string" ? args.resumeSessionId : undefined;
|
|
64
|
+
// Default to bypassPermissions: this tool is a fire-one-turn delegation to
|
|
65
|
+
// an external CLI with nobody watching for approvals, and there is no
|
|
66
|
+
// interactive approval loop here — so under "default" a tool that needs
|
|
67
|
+
// approval (WebSearch/WebFetch/Write) silently can't run (the
|
|
68
|
+
// "DriveClaudeCode 没有联网能力" report). A caller that wants gating passes
|
|
69
|
+
// an explicit mode, which is honored. (For codex, the mode maps to a sandbox
|
|
70
|
+
// tier inside codexAdapter.)
|
|
71
|
+
const permissionMode = args.permissionMode === "default" ||
|
|
72
|
+
args.permissionMode === "acceptEdits" ||
|
|
73
|
+
args.permissionMode === "bypassPermissions"
|
|
74
|
+
? args.permissionMode
|
|
75
|
+
: "bypassPermissions";
|
|
76
|
+
const cliName = cli === "codex" ? "Codex" : "Claude Code";
|
|
77
|
+
const label = `DriveAgent(${cli}): ${prompt.slice(0, 40)}`;
|
|
78
|
+
// Background by default (these tasks are typically long). Only an explicit
|
|
79
|
+
// background:false runs in the foreground and returns the result inline.
|
|
80
|
+
const background = args.background !== false;
|
|
81
|
+
if (background) {
|
|
82
|
+
// Fail loud on a missing sessionId: a background job whose completion
|
|
83
|
+
// notification can't be routed (enqueue drops invalid/empty sessionId)
|
|
84
|
+
// would run to completion and then silently vanish — nobody gets woken
|
|
85
|
+
// with the result. Refuse up front instead of launching disappearing work.
|
|
86
|
+
const sessionId = ctx?.sessionId;
|
|
87
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
88
|
+
return `Error: cannot start a background ${cliName} job without a session — its result notification would be dropped. Retry with background:false, or ensure the tool runs inside a session.`;
|
|
89
|
+
}
|
|
90
|
+
const jobId = `cc-${process.hrtime.bigint().toString(36)}`;
|
|
91
|
+
backgroundJobRegistry.start(jobId, sessionId, label);
|
|
92
|
+
void runner({ cli, prompt, resumeSessionId, cwd, permissionMode })
|
|
93
|
+
.then((r) => {
|
|
94
|
+
// Deliver the result back so the woken agent actually sees the answer
|
|
95
|
+
// (not just "a job finished"). Mirrors the video/sub-agent completion
|
|
96
|
+
// path — enqueue lands in the same notificationQueue the wakeup drains.
|
|
97
|
+
notificationQueue.enqueue(r.isError
|
|
98
|
+
? { agentId: jobId, description: label, status: "failed", workKind: "cc", error: r.finalText || "(no output)", ccSessionId: r.sessionId || undefined, enqueuedAt: Date.now() }
|
|
99
|
+
: { agentId: jobId, description: label, status: "completed", workKind: "cc", finalText: r.finalText, ccSessionId: r.sessionId || undefined, enqueuedAt: Date.now() }, sessionId);
|
|
100
|
+
// Attribute the files the external agent changed by parsing its own
|
|
101
|
+
// transcript (#6) — those Edit/Write calls are invisible to the host's
|
|
102
|
+
// in-session aggregator. Best-effort; [] on any failure.
|
|
103
|
+
const changedFiles = r.sessionId
|
|
104
|
+
? readExternalChangedFiles(cli, cwd, r.sessionId)
|
|
105
|
+
: [];
|
|
106
|
+
// Retain the job in the panel with its result + the external CLI
|
|
107
|
+
// session id + changed files.
|
|
108
|
+
backgroundJobRegistry.finish(jobId, {
|
|
109
|
+
status: r.isError ? "failed" : "completed",
|
|
110
|
+
finalText: r.finalText || undefined,
|
|
111
|
+
ccSessionId: r.sessionId || undefined,
|
|
112
|
+
...(changedFiles.length ? { changedFiles } : {}),
|
|
113
|
+
});
|
|
114
|
+
})
|
|
115
|
+
.catch((err) => {
|
|
116
|
+
const msg = err?.message ?? String(err);
|
|
117
|
+
notificationQueue.enqueue({ agentId: jobId, description: label, status: "failed", workKind: "cc", error: msg, enqueuedAt: Date.now() }, sessionId);
|
|
118
|
+
backgroundJobRegistry.finish(jobId, { status: "failed", finalText: msg });
|
|
119
|
+
});
|
|
120
|
+
return `已在后台启动 ${cliName}(jobId ${jobId})。完成后会通知你结果,无需轮询。`;
|
|
121
|
+
}
|
|
122
|
+
const r = await runner({ cli, prompt, resumeSessionId, cwd, permissionMode });
|
|
123
|
+
if (r.isError)
|
|
124
|
+
return `${cliName} 运行出错(session ${r.sessionId}):\n${r.finalText}`;
|
|
125
|
+
return `${cliName} 完成(session ${r.sessionId}):\n${r.finalText}`;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export const driveAgentTool = makeDriveAgentTool();
|
|
129
|
+
// ── Back-compat: DriveClaudeCode = DriveAgent pinned to cli:"claude" ──────────
|
|
130
|
+
// Kept so old prompts / memories / call sites that reference DriveClaudeCode
|
|
131
|
+
// keep working. It's a thin alias over the same machinery (fixedCli "claude").
|
|
132
|
+
export const driveClaudeCodeToolDef = {
|
|
133
|
+
...driveAgentToolDef,
|
|
134
|
+
name: "DriveClaudeCode",
|
|
135
|
+
description: "(Alias of DriveAgent with cli:claude.) Delegate a task to the external Claude Code CLI " +
|
|
136
|
+
"(drives `claude` for one turn). Prefer DriveAgent for new calls; this name is kept for " +
|
|
137
|
+
"compatibility. " + driveAgentToolDef.description,
|
|
138
|
+
inputSchema: {
|
|
139
|
+
type: "object",
|
|
140
|
+
properties: {
|
|
141
|
+
// intentionally omit `cli` — this alias is always claude
|
|
142
|
+
prompt: driveAgentToolDef.inputSchema.properties.prompt,
|
|
143
|
+
resumeSessionId: { type: "string", description: "Existing CC session id to resume (keeps context). Omit for a fresh session." },
|
|
144
|
+
cwd: driveAgentToolDef.inputSchema.properties.cwd,
|
|
145
|
+
permissionMode: driveAgentToolDef.inputSchema.properties.permissionMode,
|
|
146
|
+
background: driveAgentToolDef.inputSchema.properties.background,
|
|
147
|
+
},
|
|
148
|
+
required: ["prompt", "cwd"],
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
export function makeDriveClaudeCodeTool(runner) {
|
|
152
|
+
const generic = runner
|
|
153
|
+
? ({ prompt, resumeSessionId, cwd, permissionMode }) => runner({ prompt, resumeSessionId, cwd, permissionMode })
|
|
154
|
+
: undefined;
|
|
155
|
+
return makeDriveAgentTool(generic ?? defaultRunner, "claude");
|
|
156
|
+
}
|
|
157
|
+
export const driveClaudeCodeTool = makeDriveClaudeCodeTool();
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EditModelCatalog tool — add or update a provider/model template in the user
|
|
3
|
+
* model catalog (~/.code-shell/model-catalog.user.json). Pairs with the
|
|
4
|
+
* model-fact-finder skill: the skill researches a model's facts (modalities,
|
|
5
|
+
* params, context), then this tool writes them into a CatalogEntry so the
|
|
6
|
+
* connection page picks it up. Backs up before writing; validates against the
|
|
7
|
+
* schema; never touches API keys/credentials (those go through the user's own
|
|
8
|
+
* Edit, by design). See docs/.../2026-06-15-unified-model-catalog-design.md §7.
|
|
9
|
+
*/
|
|
10
|
+
import { randomBytes } from "node:crypto";
|
|
11
|
+
import { userCatalogPath } from "../../model-catalog/index.js";
|
|
12
|
+
import { saveCatalogEntry } from "../../model-catalog/save-entry.js";
|
|
13
|
+
export const editModelCatalogToolDef = {
|
|
14
|
+
name: "EditModelCatalog",
|
|
15
|
+
description: "Add or update a provider/model template in the user model catalog so it " +
|
|
16
|
+
"appears in the connection page (text/image/video). Keyed by `id` — a new id " +
|
|
17
|
+
"adds, an existing id updates (in place). Backs up the file before writing and " +
|
|
18
|
+
"validates the entry. Use after researching a model's real facts (id, context " +
|
|
19
|
+
"window, supported params, modalities) — do NOT guess; verify against the " +
|
|
20
|
+
"provider's official docs first (see the model-fact-finder skill). Does NOT set " +
|
|
21
|
+
"API keys: the user enters keys in the connection page (credentials), not here.",
|
|
22
|
+
inputSchema: {
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
entry: {
|
|
26
|
+
type: "object",
|
|
27
|
+
description: "A full CatalogEntry. Required: id, tag (text|image|video), adapterKind " +
|
|
28
|
+
"(an already-wired adapter: openai|anthropic|google|fal), displayName, " +
|
|
29
|
+
"description, defaultBaseUrl. Optional: protocol (openai-compat|anthropic-style), " +
|
|
30
|
+
"defaultModel, needsKey, signupUrl, test, modelPresets[] (each {value, label?, " +
|
|
31
|
+
"maxContextTokens?, maxOutputTokens?, supportsVision?, params?[]}). Each param: " +
|
|
32
|
+
"{name, label?, control (enum|number|toggle|text), options?[], min?, max?, default?, " +
|
|
33
|
+
"doc?, wire?{field}}. Fill maxContextTokens with the model's REAL window; declare " +
|
|
34
|
+
"params per-model (only what that model supports).",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
required: ["entry"],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
export async function editModelCatalogTool(args) {
|
|
41
|
+
const entry = args.entry;
|
|
42
|
+
if (!entry || typeof entry !== "object") {
|
|
43
|
+
return "Error: `entry` (a CatalogEntry object) is required.";
|
|
44
|
+
}
|
|
45
|
+
const stamp = `${Date.now()}-${randomBytes(3).toString("hex")}`;
|
|
46
|
+
const r = saveCatalogEntry(entry, { path: userCatalogPath(), stamp });
|
|
47
|
+
if (!r.ok)
|
|
48
|
+
return `Error: ${r.error}`;
|
|
49
|
+
return summarizeWrite(entry, r.action ?? "added", r.backup);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Build a structured completion summary so the user can SEE exactly what was
|
|
53
|
+
* written and catch a wrong value at a glance — every param's options/default
|
|
54
|
+
* is echoed back, because that's where catalog entries go wrong (e.g. listing a
|
|
55
|
+
* gateway's input aliases as if they were the model's native effort levels).
|
|
56
|
+
* The LLM is told to relay this and ask the user to verify against the docs.
|
|
57
|
+
*/
|
|
58
|
+
function summarizeWrite(entry, action, backup) {
|
|
59
|
+
const id = entry.id ?? "(unknown)";
|
|
60
|
+
const lines = [];
|
|
61
|
+
lines.push(`✅ ${action === "updated" ? "Updated" : "Added"} catalog entry "${id}".`);
|
|
62
|
+
lines.push(`tag: ${entry.tag ?? "?"} | adapter: ${entry.adapterKind ?? "?"}` +
|
|
63
|
+
(entry.defaultModel ? ` | defaultModel: ${entry.defaultModel}` : "") +
|
|
64
|
+
(entry.defaultBaseUrl ? ` | baseUrl: ${entry.defaultBaseUrl}` : ""));
|
|
65
|
+
const presets = entry.modelPresets ?? [];
|
|
66
|
+
if (presets.length === 0) {
|
|
67
|
+
lines.push("(no modelPresets)");
|
|
68
|
+
}
|
|
69
|
+
for (const p of presets) {
|
|
70
|
+
const ctx = p.maxContextTokens ? `ctx ${p.maxContextTokens}` : "";
|
|
71
|
+
const out = p.maxOutputTokens ? `out ${p.maxOutputTokens}` : "";
|
|
72
|
+
const limits = [ctx, out].filter(Boolean).join(", ");
|
|
73
|
+
lines.push(`\nmodel: ${p.value ?? "?"}${p.label ? ` (${p.label})` : ""}${limits ? ` — ${limits}` : ""}`);
|
|
74
|
+
const params = p.params ?? [];
|
|
75
|
+
if (params.length === 0) {
|
|
76
|
+
lines.push(" (no params declared)");
|
|
77
|
+
}
|
|
78
|
+
for (const pa of params) {
|
|
79
|
+
let detail = "";
|
|
80
|
+
if (pa.control === "enum")
|
|
81
|
+
detail = `options=[${(pa.options ?? []).join(", ")}]`;
|
|
82
|
+
else if (pa.control === "number")
|
|
83
|
+
detail = `range ${pa.min ?? "?"}..${pa.max ?? "?"}`;
|
|
84
|
+
const def = pa.default !== undefined ? ` default=${JSON.stringify(pa.default)}` : "";
|
|
85
|
+
lines.push(` - ${pa.name ?? "?"} (${pa.control ?? "?"}) ${detail}${def}`.trimEnd());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
lines.push(`\nWritten to ${userCatalogPath()}.` + (backup ? ` Backup: ${backup}.` : ""));
|
|
89
|
+
lines.push("Hot-reloads — the connection page refreshes once this turn completes.");
|
|
90
|
+
lines.push("⚠️ Relay this summary to the user and ask them to verify each param's options/default " +
|
|
91
|
+
"match the provider's OFFICIAL docs — especially enum levels (a gateway's input aliases " +
|
|
92
|
+
"are NOT the model's native values). To fix: edit this file directly, or ask me to.");
|
|
93
|
+
return lines.join("\n");
|
|
94
|
+
}
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
* Built-in Edit file tool — exact string replacement.
|
|
3
3
|
*/
|
|
4
4
|
import type { ToolDefinition } from "../../types.js";
|
|
5
|
+
import type { ToolContext } from "../context.js";
|
|
5
6
|
export declare const editToolDef: ToolDefinition;
|
|
6
|
-
export declare function editTool(args: Record<string, unknown
|
|
7
|
+
export declare function editTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { readFile, writeFile } from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { fileCache } from "./file-cache.js";
|
|
7
|
+
import { detectEol, toLf, applyEol } from "./eol.js";
|
|
7
8
|
export const editToolDef = {
|
|
8
9
|
name: "Edit",
|
|
9
10
|
description: "Perform exact string replacements in a file. " +
|
|
@@ -30,7 +31,7 @@ export const editToolDef = {
|
|
|
30
31
|
required: ["file_path", "old_string", "new_string"],
|
|
31
32
|
},
|
|
32
33
|
};
|
|
33
|
-
export async function editTool(args) {
|
|
34
|
+
export async function editTool(args, ctx) {
|
|
34
35
|
const filePath = args.file_path;
|
|
35
36
|
const oldString = args.old_string;
|
|
36
37
|
const newString = args.new_string;
|
|
@@ -46,28 +47,36 @@ export async function editTool(args) {
|
|
|
46
47
|
if (!existsSync(filePath))
|
|
47
48
|
return `Error: File not found: ${filePath}`;
|
|
48
49
|
try {
|
|
49
|
-
const
|
|
50
|
-
|
|
50
|
+
const raw = await readFile(filePath, "utf-8");
|
|
51
|
+
// CRLF handling: detect the file's line ending, then match/replace in LF
|
|
52
|
+
// space (the model emits LF, so a CRLF file would never match otherwise),
|
|
53
|
+
// and write back in the ORIGINAL EOL so a CRLF file stays CRLF (no whole-
|
|
54
|
+
// file diff churn). See eol.ts.
|
|
55
|
+
const eol = detectEol(raw);
|
|
56
|
+
const content = toLf(raw);
|
|
57
|
+
const oldLf = toLf(oldString);
|
|
58
|
+
const newLf = toLf(newString);
|
|
59
|
+
if (!content.includes(oldLf)) {
|
|
51
60
|
return "Error: old_string not found in file";
|
|
52
61
|
}
|
|
53
62
|
if (!replaceAll) {
|
|
54
|
-
const firstIdx = content.indexOf(
|
|
55
|
-
const lastIdx = content.lastIndexOf(
|
|
63
|
+
const firstIdx = content.indexOf(oldLf);
|
|
64
|
+
const lastIdx = content.lastIndexOf(oldLf);
|
|
56
65
|
if (firstIdx !== lastIdx) {
|
|
57
66
|
return "Error: old_string is not unique in the file. Provide more context or use replace_all.";
|
|
58
67
|
}
|
|
59
68
|
}
|
|
60
|
-
const
|
|
61
|
-
? content.split(
|
|
62
|
-
: content.replace(
|
|
63
|
-
await writeFile(filePath,
|
|
69
|
+
const updatedLf = replaceAll
|
|
70
|
+
? content.split(oldLf).join(newLf)
|
|
71
|
+
: content.replace(oldLf, newLf);
|
|
72
|
+
await writeFile(filePath, applyEol(updatedLf, eol), "utf-8");
|
|
64
73
|
fileCache.invalidate(filePath);
|
|
65
74
|
const count = replaceAll
|
|
66
|
-
? (content.split(
|
|
75
|
+
? (content.split(oldLf).length - 1)
|
|
67
76
|
: 1;
|
|
68
77
|
// Generate a compact diff summary
|
|
69
|
-
const oldLines =
|
|
70
|
-
const newLines =
|
|
78
|
+
const oldLines = oldLf.split("\n");
|
|
79
|
+
const newLines = newLf.split("\n");
|
|
71
80
|
const diffSummary = generateCompactDiff(oldLines, newLines, filePath);
|
|
72
81
|
return `Successfully edited ${filePath} (${count} replacement${count > 1 ? "s" : ""})\n${diffSummary}`;
|
|
73
82
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EOL (line-ending) helpers for file-editing tools.
|
|
3
|
+
*
|
|
4
|
+
* Windows files are typically CRLF (`\r\n`); the model emits LF (`\n`). The
|
|
5
|
+
* file tools match the model's strings against file content and write the
|
|
6
|
+
* result back. Without normalization:
|
|
7
|
+
* - an LF `old_string` never matches a CRLF file → "old_string not found";
|
|
8
|
+
* - a successful write that re-joins with LF silently converts a CRLF file
|
|
9
|
+
* to LF, so `git diff` shows the whole file changed (and an .editorconfig
|
|
10
|
+
* /prettier may flip it right back → churn).
|
|
11
|
+
*
|
|
12
|
+
* The contract these helpers enforce:
|
|
13
|
+
* 1. Detect the file's dominant EOL.
|
|
14
|
+
* 2. Compare/replace in LF space (normalize both file content and the
|
|
15
|
+
* model's needle to LF first).
|
|
16
|
+
* 3. Write back in the ORIGINAL EOL so the file's line-ending style is
|
|
17
|
+
* preserved.
|
|
18
|
+
*/
|
|
19
|
+
export type Eol = "\r\n" | "\n";
|
|
20
|
+
/**
|
|
21
|
+
* The file's dominant line ending. CRLF if the content contains ANY `\r\n`
|
|
22
|
+
* (Windows editors are all-or-nothing in practice); otherwise LF. Empty/no-
|
|
23
|
+
* newline content defaults to LF.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectEol(content: string): Eol;
|
|
26
|
+
/** Collapse all CRLF (and lone CR) to LF for comparison/replacement. */
|
|
27
|
+
export declare function toLf(s: string): string;
|
|
28
|
+
/** Re-apply an EOL to LF-normalized text. No-op for LF. */
|
|
29
|
+
export declare function applyEol(s: string, eol: Eol): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EOL (line-ending) helpers for file-editing tools.
|
|
3
|
+
*
|
|
4
|
+
* Windows files are typically CRLF (`\r\n`); the model emits LF (`\n`). The
|
|
5
|
+
* file tools match the model's strings against file content and write the
|
|
6
|
+
* result back. Without normalization:
|
|
7
|
+
* - an LF `old_string` never matches a CRLF file → "old_string not found";
|
|
8
|
+
* - a successful write that re-joins with LF silently converts a CRLF file
|
|
9
|
+
* to LF, so `git diff` shows the whole file changed (and an .editorconfig
|
|
10
|
+
* /prettier may flip it right back → churn).
|
|
11
|
+
*
|
|
12
|
+
* The contract these helpers enforce:
|
|
13
|
+
* 1. Detect the file's dominant EOL.
|
|
14
|
+
* 2. Compare/replace in LF space (normalize both file content and the
|
|
15
|
+
* model's needle to LF first).
|
|
16
|
+
* 3. Write back in the ORIGINAL EOL so the file's line-ending style is
|
|
17
|
+
* preserved.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The file's dominant line ending. CRLF if the content contains ANY `\r\n`
|
|
21
|
+
* (Windows editors are all-or-nothing in practice); otherwise LF. Empty/no-
|
|
22
|
+
* newline content defaults to LF.
|
|
23
|
+
*/
|
|
24
|
+
export function detectEol(content) {
|
|
25
|
+
return content.includes("\r\n") ? "\r\n" : "\n";
|
|
26
|
+
}
|
|
27
|
+
/** Collapse all CRLF (and lone CR) to LF for comparison/replacement. */
|
|
28
|
+
export function toLf(s) {
|
|
29
|
+
return s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
30
|
+
}
|
|
31
|
+
/** Re-apply an EOL to LF-normalized text. No-op for LF. */
|
|
32
|
+
export function applyEol(s, eol) {
|
|
33
|
+
if (eol === "\n")
|
|
34
|
+
return s;
|
|
35
|
+
// s is already LF-normalized by callers; map every LF back to CRLF.
|
|
36
|
+
return s.replace(/\n/g, "\r\n");
|
|
37
|
+
}
|
|
@@ -5,6 +5,12 @@ declare class FileStateCache {
|
|
|
5
5
|
/** Invalidate a specific path (after Write/Edit). */
|
|
6
6
|
invalidate(filePath: string): void;
|
|
7
7
|
clear(): void;
|
|
8
|
+
/**
|
|
9
|
+
* True if a cache entry for `filePath` is currently held. Pure key-presence
|
|
10
|
+
* check — does NOT stat/self-heal like `get()`, so a test can assert a manual
|
|
11
|
+
* `invalidate()` actually removed the key without the mtime path masking it.
|
|
12
|
+
*/
|
|
13
|
+
has(filePath: string): boolean;
|
|
8
14
|
get size(): number;
|
|
9
15
|
}
|
|
10
16
|
export declare const fileCache: FileStateCache;
|
|
@@ -32,6 +32,14 @@ class FileStateCache {
|
|
|
32
32
|
clear() {
|
|
33
33
|
this.cache.clear();
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* True if a cache entry for `filePath` is currently held. Pure key-presence
|
|
37
|
+
* check — does NOT stat/self-heal like `get()`, so a test can assert a manual
|
|
38
|
+
* `invalidate()` actually removed the key without the mtime path masking it.
|
|
39
|
+
*/
|
|
40
|
+
has(filePath) {
|
|
41
|
+
return this.cache.has(filePath);
|
|
42
|
+
}
|
|
35
43
|
get size() {
|
|
36
44
|
return this.cache.size;
|
|
37
45
|
}
|