@cjhyy/code-shell-core 0.5.0-rc.1 → 0.6.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -10
- package/dist/agent/agent-definition-registry.d.ts +21 -3
- package/dist/agent/agent-definition-registry.js +49 -18
- package/dist/agent/agent-definition.d.ts +32 -0
- package/dist/agent/agent-definition.js +49 -4
- package/dist/arena/arena.js +11 -12
- package/dist/arena/context/context-tools.js +47 -6
- package/dist/arena/context/within-root.d.ts +7 -0
- package/dist/arena/context/within-root.js +15 -0
- package/dist/arena/iterate/phases/argue.js +8 -2
- package/dist/arena/iterate/phases/revise.js +1 -1
- package/dist/arena/iterate/phases/tournament.js +3 -3
- package/dist/arena/ledger.js +9 -1
- package/dist/arena/phases/adjudication.js +1 -4
- package/dist/arena/phases/build-consensus.js +1 -4
- package/dist/arena/phases/cross-review.js +2 -8
- package/dist/arena/phases/debate-rounds.js +1 -4
- package/dist/arena/phases/participant-research.js +1 -4
- package/dist/arena/phases/planning-detail-expansion.js +8 -10
- package/dist/arena/planner.js +0 -1
- package/dist/arena/providers/docs.d.ts +1 -0
- package/dist/arena/providers/docs.js +5 -2
- package/dist/arena/providers/repo.d.ts +1 -0
- package/dist/arena/providers/repo.js +5 -2
- package/dist/arena/strategies/utils.d.ts +1 -4
- package/dist/arena/strategies/utils.js +7 -51
- package/dist/arena/transitions.d.ts +7 -2
- package/dist/arena/transitions.js +9 -4
- package/dist/arena/types.d.ts +8 -2
- package/dist/automation/cron-expr.d.ts +41 -0
- package/dist/automation/cron-expr.js +169 -0
- package/dist/automation/index.d.ts +41 -0
- package/dist/automation/index.js +39 -0
- package/dist/automation/runner.d.ts +84 -0
- package/dist/automation/runner.js +92 -0
- package/dist/automation/scheduler.d.ts +194 -0
- package/dist/automation/scheduler.js +623 -0
- package/dist/automation/store.d.ts +39 -0
- package/dist/automation/store.js +122 -0
- package/dist/automation/write-policy.d.ts +34 -0
- package/dist/automation/write-policy.js +113 -0
- package/dist/automation/write-run.d.ts +51 -0
- package/dist/automation/write-run.js +38 -0
- package/dist/capability-control/disabled-lists.d.ts +25 -0
- package/dist/capability-control/disabled-lists.js +57 -0
- package/dist/capability-control/index.d.ts +5 -0
- package/dist/capability-control/index.js +3 -0
- package/dist/capability-control/overlay.d.ts +64 -0
- package/dist/capability-control/overlay.js +116 -0
- package/dist/capability-control/project.d.ts +65 -0
- package/dist/capability-control/project.js +147 -0
- package/dist/capability-control/service.d.ts +70 -0
- package/dist/capability-control/service.js +147 -0
- package/dist/capability-control/types.d.ts +62 -0
- package/dist/capability-control/types.js +17 -0
- package/dist/cc-orchestrator/agent-adapter.d.ts +50 -0
- package/dist/cc-orchestrator/agent-adapter.js +133 -0
- package/dist/cc-orchestrator/cc-capability.d.ts +19 -0
- package/dist/cc-orchestrator/cc-capability.js +53 -0
- package/dist/cc-orchestrator/codex-session-discovery.d.ts +24 -0
- package/dist/cc-orchestrator/codex-session-discovery.js +191 -0
- package/dist/cc-orchestrator/codex-session-history.d.ts +25 -0
- package/dist/cc-orchestrator/codex-session-history.js +187 -0
- package/dist/cc-orchestrator/external-agent-changes.d.ts +19 -0
- package/dist/cc-orchestrator/external-agent-changes.js +214 -0
- package/dist/cc-orchestrator/external-agent-driver.d.ts +18 -0
- package/dist/cc-orchestrator/external-agent-driver.js +69 -0
- package/dist/cc-orchestrator/index.d.ts +8 -0
- package/dist/cc-orchestrator/index.js +8 -0
- package/dist/cc-orchestrator/relevance-judge.d.ts +15 -0
- package/dist/cc-orchestrator/relevance-judge.js +29 -0
- package/dist/cc-orchestrator/session-discovery.d.ts +46 -0
- package/dist/cc-orchestrator/session-discovery.js +125 -0
- package/dist/cc-orchestrator/session-history.d.ts +19 -0
- package/dist/cc-orchestrator/session-history.js +67 -0
- package/dist/cli/agent-server-stdio.d.ts +26 -1
- package/dist/cli/agent-server-stdio.js +221 -28
- package/dist/cli/agent-server-tcp.d.ts +20 -0
- package/dist/cli/agent-server-tcp.js +134 -0
- package/dist/cli/graceful-shutdown.d.ts +27 -0
- package/dist/cli/graceful-shutdown.js +30 -0
- package/dist/context/compaction.d.ts +56 -0
- package/dist/context/compaction.js +209 -15
- package/dist/context/manager.d.ts +0 -20
- package/dist/context/manager.js +25 -41
- package/dist/cost-tracker.js +5 -61
- package/dist/credentials/cipher.d.ts +49 -0
- package/dist/credentials/cipher.js +45 -0
- package/dist/credentials/cookie-jar.d.ts +24 -0
- package/dist/credentials/cookie-jar.js +40 -0
- package/dist/credentials/index.d.ts +7 -0
- package/dist/credentials/index.js +5 -0
- package/dist/credentials/inject-credential-tool.d.ts +20 -0
- package/dist/credentials/inject-credential-tool.js +130 -0
- package/dist/credentials/store.d.ts +72 -0
- package/dist/credentials/store.js +184 -0
- package/dist/credentials/types.d.ts +56 -0
- package/dist/credentials/use-credential-tool.d.ts +29 -0
- package/dist/credentials/use-credential-tool.js +205 -0
- package/dist/credentials/use-gate.d.ts +56 -0
- package/dist/credentials/use-gate.js +52 -0
- package/dist/cron/cron-runtime.d.ts +2 -0
- package/dist/cron/cron-runtime.js +2 -0
- package/dist/cron/cron-store.d.ts +2 -0
- package/dist/cron/cron-store.js +2 -0
- package/dist/cron/scheduler.d.ts +5 -32
- package/dist/cron/scheduler.js +5 -113
- package/dist/data/model-metadata.d.ts +77 -0
- package/dist/data/model-metadata.js +56 -0
- package/dist/data/model-metadata.json +216 -0
- package/dist/data/openrouter-models.d.ts +18 -7
- package/dist/data/openrouter-models.js +35 -8
- package/dist/data/openrouter-sync.js +1 -1
- package/dist/engine/aux-key.d.ts +10 -0
- package/dist/engine/aux-key.js +11 -0
- package/dist/engine/dynamic-tool-defs.d.ts +19 -0
- package/dist/engine/dynamic-tool-defs.js +36 -0
- package/dist/engine/engine.d.ts +431 -108
- package/dist/engine/engine.js +1630 -279
- package/dist/engine/friendly-error.d.ts +18 -0
- package/dist/engine/friendly-error.js +63 -0
- package/dist/engine/goal.d.ts +187 -0
- package/dist/engine/goal.js +196 -0
- package/dist/engine/image-compression.d.ts +81 -0
- package/dist/engine/image-compression.js +186 -0
- package/dist/engine/image-policy.d.ts +165 -0
- package/dist/engine/image-policy.js +189 -0
- package/dist/engine/model-connections-pool.d.ts +17 -0
- package/dist/engine/model-connections-pool.js +66 -0
- package/dist/engine/model-facade.d.ts +10 -0
- package/dist/engine/model-facade.js +25 -0
- package/dist/engine/patch-orphaned-tools.js +3 -0
- package/dist/engine/reactive-threshold.d.ts +13 -0
- package/dist/engine/reactive-threshold.js +17 -0
- package/dist/engine/resolve-llm-config.d.ts +16 -0
- package/dist/engine/resolve-llm-config.js +44 -0
- package/dist/engine/runtime.js +9 -1
- package/dist/engine/sandbox-cache-key.d.ts +10 -0
- package/dist/engine/sandbox-cache-key.js +9 -0
- package/dist/engine/sandbox-config.d.ts +31 -0
- package/dist/engine/sandbox-config.js +38 -0
- package/dist/engine/session-title.d.ts +13 -0
- package/dist/engine/session-title.js +34 -0
- package/dist/engine/session-usage.d.ts +19 -0
- package/dist/engine/session-usage.js +25 -0
- package/dist/engine/steer-queue.d.ts +32 -0
- package/dist/engine/steer-queue.js +26 -0
- package/dist/engine/streaming-tool-queue.d.ts +12 -0
- package/dist/engine/streaming-tool-queue.js +50 -10
- package/dist/engine/turn-loop.d.ts +94 -9
- package/dist/engine/turn-loop.js +775 -342
- package/dist/engine/types.d.ts +175 -0
- package/dist/engine/types.js +13 -0
- package/dist/external-agents/config.d.ts +2 -0
- package/dist/external-agents/config.js +15 -0
- package/dist/external-agents/types.d.ts +31 -0
- package/dist/external-agents/types.js +1 -0
- package/dist/git/parse-log.d.ts +13 -0
- package/dist/git/parse-log.js +21 -0
- package/dist/git/utils.d.ts +8 -6
- package/dist/git/utils.js +62 -26
- package/dist/git/worktree.d.ts +48 -0
- package/dist/git/worktree.js +111 -20
- package/dist/hooks/events.d.ts +23 -1
- package/dist/hooks/goal-stop-hook.d.ts +58 -0
- package/dist/hooks/goal-stop-hook.js +279 -0
- package/dist/hooks/hook-output.d.ts +33 -0
- package/dist/hooks/hook-output.js +79 -0
- package/dist/hooks/registry.d.ts +15 -0
- package/dist/hooks/registry.js +57 -1
- package/dist/hooks/shell-runner.d.ts +2 -0
- package/dist/hooks/shell-runner.js +48 -18
- package/dist/index.d.ts +79 -11
- package/dist/index.js +89 -6
- package/dist/llm/capabilities/param-specs.d.ts +14 -0
- package/dist/llm/capabilities/param-specs.js +62 -0
- package/dist/llm/capabilities/reasoning-control.d.ts +24 -0
- package/dist/llm/capabilities/reasoning-control.js +38 -0
- package/dist/llm/capabilities/rules.js +37 -3
- package/dist/llm/capabilities/types.d.ts +32 -2
- package/dist/llm/clamp-max-tokens.d.ts +11 -0
- package/dist/llm/clamp-max-tokens.js +17 -0
- package/dist/llm/client-base.d.ts +69 -5
- package/dist/llm/client-base.js +185 -25
- package/dist/llm/client-factory.d.ts +3 -3
- package/dist/llm/client-factory.js +2 -2
- package/dist/llm/model-cache.js +4 -2
- package/dist/llm/model-pool.d.ts +29 -11
- package/dist/llm/model-pool.js +36 -20
- package/dist/llm/provider-auth.d.ts +41 -0
- package/dist/llm/provider-auth.js +76 -0
- package/dist/llm/provider-catalog.d.ts +6 -2
- package/dist/llm/providers/anthropic.d.ts +32 -2
- package/dist/llm/providers/anthropic.js +207 -18
- package/dist/llm/providers/openai.d.ts +47 -2
- package/dist/llm/providers/openai.js +478 -71
- package/dist/llm/reasoning-setting.d.ts +51 -0
- package/dist/llm/reasoning-setting.js +40 -0
- package/dist/llm/stop-reason.d.ts +13 -0
- package/dist/llm/stop-reason.js +21 -0
- package/dist/llm/stream-watchdog.js +5 -1
- package/dist/llm/strip-vision.d.ts +32 -0
- package/dist/llm/strip-vision.js +94 -0
- package/dist/llm/token-counter.js +9 -2
- package/dist/llm/types.d.ts +9 -6
- package/dist/logging/logger.js +18 -4
- package/dist/logging/sanitize-messages.d.ts +10 -0
- package/dist/logging/sanitize-messages.js +112 -0
- package/dist/lsp/client.js +28 -8
- package/dist/lsp/manager.d.ts +1 -1
- package/dist/lsp/manager.js +42 -11
- package/dist/lsp/root-path.d.ts +9 -0
- package/dist/lsp/root-path.js +12 -0
- package/dist/model-catalog/builtin.d.ts +12 -0
- package/dist/model-catalog/builtin.js +407 -0
- package/dist/model-catalog/gen-connections.d.ts +20 -0
- package/dist/model-catalog/gen-connections.js +28 -0
- package/dist/model-catalog/index.d.ts +41 -0
- package/dist/model-catalog/index.js +90 -0
- package/dist/model-catalog/params.d.ts +20 -0
- package/dist/model-catalog/params.js +45 -0
- package/dist/model-catalog/resolve.d.ts +48 -0
- package/dist/model-catalog/resolve.js +33 -0
- package/dist/model-catalog/save-entry.d.ts +32 -0
- package/dist/model-catalog/save-entry.js +104 -0
- package/dist/model-catalog/types.d.ts +561 -0
- package/dist/model-catalog/types.js +93 -0
- package/dist/model-catalog/upsert.d.ts +9 -0
- package/dist/model-catalog/upsert.js +8 -0
- package/dist/onboarding.d.ts +12 -82
- package/dist/onboarding.js +75 -333
- package/dist/plugins/gitOps.d.ts +53 -0
- package/dist/plugins/gitOps.js +130 -5
- package/dist/plugins/installer/checkUpdate.d.ts +16 -0
- package/dist/plugins/installer/checkUpdate.js +32 -0
- package/dist/plugins/installer/codex/convertAgents.d.ts +7 -0
- package/dist/plugins/installer/codex/convertAgents.js +55 -0
- package/dist/plugins/installer/codex/convertCommands.d.ts +19 -0
- package/dist/plugins/installer/codex/convertCommands.js +46 -0
- package/dist/plugins/installer/codex/convertMcp.d.ts +11 -0
- package/dist/plugins/installer/codex/convertMcp.js +85 -0
- package/dist/plugins/installer/codex/convertSkills.d.ts +12 -0
- package/dist/plugins/installer/codex/convertSkills.js +33 -0
- package/dist/plugins/installer/detectFormat.d.ts +2 -0
- package/dist/plugins/installer/detectFormat.js +6 -0
- package/dist/plugins/installer/install.d.ts +7 -0
- package/dist/plugins/installer/install.js +123 -0
- package/dist/plugins/installer/installFromArchive.d.ts +43 -0
- package/dist/plugins/installer/installFromArchive.js +134 -0
- package/dist/plugins/installer/installFromSource.d.ts +13 -0
- package/dist/plugins/installer/installFromSource.js +51 -0
- package/dist/plugins/installer/list.d.ts +9 -0
- package/dist/plugins/installer/list.js +30 -0
- package/dist/plugins/installer/loadPluginAgents.d.ts +3 -0
- package/dist/plugins/installer/loadPluginAgents.js +27 -0
- package/dist/plugins/installer/loadPluginMcp.d.ts +14 -0
- package/dist/plugins/installer/loadPluginMcp.js +107 -0
- package/dist/plugins/installer/parseSource.d.ts +20 -0
- package/dist/plugins/installer/parseSource.js +74 -0
- package/dist/plugins/installer/paths.d.ts +5 -0
- package/dist/plugins/installer/paths.js +25 -0
- package/dist/plugins/installer/pruneDisabled.d.ts +24 -0
- package/dist/plugins/installer/pruneDisabled.js +73 -0
- package/dist/plugins/installer/types.d.ts +52 -0
- package/dist/plugins/installer/types.js +28 -0
- package/dist/plugins/installer/uninstall.d.ts +2 -0
- package/dist/plugins/installer/uninstall.js +18 -0
- package/dist/plugins/installer/unzip.d.ts +14 -0
- package/dist/plugins/installer/unzip.js +82 -0
- package/dist/plugins/installer/update.d.ts +28 -0
- package/dist/plugins/installer/update.js +97 -0
- package/dist/plugins/loadPluginHooks.d.ts +54 -1
- package/dist/plugins/loadPluginHooks.js +83 -1
- package/dist/plugins/marketplaceManager.d.ts +15 -1
- package/dist/plugins/marketplaceManager.js +58 -4
- package/dist/plugins/pluginCommandHook.js +34 -14
- package/dist/plugins/pluginContent.d.ts +30 -0
- package/dist/plugins/pluginContent.js +83 -0
- package/dist/plugins/pluginInstaller.d.ts +34 -0
- package/dist/plugins/pluginInstaller.js +168 -35
- package/dist/plugins/schemas.js +41 -6
- package/dist/plugins/types.d.ts +10 -0
- package/dist/preset/index.d.ts +7 -1
- package/dist/preset/index.js +112 -6
- package/dist/product/types.d.ts +1 -1
- package/dist/prompt/composer.d.ts +31 -0
- package/dist/prompt/composer.js +95 -25
- package/dist/prompt/instruction-scanner.js +5 -3
- package/dist/prompt/section-loader.js +1 -0
- package/dist/prompt/sections/base.md +1 -0
- package/dist/prompt/sections/browser.md +10 -0
- package/dist/prompt/sections/coding.md +4 -0
- package/dist/prompt/sections/orchestration.md +8 -0
- package/dist/protocol/chat-session-manager.d.ts +15 -2
- package/dist/protocol/chat-session-manager.js +46 -0
- package/dist/protocol/chat-session.d.ts +82 -0
- package/dist/protocol/chat-session.js +121 -1
- package/dist/protocol/client.d.ts +27 -0
- package/dist/protocol/client.js +38 -0
- package/dist/protocol/redact.d.ts +50 -0
- package/dist/protocol/redact.js +71 -0
- package/dist/protocol/server.d.ts +153 -2
- package/dist/protocol/server.js +807 -39
- package/dist/protocol/tcp-transport.d.ts +45 -0
- package/dist/protocol/tcp-transport.js +74 -0
- package/dist/protocol/transport.js +3 -2
- package/dist/protocol/types.d.ts +69 -0
- package/dist/protocol/types.js +22 -0
- package/dist/quota/credentials.d.ts +3 -0
- package/dist/quota/credentials.js +80 -0
- package/dist/quota/index.d.ts +36 -0
- package/dist/quota/index.js +155 -0
- package/dist/quota/types.d.ts +48 -0
- package/dist/quota/types.js +13 -0
- package/dist/remote/bridge.d.ts +11 -2
- package/dist/remote/bridge.js +61 -33
- package/dist/review/review-prompt.d.ts +28 -0
- package/dist/review/review-prompt.js +81 -0
- package/dist/run/ArtifactTracker.js +5 -4
- package/dist/run/EngineRunner.d.ts +27 -1
- package/dist/run/EngineRunner.js +46 -8
- package/dist/run/FileRunStore.js +40 -11
- package/dist/run/RunApprovalBackend.js +25 -5
- package/dist/run/RunLock.d.ts +28 -2
- package/dist/run/RunLock.js +49 -7
- package/dist/run/RunManager.d.ts +12 -0
- package/dist/run/RunManager.js +86 -3
- package/dist/run/RunQueue.d.ts +1 -0
- package/dist/run/RunQueue.js +8 -2
- package/dist/run/factory.d.ts +8 -1
- package/dist/run/factory.js +1 -0
- package/dist/run/index.d.ts +2 -2
- package/dist/run/index.js +1 -1
- package/dist/run/redirect-target.d.ts +7 -0
- package/dist/run/redirect-target.js +13 -0
- package/dist/run/types.js +1 -1
- package/dist/runtime/background-shell.d.ts +139 -0
- package/dist/runtime/background-shell.js +495 -0
- package/dist/runtime/output-clean.d.ts +24 -0
- package/dist/runtime/output-clean.js +41 -0
- package/dist/runtime/ring-file.d.ts +64 -0
- package/dist/runtime/ring-file.js +174 -0
- package/dist/runtime/safe-spawn.js +15 -34
- package/dist/runtime/spawn-common.d.ts +148 -0
- package/dist/runtime/spawn-common.js +303 -0
- package/dist/runtime/truncate-output.d.ts +22 -0
- package/dist/runtime/truncate-output.js +49 -0
- package/dist/runtime/utf8-cut.d.ts +11 -0
- package/dist/runtime/utf8-cut.js +23 -0
- package/dist/services/auto-dream.d.ts +4 -0
- package/dist/services/auto-dream.js +26 -26
- package/dist/services/browser-open.d.ts +13 -0
- package/dist/services/browser-open.js +16 -0
- package/dist/services/diagnostics.d.ts +1 -2
- package/dist/services/diagnostics.js +12 -7
- package/dist/services/dream-consolidation.d.ts +57 -0
- package/dist/services/dream-consolidation.js +151 -0
- package/dist/services/extract-memories.d.ts +14 -1
- package/dist/services/extract-memories.js +45 -6
- package/dist/services/memory-orchestrator.d.ts +21 -0
- package/dist/services/memory-orchestrator.js +125 -32
- package/dist/services/notifier.d.ts +8 -0
- package/dist/services/notifier.js +39 -25
- package/dist/services/oauth.js +5 -7
- package/dist/services/session-memory-sort.d.ts +8 -0
- package/dist/services/session-memory-sort.js +9 -0
- package/dist/services/session-memory.js +30 -19
- package/dist/session/file-history.d.ts +124 -1
- package/dist/session/file-history.js +232 -9
- package/dist/session/memory.d.ts +116 -2
- package/dist/session/memory.js +250 -28
- package/dist/session/session-manager.d.ts +63 -1
- package/dist/session/session-manager.js +186 -5
- package/dist/session/simple-diff.d.ts +23 -0
- package/dist/session/simple-diff.js +84 -0
- package/dist/session/transcript.d.ts +25 -1
- package/dist/session/transcript.js +35 -2
- package/dist/session/undo-target.d.ts +67 -0
- package/dist/session/undo-target.js +144 -0
- package/dist/settings/disk-defaults.d.ts +42 -0
- package/dist/settings/disk-defaults.js +33 -0
- package/dist/settings/feature-flags.d.ts +64 -0
- package/dist/settings/feature-flags.js +61 -0
- package/dist/settings/manager.d.ts +101 -1
- package/dist/settings/manager.js +345 -15
- package/dist/settings/migrate-config.d.ts +45 -0
- package/dist/settings/migrate-config.js +125 -0
- package/dist/settings/personalization.d.ts +19 -0
- package/dist/settings/personalization.js +7 -0
- package/dist/settings/schema-export.d.ts +25 -0
- package/dist/settings/schema-export.js +38 -0
- package/dist/settings/schema.d.ts +1827 -396
- package/dist/settings/schema.js +361 -81
- package/dist/skills/scanner.d.ts +9 -0
- package/dist/skills/scanner.js +30 -2
- package/dist/stt/resolve-transcribe.d.ts +31 -0
- package/dist/stt/resolve-transcribe.js +108 -0
- package/dist/stt/transcribe.d.ts +51 -0
- package/dist/stt/transcribe.js +65 -0
- package/dist/tool-system/browser-bridge.d.ts +226 -0
- package/dist/tool-system/browser-bridge.js +163 -0
- package/dist/tool-system/builtin/add-marketplace.d.ts +12 -0
- package/dist/tool-system/builtin/add-marketplace.js +76 -0
- package/dist/tool-system/builtin/agent-heartbeat.d.ts +49 -0
- package/dist/tool-system/builtin/agent-heartbeat.js +89 -0
- package/dist/tool-system/builtin/agent-notifications.d.ts +12 -3
- package/dist/tool-system/builtin/agent-notifications.js +9 -3
- package/dist/tool-system/builtin/agent-output-file.d.ts +38 -0
- package/dist/tool-system/builtin/agent-output-file.js +72 -0
- package/dist/tool-system/builtin/agent-registry.d.ts +23 -0
- package/dist/tool-system/builtin/agent-registry.js +16 -4
- package/dist/tool-system/builtin/agent.d.ts +50 -11
- package/dist/tool-system/builtin/agent.js +576 -73
- package/dist/tool-system/builtin/apply-patch/applier.js +66 -8
- package/dist/tool-system/builtin/apply-patch/backup-targets.d.ts +10 -0
- package/dist/tool-system/builtin/apply-patch/backup-targets.js +30 -0
- package/dist/tool-system/builtin/apply-patch/index.js +7 -3
- package/dist/tool-system/builtin/arena.js +6 -7
- package/dist/tool-system/builtin/background-jobs.d.ts +76 -0
- package/dist/tool-system/builtin/background-jobs.js +124 -0
- package/dist/tool-system/builtin/background-shell-tools.d.ts +20 -0
- package/dist/tool-system/builtin/background-shell-tools.js +108 -0
- package/dist/tool-system/builtin/background-work.d.ts +67 -0
- package/dist/tool-system/builtin/background-work.js +86 -0
- package/dist/tool-system/builtin/bash-output-style.d.ts +32 -0
- package/dist/tool-system/builtin/bash-output-style.js +40 -0
- package/dist/tool-system/builtin/bash.d.ts +5 -2
- package/dist/tool-system/builtin/bash.js +98 -62
- package/dist/tool-system/builtin/browser-tools.d.ts +33 -0
- package/dist/tool-system/builtin/browser-tools.js +312 -0
- package/dist/tool-system/builtin/cancel-goal.d.ts +31 -0
- package/dist/tool-system/builtin/cancel-goal.js +64 -0
- package/dist/tool-system/builtin/check-quota.d.ts +15 -0
- package/dist/tool-system/builtin/check-quota.js +34 -0
- package/dist/tool-system/builtin/complete-goal.d.ts +25 -0
- package/dist/tool-system/builtin/complete-goal.js +45 -0
- package/dist/tool-system/builtin/config.js +7 -0
- package/dist/tool-system/builtin/cron.d.ts +7 -0
- package/dist/tool-system/builtin/cron.js +105 -9
- package/dist/tool-system/builtin/drive-claude-code.d.ts +30 -0
- package/dist/tool-system/builtin/drive-claude-code.js +157 -0
- package/dist/tool-system/builtin/edit-model-catalog.d.ts +3 -0
- package/dist/tool-system/builtin/edit-model-catalog.js +94 -0
- package/dist/tool-system/builtin/edit.d.ts +2 -1
- package/dist/tool-system/builtin/edit.js +21 -12
- package/dist/tool-system/builtin/eol.d.ts +29 -0
- package/dist/tool-system/builtin/eol.js +37 -0
- package/dist/tool-system/builtin/file-cache.d.ts +6 -0
- package/dist/tool-system/builtin/file-cache.js +8 -0
- package/dist/tool-system/builtin/generate-image.d.ts +60 -0
- package/dist/tool-system/builtin/generate-image.js +374 -0
- package/dist/tool-system/builtin/generate-video.d.ts +55 -0
- package/dist/tool-system/builtin/generate-video.js +361 -0
- package/dist/tool-system/builtin/grep.js +6 -2
- package/dist/tool-system/builtin/image-providers.d.ts +86 -0
- package/dist/tool-system/builtin/image-providers.js +190 -0
- package/dist/tool-system/builtin/image-uploader.d.ts +33 -0
- package/dist/tool-system/builtin/image-uploader.js +74 -0
- package/dist/tool-system/builtin/index.d.ts +24 -1
- package/dist/tool-system/builtin/index.js +310 -25
- package/dist/tool-system/builtin/mcp-tools.js +23 -3
- package/dist/tool-system/builtin/memory.js +45 -7
- package/dist/tool-system/builtin/notebook-edit.d.ts +2 -1
- package/dist/tool-system/builtin/notebook-edit.js +1 -1
- package/dist/tool-system/builtin/powershell.js +4 -1
- package/dist/tool-system/builtin/read.d.ts +2 -1
- package/dist/tool-system/builtin/read.js +11 -3
- package/dist/tool-system/builtin/repl.js +4 -1
- package/dist/tool-system/builtin/skill.js +9 -0
- package/dist/tool-system/builtin/sleep.js +12 -5
- package/dist/tool-system/builtin/task.js +4 -1
- package/dist/tool-system/builtin/tool-search.js +25 -7
- package/dist/tool-system/builtin/update-automation-memory.d.ts +24 -0
- package/dist/tool-system/builtin/update-automation-memory.js +60 -0
- package/dist/tool-system/builtin/video-providers.d.ts +154 -0
- package/dist/tool-system/builtin/video-providers.js +235 -0
- package/dist/tool-system/builtin/view-image.d.ts +18 -0
- package/dist/tool-system/builtin/view-image.js +96 -0
- package/dist/tool-system/builtin/web-fetch.js +12 -2
- package/dist/tool-system/builtin/web-search.d.ts +4 -1
- package/dist/tool-system/builtin/web-search.js +57 -10
- package/dist/tool-system/builtin/worktree.d.ts +2 -1
- package/dist/tool-system/builtin/worktree.js +31 -4
- package/dist/tool-system/builtin/write.d.ts +2 -1
- package/dist/tool-system/builtin/write.js +1 -1
- package/dist/tool-system/context.d.ts +166 -6
- package/dist/tool-system/executor.d.ts +3 -2
- package/dist/tool-system/executor.js +197 -119
- package/dist/tool-system/investigation-guard.d.ts +4 -1
- package/dist/tool-system/investigation-guard.js +20 -4
- package/dist/tool-system/mcp-manager.d.ts +78 -16
- package/dist/tool-system/mcp-manager.js +357 -28
- package/dist/tool-system/path-policy.d.ts +99 -0
- package/dist/tool-system/path-policy.js +578 -0
- package/dist/tool-system/permission.d.ts +36 -1
- package/dist/tool-system/permission.js +322 -117
- package/dist/tool-system/plan-mode-allowlist.d.ts +32 -0
- package/dist/tool-system/plan-mode-allowlist.js +65 -0
- package/dist/tool-system/registry.d.ts +1 -0
- package/dist/tool-system/registry.js +26 -1
- package/dist/tool-system/sandbox/index.d.ts +8 -0
- package/dist/tool-system/sandbox/index.js +7 -2
- package/dist/tool-system/validate-tool-metadata.d.ts +36 -0
- package/dist/tool-system/validate-tool-metadata.js +63 -0
- package/dist/tool-system/validation.d.ts +10 -0
- package/dist/tool-system/validation.js +16 -3
- package/dist/types.d.ts +301 -15
- package/dist/updater.js +20 -9
- package/dist/utils/envUtils.d.ts +0 -9
- package/dist/utils/envUtils.js +3 -28
- package/dist/utils/exec.d.ts +40 -0
- package/dist/utils/exec.js +144 -0
- package/dist/utils/format.js +4 -2
- package/dist/utils/json.d.ts +12 -0
- package/dist/utils/json.js +92 -0
- package/dist/utils/lockfile.js +9 -2
- package/dist/utils/theme.d.ts +7 -1
- package/dist/utils/theme.js +5 -3
- package/dist/utils/toolDisplay.js +0 -1
- package/package.json +14 -7
- package/dist/agent/coordinator.d.ts +0 -49
- package/dist/agent/coordinator.js +0 -77
- package/dist/settings/manager.test.js +0 -73
- package/dist/tool-system/builtin/remote-trigger.d.ts +0 -6
- package/dist/tool-system/builtin/remote-trigger.js +0 -54
- package/dist/tool-system/builtin/send-message.d.ts +0 -6
- package/dist/tool-system/builtin/send-message.js +0 -47
- /package/dist/{settings/manager.test.d.ts → credentials/types.js} +0 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
UI-agnostic agent orchestration framework. The headless core of [`code-shell`](https://github.com/cjhyy/codeshell): turn an LLM + a tool registry + a transcript into a multi-turn agent loop, with permissions, hooks, MCP support, and pluggable approval backends.
|
|
4
4
|
|
|
5
|
-
Compatible with Anthropic and OpenAI-protocol providers (Claude, DeepSeek, GPT, Gemini, Qwen, …). No terminal UI dependencies — embed it in a CLI, a web service, a Slack bot, a desktop app.
|
|
5
|
+
Compatible with Anthropic and OpenAI-protocol providers (Claude, DeepSeek, GPT, Gemini, Qwen, …). No terminal UI dependencies — embed it in a CLI, a web service, a Slack bot, a desktop app. This is a Node.js runtime package, not a browser SDK.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ npm install @cjhyy/code-shell-core
|
|
|
12
12
|
bun add @cjhyy/code-shell-core
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Requires Node ≥ 20.10.
|
|
15
|
+
Requires Node ≥ 20.10 and an ESM-capable runtime.
|
|
16
16
|
|
|
17
17
|
## Quickstart
|
|
18
18
|
|
|
@@ -29,8 +29,10 @@ const engine = new Engine({
|
|
|
29
29
|
apiKey: process.env.ANTHROPIC_API_KEY!,
|
|
30
30
|
},
|
|
31
31
|
cwd: process.cwd(),
|
|
32
|
-
// Headless approval — "approve-all" trusts the model fully
|
|
33
|
-
// "approve-read-only"
|
|
32
|
+
// Headless approval — "approve-all" trusts the model fully and is
|
|
33
|
+
// only appropriate for local/trusted prompts. Use "approve-read-only",
|
|
34
|
+
// explicit permissionMode/tool allowlists, or a custom ApprovalBackend
|
|
35
|
+
// in production.
|
|
34
36
|
approvalBackend: new HeadlessApprovalBackend("approve-all"),
|
|
35
37
|
headless: true,
|
|
36
38
|
});
|
|
@@ -78,7 +80,7 @@ new Engine({
|
|
|
78
80
|
|
|
79
81
|
## Designing for production
|
|
80
82
|
|
|
81
|
-
- **Approval backend.** `HeadlessApprovalBackend("approve-all")` is fine for trusted prompts. For untrusted input, implement `ApprovalBackend` to gate destructive tools (Write/Edit/Bash) through your own auth.
|
|
83
|
+
- **Approval backend.** `HeadlessApprovalBackend("approve-all")` is fine only for local/trusted prompts. For untrusted input, explicitly set `permissionMode`, restrict tools with `enabledBuiltinTools` / `disabledBuiltinTools`, or implement `ApprovalBackend` to gate destructive tools (Write/Edit/Bash) through your own auth.
|
|
82
84
|
- **Permission rules.** Pass `permissionRules` to the engine for fine-grained allow/deny per tool + args pattern. Bash commands additionally get a built-in safety classifier (dangerous commands like `rm -rf` always require explicit approval).
|
|
83
85
|
- **Hooks** are the right place for audit logging, prompt rewriting, and policy enforcement.
|
|
84
86
|
- **Memory.** The engine ships with an extract-memories + auto-dream pipeline that persists to `~/.code-shell/memory/`. Disable by passing a no-op `MemoryOrchestrator`, or scope to a project by setting `CODE_SHELL_HOME`.
|
|
@@ -144,11 +146,12 @@ These exports are covered by the stability promise:
|
|
|
144
146
|
|
|
145
147
|
### Treat as internal
|
|
146
148
|
|
|
147
|
-
Anything not in the table above — including
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
Anything not in the table above — including root-entry exports for
|
|
150
|
+
product/runtime helpers and direct imports from `./engine/...`,
|
|
151
|
+
`./tool-system/...`, `./session/...`, `./hooks/...` subpaths — is
|
|
152
|
+
experimental/internal unless explicitly documented otherwise, and may
|
|
153
|
+
change between minor versions without notice. Plan to migrate via the
|
|
154
|
+
protocol surface instead of deep-importing.
|
|
152
155
|
|
|
153
156
|
## Stability
|
|
154
157
|
|
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
import { type AgentDefinition } from "./agent-definition.js";
|
|
2
|
+
export interface AgentSourceDir {
|
|
3
|
+
dir: string;
|
|
4
|
+
source: "project" | "user" | "plugin";
|
|
5
|
+
/** For source === "plugin": the owning plugin name, carried onto each def
|
|
6
|
+
* so the spawn layer can namespace bare skill allowlists. */
|
|
7
|
+
pluginName?: string;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
|
-
* Loads reusable sub-agent role definitions from
|
|
4
|
-
* Non-recursive. Malformed files are skipped with a
|
|
5
|
-
* failing the whole load — one bad role file must
|
|
10
|
+
* Loads reusable sub-agent role definitions from one or more directories
|
|
11
|
+
* of `*.md` files. Non-recursive. Malformed files are skipped with a
|
|
12
|
+
* warning rather than failing the whole load — one bad role file must
|
|
13
|
+
* not break the agent system.
|
|
14
|
+
*
|
|
15
|
+
* When multiple dirs define the same role name, the LAST dir wins. This is
|
|
16
|
+
* pure mechanism — the project>user POLICY lives in the caller's dir ORDER
|
|
17
|
+
* (loadAgentDefinitionsForCwd passes [user, ...plugins, project] so a repo's
|
|
18
|
+
* in-tree agent wins; see spec §7.2). The shadowing def is marked
|
|
19
|
+
* `override: true` and records the sources it shadowed in `shadowedSources`.
|
|
20
|
+
* Names in `disabled` are filtered out entirely after the merge, so the LLM
|
|
21
|
+
* never sees them.
|
|
6
22
|
*/
|
|
7
23
|
export declare class AgentDefinitionRegistry {
|
|
8
24
|
private defs;
|
|
9
25
|
readonly warnings: string[];
|
|
26
|
+
/** Back-compat single-dir loader (project source, no disabled filter). */
|
|
10
27
|
static loadFromDir(dir: string): AgentDefinitionRegistry;
|
|
28
|
+
static loadFromDirs(dirs: AgentSourceDir[], disabled: string[]): AgentDefinitionRegistry;
|
|
11
29
|
has(name: string): boolean;
|
|
12
30
|
get(name: string): AgentDefinition | undefined;
|
|
13
31
|
list(): AgentDefinition[];
|
|
@@ -2,35 +2,66 @@ import { readdirSync, readFileSync, existsSync, statSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { parseAgentDefinition } from "./agent-definition.js";
|
|
4
4
|
/**
|
|
5
|
-
* Loads reusable sub-agent role definitions from
|
|
6
|
-
* Non-recursive. Malformed files are skipped with a
|
|
7
|
-
* failing the whole load — one bad role file must
|
|
5
|
+
* Loads reusable sub-agent role definitions from one or more directories
|
|
6
|
+
* of `*.md` files. Non-recursive. Malformed files are skipped with a
|
|
7
|
+
* warning rather than failing the whole load — one bad role file must
|
|
8
|
+
* not break the agent system.
|
|
9
|
+
*
|
|
10
|
+
* When multiple dirs define the same role name, the LAST dir wins. This is
|
|
11
|
+
* pure mechanism — the project>user POLICY lives in the caller's dir ORDER
|
|
12
|
+
* (loadAgentDefinitionsForCwd passes [user, ...plugins, project] so a repo's
|
|
13
|
+
* in-tree agent wins; see spec §7.2). The shadowing def is marked
|
|
14
|
+
* `override: true` and records the sources it shadowed in `shadowedSources`.
|
|
15
|
+
* Names in `disabled` are filtered out entirely after the merge, so the LLM
|
|
16
|
+
* never sees them.
|
|
8
17
|
*/
|
|
9
18
|
export class AgentDefinitionRegistry {
|
|
10
19
|
defs = new Map();
|
|
11
20
|
warnings = [];
|
|
21
|
+
/** Back-compat single-dir loader (project source, no disabled filter). */
|
|
12
22
|
static loadFromDir(dir) {
|
|
23
|
+
return AgentDefinitionRegistry.loadFromDirs([{ dir, source: "project" }], []);
|
|
24
|
+
}
|
|
25
|
+
static loadFromDirs(dirs, disabled) {
|
|
13
26
|
const reg = new AgentDefinitionRegistry();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
for (const entry of readdirSync(dir).sort()) {
|
|
17
|
-
if (!entry.endsWith(".md"))
|
|
27
|
+
for (const { dir, source, pluginName } of dirs) {
|
|
28
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory())
|
|
18
29
|
continue;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
if (!statSync(full).isFile())
|
|
22
|
-
continue;
|
|
23
|
-
const def = parseAgentDefinition(readFileSync(full, "utf8"), entry);
|
|
24
|
-
if (reg.defs.has(def.name)) {
|
|
25
|
-
reg.warnings.push(`${entry}: duplicate agent name '${def.name}' ignored (first definition wins)`);
|
|
30
|
+
for (const entry of readdirSync(dir).sort()) {
|
|
31
|
+
if (!entry.endsWith(".md"))
|
|
26
32
|
continue;
|
|
33
|
+
const full = join(dir, entry);
|
|
34
|
+
try {
|
|
35
|
+
if (!statSync(full).isFile())
|
|
36
|
+
continue;
|
|
37
|
+
const def = parseAgentDefinition(readFileSync(full, "utf8"), entry);
|
|
38
|
+
def.source = source;
|
|
39
|
+
if (pluginName)
|
|
40
|
+
def.pluginName = pluginName;
|
|
41
|
+
def.filePath = full;
|
|
42
|
+
// A later dir overriding an earlier one. Carry forward the shadowed
|
|
43
|
+
// sources (the prev def's own source + anything it already shadowed)
|
|
44
|
+
// so a project def that shadows a plugin def that shadowed a user
|
|
45
|
+
// def reports both.
|
|
46
|
+
const prev = reg.defs.get(def.name);
|
|
47
|
+
if (prev) {
|
|
48
|
+
def.override = true;
|
|
49
|
+
const shadowed = new Set(prev.shadowedSources ?? []);
|
|
50
|
+
if (prev.source)
|
|
51
|
+
shadowed.add(prev.source);
|
|
52
|
+
def.shadowedSources = [...shadowed];
|
|
53
|
+
}
|
|
54
|
+
reg.defs.set(def.name, def);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
reg.warnings.push(`${entry}: ${err.message}`);
|
|
27
58
|
}
|
|
28
|
-
reg.defs.set(def.name, def);
|
|
29
|
-
}
|
|
30
|
-
catch (err) {
|
|
31
|
-
reg.warnings.push(`${entry}: ${err.message}`);
|
|
32
59
|
}
|
|
33
60
|
}
|
|
61
|
+
// Filter disabled roles after the merge so a user override of a
|
|
62
|
+
// disabled name is still removed.
|
|
63
|
+
for (const name of new Set(disabled))
|
|
64
|
+
reg.defs.delete(name);
|
|
34
65
|
return reg;
|
|
35
66
|
}
|
|
36
67
|
has(name) {
|
|
@@ -10,11 +10,43 @@ export interface AgentDefinition {
|
|
|
10
10
|
maxTurns?: number;
|
|
11
11
|
/** Optional tool allowlist. Undefined → inherit parent's full tool set. */
|
|
12
12
|
tools?: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Optional skill allowlist. Undefined → inherit the parent's full skill
|
|
15
|
+
* pool (every non-disabled skill in the project). When set, the sub-agent
|
|
16
|
+
* physically only sees these skills: they're the only ones listed in its
|
|
17
|
+
* system prompt and the only ones it may invoke. Empty array → no skills.
|
|
18
|
+
*/
|
|
19
|
+
skills?: string[];
|
|
13
20
|
/** Markdown body — becomes the child Engine's appendSystemPrompt. */
|
|
14
21
|
systemPrompt: string;
|
|
22
|
+
/** Where this def was loaded from. Runtime-only; never serialized. */
|
|
23
|
+
source?: "project" | "user" | "plugin";
|
|
24
|
+
/**
|
|
25
|
+
* Owning plugin name when source === "plugin" (e.g. "mimi-video"). Runtime-
|
|
26
|
+
* only; never serialized. Used to namespace this agent's bare skill
|
|
27
|
+
* allowlist into `<pluginName>:<skill>` at spawn time, since a plugin's
|
|
28
|
+
* frontmatter references its own skills by bare name (CC convention) but
|
|
29
|
+
* the scanner registers them namespaced. Undefined for project/user agents.
|
|
30
|
+
*/
|
|
31
|
+
pluginName?: string;
|
|
32
|
+
/** Absolute path of the file it came from. Runtime-only. */
|
|
33
|
+
filePath?: string;
|
|
34
|
+
/** True when this def shadows a same-named def from a lower-priority dir. */
|
|
35
|
+
override?: boolean;
|
|
36
|
+
/** Sources whose same-named def this one shadows (runtime-only). Drives the
|
|
37
|
+
* UI "this project overrides your user version" warning (spec §7.2). */
|
|
38
|
+
shadowedSources?: Array<"project" | "user" | "plugin">;
|
|
15
39
|
}
|
|
16
40
|
/**
|
|
17
41
|
* Parse a Markdown agent-definition file (YAML frontmatter + body).
|
|
18
42
|
* Pure: no filesystem access. `sourceName` is only used in error messages.
|
|
19
43
|
*/
|
|
20
44
|
export declare function parseAgentDefinition(raw: string, sourceName: string): AgentDefinition;
|
|
45
|
+
/**
|
|
46
|
+
* Serialize an AgentDefinition back to a Markdown file body (YAML
|
|
47
|
+
* frontmatter + system prompt). Inverse of parseAgentDefinition.
|
|
48
|
+
* Optional fields that are unset are omitted entirely so an inheriting
|
|
49
|
+
* role (e.g. model undefined → inherit parent) stays clean on disk.
|
|
50
|
+
* Runtime-only metadata (source/filePath/override) is never written.
|
|
51
|
+
*/
|
|
52
|
+
export declare function serializeAgentDefinition(def: AgentDefinition): string;
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
import { parse as parseYaml } from "yaml";
|
|
1
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a frontmatter `tools:` / `skills:` value into a string[].
|
|
4
|
+
* Accepts both a YAML list (`[a, b]`) and a comma/whitespace-separated
|
|
5
|
+
* string (`a, b`) — CC-lineage agent files use either form. Returns
|
|
6
|
+
* undefined when the field is absent or not a usable shape, so the caller
|
|
7
|
+
* keeps the "inherit parent" default.
|
|
8
|
+
*/
|
|
9
|
+
function normalizeNameList(value) {
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
return value.filter((t) => typeof t === "string");
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === "string") {
|
|
14
|
+
return value
|
|
15
|
+
.split(/[,\s]+/)
|
|
16
|
+
.map((s) => s.trim())
|
|
17
|
+
.filter((s) => s.length > 0);
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
2
21
|
/**
|
|
3
22
|
* Parse a Markdown agent-definition file (YAML frontmatter + body).
|
|
4
23
|
* Pure: no filesystem access. `sourceName` is only used in error messages.
|
|
@@ -31,8 +50,34 @@ export function parseAgentDefinition(raw, sourceName) {
|
|
|
31
50
|
def.model = fm.model.trim();
|
|
32
51
|
if (typeof fm.maxTurns === "number")
|
|
33
52
|
def.maxTurns = fm.maxTurns;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
53
|
+
const tools = normalizeNameList(fm.tools);
|
|
54
|
+
if (tools !== undefined)
|
|
55
|
+
def.tools = tools;
|
|
56
|
+
const skills = normalizeNameList(fm.skills);
|
|
57
|
+
if (skills !== undefined)
|
|
58
|
+
def.skills = skills;
|
|
37
59
|
return def;
|
|
38
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Serialize an AgentDefinition back to a Markdown file body (YAML
|
|
63
|
+
* frontmatter + system prompt). Inverse of parseAgentDefinition.
|
|
64
|
+
* Optional fields that are unset are omitted entirely so an inheriting
|
|
65
|
+
* role (e.g. model undefined → inherit parent) stays clean on disk.
|
|
66
|
+
* Runtime-only metadata (source/filePath/override) is never written.
|
|
67
|
+
*/
|
|
68
|
+
export function serializeAgentDefinition(def) {
|
|
69
|
+
const fm = {
|
|
70
|
+
name: def.name,
|
|
71
|
+
description: def.description,
|
|
72
|
+
};
|
|
73
|
+
if (def.model !== undefined)
|
|
74
|
+
fm.model = def.model;
|
|
75
|
+
if (def.maxTurns !== undefined)
|
|
76
|
+
fm.maxTurns = def.maxTurns;
|
|
77
|
+
if (def.tools !== undefined)
|
|
78
|
+
fm.tools = def.tools;
|
|
79
|
+
if (def.skills !== undefined)
|
|
80
|
+
fm.skills = def.skills;
|
|
81
|
+
const yaml = stringifyYaml(fm).trimEnd();
|
|
82
|
+
return `---\n${yaml}\n---\n${def.systemPrompt}\n`;
|
|
83
|
+
}
|
package/dist/arena/arena.js
CHANGED
|
@@ -28,6 +28,15 @@ import { runDetailExpansion } from "./phases/planning-detail-expansion.js";
|
|
|
28
28
|
import { withLanguage } from "./strategies/language-wrapper.js";
|
|
29
29
|
import { ArenaLedger } from "./ledger.js";
|
|
30
30
|
import { registerClaims } from "./phases/claim-registry.js";
|
|
31
|
+
/** Bucket claims by status. Shared by the two consensus phases. */
|
|
32
|
+
function summarizeClaims(all) {
|
|
33
|
+
return {
|
|
34
|
+
verified: all.filter((c) => c.status === "verified"),
|
|
35
|
+
contested: all.filter((c) => c.status === "contested"),
|
|
36
|
+
unresolved: all.filter((c) => c.status === "unresolved"),
|
|
37
|
+
rejected: all.filter((c) => c.status === "rejected"),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
31
40
|
export class Arena {
|
|
32
41
|
config;
|
|
33
42
|
strategy;
|
|
@@ -192,12 +201,7 @@ export class Arena {
|
|
|
192
201
|
signal?.throwIfAborted();
|
|
193
202
|
// ─── Roadmap Consensus ───────────────────────────────────
|
|
194
203
|
const allClaims = ledger.getAllClaims();
|
|
195
|
-
const claimSummary =
|
|
196
|
-
verified: allClaims.filter((c) => c.status === "verified"),
|
|
197
|
-
contested: allClaims.filter((c) => c.status === "contested"),
|
|
198
|
-
unresolved: allClaims.filter((c) => c.status === "unresolved"),
|
|
199
|
-
rejected: allClaims.filter((c) => c.status === "rejected"),
|
|
200
|
-
};
|
|
204
|
+
const claimSummary = summarizeClaims(allClaims);
|
|
201
205
|
logger.info("arena.planning_consensus_phase", { concluder: concluder.name });
|
|
202
206
|
const consensus = await buildConsensus({
|
|
203
207
|
concluder,
|
|
@@ -295,12 +299,7 @@ export class Arena {
|
|
|
295
299
|
signal?.throwIfAborted();
|
|
296
300
|
// ─── Consensus (claim-aware) ─────────────────────────────
|
|
297
301
|
const allClaims = ledger.getAllClaims();
|
|
298
|
-
const claimSummary =
|
|
299
|
-
verified: allClaims.filter((c) => c.status === "verified"),
|
|
300
|
-
contested: allClaims.filter((c) => c.status === "contested"),
|
|
301
|
-
unresolved: allClaims.filter((c) => c.status === "unresolved"),
|
|
302
|
-
rejected: allClaims.filter((c) => c.status === "rejected"),
|
|
303
|
-
};
|
|
302
|
+
const claimSummary = summarizeClaims(allClaims);
|
|
304
303
|
logger.info("arena.consensus_phase", {
|
|
305
304
|
concluder: concluder.name,
|
|
306
305
|
verified: claimSummary.verified.length,
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* to prevent command injection. File paths are validated against the
|
|
7
7
|
* repository boundary to prevent path traversal.
|
|
8
8
|
*/
|
|
9
|
-
import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
|
|
9
|
+
import { readFileSync, existsSync, readdirSync, statSync, realpathSync } from "node:fs";
|
|
10
10
|
import { execFileSync } from "node:child_process";
|
|
11
|
-
import { resolve, join } from "node:path";
|
|
11
|
+
import { resolve, join, dirname, basename } from "node:path";
|
|
12
|
+
import { isWithinRoot } from "./within-root.js";
|
|
12
13
|
export const MAX_TOOL_RESULT = 15_000; // chars per tool call
|
|
13
14
|
// 5 was too generous for thinking-mode models — they'd spend the
|
|
14
15
|
// entire budget on read_file with textLen=0, then need an
|
|
@@ -112,10 +113,41 @@ export function executeContextTool(tc) {
|
|
|
112
113
|
*/
|
|
113
114
|
function validatePath(filePath) {
|
|
114
115
|
const resolved = resolve(filePath);
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
// Realpath both sides so a symlink planted inside the repo that points OUTSIDE
|
|
117
|
+
// can't pass a lexical containment check (isWithinRoot assumes resolved input
|
|
118
|
+
// and won't catch a link escape on its own). Matches fs-service's discipline.
|
|
119
|
+
// Reads are read-only, but a contained-looking symlink would still leak an
|
|
120
|
+
// out-of-repo file into arena context. Fall back to the lexical check when the
|
|
121
|
+
// target doesn't exist yet (a read of a missing file fails downstream anyway).
|
|
122
|
+
let realRoot;
|
|
123
|
+
try {
|
|
124
|
+
realRoot = realpathSync(REPO_ROOT);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
realRoot = REPO_ROOT;
|
|
128
|
+
}
|
|
129
|
+
let realTarget;
|
|
130
|
+
try {
|
|
131
|
+
realTarget = realpathSync(resolved);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
// Target doesn't exist yet. Compare REAL-vs-REAL by resolving the existing
|
|
135
|
+
// parent dir's realpath and rejoining the missing leaf — comparing realRoot
|
|
136
|
+
// (a real path) against a lexical `resolved` would false-reject valid files
|
|
137
|
+
// whenever REPO_ROOT (or any ancestor) is reached through a symlink.
|
|
138
|
+
let realParent;
|
|
139
|
+
try {
|
|
140
|
+
realParent = realpathSync(dirname(resolved));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Parent missing too — no realpath available; fall back to lexical-vs-lexical
|
|
144
|
+
// so both operands share the same (unresolved) mode.
|
|
145
|
+
return isWithinRoot(resolve(REPO_ROOT), resolved) ? resolved : null;
|
|
146
|
+
}
|
|
147
|
+
const candidate = join(realParent, basename(resolved));
|
|
148
|
+
return isWithinRoot(realRoot, candidate) ? candidate : null;
|
|
117
149
|
}
|
|
118
|
-
return null;
|
|
150
|
+
return isWithinRoot(realRoot, realTarget) ? realTarget : null;
|
|
119
151
|
}
|
|
120
152
|
function executeReadFile(args) {
|
|
121
153
|
const filePath = args.path;
|
|
@@ -126,7 +158,16 @@ function executeReadFile(args) {
|
|
|
126
158
|
const raw = readFileSync(filePath, "utf-8");
|
|
127
159
|
const lines = raw.split("\n");
|
|
128
160
|
const offset = Math.max(0, (args.offset ?? 1) - 1);
|
|
129
|
-
|
|
161
|
+
// Guard `limit` before slicing: a negative limit makes lines.slice count
|
|
162
|
+
// "from the end" and silently drop the file's tail (reader thinks the file is
|
|
163
|
+
// shorter). A missing/NaN limit falls back to the default; a non-positive
|
|
164
|
+
// limit reads nothing.
|
|
165
|
+
const rawLimit = args.limit;
|
|
166
|
+
const limit = rawLimit === undefined || !Number.isFinite(rawLimit)
|
|
167
|
+
? 200
|
|
168
|
+
: rawLimit > 0
|
|
169
|
+
? Math.floor(rawLimit)
|
|
170
|
+
: 0;
|
|
130
171
|
const slice = lines.slice(offset, offset + limit);
|
|
131
172
|
const numbered = slice.map((l, i) => `${offset + i + 1}\t${l}`).join("\n");
|
|
132
173
|
return truncateResult(numbered);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when `target` is the root itself or a descendant of it. Uses the
|
|
3
|
+
* platform separator (the old check hardcoded "/", which broke on Windows)
|
|
4
|
+
* and avoids the sibling-prefix trap (/repo vs /repo-evil). Both inputs are
|
|
5
|
+
* assumed already resolved to absolute paths.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isWithinRoot(root: string, target: string): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* True when `target` is the root itself or a descendant of it. Uses the
|
|
4
|
+
* platform separator (the old check hardcoded "/", which broke on Windows)
|
|
5
|
+
* and avoids the sibling-prefix trap (/repo vs /repo-evil). Both inputs are
|
|
6
|
+
* assumed already resolved to absolute paths.
|
|
7
|
+
*/
|
|
8
|
+
export function isWithinRoot(root, target) {
|
|
9
|
+
if (target === root)
|
|
10
|
+
return true;
|
|
11
|
+
const rel = path.relative(root, target);
|
|
12
|
+
// Outside the root iff the relative path climbs out ("..") or is absolute
|
|
13
|
+
// (different drive on Windows).
|
|
14
|
+
return rel !== "" && !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
15
|
+
}
|
|
@@ -61,7 +61,7 @@ export async function runArgueRound(args) {
|
|
|
61
61
|
// ─── Single-shot argue (no tools) ─────────────────────────────────────
|
|
62
62
|
async function argueSingleShot(args) {
|
|
63
63
|
const { critic, subject, format, draft, idPrefix, signal } = args;
|
|
64
|
-
const client = await createLLMClient(
|
|
64
|
+
const client = await createLLMClient(critic.llm, critic.clientDefaults);
|
|
65
65
|
const resp = await client.createMessage({
|
|
66
66
|
systemPrompt: format.argueSystem(format.format),
|
|
67
67
|
messages: [{ role: "user", content: format.argueUser(subject, draft) }],
|
|
@@ -78,7 +78,7 @@ async function argueSingleShot(args) {
|
|
|
78
78
|
// ─── Tool-use argue (with web search) ─────────────────────────────────
|
|
79
79
|
async function argueWithToolLoop(args) {
|
|
80
80
|
const { critic, subject, format, draft, idPrefix, maxToolRounds, signal } = args;
|
|
81
|
-
const client = await createLLMClient(
|
|
81
|
+
const client = await createLLMClient(critic.llm, critic.clientDefaults);
|
|
82
82
|
const messages = [
|
|
83
83
|
{ role: "user", content: format.argueUser(subject, draft) },
|
|
84
84
|
];
|
|
@@ -149,6 +149,12 @@ async function argueWithToolLoop(args) {
|
|
|
149
149
|
});
|
|
150
150
|
finalText = resp.text;
|
|
151
151
|
}
|
|
152
|
+
if (!finalText) {
|
|
153
|
+
// Both the tool loop and the force-conclude fallback produced no text
|
|
154
|
+
// (e.g. repeated max-token truncation). Log it — parseCritiquesResponse
|
|
155
|
+
// will just yield no critiques rather than silently parsing "".
|
|
156
|
+
logger.warn("arena.iterate.argue_empty_response", { critic: critic.name, toolRounds });
|
|
157
|
+
}
|
|
152
158
|
const critiques = parseCritiquesResponse(finalText, critic.name, idPrefix);
|
|
153
159
|
logger.info("arena.iterate.argue_toolloop", {
|
|
154
160
|
critic: critic.name,
|
|
@@ -7,7 +7,7 @@ import { parseReviseResponse } from "../parse.js";
|
|
|
7
7
|
export async function runRevise(args) {
|
|
8
8
|
const { subject, format, previous, critiques, author, minDraftLength, signal, onProgress } = args;
|
|
9
9
|
onProgress?.({ type: "revise_start", round: previous.version + 1, participant: author.name });
|
|
10
|
-
const client = await createLLMClient(
|
|
10
|
+
const client = await createLLMClient(author.llm, author.clientDefaults);
|
|
11
11
|
const prompt = format.revisePrompt(subject, previous, critiques, minDraftLength);
|
|
12
12
|
const resp = await client.createMessage({
|
|
13
13
|
systemPrompt: prompt,
|
|
@@ -11,7 +11,7 @@ export async function runTournamentCandidates(args) {
|
|
|
11
11
|
onProgress?.({ type: "v1_tournament_start", data: { count: participants.length } });
|
|
12
12
|
const tasks = participants.map(async (p, idx) => {
|
|
13
13
|
signal?.throwIfAborted();
|
|
14
|
-
const client = await createLLMClient(
|
|
14
|
+
const client = await createLLMClient(p.llm, p.clientDefaults);
|
|
15
15
|
const prompt = format.draftPrompt(subject, minDraftLength);
|
|
16
16
|
// Long-form generation needs a high output ceiling; the default 8k from
|
|
17
17
|
// LLMClientBase is too low for a substantive PRD or design doc and
|
|
@@ -66,7 +66,7 @@ export async function runTournamentCandidates(args) {
|
|
|
66
66
|
export async function mergeCandidatesToV1(args) {
|
|
67
67
|
const { subject, format, author, candidates, minDraftLength, signal, onProgress } = args;
|
|
68
68
|
onProgress?.({ type: "v1_merge_start", participant: author.name });
|
|
69
|
-
const client = await createLLMClient(
|
|
69
|
+
const client = await createLLMClient(author.llm, author.clientDefaults);
|
|
70
70
|
const prompt = format.mergePrompt(subject, candidates, minDraftLength);
|
|
71
71
|
const resp = await client.createMessage({
|
|
72
72
|
systemPrompt: prompt,
|
|
@@ -95,7 +95,7 @@ export async function mergeCandidatesToV1(args) {
|
|
|
95
95
|
/** Single-author v1 (tournament disabled) — author writes alone. */
|
|
96
96
|
export async function singleAuthorV1(args) {
|
|
97
97
|
const { subject, format, author, minDraftLength, signal } = args;
|
|
98
|
-
const client = await createLLMClient(
|
|
98
|
+
const client = await createLLMClient(author.llm, author.clientDefaults);
|
|
99
99
|
const prompt = format.draftPrompt(subject, minDraftLength);
|
|
100
100
|
const resp = await client.createMessage({
|
|
101
101
|
systemPrompt: prompt,
|
package/dist/arena/ledger.js
CHANGED
|
@@ -68,11 +68,16 @@ export class ArenaLedger {
|
|
|
68
68
|
}
|
|
69
69
|
appendChallenge(challenge) {
|
|
70
70
|
this.ledger.challenges.push(challenge);
|
|
71
|
-
// Also add to the claim's challenges array
|
|
71
|
+
// Also add to the claim's challenges array. If the claimId doesn't resolve
|
|
72
|
+
// the challenge still lives in ledger.challenges but is invisible to any
|
|
73
|
+
// code reading claim.challenges directly — surface that inconsistency.
|
|
72
74
|
const claim = this.index.claimsById.get(challenge.claimId);
|
|
73
75
|
if (claim) {
|
|
74
76
|
claim.challenges.push(challenge);
|
|
75
77
|
}
|
|
78
|
+
else {
|
|
79
|
+
logger.warn("arena.challenge_for_unknown_claim", { claimId: challenge.claimId });
|
|
80
|
+
}
|
|
76
81
|
this.checkGrowth();
|
|
77
82
|
// Register any requested checks
|
|
78
83
|
if (challenge.requestedChecks) {
|
|
@@ -94,6 +99,9 @@ export class ArenaLedger {
|
|
|
94
99
|
if (claim) {
|
|
95
100
|
claim.adjudication = adjudication;
|
|
96
101
|
}
|
|
102
|
+
else {
|
|
103
|
+
logger.warn("arena.adjudication_for_unknown_claim", { claimId: adjudication.claimId });
|
|
104
|
+
}
|
|
97
105
|
}
|
|
98
106
|
// ─── Query operations ───────────────────────────────────────
|
|
99
107
|
/**
|
|
@@ -33,10 +33,7 @@ export async function runAdjudication(options) {
|
|
|
33
33
|
verified: verifiedClaims.length,
|
|
34
34
|
});
|
|
35
35
|
// Adjudicate contested claims via LLM
|
|
36
|
-
const client = await createLLMClient(
|
|
37
|
-
...concluder.llm,
|
|
38
|
-
enableStreaming: false,
|
|
39
|
-
});
|
|
36
|
+
const client = await createLLMClient(concluder.llm, concluder.clientDefaults);
|
|
40
37
|
for (const claim of contestedClaims) {
|
|
41
38
|
signal?.throwIfAborted();
|
|
42
39
|
const digest = buildDigest(ledger, {
|
|
@@ -18,10 +18,7 @@ import { isStrategyV2 } from "../types.js";
|
|
|
18
18
|
export async function buildConsensus(options) {
|
|
19
19
|
const { concluder, strategy, topic, reports, reviews, claimSummary, signal, onProgress } = options;
|
|
20
20
|
onProgress?.({ type: "consensus_start" });
|
|
21
|
-
const client = await createLLMClient(
|
|
22
|
-
...concluder.llm,
|
|
23
|
-
enableStreaming: false,
|
|
24
|
-
});
|
|
21
|
+
const client = await createLLMClient(concluder.llm, concluder.clientDefaults);
|
|
25
22
|
const systemPrompt = strategy.consensusSystemPrompt();
|
|
26
23
|
// Choose user prompt: claim-aware (V2) or standard (V1)
|
|
27
24
|
let userContent;
|
|
@@ -28,10 +28,7 @@ export async function runCrossReview(options) {
|
|
|
28
28
|
return [];
|
|
29
29
|
if (!myReport)
|
|
30
30
|
return [];
|
|
31
|
-
const client = await createLLMClient(
|
|
32
|
-
...p.llm,
|
|
33
|
-
enableStreaming: false,
|
|
34
|
-
});
|
|
31
|
+
const client = await createLLMClient(p.llm, p.clientDefaults);
|
|
35
32
|
const systemPrompt = strategy.crossReviewSystemPrompt(p.name);
|
|
36
33
|
const userContent = strategy.crossReviewUserPrompt(topic, myReport, otherReports);
|
|
37
34
|
let response = await client.createMessage({
|
|
@@ -110,10 +107,7 @@ export async function runVerificationReview(options) {
|
|
|
110
107
|
const myClaims = claimsToReview.filter((c) => c.owner !== p.name);
|
|
111
108
|
if (myClaims.length === 0)
|
|
112
109
|
return;
|
|
113
|
-
const client = await createLLMClient(
|
|
114
|
-
...p.llm,
|
|
115
|
-
enableStreaming: false,
|
|
116
|
-
});
|
|
110
|
+
const client = await createLLMClient(p.llm, p.clientDefaults);
|
|
117
111
|
const systemPrompt = strategy.crossReviewSystemPrompt(p.name);
|
|
118
112
|
if (v2) {
|
|
119
113
|
// V2 path: claim-aware verification review (or merge review for planning)
|
|
@@ -75,10 +75,7 @@ async function debateClaim(options) {
|
|
|
75
75
|
});
|
|
76
76
|
// Each debater produces a turn
|
|
77
77
|
const turnPromises = debaters.map(async (p) => {
|
|
78
|
-
const client = await createLLMClient(
|
|
79
|
-
...p.llm,
|
|
80
|
-
enableStreaming: false,
|
|
81
|
-
});
|
|
78
|
+
const client = await createLLMClient(p.llm, p.clientDefaults);
|
|
82
79
|
const systemPrompt = strategy.crossReviewSystemPrompt(p.name);
|
|
83
80
|
let userContent;
|
|
84
81
|
if (v2) {
|
|
@@ -27,10 +27,7 @@ export async function runParticipantResearchWithDossiers(options) {
|
|
|
27
27
|
const tools = enableContextTools ? (contextTools ?? CONTEXT_TOOLS) : undefined;
|
|
28
28
|
const tasks = participants.map(async (p) => {
|
|
29
29
|
onProgress?.({ type: "research_start", participant: p.name });
|
|
30
|
-
const client = await createLLMClient(
|
|
31
|
-
...p.llm,
|
|
32
|
-
enableStreaming: false,
|
|
33
|
-
});
|
|
30
|
+
const client = await createLLMClient(p.llm, p.clientDefaults);
|
|
34
31
|
const messages = [
|
|
35
32
|
{
|
|
36
33
|
role: "user",
|
|
@@ -31,10 +31,7 @@ export async function runDetailExpansion(options) {
|
|
|
31
31
|
onProgress?.({ type: "roadmap_expansion_start", phaseCount: toExpand.length });
|
|
32
32
|
logger.info("arena.detail_expansion_start", { phaseCount: toExpand.length });
|
|
33
33
|
const details = [];
|
|
34
|
-
const client = await createLLMClient(
|
|
35
|
-
...concluder.llm,
|
|
36
|
-
enableStreaming: false,
|
|
37
|
-
});
|
|
34
|
+
const client = await createLLMClient(concluder.llm, concluder.clientDefaults);
|
|
38
35
|
const systemPrompt = strategy.detailExpansionSystemPrompt();
|
|
39
36
|
// Expand each phase sequentially
|
|
40
37
|
for (const phase of toExpand) {
|
|
@@ -45,13 +42,18 @@ export async function runDetailExpansion(options) {
|
|
|
45
42
|
const userContent = strategy.detailExpansionUserPrompt(topic, phase, digest);
|
|
46
43
|
const messages = [{ role: "user", content: userContent }];
|
|
47
44
|
let finalText = "";
|
|
48
|
-
// Tool-use loop: allow LLM to verify file paths and interfaces
|
|
45
|
+
// Tool-use loop: allow LLM to verify file paths and interfaces.
|
|
46
|
+
// `maxRounds` bounds the number of tool rounds; after the last one we make
|
|
47
|
+
// one final call (without tools) so the model produces text FROM the tool
|
|
48
|
+
// results rather than the empty text it emitted alongside the tool calls.
|
|
49
49
|
const maxRounds = tools ? Math.min(MAX_EXPANSION_TOOL_ROUNDS, MAX_TOOL_ROUNDS) : 0;
|
|
50
50
|
for (let round = 0; round <= maxRounds; round++) {
|
|
51
|
+
// On the final round, stop offering tools so the model must answer.
|
|
52
|
+
const offerTools = round < maxRounds ? tools : undefined;
|
|
51
53
|
const response = await client.createMessage({
|
|
52
54
|
systemPrompt,
|
|
53
55
|
messages,
|
|
54
|
-
tools,
|
|
56
|
+
tools: offerTools,
|
|
55
57
|
signal,
|
|
56
58
|
});
|
|
57
59
|
const hasTools = response.toolCalls && response.toolCalls.length > 0;
|
|
@@ -90,10 +92,6 @@ export async function runDetailExpansion(options) {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
messages.push({ role: "user", content: toolResultBlocks });
|
|
93
|
-
// Last round: force a text response
|
|
94
|
-
if (round === maxRounds) {
|
|
95
|
-
finalText = response.text;
|
|
96
|
-
}
|
|
97
95
|
}
|
|
98
96
|
// Retry if truncated
|
|
99
97
|
if (!finalText) {
|