@ai-agent-forge/agent-forge 0.88.2 → 0.88.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -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 +244 -234
- 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-6F5JWGKE.js → chunk-32YDZI4J.js} +1 -1
- package/dist/bundle/chunks/{chunk-LSP24WNH.js → chunk-755VNWIF.js} +12 -12
- package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-BVVSHK6W.js} +1 -1
- package/dist/bundle/chunks/{chunk-HTC5K5SM.js → chunk-HEL6TAWE.js} +95 -90
- package/dist/bundle/chunks/{chunk-6R7UI4IY.js → chunk-QDLOMKF6.js} +1 -1
- package/dist/bundle/chunks/{chunk-44I47ACN.js → chunk-V3ACW7VD.js} +1 -1
- 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 +1 -1
- 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/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-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 +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -1
- package/dist/core/agent-session-services.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-plugin.d.ts.map +1 -1
- package/dist/core/extensions/capability-plugin.js +15 -8
- package/dist/core/extensions/capability-plugin.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 +12 -4
- 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/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/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 +6 -7
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -4
- 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/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/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 +25 -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 +3 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +83 -24
- 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.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +2 -2
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +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 +2 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +96 -4
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-run-group.js +1 -1
- package/dist/modes/interactive/components/tool-run-group.js.map +1 -1
- 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 +123 -6
- package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-commands.js +691 -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 +240 -133
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +251 -2159
- 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/node-package-install-host.d.ts +9 -1
- package/dist/plugins/ecosystem/node-package-install-host.d.ts.map +1 -1
- package/dist/plugins/ecosystem/node-package-install-host.js +79 -0
- package/dist/plugins/ecosystem/node-package-install-host.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/suites/builtin-suites.d.ts.map +1 -0
- 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 +15 -1
- 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/usage.md +292 -292
- 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/mcp-stdio/index.d.ts +64 -0
- package/examples/extensions/mcp-stdio/index.d.ts.map +1 -0
- package/examples/extensions/mcp-stdio/index.js +292 -0
- package/examples/extensions/mcp-stdio/index.js.map +1 -0
- 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-MRXD3RWG.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}/builtin-suites.d.ts +0 -0
- /package/dist/{profiles → suites}/builtin-suites.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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-events.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-events.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent event bridge and transcript rendering for interactive mode (拆分\n * slice 5, docs/plans/interactive-mode拆分计划.md): the session subscription,\n * the handleEvent dispatch (every session event the TUI reacts to), the\n * transcript renderers (addMessageToChat / renderSessionItems /\n * renderSessionEntries / renderInitialMessages / rebuildChatFromMessages),\n * and the cache-miss / thinking-drop / compaction-cost notices.\n *\n * InteractiveMode implements EventsHost and keeps same-name delegate methods so\n * prototype-level tests and the rebind/subscribe flow keep working; the\n * functions below receive the mode through EventsHost. Cross-family faces go\n * through host methods only (checkShutdownRequested → ./interactive-lifecycle.ts,\n * flushCompactionQueue / updatePendingMessagesDisplay →\n * ./interactive-queues.ts); no sibling module is imported here.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { AgentMessage } from \"@agent-forge/agent-core\";\nimport type { AssistantMessage, Message, Usage } from \"@agent-forge/ai/compat\";\nimport type { Container, EditorComponent, MarkdownTheme, TUI } from \"@agent-forge/tui\";\nimport { Spacer, Text } from \"@agent-forge/tui\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport { parseSkillBlock } from \"../../core/agent-session.ts\";\nimport { CACHE_TTL_MS, type CacheMiss, collectCacheMisses, detectCacheMiss } from \"../../core/cache-stats.ts\";\nimport type { CodingAgentFacadeV1 } from \"../../core/facade/index.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport { createCompactionSummaryMessage } from \"../../core/messages.ts\";\nimport { type SessionEntry, sessionEntryToContextMessages } from \"../../core/session-manager.ts\";\nimport type { SettingsManager } from \"../../core/settings-manager.ts\";\nimport type { TruncationResult } from \"../../core/tools/truncate.ts\";\nimport { theme } from \"../../theme/theme.ts\";\nimport { AssistantMessageComponent } from \"./components/assistant-message.ts\";\nimport { BashExecutionComponent } from \"./components/bash-execution.ts\";\nimport { BranchSummaryMessageComponent } from \"./components/branch-summary-message.ts\";\nimport { CompactionSummaryMessageComponent } from \"./components/compaction-summary-message.ts\";\nimport type { CustomEditor } from \"./components/custom-editor.ts\";\nimport { CustomMessageComponent } from \"./components/custom-message.ts\";\nimport { type FooterComponent, formatTokens } from \"./components/footer.ts\";\nimport type { MarkdownTransformer } from \"./components/render-types.ts\";\nimport { SkillInvocationMessageComponent } from \"./components/skill-invocation-message.ts\";\nimport {\n\tBranchSummaryStatusIndicator,\n\tCompactionStatusIndicator,\n\tRetryStatusIndicator,\n\ttype StatusIndicator,\n} from \"./components/status-indicator.ts\";\nimport { ToolExecutionComponent } from \"./components/tool-execution.ts\";\nimport { ToolRunGroupComponent } from \"./components/tool-run-group.ts\";\nimport { UserMessageComponent } from \"./components/user-message.ts\";\n\nexport type CompactionCostNotice = {\n\ttype: \"compaction_cost\";\n\tkind: \"compaction\" | \"branch_summary\";\n\tusage: Usage;\n};\n\nexport type RenderSessionItem = AgentMessage | Extract<SessionEntry, { type: \"custom\" }> | CompactionCostNotice;\n\nfunction isCustomSessionEntry(item: RenderSessionItem): item is Extract<SessionEntry, { type: \"custom\" }> {\n\treturn \"type\" in item && item.type === \"custom\";\n}\n\nfunction isCompactionCostNotice(item: RenderSessionItem): item is CompactionCostNotice {\n\treturn \"type\" in item && item.type === \"compaction_cost\";\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the event bridge and\n * transcript renderers (which stay on the mode for prototype-level tests and\n * the rebind flow), the streaming/transcript state they drive, and the\n * cross-family faces they call (lifecycle shutdown gate, compaction queue\n * flush, pending-messages display).\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface EventsHost {\n\tui: TUI;\n\t/** Stable facade (阶段 1 slice 1). */\n\tfacade: CodingAgentFacadeV1;\n\tsettingsManager: SettingsManager;\n\tfooter: FooterComponent;\n\tchatContainer: Container;\n\teditor: EditorComponent;\n\t/** Default editor instance; compaction/retry escape handlers swap onEscape. */\n\tdefaultEditor: CustomEditor;\n\t/** Agent subscription unsubscribe function (assigned by subscribeToAgent). */\n\tunsubscribe?: (() => void) | undefined;\n\tisInitialized: boolean;\n\t/** Per-second failover countdown ticker; handleEvent refreshes it. */\n\tfailoverTicker: { refresh(): void } | undefined;\n\tpendingTools: Map<string, ToolExecutionComponent>;\n\tretryEscapeHandler?: (() => void) | undefined;\n\tautoCompactionEscapeHandler?: (() => void) | undefined;\n\tworkingVisible: boolean;\n\tstreamingComponent: AssistantMessageComponent | undefined;\n\tstreamingMessage: AssistantMessage | undefined;\n\tactiveToolRunGroup: ToolRunGroupComponent | undefined;\n\tactiveStatusIndicator: StatusIndicator | undefined;\n\thideThinkingBlock: boolean;\n\thiddenThinkingLabel: string;\n\toutputPad: number;\n\ttoolOutputExpanded: boolean;\n\tmermaidMarkdownTransformer: MarkdownTransformer;\n\n\tinit(): Promise<void>;\n\tshowWorkingStatusIndicator(): void;\n\tclearStatusIndicator(kind?: StatusIndicator[\"kind\"]): void;\n\tshowStatusIndicator(indicator: StatusIndicator): void;\n\tshowStatus(message: string): void;\n\tshowError(message: string): void;\n\tupdatePendingMessagesDisplay(): void;\n\tupdateTerminalTitle(): void;\n\tupdateEditorBorderColor(): void;\n\tgetMarkdownThemeWithSettings(): MarkdownTheme;\n\tgetMarkdownTransformers(): MarkdownTransformer[];\n\tgetRegisteredToolDefinition(toolName: string): ReturnType<CodingAgentFacadeV1[\"getToolDefinition\"]>;\n\thandleEvent(event: AgentSessionEvent): Promise<void>;\n\taddMessageToChat(message: AgentMessage, options?: { populateHistory?: boolean }): void;\n\tgetUserMessageText(message: Message): string;\n\trenderSessionEntries(entries: SessionEntry[], options?: { updateFooter?: boolean; populateHistory?: boolean }): void;\n\trenderSessionItems(\n\t\titems: readonly RenderSessionItem[],\n\t\toptions?: { updateFooter?: boolean; populateHistory?: boolean },\n\t): void;\n\taddCompactionCostNotice(notice: CompactionCostNotice): void;\n\tmaybeShowThinkingDropNotice(message: AssistantMessage): void;\n\tmaybeShowCacheMissNotice(message: AssistantMessage): void;\n\taddCacheMissNotice(miss: CacheMiss): void;\n\taddToolToRunGroup(component: ToolExecutionComponent): void;\n\tnoteResultInActiveToolRunGroup(isError: boolean): void;\n\tmarkActiveToolRunGroupComplete(): void;\n\t/** Lifecycle face (./interactive-lifecycle.ts): agent_settled exit gate. */\n\tcheckShutdownRequested(): Promise<void>;\n\t/** Queue face (./interactive-queues.ts): compaction_end queue flush. */\n\tflushCompactionQueue(options?: { willRetry?: boolean }): Promise<void>;\n}\n\nexport function subscribeToAgent(host: EventsHost): void {\n\thost.unsubscribe = host.facade.subscribe(async (event) => {\n\t\tawait host.handleEvent(event);\n\t});\n}\n\nexport async function handleEvent(host: EventsHost, event: AgentSessionEvent): Promise<void> {\n\tif (!host.isInitialized) {\n\t\tawait host.init();\n\t}\n\n\thost.footer.invalidate();\n\t// Failover snapshots land as entry_appended events; the ticker decides here\n\t// whether the per-second countdown re-render is needed (§4.7 Phase 3).\n\thost.failoverTicker?.refresh();\n\n\tswitch (event.type) {\n\t\tcase \"agent_start\":\n\t\t\thost.pendingTools.clear();\n\t\t\t// Restore main escape handler if retry handler is still active\n\t\t\t// (retry success event fires later, but we need main handler now)\n\t\t\tif (host.retryEscapeHandler) {\n\t\t\t\thost.defaultEditor.onEscape = host.retryEscapeHandler;\n\t\t\t\thost.retryEscapeHandler = undefined;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase \"turn_start\":\n\t\t\tif (host.settingsManager.getShowTerminalProgress()) {\n\t\t\t\thost.ui.terminal.setProgress(true);\n\t\t\t}\n\t\t\tif (host.workingVisible) {\n\t\t\t\tif (host.activeStatusIndicator?.kind !== \"working\") {\n\t\t\t\t\thost.showWorkingStatusIndicator();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\thost.clearStatusIndicator();\n\t\t\t}\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\n\t\tcase \"queue_update\":\n\t\t\thost.updatePendingMessagesDisplay();\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\n\t\tcase \"entry_appended\":\n\t\t\t// Custom entries have no renderer source since the legacy extension\n\t\t\t// surface was removed; nothing to append to the chat.\n\t\t\tbreak;\n\n\t\tcase \"session_info_changed\":\n\t\t\thost.updateTerminalTitle();\n\t\t\thost.footer.invalidate();\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\n\t\tcase \"thinking_level_changed\":\n\t\t\thost.footer.invalidate();\n\t\t\thost.updateEditorBorderColor();\n\t\t\tbreak;\n\n\t\tcase \"message_start\":\n\t\t\tif (event.message.role === \"custom\") {\n\t\t\t\thost.addMessageToChat(event.message);\n\t\t\t\thost.ui.requestRender();\n\t\t\t} else if (event.message.role === \"user\") {\n\t\t\t\thost.addMessageToChat(event.message);\n\t\t\t\thost.updatePendingMessagesDisplay();\n\t\t\t\thost.ui.requestRender();\n\t\t\t} else if (event.message.role === \"assistant\") {\n\t\t\t\t// D-083: a new assistant turn closes the previous turn's\n\t\t\t\t// tool-run group (tools executed between the turns) and\n\t\t\t\t// starts a fresh one on its first toolCall.\n\t\t\t\thost.activeToolRunGroup?.markRunComplete();\n\t\t\t\thost.activeToolRunGroup = undefined;\n\t\t\t\thost.streamingComponent = new AssistantMessageComponent(\n\t\t\t\t\tundefined,\n\t\t\t\t\thost.hideThinkingBlock,\n\t\t\t\t\thost.getMarkdownThemeWithSettings(),\n\t\t\t\t\thost.hiddenThinkingLabel,\n\t\t\t\t\thost.outputPad,\n\t\t\t\t\thost.getMarkdownTransformers(),\n\t\t\t\t);\n\t\t\t\t// D-083: components created after a ctrl+o toggle inherit the\n\t\t\t\t// current expansion so detail mode holds across turns.\n\t\t\t\tif (host.toolOutputExpanded) {\n\t\t\t\t\thost.streamingComponent.setExpanded(true);\n\t\t\t\t}\n\t\t\t\thost.streamingMessage = event.message;\n\t\t\t\thost.chatContainer.addChild(host.streamingComponent);\n\t\t\t\thost.streamingComponent.updateContent(host.streamingMessage, true);\n\t\t\t\thost.ui.requestRender();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase \"message_update\":\n\t\t\tif (host.streamingComponent && event.message.role === \"assistant\") {\n\t\t\t\thost.streamingMessage = event.message;\n\t\t\t\thost.streamingComponent.updateContent(host.streamingMessage, true);\n\n\t\t\t\tfor (const content of host.streamingMessage.content) {\n\t\t\t\t\tif (content.type === \"toolCall\") {\n\t\t\t\t\t\tif (!host.pendingTools.has(content.id)) {\n\t\t\t\t\t\t\tconst component = new ToolExecutionComponent(\n\t\t\t\t\t\t\t\tcontent.name,\n\t\t\t\t\t\t\t\tcontent.id,\n\t\t\t\t\t\t\t\tcontent.arguments,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tshowImages: host.settingsManager.getShowImages(),\n\t\t\t\t\t\t\t\t\timageWidthCells: host.settingsManager.getImageWidthCells(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\thost.getRegisteredToolDefinition(content.name),\n\t\t\t\t\t\t\t\thost.ui,\n\t\t\t\t\t\t\t\thost.facade.getCwd(),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\t\t\t\t\thost.addToolToRunGroup(component);\n\t\t\t\t\t\t\thost.pendingTools.set(content.id, component);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst component = host.pendingTools.get(content.id);\n\t\t\t\t\t\t\t// v8 ignore next -- has() 已确认键存在,get() 恒返回组件\n\t\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\t\tcomponent.updateArgs(content.arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thost.ui.requestRender();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase \"message_end\":\n\t\t\tif (event.message.role === \"user\") break;\n\t\t\tif (host.streamingComponent && event.message.role === \"assistant\") {\n\t\t\t\thost.streamingMessage = event.message;\n\t\t\t\tlet errorMessage: string | undefined;\n\t\t\t\tif (host.streamingMessage.stopReason === \"aborted\") {\n\t\t\t\t\tconst retryAttempt = host.facade.getRetryAttempt();\n\t\t\t\t\terrorMessage =\n\t\t\t\t\t\tretryAttempt > 0\n\t\t\t\t\t\t\t? retryAttempt === 1\n\t\t\t\t\t\t\t\t? t(\"Aborted after {count} retry attempt\", { count: retryAttempt })\n\t\t\t\t\t\t\t\t: t(\"Aborted after {count} retry attempts\", { count: retryAttempt })\n\t\t\t\t\t\t\t: t(\"Operation aborted\");\n\t\t\t\t\thost.streamingMessage.errorMessage = errorMessage;\n\t\t\t\t}\n\t\t\t\thost.streamingComponent.updateContent(host.streamingMessage, false);\n\n\t\t\t\tif (host.streamingMessage.stopReason === \"aborted\" || host.streamingMessage.stopReason === \"error\") {\n\t\t\t\t\tif (!errorMessage) {\n\t\t\t\t\t\terrorMessage = host.streamingMessage.errorMessage || t(\"Error\");\n\t\t\t\t\t}\n\t\t\t\t\tfor (const [, component] of host.pendingTools.entries()) {\n\t\t\t\t\t\tcomponent.updateResult({\n\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: errorMessage }],\n\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t\thost.activeToolRunGroup?.noteResult(true);\n\t\t\t\t\t}\n\t\t\t\t\t// No tool execution follows an aborted/errored message:\n\t\t\t\t\t// finalize the group marker here.\n\t\t\t\t\thost.activeToolRunGroup?.markRunComplete();\n\t\t\t\t\thost.pendingTools.clear();\n\t\t\t\t} else {\n\t\t\t\t\t// Args are now complete - trigger diff computation for edit tools\n\t\t\t\t\tfor (const [, component] of host.pendingTools.entries()) {\n\t\t\t\t\t\tcomponent.setArgsComplete();\n\t\t\t\t\t}\n\t\t\t\t\thost.maybeShowThinkingDropNotice(host.streamingMessage);\n\t\t\t\t\thost.maybeShowCacheMissNotice(host.streamingMessage);\n\t\t\t\t}\n\t\t\t\thost.streamingComponent = undefined;\n\t\t\t\thost.streamingMessage = undefined;\n\t\t\t\t// D-083: a toolUse stop reason is followed by tool execution\n\t\t\t\t// events (start/end arrive after message_end — the session\n\t\t\t\t// executes tools once the streamed message completes), so the\n\t\t\t\t// group stays open for setActiveTool/noteResult here and is\n\t\t\t\t// finalized at agent_end / the next message_start.\n\t\t\t\thost.footer.invalidate();\n\t\t\t}\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\n\t\tcase \"bash_execution_update\":\n\t\t\t// The bash execution callback handles TUI output rendering.\n\t\t\tbreak;\n\n\t\tcase \"tool_execution_start\": {\n\t\t\tlet component = host.pendingTools.get(event.toolCallId);\n\t\t\tif (!component) {\n\t\t\t\tcomponent = new ToolExecutionComponent(\n\t\t\t\t\tevent.toolName,\n\t\t\t\t\tevent.toolCallId,\n\t\t\t\t\tevent.args,\n\t\t\t\t\t{\n\t\t\t\t\t\tshowImages: host.settingsManager.getShowImages(),\n\t\t\t\t\t\timageWidthCells: host.settingsManager.getImageWidthCells(),\n\t\t\t\t\t},\n\t\t\t\t\thost.getRegisteredToolDefinition(event.toolName),\n\t\t\t\t\thost.ui,\n\t\t\t\t\thost.facade.getCwd(),\n\t\t\t\t);\n\t\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\t\thost.addToolToRunGroup(component);\n\t\t\t\thost.pendingTools.set(event.toolCallId, component);\n\t\t\t}\n\t\t\tcomponent.markExecutionStarted();\n\t\t\thost.activeToolRunGroup?.setActiveTool(event.toolName);\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"tool_execution_update\": {\n\t\t\tconst component = host.pendingTools.get(event.toolCallId);\n\t\t\tif (component) {\n\t\t\t\tcomponent.updateResult({ ...event.partialResult, isError: false }, true);\n\t\t\t\thost.ui.requestRender();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"tool_execution_end\": {\n\t\t\tconst component = host.pendingTools.get(event.toolCallId);\n\t\t\tif (component) {\n\t\t\t\tcomponent.updateResult({ ...event.result, isError: event.isError });\n\t\t\t\thost.activeToolRunGroup?.noteResult(event.isError);\n\t\t\t\thost.pendingTools.delete(event.toolCallId);\n\t\t\t\thost.ui.requestRender();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"capability_command_result\": {\n\t\t\tconst links = event.result.links?.map((link) => `${link.label}: ${link.url}`) ?? [];\n\t\t\tconst message = [event.result.message, ...links].filter(Boolean).join(\"\\n\");\n\t\t\tif (event.result.status === \"error\") host.showError(message);\n\t\t\telse host.showStatus(message);\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"agent_end\":\n\t\t\tif (host.settingsManager.getShowTerminalProgress()) {\n\t\t\t\thost.ui.terminal.setProgress(false);\n\t\t\t}\n\t\t\thost.clearStatusIndicator(\"working\");\n\t\t\tif (host.streamingComponent) {\n\t\t\t\thost.chatContainer.removeChild(host.streamingComponent);\n\t\t\t\thost.streamingComponent = undefined;\n\t\t\t\thost.streamingMessage = undefined;\n\t\t\t}\n\t\t\thost.pendingTools.clear();\n\t\t\t// D-083: the whole agent turn (messages + tool executions) is\n\t\t\t// over — finalize the last group's marker (count/sole-tool name\n\t\t\t// + failure count). Completed groups stay in the transcript.\n\t\t\thost.activeToolRunGroup?.markRunComplete();\n\t\t\thost.activeToolRunGroup = undefined;\n\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\n\t\tcase \"agent_settled\":\n\t\t\tawait host.checkShutdownRequested();\n\t\t\tbreak;\n\n\t\tcase \"compaction_start\": {\n\t\t\tif (host.settingsManager.getShowTerminalProgress()) {\n\t\t\t\thost.ui.terminal.setProgress(true);\n\t\t\t}\n\t\t\t// Keep editor active; submissions are queued during compaction.\n\t\t\thost.autoCompactionEscapeHandler = host.defaultEditor.onEscape;\n\t\t\thost.defaultEditor.onEscape = () => {\n\t\t\t\thost.facade.abortCompaction();\n\t\t\t};\n\t\t\thost.showStatusIndicator(new CompactionStatusIndicator(host.ui, event.reason));\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"compaction_end\": {\n\t\t\tif (host.settingsManager.getShowTerminalProgress()) {\n\t\t\t\thost.ui.terminal.setProgress(false);\n\t\t\t}\n\t\t\tif (host.autoCompactionEscapeHandler) {\n\t\t\t\thost.defaultEditor.onEscape = host.autoCompactionEscapeHandler;\n\t\t\t\thost.autoCompactionEscapeHandler = undefined;\n\t\t\t}\n\t\t\thost.clearStatusIndicator(\"compaction\");\n\t\t\tif (event.aborted) {\n\t\t\t\tif (event.reason === \"manual\") {\n\t\t\t\t\thost.showError(t(\"Compaction cancelled\"));\n\t\t\t\t} else {\n\t\t\t\t\thost.showStatus(t(\"Auto-compaction cancelled\"));\n\t\t\t\t}\n\t\t\t} else if (event.result) {\n\t\t\t\tconst entries = host.facade.getContextEntries();\n\t\t\t\tif (entries[0]?.type !== \"compaction\") {\n\t\t\t\t\tthrow new Error(t(\"Completed compaction is missing from the session context\"));\n\t\t\t\t}\n\t\t\t\thost.chatContainer.clear();\n\t\t\t\t// The latest compaction is prepended for model context; append it below at its chronological position.\n\t\t\t\thost.renderSessionEntries(entries.slice(1));\n\t\t\t\thost.addMessageToChat(\n\t\t\t\t\tcreateCompactionSummaryMessage(\n\t\t\t\t\t\tevent.result.summary,\n\t\t\t\t\t\tevent.result.tokensBefore,\n\t\t\t\t\t\tnew Date().toISOString(),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tif (event.result.usage) {\n\t\t\t\t\thost.addCompactionCostNotice({\n\t\t\t\t\t\ttype: \"compaction_cost\",\n\t\t\t\t\t\tkind: \"compaction\",\n\t\t\t\t\t\tusage: event.result.usage,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\thost.footer.invalidate();\n\t\t\t} else if (event.errorMessage) {\n\t\t\t\tif (event.reason === \"manual\") {\n\t\t\t\t\thost.showError(event.errorMessage);\n\t\t\t\t} else {\n\t\t\t\t\thost.chatContainer.addChild(new Spacer(1));\n\t\t\t\t\thost.chatContainer.addChild(new Text(theme.fg(\"error\", event.errorMessage), 1, 0));\n\t\t\t\t}\n\t\t\t}\n\t\t\tvoid host.flushCompactionQueue({ willRetry: event.willRetry });\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"compaction_skipped\": {\n\t\t\thost.showStatus(t(\"Auto-compaction skipped: nothing to compact\"));\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"auto_retry_start\": {\n\t\t\t// Set up escape to abort retry\n\t\t\thost.retryEscapeHandler = host.defaultEditor.onEscape;\n\t\t\thost.defaultEditor.onEscape = () => {\n\t\t\t\thost.facade.abortRetry();\n\t\t\t};\n\t\t\thost.showStatusIndicator(new RetryStatusIndicator(host.ui, event.attempt, event.maxAttempts, event.delayMs));\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"auto_retry_end\": {\n\t\t\t// Restore escape handler\n\t\t\tif (host.retryEscapeHandler) {\n\t\t\t\thost.defaultEditor.onEscape = host.retryEscapeHandler;\n\t\t\t\thost.retryEscapeHandler = undefined;\n\t\t\t}\n\t\t\thost.clearStatusIndicator(\"retry\");\n\t\t\t// Show error only on final failure (success shows normal response)\n\t\t\tif (!event.success) {\n\t\t\t\thost.showError(\n\t\t\t\t\tt(\"Retry failed after {count} attempts: {error}\", {\n\t\t\t\t\t\tcount: event.attempt,\n\t\t\t\t\t\terror: event.finalError || t(\"Unknown error\"),\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"summarization_retry_scheduled\": {\n\t\t\thost.showError(event.errorMessage);\n\t\t\thost.showStatusIndicator(new RetryStatusIndicator(host.ui, event.attempt, event.maxAttempts, event.delayMs));\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"summarization_retry_attempt_start\": {\n\t\t\thost.clearStatusIndicator(\"retry\");\n\t\t\tif (event.source === \"branchSummary\") {\n\t\t\t\thost.showStatusIndicator(new BranchSummaryStatusIndicator(host.ui));\n\t\t\t} else {\n\t\t\t\thost.showStatusIndicator(new CompactionStatusIndicator(host.ui, event.reason));\n\t\t\t}\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase \"summarization_retry_finished\": {\n\t\t\thost.clearStatusIndicator(\"retry\");\n\t\t\thost.ui.requestRender();\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/** Extract text content from a user message */\nexport function getUserMessageText(message: Message): string {\n\tif (message.role !== \"user\") return \"\";\n\tconst textBlocks =\n\t\ttypeof message.content === \"string\"\n\t\t\t? [{ type: \"text\", text: message.content }]\n\t\t\t: message.content.filter((c: { type: string }) => c.type === \"text\");\n\treturn textBlocks.map((c) => (c as { text: string }).text).join(\"\");\n}\n\nexport function addMessageToChat(\n\thost: EventsHost,\n\tmessage: AgentMessage,\n\toptions?: { populateHistory?: boolean },\n): void {\n\tswitch (message.role) {\n\t\tcase \"bashExecution\": {\n\t\t\tconst component = new BashExecutionComponent(message.command, host.ui, message.excludeFromContext);\n\t\t\tif (message.output) {\n\t\t\t\tcomponent.appendOutput(message.output);\n\t\t\t}\n\t\t\tcomponent.setComplete(\n\t\t\t\tmessage.exitCode,\n\t\t\t\tmessage.cancelled,\n\t\t\t\tmessage.truncated ? ({ truncated: true } as TruncationResult) : undefined,\n\t\t\t\tmessage.fullOutputPath,\n\t\t\t);\n\t\t\thost.chatContainer.addChild(component);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"custom\": {\n\t\t\tif (message.display) {\n\t\t\t\tconst renderer = undefined;\n\t\t\t\tconst component = new CustomMessageComponent(\n\t\t\t\t\tmessage,\n\t\t\t\t\trenderer,\n\t\t\t\t\thost.getMarkdownThemeWithSettings(),\n\t\t\t\t\thost.outputPad,\n\t\t\t\t);\n\t\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\t\thost.chatContainer.addChild(component);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase \"compactionSummary\": {\n\t\t\thost.chatContainer.addChild(new Spacer(1));\n\t\t\tconst component = new CompactionSummaryMessageComponent(message, host.getMarkdownThemeWithSettings());\n\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\thost.chatContainer.addChild(component);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"branchSummary\": {\n\t\t\thost.chatContainer.addChild(new Spacer(1));\n\t\t\tconst component = new BranchSummaryMessageComponent(message, host.getMarkdownThemeWithSettings());\n\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\thost.chatContainer.addChild(component);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"user\": {\n\t\t\tconst textContent = host.getUserMessageText(message);\n\t\t\tif (textContent) {\n\t\t\t\tif (host.chatContainer.children.length > 0) {\n\t\t\t\t\thost.chatContainer.addChild(new Spacer(1));\n\t\t\t\t}\n\t\t\t\tconst skillBlock = parseSkillBlock(textContent);\n\t\t\t\tif (skillBlock) {\n\t\t\t\t\t// Render skill block (collapsible)\n\t\t\t\t\tconst component = new SkillInvocationMessageComponent(skillBlock, host.getMarkdownThemeWithSettings());\n\t\t\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\t\t\thost.chatContainer.addChild(component);\n\t\t\t\t\t// Render user message separately if present\n\t\t\t\t\tif (skillBlock.userMessage) {\n\t\t\t\t\t\thost.chatContainer.addChild(new Spacer(1));\n\t\t\t\t\t\tconst userComponent = new UserMessageComponent(\n\t\t\t\t\t\t\tskillBlock.userMessage,\n\t\t\t\t\t\t\thost.getMarkdownThemeWithSettings(),\n\t\t\t\t\t\t\thost.outputPad,\n\t\t\t\t\t\t\thost.getMarkdownTransformers(),\n\t\t\t\t\t\t);\n\t\t\t\t\t\thost.chatContainer.addChild(userComponent);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconst userComponent = new UserMessageComponent(\n\t\t\t\t\t\ttextContent,\n\t\t\t\t\t\thost.getMarkdownThemeWithSettings(),\n\t\t\t\t\t\thost.outputPad,\n\t\t\t\t\t\thost.getMarkdownTransformers(),\n\t\t\t\t\t);\n\t\t\t\t\thost.chatContainer.addChild(userComponent);\n\t\t\t\t}\n\t\t\t\tif (options?.populateHistory) {\n\t\t\t\t\thost.editor.addToHistory?.(textContent);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase \"assistant\": {\n\t\t\tconst assistantComponent = new AssistantMessageComponent(\n\t\t\t\tmessage,\n\t\t\t\thost.hideThinkingBlock,\n\t\t\t\thost.getMarkdownThemeWithSettings(),\n\t\t\t\thost.hiddenThinkingLabel,\n\t\t\t\thost.outputPad,\n\t\t\t\thost.getMarkdownTransformers(),\n\t\t\t);\n\t\t\t// D-083: restored/finished-turn thinking must follow detail mode\n\t\t\t// (ctrl+o) — the setToolsExpanded loop only reaches children on\n\t\t\t// toggle, not components created while already expanded.\n\t\t\tif (host.toolOutputExpanded) {\n\t\t\t\tassistantComponent.setExpanded(true);\n\t\t\t}\n\t\t\thost.chatContainer.addChild(assistantComponent);\n\t\t\tbreak;\n\t\t}\n\t\tcase \"toolResult\": {\n\t\t\t// Tool results are rendered inline with tool calls, handled separately\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t// v8 ignore next -- exhaustive over AgentMessage roles\n\t\t\tconst _exhaustive: never = message;\n\t\t}\n\t}\n}\n\nexport function renderSessionItems(\n\thost: EventsHost,\n\titems: readonly RenderSessionItem[],\n\toptions: { updateFooter?: boolean; populateHistory?: boolean } = {},\n): void {\n\thost.pendingTools.clear();\n\tconst renderedPendingTools = new Map<string, ToolExecutionComponent>();\n\t// Cache-miss notices are not persisted; re-derive them from the full entry\n\t// list and re-inject them after the assistant messages that paid for them.\n\tconst cacheMisses = host.settingsManager.getShowCacheMissNotices()\n\t\t? collectCacheMisses(host.facade.getEntries(), host.facade.getModelPriceSource())\n\t\t: new Map<AssistantMessage, CacheMiss>();\n\n\tif (options.updateFooter) {\n\t\thost.footer.invalidate();\n\t\thost.updateEditorBorderColor();\n\t}\n\n\tfor (const item of items) {\n\t\tif (isCustomSessionEntry(item)) {\n\t\t\t// No entry renderer source since the legacy extension surface was\n\t\t\t// removed; previously renderer-less entries were skipped as well.\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCompactionCostNotice(item)) {\n\t\t\thost.addCompactionCostNotice(item);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst message = item;\n\t\t// Assistant messages need special handling for tool calls\n\t\tif (message.role === \"assistant\") {\n\t\t\thost.addMessageToChat(message);\n\t\t\t// No message_start on the restore path: reset the group pointer\n\t\t\t// so each assistant message forms its own tool-run group (D-083).\n\t\t\thost.activeToolRunGroup = undefined;\n\t\t\t// Render tool call components\n\t\t\tfor (const content of message.content) {\n\t\t\t\tif (content.type === \"toolCall\") {\n\t\t\t\t\tconst component = new ToolExecutionComponent(\n\t\t\t\t\t\tcontent.name,\n\t\t\t\t\t\tcontent.id,\n\t\t\t\t\t\tcontent.arguments,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tshowImages: host.settingsManager.getShowImages(),\n\t\t\t\t\t\t\timageWidthCells: host.settingsManager.getImageWidthCells(),\n\t\t\t\t\t\t},\n\t\t\t\t\t\thost.getRegisteredToolDefinition(content.name),\n\t\t\t\t\t\thost.ui,\n\t\t\t\t\t\thost.facade.getCwd(),\n\t\t\t\t\t);\n\t\t\t\t\tcomponent.setExpanded(host.toolOutputExpanded);\n\t\t\t\t\thost.addToolToRunGroup(component);\n\n\t\t\t\t\tif (message.stopReason === \"aborted\" || message.stopReason === \"error\") {\n\t\t\t\t\t\tlet errorMessage: string;\n\t\t\t\t\t\tif (message.stopReason === \"aborted\") {\n\t\t\t\t\t\t\tconst retryAttempt = host.facade.getRetryAttempt();\n\t\t\t\t\t\t\terrorMessage =\n\t\t\t\t\t\t\t\tretryAttempt > 0\n\t\t\t\t\t\t\t\t\t? retryAttempt === 1\n\t\t\t\t\t\t\t\t\t\t? t(\"Aborted after {count} retry attempt\", { count: retryAttempt })\n\t\t\t\t\t\t\t\t\t\t: t(\"Aborted after {count} retry attempts\", { count: retryAttempt })\n\t\t\t\t\t\t\t\t\t: t(\"Operation aborted\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\terrorMessage = message.errorMessage || t(\"Error\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcomponent.updateResult({ content: [{ type: \"text\", text: errorMessage }], isError: true });\n\t\t\t\t\t\thost.noteResultInActiveToolRunGroup(true);\n\t\t\t\t\t} else {\n\t\t\t\t\t\trenderedPendingTools.set(content.id, component);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\thost.markActiveToolRunGroupComplete();\n\t\t\tif (message.stopReason !== \"aborted\" && message.stopReason !== \"error\") {\n\t\t\t\tconst miss = cacheMisses.get(message);\n\t\t\t\tif (miss) host.addCacheMissNotice(miss);\n\t\t\t}\n\t\t} else if (message.role === \"toolResult\") {\n\t\t\t// Match tool results to pending tool components\n\t\t\tconst component = renderedPendingTools.get(message.toolCallId);\n\t\t\tif (component) {\n\t\t\t\tcomponent.updateResult(message);\n\t\t\t\t// Failure never goes silent (D-083): count it on the group\n\t\t\t\t// the restored tool call belongs to.\n\t\t\t\thost.noteResultInActiveToolRunGroup(message.isError);\n\t\t\t\trenderedPendingTools.delete(message.toolCallId);\n\t\t\t}\n\t\t} else {\n\t\t\t// All other messages use standard rendering\n\t\t\thost.addMessageToChat(message, options);\n\t\t}\n\t}\n\n\tfor (const [toolCallId, component] of renderedPendingTools) {\n\t\thost.pendingTools.set(toolCallId, component);\n\t}\n\t// Groups stay in the transcript; reset the pointer so a live turn\n\t// starts a fresh group (D-083).\n\thost.activeToolRunGroup = undefined;\n\thost.ui.requestRender();\n}\n\n/**\n * Render session entries to chat. Used for initial load and rebuild after compaction.\n * @param entries Compaction-aware session entries to render\n * @param options.updateFooter Update footer state\n * @param options.populateHistory Add user messages to editor history\n */\nexport function renderSessionEntries(\n\thost: EventsHost,\n\tentries: SessionEntry[],\n\toptions: { updateFooter?: boolean; populateHistory?: boolean } = {},\n): void {\n\tconst items = entries.flatMap((entry): RenderSessionItem[] => {\n\t\tif (entry.type === \"custom\") {\n\t\t\treturn [entry];\n\t\t}\n\t\tconst messages = sessionEntryToContextMessages(entry);\n\t\tif ((entry.type === \"compaction\" || entry.type === \"branch_summary\") && entry.usage && messages.length > 0) {\n\t\t\treturn [...messages, { type: \"compaction_cost\", kind: entry.type, usage: entry.usage }];\n\t\t}\n\t\treturn messages;\n\t});\n\thost.renderSessionItems(items, options);\n}\n\n/**\n * Render billing usage for a compaction or branch summary. The notice is derived\n * from persisted summary usage and is not stored as a separate session entry.\n */\nexport function addCompactionCostNotice(host: EventsHost, notice: CompactionCostNotice): void {\n\tif (!host.settingsManager.getShowCacheMissNotices()) return;\n\n\tconst { usage } = notice;\n\tconst tokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;\n\tconst cost = usage.cost.total >= 0.01 ? ` (~$${usage.cost.total.toFixed(2)})` : \"\";\n\tconst label = notice.kind === \"compaction\" ? t(\"Compaction\") : t(\"Branch summary\");\n\thost.chatContainer.addChild(new Spacer(1));\n\thost.chatContainer.addChild(\n\t\tnew Text(\n\t\t\ttheme.fg(\"warning\", `${label}: ${t(\"{tokens} tokens billed{cost}\", { tokens: formatTokens(tokens), cost })}`),\n\t\t\t1,\n\t\t\t0,\n\t\t),\n\t);\n}\n\nfunction countDroppedThinkingBlocks(message: AssistantMessage): number {\n\tlet count = 0;\n\tfor (const diagnostic of message.diagnostics ?? []) {\n\t\tif (diagnostic.type !== \"anthropic_input_transformations\") continue;\n\t\tconst transformations = diagnostic.details?.transformations;\n\t\tif (!Array.isArray(transformations)) continue;\n\t\tcount += transformations.filter(\n\t\t\t(transformation) =>\n\t\t\t\ttypeof transformation === \"object\" &&\n\t\t\t\ttransformation !== null &&\n\t\t\t\t(transformation as Record<string, unknown>).type === \"thinking_dropped\",\n\t\t).length;\n\t}\n\treturn count;\n}\n\nexport function maybeShowThinkingDropNotice(host: EventsHost, message: AssistantMessage): void {\n\tif (!host.settingsManager.getShowCacheMissNotices()) return;\n\n\tconst droppedCount = countDroppedThinkingBlocks(message);\n\tif (droppedCount === 0) return;\n\n\tlet previousDroppedCount = 0;\n\t// message_end reaches the UI before the current message is persisted,\n\t// so the branch's last assistant message is the previous response.\n\tconst entries = host.facade.getEntries();\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tif (entry.type === \"message\" && entry.message.role === \"assistant\") {\n\t\t\tpreviousDroppedCount = countDroppedThinkingBlocks(entry.message);\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (droppedCount <= previousDroppedCount) return;\n\n\thost.chatContainer.addChild(new Spacer(1));\n\thost.chatContainer.addChild(\n\t\tnew Text(\n\t\t\ttheme.fg(\n\t\t\t\t\"warning\",\n\t\t\t\tt(\"Anthropic dropped {count} thinking blocks (details in session)\", { count: droppedCount }),\n\t\t\t),\n\t\t\t1,\n\t\t\t0,\n\t\t),\n\t);\n}\n\n/**\n * Show a transcript notice when a completed assistant message paid for a\n * significant cache miss. Only states observable facts: the miss itself,\n * a model switch, or an idle gap past the cache TTL.\n */\nexport function maybeShowCacheMissNotice(host: EventsHost, message: AssistantMessage): void {\n\tif (!host.settingsManager.getShowCacheMissNotices()) return;\n\n\t// Entries don't contain `message` yet: message_end fires before persistence.\n\tconst miss = detectCacheMiss(host.facade.getEntries(), message, host.facade.getModelPriceSource());\n\tif (miss) host.addCacheMissNotice(miss);\n}\n\nexport function addCacheMissNotice(host: EventsHost, miss: CacheMiss): void {\n\tif (miss.missedTokens < 20_000 && miss.missedCost < 0.1) return;\n\n\tconst cost = miss.missedCost >= 0.01 ? ` (~$${miss.missedCost.toFixed(2)})` : \"\";\n\tconst reBilled = t(\"{tokens} tokens re-billed{cost}\", { tokens: formatTokens(miss.missedTokens), cost });\n\tlet label = t(\"Cache miss\");\n\tif (miss.modelChanged) {\n\t\tlabel = t(\"Cache miss after model switch\");\n\t} else if (miss.idleMs >= CACHE_TTL_MS) {\n\t\tlabel = t(\"Cache miss after {minutes}m idle\", { minutes: Math.round(miss.idleMs / 60_000) });\n\t}\n\tconst text = theme.fg(\"warning\", `${label}: ${reBilled}`);\n\thost.chatContainer.addChild(new Spacer(1));\n\thost.chatContainer.addChild(new Text(text, 1, 0));\n}\n\nexport function renderInitialMessages(host: EventsHost): void {\n\tconst entries = host.facade.getContextEntries();\n\thost.renderSessionEntries(entries, {\n\t\tupdateFooter: true,\n\t\tpopulateHistory: true,\n\t});\n\t// Show compaction info if session was compacted\n\tconst allEntries = host.facade.getEntries();\n\tconst compactionCount = allEntries.filter((e) => e.type === \"compaction\").length;\n\tif (compactionCount > 0) {\n\t\thost.showStatus(\n\t\t\tcompactionCount === 1\n\t\t\t\t? t(\"Session compacted {count} time\", { count: compactionCount })\n\t\t\t\t: t(\"Session compacted {count} times\", { count: compactionCount }),\n\t\t);\n\t}\n}\n\nexport function rebuildChatFromMessages(host: EventsHost): void {\n\thost.chatContainer.clear();\n\thost.renderSessionEntries(host.facade.getContextEntries());\n}\n\nexport function getRegisteredToolDefinition(host: EventsHost, toolName: string) {\n\treturn host.facade.getToolDefinition(toolName);\n}\n\nexport function getMarkdownTransformers(host: EventsHost): MarkdownTransformer[] {\n\treturn [host.mermaidMarkdownTransformer];\n}\n\n/**\n * D-083 quiet transcript: mount a tool component into the current\n * assistant turn's tool-run group (creating the group on first tool of\n * the turn) instead of the chat container directly. Collapsed groups\n * render one dim marker line for the whole turn.\n */\nexport function addToolToRunGroup(host: EventsHost, component: ToolExecutionComponent): void {\n\tif (!host.activeToolRunGroup) {\n\t\thost.activeToolRunGroup = new ToolRunGroupComponent();\n\t\thost.activeToolRunGroup.setExpanded(host.toolOutputExpanded);\n\t\thost.chatContainer.addChild(host.activeToolRunGroup);\n\t}\n\thost.activeToolRunGroup.addTool(component);\n}\n\n/**\n * Narrowing-safe faces for the active group inside renderSessionItems:\n * addToolToRunGroup may (re)assign host.activeToolRunGroup behind the\n * compiler's back, so group reads go through methods instead of the\n * narrowed property reference.\n */\nexport function noteResultInActiveToolRunGroup(host: EventsHost, isError: boolean): void {\n\thost.activeToolRunGroup?.noteResult(isError);\n}\n\nexport function markActiveToolRunGroupComplete(host: EventsHost): void {\n\thost.activeToolRunGroup?.markRunComplete();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-format.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-format.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { theme } from \"../../theme/theme.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import { t } from "../../core/i18n/index.js";
|
|
9
|
+
import { theme } from "../../theme/theme.js";
|
|
9
10
|
import { parseGitUrl } from "../../utils/git.js";
|
|
10
11
|
import { getCwdRelativePath } from "../../utils/paths.js";
|
|
11
|
-
import { theme } from "./theme/theme.js";
|
|
12
12
|
export function formatMetricsPercent(ratio) {
|
|
13
13
|
return `${(ratio * 100).toFixed(1)}%`;
|
|
14
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-format.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-format.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-format.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure formatting helpers for interactive mode: metrics snapshots and\n * path/source/scope display formatting. Implementations live here;\n * InteractiveMode keeps thin instance delegates for compatibility.\n */\n\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { ResourceDiagnostic } from \"../../core/resource-loader.ts\";\nimport type { SourceInfo } from \"../../core/source-info.ts\";\nimport type { MetricsSnapshotV1 } from \"../../plugins/observability-types.ts\";\nimport { theme } from \"../../theme/theme.ts\";\nimport { parseGitUrl } from \"../../utils/git.ts\";\nimport { getCwdRelativePath } from \"../../utils/paths.ts\";\n\nexport function formatMetricsPercent(ratio: number): string {\n\treturn `${(ratio * 100).toFixed(1)}%`;\n}\n\nexport function formatMetricsDuration(ms: number | null): string {\n\tif (ms === null) return \"n/a\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nexport function formatMetricsSnapshot(snapshot: MetricsSnapshotV1): string {\n\tlet info = `${theme.bold(t(\"Product Metrics\"))}\\n\\n`;\n\tconst bound =\n\t\tsnapshot.window.windowTurns === null\n\t\t\t? t(\"whole journal\")\n\t\t\t: t(\"last {count} turns\", { count: snapshot.window.windowTurns });\n\tinfo += `${theme.fg(\"dim\", t(\"Window:\"))} ${bound} ${t(\"({count} sampled)\", { count: snapshot.window.sampledTurns })}\\n`;\n\n\tconst successRate =\n\t\tsnapshot.turns.successRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.turns.successRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turns:\"))} ${t(\"{count} total, {succeeded} succeeded\", {\n\t\tcount: snapshot.turns.count,\n\t\tsucceeded: snapshot.turns.successCount,\n\t})}${successRate}\\n`;\n\tinfo += `${theme.fg(\"dim\", t(\"Turn duration:\"))} p50 ${formatMetricsDuration(snapshot.turns.p50DurationMs)}, p95 ${formatMetricsDuration(snapshot.turns.p95DurationMs)}\\n`;\n\n\tconst errorRate = snapshot.tools.errorRate === null ? \"\" : ` (${formatMetricsPercent(snapshot.tools.errorRate)})`;\n\tinfo += `${theme.fg(\"dim\", t(\"Tools:\"))} ${t(\"{calls} calls, {errors} errors\", {\n\t\tcalls: snapshot.tools.calls,\n\t\terrors: snapshot.tools.errors,\n\t})}${errorRate}\\n`;\n\tif (snapshot.tools.topErrors.length > 0) {\n\t\tconst top = snapshot.tools.topErrors.map((entry) => `${entry.toolName} (${entry.errors})`).join(\", \");\n\t\tinfo += `${theme.fg(\"dim\", t(\"Top errors:\"))} ${top}\\n`;\n\t}\n\n\tconst memoryRecall =\n\t\tsnapshot.memoryRecall.status === \"sampled\"\n\t\t\t? t(\"{calls} calls, {hits} hits ({percent})\", {\n\t\t\t\t\tcalls: snapshot.memoryRecall.calls,\n\t\t\t\t\thits: snapshot.memoryRecall.hits,\n\t\t\t\t\tpercent: formatMetricsPercent(snapshot.memoryRecall.hitRate),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.memoryRecall.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Memory recall:\"))} ${memoryRecall}\\n`;\n\n\tconst cancelLatency =\n\t\tsnapshot.cancelLatencyMs.status === \"sampled\"\n\t\t\t? t(\"{count} samples, p95 {p95}\", {\n\t\t\t\t\tcount: snapshot.cancelLatencyMs.count,\n\t\t\t\t\tp95: formatMetricsDuration(snapshot.cancelLatencyMs.p95Ms),\n\t\t\t\t})\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.cancelLatencyMs.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Cancel latency:\"))} ${cancelLatency}\\n`;\n\n\tconst tokens =\n\t\tsnapshot.tokens.status === \"sampled\"\n\t\t\t? t(\"{count} tokens\", { count: snapshot.tokens.totalTokens })\n\t\t\t: t(\"not sampled ({reason})\", { reason: snapshot.tokens.reason });\n\tinfo += `${theme.fg(\"dim\", t(\"Tokens:\"))} ${tokens}\\n`;\n\treturn info;\n}\n\nexport function formatDisplayPath(p: string): string {\n\tconst home = os.homedir();\n\tlet result = p;\n\n\t// Replace home directory with ~. On Windows the path may arrive with\n\t// forward slashes while homedir() uses backslashes, so compare both in\n\t// slash form and keep the output in the path's own form.\n\tif (result.startsWith(home)) {\n\t\tresult = `~${result.slice(home.length)}`;\n\t} else {\n\t\tconst homeSlash = home.replaceAll(\"\\\\\", \"/\");\n\t\tconst resultSlash = result.replaceAll(\"\\\\\", \"/\");\n\t\tif (homeSlash !== home && resultSlash.startsWith(homeSlash)) {\n\t\t\tresult = `~${resultSlash.slice(homeSlash.length)}`;\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/** Resolve a path against cwd and prefer a cwd-relative rendering. */\nexport function formatContextPath(p: string, cwd: string): string {\n\tconst resolvedCwd = path.resolve(cwd);\n\tconst absolutePath = path.isAbsolute(p) ? path.resolve(p) : path.resolve(resolvedCwd, p);\n\tconst relativePath = getCwdRelativePath(absolutePath, resolvedCwd);\n\tif (relativePath !== undefined) {\n\t\treturn relativePath;\n\t}\n\n\treturn formatDisplayPath(absolutePath);\n}\n\nexport function isPackageSource(sourceInfo?: SourceInfo): boolean {\n\tconst source = sourceInfo?.source ?? \"\";\n\treturn source.startsWith(\"npm:\") || source.startsWith(\"git:\");\n}\n\n/**\n * Get a short path relative to the package root for display.\n */\nexport function getShortPath(fullPath: string, sourceInfo?: SourceInfo): string {\n\tconst normalizedFullPath = fullPath.replace(/\\\\/g, \"/\");\n\tconst baseDir = sourceInfo?.baseDir;\n\tif (baseDir && isPackageSource(sourceInfo)) {\n\t\tconst normalizedBaseDir = baseDir.replace(/\\\\/g, \"/\");\n\t\tconst npmRootMatch = normalizedBaseDir.match(/^(.*\\/node_modules)\\/(@?[^/]+(?:\\/[^/]+)?)$/);\n\t\t// If fullPath is under the same node_modules root as baseDir, preserve that relative topology.\n\t\tif (npmRootMatch?.[1] && normalizedFullPath.startsWith(`${npmRootMatch[1]}/`)) {\n\t\t\treturn path.posix.relative(normalizedBaseDir, normalizedFullPath);\n\t\t}\n\n\t\tconst relativePath = path.relative(path.resolve(baseDir), path.resolve(fullPath));\n\t\tif (\n\t\t\trelativePath &&\n\t\t\trelativePath !== \".\" &&\n\t\t\t!relativePath.startsWith(\"..\") &&\n\t\t\t!relativePath.startsWith(`..${path.sep}`) &&\n\t\t\t!path.isAbsolute(relativePath)\n\t\t) {\n\t\t\treturn relativePath.replace(/\\\\/g, \"/\");\n\t\t}\n\t}\n\n\tconst source = sourceInfo?.source ?? \"\";\n\tconst npmMatch = normalizedFullPath.match(/node_modules\\/(@?[^/]+(?:\\/[^/]+)?)\\/(.*)/);\n\tif (npmMatch && source.startsWith(\"npm:\")) {\n\t\treturn npmMatch[2];\n\t}\n\n\tconst gitMatch = normalizedFullPath.match(/git\\/[^/]+\\/[^/]+\\/(.*)/);\n\tif (gitMatch && source.startsWith(\"git:\")) {\n\t\treturn gitMatch[1];\n\t}\n\n\treturn formatDisplayPath(fullPath);\n}\n\nexport function getCompactPathLabel(resourcePath: string, sourceInfo?: SourceInfo): string {\n\tconst shortPath = getShortPath(resourcePath, sourceInfo);\n\tconst normalizedPath = shortPath.replace(/\\\\/g, \"/\");\n\tconst segments = normalizedPath.split(\"/\").filter((segment) => segment.length > 0 && segment !== \"~\");\n\tif (segments.length > 0) {\n\t\treturn segments[segments.length - 1]!;\n\t}\n\treturn shortPath;\n}\n\nexport function getCompactPackageSourceLabel(sourceInfo?: SourceInfo): string {\n\tconst source = sourceInfo?.source ?? \"\";\n\tif (source.startsWith(\"npm:\")) {\n\t\treturn source.slice(\"npm:\".length) || source;\n\t}\n\n\tconst gitSource = parseGitUrl(source);\n\tif (gitSource) {\n\t\t// v8 ignore next -- buildGitSource 仅在 path 非空时返回,|| 回退不可达\n\t\treturn gitSource.path || source;\n\t}\n\n\treturn source;\n}\n\nexport function getDisplaySourceInfo(sourceInfo?: SourceInfo): {\n\tlabel: string;\n\tscopeLabel?: string;\n\tcolor: \"accent\" | \"muted\";\n} {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"local\") {\n\t\tif (scope === \"user\") {\n\t\t\treturn { label: \"user\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"project\") {\n\t\t\treturn { label: \"project\", color: \"muted\" };\n\t\t}\n\t\tif (scope === \"temporary\") {\n\t\t\treturn { label: \"path\", scopeLabel: \"temp\", color: \"muted\" };\n\t\t}\n\t\treturn { label: \"path\", color: \"muted\" };\n\t}\n\n\tif (source === \"cli\") {\n\t\treturn { label: \"path\", scopeLabel: scope === \"temporary\" ? \"temp\" : undefined, color: \"muted\" };\n\t}\n\n\tconst scopeLabel =\n\t\tscope === \"user\" ? \"user\" : scope === \"project\" ? \"project\" : scope === \"temporary\" ? \"temp\" : undefined;\n\treturn { label: source, scopeLabel, color: \"accent\" };\n}\n\nexport function getScopeGroup(sourceInfo?: SourceInfo): \"user\" | \"project\" | \"path\" {\n\tconst source = sourceInfo?.source ?? \"local\";\n\tconst scope = sourceInfo?.scope ?? \"project\";\n\tif (source === \"cli\" || scope === \"temporary\") return \"path\";\n\tif (scope === \"user\") return \"user\";\n\tif (scope === \"project\") return \"project\";\n\treturn \"path\";\n}\n\nexport function buildScopeGroups(items: Array<{ path: string; sourceInfo?: SourceInfo }>): Array<{\n\tscope: \"user\" | \"project\" | \"path\";\n\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n}> {\n\tconst groups: Record<\n\t\t\"user\" | \"project\" | \"path\",\n\t\t{\n\t\t\tscope: \"user\" | \"project\" | \"path\";\n\t\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t\t}\n\t> = {\n\t\tuser: { scope: \"user\", paths: [], packages: new Map() },\n\t\tproject: { scope: \"project\", paths: [], packages: new Map() },\n\t\tpath: { scope: \"path\", paths: [], packages: new Map() },\n\t};\n\n\tfor (const item of items) {\n\t\tconst groupKey = getScopeGroup(item.sourceInfo);\n\t\tconst group = groups[groupKey];\n\t\tconst source = item.sourceInfo?.source ?? \"local\";\n\n\t\tif (isPackageSource(item.sourceInfo)) {\n\t\t\tconst list = group.packages.get(source) ?? [];\n\t\t\tlist.push(item);\n\t\t\tgroup.packages.set(source, list);\n\t\t} else {\n\t\t\tgroup.paths.push(item);\n\t\t}\n\t}\n\n\treturn [groups.project, groups.user, groups.path].filter(\n\t\t(group) => group.paths.length > 0 || group.packages.size > 0,\n\t);\n}\n\nexport function formatScopeGroups(\n\tgroups: Array<{\n\t\tscope: \"user\" | \"project\" | \"path\";\n\t\tpaths: Array<{ path: string; sourceInfo?: SourceInfo }>;\n\t\tpackages: Map<string, Array<{ path: string; sourceInfo?: SourceInfo }>>;\n\t}>,\n\toptions: {\n\t\tformatPath: (item: { path: string; sourceInfo?: SourceInfo }) => string;\n\t\tformatPackagePath: (item: { path: string; sourceInfo?: SourceInfo }, source: string) => string;\n\t},\n): string {\n\tconst lines: string[] = [];\n\n\tfor (const group of groups) {\n\t\tlines.push(` ${theme.fg(\"accent\", group.scope)}`);\n\n\t\tconst sortedPaths = [...group.paths].sort((a, b) => a.path.localeCompare(b.path));\n\t\tfor (const item of sortedPaths) {\n\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPath(item)}`));\n\t\t}\n\n\t\tconst sortedPackages = Array.from(group.packages.entries()).sort(([a], [b]) => a.localeCompare(b));\n\t\tfor (const [source, items] of sortedPackages) {\n\t\t\tlines.push(` ${theme.fg(\"mdLink\", source)}`);\n\t\t\tconst sortedPackagePaths = [...items].sort((a, b) => a.path.localeCompare(b.path));\n\t\t\tfor (const item of sortedPackagePaths) {\n\t\t\t\tlines.push(theme.fg(\"dim\", ` ${options.formatPackagePath(item, source)}`));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n\nexport function findSourceInfoForPath(p: string, sourceInfos: Map<string, SourceInfo>): SourceInfo | undefined {\n\tconst exact = sourceInfos.get(p);\n\tif (exact) return exact;\n\n\tlet current = p;\n\twhile (current.includes(\"/\")) {\n\t\tcurrent = current.substring(0, current.lastIndexOf(\"/\"));\n\t\tconst parent = sourceInfos.get(current);\n\t\tif (parent) return parent;\n\t}\n\n\treturn undefined;\n}\n\nexport function formatPathWithSource(p: string, sourceInfo?: SourceInfo): string {\n\tif (sourceInfo) {\n\t\tconst shortPath = getShortPath(p, sourceInfo);\n\t\tconst { label, scopeLabel } = getDisplaySourceInfo(sourceInfo);\n\t\tconst labelText = scopeLabel ? `${label} (${scopeLabel})` : label;\n\t\treturn `${labelText} ${shortPath}`;\n\t}\n\treturn formatDisplayPath(p);\n}\n\nexport function formatDiagnostics(\n\tdiagnostics: readonly ResourceDiagnostic[],\n\tsourceInfos: Map<string, SourceInfo>,\n): string {\n\tconst lines: string[] = [];\n\n\t// Group collision diagnostics by name\n\tconst collisions = new Map<string, ResourceDiagnostic[]>();\n\tconst otherDiagnostics: ResourceDiagnostic[] = [];\n\n\tfor (const d of diagnostics) {\n\t\tif (d.type === \"collision\" && d.collision) {\n\t\t\tconst list = collisions.get(d.collision.name) ?? [];\n\t\t\tlist.push(d);\n\t\t\tcollisions.set(d.collision.name, list);\n\t\t} else {\n\t\t\totherDiagnostics.push(d);\n\t\t}\n\t}\n\n\t// Format collision diagnostics grouped by name\n\tfor (const [name, collisionList] of collisions) {\n\t\tconst first = collisionList[0]?.collision;\n\t\t// v8 ignore next -- collision lists only hold diagnostics whose collision payload is set\n\t\tif (!first) continue;\n\t\tlines.push(theme.fg(\"warning\", ` ${t('\"{name}\" collision:', { name })}`));\n\t\tlines.push(\n\t\t\ttheme.fg(\n\t\t\t\t\"dim\",\n\t\t\t\t` ${theme.fg(\"success\", \"✓\")} ${formatPathWithSource(first.winnerPath, findSourceInfoForPath(first.winnerPath, sourceInfos))}`,\n\t\t\t),\n\t\t);\n\t\tfor (const d of collisionList) {\n\t\t\t// v8 ignore next -- collision 列表仅收集带 collision 载荷的诊断\n\t\t\tif (d.collision) {\n\t\t\t\tlines.push(\n\t\t\t\t\ttheme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\t` ${theme.fg(\"warning\", \"✗\")} ${formatPathWithSource(d.collision.loserPath, findSourceInfoForPath(d.collision.loserPath, sourceInfos))} ${t(\"(skipped)\")}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const d of otherDiagnostics) {\n\t\tif (d.path) {\n\t\t\tconst formattedPath = formatPathWithSource(d.path, findSourceInfoForPath(d.path, sourceInfos));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${formattedPath}`));\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t} else {\n\t\t\tlines.push(theme.fg(d.type === \"error\" ? \"error\" : \"warning\", ` ${d.message}`));\n\t\t}\n\t}\n\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit and signal lifecycle for interactive mode (拆分 slice 4,
|
|
3
|
+
* docs/plans/interactive-mode拆分计划.md): the Ctrl+C / Ctrl+D / Ctrl+Z
|
|
4
|
+
* handlers, graceful shutdown, the dead-terminal emergency exit, the uncaught
|
|
5
|
+
* exception crash handler, and signal-handler registration/unregistration.
|
|
6
|
+
*
|
|
7
|
+
* InteractiveMode implements LifecycleHost and keeps same-name delegate methods
|
|
8
|
+
* so prototype-level tests and the editor key wiring keep working; the
|
|
9
|
+
* functions below receive the mode through LifecycleHost. The main loop
|
|
10
|
+
* (run/init) and the TUI teardown (stop) stay on the mode; formatResumeCommand
|
|
11
|
+
* also stays resident in interactive-mode.ts (D-041 §3.5: the resume hint is
|
|
12
|
+
* host TUI behavior, not a facade contract) and is reached here through the
|
|
13
|
+
* host method.
|
|
14
|
+
*
|
|
15
|
+
* Internal collaboration interface (same pattern as AuthUiHost): not a plugin
|
|
16
|
+
* API and not exported from the package root.
|
|
17
|
+
*/
|
|
18
|
+
import type { TUI } from "@agent-forge/tui";
|
|
19
|
+
import type { CodingAgentRuntimeFacadeV1 } from "../../core/facade/index.ts";
|
|
20
|
+
import type { FullscreenExitOutput } from "../../core/settings-manager.ts";
|
|
21
|
+
import type { InteractiveThemeController } from "../../theme/theme-controller.ts";
|
|
22
|
+
/**
|
|
23
|
+
* Session read view the shutdown resume hint consumes (structural twin of the
|
|
24
|
+
* reads formatResumeCommand takes; the real interface and function stay in
|
|
25
|
+
* ./interactive-mode.ts, D-041 §3.5).
|
|
26
|
+
*/
|
|
27
|
+
interface ShutdownResumeSessionReads {
|
|
28
|
+
isPersisted(): boolean;
|
|
29
|
+
getSessionFile(): string | undefined;
|
|
30
|
+
usesDefaultSessionDir(): boolean;
|
|
31
|
+
getSessionDir(): string;
|
|
32
|
+
getSessionId(): string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Host surface InteractiveMode exposes to this module: the TUI, the runtime
|
|
36
|
+
* facade (dispose), the theme controller, the shutdown state fields, and the
|
|
37
|
+
* mode-owned surfaces shutdown drives (stop, editor clear, status line).
|
|
38
|
+
*
|
|
39
|
+
* Internal collaboration interface (same pattern as AuthUiHost): not a plugin
|
|
40
|
+
* API and not exported from the package root.
|
|
41
|
+
*/
|
|
42
|
+
export interface LifecycleHost {
|
|
43
|
+
ui: TUI;
|
|
44
|
+
/** Stable runtime facade (阶段 4 slice 3): dispose on shutdown. */
|
|
45
|
+
runtimeFacade: CodingAgentRuntimeFacadeV1;
|
|
46
|
+
themeController: InteractiveThemeController;
|
|
47
|
+
/** Timestamp of the last Ctrl+C clear; a second press inside 500ms exits. */
|
|
48
|
+
lastSigintTime: number;
|
|
49
|
+
/** Reentrancy guard shared by shutdown / emergencyTerminalExit / uncaughtCrash. */
|
|
50
|
+
isShuttingDown: boolean;
|
|
51
|
+
/** Set when the session asks the UI to exit once the agent settles. */
|
|
52
|
+
shutdownRequested: boolean;
|
|
53
|
+
/** Cleanup closures for every process-level listener this module registers. */
|
|
54
|
+
signalCleanupHandlers: Array<() => void>;
|
|
55
|
+
/** TUI teardown; stays on the mode (also the /quit-adjacent stop path). */
|
|
56
|
+
stop(fullscreenExitOutput?: FullscreenExitOutput): void;
|
|
57
|
+
clearEditor(): void;
|
|
58
|
+
showStatus(message: string): void;
|
|
59
|
+
shutdown(options?: {
|
|
60
|
+
fromSignal?: boolean;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
emergencyTerminalExit(): never;
|
|
63
|
+
uncaughtCrash(error: Error): never;
|
|
64
|
+
unregisterSignalHandlers(): void;
|
|
65
|
+
/** D-041 §3.5: the function stays resident in interactive-mode.ts. */
|
|
66
|
+
formatResumeCommand(session: ShutdownResumeSessionReads): string | undefined;
|
|
67
|
+
}
|
|
68
|
+
export declare function handleCtrlC(host: LifecycleHost): void;
|
|
69
|
+
export declare function handleCtrlD(host: LifecycleHost): void;
|
|
70
|
+
export declare function shutdown(host: LifecycleHost, options?: {
|
|
71
|
+
fromSignal?: boolean;
|
|
72
|
+
}): Promise<void>;
|
|
73
|
+
export declare function emergencyTerminalExit(host: LifecycleHost): never;
|
|
74
|
+
/**
|
|
75
|
+
* Last-resort handler for uncaught exceptions. The TUI puts stdin into raw
|
|
76
|
+
* mode and hides the cursor; without this handler, an uncaught throw from
|
|
77
|
+
* anywhere (e.g. an extension's async `ChildProcess.on("exit")` callback)
|
|
78
|
+
* tears down the process while leaving the terminal in raw mode with no
|
|
79
|
+
* cursor, requiring `stty sane && reset` to recover.
|
|
80
|
+
*
|
|
81
|
+
* Unlike emergencyTerminalExit, the terminal is still alive here, so we
|
|
82
|
+
* call ui.stop() to restore cooked mode, the cursor, and disable bracketed
|
|
83
|
+
* paste / Kitty / modifyOtherKeys sequences.
|
|
84
|
+
*/
|
|
85
|
+
export declare function uncaughtCrash(host: LifecycleHost, error: Error): never;
|
|
86
|
+
/**
|
|
87
|
+
* Check if shutdown was requested and perform shutdown if so.
|
|
88
|
+
*/
|
|
89
|
+
export declare function checkShutdownRequested(host: LifecycleHost): Promise<void>;
|
|
90
|
+
export declare function registerSignalHandlers(host: LifecycleHost): void;
|
|
91
|
+
export declare function unregisterSignalHandlers(host: LifecycleHost): void;
|
|
92
|
+
export declare function handleCtrlZ(host: LifecycleHost): void;
|
|
93
|
+
export {};
|
|
94
|
+
//# sourceMappingURL=interactive-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAG5C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAIlF;;;;GAIG;AACH,UAAU,0BAA0B;IACnC,WAAW,IAAI,OAAO,CAAC;IACvB,cAAc,IAAI,MAAM,GAAG,SAAS,CAAC;IACrC,qBAAqB,IAAI,OAAO,CAAC;IACjC,aAAa,IAAI,MAAM,CAAC;IACxB,YAAY,IAAI,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,GAAG,CAAC;IACR,qEAAiE;IACjE,aAAa,EAAE,0BAA0B,CAAC;IAC1C,eAAe,EAAE,0BAA0B,CAAC;IAC5C,6EAA6E;IAC7E,cAAc,EAAE,MAAM,CAAC;IACvB,mFAAmF;IACnF,cAAc,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,qBAAqB,EAAE,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;IAEzC,2EAA2E;IAC3E,IAAI,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACxD,WAAW,IAAI,IAAI,CAAC;IACpB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,qBAAqB,IAAI,KAAK,CAAC;IAC/B,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC;IACnC,wBAAwB,IAAI,IAAI,CAAC;IACjC,uEAAsE;IACtE,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,GAAG,SAAS,CAAC;CAC7E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAQrD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAGrD;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuCrG;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,aAAa,GAAG,KAAK,CAOhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAiBtE;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAsChE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAKlE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAmCrD","sourcesContent":["/**\n * Exit and signal lifecycle for interactive mode (拆分 slice 4,\n * docs/plans/interactive-mode拆分计划.md): the Ctrl+C / Ctrl+D / Ctrl+Z\n * handlers, graceful shutdown, the dead-terminal emergency exit, the uncaught\n * exception crash handler, and signal-handler registration/unregistration.\n *\n * InteractiveMode implements LifecycleHost and keeps same-name delegate methods\n * so prototype-level tests and the editor key wiring keep working; the\n * functions below receive the mode through LifecycleHost. The main loop\n * (run/init) and the TUI teardown (stop) stay on the mode; formatResumeCommand\n * also stays resident in interactive-mode.ts (D-041 §3.5: the resume hint is\n * host TUI behavior, not a facade contract) and is reached here through the\n * host method.\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nimport type { TUI } from \"@agent-forge/tui\";\nimport chalk from \"chalk\";\nimport { APP_NAME } from \"../../config.ts\";\nimport type { CodingAgentRuntimeFacadeV1 } from \"../../core/facade/index.ts\";\nimport { t } from \"../../core/i18n/index.ts\";\nimport type { FullscreenExitOutput } from \"../../core/settings-manager.ts\";\nimport type { InteractiveThemeController } from \"../../theme/theme-controller.ts\";\nimport { killTrackedDetachedChildren } from \"../../utils/shell.ts\";\nimport { isDeadTerminalError } from \"./interactive-helpers.ts\";\n\n/**\n * Session read view the shutdown resume hint consumes (structural twin of the\n * reads formatResumeCommand takes; the real interface and function stay in\n * ./interactive-mode.ts, D-041 §3.5).\n */\ninterface ShutdownResumeSessionReads {\n\tisPersisted(): boolean;\n\tgetSessionFile(): string | undefined;\n\tusesDefaultSessionDir(): boolean;\n\tgetSessionDir(): string;\n\tgetSessionId(): string;\n}\n\n/**\n * Host surface InteractiveMode exposes to this module: the TUI, the runtime\n * facade (dispose), the theme controller, the shutdown state fields, and the\n * mode-owned surfaces shutdown drives (stop, editor clear, status line).\n *\n * Internal collaboration interface (same pattern as AuthUiHost): not a plugin\n * API and not exported from the package root.\n */\nexport interface LifecycleHost {\n\tui: TUI;\n\t/** Stable runtime facade (阶段 4 slice 3): dispose on shutdown. */\n\truntimeFacade: CodingAgentRuntimeFacadeV1;\n\tthemeController: InteractiveThemeController;\n\t/** Timestamp of the last Ctrl+C clear; a second press inside 500ms exits. */\n\tlastSigintTime: number;\n\t/** Reentrancy guard shared by shutdown / emergencyTerminalExit / uncaughtCrash. */\n\tisShuttingDown: boolean;\n\t/** Set when the session asks the UI to exit once the agent settles. */\n\tshutdownRequested: boolean;\n\t/** Cleanup closures for every process-level listener this module registers. */\n\tsignalCleanupHandlers: Array<() => void>;\n\n\t/** TUI teardown; stays on the mode (also the /quit-adjacent stop path). */\n\tstop(fullscreenExitOutput?: FullscreenExitOutput): void;\n\tclearEditor(): void;\n\tshowStatus(message: string): void;\n\tshutdown(options?: { fromSignal?: boolean }): Promise<void>;\n\temergencyTerminalExit(): never;\n\tuncaughtCrash(error: Error): never;\n\tunregisterSignalHandlers(): void;\n\t/** D-041 §3.5: the function stays resident in interactive-mode.ts. */\n\tformatResumeCommand(session: ShutdownResumeSessionReads): string | undefined;\n}\n\nexport function handleCtrlC(host: LifecycleHost): void {\n\tconst now = Date.now();\n\tif (now - host.lastSigintTime < 500) {\n\t\tvoid host.shutdown();\n\t} else {\n\t\thost.clearEditor();\n\t\thost.lastSigintTime = now;\n\t}\n}\n\nexport function handleCtrlD(host: LifecycleHost): void {\n\t// Only called when editor is empty (enforced by CustomEditor)\n\tvoid host.shutdown();\n}\n\nexport async function shutdown(host: LifecycleHost, options?: { fromSignal?: boolean }): Promise<void> {\n\tif (host.isShuttingDown) return;\n\thost.isShuttingDown = true;\n\t// Keep signal handlers registered until terminal cleanup has completed.\n\t// `signal-exit` checks the listener list during the same SIGTERM/SIGHUP\n\t// dispatch and re-sends the signal if only its own listeners remain.\n\n\tif (options?.fromSignal) {\n\t\t// Signal-triggered shutdown (SIGTERM/SIGHUP). Emit extension cleanup\n\t\t// (session_shutdown) BEFORE touching the terminal. Extension teardown\n\t\t// such as removing sockets does not write to the tty, so it must not be\n\t\t// skipped if a later terminal-restore write fails on a dead or stalled\n\t\t// terminal. If the terminal is gone, the restore writes below emit EIO,\n\t\t// which the stdout/stderr error handler turns into emergencyTerminalExit;\n\t\t// the render loop is already idle, so this cannot hot-spin (see #4144).\n\t\tawait host.runtimeFacade.dispose();\n\t\thost.themeController.disableAutoSync();\n\t\tawait host.ui.terminal.drainInput(1000);\n\t\thost.stop();\n\t\tprocess.exit(0);\n\t}\n\n\t// Interactive quit (Ctrl+D, Ctrl+C, /quit, extension shutdown()). Stop the\n\t// TUI before emitting shutdown events so extension UI cleanup cannot repaint\n\t// the final frame while the process is exiting.\n\t// Drain any in-flight Kitty key release events before stopping.\n\t// This prevents escape sequences from leaking to the parent shell over slow SSH.\n\thost.themeController.disableAutoSync();\n\tawait host.ui.terminal.drainInput(1000);\n\n\thost.stop();\n\tawait host.runtimeFacade.dispose();\n\n\tconst resumeCommand = host.formatResumeCommand(host.runtimeFacade);\n\tif (resumeCommand) {\n\t\tprocess.stdout.write(`${chalk.dim(t(\"To resume this session:\"))} ${resumeCommand}\\n`);\n\t}\n\n\tprocess.exit(0);\n}\n\nexport function emergencyTerminalExit(host: LifecycleHost): never {\n\thost.isShuttingDown = true;\n\thost.unregisterSignalHandlers();\n\tkillTrackedDetachedChildren();\n\t// The terminal is gone. Do not run normal shutdown because TUI and\n\t// extension cleanup can write restore sequences and re-trigger EIO.\n\tprocess.exit(129);\n}\n\n/**\n * Last-resort handler for uncaught exceptions. The TUI puts stdin into raw\n * mode and hides the cursor; without this handler, an uncaught throw from\n * anywhere (e.g. an extension's async `ChildProcess.on(\"exit\")` callback)\n * tears down the process while leaving the terminal in raw mode with no\n * cursor, requiring `stty sane && reset` to recover.\n *\n * Unlike emergencyTerminalExit, the terminal is still alive here, so we\n * call ui.stop() to restore cooked mode, the cursor, and disable bracketed\n * paste / Kitty / modifyOtherKeys sequences.\n */\nexport function uncaughtCrash(host: LifecycleHost, error: Error): never {\n\tif (host.isShuttingDown) {\n\t\tprocess.exit(1);\n\t}\n\thost.isShuttingDown = true;\n\ttry {\n\t\thost.unregisterSignalHandlers();\n\t} catch {}\n\ttry {\n\t\tkillTrackedDetachedChildren();\n\t} catch {}\n\ttry {\n\t\thost.ui.stop();\n\t} catch {}\n\tconsole.error(t(\"{app} exiting due to uncaughtException:\", { app: APP_NAME }));\n\tconsole.error(error);\n\tprocess.exit(1);\n}\n\n/**\n * Check if shutdown was requested and perform shutdown if so.\n */\nexport async function checkShutdownRequested(host: LifecycleHost): Promise<void> {\n\tif (!host.shutdownRequested) return;\n\tawait host.shutdown();\n}\n\nexport function registerSignalHandlers(host: LifecycleHost): void {\n\thost.unregisterSignalHandlers();\n\n\tconst signals: NodeJS.Signals[] = [\"SIGTERM\"];\n\tif (process.platform !== \"win32\") {\n\t\tsignals.push(\"SIGHUP\");\n\t}\n\n\tfor (const signal of signals) {\n\t\tconst handler = () => {\n\t\t\t// SIGHUP no longer hard-exits: graceful shutdown emits session_shutdown\n\t\t\t// first, then attempts terminal restore. A genuinely dead terminal\n\t\t\t// surfaces as an EIO on the restore writes, which the stdout/stderr\n\t\t\t// error handler converts into emergencyTerminalExit (see #4144, #5080).\n\t\t\tkillTrackedDetachedChildren();\n\t\t\tvoid host.shutdown({ fromSignal: true });\n\t\t};\n\t\tprocess.prependListener(signal, handler);\n\t\thost.signalCleanupHandlers.push(() => process.off(signal, handler));\n\t}\n\n\tconst terminalErrorHandler = (error: Error) => {\n\t\tif (isDeadTerminalError(error)) {\n\t\t\thost.emergencyTerminalExit();\n\t\t}\n\t\tthrow error;\n\t};\n\tprocess.stdout.on(\"error\", terminalErrorHandler);\n\tprocess.stderr.on(\"error\", terminalErrorHandler);\n\thost.signalCleanupHandlers.push(() => process.stdout.off(\"error\", terminalErrorHandler));\n\thost.signalCleanupHandlers.push(() => process.stderr.off(\"error\", terminalErrorHandler));\n\n\t// Restore the terminal before the process dies on any uncaught throw.\n\t// Without this, an unhandled exception from extension code (or anywhere\n\t// in the application) leaves the terminal in raw mode with no cursor.\n\tconst uncaughtExceptionHandler = (error: Error) => host.uncaughtCrash(error);\n\tprocess.prependListener(\"uncaughtException\", uncaughtExceptionHandler);\n\thost.signalCleanupHandlers.push(() => process.off(\"uncaughtException\", uncaughtExceptionHandler));\n}\n\nexport function unregisterSignalHandlers(host: LifecycleHost): void {\n\tfor (const cleanup of host.signalCleanupHandlers) {\n\t\tcleanup();\n\t}\n\thost.signalCleanupHandlers = [];\n}\n\nexport function handleCtrlZ(host: LifecycleHost): void {\n\tif (process.platform === \"win32\") {\n\t\thost.showStatus(t(\"Suspend to background is not supported on Windows\"));\n\t\treturn;\n\t}\n\n\t// Keep the event loop alive while suspended. Without this, stopping the TUI\n\t// can leave Node with no ref'ed handles, causing the process to exit on fg\n\t// before the SIGCONT handler gets a chance to restore the terminal.\n\tconst suspendKeepAlive = setInterval(() => {}, 2 ** 30);\n\n\t// Ignore SIGINT while suspended so Ctrl+C in the terminal does not\n\t// kill the backgrounded process. The handler is removed on resume.\n\tconst ignoreSigint = () => {};\n\tprocess.on(\"SIGINT\", ignoreSigint);\n\n\t// Set up handler to restore TUI when resumed\n\tprocess.once(\"SIGCONT\", () => {\n\t\tclearInterval(suspendKeepAlive);\n\t\tprocess.removeListener(\"SIGINT\", ignoreSigint);\n\t\thost.ui.start();\n\t\thost.ui.requestRender(true);\n\t});\n\n\ttry {\n\t\t// Stop the TUI (restore terminal to normal mode)\n\t\thost.ui.stop();\n\n\t\t// Send SIGTSTP to process group (pid=0 means all processes in group)\n\t\tprocess.kill(0, \"SIGTSTP\");\n\t} catch (error) {\n\t\tclearInterval(suspendKeepAlive);\n\t\tprocess.removeListener(\"SIGINT\", ignoreSigint);\n\t\tthrow error;\n\t}\n}\n"]}
|