@nodetool-ai/cli 0.7.0-rc.23 → 0.8.2

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 (535) hide show
  1. package/README.md +82 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/ExecutionTree.d.ts +2 -1
  4. package/dist/ExecutionTree.d.ts.map +1 -1
  5. package/dist/ExecutionTree.js +1 -1
  6. package/dist/ExecutionTree.js.map +1 -1
  7. package/dist/affected/affected.d.ts +45 -0
  8. package/dist/affected/affected.d.ts.map +1 -0
  9. package/dist/affected/affected.js +160 -0
  10. package/dist/affected/affected.js.map +1 -0
  11. package/dist/agent-toolbelt.d.ts +15 -0
  12. package/dist/agent-toolbelt.d.ts.map +1 -0
  13. package/dist/agent-toolbelt.js +28 -0
  14. package/dist/agent-toolbelt.js.map +1 -0
  15. package/dist/api-client.d.ts +12 -0
  16. package/dist/api-client.d.ts.map +1 -0
  17. package/dist/api-client.js +21 -0
  18. package/dist/api-client.js.map +1 -0
  19. package/dist/app-build/bundle.d.ts +15 -0
  20. package/dist/app-build/bundle.d.ts.map +1 -0
  21. package/dist/app-build/bundle.js +45 -0
  22. package/dist/app-build/bundle.js.map +1 -0
  23. package/dist/app-build/watch.d.ts +13 -0
  24. package/dist/app-build/watch.d.ts.map +1 -0
  25. package/dist/app-build/watch.js +25 -0
  26. package/dist/app-build/watch.js.map +1 -0
  27. package/dist/app-debug/app-target.d.ts +14 -0
  28. package/dist/app-debug/app-target.d.ts.map +1 -0
  29. package/dist/app-debug/app-target.js +120 -0
  30. package/dist/app-debug/app-target.js.map +1 -0
  31. package/dist/app-debug/harness.d.ts +29 -0
  32. package/dist/app-debug/harness.d.ts.map +1 -0
  33. package/dist/app-debug/harness.js +116 -0
  34. package/dist/app-debug/harness.js.map +1 -0
  35. package/dist/app-debug/index.d.ts +12 -0
  36. package/dist/app-debug/index.d.ts.map +1 -0
  37. package/dist/app-debug/index.js +9 -0
  38. package/dist/app-debug/index.js.map +1 -0
  39. package/dist/app.d.ts +38 -48
  40. package/dist/app.d.ts.map +1 -1
  41. package/dist/app.js +980 -677
  42. package/dist/app.js.map +1 -1
  43. package/dist/bash-tool.d.ts +13 -0
  44. package/dist/bash-tool.d.ts.map +1 -0
  45. package/dist/bash-tool.js +85 -0
  46. package/dist/bash-tool.js.map +1 -0
  47. package/dist/chat-codeact.d.ts +93 -0
  48. package/dist/chat-codeact.d.ts.map +1 -0
  49. package/dist/chat-codeact.js +179 -0
  50. package/dist/chat-codeact.js.map +1 -0
  51. package/dist/chat-context.d.ts +18 -0
  52. package/dist/chat-context.d.ts.map +1 -0
  53. package/dist/chat-context.js +32 -0
  54. package/dist/chat-context.js.map +1 -0
  55. package/dist/chat-media.d.ts +3 -0
  56. package/dist/chat-media.d.ts.map +1 -0
  57. package/dist/chat-media.js +46 -0
  58. package/dist/chat-media.js.map +1 -0
  59. package/dist/chat-prompts.d.ts +20 -0
  60. package/dist/chat-prompts.d.ts.map +1 -0
  61. package/dist/chat-prompts.js +42 -0
  62. package/dist/chat-prompts.js.map +1 -0
  63. package/dist/chat-sessions.d.ts +25 -0
  64. package/dist/chat-sessions.d.ts.map +1 -0
  65. package/dist/chat-sessions.js +153 -0
  66. package/dist/chat-sessions.js.map +1 -0
  67. package/dist/command-errors.d.ts +10 -0
  68. package/dist/command-errors.d.ts.map +1 -0
  69. package/dist/command-errors.js +15 -0
  70. package/dist/command-errors.js.map +1 -0
  71. package/dist/commands/__tests__/jtbd.test.d.ts +2 -0
  72. package/dist/commands/__tests__/jtbd.test.d.ts.map +1 -0
  73. package/dist/commands/__tests__/jtbd.test.js +120 -0
  74. package/dist/commands/__tests__/jtbd.test.js.map +1 -0
  75. package/dist/commands/__tests__/timeline-render-audio.test.d.ts +2 -0
  76. package/dist/commands/__tests__/timeline-render-audio.test.d.ts.map +1 -0
  77. package/dist/commands/__tests__/timeline-render-audio.test.js +53 -0
  78. package/dist/commands/__tests__/timeline-render-audio.test.js.map +1 -0
  79. package/dist/commands/__tests__/timeline-render-completeness.test.d.ts +2 -0
  80. package/dist/commands/__tests__/timeline-render-completeness.test.d.ts.map +1 -0
  81. package/dist/commands/__tests__/timeline-render-completeness.test.js +117 -0
  82. package/dist/commands/__tests__/timeline-render-completeness.test.js.map +1 -0
  83. package/dist/commands/__tests__/timeline-render.test.d.ts +2 -0
  84. package/dist/commands/__tests__/timeline-render.test.d.ts.map +1 -0
  85. package/dist/commands/__tests__/timeline-render.test.js +115 -0
  86. package/dist/commands/__tests__/timeline-render.test.js.map +1 -0
  87. package/dist/commands/__tests__/timeline-score.test.d.ts +2 -0
  88. package/dist/commands/__tests__/timeline-score.test.d.ts.map +1 -0
  89. package/dist/commands/__tests__/timeline-score.test.js +100 -0
  90. package/dist/commands/__tests__/timeline-score.test.js.map +1 -0
  91. package/dist/commands/affected.d.ts +9 -0
  92. package/dist/commands/affected.d.ts.map +1 -0
  93. package/dist/commands/affected.js +122 -0
  94. package/dist/commands/affected.js.map +1 -0
  95. package/dist/commands/agent.d.ts +26 -4
  96. package/dist/commands/agent.d.ts.map +1 -1
  97. package/dist/commands/agent.js +328 -306
  98. package/dist/commands/agent.js.map +1 -1
  99. package/dist/commands/app.d.ts +3 -0
  100. package/dist/commands/app.d.ts.map +1 -0
  101. package/dist/commands/app.js +405 -0
  102. package/dist/commands/app.js.map +1 -0
  103. package/dist/commands/apps.d.ts +15 -0
  104. package/dist/commands/apps.d.ts.map +1 -0
  105. package/dist/commands/apps.js +180 -0
  106. package/dist/commands/apps.js.map +1 -0
  107. package/dist/commands/auth.d.ts +12 -0
  108. package/dist/commands/auth.d.ts.map +1 -0
  109. package/dist/commands/auth.js +154 -0
  110. package/dist/commands/auth.js.map +1 -0
  111. package/dist/commands/collections.d.ts +10 -0
  112. package/dist/commands/collections.d.ts.map +1 -0
  113. package/dist/commands/collections.js +257 -0
  114. package/dist/commands/collections.js.map +1 -0
  115. package/dist/commands/costs.d.ts +15 -0
  116. package/dist/commands/costs.d.ts.map +1 -0
  117. package/dist/commands/costs.js +201 -0
  118. package/dist/commands/costs.js.map +1 -0
  119. package/dist/commands/db.d.ts +3 -0
  120. package/dist/commands/db.d.ts.map +1 -0
  121. package/dist/commands/db.js +176 -0
  122. package/dist/commands/db.js.map +1 -0
  123. package/dist/commands/debug-summary-output.d.ts +22 -0
  124. package/dist/commands/debug-summary-output.d.ts.map +1 -0
  125. package/dist/commands/debug-summary-output.js +28 -0
  126. package/dist/commands/debug-summary-output.js.map +1 -0
  127. package/dist/commands/debug.d.ts +13 -0
  128. package/dist/commands/debug.d.ts.map +1 -0
  129. package/dist/commands/debug.js +138 -0
  130. package/dist/commands/debug.js.map +1 -0
  131. package/dist/commands/deploy-helpers.d.ts +49 -18
  132. package/dist/commands/deploy-helpers.d.ts.map +1 -1
  133. package/dist/commands/deploy-helpers.js +10 -276
  134. package/dist/commands/deploy-helpers.js.map +1 -1
  135. package/dist/commands/deploy.d.ts +0 -1
  136. package/dist/commands/deploy.d.ts.map +1 -1
  137. package/dist/commands/deploy.js +21 -217
  138. package/dist/commands/deploy.js.map +1 -1
  139. package/dist/commands/errors.d.ts +11 -0
  140. package/dist/commands/errors.d.ts.map +1 -0
  141. package/dist/commands/errors.js +177 -0
  142. package/dist/commands/errors.js.map +1 -0
  143. package/dist/commands/eval.d.ts +152 -0
  144. package/dist/commands/eval.d.ts.map +1 -0
  145. package/dist/commands/eval.js +690 -0
  146. package/dist/commands/eval.js.map +1 -0
  147. package/dist/commands/extension.d.ts +12 -0
  148. package/dist/commands/extension.d.ts.map +1 -0
  149. package/dist/commands/extension.js +30 -0
  150. package/dist/commands/extension.js.map +1 -0
  151. package/dist/commands/game-benchmark.d.ts +34 -0
  152. package/dist/commands/game-benchmark.d.ts.map +1 -0
  153. package/dist/commands/game-benchmark.js +95 -0
  154. package/dist/commands/game-benchmark.js.map +1 -0
  155. package/dist/commands/game-smoke.d.ts +3 -0
  156. package/dist/commands/game-smoke.d.ts.map +1 -0
  157. package/dist/commands/game-smoke.js +23 -0
  158. package/dist/commands/game-smoke.js.map +1 -0
  159. package/dist/commands/game.d.ts +4 -0
  160. package/dist/commands/game.d.ts.map +1 -0
  161. package/dist/commands/game.js +624 -0
  162. package/dist/commands/game.js.map +1 -0
  163. package/dist/commands/generate.d.ts +17 -0
  164. package/dist/commands/generate.d.ts.map +1 -0
  165. package/dist/commands/generate.js +324 -0
  166. package/dist/commands/generate.js.map +1 -0
  167. package/dist/commands/generations.d.ts +17 -0
  168. package/dist/commands/generations.d.ts.map +1 -0
  169. package/dist/commands/generations.js +408 -0
  170. package/dist/commands/generations.js.map +1 -0
  171. package/dist/commands/harness.d.ts +69 -0
  172. package/dist/commands/harness.d.ts.map +1 -0
  173. package/dist/commands/harness.js +575 -0
  174. package/dist/commands/harness.js.map +1 -0
  175. package/dist/commands/js-script-validation-output.d.ts +7 -0
  176. package/dist/commands/js-script-validation-output.d.ts.map +1 -0
  177. package/dist/commands/js-script-validation-output.js +5 -0
  178. package/dist/commands/js-script-validation-output.js.map +1 -0
  179. package/dist/commands/js-script-versions.d.ts +53 -0
  180. package/dist/commands/js-script-versions.d.ts.map +1 -0
  181. package/dist/commands/js-script-versions.js +89 -0
  182. package/dist/commands/js-script-versions.js.map +1 -0
  183. package/dist/commands/js-script.d.ts +29 -0
  184. package/dist/commands/js-script.d.ts.map +1 -0
  185. package/dist/commands/js-script.js +211 -0
  186. package/dist/commands/js-script.js.map +1 -0
  187. package/dist/commands/jtbd.d.ts +38 -0
  188. package/dist/commands/jtbd.d.ts.map +1 -0
  189. package/dist/commands/jtbd.js +261 -0
  190. package/dist/commands/jtbd.js.map +1 -0
  191. package/dist/commands/local-db.d.ts +16 -0
  192. package/dist/commands/local-db.d.ts.map +1 -0
  193. package/dist/commands/local-db.js +33 -0
  194. package/dist/commands/local-db.js.map +1 -0
  195. package/dist/commands/mcp.d.ts +21 -0
  196. package/dist/commands/mcp.d.ts.map +1 -0
  197. package/dist/commands/mcp.js +164 -0
  198. package/dist/commands/mcp.js.map +1 -0
  199. package/dist/commands/migrate-code-inputs.d.ts +24 -0
  200. package/dist/commands/migrate-code-inputs.d.ts.map +1 -0
  201. package/dist/commands/migrate-code-inputs.js +120 -0
  202. package/dist/commands/migrate-code-inputs.js.map +1 -0
  203. package/dist/commands/models-hf.js +4 -4
  204. package/dist/commands/models-hf.js.map +1 -1
  205. package/dist/commands/models-recommended.d.ts.map +1 -1
  206. package/dist/commands/models-recommended.js +16 -24
  207. package/dist/commands/models-recommended.js.map +1 -1
  208. package/dist/commands/node.d.ts +10 -0
  209. package/dist/commands/node.d.ts.map +1 -0
  210. package/dist/commands/node.js +72 -0
  211. package/dist/commands/node.js.map +1 -0
  212. package/dist/commands/output.d.ts +24 -0
  213. package/dist/commands/output.d.ts.map +1 -0
  214. package/dist/commands/output.js +132 -0
  215. package/dist/commands/output.js.map +1 -0
  216. package/dist/commands/package-helpers.d.ts +1 -7
  217. package/dist/commands/package-helpers.d.ts.map +1 -1
  218. package/dist/commands/package-helpers.js +3 -26
  219. package/dist/commands/package-helpers.js.map +1 -1
  220. package/dist/commands/package.d.ts.map +1 -1
  221. package/dist/commands/package.js +14 -14
  222. package/dist/commands/package.js.map +1 -1
  223. package/dist/commands/packs.d.ts +13 -0
  224. package/dist/commands/packs.d.ts.map +1 -0
  225. package/dist/commands/packs.js +60 -0
  226. package/dist/commands/packs.js.map +1 -0
  227. package/dist/commands/reliability.d.ts +14 -0
  228. package/dist/commands/reliability.d.ts.map +1 -0
  229. package/dist/commands/reliability.js +80 -0
  230. package/dist/commands/reliability.js.map +1 -0
  231. package/dist/commands/resource-read.d.ts +28 -0
  232. package/dist/commands/resource-read.d.ts.map +1 -0
  233. package/dist/commands/resource-read.js +316 -0
  234. package/dist/commands/resource-read.js.map +1 -0
  235. package/dist/commands/runs.d.ts +7 -0
  236. package/dist/commands/runs.d.ts.map +1 -0
  237. package/dist/commands/runs.js +302 -0
  238. package/dist/commands/runs.js.map +1 -0
  239. package/dist/commands/sketch-validation-output.d.ts +7 -0
  240. package/dist/commands/sketch-validation-output.d.ts.map +1 -0
  241. package/dist/commands/sketch-validation-output.js +5 -0
  242. package/dist/commands/sketch-validation-output.js.map +1 -0
  243. package/dist/commands/sketch-versions.d.ts +66 -0
  244. package/dist/commands/sketch-versions.d.ts.map +1 -0
  245. package/dist/commands/sketch-versions.js +108 -0
  246. package/dist/commands/sketch-versions.js.map +1 -0
  247. package/dist/commands/sketch.d.ts +21 -0
  248. package/dist/commands/sketch.d.ts.map +1 -0
  249. package/dist/commands/sketch.js +101 -0
  250. package/dist/commands/sketch.js.map +1 -0
  251. package/dist/commands/storage.d.ts +24 -0
  252. package/dist/commands/storage.d.ts.map +1 -0
  253. package/dist/commands/storage.js +112 -0
  254. package/dist/commands/storage.js.map +1 -0
  255. package/dist/commands/telegram.d.ts +11 -0
  256. package/dist/commands/telegram.d.ts.map +1 -0
  257. package/dist/commands/telegram.js +66 -0
  258. package/dist/commands/telegram.js.map +1 -0
  259. package/dist/commands/timeline-render.d.ts +85 -0
  260. package/dist/commands/timeline-render.d.ts.map +1 -0
  261. package/dist/commands/timeline-render.js +474 -0
  262. package/dist/commands/timeline-render.js.map +1 -0
  263. package/dist/commands/timeline-score.d.ts +16 -0
  264. package/dist/commands/timeline-score.d.ts.map +1 -0
  265. package/dist/commands/timeline-score.js +89 -0
  266. package/dist/commands/timeline-score.js.map +1 -0
  267. package/dist/commands/timeline-validation-output.d.ts +7 -0
  268. package/dist/commands/timeline-validation-output.d.ts.map +1 -0
  269. package/dist/commands/timeline-validation-output.js +9 -0
  270. package/dist/commands/timeline-validation-output.js.map +1 -0
  271. package/dist/commands/timeline-versions.d.ts +72 -0
  272. package/dist/commands/timeline-versions.d.ts.map +1 -0
  273. package/dist/commands/timeline-versions.js +108 -0
  274. package/dist/commands/timeline-versions.js.map +1 -0
  275. package/dist/commands/timeline.d.ts +22 -0
  276. package/dist/commands/timeline.d.ts.map +1 -0
  277. package/dist/commands/timeline.js +105 -0
  278. package/dist/commands/timeline.js.map +1 -0
  279. package/dist/commands/validate.d.ts +22 -0
  280. package/dist/commands/validate.d.ts.map +1 -0
  281. package/dist/commands/validate.js +127 -0
  282. package/dist/commands/validate.js.map +1 -0
  283. package/dist/commands/validation-output.d.ts +25 -0
  284. package/dist/commands/validation-output.d.ts.map +1 -0
  285. package/dist/commands/validation-output.js +29 -0
  286. package/dist/commands/validation-output.js.map +1 -0
  287. package/dist/commands/version-commands.d.ts +94 -0
  288. package/dist/commands/version-commands.d.ts.map +1 -0
  289. package/dist/commands/version-commands.js +227 -0
  290. package/dist/commands/version-commands.js.map +1 -0
  291. package/dist/commands/worker-models.d.ts +13 -0
  292. package/dist/commands/worker-models.d.ts.map +1 -0
  293. package/dist/commands/worker-models.js +207 -0
  294. package/dist/commands/worker-models.js.map +1 -0
  295. package/dist/commands/worker.d.ts +23 -0
  296. package/dist/commands/worker.d.ts.map +1 -0
  297. package/dist/commands/worker.js +374 -0
  298. package/dist/commands/worker.js.map +1 -0
  299. package/dist/debug/browser-runner.d.ts +21 -0
  300. package/dist/debug/browser-runner.d.ts.map +1 -0
  301. package/dist/debug/browser-runner.js +196 -0
  302. package/dist/debug/browser-runner.js.map +1 -0
  303. package/dist/debug/collector.d.ts +9 -0
  304. package/dist/debug/collector.d.ts.map +1 -0
  305. package/dist/debug/collector.js +9 -0
  306. package/dist/debug/collector.js.map +1 -0
  307. package/dist/debug/diff.d.ts +48 -0
  308. package/dist/debug/diff.d.ts.map +1 -0
  309. package/dist/debug/diff.js +68 -0
  310. package/dist/debug/diff.js.map +1 -0
  311. package/dist/debug/harness.d.ts +11 -0
  312. package/dist/debug/harness.d.ts.map +1 -0
  313. package/dist/debug/harness.js +103 -0
  314. package/dist/debug/harness.js.map +1 -0
  315. package/dist/debug/index.d.ts +17 -0
  316. package/dist/debug/index.d.ts.map +1 -0
  317. package/dist/debug/index.js +16 -0
  318. package/dist/debug/index.js.map +1 -0
  319. package/dist/debug/markdown.d.ts +3 -0
  320. package/dist/debug/markdown.d.ts.map +1 -0
  321. package/dist/debug/markdown.js +127 -0
  322. package/dist/debug/markdown.js.map +1 -0
  323. package/dist/debug/server-runner.d.ts +24 -0
  324. package/dist/debug/server-runner.d.ts.map +1 -0
  325. package/dist/debug/server-runner.js +197 -0
  326. package/dist/debug/server-runner.js.map +1 -0
  327. package/dist/debug/target.d.ts +34 -0
  328. package/dist/debug/target.d.ts.map +1 -0
  329. package/dist/debug/target.js +104 -0
  330. package/dist/debug/target.js.map +1 -0
  331. package/dist/debug/trace.d.ts +30 -0
  332. package/dist/debug/trace.d.ts.map +1 -0
  333. package/dist/debug/trace.js +87 -0
  334. package/dist/debug/trace.js.map +1 -0
  335. package/dist/debug/types.d.ts +82 -0
  336. package/dist/debug/types.d.ts.map +1 -0
  337. package/dist/debug/types.js +13 -0
  338. package/dist/debug/types.js.map +1 -0
  339. package/dist/debug/verdict.d.ts +3 -0
  340. package/dist/debug/verdict.d.ts.map +1 -0
  341. package/dist/debug/verdict.js +78 -0
  342. package/dist/debug/verdict.js.map +1 -0
  343. package/dist/debug/watch.d.ts +23 -0
  344. package/dist/debug/watch.d.ts.map +1 -0
  345. package/dist/debug/watch.js +68 -0
  346. package/dist/debug/watch.js.map +1 -0
  347. package/dist/diagnose.d.ts +139 -0
  348. package/dist/diagnose.d.ts.map +1 -0
  349. package/dist/diagnose.js +418 -0
  350. package/dist/diagnose.js.map +1 -0
  351. package/dist/evals/graph-runner.d.ts +8 -0
  352. package/dist/evals/graph-runner.d.ts.map +1 -0
  353. package/dist/evals/graph-runner.js +136 -0
  354. package/dist/evals/graph-runner.js.map +1 -0
  355. package/dist/harness/capability-coverage.d.ts +161 -0
  356. package/dist/harness/capability-coverage.d.ts.map +1 -0
  357. package/dist/harness/capability-coverage.js +266 -0
  358. package/dist/harness/capability-coverage.js.map +1 -0
  359. package/dist/harness/capability-table.d.ts +17 -0
  360. package/dist/harness/capability-table.d.ts.map +1 -0
  361. package/dist/harness/capability-table.js +3844 -0
  362. package/dist/harness/capability-table.js.map +1 -0
  363. package/dist/harness/changed-files.d.ts +20 -0
  364. package/dist/harness/changed-files.d.ts.map +1 -0
  365. package/dist/harness/changed-files.js +90 -0
  366. package/dist/harness/changed-files.js.map +1 -0
  367. package/dist/harness/declared-capabilities.d.ts +12 -0
  368. package/dist/harness/declared-capabilities.d.ts.map +1 -0
  369. package/dist/harness/declared-capabilities.js +21 -0
  370. package/dist/harness/declared-capabilities.js.map +1 -0
  371. package/dist/harness/registry.d.ts +190 -0
  372. package/dist/harness/registry.d.ts.map +1 -0
  373. package/dist/harness/registry.js +2034 -0
  374. package/dist/harness/registry.js.map +1 -0
  375. package/dist/index.js +122 -131
  376. package/dist/index.js.map +1 -1
  377. package/dist/interaction-script.d.ts +40 -0
  378. package/dist/interaction-script.d.ts.map +1 -0
  379. package/dist/interaction-script.js +96 -0
  380. package/dist/interaction-script.js.map +1 -0
  381. package/dist/js-script-debug/harness.d.ts +124 -0
  382. package/dist/js-script-debug/harness.d.ts.map +1 -0
  383. package/dist/js-script-debug/harness.js +230 -0
  384. package/dist/js-script-debug/harness.js.map +1 -0
  385. package/dist/js-script-debug/index.d.ts +9 -0
  386. package/dist/js-script-debug/index.d.ts.map +1 -0
  387. package/dist/js-script-debug/index.js +9 -0
  388. package/dist/js-script-debug/index.js.map +1 -0
  389. package/dist/js-script-debug/interactions.d.ts +19 -0
  390. package/dist/js-script-debug/interactions.d.ts.map +1 -0
  391. package/dist/js-script-debug/interactions.js +17 -0
  392. package/dist/js-script-debug/interactions.js.map +1 -0
  393. package/dist/js-script-debug/target.d.ts +20 -0
  394. package/dist/js-script-debug/target.d.ts.map +1 -0
  395. package/dist/js-script-debug/target.js +78 -0
  396. package/dist/js-script-debug/target.js.map +1 -0
  397. package/dist/local-model-interfaces.d.ts +20 -0
  398. package/dist/local-model-interfaces.d.ts.map +1 -0
  399. package/dist/local-model-interfaces.js +41 -0
  400. package/dist/local-model-interfaces.js.map +1 -0
  401. package/dist/local-secrets.d.ts +3 -0
  402. package/dist/local-secrets.d.ts.map +1 -0
  403. package/dist/local-secrets.js +16 -0
  404. package/dist/local-secrets.js.map +1 -0
  405. package/dist/markdown.d.ts.map +1 -1
  406. package/dist/markdown.js +7 -2
  407. package/dist/markdown.js.map +1 -1
  408. package/dist/node/run-node.d.ts +28 -0
  409. package/dist/node/run-node.d.ts.map +1 -0
  410. package/dist/node/run-node.js +76 -0
  411. package/dist/node/run-node.js.map +1 -0
  412. package/dist/node-registry.d.ts +27 -0
  413. package/dist/node-registry.d.ts.map +1 -0
  414. package/dist/node-registry.js +33 -0
  415. package/dist/node-registry.js.map +1 -0
  416. package/dist/nodetool-main.d.ts +15 -0
  417. package/dist/nodetool-main.d.ts.map +1 -0
  418. package/dist/nodetool-main.js +1368 -0
  419. package/dist/nodetool-main.js.map +1 -0
  420. package/dist/nodetool.d.ts +0 -13
  421. package/dist/nodetool.d.ts.map +1 -1
  422. package/dist/nodetool.js +17 -1147
  423. package/dist/nodetool.js.map +1 -1
  424. package/dist/numeric-options.d.ts +22 -0
  425. package/dist/numeric-options.d.ts.map +1 -0
  426. package/dist/numeric-options.js +45 -0
  427. package/dist/numeric-options.js.map +1 -0
  428. package/dist/permission-gate.d.ts +55 -0
  429. package/dist/permission-gate.d.ts.map +1 -0
  430. package/dist/permission-gate.js +118 -0
  431. package/dist/permission-gate.js.map +1 -0
  432. package/dist/predicates.d.ts +6 -0
  433. package/dist/predicates.d.ts.map +1 -0
  434. package/dist/predicates.js +6 -0
  435. package/dist/predicates.js.map +1 -0
  436. package/dist/providers.d.ts +73 -10
  437. package/dist/providers.d.ts.map +1 -1
  438. package/dist/providers.js +339 -97
  439. package/dist/providers.js.map +1 -1
  440. package/dist/readline-input.d.ts +13 -19
  441. package/dist/readline-input.d.ts.map +1 -1
  442. package/dist/readline-input.js +201 -190
  443. package/dist/readline-input.js.map +1 -1
  444. package/dist/run-budget.d.ts +40 -0
  445. package/dist/run-budget.d.ts.map +1 -0
  446. package/dist/run-budget.js +119 -0
  447. package/dist/run-budget.js.map +1 -0
  448. package/dist/run-dsl-supervised.d.ts +11 -0
  449. package/dist/run-dsl-supervised.d.ts.map +1 -0
  450. package/dist/run-dsl-supervised.js +82 -0
  451. package/dist/run-dsl-supervised.js.map +1 -0
  452. package/dist/run-dsl.d.ts +29 -0
  453. package/dist/run-dsl.d.ts.map +1 -1
  454. package/dist/run-dsl.js +44 -10
  455. package/dist/run-dsl.js.map +1 -1
  456. package/dist/run-json.d.ts +24 -0
  457. package/dist/run-json.d.ts.map +1 -0
  458. package/dist/run-json.js +132 -0
  459. package/dist/run-json.js.map +1 -0
  460. package/dist/sandbox-catalog.d.ts +24 -0
  461. package/dist/sandbox-catalog.d.ts.map +1 -0
  462. package/dist/sandbox-catalog.js +78 -0
  463. package/dist/sandbox-catalog.js.map +1 -0
  464. package/dist/settings.d.ts +11 -10
  465. package/dist/settings.d.ts.map +1 -1
  466. package/dist/settings.js +71 -13
  467. package/dist/settings.js.map +1 -1
  468. package/dist/sketch-debug/harness.d.ts +87 -0
  469. package/dist/sketch-debug/harness.d.ts.map +1 -0
  470. package/dist/sketch-debug/harness.js +145 -0
  471. package/dist/sketch-debug/harness.js.map +1 -0
  472. package/dist/sketch-debug/index.d.ts +9 -0
  473. package/dist/sketch-debug/index.d.ts.map +1 -0
  474. package/dist/sketch-debug/index.js +9 -0
  475. package/dist/sketch-debug/index.js.map +1 -0
  476. package/dist/sketch-debug/interactions.d.ts +19 -0
  477. package/dist/sketch-debug/interactions.d.ts.map +1 -0
  478. package/dist/sketch-debug/interactions.js +17 -0
  479. package/dist/sketch-debug/interactions.js.map +1 -0
  480. package/dist/sketch-debug/target.d.ts +48 -0
  481. package/dist/sketch-debug/target.d.ts.map +1 -0
  482. package/dist/sketch-debug/target.js +138 -0
  483. package/dist/sketch-debug/target.js.map +1 -0
  484. package/dist/stdin.d.ts +18 -19
  485. package/dist/stdin.d.ts.map +1 -1
  486. package/dist/stdin.js +160 -157
  487. package/dist/stdin.js.map +1 -1
  488. package/dist/supervisor.d.ts +97 -0
  489. package/dist/supervisor.d.ts.map +1 -0
  490. package/dist/supervisor.js +194 -0
  491. package/dist/supervisor.js.map +1 -0
  492. package/dist/terminal-clipboard.d.ts +3 -0
  493. package/dist/terminal-clipboard.d.ts.map +1 -0
  494. package/dist/terminal-clipboard.js +24 -0
  495. package/dist/terminal-clipboard.js.map +1 -0
  496. package/dist/terminal-mouse.d.ts +24 -0
  497. package/dist/terminal-mouse.d.ts.map +1 -0
  498. package/dist/terminal-mouse.js +84 -0
  499. package/dist/terminal-mouse.js.map +1 -0
  500. package/dist/terminal-screen.d.ts +41 -0
  501. package/dist/terminal-screen.d.ts.map +1 -0
  502. package/dist/terminal-screen.js +228 -0
  503. package/dist/terminal-screen.js.map +1 -0
  504. package/dist/timeline-debug/harness.d.ts +79 -0
  505. package/dist/timeline-debug/harness.d.ts.map +1 -0
  506. package/dist/timeline-debug/harness.js +122 -0
  507. package/dist/timeline-debug/harness.js.map +1 -0
  508. package/dist/timeline-debug/index.d.ts +9 -0
  509. package/dist/timeline-debug/index.d.ts.map +1 -0
  510. package/dist/timeline-debug/index.js +9 -0
  511. package/dist/timeline-debug/index.js.map +1 -0
  512. package/dist/timeline-debug/interactions.d.ts +19 -0
  513. package/dist/timeline-debug/interactions.d.ts.map +1 -0
  514. package/dist/timeline-debug/interactions.js +17 -0
  515. package/dist/timeline-debug/interactions.js.map +1 -0
  516. package/dist/timeline-debug/target.d.ts +34 -0
  517. package/dist/timeline-debug/target.d.ts.map +1 -0
  518. package/dist/timeline-debug/target.js +132 -0
  519. package/dist/timeline-debug/target.js.map +1 -0
  520. package/dist/tool-format.d.ts +54 -0
  521. package/dist/tool-format.d.ts.map +1 -0
  522. package/dist/tool-format.js +360 -0
  523. package/dist/tool-format.js.map +1 -0
  524. package/dist/useExecutionState.d.ts.map +1 -1
  525. package/dist/useExecutionState.js +8 -4
  526. package/dist/useExecutionState.js.map +1 -1
  527. package/dist/validate/index.d.ts +28 -0
  528. package/dist/validate/index.d.ts.map +1 -0
  529. package/dist/validate/index.js +51 -0
  530. package/dist/validate/index.js.map +1 -0
  531. package/dist/websocket-client.d.ts +78 -15
  532. package/dist/websocket-client.d.ts.map +1 -1
  533. package/dist/websocket-client.js +497 -171
  534. package/dist/websocket-client.js.map +1 -1
  535. package/package.json +65 -31
