@nghyane/arcane 0.1.12 → 0.1.14

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 (333) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +21 -70
  3. package/scripts/format-prompts.ts +1 -3
  4. package/src/cli/args.ts +2 -7
  5. package/src/cli/config-cli.ts +1 -1
  6. package/src/cli/plugin-cli.ts +1 -1
  7. package/src/cli/setup-cli.ts +1 -1
  8. package/src/cli/update-cli.ts +1 -1
  9. package/src/cli/web-search-cli.ts +1 -1
  10. package/src/cli.ts +0 -1
  11. package/src/commands/config.ts +1 -1
  12. package/src/commands/grep.ts +1 -1
  13. package/src/commands/jupyter.ts +1 -1
  14. package/src/commands/plugin.ts +1 -1
  15. package/src/commands/setup.ts +1 -1
  16. package/src/commands/shell.ts +1 -1
  17. package/src/commands/ssh.ts +1 -1
  18. package/src/commands/stats.ts +1 -1
  19. package/src/commands/update.ts +1 -1
  20. package/src/config/model-registry.ts +3 -4
  21. package/src/config/model-resolver.ts +36 -9
  22. package/src/config/prompt-templates.ts +1 -9
  23. package/src/config/settings-schema.ts +32 -88
  24. package/src/config/settings.ts +3 -4
  25. package/src/debug/index.ts +1 -1
  26. package/src/debug/log-formatting.ts +1 -1
  27. package/src/debug/log-viewer.ts +2 -2
  28. package/src/discovery/helpers.ts +13 -3
  29. package/src/exa/company.ts +2 -7
  30. package/src/exa/index.ts +1 -35
  31. package/src/exa/linkedin.ts +2 -7
  32. package/src/exa/mcp-client.ts +21 -11
  33. package/src/exa/render.ts +30 -190
  34. package/src/exa/researcher.ts +2 -12
  35. package/src/exa/search.ts +5 -25
  36. package/src/exa/types.ts +3 -3
  37. package/src/exec/bash-executor.ts +2 -1
  38. package/src/exec/non-interactive-env.ts +43 -0
  39. package/src/export/html/index.ts +1 -1
  40. package/src/extensibility/custom-tools/loader.ts +1 -1
  41. package/src/extensibility/custom-tools/types.ts +5 -1
  42. package/src/extensibility/custom-tools/wrapper.ts +1 -1
  43. package/src/extensibility/extensions/runner.ts +1 -1
  44. package/src/extensibility/extensions/types.ts +1 -1
  45. package/src/extensibility/extensions/wrapper.ts +7 -15
  46. package/src/extensibility/hooks/runner.ts +1 -1
  47. package/src/extensibility/hooks/types.ts +1 -1
  48. package/src/extensibility/plugins/doctor.ts +1 -1
  49. package/src/index.ts +13 -13
  50. package/src/lsp/index.ts +77 -24
  51. package/src/lsp/render.ts +34 -583
  52. package/src/lsp/types.ts +3 -3
  53. package/src/lsp/utils.ts +1 -1
  54. package/src/main.ts +1 -1
  55. package/src/mcp/tool-bridge.ts +1 -24
  56. package/src/modes/components/assistant-message.ts +7 -7
  57. package/src/modes/components/bash-execution.ts +48 -113
  58. package/src/modes/components/bordered-loader.ts +1 -1
  59. package/src/modes/components/branch-summary-message.ts +13 -10
  60. package/src/modes/components/compaction-summary-message.ts +14 -13
  61. package/src/modes/components/context-group.ts +106 -0
  62. package/src/modes/components/custom-message.ts +4 -5
  63. package/src/modes/components/diff.ts +2 -2
  64. package/src/modes/components/dynamic-border.ts +1 -1
  65. package/src/modes/components/extensions/extension-dashboard.ts +2 -2
  66. package/src/modes/components/extensions/extension-list.ts +1 -1
  67. package/src/modes/components/extensions/inspector-panel.ts +8 -3
  68. package/src/modes/components/footer.ts +2 -2
  69. package/src/modes/components/history-search.ts +1 -1
  70. package/src/modes/components/hook-editor.ts +1 -1
  71. package/src/modes/components/hook-input.ts +1 -1
  72. package/src/modes/components/hook-message.ts +4 -5
  73. package/src/modes/components/hook-selector.ts +1 -1
  74. package/src/modes/components/index.ts +0 -2
  75. package/src/modes/components/keybinding-hints.ts +1 -1
  76. package/src/modes/components/login-dialog.ts +1 -1
  77. package/src/modes/components/mcp-add-wizard.ts +1 -1
  78. package/src/modes/components/model-selector.ts +1 -1
  79. package/src/modes/components/oauth-selector.ts +1 -1
  80. package/src/modes/components/plugin-settings.ts +1 -1
  81. package/src/modes/components/python-execution.ts +49 -92
  82. package/src/modes/components/queue-mode-selector.ts +1 -1
  83. package/src/modes/components/session-selector.ts +1 -1
  84. package/src/modes/components/settings-defs.ts +5 -10
  85. package/src/modes/components/settings-selector.ts +1 -1
  86. package/src/modes/components/show-images-selector.ts +1 -1
  87. package/src/modes/components/skill-message.ts +4 -4
  88. package/src/modes/components/status-line/segments.ts +2 -2
  89. package/src/modes/components/status-line/separators.ts +1 -1
  90. package/src/modes/components/status-line-segment-editor.ts +1 -1
  91. package/src/modes/components/status-line.ts +1 -1
  92. package/src/modes/components/theme-selector.ts +1 -1
  93. package/src/modes/components/thinking-selector.ts +1 -1
  94. package/src/modes/components/todo-display.ts +2 -4
  95. package/src/modes/components/todo-reminder.ts +4 -4
  96. package/src/modes/components/tool-execution.ts +118 -440
  97. package/src/modes/components/tool-image-display.ts +107 -0
  98. package/src/modes/components/tree-selector.ts +2 -2
  99. package/src/modes/components/ttsr-notification.ts +4 -17
  100. package/src/modes/components/user-message-selector.ts +1 -1
  101. package/src/modes/components/user-message.ts +9 -10
  102. package/src/modes/components/welcome.ts +1 -1
  103. package/src/modes/controllers/command-controller.ts +1 -1
  104. package/src/modes/controllers/event-controller.ts +58 -187
  105. package/src/modes/controllers/extension-ui-controller.ts +1 -1
  106. package/src/modes/controllers/input-controller.ts +3 -1
  107. package/src/modes/controllers/mcp-command-controller.ts +1 -1
  108. package/src/modes/controllers/selector-controller.ts +3 -26
  109. package/src/modes/controllers/ssh-command-controller.ts +1 -1
  110. package/src/modes/interactive-mode.ts +3 -7
  111. package/src/modes/print-mode.ts +5 -5
  112. package/src/modes/rpc/rpc-mode.ts +1 -1
  113. package/src/modes/types.ts +1 -2
  114. package/src/modes/utils/ui-helpers.ts +34 -32
  115. package/src/patch/edit-tool.ts +742 -0
  116. package/src/patch/index.ts +32 -898
  117. package/src/patch/schemas.ts +208 -0
  118. package/src/patch/shared.ts +83 -151
  119. package/src/prompts/agents/explore.md +22 -37
  120. package/src/prompts/agents/frontmatter.md +1 -1
  121. package/src/prompts/agents/init.md +2 -2
  122. package/src/prompts/agents/librarian.md +30 -21
  123. package/src/prompts/agents/oracle.md +9 -2
  124. package/src/prompts/agents/reviewer.md +15 -49
  125. package/src/prompts/agents/task.md +17 -9
  126. package/src/prompts/compaction/branch-summary-context.md +1 -1
  127. package/src/prompts/compaction/branch-summary-preamble.md +1 -1
  128. package/src/prompts/compaction/branch-summary.md +4 -1
  129. package/src/prompts/compaction/compaction-short-summary.md +1 -1
  130. package/src/prompts/compaction/compaction-summary-context.md +1 -1
  131. package/src/prompts/compaction/compaction-summary.md +4 -1
  132. package/src/prompts/compaction/compaction-turn-prefix.md +1 -1
  133. package/src/prompts/compaction/compaction-update-summary.md +1 -1
  134. package/src/prompts/memories/consolidation.md +1 -1
  135. package/src/prompts/memories/read_path.md +1 -1
  136. package/src/prompts/memories/stage_one_input.md +1 -1
  137. package/src/prompts/memories/stage_one_system.md +1 -1
  138. package/src/prompts/review-request.md +1 -1
  139. package/src/prompts/system/agent-creation-architect.md +1 -1
  140. package/src/prompts/system/agent-creation-user.md +1 -1
  141. package/src/prompts/system/custom-system-prompt.md +1 -1
  142. package/src/prompts/system/file-operations.md +1 -1
  143. package/src/prompts/system/subagent-system-prompt.md +2 -2
  144. package/src/prompts/system/summarization-system.md +1 -1
  145. package/src/prompts/system/system-prompt.md +163 -178
  146. package/src/prompts/system/title-system.md +1 -1
  147. package/src/prompts/system/ttsr-interrupt.md +1 -1
  148. package/src/prompts/system/verification-reminder.md +6 -0
  149. package/src/prompts/system/web-search.md +1 -1
  150. package/src/sdk.ts +0 -9
  151. package/src/session/agent-session.ts +244 -1459
  152. package/src/session/auth-storage.ts +5 -0
  153. package/src/session/model-controller.ts +406 -0
  154. package/src/session/retry-utils.ts +71 -0
  155. package/src/session/session-manager.ts +22 -186
  156. package/src/session/session-types.ts +312 -0
  157. package/src/session/stats.ts +387 -0
  158. package/src/session/streaming-edit.ts +258 -0
  159. package/src/session/ttsr.ts +213 -0
  160. package/src/slash-commands/builtin-registry.ts +0 -8
  161. package/src/ssh/connection-manager.ts +1 -0
  162. package/src/stt/recorder.ts +2 -2
  163. package/src/system-prompt.ts +1 -14
  164. package/src/task/agents.ts +7 -33
  165. package/src/task/executor.ts +50 -438
  166. package/src/task/index.ts +104 -71
  167. package/src/task/progress-tracker.ts +390 -0
  168. package/src/task/render.ts +371 -187
  169. package/src/task/subprocess-tool-registry.ts +1 -1
  170. package/src/task/types.ts +14 -47
  171. package/src/tools/ask.ts +31 -42
  172. package/src/tools/bash-interactive.ts +4 -47
  173. package/src/tools/bash-interceptor.ts +2 -2
  174. package/src/tools/bash-normalize.ts +1 -1
  175. package/src/tools/bash-skill-urls.ts +2 -2
  176. package/src/tools/bash.ts +87 -136
  177. package/src/tools/browser.ts +54 -84
  178. package/src/tools/create-tools.ts +186 -0
  179. package/src/tools/default-renderer.ts +104 -0
  180. package/src/tools/explore.ts +11 -10
  181. package/src/tools/fetch.ts +24 -114
  182. package/src/tools/find.ts +48 -132
  183. package/src/tools/gemini-image.ts +5 -15
  184. package/src/tools/github.ts +450 -0
  185. package/src/tools/grep.ts +43 -179
  186. package/src/tools/index.ts +35 -198
  187. package/src/tools/json-tree.ts +3 -3
  188. package/src/tools/librarian.ts +18 -18
  189. package/src/tools/list-limit.ts +2 -2
  190. package/src/tools/notebook.ts +35 -87
  191. package/src/tools/oracle.ts +25 -25
  192. package/src/tools/output-meta.ts +89 -4
  193. package/src/tools/output-utils.ts +2 -2
  194. package/src/tools/python.ts +86 -637
  195. package/src/tools/read.ts +36 -119
  196. package/src/tools/reviewer-tool.ts +19 -21
  197. package/src/tools/search-code.ts +128 -0
  198. package/src/tools/ssh.ts +67 -126
  199. package/src/tools/subagent-tool.ts +197 -123
  200. package/src/tools/todo-write.ts +15 -31
  201. package/src/tools/tool-errors.ts +0 -30
  202. package/src/tools/undo-edit.ts +30 -67
  203. package/src/tools/write.ts +78 -127
  204. package/src/tui/code-cell.ts +4 -4
  205. package/src/tui/file-list.ts +2 -2
  206. package/src/tui/output-block.ts +1 -1
  207. package/src/tui/status-line.ts +1 -1
  208. package/src/tui/tree-list.ts +2 -2
  209. package/src/tui/types.ts +1 -1
  210. package/src/tui/utils.ts +1 -1
  211. package/src/{tools → ui}/render-utils.ts +87 -126
  212. package/src/utils/external-editor.ts +4 -4
  213. package/src/utils/file-mentions.ts +1 -1
  214. package/src/utils/index.ts +30 -0
  215. package/src/utils/tools-manager.ts +9 -19
  216. package/src/web/github-client.ts +290 -0
  217. package/src/web/scrapers/github.ts +11 -62
  218. package/src/web/search/auth.ts +1 -3
  219. package/src/web/search/index.ts +85 -49
  220. package/src/web/search/provider.ts +11 -16
  221. package/src/web/search/providers/grep.ts +160 -0
  222. package/src/web/search/render.ts +48 -235
  223. package/src/web/search/types.ts +1 -1
  224. package/src/commands/commit.ts +0 -36
  225. package/src/commit/agentic/agent.ts +0 -311
  226. package/src/commit/agentic/fallback.ts +0 -96
  227. package/src/commit/agentic/index.ts +0 -359
  228. package/src/commit/agentic/prompts/analyze-file.md +0 -22
  229. package/src/commit/agentic/prompts/session-user.md +0 -25
  230. package/src/commit/agentic/prompts/split-confirm.md +0 -1
  231. package/src/commit/agentic/prompts/system.md +0 -38
  232. package/src/commit/agentic/state.ts +0 -69
  233. package/src/commit/agentic/tools/analyze-file.ts +0 -118
  234. package/src/commit/agentic/tools/git-file-diff.ts +0 -194
  235. package/src/commit/agentic/tools/git-hunk.ts +0 -50
  236. package/src/commit/agentic/tools/git-overview.ts +0 -84
  237. package/src/commit/agentic/tools/index.ts +0 -56
  238. package/src/commit/agentic/tools/propose-changelog.ts +0 -128
  239. package/src/commit/agentic/tools/propose-commit.ts +0 -154
  240. package/src/commit/agentic/tools/recent-commits.ts +0 -81
  241. package/src/commit/agentic/tools/split-commit.ts +0 -280
  242. package/src/commit/agentic/topo-sort.ts +0 -44
  243. package/src/commit/agentic/trivial.ts +0 -51
  244. package/src/commit/agentic/validation.ts +0 -200
  245. package/src/commit/analysis/conventional.ts +0 -165
  246. package/src/commit/analysis/index.ts +0 -4
  247. package/src/commit/analysis/scope.ts +0 -242
  248. package/src/commit/analysis/summary.ts +0 -112
  249. package/src/commit/analysis/validation.ts +0 -66
  250. package/src/commit/changelog/detect.ts +0 -37
  251. package/src/commit/changelog/generate.ts +0 -110
  252. package/src/commit/changelog/index.ts +0 -234
  253. package/src/commit/changelog/parse.ts +0 -44
  254. package/src/commit/cli.ts +0 -93
  255. package/src/commit/git/diff.ts +0 -148
  256. package/src/commit/git/errors.ts +0 -9
  257. package/src/commit/git/index.ts +0 -211
  258. package/src/commit/git/operations.ts +0 -54
  259. package/src/commit/index.ts +0 -5
  260. package/src/commit/map-reduce/index.ts +0 -64
  261. package/src/commit/map-reduce/map-phase.ts +0 -178
  262. package/src/commit/map-reduce/reduce-phase.ts +0 -145
  263. package/src/commit/map-reduce/utils.ts +0 -9
  264. package/src/commit/message.ts +0 -11
  265. package/src/commit/model-selection.ts +0 -69
  266. package/src/commit/pipeline.ts +0 -243
  267. package/src/commit/prompts/analysis-system.md +0 -148
  268. package/src/commit/prompts/analysis-user.md +0 -38
  269. package/src/commit/prompts/changelog-system.md +0 -50
  270. package/src/commit/prompts/changelog-user.md +0 -18
  271. package/src/commit/prompts/file-observer-system.md +0 -24
  272. package/src/commit/prompts/file-observer-user.md +0 -8
  273. package/src/commit/prompts/reduce-system.md +0 -50
  274. package/src/commit/prompts/reduce-user.md +0 -17
  275. package/src/commit/prompts/summary-retry.md +0 -3
  276. package/src/commit/prompts/summary-system.md +0 -38
  277. package/src/commit/prompts/summary-user.md +0 -13
  278. package/src/commit/prompts/types-description.md +0 -2
  279. package/src/commit/types.ts +0 -109
  280. package/src/commit/utils/exclusions.ts +0 -42
  281. package/src/mcp/render.ts +0 -123
  282. package/src/modes/components/agent-dashboard.ts +0 -1130
  283. package/src/modes/components/codemode-group.ts +0 -369
  284. package/src/modes/components/read-tool-group.ts +0 -119
  285. package/src/modes/components/visual-truncate.ts +0 -63
  286. package/src/prompts/system/subagent-user-prompt.md +0 -8
  287. package/src/prompts/tools/ask.md +0 -44
  288. package/src/prompts/tools/bash.md +0 -24
  289. package/src/prompts/tools/browser.md +0 -33
  290. package/src/prompts/tools/calculator.md +0 -12
  291. package/src/prompts/tools/explore.md +0 -29
  292. package/src/prompts/tools/fetch.md +0 -16
  293. package/src/prompts/tools/find.md +0 -18
  294. package/src/prompts/tools/gemini-image.md +0 -23
  295. package/src/prompts/tools/grep.md +0 -28
  296. package/src/prompts/tools/hashline.md +0 -232
  297. package/src/prompts/tools/librarian.md +0 -24
  298. package/src/prompts/tools/lsp.md +0 -28
  299. package/src/prompts/tools/oracle.md +0 -26
  300. package/src/prompts/tools/patch.md +0 -74
  301. package/src/prompts/tools/python.md +0 -66
  302. package/src/prompts/tools/read.md +0 -36
  303. package/src/prompts/tools/replace.md +0 -38
  304. package/src/prompts/tools/reviewer.md +0 -41
  305. package/src/prompts/tools/ssh.md +0 -51
  306. package/src/prompts/tools/task-summary.md +0 -28
  307. package/src/prompts/tools/task.md +0 -146
  308. package/src/prompts/tools/todo-write.md +0 -65
  309. package/src/prompts/tools/undo-edit.md +0 -7
  310. package/src/prompts/tools/web-search.md +0 -19
  311. package/src/prompts/tools/write.md +0 -18
  312. package/src/task/batch.ts +0 -102
  313. package/src/task/discovery.ts +0 -126
  314. package/src/task/parallel.ts +0 -84
  315. package/src/task/template.ts +0 -32
  316. package/src/tools/calculator.ts +0 -537
  317. package/src/tools/jtd-to-typescript.ts +0 -198
  318. package/src/tools/renderers.ts +0 -60
  319. package/src/tools/tool-result.ts +0 -86
  320. /package/src/{modes/theme → theme}/dark.json +0 -0
  321. /package/src/{modes/theme → theme}/defaults/dark-catppuccin.json +0 -0
  322. /package/src/{modes/theme → theme}/defaults/dark-dracula.json +0 -0
  323. /package/src/{modes/theme → theme}/defaults/dark-gruvbox.json +0 -0
  324. /package/src/{modes/theme → theme}/defaults/dark-solarized.json +0 -0
  325. /package/src/{modes/theme → theme}/defaults/dark-tokyo-night.json +0 -0
  326. /package/src/{modes/theme → theme}/defaults/index.ts +0 -0
  327. /package/src/{modes/theme → theme}/defaults/light-catppuccin.json +0 -0
  328. /package/src/{modes/theme → theme}/defaults/light-github.json +0 -0
  329. /package/src/{modes/theme → theme}/defaults/light-solarized.json +0 -0
  330. /package/src/{modes/theme → theme}/light.json +0 -0
  331. /package/src/{modes/theme → theme}/mermaid-cache.ts +0 -0
  332. /package/src/{modes/theme → theme}/theme-schema.json +0 -0
  333. /package/src/{modes/theme → theme}/theme.ts +0 -0
