@travisennis/acai 0.0.3 → 0.0.5

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 (316) hide show
  1. package/README.md +225 -6
  2. package/dist/api/exa/index.d.ts +177 -0
  3. package/dist/api/exa/index.d.ts.map +1 -0
  4. package/dist/api/exa/index.js +439 -0
  5. package/dist/cli.d.ts +3 -2
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/commands/application-log-command.d.ts +1 -0
  8. package/dist/commands/application-log-command.d.ts.map +1 -0
  9. package/dist/commands/application-log-command.js +5 -3
  10. package/dist/commands/clear-command.d.ts +1 -0
  11. package/dist/commands/clear-command.d.ts.map +1 -0
  12. package/dist/commands/clear-command.js +2 -3
  13. package/dist/commands/compact-command.d.ts +1 -0
  14. package/dist/commands/compact-command.d.ts.map +1 -0
  15. package/dist/commands/compact-command.js +1 -1
  16. package/dist/commands/copy-command.d.ts +1 -0
  17. package/dist/commands/copy-command.d.ts.map +1 -0
  18. package/dist/commands/copy-command.js +3 -2
  19. package/dist/commands/edit-command.d.ts +1 -0
  20. package/dist/commands/edit-command.d.ts.map +1 -0
  21. package/dist/commands/edit-command.js +7 -5
  22. package/dist/commands/edit-prompt-command.d.ts +2 -1
  23. package/dist/commands/edit-prompt-command.d.ts.map +1 -0
  24. package/dist/commands/edit-prompt-command.js +15 -7
  25. package/dist/commands/exit-command.d.ts +13 -2
  26. package/dist/commands/exit-command.d.ts.map +1 -0
  27. package/dist/commands/exit-command.js +14 -2
  28. package/dist/commands/files-command.d.ts +1 -0
  29. package/dist/commands/files-command.d.ts.map +1 -0
  30. package/dist/commands/files-command.js +9 -8
  31. package/dist/commands/generate-rules-command.d.ts +1 -0
  32. package/dist/commands/generate-rules-command.d.ts.map +1 -0
  33. package/dist/commands/generate-rules-command.js +4 -3
  34. package/dist/commands/health-command.d.ts +3 -1
  35. package/dist/commands/health-command.d.ts.map +1 -0
  36. package/dist/commands/health-command.js +42 -5
  37. package/dist/commands/help-command.d.ts +1 -0
  38. package/dist/commands/help-command.d.ts.map +1 -0
  39. package/dist/commands/help-command.js +2 -3
  40. package/dist/commands/init-command.d.ts +1 -0
  41. package/dist/commands/init-command.d.ts.map +1 -0
  42. package/dist/commands/init-command.js +1 -2
  43. package/dist/commands/last-log-command.d.ts +1 -0
  44. package/dist/commands/last-log-command.d.ts.map +1 -0
  45. package/dist/commands/last-log-command.js +12 -17
  46. package/dist/commands/list-tools-command.d.ts +3 -0
  47. package/dist/commands/list-tools-command.d.ts.map +1 -0
  48. package/dist/commands/list-tools-command.js +61 -0
  49. package/dist/commands/manager.d.ts +7 -2
  50. package/dist/commands/manager.d.ts.map +1 -0
  51. package/dist/commands/manager.js +43 -6
  52. package/dist/commands/model-command.d.ts +1 -0
  53. package/dist/commands/model-command.d.ts.map +1 -0
  54. package/dist/commands/model-command.js +5 -5
  55. package/dist/commands/paste-command.d.ts +1 -0
  56. package/dist/commands/paste-command.d.ts.map +1 -0
  57. package/dist/commands/paste-command.js +6 -5
  58. package/dist/commands/prompt-command.d.ts +2 -1
  59. package/dist/commands/prompt-command.d.ts.map +1 -0
  60. package/dist/commands/prompt-command.js +62 -8
  61. package/dist/commands/reset-command.d.ts +1 -0
  62. package/dist/commands/reset-command.d.ts.map +1 -0
  63. package/dist/commands/reset-command.js +1 -1
  64. package/dist/commands/rules-command.d.ts +1 -0
  65. package/dist/commands/rules-command.d.ts.map +1 -0
  66. package/dist/commands/rules-command.js +5 -3
  67. package/dist/commands/save-command.d.ts +1 -0
  68. package/dist/commands/save-command.d.ts.map +1 -0
  69. package/dist/commands/save-command.js +1 -1
  70. package/dist/commands/shell-command.d.ts +3 -0
  71. package/dist/commands/shell-command.d.ts.map +1 -0
  72. package/dist/commands/shell-command.js +60 -0
  73. package/dist/commands/types.d.ts +9 -6
  74. package/dist/commands/types.d.ts.map +1 -0
  75. package/dist/commands/usage-command.d.ts +1 -0
  76. package/dist/commands/usage-command.d.ts.map +1 -0
  77. package/dist/commands/usage-command.js +2 -3
  78. package/dist/config.d.ts +22 -34
  79. package/dist/config.d.ts.map +1 -0
  80. package/dist/config.js +61 -15
  81. package/dist/conversation-analyzer.d.ts +2 -1
  82. package/dist/conversation-analyzer.d.ts.map +1 -0
  83. package/dist/dedent.d.ts +1 -0
  84. package/dist/dedent.d.ts.map +1 -0
  85. package/dist/execution/index.d.ts +112 -0
  86. package/dist/execution/index.d.ts.map +1 -0
  87. package/dist/execution/index.js +432 -0
  88. package/dist/formatting.d.ts +2 -13
  89. package/dist/formatting.d.ts.map +1 -0
  90. package/dist/formatting.js +5 -64
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +14 -4
  94. package/dist/logger.d.ts +1 -0
  95. package/dist/logger.d.ts.map +1 -0
  96. package/dist/mentions.d.ts +4 -0
  97. package/dist/mentions.d.ts.map +1 -0
  98. package/dist/mentions.js +42 -10
  99. package/dist/messages.d.ts +8 -20
  100. package/dist/messages.d.ts.map +1 -0
  101. package/dist/messages.js +33 -53
  102. package/dist/middleware/audit-message.d.ts +1 -0
  103. package/dist/middleware/audit-message.d.ts.map +1 -0
  104. package/dist/middleware/index.d.ts +1 -0
  105. package/dist/middleware/index.d.ts.map +1 -0
  106. package/dist/middleware/rate-limit.d.ts +1 -0
  107. package/dist/middleware/rate-limit.d.ts.map +1 -0
  108. package/dist/models/ai-config.d.ts +1 -0
  109. package/dist/models/ai-config.d.ts.map +1 -0
  110. package/dist/models/anthropic-provider.d.ts +1 -0
  111. package/dist/models/anthropic-provider.d.ts.map +1 -0
  112. package/dist/models/deepseek-provider.d.ts +1 -0
  113. package/dist/models/deepseek-provider.d.ts.map +1 -0
  114. package/dist/models/google-provider.d.ts +1 -0
  115. package/dist/models/google-provider.d.ts.map +1 -0
  116. package/dist/models/groq-provider.d.ts +20 -0
  117. package/dist/models/groq-provider.d.ts.map +1 -0
  118. package/dist/models/groq-provider.js +31 -0
  119. package/dist/models/manager.d.ts +1 -0
  120. package/dist/models/manager.d.ts.map +1 -0
  121. package/dist/models/openai-provider.d.ts +2 -1
  122. package/dist/models/openai-provider.d.ts.map +1 -0
  123. package/dist/models/openrouter-provider.d.ts +31 -22
  124. package/dist/models/openrouter-provider.d.ts.map +1 -0
  125. package/dist/models/openrouter-provider.js +115 -1
  126. package/dist/models/providers.d.ts +4 -5
  127. package/dist/models/providers.d.ts.map +1 -0
  128. package/dist/models/providers.js +7 -3
  129. package/dist/models/xai-provider.d.ts +1 -0
  130. package/dist/models/xai-provider.d.ts.map +1 -0
  131. package/dist/parsing.d.ts +2 -1
  132. package/dist/parsing.d.ts.map +1 -0
  133. package/dist/prompts/manager.d.ts +14 -2
  134. package/dist/prompts/manager.d.ts.map +1 -0
  135. package/dist/prompts.d.ts +1 -0
  136. package/dist/prompts.d.ts.map +1 -0
  137. package/dist/prompts.js +17 -11
  138. package/dist/repl/display-tool-messages.d.ts +4 -0
  139. package/dist/repl/display-tool-messages.d.ts.map +1 -0
  140. package/dist/repl/display-tool-messages.js +55 -0
  141. package/dist/repl/display-tool-use.d.ts +14 -0
  142. package/dist/repl/display-tool-use.d.ts.map +1 -0
  143. package/dist/repl/display-tool-use.js +63 -0
  144. package/dist/repl/get-prompt-header.d.ts +8 -0
  145. package/dist/repl/get-prompt-header.d.ts.map +1 -0
  146. package/dist/repl/get-prompt-header.js +38 -0
  147. package/dist/repl/tool-call-repair.d.ts +4 -0
  148. package/dist/repl/tool-call-repair.d.ts.map +1 -0
  149. package/dist/repl/tool-call-repair.js +50 -0
  150. package/dist/repl-prompt.d.ts +1 -0
  151. package/dist/repl-prompt.d.ts.map +1 -0
  152. package/dist/repl.d.ts +8 -4
  153. package/dist/repl.d.ts.map +1 -0
  154. package/dist/repl.js +108 -252
  155. package/dist/terminal/ansi-styles.d.ts +77 -0
  156. package/dist/terminal/ansi-styles.d.ts.map +1 -0
  157. package/dist/terminal/ansi-styles.js +215 -0
  158. package/dist/terminal/checkbox-prompt.d.ts +36 -0
  159. package/dist/terminal/checkbox-prompt.d.ts.map +1 -0
  160. package/dist/terminal/checkbox-prompt.js +362 -0
  161. package/dist/terminal/default-theme.d.ts +6 -0
  162. package/dist/terminal/default-theme.d.ts.map +1 -0
  163. package/dist/terminal/default-theme.js +182 -0
  164. package/dist/terminal/east-asian-width.d.ts +8 -0
  165. package/dist/terminal/east-asian-width.d.ts.map +1 -0
  166. package/dist/terminal/east-asian-width.js +409 -0
  167. package/dist/terminal/editor-prompt.d.ts +10 -0
  168. package/dist/terminal/editor-prompt.d.ts.map +1 -0
  169. package/dist/terminal/editor-prompt.js +61 -0
  170. package/dist/terminal/errors.d.ts +19 -0
  171. package/dist/terminal/errors.d.ts.map +1 -0
  172. package/dist/terminal/errors.js +37 -0
  173. package/dist/terminal/formatting.d.ts +1 -11
  174. package/dist/terminal/formatting.d.ts.map +1 -0
  175. package/dist/terminal/formatting.js +4 -20
  176. package/dist/terminal/highlight/index.d.ts +53 -0
  177. package/dist/terminal/highlight/index.d.ts.map +1 -0
  178. package/dist/terminal/highlight/index.js +90 -0
  179. package/dist/terminal/highlight/theme.d.ts +233 -0
  180. package/dist/terminal/highlight/theme.d.ts.map +1 -0
  181. package/dist/terminal/highlight/theme.js +83 -0
  182. package/dist/terminal/index.d.ts +16 -9
  183. package/dist/terminal/index.d.ts.map +1 -0
  184. package/dist/terminal/index.js +42 -126
  185. package/dist/terminal/input-prompt.d.ts +16 -0
  186. package/dist/terminal/input-prompt.d.ts.map +1 -0
  187. package/dist/terminal/input-prompt.js +181 -0
  188. package/dist/terminal/markdown-utils.d.ts +1 -0
  189. package/dist/terminal/markdown-utils.d.ts.map +1 -0
  190. package/dist/terminal/markdown.d.ts +1 -0
  191. package/dist/terminal/markdown.d.ts.map +1 -0
  192. package/dist/terminal/markdown.js +17 -12
  193. package/dist/terminal/search-prompt.d.ts +20 -0
  194. package/dist/terminal/search-prompt.d.ts.map +1 -0
  195. package/dist/terminal/search-prompt.js +279 -0
  196. package/dist/terminal/select-prompt.d.ts +26 -0
  197. package/dist/terminal/select-prompt.d.ts.map +1 -0
  198. package/dist/terminal/select-prompt.js +298 -0
  199. package/dist/terminal/string-width.d.ts +7 -0
  200. package/dist/terminal/string-width.d.ts.map +1 -0
  201. package/dist/terminal/string-width.js +61 -0
  202. package/dist/terminal/strip-ansi.d.ts +2 -0
  203. package/dist/terminal/strip-ansi.d.ts.map +1 -0
  204. package/dist/terminal/strip-ansi.js +20 -0
  205. package/dist/terminal/style.d.ts +191 -0
  206. package/dist/terminal/style.d.ts.map +1 -0
  207. package/dist/terminal/style.js +259 -0
  208. package/dist/terminal/supports-color.d.ts +1 -0
  209. package/dist/terminal/supports-color.d.ts.map +1 -0
  210. package/dist/terminal/supports-hyperlinks.d.ts +1 -3
  211. package/dist/terminal/supports-hyperlinks.d.ts.map +1 -0
  212. package/dist/terminal/supports-hyperlinks.js +1 -1
  213. package/dist/terminal/types.d.ts +1 -37
  214. package/dist/terminal/types.d.ts.map +1 -0
  215. package/dist/terminal/wrap-ansi.d.ts +8 -0
  216. package/dist/terminal/wrap-ansi.d.ts.map +1 -0
  217. package/dist/terminal/wrap-ansi.js +190 -0
  218. package/dist/{token-utils.d.ts → tokens/counter.d.ts} +1 -0
  219. package/dist/tokens/counter.d.ts.map +1 -0
  220. package/dist/{token-utils.js → tokens/counter.js} +1 -1
  221. package/dist/tokens/manage-output.d.ts +34 -0
  222. package/dist/tokens/manage-output.d.ts.map +1 -0
  223. package/dist/tokens/manage-output.js +44 -0
  224. package/dist/{token-tracker.d.ts → tokens/tracker.d.ts} +1 -0
  225. package/dist/tokens/tracker.d.ts.map +1 -0
  226. package/dist/tool-executor.d.ts +28 -0
  227. package/dist/tool-executor.d.ts.map +1 -0
  228. package/dist/tool-executor.js +74 -0
  229. package/dist/tools/agent.d.ts +3 -2
  230. package/dist/tools/agent.d.ts.map +1 -0
  231. package/dist/tools/agent.js +7 -4
  232. package/dist/tools/bash-utils.d.ts +7 -0
  233. package/dist/tools/bash-utils.d.ts.map +1 -0
  234. package/dist/tools/bash-utils.js +212 -0
  235. package/dist/tools/bash.d.ts +9 -7
  236. package/dist/tools/bash.d.ts.map +1 -0
  237. package/dist/tools/bash.js +95 -212
  238. package/dist/tools/code-interpreter.d.ts +1 -0
  239. package/dist/tools/code-interpreter.d.ts.map +1 -0
  240. package/dist/tools/code-interpreter.js +33 -8
  241. package/dist/tools/delete-file.d.ts +5 -3
  242. package/dist/tools/delete-file.d.ts.map +1 -0
  243. package/dist/tools/delete-file.js +47 -33
  244. package/dist/tools/directory-tree.d.ts +10 -1
  245. package/dist/tools/directory-tree.d.ts.map +1 -0
  246. package/dist/tools/directory-tree.js +91 -8
  247. package/dist/tools/dynamic-tool-loader.d.ts +12 -0
  248. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -0
  249. package/dist/tools/dynamic-tool-loader.js +280 -0
  250. package/dist/tools/dynamic-tool-parser.d.ts +20 -0
  251. package/dist/tools/dynamic-tool-parser.d.ts.map +1 -0
  252. package/dist/tools/dynamic-tool-parser.js +21 -0
  253. package/dist/tools/edit-file.d.ts +10 -2
  254. package/dist/tools/edit-file.d.ts.map +1 -0
  255. package/dist/tools/edit-file.js +117 -40
  256. package/dist/tools/file-editing-utils.d.ts +2 -0
  257. package/dist/tools/file-editing-utils.d.ts.map +1 -0
  258. package/dist/tools/file-editing-utils.js +135 -0
  259. package/dist/tools/filesystem-utils.d.ts +6 -21
  260. package/dist/tools/filesystem-utils.d.ts.map +1 -0
  261. package/dist/tools/filesystem-utils.js +96 -148
  262. package/dist/tools/git-utils.d.ts +1 -0
  263. package/dist/tools/git-utils.d.ts.map +1 -0
  264. package/dist/tools/grep.d.ts +5 -3
  265. package/dist/tools/grep.d.ts.map +1 -0
  266. package/dist/tools/grep.js +67 -27
  267. package/dist/tools/index.d.ts +10 -14
  268. package/dist/tools/index.d.ts.map +1 -0
  269. package/dist/tools/index.js +33 -22
  270. package/dist/tools/move-file.d.ts +1 -0
  271. package/dist/tools/move-file.d.ts.map +1 -0
  272. package/dist/tools/move-file.js +12 -5
  273. package/dist/tools/read-file.d.ts +2 -1
  274. package/dist/tools/read-file.d.ts.map +1 -0
  275. package/dist/tools/read-file.js +13 -6
  276. package/dist/tools/read-multiple-files.d.ts +2 -1
  277. package/dist/tools/read-multiple-files.d.ts.map +1 -0
  278. package/dist/tools/read-multiple-files.js +90 -9
  279. package/dist/tools/save-file.d.ts +5 -3
  280. package/dist/tools/save-file.d.ts.map +1 -0
  281. package/dist/tools/save-file.js +64 -36
  282. package/dist/tools/think.d.ts +1 -0
  283. package/dist/tools/think.d.ts.map +1 -0
  284. package/dist/tools/think.js +5 -1
  285. package/dist/tools/types.d.ts +14 -1
  286. package/dist/tools/types.d.ts.map +1 -0
  287. package/dist/tools/web-fetch.d.ts +4 -2
  288. package/dist/tools/web-fetch.d.ts.map +1 -0
  289. package/dist/tools/web-fetch.js +2 -2
  290. package/dist/tools/web-search.d.ts +2 -1
  291. package/dist/tools/web-search.d.ts.map +1 -0
  292. package/dist/tools/web-search.js +46 -11
  293. package/dist/utils/filesystem.d.ts +23 -0
  294. package/dist/utils/filesystem.d.ts.map +1 -0
  295. package/dist/utils/filesystem.js +140 -0
  296. package/dist/utils/filetype-detection.d.ts +3 -0
  297. package/dist/utils/filetype-detection.d.ts.map +1 -0
  298. package/dist/utils/filetype-detection.js +112 -0
  299. package/dist/utils/glob.d.ts +52 -0
  300. package/dist/utils/glob.d.ts.map +1 -0
  301. package/dist/utils/glob.js +376 -0
  302. package/dist/utils/ignore.d.ts +104 -0
  303. package/dist/utils/ignore.d.ts.map +1 -0
  304. package/dist/utils/ignore.js +649 -0
  305. package/dist/utils/process.d.ts +10 -1
  306. package/dist/utils/process.d.ts.map +1 -0
  307. package/dist/utils/process.js +104 -5
  308. package/dist/utils/zod-utils.d.ts +4 -0
  309. package/dist/utils/zod-utils.d.ts.map +1 -0
  310. package/dist/utils/zod-utils.js +7 -0
  311. package/dist/version.d.ts +1 -0
  312. package/dist/version.d.ts.map +1 -0
  313. package/package.json +32 -30
  314. package/dist/tools/command-validation.d.ts +0 -12
  315. package/dist/tools/command-validation.js +0 -113
  316. /package/dist/{token-tracker.js → tokens/tracker.js} +0 -0