@@ -1,21 +1,35 @@
1
1
  /**
2
- * `nodetool agent` — load YAML agent configs and run them with full trace output.
2
+ * `nodetool agent` — run one CodeAct turn over the default toolbelt, with full
3
+ * trace output.
4
+ *
5
+ * The loop is the chat's loop: the belt is assembled by `buildCliAgentBelt`
6
+ * and the turn by `createCliCodeActTurn`, both shared with `--stdin` chat, so
7
+ * the provider is offered `execute_code` and the toolbelt lives in the sandbox.
8
+ * `create_plan` and `execute_plan` are on the belt, so an objective that wants
9
+ * a plan gets one and the `planning_update` / `task_update` events stream.
3
10
  *
4
11
  * Subcommands:
5
- * nodetool agent run <yaml-file> [--objective "..."] [--mode loop|plan|multi-agent]
6
- * nodetool agent test <yaml-file> # validate config + dry list of tools/provider
7
- * nodetool agent list <dir> # list YAML configs in a directory
12
+ * nodetool agent run --objective "..." # objective may also come from stdin
13
+ * nodetool agent diagnose <job_id> # aggregate a failed run into a report
8
14
  */
9
15
  import * as fs from "node:fs";
10
16
  import * as fsp from "node:fs/promises";
11
17
  import * as path from "node:path";
