@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
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
DEFAULT_MODEL_SELECTION_RECOVERY_MESSAGE,
|
|
4
4
|
parseDefaultModelSelectionRecovery,
|
|
5
5
|
} from "../../../session/default-model-selection";
|
|
6
|
-
import { isElevationAllowlisted } from "../../elevation/allowlist";
|
|
7
6
|
import { OPERATIONS, type Operation } from "../../protocol/operation-registry";
|
|
8
7
|
import type { ControlInput, ControlSurface, ControlValue } from "./operations";
|
|
8
|
+
import { brokerRuntimeCloseCapability, hasBrokerRuntimeCloseCapability } from "./runtime-gate";
|
|
9
9
|
|
|
10
10
|
export interface ControlRequest {
|
|
11
11
|
id: string;
|
|
@@ -14,8 +14,6 @@ export interface ControlRequest {
|
|
|
14
14
|
expectedRevision?: string;
|
|
15
15
|
idempotencyKey?: string;
|
|
16
16
|
confirm?: boolean;
|
|
17
|
-
/** Top-level elevation claim selector, preserved from the control frame. */
|
|
18
|
-
elevationRequestId?: string;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
export type ControlErrorCode = string;
|
|
@@ -69,8 +67,21 @@ const SHARED_ERROR_CODES = new Set([
|
|
|
69
67
|
"cursor_expired",
|
|
70
68
|
"event_gap",
|
|
71
69
|
"unavailable",
|
|
70
|
+
"operation_prohibited",
|
|
72
71
|
"internal",
|
|
73
72
|
]);
|
|
73
|
+
|
|
74
|
+
/** Lifecycle mutations must enter through the Broker-backed lifecycle service. */
|
|
75
|
+
const BROKER_LIFECYCLE_CONTROL_OPERATIONS = new Set([
|
|
76
|
+
"session.new",
|
|
77
|
+
"session.fork",
|
|
78
|
+
"session.resume",
|
|
79
|
+
"session.switch",
|
|
80
|
+
"session.branch",
|
|
81
|
+
"session.handoff",
|
|
82
|
+
"session.close",
|
|
83
|
+
"session.delete",
|
|
84
|
+
]);
|
|
74
85
|
const IDEMPOTENCY_TTL_MS = 15 * 60 * 1_000;
|
|
75
86
|
const MAX_IDEMPOTENCY_ENTRIES = 256;
|
|
76
87
|
|
|
@@ -108,11 +119,7 @@ function failure(
|
|
|
108
119
|
function isInput(value: unknown): value is ControlInput {
|
|
109
120
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
110
121
|
}
|
|
111
|
-
|
|
112
|
-
* Build the typed control request from a wire frame. Every runtime transport
|
|
113
|
-
* mapper uses this helper so the top-level elevation claim selector cannot
|
|
114
|
-
* drift between callsites.
|
|
115
|
-
*/
|
|
122
|
+
|
|
116
123
|
export function controlRequestFromFrame(frame: Record<string, unknown>): ControlRequest {
|
|
117
124
|
return {
|
|
118
125
|
id: typeof frame.id === "string" ? frame.id : "",
|
|
@@ -121,7 +128,6 @@ export function controlRequestFromFrame(frame: Record<string, unknown>): Control
|
|
|
121
128
|
expectedRevision: typeof frame.expectedRevision === "string" ? frame.expectedRevision : undefined,
|
|
122
129
|
idempotencyKey: typeof frame.idempotencyKey === "string" ? frame.idempotencyKey : undefined,
|
|
123
130
|
confirm: frame.confirm === true,
|
|
124
|
-
elevationRequestId: typeof frame.elevationRequestId === "string" ? frame.elevationRequestId : undefined,
|
|
125
131
|
};
|
|
126
132
|
}
|
|
127
133
|
|
|
@@ -142,47 +148,95 @@ function inputHash(input: unknown): string {
|
|
|
142
148
|
.update(JSON.stringify(canonicalize(input)))
|
|
143
149
|
.digest("hex");
|
|
144
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Normalize a WELL-FORMED terminal abort input for the idempotency hash:
|
|
153
|
+
* omitted scope defaults to "turn", so `{mode:"terminal"}` and
|
|
154
|
+
* `{mode:"terminal", scope:"turn"}` share one idempotency key (the durable
|
|
155
|
+
* terminal-scope replay hashes the same normalized payload). Malformed
|
|
156
|
+
* inputs (unknown fields, invalid mode/scope) are left raw so they are
|
|
157
|
+
* rejected downstream and never collide with a valid input's key.
|
|
158
|
+
*/
|
|
159
|
+
function normalizeTerminalAbortInputForHash(input: unknown): unknown {
|
|
160
|
+
if (typeof input !== "object" || input === null) return input;
|
|
161
|
+
const record = input as Record<string, unknown>;
|
|
162
|
+
if (record.mode !== "terminal") return input;
|
|
163
|
+
for (const key of Object.keys(record)) if (!TERMINAL_ABORT_FIELDS.has(key)) return input;
|
|
164
|
+
const scope = record.scope;
|
|
165
|
+
if (scope !== undefined && scope !== "turn" && scope !== "owned") return input;
|
|
166
|
+
return { mode: "terminal", scope: scope === undefined ? "turn" : scope };
|
|
167
|
+
}
|
|
145
168
|
|
|
146
169
|
function text(input: ControlInput, key = "text"): string {
|
|
147
170
|
return input[key] as string;
|
|
148
171
|
}
|
|
149
172
|
|
|
173
|
+
const TERMINAL_ABORT_FIELDS = new Set(["mode", "scope"]);
|
|
174
|
+
|
|
175
|
+
function invalidInput(message: string): never {
|
|
176
|
+
throw new TypedControlError("invalid_input", message);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* C04 `turn.abort` dispatch.
|
|
181
|
+
*
|
|
182
|
+
* Legacy behavior (omitted mode or `mode:"turn"`) is preserved verbatim: the
|
|
183
|
+
* input is dropped and the ordinary argument-less `surface.abort()` runs.
|
|
184
|
+
*
|
|
185
|
+
* Terminal mode (`mode:"terminal"`) is validated strictly and side-effect-free
|
|
186
|
+
* before any surface call: only `mode`/`scope` fields are accepted, `scope`
|
|
187
|
+
* must be `"turn"` or `"owned"` (default `"turn"`), and a nonempty idempotency
|
|
188
|
+
* key of at most 128 UTF-8 bytes is required on the request envelope. Terminal
|
|
189
|
+
* semantics (see the approved plan): stop the root worker's current turn and
|
|
190
|
+
* block only its own continuation routes; left-running owned work keeps
|
|
191
|
+
* running and its completions are delivered normally so the root worker can
|
|
192
|
+
* resume with a fresh attempt — owned delivery is NOT suppressed.
|
|
193
|
+
*/
|
|
194
|
+
function invokeAbort(surface: ControlSurface, input: ControlInput, idempotencyKey: string | undefined): ControlValue {
|
|
195
|
+
const mode = input.mode === undefined ? "turn" : input.mode;
|
|
196
|
+
if (mode === "turn") return surface.abort();
|
|
197
|
+
if (mode !== "terminal") invalidInput('turn.abort mode must be "turn" or "terminal".');
|
|
198
|
+
for (const key of Object.keys(input))
|
|
199
|
+
if (!TERMINAL_ABORT_FIELDS.has(key)) invalidInput(`Unknown turn.abort terminal field: ${key}`);
|
|
200
|
+
const scope = input.scope === undefined ? "turn" : input.scope;
|
|
201
|
+
if (scope !== "turn" && scope !== "owned") invalidInput('turn.abort terminal scope must be "turn" or "owned".');
|
|
202
|
+
if (typeof idempotencyKey !== "string" || idempotencyKey.length === 0)
|
|
203
|
+
invalidInput("terminal abort requires a nonempty idempotency key.");
|
|
204
|
+
if (new TextEncoder().encode(idempotencyKey).length > 128)
|
|
205
|
+
invalidInput("terminal abort idempotency key must be at most 128 UTF-8 bytes.");
|
|
206
|
+
if (!surface.abortTerminal) invalidInput("terminal abort is not supported by this surface.");
|
|
207
|
+
return surface.abortTerminal({ mode: "terminal", scope }, idempotencyKey);
|
|
208
|
+
}
|
|
150
209
|
function invoke(
|
|
151
210
|
surface: ControlSurface,
|
|
152
211
|
operation: string,
|
|
153
212
|
input: ControlInput,
|
|
154
213
|
confirm: boolean | undefined,
|
|
155
214
|
idempotencyKey: string | undefined,
|
|
156
|
-
elevationRequestId: string | undefined,
|
|
157
215
|
): Promise<ControlValue> | ControlValue {
|
|
158
216
|
switch (operation) {
|
|
159
217
|
case "turn.prompt":
|
|
160
218
|
return surface.prompt(text(input), input.images, input.clientRef as string | undefined);
|
|
161
219
|
case "turn.steer":
|
|
162
|
-
return surface.steer(text(input));
|
|
220
|
+
return surface.steer(text(input), typeof input.clientRef === "string" ? input.clientRef : undefined);
|
|
163
221
|
case "turn.follow_up":
|
|
164
222
|
return surface.followUp(text(input));
|
|
165
223
|
case "turn.abort":
|
|
166
|
-
return surface
|
|
224
|
+
return invokeAbort(surface, input, idempotencyKey);
|
|
167
225
|
case "turn.abort_and_prompt":
|
|
168
226
|
return surface.abortAndPrompt(text(input));
|
|
169
227
|
case "ask.answer":
|
|
170
228
|
return surface.answerAsk(text(input, "id"), input.answer);
|
|
171
229
|
case "workflow.gate_answer":
|
|
230
|
+
if (idempotencyKey === undefined)
|
|
231
|
+
return surface.answerGate(text(input, "id"), input.response, input.expectedSessionId as string | undefined);
|
|
172
232
|
return surface.answerGate(
|
|
173
233
|
text(input, "id"),
|
|
174
234
|
input.response,
|
|
175
235
|
input.expectedSessionId as string | undefined,
|
|
176
236
|
idempotencyKey,
|
|
177
|
-
elevationRequestId,
|
|
178
237
|
);
|
|
179
238
|
case "workflow.plan_approve":
|
|
180
|
-
return surface.approvePlan(
|
|
181
|
-
text(input, "id"),
|
|
182
|
-
input.choice,
|
|
183
|
-
input.expectedSessionId as string | undefined,
|
|
184
|
-
elevationRequestId,
|
|
185
|
-
);
|
|
239
|
+
return surface.approvePlan(text(input, "id"), input.choice, input.expectedSessionId as string | undefined);
|
|
186
240
|
case "skill.invoke":
|
|
187
241
|
return surface.invokeSkill(
|
|
188
242
|
text(input, "name"),
|
|
@@ -225,22 +279,10 @@ function invoke(
|
|
|
225
279
|
return surface.executeBash(text(input, "cmd"));
|
|
226
280
|
case "bash.abort":
|
|
227
281
|
return surface.abortBash();
|
|
228
|
-
case "session.new":
|
|
229
|
-
return surface.newSession();
|
|
230
|
-
case "session.fork":
|
|
231
|
-
return surface.forkSession();
|
|
232
|
-
case "session.resume":
|
|
233
|
-
return surface.resumeSession(text(input, "id"));
|
|
234
282
|
case "session.close":
|
|
235
|
-
return surface.closeSession();
|
|
236
|
-
case "session.switch":
|
|
237
|
-
return surface.switchSession(text(input, "id"));
|
|
238
|
-
case "session.branch":
|
|
239
|
-
return surface.branchSession(text(input, "entryId"));
|
|
283
|
+
return surface.closeSession(brokerRuntimeCloseCapability(input));
|
|
240
284
|
case "session.rename":
|
|
241
285
|
return surface.renameSession(text(input, "name"));
|
|
242
|
-
case "session.handoff":
|
|
243
|
-
return surface.handoffSession(input.target);
|
|
244
286
|
case "session.export_html":
|
|
245
287
|
return surface.exportHtml();
|
|
246
288
|
case "config.patch":
|
|
@@ -270,8 +312,6 @@ function invoke(
|
|
|
270
312
|
return surface.setExtensionEnabled(text(input, "id"), input.on as boolean);
|
|
271
313
|
case "context.clear":
|
|
272
314
|
return surface.clearContext(confirm === true);
|
|
273
|
-
case "session.delete":
|
|
274
|
-
return surface.deleteSession(text(input, "id"), confirm === true);
|
|
275
315
|
case "session.cwd.move":
|
|
276
316
|
return surface.moveCwd(text(input, "path"));
|
|
277
317
|
case "retry.last":
|
|
@@ -329,7 +369,6 @@ async function execute(surface: ControlSurface, row: Operation, request: Control
|
|
|
329
369
|
request.input as ControlInput,
|
|
330
370
|
request.confirm,
|
|
331
371
|
request.idempotencyKey,
|
|
332
|
-
request.elevationRequestId,
|
|
333
372
|
),
|
|
334
373
|
};
|
|
335
374
|
} catch (error) {
|
|
@@ -364,7 +403,11 @@ function idempotent(
|
|
|
364
403
|
const now = Date.now();
|
|
365
404
|
for (const [key, entry] of requests) if (entry.expiresAt <= now) requests.delete(key);
|
|
366
405
|
const key = `${row.sdkId}\u0000${request.idempotencyKey}`;
|
|
367
|
-
|
|
406
|
+
// Terminal abort normalizes the omitted scope BEFORE hashing so the
|
|
407
|
+
// defaulted and explicit shapes share one idempotency key (and reach the
|
|
408
|
+
// durable terminal-scope replay on eviction); malformed inputs stay raw.
|
|
409
|
+
const hashInput = row.sdkId === "turn.abort" ? normalizeTerminalAbortInputForHash(request.input) : request.input;
|
|
410
|
+
const hash = inputHash(hashInput);
|
|
368
411
|
const existing = requests.get(key);
|
|
369
412
|
if (existing) {
|
|
370
413
|
requests.delete(key);
|
|
@@ -400,33 +443,25 @@ export function dispatchControl(
|
|
|
400
443
|
return Promise.resolve(
|
|
401
444
|
failure(request.id, "unknown_operation", `Unknown control operation: ${request.operation}.`),
|
|
402
445
|
);
|
|
403
|
-
|
|
446
|
+
const brokerCloseAuthorized = row.sdkId === "session.close" && hasBrokerRuntimeCloseCapability(request.input);
|
|
447
|
+
if (BROKER_LIFECYCLE_CONTROL_OPERATIONS.has(row.sdkId) && !brokerCloseAuthorized)
|
|
448
|
+
return Promise.resolve(
|
|
449
|
+
failure(
|
|
450
|
+
request.id,
|
|
451
|
+
"operation_prohibited",
|
|
452
|
+
`${request.operation} is available only through the Broker lifecycle service.`,
|
|
453
|
+
),
|
|
454
|
+
);
|
|
455
|
+
if (
|
|
456
|
+
!brokerCloseAuthorized &&
|
|
457
|
+
surface.installedOperations instanceof Set &&
|
|
458
|
+
!surface.installedOperations.has(row.sdkId)
|
|
459
|
+
)
|
|
404
460
|
return Promise.resolve(
|
|
405
461
|
failure(request.id, "operation_not_session_owned", `${request.operation} is not installed for this session.`),
|
|
406
462
|
);
|
|
407
463
|
if (!isInput(request.input))
|
|
408
464
|
return Promise.resolve(failure(request.id, "invalid_input", "Control input must be an object."));
|
|
409
|
-
const elevationEnabled =
|
|
410
|
-
process.env.GJC_SDK_ELEVATION_ENABLED === "1" || process.env.GJC_SDK_ELEVATION_ENABLED === "true";
|
|
411
|
-
const elevationAllowlisted = isElevationAllowlisted("control", row.sdkId);
|
|
412
|
-
const elevationRequired = elevationEnabled && elevationAllowlisted;
|
|
413
|
-
if (elevationRequired && request.elevationRequestId === undefined)
|
|
414
|
-
return Promise.resolve(failure(request.id, "elevation_required", `${row.sdkId} requires an elevation grant.`));
|
|
415
|
-
if (request.elevationRequestId !== undefined) {
|
|
416
|
-
const claim = request.elevationRequestId.trim();
|
|
417
|
-
if (!claim || claim.length > 128)
|
|
418
|
-
return Promise.resolve(
|
|
419
|
-
failure(request.id, "invalid_input", "elevationRequestId must be a non-empty bounded string."),
|
|
420
|
-
);
|
|
421
|
-
if (!elevationAllowlisted)
|
|
422
|
-
return Promise.resolve(
|
|
423
|
-
failure(request.id, "invalid_input", "Only allowlisted elevation operations may carry elevationRequestId."),
|
|
424
|
-
);
|
|
425
|
-
if (!surface.authorizeElevationClaim?.(row.sdkId, request.input, claim))
|
|
426
|
-
return Promise.resolve(
|
|
427
|
-
failure(request.id, "elevation_required", "The elevation claim is not broker-authorized for this control."),
|
|
428
|
-
);
|
|
429
|
-
}
|
|
430
465
|
if ((row.sdkId === "context.clear" || row.sdkId === "session.delete") && request.confirm !== true)
|
|
431
466
|
return Promise.resolve(
|
|
432
467
|
failure(request.id, "invalid_input", "confirm: true is required for this destructive operation."),
|
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
export type ControlValue = unknown;
|
|
2
|
+
export type AbortMode = "turn" | "terminal";
|
|
3
|
+
export type AbortScope = "turn" | "owned";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Terminal-mode C04 `turn.abort` input. `scope` selects whether exact causal
|
|
7
|
+
* owned work (background Bash/task jobs, detached subagents) is also stopped
|
|
8
|
+
* (`"owned"`) or left running so its completion can resume the root worker
|
|
9
|
+
* (`"turn"`, the default).
|
|
10
|
+
*/
|
|
11
|
+
export interface TerminalAbortInput {
|
|
12
|
+
mode: "terminal";
|
|
13
|
+
scope?: AbortScope;
|
|
14
|
+
}
|
|
2
15
|
export type ControlInput = Record<string, unknown>;
|
|
3
16
|
|
|
4
17
|
/**
|
|
@@ -6,11 +19,12 @@ export type ControlInput = Record<string, unknown>;
|
|
|
6
19
|
* AgentSession and its controllers without exposing those concrete types here.
|
|
7
20
|
*/
|
|
8
21
|
export interface ControlSurface {
|
|
9
|
-
authorizeElevationClaim?(sdkId: string, input: ControlInput, capability: string): boolean;
|
|
10
22
|
prompt(text: string, images?: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
|
|
11
|
-
steer(text: string): Promise<ControlValue> | ControlValue;
|
|
23
|
+
steer(text: string, clientRef?: string): Promise<ControlValue> | ControlValue;
|
|
12
24
|
followUp(text: string): Promise<ControlValue> | ControlValue;
|
|
13
25
|
abort(): Promise<ControlValue> | ControlValue;
|
|
26
|
+
/** Terminal abort: stop the current root turn (and optionally exact owned work). */
|
|
27
|
+
abortTerminal?(input: TerminalAbortInput, idempotencyKey?: string): Promise<ControlValue> | ControlValue;
|
|
14
28
|
abortAndPrompt(text: string): Promise<ControlValue> | ControlValue;
|
|
15
29
|
answerAsk(id: string, answer: ControlValue): Promise<ControlValue> | ControlValue;
|
|
16
30
|
answerGate(
|
|
@@ -18,14 +32,8 @@ export interface ControlSurface {
|
|
|
18
32
|
response: ControlValue,
|
|
19
33
|
expectedSessionId?: string,
|
|
20
34
|
idempotencyKey?: string,
|
|
21
|
-
elevationRequestId?: string,
|
|
22
|
-
): Promise<ControlValue> | ControlValue;
|
|
23
|
-
approvePlan(
|
|
24
|
-
id: string,
|
|
25
|
-
choice: ControlValue,
|
|
26
|
-
expectedSessionId?: string,
|
|
27
|
-
elevationRequestId?: string,
|
|
28
35
|
): Promise<ControlValue> | ControlValue;
|
|
36
|
+
approvePlan(id: string, choice: ControlValue, expectedSessionId?: string): Promise<ControlValue> | ControlValue;
|
|
29
37
|
invokeSkill(name: string, args: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
|
|
30
38
|
setPlanMode(on: boolean): Promise<ControlValue> | ControlValue;
|
|
31
39
|
operateGoal(op: string, objective?: string): Promise<ControlValue> | ControlValue;
|
|
@@ -46,7 +54,7 @@ export interface ControlSurface {
|
|
|
46
54
|
newSession(): Promise<ControlValue> | ControlValue;
|
|
47
55
|
forkSession(): Promise<ControlValue> | ControlValue;
|
|
48
56
|
resumeSession(id: string): Promise<ControlValue> | ControlValue;
|
|
49
|
-
closeSession(): Promise<ControlValue> | ControlValue;
|
|
57
|
+
closeSession(capability?: string): Promise<ControlValue> | ControlValue;
|
|
50
58
|
switchSession(id: string): Promise<ControlValue> | ControlValue;
|
|
51
59
|
branchSession(entryId: string): Promise<ControlValue> | ControlValue;
|
|
52
60
|
renameSession(name: string): Promise<ControlValue> | ControlValue;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Private field carried only on the Broker's endpoint close request.
|
|
3
|
+
*
|
|
4
|
+
* The value is the lifecycle effect marker bound to the serving process. It is
|
|
5
|
+
* never published in endpoint discovery or lifecycle service results; callers
|
|
6
|
+
* that do not hold the Broker's indexed lifecycle record cannot satisfy this
|
|
7
|
+
* gate.
|
|
8
|
+
*/
|
|
9
|
+
export const BROKER_RUNTIME_CLOSE_CAPABILITY_FIELD = "__gjcBrokerCloseCapability";
|
|
10
|
+
const EXPECTED_BROKER_RUNTIME_CLOSE_CAPABILITY = process.env.GJC_LIFECYCLE_REQUEST_ID;
|
|
11
|
+
|
|
12
|
+
function record(value: unknown): Record<string, unknown> | undefined {
|
|
13
|
+
return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function brokerRuntimeCloseCapability(input: unknown): string | undefined {
|
|
17
|
+
const value = record(input)?.[BROKER_RUNTIME_CLOSE_CAPABILITY_FIELD];
|
|
18
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Remove the private close capability before a request is exposed to diagnostics. */
|
|
22
|
+
export function redactBrokerRuntimeCloseCapability(frame: Record<string, unknown>): Record<string, unknown> {
|
|
23
|
+
if (frame.type !== "control_request" || frame.operation !== "session.close") return frame;
|
|
24
|
+
const input = record(frame.input);
|
|
25
|
+
if (!input || !Object.hasOwn(input, BROKER_RUNTIME_CLOSE_CAPABILITY_FIELD)) return frame;
|
|
26
|
+
const { [BROKER_RUNTIME_CLOSE_CAPABILITY_FIELD]: _capability, ...publicInput } = input;
|
|
27
|
+
return { ...frame, input: publicInput };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Runtime-local authority check for the Broker-only graceful close executor.
|
|
32
|
+
*
|
|
33
|
+
* A lifecycle child receives GJC_LIFECYCLE_REQUEST_ID from the Broker launch
|
|
34
|
+
* environment. Generic SDK requests never receive that private marker.
|
|
35
|
+
*/
|
|
36
|
+
export function hasBrokerRuntimeCloseCapability(input: unknown): boolean {
|
|
37
|
+
const expected = EXPECTED_BROKER_RUNTIME_CLOSE_CAPABILITY;
|
|
38
|
+
const actual = brokerRuntimeCloseCapability(input);
|
|
39
|
+
return typeof expected === "string" && expected.length > 0 && actual === expected;
|
|
40
|
+
}
|
package/src/sdk/host/host.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { logger } from "@gajae-code/utils";
|
|
2
|
+
import { redactBrokerRuntimeCloseCapability } from "./control/runtime-gate";
|
|
1
3
|
import { type EventFrame, SessionEventStream } from "./events";
|
|
2
4
|
import { type ProviderLease, ReverseLeaseError, ReverseLeaseRuntime } from "./reverse-leases";
|
|
3
5
|
import type { BrokerIndexWriter, HostEndpointAdapters, SdkFrame } from "./types";
|
|
@@ -43,6 +45,8 @@ export type SessionActivationGate = (input: { sessionId: string; generation: num
|
|
|
43
45
|
export interface SessionSdkHostOptions extends HostEndpointAdapters {
|
|
44
46
|
control?: (connectionId: string, frame: SdkFrame) => unknown | Promise<unknown>;
|
|
45
47
|
query?: (connectionId: string, frame: SdkFrame) => unknown | Promise<unknown>;
|
|
48
|
+
/** Test/lifecycle seam invoked synchronously before fire-and-forget dispatch. */
|
|
49
|
+
onFrameAdmitted?: (connectionId: string, frame: SdkFrame) => void;
|
|
46
50
|
/** Best-effort diagnostic observation of accepted control/query frames. */
|
|
47
51
|
onRequest?: SdkRequestObserver;
|
|
48
52
|
/** Runs before a control response is sent; identity transitions use sendTerminal. */
|
|
@@ -50,10 +54,22 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
|
|
|
50
54
|
connectionId: string,
|
|
51
55
|
request: SdkFrame,
|
|
52
56
|
response: SdkFrame,
|
|
53
|
-
sendTerminal: () => Promise<
|
|
57
|
+
sendTerminal: () => Promise<unknown>,
|
|
54
58
|
) => void | Promise<void>;
|
|
55
59
|
/** Runs only after a successful control response has been sent to the client. */
|
|
56
60
|
afterControlResponse?: (connectionId: string, request: SdkFrame, response: SdkFrame) => void | Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Classifies the awaited control-response write exactly once: `written`
|
|
63
|
+
* (sent), `rejected` (the write threw), or `dropped` (the send adapter
|
|
64
|
+
* deliberately skipped delivery). `afterControlResponse` runs only
|
|
65
|
+
* on `written`. Used to persist monotonic response-state transitions.
|
|
66
|
+
*/
|
|
67
|
+
onControlResponseDelivery?: (
|
|
68
|
+
connectionId: string,
|
|
69
|
+
request: SdkFrame,
|
|
70
|
+
response: SdkFrame,
|
|
71
|
+
outcome: "written" | "rejected" | "dropped",
|
|
72
|
+
) => void | Promise<void>;
|
|
57
73
|
installProviderDefinitions?: (capability: string, definitions: unknown) => void;
|
|
58
74
|
onProviderDefinitionsRemoved?: (capability: string) => void;
|
|
59
75
|
onReverseCancel?: (requestId: string, reason: "provider_disconnected" | "lease_released") => void;
|
|
@@ -69,8 +85,11 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
|
|
|
69
85
|
activationGate?: SessionActivationGate;
|
|
70
86
|
}
|
|
71
87
|
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
/** Shared by the replay filter and transport live broadcasts: a connection
|
|
89
|
+
* must see the same capability-gated event kinds on both legs, or live and
|
|
90
|
+
* replay delivery diverge for the same subscriber. */
|
|
91
|
+
export const TOOL_ACTIVITY_CAPABILITY = "tool_activity_v2";
|
|
92
|
+
export const CAP_GATED_FRAME_KINDS: ReadonlySet<string> = new Set(["tool_activity", "reasoning_summary"]);
|
|
74
93
|
const EMPTY_CAPABILITIES: ReadonlySet<string> = new Set();
|
|
75
94
|
|
|
76
95
|
/** Safe, identifier-free explanations for every refused activation status. */
|
|
@@ -239,6 +258,7 @@ export class SessionSdkHost {
|
|
|
239
258
|
generation: this.events.generation,
|
|
240
259
|
});
|
|
241
260
|
const disposer = this.#options.onFrame((connectionId, frame) => {
|
|
261
|
+
this.#options.onFrameAdmitted?.(connectionId, frame);
|
|
242
262
|
void this.#onFrame(connectionId, frame);
|
|
243
263
|
});
|
|
244
264
|
this.#unsubscribe = typeof disposer === "function" ? disposer : undefined;
|
|
@@ -353,8 +373,8 @@ export class SessionSdkHost {
|
|
|
353
373
|
});
|
|
354
374
|
}
|
|
355
375
|
|
|
356
|
-
async #send(connectionId: string, frame: SdkFrame): Promise<
|
|
357
|
-
await this.#options.sendFrame(connectionId, frame);
|
|
376
|
+
async #send(connectionId: string, frame: SdkFrame): Promise<"written" | "dropped"> {
|
|
377
|
+
return await this.#options.sendFrame(connectionId, frame);
|
|
358
378
|
}
|
|
359
379
|
|
|
360
380
|
/**
|
|
@@ -395,14 +415,45 @@ export class SessionSdkHost {
|
|
|
395
415
|
if (result !== undefined) {
|
|
396
416
|
const response = { type: "control_response", ...(result as SdkFrame) };
|
|
397
417
|
let terminalSent = false;
|
|
398
|
-
|
|
399
|
-
|
|
418
|
+
let sendOutcome: "written" | "rejected" | "dropped" = "dropped";
|
|
419
|
+
const sendTerminal = async (): Promise<"written" | "rejected" | "dropped"> => {
|
|
420
|
+
// Repeat calls (early hook send + fallback) return the FIRST,
|
|
421
|
+
// actual outcome — never a false dropped for an already
|
|
422
|
+
// written response (early-identity-rotation pattern).
|
|
423
|
+
if (terminalSent) return sendOutcome;
|
|
400
424
|
terminalSent = true;
|
|
401
|
-
|
|
425
|
+
try {
|
|
426
|
+
const outcome = await this.#send(connectionId, response);
|
|
427
|
+
sendOutcome = outcome === "written" ? "written" : "dropped";
|
|
428
|
+
} catch {
|
|
429
|
+
sendOutcome = "rejected";
|
|
430
|
+
}
|
|
431
|
+
return sendOutcome;
|
|
402
432
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
433
|
+
try {
|
|
434
|
+
await this.#options.beforeControlResponse?.(connectionId, frame, response, sendTerminal);
|
|
435
|
+
// Fallback: if the before hook did not send early (identity
|
|
436
|
+
// rotation), the response is always sent here.
|
|
437
|
+
if (!terminalSent) sendOutcome = await sendTerminal();
|
|
438
|
+
} finally {
|
|
439
|
+
// Classify exactly once, immediately after the send attempt and
|
|
440
|
+
// BEFORE the optional post-write hook, so a rejected/dropped
|
|
441
|
+
// write (or an afterControlResponse throw) never mislabels it.
|
|
442
|
+
try {
|
|
443
|
+
await this.#options.onControlResponseDelivery?.(connectionId, frame, response, sendOutcome);
|
|
444
|
+
} catch (error) {
|
|
445
|
+
// Contain observer persistence failures: the response was already
|
|
446
|
+
// sent (or classified) and its delivery state recorded; rethrowing
|
|
447
|
+
// would escape into the outer #onFrame catch and send a SECOND
|
|
448
|
+
// control_response for the same request id (review thread P2).
|
|
449
|
+
logger.warn("sdk control delivery observer failed", {
|
|
450
|
+
error: error instanceof Error ? error.message : String(error),
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (sendOutcome === "written") {
|
|
455
|
+
await this.#options.afterControlResponse?.(connectionId, frame, response);
|
|
456
|
+
}
|
|
406
457
|
}
|
|
407
458
|
break;
|
|
408
459
|
}
|
|
@@ -542,7 +593,7 @@ export class SessionSdkHost {
|
|
|
542
593
|
}
|
|
543
594
|
#observeRequest(kind: "control" | "query", connectionId: string, frame: SdkFrame): void {
|
|
544
595
|
try {
|
|
545
|
-
this.#options.onRequest?.(kind, connectionId, frame);
|
|
596
|
+
this.#options.onRequest?.(kind, connectionId, redactBrokerRuntimeCloseCapability(frame));
|
|
546
597
|
} catch {
|
|
547
598
|
// Diagnostic observers must not change request handling.
|
|
548
599
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { PROMPT_CLIENT_REF_MAX_LENGTH } from "../../prompt-status.js";
|
|
3
|
+
import { TURN_RESULT_PROMPT_ALIAS, TURN_RESULT_SKILL_ALIAS } from "../../protocol/operation-registry.js";
|
|
4
|
+
|
|
3
5
|
import type { ActiveProviderDescriptor } from "../../providers.js";
|
|
4
6
|
import { ActiveProviderResolutionError } from "../../providers.js";
|
|
7
|
+
|
|
5
8
|
import {
|
|
6
9
|
assertCursorSelector,
|
|
7
10
|
type CursorEnvelope,
|
|
@@ -61,6 +64,7 @@ export interface SessionSurface {
|
|
|
61
64
|
commandId?: string;
|
|
62
65
|
turnId?: string;
|
|
63
66
|
}): unknown | Promise<unknown>;
|
|
67
|
+
getSteerStatus?(selector: { commandId?: string; turnId?: string; clientRef?: string }): unknown | Promise<unknown>;
|
|
64
68
|
/** Q27 effective model-profile catalog from the live session registry. */
|
|
65
69
|
getModelProfiles?(): unknown[] | Promise<unknown[]>;
|
|
66
70
|
/**
|
|
@@ -175,9 +179,11 @@ const names = [
|
|
|
175
179
|
"runtime.jobs.list",
|
|
176
180
|
"turn.result",
|
|
177
181
|
"models.profiles.list",
|
|
178
|
-
|
|
182
|
+
// Q28 was folded into Q26; retain the vacant slot so Q29/Q30 remain stable.
|
|
183
|
+
undefined,
|
|
179
184
|
"providers.list/active",
|
|
180
185
|
"session.checkpoint",
|
|
186
|
+
"turn.steer_status",
|
|
181
187
|
];
|
|
182
188
|
|
|
183
189
|
export class QueryHandlers {
|
|
@@ -199,8 +205,9 @@ export class QueryHandlers {
|
|
|
199
205
|
);
|
|
200
206
|
return await this.#turnResult(request);
|
|
201
207
|
}
|
|
202
|
-
if (request.query ===
|
|
203
|
-
|
|
208
|
+
if (request.query === TURN_RESULT_PROMPT_ALIAS) return await this.#promptTurnResult(request);
|
|
209
|
+
|
|
210
|
+
if (request.query === TURN_RESULT_SKILL_ALIAS) return await this.#skillTurnResult(request);
|
|
204
211
|
|
|
205
212
|
const query = request.query.startsWith("Q")
|
|
206
213
|
? request.query
|
|
@@ -217,7 +224,7 @@ export class QueryHandlers {
|
|
|
217
224
|
);
|
|
218
225
|
return await this.#turnResult(request);
|
|
219
226
|
}
|
|
220
|
-
|
|
227
|
+
|
|
221
228
|
if (
|
|
222
229
|
this.surface.installedQueries instanceof Set &&
|
|
223
230
|
!this.surface.installedQueries.has(names[Number(query.slice(1)) - 1] ?? "")
|
|
@@ -252,6 +259,7 @@ export class QueryHandlers {
|
|
|
252
259
|
if (query === "Q23") return await this.#resourceBody(request);
|
|
253
260
|
if (query === "Q24") return await this.#artifact(request);
|
|
254
261
|
if (query === "Q30") return await this.#checkpoint(request);
|
|
262
|
+
if (query === "Q31") return await this.#steerStatus(request);
|
|
255
263
|
if (query === "Q27" && request.input && Object.keys(request.input).length > 0)
|
|
256
264
|
return this.#error(request, "invalid_request", false, "models.profiles.list does not accept input fields.");
|
|
257
265
|
if (query === "Q27" && typeof this.surface.getModelProfiles !== "function")
|
|
@@ -581,7 +589,8 @@ export class QueryHandlers {
|
|
|
581
589
|
// unreachable: the bounded content cap is well under both RESPONSE_CEILING_BYTES
|
|
582
590
|
// and TARGET_PAGE_BYTES, so no revision is ever created. Reject cursors
|
|
583
591
|
// upfront instead of advertising a continuation path that can never fire.
|
|
584
|
-
if (request.cursor
|
|
592
|
+
if (request.cursor !== undefined)
|
|
593
|
+
return this.#error(request, "invalid_request", false, "turn.result does not support cursors.");
|
|
585
594
|
if (typeof this.surface.getTurnResult !== "function") return this.#error(request, "unavailable");
|
|
586
595
|
const result = await this.surface.getTurnResult({
|
|
587
596
|
kind,
|
|
@@ -637,12 +646,12 @@ export class QueryHandlers {
|
|
|
637
646
|
return await this.#turnResult({ ...request, input: { ...input, kind: "prompt" } });
|
|
638
647
|
}
|
|
639
648
|
async #skillTurnResult(request: QueryRequest): Promise<QueryResponse> {
|
|
640
|
-
if (this.surface.installedQueries instanceof Set && !this.surface.installedQueries.has("
|
|
649
|
+
if (this.surface.installedQueries instanceof Set && !this.surface.installedQueries.has("turn.result"))
|
|
641
650
|
return this.#error(
|
|
642
651
|
request,
|
|
643
652
|
"operation_not_session_owned",
|
|
644
653
|
false,
|
|
645
|
-
"
|
|
654
|
+
"turn.result is not installed for this session.",
|
|
646
655
|
);
|
|
647
656
|
const input = request.input ?? {};
|
|
648
657
|
if (input.kind !== undefined && input.kind !== "skill")
|
|
@@ -779,6 +788,56 @@ export class QueryHandlers {
|
|
|
779
788
|
return { id: request.id, ok: true, page };
|
|
780
789
|
}
|
|
781
790
|
|
|
791
|
+
async #steerStatus(request: QueryRequest): Promise<QueryResponse> {
|
|
792
|
+
if (request.cursor)
|
|
793
|
+
return this.#error(request, "invalid_request", false, "turn.steer_status does not support cursors.");
|
|
794
|
+
const input = request.input ?? {};
|
|
795
|
+
for (const key of Object.keys(input))
|
|
796
|
+
if (key !== "commandId" && key !== "turnId" && key !== "clientRef")
|
|
797
|
+
return this.#error(
|
|
798
|
+
request,
|
|
799
|
+
"invalid_request",
|
|
800
|
+
false,
|
|
801
|
+
`turn.steer_status does not accept selector field "${key}".`,
|
|
802
|
+
);
|
|
803
|
+
const commandId = typeof input.commandId === "string" && input.commandId ? input.commandId : undefined;
|
|
804
|
+
const turnId = typeof input.turnId === "string" && input.turnId ? input.turnId : undefined;
|
|
805
|
+
const rawClientRef = typeof input.clientRef === "string" ? input.clientRef : undefined;
|
|
806
|
+
const clientRef = rawClientRef?.trim() || undefined;
|
|
807
|
+
if (rawClientRef !== undefined && (!clientRef || clientRef.length > PROMPT_CLIENT_REF_MAX_LENGTH))
|
|
808
|
+
return this.#error(
|
|
809
|
+
request,
|
|
810
|
+
"invalid_request",
|
|
811
|
+
false,
|
|
812
|
+
"clientRef must be a non-empty string of at most 128 characters.",
|
|
813
|
+
);
|
|
814
|
+
if ((commandId === undefined) !== (turnId === undefined))
|
|
815
|
+
return this.#error(request, "invalid_request", false, "commandId and turnId must be provided together.");
|
|
816
|
+
if (commandId !== undefined && clientRef !== undefined)
|
|
817
|
+
return this.#error(
|
|
818
|
+
request,
|
|
819
|
+
"invalid_request",
|
|
820
|
+
false,
|
|
821
|
+
"Provide exactly one selector: a commandId/turnId pair or a clientRef.",
|
|
822
|
+
);
|
|
823
|
+
if (commandId === undefined && clientRef === undefined)
|
|
824
|
+
return this.#error(
|
|
825
|
+
request,
|
|
826
|
+
"invalid_request",
|
|
827
|
+
false,
|
|
828
|
+
"turn.steer_status requires a commandId/turnId pair or a clientRef.",
|
|
829
|
+
);
|
|
830
|
+
if (typeof this.surface.getSteerStatus !== "function")
|
|
831
|
+
return this.#error(request, "unavailable", false, "turn.steer_status is unavailable for this session.");
|
|
832
|
+
return {
|
|
833
|
+
id: request.id,
|
|
834
|
+
ok: true,
|
|
835
|
+
result: await this.surface.getSteerStatus(
|
|
836
|
+
clientRef !== undefined ? { clientRef } : { commandId: commandId!, turnId: turnId! },
|
|
837
|
+
),
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
|
|
782
841
|
#error(request: QueryRequest, code: string, restartQuery = false, message = code, details?: unknown): QueryResponse {
|
|
783
842
|
return {
|
|
784
843
|
id: request.id,
|
|
@@ -57,7 +57,7 @@ interface Outstanding {
|
|
|
57
57
|
export interface ReverseLeaseOptions {
|
|
58
58
|
now?: () => number;
|
|
59
59
|
leaseTtlMs?: number;
|
|
60
|
-
sendFrame: (connectionId: string, frame: SdkFrame) =>
|
|
60
|
+
sendFrame: (connectionId: string, frame: SdkFrame) => unknown;
|
|
61
61
|
installDefinitions?: (capability: string, definitions: unknown) => void;
|
|
62
62
|
onCancel?: (requestId: string, reason: "provider_disconnected" | "lease_released") => void;
|
|
63
63
|
onDefinitionsRemoved?: (capability: string) => void;
|
|
@@ -245,7 +245,7 @@ export class ReverseLeaseRuntime {
|
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
let delivery:
|
|
248
|
+
let delivery: unknown;
|
|
249
249
|
try {
|
|
250
250
|
delivery = this.#sendFrame(lease.connectionId, {
|
|
251
251
|
type: "reverse_request",
|