@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,8 @@ import { CompactionCancelledError, type CompactionOutcome } from "@gajae-code/ag
|
|
|
5
5
|
import { getEnvApiKey, type ToolCall, type UsageLimit, type UsageReport } from "@gajae-code/ai/core";
|
|
6
6
|
import type { ProviderDetails } from "@gajae-code/ai/provider-details";
|
|
7
7
|
import { type Keybinding, Loader, Markdown, padding, Spacer, Text, visibleWidth } from "@gajae-code/tui";
|
|
8
|
-
import { formatBytes, formatDuration,
|
|
8
|
+
import { formatBytes, formatDuration, setProjectDir } from "@gajae-code/utils";
|
|
9
|
+
import { canonicalEnvKey, projectEnvSnapshot } from "@gajae-code/utils/env-file";
|
|
9
10
|
import { resolveAppendOnlyMode } from "../../append-only-mode";
|
|
10
11
|
import { jobElapsedMs } from "../../async";
|
|
11
12
|
import { reset as resetCapabilities } from "../../capability";
|
|
@@ -47,6 +48,7 @@ import {
|
|
|
47
48
|
buildConversationTitleInput,
|
|
48
49
|
generateSessionTitle,
|
|
49
50
|
setSessionTerminalTitle,
|
|
51
|
+
titleInputObfuscator,
|
|
50
52
|
} from "../../utils/title-generator";
|
|
51
53
|
import { addChatChild, prepareTranscriptRebuild, syncPendingExecutionComponents } from "../utils/ui-helpers";
|
|
52
54
|
|
|
@@ -107,6 +109,266 @@ export function buildHelpMarkdown(keybindings: Pick<KeybindingsManager, "getAcce
|
|
|
107
109
|
].join("\n");
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
const GH_SHARE_TRUST_KEYS = [
|
|
113
|
+
"GH_HOST",
|
|
114
|
+
"GH_CONFIG_DIR",
|
|
115
|
+
"GH_TOKEN",
|
|
116
|
+
"GITHUB_TOKEN",
|
|
117
|
+
"GH_ENTERPRISE_TOKEN",
|
|
118
|
+
"GITHUB_ENTERPRISE_TOKEN",
|
|
119
|
+
"XDG_CONFIG_HOME",
|
|
120
|
+
"HOME",
|
|
121
|
+
"USERPROFILE",
|
|
122
|
+
"APPDATA",
|
|
123
|
+
"BASH_ENV",
|
|
124
|
+
"BUN_OPTIONS",
|
|
125
|
+
"ENV",
|
|
126
|
+
"ZDOTDIR",
|
|
127
|
+
"NODE_OPTIONS",
|
|
128
|
+
"NODE_PATH",
|
|
129
|
+
"PYTHONHOME",
|
|
130
|
+
"PYTHONPATH",
|
|
131
|
+
"PYTHONUSERBASE",
|
|
132
|
+
"PYTHONSTARTUP",
|
|
133
|
+
"JULIA_DEPOT_PATH",
|
|
134
|
+
"JULIA_LOAD_PATH",
|
|
135
|
+
"JULIA_PROJECT",
|
|
136
|
+
"TCL_LIBRARY",
|
|
137
|
+
"TCLLIBPATH",
|
|
138
|
+
"LUA_INIT",
|
|
139
|
+
"LUA_INIT_5_1",
|
|
140
|
+
"LUA_INIT_5_2",
|
|
141
|
+
"LUA_INIT_5_3",
|
|
142
|
+
"LUA_INIT_5_4",
|
|
143
|
+
"LUA_INIT_5_5",
|
|
144
|
+
"LUA_PATH",
|
|
145
|
+
"LUA_CPATH",
|
|
146
|
+
"LUA_PATH_5_1",
|
|
147
|
+
"LUA_PATH_5_2",
|
|
148
|
+
"LUA_PATH_5_3",
|
|
149
|
+
"LUA_PATH_5_4",
|
|
150
|
+
"LUA_PATH_5_5",
|
|
151
|
+
"LUA_CPATH_5_1",
|
|
152
|
+
"LUA_CPATH_5_2",
|
|
153
|
+
"LUA_CPATH_5_3",
|
|
154
|
+
"LUA_CPATH_5_4",
|
|
155
|
+
"LUA_CPATH_5_5",
|
|
156
|
+
"R_ENVIRON",
|
|
157
|
+
"R_ENVIRON_USER",
|
|
158
|
+
"R_PROFILE",
|
|
159
|
+
"R_PROFILE_USER",
|
|
160
|
+
"ELIXIR_ERL_OPTIONS",
|
|
161
|
+
"ERL_AFLAGS",
|
|
162
|
+
"ERL_FLAGS",
|
|
163
|
+
"ERL_ZFLAGS",
|
|
164
|
+
"BUNDLER_SETUP",
|
|
165
|
+
"BUNDLE_GEMFILE",
|
|
166
|
+
"GEM_HOME",
|
|
167
|
+
"GEM_PATH",
|
|
168
|
+
"RUBYGEMS_GEMDEPS",
|
|
169
|
+
"RUBYOPT",
|
|
170
|
+
"RUBYLIB",
|
|
171
|
+
"PERL5OPT",
|
|
172
|
+
"PERL5LIB",
|
|
173
|
+
"PERLLIB",
|
|
174
|
+
"JAVA_HOME",
|
|
175
|
+
"JAVA_TOOL_OPTIONS",
|
|
176
|
+
"JDK_JAVA_OPTIONS",
|
|
177
|
+
"_JAVA_OPTIONS",
|
|
178
|
+
"CLASSPATH",
|
|
179
|
+
"PHPRC",
|
|
180
|
+
"PHP_INI_SCAN_DIR",
|
|
181
|
+
"DOTNET_STARTUP_HOOKS",
|
|
182
|
+
"DOTNET_ROOT",
|
|
183
|
+
"DOTNET_ROOT_X86",
|
|
184
|
+
"DOTNET_ROOT_X64",
|
|
185
|
+
"DOTNET_ROOT_ARM",
|
|
186
|
+
"DOTNET_ROOT_ARM64",
|
|
187
|
+
"CORECLR_ENABLE_PROFILING",
|
|
188
|
+
"DOTNET_ENABLE_PROFILING",
|
|
189
|
+
"CORECLR_PROFILER",
|
|
190
|
+
"DOTNET_PROFILER",
|
|
191
|
+
"CORECLR_PROFILER_PATH",
|
|
192
|
+
"CORECLR_PROFILER_PATH_32",
|
|
193
|
+
"CORECLR_PROFILER_PATH_64",
|
|
194
|
+
"CORECLR_PROFILER_PATH_ARM32",
|
|
195
|
+
"CORECLR_PROFILER_PATH_ARM64",
|
|
196
|
+
"DOTNET_PROFILER_PATH",
|
|
197
|
+
"DOTNET_PROFILER_PATH_32",
|
|
198
|
+
"DOTNET_PROFILER_PATH_64",
|
|
199
|
+
"DOTNET_PROFILER_PATH_ARM32",
|
|
200
|
+
"DOTNET_PROFILER_PATH_ARM64",
|
|
201
|
+
"PATH",
|
|
202
|
+
"HTTP_PROXY",
|
|
203
|
+
"HTTPS_PROXY",
|
|
204
|
+
"ALL_PROXY",
|
|
205
|
+
"NO_PROXY",
|
|
206
|
+
"OPENSSL_CONF",
|
|
207
|
+
"OPENSSL_CONF_INCLUDE",
|
|
208
|
+
"OPENSSL_MODULES",
|
|
209
|
+
"OPENSSL_ENGINES",
|
|
210
|
+
"SSL_CERT_FILE",
|
|
211
|
+
"SSL_CERT_DIR",
|
|
212
|
+
"LD_PRELOAD",
|
|
213
|
+
"LD_LIBRARY_PATH",
|
|
214
|
+
"LD_AUDIT",
|
|
215
|
+
"DYLD_INSERT_LIBRARIES",
|
|
216
|
+
"DYLD_LIBRARY_PATH",
|
|
217
|
+
"DYLD_FRAMEWORK_PATH",
|
|
218
|
+
"DYLD_FALLBACK_LIBRARY_PATH",
|
|
219
|
+
"DYLD_FALLBACK_FRAMEWORK_PATH",
|
|
220
|
+
"DYLD_ROOT_PATH",
|
|
221
|
+
] as const;
|
|
222
|
+
const GH_SHARE_TRUST_KEY_SET = new Set(GH_SHARE_TRUST_KEYS.map(name => name.toUpperCase()));
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Project dotenv at import, before `/move` changes cwd. Those declarations are
|
|
226
|
+
* already in the process environment, and a later `setProjectDir` does not
|
|
227
|
+
* remove them.
|
|
228
|
+
*/
|
|
229
|
+
const ghShareProjectSnapshot = projectEnvSnapshot();
|
|
230
|
+
const ghShareOperatorPath = process.env.PATH;
|
|
231
|
+
const ghShareLaunchRoot = path.resolve(process.cwd());
|
|
232
|
+
|
|
233
|
+
function isInsideDirectory(root: string, candidate: string): boolean {
|
|
234
|
+
const relative = path.relative(root, candidate);
|
|
235
|
+
return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function findCheckoutRoots(directory: string): Promise<string[] | undefined> {
|
|
239
|
+
const resolvedDirectory = await fs.realpath(directory).catch(() => undefined);
|
|
240
|
+
if (!resolvedDirectory) return undefined;
|
|
241
|
+
const roots: string[] = [];
|
|
242
|
+
let ancestor = resolvedDirectory;
|
|
243
|
+
while (true) {
|
|
244
|
+
try {
|
|
245
|
+
await fs.lstat(path.join(ancestor, ".git"));
|
|
246
|
+
roots.push(ancestor);
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") return undefined;
|
|
249
|
+
}
|
|
250
|
+
const parent = path.dirname(ancestor);
|
|
251
|
+
if (parent === ancestor) break;
|
|
252
|
+
ancestor = parent;
|
|
253
|
+
}
|
|
254
|
+
return roots;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function isInsideAnyDirectory(roots: readonly string[], candidate: string): boolean {
|
|
258
|
+
return roots.some(root => isInsideDirectory(root, candidate));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async function resolveGhShareExecutable(): Promise<{ executable: string; searchPath: string } | undefined> {
|
|
262
|
+
const operatorPath = ghShareOperatorPath;
|
|
263
|
+
const key = canonicalEnvKey("PATH");
|
|
264
|
+
const declared = ghShareProjectSnapshot.values[key];
|
|
265
|
+
if (
|
|
266
|
+
!operatorPath ||
|
|
267
|
+
(declared !== undefined && (ghShareProjectSnapshot.dynamic.has(key) || declared.trim() === operatorPath.trim()))
|
|
268
|
+
)
|
|
269
|
+
return undefined;
|
|
270
|
+
const checkoutRoots = new Set<string>();
|
|
271
|
+
for (const directory of new Set([ghShareLaunchRoot, path.resolve(process.cwd())])) {
|
|
272
|
+
const roots = await findCheckoutRoots(directory);
|
|
273
|
+
if (!roots) return undefined;
|
|
274
|
+
for (const root of roots) checkoutRoots.add(root);
|
|
275
|
+
}
|
|
276
|
+
const untrustedDirectories = [...checkoutRoots];
|
|
277
|
+
const trustedDirectories: string[] = [];
|
|
278
|
+
const seenDirectories = new Set<string>();
|
|
279
|
+
let executable: string | undefined;
|
|
280
|
+
for (const directory of operatorPath.split(path.delimiter)) {
|
|
281
|
+
if (!path.isAbsolute(directory)) continue;
|
|
282
|
+
const absoluteDirectory = path.resolve(directory);
|
|
283
|
+
if (isInsideAnyDirectory(untrustedDirectories, absoluteDirectory)) continue;
|
|
284
|
+
const realDirectory = await fs.realpath(absoluteDirectory).catch(() => undefined);
|
|
285
|
+
if (
|
|
286
|
+
!realDirectory ||
|
|
287
|
+
isInsideAnyDirectory(untrustedDirectories, realDirectory) ||
|
|
288
|
+
seenDirectories.has(realDirectory)
|
|
289
|
+
)
|
|
290
|
+
continue;
|
|
291
|
+
const candidate = Bun.which("gh", { PATH: realDirectory });
|
|
292
|
+
if (candidate) {
|
|
293
|
+
const absoluteCandidate = path.resolve(candidate);
|
|
294
|
+
if (isInsideAnyDirectory(untrustedDirectories, absoluteCandidate)) continue;
|
|
295
|
+
const realExecutable = await fs.realpath(absoluteCandidate).catch(() => undefined);
|
|
296
|
+
if (!realExecutable || isInsideAnyDirectory(untrustedDirectories, realExecutable)) continue;
|
|
297
|
+
executable ??= realExecutable;
|
|
298
|
+
}
|
|
299
|
+
seenDirectories.add(realDirectory);
|
|
300
|
+
trustedDirectories.push(realDirectory);
|
|
301
|
+
}
|
|
302
|
+
return executable ? { executable, searchPath: trustedDirectories.join(path.delimiter) } : undefined;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Environment for the default `/share` `gh` children. GitHub CLI routing,
|
|
307
|
+
* config, authentication, proxy, certificate, shell/runtime startup, executable-search,
|
|
308
|
+
* and dynamic loader overrides that match the project dotenv are omitted so a repository
|
|
309
|
+
* cannot redirect the upload, substitute the `gh` binary, authenticate with a
|
|
310
|
+
* project-provided token, or intercept its HTTPS request. The executable itself
|
|
311
|
+
* and its child search path use absolute operator PATH directories whose real
|
|
312
|
+
* paths are outside actual launch and active checkout roots. Operator values the project
|
|
313
|
+
* does not declare are kept.
|
|
314
|
+
*/
|
|
315
|
+
function ghShareChildEnv(trustedPath: string, env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
|
|
316
|
+
const child: NodeJS.ProcessEnv = { ...env };
|
|
317
|
+
for (const name of Object.keys(child)) {
|
|
318
|
+
if (!GH_SHARE_TRUST_KEY_SET.has(name.toUpperCase())) continue;
|
|
319
|
+
const raw = child[name];
|
|
320
|
+
if (typeof raw !== "string") continue;
|
|
321
|
+
const key = canonicalEnvKey(name);
|
|
322
|
+
const declared = ghShareProjectSnapshot.values[key];
|
|
323
|
+
if (declared === undefined) continue;
|
|
324
|
+
if (!(ghShareProjectSnapshot.dynamic.has(key) || declared.trim() === raw.trim())) continue;
|
|
325
|
+
delete child[name];
|
|
326
|
+
if (process.platform === "win32") {
|
|
327
|
+
for (const present of Object.keys(child)) {
|
|
328
|
+
if (canonicalEnvKey(present) === key) delete child[present];
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const ghConfigDirKey = canonicalEnvKey("GH_CONFIG_DIR");
|
|
333
|
+
const xdgConfigHomeKey = canonicalEnvKey("XDG_CONFIG_HOME");
|
|
334
|
+
for (const name of Object.keys(child)) {
|
|
335
|
+
const key = canonicalEnvKey(name);
|
|
336
|
+
if (key !== ghConfigDirKey && key !== xdgConfigHomeKey) continue;
|
|
337
|
+
const value = child[name];
|
|
338
|
+
if (typeof value !== "string" || value.length === 0 || path.isAbsolute(value)) continue;
|
|
339
|
+
// `gh` children use the filesystem root as cwd to avoid project Bun
|
|
340
|
+
// preloads, so retain the launch-directory meaning of relative config paths.
|
|
341
|
+
child[name] = path.resolve(ghShareLaunchRoot, value);
|
|
342
|
+
}
|
|
343
|
+
const certFileKey = canonicalEnvKey("SSL_CERT_FILE");
|
|
344
|
+
const certDirKey = canonicalEnvKey("SSL_CERT_DIR");
|
|
345
|
+
for (const name of Object.keys(child)) {
|
|
346
|
+
const key = canonicalEnvKey(name);
|
|
347
|
+
const value = child[name];
|
|
348
|
+
if (typeof value !== "string" || value.length === 0) continue;
|
|
349
|
+
if (key === certFileKey && !path.isAbsolute(value)) {
|
|
350
|
+
// Certificate overrides retain their launch-directory meaning even
|
|
351
|
+
// though `gh` children run from the filesystem root.
|
|
352
|
+
child[name] = path.resolve(ghShareLaunchRoot, value);
|
|
353
|
+
} else if (key === certDirKey) {
|
|
354
|
+
child[name] = value
|
|
355
|
+
.split(path.delimiter)
|
|
356
|
+
.map(directory =>
|
|
357
|
+
directory.length > 0 && !path.isAbsolute(directory)
|
|
358
|
+
? path.resolve(ghShareLaunchRoot, directory)
|
|
359
|
+
: directory,
|
|
360
|
+
)
|
|
361
|
+
.join(path.delimiter);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const pathKey = canonicalEnvKey("PATH");
|
|
365
|
+
for (const name of Object.keys(child)) {
|
|
366
|
+
if (canonicalEnvKey(name) === pathKey) delete child[name];
|
|
367
|
+
}
|
|
368
|
+
child.PATH = trustedPath;
|
|
369
|
+
return child;
|
|
370
|
+
}
|
|
371
|
+
|
|
110
372
|
export class CommandController {
|
|
111
373
|
constructor(private readonly ctx: InteractiveModeContext) {}
|
|
112
374
|
|
|
@@ -147,6 +409,7 @@ export class CommandController {
|
|
|
147
409
|
}
|
|
148
410
|
|
|
149
411
|
async handleDebugTranscriptCommand(): Promise<void> {
|
|
412
|
+
let tempDir: string | undefined;
|
|
150
413
|
try {
|
|
151
414
|
const width = Math.max(1, this.ctx.ui.terminal.columns);
|
|
152
415
|
const renderedLines = this.ctx.chatContainer.render(width).map(line => replaceTabs(Bun.stripANSI(line)));
|
|
@@ -155,10 +418,22 @@ export class CommandController {
|
|
|
155
418
|
this.ctx.showError("No messages to dump yet.");
|
|
156
419
|
return;
|
|
157
420
|
}
|
|
158
|
-
|
|
159
|
-
|
|
421
|
+
// Random directory plus an exclusive create: a preexisting symlink under the
|
|
422
|
+
// shared temp directory is not opened, and the transcript is not left world-readable.
|
|
423
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "gjc-debug-transcript-"));
|
|
424
|
+
if (process.platform !== "win32") await fs.chmod(tempDir, 0o700);
|
|
425
|
+
const tmpPath = path.join(tempDir, "transcript.txt");
|
|
426
|
+
const handle = await fs.open(tmpPath, "wx", 0o600);
|
|
427
|
+
try {
|
|
428
|
+
await handle.writeFile(`${rendered}\n`);
|
|
429
|
+
} finally {
|
|
430
|
+
await handle.close();
|
|
431
|
+
}
|
|
432
|
+
if (process.platform !== "win32") await fs.chmod(tmpPath, 0o600);
|
|
160
433
|
this.ctx.showStatus(`Debug transcript written to:\n${tmpPath}`);
|
|
434
|
+
tempDir = undefined;
|
|
161
435
|
} catch (error: unknown) {
|
|
436
|
+
if (tempDir) await fs.rm(tempDir, { recursive: true, force: true }).catch(() => {});
|
|
162
437
|
this.ctx.showError(
|
|
163
438
|
`Failed to write debug transcript: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
164
439
|
);
|
|
@@ -242,9 +517,21 @@ export class CommandController {
|
|
|
242
517
|
return;
|
|
243
518
|
}
|
|
244
519
|
|
|
520
|
+
const ghShare = await resolveGhShareExecutable();
|
|
521
|
+
if (!ghShare) {
|
|
522
|
+
this.ctx.showError(
|
|
523
|
+
"GitHub CLI (gh) is not installed on the trusted operator PATH. Install it from https://cli.github.com/",
|
|
524
|
+
);
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
const ghShareExecutable = ghShare.executable;
|
|
528
|
+
// Bun wrappers load project bunfig.toml preloads from their working directory.
|
|
529
|
+
const ghShareCwd = path.parse(ghShareLaunchRoot).root;
|
|
530
|
+
const ghEnv = ghShareChildEnv(ghShare.searchPath);
|
|
245
531
|
try {
|
|
246
|
-
const authProcess = Bun.spawn([
|
|
247
|
-
|
|
532
|
+
const authProcess = Bun.spawn([ghShareExecutable, "auth", "status"], {
|
|
533
|
+
cwd: ghShareCwd,
|
|
534
|
+
env: ghEnv,
|
|
248
535
|
stdin: "ignore",
|
|
249
536
|
stdout: "ignore",
|
|
250
537
|
stderr: "ignore",
|
|
@@ -277,8 +564,9 @@ export class CommandController {
|
|
|
277
564
|
|
|
278
565
|
let cancellationRequested = false;
|
|
279
566
|
try {
|
|
280
|
-
const gistProcess = Bun.spawn([
|
|
281
|
-
|
|
567
|
+
const gistProcess = Bun.spawn([ghShareExecutable, "gist", "create", "--public=false", tmpFile], {
|
|
568
|
+
cwd: ghShareCwd,
|
|
569
|
+
env: ghEnv,
|
|
282
570
|
stdin: "ignore",
|
|
283
571
|
stdout: "pipe",
|
|
284
572
|
stderr: "pipe",
|
|
@@ -1176,7 +1464,9 @@ export class CommandController {
|
|
|
1176
1464
|
try {
|
|
1177
1465
|
if (!title?.trim()) {
|
|
1178
1466
|
const generation = beginSessionTitleGeneration(this.ctx.sessionManager);
|
|
1179
|
-
const
|
|
1467
|
+
const activeCwd = this.ctx.sessionManager.getCwd();
|
|
1468
|
+
const obfuscateText = await titleInputObfuscator(this.ctx.settings, activeCwd);
|
|
1469
|
+
const input = buildConversationTitleInput(this.ctx.session.messages, obfuscateText);
|
|
1180
1470
|
if (!input) {
|
|
1181
1471
|
this.ctx.showError("Nothing to summarize yet — pass a title: /rename <title>");
|
|
1182
1472
|
return;
|
|
@@ -1189,10 +1479,11 @@ export class CommandController {
|
|
|
1189
1479
|
this.ctx.session.credentialSessionId,
|
|
1190
1480
|
this.ctx.session.model,
|
|
1191
1481
|
provider => this.ctx.session.agent.metadataForProvider(provider),
|
|
1482
|
+
activeCwd,
|
|
1192
1483
|
);
|
|
1193
1484
|
if (
|
|
1194
1485
|
!isSessionTitleGenerationCurrent(this.ctx.sessionManager, generation) ||
|
|
1195
|
-
buildConversationTitleInput(this.ctx.session.messages) !== input
|
|
1486
|
+
buildConversationTitleInput(this.ctx.session.messages, obfuscateText) !== input
|
|
1196
1487
|
)
|
|
1197
1488
|
return;
|
|
1198
1489
|
if (!generated) {
|
|
@@ -716,7 +716,7 @@ export class EventController {
|
|
|
716
716
|
): Promise<void> {
|
|
717
717
|
this.ctx.showStatus(`Fallback model: ${event.from} → ${event.to}`);
|
|
718
718
|
this.ctx.statusLine.invalidate();
|
|
719
|
-
this.ctx.
|
|
719
|
+
this.ctx.updateEditorBorderColor();
|
|
720
720
|
}
|
|
721
721
|
|
|
722
722
|
async #handleNotice(event: Extract<AgentSessionEvent, { type: "notice" }>): Promise<void> {
|
|
@@ -84,6 +84,7 @@ const EXTENSION_CONTEXT_MUTATIONS: ReadonlySet<PropertyKey> = new Set([
|
|
|
84
84
|
"clearContext",
|
|
85
85
|
"cycleModel",
|
|
86
86
|
"setModelProfile",
|
|
87
|
+
"setDefaultModelProfile",
|
|
87
88
|
"cycleThinkingLevel",
|
|
88
89
|
"setQueueMode",
|
|
89
90
|
"invokeSkill",
|
|
@@ -93,6 +94,14 @@ const EXTENSION_CONTEXT_MUTATIONS: ReadonlySet<PropertyKey> = new Set([
|
|
|
93
94
|
"setSdkClientBridge",
|
|
94
95
|
"sdkControl",
|
|
95
96
|
]);
|
|
97
|
+
const MODEL_CHANGE_MUTATIONS: ReadonlySet<PropertyKey> = new Set([
|
|
98
|
+
"setModel",
|
|
99
|
+
"setModelTemporaryForControl",
|
|
100
|
+
"cycleModel",
|
|
101
|
+
"setModelProfile",
|
|
102
|
+
"setDefaultModelProfile",
|
|
103
|
+
"sdkControl",
|
|
104
|
+
]);
|
|
96
105
|
const EXTENSION_COMMAND_MUTATIONS: ReadonlySet<PropertyKey> = new Set([
|
|
97
106
|
"reload",
|
|
98
107
|
"newSession",
|
|
@@ -250,7 +259,11 @@ export class ExtensionUiController {
|
|
|
250
259
|
const slashIndex = selector.indexOf("/");
|
|
251
260
|
const model =
|
|
252
261
|
slashIndex > 0
|
|
253
|
-
? session.modelRegistry.find(
|
|
262
|
+
? session.modelRegistry.find(
|
|
263
|
+
selector.slice(0, slashIndex),
|
|
264
|
+
selector.slice(slashIndex + 1),
|
|
265
|
+
session.credentialSessionId,
|
|
266
|
+
)
|
|
254
267
|
: undefined;
|
|
255
268
|
if (!model || !thinkingLevel || thinkingLevel === ThinkingLevel.Inherit)
|
|
256
269
|
throw Object.assign(new Error("model.set requires a valid model id and concrete thinkingLevel."), {
|
|
@@ -442,6 +455,14 @@ export class ExtensionUiController {
|
|
|
442
455
|
return this.ctx.isStopped?.() === true;
|
|
443
456
|
}
|
|
444
457
|
|
|
458
|
+
async #withModelChangeRefresh<T>(changeModel: () => Promise<T>): Promise<T> {
|
|
459
|
+
try {
|
|
460
|
+
return await changeModel();
|
|
461
|
+
} finally {
|
|
462
|
+
if (!this.#isStopped()) this.ctx.updateEditorChrome();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
445
466
|
#assertActive(): void {
|
|
446
467
|
if (this.#isStopped()) throw Object.assign(new Error("Interactive mode stopped"), { code: "cancelled" });
|
|
447
468
|
}
|
|
@@ -453,6 +474,9 @@ export class ExtensionUiController {
|
|
|
453
474
|
if (!mutationNames.has(property) || typeof member !== "function") return member;
|
|
454
475
|
return (...args: unknown[]) => {
|
|
455
476
|
this.#assertActive();
|
|
477
|
+
if (MODEL_CHANGE_MUTATIONS.has(property)) {
|
|
478
|
+
return this.#withModelChangeRefresh(async () => Reflect.apply(member, current, args));
|
|
479
|
+
}
|
|
456
480
|
return Reflect.apply(member, current, args);
|
|
457
481
|
};
|
|
458
482
|
},
|
|
@@ -646,6 +670,7 @@ export class ExtensionUiController {
|
|
|
646
670
|
branch: async () => prohibitBrokerLifecycleOperation("session.branch"),
|
|
647
671
|
navigateTree: async (targetId, navOptions) => {
|
|
648
672
|
const result = await this.ctx.session.navigateTree(targetId, { summarize: navOptions?.summarize });
|
|
673
|
+
if (!result.cancelled) await this.ctx.session.notifySessionIdentityChanged();
|
|
649
674
|
return { cancelled: result.cancelled };
|
|
650
675
|
},
|
|
651
676
|
switchSession: async () => prohibitBrokerLifecycleOperation("session.switch"),
|
|
@@ -653,6 +678,8 @@ export class ExtensionUiController {
|
|
|
653
678
|
const previousSessionId = this.ctx.sessionManager.getSessionId();
|
|
654
679
|
await this.ctx.session.reload();
|
|
655
680
|
if (this.#isStopped()) return;
|
|
681
|
+
await this.ctx.session.notifySessionIdentityChanged();
|
|
682
|
+
if (this.#isStopped()) return;
|
|
656
683
|
const sessionIdentityChanged = previousSessionId !== this.ctx.sessionManager.getSessionId();
|
|
657
684
|
if (sessionIdentityChanged) this.ctx.resetIrcSidebarSession();
|
|
658
685
|
this.ctx.rebuildInitialMessages(sessionIdentityChanged ? "replace-identity" : "reconcile-same-transcript");
|
|
@@ -876,6 +903,7 @@ export class ExtensionUiController {
|
|
|
876
903
|
branch: async () => prohibitBrokerLifecycleOperation("session.branch"),
|
|
877
904
|
navigateTree: async (targetId, navOptions) => {
|
|
878
905
|
const result = await this.ctx.session.navigateTree(targetId, { summarize: navOptions?.summarize });
|
|
906
|
+
if (!result.cancelled) await this.ctx.session.notifySessionIdentityChanged();
|
|
879
907
|
return { cancelled: result.cancelled };
|
|
880
908
|
},
|
|
881
909
|
switchSession: async () => prohibitBrokerLifecycleOperation("session.switch"),
|
|
@@ -886,6 +914,8 @@ export class ExtensionUiController {
|
|
|
886
914
|
const previousSessionId = this.ctx.sessionManager.getSessionId();
|
|
887
915
|
await this.ctx.session.reload();
|
|
888
916
|
if (this.#isStopped()) return;
|
|
917
|
+
await this.ctx.session.notifySessionIdentityChanged();
|
|
918
|
+
if (this.#isStopped()) return;
|
|
889
919
|
const sessionIdentityChanged = previousSessionId !== this.ctx.sessionManager.getSessionId();
|
|
890
920
|
if (sessionIdentityChanged) this.ctx.resetIrcSidebarSession();
|
|
891
921
|
this.ctx.rebuildInitialMessages(sessionIdentityChanged ? "replace-identity" : "reconcile-same-transcript");
|
|
@@ -54,6 +54,7 @@ export class GoalModeController {
|
|
|
54
54
|
#enabled = false;
|
|
55
55
|
#paused = false;
|
|
56
56
|
#previousTools: string[] | undefined;
|
|
57
|
+
#previousMCPToolNames: string[] | undefined;
|
|
57
58
|
#continuationTimer: NodeJS.Timeout | undefined;
|
|
58
59
|
#turnHadToolCalls = false;
|
|
59
60
|
#continuationTurnInFlight = false;
|
|
@@ -264,8 +265,13 @@ export class GoalModeController {
|
|
|
264
265
|
if (this.#enabled || this.#paused) this.ctx.modeGate.enter("goal");
|
|
265
266
|
if (restored?.goal) {
|
|
266
267
|
this.#previousTools = this.ctx.session.getActiveToolNames();
|
|
268
|
+
this.#previousMCPToolNames = this.ctx.session.getActiveMCPToolNames();
|
|
267
269
|
if (!this.ctx.session.isExplicitEmptyToolSelection()) {
|
|
268
|
-
await this.ctx.session.setActiveToolsByName([...new Set([...this.#previousTools, "goal"])]
|
|
270
|
+
await this.ctx.session.setActiveToolsByName([...new Set([...this.#previousTools, "goal"])], {
|
|
271
|
+
explicit: false,
|
|
272
|
+
persistMCPSelection: false,
|
|
273
|
+
retryOnMcpCatalogChange: true,
|
|
274
|
+
});
|
|
269
275
|
}
|
|
270
276
|
}
|
|
271
277
|
this.#updateStatus();
|
|
@@ -316,16 +322,63 @@ export class GoalModeController {
|
|
|
316
322
|
}): Promise<void> {
|
|
317
323
|
if (this.#enabled) return;
|
|
318
324
|
if (!this.ctx.modeGate.enter("goal")) return this.ctx.showWarning("Exit plan mode first.");
|
|
325
|
+
const previousGoalState = this.ctx.session.getGoalModeState();
|
|
319
326
|
this.#previousTools = this.ctx.session.getActiveToolNames();
|
|
327
|
+
this.#previousMCPToolNames = this.ctx.session.getActiveMCPToolNames();
|
|
320
328
|
this.#paused = false;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
+
let state: GoalModeState;
|
|
330
|
+
try {
|
|
331
|
+
state = options.resume
|
|
332
|
+
? await this.ctx.session.goalRuntime.resumeGoal()
|
|
333
|
+
: await this.ctx.session.goalRuntime.createGoal({
|
|
334
|
+
objective: options.objective ?? "",
|
|
335
|
+
provenance: options.provenance,
|
|
336
|
+
});
|
|
337
|
+
if (!this.ctx.session.isExplicitEmptyToolSelection()) {
|
|
338
|
+
await this.ctx.session.setActiveToolsByName(
|
|
339
|
+
[...new Set([...this.#restoreToolsWithCurrentMCPSelection(this.#previousTools), "goal"])],
|
|
340
|
+
{
|
|
341
|
+
explicit: false,
|
|
342
|
+
persistMCPSelection: false,
|
|
343
|
+
retryOnMcpCatalogChange: true,
|
|
344
|
+
},
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
} catch (error) {
|
|
348
|
+
const currentGoalState = this.ctx.session.getGoalModeState();
|
|
349
|
+
const goalWasActivated =
|
|
350
|
+
currentGoalState?.enabled === true &&
|
|
351
|
+
currentGoalState.goal.status === "active" &&
|
|
352
|
+
(options.resume
|
|
353
|
+
? previousGoalState?.goal.status === "paused" && currentGoalState.goal.id === previousGoalState.goal.id
|
|
354
|
+
: currentGoalState.goal.id !== previousGoalState?.goal.id);
|
|
355
|
+
let rollbackError: unknown;
|
|
356
|
+
if (goalWasActivated) {
|
|
357
|
+
try {
|
|
358
|
+
if (options.resume) await this.ctx.session.goalRuntime.pauseGoal();
|
|
359
|
+
else await this.ctx.session.goalRuntime.dropGoal();
|
|
360
|
+
} catch (goalRollbackError) {
|
|
361
|
+
rollbackError = goalRollbackError;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
const rollbackState = this.ctx.session.getGoalModeState();
|
|
365
|
+
this.#enabled = rollbackState?.enabled === true;
|
|
366
|
+
this.#paused = rollbackState?.enabled !== true && rollbackState?.goal.status === "paused";
|
|
367
|
+
this.#previousTools = undefined;
|
|
368
|
+
this.#previousMCPToolNames = undefined;
|
|
369
|
+
this.#continuationTurnInFlight = false;
|
|
370
|
+
this.#resetContinuationSuppression();
|
|
371
|
+
this.cancelContinuation();
|
|
372
|
+
if (this.#enabled || this.#paused) this.ctx.modeGate.enter("goal");
|
|
373
|
+
else this.ctx.modeGate.exit("goal");
|
|
374
|
+
this.#updateStatus();
|
|
375
|
+
if (rollbackError !== undefined) {
|
|
376
|
+
throw new AggregateError(
|
|
377
|
+
[error, rollbackError],
|
|
378
|
+
"Goal-mode entry failed and goal state rollback also failed",
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
throw error;
|
|
329
382
|
}
|
|
330
383
|
this.ctx.session.setGoalModeState(state);
|
|
331
384
|
this.#enabled = true;
|
|
@@ -344,7 +397,12 @@ export class GoalModeController {
|
|
|
344
397
|
this.#previousTools &&
|
|
345
398
|
options?.reason !== "dropped" &&
|
|
346
399
|
(this.#enabled || options?.reason === "completed" || options?.paused);
|
|
347
|
-
if (shouldRestoreTools && this.#previousTools)
|
|
400
|
+
if (shouldRestoreTools && this.#previousTools)
|
|
401
|
+
await this.ctx.session.setActiveToolsByName(this.#restoreToolsWithCurrentMCPSelection(this.#previousTools), {
|
|
402
|
+
explicit: false,
|
|
403
|
+
persistMCPSelection: false,
|
|
404
|
+
retryOnMcpCatalogChange: true,
|
|
405
|
+
});
|
|
348
406
|
const currentState = this.ctx.session.getGoalModeState();
|
|
349
407
|
if (options?.reason === "completed") {
|
|
350
408
|
this.ctx.session.setGoalModeState(undefined);
|
|
@@ -358,6 +416,7 @@ export class GoalModeController {
|
|
|
358
416
|
this.#enabled = false;
|
|
359
417
|
this.#paused = options?.paused ?? false;
|
|
360
418
|
this.#previousTools = undefined;
|
|
419
|
+
this.#previousMCPToolNames = undefined;
|
|
361
420
|
this.#continuationTurnInFlight = false;
|
|
362
421
|
this.#resetContinuationSuppression();
|
|
363
422
|
this.cancelContinuation();
|
|
@@ -375,6 +434,16 @@ export class GoalModeController {
|
|
|
375
434
|
);
|
|
376
435
|
}
|
|
377
436
|
|
|
437
|
+
#restoreToolsWithCurrentMCPSelection(previousTools: readonly string[]): string[] {
|
|
438
|
+
const previousMCPToolNames = new Set(this.#previousMCPToolNames ?? []);
|
|
439
|
+
return [
|
|
440
|
+
...new Set([
|
|
441
|
+
...previousTools.filter(name => !previousMCPToolNames.has(name)),
|
|
442
|
+
...this.ctx.session.getActiveMCPToolNames(),
|
|
443
|
+
]),
|
|
444
|
+
];
|
|
445
|
+
}
|
|
446
|
+
|
|
378
447
|
#getPausedState(): GoalModeState | undefined {
|
|
379
448
|
const state = this.ctx.session.getGoalModeState();
|
|
380
449
|
return state?.goal && !state.enabled && state.goal.status === "paused" ? state : undefined;
|
|
@@ -1642,6 +1642,7 @@ export class InputController {
|
|
|
1642
1642
|
// Keep locally intercepted command arguments away from the title model.
|
|
1643
1643
|
if (this.ctx.session.isLocallyHandledSlashCommand(text)) return;
|
|
1644
1644
|
this.#autoTitleInFlightSessionId = sessionId;
|
|
1645
|
+
const activeCwd = this.ctx.sessionManager.getCwd();
|
|
1645
1646
|
generateSessionTitle(
|
|
1646
1647
|
text,
|
|
1647
1648
|
this.ctx.session.modelRegistry,
|
|
@@ -1649,6 +1650,7 @@ export class InputController {
|
|
|
1649
1650
|
this.ctx.session.credentialSessionId,
|
|
1650
1651
|
this.ctx.session.model,
|
|
1651
1652
|
provider => this.ctx.session.agent.metadataForProvider(provider),
|
|
1653
|
+
activeCwd,
|
|
1652
1654
|
)
|
|
1653
1655
|
.then(async title => {
|
|
1654
1656
|
if (!title || this.ctx.sessionManager.getSessionId() !== sessionId) return;
|