@greppleai/grip 0.0.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +13 -7
  3. package/dist/bun/cli.d.ts.map +1 -1
  4. package/dist/bun/cli.js +4 -2
  5. package/dist/bun/cli.js.map +1 -1
  6. package/dist/bun/embedded-assets.d.ts +3 -0
  7. package/dist/bun/embedded-assets.d.ts.map +1 -0
  8. package/dist/bun/embedded-assets.js +52 -0
  9. package/dist/bun/embedded-assets.js.map +1 -0
  10. package/dist/cli/args.d.ts.map +1 -1
  11. package/dist/cli/args.js +1 -0
  12. package/dist/cli/args.js.map +1 -1
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +3 -3
  15. package/dist/config.js.map +1 -1
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +17 -2
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/remote-workspace-protocol/contract.d.ts +13 -4
  20. package/dist/core/remote-workspace-protocol/contract.d.ts.map +1 -1
  21. package/dist/core/remote-workspace-protocol/contract.js +17 -1
  22. package/dist/core/remote-workspace-protocol/contract.js.map +1 -1
  23. package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts +16 -0
  24. package/dist/core/remote-workspace-protocol/guest-shared-client.d.ts.map +1 -0
  25. package/dist/core/remote-workspace-protocol/guest-shared-client.js +54 -0
  26. package/dist/core/remote-workspace-protocol/guest-shared-client.js.map +1 -0
  27. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts +23 -0
  28. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.d.ts.map +1 -0
  29. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js +112 -0
  30. package/dist/core/remote-workspace-protocol/guest-shared-outbound-scheduler.js.map +1 -0
  31. package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts +30 -0
  32. package/dist/core/remote-workspace-protocol/guest-shared-uplink.d.ts.map +1 -0
  33. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js +243 -0
  34. package/dist/core/remote-workspace-protocol/guest-shared-uplink.js.map +1 -0
  35. package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts +3 -0
  36. package/dist/core/remote-workspace-protocol/lima-owner-directory.d.ts.map +1 -0
  37. package/dist/core/remote-workspace-protocol/lima-owner-directory.js +31 -0
  38. package/dist/core/remote-workspace-protocol/lima-owner-directory.js.map +1 -0
  39. package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts +9 -0
  40. package/dist/core/remote-workspace-protocol/lima-owner-lock.d.ts.map +1 -0
  41. package/dist/core/remote-workspace-protocol/lima-owner-lock.js +89 -0
  42. package/dist/core/remote-workspace-protocol/lima-owner-lock.js.map +1 -0
  43. package/dist/core/remote-workspace-protocol/session.d.ts +2 -0
  44. package/dist/core/remote-workspace-protocol/session.d.ts.map +1 -1
  45. package/dist/core/remote-workspace-protocol/session.js +3 -0
  46. package/dist/core/remote-workspace-protocol/session.js.map +1 -1
  47. package/dist/core/remote-workspace-protocol/shared-transport.d.ts +71 -0
  48. package/dist/core/remote-workspace-protocol/shared-transport.d.ts.map +1 -0
  49. package/dist/core/remote-workspace-protocol/shared-transport.js +68 -0
  50. package/dist/core/remote-workspace-protocol/shared-transport.js.map +1 -0
  51. package/dist/core/sandbox/command.d.ts +2 -4
  52. package/dist/core/sandbox/command.d.ts.map +1 -1
  53. package/dist/core/sandbox/command.js +24 -46
  54. package/dist/core/sandbox/command.js.map +1 -1
  55. package/dist/core/sandbox/config.d.ts +91 -0
  56. package/dist/core/sandbox/config.d.ts.map +1 -0
  57. package/dist/core/sandbox/config.js +88 -0
  58. package/dist/core/sandbox/config.js.map +1 -0
  59. package/dist/core/sandbox/lima-guest-binary.d.ts +11 -0
  60. package/dist/core/sandbox/lima-guest-binary.d.ts.map +1 -0
  61. package/dist/core/sandbox/lima-guest-binary.js +140 -0
  62. package/dist/core/sandbox/lima-guest-binary.js.map +1 -0
  63. package/dist/core/sandbox/lima.d.ts +22 -3
  64. package/dist/core/sandbox/lima.d.ts.map +1 -1
  65. package/dist/core/sandbox/lima.js +434 -42
  66. package/dist/core/sandbox/lima.js.map +1 -1
  67. package/dist/core/sandbox/shared-lima-roots.d.ts +11 -0
  68. package/dist/core/sandbox/shared-lima-roots.d.ts.map +1 -0
  69. package/dist/core/sandbox/shared-lima-roots.js +25 -0
  70. package/dist/core/sandbox/shared-lima-roots.js.map +1 -0
  71. package/dist/core/sandbox/update-shared-guest-binary.d.ts +8 -0
  72. package/dist/core/sandbox/update-shared-guest-binary.d.ts.map +1 -0
  73. package/dist/core/sandbox/update-shared-guest-binary.js +100 -0
  74. package/dist/core/sandbox/update-shared-guest-binary.js.map +1 -0
  75. package/dist/core/settings-manager.d.ts +1 -5
  76. package/dist/core/settings-manager.d.ts.map +1 -1
  77. package/dist/core/settings-manager.js.map +1 -1
  78. package/dist/core/tools/bash.d.ts.map +1 -1
  79. package/dist/core/tools/bash.js +25 -14
  80. package/dist/core/tools/bash.js.map +1 -1
  81. package/dist/core/tools/file-mutation-queue.d.ts +2 -0
  82. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  83. package/dist/core/tools/file-mutation-queue.js +9 -0
  84. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  85. package/dist/core/tools/operations.d.ts +13 -2
  86. package/dist/core/tools/operations.d.ts.map +1 -1
  87. package/dist/core/tools/operations.js +132 -36
  88. package/dist/core/tools/operations.js.map +1 -1
  89. package/dist/daemon/activity-budget.d.ts +10 -0
  90. package/dist/daemon/activity-budget.d.ts.map +1 -0
  91. package/dist/daemon/activity-budget.js +34 -0
  92. package/dist/daemon/activity-budget.js.map +1 -0
  93. package/dist/daemon/config.d.ts +2 -0
  94. package/dist/daemon/config.d.ts.map +1 -1
  95. package/dist/daemon/config.js +15 -0
  96. package/dist/daemon/config.js.map +1 -1
  97. package/dist/daemon/outbound-budget.d.ts +10 -0
  98. package/dist/daemon/outbound-budget.d.ts.map +1 -0
  99. package/dist/daemon/outbound-budget.js +30 -0
  100. package/dist/daemon/outbound-budget.js.map +1 -0
  101. package/dist/daemon/security.d.ts.map +1 -1
  102. package/dist/daemon/security.js +3 -1
  103. package/dist/daemon/security.js.map +1 -1
  104. package/dist/daemon/server.d.ts.map +1 -1
  105. package/dist/daemon/server.js +104 -24
  106. package/dist/daemon/server.js.map +1 -1
  107. package/dist/daemon/shared-connection.d.ts +33 -0
  108. package/dist/daemon/shared-connection.d.ts.map +1 -0
  109. package/dist/daemon/shared-connection.js +271 -0
  110. package/dist/daemon/shared-connection.js.map +1 -0
  111. package/dist/daemon/shared-revision.d.ts +5 -0
  112. package/dist/daemon/shared-revision.d.ts.map +1 -0
  113. package/dist/daemon/shared-revision.js +61 -0
  114. package/dist/daemon/shared-revision.js.map +1 -0
  115. package/dist/daemon/shared-roots.d.ts +9 -0
  116. package/dist/daemon/shared-roots.d.ts.map +1 -0
  117. package/dist/daemon/shared-roots.js +33 -0
  118. package/dist/daemon/shared-roots.js.map +1 -0
  119. package/dist/daemon/workspace-runtime.d.ts +1 -1
  120. package/dist/daemon/workspace-runtime.d.ts.map +1 -1
  121. package/dist/daemon/workspace-runtime.js +42 -10
  122. package/dist/daemon/workspace-runtime.js.map +1 -1
  123. package/dist/main.d.ts.map +1 -1
  124. package/dist/main.js +5 -3
  125. package/dist/main.js.map +1 -1
  126. package/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  127. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  128. package/dist/modes/interactive/components/assistant-message.js +13 -3
  129. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  130. package/dist/modes/interactive/components/branch-summary-message.d.ts +4 -3
  131. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/branch-summary-message.js +5 -4
  133. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  134. package/dist/modes/interactive/components/compaction-summary-message.d.ts +4 -3
  135. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  136. package/dist/modes/interactive/components/compaction-summary-message.js +5 -4
  137. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  138. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  139. package/dist/modes/interactive/components/custom-message.js +4 -3
  140. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  141. package/dist/modes/interactive/components/hook-execution.d.ts.map +1 -1
  142. package/dist/modes/interactive/components/hook-execution.js +3 -2
  143. package/dist/modes/interactive/components/hook-execution.js.map +1 -1
  144. package/dist/modes/interactive/components/message-card.d.ts +9 -0
  145. package/dist/modes/interactive/components/message-card.d.ts.map +1 -0
  146. package/dist/modes/interactive/components/message-card.js +24 -0
  147. package/dist/modes/interactive/components/message-card.js.map +1 -0
  148. package/dist/modes/interactive/components/skill-invocation-message.d.ts +4 -3
  149. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  150. package/dist/modes/interactive/components/skill-invocation-message.js +5 -4
  151. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  152. package/dist/modes/interactive/components/tool-execution.d.ts +1 -1
  153. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  154. package/dist/modes/interactive/components/tool-execution.js +27 -21
  155. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  156. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  157. package/dist/modes/interactive/components/user-message.js +3 -2
  158. package/dist/modes/interactive/components/user-message.js.map +1 -1
  159. package/dist/modes/interactive/interactive-mode.d.ts +0 -3
  160. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  161. package/dist/modes/interactive/interactive-mode.js +55 -44
  162. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  163. package/dist/modes/interactive/theme/theme.d.ts +3 -0
  164. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  165. package/dist/modes/interactive/theme/theme.js +10 -0
  166. package/dist/modes/interactive/theme/theme.js.map +1 -1
  167. package/dist/utils/clipboard-native.d.ts.map +1 -1
  168. package/dist/utils/clipboard-native.js +1 -1
  169. package/dist/utils/clipboard-native.js.map +1 -1
  170. package/dist/utils/image-resize.d.ts.map +1 -1
  171. package/dist/utils/image-resize.js +5 -0
  172. package/dist/utils/image-resize.js.map +1 -1
  173. package/dist/utils/photon.d.ts.map +1 -1
  174. package/dist/utils/photon.js +1 -0
  175. package/dist/utils/photon.js.map +1 -1
  176. package/docs/daemon.md +6 -4
  177. package/docs/docs.json +1 -1
  178. package/docs/index.md +8 -12
  179. package/docs/packages.md +3 -3
  180. package/docs/quickstart.md +11 -19
  181. package/docs/sandbox.md +40 -117
  182. package/docs/settings.md +12 -11
  183. package/docs/termux.md +1 -18
  184. package/docs/usage.md +2 -2
  185. package/examples/README.md +0 -2
  186. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  187. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  188. package/examples/extensions/sandbox/package.json +1 -1
  189. package/examples/extensions/with-deps/package.json +1 -1
  190. package/npm-shrinkwrap.json +12 -12
  191. package/package.json +5 -6
  192. package/dist/core/sandbox/docker.d.ts +0 -169
  193. package/dist/core/sandbox/docker.d.ts.map +0 -1
  194. package/dist/core/sandbox/docker.js +0 -633
  195. package/dist/core/sandbox/docker.js.map +0 -1
  196. package/examples/sandbox-docker/Dockerfile +0 -274
  197. package/examples/sandbox-docker/README.md +0 -88
