@ai-agent-forge/agent-forge 0.86.6 → 0.87.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 +19 -1
- package/README.md +8 -9
- package/dist/artifacts/artifact-store.d.ts.map +1 -1
- package/dist/artifacts/artifact-store.js +9 -5
- package/dist/artifacts/artifact-store.js.map +1 -1
- package/dist/bundle/.build-manifest.json +410 -371
- package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
- package/dist/bundle/chunks/chunk-BFC2BDVJ.js +13 -0
- package/dist/bundle/chunks/chunk-MOHOLL3F.js +1456 -0
- package/dist/bundle/chunks/image-resize-worker.js +12 -1
- package/dist/bundle/chunks/{virtual-modules-3IZ4MYSQ.js → virtual-modules-KZ5DRH7Q.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +2 -2
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +231 -185
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-check.d.ts.map +1 -1
- package/dist/cli/auth-check.js +3 -2
- package/dist/cli/auth-check.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +15 -9
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/credential-print.d.ts.map +1 -1
- package/dist/cli/credential-print.js +14 -7
- package/dist/cli/credential-print.js.map +1 -1
- package/dist/cli/experimental/command.d.ts.map +1 -1
- package/dist/cli/experimental/command.js +6 -5
- package/dist/cli/experimental/command.js.map +1 -1
- package/dist/cli/list-models.d.ts.map +1 -1
- package/dist/cli/list-models.js +9 -8
- package/dist/cli/list-models.js.map +1 -1
- package/dist/cli/plugin-manager-controller.d.ts.map +1 -1
- package/dist/cli/plugin-manager-controller.js +2 -1
- package/dist/cli/plugin-manager-controller.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +8 -5
- package/dist/cli/serve.js.map +1 -1
- package/dist/client/remote-session.d.ts.map +1 -1
- package/dist/client/remote-session.js +16 -9
- package/dist/client/remote-session.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-capability-contract.d.ts +0 -7
- package/dist/core/agent-capability-contract.d.ts.map +1 -1
- package/dist/core/agent-capability-contract.js +72 -68
- package/dist/core/agent-capability-contract.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +5 -4
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +28 -22
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-context.d.ts.map +1 -1
- package/dist/core/agent-session-context.js +18 -13
- package/dist/core/agent-session-context.js.map +1 -1
- package/dist/core/agent-session-model.d.ts.map +1 -1
- package/dist/core/agent-session-model.js +2 -1
- package/dist/core/agent-session-model.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +3 -2
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +7 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tools.d.ts.map +1 -1
- package/dist/core/agent-session-tools.js +3 -2
- package/dist/core/agent-session-tools.js.map +1 -1
- package/dist/core/agent-session.d.ts +40 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +142 -34
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js +11 -5
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +9 -6
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +2 -1
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/embedded-sdk.d.ts.map +1 -1
- package/dist/core/embedded-sdk.js +10 -6
- package/dist/core/embedded-sdk.js.map +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +9 -4
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/agent-composition.d.ts.map +1 -1
- package/dist/core/extensions/agent-composition.js +26 -19
- package/dist/core/extensions/agent-composition.js.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-agent-loop.js +3 -2
- package/dist/core/extensions/bootstrap-agent-loop.js.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-lifecycle.js +20 -17
- package/dist/core/extensions/bootstrap-lifecycle.js.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js +2 -1
- package/dist/core/extensions/bootstrap-overflow-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-retry-policy.js +2 -1
- package/dist/core/extensions/bootstrap-retry-policy.js.map +1 -1
- package/dist/core/extensions/bootstrap-skills.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-skills.js +7 -6
- package/dist/core/extensions/bootstrap-skills.js.map +1 -1
- package/dist/core/extensions/bootstrap-tools.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-tools.js +2 -1
- package/dist/core/extensions/bootstrap-tools.js.map +1 -1
- package/dist/core/extensions/capability-plugin.d.ts.map +1 -1
- package/dist/core/extensions/capability-plugin.js +37 -13
- package/dist/core/extensions/capability-plugin.js.map +1 -1
- package/dist/core/extensions/capability-runtime-events.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-events.js +17 -13
- package/dist/core/extensions/capability-runtime-events.js.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-guards.js +16 -15
- package/dist/core/extensions/capability-runtime-guards.js.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-manifest.js +52 -30
- package/dist/core/extensions/capability-runtime-manifest.js.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-validation.js +66 -65
- package/dist/core/extensions/capability-runtime-validation.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +147 -127
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.d.ts.map +1 -1
- package/dist/core/extensions/compaction-memory-failure-mode.js +3 -2
- package/dist/core/extensions/compaction-memory-failure-mode.js.map +1 -1
- package/dist/core/extensions/context-strategy-binding.d.ts.map +1 -1
- package/dist/core/extensions/context-strategy-binding.js +7 -4
- package/dist/core/extensions/context-strategy-binding.js.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-catalog.js +290 -279
- package/dist/core/extensions/lifecycle-catalog.js.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.d.ts.map +1 -1
- package/dist/core/extensions/lifecycle-delivery-queue.js +3 -2
- package/dist/core/extensions/lifecycle-delivery-queue.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +6 -0
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +2 -0
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -1
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/i18n/index.d.ts +14 -0
- package/dist/core/i18n/index.d.ts.map +1 -0
- package/dist/core/i18n/index.js +67 -0
- package/dist/core/i18n/index.js.map +1 -0
- package/dist/core/i18n/locales/en/example.d.ts +7 -0
- package/dist/core/i18n/locales/en/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/en/example.js +7 -0
- package/dist/core/i18n/locales/en/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/cli.js +227 -0
- package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts +6 -0
- package/dist/core/i18n/locales/zh-cn/common.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/common.js +6 -0
- package/dist/core/i18n/locales/zh-cn/common.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js +173 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-core.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js +582 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-extensions.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js +55 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +455 -0
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js +191 -0
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/example.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/example.js +10 -0
- package/dist/core/i18n/locales/zh-cn/example.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts +2 -0
- package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/index.js +41 -0
- package/dist/core/i18n/locales/zh-cn/index.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +265 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts +11 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js +67 -0
- package/dist/core/i18n/locales/zh-cn/keybindings.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js +39 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts +10 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js +15 -0
- package/dist/core/i18n/locales/zh-cn/tui-builtin.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts +13 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +102 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts +12 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js +288 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-selectors.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts +9 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js +79 -0
- package/dist/core/i18n/locales/zh-cn/tui-interactive-misc.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts +8 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js +72 -0
- package/dist/core/i18n/locales/zh-cn/tui-self-owned.js.map +1 -0
- package/dist/core/keybindings.d.ts +15 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +18 -0
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +5 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +8 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-install-host.d.ts.map +1 -1
- package/dist/core/package-install-host.js +4 -3
- package/dist/core/package-install-host.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +15 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/package-resource-collection.d.ts.map +1 -1
- package/dist/core/package-resource-collection.js +2 -1
- package/dist/core/package-resource-collection.js.map +1 -1
- package/dist/core/package-source.d.ts.map +1 -1
- package/dist/core/package-source.js +3 -2
- package/dist/core/package-source.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +22 -13
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +6 -2
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +15 -5
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/sdk.d.ts +19 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +74 -54
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +5 -2
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/session-export.d.ts.map +1 -1
- package/dist/core/session-export.js +2 -1
- package/dist/core/session-export.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +39 -29
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-storage.d.ts.map +1 -1
- package/dist/core/session-storage.js +3 -3
- package/dist/core/session-storage.js.map +1 -1
- package/dist/core/settings-manager.d.ts +11 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +27 -5
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +53 -32
- 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 +25 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +11 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +9 -4
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +4 -3
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +3 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +2 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +6 -2
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +2 -1
- package/dist/core/tools/write.js.map +1 -1
- package/dist/durable/durable-service.d.ts.map +1 -1
- package/dist/durable/durable-service.js +25 -18
- package/dist/durable/durable-service.js.map +1 -1
- package/dist/host/checkpoint-commit.d.ts.map +1 -1
- package/dist/host/checkpoint-commit.js +2 -1
- package/dist/host/checkpoint-commit.js.map +1 -1
- package/dist/host/manual-compaction.d.ts.map +1 -1
- package/dist/host/manual-compaction.js +2 -1
- package/dist/host/manual-compaction.js.map +1 -1
- package/dist/host/output-projection.d.ts +0 -13
- package/dist/host/output-projection.d.ts.map +1 -1
- package/dist/host/output-projection.js +16 -2
- package/dist/host/output-projection.js.map +1 -1
- package/dist/host/summary-retry.d.ts.map +1 -1
- package/dist/host/summary-retry.js +3 -2
- package/dist/host/summary-retry.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +94 -58
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/agents-view.js +18 -15
- package/dist/modes/interactive/components/agents-view.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +6 -5
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +12 -7
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.js +2 -1
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +6 -5
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +9 -5
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +18 -15
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +2 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.js +5 -4
- package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
- package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-input.js +2 -1
- package/dist/modes/interactive/components/dialog-input.js.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-selector.js +4 -3
- package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +11 -10
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +7 -4
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +3 -2
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +12 -11
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- package/dist/modes/interactive/components/mermaid.js +6 -2
- package/dist/modes/interactive/components/mermaid.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +28 -16
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +10 -9
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-manager-entry.js +22 -13
- package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js +27 -12
- package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.d.ts +60 -0
- package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/queue-manager-selector.js +166 -0
- package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +16 -14
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +43 -31
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +113 -96
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.js +5 -4
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/show-images-selector.js +3 -2
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +4 -3
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +14 -5
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/theme-selector.js +2 -1
- package/dist/modes/interactive/components/theme-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +11 -4
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +8 -3
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-list.js +7 -6
- package/dist/modes/interactive/components/tree-list.js.map +1 -1
- package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-render.js +28 -23
- package/dist/modes/interactive/components/tree-render.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js +9 -7
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message-selector.js +5 -4
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/workflow-view.js +36 -21
- package/dist/modes/interactive/components/workflow-view.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-auth.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth.js +71 -40
- package/dist/modes/interactive/interactive-auth.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts +1 -0
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +3 -0
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-dialog-ui.js +5 -5
- package/dist/modes/interactive/interactive-dialog-ui.js.map +1 -1
- package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-format.js +34 -18
- package/dist/modes/interactive/interactive-format.js.map +1 -1
- package/dist/modes/interactive/interactive-helpers.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-helpers.js +7 -2
- package/dist/modes/interactive/interactive-helpers.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +327 -243
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.d.ts +9 -0
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +79 -25
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +5 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +26 -23
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +3 -2
- 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 +3 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -2
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +28 -13
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/plugins/ecosystem/catalog.d.ts.map +1 -1
- package/dist/plugins/ecosystem/catalog.js +3 -2
- package/dist/plugins/ecosystem/catalog.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +2 -1
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.d.ts.map +1 -1
- package/dist/plugins/ecosystem/default-plugin-market.js +3 -2
- package/dist/plugins/ecosystem/default-plugin-market.js.map +1 -1
- package/dist/plugins/ecosystem/distribution.d.ts.map +1 -1
- package/dist/plugins/ecosystem/distribution.js +2 -1
- package/dist/plugins/ecosystem/distribution.js.map +1 -1
- package/dist/plugins/ecosystem/installer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/installer.js +3 -2
- package/dist/plugins/ecosystem/installer.js.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-disk-registry-source.js +20 -17
- package/dist/plugins/ecosystem/node-disk-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-distribution-host.js +35 -34
- package/dist/plugins/ecosystem/node-distribution-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-npm-registry-source.js +35 -34
- package/dist/plugins/ecosystem/node-npm-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +9 -8
- package/dist/plugins/ecosystem/node-package-install-host.js.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-persistence.js +4 -3
- package/dist/plugins/ecosystem/node-package-install-persistence.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +21 -5
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-trust-root.js +10 -9
- package/dist/plugins/ecosystem/node-plugin-trust-root.js.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-registry-source.js +31 -30
- package/dist/plugins/ecosystem/node-registry-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-release-package-source.js +30 -29
- package/dist/plugins/ecosystem/node-release-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-tar-writer.js +11 -10
- package/dist/plugins/ecosystem/node-tar-writer.js.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-url-package-source.js +21 -20
- package/dist/plugins/ecosystem/node-url-package-source.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-acquisition.js +3 -2
- package/dist/plugins/ecosystem/plugin-acquisition.js.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js +2 -1
- package/dist/plugins/ecosystem/registry-cli-adapter.js.map +1 -1
- package/dist/plugins/ecosystem/registry.d.ts.map +1 -1
- package/dist/plugins/ecosystem/registry.js +35 -32
- package/dist/plugins/ecosystem/registry.js.map +1 -1
- package/dist/plugins/ecosystem/resolver.d.ts.map +1 -1
- package/dist/plugins/ecosystem/resolver.js +3 -2
- package/dist/plugins/ecosystem/resolver.js.map +1 -1
- package/dist/plugins/ecosystem/selection-store.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection-store.js +11 -10
- package/dist/plugins/ecosystem/selection-store.js.map +1 -1
- package/dist/plugins/ecosystem/selection.d.ts.map +1 -1
- package/dist/plugins/ecosystem/selection.js +8 -7
- package/dist/plugins/ecosystem/selection.js.map +1 -1
- package/dist/plugins/ecosystem/state.d.ts.map +1 -1
- package/dist/plugins/ecosystem/state.js +24 -23
- package/dist/plugins/ecosystem/state.js.map +1 -1
- package/dist/plugins/ecosystem/updates.d.ts.map +1 -1
- package/dist/plugins/ecosystem/updates.js +5 -4
- package/dist/plugins/ecosystem/updates.js.map +1 -1
- package/dist/plugins/mcp-http.d.ts +0 -17
- package/dist/plugins/mcp-http.d.ts.map +1 -1
- package/dist/plugins/mcp-http.js +30 -7
- package/dist/plugins/mcp-http.js.map +1 -1
- package/dist/plugins/plugin-supervisor.d.ts.map +1 -1
- package/dist/plugins/plugin-supervisor.js +19 -1
- package/dist/plugins/plugin-supervisor.js.map +1 -1
- package/dist/profile/first-roles.d.ts.map +1 -1
- package/dist/profile/first-roles.js +10 -1
- package/dist/profile/first-roles.js.map +1 -1
- package/dist/profile/goal-plugin.d.ts.map +1 -1
- package/dist/profile/goal-plugin.js +24 -5
- package/dist/profile/goal-plugin.js.map +1 -1
- package/dist/profile/identity.d.ts.map +1 -1
- package/dist/profile/identity.js +7 -6
- package/dist/profile/identity.js.map +1 -1
- package/dist/profile/lock.d.ts.map +1 -1
- package/dist/profile/lock.js +15 -1
- package/dist/profile/lock.js.map +1 -1
- package/dist/profile/plan-plugin.d.ts.map +1 -1
- package/dist/profile/plan-plugin.js +26 -13
- package/dist/profile/plan-plugin.js.map +1 -1
- package/dist/profile/plugin-profiles.d.ts.map +1 -1
- package/dist/profile/plugin-profiles.js +2 -1
- package/dist/profile/plugin-profiles.js.map +1 -1
- package/dist/profile/policy-manifest.d.ts.map +1 -1
- package/dist/profile/policy-manifest.js +5 -4
- package/dist/profile/policy-manifest.js.map +1 -1
- package/dist/profile/profile-registry.d.ts +0 -12
- package/dist/profile/profile-registry.d.ts.map +1 -1
- package/dist/profile/profile-registry.js +14 -1
- package/dist/profile/profile-registry.js.map +1 -1
- package/dist/profile/role-catalog.d.ts +0 -1
- package/dist/profile/role-catalog.d.ts.map +1 -1
- package/dist/profile/role-catalog.js +17 -15
- package/dist/profile/role-catalog.js.map +1 -1
- package/dist/profile/role-orchestrator.d.ts.map +1 -1
- package/dist/profile/role-orchestrator.js +8 -7
- package/dist/profile/role-orchestrator.js.map +1 -1
- package/dist/profile/role-runner.d.ts.map +1 -1
- package/dist/profile/role-runner.js +3 -2
- package/dist/profile/role-runner.js.map +1 -1
- package/dist/profile/root-facade.d.ts.map +1 -1
- package/dist/profile/root-facade.js +2 -1
- package/dist/profile/root-facade.js.map +1 -1
- package/dist/profile/skill-discovery-wiring.d.ts.map +1 -1
- package/dist/profile/skill-discovery-wiring.js +7 -2
- package/dist/profile/skill-discovery-wiring.js.map +1 -1
- package/dist/profile/state-store.d.ts.map +1 -1
- package/dist/profile/state-store.js +13 -9
- package/dist/profile/state-store.js.map +1 -1
- package/dist/profile/todo-plugin.d.ts.map +1 -1
- package/dist/profile/todo-plugin.js +9 -4
- package/dist/profile/todo-plugin.js.map +1 -1
- package/dist/profiles/builtin-suites.d.ts +13 -6
- package/dist/profiles/builtin-suites.d.ts.map +1 -1
- package/dist/profiles/builtin-suites.js +15 -6
- package/dist/profiles/builtin-suites.js.map +1 -1
- package/dist/profiles/suite-loader.d.ts +25 -1
- package/dist/profiles/suite-loader.d.ts.map +1 -1
- package/dist/profiles/suite-loader.js +34 -9
- package/dist/profiles/suite-loader.js.map +1 -1
- package/dist/remote/server-entry.d.ts.map +1 -1
- package/dist/remote/server-entry.js +3 -2
- package/dist/remote/server-entry.js.map +1 -1
- package/dist/remote/session-source.d.ts.map +1 -1
- package/dist/remote/session-source.js +8 -4
- package/dist/remote/session-source.js.map +1 -1
- package/dist/share/session-share.d.ts.map +1 -1
- package/dist/share/session-share.js +14 -2
- package/dist/share/session-share.js.map +1 -1
- package/dist/testing/plugin-testkit.d.ts.map +1 -1
- package/dist/testing/plugin-testkit.js +4 -3
- package/dist/testing/plugin-testkit.js.map +1 -1
- package/dist/testing/runtime-delivery-queue.d.ts.map +1 -1
- package/dist/testing/runtime-delivery-queue.js +2 -1
- package/dist/testing/runtime-delivery-queue.js.map +1 -1
- package/dist/testing/session-plugin-testkit.d.ts.map +1 -1
- package/dist/testing/session-plugin-testkit.js +10 -7
- package/dist/testing/session-plugin-testkit.js.map +1 -1
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +2 -1
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +7 -6
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-resize-worker.d.ts.map +1 -1
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +9 -8
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +23 -13
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +5 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/keybindings.md +3 -0
- package/docs/quickstart.md +1 -1
- package/docs/settings.md +1 -0
- package/docs/terminal-setup.md +2 -3
- package/docs/usage.md +6 -5
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/package.json +1 -1
- package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
|
@@ -20,6 +20,7 @@ import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "../../core/defau
|
|
|
20
20
|
import { createCodingAgentFacade, createCodingAgentRuntimeFacade, } from "../../core/facade/index.js";
|
|
21
21
|
import { FooterDataProvider } from "../../core/footer-data-provider.js";
|
|
22
22
|
import { configureHttpDispatcher, formatHttpIdleTimeoutMs } from "../../core/http-dispatcher.js";
|
|
23
|
+
import { setI18nLanguage, t } from "../../core/i18n/index.js";
|
|
23
24
|
import { KeybindingsManager } from "../../core/keybindings.js";
|
|
24
25
|
import { createCompactionSummaryMessage } from "../../core/messages.js";
|
|
25
26
|
import { DefaultPackageManager } from "../../core/package-manager.js";
|
|
@@ -149,6 +150,14 @@ export function createInteractiveTui(options) {
|
|
|
149
150
|
return error instanceof Error ? error.message : String(error);
|
|
150
151
|
}
|
|
151
152
|
},
|
|
153
|
+
// tui 包自带文案的注入式翻译(批次⑦):默认英文,en 下逐字节不变;
|
|
154
|
+
// 前导/尾随空格在 t() 外拼接(t() 会 trim key)。
|
|
155
|
+
labels: {
|
|
156
|
+
searchTitle: ` ${t("Find transcript")}`,
|
|
157
|
+
searchNoMatches: `${t("No matches")} `,
|
|
158
|
+
copied: t("Copied!"),
|
|
159
|
+
copyFailed: t("Copy failed"),
|
|
160
|
+
},
|
|
152
161
|
});
|
|
153
162
|
}
|
|
154
163
|
return new TuiMainScreen(terminal, options.showHardwareCursor, options.logDirectory);
|
|
@@ -168,7 +177,7 @@ export function createInteractiveTuiReference(getTui) {
|
|
|
168
177
|
if (currentTui !== methodTui) {
|
|
169
178
|
const currentMethod = Reflect.get(currentTui, property, currentTui);
|
|
170
179
|
if (typeof currentMethod !== "function") {
|
|
171
|
-
throw new TypeError(
|
|
180
|
+
throw new TypeError(t("TUI property {property} is not callable", { property: String(property) }));
|
|
172
181
|
}
|
|
173
182
|
methodTui = currentTui;
|
|
174
183
|
method = currentMethod;
|
|
@@ -270,8 +279,8 @@ export class InteractiveMode {
|
|
|
270
279
|
workingMessage = undefined;
|
|
271
280
|
workingVisible = true;
|
|
272
281
|
workingIndicatorOptions = undefined;
|
|
273
|
-
defaultWorkingMessage = "Working...";
|
|
274
|
-
defaultHiddenThinkingLabel = "Thinking...";
|
|
282
|
+
defaultWorkingMessage = t("Working...");
|
|
283
|
+
defaultHiddenThinkingLabel = t("Thinking...");
|
|
275
284
|
hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
|
|
276
285
|
lastSigintTime = 0;
|
|
277
286
|
lastEscapeTime = 0;
|
|
@@ -366,6 +375,7 @@ export class InteractiveMode {
|
|
|
366
375
|
// manager (D-047) and the constructor uses it before anything else.
|
|
367
376
|
this.options = { ...options };
|
|
368
377
|
this.runtimeHost = runtimeHost;
|
|
378
|
+
setI18nLanguage(this.settingsManager.getUiLanguage());
|
|
369
379
|
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
370
380
|
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
371
381
|
this.options.tuiMode = tuiMode;
|
|
@@ -577,11 +587,14 @@ export class InteractiveMode {
|
|
|
577
587
|
if (this.settingsManager.getCollapseChangelog()) {
|
|
578
588
|
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
579
589
|
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
580
|
-
const condensedText =
|
|
590
|
+
const condensedText = t("Updated to v{version}. Use {command} to view full changelog.", {
|
|
591
|
+
version: latestVersion,
|
|
592
|
+
command: theme.bold("/changelog"),
|
|
593
|
+
});
|
|
581
594
|
this.chatContainer.addChild(new Text(condensedText, 1, 0));
|
|
582
595
|
}
|
|
583
596
|
else {
|
|
584
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
597
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("What's New"))), 1, 0));
|
|
585
598
|
this.chatContainer.addChild(new Spacer(1));
|
|
586
599
|
this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
|
|
587
600
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -593,7 +606,7 @@ export class InteractiveMode {
|
|
|
593
606
|
tui.addChild(component);
|
|
594
607
|
if (TuiLayouts.isViewportTUI(tui)) {
|
|
595
608
|
if (!this.fullscreenLayoutRoot)
|
|
596
|
-
throw new Error("Fullscreen layout is not initialized");
|
|
609
|
+
throw new Error(t("Fullscreen layout is not initialized"));
|
|
597
610
|
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
598
611
|
}
|
|
599
612
|
}
|
|
@@ -673,9 +686,11 @@ export class InteractiveMode {
|
|
|
673
686
|
.join(", ");
|
|
674
687
|
const cycleKeys = this.keybindings.getKeys("app.model.cycleForward");
|
|
675
688
|
const cycleHint = cycleKeys.length > 0
|
|
676
|
-
? theme.fg("muted", `
|
|
689
|
+
? theme.fg("muted", ` ${t("({key} to cycle)", {
|
|
690
|
+
key: formatKeyText(cycleKeys.join("/"), { capitalize: true }),
|
|
691
|
+
})}`)
|
|
677
692
|
: "";
|
|
678
|
-
console.log(theme.fg("dim",
|
|
693
|
+
console.log(theme.fg("dim", t("Model scope: {models}{hint}", { models: modelList, hint: cycleHint })));
|
|
679
694
|
}
|
|
680
695
|
// Keep one component tree and remount it when changing renderers.
|
|
681
696
|
// Widget chrome is fixed empty; no initialization render needed.
|
|
@@ -722,30 +737,32 @@ export class InteractiveMode {
|
|
|
722
737
|
// Build startup instructions using keybinding hint helpers
|
|
723
738
|
const hint = (keybinding, description) => keyHint(keybinding, description);
|
|
724
739
|
const expandedInstructions = [
|
|
725
|
-
hint("app.interrupt", "to interrupt"),
|
|
726
|
-
hint("app.clear", "to clear"),
|
|
727
|
-
rawKeyHint(
|
|
728
|
-
hint("app.exit", "to exit (empty)"),
|
|
729
|
-
hint("app.suspend", "to suspend"),
|
|
730
|
-
keyHint("tui.editor.deleteToLineEnd", "to delete to end"),
|
|
731
|
-
hint("app.tools.expand", "to expand tools"),
|
|
732
|
-
hint("app.thinking.toggle", "to expand thinking"),
|
|
733
|
-
hint("app.editor.external", "for external editor"),
|
|
734
|
-
rawKeyHint("/", "for commands"),
|
|
735
|
-
rawKeyHint("!", "to run bash"),
|
|
736
|
-
rawKeyHint("!!", "to run bash (no context)"),
|
|
737
|
-
hint("app.clipboard.pasteImage", "to paste image (with text fallback)"),
|
|
738
|
-
rawKeyHint("drop files", "to attach"),
|
|
740
|
+
hint("app.interrupt", t("to interrupt")),
|
|
741
|
+
hint("app.clear", t("to clear")),
|
|
742
|
+
rawKeyHint(t("{key} twice", { key: keyText("app.clear") }), t("to exit")),
|
|
743
|
+
hint("app.exit", t("to exit (empty)")),
|
|
744
|
+
hint("app.suspend", t("to suspend")),
|
|
745
|
+
keyHint("tui.editor.deleteToLineEnd", t("to delete to end")),
|
|
746
|
+
hint("app.tools.expand", t("to expand tools")),
|
|
747
|
+
hint("app.thinking.toggle", t("to expand thinking")),
|
|
748
|
+
hint("app.editor.external", t("for external editor")),
|
|
749
|
+
rawKeyHint("/", t("for commands")),
|
|
750
|
+
rawKeyHint("!", t("to run bash")),
|
|
751
|
+
rawKeyHint("!!", t("to run bash (no context)")),
|
|
752
|
+
hint("app.clipboard.pasteImage", t("to paste image (with text fallback)")),
|
|
753
|
+
rawKeyHint("drop files", t("to attach")),
|
|
739
754
|
].join("\n");
|
|
740
755
|
const compactInstructions = [
|
|
741
|
-
hint("app.interrupt", "interrupt"),
|
|
742
|
-
rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`, "clear/exit"),
|
|
743
|
-
rawKeyHint("/", "commands"),
|
|
744
|
-
rawKeyHint("!", "bash"),
|
|
745
|
-
hint("app.tools.expand", "more"),
|
|
756
|
+
hint("app.interrupt", t("interrupt")),
|
|
757
|
+
rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`, t("clear/exit")),
|
|
758
|
+
rawKeyHint("/", t("commands")),
|
|
759
|
+
rawKeyHint("!", t("bash")),
|
|
760
|
+
hint("app.tools.expand", t("more")),
|
|
746
761
|
].join(theme.fg("muted", " · "));
|
|
747
|
-
const compactOnboarding = theme.fg("dim",
|
|
748
|
-
|
|
762
|
+
const compactOnboarding = theme.fg("dim", t("Press {key} to show full startup help and loaded resources.", {
|
|
763
|
+
key: keyText("app.tools.expand"),
|
|
764
|
+
}));
|
|
765
|
+
const onboarding = theme.fg("dim", t("Agent Forge can explain its own features and look up its docs. Ask it how to use or extend Agent Forge."));
|
|
749
766
|
this.builtInHeader = new ExpandableText(() => `${logo}\n${compactInstructions}\n${compactOnboarding}\n\n${onboarding}`, () => `${logo}\n${expandedInstructions}\n\n${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
750
767
|
// Setup UI layout
|
|
751
768
|
this.headerContainer.addChild(new Spacer(1));
|
|
@@ -873,11 +890,11 @@ export class InteractiveMode {
|
|
|
873
890
|
}
|
|
874
891
|
}
|
|
875
892
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
876
|
-
this.showWarning(
|
|
893
|
+
this.showWarning(t("Migrated credentials to auth.json: {providers}", { providers: migratedProviders.join(", ") }));
|
|
877
894
|
}
|
|
878
895
|
const modelsJsonError = this.facade.getModelsError();
|
|
879
896
|
if (modelsJsonError) {
|
|
880
|
-
this.showError(
|
|
897
|
+
this.showError(t("models.json error: {error}", { error: modelsJsonError }));
|
|
881
898
|
}
|
|
882
899
|
if (modelFallbackMessage) {
|
|
883
900
|
this.showWarning(modelFallbackMessage);
|
|
@@ -889,7 +906,7 @@ export class InteractiveMode {
|
|
|
889
906
|
await this.facade.prompt(initialMessage, { images: initialImages });
|
|
890
907
|
}
|
|
891
908
|
catch (error) {
|
|
892
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
909
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
893
910
|
this.showError(errorMessage);
|
|
894
911
|
}
|
|
895
912
|
}
|
|
@@ -899,7 +916,7 @@ export class InteractiveMode {
|
|
|
899
916
|
await this.facade.prompt(message);
|
|
900
917
|
}
|
|
901
918
|
catch (error) {
|
|
902
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
919
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
903
920
|
this.showError(errorMessage);
|
|
904
921
|
}
|
|
905
922
|
}
|
|
@@ -918,7 +935,7 @@ export class InteractiveMode {
|
|
|
918
935
|
await this.promptWithEmptyReplyRetry(userInput);
|
|
919
936
|
}
|
|
920
937
|
catch (error) {
|
|
921
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
938
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
922
939
|
this.showError(errorMessage);
|
|
923
940
|
}
|
|
924
941
|
}
|
|
@@ -942,7 +959,7 @@ export class InteractiveMode {
|
|
|
942
959
|
return;
|
|
943
960
|
if (contentText(lastAssistant.content).trim().length > 0)
|
|
944
961
|
return;
|
|
945
|
-
this.showStatus("Previous reply was empty, retrying...");
|
|
962
|
+
this.showStatus(t("Previous reply was empty, retrying..."));
|
|
946
963
|
await this.facade.prompt(EMPTY_REPLY_RETRY_PROMPT);
|
|
947
964
|
}
|
|
948
965
|
async checkForPackageUpdates() {
|
|
@@ -996,10 +1013,10 @@ export class InteractiveMode {
|
|
|
996
1013
|
if (extendedKeys === undefined)
|
|
997
1014
|
return undefined;
|
|
998
1015
|
if (extendedKeys !== "on" && extendedKeys !== "always") {
|
|
999
|
-
return "tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.";
|
|
1016
|
+
return t("tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.");
|
|
1000
1017
|
}
|
|
1001
1018
|
if (extendedKeysFormat === "xterm") {
|
|
1002
|
-
return "tmux extended-keys-format is xterm. Agent Forge works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux.";
|
|
1019
|
+
return t("tmux extended-keys-format is xterm. Agent Forge works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux.");
|
|
1003
1020
|
}
|
|
1004
1021
|
return undefined;
|
|
1005
1022
|
}
|
|
@@ -1137,7 +1154,7 @@ export class InteractiveMode {
|
|
|
1137
1154
|
.map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
|
|
1138
1155
|
.join("\n");
|
|
1139
1156
|
const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
|
|
1140
|
-
addLoadedSection("Context", contextCompactList, contextList);
|
|
1157
|
+
addLoadedSection(t("Context"), contextCompactList, contextList);
|
|
1141
1158
|
}
|
|
1142
1159
|
const skills = skillsResult.skills;
|
|
1143
1160
|
if (skills.length > 0) {
|
|
@@ -1147,7 +1164,7 @@ export class InteractiveMode {
|
|
|
1147
1164
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1148
1165
|
});
|
|
1149
1166
|
const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
|
|
1150
|
-
addLoadedSection("Skills", skillCompactList, skillList);
|
|
1167
|
+
addLoadedSection(t("Skills"), skillCompactList, skillList);
|
|
1151
1168
|
}
|
|
1152
1169
|
const templates = this.facade.getPromptTemplates();
|
|
1153
1170
|
if (templates.length > 0) {
|
|
@@ -1166,7 +1183,7 @@ export class InteractiveMode {
|
|
|
1166
1183
|
},
|
|
1167
1184
|
});
|
|
1168
1185
|
const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
|
|
1169
|
-
addLoadedSection("Prompts", promptCompactList, templateList);
|
|
1186
|
+
addLoadedSection(t("Prompts"), promptCompactList, templateList);
|
|
1170
1187
|
}
|
|
1171
1188
|
// Show loaded themes (excluding built-in)
|
|
1172
1189
|
const loadedThemes = themesResult.themes;
|
|
@@ -1181,7 +1198,7 @@ export class InteractiveMode {
|
|
|
1181
1198
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1182
1199
|
});
|
|
1183
1200
|
const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ?? this.getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
|
|
1184
|
-
addLoadedSection("Themes", themeCompactList, themeList);
|
|
1201
|
+
addLoadedSection(t("Themes"), themeCompactList, themeList);
|
|
1185
1202
|
}
|
|
1186
1203
|
}
|
|
1187
1204
|
// v8 ignore next -- showDiagnostics 为假时上方已提前返回,此处恒为真
|
|
@@ -1189,19 +1206,19 @@ export class InteractiveMode {
|
|
|
1189
1206
|
const skillDiagnostics = skillsResult.diagnostics;
|
|
1190
1207
|
if (skillDiagnostics.length > 0) {
|
|
1191
1208
|
const warningLines = this.formatDiagnostics(skillDiagnostics, sourceInfos);
|
|
1192
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
|
|
1209
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Skill conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1193
1210
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1194
1211
|
}
|
|
1195
1212
|
const promptDiagnostics = promptsResult.diagnostics;
|
|
1196
1213
|
if (promptDiagnostics.length > 0) {
|
|
1197
1214
|
const warningLines = this.formatDiagnostics(promptDiagnostics, sourceInfos);
|
|
1198
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
|
|
1215
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Prompt conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1199
1216
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1200
1217
|
}
|
|
1201
1218
|
const themeDiagnostics = themesResult.diagnostics;
|
|
1202
1219
|
if (themeDiagnostics.length > 0) {
|
|
1203
1220
|
const warningLines = this.formatDiagnostics(themeDiagnostics, sourceInfos);
|
|
1204
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
|
|
1221
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Theme conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1205
1222
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1206
1223
|
}
|
|
1207
1224
|
}
|
|
@@ -1222,6 +1239,7 @@ export class InteractiveMode {
|
|
|
1222
1239
|
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1223
1240
|
}
|
|
1224
1241
|
applyRuntimeSettings() {
|
|
1242
|
+
setI18nLanguage(this.settingsManager.getUiLanguage());
|
|
1225
1243
|
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
1226
1244
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1227
1245
|
this.applyFullscreenScrollbarSetting();
|
|
@@ -1378,7 +1396,7 @@ export class InteractiveMode {
|
|
|
1378
1396
|
this.workingVisible = true;
|
|
1379
1397
|
this.setWorkingIndicator();
|
|
1380
1398
|
if (this.activeStatusIndicator?.kind === "working") {
|
|
1381
|
-
this.activeStatusIndicator.setMessage(`${this.defaultWorkingMessage}
|
|
1399
|
+
this.activeStatusIndicator.setMessage(`${this.defaultWorkingMessage} ${t("({key} to interrupt)", { key: keyText("app.interrupt") })}`);
|
|
1382
1400
|
}
|
|
1383
1401
|
this.setHiddenThinkingLabel();
|
|
1384
1402
|
}
|
|
@@ -1598,7 +1616,7 @@ export class InteractiveMode {
|
|
|
1598
1616
|
if (!text.trim())
|
|
1599
1617
|
return;
|
|
1600
1618
|
this.pendingUserInputs.push(text);
|
|
1601
|
-
this.showStatus("Startup in progress — input queued and will run when startup completes");
|
|
1619
|
+
this.showStatus(t("Startup in progress — input queued and will run when startup completes"));
|
|
1602
1620
|
}
|
|
1603
1621
|
setupEditorSubmitHandler() {
|
|
1604
1622
|
this.defaultEditor.onSubmit = async (rawText) => {
|
|
@@ -1656,7 +1674,7 @@ export class InteractiveMode {
|
|
|
1656
1674
|
const command = isExcluded ? text.slice(2).trim() : text.slice(1).trim();
|
|
1657
1675
|
if (command) {
|
|
1658
1676
|
if (this.facade.isBashRunning()) {
|
|
1659
|
-
this.showWarning("A bash command is already running. Press Esc to cancel it first.");
|
|
1677
|
+
this.showWarning(t("A bash command is already running. Press Esc to cancel it first."));
|
|
1660
1678
|
this.editor.setText(text);
|
|
1661
1679
|
return true;
|
|
1662
1680
|
}
|
|
@@ -1813,14 +1831,16 @@ export class InteractiveMode {
|
|
|
1813
1831
|
const retryAttempt = this.facade.getRetryAttempt();
|
|
1814
1832
|
errorMessage =
|
|
1815
1833
|
retryAttempt > 0
|
|
1816
|
-
?
|
|
1817
|
-
|
|
1834
|
+
? retryAttempt === 1
|
|
1835
|
+
? t("Aborted after {count} retry attempt", { count: retryAttempt })
|
|
1836
|
+
: t("Aborted after {count} retry attempts", { count: retryAttempt })
|
|
1837
|
+
: t("Operation aborted");
|
|
1818
1838
|
this.streamingMessage.errorMessage = errorMessage;
|
|
1819
1839
|
}
|
|
1820
1840
|
this.streamingComponent.updateContent(this.streamingMessage, false);
|
|
1821
1841
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
1822
1842
|
if (!errorMessage) {
|
|
1823
|
-
errorMessage = this.streamingMessage.errorMessage || "Error";
|
|
1843
|
+
errorMessage = this.streamingMessage.errorMessage || t("Error");
|
|
1824
1844
|
}
|
|
1825
1845
|
for (const [, component] of this.pendingTools.entries()) {
|
|
1826
1846
|
component.updateResult({
|
|
@@ -1929,16 +1949,16 @@ export class InteractiveMode {
|
|
|
1929
1949
|
this.clearStatusIndicator("compaction");
|
|
1930
1950
|
if (event.aborted) {
|
|
1931
1951
|
if (event.reason === "manual") {
|
|
1932
|
-
this.showError("Compaction cancelled");
|
|
1952
|
+
this.showError(t("Compaction cancelled"));
|
|
1933
1953
|
}
|
|
1934
1954
|
else {
|
|
1935
|
-
this.showStatus("Auto-compaction cancelled");
|
|
1955
|
+
this.showStatus(t("Auto-compaction cancelled"));
|
|
1936
1956
|
}
|
|
1937
1957
|
}
|
|
1938
1958
|
else if (event.result) {
|
|
1939
1959
|
const entries = this.facade.getContextEntries();
|
|
1940
1960
|
if (entries[0]?.type !== "compaction") {
|
|
1941
|
-
throw new Error("Completed compaction is missing from the session context");
|
|
1961
|
+
throw new Error(t("Completed compaction is missing from the session context"));
|
|
1942
1962
|
}
|
|
1943
1963
|
this.chatContainer.clear();
|
|
1944
1964
|
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
@@ -1967,7 +1987,7 @@ export class InteractiveMode {
|
|
|
1967
1987
|
break;
|
|
1968
1988
|
}
|
|
1969
1989
|
case "compaction_skipped": {
|
|
1970
|
-
this.showStatus("Auto-compaction skipped: nothing to compact");
|
|
1990
|
+
this.showStatus(t("Auto-compaction skipped: nothing to compact"));
|
|
1971
1991
|
this.ui.requestRender();
|
|
1972
1992
|
break;
|
|
1973
1993
|
}
|
|
@@ -1990,7 +2010,10 @@ export class InteractiveMode {
|
|
|
1990
2010
|
this.clearStatusIndicator("retry");
|
|
1991
2011
|
// Show error only on final failure (success shows normal response)
|
|
1992
2012
|
if (!event.success) {
|
|
1993
|
-
this.showError(
|
|
2013
|
+
this.showError(t("Retry failed after {count} attempts: {error}", {
|
|
2014
|
+
count: event.attempt,
|
|
2015
|
+
error: event.finalError || t("Unknown error"),
|
|
2016
|
+
}));
|
|
1994
2017
|
}
|
|
1995
2018
|
this.ui.requestRender();
|
|
1996
2019
|
break;
|
|
@@ -2034,7 +2057,7 @@ export class InteractiveMode {
|
|
|
2034
2057
|
this.chatContainer.addChild(new Spacer(1));
|
|
2035
2058
|
this.managedToolStatusStarted = true;
|
|
2036
2059
|
}
|
|
2037
|
-
const message = status.type === "warning" ?
|
|
2060
|
+
const message = status.type === "warning" ? t("Warning: {message}", { message: status.message }) : status.message;
|
|
2038
2061
|
const color = status.type === "warning" ? "warning" : "dim";
|
|
2039
2062
|
this.chatContainer.addChild(new Text(theme.fg(color, message), 1, 0));
|
|
2040
2063
|
this.lastStatusSpacer = undefined;
|
|
@@ -2183,11 +2206,13 @@ export class InteractiveMode {
|
|
|
2183
2206
|
const retryAttempt = this.facade.getRetryAttempt();
|
|
2184
2207
|
errorMessage =
|
|
2185
2208
|
retryAttempt > 0
|
|
2186
|
-
?
|
|
2187
|
-
|
|
2209
|
+
? retryAttempt === 1
|
|
2210
|
+
? t("Aborted after {count} retry attempt", { count: retryAttempt })
|
|
2211
|
+
: t("Aborted after {count} retry attempts", { count: retryAttempt })
|
|
2212
|
+
: t("Operation aborted");
|
|
2188
2213
|
}
|
|
2189
2214
|
else {
|
|
2190
|
-
errorMessage = message.errorMessage || "Error";
|
|
2215
|
+
errorMessage = message.errorMessage || t("Error");
|
|
2191
2216
|
}
|
|
2192
2217
|
component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
|
|
2193
2218
|
}
|
|
@@ -2249,9 +2274,9 @@ export class InteractiveMode {
|
|
|
2249
2274
|
const { usage } = notice;
|
|
2250
2275
|
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
2251
2276
|
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
2252
|
-
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
2277
|
+
const label = notice.kind === "compaction" ? t("Compaction") : t("Branch summary");
|
|
2253
2278
|
this.chatContainer.addChild(new Spacer(1));
|
|
2254
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${
|
|
2279
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${t("{tokens} tokens billed{cost}", { tokens: formatTokens(tokens), cost })}`), 1, 0));
|
|
2255
2280
|
}
|
|
2256
2281
|
static countDroppedThinkingBlocks(message) {
|
|
2257
2282
|
let count = 0;
|
|
@@ -2286,9 +2311,8 @@ export class InteractiveMode {
|
|
|
2286
2311
|
}
|
|
2287
2312
|
if (droppedCount <= previousDroppedCount)
|
|
2288
2313
|
return;
|
|
2289
|
-
const noun = droppedCount === 1 ? "thinking block" : "thinking blocks";
|
|
2290
2314
|
this.chatContainer.addChild(new Spacer(1));
|
|
2291
|
-
this.chatContainer.addChild(new Text(theme.fg("warning",
|
|
2315
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", t("Anthropic dropped {count} thinking blocks (details in session)", { count: droppedCount })), 1, 0));
|
|
2292
2316
|
}
|
|
2293
2317
|
/**
|
|
2294
2318
|
* Show a transcript notice when a completed assistant message paid for a
|
|
@@ -2307,13 +2331,13 @@ export class InteractiveMode {
|
|
|
2307
2331
|
if (miss.missedTokens < 20_000 && miss.missedCost < 0.1)
|
|
2308
2332
|
return;
|
|
2309
2333
|
const cost = miss.missedCost >= 0.01 ? ` (~$${miss.missedCost.toFixed(2)})` : "";
|
|
2310
|
-
const reBilled =
|
|
2311
|
-
let label = "Cache miss";
|
|
2334
|
+
const reBilled = t("{tokens} tokens re-billed{cost}", { tokens: formatTokens(miss.missedTokens), cost });
|
|
2335
|
+
let label = t("Cache miss");
|
|
2312
2336
|
if (miss.modelChanged) {
|
|
2313
|
-
label = "Cache miss after model switch";
|
|
2337
|
+
label = t("Cache miss after model switch");
|
|
2314
2338
|
}
|
|
2315
2339
|
else if (miss.idleMs >= CACHE_TTL_MS) {
|
|
2316
|
-
label =
|
|
2340
|
+
label = t("Cache miss after {minutes}m idle", { minutes: Math.round(miss.idleMs / 60_000) });
|
|
2317
2341
|
}
|
|
2318
2342
|
const text = theme.fg("warning", `${label}: ${reBilled}`);
|
|
2319
2343
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -2329,8 +2353,9 @@ export class InteractiveMode {
|
|
|
2329
2353
|
const allEntries = this.facade.getEntries();
|
|
2330
2354
|
const compactionCount = allEntries.filter((e) => e.type === "compaction").length;
|
|
2331
2355
|
if (compactionCount > 0) {
|
|
2332
|
-
|
|
2333
|
-
|
|
2356
|
+
this.showStatus(compactionCount === 1
|
|
2357
|
+
? t("Session compacted {count} time", { count: compactionCount })
|
|
2358
|
+
: t("Session compacted {count} times", { count: compactionCount }));
|
|
2334
2359
|
}
|
|
2335
2360
|
}
|
|
2336
2361
|
async getUserInput() {
|
|
@@ -2404,7 +2429,7 @@ export class InteractiveMode {
|
|
|
2404
2429
|
await this.runtimeFacade.dispose();
|
|
2405
2430
|
const resumeCommand = formatResumeCommand(this.runtimeFacade);
|
|
2406
2431
|
if (resumeCommand) {
|
|
2407
|
-
process.stdout.write(`${chalk.dim("To resume this session:")} ${resumeCommand}\n`);
|
|
2432
|
+
process.stdout.write(`${chalk.dim(t("To resume this session:"))} ${resumeCommand}\n`);
|
|
2408
2433
|
}
|
|
2409
2434
|
process.exit(0);
|
|
2410
2435
|
}
|
|
@@ -2444,7 +2469,7 @@ export class InteractiveMode {
|
|
|
2444
2469
|
this.ui.stop();
|
|
2445
2470
|
}
|
|
2446
2471
|
catch { }
|
|
2447
|
-
console.error(
|
|
2472
|
+
console.error(t("{app} exiting due to uncaughtException:", { app: APP_NAME }));
|
|
2448
2473
|
console.error(error);
|
|
2449
2474
|
process.exit(1);
|
|
2450
2475
|
}
|
|
@@ -2499,7 +2524,7 @@ export class InteractiveMode {
|
|
|
2499
2524
|
}
|
|
2500
2525
|
handleCtrlZ() {
|
|
2501
2526
|
if (process.platform === "win32") {
|
|
2502
|
-
this.showStatus("Suspend to background is not supported on Windows");
|
|
2527
|
+
this.showStatus(t("Suspend to background is not supported on Windows"));
|
|
2503
2528
|
return;
|
|
2504
2529
|
}
|
|
2505
2530
|
// Keep the event loop alive while suspended. Without this, stopping the TUI
|
|
@@ -2560,16 +2585,19 @@ export class InteractiveMode {
|
|
|
2560
2585
|
handleDequeue() {
|
|
2561
2586
|
const restored = this.restoreQueuedMessagesToEditor();
|
|
2562
2587
|
if (restored === 0) {
|
|
2563
|
-
this.showStatus("No queued messages to restore");
|
|
2588
|
+
this.showStatus(t("No queued messages to restore"));
|
|
2589
|
+
}
|
|
2590
|
+
else if (restored === 1) {
|
|
2591
|
+
this.showStatus(t("Restored {count} queued message to editor", { count: restored }));
|
|
2564
2592
|
}
|
|
2565
2593
|
else {
|
|
2566
|
-
this.showStatus(
|
|
2594
|
+
this.showStatus(t("Restored {count} queued messages to editor", { count: restored }));
|
|
2567
2595
|
}
|
|
2568
2596
|
}
|
|
2569
2597
|
/** /queue command host face (single-entry iron law): queues the given text for after the current run. A bare /queue cannot mirror the keybinding — the editor buffer is cleared on submit before the command runs — so it prints usage instead of silently doing nothing. */
|
|
2570
2598
|
handleQueueCommand(text) {
|
|
2571
2599
|
if (text === undefined || text.trim() === "") {
|
|
2572
|
-
this.showStatus("Usage: /queue <text>");
|
|
2600
|
+
this.showStatus(t("Usage: /queue <text>"));
|
|
2573
2601
|
return Promise.resolve();
|
|
2574
2602
|
}
|
|
2575
2603
|
return this.handleFollowUp(text);
|
|
@@ -2578,6 +2606,16 @@ export class InteractiveMode {
|
|
|
2578
2606
|
handleDequeueCommand() {
|
|
2579
2607
|
this.handleDequeue();
|
|
2580
2608
|
}
|
|
2609
|
+
/** /queue-list command host face: open the queued-message manager selector. Both queues empty is a status message, not an empty overlay. */
|
|
2610
|
+
handleQueueListCommand() {
|
|
2611
|
+
const steering = this.facade.getSteeringMessages();
|
|
2612
|
+
const followUp = this.facade.getFollowUpMessages();
|
|
2613
|
+
if (steering.length === 0 && followUp.length === 0) {
|
|
2614
|
+
this.showStatus(t("No queued messages to manage"));
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
selectorsFlow.showQueueManagerSelector(this);
|
|
2618
|
+
}
|
|
2581
2619
|
/** /editor command host face: edit the current input in an external editor. */
|
|
2582
2620
|
handleEditorCommand() {
|
|
2583
2621
|
return this.handleOpenExternalEditor();
|
|
@@ -2596,26 +2634,31 @@ export class InteractiveMode {
|
|
|
2596
2634
|
cycleThinkingLevel() {
|
|
2597
2635
|
const newLevel = this.facade.cycleThinkingLevel();
|
|
2598
2636
|
if (newLevel === undefined) {
|
|
2599
|
-
this.showStatus("Current model does not support thinking");
|
|
2637
|
+
this.showStatus(t("Current model does not support thinking"));
|
|
2600
2638
|
}
|
|
2601
2639
|
else {
|
|
2602
2640
|
this.footer.invalidate();
|
|
2603
2641
|
this.updateEditorBorderColor();
|
|
2604
|
-
this.showStatus(
|
|
2642
|
+
this.showStatus(t("Thinking level: {level}", { level: newLevel }));
|
|
2605
2643
|
}
|
|
2606
2644
|
}
|
|
2607
2645
|
async cycleModel(direction) {
|
|
2608
2646
|
try {
|
|
2609
2647
|
const result = await this.facade.cycleModel(direction);
|
|
2610
2648
|
if (result === undefined) {
|
|
2611
|
-
const msg = this.facade.getScopedModels().length > 0 ? "Only one model in scope" : "Only one model available";
|
|
2649
|
+
const msg = this.facade.getScopedModels().length > 0 ? t("Only one model in scope") : t("Only one model available");
|
|
2612
2650
|
this.showStatus(msg);
|
|
2613
2651
|
}
|
|
2614
2652
|
else {
|
|
2615
2653
|
this.footer.invalidate();
|
|
2616
2654
|
this.updateEditorBorderColor();
|
|
2617
|
-
const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off"
|
|
2618
|
-
|
|
2655
|
+
const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off"
|
|
2656
|
+
? ` ${t("(thinking: {level})", { level: result.thinkingLevel })}`
|
|
2657
|
+
: "";
|
|
2658
|
+
this.showStatus(t("Switched to {model}{thinking}", {
|
|
2659
|
+
model: result.model.name || result.model.id,
|
|
2660
|
+
thinking: thinkingStr,
|
|
2661
|
+
}));
|
|
2619
2662
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);
|
|
2620
2663
|
}
|
|
2621
2664
|
}
|
|
@@ -2641,7 +2684,7 @@ export class InteractiveMode {
|
|
|
2641
2684
|
}
|
|
2642
2685
|
}
|
|
2643
2686
|
}
|
|
2644
|
-
this.showStatus(
|
|
2687
|
+
this.showStatus(expanded ? t("Tool output: expanded") : t("Tool output: collapsed"));
|
|
2645
2688
|
}
|
|
2646
2689
|
/** Update rendered assistant messages without rebuilding live tool components. */
|
|
2647
2690
|
updateThinkingBlockVisibility() {
|
|
@@ -2656,7 +2699,7 @@ export class InteractiveMode {
|
|
|
2656
2699
|
this.hideThinkingBlock = !this.hideThinkingBlock;
|
|
2657
2700
|
this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);
|
|
2658
2701
|
this.updateThinkingBlockVisibility();
|
|
2659
|
-
this.showStatus(
|
|
2702
|
+
this.showStatus(this.hideThinkingBlock ? t("Thinking blocks: hidden") : t("Thinking blocks: visible"));
|
|
2660
2703
|
}
|
|
2661
2704
|
async handleOpenExternalEditor() {
|
|
2662
2705
|
const editorCmd = this.settingsManager.getExternalEditorCommand();
|
|
@@ -2685,28 +2728,28 @@ export class InteractiveMode {
|
|
|
2685
2728
|
}
|
|
2686
2729
|
showError(errorMessage) {
|
|
2687
2730
|
this.chatContainer.addChild(new Spacer(1));
|
|
2688
|
-
this.chatContainer.addChild(new Text(theme.fg("error",
|
|
2731
|
+
this.chatContainer.addChild(new Text(theme.fg("error", t("Error: {message}", { message: errorMessage })), this.outputPad, 0));
|
|
2689
2732
|
this.ui.requestRender();
|
|
2690
2733
|
}
|
|
2691
2734
|
showWarning(warningMessage) {
|
|
2692
2735
|
this.chatContainer.addChild(new Spacer(1));
|
|
2693
|
-
this.chatContainer.addChild(new Text(theme.fg("warning",
|
|
2736
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", t("Warning: {message}", { message: warningMessage })), 1, 0));
|
|
2694
2737
|
this.ui.requestRender();
|
|
2695
2738
|
}
|
|
2696
2739
|
showNewVersionNotification(release) {
|
|
2697
2740
|
const action = theme.fg("accent", `${APP_NAME} update`);
|
|
2698
|
-
const updateInstruction = theme.fg("muted",
|
|
2741
|
+
const updateInstruction = theme.fg("muted", `${t("New version {version} is available. Run", { version: release.version })} `) + action;
|
|
2699
2742
|
const changelogUrl = process.env.AGENT_FORGE_CHANGELOG_URL;
|
|
2700
2743
|
const changelogLine = changelogUrl
|
|
2701
|
-
? theme.fg("muted", "Changelog:
|
|
2744
|
+
? theme.fg("muted", `${t("Changelog:")} `) +
|
|
2702
2745
|
(getCapabilities().hyperlinks
|
|
2703
2746
|
? hyperlink(theme.fg("accent", changelogUrl), changelogUrl)
|
|
2704
2747
|
: theme.fg("accent", changelogUrl))
|
|
2705
|
-
: theme.fg("muted", "Changelog URL is not configured.");
|
|
2748
|
+
: theme.fg("muted", t("Changelog URL is not configured."));
|
|
2706
2749
|
const note = release.note?.trim();
|
|
2707
2750
|
this.chatContainer.addChild(new Spacer(1));
|
|
2708
2751
|
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
2709
|
-
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", "Update Available"))}\n${updateInstruction}`, 1, 0));
|
|
2752
|
+
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", t("Update Available")))}\n${updateInstruction}`, 1, 0));
|
|
2710
2753
|
if (note) {
|
|
2711
2754
|
this.chatContainer.addChild(new Spacer(1));
|
|
2712
2755
|
this.chatContainer.addChild(new Markdown(note, 1, 0, this.getMarkdownThemeWithSettings(), {
|
|
@@ -2720,11 +2763,11 @@ export class InteractiveMode {
|
|
|
2720
2763
|
}
|
|
2721
2764
|
showPackageUpdateNotification(packages) {
|
|
2722
2765
|
const action = theme.fg("accent", `${APP_NAME} update --extensions`);
|
|
2723
|
-
const updateInstruction = theme.fg("muted", "Package updates are available. Run
|
|
2766
|
+
const updateInstruction = theme.fg("muted", `${t("Package updates are available. Run")} `) + action;
|
|
2724
2767
|
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
|
2725
2768
|
this.chatContainer.addChild(new Spacer(1));
|
|
2726
2769
|
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
2727
|
-
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", "Package Updates Available"))}\n${updateInstruction}\n${theme.fg("muted", "Packages:")}\n${packageLines}`, 1, 0));
|
|
2770
|
+
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", t("Package Updates Available")))}\n${updateInstruction}\n${theme.fg("muted", `${t("Packages:")}`)}\n${packageLines}`, 1, 0));
|
|
2728
2771
|
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
2729
2772
|
this.ui.requestRender();
|
|
2730
2773
|
}
|
|
@@ -2762,23 +2805,24 @@ export class InteractiveMode {
|
|
|
2762
2805
|
followUp: [...followUp, ...compactionFollowUp],
|
|
2763
2806
|
};
|
|
2764
2807
|
}
|
|
2808
|
+
/** Host-visible for ./interactive-selectors.ts (queue manager close path). */
|
|
2765
2809
|
updatePendingMessagesDisplay() {
|
|
2766
2810
|
this.pendingMessagesContainer.clear();
|
|
2767
2811
|
const { steering: steeringMessages, followUp: followUpMessages } = this.getAllQueuedMessages();
|
|
2768
2812
|
if (steeringMessages.length > 0 || followUpMessages.length > 0) {
|
|
2769
2813
|
this.pendingMessagesContainer.addChild(new Spacer(1));
|
|
2770
2814
|
for (const message of steeringMessages) {
|
|
2771
|
-
const text = theme.fg("dim",
|
|
2815
|
+
const text = theme.fg("dim", t("Steering: {message}", { message }));
|
|
2772
2816
|
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
2773
2817
|
}
|
|
2774
2818
|
for (const message of followUpMessages) {
|
|
2775
|
-
const text = theme.fg("dim",
|
|
2819
|
+
const text = theme.fg("dim", t("Follow-up: {message}", { message }));
|
|
2776
2820
|
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
2777
2821
|
}
|
|
2778
2822
|
// The dequeue keybinding's shipped default was cleared (iron law):
|
|
2779
2823
|
// /queue's sibling command is the discoverable entry.
|
|
2780
2824
|
const dequeueHint = this.getAppKeyDisplay("app.message.dequeue") || "/dequeue";
|
|
2781
|
-
const hintText = theme.fg("dim",
|
|
2825
|
+
const hintText = theme.fg("dim", t("↳ {key} to edit all queued messages", { key: dequeueHint }));
|
|
2782
2826
|
this.pendingMessagesContainer.addChild(new TruncatedText(hintText, 1, 0));
|
|
2783
2827
|
}
|
|
2784
2828
|
}
|
|
@@ -2810,7 +2854,7 @@ export class InteractiveMode {
|
|
|
2810
2854
|
this.editor.addToHistory?.(text);
|
|
2811
2855
|
this.editor.setText("");
|
|
2812
2856
|
this.updatePendingMessagesDisplay();
|
|
2813
|
-
this.showStatus("Queued message for after compaction");
|
|
2857
|
+
this.showStatus(t("Queued message for after compaction"));
|
|
2814
2858
|
}
|
|
2815
2859
|
async flushCompactionQueue(options) {
|
|
2816
2860
|
if (this.compactionQueuedMessages.length === 0) {
|
|
@@ -2823,7 +2867,13 @@ export class InteractiveMode {
|
|
|
2823
2867
|
this.facade.clearQueue();
|
|
2824
2868
|
this.compactionQueuedMessages = queuedMessages;
|
|
2825
2869
|
this.updatePendingMessagesDisplay();
|
|
2826
|
-
this.showError(
|
|
2870
|
+
this.showError(queuedMessages.length > 1
|
|
2871
|
+
? t("Failed to send queued messages: {error}", {
|
|
2872
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2873
|
+
})
|
|
2874
|
+
: t("Failed to send queued message: {error}", {
|
|
2875
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2876
|
+
}));
|
|
2827
2877
|
};
|
|
2828
2878
|
try {
|
|
2829
2879
|
if (options?.willRetry) {
|
|
@@ -2920,7 +2970,7 @@ export class InteractiveMode {
|
|
|
2920
2970
|
let selector;
|
|
2921
2971
|
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
2922
2972
|
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
2923
|
-
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
2973
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : t("not set");
|
|
2924
2974
|
selector = new SettingsSelectorComponent({
|
|
2925
2975
|
autoCompact: this.facade.isAutoCompactionEnabled(),
|
|
2926
2976
|
defaultModel,
|
|
@@ -2945,6 +2995,7 @@ export class InteractiveMode {
|
|
|
2945
2995
|
mermaidRenderingMode: this.settingsManager.getMermaidRenderingMode(),
|
|
2946
2996
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
2947
2997
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
2998
|
+
uiLanguage: this.settingsManager.getUiLanguage(),
|
|
2948
2999
|
treeFilterMode: this.settingsManager.getTreeFilterMode(),
|
|
2949
3000
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
2950
3001
|
showCacheMissNotices: this.settingsManager.getShowCacheMissNotices(),
|
|
@@ -3004,7 +3055,7 @@ export class InteractiveMode {
|
|
|
3004
3055
|
onHttpIdleTimeoutMsChange: (timeoutMs) => {
|
|
3005
3056
|
this.settingsManager.setHttpIdleTimeoutMs(timeoutMs);
|
|
3006
3057
|
configureHttpDispatcher(timeoutMs);
|
|
3007
|
-
this.showStatus(
|
|
3058
|
+
this.showStatus(t("HTTP idle timeout: {value}", { value: formatHttpIdleTimeoutMs(timeoutMs) }));
|
|
3008
3059
|
},
|
|
3009
3060
|
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
3010
3061
|
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
@@ -3055,6 +3106,11 @@ export class InteractiveMode {
|
|
|
3055
3106
|
onDoubleEscapeActionChange: (action) => {
|
|
3056
3107
|
this.settingsManager.setDoubleEscapeAction(action);
|
|
3057
3108
|
},
|
|
3109
|
+
onUiLanguageChange: (language) => {
|
|
3110
|
+
this.settingsManager.setUiLanguage(language);
|
|
3111
|
+
setI18nLanguage(language);
|
|
3112
|
+
this.ui.requestRender();
|
|
3113
|
+
},
|
|
3058
3114
|
onTreeFilterModeChange: (mode) => {
|
|
3059
3115
|
this.settingsManager.setTreeFilterMode(mode);
|
|
3060
3116
|
},
|
|
@@ -3108,13 +3164,13 @@ export class InteractiveMode {
|
|
|
3108
3164
|
onTuiModeChange: (mode) => {
|
|
3109
3165
|
if (!this.switchTuiMode(mode)) {
|
|
3110
3166
|
selector?.getSettingsList().updateValue("tui-mode", this.ui.mode);
|
|
3111
|
-
this.showStatus("Close active overlays before changing TUI mode");
|
|
3167
|
+
this.showStatus(t("Close active overlays before changing TUI mode"));
|
|
3112
3168
|
return;
|
|
3113
3169
|
}
|
|
3114
3170
|
this.settingsManager.setTuiMode(mode);
|
|
3115
3171
|
if (!this.activeStatusIndicator)
|
|
3116
3172
|
this.statusContainer.clear();
|
|
3117
|
-
this.showStatus(
|
|
3173
|
+
this.showStatus(t("TUI mode: {mode}", { mode }));
|
|
3118
3174
|
},
|
|
3119
3175
|
onFullscreenExitOutputChange: (output) => {
|
|
3120
3176
|
this.settingsManager.setFullscreenExitOutput(output);
|
|
@@ -3222,22 +3278,26 @@ export class InteractiveMode {
|
|
|
3222
3278
|
const selected = await new Promise((resolve) => {
|
|
3223
3279
|
this.openSuiteListSelector({
|
|
3224
3280
|
availableSuites: pending.available,
|
|
3225
|
-
note:
|
|
3281
|
+
note: t('Suite "{id}" was not found. The selected suite applies to the new session.', {
|
|
3282
|
+
id: pending.requestedId,
|
|
3283
|
+
}),
|
|
3226
3284
|
onSelect: (suiteId) => resolve(suiteId),
|
|
3227
3285
|
onCancel: () => resolve(undefined),
|
|
3228
3286
|
});
|
|
3229
3287
|
});
|
|
3230
3288
|
if (selected === undefined) {
|
|
3231
|
-
this.showWarning(
|
|
3289
|
+
this.showWarning(t('Suite "{id}" was not found — continuing without a suite. Use /suite to choose one.', {
|
|
3290
|
+
id: pending.requestedId,
|
|
3291
|
+
}));
|
|
3232
3292
|
return;
|
|
3233
3293
|
}
|
|
3234
3294
|
this.settingsManager.setProjectSuite(selected);
|
|
3235
3295
|
try {
|
|
3236
3296
|
await this.runtimeFacade.newSession();
|
|
3237
|
-
this.showStatus(
|
|
3297
|
+
this.showStatus(t("Suite set to {id} — new session started", { id: selected }));
|
|
3238
3298
|
}
|
|
3239
3299
|
catch (error) {
|
|
3240
|
-
await this.handleFatalRuntimeError("Failed to create session", error);
|
|
3300
|
+
await this.handleFatalRuntimeError(t("Failed to create session"), error);
|
|
3241
3301
|
}
|
|
3242
3302
|
}
|
|
3243
3303
|
/** /model command entry; implementation in ./interactive-selectors.ts (S5 slice 5). */
|
|
@@ -3273,7 +3333,7 @@ export class InteractiveMode {
|
|
|
3273
3333
|
try {
|
|
3274
3334
|
if ((await this.facade.checkProviderAuth("anthropic"))?.type === "oauth") {
|
|
3275
3335
|
this.anthropicSubscriptionWarningShown = true;
|
|
3276
|
-
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
3336
|
+
this.showWarning(t(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING));
|
|
3277
3337
|
return;
|
|
3278
3338
|
}
|
|
3279
3339
|
const apiKey = (await this.facade.getProviderAuth(model.provider))?.auth.apiKey;
|
|
@@ -3281,7 +3341,7 @@ export class InteractiveMode {
|
|
|
3281
3341
|
return;
|
|
3282
3342
|
}
|
|
3283
3343
|
this.anthropicSubscriptionWarningShown = true;
|
|
3284
|
-
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
3344
|
+
this.showWarning(t(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING));
|
|
3285
3345
|
}
|
|
3286
3346
|
catch {
|
|
3287
3347
|
// Ignore auth lookup failures for warning-only checks.
|
|
@@ -3314,7 +3374,7 @@ export class InteractiveMode {
|
|
|
3314
3374
|
.getEntries()
|
|
3315
3375
|
.some((entry) => entry.type === "custom" && entry.customType === "workflow.state");
|
|
3316
3376
|
if (!hasSnapshot) {
|
|
3317
|
-
this.showStatus("No workflow in this session");
|
|
3377
|
+
this.showStatus(t("No workflow in this session"));
|
|
3318
3378
|
return;
|
|
3319
3379
|
}
|
|
3320
3380
|
this.showSelector((done) => {
|
|
@@ -3328,7 +3388,7 @@ export class InteractiveMode {
|
|
|
3328
3388
|
done();
|
|
3329
3389
|
this.editor.setText(text);
|
|
3330
3390
|
this.ui.requestRender();
|
|
3331
|
-
this.showStatus("Workflow action staged — review in the editor and submit");
|
|
3391
|
+
this.showStatus(t("Workflow action staged — review in the editor and submit"));
|
|
3332
3392
|
};
|
|
3333
3393
|
return { component: view, focus: view, dispose: () => view.dispose() };
|
|
3334
3394
|
});
|
|
@@ -3344,7 +3404,7 @@ export class InteractiveMode {
|
|
|
3344
3404
|
const agentDir = getAgentDir();
|
|
3345
3405
|
const sessions = listAgentSessions({ agentDir, parentAgentSession: this.facade.getSessionId() });
|
|
3346
3406
|
if (sessions.length === 0) {
|
|
3347
|
-
this.showStatus("No subagent sessions in this session");
|
|
3407
|
+
this.showStatus(t("No subagent sessions in this session"));
|
|
3348
3408
|
return;
|
|
3349
3409
|
}
|
|
3350
3410
|
this.showSelector((done) => {
|
|
@@ -3363,7 +3423,7 @@ export class InteractiveMode {
|
|
|
3363
3423
|
const realLeafId = this.facade.getLeafId();
|
|
3364
3424
|
const initialFilterMode = this.settingsManager.getTreeFilterMode();
|
|
3365
3425
|
if (tree.length === 0) {
|
|
3366
|
-
this.showStatus("No entries in session");
|
|
3426
|
+
this.showStatus(t("No entries in session"));
|
|
3367
3427
|
return;
|
|
3368
3428
|
}
|
|
3369
3429
|
this.showSelector((done) => {
|
|
@@ -3371,7 +3431,7 @@ export class InteractiveMode {
|
|
|
3371
3431
|
// Selecting the current leaf is a no-op (already there)
|
|
3372
3432
|
if (entryId === this.facade.getLeafId()) {
|
|
3373
3433
|
done();
|
|
3374
|
-
this.showStatus("Already at this point");
|
|
3434
|
+
this.showStatus(t("Already at this point"));
|
|
3375
3435
|
return;
|
|
3376
3436
|
}
|
|
3377
3437
|
// Ask about summarization
|
|
@@ -3382,19 +3442,19 @@ export class InteractiveMode {
|
|
|
3382
3442
|
// Check if we should skip the prompt (user preference to always default to no summary)
|
|
3383
3443
|
if (!this.settingsManager.getBranchSummarySkipPrompt()) {
|
|
3384
3444
|
while (true) {
|
|
3385
|
-
const summaryChoice = await this.showDialogSelector("Summarize branch?", [
|
|
3386
|
-
"No summary",
|
|
3387
|
-
"Summarize",
|
|
3388
|
-
"Summarize with custom prompt",
|
|
3445
|
+
const summaryChoice = await this.showDialogSelector(t("Summarize branch?"), [
|
|
3446
|
+
t("No summary"),
|
|
3447
|
+
t("Summarize"),
|
|
3448
|
+
t("Summarize with custom prompt"),
|
|
3389
3449
|
]);
|
|
3390
3450
|
if (summaryChoice === undefined) {
|
|
3391
3451
|
// User pressed escape - re-show tree selector with same selection
|
|
3392
3452
|
this.showTreeSelector(entryId);
|
|
3393
3453
|
return;
|
|
3394
3454
|
}
|
|
3395
|
-
wantsSummary = summaryChoice !== "No summary";
|
|
3396
|
-
if (summaryChoice === "Summarize with custom prompt") {
|
|
3397
|
-
customInstructions = await this.showDialogEditor("Custom summarization instructions");
|
|
3455
|
+
wantsSummary = summaryChoice !== t("No summary");
|
|
3456
|
+
if (summaryChoice === t("Summarize with custom prompt")) {
|
|
3457
|
+
customInstructions = await this.showDialogEditor(t("Custom summarization instructions"));
|
|
3398
3458
|
if (customInstructions === undefined) {
|
|
3399
3459
|
// User cancelled - loop back to summary selector
|
|
3400
3460
|
continue;
|
|
@@ -3429,12 +3489,12 @@ export class InteractiveMode {
|
|
|
3429
3489
|
});
|
|
3430
3490
|
if (result.aborted) {
|
|
3431
3491
|
// Summarization aborted - re-show tree selector with same selection
|
|
3432
|
-
this.showStatus("Branch summarization cancelled");
|
|
3492
|
+
this.showStatus(t("Branch summarization cancelled"));
|
|
3433
3493
|
this.showTreeSelector(entryId);
|
|
3434
3494
|
return;
|
|
3435
3495
|
}
|
|
3436
3496
|
if (result.cancelled) {
|
|
3437
|
-
this.showStatus("Navigation cancelled");
|
|
3497
|
+
this.showStatus(t("Navigation cancelled"));
|
|
3438
3498
|
return;
|
|
3439
3499
|
}
|
|
3440
3500
|
// Update UI
|
|
@@ -3443,7 +3503,7 @@ export class InteractiveMode {
|
|
|
3443
3503
|
if (result.editorText && !this.editor.getText().trim()) {
|
|
3444
3504
|
this.editor.setText(result.editorText);
|
|
3445
3505
|
}
|
|
3446
|
-
this.showStatus("Navigated to selected point");
|
|
3506
|
+
this.showStatus(t("Navigated to selected point"));
|
|
3447
3507
|
void this.flushCompactionQueue({ willRetry: false });
|
|
3448
3508
|
}
|
|
3449
3509
|
catch (error) {
|
|
@@ -3464,12 +3524,12 @@ export class InteractiveMode {
|
|
|
3464
3524
|
}, initialSelectedId, initialFilterMode);
|
|
3465
3525
|
selector.onCopy = async (text) => {
|
|
3466
3526
|
if (!text) {
|
|
3467
|
-
this.showError("Selected entry has no text to copy");
|
|
3527
|
+
this.showError(t("Selected entry has no text to copy"));
|
|
3468
3528
|
return;
|
|
3469
3529
|
}
|
|
3470
3530
|
try {
|
|
3471
3531
|
await copyToClipboard(text);
|
|
3472
|
-
this.showStatus("Copied selected message to clipboard");
|
|
3532
|
+
this.showStatus(t("Copied selected message to clipboard"));
|
|
3473
3533
|
}
|
|
3474
3534
|
catch (error) {
|
|
3475
3535
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -3517,7 +3577,7 @@ export class InteractiveMode {
|
|
|
3517
3577
|
if (result.cancelled) {
|
|
3518
3578
|
return result;
|
|
3519
3579
|
}
|
|
3520
|
-
this.showStatus("Resumed session");
|
|
3580
|
+
this.showStatus(t("Resumed session"));
|
|
3521
3581
|
this.detectCrossSuiteResume();
|
|
3522
3582
|
return result;
|
|
3523
3583
|
}
|
|
@@ -3525,7 +3585,7 @@ export class InteractiveMode {
|
|
|
3525
3585
|
if (error instanceof MissingSessionCwdError) {
|
|
3526
3586
|
const selectedCwd = await this.promptForMissingSessionCwd(error);
|
|
3527
3587
|
if (!selectedCwd) {
|
|
3528
|
-
this.showStatus("Resume cancelled");
|
|
3588
|
+
this.showStatus(t("Resume cancelled"));
|
|
3529
3589
|
return { cancelled: true };
|
|
3530
3590
|
}
|
|
3531
3591
|
const result = await this.runtimeFacade.switchSession(sessionPath, {
|
|
@@ -3535,11 +3595,11 @@ export class InteractiveMode {
|
|
|
3535
3595
|
if (result.cancelled) {
|
|
3536
3596
|
return result;
|
|
3537
3597
|
}
|
|
3538
|
-
this.showStatus("Resumed session in current cwd");
|
|
3598
|
+
this.showStatus(t("Resumed session in current cwd"));
|
|
3539
3599
|
this.detectCrossSuiteResume();
|
|
3540
3600
|
return result;
|
|
3541
3601
|
}
|
|
3542
|
-
return this.handleFatalRuntimeError("Failed to resume session", error);
|
|
3602
|
+
return this.handleFatalRuntimeError(t("Failed to resume session"), error);
|
|
3543
3603
|
}
|
|
3544
3604
|
}
|
|
3545
3605
|
/**
|
|
@@ -3563,7 +3623,10 @@ export class InteractiveMode {
|
|
|
3563
3623
|
});
|
|
3564
3624
|
if (currentSuiteId === originalSuiteId)
|
|
3565
3625
|
return;
|
|
3566
|
-
this.showStatus(
|
|
3626
|
+
this.showStatus(t('Cross-suite compatible mode: session created with "{from}", assembling with "{to}"', {
|
|
3627
|
+
from: originalSuiteId,
|
|
3628
|
+
to: currentSuiteId,
|
|
3629
|
+
}));
|
|
3567
3630
|
this.facade.recordSuiteMismatch(originalSuiteId, currentSuiteId);
|
|
3568
3631
|
}
|
|
3569
3632
|
// =========================================================================
|
|
@@ -3681,11 +3744,11 @@ export class InteractiveMode {
|
|
|
3681
3744
|
// =========================================================================
|
|
3682
3745
|
async handleReloadCommand() {
|
|
3683
3746
|
if (this.facade.isStreaming()) {
|
|
3684
|
-
this.showWarning("Wait for the current response to finish before reloading.");
|
|
3747
|
+
this.showWarning(t("Wait for the current response to finish before reloading."));
|
|
3685
3748
|
return;
|
|
3686
3749
|
}
|
|
3687
3750
|
if (this.facade.isCompacting()) {
|
|
3688
|
-
this.showWarning("Wait for compaction to finish before reloading.");
|
|
3751
|
+
this.showWarning(t("Wait for compaction to finish before reloading."));
|
|
3689
3752
|
return;
|
|
3690
3753
|
}
|
|
3691
3754
|
this.resetDialogUI();
|
|
@@ -3693,7 +3756,7 @@ export class InteractiveMode {
|
|
|
3693
3756
|
const borderColor = (s) => theme.fg("border", s);
|
|
3694
3757
|
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
3695
3758
|
reloadBox.addChild(new Spacer(1));
|
|
3696
|
-
reloadBox.addChild(new Text(theme.fg("muted", "Reloading keybindings, skills, prompts, themes, and context files..."), 1, 0));
|
|
3759
|
+
reloadBox.addChild(new Text(theme.fg("muted", t("Reloading keybindings, skills, prompts, themes, and context files...")), 1, 0));
|
|
3697
3760
|
reloadBox.addChild(new Spacer(1));
|
|
3698
3761
|
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
3699
3762
|
const previousEditor = this.editor;
|
|
@@ -3737,9 +3800,9 @@ export class InteractiveMode {
|
|
|
3737
3800
|
});
|
|
3738
3801
|
const modelsJsonError = this.facade.getModelsError();
|
|
3739
3802
|
if (modelsJsonError) {
|
|
3740
|
-
this.showError(
|
|
3803
|
+
this.showError(t("models.json error: {error}", { error: modelsJsonError }));
|
|
3741
3804
|
}
|
|
3742
|
-
this.showStatus("Reloaded keybindings, skills, prompts, themes, and context files");
|
|
3805
|
+
this.showStatus(t("Reloaded keybindings, skills, prompts, themes, and context files"));
|
|
3743
3806
|
dismissReloadBox(this.editor);
|
|
3744
3807
|
reloadBoxDismissed = true;
|
|
3745
3808
|
}
|
|
@@ -3748,7 +3811,7 @@ export class InteractiveMode {
|
|
|
3748
3811
|
if (!reloadBoxDismissed) {
|
|
3749
3812
|
dismissReloadBox(previousEditor);
|
|
3750
3813
|
}
|
|
3751
|
-
this.showError(
|
|
3814
|
+
this.showError(t("Reload failed: {error}", { error: error instanceof Error ? error.message : String(error) }));
|
|
3752
3815
|
}
|
|
3753
3816
|
}
|
|
3754
3817
|
async handleExportCommand(text) {
|
|
@@ -3756,17 +3819,19 @@ export class InteractiveMode {
|
|
|
3756
3819
|
try {
|
|
3757
3820
|
if (outputPath?.endsWith(".jsonl")) {
|
|
3758
3821
|
const filePath = this.facade.exportToJsonl(outputPath);
|
|
3759
|
-
this.showStatus(
|
|
3822
|
+
this.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
3760
3823
|
}
|
|
3761
3824
|
else {
|
|
3762
3825
|
const filePath = await this.facade.exportToHtml(outputPath, {
|
|
3763
3826
|
themeName: theme.name,
|
|
3764
3827
|
});
|
|
3765
|
-
this.showStatus(
|
|
3828
|
+
this.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
3766
3829
|
}
|
|
3767
3830
|
}
|
|
3768
3831
|
catch (error) {
|
|
3769
|
-
this.showError(
|
|
3832
|
+
this.showError(t("Failed to export session: {error}", {
|
|
3833
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
3834
|
+
}));
|
|
3770
3835
|
}
|
|
3771
3836
|
}
|
|
3772
3837
|
getPathCommandArgument(text, command) {
|
|
@@ -3797,43 +3862,43 @@ export class InteractiveMode {
|
|
|
3797
3862
|
async handleImportCommand(text) {
|
|
3798
3863
|
const inputPath = this.getPathCommandArgument(text, "/import");
|
|
3799
3864
|
if (!inputPath) {
|
|
3800
|
-
this.showError("Usage: /import <path.jsonl>");
|
|
3865
|
+
this.showError(t("Usage: /import <path.jsonl>"));
|
|
3801
3866
|
return;
|
|
3802
3867
|
}
|
|
3803
|
-
const confirmed = await this.showDialogConfirm("Import session",
|
|
3868
|
+
const confirmed = await this.showDialogConfirm(t("Import session"), t("Replace current session with {path}?", { path: inputPath }));
|
|
3804
3869
|
if (!confirmed) {
|
|
3805
|
-
this.showStatus("Import cancelled");
|
|
3870
|
+
this.showStatus(t("Import cancelled"));
|
|
3806
3871
|
return;
|
|
3807
3872
|
}
|
|
3808
3873
|
try {
|
|
3809
3874
|
this.clearStatusIndicator();
|
|
3810
3875
|
const result = await this.runtimeFacade.importFromJsonl(inputPath);
|
|
3811
3876
|
if (result.cancelled) {
|
|
3812
|
-
this.showStatus("Import cancelled");
|
|
3877
|
+
this.showStatus(t("Import cancelled"));
|
|
3813
3878
|
return;
|
|
3814
3879
|
}
|
|
3815
|
-
this.showStatus(
|
|
3880
|
+
this.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
3816
3881
|
}
|
|
3817
3882
|
catch (error) {
|
|
3818
3883
|
if (error instanceof MissingSessionCwdError) {
|
|
3819
3884
|
const selectedCwd = await this.promptForMissingSessionCwd(error);
|
|
3820
3885
|
if (!selectedCwd) {
|
|
3821
|
-
this.showStatus("Import cancelled");
|
|
3886
|
+
this.showStatus(t("Import cancelled"));
|
|
3822
3887
|
return;
|
|
3823
3888
|
}
|
|
3824
3889
|
const result = await this.runtimeFacade.importFromJsonl(inputPath, selectedCwd);
|
|
3825
3890
|
if (result.cancelled) {
|
|
3826
|
-
this.showStatus("Import cancelled");
|
|
3891
|
+
this.showStatus(t("Import cancelled"));
|
|
3827
3892
|
return;
|
|
3828
3893
|
}
|
|
3829
|
-
this.showStatus(
|
|
3894
|
+
this.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
3830
3895
|
return;
|
|
3831
3896
|
}
|
|
3832
3897
|
if (error instanceof SessionImportFileNotFoundError) {
|
|
3833
|
-
this.showError(
|
|
3898
|
+
this.showError(t("Failed to import session: {error}", { error: error.message }));
|
|
3834
3899
|
return;
|
|
3835
3900
|
}
|
|
3836
|
-
await this.handleFatalRuntimeError("Failed to import session", error);
|
|
3901
|
+
await this.handleFatalRuntimeError(t("Failed to import session"), error);
|
|
3837
3902
|
}
|
|
3838
3903
|
}
|
|
3839
3904
|
async handleCopyCommand(options = {}) {
|
|
@@ -3846,16 +3911,16 @@ export class InteractiveMode {
|
|
|
3846
3911
|
}
|
|
3847
3912
|
const text = this.facade.getLastAssistantText();
|
|
3848
3913
|
if (!text) {
|
|
3849
|
-
this.showError("No agent messages to copy yet.");
|
|
3914
|
+
this.showError(t("No agent messages to copy yet."));
|
|
3850
3915
|
return;
|
|
3851
3916
|
}
|
|
3852
3917
|
try {
|
|
3853
3918
|
await copyToClipboard(text);
|
|
3854
3919
|
if (options.flashConfirmation && this.ui instanceof TuiAltScreen) {
|
|
3855
|
-
this.ui.flash("Copied!");
|
|
3920
|
+
this.ui.flash(t("Copied!"));
|
|
3856
3921
|
}
|
|
3857
3922
|
else {
|
|
3858
|
-
this.showStatus("Copied last agent message to clipboard");
|
|
3923
|
+
this.showStatus(t("Copied last agent message to clipboard"));
|
|
3859
3924
|
}
|
|
3860
3925
|
}
|
|
3861
3926
|
catch (error) {
|
|
@@ -3868,10 +3933,10 @@ export class InteractiveMode {
|
|
|
3868
3933
|
const currentName = this.facade.getSessionName();
|
|
3869
3934
|
if (currentName) {
|
|
3870
3935
|
this.chatContainer.addChild(new Spacer(1));
|
|
3871
|
-
this.chatContainer.addChild(new Text(theme.fg("dim",
|
|
3936
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", t("Session name: {name}", { name: currentName })), 1, 0));
|
|
3872
3937
|
}
|
|
3873
3938
|
else {
|
|
3874
|
-
this.showWarning("Usage: /name <name>");
|
|
3939
|
+
this.showWarning(t("Usage: /name <name>"));
|
|
3875
3940
|
}
|
|
3876
3941
|
this.ui.requestRender();
|
|
3877
3942
|
return;
|
|
@@ -3879,10 +3944,13 @@ export class InteractiveMode {
|
|
|
3879
3944
|
this.facade.setSessionName(name);
|
|
3880
3945
|
const sessionName = this.facade.getSessionName();
|
|
3881
3946
|
if (sessionName !== name) {
|
|
3882
|
-
this.showWarning(
|
|
3947
|
+
this.showWarning(t("Session name was normalized from {from} to {to}", {
|
|
3948
|
+
from: JSON.stringify(name),
|
|
3949
|
+
to: JSON.stringify(sessionName),
|
|
3950
|
+
}));
|
|
3883
3951
|
}
|
|
3884
3952
|
this.chatContainer.addChild(new Spacer(1));
|
|
3885
|
-
this.chatContainer.addChild(new Text(theme.fg("dim",
|
|
3953
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", t("Session name set: {name}", { name: sessionName ?? name })), 1, 0));
|
|
3886
3954
|
this.ui.requestRender();
|
|
3887
3955
|
}
|
|
3888
3956
|
/**
|
|
@@ -3892,11 +3960,13 @@ export class InteractiveMode {
|
|
|
3892
3960
|
handleStopAgentsCommand() {
|
|
3893
3961
|
const active = this.facade.getActiveAgentTaskCount();
|
|
3894
3962
|
if (active === 0) {
|
|
3895
|
-
this.showStatus("No background subagents running");
|
|
3963
|
+
this.showStatus(t("No background subagents running"));
|
|
3896
3964
|
return;
|
|
3897
3965
|
}
|
|
3898
3966
|
this.facade.abortAgentTasks();
|
|
3899
|
-
this.showStatus(
|
|
3967
|
+
this.showStatus(active === 1
|
|
3968
|
+
? t("Terminated {count} background subagent", { count: active })
|
|
3969
|
+
: t("Terminated {count} background subagents", { count: active }));
|
|
3900
3970
|
}
|
|
3901
3971
|
handleSessionCommand() {
|
|
3902
3972
|
const stats = this.facade.getSessionStats();
|
|
@@ -3907,71 +3977,81 @@ export class InteractiveMode {
|
|
|
3907
3977
|
// resolves to a concrete responseModel). Usage without model attribution is
|
|
3908
3978
|
// grouped separately so the breakdown reconciles with the session total.
|
|
3909
3979
|
const usageBreakdown = getUsageCostBreakdown(entries);
|
|
3910
|
-
let info = `${theme.bold("Session Info")}\n\n`;
|
|
3980
|
+
let info = `${theme.bold(t("Session Info"))}\n\n`;
|
|
3911
3981
|
if (sessionName) {
|
|
3912
|
-
info += `${theme.fg("dim", "Name:")} ${sessionName}\n`;
|
|
3913
|
-
}
|
|
3914
|
-
info += `${theme.fg("dim", "File:")} ${stats.sessionFile ?? "In-memory"}\n`;
|
|
3915
|
-
info += `${theme.fg("dim", "ID:")} ${stats.sessionId}\n\n`;
|
|
3916
|
-
info += `${theme.bold("Messages")}\n`;
|
|
3917
|
-
info += `${theme.fg("dim", "Total:")} ${stats.totalMessages}\n`;
|
|
3918
|
-
info += `${theme.fg("dim", "User:")} ${stats.userMessages}\n`;
|
|
3919
|
-
info += `${theme.fg("dim", "Assistant:")} ${stats.assistantMessages}\n`;
|
|
3920
|
-
info += `${theme.fg("dim", "Tools:")} ${
|
|
3921
|
-
|
|
3982
|
+
info += `${theme.fg("dim", t("Name:"))} ${sessionName}\n`;
|
|
3983
|
+
}
|
|
3984
|
+
info += `${theme.fg("dim", t("File:"))} ${stats.sessionFile ?? t("In-memory")}\n`;
|
|
3985
|
+
info += `${theme.fg("dim", t("ID:"))} ${stats.sessionId}\n\n`;
|
|
3986
|
+
info += `${theme.bold(t("Messages"))}\n`;
|
|
3987
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.totalMessages}\n`;
|
|
3988
|
+
info += `${theme.fg("dim", t("User:"))} ${stats.userMessages}\n`;
|
|
3989
|
+
info += `${theme.fg("dim", t("Assistant:"))} ${stats.assistantMessages}\n`;
|
|
3990
|
+
info += `${theme.fg("dim", t("Tools:"))} ${t("{calls} calls, {results} results", {
|
|
3991
|
+
calls: stats.toolCalls,
|
|
3992
|
+
results: stats.toolResults,
|
|
3993
|
+
})}\n\n`;
|
|
3994
|
+
info += `${theme.bold(t("Tokens"))}\n`;
|
|
3922
3995
|
// "Input" is the full prompt volume. With cache activity, split it into
|
|
3923
3996
|
// cached (served from cache) vs uncached (everything else) - the only
|
|
3924
3997
|
// provider-independent split. Cache writes, where reported, are a detail
|
|
3925
3998
|
// of the uncached portion.
|
|
3926
3999
|
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
3927
4000
|
const promptTokens = input + cacheRead + cacheWrite;
|
|
3928
|
-
info += `${theme.fg("dim", "Input:")} ${promptTokens.toLocaleString()}\n`;
|
|
4001
|
+
info += `${theme.fg("dim", t("Input:"))} ${promptTokens.toLocaleString()}\n`;
|
|
3929
4002
|
if (promptTokens > 0 && (cacheRead > 0 || cacheWrite > 0)) {
|
|
3930
4003
|
const hitRate = theme.fg("dim", `(${((cacheRead / promptTokens) * 100).toFixed(1)}%)`);
|
|
3931
|
-
info += ` ${theme.fg("dim", "Cached:")} ${cacheRead.toLocaleString()} ${hitRate}\n`;
|
|
3932
|
-
const written = cacheWrite > 0
|
|
3933
|
-
|
|
4004
|
+
info += ` ${theme.fg("dim", t("Cached:"))} ${cacheRead.toLocaleString()} ${hitRate}\n`;
|
|
4005
|
+
const written = cacheWrite > 0
|
|
4006
|
+
? ` ${theme.fg("dim", t("({count} written to cache)", { count: cacheWrite.toLocaleString() }))}`
|
|
4007
|
+
: "";
|
|
4008
|
+
info += ` ${theme.fg("dim", t("Uncached:"))} ${(input + cacheWrite).toLocaleString()}${written}\n`;
|
|
3934
4009
|
}
|
|
3935
|
-
info += `${theme.fg("dim", "Output:")} ${stats.tokens.output.toLocaleString()}\n`;
|
|
3936
|
-
info += `${theme.fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
|
|
4010
|
+
info += `${theme.fg("dim", t("Output:"))} ${stats.tokens.output.toLocaleString()}\n`;
|
|
4011
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.tokens.total.toLocaleString()}\n`;
|
|
3937
4012
|
// 双维度统计(用户裁决 2026-09-25):总计之外按供应商/模型分桶——缓存读/写、
|
|
3938
4013
|
// 命中率、费用逐桶可见。此前该拆分门控在 cost>0 且多桶才渲染,单价为 0 的
|
|
3939
4014
|
// 自定义供应商(如自建代理)永远看不到。
|
|
3940
4015
|
if (usageBreakdown.length > 0) {
|
|
3941
|
-
info += `\n${theme.bold("By Provider/Model")}\n`;
|
|
4016
|
+
info += `\n${theme.bold(t("By Provider/Model"))}\n`;
|
|
3942
4017
|
for (const entry of usageBreakdown) {
|
|
3943
4018
|
const bucket = entry.totals;
|
|
3944
4019
|
const promptBucket = bucket.input + bucket.cacheRead + bucket.cacheWrite;
|
|
3945
4020
|
let line = ` ${theme.bold(entry.key)}`;
|
|
3946
4021
|
if (promptBucket > 0) {
|
|
3947
|
-
line += `\n ${theme.fg("dim", "Input:")} ${promptBucket.toLocaleString()}`;
|
|
4022
|
+
line += `\n ${theme.fg("dim", t("Input:"))} ${promptBucket.toLocaleString()}`;
|
|
3948
4023
|
if (bucket.cacheRead > 0 || bucket.cacheWrite > 0) {
|
|
3949
4024
|
const rate = promptBucket > 0 ? ((bucket.cacheRead / promptBucket) * 100).toFixed(1) : "0.0";
|
|
3950
|
-
line += ` ${theme.fg("dim",
|
|
4025
|
+
line += ` ${theme.fg("dim", t("(cache {rate}%, W {written})", { rate, written: bucket.cacheWrite.toLocaleString() }))}`;
|
|
3951
4026
|
}
|
|
3952
4027
|
}
|
|
3953
4028
|
if (bucket.output > 0)
|
|
3954
|
-
line += `\n ${theme.fg("dim", "Output:")} ${bucket.output.toLocaleString()}`;
|
|
4029
|
+
line += `\n ${theme.fg("dim", t("Output:"))} ${bucket.output.toLocaleString()}`;
|
|
3955
4030
|
if (entry.cost > 0)
|
|
3956
4031
|
line += ` ${theme.fg("dim", `$${entry.cost.toFixed(3)}`)}`;
|
|
3957
4032
|
info += `${line}\n`;
|
|
3958
4033
|
}
|
|
3959
4034
|
}
|
|
3960
4035
|
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
3961
|
-
info += `\n${theme.bold("Cost")}\n`;
|
|
3962
|
-
info += `${theme.fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
|
|
4036
|
+
info += `\n${theme.bold(t("Cost"))}\n`;
|
|
4037
|
+
info += `${theme.fg("dim", t("Total:"))} $${stats.cost.toFixed(3)}`;
|
|
3963
4038
|
if (usageBreakdown.length > 1) {
|
|
3964
4039
|
for (const entry of usageBreakdown) {
|
|
3965
|
-
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim",
|
|
4040
|
+
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim", t("({tokens} tokens)", { tokens: formatTokens(entry.tokens) }))}`;
|
|
3966
4041
|
}
|
|
3967
4042
|
}
|
|
3968
4043
|
if (cacheWaste.missedTokens > 0) {
|
|
3969
|
-
const missLabel = cacheWaste.missCount === 1
|
|
3970
|
-
|
|
4044
|
+
const missLabel = cacheWaste.missCount === 1
|
|
4045
|
+
? t("{count} miss", { count: cacheWaste.missCount })
|
|
4046
|
+
: t("{count} misses", { count: cacheWaste.missCount });
|
|
4047
|
+
const detail = t("{tokens} tokens, {misses}", {
|
|
4048
|
+
tokens: cacheWaste.missedTokens.toLocaleString(),
|
|
4049
|
+
misses: missLabel,
|
|
4050
|
+
});
|
|
3971
4051
|
info +=
|
|
3972
4052
|
cacheWaste.missedCost >= 0.0001
|
|
3973
|
-
? `\n${theme.fg("dim", "Cache Re-billed:")} $${cacheWaste.missedCost.toFixed(3)} ${theme.fg("dim", `(${detail})`)}`
|
|
3974
|
-
: `\n${theme.fg("dim", "Cache Re-billed:")} ${detail}`;
|
|
4053
|
+
? `\n${theme.fg("dim", t("Cache Re-billed:"))} $${cacheWaste.missedCost.toFixed(3)} ${theme.fg("dim", `(${detail})`)}`
|
|
4054
|
+
: `\n${theme.fg("dim", t("Cache Re-billed:"))} ${detail}`;
|
|
3975
4055
|
}
|
|
3976
4056
|
}
|
|
3977
4057
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -3981,14 +4061,14 @@ export class InteractiveMode {
|
|
|
3981
4061
|
handleMetricsCommand(turnsArg) {
|
|
3982
4062
|
const provider = this.options.getMetrics;
|
|
3983
4063
|
if (!provider) {
|
|
3984
|
-
this.showWarning("Metrics are not available: the observability plugin is not mounted in this session");
|
|
4064
|
+
this.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
3985
4065
|
return;
|
|
3986
4066
|
}
|
|
3987
4067
|
let windowTurns;
|
|
3988
4068
|
if (turnsArg !== undefined) {
|
|
3989
4069
|
const parsed = Number.parseInt(turnsArg, 10);
|
|
3990
4070
|
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
3991
|
-
this.showWarning(
|
|
4071
|
+
this.showWarning(t("Invalid turns: {turns}. Usage: /metrics [turns]", { turns: turnsArg }));
|
|
3992
4072
|
return;
|
|
3993
4073
|
}
|
|
3994
4074
|
windowTurns = parsed;
|
|
@@ -3997,7 +4077,7 @@ export class InteractiveMode {
|
|
|
3997
4077
|
try {
|
|
3998
4078
|
const result = provider({ windowTurns });
|
|
3999
4079
|
if (result === undefined) {
|
|
4000
|
-
this.showWarning("Metrics are not available: the observability plugin is not mounted in this session");
|
|
4080
|
+
this.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
4001
4081
|
return;
|
|
4002
4082
|
}
|
|
4003
4083
|
snapshot = result;
|
|
@@ -4018,10 +4098,10 @@ export class InteractiveMode {
|
|
|
4018
4098
|
.reverse()
|
|
4019
4099
|
.map((e) => normalizeChangelogLinks(e.content, e))
|
|
4020
4100
|
.join("\n\n")
|
|
4021
|
-
: "No changelog entries found.";
|
|
4101
|
+
: t("No changelog entries found.");
|
|
4022
4102
|
this.chatContainer.addChild(new Spacer(1));
|
|
4023
4103
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4024
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
4104
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("What's New"))), 1, 0));
|
|
4025
4105
|
this.chatContainer.addChild(new Spacer(1));
|
|
4026
4106
|
this.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4027
4107
|
this.chatContainer.addChild(new DynamicBorder());
|
|
@@ -4043,7 +4123,7 @@ export class InteractiveMode {
|
|
|
4043
4123
|
const section = (title, rows) => {
|
|
4044
4124
|
if (rows.length === 0)
|
|
4045
4125
|
return "";
|
|
4046
|
-
let table = `\n**${title}**\n| Command | Description |\n|---------|-------------|\n`;
|
|
4126
|
+
let table = `\n**${title}**\n| ${t("Command")} | ${t("Description")} |\n|---------|-------------|\n`;
|
|
4047
4127
|
for (const row of rows) {
|
|
4048
4128
|
const command = row.hint ? `\`/${row.name} ${row.hint}\`` : `\`/${row.name}\``;
|
|
4049
4129
|
table += `| ${command} | ${row.description ?? ""} |\n`;
|
|
@@ -4064,13 +4144,13 @@ export class InteractiveMode {
|
|
|
4064
4144
|
name: `skill:${skill.name}`,
|
|
4065
4145
|
description: skill.description,
|
|
4066
4146
|
}));
|
|
4067
|
-
const help = section("Built-in commands", builtinRows) +
|
|
4068
|
-
section("Prompt templates", promptRows) +
|
|
4069
|
-
section("Skills", skillRows) +
|
|
4070
|
-
"
|
|
4147
|
+
const help = section(t("Built-in commands"), builtinRows) +
|
|
4148
|
+
section(t("Prompt templates"), promptRows) +
|
|
4149
|
+
section(t("Skills"), skillRows) +
|
|
4150
|
+
`\n${t("Type `/` for autocomplete. Use `/hotkeys` for keyboard shortcuts.")}`;
|
|
4071
4151
|
this.chatContainer.addChild(new Spacer(1));
|
|
4072
4152
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4073
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Available Commands")), 1, 0));
|
|
4153
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Available Commands"))), 1, 0));
|
|
4074
4154
|
this.chatContainer.addChild(new Markdown(help.trim(), 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4075
4155
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4076
4156
|
this.ui.requestRender();
|
|
@@ -4118,68 +4198,70 @@ export class InteractiveMode {
|
|
|
4118
4198
|
const pasteImage = this.getAppKeyDisplay("app.clipboard.pasteImage");
|
|
4119
4199
|
// Iron law (2026-10-01): these shipped defaults were cleared in favor of
|
|
4120
4200
|
// the /model command; the row only appears when a user re-configures a key.
|
|
4121
|
-
const selectModelRow = selectModel ? `| \`${selectModel}\` | Open model selector |\n` : "";
|
|
4201
|
+
const selectModelRow = selectModel ? `| \`${selectModel}\` | ${t("Open model selector")} |\n` : "";
|
|
4122
4202
|
// Iron law (2026-10-02 复审): ctrl+g/ctrl+x stay bound only for the
|
|
4123
4203
|
// components without a command channel — the main editor ignores them
|
|
4124
4204
|
// (/editor and /copy are its single entries), so the rows say where
|
|
4125
4205
|
// each key actually acts.
|
|
4126
|
-
const copyMessageRow = copyMessage ? `| \`${copyMessage}\` | Copy selection in /tree |\n` : "";
|
|
4206
|
+
const copyMessageRow = copyMessage ? `| \`${copyMessage}\` | ${t("Copy selection in /tree")} |\n` : "";
|
|
4127
4207
|
const externalEditorRow = externalEditor
|
|
4128
|
-
? `| \`${externalEditor}\` | External editor (inside dialog inputs) |\n`
|
|
4208
|
+
? `| \`${externalEditor}\` | ${t("External editor (inside dialog inputs)")} |\n`
|
|
4129
4209
|
: "";
|
|
4130
4210
|
// Iron law (2026-10-01): the message queue is the /queue and /dequeue
|
|
4131
4211
|
// commands' feature; rows only appear when a user re-configures a key.
|
|
4132
|
-
const followUpRow = followUp ? `| \`${followUp}\` | Queue follow-up message |\n` : "";
|
|
4133
|
-
const dequeueRow = dequeue ? `| \`${dequeue}\` | Restore queued messages |\n` : "";
|
|
4134
|
-
const cycleThinkingRow = cycleThinkingLevel
|
|
4212
|
+
const followUpRow = followUp ? `| \`${followUp}\` | ${t("Queue follow-up message")} |\n` : "";
|
|
4213
|
+
const dequeueRow = dequeue ? `| \`${dequeue}\` | ${t("Restore queued messages")} |\n` : "";
|
|
4214
|
+
const cycleThinkingRow = cycleThinkingLevel
|
|
4215
|
+
? `| \`${cycleThinkingLevel}\` | ${t("Cycle thinking level")} |\n`
|
|
4216
|
+
: "";
|
|
4135
4217
|
const cycleModelsRow = cycleModelForward || cycleModelBackward
|
|
4136
|
-
? `| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | Cycle models |\n`
|
|
4218
|
+
? `| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | ${t("Cycle models")} |\n`
|
|
4137
4219
|
: "";
|
|
4138
4220
|
// Suspend has no default key on native Windows; hide the row there.
|
|
4139
|
-
const suspendRow = suspend ? `| \`${suspend}\` | Suspend to background |\n` : "";
|
|
4221
|
+
const suspendRow = suspend ? `| \`${suspend}\` | ${t("Suspend to background")} |\n` : "";
|
|
4140
4222
|
const hotkeys = `
|
|
4141
|
-
|
|
4142
|
-
| Key | Action |
|
|
4223
|
+
**${t("Navigation")}**
|
|
4224
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4143
4225
|
|-----|--------|
|
|
4144
|
-
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | Move cursor / browse history |
|
|
4145
|
-
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | Move by word |
|
|
4146
|
-
| \`${cursorLineStart}\` | Start of line |
|
|
4147
|
-
| \`${cursorLineEnd}\` | End of line |
|
|
4148
|
-
| \`${jumpForward}\` | Jump forward to character |
|
|
4149
|
-
| \`${jumpBackward}\` | Jump backward to character |
|
|
4150
|
-
| \`${pageUp}\` / \`${pageDown}\` | Scroll by page |
|
|
4226
|
+
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | ${t("Move cursor / browse history")} |
|
|
4227
|
+
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | ${t("Move by word")} |
|
|
4228
|
+
| \`${cursorLineStart}\` | ${t("Start of line")} |
|
|
4229
|
+
| \`${cursorLineEnd}\` | ${t("End of line")} |
|
|
4230
|
+
| \`${jumpForward}\` | ${t("Jump forward to character")} |
|
|
4231
|
+
| \`${jumpBackward}\` | ${t("Jump backward to character")} |
|
|
4232
|
+
| \`${pageUp}\` / \`${pageDown}\` | ${t("Scroll by page")} |
|
|
4151
4233
|
|
|
4152
|
-
|
|
4153
|
-
| Key | Action |
|
|
4234
|
+
**${t("Editing")}**
|
|
4235
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4154
4236
|
|-----|--------|
|
|
4155
|
-
| \`${submit}\` | Send message |
|
|
4156
|
-
| \`${newLine}\` |
|
|
4157
|
-
| \`${deleteWordBackward}\` | Delete word backwards |
|
|
4158
|
-
| \`${deleteWordForward}\` | Delete word forwards |
|
|
4159
|
-
| \`${deleteToLineStart}\` | Delete to start of line |
|
|
4160
|
-
| \`${deleteToLineEnd}\` | Delete to end of line |
|
|
4161
|
-
| \`${yank}\` | Paste the most-recently-deleted text |
|
|
4162
|
-
| \`${yankPop}\` | Cycle through the deleted text after pasting |
|
|
4163
|
-
| \`${undo}\` | Undo |
|
|
4237
|
+
| \`${submit}\` | ${t("Send message")} |
|
|
4238
|
+
| \`${newLine}\` | ${process.platform === "win32" ? t("New line (Ctrl+Enter on Windows Terminal)") : t("New line")} |
|
|
4239
|
+
| \`${deleteWordBackward}\` | ${t("Delete word backwards")} |
|
|
4240
|
+
| \`${deleteWordForward}\` | ${t("Delete word forwards")} |
|
|
4241
|
+
| \`${deleteToLineStart}\` | ${t("Delete to start of line")} |
|
|
4242
|
+
| \`${deleteToLineEnd}\` | ${t("Delete to end of line")} |
|
|
4243
|
+
| \`${yank}\` | ${t("Paste the most-recently-deleted text")} |
|
|
4244
|
+
| \`${yankPop}\` | ${t("Cycle through the deleted text after pasting")} |
|
|
4245
|
+
| \`${undo}\` | ${t("Undo")} |
|
|
4164
4246
|
|
|
4165
|
-
|
|
4166
|
-
| Key | Action |
|
|
4247
|
+
**${t("Other")}**
|
|
4248
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4167
4249
|
|-----|--------|
|
|
4168
|
-
| \`${tab}\` | Path completion / accept autocomplete |
|
|
4169
|
-
| \`${interrupt}\` | Cancel autocomplete / abort streaming |
|
|
4170
|
-
| \`${clear}\` | Clear editor (first) / exit (second) |
|
|
4171
|
-
| \`${exit}\` | Exit (when editor is empty) |
|
|
4172
|
-
${suspendRow}${cycleThinkingRow}${cycleModelsRow}${selectModelRow}| \`${expandTools}\` | Toggle tool output expansion |
|
|
4173
|
-
| \`${toggleThinking}\` | Toggle thinking block visibility |
|
|
4250
|
+
| \`${tab}\` | ${t("Path completion / accept autocomplete")} |
|
|
4251
|
+
| \`${interrupt}\` | ${t("Cancel autocomplete / abort streaming")} |
|
|
4252
|
+
| \`${clear}\` | ${t("Clear editor (first) / exit (second)")} |
|
|
4253
|
+
| \`${exit}\` | ${t("Exit (when editor is empty)")} |
|
|
4254
|
+
${suspendRow}${cycleThinkingRow}${cycleModelsRow}${selectModelRow}| \`${expandTools}\` | ${t("Toggle tool output expansion")} |
|
|
4255
|
+
| \`${toggleThinking}\` | ${t("Toggle thinking block visibility")} |
|
|
4174
4256
|
${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
4175
|
-
| \`${pasteImage}\` | Paste image or text from clipboard |
|
|
4176
|
-
| \`/\` | Slash commands |
|
|
4177
|
-
| \`!\` | Run bash command |
|
|
4178
|
-
| \`!!\` | Run bash command (excluded from context) |
|
|
4257
|
+
| \`${pasteImage}\` | ${t("Paste image or text from clipboard")} |
|
|
4258
|
+
| \`/\` | ${t("Slash commands")} |
|
|
4259
|
+
| \`!\` | ${t("Run bash command")} |
|
|
4260
|
+
| \`!!\` | ${t("Run bash command (excluded from context)")} |
|
|
4179
4261
|
`;
|
|
4180
4262
|
this.chatContainer.addChild(new Spacer(1));
|
|
4181
4263
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4182
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Keyboard Shortcuts")), 1, 0));
|
|
4264
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Keyboard Shortcuts"))), 1, 0));
|
|
4183
4265
|
this.chatContainer.addChild(new Spacer(1));
|
|
4184
4266
|
this.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4185
4267
|
this.chatContainer.addChild(new DynamicBorder());
|
|
@@ -4193,7 +4275,7 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4193
4275
|
return;
|
|
4194
4276
|
}
|
|
4195
4277
|
this.chatContainer.addChild(new Spacer(1));
|
|
4196
|
-
this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ New session started")}`, 1, 1));
|
|
4278
|
+
this.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ New session started"))}`, 1, 1));
|
|
4197
4279
|
this.ui.requestRender();
|
|
4198
4280
|
}
|
|
4199
4281
|
catch (error) {
|
|
@@ -4206,18 +4288,18 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4206
4288
|
const allLines = this.ui.render(width);
|
|
4207
4289
|
const debugLogPath = getDebugLogPath();
|
|
4208
4290
|
const debugData = [
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4291
|
+
t("Debug output at {date}", { date: new Date().toISOString() }),
|
|
4292
|
+
t("Terminal: {columns}x{rows}", { columns: width, rows: height }),
|
|
4293
|
+
t("Total lines: {count}", { count: allLines.length }),
|
|
4212
4294
|
"",
|
|
4213
|
-
"=== All rendered lines with visible widths ===",
|
|
4295
|
+
t("=== All rendered lines with visible widths ==="),
|
|
4214
4296
|
...allLines.map((line, idx) => {
|
|
4215
4297
|
const vw = visibleWidth(line);
|
|
4216
4298
|
const escaped = JSON.stringify(line);
|
|
4217
4299
|
return `[${idx}] (w=${vw}) ${escaped}`;
|
|
4218
4300
|
}),
|
|
4219
4301
|
"",
|
|
4220
|
-
"=== Agent messages (JSONL) ===",
|
|
4302
|
+
t("=== Agent messages (JSONL) ==="),
|
|
4221
4303
|
...this.facade
|
|
4222
4304
|
.getSessionAPI()
|
|
4223
4305
|
.getMessages()
|
|
@@ -4227,7 +4309,7 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4227
4309
|
fs.mkdirSync(path.dirname(debugLogPath), { recursive: true });
|
|
4228
4310
|
fs.writeFileSync(debugLogPath, debugData);
|
|
4229
4311
|
this.chatContainer.addChild(new Spacer(1));
|
|
4230
|
-
this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ Debug log written")}\n${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
4312
|
+
this.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ Debug log written"))}\n${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
4231
4313
|
this.ui.requestRender();
|
|
4232
4314
|
}
|
|
4233
4315
|
handleArminSaysHi() {
|
|
@@ -4277,7 +4359,9 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4277
4359
|
if (this.bashComponent) {
|
|
4278
4360
|
this.bashComponent.setComplete(undefined, false);
|
|
4279
4361
|
}
|
|
4280
|
-
this.showError(
|
|
4362
|
+
this.showError(t("Bash command failed: {error}", {
|
|
4363
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
4364
|
+
}));
|
|
4281
4365
|
}
|
|
4282
4366
|
this.bashComponent = undefined;
|
|
4283
4367
|
this.ui.requestRender();
|