12
- import * as yaml from "js-yaml";
13
18
  import chalk from "chalk";
14
- import { ProcessingContext } from "@nodetool-ai/runtime";
15
- import { MultiModeAgent, FindModelTool, GenerateImageTool, EditImageTool, GenerateVideoTool, AnimateImageTool, GenerateSpeechTool, TranscribeAudioTool, EmbedTextTool, ReadFileTool, WriteFileTool, ListDirectoryTool, EditFileTool, GlobTool, GrepTool, DownloadFileTool, HttpRequestTool, GoogleSearchTool, GoogleNewsTool, GoogleImagesTool, BrowserTool, ScreenshotTool, RunCodeTool, CalculatorTool, ExtractPDFTextTool, ConvertPDFToMarkdownTool, ConvertDocumentTool, StatisticsTool, GeometryTool, ConversionTool, OpenAIWebSearchTool, OpenAIImageGenerationTool, OpenAITextToSpeechTool, DataForSEOSearchTool, DataForSEONewsTool, SearchEmailTool, ArchiveEmailTool, getAllMcpTools } from "@nodetool-ai/agents";
16
- import { initDb, getSecret } from "@nodetool-ai/models";
19
+ import { RUN_BUDGET_CONTEXT_KEY } from "@nodetool-ai/runtime";
20
+ import { PERMISSION_GATE_CONTEXT_KEY } from "@nodetool-ai/agents";
21
+ import { processChat } from "@nodetool-ai/chat";
22
+ import { initDb } from "@nodetool-ai/models";
17
23
  import { getDefaultDbPath, configureLogging } from "@nodetool-ai/config";
