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
|
@@ -296,6 +296,7 @@ export function createSessionService({
|
|
|
296
296
|
},
|
|
297
297
|
getSize: () => sessions.size,
|
|
298
298
|
getBusyCount: retention.liveBusyCount,
|
|
299
|
+
getTurnBusyCount: retention.liveTurnBusyCount,
|
|
299
300
|
getStatus,
|
|
300
301
|
getExternalClientCount: () => desktopServices.externalClientCount,
|
|
301
302
|
});
|
package/src/tui/App.jsx
CHANGED
|
@@ -21,6 +21,7 @@ import { useApp, useStdin, useStdout } from 'ink';
|
|
|
21
21
|
import { useSession } from './hooks/useSession.mjs';
|
|
22
22
|
import { pickFolder } from '../standalone/folder-dialog.mjs';
|
|
23
23
|
import { deriveSlashPalette } from './app/slash-palette.mjs';
|
|
24
|
+
import { skillMentionQuery, useSkillMentionSkills } from './app/skill-mention-palette.mjs';
|
|
24
25
|
import { shouldSupersedePanelEpoch, supersedePanelEpoch } from './app/panel-epoch.mjs';
|
|
25
26
|
import { createPanelSurface } from './app/panel-surface.mjs';
|
|
26
27
|
import { resolvePickerState } from './app/picker-index-mode.mjs';
|
|
@@ -215,6 +216,8 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
|
|
|
215
216
|
setPromptDraft,
|
|
216
217
|
promptDraftOverride,
|
|
217
218
|
setPromptDraftOverride,
|
|
219
|
+
promptCaret,
|
|
220
|
+
setPromptCaret,
|
|
218
221
|
promptLayoutValueRef,
|
|
219
222
|
setPromptLayoutRows,
|
|
220
223
|
textEntryLayoutRows,
|
|
@@ -625,7 +628,8 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
|
|
|
625
628
|
pastedTextsRef,
|
|
626
629
|
});
|
|
627
630
|
|
|
628
|
-
const
|
|
631
|
+
const mentionSkills = useSkillMentionSkills(store, skillMentionQuery(promptDraft, promptCaret) !== null);
|
|
632
|
+
const { activeSlashQuery, slashCommands, slashPaletteOpen, paletteKind } = deriveSlashPalette({
|
|
629
633
|
providerPrompt,
|
|
630
634
|
settingsPrompt,
|
|
631
635
|
toolApproval,
|
|
@@ -636,6 +640,8 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
|
|
|
636
640
|
commandBusy: state.commandBusy,
|
|
637
641
|
promptDraft,
|
|
638
642
|
slashDismissedFor,
|
|
643
|
+
skills: mentionSkills,
|
|
644
|
+
promptCaret,
|
|
639
645
|
});
|
|
640
646
|
slashPaletteRef.current = { open: slashPaletteOpen, count: slashCommands.length };
|
|
641
647
|
scrollFocusRef.current = {
|
|
@@ -833,10 +839,12 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
|
|
|
833
839
|
hasUserMessages,
|
|
834
840
|
initialStatusLine,
|
|
835
841
|
onPromptDraftChange,
|
|
842
|
+
onPromptCaretChange: setPromptCaret,
|
|
836
843
|
onSubmit,
|
|
837
844
|
overlayHintAttachItemIndex,
|
|
838
845
|
overlayHintFallbackRow,
|
|
839
846
|
overlayHintOnLastItem,
|
|
847
|
+
paletteKind,
|
|
840
848
|
panelInkMaskEpoch,
|
|
841
849
|
panelTransitionEpoch,
|
|
842
850
|
picker,
|
|
@@ -18,6 +18,12 @@ import { textEntryClearsByEmpty } from '../text-entry-policy.mjs';
|
|
|
18
18
|
import { withPickerEnterLatch } from '../picker-enter-latch.mjs';
|
|
19
19
|
import { providerPromptFields, settingsPromptFields } from './text-entry-labels.mjs';
|
|
20
20
|
|
|
21
|
+
// `$name` skill completion reuses the command palette with its own copy.
|
|
22
|
+
const SKILL_PALETTE_TEXT = {
|
|
23
|
+
description: 'Type to filter · Enter or Tab inserts the highlighted skill.',
|
|
24
|
+
help: '↑/↓ select · Enter insert · Esc cancel',
|
|
25
|
+
};
|
|
26
|
+
|
|
21
27
|
function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionPanel }) {
|
|
22
28
|
const resolve = (approved) => {
|
|
23
29
|
store.resolveToolApproval?.(toolApproval.id, {
|
|
@@ -166,13 +172,15 @@ export function renderFloatingPanel(ctx) {
|
|
|
166
172
|
);
|
|
167
173
|
}
|
|
168
174
|
if (slashPaletteOpen) {
|
|
175
|
+
const skills = ctx.paletteKind === 'skills';
|
|
169
176
|
return (
|
|
170
177
|
<SlashCommandPalette
|
|
171
178
|
commands={slashCommands}
|
|
172
179
|
selectedIndex={slashIndex}
|
|
173
|
-
title=
|
|
180
|
+
title={skills ? 'Skills' : 'Commands'}
|
|
174
181
|
columns={frameColumns}
|
|
175
182
|
query={activeSlashQuery}
|
|
183
|
+
{...(skills ? SKILL_PALETTE_TEXT : {})}
|
|
176
184
|
/>
|
|
177
185
|
);
|
|
178
186
|
}
|
package/src/tui/app/app-view.jsx
CHANGED
|
@@ -52,8 +52,10 @@ export function renderAppView(ctx) {
|
|
|
52
52
|
inputHint,
|
|
53
53
|
inputHintTone,
|
|
54
54
|
liveSpinner,
|
|
55
|
+
onPromptCaretChange,
|
|
55
56
|
onPromptDraftChange,
|
|
56
57
|
onSubmit,
|
|
58
|
+
paletteKind,
|
|
57
59
|
panelTransitionClearRows,
|
|
58
60
|
picker,
|
|
59
61
|
promptBoxRectRef,
|
|
@@ -85,6 +87,7 @@ export function renderAppView(ctx) {
|
|
|
85
87
|
onSubmit={onSubmit}
|
|
86
88
|
disabled={exiting || !!picker || !!contextPanel || !!toolApproval || !tuiReady}
|
|
87
89
|
onDraftChange={onPromptDraftChange}
|
|
90
|
+
onCaretChange={onPromptCaretChange}
|
|
88
91
|
interruptActive={state.busy}
|
|
89
92
|
onInterrupt={handlePromptInterrupt}
|
|
90
93
|
initialValue={promptDraft}
|
|
@@ -108,6 +111,9 @@ export function renderAppView(ctx) {
|
|
|
108
111
|
commandPaletteActive={slashPaletteOpen && slashCommands.length > 0}
|
|
109
112
|
commandPaletteOpen={slashPaletteOpen}
|
|
110
113
|
commandPaletteOptionCount={slashCommands.length}
|
|
114
|
+
// The `$name` skill palette leaves Left/Right to the caret: the
|
|
115
|
+
// mention follows it.
|
|
116
|
+
commandPaletteMovesCaret={paletteKind === 'skills'}
|
|
111
117
|
onCommandPaletteNavigate={(direction) => {
|
|
112
118
|
setSlashIndex((index) => stepPaletteIndex(index, direction, slashCommands.length));
|
|
113
119
|
}}
|
|
@@ -229,6 +235,7 @@ export function renderAppView(ctx) {
|
|
|
229
235
|
model={state.model}
|
|
230
236
|
effort={state.effort}
|
|
231
237
|
fast={state.fast}
|
|
238
|
+
ultra={state.fast === true && state.modelParameters?.serviceTier === 'ultrafast'}
|
|
232
239
|
cwd={state.cwd}
|
|
233
240
|
stats={statuslineStats}
|
|
234
241
|
contextWindow={state.contextWindow}
|
|
@@ -88,6 +88,8 @@ export function createAppPickers({
|
|
|
88
88
|
const {
|
|
89
89
|
openMcpServersPicker,
|
|
90
90
|
openMcpPicker,
|
|
91
|
+
loginMcpServer,
|
|
92
|
+
logoutMcpServer,
|
|
91
93
|
openProjectSkillsPicker,
|
|
92
94
|
openSkillsPicker,
|
|
93
95
|
openSkillDetailPicker,
|
|
@@ -219,6 +221,8 @@ export function createAppPickers({
|
|
|
219
221
|
enterProject: (...a) => enterProject(...a),
|
|
220
222
|
openProjectPicker: (...a) => openProjectPicker(...a),
|
|
221
223
|
openMcpPicker: (...a) => openMcpPicker(...a),
|
|
224
|
+
loginMcpServer,
|
|
225
|
+
logoutMcpServer,
|
|
222
226
|
openSkillsPicker: (...a) => openSkillsPicker(...a),
|
|
223
227
|
openPluginsPicker: (...a) => openPluginsPicker(...a),
|
|
224
228
|
openProviderSetupPicker: (...a) => openProviderSetupPicker(...a),
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// extension-pickers/mcp-login.mjs
|
|
2
|
+
// `/mcp login <name>` and `/mcp logout <name>`. The sign-in URL is always
|
|
3
|
+
// printed (and kept in the live prompt); the runtime may open the browser. The
|
|
4
|
+
// flow is polled while a paste prompt (the shared 'oauth-code' provider prompt)
|
|
5
|
+
// accepts the final redirect address. Pasted text is never echoed.
|
|
6
|
+
const POLL_MS = 1500;
|
|
7
|
+
|
|
8
|
+
export function createMcpLogin({ store, setProviderPrompt, pollMs = POLL_MS }) {
|
|
9
|
+
let active = null;
|
|
10
|
+
|
|
11
|
+
const stop = (flow) => {
|
|
12
|
+
flow.finished = true;
|
|
13
|
+
clearTimeout(flow.timer);
|
|
14
|
+
if (active === flow) active = null;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const closePrompt = (flow) => setProviderPrompt((prompt) => (prompt === flow.prompt ? null : prompt));
|
|
18
|
+
|
|
19
|
+
const showPrompt = (flow) => {
|
|
20
|
+
if (flow.finished) return;
|
|
21
|
+
const prompt = {
|
|
22
|
+
kind: 'oauth-code',
|
|
23
|
+
providerName: `MCP ${flow.name}`,
|
|
24
|
+
// The shared prompt pushes the one completion notice; no provider picker follows.
|
|
25
|
+
successReturn: () => {},
|
|
26
|
+
label: `MCP sign-in · ${flow.name}`,
|
|
27
|
+
hint: 'If the browser page fails to load, paste its address here.',
|
|
28
|
+
detail: flow.url,
|
|
29
|
+
login: {
|
|
30
|
+
completeCode: async (text) => {
|
|
31
|
+
const result = await store.completeMcpOAuthLogin(flow.id, text);
|
|
32
|
+
if (result?.state !== 'complete') throw new Error(result?.error || 'sign-in did not complete');
|
|
33
|
+
stop(flow);
|
|
34
|
+
},
|
|
35
|
+
cancel: () => {
|
|
36
|
+
if (flow.finished) return;
|
|
37
|
+
stop(flow);
|
|
38
|
+
void Promise.resolve(store.cancelMcpOAuthLogin(flow.id)).catch(() => {});
|
|
39
|
+
store.pushNotice(`MCP sign-in cancelled for ${flow.name}`, 'info');
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
failureReturn: () => showPrompt(flow),
|
|
43
|
+
};
|
|
44
|
+
flow.prompt = prompt;
|
|
45
|
+
setProviderPrompt(prompt);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const poll = (flow) => {
|
|
49
|
+
flow.timer = setTimeout(async () => {
|
|
50
|
+
if (flow.finished) return;
|
|
51
|
+
let status;
|
|
52
|
+
try {
|
|
53
|
+
status = await store.getMcpOAuthLoginStatus(flow.id);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
if (flow.finished) return;
|
|
56
|
+
stop(flow);
|
|
57
|
+
closePrompt(flow);
|
|
58
|
+
store.pushNotice(`MCP sign-in failed for ${flow.name}: ${e?.message || e}`, 'error');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (flow.finished) return;
|
|
62
|
+
if (status?.state === 'pending') {
|
|
63
|
+
poll(flow);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
stop(flow);
|
|
67
|
+
closePrompt(flow);
|
|
68
|
+
if (status?.state === 'complete') store.pushNotice(`MCP sign-in complete for ${flow.name}`, 'info');
|
|
69
|
+
else if (status?.state === 'cancelled') store.pushNotice(`MCP sign-in cancelled for ${flow.name}`, 'info');
|
|
70
|
+
else store.pushNotice(`MCP sign-in failed for ${flow.name}${status?.error ? `: ${status.error}` : ''}`, 'error');
|
|
71
|
+
}, pollMs);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const loginMcpServer = async (name) => {
|
|
75
|
+
if (active) {
|
|
76
|
+
const previous = active;
|
|
77
|
+
stop(previous);
|
|
78
|
+
closePrompt(previous);
|
|
79
|
+
void Promise.resolve(store.cancelMcpOAuthLogin(previous.id)).catch(() => {});
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const started = await store.beginMcpOAuthLogin(name, { openBrowser: true });
|
|
83
|
+
if (started?.state === 'complete') {
|
|
84
|
+
store.pushNotice(`MCP sign-in complete for ${name}`, 'info');
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const flow = { id: started.flowId, name, url: started.url || '', finished: false, timer: null, prompt: null };
|
|
88
|
+
active = flow;
|
|
89
|
+
if (flow.url) store.pushNotice(`Sign in to ${name}: ${flow.url}`, 'info');
|
|
90
|
+
showPrompt(flow);
|
|
91
|
+
poll(flow);
|
|
92
|
+
} catch (e) {
|
|
93
|
+
store.pushNotice(`MCP sign-in failed for ${name}: ${e?.message || e}`, 'error');
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const logoutMcpServer = async (name) => {
|
|
98
|
+
try {
|
|
99
|
+
await store.signOutMcpServer(name);
|
|
100
|
+
store.pushNotice(`MCP signed out of ${name}`, 'info');
|
|
101
|
+
} catch (e) {
|
|
102
|
+
store.pushNotice(`MCP sign-out failed for ${name}: ${e?.message || e}`, 'error');
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return { loginMcpServer, logoutMcpServer };
|
|
107
|
+
}
|
|
@@ -8,8 +8,9 @@ const serverDescription = (server, pending, optimistic) => {
|
|
|
8
8
|
const transport = server.transport || 'unknown';
|
|
9
9
|
if (pending) return `${optimistic.enabled ? 'enabling' : 'disabling'}… · ${transport}`;
|
|
10
10
|
const error = server.error ? ` · ${server.error}` : '';
|
|
11
|
+
const signIn = server.authRequired ? ` · sign-in required: /mcp login ${server.name}` : '';
|
|
11
12
|
return withScope(
|
|
12
|
-
`${server.source || 'config'} · ${server.status || 'unknown'} · ${transport} · ${server.toolCount || 0} tools${error}`,
|
|
13
|
+
`${server.source || 'config'} · ${server.status || 'unknown'} · ${transport} · ${server.toolCount || 0} tools${error}${signIn}`,
|
|
13
14
|
server
|
|
14
15
|
);
|
|
15
16
|
};
|
|
@@ -3,34 +3,52 @@
|
|
|
3
3
|
// (info / update / MCP / copy / uninstall) and the add-plugin prompt.
|
|
4
4
|
import { readStatus, withScope } from './scope-note.mjs';
|
|
5
5
|
|
|
6
|
+
// A plugin's MCP servers are derived from its declarations (`mcpServers` on
|
|
7
|
+
// the status row); older hosts only report `mcpScript`/`mcpServerName`.
|
|
8
|
+
function mcpNames(p) {
|
|
9
|
+
if (Array.isArray(p.mcpServers)) return p.mcpServers.map((server) => server.name);
|
|
10
|
+
return p.mcpServerName ? [p.mcpServerName] : [];
|
|
11
|
+
}
|
|
12
|
+
const hasMcp = (p) => mcpNames(p).length > 0 || Boolean(p.mcpScript || p.mcpInline);
|
|
13
|
+
|
|
14
|
+
function serverState(server) {
|
|
15
|
+
if (server.serverEnabled === false) return 'off';
|
|
16
|
+
if (server.enabled === false) return 'plugin off';
|
|
17
|
+
return server.status || (server.connected ? 'connected' : 'disconnected');
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
const mcpSummary = (p) => {
|
|
7
|
-
if (!p
|
|
8
|
-
|
|
9
|
-
return `${
|
|
21
|
+
if (!hasMcp(p))
|
|
22
|
+
return Array.isArray(p.mcpErrors) && p.mcpErrors.length ? `(invalid: ${p.mcpErrors[0].message})` : '(none)';
|
|
23
|
+
if (!Array.isArray(p.mcpServers)) return `${p.mcpEnabled ? 'enabled' : 'available'} (${mcpNames(p).join(', ')})`;
|
|
24
|
+
const errors =
|
|
25
|
+
Array.isArray(p.mcpErrors) && p.mcpErrors.length ? ` · ${p.mcpErrors.length} declaration error(s)` : '';
|
|
26
|
+
return `${p.mcpServers.map((server) => `${server.name} ${serverState(server)}`).join(', ')}${errors}`;
|
|
10
27
|
};
|
|
11
28
|
|
|
12
29
|
function mcpActionItem(p) {
|
|
13
|
-
if (!p
|
|
30
|
+
if (!hasMcp(p)) {
|
|
14
31
|
return {
|
|
15
32
|
value: 'enable-mcp',
|
|
16
|
-
label: 'No MCP
|
|
17
|
-
description: 'plugin
|
|
33
|
+
label: 'No MCP server',
|
|
34
|
+
description: 'plugin declares no MCP servers (.mcp.json or manifest mcpServers)',
|
|
18
35
|
_action: 'noop',
|
|
19
36
|
};
|
|
20
37
|
}
|
|
21
38
|
return {
|
|
22
39
|
value: 'enable-mcp',
|
|
23
|
-
label: p.mcpEnabled ? '
|
|
24
|
-
description: `${p.
|
|
40
|
+
label: p.mcpEnabled ? 'Reconnect MCP servers' : 'Enable MCP servers',
|
|
41
|
+
description: `${mcpNames(p).join(', ') || 'plugin MCP'} · ${p.mcpEnabled ? 'on' : 'turned off'}`,
|
|
25
42
|
_action: 'enable-mcp',
|
|
26
43
|
};
|
|
27
44
|
}
|
|
28
45
|
|
|
29
46
|
function pluginSummary(plugin) {
|
|
30
47
|
const version = plugin.version ? ` · ${plugin.version}` : '';
|
|
31
|
-
const
|
|
32
|
-
const mcp = plugin
|
|
33
|
-
|
|
48
|
+
const mcpOff = plugin.mcpEnabled ? '' : ' off';
|
|
49
|
+
const mcp = hasMcp(plugin) ? ` · mcp ${mcpNames(plugin).length || 1}${mcpOff}` : '';
|
|
50
|
+
const warning = plugin.warning ? ` · ⚠ ${plugin.warning}` : '';
|
|
51
|
+
return `${plugin.sourceType || plugin.source}${version} · skills ${plugin.skillCount || 0}${mcp}${warning}`;
|
|
34
52
|
}
|
|
35
53
|
|
|
36
54
|
const pluginInfoNotice = (p) =>
|
|
@@ -41,6 +59,7 @@ const pluginInfoNotice = (p) =>
|
|
|
41
59
|
`mcp: ${mcpSummary(p)}`,
|
|
42
60
|
`applies to: ${Array.isArray(p.scope) && p.scope.length ? p.scope.join(', ') : 'all projects'}`,
|
|
43
61
|
`root: ${p.root}`,
|
|
62
|
+
p.warning ? `warning: ${p.warning}` : '',
|
|
44
63
|
p.description ? `\n${p.description}` : '',
|
|
45
64
|
]
|
|
46
65
|
.filter(Boolean)
|
|
@@ -68,9 +87,9 @@ const pluginDetailItems = (p) => [
|
|
|
68
87
|
},
|
|
69
88
|
{
|
|
70
89
|
value: 'copy-mcp-name',
|
|
71
|
-
label: p.
|
|
72
|
-
description: p.
|
|
73
|
-
_action: p.
|
|
90
|
+
label: mcpNames(p).length ? 'Copy MCP server name' : 'No MCP server name',
|
|
91
|
+
description: mcpNames(p).join(', '),
|
|
92
|
+
_action: mcpNames(p).length ? 'copy-mcp-name' : 'noop',
|
|
74
93
|
},
|
|
75
94
|
{
|
|
76
95
|
value: 'uninstall',
|
|
@@ -127,7 +146,7 @@ export function createPluginsPickers({
|
|
|
127
146
|
void store
|
|
128
147
|
.enablePluginMcp?.(p)
|
|
129
148
|
.then(own.defer(() => openMcpPicker()))
|
|
130
|
-
.catch((e) => store.pushNotice(`plugin MCP
|
|
149
|
+
.catch((e) => store.pushNotice(`plugin MCP reconnect failed: ${e?.message || e}`, 'error'));
|
|
131
150
|
return;
|
|
132
151
|
}
|
|
133
152
|
if (detail._action === 'copy-root') {
|
|
@@ -135,7 +154,7 @@ export function createPluginsPickers({
|
|
|
135
154
|
return;
|
|
136
155
|
}
|
|
137
156
|
if (detail._action === 'copy-mcp-name') {
|
|
138
|
-
copyText(p.
|
|
157
|
+
copyText(mcpNames(p).join(', '), `copied plugin MCP server: ${mcpNames(p).join(', ')}`);
|
|
139
158
|
return;
|
|
140
159
|
}
|
|
141
160
|
if (detail._action === 'uninstall') {
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* store state, so they can't be pure. openMcpPicker is exposed for the
|
|
8
8
|
* plugin-detail enable-mcp path (also aliased on the App body).
|
|
9
9
|
*/
|
|
10
|
+
import { createMcpLogin } from './extension-pickers/mcp-login.mjs';
|
|
10
11
|
import { createMcpServersPicker } from './extension-pickers/mcp-servers-picker.mjs';
|
|
11
12
|
import { createPluginsPickers } from './extension-pickers/plugins-pickers.mjs';
|
|
12
13
|
import { createSkillsPickers } from './extension-pickers/skills-pickers.mjs';
|
|
@@ -43,5 +44,5 @@ export function createExtensionPickers({
|
|
|
43
44
|
setSettingsPrompt,
|
|
44
45
|
openMcpPicker: mcp.openMcpPicker,
|
|
45
46
|
});
|
|
46
|
-
return { ...mcp, ...skills, ...plugins };
|
|
47
|
+
return { ...mcp, ...createMcpLogin({ store, setProviderPrompt }), ...skills, ...plugins };
|
|
47
48
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* displayModelName formatter.
|
|
7
7
|
*/
|
|
8
8
|
import { theme } from '../theme.mjs';
|
|
9
|
-
import { displayModelName } from '../../runtime/shared/model-display.mjs';
|
|
9
|
+
import { displayModelName, effortDisplayLabel } from '../../runtime/shared/model-display.mjs';
|
|
10
10
|
import { isRollingModelAlias } from '../../runtime/shared/model-alias.mjs';
|
|
11
11
|
import { DAYBREAK_PROVIDER, daybreakBlueOn } from '../../runtime/shared/llm/openai-daybreak.mjs';
|
|
12
12
|
|
|
@@ -169,6 +169,7 @@ const PROVIDER_DISPLAY_NAMES = new Map([
|
|
|
169
169
|
['anthropic-oauth', 'Anthropic OAuth'],
|
|
170
170
|
['grok-oauth', 'Grok OAuth'],
|
|
171
171
|
['muse-code-oauth', 'Muse Code'],
|
|
172
|
+
['command-code-oauth', 'Command Code'],
|
|
172
173
|
['mimo-oauth', 'MiMo'],
|
|
173
174
|
['cursor-oauth', 'Cursor OAuth'],
|
|
174
175
|
['antigravity-oauth', 'Antigravity OAuth'],
|
|
@@ -225,6 +226,7 @@ const PROVIDER_DISPLAY_RANKS = {
|
|
|
225
226
|
'anthropic-oauth': 20,
|
|
226
227
|
'grok-oauth': 30,
|
|
227
228
|
'muse-code-oauth': 33,
|
|
229
|
+
'command-code-oauth': 33.5,
|
|
228
230
|
'mimo-oauth': 34,
|
|
229
231
|
'antigravity-oauth': 31,
|
|
230
232
|
'cursor-oauth': 32,
|
|
@@ -246,18 +248,7 @@ const PROVIDER_DISPLAY_RANKS = {
|
|
|
246
248
|
|
|
247
249
|
export const providerDisplayRank = (provider) => PROVIDER_DISPLAY_RANKS[String(provider || '').toLowerCase()] ?? 900;
|
|
248
250
|
|
|
249
|
-
|
|
250
|
-
String(value || '')
|
|
251
|
-
.split(/([\s_-]+)/)
|
|
252
|
-
.map((part) => (/^[\s_-]+$/.test(part) ? part : `${part.charAt(0).toUpperCase()}${part.slice(1).toLowerCase()}`))
|
|
253
|
-
.join('');
|
|
254
|
-
|
|
255
|
-
export const effortDisplayLabel = (value) => {
|
|
256
|
-
const text = String(value || '').trim();
|
|
257
|
-
if (!text) return '';
|
|
258
|
-
if (text.toLowerCase() === 'xhigh') return 'XHigh';
|
|
259
|
-
return titleCaseOption(text);
|
|
260
|
-
};
|
|
251
|
+
export { effortDisplayLabel };
|
|
261
252
|
|
|
262
253
|
export const fastDisplayLabel = (enabled = true) => `Fast ${enabled ? 'On' : 'Off'}`;
|
|
263
254
|
|
|
@@ -328,9 +319,15 @@ export const buildProviderModelItems = (models, provider, currentRoute = null) =
|
|
|
328
319
|
}));
|
|
329
320
|
};
|
|
330
321
|
|
|
331
|
-
//
|
|
322
|
+
// The configured speed tier: Ultrafast when the fast route asks for it.
|
|
323
|
+
const routeSpeedLabel = (route) => {
|
|
324
|
+
if (!route?.fast) return '';
|
|
325
|
+
return route.modelParameters?.serviceTier === 'ultrafast' ? 'Ultrafast' : 'Fast';
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Model · Effort · Fast/Ultrafast, dropping the empty parts.
|
|
332
329
|
const routeModelDetails = (route) =>
|
|
333
|
-
[routeModelDisplayName(route), route.effort ? effortDisplayLabel(route.effort) : '', route
|
|
330
|
+
[routeModelDisplayName(route), route.effort ? effortDisplayLabel(route.effort) : '', routeSpeedLabel(route)]
|
|
334
331
|
.filter(Boolean)
|
|
335
332
|
.join(' · ');
|
|
336
333
|
|
|
@@ -346,7 +343,7 @@ export const agentModelProfile = (route) => (route?.model ? routeModelDetails(ro
|
|
|
346
343
|
export const agentModelParts = (route) => [
|
|
347
344
|
{ text: route?.model ? routeModelDisplayName(route) : '', width: 17 },
|
|
348
345
|
{ text: route?.effort ? effortDisplayLabel(route.effort) : '', width: 6 },
|
|
349
|
-
{ text: route
|
|
346
|
+
{ text: routeSpeedLabel(route), width: 9 },
|
|
350
347
|
];
|
|
351
348
|
|
|
352
349
|
export const routeFromModel = (model, effort = null) => ({
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* app/skill-mention-palette.mjs — `$name` skill completion in the prompt.
|
|
3
|
+
*
|
|
4
|
+
* Typing `$` at the start of the draft or after whitespace/an opening
|
|
5
|
+
* bracket or quote (the shared runtime mention rule, runtime/shared/
|
|
6
|
+
* skill-mentions.mjs) opens the command palette with the user's enabled
|
|
7
|
+
* custom skills; accepting inserts `$name `. Built-in skills are not listed,
|
|
8
|
+
* but still load when their name is typed: the runtime resolves mentions.
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useState } from 'react';
|
|
11
|
+
import { isInMarkdownCode, isReservedMentionName } from '../../runtime/shared/skill-mentions.mjs';
|
|
12
|
+
|
|
13
|
+
// A mention being typed just before the caret: `$` plus a partial name.
|
|
14
|
+
const MENTION_TAIL = /(^|[\s([{"'`])\$([a-z0-9][a-z0-9-]{0,63})?$/;
|
|
15
|
+
|
|
16
|
+
const caretIn = (text, caret) => (Number.isInteger(caret) ? Math.max(0, Math.min(text.length, caret)) : text.length);
|
|
17
|
+
|
|
18
|
+
/** The mention being typed before `caret` (default: end of `value`), or null.
|
|
19
|
+
* `start` is the `$`, `end` the caret. */
|
|
20
|
+
export function skillMentionQuery(value, caret) {
|
|
21
|
+
const text = String(value ?? '');
|
|
22
|
+
const end = caretIn(text, caret);
|
|
23
|
+
const match = MENTION_TAIL.exec(text.slice(0, end));
|
|
24
|
+
if (!match) return null;
|
|
25
|
+
const start = match.index + match[1].length;
|
|
26
|
+
// `$` inside inline code or a fenced block is never a mention (the shared
|
|
27
|
+
// parser's rule, judged on the whole draft like the desktop composer).
|
|
28
|
+
if (isInMarkdownCode(text, start)) return null;
|
|
29
|
+
return { query: match[2] || '', start, end };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const byName = (a, b) => a.name.localeCompare(b.name, 'en');
|
|
33
|
+
|
|
34
|
+
/** Palette rows for `query`: enabled, in-project (not `activeHere:false`)
|
|
35
|
+
* non-built-in skills whose name starts with the query, then those that
|
|
36
|
+
* merely contain it, each alphabetical. */
|
|
37
|
+
export function skillMentionItems(skills, query) {
|
|
38
|
+
const needle = String(query || '').toLowerCase();
|
|
39
|
+
const usable = (Array.isArray(skills) ? skills : []).filter(
|
|
40
|
+
(skill) =>
|
|
41
|
+
typeof skill?.name === 'string' &&
|
|
42
|
+
skill.name &&
|
|
43
|
+
skill.enabled !== false &&
|
|
44
|
+
skill.activeHere !== false &&
|
|
45
|
+
skill.source !== 'builtin' &&
|
|
46
|
+
// `$path`/`$300` are never mentions, so offering them would insert prose.
|
|
47
|
+
!isReservedMentionName(skill.name)
|
|
48
|
+
);
|
|
49
|
+
const prefix = usable.filter((skill) => skill.name.startsWith(needle)).sort(byName);
|
|
50
|
+
const contains = needle
|
|
51
|
+
? usable.filter((skill) => !skill.name.startsWith(needle) && skill.name.includes(needle)).sort(byName)
|
|
52
|
+
: [];
|
|
53
|
+
return [...prefix, ...contains].map((skill) => ({
|
|
54
|
+
kind: 'skill',
|
|
55
|
+
name: skill.name,
|
|
56
|
+
label: `$${skill.name}`,
|
|
57
|
+
description: skill.description || '',
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The draft with the `$fragment` before `caret` replaced by `$name `; the
|
|
62
|
+
* text after the caret is kept and the caret lands after the insertion. */
|
|
63
|
+
export function completeSkillMention(value, name, caret) {
|
|
64
|
+
const text = String(value ?? '');
|
|
65
|
+
const mention = skillMentionQuery(text, caret);
|
|
66
|
+
if (!mention || !name) return undefined;
|
|
67
|
+
const head = `${text.slice(0, mention.start)}$${name} `;
|
|
68
|
+
return { value: head + text.slice(mention.end), cursor: head.length };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The skill list for the palette, fetched each time a mention starts. */
|
|
72
|
+
export function useSkillMentionSkills(store, active) {
|
|
73
|
+
const [skills, setSkills] = useState([]);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
if (!active) return undefined;
|
|
76
|
+
let live = true;
|
|
77
|
+
Promise.resolve()
|
|
78
|
+
.then(() => store.skillsStatus?.())
|
|
79
|
+
.then((status) => {
|
|
80
|
+
if (live) setSkills(Array.isArray(status?.skills) ? status.skills : []);
|
|
81
|
+
})
|
|
82
|
+
.catch(() => {});
|
|
83
|
+
return () => {
|
|
84
|
+
live = false;
|
|
85
|
+
};
|
|
86
|
+
}, [store, active]);
|
|
87
|
+
return skills;
|
|
88
|
+
}
|
|
@@ -50,8 +50,13 @@ export const SLASH_COMMANDS = [
|
|
|
50
50
|
{ name: 'theme', usage: '/theme', params: '[id]', description: 'Change the TUI color theme' },
|
|
51
51
|
{ name: 'agents', usage: '/agents', params: '[refresh]', description: 'Show available workflow agents' },
|
|
52
52
|
{ name: 'effort', usage: '/effort', params: '[level]', description: 'Set reasoning effort for the current model' },
|
|
53
|
-
{
|
|
54
|
-
|
|
53
|
+
{
|
|
54
|
+
name: 'fast',
|
|
55
|
+
usage: '/fast',
|
|
56
|
+
params: '[on|off|ultra]',
|
|
57
|
+
description: 'Set Fast or Ultrafast mode for the current model',
|
|
58
|
+
},
|
|
59
|
+
{ name: 'mcp', usage: '/mcp', params: '[login|logout <name>]', description: 'Manage MCP servers and tools' },
|
|
55
60
|
{ name: 'skills', usage: '/skills', description: 'Choose a skill for the next request' },
|
|
56
61
|
{ name: 'memory', usage: '/memory', params: '[status|core ...]', description: 'List and edit core memories' },
|
|
57
62
|
{ name: 'plugins', usage: '/plugins', description: 'Manage local plugin integrations' },
|
|
@@ -14,6 +14,8 @@ const desktopOnlyNotice = (ctx) => {
|
|
|
14
14
|
return true;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
const openMcpPanel = panelCommand('mcp', 'MCP Servers', (deps) => deps.openMcpPicker());
|
|
18
|
+
|
|
17
19
|
const openSettings = panelCommand('settings', 'Settings', (deps) => deps.openSettingsPicker());
|
|
18
20
|
|
|
19
21
|
export const panelCommands = {
|
|
@@ -26,7 +28,20 @@ export const panelCommands = {
|
|
|
26
28
|
ctx.openSlashPanel('project', 'Projects', () => ctx.deps.openProjectPicker());
|
|
27
29
|
return true;
|
|
28
30
|
},
|
|
29
|
-
mcp
|
|
31
|
+
mcp(ctx, arg) {
|
|
32
|
+
const [sub, ...rest] = arg.trim().split(/\s+/);
|
|
33
|
+
const action = sub?.toLowerCase();
|
|
34
|
+
if (action === 'login' || action === 'logout') {
|
|
35
|
+
const name = rest.join(' ');
|
|
36
|
+
if (!name) {
|
|
37
|
+
ctx.store.pushNotice(`usage: /mcp ${action} <name>`, 'warn');
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
void (action === 'login' ? ctx.deps.loginMcpServer(name) : ctx.deps.logoutMcpServer(name));
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
return openMcpPanel(ctx);
|
|
44
|
+
},
|
|
30
45
|
skills: panelCommand('skills', 'Skills', (deps) => deps.openSkillsPicker()),
|
|
31
46
|
plugins: panelCommand('plugins', 'Plugins', (deps) => deps.openPluginsPicker()),
|
|
32
47
|
providers: panelCommand('providers', 'Providers', (deps) => deps.openProviderSetupPicker()),
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* app/slash-palette.mjs — which slash palette (if any) the prompt draft opens.
|
|
3
3
|
*/
|
|
4
4
|
import { SLASH_COMMANDS, slashQuery, slashCommandMatches, compareSlashCommands } from './slash-commands.mjs';
|
|
5
|
+
import { skillMentionItems, skillMentionQuery } from './skill-mention-palette.mjs';
|
|
5
6
|
|
|
6
7
|
export function deriveSlashPalette({
|
|
7
8
|
providerPrompt,
|
|
@@ -14,18 +15,33 @@ export function deriveSlashPalette({
|
|
|
14
15
|
commandBusy,
|
|
15
16
|
promptDraft,
|
|
16
17
|
slashDismissedFor,
|
|
18
|
+
skills = [],
|
|
19
|
+
promptCaret = null,
|
|
17
20
|
}) {
|
|
18
21
|
const activeSlashQuery =
|
|
19
22
|
providerPrompt || settingsPrompt || toolApproval || contextPanel || usagePanel ? null : slashQuery(promptDraft);
|
|
23
|
+
const surfaceFree = !picker && !toolApproval && !contextPanel && !usagePanel && !exiting && !commandBusy;
|
|
20
24
|
// "Slash mode" is live whenever a /token is being edited and no other
|
|
21
25
|
// surface owns the floating area. The palette stays OPEN for the whole
|
|
22
26
|
// slash session — including 0-match frames — so its 14-row layout never
|
|
23
27
|
// unmounts/remounts per keystroke (fullscreen repaint flicker fix).
|
|
24
|
-
const slashModeLive =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const slashModeLive = activeSlashQuery !== null && surfaceFree;
|
|
29
|
+
if (!slashModeLive) {
|
|
30
|
+
// `$name` completion shares the palette, but opens only while a skill
|
|
31
|
+
// matches: `$HOME` or `$300` in prose must not raise a panel.
|
|
32
|
+
const mention =
|
|
33
|
+
surfaceFree && !providerPrompt && !settingsPrompt ? skillMentionQuery(promptDraft, promptCaret) : null;
|
|
34
|
+
const slashCommands = mention ? skillMentionItems(skills, mention.query) : [];
|
|
35
|
+
return {
|
|
36
|
+
activeSlashQuery: mention ? mention.query : null,
|
|
37
|
+
slashCommands,
|
|
38
|
+
slashPaletteOpen: slashCommands.length > 0 && slashDismissedFor !== promptDraft,
|
|
39
|
+
paletteKind: mention ? 'skills' : 'commands',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const slashCommands = SLASH_COMMANDS.filter((command) => slashCommandMatches(command, activeSlashQuery)).sort(
|
|
43
|
+
compareSlashCommands
|
|
44
|
+
);
|
|
45
|
+
const slashPaletteOpen = slashDismissedFor !== promptDraft;
|
|
46
|
+
return { activeSlashQuery, slashCommands, slashPaletteOpen, paletteKind: 'commands' };
|
|
31
47
|
}
|