@ashx-j/lunr 0.2.7 → 0.2.9

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 (164) hide show
  1. package/dist/builtin-extensions/ashxj-spinners.d.ts +7 -0
  2. package/dist/builtin-extensions/ashxj-spinners.d.ts.map +1 -1
  3. package/dist/builtin-extensions/ashxj-spinners.js +40 -3
  4. package/dist/builtin-extensions/ashxj-spinners.js.map +1 -1
  5. package/dist/builtin-extensions/ashxj-tui.d.ts +4 -0
  6. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.js +44 -0
  8. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  9. package/dist/builtin-extensions/lunr-behavior.d.ts +2 -1
  10. package/dist/builtin-extensions/lunr-behavior.d.ts.map +1 -1
  11. package/dist/builtin-extensions/lunr-behavior.js +26 -14
  12. package/dist/builtin-extensions/lunr-behavior.js.map +1 -1
  13. package/dist/builtin-extensions/lunr-todos.d.ts +4 -7
  14. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  15. package/dist/builtin-extensions/lunr-todos.js +18 -10
  16. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.js +3 -3
  19. package/dist/builtin-extensions/pi-subagents/src/agents/agent-management.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js +2 -2
  22. package/dist/builtin-extensions/pi-subagents/src/extension/control-notices.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +1 -7
  25. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  27. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +2 -2
  28. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +2 -2
  30. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +3 -4
  32. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  33. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +21 -0
  35. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +6 -18
  38. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +13 -5
  41. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  42. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.d.ts +21 -0
  43. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.d.ts.map +1 -0
  44. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.js +22 -0
  45. package/dist/builtin-extensions/pi-subagents/src/shared/lunr-child-context.js.map +1 -0
  46. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +1 -0
  47. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  48. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  49. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +2 -1
  51. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +10 -18
  54. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +3 -0
  56. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  57. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +9 -11
  58. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  59. package/dist/builtin-extensions/pi-web-access/render-search-error.d.ts.map +1 -1
  60. package/dist/builtin-extensions/pi-web-access/render-search-error.js +1 -1
  61. package/dist/builtin-extensions/pi-web-access/render-search-error.js.map +1 -1
  62. package/dist/catalog/models.json +1 -1
  63. package/dist/catalog/providers/github-copilot.json +1 -1
  64. package/dist/catalog/providers/google-vertex.json +1 -1
  65. package/dist/catalog/providers/google.json +1 -1
  66. package/dist/catalog/providers/nvidia.json +1 -1
  67. package/dist/catalog/providers/opencode-go.json +1 -1
  68. package/dist/catalog/providers/opencode.json +1 -1
  69. package/dist/catalog/providers/openrouter.json +1 -1
  70. package/dist/catalog/providers/vercel-ai-gateway.json +1 -1
  71. package/dist/catalog/publication.json +3 -3
  72. package/dist/cli/update-cli.d.ts +16 -0
  73. package/dist/cli/update-cli.d.ts.map +1 -0
  74. package/dist/cli/update-cli.js +83 -0
  75. package/dist/cli/update-cli.js.map +1 -0
  76. package/dist/cli.d.ts.map +1 -1
  77. package/dist/cli.js +6 -0
  78. package/dist/cli.js.map +1 -1
  79. package/dist/core/behavior-preset.d.ts +60 -0
  80. package/dist/core/behavior-preset.d.ts.map +1 -0
  81. package/dist/core/behavior-preset.js +257 -0
  82. package/dist/core/behavior-preset.js.map +1 -0
  83. package/dist/core/customize.d.ts +3 -0
  84. package/dist/core/customize.d.ts.map +1 -1
  85. package/dist/core/customize.js +9 -0
  86. package/dist/core/customize.js.map +1 -1
  87. package/dist/core/footer-data-provider.d.ts +12 -1
  88. package/dist/core/footer-data-provider.d.ts.map +1 -1
  89. package/dist/core/footer-data-provider.js +70 -5
  90. package/dist/core/footer-data-provider.js.map +1 -1
  91. package/dist/core/keybindings.d.ts +2 -2
  92. package/dist/core/keybindings.d.ts.map +1 -1
  93. package/dist/core/keybindings.js +1 -1
  94. package/dist/core/keybindings.js.map +1 -1
  95. package/dist/core/model-tiers.d.ts +9 -0
  96. package/dist/core/model-tiers.d.ts.map +1 -1
  97. package/dist/core/model-tiers.js +16 -0
  98. package/dist/core/model-tiers.js.map +1 -1
  99. package/dist/core/rollback.d.ts +1 -1
  100. package/dist/core/rollback.d.ts.map +1 -1
  101. package/dist/core/rollback.js +1 -1
  102. package/dist/core/rollback.js.map +1 -1
  103. package/dist/core/settings-manager.d.ts +23 -0
  104. package/dist/core/settings-manager.d.ts.map +1 -1
  105. package/dist/core/settings-manager.js +66 -0
  106. package/dist/core/settings-manager.js.map +1 -1
  107. package/dist/core/slash-commands.d.ts.map +1 -1
  108. package/dist/core/slash-commands.js +2 -1
  109. package/dist/core/slash-commands.js.map +1 -1
  110. package/dist/core/tools/bash.d.ts.map +1 -1
  111. package/dist/core/tools/bash.js +1 -3
  112. package/dist/core/tools/bash.js.map +1 -1
  113. package/dist/core/update-check.d.ts +32 -0
  114. package/dist/core/update-check.d.ts.map +1 -0
  115. package/dist/core/update-check.js +112 -0
  116. package/dist/core/update-check.js.map +1 -0
  117. package/dist/core/usage-service.d.ts +24 -1
  118. package/dist/core/usage-service.d.ts.map +1 -1
  119. package/dist/core/usage-service.js +91 -14
  120. package/dist/core/usage-service.js.map +1 -1
  121. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  122. package/dist/gateway/agent-bridge.js +5 -1
  123. package/dist/gateway/agent-bridge.js.map +1 -1
  124. package/dist/gateway/cron.d.ts.map +1 -1
  125. package/dist/gateway/cron.js +5 -1
  126. package/dist/gateway/cron.js.map +1 -1
  127. package/dist/main.d.ts.map +1 -1
  128. package/dist/main.js +13 -1
  129. package/dist/main.js.map +1 -1
  130. package/dist/modes/interactive/components/assistant-message.d.ts +10 -1
  131. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/assistant-message.js +154 -68
  133. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  134. package/dist/modes/interactive/components/settings-selector.d.ts +13 -0
  135. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  136. package/dist/modes/interactive/components/settings-selector.js +157 -10
  137. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  138. package/dist/modes/interactive/components/thinking-summary.d.ts +4 -4
  139. package/dist/modes/interactive/components/thinking-summary.d.ts.map +1 -1
  140. package/dist/modes/interactive/components/thinking-summary.js +7 -5
  141. package/dist/modes/interactive/components/thinking-summary.js.map +1 -1
  142. package/dist/modes/interactive/components/thinking-tail.d.ts.map +1 -1
  143. package/dist/modes/interactive/components/thinking-tail.js +5 -3
  144. package/dist/modes/interactive/components/thinking-tail.js.map +1 -1
  145. package/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  146. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  147. package/dist/modes/interactive/components/tool-execution.js +9 -0
  148. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  149. package/dist/modes/interactive/interactive-mode.d.ts +6 -1
  150. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  151. package/dist/modes/interactive/interactive-mode.js +124 -43
  152. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  153. package/docs/keybindings.md +1 -1
  154. package/docs/providers.md +2 -0
  155. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  156. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  157. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  158. package/examples/extensions/gondolin/package-lock.json +2 -2
  159. package/examples/extensions/gondolin/package.json +1 -1
  160. package/examples/extensions/sandbox/package-lock.json +2 -2
  161. package/examples/extensions/sandbox/package.json +1 -1
  162. package/examples/extensions/with-deps/package-lock.json +2 -2
  163. package/examples/extensions/with-deps/package.json +1 -1
  164. package/package.json +4 -4
