mixdog 1.2.0 → 1.2.2
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 +7 -5
- package/package.json +1 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -0
- package/src/defaults/skills/pptx/SKILL.md +6 -6
- package/src/defaults/skills/pptx/references/review.md +6 -4
- package/src/defaults/skills/pptx/scripts/source-extract.mjs +1 -1
- package/src/defaults/skills/setup/references/actions.md +13 -3
- package/src/defaults/skills/visualize/SKILL.md +12 -9
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/shared/60-verification.md +3 -1
- package/src/rules/shared/70-delivery.md +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +26 -5
- package/src/runtime/agent/orchestrator/config.mjs +10 -4
- package/src/runtime/agent/orchestrator/context/collect.mjs +2 -1
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +11 -5
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +74 -21
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +54 -11
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +104 -9
- package/src/runtime/agent/orchestrator/mcp/client.mjs +358 -140
- package/src/runtime/agent/orchestrator/mcp/lazy-output-validator.mjs +25 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
- package/src/runtime/agent/orchestrator/mcp/plugin-placeholders.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +294 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +96 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +25 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +73 -35
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +8 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +53 -18
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +30 -14
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +93 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +82 -9
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +337 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs +159 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +447 -0
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +38 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +102 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +29 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +18 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +86 -19
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +29 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +191 -0
- package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +21 -82
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -12
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +21 -20
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +97 -51
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +68 -19
- package/src/runtime/agent/orchestrator/providers/lib/gemini-model-catalog.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-bridge.mjs +1080 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +15 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +35 -0
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +6 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +22 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +23 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +94 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +26 -6
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +42 -25
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +34 -3
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +5 -9
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
- package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +35 -24
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +581 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +35 -9
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +118 -219
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +15 -55
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +15 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +268 -181
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +54 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +284 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +270 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/sqlite-gate.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +628 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +184 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +136 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/explicit-skills.mjs +83 -5
- package/src/runtime/agent/orchestrator/session/imported-message.mjs +11 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -4
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +102 -18
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +42 -5
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +14 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +20 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +50 -23
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +155 -29
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +819 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +22 -12
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +158 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +183 -374
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +41 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +38 -17
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +173 -22
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-guards.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +15 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +13 -10
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +17 -12
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/route.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/read-redirects.mjs +34 -30
- package/src/runtime/agent/orchestrator/tools/patch/sequence/units.mjs +7 -7
- package/src/runtime/agent/orchestrator/tools/patch/sequence.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -0
- package/src/runtime/attachments/store.d.mts +3 -0
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +1 -1
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +16 -4
- package/src/runtime/channels/lib/worker-main.mjs +17 -14
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -2
- package/src/runtime/effort-judge/judge-client.mjs +56 -18
- package/src/runtime/memory/lib/memory.mjs +1 -1
- package/src/runtime/memory/lib/pg/process.mjs +34 -24
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -13
- package/src/runtime/memory/lib/session-ingest.mjs +2 -2
- package/src/runtime/office/README.md +1 -1
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/atomic-file.mjs +25 -4
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/err-text.mjs +25 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/extension-scopes.mjs +5 -3
- package/src/runtime/shared/file-lock.mjs +37 -11
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +134 -131
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -52
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +17 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/plugin-manifest.mjs +18 -9
- package/src/runtime/shared/pristine-execution-contract.json +9 -2
- package/src/runtime/shared/pristine-execution.mjs +28 -4
- package/src/runtime/shared/provider-accounts.mjs +124 -20
- package/src/runtime/shared/provider-api-key.mjs +12 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/shell-display.mjs +9 -3
- package/src/runtime/shared/skill-mentions.d.mts +10 -0
- package/src/runtime/shared/skill-mentions.mjs +133 -0
- package/src/runtime/shared/skill-script-runtime.mjs +264 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +35 -2
- package/src/runtime/shared/turn-changes.mjs +447 -219
- package/src/runtime/shared/turn-snapshot-store.mjs +182 -1
- package/src/runtime/shared/turn-snapshot.mjs +170 -48
- package/src/runtime/shared/turn-worktree-snapshot.mjs +160 -51
- package/src/runtime/shared/worker-requests.mjs +15 -2
- package/src/runtime/shared/worktrees/contract.mjs +0 -24
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/session-runtime/automation-agents.mjs +8 -2
- package/src/session-runtime/boot/apis.mjs +61 -0
- package/src/session-runtime/boot/config.mjs +5 -2
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +35 -18
- package/src/session-runtime/conversation-import/discovery.mjs +698 -0
- package/src/session-runtime/conversation-import/service.mjs +369 -0
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +10 -5
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +47 -42
- package/src/session-runtime/lifecycle/session-catalog.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/connect.mjs +83 -16
- package/src/session-runtime/mcp-glue/plugin-servers.mjs +499 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +135 -33
- package/src/session-runtime/mcp-glue.mjs +25 -2
- package/src/session-runtime/mcp-oauth-login.mjs +174 -0
- package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
- package/src/session-runtime/model-route/set-route.mjs +83 -15
- package/src/session-runtime/model-route/web-search-route.mjs +1 -1
- package/src/session-runtime/native-web-search/routes.mjs +22 -3
- package/src/session-runtime/new-session-config.mjs +3 -2
- package/src/session-runtime/notification-bus.mjs +9 -2
- package/src/session-runtime/provider-auth/accounts.mjs +33 -15
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- package/src/session-runtime/provider-models/web-search-catalog.mjs +5 -1
- package/src/session-runtime/provider-readiness.mjs +16 -10
- package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
- package/src/session-runtime/quick-web-search-models.mjs +13 -38
- package/src/session-runtime/resource-extension-sync.mjs +24 -5
- package/src/session-runtime/resource-mcp-api.mjs +198 -78
- package/src/session-runtime/resource-plugins-api.mjs +29 -41
- package/src/session-runtime/resource-scope-decorate.mjs +6 -8
- package/src/session-runtime/resource-skills-api.mjs +23 -2
- package/src/session-runtime/runtime-review-api.mjs +13 -0
- package/src/session-runtime/schedule-session-run.mjs +1 -1
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
- package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/channel-session-router.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +4 -1
- package/src/session-runtime/services/hook-bus/handlers.mjs +7 -3
- package/src/session-runtime/services/provider-admin.mjs +64 -18
- package/src/session-runtime/services/usage-dashboard-model.mjs +3 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +12 -1
- package/src/session-runtime/setup-tool/extended-actions.mjs +1 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +1 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +7 -1
- package/src/session-runtime/skills-api.mjs +7 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/webhook-session-run.mjs +16 -4
- package/src/skill-script-entry.mjs +36 -0
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-stored-session-views.mjs +11 -3
- package/src/standalone/daemon-telemetry.mjs +55 -0
- package/src/standalone/daemon.mjs +44 -11
- package/src/standalone/session-protocol.mjs +12 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
- package/src/standalone/session-service/agent-tree.mjs +12 -0
- package/src/standalone/session-service/quota-resume.mjs +8 -0
- package/src/standalone/session-service/retention/busy.mjs +15 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +6 -1
- package/src/standalone/session-service-api.mjs +5 -0
- package/src/standalone/session-service.mjs +1 -0
- package/src/tui/App.jsx +9 -1
- package/src/tui/app/app-view/floating-panel.jsx +9 -1
- package/src/tui/app/app-view.jsx +7 -0
- package/src/tui/app/create-app-pickers.mjs +4 -0
- package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
- package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
- package/src/tui/app/extension-pickers/plugins-pickers.mjs +35 -16
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +13 -16
- package/src/tui/app/skill-mention-palette.mjs +88 -0
- package/src/tui/app/slash-commands.mjs +7 -2
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-palette.mjs +23 -7
- package/src/tui/app/transcript-row-estimate.mjs +11 -3
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -2
- package/src/tui/app/use-prompt-state.mjs +5 -0
- package/src/tui/components/Message.jsx +22 -1
- package/src/tui/components/PromptInput.jsx +21 -3
- package/src/tui/components/SlashCommandPalette.jsx +12 -3
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/TranscriptItem.jsx +9 -1
- package/src/tui/components/prompt-input/key-handler.mjs +21 -8
- package/src/tui/components/status-line/local-line.mjs +5 -2
- package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
- package/src/tui/components/user-message-skills.mjs +38 -0
- package/src/tui/dist/index.mjs +1323 -214
- package/src/tui/session/queue-helpers.mjs +7 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +33 -24
- package/src/tui/session/session-api/extensions.mjs +26 -2
- package/src/tui/session/session-api/integrations.mjs +7 -0
- package/src/tui/session/session-api/lifecycle.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +12 -14
- package/src/tui/session/session-flow/drain.mjs +21 -5
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tui-steering-persist.mjs +25 -9
- package/src/tui/session/turn.mjs +55 -15
- package/src/tui/statusline-ansi-bridge.mjs +1 -1
- package/src/ui/statusline-agents.mjs +15 -4
- package/src/ui/statusline.mjs +7 -3
- package/src/ui/streaming-markdown-heal.mjs +34 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
- package/src/runtime/effort-judge/previous-human-request.mjs +0 -162
- package/src/runtime/effort-judge/verified-context-input.mjs +0 -10
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -5,6 +5,8 @@ import { ACTIVE_STAGES } from '../tool-def.mjs';
|
|
|
5
5
|
import { isTerminalWorkerStatus } from '../worker-rows.mjs';
|
|
6
6
|
import { sessionUsageTotals } from '../../../../runtime/shared/session-usage-totals.mjs';
|
|
7
7
|
|
|
8
|
+
const CANCELLED_WORKER_STATUS = /^(?:cancelled|canceled|killed|cancel[-_\s]?(?:unconfirmed|pending))$/;
|
|
9
|
+
|
|
8
10
|
// Idle, closed, errored and reaped/unknown rows are history and stay reachable
|
|
9
11
|
// through the task section (status/read keep their terminal result).
|
|
10
12
|
export function isActiveWorkerRow(row = {}) {
|
|
@@ -14,8 +16,11 @@ export function isActiveWorkerRow(row = {}) {
|
|
|
14
16
|
const status = String(row.status ?? '')
|
|
15
17
|
.trim()
|
|
16
18
|
.toLowerCase();
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
// `status` decides; the stage is the runtime phase and only stands in for a
|
|
20
|
+
// row with no status. A cancel in either field is not work.
|
|
21
|
+
if (CANCELLED_WORKER_STATUS.test(stage) || CANCELLED_WORKER_STATUS.test(status)) return false;
|
|
22
|
+
const effective = status || stage;
|
|
23
|
+
if (ACTIVE_STAGES.has(effective)) return true;
|
|
19
24
|
if (!effective || effective === 'unknown') return false;
|
|
20
25
|
return !isTerminalWorkerStatus(effective);
|
|
21
26
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveAgentWatchdogPolicy,
|
|
3
3
|
resolveHandoffMessageStartIndex,
|
|
4
|
+
turnPartialHandoff,
|
|
4
5
|
watchdogPartialHandoffFromError,
|
|
5
6
|
watchdogStoppedHandoff,
|
|
6
7
|
} from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
7
8
|
import { clean, normalizeAgentName, resolvePrompt } from './helpers.mjs';
|
|
8
9
|
import { abnormalEmptyFinishError, renderResult } from './render.mjs';
|
|
9
10
|
import {
|
|
11
|
+
reconcileJobCancelled,
|
|
10
12
|
reconcileJobFinally,
|
|
11
13
|
reconcileJobStreamStalled,
|
|
12
14
|
reconcileJobWatchdogPartial,
|
|
@@ -93,6 +95,18 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
93
95
|
turnStartedAt: new Date().toISOString(),
|
|
94
96
|
});
|
|
95
97
|
let handoffMsgStart = 0;
|
|
98
|
+
// A cancelled turn reports the output it produced before it stopped.
|
|
99
|
+
const settleCancelled = (error, result = null) => {
|
|
100
|
+
finalStatus = 'cancelled';
|
|
101
|
+
reconcileJobCancelled(job, {
|
|
102
|
+
tag,
|
|
103
|
+
sessionId,
|
|
104
|
+
agent: session.agent || null,
|
|
105
|
+
provider: session.provider,
|
|
106
|
+
model: session.model,
|
|
107
|
+
content: turnPartialHandoff(error, mgr.getSession(sessionId), handoffMsgStart) || result?.content || '',
|
|
108
|
+
});
|
|
109
|
+
};
|
|
96
110
|
try {
|
|
97
111
|
handoffMsgStart = resolveHandoffMessageStartIndex(mgr.getSession(sessionId));
|
|
98
112
|
const turnHooks = buildTurnHooks({ sessionId, notifyContext, job, turnReview, completionValue });
|
|
@@ -100,6 +114,10 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
100
114
|
// Early preview no longer suppresses the canonical body notification;
|
|
101
115
|
// notifyTaskCompletion fires once with output via resolve/reconcile.
|
|
102
116
|
const finalValue = completionValue(result);
|
|
117
|
+
if (job?.status === 'cancelled') {
|
|
118
|
+
settleCancelled(null, result);
|
|
119
|
+
return finalValue;
|
|
120
|
+
}
|
|
103
121
|
if (finalValue.error) {
|
|
104
122
|
finalStatus = 'error';
|
|
105
123
|
if (job) job._terminalResultValue = finalValue;
|
|
@@ -107,6 +125,10 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
107
125
|
}
|
|
108
126
|
return finalValue;
|
|
109
127
|
} catch (error) {
|
|
128
|
+
if (job?.status === 'cancelled') {
|
|
129
|
+
settleCancelled(error);
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
110
132
|
const partial = watchdogPartialHandoffFromError(error, mgr.getSession(sessionId), handoffMsgStart);
|
|
111
133
|
if (partial) {
|
|
112
134
|
finalStatus = 'idle';
|
|
@@ -123,10 +145,6 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
123
145
|
reconcileJobWatchdogPartial(job, value);
|
|
124
146
|
return value;
|
|
125
147
|
}
|
|
126
|
-
if (job?.status === 'cancelled') {
|
|
127
|
-
finalStatus = 'cancelled';
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
148
|
finalStatus = 'error';
|
|
131
149
|
reconcileJobStreamStalled(job, error);
|
|
132
150
|
throw error;
|
|
@@ -44,6 +44,8 @@ export function createJobStarter({ mgr, notifyStatusChange, notifySessionComplet
|
|
|
44
44
|
meta: jobMeta,
|
|
45
45
|
resultType: 'agent_task_result',
|
|
46
46
|
renderResult: (result) => renderResult(result),
|
|
47
|
+
// Cancellation reaches the owner once, with the worker's partial output.
|
|
48
|
+
notifyOnCancel: true,
|
|
47
49
|
cancel: () => {
|
|
48
50
|
try {
|
|
49
51
|
admissionController.abort(new Error('agent task cancelled before resource admission'));
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { createNotify } from '../notify.mjs';
|
|
8
8
|
import {
|
|
9
|
+
reconcileJobCancelled,
|
|
9
10
|
reconcileJobFinally,
|
|
10
11
|
reconcileJobStreamStalled,
|
|
11
12
|
reconcileJobWatchdogPartial,
|
|
@@ -15,11 +16,13 @@ import { abnormalEmptyFinishError } from '../render.mjs';
|
|
|
15
16
|
import { createProgressWatchdogRegistry } from '../../agent-watchdog-registry.mjs';
|
|
16
17
|
import {
|
|
17
18
|
resolveHandoffMessageStartIndex,
|
|
19
|
+
turnPartialHandoff,
|
|
18
20
|
watchdogPartialHandoffFromError,
|
|
19
21
|
watchdogStoppedHandoff,
|
|
20
22
|
} from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
21
23
|
import { saveSessionAsync } from '../../../../runtime/agent/orchestrator/session/store.mjs';
|
|
22
24
|
import { presetDescriptor } from './spawn-prep.mjs';
|
|
25
|
+
import { workerStageForStatus } from '../worker-rows.mjs';
|
|
23
26
|
|
|
24
27
|
// Mid-turn worker persistence cadence. The watchdog sweep runs every second;
|
|
25
28
|
// a transcript save is far more expensive than a bookkeeping stamp, so the
|
|
@@ -68,7 +71,7 @@ export function createSpawnRunner({
|
|
|
68
71
|
const messages = Number(progress?.messages) || 0;
|
|
69
72
|
upsertWorkerSessionDeferred(session, tag, {
|
|
70
73
|
status: 'running',
|
|
71
|
-
stage:
|
|
74
|
+
stage: workerStageForStatus('running', progress.stage),
|
|
72
75
|
...(messages > 0 ? { messages } : {}),
|
|
73
76
|
});
|
|
74
77
|
// The canonical runtime owns persistence; this session is only its descriptor.
|
|
@@ -135,6 +138,16 @@ export function createSpawnRunner({
|
|
|
135
138
|
});
|
|
136
139
|
notifyStatusChange();
|
|
137
140
|
let handoffMsgStart = 0;
|
|
141
|
+
// A cancelled turn reports the output it produced before it stopped.
|
|
142
|
+
const settleCancelled = (error, result = null) => {
|
|
143
|
+
finalStatus = 'cancelled';
|
|
144
|
+
reconcileJobCancelled(job, {
|
|
145
|
+
tag,
|
|
146
|
+
sessionId: session.id,
|
|
147
|
+
...presetDescriptor(agent, preset, presetName),
|
|
148
|
+
content: turnPartialHandoff(error, mgr.getSession(session.id), handoffMsgStart) || result?.content || '',
|
|
149
|
+
});
|
|
150
|
+
};
|
|
138
151
|
try {
|
|
139
152
|
handoffMsgStart = resolveHandoffMessageStartIndex(mgr.getSession(session.id));
|
|
140
153
|
const turnHooks = {
|
|
@@ -157,6 +170,10 @@ export function createSpawnRunner({
|
|
|
157
170
|
// notifyTaskCompletion is left to fire exactly once with output via the
|
|
158
171
|
// resolve/reconcile/finally path.
|
|
159
172
|
const finalValue = completionValue(result);
|
|
173
|
+
if (job?.status === 'cancelled') {
|
|
174
|
+
settleCancelled(null, result);
|
|
175
|
+
return finalValue;
|
|
176
|
+
}
|
|
160
177
|
// Non-job return path (or job path where the terminal-result reconcile
|
|
161
178
|
// already ran): if the finish was abnormal-empty, surface it as a thrown
|
|
162
179
|
// error so finalStatus becomes 'error' and the caller's error path (and
|
|
@@ -168,6 +185,10 @@ export function createSpawnRunner({
|
|
|
168
185
|
}
|
|
169
186
|
return finalValue;
|
|
170
187
|
} catch (error) {
|
|
188
|
+
if (job?.status === 'cancelled') {
|
|
189
|
+
settleCancelled(error);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
171
192
|
const partial = watchdogPartialHandoffFromError(error, mgr.getSession(session.id), handoffMsgStart);
|
|
172
193
|
if (partial) {
|
|
173
194
|
finalStatus = 'idle';
|
|
@@ -182,10 +203,6 @@ export function createSpawnRunner({
|
|
|
182
203
|
reconcileJobWatchdogPartial(job, value);
|
|
183
204
|
return value;
|
|
184
205
|
}
|
|
185
|
-
if (job?.status === 'cancelled') {
|
|
186
|
-
finalStatus = 'cancelled';
|
|
187
|
-
throw error;
|
|
188
|
-
}
|
|
189
206
|
finalStatus = 'error';
|
|
190
207
|
reconcileJobStreamStalled(job, error);
|
|
191
208
|
throw error;
|
|
@@ -11,8 +11,15 @@ const ACTIVE_WORKER_STATUS =
|
|
|
11
11
|
/^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
|
|
12
12
|
const WORKER_POOL_FRESH_MS = 2 * 60 * 1000;
|
|
13
13
|
|
|
14
|
+
const CANCELLED_WORKER_STATUS = /^(?:cancelled|canceled|killed|cancel[-_\s]?(?:unconfirmed|pending))$/i;
|
|
15
|
+
|
|
16
|
+
/** `status` decides; `stage` is the runtime phase copied in by the progress
|
|
17
|
+
* sweep and only decides for a row with no status. A cancel in either field
|
|
18
|
+
* is not work (bare `cancelling` still is). */
|
|
14
19
|
export const isActiveWorkerRow = (row) =>
|
|
15
|
-
|
|
20
|
+
!CANCELLED_WORKER_STATUS.test(clean(row?.status)) &&
|
|
21
|
+
!CANCELLED_WORKER_STATUS.test(clean(row?.stage)) &&
|
|
22
|
+
ACTIVE_WORKER_STATUS.test(clean(row?.status) || clean(row?.stage));
|
|
16
23
|
|
|
17
24
|
/** A persisted approval wait whose runtime is gone: the in-memory wait died
|
|
18
25
|
* with that process (daemon restart), so the flag must not stick. */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// The one row shape of the worker index: coercing whatever a stored file or a
|
|
3
3
|
// caller hands in, and projecting a live session into a row.
|
|
4
4
|
import { agentTagOf, clean, positiveInt } from '../helpers.mjs';
|
|
5
|
-
import { isLeadPoolAgent } from '../worker-rows.mjs';
|
|
5
|
+
import { isLeadPoolAgent, workerStageForStatus } from '../worker-rows.mjs';
|
|
6
6
|
|
|
7
7
|
/** An explicit boolean wins; otherwise the session's own fast flag (true) or unknown. */
|
|
8
8
|
function fastFlag(explicit, sessionFast) {
|
|
@@ -72,7 +72,7 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
|
|
|
72
72
|
if (!tag || !sessionId) return null;
|
|
73
73
|
const runtime = getSessionRuntime(sessionId);
|
|
74
74
|
const status = clean(extra.status) || (session?.closed === true ? 'closed' : clean(session?.status) || 'idle');
|
|
75
|
-
const stage = clean(extra.stage) ||
|
|
75
|
+
const stage = clean(extra.stage) || workerStageForStatus(status, runtime?.stage);
|
|
76
76
|
const nowIso = new Date().toISOString();
|
|
77
77
|
return {
|
|
78
78
|
tag,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { agentTagOf, clean, positiveInt, stampMs } from './helpers.mjs';
|
|
2
|
+
import { ACTIVE_STAGES } from './tool-def.mjs';
|
|
2
3
|
|
|
3
4
|
import { TAG_TOMBSTONE_TTL_MS, tagTombstoneKey } from '../../../runtime/shared/agent-reap-state.mjs';
|
|
4
5
|
export { TAG_TOMBSTONE_TTL_MS, tagTombstoneKey };
|
|
@@ -27,6 +28,22 @@ export function isTerminalWorkerStatus(status) {
|
|
|
27
28
|
);
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
const WORKING_WORKER_STATUS =
|
|
32
|
+
/^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
|
|
33
|
+
const WORKING_WORKER_STAGES = new Set([...ACTIVE_STAGES, 'resource_wait']);
|
|
34
|
+
|
|
35
|
+
/** The `stage` to store beside a worker `status`, from a stage read off the
|
|
36
|
+
* live runtime. That stage is the runtime's own phase, so mid-work it can say
|
|
37
|
+
* `idle`/`done`/`error` (a fresh or just-settled runtime entry) while the
|
|
38
|
+
* worker is still running. Stored next to a working status it made a mixed
|
|
39
|
+
* row that readers classified as finished, so a working status keeps a
|
|
40
|
+
* working stage and falls back to the status itself. */
|
|
41
|
+
export function workerStageForStatus(status, runtimeStage) {
|
|
42
|
+
const stage = clean(runtimeStage);
|
|
43
|
+
if (!WORKING_WORKER_STATUS.test(clean(status))) return stage || clean(status);
|
|
44
|
+
return WORKING_WORKER_STAGES.has(stage.toLowerCase()) ? stage : clean(status);
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
export function recoverTagTombstoneOwner(row, sessions) {
|
|
31
48
|
if (clean(row.parentSessionId || row.ownerSessionId)) return row;
|
|
32
49
|
const pid = positiveInt(row.clientHostPid);
|
|
@@ -19,7 +19,10 @@ export function createChannelSessionRouter({ getSessionService, getSessionId, lo
|
|
|
19
19
|
service.submitSession({
|
|
20
20
|
sessionId,
|
|
21
21
|
prompt: content,
|
|
22
|
-
|
|
22
|
+
// A channel notification (webhook event rules carry fenced external
|
|
23
|
+
// values) is queued as a task notification, never as typed input, so
|
|
24
|
+
// nothing inside it selects a skill.
|
|
25
|
+
options: { source: 'channel', mode: 'task-notification' },
|
|
23
26
|
})
|
|
24
27
|
).catch((error) => {
|
|
25
28
|
log(`channel session delivery failed session=${sessionId}: ${error?.message || error}`);
|
|
@@ -3,6 +3,7 @@ import { spawn, spawnSync } from 'node:child_process';
|
|
|
3
3
|
import { MAX_BUFFER_BYTES } from './constants.mjs';
|
|
4
4
|
import { handlerTimeoutS } from './handler-timeout.mjs';
|
|
5
5
|
import { abortReason, throwIfAborted } from '../../../runtime/shared/abort-race.mjs';
|
|
6
|
+
import { scrubRuntimeRootVars } from '../../../runtime/agent/orchestrator/tools/env-scrub.mjs';
|
|
6
7
|
|
|
7
8
|
function resolvePlaceholders(str, projectDir, pluginData, pluginRoot = null) {
|
|
8
9
|
if (typeof str !== 'string') return str;
|
|
@@ -88,8 +89,10 @@ function hookEnv(projectDir, pluginData, payload, pluginRoot = null) {
|
|
|
88
89
|
const resolvedProject = projectDir || process.cwd();
|
|
89
90
|
const resolvedPluginRoot = pluginRoot || resolvedProject;
|
|
90
91
|
const resolvedPluginData = pluginData || resolvedProject;
|
|
92
|
+
// Hooks are user commands like model shells: the host's runtime root,
|
|
93
|
+
// identity and Electron node-mode must not reach them.
|
|
91
94
|
const env = {
|
|
92
|
-
...process.env,
|
|
95
|
+
...scrubRuntimeRootVars({ ...process.env }),
|
|
93
96
|
MIXDOG_PROJECT_DIR: resolvedProject,
|
|
94
97
|
MIXDOG_PLUGIN_ROOT: resolvedPluginRoot,
|
|
95
98
|
MIXDOG_PLUGIN_DATA: resolvedPluginData,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readResponseBuffer } from '../../../runtime/shared/bounded-download.mjs';
|
|
2
2
|
import { runAbortable, throwIfAborted } from '../../../runtime/shared/abort-race.mjs';
|
|
3
3
|
import { assertPublicUrl, pinnedFetch } from '../../../runtime/web-search/lib/ssrf-guard.mjs';
|
|
4
|
+
import { providerSafeMcpToolName } from '../../../runtime/agent/orchestrator/mcp/client-config.mjs';
|
|
4
5
|
import { handlerTimeoutS } from './handler-timeout.mjs';
|
|
5
6
|
export { handlerTimeoutS } from './handler-timeout.mjs';
|
|
6
7
|
export { defaultShellKind, runCommandHandler } from './command-handler.mjs';
|
|
@@ -216,8 +217,9 @@ export async function runMcpToolHandler(handler, payload, eventName, mcpToolRunn
|
|
|
216
217
|
throwIfAborted(signal);
|
|
217
218
|
const timeoutMs = Math.round(handlerTimeoutS(handler, eventName) * 1000);
|
|
218
219
|
let name = String(handler.tool || '').trim();
|
|
219
|
-
if (handler.server && !name.startsWith('mcp__')) {
|
|
220
|
-
name
|
|
220
|
+
if (handler.server && name && !name.startsWith('mcp__')) {
|
|
221
|
+
// The same provider-safe name the server's tool was registered under.
|
|
222
|
+
name = providerSafeMcpToolName(String(handler.server).trim(), name);
|
|
221
223
|
}
|
|
222
224
|
if (!name) {
|
|
223
225
|
return {
|
|
@@ -241,7 +243,9 @@ export async function runMcpToolHandler(handler, payload, eventName, mcpToolRunn
|
|
|
241
243
|
onTimeout: () => {
|
|
242
244
|
try {
|
|
243
245
|
controller.abort(new Error(`mcp_tool hook timed out: ${name}`));
|
|
244
|
-
} catch {
|
|
246
|
+
} catch {
|
|
247
|
+
// Abort is best-effort; the timeout error below is what callers see.
|
|
248
|
+
}
|
|
245
249
|
return new Error(`mcp_tool hook timed out: ${name}`);
|
|
246
250
|
},
|
|
247
251
|
}
|
|
@@ -54,6 +54,15 @@ import {
|
|
|
54
54
|
beginOAuthLogin as beginMuseCodeOAuthLogin,
|
|
55
55
|
loginOAuth as loginMuseCodeOAuth,
|
|
56
56
|
} from '../../runtime/agent/orchestrator/providers/muse-code-oauth-login.mjs';
|
|
57
|
+
import {
|
|
58
|
+
describeCommandCodeOAuthCredentials,
|
|
59
|
+
forgetCommandCodeOAuthCredentials,
|
|
60
|
+
hasCommandCodeOAuthCredentials,
|
|
61
|
+
} from '../../runtime/agent/orchestrator/providers/command-code-oauth-tokens.mjs';
|
|
62
|
+
import {
|
|
63
|
+
beginOAuthLogin as beginCommandCodeOAuthLogin,
|
|
64
|
+
loginOAuth as loginCommandCodeOAuth,
|
|
65
|
+
} from '../../runtime/agent/orchestrator/providers/command-code-oauth-login.mjs';
|
|
57
66
|
import {
|
|
58
67
|
beginCursorOAuthLogin,
|
|
59
68
|
describeCursorOAuthCredentials,
|
|
@@ -80,6 +89,7 @@ import {
|
|
|
80
89
|
changeProviderAccounts,
|
|
81
90
|
removeProviderAccount,
|
|
82
91
|
clearProviderAccountQuotaState,
|
|
92
|
+
providerAccountLimit,
|
|
83
93
|
ACCOUNT_PROVIDERS,
|
|
84
94
|
} from '../../runtime/shared/provider-accounts.mjs';
|
|
85
95
|
import { currentProviderAccountId, withProviderAccount } from '../../runtime/shared/provider-auth-binding.mjs';
|
|
@@ -154,6 +164,16 @@ const OAUTH_PROVIDERS = Object.freeze([
|
|
|
154
164
|
begin: beginMuseCodeOAuthLogin,
|
|
155
165
|
login: loginMuseCodeOAuth,
|
|
156
166
|
}),
|
|
167
|
+
Object.freeze({
|
|
168
|
+
id: 'command-code-oauth',
|
|
169
|
+
name: 'Command Code',
|
|
170
|
+
desc: 'Sign in with your Command Code account',
|
|
171
|
+
has: hasCommandCodeOAuthCredentials,
|
|
172
|
+
describe: describeCommandCodeOAuthCredentials,
|
|
173
|
+
forget: forgetCommandCodeOAuthCredentials,
|
|
174
|
+
begin: beginCommandCodeOAuthLogin,
|
|
175
|
+
login: loginCommandCodeOAuth,
|
|
176
|
+
}),
|
|
157
177
|
Object.freeze({
|
|
158
178
|
id: 'mimo-oauth',
|
|
159
179
|
name: 'MiMo',
|
|
@@ -421,6 +441,12 @@ function customProviderRow(id, entry, checkSecrets = true) {
|
|
|
421
441
|
const keyless = (config?.auth ?? entry.auth) === 'none';
|
|
422
442
|
const stored = checkSecrets ? hasStoredSecret(SECRET_ACCOUNTS.agentApiKey(id)) : false;
|
|
423
443
|
const unstoredStatus = configuredEnabled ? 'No Key' : 'Off';
|
|
444
|
+
let status = stored ? 'Set' : unstoredStatus;
|
|
445
|
+
let detail = stored ? 'stored in keychain' : 'custom endpoint';
|
|
446
|
+
if (keyless) {
|
|
447
|
+
status = configuredEnabled ? 'Keyless' : 'Off';
|
|
448
|
+
detail = 'no API key required';
|
|
449
|
+
}
|
|
424
450
|
const row = {
|
|
425
451
|
id,
|
|
426
452
|
name: entry.name,
|
|
@@ -431,12 +457,12 @@ function customProviderRow(id, entry, checkSecrets = true) {
|
|
|
431
457
|
group: 'api',
|
|
432
458
|
type: 'api-key',
|
|
433
459
|
enabled: configuredEnabled,
|
|
434
|
-
authenticated: keyless
|
|
460
|
+
authenticated: keyless || (checkSecrets ? stored : configuredEnabled),
|
|
435
461
|
stored,
|
|
436
462
|
env: false,
|
|
437
463
|
envName: null,
|
|
438
|
-
status
|
|
439
|
-
detail
|
|
464
|
+
status,
|
|
465
|
+
detail,
|
|
440
466
|
};
|
|
441
467
|
row.schemaVersion = config?.schemaVersion ?? entry.schemaVersion;
|
|
442
468
|
row.auth = keyless ? 'none' : 'key';
|
|
@@ -584,7 +610,7 @@ export async function loginOAuthProvider(cfgMod, provider) {
|
|
|
584
610
|
updateConfigProvider(cfgMod, id, { enabled: true });
|
|
585
611
|
// Same reason as the interactive add-account flow: a fresh credential says
|
|
586
612
|
// nothing about the quota the previous one exhausted.
|
|
587
|
-
if (ACCOUNT_PROVIDERS.includes(id)) clearProviderAccountQuotaState(id, currentProviderAccountId(id));
|
|
613
|
+
if (ACCOUNT_PROVIDERS.includes(id)) await clearProviderAccountQuotaState(id, currentProviderAccountId(id));
|
|
588
614
|
}
|
|
589
615
|
return { provider: id, type: 'oauth', authenticated: Boolean(auth.authenticated), status: auth.status || null };
|
|
590
616
|
}
|
|
@@ -621,7 +647,7 @@ function rosterAccountForIdentity(id, oauth, newAccountId, auth) {
|
|
|
621
647
|
return match?.id || null;
|
|
622
648
|
}
|
|
623
649
|
|
|
624
|
-
function settleOAuthLogin(
|
|
650
|
+
async function settleOAuthLogin(
|
|
625
651
|
{ cfgMod, id, accountId: signedInId, addAccount, includeDefault, label, inAccount, oauth },
|
|
626
652
|
result
|
|
627
653
|
) {
|
|
@@ -635,11 +661,11 @@ function settleOAuthLogin(
|
|
|
635
661
|
renameSync(providerAccountPath(id, signedInId), providerAccountPath(id, existingId));
|
|
636
662
|
accountId = existingId;
|
|
637
663
|
}
|
|
638
|
-
registerProviderAccount(id, accountId, { includeDefault, label });
|
|
664
|
+
await registerProviderAccount(id, accountId, { includeDefault, label });
|
|
639
665
|
// A re-connect can follow a re-created subscription under the same
|
|
640
666
|
// account id: start it from no recorded quota rather than from the
|
|
641
667
|
// exhausted window the previous credential earned.
|
|
642
|
-
clearProviderAccountQuotaState(id, accountId);
|
|
668
|
+
await clearProviderAccountQuotaState(id, accountId);
|
|
643
669
|
updateConfigProvider(cfgMod, id, { enabled: true });
|
|
644
670
|
}
|
|
645
671
|
return {
|
|
@@ -688,12 +714,20 @@ export async function beginOAuthProviderLogin(cfgMod, provider, options = {}) {
|
|
|
688
714
|
// The callback and a pasted code can both deliver the same sign-in; it must
|
|
689
715
|
// settle once, because settling may move the credential to an existing id.
|
|
690
716
|
let settled = null;
|
|
717
|
+
let settling = null;
|
|
691
718
|
const finish = async (result) => {
|
|
692
719
|
if (!result || cancelled) return null;
|
|
693
720
|
if (settled) return settled;
|
|
694
|
-
|
|
695
|
-
if (
|
|
696
|
-
|
|
721
|
+
// Settling is async now: a second delivery arriving mid-write shares it.
|
|
722
|
+
if (settling) return settling;
|
|
723
|
+
settling = settleOAuthLogin(login, result);
|
|
724
|
+
try {
|
|
725
|
+
const outcome = await settling;
|
|
726
|
+
if (outcome.authenticated) settled = outcome;
|
|
727
|
+
return outcome;
|
|
728
|
+
} finally {
|
|
729
|
+
settling = null;
|
|
730
|
+
}
|
|
697
731
|
};
|
|
698
732
|
return {
|
|
699
733
|
provider: id,
|
|
@@ -721,9 +755,11 @@ export function listProviderAccounts(provider) {
|
|
|
721
755
|
if (!oauth) throw new TypeError('Unknown OAuth provider.');
|
|
722
756
|
const pool = readProviderAccountPool(provider);
|
|
723
757
|
const accounts = pool.accounts.length ? pool.accounts : defaultAccountRows(provider, oauth);
|
|
758
|
+
const now = Date.now();
|
|
724
759
|
return {
|
|
725
760
|
provider,
|
|
726
761
|
auto: pool.auto !== false,
|
|
762
|
+
policy: pool.policy,
|
|
727
763
|
useCredits: pool.useCredits === true,
|
|
728
764
|
selectedId: pool.selectedId || accounts[0]?.id || null,
|
|
729
765
|
accounts: accounts.map((row) => {
|
|
@@ -740,6 +776,9 @@ export function listProviderAccounts(provider) {
|
|
|
740
776
|
reauthRequired: auth.reauthRequired === true,
|
|
741
777
|
usage: row.usage || null,
|
|
742
778
|
blockedUntil: row.blockedUntil || null,
|
|
779
|
+
// The limit holding the account now: account-wide, or only for one
|
|
780
|
+
// model family ("7D Fable") while other models still run.
|
|
781
|
+
limit: providerAccountLimit(row, now, { useCredits: pool.useCredits === true }),
|
|
743
782
|
...(identity ? { identity } : {}),
|
|
744
783
|
...(typeof auth.email === 'string' && auth.email.trim() ? { email: auth.email.trim() } : {}),
|
|
745
784
|
};
|
|
@@ -753,17 +792,23 @@ function defaultAccountRows(provider, oauth) {
|
|
|
753
792
|
return authenticated ? [{ id: 'default', label: 'Account 1' }] : [];
|
|
754
793
|
}
|
|
755
794
|
|
|
756
|
-
|
|
795
|
+
// Store the implicit signed-in `default` account in the roster, so a change or
|
|
796
|
+
// a usage measurement has a row to land on. Returns the current roster view.
|
|
797
|
+
export async function materializeProviderAccounts(provider) {
|
|
757
798
|
const current = listProviderAccounts(provider);
|
|
758
|
-
if (
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
799
|
+
if (readProviderAccountPool(provider).accounts.length || !current.accounts.length) return current;
|
|
800
|
+
await registerProviderAccount(provider, 'default', { label: 'Account 1' });
|
|
801
|
+
return listProviderAccounts(provider);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
export async function updateProviderAccounts(provider, change) {
|
|
805
|
+
await materializeProviderAccounts(provider);
|
|
806
|
+
await changeProviderAccounts(provider, change);
|
|
762
807
|
// Picking an account by hand is a decision to use it NOW, so the refusal
|
|
763
808
|
// window and meter stored against it — both describing the state the user
|
|
764
809
|
// just changed — are dropped here. Never in the pool's own fallback commit,
|
|
765
810
|
// where clearing them would send the request back to a spent account.
|
|
766
|
-
if (change?.selectedId !== undefined) clearProviderAccountQuotaState(provider, change.selectedId);
|
|
811
|
+
if (change?.selectedId !== undefined) await clearProviderAccountQuotaState(provider, change.selectedId);
|
|
767
812
|
return listProviderAccounts(provider);
|
|
768
813
|
}
|
|
769
814
|
|
|
@@ -859,7 +904,8 @@ async function resolveCustomInput(cfgMod, rawInput, options) {
|
|
|
859
904
|
const config = normalizeCustomProviderConfig(input, options);
|
|
860
905
|
const typed = typeof input.apiKey === 'string' ? input.apiKey.trim() : '';
|
|
861
906
|
const keyless = config.auth === 'none';
|
|
862
|
-
|
|
907
|
+
let apiKey = '';
|
|
908
|
+
if (!keyless) apiKey = typed || (id ? getAgentApiKey(id) || '' : '');
|
|
863
909
|
return { id, config, typed: keyless ? '' : typed, apiKey, keyless };
|
|
864
910
|
}
|
|
865
911
|
|
|
@@ -1078,7 +1124,7 @@ export async function forgetProviderAuth(cfgModOrProvider, maybeProvider, reques
|
|
|
1078
1124
|
throw new TypeError('Account is no longer connected.');
|
|
1079
1125
|
}
|
|
1080
1126
|
const result = withProviderAccount(id, accountId, () => oauth.forget());
|
|
1081
|
-
const pool = removeProviderAccount(id, accountId);
|
|
1127
|
+
const pool = await removeProviderAccount(id, accountId);
|
|
1082
1128
|
if (cfgMod) updateConfigProvider(cfgMod, id, { enabled: pool.accounts.length > 0 });
|
|
1083
1129
|
return { provider: id, type: 'oauth', forgotten: true, removed: Boolean(result?.removed) };
|
|
1084
1130
|
}
|
|
@@ -236,6 +236,8 @@ function providerDescription(id, group) {
|
|
|
236
236
|
return 'Grok Build subscription quota';
|
|
237
237
|
case 'muse-code-oauth':
|
|
238
238
|
return 'Muse Code subscription quota';
|
|
239
|
+
case 'command-code-oauth':
|
|
240
|
+
return 'Command Code subscription quota';
|
|
239
241
|
case 'mimo-oauth':
|
|
240
242
|
return 'MiMo Token Plan subscription quota';
|
|
241
243
|
case 'antigravity-oauth':
|
|
@@ -343,6 +345,7 @@ const PROVIDER_RANKS = {
|
|
|
343
345
|
'anthropic-oauth': 20,
|
|
344
346
|
'grok-oauth': 30,
|
|
345
347
|
'muse-code-oauth': 33,
|
|
348
|
+
'command-code-oauth': 33.5,
|
|
346
349
|
'mimo-oauth': 34,
|
|
347
350
|
'cursor-oauth': 35,
|
|
348
351
|
'antigravity-oauth': 36,
|
|
@@ -82,6 +82,7 @@ export function createCompactionSettings({
|
|
|
82
82
|
const next = { ...current };
|
|
83
83
|
if (hasOwn(input, 'auto')) next.auto = input.auto !== false;
|
|
84
84
|
if (hasOwn(input, 'enabled')) next.auto = input.enabled !== false;
|
|
85
|
+
if (hasOwn(input, 'onModelChange')) next.onModelChange = input.onModelChange !== false;
|
|
85
86
|
// Legacy Compact type fields are intentionally ignored. There is one
|
|
86
87
|
// fresh-context Compact contract for every session.
|
|
87
88
|
// A new budget representation replaces the previous one. Otherwise a
|
|
@@ -146,6 +146,7 @@ function publicAccounts(pool) {
|
|
|
146
146
|
return {
|
|
147
147
|
selectedId: pool.selectedId,
|
|
148
148
|
auto: pool.auto,
|
|
149
|
+
...(pool.policy ? { policy: pool.policy } : {}),
|
|
149
150
|
useCredits: pool.useCredits === true,
|
|
150
151
|
accounts: pool.accounts.map(({ id, label, authenticated, reauthRequired }) => ({
|
|
151
152
|
id,
|
|
@@ -166,9 +167,15 @@ function mcpRows(status) {
|
|
|
166
167
|
transport: server.transport || server.type || '',
|
|
167
168
|
toolCount: Number(server.toolCount || 0),
|
|
168
169
|
source: server.source || '',
|
|
170
|
+
...(server.owner?.kind === 'plugin'
|
|
171
|
+
? { plugin: server.owner.id, pluginServer: server.owner.key, disabledReason: server.disabledReason || null }
|
|
172
|
+
: {}),
|
|
169
173
|
error: server.error || null,
|
|
174
|
+
...(server.warnings?.length ? { warnings: server.warnings } : {}),
|
|
170
175
|
scope: Array.isArray(server.scope) ? server.scope : null,
|
|
171
176
|
})),
|
|
177
|
+
...(status?.warnings?.length ? { warnings: status.warnings } : {}),
|
|
178
|
+
...(status?.declarationErrors?.length ? { declarationErrors: status.declarationErrors } : {}),
|
|
172
179
|
};
|
|
173
180
|
}
|
|
174
181
|
|
|
@@ -577,7 +584,11 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
577
584
|
const plugin = ((await rt.pluginsStatus())?.plugins || []).find((row) => row.name === name || row.id === name);
|
|
578
585
|
if (!plugin) throw new Error(`plugin "${name}" not found`);
|
|
579
586
|
const result = await rt.enablePluginMcp(plugin);
|
|
580
|
-
return {
|
|
587
|
+
return {
|
|
588
|
+
serverName: result.serverName,
|
|
589
|
+
...(result.serverNames ? { serverNames: result.serverNames } : {}),
|
|
590
|
+
mcp: mcpRows(result.status),
|
|
591
|
+
};
|
|
581
592
|
},
|
|
582
593
|
};
|
|
583
594
|
|
|
@@ -34,6 +34,7 @@ function publicMcpConfig(row) {
|
|
|
34
34
|
return {
|
|
35
35
|
name: row.name,
|
|
36
36
|
source: row.source,
|
|
37
|
+
...(row.owner?.kind === 'plugin' ? { plugin: row.owner.id, pluginServer: row.owner.key, readOnly: true } : {}),
|
|
37
38
|
enabled: row.enabled !== false,
|
|
38
39
|
type: config.type || 'stdio',
|
|
39
40
|
cwd: config.cwd || '',
|
|
@@ -196,6 +196,7 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
196
196
|
runInBackground: boolean,
|
|
197
197
|
turnNotifications: boolean,
|
|
198
198
|
usagePinned: boolean,
|
|
199
|
+
usageRailShortLong: boolean,
|
|
199
200
|
computerObserveOnly: boolean,
|
|
200
201
|
notificationVolume: {
|
|
201
202
|
type: 'integer',
|
|
@@ -227,7 +227,7 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
227
227
|
type: 'string',
|
|
228
228
|
enum: [...INSTRUCTION_FILES_MODES],
|
|
229
229
|
description:
|
|
230
|
-
|
|
230
|
+
"set_instruction_files: which user instruction files new sessions load (global ~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, then the Project root's AGENTS.md/CLAUDE.md).",
|
|
231
231
|
},
|
|
232
232
|
name: {
|
|
233
233
|
type: 'string',
|
|
@@ -244,6 +244,12 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
244
244
|
properties: {
|
|
245
245
|
selectedId: { type: 'string', description: 'Account to use now.' },
|
|
246
246
|
auto: { type: 'boolean', description: 'Automatic switching to another account when one is exhausted.' },
|
|
247
|
+
policy: {
|
|
248
|
+
type: 'string',
|
|
249
|
+
enum: ['manual', 'limit', 'headroom'],
|
|
250
|
+
description:
|
|
251
|
+
'Account switching: manual = selected account only; limit = switch when it reaches a limit; headroom = each new session starts on the account with the most headroom.',
|
|
252
|
+
},
|
|
247
253
|
useCredits: { type: 'boolean', description: 'Allow paid credits once plan limits are reached.' },
|
|
248
254
|
order: {
|
|
249
255
|
type: 'array',
|
|
@@ -24,8 +24,8 @@ const DEFAULT_SKILL_BODY = '# Instructions\n\nDescribe how to use this skill.';
|
|
|
24
24
|
export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
25
25
|
const globalSkillsRoot = () => resolve(resolvePluginData(), 'skills');
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
/** `cwd` overrides the session's folder (already validated by the caller). */
|
|
28
|
+
function skillsStatus({ cwd = getCwd() } = {}) {
|
|
29
29
|
const skills = typeof contextMod.collectSkillsCached === 'function' ? contextMod.collectSkillsCached(cwd) : [];
|
|
30
30
|
const norm = (value) =>
|
|
31
31
|
String(value || '')
|
|
@@ -54,7 +54,10 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
54
54
|
const source = sourceForSkill(skill);
|
|
55
55
|
return {
|
|
56
56
|
name: skill.name,
|
|
57
|
-
enabled: !(
|
|
57
|
+
enabled: !(
|
|
58
|
+
contextMod.isSkillDisabled?.(skill.name, null, skills) ||
|
|
59
|
+
contextMod.skillMissingFeature?.(skill.name, null, skills)
|
|
60
|
+
),
|
|
58
61
|
description: skill.description || '',
|
|
59
62
|
whenToUse: skill.whenToUse || '',
|
|
60
63
|
filePath: skill.filePath || null,
|
|
@@ -90,6 +93,7 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
90
93
|
if (typeof contextMod.isSkillDisabled === 'function' && contextMod.isSkillDisabled(skillName)) {
|
|
91
94
|
return `Error: skill "${skillName}" is disabled`;
|
|
92
95
|
}
|
|
96
|
+
if (contextMod.skillOutsideScope?.(skillName, getCwd())) return contextMod.skillOutsideScopeError(skillName);
|
|
93
97
|
const skill = skillContent(skillName);
|
|
94
98
|
// The general tool envelope keeps the main/Lead session identical to agent
|
|
95
99
|
// loops: the model-visible tool_result is the short stub and the SKILL.md
|
|
@@ -91,6 +91,7 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
|
|
|
91
91
|
onStreamDelta: streamDelta(turn, options),
|
|
92
92
|
drainSteering: options.drainSteering,
|
|
93
93
|
onSteerMessage: options.onSteerMessage,
|
|
94
|
+
onSkillsApplied: options.onSkillsApplied,
|
|
94
95
|
notifyFn: notifyFnForSession(session0.id),
|
|
95
96
|
signal: turn.signal,
|
|
96
97
|
};
|