apex-code 0.0.1-alpha.8 → 0.0.4
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 +231 -0
- package/README.md +9 -8
- package/dist/cli/args.d.ts +26 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +72 -10
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/mcp-command.d.ts +9 -0
- package/dist/cli/mcp-command.d.ts.map +1 -0
- package/dist/cli/mcp-command.js +53 -0
- package/dist/cli/mcp-command.js.map +1 -0
- package/dist/cli/project-trust.d.ts.map +1 -1
- package/dist/cli/project-trust.js +3 -1
- package/dist/cli/project-trust.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +2 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +94 -5
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +45 -18
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +3 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +183 -15
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +728 -117
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +6 -7
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +7 -0
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/checkpoints/git-checkpoints.d.ts +39 -0
- package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/git-checkpoints.js +251 -0
- package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.js +36 -0
- package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +7 -3
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +9 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +59 -36
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/delegation/runtime.d.ts +6 -5
- package/dist/core/delegation/runtime.d.ts.map +1 -1
- package/dist/core/delegation/runtime.js +4 -3
- package/dist/core/delegation/runtime.js.map +1 -1
- package/dist/core/durable-state/sqlite.d.ts.map +1 -1
- package/dist/core/durable-state/sqlite.js +26 -2
- package/dist/core/durable-state/sqlite.js.map +1 -1
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +5 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +123 -50
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +5 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +45 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/source-runtime.d.ts +14 -0
- package/dist/core/extensions/source-runtime.d.ts.map +1 -0
- package/dist/core/extensions/source-runtime.js +56 -0
- package/dist/core/extensions/source-runtime.js.map +1 -0
- package/dist/core/extensions/types.d.ts +60 -11
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/formatter-lifecycle.d.ts +69 -0
- package/dist/core/formatter-lifecycle.d.ts.map +1 -0
- package/dist/core/formatter-lifecycle.js +360 -0
- package/dist/core/formatter-lifecycle.js.map +1 -0
- package/dist/core/hooks/command-handler.d.ts +19 -0
- package/dist/core/hooks/command-handler.d.ts.map +1 -0
- package/dist/core/hooks/command-handler.js +112 -0
- package/dist/core/hooks/command-handler.js.map +1 -0
- package/dist/core/hooks/http-handler.d.ts +10 -0
- package/dist/core/hooks/http-handler.d.ts.map +1 -0
- package/dist/core/hooks/http-handler.js +36 -0
- package/dist/core/hooks/http-handler.js.map +1 -0
- package/dist/core/hooks/loader.d.ts +29 -0
- package/dist/core/hooks/loader.d.ts.map +1 -0
- package/dist/core/hooks/loader.js +139 -0
- package/dist/core/hooks/loader.js.map +1 -0
- package/dist/core/hooks/runtime.d.ts +13 -0
- package/dist/core/hooks/runtime.d.ts.map +1 -0
- package/dist/core/hooks/runtime.js +63 -0
- package/dist/core/hooks/runtime.js.map +1 -0
- package/dist/core/hooks/types.d.ts +83 -0
- package/dist/core/hooks/types.d.ts.map +1 -0
- package/dist/core/hooks/types.js +24 -0
- package/dist/core/hooks/types.js.map +1 -0
- package/dist/core/keybindings.d.ts +20 -19
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/mcp/config.d.ts +16 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +166 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/connector.d.ts +35 -0
- package/dist/core/mcp/connector.d.ts.map +1 -0
- package/dist/core/mcp/connector.js +105 -0
- package/dist/core/mcp/connector.js.map +1 -0
- package/dist/core/mcp/contract.d.ts +19 -0
- package/dist/core/mcp/contract.d.ts.map +1 -0
- package/dist/core/mcp/contract.js +89 -0
- package/dist/core/mcp/contract.js.map +1 -0
- package/dist/core/mcp/mcp-tool.d.ts +32 -0
- package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
- package/dist/core/mcp/mcp-tool.js +171 -0
- package/dist/core/mcp/mcp-tool.js.map +1 -0
- package/dist/core/mcp/metadata-cache.d.ts +29 -0
- package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/core/mcp/metadata-cache.js +99 -0
- package/dist/core/mcp/metadata-cache.js.map +1 -0
- package/dist/core/mcp/oauth/authorize.d.ts +21 -0
- package/dist/core/mcp/oauth/authorize.d.ts.map +1 -0
- package/dist/core/mcp/oauth/authorize.js +32 -0
- package/dist/core/mcp/oauth/authorize.js.map +1 -0
- package/dist/core/mcp/oauth/discover.d.ts +27 -0
- package/dist/core/mcp/oauth/discover.d.ts.map +1 -0
- package/dist/core/mcp/oauth/discover.js +116 -0
- package/dist/core/mcp/oauth/discover.js.map +1 -0
- package/dist/core/mcp/oauth/flow.d.ts +31 -0
- package/dist/core/mcp/oauth/flow.d.ts.map +1 -0
- package/dist/core/mcp/oauth/flow.js +175 -0
- package/dist/core/mcp/oauth/flow.js.map +1 -0
- package/dist/core/mcp/oauth/mcp-token.d.ts +51 -0
- package/dist/core/mcp/oauth/mcp-token.d.ts.map +1 -0
- package/dist/core/mcp/oauth/mcp-token.js +129 -0
- package/dist/core/mcp/oauth/mcp-token.js.map +1 -0
- package/dist/core/mcp/oauth/pkce.d.ts +12 -0
- package/dist/core/mcp/oauth/pkce.d.ts.map +1 -0
- package/dist/core/mcp/oauth/pkce.js +11 -0
- package/dist/core/mcp/oauth/pkce.js.map +1 -0
- package/dist/core/mcp/oauth/register.d.ts +16 -0
- package/dist/core/mcp/oauth/register.d.ts.map +1 -0
- package/dist/core/mcp/oauth/register.js +42 -0
- package/dist/core/mcp/oauth/register.js.map +1 -0
- package/dist/core/mcp/oauth/token-client.d.ts +33 -0
- package/dist/core/mcp/oauth/token-client.d.ts.map +1 -0
- package/dist/core/mcp/oauth/token-client.js +65 -0
- package/dist/core/mcp/oauth/token-client.js.map +1 -0
- package/dist/core/mcp/runtime.d.ts +20 -0
- package/dist/core/mcp/runtime.d.ts.map +1 -0
- package/dist/core/mcp/runtime.js +37 -0
- package/dist/core/mcp/runtime.js.map +1 -0
- package/dist/core/mcp/schema.d.ts +22 -0
- package/dist/core/mcp/schema.d.ts.map +1 -0
- package/dist/core/mcp/schema.js +20 -0
- package/dist/core/mcp/schema.js.map +1 -0
- package/dist/core/mcp/server-manager.d.ts +43 -0
- package/dist/core/mcp/server-manager.d.ts.map +1 -0
- package/dist/core/mcp/server-manager.js +142 -0
- package/dist/core/mcp/server-manager.js.map +1 -0
- package/dist/core/mcp/types.d.ts +100 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +8 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/model-config.d.ts +5 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +3 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +14 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +22 -14
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions/gate.d.ts.map +1 -1
- package/dist/core/permissions/gate.js +45 -4
- package/dist/core/permissions/gate.js.map +1 -1
- package/dist/core/permissions/operations.d.ts +20 -0
- package/dist/core/permissions/operations.d.ts.map +1 -0
- package/dist/core/permissions/operations.js +9 -0
- package/dist/core/permissions/operations.js.map +1 -0
- package/dist/core/permissions/policy-command.d.ts +42 -0
- package/dist/core/permissions/policy-command.d.ts.map +1 -0
- package/dist/core/permissions/policy-command.js +44 -0
- package/dist/core/permissions/policy-command.js.map +1 -0
- package/dist/core/permissions/responder.d.ts +49 -2
- package/dist/core/permissions/responder.d.ts.map +1 -1
- package/dist/core/permissions/responder.js +20 -8
- package/dist/core/permissions/responder.js.map +1 -1
- package/dist/core/permissions/rules.d.ts.map +1 -1
- package/dist/core/permissions/rules.js +11 -1
- package/dist/core/permissions/rules.js.map +1 -1
- package/dist/core/permissions/store.d.ts +18 -0
- package/dist/core/permissions/store.d.ts.map +1 -1
- package/dist/core/permissions/store.js +89 -8
- package/dist/core/permissions/store.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/policy-executor.d.ts +47 -0
- package/dist/core/policy-executor.d.ts.map +1 -0
- package/dist/core/policy-executor.js +228 -0
- package/dist/core/policy-executor.js.map +1 -0
- package/dist/core/policy-loader.d.ts +72 -0
- package/dist/core/policy-loader.d.ts.map +1 -0
- package/dist/core/policy-loader.js +195 -0
- package/dist/core/policy-loader.js.map +1 -0
- package/dist/core/project-trust.d.ts +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/bwrap-arguments.d.ts +41 -0
- package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
- package/dist/core/sandbox/bwrap-arguments.js +136 -0
- package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
- package/dist/core/sandbox/child-entry.d.ts.map +1 -1
- package/dist/core/sandbox/child-entry.js +3 -1
- package/dist/core/sandbox/child-entry.js.map +1 -1
- package/dist/core/sandbox/cli-launch.d.ts +84 -4
- package/dist/core/sandbox/cli-launch.d.ts.map +1 -1
- package/dist/core/sandbox/cli-launch.js +115 -16
- package/dist/core/sandbox/cli-launch.js.map +1 -1
- package/dist/core/sandbox/cli-supervisor.d.ts +2 -0
- package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -1
- package/dist/core/sandbox/cli-supervisor.js +50 -2
- package/dist/core/sandbox/cli-supervisor.js.map +1 -1
- package/dist/core/sandbox/full-access.d.ts +28 -0
- package/dist/core/sandbox/full-access.d.ts.map +1 -0
- package/dist/core/sandbox/full-access.js +63 -0
- package/dist/core/sandbox/full-access.js.map +1 -0
- package/dist/core/sandbox/git-identity.d.ts +57 -0
- package/dist/core/sandbox/git-identity.d.ts.map +1 -0
- package/dist/core/sandbox/git-identity.js +78 -0
- package/dist/core/sandbox/git-identity.js.map +1 -0
- package/dist/core/sandbox/host-approval.d.ts +42 -0
- package/dist/core/sandbox/host-approval.d.ts.map +1 -0
- package/dist/core/sandbox/host-approval.js +99 -0
- package/dist/core/sandbox/host-approval.js.map +1 -0
- package/dist/core/sandbox/linux-backend.d.ts +14 -0
- package/dist/core/sandbox/linux-backend.d.ts.map +1 -1
- package/dist/core/sandbox/linux-backend.js +158 -80
- package/dist/core/sandbox/linux-backend.js.map +1 -1
- package/dist/core/sandbox/macos-backend.d.ts +5 -0
- package/dist/core/sandbox/macos-backend.d.ts.map +1 -1
- package/dist/core/sandbox/macos-backend.js +164 -5
- package/dist/core/sandbox/macos-backend.js.map +1 -1
- package/dist/core/sandbox/network-proxy.d.ts +19 -0
- package/dist/core/sandbox/network-proxy.d.ts.map +1 -1
- package/dist/core/sandbox/network-proxy.js +93 -19
- package/dist/core/sandbox/network-proxy.js.map +1 -1
- package/dist/core/sandbox/policy.d.ts +8 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -1
- package/dist/core/sandbox/policy.js +29 -12
- package/dist/core/sandbox/policy.js.map +1 -1
- package/dist/core/sandbox/profiles.d.ts +25 -0
- package/dist/core/sandbox/profiles.d.ts.map +1 -0
- package/dist/core/sandbox/profiles.js +23 -0
- package/dist/core/sandbox/profiles.js.map +1 -0
- package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
- package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-client.js +86 -0
- package/dist/core/sandbox/rpc/command-client.js.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.js +120 -0
- package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -1
- package/dist/core/sandbox/rpc/credential-proxy.js +2 -96
- package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -1
- package/dist/core/sandbox/rpc/framing.d.ts +35 -0
- package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/framing.js +114 -0
- package/dist/core/sandbox/rpc/framing.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts +47 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js +222 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +66 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js +209 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
- package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
- package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor-temp.js +21 -0
- package/dist/core/sandbox/supervisor-temp.js.map +1 -0
- package/dist/core/sandbox/supervisor.d.ts +12 -1
- package/dist/core/sandbox/supervisor.d.ts.map +1 -1
- package/dist/core/sandbox/supervisor.js +15 -1
- package/dist/core/sandbox/supervisor.js.map +1 -1
- package/dist/core/sandbox/terminal-handoff.d.ts +68 -0
- package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-handoff.js +221 -0
- package/dist/core/sandbox/terminal-handoff.js.map +1 -0
- package/dist/core/sandbox/terminal-size.d.ts +13 -0
- package/dist/core/sandbox/terminal-size.d.ts.map +1 -1
- package/dist/core/sandbox/terminal-size.js +23 -2
- package/dist/core/sandbox/terminal-size.js.map +1 -1
- package/dist/core/sdk.d.ts +24 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +63 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-manager.d.ts +13 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +34 -6
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +172 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +160 -11
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +4 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +8 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/background-shell.d.ts +39 -0
- package/dist/core/tools/background-shell.d.ts.map +1 -0
- package/dist/core/tools/background-shell.js +81 -0
- package/dist/core/tools/background-shell.js.map +1 -0
- package/dist/core/tools/bash-command-segments.d.ts.map +1 -1
- package/dist/core/tools/bash-command-segments.js +2 -0
- package/dist/core/tools/bash-command-segments.js.map +1 -1
- package/dist/core/tools/bash.d.ts +44 -16
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +264 -32
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/contract-snapshot.d.ts +58 -0
- package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
- package/dist/core/tools/contract-snapshot.js +51 -0
- package/dist/core/tools/contract-snapshot.js.map +1 -0
- package/dist/core/tools/contract.d.ts +53 -5
- package/dist/core/tools/contract.d.ts.map +1 -1
- package/dist/core/tools/contract.js +22 -2
- package/dist/core/tools/contract.js.map +1 -1
- package/dist/core/tools/delegate.d.ts +6 -4
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +21 -11
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +48 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +217 -8
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +8 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +72 -10
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +5 -2
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +5 -2
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +14 -2
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +12 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +5 -2
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/lsp.d.ts +19 -1
- package/dist/core/tools/lsp.d.ts.map +1 -1
- package/dist/core/tools/lsp.js +163 -10
- package/dist/core/tools/lsp.js.map +1 -1
- package/dist/core/tools/path-permission.d.ts +3 -0
- package/dist/core/tools/path-permission.d.ts.map +1 -1
- package/dist/core/tools/path-permission.js +16 -4
- package/dist/core/tools/path-permission.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +27 -2
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +221 -4
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +20 -11
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/test.d.ts +54 -9
- package/dist/core/tools/test.d.ts.map +1 -1
- package/dist/core/tools/test.js +239 -19
- package/dist/core/tools/test.js.map +1 -1
- package/dist/core/tools/write.d.ts +7 -0
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +64 -9
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/verification-lifecycle.d.ts +77 -0
- package/dist/core/verification-lifecycle.d.ts.map +1 -0
- package/dist/core/verification-lifecycle.js +146 -0
- package/dist/core/verification-lifecycle.js.map +1 -0
- package/dist/core/workspace/artifacts.d.ts +45 -0
- package/dist/core/workspace/artifacts.d.ts.map +1 -0
- package/dist/core/workspace/artifacts.js +165 -0
- package/dist/core/workspace/artifacts.js.map +1 -0
- package/dist/core/workspace/comparison.d.ts +27 -0
- package/dist/core/workspace/comparison.d.ts.map +1 -0
- package/dist/core/workspace/comparison.js +94 -0
- package/dist/core/workspace/comparison.js.map +1 -0
- package/dist/core/workspace/git-observer.d.ts +48 -0
- package/dist/core/workspace/git-observer.d.ts.map +1 -0
- package/dist/core/workspace/git-observer.js +346 -0
- package/dist/core/workspace/git-observer.js.map +1 -0
- package/dist/core/workspace/projection.d.ts +3 -0
- package/dist/core/workspace/projection.d.ts.map +1 -0
- package/dist/core/workspace/projection.js +56 -0
- package/dist/core/workspace/projection.js.map +1 -0
- package/dist/core/workspace/state.d.ts +133 -0
- package/dist/core/workspace/state.d.ts.map +1 -0
- package/dist/core/workspace/state.js +96 -0
- package/dist/core/workspace/state.js.map +1 -0
- package/dist/extensions/llama/client.d.ts +6 -0
- package/dist/extensions/llama/client.d.ts.map +1 -1
- package/dist/extensions/llama/client.js +7 -0
- package/dist/extensions/llama/client.js.map +1 -1
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts +3 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +29 -4
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +6 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +58 -23
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/acp/server.d.ts +55 -0
- package/dist/modes/acp/server.d.ts.map +1 -0
- package/dist/modes/acp/server.js +244 -0
- package/dist/modes/acp/server.js.map +1 -0
- package/dist/modes/acp/translate.d.ts +37 -0
- package/dist/modes/acp/translate.d.ts.map +1 -0
- package/dist/modes/acp/translate.js +50 -0
- package/dist/modes/acp/translate.js.map +1 -0
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +182 -23
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +20 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +9 -4
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +20 -9
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +7 -1
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +7 -3
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +19 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +70 -10
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +10 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +56 -14
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/permission-preview.d.ts +15 -0
- package/dist/modes/interactive/components/permission-preview.d.ts.map +1 -0
- package/dist/modes/interactive/components/permission-preview.js +33 -0
- package/dist/modes/interactive/components/permission-preview.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +2 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +9 -2
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +128 -56
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +23 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +64 -10
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +45 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +395 -43
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +12 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +20 -9
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +27 -12
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +7 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +12 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +196 -10
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +23 -9
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +6 -4
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +19 -0
- package/docs/custom-provider.md +12 -9
- package/docs/environment-variables.md +1 -1
- package/docs/extensions.md +35 -7
- package/docs/json.md +7 -2
- package/docs/keybindings.md +9 -9
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +32 -3
- package/docs/sdk.md +32 -2
- package/docs/settings.md +23 -7
- package/docs/skills.md +4 -3
- package/docs/terminal-setup.md +23 -7
- package/docs/usage.md +10 -5
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/built-in-tool-renderer.ts +8 -4
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +24 -36
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/minimal-mode.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/permission-gate.ts +1 -1
- package/examples/extensions/plan-mode/index.ts +1 -1
- package/examples/extensions/rpc-demo.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +439 -405
- package/package.json +17 -17
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -107
- package/dist/server/create-harness.js.map +0 -1
|
@@ -7,22 +7,25 @@ import * as fs from "node:fs";
|
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as path from "node:path";
|
|
9
9
|
import * as TuiLayouts from "@earendil-works/pi-tui";
|
|
10
|
-
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
10
|
+
import { CombinedAutocompleteProvider, Container, fuzzyFilter, getCapabilities, hyperlink, Markdown, matchesKey, ProcessTerminal, Spacer, setCapabilityOverrides, setKeybindings, Text, TruncatedText, TuiAltScreen, TuiMainScreen, visibleWidth, } from "@earendil-works/pi-tui";
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import { spawn, spawnSync } from "child_process";
|
|
13
13
|
import { APP_NAME, APP_TITLE, CONFIG_DIR_NAME, getAgentDir, getAuthPath, getDebugLogPath, getDocsPath, getShareViewerUrl, VERSION, } from "../../config.js";
|
|
14
14
|
import { parseSkillBlock } from "../../core/agent-session.js";
|
|
15
15
|
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
16
16
|
import { CACHE_TTL_MS, collectCacheMisses, computeCacheWaste, detectCacheMiss, } from "../../core/cache-stats.js";
|
|
17
|
+
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defaults.js";
|
|
17
18
|
import { getApexEnvironment } from "../../core/environment.js";
|
|
18
19
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
19
20
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
20
21
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
22
|
+
import { authorizeConfiguredServer } from "../../core/mcp/oauth/authorize.js";
|
|
21
23
|
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
22
24
|
import { defaultModelPerProvider, findExactModelReferenceMatch, resolveModelScopeFromModels, } from "../../core/model-resolver.js";
|
|
23
25
|
import { CredentialSynchronizationError } from "../../core/model-runtime.js";
|
|
24
26
|
import { aggregateUsagePerformance } from "../../core/observability/aggregate.js";
|
|
25
27
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
28
|
+
import { observeTerminalHandoff, TERMINAL_HANDOFF_ACK_PATH_VARIABLE, TERMINAL_HANDOFF_PATH_VARIABLE, } from "../../core/sandbox/terminal-handoff.js";
|
|
26
29
|
import { formatMissingSessionCwdPrompt, MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
27
30
|
import { SessionManager, sessionEntryToContextMessages } from "../../core/session-manager.js";
|
|
28
31
|
import { formatShareUnavailableMessage, publishSessionShare } from "../../core/session-share.js";
|
|
@@ -37,6 +40,7 @@ import { parseGitUrl } from "../../utils/git.js";
|
|
|
37
40
|
import { openBrowser } from "../../utils/open-browser.js";
|
|
38
41
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
39
42
|
import { killTrackedDetachedChildren } from "../../utils/shell.js";
|
|
43
|
+
import { loadAllHighlightLanguages } from "../../utils/syntax-highlight.js";
|
|
40
44
|
import { ensureTool } from "../../utils/tools-manager.js";
|
|
41
45
|
import { checkForNewApexCodeVersion } from "../../utils/version-check.js";
|
|
42
46
|
import { ArminComponent } from "./components/armin.js";
|
|
@@ -61,12 +65,14 @@ import { LoginDialogComponent } from "./components/login-dialog.js";
|
|
|
61
65
|
import { createMermaidMarkdownTransformer } from "./components/mermaid.js";
|
|
62
66
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
63
67
|
import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
68
|
+
import { renderPermissionPreview } from "./components/permission-preview.js";
|
|
64
69
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
65
70
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
66
71
|
import { PERMISSION_MODE_OVERRIDE_HINTS, SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
67
72
|
import { SkillInvocationMessageComponent } from "./components/skill-invocation-message.js";
|
|
68
73
|
import { ApexSplashHeader } from "./components/splash-header.js";
|
|
69
74
|
import { BranchSummaryStatusIndicator, CompactionStatusIndicator, IdleStatus, RetryStatusIndicator, WorkingStatusIndicator, } from "./components/status-indicator.js";
|
|
75
|
+
import { ThinkingSelectorComponent } from "./components/thinking-selector.js";
|
|
70
76
|
import { ToolExecutionComponent } from "./components/tool-execution.js";
|
|
71
77
|
import { TreeSelectorComponent } from "./components/tree-selector.js";
|
|
72
78
|
import { TrustSelectorComponent } from "./components/trust-selector.js";
|
|
@@ -95,6 +101,9 @@ class ExpandableText extends Text {
|
|
|
95
101
|
function isCustomSessionEntry(item) {
|
|
96
102
|
return "type" in item && item.type === "custom";
|
|
97
103
|
}
|
|
104
|
+
function isCompactionCostNotice(item) {
|
|
105
|
+
return "type" in item && item.type === "compaction_cost";
|
|
106
|
+
}
|
|
98
107
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
99
108
|
function isDeadTerminalError(error) {
|
|
100
109
|
if (!error || typeof error !== "object" || !("code" in error)) {
|
|
@@ -134,6 +143,11 @@ export function formatResumeCommand(sessionManager) {
|
|
|
134
143
|
function hasDefaultModelProvider(providerId) {
|
|
135
144
|
return providerId in defaultModelPerProvider;
|
|
136
145
|
}
|
|
146
|
+
function llamaCppPostLoginGuidance(actionLabel, loadedModelCount) {
|
|
147
|
+
return loadedModelCount === 0
|
|
148
|
+
? `${actionLabel}. No llama.cpp models are loaded. Use /llama to load a model, then /model to select it.`
|
|
149
|
+
: `${actionLabel}. Use /model to select a loaded llama.cpp model, or /llama to manage models.`;
|
|
150
|
+
}
|
|
137
151
|
const AUTH_TYPE_ORDER = { oauth: 0, api_key: 1 };
|
|
138
152
|
function createFuzzyAutocompleteItems(items, prefix, getSearchText, toAutocompleteItem) {
|
|
139
153
|
const filtered = fuzzyFilter(items, prefix, getSearchText);
|
|
@@ -180,6 +194,7 @@ export function createInteractiveTui(options) {
|
|
|
180
194
|
searchCurrentMatchStyle: (text) => theme.bold(theme.inverse(styleSearchMatch(text))),
|
|
181
195
|
openUrl: openBrowser,
|
|
182
196
|
onRightClickPaste: options.onRightClickPaste,
|
|
197
|
+
copyOnSelect: options.fullscreenCopyOnSelect,
|
|
183
198
|
copySelection: async (text) => {
|
|
184
199
|
try {
|
|
185
200
|
await copyToClipboard(text);
|
|
@@ -224,6 +239,23 @@ export function createInteractiveTuiReference(getTui) {
|
|
|
224
239
|
getPrototypeOf: () => Reflect.getPrototypeOf(getTui()),
|
|
225
240
|
});
|
|
226
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* Working status rides in the footer tray; everything else keeps its own rows.
|
|
244
|
+
*
|
|
245
|
+
* The tray is a line the screen already spends, so a turn no longer costs two
|
|
246
|
+
* rows above the editor. Retry, compaction and branch summary stay in the status
|
|
247
|
+
* container. They are interruptions rather than steady state and they carry
|
|
248
|
+
* their own countdowns.
|
|
249
|
+
*
|
|
250
|
+
* A custom footer replaces the built-in one entirely, so a session running one
|
|
251
|
+
* keeps its indicator where it can still be seen.
|
|
252
|
+
*
|
|
253
|
+
* Free of `this` so the white-box prototype tests can exercise the callers
|
|
254
|
+
* without fabricating a whole InteractiveMode.
|
|
255
|
+
*/
|
|
256
|
+
function trayOwnsActivity(kind, hasCustomFooter) {
|
|
257
|
+
return kind === "working" && !hasCustomFooter;
|
|
258
|
+
}
|
|
227
259
|
export class InteractiveMode {
|
|
228
260
|
runtimeHost;
|
|
229
261
|
/** Settled once the most recent /settings permission-mode write has hit disk. */
|
|
@@ -305,6 +337,11 @@ export class InteractiveMode {
|
|
|
305
337
|
firstUseHints;
|
|
306
338
|
// Track current bash execution component
|
|
307
339
|
bashComponent = undefined;
|
|
340
|
+
// Reentrancy guard: session.isBashRunning only turns true inside
|
|
341
|
+
// executeBash, so a second `!cmd` submitted during the extension
|
|
342
|
+
// emitUserBash await would otherwise overwrite the in-flight component
|
|
343
|
+
// and orphan the first command's output callback.
|
|
344
|
+
isHandlingBashCommand = false;
|
|
308
345
|
// Track pending bash components (shown in pending area, moved to chat on submit)
|
|
309
346
|
pendingBashComponents = [];
|
|
310
347
|
// Auto-compaction state
|
|
@@ -362,6 +399,7 @@ export class InteractiveMode {
|
|
|
362
399
|
}
|
|
363
400
|
constructor(runtimeHost, options = {}) {
|
|
364
401
|
this.runtimeHost = runtimeHost;
|
|
402
|
+
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
365
403
|
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
366
404
|
this.options = { ...options, tuiMode };
|
|
367
405
|
this.autoTrustOnReloadCwd = options.autoTrustOnReloadCwd;
|
|
@@ -378,6 +416,7 @@ export class InteractiveMode {
|
|
|
378
416
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
379
417
|
logDirectory: getAgentDir(),
|
|
380
418
|
onRightClickPaste: this.onRightClickPaste,
|
|
419
|
+
fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
|
|
381
420
|
});
|
|
382
421
|
this.ui = createInteractiveTuiReference(() => this.renderer);
|
|
383
422
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
@@ -401,6 +440,10 @@ export class InteractiveMode {
|
|
|
401
440
|
autocompleteMaxVisible,
|
|
402
441
|
promptPrefix: "› ",
|
|
403
442
|
promptColor: (text) => theme.fg("accent", text),
|
|
443
|
+
// Bash mode changes the glyph as well as the hue, so the mode is still
|
|
444
|
+
// readable on a monochrome terminal. Same cell count, so nothing shifts.
|
|
445
|
+
bashPromptPrefix: "! ",
|
|
446
|
+
bashPromptColor: (text) => theme.fg("bashMode", text),
|
|
404
447
|
placeholder: "Ask anything",
|
|
405
448
|
placeholderColor: (text) => theme.fg("dim", text),
|
|
406
449
|
commandColor: (text) => theme.fg("accent", text),
|
|
@@ -467,8 +510,21 @@ export class InteractiveMode {
|
|
|
467
510
|
path: command.sourceInfo.path,
|
|
468
511
|
}));
|
|
469
512
|
}
|
|
470
|
-
|
|
471
|
-
|
|
513
|
+
/**
|
|
514
|
+
* Every *registered* command: builtin, prompt template, extension, and skill.
|
|
515
|
+
*
|
|
516
|
+
* One function rather than two because `/help` renders this list and autocomplete
|
|
517
|
+
* completes it. Built in two places they would disagree the first time either grew a
|
|
518
|
+
* source, and the disagreement would show up as a command a user can complete but not
|
|
519
|
+
* find, or find but not run.
|
|
520
|
+
*
|
|
521
|
+
* A few commands are dispatched without being registered -- `/debug`, and the
|
|
522
|
+
* `/arminsayshi` and `/dementedelves` easter eggs. They are absent here on purpose,
|
|
523
|
+
* which is also why autocomplete has never offered them. "Registered" is the boundary
|
|
524
|
+
* both surfaces share; listing them in `/help` would advertise what completion cannot
|
|
525
|
+
* complete.
|
|
526
|
+
*/
|
|
527
|
+
collectSessionCommands() {
|
|
472
528
|
const slashCommands = BUILTIN_SLASH_COMMANDS.map((command) => ({
|
|
473
529
|
name: command.name,
|
|
474
530
|
description: command.description,
|
|
@@ -496,6 +552,15 @@ export class InteractiveMode {
|
|
|
496
552
|
}));
|
|
497
553
|
};
|
|
498
554
|
}
|
|
555
|
+
const thinkingCommand = slashCommands.find((command) => command.name === "thinking");
|
|
556
|
+
if (thinkingCommand) {
|
|
557
|
+
thinkingCommand.getArgumentCompletions = (prefix) => {
|
|
558
|
+
return createFuzzyAutocompleteItems(this.session.getAvailableThinkingLevels(), prefix, (level) => level, (level) => ({
|
|
559
|
+
value: level,
|
|
560
|
+
label: level,
|
|
561
|
+
}));
|
|
562
|
+
};
|
|
563
|
+
}
|
|
499
564
|
const loginCommand = slashCommands.find((command) => command.name === "login");
|
|
500
565
|
if (loginCommand) {
|
|
501
566
|
loginCommand.getArgumentCompletions = (prefix) => {
|
|
@@ -536,7 +601,10 @@ export class InteractiveMode {
|
|
|
536
601
|
});
|
|
537
602
|
}
|
|
538
603
|
}
|
|
539
|
-
return
|
|
604
|
+
return [...slashCommands, ...templateCommands, ...extensionCommands, ...skillCommandList];
|
|
605
|
+
}
|
|
606
|
+
createBaseAutocompleteProvider() {
|
|
607
|
+
return new CombinedAutocompleteProvider(this.collectSessionCommands(), this.sessionManager.getCwd(), this.fdPath);
|
|
540
608
|
}
|
|
541
609
|
setupAutocompleteProvider() {
|
|
542
610
|
let provider = this.createBaseAutocompleteProvider();
|
|
@@ -624,6 +692,7 @@ export class InteractiveMode {
|
|
|
624
692
|
logDirectory: getAgentDir(),
|
|
625
693
|
terminal,
|
|
626
694
|
onRightClickPaste: this.onRightClickPaste,
|
|
695
|
+
fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
|
|
627
696
|
});
|
|
628
697
|
nextUi.setClearOnShrink(clearOnShrink);
|
|
629
698
|
nextUi.onDebug = onDebug;
|
|
@@ -792,6 +861,14 @@ export class InteractiveMode {
|
|
|
792
861
|
});
|
|
793
862
|
// Initialize available provider count for footer display
|
|
794
863
|
await this.updateAvailableProviderCount();
|
|
864
|
+
// Flush the completed startup state before loading the remaining syntax grammars.
|
|
865
|
+
this.ui.renderNow();
|
|
866
|
+
void loadAllHighlightLanguages().then(() => {
|
|
867
|
+
if (!this.isInitialized)
|
|
868
|
+
return;
|
|
869
|
+
this.ui.invalidate();
|
|
870
|
+
this.ui.requestRender();
|
|
871
|
+
});
|
|
795
872
|
}
|
|
796
873
|
/**
|
|
797
874
|
* Update terminal title with session name and cwd.
|
|
@@ -847,7 +924,18 @@ export class InteractiveMode {
|
|
|
847
924
|
}
|
|
848
925
|
});
|
|
849
926
|
// Show startup warnings
|
|
850
|
-
const { migratedProviders, modelFallbackMessage, initialMessage, initialImages, initialMessages } = this.options;
|
|
927
|
+
const { migratedProviders, startupDiagnostics, modelFallbackMessage, initialMessage, initialImages, initialMessages, } = this.options;
|
|
928
|
+
for (const diagnostic of startupDiagnostics ?? []) {
|
|
929
|
+
if (diagnostic.type === "error") {
|
|
930
|
+
this.showError(diagnostic.message);
|
|
931
|
+
}
|
|
932
|
+
else if (diagnostic.type === "warning") {
|
|
933
|
+
this.showWarning(diagnostic.message);
|
|
934
|
+
}
|
|
935
|
+
else {
|
|
936
|
+
this.showStatus(diagnostic.message);
|
|
937
|
+
}
|
|
938
|
+
}
|
|
851
939
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
852
940
|
this.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(", ")}`);
|
|
853
941
|
}
|
|
@@ -1569,8 +1657,12 @@ export class InteractiveMode {
|
|
|
1569
1657
|
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1570
1658
|
}
|
|
1571
1659
|
applyRuntimeSettings() {
|
|
1660
|
+
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
1572
1661
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1573
1662
|
this.applyFullscreenScrollbarSetting();
|
|
1663
|
+
if (this.renderer instanceof TuiAltScreen) {
|
|
1664
|
+
this.renderer.setCopyOnSelect(this.settingsManager.getFullscreenCopyOnSelect());
|
|
1665
|
+
}
|
|
1574
1666
|
this.footer.setSession(this.session);
|
|
1575
1667
|
this.footer.setAutoCompactEnabled(this.session.autoCompactionEnabled);
|
|
1576
1668
|
void this.refreshFooterPermissionMode();
|
|
@@ -1626,6 +1718,15 @@ export class InteractiveMode {
|
|
|
1626
1718
|
this.compactionQueuedMessages = [];
|
|
1627
1719
|
this.streamingComponent = undefined;
|
|
1628
1720
|
this.streamingMessage = undefined;
|
|
1721
|
+
// The clears above detach children without stopping their animation
|
|
1722
|
+
// timers. Bash components embed an animated loader; dispose them
|
|
1723
|
+
// explicitly so an in-flight `!cmd` cannot keep rendering (or get
|
|
1724
|
+
// flushed back into a fresh session by flushPendingBashComponents).
|
|
1725
|
+
for (const component of this.pendingBashComponents)
|
|
1726
|
+
component.dispose();
|
|
1727
|
+
this.pendingBashComponents = [];
|
|
1728
|
+
this.bashComponent?.dispose();
|
|
1729
|
+
this.bashComponent = undefined;
|
|
1629
1730
|
this.clearPendingTools();
|
|
1630
1731
|
this.renderInitialMessages();
|
|
1631
1732
|
}
|
|
@@ -1712,6 +1813,11 @@ export class InteractiveMode {
|
|
|
1712
1813
|
this.activeStatusIndicator?.dispose();
|
|
1713
1814
|
this.activeStatusIndicator = indicator;
|
|
1714
1815
|
this.statusContainer.clear();
|
|
1816
|
+
if (trayOwnsActivity(indicator.kind, this.customFooter !== undefined)) {
|
|
1817
|
+
this.footer.setActivity(indicator);
|
|
1818
|
+
return;
|
|
1819
|
+
}
|
|
1820
|
+
this.footer.setActivity(undefined);
|
|
1715
1821
|
this.statusContainer.addChild(indicator);
|
|
1716
1822
|
}
|
|
1717
1823
|
clearStatusIndicator(kind) {
|
|
@@ -1719,13 +1825,23 @@ export class InteractiveMode {
|
|
|
1719
1825
|
return;
|
|
1720
1826
|
}
|
|
1721
1827
|
const hadActiveStatusIndicator = this.activeStatusIndicator !== undefined;
|
|
1828
|
+
const wasInTray = this.activeStatusIndicator !== undefined &&
|
|
1829
|
+
trayOwnsActivity(this.activeStatusIndicator.kind, this.customFooter !== undefined);
|
|
1722
1830
|
this.activeStatusIndicator?.dispose();
|
|
1723
1831
|
this.activeStatusIndicator = undefined;
|
|
1832
|
+
this.footer?.setActivity(undefined);
|
|
1724
1833
|
this.statusContainer.clear();
|
|
1834
|
+
// The tray never occupied those rows, so it must not leave the idle filler
|
|
1835
|
+
// behind to reserve them.
|
|
1836
|
+
if (wasInTray)
|
|
1837
|
+
return;
|
|
1725
1838
|
if (hadActiveStatusIndicator && this.options.tuiMode === "regular" && this.ui.getClearOnShrink()) {
|
|
1726
1839
|
this.statusContainer.addChild(this.idleStatus);
|
|
1727
1840
|
}
|
|
1728
1841
|
}
|
|
1842
|
+
showWorkingStatusIndicator() {
|
|
1843
|
+
this.showStatusIndicator(new WorkingStatusIndicator(this.ui, this.workingMessage ?? this.defaultWorkingMessage, this.workingIndicatorOptions));
|
|
1844
|
+
}
|
|
1729
1845
|
setWorkingVisible(visible) {
|
|
1730
1846
|
this.workingVisible = visible;
|
|
1731
1847
|
if (!visible) {
|
|
@@ -1734,7 +1850,7 @@ export class InteractiveMode {
|
|
|
1734
1850
|
return;
|
|
1735
1851
|
}
|
|
1736
1852
|
if (this.session.isStreaming && this.activeStatusIndicator?.kind !== "working") {
|
|
1737
|
-
this.
|
|
1853
|
+
this.showWorkingStatusIndicator();
|
|
1738
1854
|
}
|
|
1739
1855
|
this.ui.requestRender();
|
|
1740
1856
|
}
|
|
@@ -2040,6 +2156,7 @@ export class InteractiveMode {
|
|
|
2040
2156
|
timeout: opts?.timeout,
|
|
2041
2157
|
onToggleToolsExpanded: () => this.toggleToolOutputExpansion(),
|
|
2042
2158
|
enableSearch,
|
|
2159
|
+
preamble: opts?.preview ? renderPermissionPreview(opts.preview) : undefined,
|
|
2043
2160
|
});
|
|
2044
2161
|
this.disposeActiveSelector();
|
|
2045
2162
|
this.editorContainer.clear();
|
|
@@ -2089,10 +2206,24 @@ export class InteractiveMode {
|
|
|
2089
2206
|
this.showTrustSelector();
|
|
2090
2207
|
break;
|
|
2091
2208
|
case "Resources, extensions, and MCP adapters":
|
|
2092
|
-
this.showStatus(
|
|
2209
|
+
this.showStatus(this.describeMcpServers());
|
|
2093
2210
|
break;
|
|
2094
2211
|
}
|
|
2095
2212
|
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Report configured MCP servers and their live connection state. Replaces a string
|
|
2215
|
+
* that offered MCP management from `apex-code config`, which manages package
|
|
2216
|
+
* resources and has never been able to configure a server.
|
|
2217
|
+
*/
|
|
2218
|
+
describeMcpServers() {
|
|
2219
|
+
const runtime = this.session.mcpRuntime;
|
|
2220
|
+
const servers = runtime ? [...runtime.servers.keys()] : [];
|
|
2221
|
+
if (servers.length === 0) {
|
|
2222
|
+
return "Run apex-code config to manage resources and extensions. No MCP server is configured; add one to .mcp.json.";
|
|
2223
|
+
}
|
|
2224
|
+
const states = servers.map((name) => `${name} (${runtime?.manager.state(name).kind ?? "disconnected"})`);
|
|
2225
|
+
return `Run apex-code config to manage resources and extensions. MCP servers: ${states.join(", ")}.`;
|
|
2226
|
+
}
|
|
2096
2227
|
/**
|
|
2097
2228
|
* Show a confirmation dialog for extensions.
|
|
2098
2229
|
*/
|
|
@@ -2393,7 +2524,7 @@ export class InteractiveMode {
|
|
|
2393
2524
|
this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
|
|
2394
2525
|
this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
|
|
2395
2526
|
this.defaultEditor.onAction("app.editor.external", () => void this.handleOpenExternalEditor());
|
|
2396
|
-
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true }));
|
|
2527
|
+
this.defaultEditor.onAction("app.message.copy", () => void this.handleCopyCommand({ flashConfirmation: true, preferSelection: true }));
|
|
2397
2528
|
this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
|
|
2398
2529
|
this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
|
|
2399
2530
|
this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
|
|
@@ -2492,6 +2623,12 @@ export class InteractiveMode {
|
|
|
2492
2623
|
await this.handleModelCommand(searchTerm);
|
|
2493
2624
|
return;
|
|
2494
2625
|
}
|
|
2626
|
+
if (text === "/thinking" || text.startsWith("/thinking ")) {
|
|
2627
|
+
const searchTerm = text.startsWith("/thinking ") ? text.slice(10).trim() : undefined;
|
|
2628
|
+
this.editor.setText("");
|
|
2629
|
+
this.handleThinkingCommand(searchTerm);
|
|
2630
|
+
return;
|
|
2631
|
+
}
|
|
2495
2632
|
if (text === "/export" || text.startsWith("/export ")) {
|
|
2496
2633
|
await this.handleExportCommand(text);
|
|
2497
2634
|
this.editor.setText("");
|
|
@@ -2537,6 +2674,11 @@ export class InteractiveMode {
|
|
|
2537
2674
|
this.editor.setText("");
|
|
2538
2675
|
return;
|
|
2539
2676
|
}
|
|
2677
|
+
if (text === "/help") {
|
|
2678
|
+
this.handleHelpCommand();
|
|
2679
|
+
this.editor.setText("");
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2540
2682
|
if (text === "/fork") {
|
|
2541
2683
|
this.showUserMessageSelector();
|
|
2542
2684
|
this.editor.setText("");
|
|
@@ -2568,6 +2710,12 @@ export class InteractiveMode {
|
|
|
2568
2710
|
this.editor.setText("");
|
|
2569
2711
|
return;
|
|
2570
2712
|
}
|
|
2713
|
+
if (text === "/mcp" || text.startsWith("/mcp ")) {
|
|
2714
|
+
const mcpArgs = text.slice(4).trim().split(/\s+/).filter(Boolean);
|
|
2715
|
+
this.editor.setText("");
|
|
2716
|
+
await this.handleMcpAuthCommand(mcpArgs);
|
|
2717
|
+
return;
|
|
2718
|
+
}
|
|
2571
2719
|
if (text === "/new") {
|
|
2572
2720
|
this.editor.setText("");
|
|
2573
2721
|
await this.handleClearCommand();
|
|
@@ -2682,8 +2830,15 @@ export class InteractiveMode {
|
|
|
2682
2830
|
this.defaultEditor.onEscape = this.retryEscapeHandler;
|
|
2683
2831
|
this.retryEscapeHandler = undefined;
|
|
2684
2832
|
}
|
|
2833
|
+
break;
|
|
2834
|
+
case "turn_start":
|
|
2835
|
+
if (this.settingsManager.getShowTerminalProgress()) {
|
|
2836
|
+
this.ui.terminal.setProgress(true);
|
|
2837
|
+
}
|
|
2685
2838
|
if (this.workingVisible) {
|
|
2686
|
-
|
|
2839
|
+
if (this.activeStatusIndicator?.kind !== "working") {
|
|
2840
|
+
this.showWorkingStatusIndicator();
|
|
2841
|
+
}
|
|
2687
2842
|
}
|
|
2688
2843
|
else {
|
|
2689
2844
|
this.clearStatusIndicator();
|
|
@@ -2878,9 +3033,21 @@ export class InteractiveMode {
|
|
|
2878
3033
|
}
|
|
2879
3034
|
}
|
|
2880
3035
|
else if (event.result) {
|
|
3036
|
+
const entries = this.sessionManager.buildContextEntries();
|
|
3037
|
+
if (entries[0]?.type !== "compaction") {
|
|
3038
|
+
throw new Error("Completed compaction is missing from the session context");
|
|
3039
|
+
}
|
|
2881
3040
|
this.chatContainer.clear();
|
|
2882
|
-
|
|
3041
|
+
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
3042
|
+
this.renderSessionEntries(entries.slice(1));
|
|
2883
3043
|
this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
|
|
3044
|
+
if (event.result.usage) {
|
|
3045
|
+
this.addCompactionCostNotice({
|
|
3046
|
+
type: "compaction_cost",
|
|
3047
|
+
kind: "compaction",
|
|
3048
|
+
usage: event.result.usage,
|
|
3049
|
+
});
|
|
3050
|
+
}
|
|
2884
3051
|
this.footer.invalidate();
|
|
2885
3052
|
}
|
|
2886
3053
|
else if (event.errorMessage) {
|
|
@@ -3102,6 +3269,10 @@ export class InteractiveMode {
|
|
|
3102
3269
|
this.addCustomEntryToChat(item);
|
|
3103
3270
|
continue;
|
|
3104
3271
|
}
|
|
3272
|
+
if (isCompactionCostNotice(item)) {
|
|
3273
|
+
this.addCompactionCostNotice(item);
|
|
3274
|
+
continue;
|
|
3275
|
+
}
|
|
3105
3276
|
const message = item;
|
|
3106
3277
|
// Assistant messages need special handling for tool calls
|
|
3107
3278
|
if (message.role === "assistant") {
|
|
@@ -3169,10 +3340,28 @@ export class InteractiveMode {
|
|
|
3169
3340
|
if (entry.type === "custom") {
|
|
3170
3341
|
return [entry];
|
|
3171
3342
|
}
|
|
3172
|
-
|
|
3343
|
+
const messages = sessionEntryToContextMessages(entry);
|
|
3344
|
+
if ((entry.type === "compaction" || entry.type === "branch_summary") && entry.usage && messages.length > 0) {
|
|
3345
|
+
return [...messages, { type: "compaction_cost", kind: entry.type, usage: entry.usage }];
|
|
3346
|
+
}
|
|
3347
|
+
return messages;
|
|
3173
3348
|
});
|
|
3174
3349
|
this.renderSessionItems(items, options);
|
|
3175
3350
|
}
|
|
3351
|
+
/**
|
|
3352
|
+
* Render billing usage for a compaction or branch summary. The notice is derived
|
|
3353
|
+
* from persisted summary usage and is not stored as a separate session entry.
|
|
3354
|
+
*/
|
|
3355
|
+
addCompactionCostNotice(notice) {
|
|
3356
|
+
if (!this.settingsManager.getShowCacheMissNotices())
|
|
3357
|
+
return;
|
|
3358
|
+
const { usage } = notice;
|
|
3359
|
+
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
3360
|
+
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
3361
|
+
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
3362
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
3363
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${formatTokens(tokens)} tokens billed${cost}`), 1, 0));
|
|
3364
|
+
}
|
|
3176
3365
|
/**
|
|
3177
3366
|
* Show a transcript notice when a completed assistant message paid for a
|
|
3178
3367
|
* significant cache miss. Only states observable facts: the miss itself,
|
|
@@ -3383,6 +3572,34 @@ export class InteractiveMode {
|
|
|
3383
3572
|
const uncaughtExceptionHandler = (error) => this.uncaughtCrash(error);
|
|
3384
3573
|
process.prependListener("uncaughtException", uncaughtExceptionHandler);
|
|
3385
3574
|
this.signalCleanupHandlers.push(() => process.off("uncaughtException", uncaughtExceptionHandler));
|
|
3575
|
+
// Lend the terminal back to the supervisor when it needs to draw a sandbox
|
|
3576
|
+
// escalation prompt. The supervisor owns that decision (ADR 0023) and this
|
|
3577
|
+
// process cannot read the answer anyway -- bwrap --new-session leaves it with no
|
|
3578
|
+
// controlling terminal. `ui.stop()` is the same restore Ctrl+Z already performs,
|
|
3579
|
+
// so the terminal is in cooked mode with a visible cursor while the human answers.
|
|
3580
|
+
const handoffDirectory = process.env[TERMINAL_HANDOFF_PATH_VARIABLE];
|
|
3581
|
+
if (handoffDirectory) {
|
|
3582
|
+
const observer = observeTerminalHandoff(handoffDirectory, {
|
|
3583
|
+
suspend: () => {
|
|
3584
|
+
try {
|
|
3585
|
+
this.ui.stop();
|
|
3586
|
+
}
|
|
3587
|
+
catch {
|
|
3588
|
+
// A terminal we cannot restore still leaves the prompt readable.
|
|
3589
|
+
}
|
|
3590
|
+
},
|
|
3591
|
+
resume: () => {
|
|
3592
|
+
try {
|
|
3593
|
+
this.ui.start();
|
|
3594
|
+
this.ui.requestRender(true);
|
|
3595
|
+
}
|
|
3596
|
+
catch {
|
|
3597
|
+
// Nothing further to try; the next render request recovers.
|
|
3598
|
+
}
|
|
3599
|
+
},
|
|
3600
|
+
}, { acknowledgementPath: process.env[TERMINAL_HANDOFF_ACK_PATH_VARIABLE] });
|
|
3601
|
+
this.signalCleanupHandlers.push(() => observer.stop());
|
|
3602
|
+
}
|
|
3386
3603
|
}
|
|
3387
3604
|
unregisterSignalHandlers() {
|
|
3388
3605
|
for (const cleanup of this.signalCleanupHandlers) {
|
|
@@ -3464,7 +3681,9 @@ export class InteractiveMode {
|
|
|
3464
3681
|
}
|
|
3465
3682
|
}
|
|
3466
3683
|
updateEditorBorderColor() {
|
|
3467
|
-
|
|
3684
|
+
// Streaming no longer touches the dock. WorkingStatusIndicator already owns
|
|
3685
|
+
// that signal, and a `[busy]` prefix moved the caret mid-turn.
|
|
3686
|
+
this.defaultEditor.setPromptMode(this.isBashMode ? "bash" : "agent");
|
|
3468
3687
|
if (this.isBashMode) {
|
|
3469
3688
|
this.editor.borderColor = theme.getBashModeBorderColor();
|
|
3470
3689
|
}
|
|
@@ -3524,19 +3743,20 @@ export class InteractiveMode {
|
|
|
3524
3743
|
}
|
|
3525
3744
|
this.showStatus(`Tool output: ${expanded ? "expanded" : "collapsed"}`);
|
|
3526
3745
|
}
|
|
3746
|
+
/** Update rendered assistant messages without rebuilding live tool components. */
|
|
3747
|
+
updateThinkingBlockVisibility() {
|
|
3748
|
+
for (const child of this.chatContainer.children) {
|
|
3749
|
+
if (child instanceof AssistantMessageComponent) {
|
|
3750
|
+
child.setHideThinkingBlock(this.hideThinkingBlock);
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
this.ui.requestRender();
|
|
3754
|
+
}
|
|
3527
3755
|
toggleThinkingBlockVisibility() {
|
|
3528
3756
|
this.offerFirstUseHint("thinking");
|
|
3529
3757
|
this.hideThinkingBlock = !this.hideThinkingBlock;
|
|
3530
3758
|
this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);
|
|
3531
|
-
|
|
3532
|
-
this.chatContainer.clear();
|
|
3533
|
-
this.rebuildChatFromMessages();
|
|
3534
|
-
// If streaming, re-add the streaming component with updated visibility and re-render
|
|
3535
|
-
if (this.streamingComponent && this.streamingMessage) {
|
|
3536
|
-
this.streamingComponent.setHideThinkingBlock(this.hideThinkingBlock);
|
|
3537
|
-
this.streamingComponent.updateContent(this.streamingMessage);
|
|
3538
|
-
this.chatContainer.addChild(this.streamingComponent);
|
|
3539
|
-
}
|
|
3759
|
+
this.updateThinkingBlockVisibility();
|
|
3540
3760
|
this.showStatus(`Thinking blocks: ${this.hideThinkingBlock ? "hidden" : "visible"}`);
|
|
3541
3761
|
}
|
|
3542
3762
|
async handleOpenExternalEditor() {
|
|
@@ -3858,8 +4078,14 @@ export class InteractiveMode {
|
|
|
3858
4078
|
const permissionMode = await this.session.getPermissionMode();
|
|
3859
4079
|
this.showSelector((done) => {
|
|
3860
4080
|
let selector;
|
|
4081
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4082
|
+
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
4083
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
3861
4084
|
selector = new SettingsSelectorComponent({
|
|
3862
4085
|
autoCompact: this.session.autoCompactionEnabled,
|
|
4086
|
+
defaultModel,
|
|
4087
|
+
currentModel: this.session.model,
|
|
4088
|
+
availableDefaultModels: this.session.modelRuntime.getAvailableSnapshot(),
|
|
3863
4089
|
showImages: this.settingsManager.getShowImages(),
|
|
3864
4090
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
3865
4091
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
@@ -3869,8 +4095,9 @@ export class InteractiveMode {
|
|
|
3869
4095
|
followUpMode: this.session.followUpMode,
|
|
3870
4096
|
transport: this.settingsManager.getTransport(),
|
|
3871
4097
|
httpIdleTimeoutMs: this.settingsManager.getHttpIdleTimeoutMs(),
|
|
3872
|
-
thinkingLevel: this.
|
|
3873
|
-
availableThinkingLevels:
|
|
4098
|
+
thinkingLevel: this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL,
|
|
4099
|
+
availableThinkingLevels: [...THINKING_LEVEL_OPTIONS],
|
|
4100
|
+
modelThinkingLevels: this.settingsManager.getAllModelThinkingLevels(),
|
|
3874
4101
|
currentTheme: this.themeController.getThemeSelection() || "dark",
|
|
3875
4102
|
terminalTheme: this.themeController.getTerminalTheme(),
|
|
3876
4103
|
availableThemes: getAvailableThemes(),
|
|
@@ -3893,6 +4120,7 @@ export class InteractiveMode {
|
|
|
3893
4120
|
tuiMode: this.ui.mode,
|
|
3894
4121
|
fullscreenExitOutput: this.settingsManager.getFullscreenExitOutput(),
|
|
3895
4122
|
fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
|
|
4123
|
+
fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
|
|
3896
4124
|
warnings: this.settingsManager.getWarnings(),
|
|
3897
4125
|
}, {
|
|
3898
4126
|
onAutoCompactChange: (enabled) => {
|
|
@@ -3940,10 +4168,26 @@ export class InteractiveMode {
|
|
|
3940
4168
|
configureHttpDispatcher(timeoutMs);
|
|
3941
4169
|
this.showStatus(`HTTP idle timeout: ${formatHttpIdleTimeoutMs(timeoutMs)}`);
|
|
3942
4170
|
},
|
|
3943
|
-
|
|
3944
|
-
this.
|
|
3945
|
-
|
|
3946
|
-
this.
|
|
4171
|
+
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
4172
|
+
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
4173
|
+
// If the override is for the current model, apply it to the session too
|
|
4174
|
+
const current = this.session.model;
|
|
4175
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4176
|
+
this.session.setThinkingLevel(level);
|
|
4177
|
+
this.footer.invalidate();
|
|
4178
|
+
this.updateEditorBorderColor();
|
|
4179
|
+
}
|
|
4180
|
+
},
|
|
4181
|
+
onModelThinkingLevelRemove: (provider, modelId) => {
|
|
4182
|
+
this.settingsManager.removeModelThinkingLevel(provider, modelId);
|
|
4183
|
+
// If the override was for the current model, revert to global default
|
|
4184
|
+
const current = this.session.model;
|
|
4185
|
+
if (current && current.provider === provider && current.id === modelId) {
|
|
4186
|
+
const globalDefault = this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
4187
|
+
this.session.setThinkingLevel(globalDefault);
|
|
4188
|
+
this.footer.invalidate();
|
|
4189
|
+
this.updateEditorBorderColor();
|
|
4190
|
+
}
|
|
3947
4191
|
},
|
|
3948
4192
|
onThemeChange: (themeSetting) => {
|
|
3949
4193
|
this.settingsManager.setTheme(themeSetting);
|
|
@@ -3953,13 +4197,7 @@ export class InteractiveMode {
|
|
|
3953
4197
|
onHideThinkingBlockChange: (hidden) => {
|
|
3954
4198
|
this.hideThinkingBlock = hidden;
|
|
3955
4199
|
this.settingsManager.setHideThinkingBlock(hidden);
|
|
3956
|
-
|
|
3957
|
-
if (child instanceof AssistantMessageComponent) {
|
|
3958
|
-
child.setHideThinkingBlock(hidden);
|
|
3959
|
-
}
|
|
3960
|
-
}
|
|
3961
|
-
this.chatContainer.clear();
|
|
3962
|
-
this.rebuildChatFromMessages();
|
|
4200
|
+
this.updateThinkingBlockVisibility();
|
|
3963
4201
|
},
|
|
3964
4202
|
onMermaidRenderingModeChange: (mode) => {
|
|
3965
4203
|
this.settingsManager.setMermaidRenderingMode(mode);
|
|
@@ -4056,6 +4294,11 @@ export class InteractiveMode {
|
|
|
4056
4294
|
this.settingsManager.setFullscreenScrollbar(mode);
|
|
4057
4295
|
this.applyFullscreenScrollbarSetting();
|
|
4058
4296
|
},
|
|
4297
|
+
onFullscreenCopyOnSelectChange: (enabled) => {
|
|
4298
|
+
this.settingsManager.setFullscreenCopyOnSelect(enabled);
|
|
4299
|
+
if (this.renderer instanceof TuiAltScreen)
|
|
4300
|
+
this.renderer.setCopyOnSelect(enabled);
|
|
4301
|
+
},
|
|
4059
4302
|
onWarningsChange: (warnings) => {
|
|
4060
4303
|
this.settingsManager.setWarnings(warnings);
|
|
4061
4304
|
},
|
|
@@ -4067,6 +4310,44 @@ export class InteractiveMode {
|
|
|
4067
4310
|
return { component: selector, focus: selector.getSettingsList() };
|
|
4068
4311
|
});
|
|
4069
4312
|
}
|
|
4313
|
+
handleThinkingCommand(searchTerm) {
|
|
4314
|
+
const availableLevels = this.session.getAvailableThinkingLevels();
|
|
4315
|
+
if (!searchTerm) {
|
|
4316
|
+
this.showThinkingSelector();
|
|
4317
|
+
return;
|
|
4318
|
+
}
|
|
4319
|
+
const normalized = searchTerm.trim().toLowerCase();
|
|
4320
|
+
const level = availableLevels.find((candidate) => candidate.toLowerCase() === normalized);
|
|
4321
|
+
if (!level) {
|
|
4322
|
+
this.showError(`Unknown thinking level "${searchTerm}". Available levels: ${availableLevels.join(", ")}.`);
|
|
4323
|
+
return;
|
|
4324
|
+
}
|
|
4325
|
+
this.selectThinkingLevel(level, false);
|
|
4326
|
+
}
|
|
4327
|
+
selectThinkingLevel(level, persist) {
|
|
4328
|
+
try {
|
|
4329
|
+
this.session.setThinkingLevel(level, { persist });
|
|
4330
|
+
this.footer.invalidate();
|
|
4331
|
+
this.updateEditorBorderColor();
|
|
4332
|
+
this.showStatus(persist ? `Default thinking level: ${level}` : `Thinking level: ${level}`);
|
|
4333
|
+
}
|
|
4334
|
+
catch (error) {
|
|
4335
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
showThinkingSelector() {
|
|
4339
|
+
this.showSelector((done) => {
|
|
4340
|
+
const selectLevel = (level, persist) => {
|
|
4341
|
+
this.selectThinkingLevel(level, persist);
|
|
4342
|
+
done();
|
|
4343
|
+
};
|
|
4344
|
+
const selector = new ThinkingSelectorComponent(this.session.thinkingLevel ?? DEFAULT_THINKING_LEVEL, this.session.getAvailableThinkingLevels(), (level) => selectLevel(level, false), () => {
|
|
4345
|
+
done();
|
|
4346
|
+
this.ui.requestRender();
|
|
4347
|
+
}, (level) => selectLevel(level, true), this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);
|
|
4348
|
+
return { component: selector, focus: selector };
|
|
4349
|
+
});
|
|
4350
|
+
}
|
|
4070
4351
|
async handleModelCommand(searchTerm) {
|
|
4071
4352
|
if (!searchTerm) {
|
|
4072
4353
|
this.showModelSelector();
|
|
@@ -4075,7 +4356,7 @@ export class InteractiveMode {
|
|
|
4075
4356
|
const model = await this.findExactModelMatch(searchTerm);
|
|
4076
4357
|
if (model) {
|
|
4077
4358
|
try {
|
|
4078
|
-
await this.session.setModel(model);
|
|
4359
|
+
await this.session.setModel(model, { persist: false });
|
|
4079
4360
|
this.footer.invalidate();
|
|
4080
4361
|
this.updateEditorBorderColor();
|
|
4081
4362
|
this.showStatus(`Model: ${model.id}`);
|
|
@@ -4204,13 +4485,14 @@ export class InteractiveMode {
|
|
|
4204
4485
|
}
|
|
4205
4486
|
showModelSelector(initialSearchInput) {
|
|
4206
4487
|
this.showSelector((done) => {
|
|
4207
|
-
const
|
|
4488
|
+
const selectModel = async (model, persist) => {
|
|
4208
4489
|
try {
|
|
4209
|
-
await this.session.setModel(model);
|
|
4490
|
+
await this.session.setModel(model, { persist });
|
|
4491
|
+
this.updateAvailableProviderCount();
|
|
4210
4492
|
this.footer.invalidate();
|
|
4211
4493
|
this.updateEditorBorderColor();
|
|
4212
4494
|
done();
|
|
4213
|
-
this.showStatus(`Model: ${model.id}`);
|
|
4495
|
+
this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
|
|
4214
4496
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(model);
|
|
4215
4497
|
this.checkDaxnutsEasterEgg(model);
|
|
4216
4498
|
}
|
|
@@ -4218,10 +4500,13 @@ export class InteractiveMode {
|
|
|
4218
4500
|
done();
|
|
4219
4501
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
4220
4502
|
}
|
|
4221
|
-
}
|
|
4503
|
+
};
|
|
4504
|
+
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
4505
|
+
const defaultModel = this.settingsManager.getDefaultModel();
|
|
4506
|
+
const selector = new ModelSelectorComponent(this.ui, this.session.model, this.session.modelRuntime, this.session.scopedModels, (model) => selectModel(model, false), () => {
|
|
4222
4507
|
done();
|
|
4223
4508
|
this.ui.requestRender();
|
|
4224
|
-
}, initialSearchInput);
|
|
4509
|
+
}, initialSearchInput, (model) => selectModel(model, true), defaultProvider && defaultModel ? { provider: defaultProvider, id: defaultModel } : undefined);
|
|
4225
4510
|
return { component: selector, focus: selector, dispose: () => selector.dispose() };
|
|
4226
4511
|
});
|
|
4227
4512
|
}
|
|
@@ -4614,6 +4899,27 @@ export class InteractiveMode {
|
|
|
4614
4899
|
return this.getLoginProviderOptions().filter((provider) => provider.id.toLowerCase() === normalizedProviderRef ||
|
|
4615
4900
|
provider.name.toLowerCase() === normalizedProviderRef);
|
|
4616
4901
|
}
|
|
4902
|
+
/** `/mcp auth <server>`: runs the same OAuth flow as the CLI, printing into the chat. */
|
|
4903
|
+
async handleMcpAuthCommand(mcpArgs) {
|
|
4904
|
+
const show = (line, kind = "dim") => {
|
|
4905
|
+
this.chatContainer.addChild(new Text(theme.fg(kind, line), 1, 0));
|
|
4906
|
+
this.ui.requestRender();
|
|
4907
|
+
};
|
|
4908
|
+
if (mcpArgs[0] !== "auth" || !mcpArgs[1] || mcpArgs.length > 2) {
|
|
4909
|
+
show("Usage: /mcp auth <server>", "error");
|
|
4910
|
+
return;
|
|
4911
|
+
}
|
|
4912
|
+
try {
|
|
4913
|
+
await authorizeConfiguredServer({
|
|
4914
|
+
serverName: mcpArgs[1],
|
|
4915
|
+
openBrowser: (url) => openBrowser(url),
|
|
4916
|
+
log: (line) => show(line),
|
|
4917
|
+
});
|
|
4918
|
+
}
|
|
4919
|
+
catch (error) {
|
|
4920
|
+
show(`Error: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
4921
|
+
}
|
|
4922
|
+
}
|
|
4617
4923
|
async handleLoginCommand(providerRef) {
|
|
4618
4924
|
if (!providerRef) {
|
|
4619
4925
|
this.showLoginAuthTypeSelector();
|
|
@@ -4777,7 +5083,11 @@ export class InteractiveMode {
|
|
|
4777
5083
|
if (isUnknownModel(previousModel)) {
|
|
4778
5084
|
const availableModels = this.session.modelRuntime.getAvailableSnapshot();
|
|
4779
5085
|
const providerModels = availableModels.filter((model) => model.provider === providerId);
|
|
4780
|
-
|
|
5086
|
+
// Matches LLAMA_PROVIDER_ID from extensions/llama/provider.ts; kept inline to avoid coupling interactive mode to the built-in extension.
|
|
5087
|
+
if (providerId === "llama.cpp") {
|
|
5088
|
+
selectionError = llamaCppPostLoginGuidance(actionLabel, providerModels.length);
|
|
5089
|
+
}
|
|
5090
|
+
else if (!hasDefaultModelProvider(providerId)) {
|
|
4781
5091
|
selectionError = `${actionLabel}, but no default model is configured for provider "${providerId}". Use /model to select a model.`;
|
|
4782
5092
|
}
|
|
4783
5093
|
else if (providerModels.length === 0) {
|
|
@@ -4791,7 +5101,7 @@ export class InteractiveMode {
|
|
|
4791
5101
|
}
|
|
4792
5102
|
else {
|
|
4793
5103
|
try {
|
|
4794
|
-
await this.session.setModel(selectedModel);
|
|
5104
|
+
await this.session.setModel(selectedModel, { persist: true });
|
|
4795
5105
|
}
|
|
4796
5106
|
catch (error) {
|
|
4797
5107
|
selectedModel = undefined;
|
|
@@ -5048,8 +5358,8 @@ export class InteractiveMode {
|
|
|
5048
5358
|
activeHeader.setExpanded(this.toolOutputExpanded);
|
|
5049
5359
|
}
|
|
5050
5360
|
setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
|
|
5051
|
-
await this.themeController.applyFromSettings();
|
|
5052
5361
|
this.applyRuntimeSettings();
|
|
5362
|
+
await this.themeController.applyFromSettings();
|
|
5053
5363
|
this.setupAutocompleteProvider();
|
|
5054
5364
|
const runner = this.session.extensionRunner;
|
|
5055
5365
|
this.setupExtensionShortcuts(runner);
|
|
@@ -5233,6 +5543,13 @@ export class InteractiveMode {
|
|
|
5233
5543
|
}
|
|
5234
5544
|
}
|
|
5235
5545
|
async handleCopyCommand(options = {}) {
|
|
5546
|
+
if (options.preferSelection &&
|
|
5547
|
+
this.ui instanceof TuiAltScreen &&
|
|
5548
|
+
!this.ui.getCopyOnSelect() &&
|
|
5549
|
+
this.ui.hasActiveSelection()) {
|
|
5550
|
+
await this.ui.copyActiveSelectionToClipboard();
|
|
5551
|
+
return;
|
|
5552
|
+
}
|
|
5236
5553
|
const text = this.session.getLastAssistantText();
|
|
5237
5554
|
if (!text) {
|
|
5238
5555
|
this.showError("No agent messages to copy yet.");
|
|
@@ -5491,6 +5808,28 @@ export class InteractiveMode {
|
|
|
5491
5808
|
this.chatContainer.addChild(new DynamicBorder());
|
|
5492
5809
|
this.ui.requestRender();
|
|
5493
5810
|
}
|
|
5811
|
+
/**
|
|
5812
|
+
* Renders what `collectSessionCommands` returns, so the list a user reads and the list
|
|
5813
|
+
* autocomplete offers are the same list rather than two that agree today. Unregistered
|
|
5814
|
+
* dispatch-only commands are outside that boundary; see the note there.
|
|
5815
|
+
*/
|
|
5816
|
+
handleHelpCommand() {
|
|
5817
|
+
const commands = this.collectSessionCommands();
|
|
5818
|
+
const rows = commands
|
|
5819
|
+
.map((command) => {
|
|
5820
|
+
const invocation = command.argumentHint ? `/${command.name} ${command.argumentHint}` : `/${command.name}`;
|
|
5821
|
+
return `| \`${invocation}\` | ${command.description ?? ""} |`;
|
|
5822
|
+
})
|
|
5823
|
+
.join("\n");
|
|
5824
|
+
const help = `| Command | Description |\n|---------|-------------|\n${rows}\n\nType \`/\` to filter these, or \`/hotkeys\` for keyboard shortcuts.`;
|
|
5825
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5826
|
+
this.chatContainer.addChild(new DynamicBorder());
|
|
5827
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Commands")), 1, 0));
|
|
5828
|
+
this.chatContainer.addChild(new Spacer(1));
|
|
5829
|
+
this.chatContainer.addChild(new Markdown(help, 1, 1, this.getMarkdownThemeWithSettings()));
|
|
5830
|
+
this.chatContainer.addChild(new DynamicBorder());
|
|
5831
|
+
this.ui.requestRender();
|
|
5832
|
+
}
|
|
5494
5833
|
async handleClearCommand() {
|
|
5495
5834
|
this.clearStatusIndicator();
|
|
5496
5835
|
try {
|
|
@@ -5554,6 +5893,19 @@ export class InteractiveMode {
|
|
|
5554
5893
|
}
|
|
5555
5894
|
}
|
|
5556
5895
|
async handleBashCommand(command, excludeFromContext = false) {
|
|
5896
|
+
if (this.isHandlingBashCommand) {
|
|
5897
|
+
this.showWarning("A bash command is already running; wait for it to finish");
|
|
5898
|
+
return;
|
|
5899
|
+
}
|
|
5900
|
+
this.isHandlingBashCommand = true;
|
|
5901
|
+
try {
|
|
5902
|
+
await this.runBashCommand(command, excludeFromContext);
|
|
5903
|
+
}
|
|
5904
|
+
finally {
|
|
5905
|
+
this.isHandlingBashCommand = false;
|
|
5906
|
+
}
|
|
5907
|
+
}
|
|
5908
|
+
async runBashCommand(command, excludeFromContext = false) {
|
|
5557
5909
|
const extensionRunner = this.session.extensionRunner;
|
|
5558
5910
|
// Emit user_bash event to let extensions intercept
|
|
5559
5911
|
const eventResult = await extensionRunner.emitUserBash({
|