@@ -0,0 +1,24 @@
1
+ import { Box } from "@greppleai/grip-tui";
2
+ import { theme } from "../theme/theme.js";
3
+ /** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */
4
+ export class MessageCard extends Box {
5
+ stripeColor;
6
+ constructor(paddingX, paddingY, stripeColor) {
7
+ super(paddingX, paddingY);
8
+ this.stripeColor = stripeColor;
9
+ }
10
+ render(width) {
11
+ if (!this.stripeColor)
12
+ return super.render(width).map((line) => line.trimEnd());
13
+ if (width < 1)
14
+ return [];
15
+ const marker = theme.bgFromFg(this.stripeColor, " ");
16
+ return super.render(Math.max(1, width - 2)).map((line) => {
17
+ if (width <= 2)
18
+ return marker;
19
+ const content = line.trimEnd();
20
+ return content ? `${marker} ${content}` : marker;
21
+ });
22
+ }
23
+ }
24
+ //# sourceMappingURL=message-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-card.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/message-card.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAmB,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE3D,+FAA+F;AAC/F,MAAM,OAAO,WAAY,SAAQ,GAAG;IAClB,WAAW,CAAc;IAE1C,YAAY,QAAgB,EAAE,QAAgB,EAAE,WAAwB,EAAE;QACzE,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAAA,CAC/B;IAEQ,MAAM,CAAC,KAAa,EAAY;QACxC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAChF,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,MAAM,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAAA,CACjD,CAAC,CAAC;IAAA,CACH;CACD","sourcesContent":["import { Box } from \"@greppleai/grip-tui\";\nimport { type ThemeColor, theme } from \"../theme/theme.ts\";\n\n/** Message card with internal padding, an optional one-cell stripe, and no trailing spaces. */\nexport class MessageCard extends Box {\n\tprivate readonly stripeColor?: ThemeColor;\n\n\tconstructor(paddingX: number, paddingY: number, stripeColor?: ThemeColor) {\n\t\tsuper(paddingX, paddingY);\n\t\tthis.stripeColor = stripeColor;\n\t}\n\n\toverride render(width: number): string[] {\n\t\tif (!this.stripeColor) return super.render(width).map((line) => line.trimEnd());\n\t\tif (width < 1) return [];\n\n\t\tconst marker = theme.bgFromFg(this.stripeColor, \" \");\n\t\treturn super.render(Math.max(1, width - 2)).map((line) => {\n\t\t\tif (width <= 2) return marker;\n\t\t\tconst content = line.trimEnd();\n\t\t\treturn content ? `${marker} ${content}` : marker;\n\t\t});\n\t}\n}\n"]}
@@ -1,11 +1,12 @@
1
- import { Box, type MarkdownTheme } from "@greppleai/grip-tui";
1
+ import { type MarkdownTheme } from "@greppleai/grip-tui";
2
2
  import type { ParsedSkillBlock } from "../../../core/agent-session.ts";
3
+ import { MessageCard } from "./message-card.ts";
3
4
  /**
4
5
  * Component that renders a skill invocation message with collapsed/expanded state.
5
- * Uses same background color as custom messages for visual consistency.
6
+ * Uses a colored label to distinguish it without filling the whole card background.
6
7
  * Only renders the skill block itself - user message is rendered separately.
7
8
  */
