@nghyane/arcane 0.1.13 → 0.1.15

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 (303) 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/index.ts +1 -35
  30. package/src/exa/render.ts +30 -190
  31. package/src/export/html/index.ts +1 -1
  32. package/src/extensibility/custom-tools/loader.ts +1 -1
  33. package/src/extensibility/custom-tools/types.ts +5 -1
  34. package/src/extensibility/custom-tools/wrapper.ts +1 -1
  35. package/src/extensibility/extensions/runner.ts +1 -1
  36. package/src/extensibility/extensions/types.ts +1 -1
  37. package/src/extensibility/extensions/wrapper.ts +7 -15
  38. package/src/extensibility/hooks/runner.ts +1 -1
  39. package/src/extensibility/hooks/types.ts +1 -1
  40. package/src/extensibility/plugins/doctor.ts +1 -1
  41. package/src/index.ts +13 -13
  42. package/src/lsp/index.ts +77 -24
  43. package/src/lsp/render.ts +34 -583
  44. package/src/lsp/types.ts +3 -3
  45. package/src/lsp/utils.ts +1 -1
  46. package/src/main.ts +1 -1
  47. package/src/mcp/tool-bridge.ts +1 -24
  48. package/src/modes/components/assistant-message.ts +7 -7
  49. package/src/modes/components/bash-execution.ts +50 -112
  50. package/src/modes/components/bordered-loader.ts +1 -1
  51. package/src/modes/components/branch-summary-message.ts +16 -10
  52. package/src/modes/components/compaction-summary-message.ts +20 -12
  53. package/src/modes/components/context-group.ts +106 -0
  54. package/src/modes/components/custom-message.ts +4 -5
  55. package/src/modes/components/diff.ts +2 -2
  56. package/src/modes/components/dynamic-border.ts +1 -1
  57. package/src/modes/components/extensions/extension-dashboard.ts +1 -1
  58. package/src/modes/components/extensions/extension-list.ts +1 -1
  59. package/src/modes/components/extensions/inspector-panel.ts +1 -1
  60. package/src/modes/components/footer.ts +2 -2
  61. package/src/modes/components/history-search.ts +1 -1
  62. package/src/modes/components/hook-editor.ts +1 -1
  63. package/src/modes/components/hook-input.ts +1 -1
  64. package/src/modes/components/hook-message.ts +4 -5
  65. package/src/modes/components/hook-selector.ts +1 -1
  66. package/src/modes/components/index.ts +0 -2
  67. package/src/modes/components/keybinding-hints.ts +1 -1
  68. package/src/modes/components/login-dialog.ts +1 -1
  69. package/src/modes/components/mcp-add-wizard.ts +1 -1
  70. package/src/modes/components/model-selector.ts +1 -1
  71. package/src/modes/components/oauth-selector.ts +1 -1
  72. package/src/modes/components/plugin-settings.ts +1 -1
  73. package/src/modes/components/python-execution.ts +51 -91
  74. package/src/modes/components/queue-mode-selector.ts +1 -1
  75. package/src/modes/components/session-selector.ts +1 -1
  76. package/src/modes/components/settings-defs.ts +5 -10
  77. package/src/modes/components/settings-selector.ts +1 -1
  78. package/src/modes/components/show-images-selector.ts +1 -1
  79. package/src/modes/components/skill-message.ts +4 -4
  80. package/src/modes/components/status-line/segments.ts +2 -2
  81. package/src/modes/components/status-line/separators.ts +1 -1
  82. package/src/modes/components/status-line-segment-editor.ts +1 -1
  83. package/src/modes/components/status-line.ts +1 -1
  84. package/src/modes/components/theme-selector.ts +1 -1
  85. package/src/modes/components/thinking-selector.ts +1 -1
  86. package/src/modes/components/todo-display.ts +2 -4
  87. package/src/modes/components/todo-reminder.ts +4 -4
  88. package/src/modes/components/tool-execution.ts +118 -440
  89. package/src/modes/components/tool-image-display.ts +107 -0
  90. package/src/modes/components/tree-selector.ts +2 -2
  91. package/src/modes/components/ttsr-notification.ts +4 -17
  92. package/src/modes/components/user-message-selector.ts +1 -1
  93. package/src/modes/components/user-message.ts +9 -10
  94. package/src/modes/components/welcome.ts +1 -1
  95. package/src/modes/controllers/command-controller.ts +1 -1
  96. package/src/modes/controllers/event-controller.ts +58 -187
  97. package/src/modes/controllers/extension-ui-controller.ts +1 -1
  98. package/src/modes/controllers/input-controller.ts +3 -1
  99. package/src/modes/controllers/mcp-command-controller.ts +1 -1
  100. package/src/modes/controllers/selector-controller.ts +3 -26
  101. package/src/modes/controllers/ssh-command-controller.ts +1 -1
  102. package/src/modes/interactive-mode.ts +3 -7
  103. package/src/modes/print-mode.ts +5 -5
  104. package/src/modes/rpc/rpc-mode.ts +1 -1
  105. package/src/modes/types.ts +1 -2
  106. package/src/modes/utils/ui-helpers.ts +34 -32
  107. package/src/patch/edit-tool.ts +742 -0
  108. package/src/patch/index.ts +32 -898
  109. package/src/patch/schemas.ts +208 -0
  110. package/src/patch/shared.ts +83 -151
  111. package/src/prompts/agents/explore.md +22 -37
  112. package/src/prompts/agents/init.md +1 -1
  113. package/src/prompts/agents/librarian.md +29 -20
  114. package/src/prompts/agents/oracle.md +9 -2
  115. package/src/prompts/agents/reviewer.md +14 -48
  116. package/src/prompts/agents/task.md +16 -8
  117. package/src/prompts/compaction/branch-summary.md +4 -1
  118. package/src/prompts/compaction/compaction-summary.md +4 -1
  119. package/src/prompts/system/subagent-system-prompt.md +1 -1
  120. package/src/prompts/system/system-prompt.md +162 -178
  121. package/src/prompts/system/verification-reminder.md +6 -0
  122. package/src/sdk.ts +0 -9
  123. package/src/session/agent-session.ts +244 -1459
  124. package/src/session/model-controller.ts +406 -0
  125. package/src/session/retry-utils.ts +71 -0
  126. package/src/session/session-manager.ts +22 -186
  127. package/src/session/session-types.ts +312 -0
  128. package/src/session/stats.ts +387 -0
  129. package/src/session/streaming-edit.ts +258 -0
  130. package/src/session/ttsr.ts +213 -0
  131. package/src/slash-commands/builtin-registry.ts +0 -8
  132. package/src/stt/recorder.ts +2 -2
  133. package/src/system-prompt.ts +1 -14
  134. package/src/task/agents.ts +7 -33
  135. package/src/task/executor.ts +50 -438
  136. package/src/task/index.ts +104 -71
  137. package/src/task/progress-tracker.ts +390 -0
  138. package/src/task/render.ts +371 -187
  139. package/src/task/subprocess-tool-registry.ts +1 -1
  140. package/src/task/types.ts +14 -47
  141. package/src/tools/ask.ts +31 -42
  142. package/src/tools/bash-interactive.ts +2 -2
  143. package/src/tools/bash-interceptor.ts +2 -2
  144. package/src/tools/bash-normalize.ts +1 -1
  145. package/src/tools/bash-skill-urls.ts +2 -2
  146. package/src/tools/bash.ts +87 -136
  147. package/src/tools/browser.ts +54 -84
  148. package/src/tools/create-tools.ts +186 -0
  149. package/src/tools/default-renderer.ts +104 -0
  150. package/src/tools/explore.ts +11 -10
  151. package/src/tools/fetch.ts +24 -114
  152. package/src/tools/find.ts +48 -132
  153. package/src/tools/gemini-image.ts +5 -15
  154. package/src/tools/github.ts +450 -0
  155. package/src/tools/grep.ts +43 -179
  156. package/src/tools/index.ts +35 -198
  157. package/src/tools/json-tree.ts +3 -3
  158. package/src/tools/librarian.ts +18 -18
  159. package/src/tools/list-limit.ts +2 -2
  160. package/src/tools/notebook.ts +35 -87
  161. package/src/tools/oracle.ts +25 -25
  162. package/src/tools/output-meta.ts +89 -4
  163. package/src/tools/output-utils.ts +2 -2
  164. package/src/tools/python.ts +86 -637
  165. package/src/tools/read.ts +36 -119
  166. package/src/tools/reviewer-tool.ts +19 -21
  167. package/src/tools/search-code.ts +128 -0
  168. package/src/tools/ssh.ts +67 -126
  169. package/src/tools/subagent-tool.ts +197 -123
  170. package/src/tools/todo-write.ts +15 -31
  171. package/src/tools/tool-errors.ts +0 -30
  172. package/src/tools/undo-edit.ts +30 -67
  173. package/src/tools/write.ts +78 -127
  174. package/src/tui/code-cell.ts +4 -4
  175. package/src/tui/file-list.ts +2 -2
  176. package/src/tui/output-block.ts +1 -1
  177. package/src/tui/status-line.ts +1 -1
  178. package/src/tui/tree-list.ts +2 -2
  179. package/src/tui/types.ts +1 -1
  180. package/src/tui/utils.ts +1 -1
  181. package/src/{tools → ui}/render-utils.ts +87 -126
  182. package/src/utils/external-editor.ts +4 -4
  183. package/src/utils/file-mentions.ts +1 -1
  184. package/src/utils/index.ts +30 -0
  185. package/src/utils/tools-manager.ts +9 -19
  186. package/src/web/github-client.ts +290 -0
  187. package/src/web/scrapers/github.ts +11 -62
  188. package/src/web/search/auth.ts +1 -3
  189. package/src/web/search/index.ts +82 -46
  190. package/src/web/search/provider.ts +11 -16
  191. package/src/web/search/providers/grep.ts +160 -0
  192. package/src/web/search/render.ts +48 -235
  193. package/src/web/search/types.ts +1 -1
  194. package/src/commands/commit.ts +0 -36
  195. package/src/commit/agentic/agent.ts +0 -311
  196. package/src/commit/agentic/fallback.ts +0 -96
  197. package/src/commit/agentic/index.ts +0 -359
  198. package/src/commit/agentic/prompts/analyze-file.md +0 -22
  199. package/src/commit/agentic/prompts/session-user.md +0 -25
  200. package/src/commit/agentic/prompts/split-confirm.md +0 -1
  201. package/src/commit/agentic/prompts/system.md +0 -38
  202. package/src/commit/agentic/state.ts +0 -69
  203. package/src/commit/agentic/tools/analyze-file.ts +0 -118
  204. package/src/commit/agentic/tools/git-file-diff.ts +0 -194
  205. package/src/commit/agentic/tools/git-hunk.ts +0 -50
  206. package/src/commit/agentic/tools/git-overview.ts +0 -84
  207. package/src/commit/agentic/tools/index.ts +0 -56
  208. package/src/commit/agentic/tools/propose-changelog.ts +0 -128
  209. package/src/commit/agentic/tools/propose-commit.ts +0 -154
  210. package/src/commit/agentic/tools/recent-commits.ts +0 -81
  211. package/src/commit/agentic/tools/split-commit.ts +0 -280
  212. package/src/commit/agentic/topo-sort.ts +0 -44
  213. package/src/commit/agentic/trivial.ts +0 -51
  214. package/src/commit/agentic/validation.ts +0 -200
  215. package/src/commit/analysis/conventional.ts +0 -165
  216. package/src/commit/analysis/index.ts +0 -4
  217. package/src/commit/analysis/scope.ts +0 -242
  218. package/src/commit/analysis/summary.ts +0 -112
  219. package/src/commit/analysis/validation.ts +0 -66
  220. package/src/commit/changelog/detect.ts +0 -37
  221. package/src/commit/changelog/generate.ts +0 -110
  222. package/src/commit/changelog/index.ts +0 -234
  223. package/src/commit/changelog/parse.ts +0 -44
  224. package/src/commit/cli.ts +0 -93
  225. package/src/commit/git/diff.ts +0 -148
  226. package/src/commit/git/errors.ts +0 -9
  227. package/src/commit/git/index.ts +0 -211
  228. package/src/commit/git/operations.ts +0 -54
  229. package/src/commit/index.ts +0 -5
  230. package/src/commit/map-reduce/index.ts +0 -64
  231. package/src/commit/map-reduce/map-phase.ts +0 -178
  232. package/src/commit/map-reduce/reduce-phase.ts +0 -145
  233. package/src/commit/map-reduce/utils.ts +0 -9
  234. package/src/commit/message.ts +0 -11
  235. package/src/commit/model-selection.ts +0 -69
  236. package/src/commit/pipeline.ts +0 -243
  237. package/src/commit/prompts/analysis-system.md +0 -148
  238. package/src/commit/prompts/analysis-user.md +0 -38
  239. package/src/commit/prompts/changelog-system.md +0 -50
  240. package/src/commit/prompts/changelog-user.md +0 -18
  241. package/src/commit/prompts/file-observer-system.md +0 -24
  242. package/src/commit/prompts/file-observer-user.md +0 -8
  243. package/src/commit/prompts/reduce-system.md +0 -50
  244. package/src/commit/prompts/reduce-user.md +0 -17
  245. package/src/commit/prompts/summary-retry.md +0 -3
  246. package/src/commit/prompts/summary-system.md +0 -38
  247. package/src/commit/prompts/summary-user.md +0 -13
  248. package/src/commit/prompts/types-description.md +0 -2
  249. package/src/commit/types.ts +0 -109
  250. package/src/commit/utils/exclusions.ts +0 -42
  251. package/src/mcp/render.ts +0 -123
  252. package/src/modes/components/agent-dashboard.ts +0 -1130
  253. package/src/modes/components/codemode-group.ts +0 -369
  254. package/src/modes/components/read-tool-group.ts +0 -119
  255. package/src/modes/components/visual-truncate.ts +0 -63
  256. package/src/prompts/system/subagent-user-prompt.md +0 -8
  257. package/src/prompts/tools/ask.md +0 -44
  258. package/src/prompts/tools/bash.md +0 -24
  259. package/src/prompts/tools/browser.md +0 -33
  260. package/src/prompts/tools/calculator.md +0 -12
  261. package/src/prompts/tools/explore.md +0 -29
  262. package/src/prompts/tools/fetch.md +0 -16
  263. package/src/prompts/tools/find.md +0 -18
  264. package/src/prompts/tools/gemini-image.md +0 -23
  265. package/src/prompts/tools/grep.md +0 -28
  266. package/src/prompts/tools/hashline.md +0 -232
  267. package/src/prompts/tools/librarian.md +0 -24
  268. package/src/prompts/tools/lsp.md +0 -28
  269. package/src/prompts/tools/oracle.md +0 -26
  270. package/src/prompts/tools/patch.md +0 -74
  271. package/src/prompts/tools/python.md +0 -66
  272. package/src/prompts/tools/read.md +0 -36
  273. package/src/prompts/tools/replace.md +0 -38
  274. package/src/prompts/tools/reviewer.md +0 -41
  275. package/src/prompts/tools/ssh.md +0 -51
  276. package/src/prompts/tools/task-summary.md +0 -28
  277. package/src/prompts/tools/task.md +0 -146
  278. package/src/prompts/tools/todo-write.md +0 -65
  279. package/src/prompts/tools/undo-edit.md +0 -7
  280. package/src/prompts/tools/web-search.md +0 -19
  281. package/src/prompts/tools/write.md +0 -18
  282. package/src/task/batch.ts +0 -102
  283. package/src/task/discovery.ts +0 -126
  284. package/src/task/parallel.ts +0 -84
  285. package/src/task/template.ts +0 -32
  286. package/src/tools/calculator.ts +0 -537
  287. package/src/tools/jtd-to-typescript.ts +0 -198
  288. package/src/tools/renderers.ts +0 -60
  289. package/src/tools/tool-result.ts +0 -86
  290. /package/src/{modes/theme → theme}/dark.json +0 -0
  291. /package/src/{modes/theme → theme}/defaults/dark-catppuccin.json +0 -0
  292. /package/src/{modes/theme → theme}/defaults/dark-dracula.json +0 -0
  293. /package/src/{modes/theme → theme}/defaults/dark-gruvbox.json +0 -0
  294. /package/src/{modes/theme → theme}/defaults/dark-solarized.json +0 -0
  295. /package/src/{modes/theme → theme}/defaults/dark-tokyo-night.json +0 -0
  296. /package/src/{modes/theme → theme}/defaults/index.ts +0 -0
  297. /package/src/{modes/theme → theme}/defaults/light-catppuccin.json +0 -0
  298. /package/src/{modes/theme → theme}/defaults/light-github.json +0 -0
  299. /package/src/{modes/theme → theme}/defaults/light-solarized.json +0 -0
  300. /package/src/{modes/theme → theme}/light.json +0 -0
  301. /package/src/{modes/theme → theme}/mermaid-cache.ts +0 -0
  302. /package/src/{modes/theme → theme}/theme-schema.json +0 -0
  303. /package/src/{modes/theme → theme}/theme.ts +0 -0
