@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
|
@@ -17,6 +17,7 @@ import * as crypto from "node:crypto";
|
|
|
17
17
|
import * as fs from "node:fs/promises";
|
|
18
18
|
import * as os from "node:os";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
+
import { cleanReason } from "@gajae-code/ai/auth-broker/redact";
|
|
20
21
|
import {
|
|
21
22
|
AuthBrokerClient,
|
|
22
23
|
type AuthCredential,
|
|
@@ -28,13 +29,19 @@ import {
|
|
|
28
29
|
listProvidersWithEnvKey,
|
|
29
30
|
type OAuthCredential,
|
|
30
31
|
type OAuthProvider,
|
|
32
|
+
resolveOAuthStorageProvider,
|
|
31
33
|
SqliteAuthCredentialStore,
|
|
32
34
|
startAuthBroker,
|
|
33
35
|
} from "@gajae-code/ai/core";
|
|
34
|
-
import { $which, APP_NAME, getAgentDbPath, getConfigRootDir,
|
|
36
|
+
import { $which, APP_NAME, getAgentDbPath, getConfigRootDir, logger, VERSION } from "@gajae-code/utils";
|
|
35
37
|
import { $ } from "bun";
|
|
36
38
|
import chalk from "chalk";
|
|
37
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
createSecureTokenFileExclusive,
|
|
41
|
+
readSecureTokenFile,
|
|
42
|
+
writeSecureTokenFile,
|
|
43
|
+
} from "../session/secure-token-file";
|
|
44
|
+
import { resolveStartupAuthConfig } from "../session/startup-auth-config";
|
|
38
45
|
|
|
39
46
|
export type AuthBrokerAction = "serve" | "token" | "login" | "logout" | "status" | "import" | "migrate";
|
|
40
47
|
|
|
@@ -62,6 +69,39 @@ export interface AuthBrokerCommandArgs {
|
|
|
62
69
|
|
|
63
70
|
const ACTIONS: readonly AuthBrokerAction[] = ["serve", "token", "login", "logout", "import", "migrate", "status"];
|
|
64
71
|
|
|
72
|
+
type AuthBrokerCliErrorCode =
|
|
73
|
+
| "broker_unavailable"
|
|
74
|
+
| "credential_import_failed"
|
|
75
|
+
| "credential_migration_failed"
|
|
76
|
+
| "auth_broker_command_failed";
|
|
77
|
+
|
|
78
|
+
function stableErrorForAction(action: AuthBrokerAction): { code: AuthBrokerCliErrorCode; message: string } {
|
|
79
|
+
switch (action) {
|
|
80
|
+
case "status":
|
|
81
|
+
return { code: "broker_unavailable", message: "Auth broker is unavailable." };
|
|
82
|
+
case "import":
|
|
83
|
+
return { code: "credential_import_failed", message: "Credential import failed." };
|
|
84
|
+
case "migrate":
|
|
85
|
+
return { code: "credential_migration_failed", message: "Credential migration failed." };
|
|
86
|
+
default:
|
|
87
|
+
return { code: "auth_broker_command_failed", message: "Auth broker command failed." };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function safeDiagnostic(value: unknown, fallback: string): string {
|
|
92
|
+
return cleanReason(value) ?? fallback;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function writeCommandFailure(action: AuthBrokerAction, flags: AuthBrokerCommandArgs["flags"], error: unknown): void {
|
|
96
|
+
const stable = stableErrorForAction(action);
|
|
97
|
+
if (flags.json) {
|
|
98
|
+
process.stdout.write(`${JSON.stringify({ ok: false, error: stable })}\n`);
|
|
99
|
+
} else {
|
|
100
|
+
process.stderr.write(`${chalk.red("FAILED")} ${safeDiagnostic(error, stable.message)}\n`);
|
|
101
|
+
}
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
|
|
65
105
|
/** Callback ports baked from the per-provider OAuth flow modules. */
|
|
66
106
|
const CALLBACK_PORTS: Record<string, number> = {
|
|
67
107
|
anthropic: 54545,
|
|
@@ -78,25 +118,15 @@ function getTokenFilePath(): string {
|
|
|
78
118
|
}
|
|
79
119
|
|
|
80
120
|
async function readToken(): Promise<string | null> {
|
|
81
|
-
|
|
82
|
-
const raw = await Bun.file(getTokenFilePath()).text();
|
|
83
|
-
const trimmed = raw.trim();
|
|
84
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
85
|
-
} catch (err) {
|
|
86
|
-
if (isEnoent(err)) return null;
|
|
87
|
-
throw err;
|
|
88
|
-
}
|
|
121
|
+
return readSecureTokenFile(getTokenFilePath());
|
|
89
122
|
}
|
|
90
123
|
|
|
91
124
|
async function writeToken(token: string): Promise<void> {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} catch {
|
|
98
|
-
// Best-effort (e.g. Windows).
|
|
99
|
-
}
|
|
125
|
+
await writeSecureTokenFile(getTokenFilePath(), token);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function createTokenExclusive(token: string): Promise<boolean> {
|
|
129
|
+
return createSecureTokenFileExclusive(getTokenFilePath(), token);
|
|
100
130
|
}
|
|
101
131
|
|
|
102
132
|
function generateToken(): string {
|
|
@@ -107,8 +137,19 @@ async function ensureToken(): Promise<string> {
|
|
|
107
137
|
const existing = await readToken();
|
|
108
138
|
if (existing) return existing;
|
|
109
139
|
const token = generateToken();
|
|
110
|
-
await
|
|
111
|
-
|
|
140
|
+
if (await createTokenExclusive(token)) return token;
|
|
141
|
+
// Another concurrent invocation won the create race. Its file may exist
|
|
142
|
+
// briefly before the winner writes the token, so retry reads without ever
|
|
143
|
+
// overwriting the winner's file.
|
|
144
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
145
|
+
const fromRace = await readToken();
|
|
146
|
+
if (fromRace) return fromRace;
|
|
147
|
+
if (attempt < 4) await Bun.sleep(10);
|
|
148
|
+
}
|
|
149
|
+
// If the file disappeared, make one final exclusive-create attempt. Never
|
|
150
|
+
// fall back to an unconditional write after observing EEXIST.
|
|
151
|
+
if (await createTokenExclusive(token)) return token;
|
|
152
|
+
throw new Error("Unable to initialize auth-broker token: another process owns an empty token file.");
|
|
112
153
|
}
|
|
113
154
|
|
|
114
155
|
async function runServe(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
@@ -133,7 +174,7 @@ async function runServe(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
133
174
|
logger.info("auth-broker bearer token loaded", { path: getTokenFilePath(), mode: "0600" });
|
|
134
175
|
|
|
135
176
|
const credentialDisabledUnsub = storage.onCredentialDisabled((event: CredentialDisabledEvent) => {
|
|
136
|
-
logger.warn("auth-broker credential disabled", {
|
|
177
|
+
logger.warn("auth-broker credential disabled", { provider: event.provider });
|
|
137
178
|
});
|
|
138
179
|
|
|
139
180
|
const shutdown = async (signal: NodeJS.Signals): Promise<void> => {
|
|
@@ -241,10 +282,11 @@ async function runLogout(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
241
282
|
if (!providerArg) {
|
|
242
283
|
throw new Error("Usage: gjc auth-broker logout <provider>");
|
|
243
284
|
}
|
|
285
|
+
const provider = resolveOAuthStorageProvider(providerArg);
|
|
244
286
|
const store = await SqliteAuthCredentialStore.open(getAgentDbPath());
|
|
245
287
|
try {
|
|
246
|
-
store.deleteAuthCredentialsForProvider(
|
|
247
|
-
process.stdout.write(`Logged out of ${
|
|
288
|
+
store.deleteAuthCredentialsForProvider(provider, "logged out by user");
|
|
289
|
+
process.stdout.write(`Logged out of ${provider}\n`);
|
|
248
290
|
} finally {
|
|
249
291
|
store.close();
|
|
250
292
|
}
|
|
@@ -338,7 +380,7 @@ async function loadImportPlan(
|
|
|
338
380
|
try {
|
|
339
381
|
json = (await Bun.file(file).json()) as CliProxyCredentialJson;
|
|
340
382
|
} catch (err) {
|
|
341
|
-
skipped.push({ file, reason: `unreadable JSON: ${
|
|
383
|
+
skipped.push({ file, reason: `unreadable JSON: ${safeDiagnostic(err, "unreadable JSON")}` });
|
|
342
384
|
continue;
|
|
343
385
|
}
|
|
344
386
|
if (json.disabled === true && !includeDisabled) {
|
|
@@ -415,14 +457,19 @@ async function runImport(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
415
457
|
disabled: e.disabled,
|
|
416
458
|
file: e.sourceFile,
|
|
417
459
|
})),
|
|
418
|
-
skipped
|
|
460
|
+
skipped: skipped.map(skip => ({
|
|
461
|
+
...skip,
|
|
462
|
+
reason: safeDiagnostic(skip.reason, "Credential import skipped."),
|
|
463
|
+
})),
|
|
419
464
|
})}\n`,
|
|
420
465
|
);
|
|
421
466
|
}
|
|
422
467
|
|
|
423
468
|
if (!flags.json) {
|
|
424
469
|
for (const skip of skipped) {
|
|
425
|
-
process.stdout.write(
|
|
470
|
+
process.stdout.write(
|
|
471
|
+
`${chalk.yellow("skip")} ${skip.file}: ${safeDiagnostic(skip.reason, "Credential import skipped.")}\n`,
|
|
472
|
+
);
|
|
426
473
|
}
|
|
427
474
|
}
|
|
428
475
|
|
|
@@ -439,7 +486,7 @@ async function runImport(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
439
486
|
return;
|
|
440
487
|
}
|
|
441
488
|
|
|
442
|
-
const brokerConfig = await
|
|
489
|
+
const brokerConfig = (await resolveStartupAuthConfig()).broker;
|
|
443
490
|
if (brokerConfig) {
|
|
444
491
|
const client = new AuthBrokerClient({ url: brokerConfig.url, token: brokerConfig.token });
|
|
445
492
|
for (const entry of entries) {
|
|
@@ -449,11 +496,14 @@ async function runImport(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
449
496
|
process.stdout.write(`${chalk.green("uploaded")} ${describeImportEntry(entry)} → ${brokerConfig.url}\n`);
|
|
450
497
|
}
|
|
451
498
|
} catch (error) {
|
|
452
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
453
499
|
if (flags.json) {
|
|
454
|
-
process.stdout.write(
|
|
500
|
+
process.stdout.write(
|
|
501
|
+
`${JSON.stringify({ ok: false, error: { code: "credential_import_failed", message: "Credential import failed." }, file: entry.sourceFile })}\n`,
|
|
502
|
+
);
|
|
455
503
|
} else {
|
|
456
|
-
process.stdout.write(
|
|
504
|
+
process.stdout.write(
|
|
505
|
+
`${chalk.red("failed")} ${describeImportEntry(entry)}: ${safeDiagnostic(error, "Credential import failed.")}\n`,
|
|
506
|
+
);
|
|
457
507
|
}
|
|
458
508
|
process.exitCode = 1;
|
|
459
509
|
}
|
|
@@ -531,7 +581,7 @@ function brokerAlreadyHas(existing: Map<string, Set<string>>, provider: string,
|
|
|
531
581
|
}
|
|
532
582
|
|
|
533
583
|
async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
534
|
-
const brokerConfig = await
|
|
584
|
+
const brokerConfig = (await resolveStartupAuthConfig()).broker;
|
|
535
585
|
if (!brokerConfig) {
|
|
536
586
|
throw new Error(
|
|
537
587
|
"GJC_AUTH_BROKER_URL must be set (or `auth.broker.url` in config.yml). `migrate` uploads local credentials to a configured broker.",
|
|
@@ -640,13 +690,16 @@ async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void>
|
|
|
640
690
|
`${JSON.stringify({
|
|
641
691
|
dryRun: flags.dryRun === true,
|
|
642
692
|
plan: plan.map(p => ({ source: p.source, provider: p.provider, identity: p.identity })),
|
|
643
|
-
skipped
|
|
693
|
+
skipped: skipped.map(skip => ({
|
|
694
|
+
...skip,
|
|
695
|
+
reason: safeDiagnostic(skip.reason, "Credential migration skipped."),
|
|
696
|
+
})),
|
|
644
697
|
})}\n`,
|
|
645
698
|
);
|
|
646
699
|
} else {
|
|
647
700
|
for (const skip of skipped) {
|
|
648
701
|
process.stdout.write(
|
|
649
|
-
`${chalk.yellow("skip")} [${skip.source}] ${skip.provider} ${skip.identity}: ${skip.reason}\n`,
|
|
702
|
+
`${chalk.yellow("skip")} [${skip.source}] ${skip.provider} ${skip.identity}: ${safeDiagnostic(skip.reason, "Credential migration skipped.")}\n`,
|
|
650
703
|
);
|
|
651
704
|
}
|
|
652
705
|
}
|
|
@@ -673,11 +726,14 @@ async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void>
|
|
|
673
726
|
process.stdout.write(`${chalk.green("uploaded")} [${entry.source}] ${entry.provider} ${entry.identity}\n`);
|
|
674
727
|
}
|
|
675
728
|
} catch (error) {
|
|
676
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
677
729
|
if (flags.json) {
|
|
678
|
-
process.stdout.write(
|
|
730
|
+
process.stdout.write(
|
|
731
|
+
`${JSON.stringify({ ok: false, error: { code: "credential_migration_failed", message: "Credential migration failed." }, provider: entry.provider })}\n`,
|
|
732
|
+
);
|
|
679
733
|
} else {
|
|
680
|
-
process.stdout.write(
|
|
734
|
+
process.stdout.write(
|
|
735
|
+
`${chalk.red("failed")} [${entry.source}] ${entry.provider}: ${safeDiagnostic(error, "Credential migration failed.")}\n`,
|
|
736
|
+
);
|
|
681
737
|
}
|
|
682
738
|
process.exitCode = 1;
|
|
683
739
|
}
|
|
@@ -685,10 +741,13 @@ async function runMigrate(flags: AuthBrokerCommandArgs["flags"]): Promise<void>
|
|
|
685
741
|
}
|
|
686
742
|
|
|
687
743
|
async function runStatus(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
688
|
-
const cfg = await
|
|
744
|
+
const cfg = (await resolveStartupAuthConfig()).broker;
|
|
689
745
|
if (!cfg) {
|
|
690
746
|
const message = "No auth-broker configured (set GJC_AUTH_BROKER_URL to enable).";
|
|
691
|
-
if (flags.json)
|
|
747
|
+
if (flags.json)
|
|
748
|
+
process.stdout.write(
|
|
749
|
+
`${JSON.stringify({ ok: false, error: { code: "broker_not_configured", message: "Auth broker is not configured." } })}\n`,
|
|
750
|
+
);
|
|
692
751
|
else process.stdout.write(`${chalk.yellow(message)}\n`);
|
|
693
752
|
return;
|
|
694
753
|
}
|
|
@@ -701,44 +760,55 @@ async function runStatus(flags: AuthBrokerCommandArgs["flags"]): Promise<void> {
|
|
|
701
760
|
process.stdout.write(`${chalk.green("OK")} ${cfg.url} (version=${health.version ?? "unknown"})\n`);
|
|
702
761
|
}
|
|
703
762
|
} catch (error) {
|
|
704
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
705
763
|
if (flags.json) {
|
|
706
|
-
process.stdout.write(
|
|
764
|
+
process.stdout.write(
|
|
765
|
+
`${JSON.stringify({ ok: false, url: cfg.url, error: { code: "broker_unavailable", message: "Auth broker is unavailable." } })}\n`,
|
|
766
|
+
);
|
|
707
767
|
} else {
|
|
708
|
-
process.stdout.write(
|
|
768
|
+
process.stdout.write(
|
|
769
|
+
`${chalk.red("FAILED")} ${cfg.url}: ${safeDiagnostic(error, "Auth broker is unavailable.")}\n`,
|
|
770
|
+
);
|
|
709
771
|
}
|
|
710
772
|
process.exitCode = 1;
|
|
711
773
|
}
|
|
712
774
|
}
|
|
713
775
|
|
|
714
776
|
export async function runAuthBrokerCommand(cmd: AuthBrokerCommandArgs): Promise<void> {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
777
|
+
try {
|
|
778
|
+
switch (cmd.action) {
|
|
779
|
+
case "serve":
|
|
780
|
+
await runServe(cmd.flags);
|
|
781
|
+
return;
|
|
782
|
+
case "token":
|
|
783
|
+
await runToken(cmd.flags);
|
|
784
|
+
return;
|
|
785
|
+
case "login":
|
|
786
|
+
await runLogin(cmd.flags);
|
|
787
|
+
return;
|
|
788
|
+
case "logout":
|
|
789
|
+
await runLogout(cmd.flags);
|
|
790
|
+
return;
|
|
791
|
+
case "import":
|
|
792
|
+
await runImport(cmd.flags);
|
|
793
|
+
return;
|
|
794
|
+
case "migrate":
|
|
795
|
+
await runMigrate(cmd.flags);
|
|
796
|
+
return;
|
|
797
|
+
case "status":
|
|
798
|
+
await runStatus(cmd.flags);
|
|
799
|
+
return;
|
|
800
|
+
default: {
|
|
801
|
+
// Exhaustive check.
|
|
802
|
+
const _exhaustive: never = cmd.action;
|
|
803
|
+
throw new Error(`Unknown auth-broker action: ${String(_exhaustive)}`);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
} catch (error) {
|
|
807
|
+
if (cmd.action === "status" || cmd.action === "import" || cmd.action === "migrate") {
|
|
808
|
+
writeCommandFailure(cmd.action, cmd.flags, error);
|
|
736
809
|
return;
|
|
737
|
-
default: {
|
|
738
|
-
// Exhaustive check.
|
|
739
|
-
const _exhaustive: never = cmd.action;
|
|
740
|
-
throw new Error(`Unknown auth-broker action: ${String(_exhaustive)}`);
|
|
741
810
|
}
|
|
811
|
+
throw error;
|
|
742
812
|
}
|
|
743
813
|
}
|
|
744
814
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* - `status` — prints the locally-stored gateway token and bind hint.
|
|
14
14
|
*/
|
|
15
15
|
import * as crypto from "node:crypto";
|
|
16
|
-
import * as fs from "node:fs/promises";
|
|
17
16
|
import * as path from "node:path";
|
|
17
|
+
import { cleanReason } from "@gajae-code/ai/auth-broker/redact";
|
|
18
18
|
import { startAuthGateway } from "@gajae-code/ai/auth-gateway/server";
|
|
19
19
|
import {
|
|
20
20
|
type Api,
|
|
@@ -28,9 +28,14 @@ import {
|
|
|
28
28
|
RemoteAuthCredentialStore,
|
|
29
29
|
type SnapshotResponse,
|
|
30
30
|
} from "@gajae-code/ai/core";
|
|
31
|
-
import { getConfigRootDir,
|
|
31
|
+
import { getConfigRootDir, VERSION } from "@gajae-code/utils";
|
|
32
32
|
import chalk from "chalk";
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
createSecureTokenFileExclusive,
|
|
35
|
+
readSecureTokenFile,
|
|
36
|
+
writeSecureTokenFile,
|
|
37
|
+
} from "../session/secure-token-file";
|
|
38
|
+
import { type AuthBrokerClientConfig, resolveStartupAuthConfig } from "../session/startup-auth-config";
|
|
34
39
|
|
|
35
40
|
export type AuthGatewayAction = "serve" | "token" | "status" | "check";
|
|
36
41
|
|
|
@@ -51,53 +56,51 @@ export interface AuthGatewayCommandArgs {
|
|
|
51
56
|
|
|
52
57
|
const ACTIONS: readonly AuthGatewayAction[] = ["serve", "token", "status", "check"];
|
|
53
58
|
|
|
59
|
+
type AuthGatewayCliErrorCode =
|
|
60
|
+
| "broker_not_configured"
|
|
61
|
+
| "broker_unavailable"
|
|
62
|
+
| "credential_check_failed"
|
|
63
|
+
| "auth_gateway_command_failed";
|
|
64
|
+
|
|
65
|
+
function stableErrorForAction(action: AuthGatewayAction): { code: AuthGatewayCliErrorCode; message: string } {
|
|
66
|
+
switch (action) {
|
|
67
|
+
case "status":
|
|
68
|
+
return { code: "broker_unavailable", message: "Auth broker is unavailable." };
|
|
69
|
+
case "check":
|
|
70
|
+
return { code: "credential_check_failed", message: "Credential check failed." };
|
|
71
|
+
default:
|
|
72
|
+
return { code: "auth_gateway_command_failed", message: "Auth gateway command failed." };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function safeDiagnostic(value: unknown, fallback: string): string {
|
|
77
|
+
return cleanReason(value) ?? fallback;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function writeCommandFailure(action: AuthGatewayAction, flags: AuthGatewayCommandArgs["flags"], error: unknown): void {
|
|
81
|
+
const stable = stableErrorForAction(action);
|
|
82
|
+
if (flags.json) {
|
|
83
|
+
process.stdout.write(`${JSON.stringify({ ok: false, error: stable })}\n`);
|
|
84
|
+
} else {
|
|
85
|
+
process.stderr.write(`${chalk.red("FAILED")} ${safeDiagnostic(error, stable.message)}\n`);
|
|
86
|
+
}
|
|
87
|
+
process.exitCode = 1;
|
|
88
|
+
}
|
|
89
|
+
|
|
54
90
|
function getTokenFilePath(): string {
|
|
55
91
|
return path.join(getConfigRootDir(), "auth-gateway.token");
|
|
56
92
|
}
|
|
57
93
|
|
|
58
94
|
async function readToken(): Promise<string | null> {
|
|
59
|
-
|
|
60
|
-
const raw = await Bun.file(getTokenFilePath()).text();
|
|
61
|
-
const trimmed = raw.trim();
|
|
62
|
-
return trimmed.length > 0 ? trimmed : null;
|
|
63
|
-
} catch (err) {
|
|
64
|
-
if (isEnoent(err)) return null;
|
|
65
|
-
throw err;
|
|
66
|
-
}
|
|
95
|
+
return readSecureTokenFile(getTokenFilePath());
|
|
67
96
|
}
|
|
68
97
|
|
|
69
98
|
async function writeToken(token: string): Promise<void> {
|
|
70
|
-
|
|
71
|
-
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
72
|
-
await fs.writeFile(file, token, { mode: 0o600 });
|
|
73
|
-
try {
|
|
74
|
-
await fs.chmod(file, 0o600);
|
|
75
|
-
} catch {
|
|
76
|
-
// Best-effort (e.g. Windows).
|
|
77
|
-
}
|
|
99
|
+
await writeSecureTokenFile(getTokenFilePath(), token);
|
|
78
100
|
}
|
|
79
101
|
|
|
80
|
-
/**
|
|
81
|
-
* Atomically create the token file, refusing to clobber an existing one.
|
|
82
|
-
* Returns `true` on success, `false` when the file already existed (so the
|
|
83
|
-
* caller re-reads it instead of racing another concurrent `ensureToken`).
|
|
84
|
-
*/
|
|
85
102
|
async function createTokenExclusive(token: string): Promise<boolean> {
|
|
86
|
-
|
|
87
|
-
await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
|
|
88
|
-
try {
|
|
89
|
-
// `wx` = O_CREAT | O_EXCL — fails with EEXIST if the file is already there.
|
|
90
|
-
await fs.writeFile(file, token, { flag: "wx", mode: 0o600 });
|
|
91
|
-
} catch (err) {
|
|
92
|
-
if ((err as NodeJS.ErrnoException).code === "EEXIST") return false;
|
|
93
|
-
throw err;
|
|
94
|
-
}
|
|
95
|
-
try {
|
|
96
|
-
await fs.chmod(file, 0o600);
|
|
97
|
-
} catch {
|
|
98
|
-
// Best-effort (e.g. Windows).
|
|
99
|
-
}
|
|
100
|
-
return true;
|
|
103
|
+
return createSecureTokenFileExclusive(getTokenFilePath(), token);
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
function generateToken(): string {
|
|
@@ -109,13 +112,18 @@ async function ensureToken(): Promise<string> {
|
|
|
109
112
|
if (existing) return existing;
|
|
110
113
|
const token = generateToken();
|
|
111
114
|
if (await createTokenExclusive(token)) return token;
|
|
112
|
-
// Another concurrent invocation won the create race
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
// Another concurrent invocation won the create race. Its file may exist
|
|
116
|
+
// briefly before the winner writes the token, so retry reads without ever
|
|
117
|
+
// overwriting the winner's file.
|
|
118
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
119
|
+
const fromRace = await readToken();
|
|
120
|
+
if (fromRace) return fromRace;
|
|
121
|
+
if (attempt < 4) await Bun.sleep(10);
|
|
122
|
+
}
|
|
123
|
+
// If the file disappeared, make one final exclusive-create attempt. Never
|
|
124
|
+
// fall back to an unconditional write after observing EEXIST.
|
|
125
|
+
if (await createTokenExclusive(token)) return token;
|
|
126
|
+
throw new Error("Unable to initialize auth-gateway token: another process owns an empty token file.");
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
function createBrokerClient(brokerConfig: AuthBrokerClientConfig): AuthBrokerClient {
|
|
@@ -129,7 +137,7 @@ async function fetchBrokerSnapshot(client: AuthBrokerClient): Promise<SnapshotRe
|
|
|
129
137
|
}
|
|
130
138
|
|
|
131
139
|
async function runServe(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
132
|
-
const brokerConfig = await
|
|
140
|
+
const brokerConfig = (await resolveStartupAuthConfig()).broker;
|
|
133
141
|
if (!brokerConfig) {
|
|
134
142
|
throw new Error(
|
|
135
143
|
"`gjc auth-gateway serve` requires GJC_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). The gateway is itself a broker client.",
|
|
@@ -243,12 +251,13 @@ async function runToken(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
|
243
251
|
|
|
244
252
|
async function runStatus(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
245
253
|
const token = await readToken();
|
|
246
|
-
const brokerConfig = await
|
|
254
|
+
const brokerConfig = (await resolveStartupAuthConfig()).broker;
|
|
247
255
|
const tokenFile = getTokenFilePath();
|
|
248
256
|
if (!brokerConfig) {
|
|
249
257
|
const status = {
|
|
250
258
|
ready: false,
|
|
251
|
-
reason: "
|
|
259
|
+
reason: "broker_not_configured",
|
|
260
|
+
error: { code: "broker_not_configured", message: "Auth broker is not configured." },
|
|
252
261
|
tokenFile,
|
|
253
262
|
tokenPresent: token !== null,
|
|
254
263
|
broker: null,
|
|
@@ -298,7 +307,6 @@ async function runStatus(flags: AuthGatewayCommandArgs["flags"]): Promise<void>
|
|
|
298
307
|
}
|
|
299
308
|
if (!tokenPresent) process.exitCode = 1;
|
|
300
309
|
} catch (error) {
|
|
301
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
302
310
|
const status = {
|
|
303
311
|
ready: false,
|
|
304
312
|
reason: "broker_unavailable",
|
|
@@ -307,12 +315,14 @@ async function runStatus(flags: AuthGatewayCommandArgs["flags"]): Promise<void>
|
|
|
307
315
|
broker: brokerConfig.url,
|
|
308
316
|
brokerConfigured: true,
|
|
309
317
|
brokerAuthenticated: false,
|
|
310
|
-
error: message,
|
|
318
|
+
error: { code: "broker_unavailable", message: "Auth broker is unavailable." },
|
|
311
319
|
};
|
|
312
320
|
if (flags.json) {
|
|
313
321
|
process.stdout.write(`${JSON.stringify(status)}\n`);
|
|
314
322
|
} else {
|
|
315
|
-
process.stdout.write(
|
|
323
|
+
process.stdout.write(
|
|
324
|
+
`${chalk.red("FAILED")} upstream broker: ${brokerConfig.url}: ${safeDiagnostic(error, "Auth broker is unavailable.")}\n`,
|
|
325
|
+
);
|
|
316
326
|
process.stdout.write(
|
|
317
327
|
`token: ${status.tokenPresent ? chalk.green("present") : chalk.red("missing")} at ${status.tokenFile}\n`,
|
|
318
328
|
);
|
|
@@ -322,23 +332,31 @@ async function runStatus(flags: AuthGatewayCommandArgs["flags"]): Promise<void>
|
|
|
322
332
|
}
|
|
323
333
|
|
|
324
334
|
export async function runAuthGatewayCommand(cmd: AuthGatewayCommandArgs): Promise<void> {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
335
|
+
try {
|
|
336
|
+
switch (cmd.action) {
|
|
337
|
+
case "serve":
|
|
338
|
+
await runServe(cmd.flags);
|
|
339
|
+
return;
|
|
340
|
+
case "token":
|
|
341
|
+
await runToken(cmd.flags);
|
|
342
|
+
return;
|
|
343
|
+
case "status":
|
|
344
|
+
await runStatus(cmd.flags);
|
|
345
|
+
return;
|
|
346
|
+
case "check":
|
|
347
|
+
await runCheck(cmd.flags);
|
|
348
|
+
return;
|
|
349
|
+
default: {
|
|
350
|
+
const _exhaustive: never = cmd.action;
|
|
351
|
+
throw new Error(`Unknown auth-gateway action: ${String(_exhaustive)}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} catch (error) {
|
|
355
|
+
if (cmd.action === "status" || cmd.action === "check") {
|
|
356
|
+
writeCommandFailure(cmd.action, cmd.flags, error);
|
|
337
357
|
return;
|
|
338
|
-
default: {
|
|
339
|
-
const _exhaustive: never = cmd.action;
|
|
340
|
-
throw new Error(`Unknown auth-gateway action: ${String(_exhaustive)}`);
|
|
341
358
|
}
|
|
359
|
+
throw error;
|
|
342
360
|
}
|
|
343
361
|
}
|
|
344
362
|
|
|
@@ -350,7 +368,7 @@ export async function runAuthGatewayCommand(cmd: AuthGatewayCommandArgs): Promis
|
|
|
350
368
|
* dedicated diagnostic is the only way to see which credentials failed.
|
|
351
369
|
*/
|
|
352
370
|
async function runCheck(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
353
|
-
const brokerConfig = await
|
|
371
|
+
const brokerConfig = (await resolveStartupAuthConfig()).broker;
|
|
354
372
|
if (!brokerConfig) {
|
|
355
373
|
throw new Error(
|
|
356
374
|
"`gjc auth-gateway check` requires GJC_AUTH_BROKER_URL (or `auth.broker.url`/`auth.broker.token` in config.yml). It probes the same credentials the gateway would serve.",
|
|
@@ -366,7 +384,11 @@ async function runCheck(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
|
366
384
|
const results = await storage.checkCredentials();
|
|
367
385
|
|
|
368
386
|
if (flags.json) {
|
|
369
|
-
|
|
387
|
+
const credentials = results.map(row => ({
|
|
388
|
+
...row,
|
|
389
|
+
...(row.reason ? { reason: safeDiagnostic(row.reason, "Credential check failed.") } : {}),
|
|
390
|
+
}));
|
|
391
|
+
process.stdout.write(`${JSON.stringify({ broker: brokerConfig.url, credentials }, null, 2)}\n`);
|
|
370
392
|
} else {
|
|
371
393
|
const grouped = new Map<string, typeof results>();
|
|
372
394
|
for (const row of results) {
|
|
@@ -389,7 +411,9 @@ async function runCheck(flags: AuthGatewayCommandArgs["flags"]): Promise<void> {
|
|
|
389
411
|
const identity =
|
|
390
412
|
row.email ?? row.accountId ?? (row.type === "api_key" ? "(api key)" : "(no identity on credential)");
|
|
391
413
|
const remote = row.remoteRefresh ? chalk.dim(" [remote-refresh]") : "";
|
|
392
|
-
const reason = row.reason
|
|
414
|
+
const reason = row.reason
|
|
415
|
+
? chalk.dim(` — ${safeDiagnostic(row.reason, "Credential check failed.")}`)
|
|
416
|
+
: "";
|
|
393
417
|
process.stdout.write(
|
|
394
418
|
` ${status} id=${row.id.toString().padStart(3)} ${row.type.padEnd(7)} ${identity}${remote}${reason}\n`,
|
|
395
419
|
);
|
package/src/cli/config-cli.ts
CHANGED
|
@@ -10,6 +10,9 @@ import type * as path from "node:path";
|
|
|
10
10
|
import { APP_NAME, getAgentDir } from "@gajae-code/utils";
|
|
11
11
|
import { YAML } from "bun";
|
|
12
12
|
import chalk from "chalk";
|
|
13
|
+
import { resolveModelProfileName } from "../config/model-profile-contract";
|
|
14
|
+
import { mergeModelProfiles } from "../config/model-profiles";
|
|
15
|
+
import { ModelsConfigFile } from "../config/model-registry";
|
|
13
16
|
import {
|
|
14
17
|
getDefault,
|
|
15
18
|
getEnumValues,
|
|
@@ -21,6 +24,7 @@ import {
|
|
|
21
24
|
type SettingValue,
|
|
22
25
|
settings,
|
|
23
26
|
} from "../config/settings";
|
|
27
|
+
import { resolveEagerTaskDelegation } from "../config/task-delegation";
|
|
24
28
|
import { theme } from "../modes/theme/theme";
|
|
25
29
|
import { initXdg } from "./commands/init-xdg";
|
|
26
30
|
|
|
@@ -449,17 +453,38 @@ function handlePath(): void {
|
|
|
449
453
|
console.log(getAgentDir());
|
|
450
454
|
}
|
|
451
455
|
|
|
456
|
+
/**
|
|
457
|
+
* Configuration conflicts that no schema check can see: an explicit
|
|
458
|
+
* `task.eager false` keeps a vendor-separated profile's workers unused, so the
|
|
459
|
+
* main provider's quota pays for work the layout meant to offload.
|
|
460
|
+
*/
|
|
461
|
+
export function collectConfigAdvisories(): string[] {
|
|
462
|
+
const profileName = settings.get("modelProfile.default");
|
|
463
|
+
const profiles = mergeModelProfiles(ModelsConfigFile.load()?.profiles);
|
|
464
|
+
const resolvedProfileName = profileName ? resolveModelProfileName(profileName, profiles) : undefined;
|
|
465
|
+
const delegation = resolveEagerTaskDelegation({
|
|
466
|
+
settings,
|
|
467
|
+
profile: resolvedProfileName ? profiles.get(resolvedProfileName) : undefined,
|
|
468
|
+
});
|
|
469
|
+
if (!delegation.suppressedByExplicitSetting) return [];
|
|
470
|
+
return [
|
|
471
|
+
`task.eager is false while ${delegation.vendorSeparatedRoles.join(" and ")} run on a different provider than the default role; those workers will not be used. Run \`${APP_NAME} config set task.eager true\` or reset task.eager to delegate by default.`,
|
|
472
|
+
];
|
|
473
|
+
}
|
|
474
|
+
|
|
452
475
|
function handleDoctor(flags: { json?: boolean }): void {
|
|
453
476
|
const report = settings.getSchemaReport();
|
|
477
|
+
const advisories = collectConfigAdvisories();
|
|
454
478
|
if (flags.json) {
|
|
455
|
-
console.log(JSON.stringify(report, null, 2));
|
|
479
|
+
console.log(JSON.stringify({ ...report, advisories }, null, 2));
|
|
456
480
|
return;
|
|
457
481
|
}
|
|
458
|
-
if (report.issues.length === 0) {
|
|
482
|
+
if (report.issues.length === 0 && advisories.length === 0) {
|
|
459
483
|
console.log(chalk.green("Settings schema is healthy."));
|
|
460
484
|
return;
|
|
461
485
|
}
|
|
462
486
|
for (const issue of report.issues) console.log(`${issue.kind}\t${issue.path}\t${issue.detail}`);
|
|
487
|
+
for (const advisory of advisories) console.log(chalk.yellow(`advisory\ttask.eager\t${advisory}`));
|
|
463
488
|
}
|
|
464
489
|
|
|
465
490
|
type ConfigDoctorReport = {
|