@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,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Settings schema with Zod validation.
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
export const SettingsSchema = z
|
|
6
|
+
.object({
|
|
7
|
+
agent: z
|
|
8
|
+
.object({
|
|
9
|
+
// Use z.string() instead of z.enum() to allow custom presets registered via registerPreset()
|
|
10
|
+
preset: z.string().default("terminal-coding"),
|
|
11
|
+
enabledBuiltinTools: z.array(z.string()).default([]),
|
|
12
|
+
disabledBuiltinTools: z.array(z.string()).default([]),
|
|
13
|
+
customSystemPrompt: z.string().optional(),
|
|
14
|
+
appendSystemPrompt: z.string().optional(),
|
|
15
|
+
})
|
|
16
|
+
.default({}),
|
|
17
|
+
/**
|
|
18
|
+
* Primary source of truth for the active model is settings.activeKey
|
|
19
|
+
* (points at models[].key). settings.model is a derived mirror of that
|
|
20
|
+
* entry kept in sync for legacy boot paths (cli/main.ts, repl.ts, etc.)
|
|
21
|
+
* which read provider/name/apiKey/baseUrl directly. Writers must update
|
|
22
|
+
* both — appendOnboardingResult does this in one shot.
|
|
23
|
+
*/
|
|
24
|
+
activeKey: z.string().optional(),
|
|
25
|
+
/**
|
|
26
|
+
* Toggle background auto-update. When true (default), code-shell checks
|
|
27
|
+
* npm for newer versions and — if the npm global prefix is writable —
|
|
28
|
+
* installs the update in the background on process exit so the next
|
|
29
|
+
* launch picks it up.
|
|
30
|
+
* Can also be disabled via env var `DISABLE_AUTOUPDATER=1`.
|
|
31
|
+
*/
|
|
32
|
+
autoUpdates: z.boolean().default(true),
|
|
33
|
+
model: z
|
|
34
|
+
.object({
|
|
35
|
+
provider: z.string().default("openai"),
|
|
36
|
+
name: z.string().default("anthropic/claude-opus-4-6"),
|
|
37
|
+
apiKey: z.string().optional(),
|
|
38
|
+
baseUrl: z.string().default("https://openrouter.ai/api/v1"),
|
|
39
|
+
temperature: z.number().min(0).max(2).default(0.3),
|
|
40
|
+
maxTokens: z.number().default(8192),
|
|
41
|
+
})
|
|
42
|
+
.default({}),
|
|
43
|
+
providers: z
|
|
44
|
+
.array(z.object({
|
|
45
|
+
key: z.string(),
|
|
46
|
+
label: z.string().optional(),
|
|
47
|
+
kind: z.enum([
|
|
48
|
+
"openai",
|
|
49
|
+
"anthropic",
|
|
50
|
+
"deepseek",
|
|
51
|
+
"zai",
|
|
52
|
+
"xai",
|
|
53
|
+
"mistral",
|
|
54
|
+
"groq",
|
|
55
|
+
"google",
|
|
56
|
+
"openrouter",
|
|
57
|
+
"ollama",
|
|
58
|
+
"custom",
|
|
59
|
+
]),
|
|
60
|
+
baseUrl: z.string(),
|
|
61
|
+
apiKey: z.string().optional(),
|
|
62
|
+
protocol: z.enum(["openai-compat", "anthropic-style"]).optional(),
|
|
63
|
+
modelsPath: z.string().optional(),
|
|
64
|
+
/**
|
|
65
|
+
* DeepSeek V4 thinking-mode default for this provider. "enabled"
|
|
66
|
+
* matches endpoint default; "disabled" makes V4 calls run in
|
|
67
|
+
* non-thinking mode (faster, cheaper). Ignored by every provider
|
|
68
|
+
* other than DeepSeek V4. Per-call overrides still win.
|
|
69
|
+
*/
|
|
70
|
+
thinking: z.enum(["enabled", "disabled"]).optional(),
|
|
71
|
+
}))
|
|
72
|
+
.default([]),
|
|
73
|
+
models: z
|
|
74
|
+
.array(z
|
|
75
|
+
.object({
|
|
76
|
+
key: z.string(),
|
|
77
|
+
label: z.string().optional(),
|
|
78
|
+
providerKey: z.string().optional(),
|
|
79
|
+
model: z.string(),
|
|
80
|
+
maxOutputTokens: z.number().optional(),
|
|
81
|
+
maxContextTokens: z.number().optional(),
|
|
82
|
+
/**
|
|
83
|
+
* Which LLM client to use ("openai" or "anthropic"). New name —
|
|
84
|
+
* the legacy field is `provider`, which we still accept and
|
|
85
|
+
* fold into `protocol` below so old configs keep working.
|
|
86
|
+
* NOT the brand/vendor — that's providerKey above.
|
|
87
|
+
*/
|
|
88
|
+
protocol: z.string().optional(),
|
|
89
|
+
provider: z.string().optional(),
|
|
90
|
+
baseUrl: z.string().optional(),
|
|
91
|
+
apiKey: z.string().optional(),
|
|
92
|
+
/**
|
|
93
|
+
* Per-model thinking override. Wins over the provider-level
|
|
94
|
+
* setting (settings.providers[].thinking). Use this when
|
|
95
|
+
* different models under the same provider need different
|
|
96
|
+
* defaults — e.g. DeepSeek V4 Pro off (faster) but V4 Flash on.
|
|
97
|
+
*/
|
|
98
|
+
thinking: z.enum(["enabled", "disabled"]).optional(),
|
|
99
|
+
})
|
|
100
|
+
.transform((m) => {
|
|
101
|
+
// Normalize: prefer `protocol`; fall back to legacy `provider`.
|
|
102
|
+
// We keep `provider` populated as a mirror because engine code
|
|
103
|
+
// and a few downstream readers still query it directly.
|
|
104
|
+
const effective = m.protocol ?? m.provider;
|
|
105
|
+
return {
|
|
106
|
+
...m,
|
|
107
|
+
protocol: effective,
|
|
108
|
+
provider: effective,
|
|
109
|
+
};
|
|
110
|
+
}))
|
|
111
|
+
.default([]),
|
|
112
|
+
permissions: z
|
|
113
|
+
.object({
|
|
114
|
+
defaultMode: z
|
|
115
|
+
.enum(["default", "acceptEdits", "dontAsk", "bypassPermissions", "auto", "plan"])
|
|
116
|
+
.default("default"),
|
|
117
|
+
rules: z
|
|
118
|
+
.array(z.object({
|
|
119
|
+
tool: z.string(),
|
|
120
|
+
argsPattern: z.record(z.string()).optional(),
|
|
121
|
+
decision: z.enum(["allow", "deny", "ask"]),
|
|
122
|
+
reason: z.string().optional(),
|
|
123
|
+
}))
|
|
124
|
+
.default([]),
|
|
125
|
+
})
|
|
126
|
+
.default({}),
|
|
127
|
+
context: z
|
|
128
|
+
.object({
|
|
129
|
+
maxTokens: z.number().default(200_000),
|
|
130
|
+
compactAtRatio: z.number().default(0.6),
|
|
131
|
+
summarizeAtRatio: z.number().default(0.8),
|
|
132
|
+
})
|
|
133
|
+
.default({}),
|
|
134
|
+
session: z
|
|
135
|
+
.object({
|
|
136
|
+
storageDir: z.string().optional(),
|
|
137
|
+
maxHistory: z.number().default(100),
|
|
138
|
+
})
|
|
139
|
+
.default({}),
|
|
140
|
+
mcpServers: z
|
|
141
|
+
.record(z.object({
|
|
142
|
+
name: z.string(),
|
|
143
|
+
command: z.string().optional(),
|
|
144
|
+
args: z.array(z.string()).optional(),
|
|
145
|
+
env: z.record(z.string()).optional(),
|
|
146
|
+
url: z.string().optional(),
|
|
147
|
+
transport: z.enum(["stdio", "sse", "streamable-http", "inprocess"]).optional(),
|
|
148
|
+
headers: z.record(z.string()).optional(),
|
|
149
|
+
}))
|
|
150
|
+
.default({}),
|
|
151
|
+
/**
|
|
152
|
+
* Skill names hidden from the LLM. Names include the full
|
|
153
|
+
* "<plugin>:<skill>" prefix for plugin skills. Filtered at the
|
|
154
|
+
* scanner so PromptComposer's skills listing and the skill builtin
|
|
155
|
+
* tool both see the filtered set — see scanSkills(opts).
|
|
156
|
+
*/
|
|
157
|
+
disabledSkills: z.array(z.string()).default([]),
|
|
158
|
+
instructions: z
|
|
159
|
+
.object({
|
|
160
|
+
fileName: z.string().default("CODESHELL.md"),
|
|
161
|
+
scanDirs: z.array(z.string()).default([]),
|
|
162
|
+
compatFileNames: z.array(z.string()).default(["CLAUDE.md", "AGENTS.md"]),
|
|
163
|
+
ignoreGitBoundary: z.boolean().default(false),
|
|
164
|
+
})
|
|
165
|
+
.default({}),
|
|
166
|
+
arena: z
|
|
167
|
+
.object({
|
|
168
|
+
participants: z
|
|
169
|
+
.array(z.union([
|
|
170
|
+
// Short form: just a model pool key
|
|
171
|
+
z.string(),
|
|
172
|
+
// Full form: explicit config (backward compat)
|
|
173
|
+
z.object({
|
|
174
|
+
name: z.string(),
|
|
175
|
+
model: z.string(),
|
|
176
|
+
provider: z.string().optional(),
|
|
177
|
+
apiKey: z.string().optional(),
|
|
178
|
+
baseUrl: z.string().optional(),
|
|
179
|
+
}),
|
|
180
|
+
]))
|
|
181
|
+
.default([]),
|
|
182
|
+
})
|
|
183
|
+
.default({}),
|
|
184
|
+
search: z
|
|
185
|
+
.object({
|
|
186
|
+
provider: z.enum(["serper", "tavily", "searxng"]).default("serper"),
|
|
187
|
+
apiKey: z.string().optional(),
|
|
188
|
+
baseUrl: z.string().optional(),
|
|
189
|
+
/**
|
|
190
|
+
* Per-provider credentials bag. Lets the desktop UI keep
|
|
191
|
+
* Serper/Tavily/SearXNG configured simultaneously and flip the
|
|
192
|
+
* default without losing the others. `provider/apiKey/baseUrl`
|
|
193
|
+
* remain authoritative for the *active* provider so legacy
|
|
194
|
+
* readers keep working.
|
|
195
|
+
*/
|
|
196
|
+
providers: z
|
|
197
|
+
.record(z.enum(["serper", "tavily", "searxng"]), z.object({
|
|
198
|
+
apiKey: z.string().optional(),
|
|
199
|
+
baseUrl: z.string().optional(),
|
|
200
|
+
}))
|
|
201
|
+
.optional(),
|
|
202
|
+
})
|
|
203
|
+
.default({}),
|
|
204
|
+
output: z
|
|
205
|
+
.object({
|
|
206
|
+
format: z.enum(["text", "json", "jsonl", "stream-json"]).default("text"),
|
|
207
|
+
})
|
|
208
|
+
.default({}),
|
|
209
|
+
/**
|
|
210
|
+
* OS-level sandbox for shell-tool execution. "auto" picks per platform:
|
|
211
|
+
* Seatbelt on macOS, bubblewrap on Linux when installed, otherwise off.
|
|
212
|
+
* Defaults are applied per Engine run depending on headless vs REPL —
|
|
213
|
+
* see Engine.run() and run.ts.
|
|
214
|
+
*/
|
|
215
|
+
sandbox: z
|
|
216
|
+
.object({
|
|
217
|
+
mode: z.enum(["off", "auto", "seatbelt", "bwrap"]).optional(),
|
|
218
|
+
writableRoots: z.array(z.string()).optional(),
|
|
219
|
+
deniedReads: z.array(z.string()).optional(),
|
|
220
|
+
network: z.enum(["allow", "deny"]).optional(),
|
|
221
|
+
})
|
|
222
|
+
.optional(),
|
|
223
|
+
/**
|
|
224
|
+
* Shell-hook configuration. Each entry binds a HookEventName to a
|
|
225
|
+
* shell command; the command receives ctx JSON on stdin and returns
|
|
226
|
+
* a HookResult JSON on stdout (or exit 2 = deny with stderr as
|
|
227
|
+
* reason). See src/hooks/shell-runner.ts for the wire protocol.
|
|
228
|
+
*
|
|
229
|
+
* The event field is loose-typed here (z.string()) because adding
|
|
230
|
+
* new lifecycle events shouldn't force a schema bump; the runner
|
|
231
|
+
* silently ignores entries whose event isn't registered.
|
|
232
|
+
*/
|
|
233
|
+
hooks: z
|
|
234
|
+
.array(z.object({
|
|
235
|
+
event: z.string(),
|
|
236
|
+
command: z.string().min(1),
|
|
237
|
+
matcher: z.string().optional(),
|
|
238
|
+
timeout_ms: z.number().int().positive().optional(),
|
|
239
|
+
cwd: z.string().optional(),
|
|
240
|
+
}))
|
|
241
|
+
.optional(),
|
|
242
|
+
})
|
|
243
|
+
.passthrough();
|
|
244
|
+
export function validateSettings(raw) {
|
|
245
|
+
return SettingsSchema.parse(raw);
|
|
246
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter parser for SKILL.md files. Byte-compatible with Claude Code's
|
|
3
|
+
* `utils/frontmatterParser.ts` so community skill repositories can be reused
|
|
4
|
+
* without modification.
|
|
5
|
+
*/
|
|
6
|
+
export declare const FRONTMATTER_REGEX: RegExp;
|
|
7
|
+
export interface ParsedFrontmatter {
|
|
8
|
+
frontmatter: Record<string, unknown>;
|
|
9
|
+
body: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseFrontmatter(raw: string): ParsedFrontmatter;
|
|
12
|
+
export declare function quoteProblematicValues(frontmatterText: string): string;
|
|
13
|
+
export declare function coerceDescription(value: unknown): string;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontmatter parser for SKILL.md files. Byte-compatible with Claude Code's
|
|
3
|
+
* `utils/frontmatterParser.ts` so community skill repositories can be reused
|
|
4
|
+
* without modification.
|
|
5
|
+
*/
|
|
6
|
+
import { parse as parseYaml } from "yaml";
|
|
7
|
+
export const FRONTMATTER_REGEX = /^---\s*\n([\s\S]*?)---\s*\n?/;
|
|
8
|
+
const YAML_SPECIAL_CHARS = /[{}[\]*&#!|>%@`]|: /;
|
|
9
|
+
export function parseFrontmatter(raw) {
|
|
10
|
+
const match = raw.match(FRONTMATTER_REGEX);
|
|
11
|
+
if (!match) {
|
|
12
|
+
return { frontmatter: {}, body: raw };
|
|
13
|
+
}
|
|
14
|
+
const text = match[1] ?? "";
|
|
15
|
+
const body = raw.slice(match[0].length);
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = parseYaml(text);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
try {
|
|
22
|
+
parsed = parseYaml(quoteProblematicValues(text));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return { frontmatter: {}, body };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
29
|
+
return { frontmatter: parsed, body };
|
|
30
|
+
}
|
|
31
|
+
return { frontmatter: {}, body };
|
|
32
|
+
}
|
|
33
|
+
export function quoteProblematicValues(frontmatterText) {
|
|
34
|
+
const lines = frontmatterText.split("\n");
|
|
35
|
+
const result = [];
|
|
36
|
+
for (const line of lines) {
|
|
37
|
+
const m = line.match(/^([a-zA-Z_-]+):\s+(.+)$/);
|
|
38
|
+
if (!m) {
|
|
39
|
+
result.push(line);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const key = m[1];
|
|
43
|
+
const value = m[2];
|
|
44
|
+
if (!key || !value) {
|
|
45
|
+
result.push(line);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
49
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
50
|
+
result.push(line);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (YAML_SPECIAL_CHARS.test(value)) {
|
|
54
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
55
|
+
result.push(`${key}: "${escaped}"`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
result.push(line);
|
|
59
|
+
}
|
|
60
|
+
return result.join("\n");
|
|
61
|
+
}
|
|
62
|
+
export function coerceDescription(value) {
|
|
63
|
+
if (value == null)
|
|
64
|
+
return "";
|
|
65
|
+
if (typeof value === "string")
|
|
66
|
+
return value.trim();
|
|
67
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
68
|
+
return String(value);
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills barrel. Phase A keeps the scanner only. Listing rendering lives in
|
|
3
|
+
* src/tool-system/builtin/skill-prompt.ts so the prompt-formatting layer can
|
|
4
|
+
* grow token-budget logic later without churn here.
|
|
5
|
+
*/
|
|
6
|
+
export { scanSkills, invalidateSkillCache } from "./scanner.js";
|
|
7
|
+
export type { SkillDefinition } from "./scanner.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills barrel. Phase A keeps the scanner only. Listing rendering lives in
|
|
3
|
+
* src/tool-system/builtin/skill-prompt.ts so the prompt-formatting layer can
|
|
4
|
+
* grow token-budget logic later without churn here.
|
|
5
|
+
*/
|
|
6
|
+
export { scanSkills, invalidateSkillCache } from "./scanner.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill scanner — discovers <base>/<name>/SKILL.md files from project + user
|
|
3
|
+
* directories AND from installed plugins. Mirrors Claude Code's
|
|
4
|
+
* `loadSkillsFromSkillsDir` (skills/loadSkillsDir.ts:407) plus plugin
|
|
5
|
+
* integration (utils/plugins/pluginLoader.ts).
|
|
6
|
+
*/
|
|
7
|
+
export interface SkillDefinition {
|
|
8
|
+
/** Directory name; authoritative regardless of frontmatter.name. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** From frontmatter.description, coerced. Empty string if absent or invalid. */
|
|
11
|
+
description: string;
|
|
12
|
+
/** SKILL.md body with frontmatter stripped. */
|
|
13
|
+
content: string;
|
|
14
|
+
/** Absolute path to the SKILL.md file. */
|
|
15
|
+
filePath: string;
|
|
16
|
+
/** Where the skill was loaded from. */
|
|
17
|
+
source: "project" | "user" | "plugin";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options accepted by scanSkills. The disabled-skill filter is applied
|
|
21
|
+
* after the memoized scan returns so the cache stays warm across
|
|
22
|
+
* different filter values — changing `settings.disabledSkills` should
|
|
23
|
+
* never force a re-scan. Names in `disabledSkills` must match the
|
|
24
|
+
* SkillDefinition.name exactly, including any "<plugin>:" prefix —
|
|
25
|
+
* see scanInstalledPlugins() at line ~168 for namespace construction.
|
|
26
|
+
*/
|
|
27
|
+
export interface ScanSkillsOptions {
|
|
28
|
+
disabledSkills?: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare function scanSkills(cwd: string, opts?: ScanSkillsOptions): SkillDefinition[];
|
|
31
|
+
export declare function invalidateSkillCache(): void;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill scanner — discovers <base>/<name>/SKILL.md files from project + user
|
|
3
|
+
* directories AND from installed plugins. Mirrors Claude Code's
|
|
4
|
+
* `loadSkillsFromSkillsDir` (skills/loadSkillsDir.ts:407) plus plugin
|
|
5
|
+
* integration (utils/plugins/pluginLoader.ts).
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { memoize } from "../utils/memoize.js";
|
|
11
|
+
import { parseFrontmatter, coerceDescription } from "./frontmatter.js";
|
|
12
|
+
import { installedPluginsPath, readInstalledPlugins } from "../plugins/installedPlugins.js";
|
|
13
|
+
function userHome() {
|
|
14
|
+
// Honor process.env.HOME so tests (and shell overrides) can redirect the
|
|
15
|
+
// user-skills lookup. node:os homedir() reads from getpwuid and ignores
|
|
16
|
+
// later mutations of process.env.HOME, which is what the test suite relies
|
|
17
|
+
// on. Falls back to homedir() when HOME is unset.
|
|
18
|
+
return process.env.HOME ?? homedir();
|
|
19
|
+
}
|
|
20
|
+
function bases(cwd) {
|
|
21
|
+
return [
|
|
22
|
+
{ dir: join(cwd, ".code-shell", "skills"), source: "project" },
|
|
23
|
+
{ dir: join(userHome(), ".code-shell", "skills"), source: "user" },
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
function isENOENT(e) {
|
|
27
|
+
return (typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT");
|
|
28
|
+
}
|
|
29
|
+
function isInaccessible(e) {
|
|
30
|
+
if (typeof e !== "object" || e === null || !("code" in e))
|
|
31
|
+
return false;
|
|
32
|
+
const code = e.code;
|
|
33
|
+
return code === "EACCES" || code === "EPERM" || code === "EIO";
|
|
34
|
+
}
|
|
35
|
+
function readSkillFile(skillFile) {
|
|
36
|
+
try {
|
|
37
|
+
return readFileSync(skillFile, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (isENOENT(e))
|
|
41
|
+
return null;
|
|
42
|
+
if (isInaccessible(e)) {
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.warn(`[skills] cannot read ${skillFile}: ${e.message}`);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
throw e;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function buildSkillFromFile(filePath, defaultName, source, raw, namePrefix) {
|
|
51
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
52
|
+
const fmName = typeof frontmatter.name === "string" ? frontmatter.name : undefined;
|
|
53
|
+
if (fmName !== undefined && fmName !== defaultName) {
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.warn(`[skills] frontmatter.name "${fmName}" in ${filePath} does not match directory name "${defaultName}"; using directory name`);
|
|
56
|
+
}
|
|
57
|
+
const description = coerceDescription(frontmatter.description);
|
|
58
|
+
const name = namePrefix ? `${namePrefix}:${defaultName}` : defaultName;
|
|
59
|
+
return { name, description, content: body, filePath, source };
|
|
60
|
+
}
|
|
61
|
+
function scanDirBases(bases, results, seen, seenBaseDirs) {
|
|
62
|
+
for (const { dir, source } of bases) {
|
|
63
|
+
if (!existsSync(dir))
|
|
64
|
+
continue;
|
|
65
|
+
let realDir;
|
|
66
|
+
try {
|
|
67
|
+
realDir = realpathSync(dir);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (seenBaseDirs.has(realDir))
|
|
73
|
+
continue;
|
|
74
|
+
seenBaseDirs.add(realDir);
|
|
75
|
+
let entries;
|
|
76
|
+
try {
|
|
77
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
if (isInaccessible(e)) {
|
|
81
|
+
// eslint-disable-next-line no-console
|
|
82
|
+
console.warn(`[skills] cannot read ${dir}: ${e.message}`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
throw e;
|
|
86
|
+
}
|
|
87
|
+
for (const entry of entries) {
|
|
88
|
+
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
89
|
+
continue;
|
|
90
|
+
if (seen.has(entry.name))
|
|
91
|
+
continue;
|
|
92
|
+
const skillFile = join(dir, entry.name, "SKILL.md");
|
|
93
|
+
const raw = readSkillFile(skillFile);
|
|
94
|
+
if (raw === null)
|
|
95
|
+
continue;
|
|
96
|
+
results.push(buildSkillFromFile(skillFile, entry.name, source, raw));
|
|
97
|
+
seen.add(entry.name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function scanInstalledPlugins(results) {
|
|
102
|
+
const data = readInstalledPlugins();
|
|
103
|
+
const pluginSeen = new Set();
|
|
104
|
+
// Stable order so /skills output is deterministic.
|
|
105
|
+
const keys = Object.keys(data.plugins).sort();
|
|
106
|
+
for (const key of keys) {
|
|
107
|
+
const entries = data.plugins[key] ?? [];
|
|
108
|
+
// <plugin>@<marketplace>
|
|
109
|
+
const atIdx = key.lastIndexOf("@");
|
|
110
|
+
const pluginName = atIdx > 0 ? key.slice(0, atIdx) : key;
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
const skillsDir = join(entry.installPath, "skills");
|
|
113
|
+
if (!existsSync(skillsDir))
|
|
114
|
+
continue;
|
|
115
|
+
let dirEntries;
|
|
116
|
+
try {
|
|
117
|
+
dirEntries = readdirSync(skillsDir, { withFileTypes: true });
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
if (isInaccessible(e)) {
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.warn(`[skills] cannot read ${skillsDir}: ${e.message}`);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
for (const dirent of dirEntries) {
|
|
128
|
+
if (!dirent.isDirectory() && !dirent.isSymbolicLink())
|
|
129
|
+
continue;
|
|
130
|
+
const namespacedName = `${pluginName}:${dirent.name}`;
|
|
131
|
+
if (pluginSeen.has(namespacedName))
|
|
132
|
+
continue;
|
|
133
|
+
const skillFile = join(skillsDir, dirent.name, "SKILL.md");
|
|
134
|
+
const raw = readSkillFile(skillFile);
|
|
135
|
+
if (raw === null)
|
|
136
|
+
continue;
|
|
137
|
+
results.push(buildSkillFromFile(skillFile, dirent.name, "plugin", raw, pluginName));
|
|
138
|
+
pluginSeen.add(namespacedName);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function scanOnce(cwd) {
|
|
144
|
+
const results = [];
|
|
145
|
+
const seen = new Set();
|
|
146
|
+
const seenBaseDirs = new Set();
|
|
147
|
+
scanDirBases(bases(cwd), results, seen, seenBaseDirs);
|
|
148
|
+
scanInstalledPlugins(results);
|
|
149
|
+
return results;
|
|
150
|
+
}
|
|
151
|
+
function installedPluginsMtime() {
|
|
152
|
+
const p = installedPluginsPath();
|
|
153
|
+
try {
|
|
154
|
+
return statSync(p).mtimeMs.toString();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return "0";
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const memoized = memoize(scanOnce, (cwd) => `${cwd}\0${userHome()}\0${installedPluginsMtime()}`);
|
|
161
|
+
export function scanSkills(cwd, opts) {
|
|
162
|
+
const all = memoized(cwd);
|
|
163
|
+
const disabled = opts?.disabledSkills;
|
|
164
|
+
if (!disabled || disabled.length === 0)
|
|
165
|
+
return all;
|
|
166
|
+
const set = new Set(disabled);
|
|
167
|
+
return all.filter((s) => !set.has(s.name));
|
|
168
|
+
}
|
|
169
|
+
export function invalidateSkillCache() {
|
|
170
|
+
memoized.cache.clear?.();
|
|
171
|
+
}
|