@@ -5,24 +5,18 @@ import { Text } from "@nghyane/arcane-tui";
5
5
  import { untilAborted } from "@nghyane/arcane-utils";
6
6
  import { type Static, Type } from "@sinclair/typebox";
7
7
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
8
- import type { Theme } from "../modes/theme/theme";
9
8
  import type { ToolSession } from "../sdk";
10
- import { Hasher, type RenderCache, renderCodeCell, renderStatusLine } from "../tui";
9
+ import type { Theme } from "../theme/theme";
10
+ import { renderStatusLine } from "../tui";
11
+ import { formatCount, formatErrorMessage, shortenPath } from "../ui/render-utils";
11
12
  import { resolveToCwd } from "./path-utils";
12
- import { formatCount, formatErrorMessage, PREVIEW_LIMITS } from "./render-utils";
13
13
 
14
14
  const notebookSchema = Type.Object({
15
- action: StringEnum(["edit", "insert", "delete"], {
16
- description: "Action to perform on the notebook cell",
17
- }),
18
- notebook_path: Type.String({ description: "Path to the .ipynb file (relative or absolute)" }),
19
- cell_index: Type.Number({ description: "0-based index of the cell to operate on" }),
20
- content: Type.Optional(Type.String({ description: "New cell content (required for edit/insert)" })),
21
- cell_type: Type.Optional(
22
- StringEnum(["code", "markdown"], {
23
- description: "Cell type for insert (default: code)",
24
- }),
25
- ),
15
+ action: StringEnum(["edit", "insert", "delete"], { description: "Operation to perform on notebook cell" }),
16
+ notebook_path: Type.String({ description: "Path to the notebook file" }),
17
+ cell_index: Type.Number({ description: "Zero-based cell index" }),
18
+ content: Type.Optional(Type.String({ description: "Cell content (for edit/insert)" })),
19
+ cell_type: Type.Optional(StringEnum(["code", "markdown"], { description: "Cell type (default: code)" })),
26
20
  });
