@gajae-code/coding-agent 0.10.1 → 0.11.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 +70 -2
- package/dist/types/append-only-mode.d.ts +1 -1
- package/dist/types/cli/args.d.ts +4 -5
- package/dist/types/cli/daemon-cli.d.ts +12 -1
- package/dist/types/cli/notify-cli.d.ts +21 -1
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +39 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/commands/notify.d.ts +28 -1
- package/dist/types/commands/sdk.d.ts +33 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
- package/dist/types/config/model-profile-activation.d.ts +35 -15
- package/dist/types/config/model-profiles.d.ts +11 -5
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/model-resolver.d.ts +39 -6
- package/dist/types/config/model-selector-value.d.ts +17 -0
- package/dist/types/config/models-config-schema.d.ts +10 -6
- package/dist/types/config/settings-schema.d.ts +133 -6
- package/dist/types/config/settings.d.ts +63 -35
- package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
- package/dist/types/coordinator-mcp/server.d.ts +6 -49
- package/dist/types/daemon/builtin.d.ts +6 -5
- package/dist/types/daemon/control-types.d.ts +1 -1
- package/dist/types/discovery/mcp-json.d.ts +12 -1
- package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
- package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
- package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +10 -1
- package/dist/types/extensibility/extensions/runner.d.ts +3 -3
- package/dist/types/extensibility/extensions/types.d.ts +141 -16
- package/dist/types/extensibility/hooks/types.d.ts +1 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
- package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
- package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
- package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
- package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
- package/dist/types/harness-control-plane/operate.d.ts +5 -5
- package/dist/types/harness-control-plane/owner.d.ts +18 -4
- package/dist/types/harness-control-plane/receipts.d.ts +0 -1
- package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
- package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
- package/dist/types/harness-control-plane/types.d.ts +3 -4
- package/dist/types/lsp/index.d.ts +1 -1
- package/dist/types/main.d.ts +32 -38
- package/dist/types/modes/acp/acp-agent.d.ts +224 -53
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
- package/dist/types/modes/acp/acp-mode.d.ts +6 -15
- package/dist/types/modes/acp/permission-mode.d.ts +4 -0
- package/dist/types/modes/acp/startup-options.d.ts +6 -0
- package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +1 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
- package/dist/types/modes/components/pet-capability.d.ts +37 -0
- package/dist/types/modes/components/pet-selector.d.ts +1 -1
- package/dist/types/modes/components/settings-selector.d.ts +15 -4
- package/dist/types/modes/components/welcome.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
- package/dist/types/modes/index.d.ts +0 -4
- package/dist/types/modes/interactive-mode.d.ts +5 -1
- package/dist/types/modes/runtime-init.d.ts +2 -2
- package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
- package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
- package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
- package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
- package/dist/types/modes/types.d.ts +16 -1
- package/dist/types/runtime-mcp/client.d.ts +2 -0
- package/dist/types/runtime-mcp/config.d.ts +5 -1
- package/dist/types/runtime-mcp/manager.d.ts +8 -1
- package/dist/types/runtime-mcp/types.d.ts +4 -0
- package/dist/types/sdk/acp/adapter.d.ts +67 -0
- package/dist/types/sdk/acp/index.d.ts +2 -0
- package/dist/types/sdk/broker/broker.d.ts +53 -0
- package/dist/types/sdk/broker/discovery.d.ts +30 -0
- package/dist/types/sdk/broker/ensure.d.ts +33 -0
- package/dist/types/sdk/broker/identity.d.ts +3 -0
- package/dist/types/sdk/broker/index.d.ts +8 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
- package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
- package/dist/types/sdk/broker/runtime.d.ts +33 -0
- package/dist/types/sdk/broker/session-index.d.ts +57 -0
- package/dist/types/sdk/broker/state-version.d.ts +8 -0
- package/dist/types/sdk/broker/transport.d.ts +9 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
- package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
- package/dist/types/sdk/bus/config.d.ts +274 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
- package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
- package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
- package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
- package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
- package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
- package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
- package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
- package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
- package/dist/types/sdk/bus/session-control.d.ts +83 -0
- package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
- package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
- package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
- package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
- package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
- package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
- package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
- package/dist/types/sdk/cli/index.d.ts +1 -0
- package/dist/types/sdk/cli/session-cli.d.ts +19 -0
- package/dist/types/sdk/client/client.d.ts +1 -0
- package/dist/types/sdk/client/discovery.d.ts +27 -0
- package/dist/types/sdk/client/index.d.ts +2 -0
- package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
- package/dist/types/sdk/host/control/index.d.ts +2 -0
- package/dist/types/sdk/host/control/operations.d.ts +65 -0
- package/dist/types/sdk/host/events.d.ts +35 -0
- package/dist/types/sdk/host/host.d.ts +35 -0
- package/dist/types/sdk/host/index.d.ts +4 -0
- package/dist/types/sdk/host/query/cursor.d.ts +62 -0
- package/dist/types/sdk/host/query/handlers.d.ts +70 -0
- package/dist/types/sdk/host/query/index.d.ts +3 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
- package/dist/types/sdk/host/types.d.ts +32 -0
- package/dist/types/sdk/index.d.ts +6 -0
- package/dist/types/sdk/lifecycle-session.d.ts +14 -0
- package/dist/types/sdk/mcp/index.d.ts +1 -0
- package/dist/types/sdk/mcp/server.d.ts +37 -0
- package/dist/types/sdk/models.d.ts +44 -0
- package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
- package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
- package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
- package/dist/types/sdk/startup-capability.d.ts +50 -0
- package/dist/types/session/agent-session.d.ts +114 -21
- package/dist/types/session/default-model-selection.d.ts +25 -0
- package/dist/types/session/fallback-chain-controller.d.ts +52 -0
- package/dist/types/session/session-manager.d.ts +58 -1
- package/dist/types/setup/credential-auto-import.d.ts +36 -6
- package/dist/types/tools/ask-answer-registry.d.ts +1 -1
- package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
- package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
- package/dist/types/tools/browser/launch.d.ts +22 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
- package/dist/types/tools/browser/profile-posture.d.ts +37 -0
- package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
- package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
- package/dist/types/tools/browser/registry.d.ts +19 -0
- package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
- package/dist/types/tools/index.d.ts +8 -8
- package/package.json +34 -13
- package/scripts/build-sdk-package-smoke.ts +94 -0
- package/scripts/capture-notifications-settings-showcase.ts +435 -0
- package/scripts/compile-args.ts +4 -2
- package/scripts/g005-daemon-smoke.ts +4 -5
- package/scripts/g011-daemon-path-smoke.ts +5 -5
- package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
- package/scripts/generate-sdk-operation-inventory.ts +867 -0
- package/scripts/generate-telegram-baseline-manifest.ts +128 -0
- package/scripts/manifest-schema.ts +124 -0
- package/scripts/run-test-manifest.ts +153 -0
- package/scripts/run-threat-model-check.ts +157 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
- package/scripts/verify-gjc-sdk-rename.ts +90 -0
- package/src/append-only-mode.ts +1 -1
- package/src/cli/args.ts +43 -12
- package/src/cli/auth-gateway-cli.ts +2 -2
- package/src/cli/config-cli.ts +2 -1
- package/src/cli/daemon-cli.ts +63 -14
- package/src/cli/list-models.ts +1 -1
- package/src/cli/notify-cli.ts +288 -286
- package/src/cli.ts +21 -2
- package/src/commands/daemon.ts +50 -6
- package/src/commands/harness.ts +93 -36
- package/src/commands/launch.ts +5 -2
- package/src/commands/mcp-serve.ts +19 -12
- package/src/commands/notify.ts +36 -3
- package/src/commands/sdk.ts +426 -0
- package/src/commit/agentic/agent.ts +1 -0
- package/src/config/atomic-yaml-patch.ts +423 -0
- package/src/config/model-profile-activation.ts +240 -89
- package/src/config/model-profiles.ts +37 -34
- package/src/config/model-registry.ts +51 -26
- package/src/config/model-resolver.ts +138 -51
- package/src/config/model-selector-value.ts +50 -0
- package/src/config/models-config-schema.ts +14 -21
- package/src/config/settings-schema.ts +128 -10
- package/src/config/settings.ts +1120 -158
- package/src/coordinator-mcp/model-preset.ts +74 -20
- package/src/coordinator-mcp/server.ts +1597 -3052
- package/src/daemon/builtin.ts +8 -5
- package/src/daemon/control-types.ts +1 -1
- package/src/defaults/gjc/skills/team/SKILL.md +4 -4
- package/src/discovery/mcp-json.ts +327 -20
- package/src/extensibility/custom-tools/types.ts +1 -1
- package/src/extensibility/extensions/compact-handler.ts +3 -3
- package/src/extensibility/extensions/get-commands-handler.ts +2 -2
- package/src/extensibility/extensions/loader.ts +69 -5
- package/src/extensibility/extensions/runner.ts +112 -4
- package/src/extensibility/extensions/types.ts +176 -17
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/extensibility/slash-commands.ts +3 -3
- package/src/gjc-runtime/launch-tmux.ts +170 -86
- package/src/gjc-runtime/psmux-detect.ts +82 -4
- package/src/gjc-runtime/session-state-sidecar.ts +41 -31
- package/src/gjc-runtime/team-runtime.ts +54 -35
- package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -2
- package/src/gjc-runtime/tmux-sessions.ts +19 -13
- package/src/gjc-runtime/ultragoal-guard.ts +53 -6
- package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
- package/src/gjc-runtime/windows-powershell-command.ts +58 -0
- package/src/harness-control-plane/operate.ts +9 -9
- package/src/harness-control-plane/owner.ts +283 -39
- package/src/harness-control-plane/receipts.ts +0 -1
- package/src/harness-control-plane/sdk-transport.ts +395 -0
- package/src/harness-control-plane/session-transport.ts +94 -0
- package/src/harness-control-plane/types.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +36 -37
- package/src/lsp/client.ts +42 -6
- package/src/lsp/index.ts +2 -2
- package/src/main.ts +299 -204
- package/src/modes/DESIGN.md +258 -0
- package/src/modes/acp/acp-agent.ts +1228 -2612
- package/src/modes/acp/acp-client-bridge.ts +2 -20
- package/src/modes/acp/acp-event-mapper.ts +18 -2
- package/src/modes/acp/acp-mode.ts +8 -36
- package/src/modes/acp/permission-mode.ts +25 -0
- package/src/modes/acp/startup-options.ts +6 -0
- package/src/modes/components/agent-dashboard.ts +37 -17
- package/src/modes/components/custom-editor.ts +1 -0
- package/src/modes/components/gajae-pet-widget.ts +169 -20
- package/src/modes/components/model-selector.ts +93 -35
- package/src/modes/components/notifications-settings-editor.ts +1379 -0
- package/src/modes/components/pet-capability.ts +115 -0
- package/src/modes/components/pet-selector.ts +4 -6
- package/src/modes/components/settings-selector.ts +86 -11
- package/src/modes/components/welcome.ts +4 -4
- package/src/modes/controllers/command-controller.ts +1 -2
- package/src/modes/controllers/event-controller.ts +11 -16
- package/src/modes/controllers/extension-ui-controller.ts +357 -12
- package/src/modes/controllers/input-controller.ts +43 -13
- package/src/modes/controllers/selector-controller.ts +671 -44
- package/src/modes/index.ts +0 -22
- package/src/modes/interactive-mode.ts +108 -24
- package/src/modes/runtime-init.ts +298 -6
- package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
- package/src/modes/shared/agent-wire/event-contract.ts +7 -8
- package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
- package/src/modes/shared/agent-wire/event-observation.ts +16 -7
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
- package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
- package/src/modes/types.ts +16 -1
- package/src/runtime-mcp/client.ts +94 -19
- package/src/runtime-mcp/config.ts +27 -15
- package/src/runtime-mcp/manager.ts +343 -105
- package/src/runtime-mcp/oauth-flow.ts +42 -12
- package/src/runtime-mcp/transports/http.ts +49 -19
- package/src/runtime-mcp/transports/stdio.ts +47 -28
- package/src/runtime-mcp/types.ts +10 -0
- package/src/sdk/acp/adapter.ts +418 -0
- package/src/sdk/acp/index.ts +2 -0
- package/src/sdk/broker/broker.ts +642 -0
- package/src/sdk/broker/discovery.ts +94 -0
- package/src/sdk/broker/ensure.ts +249 -0
- package/src/sdk/broker/identity.ts +42 -0
- package/src/sdk/broker/index.ts +8 -0
- package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
- package/src/sdk/broker/internal-source.bunfig.toml +1 -0
- package/src/sdk/broker/lifecycle-ledger.ts +286 -0
- package/src/sdk/broker/lifecycle.ts +2157 -0
- package/src/sdk/broker/process-incarnation.ts +159 -0
- package/src/sdk/broker/runtime.ts +164 -0
- package/src/sdk/broker/session-index.ts +318 -0
- package/src/sdk/broker/state-version.ts +23 -0
- package/src/sdk/broker/transport.ts +125 -0
- package/src/sdk/bus/chat-command-policy.ts +107 -0
- package/src/sdk/bus/chat-daemon-cli.ts +214 -0
- package/src/sdk/bus/chat-daemon-control.ts +713 -0
- package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
- package/src/sdk/bus/chat-effect-journal.ts +353 -0
- package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
- package/src/sdk/bus/config.ts +433 -0
- package/src/sdk/bus/conversation-store.ts +391 -0
- package/src/sdk/bus/discord-conversation.ts +85 -0
- package/src/sdk/bus/discord-daemon.ts +2275 -0
- package/src/sdk/bus/discord-live-provider.ts +521 -0
- package/src/sdk/bus/discord-provider.ts +56 -0
- package/src/{notifications → sdk/bus}/html-format.ts +2 -2
- package/src/sdk/bus/index.ts +3943 -0
- package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
- package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
- package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
- package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
- package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
- package/src/sdk/bus/natives-augment.d.ts +38 -0
- package/src/sdk/bus/notification-orchestration.ts +535 -0
- package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
- package/src/sdk/bus/session-control.ts +333 -0
- package/src/sdk/bus/slack-conversation.ts +74 -0
- package/src/sdk/bus/slack-daemon.ts +2144 -0
- package/src/sdk/bus/slack-live-provider.ts +380 -0
- package/src/sdk/bus/slack-provider.ts +76 -0
- package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
- package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
- package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
- package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
- package/src/sdk/bus/telegram-setup.ts +663 -0
- package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
- package/src/sdk/cli/index.ts +1 -0
- package/src/sdk/cli/session-cli.ts +275 -0
- package/src/sdk/client/client.ts +1 -0
- package/src/sdk/client/discovery.ts +108 -0
- package/src/sdk/client/index.ts +2 -0
- package/src/sdk/host/control/dispatch.ts +367 -0
- package/src/sdk/host/control/index.ts +10 -0
- package/src/sdk/host/control/operations.ts +63 -0
- package/src/sdk/host/events.ts +91 -0
- package/src/sdk/host/host.ts +296 -0
- package/src/sdk/host/index.ts +4 -0
- package/src/sdk/host/query/cursor.ts +189 -0
- package/src/sdk/host/query/handlers.ts +533 -0
- package/src/sdk/host/query/index.ts +3 -0
- package/src/sdk/host/query/revision-store.ts +1126 -0
- package/src/sdk/host/reverse-leases.ts +325 -0
- package/src/sdk/host/types.ts +29 -0
- package/src/sdk/index.ts +13 -0
- package/src/sdk/lifecycle-session.ts +39 -0
- package/src/sdk/mcp/index.ts +1 -0
- package/src/sdk/mcp/server.ts +332 -0
- package/src/sdk/models.ts +168 -0
- package/src/sdk/protocol/adapter-validation.ts +48 -0
- package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
- package/src/sdk/protocol/operation-registry.ts +312 -0
- package/src/{sdk.ts → sdk/session.ts} +339 -212
- package/src/sdk/startup-capability.ts +189 -0
- package/src/session/agent-session.ts +2470 -866
- package/src/session/default-model-selection.ts +93 -0
- package/src/session/fallback-chain-controller.ts +136 -0
- package/src/session/session-manager.ts +447 -13
- package/src/session/session-storage.ts +8 -1
- package/src/setup/credential-auto-import.ts +290 -35
- package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
- package/src/slash-commands/builtin-registry.ts +33 -30
- package/src/task/executor.ts +62 -13
- package/src/tools/ask-answer-registry.ts +1 -1
- package/src/tools/ask.ts +13 -8
- package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
- package/src/tools/browser/benchmark/detector-report.ts +157 -0
- package/src/tools/browser/benchmark/run-suite.ts +39 -0
- package/src/tools/browser/launch.ts +124 -19
- package/src/tools/browser/profile-discovery.ts +63 -0
- package/src/tools/browser/profile-posture.ts +59 -0
- package/src/tools/browser/profile-reuse.ts +102 -0
- package/src/tools/browser/profile-warmup.ts +109 -0
- package/src/tools/browser/registry.ts +87 -11
- package/src/tools/browser/tab-protocol.ts +1 -0
- package/src/tools/browser/tab-supervisor.ts +1 -0
- package/src/tools/browser/tab-worker.ts +1 -1
- package/src/tools/browser.ts +6 -0
- package/src/tools/index.ts +8 -8
- package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
- package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
- package/src/tools/telegram-send.ts +2 -2
- package/vendor/insane-search/MANIFEST.json +2 -1
- package/vendor/insane-search/engine/bias_check.py +4 -1
- package/vendor/insane-search/engine/phase0.py +26 -1
- package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
- package/dist/types/modes/bridge/auth.d.ts +0 -12
- package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
- package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
- package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
- package/dist/types/modes/bridge/event-stream.d.ts +0 -8
- package/dist/types/modes/rpc/host-tools.d.ts +0 -1
- package/dist/types/modes/rpc/host-uris.d.ts +0 -1
- package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
- package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
- package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
- package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
- package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
- package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
- package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
- package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
- package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
- package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
- package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
- package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
- package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
- package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
- package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
- package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
- package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
- package/dist/types/notifications/config.d.ts +0 -132
- package/src/harness-control-plane/rpc-adapter.ts +0 -290
- package/src/modes/bridge/auth.ts +0 -41
- package/src/modes/bridge/bridge-client-bridge.ts +0 -47
- package/src/modes/bridge/bridge-mode.ts +0 -675
- package/src/modes/bridge/bridge-ui-context.ts +0 -200
- package/src/modes/bridge/event-stream.ts +0 -70
- package/src/modes/rpc/host-tools.ts +0 -1
- package/src/modes/rpc/host-uris.ts +0 -1
- package/src/modes/rpc/rpc-client.ts +0 -1166
- package/src/modes/rpc/rpc-mode.ts +0 -1029
- package/src/modes/rpc/rpc-socket-security.ts +0 -115
- package/src/modes/rpc/rpc-types.ts +0 -637
- package/src/modes/shared/agent-wire/command-contract.ts +0 -18
- package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
- package/src/modes/shared/agent-wire/command-validation.ts +0 -181
- package/src/modes/shared/agent-wire/handshake.ts +0 -157
- package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
- package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
- package/src/modes/shared/agent-wire/protocol.ts +0 -46
- package/src/modes/shared/agent-wire/responses.ts +0 -17
- package/src/modes/shared/agent-wire/scopes.ts +0 -94
- package/src/modes/shared/agent-wire/session-registry.ts +0 -109
- package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
- package/src/modes/shared/agent-wire/ui-result.ts +0 -48
- package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
- package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
- package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
- package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
- package/src/notifications/config.ts +0 -219
- package/src/notifications/index.ts +0 -1835
- package/src/notifications/telegram-daemon-cli.ts +0 -243
- package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
- /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
- /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
- /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
- /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
- /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
- /package/src/{notifications → sdk/bus}/engine.ts +0 -0
- /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
- /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
- /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
- /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
- /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
- /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
- /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
1
2
|
import { ThinkingLevel } from "@gajae-code/agent-core";
|
|
2
3
|
import { getOAuthProviders } from "@gajae-code/ai/utils/oauth";
|
|
3
4
|
import type { OAuthProvider } from "@gajae-code/ai/utils/oauth/types";
|
|
4
5
|
import type { Component, OverlayHandle } from "@gajae-code/tui";
|
|
5
6
|
import { Input, isPetMode, Loader, Spacer, Text } from "@gajae-code/tui";
|
|
6
|
-
import { getAgentDbPath, getProjectDir } from "@gajae-code/utils";
|
|
7
|
+
import { getAgentDbPath, getProjectDir, logger, VERSION } from "@gajae-code/utils";
|
|
7
8
|
import {
|
|
8
9
|
activateModelProfile,
|
|
9
10
|
type MaterializeModelProfileForDeletionResult,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
import { formatModelProfileDisplayLabel, recommendModelProfileForProvider } from "../../config/model-profiles";
|
|
16
17
|
import { GJC_MODEL_ASSIGNMENT_TARGETS, type GjcModelAssignmentTargetId } from "../../config/model-registry";
|
|
17
18
|
import { formatModelSelectorValue } from "../../config/model-resolver";
|
|
19
|
+
import { selectorHead } from "../../config/model-selector-value";
|
|
18
20
|
import type { ModelProfileConfig } from "../../config/models-config-schema";
|
|
19
21
|
import { type Settings, settings } from "../../config/settings";
|
|
20
22
|
import { DebugSelectorComponent } from "../../debug";
|
|
@@ -40,10 +42,48 @@ import {
|
|
|
40
42
|
theme,
|
|
41
43
|
} from "../../modes/theme/theme";
|
|
42
44
|
import type { InteractiveModeContext, OAuthSelectorOptions } from "../../modes/types";
|
|
45
|
+
import { getNotificationConfig, maskToken } from "../../sdk/bus/config";
|
|
46
|
+
import {
|
|
47
|
+
clearTelegramActivationMarker,
|
|
48
|
+
createTelegramActivationMarker,
|
|
49
|
+
observedTelegramActivationMarker,
|
|
50
|
+
persistTelegramActivationMarker,
|
|
51
|
+
proposedTelegramIdentity,
|
|
52
|
+
reconcileCommittedTelegramConfiguration,
|
|
53
|
+
removeTelegramConfiguration,
|
|
54
|
+
saveTelegramInactive,
|
|
55
|
+
} from "../../sdk/bus/notification-orchestration";
|
|
56
|
+
import {
|
|
57
|
+
buildNotificationStatusReport,
|
|
58
|
+
checkNotificationHealth,
|
|
59
|
+
recoverNotifications,
|
|
60
|
+
sanitizeDiagnostic,
|
|
61
|
+
sendNotificationTest,
|
|
62
|
+
} from "../../sdk/bus/notification-service";
|
|
63
|
+
import type { NotificationSessionStatus } from "../../sdk/bus/session-control";
|
|
64
|
+
import {
|
|
65
|
+
ensureTelegramDaemonRunningDetailed,
|
|
66
|
+
readDaemonState,
|
|
67
|
+
unregisterNotificationRoot,
|
|
68
|
+
} from "../../sdk/bus/telegram-daemon";
|
|
69
|
+
import { TelegramDaemonController } from "../../sdk/bus/telegram-daemon-control";
|
|
70
|
+
import { runTelegramSetup, type TelegramSetupPreflight } from "../../sdk/bus/telegram-setup";
|
|
43
71
|
import { type SessionInfo, SessionManager } from "../../session/session-manager";
|
|
44
72
|
import { FileSessionStorage } from "../../session/session-storage";
|
|
45
73
|
import {
|
|
74
|
+
CREDENTIAL_AUTO_IMPORT_DISCOVERY_WARNING,
|
|
75
|
+
CREDENTIAL_AUTO_IMPORT_PERSISTENCE_WARNING,
|
|
76
|
+
CREDENTIAL_AUTO_IMPORT_REFRESH_WARNING,
|
|
77
|
+
CREDENTIAL_AUTO_IMPORT_RETRY_WARNING,
|
|
46
78
|
CREDENTIAL_AUTO_IMPORT_ROTATION_WARNING,
|
|
79
|
+
CREDENTIAL_AUTO_IMPORT_STATE_UNREADABLE_WARNING,
|
|
80
|
+
type CredentialAutoImportStateReadResult,
|
|
81
|
+
type CredentialAutoImportStateStore,
|
|
82
|
+
createCredentialAutoImportStateStore,
|
|
83
|
+
formatCredentialAutoImportCandidateLabel,
|
|
84
|
+
formatCredentialAutoImportPrompt,
|
|
85
|
+
isCredentialAutoImportStateResolvedForVersion,
|
|
86
|
+
logCredentialAutoImportFailures,
|
|
47
87
|
runExternalCredentialAutoImport,
|
|
48
88
|
} from "../../setup/credential-auto-import";
|
|
49
89
|
import {
|
|
@@ -78,7 +118,12 @@ import type { PetMode } from "../components/gajae-pet-widget";
|
|
|
78
118
|
import { HistorySearchComponent } from "../components/history-search";
|
|
79
119
|
import { JobsOverlayComponent } from "../components/jobs-overlay";
|
|
80
120
|
import { ModelSelectorComponent } from "../components/model-selector";
|
|
121
|
+
import type {
|
|
122
|
+
NotificationsEditorOperations,
|
|
123
|
+
PreparedTelegramConfiguration,
|
|
124
|
+
} from "../components/notifications-settings-editor";
|
|
81
125
|
import { OAuthSelectorComponent } from "../components/oauth-selector";
|
|
126
|
+
import { isPetAvailable } from "../components/pet-capability";
|
|
82
127
|
import { PetSelectorComponent } from "../components/pet-selector";
|
|
83
128
|
import { PluginSelectorComponent } from "../components/plugin-selector";
|
|
84
129
|
import {
|
|
@@ -141,8 +186,512 @@ function formatProviderOnboardingCommandGuide(): string {
|
|
|
141
186
|
].join("\n");
|
|
142
187
|
}
|
|
143
188
|
|
|
189
|
+
export interface NotificationsEditorAdapterContext {
|
|
190
|
+
settings: Settings;
|
|
191
|
+
session: Pick<InteractiveModeContext["session"], "notificationSessionController">;
|
|
192
|
+
sessionManager: Pick<InteractiveModeContext["sessionManager"], "getCwd" | "getSessionId">;
|
|
193
|
+
notifyConfigChanged?: () => Promise<void> | void;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface NotificationsEditorOperationDependencies {
|
|
197
|
+
getNotificationConfig: typeof getNotificationConfig;
|
|
198
|
+
maskToken: typeof maskToken;
|
|
199
|
+
buildNotificationStatusReport: typeof buildNotificationStatusReport;
|
|
200
|
+
checkNotificationHealth: typeof checkNotificationHealth;
|
|
201
|
+
sendNotificationTest: typeof sendNotificationTest;
|
|
202
|
+
recoverNotifications: typeof recoverNotifications;
|
|
203
|
+
sanitizeDiagnostic: typeof sanitizeDiagnostic;
|
|
204
|
+
ensureTelegramDaemonRunningDetailed: typeof ensureTelegramDaemonRunningDetailed;
|
|
205
|
+
runTelegramSetup: typeof runTelegramSetup;
|
|
206
|
+
proposedTelegramIdentity: typeof proposedTelegramIdentity;
|
|
207
|
+
reconcileCommittedTelegramConfiguration: typeof reconcileCommittedTelegramConfiguration;
|
|
208
|
+
saveTelegramInactive: typeof saveTelegramInactive;
|
|
209
|
+
removeTelegramConfiguration: typeof removeTelegramConfiguration;
|
|
210
|
+
unregisterNotificationRoot: typeof unregisterNotificationRoot;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const notificationEditorOperationDependencies: NotificationsEditorOperationDependencies = {
|
|
214
|
+
getNotificationConfig,
|
|
215
|
+
maskToken,
|
|
216
|
+
buildNotificationStatusReport,
|
|
217
|
+
checkNotificationHealth,
|
|
218
|
+
sendNotificationTest,
|
|
219
|
+
recoverNotifications,
|
|
220
|
+
sanitizeDiagnostic,
|
|
221
|
+
ensureTelegramDaemonRunningDetailed,
|
|
222
|
+
runTelegramSetup,
|
|
223
|
+
proposedTelegramIdentity,
|
|
224
|
+
reconcileCommittedTelegramConfiguration,
|
|
225
|
+
saveTelegramInactive,
|
|
226
|
+
removeTelegramConfiguration,
|
|
227
|
+
unregisterNotificationRoot,
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
function unavailableNotificationSessionStatus(): NotificationSessionStatus {
|
|
231
|
+
return {
|
|
232
|
+
eligible: false,
|
|
233
|
+
locallyEnabled: true,
|
|
234
|
+
effectiveEnabled: false,
|
|
235
|
+
running: false,
|
|
236
|
+
environment: "off",
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function unavailableNotificationSessionResult() {
|
|
241
|
+
return { outcome: "disabled" as const, status: unavailableNotificationSessionStatus() };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function notificationOperationError(
|
|
245
|
+
services: NotificationsEditorOperationDependencies,
|
|
246
|
+
error: unknown,
|
|
247
|
+
token?: string,
|
|
248
|
+
): Error {
|
|
249
|
+
return new Error(
|
|
250
|
+
services.sanitizeDiagnostic(error instanceof Error ? error.message : "Notification operation failed.", token),
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Concrete service adapter for the direct Notifications settings tab. Secrets remain in this closure's
|
|
256
|
+
* WeakMap and are never exposed through the editor's safe draft contract.
|
|
257
|
+
*/
|
|
258
|
+
export function createNotificationsEditorOperations(
|
|
259
|
+
ctx: NotificationsEditorAdapterContext,
|
|
260
|
+
overrides: Partial<NotificationsEditorOperationDependencies> = {},
|
|
261
|
+
): NotificationsEditorOperations {
|
|
262
|
+
const services = { ...notificationEditorOperationDependencies, ...overrides };
|
|
263
|
+
const drafts = new WeakMap<PreparedTelegramConfiguration, string>();
|
|
264
|
+
const sessionContext = () => ({ sessionManager: ctx.sessionManager });
|
|
265
|
+
const notifyAfterDurableCommit = async (): Promise<void> => {
|
|
266
|
+
await ctx.notifyConfigChanged?.();
|
|
267
|
+
};
|
|
268
|
+
const reconnect = async () =>
|
|
269
|
+
await services.ensureTelegramDaemonRunningDetailed({
|
|
270
|
+
settings: ctx.settings,
|
|
271
|
+
cwd: ctx.sessionManager.getCwd(),
|
|
272
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
273
|
+
});
|
|
274
|
+
const telegramSetupPreflight = async (): Promise<TelegramSetupPreflight> => {
|
|
275
|
+
const storedChatId = services.getNotificationConfig(ctx.settings).chatId;
|
|
276
|
+
try {
|
|
277
|
+
const state = await readDaemonState(ctx.settings);
|
|
278
|
+
const validPid = Number.isSafeInteger(state?.pid) && (state?.pid ?? 0) > 0;
|
|
279
|
+
if (!state || !validPid) return { storedChatId };
|
|
280
|
+
let live = false;
|
|
281
|
+
try {
|
|
282
|
+
process.kill(state.pid, 0);
|
|
283
|
+
live = true;
|
|
284
|
+
} catch (error) {
|
|
285
|
+
live = (error as NodeJS.ErrnoException).code === "EPERM";
|
|
286
|
+
}
|
|
287
|
+
return live
|
|
288
|
+
? {
|
|
289
|
+
storedChatId,
|
|
290
|
+
daemon: {
|
|
291
|
+
live,
|
|
292
|
+
tokenFingerprint: typeof state.tokenFingerprint === "string" ? state.tokenFingerprint : undefined,
|
|
293
|
+
chatId: typeof state.chatId === "string" && state.chatId.trim() ? state.chatId.trim() : undefined,
|
|
294
|
+
},
|
|
295
|
+
}
|
|
296
|
+
: { storedChatId };
|
|
297
|
+
} catch {
|
|
298
|
+
return { storedChatId };
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
loadState: async () => {
|
|
304
|
+
const config = services.getNotificationConfig(ctx.settings);
|
|
305
|
+
return {
|
|
306
|
+
status: services.buildNotificationStatusReport(ctx.settings),
|
|
307
|
+
session:
|
|
308
|
+
ctx.session.notificationSessionController?.query(sessionContext()) ??
|
|
309
|
+
unavailableNotificationSessionStatus(),
|
|
310
|
+
preferences: {
|
|
311
|
+
redact: config.redact,
|
|
312
|
+
verbosity: config.verbosity,
|
|
313
|
+
sessionScope: config.sessionScope,
|
|
314
|
+
richEnabled: config.rich.enabled,
|
|
315
|
+
richDraftEnabled: config.richDraft.enabled,
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
refreshHealth: async ({ probe, signal }) => {
|
|
321
|
+
if (signal?.aborted) throw new Error("Notification health refresh cancelled.");
|
|
322
|
+
try {
|
|
323
|
+
const input: Parameters<typeof checkNotificationHealth>[0] & { signal?: AbortSignal } = {
|
|
324
|
+
settings: ctx.settings,
|
|
325
|
+
stateRoot: path.join(ctx.sessionManager.getCwd(), ".gjc", "state"),
|
|
326
|
+
probe,
|
|
327
|
+
signal,
|
|
328
|
+
};
|
|
329
|
+
const report = await services.checkNotificationHealth(input);
|
|
330
|
+
if (signal?.aborted) throw new Error("Notification health refresh cancelled.");
|
|
331
|
+
const token = services.getNotificationConfig(ctx.settings).botToken;
|
|
332
|
+
return {
|
|
333
|
+
...report,
|
|
334
|
+
checks: report.checks.map(check => ({
|
|
335
|
+
...check,
|
|
336
|
+
detail: services.sanitizeDiagnostic(check.detail, token),
|
|
337
|
+
})),
|
|
338
|
+
reachability: {
|
|
339
|
+
...report.reachability,
|
|
340
|
+
detail: services.sanitizeDiagnostic(report.reachability.detail, token),
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
} catch (error) {
|
|
344
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
|
|
348
|
+
sendTest: async () => {
|
|
349
|
+
try {
|
|
350
|
+
const result = await services.sendNotificationTest({ settings: ctx.settings });
|
|
351
|
+
return {
|
|
352
|
+
...result,
|
|
353
|
+
detail: services.sanitizeDiagnostic(
|
|
354
|
+
result.detail,
|
|
355
|
+
services.getNotificationConfig(ctx.settings).botToken,
|
|
356
|
+
),
|
|
357
|
+
};
|
|
358
|
+
} catch (error) {
|
|
359
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
360
|
+
}
|
|
361
|
+
},
|
|
362
|
+
|
|
363
|
+
recover: async () => {
|
|
364
|
+
try {
|
|
365
|
+
const result = await services.recoverNotifications({
|
|
366
|
+
settings: ctx.settings,
|
|
367
|
+
stateRoot: path.join(ctx.sessionManager.getCwd(), ".gjc", "state"),
|
|
368
|
+
});
|
|
369
|
+
return {
|
|
370
|
+
...result,
|
|
371
|
+
daemon: {
|
|
372
|
+
...result.daemon,
|
|
373
|
+
detail: services.sanitizeDiagnostic(
|
|
374
|
+
result.daemon.detail,
|
|
375
|
+
services.getNotificationConfig(ctx.settings).botToken,
|
|
376
|
+
),
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
} catch (error) {
|
|
380
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
reconnect: async () => {
|
|
385
|
+
try {
|
|
386
|
+
const result = await reconnect();
|
|
387
|
+
const controller = ctx.session.notificationSessionController;
|
|
388
|
+
if (result === "blocked_identity") {
|
|
389
|
+
await controller?.enterBlockedRuntime(sessionContext());
|
|
390
|
+
} else if (result === "spawned" || result === "reloaded" || result === "attached") {
|
|
391
|
+
await controller?.clearBlockedRuntime(sessionContext());
|
|
392
|
+
await controller?.reconcileCurrentSession(sessionContext());
|
|
393
|
+
}
|
|
394
|
+
return result;
|
|
395
|
+
} catch (error) {
|
|
396
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
|
|
400
|
+
preflightProposedIdentity: async (input, signal) => {
|
|
401
|
+
const token = input.token.consume();
|
|
402
|
+
const unknownIdentity = { status: "unknown" as const };
|
|
403
|
+
if (!token.trim()) {
|
|
404
|
+
return {
|
|
405
|
+
status: "error",
|
|
406
|
+
identity: unknownIdentity,
|
|
407
|
+
message: "Telegram bot token is required.",
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
const setup = await services.runTelegramSetup({
|
|
412
|
+
token,
|
|
413
|
+
chatId: input.chatId,
|
|
414
|
+
preflight: await telegramSetupPreflight(),
|
|
415
|
+
revalidatePreflight: async () => await telegramSetupPreflight(),
|
|
416
|
+
interactive: false,
|
|
417
|
+
signal,
|
|
418
|
+
deps: { fetchImpl: globalThis.fetch },
|
|
419
|
+
});
|
|
420
|
+
if (!setup.ok) {
|
|
421
|
+
return {
|
|
422
|
+
status: setup.status === "aborted" ? "aborted" : setup.status === "cancelled" ? "cancelled" : "error",
|
|
423
|
+
identity: unknownIdentity,
|
|
424
|
+
message: services.sanitizeDiagnostic(setup.detail, token),
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
if (signal.aborted) {
|
|
428
|
+
return {
|
|
429
|
+
status: "aborted",
|
|
430
|
+
identity: unknownIdentity,
|
|
431
|
+
message: "Telegram setup cancelled.",
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
const identity = await services.proposedTelegramIdentity({
|
|
435
|
+
settings: ctx.settings,
|
|
436
|
+
botToken: token,
|
|
437
|
+
chatId: setup.chatId,
|
|
438
|
+
chatDisplay: setup.chatId,
|
|
439
|
+
});
|
|
440
|
+
if (signal.aborted) {
|
|
441
|
+
return {
|
|
442
|
+
status: "aborted",
|
|
443
|
+
identity,
|
|
444
|
+
message: "Telegram setup cancelled.",
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
const draft: PreparedTelegramConfiguration = {
|
|
448
|
+
chatId: setup.chatId,
|
|
449
|
+
tokenMask: services.maskToken(token),
|
|
450
|
+
tokenFingerprint: setup.tokenFingerprint,
|
|
451
|
+
richEnabled: input.richEnabled,
|
|
452
|
+
richDraftEnabled: input.richDraftEnabled,
|
|
453
|
+
};
|
|
454
|
+
drafts.set(draft, token);
|
|
455
|
+
const pairingMessage =
|
|
456
|
+
setup.pairingSource === "discovered"
|
|
457
|
+
? "Telegram private chat discovered and validated."
|
|
458
|
+
: setup.pairingSource === "reused"
|
|
459
|
+
? "Stored Telegram private chat validated without polling."
|
|
460
|
+
: "Supplied Telegram private chat validated.";
|
|
461
|
+
return {
|
|
462
|
+
status: "ready",
|
|
463
|
+
identity,
|
|
464
|
+
draft,
|
|
465
|
+
pairingSource: setup.pairingSource,
|
|
466
|
+
message:
|
|
467
|
+
identity.status === "foreign" || identity.status === "unknown"
|
|
468
|
+
? `${pairingMessage} Activation is blocked by the current daemon identity.`
|
|
469
|
+
: pairingMessage,
|
|
470
|
+
};
|
|
471
|
+
} catch (error) {
|
|
472
|
+
return {
|
|
473
|
+
status: signal.aborted ? "aborted" : "error",
|
|
474
|
+
identity: unknownIdentity,
|
|
475
|
+
message: signal.aborted
|
|
476
|
+
? "Telegram setup cancelled."
|
|
477
|
+
: services.sanitizeDiagnostic(
|
|
478
|
+
error instanceof Error ? error.message : "Telegram setup failed.",
|
|
479
|
+
token,
|
|
480
|
+
),
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
},
|
|
484
|
+
|
|
485
|
+
commitConfigure: async draft => {
|
|
486
|
+
const token = drafts.get(draft);
|
|
487
|
+
if (!token) throw new Error("The Telegram setup draft expired. Re-enter the masked bot token.");
|
|
488
|
+
try {
|
|
489
|
+
const inactiveMarkerToClear = observedTelegramActivationMarker(ctx.settings, token, draft.chatId);
|
|
490
|
+
const receipt = await ctx.settings.commitAtomicBatch([
|
|
491
|
+
{ path: "notifications.enabled", op: "set", value: true },
|
|
492
|
+
{ path: "notifications.telegram.botToken", op: "set", value: token },
|
|
493
|
+
{ path: "notifications.telegram.chatId", op: "set", value: draft.chatId },
|
|
494
|
+
{ path: "notifications.telegram.rich.enabled", op: "set", value: draft.richEnabled },
|
|
495
|
+
{ path: "notifications.telegram.richDraft.enabled", op: "set", value: draft.richDraftEnabled },
|
|
496
|
+
]);
|
|
497
|
+
drafts.delete(draft);
|
|
498
|
+
const activationMarker = createTelegramActivationMarker({
|
|
499
|
+
botToken: token,
|
|
500
|
+
chatId: draft.chatId,
|
|
501
|
+
state: "blocked",
|
|
502
|
+
reason: "identity_mismatch",
|
|
503
|
+
});
|
|
504
|
+
const controller = ctx.session.notificationSessionController;
|
|
505
|
+
const activation = await services.reconcileCommittedTelegramConfiguration({
|
|
506
|
+
receipt,
|
|
507
|
+
inactiveMarkerToClear,
|
|
508
|
+
activation: {
|
|
509
|
+
controller: controller
|
|
510
|
+
? {
|
|
511
|
+
enterBlockedRuntime: async () => await controller.enterBlockedRuntime(sessionContext()),
|
|
512
|
+
clearBlockedRuntime: async () => await controller.clearBlockedRuntime(sessionContext()),
|
|
513
|
+
reconcileCurrentSession: async () =>
|
|
514
|
+
await controller.reconcileCurrentSession(sessionContext()),
|
|
515
|
+
}
|
|
516
|
+
: {
|
|
517
|
+
enterBlockedRuntime: async () => undefined,
|
|
518
|
+
clearBlockedRuntime: async () => undefined,
|
|
519
|
+
reconcileCurrentSession: async () => undefined,
|
|
520
|
+
},
|
|
521
|
+
reconnect,
|
|
522
|
+
persistInactive: async marker => await persistTelegramActivationMarker(ctx.settings, marker),
|
|
523
|
+
clearInactive: async marker => await clearTelegramActivationMarker(ctx.settings, marker),
|
|
524
|
+
marker: activationMarker,
|
|
525
|
+
},
|
|
526
|
+
});
|
|
527
|
+
await notifyAfterDurableCommit();
|
|
528
|
+
if (activation.status === "blocked_identity") {
|
|
529
|
+
return {
|
|
530
|
+
status: "blocked_identity" as const,
|
|
531
|
+
receipt,
|
|
532
|
+
message: services.sanitizeDiagnostic(activation.message, token),
|
|
533
|
+
restore: async () => {
|
|
534
|
+
const restored = await activation.restore();
|
|
535
|
+
if (restored.status === "restored" || restored.status === "still_blocked") {
|
|
536
|
+
await notifyAfterDurableCommit();
|
|
537
|
+
}
|
|
538
|
+
return restored;
|
|
539
|
+
},
|
|
540
|
+
retainCommitted: () => activation.retainCommitted(),
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
status: "saved" as const,
|
|
545
|
+
receipt,
|
|
546
|
+
message: services.sanitizeDiagnostic("Telegram configuration saved and reconciled.", token),
|
|
547
|
+
};
|
|
548
|
+
} catch (error) {
|
|
549
|
+
throw notificationOperationError(services, error, token);
|
|
550
|
+
}
|
|
551
|
+
},
|
|
552
|
+
|
|
553
|
+
saveInactive: async draft => {
|
|
554
|
+
const token = drafts.get(draft);
|
|
555
|
+
if (!token) throw new Error("The Telegram setup draft expired. Re-enter the masked bot token.");
|
|
556
|
+
try {
|
|
557
|
+
const result = await services.saveTelegramInactive({
|
|
558
|
+
settings: ctx.settings,
|
|
559
|
+
botToken: token,
|
|
560
|
+
chatId: draft.chatId,
|
|
561
|
+
});
|
|
562
|
+
drafts.delete(draft);
|
|
563
|
+
await notifyAfterDurableCommit();
|
|
564
|
+
return {
|
|
565
|
+
status: "saved_inactive" as const,
|
|
566
|
+
receipt: result.receipt,
|
|
567
|
+
message: "Telegram configuration saved inactive; no runtime activation was requested.",
|
|
568
|
+
};
|
|
569
|
+
} catch (error) {
|
|
570
|
+
throw notificationOperationError(services, error, token);
|
|
571
|
+
}
|
|
572
|
+
},
|
|
573
|
+
|
|
574
|
+
discardConfigureDraft: draft => {
|
|
575
|
+
drafts.delete(draft);
|
|
576
|
+
},
|
|
577
|
+
|
|
578
|
+
enableGlobally: async () => {
|
|
579
|
+
try {
|
|
580
|
+
const receipt = await ctx.settings.commitAtomicBatch([
|
|
581
|
+
{ path: "notifications.enabled", op: "set", value: true },
|
|
582
|
+
]);
|
|
583
|
+
await notifyAfterDurableCommit();
|
|
584
|
+
return { receipt, message: "Global notifications enabled using stored configuration." };
|
|
585
|
+
} catch (error) {
|
|
586
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
587
|
+
}
|
|
588
|
+
},
|
|
589
|
+
|
|
590
|
+
disableGlobally: async () => {
|
|
591
|
+
try {
|
|
592
|
+
const receipt = await ctx.settings.commitAtomicBatch([
|
|
593
|
+
{ path: "notifications.enabled", op: "set", value: false },
|
|
594
|
+
]);
|
|
595
|
+
await notifyAfterDurableCommit();
|
|
596
|
+
return { receipt, message: "Global notifications disabled." };
|
|
597
|
+
} catch (error) {
|
|
598
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
599
|
+
}
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
removeTelegram: async () => {
|
|
603
|
+
const controller = ctx.session.notificationSessionController;
|
|
604
|
+
let runtimePrepared = false;
|
|
605
|
+
try {
|
|
606
|
+
const result = await services.removeTelegramConfiguration({
|
|
607
|
+
settings: ctx.settings,
|
|
608
|
+
removal: {
|
|
609
|
+
stopAndUnregister: async () => {
|
|
610
|
+
if (controller) await controller.enterBlockedRuntime(sessionContext());
|
|
611
|
+
runtimePrepared = true;
|
|
612
|
+
const unregistered = await services.unregisterNotificationRoot({
|
|
613
|
+
settings: ctx.settings,
|
|
614
|
+
cwd: ctx.sessionManager.getCwd(),
|
|
615
|
+
sessionId: ctx.sessionManager.getSessionId(),
|
|
616
|
+
});
|
|
617
|
+
if (unregistered.remainingRoots === 0) {
|
|
618
|
+
const stopped = await new TelegramDaemonController(ctx.settings).stop();
|
|
619
|
+
if (!stopped.ok) throw new Error(stopped.message);
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
},
|
|
623
|
+
});
|
|
624
|
+
if (runtimePrepared && controller) {
|
|
625
|
+
await controller.clearBlockedRuntime(sessionContext());
|
|
626
|
+
await controller.reconcileCurrentSession(sessionContext());
|
|
627
|
+
}
|
|
628
|
+
await notifyAfterDurableCommit();
|
|
629
|
+
return {
|
|
630
|
+
receipt: result.receipt,
|
|
631
|
+
globallyDisabled: result.globallyDisabled,
|
|
632
|
+
message: result.globallyDisabled
|
|
633
|
+
? "Telegram configuration removed and global notifications disabled."
|
|
634
|
+
: "Telegram configuration removed; Discord or Slack configuration was preserved.",
|
|
635
|
+
};
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (runtimePrepared) {
|
|
638
|
+
const restored = await reconnect();
|
|
639
|
+
if (restored !== "blocked_identity" && controller) {
|
|
640
|
+
await controller.clearBlockedRuntime(sessionContext());
|
|
641
|
+
await controller.reconcileCurrentSession(sessionContext());
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
|
|
648
|
+
setSessionLocal: async enabled => {
|
|
649
|
+
const controller = ctx.session.notificationSessionController;
|
|
650
|
+
if (!controller) return unavailableNotificationSessionResult();
|
|
651
|
+
try {
|
|
652
|
+
return await controller.setLocalEnabled(sessionContext(), enabled);
|
|
653
|
+
} catch (error) {
|
|
654
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
|
|
658
|
+
commitPreferences: async preferences => {
|
|
659
|
+
try {
|
|
660
|
+
const receipt = await ctx.settings.commitAtomicBatch([
|
|
661
|
+
{ path: "notifications.redact", op: "set", value: preferences.redact },
|
|
662
|
+
{ path: "notifications.verbosity", op: "set", value: preferences.verbosity },
|
|
663
|
+
{ path: "notifications.sessionScope", op: "set", value: preferences.sessionScope },
|
|
664
|
+
{ path: "notifications.telegram.rich.enabled", op: "set", value: preferences.richEnabled },
|
|
665
|
+
{ path: "notifications.telegram.richDraft.enabled", op: "set", value: preferences.richDraftEnabled },
|
|
666
|
+
]);
|
|
667
|
+
await notifyAfterDurableCommit();
|
|
668
|
+
return { receipt, message: "Notification preferences saved atomically." };
|
|
669
|
+
} catch (error) {
|
|
670
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
671
|
+
}
|
|
672
|
+
},
|
|
673
|
+
|
|
674
|
+
reconcileCurrentSession: async () => {
|
|
675
|
+
const controller = ctx.session.notificationSessionController;
|
|
676
|
+
if (!controller) return unavailableNotificationSessionResult();
|
|
677
|
+
try {
|
|
678
|
+
return await controller.reconcileCurrentSession(sessionContext());
|
|
679
|
+
} catch (error) {
|
|
680
|
+
throw notificationOperationError(services, error, services.getNotificationConfig(ctx.settings).botToken);
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
144
686
|
export class SelectorController {
|
|
145
|
-
|
|
687
|
+
#credentialAutoImportStateStore?: CredentialAutoImportStateStore;
|
|
688
|
+
|
|
689
|
+
constructor(
|
|
690
|
+
private ctx: InteractiveModeContext,
|
|
691
|
+
credentialAutoImportStateStore?: CredentialAutoImportStateStore,
|
|
692
|
+
) {
|
|
693
|
+
this.#credentialAutoImportStateStore = credentialAutoImportStateStore;
|
|
694
|
+
}
|
|
146
695
|
|
|
147
696
|
async #refreshOAuthProviderAuthState(): Promise<void> {
|
|
148
697
|
const oauthProviders = getOAuthProviders();
|
|
@@ -485,6 +1034,8 @@ export class SelectorController {
|
|
|
485
1034
|
showSettingsSelector(): void {
|
|
486
1035
|
getAvailableThemes().then(availableThemes => {
|
|
487
1036
|
this.showSelector(done => {
|
|
1037
|
+
const notificationsOperations = createNotificationsEditorOperations(this.ctx);
|
|
1038
|
+
|
|
488
1039
|
const selector = new SettingsSelectorComponent(
|
|
489
1040
|
{
|
|
490
1041
|
availableThinkingLevels: [...this.ctx.session.getAvailableThinkingLevels()],
|
|
@@ -540,6 +1091,7 @@ export class SelectorController {
|
|
|
540
1091
|
this.ctx.ui.requestRender();
|
|
541
1092
|
},
|
|
542
1093
|
},
|
|
1094
|
+
notificationsOperations,
|
|
543
1095
|
);
|
|
544
1096
|
return { component: selector, focus: selector };
|
|
545
1097
|
});
|
|
@@ -607,6 +1159,7 @@ export class SelectorController {
|
|
|
607
1159
|
mode => {
|
|
608
1160
|
this.ctx.previewPetMode(mode);
|
|
609
1161
|
},
|
|
1162
|
+
isPetAvailable(),
|
|
610
1163
|
);
|
|
611
1164
|
return { component: selector, focus: selector.getSelectList() };
|
|
612
1165
|
});
|
|
@@ -660,7 +1213,7 @@ export class SelectorController {
|
|
|
660
1213
|
const dashboard = await AgentDashboard.create(getProjectDir(), this.ctx.settings, this.ctx.ui.terminal.rows, {
|
|
661
1214
|
modelRegistry: this.ctx.session.modelRegistry,
|
|
662
1215
|
activeModelPattern,
|
|
663
|
-
defaultModelPattern,
|
|
1216
|
+
defaultModelPattern: selectorHead(defaultModelPattern),
|
|
664
1217
|
});
|
|
665
1218
|
this.showSelector(done => {
|
|
666
1219
|
dashboard.onClose = () => {
|
|
@@ -942,7 +1495,13 @@ export class SelectorController {
|
|
|
942
1495
|
const { model, role, thinkingLevel, selector: selectedSelector } = selection;
|
|
943
1496
|
if (role === null) {
|
|
944
1497
|
// Temporary: update agent state but don't persist to settings
|
|
945
|
-
await this.ctx.session.setModelTemporary(model, thinkingLevel
|
|
1498
|
+
await this.ctx.session.setModelTemporary(model, thinkingLevel, {
|
|
1499
|
+
cause: "temporary-operation",
|
|
1500
|
+
reason: "other",
|
|
1501
|
+
});
|
|
1502
|
+
this.ctx.session.setDefaultFallbackRuntimeModel(
|
|
1503
|
+
selectedSelector ?? formatModelSelectorValue(`${model.provider}/${model.id}`, thinkingLevel),
|
|
1504
|
+
);
|
|
946
1505
|
this.ctx.statusLine.invalidate();
|
|
947
1506
|
this.ctx.updateEditorBorderColor();
|
|
948
1507
|
this.ctx.showStatus(`Temporary model: ${selectedSelector ?? model.id}`);
|
|
@@ -974,6 +1533,7 @@ export class SelectorController {
|
|
|
974
1533
|
await this.ctx.session.setModel(model, "default", {
|
|
975
1534
|
selector: defaultSelector,
|
|
976
1535
|
thinkingLevel,
|
|
1536
|
+
cause: "user-selection",
|
|
977
1537
|
});
|
|
978
1538
|
if (thinkingLevel && thinkingLevel !== ThinkingLevel.Inherit) {
|
|
979
1539
|
this.ctx.session.setThinkingLevel(thinkingLevel);
|
|
@@ -985,21 +1545,14 @@ export class SelectorController {
|
|
|
985
1545
|
assignments,
|
|
986
1546
|
});
|
|
987
1547
|
if (!materializedProfile) {
|
|
988
|
-
const overrides = this.ctx.settings.get("task.agentModelOverrides");
|
|
989
|
-
const nextOverrides = { ...overrides };
|
|
990
|
-
let writesOverrides = false;
|
|
991
1548
|
for (const targetRole of targetRoles) {
|
|
992
1549
|
const target = GJC_MODEL_ASSIGNMENT_TARGETS[targetRole];
|
|
993
1550
|
if (target.settingsPath === "modelRoles") {
|
|
994
1551
|
this.ctx.settings.setModelRole(targetRole, value);
|
|
995
1552
|
} else {
|
|
996
|
-
|
|
997
|
-
writesOverrides = true;
|
|
1553
|
+
this.ctx.settings.setAgentModelOverride(targetRole, value);
|
|
998
1554
|
}
|
|
999
1555
|
}
|
|
1000
|
-
if (writesOverrides) {
|
|
1001
|
-
this.ctx.settings.set("task.agentModelOverrides", nextOverrides);
|
|
1002
|
-
}
|
|
1003
1556
|
}
|
|
1004
1557
|
modelSelector.refreshRoleAssignments({
|
|
1005
1558
|
currentModel: this.ctx.session.model,
|
|
@@ -1026,6 +1579,7 @@ export class SelectorController {
|
|
|
1026
1579
|
await this.ctx.session.setModel(model, role, {
|
|
1027
1580
|
selector: selectedSelector,
|
|
1028
1581
|
thinkingLevel,
|
|
1582
|
+
cause: "user-selection",
|
|
1029
1583
|
});
|
|
1030
1584
|
const value = formatModelSelectorValue(
|
|
1031
1585
|
selectedSelector ?? `${model.provider}/${model.id}`,
|
|
@@ -1069,10 +1623,7 @@ export class SelectorController {
|
|
|
1069
1623
|
if (target.settingsPath === "modelRoles") {
|
|
1070
1624
|
this.ctx.settings.setModelRole(role, value);
|
|
1071
1625
|
} else {
|
|
1072
|
-
this.ctx.settings.
|
|
1073
|
-
...this.ctx.settings.get("task.agentModelOverrides"),
|
|
1074
|
-
[role]: value,
|
|
1075
|
-
});
|
|
1626
|
+
this.ctx.settings.setAgentModelOverride(role, value);
|
|
1076
1627
|
}
|
|
1077
1628
|
}
|
|
1078
1629
|
modelSelector.refreshRoleAssignments({
|
|
@@ -1654,34 +2205,110 @@ export class SelectorController {
|
|
|
1654
2205
|
options?.allowExternalCredentialDiscovery === true &&
|
|
1655
2206
|
options.trigger === "bare-login"
|
|
1656
2207
|
) {
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
},
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
2208
|
+
const stateStore =
|
|
2209
|
+
this.#credentialAutoImportStateStore ??
|
|
2210
|
+
createCredentialAutoImportStateStore(this.ctx.settings.getAgentDir());
|
|
2211
|
+
let stateRead: CredentialAutoImportStateReadResult | undefined;
|
|
2212
|
+
try {
|
|
2213
|
+
stateRead = await stateStore.read();
|
|
2214
|
+
} catch {
|
|
2215
|
+
logger.warn("Credential auto-import state read failed", { classification: "state-read-failed" });
|
|
2216
|
+
stateRead = { state: {}, problems: [], unreadable: true };
|
|
2217
|
+
}
|
|
2218
|
+
if (stateRead?.unreadable === true) {
|
|
2219
|
+
logger.warn("Credential auto-import state unavailable", { classification: "state-unreadable" });
|
|
2220
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_STATE_UNREADABLE_WARNING);
|
|
2221
|
+
} else if (stateRead && !isCredentialAutoImportStateResolvedForVersion(stateRead.state, VERSION)) {
|
|
2222
|
+
const preview = await runExternalCredentialAutoImport({
|
|
2223
|
+
authStorage: {
|
|
2224
|
+
importCredentialIfAbsent: async () => ({
|
|
2225
|
+
inserted: false,
|
|
2226
|
+
reason: "skipped-existing",
|
|
2227
|
+
provider: "",
|
|
2228
|
+
entries: [],
|
|
2229
|
+
}),
|
|
2230
|
+
},
|
|
2231
|
+
trigger: "bare-login",
|
|
2232
|
+
discover: options.externalCredentialDiscover,
|
|
2233
|
+
});
|
|
2234
|
+
if (!preview.discovered) {
|
|
2235
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_DISCOVERY_WARNING);
|
|
2236
|
+
} else {
|
|
2237
|
+
const result = preview.discovery ?? { importable: [], skipped: [], environment: [] };
|
|
2238
|
+
const candidates = filterAutoImportOAuthCredentials(result.importable);
|
|
2239
|
+
const previewSourceFailures = preview.failures.filter(failure => failure.credential === undefined);
|
|
2240
|
+
if (candidates.length === 0 && previewSourceFailures.length > 0) {
|
|
2241
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_DISCOVERY_WARNING);
|
|
2242
|
+
} else if (candidates.length > 0) {
|
|
2243
|
+
const confirmed = await this.ctx.showHookConfirm(
|
|
2244
|
+
`Import ${candidates.length} external credential(s)?`,
|
|
2245
|
+
`${formatCredentialAutoImportPrompt(candidates)}\n\n${CREDENTIAL_AUTO_IMPORT_ROTATION_WARNING}`,
|
|
2246
|
+
);
|
|
2247
|
+
if (!confirmed) {
|
|
2248
|
+
let persisted = false;
|
|
2249
|
+
try {
|
|
2250
|
+
persisted = await stateStore.write({ initialImportResolution: "declined" });
|
|
2251
|
+
} catch {
|
|
2252
|
+
logger.warn("Credential auto-import state persistence failed", {
|
|
2253
|
+
classification: "state-write-failed",
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
if (!persisted) this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_PERSISTENCE_WARNING);
|
|
2257
|
+
} else {
|
|
2258
|
+
const summary = await runExternalCredentialAutoImport({
|
|
2259
|
+
authStorage: this.ctx.session.modelRegistry.authStorage,
|
|
2260
|
+
trigger: "bare-login",
|
|
2261
|
+
discover: options.externalCredentialDiscover,
|
|
2262
|
+
});
|
|
2263
|
+
if (!summary.discovered) {
|
|
2264
|
+
logCredentialAutoImportFailures("bare-login", summary.failures);
|
|
2265
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_RETRY_WARNING);
|
|
2266
|
+
} else {
|
|
2267
|
+
const secondResult = summary.discovery ?? { importable: [], skipped: [], environment: [] };
|
|
2268
|
+
const secondCandidates = filterAutoImportOAuthCredentials(secondResult.importable);
|
|
2269
|
+
const secondSourceFailures = summary.failures.filter(
|
|
2270
|
+
failure => failure.credential === undefined,
|
|
2271
|
+
);
|
|
2272
|
+
const handledCandidates = summary.imported.length + summary.skipped.length > 0;
|
|
2273
|
+
if (handledCandidates || (secondCandidates.length === 0 && secondSourceFailures.length === 0)) {
|
|
2274
|
+
let persisted = false;
|
|
2275
|
+
try {
|
|
2276
|
+
persisted = await stateStore.write({ initialImportResolution: "accepted" });
|
|
2277
|
+
} catch {
|
|
2278
|
+
logger.warn("Credential auto-import state persistence failed", {
|
|
2279
|
+
classification: "state-write-failed",
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
if (!persisted) this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_PERSISTENCE_WARNING);
|
|
2283
|
+
externalCredentialCandidates = summary.imported.map(credential => ({
|
|
2284
|
+
...credential,
|
|
2285
|
+
source: formatCredentialAutoImportCandidateLabel(credential),
|
|
2286
|
+
}));
|
|
2287
|
+
if (!handledCandidates) {
|
|
2288
|
+
this.ctx.showStatus("External credentials were no longer available to import.");
|
|
2289
|
+
}
|
|
2290
|
+
if (summary.imported.length > 0) {
|
|
2291
|
+
try {
|
|
2292
|
+
await this.ctx.session.modelRegistry.refresh("offline");
|
|
2293
|
+
} catch {
|
|
2294
|
+
logger.warn("Credential auto-import refresh failed", {
|
|
2295
|
+
classification: "refresh-failed",
|
|
2296
|
+
});
|
|
2297
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_REFRESH_WARNING);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
if (handledCandidates && summary.failures.length > 0) {
|
|
2301
|
+
logCredentialAutoImportFailures("bare-login", summary.failures);
|
|
2302
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_RETRY_WARNING);
|
|
2303
|
+
}
|
|
2304
|
+
} else if (secondCandidates.length > 0 && summary.failures.length > 0) {
|
|
2305
|
+
logCredentialAutoImportFailures("bare-login", summary.failures);
|
|
2306
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_RETRY_WARNING);
|
|
2307
|
+
} else {
|
|
2308
|
+
this.ctx.showWarning(CREDENTIAL_AUTO_IMPORT_DISCOVERY_WARNING);
|
|
2309
|
+
}
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
1685
2312
|
}
|
|
1686
2313
|
}
|
|
1687
2314
|
}
|