@ai-agent-forge/agent-forge 0.86.7 → 0.88.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 +45 -0
- package/README.md +10 -11
- 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 +430 -413
- package/dist/bundle/chunks/{chunk-A7GUOX2H.js → chunk-6ZKDNZHA.js} +5 -1
- package/dist/bundle/chunks/chunk-HLJEVRWP.js +13 -0
- package/dist/bundle/chunks/chunk-YGHQME4V.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 +17 -4
- 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 +5 -3
- 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 +6 -10
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +35 -133
- 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-internal.d.ts +0 -6
- package/dist/core/agent-session-internal.d.ts.map +1 -1
- package/dist/core/agent-session-internal.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 -3
- 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 -22
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +147 -67
- 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-compaction-policy.d.ts.map +1 -1
- package/dist/core/extensions/bootstrap-compaction-policy.js +0 -34
- package/dist/core/extensions/bootstrap-compaction-policy.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 +4 -3
- 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/extensions/provider-failover.d.ts +7 -3
- package/dist/core/extensions/provider-failover.d.ts.map +1 -1
- package/dist/core/extensions/provider-failover.js +9 -8
- package/dist/core/extensions/provider-failover.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +6 -6
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +2 -3
- 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 +229 -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 +267 -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 +286 -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-config.d.ts +0 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +9 -1
- package/dist/core/model-config.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 +11 -7
- 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 +2 -2
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +29 -21
- 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 +27 -5
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +80 -55
- 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 +20 -20
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +47 -59
- 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 +97 -60
- 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 +0 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +8 -10
- 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 +4 -6
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +115 -120
- 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 -2
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +350 -279
- 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 +0 -8
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +3 -14
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +0 -9
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -19
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.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 +9 -2
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +44 -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/plugin-bootstrap.d.ts +9 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +5 -0
- package/dist/plugins/ecosystem/plugin-bootstrap.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/photon.d.ts +2 -2
- package/dist/utils/photon.d.ts.map +1 -1
- package/dist/utils/photon.js +2 -2
- package/dist/utils/photon.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/compaction.md +1 -3
- package/docs/docs.json +4 -0
- package/docs/index.md +1 -0
- package/docs/keybindings.md +3 -0
- package/docs/mcp.md +103 -0
- package/docs/models.md +14 -22
- package/docs/providers.md +0 -1
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +1 -26
- package/docs/sdk.md +4 -6
- package/docs/settings.md +10 -12
- package/docs/skills.md +1 -9
- package/docs/terminal-setup.md +2 -3
- package/docs/usage.md +7 -6
- 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/examples/sdk/10-settings.ts +2 -4
- package/examples/sdk/12-full-control.ts +1 -2
- package/package.json +1 -3
- package/dist/bundle/chunks/chunk-EALJ5DDX.js +0 -1452
- package/dist/core/extensions/microcompact.d.ts +0 -80
- package/dist/core/extensions/microcompact.d.ts.map +0 -1
- package/dist/core/extensions/microcompact.js +0 -134
- package/dist/core/extensions/microcompact.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -106
- package/dist/server/create-harness.js.map +0 -1
|
@@ -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;
|
|
@@ -297,8 +306,6 @@ export class InteractiveMode {
|
|
|
297
306
|
getMode: () => this.settingsManager.getMermaidRenderingMode(),
|
|
298
307
|
theme,
|
|
299
308
|
});
|
|
300
|
-
// Skill commands: command name -> skill file path
|
|
301
|
-
skillCommands = new Map();
|
|
302
309
|
// Agent subscription unsubscribe function
|
|
303
310
|
unsubscribe;
|
|
304
311
|
signalCleanupHandlers = [];
|
|
@@ -366,6 +373,7 @@ export class InteractiveMode {
|
|
|
366
373
|
// manager (D-047) and the constructor uses it before anything else.
|
|
367
374
|
this.options = { ...options };
|
|
368
375
|
this.runtimeHost = runtimeHost;
|
|
376
|
+
setI18nLanguage(this.settingsManager.getUiLanguage());
|
|
369
377
|
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
370
378
|
const tuiMode = options.tuiMode ?? this.settingsManager.getTuiMode();
|
|
371
379
|
this.options.tuiMode = tuiMode;
|
|
@@ -413,7 +421,6 @@ export class InteractiveMode {
|
|
|
413
421
|
this.editorContainer.addChild(this.editor);
|
|
414
422
|
this.footerDataProvider = new FooterDataProvider(this.facade.getCwd());
|
|
415
423
|
this.footer = new FooterComponent(this.session, this.footerDataProvider);
|
|
416
|
-
this.footer.setAutoCompactEnabled(this.facade.isAutoCompactionEnabled());
|
|
417
424
|
this.footerContainer = new Container();
|
|
418
425
|
this.footerContainer.addChild(this.footer);
|
|
419
426
|
this.failoverTicker = new ProviderFailoverTicker(() => this.footer.isProviderFailoverOpen(), () => this.ui.requestRender());
|
|
@@ -537,20 +544,19 @@ export class InteractiveMode {
|
|
|
537
544
|
description: definition.description,
|
|
538
545
|
...(definition.argumentHint && { argumentHint: definition.argumentHint }),
|
|
539
546
|
})), [builtinCommandNames, templateCommandNames, [...resourceSkillCommandNames]]);
|
|
540
|
-
//
|
|
541
|
-
|
|
547
|
+
// Skill commands register unconditionally (D-079: the enableSkillCommands
|
|
548
|
+
// switch is retired). A capability command claiming the same skill:name
|
|
549
|
+
// still wins: conflicting names are rejected by AgentSession, so neither
|
|
550
|
+
// side is offered as an executable completion.
|
|
542
551
|
const skillCommandList = [];
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
description: this.prefixAutocompleteDescription(skill.description, skill.sourceInfo),
|
|
552
|
-
});
|
|
553
|
-
}
|
|
552
|
+
for (const skill of this.facade.getSkills().skills) {
|
|
553
|
+
const commandName = `skill:${skill.name}`;
|
|
554
|
+
if (capabilityCommandNames.has(commandName))
|
|
555
|
+
continue;
|
|
556
|
+
skillCommandList.push({
|
|
557
|
+
name: commandName,
|
|
558
|
+
description: this.prefixAutocompleteDescription(skill.description, skill.sourceInfo),
|
|
559
|
+
});
|
|
554
560
|
}
|
|
555
561
|
return new CombinedAutocompleteProvider([...slashCommands, ...templateCommands, ...capabilityCommands, ...skillCommandList], this.facade.getCwd(), this.fdPath);
|
|
556
562
|
}
|
|
@@ -577,11 +583,14 @@ export class InteractiveMode {
|
|
|
577
583
|
if (this.settingsManager.getCollapseChangelog()) {
|
|
578
584
|
const versionMatch = this.changelogMarkdown.match(/##\s+\[?(\d+\.\d+\.\d+)\]?/);
|
|
579
585
|
const latestVersion = versionMatch ? versionMatch[1] : this.version;
|
|
580
|
-
const condensedText =
|
|
586
|
+
const condensedText = t("Updated to v{version}. Use {command} to view full changelog.", {
|
|
587
|
+
version: latestVersion,
|
|
588
|
+
command: theme.bold("/changelog"),
|
|
589
|
+
});
|
|
581
590
|
this.chatContainer.addChild(new Text(condensedText, 1, 0));
|
|
582
591
|
}
|
|
583
592
|
else {
|
|
584
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
593
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("What's New"))), 1, 0));
|
|
585
594
|
this.chatContainer.addChild(new Spacer(1));
|
|
586
595
|
this.chatContainer.addChild(new Markdown(this.changelogMarkdown.trim(), 1, 0, this.getMarkdownThemeWithSettings()));
|
|
587
596
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -593,7 +602,7 @@ export class InteractiveMode {
|
|
|
593
602
|
tui.addChild(component);
|
|
594
603
|
if (TuiLayouts.isViewportTUI(tui)) {
|
|
595
604
|
if (!this.fullscreenLayoutRoot)
|
|
596
|
-
throw new Error("Fullscreen layout is not initialized");
|
|
605
|
+
throw new Error(t("Fullscreen layout is not initialized"));
|
|
597
606
|
tui.setLayoutRoot(this.fullscreenLayoutRoot);
|
|
598
607
|
}
|
|
599
608
|
}
|
|
@@ -673,9 +682,11 @@ export class InteractiveMode {
|
|
|
673
682
|
.join(", ");
|
|
674
683
|
const cycleKeys = this.keybindings.getKeys("app.model.cycleForward");
|
|
675
684
|
const cycleHint = cycleKeys.length > 0
|
|
676
|
-
? theme.fg("muted", `
|
|
685
|
+
? theme.fg("muted", ` ${t("({key} to cycle)", {
|
|
686
|
+
key: formatKeyText(cycleKeys.join("/"), { capitalize: true }),
|
|
687
|
+
})}`)
|
|
677
688
|
: "";
|
|
678
|
-
console.log(theme.fg("dim",
|
|
689
|
+
console.log(theme.fg("dim", t("Model scope: {models}{hint}", { models: modelList, hint: cycleHint })));
|
|
679
690
|
}
|
|
680
691
|
// Keep one component tree and remount it when changing renderers.
|
|
681
692
|
// Widget chrome is fixed empty; no initialization render needed.
|
|
@@ -722,30 +733,32 @@ export class InteractiveMode {
|
|
|
722
733
|
// Build startup instructions using keybinding hint helpers
|
|
723
734
|
const hint = (keybinding, description) => keyHint(keybinding, description);
|
|
724
735
|
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"),
|
|
736
|
+
hint("app.interrupt", t("to interrupt")),
|
|
737
|
+
hint("app.clear", t("to clear")),
|
|
738
|
+
rawKeyHint(t("{key} twice", { key: keyText("app.clear") }), t("to exit")),
|
|
739
|
+
hint("app.exit", t("to exit (empty)")),
|
|
740
|
+
hint("app.suspend", t("to suspend")),
|
|
741
|
+
keyHint("tui.editor.deleteToLineEnd", t("to delete to end")),
|
|
742
|
+
hint("app.tools.expand", t("to expand tools")),
|
|
743
|
+
hint("app.thinking.toggle", t("to expand thinking")),
|
|
744
|
+
hint("app.editor.external", t("for external editor")),
|
|
745
|
+
rawKeyHint("/", t("for commands")),
|
|
746
|
+
rawKeyHint("!", t("to run bash")),
|
|
747
|
+
rawKeyHint("!!", t("to run bash (no context)")),
|
|
748
|
+
hint("app.clipboard.pasteImage", t("to paste image (with text fallback)")),
|
|
749
|
+
rawKeyHint("drop files", t("to attach")),
|
|
739
750
|
].join("\n");
|
|
740
751
|
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"),
|
|
752
|
+
hint("app.interrupt", t("interrupt")),
|
|
753
|
+
rawKeyHint(`${keyText("app.clear")}/${keyText("app.exit")}`, t("clear/exit")),
|
|
754
|
+
rawKeyHint("/", t("commands")),
|
|
755
|
+
rawKeyHint("!", t("bash")),
|
|
756
|
+
hint("app.tools.expand", t("more")),
|
|
746
757
|
].join(theme.fg("muted", " · "));
|
|
747
|
-
const compactOnboarding = theme.fg("dim",
|
|
748
|
-
|
|
758
|
+
const compactOnboarding = theme.fg("dim", t("Press {key} to show full startup help and loaded resources.", {
|
|
759
|
+
key: keyText("app.tools.expand"),
|
|
760
|
+
}));
|
|
761
|
+
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
762
|
this.builtInHeader = new ExpandableText(() => `${logo}\n${compactInstructions}\n${compactOnboarding}\n\n${onboarding}`, () => `${logo}\n${expandedInstructions}\n\n${onboarding}`, this.getStartupExpansionState(), 1, 0);
|
|
750
763
|
// Setup UI layout
|
|
751
764
|
this.headerContainer.addChild(new Spacer(1));
|
|
@@ -873,11 +886,11 @@ export class InteractiveMode {
|
|
|
873
886
|
}
|
|
874
887
|
}
|
|
875
888
|
if (migratedProviders && migratedProviders.length > 0) {
|
|
876
|
-
this.showWarning(
|
|
889
|
+
this.showWarning(t("Migrated credentials to auth.json: {providers}", { providers: migratedProviders.join(", ") }));
|
|
877
890
|
}
|
|
878
891
|
const modelsJsonError = this.facade.getModelsError();
|
|
879
892
|
if (modelsJsonError) {
|
|
880
|
-
this.showError(
|
|
893
|
+
this.showError(t("models.json error: {error}", { error: modelsJsonError }));
|
|
881
894
|
}
|
|
882
895
|
if (modelFallbackMessage) {
|
|
883
896
|
this.showWarning(modelFallbackMessage);
|
|
@@ -889,7 +902,7 @@ export class InteractiveMode {
|
|
|
889
902
|
await this.facade.prompt(initialMessage, { images: initialImages });
|
|
890
903
|
}
|
|
891
904
|
catch (error) {
|
|
892
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
905
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
893
906
|
this.showError(errorMessage);
|
|
894
907
|
}
|
|
895
908
|
}
|
|
@@ -899,7 +912,7 @@ export class InteractiveMode {
|
|
|
899
912
|
await this.facade.prompt(message);
|
|
900
913
|
}
|
|
901
914
|
catch (error) {
|
|
902
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
915
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
903
916
|
this.showError(errorMessage);
|
|
904
917
|
}
|
|
905
918
|
}
|
|
@@ -918,7 +931,7 @@ export class InteractiveMode {
|
|
|
918
931
|
await this.promptWithEmptyReplyRetry(userInput);
|
|
919
932
|
}
|
|
920
933
|
catch (error) {
|
|
921
|
-
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
934
|
+
const errorMessage = error instanceof Error ? error.message : t("Unknown error occurred");
|
|
922
935
|
this.showError(errorMessage);
|
|
923
936
|
}
|
|
924
937
|
}
|
|
@@ -942,7 +955,7 @@ export class InteractiveMode {
|
|
|
942
955
|
return;
|
|
943
956
|
if (contentText(lastAssistant.content).trim().length > 0)
|
|
944
957
|
return;
|
|
945
|
-
this.showStatus("Previous reply was empty, retrying...");
|
|
958
|
+
this.showStatus(t("Previous reply was empty, retrying..."));
|
|
946
959
|
await this.facade.prompt(EMPTY_REPLY_RETRY_PROMPT);
|
|
947
960
|
}
|
|
948
961
|
async checkForPackageUpdates() {
|
|
@@ -996,10 +1009,10 @@ export class InteractiveMode {
|
|
|
996
1009
|
if (extendedKeys === undefined)
|
|
997
1010
|
return undefined;
|
|
998
1011
|
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.";
|
|
1012
|
+
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
1013
|
}
|
|
1001
1014
|
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.";
|
|
1015
|
+
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
1016
|
}
|
|
1004
1017
|
return undefined;
|
|
1005
1018
|
}
|
|
@@ -1137,7 +1150,7 @@ export class InteractiveMode {
|
|
|
1137
1150
|
.map((f) => theme.fg("dim", ` ${this.formatDisplayPath(f.path)}`))
|
|
1138
1151
|
.join("\n");
|
|
1139
1152
|
const contextCompactList = formatCompactList(contextFiles.map((contextFile) => this.formatContextPath(contextFile.path)), { sort: false });
|
|
1140
|
-
addLoadedSection("Context", contextCompactList, contextList);
|
|
1153
|
+
addLoadedSection(t("Context"), contextCompactList, contextList);
|
|
1141
1154
|
}
|
|
1142
1155
|
const skills = skillsResult.skills;
|
|
1143
1156
|
if (skills.length > 0) {
|
|
@@ -1147,7 +1160,7 @@ export class InteractiveMode {
|
|
|
1147
1160
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1148
1161
|
});
|
|
1149
1162
|
const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
|
|
1150
|
-
addLoadedSection("Skills", skillCompactList, skillList);
|
|
1163
|
+
addLoadedSection(t("Skills"), skillCompactList, skillList);
|
|
1151
1164
|
}
|
|
1152
1165
|
const templates = this.facade.getPromptTemplates();
|
|
1153
1166
|
if (templates.length > 0) {
|
|
@@ -1166,7 +1179,7 @@ export class InteractiveMode {
|
|
|
1166
1179
|
},
|
|
1167
1180
|
});
|
|
1168
1181
|
const promptCompactList = formatCompactList(templates.map((template) => `/${template.name}`));
|
|
1169
|
-
addLoadedSection("Prompts", promptCompactList, templateList);
|
|
1182
|
+
addLoadedSection(t("Prompts"), promptCompactList, templateList);
|
|
1170
1183
|
}
|
|
1171
1184
|
// Show loaded themes (excluding built-in)
|
|
1172
1185
|
const loadedThemes = themesResult.themes;
|
|
@@ -1181,7 +1194,7 @@ export class InteractiveMode {
|
|
|
1181
1194
|
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
1182
1195
|
});
|
|
1183
1196
|
const themeCompactList = formatCompactList(customThemes.map((loadedTheme) => loadedTheme.name ?? this.getCompactPathLabel(loadedTheme.sourcePath, loadedTheme.sourceInfo)));
|
|
1184
|
-
addLoadedSection("Themes", themeCompactList, themeList);
|
|
1197
|
+
addLoadedSection(t("Themes"), themeCompactList, themeList);
|
|
1185
1198
|
}
|
|
1186
1199
|
}
|
|
1187
1200
|
// v8 ignore next -- showDiagnostics 为假时上方已提前返回,此处恒为真
|
|
@@ -1189,19 +1202,19 @@ export class InteractiveMode {
|
|
|
1189
1202
|
const skillDiagnostics = skillsResult.diagnostics;
|
|
1190
1203
|
if (skillDiagnostics.length > 0) {
|
|
1191
1204
|
const warningLines = this.formatDiagnostics(skillDiagnostics, sourceInfos);
|
|
1192
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
|
|
1205
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Skill conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1193
1206
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1194
1207
|
}
|
|
1195
1208
|
const promptDiagnostics = promptsResult.diagnostics;
|
|
1196
1209
|
if (promptDiagnostics.length > 0) {
|
|
1197
1210
|
const warningLines = this.formatDiagnostics(promptDiagnostics, sourceInfos);
|
|
1198
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
|
|
1211
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Prompt conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1199
1212
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1200
1213
|
}
|
|
1201
1214
|
const themeDiagnostics = themesResult.diagnostics;
|
|
1202
1215
|
if (themeDiagnostics.length > 0) {
|
|
1203
1216
|
const warningLines = this.formatDiagnostics(themeDiagnostics, sourceInfos);
|
|
1204
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
|
|
1217
|
+
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", t("[Theme conflicts]"))}\n${warningLines}`, 0, 0));
|
|
1205
1218
|
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1206
1219
|
}
|
|
1207
1220
|
}
|
|
@@ -1222,6 +1235,7 @@ export class InteractiveMode {
|
|
|
1222
1235
|
this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
|
|
1223
1236
|
}
|
|
1224
1237
|
applyRuntimeSettings() {
|
|
1238
|
+
setI18nLanguage(this.settingsManager.getUiLanguage());
|
|
1225
1239
|
setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
|
|
1226
1240
|
configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
|
|
1227
1241
|
this.applyFullscreenScrollbarSetting();
|
|
@@ -1230,7 +1244,6 @@ export class InteractiveMode {
|
|
|
1230
1244
|
this.renderer.setWheelScrollLines(this.settingsManager.getFullscreenWheelScrollLines());
|
|
1231
1245
|
}
|
|
1232
1246
|
this.footer.setSession(this.session);
|
|
1233
|
-
this.footer.setAutoCompactEnabled(this.facade.isAutoCompactionEnabled());
|
|
1234
1247
|
this.footerDataProvider.setCwd(this.facade.getCwd());
|
|
1235
1248
|
// The switched session carries its own failover snapshot history; re-check
|
|
1236
1249
|
// whether the countdown ticker is needed.
|
|
@@ -1378,7 +1391,7 @@ export class InteractiveMode {
|
|
|
1378
1391
|
this.workingVisible = true;
|
|
1379
1392
|
this.setWorkingIndicator();
|
|
1380
1393
|
if (this.activeStatusIndicator?.kind === "working") {
|
|
1381
|
-
this.activeStatusIndicator.setMessage(`${this.defaultWorkingMessage}
|
|
1394
|
+
this.activeStatusIndicator.setMessage(`${this.defaultWorkingMessage} ${t("({key} to interrupt)", { key: keyText("app.interrupt") })}`);
|
|
1382
1395
|
}
|
|
1383
1396
|
this.setHiddenThinkingLabel();
|
|
1384
1397
|
}
|
|
@@ -1480,7 +1493,14 @@ export class InteractiveMode {
|
|
|
1480
1493
|
this.restoreQueuedMessagesToEditor({ abort: true, cancelAgentTasks: false });
|
|
1481
1494
|
const activeAgents = this.facade.getActiveAgentTaskCount();
|
|
1482
1495
|
if (activeAgents > 0) {
|
|
1483
|
-
|
|
1496
|
+
// 单复数拆双 key 保 en 语法(批次⑩规则,同 handleStopAgentsCommand)。
|
|
1497
|
+
this.showStatus(activeAgents === 1
|
|
1498
|
+
? t("{count} subagent still running · /stop-agents stops all (Esc only stops the current turn)", {
|
|
1499
|
+
count: activeAgents,
|
|
1500
|
+
})
|
|
1501
|
+
: t("{count} subagents still running · /stop-agents stops all (Esc only stops the current turn)", {
|
|
1502
|
+
count: activeAgents,
|
|
1503
|
+
}));
|
|
1484
1504
|
}
|
|
1485
1505
|
}
|
|
1486
1506
|
else if (this.facade.isBashRunning()) {
|
|
@@ -1492,17 +1512,12 @@ export class InteractiveMode {
|
|
|
1492
1512
|
this.updateEditorBorderColor();
|
|
1493
1513
|
}
|
|
1494
1514
|
else if (!this.editor.getText().trim()) {
|
|
1495
|
-
// Double-escape with empty editor triggers /tree
|
|
1515
|
+
// Double-escape with empty editor triggers /tree or nothing based on setting
|
|
1496
1516
|
const action = this.settingsManager.getDoubleEscapeAction();
|
|
1497
|
-
if (action
|
|
1517
|
+
if (action === "tree") {
|
|
1498
1518
|
const now = Date.now();
|
|
1499
1519
|
if (now - this.lastEscapeTime < 500) {
|
|
1500
|
-
|
|
1501
|
-
this.showTreeSelector();
|
|
1502
|
-
}
|
|
1503
|
-
else {
|
|
1504
|
-
this.showUserMessageSelector();
|
|
1505
|
-
}
|
|
1520
|
+
this.showTreeSelector();
|
|
1506
1521
|
this.lastEscapeTime = 0;
|
|
1507
1522
|
}
|
|
1508
1523
|
else {
|
|
@@ -1598,7 +1613,7 @@ export class InteractiveMode {
|
|
|
1598
1613
|
if (!text.trim())
|
|
1599
1614
|
return;
|
|
1600
1615
|
this.pendingUserInputs.push(text);
|
|
1601
|
-
this.showStatus("Startup in progress — input queued and will run when startup completes");
|
|
1616
|
+
this.showStatus(t("Startup in progress — input queued and will run when startup completes"));
|
|
1602
1617
|
}
|
|
1603
1618
|
setupEditorSubmitHandler() {
|
|
1604
1619
|
this.defaultEditor.onSubmit = async (rawText) => {
|
|
@@ -1656,7 +1671,7 @@ export class InteractiveMode {
|
|
|
1656
1671
|
const command = isExcluded ? text.slice(2).trim() : text.slice(1).trim();
|
|
1657
1672
|
if (command) {
|
|
1658
1673
|
if (this.facade.isBashRunning()) {
|
|
1659
|
-
this.showWarning("A bash command is already running. Press Esc to cancel it first.");
|
|
1674
|
+
this.showWarning(t("A bash command is already running. Press Esc to cancel it first."));
|
|
1660
1675
|
this.editor.setText(text);
|
|
1661
1676
|
return true;
|
|
1662
1677
|
}
|
|
@@ -1813,14 +1828,16 @@ export class InteractiveMode {
|
|
|
1813
1828
|
const retryAttempt = this.facade.getRetryAttempt();
|
|
1814
1829
|
errorMessage =
|
|
1815
1830
|
retryAttempt > 0
|
|
1816
|
-
?
|
|
1817
|
-
|
|
1831
|
+
? retryAttempt === 1
|
|
1832
|
+
? t("Aborted after {count} retry attempt", { count: retryAttempt })
|
|
1833
|
+
: t("Aborted after {count} retry attempts", { count: retryAttempt })
|
|
1834
|
+
: t("Operation aborted");
|
|
1818
1835
|
this.streamingMessage.errorMessage = errorMessage;
|
|
1819
1836
|
}
|
|
1820
1837
|
this.streamingComponent.updateContent(this.streamingMessage, false);
|
|
1821
1838
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
1822
1839
|
if (!errorMessage) {
|
|
1823
|
-
errorMessage = this.streamingMessage.errorMessage || "Error";
|
|
1840
|
+
errorMessage = this.streamingMessage.errorMessage || t("Error");
|
|
1824
1841
|
}
|
|
1825
1842
|
for (const [, component] of this.pendingTools.entries()) {
|
|
1826
1843
|
component.updateResult({
|
|
@@ -1929,16 +1946,16 @@ export class InteractiveMode {
|
|
|
1929
1946
|
this.clearStatusIndicator("compaction");
|
|
1930
1947
|
if (event.aborted) {
|
|
1931
1948
|
if (event.reason === "manual") {
|
|
1932
|
-
this.showError("Compaction cancelled");
|
|
1949
|
+
this.showError(t("Compaction cancelled"));
|
|
1933
1950
|
}
|
|
1934
1951
|
else {
|
|
1935
|
-
this.showStatus("Auto-compaction cancelled");
|
|
1952
|
+
this.showStatus(t("Auto-compaction cancelled"));
|
|
1936
1953
|
}
|
|
1937
1954
|
}
|
|
1938
1955
|
else if (event.result) {
|
|
1939
1956
|
const entries = this.facade.getContextEntries();
|
|
1940
1957
|
if (entries[0]?.type !== "compaction") {
|
|
1941
|
-
throw new Error("Completed compaction is missing from the session context");
|
|
1958
|
+
throw new Error(t("Completed compaction is missing from the session context"));
|
|
1942
1959
|
}
|
|
1943
1960
|
this.chatContainer.clear();
|
|
1944
1961
|
// The latest compaction is prepended for model context; append it below at its chronological position.
|
|
@@ -1967,7 +1984,7 @@ export class InteractiveMode {
|
|
|
1967
1984
|
break;
|
|
1968
1985
|
}
|
|
1969
1986
|
case "compaction_skipped": {
|
|
1970
|
-
this.showStatus("Auto-compaction skipped: nothing to compact");
|
|
1987
|
+
this.showStatus(t("Auto-compaction skipped: nothing to compact"));
|
|
1971
1988
|
this.ui.requestRender();
|
|
1972
1989
|
break;
|
|
1973
1990
|
}
|
|
@@ -1990,7 +2007,10 @@ export class InteractiveMode {
|
|
|
1990
2007
|
this.clearStatusIndicator("retry");
|
|
1991
2008
|
// Show error only on final failure (success shows normal response)
|
|
1992
2009
|
if (!event.success) {
|
|
1993
|
-
this.showError(
|
|
2010
|
+
this.showError(t("Retry failed after {count} attempts: {error}", {
|
|
2011
|
+
count: event.attempt,
|
|
2012
|
+
error: event.finalError || t("Unknown error"),
|
|
2013
|
+
}));
|
|
1994
2014
|
}
|
|
1995
2015
|
this.ui.requestRender();
|
|
1996
2016
|
break;
|
|
@@ -2034,7 +2054,7 @@ export class InteractiveMode {
|
|
|
2034
2054
|
this.chatContainer.addChild(new Spacer(1));
|
|
2035
2055
|
this.managedToolStatusStarted = true;
|
|
2036
2056
|
}
|
|
2037
|
-
const message = status.type === "warning" ?
|
|
2057
|
+
const message = status.type === "warning" ? t("Warning: {message}", { message: status.message }) : status.message;
|
|
2038
2058
|
const color = status.type === "warning" ? "warning" : "dim";
|
|
2039
2059
|
this.chatContainer.addChild(new Text(theme.fg(color, message), 1, 0));
|
|
2040
2060
|
this.lastStatusSpacer = undefined;
|
|
@@ -2183,11 +2203,13 @@ export class InteractiveMode {
|
|
|
2183
2203
|
const retryAttempt = this.facade.getRetryAttempt();
|
|
2184
2204
|
errorMessage =
|
|
2185
2205
|
retryAttempt > 0
|
|
2186
|
-
?
|
|
2187
|
-
|
|
2206
|
+
? retryAttempt === 1
|
|
2207
|
+
? t("Aborted after {count} retry attempt", { count: retryAttempt })
|
|
2208
|
+
: t("Aborted after {count} retry attempts", { count: retryAttempt })
|
|
2209
|
+
: t("Operation aborted");
|
|
2188
2210
|
}
|
|
2189
2211
|
else {
|
|
2190
|
-
errorMessage = message.errorMessage || "Error";
|
|
2212
|
+
errorMessage = message.errorMessage || t("Error");
|
|
2191
2213
|
}
|
|
2192
2214
|
component.updateResult({ content: [{ type: "text", text: errorMessage }], isError: true });
|
|
2193
2215
|
}
|
|
@@ -2249,9 +2271,9 @@ export class InteractiveMode {
|
|
|
2249
2271
|
const { usage } = notice;
|
|
2250
2272
|
const tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
|
|
2251
2273
|
const cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : "";
|
|
2252
|
-
const label = notice.kind === "compaction" ? "Compaction" : "Branch summary";
|
|
2274
|
+
const label = notice.kind === "compaction" ? t("Compaction") : t("Branch summary");
|
|
2253
2275
|
this.chatContainer.addChild(new Spacer(1));
|
|
2254
|
-
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${
|
|
2276
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", `${label}: ${t("{tokens} tokens billed{cost}", { tokens: formatTokens(tokens), cost })}`), 1, 0));
|
|
2255
2277
|
}
|
|
2256
2278
|
static countDroppedThinkingBlocks(message) {
|
|
2257
2279
|
let count = 0;
|
|
@@ -2286,9 +2308,8 @@ export class InteractiveMode {
|
|
|
2286
2308
|
}
|
|
2287
2309
|
if (droppedCount <= previousDroppedCount)
|
|
2288
2310
|
return;
|
|
2289
|
-
const noun = droppedCount === 1 ? "thinking block" : "thinking blocks";
|
|
2290
2311
|
this.chatContainer.addChild(new Spacer(1));
|
|
2291
|
-
this.chatContainer.addChild(new Text(theme.fg("warning",
|
|
2312
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", t("Anthropic dropped {count} thinking blocks (details in session)", { count: droppedCount })), 1, 0));
|
|
2292
2313
|
}
|
|
2293
2314
|
/**
|
|
2294
2315
|
* Show a transcript notice when a completed assistant message paid for a
|
|
@@ -2307,13 +2328,13 @@ export class InteractiveMode {
|
|
|
2307
2328
|
if (miss.missedTokens < 20_000 && miss.missedCost < 0.1)
|
|
2308
2329
|
return;
|
|
2309
2330
|
const cost = miss.missedCost >= 0.01 ? ` (~$${miss.missedCost.toFixed(2)})` : "";
|
|
2310
|
-
const reBilled =
|
|
2311
|
-
let label = "Cache miss";
|
|
2331
|
+
const reBilled = t("{tokens} tokens re-billed{cost}", { tokens: formatTokens(miss.missedTokens), cost });
|
|
2332
|
+
let label = t("Cache miss");
|
|
2312
2333
|
if (miss.modelChanged) {
|
|
2313
|
-
label = "Cache miss after model switch";
|
|
2334
|
+
label = t("Cache miss after model switch");
|
|
2314
2335
|
}
|
|
2315
2336
|
else if (miss.idleMs >= CACHE_TTL_MS) {
|
|
2316
|
-
label =
|
|
2337
|
+
label = t("Cache miss after {minutes}m idle", { minutes: Math.round(miss.idleMs / 60_000) });
|
|
2317
2338
|
}
|
|
2318
2339
|
const text = theme.fg("warning", `${label}: ${reBilled}`);
|
|
2319
2340
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -2329,8 +2350,9 @@ export class InteractiveMode {
|
|
|
2329
2350
|
const allEntries = this.facade.getEntries();
|
|
2330
2351
|
const compactionCount = allEntries.filter((e) => e.type === "compaction").length;
|
|
2331
2352
|
if (compactionCount > 0) {
|
|
2332
|
-
|
|
2333
|
-
|
|
2353
|
+
this.showStatus(compactionCount === 1
|
|
2354
|
+
? t("Session compacted {count} time", { count: compactionCount })
|
|
2355
|
+
: t("Session compacted {count} times", { count: compactionCount }));
|
|
2334
2356
|
}
|
|
2335
2357
|
}
|
|
2336
2358
|
async getUserInput() {
|
|
@@ -2404,7 +2426,7 @@ export class InteractiveMode {
|
|
|
2404
2426
|
await this.runtimeFacade.dispose();
|
|
2405
2427
|
const resumeCommand = formatResumeCommand(this.runtimeFacade);
|
|
2406
2428
|
if (resumeCommand) {
|
|
2407
|
-
process.stdout.write(`${chalk.dim("To resume this session:")} ${resumeCommand}\n`);
|
|
2429
|
+
process.stdout.write(`${chalk.dim(t("To resume this session:"))} ${resumeCommand}\n`);
|
|
2408
2430
|
}
|
|
2409
2431
|
process.exit(0);
|
|
2410
2432
|
}
|
|
@@ -2444,7 +2466,7 @@ export class InteractiveMode {
|
|
|
2444
2466
|
this.ui.stop();
|
|
2445
2467
|
}
|
|
2446
2468
|
catch { }
|
|
2447
|
-
console.error(
|
|
2469
|
+
console.error(t("{app} exiting due to uncaughtException:", { app: APP_NAME }));
|
|
2448
2470
|
console.error(error);
|
|
2449
2471
|
process.exit(1);
|
|
2450
2472
|
}
|
|
@@ -2499,7 +2521,7 @@ export class InteractiveMode {
|
|
|
2499
2521
|
}
|
|
2500
2522
|
handleCtrlZ() {
|
|
2501
2523
|
if (process.platform === "win32") {
|
|
2502
|
-
this.showStatus("Suspend to background is not supported on Windows");
|
|
2524
|
+
this.showStatus(t("Suspend to background is not supported on Windows"));
|
|
2503
2525
|
return;
|
|
2504
2526
|
}
|
|
2505
2527
|
// Keep the event loop alive while suspended. Without this, stopping the TUI
|
|
@@ -2560,16 +2582,19 @@ export class InteractiveMode {
|
|
|
2560
2582
|
handleDequeue() {
|
|
2561
2583
|
const restored = this.restoreQueuedMessagesToEditor();
|
|
2562
2584
|
if (restored === 0) {
|
|
2563
|
-
this.showStatus("No queued messages to restore");
|
|
2585
|
+
this.showStatus(t("No queued messages to restore"));
|
|
2586
|
+
}
|
|
2587
|
+
else if (restored === 1) {
|
|
2588
|
+
this.showStatus(t("Restored {count} queued message to editor", { count: restored }));
|
|
2564
2589
|
}
|
|
2565
2590
|
else {
|
|
2566
|
-
this.showStatus(
|
|
2591
|
+
this.showStatus(t("Restored {count} queued messages to editor", { count: restored }));
|
|
2567
2592
|
}
|
|
2568
2593
|
}
|
|
2569
2594
|
/** /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
2595
|
handleQueueCommand(text) {
|
|
2571
2596
|
if (text === undefined || text.trim() === "") {
|
|
2572
|
-
this.showStatus("Usage: /queue <text>");
|
|
2597
|
+
this.showStatus(t("Usage: /queue <text>"));
|
|
2573
2598
|
return Promise.resolve();
|
|
2574
2599
|
}
|
|
2575
2600
|
return this.handleFollowUp(text);
|
|
@@ -2578,6 +2603,16 @@ export class InteractiveMode {
|
|
|
2578
2603
|
handleDequeueCommand() {
|
|
2579
2604
|
this.handleDequeue();
|
|
2580
2605
|
}
|
|
2606
|
+
/** /queue-list command host face: open the queued-message manager selector. Both queues empty is a status message, not an empty overlay. */
|
|
2607
|
+
handleQueueListCommand() {
|
|
2608
|
+
const steering = this.facade.getSteeringMessages();
|
|
2609
|
+
const followUp = this.facade.getFollowUpMessages();
|
|
2610
|
+
if (steering.length === 0 && followUp.length === 0) {
|
|
2611
|
+
this.showStatus(t("No queued messages to manage"));
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
selectorsFlow.showQueueManagerSelector(this);
|
|
2615
|
+
}
|
|
2581
2616
|
/** /editor command host face: edit the current input in an external editor. */
|
|
2582
2617
|
handleEditorCommand() {
|
|
2583
2618
|
return this.handleOpenExternalEditor();
|
|
@@ -2596,26 +2631,31 @@ export class InteractiveMode {
|
|
|
2596
2631
|
cycleThinkingLevel() {
|
|
2597
2632
|
const newLevel = this.facade.cycleThinkingLevel();
|
|
2598
2633
|
if (newLevel === undefined) {
|
|
2599
|
-
this.showStatus("Current model does not support thinking");
|
|
2634
|
+
this.showStatus(t("Current model does not support thinking"));
|
|
2600
2635
|
}
|
|
2601
2636
|
else {
|
|
2602
2637
|
this.footer.invalidate();
|
|
2603
2638
|
this.updateEditorBorderColor();
|
|
2604
|
-
this.showStatus(
|
|
2639
|
+
this.showStatus(t("Thinking level: {level}", { level: newLevel }));
|
|
2605
2640
|
}
|
|
2606
2641
|
}
|
|
2607
2642
|
async cycleModel(direction) {
|
|
2608
2643
|
try {
|
|
2609
2644
|
const result = await this.facade.cycleModel(direction);
|
|
2610
2645
|
if (result === undefined) {
|
|
2611
|
-
const msg = this.facade.getScopedModels().length > 0 ? "Only one model in scope" : "Only one model available";
|
|
2646
|
+
const msg = this.facade.getScopedModels().length > 0 ? t("Only one model in scope") : t("Only one model available");
|
|
2612
2647
|
this.showStatus(msg);
|
|
2613
2648
|
}
|
|
2614
2649
|
else {
|
|
2615
2650
|
this.footer.invalidate();
|
|
2616
2651
|
this.updateEditorBorderColor();
|
|
2617
|
-
const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off"
|
|
2618
|
-
|
|
2652
|
+
const thinkingStr = result.model.reasoning && result.thinkingLevel !== "off"
|
|
2653
|
+
? ` ${t("(thinking: {level})", { level: result.thinkingLevel })}`
|
|
2654
|
+
: "";
|
|
2655
|
+
this.showStatus(t("Switched to {model}{thinking}", {
|
|
2656
|
+
model: result.model.name || result.model.id,
|
|
2657
|
+
thinking: thinkingStr,
|
|
2658
|
+
}));
|
|
2619
2659
|
void this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);
|
|
2620
2660
|
}
|
|
2621
2661
|
}
|
|
@@ -2641,7 +2681,7 @@ export class InteractiveMode {
|
|
|
2641
2681
|
}
|
|
2642
2682
|
}
|
|
2643
2683
|
}
|
|
2644
|
-
this.showStatus(
|
|
2684
|
+
this.showStatus(expanded ? t("Tool output: expanded") : t("Tool output: collapsed"));
|
|
2645
2685
|
}
|
|
2646
2686
|
/** Update rendered assistant messages without rebuilding live tool components. */
|
|
2647
2687
|
updateThinkingBlockVisibility() {
|
|
@@ -2656,7 +2696,7 @@ export class InteractiveMode {
|
|
|
2656
2696
|
this.hideThinkingBlock = !this.hideThinkingBlock;
|
|
2657
2697
|
this.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);
|
|
2658
2698
|
this.updateThinkingBlockVisibility();
|
|
2659
|
-
this.showStatus(
|
|
2699
|
+
this.showStatus(this.hideThinkingBlock ? t("Thinking blocks: hidden") : t("Thinking blocks: visible"));
|
|
2660
2700
|
}
|
|
2661
2701
|
async handleOpenExternalEditor() {
|
|
2662
2702
|
const editorCmd = this.settingsManager.getExternalEditorCommand();
|
|
@@ -2685,28 +2725,28 @@ export class InteractiveMode {
|
|
|
2685
2725
|
}
|
|
2686
2726
|
showError(errorMessage) {
|
|
2687
2727
|
this.chatContainer.addChild(new Spacer(1));
|
|
2688
|
-
this.chatContainer.addChild(new Text(theme.fg("error",
|
|
2728
|
+
this.chatContainer.addChild(new Text(theme.fg("error", t("Error: {message}", { message: errorMessage })), this.outputPad, 0));
|
|
2689
2729
|
this.ui.requestRender();
|
|
2690
2730
|
}
|
|
2691
2731
|
showWarning(warningMessage) {
|
|
2692
2732
|
this.chatContainer.addChild(new Spacer(1));
|
|
2693
|
-
this.chatContainer.addChild(new Text(theme.fg("warning",
|
|
2733
|
+
this.chatContainer.addChild(new Text(theme.fg("warning", t("Warning: {message}", { message: warningMessage })), 1, 0));
|
|
2694
2734
|
this.ui.requestRender();
|
|
2695
2735
|
}
|
|
2696
2736
|
showNewVersionNotification(release) {
|
|
2697
2737
|
const action = theme.fg("accent", `${APP_NAME} update`);
|
|
2698
|
-
const updateInstruction = theme.fg("muted",
|
|
2738
|
+
const updateInstruction = theme.fg("muted", `${t("New version {version} is available. Run", { version: release.version })} `) + action;
|
|
2699
2739
|
const changelogUrl = process.env.AGENT_FORGE_CHANGELOG_URL;
|
|
2700
2740
|
const changelogLine = changelogUrl
|
|
2701
|
-
? theme.fg("muted", "Changelog:
|
|
2741
|
+
? theme.fg("muted", `${t("Changelog:")} `) +
|
|
2702
2742
|
(getCapabilities().hyperlinks
|
|
2703
2743
|
? hyperlink(theme.fg("accent", changelogUrl), changelogUrl)
|
|
2704
2744
|
: theme.fg("accent", changelogUrl))
|
|
2705
|
-
: theme.fg("muted", "Changelog URL is not configured.");
|
|
2745
|
+
: theme.fg("muted", t("Changelog URL is not configured."));
|
|
2706
2746
|
const note = release.note?.trim();
|
|
2707
2747
|
this.chatContainer.addChild(new Spacer(1));
|
|
2708
2748
|
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));
|
|
2749
|
+
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("warning", t("Update Available")))}\n${updateInstruction}`, 1, 0));
|
|
2710
2750
|
if (note) {
|
|
2711
2751
|
this.chatContainer.addChild(new Spacer(1));
|
|
2712
2752
|
this.chatContainer.addChild(new Markdown(note, 1, 0, this.getMarkdownThemeWithSettings(), {
|
|
@@ -2720,11 +2760,11 @@ export class InteractiveMode {
|
|
|
2720
2760
|
}
|
|
2721
2761
|
showPackageUpdateNotification(packages) {
|
|
2722
2762
|
const action = theme.fg("accent", `${APP_NAME} update --extensions`);
|
|
2723
|
-
const updateInstruction = theme.fg("muted", "Package updates are available. Run
|
|
2763
|
+
const updateInstruction = theme.fg("muted", `${t("Package updates are available. Run")} `) + action;
|
|
2724
2764
|
const packageLines = packages.map((pkg) => `- ${pkg}`).join("\n");
|
|
2725
2765
|
this.chatContainer.addChild(new Spacer(1));
|
|
2726
2766
|
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));
|
|
2767
|
+
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
2768
|
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
2729
2769
|
this.ui.requestRender();
|
|
2730
2770
|
}
|
|
@@ -2762,23 +2802,24 @@ export class InteractiveMode {
|
|
|
2762
2802
|
followUp: [...followUp, ...compactionFollowUp],
|
|
2763
2803
|
};
|
|
2764
2804
|
}
|
|
2805
|
+
/** Host-visible for ./interactive-selectors.ts (queue manager close path). */
|
|
2765
2806
|
updatePendingMessagesDisplay() {
|
|
2766
2807
|
this.pendingMessagesContainer.clear();
|
|
2767
2808
|
const { steering: steeringMessages, followUp: followUpMessages } = this.getAllQueuedMessages();
|
|
2768
2809
|
if (steeringMessages.length > 0 || followUpMessages.length > 0) {
|
|
2769
2810
|
this.pendingMessagesContainer.addChild(new Spacer(1));
|
|
2770
2811
|
for (const message of steeringMessages) {
|
|
2771
|
-
const text = theme.fg("dim",
|
|
2812
|
+
const text = theme.fg("dim", t("Steering: {message}", { message }));
|
|
2772
2813
|
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
2773
2814
|
}
|
|
2774
2815
|
for (const message of followUpMessages) {
|
|
2775
|
-
const text = theme.fg("dim",
|
|
2816
|
+
const text = theme.fg("dim", t("Follow-up: {message}", { message }));
|
|
2776
2817
|
this.pendingMessagesContainer.addChild(new TruncatedText(text, 1, 0));
|
|
2777
2818
|
}
|
|
2778
2819
|
// The dequeue keybinding's shipped default was cleared (iron law):
|
|
2779
2820
|
// /queue's sibling command is the discoverable entry.
|
|
2780
2821
|
const dequeueHint = this.getAppKeyDisplay("app.message.dequeue") || "/dequeue";
|
|
2781
|
-
const hintText = theme.fg("dim",
|
|
2822
|
+
const hintText = theme.fg("dim", t("↳ {key} to edit all queued messages", { key: dequeueHint }));
|
|
2782
2823
|
this.pendingMessagesContainer.addChild(new TruncatedText(hintText, 1, 0));
|
|
2783
2824
|
}
|
|
2784
2825
|
}
|
|
@@ -2810,7 +2851,7 @@ export class InteractiveMode {
|
|
|
2810
2851
|
this.editor.addToHistory?.(text);
|
|
2811
2852
|
this.editor.setText("");
|
|
2812
2853
|
this.updatePendingMessagesDisplay();
|
|
2813
|
-
this.showStatus("Queued message for after compaction");
|
|
2854
|
+
this.showStatus(t("Queued message for after compaction"));
|
|
2814
2855
|
}
|
|
2815
2856
|
async flushCompactionQueue(options) {
|
|
2816
2857
|
if (this.compactionQueuedMessages.length === 0) {
|
|
@@ -2823,7 +2864,13 @@ export class InteractiveMode {
|
|
|
2823
2864
|
this.facade.clearQueue();
|
|
2824
2865
|
this.compactionQueuedMessages = queuedMessages;
|
|
2825
2866
|
this.updatePendingMessagesDisplay();
|
|
2826
|
-
this.showError(
|
|
2867
|
+
this.showError(queuedMessages.length > 1
|
|
2868
|
+
? t("Failed to send queued messages: {error}", {
|
|
2869
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2870
|
+
})
|
|
2871
|
+
: t("Failed to send queued message: {error}", {
|
|
2872
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2873
|
+
}));
|
|
2827
2874
|
};
|
|
2828
2875
|
try {
|
|
2829
2876
|
if (options?.willRetry) {
|
|
@@ -2920,9 +2967,8 @@ export class InteractiveMode {
|
|
|
2920
2967
|
let selector;
|
|
2921
2968
|
const defaultProvider = this.settingsManager.getDefaultProvider();
|
|
2922
2969
|
const defaultModelId = this.settingsManager.getDefaultModel();
|
|
2923
|
-
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : "not set";
|
|
2970
|
+
const defaultModel = defaultProvider && defaultModelId ? `${defaultProvider}/${defaultModelId}` : t("not set");
|
|
2924
2971
|
selector = new SettingsSelectorComponent({
|
|
2925
|
-
autoCompact: this.facade.isAutoCompactionEnabled(),
|
|
2926
2972
|
defaultModel,
|
|
2927
2973
|
currentModel: this.facade.getModel(),
|
|
2928
2974
|
availableDefaultModels: this.facade.getAvailableModels(),
|
|
@@ -2930,7 +2976,6 @@ export class InteractiveMode {
|
|
|
2930
2976
|
imageWidthCells: this.settingsManager.getImageWidthCells(),
|
|
2931
2977
|
autoResizeImages: this.settingsManager.getImageAutoResize(),
|
|
2932
2978
|
blockImages: this.settingsManager.getBlockImages(),
|
|
2933
|
-
enableSkillCommands: this.settingsManager.getEnableSkillCommands(),
|
|
2934
2979
|
steeringMode: this.facade.getSteeringMode(),
|
|
2935
2980
|
followUpMode: this.facade.getFollowUpMode(),
|
|
2936
2981
|
transport: this.settingsManager.getTransport(),
|
|
@@ -2945,6 +2990,7 @@ export class InteractiveMode {
|
|
|
2945
2990
|
mermaidRenderingMode: this.settingsManager.getMermaidRenderingMode(),
|
|
2946
2991
|
collapseChangelog: this.settingsManager.getCollapseChangelog(),
|
|
2947
2992
|
doubleEscapeAction: this.settingsManager.getDoubleEscapeAction(),
|
|
2993
|
+
uiLanguage: this.settingsManager.getUiLanguage(),
|
|
2948
2994
|
treeFilterMode: this.settingsManager.getTreeFilterMode(),
|
|
2949
2995
|
showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
|
|
2950
2996
|
showCacheMissNotices: this.settingsManager.getShowCacheMissNotices(),
|
|
@@ -2961,10 +3007,6 @@ export class InteractiveMode {
|
|
|
2961
3007
|
fullscreenWheelScrollLines: this.settingsManager.getFullscreenWheelScrollLines(),
|
|
2962
3008
|
warnings: this.settingsManager.getWarnings(),
|
|
2963
3009
|
}, {
|
|
2964
|
-
onAutoCompactChange: (enabled) => {
|
|
2965
|
-
this.facade.setAutoCompactionEnabled(enabled);
|
|
2966
|
-
this.footer.setAutoCompactEnabled(enabled);
|
|
2967
|
-
},
|
|
2968
3010
|
onShowImagesChange: (enabled) => {
|
|
2969
3011
|
this.settingsManager.setShowImages(enabled);
|
|
2970
3012
|
for (const child of this.chatContainer.children) {
|
|
@@ -2987,10 +3029,6 @@ export class InteractiveMode {
|
|
|
2987
3029
|
onBlockImagesChange: (blocked) => {
|
|
2988
3030
|
this.settingsManager.setBlockImages(blocked);
|
|
2989
3031
|
},
|
|
2990
|
-
onEnableSkillCommandsChange: (enabled) => {
|
|
2991
|
-
this.settingsManager.setEnableSkillCommands(enabled);
|
|
2992
|
-
this.setupAutocompleteProvider();
|
|
2993
|
-
},
|
|
2994
3032
|
onSteeringModeChange: (mode) => {
|
|
2995
3033
|
this.facade.setSteeringMode(mode);
|
|
2996
3034
|
},
|
|
@@ -3004,7 +3042,7 @@ export class InteractiveMode {
|
|
|
3004
3042
|
onHttpIdleTimeoutMsChange: (timeoutMs) => {
|
|
3005
3043
|
this.settingsManager.setHttpIdleTimeoutMs(timeoutMs);
|
|
3006
3044
|
configureHttpDispatcher(timeoutMs);
|
|
3007
|
-
this.showStatus(
|
|
3045
|
+
this.showStatus(t("HTTP idle timeout: {value}", { value: formatHttpIdleTimeoutMs(timeoutMs) }));
|
|
3008
3046
|
},
|
|
3009
3047
|
onModelThinkingLevelChange: (provider, modelId, level) => {
|
|
3010
3048
|
this.settingsManager.setModelThinkingLevel(provider, modelId, level);
|
|
@@ -3055,6 +3093,11 @@ export class InteractiveMode {
|
|
|
3055
3093
|
onDoubleEscapeActionChange: (action) => {
|
|
3056
3094
|
this.settingsManager.setDoubleEscapeAction(action);
|
|
3057
3095
|
},
|
|
3096
|
+
onUiLanguageChange: (language) => {
|
|
3097
|
+
this.settingsManager.setUiLanguage(language);
|
|
3098
|
+
setI18nLanguage(language);
|
|
3099
|
+
this.ui.requestRender();
|
|
3100
|
+
},
|
|
3058
3101
|
onTreeFilterModeChange: (mode) => {
|
|
3059
3102
|
this.settingsManager.setTreeFilterMode(mode);
|
|
3060
3103
|
},
|
|
@@ -3108,13 +3151,13 @@ export class InteractiveMode {
|
|
|
3108
3151
|
onTuiModeChange: (mode) => {
|
|
3109
3152
|
if (!this.switchTuiMode(mode)) {
|
|
3110
3153
|
selector?.getSettingsList().updateValue("tui-mode", this.ui.mode);
|
|
3111
|
-
this.showStatus("Close active overlays before changing TUI mode");
|
|
3154
|
+
this.showStatus(t("Close active overlays before changing TUI mode"));
|
|
3112
3155
|
return;
|
|
3113
3156
|
}
|
|
3114
3157
|
this.settingsManager.setTuiMode(mode);
|
|
3115
3158
|
if (!this.activeStatusIndicator)
|
|
3116
3159
|
this.statusContainer.clear();
|
|
3117
|
-
this.showStatus(
|
|
3160
|
+
this.showStatus(t("TUI mode: {mode}", { mode }));
|
|
3118
3161
|
},
|
|
3119
3162
|
onFullscreenExitOutputChange: (output) => {
|
|
3120
3163
|
this.settingsManager.setFullscreenExitOutput(output);
|
|
@@ -3222,22 +3265,26 @@ export class InteractiveMode {
|
|
|
3222
3265
|
const selected = await new Promise((resolve) => {
|
|
3223
3266
|
this.openSuiteListSelector({
|
|
3224
3267
|
availableSuites: pending.available,
|
|
3225
|
-
note:
|
|
3268
|
+
note: t('Suite "{id}" was not found. The selected suite applies to the new session.', {
|
|
3269
|
+
id: pending.requestedId,
|
|
3270
|
+
}),
|
|
3226
3271
|
onSelect: (suiteId) => resolve(suiteId),
|
|
3227
3272
|
onCancel: () => resolve(undefined),
|
|
3228
3273
|
});
|
|
3229
3274
|
});
|
|
3230
3275
|
if (selected === undefined) {
|
|
3231
|
-
this.showWarning(
|
|
3276
|
+
this.showWarning(t('Suite "{id}" was not found — continuing without a suite. Use /suite to choose one.', {
|
|
3277
|
+
id: pending.requestedId,
|
|
3278
|
+
}));
|
|
3232
3279
|
return;
|
|
3233
3280
|
}
|
|
3234
3281
|
this.settingsManager.setProjectSuite(selected);
|
|
3235
3282
|
try {
|
|
3236
3283
|
await this.runtimeFacade.newSession();
|
|
3237
|
-
this.showStatus(
|
|
3284
|
+
this.showStatus(t("Suite set to {id} — new session started", { id: selected }));
|
|
3238
3285
|
}
|
|
3239
3286
|
catch (error) {
|
|
3240
|
-
await this.handleFatalRuntimeError("Failed to create session", error);
|
|
3287
|
+
await this.handleFatalRuntimeError(t("Failed to create session"), error);
|
|
3241
3288
|
}
|
|
3242
3289
|
}
|
|
3243
3290
|
/** /model command entry; implementation in ./interactive-selectors.ts (S5 slice 5). */
|
|
@@ -3273,7 +3320,7 @@ export class InteractiveMode {
|
|
|
3273
3320
|
try {
|
|
3274
3321
|
if ((await this.facade.checkProviderAuth("anthropic"))?.type === "oauth") {
|
|
3275
3322
|
this.anthropicSubscriptionWarningShown = true;
|
|
3276
|
-
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
3323
|
+
this.showWarning(t(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING));
|
|
3277
3324
|
return;
|
|
3278
3325
|
}
|
|
3279
3326
|
const apiKey = (await this.facade.getProviderAuth(model.provider))?.auth.apiKey;
|
|
@@ -3281,7 +3328,7 @@ export class InteractiveMode {
|
|
|
3281
3328
|
return;
|
|
3282
3329
|
}
|
|
3283
3330
|
this.anthropicSubscriptionWarningShown = true;
|
|
3284
|
-
this.showWarning(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING);
|
|
3331
|
+
this.showWarning(t(ANTHROPIC_SUBSCRIPTION_AUTH_WARNING));
|
|
3285
3332
|
}
|
|
3286
3333
|
catch {
|
|
3287
3334
|
// Ignore auth lookup failures for warning-only checks.
|
|
@@ -3314,7 +3361,7 @@ export class InteractiveMode {
|
|
|
3314
3361
|
.getEntries()
|
|
3315
3362
|
.some((entry) => entry.type === "custom" && entry.customType === "workflow.state");
|
|
3316
3363
|
if (!hasSnapshot) {
|
|
3317
|
-
this.showStatus("No workflow in this session");
|
|
3364
|
+
this.showStatus(t("No workflow in this session"));
|
|
3318
3365
|
return;
|
|
3319
3366
|
}
|
|
3320
3367
|
this.showSelector((done) => {
|
|
@@ -3328,7 +3375,7 @@ export class InteractiveMode {
|
|
|
3328
3375
|
done();
|
|
3329
3376
|
this.editor.setText(text);
|
|
3330
3377
|
this.ui.requestRender();
|
|
3331
|
-
this.showStatus("Workflow action staged — review in the editor and submit");
|
|
3378
|
+
this.showStatus(t("Workflow action staged — review in the editor and submit"));
|
|
3332
3379
|
};
|
|
3333
3380
|
return { component: view, focus: view, dispose: () => view.dispose() };
|
|
3334
3381
|
});
|
|
@@ -3344,7 +3391,7 @@ export class InteractiveMode {
|
|
|
3344
3391
|
const agentDir = getAgentDir();
|
|
3345
3392
|
const sessions = listAgentSessions({ agentDir, parentAgentSession: this.facade.getSessionId() });
|
|
3346
3393
|
if (sessions.length === 0) {
|
|
3347
|
-
this.showStatus("No subagent sessions in this session");
|
|
3394
|
+
this.showStatus(t("No subagent sessions in this session"));
|
|
3348
3395
|
return;
|
|
3349
3396
|
}
|
|
3350
3397
|
this.showSelector((done) => {
|
|
@@ -3363,7 +3410,7 @@ export class InteractiveMode {
|
|
|
3363
3410
|
const realLeafId = this.facade.getLeafId();
|
|
3364
3411
|
const initialFilterMode = this.settingsManager.getTreeFilterMode();
|
|
3365
3412
|
if (tree.length === 0) {
|
|
3366
|
-
this.showStatus("No entries in session");
|
|
3413
|
+
this.showStatus(t("No entries in session"));
|
|
3367
3414
|
return;
|
|
3368
3415
|
}
|
|
3369
3416
|
this.showSelector((done) => {
|
|
@@ -3371,7 +3418,7 @@ export class InteractiveMode {
|
|
|
3371
3418
|
// Selecting the current leaf is a no-op (already there)
|
|
3372
3419
|
if (entryId === this.facade.getLeafId()) {
|
|
3373
3420
|
done();
|
|
3374
|
-
this.showStatus("Already at this point");
|
|
3421
|
+
this.showStatus(t("Already at this point"));
|
|
3375
3422
|
return;
|
|
3376
3423
|
}
|
|
3377
3424
|
// Ask about summarization
|
|
@@ -3382,19 +3429,19 @@ export class InteractiveMode {
|
|
|
3382
3429
|
// Check if we should skip the prompt (user preference to always default to no summary)
|
|
3383
3430
|
if (!this.settingsManager.getBranchSummarySkipPrompt()) {
|
|
3384
3431
|
while (true) {
|
|
3385
|
-
const summaryChoice = await this.showDialogSelector("Summarize branch?", [
|
|
3386
|
-
"No summary",
|
|
3387
|
-
"Summarize",
|
|
3388
|
-
"Summarize with custom prompt",
|
|
3432
|
+
const summaryChoice = await this.showDialogSelector(t("Summarize branch?"), [
|
|
3433
|
+
t("No summary"),
|
|
3434
|
+
t("Summarize"),
|
|
3435
|
+
t("Summarize with custom prompt"),
|
|
3389
3436
|
]);
|
|
3390
3437
|
if (summaryChoice === undefined) {
|
|
3391
3438
|
// User pressed escape - re-show tree selector with same selection
|
|
3392
3439
|
this.showTreeSelector(entryId);
|
|
3393
3440
|
return;
|
|
3394
3441
|
}
|
|
3395
|
-
wantsSummary = summaryChoice !== "No summary";
|
|
3396
|
-
if (summaryChoice === "Summarize with custom prompt") {
|
|
3397
|
-
customInstructions = await this.showDialogEditor("Custom summarization instructions");
|
|
3442
|
+
wantsSummary = summaryChoice !== t("No summary");
|
|
3443
|
+
if (summaryChoice === t("Summarize with custom prompt")) {
|
|
3444
|
+
customInstructions = await this.showDialogEditor(t("Custom summarization instructions"));
|
|
3398
3445
|
if (customInstructions === undefined) {
|
|
3399
3446
|
// User cancelled - loop back to summary selector
|
|
3400
3447
|
continue;
|
|
@@ -3429,12 +3476,12 @@ export class InteractiveMode {
|
|
|
3429
3476
|
});
|
|
3430
3477
|
if (result.aborted) {
|
|
3431
3478
|
// Summarization aborted - re-show tree selector with same selection
|
|
3432
|
-
this.showStatus("Branch summarization cancelled");
|
|
3479
|
+
this.showStatus(t("Branch summarization cancelled"));
|
|
3433
3480
|
this.showTreeSelector(entryId);
|
|
3434
3481
|
return;
|
|
3435
3482
|
}
|
|
3436
3483
|
if (result.cancelled) {
|
|
3437
|
-
this.showStatus("Navigation cancelled");
|
|
3484
|
+
this.showStatus(t("Navigation cancelled"));
|
|
3438
3485
|
return;
|
|
3439
3486
|
}
|
|
3440
3487
|
// Update UI
|
|
@@ -3443,7 +3490,7 @@ export class InteractiveMode {
|
|
|
3443
3490
|
if (result.editorText && !this.editor.getText().trim()) {
|
|
3444
3491
|
this.editor.setText(result.editorText);
|
|
3445
3492
|
}
|
|
3446
|
-
this.showStatus("Navigated to selected point");
|
|
3493
|
+
this.showStatus(t("Navigated to selected point"));
|
|
3447
3494
|
void this.flushCompactionQueue({ willRetry: false });
|
|
3448
3495
|
}
|
|
3449
3496
|
catch (error) {
|
|
@@ -3464,12 +3511,12 @@ export class InteractiveMode {
|
|
|
3464
3511
|
}, initialSelectedId, initialFilterMode);
|
|
3465
3512
|
selector.onCopy = async (text) => {
|
|
3466
3513
|
if (!text) {
|
|
3467
|
-
this.showError("Selected entry has no text to copy");
|
|
3514
|
+
this.showError(t("Selected entry has no text to copy"));
|
|
3468
3515
|
return;
|
|
3469
3516
|
}
|
|
3470
3517
|
try {
|
|
3471
3518
|
await copyToClipboard(text);
|
|
3472
|
-
this.showStatus("Copied selected message to clipboard");
|
|
3519
|
+
this.showStatus(t("Copied selected message to clipboard"));
|
|
3473
3520
|
}
|
|
3474
3521
|
catch (error) {
|
|
3475
3522
|
this.showError(error instanceof Error ? error.message : String(error));
|
|
@@ -3517,7 +3564,7 @@ export class InteractiveMode {
|
|
|
3517
3564
|
if (result.cancelled) {
|
|
3518
3565
|
return result;
|
|
3519
3566
|
}
|
|
3520
|
-
this.showStatus("Resumed session");
|
|
3567
|
+
this.showStatus(t("Resumed session"));
|
|
3521
3568
|
this.detectCrossSuiteResume();
|
|
3522
3569
|
return result;
|
|
3523
3570
|
}
|
|
@@ -3525,7 +3572,7 @@ export class InteractiveMode {
|
|
|
3525
3572
|
if (error instanceof MissingSessionCwdError) {
|
|
3526
3573
|
const selectedCwd = await this.promptForMissingSessionCwd(error);
|
|
3527
3574
|
if (!selectedCwd) {
|
|
3528
|
-
this.showStatus("Resume cancelled");
|
|
3575
|
+
this.showStatus(t("Resume cancelled"));
|
|
3529
3576
|
return { cancelled: true };
|
|
3530
3577
|
}
|
|
3531
3578
|
const result = await this.runtimeFacade.switchSession(sessionPath, {
|
|
@@ -3535,11 +3582,11 @@ export class InteractiveMode {
|
|
|
3535
3582
|
if (result.cancelled) {
|
|
3536
3583
|
return result;
|
|
3537
3584
|
}
|
|
3538
|
-
this.showStatus("Resumed session in current cwd");
|
|
3585
|
+
this.showStatus(t("Resumed session in current cwd"));
|
|
3539
3586
|
this.detectCrossSuiteResume();
|
|
3540
3587
|
return result;
|
|
3541
3588
|
}
|
|
3542
|
-
return this.handleFatalRuntimeError("Failed to resume session", error);
|
|
3589
|
+
return this.handleFatalRuntimeError(t("Failed to resume session"), error);
|
|
3543
3590
|
}
|
|
3544
3591
|
}
|
|
3545
3592
|
/**
|
|
@@ -3563,7 +3610,10 @@ export class InteractiveMode {
|
|
|
3563
3610
|
});
|
|
3564
3611
|
if (currentSuiteId === originalSuiteId)
|
|
3565
3612
|
return;
|
|
3566
|
-
this.showStatus(
|
|
3613
|
+
this.showStatus(t('Cross-suite compatible mode: session created with "{from}", assembling with "{to}"', {
|
|
3614
|
+
from: originalSuiteId,
|
|
3615
|
+
to: currentSuiteId,
|
|
3616
|
+
}));
|
|
3567
3617
|
this.facade.recordSuiteMismatch(originalSuiteId, currentSuiteId);
|
|
3568
3618
|
}
|
|
3569
3619
|
// =========================================================================
|
|
@@ -3681,11 +3731,11 @@ export class InteractiveMode {
|
|
|
3681
3731
|
// =========================================================================
|
|
3682
3732
|
async handleReloadCommand() {
|
|
3683
3733
|
if (this.facade.isStreaming()) {
|
|
3684
|
-
this.showWarning("Wait for the current response to finish before reloading.");
|
|
3734
|
+
this.showWarning(t("Wait for the current response to finish before reloading."));
|
|
3685
3735
|
return;
|
|
3686
3736
|
}
|
|
3687
3737
|
if (this.facade.isCompacting()) {
|
|
3688
|
-
this.showWarning("Wait for compaction to finish before reloading.");
|
|
3738
|
+
this.showWarning(t("Wait for compaction to finish before reloading."));
|
|
3689
3739
|
return;
|
|
3690
3740
|
}
|
|
3691
3741
|
this.resetDialogUI();
|
|
@@ -3693,7 +3743,7 @@ export class InteractiveMode {
|
|
|
3693
3743
|
const borderColor = (s) => theme.fg("border", s);
|
|
3694
3744
|
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
3695
3745
|
reloadBox.addChild(new Spacer(1));
|
|
3696
|
-
reloadBox.addChild(new Text(theme.fg("muted", "Reloading keybindings, skills, prompts, themes, and context files..."), 1, 0));
|
|
3746
|
+
reloadBox.addChild(new Text(theme.fg("muted", t("Reloading keybindings, skills, prompts, themes, and context files...")), 1, 0));
|
|
3697
3747
|
reloadBox.addChild(new Spacer(1));
|
|
3698
3748
|
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
3699
3749
|
const previousEditor = this.editor;
|
|
@@ -3737,9 +3787,9 @@ export class InteractiveMode {
|
|
|
3737
3787
|
});
|
|
3738
3788
|
const modelsJsonError = this.facade.getModelsError();
|
|
3739
3789
|
if (modelsJsonError) {
|
|
3740
|
-
this.showError(
|
|
3790
|
+
this.showError(t("models.json error: {error}", { error: modelsJsonError }));
|
|
3741
3791
|
}
|
|
3742
|
-
this.showStatus("Reloaded keybindings, skills, prompts, themes, and context files");
|
|
3792
|
+
this.showStatus(t("Reloaded keybindings, skills, prompts, themes, and context files"));
|
|
3743
3793
|
dismissReloadBox(this.editor);
|
|
3744
3794
|
reloadBoxDismissed = true;
|
|
3745
3795
|
}
|
|
@@ -3748,7 +3798,7 @@ export class InteractiveMode {
|
|
|
3748
3798
|
if (!reloadBoxDismissed) {
|
|
3749
3799
|
dismissReloadBox(previousEditor);
|
|
3750
3800
|
}
|
|
3751
|
-
this.showError(
|
|
3801
|
+
this.showError(t("Reload failed: {error}", { error: error instanceof Error ? error.message : String(error) }));
|
|
3752
3802
|
}
|
|
3753
3803
|
}
|
|
3754
3804
|
async handleExportCommand(text) {
|
|
@@ -3756,17 +3806,19 @@ export class InteractiveMode {
|
|
|
3756
3806
|
try {
|
|
3757
3807
|
if (outputPath?.endsWith(".jsonl")) {
|
|
3758
3808
|
const filePath = this.facade.exportToJsonl(outputPath);
|
|
3759
|
-
this.showStatus(
|
|
3809
|
+
this.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
3760
3810
|
}
|
|
3761
3811
|
else {
|
|
3762
3812
|
const filePath = await this.facade.exportToHtml(outputPath, {
|
|
3763
3813
|
themeName: theme.name,
|
|
3764
3814
|
});
|
|
3765
|
-
this.showStatus(
|
|
3815
|
+
this.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
3766
3816
|
}
|
|
3767
3817
|
}
|
|
3768
3818
|
catch (error) {
|
|
3769
|
-
this.showError(
|
|
3819
|
+
this.showError(t("Failed to export session: {error}", {
|
|
3820
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
3821
|
+
}));
|
|
3770
3822
|
}
|
|
3771
3823
|
}
|
|
3772
3824
|
getPathCommandArgument(text, command) {
|
|
@@ -3797,43 +3849,43 @@ export class InteractiveMode {
|
|
|
3797
3849
|
async handleImportCommand(text) {
|
|
3798
3850
|
const inputPath = this.getPathCommandArgument(text, "/import");
|
|
3799
3851
|
if (!inputPath) {
|
|
3800
|
-
this.showError("Usage: /import <path.jsonl>");
|
|
3852
|
+
this.showError(t("Usage: /import <path.jsonl>"));
|
|
3801
3853
|
return;
|
|
3802
3854
|
}
|
|
3803
|
-
const confirmed = await this.showDialogConfirm("Import session",
|
|
3855
|
+
const confirmed = await this.showDialogConfirm(t("Import session"), t("Replace current session with {path}?", { path: inputPath }));
|
|
3804
3856
|
if (!confirmed) {
|
|
3805
|
-
this.showStatus("Import cancelled");
|
|
3857
|
+
this.showStatus(t("Import cancelled"));
|
|
3806
3858
|
return;
|
|
3807
3859
|
}
|
|
3808
3860
|
try {
|
|
3809
3861
|
this.clearStatusIndicator();
|
|
3810
3862
|
const result = await this.runtimeFacade.importFromJsonl(inputPath);
|
|
3811
3863
|
if (result.cancelled) {
|
|
3812
|
-
this.showStatus("Import cancelled");
|
|
3864
|
+
this.showStatus(t("Import cancelled"));
|
|
3813
3865
|
return;
|
|
3814
3866
|
}
|
|
3815
|
-
this.showStatus(
|
|
3867
|
+
this.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
3816
3868
|
}
|
|
3817
3869
|
catch (error) {
|
|
3818
3870
|
if (error instanceof MissingSessionCwdError) {
|
|
3819
3871
|
const selectedCwd = await this.promptForMissingSessionCwd(error);
|
|
3820
3872
|
if (!selectedCwd) {
|
|
3821
|
-
this.showStatus("Import cancelled");
|
|
3873
|
+
this.showStatus(t("Import cancelled"));
|
|
3822
3874
|
return;
|
|
3823
3875
|
}
|
|
3824
3876
|
const result = await this.runtimeFacade.importFromJsonl(inputPath, selectedCwd);
|
|
3825
3877
|
if (result.cancelled) {
|
|
3826
|
-
this.showStatus("Import cancelled");
|
|
3878
|
+
this.showStatus(t("Import cancelled"));
|
|
3827
3879
|
return;
|
|
3828
3880
|
}
|
|
3829
|
-
this.showStatus(
|
|
3881
|
+
this.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
3830
3882
|
return;
|
|
3831
3883
|
}
|
|
3832
3884
|
if (error instanceof SessionImportFileNotFoundError) {
|
|
3833
|
-
this.showError(
|
|
3885
|
+
this.showError(t("Failed to import session: {error}", { error: error.message }));
|
|
3834
3886
|
return;
|
|
3835
3887
|
}
|
|
3836
|
-
await this.handleFatalRuntimeError("Failed to import session", error);
|
|
3888
|
+
await this.handleFatalRuntimeError(t("Failed to import session"), error);
|
|
3837
3889
|
}
|
|
3838
3890
|
}
|
|
3839
3891
|
async handleCopyCommand(options = {}) {
|
|
@@ -3846,16 +3898,16 @@ export class InteractiveMode {
|
|
|
3846
3898
|
}
|
|
3847
3899
|
const text = this.facade.getLastAssistantText();
|
|
3848
3900
|
if (!text) {
|
|
3849
|
-
this.showError("No agent messages to copy yet.");
|
|
3901
|
+
this.showError(t("No agent messages to copy yet."));
|
|
3850
3902
|
return;
|
|
3851
3903
|
}
|
|
3852
3904
|
try {
|
|
3853
3905
|
await copyToClipboard(text);
|
|
3854
3906
|
if (options.flashConfirmation && this.ui instanceof TuiAltScreen) {
|
|
3855
|
-
this.ui.flash("Copied!");
|
|
3907
|
+
this.ui.flash(t("Copied!"));
|
|
3856
3908
|
}
|
|
3857
3909
|
else {
|
|
3858
|
-
this.showStatus("Copied last agent message to clipboard");
|
|
3910
|
+
this.showStatus(t("Copied last agent message to clipboard"));
|
|
3859
3911
|
}
|
|
3860
3912
|
}
|
|
3861
3913
|
catch (error) {
|
|
@@ -3868,10 +3920,10 @@ export class InteractiveMode {
|
|
|
3868
3920
|
const currentName = this.facade.getSessionName();
|
|
3869
3921
|
if (currentName) {
|
|
3870
3922
|
this.chatContainer.addChild(new Spacer(1));
|
|
3871
|
-
this.chatContainer.addChild(new Text(theme.fg("dim",
|
|
3923
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", t("Session name: {name}", { name: currentName })), 1, 0));
|
|
3872
3924
|
}
|
|
3873
3925
|
else {
|
|
3874
|
-
this.showWarning("Usage: /name <name>");
|
|
3926
|
+
this.showWarning(t("Usage: /name <name>"));
|
|
3875
3927
|
}
|
|
3876
3928
|
this.ui.requestRender();
|
|
3877
3929
|
return;
|
|
@@ -3879,10 +3931,13 @@ export class InteractiveMode {
|
|
|
3879
3931
|
this.facade.setSessionName(name);
|
|
3880
3932
|
const sessionName = this.facade.getSessionName();
|
|
3881
3933
|
if (sessionName !== name) {
|
|
3882
|
-
this.showWarning(
|
|
3934
|
+
this.showWarning(t("Session name was normalized from {from} to {to}", {
|
|
3935
|
+
from: JSON.stringify(name),
|
|
3936
|
+
to: JSON.stringify(sessionName),
|
|
3937
|
+
}));
|
|
3883
3938
|
}
|
|
3884
3939
|
this.chatContainer.addChild(new Spacer(1));
|
|
3885
|
-
this.chatContainer.addChild(new Text(theme.fg("dim",
|
|
3940
|
+
this.chatContainer.addChild(new Text(theme.fg("dim", t("Session name set: {name}", { name: sessionName ?? name })), 1, 0));
|
|
3886
3941
|
this.ui.requestRender();
|
|
3887
3942
|
}
|
|
3888
3943
|
/**
|
|
@@ -3892,11 +3947,13 @@ export class InteractiveMode {
|
|
|
3892
3947
|
handleStopAgentsCommand() {
|
|
3893
3948
|
const active = this.facade.getActiveAgentTaskCount();
|
|
3894
3949
|
if (active === 0) {
|
|
3895
|
-
this.showStatus("No background subagents running");
|
|
3950
|
+
this.showStatus(t("No background subagents running"));
|
|
3896
3951
|
return;
|
|
3897
3952
|
}
|
|
3898
3953
|
this.facade.abortAgentTasks();
|
|
3899
|
-
this.showStatus(
|
|
3954
|
+
this.showStatus(active === 1
|
|
3955
|
+
? t("Terminated {count} background subagent", { count: active })
|
|
3956
|
+
: t("Terminated {count} background subagents", { count: active }));
|
|
3900
3957
|
}
|
|
3901
3958
|
handleSessionCommand() {
|
|
3902
3959
|
const stats = this.facade.getSessionStats();
|
|
@@ -3907,71 +3964,81 @@ export class InteractiveMode {
|
|
|
3907
3964
|
// resolves to a concrete responseModel). Usage without model attribution is
|
|
3908
3965
|
// grouped separately so the breakdown reconciles with the session total.
|
|
3909
3966
|
const usageBreakdown = getUsageCostBreakdown(entries);
|
|
3910
|
-
let info = `${theme.bold("Session Info")}\n\n`;
|
|
3967
|
+
let info = `${theme.bold(t("Session Info"))}\n\n`;
|
|
3911
3968
|
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
|
-
|
|
3969
|
+
info += `${theme.fg("dim", t("Name:"))} ${sessionName}\n`;
|
|
3970
|
+
}
|
|
3971
|
+
info += `${theme.fg("dim", t("File:"))} ${stats.sessionFile ?? t("In-memory")}\n`;
|
|
3972
|
+
info += `${theme.fg("dim", t("ID:"))} ${stats.sessionId}\n\n`;
|
|
3973
|
+
info += `${theme.bold(t("Messages"))}\n`;
|
|
3974
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.totalMessages}\n`;
|
|
3975
|
+
info += `${theme.fg("dim", t("User:"))} ${stats.userMessages}\n`;
|
|
3976
|
+
info += `${theme.fg("dim", t("Assistant:"))} ${stats.assistantMessages}\n`;
|
|
3977
|
+
info += `${theme.fg("dim", t("Tools:"))} ${t("{calls} calls, {results} results", {
|
|
3978
|
+
calls: stats.toolCalls,
|
|
3979
|
+
results: stats.toolResults,
|
|
3980
|
+
})}\n\n`;
|
|
3981
|
+
info += `${theme.bold(t("Tokens"))}\n`;
|
|
3922
3982
|
// "Input" is the full prompt volume. With cache activity, split it into
|
|
3923
3983
|
// cached (served from cache) vs uncached (everything else) - the only
|
|
3924
3984
|
// provider-independent split. Cache writes, where reported, are a detail
|
|
3925
3985
|
// of the uncached portion.
|
|
3926
3986
|
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
3927
3987
|
const promptTokens = input + cacheRead + cacheWrite;
|
|
3928
|
-
info += `${theme.fg("dim", "Input:")} ${promptTokens.toLocaleString()}\n`;
|
|
3988
|
+
info += `${theme.fg("dim", t("Input:"))} ${promptTokens.toLocaleString()}\n`;
|
|
3929
3989
|
if (promptTokens > 0 && (cacheRead > 0 || cacheWrite > 0)) {
|
|
3930
3990
|
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
|
-
|
|
3991
|
+
info += ` ${theme.fg("dim", t("Cached:"))} ${cacheRead.toLocaleString()} ${hitRate}\n`;
|
|
3992
|
+
const written = cacheWrite > 0
|
|
3993
|
+
? ` ${theme.fg("dim", t("({count} written to cache)", { count: cacheWrite.toLocaleString() }))}`
|
|
3994
|
+
: "";
|
|
3995
|
+
info += ` ${theme.fg("dim", t("Uncached:"))} ${(input + cacheWrite).toLocaleString()}${written}\n`;
|
|
3934
3996
|
}
|
|
3935
|
-
info += `${theme.fg("dim", "Output:")} ${stats.tokens.output.toLocaleString()}\n`;
|
|
3936
|
-
info += `${theme.fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
|
|
3997
|
+
info += `${theme.fg("dim", t("Output:"))} ${stats.tokens.output.toLocaleString()}\n`;
|
|
3998
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.tokens.total.toLocaleString()}\n`;
|
|
3937
3999
|
// 双维度统计(用户裁决 2026-09-25):总计之外按供应商/模型分桶——缓存读/写、
|
|
3938
4000
|
// 命中率、费用逐桶可见。此前该拆分门控在 cost>0 且多桶才渲染,单价为 0 的
|
|
3939
4001
|
// 自定义供应商(如自建代理)永远看不到。
|
|
3940
4002
|
if (usageBreakdown.length > 0) {
|
|
3941
|
-
info += `\n${theme.bold("By Provider/Model")}\n`;
|
|
4003
|
+
info += `\n${theme.bold(t("By Provider/Model"))}\n`;
|
|
3942
4004
|
for (const entry of usageBreakdown) {
|
|
3943
4005
|
const bucket = entry.totals;
|
|
3944
4006
|
const promptBucket = bucket.input + bucket.cacheRead + bucket.cacheWrite;
|
|
3945
4007
|
let line = ` ${theme.bold(entry.key)}`;
|
|
3946
4008
|
if (promptBucket > 0) {
|
|
3947
|
-
line += `\n ${theme.fg("dim", "Input:")} ${promptBucket.toLocaleString()}`;
|
|
4009
|
+
line += `\n ${theme.fg("dim", t("Input:"))} ${promptBucket.toLocaleString()}`;
|
|
3948
4010
|
if (bucket.cacheRead > 0 || bucket.cacheWrite > 0) {
|
|
3949
4011
|
const rate = promptBucket > 0 ? ((bucket.cacheRead / promptBucket) * 100).toFixed(1) : "0.0";
|
|
3950
|
-
line += ` ${theme.fg("dim",
|
|
4012
|
+
line += ` ${theme.fg("dim", t("(cache {rate}%, W {written})", { rate, written: bucket.cacheWrite.toLocaleString() }))}`;
|
|
3951
4013
|
}
|
|
3952
4014
|
}
|
|
3953
4015
|
if (bucket.output > 0)
|
|
3954
|
-
line += `\n ${theme.fg("dim", "Output:")} ${bucket.output.toLocaleString()}`;
|
|
4016
|
+
line += `\n ${theme.fg("dim", t("Output:"))} ${bucket.output.toLocaleString()}`;
|
|
3955
4017
|
if (entry.cost > 0)
|
|
3956
4018
|
line += ` ${theme.fg("dim", `$${entry.cost.toFixed(3)}`)}`;
|
|
3957
4019
|
info += `${line}\n`;
|
|
3958
4020
|
}
|
|
3959
4021
|
}
|
|
3960
4022
|
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
3961
|
-
info += `\n${theme.bold("Cost")}\n`;
|
|
3962
|
-
info += `${theme.fg("dim", "Total:")} $${stats.cost.toFixed(3)}`;
|
|
4023
|
+
info += `\n${theme.bold(t("Cost"))}\n`;
|
|
4024
|
+
info += `${theme.fg("dim", t("Total:"))} $${stats.cost.toFixed(3)}`;
|
|
3963
4025
|
if (usageBreakdown.length > 1) {
|
|
3964
4026
|
for (const entry of usageBreakdown) {
|
|
3965
|
-
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim",
|
|
4027
|
+
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim", t("({tokens} tokens)", { tokens: formatTokens(entry.tokens) }))}`;
|
|
3966
4028
|
}
|
|
3967
4029
|
}
|
|
3968
4030
|
if (cacheWaste.missedTokens > 0) {
|
|
3969
|
-
const missLabel = cacheWaste.missCount === 1
|
|
3970
|
-
|
|
4031
|
+
const missLabel = cacheWaste.missCount === 1
|
|
4032
|
+
? t("{count} miss", { count: cacheWaste.missCount })
|
|
4033
|
+
: t("{count} misses", { count: cacheWaste.missCount });
|
|
4034
|
+
const detail = t("{tokens} tokens, {misses}", {
|
|
4035
|
+
tokens: cacheWaste.missedTokens.toLocaleString(),
|
|
4036
|
+
misses: missLabel,
|
|
4037
|
+
});
|
|
3971
4038
|
info +=
|
|
3972
4039
|
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}`;
|
|
4040
|
+
? `\n${theme.fg("dim", t("Cache Re-billed:"))} $${cacheWaste.missedCost.toFixed(3)} ${theme.fg("dim", `(${detail})`)}`
|
|
4041
|
+
: `\n${theme.fg("dim", t("Cache Re-billed:"))} ${detail}`;
|
|
3975
4042
|
}
|
|
3976
4043
|
}
|
|
3977
4044
|
this.chatContainer.addChild(new Spacer(1));
|
|
@@ -3981,14 +4048,14 @@ export class InteractiveMode {
|
|
|
3981
4048
|
handleMetricsCommand(turnsArg) {
|
|
3982
4049
|
const provider = this.options.getMetrics;
|
|
3983
4050
|
if (!provider) {
|
|
3984
|
-
this.showWarning("Metrics are not available: the observability plugin is not mounted in this session");
|
|
4051
|
+
this.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
3985
4052
|
return;
|
|
3986
4053
|
}
|
|
3987
4054
|
let windowTurns;
|
|
3988
4055
|
if (turnsArg !== undefined) {
|
|
3989
4056
|
const parsed = Number.parseInt(turnsArg, 10);
|
|
3990
4057
|
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
3991
|
-
this.showWarning(
|
|
4058
|
+
this.showWarning(t("Invalid turns: {turns}. Usage: /metrics [turns]", { turns: turnsArg }));
|
|
3992
4059
|
return;
|
|
3993
4060
|
}
|
|
3994
4061
|
windowTurns = parsed;
|
|
@@ -3997,7 +4064,7 @@ export class InteractiveMode {
|
|
|
3997
4064
|
try {
|
|
3998
4065
|
const result = provider({ windowTurns });
|
|
3999
4066
|
if (result === undefined) {
|
|
4000
|
-
this.showWarning("Metrics are not available: the observability plugin is not mounted in this session");
|
|
4067
|
+
this.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
4001
4068
|
return;
|
|
4002
4069
|
}
|
|
4003
4070
|
snapshot = result;
|
|
@@ -4018,10 +4085,10 @@ export class InteractiveMode {
|
|
|
4018
4085
|
.reverse()
|
|
4019
4086
|
.map((e) => normalizeChangelogLinks(e.content, e))
|
|
4020
4087
|
.join("\n\n")
|
|
4021
|
-
: "No changelog entries found.";
|
|
4088
|
+
: t("No changelog entries found.");
|
|
4022
4089
|
this.chatContainer.addChild(new Spacer(1));
|
|
4023
4090
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4024
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "What's New")), 1, 0));
|
|
4091
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("What's New"))), 1, 0));
|
|
4025
4092
|
this.chatContainer.addChild(new Spacer(1));
|
|
4026
4093
|
this.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4027
4094
|
this.chatContainer.addChild(new DynamicBorder());
|
|
@@ -4043,7 +4110,7 @@ export class InteractiveMode {
|
|
|
4043
4110
|
const section = (title, rows) => {
|
|
4044
4111
|
if (rows.length === 0)
|
|
4045
4112
|
return "";
|
|
4046
|
-
let table = `\n**${title}**\n| Command | Description |\n|---------|-------------|\n`;
|
|
4113
|
+
let table = `\n**${title}**\n| ${t("Command")} | ${t("Description")} |\n|---------|-------------|\n`;
|
|
4047
4114
|
for (const row of rows) {
|
|
4048
4115
|
const command = row.hint ? `\`/${row.name} ${row.hint}\`` : `\`/${row.name}\``;
|
|
4049
4116
|
table += `| ${command} | ${row.description ?? ""} |\n`;
|
|
@@ -4064,13 +4131,13 @@ export class InteractiveMode {
|
|
|
4064
4131
|
name: `skill:${skill.name}`,
|
|
4065
4132
|
description: skill.description,
|
|
4066
4133
|
}));
|
|
4067
|
-
const help = section("Built-in commands", builtinRows) +
|
|
4068
|
-
section("Prompt templates", promptRows) +
|
|
4069
|
-
section("Skills", skillRows) +
|
|
4070
|
-
"
|
|
4134
|
+
const help = section(t("Built-in commands"), builtinRows) +
|
|
4135
|
+
section(t("Prompt templates"), promptRows) +
|
|
4136
|
+
section(t("Skills"), skillRows) +
|
|
4137
|
+
`\n${t("Type `/` for autocomplete. Use `/hotkeys` for keyboard shortcuts.")}`;
|
|
4071
4138
|
this.chatContainer.addChild(new Spacer(1));
|
|
4072
4139
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4073
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Available Commands")), 1, 0));
|
|
4140
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Available Commands"))), 1, 0));
|
|
4074
4141
|
this.chatContainer.addChild(new Markdown(help.trim(), 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4075
4142
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4076
4143
|
this.ui.requestRender();
|
|
@@ -4118,68 +4185,70 @@ export class InteractiveMode {
|
|
|
4118
4185
|
const pasteImage = this.getAppKeyDisplay("app.clipboard.pasteImage");
|
|
4119
4186
|
// Iron law (2026-10-01): these shipped defaults were cleared in favor of
|
|
4120
4187
|
// the /model command; the row only appears when a user re-configures a key.
|
|
4121
|
-
const selectModelRow = selectModel ? `| \`${selectModel}\` | Open model selector |\n` : "";
|
|
4188
|
+
const selectModelRow = selectModel ? `| \`${selectModel}\` | ${t("Open model selector")} |\n` : "";
|
|
4122
4189
|
// Iron law (2026-10-02 复审): ctrl+g/ctrl+x stay bound only for the
|
|
4123
4190
|
// components without a command channel — the main editor ignores them
|
|
4124
4191
|
// (/editor and /copy are its single entries), so the rows say where
|
|
4125
4192
|
// each key actually acts.
|
|
4126
|
-
const copyMessageRow = copyMessage ? `| \`${copyMessage}\` | Copy selection in /tree |\n` : "";
|
|
4193
|
+
const copyMessageRow = copyMessage ? `| \`${copyMessage}\` | ${t("Copy selection in /tree")} |\n` : "";
|
|
4127
4194
|
const externalEditorRow = externalEditor
|
|
4128
|
-
? `| \`${externalEditor}\` | External editor (inside dialog inputs) |\n`
|
|
4195
|
+
? `| \`${externalEditor}\` | ${t("External editor (inside dialog inputs)")} |\n`
|
|
4129
4196
|
: "";
|
|
4130
4197
|
// Iron law (2026-10-01): the message queue is the /queue and /dequeue
|
|
4131
4198
|
// 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
|
|
4199
|
+
const followUpRow = followUp ? `| \`${followUp}\` | ${t("Queue follow-up message")} |\n` : "";
|
|
4200
|
+
const dequeueRow = dequeue ? `| \`${dequeue}\` | ${t("Restore queued messages")} |\n` : "";
|
|
4201
|
+
const cycleThinkingRow = cycleThinkingLevel
|
|
4202
|
+
? `| \`${cycleThinkingLevel}\` | ${t("Cycle thinking level")} |\n`
|
|
4203
|
+
: "";
|
|
4135
4204
|
const cycleModelsRow = cycleModelForward || cycleModelBackward
|
|
4136
|
-
? `| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | Cycle models |\n`
|
|
4205
|
+
? `| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | ${t("Cycle models")} |\n`
|
|
4137
4206
|
: "";
|
|
4138
4207
|
// Suspend has no default key on native Windows; hide the row there.
|
|
4139
|
-
const suspendRow = suspend ? `| \`${suspend}\` | Suspend to background |\n` : "";
|
|
4208
|
+
const suspendRow = suspend ? `| \`${suspend}\` | ${t("Suspend to background")} |\n` : "";
|
|
4140
4209
|
const hotkeys = `
|
|
4141
|
-
|
|
4142
|
-
| Key | Action |
|
|
4210
|
+
**${t("Navigation")}**
|
|
4211
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4143
4212
|
|-----|--------|
|
|
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 |
|
|
4213
|
+
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | ${t("Move cursor / browse history")} |
|
|
4214
|
+
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | ${t("Move by word")} |
|
|
4215
|
+
| \`${cursorLineStart}\` | ${t("Start of line")} |
|
|
4216
|
+
| \`${cursorLineEnd}\` | ${t("End of line")} |
|
|
4217
|
+
| \`${jumpForward}\` | ${t("Jump forward to character")} |
|
|
4218
|
+
| \`${jumpBackward}\` | ${t("Jump backward to character")} |
|
|
4219
|
+
| \`${pageUp}\` / \`${pageDown}\` | ${t("Scroll by page")} |
|
|
4151
4220
|
|
|
4152
|
-
|
|
4153
|
-
| Key | Action |
|
|
4221
|
+
**${t("Editing")}**
|
|
4222
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4154
4223
|
|-----|--------|
|
|
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 |
|
|
4224
|
+
| \`${submit}\` | ${t("Send message")} |
|
|
4225
|
+
| \`${newLine}\` | ${process.platform === "win32" ? t("New line (Ctrl+Enter on Windows Terminal)") : t("New line")} |
|
|
4226
|
+
| \`${deleteWordBackward}\` | ${t("Delete word backwards")} |
|
|
4227
|
+
| \`${deleteWordForward}\` | ${t("Delete word forwards")} |
|
|
4228
|
+
| \`${deleteToLineStart}\` | ${t("Delete to start of line")} |
|
|
4229
|
+
| \`${deleteToLineEnd}\` | ${t("Delete to end of line")} |
|
|
4230
|
+
| \`${yank}\` | ${t("Paste the most-recently-deleted text")} |
|
|
4231
|
+
| \`${yankPop}\` | ${t("Cycle through the deleted text after pasting")} |
|
|
4232
|
+
| \`${undo}\` | ${t("Undo")} |
|
|
4164
4233
|
|
|
4165
|
-
|
|
4166
|
-
| Key | Action |
|
|
4234
|
+
**${t("Other")}**
|
|
4235
|
+
| ${t("Key")} | ${t("Action")} |
|
|
4167
4236
|
|-----|--------|
|
|
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 |
|
|
4237
|
+
| \`${tab}\` | ${t("Path completion / accept autocomplete")} |
|
|
4238
|
+
| \`${interrupt}\` | ${t("Cancel autocomplete / abort streaming")} |
|
|
4239
|
+
| \`${clear}\` | ${t("Clear editor (first) / exit (second)")} |
|
|
4240
|
+
| \`${exit}\` | ${t("Exit (when editor is empty)")} |
|
|
4241
|
+
${suspendRow}${cycleThinkingRow}${cycleModelsRow}${selectModelRow}| \`${expandTools}\` | ${t("Toggle tool output expansion")} |
|
|
4242
|
+
| \`${toggleThinking}\` | ${t("Toggle thinking block visibility")} |
|
|
4174
4243
|
${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) |
|
|
4244
|
+
| \`${pasteImage}\` | ${t("Paste image or text from clipboard")} |
|
|
4245
|
+
| \`/\` | ${t("Slash commands")} |
|
|
4246
|
+
| \`!\` | ${t("Run bash command")} |
|
|
4247
|
+
| \`!!\` | ${t("Run bash command (excluded from context)")} |
|
|
4179
4248
|
`;
|
|
4180
4249
|
this.chatContainer.addChild(new Spacer(1));
|
|
4181
4250
|
this.chatContainer.addChild(new DynamicBorder());
|
|
4182
|
-
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", "Keyboard Shortcuts")), 1, 0));
|
|
4251
|
+
this.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Keyboard Shortcuts"))), 1, 0));
|
|
4183
4252
|
this.chatContainer.addChild(new Spacer(1));
|
|
4184
4253
|
this.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 1, this.getMarkdownThemeWithSettings()));
|
|
4185
4254
|
this.chatContainer.addChild(new DynamicBorder());
|
|
@@ -4193,7 +4262,7 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4193
4262
|
return;
|
|
4194
4263
|
}
|
|
4195
4264
|
this.chatContainer.addChild(new Spacer(1));
|
|
4196
|
-
this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ New session started")}`, 1, 1));
|
|
4265
|
+
this.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ New session started"))}`, 1, 1));
|
|
4197
4266
|
this.ui.requestRender();
|
|
4198
4267
|
}
|
|
4199
4268
|
catch (error) {
|
|
@@ -4206,18 +4275,18 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4206
4275
|
const allLines = this.ui.render(width);
|
|
4207
4276
|
const debugLogPath = getDebugLogPath();
|
|
4208
4277
|
const debugData = [
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4278
|
+
t("Debug output at {date}", { date: new Date().toISOString() }),
|
|
4279
|
+
t("Terminal: {columns}x{rows}", { columns: width, rows: height }),
|
|
4280
|
+
t("Total lines: {count}", { count: allLines.length }),
|
|
4212
4281
|
"",
|
|
4213
|
-
"=== All rendered lines with visible widths ===",
|
|
4282
|
+
t("=== All rendered lines with visible widths ==="),
|
|
4214
4283
|
...allLines.map((line, idx) => {
|
|
4215
4284
|
const vw = visibleWidth(line);
|
|
4216
4285
|
const escaped = JSON.stringify(line);
|
|
4217
4286
|
return `[${idx}] (w=${vw}) ${escaped}`;
|
|
4218
4287
|
}),
|
|
4219
4288
|
"",
|
|
4220
|
-
"=== Agent messages (JSONL) ===",
|
|
4289
|
+
t("=== Agent messages (JSONL) ==="),
|
|
4221
4290
|
...this.facade
|
|
4222
4291
|
.getSessionAPI()
|
|
4223
4292
|
.getMessages()
|
|
@@ -4227,7 +4296,7 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4227
4296
|
fs.mkdirSync(path.dirname(debugLogPath), { recursive: true });
|
|
4228
4297
|
fs.writeFileSync(debugLogPath, debugData);
|
|
4229
4298
|
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));
|
|
4299
|
+
this.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ Debug log written"))}\n${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
4231
4300
|
this.ui.requestRender();
|
|
4232
4301
|
}
|
|
4233
4302
|
handleArminSaysHi() {
|
|
@@ -4277,7 +4346,9 @@ ${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
|
4277
4346
|
if (this.bashComponent) {
|
|
4278
4347
|
this.bashComponent.setComplete(undefined, false);
|
|
4279
4348
|
}
|
|
4280
|
-
this.showError(
|
|
4349
|
+
this.showError(t("Bash command failed: {error}", {
|
|
4350
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
4351
|
+
}));
|
|
4281
4352
|
}
|
|
4282
4353
|
this.bashComponent = undefined;
|
|
4283
4354
|
this.ui.requestRender();
|