8
- export declare class SkillInvocationMessageComponent extends Box {
9
+ export declare class SkillInvocationMessageComponent extends MessageCard {
9
10
  private expanded;
10
11
  private skillBlock;
11
12
  private markdownTheme;
@@ -1 +1 @@
1
- {"version":3,"file":"skill-invocation-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/skill-invocation-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAY,KAAK,aAAa,EAAQ,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAIvE;;;;GAIG;AACH,qBAAa,+BAAgC,SAAQ,GAAG;IACvD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,UAAU,EAAE,gBAAgB,EAAE,aAAa,GAAE,aAAkC,EAK1F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;CAsBrB","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Text } from \"@greppleai/grip-tui\";\nimport type { ParsedSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/**\n * Component that renders a skill invocation message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n * Only renders the skill block itself - user message is rendered separately.\n */\nexport class SkillInvocationMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate skillBlock: ParsedSkillBlock;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(skillBlock: ParsedSkillBlock, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.skillBlock = skillBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tif (this.expanded) {\n\t\t\t// Expanded: label + skill name header + full content\n\t\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m`);\n\t\t\tthis.addChild(new Text(label, 0, 0));\n\t\t\tconst header = `**${this.skillBlock.name}**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.skillBlock.content, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\t// Collapsed: single line - [skill] name (hint to expand)\n\t\t\tconst line =\n\t\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\t\ttheme.fg(\"customMessageText\", this.skillBlock.name) +\n\t\t\t\ttheme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\t\t\tthis.addChild(new Text(line, 0, 0));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"skill-invocation-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/skill-invocation-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,aAAa,EAAQ,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,+BAAgC,SAAQ,WAAW;IAC/D,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,aAAa,CAAgB;IAErC,YAAY,UAAU,EAAE,gBAAgB,EAAE,aAAa,GAAE,aAAkC,EAK1F;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAGnC;IAEQ,UAAU,IAAI,IAAI,CAG1B;IAED,OAAO,CAAC,aAAa;CAsBrB","sourcesContent":["import { Markdown, type MarkdownTheme, Text } from \"@greppleai/grip-tui\";\nimport type { ParsedSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\nimport { MessageCard } from \"./message-card.ts\";\n\n/**\n * Component that renders a skill invocation message with collapsed/expanded state.\n * Uses a colored label to distinguish it without filling the whole card background.\n * Only renders the skill block itself - user message is rendered separately.\n */\nexport class SkillInvocationMessageComponent extends MessageCard {\n\tprivate expanded = false;\n\tprivate skillBlock: ParsedSkillBlock;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(skillBlock: ParsedSkillBlock, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1);\n\t\tthis.skillBlock = skillBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tif (this.expanded) {\n\t\t\t// Expanded: label + skill name header + full content\n\t\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m`);\n\t\t\tthis.addChild(new Text(label, 0, 0));\n\t\t\tconst header = `**${this.skillBlock.name}**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.skillBlock.content, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\t// Collapsed: single line - [skill] name (hint to expand)\n\t\t\tconst line =\n\t\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\t\ttheme.fg(\"customMessageText\", this.skillBlock.name) +\n\t\t\t\ttheme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\t\t\tthis.addChild(new Text(line, 0, 0));\n\t\t}\n\t}\n}\n"]}
@@ -1,17 +1,18 @@
1
- import { Box, Markdown, Text } from "@greppleai/grip-tui";
1
+ import { Markdown, Text } from "@greppleai/grip-tui";
2
2
  import { getMarkdownTheme, theme } from "../theme/theme.js";
3
3
  import { keyText } from "./keybinding-hints.js";
4
+ import { MessageCard } from "./message-card.js";
4
5
  /**
5
6
  * Component that renders a skill invocation message with collapsed/expanded state.
6
- * Uses same background color as custom messages for visual consistency.
7
+ * Uses a colored label to distinguish it without filling the whole card background.
7
8
  * Only renders the skill block itself - user message is rendered separately.
8
9
  */
9
- export class SkillInvocationMessageComponent extends Box {
10
+ export class SkillInvocationMessageComponent extends MessageCard {
10
11
  expanded = false;
11
12
  skillBlock;
12
13
  markdownTheme;
13
14
  constructor(skillBlock, markdownTheme = getMarkdownTheme()) {
14
- super(1, 1, (t) => theme.bg("customMessageBg", t));
15
+ super(1, 1);
15
16
  this.skillBlock = skillBlock;
16
17
  this.markdownTheme = markdownTheme;
17
18
  this.updateDisplay();
@@ -1 +1 @@
1
- {"version":3,"file":"skill-invocation-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/skill-invocation-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAsB,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,OAAO,+BAAgC,SAAQ,GAAG;IAC/C,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,CAAmB;IAC7B,aAAa,CAAgB;IAErC,YAAY,UAA4B,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE;QAC5F,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC;YACjD,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACxE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,yDAAyD;YACzD,MAAM,IAAI,GACT,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,yBAAyB,CAAC;gBACzD,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,OAAO,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;IAAA,CACD;CACD","sourcesContent":["import { Box, Markdown, type MarkdownTheme, Text } from \"@greppleai/grip-tui\";\nimport type { ParsedSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\n\n/**\n * Component that renders a skill invocation message with collapsed/expanded state.\n * Uses same background color as custom messages for visual consistency.\n * Only renders the skill block itself - user message is rendered separately.\n */\nexport class SkillInvocationMessageComponent extends Box {\n\tprivate expanded = false;\n\tprivate skillBlock: ParsedSkillBlock;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(skillBlock: ParsedSkillBlock, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1, (t) => theme.bg(\"customMessageBg\", t));\n\t\tthis.skillBlock = skillBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tif (this.expanded) {\n\t\t\t// Expanded: label + skill name header + full content\n\t\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m`);\n\t\t\tthis.addChild(new Text(label, 0, 0));\n\t\t\tconst header = `**${this.skillBlock.name}**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.skillBlock.content, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\t// Collapsed: single line - [skill] name (hint to expand)\n\t\t\tconst line =\n\t\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\t\ttheme.fg(\"customMessageText\", this.skillBlock.name) +\n\t\t\t\ttheme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\t\t\tthis.addChild(new Text(line, 0, 0));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"skill-invocation-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/skill-invocation-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,OAAO,+BAAgC,SAAQ,WAAW;IACvD,QAAQ,GAAG,KAAK,CAAC;IACjB,UAAU,CAAmB;IAC7B,aAAa,CAAgB;IAErC,YAAY,UAA4B,EAAE,aAAa,GAAkB,gBAAgB,EAAE,EAAE;QAC5F,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACZ,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAED,WAAW,CAAC,QAAiB,EAAQ;QACpC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEQ,UAAU,GAAS;QAC3B,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,IAAI,CAAC,aAAa,EAAE,CAAC;IAAA,CACrB;IAEO,aAAa,GAAS;QAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,qDAAqD;YACrD,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC;YACvE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC;YACjD,IAAI,CAAC,QAAQ,CACZ,IAAI,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE;gBACxE,KAAK,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC;aAC5D,CAAC,CACF,CAAC;QACH,CAAC;aAAM,CAAC;YACP,yDAAyD;YACzD,MAAM,IAAI,GACT,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,yBAAyB,CAAC;gBACzD,KAAK,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;gBACnD,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,OAAO,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAChE,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;IAAA,CACD;CACD","sourcesContent":["import { Markdown, type MarkdownTheme, Text } from \"@greppleai/grip-tui\";\nimport type { ParsedSkillBlock } from \"../../../core/agent-session.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { keyText } from \"./keybinding-hints.ts\";\nimport { MessageCard } from \"./message-card.ts\";\n\n/**\n * Component that renders a skill invocation message with collapsed/expanded state.\n * Uses a colored label to distinguish it without filling the whole card background.\n * Only renders the skill block itself - user message is rendered separately.\n */\nexport class SkillInvocationMessageComponent extends MessageCard {\n\tprivate expanded = false;\n\tprivate skillBlock: ParsedSkillBlock;\n\tprivate markdownTheme: MarkdownTheme;\n\n\tconstructor(skillBlock: ParsedSkillBlock, markdownTheme: MarkdownTheme = getMarkdownTheme()) {\n\t\tsuper(1, 1);\n\t\tthis.skillBlock = skillBlock;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.updateDisplay();\n\t}\n\n\tsetExpanded(expanded: boolean): void {\n\t\tthis.expanded = expanded;\n\t\tthis.updateDisplay();\n\t}\n\n\toverride invalidate(): void {\n\t\tsuper.invalidate();\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.clear();\n\n\t\tif (this.expanded) {\n\t\t\t// Expanded: label + skill name header + full content\n\t\t\tconst label = theme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m`);\n\t\t\tthis.addChild(new Text(label, 0, 0));\n\t\t\tconst header = `**${this.skillBlock.name}**\\n\\n`;\n\t\t\tthis.addChild(\n\t\t\t\tnew Markdown(header + this.skillBlock.content, 0, 0, this.markdownTheme, {\n\t\t\t\t\tcolor: (text: string) => theme.fg(\"customMessageText\", text),\n\t\t\t\t}),\n\t\t\t);\n\t\t} else {\n\t\t\t// Collapsed: single line - [skill] name (hint to expand)\n\t\t\tconst line =\n\t\t\t\ttheme.fg(\"customMessageLabel\", `\\x1b[1m[skill]\\x1b[22m `) +\n\t\t\t\ttheme.fg(\"customMessageText\", this.skillBlock.name) +\n\t\t\t\ttheme.fg(\"dim\", ` (${keyText(\"app.tools.expand\")} to expand)`);\n\t\t\tthis.addChild(new Text(line, 0, 0));\n\t\t}\n\t}\n}\n"]}
@@ -36,6 +36,7 @@ export declare class ToolExecutionComponent extends Container {
36
36
  private convertedImages;
37
37
  private hideComponent;
38
38
  constructor(toolName: string, toolCallId: string, args: any, options: ToolExecutionOptions | undefined, toolDefinition: ToolDefinition<any, any> | undefined, ui: TUI, cwd: string);
39
+ private withStatusLine;
39
40
  private getCallRenderer;
40
41
  private getResultRenderer;
41
42
  private hasRendererDefinition;
@@ -53,7 +54,6 @@ export declare class ToolExecutionComponent extends Container {
53
54
  setImageWidthCells(width: number): void;
54
55
  invalidate(): void;
55
56
  render(width: number): string[];
56
- private getBackgroundFormatter;
57
57
  private renderToolCall;
58
58
  private renderToolResult;
59
59
  private renderDefinitionContent;
@@ -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 \"@greppleai/grip-tui\";\nimport type {\n\tToolCallRenderer,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderShell,\n\tToolResultRenderer,\n} from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { LocalToolOperations } from \"../../../core/tools/operations.ts\";\nimport {\n\tgetTextOutput as getRenderedTextOutput,\n\ttype ToolTextOutputContent,\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}\nexport interface ToolExecutionDisplayResult {\n\tcontent: ToolTextOutputContent[];\n\tdetails?: any;\n\tisError: boolean;\n}\n\ntype ToolBackgroundFormatter = (text: string) => string;\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: 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?: ToolExecutionDisplayResult;\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = 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(new LocalToolOperations(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.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolCallRenderer<any, any> | 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(): ToolResultRenderer<any, any, any> | 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(): ToolRenderShell {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\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(result: ToolExecutionDisplayResult, isPartial = false): 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\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\t\treturn super.render(width);\n\t}\n\n\tprivate getBackgroundFormatter(): ToolBackgroundFormatter {\n\t\tif (this.isPartial) return (text) => theme.bg(\"toolPendingBg\", text);\n\t\tif (this.result?.isError) return (text) => theme.bg(\"toolErrorBg\", text);\n\t\treturn (text) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\n\tprivate renderToolCall(renderContainer: Container): boolean {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tif (!callRenderer) {\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\tthis.callRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t} catch {\n\t\t\tthis.callRendererComponent = undefined;\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate renderToolResult(renderContainer: Container): boolean {\n\t\tif (!this.result) return false;\n\t\tconst resultRenderer = this.getResultRenderer();\n\t\tif (!resultRenderer) {\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = resultRenderer(\n\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\ttheme,\n\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t);\n\t\t\tthis.resultRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tthis.resultRendererComponent = undefined;\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate renderDefinitionContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\tif (renderContainer instanceof Box) renderContainer.setBgFn(backgroundFormatter);\n\t\trenderContainer.clear();\n\t\tconst callHasContent = this.renderToolCall(renderContainer);\n\t\tconst resultHasContent = this.renderToolResult(renderContainer);\n\t\treturn callHasContent || resultHasContent;\n\t}\n\n\tprivate renderGenericContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tthis.contentText.setCustomBgFn(backgroundFormatter);\n\t\tthis.contentText.setText(this.formatToolExecution());\n\t\treturn true;\n\t}\n\n\tprivate clearRenderedImages(): void {\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t}\n\n\tprivate renderResultImages(): void {\n\t\tif (!this.result) return;\n\t\tconst imageBlocks = this.result.content.filter((content) => content.type === \"image\");\n\t\tconst capabilities = getCapabilities();\n\t\tfor (let index = 0; index < imageBlocks.length; index++) {\n\t\t\tconst image = imageBlocks[index];\n\t\t\tif (!capabilities.images || !this.showImages || !image.data || !image.mimeType) continue;\n\t\t\tconst converted = this.convertedImages.get(index);\n\t\t\tconst imageData = converted?.data ?? image.data;\n\t\t\tconst imageMimeType = converted?.mimeType ?? image.mimeType;\n\t\t\tif (capabilities.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst imageComponent = new Image(\n\t\t\t\timageData,\n\t\t\t\timageMimeType,\n\t\t\t\t{ fallbackColor: (text: string) => theme.fg(\"toolOutput\", text) },\n\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\tthis.addChild(imageComponent);\n\t\t}\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst backgroundFormatter = this.getBackgroundFormatter();\n\t\tthis.hideComponent = false;\n\t\tconst hasRendererDefinition = this.hasRendererDefinition();\n\t\tconst hasContent = hasRendererDefinition\n\t\t\t? this.renderDefinitionContent(backgroundFormatter)\n\t\t\t: this.renderGenericContent(backgroundFormatter);\n\n\t\tthis.clearRenderedImages();\n\t\tthis.renderResultImages();\n\t\tif (hasRendererDefinition && !hasContent && this.imageComponents.length === 0) this.hideComponent = true;\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tBox,\n\ttype Component,\n\tContainer,\n\tgetCapabilities,\n\tImage,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type {\n\tToolCallRenderer,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderShell,\n\tToolResultRenderer,\n} from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { LocalToolOperations } from \"../../../core/tools/operations.ts\";\nimport {\n\tgetTextOutput as getRenderedTextOutput,\n\ttype ToolTextOutputContent,\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}\nexport interface ToolExecutionDisplayResult {\n\tcontent: ToolTextOutputContent[];\n\tdetails?: any;\n\tisError: boolean;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: 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?: ToolExecutionDisplayResult;\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = 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(new LocalToolOperations(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.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1);\n\t\tthis.contentText = new Text(\"\", 1, 1);\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst shell =\n\t\t\t\tthis.getRenderShell() === \"self\" ? this.selfRenderContainer : this.withStatusLine(this.contentBox);\n\t\t\tthis.addChild(shell);\n\t\t} else {\n\t\t\tthis.addChild(this.withStatusLine(this.contentText));\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate withStatusLine(content: Component): Component {\n\t\treturn {\n\t\t\trender: (width) => {\n\t\t\t\tif (width < 1) return [];\n\t\t\t\tconst color = this.isPartial ? \"muted\" : this.result?.isError ? \"error\" : \"success\";\n\t\t\t\tconst marker = theme.bgFromFg(color, \" \");\n\t\t\t\tconst contentWidth = Math.max(1, width - 2);\n\t\t\t\treturn content.render(contentWidth).map((line) => {\n\t\t\t\t\tif (width <= 2) return marker;\n\t\t\t\t\tconst rendered = truncateToWidth(line.trimEnd(), contentWidth, \"\");\n\t\t\t\t\treturn rendered ? `${marker} ${rendered}` : marker;\n\t\t\t\t});\n\t\t\t},\n\t\t\tinvalidate: () => content.invalidate(),\n\t\t};\n\t}\n\n\tprivate getCallRenderer(): ToolCallRenderer<any, any> | 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(): ToolResultRenderer<any, any, any> | 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(): ToolRenderShell {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\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(result: ToolExecutionDisplayResult, isPartial = false): 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\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\t\treturn super.render(width);\n\t}\n\n\tprivate renderToolCall(renderContainer: Container): boolean {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tif (!callRenderer) {\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\tthis.callRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t} catch {\n\t\t\tthis.callRendererComponent = undefined;\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate renderToolResult(renderContainer: Container): boolean {\n\t\tif (!this.result) return false;\n\t\tconst resultRenderer = this.getResultRenderer();\n\t\tif (!resultRenderer) {\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = resultRenderer(\n\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\ttheme,\n\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t);\n\t\t\tthis.resultRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tthis.resultRendererComponent = undefined;\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate renderDefinitionContent(): boolean {\n\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\trenderContainer.clear();\n\t\tconst callHasContent = this.renderToolCall(renderContainer);\n\t\tconst resultHasContent = this.renderToolResult(renderContainer);\n\t\treturn callHasContent || resultHasContent;\n\t}\n\n\tprivate renderGenericContent(): boolean {\n\t\tthis.contentText.setText(this.formatToolExecution());\n\t\treturn true;\n\t}\n\n\tprivate clearRenderedImages(): void {\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t}\n\n\tprivate renderResultImages(): void {\n\t\tif (!this.result) return;\n\t\tconst imageBlocks = this.result.content.filter((content) => content.type === \"image\");\n\t\tconst capabilities = getCapabilities();\n\t\tfor (let index = 0; index < imageBlocks.length; index++) {\n\t\t\tconst image = imageBlocks[index];\n\t\t\tif (!capabilities.images || !this.showImages || !image.data || !image.mimeType) continue;\n\t\t\tconst converted = this.convertedImages.get(index);\n\t\t\tconst imageData = converted?.data ?? image.data;\n\t\t\tconst imageMimeType = converted?.mimeType ?? image.mimeType;\n\t\t\tif (capabilities.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst imageComponent = new Image(\n\t\t\t\timageData,\n\t\t\t\timageMimeType,\n\t\t\t\t{ fallbackColor: (text: string) => theme.fg(\"toolOutput\", text) },\n\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\tthis.addChild(imageComponent);\n\t\t}\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.hideComponent = false;\n\t\tconst hasRendererDefinition = this.hasRendererDefinition();\n\t\tconst hasContent = hasRendererDefinition ? this.renderDefinitionContent() : this.renderGenericContent();\n\n\t\tthis.clearRenderedImages();\n\t\tthis.renderResultImages();\n\t\tif (hasRendererDefinition && !hasContent && this.imageComponents.length === 0) this.hideComponent = true;\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Box, Container, getCapabilities, Image, Spacer, Text } from "@greppleai/grip-tui";
1
+ import { Box, Container, getCapabilities, Image, Spacer, Text, truncateToWidth, } from "@greppleai/grip-tui";
2
2
  import { createAllToolDefinitions } from "../../../core/tools/index.js";
3
3
  import { LocalToolOperations } from "../../../core/tools/operations.js";
4
4
  import { getTextOutput as getRenderedTextOutput, } from "../../../core/tools/render-utils.js";
@@ -44,17 +44,36 @@ export class ToolExecutionComponent extends Container {
44
44
  // Always create all shell variants. contentBox is used for default renderer-based composition.
45
45
  // selfRenderContainer is used when the tool renders its own framing.
46
46
  // contentText is reserved for generic fallback rendering when no tool definition exists.
47
- this.contentBox = new Box(1, 1, (text) => theme.bg("toolPendingBg", text));
48
- this.contentText = new Text("", 1, 1, (text) => theme.bg("toolPendingBg", text));
47
+ this.contentBox = new Box(1, 1);
48
+ this.contentText = new Text("", 1, 1);
49
49
  this.selfRenderContainer = new Container();
50
50
  if (this.hasRendererDefinition()) {
51
- this.addChild(this.getRenderShell() === "self" ? this.selfRenderContainer : this.contentBox);
51
+ const shell = this.getRenderShell() === "self" ? this.selfRenderContainer : this.withStatusLine(this.contentBox);
52
+ this.addChild(shell);
52
53
  }
53
54
  else {
54
- this.addChild(this.contentText);
55
+ this.addChild(this.withStatusLine(this.contentText));
55
56
  }
56
57
  this.updateDisplay();
57
58
  }
59
+ withStatusLine(content) {
60
+ return {
61
+ render: (width) => {
62
+ if (width < 1)
63
+ return [];
64
+ const color = this.isPartial ? "muted" : this.result?.isError ? "error" : "success";
65
+ const marker = theme.bgFromFg(color, " ");
66
+ const contentWidth = Math.max(1, width - 2);
67
+ return content.render(contentWidth).map((line) => {
68
+ if (width <= 2)
69
+ return marker;
70
+ const rendered = truncateToWidth(line.trimEnd(), contentWidth, "");
71
+ return rendered ? `${marker} ${rendered}` : marker;
72
+ });
73
+ },
74
+ invalidate: () => content.invalidate(),
75
+ };
76
+ }
58
77
  getCallRenderer() {
59
78
  if (!this.builtInToolDefinition) {
60
79
  return this.toolDefinition?.renderCall;
@@ -181,13 +200,6 @@ export class ToolExecutionComponent extends Container {
181
200
  }
182
201
  return super.render(width);
183
202
  }
184
- getBackgroundFormatter() {
185
- if (this.isPartial)
186
- return (text) => theme.bg("toolPendingBg", text);
187
- if (this.result?.isError)
188
- return (text) => theme.bg("toolErrorBg", text);
189
- return (text) => theme.bg("toolSuccessBg", text);
190
- }
191
203
  renderToolCall(renderContainer) {
192
204
  const callRenderer = this.getCallRenderer();
193
205
  if (!callRenderer) {
@@ -231,17 +243,14 @@ export class ToolExecutionComponent extends Container {
231
243
  return true;
232
244
  }
233
245
  }
234
- renderDefinitionContent(backgroundFormatter) {
246
+ renderDefinitionContent() {
235
247
  const renderContainer = this.getRenderShell() === "self" ? this.selfRenderContainer : this.contentBox;
236
- if (renderContainer instanceof Box)
237
- renderContainer.setBgFn(backgroundFormatter);
238
248
  renderContainer.clear();
239
249
  const callHasContent = this.renderToolCall(renderContainer);
240
250
  const resultHasContent = this.renderToolResult(renderContainer);
241
251
  return callHasContent || resultHasContent;
242
252
  }
243
- renderGenericContent(backgroundFormatter) {
244
- this.contentText.setCustomBgFn(backgroundFormatter);
253
+ renderGenericContent() {
245
254
  this.contentText.setText(this.formatToolExecution());
246
255
  return true;
247
256
  }
@@ -276,12 +285,9 @@ export class ToolExecutionComponent extends Container {
276
285
  }
277
286
  }
278
287
  updateDisplay() {
279
- const backgroundFormatter = this.getBackgroundFormatter();
280
288
  this.hideComponent = false;
281
289
  const hasRendererDefinition = this.hasRendererDefinition();
282
- const hasContent = hasRendererDefinition
283
- ? this.renderDefinitionContent(backgroundFormatter)
284
- : this.renderGenericContent(backgroundFormatter);
290
+ const hasContent = hasRendererDefinition ? this.renderDefinitionContent() : this.renderGenericContent();
285
291
  this.clearRenderedImages();
286
292
  this.renderResultImages();
287
293
  if (hasRendererDefinition && !hasContent && this.imageComponents.length === 0)
@@ -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 \"@greppleai/grip-tui\";\nimport type {\n\tToolCallRenderer,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderShell,\n\tToolResultRenderer,\n} from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { LocalToolOperations } from \"../../../core/tools/operations.ts\";\nimport {\n\tgetTextOutput as getRenderedTextOutput,\n\ttype ToolTextOutputContent,\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}\nexport interface ToolExecutionDisplayResult {\n\tcontent: ToolTextOutputContent[];\n\tdetails?: any;\n\tisError: boolean;\n}\n\ntype ToolBackgroundFormatter = (text: string) => string;\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: 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?: ToolExecutionDisplayResult;\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = 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(new LocalToolOperations(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.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.contentText = new Text(\"\", 1, 1, (text: string) => theme.bg(\"toolPendingBg\", text));\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tthis.addChild(this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox);\n\t\t} else {\n\t\t\tthis.addChild(this.contentText);\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate getCallRenderer(): ToolCallRenderer<any, any> | 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(): ToolResultRenderer<any, any, any> | 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(): ToolRenderShell {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\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(result: ToolExecutionDisplayResult, isPartial = false): 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\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\t\treturn super.render(width);\n\t}\n\n\tprivate getBackgroundFormatter(): ToolBackgroundFormatter {\n\t\tif (this.isPartial) return (text) => theme.bg(\"toolPendingBg\", text);\n\t\tif (this.result?.isError) return (text) => theme.bg(\"toolErrorBg\", text);\n\t\treturn (text) => theme.bg(\"toolSuccessBg\", text);\n\t}\n\n\tprivate renderToolCall(renderContainer: Container): boolean {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tif (!callRenderer) {\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\tthis.callRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t} catch {\n\t\t\tthis.callRendererComponent = undefined;\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate renderToolResult(renderContainer: Container): boolean {\n\t\tif (!this.result) return false;\n\t\tconst resultRenderer = this.getResultRenderer();\n\t\tif (!resultRenderer) {\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = resultRenderer(\n\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\ttheme,\n\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t);\n\t\t\tthis.resultRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tthis.resultRendererComponent = undefined;\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate renderDefinitionContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\tif (renderContainer instanceof Box) renderContainer.setBgFn(backgroundFormatter);\n\t\trenderContainer.clear();\n\t\tconst callHasContent = this.renderToolCall(renderContainer);\n\t\tconst resultHasContent = this.renderToolResult(renderContainer);\n\t\treturn callHasContent || resultHasContent;\n\t}\n\n\tprivate renderGenericContent(backgroundFormatter: ToolBackgroundFormatter): boolean {\n\t\tthis.contentText.setCustomBgFn(backgroundFormatter);\n\t\tthis.contentText.setText(this.formatToolExecution());\n\t\treturn true;\n\t}\n\n\tprivate clearRenderedImages(): void {\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t}\n\n\tprivate renderResultImages(): void {\n\t\tif (!this.result) return;\n\t\tconst imageBlocks = this.result.content.filter((content) => content.type === \"image\");\n\t\tconst capabilities = getCapabilities();\n\t\tfor (let index = 0; index < imageBlocks.length; index++) {\n\t\t\tconst image = imageBlocks[index];\n\t\t\tif (!capabilities.images || !this.showImages || !image.data || !image.mimeType) continue;\n\t\t\tconst converted = this.convertedImages.get(index);\n\t\t\tconst imageData = converted?.data ?? image.data;\n\t\t\tconst imageMimeType = converted?.mimeType ?? image.mimeType;\n\t\t\tif (capabilities.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst imageComponent = new Image(\n\t\t\t\timageData,\n\t\t\t\timageMimeType,\n\t\t\t\t{ fallbackColor: (text: string) => theme.fg(\"toolOutput\", text) },\n\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\tthis.addChild(imageComponent);\n\t\t}\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tconst backgroundFormatter = this.getBackgroundFormatter();\n\t\tthis.hideComponent = false;\n\t\tconst hasRendererDefinition = this.hasRendererDefinition();\n\t\tconst hasContent = hasRendererDefinition\n\t\t\t? this.renderDefinitionContent(backgroundFormatter)\n\t\t\t: this.renderGenericContent(backgroundFormatter);\n\n\t\tthis.clearRenderedImages();\n\t\tthis.renderResultImages();\n\t\tif (hasRendererDefinition && !hasContent && this.imageComponents.length === 0) this.hideComponent = true;\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
1
+ {"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/tool-execution.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tBox,\n\ttype Component,\n\tContainer,\n\tgetCapabilities,\n\tImage,\n\tSpacer,\n\tText,\n\ttype TUI,\n\ttruncateToWidth,\n} from \"@greppleai/grip-tui\";\nimport type {\n\tToolCallRenderer,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderShell,\n\tToolResultRenderer,\n} from \"../../../core/extensions/types.ts\";\nimport { createAllToolDefinitions, type ToolName } from \"../../../core/tools/index.ts\";\nimport { LocalToolOperations } from \"../../../core/tools/operations.ts\";\nimport {\n\tgetTextOutput as getRenderedTextOutput,\n\ttype ToolTextOutputContent,\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}\nexport interface ToolExecutionDisplayResult {\n\tcontent: ToolTextOutputContent[];\n\tdetails?: any;\n\tisError: boolean;\n}\n\nexport class ToolExecutionComponent extends Container {\n\tprivate contentBox: Box;\n\tprivate contentText: Text;\n\tprivate selfRenderContainer: Container;\n\tprivate callRendererComponent?: Component;\n\tprivate resultRendererComponent?: Component;\n\tprivate rendererState: 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?: ToolExecutionDisplayResult;\n\tprivate convertedImages: Map<number, { data: string; mimeType: string }> = new Map();\n\tprivate hideComponent = 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(new LocalToolOperations(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.addChild(new Spacer(1));\n\n\t\t// Always create all shell variants. contentBox is used for default renderer-based composition.\n\t\t// selfRenderContainer is used when the tool renders its own framing.\n\t\t// contentText is reserved for generic fallback rendering when no tool definition exists.\n\t\tthis.contentBox = new Box(1, 1);\n\t\tthis.contentText = new Text(\"\", 1, 1);\n\t\tthis.selfRenderContainer = new Container();\n\n\t\tif (this.hasRendererDefinition()) {\n\t\t\tconst shell =\n\t\t\t\tthis.getRenderShell() === \"self\" ? this.selfRenderContainer : this.withStatusLine(this.contentBox);\n\t\t\tthis.addChild(shell);\n\t\t} else {\n\t\t\tthis.addChild(this.withStatusLine(this.contentText));\n\t\t}\n\n\t\tthis.updateDisplay();\n\t}\n\n\tprivate withStatusLine(content: Component): Component {\n\t\treturn {\n\t\t\trender: (width) => {\n\t\t\t\tif (width < 1) return [];\n\t\t\t\tconst color = this.isPartial ? \"muted\" : this.result?.isError ? \"error\" : \"success\";\n\t\t\t\tconst marker = theme.bgFromFg(color, \" \");\n\t\t\t\tconst contentWidth = Math.max(1, width - 2);\n\t\t\t\treturn content.render(contentWidth).map((line) => {\n\t\t\t\t\tif (width <= 2) return marker;\n\t\t\t\t\tconst rendered = truncateToWidth(line.trimEnd(), contentWidth, \"\");\n\t\t\t\t\treturn rendered ? `${marker} ${rendered}` : marker;\n\t\t\t\t});\n\t\t\t},\n\t\t\tinvalidate: () => content.invalidate(),\n\t\t};\n\t}\n\n\tprivate getCallRenderer(): ToolCallRenderer<any, any> | 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(): ToolResultRenderer<any, any, any> | 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(): ToolRenderShell {\n\t\tif (!this.builtInToolDefinition) {\n\t\t\treturn this.toolDefinition?.renderShell ?? \"default\";\n\t\t}\n\t\tif (!this.toolDefinition) {\n\t\t\treturn this.builtInToolDefinition.renderShell ?? \"default\";\n\t\t}\n\t\treturn this.toolDefinition.renderShell ?? this.builtInToolDefinition.renderShell ?? \"default\";\n\t}\n\n\tprivate getRenderContext(lastComponent: Component | undefined): ToolRenderContext {\n\t\treturn {\n\t\t\targs: this.args,\n\t\t\ttoolCallId: this.toolCallId,\n\t\t\tinvalidate: () => {\n\t\t\t\tthis.invalidate();\n\t\t\t\tthis.ui.requestRender();\n\t\t\t},\n\t\t\tlastComponent,\n\t\t\tstate: this.rendererState,\n\t\t\tcwd: this.cwd,\n\t\t\texecutionStarted: this.executionStarted,\n\t\t\targsComplete: this.argsComplete,\n\t\t\tisPartial: this.isPartial,\n\t\t\texpanded: this.expanded,\n\t\t\tshowImages: this.showImages,\n\t\t\tisError: this.result?.isError ?? false,\n\t\t};\n\t}\n\n\tprivate createCallFallback(): Component {\n\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(this.toolName)), 0, 0);\n\t}\n\n\tprivate createResultFallback(): Component | undefined {\n\t\tconst output = this.getTextOutput();\n\t\tif (!output) {\n\t\t\treturn undefined;\n\t\t}\n\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(result: ToolExecutionDisplayResult, isPartial = false): 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\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\t\treturn super.render(width);\n\t}\n\n\tprivate renderToolCall(renderContainer: Container): boolean {\n\t\tconst callRenderer = this.getCallRenderer();\n\t\tif (!callRenderer) {\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = callRenderer(this.args, theme, this.getRenderContext(this.callRendererComponent));\n\t\t\tthis.callRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t} catch {\n\t\t\tthis.callRendererComponent = undefined;\n\t\t\trenderContainer.addChild(this.createCallFallback());\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate renderToolResult(renderContainer: Container): boolean {\n\t\tif (!this.result) return false;\n\t\tconst resultRenderer = this.getResultRenderer();\n\t\tif (!resultRenderer) {\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t\ttry {\n\t\t\tconst component = resultRenderer(\n\t\t\t\t{ content: this.result.content as any, details: this.result.details },\n\t\t\t\t{ expanded: this.expanded, isPartial: this.isPartial },\n\t\t\t\ttheme,\n\t\t\t\tthis.getRenderContext(this.resultRendererComponent),\n\t\t\t);\n\t\t\tthis.resultRendererComponent = component;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tthis.resultRendererComponent = undefined;\n\t\t\tconst component = this.createResultFallback();\n\t\t\tif (!component) return false;\n\t\t\trenderContainer.addChild(component);\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tprivate renderDefinitionContent(): boolean {\n\t\tconst renderContainer = this.getRenderShell() === \"self\" ? this.selfRenderContainer : this.contentBox;\n\t\trenderContainer.clear();\n\t\tconst callHasContent = this.renderToolCall(renderContainer);\n\t\tconst resultHasContent = this.renderToolResult(renderContainer);\n\t\treturn callHasContent || resultHasContent;\n\t}\n\n\tprivate renderGenericContent(): boolean {\n\t\tthis.contentText.setText(this.formatToolExecution());\n\t\treturn true;\n\t}\n\n\tprivate clearRenderedImages(): void {\n\t\tfor (const image of this.imageComponents) this.removeChild(image);\n\t\tthis.imageComponents = [];\n\t\tfor (const spacer of this.imageSpacers) this.removeChild(spacer);\n\t\tthis.imageSpacers = [];\n\t}\n\n\tprivate renderResultImages(): void {\n\t\tif (!this.result) return;\n\t\tconst imageBlocks = this.result.content.filter((content) => content.type === \"image\");\n\t\tconst capabilities = getCapabilities();\n\t\tfor (let index = 0; index < imageBlocks.length; index++) {\n\t\t\tconst image = imageBlocks[index];\n\t\t\tif (!capabilities.images || !this.showImages || !image.data || !image.mimeType) continue;\n\t\t\tconst converted = this.convertedImages.get(index);\n\t\t\tconst imageData = converted?.data ?? image.data;\n\t\t\tconst imageMimeType = converted?.mimeType ?? image.mimeType;\n\t\t\tif (capabilities.images === \"kitty\" && imageMimeType !== \"image/png\") continue;\n\t\t\tconst spacer = new Spacer(1);\n\t\t\tthis.addChild(spacer);\n\t\t\tthis.imageSpacers.push(spacer);\n\t\t\tconst imageComponent = new Image(\n\t\t\t\timageData,\n\t\t\t\timageMimeType,\n\t\t\t\t{ fallbackColor: (text: string) => theme.fg(\"toolOutput\", text) },\n\t\t\t\t{ maxWidthCells: this.imageWidthCells },\n\t\t\t);\n\t\t\tthis.imageComponents.push(imageComponent);\n\t\t\tthis.addChild(imageComponent);\n\t\t}\n\t}\n\n\tprivate updateDisplay(): void {\n\t\tthis.hideComponent = false;\n\t\tconst hasRendererDefinition = this.hasRendererDefinition();\n\t\tconst hasContent = hasRendererDefinition ? this.renderDefinitionContent() : this.renderGenericContent();\n\n\t\tthis.clearRenderedImages();\n\t\tthis.renderResultImages();\n\t\tif (hasRendererDefinition && !hasContent && this.imageComponents.length === 0) this.hideComponent = true;\n\t}\n\n\tprivate getTextOutput(): string {\n\t\treturn getRenderedTextOutput(this.result, this.showImages);\n\t}\n\n\tprivate formatToolExecution(): string {\n\t\tlet text = theme.fg(\"toolTitle\", theme.bold(this.toolName));\n\t\tconst content = JSON.stringify(this.args, null, 2);\n\t\tif (content) {\n\t\t\ttext += `\\n\\n${content}`;\n\t\t}\n\t\tconst output = this.getTextOutput();\n\t\tif (output) {\n\t\t\ttext += `\\n${output}`;\n\t\t}\n\t\treturn text;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"user-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAQ7E;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,YACC,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,aAAkC,EACjD,SAAS,SAAI,EACb,oBAAoB,GAAE,SAAS,mBAAmB,EAAO,EAQzD;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,OAAO,CAAC,OAAO;IAsBN,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASvC;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@greppleai/grip-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tconstructor(\n\t\ttext: string,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new Box(this.outputPad, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpreserveOrderedListMarkers: true,\n\t\t\t\t\tpreserveBackslashEscapes: true,\n\t\t\t\t\ttransform: createMarkdownTransform(\"user\", false, this.markdownTransformers),\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"user-message.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAS7E;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IAClD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,YACC,IAAI,EAAE,MAAM,EACZ,aAAa,GAAE,aAAkC,EACjD,SAAS,SAAI,EACb,oBAAoB,GAAE,SAAS,mBAAmB,EAAO,EAQzD;IAED,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAGlC;IAED,OAAO,CAAC,OAAO;IAsBN,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASvC;CACD","sourcesContent":["import { Container, Markdown, type MarkdownTheme } from \"@greppleai/grip-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\nimport { MessageCard } from \"./message-card.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tconstructor(\n\t\ttext: string,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new MessageCard(this.outputPad, 1, \"accent\");\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpreserveOrderedListMarkers: true,\n\t\t\t\t\tpreserveBackslashEscapes: true,\n\t\t\t\t\ttransform: createMarkdownTransform(\"user\", false, this.markdownTransformers),\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
@@ -1,6 +1,7 @@
1
- import { Box, Container, Markdown } from "@greppleai/grip-tui";
1
+ import { Container, Markdown } from "@greppleai/grip-tui";
2
2
  import { getMarkdownTheme, theme } from "../theme/theme.js";
3
3
  import { createMarkdownTransform } from "./markdown-transform.js";
4
+ import { MessageCard } from "./message-card.js";
4
5
  const OSC133_ZONE_START = "\x1b]133;A\x07";
5
6
  const OSC133_ZONE_END = "\x1b]133;B\x07";
6
7
  const OSC133_ZONE_FINAL = "\x1b]133;C\x07";
@@ -26,7 +27,7 @@ export class UserMessageComponent extends Container {
26
27
  }
27
28
  rebuild() {
28
29
  this.clear();
29
- const contentBox = new Box(this.outputPad, 1, (content) => theme.bg("userMessageBg", content));
30
+ const contentBox = new MessageCard(this.outputPad, 1, "accent");
30
31
  contentBox.addChild(new Markdown(this.text, 0, 0, this.markdownTheme, {
31
32
  color: (content) => theme.fg("userMessageText", content),
32
33
  }, {
@@ -1 +1 @@
1
- {"version":3,"file":"user-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAElE,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAC1C,IAAI,CAAS;IACb,aAAa,CAAgB;IAC7B,SAAS,CAAS;IAClB,oBAAoB,CAAiC;IAC7D,YACC,IAAY,EACZ,aAAa,GAAkB,gBAAgB,EAAE,EACjD,SAAS,GAAG,CAAC,EACb,oBAAoB,GAAmC,EAAE,EACxD;QACD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;QACjD,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACf;IAED,YAAY,CAAC,OAAe,EAAQ;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACf;IAEO,OAAO,GAAS;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACvG,UAAU,CAAC,QAAQ,CAClB,IAAI,QAAQ,CACX,IAAI,CAAC,IAAI,EACT,CAAC,EACD,CAAC,EACD,IAAI,CAAC,aAAa,EAClB;YACC,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC;SAChE,EACD;YACC,0BAA0B,EAAE,IAAI;YAChC,wBAAwB,EAAE,IAAI;YAC9B,SAAS,EAAE,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC;SAC5E,CACD,CACD,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAAA,CAC1B;IAEQ,MAAM,CAAC,KAAa,EAAY;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,GAAG,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxF,OAAO,KAAK,CAAC;IAAA,CACb;CACD","sourcesContent":["import { Box, Container, Markdown, type MarkdownTheme } from \"@greppleai/grip-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tconstructor(\n\t\ttext: string,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new Box(this.outputPad, 1, (content: string) => theme.bg(\"userMessageBg\", content));\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpreserveOrderedListMarkers: true,\n\t\t\t\t\tpreserveBackslashEscapes: true,\n\t\t\t\t\ttransform: createMarkdownTransform(\"user\", false, this.markdownTransformers),\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
1
+ {"version":3,"file":"user-message.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAsB,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAC3C,MAAM,eAAe,GAAG,gBAAgB,CAAC;AACzC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IAC1C,IAAI,CAAS;IACb,aAAa,CAAgB;IAC7B,SAAS,CAAS;IAClB,oBAAoB,CAAiC;IAC7D,YACC,IAAY,EACZ,aAAa,GAAkB,gBAAgB,EAAE,EACjD,SAAS,GAAG,CAAC,EACb,oBAAoB,GAAmC,EAAE,EACxD;QACD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;QACjD,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACf;IAED,YAAY,CAAC,OAAe,EAAQ;QACnC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC;QACzB,IAAI,CAAC,OAAO,EAAE,CAAC;IAAA,CACf;IAEO,OAAO,GAAS;QACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,MAAM,UAAU,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;QAChE,UAAU,CAAC,QAAQ,CAClB,IAAI,QAAQ,CACX,IAAI,CAAC,IAAI,EACT,CAAC,EACD,CAAC,EACD,IAAI,CAAC,aAAa,EAClB;YACC,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC;SAChE,EACD;YACC,0BAA0B,EAAE,IAAI;YAChC,wBAAwB,EAAE,IAAI;YAC9B,SAAS,EAAE,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,oBAAoB,CAAC;SAC5E,CACD,CACD,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAAA,CAC1B;IAEQ,MAAM,CAAC,KAAa,EAAY;QACxC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACd,CAAC;QAED,KAAK,CAAC,CAAC,CAAC,GAAG,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACxC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,eAAe,GAAG,iBAAiB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxF,OAAO,KAAK,CAAC;IAAA,CACb;CACD","sourcesContent":["import { Container, Markdown, type MarkdownTheme } from \"@greppleai/grip-tui\";\nimport type { MarkdownTransformer } from \"../../../core/extensions/types.ts\";\nimport { getMarkdownTheme, theme } from \"../theme/theme.ts\";\nimport { createMarkdownTransform } from \"./markdown-transform.ts\";\nimport { MessageCard } from \"./message-card.ts\";\n\nconst OSC133_ZONE_START = \"\\x1b]133;A\\x07\";\nconst OSC133_ZONE_END = \"\\x1b]133;B\\x07\";\nconst OSC133_ZONE_FINAL = \"\\x1b]133;C\\x07\";\n\n/**\n * Component that renders a user message\n */\nexport class UserMessageComponent extends Container {\n\tprivate text: string;\n\tprivate markdownTheme: MarkdownTheme;\n\tprivate outputPad: number;\n\tprivate markdownTransformers: readonly MarkdownTransformer[];\n\tconstructor(\n\t\ttext: string,\n\t\tmarkdownTheme: MarkdownTheme = getMarkdownTheme(),\n\t\toutputPad = 1,\n\t\tmarkdownTransformers: readonly MarkdownTransformer[] = [],\n\t) {\n\t\tsuper();\n\t\tthis.text = text;\n\t\tthis.markdownTheme = markdownTheme;\n\t\tthis.outputPad = outputPad;\n\t\tthis.markdownTransformers = markdownTransformers;\n\t\tthis.rebuild();\n\t}\n\n\tsetOutputPad(padding: number): void {\n\t\tthis.outputPad = padding;\n\t\tthis.rebuild();\n\t}\n\n\tprivate rebuild(): void {\n\t\tthis.clear();\n\t\tconst contentBox = new MessageCard(this.outputPad, 1, \"accent\");\n\t\tcontentBox.addChild(\n\t\t\tnew Markdown(\n\t\t\t\tthis.text,\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\tthis.markdownTheme,\n\t\t\t\t{\n\t\t\t\t\tcolor: (content: string) => theme.fg(\"userMessageText\", content),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpreserveOrderedListMarkers: true,\n\t\t\t\t\tpreserveBackslashEscapes: true,\n\t\t\t\t\ttransform: createMarkdownTransform(\"user\", false, this.markdownTransformers),\n\t\t\t\t},\n\t\t\t),\n\t\t);\n\t\tthis.addChild(contentBox);\n\t}\n\n\toverride render(width: number): string[] {\n\t\tconst lines = super.render(width);\n\t\tif (lines.length === 0) {\n\t\t\treturn lines;\n\t\t}\n\n\t\tlines[0] = OSC133_ZONE_START + lines[0];\n\t\tlines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1];\n\t\treturn lines;\n\t}\n}\n"]}
@@ -109,10 +109,8 @@ export declare class InteractiveMode {
109
109
  private pendingTools;
110
110
  private toolOutputExpanded;
111
111
  private activeSandboxContainerId;
112
- private activeSandboxRuntime;
113
112
  private activeSandboxBackendConnected;
114
113
  private readonly sessionSandboxStates;
115
- private readonly managedSandboxContainers;
116
114
  private readonly managedLimaInstances;
117
115
  private hideThinkingBlock;
118
116
  private outputPad;
@@ -517,7 +515,6 @@ export declare class InteractiveMode {
517
515
  private handleHooksCommand;
518
516
  private handleNameCommand;
519
517
  private refreshUiAfterBackendChange;
520
- private createDockerSandboxService;
521
518
  private createLimaSandboxService;
522
519
  private disposeRuntimeResources;
523
520
  private restoreCurrentSessionSandbox;