@@ -8,14 +8,20 @@ import { z } from "zod";
8
8
  export const CodeInterpreterTool = {
9
9
  name: "codeInterpreter",
10
10
  };
11
- const toolDescription = `Executes JavaScript code in a separate Node.js process using Node's Permission Model. By default, the child process has no permissions except read/write within the current working directory. The tool returns stdout, stderr, and exitCode. Use console.log/console.error to produce output.
11
+ const toolDescription = `Executes Typescript code in a separate Node.js process using Node's Permission Model.
12
12
 
13
13
  ⚠️ **IMPORTANT**: This tool uses ES Modules (ESM) only.
14
14
  - Use \`import\` statements, NOT \`require()\`
15
15
  - Examples: \`import fs from 'node:fs'\` NOT \`const fs = require('fs')\`
16
16
  - Add file extensions for relative imports: \`import { utils } from './utils.js'\`
17
17
 
18
- These scripts are run in the \`${process.cwd}/.acai-ci-tmp\`. Keep this in mind if you intend to import or reference files from this project in your script.
18
+ These scripts are run in the \`${process.cwd()}/.acai-ci-tmp\`. You can import project source files using relative paths from the project root with .ts extensions:
19
+
20
+ \`\`\` typescript
21
+ import { functionName } from '../source/path/to/module.ts';
22
+ \`\`\`
23
+
24
+ The interpreter supports ES Modules with TypeScript files directly.
19
25
 
20
26
  Timeout defaults to 5 seconds and can be extended up to 60 seconds.`;