@@ -84,11 +84,13 @@ export function updateThinkingRunTimings(timings, content, now, isFinal) {
84
84
  /**
85
85
  * Whether a thinking run is complete and may collapse. Note: partial streaming
86
86
  * messages carry `stopReason: "stop"` from the start, so stopReason cannot be
87
- * used. Instead: a run is complete when a block follows it, when its live
88
- * timing has an `end`, or when no timings are attached at all (history /
89
- * resumed messages are always final).
87
+ * used. History / resumed messages have no timings and are always final. A
88
+ * live run stays open until its timing records `end` a following empty
89
+ * block must not collapse it early.
90
90
  */
91
- export function isThinkingRunComplete(hasFollowingBlock, timing, timingsAttached) {
92
- return hasFollowingBlock || timing?.end !== undefined || !timingsAttached;
91
+ export function isThinkingRunComplete(_hasFollowingBlock, timing, timingsAttached) {
92
+ if (!timingsAttached)
93
+ return true;
94
+ return timing?.end !== undefined;
93
95
  }
94
96
  //# sourceMappingURL=thinking-summary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"thinking-summary.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-summary.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\n\n/**\n * lunr: pure helpers for the collapsible-reasoning feature. A completed\n * thinking run renders as \"✻ Thought for Xs\" + the run's first sentence\n * instead of the full block. Kept component-free so vitest can cover the\n * extraction/timing logic directly.\n */\n\n/** Live timing for one thinking run (a maximal run of consecutive thinking blocks). */\nexport interface ThinkingRunTiming {\n\tstart: number;\n\tend?: number;\n}\n\n/** Leading markdown punctuation stripped before sentence extraction. */\nconst LEADING_MARKDOWN_RE = /^[#*`>\\-\\s]+/;\n\n/**\n * Extract a one-line summary from a thinking run: the first sentence of the\n * first substantive line (blank and markdown-only lines skipped). If no\n * sentence terminator appears within `maxLen` chars, hard-truncate at the\n * last word boundary and append an ellipsis.\n */\nexport function thinkingSnippet(joinedThinking: string, maxLen = 120): string {\n\tconst text = joinedThinking\n\t\t.split(\"\\n\")\n\t\t// Markdown headers are structural labels, not sentences — skip them.\n\t\t.filter((line) => !line.trimStart().startsWith(\"#\"))\n\t\t.map((line) => line.replace(LEADING_MARKDOWN_RE, \"\").trim())\n\t\t.filter((line) => line.length > 0)\n\t\t.join(\" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\tif (!text) {\n\t\treturn \"\";\n\t}\n\t// First sentence: up to a terminator followed by whitespace or end-of-text.\n\tconst sentenceMatch = text.match(/^.*?[.!?](?=\\s|$)/);\n\tif (sentenceMatch && sentenceMatch[0].length <= maxLen) {\n\t\treturn sentenceMatch[0];\n\t}\n\tif (text.length <= maxLen) {\n\t\treturn text;\n\t}\n\tconst window = text.slice(0, maxLen);\n\tconst lastSpace = window.lastIndexOf(\" \");\n\tconst cut = lastSpace > 0 ? window.slice(0, lastSpace) : window;\n\treturn `${cut}…`;\n}\n\n/** Format a thinking duration: `<1s`, `Ns`, or `Mm Ss`. */\nexport function formatThoughtDuration(ms: number): string {\n\tconst seconds = Math.round(ms / 1000);\n\tif (seconds < 1) {\n\t\treturn \"<1s\";\n\t}\n\tif (seconds < 60) {\n\t\treturn `${seconds}s`;\n\t}\n\tconst minutes = Math.floor(seconds / 60);\n\tconst rest = seconds % 60;\n\treturn rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`;\n}\n\n/**\n * Update per-run timings from the full (un-sliced) streaming message content.\n * A run gets `start` the first time it is seen and `end` (once) when any\n * content block follows it or the message is final.\n */\nexport function updateThinkingRunTimings(\n\ttimings: ThinkingRunTiming[],\n\tcontent: AssistantMessage[\"content\"],\n\tnow: number,\n\tisFinal: boolean,\n): void {\n\tlet runIndex = -1;\n\tlet inThinkingRun = false;\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type === \"thinking\") {\n\t\t\tif (!inThinkingRun) {\n\t\t\t\trunIndex++;\n\t\t\t\tinThinkingRun = true;\n\t\t\t\tif (!timings[runIndex]) {\n\t\t\t\t\ttimings[runIndex] = { start: now };\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (inThinkingRun) {\n\t\t\t// A non-thinking block follows the run: it is complete.\n\t\t\tconst timing = timings[runIndex];\n\t\t\tif (timing && timing.end === undefined) {\n\t\t\t\ttiming.end = now;\n\t\t\t}\n\t\t\tinThinkingRun = false;\n\t\t}\n\t}\n\tif (isFinal && inThinkingRun) {\n\t\tconst timing = timings[runIndex];\n\t\tif (timing && timing.end === undefined) {\n\t\t\ttiming.end = now;\n\t\t}\n\t}\n}\n\n/**\n * Whether a thinking run is complete and may collapse. Note: partial streaming\n * messages carry `stopReason: \"stop\"` from the start, so stopReason cannot be\n * used. Instead: a run is complete when a block follows it, when its live\n * timing has an `end`, or when no timings are attached at all (history /\n * resumed messages are always final).\n */\nexport function isThinkingRunComplete(\n\thasFollowingBlock: boolean,\n\ttiming: ThinkingRunTiming | undefined,\n\ttimingsAttached: boolean,\n): boolean {\n\treturn hasFollowingBlock || timing?.end !== undefined || !timingsAttached;\n}\n"]}
1
+ {"version":3,"file":"thinking-summary.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-summary.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AssistantMessage } from \"@ashx-j/lunr-ai\";\n\n/**\n * lunr: pure helpers for the collapsible-reasoning feature. A completed\n * thinking run renders as \"✻ Thought for Xs\" + the run's first sentence\n * instead of the full block. Kept component-free so vitest can cover the\n * extraction/timing logic directly.\n */\n\n/** Live timing for one thinking run (a maximal run of consecutive thinking blocks). */\nexport interface ThinkingRunTiming {\n\tstart: number;\n\tend?: number;\n}\n\n/** Leading markdown punctuation stripped before sentence extraction. */\nconst LEADING_MARKDOWN_RE = /^[#*`>\\-\\s]+/;\n\n/**\n * Extract a one-line summary from a thinking run: the first sentence of the\n * first substantive line (blank and markdown-only lines skipped). If no\n * sentence terminator appears within `maxLen` chars, hard-truncate at the\n * last word boundary and append an ellipsis.\n */\nexport function thinkingSnippet(joinedThinking: string, maxLen = 120): string {\n\tconst text = joinedThinking\n\t\t.split(\"\\n\")\n\t\t// Markdown headers are structural labels, not sentences — skip them.\n\t\t.filter((line) => !line.trimStart().startsWith(\"#\"))\n\t\t.map((line) => line.replace(LEADING_MARKDOWN_RE, \"\").trim())\n\t\t.filter((line) => line.length > 0)\n\t\t.join(\" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n\tif (!text) {\n\t\treturn \"\";\n\t}\n\t// First sentence: up to a terminator followed by whitespace or end-of-text.\n\tconst sentenceMatch = text.match(/^.*?[.!?](?=\\s|$)/);\n\tif (sentenceMatch && sentenceMatch[0].length <= maxLen) {\n\t\treturn sentenceMatch[0];\n\t}\n\tif (text.length <= maxLen) {\n\t\treturn text;\n\t}\n\tconst window = text.slice(0, maxLen);\n\tconst lastSpace = window.lastIndexOf(\" \");\n\tconst cut = lastSpace > 0 ? window.slice(0, lastSpace) : window;\n\treturn `${cut}…`;\n}\n\n/** Format a thinking duration: `<1s`, `Ns`, or `Mm Ss`. */\nexport function formatThoughtDuration(ms: number): string {\n\tconst seconds = Math.round(ms / 1000);\n\tif (seconds < 1) {\n\t\treturn \"<1s\";\n\t}\n\tif (seconds < 60) {\n\t\treturn `${seconds}s`;\n\t}\n\tconst minutes = Math.floor(seconds / 60);\n\tconst rest = seconds % 60;\n\treturn rest > 0 ? `${minutes}m ${rest}s` : `${minutes}m`;\n}\n\n/**\n * Update per-run timings from the full (un-sliced) streaming message content.\n * A run gets `start` the first time it is seen and `end` (once) when any\n * content block follows it or the message is final.\n */\nexport function updateThinkingRunTimings(\n\ttimings: ThinkingRunTiming[],\n\tcontent: AssistantMessage[\"content\"],\n\tnow: number,\n\tisFinal: boolean,\n): void {\n\tlet runIndex = -1;\n\tlet inThinkingRun = false;\n\tfor (let i = 0; i < content.length; i++) {\n\t\tconst block = content[i];\n\t\tif (block.type === \"thinking\") {\n\t\t\tif (!inThinkingRun) {\n\t\t\t\trunIndex++;\n\t\t\t\tinThinkingRun = true;\n\t\t\t\tif (!timings[runIndex]) {\n\t\t\t\t\ttimings[runIndex] = { start: now };\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (inThinkingRun) {\n\t\t\t// A non-thinking block follows the run: it is complete.\n\t\t\tconst timing = timings[runIndex];\n\t\t\tif (timing && timing.end === undefined) {\n\t\t\t\ttiming.end = now;\n\t\t\t}\n\t\t\tinThinkingRun = false;\n\t\t}\n\t}\n\tif (isFinal && inThinkingRun) {\n\t\tconst timing = timings[runIndex];\n\t\tif (timing && timing.end === undefined) {\n\t\t\ttiming.end = now;\n\t\t}\n\t}\n}\n\n/**\n * Whether a thinking run is complete and may collapse. Note: partial streaming\n * messages carry `stopReason: \"stop\"` from the start, so stopReason cannot be\n * used. History / resumed messages have no timings and are always final. A\n * live run stays open until its timing records `end` a following empty\n * block must not collapse it early.\n */\nexport function isThinkingRunComplete(\n\t_hasFollowingBlock: boolean,\n\ttiming: ThinkingRunTiming | undefined,\n\ttimingsAttached: boolean,\n): boolean {\n\tif (!timingsAttached) return true;\n\treturn timing?.end !== undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"thinking-tail.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtF;;;;;;GAMG;AAEH,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,qBAAa,qBAAsB,YAAW,SAAS;IACtD,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAEzB,YACC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,EAC5B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAChE,QAAQ,GAAE,MAA4B,EAItC;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9B;CACD","sourcesContent":["import { type Component, Markdown, type MarkdownTheme } from \"@ashx-j/lunr-tui\";\n\n/**\n * lunr: rolling window for a still-streaming thinking run. Renders the full\n * Markdown block (same styling as the complete-run branch) but returns only\n * the last `maxLines` rendered lines, so at most N visual lines of reasoning\n * are on screen at a time and older lines disappear as new ones stream in.\n * Applied render-time only; the transcript is untouched.\n */\n\n/** Maximum rendered lines shown for a streaming thinking run. */\nexport const THINKING_TAIL_LINES = 4;\n\nexport class ThinkingTailComponent implements Component {\n\tprivate markdown: Markdown;\n\tprivate maxLines: number;\n\n\tconstructor(\n\t\ttext: string,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\toptions?: { color?: (text: string) => string; italic?: boolean },\n\t\tmaxLines: number = THINKING_TAIL_LINES,\n\t) {\n\t\tthis.maxLines = maxLines;\n\t\tthis.markdown = new Markdown(text, paddingX, paddingY, markdownTheme, options);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.markdown.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines = this.markdown.render(width);\n\t\tif (lines.length <= this.maxLines) {\n\t\t\treturn lines;\n\t\t}\n\t\treturn lines.slice(-this.maxLines);\n\t}\n}\n"]}
1
+ {"version":3,"file":"thinking-tail.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtF;;;;;;GAMG;AAEH,iEAAiE;AACjE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,qBAAa,qBAAsB,YAAW,SAAS;IACtD,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAEzB,YACC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,aAAa,EAC5B,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,EAChE,QAAQ,GAAE,MAA4B,EAItC;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ9B;CACD","sourcesContent":["import { type Component, Markdown, type MarkdownTheme } from \"@ashx-j/lunr-tui\";\n\n/**\n * lunr: rolling window for a still-streaming thinking run. Renders the full\n * Markdown block (same styling as the complete-run branch) but returns only\n * the last `maxLines` rendered lines, so at most N visual lines of reasoning\n * are on screen at a time and older lines disappear as new ones stream in.\n * Applied render-time only; the transcript is untouched.\n */\n\n/** Maximum rendered lines shown for a streaming thinking run. */\nexport const THINKING_TAIL_LINES = 4;\n\nexport class ThinkingTailComponent implements Component {\n\tprivate markdown: Markdown;\n\tprivate maxLines: number;\n\n\tconstructor(\n\t\ttext: string,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\toptions?: { color?: (text: string) => string; italic?: boolean },\n\t\tmaxLines: number = THINKING_TAIL_LINES,\n\t) {\n\t\tthis.maxLines = maxLines;\n\t\tthis.markdown = new Markdown(text, paddingX, paddingY, markdownTheme, options);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.markdown.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines = this.markdown.render(width);\n\t\tconst tail = lines.length <= this.maxLines ? lines : lines.slice(-this.maxLines);\n\t\tif (tail.length >= this.maxLines) {\n\t\t\treturn tail;\n\t\t}\n\t\tconst pad = this.maxLines - tail.length;\n\t\treturn [...Array.from({ length: pad }, () => \"\"), ...tail];\n\t}\n}\n"]}
@@ -20,10 +20,12 @@ export class ThinkingTailComponent {
20
20
  }
21
21
  render(width) {
22
22
  const lines = this.markdown.render(width);
23
- if (lines.length <= this.maxLines) {
24
- return lines;
23
+ const tail = lines.length <= this.maxLines ? lines : lines.slice(-this.maxLines);
24
+ if (tail.length >= this.maxLines) {
25
+ return tail;
25
26
  }
26
- return lines.slice(-this.maxLines);
27
+ const pad = this.maxLines - tail.length;
28
+ return [...Array.from({ length: pad }, () => ""), ...tail];
27
29
  }
28
30
  }
29
31
  //# sourceMappingURL=thinking-tail.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"thinking-tail.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAsB,MAAM,wBAAwB,CAAC;AAEtF;;;;;;GAMG;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,OAAO,qBAAqB;IACzB,QAAQ,CAAW;IACnB,QAAQ,CAAS;IAEzB,YACC,IAAY,EACZ,QAAgB,EAChB,QAAgB,EAChB,aAA4B,EAC5B,OAAgE,EAChE,QAAQ,GAAW,mBAAmB,EACrC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAAA,CAC/E;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAAA,CAC3B;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAAA,CACnC;CACD","sourcesContent":["import { type Component, Markdown, type MarkdownTheme } from \"@ashx-j/lunr-tui\";\n\n/**\n * lunr: rolling window for a still-streaming thinking run. Renders the full\n * Markdown block (same styling as the complete-run branch) but returns only\n * the last `maxLines` rendered lines, so at most N visual lines of reasoning\n * are on screen at a time and older lines disappear as new ones stream in.\n * Applied render-time only; the transcript is untouched.\n */\n\n/** Maximum rendered lines shown for a streaming thinking run. */\nexport const THINKING_TAIL_LINES = 4;\n\nexport class ThinkingTailComponent implements Component {\n\tprivate markdown: Markdown;\n\tprivate maxLines: number;\n\n\tconstructor(\n\t\ttext: string,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\toptions?: { color?: (text: string) => string; italic?: boolean },\n\t\tmaxLines: number = THINKING_TAIL_LINES,\n\t) {\n\t\tthis.maxLines = maxLines;\n\t\tthis.markdown = new Markdown(text, paddingX, paddingY, markdownTheme, options);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.markdown.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines = this.markdown.render(width);\n\t\tif (lines.length <= this.maxLines) {\n\t\t\treturn lines;\n\t\t}\n\t\treturn lines.slice(-this.maxLines);\n\t}\n}\n"]}
1
+ {"version":3,"file":"thinking-tail.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/thinking-tail.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,QAAQ,EAAsB,MAAM,wBAAwB,CAAC;AAEtF;;;;;;GAMG;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,OAAO,qBAAqB;IACzB,QAAQ,CAAW;IACnB,QAAQ,CAAS;IAEzB,YACC,IAAY,EACZ,QAAgB,EAChB,QAAgB,EAChB,aAA4B,EAC5B,OAAgE,EAChE,QAAQ,GAAW,mBAAmB,EACrC;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;IAAA,CAC/E;IAED,UAAU,GAAS;QAClB,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IAAA,CAC3B;IAED,MAAM,CAAC,KAAa,EAAY;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjF,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC;QACxC,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAAA,CAC3D;CACD","sourcesContent":["import { type Component, Markdown, type MarkdownTheme } from \"@ashx-j/lunr-tui\";\n\n/**\n * lunr: rolling window for a still-streaming thinking run. Renders the full\n * Markdown block (same styling as the complete-run branch) but returns only\n * the last `maxLines` rendered lines, so at most N visual lines of reasoning\n * are on screen at a time and older lines disappear as new ones stream in.\n * Applied render-time only; the transcript is untouched.\n */\n\n/** Maximum rendered lines shown for a streaming thinking run. */\nexport const THINKING_TAIL_LINES = 4;\n\nexport class ThinkingTailComponent implements Component {\n\tprivate markdown: Markdown;\n\tprivate maxLines: number;\n\n\tconstructor(\n\t\ttext: string,\n\t\tpaddingX: number,\n\t\tpaddingY: number,\n\t\tmarkdownTheme: MarkdownTheme,\n\t\toptions?: { color?: (text: string) => string; italic?: boolean },\n\t\tmaxLines: number = THINKING_TAIL_LINES,\n\t) {\n\t\tthis.maxLines = maxLines;\n\t\tthis.markdown = new Markdown(text, paddingX, paddingY, markdownTheme, options);\n\t}\n\n\tinvalidate(): void {\n\t\tthis.markdown.invalidate();\n\t}\n\n\trender(width: number): string[] {\n\t\tconst lines = this.markdown.render(width);\n\t\tconst tail = lines.length <= this.maxLines ? lines : lines.slice(-this.maxLines);\n\t\tif (tail.length >= this.maxLines) {\n\t\t\treturn tail;\n\t\t}\n\t\tconst pad = this.maxLines - tail.length;\n\t\treturn [...Array.from({ length: pad }, () => \"\"), ...tail];\n\t}\n}\n"]}
@@ -56,6 +56,7 @@ export declare class ToolExecutionComponent extends Container {
56
56
  }, isPartial?: boolean): void;