18
24
  import { createProvider, buildConfiguredProviders } from "../providers.js";
25
+ import { buildFullRegistry } from "../node-registry.js";
26
+ import { buildCliToolbelt } from "../agent-toolbelt.js";
27
+ import { applySystemPrompt, buildCliAgentBelt, createCliCodeActTurn, loadCliSkillCatalog } from "../chat-codeact.js";
28
+ import { createChatContext } from "../chat-context.js";
29
+ import { budgetStopReason, budgetSummaryLine, createCliRunBudget } from "../run-budget.js";
30
+ import { createCliPermissionGate, parsePermissionMode, PERMISSION_MODE_NAMES } from "../permission-gate.js";
31
+ import { diagnoseRun, renderDiagnosis } from "../diagnose.js";
32
+ import { isRecord, isString } from "../predicates.js";
19
33
  const PROVIDER_ALIASES = {
20
34
  google: "gemini",
21
35
  googleai: "gemini",
@@ -31,94 +45,6 @@ function expandTilde(p) {
31
45
  }
32
46
  return p;
33
47
  }
34
- /**
35
- * FindModelTool that injects YAML-declared preferences as defaults when the
36
- * LLM omits explicit hints.
37
- */
38
- class PreferringFindModelTool extends FindModelTool {
39
- prefs;
40
- constructor(providers, prefs) {
41
- super(providers);
42
- this.prefs = prefs;
43
- }
44
- async process(context, params) {
45
- const merged = { ...params };
46
- const capability = typeof params["capability"] === "string"
47
- ? params["capability"]
48
- : undefined;
49
- if (typeof merged["provider_hint"] !== "string" &&
50
- this.prefs.preferredProviders &&
51
- this.prefs.preferredProviders.length > 0) {
52
- merged["provider_hint"] = this.prefs.preferredProviders[0];
53
- }
54
- if (capability && !merged["model_hint"]) {
55
- const pref = this.prefs.preferredModels?.[capability];
56
- if (pref && pref.length > 0) {
57
- merged["model_hint"] = pref;
58
- }
59
- }
60
- return super.process(context, merged);
61
- }
62
- }
63
- function buildToolMap(providers, prefs = {}) {
64
- const m = {
65
- find_model: new PreferringFindModelTool(providers ?? {}, prefs),
66
- generate_image: new GenerateImageTool(),
67
- edit_image: new EditImageTool(),
68
- generate_video: new GenerateVideoTool(),
69
- animate_image: new AnimateImageTool(),
70
- generate_speech: new GenerateSpeechTool(),
71
- transcribe_audio: new TranscribeAudioTool(),
72
- embed_text: new EmbedTextTool(),
73
- read_file: new ReadFileTool(),
74
- write_file: new WriteFileTool(),
75
- edit_file: new EditFileTool(),
76
- list_directory: new ListDirectoryTool(),
77
- glob: new GlobTool(),
78
- grep: new GrepTool(),
79
- download_file: new DownloadFileTool(),
80
- http_request: new HttpRequestTool(),
81
- google_search: new GoogleSearchTool(),
82
- google_news: new GoogleNewsTool(),
83
- google_images: new GoogleImagesTool(),
84
- browser: new BrowserTool(),
85
- screenshot: new ScreenshotTool(),
86
- run_code: new RunCodeTool(),
87
- calculator: new CalculatorTool(),
88
- statistics: new StatisticsTool(),
89
- geometry: new GeometryTool(),
90
- conversion: new ConversionTool(),
91
- extract_pdf_text: new ExtractPDFTextTool(),
92
- convert_pdf_to_markdown: new ConvertPDFToMarkdownTool(),
93
- convert_document: new ConvertDocumentTool(),
94
- openai_web_search: new OpenAIWebSearchTool(),
95
- openai_image_generation: new OpenAIImageGenerationTool(),
96
- openai_text_to_speech: new OpenAITextToSpeechTool(),
97
- dataseo_search: new DataForSEOSearchTool(),
98
- dataseo_news: new DataForSEONewsTool(),
99
- search_email: new SearchEmailTool(),
100
- archive_email: new ArchiveEmailTool()
101
- };
102
- for (const tool of getAllMcpTools({ providers })) {
103
- m[tool.name] = tool;
104
- }
105
- return m;
106
- }
107
- function resolveTools(names, providers, prefs = {}) {
108
- if (!names || names.length === 0)
109
- return { tools: [], unknown: [] };
110
- const map = buildToolMap(providers, prefs);
111
- const tools = [];
112
- const unknown = [];
113
- for (const name of names) {
114
- const tool = map[name];
115
- if (tool)
116
- tools.push(tool);
117
- else
118
- unknown.push(name);
119
- }
120
- return { tools, unknown };
121
- }
122
48
  function shorten(s, n = 200) {
123
49
  const oneLine = s.replace(/\s+/g, " ").trim();
124
50
  return oneLine.length > n ? oneLine.slice(0, n) + "…" : oneLine;
@@ -156,8 +82,10 @@ function traceEvent(msg, opts) {
156
82
  break;
157
83
  }
158
84
  case "step_result": {
159
- const tag = msg.is_task_result ? chalk.green("result★") : chalk.green("step✓ ");
160
- const preview = typeof msg.result === "string"
85
+ const tag = msg.is_task_result
86
+ ? chalk.green("result★")
87
+ : chalk.green("step✓ ");
88
+ const preview = isString(msg.result)
161
89
  ? shorten(msg.result, 200)
162
90
  : shorten(JSON.stringify(msg.result ?? null), 200);
163
91
  process.stderr.write(`${t} ${tag} ${preview}\n`);
@@ -166,7 +94,7 @@ function traceEvent(msg, opts) {
166
94
  break;
167
95
  }
168
96
  case "chunk":
169
- if (opts.verbose && msg.content) {
97
+ if (opts.verbose && isString(msg.content)) {
170
98
  process.stderr.write(`${t} ${chalk.gray("chunk")} ${shorten(msg.content, 80)}\n`);
171
99
  }
172
100
  break;
@@ -180,16 +108,8 @@ function traceEvent(msg, opts) {
180
108
  }
181
109
  }
182
110
  // ---------------------------------------------------------------------------
183
- // Loaders
111
+ // run subcommand
184
112
  // ---------------------------------------------------------------------------
185
- async function loadAgentYaml(file) {
186
- const raw = await fsp.readFile(file, "utf-8");
187
- const parsed = yaml.load(raw);
188
- if (!parsed || typeof parsed !== "object") {
189
- throw new Error(`YAML did not parse to an object: ${file}`);
190
- }
191
- return parsed;
192
- }
193
113
  async function readObjectiveFromStdin() {
194
114
  if (process.stdin.isTTY)
195
115
  return null;
@@ -200,7 +120,20 @@ async function readObjectiveFromStdin() {
200
120
  const text = Buffer.concat(chunks).toString("utf-8").trim();
201
121
  return text || null;
202
122
  }
203
- async function runAgentCommand(file, opts) {
123
+ /** The text the run answers with: the last assistant message that carries any. */
124
+ function finalAssistantText(messages) {
125
+ for (let i = messages.length - 1; i >= 0; i--) {
126
+ const message = messages[i];
127
+ if (message.role !== "assistant")
128
+ continue;
129
+ if (isString(message.content) && message.content.trim()) {
130
+ return message.content;
131
+ }
132
+ }
133
+ return null;
134
+ }
135
+ /** Exit code for the process: 0 when the turn finished without an error. */
136
+ export async function runAgentCommand(opts) {
204
137
  // Quiet the runtime's INFO logger so it doesn't interleave the trace.
205
138
  // Users who want raw logs can set NODETOOL_LOG_LEVEL=info before running.
206
139
  if (!process.env["NODETOOL_LOG_LEVEL"]) {
@@ -214,253 +147,339 @@ async function runAgentCommand(file, opts) {
214
147
  catch {
215
148
  /* fallback to env vars */
216
149
  }
217
- const cfg = await loadAgentYaml(file);
218
- // Resolve provider/model (CLI flags override YAML)
219
- const providerId = opts.provider ?? normalizeProvider(cfg.model?.provider ?? "");
220
- if (!providerId) {
221
- throw new Error("No provider specified. Set `model.provider` in YAML or use --provider.");
150
+ if (!opts.provider) {
151
+ throw new Error("No provider specified. Use --provider <id>.");
222
152
  }
223
- const modelId = opts.model ?? cfg.model?.id;
153
+ const providerId = normalizeProvider(opts.provider);
154
+ const modelId = opts.model;
224
155
  if (!modelId) {
225
- throw new Error("No model specified. Set `model.id` in YAML or use --model.");
156
+ throw new Error("No model specified. Use --model <id>.");
226
157
  }
227
- // Resolve objective: --objective > stdin > YAML default
228
- const stdinObjective = await readObjectiveFromStdin();
229
- const objective = opts.objective ?? stdinObjective ?? cfg.objective;
158
+ const objective = opts.objective ?? (await readObjectiveFromStdin());
230
159
  if (!objective) {
231
- throw new Error("No objective provided. Use --objective \"...\", pipe via stdin, or set `objective:` in YAML.");
160
+ throw new Error('No objective provided. Use --objective "..." or pipe it via stdin.');
232
161
  }
233
162
  // Configured providers (for find_model + media tool dispatch)
234
163
  const configuredProviders = await buildConfiguredProviders();
235
- // Preferences from YAML (preferred_providers, preferred_models)
236
- const prefs = {};
237
- if (Array.isArray(cfg.preferred_providers)) {
238
- prefs.preferredProviders = cfg.preferred_providers.filter((x) => typeof x === "string");
239
- }
240
- if (cfg.preferred_models && typeof cfg.preferred_models === "object") {
241
- prefs.preferredModels = {};
242
- for (const [cap, val] of Object.entries(cfg.preferred_models)) {
243
- const list = typeof val === "string" ? [val] : Array.isArray(val) ? val : [];
244
- const cleaned = list.filter((x) => typeof x === "string");
245
- if (cleaned.length > 0)
246
- prefs.preferredModels[cap] = cleaned;
247
- }
248
- }
249
- // Tools
250
- const { tools, unknown } = resolveTools(cfg.tools, configuredProviders, prefs);
251
- if (unknown.length > 0) {
252
- process.stderr.write(chalk.yellow(`warn: ignoring unknown tools: ${unknown.join(", ")}\n`));
253
- }
254
- // Workspace
255
- const workspaceDir = expandTilde(opts.workspace ?? cfg.workspace?.path ?? process.cwd());
256
- if (cfg.workspace?.auto_create !== false) {
257
- try {
258
- fs.mkdirSync(workspaceDir, { recursive: true });
259
- }
260
- catch {
261
- /* ignore */
262
- }
164
+ const workspaceDir = expandTilde(opts.workspace ?? process.cwd());
165
+ try {
166
+ fs.mkdirSync(workspaceDir, { recursive: true });
263
167
  }
264
- // Mode
265
- const modeArg = (opts.mode ?? cfg.mode ?? "plan");
266
- if (!["loop", "plan", "multi-agent"].includes(modeArg)) {
267
- throw new Error(`Invalid mode: ${modeArg}. Use loop|plan|multi-agent.`);
168
+ catch {
169
+ /* ignore — an existing dir is the common case */
268
170
  }
269
171
  const provider = await createProvider(providerId);
270
- // Header
271
- if (!opts.json) {
272
- process.stderr.write(chalk.bold(`\n▸ ${cfg.name ?? path.basename(file)}\n`) +
273
- chalk.gray(` provider=${providerId} model=${modelId} mode=${modeArg} tools=${tools.length}\n`) +
274
- chalk.gray(` objective: ${shorten(objective, 200)}\n\n`));
275
- }
276
- const planningModel = cfg.planning_agent?.enabled === false ? modelId : cfg.planning_agent?.model?.id ?? modelId;
277
- // Build the effective system prompt: user prompt + a preferences block so
278
- // the LLM also "knows" which providers/models to favor (in addition to the
279
- // hint injection inside FindModelTool).
280
- const prefLines = [];
281
- if (prefs.preferredProviders && prefs.preferredProviders.length > 0) {
282
- prefLines.push(`Preferred providers (in order): ${prefs.preferredProviders.join(", ")}.`);
172
+ const context = await createChatContext({ workspaceDir });
173
+ // Hand the context the instances already configured above, so a tool that
174
+ // dispatches by provider id gets this run's provider rather than resolving a
175
+ // second one of its own.
176
+ for (const [id, configured] of Object.entries(configuredProviders)) {
177
+ context.registerProvider(id, configured);
283
178
  }
284
- if (prefs.preferredModels) {
285
- for (const [cap, list] of Object.entries(prefs.preferredModels)) {
286
- prefLines.push(`Preferred ${cap} model: ${list.join(" or ")}.`);
179
+ const traceOpts = {
180
+ json: !!opts.json,
181
+ verbose: !!opts.verbose
182
+ };
183
+ const emit = (message) => {
184
+ traceEvent(message, traceOpts);
185
+ };
186
+ // The run's gate, built once. `readObjectiveFromStdin` already returned null
187
+ // on a TTY, so the same test says whether anyone is there to answer a
188
+ // prompt: an objective that arrived down a pipe leaves nobody at the
189
+ // keyboard, and the run gates headless with the notice below.
190
+ const gate = createCliPermissionGate({
191
+ hostName: "nodetool agent run",
192
+ mode: parsePermissionMode(opts.permissionMode),
193
+ interactive: process.stdin.isTTY === true,
194
+ // In `--json` the notice and any prompt ride the event stream, so it stays
195
+ // one JSON object per line.
196
+ write: (text) => {
197
+ if (opts.json) {
198
+ emit({
199
+ type: "log_update",
200
+ node_id: "agent",
201
+ node_name: "permissions",
202
+ content: text,
203
+ severity: "info"
204
+ });
205
+ }
206
+ else {
207
+ process.stderr.write(chalk.gray(`${text}\n`));
208
+ }
287
209
  }
288
- }
289
- const effectiveSystemPrompt = prefLines.length > 0
290
- ? `${cfg.system_prompt ?? ""}\n\n# Model Preferences\n${prefLines.join("\n")}\nUse these when calling find_model unless they cannot satisfy the request.`.trim()
291
- : cfg.system_prompt;
292
- const agent = new MultiModeAgent({
293
- name: cfg.name ?? "yaml-agent",
294
- objective,
210
+ });
211
+ // Loops this command never constructs — an `AgentNode` reached through
212
+ // `run_node`, a JS script — read the gate off the context rather than
213
+ // building an ungated run of their own (`gateFromContext`, invariant I-1).
214
+ context.set(PERMISSION_GATE_CONTEXT_KEY, gate);
215
+ // The bounds this run shares downward, created once (invariant I-2). The
216
+ // same channel the gate takes: a loop this command never constructs reads
217
+ // the budget off the context instead of opening an allowance of its own.
218
+ const budget = await createCliRunBudget({
219
+ ...(opts.costCap !== undefined && { costCap: opts.costCap }),
220
+ ...(opts.timeout !== undefined && { timeout: opts.timeout })
221
+ });
222
+ context.set(RUN_BUDGET_CONTEXT_KEY, budget);
223
+ // One belt, every run. A narrowing flag made each invocation its own
224
+ // configuration — the thing YAML configs were removed for — and an agent
225
+ // run that behaves differently from the last one is not reproducible.
226
+ const belt = buildCliAgentBelt({
227
+ baseTools: buildCliToolbelt(configuredProviders, buildFullRegistry()),
295
228
  provider,
296
229
  model: modelId,
297
- mode: modeArg,
298
- tools,
299
- systemPrompt: effectiveSystemPrompt,
300
- maxTokenLimit: cfg.max_tokens,
301
- maxIterations: cfg.max_iterations,
302
- maxSteps: cfg.max_steps,
303
- planningModel
230
+ forwardMessage: emit,
231
+ gate,
232
+ // An objective is a job, not a conversation: the two plan capabilities are
233
+ // on the belt so the model can decompose one and run the DAG itself.
234
+ planning: true,
235
+ budget
304
236
  });
305
- const ctx = new ProcessingContext({
306
- jobId: `agent-${Date.now()}`,
307
- userId: "1",
308
- workspaceDir,
309
- secretResolver: getSecret
310
- });
311
- for (const [id, p] of Object.entries(configuredProviders)) {
312
- ctx.registerProvider(id, p);
237
+ if (!opts.json) {
238
+ process.stderr.write(chalk.bold(`\n▸ agent\n`) +
239
+ chalk.gray(` provider=${providerId} model=${modelId} tools=${belt.length}\n`) +
240
+ chalk.gray(` objective: ${shorten(objective, 200)}\n\n`));
313
241
  }
314
- const traceOpts = {
315
- json: !!opts.json,
316
- verbose: !!opts.verbose
317
- };
318
- let finalText = null;
242
+ const turn = createCliCodeActTurn({
243
+ tools: belt,
244
+ context,
245
+ skillCatalog: await loadCliSkillCatalog(context.userId),
246
+ // Calls the sandbox makes have no provider tool-call id of their own.
247
+ onToolCall: ({ name, args }) => {
248
+ emit({ type: "tool_call_update", name, args });
249
+ }
250
+ });
251
+ const messages = [];
252
+ applySystemPrompt(messages, turn.systemPrompt);
319
253
  let errored = false;
320
254
  try {
321
- for await (const msg of agent.execute(ctx)) {
322
- traceEvent(msg, traceOpts);
323
- if (msg.type === "step_result") {
324
- const sr = msg;
325
- if (sr.is_task_result) {
326
- finalText =
327
- typeof sr.result === "string"
328
- ? sr.result
329
- : JSON.stringify(sr.result, null, 2);
255
+ await processChat({
256
+ userInput: objective,
257
+ messages,
258
+ model: modelId,
259
+ provider,
260
+ context,
261
+ tools: turn.tools,
262
+ turnBudget: budget,
263
+ maxIterations: opts.maxIterations === undefined ? undefined : Number(opts.maxIterations),
264
+ callbacks: {
265
+ onChunk: (content) => {
266
+ emit({ type: "chunk", content, done: false });
267
+ },
268
+ onToolCall: (call) => {
269
+ emit({
270
+ type: "tool_call_update",
271
+ name: call.name,
272
+ args: call.args,
273
+ tool_call_id: call.id
274
+ });
275
+ },
276
+ onToolResult: (call, result) => {
277
+ emit({
278
+ type: "tool_result_update",
279
+ node_id: "agent",
280
+ name: call.name,
281
+ tool_call_id: call.id,
282
+ result: isRecord(result) ? result : { value: result }
283
+ });
330
284
  }
331
285
  }
332
- else if (msg.type === "error") {
333
- errored = true;
334
- }
335
- }
286
+ });
336
287
  }
337
288
  catch (e) {
338
289
  errored = true;
339
- process.stderr.write(chalk.red(`\nagent failed: ${String(e)}\n`));
340
- }
341
- if (finalText === null) {
342
- const r = agent.getResults();
343
- if (r != null) {
344
- finalText = typeof r === "string" ? r : JSON.stringify(r, null, 2);
290
+ const message = e instanceof Error ? e.message : String(e);
291
+ emit({ type: "error", message });
292
+ if (!opts.json) {
293
+ process.stderr.write(chalk.red(`\nagent failed: ${message}\n`));
345
294
  }
346
295
  }
296
+ const finalText = finalAssistantText(messages);
347
297
  if (!opts.json)
348
298
  process.stderr.write(chalk.bold("\n— result —\n"));
349
299
  if (finalText)
350
300
  process.stdout.write(finalText + "\n");
351
- process.exit(errored ? 1 : 0);
352
- }
353
- // ---------------------------------------------------------------------------
354
- // test subcommand — validate config without running
355
- // ---------------------------------------------------------------------------
356
- async function testAgentCommand(file) {
357
- if (!process.env["NODETOOL_LOG_LEVEL"]) {
358
- process.env["NODETOOL_LOG_LEVEL"] = "error";
359
- }
360
- configureLogging();
361
- try {
362
- initDb(getDefaultDbPath());
301
+ // What the whole run — this loop plus every sub-agent and node it started —
302
+ // committed against the shared cap.
303
+ const summary = budgetSummaryLine(budget);
304
+ if (opts.json) {
305
+ emit({
306
+ type: "log_update",
307
+ node_id: "agent",
308
+ node_name: "budget",
309
+ content: summary,
310
+ severity: "info"
311
+ });
312
+ }
313
+ else {
314
+ process.stderr.write(chalk.gray(`\n${summary}\n`));
315
+ }
316
+ // A ceiling ended the run, not the model finishing its answer. Said nowhere,
317
+ // the two are indistinguishable from an empty transcript (invariant I-3), so
318
+ // the reason is reported before anything else about how the run ended.
319
+ const stopReason = budgetStopReason(budget);
320
+ if (!errored && stopReason) {
321
+ emit({ type: "error", message: stopReason });
322
+ if (!opts.json) {
323
+ process.stderr.write(chalk.red(`\nagent stopped: ${stopReason}\n`));
324
+ }
325
+ return 1;
326
+ }
327
+ // A run that ended on a tool call or a contentless assistant turn produced
328
+ // no answer. Writing nothing and exiting 0 is indistinguishable from an
329
+ // empty-but-successful result, so it fails instead (invariant I-3).
330
+ if (!errored && !finalText) {
331
+ const message = "agent produced no answer: the turn ended without a final assistant message";
332
+ emit({ type: "error", message });
333
+ if (!opts.json) {
334
+ process.stderr.write(chalk.red(`\nagent failed: ${message}\n`));
335
+ }
336
+ return 1;
363
337
  }
364
- catch {
365
- /* fallback to env vars */
338
+ return errored ? 1 : 0;
339
+ }
340
+ /** Parse a JSONL file into one parsed object per non-blank line. */
341
+ async function readJsonl(file) {
342
+ const text = await fsp.readFile(file, "utf-8");
343
+ const out = [];
344
+ for (const line of text.split("\n")) {
345
+ const trimmed = line.trim();
346
+ if (!trimmed)
347
+ continue;
348
+ try {
349
+ // SAFETY: each caller names the record shape its own bundle file was
350
+ // written with — this reader only splits lines and parses JSON.
351
+ out.push(JSON.parse(trimmed));
352
+ }
353
+ catch {
354
+ // Skip partial/corrupt lines (e.g. a crash mid-write).
355
+ }
366
356
  }
367
- const cfg = await loadAgentYaml(file);
368
- const issues = [];
369
- const okLines = [];
370
- okLines.push(`name: ${cfg.name ?? "(unset)"}`);
371
- okLines.push(`description: ${cfg.description ?? "(unset)"}`);
372
- const provider = cfg.model?.provider;
373
- if (!provider)
374
- issues.push("missing model.provider");
375
- else
376
- okLines.push(`provider: ${provider} → ${normalizeProvider(provider)}`);
377
- if (!cfg.model?.id)
378
- issues.push("missing model.id");
379
- else
380
- okLines.push(`model: ${cfg.model.id}`);
381
- okLines.push(`mode: ${cfg.mode ?? "plan (default)"}`);
382
- okLines.push(`system_prompt: ${cfg.system_prompt ? `${cfg.system_prompt.length} chars` : "(none)"}`);
383
- const { tools, unknown } = resolveTools(cfg.tools);
384
- okLines.push(`tools resolved: ${tools.map((t) => t.name).join(", ") || "(none)"}`);
385
- if (unknown.length > 0)
386
- issues.push(`unknown tools: ${unknown.join(", ")}`);
387
- // Check provider can be instantiated
388
- if (provider) {
357
+ return out;
358
+ }
359
+ /** First existing path among the candidates, or null. */
360
+ function firstExisting(candidates) {
361
+ for (const p of candidates) {
389
362
  try {
390
- await createProvider(normalizeProvider(provider));
391
- okLines.push(`provider instantiation: ok`);
363
+ if (fs.statSync(p).isFile())
364
+ return p;
392
365
  }
393
- catch (e) {
394
- issues.push(`provider instantiation failed: ${String(e)}`);
366
+ catch {
367
+ // Not a readable file — try the next candidate.
395
368
  }
396
369
  }
397
- process.stdout.write(chalk.bold(`\n▸ ${path.basename(file)}\n\n`));
398
- for (const line of okLines)
399
- process.stdout.write(` ${chalk.green("✓")} ${line}\n`);
400
- for (const issue of issues)
401
- process.stdout.write(` ${chalk.red("✗")} ${issue}\n`);
402
- process.stdout.write("\n");
403
- process.exit(issues.length > 0 ? 1 : 0);
370
+ return null;
404
371
  }
405
- // ---------------------------------------------------------------------------
406
- // list subcommand
407
- // ---------------------------------------------------------------------------
408
- async function listAgentsCommand(dir) {
409
- const abs = path.resolve(expandTilde(dir));
372
+ /**
373
+ * Locate a debug bundle directory for a job id. The `debug` command writes
374
+ * bundles to `nodetool-debug/<id>-<timestamp>/`; we pick the most recent dir
375
+ * whose name starts with the id, relative to cwd.
376
+ */
377
+ function findDebugBundle(jobId) {
378
+ const root = path.join(process.cwd(), "nodetool-debug");
410
379
  let entries;
411
380
  try {
412
- entries = await fsp.readdir(abs, { withFileTypes: true });
381
+ entries = fs.readdirSync(root, { withFileTypes: true });
413
382
  }
414
- catch (e) {
415
- process.stderr.write(`Cannot read ${abs}: ${String(e)}\n`);
416
- process.exit(1);
383
+ catch {
384
+ return null;
417
385
  }
418
- const yamls = entries.filter((e) => e.isFile() && (e.name.endsWith(".yaml") || e.name.endsWith(".yml")));
419
- if (yamls.length === 0) {
420
- process.stdout.write(`(no YAML configs in ${abs})\n`);
421
- return;
386
+ const matches = entries
387
+ .filter((e) => e.isDirectory() && e.name.startsWith(`${jobId}-`))
388
+ .map((e) => path.join(root, e.name))
389
+ .sort();
390
+ return matches.length > 0 ? matches[matches.length - 1] : null;
391
+ }
392
+ /** Fetch a job record over the tRPC API; null when unreachable/not found. */
393
+ async function fetchJob(apiUrl, jobId) {
394
+ try {
395
+ const { createApiClient } = await import("../api-client.js");
396
+ const client = createApiClient(apiUrl);
397
+ const data = await client.jobs.get.query({ id: jobId });
398
+ return {
399
+ id: isString(data["id"]) ? data["id"] : jobId,
400
+ status: isString(data["status"]) ? data["status"] : undefined,
401
+ error: isString(data["error"]) ? data["error"] : null,
402
+ workflowId: isString(data["workflow_id"]) ? data["workflow_id"] : null
403
+ };
404
+ }
405
+ catch {
406
+ // Server unreachable or job missing — diagnose degrades on a null job.
407
+ return null;
422
408
  }
423
- for (const e of yamls) {
424
- const file = path.join(abs, e.name);
409
+ }
410
+ async function diagnoseCommand(jobId, opts) {
411
+ const apiUrl = opts.apiUrl ?? process.env["NODETOOL_API_URL"] ?? "http://localhost:7777";
412
+ const inputs = {};
413
+ // Job record (best-effort over the API).
414
+ const job = await fetchJob(apiUrl, jobId);
415
+ if (job)
416
+ inputs.job = job;
417
+ else
418
+ inputs.job = { id: jobId };
419
+ // Messages + trace from a debug bundle (when one exists for this job).
420
+ const bundle = findDebugBundle(jobId);
421
+ if (bundle) {
422
+ const messagesPath = firstExisting([
423
+ path.join(bundle, "server", "messages.jsonl")
424
+ ]);
425
+ if (messagesPath) {
426
+ try {
427
+ inputs.messages = await readJsonl(messagesPath);
428
+ }
429
+ catch {
430
+ // Unreadable — leave messages unset so the report flags it missing.
431
+ }
432
+ }
433
+ }
434
+ // Trace spans: --trace-file > NODETOOL_TRACE_FILE > the bundle's trace.jsonl.
435
+ const tracePath = firstExisting([
436
+ opts.traceFile,
437
+ process.env["NODETOOL_TRACE_FILE"],
438
+ bundle ? path.join(bundle, "server", "trace.jsonl") : undefined
439
+ ].filter((p) => p != null));
440
+ if (tracePath) {
425
441
  try {
426
- const cfg = await loadAgentYaml(file);
427
- process.stdout.write(`${chalk.bold(e.name)} ${chalk.gray(cfg.model?.provider ?? "?")}/${chalk.gray(cfg.model?.id ?? "?")}\n ${cfg.description ?? "(no description)"}\n`);
442
+ inputs.spans = await readJsonl(tracePath);
428
443
  }
429
- catch (err) {
430
- process.stdout.write(`${e.name} ${chalk.red("invalid: " + String(err))}\n`);
444
+ catch {
445
+ // Unreadable — report flags trace as missing.
431
446
  }
432
447
  }
448
+ const report = diagnoseRun(inputs);
449
+ if (opts.json) {
450
+ process.stdout.write(JSON.stringify(report, null, 2) + "\n");
451
+ }
452
+ else {
453
+ process.stdout.write(renderDiagnosis(report) + "\n");
454
+ }
455
+ process.exit(report.ok ? 0 : 1);
433
456
  }
434
457
  // ---------------------------------------------------------------------------
435
458
  // Registration
436
459
  // ---------------------------------------------------------------------------
437
460
  export function registerAgentCommands(program) {
438
- const agent = program.command("agent").description("Run YAML-defined agents");
461
+ const agent = program
462
+ .command("agent")
463
+ .description("Run the agent loop from the command line");
439
464
  agent
440
- .command("run <yaml-file>")
441
- .description("Run an agent from a YAML config (objective via --objective or stdin)")
442
- .option("-o, --objective <text>", "Objective for the agent (overrides stdin/yaml default)")
443
- .option("--mode <mode>", "Override mode: loop|plan|multi-agent")
444
- .option("-p, --provider <id>", "Override provider")
445
- .option("-m, --model <id>", "Override model")
446
- .option("-w, --workspace <path>", "Override workspace dir")
465
+ .command("run")
466
+ .description("Run an agent over the default toolbelt (objective via --objective or stdin)")
467
+ .option("-o, --objective <text>", "Objective for the agent")
468
+ .option("-p, --provider <id>", "Provider id")
469
+ .option("-m, --model <id>", "Model id")
470
+ .option("-w, --workspace <path>", "Workspace dir (default: cwd)")
471
+ .option("--max-iterations <n>", "Tool-calling rounds in the turn (default 25)")
472
+ .option("--permission-mode <mode>", `Permission mode (${PERMISSION_MODE_NAMES.join(" | ")}); on a TTY the ` +
473
+ "default asks before each write, execute or external call")
474
+ .option("--cost-cap <usd>", "Ceiling on provider spend for the whole run, shared by every loop it " +
475
+ "starts; 0 lifts it (default: NODETOOL_AGENT_TURN_COST_CAP_USD)")
476
+ .option("--timeout <s>", "Wall-clock bound on the run in seconds; 0 leaves it no time at all " +
477
+ "(default: NODETOOL_AGENT_TURN_DEADLINE_MS)")
447
478
  .option("--json", "Emit each event as a JSON line on stderr")
448
479
  .option("-v, --verbose", "Include chunk/other low-level events in trace")
449
- .action(async (file, opts) => {
450
- try {
451
- await runAgentCommand(file, opts);
452
- }
453
- catch (e) {
454
- process.stderr.write(chalk.red(`error: ${String(e)}\n`));
455
- process.exit(1);
456
- }
457
- });
458
- agent
459
- .command("test <yaml-file>")
460
- .description("Validate an agent YAML config (provider, model, tools)")
461
- .action(async (file) => {
480
+ .action(async (opts) => {
462
481
  try {
463
- await testAgentCommand(file);
482
+ process.exit(await runAgentCommand(opts));
464
483
  }
465
484
  catch (e) {
466
485
  process.stderr.write(chalk.red(`error: ${String(e)}\n`));
@@ -468,11 +487,14 @@ export function registerAgentCommands(program) {
468
487
  }
469
488
  });
470
489
  agent
471
- .command("list <dir>")
472
- .description("List YAML agent configs in a directory")
473
- .action(async (dir) => {
490
+ .command("diagnose <job_id>")
491
+ .description("Aggregate a failed run (failing node/step, error, last LLM call, memory) into one report")
492
+ .option("--json", "Emit the DiagnosisReport as JSON")
493
+ .option("--trace-file <path>", "Trace JSONL to read the last llm.chat span from (else NODETOOL_TRACE_FILE or the debug bundle)")
494
+ .option("--api-url <url>", "API base URL for the job lookup")
495
+ .action(async (jobId, opts) => {
474
496
  try {
475
- await listAgentsCommand(dir);
497
+ await diagnoseCommand(jobId, opts);
476
498
  }
477
499
  catch (e) {
478
500
  process.stderr.write(chalk.red(`error: ${String(e)}\n`));