@ai-agent-forge/agent-forge 0.88.1 → 0.88.3
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 +71 -0
- package/README.md +1 -1
- package/bundled-plugins/agent-loop-policy/agent-forge.json +1 -1
- package/bundled-plugins/agent-loop-policy/plugin.json +1 -1
- package/bundled-plugins/coding-tools/agent-forge.json +1 -1
- package/bundled-plugins/coding-tools/plugin.json +1 -1
- package/bundled-plugins/compaction-policy/agent-forge.json +1 -1
- package/bundled-plugins/compaction-policy/plugin.json +1 -1
- package/bundled-plugins/overflow-policy/agent-forge.json +1 -1
- package/bundled-plugins/overflow-policy/plugin.json +1 -1
- package/bundled-plugins/provider-failover/agent-forge.json +1 -1
- package/bundled-plugins/provider-failover/plugin.json +1 -1
- package/bundled-plugins/retry-policy/agent-forge.json +1 -1
- package/bundled-plugins/retry-policy/plugin.json +1 -1
- package/dist/artifacts/paged-read.d.ts +6 -1
- package/dist/artifacts/paged-read.d.ts.map +1 -1
- package/dist/artifacts/paged-read.js.map +1 -1
- package/dist/bundle/.build-manifest.json +283 -263
- package/dist/bundle/chunks/{anthropic-messages-PLAKXR73.js → anthropic-messages-3FJHRAJL.js} +2 -2
- package/dist/bundle/chunks/anthropic.js +1 -1
- package/dist/bundle/chunks/{azure-openai-responses-OUWQ2AZD.js → azure-openai-responses-GCL47IDS.js} +1 -1
- package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
- package/dist/bundle/chunks/{chunk-Z72JWUZ4.js → chunk-32YDZI4J.js} +1 -1
- package/dist/bundle/chunks/{chunk-AQLNTW2B.js → chunk-755VNWIF.js} +17 -16
- package/dist/bundle/chunks/{chunk-LZOEQITZ.js → chunk-B42Y2VME.js} +120 -104
- package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-BVVSHK6W.js} +1 -1
- package/dist/bundle/chunks/{chunk-6R7UI4IY.js → chunk-QDLOMKF6.js} +1 -1
- package/dist/bundle/chunks/{chunk-D3ARGZFR.js → chunk-V3ACW7VD.js} +3 -3
- package/dist/bundle/chunks/{google-generative-ai-DLII6DAT.js → google-generative-ai-6BMXWA44.js} +1 -1
- package/dist/bundle/chunks/{google-vertex-G7BZL7GM.js → google-vertex-6H7NLRTK.js} +1 -1
- package/dist/bundle/chunks/image-resize-worker.js +3 -3
- package/dist/bundle/chunks/{mistral-conversations-JXUK24ID.js → mistral-conversations-IXUHSFSJ.js} +1 -1
- package/dist/bundle/chunks/{openai-codex-responses-5GSGFIPG.js → openai-codex-responses-YHUAEVCM.js} +1 -1
- package/dist/bundle/chunks/openai-codex.js +1 -1
- package/dist/bundle/chunks/{openai-completions-EI2I6DTG.js → openai-completions-ULQCFC72.js} +1 -1
- package/dist/bundle/chunks/openai-responses-NLLAJDPS.js +2 -0
- package/dist/bundle/chunks/{openrouter-images-G4GQRUSG.js → openrouter-images-GZZQZXMS.js} +1 -1
- package/dist/bundle/chunks/openrouter.js +1 -1
- package/dist/bundle/chunks/{pi-messages-PWU2VJMR.js → pi-messages-EJTI2EJ3.js} +1 -1
- package/dist/bundle/chunks/virtual-modules-TQWEGNNZ.js +5 -0
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/client.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/cli/args.d.ts +0 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/experimental/cli.d.ts +3 -3
- package/dist/cli/experimental/cli.d.ts.map +1 -1
- package/dist/cli/experimental/cli.js +2 -2
- package/dist/cli/experimental/cli.js.map +1 -1
- package/dist/cli/experimental/commands/agent-forge.d.ts +15 -0
- package/dist/cli/experimental/commands/agent-forge.d.ts.map +1 -0
- package/dist/cli/experimental/commands/{pi.js → agent-forge.js} +4 -4
- package/dist/cli/experimental/commands/agent-forge.js.map +1 -0
- package/dist/cli/plugin-command.d.ts.map +1 -1
- package/dist/cli/plugin-command.js +8 -2
- package/dist/cli/plugin-command.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts +4 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -7
- package/dist/config.js.map +1 -1
- package/dist/core/agent-forge-manifest.d.ts +7 -0
- package/dist/core/agent-forge-manifest.d.ts.map +1 -0
- package/dist/core/{pi-manifest.js → agent-forge-manifest.js} +4 -4
- package/dist/core/agent-forge-manifest.js.map +1 -0
- package/dist/core/agent-session-compaction.d.ts +1 -1
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +3 -3
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-internal.d.ts +2 -0
- 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-lifecycle.d.ts.map +1 -1
- package/dist/core/agent-session-lifecycle.js +12 -1
- package/dist/core/agent-session-lifecycle.js.map +1 -1
- package/dist/core/agent-session-projection.d.ts.map +1 -1
- package/dist/core/agent-session-projection.js +3 -3
- package/dist/core/agent-session-projection.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +3 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-store.d.ts.map +1 -1
- package/dist/core/agent-session-store.js +6 -1
- package/dist/core/agent-session-store.js.map +1 -1
- package/dist/core/agent-session-tools.d.ts.map +1 -1
- package/dist/core/agent-session-tools.js +13 -0
- package/dist/core/agent-session-tools.js.map +1 -1
- package/dist/core/agent-session.d.ts +24 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +58 -4
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +1 -1
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +1 -3
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/capability-runtime-store.d.ts +20 -1
- package/dist/core/extensions/capability-runtime-store.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-store.js +67 -0
- package/dist/core/extensions/capability-runtime-store.js.map +1 -1
- package/dist/core/extensions/capability-runtime-types.d.ts +14 -0
- package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime-types.js +7 -1
- package/dist/core/extensions/capability-runtime-types.js.map +1 -1
- package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
- package/dist/core/extensions/capability-runtime.js +144 -42
- package/dist/core/extensions/capability-runtime.js.map +1 -1
- package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/virtual-modules.js +6 -1
- package/dist/core/extensions/virtual-modules.js.map +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts +1 -1
- package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
- package/dist/core/facade/coding-agent-facade.js +1 -1
- package/dist/core/facade/coding-agent-facade.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/cli.js +2 -0
- package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js +3 -3
- package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +1 -1
- package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js +1 -1
- package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/index.js +2 -0
- package/dist/core/i18n/locales/zh-cn/index.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js +5 -0
- package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts +7 -0
- package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts.map +1 -0
- package/dist/core/i18n/locales/zh-cn/session-cleanup.js +15 -0
- package/dist/core/i18n/locales/zh-cn/session-cleanup.js.map +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/slash-commands.js +1 -0
- package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -1
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +2 -0
- package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +4 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-resource-collection.d.ts.map +1 -1
- package/dist/core/package-resource-collection.js +5 -5
- package/dist/core/package-resource-collection.js.map +1 -1
- package/dist/core/provider-composer.d.ts.map +1 -1
- package/dist/core/provider-composer.js +3 -3
- package/dist/core/provider-composer.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +1 -1
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +30 -8
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-cleanup.d.ts +49 -0
- package/dist/core/session-cleanup.d.ts.map +1 -0
- package/dist/core/session-cleanup.js +159 -0
- package/dist/core/session-cleanup.js.map +1 -0
- package/dist/core/session-index.d.ts +75 -0
- package/dist/core/session-index.d.ts.map +1 -0
- package/dist/core/session-index.js +455 -0
- package/dist/core/session-index.js.map +1 -0
- package/dist/core/session-manager.d.ts +9 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +206 -51
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +5 -10
- 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 +5 -0
- 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 +12 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +1 -3
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/capability-mount.d.ts +40 -0
- package/dist/core/tools/capability-mount.d.ts.map +1 -0
- package/dist/core/tools/capability-mount.js +112 -0
- package/dist/core/tools/capability-mount.js.map +1 -0
- package/dist/core/tools/render-utils.d.ts +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/tool-definition.d.ts +1 -1
- package/dist/core/tools/tool-definition.d.ts.map +1 -1
- package/dist/core/tools/tool-definition.js.map +1 -1
- package/dist/core/trace-retention.d.ts +16 -1
- package/dist/core/trace-retention.d.ts.map +1 -1
- package/dist/core/trace-retention.js +43 -20
- package/dist/core/trace-retention.js.map +1 -1
- package/dist/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/export-html/ansi-to-html.js.map +1 -0
- package/dist/{core/export-html → export-html}/index.d.ts +1 -1
- package/dist/export-html/index.d.ts.map +1 -0
- package/dist/{core/export-html → export-html}/index.js +5 -5
- package/dist/export-html/index.js.map +1 -0
- package/dist/{core/export-html → export-html}/tool-renderer.d.ts +2 -2
- package/dist/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/export-html/tool-renderer.js.map +1 -0
- package/dist/{modes/interactive → host}/model-catalog-refresh.d.ts +1 -1
- package/dist/host/model-catalog-refresh.d.ts.map +1 -0
- package/dist/{modes/interactive → host}/model-catalog-refresh.js +1 -1
- package/dist/host/model-catalog-refresh.js.map +1 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +26 -14
- 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 +1 -1
- package/dist/modes/interactive/components/agents-view.js.map +1 -1
- package/dist/modes/interactive/components/armin.d.ts.map +1 -1
- package/dist/modes/interactive/components/armin.js +1 -1
- package/dist/modes/interactive/components/armin.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +6 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +108 -27
- 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 +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
- package/dist/modes/interactive/components/daxnuts.js +1 -1
- package/dist/modes/interactive/components/daxnuts.js.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/dialog-editor.js +1 -1
- 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 +1 -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 +1 -1
- package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
- package/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/dist/modes/interactive/components/diff.js +1 -1
- package/dist/modes/interactive/components/diff.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +1 -1
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +1 -1
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +1 -1
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts +1 -1
- package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
- 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 +2 -2
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.js +1 -1
- package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -1
- package/dist/modes/interactive/components/render-types.d.ts +1 -1
- package/dist/modes/interactive/components/render-types.d.ts.map +1 -1
- package/dist/modes/interactive/components/render-types.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +5 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +11 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -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 +1 -1
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +19 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +139 -4
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.d.ts +44 -0
- package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-run-group.js +121 -0
- package/dist/modes/interactive/components/tool-run-group.js.map +1 -0
- package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-list.js +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +1 -1
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
- package/dist/modes/interactive/components/workflow-view.js +1 -1
- package/dist/modes/interactive/components/workflow-view.js.map +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts +1 -1
- package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-auth.js +1 -1
- package/dist/modes/interactive/interactive-auth.js.map +1 -1
- package/dist/modes/interactive/interactive-commands.d.ts +125 -6
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +698 -4
- package/dist/modes/interactive/interactive-commands.js.map +1 -1
- package/dist/modes/interactive/interactive-events.d.ts +174 -0
- package/dist/modes/interactive/interactive-events.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-events.js +704 -0
- package/dist/modes/interactive/interactive-events.js.map +1 -0
- package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-format.js +1 -1
- package/dist/modes/interactive/interactive-format.js.map +1 -1
- package/dist/modes/interactive/interactive-lifecycle.d.ts +94 -0
- package/dist/modes/interactive/interactive-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-lifecycle.js +177 -0
- package/dist/modes/interactive/interactive-lifecycle.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +254 -129
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +275 -2101
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/interactive-queues.d.ts +96 -0
- package/dist/modes/interactive/interactive-queues.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-queues.js +183 -0
- package/dist/modes/interactive/interactive-queues.js.map +1 -0
- package/dist/modes/interactive/interactive-selectors.d.ts +95 -5
- package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +517 -6
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/startup-services.d.ts +31 -0
- package/dist/modes/interactive/startup-services.d.ts.map +1 -0
- package/dist/modes/interactive/startup-services.js +123 -0
- package/dist/modes/interactive/startup-services.js.map +1 -0
- package/dist/modes/memory-preheat.d.ts +11 -0
- package/dist/modes/memory-preheat.d.ts.map +1 -0
- package/dist/modes/memory-preheat.js +20 -0
- package/dist/modes/memory-preheat.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +3 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
- package/dist/plugins/ecosystem/cli.js +6 -3
- package/dist/plugins/ecosystem/cli.js.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +7 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js +50 -3
- package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +28 -16
- package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
- package/dist/plugins/ecosystem/plugin-bootstrap.js +35 -33
- package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
- package/dist/profile/plugin-profiles.d.ts +1 -1
- package/dist/profile/plugin-profiles.d.ts.map +1 -1
- package/dist/profile/plugin-profiles.js +18 -0
- package/dist/profile/plugin-profiles.js.map +1 -1
- package/dist/remote/server-assembly.d.ts.map +1 -1
- package/dist/remote/server-assembly.js +7 -2
- package/dist/remote/server-assembly.js.map +1 -1
- package/dist/{profiles → suites}/builtin-suites.d.ts +14 -4
- package/dist/suites/builtin-suites.d.ts.map +1 -0
- package/dist/{profiles → suites}/builtin-suites.js +20 -5
- package/dist/suites/builtin-suites.js.map +1 -0
- package/dist/suites/resolved-agent-profile.d.ts.map +1 -0
- package/dist/suites/resolved-agent-profile.js.map +1 -0
- package/dist/suites/suite-lifecycle.d.ts.map +1 -0
- package/dist/suites/suite-lifecycle.js.map +1 -0
- package/dist/suites/suite-loader.d.ts.map +1 -0
- package/dist/suites/suite-loader.js.map +1 -0
- package/dist/{modes/interactive/theme → theme}/dark.json +1 -1
- package/dist/{modes/interactive/theme → theme}/light.json +1 -1
- package/dist/{modes/interactive/theme → theme}/theme-controller.d.ts +1 -1
- package/dist/theme/theme-controller.d.ts.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme-controller.js +1 -1
- package/dist/theme/theme-controller.js.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme.d.ts +1 -1
- package/dist/theme/theme.d.ts.map +1 -0
- package/dist/{modes/interactive/theme → theme}/theme.js +5 -5
- package/dist/theme/theme.js.map +1 -0
- package/docs/compaction.md +7 -7
- package/docs/environment-variables.md +10 -4
- package/docs/keybindings.md +3 -3
- package/docs/models.md +17 -17
- package/docs/packages.md +1 -1
- package/docs/prompt-templates.md +1 -1
- package/docs/rpc.md +2 -2
- package/docs/sdk.md +5 -5
- package/docs/session-format.md +3 -3
- package/docs/settings.md +368 -354
- package/docs/shell-aliases.md +1 -1
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +17 -17
- package/docs/themes.md +5 -5
- package/docs/tmux.md +4 -4
- package/docs/tui.md +1 -1
- package/docs/windows.md +1 -1
- package/examples/extensions/bash-spawn-hook/index.ts +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -6
- package/examples/extensions/with-deps/plugin.json +1 -1
- package/package.json +2 -2
- package/dist/bundle/chunks/openai-responses-AUJQ3NWT.js +0 -2
- package/dist/bundle/chunks/virtual-modules-WF6WRHP7.js +0 -5
- package/dist/cli/experimental/commands/pi.d.ts +0 -15
- package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
- package/dist/cli/experimental/commands/pi.js.map +0 -1
- package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
- package/dist/core/export-html/ansi-to-html.js.map +0 -1
- package/dist/core/export-html/index.d.ts.map +0 -1
- package/dist/core/export-html/index.js.map +0 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
- package/dist/core/export-html/tool-renderer.js.map +0 -1
- package/dist/core/pi-manifest.d.ts +0 -7
- package/dist/core/pi-manifest.d.ts.map +0 -1
- package/dist/core/pi-manifest.js.map +0 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +0 -1
- package/dist/modes/interactive/model-catalog-refresh.js.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
- package/dist/modes/interactive/theme/theme.js.map +0 -1
- package/dist/profiles/builtin-suites.d.ts.map +0 -1
- package/dist/profiles/builtin-suites.js.map +0 -1
- package/dist/profiles/resolved-agent-profile.d.ts.map +0 -1
- package/dist/profiles/resolved-agent-profile.js.map +0 -1
- package/dist/profiles/suite-lifecycle.d.ts.map +0 -1
- package/dist/profiles/suite-lifecycle.js.map +0 -1
- package/dist/profiles/suite-loader.d.ts.map +0 -1
- package/dist/profiles/suite-loader.js.map +0 -1
- package/dist/utils/deprecation.d.ts +0 -4
- package/dist/utils/deprecation.d.ts.map +0 -1
- package/dist/utils/deprecation.js +0 -13
- package/dist/utils/deprecation.js.map +0 -1
- /package/dist/{core/export-html → export-html}/ansi-to-html.d.ts +0 -0
- /package/dist/{core/export-html → export-html}/ansi-to-html.js +0 -0
- /package/dist/{core/export-html → export-html}/template.css +0 -0
- /package/dist/{core/export-html → export-html}/template.html +0 -0
- /package/dist/{core/export-html → export-html}/template.js +0 -0
- /package/dist/{core/export-html → export-html}/tool-renderer.js +0 -0
- /package/dist/{core/export-html → export-html}/vendor/highlight.min.js +0 -0
- /package/dist/{core/export-html → export-html}/vendor/marked.min.js +0 -0
- /package/dist/{profiles → suites}/resolved-agent-profile.d.ts +0 -0
- /package/dist/{profiles → suites}/resolved-agent-profile.js +0 -0
- /package/dist/{profiles → suites}/suite-lifecycle.d.ts +0 -0
- /package/dist/{profiles → suites}/suite-lifecycle.js +0 -0
- /package/dist/{profiles → suites}/suite-loader.d.ts +0 -0
- /package/dist/{profiles → suites}/suite-loader.js +0 -0
- /package/dist/{modes/interactive/theme → theme}/theme-schema.json +0 -0
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Slash-command dispatch table for the interactive mode editor submit handler
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Slash-command dispatch table for the interactive mode editor submit handler,
|
|
3
|
+
* plus the command-handler implementations behind it (拆分 slice 1).
|
|
4
|
+
*
|
|
5
|
+
* The dispatch table was extracted from InteractiveMode.setupEditorSubmitHandler;
|
|
6
|
+
* entry order mirrors the original if-chain and each run body mirrors its
|
|
7
|
+
* branch verbatim (await/no-await and editor clearing order included). The
|
|
8
|
+
* handler functions below were moved verbatim out of InteractiveMode (拆分
|
|
9
|
+
* slice 1, docs/plans/interactive-mode拆分计划.md); the mode keeps same-name
|
|
10
|
+
* delegate methods so prototype-level tests and the dispatch table keep
|
|
11
|
+
* working.
|
|
6
12
|
*/
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { Container, Markdown, Spacer, Text, TuiAltScreen, visibleWidth } from "@agent-forge/tui";
|
|
16
|
+
import { getDebugLogPath } from "../../config.js";
|
|
17
|
+
import { SessionImportFileNotFoundError } from "../../core/agent-session-runtime.js";
|
|
18
|
+
import { computeCacheWaste } from "../../core/cache-stats.js";
|
|
19
|
+
import { t } from "../../core/i18n/index.js";
|
|
20
|
+
import { runCleanSessions } from "../../core/session-cleanup.js";
|
|
21
|
+
import { MissingSessionCwdError } from "../../core/session-cwd.js";
|
|
22
|
+
import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
|
|
23
|
+
import { getUsageCostBreakdown } from "../../core/usage-totals.js";
|
|
24
|
+
import { loadThemeFromPath, setRegisteredThemes, theme } from "../../theme/theme.js";
|
|
25
|
+
import { getChangelogPath, normalizeChangelogLinks, parseChangelog } from "../../utils/changelog.js";
|
|
26
|
+
import { copyToClipboard } from "../../utils/clipboard.js";
|
|
27
|
+
import { ArminComponent } from "./components/armin.js";
|
|
28
|
+
import { BashExecutionComponent } from "./components/bash-execution.js";
|
|
29
|
+
import { DaxnutsComponent } from "./components/daxnuts.js";
|
|
30
|
+
import { DynamicBorder } from "./components/dynamic-border.js";
|
|
31
|
+
import { formatTokens } from "./components/footer.js";
|
|
32
|
+
import { keyDisplayText } from "./components/keybinding-hints.js";
|
|
33
|
+
import { isExpandable } from "./interactive-dialog-ui.js";
|
|
34
|
+
import { formatMetricsSnapshot } from "./interactive-format.js";
|
|
7
35
|
export const COMMAND_DISPATCH_ENTRIES = [
|
|
8
36
|
{
|
|
9
37
|
command: "/settings",
|
|
@@ -127,6 +155,13 @@ export const COMMAND_DISPATCH_ENTRIES = [
|
|
|
127
155
|
clearEditorBeforeRun: true,
|
|
128
156
|
run: (host, _text, arg) => host.handleCompactCommand(arg),
|
|
129
157
|
},
|
|
158
|
+
{
|
|
159
|
+
command: "/clean-sessions",
|
|
160
|
+
argOffset: 16,
|
|
161
|
+
blankArgToUndefined: true,
|
|
162
|
+
clearEditorBeforeRun: true,
|
|
163
|
+
run: (host, _text, arg) => host.handleCleanSessionsCommand(arg),
|
|
164
|
+
},
|
|
130
165
|
{ command: "/reload", clearEditorBeforeRun: true, run: (host) => host.handleReloadCommand() },
|
|
131
166
|
{
|
|
132
167
|
command: "/debug",
|
|
@@ -213,4 +248,663 @@ export function filterCapabilityCommandsForCompletions(capabilityCommands, reser
|
|
|
213
248
|
...(command.argumentHint !== undefined ? { argumentHint: command.argumentHint } : {}),
|
|
214
249
|
}));
|
|
215
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Rebuilds real Theme instances from the resource loader's ThemeMetaV1
|
|
253
|
+
* projection for the theme registry (B-S2b v1). Registration points
|
|
254
|
+
* (constructor, runtime session start, reload) need loadable instances —
|
|
255
|
+
* setRegisteredThemes stores what it is given and getThemeByName returns the
|
|
256
|
+
* registered instance first — while the loader surface now projects only
|
|
257
|
+
* metadata. Re-loading is synchronous and deterministic per sourcePath;
|
|
258
|
+
* theme names come from the same JSON the loader parsed, so meta.name ===
|
|
259
|
+
* Theme.name and the registry keeps its own name-filter/dedupe semantics.
|
|
260
|
+
*
|
|
261
|
+
* Contract: a meta without a sourcePath (or one whose file no longer parses)
|
|
262
|
+
* throws — themesOverride host inputs must always carry a loadable
|
|
263
|
+
* sourcePath. This adds one extra parse per theme at registration time
|
|
264
|
+
* (constructor / session start / reload, not per turn).
|
|
265
|
+
*
|
|
266
|
+
* Re-exported from ./interactive-mode.ts for existing consumers of that module.
|
|
267
|
+
*/
|
|
268
|
+
export function buildRegisteredThemes(themes) {
|
|
269
|
+
return themes.map((meta) => loadThemeFromPath(meta.sourcePath));
|
|
270
|
+
}
|
|
271
|
+
export async function handleReloadCommand(host) {
|
|
272
|
+
if (host.facade.isStreaming()) {
|
|
273
|
+
host.showWarning(t("Wait for the current response to finish before reloading."));
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (host.facade.isCompacting()) {
|
|
277
|
+
host.showWarning(t("Wait for compaction to finish before reloading."));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
host.resetDialogUI();
|
|
281
|
+
const reloadBox = new Container();
|
|
282
|
+
const borderColor = (s) => theme.fg("border", s);
|
|
283
|
+
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
284
|
+
reloadBox.addChild(new Spacer(1));
|
|
285
|
+
reloadBox.addChild(new Text(theme.fg("muted", t("Reloading keybindings, skills, prompts, themes, and context files...")), 1, 0));
|
|
286
|
+
reloadBox.addChild(new Spacer(1));
|
|
287
|
+
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
288
|
+
const previousEditor = host.editor;
|
|
289
|
+
host.editorContainer.clear();
|
|
290
|
+
host.editorContainer.addChild(reloadBox);
|
|
291
|
+
host.ui.setFocus(reloadBox);
|
|
292
|
+
host.ui.requestRender(true);
|
|
293
|
+
await new Promise((resolve) => process.nextTick(resolve));
|
|
294
|
+
const dismissReloadBox = (editor) => {
|
|
295
|
+
host.editorContainer.clear();
|
|
296
|
+
host.editorContainer.addChild(editor);
|
|
297
|
+
host.ui.setFocus(editor);
|
|
298
|
+
host.ui.requestRender();
|
|
299
|
+
};
|
|
300
|
+
let chatRestoredBeforeSessionStart = false;
|
|
301
|
+
let reloadBoxDismissed = false;
|
|
302
|
+
const restoreChatBeforeSessionStart = () => {
|
|
303
|
+
if (chatRestoredBeforeSessionStart) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
host.hideThinkingBlock = host.settingsManager.getHideThinkingBlock();
|
|
307
|
+
host.outputPad = host.settingsManager.getOutputPad();
|
|
308
|
+
host.rebuildChatFromMessages();
|
|
309
|
+
chatRestoredBeforeSessionStart = true;
|
|
310
|
+
};
|
|
311
|
+
try {
|
|
312
|
+
await host.facade.reload({ beforeSessionStart: restoreChatBeforeSessionStart });
|
|
313
|
+
restoreChatBeforeSessionStart();
|
|
314
|
+
host.keybindings.reload();
|
|
315
|
+
const activeHeader = host.builtInHeader;
|
|
316
|
+
if (isExpandable(activeHeader)) {
|
|
317
|
+
activeHeader.setExpanded(host.toolOutputExpanded);
|
|
318
|
+
}
|
|
319
|
+
setRegisteredThemes(buildRegisteredThemes(host.facade.getThemes().themes));
|
|
320
|
+
host.applyRuntimeSettings();
|
|
321
|
+
await host.themeController.applyFromSettings();
|
|
322
|
+
host.setupAutocompleteProvider();
|
|
323
|
+
host.showLoadedResources({
|
|
324
|
+
force: false,
|
|
325
|
+
showDiagnosticsWhenQuiet: true,
|
|
326
|
+
});
|
|
327
|
+
const modelsJsonError = host.facade.getModelsError();
|
|
328
|
+
if (modelsJsonError) {
|
|
329
|
+
host.showError(t("models.json error: {error}", { error: modelsJsonError }));
|
|
330
|
+
}
|
|
331
|
+
host.showStatus(t("Reloaded keybindings, skills, prompts, themes, and context files"));
|
|
332
|
+
dismissReloadBox(host.editor);
|
|
333
|
+
reloadBoxDismissed = true;
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
// v8 ignore next -- reloadBoxDismissed 置位后 catch 前无可抛出点,恒走 dismiss 分支
|
|
337
|
+
if (!reloadBoxDismissed) {
|
|
338
|
+
dismissReloadBox(previousEditor);
|
|
339
|
+
}
|
|
340
|
+
host.showError(t("Reload failed: {error}", { error: error instanceof Error ? error.message : String(error) }));
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
export async function handleExportCommand(host, text) {
|
|
344
|
+
const outputPath = getPathCommandArgument(text, "/export");
|
|
345
|
+
try {
|
|
346
|
+
if (outputPath?.endsWith(".jsonl")) {
|
|
347
|
+
const filePath = host.facade.exportToJsonl(outputPath);
|
|
348
|
+
host.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
const filePath = await host.facade.exportToHtml(outputPath, {
|
|
352
|
+
themeName: theme.name,
|
|
353
|
+
});
|
|
354
|
+
host.showStatus(t("Session exported to: {path}", { path: filePath }));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
host.showError(t("Failed to export session: {error}", {
|
|
359
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
360
|
+
}));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
export function getPathCommandArgument(text, command) {
|
|
364
|
+
if (text === command) {
|
|
365
|
+
return undefined;
|
|
366
|
+
}
|
|
367
|
+
if (!text.startsWith(`${command} `)) {
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
const argsString = text.slice(command.length + 1).trimStart();
|
|
371
|
+
if (!argsString) {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
374
|
+
const firstChar = argsString[0];
|
|
375
|
+
if (firstChar === '"' || firstChar === "'") {
|
|
376
|
+
const closingQuoteIndex = argsString.indexOf(firstChar, 1);
|
|
377
|
+
if (closingQuoteIndex < 0) {
|
|
378
|
+
return undefined;
|
|
379
|
+
}
|
|
380
|
+
return argsString.slice(1, closingQuoteIndex);
|
|
381
|
+
}
|
|
382
|
+
const firstWhitespaceIndex = argsString.search(/\s/);
|
|
383
|
+
if (firstWhitespaceIndex < 0) {
|
|
384
|
+
return argsString;
|
|
385
|
+
}
|
|
386
|
+
return argsString.slice(0, firstWhitespaceIndex);
|
|
387
|
+
}
|
|
388
|
+
export async function handleImportCommand(host, text) {
|
|
389
|
+
const inputPath = getPathCommandArgument(text, "/import");
|
|
390
|
+
if (!inputPath) {
|
|
391
|
+
host.showError(t("Usage: /import <path.jsonl>"));
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const confirmed = await host.showDialogConfirm(t("Import session"), t("Replace current session with {path}?", { path: inputPath }));
|
|
395
|
+
if (!confirmed) {
|
|
396
|
+
host.showStatus(t("Import cancelled"));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
host.clearStatusIndicator();
|
|
401
|
+
const result = await host.runtimeFacade.importFromJsonl(inputPath);
|
|
402
|
+
if (result.cancelled) {
|
|
403
|
+
host.showStatus(t("Import cancelled"));
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
host.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
if (error instanceof MissingSessionCwdError) {
|
|
410
|
+
const selectedCwd = await host.promptForMissingSessionCwd(error);
|
|
411
|
+
if (!selectedCwd) {
|
|
412
|
+
host.showStatus(t("Import cancelled"));
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
const result = await host.runtimeFacade.importFromJsonl(inputPath, selectedCwd);
|
|
416
|
+
if (result.cancelled) {
|
|
417
|
+
host.showStatus(t("Import cancelled"));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
host.showStatus(t("Session imported from: {path}", { path: inputPath }));
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (error instanceof SessionImportFileNotFoundError) {
|
|
424
|
+
host.showError(t("Failed to import session: {error}", { error: error.message }));
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
await host.handleFatalRuntimeError(t("Failed to import session"), error);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
export async function handleCopyCommand(host, options = {}) {
|
|
431
|
+
if (options.preferSelection &&
|
|
432
|
+
host.ui instanceof TuiAltScreen &&
|
|
433
|
+
!host.ui.getCopyOnSelect() &&
|
|
434
|
+
host.ui.hasActiveSelection()) {
|
|
435
|
+
await host.ui.copyActiveSelectionToClipboard();
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
const text = host.facade.getLastAssistantText();
|
|
439
|
+
if (!text) {
|
|
440
|
+
host.showError(t("No agent messages to copy yet."));
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
try {
|
|
444
|
+
await copyToClipboard(text);
|
|
445
|
+
if (options.flashConfirmation && host.ui instanceof TuiAltScreen) {
|
|
446
|
+
host.ui.flash(t("Copied!"));
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
host.showStatus(t("Copied last agent message to clipboard"));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (error) {
|
|
453
|
+
host.showError(error instanceof Error ? error.message : String(error));
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
export function handleNameCommand(host, text) {
|
|
457
|
+
const name = text.replace(/^\/name\s*/, "").trim();
|
|
458
|
+
if (!name) {
|
|
459
|
+
const currentName = host.facade.getSessionName();
|
|
460
|
+
if (currentName) {
|
|
461
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
462
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", t("Session name: {name}", { name: currentName })), 1, 0));
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
host.showWarning(t("Usage: /name <name>"));
|
|
466
|
+
}
|
|
467
|
+
host.ui.requestRender();
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
host.facade.setSessionName(name);
|
|
471
|
+
const sessionName = host.facade.getSessionName();
|
|
472
|
+
if (sessionName !== name) {
|
|
473
|
+
host.showWarning(t("Session name was normalized from {from} to {to}", {
|
|
474
|
+
from: JSON.stringify(name),
|
|
475
|
+
to: JSON.stringify(sessionName),
|
|
476
|
+
}));
|
|
477
|
+
}
|
|
478
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
479
|
+
host.chatContainer.addChild(new Text(theme.fg("dim", t("Session name set: {name}", { name: sessionName ?? name })), 1, 0));
|
|
480
|
+
host.ui.requestRender();
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* 中断分级(设计 子代理运行时 §4.2,2026-10-02):/stop-agents 的唯一执行
|
|
484
|
+
* 面——终止全部后台子代理(不触当前回合)。Esc 从不做这件事。
|
|
485
|
+
*/
|
|
486
|
+
export function handleStopAgentsCommand(host) {
|
|
487
|
+
const active = host.facade.getActiveAgentTaskCount();
|
|
488
|
+
if (active === 0) {
|
|
489
|
+
host.showStatus(t("No background subagents running"));
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
host.facade.abortAgentTasks();
|
|
493
|
+
host.showStatus(active === 1
|
|
494
|
+
? t("Terminated {count} background subagent", { count: active })
|
|
495
|
+
: t("Terminated {count} background subagents", { count: active }));
|
|
496
|
+
}
|
|
497
|
+
export function handleSessionCommand(host) {
|
|
498
|
+
const stats = host.facade.getSessionStats();
|
|
499
|
+
const sessionName = host.facade.getSessionName();
|
|
500
|
+
const entries = host.facade.getEntries();
|
|
501
|
+
const cacheWaste = computeCacheWaste(entries, host.facade.getModelPriceSource());
|
|
502
|
+
// Cost/token totals per provider/model actually used (e.g. OpenRouter `auto`
|
|
503
|
+
// resolves to a concrete responseModel). Usage without model attribution is
|
|
504
|
+
// grouped separately so the breakdown reconciles with the session total.
|
|
505
|
+
const usageBreakdown = getUsageCostBreakdown(entries);
|
|
506
|
+
let info = `${theme.bold(t("Session Info"))}\n\n`;
|
|
507
|
+
if (sessionName) {
|
|
508
|
+
info += `${theme.fg("dim", t("Name:"))} ${sessionName}\n`;
|
|
509
|
+
}
|
|
510
|
+
info += `${theme.fg("dim", t("File:"))} ${stats.sessionFile ?? t("In-memory")}\n`;
|
|
511
|
+
info += `${theme.fg("dim", t("ID:"))} ${stats.sessionId}\n\n`;
|
|
512
|
+
info += `${theme.bold(t("Messages"))}\n`;
|
|
513
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.totalMessages}\n`;
|
|
514
|
+
info += `${theme.fg("dim", t("User:"))} ${stats.userMessages}\n`;
|
|
515
|
+
info += `${theme.fg("dim", t("Assistant:"))} ${stats.assistantMessages}\n`;
|
|
516
|
+
info += `${theme.fg("dim", t("Tools:"))} ${t("{calls} calls, {results} results", {
|
|
517
|
+
calls: stats.toolCalls,
|
|
518
|
+
results: stats.toolResults,
|
|
519
|
+
})}\n\n`;
|
|
520
|
+
info += `${theme.bold(t("Tokens"))}\n`;
|
|
521
|
+
// "Input" is the full prompt volume. With cache activity, split it into
|
|
522
|
+
// cached (served from cache) vs uncached (everything else) - the only
|
|
523
|
+
// provider-independent split. Cache writes, where reported, are a detail
|
|
524
|
+
// of the uncached portion.
|
|
525
|
+
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
526
|
+
const promptTokens = input + cacheRead + cacheWrite;
|
|
527
|
+
info += `${theme.fg("dim", t("Input:"))} ${promptTokens.toLocaleString()}\n`;
|
|
528
|
+
if (promptTokens > 0 && (cacheRead > 0 || cacheWrite > 0)) {
|
|
529
|
+
const hitRate = theme.fg("dim", `(${((cacheRead / promptTokens) * 100).toFixed(1)}%)`);
|
|
530
|
+
info += ` ${theme.fg("dim", t("Cached:"))} ${cacheRead.toLocaleString()} ${hitRate}\n`;
|
|
531
|
+
const written = cacheWrite > 0
|
|
532
|
+
? ` ${theme.fg("dim", t("({count} written to cache)", { count: cacheWrite.toLocaleString() }))}`
|
|
533
|
+
: "";
|
|
534
|
+
info += ` ${theme.fg("dim", t("Uncached:"))} ${(input + cacheWrite).toLocaleString()}${written}\n`;
|
|
535
|
+
}
|
|
536
|
+
info += `${theme.fg("dim", t("Output:"))} ${stats.tokens.output.toLocaleString()}\n`;
|
|
537
|
+
info += `${theme.fg("dim", t("Total:"))} ${stats.tokens.total.toLocaleString()}\n`;
|
|
538
|
+
// 双维度统计(用户裁决 2026-09-25):总计之外按供应商/模型分桶——缓存读/写、
|
|
539
|
+
// 命中率、费用逐桶可见。此前该拆分门控在 cost>0 且多桶才渲染,单价为 0 的
|
|
540
|
+
// 自定义供应商(如自建代理)永远看不到。
|
|
541
|
+
if (usageBreakdown.length > 0) {
|
|
542
|
+
info += `\n${theme.bold(t("By Provider/Model"))}\n`;
|
|
543
|
+
for (const entry of usageBreakdown) {
|
|
544
|
+
const bucket = entry.totals;
|
|
545
|
+
const promptBucket = bucket.input + bucket.cacheRead + bucket.cacheWrite;
|
|
546
|
+
let line = ` ${theme.bold(entry.key)}`;
|
|
547
|
+
if (promptBucket > 0) {
|
|
548
|
+
line += `\n ${theme.fg("dim", t("Input:"))} ${promptBucket.toLocaleString()}`;
|
|
549
|
+
if (bucket.cacheRead > 0 || bucket.cacheWrite > 0) {
|
|
550
|
+
const rate = promptBucket > 0 ? ((bucket.cacheRead / promptBucket) * 100).toFixed(1) : "0.0";
|
|
551
|
+
line += ` ${theme.fg("dim", t("(cache {rate}%, W {written})", { rate, written: bucket.cacheWrite.toLocaleString() }))}`;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (bucket.output > 0)
|
|
555
|
+
line += `\n ${theme.fg("dim", t("Output:"))} ${bucket.output.toLocaleString()}`;
|
|
556
|
+
if (entry.cost > 0)
|
|
557
|
+
line += ` ${theme.fg("dim", `$${entry.cost.toFixed(3)}`)}`;
|
|
558
|
+
info += `${line}\n`;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (stats.cost > 0 || cacheWaste.missedTokens > 0) {
|
|
562
|
+
info += `\n${theme.bold(t("Cost"))}\n`;
|
|
563
|
+
info += `${theme.fg("dim", t("Total:"))} $${stats.cost.toFixed(3)}`;
|
|
564
|
+
if (usageBreakdown.length > 1) {
|
|
565
|
+
for (const entry of usageBreakdown) {
|
|
566
|
+
info += `\n ${theme.fg("dim", `${entry.key}:`)} $${entry.cost.toFixed(3)} ${theme.fg("dim", t("({tokens} tokens)", { tokens: formatTokens(entry.tokens) }))}`;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (cacheWaste.missedTokens > 0) {
|
|
570
|
+
const missLabel = cacheWaste.missCount === 1
|
|
571
|
+
? t("{count} miss", { count: cacheWaste.missCount })
|
|
572
|
+
: t("{count} misses", { count: cacheWaste.missCount });
|
|
573
|
+
const detail = t("{tokens} tokens, {misses}", {
|
|
574
|
+
tokens: cacheWaste.missedTokens.toLocaleString(),
|
|
575
|
+
misses: missLabel,
|
|
576
|
+
});
|
|
577
|
+
info +=
|
|
578
|
+
cacheWaste.missedCost >= 0.0001
|
|
579
|
+
? `\n${theme.fg("dim", t("Cache Re-billed:"))} $${cacheWaste.missedCost.toFixed(3)} ${theme.fg("dim", `(${detail})`)}`
|
|
580
|
+
: `\n${theme.fg("dim", t("Cache Re-billed:"))} ${detail}`;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
584
|
+
host.chatContainer.addChild(new Text(info, 1, 0));
|
|
585
|
+
host.ui.requestRender();
|
|
586
|
+
}
|
|
587
|
+
export function handleMetricsCommand(host, turnsArg) {
|
|
588
|
+
const provider = host.options.getMetrics;
|
|
589
|
+
if (!provider) {
|
|
590
|
+
host.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
let windowTurns;
|
|
594
|
+
if (turnsArg !== undefined) {
|
|
595
|
+
const parsed = Number.parseInt(turnsArg, 10);
|
|
596
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) {
|
|
597
|
+
host.showWarning(t("Invalid turns: {turns}. Usage: /metrics [turns]", { turns: turnsArg }));
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
windowTurns = parsed;
|
|
601
|
+
}
|
|
602
|
+
let snapshot;
|
|
603
|
+
try {
|
|
604
|
+
const result = provider({ windowTurns });
|
|
605
|
+
if (result === undefined) {
|
|
606
|
+
host.showWarning(t("Metrics are not available: the observability plugin is not mounted in this session"));
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
snapshot = result;
|
|
610
|
+
}
|
|
611
|
+
catch (error) {
|
|
612
|
+
host.showError(error instanceof Error ? error.message : String(error));
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
616
|
+
host.chatContainer.addChild(new Text(formatMetricsSnapshot(snapshot), 1, 0));
|
|
617
|
+
host.ui.requestRender();
|
|
618
|
+
}
|
|
619
|
+
export function handleChangelogCommand(host) {
|
|
620
|
+
const changelogPath = getChangelogPath();
|
|
621
|
+
const allEntries = parseChangelog(changelogPath);
|
|
622
|
+
const changelogMarkdown = allEntries.length > 0
|
|
623
|
+
? allEntries
|
|
624
|
+
.reverse()
|
|
625
|
+
.map((e) => normalizeChangelogLinks(e.content, e))
|
|
626
|
+
.join("\n\n")
|
|
627
|
+
: t("No changelog entries found.");
|
|
628
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
629
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
630
|
+
host.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("What's New"))), 1, 0));
|
|
631
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
632
|
+
host.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, host.getMarkdownThemeWithSettings()));
|
|
633
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
634
|
+
host.ui.requestRender();
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Get capitalized display string for an app keybinding action.
|
|
638
|
+
*/
|
|
639
|
+
export function getAppKeyDisplay(action) {
|
|
640
|
+
return keyDisplayText(action);
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Get capitalized display string for an editor keybinding action.
|
|
644
|
+
*/
|
|
645
|
+
export function getEditorKeyDisplay(action) {
|
|
646
|
+
return keyDisplayText(action);
|
|
647
|
+
}
|
|
648
|
+
export function handleHelpCommand(host) {
|
|
649
|
+
const section = (title, rows) => {
|
|
650
|
+
if (rows.length === 0)
|
|
651
|
+
return "";
|
|
652
|
+
let table = `\n**${title}**\n| ${t("Command")} | ${t("Description")} |\n|---------|-------------|\n`;
|
|
653
|
+
for (const row of rows) {
|
|
654
|
+
const command = row.hint ? `\`/${row.name} ${row.hint}\`` : `\`/${row.name}\``;
|
|
655
|
+
table += `| ${command} | ${row.description ?? ""} |\n`;
|
|
656
|
+
}
|
|
657
|
+
return table;
|
|
658
|
+
};
|
|
659
|
+
const builtinRows = BUILTIN_SLASH_COMMANDS.map((command) => ({
|
|
660
|
+
name: command.name,
|
|
661
|
+
hint: command.argumentHint,
|
|
662
|
+
description: command.description,
|
|
663
|
+
}));
|
|
664
|
+
const promptRows = host.facade.getPromptTemplates().map((template) => ({
|
|
665
|
+
name: template.name,
|
|
666
|
+
hint: template.argumentHint,
|
|
667
|
+
description: template.description,
|
|
668
|
+
}));
|
|
669
|
+
const skillRows = host.facade.getSkills().skills.map((skill) => ({
|
|
670
|
+
name: `skill:${skill.name}`,
|
|
671
|
+
description: skill.description,
|
|
672
|
+
}));
|
|
673
|
+
const help = section(t("Built-in commands"), builtinRows) +
|
|
674
|
+
section(t("Prompt templates"), promptRows) +
|
|
675
|
+
section(t("Skills"), skillRows) +
|
|
676
|
+
`\n${t("Type `/` for autocomplete. Use `/hotkeys` for keyboard shortcuts.")}`;
|
|
677
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
678
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
679
|
+
host.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Available Commands"))), 1, 0));
|
|
680
|
+
host.chatContainer.addChild(new Markdown(help.trim(), 1, 1, host.getMarkdownThemeWithSettings()));
|
|
681
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
682
|
+
host.ui.requestRender();
|
|
683
|
+
}
|
|
684
|
+
export function handleHotkeysCommand(host) {
|
|
685
|
+
// Navigation keybindings
|
|
686
|
+
const cursorUp = getEditorKeyDisplay("tui.editor.cursorUp");
|
|
687
|
+
const cursorDown = getEditorKeyDisplay("tui.editor.cursorDown");
|
|
688
|
+
const cursorLeft = getEditorKeyDisplay("tui.editor.cursorLeft");
|
|
689
|
+
const cursorRight = getEditorKeyDisplay("tui.editor.cursorRight");
|
|
690
|
+
const cursorWordLeft = getEditorKeyDisplay("tui.editor.cursorWordLeft");
|
|
691
|
+
const cursorWordRight = getEditorKeyDisplay("tui.editor.cursorWordRight");
|
|
692
|
+
const cursorLineStart = getEditorKeyDisplay("tui.editor.cursorLineStart");
|
|
693
|
+
const cursorLineEnd = getEditorKeyDisplay("tui.editor.cursorLineEnd");
|
|
694
|
+
const jumpForward = getEditorKeyDisplay("tui.editor.jumpForward");
|
|
695
|
+
const jumpBackward = getEditorKeyDisplay("tui.editor.jumpBackward");
|
|
696
|
+
const pageUp = getEditorKeyDisplay("tui.editor.pageUp");
|
|
697
|
+
const pageDown = getEditorKeyDisplay("tui.editor.pageDown");
|
|
698
|
+
// Editing keybindings
|
|
699
|
+
const submit = getEditorKeyDisplay("tui.input.submit");
|
|
700
|
+
const newLine = getEditorKeyDisplay("tui.input.newLine");
|
|
701
|
+
const deleteWordBackward = getEditorKeyDisplay("tui.editor.deleteWordBackward");
|
|
702
|
+
const deleteWordForward = getEditorKeyDisplay("tui.editor.deleteWordForward");
|
|
703
|
+
const deleteToLineStart = getEditorKeyDisplay("tui.editor.deleteToLineStart");
|
|
704
|
+
const deleteToLineEnd = getEditorKeyDisplay("tui.editor.deleteToLineEnd");
|
|
705
|
+
const yank = getEditorKeyDisplay("tui.editor.yank");
|
|
706
|
+
const yankPop = getEditorKeyDisplay("tui.editor.yankPop");
|
|
707
|
+
const undo = getEditorKeyDisplay("tui.editor.undo");
|
|
708
|
+
const tab = getEditorKeyDisplay("tui.input.tab");
|
|
709
|
+
// App keybindings
|
|
710
|
+
const interrupt = getAppKeyDisplay("app.interrupt");
|
|
711
|
+
const clear = getAppKeyDisplay("app.clear");
|
|
712
|
+
const exit = getAppKeyDisplay("app.exit");
|
|
713
|
+
const suspend = getAppKeyDisplay("app.suspend");
|
|
714
|
+
const cycleThinkingLevel = getAppKeyDisplay("app.thinking.cycle");
|
|
715
|
+
const cycleModelForward = getAppKeyDisplay("app.model.cycleForward");
|
|
716
|
+
const selectModel = getAppKeyDisplay("app.model.select");
|
|
717
|
+
const expandTools = getAppKeyDisplay("app.tools.expand");
|
|
718
|
+
const toggleThinking = getAppKeyDisplay("app.thinking.toggle");
|
|
719
|
+
const externalEditor = getAppKeyDisplay("app.editor.external");
|
|
720
|
+
const cycleModelBackward = getAppKeyDisplay("app.model.cycleBackward");
|
|
721
|
+
const copyMessage = getAppKeyDisplay("app.message.copy");
|
|
722
|
+
const followUp = getAppKeyDisplay("app.message.followUp");
|
|
723
|
+
const dequeue = getAppKeyDisplay("app.message.dequeue");
|
|
724
|
+
const pasteImage = getAppKeyDisplay("app.clipboard.pasteImage");
|
|
725
|
+
// Iron law (2026-10-01): these shipped defaults were cleared in favor of
|
|
726
|
+
// the /model command; the row only appears when a user re-configures a key.
|
|
727
|
+
const selectModelRow = selectModel ? `| \`${selectModel}\` | ${t("Open model selector")} |\n` : "";
|
|
728
|
+
// Iron law (2026-10-02 复审): ctrl+g/ctrl+x stay bound only for the
|
|
729
|
+
// components without a command channel — the main editor ignores them
|
|
730
|
+
// (/editor and /copy are its single entries), so the rows say where
|
|
731
|
+
// each key actually acts.
|
|
732
|
+
const copyMessageRow = copyMessage ? `| \`${copyMessage}\` | ${t("Copy selection in /tree")} |\n` : "";
|
|
733
|
+
const externalEditorRow = externalEditor
|
|
734
|
+
? `| \`${externalEditor}\` | ${t("External editor (inside dialog inputs)")} |\n`
|
|
735
|
+
: "";
|
|
736
|
+
// Iron law (2026-10-01): the message queue is the /queue and /dequeue
|
|
737
|
+
// commands' feature; rows only appear when a user re-configures a key.
|
|
738
|
+
const followUpRow = followUp ? `| \`${followUp}\` | ${t("Queue follow-up message")} |\n` : "";
|
|
739
|
+
const dequeueRow = dequeue ? `| \`${dequeue}\` | ${t("Restore queued messages")} |\n` : "";
|
|
740
|
+
const cycleThinkingRow = cycleThinkingLevel ? `| \`${cycleThinkingLevel}\` | ${t("Cycle thinking level")} |\n` : "";
|
|
741
|
+
const cycleModelsRow = cycleModelForward || cycleModelBackward
|
|
742
|
+
? `| \`${cycleModelForward}\` / \`${cycleModelBackward}\` | ${t("Cycle models")} |\n`
|
|
743
|
+
: "";
|
|
744
|
+
// Suspend has no default key on native Windows; hide the row there.
|
|
745
|
+
const suspendRow = suspend ? `| \`${suspend}\` | ${t("Suspend to background")} |\n` : "";
|
|
746
|
+
const hotkeys = `
|
|
747
|
+
**${t("Navigation")}**
|
|
748
|
+
| ${t("Key")} | ${t("Action")} |
|
|
749
|
+
|-----|--------|
|
|
750
|
+
| \`${cursorUp}\` / \`${cursorDown}\` / \`${cursorLeft}\` / \`${cursorRight}\` | ${t("Move cursor / browse history")} |
|
|
751
|
+
| \`${cursorWordLeft}\` / \`${cursorWordRight}\` | ${t("Move by word")} |
|
|
752
|
+
| \`${cursorLineStart}\` | ${t("Start of line")} |
|
|
753
|
+
| \`${cursorLineEnd}\` | ${t("End of line")} |
|
|
754
|
+
| \`${jumpForward}\` | ${t("Jump forward to character")} |
|
|
755
|
+
| \`${jumpBackward}\` | ${t("Jump backward to character")} |
|
|
756
|
+
| \`${pageUp}\` / \`${pageDown}\` | ${t("Scroll by page")} |
|
|
757
|
+
|
|
758
|
+
**${t("Editing")}**
|
|
759
|
+
| ${t("Key")} | ${t("Action")} |
|
|
760
|
+
|-----|--------|
|
|
761
|
+
| \`${submit}\` | ${t("Send message")} |
|
|
762
|
+
| \`${newLine}\` | ${process.platform === "win32" ? t("New line (Ctrl+Enter on Windows Terminal)") : t("New line")} |
|
|
763
|
+
| \`${deleteWordBackward}\` | ${t("Delete word backwards")} |
|
|
764
|
+
| \`${deleteWordForward}\` | ${t("Delete word forwards")} |
|
|
765
|
+
| \`${deleteToLineStart}\` | ${t("Delete to start of line")} |
|
|
766
|
+
| \`${deleteToLineEnd}\` | ${t("Delete to end of line")} |
|
|
767
|
+
| \`${yank}\` | ${t("Paste the most-recently-deleted text")} |
|
|
768
|
+
| \`${yankPop}\` | ${t("Cycle through the deleted text after pasting")} |
|
|
769
|
+
| \`${undo}\` | ${t("Undo")} |
|
|
770
|
+
|
|
771
|
+
**${t("Other")}**
|
|
772
|
+
| ${t("Key")} | ${t("Action")} |
|
|
773
|
+
|-----|--------|
|
|
774
|
+
| \`${tab}\` | ${t("Path completion / accept autocomplete")} |
|
|
775
|
+
| \`${interrupt}\` | ${t("Cancel autocomplete / abort streaming")} |
|
|
776
|
+
| \`${clear}\` | ${t("Clear editor (first) / exit (second)")} |
|
|
777
|
+
| \`${exit}\` | ${t("Exit (when editor is empty)")} |
|
|
778
|
+
${suspendRow}${cycleThinkingRow}${cycleModelsRow}${selectModelRow}| \`${expandTools}\` | ${t("Toggle tool output expansion")} |
|
|
779
|
+
| \`${toggleThinking}\` | ${t("Toggle thinking block visibility")} |
|
|
780
|
+
${externalEditorRow}${copyMessageRow}${followUpRow}${dequeueRow}
|
|
781
|
+
| \`${pasteImage}\` | ${t("Paste image or text from clipboard")} |
|
|
782
|
+
| \`/\` | ${t("Slash commands")} |
|
|
783
|
+
| \`!\` | ${t("Run bash command")} |
|
|
784
|
+
| \`!!\` | ${t("Run bash command (excluded from context)")} |
|
|
785
|
+
`;
|
|
786
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
787
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
788
|
+
host.chatContainer.addChild(new Text(theme.bold(theme.fg("accent", t("Keyboard Shortcuts"))), 1, 0));
|
|
789
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
790
|
+
host.chatContainer.addChild(new Markdown(hotkeys.trim(), 1, 1, host.getMarkdownThemeWithSettings()));
|
|
791
|
+
host.chatContainer.addChild(new DynamicBorder());
|
|
792
|
+
host.ui.requestRender();
|
|
793
|
+
}
|
|
794
|
+
export async function handleClearCommand(host) {
|
|
795
|
+
host.clearStatusIndicator();
|
|
796
|
+
try {
|
|
797
|
+
const result = await host.runtimeFacade.newSession();
|
|
798
|
+
if (result.cancelled) {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
802
|
+
host.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ New session started"))}`, 1, 1));
|
|
803
|
+
host.ui.requestRender();
|
|
804
|
+
}
|
|
805
|
+
catch (error) {
|
|
806
|
+
await host.handleFatalRuntimeError("Failed to create session", error);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
export function handleDebugCommand(host) {
|
|
810
|
+
const width = host.ui.terminal.columns;
|
|
811
|
+
const height = host.ui.terminal.rows;
|
|
812
|
+
const allLines = host.ui.render(width);
|
|
813
|
+
const debugLogPath = getDebugLogPath();
|
|
814
|
+
const debugData = [
|
|
815
|
+
t("Debug output at {date}", { date: new Date().toISOString() }),
|
|
816
|
+
t("Terminal: {columns}x{rows}", { columns: width, rows: height }),
|
|
817
|
+
t("Total lines: {count}", { count: allLines.length }),
|
|
818
|
+
"",
|
|
819
|
+
t("=== All rendered lines with visible widths ==="),
|
|
820
|
+
...allLines.map((line, idx) => {
|
|
821
|
+
const vw = visibleWidth(line);
|
|
822
|
+
const escaped = JSON.stringify(line);
|
|
823
|
+
return `[${idx}] (w=${vw}) ${escaped}`;
|
|
824
|
+
}),
|
|
825
|
+
"",
|
|
826
|
+
t("=== Agent messages (JSONL) ==="),
|
|
827
|
+
...host.facade
|
|
828
|
+
.getSessionAPI()
|
|
829
|
+
.getMessages()
|
|
830
|
+
.map((msg) => JSON.stringify(msg)),
|
|
831
|
+
"",
|
|
832
|
+
].join("\n");
|
|
833
|
+
fs.mkdirSync(path.dirname(debugLogPath), { recursive: true });
|
|
834
|
+
fs.writeFileSync(debugLogPath, debugData);
|
|
835
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
836
|
+
host.chatContainer.addChild(new Text(`${theme.fg("accent", t("✓ Debug log written"))}\n${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
837
|
+
host.ui.requestRender();
|
|
838
|
+
}
|
|
839
|
+
export function handleArminSaysHi(host) {
|
|
840
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
841
|
+
host.chatContainer.addChild(new ArminComponent(host.ui));
|
|
842
|
+
host.ui.requestRender();
|
|
843
|
+
}
|
|
844
|
+
export function handleDaxnuts(host) {
|
|
845
|
+
host.chatContainer.addChild(new Spacer(1));
|
|
846
|
+
host.chatContainer.addChild(new DaxnutsComponent(host.ui));
|
|
847
|
+
host.ui.requestRender();
|
|
848
|
+
}
|
|
849
|
+
/** Host-visible for ./interactive-auth.ts (S5 slice 3). */
|
|
850
|
+
export function checkDaxnutsEasterEgg(host, model) {
|
|
851
|
+
if (model.provider === "opencode" && model.id.toLowerCase().includes("kimi-k2.5")) {
|
|
852
|
+
host.handleDaxnuts();
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
export async function handleBashCommand(host, command, excludeFromContext = false) {
|
|
856
|
+
// Dispatch the user.bash lifecycle facts, then execute locally.
|
|
857
|
+
host.facade.emitUserBash(excludeFromContext);
|
|
858
|
+
// Normal execution path
|
|
859
|
+
const isDeferred = host.facade.isStreaming();
|
|
860
|
+
host.bashComponent = new BashExecutionComponent(command, host.ui, excludeFromContext);
|
|
861
|
+
if (isDeferred) {
|
|
862
|
+
// Show in pending area when agent is streaming
|
|
863
|
+
host.pendingMessagesContainer.addChild(host.bashComponent);
|
|
864
|
+
host.pendingBashComponents.push(host.bashComponent);
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
// Show in chat immediately when agent is idle
|
|
868
|
+
host.chatContainer.addChild(host.bashComponent);
|
|
869
|
+
}
|
|
870
|
+
host.ui.requestRender();
|
|
871
|
+
try {
|
|
872
|
+
const result = await host.facade.executeBash(command, (chunk) => {
|
|
873
|
+
if (host.bashComponent) {
|
|
874
|
+
host.bashComponent.appendOutput(chunk);
|
|
875
|
+
host.ui.requestRender();
|
|
876
|
+
}
|
|
877
|
+
}, { excludeFromContext });
|
|
878
|
+
if (host.bashComponent) {
|
|
879
|
+
host.bashComponent.setComplete(result.exitCode, result.cancelled, result.truncated ? { truncated: true, content: result.output } : undefined, result.fullOutputPath);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
catch (error) {
|
|
883
|
+
if (host.bashComponent) {
|
|
884
|
+
host.bashComponent.setComplete(undefined, false);
|
|
885
|
+
}
|
|
886
|
+
host.showError(t("Bash command failed: {error}", {
|
|
887
|
+
error: error instanceof Error ? error.message : t("Unknown error"),
|
|
888
|
+
}));
|
|
889
|
+
}
|
|
890
|
+
host.bashComponent = undefined;
|
|
891
|
+
host.ui.requestRender();
|
|
892
|
+
}
|
|
893
|
+
export async function handleCompactCommand(host, customInstructions) {
|
|
894
|
+
host.clearStatusIndicator();
|
|
895
|
+
try {
|
|
896
|
+
await host.facade.compact(customInstructions);
|
|
897
|
+
}
|
|
898
|
+
catch {
|
|
899
|
+
// Ignore, will be emitted as an event
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
/** /clean-sessions:会话清理两阶段流程;输出/确认走宿主既有机制(设计 §7)。 */
|
|
903
|
+
export async function handleCleanSessionsCommand(host, arg) {
|
|
904
|
+
await runCleanSessions({
|
|
905
|
+
showMessage: (text) => host.showStatus(text),
|
|
906
|
+
showError: (text) => host.showError(text),
|
|
907
|
+
confirm: (title, message) => host.showDialogConfirm(title, message),
|
|
908
|
+
}, arg);
|
|
909
|
+
}
|
|
216
910
|
//# sourceMappingURL=interactive-commands.js.map
|