57
57
  private maybeConvertImagesForKitty;
58
58
  setExpanded(expanded: boolean): void;
59
+ handleClick(_localY: number, _width: number): boolean;
59
60
  getToolName(): string;
60
61
  setGroupContinuation(on: boolean): void;
61
62
  setGroupFollowed(on: boolean): void;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport {\n\tformatGroupedCall,\n\tgetTextOutput as getRenderedTextOutput,\n\ttoolGroupRole,\n\ttoolStatusDot,\n} from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\t// lunr: top spacer kept as a field so consecutive same-tool calls can be\n\t// grouped into one continuous background by zeroing it (setGroupContinuation).\n\tprivate topSpacer: Spacer;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\tprivate groupContinuation = false;\n\tprivate groupFollowed = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | 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.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.topSpacer = new Spacer(1);\n\t\tthis.addChild(this.topSpacer);\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\t// lunr: default Box(1, 1). Same-name neighbors collapse facing pad only\n\t\t// (setGroupContinuation / setGroupFollowed); mixed and lone cards keep air.\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<any, any>[\"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<any, any>[\"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\trequestRender: () => {\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\tresult: this.result,\n\t\t\tgroupRole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t};\n\t}\n\n\tprivate getStatusDot(): string {\n\t\tconst state = this.isPartial ? \"pending\" : this.result?.isError ? \"error\" : \"success\";\n\t\treturn toolStatusDot(state, theme);\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(\n\t\t\tformatGroupedCall({\n\t\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\t\tcompact: !this.isPartial && !this.expanded && !this.result?.isError,\n\t\t\t\tdot: this.getStatusDot(),\n\t\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t\t}),\n\t\t\t0,\n\t\t\t0,\n\t\t);\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\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\t// lunr: consecutive same-tool grouping — exposes the tool name so the caller\n\t// can detect adjacency.\n\tgetToolName(): string {\n\t\treturn this.toolName;\n\t}\n\n\t// lunr: consecutive same-tool grouping — continuation calls hide the top\n\t// spacer and top box pad so adjacent same-bg boxes read as one continuous\n\t// background; the last card in a run keeps its bottom pad.\n\tsetGroupContinuation(on: boolean): void {\n\t\tthis.groupContinuation = on;\n\t\tthis.topSpacer.setLines(on ? 0 : 1);\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\t// lunr: previous card in a same-name run drops its bottom pad so the next\n\t// header sits flush. Singletons and mixed neighbors keep paddingBottom = 1.\n\tsetGroupFollowed(on: boolean): void {\n\t\tthis.groupFollowed = on;\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\tprivate applyGroupPadding(): void {\n\t\tconst top = this.groupContinuation ? 0 : 1;\n\t\tconst bottom = this.groupFollowed ? 0 : 1;\n\t\tthis.contentBox.setPaddingTop(top);\n\t\tthis.contentBox.setPaddingBottom(bottom);\n\t\tthis.contentText.setPaddingTop(top);\n\t\tthis.contentText.setPaddingBottom(bottom);\n\t\tif (this.getRenderShell() === \"self\" && this.callRendererComponent instanceof Box) {\n\t\t\tthis.callRendererComponent.setPaddingTop(top);\n\t\t\tthis.callRendererComponent.setPaddingBottom(bottom);\n\t\t}\n\t}\n\n\tprivate shouldSkipCompactResult(): boolean {\n\t\treturn (\n\t\t\tthis.getRenderShell() === \"default\" &&\n\t\t\tthis.result !== undefined &&\n\t\t\t!this.isPartial &&\n\t\t\t!this.expanded &&\n\t\t\t!this.result.isError\n\t\t);\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\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\tif (!this.groupContinuation) {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\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\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}\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\trenderContainer.addChild(this.createCallFallback());\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 skipCompactBody = this.shouldSkipCompactResult();\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tif (!skipCompactBody) {\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} 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 as any, details: this.result.details },\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\tif (!skipCompactBody) {\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} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tif (!skipCompactBody) {\n\t\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\n\t\tthis.applyGroupPadding();\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tconst compact = !this.isPartial && !this.expanded && !this.result?.isError;\n\t\tlet text = formatGroupedCall({\n\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\tcompact,\n\t\t\tdot: this.getStatusDot(),\n\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t});\n\t\tif (compact) {\n\t\t\treturn text;\n\t\t}\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\n/** Collapse facing pad when `next` is appended after a same-name tool card. */\nexport function applySameToolGrouping(\n\tprevious: ToolExecutionComponent | undefined,\n\tnext: ToolExecutionComponent,\n): void {\n\tif (previous && previous.getToolName() === next.getToolName()) {\n\t\tprevious.setGroupFollowed(true);\n\t\tnext.setGroupContinuation(true);\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport {\n\tformatGroupedCall,\n\tgetTextOutput as getRenderedTextOutput,\n\ttoolGroupRole,\n\ttoolStatusDot,\n} from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\t// lunr: top spacer kept as a field so consecutive same-tool calls can be\n\t// grouped into one continuous background by zeroing it (setGroupContinuation).\n\tprivate topSpacer: Spacer;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\tprivate groupContinuation = false;\n\tprivate groupFollowed = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | 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.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.topSpacer = new Spacer(1);\n\t\tthis.addChild(this.topSpacer);\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\t// lunr: default Box(1, 1). Same-name neighbors collapse facing pad only\n\t\t// (setGroupContinuation / setGroupFollowed); mixed and lone cards keep air.\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<any, any>[\"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<any, any>[\"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\trequestRender: () => {\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\tresult: this.result,\n\t\t\tgroupRole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t};\n\t}\n\n\tprivate getStatusDot(): string {\n\t\tconst state = this.isPartial ? \"pending\" : this.result?.isError ? \"error\" : \"success\";\n\t\treturn toolStatusDot(state, theme);\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(\n\t\t\tformatGroupedCall({\n\t\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\t\tcompact: !this.isPartial && !this.expanded && !this.result?.isError,\n\t\t\t\tdot: this.getStatusDot(),\n\t\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t\t}),\n\t\t\t0,\n\t\t\t0,\n\t\t);\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\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tif (this.isPartial) return false;\n\t\tif (this.toolName === \"subagent\" || this.toolName === \"subagent_wait\") return false;\n\t\tthis.setExpanded(!this.expanded);\n\t\tthis.ui.requestRender();\n\t\treturn true;\n\t}\n\n\t// lunr: consecutive same-tool grouping — exposes the tool name so the caller\n\t// can detect adjacency.\n\tgetToolName(): string {\n\t\treturn this.toolName;\n\t}\n\n\t// lunr: consecutive same-tool grouping — continuation calls hide the top\n\t// spacer and top box pad so adjacent same-bg boxes read as one continuous\n\t// background; the last card in a run keeps its bottom pad.\n\tsetGroupContinuation(on: boolean): void {\n\t\tthis.groupContinuation = on;\n\t\tthis.topSpacer.setLines(on ? 0 : 1);\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\t// lunr: previous card in a same-name run drops its bottom pad so the next\n\t// header sits flush. Singletons and mixed neighbors keep paddingBottom = 1.\n\tsetGroupFollowed(on: boolean): void {\n\t\tthis.groupFollowed = on;\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\tprivate applyGroupPadding(): void {\n\t\tconst top = this.groupContinuation ? 0 : 1;\n\t\tconst bottom = this.groupFollowed ? 0 : 1;\n\t\tthis.contentBox.setPaddingTop(top);\n\t\tthis.contentBox.setPaddingBottom(bottom);\n\t\tthis.contentText.setPaddingTop(top);\n\t\tthis.contentText.setPaddingBottom(bottom);\n\t\tif (this.getRenderShell() === \"self\" && this.callRendererComponent instanceof Box) {\n\t\t\tthis.callRendererComponent.setPaddingTop(top);\n\t\t\tthis.callRendererComponent.setPaddingBottom(bottom);\n\t\t}\n\t}\n\n\tprivate shouldSkipCompactResult(): boolean {\n\t\treturn (\n\t\t\tthis.getRenderShell() === \"default\" &&\n\t\t\tthis.result !== undefined &&\n\t\t\t!this.isPartial &&\n\t\t\t!this.expanded &&\n\t\t\t!this.result.isError\n\t\t);\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\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\tif (!this.groupContinuation) {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\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\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}\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\trenderContainer.addChild(this.createCallFallback());\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 skipCompactBody = this.shouldSkipCompactResult();\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tif (!skipCompactBody) {\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} 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 as any, details: this.result.details },\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\tif (!skipCompactBody) {\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} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tif (!skipCompactBody) {\n\t\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\n\t\tthis.applyGroupPadding();\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tconst compact = !this.isPartial && !this.expanded && !this.result?.isError;\n\t\tlet text = formatGroupedCall({\n\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\tcompact,\n\t\t\tdot: this.getStatusDot(),\n\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t});\n\t\tif (compact) {\n\t\t\treturn text;\n\t\t}\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\n/** Collapse facing pad when `next` is appended after a same-name tool card. */\nexport function applySameToolGrouping(\n\tprevious: ToolExecutionComponent | undefined,\n\tnext: ToolExecutionComponent,\n): void {\n\tif (previous && previous.getToolName() === next.getToolName()) {\n\t\tprevious.setGroupFollowed(true);\n\t\tnext.setGroupContinuation(true);\n\t}\n}\n"]}
