@cjhyy/code-shell-core 0.5.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/agent/coordinator.d.ts +49 -0
- package/dist/agent/coordinator.js +77 -0
- package/dist/arena/arena.d.ts +43 -0
- package/dist/arena/arena.js +334 -0
- package/dist/arena/context/context-tools.d.ts +16 -0
- package/dist/arena/context/context-tools.js +231 -0
- package/dist/arena/detect-mode.d.ts +20 -0
- package/dist/arena/detect-mode.js +78 -0
- package/dist/arena/digest-builder.d.ts +25 -0
- package/dist/arena/digest-builder.js +120 -0
- package/dist/arena/index.d.ts +29 -0
- package/dist/arena/index.js +29 -0
- package/dist/arena/iterate/convergence.d.ts +25 -0
- package/dist/arena/iterate/convergence.js +103 -0
- package/dist/arena/iterate/formats/index.d.ts +22 -0
- package/dist/arena/iterate/formats/index.js +283 -0
- package/dist/arena/iterate/index.d.ts +11 -0
- package/dist/arena/iterate/index.js +9 -0
- package/dist/arena/iterate/iterative-arena.d.ts +23 -0
- package/dist/arena/iterate/iterative-arena.js +237 -0
- package/dist/arena/iterate/parse.d.ts +42 -0
- package/dist/arena/iterate/parse.js +123 -0
- package/dist/arena/iterate/phases/argue.d.ts +22 -0
- package/dist/arena/iterate/phases/argue.js +159 -0
- package/dist/arena/iterate/phases/revise.d.ts +16 -0
- package/dist/arena/iterate/phases/revise.js +62 -0
- package/dist/arena/iterate/phases/tournament.d.ts +34 -0
- package/dist/arena/iterate/phases/tournament.js +113 -0
- package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
- package/dist/arena/iterate/tools/web-tools.js +54 -0
- package/dist/arena/iterate/types.d.ts +152 -0
- package/dist/arena/iterate/types.js +8 -0
- package/dist/arena/ledger.d.ts +47 -0
- package/dist/arena/ledger.js +151 -0
- package/dist/arena/lenses/architecture.d.ts +5 -0
- package/dist/arena/lenses/architecture.js +22 -0
- package/dist/arena/lenses/engineering.d.ts +5 -0
- package/dist/arena/lenses/engineering.js +22 -0
- package/dist/arena/lenses/general.d.ts +5 -0
- package/dist/arena/lenses/general.js +20 -0
- package/dist/arena/lenses/index.d.ts +16 -0
- package/dist/arena/lenses/index.js +47 -0
- package/dist/arena/lenses/product.d.ts +5 -0
- package/dist/arena/lenses/product.js +22 -0
- package/dist/arena/model-presets.d.ts +23 -0
- package/dist/arena/model-presets.js +44 -0
- package/dist/arena/phases/adjudication.d.ts +24 -0
- package/dist/arena/phases/adjudication.js +144 -0
- package/dist/arena/phases/build-consensus.d.ts +29 -0
- package/dist/arena/phases/build-consensus.js +86 -0
- package/dist/arena/phases/claim-registry.d.ts +26 -0
- package/dist/arena/phases/claim-registry.js +60 -0
- package/dist/arena/phases/cross-review.d.ts +45 -0
- package/dist/arena/phases/cross-review.js +224 -0
- package/dist/arena/phases/debate-rounds.d.ts +27 -0
- package/dist/arena/phases/debate-rounds.js +162 -0
- package/dist/arena/phases/participant-research.d.ts +38 -0
- package/dist/arena/phases/participant-research.js +317 -0
- package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
- package/dist/arena/phases/planning-detail-expansion.js +121 -0
- package/dist/arena/planner.d.ts +27 -0
- package/dist/arena/planner.js +312 -0
- package/dist/arena/providers/docs.d.ts +6 -0
- package/dist/arena/providers/docs.js +108 -0
- package/dist/arena/providers/git.d.ts +8 -0
- package/dist/arena/providers/git.js +174 -0
- package/dist/arena/providers/index.d.ts +32 -0
- package/dist/arena/providers/index.js +132 -0
- package/dist/arena/providers/none.d.ts +7 -0
- package/dist/arena/providers/none.js +11 -0
- package/dist/arena/providers/repo.d.ts +6 -0
- package/dist/arena/providers/repo.js +255 -0
- package/dist/arena/render/session.d.ts +17 -0
- package/dist/arena/render/session.js +190 -0
- package/dist/arena/render/terminal.d.ts +34 -0
- package/dist/arena/render/terminal.js +286 -0
- package/dist/arena/strategies/discussion.d.ts +25 -0
- package/dist/arena/strategies/discussion.js +143 -0
- package/dist/arena/strategies/index.d.ts +15 -0
- package/dist/arena/strategies/index.js +28 -0
- package/dist/arena/strategies/language-wrapper.d.ts +17 -0
- package/dist/arena/strategies/language-wrapper.js +102 -0
- package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
- package/dist/arena/strategies/lens-wrapper.js +236 -0
- package/dist/arena/strategies/planning.d.ts +30 -0
- package/dist/arena/strategies/planning.js +225 -0
- package/dist/arena/strategies/review.d.ts +26 -0
- package/dist/arena/strategies/review.js +168 -0
- package/dist/arena/strategies/utils.d.ts +39 -0
- package/dist/arena/strategies/utils.js +647 -0
- package/dist/arena/tools/selector.d.ts +17 -0
- package/dist/arena/tools/selector.js +61 -0
- package/dist/arena/transitions.d.ts +48 -0
- package/dist/arena/transitions.js +92 -0
- package/dist/arena/types.d.ts +508 -0
- package/dist/arena/types.js +27 -0
- package/dist/cli/agent-server-stdio.d.ts +32 -0
- package/dist/cli/agent-server-stdio.js +116 -0
- package/dist/colorizer.d.ts +23 -0
- package/dist/colorizer.js +12 -0
- package/dist/context/compaction.d.ts +116 -0
- package/dist/context/compaction.js +534 -0
- package/dist/context/manager.d.ts +145 -0
- package/dist/context/manager.js +423 -0
- package/dist/context/token-counter.d.ts +27 -0
- package/dist/context/token-counter.js +91 -0
- package/dist/context/tool-result-storage.d.ts +96 -0
- package/dist/context/tool-result-storage.js +296 -0
- package/dist/cost-tracker.d.ts +64 -0
- package/dist/cost-tracker.js +314 -0
- package/dist/cron/scheduler.d.ts +34 -0
- package/dist/cron/scheduler.js +115 -0
- package/dist/data/deepseek-models.json +46 -0
- package/dist/data/gemini-models.json +67 -0
- package/dist/data/openai-models.json +175 -0
- package/dist/data/openrouter-models.d.ts +35 -0
- package/dist/data/openrouter-models.js +36 -0
- package/dist/data/openrouter-models.json +4626 -0
- package/dist/data/openrouter-sync.d.ts +16 -0
- package/dist/data/openrouter-sync.js +53 -0
- package/dist/data/static-catalogs.d.ts +25 -0
- package/dist/data/static-catalogs.js +26 -0
- package/dist/data/zai-models.json +56 -0
- package/dist/engine/cost-store.d.ts +22 -0
- package/dist/engine/cost-store.js +15 -0
- package/dist/engine/engine.d.ts +295 -0
- package/dist/engine/engine.js +1467 -0
- package/dist/engine/model-facade.d.ts +24 -0
- package/dist/engine/model-facade.js +194 -0
- package/dist/engine/parse-task.d.ts +59 -0
- package/dist/engine/parse-task.js +135 -0
- package/dist/engine/patch-orphaned-tools.d.ts +52 -0
- package/dist/engine/patch-orphaned-tools.js +95 -0
- package/dist/engine/query.d.ts +50 -0
- package/dist/engine/query.js +107 -0
- package/dist/engine/runtime.d.ts +50 -0
- package/dist/engine/runtime.js +59 -0
- package/dist/engine/streaming-tool-queue.d.ts +34 -0
- package/dist/engine/streaming-tool-queue.js +61 -0
- package/dist/engine/token-budget.d.ts +22 -0
- package/dist/engine/token-budget.js +40 -0
- package/dist/engine/tool-summary.d.ts +13 -0
- package/dist/engine/tool-summary.js +35 -0
- package/dist/engine/turn-loop.d.ts +122 -0
- package/dist/engine/turn-loop.js +602 -0
- package/dist/engine/turn-state.d.ts +20 -0
- package/dist/engine/turn-state.js +17 -0
- package/dist/exceptions.d.ts +61 -0
- package/dist/exceptions.js +116 -0
- package/dist/git/utils.d.ts +35 -0
- package/dist/git/utils.js +98 -0
- package/dist/git/worktree.d.ts +36 -0
- package/dist/git/worktree.js +139 -0
- package/dist/hooks/events.d.ts +114 -0
- package/dist/hooks/events.js +4 -0
- package/dist/hooks/inject.d.ts +19 -0
- package/dist/hooks/inject.js +29 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +84 -0
- package/dist/hooks/shell-runner.d.ts +45 -0
- package/dist/hooks/shell-runner.js +173 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.js +145 -0
- package/dist/llm/api-key-sanitize.d.ts +22 -0
- package/dist/llm/api-key-sanitize.js +81 -0
- package/dist/llm/capabilities/index.d.ts +20 -0
- package/dist/llm/capabilities/index.js +39 -0
- package/dist/llm/capabilities/rules.d.ts +26 -0
- package/dist/llm/capabilities/rules.js +215 -0
- package/dist/llm/capabilities/types.d.ts +114 -0
- package/dist/llm/capabilities/types.js +24 -0
- package/dist/llm/client-base.d.ts +29 -0
- package/dist/llm/client-base.js +137 -0
- package/dist/llm/client-factory.d.ts +10 -0
- package/dist/llm/client-factory.js +29 -0
- package/dist/llm/model-cache.d.ts +21 -0
- package/dist/llm/model-cache.js +46 -0
- package/dist/llm/model-fetcher.d.ts +29 -0
- package/dist/llm/model-fetcher.js +282 -0
- package/dist/llm/model-pool.d.ts +95 -0
- package/dist/llm/model-pool.js +246 -0
- package/dist/llm/provider-catalog.d.ts +32 -0
- package/dist/llm/provider-catalog.js +50 -0
- package/dist/llm/provider-kinds.d.ts +21 -0
- package/dist/llm/provider-kinds.js +132 -0
- package/dist/llm/providers/anthropic.d.ts +19 -0
- package/dist/llm/providers/anthropic.js +267 -0
- package/dist/llm/providers/openai.d.ts +64 -0
- package/dist/llm/providers/openai.js +606 -0
- package/dist/llm/retry.d.ts +12 -0
- package/dist/llm/retry.js +17 -0
- package/dist/llm/stream-watchdog.d.ts +42 -0
- package/dist/llm/stream-watchdog.js +70 -0
- package/dist/llm/token-counter.d.ts +17 -0
- package/dist/llm/token-counter.js +36 -0
- package/dist/llm/types.d.ts +37 -0
- package/dist/llm/types.js +4 -0
- package/dist/logging/logger.d.ts +109 -0
- package/dist/logging/logger.js +390 -0
- package/dist/logging/sanitize-messages.d.ts +42 -0
- package/dist/logging/sanitize-messages.js +150 -0
- package/dist/logging/session-recorder.d.ts +90 -0
- package/dist/logging/session-recorder.js +304 -0
- package/dist/lsp/client.d.ts +41 -0
- package/dist/lsp/client.js +166 -0
- package/dist/lsp/manager.d.ts +40 -0
- package/dist/lsp/manager.js +124 -0
- package/dist/lsp/servers.d.ts +16 -0
- package/dist/lsp/servers.js +60 -0
- package/dist/migrate-models.d.ts +45 -0
- package/dist/migrate-models.js +179 -0
- package/dist/onboarding.d.ts +189 -0
- package/dist/onboarding.js +625 -0
- package/dist/plugins/gitOps.d.ts +32 -0
- package/dist/plugins/gitOps.js +62 -0
- package/dist/plugins/installedPlugins.d.ts +15 -0
- package/dist/plugins/installedPlugins.js +56 -0
- package/dist/plugins/knownMarketplaces.d.ts +10 -0
- package/dist/plugins/knownMarketplaces.js +46 -0
- package/dist/plugins/loadPluginHooks.d.ts +52 -0
- package/dist/plugins/loadPluginHooks.js +162 -0
- package/dist/plugins/marketplaceManager.d.ts +49 -0
- package/dist/plugins/marketplaceManager.js +142 -0
- package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
- package/dist/plugins/parseMarketplaceInput.js +73 -0
- package/dist/plugins/pluginCommandHook.d.ts +54 -0
- package/dist/plugins/pluginCommandHook.js +180 -0
- package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
- package/dist/plugins/pluginCommandsLoader.js +114 -0
- package/dist/plugins/pluginInstaller.d.ts +36 -0
- package/dist/plugins/pluginInstaller.js +228 -0
- package/dist/plugins/schemas.d.ts +9 -0
- package/dist/plugins/schemas.js +136 -0
- package/dist/plugins/types.d.ts +75 -0
- package/dist/plugins/types.js +7 -0
- package/dist/plugins/varRewrite.d.ts +42 -0
- package/dist/plugins/varRewrite.js +129 -0
- package/dist/preset/index.d.ts +60 -0
- package/dist/preset/index.js +159 -0
- package/dist/product/define.d.ts +60 -0
- package/dist/product/define.js +123 -0
- package/dist/product/index.d.ts +5 -0
- package/dist/product/index.js +4 -0
- package/dist/product/types.d.ts +111 -0
- package/dist/product/types.js +21 -0
- package/dist/prompt/composer.d.ts +49 -0
- package/dist/prompt/composer.js +168 -0
- package/dist/prompt/instruction-scanner.d.ts +54 -0
- package/dist/prompt/instruction-scanner.js +187 -0
- package/dist/prompt/section-cache.d.ts +15 -0
- package/dist/prompt/section-cache.js +31 -0
- package/dist/prompt/section-loader.d.ts +26 -0
- package/dist/prompt/section-loader.js +53 -0
- package/dist/prompt/sections/base.md +35 -0
- package/dist/prompt/sections/coding.md +31 -0
- package/dist/prompt/sections/orchestration.md +16 -0
- package/dist/prompt/sections/tone.md +9 -0
- package/dist/protocol/chat-session-manager.d.ts +33 -0
- package/dist/protocol/chat-session-manager.js +65 -0
- package/dist/protocol/chat-session.d.ts +49 -0
- package/dist/protocol/chat-session.js +86 -0
- package/dist/protocol/client.d.ts +104 -0
- package/dist/protocol/client.js +260 -0
- package/dist/protocol/factories.d.ts +93 -0
- package/dist/protocol/factories.js +64 -0
- package/dist/protocol/helpers.d.ts +42 -0
- package/dist/protocol/helpers.js +55 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/server.d.ts +80 -0
- package/dist/protocol/server.js +855 -0
- package/dist/protocol/transport.d.ts +37 -0
- package/dist/protocol/transport.js +85 -0
- package/dist/protocol/types.d.ts +221 -0
- package/dist/protocol/types.js +61 -0
- package/dist/remote/bridge.d.ts +37 -0
- package/dist/remote/bridge.js +103 -0
- package/dist/run/ArtifactTracker.d.ts +38 -0
- package/dist/run/ArtifactTracker.js +132 -0
- package/dist/run/CheckpointWriter.d.ts +53 -0
- package/dist/run/CheckpointWriter.js +135 -0
- package/dist/run/EngineRunner.d.ts +72 -0
- package/dist/run/EngineRunner.js +119 -0
- package/dist/run/Evaluator.d.ts +56 -0
- package/dist/run/Evaluator.js +62 -0
- package/dist/run/FileRunStore.d.ts +39 -0
- package/dist/run/FileRunStore.js +176 -0
- package/dist/run/Heartbeat.d.ts +54 -0
- package/dist/run/Heartbeat.js +123 -0
- package/dist/run/RunApprovalBackend.d.ts +53 -0
- package/dist/run/RunApprovalBackend.js +85 -0
- package/dist/run/RunLock.d.ts +40 -0
- package/dist/run/RunLock.js +98 -0
- package/dist/run/RunManager.d.ts +82 -0
- package/dist/run/RunManager.js +587 -0
- package/dist/run/RunQueue.d.ts +27 -0
- package/dist/run/RunQueue.js +73 -0
- package/dist/run/RunStore.d.ts +25 -0
- package/dist/run/RunStore.js +9 -0
- package/dist/run/factory.d.ts +63 -0
- package/dist/run/factory.js +51 -0
- package/dist/run/index.d.ts +17 -0
- package/dist/run/index.js +23 -0
- package/dist/run/types.d.ts +136 -0
- package/dist/run/types.js +28 -0
- package/dist/runtime/safe-spawn.d.ts +118 -0
- package/dist/runtime/safe-spawn.js +268 -0
- package/dist/services/analytics.d.ts +29 -0
- package/dist/services/analytics.js +84 -0
- package/dist/services/auto-dream.d.ts +49 -0
- package/dist/services/auto-dream.js +124 -0
- package/dist/services/diagnostics.d.ts +41 -0
- package/dist/services/diagnostics.js +99 -0
- package/dist/services/extract-memories.d.ts +31 -0
- package/dist/services/extract-memories.js +71 -0
- package/dist/services/index.d.ts +11 -0
- package/dist/services/index.js +17 -0
- package/dist/services/memory-orchestrator.d.ts +60 -0
- package/dist/services/memory-orchestrator.js +133 -0
- package/dist/services/notifier.d.ts +25 -0
- package/dist/services/notifier.js +69 -0
- package/dist/services/oauth.d.ts +27 -0
- package/dist/services/oauth.js +153 -0
- package/dist/services/session-memory.d.ts +37 -0
- package/dist/services/session-memory.js +81 -0
- package/dist/session/file-history.d.ts +41 -0
- package/dist/session/file-history.js +115 -0
- package/dist/session/memory.d.ts +104 -0
- package/dist/session/memory.js +310 -0
- package/dist/session/session-manager.d.ts +41 -0
- package/dist/session/session-manager.js +261 -0
- package/dist/session/transcript.d.ts +39 -0
- package/dist/session/transcript.js +186 -0
- package/dist/settings/manager.d.ts +36 -0
- package/dist/settings/manager.js +187 -0
- package/dist/settings/schema.d.ts +1219 -0
- package/dist/settings/schema.js +246 -0
- package/dist/skills/frontmatter.d.ts +13 -0
- package/dist/skills/frontmatter.js +70 -0
- package/dist/skills/index.d.ts +7 -0
- package/dist/skills/index.js +6 -0
- package/dist/skills/scanner.d.ts +31 -0
- package/dist/skills/scanner.js +171 -0
- package/dist/state.d.ts +160 -0
- package/dist/state.js +267 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
- package/dist/tool-system/builtin/agent-notifications.js +197 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
- package/dist/tool-system/builtin/agent-registry.js +126 -0
- package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
- package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
- package/dist/tool-system/builtin/agent.d.ts +16 -0
- package/dist/tool-system/builtin/agent.js +364 -0
- package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
- package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
- package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
- package/dist/tool-system/builtin/apply-patch/index.js +101 -0
- package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
- package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
- package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
- package/dist/tool-system/builtin/apply-patch/types.js +13 -0
- package/dist/tool-system/builtin/arena.d.ts +31 -0
- package/dist/tool-system/builtin/arena.js +416 -0
- package/dist/tool-system/builtin/ask-user.d.ts +20 -0
- package/dist/tool-system/builtin/ask-user.js +99 -0
- package/dist/tool-system/builtin/bash.d.ts +21 -0
- package/dist/tool-system/builtin/bash.js +149 -0
- package/dist/tool-system/builtin/brief.d.ts +6 -0
- package/dist/tool-system/builtin/brief.js +41 -0
- package/dist/tool-system/builtin/config.d.ts +6 -0
- package/dist/tool-system/builtin/config.js +67 -0
- package/dist/tool-system/builtin/cron.d.ts +10 -0
- package/dist/tool-system/builtin/cron.js +61 -0
- package/dist/tool-system/builtin/edit.d.ts +6 -0
- package/dist/tool-system/builtin/edit.js +100 -0
- package/dist/tool-system/builtin/file-cache.d.ts +11 -0
- package/dist/tool-system/builtin/file-cache.js +39 -0
- package/dist/tool-system/builtin/glob.d.ts +7 -0
- package/dist/tool-system/builtin/glob.js +76 -0
- package/dist/tool-system/builtin/grep.d.ts +7 -0
- package/dist/tool-system/builtin/grep.js +150 -0
- package/dist/tool-system/builtin/index.d.ts +20 -0
- package/dist/tool-system/builtin/index.js +449 -0
- package/dist/tool-system/builtin/lsp.d.ts +6 -0
- package/dist/tool-system/builtin/lsp.js +141 -0
- package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
- package/dist/tool-system/builtin/mcp-tools.js +102 -0
- package/dist/tool-system/builtin/memory.d.ts +26 -0
- package/dist/tool-system/builtin/memory.js +226 -0
- package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
- package/dist/tool-system/builtin/notebook-edit.js +124 -0
- package/dist/tool-system/builtin/plan.d.ts +15 -0
- package/dist/tool-system/builtin/plan.js +55 -0
- package/dist/tool-system/builtin/powershell.d.ts +11 -0
- package/dist/tool-system/builtin/powershell.js +64 -0
- package/dist/tool-system/builtin/read.d.ts +6 -0
- package/dist/tool-system/builtin/read.js +70 -0
- package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
- package/dist/tool-system/builtin/remote-trigger.js +54 -0
- package/dist/tool-system/builtin/repl.d.ts +11 -0
- package/dist/tool-system/builtin/repl.js +82 -0
- package/dist/tool-system/builtin/send-message.d.ts +6 -0
- package/dist/tool-system/builtin/send-message.js +47 -0
- package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
- package/dist/tool-system/builtin/skill-prompt.js +52 -0
- package/dist/tool-system/builtin/skill.d.ts +9 -0
- package/dist/tool-system/builtin/skill.js +55 -0
- package/dist/tool-system/builtin/sleep.d.ts +6 -0
- package/dist/tool-system/builtin/sleep.js +33 -0
- package/dist/tool-system/builtin/task.d.ts +48 -0
- package/dist/tool-system/builtin/task.js +139 -0
- package/dist/tool-system/builtin/tool-search.d.ts +11 -0
- package/dist/tool-system/builtin/tool-search.js +90 -0
- package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
- package/dist/tool-system/builtin/web-fetch.js +328 -0
- package/dist/tool-system/builtin/web-search.d.ts +25 -0
- package/dist/tool-system/builtin/web-search.js +174 -0
- package/dist/tool-system/builtin/worktree.d.ts +10 -0
- package/dist/tool-system/builtin/worktree.js +95 -0
- package/dist/tool-system/builtin/write.d.ts +6 -0
- package/dist/tool-system/builtin/write.js +36 -0
- package/dist/tool-system/context.d.ts +165 -0
- package/dist/tool-system/context.js +18 -0
- package/dist/tool-system/executor.d.ts +49 -0
- package/dist/tool-system/executor.js +495 -0
- package/dist/tool-system/investigation-guard.d.ts +46 -0
- package/dist/tool-system/investigation-guard.js +155 -0
- package/dist/tool-system/mcp-manager.d.ts +67 -0
- package/dist/tool-system/mcp-manager.js +249 -0
- package/dist/tool-system/permission.d.ts +111 -0
- package/dist/tool-system/permission.js +774 -0
- package/dist/tool-system/registry.d.ts +32 -0
- package/dist/tool-system/registry.js +131 -0
- package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
- package/dist/tool-system/sandbox/bwrap.js +63 -0
- package/dist/tool-system/sandbox/index.d.ts +78 -0
- package/dist/tool-system/sandbox/index.js +222 -0
- package/dist/tool-system/sandbox/off.d.ts +2 -0
- package/dist/tool-system/sandbox/off.js +8 -0
- package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
- package/dist/tool-system/sandbox/seatbelt.js +109 -0
- package/dist/tool-system/task-guard.d.ts +29 -0
- package/dist/tool-system/task-guard.js +70 -0
- package/dist/tool-system/validation.d.ts +5 -0
- package/dist/tool-system/validation.js +39 -0
- package/dist/types.d.ts +376 -0
- package/dist/types.js +4 -0
- package/dist/updater.d.ts +65 -0
- package/dist/updater.js +405 -0
- package/dist/utils/debug.d.ts +41 -0
- package/dist/utils/debug.js +110 -0
- package/dist/utils/earlyInput.d.ts +43 -0
- package/dist/utils/earlyInput.js +166 -0
- package/dist/utils/env.d.ts +24 -0
- package/dist/utils/env.js +104 -0
- package/dist/utils/envUtils.d.ts +51 -0
- package/dist/utils/envUtils.js +135 -0
- package/dist/utils/execFileNoThrow.d.ts +39 -0
- package/dist/utils/execFileNoThrow.js +74 -0
- package/dist/utils/format.d.ts +44 -0
- package/dist/utils/format.js +236 -0
- package/dist/utils/intl.d.ts +22 -0
- package/dist/utils/intl.js +83 -0
- package/dist/utils/lockfile.d.ts +15 -0
- package/dist/utils/lockfile.js +30 -0
- package/dist/utils/memoize.d.ts +19 -0
- package/dist/utils/memoize.js +14 -0
- package/dist/utils/semver.d.ts +6 -0
- package/dist/utils/semver.js +13 -0
- package/dist/utils/sliceAnsi.d.ts +12 -0
- package/dist/utils/sliceAnsi.js +62 -0
- package/dist/utils/systemTheme.d.ts +40 -0
- package/dist/utils/systemTheme.js +108 -0
- package/dist/utils/task-sanitizer.d.ts +6 -0
- package/dist/utils/task-sanitizer.js +24 -0
- package/dist/utils/theme.d.ts +93 -0
- package/dist/utils/theme.js +544 -0
- package/dist/utils/toolDisplay.d.ts +31 -0
- package/dist/utils/toolDisplay.js +188 -0
- package/package.json +72 -0
|
@@ -0,0 +1,855 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentServer — wraps ChatSessionManager and exposes it over the protocol.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Handles RPC requests from the client (run, approve, cancel, configure, query)
|
|
6
|
+
* - Forwards StreamEvents to the client as notifications with sessionId envelope
|
|
7
|
+
* - Manages per-session approval flow
|
|
8
|
+
* - Dispatches agent/run through ChatSessionManager so multiple sessions
|
|
9
|
+
* run concurrently without cross-talk
|
|
10
|
+
*
|
|
11
|
+
* Backward compat: an optional `engine` can be supplied for global operations
|
|
12
|
+
* (model list, config reads/writes, tool registry queries, etc.) that don't
|
|
13
|
+
* yet have a natural "which session" answer. When not supplied the server
|
|
14
|
+
* falls back to borrowing any live session's engine for those reads.
|
|
15
|
+
*/
|
|
16
|
+
import { Methods, ErrorCodes, createResponse, createErrorResponse, createNotification, isRequest, } from "./types.js";
|
|
17
|
+
import { setInteractiveApprovalFn } from "../tool-system/permission.js";
|
|
18
|
+
import { getArenaStatus } from "../tool-system/builtin/arena.js";
|
|
19
|
+
import { agentNotificationBus } from "../tool-system/builtin/agent-notifications.js";
|
|
20
|
+
import { nanoid } from "nanoid";
|
|
21
|
+
export class AgentServer {
|
|
22
|
+
chatManager;
|
|
23
|
+
legacyEngine;
|
|
24
|
+
transport;
|
|
25
|
+
// ── Legacy single-engine state (used when chatManager is null) ──
|
|
26
|
+
running = false;
|
|
27
|
+
abortController = null;
|
|
28
|
+
/** Pending approval requests: requestId → resolve function (legacy path) */
|
|
29
|
+
pendingApprovals = new Map();
|
|
30
|
+
/** Timers for approval timeouts */
|
|
31
|
+
approvalTimers = new Map();
|
|
32
|
+
/** Default approval timeout: 5 minutes */
|
|
33
|
+
static APPROVAL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
34
|
+
/**
|
|
35
|
+
* Unsubscribe handle for the process-local `agentNotificationBus`
|
|
36
|
+
* subscription set up in the constructor. Called from `close()` so a
|
|
37
|
+
* shut-down server stops forwarding completion events even if the bus
|
|
38
|
+
* itself outlives the server (it's a process-local singleton).
|
|
39
|
+
*/
|
|
40
|
+
bgAgentBusUnsubscribe = null;
|
|
41
|
+
constructor(options) {
|
|
42
|
+
this.chatManager = options.chatManager ?? null;
|
|
43
|
+
this.legacyEngine = options.engine ?? null;
|
|
44
|
+
if (!this.chatManager && !this.legacyEngine) {
|
|
45
|
+
throw new Error("AgentServer: either chatManager or engine must be supplied");
|
|
46
|
+
}
|
|
47
|
+
this.transport = options.transport;
|
|
48
|
+
// Wire up incoming messages
|
|
49
|
+
this.transport.onMessage((msg) => {
|
|
50
|
+
if (isRequest(msg)) {
|
|
51
|
+
this.handleRequest(msg).catch((err) => {
|
|
52
|
+
this.transport.send(createErrorResponse(msg.id, ErrorCodes.InternalError, err.message));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Wire approval flow for the legacy single-engine path.
|
|
57
|
+
// In the chatManager path approval flows are per-session and registered
|
|
58
|
+
// when the session's engine raises an approval request via onStream.
|
|
59
|
+
if (this.legacyEngine) {
|
|
60
|
+
setInteractiveApprovalFn((request) => {
|
|
61
|
+
return this.requestApprovalFromClient(request);
|
|
62
|
+
});
|
|
63
|
+
this.legacyEngine.setAskUser((question, opts) => {
|
|
64
|
+
return this.requestAskUserFromClient(question, opts);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// B2.2 — forward background sub-agent completion events through the
|
|
68
|
+
// protocol so Desktop / SDK / remote AgentClients see them too. The
|
|
69
|
+
// bus is fed from `NotificationQueue.enqueue`, so this single
|
|
70
|
+
// subscription covers every enqueue site (today: only agent.ts). The
|
|
71
|
+
// bus now guarantees a real sessionId (no more legacy-bucket coercion
|
|
72
|
+
// to ""), so we forward whatever sid it hands us.
|
|
73
|
+
this.bgAgentBusUnsubscribe = agentNotificationBus.subscribe((sessionId, event) => {
|
|
74
|
+
this.notify(Methods.StreamEvent, { sessionId, event });
|
|
75
|
+
});
|
|
76
|
+
// Notify client we're ready
|
|
77
|
+
this.notify(Methods.Status, { status: "ready" });
|
|
78
|
+
}
|
|
79
|
+
// ─── Request Dispatch ───────────────────────────────────────────
|
|
80
|
+
async handleRequest(req) {
|
|
81
|
+
switch (req.method) {
|
|
82
|
+
case Methods.Run:
|
|
83
|
+
await this.handleRun(req);
|
|
84
|
+
break;
|
|
85
|
+
case Methods.Approve:
|
|
86
|
+
this.handleApprove(req);
|
|
87
|
+
break;
|
|
88
|
+
case Methods.Cancel:
|
|
89
|
+
this.handleCancel(req);
|
|
90
|
+
break;
|
|
91
|
+
case Methods.Configure:
|
|
92
|
+
this.handleConfigure(req);
|
|
93
|
+
break;
|
|
94
|
+
case Methods.Query:
|
|
95
|
+
await this.handleQuery(req);
|
|
96
|
+
break;
|
|
97
|
+
case Methods.Inject:
|
|
98
|
+
this.handleInject(req);
|
|
99
|
+
break;
|
|
100
|
+
case Methods.CloseSession:
|
|
101
|
+
this.handleCloseSession(req);
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.MethodNotFound, `Unknown method: ${req.method}`));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// ─── Run ────────────────────────────────────────────────────────
|
|
108
|
+
async handleRun(req) {
|
|
109
|
+
// ── ChatSessionManager path (multi-session) ──────────────────
|
|
110
|
+
if (this.chatManager) {
|
|
111
|
+
return this.handleRunMulti(req);
|
|
112
|
+
}
|
|
113
|
+
// ── Legacy single-engine path ────────────────────────────────
|
|
114
|
+
return this.handleRunLegacy(req);
|
|
115
|
+
}
|
|
116
|
+
async handleRunMulti(req) {
|
|
117
|
+
const cm = this.chatManager;
|
|
118
|
+
const params = (req.params ?? {});
|
|
119
|
+
if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
|
|
120
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (!params.task) {
|
|
124
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "task is required"));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
let session;
|
|
128
|
+
try {
|
|
129
|
+
session = cm.getOrCreate(params.sessionId, {
|
|
130
|
+
permissionMode: params.permissionMode,
|
|
131
|
+
cwd: params.cwd,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
const code = err.code ?? ErrorCodes.InternalError;
|
|
136
|
+
this.transport.send(createErrorResponse(req.id, code, err.message));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (typeof params.planMode === "boolean") {
|
|
140
|
+
session.engine.setPlanMode(params.planMode);
|
|
141
|
+
}
|
|
142
|
+
const sid = params.sessionId;
|
|
143
|
+
try {
|
|
144
|
+
const result = await session.enqueueTurn(params.task, {
|
|
145
|
+
cwd: params.cwd,
|
|
146
|
+
onStream: (event) => this.notify(Methods.StreamEvent, { sessionId: sid, event }),
|
|
147
|
+
});
|
|
148
|
+
const runResult = {
|
|
149
|
+
text: result.text,
|
|
150
|
+
reason: result.reason,
|
|
151
|
+
sessionId: result.sessionId ?? sid,
|
|
152
|
+
turnCount: result.turnCount,
|
|
153
|
+
usage: result.usage,
|
|
154
|
+
};
|
|
155
|
+
this.transport.send(createResponse(req.id, runResult));
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async handleRunLegacy(req) {
|
|
162
|
+
if (this.running) {
|
|
163
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.Overloaded, "Agent is already running"));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const params = (req.params ?? {});
|
|
167
|
+
if (!params.task) {
|
|
168
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "task is required"));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (params.cwd !== undefined && (typeof params.cwd !== "string" || params.cwd.length === 0)) {
|
|
172
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "cwd must be a non-empty string"));
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (params.permissionMode !== undefined) {
|
|
176
|
+
const mode = params.permissionMode;
|
|
177
|
+
if (!isValidPermissionMode(mode)) {
|
|
178
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `invalid permission mode: ${mode}`));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.legacyEngine.setPermissionMode(mode);
|
|
182
|
+
// setRuntimeBypass / setInPlanMode singletons were removed in T4/T5;
|
|
183
|
+
// Engine.setPermissionMode now keeps this.permissionMode + this.planMode
|
|
184
|
+
// in sync and tools read them via ToolContext.permissionMode/planMode.
|
|
185
|
+
}
|
|
186
|
+
this.running = true;
|
|
187
|
+
this.abortController = new AbortController();
|
|
188
|
+
this.notify(Methods.Status, { status: "running" });
|
|
189
|
+
const streamToClient = (event) => {
|
|
190
|
+
this.notify(Methods.StreamEvent, { sessionId: params.sessionId ?? "", event });
|
|
191
|
+
};
|
|
192
|
+
// TodoWrite emits task_update directly through ToolContext.streamCallback;
|
|
193
|
+
// no module singleton wiring needed anymore.
|
|
194
|
+
try {
|
|
195
|
+
const result = await this.legacyEngine.run(params.task, {
|
|
196
|
+
cwd: params.cwd,
|
|
197
|
+
sessionId: params.sessionId,
|
|
198
|
+
signal: this.abortController.signal,
|
|
199
|
+
onStream: streamToClient,
|
|
200
|
+
});
|
|
201
|
+
const runResult = {
|
|
202
|
+
text: result.text,
|
|
203
|
+
reason: result.reason,
|
|
204
|
+
sessionId: result.sessionId,
|
|
205
|
+
turnCount: result.turnCount,
|
|
206
|
+
usage: result.usage,
|
|
207
|
+
};
|
|
208
|
+
this.transport.send(createResponse(req.id, runResult));
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
this.running = false;
|
|
215
|
+
this.abortController = null;
|
|
216
|
+
this.notify(Methods.Status, { status: "ready" });
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// ─── Approve ────────────────────────────────────────────────────
|
|
220
|
+
handleApprove(req) {
|
|
221
|
+
const params = (req.params ?? {});
|
|
222
|
+
// ChatSessionManager path: look up per-session pendingApprovals
|
|
223
|
+
if (this.chatManager && typeof params.sessionId === "string") {
|
|
224
|
+
const s = this.chatManager.get(params.sessionId);
|
|
225
|
+
if (!s) {
|
|
226
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const resolve = s.pendingApprovals.get(params.requestId);
|
|
230
|
+
if (!resolve) {
|
|
231
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `No pending approval: ${params.requestId}`));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
s.pendingApprovals.delete(params.requestId);
|
|
235
|
+
resolve(params.decision);
|
|
236
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
// Legacy path
|
|
240
|
+
const resolve = this.pendingApprovals.get(params.requestId);
|
|
241
|
+
if (!resolve) {
|
|
242
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `No pending approval: ${params.requestId}`));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
this.pendingApprovals.delete(params.requestId);
|
|
246
|
+
this.clearApprovalTimer(params.requestId);
|
|
247
|
+
resolve(params.decision);
|
|
248
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
249
|
+
}
|
|
250
|
+
// ─── Cancel ─────────────────────────────────────────────────────
|
|
251
|
+
handleCancel(req) {
|
|
252
|
+
const params = (req.params ?? {});
|
|
253
|
+
// ChatSessionManager path: cancel a specific session
|
|
254
|
+
if (this.chatManager) {
|
|
255
|
+
if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
|
|
256
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
const s = this.chatManager.get(params.sessionId);
|
|
260
|
+
if (!s) {
|
|
261
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
s.cancel();
|
|
265
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
// Legacy path
|
|
269
|
+
if (!this.running || !this.abortController) {
|
|
270
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, "Agent is not running"));
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
this.abortController.abort();
|
|
274
|
+
for (const [, resolve] of this.pendingApprovals) {
|
|
275
|
+
resolve({ approved: false, reason: "cancelled" });
|
|
276
|
+
}
|
|
277
|
+
this.pendingApprovals.clear();
|
|
278
|
+
this.clearAllApprovalTimers();
|
|
279
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
280
|
+
}
|
|
281
|
+
// ─── CloseSession ───────────────────────────────────────────────
|
|
282
|
+
handleCloseSession(req) {
|
|
283
|
+
const params = (req.params ?? {});
|
|
284
|
+
if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
|
|
285
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId is required"));
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (this.chatManager) {
|
|
289
|
+
this.chatManager.close(params.sessionId);
|
|
290
|
+
}
|
|
291
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
292
|
+
}
|
|
293
|
+
// ─── Configure ──────────────────────────────────────────────────
|
|
294
|
+
handleConfigure(req) {
|
|
295
|
+
const params = (req.params ?? {});
|
|
296
|
+
// If a sessionId is present, mutate that specific session's engine
|
|
297
|
+
if (this.chatManager && typeof params.sessionId === "string") {
|
|
298
|
+
const sid = params.sessionId;
|
|
299
|
+
const s = this.chatManager.get(sid);
|
|
300
|
+
if (!s) {
|
|
301
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${sid}`));
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (typeof params.planMode === "boolean")
|
|
305
|
+
s.engine.setPlanMode(params.planMode);
|
|
306
|
+
if (typeof params.permissionMode === "string") {
|
|
307
|
+
s.engine.setPermissionMode(params.permissionMode);
|
|
308
|
+
}
|
|
309
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
// Global configure — delegate to legacyEngine if available,
|
|
313
|
+
// or to any session's engine from chatManager for settings ops
|
|
314
|
+
const engine = this.legacyEngine ?? this.anyEngine();
|
|
315
|
+
if (params.reloadModels && engine) {
|
|
316
|
+
try {
|
|
317
|
+
engine.reloadModelPool();
|
|
318
|
+
}
|
|
319
|
+
catch (err) {
|
|
320
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (params.model !== undefined && engine) {
|
|
325
|
+
try {
|
|
326
|
+
const entry = engine.switchModel(params.model);
|
|
327
|
+
this.transport.send(createResponse(req.id, { ok: true, model: entry.model, key: entry.key }));
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
catch (err) {
|
|
331
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, err.message));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
if (params.planMode !== undefined && engine) {
|
|
336
|
+
engine.setPlanMode(params.planMode);
|
|
337
|
+
}
|
|
338
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
339
|
+
}
|
|
340
|
+
// ─── Query ──────────────────────────────────────────────────────
|
|
341
|
+
async handleQuery(req) {
|
|
342
|
+
const params = (req.params ?? {});
|
|
343
|
+
// For query operations we prefer the legacyEngine; if absent borrow any
|
|
344
|
+
// session engine from the manager (model pool, settings are shared).
|
|
345
|
+
const engine = this.legacyEngine ?? this.anyEngine();
|
|
346
|
+
switch (params.type) {
|
|
347
|
+
case "tools": {
|
|
348
|
+
if (!engine) {
|
|
349
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for tools query"));
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const registry = engine.getToolRegistry();
|
|
353
|
+
const tools = typeof registry.listToolsDetailed === "function"
|
|
354
|
+
? registry
|
|
355
|
+
.listToolsDetailed()
|
|
356
|
+
.map((t) => ({ name: t.name, description: t.description ?? "" }))
|
|
357
|
+
: registry.listTools().map((name) => ({ name, description: "" }));
|
|
358
|
+
this.transport.send(createResponse(req.id, { type: "tools", data: tools }));
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case "sessions": {
|
|
362
|
+
if (this.chatManager) {
|
|
363
|
+
// Return the ChatSessionManager's live sessions
|
|
364
|
+
const sessions = [...this.chatManager.sessions.entries()].map(([id, s]) => ({
|
|
365
|
+
sessionId: id,
|
|
366
|
+
busy: s.isBusy(),
|
|
367
|
+
queueDepth: s.queueDepth(),
|
|
368
|
+
lastActivityAt: s.lastActivityAt,
|
|
369
|
+
}));
|
|
370
|
+
this.transport.send(createResponse(req.id, { type: "sessions", data: sessions }));
|
|
371
|
+
}
|
|
372
|
+
else if (engine) {
|
|
373
|
+
const sessions = engine.getSessionManager().list();
|
|
374
|
+
this.transport.send(createResponse(req.id, { type: "sessions", data: sessions }));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
this.transport.send(createResponse(req.id, { type: "sessions", data: [] }));
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case "config": {
|
|
382
|
+
if (!engine) {
|
|
383
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config query"));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
const config = engine.getConfig();
|
|
387
|
+
this.transport.send(createResponse(req.id, {
|
|
388
|
+
type: "config",
|
|
389
|
+
data: {
|
|
390
|
+
permissionMode: config.permissionMode ?? "default",
|
|
391
|
+
planMode: engine.planMode ?? false,
|
|
392
|
+
preset: config.preset,
|
|
393
|
+
model: config.llm.model,
|
|
394
|
+
cwd: config.cwd,
|
|
395
|
+
maxContextTokens: config.maxContextTokens,
|
|
396
|
+
llm: {
|
|
397
|
+
provider: config.llm.provider,
|
|
398
|
+
model: config.llm.model,
|
|
399
|
+
apiKey: config.llm.apiKey,
|
|
400
|
+
baseUrl: config.llm.baseUrl,
|
|
401
|
+
temperature: config.llm.temperature,
|
|
402
|
+
maxTokens: config.llm.maxTokens,
|
|
403
|
+
enableStreaming: config.llm.enableStreaming,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
}));
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
case "session_detail": {
|
|
410
|
+
if (!engine) {
|
|
411
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for session_detail query"));
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (params.sessionId) {
|
|
415
|
+
try {
|
|
416
|
+
const bundle = engine.getSessionManager().resume(params.sessionId);
|
|
417
|
+
const data = {
|
|
418
|
+
state: bundle.state,
|
|
419
|
+
transcript: bundle.transcript.getEvents(),
|
|
420
|
+
};
|
|
421
|
+
this.transport.send(createResponse(req.id, { type: "session_detail", data }));
|
|
422
|
+
}
|
|
423
|
+
catch (err) {
|
|
424
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionNotFound, err.message));
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "sessionId required for session_detail"));
|
|
429
|
+
}
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
case "compact": {
|
|
433
|
+
if (!engine) {
|
|
434
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for compact query"));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
try {
|
|
438
|
+
const result = engine.forceCompact();
|
|
439
|
+
this.transport.send(createResponse(req.id, {
|
|
440
|
+
type: "compact",
|
|
441
|
+
data: result,
|
|
442
|
+
}));
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
446
|
+
}
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
case "models": {
|
|
450
|
+
if (!engine) {
|
|
451
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for models query"));
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const pool = engine.getModelPool();
|
|
455
|
+
const models = pool.list().map((m) => ({
|
|
456
|
+
key: m.key,
|
|
457
|
+
label: m.label ?? m.key,
|
|
458
|
+
model: m.model,
|
|
459
|
+
protocol: m.provider,
|
|
460
|
+
providerKey: m.providerKey,
|
|
461
|
+
active: m.key === pool.getActiveKey(),
|
|
462
|
+
maxOutputTokens: m.maxOutputTokens,
|
|
463
|
+
maxContextTokens: m.maxContextTokens,
|
|
464
|
+
}));
|
|
465
|
+
this.transport.send(createResponse(req.id, { type: "models", data: models }));
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
case "providers": {
|
|
469
|
+
if (!engine) {
|
|
470
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for providers query"));
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
try {
|
|
474
|
+
const providersRaw = engine.readSetting("providers");
|
|
475
|
+
const modelsRaw = engine.readSetting("models");
|
|
476
|
+
const providerList = Array.isArray(providersRaw)
|
|
477
|
+
? providersRaw
|
|
478
|
+
: [];
|
|
479
|
+
const modelsList = Array.isArray(modelsRaw)
|
|
480
|
+
? modelsRaw
|
|
481
|
+
: [];
|
|
482
|
+
const counts = new Map();
|
|
483
|
+
for (const m of modelsList) {
|
|
484
|
+
const pk = typeof m.providerKey === "string" ? m.providerKey : "";
|
|
485
|
+
if (!pk)
|
|
486
|
+
continue;
|
|
487
|
+
counts.set(pk, (counts.get(pk) ?? 0) + 1);
|
|
488
|
+
}
|
|
489
|
+
const { readCache } = await import("../llm/model-cache.js");
|
|
490
|
+
const { defaultCacheDir } = await import("../llm/model-cache.js");
|
|
491
|
+
const cacheDir = defaultCacheDir();
|
|
492
|
+
const enriched = providerList.map((p) => {
|
|
493
|
+
const key = typeof p.key === "string" ? p.key : "";
|
|
494
|
+
const cache = key ? readCache(cacheDir, key) : undefined;
|
|
495
|
+
return {
|
|
496
|
+
...p,
|
|
497
|
+
modelCount: counts.get(key) ?? 0,
|
|
498
|
+
cachedModels: cache ? cache.models.length : undefined,
|
|
499
|
+
cachedAt: cache ? cache.fetchedAt : undefined,
|
|
500
|
+
};
|
|
501
|
+
});
|
|
502
|
+
this.transport.send(createResponse(req.id, { type: "providers", data: enriched }));
|
|
503
|
+
}
|
|
504
|
+
catch (err) {
|
|
505
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
506
|
+
}
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
case "arena_status": {
|
|
510
|
+
const status = getArenaStatus();
|
|
511
|
+
this.transport.send(createResponse(req.id, { type: "arena_status", data: status }));
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
case "config_set": {
|
|
515
|
+
if (!engine) {
|
|
516
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config_set"));
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
const { key, value } = params;
|
|
521
|
+
if (!key)
|
|
522
|
+
throw new Error("key is required for config_set");
|
|
523
|
+
engine.updateConfig(key, value);
|
|
524
|
+
this.transport.send(createResponse(req.id, { type: "config_set", data: { key, value } }));
|
|
525
|
+
}
|
|
526
|
+
catch (err) {
|
|
527
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
528
|
+
}
|
|
529
|
+
break;
|
|
530
|
+
}
|
|
531
|
+
case "config_get": {
|
|
532
|
+
if (!engine) {
|
|
533
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for config_get"));
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
try {
|
|
537
|
+
const { key } = params;
|
|
538
|
+
if (!key)
|
|
539
|
+
throw new Error("key is required for config_get");
|
|
540
|
+
const value = engine.readSetting(key);
|
|
541
|
+
this.transport.send(createResponse(req.id, { type: "config_get", data: { key, value } }));
|
|
542
|
+
}
|
|
543
|
+
catch (err) {
|
|
544
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
545
|
+
}
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
case "permission_set": {
|
|
549
|
+
if (!engine) {
|
|
550
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for permission_set"));
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
try {
|
|
554
|
+
const value = params.value;
|
|
555
|
+
const valid = ["default", "acceptEdits", "dontAsk", "bypassPermissions", "auto", "plan"];
|
|
556
|
+
if (!value || !valid.includes(value)) {
|
|
557
|
+
throw new Error(`invalid permission mode: ${value}`);
|
|
558
|
+
}
|
|
559
|
+
engine.setPermissionMode(value);
|
|
560
|
+
this.transport.send(createResponse(req.id, {
|
|
561
|
+
type: "permission_set",
|
|
562
|
+
data: { mode: value },
|
|
563
|
+
}));
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
567
|
+
}
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
case "provider_add": {
|
|
571
|
+
if (!engine) {
|
|
572
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_add"));
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
try {
|
|
576
|
+
const cfg = params.provider;
|
|
577
|
+
if (!cfg ||
|
|
578
|
+
typeof cfg.key !== "string" ||
|
|
579
|
+
typeof cfg.kind !== "string" ||
|
|
580
|
+
typeof cfg.baseUrl !== "string") {
|
|
581
|
+
throw new Error("provider_add: requires {key, kind, baseUrl, ...}");
|
|
582
|
+
}
|
|
583
|
+
const current = engine.readSetting("providers") ?? [];
|
|
584
|
+
const next = [...current, cfg];
|
|
585
|
+
engine.updateConfig("providers", next);
|
|
586
|
+
this.transport.send(createResponse(req.id, { type: "provider_add", data: { ok: true, key: cfg.key } }));
|
|
587
|
+
}
|
|
588
|
+
catch (err) {
|
|
589
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
590
|
+
}
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
case "provider_refresh": {
|
|
594
|
+
if (!engine) {
|
|
595
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_refresh"));
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
try {
|
|
599
|
+
const key = params.key;
|
|
600
|
+
if (!key)
|
|
601
|
+
throw new Error("provider_refresh: key required");
|
|
602
|
+
const providers = engine.readSetting("providers") ??
|
|
603
|
+
[];
|
|
604
|
+
const p = providers.find((x) => x.key === key);
|
|
605
|
+
if (!p)
|
|
606
|
+
throw new Error(`provider not found: ${key}`);
|
|
607
|
+
const { fetchModelList } = await import("../llm/model-fetcher.js");
|
|
608
|
+
const { defaultCacheDir } = await import("../llm/model-cache.js");
|
|
609
|
+
const res = await fetchModelList({
|
|
610
|
+
key: p.key,
|
|
611
|
+
kind: p.kind,
|
|
612
|
+
baseUrl: p.baseUrl,
|
|
613
|
+
apiKey: p.apiKey,
|
|
614
|
+
}, { cacheDir: defaultCacheDir(), refresh: true });
|
|
615
|
+
this.transport.send(createResponse(req.id, {
|
|
616
|
+
type: "provider_refresh",
|
|
617
|
+
data: { count: res.models.length, error: res.error },
|
|
618
|
+
}));
|
|
619
|
+
}
|
|
620
|
+
catch (err) {
|
|
621
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
622
|
+
}
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
case "provider_delete": {
|
|
626
|
+
if (!engine) {
|
|
627
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for provider_delete"));
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
try {
|
|
631
|
+
const key = params.key;
|
|
632
|
+
if (!key)
|
|
633
|
+
throw new Error("provider_delete: key required");
|
|
634
|
+
const models = engine.readSetting("models") ?? [];
|
|
635
|
+
const refs = models.filter((m) => m.providerKey === key).map((m) => m.key);
|
|
636
|
+
if (refs.length > 0) {
|
|
637
|
+
throw new Error(`provider ${key} referenced by models: ${refs.join(", ")}`);
|
|
638
|
+
}
|
|
639
|
+
const providers = engine.readSetting("providers") ??
|
|
640
|
+
[];
|
|
641
|
+
const next = providers.filter((p) => p.key !== key);
|
|
642
|
+
engine.updateConfig("providers", next);
|
|
643
|
+
this.transport.send(createResponse(req.id, { type: "provider_delete", data: { ok: true } }));
|
|
644
|
+
}
|
|
645
|
+
catch (err) {
|
|
646
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
647
|
+
}
|
|
648
|
+
break;
|
|
649
|
+
}
|
|
650
|
+
case "model_add": {
|
|
651
|
+
if (!engine) {
|
|
652
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for model_add"));
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
try {
|
|
656
|
+
const entry = params.model;
|
|
657
|
+
if (!entry || typeof entry.key !== "string" || typeof entry.model !== "string") {
|
|
658
|
+
throw new Error("model_add: requires {key, model, providerKey}");
|
|
659
|
+
}
|
|
660
|
+
const current = engine.readSetting("models") ?? [];
|
|
661
|
+
const next = [...current, entry];
|
|
662
|
+
engine.updateConfig("models", next);
|
|
663
|
+
this.transport.send(createResponse(req.id, { type: "model_add", data: { ok: true, key: entry.key } }));
|
|
664
|
+
}
|
|
665
|
+
catch (err) {
|
|
666
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
case "model_delete": {
|
|
671
|
+
if (!engine) {
|
|
672
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, "No engine available for model_delete"));
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
try {
|
|
676
|
+
const key = params.key;
|
|
677
|
+
if (!key)
|
|
678
|
+
throw new Error("model_delete: key required");
|
|
679
|
+
const current = engine.readSetting("models") ?? [];
|
|
680
|
+
const next = current.filter((m) => m.key !== key);
|
|
681
|
+
engine.updateConfig("models", next);
|
|
682
|
+
this.transport.send(createResponse(req.id, { type: "model_delete", data: { ok: true } }));
|
|
683
|
+
}
|
|
684
|
+
catch (err) {
|
|
685
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
686
|
+
}
|
|
687
|
+
break;
|
|
688
|
+
}
|
|
689
|
+
default:
|
|
690
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, `Unknown query type: ${params.type}`));
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
// ─── Inject ─────────────────────────────────────────────────────
|
|
694
|
+
handleInject(req) {
|
|
695
|
+
const params = (req.params ?? {});
|
|
696
|
+
if (!params.content || !params.sessionId) {
|
|
697
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InvalidParams, "content and sessionId required"));
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
// In the chatManager path, inject into the session's engine
|
|
701
|
+
if (this.chatManager) {
|
|
702
|
+
const s = this.chatManager.get(params.sessionId);
|
|
703
|
+
if (!s) {
|
|
704
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.SessionClosed, `No such session: ${params.sessionId}`));
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
try {
|
|
708
|
+
s.engine.injectContext(params.sessionId, params.content);
|
|
709
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
710
|
+
}
|
|
711
|
+
catch (err) {
|
|
712
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
713
|
+
}
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
716
|
+
try {
|
|
717
|
+
this.legacyEngine.injectContext(params.sessionId, params.content);
|
|
718
|
+
this.transport.send(createResponse(req.id, { ok: true }));
|
|
719
|
+
}
|
|
720
|
+
catch (err) {
|
|
721
|
+
this.transport.send(createErrorResponse(req.id, ErrorCodes.InternalError, err.message));
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
// ─── Client Communication ───────────────────────────────────────
|
|
725
|
+
/**
|
|
726
|
+
* Ask the client to approve a tool operation (legacy single-engine path).
|
|
727
|
+
*/
|
|
728
|
+
requestApprovalFromClient(request) {
|
|
729
|
+
return new Promise((resolve) => {
|
|
730
|
+
const requestId = nanoid(12);
|
|
731
|
+
this.pendingApprovals.set(requestId, resolve);
|
|
732
|
+
const timer = setTimeout(() => {
|
|
733
|
+
if (this.pendingApprovals.has(requestId)) {
|
|
734
|
+
this.pendingApprovals.delete(requestId);
|
|
735
|
+
this.approvalTimers.delete(requestId);
|
|
736
|
+
resolve({ approved: false, reason: "approval timed out" });
|
|
737
|
+
}
|
|
738
|
+
}, AgentServer.APPROVAL_TIMEOUT_MS);
|
|
739
|
+
this.approvalTimers.set(requestId, timer);
|
|
740
|
+
this.notify(Methods.ApprovalRequest, { requestId, request });
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Ask the client to answer a question from the agent (legacy single-engine path).
|
|
745
|
+
*/
|
|
746
|
+
requestAskUserFromClient(question, opts) {
|
|
747
|
+
return new Promise((resolve) => {
|
|
748
|
+
const requestId = nanoid(12);
|
|
749
|
+
this.pendingApprovals.set(requestId, (result) => {
|
|
750
|
+
this.clearApprovalTimer(requestId);
|
|
751
|
+
if (result.approved) {
|
|
752
|
+
resolve(result.answer ?? "");
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
resolve(result.reason ?? "(user declined to answer)");
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
const timer = setTimeout(() => {
|
|
759
|
+
if (this.pendingApprovals.has(requestId)) {
|
|
760
|
+
this.pendingApprovals.delete(requestId);
|
|
761
|
+
this.approvalTimers.delete(requestId);
|
|
762
|
+
resolve("(approval timed out)");
|
|
763
|
+
}
|
|
764
|
+
}, AgentServer.APPROVAL_TIMEOUT_MS);
|
|
765
|
+
this.approvalTimers.set(requestId, timer);
|
|
766
|
+
const args = { question };
|
|
767
|
+
if (opts?.header !== undefined)
|
|
768
|
+
args.header = opts.header;
|
|
769
|
+
if (opts?.options !== undefined)
|
|
770
|
+
args.options = opts.options;
|
|
771
|
+
if (opts?.multiSelect !== undefined)
|
|
772
|
+
args.multiSelect = opts.multiSelect;
|
|
773
|
+
this.notify(Methods.ApprovalRequest, {
|
|
774
|
+
requestId,
|
|
775
|
+
request: {
|
|
776
|
+
toolName: "__ask_user__",
|
|
777
|
+
args,
|
|
778
|
+
description: question,
|
|
779
|
+
riskLevel: "low",
|
|
780
|
+
},
|
|
781
|
+
});
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
notify(method, params) {
|
|
785
|
+
this.transport.send(createNotification(method, params));
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Get any available engine — used for global query ops when chatManager is
|
|
789
|
+
* present but no legacyEngine was supplied. Borrows the first live session.
|
|
790
|
+
*/
|
|
791
|
+
anyEngine() {
|
|
792
|
+
if (!this.chatManager)
|
|
793
|
+
return null;
|
|
794
|
+
// Access private `sessions` map — acceptable for same-package access.
|
|
795
|
+
const sessions = this.chatManager.sessions;
|
|
796
|
+
const first = sessions.values().next().value;
|
|
797
|
+
return first ? first.engine : null;
|
|
798
|
+
}
|
|
799
|
+
// ─── Lifecycle ──────────────────────────────────────────────────
|
|
800
|
+
close() {
|
|
801
|
+
// Detach the bg-agent bus subscription first so a final flurry of
|
|
802
|
+
// completions during shutdown can't race the `shutdown` status
|
|
803
|
+
// notify below. Safe to call repeatedly — the unsubscribe is a
|
|
804
|
+
// single-shot Set.delete.
|
|
805
|
+
if (this.bgAgentBusUnsubscribe) {
|
|
806
|
+
try {
|
|
807
|
+
this.bgAgentBusUnsubscribe();
|
|
808
|
+
}
|
|
809
|
+
catch {
|
|
810
|
+
// swallow
|
|
811
|
+
}
|
|
812
|
+
this.bgAgentBusUnsubscribe = null;
|
|
813
|
+
}
|
|
814
|
+
if (this.chatManager) {
|
|
815
|
+
this.chatManager.closeAll();
|
|
816
|
+
}
|
|
817
|
+
// Legacy path cleanup
|
|
818
|
+
if (this.abortController) {
|
|
819
|
+
try {
|
|
820
|
+
this.abortController.abort("server closing");
|
|
821
|
+
}
|
|
822
|
+
catch {
|
|
823
|
+
// swallow
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
for (const [, resolve] of this.pendingApprovals) {
|
|
827
|
+
resolve({ approved: false, reason: "server closing" });
|
|
828
|
+
}
|
|
829
|
+
this.pendingApprovals.clear();
|
|
830
|
+
this.clearAllApprovalTimers();
|
|
831
|
+
this.notify(Methods.Status, { status: "shutdown" });
|
|
832
|
+
this.transport.close();
|
|
833
|
+
}
|
|
834
|
+
clearApprovalTimer(requestId) {
|
|
835
|
+
const timer = this.approvalTimers.get(requestId);
|
|
836
|
+
if (timer) {
|
|
837
|
+
clearTimeout(timer);
|
|
838
|
+
this.approvalTimers.delete(requestId);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
clearAllApprovalTimers() {
|
|
842
|
+
for (const timer of this.approvalTimers.values()) {
|
|
843
|
+
clearTimeout(timer);
|
|
844
|
+
}
|
|
845
|
+
this.approvalTimers.clear();
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
function isValidPermissionMode(value) {
|
|
849
|
+
return (value === "default" ||
|
|
850
|
+
value === "acceptEdits" ||
|
|
851
|
+
value === "dontAsk" ||
|
|
852
|
+
value === "bypassPermissions" ||
|
|
853
|
+
value === "auto" ||
|
|
854
|
+
value === "plan");
|
|
855
|
+
}
|