@@ -7,7 +7,7 @@
7
7
  * - Provide custom rendering for realtime/final display
8
8
  */
9
9
  import type { Component } from "@nghyane/arcane-tui";
10
- import type { Theme } from "../modes/theme/theme";
10
+ import type { Theme } from "../theme/theme";
11
11
 
12
12
  /** Event from subprocess tool execution (parsed from JSONL) */
13
13
  export interface SubprocessToolEvent {
package/src/task/types.ts CHANGED
@@ -1,58 +1,30 @@
1
1
  import type { ThinkingLevel } from "@nghyane/arcane-agent";
2
2
  import type { Usage } from "@nghyane/arcane-ai";
3
- import { $env } from "@nghyane/arcane-utils";
4
3
  import { type Static, Type } from "@sinclair/typebox";
5
4
 
6
5
  /** Source of an agent definition */
7
6
  export type AgentSource = "bundled" | "user" | "project";
8
7
 
9
- const parseNumber = (value: string | undefined, defaultValue: number): number => {
10
- if (!value) return defaultValue;
11
- const number = Number.parseInt(value, 10);
12
- return Number.isNaN(number) || number <= 0 ? defaultValue : number;
13
- };
14
-
15
- /** Maximum output bytes per agent */
16
- export const MAX_OUTPUT_BYTES = parseNumber($env.ARCANE_TASK_MAX_OUTPUT_BYTES, 500_000);
17
-
18
- /** Maximum output lines per agent */
19
- export const MAX_OUTPUT_LINES = parseNumber($env.ARCANE_TASK_MAX_OUTPUT_LINES, 5000);
8
+ /** Discriminant for agent capability profile */
9
+ export type AgentKind = "local" | "remote" | "hybrid" | "reasoning";
20
10
 
21
11
  /** EventBus channel for raw subagent events */
22
12
  export const TASK_SUBAGENT_EVENT_CHANNEL = "task:subagent:event";
23
13
 
24
- /** EventBus channel for aggregated subagent progress */
25
- export const TASK_SUBAGENT_PROGRESS_CHANNEL = "task:subagent:progress";
26
-
27
- /** Single task item for execution */
28
- export interface TaskItem {
29
- id: string;
30
- description: string;
31
- assignment: string;
32
- skills?: string[];
33
- }
34
-
35
- /** Task schema — single task with optional context */
14
+ /** Task schema simplified prompt + description */
36
15
  export const taskSchema = Type.Object({
37
- id: Type.String({
38
- description: "CamelCase identifier, max 32 chars",
39
- maxLength: 32,
16
+ prompt: Type.String({
17
+ description:
18
+ "The task for the agent to perform. Be specific about what needs to be done and include any relevant context.",
40
19
  }),
41
20
  description: Type.String({
42
- description: "Short one-liner for UI display only \u2014 not seen by the subagent",
43
- }),
44
- assignment: Type.String({
45
- description:
46
- "Complete instructions the subagent executes. Include target files, change description, edge cases, and acceptance criteria.",
21
+ description: "A very short description of the task that can be displayed to the user.",
47
22
  }),
48
- context: Type.Optional(
49
- Type.String({
50
- description: "Optional shared background prepended to the assignment.",
51
- }),
52
- ),
53
- skills: Type.Optional(
54
- Type.Array(Type.String(), {
55
- description: "Skill names to preload into the subagent.",
23
+ complexity: Type.Optional(
24
+ Type.Union([Type.Literal("low"), Type.Literal("high")], {
25
+ description:
26
+ "Task complexity. 'low' for mechanical/rote changes (rename, add import, update config). 'high' for changes requiring reasoning (refactors, bug fixes, new features). Default: high.",
27
+ default: "high",
56
28
  }),
57
29
  ),
58
30
  });
@@ -62,10 +34,11 @@ export type TaskParams = Static<TaskSchema>;
62
34
 
63
35
  /** Agent definition (bundled or discovered) */
64
36
  export interface AgentDefinition {
37
+ kind: AgentKind;
65
38
  name: string;
66
39
  description: string;
67
40
  systemPrompt: string;
68
- tools?: string[];
41
+ tools: string[];
69
42
  model?: string[];
70
43
  thinkingLevel?: ThinkingLevel;
71
44
  source: AgentSource;
@@ -104,19 +77,13 @@ export interface SingleResult {
104
77
  description?: string;
105
78
  lastIntent?: string;
106
79
  exitCode: number;
107
- output: string;
108
80
  stderr: string;
109
- truncated: boolean;
110
81
  durationMs: number;
111
82
  tokens: number;
112
83
  error?: string;
113
84
  aborted?: boolean;
114
85
  /** Aggregated usage from the subprocess, accumulated incrementally from message_end events. */
115
86
  usage?: Usage;
116
- /** Output path for the task result */
117
- outputPath?: string;
118
- /** Output metadata for agent:// URL integration */
119
- outputMeta?: { lineCount: number; charCount: number };
120
87
  /** Full history of tool calls for nested display */
121
88
  toolHistory?: Array<{ tool: string; args: string; status: "success" | "error" }>;
122
89
  }
package/src/tools/ask.ts CHANGED
@@ -18,38 +18,36 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
18
18
  import type { Component } from "@nghyane/arcane-tui";
19
19
  import { TERMINAL, Text } from "@nghyane/arcane-tui";
20
20
  import { type Static, Type } from "@sinclair/typebox";
21
- import { renderPromptTemplate } from "../config/prompt-templates";
22
21
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
23
- import { type Theme, theme } from "../modes/theme/theme";
24
- import askDescription from "../prompts/tools/ask.md" with { type: "text" };
22
+ import { type Theme, theme } from "../theme/theme";
25
23
  import { renderStatusLine } from "../tui";
24
+ import { formatErrorMessage } from "../ui/render-utils";
26
25
  import type { ToolSession } from ".";
27
- import { ToolUIKit } from "./render-utils";
28
26
 
29
27
  // =============================================================================
30
28
  // Types
31
29
  // =============================================================================
32
30
 
33
31
  const OptionItem = Type.Object({
34
- label: Type.String({ description: "Display label" }),
32
+ label: Type.String({ description: "Display text for the option" }),
35
33
  });
36
34
 
37
35
  const QuestionItem = Type.Object({
38
- id: Type.String({ description: "Question ID, e.g. 'auth', 'cache'" }),
39
- question: Type.String({ description: "Question text" }),
40
- options: Type.Array(OptionItem, { description: "Available options" }),
36
+ id: Type.String({ description: "Unique question identifier" }),
37
+ question: Type.String({ description: "Question text to display" }),
38
+ options: Type.Array(OptionItem),
41
39
  multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections" })),
42
- recommended: Type.Optional(Type.Number({ description: "Index of recommended option (0-indexed)" })),
40
+ recommended: Type.Optional(Type.Number({ description: "Index of the recommended option" })),
43
41
  });
44
42
 
45
43
  const askSchema = Type.Object({
46
- questions: Type.Array(QuestionItem, { description: "Questions to ask", minItems: 1 }),
44
+ questions: Type.Array(QuestionItem, { minItems: 1 }),
47
45
  });
48
46
 
49
- export type AskToolInput = Static<typeof askSchema>;
47
+ type AskToolInput = Static<typeof askSchema>;
50
48
 
51
49
  /** Result for a single question */
52
- export interface QuestionResult {
50
+ interface QuestionResult {
53
51
  id: string;
54
52
  question: string;
55
53
  options: string[];
@@ -243,15 +241,13 @@ type AskParams = AskToolInput;
243
241
  * Allows gathering user preferences, clarifying instructions, and getting decisions
244
242
  * on implementation choices as the agent works.
245
243
  */
246
- export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
244
+ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails, Theme> {
247
245
  readonly name = "ask";
248
246
  readonly label = "Ask";
249
- readonly description: string;
247
+ description = "Ask the user a question when genuinely blocked";
250
248
  readonly parameters = askSchema;
251
249
 
252
- constructor(private readonly session: ToolSession) {
253
- this.description = renderPromptTemplate(askDescription);
254
- }
250
+ constructor(private readonly session: ToolSession) {}
255
251
 
256
252
  static createIf(session: ToolSession): AskTool | null {
257
253
  return session.hasUI ? new AskTool(session) : null;
@@ -358,28 +354,9 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
358
354
 
359
355
  return { content: [{ type: "text" as const, text: responseText }], details };
360
356
  }
361
- }
362
-
363
- // =============================================================================
364
- // TUI Renderer
365
- // =============================================================================
366
-
367
- interface AskRenderArgs {
368
- question?: string;
369
- options?: Array<{ label: string }>;
370
- multi?: boolean;
371
- questions?: Array<{
372
- id: string;
373
- question: string;
374
- options: Array<{ label: string }>;
375
- multi?: boolean;
376
- }>;
377
- }
378
357
 
379
- export const askToolRenderer = {
380
358
  renderCall(args: AskRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
381
- const ui = new ToolUIKit(uiTheme);
382
- const label = ui.title("Ask");
359
+ const label = uiTheme.fg("toolTitle", uiTheme.bold("Ask"));
383
360
 
384
361
  // Multi-part questions
385
362
  if (args.questions && args.questions.length > 0) {
@@ -414,14 +391,14 @@ export const askToolRenderer = {
414
391
 
415
392
  // Single question
416
393
  if (!args.question) {
417
- return new Text(ui.errorMessage("No question provided"), 0, 0);
394
+ return new Text(formatErrorMessage("No question provided", uiTheme), 0, 0);
418
395
  }
419
396
 
420
397
  let text = `${label} ${uiTheme.fg("accent", args.question)}`;
421
398
  const meta: string[] = [];
422
399
  if (args.multi) meta.push("multi");
423
400
  if (args.options?.length) meta.push(`options:${args.options.length}`);
424
- text += ui.meta(meta);
401
+ text += meta.length > 0 ? ` ${uiTheme.fg("muted", meta.join(uiTheme.sep.dot))}` : "";
425
402
 
426
403
  if (args.options?.length) {
427
404
  for (let i = 0; i < args.options.length; i++) {
@@ -433,7 +410,7 @@ export const askToolRenderer = {
433
410
  }
434
411
 
435
412
  return new Text(text, 0, 0);
436
- },
413
+ }
437
414
 
438
415
  renderResult(
439
416
  result: { content: Array<{ type: string; text?: string }>; details?: AskToolDetails },
@@ -519,5 +496,17 @@ export const askToolRenderer = {
519
496
  }
520
497
 
521
498
  return new Text(text, 0, 0);
522
- },
523
- };
499
+ }
500
+ }
501
+
502
+ interface AskRenderArgs {
503
+ question?: string;
504
+ options?: Array<{ label: string }>;
505
+ multi?: boolean;
506
+ questions?: Array<{
507
+ id: string;
508
+ question: string;
509
+ options: Array<{ label: string }>;
510
+ multi?: boolean;
511
+ }>;
512
+ }
@@ -11,10 +11,11 @@ import {
11
11
  } from "@nghyane/arcane-tui";
12
12
  import type { Terminal as XtermTerminalType } from "@xterm/headless";
13
13
  import xterm from "@xterm/headless";
14
- import type { Theme } from "../modes/theme/theme";
14
+ import { NON_INTERACTIVE_ENV } from "../exec/non-interactive-env";
15
15
  import { OutputSink, type OutputSummary } from "../session/streaming-output";
16
+ import type { Theme } from "../theme/theme";
16
17
  import { getStateIcon } from "../tui";
17
- import { replaceTabs } from "./render-utils";
18
+ import { replaceTabs } from "../ui/render-utils";
18
19
 
19
20
  export interface BashInteractiveResult extends OutputSummary {
20
21
  exitCode: number | undefined;
@@ -276,50 +277,6 @@ class BashInteractiveOverlayComponent implements Component {
276
277
  }
277
278
  }
278
279
 
279
- const NO_PAGER_ENV = {
280
- // Disable pagers so commands don't block on interactive views.
281
- PAGER: "cat",
282
- GIT_PAGER: "cat",
283
- MANPAGER: "cat",
284
- SYSTEMD_PAGER: "cat",
285
- BAT_PAGER: "cat",
286
- DELTA_PAGER: "cat",
287
- GH_PAGER: "cat",
288
- GLAB_PAGER: "cat",
289
- PSQL_PAGER: "cat",
290
- MYSQL_PAGER: "cat",
291
- AWS_PAGER: "",
292
- HOMEBREW_PAGER: "cat",
293
- LESS: "FRX",
294
- // Disable editor and terminal credential prompts.
295
- GIT_EDITOR: "true",
296
- VISUAL: "true",
297
- EDITOR: "true",
298
- GIT_TERMINAL_PROMPT: "0",
299
- SSH_ASKPASS: "/usr/bin/false",
300
- CI: "1",
301
- // Package manager defaults for unattended execution.
302
- npm_config_yes: "true",
303
- npm_config_update_notifier: "false",
304
- npm_config_fund: "false",
305
- npm_config_audit: "false",
306
- npm_config_progress: "false",
307
- PNPM_DISABLE_SELF_UPDATE_CHECK: "true",
308
- PNPM_UPDATE_NOTIFIER: "false",
309
- YARN_ENABLE_TELEMETRY: "0",
310
- YARN_ENABLE_PROGRESS_BARS: "0",
311
- // Cross-language/tooling non-interactive defaults.
312
- CARGO_TERM_PROGRESS_WHEN: "never",
313
- DEBIAN_FRONTEND: "noninteractive",
314
- PIP_NO_INPUT: "1",
315
- PIP_DISABLE_PIP_VERSION_CHECK: "1",
316
- TF_INPUT: "0",
317
- TF_IN_AUTOMATION: "1",
318
- GH_PROMPT_DISABLED: "1",
319
- COMPOSER_NO_INTERACTION: "1",
320
- CLOUDSDK_CORE_DISABLE_PROMPTS: "1",
321
- };
322
-
323
280
  export async function runInteractiveBashPty(
324
281
  ui: NonNullable<AgentToolContext["ui"]>,
325
282
  options: {
@@ -389,8 +346,8 @@ export async function runInteractiveBashPty(
389
346
  cwd: options.cwd,
390
347
  timeoutMs: options.timeoutMs,
391
348
  env: {
349
+ ...NON_INTERACTIVE_ENV,
392
350
  ...options.env,
393
- ...NO_PAGER_ENV,
394
351
  },
395
352
  signal: options.signal,
396
353
  cols,
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import type { BashInterceptorRule } from "../config/settings-schema";
9
9
 
10
- export const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
10
+ const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
11
11
  {
12
12
  pattern: "^\\s*(cat|head|tail|less|more)\\s+",
13
13
  tool: "read",
@@ -45,7 +45,7 @@ export const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
45
45
  },
46
46
  ];
47
47
 
48
- export interface InterceptionResult {
48
+ interface InterceptionResult {
49
49
  /** If true, the bash command should be blocked */
50
50
  block: boolean;
51
51
  /** Error message to return instead of executing */
@@ -6,7 +6,7 @@
6
6
  * - `| tail -n N` / `| tail -N` - extracted to tailLines
7
7
  */
8
8
 
9
- export interface NormalizedCommand {
9
+ interface NormalizedCommand {
10
10
  /** Cleaned command with patterns stripped */
11
11
  command: string;
12
12
  /** Extracted head line count, if any */
@@ -20,7 +20,7 @@ interface InternalUrlResolver {
20
20
  resolve(input: string): Promise<InternalResource>;
21
21
  }
22
22
 
23
- export interface InternalUrlExpansionOptions {
23
+ interface InternalUrlExpansionOptions {
24
24
  skills: readonly Skill[];
25
25
  internalRouter?: InternalUrlResolver;
26
26
  }
@@ -29,7 +29,7 @@ export interface InternalUrlExpansionOptions {
29
29
  * Resolve a single skill:// URL to its absolute filesystem path.
30
30
  * Does NOT read file content or verify existence.
31
31
  */
32
- export function resolveSkillUrlToPath(url: string, skills: readonly Skill[]): string {
32
+ function resolveSkillUrlToPath(url: string, skills: readonly Skill[]): string {
33
33
  const parsed = /^skill:\/\/([^/?#]+)(\/[^?#]*)?(?:[?#].*)?$/.exec(url);
34
34
  if (!parsed) {
35
35
  throw new ToolError(`Invalid skill:// URL: ${url}`);
package/src/tools/bash.ts CHANGED
@@ -6,35 +6,30 @@ import { Text } from "@nghyane/arcane-tui";
6
6
  import { $env, isEnoent } from "@nghyane/arcane-utils";
7
7
  import { getProjectDir } from "@nghyane/arcane-utils/dirs";
8
8
  import { type Static, Type } from "@sinclair/typebox";
9
- import { renderPromptTemplate } from "../config/prompt-templates";
10
9
  import { type BashResult, executeBash } from "../exec/bash-executor";
11
10
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
12
- import { truncateToVisualLines } from "../modes/components/visual-truncate";
13
- import type { Theme } from "../modes/theme/theme";
14
- import bashDescription from "../prompts/tools/bash.md" with { type: "text" };
15
11
  import { DEFAULT_MAX_BYTES } from "../session/streaming-output";
12
+ import type { Theme } from "../theme/theme";
16
13
  import { renderStatusLine } from "../tui";
17
- import { CachedOutputBlock } from "../tui/output-block";
14
+ import { formatClickHint, PREVIEW_LIMITS, replaceTabs } from "../ui/render-utils";
18
15
  import type { ToolSession } from ".";
19
16
  import { type BashInteractiveResult, runInteractiveBashPty } from "./bash-interactive";
20
17
  import { checkBashInterception } from "./bash-interceptor";
21
18
  import { applyHeadTail } from "./bash-normalize";
22
19
  import { expandInternalUrls } from "./bash-skill-urls";
23
- import type { OutputMeta } from "./output-meta";
20
+ import { type OutputMeta, toolResult } from "./output-meta";
24
21
  import { allocateOutputArtifact, createTailBuffer } from "./output-utils";
25
22
  import { resolveToCwd } from "./path-utils";
26
- import { formatBytes, replaceTabs, wrapBrackets } from "./render-utils";
27
23
  import { ToolAbortError, ToolError } from "./tool-errors";
28
- import { toolResult } from "./tool-result";
29
24
 
30
25
  export const BASH_DEFAULT_PREVIEW_LINES = 10;
31
26
 
32
27
  const bashSchema = Type.Object({
33
- command: Type.String({ description: "Command to execute" }),
34
- timeout: Type.Optional(Type.Number({ description: "Timeout in seconds (default: 300)" })),
35
- cwd: Type.Optional(Type.String({ description: "Working directory (default: cwd)" })),
36
- head: Type.Optional(Type.Number({ description: "Return only first N lines of output" })),
37
- tail: Type.Optional(Type.Number({ description: "Return only last N lines of output" })),
28
+ command: Type.String({ description: "Shell command to execute" }),
29
+ timeout: Type.Optional(Type.Number({ description: "Timeout in milliseconds" })),
30
+ cwd: Type.Optional(Type.String({ description: "Working directory" })),
31
+ head: Type.Optional(Type.Number({ description: "Return only the first N lines of output" })),
32
+ tail: Type.Optional(Type.Number({ description: "Return only the last N lines of output" })),
38
33
  });
39
34
 
40
35
  export type BashToolInput = Static<typeof bashSchema>;
@@ -57,16 +52,14 @@ function isInteractiveResult(result: BashResult | BashInteractiveResult): result
57
52
  *
58
53
  * Executes bash commands with optional timeout and working directory.
59
54
  */
60
- export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails> {
55
+ export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails, Theme> {
61
56
  readonly name = "bash";
62
57
  readonly label = "Bash";
63
- readonly description: string;
58
+ description = "Execute a shell command";
64
59
  readonly parameters = bashSchema;
65
60
  readonly concurrency = "exclusive";
66
61
 
67
- constructor(private readonly session: ToolSession) {
68
- this.description = renderPromptTemplate(bashDescription);
69
- }
62
+ constructor(private readonly session: ToolSession) {}
70
63
 
71
64
  async execute(
72
65
  _toolCallId: string,
@@ -183,11 +176,83 @@ export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails> {
183
176
 
184
177
  return resultBuilder.done();
185
178
  }
186
- }
187
179
 
188
- // =============================================================================
189
- // TUI Renderer
190
- // =============================================================================
180
+ buildRenderContext(info: {
181
+ args: BashToolInput;
182
+ result?: AgentToolResult<BashToolDetails>;
183
+ expanded: boolean;
184
+ getTextOutput: () => string;
185
+ }): Record<string, unknown> {
186
+ const context: Record<string, unknown> = {};
187
+ if (info.result) {
188
+ context.output = info.getTextOutput().trimEnd();
189
+ context.expanded = info.expanded;
190
+ context.previewLines = BASH_DEFAULT_PREVIEW_LINES;
191
+ if (typeof info.args.timeout === "number" && Number.isFinite(info.args.timeout)) {
192
+ context.timeout = Math.max(1, Math.min(3600, info.args.timeout));
193
+ }
194
+ }
195
+ return context;
196
+ }
197
+
198
+ renderCall(args: BashRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
199
+ const cmdText = formatBashCommand(args, uiTheme);
200
+ const text = renderStatusLine({ icon: "pending", title: "Bash", description: cmdText }, uiTheme);
201
+ return new Text(text, 0, 0);
202
+ }
203
+
204
+ renderResult(
205
+ result: {
206
+ content: Array<{ type: string; text?: string }>;
207
+ details?: BashToolDetails;
208
+ isError?: boolean;
209
+ },
210
+ options: RenderResultOptions & { renderContext?: BashRenderContext },
211
+ uiTheme: Theme,
212
+ args?: BashRenderArgs,
213
+ ): Component {
214
+ const cmdText = args ? formatBashCommand(args, uiTheme) : "…";
215
+ const isError = result.isError === true;
216
+ const { renderContext } = options;
217
+ const output = (renderContext?.output ?? result.content?.find(c => c.type === "text")?.text ?? "").trimEnd();
218
+ const outputLines = output ? output.split("\n") : [];
219
+ const total = outputLines.length;
220
+ const truncation = result.details?.meta?.truncation;
221
+
222
+ const meta: string[] = [];
223
+ if (isError) meta.push("failed");
224
+ if (total > 0) meta.push(`${total} lines`);
225
+
226
+ const header = renderStatusLine(
227
+ { icon: isError ? "error" : "success", title: "Bash", description: cmdText, meta },
228
+ uiTheme,
229
+ );
230
+
231
+ const expanded = renderContext?.expanded ?? options.expanded;
232
+ const showAll = isError || expanded;
233
+ const displayLines = showAll ? outputLines : outputLines.slice(-PREVIEW_LIMITS.OUTPUT_COLLAPSED);
234
+ const skipped = total - displayLines.length;
235
+
236
+ const bodyLines: string[] = [];
237
+ if (skipped > 0) {
238
+ bodyLines.push(uiTheme.fg("dim", `… (${skipped} earlier lines)`));
239
+ }
240
+ const hasTruncation = Boolean(truncation);
241
+ for (let i = 0; i < displayLines.length; i++) {
242
+ bodyLines.push(uiTheme.fg("toolOutput", replaceTabs(displayLines[i])));
243
+ }
244
+
245
+ if (hasTruncation) {
246
+ bodyLines.push(uiTheme.fg("warning", "output truncated"));
247
+ }
248
+ if (!showAll && skipped > 0) {
249
+ bodyLines.push(formatClickHint(uiTheme));
250
+ }
251
+
252
+ const lines = bodyLines.length > 0 ? [header, ...bodyLines] : [header];
253
+ return new Text(lines.join("\n"), 0, 0);
254
+ }
255
+ }
191
256
 
192
257
  interface BashRenderArgs {
193
258
  command?: string;
@@ -231,117 +296,3 @@ function formatBashCommand(args: BashRenderArgs, _uiTheme: Theme): string {
231
296
 
232
297
  return displayWorkdir ? `${prompt} cd ${displayWorkdir} && ${command}` : `${prompt} ${command}`;
233
298
  }
234
-
235
- // Preview line limit when not expanded (matches tool-execution behavior)
236
- export const BASH_PREVIEW_LINES = 10;
237
-
238
- export const bashToolRenderer = {
239
- renderCall(args: BashRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
240
- const cmdText = formatBashCommand(args, uiTheme);
241
- const text = renderStatusLine({ icon: "pending", title: "Bash", description: cmdText }, uiTheme);
242
- return new Text(text, 0, 0);
243
- },
244
-
245
- renderResult(
246
- result: {
247
- content: Array<{ type: string; text?: string }>;
248
- details?: BashToolDetails;
249
- isError?: boolean;
250
- },
251
- options: RenderResultOptions & { renderContext?: BashRenderContext },
252
- uiTheme: Theme,
253
- args?: BashRenderArgs,
254
- ): Component {
255
- const cmdText = args ? formatBashCommand(args, uiTheme) : undefined;
256
- const isError = result.isError === true;
257
- const header = renderStatusLine({ icon: isError ? "error" : "success", title: "Bash" }, uiTheme);
258
- const details = result.details;
259
- const truncation = details?.meta?.truncation;
260
- const outputBlock = new CachedOutputBlock();
261
-
262
- return {
263
- render: (width: number): string[] => {
264
- // REACTIVE: read mutable options at render time
265
- const { renderContext } = options;
266
- const expanded = renderContext?.expanded ?? options.expanded;
267
- const previewLines = renderContext?.previewLines ?? BASH_DEFAULT_PREVIEW_LINES;
268
-
269
- // Get output from context (preferred) or fall back to result content
270
- const output = renderContext?.output ?? result.content?.find(c => c.type === "text")?.text ?? "";
271
- const displayOutput = output.trimEnd();
272
- const showingFullOutput = expanded && renderContext?.isFullOutput === true;
273
-
274
- // Build truncation warning
275
- const timeoutSeconds = renderContext?.timeout;
276
- const timeoutLine =
277
- typeof timeoutSeconds === "number"
278
- ? uiTheme.fg(
279
- "dim",
280
- `${uiTheme.format.bracketLeft}Timeout: ${timeoutSeconds}s${uiTheme.format.bracketRight}`,
281
- )
282
- : undefined;
283
- let warningLine: string | undefined;
284
- if (truncation && !showingFullOutput) {
285
- const warnings: string[] = [];
286
- if (truncation?.artifactId) {
287
- warnings.push(`Full output: artifact://${truncation.artifactId}`);
288
- }
289
- if (truncation.truncatedBy === "lines") {
290
- warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
291
- } else {
292
- warnings.push(
293
- `Truncated: ${truncation.outputLines} lines shown (${formatBytes(truncation.outputBytes)} limit)`,
294
- );
295
- }
296
- if (warnings.length > 0) {
297
- warningLine = uiTheme.fg("warning", wrapBrackets(warnings.join(". "), uiTheme));
298
- }
299
- }
300
-
301
- const outputLines: string[] = [];
302
- const hasOutput = displayOutput.trim().length > 0;
303
- if (hasOutput) {
304
- if (expanded) {
305
- outputLines.push(...displayOutput.split("\n").map(line => replaceTabs(line)));
306
- } else {
307
- const styledOutput = displayOutput
308
- .split("\n")
309
- .map(line => replaceTabs(line))
310
- .join("\n");
311
- const textContent = styledOutput;
312
- const result = truncateToVisualLines(textContent, previewLines, width);
313
- if (result.skippedCount > 0) {
314
- outputLines.push(
315
- uiTheme.fg(
316
- "dim",
317
- `… (${result.skippedCount} earlier lines, showing ${result.visualLines.length} of ${result.skippedCount + result.visualLines.length}) (ctrl+o to expand)`,
318
- ),
319
- );
320
- }
321
- outputLines.push(...result.visualLines);
322
- }
323
- }
324
- if (timeoutLine) outputLines.push(timeoutLine);
325
- if (warningLine) outputLines.push(warningLine);
326
-
327
- return outputBlock.render(
328
- {
329
- header,
330
- state: isError ? "error" : "success",
331
- sections: [
332
- { lines: cmdText ? [uiTheme.fg("dim", cmdText)] : [] },
333
- { label: uiTheme.fg("toolTitle", "Output"), lines: outputLines },
334
- ],
335
- width,
336
- },
337
- uiTheme,
338
- );
339
- },
340
- invalidate: () => {
341
- outputBlock.invalidate();
342
- },
343
- };
344
- },
345
- mergeCallAndResult: true,
346
- inline: true,
347
- };