@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
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { AuthCredentialSelector, CredentialInventoryRecord, CredentialRemovalTarget } from "@gajae-code/ai/core";
|
|
2
|
+
import { getEnvApiKey } from "@gajae-code/ai/core";
|
|
1
3
|
import { getOAuthProviders } from "@gajae-code/ai/utils/oauth";
|
|
2
4
|
import type { OAuthProviderInfo } from "@gajae-code/ai/utils/oauth/types";
|
|
3
5
|
import { Container, fuzzyFilter, Input, matchesKey, Spacer, TruncatedText } from "@gajae-code/tui";
|
|
@@ -10,16 +12,44 @@ import type { ImportableCredential } from "../../setup/credential-import";
|
|
|
10
12
|
import { DynamicBorder } from "./dynamic-border";
|
|
11
13
|
|
|
12
14
|
const OAUTH_SELECTOR_MAX_VISIBLE = 10;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const SAFE_LABEL_MAX_LENGTH = 160;
|
|
16
|
+
|
|
17
|
+
export interface OAuthSelectorAccountOptions {
|
|
18
|
+
accountProviderId?: string;
|
|
19
|
+
onAccountSelect?: (selector: AuthCredentialSelector) => void | Promise<void>;
|
|
20
|
+
onAutoSelect?: () => void | Promise<void>;
|
|
21
|
+
onAddAccount?: () => void | Promise<void>;
|
|
22
|
+
onAccountRemove?: (targets: readonly CredentialRemovalTarget[]) => void | Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type AccountEntry =
|
|
26
|
+
| { kind: "account"; row: CredentialInventoryRecord; target?: CredentialRemovalTarget; selectable: boolean }
|
|
27
|
+
| { kind: "auto"; selectable: true }
|
|
28
|
+
| { kind: "add"; selectable: boolean }
|
|
29
|
+
| { kind: "all"; selectable: boolean };
|
|
30
|
+
|
|
31
|
+
function safeLabel(value: unknown, fallback: string): string {
|
|
32
|
+
if (typeof value !== "string") return fallback;
|
|
33
|
+
const normalized = value
|
|
34
|
+
.replace(/bearer\s+[^\s,;]+/gi, "Bearer [redacted]")
|
|
35
|
+
.replace(/(api[_-]?key|token|secret|authorization)[=:]\s*[^\s,;]+/gi, "$1=[redacted]")
|
|
36
|
+
.replace(/[\u0000-\u001f\u007f]/g, " ")
|
|
37
|
+
.replace(/\s+/g, " ")
|
|
38
|
+
.trim()
|
|
39
|
+
.slice(0, SAFE_LABEL_MAX_LENGTH);
|
|
40
|
+
return normalized || fallback;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Component that renders an OAuth provider selector or a provider-scoped account selector. */
|
|
16
44
|
export class OAuthSelectorComponent extends Container {
|
|
17
45
|
#listContainer: Container;
|
|
18
46
|
#allProviders: OAuthProviderInfo[] = [];
|
|
19
47
|
#sortedProviders: OAuthProviderInfo[] = [];
|
|
20
48
|
#filteredProviders: OAuthProviderInfo[] = [];
|
|
49
|
+
#accountEntries: AccountEntry[] = [];
|
|
50
|
+
#filteredAccountEntries: AccountEntry[] = [];
|
|
21
51
|
#searchInput: Input;
|
|
22
|
-
#selectedIndex
|
|
52
|
+
#selectedIndex = 0;
|
|
23
53
|
#mode: "login" | "logout";
|
|
24
54
|
#authStorage: AuthStorage;
|
|
25
55
|
#onSelectCallback: (providerId: string) => void;
|
|
@@ -29,9 +59,16 @@ export class OAuthSelectorComponent extends Container {
|
|
|
29
59
|
#requestRenderCallback?: () => void;
|
|
30
60
|
#authState: Map<string, "checking" | "valid" | "invalid"> = new Map();
|
|
31
61
|
#externalCredentialCandidates: ImportableCredential[] = [];
|
|
32
|
-
#spinnerFrame
|
|
62
|
+
#spinnerFrame = 0;
|
|
33
63
|
#spinnerInterval?: NodeJS.Timeout;
|
|
34
|
-
#validationGeneration
|
|
64
|
+
#validationGeneration = 0;
|
|
65
|
+
#accountProviderId?: string;
|
|
66
|
+
#onAccountSelect?: (selector: AuthCredentialSelector) => void | Promise<void>;
|
|
67
|
+
#onAutoSelect?: () => void | Promise<void>;
|
|
68
|
+
#onAddAccount?: () => void | Promise<void>;
|
|
69
|
+
#onAccountRemove?: (targets: readonly CredentialRemovalTarget[]) => void | Promise<void>;
|
|
70
|
+
#pendingAccountRemovalTargets?: readonly CredentialRemovalTarget[];
|
|
71
|
+
|
|
35
72
|
constructor(
|
|
36
73
|
mode: "login" | "logout",
|
|
37
74
|
authStorage: AuthStorage,
|
|
@@ -41,7 +78,7 @@ export class OAuthSelectorComponent extends Container {
|
|
|
41
78
|
validateAuth?: (providerId: string) => Promise<boolean>;
|
|
42
79
|
requestRender?: () => void;
|
|
43
80
|
externalCredentialCandidates?: ImportableCredential[];
|
|
44
|
-
}
|
|
81
|
+
} & Partial<OAuthSelectorAccountOptions>,
|
|
45
82
|
) {
|
|
46
83
|
super();
|
|
47
84
|
this.#mode = mode;
|
|
@@ -51,29 +88,32 @@ export class OAuthSelectorComponent extends Container {
|
|
|
51
88
|
this.#validateAuthCallback = options?.validateAuth;
|
|
52
89
|
this.#requestRenderCallback = options?.requestRender;
|
|
53
90
|
this.#externalCredentialCandidates = options?.externalCredentialCandidates ?? [];
|
|
54
|
-
|
|
55
|
-
this.#
|
|
91
|
+
this.#accountProviderId = options?.accountProviderId;
|
|
92
|
+
this.#onAccountSelect = options?.onAccountSelect;
|
|
93
|
+
this.#onAutoSelect = options?.onAutoSelect;
|
|
94
|
+
this.#onAddAccount = options?.onAddAccount;
|
|
95
|
+
this.#onAccountRemove = options?.onAccountRemove;
|
|
96
|
+
|
|
97
|
+
if (this.#accountProviderId) this.#loadAccountEntries();
|
|
98
|
+
else this.#loadProviders();
|
|
99
|
+
|
|
56
100
|
this.addChild(new DynamicBorder());
|
|
57
101
|
this.addChild(new Spacer(1));
|
|
58
|
-
|
|
59
|
-
|
|
102
|
+
const title = this.#accountProviderId
|
|
103
|
+
? `${mode === "login" ? "Select account to login for" : "Select account to logout from"} ${safeLabel(this.#accountProviderId, "provider")}:`
|
|
104
|
+
: mode === "login"
|
|
105
|
+
? "Select provider to login:"
|
|
106
|
+
: "Select provider to logout:";
|
|
60
107
|
this.addChild(new TruncatedText(theme.bold(title)));
|
|
61
108
|
this.addChild(new Spacer(1));
|
|
62
|
-
// Filter box: the provider list is long enough that arrow-key-only
|
|
63
|
-
// navigation buries entries below the visible window.
|
|
64
109
|
this.#searchInput = new Input();
|
|
65
|
-
this.#searchInput.onSubmit = () =>
|
|
66
|
-
this.#selectCurrentProvider();
|
|
67
|
-
};
|
|
110
|
+
this.#searchInput.onSubmit = () => this.#selectCurrent();
|
|
68
111
|
this.addChild(this.#searchInput);
|
|
69
112
|
this.addChild(new Spacer(1));
|
|
70
|
-
// Create list container
|
|
71
113
|
this.#listContainer = new Container();
|
|
72
114
|
this.addChild(this.#listContainer);
|
|
73
115
|
this.addChild(new Spacer(1));
|
|
74
|
-
// Add bottom border
|
|
75
116
|
this.addChild(new DynamicBorder());
|
|
76
|
-
// Initial render
|
|
77
117
|
this.#updateList();
|
|
78
118
|
this.#startValidation();
|
|
79
119
|
}
|
|
@@ -87,12 +127,47 @@ export class OAuthSelectorComponent extends Container {
|
|
|
87
127
|
this.stopValidation();
|
|
88
128
|
super.dispose();
|
|
89
129
|
}
|
|
130
|
+
|
|
90
131
|
#loadProviders(): void {
|
|
91
132
|
this.#allProviders = getOAuthProviders();
|
|
92
133
|
}
|
|
93
134
|
|
|
135
|
+
#loadAccountEntries(): void {
|
|
136
|
+
const provider = this.#accountProviderId;
|
|
137
|
+
if (!provider) return;
|
|
138
|
+
const inventory = this.#authStorage
|
|
139
|
+
.listCredentialInventory(provider)
|
|
140
|
+
.filter(row => row.provider === provider)
|
|
141
|
+
.sort((left, right) => left.id - right.id);
|
|
142
|
+
const targets = new Map(
|
|
143
|
+
this.#authStorage.listCredentialRemovalTargets(provider).map(target => [target.id, target]),
|
|
144
|
+
);
|
|
145
|
+
const apiKeyOverrideActive =
|
|
146
|
+
this.#authStorage.hasRuntimeApiKey(provider) ||
|
|
147
|
+
this.#authStorage.hasConfigApiKey(provider) ||
|
|
148
|
+
Boolean(getEnvApiKey(provider));
|
|
149
|
+
const rows = inventory.filter(row => this.#mode === "login" || row.credentialKind === "oauth");
|
|
150
|
+
this.#accountEntries = rows.map(row => ({
|
|
151
|
+
kind: "account" as const,
|
|
152
|
+
row,
|
|
153
|
+
target: targets.get(row.id),
|
|
154
|
+
selectable:
|
|
155
|
+
row.credentialKind === "oauth" &&
|
|
156
|
+
!apiKeyOverrideActive &&
|
|
157
|
+
(this.#mode === "login" ? !row.disabled : targets.has(row.id)),
|
|
158
|
+
}));
|
|
159
|
+
if (this.#mode === "login") {
|
|
160
|
+
this.#accountEntries.push(
|
|
161
|
+
{ kind: "auto", selectable: true },
|
|
162
|
+
{ kind: "add", selectable: this.#onAddAccount !== undefined },
|
|
163
|
+
);
|
|
164
|
+
} else if (this.#accountEntries.some(entry => entry.kind === "account" && entry.selectable)) {
|
|
165
|
+
this.#accountEntries.push({ kind: "all", selectable: this.#onAccountRemove !== undefined });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
94
169
|
#startValidation(): void {
|
|
95
|
-
if (!this.#validateAuthCallback) return;
|
|
170
|
+
if (this.#accountProviderId || !this.#validateAuthCallback) return;
|
|
96
171
|
const generation = this.#validationGeneration + 1;
|
|
97
172
|
this.#validationGeneration = generation;
|
|
98
173
|
|
|
@@ -122,17 +197,12 @@ export class OAuthSelectorComponent extends Container {
|
|
|
122
197
|
} catch {
|
|
123
198
|
isValid = false;
|
|
124
199
|
}
|
|
125
|
-
|
|
126
200
|
if (generation !== this.#validationGeneration) return;
|
|
127
201
|
this.#authState.set(providerId, isValid ? "valid" : "invalid");
|
|
128
|
-
// Only record the ordering hint when the credentials validated are still the
|
|
129
|
-
// current ones; a result from a superseded generation must not describe them.
|
|
130
202
|
if (authGeneration === this.#authStorage.getGeneration()) {
|
|
131
203
|
recordProviderAuthHealth(this.#authStorage, providerId, isValid ? "valid" : "invalid");
|
|
132
204
|
}
|
|
133
|
-
if (![...this.#authState.values()].includes("checking"))
|
|
134
|
-
this.#stopSpinner();
|
|
135
|
-
}
|
|
205
|
+
if (![...this.#authState.values()].includes("checking")) this.#stopSpinner();
|
|
136
206
|
this.#updateList();
|
|
137
207
|
this.#requestRenderCallback?.();
|
|
138
208
|
}
|
|
@@ -141,9 +211,7 @@ export class OAuthSelectorComponent extends Container {
|
|
|
141
211
|
if (this.#spinnerInterval) return;
|
|
142
212
|
this.#spinnerInterval = setInterval(() => {
|
|
143
213
|
const frameCount = theme.spinnerFrames.length;
|
|
144
|
-
if (frameCount > 0)
|
|
145
|
-
this.#spinnerFrame = (this.#spinnerFrame + 1) % frameCount;
|
|
146
|
-
}
|
|
214
|
+
if (frameCount > 0) this.#spinnerFrame = (this.#spinnerFrame + 1) % frameCount;
|
|
147
215
|
this.#updateList();
|
|
148
216
|
this.#requestRenderCallback?.();
|
|
149
217
|
}, 80);
|
|
@@ -167,15 +235,70 @@ export class OAuthSelectorComponent extends Container {
|
|
|
167
235
|
const spinner = frameCount > 0 ? theme.spinnerFrames[this.#spinnerFrame % frameCount] : theme.status.pending;
|
|
168
236
|
return theme.fg("warning", ` ${spinner} checking`);
|
|
169
237
|
}
|
|
170
|
-
if (state === "invalid") {
|
|
171
|
-
|
|
238
|
+
if (state === "invalid") return theme.fg("error", ` ${theme.status.error} invalid`);
|
|
239
|
+
if (state === "valid") return theme.fg("success", ` ${theme.status.success} logged in`);
|
|
240
|
+
return this.#authStorage.hasAuth(providerId) ? theme.fg("success", ` ${theme.status.success} logged in`) : "";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
#accountLabel(entry: AccountEntry): string {
|
|
244
|
+
switch (entry.kind) {
|
|
245
|
+
case "auto":
|
|
246
|
+
return "AUTO (ranked)";
|
|
247
|
+
case "add":
|
|
248
|
+
return "Add new account";
|
|
249
|
+
case "all":
|
|
250
|
+
return "Remove all accounts";
|
|
251
|
+
case "account": {
|
|
252
|
+
const identity =
|
|
253
|
+
entry.row.credentialKind === "oauth"
|
|
254
|
+
? safeLabel(entry.row.identityLabel, `OAuth account · row ${entry.row.id}`)
|
|
255
|
+
: `API key · row ${entry.row.id}`;
|
|
256
|
+
const status = entry.row.disabled
|
|
257
|
+
? `disabled${entry.row.disabledCause ? `: ${safeLabel(entry.row.disabledCause, "disabled")}` : ""}`
|
|
258
|
+
: "active";
|
|
259
|
+
return `${identity} (${status})`;
|
|
260
|
+
}
|
|
172
261
|
}
|
|
173
|
-
|
|
174
|
-
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
#clearPendingAccountRemoval(): boolean {
|
|
265
|
+
if (this.#pendingAccountRemovalTargets === undefined) return false;
|
|
266
|
+
this.#pendingAccountRemovalTargets = undefined;
|
|
267
|
+
this.#statusMessage = undefined;
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
#getAccountRemovalTargets(): CredentialRemovalTarget[] {
|
|
272
|
+
return this.#accountEntries
|
|
273
|
+
.filter(
|
|
274
|
+
(entry): entry is Extract<AccountEntry, { kind: "account" }> =>
|
|
275
|
+
entry.kind === "account" && entry.selectable && entry.target !== undefined,
|
|
276
|
+
)
|
|
277
|
+
.map(entry => entry.target as CredentialRemovalTarget);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
#confirmOrArmAccountRemoval(targets: readonly CredentialRemovalTarget[], prompt: string): void {
|
|
281
|
+
if (this.#pendingAccountRemovalTargets !== undefined) {
|
|
282
|
+
const pending = this.#pendingAccountRemovalTargets;
|
|
283
|
+
this.#pendingAccountRemovalTargets = undefined;
|
|
284
|
+
this.#statusMessage = undefined;
|
|
285
|
+
void this.#onAccountRemove?.(pending);
|
|
286
|
+
return;
|
|
175
287
|
}
|
|
176
|
-
|
|
288
|
+
if (targets.length === 0) {
|
|
289
|
+
this.#statusMessage = "No accounts available to remove.";
|
|
290
|
+
} else {
|
|
291
|
+
this.#pendingAccountRemovalTargets = targets;
|
|
292
|
+
this.#statusMessage = `${prompt} Enter to confirm, Esc to cancel`;
|
|
293
|
+
}
|
|
294
|
+
this.#updateList();
|
|
177
295
|
}
|
|
178
296
|
#updateList(): void {
|
|
297
|
+
if (this.#accountProviderId) {
|
|
298
|
+
this.#updateAccountList();
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
|
|
179
302
|
const selectedProviderId = this.#filteredProviders[this.#selectedIndex]?.id;
|
|
180
303
|
const rankedProviders = this.#allProviders.map(provider => ({
|
|
181
304
|
provider,
|
|
@@ -185,8 +308,6 @@ export class OAuthSelectorComponent extends Container {
|
|
|
185
308
|
}));
|
|
186
309
|
rankedProviders.sort(compareRankedProviders);
|
|
187
310
|
this.#sortedProviders = rankedProviders.map(({ provider }) => provider);
|
|
188
|
-
// Filter after ranking so an empty query preserves the curated order and a
|
|
189
|
-
// query still surfaces matches in that same order of preference.
|
|
190
311
|
this.#filteredProviders = fuzzyFilter(
|
|
191
312
|
this.#sortedProviders,
|
|
192
313
|
this.#searchInput.getValue(),
|
|
@@ -208,33 +329,25 @@ export class OAuthSelectorComponent extends Container {
|
|
|
208
329
|
? 0
|
|
209
330
|
: Math.max(0, Math.min(this.#selectedIndex - Math.floor(maxVisible / 2), total - maxVisible));
|
|
210
331
|
const endIndex = Math.min(startIndex + maxVisible, total);
|
|
211
|
-
|
|
212
332
|
for (let i = startIndex; i < endIndex; i++) {
|
|
213
333
|
const provider = this.#filteredProviders[i];
|
|
214
334
|
if (!provider) continue;
|
|
215
335
|
const isSelected = i === this.#selectedIndex;
|
|
216
336
|
const isAvailable = provider.available;
|
|
217
337
|
const statusIndicator = this.#getStatusIndicator(provider.id);
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const text = isAvailable ? ` ${provider.name}` : theme.fg("dim", ` ${provider.name}`);
|
|
226
|
-
line = text + statusIndicator;
|
|
227
|
-
}
|
|
228
|
-
this.#listContainer.addChild(new TruncatedText(line, 0, 0));
|
|
338
|
+
const prefix = isSelected ? theme.fg("accent", `${theme.nav.cursor} `) : " ";
|
|
339
|
+
const text = isAvailable
|
|
340
|
+
? isSelected
|
|
341
|
+
? theme.fg("accent", provider.name)
|
|
342
|
+
: provider.name
|
|
343
|
+
: theme.fg("dim", provider.name);
|
|
344
|
+
this.#listContainer.addChild(new TruncatedText(prefix + text + statusIndicator, 0, 0));
|
|
229
345
|
}
|
|
230
|
-
|
|
231
|
-
// Scroll indicator when list is windowed
|
|
232
346
|
if (startIndex > 0 || endIndex < total) {
|
|
233
|
-
|
|
234
|
-
|
|
347
|
+
this.#listContainer.addChild(
|
|
348
|
+
new TruncatedText(theme.fg("muted", ` (${this.#selectedIndex + 1}/${total})`), 0, 0),
|
|
349
|
+
);
|
|
235
350
|
}
|
|
236
|
-
|
|
237
|
-
// Show "no providers" if empty
|
|
238
351
|
if (total === 0) {
|
|
239
352
|
const message = this.#searchInput.getValue().trim()
|
|
240
353
|
? "No providers match the filter"
|
|
@@ -245,7 +358,13 @@ export class OAuthSelectorComponent extends Container {
|
|
|
245
358
|
}
|
|
246
359
|
if (this.#statusMessage) {
|
|
247
360
|
this.#listContainer.addChild(new Spacer(1));
|
|
248
|
-
this.#listContainer.addChild(
|
|
361
|
+
this.#listContainer.addChild(
|
|
362
|
+
new TruncatedText(
|
|
363
|
+
theme.fg("warning", ` ${safeLabel(this.#statusMessage, "Unable to select provider")}`),
|
|
364
|
+
0,
|
|
365
|
+
0,
|
|
366
|
+
),
|
|
367
|
+
);
|
|
249
368
|
}
|
|
250
369
|
if (this.#mode === "login" && this.#externalCredentialCandidates.length > 0) {
|
|
251
370
|
this.#listContainer.addChild(new Spacer(1));
|
|
@@ -254,7 +373,7 @@ export class OAuthSelectorComponent extends Container {
|
|
|
254
373
|
new TruncatedText(
|
|
255
374
|
theme.fg(
|
|
256
375
|
"success",
|
|
257
|
-
` ${theme.status.success} Imported ${credential.provider} from ${credential.source}`,
|
|
376
|
+
` ${theme.status.success} Imported ${safeLabel(credential.provider, "provider")} from ${safeLabel(credential.source, "external source")}`,
|
|
258
377
|
),
|
|
259
378
|
0,
|
|
260
379
|
0,
|
|
@@ -263,7 +382,88 @@ export class OAuthSelectorComponent extends Container {
|
|
|
263
382
|
}
|
|
264
383
|
}
|
|
265
384
|
}
|
|
266
|
-
|
|
385
|
+
|
|
386
|
+
#updateAccountList(): void {
|
|
387
|
+
const query = this.#searchInput.getValue().trim().toLowerCase();
|
|
388
|
+
this.#filteredAccountEntries = this.#accountEntries.filter(entry =>
|
|
389
|
+
this.#accountLabel(entry).toLowerCase().includes(query),
|
|
390
|
+
);
|
|
391
|
+
if (this.#selectedIndex >= this.#filteredAccountEntries.length) {
|
|
392
|
+
this.#selectedIndex = Math.max(0, this.#filteredAccountEntries.length - 1);
|
|
393
|
+
}
|
|
394
|
+
this.#listContainer.clear();
|
|
395
|
+
const total = this.#filteredAccountEntries.length;
|
|
396
|
+
const maxVisible = OAUTH_SELECTOR_MAX_VISIBLE;
|
|
397
|
+
const startIndex =
|
|
398
|
+
total <= maxVisible
|
|
399
|
+
? 0
|
|
400
|
+
: Math.max(0, Math.min(this.#selectedIndex - Math.floor(maxVisible / 2), total - maxVisible));
|
|
401
|
+
const endIndex = Math.min(startIndex + maxVisible, total);
|
|
402
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
403
|
+
const entry = this.#filteredAccountEntries[i];
|
|
404
|
+
if (!entry) continue;
|
|
405
|
+
const selected = i === this.#selectedIndex;
|
|
406
|
+
const prefix = selected ? theme.fg("accent", `${theme.nav.cursor} `) : " ";
|
|
407
|
+
const label = this.#accountLabel(entry);
|
|
408
|
+
const disabled = !entry.selectable;
|
|
409
|
+
const text = disabled ? theme.fg("dim", label) : selected ? theme.fg("accent", label) : label;
|
|
410
|
+
this.#listContainer.addChild(new TruncatedText(prefix + text, 0, 0));
|
|
411
|
+
}
|
|
412
|
+
if (startIndex > 0 || endIndex < total) {
|
|
413
|
+
this.#listContainer.addChild(
|
|
414
|
+
new TruncatedText(theme.fg("muted", ` (${this.#selectedIndex + 1}/${total})`), 0, 0),
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
if (total === 0) {
|
|
418
|
+
this.#listContainer.addChild(new TruncatedText(theme.fg("muted", " No accounts available"), 0, 0));
|
|
419
|
+
}
|
|
420
|
+
if (this.#statusMessage) {
|
|
421
|
+
this.#listContainer.addChild(new Spacer(1));
|
|
422
|
+
this.#listContainer.addChild(
|
|
423
|
+
new TruncatedText(
|
|
424
|
+
theme.fg("warning", ` ${safeLabel(this.#statusMessage, "Unable to select account")}`),
|
|
425
|
+
0,
|
|
426
|
+
0,
|
|
427
|
+
),
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
#selectCurrent(): void {
|
|
433
|
+
if (this.#accountProviderId) {
|
|
434
|
+
const selected = this.#filteredAccountEntries[this.#selectedIndex];
|
|
435
|
+
if (!selected) return;
|
|
436
|
+
if (!selected.selectable) {
|
|
437
|
+
this.#statusMessage = "This account is not selectable.";
|
|
438
|
+
this.#updateList();
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
this.#statusMessage = undefined;
|
|
442
|
+
this.stopValidation();
|
|
443
|
+
if (selected.kind === "account") {
|
|
444
|
+
if (selected.row.credentialKind !== "oauth") return;
|
|
445
|
+
if (this.#mode === "login") {
|
|
446
|
+
void this.#onAccountSelect?.({ kind: "id", value: String(selected.row.id) });
|
|
447
|
+
} else if (selected.target) {
|
|
448
|
+
this.#confirmOrArmAccountRemoval([selected.target], "Remove this account?");
|
|
449
|
+
}
|
|
450
|
+
} else if (selected.kind === "auto") {
|
|
451
|
+
void this.#onAutoSelect?.();
|
|
452
|
+
} else if (selected.kind === "add") {
|
|
453
|
+
void this.#onAddAccount?.();
|
|
454
|
+
} else if (selected.kind === "all") {
|
|
455
|
+
if (this.#pendingAccountRemovalTargets !== undefined) {
|
|
456
|
+
const targets = this.#pendingAccountRemovalTargets;
|
|
457
|
+
this.#pendingAccountRemovalTargets = undefined;
|
|
458
|
+
void this.#onAccountRemove?.(targets);
|
|
459
|
+
} else {
|
|
460
|
+
const targets = this.#getAccountRemovalTargets();
|
|
461
|
+
this.#confirmOrArmAccountRemoval(targets, `Remove all ${targets.length} accounts?`);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
267
467
|
const selectedProvider = this.#filteredProviders[this.#selectedIndex];
|
|
268
468
|
if (selectedProvider?.available) {
|
|
269
469
|
this.#statusMessage = undefined;
|
|
@@ -274,64 +474,55 @@ export class OAuthSelectorComponent extends Container {
|
|
|
274
474
|
this.#updateList();
|
|
275
475
|
}
|
|
276
476
|
}
|
|
477
|
+
|
|
277
478
|
handleInput(keyData: string): void {
|
|
278
|
-
|
|
479
|
+
const isConfirm = matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n";
|
|
480
|
+
const isCancel = matchesSelectCancel(keyData);
|
|
481
|
+
const pendingConfirmationCleared = !isConfirm && !isCancel ? this.#clearPendingAccountRemoval() : false;
|
|
482
|
+
const itemCount = this.#accountProviderId ? this.#filteredAccountEntries.length : this.#filteredProviders.length;
|
|
279
483
|
if (matchesKey(keyData, "up")) {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
this.#selectedIndex === 0 ? this.#filteredProviders.length - 1 : this.#selectedIndex - 1;
|
|
283
|
-
}
|
|
484
|
+
this.#clearPendingAccountRemoval();
|
|
485
|
+
if (itemCount > 0) this.#selectedIndex = this.#selectedIndex === 0 ? itemCount - 1 : this.#selectedIndex - 1;
|
|
284
486
|
this.#statusMessage = undefined;
|
|
285
487
|
this.#updateList();
|
|
286
488
|
return;
|
|
287
489
|
}
|
|
288
|
-
// Down arrow
|
|
289
490
|
if (matchesKey(keyData, "down")) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
this.#selectedIndex === this.#filteredProviders.length - 1 ? 0 : this.#selectedIndex + 1;
|
|
293
|
-
}
|
|
491
|
+
this.#clearPendingAccountRemoval();
|
|
492
|
+
if (itemCount > 0) this.#selectedIndex = this.#selectedIndex === itemCount - 1 ? 0 : this.#selectedIndex + 1;
|
|
294
493
|
this.#statusMessage = undefined;
|
|
295
494
|
this.#updateList();
|
|
296
495
|
return;
|
|
297
496
|
}
|
|
298
|
-
// Page up - jump up by one visible page
|
|
299
497
|
if (matchesKey(keyData, "pageUp")) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
498
|
+
this.#clearPendingAccountRemoval();
|
|
499
|
+
if (itemCount > 0) this.#selectedIndex = Math.max(0, this.#selectedIndex - OAUTH_SELECTOR_MAX_VISIBLE);
|
|
303
500
|
this.#statusMessage = undefined;
|
|
304
501
|
this.#updateList();
|
|
305
502
|
return;
|
|
306
503
|
}
|
|
307
|
-
// Page down - jump down by one visible page
|
|
308
504
|
if (matchesKey(keyData, "pageDown")) {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this.#selectedIndex + OAUTH_SELECTOR_MAX_VISIBLE,
|
|
313
|
-
);
|
|
314
|
-
}
|
|
505
|
+
this.#clearPendingAccountRemoval();
|
|
506
|
+
if (itemCount > 0)
|
|
507
|
+
this.#selectedIndex = Math.min(itemCount - 1, this.#selectedIndex + OAUTH_SELECTOR_MAX_VISIBLE);
|
|
315
508
|
this.#statusMessage = undefined;
|
|
316
509
|
this.#updateList();
|
|
317
510
|
return;
|
|
318
511
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
this.#selectCurrentProvider();
|
|
512
|
+
if (isConfirm) {
|
|
513
|
+
this.#selectCurrent();
|
|
322
514
|
return;
|
|
323
515
|
}
|
|
324
|
-
|
|
325
|
-
|
|
516
|
+
if (isCancel) {
|
|
517
|
+
const pending = this.#clearPendingAccountRemoval();
|
|
326
518
|
this.stopValidation();
|
|
519
|
+
if (pending) this.#updateList();
|
|
327
520
|
this.#onCancelCallback();
|
|
328
521
|
return;
|
|
329
522
|
}
|
|
330
|
-
// Everything else edits the filter. A changed query invalidates the current
|
|
331
|
-
// position, so selection restarts at the best match.
|
|
332
523
|
const previousQuery = this.#searchInput.getValue();
|
|
333
524
|
this.#searchInput.handleInput(keyData);
|
|
334
|
-
if (this.#searchInput.getValue() !== previousQuery) {
|
|
525
|
+
if (pendingConfirmationCleared || this.#searchInput.getValue() !== previousQuery) {
|
|
335
526
|
this.#selectedIndex = 0;
|
|
336
527
|
this.#statusMessage = undefined;
|
|
337
528
|
this.#updateList();
|
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
shouldProbeSixelCapability,
|
|
7
7
|
TERMINAL,
|
|
8
8
|
} from "@gajae-code/tui";
|
|
9
|
+
import type { PetTransportAvailability } from "./iterm-pet-transport";
|
|
9
10
|
|
|
10
|
-
export type PetPixelProtocol = "sixel" | "kitty";
|
|
11
|
+
export type PetPixelProtocol = "sixel" | "kitty" | "iterm";
|
|
11
12
|
|
|
12
13
|
export const PET_UNAVAILABLE_DESCRIPTION = "Unavailable: requires compatible Kitty or Sixel overlay rendering";
|
|
13
14
|
export const PET_SAVED_UNAVAILABLE_DESCRIPTION =
|
|
@@ -21,9 +22,34 @@ export function getPetUnavailableWarning(env: NodeJS.ProcessEnv = Bun.env): stri
|
|
|
21
22
|
return isUnderTerminalMultiplexer(env) ? PET_MULTIPLEXER_UNAVAILABLE_WARNING : PET_UNAVAILABLE_WARNING;
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
let latestItermAvailability: PetTransportAvailability | undefined;
|
|
26
|
+
let verifiedItermAvailability: PetTransportAvailability | undefined;
|
|
27
|
+
const verifiedItermListeners = new Set<(availability: PetTransportAvailability | undefined) => void>();
|
|
28
|
+
export function subscribeVerifiedItermPetAvailability(
|
|
29
|
+
callback: (availability: PetTransportAvailability | undefined) => void,
|
|
30
|
+
): () => void {
|
|
31
|
+
verifiedItermListeners.add(callback);
|
|
32
|
+
return () => verifiedItermListeners.delete(callback);
|
|
33
|
+
}
|
|
34
|
+
export function setVerifiedItermPetAvailability(availability: PetTransportAvailability | undefined): void {
|
|
35
|
+
latestItermAvailability = availability;
|
|
36
|
+
verifiedItermAvailability = availability?.available ? availability : undefined;
|
|
37
|
+
for (const listener of verifiedItermListeners) listener(verifiedItermAvailability);
|
|
38
|
+
}
|
|
39
|
+
export function getItermPetAvailability(): PetTransportAvailability | undefined {
|
|
40
|
+
return latestItermAvailability;
|
|
41
|
+
}
|
|
42
|
+
export function getVerifiedItermPetAvailability(): PetTransportAvailability | undefined {
|
|
43
|
+
return verifiedItermAvailability;
|
|
44
|
+
}
|
|
45
|
+
export function getItermPetUnavailableReason(): string | undefined {
|
|
46
|
+
return latestItermAvailability?.available ? undefined : latestItermAvailability?.reason;
|
|
47
|
+
}
|
|
48
|
+
|
|
24
49
|
export function getPetPixelProtocol(): PetPixelProtocol | null {
|
|
25
|
-
if (TERMINAL.imageProtocol === ImageProtocol.Kitty) return "kitty";
|
|
50
|
+
if (TERMINAL.imageProtocol === ImageProtocol.Kitty && !isUnderTerminalMultiplexer()) return "kitty";
|
|
26
51
|
if (TERMINAL.imageProtocol === ImageProtocol.Sixel) return "sixel";
|
|
52
|
+
if (verifiedItermAvailability?.available) return "iterm";
|
|
27
53
|
return null;
|
|
28
54
|
}
|
|
29
55
|
|
|
@@ -41,31 +67,13 @@ export function createPetSelectItems(
|
|
|
41
67
|
const current = option.value === currentValue;
|
|
42
68
|
const savedUnavailable = disabled && current;
|
|
43
69
|
let description = `${option.description ?? ""}${current ? " (current)" : ""}`;
|
|
44
|
-
if (disabled)
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
...option,
|
|
49
|
-
label: savedUnavailable ? `${option.label} (saved)` : option.label,
|
|
50
|
-
description,
|
|
51
|
-
disabled,
|
|
52
|
-
};
|
|
70
|
+
if (disabled) description = savedUnavailable ? PET_SAVED_UNAVAILABLE_DESCRIPTION : PET_UNAVAILABLE_DESCRIPTION;
|
|
71
|
+
return { ...option, label: savedUnavailable ? `${option.label} (saved)` : option.label, description, disabled };
|
|
53
72
|
});
|
|
54
73
|
}
|
|
55
74
|
|
|
56
|
-
/**
|
|
57
|
-
* Grace period before declaring the terminal pet-incapable at startup. The
|
|
58
|
-
* asynchronous Sixel capability probe starts inside `TUI.start()` and answers
|
|
59
|
-
* within its own 250 ms deadline; this margin covers probe scheduling so a
|
|
60
|
-
* supported terminal is never told it is incompatible while the probe is
|
|
61
|
-
* still in flight.
|
|
62
|
-
*/
|
|
63
75
|
export const PET_CAPABILITY_SETTLE_MS = 1_000;
|
|
64
76
|
|
|
65
|
-
/**
|
|
66
|
-
* Whether the asynchronous startup Sixel capability probe may still enable
|
|
67
|
-
* graphics for this session, meaning current unavailability is not final.
|
|
68
|
-
*/
|
|
69
77
|
export function isPetCapabilityProbePending(
|
|
70
78
|
env: NodeJS.ProcessEnv = Bun.env,
|
|
71
79
|
platform: NodeJS.Platform = process.platform,
|
|
@@ -75,15 +83,6 @@ export function isPetCapabilityProbePending(
|
|
|
75
83
|
return shouldProbeSixelCapability(env, platform);
|
|
76
84
|
}
|
|
77
85
|
|
|
78
|
-
/**
|
|
79
|
-
* Deliver the pet-unavailable startup warning only once the capability
|
|
80
|
-
* question is settled. With no probe pending, unavailability is final and
|
|
81
|
-
* `onUnavailable` fires immediately. While a probe may still enable
|
|
82
|
-
* graphics, the warning is deferred: a protocol-change event cancels it (the
|
|
83
|
-
* saved pet re-applies through the existing subscription), and only the
|
|
84
|
-
* settle deadline passing with the terminal still unavailable emits it.
|
|
85
|
-
* Returns a disposer that cancels the pending decision.
|
|
86
|
-
*/
|
|
87
86
|
export function warnWhenPetCapabilitySettled(options: {
|
|
88
87
|
probePending: boolean;
|
|
89
88
|
isAvailable?: () => boolean;
|
|
@@ -96,16 +95,21 @@ export function warnWhenPetCapabilitySettled(options: {
|
|
|
96
95
|
}
|
|
97
96
|
const isAvailable = options.isAvailable ?? isPetAvailable;
|
|
98
97
|
let settled = false;
|
|
98
|
+
let unsubscribeIterm = () => {};
|
|
99
99
|
const finish = () => {
|
|
100
100
|
if (settled) return;
|
|
101
101
|
settled = true;
|
|
102
102
|
clearTimeout(timer);
|
|
103
103
|
unsubscribe();
|
|
104
|
+
unsubscribeIterm();
|
|
104
105
|
};
|
|
105
106
|
const unsubscribe = onImageProtocolChanged(protocol => {
|
|
106
107
|
if (!protocol) return;
|
|
107
108
|
finish();
|
|
108
109
|
});
|
|
110
|
+
unsubscribeIterm = subscribeVerifiedItermPetAvailability(availability => {
|
|
111
|
+
if (availability?.available) finish();
|
|
112
|
+
});
|
|
109
113
|
const timer = setTimeout(() => {
|
|
110
114
|
finish();
|
|
111
115
|
if (!isAvailable()) options.onUnavailable();
|