27
21
 
28
22
  export interface NotebookToolDetails {
@@ -59,7 +53,7 @@ function splitIntoLines(content: string): string[] {
59
53
 
60
54
  type NotebookParams = Static<typeof notebookSchema>;
61
55
 
62
- export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookToolDetails> {
56
+ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookToolDetails, Theme> {
63
57
  readonly name = "notebook";
64
58
  readonly label = "Notebook";
65
59
  readonly description =
@@ -183,26 +177,7 @@ export class NotebookTool implements AgentTool<typeof notebookSchema, NotebookTo
183
177
  };
184
178
  });
185
179
  }
186
- }
187
-
188
- // =============================================================================
189
- // TUI Renderer
190
- // =============================================================================
191
180
 
192
- interface NotebookRenderArgs {
193
- action: string;
194
- notebookPath?: string;
195
- notebook_path?: string;
196
- cellNumber?: number;
197
- cell_index?: number;
198
- cellType?: string;
199
- cell_type?: string;
200
- content?: string;
201
- }
202
-
203
- const COLLAPSED_TEXT_LIMIT = PREVIEW_LIMITS.COLLAPSED_LINES * 2;
204
-
205
- export const notebookToolRenderer = {
206
181
  renderCall(args: NotebookRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
207
182
  const meta: string[] = [];
208
183
  const notebookPath = args.notebookPath ?? args.notebook_path;
@@ -217,71 +192,44 @@ export const notebookToolRenderer = {
217
192
  uiTheme,
218
193
  );
219
194
  return new Text(text, 0, 0);
220
- },
195
+ }
221
196
 
