@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
package/dist/remote/bridge.js
CHANGED
|
@@ -6,42 +6,71 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { spawn } from "node:child_process";
|
|
8
8
|
import { createInterface } from "node:readline";
|
|
9
|
+
/**
|
|
10
|
+
* Build the ssh argv. Each value is a discrete element — spawn runs ssh
|
|
11
|
+
* without a shell, so identityFile/port/host are never shell-interpreted
|
|
12
|
+
* (there is no local command-injection surface here).
|
|
13
|
+
*/
|
|
14
|
+
export function buildSSHArgs(config) {
|
|
15
|
+
const args = ["-T"]; // No pseudo-terminal
|
|
16
|
+
if (config.port)
|
|
17
|
+
args.push("-p", String(config.port));
|
|
18
|
+
if (config.identityFile)
|
|
19
|
+
args.push("-i", config.identityFile);
|
|
20
|
+
args.push(config.user ? `${config.user}@${config.host}` : config.host);
|
|
21
|
+
return args;
|
|
22
|
+
}
|
|
9
23
|
export class RemoteBridge {
|
|
10
24
|
config;
|
|
11
25
|
ssh;
|
|
12
26
|
connected = false;
|
|
13
|
-
|
|
27
|
+
spawnFn;
|
|
28
|
+
constructor(config, spawnFn) {
|
|
14
29
|
this.config = config;
|
|
30
|
+
this.spawnFn = spawnFn ?? ((cmd, args) => spawn(cmd, args, { stdio: ["pipe", "pipe", "pipe"] }));
|
|
15
31
|
}
|
|
16
32
|
/**
|
|
17
33
|
* Connect to the remote host via SSH and start code-shell in NDJSON mode.
|
|
18
34
|
*/
|
|
19
35
|
async connect() {
|
|
20
|
-
const sshArgs = this.
|
|
36
|
+
const sshArgs = buildSSHArgs(this.config);
|
|
21
37
|
const remoteCmd = this.config.remoteCommand ?? "code-shell run --output stream-json";
|
|
22
|
-
this.ssh =
|
|
23
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
24
|
-
});
|
|
38
|
+
this.ssh = this.spawnFn("ssh", [...sshArgs, remoteCmd]);
|
|
25
39
|
return new Promise((resolve, reject) => {
|
|
40
|
+
// Settle exactly once: the first stdout resolves; an error/early-exit
|
|
41
|
+
// before that rejects. Events after settlement are ignored (the old
|
|
42
|
+
// code re-rejected an already-settled promise and used a dead
|
|
43
|
+
// `if (!this.connected)` guard that was always true).
|
|
44
|
+
let settled = false;
|
|
26
45
|
const timer = setTimeout(() => {
|
|
46
|
+
if (settled)
|
|
47
|
+
return;
|
|
48
|
+
settled = true;
|
|
27
49
|
reject(new Error("SSH connection timed out"));
|
|
28
50
|
this.disconnect();
|
|
29
51
|
}, 30000);
|
|
30
52
|
this.ssh.stdout?.once("data", () => {
|
|
53
|
+
if (settled)
|
|
54
|
+
return;
|
|
55
|
+
settled = true;
|
|
31
56
|
clearTimeout(timer);
|
|
32
57
|
this.connected = true;
|
|
33
58
|
resolve();
|
|
34
59
|
});
|
|
35
60
|
this.ssh.on("error", (err) => {
|
|
61
|
+
if (settled)
|
|
62
|
+
return;
|
|
63
|
+
settled = true;
|
|
36
64
|
clearTimeout(timer);
|
|
37
65
|
reject(err);
|
|
38
66
|
});
|
|
39
67
|
this.ssh.on("exit", (code) => {
|
|
40
68
|
this.connected = false;
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
69
|
+
if (settled)
|
|
70
|
+
return;
|
|
71
|
+
settled = true;
|
|
72
|
+
clearTimeout(timer);
|
|
73
|
+
reject(new Error(`SSH exited with code ${code}`));
|
|
45
74
|
});
|
|
46
75
|
});
|
|
47
76
|
}
|
|
@@ -52,7 +81,13 @@ export class RemoteBridge {
|
|
|
52
81
|
if (!this.connected || !this.ssh?.stdin) {
|
|
53
82
|
throw new Error("Not connected");
|
|
54
83
|
}
|
|
55
|
-
this.ssh.stdin.write(JSON.stringify(message) + "\n")
|
|
84
|
+
this.ssh.stdin.write(JSON.stringify(message) + "\n", (err) => {
|
|
85
|
+
if (err) {
|
|
86
|
+
// A broken pipe means the remote is gone — surface it as a
|
|
87
|
+
// disconnect rather than swallowing the failed write.
|
|
88
|
+
this.connected = false;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
56
91
|
}
|
|
57
92
|
/**
|
|
58
93
|
* Async iterator for messages from the remote code-shell.
|
|
@@ -61,17 +96,24 @@ export class RemoteBridge {
|
|
|
61
96
|
if (!this.ssh?.stdout)
|
|
62
97
|
return;
|
|
63
98
|
const rl = createInterface({ input: this.ssh.stdout, crlfDelay: Infinity });
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
99
|
+
try {
|
|
100
|
+
for await (const line of rl) {
|
|
101
|
+
const trimmed = line.trim();
|
|
102
|
+
if (!trimmed)
|
|
103
|
+
continue;
|
|
104
|
+
try {
|
|
105
|
+
yield JSON.parse(trimmed);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
// Skip malformed
|
|
109
|
+
}
|
|
73
110
|
}
|
|
74
111
|
}
|
|
112
|
+
finally {
|
|
113
|
+
// Close the interface if the consumer breaks/returns early — otherwise
|
|
114
|
+
// it (and its stdout listener) leaks.
|
|
115
|
+
rl.close();
|
|
116
|
+
}
|
|
75
117
|
}
|
|
76
118
|
/**
|
|
77
119
|
* Disconnect from the remote host.
|
|
@@ -86,18 +128,4 @@ export class RemoteBridge {
|
|
|
86
128
|
get isConnected() {
|
|
87
129
|
return this.connected;
|
|
88
130
|
}
|
|
89
|
-
buildSSHArgs() {
|
|
90
|
-
const args = ["-T"]; // No pseudo-terminal
|
|
91
|
-
if (this.config.port)
|
|
92
|
-
args.push("-p", String(this.config.port));
|
|
93
|
-
if (this.config.identityFile)
|
|
94
|
-
args.push("-i", this.config.identityFile);
|
|
95
|
-
if (this.config.user) {
|
|
96
|
-
args.push(`${this.config.user}@${this.config.host}`);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
args.push(this.config.host);
|
|
100
|
-
}
|
|
101
|
-
return args;
|
|
102
|
-
}
|
|
103
131
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code-review prompt builder (TODO 7.3). Produces the instruction sent to the
|
|
3
|
+
* model for `/review`. Pure + testable — the TUI/desktop command gathers the
|
|
4
|
+
* diff or file contents and calls this; the model does the actual reasoning.
|
|
5
|
+
*
|
|
6
|
+
* Findings are structured: priority P0–P3, a confidence score, and a precise
|
|
7
|
+
* location, so the output is consistent and (optionally) machine-readable for
|
|
8
|
+
* CI/CD via `--json`.
|
|
9
|
+
*/
|
|
10
|
+
export type ReviewDimension = "security" | "performance" | "readability" | "correctness";
|
|
11
|
+
export declare const ALL_DIMENSIONS: ReviewDimension[];
|
|
12
|
+
export interface ReviewPromptOptions {
|
|
13
|
+
/** The unified diff (incremental) or full file contents to review. */
|
|
14
|
+
content: string;
|
|
15
|
+
/** Which dimensions to weigh. Defaults to all four. */
|
|
16
|
+
dimensions?: ReviewDimension[];
|
|
17
|
+
/** True when reviewing a diff (incremental); false when reviewing whole files. */
|
|
18
|
+
incremental?: boolean;
|
|
19
|
+
/** Emit a machine-readable JSON findings array (for CI/CD) instead of prose. */
|
|
20
|
+
json?: boolean;
|
|
21
|
+
/** Optional label for what's under review (e.g. a file path). */
|
|
22
|
+
label?: string;
|
|
23
|
+
/** Truncate content to this many chars (default 12000). */
|
|
24
|
+
maxChars?: number;
|
|
25
|
+
}
|
|
26
|
+
/** Normalize a comma/space list of dimension names; invalid names dropped. */
|
|
27
|
+
export declare function parseDimensions(input: string | undefined): ReviewDimension[];
|
|
28
|
+
export declare function buildReviewPrompt(opts: ReviewPromptOptions): string;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code-review prompt builder (TODO 7.3). Produces the instruction sent to the
|
|
3
|
+
* model for `/review`. Pure + testable — the TUI/desktop command gathers the
|
|
4
|
+
* diff or file contents and calls this; the model does the actual reasoning.
|
|
5
|
+
*
|
|
6
|
+
* Findings are structured: priority P0–P3, a confidence score, and a precise
|
|
7
|
+
* location, so the output is consistent and (optionally) machine-readable for
|
|
8
|
+
* CI/CD via `--json`.
|
|
9
|
+
*/
|
|
10
|
+
export const ALL_DIMENSIONS = [
|
|
11
|
+
"correctness",
|
|
12
|
+
"security",
|
|
13
|
+
"performance",
|
|
14
|
+
"readability",
|
|
15
|
+
];
|
|
16
|
+
const DIMENSION_LABEL = {
|
|
17
|
+
security: "安全 (injection, authz, secret leakage, unsafe deserialization)",
|
|
18
|
+
performance: "性能 (N+1, needless allocation, blocking I/O, complexity)",
|
|
19
|
+
readability: "可读性 (naming, structure, dead code, comment accuracy)",
|
|
20
|
+
correctness: "正确性 (logic bugs, edge cases, error handling, races)",
|
|
21
|
+
};
|
|
22
|
+
/** Normalize a comma/space list of dimension names; invalid names dropped. */
|
|
23
|
+
export function parseDimensions(input) {
|
|
24
|
+
if (!input)
|
|
25
|
+
return ALL_DIMENSIONS;
|
|
26
|
+
const wanted = input
|
|
27
|
+
.split(/[\s,]+/)
|
|
28
|
+
.map((s) => s.trim().toLowerCase())
|
|
29
|
+
.filter(Boolean);
|
|
30
|
+
const picked = ALL_DIMENSIONS.filter((d) => wanted.includes(d));
|
|
31
|
+
return picked.length > 0 ? picked : ALL_DIMENSIONS;
|
|
32
|
+
}
|
|
33
|
+
const PRIORITY_GUIDE = "Priority: P0 = must fix before merge (data loss, security hole, crash); " +
|
|
34
|
+
"P1 = should fix (likely bug, real risk); " +
|
|
35
|
+
"P2 = nice to fix (smell, minor inefficiency); " +
|
|
36
|
+
"P3 = optional (style, nit).";
|
|
37
|
+
export function buildReviewPrompt(opts) {
|
|
38
|
+
const dims = opts.dimensions?.length ? opts.dimensions : ALL_DIMENSIONS;
|
|
39
|
+
const maxChars = opts.maxChars ?? 12_000;
|
|
40
|
+
const body = opts.content.length > maxChars
|
|
41
|
+
? opts.content.slice(0, maxChars) + "\n…(truncated)…"
|
|
42
|
+
: opts.content;
|
|
43
|
+
const fence = opts.incremental === false ? "" : "diff";
|
|
44
|
+
const what = opts.incremental === false ? "code" : "code changes (diff)";
|
|
45
|
+
const subject = opts.label ? ` for \`${opts.label}\`` : "";
|
|
46
|
+
const dimLines = dims.map((d) => ` - ${DIMENSION_LABEL[d]}`).join("\n");
|
|
47
|
+
if (opts.json) {
|
|
48
|
+
return [
|
|
49
|
+
`Review the following ${what}${subject} across these dimensions:`,
|
|
50
|
+
dimLines,
|
|
51
|
+
``,
|
|
52
|
+
PRIORITY_GUIDE,
|
|
53
|
+
``,
|
|
54
|
+
`Respond with ONLY a JSON object (no prose, no markdown fence) of the form:`,
|
|
55
|
+
`{"summary": string, "findings": [{"priority": "P0"|"P1"|"P2"|"P3", ` +
|
|
56
|
+
`"dimension": ${dims.map((d) => `"${d}"`).join("|")}, ` +
|
|
57
|
+
`"confidence": number /*0..1*/, "location": string /*file:line*/, ` +
|
|
58
|
+
`"title": string, "detail": string, "suggestion": string}]}`,
|
|
59
|
+
`Order findings by priority then confidence. Omit a finding rather than guess.`,
|
|
60
|
+
``,
|
|
61
|
+
"```" + fence,
|
|
62
|
+
body,
|
|
63
|
+
"```",
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
return [
|
|
67
|
+
`Review the following ${what}${subject} across these dimensions:`,
|
|
68
|
+
dimLines,
|
|
69
|
+
``,
|
|
70
|
+
PRIORITY_GUIDE,
|
|
71
|
+
``,
|
|
72
|
+
`For each finding, give: **[P0-P3]** a short title, the location (file:line), ` +
|
|
73
|
+
`your confidence (low/med/high), what's wrong, and a concrete fix.`,
|
|
74
|
+
`Start with a one-line summary, then list findings ordered by priority. ` +
|
|
75
|
+
`If nothing warrants a finding, say so plainly. Don't pad with nits to look thorough.`,
|
|
76
|
+
``,
|
|
77
|
+
"```" + fence,
|
|
78
|
+
body,
|
|
79
|
+
"```",
|
|
80
|
+
].join("\n");
|
|
81
|
+
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* - Judgment: file writes are artifacts, reads are not
|
|
13
13
|
*/
|
|
14
14
|
import { nanoid } from "nanoid";
|
|
15
|
+
import { parseRedirectTarget } from "./redirect-target.js";
|
|
15
16
|
export class ArtifactTracker {
|
|
16
17
|
config;
|
|
17
18
|
pendingCalls = new Map();
|
|
@@ -111,10 +112,10 @@ export class ArtifactTracker {
|
|
|
111
112
|
await this.config.store.appendArtifactRef(ref);
|
|
112
113
|
return;
|
|
113
114
|
}
|
|
114
|
-
// Redirect output: command > file or command >> file
|
|
115
|
-
const
|
|
116
|
-
if (
|
|
117
|
-
await this.recordFileArtifact(
|
|
115
|
+
// Redirect output: command > file or command >> file (quoted-path aware)
|
|
116
|
+
const redirectTarget = parseRedirectTarget(trimmed);
|
|
117
|
+
if (redirectTarget) {
|
|
118
|
+
await this.recordFileArtifact(redirectTarget, "output", "file");
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
// cp / mv — destination is an artifact
|
|
@@ -9,9 +9,25 @@
|
|
|
9
9
|
* - Return execution result (does NOT manage run state transitions)
|
|
10
10
|
*/
|
|
11
11
|
import { type EngineConfig, type EngineHookConfig } from "../engine/engine.js";
|
|
12
|
-
import type { LLMConfig, RegisteredTool } from "../types.js";
|
|
12
|
+
import type { ClientDefaults, LLMConfig, RegisteredTool } from "../types.js";
|
|
13
13
|
import type { RunSnapshot, RunExecutionContext, RunExecutionResult } from "./types.js";
|
|
14
14
|
import { type RunLifecycleHooks } from "./RunApprovalBackend.js";
|
|
15
|
+
import type { ApprovalBackend } from "../tool-system/permission.js";
|
|
16
|
+
/** Unattended runs (those with an injected approval backend) run headless so
|
|
17
|
+
* the in-process AgentServer does not wire an interactive askUser. Exported
|
|
18
|
+
* for unit testing the decision rule. */
|
|
19
|
+
export declare function buildHeadlessFlag(override: ApprovalBackend | undefined): boolean;
|
|
20
|
+
/** Run-metadata `source` value tagging a run as unattended automation
|
|
21
|
+
* (set by the automation host; read here to decide prompt/headless behavior). */
|
|
22
|
+
export declare const AUTOMATION_RUN_SOURCE = "automation";
|
|
23
|
+
/** Appended to the system prompt for unattended automation runs so the model
|
|
24
|
+
* knows it IS the automation and must not ask the user or offer to schedule
|
|
25
|
+
* automation. English by repo convention; the model answers in the user's
|
|
26
|
+
* language regardless. */
|
|
27
|
+
export declare const AUTOMATION_PROMPT_NOTE: string;
|
|
28
|
+
/** Compose the run's appendSystemPrompt: prepend the automation note when the
|
|
29
|
+
* run is tagged source "automation", preserving any host-provided append. */
|
|
30
|
+
export declare function buildAppendSystemPrompt(hostAppend: string | undefined, metadata: Record<string, unknown> | undefined): string | undefined;
|
|
15
31
|
/**
|
|
16
32
|
* Handles returned from execute() to allow RunManager to resolve
|
|
17
33
|
* pending approvals and user input while Engine is suspended.
|
|
@@ -48,6 +64,8 @@ export interface CustomToolEntry {
|
|
|
48
64
|
}
|
|
49
65
|
export interface EngineRunnerConfig {
|
|
50
66
|
llm: LLMConfig;
|
|
67
|
+
/** Cross-model runtime knobs (temperature/timeout/imageDetail). */
|
|
68
|
+
clientDefaults?: ClientDefaults;
|
|
51
69
|
maxTurns?: number;
|
|
52
70
|
maxContextTokens?: number;
|
|
53
71
|
sessionStorageDir?: string;
|
|
@@ -61,6 +79,14 @@ export interface EngineRunnerConfig {
|
|
|
61
79
|
customTools?: CustomToolEntry[];
|
|
62
80
|
/** Hooks registered into each Engine instance before run execution. */
|
|
63
81
|
hooks?: EngineHookConfig[];
|
|
82
|
+
/**
|
|
83
|
+
* Override the approval backend. When set, the run uses THIS backend instead
|
|
84
|
+
* of the interactive run-aware RunApprovalBackend — used by unattended hosts
|
|
85
|
+
* (e.g. automation/cron) that must auto-decide without a UI, e.g. a
|
|
86
|
+
* HeadlessApprovalBackend("approve-read-only"). When unset, the interactive
|
|
87
|
+
* run-aware backend is used (default REPL/desktop behavior).
|
|
88
|
+
*/
|
|
89
|
+
approvalBackend?: ApprovalBackend;
|
|
64
90
|
}
|
|
65
91
|
export declare class EngineRunner implements RunExecutor {
|
|
66
92
|
private readonly config;
|
package/dist/run/EngineRunner.js
CHANGED
|
@@ -11,6 +11,33 @@
|
|
|
11
11
|
import { Engine } from "../engine/engine.js";
|
|
12
12
|
import { RunApprovalBackend, createRunAskUserFn, } from "./RunApprovalBackend.js";
|
|
13
13
|
import { createInProcessClient } from "../protocol/helpers.js";
|
|
14
|
+
/** Unattended runs (those with an injected approval backend) run headless so
|
|
15
|
+
* the in-process AgentServer does not wire an interactive askUser. Exported
|
|
16
|
+
* for unit testing the decision rule. */
|
|
17
|
+
export function buildHeadlessFlag(override) {
|
|
18
|
+
return override !== undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Run-metadata `source` value tagging a run as unattended automation
|
|
21
|
+
* (set by the automation host; read here to decide prompt/headless behavior). */
|
|
22
|
+
export const AUTOMATION_RUN_SOURCE = "automation";
|
|
23
|
+
/** Appended to the system prompt for unattended automation runs so the model
|
|
24
|
+
* knows it IS the automation and must not ask the user or offer to schedule
|
|
25
|
+
* automation. English by repo convention; the model answers in the user's
|
|
26
|
+
* language regardless. */
|
|
27
|
+
export const AUTOMATION_PROMPT_NOTE = "This is an unattended, scheduled automation run. No human is watching, and " +
|
|
28
|
+
"AskUserQuestion will not reach anyone. You ARE the automation — do not ask " +
|
|
29
|
+
"the user questions and do not offer to set up or schedule automation. " +
|
|
30
|
+
"Produce the requested output directly; when uncertain, state your assumption " +
|
|
31
|
+
"and proceed." +
|
|
32
|
+
" When finished, call UpdateAutomationMemory exactly once with a concise " +
|
|
33
|
+
"summary of this run's key findings/state for the next run.";
|
|
34
|
+
/** Compose the run's appendSystemPrompt: prepend the automation note when the
|
|
35
|
+
* run is tagged source "automation", preserving any host-provided append. */
|
|
36
|
+
export function buildAppendSystemPrompt(hostAppend, metadata) {
|
|
37
|
+
if (metadata?.source !== AUTOMATION_RUN_SOURCE)
|
|
38
|
+
return hostAppend;
|
|
39
|
+
return hostAppend ? `${AUTOMATION_PROMPT_NOTE}\n\n${hostAppend}` : AUTOMATION_PROMPT_NOTE;
|
|
40
|
+
}
|
|
14
41
|
// ─── EngineRunner (built-in RunExecutor) ────────────────────────
|
|
15
42
|
export class EngineRunner {
|
|
16
43
|
config;
|
|
@@ -18,23 +45,30 @@ export class EngineRunner {
|
|
|
18
45
|
this.config = config;
|
|
19
46
|
}
|
|
20
47
|
async execute(run, context, lifecycleHooks, onHandleReady) {
|
|
21
|
-
//
|
|
22
|
-
|
|
48
|
+
// Run-aware approval backend (interactive: suspends the run and waits for
|
|
49
|
+
// RunManager to resolve via the handle). Always constructed so the handle
|
|
50
|
+
// stays well-formed, but only wired into the engine when no override is set.
|
|
51
|
+
const runApprovalBackend = new RunApprovalBackend();
|
|
52
|
+
// Unattended override: a host (automation/cron) can inject a backend that
|
|
53
|
+
// auto-decides (e.g. approve-read-only). When set, the engine uses it and
|
|
54
|
+
// the interactive resolve path is inert (no UI to resolve approvals).
|
|
55
|
+
const override = this.config.approvalBackend;
|
|
56
|
+
const engineApprovalBackend = override ?? runApprovalBackend;
|
|
23
57
|
// Create run-aware askUser adapter
|
|
24
58
|
let resolveInputFn = () => false;
|
|
25
59
|
let hasPendingInputFn = () => false;
|
|
26
60
|
let askUserFn;
|
|
27
|
-
if (lifecycleHooks) {
|
|
28
|
-
|
|
61
|
+
if (lifecycleHooks && !override) {
|
|
62
|
+
runApprovalBackend.setHooks(lifecycleHooks);
|
|
29
63
|
const askAdapter = createRunAskUserFn(lifecycleHooks);
|
|
30
64
|
askUserFn = askAdapter.askUserFn;
|
|
31
65
|
resolveInputFn = askAdapter.resolveInput;
|
|
32
66
|
hasPendingInputFn = askAdapter.hasPendingInput;
|
|
33
67
|
}
|
|
34
68
|
const handle = {
|
|
35
|
-
resolveApproval: (approved, reason) =>
|
|
69
|
+
resolveApproval: (approved, reason) => runApprovalBackend.resolveApproval(approved ? { approved: true } : { approved: false, reason }),
|
|
36
70
|
resolveInput: resolveInputFn,
|
|
37
|
-
hasPendingApproval: () =>
|
|
71
|
+
hasPendingApproval: () => runApprovalBackend.hasPendingApproval(),
|
|
38
72
|
hasPendingInput: hasPendingInputFn,
|
|
39
73
|
};
|
|
40
74
|
// Expose handle immediately so RunManager can resolve approvals/input
|
|
@@ -42,19 +76,23 @@ export class EngineRunner {
|
|
|
42
76
|
onHandleReady?.(handle);
|
|
43
77
|
const engineConfig = {
|
|
44
78
|
llm: this.config.llm,
|
|
79
|
+
clientDefaults: this.config.clientDefaults,
|
|
45
80
|
cwd: run.cwd,
|
|
46
81
|
maxTurns: this.config.maxTurns ?? 30,
|
|
47
82
|
maxContextTokens: this.config.maxContextTokens ?? 200_000,
|
|
48
83
|
permissionMode: this.config.permissionMode ?? "acceptEdits",
|
|
84
|
+
headless: buildHeadlessFlag(override),
|
|
49
85
|
preset: run.preset,
|
|
50
86
|
enabledBuiltinTools: this.config.enabledBuiltinTools,
|
|
51
87
|
disabledBuiltinTools: this.config.disabledBuiltinTools,
|
|
52
88
|
customSystemPrompt: this.config.customSystemPrompt,
|
|
53
|
-
|
|
89
|
+
// NOTE: callers must not pass appendSystemPrompt in engineConfigOverrides
|
|
90
|
+
// below, or it will clobber this composed (automation note + host) value.
|
|
91
|
+
appendSystemPrompt: buildAppendSystemPrompt(this.config.appendSystemPrompt, run.metadata),
|
|
54
92
|
sessionStorageDir: this.config.sessionStorageDir,
|
|
55
93
|
mcpServers: this.config.mcpServers,
|
|
56
94
|
hooks: this.config.hooks,
|
|
57
|
-
approvalBackend,
|
|
95
|
+
approvalBackend: engineApprovalBackend,
|
|
58
96
|
askUser: askUserFn,
|
|
59
97
|
...context.engineConfigOverrides,
|
|
60
98
|
};
|
package/dist/run/FileRunStore.js
CHANGED
|
@@ -32,9 +32,16 @@ export class FileRunStore {
|
|
|
32
32
|
}
|
|
33
33
|
writeJson(filePath, data) {
|
|
34
34
|
const tmp = filePath + ".tmp";
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
try {
|
|
36
|
+
writeFileSync(tmp, JSON.stringify(data, null, 2), "utf-8");
|
|
37
|
+
// Atomic rename — prevents partial writes on crash
|
|
38
|
+
renameSync(tmp, filePath);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// Don't leave a dangling .tmp behind on a failed write/rename.
|
|
42
|
+
rmSync(tmp, { force: true });
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
38
45
|
}
|
|
39
46
|
readJson(filePath) {
|
|
40
47
|
if (!existsSync(filePath))
|
|
@@ -44,13 +51,30 @@ export class FileRunStore {
|
|
|
44
51
|
/** Serializes concurrent JSONL appends per file path. */
|
|
45
52
|
appendLocks = new Map();
|
|
46
53
|
async appendJsonl(filePath, data) {
|
|
47
|
-
// Serialize writes to the same file to prevent interleaved output
|
|
54
|
+
// Serialize writes to the same file to prevent interleaved output. The
|
|
55
|
+
// chain we STORE as the lock must never reject — otherwise a single failed
|
|
56
|
+
// write poisons the lock and every later write chains off the rejected
|
|
57
|
+
// promise, skips its callback, and fails forever. So sequence off the
|
|
58
|
+
// previous lock's settlement (.catch(()=>{})), do the write, and surface
|
|
59
|
+
// this write's own error to *this* caller via a separate promise.
|
|
48
60
|
const prev = this.appendLocks.get(filePath) ?? Promise.resolve();
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
let settle;
|
|
62
|
+
const lock = new Promise((resolve) => {
|
|
63
|
+
settle = resolve;
|
|
51
64
|
});
|
|
52
|
-
this.appendLocks.set(filePath,
|
|
53
|
-
|
|
65
|
+
this.appendLocks.set(filePath, lock);
|
|
66
|
+
try {
|
|
67
|
+
await prev.catch(() => { });
|
|
68
|
+
appendFileSync(filePath, JSON.stringify(data) + "\n", "utf-8");
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
// Release the lock for the next writer regardless of success/failure,
|
|
72
|
+
// and drop the map entry if no newer writer has queued behind us.
|
|
73
|
+
settle();
|
|
74
|
+
if (this.appendLocks.get(filePath) === lock) {
|
|
75
|
+
this.appendLocks.delete(filePath);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
54
78
|
}
|
|
55
79
|
readJsonl(filePath) {
|
|
56
80
|
if (!existsSync(filePath))
|
|
@@ -102,9 +126,14 @@ export class FileRunStore {
|
|
|
102
126
|
}
|
|
103
127
|
// Sort by createdAt descending (newest first)
|
|
104
128
|
snapshots.sort((a, b) => b.createdAt - a.createdAt);
|
|
105
|
-
// Pagination
|
|
106
|
-
|
|
107
|
-
|
|
129
|
+
// Pagination. Clamp to sane bounds before slicing: a negative offset would
|
|
130
|
+
// make Array.slice count "from the end" and silently return a surprise tail
|
|
131
|
+
// window; a negative limit would drop elements off the end. Both nonsensical
|
|
132
|
+
// for pagination — clamp offset≥0, treat a non-positive limit as an empty page.
|
|
133
|
+
const rawOffset = query?.offset ?? 0;
|
|
134
|
+
const rawLimit = query?.limit ?? 50;
|
|
135
|
+
const offset = Number.isFinite(rawOffset) && rawOffset > 0 ? Math.floor(rawOffset) : 0;
|
|
136
|
+
const limit = Number.isFinite(rawLimit) && rawLimit > 0 ? Math.floor(rawLimit) : 0;
|
|
108
137
|
return snapshots.slice(offset, offset + limit);
|
|
109
138
|
}
|
|
110
139
|
async delete(runId) {
|
|
@@ -24,8 +24,15 @@ export class RunApprovalBackend {
|
|
|
24
24
|
}
|
|
25
25
|
async requestApproval(request) {
|
|
26
26
|
if (!this.hooks) {
|
|
27
|
-
// No hooks wired —
|
|
28
|
-
|
|
27
|
+
// No hooks wired — fail CLOSED. This backend is the engine's approval
|
|
28
|
+
// path for an interactive run; if a host forgot to setHooks() there is
|
|
29
|
+
// no UI to ask, so auto-approving every tool (the old behavior) silently
|
|
30
|
+
// bypassed all approval. Denying is the safe default — a misconfigured
|
|
31
|
+
// run refuses tools instead of running `rm -rf /` unattended. (§5.6 #15)
|
|
32
|
+
return {
|
|
33
|
+
approved: false,
|
|
34
|
+
reason: "run approval backend has no lifecycle hooks wired (denied fail-closed)",
|
|
35
|
+
};
|
|
29
36
|
}
|
|
30
37
|
// Notify RunManager that approval is needed
|
|
31
38
|
const { approvalId } = await this.hooks.onApprovalNeeded(request);
|
|
@@ -64,12 +71,25 @@ export class RunApprovalBackend {
|
|
|
64
71
|
*/
|
|
65
72
|
export function createRunAskUserFn(hooks) {
|
|
66
73
|
let pending = null;
|
|
74
|
+
const supersedePending = () => {
|
|
75
|
+
// A run suspends on a single input at a time (RunManager resolves via one
|
|
76
|
+
// handle). If a second ask arrives while one is still pending, the old
|
|
77
|
+
// code overwrote the slot and the first promise hung forever. Reject the
|
|
78
|
+
// prior one so its awaiter unblocks instead of leaking. (§5.6 #15)
|
|
79
|
+
if (pending) {
|
|
80
|
+
pending.reject(new Error("superseded: a newer AskUser request replaced this one before it was answered"));
|
|
81
|
+
pending = null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
67
84
|
const askUserFn = async (question) => {
|
|
68
85
|
// Notify RunManager
|
|
69
86
|
await hooks.onInputNeeded(question);
|
|
70
|
-
// Suspend execution until user provides input
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
// Suspend execution until user provides input. The supersede check runs
|
|
88
|
+
// here — AFTER the await — so it sees a `pending` set by an earlier ask
|
|
89
|
+
// whose own await already resolved, rather than racing the assignment.
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
supersedePending();
|
|
92
|
+
pending = { resolve, reject, question };
|
|
73
93
|
});
|
|
74
94
|
};
|
|
75
95
|
const resolveInput = (answer) => {
|
package/dist/run/RunLock.d.ts
CHANGED
|
@@ -10,16 +10,42 @@ export interface RunLockConfig {
|
|
|
10
10
|
runsDir?: string;
|
|
11
11
|
/** Stale lock timeout in ms. Default: 60_000 (1 minute) */
|
|
12
12
|
staleMs?: number;
|
|
13
|
+
/** How long to wait for runs/<id>/run.json to appear before failing. */
|
|
14
|
+
targetWaitMs?: number;
|
|
15
|
+
/** Poll interval while waiting for the lock target file. */
|
|
16
|
+
targetPollMs?: number;
|
|
13
17
|
}
|
|
18
|
+
export type RunLockAcquireResult = {
|
|
19
|
+
acquired: true;
|
|
20
|
+
} | {
|
|
21
|
+
acquired: false;
|
|
22
|
+
reason: "missing_target" | "locked";
|
|
23
|
+
message?: string;
|
|
24
|
+
code?: string;
|
|
25
|
+
};
|
|
14
26
|
export declare class RunLock {
|
|
15
27
|
private readonly runsDir;
|
|
16
28
|
private readonly staleMs;
|
|
29
|
+
private readonly targetWaitMs;
|
|
30
|
+
private readonly targetPollMs;
|
|
17
31
|
private readonly releaseFns;
|
|
18
32
|
constructor(config?: RunLockConfig);
|
|
19
33
|
/**
|
|
20
|
-
* Acquire a lock for a run.
|
|
34
|
+
* Acquire a lock for a run. Missing target and held-lock failures are
|
|
35
|
+
* intentionally distinct so callers don't silently abandon a run as "locked"
|
|
36
|
+
* when the real issue is a bad/mismatched run store path.
|
|
37
|
+
*
|
|
38
|
+
* Race note: if the queue reaches acquire() before the file is visible, a
|
|
39
|
+
* short wait bridges that gap. Only a proper-lockfile conflict is "locked".
|
|
21
40
|
*/
|
|
22
|
-
acquire(runId: string): Promise<
|
|
41
|
+
acquire(runId: string): Promise<RunLockAcquireResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Wait (up to ~targetWaitMs) for the lock target file to exist, polling on a
|
|
44
|
+
* short interval. Returns true once present, false if it never appears
|
|
45
|
+
* within the window. Bridges the submit→executeRun create race without
|
|
46
|
+
* blocking meaningfully when the file is already there (first check hits).
|
|
47
|
+
*/
|
|
48
|
+
private waitForTarget;
|
|
23
49
|
/**
|
|
24
50
|
* Release the lock for a run.
|
|
25
51
|
*/
|