21
27
  export const createCodeInterpreterTool = ({ sendData, }) => {
@@ -23,7 +29,7 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
23
29
  [CodeInterpreterTool.name]: tool({
24
30
  description: toolDescription,
25
31
  inputSchema: z.object({
26
- code: z.string().describe("JavaScript code to be executed."),
32
+ code: z.string().describe("The Typescript code to be executed."),
27
33
  timeoutSeconds: z
28
34
  .number()
29
35
  .int()
@@ -32,7 +38,11 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
32
38
  .nullable()
33
39
  .describe("Execution timeout in seconds (1-60). Default 5."),
34
40
  }),
35
- execute: async ({ code, timeoutSeconds }, { toolCallId }) => {
41
+ execute: async ({ code, timeoutSeconds }, { toolCallId, abortSignal }) => {
42
+ // Check if execution has been aborted
43
+ if (abortSignal?.aborted) {
44
+ throw new Error("Code interpretation aborted");
45
+ }
36
46
  const workingDirectory = process.cwd();
37
47
  try {
38
48
  sendData?.({
@@ -40,23 +50,28 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
40
50
  id: toolCallId,
41
51
  data: "Initializing code interpreter environment",
42
52
  });
53
+ const scriptType = "typescript";
43
54
  sendData?.({
44
55
  event: "tool-update",
45
56
  id: toolCallId,
46
57
  data: {
47
58
  primary: "Executing...",
48
59
  secondary: [
49
- `${"`".repeat(3)} javascript\n${code.slice(0, 500)}${"`".repeat(3)}`,
60
+ `${"`".repeat(3)} ${scriptType}}\n${code.slice(0, 500)}${"`".repeat(3)}`,
50
61
  ],
51
62
  },
52
63
  });
53
64
  if (code.trim().length === 0) {
54
65
  throw new Error("No code provided");
55
66
  }
67
+ if (abortSignal?.aborted) {
68
+ throw new Error("Code interpretation aborted before execution");
69
+ }
56
70
  const timeoutMs = Math.min(Math.max((timeoutSeconds ?? 5) * 1000, 1000), 60000);
57
71
  const tmpBase = join(workingDirectory, ".acai-ci-tmp");
58
72
  await mkdir(tmpBase, { recursive: true });
59
- const scriptPath = join(tmpBase, `temp_script_${Date.now()}_${randomUUID()}.mjs`);
73
+ const ext = ".ts";
74
+ const scriptPath = join(tmpBase, `temp_script_${Date.now()}_${randomUUID()}${ext}`);
60
75
  await writeFile(scriptPath, code, { encoding: "utf8" });
61
76
  const args = [
62
77
  "--permission",
@@ -75,6 +90,16 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
75
90
  NODE_OPTIONS: "",
76
91
  }),
77
92
  });
93
+ // Handle abort signal by killing the child process
94
+ if (abortSignal) {
95
+ abortSignal.addEventListener("abort", () => {
96
+ try {
97
+ child.kill("SIGKILL");
98
+ }
99
+ catch { }
100
+ throw new Error("Code interpretation aborted during execution");
101
+ });
102
+ }
78
103
  let stdout = "";
79
104
  let stderr = "";
80
105
  let timedOut = false;
@@ -108,7 +133,7 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
108
133
  throw new Error(`Process terminated by signal ${completed.signal ?? "unknown"}`);
109
134
  }
110
135
  if (completed.code !== 0) {
111
- const message = `Process exited with code ${completed.code}. Stderr: ${stderr.trim()}`;
136
+ const message = `Process exited with code ${completed.code}. Stderr:\n${stderr.trim()}`;
112
137
  throw new Error(message);
113
138
  }
114
139
  const result = {
@@ -127,7 +152,7 @@ export const createCodeInterpreterTool = ({ sendData, }) => {
127
152
  const errorMessage = err.name === "ETIMEDOUT" ||
128
153
  err.message.includes("timed out")
129
154
  ? "Script timed out"
130
- : `Error: ${err.message}`;
155
+ : `Error:\n${err.message}`;
131
156
  sendData?.({
132
157
  event: "tool-error",
133
158
  id: toolCallId,
@@ -1,15 +1,17 @@
1
1
  import type { Terminal } from "../terminal/index.ts";
2
+ import type { ToolExecutor } from "../tool-executor.ts";
2
3
  import type { SendData } from "./types.ts";
3
4
  export declare const DeleteFileTool: {
4
5
  name: "deleteFile";
5
6
  };
6
- export declare const createDeleteFileTool: ({ workingDir, sendData, terminal, autoAcceptAll, }: {
7
+ export declare const createDeleteFileTool: ({ workingDir, terminal, sendData, toolExecutor, }: {
7
8
  workingDir: string;
8
- sendData?: SendData;
9
9
  terminal?: Terminal;
10
- autoAcceptAll?: boolean;
10
+ sendData?: SendData;
11
+ toolExecutor?: ToolExecutor;
11
12
  }) => Promise<{
12
13
  deleteFile: import("ai").Tool<{
13
14
  path: string;
14
15
  }, string>;
15
16
  }>;
17
+ //# sourceMappingURL=delete-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-file.d.ts","sourceRoot":"","sources":["../../source/tools/delete-file.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAErE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,cAAc;;CAE1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,mDAKxC;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;;;;EA2HA,CAAC"}
@@ -1,82 +1,96 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import fs from "node:fs/promises";
3
- import { input, select } from "@inquirer/prompts";
4
3
  import { tool } from "ai";
5
- import chalk from "chalk";
6
4
  import { z } from "zod";
5
+ import style from "../terminal/style.js";
7
6
  import { joinWorkingDir, validatePath } from "./filesystem-utils.js";
8
7
  export const DeleteFileTool = {
9
8
  name: "deleteFile",
10
9
  };
11
- export const createDeleteFileTool = async ({ workingDir, sendData, terminal, autoAcceptAll, }) => {
10
+ export const createDeleteFileTool = async ({ workingDir, terminal, sendData, toolExecutor, }) => {
12
11
  const allowedDirectory = workingDir;
13
- let autoAcceptDeletes = autoAcceptAll ?? false;
14
12
  return {
15
13
  [DeleteFileTool.name]: tool({
16
14
  description: "Delete a file permanently.",
17
15
  inputSchema: z.object({
18
16
  path: z.string().describe("Absolute path to the file to delete"),
19
17
  }),
20
- execute: async ({ path: userPath }, { toolCallId }) => {
18
+ execute: async ({ path: userPath }, { toolCallId, abortSignal }) => {
19
+ // Check if execution has been aborted
20
+ if (abortSignal?.aborted) {
21
+ throw new Error("File deletion aborted");
22
+ }
21
23
  sendData?.({
22
24
  id: toolCallId,
23
25
  event: "tool-init",
24
- data: `Deleting file: ${chalk.cyan(userPath)}`,
26
+ data: `Deleting file: ${style.cyan(userPath)}`,
25
27
  });
26
28
  try {
27
- const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory);
29
+ const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory, { abortSignal });
28
30
  // Check if file exists before attempting delete
29
31
  if (!existsSync(filePath)) {
30
32
  throw new Error(`File not found: ${filePath}`);
31
33
  }
34
+ // Pre-check for stat
35
+ if (abortSignal?.aborted) {
36
+ throw new Error("File deletion aborted before stat");
37
+ }
32
38
  // Ensure it's a file, not a directory
33
39
  const stats = await fs.stat(filePath);
34
40
  if (stats.isDirectory()) {
35
41
  throw new Error(`Path is a directory, not a file: ${filePath}`);
36
42
  }
37
43
  if (terminal) {
38
- terminal.writeln(`\n${chalk.red.bold("●")} Proposing file deletion: ${chalk.cyan(userPath)}`);
44
+ terminal.writeln(`\n${style.red.bold("●")} Proposing file deletion: ${style.cyan(userPath)}`);
39
45
  terminal.lineBreak();
40
46
  terminal.writeln("This action cannot be undone.");
41
47
  terminal.lineBreak();
42
- let userChoice;
43
- if (autoAcceptDeletes) {
44
- terminal.writeln(chalk.green("✓ Auto-accepting deletions (all future deletions will be accepted)"));
45
- userChoice = "accept";
46
- }
47
- else {
48
- userChoice = await select({
49
- message: "What would you like to do with this file?",
50
- choices: [
51
- { name: "Accept and delete this file", value: "accept" },
52
- {
53
- name: "Accept all future deletions (including this)",
54
- value: "accept-all",
55
- },
56
- { name: "Reject this deletion", value: "reject" },
57
- ],
58
- default: "accept",
59
- });
48
+ let userResponse;
49
+ if (toolExecutor) {
50
+ const ctx = {
51
+ toolName: DeleteFileTool.name,
52
+ toolCallId,
53
+ message: "What would you like to do with this deletion?",
54
+ choices: {
55
+ accept: "Accept this deletion",
56
+ acceptAll: "Accept all future deletions (including this)",
57
+ reject: "Reject this deletion",
58
+ },
59
+ };
60
+ try {
61
+ userResponse = await toolExecutor.ask(ctx, { abortSignal });
62
+ }
63
+ catch (e) {
64
+ if (e.name === "AbortError") {
65
+ throw new Error("File deletion aborted during user input");
66
+ }
67
+ throw e;
68
+ }
60
69
  }
70
+ const { result: userChoice, reason } = userResponse ?? {
71
+ result: "accept",
72
+ };
61
73
  terminal.lineBreak();
62
74
  if (userChoice === "accept-all") {
63
- autoAcceptDeletes = true;
64
- terminal.writeln(chalk.yellow("✓ Auto-accept mode enabled for all future deletions"));
75
+ terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all deletions"));
65
76
  terminal.lineBreak();
66
77
  }
67
78
  if (userChoice === "reject") {
68
- const reason = await input({ message: "Feedback: " });
69
79
  terminal.lineBreak();
80
+ const rejectionReason = reason || "No reason provided";
70
81
  sendData?.({
71
82
  id: toolCallId,
72
83
  event: "tool-completion",
73
- data: `Deletion rejected by user. Reason: ${reason}`,
84
+ data: `Deletion rejected by user. Reason: ${rejectionReason}`,
74
85
  });
75
- return `The user rejected this deletion. Reason: ${reason}`;
86
+ return `The user rejected this deletion. Reason: ${rejectionReason}`;
76
87
  }
77
- // If accepted, proceed to delete file
78
88
  }
79
- // Delete the file
89
+ // Pre-side-effect check
90
+ if (abortSignal?.aborted) {
91
+ throw new Error("File deletion aborted before unlink");
92
+ }
93
+ // Delete the file with signal
80
94
  await fs.unlink(filePath);
81
95
  sendData?.({
82
96
  id: toolCallId,
@@ -1,12 +1,21 @@
1
+ import type { TokenCounter } from "../tokens/counter.ts";
1
2
  import type { SendData } from "./types.ts";
2
3
  export declare const DirectoryTreeTool: {
3
4
  name: "directoryTree";
4
5
  };
5
- export declare const createDirectoryTreeTool: ({ workingDir, sendData, }: {
6
+ export declare const createDirectoryTreeTool: ({ workingDir, sendData, tokenCounter, }: {
6
7
  workingDir: string;
7
8
  sendData?: SendData;
9
+ tokenCounter: TokenCounter;
8
10
  }) => Promise<{
9
11
  directoryTree: import("ai").Tool<{
10
12
  path: string;
11
13
  }, string>;
12
14
  }>;
15
+ /**
16
+ * Generates a string representation of a directory tree starting from the given path.
17
+ * @param dirPath - The path of the directory to generate the tree for.
18
+ * @returns A Promise that resolves to a string representation of the directory tree.
19
+ */
20
+ export declare function directoryTree(dirPath: string): Promise<string>;
21
+ //# sourceMappingURL=directory-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../../source/tools/directory-tree.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,iBAAiB;;CAE7B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,yCAI3C;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;EAmEA,CAAC;AA8CF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpE"}
@@ -1,11 +1,16 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
1
3
  import { tool } from "ai";
2
- import chalk from "chalk";
3
4
  import { z } from "zod";
4
- import { directoryTree, joinWorkingDir, validatePath, } from "./filesystem-utils.js";
5
+ import { config } from "../config.js";
6
+ import style from "../terminal/style.js";
7
+ import { manageOutput } from "../tokens/manage-output.js";
8
+ import ignore from "../utils/ignore.js";
9
+ import { joinWorkingDir, validatePath } from "./filesystem-utils.js";
5
10
  export const DirectoryTreeTool = {
6
11
  name: "directoryTree",
7
12
  };
8
- export const createDirectoryTreeTool = async ({ workingDir, sendData, }) => {
13
+ export const createDirectoryTreeTool = async ({ workingDir, sendData, tokenCounter, }) => {
9
14
  const allowedDirectory = workingDir;
10
15
  return {
11
16
  [DirectoryTreeTool.name]: tool({
@@ -13,26 +18,104 @@ export const createDirectoryTreeTool = async ({ workingDir, sendData, }) => {
13
18
  inputSchema: z.object({
14
19
  path: z.string().describe("The path."),
15
20
  }),
16
- execute: async ({ path }, { toolCallId }) => {
21
+ execute: async ({ path }, { toolCallId, abortSignal }) => {
22
+ // Check if execution has been aborted
23
+ if (abortSignal?.aborted) {
24
+ throw new Error("Directory tree listing aborted");
25
+ }
17
26
  let validPath;
18
27
  try {
28
+ if (abortSignal?.aborted) {
29
+ throw new Error("Directory tree listing aborted before path validation");
30
+ }
19
31
  sendData?.({
20
32
  id: toolCallId,
21
33
  event: "tool-init",
22
- data: `Listing directory tree: ${chalk.cyan(path)}`,
34
+ data: `Listing directory tree: ${style.cyan(path)}`,
35
+ });
36
+ validPath = await validatePath(joinWorkingDir(path, workingDir), allowedDirectory, { abortSignal });
37
+ const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
38
+ const rawTree = await directoryTree(validPath);
39
+ const managed = manageOutput(rawTree, {
40
+ tokenCounter,
41
+ threshold: maxTokens,
23
42
  });
24
- validPath = await validatePath(joinWorkingDir(path, workingDir), allowedDirectory);
43
+ if (managed.truncated) {
44
+ sendData?.({
45
+ id: toolCallId,
46
+ event: "tool-update",
47
+ data: { primary: managed.warning },
48
+ });
49
+ }
25
50
  sendData?.({
26
51
  id: toolCallId,
27
52
  event: "tool-completion",
28
- data: "Done",
53
+ data: `Done (${managed.tokenCount} tokens)`,
29
54
  });
55
+ return managed.content;
30
56
  }
31
57
  catch (error) {
58
+ sendData?.({
59
+ id: toolCallId,
60
+ event: "tool-error",
61
+ data: "Failed to show directory tree.",
62
+ });
32
63
  return `Failed to show directory tree: ${error.message}`;
33
64
  }
34
- return directoryTree(validPath);
35
65
  },
36
66
  }),
37
67
  };
38
68
  };
69
+ /**
70
+ * Generates the indentation string for a given level in the directory tree.
71
+ * @param level - The current level in the directory tree.
72
+ * @param isLast - Indicates if the current item is the last in its parent directory.
73
+ * @returns The indentation string for the current level.
74
+ */
75
+ function getIndent(level, isLast) {
76
+ const indent = "│ ".repeat(level - 1);
77
+ return level === 0 ? "" : `${indent}${isLast ? "└── " : "├── "}`;
78
+ }
79
+ /**
80
+ * Recursively generates a string representation of a directory tree.
81
+ * @param dirPath - The path of the directory to generate the tree for.
82
+ * @param level - The current level in the directory tree (default: 1).
83
+ * @returns A Promise that resolves to a string representation of the directory tree.
84
+ * @throws Will log an error if there's an issue reading the directory.
85
+ */
86
+ async function generateDirectoryTree(dirPath, ig, level = 1) {
87
+ const name = path.basename(dirPath);
88
+ let output = `${getIndent(level, false)}${name}\n`;
89
+ const items = await fs.readdir(dirPath);
90
+ const filteredItems = ig.filter(items);
91
+ for (let i = 0; i < filteredItems.length; i++) {
92
+ const item = filteredItems[i] ?? "";
93
+ const itemPath = path.join(dirPath, item);
94
+ const isLast = i === filteredItems.length - 1;
95
+ const stats = await fs.stat(itemPath);
96
+ if (stats.isDirectory()) {
97
+ output += await generateDirectoryTree(itemPath, ig, level + 1);
98
+ }
99
+ else {
100
+ output += `${getIndent(level + 1, isLast)}${item}\n`;
101
+ }
102
+ }
103
+ return output;
104
+ }
105
+ /**
106
+ * Generates a string representation of a directory tree starting from the given path.
107
+ * @param dirPath - The path of the directory to generate the tree for.
108
+ * @returns A Promise that resolves to a string representation of the directory tree.
109
+ */
110
+ export async function directoryTree(dirPath) {
111
+ let ig;
112
+ try {
113
+ const ignoreFile = await fs.readFile(path.join(process.cwd(), ".gitignore"));
114
+ ig = ignore().add(ignoreFile.toString()).add(".git");
115
+ }
116
+ catch (_error) {
117
+ // If .gitignore doesn't exist, create basic ignore with just .git
118
+ ig = ignore().add(".git");
119
+ }
120
+ return (await generateDirectoryTree(dirPath, ig)).trim();
121
+ }
@@ -0,0 +1,12 @@
1
+ import { type ToolMetadata } from "./dynamic-tool-parser.ts";
2
+ import type { SendData } from "./types.ts";
3
+ export declare function createDynamicTool(scriptPath: string, metadata: ToolMetadata, sendData?: SendData): {
4
+ [x: string]: import("ai").Tool<Record<string, unknown>, unknown>;
5
+ };
6
+ export declare function loadDynamicTools({ baseDir, sendData, }: {
7
+ baseDir: string;
8
+ sendData?: SendData;
9
+ }): Promise<Record<string, {
10
+ [x: string]: import("ai").Tool<Record<string, unknown>, unknown>;
11
+ }>>;
12
+ //# sourceMappingURL=dynamic-tool-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-tool-loader.d.ts","sourceRoot":"","sources":["../../source/tools/dynamic-tool-loader.ts"],"names":[],"mappings":"AAQA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAwF3C,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,YAAY,EACtB,QAAQ,CAAC,EAAE,QAAQ;;EAuJpB;AAED,wBAAsB,gBAAgB,CAAC,EACrC,OAAO,EACP,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;;IAgEA"}