@gajae-code/coding-agent 0.18.11 → 0.19.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 +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
invalidateSessionTitleGeneration,
|
|
58
58
|
isSessionTitleGenerationCurrent,
|
|
59
59
|
} from "../utils/session-title-generation";
|
|
60
|
-
import { buildConversationTitleInput, generateSessionTitle } from "../utils/title-generator";
|
|
60
|
+
import { buildConversationTitleInput, generateSessionTitle, titleInputObfuscator } from "../utils/title-generator";
|
|
61
61
|
import { handleAsideAcp } from "./helpers/aside";
|
|
62
62
|
import { buildAutoroutingStatusReport } from "./helpers/autorouting-status";
|
|
63
63
|
import { buildContextReportText } from "./helpers/context-report";
|
|
@@ -66,6 +66,7 @@ import { buildFastStatusReport } from "./helpers/fast-status-report";
|
|
|
66
66
|
import { formatDuration } from "./helpers/format";
|
|
67
67
|
import { commandConsumed, errorMessage, parseSlashCommand, parseSubcommand, usage } from "./helpers/parse";
|
|
68
68
|
import { renderProgressReportLines, renderProgressReportText } from "./helpers/progress-report";
|
|
69
|
+
import { buildProviderAuthStatusText } from "./helpers/provider-auth-status";
|
|
69
70
|
import { handleSshAcp } from "./helpers/ssh";
|
|
70
71
|
import { buildUsageReportText, collectCachedUsageReports } from "./helpers/usage-report";
|
|
71
72
|
import type {
|
|
@@ -157,7 +158,9 @@ function toSlashCommandRuntime(runtime: TuiSlashCommandRuntime): SlashCommandRun
|
|
|
157
158
|
async function regenerateSessionTitle(runtime: SlashCommandRuntime): Promise<SlashCommandResult> {
|
|
158
159
|
try {
|
|
159
160
|
const generation = beginSessionTitleGeneration(runtime.sessionManager);
|
|
160
|
-
const
|
|
161
|
+
const activeCwd = runtime.sessionManager.getCwd();
|
|
162
|
+
const obfuscateText = await titleInputObfuscator(runtime.settings, activeCwd);
|
|
163
|
+
const input = buildConversationTitleInput(runtime.session.messages, obfuscateText);
|
|
161
164
|
if (!input) {
|
|
162
165
|
return usage("Nothing to summarize yet — pass a title: /rename <title>", runtime);
|
|
163
166
|
}
|
|
@@ -169,10 +172,11 @@ async function regenerateSessionTitle(runtime: SlashCommandRuntime): Promise<Sla
|
|
|
169
172
|
runtime.session.credentialSessionId,
|
|
170
173
|
runtime.session.model,
|
|
171
174
|
provider => runtime.session.agent.metadataForProvider(provider),
|
|
175
|
+
activeCwd,
|
|
172
176
|
);
|
|
173
177
|
if (
|
|
174
178
|
!isSessionTitleGenerationCurrent(runtime.sessionManager, generation) ||
|
|
175
|
-
buildConversationTitleInput(runtime.session.messages) !== input
|
|
179
|
+
buildConversationTitleInput(runtime.session.messages, obfuscateText) !== input
|
|
176
180
|
)
|
|
177
181
|
return commandConsumed();
|
|
178
182
|
if (!generated) {
|
|
@@ -292,6 +296,7 @@ function providerSetupUsage(): string {
|
|
|
292
296
|
"Aliases include minimax, zai, alibaba, cline, command-code, goat, and ionet.",
|
|
293
297
|
`API providers: ${MODEL_ONBOARDING_API_PROVIDER_COMMAND} [--force]`,
|
|
294
298
|
`Available presets:\n${formatProviderPresetList()}`,
|
|
299
|
+
"Credential status: /provider status",
|
|
295
300
|
"OAuth/subscription providers: /provider login [provider-id] or /login [provider-id]",
|
|
296
301
|
"Headless OAuth callbacks can be pasted with /login <redirect URL or code>.",
|
|
297
302
|
].join("\n");
|
|
@@ -1151,6 +1156,7 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1151
1156
|
if (!materializedProfile) {
|
|
1152
1157
|
for (const [targetId, selector] of assignments) {
|
|
1153
1158
|
const target = GJC_MODEL_ASSIGNMENT_TARGETS[targetId];
|
|
1159
|
+
runtime.session.markProfileRoleOverrideManual?.(target.settingsPath, targetId);
|
|
1154
1160
|
if (target.settingsPath === "modelRoles") {
|
|
1155
1161
|
runtime.settings.setModelRole(targetId, selector);
|
|
1156
1162
|
} else {
|
|
@@ -1653,7 +1659,7 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1653
1659
|
aliases: ["account"],
|
|
1654
1660
|
description: "Switch this session's active stored account, or list accounts",
|
|
1655
1661
|
acpDescription: "Switch or list stored credentials for this session",
|
|
1656
|
-
inlineHint: "[email:<addr>|id:<n>|account:<id>|project:<id>|provider/<selector>]",
|
|
1662
|
+
inlineHint: "[email:<addr>|id:<n>|account:<id>|project:<id>|org:<id|name>|provider/<selector>]",
|
|
1657
1663
|
acpInputHint: "[selector]",
|
|
1658
1664
|
allowArgs: true,
|
|
1659
1665
|
handle: async (command, runtime) => {
|
|
@@ -1899,8 +1905,8 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1899
1905
|
|
|
1900
1906
|
{
|
|
1901
1907
|
name: "provider",
|
|
1902
|
-
description: "
|
|
1903
|
-
inlineHint: "add|login",
|
|
1908
|
+
description: "Show provider credential status or set up providers",
|
|
1909
|
+
inlineHint: "status|add|login",
|
|
1904
1910
|
allowArgs: true,
|
|
1905
1911
|
handle: async (command, runtime) => {
|
|
1906
1912
|
const args = command.args.trim();
|
|
@@ -1908,6 +1914,10 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1908
1914
|
await runtime.output(providerSetupUsage());
|
|
1909
1915
|
return commandConsumed();
|
|
1910
1916
|
}
|
|
1917
|
+
if (args === "status") {
|
|
1918
|
+
await runtime.output(await buildProviderAuthStatusText(runtime.session));
|
|
1919
|
+
return commandConsumed();
|
|
1920
|
+
}
|
|
1911
1921
|
if (args === "login" || args.startsWith("login ")) {
|
|
1912
1922
|
const providerId = args.slice("login".length).trim();
|
|
1913
1923
|
const loginCommand = providerId ? `/login ${providerId}` : "/login [provider-id]";
|
|
@@ -1976,6 +1986,11 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
1976
1986
|
runtime.ctx.editor.setText("");
|
|
1977
1987
|
return;
|
|
1978
1988
|
}
|
|
1989
|
+
if (args === "status") {
|
|
1990
|
+
runtime.ctx.showStatus(await buildProviderAuthStatusText(runtime.ctx.session));
|
|
1991
|
+
runtime.ctx.editor.setText("");
|
|
1992
|
+
return;
|
|
1993
|
+
}
|
|
1979
1994
|
if (args === "help") {
|
|
1980
1995
|
runtime.ctx.showStatus(providerSetupUsage());
|
|
1981
1996
|
runtime.ctx.editor.setText("");
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type AuthCredentialSelector,
|
|
3
|
+
type AuthCredentialSnapshotEntry,
|
|
4
|
+
formatOAuthIdentityLabel,
|
|
5
|
+
oauthCredentialMatchesOrganization,
|
|
6
|
+
} from "@gajae-code/ai/core";
|
|
2
7
|
import { parseCliCredentialSelector } from "../../runtime-credential-selector";
|
|
3
8
|
import type { SlashCommandRuntime } from "../types";
|
|
4
9
|
|
|
5
10
|
/** Human-readable label for one stored OAuth credential row. */
|
|
6
11
|
function describeCredentialRow(entry: AuthCredentialSnapshotEntry): string {
|
|
7
12
|
if (entry.credential.type !== "oauth") return `id:${entry.id} (api key)`;
|
|
8
|
-
const
|
|
9
|
-
const accountId = entry.credential.accountId;
|
|
10
|
-
const label = email ?? accountId ?? `row ${entry.id}`;
|
|
13
|
+
const label = formatOAuthIdentityLabel(entry.credential) ?? `row ${entry.id}`;
|
|
11
14
|
return `id:${entry.id} — ${label}`;
|
|
12
15
|
}
|
|
13
16
|
|
|
@@ -33,6 +36,8 @@ function selectorMatchesRow(selector: AuthCredentialSelector, entry: AuthCredent
|
|
|
33
36
|
return entry.credential.accountId === selector.value;
|
|
34
37
|
case "project":
|
|
35
38
|
return entry.credential.projectId === selector.value;
|
|
39
|
+
case "org":
|
|
40
|
+
return oauthCredentialMatchesOrganization(entry.credential, selector.value);
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -116,7 +121,7 @@ export async function switchSessionCredentialCommand(runtime: SlashCommandRuntim
|
|
|
116
121
|
try {
|
|
117
122
|
parsed = parseCliCredentialSelector(trimmed);
|
|
118
123
|
} catch {
|
|
119
|
-
return `Invalid selector "${trimmed}". Use email:name@example.com, id:15, account:<id>, project:<id>, or provider/<selector>.`;
|
|
124
|
+
return `Invalid selector "${trimmed}". Use email:name@example.com, id:15, account:<id>, project:<id>, org:<organization id or name>, or provider/<selector>.`;
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
const authStorage = runtime.session.modelRegistry.authStorage;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getMCPConfigPath } from "@gajae-code/utils";
|
|
1
|
+
import { getMCPConfigPath, sanitizeDisplayLine } from "@gajae-code/utils";
|
|
2
2
|
import { listPrompts, listResources, listTools } from "../../runtime-mcp/client";
|
|
3
3
|
import {
|
|
4
4
|
addMCPServer,
|
|
@@ -19,6 +19,14 @@ import { commandConsumed, errorMessage, parseNamedScopeArgs, parseSubcommand, us
|
|
|
19
19
|
|
|
20
20
|
type AcpMcpScope = "user" | "project";
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* One terminal row for an untrusted MCP server or tool name.
|
|
24
|
+
* Ordinary names are unchanged. Controls, OSC, and line breaks are not.
|
|
25
|
+
*/
|
|
26
|
+
export function mcpTerminalLabel(value: string): string {
|
|
27
|
+
return sanitizeDisplayLine(value);
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
interface ParsedMcpAddArgs {
|
|
23
31
|
name?: string;
|
|
24
32
|
scope: AcpMcpScope;
|
|
@@ -272,7 +280,7 @@ async function handleTestCommand(rest: string, runtime: SlashCommandRuntime): Pr
|
|
|
272
280
|
return await withPreparedMcpConnection(runtime, name, server.config, server.scope, async connection => {
|
|
273
281
|
const tools = await listTools(connection);
|
|
274
282
|
const lines = [`Server "${name}" connected (${tools.length} tools).`];
|
|
275
|
-
for (const tool of tools) lines.push(` - ${tool.name}`);
|
|
283
|
+
for (const tool of tools) lines.push(` - ${mcpTerminalLabel(tool.name)}`);
|
|
276
284
|
await runtime.output(lines.join("\n"));
|
|
277
285
|
return commandConsumed();
|
|
278
286
|
});
|
|
@@ -398,7 +406,7 @@ async function handleListCommand(runtime: SlashCommandRuntime): Promise<SlashCom
|
|
|
398
406
|
} else {
|
|
399
407
|
location = (config as { command: string }).command;
|
|
400
408
|
}
|
|
401
|
-
return `${name} | ${type} | ${status} | ${location ?? "(unknown)"} [${scope}]`;
|
|
409
|
+
return `${mcpTerminalLabel(name)} | ${type} | ${status} | ${location ?? "(unknown)"} [${scope}]`;
|
|
402
410
|
})
|
|
403
411
|
.join("\n"),
|
|
404
412
|
);
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type AuthCredentialSnapshotEntry,
|
|
3
|
+
type EnvApiKeyCredentialSource,
|
|
4
|
+
getEnvApiKeyCredentialSources,
|
|
5
|
+
listProvidersWithEnvKey,
|
|
6
|
+
resolveOAuthStorageProvider,
|
|
7
|
+
} from "@gajae-code/ai/core";
|
|
8
|
+
import { replaceTabs, truncateToWidth, wrapTextWithAnsi } from "@gajae-code/tui";
|
|
9
|
+
import { $credentialEnv, sanitizeDisplayLine } from "@gajae-code/utils";
|
|
10
|
+
import type { ModelRegistry } from "../../config/model-registry";
|
|
11
|
+
import type { AgentSession } from "../../session/agent-session";
|
|
12
|
+
|
|
13
|
+
type ProviderAuthStatusSession = Pick<AgentSession, "credentialSessionId"> & {
|
|
14
|
+
modelRegistry: Pick<
|
|
15
|
+
ModelRegistry,
|
|
16
|
+
| "authStorage"
|
|
17
|
+
| "getAll"
|
|
18
|
+
| "getAvailable"
|
|
19
|
+
| "getConfiguredProviderIds"
|
|
20
|
+
| "getAuthStorageOwner"
|
|
21
|
+
| "getProviderConfigApiKeySources"
|
|
22
|
+
| "getProviderRuntimeApiKeyEnvName"
|
|
23
|
+
| "hasRuntimeProviderApiKey"
|
|
24
|
+
>;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
interface CredentialSource {
|
|
28
|
+
kind: "api_key" | "oauth";
|
|
29
|
+
layer: "runtime-override" | "runtime-provider" | "config" | "stored" | "environment" | "fallback" | "pending";
|
|
30
|
+
label: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type ConfigApiKeySource =
|
|
34
|
+
| { kind: "environment"; name: string; provider: string }
|
|
35
|
+
| { kind: "models-yml"; provider: string };
|
|
36
|
+
|
|
37
|
+
const MAX_STATUS_VALUE_WIDTH = 120;
|
|
38
|
+
|
|
39
|
+
function displayStatusValue(value: string): string {
|
|
40
|
+
const safe = replaceTabs(sanitizeDisplayLine(value))
|
|
41
|
+
.replaceAll(/[\u2028\u2029]/gu, " ")
|
|
42
|
+
.trim();
|
|
43
|
+
return truncateToWidth(safe, MAX_STATUS_VALUE_WIDTH).trim() || "unknown";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function displayAccountLabel(value: string): string {
|
|
47
|
+
return displayStatusValue(value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function displayEnvironmentName(value: string): string {
|
|
51
|
+
return displayStatusValue(value);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function oauthLabel(entry: AuthCredentialSnapshotEntry): string {
|
|
55
|
+
if (entry.credential.type !== "oauth") return `OAuth (stored credential id:${entry.id})`;
|
|
56
|
+
const account = entry.credential.accountId ?? entry.credential.email;
|
|
57
|
+
return account ? `OAuth (account ${displayAccountLabel(account)})` : `OAuth (stored credential id:${entry.id})`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function environmentCredentialLabel(name: string): string {
|
|
61
|
+
const safeName = displayEnvironmentName(name);
|
|
62
|
+
if (name.endsWith("_API_KEY")) return `API key (env ${safeName})`;
|
|
63
|
+
if (name.includes("OAUTH") || name.includes("ACCESS_TOKEN")) return `OAuth token (env ${safeName})`;
|
|
64
|
+
return `environment credential (env ${safeName})`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function environmentSourceLabel(source: EnvApiKeyCredentialSource): string {
|
|
68
|
+
switch (source.kind) {
|
|
69
|
+
case "environment":
|
|
70
|
+
return environmentCredentialLabel(source.name);
|
|
71
|
+
case "google-adc":
|
|
72
|
+
return source.source === "explicit-file"
|
|
73
|
+
? "Google ADC (env GOOGLE_APPLICATION_CREDENTIALS)"
|
|
74
|
+
: source.source === "default-file"
|
|
75
|
+
? "Google ADC (default credentials file)"
|
|
76
|
+
: "Google ADC (metadata server)";
|
|
77
|
+
case "aws":
|
|
78
|
+
return source.source === "bearer-token"
|
|
79
|
+
? "AWS bearer token (env AWS_BEARER_TOKEN_BEDROCK)"
|
|
80
|
+
: source.source === "environment-credentials"
|
|
81
|
+
? "AWS environment credentials"
|
|
82
|
+
: source.source === "profile"
|
|
83
|
+
? "AWS profile credentials"
|
|
84
|
+
: "AWS instance profile credentials";
|
|
85
|
+
case "unknown":
|
|
86
|
+
return "environment credentials";
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function configSourceLabel(source: ConfigApiKeySource, includeProvider = false): string {
|
|
91
|
+
return source.kind === "environment"
|
|
92
|
+
? `API key (env ${displayEnvironmentName(source.name)})`
|
|
93
|
+
: includeProvider
|
|
94
|
+
? `API key (models.yml ${displayStatusValue(source.provider)})`
|
|
95
|
+
: "API key (models.yml)";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function configSourcesVaryByAlias(sources: ConfigApiKeySource[]): boolean {
|
|
99
|
+
const byProvider = new Map<string, Set<string>>();
|
|
100
|
+
for (const source of sources) {
|
|
101
|
+
const identities = byProvider.get(source.provider) ?? new Set<string>();
|
|
102
|
+
identities.add(source.kind === "environment" ? `environment:${source.name}` : `models-yml:${source.provider}`);
|
|
103
|
+
byProvider.set(source.provider, identities);
|
|
104
|
+
}
|
|
105
|
+
const signatures = new Set([...byProvider.values()].map(identities => [...identities].sort().join("\u0000")));
|
|
106
|
+
return signatures.size > 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function addSource(sources: CredentialSource[], source: CredentialSource): void {
|
|
110
|
+
if (
|
|
111
|
+
!sources.some(
|
|
112
|
+
existing =>
|
|
113
|
+
existing.kind === source.kind && existing.layer === source.layer && existing.label === source.label,
|
|
114
|
+
)
|
|
115
|
+
) {
|
|
116
|
+
sources.push(source);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function hasRuntimeProviderCredential(registry: ProviderAuthStatusSession["modelRegistry"], provider: string): boolean {
|
|
121
|
+
const envName = registry.getProviderRuntimeApiKeyEnvName(provider);
|
|
122
|
+
return registry.hasRuntimeProviderApiKey(provider) && (envName === undefined || Boolean($credentialEnv(envName)));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function storedApiKeySource(
|
|
126
|
+
authStorage: ProviderAuthStatusSession["modelRegistry"]["authStorage"],
|
|
127
|
+
provider: string,
|
|
128
|
+
entries: AuthCredentialSnapshotEntry[],
|
|
129
|
+
rowId: number | undefined,
|
|
130
|
+
): Omit<CredentialSource, "kind"> | undefined {
|
|
131
|
+
const apiKeys = entries.filter(entry => entry.credential.type === "api_key");
|
|
132
|
+
const selected = rowId === undefined ? undefined : apiKeys.find(entry => entry.id === rowId);
|
|
133
|
+
if (selected?.credential.type === "api_key") {
|
|
134
|
+
const usability = authStorage.getStoredApiKeyUsability(provider, selected.id);
|
|
135
|
+
if (selected.credential.key.startsWith("!") && usability !== true) {
|
|
136
|
+
return {
|
|
137
|
+
layer: "pending",
|
|
138
|
+
label:
|
|
139
|
+
usability === false
|
|
140
|
+
? "API key (stored credential; retry pending)"
|
|
141
|
+
: "API key (stored credential; usability pending)",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return { layer: "stored", label: `API key (stored credential id:${selected.id})` };
|
|
145
|
+
}
|
|
146
|
+
const unknownCommandKey = apiKeys.some(
|
|
147
|
+
entry =>
|
|
148
|
+
entry.credential.type === "api_key" &&
|
|
149
|
+
entry.credential.key.startsWith("!") &&
|
|
150
|
+
authStorage.getStoredApiKeyUsability(provider, entry.id) === undefined,
|
|
151
|
+
);
|
|
152
|
+
if (unknownCommandKey) {
|
|
153
|
+
return { layer: "pending", label: "API key (stored credential; usability pending)" };
|
|
154
|
+
}
|
|
155
|
+
const retryableCommandKey = apiKeys.some(
|
|
156
|
+
entry =>
|
|
157
|
+
entry.credential.type === "api_key" &&
|
|
158
|
+
entry.credential.key.startsWith("!") &&
|
|
159
|
+
authStorage.getStoredApiKeyUsability(provider, entry.id) === false,
|
|
160
|
+
);
|
|
161
|
+
if (retryableCommandKey) {
|
|
162
|
+
return { layer: "pending", label: "API key (stored credential; retry pending)" };
|
|
163
|
+
}
|
|
164
|
+
const usableApiKeys = apiKeys.filter(entry => authStorage.getStoredApiKeyUsability(provider, entry.id) !== false);
|
|
165
|
+
if (usableApiKeys.length === 1) {
|
|
166
|
+
return { layer: "stored", label: `API key (stored credential id:${usableApiKeys[0]!.id})` };
|
|
167
|
+
}
|
|
168
|
+
if (usableApiKeys.length > 1) return { layer: "pending", label: "API key (stored credential; selection pending)" };
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function collectSources(
|
|
173
|
+
provider: string,
|
|
174
|
+
entries: AuthCredentialSnapshotEntry[],
|
|
175
|
+
registry: ProviderAuthStatusSession["modelRegistry"],
|
|
176
|
+
environmentSources: EnvApiKeyCredentialSource[],
|
|
177
|
+
usesBedrockResolver: boolean,
|
|
178
|
+
): CredentialSource[] {
|
|
179
|
+
const sources: CredentialSource[] = [];
|
|
180
|
+
if (usesBedrockResolver) {
|
|
181
|
+
for (const source of environmentSources) {
|
|
182
|
+
addSource(sources, { kind: "api_key", layer: "environment", label: environmentSourceLabel(source) });
|
|
183
|
+
}
|
|
184
|
+
return sources;
|
|
185
|
+
}
|
|
186
|
+
const authStorage = registry.authStorage;
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
if (entry.credential.type === "oauth") {
|
|
189
|
+
addSource(sources, { kind: "oauth", layer: "stored", label: oauthLabel(entry) });
|
|
190
|
+
} else {
|
|
191
|
+
if (authStorage.getStoredApiKeyUsability(provider, entry.id) === false) continue;
|
|
192
|
+
addSource(sources, {
|
|
193
|
+
kind: "api_key",
|
|
194
|
+
layer: "stored",
|
|
195
|
+
label: `API key (stored credential id:${entry.id})`,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (authStorage.hasRuntimeApiKey(provider)) {
|
|
201
|
+
addSource(sources, {
|
|
202
|
+
kind: "api_key",
|
|
203
|
+
layer: "runtime-override",
|
|
204
|
+
label: "API key (runtime override)",
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
const runtimeEnvName = registry.getProviderRuntimeApiKeyEnvName(provider);
|
|
208
|
+
if (
|
|
209
|
+
registry.hasRuntimeProviderApiKey(provider) &&
|
|
210
|
+
(runtimeEnvName === undefined || $credentialEnv(runtimeEnvName) !== undefined)
|
|
211
|
+
) {
|
|
212
|
+
addSource(sources, {
|
|
213
|
+
kind: "api_key",
|
|
214
|
+
layer: "runtime-provider",
|
|
215
|
+
label: runtimeEnvName
|
|
216
|
+
? `API key (env ${displayEnvironmentName(runtimeEnvName)})`
|
|
217
|
+
: "API key (runtime provider)",
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
for (const configSource of registry.getProviderConfigApiKeySources(provider)) {
|
|
221
|
+
addSource(sources, {
|
|
222
|
+
kind: "api_key",
|
|
223
|
+
layer: "config",
|
|
224
|
+
label: configSourceLabel(configSource),
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
for (const source of environmentSources) {
|
|
228
|
+
addSource(sources, { kind: "api_key", layer: "environment", label: environmentSourceLabel(source) });
|
|
229
|
+
}
|
|
230
|
+
return sources;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function activeSource(
|
|
234
|
+
provider: string,
|
|
235
|
+
entries: AuthCredentialSnapshotEntry[],
|
|
236
|
+
session: ProviderAuthStatusSession,
|
|
237
|
+
owner: object,
|
|
238
|
+
activeType: "api_key" | "oauth",
|
|
239
|
+
environmentSources: EnvApiKeyCredentialSource[],
|
|
240
|
+
usesBedrockResolver: boolean,
|
|
241
|
+
): CredentialSource {
|
|
242
|
+
if (usesBedrockResolver) {
|
|
243
|
+
const source = environmentSources[0];
|
|
244
|
+
return source
|
|
245
|
+
? { kind: "api_key", layer: "environment", label: environmentSourceLabel(source) }
|
|
246
|
+
: { kind: "api_key", layer: "pending", label: "AWS credentials unavailable" };
|
|
247
|
+
}
|
|
248
|
+
const { authStorage } = session.modelRegistry;
|
|
249
|
+
const sessionId = session.credentialSessionId;
|
|
250
|
+
if (activeType === "oauth") {
|
|
251
|
+
const pinnedRowId = authStorage.getSelectedOAuthCredentialRowId(provider, sessionId, { owner });
|
|
252
|
+
const preferredRowId = authStorage.getPreferredOAuthCredentialRowId(provider);
|
|
253
|
+
const sessionRowId = authStorage.getSessionCredentialRowId(provider, sessionId);
|
|
254
|
+
const availableSessionRowId =
|
|
255
|
+
sessionRowId !== undefined && authStorage.isCredentialAvailable(provider, sessionRowId)
|
|
256
|
+
? sessionRowId
|
|
257
|
+
: undefined;
|
|
258
|
+
const rowId = pinnedRowId ?? availableSessionRowId ?? preferredRowId;
|
|
259
|
+
const selected = rowId === undefined ? undefined : entries.find(entry => entry.id === rowId);
|
|
260
|
+
if (
|
|
261
|
+
selected?.credential.type === "oauth" &&
|
|
262
|
+
(pinnedRowId === rowId || authStorage.isCredentialAvailable(provider, selected.id))
|
|
263
|
+
) {
|
|
264
|
+
return { kind: "oauth", layer: "stored", label: oauthLabel(selected) };
|
|
265
|
+
}
|
|
266
|
+
const oauthEntries = entries.filter(
|
|
267
|
+
entry => entry.credential.type === "oauth" && authStorage.isCredentialAvailable(provider, entry.id),
|
|
268
|
+
);
|
|
269
|
+
if (oauthEntries.length === 1) return { kind: "oauth", layer: "stored", label: oauthLabel(oauthEntries[0]!) };
|
|
270
|
+
return {
|
|
271
|
+
kind: "oauth",
|
|
272
|
+
layer: "pending",
|
|
273
|
+
label: oauthEntries.length > 1 ? "OAuth (account selection pending)" : "OAuth (account unavailable)",
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (authStorage.hasRuntimeApiKey(provider)) {
|
|
278
|
+
return { kind: "api_key", layer: "runtime-override", label: "API key (runtime override)" };
|
|
279
|
+
}
|
|
280
|
+
const runtimeEnvName = session.modelRegistry.getProviderRuntimeApiKeyEnvName(provider);
|
|
281
|
+
if (
|
|
282
|
+
session.modelRegistry.hasRuntimeProviderApiKey(provider) &&
|
|
283
|
+
(runtimeEnvName === undefined || $credentialEnv(runtimeEnvName) !== undefined)
|
|
284
|
+
) {
|
|
285
|
+
return {
|
|
286
|
+
kind: "api_key",
|
|
287
|
+
layer: "runtime-provider",
|
|
288
|
+
label: runtimeEnvName
|
|
289
|
+
? `API key (env ${displayEnvironmentName(runtimeEnvName)})`
|
|
290
|
+
: "API key (runtime provider)",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const configSources = session.modelRegistry.getProviderConfigApiKeySources(provider);
|
|
294
|
+
if (authStorage.hasConfigApiKey(provider, owner) && configSources.length > 0) {
|
|
295
|
+
const configSource = configSources[0]!;
|
|
296
|
+
if (!authStorage.hasLiteralConfigApiKey(provider, owner)) {
|
|
297
|
+
const rowId = authStorage.getProspectiveApiKeyCredentialRowId(provider, sessionId, { owner });
|
|
298
|
+
const storedSource = storedApiKeySource(authStorage, provider, entries, rowId);
|
|
299
|
+
if (storedSource) return { kind: "api_key", ...storedSource };
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
kind: "api_key",
|
|
303
|
+
layer: "config",
|
|
304
|
+
label: configSourcesVaryByAlias(configSources)
|
|
305
|
+
? "API key (models.yml; source varies by provider alias)"
|
|
306
|
+
: configSourceLabel(configSource),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const selectedRowId = authStorage.getSelectedApiKeyCredentialRowId(provider, sessionId, { owner });
|
|
310
|
+
if (selectedRowId !== undefined && authStorage.getStoredApiKeyUsability(provider, selectedRowId) === false) {
|
|
311
|
+
return { kind: "api_key", layer: "pending", label: "API key (selected credential unavailable)" };
|
|
312
|
+
}
|
|
313
|
+
const rowId = authStorage.getProspectiveApiKeyCredentialRowId(provider, sessionId, { owner });
|
|
314
|
+
const storedSource = storedApiKeySource(authStorage, provider, entries, rowId);
|
|
315
|
+
if (storedSource) return { kind: "api_key", ...storedSource };
|
|
316
|
+
|
|
317
|
+
const envSource = environmentSources[0];
|
|
318
|
+
if (envSource) return { kind: "api_key", layer: "environment", label: environmentSourceLabel(envSource) };
|
|
319
|
+
return { kind: "api_key", layer: "fallback", label: "API key (configured)" };
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Format credential provenance for `/provider status` without returning credential values. */
|
|
323
|
+
export async function buildProviderAuthStatusText(session: ProviderAuthStatusSession): Promise<string> {
|
|
324
|
+
const { modelRegistry } = session;
|
|
325
|
+
// Status must reflect rotating env-backed keys even before another model selection runs.
|
|
326
|
+
modelRegistry.getAvailable();
|
|
327
|
+
const googleVertexSources = await getEnvApiKeyCredentialSources("google-vertex");
|
|
328
|
+
const bedrockCredentialSources = await getEnvApiKeyCredentialSources("amazon-bedrock");
|
|
329
|
+
const authStorage = modelRegistry.authStorage;
|
|
330
|
+
const owner = modelRegistry.getAuthStorageOwner();
|
|
331
|
+
const snapshot = authStorage.exportSnapshot();
|
|
332
|
+
const storedProviders = new Set(snapshot.credentials.map(entry => resolveOAuthStorageProvider(entry.provider)));
|
|
333
|
+
const models = modelRegistry.getAll();
|
|
334
|
+
const providerApis = new Map<string, Set<string>>();
|
|
335
|
+
for (const model of models) {
|
|
336
|
+
const provider = resolveOAuthStorageProvider(model.provider);
|
|
337
|
+
const apis = providerApis.get(provider) ?? new Set<string>();
|
|
338
|
+
apis.add(model.api);
|
|
339
|
+
providerApis.set(provider, apis);
|
|
340
|
+
}
|
|
341
|
+
const bedrockRouteProviders = new Set<string>();
|
|
342
|
+
const bedrockOnlyProviders = new Set<string>();
|
|
343
|
+
const googleVertexRouteProviders = new Set<string>();
|
|
344
|
+
for (const [provider, apis] of providerApis) {
|
|
345
|
+
if (apis.has("google-vertex")) googleVertexRouteProviders.add(provider);
|
|
346
|
+
if (!apis.has("bedrock-converse-stream")) continue;
|
|
347
|
+
bedrockRouteProviders.add(provider);
|
|
348
|
+
if (apis.size === 1) bedrockOnlyProviders.add(provider);
|
|
349
|
+
}
|
|
350
|
+
if (!providerApis.has("google-vertex")) googleVertexRouteProviders.add("google-vertex");
|
|
351
|
+
if (!providerApis.has("amazon-bedrock")) {
|
|
352
|
+
bedrockRouteProviders.add("amazon-bedrock");
|
|
353
|
+
bedrockOnlyProviders.add("amazon-bedrock");
|
|
354
|
+
}
|
|
355
|
+
const providerIds = new Set([
|
|
356
|
+
...models.map(model => resolveOAuthStorageProvider(model.provider)),
|
|
357
|
+
...modelRegistry.getConfiguredProviderIds().map(provider => resolveOAuthStorageProvider(provider)),
|
|
358
|
+
...snapshot.credentials.map(entry => resolveOAuthStorageProvider(entry.provider)),
|
|
359
|
+
...listProvidersWithEnvKey().map(provider => resolveOAuthStorageProvider(provider)),
|
|
360
|
+
]);
|
|
361
|
+
const providers = [...providerIds]
|
|
362
|
+
.filter(
|
|
363
|
+
provider =>
|
|
364
|
+
authStorage.hasSessionCredentialUnavailable(provider, session.credentialSessionId) ||
|
|
365
|
+
storedProviders.has(provider) ||
|
|
366
|
+
(googleVertexRouteProviders.has(provider)
|
|
367
|
+
? googleVertexSources.length > 0 ||
|
|
368
|
+
modelRegistry.getProviderConfigApiKeySources(provider).length > 0 ||
|
|
369
|
+
hasRuntimeProviderCredential(modelRegistry, provider) ||
|
|
370
|
+
authStorage.hasRuntimeApiKey(provider)
|
|
371
|
+
: bedrockRouteProviders.has(provider)
|
|
372
|
+
? bedrockCredentialSources.length > 0 ||
|
|
373
|
+
authStorage.hasAuth(provider, session.credentialSessionId, { owner })
|
|
374
|
+
: authStorage.hasAuth(provider, session.credentialSessionId, { owner })),
|
|
375
|
+
)
|
|
376
|
+
.sort((left, right) => left.localeCompare(right));
|
|
377
|
+
if (providers.length === 0) return "No configured provider credentials.";
|
|
378
|
+
|
|
379
|
+
const lines = ["Provider credentials (active source per provider):"];
|
|
380
|
+
for (const provider of providers) {
|
|
381
|
+
const entries = snapshot.credentials.filter(entry => resolveOAuthStorageProvider(entry.provider) === provider);
|
|
382
|
+
const configSources = modelRegistry.getProviderConfigApiKeySources(provider);
|
|
383
|
+
const usesBedrockResolver = bedrockOnlyProviders.has(provider);
|
|
384
|
+
const hasBedrockRoute = bedrockRouteProviders.has(provider);
|
|
385
|
+
const environmentSources = googleVertexRouteProviders.has(provider)
|
|
386
|
+
? googleVertexSources
|
|
387
|
+
: usesBedrockResolver
|
|
388
|
+
? bedrockCredentialSources
|
|
389
|
+
: await getEnvApiKeyCredentialSources(provider);
|
|
390
|
+
const activeType = authStorage.getEffectiveCredentialType(provider, session.credentialSessionId, { owner });
|
|
391
|
+
const sources = collectSources(provider, entries, modelRegistry, environmentSources, usesBedrockResolver);
|
|
392
|
+
const sessionCredentialUnavailable = authStorage.hasSessionCredentialUnavailable(
|
|
393
|
+
provider,
|
|
394
|
+
session.credentialSessionId,
|
|
395
|
+
);
|
|
396
|
+
let active: { kind: "api_key" | "oauth"; layer: string; label: string } | undefined;
|
|
397
|
+
if (usesBedrockResolver) {
|
|
398
|
+
active = activeSource(provider, entries, session, owner, "api_key", environmentSources, usesBedrockResolver);
|
|
399
|
+
} else if (activeType === "oauth" || activeType === "api_key") {
|
|
400
|
+
active = activeSource(provider, entries, session, owner, activeType, environmentSources, usesBedrockResolver);
|
|
401
|
+
} else if (environmentSources[0]) {
|
|
402
|
+
active = {
|
|
403
|
+
kind: "api_key" as const,
|
|
404
|
+
layer: "environment",
|
|
405
|
+
label: environmentSourceLabel(environmentSources[0]),
|
|
406
|
+
};
|
|
407
|
+
} else {
|
|
408
|
+
active = undefined;
|
|
409
|
+
}
|
|
410
|
+
const configOverridePrecedesUnavailablePin =
|
|
411
|
+
authStorage.hasConfigApiKey(provider, owner) &&
|
|
412
|
+
modelRegistry.getProviderConfigApiKeySources(provider).length > 0;
|
|
413
|
+
const overridePrecedesUnavailablePin =
|
|
414
|
+
active?.layer === "runtime-override" ||
|
|
415
|
+
active?.layer === "runtime-provider" ||
|
|
416
|
+
configOverridePrecedesUnavailablePin;
|
|
417
|
+
if (!usesBedrockResolver && sessionCredentialUnavailable && !overridePrecedesUnavailablePin) {
|
|
418
|
+
active = { kind: "api_key", layer: "pending", label: "selected credential unavailable" };
|
|
419
|
+
}
|
|
420
|
+
lines.push(
|
|
421
|
+
...wrapTextWithAnsi(
|
|
422
|
+
`${displayStatusValue(provider)}: ${active?.label ?? "credential source unavailable"}`,
|
|
423
|
+
MAX_STATUS_VALUE_WIDTH,
|
|
424
|
+
),
|
|
425
|
+
);
|
|
426
|
+
const configSourceVariesByAlias = active?.layer === "config" && configSourcesVaryByAlias(configSources);
|
|
427
|
+
if (configSourceVariesByAlias) {
|
|
428
|
+
const configuredSources = [...new Set(configSources.map(source => configSourceLabel(source, true)))];
|
|
429
|
+
lines.push(
|
|
430
|
+
...wrapTextWithAnsi(` configured sources: ${configuredSources.join(", ")}`, MAX_STATUS_VALUE_WIDTH),
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
if (hasBedrockRoute && !usesBedrockResolver) {
|
|
434
|
+
const bedrockRouteSource = bedrockCredentialSources[0];
|
|
435
|
+
const bedrockRouteLabel = bedrockRouteSource
|
|
436
|
+
? environmentSourceLabel(bedrockRouteSource)
|
|
437
|
+
: "AWS credentials unavailable";
|
|
438
|
+
lines.push(...wrapTextWithAnsi(` Bedrock route: ${bedrockRouteLabel}`, MAX_STATUS_VALUE_WIDTH));
|
|
439
|
+
}
|
|
440
|
+
const shadowed =
|
|
441
|
+
active && active.layer !== "pending"
|
|
442
|
+
? sources
|
|
443
|
+
.filter(
|
|
444
|
+
source =>
|
|
445
|
+
!(configSourceVariesByAlias && source.layer === "config") &&
|
|
446
|
+
source.label !== active.label &&
|
|
447
|
+
!(active.layer === "stored" && source.layer === "stored" && source.kind === active.kind),
|
|
448
|
+
)
|
|
449
|
+
.map(source => source.label)
|
|
450
|
+
: [];
|
|
451
|
+
if (shadowed.length > 0) {
|
|
452
|
+
lines.push(...wrapTextWithAnsi(` shadowed: ${[...new Set(shadowed)].join(", ")}`, MAX_STATUS_VALUE_WIDTH));
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return lines.join("\n");
|
|
456
|
+
}
|
package/src/ssh/ssh-executor.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { logger, ptree } from "@gajae-code/utils";
|
|
2
2
|
import { Settings } from "../config/settings";
|
|
3
|
-
import { OutputSink } from "../session/streaming-output";
|
|
3
|
+
import { OutputSink, type TerminalArtifactPublisher } from "../session/streaming-output";
|
|
4
4
|
import { resolveOutputMaxColumns, resolveOutputSinkHeadBytes } from "../tools/output-meta";
|
|
5
5
|
import { buildRemoteCommand, ensureConnection, ensureHostInfo, type SSHConnectionTarget } from "./connection-manager";
|
|
6
6
|
import { hasSshfs, mountRemote } from "./sshfs-mount";
|
|
@@ -21,6 +21,8 @@ export interface SSHExecutorOptions {
|
|
|
21
21
|
/** Artifact path/id for full output storage */
|
|
22
22
|
artifactPath?: string;
|
|
23
23
|
artifactId?: string;
|
|
24
|
+
/** Session-owned publisher for managed sessions without a writable artifact path. */
|
|
25
|
+
artifactPublisher?: TerminalArtifactPublisher;
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface SSHResult {
|
|
@@ -40,8 +42,12 @@ export interface SSHResult {
|
|
|
40
42
|
outputLines: number;
|
|
41
43
|
/** Number of bytes included in the output text */
|
|
42
44
|
outputBytes: number;
|
|
43
|
-
/** Artifact ID if
|
|
45
|
+
/** Artifact ID if output was saved to artifact storage. */
|
|
44
46
|
artifactId?: string;
|
|
47
|
+
/** Bytes omitted from artifact storage after its hard cap was reached. */
|
|
48
|
+
artifactTruncatedBytes?: number;
|
|
49
|
+
/** Bounded diagnostic when artifact storage failed. */
|
|
50
|
+
artifactFailureDiagnostic?: string;
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
function quoteForCompatShell(command: string): string {
|
|
@@ -92,6 +98,7 @@ export async function executeSSH(
|
|
|
92
98
|
onChunk: options?.onChunk,
|
|
93
99
|
artifactPath: options?.artifactPath,
|
|
94
100
|
artifactId: options?.artifactId,
|
|
101
|
+
artifactPublisher: options?.artifactPublisher,
|
|
95
102
|
headBytes: resolveOutputSinkHeadBytes(settings),
|
|
96
103
|
maxColumns: resolveOutputMaxColumns(settings),
|
|
97
104
|
});
|