222
197
  renderResult(
223
198
  result: { content: Array<{ type: string; text?: string }>; details?: NotebookToolDetails },
224
- options: RenderResultOptions,
199
+ _options: RenderResultOptions,
225
200
  uiTheme: Theme,
226
201
  args?: NotebookRenderArgs,
227
202
  ): Component {
228
203
  const content = result.content?.[0];
229
204
  if (content?.type === "text" && content.text?.startsWith("Error:")) {
230
- const notebookPath = args?.notebookPath ?? args?.notebook_path ?? "?";
231
- const header = renderStatusLine({ icon: "error", title: "Notebook", description: notebookPath }, uiTheme);
232
- return new Text([header, formatErrorMessage(content.text, uiTheme)].join("\n"), 0, 0);
205
+ return new Text(formatErrorMessage(content.text, uiTheme), 0, 0);
233
206
  }
234
-
235
207
  const details = result.details;
236
208
  const action = details?.action ?? "edit";
237
209
  const cellIndex = details?.cellIndex;
238
210
  const cellType = details?.cellType;
239
- const totalCells = details?.totalCells;
240
- const cellSource = details?.cellSource ?? [];
241
- const lineCount = cellSource.length;
242
-
243
- const actionLabel = action === "insert" ? "Inserted" : action === "delete" ? "Deleted" : "Edited";
244
- const cellLabel = cellType || "cell";
245
- const summaryParts = [`${actionLabel} ${cellLabel} ${cellIndex ?? "?"}`];
246
- if (lineCount > 0) summaryParts.push(formatCount("line", lineCount));
247
- if (totalCells !== undefined) summaryParts.push(`${totalCells} total`);
248
-
249
- const outputLines = summaryParts.map(part => uiTheme.fg("dim", part));
250
- const codeText = cellSource.join("");
251
- const language = cellType === "markdown" ? "markdown" : undefined;
252
-
211
+ const lineCount = details?.cellSource?.length ?? 0;
253
212
  const notebookPath = args?.notebookPath ?? args?.notebook_path;
254
- const notebookLabel = notebookPath ? `${actionLabel} ${notebookPath}` : "Notebook";
255
- let cached: RenderCache | undefined;
256
-
257
- return {
258
- render: (width: number): string[] => {
259
- // REACTIVE: read mutable options at render time
260
- const { expanded } = options;
261
- const key = new Hasher().bool(expanded).u32(width).digest();
262
- if (cached?.key === key) return cached.lines;
263
-
264
- const lines = renderCodeCell(
265
- {
266
- code: codeText,
267
- language,
268
- title: notebookLabel,
269
- status: "complete",
270
- output: outputLines.join("\n"),
271
- codeMaxLines: expanded ? Number.POSITIVE_INFINITY : COLLAPSED_TEXT_LIMIT,
272
- expanded,
273
- width,
274
- },
275
- uiTheme,
276
- );
213
+ const description = notebookPath ? shortenPath(notebookPath) : "notebook";
214
+ const meta: string[] = [];
215
+ if (cellType) meta.push(cellType);
216
+ if (cellIndex !== undefined) meta.push(`cell ${cellIndex}`);
217
+ if (lineCount > 0) meta.push(formatCount("line", lineCount));
218
+ return new Text(
219
+ renderStatusLine({ icon: "success", title: `Notebook ${action}`, description, meta }, uiTheme),
220
+ 0,
221
+ 0,
222
+ );
223
+ }
224
+ }
277
225
 
278
- cached = { key, lines };
279
- return lines;
280
- },
281
- invalidate: () => {
282
- cached = undefined;
283
- },
284
- };
285
- },
286
- mergeCallAndResult: true,
287
- };
226
+ interface NotebookRenderArgs {
227
+ action: string;
228
+ notebookPath?: string;
229
+ notebook_path?: string;
230
+ cellNumber?: number;
231
+ cell_index?: number;
232
+ cellType?: string;
233
+ cell_type?: string;
234
+ content?: string;
235
+ }
@@ -1,40 +1,40 @@
1
1
  import { Type } from "@sinclair/typebox";
