@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
|
@@ -5,7 +5,7 @@ import type { CompactionOutcome } from "@gajae-code/agent-core/compaction";
|
|
|
5
5
|
import { type Model, modelsAreEqual } from "@gajae-code/ai/core";
|
|
6
6
|
import { Container, type KeyId, Markdown, Spacer, Text } from "@gajae-code/tui";
|
|
7
7
|
import { isEnoent, prompt } from "@gajae-code/utils";
|
|
8
|
-
import { resolveLocalUrlToPath } from "../../internal-urls";
|
|
8
|
+
import { resolveLocalRoot, resolveLocalUrlToPath } from "../../internal-urls";
|
|
9
9
|
import { humanizePlanTitle, type PlanApprovalDetails, resolvePlanTitle } from "../../plan-mode/approved-plan";
|
|
10
10
|
import planModeApprovedPrompt from "../../prompts/system/plan-mode-approved.md" with { type: "text" };
|
|
11
11
|
import planModeCompactInstructionsPrompt from "../../prompts/system/plan-mode-compact-instructions.md" with {
|
|
@@ -13,6 +13,7 @@ import planModeCompactInstructionsPrompt from "../../prompts/system/plan-mode-co
|
|
|
13
13
|
};
|
|
14
14
|
import type { AgentSession, TemporaryProviderSessionScope } from "../../session/agent-session";
|
|
15
15
|
import type { SessionContext, SessionManager } from "../../session/session-manager";
|
|
16
|
+
import { writeFileAtomically } from "../../tools/atomic-file-write";
|
|
16
17
|
import { normalizeLocalScheme } from "../../tools/path-utils";
|
|
17
18
|
import { type ResolveToolDetails, runResolveInvocation } from "../../tools/resolve";
|
|
18
19
|
import { ToolError } from "../../tools/tool-errors";
|
|
@@ -63,6 +64,7 @@ export class PlanModeController {
|
|
|
63
64
|
#paused = false;
|
|
64
65
|
#planFilePath: string | undefined;
|
|
65
66
|
#previousTools: string[] | undefined;
|
|
67
|
+
#previousMCPToolNames: string[] | undefined;
|
|
66
68
|
#previousModelState: { model: Model; thinkingLevel?: ThinkingLevel } | undefined;
|
|
67
69
|
#pendingModelSwitch: { model: Model; thinkingLevel?: ThinkingLevel } | undefined;
|
|
68
70
|
#providerSessionScope: TemporaryProviderSessionScope | undefined;
|
|
@@ -125,6 +127,7 @@ export class PlanModeController {
|
|
|
125
127
|
const planFilePath = options?.planFilePath ?? "local://PLAN.md";
|
|
126
128
|
const previousTools = this.ctx.session.getActiveToolNames();
|
|
127
129
|
this.#previousTools = previousTools;
|
|
130
|
+
this.#previousMCPToolNames = this.ctx.session.getActiveMCPToolNames();
|
|
128
131
|
this.#planFilePath = planFilePath;
|
|
129
132
|
this.#enabled = true;
|
|
130
133
|
const planTools = this.ctx.session.isExplicitEmptyToolSelection()
|
|
@@ -132,7 +135,20 @@ export class PlanModeController {
|
|
|
132
135
|
: this.ctx.session.getToolByName("resolve")
|
|
133
136
|
? [...new Set([...previousTools, "resolve"])]
|
|
134
137
|
: previousTools;
|
|
135
|
-
|
|
138
|
+
try {
|
|
139
|
+
await this.ctx.session.setActiveToolsByName(planTools, {
|
|
140
|
+
explicit: false,
|
|
141
|
+
persistMCPSelection: false,
|
|
142
|
+
retryOnMcpCatalogChange: true,
|
|
143
|
+
});
|
|
144
|
+
} catch (error) {
|
|
145
|
+
this.#enabled = false;
|
|
146
|
+
this.#planFilePath = undefined;
|
|
147
|
+
this.#previousTools = undefined;
|
|
148
|
+
this.#previousMCPToolNames = undefined;
|
|
149
|
+
this.ctx.modeGate.exit("plan");
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
136
152
|
this.ctx.session.setPlanModeState({
|
|
137
153
|
enabled: true,
|
|
138
154
|
planFilePath,
|
|
@@ -151,7 +167,12 @@ export class PlanModeController {
|
|
|
151
167
|
async exit(options?: { silent?: boolean; paused?: boolean }): Promise<void> {
|
|
152
168
|
if (!this.#enabled) return;
|
|
153
169
|
await this.ctx.session.abort({ timeoutMs: ABORT_TIMEOUT_MS });
|
|
154
|
-
if (this.#previousTools !== undefined)
|
|
170
|
+
if (this.#previousTools !== undefined)
|
|
171
|
+
await this.ctx.session.setActiveToolsByName(this.#restoreToolsWithCurrentMCPSelection(this.#previousTools), {
|
|
172
|
+
explicit: false,
|
|
173
|
+
persistMCPSelection: false,
|
|
174
|
+
retryOnMcpCatalogChange: true,
|
|
175
|
+
});
|
|
155
176
|
if (this.#providerSessionScope && !this.ctx.session.isStreaming) {
|
|
156
177
|
if (await this.ctx.session.restoreTemporaryProviderSessionScope(this.#providerSessionScope))
|
|
157
178
|
this.#providerSessionScope = undefined;
|
|
@@ -175,6 +196,7 @@ export class PlanModeController {
|
|
|
175
196
|
this.#paused = options?.paused ?? false;
|
|
176
197
|
this.#planFilePath = undefined;
|
|
177
198
|
this.#previousTools = undefined;
|
|
199
|
+
this.#previousMCPToolNames = undefined;
|
|
178
200
|
this.#previousModelState = undefined;
|
|
179
201
|
if (!this.#paused) this.ctx.modeGate.exit("plan");
|
|
180
202
|
this.#updateStatus();
|
|
@@ -182,6 +204,16 @@ export class PlanModeController {
|
|
|
182
204
|
if (!options?.silent) this.ctx.showStatus(this.#paused ? "Plan mode paused." : "Plan mode disabled.");
|
|
183
205
|
}
|
|
184
206
|
|
|
207
|
+
#restoreToolsWithCurrentMCPSelection(previousTools: readonly string[]): string[] {
|
|
208
|
+
const previousMCPToolNames = new Set(this.#previousMCPToolNames ?? []);
|
|
209
|
+
return [
|
|
210
|
+
...new Set([
|
|
211
|
+
...previousTools.filter(name => !previousMCPToolNames.has(name)),
|
|
212
|
+
...this.ctx.session.getActiveMCPToolNames(),
|
|
213
|
+
]),
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
|
|
185
217
|
async flushPendingModelSwitch(): Promise<void> {
|
|
186
218
|
const pending = this.#pendingModelSwitch;
|
|
187
219
|
if (!pending) return;
|
|
@@ -338,13 +370,16 @@ export class PlanModeController {
|
|
|
338
370
|
throw error;
|
|
339
371
|
}
|
|
340
372
|
}
|
|
373
|
+
#localProtocolOptions() {
|
|
374
|
+
return {
|
|
375
|
+
getArtifactsDir: () => this.ctx.sessionManager.getArtifactsDir(),
|
|
376
|
+
isManagedDestination: () => this.ctx.sessionManager.isManagedDestination(),
|
|
377
|
+
getSessionId: () => this.ctx.sessionManager.getSessionId(),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
341
380
|
#resolvePath(planFilePath: string): string {
|
|
342
381
|
return planFilePath.startsWith("local:")
|
|
343
|
-
? resolveLocalUrlToPath(normalizeLocalScheme(planFilePath),
|
|
344
|
-
getArtifactsDir: () => this.ctx.sessionManager.getArtifactsDir(),
|
|
345
|
-
isManagedDestination: () => this.ctx.sessionManager.isManagedDestination(),
|
|
346
|
-
getSessionId: () => this.ctx.sessionManager.getSessionId(),
|
|
347
|
-
})
|
|
382
|
+
? resolveLocalUrlToPath(normalizeLocalScheme(planFilePath), this.#localProtocolOptions())
|
|
348
383
|
: path.resolve(this.ctx.sessionManager.getCwd(), planFilePath);
|
|
349
384
|
}
|
|
350
385
|
async #finalizeApprovedPlan(planContent: string, planFilePath: string, finalPlanFilePath: string): Promise<void> {
|
|
@@ -420,7 +455,13 @@ export class PlanModeController {
|
|
|
420
455
|
trimTrailingNewline: false,
|
|
421
456
|
});
|
|
422
457
|
if (result !== null) {
|
|
423
|
-
|
|
458
|
+
// Lexical local:// checks do not see a symlink. Bind this save to the
|
|
459
|
+
// same local root so a link inside it cannot publish outside.
|
|
460
|
+
if (planFilePath.startsWith("local:")) {
|
|
461
|
+
await writeFileAtomically(resolved, result, {
|
|
462
|
+
trustBoundary: path.resolve(resolveLocalRoot(this.#localProtocolOptions())),
|
|
463
|
+
});
|
|
464
|
+
} else await Bun.write(resolved, result);
|
|
424
465
|
this.ctx.showStatus("Plan updated in external editor.");
|
|
425
466
|
}
|
|
426
467
|
return result;
|
|
@@ -445,12 +486,17 @@ export class PlanModeController {
|
|
|
445
486
|
},
|
|
446
487
|
): Promise<void> {
|
|
447
488
|
await this.#finalizeApprovedPlan(planContent, options.planFilePath, options.finalPlanFilePath);
|
|
448
|
-
const
|
|
489
|
+
const previousMCPToolNames = new Set(this.#previousMCPToolNames ?? this.ctx.session.getActiveMCPToolNames());
|
|
490
|
+
const previousNonMCPToolNames = (this.#previousTools ?? this.ctx.session.getActiveToolNames()).filter(
|
|
491
|
+
name => !previousMCPToolNames.has(name),
|
|
492
|
+
);
|
|
449
493
|
if (options.compactBeforeExecute) this.ctx.session.markPlanCompactAbortPending();
|
|
450
494
|
let sessionSwitchCompleted = true;
|
|
451
495
|
let compactOutcome: CompactionOutcome | undefined;
|
|
496
|
+
let mcpToolNamesBeforeSessionSwitch: string[] = [];
|
|
452
497
|
try {
|
|
453
498
|
await this.exit({ silent: true });
|
|
499
|
+
mcpToolNamesBeforeSessionSwitch = this.ctx.session.getActiveMCPToolNames();
|
|
454
500
|
if (!options.preserveContext) {
|
|
455
501
|
sessionSwitchCompleted = await this.ctx.handleClearCommand();
|
|
456
502
|
if (sessionSwitchCompleted)
|
|
@@ -478,7 +524,16 @@ export class PlanModeController {
|
|
|
478
524
|
} finally {
|
|
479
525
|
this.ctx.session.clearPlanCompactAbortPending();
|
|
480
526
|
}
|
|
481
|
-
|
|
527
|
+
const currentMCPToolNames = this.ctx.session.getActiveMCPToolNames();
|
|
528
|
+
const restoredMCPToolNames = this.ctx.session.hasMCPToolSelectionAuthority()
|
|
529
|
+
? currentMCPToolNames
|
|
530
|
+
: [...mcpToolNamesBeforeSessionSwitch, ...currentMCPToolNames];
|
|
531
|
+
const restoredTools = [...new Set([...previousNonMCPToolNames, ...restoredMCPToolNames])];
|
|
532
|
+
if (restoredTools.length)
|
|
533
|
+
await this.ctx.session.setActiveToolsByName(restoredTools, {
|
|
534
|
+
explicit: false,
|
|
535
|
+
persistMCPSelection: !options.preserveContext && sessionSwitchCompleted,
|
|
536
|
+
});
|
|
482
537
|
if (!sessionSwitchCompleted)
|
|
483
538
|
return this.ctx.showWarning(
|
|
484
539
|
"Plan approved, but the new session could not be created — execution was not dispatched.",
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
} from "../../runtime-mcp/smithery-registry";
|
|
38
38
|
import type { MCPAuthConfig, MCPServerConfig } from "../../runtime-mcp/types";
|
|
39
39
|
import type { OAuthCredential } from "../../session/auth-storage";
|
|
40
|
+
import { mcpTerminalLabel } from "../../slash-commands/helpers/mcp";
|
|
40
41
|
import { shortenPath } from "../../tools/render-utils";
|
|
41
42
|
import { openPath } from "../../utils/open";
|
|
42
43
|
import { CommandPalette, type CommandPaletteEntry } from "../components/command-palette";
|
|
@@ -1150,7 +1151,7 @@ export class MCPCommandController {
|
|
|
1150
1151
|
: state === "connecting"
|
|
1151
1152
|
? theme.fg("muted", " ◌ connecting")
|
|
1152
1153
|
: theme.fg("muted", " ○ not connected");
|
|
1153
|
-
lines.push(` ${theme.fg("accent", name)}${status} ${theme.fg("dim", `[${type}]`)}`);
|
|
1154
|
+
lines.push(` ${theme.fg("accent", mcpTerminalLabel(name))}${status} ${theme.fg("dim", `[${type}]`)}`);
|
|
1154
1155
|
}
|
|
1155
1156
|
lines.push("");
|
|
1156
1157
|
}
|
|
@@ -1173,7 +1174,7 @@ export class MCPCommandController {
|
|
|
1173
1174
|
: state === "connecting"
|
|
1174
1175
|
? theme.fg("muted", " ◌ connecting")
|
|
1175
1176
|
: theme.fg("muted", " ○ not connected");
|
|
1176
|
-
lines.push(` ${theme.fg("accent", name)}${status} ${theme.fg("dim", `[${type}]`)}`);
|
|
1177
|
+
lines.push(` ${theme.fg("accent", mcpTerminalLabel(name))}${status} ${theme.fg("dim", `[${type}]`)}`);
|
|
1177
1178
|
}
|
|
1178
1179
|
lines.push("");
|
|
1179
1180
|
}
|
|
@@ -1190,7 +1191,7 @@ export class MCPCommandController {
|
|
|
1190
1191
|
: state === "connecting"
|
|
1191
1192
|
? theme.fg("muted", " ◌ connecting")
|
|
1192
1193
|
: theme.fg("muted", " ○ not connected");
|
|
1193
|
-
lines.push(` ${theme.fg("accent", name)}${status}`);
|
|
1194
|
+
lines.push(` ${theme.fg("accent", mcpTerminalLabel(name))}${status}`);
|
|
1194
1195
|
}
|
|
1195
1196
|
lines.push("");
|
|
1196
1197
|
}
|
|
@@ -1201,7 +1202,7 @@ export class MCPCommandController {
|
|
|
1201
1202
|
if (relevantDisabled.length > 0) {
|
|
1202
1203
|
lines.push(theme.fg("accent", "Disabled") + theme.fg("muted", " (discovered servers):"));
|
|
1203
1204
|
for (const name of relevantDisabled) {
|
|
1204
|
-
lines.push(` ${theme.fg("accent", name)}${theme.fg("warning", " ◌ disabled")}`);
|
|
1205
|
+
lines.push(` ${theme.fg("accent", mcpTerminalLabel(name))}${theme.fg("warning", " ◌ disabled")}`);
|
|
1205
1206
|
}
|
|
1206
1207
|
lines.push("");
|
|
1207
1208
|
}
|
|
@@ -1310,13 +1311,13 @@ export class MCPCommandController {
|
|
|
1310
1311
|
"",
|
|
1311
1312
|
theme.fg("success", `✓ Successfully connected to "${name}"`),
|
|
1312
1313
|
"",
|
|
1313
|
-
` Server: ${connection.serverInfo.name} v${connection.serverInfo.version}`,
|
|
1314
|
+
` Server: ${mcpTerminalLabel(connection.serverInfo.name)} v${mcpTerminalLabel(connection.serverInfo.version)}`,
|
|
1314
1315
|
` Tools: ${tools.length}`,
|
|
1315
1316
|
];
|
|
1316
1317
|
|
|
1317
1318
|
if (tools.length > 0 && tools.length <= 10) {
|
|
1318
1319
|
lines.push("", " Available tools:");
|
|
1319
|
-
for (const tool of tools) lines.push(` • ${tool.name}`);
|
|
1320
|
+
for (const tool of tools) lines.push(` • ${mcpTerminalLabel(tool.name)}`);
|
|
1320
1321
|
}
|
|
1321
1322
|
|
|
1322
1323
|
lines.push("");
|
|
@@ -107,7 +107,10 @@ import { ensureTelegramDaemonRunningDetailed, resolveTelegramSetupPreflight } fr
|
|
|
107
107
|
import { TelegramDaemonController } from "../../sdk/bus/telegram-daemon-control";
|
|
108
108
|
import { runTelegramSetup, type TelegramSetupPreflight } from "../../sdk/bus/telegram-setup";
|
|
109
109
|
import { clearPersistentPinForRemovedRows } from "../../session/account-inventory";
|
|
110
|
-
import type {
|
|
110
|
+
import type {
|
|
111
|
+
AgentSessionProfileInstalledOverrideState,
|
|
112
|
+
DefaultFallbackRuntimeState,
|
|
113
|
+
} from "../../session/agent-session";
|
|
111
114
|
import { CREDENTIAL_STORE_UNREADABLE_MESSAGE } from "../../session/credential-store-errors";
|
|
112
115
|
import { type SessionInfo, SessionManager } from "../../session/session-manager";
|
|
113
116
|
import { getTreeForInternalRead } from "../../session/session-manager-internal";
|
|
@@ -1214,6 +1217,7 @@ interface DefaultAssignmentRollbackSnapshot {
|
|
|
1214
1217
|
profileOverride: SettingValue<"modelProfile.default"> | undefined;
|
|
1215
1218
|
chain: { entries: readonly string[]; origin: string; identity?: string; explicitHead?: boolean } | undefined;
|
|
1216
1219
|
activeProfile: string | undefined;
|
|
1220
|
+
profileInstalledOverrideState: AgentSessionProfileInstalledOverrideState | undefined;
|
|
1217
1221
|
canonicalVariant: string | undefined;
|
|
1218
1222
|
resumeDefaultSelector: string | undefined;
|
|
1219
1223
|
fallbackRuntimeState: DefaultFallbackRuntimeState;
|
|
@@ -1248,6 +1252,10 @@ function rawAutoroutingState(current: RawSettings): {
|
|
|
1248
1252
|
|
|
1249
1253
|
export class SelectorController {
|
|
1250
1254
|
#smartRoutingInFlight?: Promise<unknown>;
|
|
1255
|
+
#modelSelector?: ModelSelectorComponent;
|
|
1256
|
+
#settingsSelector?: SettingsSelectorComponent;
|
|
1257
|
+
#statusLinePreview?: Partial<StatusLineSettings>;
|
|
1258
|
+
#statusLinePreviewActive = false;
|
|
1251
1259
|
#transcriptViewerOpen = false;
|
|
1252
1260
|
#transcriptViewer?: TranscriptViewerOverlay;
|
|
1253
1261
|
#sessionsDashboardOpen = false;
|
|
@@ -1277,6 +1285,7 @@ export class SelectorController {
|
|
|
1277
1285
|
profileOverride: this.ctx.settings.getOverride("modelProfile.default"),
|
|
1278
1286
|
chain: this.ctx.session.getConfiguredModelChainState("default"),
|
|
1279
1287
|
activeProfile: this.ctx.session.getActiveModelProfile?.(),
|
|
1288
|
+
profileInstalledOverrideState: this.ctx.session.getProfileInstalledOverrideState?.(),
|
|
1280
1289
|
canonicalVariant: this.ctx.session.modelRegistry.getSessionCanonicalVariant?.(this.ctx.session.sessionId),
|
|
1281
1290
|
resumeDefaultSelector: this.ctx.session.sessionManager.buildSessionContext().models.default,
|
|
1282
1291
|
fallbackRuntimeState: this.ctx.session.getDefaultFallbackRuntimeState(),
|
|
@@ -1354,6 +1363,11 @@ export class SelectorController {
|
|
|
1354
1363
|
restore(() => this.ctx.session.recordResumeDefaultModel(snapshot.resumeDefaultSelector));
|
|
1355
1364
|
}
|
|
1356
1365
|
restore(() => this.ctx.session.setActiveModelProfile?.(snapshot.activeProfile));
|
|
1366
|
+
if (snapshot.profileInstalledOverrideState) {
|
|
1367
|
+
restore(() =>
|
|
1368
|
+
this.ctx.session.restoreProfileInstalledOverrideState?.(snapshot.profileInstalledOverrideState!),
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1357
1371
|
try {
|
|
1358
1372
|
await this.ctx.settings.flushOrThrow();
|
|
1359
1373
|
} catch (rollbackError) {
|
|
@@ -1401,7 +1415,15 @@ export class SelectorController {
|
|
|
1401
1415
|
*/
|
|
1402
1416
|
showSelector(create: (done: () => void) => { component: Component; focus: Component }): void {
|
|
1403
1417
|
if (this.ctx.isStopped?.()) return;
|
|
1418
|
+
this.#modelSelector = undefined;
|
|
1419
|
+
this.#settingsSelector = undefined;
|
|
1420
|
+
this.#statusLinePreview = undefined;
|
|
1421
|
+
this.#statusLinePreviewActive = false;
|
|
1404
1422
|
const done = () => {
|
|
1423
|
+
this.#modelSelector = undefined;
|
|
1424
|
+
this.#settingsSelector = undefined;
|
|
1425
|
+
this.#statusLinePreview = undefined;
|
|
1426
|
+
this.#statusLinePreviewActive = false;
|
|
1405
1427
|
if (this.ctx.isStopped?.()) return;
|
|
1406
1428
|
// Prefer the pet-aware composer restore (InteractiveMode.restoreComposer); fall back
|
|
1407
1429
|
// to a plain editor swap for contexts that predate it (e.g. lightweight test doubles).
|
|
@@ -1424,6 +1446,28 @@ export class SelectorController {
|
|
|
1424
1446
|
this.ctx.ui.requestRender();
|
|
1425
1447
|
}
|
|
1426
1448
|
|
|
1449
|
+
/** Refresh accepted disk configuration without discarding an open preview. */
|
|
1450
|
+
refreshConfiguration(): void {
|
|
1451
|
+
if (this.ctx.isStopped?.()) return;
|
|
1452
|
+
this.#applyStatusLineSettings();
|
|
1453
|
+
this.#modelSelector?.refreshRoleAssignments({
|
|
1454
|
+
currentModel: this.ctx.session.model,
|
|
1455
|
+
currentThinkingLevel: this.ctx.session.thinkingLevel,
|
|
1456
|
+
activeModelProfile: this.ctx.session.getActiveModelProfile(),
|
|
1457
|
+
});
|
|
1458
|
+
this.#modelSelector?.refreshPresetProfiles();
|
|
1459
|
+
this.#settingsSelector?.refreshFromConfiguration([...this.ctx.session.modelRegistry.getModelProfiles().keys()]);
|
|
1460
|
+
this.ctx.updateEditorTopBorder();
|
|
1461
|
+
this.ctx.ui.requestRender();
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
#applyStatusLineSettings(): void {
|
|
1465
|
+
this.ctx.statusLine.updateSettings({
|
|
1466
|
+
...buildStatusLineSettings(this.ctx.settings),
|
|
1467
|
+
...(this.#statusLinePreviewActive ? this.#statusLinePreview : undefined),
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1427
1471
|
showCommandPalette(
|
|
1428
1472
|
commands: SlashCommand[],
|
|
1429
1473
|
actions: CommandPaletteAction[],
|
|
@@ -1990,11 +2034,19 @@ export class SelectorController {
|
|
|
1990
2034
|
},
|
|
1991
2035
|
onPetCommit: mode => this.ctx.commitPetPreviewMode(mode as PetMode),
|
|
1992
2036
|
onStatusLinePreview: previewSettings => {
|
|
1993
|
-
|
|
1994
|
-
this
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2037
|
+
if (this.#statusLinePreviewActive) this.#statusLinePreview = previewSettings;
|
|
2038
|
+
this.#applyStatusLineSettings();
|
|
2039
|
+
this.ctx.updateEditorTopBorder();
|
|
2040
|
+
this.ctx.ui.requestRender();
|
|
2041
|
+
},
|
|
2042
|
+
onStatusLinePreviewStart: () => {
|
|
2043
|
+
this.#statusLinePreviewActive = true;
|
|
2044
|
+
this.#statusLinePreview = undefined;
|
|
2045
|
+
},
|
|
2046
|
+
onStatusLinePreviewEnd: () => {
|
|
2047
|
+
this.#statusLinePreviewActive = false;
|
|
2048
|
+
this.#statusLinePreview = undefined;
|
|
2049
|
+
this.#applyStatusLineSettings();
|
|
1998
2050
|
this.ctx.updateEditorTopBorder();
|
|
1999
2051
|
this.ctx.ui.requestRender();
|
|
2000
2052
|
},
|
|
@@ -2068,6 +2120,7 @@ export class SelectorController {
|
|
|
2068
2120
|
},
|
|
2069
2121
|
notificationsOperations,
|
|
2070
2122
|
);
|
|
2123
|
+
this.#settingsSelector = selector;
|
|
2071
2124
|
return { component: selector, focus: selector };
|
|
2072
2125
|
});
|
|
2073
2126
|
});
|
|
@@ -2520,7 +2573,9 @@ export class SelectorController {
|
|
|
2520
2573
|
if (issues.length > 0)
|
|
2521
2574
|
throw new Error(issues.map(issue => `${issue.path || "setup"}: ${issue.detail}`).join("; "));
|
|
2522
2575
|
const setup = structuredClone(draft);
|
|
2523
|
-
const generated = generateTierChains(setup, CURATED_TIER_MAP, [
|
|
2576
|
+
const generated = generateTierChains(setup, CURATED_TIER_MAP, [
|
|
2577
|
+
...this.ctx.session.modelRegistry.getAll(this.ctx.session.credentialSessionId),
|
|
2578
|
+
]);
|
|
2524
2579
|
const provenance: AutoroutingProvenance = {
|
|
2525
2580
|
schema: 1,
|
|
2526
2581
|
source: structuredClone(generated.sourceIdentity),
|
|
@@ -2849,6 +2904,7 @@ export class SelectorController {
|
|
|
2849
2904
|
if (!materializedProfile) {
|
|
2850
2905
|
for (const targetRole of targetRoles) {
|
|
2851
2906
|
const target = GJC_MODEL_ASSIGNMENT_TARGETS[targetRole];
|
|
2907
|
+
this.ctx.session.markProfileRoleOverrideManual?.(target.settingsPath, targetRole);
|
|
2852
2908
|
if (target.settingsPath === "modelRoles") {
|
|
2853
2909
|
this.ctx.settings.setModelRole(targetRole, value);
|
|
2854
2910
|
} else {
|
|
@@ -2952,6 +3008,7 @@ export class SelectorController {
|
|
|
2952
3008
|
});
|
|
2953
3009
|
if (!materializedProfile) {
|
|
2954
3010
|
const target = GJC_MODEL_ASSIGNMENT_TARGETS[role];
|
|
3011
|
+
this.ctx.session.markProfileRoleOverrideManual?.(target.settingsPath, role);
|
|
2955
3012
|
if (target.settingsPath === "modelRoles") {
|
|
2956
3013
|
this.ctx.settings.setModelRole(role, value);
|
|
2957
3014
|
} else {
|
|
@@ -2996,6 +3053,7 @@ export class SelectorController {
|
|
|
2996
3053
|
smartRoutingOnly: options?.smartRoutingOnly,
|
|
2997
3054
|
},
|
|
2998
3055
|
);
|
|
3056
|
+
this.#modelSelector = modelSelector;
|
|
2999
3057
|
return { component: modelSelector, focus: modelSelector };
|
|
3000
3058
|
});
|
|
3001
3059
|
}
|
|
@@ -3185,6 +3243,16 @@ export class SelectorController {
|
|
|
3185
3243
|
// cancelled transition or roll it back to the parent's UI.
|
|
3186
3244
|
branchFailure = error;
|
|
3187
3245
|
}
|
|
3246
|
+
if (
|
|
3247
|
+
this.ctx.sessionManager.getSessionId() !== openedSessionId ||
|
|
3248
|
+
this.ctx.sessionManager.getSessionFile() !== openedSessionFile
|
|
3249
|
+
) {
|
|
3250
|
+
try {
|
|
3251
|
+
await this.ctx.refreshSlashCommandState();
|
|
3252
|
+
} catch (error) {
|
|
3253
|
+
branchFailure ??= error;
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3188
3256
|
|
|
3189
3257
|
try {
|
|
3190
3258
|
onCommitted?.();
|
|
@@ -3606,6 +3674,7 @@ export class SelectorController {
|
|
|
3606
3674
|
if (option === `Use ${currentDefault.id}`) {
|
|
3607
3675
|
try {
|
|
3608
3676
|
await this.ctx.session.setModel(currentDefault);
|
|
3677
|
+
this.ctx.updateEditorChrome();
|
|
3609
3678
|
this.ctx.showStatus(`Switched to ${currentDefault.provider}/${currentDefault.id}`);
|
|
3610
3679
|
} catch (err) {
|
|
3611
3680
|
this.ctx.showError(err instanceof Error ? err.message : String(err));
|
|
@@ -16,6 +16,8 @@ import {
|
|
|
16
16
|
import { APP_NAME, adjustHsv, getAgentDir, getProjectDir, logger, postmortem, sanitizeText } from "@gajae-code/utils";
|
|
17
17
|
import chalk from "chalk";
|
|
18
18
|
import { AsyncJobManager } from "../async";
|
|
19
|
+
import { ConfigHotReloadWatcher } from "../config/config-hot-reload";
|
|
20
|
+
import { isConfigHotReloadSupported, isConfigHotReloadTrusted } from "../config/config-hot-reload-trust";
|
|
19
21
|
import {
|
|
20
22
|
type AppKeybinding,
|
|
21
23
|
defaultMessageQueueKeysForPlatform,
|
|
@@ -37,7 +39,11 @@ import type {
|
|
|
37
39
|
} from "../extensibility/extensions";
|
|
38
40
|
import type { CompactOptions } from "../extensibility/extensions/types";
|
|
39
41
|
import { resolveSkillSlashCommands, type Skill } from "../extensibility/skills";
|
|
40
|
-
import {
|
|
42
|
+
import {
|
|
43
|
+
BUILTIN_SLASH_COMMANDS,
|
|
44
|
+
getBuiltinSlashCommandsForSession,
|
|
45
|
+
loadSlashCommands,
|
|
46
|
+
} from "../extensibility/slash-commands";
|
|
41
47
|
import { getLspStartupWarningMessage, LSP_STARTUP_EVENT_CHANNEL, type LspStartupEvent } from "../lsp/startup-events";
|
|
42
48
|
import {
|
|
43
49
|
createStarReminderBeforeAgentStartContributor,
|
|
@@ -471,6 +477,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
471
477
|
#baseSlashCommands: SlashCommand[] = [];
|
|
472
478
|
#resolvedSlashCommands: SlashCommand[] = [];
|
|
473
479
|
#baseReservedSlashCommandNames: Set<string> = new Set();
|
|
480
|
+
#sessionBuiltinMcpVisible = false;
|
|
481
|
+
#slashCommandRefreshVersion = 0;
|
|
474
482
|
#cleanupUnsubscribe?: () => void;
|
|
475
483
|
#itermPetTransport?: ItermPetTransport;
|
|
476
484
|
|
|
@@ -573,6 +581,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
573
581
|
// paint, which renders the full session anyway.
|
|
574
582
|
#initialTranscriptPainted = false;
|
|
575
583
|
#stopListeners = new Set<() => void>();
|
|
584
|
+
#configHotReload?: ConfigHotReloadWatcher;
|
|
576
585
|
#eventBus?: EventBus;
|
|
577
586
|
#eventBusUnsubscribers: Array<() => void> = [];
|
|
578
587
|
#welcomeComponent?: WelcomeComponent;
|
|
@@ -768,6 +777,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
768
777
|
this.hideThinkingBlock = settings.get("hideThinkingBlock");
|
|
769
778
|
|
|
770
779
|
const builtinCommandNames = new Set(BUILTIN_SLASH_COMMANDS.map(c => c.name));
|
|
780
|
+
this.#sessionBuiltinMcpVisible = this.session.hasExactMcpControls;
|
|
781
|
+
const sessionBuiltinSlashCommands = getBuiltinSlashCommandsForSession(this.#sessionBuiltinMcpVisible);
|
|
771
782
|
const activeProvider = this.session.model?.provider;
|
|
772
783
|
const hookCommands: SlashCommand[] = (
|
|
773
784
|
this.session.extensionRunner?.getRegisteredCommands(builtinCommandNames) ?? []
|
|
@@ -785,8 +796,13 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
785
796
|
description: `${loaded.command.description} (${loaded.source})`,
|
|
786
797
|
}));
|
|
787
798
|
|
|
788
|
-
this.#baseSlashCommands = [...
|
|
789
|
-
|
|
799
|
+
this.#baseSlashCommands = [...sessionBuiltinSlashCommands, ...hookCommands, ...customCommands];
|
|
800
|
+
// Hidden builtin metadata must still reserve its name from extensions and skills.
|
|
801
|
+
this.#baseReservedSlashCommandNames = new Set([
|
|
802
|
+
...builtinCommandNames,
|
|
803
|
+
...hookCommands.map(command => command.name),
|
|
804
|
+
...customCommands.map(command => command.name),
|
|
805
|
+
]);
|
|
790
806
|
this.#resolvedSlashCommands = [...this.#baseSlashCommands, ...this.#rebuildSkillSlashCommands()];
|
|
791
807
|
|
|
792
808
|
this.#uiHelpers = new UiHelpers(this);
|
|
@@ -999,6 +1015,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
999
1015
|
this.updateEditorChrome();
|
|
1000
1016
|
this.#syncEditorMaxHeight();
|
|
1001
1017
|
this.isInitialized = true;
|
|
1018
|
+
await this.#startConfigHotReload();
|
|
1019
|
+
if (this.#stopped) return;
|
|
1002
1020
|
this.syncActivityIndicator();
|
|
1003
1021
|
if (this.settings.get("tasksPane.defaultVisible")) this.showTasksPane();
|
|
1004
1022
|
this.#syncIrcSidebarAvailabilityFromSettings();
|
|
@@ -1151,6 +1169,18 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1151
1169
|
|
|
1152
1170
|
// Subscribe to agent events
|
|
1153
1171
|
this.#subscribeToAgent();
|
|
1172
|
+
this.#eventBusUnsubscribers.push(
|
|
1173
|
+
this.session.subscribeSessionIdentityChanges(async () => {
|
|
1174
|
+
try {
|
|
1175
|
+
await this.refreshSlashCommandState();
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
if (this.#stopped) return;
|
|
1178
|
+
logger.warn("Failed to refresh slash-command state after extension session transition", {
|
|
1179
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
}),
|
|
1183
|
+
);
|
|
1154
1184
|
|
|
1155
1185
|
this.#eventBusUnsubscribers.push(
|
|
1156
1186
|
this.session.subscribe(event => {
|
|
@@ -1215,9 +1245,12 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1215
1245
|
/** Reload slash commands and autocomplete for the provided working directory. */
|
|
1216
1246
|
async refreshSlashCommandState(cwd?: string): Promise<void> {
|
|
1217
1247
|
if (this.#stopped) return;
|
|
1248
|
+
const refreshVersion = ++this.#slashCommandRefreshVersion;
|
|
1218
1249
|
const basePath = cwd ?? this.sessionManager.getCwd();
|
|
1250
|
+
this.#refreshSessionBuiltinSlashCommandVisibility(basePath);
|
|
1219
1251
|
const fileCommands = await loadSlashCommands({ cwd: basePath });
|
|
1220
|
-
if (this.#stopped) return;
|
|
1252
|
+
if (this.#stopped || refreshVersion !== this.#slashCommandRefreshVersion) return;
|
|
1253
|
+
this.#refreshSessionBuiltinSlashCommandVisibility(basePath);
|
|
1221
1254
|
const fileCommandNames = new Set(fileCommands.map(cmd => cmd.name));
|
|
1222
1255
|
this.fileSlashCommands = fileCommandNames;
|
|
1223
1256
|
const fileSlashCommands: SlashCommand[] = fileCommands.map(cmd => ({
|
|
@@ -1234,6 +1267,23 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1234
1267
|
this.session.setSlashCommands(fileCommands);
|
|
1235
1268
|
}
|
|
1236
1269
|
|
|
1270
|
+
#refreshSessionBuiltinSlashCommandVisibility(cwd: string): void {
|
|
1271
|
+
const hasExactMcpControls = this.session.hasExactMcpControls;
|
|
1272
|
+
if (hasExactMcpControls === this.#sessionBuiltinMcpVisible) return;
|
|
1273
|
+
|
|
1274
|
+
const previousSlashCommandTail = this.#resolvedSlashCommands.slice(this.#baseSlashCommands.length);
|
|
1275
|
+
const builtinCommandNames = new Set(BUILTIN_SLASH_COMMANDS.map(command => command.name));
|
|
1276
|
+
this.#baseSlashCommands = [
|
|
1277
|
+
...getBuiltinSlashCommandsForSession(hasExactMcpControls),
|
|
1278
|
+
...this.#baseSlashCommands.filter(command => !builtinCommandNames.has(command.name)),
|
|
1279
|
+
];
|
|
1280
|
+
this.#sessionBuiltinMcpVisible = hasExactMcpControls;
|
|
1281
|
+
this.#resolvedSlashCommands = [...this.#baseSlashCommands, ...previousSlashCommandTail];
|
|
1282
|
+
this.editor.setAutocompleteProvider(
|
|
1283
|
+
this.#inputController.createAutocompleteProvider(this.#resolvedSlashCommands, cwd),
|
|
1284
|
+
);
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1237
1287
|
#rebuildSkillSlashCommands(fileCommandNames: ReadonlySet<string> = new Set()): SlashCommand[] {
|
|
1238
1288
|
this.skillCommands.clear();
|
|
1239
1289
|
if (!settings.get("skills.enableSkillCommands")) {
|
|
@@ -1475,6 +1525,12 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1475
1525
|
}
|
|
1476
1526
|
this.editor.setPlaceholder(this.#getComposerPlaceholder());
|
|
1477
1527
|
this.#setComposerTopBorder();
|
|
1528
|
+
// Every live model switch (/model, profiles, cycling, fallback) refreshes the
|
|
1529
|
+
// editor chrome; keep the welcome model/provider pills on the same signal.
|
|
1530
|
+
this.#welcomeComponent?.setModel(
|
|
1531
|
+
this.session.model?.name ?? "Unknown",
|
|
1532
|
+
this.session.model?.provider ?? "Unknown",
|
|
1533
|
+
);
|
|
1478
1534
|
this.ui.requestRender();
|
|
1479
1535
|
}
|
|
1480
1536
|
|
|
@@ -1691,6 +1747,65 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1691
1747
|
return this.#stopped;
|
|
1692
1748
|
}
|
|
1693
1749
|
|
|
1750
|
+
async #startConfigHotReload(): Promise<void> {
|
|
1751
|
+
const paths = this.session.getConfigurationPaths();
|
|
1752
|
+
if (!paths) return;
|
|
1753
|
+
if (!isConfigHotReloadSupported()) {
|
|
1754
|
+
logger.debug("Configuration hot reload is unsupported on this platform", { platform: process.platform });
|
|
1755
|
+
return;
|
|
1756
|
+
}
|
|
1757
|
+
const trusted = await isConfigHotReloadTrusted(paths);
|
|
1758
|
+
if (this.#stopped || this.#isShuttingDown) return;
|
|
1759
|
+
if (!trusted) {
|
|
1760
|
+
this.showWarning(
|
|
1761
|
+
"Configuration watching could not start because directory ownership and privacy could not be verified.",
|
|
1762
|
+
);
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
const assertTrustedPaths = async (): Promise<void> => {
|
|
1766
|
+
if (await isConfigHotReloadTrusted(paths)) return;
|
|
1767
|
+
const error = new Error("Configuration directory ownership and privacy could not be verified");
|
|
1768
|
+
Object.assign(error, { code: "EACCES" });
|
|
1769
|
+
throw error;
|
|
1770
|
+
};
|
|
1771
|
+
const watcher = new ConfigHotReloadWatcher({
|
|
1772
|
+
onValidate: async candidate => {
|
|
1773
|
+
await assertTrustedPaths();
|
|
1774
|
+
await this.session.validateConfiguration(candidate);
|
|
1775
|
+
},
|
|
1776
|
+
onCandidate: async (candidate, signal) => {
|
|
1777
|
+
if (signal.aborted || this.#stopped || this.#isShuttingDown) return;
|
|
1778
|
+
await assertTrustedPaths();
|
|
1779
|
+
if (signal.aborted || this.#stopped || this.#isShuttingDown) return;
|
|
1780
|
+
const result = await this.session.reloadConfiguration(candidate, signal);
|
|
1781
|
+
if (signal.aborted || this.#stopped || this.#isShuttingDown || !result.applied) return;
|
|
1782
|
+
this.#selectorController.refreshConfiguration();
|
|
1783
|
+
this.#syncEditorMaxHeight();
|
|
1784
|
+
this.#syncIrcSidebarAvailabilityFromSettings();
|
|
1785
|
+
this.updateEditorChrome();
|
|
1786
|
+
this.showStatus(
|
|
1787
|
+
result.settingsChanged
|
|
1788
|
+
? "Configuration reloaded. Startup-only services require a restart."
|
|
1789
|
+
: "Model configuration reloaded.",
|
|
1790
|
+
);
|
|
1791
|
+
this.ui.requestRender();
|
|
1792
|
+
},
|
|
1793
|
+
onError: error => {
|
|
1794
|
+
if (!this.#stopped && !this.#isShuttingDown) {
|
|
1795
|
+
this.showWarning(`${error.message}. Repair the configuration file and save again.`);
|
|
1796
|
+
}
|
|
1797
|
+
},
|
|
1798
|
+
});
|
|
1799
|
+
this.#configHotReload = watcher;
|
|
1800
|
+
try {
|
|
1801
|
+
await watcher.start(paths);
|
|
1802
|
+
} catch {
|
|
1803
|
+
watcher.dispose();
|
|
1804
|
+
this.#configHotReload = undefined;
|
|
1805
|
+
this.showWarning("Configuration watching could not start. Restart after repairing file access.");
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1694
1809
|
onStop(callback: () => void): () => void {
|
|
1695
1810
|
if (this.#stopped) {
|
|
1696
1811
|
callback();
|
|
@@ -1703,6 +1818,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1703
1818
|
stop(): void {
|
|
1704
1819
|
const wasInitialized = this.isInitialized;
|
|
1705
1820
|
this.#stopped = true;
|
|
1821
|
+
this.#configHotReload?.dispose();
|
|
1822
|
+
this.#configHotReload = undefined;
|
|
1706
1823
|
this.ui.setRenderPreparationLifecycleCallbacks(undefined);
|
|
1707
1824
|
this.#inputController.discardDeferredSubmission();
|
|
1708
1825
|
for (const listener of this.#stopListeners) {
|
|
@@ -1776,6 +1893,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1776
1893
|
return;
|
|
1777
1894
|
}
|
|
1778
1895
|
this.#isShuttingDown = true;
|
|
1896
|
+
this.#configHotReload?.dispose();
|
|
1897
|
+
this.#configHotReload = undefined;
|
|
1779
1898
|
|
|
1780
1899
|
// `/btw` owns the shared composer while its panel is open. Never persist a
|
|
1781
1900
|
// side-chat draft or pending side-chat images into the main-session draft.
|
|
@@ -6,7 +6,7 @@ import type { InteractiveModeContext } from "./types";
|
|
|
6
6
|
* Owns the ghost-text next-prompt prediction lifecycle for interactive mode.
|
|
7
7
|
*
|
|
8
8
|
* After each agent turn ends (and only when `promptSuggestions` is enabled
|
|
9
|
-
* and the composer is empty), a
|
|
9
|
+
* and the composer is empty), a model prediction of the user's next
|
|
10
10
|
* prompt is generated in the background. The result renders as dim ghost
|
|
11
11
|
* text in the empty composer via the autocomplete provider's inline hint;
|
|
12
12
|
* Tab accepts it, typing dismisses it, and a new turn clears it.
|
|
@@ -262,7 +262,11 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
262
262
|
const slashIndex = selector.indexOf("/");
|
|
263
263
|
const model =
|
|
264
264
|
slashIndex > 0
|
|
265
|
-
? session.modelRegistry.find(
|
|
265
|
+
? session.modelRegistry.find(
|
|
266
|
+
selector.slice(0, slashIndex),
|
|
267
|
+
selector.slice(slashIndex + 1),
|
|
268
|
+
session.credentialSessionId,
|
|
269
|
+
)
|
|
266
270
|
: undefined;
|
|
267
271
|
if (!model || !thinkingLevel || thinkingLevel === ThinkingLevel.Inherit)
|
|
268
272
|
throw Object.assign(new Error("model.set requires a valid model id and concrete thinkingLevel."), {
|