@bastani/atomic 0.9.55 → 0.9.56-alpha.1

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.
Files changed (98) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  3. package/dist/builtin/intercom/index.bundle.mjs +2 -1
  4. package/dist/builtin/intercom/package.json +1 -1
  5. package/dist/builtin/mcp/package.json +1 -1
  6. package/dist/builtin/subagents/package.json +1 -1
  7. package/dist/builtin/web-access/package.json +1 -1
  8. package/dist/builtin/workflows/package.json +1 -1
  9. package/dist/cli/args.d.ts.map +1 -1
  10. package/dist/cli/args.js +4 -3
  11. package/dist/cli/args.js.map +1 -1
  12. package/dist/config-self-update.d.ts +1 -0
  13. package/dist/config-self-update.d.ts.map +1 -1
  14. package/dist/config-self-update.js +7 -7
  15. package/dist/config-self-update.js.map +1 -1
  16. package/dist/config.d.ts +13 -0
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +23 -1
  19. package/dist/config.js.map +1 -1
  20. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  21. package/dist/core/export-html/tool-renderer.js +3 -0
  22. package/dist/core/export-html/tool-renderer.js.map +1 -1
  23. package/dist/core/extensions/index.d.ts +1 -1
  24. package/dist/core/extensions/index.d.ts.map +1 -1
  25. package/dist/core/extensions/index.js.map +1 -1
  26. package/dist/core/extensions/message-types.d.ts +3 -2
  27. package/dist/core/extensions/message-types.d.ts.map +1 -1
  28. package/dist/core/extensions/message-types.js.map +1 -1
  29. package/dist/core/extensions/tool-types.d.ts +2 -1
  30. package/dist/core/extensions/tool-types.d.ts.map +1 -1
  31. package/dist/core/extensions/tool-types.js.map +1 -1
  32. package/dist/core/extensions/ui-types.d.ts +12 -1
  33. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  34. package/dist/core/extensions/ui-types.js.map +1 -1
  35. package/dist/core/settings-schema.d.ts +1 -0
  36. package/dist/core/settings-schema.d.ts.map +1 -1
  37. package/dist/core/settings-schema.js +4 -0
  38. package/dist/core/settings-schema.js.map +1 -1
  39. package/dist/core/slash-commands.js +1 -1
  40. package/dist/core/slash-commands.js.map +1 -1
  41. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  42. package/dist/extensions/mcp/cli.js +27 -8
  43. package/dist/extensions/mcp/cli.js.map +1 -1
  44. package/dist/extensions/tool-search/tool.d.ts +21 -3
  45. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  46. package/dist/extensions/tool-search/tool.js +88 -35
  47. package/dist/extensions/tool-search/tool.js.map +1 -1
  48. package/dist/index-extensions.d.ts +1 -1
  49. package/dist/index-extensions.d.ts.map +1 -1
  50. package/dist/index-extensions.js.map +1 -1
  51. package/dist/modes/interactive/chat-input-actions.d.ts +2 -0
  52. package/dist/modes/interactive/chat-input-actions.d.ts.map +1 -1
  53. package/dist/modes/interactive/chat-input-actions.js +4 -1
  54. package/dist/modes/interactive/chat-input-actions.js.map +1 -1
  55. package/dist/modes/interactive/components/chat-session-host-editor.js +1 -0
  56. package/dist/modes/interactive/components/chat-session-host-editor.js.map +1 -1
  57. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/custom-entry.js +2 -1
  59. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  60. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  61. package/dist/modes/interactive/components/custom-message.js +2 -1
  62. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  63. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  64. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  65. package/dist/modes/interactive/components/extension-editor.js +4 -0
  66. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  67. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  68. package/dist/modes/interactive/components/tool-execution.js +3 -1
  69. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  70. package/dist/modes/interactive/external-editor.d.ts +1 -0
  71. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  72. package/dist/modes/interactive/external-editor.js +15 -5
  73. package/dist/modes/interactive/external-editor.js.map +1 -1
  74. package/dist/modes/interactive/interactive-editor-actions.js +1 -0
  75. package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
  76. package/dist/package-manager-cli.d.ts.map +1 -1
  77. package/dist/package-manager-cli.js +46 -2
  78. package/dist/package-manager-cli.js.map +1 -1
  79. package/dist/utils/clipboard-image.d.ts.map +1 -1
  80. package/dist/utils/clipboard-image.js +2 -0
  81. package/dist/utils/clipboard-image.js.map +1 -1
  82. package/dist/utils/clipboard.d.ts.map +1 -1
  83. package/dist/utils/clipboard.js +10 -0
  84. package/dist/utils/clipboard.js.map +1 -1
  85. package/dist/utils/open-browser.d.ts.map +1 -1
  86. package/dist/utils/open-browser.js +3 -1
  87. package/dist/utils/open-browser.js.map +1 -1
  88. package/docs/environment-variables.md +1 -0
  89. package/docs/extensions/authoring.md +10 -11
  90. package/docs/extensions/ui.md +2 -0
  91. package/docs/mcp-servers.md +3 -3
  92. package/docs/reference/cli.md +15 -3
  93. package/docs/sessions.md +10 -0
  94. package/docs/settings.md +1 -0
  95. package/examples/extensions/debug-provider.ts +2 -2
  96. package/npm-shrinkwrap.json +32 -32
  97. package/package.json +3 -3
  98. package/schemas/settings.schema.json +8 -0
@@ -1,6 +1,7 @@
1
1
  import { Box, Container, Markdown, Spacer, Text } from "@earendil-works/pi-tui";
2
2
  import { TASK_COMPLETION_MESSAGE_TYPE } from "../../../core/tasks/completion.js";
3
3
  import { getMarkdownTheme, theme } from "../theme/theme.js";
4
+ import { keyHint, keyText } from "./keybinding-hints.js";
4
5
  import { completionNoticeFromDetails, TaskCompletionMessage } from "./task-completion-message.js";