2
- import oracleDescription from "../prompts/tools/oracle.md" with { type: "text" };
3
- import { createSubagentTool } from "./subagent-tool";
2
+ import type { SubagentConfig } from "./subagent-tool";
4
3
 
5
4
  const schema = Type.Object({
6
- task: Type.String({
7
- description:
8
- "The task or question for the Oracle. Be specific about what kind of guidance, review, or planning you need.",
9
- }),
10
- context: Type.Optional(
11
- Type.String({
12
- description: "Background about the current situation, what you've tried, or relevant information.",
13
- }),
14
- ),
15
- files: Type.Optional(
16
- Type.Array(Type.String(), {
17
- description: "File paths the Oracle should examine as part of its analysis.",
18
- }),
19
- ),
5
+ task: Type.String({ description: "Question or task for the oracle to reason about" }),
6
+ context: Type.Optional(Type.String({ description: "Additional context or constraints" })),
7
+ files: Type.Optional(Type.Array(Type.String(), { description: "File paths for the oracle to examine" })),
20
8
  });
21
9
 
22
10
  function buildTask(p: Record<string, unknown>): string {
23
- let task = p.task as string;
24
- if (p.context) task += `\n\n## Context\n${p.context}`;
11
+ const parts: string[] = [p.task as string];
12
+ if (p.context) parts.push(`\nContext: ${p.context}`);
25
13
  const files = p.files as string[] | undefined;
26
- if (files?.length) task += `\n\n## Files to examine\n${files.map(f => `- ${f}`).join("\n")}`;
27
- return task;
14
+ if (files?.length) parts.push(`\nFiles to examine:\n${files.map(f => `- ${f}`).join("\n")}`);
15
+ return parts.join("\n");
28
16
  }
