@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,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session lifecycle manager.
|
|
3
|
+
*/
|
|
4
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, readdirSync, renameSync, statSync, writeFileSync, } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { nanoid } from "nanoid";
|
|
8
|
+
import { Transcript } from "./transcript.js";
|
|
9
|
+
import { SessionError } from "../exceptions.js";
|
|
10
|
+
export class SessionManager {
|
|
11
|
+
sessionsDir;
|
|
12
|
+
constructor(storageDir) {
|
|
13
|
+
this.sessionsDir = storageDir ?? join(homedir(), ".code-shell", "sessions");
|
|
14
|
+
mkdirSync(this.sessionsDir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a new on-disk session. If `explicitSessionId` is passed, use
|
|
18
|
+
* it verbatim (ChatSessionManager-driven hosts choose a logical sid like
|
|
19
|
+
* "tui-main" and expect us to honor it). Otherwise generate one with
|
|
20
|
+
* nanoid. Either way the on-disk directory is materialized and the
|
|
21
|
+
* state.json + transcript.jsonl files are written before return.
|
|
22
|
+
*/
|
|
23
|
+
create(cwd, model, provider, explicitSessionId) {
|
|
24
|
+
const sessionId = explicitSessionId ?? nanoid(16);
|
|
25
|
+
const sessionDir = join(this.sessionsDir, sessionId);
|
|
26
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
27
|
+
const state = {
|
|
28
|
+
sessionId,
|
|
29
|
+
cwd,
|
|
30
|
+
startedAt: Date.now(),
|
|
31
|
+
model,
|
|
32
|
+
provider,
|
|
33
|
+
tokenUsage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
|
|
34
|
+
turnCount: 0,
|
|
35
|
+
invokedSkills: [],
|
|
36
|
+
status: "active",
|
|
37
|
+
};
|
|
38
|
+
writeFileSync(join(sessionDir, "state.json"), JSON.stringify(state, null, 2), "utf-8");
|
|
39
|
+
const transcript = new Transcript(join(sessionDir, "transcript.jsonl"));
|
|
40
|
+
transcript.append("session_meta", {
|
|
41
|
+
sessionId,
|
|
42
|
+
cwd,
|
|
43
|
+
model,
|
|
44
|
+
provider,
|
|
45
|
+
startedAt: state.startedAt,
|
|
46
|
+
});
|
|
47
|
+
return { state, transcript };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether a session directory exists on disk. Used by ChatSession-driven
|
|
51
|
+
* cold starts to decide between resume vs create-with-explicit-sid
|
|
52
|
+
* without catching SessionError.
|
|
53
|
+
*/
|
|
54
|
+
exists(sessionId) {
|
|
55
|
+
return existsSync(join(this.sessionsDir, sessionId));
|
|
56
|
+
}
|
|
57
|
+
resume(sessionId) {
|
|
58
|
+
const sessionDir = join(this.sessionsDir, sessionId);
|
|
59
|
+
if (!existsSync(sessionDir)) {
|
|
60
|
+
throw new SessionError(`Session not found: ${sessionId}`);
|
|
61
|
+
}
|
|
62
|
+
const stateFile = join(sessionDir, "state.json");
|
|
63
|
+
if (!existsSync(stateFile)) {
|
|
64
|
+
throw new SessionError(`Session state file not found: ${sessionId}`);
|
|
65
|
+
}
|
|
66
|
+
const state = JSON.parse(readFileSync(stateFile, "utf-8"));
|
|
67
|
+
const transcriptFile = join(sessionDir, "transcript.jsonl");
|
|
68
|
+
const transcript = Transcript.loadFromFile(transcriptFile);
|
|
69
|
+
state.status = "active";
|
|
70
|
+
return { state, transcript };
|
|
71
|
+
}
|
|
72
|
+
saveState(state) {
|
|
73
|
+
const sessionDir = join(this.sessionsDir, state.sessionId);
|
|
74
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
75
|
+
// Atomic write: stage to .tmp, then rename. Protects against two processes
|
|
76
|
+
// clobbering each other's state.json mid-write.
|
|
77
|
+
const target = join(sessionDir, "state.json");
|
|
78
|
+
const tmp = `${target}.${process.pid}.${Date.now()}.tmp`;
|
|
79
|
+
writeFileSync(tmp, JSON.stringify(state, null, 2), "utf-8");
|
|
80
|
+
renameSync(tmp, target);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Fork a session from a specific point.
|
|
84
|
+
* Creates a new session that shares events up to the given turn,
|
|
85
|
+
* then diverges independently.
|
|
86
|
+
*/
|
|
87
|
+
fork(sourceSessionId, forkAtTurn) {
|
|
88
|
+
const source = this.resume(sourceSessionId);
|
|
89
|
+
const events = source.transcript.getEvents();
|
|
90
|
+
// Determine fork point
|
|
91
|
+
const forkTurn = forkAtTurn ?? source.state.turnCount;
|
|
92
|
+
// Create new session
|
|
93
|
+
const newBundle = this.create(source.state.cwd, source.state.model, source.state.provider);
|
|
94
|
+
newBundle.state.parentSessionId = sourceSessionId;
|
|
95
|
+
// Copy events up to the fork point
|
|
96
|
+
for (const event of events) {
|
|
97
|
+
if (event.type === "turn_boundary" && event.data.turnNumber > forkTurn) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
newBundle.transcript.append(event.type, event.data);
|
|
101
|
+
}
|
|
102
|
+
this.saveState(newBundle.state);
|
|
103
|
+
return newBundle;
|
|
104
|
+
}
|
|
105
|
+
list(limit = 20) {
|
|
106
|
+
if (!existsSync(this.sessionsDir))
|
|
107
|
+
return [];
|
|
108
|
+
const dirs = readdirSync(this.sessionsDir, { withFileTypes: true })
|
|
109
|
+
.filter((d) => d.isDirectory())
|
|
110
|
+
.map((d) => d.name);
|
|
111
|
+
const candidates = [];
|
|
112
|
+
for (const dir of dirs) {
|
|
113
|
+
const stateFile = join(this.sessionsDir, dir, "state.json");
|
|
114
|
+
if (!existsSync(stateFile))
|
|
115
|
+
continue;
|
|
116
|
+
const transcriptFile = join(this.sessionsDir, dir, "transcript.jsonl");
|
|
117
|
+
let lastActiveAt;
|
|
118
|
+
let transcriptExists = false;
|
|
119
|
+
try {
|
|
120
|
+
transcriptExists = existsSync(transcriptFile);
|
|
121
|
+
if (transcriptExists) {
|
|
122
|
+
lastActiveAt = statSync(transcriptFile).mtimeMs;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// Fall back to state.json mtime (cheaper than parsing it for
|
|
126
|
+
// state.startedAt and good enough for ordering).
|
|
127
|
+
lastActiveAt = statSync(stateFile).mtimeMs;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
candidates.push({ dir, lastActiveAt, transcriptFile, stateFile, transcriptExists });
|
|
134
|
+
}
|
|
135
|
+
candidates.sort((a, b) => b.lastActiveAt - a.lastActiveAt);
|
|
136
|
+
const top = candidates.slice(0, limit);
|
|
137
|
+
const sessions = [];
|
|
138
|
+
for (const c of top) {
|
|
139
|
+
try {
|
|
140
|
+
const state = JSON.parse(readFileSync(c.stateFile, "utf-8"));
|
|
141
|
+
const preview = c.transcriptExists ? readLastUserMessage(c.transcriptFile) : undefined;
|
|
142
|
+
sessions.push({ ...state, preview, lastActiveAt: c.lastActiveAt });
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Skip corrupted sessions
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return sessions;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Scan a transcript.jsonl for the LAST user message and return a short
|
|
153
|
+
* preview, reading the file from the END in 64 KiB chunks.
|
|
154
|
+
*
|
|
155
|
+
* Why: SessionManager.list() calls this for every session in
|
|
156
|
+
* ~/.code-shell/sessions (hundreds to thousands at steady state). The
|
|
157
|
+
* earlier readFileSync-the-whole-file implementation made `/resume`
|
|
158
|
+
* scan ~64 MiB across nearly 1 k transcripts every time the list
|
|
159
|
+
* opened — visible as several seconds of UI freeze. The vast majority
|
|
160
|
+
* of transcripts have their last user message in the final few KiB, so
|
|
161
|
+
* tailing one chunk is usually enough and we never read more than we
|
|
162
|
+
* have to.
|
|
163
|
+
*
|
|
164
|
+
* Algorithm: open the file once, seek to the tail, read backwards one
|
|
165
|
+
* chunk at a time, splitting on newlines. Walk the lines we have so
|
|
166
|
+
* far from newest to oldest; the moment we find a `type:"message",
|
|
167
|
+
* role:"user"` event with non-empty text we close the fd and return.
|
|
168
|
+
* Keep a small "leftover" prefix between chunks so a JSON line straddling
|
|
169
|
+
* a chunk boundary still parses.
|
|
170
|
+
*
|
|
171
|
+
* Returns undefined if the session has no user messages, or on any IO
|
|
172
|
+
* error (caller treats the preview as optional).
|
|
173
|
+
*/
|
|
174
|
+
const TAIL_CHUNK_SIZE = 64 * 1024;
|
|
175
|
+
function readLastUserMessage(transcriptFile) {
|
|
176
|
+
if (!existsSync(transcriptFile))
|
|
177
|
+
return undefined;
|
|
178
|
+
let fd;
|
|
179
|
+
let fileSize;
|
|
180
|
+
try {
|
|
181
|
+
fd = openSync(transcriptFile, "r");
|
|
182
|
+
fileSize = statSync(transcriptFile).size;
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
if (fileSize === 0) {
|
|
188
|
+
closeSync(fd);
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
let position = fileSize;
|
|
193
|
+
// `leftover` holds bytes from the previous (later) chunk that we
|
|
194
|
+
// couldn't yet split on a newline — they're the partial start of a
|
|
195
|
+
// line whose end lives in the older chunk we just read.
|
|
196
|
+
let leftover = "";
|
|
197
|
+
const buf = Buffer.alloc(TAIL_CHUNK_SIZE);
|
|
198
|
+
while (position > 0) {
|
|
199
|
+
const readLen = Math.min(TAIL_CHUNK_SIZE, position);
|
|
200
|
+
position -= readLen;
|
|
201
|
+
const got = readSync(fd, buf, 0, readLen, position);
|
|
202
|
+
if (got <= 0)
|
|
203
|
+
break;
|
|
204
|
+
const text = buf.toString("utf8", 0, got) + leftover;
|
|
205
|
+
const lines = text.split("\n");
|
|
206
|
+
// If we haven't reached the beginning of the file, the first
|
|
207
|
+
// element of `lines` may be a partial line; defer it to the next
|
|
208
|
+
// (older) chunk. Once position==0 we know the first element is a
|
|
209
|
+
// real complete line and we should process it too.
|
|
210
|
+
const start = position === 0 ? 0 : 1;
|
|
211
|
+
if (position > 0)
|
|
212
|
+
leftover = lines[0] ?? "";
|
|
213
|
+
for (let i = lines.length - 1; i >= start; i--) {
|
|
214
|
+
const preview = parseUserPreview(lines[i]);
|
|
215
|
+
if (preview !== undefined)
|
|
216
|
+
return preview;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
finally {
|
|
225
|
+
try {
|
|
226
|
+
closeSync(fd);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
/* already closed */
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Parse one transcript line; return the preview string if it's a
|
|
235
|
+
* non-empty user message, otherwise undefined. Pulled out so the
|
|
236
|
+
* tail loop above stays focused on IO mechanics.
|
|
237
|
+
*/
|
|
238
|
+
function parseUserPreview(line) {
|
|
239
|
+
if (!line)
|
|
240
|
+
return undefined;
|
|
241
|
+
let event;
|
|
242
|
+
try {
|
|
243
|
+
event = JSON.parse(line);
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
if (event.type !== "message")
|
|
249
|
+
return undefined;
|
|
250
|
+
if (event.data?.role !== "user")
|
|
251
|
+
return undefined;
|
|
252
|
+
const content = event.data.content;
|
|
253
|
+
const text = typeof content === "string"
|
|
254
|
+
? content
|
|
255
|
+
: Array.isArray(content)
|
|
256
|
+
? (content.find((b) => b.type === "text")?.text ?? "")
|
|
257
|
+
: "";
|
|
258
|
+
if (!text.trim())
|
|
259
|
+
return undefined;
|
|
260
|
+
return text.replace(/\s+/g, " ").trim();
|
|
261
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript — JSONL event log (NOT chat history).
|
|
3
|
+
* toMessages() derives Message[] from events for sending to LLM.
|
|
4
|
+
*/
|
|
5
|
+
import type { TranscriptEvent, TranscriptEventType, Message, ContentBlock } from "../types.js";
|
|
6
|
+
export declare class Transcript {
|
|
7
|
+
private events;
|
|
8
|
+
private filePath;
|
|
9
|
+
private currentTurn;
|
|
10
|
+
getFilePath(): string;
|
|
11
|
+
constructor(filePath: string);
|
|
12
|
+
append(type: TranscriptEventType, data: Record<string, unknown>): TranscriptEvent;
|
|
13
|
+
appendMessage(role: string, content: string | ContentBlock[]): TranscriptEvent;
|
|
14
|
+
appendToolUse(toolName: string, toolCallId: string, args: Record<string, unknown>): TranscriptEvent;
|
|
15
|
+
appendToolResult(toolCallId: string, toolName: string, result?: string, error?: string): TranscriptEvent;
|
|
16
|
+
appendTurnBoundary(): TranscriptEvent;
|
|
17
|
+
appendSummary(summary: string, compactedRange: {
|
|
18
|
+
fromTurn: number;
|
|
19
|
+
toTurn: number;
|
|
20
|
+
eventCount: number;
|
|
21
|
+
}): TranscriptEvent;
|
|
22
|
+
appendError(error: string, details?: Record<string, unknown>): TranscriptEvent;
|
|
23
|
+
/**
|
|
24
|
+
* Derive Message[] from transcript events for sending to the LLM.
|
|
25
|
+
* This is the critical boundary: the LLM never sees the event log directly.
|
|
26
|
+
*/
|
|
27
|
+
toMessages(): Message[];
|
|
28
|
+
getEvents(type?: TranscriptEventType): TranscriptEvent[];
|
|
29
|
+
get turnNumber(): number;
|
|
30
|
+
get eventCount(): number;
|
|
31
|
+
private flush;
|
|
32
|
+
/**
|
|
33
|
+
* Repair tool_result pairing issues:
|
|
34
|
+
* - Orphaned tool_results (no matching tool_use) get removed
|
|
35
|
+
* - Missing tool_results (tool_use with no result) get synthetic error results
|
|
36
|
+
*/
|
|
37
|
+
repairToolResultPairs(): void;
|
|
38
|
+
static loadFromFile(filePath: string): Transcript;
|
|
39
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcript — JSONL event log (NOT chat history).
|
|
3
|
+
* toMessages() derives Message[] from events for sending to LLM.
|
|
4
|
+
*/
|
|
5
|
+
import { appendFileSync, readFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname } from "node:path";
|
|
7
|
+
import { nanoid } from "nanoid";
|
|
8
|
+
export class Transcript {
|
|
9
|
+
events = [];
|
|
10
|
+
filePath;
|
|
11
|
+
currentTurn = 0;
|
|
12
|
+
getFilePath() { return this.filePath; }
|
|
13
|
+
constructor(filePath) {
|
|
14
|
+
this.filePath = filePath;
|
|
15
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
16
|
+
if (!existsSync(filePath)) {
|
|
17
|
+
writeFileSync(filePath, "", "utf-8");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
append(type, data) {
|
|
21
|
+
const event = {
|
|
22
|
+
id: nanoid(12),
|
|
23
|
+
type,
|
|
24
|
+
timestamp: Date.now(),
|
|
25
|
+
turnNumber: this.currentTurn,
|
|
26
|
+
data,
|
|
27
|
+
};
|
|
28
|
+
this.events.push(event);
|
|
29
|
+
this.flush(event);
|
|
30
|
+
return event;
|
|
31
|
+
}
|
|
32
|
+
appendMessage(role, content) {
|
|
33
|
+
return this.append("message", { role, content });
|
|
34
|
+
}
|
|
35
|
+
appendToolUse(toolName, toolCallId, args) {
|
|
36
|
+
return this.append("tool_use", { toolName, toolCallId, args });
|
|
37
|
+
}
|
|
38
|
+
appendToolResult(toolCallId, toolName, result, error) {
|
|
39
|
+
return this.append("tool_result", { toolCallId, toolName, result, error });
|
|
40
|
+
}
|
|
41
|
+
appendTurnBoundary() {
|
|
42
|
+
this.currentTurn++;
|
|
43
|
+
return this.append("turn_boundary", { turnNumber: this.currentTurn });
|
|
44
|
+
}
|
|
45
|
+
appendSummary(summary, compactedRange) {
|
|
46
|
+
return this.append("summary", {
|
|
47
|
+
summary,
|
|
48
|
+
trigger: "auto",
|
|
49
|
+
compactedRange,
|
|
50
|
+
preservedSegment: {
|
|
51
|
+
headEventId: this.events[0]?.id,
|
|
52
|
+
tailEventId: this.events[this.events.length - 1]?.id,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
appendError(error, details) {
|
|
57
|
+
return this.append("error", { error, ...details });
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Derive Message[] from transcript events for sending to the LLM.
|
|
61
|
+
* This is the critical boundary: the LLM never sees the event log directly.
|
|
62
|
+
*/
|
|
63
|
+
toMessages() {
|
|
64
|
+
const messages = [];
|
|
65
|
+
for (const event of this.events) {
|
|
66
|
+
switch (event.type) {
|
|
67
|
+
case "message": {
|
|
68
|
+
const { role, content } = event.data;
|
|
69
|
+
messages.push({ role: role, content });
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "tool_use": {
|
|
73
|
+
// Tool use is part of assistant message content blocks
|
|
74
|
+
// Already included via the assistant message event
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "tool_result": {
|
|
78
|
+
const { toolCallId, result, error } = event.data;
|
|
79
|
+
// Find if there's already a user message with tool_results to append to
|
|
80
|
+
const lastMsg = messages[messages.length - 1];
|
|
81
|
+
const block = {
|
|
82
|
+
type: "tool_result",
|
|
83
|
+
tool_use_id: toolCallId,
|
|
84
|
+
content: error ? `Error: ${error}` : result ?? "(no output)",
|
|
85
|
+
};
|
|
86
|
+
if (lastMsg?.role === "user" && Array.isArray(lastMsg.content)) {
|
|
87
|
+
lastMsg.content.push(block);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
messages.push({ role: "user", content: [block] });
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "summary": {
|
|
95
|
+
// Content replacement: inject summary as system-reminder
|
|
96
|
+
const { summary } = event.data;
|
|
97
|
+
messages.push({
|
|
98
|
+
role: "user",
|
|
99
|
+
content: `<system-reminder>Previous conversation was summarized:\n${summary}</system-reminder>`,
|
|
100
|
+
});
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
// turn_boundary, session_meta, file_history, plan_operation, error
|
|
104
|
+
// are not included in LLM messages
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return messages;
|
|
108
|
+
}
|
|
109
|
+
getEvents(type) {
|
|
110
|
+
if (!type)
|
|
111
|
+
return [...this.events];
|
|
112
|
+
return this.events.filter((e) => e.type === type);
|
|
113
|
+
}
|
|
114
|
+
get turnNumber() {
|
|
115
|
+
return this.currentTurn;
|
|
116
|
+
}
|
|
117
|
+
get eventCount() {
|
|
118
|
+
return this.events.length;
|
|
119
|
+
}
|
|
120
|
+
flush(event) {
|
|
121
|
+
try {
|
|
122
|
+
appendFileSync(this.filePath, JSON.stringify(event) + "\n", "utf-8");
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Silently fail on flush errors — events are still in memory
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Repair tool_result pairing issues:
|
|
130
|
+
* - Orphaned tool_results (no matching tool_use) get removed
|
|
131
|
+
* - Missing tool_results (tool_use with no result) get synthetic error results
|
|
132
|
+
*/
|
|
133
|
+
repairToolResultPairs() {
|
|
134
|
+
const toolUseIds = new Set();
|
|
135
|
+
const toolResultIds = new Set();
|
|
136
|
+
for (const event of this.events) {
|
|
137
|
+
if (event.type === "tool_use") {
|
|
138
|
+
toolUseIds.add(event.data.toolCallId);
|
|
139
|
+
}
|
|
140
|
+
else if (event.type === "tool_result") {
|
|
141
|
+
toolResultIds.add(event.data.toolCallId);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Find tool_use events without matching tool_result
|
|
145
|
+
for (const id of toolUseIds) {
|
|
146
|
+
if (!toolResultIds.has(id)) {
|
|
147
|
+
// Synthesize an error result
|
|
148
|
+
this.append("tool_result", {
|
|
149
|
+
toolCallId: id,
|
|
150
|
+
toolName: "unknown",
|
|
151
|
+
error: "[Tool result missing due to interrupted session]",
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Remove orphaned tool_results (result without matching use)
|
|
156
|
+
this.events = this.events.filter((event) => {
|
|
157
|
+
if (event.type === "tool_result") {
|
|
158
|
+
const id = event.data.toolCallId;
|
|
159
|
+
return toolUseIds.has(id);
|
|
160
|
+
}
|
|
161
|
+
return true;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
static loadFromFile(filePath) {
|
|
165
|
+
const transcript = new Transcript(filePath);
|
|
166
|
+
if (!existsSync(filePath))
|
|
167
|
+
return transcript;
|
|
168
|
+
const content = readFileSync(filePath, "utf-8");
|
|
169
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
170
|
+
for (const line of lines) {
|
|
171
|
+
try {
|
|
172
|
+
const event = JSON.parse(line);
|
|
173
|
+
transcript.events.push(event);
|
|
174
|
+
if (event.type === "turn_boundary") {
|
|
175
|
+
transcript.currentTurn = event.data.turnNumber ?? transcript.currentTurn + 1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Skip malformed lines
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Repair pairing on load
|
|
183
|
+
transcript.repairToolResultPairs();
|
|
184
|
+
return transcript;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings manager — multi-source loading and merge.
|
|
3
|
+
*
|
|
4
|
+
* Priority: CLI flags > local > project > user > managed
|
|
5
|
+
*/
|
|
6
|
+
import { type ValidatedSettings } from "./schema.js";
|
|
7
|
+
export type SettingsSourceName = "managed" | "user" | "project" | "local" | "flag";
|
|
8
|
+
export declare class SettingsManager {
|
|
9
|
+
private readonly cwd;
|
|
10
|
+
private sources;
|
|
11
|
+
private merged;
|
|
12
|
+
constructor(cwd?: string);
|
|
13
|
+
/**
|
|
14
|
+
* Load settings from all sources.
|
|
15
|
+
*/
|
|
16
|
+
load(flagOverrides?: Record<string, unknown>): ValidatedSettings;
|
|
17
|
+
/**
|
|
18
|
+
* Get current effective settings.
|
|
19
|
+
*/
|
|
20
|
+
get(): ValidatedSettings;
|
|
21
|
+
/**
|
|
22
|
+
* Invalidate cached merge.
|
|
23
|
+
*/
|
|
24
|
+
invalidate(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Persist a single setting (dotted key path) to the user-level config file
|
|
27
|
+
* at ~/.code-shell/settings.json. Other sources (project / local /
|
|
28
|
+
* managed) are intentionally untouched: writing back to project/local
|
|
29
|
+
* would surprise version control, and managed is read-only.
|
|
30
|
+
*
|
|
31
|
+
* The merged cache is invalidated so the next get() picks up the change.
|
|
32
|
+
*/
|
|
33
|
+
saveUserSetting(key: string, value: unknown): void;
|
|
34
|
+
private loadJsonFile;
|
|
35
|
+
private deepMerge;
|
|
36
|
+
}
|