@gajae-code/coding-agent 0.13.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +215 -8
- package/README.md +2 -0
- package/bin/gajaessi.js +4 -0
- package/dist/types/async/job-manager.d.ts +55 -2
- package/dist/types/async/support.d.ts +14 -0
- package/dist/types/capability/mcp.d.ts +6 -0
- package/dist/types/capability/types.d.ts +6 -0
- package/dist/types/cli/accounts-cli.d.ts +19 -0
- package/dist/types/cli/args.d.ts +3 -0
- package/dist/types/cli/config-cli.d.ts +6 -0
- package/dist/types/cli/crash-cli.d.ts +10 -0
- package/dist/types/cli/customize-doctor.d.ts +145 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/mcp-cli.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/root-flags.d.ts +12 -0
- package/dist/types/cli/setup-cli.d.ts +3 -1
- package/dist/types/cli/skills-cli.d.ts +2 -1
- package/dist/types/cli/update-cli.d.ts +19 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/accounts.d.ts +40 -0
- package/dist/types/commands/crash.d.ts +24 -0
- package/dist/types/commands/customize.d.ts +22 -0
- package/dist/types/commands/daemon.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/commands/setup.d.ts +6 -0
- package/dist/types/commands/skills.d.ts +6 -1
- package/dist/types/commands/update.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
- package/dist/types/config/config-schema-version.d.ts +10 -0
- package/dist/types/config/file-lock.d.ts +18 -0
- package/dist/types/config/model-profile-activation.d.ts +3 -1
- package/dist/types/config/model-registry.d.ts +10 -1
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +73 -9
- package/dist/types/config/settings.d.ts +63 -0
- package/dist/types/config/skill-settings-defaults.d.ts +26 -0
- package/dist/types/config/task-delegation.d.ts +39 -0
- package/dist/types/config/update-channel.d.ts +10 -0
- package/dist/types/coordinator-mcp/server.d.ts +5 -1
- package/dist/types/crash/index-store.d.ts +87 -0
- package/dist/types/crash/nudge.d.ts +50 -0
- package/dist/types/crash/record-loader.d.ts +17 -0
- package/dist/types/crash/report.d.ts +134 -0
- package/dist/types/crash/sanitize.d.ts +25 -0
- package/dist/types/cursor.d.ts +13 -2
- package/dist/types/customization/import.d.ts +37 -0
- package/dist/types/customization/index.d.ts +4 -0
- package/dist/types/customization/inventory.d.ts +25 -0
- package/dist/types/customization/mutations.d.ts +32 -0
- package/dist/types/customization/types.d.ts +115 -0
- package/dist/types/daemon/control-types.d.ts +8 -1
- package/dist/types/daemon/operator-contract.d.ts +4 -4
- package/dist/types/discovery/claude.d.ts +39 -1
- package/dist/types/discovery/codex.d.ts +39 -1
- package/dist/types/discovery/index.d.ts +2 -0
- package/dist/types/discovery/mcp-compat.d.ts +30 -0
- package/dist/types/edit/renderer.d.ts +23 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -4
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
- package/dist/types/extensibility/hooks/loader.d.ts +19 -5
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
- package/dist/types/extensibility/skill-management.d.ts +107 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
- package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
- package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
- package/dist/types/hooks/events.d.ts +60 -0
- package/dist/types/hooks/normalize.d.ts +83 -0
- package/dist/types/hooks/skill-state.d.ts +9 -2
- package/dist/types/main.d.ts +2 -1
- package/dist/types/modes/acp/abort-scope.d.ts +13 -0
- package/dist/types/modes/acp/acp-agent.d.ts +7 -4
- package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
- package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
- package/dist/types/modes/components/customization/index.d.ts +1 -0
- package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
- package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
- package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
- package/dist/types/modes/components/oauth-selector.d.ts +10 -4
- package/dist/types/modes/components/pet-capability.d.ts +7 -21
- package/dist/types/modes/components/settings-selector.d.ts +5 -0
- package/dist/types/modes/components/status-line/gh.d.ts +6 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
- package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/theme/defaults/index.d.ts +118 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
- package/dist/types/runtime-mcp/config.d.ts +9 -0
- package/dist/types/runtime-mcp/manager.d.ts +26 -1
- package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
- package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
- package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
- package/dist/types/runtime-mcp/protocol.d.ts +278 -0
- package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
- package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
- package/dist/types/runtime-mcp/types.d.ts +102 -10
- package/dist/types/sdk/acp/adapter.d.ts +26 -5
- package/dist/types/sdk/broker/broker.d.ts +3 -55
- package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
- package/dist/types/sdk/broker/session-index.d.ts +14 -5
- package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
- package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
- package/dist/types/sdk/bus/index.d.ts +85 -99
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
- package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
- package/dist/types/sdk/bus/notification-service.d.ts +52 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
- package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
- package/dist/types/sdk/bus/session-control.d.ts +25 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
- package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
- package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
- package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
- package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
- package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
- package/dist/types/sdk/cli/rows.d.ts +2 -11
- package/dist/types/sdk/cli/session-cli.d.ts +15 -25
- package/dist/types/sdk/client/client.d.ts +97 -1
- package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +18 -5
- package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
- package/dist/types/sdk/host/host.d.ts +15 -1
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +127 -7
- package/dist/types/sdk/host/types.d.ts +1 -1
- package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
- package/dist/types/sdk/lifecycle/client.d.ts +59 -0
- package/dist/types/sdk/lifecycle/index.d.ts +3 -0
- package/dist/types/sdk/lifecycle/service.d.ts +232 -0
- package/dist/types/sdk/mcp/server.d.ts +9 -6
- package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
- package/dist/types/sdk/prompt-status.d.ts +10 -3
- package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
- package/dist/types/sdk/receipt-state.d.ts +17 -0
- package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
- package/dist/types/sdk/router/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +152 -0
- package/dist/types/sdk/session-list.d.ts +22 -0
- package/dist/types/sdk/session-reconnect.d.ts +43 -1
- package/dist/types/sdk/session.d.ts +34 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
- package/dist/types/session/account-inventory.d.ts +86 -0
- package/dist/types/session/agent-session.d.ts +145 -6
- package/dist/types/session/agent-storage.d.ts +10 -0
- package/dist/types/session/coordinator-tool-label.d.ts +28 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/secure-token-file.d.ts +3 -0
- package/dist/types/session/session-manager.d.ts +47 -1
- package/dist/types/session/startup-auth-config.d.ts +44 -0
- package/dist/types/session/terminal-abort.d.ts +378 -0
- package/dist/types/session/yield-queue.d.ts +7 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +88 -0
- package/dist/types/session-import/command.d.ts +35 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/provider-codex.d.ts +22 -0
- package/dist/types/session-import/provider-service.d.ts +38 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +47 -0
- package/dist/types/session-import/types.d.ts +120 -0
- package/dist/types/setup/paseo/check.d.ts +16 -0
- package/dist/types/setup/paseo/install-saga.d.ts +115 -0
- package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
- package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
- package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
- package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
- package/dist/types/setup/paseo/provider-config.d.ts +35 -0
- package/dist/types/setup/paseo/remove.d.ts +14 -0
- package/dist/types/setup/paseo/result-types.d.ts +59 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
- package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
- package/dist/types/skill-state/active-state.d.ts +5 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
- package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
- package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
- package/dist/types/slash-commands/types.d.ts +7 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/tools/ask-answer-registry.d.ts +6 -3
- package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
- package/dist/types/tools/bash.d.ts +2 -6
- package/dist/types/tools/browser/attach.d.ts +11 -0
- package/dist/types/tools/browser/launch.d.ts +20 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
- package/dist/types/tools/browser/render.d.ts +1 -0
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/image-gen.d.ts +10 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/monitor.d.ts +1 -1
- package/dist/types/tools/skill-discovery.d.ts +8 -1
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
- package/dist/types/utils/herdr-pane.d.ts +76 -0
- package/package.json +19 -9
- package/scripts/build-binary.ts +2 -1
- package/scripts/build-sdk-package-smoke.ts +2 -13
- package/scripts/capture-sticky-viewport-showcase.ts +0 -1
- package/scripts/compile-args.ts +2 -0
- package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
- package/scripts/generate-sdk-operation-inventory.ts +28 -0
- package/scripts/generate-telegram-baseline-manifest.ts +1 -0
- package/scripts/generate-tool-catalog.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
- package/src/async/job-manager.ts +352 -17
- package/src/async/support.ts +25 -0
- package/src/autoresearch/dashboard.ts +28 -13
- package/src/capability/index.ts +3 -1
- package/src/capability/mcp.ts +6 -0
- package/src/capability/types.ts +6 -0
- package/src/cli/accounts-cli.ts +395 -0
- package/src/cli/args.ts +23 -0
- package/src/cli/auth-broker-cli.ts +136 -66
- package/src/cli/auth-gateway-cli.ts +94 -70
- package/src/cli/config-cli.ts +27 -2
- package/src/cli/crash-cli.ts +78 -0
- package/src/cli/customize-doctor.ts +1605 -0
- package/src/cli/daemon-cli.ts +12 -3
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/mcp-cli.ts +128 -60
- package/src/cli/notify-cli.ts +8 -14
- package/src/cli/root-flags.ts +8 -0
- package/src/cli/setup-cli.ts +145 -0
- package/src/cli/skills-cli.ts +38 -2
- package/src/cli/update-cli.ts +167 -12
- package/src/cli.ts +4 -0
- package/src/commands/accounts.ts +71 -0
- package/src/commands/crash.ts +35 -0
- package/src/commands/customize.ts +84 -0
- package/src/commands/daemon.ts +2 -2
- package/src/commands/deep-interview.ts +2 -0
- package/src/commands/launch.ts +1 -0
- package/src/commands/mcp.ts +12 -7
- package/src/commands/ralplan.ts +2 -0
- package/src/commands/sdk.ts +65 -32
- package/src/commands/setup.ts +5 -0
- package/src/commands/skills.ts +14 -4
- package/src/commands/ultragoal.ts +10 -1
- package/src/commands/update.ts +26 -15
- package/src/config/atomic-yaml-patch-worker.ts +57 -0
- package/src/config/atomic-yaml-patch.ts +769 -29
- package/src/config/config-schema-version.ts +10 -0
- package/src/config/file-lock.ts +70 -1
- package/src/config/mcp-schema.json +52 -14
- package/src/config/model-profile-activation.ts +23 -2
- package/src/config/model-profiles.ts +88 -21
- package/src/config/model-registry.ts +147 -21
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +77 -7
- package/src/config/settings.ts +4038 -199
- package/src/config/skill-settings-defaults.ts +41 -3
- package/src/config/task-delegation.ts +87 -0
- package/src/config/update-channel.ts +23 -0
- package/src/coordinator-mcp/server.ts +377 -308
- package/src/crash/index-store.ts +723 -0
- package/src/crash/nudge.ts +89 -0
- package/src/crash/record-loader.ts +149 -0
- package/src/crash/report.ts +551 -0
- package/src/crash/sanitize.ts +129 -0
- package/src/cursor.ts +36 -10
- package/src/customization/import.ts +946 -0
- package/src/customization/index.ts +4 -0
- package/src/customization/inventory.ts +335 -0
- package/src/customization/mutations.ts +141 -0
- package/src/customization/types.ts +223 -0
- package/src/daemon/control-types.ts +8 -1
- package/src/daemon/operator-contract.ts +6 -6
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
- package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
- package/src/discovery/claude-hooks.ts +38 -0
- package/src/discovery/claude.ts +142 -209
- package/src/discovery/codex-hooks.ts +38 -0
- package/src/discovery/codex.ts +132 -198
- package/src/discovery/helpers.ts +8 -1
- package/src/discovery/index.ts +2 -0
- package/src/discovery/mcp-compat.ts +234 -0
- package/src/discovery/mcp-json.ts +6 -0
- package/src/edit/renderer.ts +40 -0
- package/src/edit/streaming.ts +4 -2
- package/src/exec/bash-executor.ts +24 -20
- package/src/export/html/index.ts +51 -2
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +17 -4
- package/src/extensibility/extensions/types.ts +31 -6
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
- package/src/extensibility/gjc-plugins/installer.ts +9 -5
- package/src/extensibility/gjc-plugins/observability.ts +8 -2
- package/src/extensibility/gjc-plugins/registry.ts +13 -2
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
- package/src/extensibility/gjc-plugins/schema.ts +222 -39
- package/src/extensibility/hooks/loader.ts +154 -10
- package/src/extensibility/runtime-skill-discovery.ts +257 -60
- package/src/extensibility/skill-management.ts +368 -0
- package/src/extensibility/skills.ts +52 -16
- package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
- package/src/gjc-runtime/launch-worktree.ts +56 -2
- package/src/gjc-runtime/linux-proc.ts +7 -1
- package/src/gjc-runtime/ralplan-runtime.ts +100 -164
- package/src/gjc-runtime/session-state-lock.ts +992 -0
- package/src/gjc-runtime/session-state-sidecar.ts +644 -142
- package/src/gjc-runtime/state-writer.ts +39 -14
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
- package/src/gjc-runtime/ultragoal-guard.ts +11 -4
- package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
- package/src/gjc-runtime/workflow-settings.ts +596 -0
- package/src/goals/tools/goal-tool.ts +6 -1
- package/src/hooks/events.ts +291 -0
- package/src/hooks/native-skill-hook.ts +4 -0
- package/src/hooks/normalize.ts +369 -0
- package/src/hooks/skill-state.ts +165 -46
- package/src/internal-urls/docs-index.generated.ts +41 -32
- package/src/main.ts +36 -5
- package/src/migrate/mcp-mapper.ts +25 -2
- package/src/modes/acp/abort-scope.ts +29 -0
- package/src/modes/acp/acp-agent.ts +423 -98
- package/src/modes/components/assistant-message.ts +6 -1
- package/src/modes/components/chrome.ts +4 -3
- package/src/modes/components/customization/customization-dashboard.ts +443 -0
- package/src/modes/components/customization/import-wizard.ts +372 -0
- package/src/modes/components/customization/index.ts +1 -0
- package/src/modes/components/dynamic-theme-text.ts +22 -0
- package/src/modes/components/gajae-pet-widget.ts +607 -193
- package/src/modes/components/irc-sidebar.ts +11 -0
- package/src/modes/components/iterm-pet-transport.ts +585 -0
- package/src/modes/components/model-selector.ts +1 -6
- package/src/modes/components/oauth-selector.ts +277 -86
- package/src/modes/components/pet-capability.ts +35 -31
- package/src/modes/components/settings-selector.ts +29 -5
- package/src/modes/components/status-line/gh.ts +45 -1
- package/src/modes/components/status-line/segments.ts +19 -4
- package/src/modes/components/tool-status-header.ts +13 -3
- package/src/modes/controllers/command-controller.ts +20 -8
- package/src/modes/controllers/extension-ui-controller.ts +56 -257
- package/src/modes/controllers/input-controller.ts +10 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
- package/src/modes/controllers/selector-controller.ts +238 -77
- package/src/modes/controllers/stt-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +88 -16
- package/src/modes/print-mode.ts +35 -6
- package/src/modes/runtime-init.ts +21 -68
- package/src/modes/theme/defaults/index.ts +2 -0
- package/src/modes/theme/defaults/ouroboros.json +118 -0
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +25 -0
- package/src/modes/utils/terminal-bell.ts +15 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/critic.md +1 -1
- package/src/prompts/system/rlm-research.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -2
- package/src/prompts/tools/bash.md +7 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/cron.md +6 -6
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/skill-discovery.md +4 -2
- package/src/runtime-mcp/client.ts +427 -23
- package/src/runtime-mcp/config.ts +37 -5
- package/src/runtime-mcp/manager-pool.test.ts +56 -0
- package/src/runtime-mcp/manager.ts +52 -2
- package/src/runtime-mcp/oauth-discovery.ts +13 -0
- package/src/runtime-mcp/oauth-flow.ts +46 -1
- package/src/runtime-mcp/pool-key.ts +5 -1
- package/src/runtime-mcp/pool.test.ts +9 -0
- package/src/runtime-mcp/protocol.test.ts +353 -0
- package/src/runtime-mcp/protocol.ts +624 -0
- package/src/runtime-mcp/scope-config.ts +78 -0
- package/src/runtime-mcp/tool-bridge.ts +44 -10
- package/src/runtime-mcp/transports/http.ts +84 -13
- package/src/runtime-mcp/types.ts +123 -12
- package/src/sdk/acp/adapter.ts +328 -97
- package/src/sdk/broker/broker.ts +160 -741
- package/src/sdk/broker/ensure.ts +9 -1
- package/src/sdk/broker/lifecycle.ts +510 -116
- package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
- package/src/sdk/broker/process-incarnation.ts +19 -0
- package/src/sdk/broker/session-index.ts +516 -117
- package/src/sdk/broker/startup-failure.ts +28 -5
- package/src/sdk/broker/transport.ts +1 -13
- package/src/sdk/bus/chat-daemon-cli.ts +4 -2
- package/src/sdk/bus/chat-daemon-control.ts +67 -6
- package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
- package/src/sdk/bus/config.ts +13 -0
- package/src/sdk/bus/conversation-store.ts +59 -171
- package/src/sdk/bus/daemon-paths.ts +20 -0
- package/src/sdk/bus/discord-conversation.ts +2 -0
- package/src/sdk/bus/discord-daemon.ts +524 -126
- package/src/sdk/bus/discord-live-provider.ts +206 -79
- package/src/sdk/bus/existing-thread-readiness.ts +4 -97
- package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
- package/src/sdk/bus/index.ts +2480 -456
- package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
- package/src/sdk/bus/lifecycle-commands.ts +2 -2
- package/src/sdk/bus/managed-daemon.ts +2 -145
- package/src/sdk/bus/notification-service.ts +196 -0
- package/src/sdk/bus/operator-runtime.ts +1 -1
- package/src/sdk/bus/prompt-reconciliation.ts +24 -15
- package/src/sdk/bus/reconciliation-store.ts +553 -24
- package/src/sdk/bus/session-control.ts +49 -3
- package/src/sdk/bus/slack-conversation.ts +4 -0
- package/src/sdk/bus/slack-daemon.ts +733 -134
- package/src/sdk/bus/slack-live-provider.ts +65 -15
- package/src/sdk/bus/slack-provider.ts +4 -0
- package/src/sdk/bus/slack-thread-binding.ts +9 -104
- package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
- package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
- package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
- package/src/sdk/bus/telegram-daemon-control.ts +3 -13
- package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
- package/src/sdk/bus/telegram-daemon.ts +2552 -2280
- package/src/sdk/bus/telegram-reference.ts +1 -226
- package/src/sdk/bus/telegram-setup.ts +2 -2
- package/src/sdk/bus/threaded-render.ts +1 -0
- package/src/sdk/bus/topic-registry.ts +279 -146
- package/src/sdk/cli/rows.ts +2 -35
- package/src/sdk/cli/session-cli.ts +776 -700
- package/src/sdk/client/client.ts +892 -1
- package/src/sdk/host/control/dispatch.ts +93 -58
- package/src/sdk/host/control/index.ts +1 -1
- package/src/sdk/host/control/operations.ts +18 -10
- package/src/sdk/host/control/runtime-gate.ts +40 -0
- package/src/sdk/host/host.ts +63 -12
- package/src/sdk/host/query/handlers.ts +66 -7
- package/src/sdk/host/reverse-leases.ts +2 -2
- package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +2787 -34
- package/src/sdk/host/session-runtime.ts +1489 -101
- package/src/sdk/host/surface-policy.ts +12 -8
- package/src/sdk/host/types.ts +1 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
- package/src/sdk/host/websocket-transport.ts +85 -50
- package/src/sdk/index.ts +2 -1
- package/src/sdk/lifecycle/broker-client.ts +53 -0
- package/src/sdk/lifecycle/client.ts +234 -0
- package/src/sdk/lifecycle/index.ts +3 -0
- package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
- package/src/sdk/lifecycle/service.ts +720 -0
- package/src/sdk/mcp/server.ts +226 -188
- package/src/sdk/prompt-deadline-lease.ts +55 -0
- package/src/sdk/prompt-deadline-manager.ts +148 -0
- package/src/sdk/prompt-status.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +272 -129
- package/src/sdk/protocol/operation-registry.ts +71 -8
- package/src/sdk/receipt-state.ts +43 -0
- package/src/sdk/reconciliation-extensions.ts +14 -0
- package/src/sdk/router/index.ts +1 -0
- package/src/sdk/router/session-router.ts +1658 -0
- package/src/sdk/session-list.ts +93 -0
- package/src/sdk/session-reconnect.ts +45 -1
- package/src/sdk/session.ts +716 -120
- package/src/sdk/transport/serve-cli.ts +18 -34
- package/src/session/account-inventory.ts +603 -0
- package/src/session/agent-session.ts +2873 -559
- package/src/session/agent-storage.ts +35 -0
- package/src/session/blob-store.ts +32 -1
- package/src/session/coordinator-tool-label.ts +40 -0
- package/src/session/internal/managed-session-scope.ts +4 -0
- package/src/session/internal/managed-session-storage.ts +199 -31
- package/src/session/messages.ts +1 -1
- package/src/session/secure-token-file.ts +80 -0
- package/src/session/session-manager.ts +757 -57
- package/src/session/session-storage.ts +25 -16
- package/src/session/startup-auth-config.ts +297 -0
- package/src/session/terminal-abort.ts +1253 -0
- package/src/session/yield-queue.ts +57 -15
- package/src/session-import/claude.ts +334 -0
- package/src/session-import/codex.ts +1033 -0
- package/src/session-import/command.ts +77 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +7 -0
- package/src/session-import/provider-codex.ts +327 -0
- package/src/session-import/provider-service.ts +457 -0
- package/src/session-import/redact.ts +128 -0
- package/src/session-import/service.ts +1264 -0
- package/src/session-import/types.ts +148 -0
- package/src/setup/paseo/check.ts +213 -0
- package/src/setup/paseo/install-saga.ts +293 -0
- package/src/setup/paseo/json-publisher.ts +263 -0
- package/src/setup/paseo/orchestration-preferences.ts +86 -0
- package/src/setup/paseo/paseo-ownership.ts +224 -0
- package/src/setup/paseo/paseo-setup.ts +253 -0
- package/src/setup/paseo/provider-config.ts +139 -0
- package/src/setup/paseo/remove.ts +183 -0
- package/src/setup/paseo/result-types.ts +79 -0
- package/src/setup/paseo/setup-deps.ts +175 -0
- package/src/setup/paseo/skills-bridge.ts +260 -0
- package/src/skill-state/active-state.ts +21 -11
- package/src/slash-commands/acp-builtins.ts +9 -1
- package/src/slash-commands/builtin-registry.ts +117 -19
- package/src/slash-commands/helpers/credential-switch.ts +143 -0
- package/src/slash-commands/helpers/mcp.ts +9 -3
- package/src/slash-commands/helpers/usage-report.ts +61 -56
- package/src/slash-commands/types.ts +7 -2
- package/src/task/executor.ts +30 -11
- package/src/task/index.ts +66 -7
- package/src/task/render.ts +23 -9
- package/src/tools/ask-answer-registry.ts +23 -7
- package/src/tools/ask.ts +8 -4
- package/src/tools/bash-sleep-advisory.ts +115 -0
- package/src/tools/bash.ts +98 -18
- package/src/tools/browser/attach.ts +71 -3
- package/src/tools/browser/launch.ts +86 -13
- package/src/tools/browser/profile-discovery.ts +57 -7
- package/src/tools/browser/render.ts +8 -1
- package/src/tools/browser.ts +130 -21
- package/src/tools/computer.enforcement.test.ts +1 -1
- package/src/tools/computer.ts +3 -2
- package/src/tools/cron.ts +12 -1
- package/src/tools/image-gen.ts +349 -142
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +33 -6
- package/src/tools/monitor.ts +41 -2
- package/src/tools/skill-discovery.ts +21 -29
- package/src/tools/subagent.ts +142 -24
- package/src/tools/todo-contract.ts +55 -3
- package/src/tools/todo-write.ts +4 -3
- package/src/tools/tool-catalog.generated.ts +6 -6
- package/src/tools/ultragoal-ask-guard.ts +10 -3
- package/src/utils/herdr-pane.ts +345 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/scrapers/index.ts +6 -4
- package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
- package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
- package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
- package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
- package/dist/types/runtime/lazy-service.test.d.ts +0 -1
- package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
- package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
- package/dist/types/runtime-mcp/config.test.d.ts +0 -1
- package/dist/types/runtime-mcp/http.test.d.ts +0 -1
- package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
- package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
- package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
- package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
- package/dist/types/sdk/elevation/audit.d.ts +0 -93
- package/dist/types/sdk/elevation/capability.d.ts +0 -3
- package/dist/types/sdk/elevation/digest.d.ts +0 -72
- package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
- package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
- package/dist/types/sdk/elevation/owner.d.ts +0 -48
- package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
- package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
- package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
- package/dist/types/session/auth-broker-config.d.ts +0 -13
- package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
- package/dist/types/skills/skills.test.d.ts +0 -1
- package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
- package/dist/types/task/token-log.test.d.ts +0 -1
- package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
- package/dist/types/tools/descriptors.test.d.ts +0 -1
- package/scripts/g005-daemon-smoke.ts +0 -180
- package/scripts/g011-daemon-path-smoke.ts +0 -153
- package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
- package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
- package/src/sdk/bus/telegram-cli.ts +0 -212
- package/src/sdk/elevation/allowlist.ts +0 -54
- package/src/sdk/elevation/audit.ts +0 -208
- package/src/sdk/elevation/capability.ts +0 -41
- package/src/sdk/elevation/digest.ts +0 -129
- package/src/sdk/elevation/dispatch-receipt.ts +0 -184
- package/src/sdk/elevation/grant-ledger.ts +0 -1142
- package/src/sdk/elevation/owner.ts +0 -109
- package/src/session/auth-broker-config.ts +0 -109
- /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
- /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
- /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP protocol generation model ("MCP v2", specification 2026-07-28).
|
|
3
|
+
*
|
|
4
|
+
* Canonical authority (verified against the primary sources, not secondary
|
|
5
|
+
* summaries):
|
|
6
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/basic
|
|
7
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http
|
|
8
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning
|
|
9
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr
|
|
10
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/server/discover
|
|
11
|
+
* - https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching
|
|
12
|
+
* - schema source of truth: modelcontextprotocol/specification schema/2026-07-28/schema.ts
|
|
13
|
+
*
|
|
14
|
+
* 2026-07-28 ("modern" era) removes the initialize/initialized handshake,
|
|
15
|
+
* protocol sessions (`Mcp-Session-Id`), the standalone GET SSE stream, and
|
|
16
|
+
* `Last-Event-ID` replay from the core request path. Every request carries its
|
|
17
|
+
* protocol version, client identity, and client capabilities in `_meta`, and
|
|
18
|
+
* Streamable HTTP mirrors selected fields into `MCP-Protocol-Version`,
|
|
19
|
+
* `Mcp-Method`, and `Mcp-Name` headers.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Protocol versions and eras
|
|
24
|
+
// =============================================================================
|
|
25
|
+
|
|
26
|
+
/** The modern (stateless) protocol revision implemented by this client. */
|
|
27
|
+
export const MCP_PROTOCOL_VERSION_2026_07_28 = "2026-07-28";
|
|
28
|
+
|
|
29
|
+
/** Legacy (initialize handshake) revision this client speaks for compatibility. */
|
|
30
|
+
export const MCP_PROTOCOL_VERSION_LEGACY = "2025-03-26";
|
|
31
|
+
|
|
32
|
+
/** Modern-era revisions this client can speak, most preferred first. */
|
|
33
|
+
export const MCP_MODERN_PROTOCOL_VERSIONS: readonly string[] = [MCP_PROTOCOL_VERSION_2026_07_28];
|
|
34
|
+
|
|
35
|
+
/** Protocol generation: modern = per-request metadata (2026-07-28+), legacy = initialize handshake. */
|
|
36
|
+
export type MCPProtocolEra = "modern" | "legacy";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Per-server protocol preference from configuration.
|
|
40
|
+
* - `auto`: attempt modern first; bounded, observable legacy fallback per the
|
|
41
|
+
* specification's era-detection rules. Default when unset.
|
|
42
|
+
* - `2026-07-28`: strict modern-only; never initializes a legacy session.
|
|
43
|
+
* - `legacy`: bounded compatibility mode; always uses the legacy handshake.
|
|
44
|
+
*/
|
|
45
|
+
export type MCPProtocolPreference = "auto" | "2026-07-28" | "legacy";
|
|
46
|
+
|
|
47
|
+
export const MCP_PROTOCOL_PREFERENCES: readonly MCPProtocolPreference[] = ["auto", "2026-07-28", "legacy"];
|
|
48
|
+
|
|
49
|
+
export function isMCPProtocolPreference(value: unknown): value is MCPProtocolPreference {
|
|
50
|
+
return typeof value === "string" && (MCP_PROTOCOL_PREFERENCES as readonly string[]).includes(value);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Resolve the effective preference; `auto` when unset. */
|
|
54
|
+
export function resolveMCPProtocolPreference(value: MCPProtocolPreference | undefined): MCPProtocolPreference {
|
|
55
|
+
return value ?? "auto";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** True when a version string names a modern-era revision (date-based, >= 2026-07-28). */
|
|
59
|
+
export function isModernProtocolVersion(version: string): boolean {
|
|
60
|
+
return version >= MCP_PROTOCOL_VERSION_2026_07_28;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// =============================================================================
|
|
64
|
+
// Protocol-defined JSON-RPC error codes (2026-07-28 reserved range)
|
|
65
|
+
// =============================================================================
|
|
66
|
+
|
|
67
|
+
/** Headers do not match the request body, or required headers are missing/malformed. */
|
|
68
|
+
export const MCP_ERROR_HEADER_MISMATCH = -32020;
|
|
69
|
+
/** The request requires a client capability the client did not declare. */
|
|
70
|
+
export const MCP_ERROR_MISSING_REQUIRED_CLIENT_CAPABILITY = -32021;
|
|
71
|
+
/** The server does not implement the requested protocol version. */
|
|
72
|
+
export const MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION = -32022;
|
|
73
|
+
/** Standard JSON-RPC method-not-found (modern servers pair it with HTTP 404). */
|
|
74
|
+
export const JSONRPC_ERROR_METHOD_NOT_FOUND = -32601;
|
|
75
|
+
/** Standard JSON-RPC invalid-params (modern servers reject missing `_meta` with it). */
|
|
76
|
+
export const JSONRPC_ERROR_INVALID_PARAMS = -32602;
|
|
77
|
+
|
|
78
|
+
// =============================================================================
|
|
79
|
+
// Per-request `_meta` (modern era)
|
|
80
|
+
// =============================================================================
|
|
81
|
+
|
|
82
|
+
export const MCP_META_PROTOCOL_VERSION = "io.modelcontextprotocol/protocolVersion";
|
|
83
|
+
export const MCP_META_CLIENT_INFO = "io.modelcontextprotocol/clientInfo";
|
|
84
|
+
export const MCP_META_CLIENT_CAPABILITIES = "io.modelcontextprotocol/clientCapabilities";
|
|
85
|
+
export const MCP_META_SERVER_INFO = "io.modelcontextprotocol/serverInfo";
|
|
86
|
+
|
|
87
|
+
/** Client identity advertised in modern per-request `_meta`. */
|
|
88
|
+
export interface MCPModernClientContext {
|
|
89
|
+
protocolVersion: string;
|
|
90
|
+
clientInfo: { name: string; version: string };
|
|
91
|
+
/** Capabilities relevant to requests, e.g. `{ roots: {...}, elicitation: {...} }`. */
|
|
92
|
+
capabilities: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Build the `_meta` object every modern request MUST carry. Callers merge this
|
|
97
|
+
* into `params._meta`, preserving any pre-existing keys (e.g. `progressToken`).
|
|
98
|
+
*/
|
|
99
|
+
export function buildModernRequestMeta(context: MCPModernClientContext): Record<string, unknown> {
|
|
100
|
+
return {
|
|
101
|
+
[MCP_META_PROTOCOL_VERSION]: context.protocolVersion,
|
|
102
|
+
[MCP_META_CLIENT_INFO]: { name: context.clientInfo.name, version: context.clientInfo.version },
|
|
103
|
+
[MCP_META_CLIENT_CAPABILITIES]: context.capabilities,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Merge modern `_meta` into request params without clobbering existing keys. */
|
|
108
|
+
export function withModernMeta(
|
|
109
|
+
params: Record<string, unknown>,
|
|
110
|
+
context: MCPModernClientContext,
|
|
111
|
+
): Record<string, unknown> {
|
|
112
|
+
const existing = params._meta;
|
|
113
|
+
const base = typeof existing === "object" && existing !== null && !Array.isArray(existing) ? existing : {};
|
|
114
|
+
return { ...params, _meta: { ...base, ...buildModernRequestMeta(context) } };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// =============================================================================
|
|
118
|
+
// Streamable HTTP mirrored headers (modern era)
|
|
119
|
+
// =============================================================================
|
|
120
|
+
|
|
121
|
+
const BASE64_SENTINEL_PREFIX = "=?base64?";
|
|
122
|
+
const BASE64_SENTINEL_SUFFIX = "?=";
|
|
123
|
+
|
|
124
|
+
/** RFC 9110 field-value safe set: visible ASCII, space, and horizontal tab. */
|
|
125
|
+
export function isPlainAsciiHeaderValue(value: string): boolean {
|
|
126
|
+
if (value.length === 0) return true;
|
|
127
|
+
// Leading/trailing whitespace forces encoding (intermediaries may trim).
|
|
128
|
+
if (value !== value.trim()) return false;
|
|
129
|
+
for (let i = 0; i < value.length; i++) {
|
|
130
|
+
const code = value.charCodeAt(i);
|
|
131
|
+
if (code === 0x09) continue;
|
|
132
|
+
if (code < 0x21 || code > 0x7e) return false;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Encode a value for `Mcp-Name` / `Mcp-Param-{Name}` headers: plain ASCII when
|
|
139
|
+
* safe, otherwise the `=?base64?<base64-utf8>?=` sentinel. Values already
|
|
140
|
+
* matching the sentinel pattern MUST also be encoded to avoid ambiguity.
|
|
141
|
+
*/
|
|
142
|
+
export function encodeMcpHeaderValue(value: string): string {
|
|
143
|
+
if (
|
|
144
|
+
isPlainAsciiHeaderValue(value) &&
|
|
145
|
+
!(value.startsWith(BASE64_SENTINEL_PREFIX) && value.endsWith(BASE64_SENTINEL_SUFFIX))
|
|
146
|
+
) {
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
return `${BASE64_SENTINEL_PREFIX}${Buffer.from(value, "utf8").toString("base64")}${BASE64_SENTINEL_SUFFIX}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** HTTP field-name token syntax (RFC 9110 §5.1: 1*tchar). */
|
|
153
|
+
const HTTP_FIELD_NAME_PATTERN = /^[!#$%&'*+\-.0-9A-Za-z^_`|~]+$/;
|
|
154
|
+
|
|
155
|
+
/** Methods whose `params.name` / `params.uri` MUST be mirrored into `Mcp-Name`. */
|
|
156
|
+
const MCP_NAME_HEADER_METHODS = new Set(["tools/call", "resources/read", "prompts/get"]);
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Build the mirrored headers a modern Streamable HTTP request MUST carry:
|
|
160
|
+
* `MCP-Protocol-Version` (must equal the `_meta` version), `Mcp-Method`, and —
|
|
161
|
+
* for `tools/call`, `resources/read`, `prompts/get` — `Mcp-Name`.
|
|
162
|
+
*/
|
|
163
|
+
export function buildModernMcpHeaders(input: {
|
|
164
|
+
protocolVersion: string;
|
|
165
|
+
method: string;
|
|
166
|
+
params?: Record<string, unknown>;
|
|
167
|
+
}): Record<string, string> {
|
|
168
|
+
const headers: Record<string, string> = {
|
|
169
|
+
"MCP-Protocol-Version": input.protocolVersion,
|
|
170
|
+
"Mcp-Method": encodeMcpHeaderValue(input.method),
|
|
171
|
+
};
|
|
172
|
+
if (MCP_NAME_HEADER_METHODS.has(input.method)) {
|
|
173
|
+
const nameValue = input.params?.name ?? input.params?.uri;
|
|
174
|
+
if (typeof nameValue === "string" && nameValue.length > 0) {
|
|
175
|
+
headers["Mcp-Name"] = encodeMcpHeaderValue(nameValue);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return headers;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// =============================================================================
|
|
182
|
+
// `x-mcp-header` tool parameter mirroring (modern era, Streamable HTTP)
|
|
183
|
+
// =============================================================================
|
|
184
|
+
|
|
185
|
+
/** A validated binding from a tool inputSchema property to an `Mcp-Param-*` header. */
|
|
186
|
+
export interface McpHeaderParamBinding {
|
|
187
|
+
/** Exact property path (chain of `properties` keys) in the call arguments. */
|
|
188
|
+
propertyPath: string[];
|
|
189
|
+
/** The `name` portion of the `Mcp-Param-{name}` header. */
|
|
190
|
+
headerName: string;
|
|
191
|
+
/** Primitive type of the annotated property. */
|
|
192
|
+
propertyType: "string" | "integer" | "boolean";
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface XMcpHeaderBindingsResult {
|
|
196
|
+
bindings: McpHeaderParamBinding[];
|
|
197
|
+
/** Human-readable reasons the tool definition is invalid for HTTP mirroring. */
|
|
198
|
+
violations: string[];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
202
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Collect `x-mcp-header` bindings from a tool `inputSchema`, enforcing the
|
|
207
|
+
* specification constraints: field-name token syntax, primitive (non-number)
|
|
208
|
+
* types, case-insensitive uniqueness, and static reachability via `properties`
|
|
209
|
+
* chains only. Any violation invalidates the tool definition for HTTP clients.
|
|
210
|
+
*/
|
|
211
|
+
export function collectXMcpHeaderBindings(inputSchema: unknown): XMcpHeaderBindingsResult {
|
|
212
|
+
const bindings: McpHeaderParamBinding[] = [];
|
|
213
|
+
const violations: string[] = [];
|
|
214
|
+
const seenHeaderNames = new Set<string>();
|
|
215
|
+
|
|
216
|
+
const walk = (schema: unknown, path: string[]): void => {
|
|
217
|
+
if (!isRecord(schema)) return;
|
|
218
|
+
const annotation = schema["x-mcp-header"];
|
|
219
|
+
if (annotation !== undefined) {
|
|
220
|
+
const label = path.length > 0 ? path.join(".") : "(root)";
|
|
221
|
+
if (typeof annotation !== "string" || annotation.length === 0) {
|
|
222
|
+
violations.push(`x-mcp-header on "${label}" must be a non-empty string`);
|
|
223
|
+
} else if (!HTTP_FIELD_NAME_PATTERN.test(annotation)) {
|
|
224
|
+
violations.push(`x-mcp-header "${annotation}" on "${label}" is not a valid HTTP field-name token`);
|
|
225
|
+
} else if (seenHeaderNames.has(annotation.toLowerCase())) {
|
|
226
|
+
violations.push(`x-mcp-header "${annotation}" is not case-insensitively unique`);
|
|
227
|
+
} else {
|
|
228
|
+
const type = schema.type;
|
|
229
|
+
if (type !== "string" && type !== "integer" && type !== "boolean") {
|
|
230
|
+
violations.push(
|
|
231
|
+
`x-mcp-header "${annotation}" on "${label}" requires a primitive type (string, integer, boolean)`,
|
|
232
|
+
);
|
|
233
|
+
} else if (path.length === 0) {
|
|
234
|
+
violations.push(`x-mcp-header "${annotation}" must annotate a property, not the schema root`);
|
|
235
|
+
} else {
|
|
236
|
+
seenHeaderNames.add(annotation.toLowerCase());
|
|
237
|
+
bindings.push({ propertyPath: path, headerName: annotation, propertyType: type });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Only `properties` chains are statically reachable; anything annotated
|
|
242
|
+
// under items/composition/conditional keywords is unreachable and invalid
|
|
243
|
+
// by construction (we simply never descend there, so such annotations are
|
|
244
|
+
// ignored rather than mirrored).
|
|
245
|
+
if (isRecord(schema.properties)) {
|
|
246
|
+
for (const [key, subschema] of Object.entries(schema.properties)) {
|
|
247
|
+
walk(subschema, [...path, key]);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
walk(inputSchema, []);
|
|
253
|
+
return { bindings, violations };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Extract `Mcp-Param-{name}` headers from tool call arguments per validated
|
|
258
|
+
* bindings. Missing or null values omit the header, per the specification.
|
|
259
|
+
*/
|
|
260
|
+
export function buildXMcpParamHeaders(
|
|
261
|
+
bindings: readonly McpHeaderParamBinding[],
|
|
262
|
+
args: Record<string, unknown>,
|
|
263
|
+
): Record<string, string> {
|
|
264
|
+
const headers: Record<string, string> = {};
|
|
265
|
+
for (const binding of bindings) {
|
|
266
|
+
let value: unknown = args;
|
|
267
|
+
for (const key of binding.propertyPath) {
|
|
268
|
+
if (!isRecord(value)) {
|
|
269
|
+
value = undefined;
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
value = value[key];
|
|
273
|
+
}
|
|
274
|
+
if (value === undefined || value === null) continue;
|
|
275
|
+
let text: string;
|
|
276
|
+
switch (binding.propertyType) {
|
|
277
|
+
case "string":
|
|
278
|
+
if (typeof value !== "string") continue;
|
|
279
|
+
text = value;
|
|
280
|
+
break;
|
|
281
|
+
case "integer":
|
|
282
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) continue;
|
|
283
|
+
text = String(value);
|
|
284
|
+
break;
|
|
285
|
+
case "boolean":
|
|
286
|
+
if (typeof value !== "boolean") continue;
|
|
287
|
+
text = value ? "true" : "false";
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
headers[`Mcp-Param-${binding.headerName}`] = encodeMcpHeaderValue(text);
|
|
291
|
+
}
|
|
292
|
+
return headers;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// =============================================================================
|
|
296
|
+
// Era detection (Streamable HTTP backward compatibility)
|
|
297
|
+
// =============================================================================
|
|
298
|
+
|
|
299
|
+
/** Failure classes for a modern probe request. */
|
|
300
|
+
export type MCPProbeFailureClass =
|
|
301
|
+
/** Recognized modern JSON-RPC error: the server speaks a modern revision. */
|
|
302
|
+
| "modern-error"
|
|
303
|
+
/** 4xx without a recognized modern error body: legacy-era server signal. */
|
|
304
|
+
| "legacy-signal"
|
|
305
|
+
/** 401/403 (and WWW-Authenticate challenges): never a downgrade signal. */
|
|
306
|
+
| "auth-failure"
|
|
307
|
+
/** Anything else (5xx, network, malformed payload): not a downgrade signal. */
|
|
308
|
+
| "other-failure";
|
|
309
|
+
|
|
310
|
+
export interface MCPProbeClassification {
|
|
311
|
+
class: MCPProbeFailureClass;
|
|
312
|
+
/** Protocol-defined modern error code when recognized. */
|
|
313
|
+
modernErrorCode?: number;
|
|
314
|
+
/** `data.supported` from an UnsupportedProtocolVersionError, when present. */
|
|
315
|
+
supportedVersions?: string[];
|
|
316
|
+
/** `data.requested` from an UnsupportedProtocolVersionError, when present. */
|
|
317
|
+
requestedVersion?: string;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function isModernErrorCode(code: number): boolean {
|
|
321
|
+
return (
|
|
322
|
+
code === MCP_ERROR_HEADER_MISMATCH ||
|
|
323
|
+
code === MCP_ERROR_MISSING_REQUIRED_CLIENT_CAPABILITY ||
|
|
324
|
+
code === MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Classify a failed modern probe per the specification's era-detection rules:
|
|
330
|
+
* recognized modern JSON-RPC errors identify a modern server; a 400/404/405
|
|
331
|
+
* without one identifies a legacy server; auth and security failures are never
|
|
332
|
+
* era signals and must never authorize a downgrade.
|
|
333
|
+
*/
|
|
334
|
+
export function classifyMcpProbeFailure(status: number, parsedBody: unknown): MCPProbeClassification {
|
|
335
|
+
if (status === 401 || status === 403) {
|
|
336
|
+
return { class: "auth-failure" };
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
let errorCode: number | undefined;
|
|
340
|
+
let errorData: unknown;
|
|
341
|
+
if (isRecord(parsedBody) && isRecord(parsedBody.error)) {
|
|
342
|
+
if (typeof parsedBody.error.code === "number") errorCode = parsedBody.error.code;
|
|
343
|
+
errorData = parsedBody.error.data;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (errorCode !== undefined && isModernErrorCode(errorCode)) {
|
|
347
|
+
const classification: MCPProbeClassification = { class: "modern-error", modernErrorCode: errorCode };
|
|
348
|
+
if (errorCode === MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION && isRecord(errorData)) {
|
|
349
|
+
if (Array.isArray(errorData.supported) && errorData.supported.every(v => typeof v === "string")) {
|
|
350
|
+
classification.supportedVersions = errorData.supported as string[];
|
|
351
|
+
}
|
|
352
|
+
if (typeof errorData.requested === "string") classification.requestedVersion = errorData.requested;
|
|
353
|
+
}
|
|
354
|
+
return classification;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// A modern server reports unknown methods as 404 + -32601; that pairing is
|
|
358
|
+
// itself a modern-era signal (legacy HTTP+SSE 404s carry no JSON-RPC body).
|
|
359
|
+
if (status === 404 && errorCode === JSONRPC_ERROR_METHOD_NOT_FOUND) {
|
|
360
|
+
return { class: "modern-error", modernErrorCode: errorCode };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (status === 400 || status === 404 || status === 405) {
|
|
364
|
+
return { class: "legacy-signal" };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return { class: "other-failure" };
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// =============================================================================
|
|
371
|
+
// Authoritative protocol observation model
|
|
372
|
+
// =============================================================================
|
|
373
|
+
|
|
374
|
+
/** Lifecycle state of a protocol feature, mirroring the specification's feature lifecycle. */
|
|
375
|
+
export type MCPFeatureLifecycle = "active" | "deprecated" | "removed";
|
|
376
|
+
|
|
377
|
+
export interface MCPProtocolFeatureState {
|
|
378
|
+
feature: string;
|
|
379
|
+
lifecycle: MCPFeatureLifecycle;
|
|
380
|
+
/** Secret-free explanation shown in diagnostics. */
|
|
381
|
+
note?: string;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** How the effective era/version was reached. */
|
|
385
|
+
export type MCPNegotiationState =
|
|
386
|
+
/** No negotiation attempt has completed yet. */
|
|
387
|
+
| "pending"
|
|
388
|
+
/** Modern era confirmed (probe or direct modern request succeeded). */
|
|
389
|
+
| "modern"
|
|
390
|
+
/** Modern era after selecting a mutually supported version from UnsupportedProtocolVersionError. */
|
|
391
|
+
| "modern-version-retry"
|
|
392
|
+
/** Legacy era via era detection (legacy server signal) under `auto`. */
|
|
393
|
+
| "legacy-fallback"
|
|
394
|
+
/** Legacy era because configuration forced it (`legacy`) or the transport is stdio. */
|
|
395
|
+
| "legacy-forced"
|
|
396
|
+
/** Negotiation failed; the connection could not be established. */
|
|
397
|
+
| "failed";
|
|
398
|
+
|
|
399
|
+
/** Machine-readable reasons a legacy fallback was engaged (never auth/security driven). */
|
|
400
|
+
export type MCPDowngradeReason =
|
|
401
|
+
/** `protocol: "legacy"` configured explicitly. */
|
|
402
|
+
| "preference-legacy"
|
|
403
|
+
/** stdio transport has no per-request HTTP signals; legacy handshake retained. */
|
|
404
|
+
| "stdio-transport"
|
|
405
|
+
/** Probe returned 400/404/405 without a recognized modern error body. */
|
|
406
|
+
| "legacy-server-signal"
|
|
407
|
+
/** A modern server advertised only legacy-era versions in `supported`. */
|
|
408
|
+
| "server-advertised-legacy-only";
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* One authoritative, secret-free observation of a server's negotiated protocol
|
|
412
|
+
* state. Consumed by `/extensions` (#4291) and customization doctor (#4288);
|
|
413
|
+
* contains no credentials, tokens, metadata documents, or header values.
|
|
414
|
+
*/
|
|
415
|
+
export interface MCPProtocolObservation {
|
|
416
|
+
/** Configured preference (defaults to `auto`). */
|
|
417
|
+
preference: MCPProtocolPreference;
|
|
418
|
+
/** Effective protocol version in use, once negotiated. */
|
|
419
|
+
effectiveVersion: string | null;
|
|
420
|
+
/** Effective era, once negotiated. */
|
|
421
|
+
era: MCPProtocolEra | null;
|
|
422
|
+
/** How the effective state was reached. */
|
|
423
|
+
negotiation: MCPNegotiationState;
|
|
424
|
+
/** Why a legacy fallback engaged; null unless `negotiation` is a legacy state. */
|
|
425
|
+
downgradeReason: MCPDowngradeReason | null;
|
|
426
|
+
/** Versions the server advertised (via server/discover or version errors). */
|
|
427
|
+
supportedVersions: string[];
|
|
428
|
+
/** Self-reported server identity (display only; never security-relevant). */
|
|
429
|
+
serverInfo: { name: string; version: string } | null;
|
|
430
|
+
/** Lifecycle visibility for protocol features (legacy session behavior, etc). */
|
|
431
|
+
features: MCPProtocolFeatureState[];
|
|
432
|
+
/** v2 capability state observed for this connection. */
|
|
433
|
+
capabilities: {
|
|
434
|
+
/** server/discover answered (optional per spec; absence does not block calls). */
|
|
435
|
+
discover: "yes" | "no" | "unknown";
|
|
436
|
+
/** Server advertised tools capability. */
|
|
437
|
+
tools: boolean;
|
|
438
|
+
/** Server advertised resources capability. */
|
|
439
|
+
resources: boolean;
|
|
440
|
+
/** Server advertised prompts capability. */
|
|
441
|
+
prompts: boolean;
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/** Initial observation before negotiation completes. */
|
|
446
|
+
export function createMCPProtocolObservation(preference: MCPProtocolPreference): MCPProtocolObservation {
|
|
447
|
+
return {
|
|
448
|
+
preference,
|
|
449
|
+
effectiveVersion: null,
|
|
450
|
+
era: null,
|
|
451
|
+
negotiation: "pending",
|
|
452
|
+
downgradeReason: null,
|
|
453
|
+
supportedVersions: [],
|
|
454
|
+
serverInfo: null,
|
|
455
|
+
features: [],
|
|
456
|
+
capabilities: { discover: "unknown", tools: false, resources: false, prompts: false },
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/** Legacy session/transport features reported as deprecated under the feature lifecycle. */
|
|
461
|
+
export function legacyEraFeatureStates(): MCPProtocolFeatureState[] {
|
|
462
|
+
return [
|
|
463
|
+
{
|
|
464
|
+
feature: "initialize-handshake",
|
|
465
|
+
lifecycle: "deprecated",
|
|
466
|
+
note: "Connection-scoped initialize/initialized handshake; removed from the core request path in 2026-07-28",
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
feature: "mcp-session-id",
|
|
470
|
+
lifecycle: "deprecated",
|
|
471
|
+
note: "Protocol-level Mcp-Session-Id sessions; not part of 2026-07-28",
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
feature: "standalone-sse-stream",
|
|
475
|
+
lifecycle: "deprecated",
|
|
476
|
+
note: "GET-opened standalone SSE stream; removed in 2026-07-28 (subscriptions/listen replaces it)",
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
feature: "sse-resumability",
|
|
480
|
+
lifecycle: "deprecated",
|
|
481
|
+
note: "Last-Event-ID stream replay; unsupported in 2026-07-28",
|
|
482
|
+
},
|
|
483
|
+
];
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** Finalize an observation for a negotiated modern connection. */
|
|
487
|
+
export function modernEraObservation(input: {
|
|
488
|
+
preference: MCPProtocolPreference;
|
|
489
|
+
effectiveVersion: string;
|
|
490
|
+
negotiation: "modern" | "modern-version-retry";
|
|
491
|
+
supportedVersions?: string[];
|
|
492
|
+
serverInfo?: { name: string; version: string } | null;
|
|
493
|
+
capabilities?: { tools?: boolean; resources?: boolean; prompts?: boolean };
|
|
494
|
+
discover: "yes" | "no" | "unknown";
|
|
495
|
+
}): MCPProtocolObservation {
|
|
496
|
+
return {
|
|
497
|
+
preference: input.preference,
|
|
498
|
+
effectiveVersion: input.effectiveVersion,
|
|
499
|
+
era: "modern",
|
|
500
|
+
negotiation: input.negotiation,
|
|
501
|
+
downgradeReason: null,
|
|
502
|
+
supportedVersions: input.supportedVersions ?? [],
|
|
503
|
+
serverInfo: input.serverInfo ?? null,
|
|
504
|
+
features: [],
|
|
505
|
+
capabilities: {
|
|
506
|
+
discover: input.discover,
|
|
507
|
+
tools: input.capabilities?.tools ?? false,
|
|
508
|
+
resources: input.capabilities?.resources ?? false,
|
|
509
|
+
prompts: input.capabilities?.prompts ?? false,
|
|
510
|
+
},
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/** Finalize an observation for a negotiated legacy connection. */
|
|
515
|
+
export function legacyEraObservation(input: {
|
|
516
|
+
preference: MCPProtocolPreference;
|
|
517
|
+
effectiveVersion: string;
|
|
518
|
+
negotiation: "legacy-fallback" | "legacy-forced";
|
|
519
|
+
downgradeReason: MCPDowngradeReason;
|
|
520
|
+
serverInfo?: { name: string; version: string } | null;
|
|
521
|
+
capabilities?: { tools?: boolean; resources?: boolean; prompts?: boolean };
|
|
522
|
+
}): MCPProtocolObservation {
|
|
523
|
+
return {
|
|
524
|
+
preference: input.preference,
|
|
525
|
+
effectiveVersion: input.effectiveVersion,
|
|
526
|
+
era: "legacy",
|
|
527
|
+
negotiation: input.negotiation,
|
|
528
|
+
downgradeReason: input.downgradeReason,
|
|
529
|
+
supportedVersions: [],
|
|
530
|
+
serverInfo: input.serverInfo ?? null,
|
|
531
|
+
features: legacyEraFeatureStates(),
|
|
532
|
+
capabilities: {
|
|
533
|
+
discover: "no",
|
|
534
|
+
tools: input.capabilities?.tools ?? false,
|
|
535
|
+
resources: input.capabilities?.resources ?? false,
|
|
536
|
+
prompts: input.capabilities?.prompts ?? false,
|
|
537
|
+
},
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// =============================================================================
|
|
542
|
+
// Caching hints (server/discover and catalog results)
|
|
543
|
+
// =============================================================================
|
|
544
|
+
|
|
545
|
+
/** Cache scope hint: public results may cross authorization contexts; private must not. */
|
|
546
|
+
export type MCPCacheScope = "public" | "private";
|
|
547
|
+
|
|
548
|
+
/** Server-supplied caching hints carried on cacheable `complete` results. */
|
|
549
|
+
export interface MCPCacheHints {
|
|
550
|
+
/** Milliseconds the result may be considered fresh; absent/negative means 0. */
|
|
551
|
+
ttlMs?: number;
|
|
552
|
+
cacheScope?: MCPCacheScope;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/** Normalize raw hints: negative ttlMs is treated as 0 per the specification. */
|
|
556
|
+
export function normalizeMcpCacheHints(raw: unknown): MCPCacheHints | undefined {
|
|
557
|
+
if (!isRecord(raw)) return undefined;
|
|
558
|
+
const hints: MCPCacheHints = {};
|
|
559
|
+
if (typeof raw.ttlMs === "number" && Number.isFinite(raw.ttlMs)) {
|
|
560
|
+
hints.ttlMs = Math.max(0, raw.ttlMs);
|
|
561
|
+
}
|
|
562
|
+
if (raw.cacheScope === "public" || raw.cacheScope === "private") {
|
|
563
|
+
hints.cacheScope = raw.cacheScope;
|
|
564
|
+
}
|
|
565
|
+
return hints.ttlMs === undefined && hints.cacheScope === undefined ? undefined : hints;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// =============================================================================
|
|
569
|
+
// MRTR (multi round-trip requests)
|
|
570
|
+
// =============================================================================
|
|
571
|
+
|
|
572
|
+
/** Result type marker for interim input requests. */
|
|
573
|
+
export const MCP_RESULT_TYPE_INPUT_REQUIRED = "input_required";
|
|
574
|
+
export const MCP_RESULT_TYPE_COMPLETE = "complete";
|
|
575
|
+
|
|
576
|
+
/** Input request methods a server may embed in an InputRequiredResult. */
|
|
577
|
+
export const MCP_INPUT_REQUEST_METHODS = new Set(["elicitation/create", "sampling/createMessage", "roots/list"]);
|
|
578
|
+
|
|
579
|
+
export interface MCPInputRequiredData {
|
|
580
|
+
inputRequests: Record<string, { method: string; params?: Record<string, unknown> }>;
|
|
581
|
+
requestState?: string;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Extract MRTR input data from a JSON-RPC result. Returns null when the result
|
|
586
|
+
* is a normal `complete` result (including legacy results with no resultType,
|
|
587
|
+
* which the specification requires clients to treat as `"complete"`).
|
|
588
|
+
* Throws on a malformed `input_required` payload.
|
|
589
|
+
*/
|
|
590
|
+
export function extractMcpInputRequired(result: unknown): MCPInputRequiredData | null {
|
|
591
|
+
if (!isRecord(result)) return null;
|
|
592
|
+
const resultType = result.resultType;
|
|
593
|
+
if (resultType === undefined || resultType === MCP_RESULT_TYPE_COMPLETE) return null;
|
|
594
|
+
if (resultType !== MCP_RESULT_TYPE_INPUT_REQUIRED) {
|
|
595
|
+
// Unrecognized resultType values are invalid per the specification.
|
|
596
|
+
throw new Error(`MCP result has unrecognized resultType "${String(resultType)}"`);
|
|
597
|
+
}
|
|
598
|
+
const inputRequests: MCPInputRequiredData["inputRequests"] = {};
|
|
599
|
+
if (result.inputRequests !== undefined) {
|
|
600
|
+
if (!isRecord(result.inputRequests)) {
|
|
601
|
+
throw new Error("MCP input_required result has malformed inputRequests");
|
|
602
|
+
}
|
|
603
|
+
for (const [key, value] of Object.entries(result.inputRequests)) {
|
|
604
|
+
if (!isRecord(value) || typeof value.method !== "string" || !MCP_INPUT_REQUEST_METHODS.has(value.method)) {
|
|
605
|
+
throw new Error(`MCP input_required request "${key}" is not a supported input request`);
|
|
606
|
+
}
|
|
607
|
+
inputRequests[key] = {
|
|
608
|
+
method: value.method,
|
|
609
|
+
...(isRecord(value.params) ? { params: value.params } : {}),
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
let requestState: string | undefined;
|
|
614
|
+
if (result.requestState !== undefined) {
|
|
615
|
+
if (typeof result.requestState !== "string") {
|
|
616
|
+
throw new Error("MCP input_required result has non-string requestState");
|
|
617
|
+
}
|
|
618
|
+
requestState = result.requestState;
|
|
619
|
+
}
|
|
620
|
+
if (Object.keys(inputRequests).length === 0 && requestState === undefined) {
|
|
621
|
+
throw new Error("MCP input_required result carries neither inputRequests nor requestState");
|
|
622
|
+
}
|
|
623
|
+
return { inputRequests, ...(requestState === undefined ? {} : { requestState }) };
|
|
624
|
+
}
|