29
17
 
30
- export const OracleTool = createSubagentTool({
18
+ export const oracleConfig: SubagentConfig<typeof schema.properties> = {
31
19
  name: "oracle",
32
20
  label: "Oracle",
33
21
  agent: "oracle",
34
22
  schema,
35
- descriptionTemplate: oracleDescription,
36
- progressText: "Consulting oracle...",
23
+ progressText: "Analyzing...",
37
24
  tmpPrefix: "arc-oracle-",
38
25
  buildTask,
39
- buildDescription: p => `Oracle: ${(p.task as string).slice(0, 60)}`,
40
- });
26
+ buildDescription: p => String(p.task ?? "").slice(0, 80),
27
+ buildContextLine: p => {
28
+ const parts: string[] = [];
29
+ if (p.context) parts.push(`Context: ${String(p.context).split("\n")[0].slice(0, 40)}`);
30
+ const files = p.files as string[] | undefined;
31
+ if (files?.length) parts.push(`${files.length} file${files.length > 1 ? "s" : ""}`);
32
+ return parts.length > 0 ? parts.join(" · ") : null;
33
+ },
34
+ toolDescription: [
35
+ "Senior engineering advisor with deep reasoning. Returns single comprehensive response — no follow-ups.",
36
+ "WHEN TO USE: Only for complex tasks requiring deep analysis, planning, or debugging across multiple files. Pass files for it to examine, context for background.",
37
+ "WHEN NOT TO USE: Simple questions answerable by reading code; tasks you can do directly.",
38
+ "Treat its response as advisory — do independent investigation after, then act.",
39
+ ].join(" "),
40
+ };
@@ -46,7 +46,7 @@ export type SourceMeta =
46
46
  /**
47
47
  * LSP diagnostic info (for edit/write tools).
48
48
  */