5
6
  /**
6
7
  * Type guard ensuring a value returned by an extension's custom renderer is a
@@ -79,7 +80,7 @@ export class CustomMessageComponent extends Container {
79
80
  // Try custom renderer first - it handles its own styling
80
81
  if (this.customRenderer) {
81
82
  try {
82
- const component = this.customRenderer(this.message, { expanded: this._expanded, outputPad: this.outputPad }, theme);
83
+ const component = this.customRenderer(this.message, { expanded: this._expanded, outputPad: this.outputPad, keyText, keyHint }, theme);
83
84
  // Explicit null = "handled; render nothing". Skip the leading spacer
84
85
  // and the default box entirely so the entry occupies zero rows. The
85
86
  // workflows inline-form renderer returns null for a rehydrated
@@ -1 +1 @@
1
- {"version":3,"file":"custom-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TextContent } from \"@bastani/pi-ai/compat\";\nimport type { Component } from \"@earendil-works/pi-tui\";\nimport { Box, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { MessageRenderer } from \"../../../core/extensions/types.ts\";\nimport type { CustomMessage } from \"../../../core/messages.ts\";\nimport { TASK_COMPLETION_MESSAGE_TYPE } from \"../../../core/tasks/completion.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { completionNoticeFromDetails, TaskCompletionMessage } from \"./task-completion-message.js\";\n\n/**\n * Type guard ensuring a value returned by an extension's custom renderer is a\n * real TUI Component (exposes a callable `render`). Extension renderer output is\n * untrusted at runtime: a renderer that returns a string or other non-Component\n * value would otherwise be added as a child and crash `Container.render()` with\n * \"child.render is not a function\".\n */\nfunction isRenderableComponent(value: unknown): value is Component {\n\treturn typeof value === \"object\" && value !== null && typeof (value as { render?: unknown }).render === \"function\";\n}\n\n/**\n * Component that renders a custom message entry from extensions.\n * Uses distinct styling to differentiate from user messages.\n */\nexport class CustomMessageComponent extends Container {\n\tprivate message: CustomMessage<unknown>;\n\tprivate customRenderer?: MessageRenderer;\n\tprivate box: Box;\n\tprivate spacer?: Spacer;\n\tprivate customComponent?: Component;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate _expanded = false;\n\tprivate outputPad: number;\n\tprivate renderLatex: boolean;\n\n\tconstructor(\n\t\tmessage: CustomMessage<unknown>,\n\t\tcustomRenderer?: MessageRenderer,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\trenderLatex = true,\n\t) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.customRenderer = customRenderer;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.renderLatex = renderLatex;\n\n\t\t// Create box with purple background (used for default rendering)\n\t\tthis.box = new Box(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\n\t\t// The leading spacer is mounted in rebuild() alongside actual content, so a\n\t\t// renderer that suppresses output (returns null) leaves no blank row.\n\t\tthis.rebuild();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this._expanded !== expanded) {\n\t\t\tthis._expanded = expanded;\n\t\t\tthis.rebuild();\n\t\t}\n\t}\n\n\tsetOutputPad(outputPad: number): void {\n\t\tif (this.outputPad === outputPad) return;\n\t\tthis.outputPad = outputPad;\n\t\tthis.rebuild();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\t// Remove previously mounted content (spacer + content) before rebuilding.\n\t\tif (this.customComponent) {\n\t\t\tthis.removeChild(this.customComponent);\n\t\t\tthis.customComponent = undefined;\n\t\t}\n\t\tif (this.spacer) {\n\t\t\tthis.removeChild(this.spacer);\n\t\t\tthis.spacer = undefined;\n\t\t}\n\t\tthis.removeChild(this.box);\n\t\tif (this.message.customType === TASK_COMPLETION_MESSAGE_TYPE) {\n\t\t\tconst notice = completionNoticeFromDetails(this.message.details);\n\t\t\tif (notice) {\n\t\t\t\tthis.spacer = new Spacer(1);\n\t\t\t\tthis.customComponent = new TaskCompletionMessage(notice, this._expanded);\n\t\t\t\tthis.addChild(this.spacer);\n\t\t\t\tthis.addChild(this.customComponent);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Try custom renderer first - it handles its own styling\n\t\tif (this.customRenderer) {\n\t\t\ttry {\n\t\t\t\tconst component = this.customRenderer(\n\t\t\t\t\tthis.message,\n\t\t\t\t\t{ expanded: this._expanded, outputPad: this.outputPad },\n\t\t\t\t\ttheme,\n\t\t\t\t);\n\t\t\t\t// Explicit null = \"handled; render nothing\". Skip the leading spacer\n\t\t\t\t// and the default box entirely so the entry occupies zero rows. The\n\t\t\t\t// workflows inline-form renderer returns null for a rehydrated\n\t\t\t\t// input-form card on /resume so the input widget does not reappear.\n\t\t\t\tif (component === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Only mount the result if it is a real Component. A non-Component,\n\t\t\t\t// non-null return (string, number, plain object, …) is ignored so we\n\t\t\t\t// fall through to the default rendering path instead of crashing\n\t\t\t\t// Container.render().\n\t\t\t\tif (isRenderableComponent(component)) {\n\t\t\t\t\t// Custom renderer provides its own styled component\n\t\t\t\t\tthis.spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(this.spacer);\n\t\t\t\t\tthis.customComponent = component;\n\t\t\t\t\tthis.addChild(component);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to default rendering\n\t\t\t}\n\t\t}\n\n\t\t// Default rendering uses our box, preceded by the standard leading spacer.\n\t\tthis.spacer = new Spacer(1);\n\t\tthis.addChild(this.spacer);\n\t\tthis.addChild(this.box);\n\t\tthis.box.clear();\n\t\tthis.box.setPaddingX(this.outputPad);\n\n\t\t// Default rendering: label + content\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[${this.message.customType}]\\x1b[22m`);\n\t\tthis.box.addChild(new Text(label, 0, 0));\n\t\tthis.box.addChild(new Spacer(1));\n\n\t\t// Extract text content\n\t\tlet text: string;\n\t\tif (typeof this.message.content === \"string\") {\n\t\t\ttext = this.message.content;\n\t\t} else {\n\t\t\ttext = this.message.content\n\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\\n\");\n\t\t}\n\n\t\tthis.box.addChild(\n\t\t\tnew Markdown(\n\t\t\t\ttext,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t},\n\t\t\t\t{ renderLatex: this.renderLatex },\n\t\t\t),\n\t\t);\n\t}\n}\n"]}
1
+ {"version":3,"file":"custom-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-message.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TextContent } from \"@bastani/pi-ai/compat\";\nimport type { Component } from \"@earendil-works/pi-tui\";\nimport { Box, Container, Markdown, type MarkdownTheme, Spacer, Text } from \"@earendil-works/pi-tui\";\nimport type { MessageRenderer } from \"../../../core/extensions/types.ts\";\nimport type { CustomMessage } from \"../../../core/messages.ts\";\nimport { TASK_COMPLETION_MESSAGE_TYPE } from \"../../../core/tasks/completion.js\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.js\";\nimport { keyHint, keyText } from \"./keybinding-hints.js\";\nimport { completionNoticeFromDetails, TaskCompletionMessage } from \"./task-completion-message.js\";\n\n/**\n * Type guard ensuring a value returned by an extension's custom renderer is a\n * real TUI Component (exposes a callable `render`). Extension renderer output is\n * untrusted at runtime: a renderer that returns a string or other non-Component\n * value would otherwise be added as a child and crash `Container.render()` with\n * \"child.render is not a function\".\n */\nfunction isRenderableComponent(value: unknown): value is Component {\n\treturn typeof value === \"object\" && value !== null && typeof (value as { render?: unknown }).render === \"function\";\n}\n\n/**\n * Component that renders a custom message entry from extensions.\n * Uses distinct styling to differentiate from user messages.\n */\nexport class CustomMessageComponent extends Container {\n\tprivate message: CustomMessage<unknown>;\n\tprivate customRenderer?: MessageRenderer;\n\tprivate box: Box;\n\tprivate spacer?: Spacer;\n\tprivate customComponent?: Component;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate _expanded = false;\n\tprivate outputPad: number;\n\tprivate renderLatex: boolean;\n\n\tconstructor(\n\t\tmessage: CustomMessage<unknown>,\n\t\tcustomRenderer?: MessageRenderer,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\trenderLatex = true,\n\t) {\n\t\tsuper();\n\t\tthis.message = message;\n\t\tthis.customRenderer = customRenderer;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.renderLatex = renderLatex;\n\n\t\t// Create box with purple background (used for default rendering)\n\t\tthis.box = new Box(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\n\t\t// The leading spacer is mounted in rebuild() alongside actual content, so a\n\t\t// renderer that suppresses output (returns null) leaves no blank row.\n\t\tthis.rebuild();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this._expanded !== expanded) {\n\t\t\tthis._expanded = expanded;\n\t\t\tthis.rebuild();\n\t\t}\n\t}\n\n\tsetOutputPad(outputPad: number): void {\n\t\tif (this.outputPad === outputPad) return;\n\t\tthis.outputPad = outputPad;\n\t\tthis.rebuild();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\t// Remove previously mounted content (spacer + content) before rebuilding.\n\t\tif (this.customComponent) {\n\t\t\tthis.removeChild(this.customComponent);\n\t\t\tthis.customComponent = undefined;\n\t\t}\n\t\tif (this.spacer) {\n\t\t\tthis.removeChild(this.spacer);\n\t\t\tthis.spacer = undefined;\n\t\t}\n\t\tthis.removeChild(this.box);\n\t\tif (this.message.customType === TASK_COMPLETION_MESSAGE_TYPE) {\n\t\t\tconst notice = completionNoticeFromDetails(this.message.details);\n\t\t\tif (notice) {\n\t\t\t\tthis.spacer = new Spacer(1);\n\t\t\t\tthis.customComponent = new TaskCompletionMessage(notice, this._expanded);\n\t\t\t\tthis.addChild(this.spacer);\n\t\t\t\tthis.addChild(this.customComponent);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Try custom renderer first - it handles its own styling\n\t\tif (this.customRenderer) {\n\t\t\ttry {\n\t\t\t\tconst component = this.customRenderer(\n\t\t\t\t\tthis.message,\n\t\t\t\t\t{ expanded: this._expanded, outputPad: this.outputPad, keyText, keyHint },\n\t\t\t\t\ttheme,\n\t\t\t\t);\n\t\t\t\t// Explicit null = \"handled; render nothing\". Skip the leading spacer\n\t\t\t\t// and the default box entirely so the entry occupies zero rows. The\n\t\t\t\t// workflows inline-form renderer returns null for a rehydrated\n\t\t\t\t// input-form card on /resume so the input widget does not reappear.\n\t\t\t\tif (component === null) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Only mount the result if it is a real Component. A non-Component,\n\t\t\t\t// non-null return (string, number, plain object, …) is ignored so we\n\t\t\t\t// fall through to the default rendering path instead of crashing\n\t\t\t\t// Container.render().\n\t\t\t\tif (isRenderableComponent(component)) {\n\t\t\t\t\t// Custom renderer provides its own styled component\n\t\t\t\t\tthis.spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(this.spacer);\n\t\t\t\t\tthis.customComponent = component;\n\t\t\t\t\tthis.addChild(component);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to default rendering\n\t\t\t}\n\t\t}\n\n\t\t// Default rendering uses our box, preceded by the standard leading spacer.\n\t\tthis.spacer = new Spacer(1);\n\t\tthis.addChild(this.spacer);\n\t\tthis.addChild(this.box);\n\t\tthis.box.clear();\n\t\tthis.box.setPaddingX(this.outputPad);\n\n\t\t// Default rendering: label + content\n\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[${this.message.customType}]\\x1b[22m`);\n\t\tthis.box.addChild(new Text(label, 0, 0));\n\t\tthis.box.addChild(new Spacer(1));\n\n\t\t// Extract text content\n\t\tlet text: string;\n\t\tif (typeof this.message.content === \"string\") {\n\t\t\ttext = this.message.content;\n\t\t} else {\n\t\t\ttext = this.message.content\n\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t.map((c) => c.text)\n\t\t\t\t.join(\"\\n\");\n\t\t}\n\n\t\tthis.box.addChild(\n\t\t\tnew Markdown(\n\t\t\t\ttext,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t},\n\t\t\t\t{ renderLatex: this.renderLatex },\n\t\t\t),\n\t\t);\n\t}\n}\n"]}
@@ -11,6 +11,8 @@ export declare class ExtensionEditorComponent extends Container implements Focus
11
11
  private tui;
12
12
  private keybindings;
13
13
  private externalEditorCommand;
14
+ /** Shows external editor failures; renders nothing while empty. */
15
+ private externalEditorStatus;
14
16
  private _focused;