@@ -184,6 +184,15 @@ export class ToolExecutionComponent extends Container {
184
184
  this.expanded = expanded;
185
185
  this.updateDisplay();
186
186
  }
187
+ handleClick(_localY, _width) {
188
+ if (this.isPartial)
189
+ return false;
190
+ if (this.toolName === "subagent" || this.toolName === "subagent_wait")
191
+ return false;
192
+ this.setExpanded(!this.expanded);
193
+ this.ui.requestRender();
194
+ return true;
195
+ }
187
196
  // lunr: consecutive same-tool grouping — exposes the tool name so the caller
188
197
  // can detect adjacency.
189
198
  getToolName() {
@@ -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 { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport {\n\tformatGroupedCall,\n\tgetTextOutput as getRenderedTextOutput,\n\ttoolGroupRole,\n\ttoolStatusDot,\n} from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\t// lunr: top spacer kept as a field so consecutive same-tool calls can be\n\t// grouped into one continuous background by zeroing it (setGroupContinuation).\n\tprivate topSpacer: Spacer;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\tprivate groupContinuation = false;\n\tprivate groupFollowed = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | 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.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.topSpacer = new Spacer(1);\n\t\tthis.addChild(this.topSpacer);\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\t// lunr: default Box(1, 1). Same-name neighbors collapse facing pad only\n\t\t// (setGroupContinuation / setGroupFollowed); mixed and lone cards keep air.\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<any, any>[\"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<any, any>[\"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\trequestRender: () => {\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\tresult: this.result,\n\t\t\tgroupRole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t};\n\t}\n\n\tprivate getStatusDot(): string {\n\t\tconst state = this.isPartial ? \"pending\" : this.result?.isError ? \"error\" : \"success\";\n\t\treturn toolStatusDot(state, theme);\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(\n\t\t\tformatGroupedCall({\n\t\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\t\tcompact: !this.isPartial && !this.expanded && !this.result?.isError,\n\t\t\t\tdot: this.getStatusDot(),\n\t\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t\t}),\n\t\t\t0,\n\t\t\t0,\n\t\t);\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\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\t// lunr: consecutive same-tool grouping — exposes the tool name so the caller\n\t// can detect adjacency.\n\tgetToolName(): string {\n\t\treturn this.toolName;\n\t}\n\n\t// lunr: consecutive same-tool grouping — continuation calls hide the top\n\t// spacer and top box pad so adjacent same-bg boxes read as one continuous\n\t// background; the last card in a run keeps its bottom pad.\n\tsetGroupContinuation(on: boolean): void {\n\t\tthis.groupContinuation = on;\n\t\tthis.topSpacer.setLines(on ? 0 : 1);\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\t// lunr: previous card in a same-name run drops its bottom pad so the next\n\t// header sits flush. Singletons and mixed neighbors keep paddingBottom = 1.\n\tsetGroupFollowed(on: boolean): void {\n\t\tthis.groupFollowed = on;\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\tprivate applyGroupPadding(): void {\n\t\tconst top = this.groupContinuation ? 0 : 1;\n\t\tconst bottom = this.groupFollowed ? 0 : 1;\n\t\tthis.contentBox.setPaddingTop(top);\n\t\tthis.contentBox.setPaddingBottom(bottom);\n\t\tthis.contentText.setPaddingTop(top);\n\t\tthis.contentText.setPaddingBottom(bottom);\n\t\tif (this.getRenderShell() === \"self\" && this.callRendererComponent instanceof Box) {\n\t\t\tthis.callRendererComponent.setPaddingTop(top);\n\t\t\tthis.callRendererComponent.setPaddingBottom(bottom);\n\t\t}\n\t}\n\n\tprivate shouldSkipCompactResult(): boolean {\n\t\treturn (\n\t\t\tthis.getRenderShell() === \"default\" &&\n\t\t\tthis.result !== undefined &&\n\t\t\t!this.isPartial &&\n\t\t\t!this.expanded &&\n\t\t\t!this.result.isError\n\t\t);\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\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\tif (!this.groupContinuation) {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\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\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}\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\trenderContainer.addChild(this.createCallFallback());\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 skipCompactBody = this.shouldSkipCompactResult();\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tif (!skipCompactBody) {\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} 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 as any, details: this.result.details },\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\tif (!skipCompactBody) {\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} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tif (!skipCompactBody) {\n\t\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\n\t\tthis.applyGroupPadding();\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tconst compact = !this.isPartial && !this.expanded && !this.result?.isError;\n\t\tlet text = formatGroupedCall({\n\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\tcompact,\n\t\t\tdot: this.getStatusDot(),\n\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t});\n\t\tif (compact) {\n\t\t\treturn text;\n\t\t}\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\n/** Collapse facing pad when `next` is appended after a same-name tool card. */\nexport function applySameToolGrouping(\n\tprevious: ToolExecutionComponent | undefined,\n\tnext: ToolExecutionComponent,\n): void {\n\tif (previous && previous.getToolName() === next.getToolName()) {\n\t\tprevious.setGroupFollowed(true);\n\t\tnext.setGroupContinuation(true);\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 { Box, type Component, Container, getCapabilities, Image, Spacer, Text, type TUI } from \"@ashx-j/lunr-tui\";\nimport type { ToolDefinition, ToolRenderContext } from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport {\n\tformatGroupedCall,\n\tgetTextOutput as getRenderedTextOutput,\n\ttoolGroupRole,\n\ttoolStatusDot,\n} from \"../../../core/tools/render-utils.ts\";\nimport { convertToPng } from \"../../../utils/image-convert.ts\";\nimport { theme } from \"../theme/theme.ts\";\n\nexport interface ToolExecutionOptions {\n\tshowImages?: boolean;\n\timageWidthCells?: number;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\t// lunr: top spacer kept as a field so consecutive same-tool calls can be\n\t// grouped into one continuous background by zeroing it (setGroupContinuation).\n\tprivate topSpacer: Spacer;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: any = {};\n\tprivate imageComponents: Image[] = [];\n\tprivate imageSpacers: Spacer[] = [];\n\tprivate toolName: string;\n\tprivate toolCallId: string;\n\tprivate args: any;\n\tprivate expanded = false;\n\tprivate showImages: boolean;\n\tprivate imageWidthCells: number;\n\tprivate isPartial = true;\n\tprivate toolDefinition?: ToolDefinition<any, any>;\n\tprivate builtInToolDefinition?: ToolDefinition<any, any>;\n\tprivate ui: TUI;\n\tprivate cwd: string;\n\tprivate executionStarted = false;\n\tprivate argsComplete = false;\n\tprivate result?: {\n\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\tisError: boolean;\n\t\tdetails?: any;\n\t};\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = false;\n\tprivate groupContinuation = false;\n\tprivate groupFollowed = false;\n\n\tconstructor(\n\t\ttoolName: string,\n\t\ttoolCallId: string,\n\t\targs: any,\n\t\toptions: ToolExecutionOptions = {},\n\t\ttoolDefinition: ToolDefinition<any, any> | 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.ui = ui;\n\t\tthis.cwd = cwd;\n\n\t\tthis.topSpacer = new Spacer(1);\n\t\tthis.addChild(this.topSpacer);\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\t// lunr: default Box(1, 1). Same-name neighbors collapse facing pad only\n\t\t// (setGroupContinuation / setGroupFollowed); mixed and lone cards keep air.\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<any, any>[\"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<any, any>[\"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\trequestRender: () => {\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\tresult: this.result,\n\t\t\tgroupRole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t};\n\t}\n\n\tprivate getStatusDot(): string {\n\t\tconst state = this.isPartial ? \"pending\" : this.result?.isError ? \"error\" : \"success\";\n\t\treturn toolStatusDot(state, theme);\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(\n\t\t\tformatGroupedCall({\n\t\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\t\tcompact: !this.isPartial && !this.expanded && !this.result?.isError,\n\t\t\t\tdot: this.getStatusDot(),\n\t\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t\t}),\n\t\t\t0,\n\t\t\t0,\n\t\t);\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\t\treturn new Text(theme.fg(\"toolOutput\", output), 0, 0);\n\t}\n\n\tupdateArgs(args: any): void {\n\t\tthis.args = args;\n\t\tthis.updateDisplay();\n\t}\n\n\tmarkExecutionStarted(): void {\n\t\tthis.executionStarted = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tsetArgsComplete(): void {\n\t\tthis.argsComplete = true;\n\t\tthis.updateDisplay();\n\t\tthis.ui.requestRender();\n\t}\n\n\tupdateResult(\n\t\tresult: {\n\t\t\tcontent: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;\n\t\t\tdetails?: any;\n\t\t\tisError: boolean;\n\t\t},\n\t\tisPartial = false,\n\t): void {\n\t\tthis.result = result;\n\t\tthis.isPartial = isPartial;\n\t\tthis.updateDisplay();\n\t\tthis.maybeConvertImagesForKitty();\n\t}\n\n\tprivate maybeConvertImagesForKitty(): void {\n\t\tconst caps = getCapabilities();\n\t\tif (caps.images !== \"kitty\") return;\n\t\tif (!this.result) return;\n\n\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\tconst img = imageBlocks[i];\n\t\t\tif (!img.data || !img.mimeType) continue;\n\t\t\tif (img.mimeType === \"image/png\") continue;\n\t\t\tif (this.convertedImages.has(i)) continue;\n\n\t\t\tconst index = i;\n\t\t\tconvertToPng(img.data, img.mimeType).then((converted) => {\n\t\t\t\tif (converted) {\n\t\t\t\t\tthis.convertedImages.set(index, converted);\n\t\t\t\t\tthis.updateDisplay();\n\t\t\t\t\tthis.ui.requestRender();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\thandleClick(_localY: number, _width: number): boolean {\n\t\tif (this.isPartial) return false;\n\t\tif (this.toolName === \"subagent\" || this.toolName === \"subagent_wait\") return false;\n\t\tthis.setExpanded(!this.expanded);\n\t\tthis.ui.requestRender();\n\t\treturn true;\n\t}\n\n\t// lunr: consecutive same-tool grouping — exposes the tool name so the caller\n\t// can detect adjacency.\n\tgetToolName(): string {\n\t\treturn this.toolName;\n\t}\n\n\t// lunr: consecutive same-tool grouping — continuation calls hide the top\n\t// spacer and top box pad so adjacent same-bg boxes read as one continuous\n\t// background; the last card in a run keeps its bottom pad.\n\tsetGroupContinuation(on: boolean): void {\n\t\tthis.groupContinuation = on;\n\t\tthis.topSpacer.setLines(on ? 0 : 1);\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\t// lunr: previous card in a same-name run drops its bottom pad so the next\n\t// header sits flush. Singletons and mixed neighbors keep paddingBottom = 1.\n\tsetGroupFollowed(on: boolean): void {\n\t\tthis.groupFollowed = on;\n\t\tthis.applyGroupPadding();\n\t\tthis.invalidate();\n\t}\n\n\tprivate applyGroupPadding(): void {\n\t\tconst top = this.groupContinuation ? 0 : 1;\n\t\tconst bottom = this.groupFollowed ? 0 : 1;\n\t\tthis.contentBox.setPaddingTop(top);\n\t\tthis.contentBox.setPaddingBottom(bottom);\n\t\tthis.contentText.setPaddingTop(top);\n\t\tthis.contentText.setPaddingBottom(bottom);\n\t\tif (this.getRenderShell() === \"self\" && this.callRendererComponent instanceof Box) {\n\t\t\tthis.callRendererComponent.setPaddingTop(top);\n\t\t\tthis.callRendererComponent.setPaddingBottom(bottom);\n\t\t}\n\t}\n\n\tprivate shouldSkipCompactResult(): boolean {\n\t\treturn (\n\t\t\tthis.getRenderShell() === \"default\" &&\n\t\t\tthis.result !== undefined &&\n\t\t\t!this.isPartial &&\n\t\t\t!this.expanded &&\n\t\t\t!this.result.isError\n\t\t);\n\t}\n\n\tsetShowImages(show: boolean): void {\n\t\tthis.showImages = show;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetImageWidthCells(width: number): void {\n\t\tthis.imageWidthCells = Math.max(1, Math.floor(width));\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\toverride render(width: number): string[] {\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\tif (!this.groupContinuation) {\n\t\t\t\t\tlines.push(\"\");\n\t\t\t\t}\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\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}\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\trenderContainer.addChild(this.createCallFallback());\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 skipCompactBody = this.shouldSkipCompactResult();\n\t\t\t\tconst resultRenderer = this.getResultRenderer();\n\t\t\t\tif (!resultRenderer) {\n\t\t\t\t\tif (!skipCompactBody) {\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} 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 as any, details: this.result.details },\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\tif (!skipCompactBody) {\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} catch {\n\t\t\t\t\t\tthis.resultRendererComponent = undefined;\n\t\t\t\t\t\tif (!skipCompactBody) {\n\t\t\t\t\t\t\tconst component = this.createResultFallback();\n\t\t\t\t\t\t\tif (component) {\n\t\t\t\t\t\t\t\trenderContainer.addChild(component);\n\t\t\t\t\t\t\t\thasContent = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.contentText.setCustomBgFn(bgFn);\n\t\t\tthis.contentText.setText(this.formatToolExecution());\n\t\t\thasContent = true;\n\t\t}\n\n\t\tfor (const img of this.imageComponents) {\n\t\t\tthis.removeChild(img);\n\t\t}\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) {\n\t\t\tthis.removeChild(spacer);\n\t\t}\n\t\tthis.imageSpacers = [];\n\n\t\tif (this.result) {\n\t\t\tconst imageBlocks = this.result.content.filter((c) => c.type === \"image\");\n\t\t\tconst caps = getCapabilities();\n\t\t\tfor (let i = 0; i < imageBlocks.length; i++) {\n\t\t\t\tconst img = imageBlocks[i];\n\t\t\t\tif (caps.images && this.showImages && img.data && img.mimeType) {\n\t\t\t\t\tconst converted = this.convertedImages.get(i);\n\t\t\t\t\tconst imageData = converted?.data ?? img.data;\n\t\t\t\t\tconst imageMimeType = converted?.mimeType ?? img.mimeType;\n\t\t\t\t\tif (caps.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\n\t\t\t\t\tconst spacer = new Spacer(1);\n\t\t\t\t\tthis.addChild(spacer);\n\t\t\t\t\tthis.imageSpacers.push(spacer);\n\t\t\t\t\tconst imageComponent = new Image(\n\t\t\t\t\t\timageData,\n\t\t\t\t\t\timageMimeType,\n\t\t\t\t\t\t{ fallbackColor: (s: string) => theme.fg(\"toolOutput\", s) },\n\t\t\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t\t\t);\n\t\t\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\t\t\tthis.addChild(imageComponent);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.hasRendererDefinition() && !hasContent && this.imageComponents.length === 0) {\n\t\t\tthis.hideComponent = true;\n\t\t}\n\n\t\tthis.applyGroupPadding();\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tconst compact = !this.isPartial && !this.expanded && !this.result?.isError;\n\t\tlet text = formatGroupedCall({\n\t\t\trole: toolGroupRole(this.groupContinuation, this.groupFollowed),\n\t\t\tcompact,\n\t\t\tdot: this.getStatusDot(),\n\t\t\ttitle: theme.fg(\"toolTitle\", theme.bold(this.toolName)),\n\t\t});\n\t\tif (compact) {\n\t\t\treturn text;\n\t\t}\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\n/** Collapse facing pad when `next` is appended after a same-name tool card. */\nexport function applySameToolGrouping(\n\tprevious: ToolExecutionComponent | undefined,\n\tnext: ToolExecutionComponent,\n): void {\n\tif (previous && previous.getToolName() === next.getToolName()) {\n\t\tprevious.setGroupFollowed(true);\n\t\tnext.setGroupContinuation(true);\n\t}\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  * Interactive mode for the coding agent.
3
3
  * Handles TUI rendering and user interaction, delegating business logic to AgentSession.
4
4
  */
5
- import type { ImageContent } from "@ashx-j/lunr-ai/compat";
5
+ import { type ImageContent } from "@ashx-j/lunr-ai/compat";
6
6
  import { type AgentSessionRuntime } from "../../core/agent-session-runtime.ts";
7
7
  import type { InlineExtension } from "../../core/extensions/index.ts";
8
8
  import { SessionManager } from "../../core/session-manager.ts";
@@ -122,6 +122,9 @@ export declare class InteractiveMode {
122
122
  init(): Promise<void>;
123
123
  /** Wait until deferred builtins have attached (or were skipped). */
124
124
  waitForDeferredBuiltins(): Promise<void>;
125
+ private planUsageTimer;
126
+ private startPlanUsagePolling;
127
+ private maybeNotifyCliUpdate;
125
128
  /**
126
129
  * Update terminal title with session name and cwd.
127
130
  */
@@ -414,7 +417,9 @@ export declare class InteractiveMode {
414
417
  private handleInitCommand;
415
418
  private handleSwarmCommand;
416
419
  private handleResearchCommand;
420
+ private rewindLastTurn;
417
421
  private handleUndoCommand;
422
+ private handleEditCommand;
418
423
  private handleRedoCommand;
419
424
  private handleReloadCommand;
420
425
  private handleExportCommand;