49
- export interface DiagnosticMeta {
49
+ interface DiagnosticMeta {
50
50
  summary: string;
51
51
  messages: string[];
52
52
  }
@@ -82,13 +82,13 @@ export interface TruncationOptions {
82
82
  artifactId?: string;
83
83
  }
84
84
 
85
- export interface TruncationSummaryOptions {
85
+ interface TruncationSummaryOptions {
86
86
  direction: "head" | "tail";
87
87
  startLine?: number;
88
88
  totalFileLines?: number;
89
89
  }
90
90
 
91
- export interface TruncationTextOptions {
91
+ interface TruncationTextOptions {
92
92
  direction: "head" | "tail";
93
93
  totalLines?: number;
94
94
  totalBytes?: number;
@@ -107,7 +107,7 @@ export interface TruncationTextOptions {
107
107
  * .get();
108
108
  * ```
109
109
  */
110
- export class OutputMetaBuilder {
110
+ class OutputMetaBuilder {
111
111
  #meta: OutputMeta = {};
112
112
 
113
113
  /** Add truncation info from TruncationResult. No-op if not truncated. */
@@ -308,6 +308,91 @@ export function outputMeta(): OutputMetaBuilder {
308
308
  return new OutputMetaBuilder();
309
309
  }
310
310
 
311
+ // =============================================================================
312
+ // ToolResultBuilder - Fluent API for building AgentToolResult with OutputMeta
313
+ // =============================================================================
314
+
315
+ type ToolContent = Array<TextContent | ImageContent>;
316
+
317
+ type DetailsWithMeta = { meta?: OutputMeta };
318
+
319
+ class ToolResultBuilder<TDetails extends DetailsWithMeta> {
320
+ #details: TDetails;
321
+ #meta = new OutputMetaBuilder();
322
+ #content: ToolContent = [];
323
+
324
+ constructor(details?: TDetails) {
325
+ this.#details = details ?? ({} as TDetails);
326
+ }
327
+
328
+ text(text: string): this {
329
+ this.#content = [{ type: "text", text }];
330
+ return this;
331
+ }
332
+
333
+ content(content: ToolContent): this {
334
+ this.#content = content;
335
+ return this;
336
+ }
337
+
338
+ truncation(result: TruncationResult, options: TruncationOptions): this {
339
+ this.#meta.truncation(result, options);
340
+ return this;
341
+ }
342
+
343
+ truncationFromSummary(summary: OutputSummary, options: TruncationSummaryOptions): this {
344
+ this.#meta.truncationFromSummary(summary, options);
345
+ return this;
346
+ }
347
+
348
+ truncationFromText(text: string, options: TruncationTextOptions): this {
349
+ this.#meta.truncationFromText(text, options);
350
+ return this;
351
+ }
352
+
353
+ limits(limits: { matchLimit?: number; resultLimit?: number; headLimit?: number; columnMax?: number }): this {
354
+ this.#meta.limits(limits);
355
+ return this;
356
+ }
357
+
358
+ sourceUrl(value: string): this {
359
+ this.#meta.sourceUrl(value);
360
+ return this;
361
+ }
362
+
363
+ sourcePath(value: string): this {
364
+ this.#meta.sourcePath(value);
365
+ return this;
366
+ }
367
+
368
+ sourceInternal(value: string): this {
369
+ this.#meta.sourceInternal(value);
370
+ return this;
371
+ }
372
+
373
+ diagnostics(summary: string, messages: string[]): this {
374
+ this.#meta.diagnostics(summary, messages);
375
+ return this;
376
+ }
377
+
378
+ done(): AgentToolResult<TDetails> {
379
+ const meta = this.#meta.get();
380
+ if (meta) {
381
+ this.#details.meta = meta;
382
+ }
383
+ const hasDetails = Object.entries(this.#details).some(([, value]) => value !== undefined);
384
+
385
+ return {
386
+ content: this.#content,
387
+ details: hasDetails ? this.#details : undefined,
388
+ };
389
+ }
390
+ }
391
+
392
+ export function toolResult<TDetails extends DetailsWithMeta>(details?: TDetails): ToolResultBuilder<TDetails> {
393
+ return new ToolResultBuilder(details);
394
+ }
395
+
311
396
  // =============================================================================
312
397
  // Notice formatting
313
398
  // =============================================================================
@@ -1,7 +1,7 @@
1
1
  import { ArtifactManager } from "../session/artifacts";
2
2
  import type { ToolSession } from ".";
3
3
 
4
- export interface TailBuffer {
4
+ interface TailBuffer {
5
5
  append(chunk: string): void;
6
6
  text(): string;
7
7
  bytes(): number;
@@ -35,7 +35,7 @@ export function createTailBuffer(maxBytes: number): TailBuffer {
35
35
  };
36
36
  }
37
37
 
38
- export function getArtifactManager(session: ToolSession): ArtifactManager | null {
38
+ function getArtifactManager(session: ToolSession): ArtifactManager | null {
39
39
  if (session.artifactManager) {
40
40
  return session.artifactManager;
41
41
  }