15
17
  get focused(): boolean;
16
18
  set focused(value: boolean);
@@ -1 +1 @@
1
- {"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,CAAC,EAAE,aAAa,EACvB,qBAAqB,CAAC,EAAE,MAAM,EAkC9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcpC;YAEa,wBAAwB;CActC"}
1
+ {"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,qBAAqB,CAAS;IACtC,mEAAmE;IACnE,OAAO,CAAC,oBAAoB,CAAsB;IAElD,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,CAAC,EAAE,aAAa,EACvB,qBAAqB,CAAC,EAAE,MAAM,EAmC9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcpC;YAEa,wBAAwB;CAetC"}
@@ -14,6 +14,8 @@ export class ExtensionEditorComponent extends Container {
14
14
  tui;
15
15
  keybindings;
16
16
  externalEditorCommand;
17
+ /** Shows external editor failures; renders nothing while empty. */
18
+ externalEditorStatus = new Text("", 1, 0);
17
19
  _focused = false;
18
20
  get focused() {
19
21
  return this._focused;
@@ -40,6 +42,7 @@ export class ExtensionEditorComponent extends Container {
40
42
  this.onSubmitCallback(text);
41
43
  };
42
44
  this.addChild(this.editor);
45
+ this.addChild(this.externalEditorStatus);
43
46
  this.addChild(new Spacer(1));
44
47
  const hint = keyHint("tui.select.confirm", "submit") +
45
48
  " " +
@@ -72,6 +75,7 @@ export class ExtensionEditorComponent extends Container {
72
75
  command: this.externalEditorCommand,
73
76
  content,
74
77
  });
78
+ this.externalEditorStatus.setText(result.status === "failed" ? theme.fg("warning", result.message) : "");
75
79
  if (result.status === "complete")
76
80
  this.editor.setText(result.content);
77
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor, resolveExternalEditorCommand } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.js\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand = resolveExternalEditorCommand(externalEditorCommand);\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) this.editor.setText(prefill);\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): boolean {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.editor.handleInput(keyData);\n\t\treturn true;\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tif (result.status === \"complete\") this.editor.setText(result.content);\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor, resolveExternalEditorCommand } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.js\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.js\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\t/** Shows external editor failures; renders nothing while empty. */\n\tprivate externalEditorStatus = new Text(\"\", 1, 0);\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand = resolveExternalEditorCommand(externalEditorCommand);\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) this.editor.setText(prefill);\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\t\tthis.addChild(this.externalEditorStatus);\n\t\tthis.addChild(new Spacer(1));\n\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): boolean {\n\t\tconst kb = getKeybindings();\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.editor.handleInput(keyData);\n\t\treturn true;\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tthis.externalEditorStatus.setText(result.status === \"failed\" ? theme.fg(\"warning\", result.message) : \"\");\n\t\t\tif (result.status === \"complete\") this.editor.setText(result.content);\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAuB,SAAS,EAAwC,KAAK,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAExH,OAAO,KAAK,EAAqC,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAU1G,MAAM,WAAW,oBAAoB;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAaF,qBAAa,sBAAuB,SAAQ,SAAS;IACpD,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,qBAAqB,CAAC,CAAY;IAC1C,OAAO,CAAC,uBAAuB,CAAC,CAAY;IAC5C,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,eAAe,CAAe;IACtC,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC,OAAO,CAAC,qBAAqB,CAAC,CAAmC;IACjE,OAAO,CAAC,EAAE,CAAM;IAChB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,YAAY,CAAS;IAC7B,oFAAoF;IACpF,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAC,CAAuB;IACtC,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,aAAa,CAAS;IAE9B,YACC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,oBAAoB,YAAK,EAClC,cAAc,EAAE,aAAa,GAAG,SAAS,EACzC,EAAE,EAAE,GAAG,EACP,GAAG,EAAE,MAAM,EA8BX;IAED,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;IAsBxB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,oBAAoB;IAiB5B;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAI9B;IAOD,oBAAoB,IAAI,IAAI,CAK3B;IAED,eAAe,IAAI,IAAI,CAKtB;IAED,YAAY,CAAC,MAAM,EAAE,oBAAoB,EAAE,SAAS,UAAQ,GAAG,IAAI,CAIlE;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAInC;IAED,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGpC;IAED,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAIjC;IAED,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAKtC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,IAAI,IAAI,CAOd;IAEQ,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BvC;IAED,OAAO,CAAC,aAAa;IAgFrB,OAAO,CAAC,mBAAmB;IAuD3B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,mBAAmB;CAY3B"}
1
+ {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { createAllToolDefinitions } from "../../../core/tools/index.js";
3
3
  import { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from "../../../core/tools/render-utils.js";
4
4
  import { ensurePngTranscoder } from "../../../utils/image-convert.js";
5
5
  import { theme } from "../theme/theme.js";
6
- import { parenthesizedKeyHint } from "./keybinding-hints.js";
6
+ import { keyHint, keyText, parenthesizedKeyHint } from "./keybinding-hints.js";
7
7
  /** Extension tools without a renderer show this many output lines before collapsing. */
8
8
  const FALLBACK_PREVIEW_LINES = 10;
9
9
  const SUBAGENT_RESULT_ANIMATION_TIMER_KEY = "subagentResultAnimationTimer";
@@ -112,6 +112,8 @@ export class ToolExecutionComponent extends Container {
112
112
  isError: this.result?.isError ?? false,
113
113
  durationMs: this.isPartial ? undefined : this.result?.durationMs,
114
114
  outputPad: this.outputPad,
115
+ keyText,
116
+ keyHint,
115
117
  };
116
118
  }
117
119
  createCallFallback() {
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type { ToolDefinition, ToolRenderContext, ToolRenderers } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.js\";\nimport { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { ensurePngTranscoder } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.js\";\nimport { parenthesizedKeyHint } from \"./keybinding-hints.js\";\n\n/** Extension tools without a renderer show this many output lines before collapsing. */\nconst FALLBACK_PREVIEW_LINES = 10;\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n\toutputPad?: number;\n}\n\ntype RenderableToolResult = Omit<AgentToolResult<unknown>, \"details\"> & {\n\tdetails?: unknown;\n\tisError: boolean;\n\tdurationMs?: number;\n};\ntype RenderableImageContent = Extract<RenderableToolResult[\"content\"][number], { type: \"image\" }>;\ntype DisposableRendererComponent = Component & { dispose?: () => void };\n/** Keep isolated-engine image components stable so pi-tui can reuse Kitty uploads. */\ninterface RenderedImageSpec {\n\tdata: string;\n\tmimeType: string;\n\tprotocol: \"kitty\" | \"iterm2\";\n\twidthCells: number;\n}\nconst SUBAGENT_RESULT_ANIMATION_TIMER_KEY = \"subagentResultAnimationTimer\";\nconst SUBAGENT_RESULT_ANIMATION_CLEANUP_KEY = \"subagentResultAnimationCleanup\";\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: Record<string, unknown> = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: unknown;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate outputPad: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolRenderers;\n\tprivate builtInToolDefinition?: ToolDefinition<TSchema, unknown>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\t/** `updateArgs()` ran since the last display update; the next render applies it. */\n\tprivate argsPending = false;\n\tprivate result?: RenderableToolResult;\n\tprivate renderedImageSpecs: RenderedImageSpec[] = [];\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: unknown,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolRenderers | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = createAllToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.outputPad = options.outputPad ?? 1;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<TSchema, unknown>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<TSchema, unknown>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\tdurationMs: this.isPartial ? undefined : this.result?.durationMs,\n\t\t\toutputPad: this.outputPad,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(formatToolCallWithArgs(this.toolName, this.args, theme, this.expanded), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst displayLines = this.expanded ? lines : lines.slice(0, FALLBACK_PREVIEW_LINES);\n\t\tconst remaining = lines.length - displayLines.length;\n\t\tlet text = displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\");\n\t\tif (remaining > 0) {\n\t\t\ttext +=\n\t\t\t\ttheme.fg(\"muted\", \"\\n... \") + parenthesizedKeyHint(\"app.tools.expand\", \"Expand\", `${remaining} more lines`);\n\t\t}\n\t\treturn new Text(text, 0, 0);\n\t}\n\n\t/**\n\t * Show new partial arguments. Applied at the next render, so a call streaming many argument deltas between two\n\t * frames runs its renderer once per frame, not once per delta (earendil-works/pi#9265).\n\t */\n\tupdateArgs(args: unknown): void {\n\t\tthis.args = args;\n\t\tthis.argsPending = true;\n\t\tthis.ui.requestRender();\n\t}\n\n\t// markExecutionStarted / setArgsComplete are idempotent: re-seeding an\n\t// already-started component must not schedule another render, or the\n\t// remote-renderer bridge (EngineRenderService) turns every repeated\n\t// engine_tool_render into a fresh invalidate → render ping-pong (TUI\n\t// flicker while a workflow stage streams).\n\tmarkExecutionStarted(): void {\n\t\tif (this.executionStarted) return;\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tif (this.argsComplete) return;\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(result: RenderableToolResult, isPartial = false): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this.expanded === expanded) return;\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetOutputPad(outputPad: number): void {\n\t\tthis.outputPad = outputPad;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (this.showImages === show) return;\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tconst nextWidth = Math.max(1, Math.floor(width));\n\t\tif (this.imageWidthCells === nextWidth) return;\n\t\tthis.imageWidthCells = nextWidth;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tdispose(): void {\n\t\tthis.disposeRendererComponent(this.callRendererComponent);\n\t\tthis.disposeRendererComponent(this.resultRendererComponent);\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.clearRendererStateTimer(SUBAGENT_RESULT_ANIMATION_TIMER_KEY, SUBAGENT_RESULT_ANIMATION_CLEANUP_KEY);\n\t\tthis.clearRendererStateTimer(\"interval\");\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.argsPending) this.updateDisplay();\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && this.getRenderShell() === \"self\") {\n\t\t\tconst contentLines = this.selfRenderContainer.render(width);\n\t\t\tif (contentLines.length === 0 && this.imageComponents.length === 0) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst lines: string[] = [];\n\t\t\tif (contentLines.length > 0) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(...contentLines);\n\t\t\t}\n\t\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t\tif (spacer) {\n\t\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t\t}\n\t\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t\tif (imageComponent) {\n\t\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn lines;\n\t\t}\n\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.argsPending = false;\n\t\tconst bgFn = this.isPartial\n\t\t\t? (text: string) => theme.bg(\"toolPendingBg\", text)\n\t\t\t: this.result?.isError\n\t\t\t\t? (text: string) => theme.bg(\"toolErrorBg\", text)\n\t\t\t\t: (text: string) => theme.bg(\"toolSuccessBg\", text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t\trenderContainer.setPaddingX(this.outputPad);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\t// A custom renderer may intentionally omit private arguments.\n\t\t\t\t\t// Do not disclose them if that renderer fails.\n\t\t\t\t\trenderContainer.addChild(new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0));\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content, details: this.result.details, terminate: this.result.terminate },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setPaddingX(this.outputPad);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tthis.syncImageComponents();\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate syncImageComponents(): void {\n\t\tconst capabilities = getCapabilities();\n\t\tconst nextSpecs: RenderedImageSpec[] = [];\n\t\tif (this.result && this.showImages && capabilities.images) {\n\t\t\tconst imageBlocks = this.result.content.filter((c): c is RenderableImageContent => c.type === \"image\");\n\t\t\tfor (const image of imageBlocks) {\n\t\t\t\tif (!image.data || !image.mimeType) continue;\n\t\t\t\tnextSpecs.push({\n\t\t\t\t\tdata: image.data,\n\t\t\t\t\tmimeType: image.mimeType,\n\t\t\t\t\tprotocol: capabilities.images,\n\t\t\t\t\twidthCells: this.imageWidthCells,\n\t\t\t\t});\n\t\t\t\tif (image.mimeType !== \"image/png\") {\n\t\t\t\t\tensurePngTranscoder(() => {\n\t\t\t\t\t\tthis.invalidate();\n\t\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst unchanged =\n\t\t\tnextSpecs.length === this.renderedImageSpecs.length &&\n\t\t\tnextSpecs.every((spec, index) => {\n\t\t\t\tconst previous = this.renderedImageSpecs[index];\n\t\t\t\treturn (\n\t\t\t\t\tprevious?.data === spec.data &&\n\t\t\t\t\tprevious.mimeType === spec.mimeType &&\n\t\t\t\t\tprevious.protocol === spec.protocol &&\n\t\t\t\t\tprevious.widthCells === spec.widthCells\n\t\t\t\t);\n\t\t\t});\n\t\tif (unchanged) return;\n\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t\tthis.renderedImageSpecs = nextSpecs;\n\n\t\tfor (const spec of nextSpecs) {\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst image = new Image(\n\t\t\t\tspec.data,\n\t\t\t\tspec.mimeType,\n\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t{ maxWidthCells: spec.widthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(image);\n\t\t\tthis.addChild(image);\n\t\t}\n\t}\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate disposeRendererComponent(component: Component | undefined): void {\n\t\t(component as DisposableRendererComponent | undefined)?.dispose?.();\n\t}\n\n\tprivate clearRendererStateTimer(timerKey: string, cleanupKey?: string): void {\n\t\tconst cleanup = cleanupKey ? this.rendererState[cleanupKey] : undefined;\n\t\tif (typeof cleanup === \"function\") {\n\t\t\tcleanup();\n\t\t\treturn;\n\t\t}\n\t\tconst timer = this.rendererState[timerKey];\n\t\tif (timer === undefined) return;\n\t\tclearInterval(timer as ReturnType<typeof setInterval>);\n\t\tthis.rendererState[timerKey] = undefined;\n\t\tif (cleanupKey) this.rendererState[cleanupKey] = undefined;\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@earendil-works/pi-tui\";\nimport type { TSchema } from \"typebox\";\nimport type { ToolDefinition, ToolRenderContext, ToolRenderers } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.js\";\nimport { formatToolCallWithArgs, getTextOutput as getRenderedTextOutput } from \"../../../core/tools/render-utils.ts\";\nimport { ensurePngTranscoder } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.js\";\nimport { keyHint, keyText, parenthesizedKeyHint } from \"./keybinding-hints.js\";\n\n/** Extension tools without a renderer show this many output lines before collapsing. */\nconst FALLBACK_PREVIEW_LINES = 10;\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n\toutputPad?: number;\n}\n\ntype RenderableToolResult = Omit<AgentToolResult<unknown>, \"details\"> & {\n\tdetails?: unknown;\n\tisError: boolean;\n\tdurationMs?: number;\n};\ntype RenderableImageContent = Extract<RenderableToolResult[\"content\"][number], { type: \"image\" }>;\ntype DisposableRendererComponent = Component & { dispose?: () => void };\n/** Keep isolated-engine image components stable so pi-tui can reuse Kitty uploads. */\ninterface RenderedImageSpec {\n\tdata: string;\n\tmimeType: string;\n\tprotocol: \"kitty\" | \"iterm2\";\n\twidthCells: number;\n}\nconst SUBAGENT_RESULT_ANIMATION_TIMER_KEY = \"subagentResultAnimationTimer\";\nconst SUBAGENT_RESULT_ANIMATION_CLEANUP_KEY = \"subagentResultAnimationCleanup\";\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: Record<string, unknown> = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: unknown;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate outputPad: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolRenderers;\n\tprivate builtInToolDefinition?: ToolDefinition<TSchema, unknown>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\t/** `updateArgs()` ran since the last display update; the next render applies it. */\n\tprivate argsPending = false;\n\tprivate result?: RenderableToolResult;\n\tprivate renderedImageSpecs: RenderedImageSpec[] = [];\n\tprivate hideComponent = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: unknown,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolRenderers | undefined,\n\t\tui: TUI,\n\t\tcwd: string,\n\t) {\n\t\tsuper();\n\t\tthis.toolName = toolName;\n\t\tthis.toolCallId = toolCallId;\n\t\tthis.args = args;\n\t\tthis.toolDefinition = toolDefinition;\n\t\tthis.builtInToolDefinition = createAllToolDefinitions(cwd)[toolName as ToolName];\n\t\tthis.showImages = options.showImages ?? true;\n\t\tthis.imageWidthCells = options.imageWidthCells ?? 60;\n\t\tthis.outputPad = options.outputPad ?? 1;\n\t\tthis.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolDefinition<TSchema, unknown>[\"renderCall\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderCall;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderCall;\n\t\t}\n\t\treturn this.toolDefinition.renderCall ?? this.builtInToolDefinition.renderCall;\n\t}\n\n\tprivate getResultRenderer(): ToolDefinition<TSchema, unknown>[\"renderResult\"] | undefined {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderResult;\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderResult;\n\t\t}\n\t\treturn this.toolDefinition.renderResult ?? this.builtInToolDefinition.renderResult;\n\t}\n\n\tprivate hasRendererDefinition(): boolean {\n\t\treturn this.builtInToolDefinition !== undefined || this.toolDefinition !== undefined;\n\t}\n\n\tprivate getRenderShell(): \"default\" | \"self\" {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t\tdurationMs: this.isPartial ? undefined : this.result?.durationMs,\n\t\t\toutputPad: this.outputPad,\n\t\t\tkeyText,\n\t\t\tkeyHint,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(formatToolCallWithArgs(this.toolName, this.args, theme, this.expanded), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst lines = output.split(\"\\n\");\n\t\tconst displayLines = this.expanded ? lines : lines.slice(0, FALLBACK_PREVIEW_LINES);\n\t\tconst remaining = lines.length - displayLines.length;\n\t\tlet text = displayLines.map((line) => theme.fg(\"toolOutput\", line)).join(\"\\n\");\n\t\tif (remaining > 0) {\n\t\t\ttext +=\n\t\t\t\ttheme.fg(\"muted\", \"\\n... \") + parenthesizedKeyHint(\"app.tools.expand\", \"Expand\", `${remaining} more lines`);\n\t\t}\n\t\treturn new Text(text, 0, 0);\n\t}\n\n\t/**\n\t * Show new partial arguments. Applied at the next render, so a call streaming many argument deltas between two\n\t * frames runs its renderer once per frame, not once per delta (earendil-works/pi#9265).\n\t */\n\tupdateArgs(args: unknown): void {\n\t\tthis.args = args;\n\t\tthis.argsPending = true;\n\t\tthis.ui.requestRender();\n\t}\n\n\t// markExecutionStarted / setArgsComplete are idempotent: re-seeding an\n\t// already-started component must not schedule another render, or the\n\t// remote-renderer bridge (EngineRenderService) turns every repeated\n\t// engine_tool_render into a fresh invalidate → render ping-pong (TUI\n\t// flicker while a workflow stage streams).\n\tmarkExecutionStarted(): void {\n\t\tif (this.executionStarted) return;\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tif (this.argsComplete) return;\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(result: RenderableToolResult, isPartial = false): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tif (this.expanded === expanded) return;\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetOutputPad(outputPad: number): void {\n\t\tthis.outputPad = outputPad;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tif (this.showImages === show) return;\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tconst nextWidth = Math.max(1, Math.floor(width));\n\t\tif (this.imageWidthCells === nextWidth) return;\n\t\tthis.imageWidthCells = nextWidth;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tdispose(): void {\n\t\tthis.disposeRendererComponent(this.callRendererComponent);\n\t\tthis.disposeRendererComponent(this.resultRendererComponent);\n\t\tthis.callRendererComponent = undefined;\n\t\tthis.resultRendererComponent = undefined;\n\t\tthis.clearRendererStateTimer(SUBAGENT_RESULT_ANIMATION_TIMER_KEY, SUBAGENT_RESULT_ANIMATION_CLEANUP_KEY);\n\t\tthis.clearRendererStateTimer(\"interval\");\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (this.argsPending) this.updateDisplay();\n\t\tif (this.hideComponent) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && this.getRenderShell() === \"self\") {\n\t\t\tconst contentLines = this.selfRenderContainer.render(width);\n\t\t\tif (contentLines.length === 0 && this.imageComponents.length === 0) {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\tconst lines: string[] = [];\n\t\t\tif (contentLines.length > 0) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(...contentLines);\n\t\t\t}\n\t\t\tfor (let i = 0; i < this.imageComponents.length; i++) {\n\t\t\t\tconst spacer = this.imageSpacers[i];\n\t\t\t\tif (spacer) {\n\t\t\t\t\tlines.push(...spacer.render(width));\n\t\t\t\t}\n\t\t\t\tconst imageComponent = this.imageComponents[i];\n\t\t\t\tif (imageComponent) {\n\t\t\t\t\tlines.push(...imageComponent.render(width));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn lines;\n\t\t}\n\n\t\treturn super.render(width);\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.argsPending = false;\n\t\tconst bgFn = this.isPartial\n\t\t\t? (text: string) => theme.bg(\"toolPendingBg\", text)\n\t\t\t: this.result?.isError\n\t\t\t\t? (text: string) => theme.bg(\"toolErrorBg\", text)\n\t\t\t\t: (text: string) => theme.bg(\"toolSuccessBg\", text);\n\n\t\tlet hasContent = false;\n\t\tthis.hideComponent = false;\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\t\tif (renderContainer instanceof Box) {\n\t\t\t\trenderContainer.setBgFn(bgFn);\n\t\t\t\trenderContainer.setPaddingX(this.outputPad);\n\t\t\t}\n\t\t\trenderContainer.clear();\n\n\t\t\tconst callRenderer = this.getCallRenderer();\n\t\t\tif (!callRenderer) {\n\t\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\t\thasContent = true;\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\t\t\tthis.callRendererComponent = component;\n\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\thasContent = true;\n\t\t\t\t} catch {\n\t\t\t\t\tthis.callRendererComponent = undefined;\n\t\t\t\t\t// A custom renderer may intentionally omit private arguments.\n\t\t\t\t\t// Do not disclose them if that renderer fails.\n\t\t\t\t\trenderContainer.addChild(new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0));\n\t\t\t\t\thasContent = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.result) {\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\tif (component) {\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst component = resultRenderer(\n\t\t\t\t\t\t\t{ content: this.result.content, details: this.result.details, terminate: this.result.terminate },\n\t\t\t\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.resultRendererComponent = component;\n\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setPaddingX(this.outputPad);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tthis.syncImageComponents();\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\t}\n\n\tprivate syncImageComponents(): void {\n\t\tconst capabilities = getCapabilities();\n\t\tconst nextSpecs: RenderedImageSpec[] = [];\n\t\tif (this.result && this.showImages && capabilities.images) {\n\t\t\tconst imageBlocks = this.result.content.filter((c): c is RenderableImageContent => c.type === \"image\");\n\t\t\tfor (const image of imageBlocks) {\n\t\t\t\tif (!image.data || !image.mimeType) continue;\n\t\t\t\tnextSpecs.push({\n\t\t\t\t\tdata: image.data,\n\t\t\t\t\tmimeType: image.mimeType,\n\t\t\t\t\tprotocol: capabilities.images,\n\t\t\t\t\twidthCells: this.imageWidthCells,\n\t\t\t\t});\n\t\t\t\tif (image.mimeType !== \"image/png\") {\n\t\t\t\t\tensurePngTranscoder(() => {\n\t\t\t\t\t\tthis.invalidate();\n\t\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst unchanged =\n\t\t\tnextSpecs.length === this.renderedImageSpecs.length &&\n\t\t\tnextSpecs.every((spec, index) => {\n\t\t\t\tconst previous = this.renderedImageSpecs[index];\n\t\t\t\treturn (\n\t\t\t\t\tprevious?.data === spec.data &&\n\t\t\t\t\tprevious.mimeType === spec.mimeType &&\n\t\t\t\t\tprevious.protocol === spec.protocol &&\n\t\t\t\t\tprevious.widthCells === spec.widthCells\n\t\t\t\t);\n\t\t\t});\n\t\tif (unchanged) return;\n\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t\tthis.renderedImageSpecs = nextSpecs;\n\n\t\tfor (const spec of nextSpecs) {\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst image = new Image(\n\t\t\t\tspec.data,\n\t\t\t\tspec.mimeType,\n\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t{ maxWidthCells: spec.widthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(image);\n\t\t\tthis.addChild(image);\n\t\t}\n\t}\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate disposeRendererComponent(component: Component | undefined): void {\n\t\t(component as DisposableRendererComponent | undefined)?.dispose?.();\n\t}\n\n\tprivate clearRendererStateTimer(timerKey: string, cleanupKey?: string): void {\n\t\tconst cleanup = cleanupKey ? this.rendererState[cleanupKey] : undefined;\n\t\tif (typeof cleanup === \"function\") {\n\t\t\tcleanup();\n\t\t\treturn;\n\t\t}\n\t\tconst timer = this.rendererState[timerKey];\n\t\tif (timer === undefined) return;\n\t\tclearInterval(timer as ReturnType<typeof setInterval>);\n\t\tthis.rendererState[timerKey] = undefined;\n\t\tif (cleanupKey) this.rendererState[cleanupKey] = undefined;\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
@@ -7,6 +7,7 @@ export type ExternalEditorResult = {
7
7
  content: string;
8
8
  } | {
9
9
  status: "failed";
10
+ message: string;
10
11
  };
11
12
  /**
12
13
  * Quote one argument for `cmd.exe`.
@@ -1 +1 @@
1
- {"version":3,"file":"external-editor.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAiDlG;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED,wBAAgB,4BAA4B,CAC3C,iBAAiB,CAAC,EAAE,MAAM,EAC1B,WAAW,GAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAe,EAC/D,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC1C,MAAM,CAKR;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8CxG"}
1
+ {"version":3,"file":"external-editor.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAiDnH;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI/D;AAED,wBAAgB,4BAA4B,CAC3C,iBAAiB,CAAC,EAAE,MAAM,EAC1B,WAAW,GAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAe,EAC/D,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC1C,MAAM,CAKR;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAwDxG"}
@@ -88,7 +88,7 @@ export async function editInExternalEditor(request) {
88
88
  });
89
89
  const [editor, ...editorArgs] = parseEditorCommand(request.command);
90
90
  if (!editor)
91
- return { status: "failed" };
91
+ return { status: "failed", message: `Failed to launch external editor: ${request.command}` };
92
92
  process.stdout.write(`Launching external editor: ${request.command}\n${APP_NAME} will resume when the editor exits.\n`);
93
93
  // Do not use spawnSync. On Windows, synchronous child_process calls can
94
94
  // leave a console read active and race the editor for keyboard input.
@@ -98,13 +98,23 @@ export async function editInExternalEditor(request) {
98
98
  // quote every token here or paths containing spaces get split apart.
99
99
  const useShell = process.platform === "win32";
100
100
  const spawnArgs = [...editorArgs, filePath];
101
- const exitCode = await new Promise((resolve) => {
101
+ // Null means the editor could not be launched. The editor inherits the cwd so project-relative paths and
102
+ // integrated terminals keep working. A long cwd can break Windows editors: Windows rejects working
103
+ // directories over MAX_PATH, and WSL launches Windows editors (code, notepad.exe) from the cwd's
104
+ // \\wsl.localhost\... path (pi#11592). The cwd is intentionally not changed; failures are reported instead.
105
+ const exit = await new Promise((resolve) => {
102
106
  const child = spawn(useShell ? quoteWindowsShellArgument(editor) : editor, useShell ? spawnArgs.map(quoteWindowsShellArgument) : spawnArgs, { stdio: "inherit", shell: useShell, env: createChildProcessEnvironment() });
103
107
  child.once("error", () => resolve(null));
104
- child.once("close", (code) => resolve(code));
108
+ child.once("close", (code, signal) => resolve(code ?? signal));
105
109
  });
106
- if (exitCode !== 0)
107
- return { status: "failed" };
110
+ if (exit === null)
111
+ return { status: "failed", message: `Failed to launch external editor: ${request.command}` };
112
+ if (exit !== 0) {
113
+ return {
114
+ status: "failed",
115
+ message: `External editor exited with ${typeof exit === "number" ? `code ${exit}` : exit}; prompt unchanged`,
116
+ };
117
+ }
108
118
  return {
109
119
  status: "complete",
110
120
  content: stripBom(readFileSync(filePath, "utf-8")).replace(/\n$/, ""),
@@ -1 +1 @@
1
- {"version":3,"file":"external-editor.js","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../../config.js\";\nimport { createChildProcessEnvironment } from \"../../utils/child-process.ts\";\nimport { stripBom } from \"../../utils/text.ts\";\n\nexport interface ExternalEditorRequest {\n\tcommand: string;\n\tcontent: string;\n}\n\nexport type ExternalEditorResult = { status: \"complete\"; content: string } | { status: \"failed\" };\n\nfunction parseEditorCommand(command: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | null = null;\n\tlet escaped = false;\n\tlet started = false;\n\n\tfor (const character of command) {\n\t\tif (escaped) {\n\t\t\tcurrent += character;\n\t\t\tescaped = false;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (character === \"\\\\\" && quote !== \"'\") {\n\t\t\tescaped = true;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote) {\n\t\t\tif (character === quote) quote = null;\n\t\t\telse current += character;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (character === \"'\" || character === '\"') {\n\t\t\tquote = character;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (/\\s/.test(character)) {\n\t\t\tif (started) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t\tstarted = false;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += character;\n\t\tstarted = true;\n\t}\n\n\tif (escaped) current += \"\\\\\";\n\tif (started) args.push(current);\n\treturn args;\n}\n\n/**\n * Quote one argument for `cmd.exe`.\n *\n * Node does not quote arguments when `shell: true`, so any value holding a\n * space would otherwise be split into several arguments by the shell.\n * Backslashes are only special when they precede a quote, so double just\n * those runs (plus a trailing run, which would escape the closing quote),\n * escape embedded quotes, then wrap the result.\n */\nexport function quoteWindowsShellArgument(value: string): string {\n\tif (value === \"\") return '\"\"';\n\tconst escaped = value.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\*)$/, \"$1$1\");\n\treturn `\"${escaped}\"`;\n}\n\nexport function resolveExternalEditorCommand(\n\tconfiguredCommand?: string,\n\tenvironment: Readonly<Partial<NodeJS.ProcessEnv>> = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (configuredCommand?.trim()) return configuredCommand;\n\tif (environment.VISUAL) return environment.VISUAL;\n\tif (environment.EDITOR) return environment.EDITOR;\n\treturn platform === \"win32\" ? \"notepad\" : \"nano\";\n}\n\nexport async function editInExternalEditor(request: ExternalEditorRequest): Promise<ExternalEditorResult> {\n\tconst directory = mkdtempSync(join(tmpdir(), `${APP_NAME}-editor-`));\n\tconst filePath = join(directory, \"prompt.md\");\n\ttry {\n\t\twriteFileSync(filePath, request.content, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tflag: \"wx\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\tconst [editor, ...editorArgs] = parseEditorCommand(request.command);\n\t\tif (!editor) return { status: \"failed\" };\n\n\t\tprocess.stdout.write(\n\t\t\t`Launching external editor: ${request.command}\\n${APP_NAME} will resume when the editor exits.\\n`,\n\t\t);\n\n\t\t// Do not use spawnSync. On Windows, synchronous child_process calls can\n\t\t// leave a console read active and race the editor for keyboard input.\n\t\t//\n\t\t// The shell is required on Windows so `.cmd`/`.bat` editor launchers\n\t\t// still run, but Node hands the command line to cmd.exe unquoted, so\n\t\t// quote every token here or paths containing spaces get split apart.\n\t\tconst useShell = process.platform === \"win32\";\n\t\tconst spawnArgs = [...editorArgs, filePath];\n\t\tconst exitCode = await new Promise<number | null>((resolve) => {\n\t\t\tconst child = spawn(\n\t\t\t\tuseShell ? quoteWindowsShellArgument(editor) : editor,\n\t\t\t\tuseShell ? spawnArgs.map(quoteWindowsShellArgument) : spawnArgs,\n\t\t\t\t{ stdio: \"inherit\", shell: useShell, env: createChildProcessEnvironment() },\n\t\t\t);\n\t\t\tchild.once(\"error\", () => resolve(null));\n\t\t\tchild.once(\"close\", (code) => resolve(code));\n\t\t});\n\n\t\tif (exitCode !== 0) return { status: \"failed\" };\n\t\treturn {\n\t\t\tstatus: \"complete\",\n\t\t\tcontent: stripBom(readFileSync(filePath, \"utf-8\")).replace(/\\n$/, \"\"),\n\t\t};\n\t} finally {\n\t\ttry {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Cleanup is best effort.\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"external-editor.js","sourceRoot":"","sources":["../../../src/modes/interactive/external-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { APP_NAME } from \"../../config.js\";\nimport { createChildProcessEnvironment } from \"../../utils/child-process.ts\";\nimport { stripBom } from \"../../utils/text.ts\";\n\nexport interface ExternalEditorRequest {\n\tcommand: string;\n\tcontent: string;\n}\n\nexport type ExternalEditorResult = { status: \"complete\"; content: string } | { status: \"failed\"; message: string };\n\nfunction parseEditorCommand(command: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet quote: \"'\" | '\"' | null = null;\n\tlet escaped = false;\n\tlet started = false;\n\n\tfor (const character of command) {\n\t\tif (escaped) {\n\t\t\tcurrent += character;\n\t\t\tescaped = false;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (character === \"\\\\\" && quote !== \"'\") {\n\t\t\tescaped = true;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote) {\n\t\t\tif (character === quote) quote = null;\n\t\t\telse current += character;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (character === \"'\" || character === '\"') {\n\t\t\tquote = character;\n\t\t\tstarted = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (/\\s/.test(character)) {\n\t\t\tif (started) {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t\tstarted = false;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tcurrent += character;\n\t\tstarted = true;\n\t}\n\n\tif (escaped) current += \"\\\\\";\n\tif (started) args.push(current);\n\treturn args;\n}\n\n/**\n * Quote one argument for `cmd.exe`.\n *\n * Node does not quote arguments when `shell: true`, so any value holding a\n * space would otherwise be split into several arguments by the shell.\n * Backslashes are only special when they precede a quote, so double just\n * those runs (plus a trailing run, which would escape the closing quote),\n * escape embedded quotes, then wrap the result.\n */\nexport function quoteWindowsShellArgument(value: string): string {\n\tif (value === \"\") return '\"\"';\n\tconst escaped = value.replace(/(\\\\*)\"/g, '$1$1\\\\\"').replace(/(\\\\*)$/, \"$1$1\");\n\treturn `\"${escaped}\"`;\n}\n\nexport function resolveExternalEditorCommand(\n\tconfiguredCommand?: string,\n\tenvironment: Readonly<Partial<NodeJS.ProcessEnv>> = process.env,\n\tplatform: NodeJS.Platform = process.platform,\n): string {\n\tif (configuredCommand?.trim()) return configuredCommand;\n\tif (environment.VISUAL) return environment.VISUAL;\n\tif (environment.EDITOR) return environment.EDITOR;\n\treturn platform === \"win32\" ? \"notepad\" : \"nano\";\n}\n\nexport async function editInExternalEditor(request: ExternalEditorRequest): Promise<ExternalEditorResult> {\n\tconst directory = mkdtempSync(join(tmpdir(), `${APP_NAME}-editor-`));\n\tconst filePath = join(directory, \"prompt.md\");\n\ttry {\n\t\twriteFileSync(filePath, request.content, {\n\t\t\tencoding: \"utf-8\",\n\t\t\tflag: \"wx\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\tconst [editor, ...editorArgs] = parseEditorCommand(request.command);\n\t\tif (!editor) return { status: \"failed\", message: `Failed to launch external editor: ${request.command}` };\n\n\t\tprocess.stdout.write(\n\t\t\t`Launching external editor: ${request.command}\\n${APP_NAME} will resume when the editor exits.\\n`,\n\t\t);\n\n\t\t// Do not use spawnSync. On Windows, synchronous child_process calls can\n\t\t// leave a console read active and race the editor for keyboard input.\n\t\t//\n\t\t// The shell is required on Windows so `.cmd`/`.bat` editor launchers\n\t\t// still run, but Node hands the command line to cmd.exe unquoted, so\n\t\t// quote every token here or paths containing spaces get split apart.\n\t\tconst useShell = process.platform === \"win32\";\n\t\tconst spawnArgs = [...editorArgs, filePath];\n\t\t// Null means the editor could not be launched. The editor inherits the cwd so project-relative paths and\n\t\t// integrated terminals keep working. A long cwd can break Windows editors: Windows rejects working\n\t\t// directories over MAX_PATH, and WSL launches Windows editors (code, notepad.exe) from the cwd's\n\t\t// \\\\wsl.localhost\\... path (pi#11592). The cwd is intentionally not changed; failures are reported instead.\n\t\tconst exit = await new Promise<number | NodeJS.Signals | null>((resolve) => {\n\t\t\tconst child = spawn(\n\t\t\t\tuseShell ? quoteWindowsShellArgument(editor) : editor,\n\t\t\t\tuseShell ? spawnArgs.map(quoteWindowsShellArgument) : spawnArgs,\n\t\t\t\t{ stdio: \"inherit\", shell: useShell, env: createChildProcessEnvironment() },\n\t\t\t);\n\t\t\tchild.once(\"error\", () => resolve(null));\n\t\t\tchild.once(\"close\", (code, signal) => resolve(code ?? signal));\n\t\t});\n\n\t\tif (exit === null) return { status: \"failed\", message: `Failed to launch external editor: ${request.command}` };\n\t\tif (exit !== 0) {\n\t\t\treturn {\n\t\t\t\tstatus: \"failed\",\n\t\t\t\tmessage: `External editor exited with ${typeof exit === \"number\" ? `code ${exit}` : exit}; prompt unchanged`,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tstatus: \"complete\",\n\t\t\tcontent: stripBom(readFileSync(filePath, \"utf-8\")).replace(/\\n$/, \"\"),\n\t\t};\n\t} finally {\n\t\ttry {\n\t\t\trmSync(directory, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Cleanup is best effort.\n\t\t}\n\t}\n}\n"]}
@@ -94,6 +94,7 @@ InteractiveModeBase.prototype.openExternalEditor = async function () {
94
94
  const updated = await openExternalEditorForText(currentText, this.ui, {
95
95
  editorCommand: this.settingsManager.getExternalEditorCommand(),
96
96
  showWarning: (message) => this.showWarning(message),
97
+ showStatus: (message) => this.showStatus(message),
97
98
  });
98
99
  if (updated !== undefined)
99
100
  this.editor.setText(updated);
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-editor-actions.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-editor-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { StartupIdentityComponent } from \"./components/startup-identity.ts\";\nimport { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport {\n\tAPP_NAME,\n\tAssistantMessageComponent,\n\tCHANGELOG_URL,\n\tContainer,\n\tDynamicBorder,\n\tgetCapabilities,\n\thyperlink,\n\topenExternalEditorForText,\n\tSpacer,\n\tText,\n\ttheme,\n} from \"./interactive-mode-deps.ts\";\nimport { ExpandableText, isExpandable } from \"./interactive-mode-helpers.ts\";\n\nInteractiveModeBase.prototype.refreshBuiltInHeader = function (this: InteractiveModeBase): void {\n\tif (this.builtInHeader instanceof ExpandableText || this.builtInHeader instanceof StartupIdentityComponent) {\n\t\tthis.builtInHeader.refresh();\n\t}\n};\n\nInteractiveModeBase.prototype.updateEditorBorderColor = function (this: InteractiveModeBase): void {\n\tif (this.isBashMode) {\n\t\tthis.editor.borderColor = theme.getBashModeBorderColor();\n\t} else {\n\t\tconst level = this.session.thinkingLevel || \"off\";\n\t\tthis.editor.borderColor = theme.getThinkingBorderColor(level);\n\t}\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.cycleThinkingLevel = async function (this: InteractiveModeBase): Promise<void> {\n\tconst newLevel = await this.session.cycleThinkingLevel({ persist: true });\n\tif (newLevel === undefined) {\n\t\tthis.showStatus(\"Current model does not support thinking\");\n\t} else {\n\t\tthis.footer.invalidate();\n\t\tthis.updateEditorBorderColor();\n\t\tthis.showStatus(`Thinking level: ${newLevel}`);\n\t}\n};\n\nInteractiveModeBase.prototype.cycleModel = async function (\n\tthis: InteractiveModeBase,\n\tdirection: \"forward\" | \"backward\",\n): Promise<void> {\n\ttry {\n\t\tconst result = await this.session.cycleModel(direction, { persist: true });\n\t\tif (result === undefined) {\n\t\t\tconst msg = this.session.scopedModels.length > 0 ? \"Only one model in scope\" : \"Only one model available\";\n\t\t\tthis.showStatus(msg);\n\t\t} else {\n\t\t\tthis.footer.invalidate();\n\t\t\tthis.updateEditorBorderColor();\n\t\t\tconst thinkingStr =\n\t\t\t\tresult.model.reasoning && result.thinkingLevel !== \"off\" ? ` (thinking: ${result.thinkingLevel})` : \"\";\n\t\t\tthis.showStatus(`Switched to ${result.model.name || result.model.id}${thinkingStr}`);\n\t\t\tvoid this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);\n\t\t}\n\t} catch (error) {\n\t\tthis.showError(error instanceof Error ? error.message : String(error));\n\t}\n};\n\nInteractiveModeBase.prototype.toggleToolOutputExpansion = function (this: InteractiveModeBase): void {\n\tthis.setToolsExpanded(!this.toolOutputExpanded);\n};\n\nInteractiveModeBase.prototype.setToolsExpanded = function (this: InteractiveModeBase, expanded: boolean): void {\n\tif (expanded === this.toolOutputExpanded) return;\n\tthis.toolOutputExpanded = expanded;\n\tconst activeHeader = this.customHeader ?? this.builtInHeader;\n\tif (isExpandable(activeHeader)) {\n\t\tactiveHeader.setExpanded(expanded);\n\t}\n\tconst visited = new Set<Container>();\n\tconst setNestedExpandables = (container: Container): void => {\n\t\tif (visited.has(container)) return;\n\t\tvisited.add(container);\n\t\tfor (const child of container.children) {\n\t\t\tif (isExpandable(child)) child.setExpanded(expanded);\n\t\t\tif (child instanceof Container) setNestedExpandables(child);\n\t\t}\n\t};\n\tsetNestedExpandables(this.chatContainer);\n\t// The rendered chat is the feedback; a status line restating it only adds noise.\n\tthis.ui.requestRender();\n};\n\n/** Update rendered assistant messages without rebuilding live tool components. */\nInteractiveModeBase.prototype.updateThinkingBlockVisibility = function (this: InteractiveModeBase): void {\n\tfor (const child of this.chatContainer.children) {\n\t\tif (child instanceof AssistantMessageComponent) {\n\t\t\tchild.setHideThinkingBlock(this.hideThinkingBlock);\n\t\t}\n\t}\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.toggleThinkingBlockVisibility = function (this: InteractiveModeBase): void {\n\tthis.hideThinkingBlock = !this.hideThinkingBlock;\n\tthis.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);\n\tthis.updateThinkingBlockVisibility();\n\tthis.showStatus(`Thinking blocks: ${this.hideThinkingBlock ? \"hidden\" : \"visible\"}`);\n};\n\nInteractiveModeBase.prototype.openExternalEditor = async function (this: InteractiveModeBase): Promise<void> {\n\tconst currentText = this.editor.getExpandedText?.() ?? this.editor.getText();\n\tconst updated = await openExternalEditorForText(currentText, this.ui, {\n\t\teditorCommand: this.settingsManager.getExternalEditorCommand(),\n\t\tshowWarning: (message) => this.showWarning(message),\n\t});\n\tif (updated !== undefined) this.editor.setText(updated);\n};\n\nInteractiveModeBase.prototype.clearEditor = function (this: InteractiveModeBase): void {\n\tthis.editor.setText(\"\");\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showError = function (this: InteractiveModeBase, errorMessage: string): void {\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMessage}`), 1, 0));\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showWarning = function (\n\tthis: InteractiveModeBase,\n\twarningMessage: string,\n\ttargetContainer = this.chatContainer,\n): void {\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new Text(theme.fg(\"warning\", `Warning: ${warningMessage}`), 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showNewVersionNotification = function (\n\tthis: InteractiveModeBase,\n\tnewVersion: string,\n\ttargetContainer = this.chatContainer,\n): void {\n\tconst action = theme.fg(\"accent\", `${APP_NAME} update`);\n\tconst updateInstruction = theme.fg(\"muted\", `New version ${newVersion} is available. Run `) + action;\n\tconst changelogLine = CHANGELOG_URL\n\t\t? `\\n${theme.fg(\"muted\", \"Changelog: \")}${\n\t\t\t\tgetCapabilities().hyperlinks\n\t\t\t\t\t? hyperlink(theme.fg(\"accent\", \"open changelog\"), CHANGELOG_URL)\n\t\t\t\t\t: theme.fg(\"accent\", CHANGELOG_URL)\n\t\t\t}`\n\t\t: \"\";\n\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\ttargetContainer.addChild(\n\t\tnew Text(`${theme.bold(theme.fg(\"warning\", \"Update Available\"))}\\n${updateInstruction}${changelogLine}`, 1, 0),\n\t);\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showPackageUpdateNotification = function (\n\tthis: InteractiveModeBase,\n\tpackages: string[],\n\ttargetContainer = this.chatContainer,\n): void {\n\tconst action = theme.fg(\"accent\", `${APP_NAME} update --extensions`);\n\tconst updateInstruction = theme.fg(\"muted\", \"Package updates are available. Run \") + action;\n\tconst packageLines = packages.map((pkg) => `- ${pkg}`).join(\"\\n\");\n\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\ttargetContainer.addChild(\n\t\tnew Text(\n\t\t\t`${theme.bold(theme.fg(\"warning\", \"Package Updates Available\"))}\\n${updateInstruction}\\n${theme.fg(\"muted\", \"Packages:\")}\\n${packageLines}`,\n\t\t\t1,\n\t\t\t0,\n\t\t),\n\t);\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\tthis.ui.requestRender();\n};\n"]}
1
+ {"version":3,"file":"interactive-editor-actions.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-editor-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import { StartupIdentityComponent } from \"./components/startup-identity.ts\";\nimport { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport {\n\tAPP_NAME,\n\tAssistantMessageComponent,\n\tCHANGELOG_URL,\n\tContainer,\n\tDynamicBorder,\n\tgetCapabilities,\n\thyperlink,\n\topenExternalEditorForText,\n\tSpacer,\n\tText,\n\ttheme,\n} from \"./interactive-mode-deps.ts\";\nimport { ExpandableText, isExpandable } from \"./interactive-mode-helpers.ts\";\n\nInteractiveModeBase.prototype.refreshBuiltInHeader = function (this: InteractiveModeBase): void {\n\tif (this.builtInHeader instanceof ExpandableText || this.builtInHeader instanceof StartupIdentityComponent) {\n\t\tthis.builtInHeader.refresh();\n\t}\n};\n\nInteractiveModeBase.prototype.updateEditorBorderColor = function (this: InteractiveModeBase): void {\n\tif (this.isBashMode) {\n\t\tthis.editor.borderColor = theme.getBashModeBorderColor();\n\t} else {\n\t\tconst level = this.session.thinkingLevel || \"off\";\n\t\tthis.editor.borderColor = theme.getThinkingBorderColor(level);\n\t}\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.cycleThinkingLevel = async function (this: InteractiveModeBase): Promise<void> {\n\tconst newLevel = await this.session.cycleThinkingLevel({ persist: true });\n\tif (newLevel === undefined) {\n\t\tthis.showStatus(\"Current model does not support thinking\");\n\t} else {\n\t\tthis.footer.invalidate();\n\t\tthis.updateEditorBorderColor();\n\t\tthis.showStatus(`Thinking level: ${newLevel}`);\n\t}\n};\n\nInteractiveModeBase.prototype.cycleModel = async function (\n\tthis: InteractiveModeBase,\n\tdirection: \"forward\" | \"backward\",\n): Promise<void> {\n\ttry {\n\t\tconst result = await this.session.cycleModel(direction, { persist: true });\n\t\tif (result === undefined) {\n\t\t\tconst msg = this.session.scopedModels.length > 0 ? \"Only one model in scope\" : \"Only one model available\";\n\t\t\tthis.showStatus(msg);\n\t\t} else {\n\t\t\tthis.footer.invalidate();\n\t\t\tthis.updateEditorBorderColor();\n\t\t\tconst thinkingStr =\n\t\t\t\tresult.model.reasoning && result.thinkingLevel !== \"off\" ? ` (thinking: ${result.thinkingLevel})` : \"\";\n\t\t\tthis.showStatus(`Switched to ${result.model.name || result.model.id}${thinkingStr}`);\n\t\t\tvoid this.maybeWarnAboutAnthropicSubscriptionAuth(result.model);\n\t\t}\n\t} catch (error) {\n\t\tthis.showError(error instanceof Error ? error.message : String(error));\n\t}\n};\n\nInteractiveModeBase.prototype.toggleToolOutputExpansion = function (this: InteractiveModeBase): void {\n\tthis.setToolsExpanded(!this.toolOutputExpanded);\n};\n\nInteractiveModeBase.prototype.setToolsExpanded = function (this: InteractiveModeBase, expanded: boolean): void {\n\tif (expanded === this.toolOutputExpanded) return;\n\tthis.toolOutputExpanded = expanded;\n\tconst activeHeader = this.customHeader ?? this.builtInHeader;\n\tif (isExpandable(activeHeader)) {\n\t\tactiveHeader.setExpanded(expanded);\n\t}\n\tconst visited = new Set<Container>();\n\tconst setNestedExpandables = (container: Container): void => {\n\t\tif (visited.has(container)) return;\n\t\tvisited.add(container);\n\t\tfor (const child of container.children) {\n\t\t\tif (isExpandable(child)) child.setExpanded(expanded);\n\t\t\tif (child instanceof Container) setNestedExpandables(child);\n\t\t}\n\t};\n\tsetNestedExpandables(this.chatContainer);\n\t// The rendered chat is the feedback; a status line restating it only adds noise.\n\tthis.ui.requestRender();\n};\n\n/** Update rendered assistant messages without rebuilding live tool components. */\nInteractiveModeBase.prototype.updateThinkingBlockVisibility = function (this: InteractiveModeBase): void {\n\tfor (const child of this.chatContainer.children) {\n\t\tif (child instanceof AssistantMessageComponent) {\n\t\t\tchild.setHideThinkingBlock(this.hideThinkingBlock);\n\t\t}\n\t}\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.toggleThinkingBlockVisibility = function (this: InteractiveModeBase): void {\n\tthis.hideThinkingBlock = !this.hideThinkingBlock;\n\tthis.settingsManager.setHideThinkingBlock(this.hideThinkingBlock);\n\tthis.updateThinkingBlockVisibility();\n\tthis.showStatus(`Thinking blocks: ${this.hideThinkingBlock ? \"hidden\" : \"visible\"}`);\n};\n\nInteractiveModeBase.prototype.openExternalEditor = async function (this: InteractiveModeBase): Promise<void> {\n\tconst currentText = this.editor.getExpandedText?.() ?? this.editor.getText();\n\tconst updated = await openExternalEditorForText(currentText, this.ui, {\n\t\teditorCommand: this.settingsManager.getExternalEditorCommand(),\n\t\tshowWarning: (message) => this.showWarning(message),\n\t\tshowStatus: (message) => this.showStatus(message),\n\t});\n\tif (updated !== undefined) this.editor.setText(updated);\n};\n\nInteractiveModeBase.prototype.clearEditor = function (this: InteractiveModeBase): void {\n\tthis.editor.setText(\"\");\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showError = function (this: InteractiveModeBase, errorMessage: string): void {\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(theme.fg(\"error\", `Error: ${errorMessage}`), 1, 0));\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showWarning = function (\n\tthis: InteractiveModeBase,\n\twarningMessage: string,\n\ttargetContainer = this.chatContainer,\n): void {\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new Text(theme.fg(\"warning\", `Warning: ${warningMessage}`), 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showNewVersionNotification = function (\n\tthis: InteractiveModeBase,\n\tnewVersion: string,\n\ttargetContainer = this.chatContainer,\n): void {\n\tconst action = theme.fg(\"accent\", `${APP_NAME} update`);\n\tconst updateInstruction = theme.fg(\"muted\", `New version ${newVersion} is available. Run `) + action;\n\tconst changelogLine = CHANGELOG_URL\n\t\t? `\\n${theme.fg(\"muted\", \"Changelog: \")}${\n\t\t\t\tgetCapabilities().hyperlinks\n\t\t\t\t\t? hyperlink(theme.fg(\"accent\", \"open changelog\"), CHANGELOG_URL)\n\t\t\t\t\t: theme.fg(\"accent\", CHANGELOG_URL)\n\t\t\t}`\n\t\t: \"\";\n\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\ttargetContainer.addChild(\n\t\tnew Text(`${theme.bold(theme.fg(\"warning\", \"Update Available\"))}\\n${updateInstruction}${changelogLine}`, 1, 0),\n\t);\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.showPackageUpdateNotification = function (\n\tthis: InteractiveModeBase,\n\tpackages: string[],\n\ttargetContainer = this.chatContainer,\n): void {\n\tconst action = theme.fg(\"accent\", `${APP_NAME} update --extensions`);\n\tconst updateInstruction = theme.fg(\"muted\", \"Package updates are available. Run \") + action;\n\tconst packageLines = packages.map((pkg) => `- ${pkg}`).join(\"\\n\");\n\n\ttargetContainer.addChild(new Spacer(1));\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\ttargetContainer.addChild(\n\t\tnew Text(\n\t\t\t`${theme.bold(theme.fg(\"warning\", \"Package Updates Available\"))}\\n${updateInstruction}\\n${theme.fg(\"muted\", \"Packages:\")}\\n${packageLines}`,\n\t\t\t1,\n\t\t\t0,\n\t\t),\n\t);\n\ttargetContainer.addChild(new DynamicBorder((text) => theme.fg(\"warning\", text)));\n\tthis.ui.requestRender();\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-cli.d.ts","sourceRoot":"","sources":["../src/package-manager-cli.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAMlE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAiC7D,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAAC,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAA;CAAO,GACvG,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAyDD,MAAM,WAAW,4BAA4B;IAC5C,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAyDD,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,GAAE,4BAAiC,GAC/C,OAAO,CAAC,OAAO,CAAC,CA8DlB;AAED,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,GAAE,4BAAiC,GAC/C,OAAO,CAAC,OAAO,CAAC,CA0MlB"}
1
+ {"version":3,"file":"package-manager-cli.d.ts","sourceRoot":"","sources":["../src/package-manager-cli.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAMlE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAiC7D,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,eAAe,CAAC;IAAC,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAA;CAAO,GACvG,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAqGD,MAAM,WAAW,4BAA4B;IAC5C,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAyDD,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,GAAE,4BAAiC,GAC/C,OAAO,CAAC,OAAO,CAAC,CA8DlB;AAED,wBAAsB,oBAAoB,CACzC,IAAI,EAAE,MAAM,EAAE,EACd,cAAc,GAAE,4BAAiC,GAC/C,OAAO,CAAC,OAAO,CAAC,CAkNlB"}