@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
@@ -0,0 +1,2034 @@
1
+ /**
2
+ * The harness registry — the machine-readable inventory behind
3
+ * harness-first engineering (docs/HARNESS_FIRST.md).
4
+ *
5
+ * Two lists, one invariant:
6
+ *
7
+ * - HARNESSES: every headless, agent-drivable way to exercise a NodeTool
8
+ * surface — validate it, run it, replay interactions against it, or score
9
+ * a model driving it. A harness with a `selfcheck` can prove its surface
10
+ * still works with no target, no key, and no human: that's what
11
+ * `nodetool harness gate` runs.
12
+ * - SURFACES: every product surface a user (or agent) can touch. Each names
13
+ * the harnesses that cover it and the code paths that belong to it, or
14
+ * carries a `gap` note saying why nothing covers it yet and what a
15
+ * harness for it would look like.
16
+ *
17
+ * The invariant — no surface without a harness or a documented gap — is
18
+ * enforced two ways: `nodetool harness audit` reports it (exit 1 with
19
+ * `--strict` on any gap), and tests/harness-registry.test.ts fails the build
20
+ * on an undocumented one. Shipping a new surface means adding it here, which
21
+ * means either pointing at its harness or writing down the debt.
22
+ *
23
+ * The `paths` on each surface are what make the registry executable:
24
+ * `nodetool harness gate` maps a diff onto surfaces by path prefix and runs
25
+ * the selfchecks of every harness covering a touched surface. The gate — not
26
+ * the author — selects the checks.
27
+ */
28
+ import { computeAffected } from "../affected/affected.js";
29
+ import { isGlobalGateFile } from "./changed-files.js";
30
+ /**
31
+ * The pure suites behind the script↔storyboard link and the guided creation
32
+ * flows. One constant because the entry's `command` and its `selfcheck` must
33
+ * not drift: a selfcheck that runs less than the command it stands for reports
34
+ * green on code it never executed.
35
+ *
36
+ * Vitest and Jest both take these positional arguments as file-path filters.
37
+ */
38
+ const SCRIPT_STORYBOARD_LINK_SUITES = "npm run test --workspace=packages/protocol -- script-link shot-prompt " +
39
+ "render-record creative-scenes screenplay-authoring api-schemas-storyboards && " +
40
+ "npm run test --workspace=packages/timeline -- script-link linked storyboard && " +
41
+ "npm run test --workspace=packages/execution -- linked-timeline-validate && " +
42
+ "npm run test --workspace=web -- src/lib/storyboard src/components/setup";
43
+ /**
44
+ * The Workflow flow's pure suites (PRD § 11): the plan schema and the plan→graph
45
+ * builder in protocol, the shipped inspiration chips built against the real node
46
+ * registry, the plan-to-graph case's grading, and the browser flow's steps and
47
+ * tools. One constant so the entry's `command` and its `selfcheck` cannot drift.
48
+ */
49
+ const WORKFLOW_PLAN_SUITES = "npm run test --workspace=packages/protocol -- workflow && " +
50
+ "npm run test --workspace=packages/base-nodes -- workflow-plan-chips && " +
51
+ "npm run test --workspace=packages/agents -- app-build-workflow-plan && " +
52
+ "npm run test --workspace=web -- src/components/setup/workflow src/hooks/workflow src/lib/tools/builtin/__tests__/workflowSetupTools";
53
+ /** Native game schemas, simulation, renderer, graph, and persistence checks. */
54
+ const GAME_FLOW_SUITES = "npm run test --workspace=packages/protocol -- game && " +
55
+ "npm run test --workspace=packages/base-nodes -- game-graph-chips && " +
56
+ "npm run test --workspace=packages/game-nodes && " +
57
+ "npm run test --workspace=packages/game-runtime && " +
58
+ "npm run test --workspace=packages/game-renderer && " +
59
+ "npm run test --workspace=packages/websocket -- trpc-games gameDraftHistory && " +
60
+ "npm run test --workspace=packages/agents -- game && " +
61
+ "npm run test --workspace=packages/cli -- game-command && " +
62
+ "npm run test --workspace=web -- src/stores/game src/components/game";
63
+ /**
64
+ * Durable generation recovery without a provider call. These suites exercise
65
+ * acceptance and lease fencing, explicit FAL queue binding, receipt ordering,
66
+ * lifecycle persistence, and signed inbox deduplication against local fakes.
67
+ */
68
+ const GENERATION_RECOVERY_SUITES = "npm run test --workspace=packages/models -- durable-generation prediction-generations schema-parity migration-schema-parity && " +
69
+ "npm run test --workspace=packages/execution -- durable-generation-lifecycle generation-recovery-worker generation-attachment-recovery fal-output-decoder fal-media-shape-parity && " +
70
+ "npm run test --workspace=packages/runtime -- generation-acceptance-order generation-receipt-binding fal-queue && " +
71
+ "npm run test --workspace=packages/websocket -- fal-webhook generation-recovery-media";
72
+ /**
73
+ * The AtlasCloud callback suites: the Ed25519 ingress route's verification and
74
+ * dispatch, the pending-prediction registry, and the submit/wait wiring that
75
+ * decides whether a run waits for a callback or polls. One constant so the
76
+ * entry's `command` and its `selfcheck` cannot drift.
77
+ */
78
+ const ATLASCLOUD_CALLBACK_SUITES = "npm run test --workspace=packages/runtime -- atlascloud-webhook && " +
79
+ "npm run test --workspace=packages/websocket -- atlascloud-webhook";
80
+ /**
81
+ * The 3D-clip suites: the render session `model3d` layers draw through in the
82
+ * browser, and the headless pre-pass that draws them for
83
+ * `preview_timeline_frame`. One constant so the entry's `command` and its
84
+ * `selfcheck` cannot drift.
85
+ *
86
+ * Vitest takes these positional arguments as file-path filters.
87
+ */
88
+ const TIMELINE_MODEL3D_SUITES = "npm run test --workspace=packages/video-nodes -- model3d-render && " +
89
+ "npm run test --workspace=packages/agents -- timeline-model3d-frames";
90
+ /**
91
+ * A trimmed imported source receives a candidate edit, keeps its active take
92
+ * inactive until the explicit promotion, then restores it with one undo. The
93
+ * package test exercises the headless contract and the web test drives the
94
+ * live TimelineStore path through its agent handler.
95
+ */
96
+ const TIMELINE_NATIVE_MEDIA_EDITING_SUITES = "npm run test --workspace=packages/timeline -- extension && " +
97
+ "npm run test --workspace=packages/runtime -- video-extension && " +
98
+ "npm run test --workspace=packages/websocket -- video-extension-inference && " +
99
+ "npm run test --workspace=packages/agents -- timeline-headless-media-parity timeline-tool-contracts timeline-generative-edit timeline-tool-loop && " +
100
+ "npm run test --workspace=web -- useTimelineAgentBridge timelineTools nativeMediaEditingAcceptance nativeMediaEditingPreview timelineExtension useTimelineExtension ExtendClipPanel" +
101
+ " && npm run test --workspace=packages/websocket -- generation-recovery-media";
102
+ /**
103
+ * The audio-driven-motion suites: `bake_audio_animation`'s own arithmetic
104
+ * (the two clock hops, the envelope/beats curve shapes) plus the end-to-end
105
+ * demonstration that bakes a beat-synced pulse onto a clip that already
106
+ * carries a hand-authored preset and checks the two compose by multiplying
107
+ * rather than one replacing the other. One constant so the entry's `command`
108
+ * and its `selfcheck` cannot drift.
109
+ */
110
+ const TIMELINE_AUDIO_DRIVE_SUITES = "npm run test --workspace=packages/agents -- timeline-audio-drive-demo capabilities-bake-audio-animation";
111
+ /**
112
+ * The generated-matte suites: the pure helpers a clip's own cutout is written
113
+ * and re-selected through, the way the scene model resolves one into a luma
114
+ * keyhole, `isolate_subject`'s document state machine (with a fake runner —
115
+ * the provider is never called), the op/bridge parity for
116
+ * `set_generated_matte`, and the HTTP door the inspector posts to. One
117
+ * constant so the entry's `command` and its `selfcheck` cannot drift.
118
+ *
119
+ * Vitest takes these positional arguments as file-path filters.
120
+ */
121
+ const TIMELINE_GENERATED_MATTE_SUITES = "npm run test --workspace=packages/timeline -- generatedMatte && " +
122
+ "npm run test --workspace=packages/agents -- capabilities-isolate-subject timeline-op-parity && " +
123
+ "npm run test --workspace=packages/websocket -- timeline-isolate-subject-route";
124
+ /**
125
+ * The per-capability contract suites. One constant because the entry's
126
+ * `command` and its `selfcheck` must not drift — a selfcheck that runs less
127
+ * than the command it stands for reports green on code it never executed.
128
+ *
129
+ * The arguments are vitest path filters, so a suite whose filename matches
130
+ * none of them is not run however well it is written: `timeline-video-flow`
131
+ * is named explicitly for that reason.
132
+ */
133
+ const CAPABILITY_SUITES = "npm run test --workspace=packages/agents -- capabilities capability " +
134
+ "mcp-tools memory-tools workflow-version-tools nodetool-api-workflows " +
135
+ "sandbox-package-docs sandbox-package-listing browser-tools " +
136
+ "timelines-op-input timeline-video-flow";
137
+ /**
138
+ * The pure derivations behind the graph-resource nodes plus the node suites
139
+ * that drive them, in dependency order (design §7). One constant because the
140
+ * entry's `command` and its `selfcheck` must not drift: a selfcheck that runs
141
+ * less than the command it stands for reports green on code it never executed.
142
+ *
143
+ * The arguments are vitest path filters, so a suite whose filename matches
144
+ * none of them is not run however well it is written.
145
+ */
146
+ const GRAPH_RESOURCES_SUITES = "npm run test --workspace=packages/storyboard && " +
147
+ "npm run test --workspace=packages/timeline -- derive && " +
148
+ "npm run test --workspace=packages/protocol -- script-fill game-slot-prompt && " +
149
+ "npm run test --workspace=packages/game-nodes && " +
150
+ "npm run test --workspace=packages/core-nodes -- entity-nodes && " +
151
+ "npm run test --workspace=packages/video-nodes -- storyboard-nodes script-nodes";
152
+ export const HARNESSES = [
153
+ {
154
+ id: "validate",
155
+ title: "Static workflow check",
156
+ command: "nodetool validate <id|file.json|file.ts>",
157
+ kind: "static",
158
+ capabilities: ["json", "no-db", "gated:pr"],
159
+ agentTool: "validate_workflow",
160
+ docs: "docs/harnesses.md § nodetool validate",
161
+ selfcheck: { command: "npm run validate:examples", cost: "cheap" }
162
+ },
163
+ {
164
+ id: "debug",
165
+ title: "Workflow debug harness (server + browser surfaces)",
166
+ command: "nodetool debug <id|file> [--browser --trace --watch --supervise]",
167
+ kind: "execution",
168
+ capabilities: ["json", "watch", "supervise", "browser", "gated:nightly"],
169
+ agentTool: "debug_workflow",
170
+ docs: "docs/harnesses.md § nodetool debug",
171
+ selfcheck: { command: "npm run examples:smoke", cost: "expensive" }
172
+ },
173
+ {
174
+ id: "reliability-ring0",
175
+ title: "Reliability Ring 0 (golden journeys on the kernel, strict lifecycle)",
176
+ command: "npm run reliability:ring0",
177
+ kind: "execution",
178
+ capabilities: ["gated:pr"],
179
+ docs: "docs/harnesses.md § nodetool reliability",
180
+ selfcheck: { command: "npm run reliability:ring0", cost: "cheap" }
181
+ },
182
+ {
183
+ id: "node-run",
184
+ title: "Single-node harness",
185
+ command: "nodetool node run <type> --props '{...}' [--no-secrets]",
186
+ kind: "execution",
187
+ capabilities: ["json", "no-db"],
188
+ docs: "docs/harnesses.md § nodetool node run",
189
+ selfcheck: {
190
+ command: 'npm run dev:nodetool -- node run nodetool.text.Concat --props \'{"a":"harness-","b":"gate"}\' --no-secrets',
191
+ cost: "cheap"
192
+ }
193
+ },
194
+ {
195
+ id: "blender",
196
+ title: "Blender headless render (nodetool.blender.* nodes)",
197
+ command: "nodetool node run nodetool.blender.RenderImage --props '<fixture>'",
198
+ kind: "execution",
199
+ capabilities: ["json", "no-db"],
200
+ docs: "docs/blender-headless-integration-design.md",
201
+ selfcheck: {
202
+ // Renders the checked-in triangle fixture through the real Blender.
203
+ // Expensive on purpose: Blender startup plus a render, and it needs
204
+ // the Blender binary, so the default gate skips it without --expensive.
205
+ command: 'npm run dev:nodetool -- node run nodetool.blender.RenderImage --props "$(cat packages/blender-nodes/tests/fixtures/render-image-props.json)" --no-secrets',
206
+ cost: "expensive"
207
+ }
208
+ },
209
+ {
210
+ id: "dsl-native-flow",
211
+ title: "Native flow (call a node as a function, host backend + guest surface)",
212
+ // No CLI command owns it: the public surface is the sandbox pack
213
+ // @nodetool-ai/sandbox-flow, and the host side is internal to
214
+ // packages/dsl. The checked-in suites are the headless surface — they call
215
+ // nodes on the flow's own invoke path, stream both directions, and abort
216
+ // mid-call, with no key, no database, and no server.
217
+ command: "npm run test --workspace=packages/dsl -- flow-core flow-streaming flow-abort",
218
+ kind: "execution",
219
+ capabilities: ["no-db"],
220
+ docs: "docs/dsl-native-flow-design.md",
221
+ selfcheck: {
222
+ command: "npm run test --workspace=packages/dsl -- flow-core flow-streaming flow-abort",
223
+ cost: "cheap",
224
+ suiteOnly: true
225
+ }
226
+ },
227
+ {
228
+ id: "app-runs",
229
+ title: "Durable app operation and generation attachment check",
230
+ command: "npm run test --workspace=packages/execution -- app-operation app-run-generation",
231
+ kind: "execution",
232
+ capabilities: [],
233
+ docs: "docs/harnesses.md § App runs phase 1",
234
+ selfcheck: {
235
+ command: "npm run test --workspace=packages/execution -- app-operation app-run-generation",
236
+ cost: "cheap"
237
+ }
238
+ },
239
+ {
240
+ id: "run-traces",
241
+ title: "Durable app trace, content policy and ancestry check",
242
+ command: "npm run test --workspace=packages/execution --workspace=packages/runtime --workspace=packages/models --workspace=packages/websocket -- run-trace external-trace-privacy http-tracing",
243
+ kind: "execution",
244
+ capabilities: [],
245
+ docs: "docs/harnesses.md § Run traces phase 2",
246
+ selfcheck: {
247
+ command: "npm run test --workspace=packages/execution --workspace=packages/runtime --workspace=packages/models --workspace=packages/websocket -- run-trace external-trace-privacy http-tracing",
248
+ cost: "cheap"
249
+ }
250
+ },
251
+ {
252
+ id: "app-debug",
253
+ title: "Mini-app debug harness",
254
+ command: "nodetool app debug <id|bundle.json> [--interact ... --no-run]",
255
+ kind: "execution",
256
+ capabilities: ["json", "interact", "no-db"],
257
+ docs: "docs/harnesses.md § nodetool app debug",
258
+ selfcheck: {
259
+ command: "npm run dev:nodetool -- app debug packages/base-nodes/nodetool/examples/apps/ad-maker.app.json --no-run",
260
+ cost: "cheap"
261
+ }
262
+ },
263
+ {
264
+ id: "run-readers",
265
+ title: "Run reader, debug history and CLI failure-path check",
266
+ command: "npm run test --workspace=packages/execution --workspace=packages/models --workspace=packages/websocket --workspace=packages/agents --workspace=packages/cli -- runs-phase3 app-debug-versioned-targets app-debug-workflow-inputs-phase3 capabilities-runs runs-command runs-integration run-readers job-find runs-trpc sandbox-api-coverage",
267
+ kind: "execution",
268
+ capabilities: ["json"],
269
+ docs: "docs/harnesses.md § Run readers phase 3",
270
+ selfcheck: {
271
+ command: "npm run test --workspace=packages/execution --workspace=packages/models --workspace=packages/websocket --workspace=packages/agents --workspace=packages/cli -- runs-phase3 app-debug-versioned-targets app-debug-workflow-inputs-phase3 capabilities-runs runs-command runs-integration run-readers job-find runs-trpc sandbox-api-coverage",
272
+ cost: "cheap"
273
+ }
274
+ },
275
+ {
276
+ id: "browser-run-spans",
277
+ title: "Browser run ownership, ancestry and restart check",
278
+ command: "npm run test --workspace=packages/websocket -- browser-run-spans-phase4 browser-app-run-phase4 app-runs-workflow",
279
+ kind: "execution",
280
+ capabilities: [],
281
+ docs: "docs/harnesses.md § Run inspection phase 4",
282
+ selfcheck: {
283
+ command: "npm run test --workspace=packages/websocket -- browser-run-spans-phase4 browser-app-run-phase4 app-runs-workflow",
284
+ cost: "cheap"
285
+ }
286
+ },
287
+ {
288
+ id: "run-inspection-ui",
289
+ title: "Stored trace, activity replay and browser recorder check",
290
+ command: "npm run test --workspace=web -- --runInBand --testPathPattern='browserRunTrace|browserWorkflowRunner|WorkflowRunner.test|TracePanel.test|TraceStore|useRuns|runTraceCache|appRunActivity|AgentActivityWidget|useWidgetRuntime|sketchPadWidget|workflowFormWidget|chatWidgets|mediaWidgets|buttonWidget|recorderWidgets|conditionalWidget|errorTraceReporting|ChatSurface.test|AskRunAgentButton|useAppRuntime|runJsScript.test'",
291
+ kind: "execution",
292
+ capabilities: [],
293
+ docs: "docs/harnesses.md § Run inspection phase 4",
294
+ selfcheck: {
295
+ command: "npm run test --workspace=web -- --runInBand --testPathPattern='browserRunTrace|browserWorkflowRunner|WorkflowRunner.test|TracePanel.test|TraceStore|useRuns|runTraceCache|appRunActivity|AgentActivityWidget|useWidgetRuntime|sketchPadWidget|workflowFormWidget|chatWidgets|mediaWidgets|buttonWidget|recorderWidgets|conditionalWidget|errorTraceReporting|ChatSurface.test|AskRunAgentButton|useAppRuntime|runJsScript.test'",
296
+ cost: "cheap"
297
+ }
298
+ },
299
+ {
300
+ id: "run-inspection-browser",
301
+ title: "Browser action ancestry and Trace/Logs reload journey",
302
+ command: "npm run test:journeys --workspace=web -- run-observability.spec.ts",
303
+ kind: "execution",
304
+ capabilities: ["browser"],
305
+ docs: "docs/harnesses.md § Run inspection phase 4"
306
+ },
307
+ {
308
+ id: "app-instance-history",
309
+ title: "Instance management, pinned versions and history projection check",
310
+ command: "npm run test --workspace=packages/models --workspace=packages/execution --workspace=packages/websocket -- app-instance run-list-app-metadata runs-phase3 app-operation",
311
+ kind: "execution",
312
+ capabilities: [],
313
+ docs: "docs/harnesses.md § App instances and history phase 5",
314
+ selfcheck: {
315
+ command: "npm run test --workspace=packages/models --workspace=packages/execution --workspace=packages/websocket -- app-instance run-list-app-metadata runs-phase3 app-operation",
316
+ cost: "cheap"
317
+ }
318
+ },
319
+ {
320
+ id: "app-instance-history-ui",
321
+ title: "Instance tabs, management cache and app host check",
322
+ command: "npm run test --workspace=web -- --runInBand --testPathPattern='WorkspaceTabsStore|useAppInstances|useAppInstance|ApplicationSurface|ApplicationRunView|AppRuntimeView|AppRunHistory|useAppRuntime'",
323
+ kind: "execution",
324
+ capabilities: [],
325
+ docs: "docs/harnesses.md § App instances and history phase 5",
326
+ selfcheck: {
327
+ command: "npm run test --workspace=web -- --runInBand --testPathPattern='WorkspaceTabsStore|useAppInstances|useAppInstance|ApplicationSurface|ApplicationRunView|AppRuntimeView|AppRunHistory|useAppRuntime'",
328
+ cost: "cheap"
329
+ }
330
+ },
331
+ {
332
+ id: "app-instance-history-browser",
333
+ title: "Independent app instances and read-only historical results journey",
334
+ command: "npm run test:journeys --workspace=web -- app-instances.spec.ts run-observability.spec.ts",
335
+ kind: "execution",
336
+ capabilities: ["browser"],
337
+ docs: "docs/harnesses.md § App instances and history phase 5"
338
+ },
339
+ {
340
+ id: "app-build",
341
+ title: "Mini-app build harness (spec→plan→author→check→run→judge)",
342
+ command: "nodetool app build <prompt|spec.json> -p <provider> -m <model>",
343
+ kind: "execution",
344
+ capabilities: ["json", "watch", "supervise", "gated:pr"],
345
+ docs: "docs/harnesses.md § nodetool app build",
346
+ selfcheck: {
347
+ // The suite's three keyless cases: two scripted app authors and the
348
+ // Workflow flow's plan-to-graph case, all on the real kernel with the
349
+ // provider constructed but never called — the same invocation the
350
+ // Quality Gate's app-build leg runs. `workflow-plan-to-graph` is graded
351
+ // on what its built graph produced, not only on whether it validated
352
+ // (PRD R6), so a plan that wires into a graph that runs and returns
353
+ // nothing fails here.
354
+ command: "npm run dev:nodetool -- eval app-build --cases greeting-card,draft-then-publish,workflow-plan-to-graph -p ollama -m none --no-find-model --min-success 1",
355
+ cost: "cheap"
356
+ }
357
+ },
358
+ {
359
+ id: "timeline-validate",
360
+ title: "Timeline static check",
361
+ command: "nodetool timeline validate <id|file.json>",
362
+ kind: "static",
363
+ capabilities: ["json", "no-db"],
364
+ agentTool: "validate_timeline",
365
+ docs: "docs/harnesses.md § nodetool timeline validate / debug",
366
+ selfcheck: {
367
+ // The validator's own rule suites plus the harness host that drives it.
368
+ // Keyless and target-free: every case is a document literal, so this is
369
+ // the check a diff under `packages/execution/src/timeline-debug/` or
370
+ // `packages/timeline/` earns.
371
+ command: "npm run test --workspace=packages/execution -- timeline- linked-timeline-validate && " +
372
+ "npm run test --workspace=packages/cli -- tests/timeline-harness.test.ts",
373
+ cost: "cheap"
374
+ }
375
+ },
376
+ {
377
+ id: "timeline-debug",
378
+ title: "Timeline edit-session replay",
379
+ command: "nodetool timeline debug <id|file.json> --interact '[...]'",
380
+ kind: "execution",
381
+ capabilities: ["json", "interact", "no-db"],
382
+ docs: "docs/harnesses.md § nodetool timeline validate / debug"
383
+ },
384
+ {
385
+ id: "timeline-render",
386
+ title: "Timeline GPU render (video, stills or contact sheet)",
387
+ command: "nodetool timeline render <id|file.json> [--stills] [--sheet [columns]] [--only <clips>] [--frames <spec>] [--scale <n>]",
388
+ kind: "execution",
389
+ capabilities: ["json", "no-db"],
390
+ agentTool: "render_timeline",
391
+ docs: "docs/harnesses.md § nodetool timeline render",
392
+ selfcheck: {
393
+ // Frame selection, preview scale and zero-area layers through the real
394
+ // GPU compositor. Skips with a reason when there is no WebGPU adapter.
395
+ command: "npm run test --workspace=packages/video-nodes -- timeline-render-frames.gpu timeline-contact-sheet && " +
396
+ "npm run test --workspace=packages/cli -- timeline-render timeline-command",
397
+ cost: "cheap"
398
+ }
399
+ },
400
+ {
401
+ id: "timeline-score",
402
+ title: "Timeline craft scorecard (agent output vs. shipped showcase examples)",
403
+ command: "nodetool timeline score <id|file.json> [--json] [--min-score <n>] [--sheet <out.png>]",
404
+ kind: "static",
405
+ capabilities: ["json", "no-db"],
406
+ docs: "docs/harnesses.md § nodetool timeline score",
407
+ selfcheck: {
408
+ // Deterministic: the metrics/formula core, plus the reference band
409
+ // computed from the shipped examples at test time — no model, no key.
410
+ command: "npm run test --workspace=packages/execution -- timeline-score && " +
411
+ "npm run test --workspace=packages/cli -- timeline-score",
412
+ cost: "cheap"
413
+ }
414
+ },
415
+ {
416
+ id: "serein-timeline-repro",
417
+ title: "Serein timeline motion frame reproduction",
418
+ command: "npm run test --workspace=packages/agents -- timeline-serein-gaps-frames",
419
+ kind: "execution",
420
+ capabilities: ["no-db"],
421
+ docs: "demo/benchmarks/serein/EVAL.md",
422
+ selfcheck: {
423
+ command: "npm run test --workspace=packages/agents -- timeline-serein-gaps-frames",
424
+ cost: "cheap"
425
+ }
426
+ },
427
+ {
428
+ id: "timeline-versions",
429
+ title: "Timeline version history (snapshot, restore, validate the restore)",
430
+ command: "nodetool timeline versions list|show|create|restore|delete <id> [<version>]",
431
+ kind: "execution",
432
+ capabilities: ["json"],
433
+ agentTool: "restore_timeline_version",
434
+ docs: "docs/harnesses.md § nodetool timeline versions"
435
+ },
436
+ {
437
+ id: "timeline-model3d",
438
+ title: "3D clips on the timeline (render session, headless preview frames)",
439
+ // No CLI command owns it: a 3D layer is drawn by the browser preview and,
440
+ // on the server, by the headless pre-pass behind `preview_timeline_frame`.
441
+ // The checked-in suites are the headless surface — the session's pure
442
+ // parts and the pre-pass's grouping, fallback and layer report, with no
443
+ // key, no database and no server. The Chromium half of the render suite
444
+ // skips without Chrome, as it did before the timeline used it.
445
+ command: TIMELINE_MODEL3D_SUITES,
446
+ kind: "static",
447
+ capabilities: ["no-db"],
448
+ agentTool: "preview_timeline_frame",
449
+ docs: "docs/harnesses.md § 3D clips in preview_timeline_frame",
450
+ selfcheck: { command: TIMELINE_MODEL3D_SUITES, cost: "cheap" }
451
+ },
452
+ {
453
+ id: "timeline-native-media-editing",
454
+ title: "Native media editing (candidate take, apply, undo)",
455
+ command: TIMELINE_NATIVE_MEDIA_EDITING_SUITES,
456
+ kind: "static",
457
+ capabilities: ["no-db"],
458
+ agentTool: "ui_timeline_generatively_edit_clip",
459
+ docs: "docs/native-media-editing/prd.md § 9",
460
+ selfcheck: { command: TIMELINE_NATIVE_MEDIA_EDITING_SUITES, cost: "cheap" }
461
+ },
462
+ {
463
+ id: "timeline-audio-drive",
464
+ title: "Audio-driven clip motion (bake_audio_animation → the animation fold)",
465
+ // No CLI command owns it: the surface is the `bake_audio_animation`
466
+ // capability plus the compose rule it depends on in the animation engine
467
+ // (`scale: "multiply"` in `ANIMATED_PROPERTY_FOLD` — a baked curve must
468
+ // drive a clip alongside a hand-authored preset, not replace it). The
469
+ // checked-in suites are the headless surface: the bake's own arithmetic
470
+ // (the two clock hops, envelope vs. beats curve shapes) plus the product
471
+ // demonstration that bakes a beat-synced pulse onto a clip already
472
+ // carrying a `pop` entrance, samples the result through
473
+ // `resolveAnimatedLayerProps`, and confirms it in rendered pixels.
474
+ command: TIMELINE_AUDIO_DRIVE_SUITES,
475
+ kind: "static",
476
+ capabilities: ["no-db"],
477
+ agentTool: "bake_audio_animation",
478
+ docs: "docs/harnesses.md § Audio-driven timeline motion",
479
+ selfcheck: {
480
+ command: TIMELINE_AUDIO_DRIVE_SUITES,
481
+ cost: "cheap",
482
+ suiteOnly: true
483
+ }
484
+ },
485
+ {
486
+ id: "timeline-generated-matte",
487
+ title: "Generated mattes (isolate_subject → the clip's own luma keyhole)",
488
+ // No CLI command owns it: the surface is the `isolate_subject` capability,
489
+ // the `set_generated_matte` op both hosts write the knobs through, and the
490
+ // scene model that resolves the result into a keyhole. The provider is
491
+ // never called — the capability takes its runner as a dependency, and the
492
+ // checked-in suites drive it with a fake one, so what is actually asserted
493
+ // is the document: which matte is current, what status it carries, and
494
+ // that a failed regenerate leaves the working one in place.
495
+ command: TIMELINE_GENERATED_MATTE_SUITES,
496
+ kind: "static",
497
+ capabilities: ["no-db"],
498
+ agentTool: "isolate_subject",
499
+ docs: "docs/harnesses.md § Generated mattes",
500
+ selfcheck: { command: TIMELINE_GENERATED_MATTE_SUITES, cost: "cheap" }
501
+ },
502
+ {
503
+ id: "sketch-validate",
504
+ title: "Sketch static check",
505
+ command: "nodetool sketch validate <id|file.json>",
506
+ kind: "static",
507
+ capabilities: ["json", "no-db"],
508
+ agentTool: "validate_sketch",
509
+ docs: "docs/harnesses.md § nodetool sketch validate / debug"
510
+ },
511
+ {
512
+ id: "sketch-debug",
513
+ title: "Sketch edit-session replay",
514
+ command: "nodetool sketch debug <id|file.json> --interact '[...]'",
515
+ kind: "execution",
516
+ capabilities: ["json", "interact", "no-db"],
517
+ docs: "docs/harnesses.md § nodetool sketch validate / debug"
518
+ },
519
+ {
520
+ id: "sketch-versions",
521
+ title: "Sketch version history (snapshot, restore, validate the restore)",
522
+ command: "nodetool sketch versions list|show|create|restore|delete <id> [<version>]",
523
+ kind: "execution",
524
+ capabilities: ["json"],
525
+ agentTool: "restore_sketch_version",
526
+ docs: "docs/harnesses.md § nodetool sketch versions"
527
+ },
528
+ {
529
+ id: "jsscript-validate",
530
+ title: "JS script static check",
531
+ command: "nodetool jsscript validate <id|file.json>",
532
+ kind: "static",
533
+ capabilities: ["json", "no-db"],
534
+ agentTool: "validate_js_script",
535
+ docs: "docs/harnesses.md § nodetool jsscript"
536
+ },
537
+ {
538
+ id: "jsscript-run",
539
+ title: "JS script single run (QuickJS sandbox)",
540
+ command: "nodetool jsscript run <id|file.json> --inputs '{...}'",
541
+ kind: "execution",
542
+ capabilities: ["json", "no-db"],
543
+ agentTool: "run_js_script",
544
+ docs: "docs/harnesses.md § nodetool jsscript"
545
+ },
546
+ {
547
+ id: "jsscript-test",
548
+ title: "JS script saved-case regression run",
549
+ command: "nodetool jsscript test <id|file.json>",
550
+ kind: "execution",
551
+ capabilities: ["json", "no-db"],
552
+ agentTool: "test_js_script",
553
+ docs: "docs/harnesses.md § nodetool jsscript",
554
+ selfcheck: {
555
+ // Three checked-in fixtures with deterministic cases: no network, no
556
+ // secrets, no database. One sums a buffered list input; one reads the
557
+ // numbers off `stream` from items the cases stage; one imports a shipped
558
+ // sandbox pack, which resolves only when the CLI installs the catalog.
559
+ command: "npm run dev:nodetool -- jsscript test packages/cli/tests/fixtures/js-script-sum.json && " +
560
+ "npm run dev:nodetool -- jsscript test packages/cli/tests/fixtures/js-script-running-total.json && " +
561
+ "npm run dev:nodetool -- jsscript test packages/cli/tests/fixtures/js-script-timeline-pack.json",
562
+ cost: "cheap"
563
+ }
564
+ },
565
+ {
566
+ id: "jsscript-debug",
567
+ title: "JS script edit-session replay",
568
+ command: "nodetool jsscript debug <id|file.json> --interact '[...]'",
569
+ kind: "execution",
570
+ capabilities: ["json", "interact", "no-db"],
571
+ docs: "docs/harnesses.md § nodetool jsscript"
572
+ },
573
+ {
574
+ id: "jsscript-versions",
575
+ title: "JS script version history (snapshot, restore, validate the restore)",
576
+ command: "nodetool jsscript versions list|show|create|restore|delete <id> [<version>]",
577
+ kind: "execution",
578
+ capabilities: ["json"],
579
+ docs: "docs/harnesses.md § nodetool jsscript"
580
+ },
581
+ {
582
+ id: "eval",
583
+ title: "Agent evaluation suites (graph-planner, graph-e2e, code-gen, task-planner, subtask, codeact, tool-loop variants, app-build)",
584
+ command: "nodetool eval <suite> -p <provider> -m <model> [--min-success N]",
585
+ kind: "eval",
586
+ // workflow_dispatch only (.github/workflows/agent-eval.yml) — no PR or
587
+ // schedule trigger, so this is not a `gated:*` harness.
588
+ capabilities: ["json"],
589
+ docs: "packages/agents/AGENTS.md"
590
+ },
591
+ {
592
+ id: "chat-terminal",
593
+ title: "Terminal chat (keyboard, viewport, sessions, approvals, transport)",
594
+ command: "npm run test --workspace=packages/cli -- tests/chat-app.test.ts tests/chat-media.test.ts tests/terminal-keyboard.test.ts tests/terminal-input.test.ts tests/terminal-mouse.test.ts tests/terminal-screen.test.ts tests/chat-prompts.test.ts tests/chat-sessions.test.ts tests/websocket-client.test.ts",
595
+ kind: "execution",
596
+ capabilities: ["no-db"],
597
+ docs: "docs/harnesses.md § nodetool chat",
598
+ selfcheck: {
599
+ command: "npm run test --workspace=packages/cli -- tests/chat-app.test.ts tests/chat-media.test.ts tests/terminal-keyboard.test.ts tests/terminal-input.test.ts tests/terminal-mouse.test.ts tests/terminal-screen.test.ts tests/chat-prompts.test.ts tests/chat-sessions.test.ts tests/websocket-client.test.ts",
600
+ cost: "cheap",
601
+ suiteOnly: true
602
+ }
603
+ },
604
+ {
605
+ id: "chat-stdin",
606
+ title: "Headless chat agent (piped stdin)",
607
+ command: 'echo "<prompt>" | nodetool-chat -p <provider> -m <model>',
608
+ kind: "execution",
609
+ capabilities: [],
610
+ docs: "docs/harnesses.md § nodetool chat"
611
+ },
612
+ {
613
+ id: "telegram-bridge",
614
+ title: "Telegram messaging bridge (renderer, router, identity, adapter)",
615
+ command: "nodetool telegram serve",
616
+ kind: "execution",
617
+ capabilities: ["no-db"],
618
+ docs: "docs/telegram-bot-design.md",
619
+ selfcheck: {
620
+ // The bridge suites are hermetic (fake Bot API, fake socket, injected
621
+ // clock) and include the dependency-cone test; the websocket files run
622
+ // the identity routes, the shared link-code store, and the tRPC router.
623
+ command: "npm run test --workspace=packages/telegram && npx vitest run tests/integrations-routes.test.ts tests/link-codes.test.ts tests/trpc-integrations.test.ts --root packages/websocket",
624
+ cost: "cheap"
625
+ }
626
+ },
627
+ {
628
+ id: "backend-smoke",
629
+ title: "Packaged-backend smoke (bundle staging + /health boot)",
630
+ command: "npm run backend:smoke",
631
+ kind: "meta",
632
+ capabilities: ["gated:pr"],
633
+ docs: "AGENTS.md § Common Pitfalls",
634
+ selfcheck: { command: "npm run backend:smoke", cost: "expensive" }
635
+ },
636
+ {
637
+ id: "docker-smoke",
638
+ title: "Deploy-image smoke (build, boot, load app in a browser)",
639
+ command: "node scripts/docker-smoke.mjs http://localhost:7777",
640
+ kind: "meta",
641
+ capabilities: ["browser", "gated:pr"],
642
+ docs: "AGENTS.md § Common Pitfalls"
643
+ },
644
+ {
645
+ id: "provider-contract",
646
+ title: "Provider contract probes (raw response fixtures + one live request per provider)",
647
+ command: "npm run probe:providers [--json] [--out report.json]",
648
+ kind: "meta",
649
+ // Nightly-only (.github/workflows/provider-contract-probe.yml: schedule +
650
+ // workflow_dispatch, no pull_request) — the offline selfcheck below is
651
+ // exercised there, not on every PR.
652
+ capabilities: ["json", "gated:nightly"],
653
+ docs: "docs/provider-contract-probes.md",
654
+ selfcheck: {
655
+ // The offline half: every manifest entry decodes its checked-in raw
656
+ // response, and every declared required field is removed once to prove
657
+ // the check can fail. No key, no network.
658
+ command: "npm run test --workspace=packages/runtime -- provider-contract-probes",
659
+ cost: "cheap"
660
+ }
661
+ },
662
+ {
663
+ id: "affected",
664
+ title: "Changed-file → workspace mapping",
665
+ command: "nodetool affected [--base main]",
666
+ kind: "meta",
667
+ capabilities: ["json", "no-db"],
668
+ docs: "docs/harnesses.md § nodetool affected"
669
+ },
670
+ {
671
+ id: "packs-compile",
672
+ title: "Sandbox npm module compiler (bundle, scan, probe, cache) and the shipped bridge packs",
673
+ command: "nodetool packs compile [--json] [--force]",
674
+ kind: "static",
675
+ capabilities: ["json", "no-db"],
676
+ docs: "docs/sandbox-package-design.md § Config-only modules from npm packages",
677
+ selfcheck: {
678
+ command: "npm run test --workspace=packages/sandbox-compiler",
679
+ cost: "cheap"
680
+ }
681
+ },
682
+ {
683
+ id: "script-storyboard-link",
684
+ title: "Script ↔ storyboard link (extract, scaffold, joint assemble, link validation)",
685
+ // No CLI command owns the link: it is pure functions in protocol and
686
+ // timeline plus the tools that call them. The checked-in suites are the
687
+ // headless surface — they build a linked document and hand the assembled
688
+ // timeline to the same validator `nodetool timeline validate` runs.
689
+ //
690
+ // The guided-creation-flow suites ride here too (PRD § 7.7): prompt
691
+ // composition, scene ordering, staleness, the Director's scene output and
692
+ // the P5 import parsers (`parseFdx`, `verifyImportedText`,
693
+ // `parseShotlistCsv`) are pure functions on the same documents, and a diff
694
+ // that touches one usually touches the link. `web/src/components/setup`
695
+ // rides along because the flow steps are where those functions are wired:
696
+ // an FDX import that stops reading back verbatim shows up there first.
697
+ command: SCRIPT_STORYBOARD_LINK_SUITES,
698
+ kind: "static",
699
+ capabilities: ["no-db"],
700
+ docs: "docs/script-storyboard-link/design.md § 6",
701
+ selfcheck: {
702
+ command: SCRIPT_STORYBOARD_LINK_SUITES,
703
+ cost: "cheap"
704
+ }
705
+ },
706
+ {
707
+ id: "workflow-plan",
708
+ title: "Workflow plan → graph (planner contract, builder, inspiration chips)",
709
+ // No CLI command owns the planner: the surface is a plan on a workflow's
710
+ // `settings.setup` and the graph it builds. The checked-in suites are the
711
+ // headless surface — they build every shipped chip's plan against the real
712
+ // node registry and hand the graph to the same validator
713
+ // `validate_workflow` runs. What a graph *produces* is graded one harness
714
+ // over, by the app-build suite's `workflow-plan-to-graph` case (PRD R6).
715
+ command: WORKFLOW_PLAN_SUITES,
716
+ kind: "static",
717
+ capabilities: ["no-db"],
718
+ docs: "docs/creation-flows/prd.md § 11",
719
+ selfcheck: { command: WORKFLOW_PLAN_SUITES, cost: "cheap" }
720
+ },
721
+ {
722
+ id: "game-flow",
723
+ title: "Native game engine (validate, simulate, render, stage, persist)",
724
+ command: GAME_FLOW_SUITES,
725
+ kind: "static",
726
+ capabilities: ["no-db"],
727
+ docs: "docs/plans/builtin-game-engine-design.md",
728
+ selfcheck: { command: GAME_FLOW_SUITES, cost: "cheap" }
729
+ },
730
+ {
731
+ id: "capability-suites",
732
+ title: "Agent capability suites (per-capability contract tests)",
733
+ // No CLI command owns a capability: the surface is the wire name a guest
734
+ // or a model calls. The checked-in suites are the headless surface, and
735
+ // `packages/cli/src/harness/capability-table.ts` says which suite covers
736
+ // which capability — the audit fails on one that names none.
737
+ command: CAPABILITY_SUITES,
738
+ kind: "static",
739
+ // Runs in CI as part of the whole-package `--filter=@nodetool-ai/agents`
740
+ // leg, but no workflow names this filtered command specifically, so it
741
+ // is not a `gated:*` harness by the substring-in-a-workflow rule.
742
+ capabilities: ["no-db"],
743
+ docs: "packages/agents/AGENTS.md § Capability coverage",
744
+ selfcheck: {
745
+ // `capabilities:check` re-derives the table from the live registry, so
746
+ // a capability added without a mapping fails here rather than in review.
747
+ command: "npm run capabilities:check && " + CAPABILITY_SUITES,
748
+ cost: "cheap"
749
+ }
750
+ },
751
+ {
752
+ id: "generation-recovery",
753
+ title: "Durable generation recovery (leases, FAL queue, and webhook inbox)",
754
+ command: GENERATION_RECOVERY_SUITES,
755
+ kind: "execution",
756
+ capabilities: ["no-db"],
757
+ docs: "docs/harnesses.md § Durable generation recovery selfcheck",
758
+ selfcheck: { command: GENERATION_RECOVERY_SUITES, cost: "cheap" }
759
+ },
760
+ {
761
+ id: "atlascloud-callbacks",
762
+ title: "AtlasCloud prediction callbacks (Ed25519 ingress and the wait it settles)",
763
+ command: ATLASCLOUD_CALLBACK_SUITES,
764
+ kind: "static",
765
+ capabilities: ["no-db"],
766
+ docs: "docs/developer/providers/atlascloud.md § Prediction callbacks (webhooks)",
767
+ selfcheck: { command: ATLASCLOUD_CALLBACK_SUITES, cost: "cheap" }
768
+ },
769
+ {
770
+ id: "graph-resources",
771
+ title: "Graph resources (recast, fill, retarget, slot prompts — pure suites plus fake-mode runs of the shipped examples)",
772
+ // Two halves, and the second is what the first cannot claim. The suites
773
+ // pin every derivation on fixtures; `fixtures:graph-resources` seeds a
774
+ // scratch install with a template board, its approved cut and an entity
775
+ // library, then runs the example graphs through `nodetool debug` on the
776
+ // fake provider — no key, no network — and reads the result back out of
777
+ // the database: E1's overlay has to come out filled on the exported
778
+ // sequence, E4's retargets have to leave every clip's start and duration
779
+ // where the approved cut put them, E3's export has to write every slot the
780
+ // platformer manifest declares.
781
+ command: `${GRAPH_RESOURCES_SUITES} && npm run fixtures:graph-resources`,
782
+ kind: "execution",
783
+ capabilities: [],
784
+ docs: "docs/harnesses.md § graph-resource fixtures",
785
+ selfcheck: {
786
+ command: `${GRAPH_RESOURCES_SUITES} && npm run fixtures:graph-resources`,
787
+ cost: "cheap"
788
+ }
789
+ },
790
+ {
791
+ id: "jtbd",
792
+ title: "Jobs to be done (end-to-end agent jobs, recorded for review)",
793
+ command: "nodetool jtbd <list|run|optimize> [-p <provider> -m <model>]",
794
+ kind: "eval",
795
+ capabilities: ["json"],
796
+ docs: "docs/harnesses.md § nodetool jtbd",
797
+ selfcheck: {
798
+ // Keyless: the catalogue's own invariants (every job states a purpose,
799
+ // grades an outcome, and fails its checks on an untouched world) plus
800
+ // the transcript capture the review step reads. No model is called.
801
+ command: "npm run test --workspace=packages/agents -- jtbd-friction jtbd-transcript",
802
+ cost: "cheap"
803
+ }
804
+ },
805
+ {
806
+ id: "provider-codegen",
807
+ title: "Generated provider metadata drift (FAL and KIE fixture mode)",
808
+ command: "npm run generate:fal:check && npm run generate:kie:check",
809
+ kind: "static",
810
+ capabilities: ["json", "no-db", "gated:pr"],
811
+ docs: "AGENTS.md § Common Pitfalls",
812
+ selfcheck: {
813
+ command: "npm run generate:fal:check -- --strict && " +
814
+ "npm run generate:kie:check -- --strict",
815
+ cost: "cheap"
816
+ }
817
+ },
818
+ {
819
+ id: "recipes",
820
+ title: "Recipe chains (shipped manifests, the app listing, the site pages)",
821
+ // A recipe names shipped example workflows and stores no graph, so what
822
+ // rots is a step whose example was renamed: the app drops the recipe from
823
+ // its Examples listing and the site's page loses a workflow. Both readers
824
+ // are checked — the resolver the app calls, and the generator the site
825
+ // builds its pages and bundles with.
826
+ command: "npx tsx marketing/scripts/generate-recipes.mjs --check",
827
+ kind: "static",
828
+ capabilities: ["no-db", "gated:pr"],
829
+ docs: "docs/harnesses.md § Shipped recipes",
830
+ selfcheck: {
831
+ command: "npm run test --workspace=packages/websocket -- example-recipes && " +
832
+ "npx tsx marketing/scripts/generate-recipes.mjs --check",
833
+ cost: "cheap"
834
+ }
835
+ },
836
+ {
837
+ id: "repo-scripts",
838
+ title: "Repo tooling scripts (test selection, validators, generators)",
839
+ // The scripts a contributor and CI run from the repo root. Their pure
840
+ // logic (test-affected's plan builder, the validators' rules) is pinned
841
+ // by the suites under scripts/__tests__; a script with no suite is
842
+ // covered only by the CI leg that runs it.
843
+ command: "npm run test:scripts",
844
+ kind: "meta",
845
+ capabilities: ["json", "no-db"],
846
+ docs: "AGENTS.md § Build, Lint & Test Commands",
847
+ selfcheck: { command: "npm run test:scripts", cost: "cheap" }
848
+ },
849
+ {
850
+ id: "tutorial-rendering",
851
+ title: "Tutorial render catalog, camera, and replay checks",
852
+ command: "npm run test --workspace=demo",
853
+ kind: "static",
854
+ capabilities: ["no-db"],
855
+ docs: "docs/plans/tutorial-focus-animation.md",
856
+ selfcheck: {
857
+ command: "npm run test --workspace=demo",
858
+ cost: "cheap",
859
+ suiteOnly: true
860
+ }
861
+ },
862
+ {
863
+ id: "harness-audit",
864
+ title: "Harness coverage audit (this registry)",
865
+ command: "nodetool harness audit [--strict]",
866
+ kind: "meta",
867
+ // Not run by name in any workflow today (the invariant it checks is
868
+ // enforced by the registry test below, in the normal test:packages leg),
869
+ // so it carries no `gated:*` tag under the substring-in-a-workflow rule.
870
+ capabilities: ["json", "no-db"],
871
+ docs: "docs/HARNESS_FIRST.md",
872
+ selfcheck: {
873
+ command: "npm run dev:nodetool -- harness audit && " +
874
+ "npm run test --workspace=packages/cli -- harness-registry.test.ts " +
875
+ "harness-gate-cli.test.ts capability-coverage.test.ts",
876
+ cost: "cheap"
877
+ }
878
+ },
879
+ {
880
+ id: "api-routes",
881
+ title: "API server routes (Fastify HTTP + WebSocket)",
882
+ command: "nodetool serve",
883
+ kind: "execution",
884
+ capabilities: ["no-db"],
885
+ docs: "docs/harnesses.md § nodetool serve",
886
+ selfcheck: {
887
+ // The websocket package's own suite: routes, the /ws runner, MCP tool
888
+ // resolution, drain/shutdown. Multi-minute (255 files), so this stays
889
+ // an --expensive selfcheck rather than the default gate.
890
+ command: "npm run test --workspace=packages/websocket",
891
+ cost: "expensive",
892
+ suiteOnly: true
893
+ }
894
+ },
895
+ {
896
+ id: "data-models",
897
+ title: "Data models (Drizzle ORM persistence layer)",
898
+ command: "npm run test --workspace=packages/models",
899
+ kind: "static",
900
+ capabilities: ["no-db"],
901
+ docs: "packages/models/AGENTS.md",
902
+ selfcheck: {
903
+ command: "npm run test --workspace=packages/models",
904
+ cost: "cheap",
905
+ suiteOnly: true
906
+ }
907
+ },
908
+ {
909
+ id: "storage-and-security",
910
+ title: "Storage, security, auth, and config packages",
911
+ command: "npm run test --workspace=packages/storage && " +
912
+ "npm run test --workspace=packages/security && " +
913
+ "npm run test --workspace=packages/auth && " +
914
+ "npm run test --workspace=packages/config",
915
+ kind: "static",
916
+ capabilities: ["no-db"],
917
+ docs: "packages/AGENTS.md",
918
+ selfcheck: {
919
+ command: "npm run test --workspace=packages/storage && " +
920
+ "npm run test --workspace=packages/security && " +
921
+ "npm run test --workspace=packages/auth && " +
922
+ "npm run test --workspace=packages/config",
923
+ cost: "cheap"
924
+ }
925
+ },
926
+ {
927
+ id: "node-pack-parity",
928
+ title: "Node-pack example-workflow parity (every shipped node covered by an example)",
929
+ command: "npm test --workspace=@nodetool-ai/base-nodes -- parity example-workflows",
930
+ kind: "static",
931
+ // Runs in the quality-checks.yml typecheck leg (pull_request-triggered),
932
+ // by this exact command.
933
+ capabilities: ["no-db", "gated:pr"],
934
+ docs: "packages/base-nodes/AGENTS.md",
935
+ selfcheck: {
936
+ command: "npm test --workspace=@nodetool-ai/base-nodes -- parity example-workflows",
937
+ cost: "cheap"
938
+ }
939
+ },
940
+ {
941
+ id: "shared-services",
942
+ title: "Shared service libraries (vector store, model pricing)",
943
+ command: "npm run test --workspace=packages/vectorstore && " +
944
+ "npm run test --workspace=packages/model-pricing",
945
+ kind: "static",
946
+ capabilities: ["no-db"],
947
+ docs: "packages/AGENTS.md",
948
+ selfcheck: {
949
+ command: "npm run test --workspace=packages/vectorstore && " +
950
+ "npm run test --workspace=packages/model-pricing",
951
+ cost: "cheap"
952
+ }
953
+ },
954
+ {
955
+ id: "execution-session-audit",
956
+ title: "Execution session hydration audit (registry handed without a resolver)",
957
+ command: "npm run test --workspace=packages/execution -- execution-session-hydration-audit",
958
+ kind: "static",
959
+ // No workflow names this test file by substring today (it runs inside
960
+ // the whole-package `packages/execution` leg), so no `gated:*` tag.
961
+ capabilities: ["no-db"],
962
+ docs: "docs/HARNESS_FIRST.md",
963
+ selfcheck: {
964
+ command: "npm run test --workspace=packages/execution -- execution-session-hydration-audit",
965
+ cost: "cheap"
966
+ }
967
+ }
968
+ ];
969
+ export const SURFACES = [
970
+ {
971
+ id: "telegram-bridge",
972
+ title: "Telegram bot bridge + messaging-integration identity",
973
+ harnesses: ["telegram-bridge"],
974
+ paths: [
975
+ "packages/telegram/",
976
+ "packages/websocket/src/routes/integrations.ts",
977
+ "packages/websocket/src/lib/link-codes.ts",
978
+ "packages/websocket/src/trpc/routers/integrations.ts",
979
+ "packages/auth/src/providers/delegated-token-provider.ts",
980
+ "packages/models/src/external-identity.ts"
981
+ ]
982
+ },
983
+ {
984
+ id: "workflow-execution",
985
+ title: "Workflow execution (kernel runner)",
986
+ harnesses: [
987
+ "validate",
988
+ "debug",
989
+ "node-run",
990
+ "reliability-ring0",
991
+ "execution-session-audit"
992
+ ],
993
+ paths: [
994
+ "packages/protocol/",
995
+ "packages/kernel/",
996
+ "packages/execution/",
997
+ "packages/runtime/",
998
+ "packages/node-sdk/",
999
+ "packages/base-nodes/",
1000
+ "reliability/",
1001
+ // The CLI-facing example graphs. `npm run validate:examples` scans them,
1002
+ // so a diff that edits one runs the validate selfcheck.
1003
+ "examples/workflows/"
1004
+ ]
1005
+ },
1006
+ {
1007
+ id: "agent-capabilities",
1008
+ title: "Agent capabilities (the wire names a guest or a model calls)",
1009
+ harnesses: ["capability-suites", "eval", "jtbd"],
1010
+ paths: [
1011
+ "packages/agents/src/capabilities/",
1012
+ // The signal analysis behind the `analyze_*` / `detect_*` capabilities.
1013
+ // It exists only to serve them, so a change here is a change to them.
1014
+ "packages/agents/src/analysis/",
1015
+ "packages/agents/src/evals/",
1016
+ "packages/agents/src/jtbd/",
1017
+ "packages/cli/src/harness/capability-table.ts",
1018
+ "packages/cli/src/harness/capability-coverage.ts",
1019
+ "scripts/sync-capability-coverage.mjs"
1020
+ ]
1021
+ },
1022
+ {
1023
+ id: "generation-tracking",
1024
+ title: "Media generation tracking (the seam, the tracker, the generations capabilities)",
1025
+ harnesses: ["capability-suites", "generation-recovery"],
1026
+ // `capability-suites` runs the tracker, seam and capability suites named
1027
+ // in the capability table, plus the seam audit that fails on a provider
1028
+ // media call outside `runGeneration` (packages/execution/tests/
1029
+ // generation-seam-audit.test.ts). Design:
1030
+ // docs/media-generation-tracking-design.md.
1031
+ paths: [
1032
+ "packages/execution/src/generation-tracker.ts",
1033
+ "packages/execution/src/generation-lifecycle.ts",
1034
+ "packages/execution/src/generation-recovery-worker.ts",
1035
+ "packages/execution/src/fal-output-decoder.ts",
1036
+ "packages/models/src/durable-generation.ts",
1037
+ "packages/models/src/schema/generation-",
1038
+ "packages/models/src/schema-pg/generation-",
1039
+ "packages/runtime/src/generation-receipt.ts",
1040
+ "packages/runtime/src/generation-registry.ts",
1041
+ "packages/runtime/src/providers/fal-queue.ts",
1042
+ "packages/runtime/src/providers/provider-queue.ts",
1043
+ "packages/runtime/src/redact-params.ts",
1044
+ "packages/websocket/src/routes/fal-webhook.ts",
1045
+ "packages/websocket/src/generation-recovery.ts",
1046
+ "packages/agents/src/capabilities/generations.ts",
1047
+ "packages/agents/src/capabilities/generations.specs.ts",
1048
+ "packages/cli/src/commands/generations.ts"
1049
+ ]
1050
+ },
1051
+ {
1052
+ id: "live-browser",
1053
+ title: "Live browser (browser_* capabilities, CDP, the Chrome extension relay)",
1054
+ harnesses: ["capability-suites"],
1055
+ // `capability-suites` covers the seam — dispatch, classification, and what
1056
+ // a process with no action layer answers. The half below it runs in
1057
+ // `npm run test:integration --workspace=packages/browser`, which
1058
+ // launches a real Chrome with the built extension loaded and its native
1059
+ // host registered, and drives the production transport end to end. It is
1060
+ // not a selfcheck: it downloads Chrome, so a diff to the relay still
1061
+ // needs it run by hand.
1062
+ paths: [
1063
+ "chrome-extension/",
1064
+ "packages/browser/",
1065
+ "packages/agents/src/capabilities/browser.ts",
1066
+ "packages/agents/src/capabilities/browser.specs.ts"
1067
+ ]
1068
+ },
1069
+ {
1070
+ id: "provider-clients",
1071
+ title: "LLM and media provider clients (request shaping + response decoding)",
1072
+ harnesses: ["provider-contract", "eval"],
1073
+ paths: [
1074
+ "packages/runtime/src/providers/",
1075
+ // Local-models BaseProvider (transformers.js/kokoro-js) — same request/
1076
+ // response contract as the hosted providers, packaged separately
1077
+ // because its weights and native deps are optional.
1078
+ "packages/transformers-js-provider/"
1079
+ ]
1080
+ },
1081
+ {
1082
+ id: "atlascloud-callbacks",
1083
+ title: "AtlasCloud prediction callbacks (signed ingress, pending registry)",
1084
+ harnesses: ["atlascloud-callbacks"],
1085
+ paths: [
1086
+ "packages/runtime/src/providers/atlascloud-webhook-registry.ts",
1087
+ "packages/runtime/src/providers/atlascloud-transport.ts",
1088
+ "packages/websocket/src/routes/atlascloud-webhook.ts"
1089
+ ]
1090
+ },
1091
+ {
1092
+ id: "workflow-authoring",
1093
+ title: "Workflow authoring (planners + ui_* graph tools)",
1094
+ harnesses: ["validate", "eval"],
1095
+ paths: ["packages/agents/", "packages/dsl/"]
1096
+ },
1097
+ {
1098
+ id: "dsl-native-flow",
1099
+ title: "Native flow (typed node calls from guest code)",
1100
+ harnesses: ["dsl-native-flow", "packs-compile"],
1101
+ paths: [
1102
+ "packages/dsl/src/flow/",
1103
+ "packages/agents/src/capabilities/flow.ts",
1104
+ "packages/agents/src/capabilities/flow.specs.ts",
1105
+ "packages/sandbox-packs/sandbox-flow/"
1106
+ ]
1107
+ },
1108
+ {
1109
+ id: "workflow-creation-flow",
1110
+ title: "Workflow creation flow (settings.setup, planner, plan review, build from plan)",
1111
+ harnesses: ["workflow-plan", "app-build", "capability-suites", "validate"],
1112
+ paths: [
1113
+ "packages/protocol/src/workflow-plan.ts",
1114
+ "packages/protocol/src/api-schemas/workflows.ts",
1115
+ "packages/agents/src/evals/app-build-plan.ts",
1116
+ "packages/base-nodes/tests/workflow-plan-chips.test.ts",
1117
+ "web/src/components/setup/workflow/",
1118
+ "web/src/hooks/workflow/",
1119
+ "web/src/lib/tools/builtin/workflowSetup.ts"
1120
+ ]
1121
+ },
1122
+ {
1123
+ id: "game-creation-flow",
1124
+ title: "Native game creation and editing",
1125
+ harnesses: ["game-flow", "capability-suites", "validate"],
1126
+ paths: [
1127
+ "packages/cli/src/commands/game.ts",
1128
+ "packages/protocol/src/game.ts",
1129
+ "packages/protocol/src/game3d.ts",
1130
+ "packages/protocol/src/game-design.ts",
1131
+ "packages/protocol/src/game-graph.ts",
1132
+ "packages/protocol/src/game-flow-prompt.ts",
1133
+ "packages/protocol/src/style-presets.ts",
1134
+ "packages/game-nodes/",
1135
+ "packages/game-runtime/",
1136
+ "packages/game-renderer/",
1137
+ "packages/godot/",
1138
+ "packages/godot-templates/",
1139
+ "packages/base-nodes/tests/game-graph-chips.test.ts",
1140
+ "packages/websocket/src/trpc/routers/games.ts",
1141
+ "packages/websocket/src/trpc/routers/gameDraftHistory.ts",
1142
+ "packages/websocket/src/lib/style-presets.ts",
1143
+ "web/src/components/game/",
1144
+ "web/src/stores/game/",
1145
+ "web/tests/journeys/native-game3d-editor.spec.ts",
1146
+ "web/src/components/workspace/GameSurface.tsx",
1147
+ "web/src/components/projects/NewProjectSurface.tsx"
1148
+ ]
1149
+ },
1150
+ {
1151
+ id: "app-runs",
1152
+ title: "App instances and durable operation runs",
1153
+ harnesses: ["app-runs"],
1154
+ paths: [
1155
+ "packages/models/src/app-instance.ts",
1156
+ "packages/models/src/migrations/versions.ts",
1157
+ "packages/protocol/src/api-schemas/app-runs.ts",
1158
+ "packages/execution/src/service/app-operation.ts",
1159
+ "packages/execution/src/app-run-generation.ts",
1160
+ "packages/websocket/src/lib/app-instances-service.ts",
1161
+ "packages/websocket/src/routes/app-runs.ts",
1162
+ "packages/websocket/src/trpc/routers/app-instances.ts",
1163
+ "packages/websocket/src/trpc/routers/app-runs.ts",
1164
+ "web/src/components/appbuilder/runtime/"
1165
+ ]
1166
+ },
1167
+ {
1168
+ id: "run-traces",
1169
+ title: "Server run trace persistence and privacy",
1170
+ harnesses: ["run-traces"],
1171
+ paths: [
1172
+ "packages/protocol/src/run-trace.ts",
1173
+ "packages/models/src/run-trace.ts",
1174
+ "packages/models/src/migrations/run-traces.ts",
1175
+ "packages/models/src/schema/run-traces.ts",
1176
+ "packages/models/src/schema-pg/run-traces.ts",
1177
+ "packages/runtime/src/run-trace-",
1178
+ "packages/runtime/src/telemetry.ts",
1179
+ "packages/runtime/src/trace-exporters.ts",
1180
+ "packages/runtime/src/providers/loop-tracing.ts",
1181
+ "packages/execution/src/run-trace-store.ts",
1182
+ "packages/execution/src/service/run-trace-lifecycle.ts",
1183
+ "packages/websocket/src/lib/http-tracing.ts",
1184
+ "packages/websocket/src/storage-retention.ts"
1185
+ ]
1186
+ },
1187
+ {
1188
+ id: "run-readers",
1189
+ title: "Common run inspection for agents and CLI",
1190
+ harnesses: ["run-readers"],
1191
+ paths: [
1192
+ "packages/protocol/src/run-readers.ts",
1193
+ "packages/protocol/src/api-schemas/runs.ts",
1194
+ "packages/models/src/run-readers.ts",
1195
+ "packages/execution/src/runs.ts",
1196
+ "packages/execution/src/app-debug/run-recording.ts",
1197
+ "packages/execution/src/service/app-debug-service.ts",
1198
+ "packages/agents/src/capabilities/runs",
1199
+ "packages/agents/src/capabilities/jobs.ts",
1200
+ "packages/agents/src/evals/codeact-api-runs.ts",
1201
+ "packages/cli/src/commands/runs.ts",
1202
+ "packages/cli/src/app-debug/harness.ts",
1203
+ "packages/websocket/src/trpc/routers/runs.ts",
1204
+ "packages/websocket/src/lib/app-debug-service.ts"
1205
+ ]
1206
+ },
1207
+ {
1208
+ id: "run-inspection",
1209
+ title: "Browser run ingestion and durable UI inspection",
1210
+ harnesses: ["browser-run-spans", "run-inspection-ui", "run-inspection-browser"],
1211
+ paths: [
1212
+ "packages/protocol/src/browser-run-traces.ts",
1213
+ "packages/execution/src/browser-app-run.ts",
1214
+ "packages/execution/src/browser-run-spans.ts",
1215
+ "packages/execution/src/browser-trace-policy.ts",
1216
+ "packages/websocket/src/routes/run-spans.ts",
1217
+ "packages/websocket/src/lib/test-ui-run-routes.ts",
1218
+ "web/src/lib/browserRunTrace.ts",
1219
+ "web/src/lib/workflow/browserWorkflowRunner.ts",
1220
+ "web/src/components/panels/TracePanel.tsx",
1221
+ "web/src/components/appbuilder/runtime/",
1222
+ "web/src/components/appbuilder/AppRuntimeView.tsx",
1223
+ "web/src/components/appbuilder/puck/useWidgetRuntime.ts",
1224
+ "web/src/components/appbuilder/puck/conditionalWidget.tsx",
1225
+ "web/src/components/workspace/ChatSurface.tsx",
1226
+ "web/src/stores/ChatDraftStore.ts",
1227
+ "web/src/components/appbuilder/puck/AgentActivityWidget.tsx",
1228
+ "web/src/components/runs/",
1229
+ "web/src/serverState/useRuns.ts",
1230
+ "web/src/serverState/runTraceCache.ts",
1231
+ "web/src/serverState/appRunActivity.ts",
1232
+ "web/src/hooks/useAppOperationRun.ts",
1233
+ "web/src/hooks/useRunInspection.ts",
1234
+ "web/src/stores/TraceStore.ts",
1235
+ "web/tests/journeys/run-observability.spec.ts"
1236
+ ]
1237
+ },
1238
+ {
1239
+ id: "app-instance-history",
1240
+ title: "App instance management and historical results",
1241
+ harnesses: ["app-instance-history", "app-instance-history-ui", "app-instance-history-browser"],
1242
+ paths: [
1243
+ "packages/models/src/app-instance",
1244
+ "packages/models/src/run-readers.ts",
1245
+ "packages/execution/src/runs.ts",
1246
+ "packages/protocol/src/api-schemas/app-runs.ts",
1247
+ "packages/websocket/src/lib/app-instances-service.ts",
1248
+ "packages/websocket/src/routes/app-runs.ts",
1249
+ "packages/websocket/src/trpc/routers/app-instances.ts",
1250
+ "web/src/components/appbuilder/",
1251
+ "web/src/components/workspace/ApplicationSurface.tsx",
1252
+ "web/src/components/workspace/TabContent.tsx",
1253
+ "web/src/stores/WorkspaceTabsStore.ts",
1254
+ "web/src/serverState/useAppInstances.ts",
1255
+ "web/src/serverState/useRuns.ts",
1256
+ "web/tests/journeys/app-instances.spec.ts"
1257
+ ]
1258
+ },
1259
+ {
1260
+ id: "mini-apps",
1261
+ title: "Mini apps (documents, bindings, operations)",
1262
+ harnesses: ["app-debug", "app-build", "eval"],
1263
+ paths: [
1264
+ "packages/app-runtime/",
1265
+ "packages/agents/src/app-build/",
1266
+ "packages/execution/src/app-debug/",
1267
+ "packages/base-nodes/nodetool/examples/apps/",
1268
+ // The directed-campaign kit's five stage graphs. They are excluded from
1269
+ // the auto-discovered e2e suite (each consumes the stage before it, so
1270
+ // none runs alone on its defaults), so name them here instead: a diff
1271
+ // touching one still selects the harnesses that cover the app.
1272
+ "packages/base-nodes/nodetool/examples/nodetool-base/Propose Three Campaign Directions.json",
1273
+ "packages/base-nodes/nodetool/examples/nodetool-base/Render a Directed Campaign Hero.json",
1274
+ "packages/base-nodes/nodetool/examples/nodetool-base/Compose Directed Campaign Formats.json",
1275
+ "packages/base-nodes/nodetool/examples/nodetool-base/Revise an Accepted Campaign Hero.json",
1276
+ "packages/base-nodes/nodetool/examples/nodetool-base/Reopen a Directed Campaign.json"
1277
+ ]
1278
+ },
1279
+ {
1280
+ id: "timeline",
1281
+ title: "Timeline sequences (ui_timeline_* tools, version history)",
1282
+ harnesses: [
1283
+ "timeline-validate",
1284
+ "timeline-debug",
1285
+ "timeline-render",
1286
+ "timeline-score",
1287
+ "timeline-versions",
1288
+ "eval"
1289
+ ],
1290
+ paths: [
1291
+ "demo/benchmarks/serein/",
1292
+ "packages/timeline/",
1293
+ "packages/execution/src/timeline-debug/",
1294
+ "packages/cli/src/timeline-debug/",
1295
+ "packages/cli/src/commands/timeline-versions.ts",
1296
+ "packages/cli/src/commands/timeline-render.ts",
1297
+ "packages/cli/src/commands/timeline-score.ts",
1298
+ "packages/video-nodes/src/nodes/timeline/compositeRender.ts",
1299
+ "packages/agents/src/tools/timeline-version-tools.ts",
1300
+ "packages/models/src/timeline-sequence-version.ts",
1301
+ "packages/websocket/src/trpc/routers/timeline.ts",
1302
+ "scripts/motion-craft-eval.mjs"
1303
+ ]
1304
+ },
1305
+ {
1306
+ id: "serein-timeline-repro",
1307
+ title: "Serein timeline frame reproduction",
1308
+ harnesses: ["serein-timeline-repro"],
1309
+ paths: [
1310
+ "demo/benchmarks/serein/",
1311
+ "packages/agents/tests/timeline-serein-gaps-frames.test.ts"
1312
+ ]
1313
+ },
1314
+ {
1315
+ id: "timeline-model3d",
1316
+ title: "3D clips on the timeline (render session, camera channels, bake)",
1317
+ harnesses: ["timeline-model3d", "capability-suites"],
1318
+ // Overlaps the surfaces that claim these trees wholesale — `domain-nodes`
1319
+ // (packages/video-nodes/), `workflow-authoring` (packages/agents/) and
1320
+ // `web-editor` (web/) — so a diff here runs their checks as well.
1321
+ paths: [
1322
+ "packages/video-nodes/src/nodes/model3d/",
1323
+ "packages/agents/src/timeline-preview/",
1324
+ "web/src/components/timeline/preview/Model3DLayerSource.ts",
1325
+ "web/src/components/timeline/preview/bakeDecoding.ts",
1326
+ "web/src/components/timeline/Tracks/model3dClipFrames.ts"
1327
+ ]
1328
+ },
1329
+ {
1330
+ id: "timeline-native-media-editing",
1331
+ title: "Native media editing (generative candidates and explicit apply)",
1332
+ harnesses: ["timeline-native-media-editing"],
1333
+ paths: [
1334
+ "packages/timeline/src/generative.ts",
1335
+ "packages/agents/src/capabilities/timelines.ts",
1336
+ "packages/agents/src/capabilities/timeline-media-edit.ts",
1337
+ "packages/agents/src/capabilities/timeline-clip-frames.ts",
1338
+ "packages/agents/tests/timeline-headless-media-parity.test.ts",
1339
+ "packages/runtime/src/trim-video-window.ts",
1340
+ "packages/websocket/src/timeline-generation-recovery.ts",
1341
+ "packages/websocket/src/lib/media.ts",
1342
+ "packages/websocket/tests/generation-recovery-media.test.ts",
1343
+ "packages/timeline/src/extension.ts",
1344
+ "packages/timeline/src/extensionRequest.ts",
1345
+ "packages/timeline/src/takes.ts",
1346
+ "packages/protocol/src/api-schemas/timeline-tool-contracts.ts",
1347
+ "packages/protocol/src/api-schemas/timeline-tool-params.ts",
1348
+ "packages/agents/src/evals/surfaces/timeline.ts",
1349
+ "web/src/components/timeline/timelineAgentBridge.ts",
1350
+ "web/src/hooks/timeline/useTimelineAgentBridge.ts",
1351
+ "web/src/hooks/timeline/useTimelineDirectGenJob.ts",
1352
+ "web/src/hooks/timeline/directGenPending.ts",
1353
+ "web/src/hooks/timeline/useTimelineExtension.ts",
1354
+ "web/src/lib/timelineExtension.ts",
1355
+ "web/src/components/timeline/Inspector/ExtendClipPanel.tsx",
1356
+ "web/src/hooks/timeline/__tests__/nativeMediaEditingAcceptance.test.tsx",
1357
+ "web/src/components/timeline/Inspector/TimelineInspector.tsx",
1358
+ "web/src/components/timeline/preview/__tests__/nativeMediaEditingPreview.test.tsx",
1359
+ "web/src/lib/tools/builtin/timeline.ts"
1360
+ ]
1361
+ },
1362
+ {
1363
+ id: "timeline-audio-drive",
1364
+ title: "Audio-driven timeline motion (bake_audio_animation, audio analysis)",
1365
+ harnesses: ["timeline-audio-drive", "capability-suites"],
1366
+ // Overlaps the wholesale claims on `packages/timeline/` (surface
1367
+ // `timeline`) and `packages/agents/` (surface `workflow-authoring`), so a
1368
+ // diff here runs their checks too.
1369
+ paths: [
1370
+ "packages/timeline/src/animation/",
1371
+ "packages/agents/src/capabilities/timeline-audio-bake.ts",
1372
+ "packages/agents/src/capabilities/analysis.ts"
1373
+ ]
1374
+ },
1375
+ {
1376
+ id: "timeline-generated-matte",
1377
+ title: "Generated mattes (isolate_subject, set_generated_matte)",
1378
+ harnesses: ["timeline-generated-matte", "capability-suites"],
1379
+ // Overlaps the wholesale claims on `packages/timeline/` (surface
1380
+ // `timeline`) and `packages/agents/` (surface `workflow-authoring`), so a
1381
+ // diff here runs their checks too.
1382
+ paths: [
1383
+ "packages/timeline/src/generatedMatte.ts",
1384
+ "packages/agents/src/capabilities/timeline-isolate-subject.ts",
1385
+ "packages/websocket/src/routes/timeline-isolate-subject.ts"
1386
+ ]
1387
+ },
1388
+ {
1389
+ id: "sketch",
1390
+ title: "Sketches (image documents, ui_sketch_* tools, version history)",
1391
+ harnesses: ["sketch-validate", "sketch-debug", "sketch-versions", "eval"],
1392
+ paths: [
1393
+ // The paint core behind sketches: types, dependency hashing, seeded
1394
+ // layer templates, host-neutral raster ops.
1395
+ "packages/image-editor/",
1396
+ "packages/execution/src/sketch-debug/",
1397
+ "packages/cli/src/sketch-debug/",
1398
+ "packages/cli/src/commands/sketch-versions.ts",
1399
+ "packages/cli/src/commands/sketch.ts",
1400
+ "packages/agents/src/tools/sketch-version-tools.ts",
1401
+ "packages/models/src/image-document-version.ts",
1402
+ "packages/websocket/src/trpc/routers/sketch.ts"
1403
+ ]
1404
+ },
1405
+ {
1406
+ id: "jsscript",
1407
+ title: "JS scripts (documents, ui_jsscript_* tools, version history)",
1408
+ harnesses: [
1409
+ "jsscript-validate",
1410
+ "jsscript-run",
1411
+ "jsscript-test",
1412
+ "jsscript-debug",
1413
+ "jsscript-versions",
1414
+ "eval"
1415
+ ],
1416
+ paths: [
1417
+ "packages/execution/src/js-script-debug/",
1418
+ "packages/cli/src/js-script-debug/",
1419
+ "packages/cli/src/commands/js-script.ts",
1420
+ "packages/cli/src/commands/js-script-versions.ts",
1421
+ "packages/cli/src/commands/js-script-validation-output.ts",
1422
+ "packages/agents/src/capabilities/js-scripts.ts",
1423
+ "packages/agents/src/capabilities/js-scripts.specs.ts",
1424
+ "packages/agents/src/evals/surfaces/js-script.ts",
1425
+ "packages/models/src/js-script.ts",
1426
+ "packages/models/src/js-script-version.ts",
1427
+ "packages/protocol/src/api-schemas/js-scripts.ts",
1428
+ "packages/websocket/src/trpc/routers/js-scripts.ts",
1429
+ "packages/websocket/src/routes/js-scripts.ts"
1430
+ ]
1431
+ },
1432
+ {
1433
+ id: "storyboard",
1434
+ title: "Storyboards (shots, keyframes, clips, ui_storyboard_* tools, script link)",
1435
+ // `validate` covers the shipped example boards: its selfcheck,
1436
+ // `npm run validate:examples`, checks each one's shot text and media.
1437
+ harnesses: [
1438
+ "script-storyboard-link",
1439
+ "timeline-validate",
1440
+ "validate",
1441
+ "eval"
1442
+ ],
1443
+ paths: [
1444
+ "packages/protocol/src/script-link.ts",
1445
+ "packages/protocol/src/api-schemas/storyboards.ts",
1446
+ // The guided creation flow's pure modules (PRD § 7.7): one prompt
1447
+ // composition for both surfaces, the derived scene order, and the
1448
+ // staleness comparison the board's marks come from.
1449
+ "packages/protocol/src/shot-prompt.ts",
1450
+ "packages/protocol/src/render-record.ts",
1451
+ "packages/protocol/src/screenplay-authoring.ts",
1452
+ "web/src/lib/storyboard/",
1453
+ "web/src/components/setup/",
1454
+ "packages/timeline/src/storyboard.ts",
1455
+ "packages/timeline/src/script-link.ts",
1456
+ "packages/timeline/src/linked.ts",
1457
+ "packages/agents/src/capabilities/storyboards.ts",
1458
+ "packages/agents/src/capabilities/storyboards.specs.ts",
1459
+ "packages/agents/src/tools/storyboard-render-tools.ts",
1460
+ "packages/agents/src/evals/surfaces/storyboard.ts",
1461
+ "packages/agents/src/evals/surfaces/creative-pipeline.ts",
1462
+ "packages/models/src/schema/storyboards.ts",
1463
+ "packages/websocket/src/trpc/routers/storyboards.ts",
1464
+ "packages/websocket/src/lib/example-storyboards.ts",
1465
+ // The shipped boards and the generator behind them. `validate:examples`
1466
+ // checks each one's shot text and that its stills and clips are on disk.
1467
+ "packages/base-nodes/nodetool/examples/storyboards/",
1468
+ "scripts/build-example-storyboards.mjs",
1469
+ "scripts/example-storyboards/",
1470
+ "web/src/components/storyboard/",
1471
+ "web/src/lib/tools/builtin/storyboard.ts",
1472
+ "web/src/studio/"
1473
+ ]
1474
+ },
1475
+ {
1476
+ id: "script",
1477
+ title: "Scripts (lines, cast, voicing, ui_script_* tools, storyboard link)",
1478
+ harnesses: ["script-storyboard-link", "timeline-validate", "eval"],
1479
+ paths: [
1480
+ "packages/protocol/src/script-link.ts",
1481
+ "packages/protocol/src/api-schemas/scripts.ts",
1482
+ "packages/timeline/src/script.ts",
1483
+ "packages/timeline/src/script-link.ts",
1484
+ "packages/timeline/src/linked.ts",
1485
+ "packages/agents/src/capabilities/scripts.ts",
1486
+ "packages/agents/src/capabilities/scripts.specs.ts",
1487
+ "packages/agents/src/tools/script-voice-tools.ts",
1488
+ "packages/agents/src/evals/surfaces/script.ts",
1489
+ "packages/agents/src/evals/surfaces/creative-pipeline.ts",
1490
+ "packages/models/src/schema/scripts.ts",
1491
+ "packages/websocket/src/trpc/routers/scripts.ts",
1492
+ "web/src/components/script/",
1493
+ "web/src/lib/tools/builtin/script.ts",
1494
+ "web/src/studio/"
1495
+ ]
1496
+ },
1497
+ {
1498
+ id: "model3d",
1499
+ title: "3D models (glTF scenes, ui_3d_* tools, model3d capabilities)",
1500
+ harnesses: ["capability-suites", "eval"],
1501
+ paths: [
1502
+ "packages/model3d/",
1503
+ "packages/agents/src/capabilities/model3d.ts",
1504
+ "packages/agents/src/capabilities/model3d.specs.ts",
1505
+ "packages/agents/src/evals/surfaces/model3d.ts",
1506
+ "web/src/components/model_editor/",
1507
+ "web/src/components/workspace/Model3DSurface.tsx",
1508
+ "web/src/lib/tools/builtin/model3d.ts"
1509
+ ]
1510
+ },
1511
+ {
1512
+ id: "native-game",
1513
+ title: "Native game assets, nodes, renderer, and agent capabilities",
1514
+ harnesses: ["capability-suites"],
1515
+ paths: [
1516
+ "packages/protocol/src/game-assets.ts",
1517
+ "packages/protocol/fixtures/game-assets/",
1518
+ "packages/game-runtime/",
1519
+ "packages/game-renderer/",
1520
+ "packages/image-nodes/src/nodes/game.ts",
1521
+ "packages/audio-nodes/src/nodes/game.ts",
1522
+ "packages/game-nodes/src/nodes/game.ts",
1523
+ "packages/agents/src/capabilities/game.ts",
1524
+ "packages/agents/src/capabilities/game.specs.ts",
1525
+ "packages/agents/src/capabilities/game3d.ts",
1526
+ "packages/agents/src/capabilities/game-asset-source.ts"
1527
+ ]
1528
+ },
1529
+ {
1530
+ id: "blender",
1531
+ title: "Blender headless render (op scripts, runner, blender nodes)",
1532
+ harnesses: ["blender"],
1533
+ paths: ["packages/blender-nodes/"]
1534
+ },
1535
+ {
1536
+ id: "entities",
1537
+ title: "Entity library (ingredients, prompt injection, ui_entity_* tools)",
1538
+ harnesses: ["capability-suites"],
1539
+ paths: [
1540
+ "packages/agents/src/capabilities/entities.ts",
1541
+ "packages/agents/src/capabilities/entities.specs.ts",
1542
+ "web/src/components/entities/",
1543
+ "web/src/serverState/useEntities.ts",
1544
+ "web/src/lib/tools/builtin/entities.ts"
1545
+ ]
1546
+ },
1547
+ {
1548
+ id: "graph-resources",
1549
+ title: "Graph resources (storyboard/entity/script/timeline/game-template nodes and the derivations under them)",
1550
+ // The documents a director approves, as graph values. The derivations are
1551
+ // pure and live in their own packages; the nodes are the only callers that
1552
+ // can get the write contract or the spend gates wrong, and the shipped
1553
+ // examples are the only place all of it is wired together.
1554
+ harnesses: ["graph-resources", "validate"],
1555
+ paths: [
1556
+ "packages/storyboard/",
1557
+ "packages/game-nodes/",
1558
+ "packages/timeline/src/retarget.ts",
1559
+ "packages/timeline/src/fill-text.ts",
1560
+ "packages/timeline/src/clone.ts",
1561
+ "packages/protocol/src/script-fill.ts",
1562
+ "packages/protocol/src/game-slot-prompt.ts",
1563
+ "packages/core-nodes/src/nodes/entity.ts",
1564
+ "packages/video-nodes/src/nodes/storyboard.ts",
1565
+ "packages/base-nodes/nodetool/examples/nodetool-base/Per-SKU Ad Factory.json",
1566
+ "packages/base-nodes/nodetool/examples/nodetool-base/Localized Explainer.json",
1567
+ "packages/base-nodes/nodetool/examples/nodetool-base/Top-down Native Asset Pack.json",
1568
+ "packages/base-nodes/nodetool/examples/nodetool-base/Three Ratios.json",
1569
+ "packages/cli/fixtures/graph-resources/",
1570
+ "scripts/graph-resources-fixtures.mjs"
1571
+ ]
1572
+ },
1573
+ {
1574
+ id: "sandbox-packages",
1575
+ title: "Sandbox packages (guest modules, host modules, npm compilation, catalog)",
1576
+ harnesses: ["packs-compile", "validate"],
1577
+ paths: [
1578
+ "packages/sandbox-compiler/",
1579
+ "packages/sandbox-packs/",
1580
+ "packages/agents/src/host-modules/",
1581
+ "packages/protocol/src/sandbox-host.ts",
1582
+ "packages/node-sdk/src/sandbox-bridge-packs.ts",
1583
+ "packages/node-sdk/src/sandbox-pack-discovery.ts",
1584
+ "packages/node-sdk/src/sandbox-module-catalog.ts",
1585
+ "packages/node-sdk/src/sandbox-catalog-host.ts",
1586
+ "packages/node-sdk/src/sandbox-npm-artifacts.ts",
1587
+ "packages/protocol/src/sandbox-package.ts",
1588
+ "packages/websocket/src/sandbox-catalog.ts",
1589
+ "electron/src/nodePackManager.ts"
1590
+ ]
1591
+ },
1592
+ {
1593
+ id: "chat-agent",
1594
+ title: "Chat agent loop (unified tool-calling loop)",
1595
+ harnesses: ["chat-terminal", "chat-stdin", "eval"],
1596
+ paths: ["packages/chat/", "packages/cli/"]
1597
+ },
1598
+ {
1599
+ id: "web-editor",
1600
+ title: "Web editor (graph canvas, run rendering)",
1601
+ harnesses: ["debug", "docker-smoke"],
1602
+ paths: ["web/"]
1603
+ },
1604
+ {
1605
+ id: "tutorial-rendering",
1606
+ title: "Tutorial rendering and inspection",
1607
+ harnesses: ["tutorial-rendering"],
1608
+ paths: [
1609
+ "demo/src/",
1610
+ "demo/scripts/render-tutorials.ts",
1611
+ "demo/scripts/render-marketing.ts",
1612
+ "demo/scripts/encode-hero.mjs",
1613
+ "demo/scripts/vibe-track.ts"
1614
+ ]
1615
+ },
1616
+ {
1617
+ id: "desktop-backend",
1618
+ title: "Packaged Electron backend (bundled server.mjs)",
1619
+ harnesses: ["backend-smoke"],
1620
+ paths: [
1621
+ "scripts/bundle-backend.mjs",
1622
+ "scripts/verify-backend-bundle.mjs",
1623
+ "packages/config/src/package-asset-registry.ts"
1624
+ ]
1625
+ },
1626
+ {
1627
+ id: "provider-codegen",
1628
+ title: "Generated FAL, KIE, and Replicate provider metadata (node manifests, node source)",
1629
+ harnesses: ["provider-codegen"],
1630
+ paths: [
1631
+ "packages/fal-codegen/",
1632
+ "packages/kie-codegen/",
1633
+ // Replicate's generator has no fixture-mode drift check of its own yet
1634
+ // (unlike fal/kie) — a diff here still runs the fal/kie selfcheck,
1635
+ // which is the closest real coverage until one is written.
1636
+ "packages/replicate-codegen/",
1637
+ "packages/fal-nodes/src/fal-manifest.json",
1638
+ "packages/kie-nodes/src/kie-manifest.json",
1639
+ "scripts/provider-codegen-check.mjs"
1640
+ ]
1641
+ },
1642
+ {
1643
+ id: "deploy-image",
1644
+ title: "Deployed GHCR image (Fly.io / self-hosted)",
1645
+ harnesses: ["docker-smoke"],
1646
+ paths: [
1647
+ "Dockerfile",
1648
+ "docker-compose.yml",
1649
+ "fly.toml",
1650
+ "scripts/docker-smoke.mjs"
1651
+ ]
1652
+ },
1653
+ {
1654
+ id: "public-app-deployments",
1655
+ title: "Deployed mini apps (hidden URL, no login)",
1656
+ harnesses: [],
1657
+ paths: [
1658
+ "packages/websocket/src/lib/app-deployment-service.ts",
1659
+ "packages/websocket/src/lib/app-session-scope.ts",
1660
+ "packages/websocket/src/routes/public-apps.ts",
1661
+ "packages/auth/src/providers/app-session-token-provider.ts",
1662
+ "packages/models/src/application-deployment.ts",
1663
+ "web/src/components/applications/PublicAppPage.tsx"
1664
+ ],
1665
+ gap: "Covered by unit tests only, and the two halves they cannot reach are " +
1666
+ "the ones that matter: what a real logged-out browser can load from " +
1667
+ "the link, and what the auth hook actually refuses an `nda_` token " +
1668
+ "outside `/ws`. A harness would boot the server with " +
1669
+ "NODETOOL_ENV=production, deploy a published example app, then (a) " +
1670
+ "walk every non-`/ws` path with the minted session and assert 401, and " +
1671
+ "(b) drive the page with Playwright carrying no account session, the " +
1672
+ "way the debug harness drives the graph canvas."
1673
+ },
1674
+ {
1675
+ id: "mobile",
1676
+ title: "Mobile app (documents via chat agent ui_* tools)",
1677
+ harnesses: [],
1678
+ paths: ["mobile/"],
1679
+ gap: "No headless harness yet. Mobile edits already flow through the chat " +
1680
+ "agent's ui_* tools (mobile/ARCHITECTURE.md § Documents), so the harness " +
1681
+ "shape exists: drive the same tool contract against a headless bridge " +
1682
+ "the way the tool-loop evals do, and validate the document each session " +
1683
+ "leaves behind."
1684
+ },
1685
+ {
1686
+ id: "electron-shell",
1687
+ title: "Electron shell (windows, IPC, menus, auto-update)",
1688
+ harnesses: [],
1689
+ paths: ["electron/"],
1690
+ gap: "Covered by Jest unit tests only. A harness would boot the packaged " +
1691
+ "shell headlessly (Playwright's Electron driver), assert the " +
1692
+ "IPC surface, and reuse backend-smoke for the server half."
1693
+ },
1694
+ {
1695
+ id: "api-server",
1696
+ title: "API server (Fastify HTTP + WebSocket routes)",
1697
+ harnesses: ["api-routes"],
1698
+ paths: ["packages/websocket/"]
1699
+ },
1700
+ {
1701
+ id: "data-models",
1702
+ title: "Data models (SQLite/Postgres persistence, Drizzle ORM)",
1703
+ harnesses: ["data-models"],
1704
+ paths: ["packages/models/"]
1705
+ },
1706
+ {
1707
+ id: "storage-and-security",
1708
+ title: "Storage, secrets, auth middleware, and config loading",
1709
+ harnesses: ["storage-and-security"],
1710
+ paths: [
1711
+ "packages/storage/",
1712
+ "packages/security/",
1713
+ "packages/auth/",
1714
+ "packages/config/"
1715
+ ]
1716
+ },
1717
+ {
1718
+ id: "domain-nodes",
1719
+ title: "Domain node packages (provider and media node factories)",
1720
+ harnesses: ["node-run", "validate", "node-pack-parity"],
1721
+ paths: [
1722
+ "packages/atlascloud-nodes/",
1723
+ "packages/audio-nodes/",
1724
+ "packages/automation-nodes/",
1725
+ "packages/code-nodes/",
1726
+ "packages/core-nodes/",
1727
+ "packages/data-nodes/",
1728
+ "packages/document-nodes/",
1729
+ "packages/elevenlabs-nodes/",
1730
+ "packages/fal-nodes/",
1731
+ // Shared by the node packages, not a node package itself: the blend-mode
1732
+ // catalog/WGSL functions (gpu) and HuggingFace cache/discovery
1733
+ // (huggingface, paired with huggingface-nodes). CI groups both with the
1734
+ // `*-nodes` filter in quality-checks.yml's test-packages-nodes leg.
1735
+ "packages/gpu/",
1736
+ "packages/huggingface/",
1737
+ "packages/huggingface-nodes/",
1738
+ "packages/higgsfield-nodes/",
1739
+ "packages/image-nodes/",
1740
+ "packages/integration-nodes/",
1741
+ "packages/kie-nodes/",
1742
+ "packages/llm-nodes/",
1743
+ "packages/minimax-nodes/",
1744
+ "packages/nodes-utils/",
1745
+ "packages/replicate-nodes/",
1746
+ "packages/reve-nodes/",
1747
+ "packages/text-nodes/",
1748
+ "packages/together-nodes/",
1749
+ "packages/topaz-nodes/",
1750
+ "packages/transformers-js-nodes/",
1751
+ "packages/whisper-cpp/",
1752
+ "packages/video-nodes/",
1753
+ // Portable runner (graph + registry → a Request/Response handler); CI
1754
+ // groups it with the node packages for the same reason.
1755
+ "packages/workflow-runner/"
1756
+ ]
1757
+ },
1758
+ {
1759
+ id: "shared-services",
1760
+ title: "Shared service libraries (vector store, model pricing)",
1761
+ harnesses: ["shared-services"],
1762
+ paths: ["packages/vectorstore/", "packages/model-pricing/"]
1763
+ },
1764
+ {
1765
+ id: "repo-scripts",
1766
+ title: "Repo tooling scripts (scripts/)",
1767
+ harnesses: ["repo-scripts"],
1768
+ // Overlaps with the surfaces that claim individual scripts (bundle
1769
+ // staging, codegen drift, docker smoke); a diff there runs both.
1770
+ paths: ["scripts/"]
1771
+ },
1772
+ {
1773
+ id: "recipes",
1774
+ title: "Recipes (ordered chains of shipped examples)",
1775
+ harnesses: ["recipes"],
1776
+ // The manifests, the resolver behind the app's Examples listing, and the
1777
+ // site pages built from the same files. Overlaps the surfaces that claim
1778
+ // the packages and the site; a diff here runs both.
1779
+ paths: [
1780
+ "packages/base-nodes/nodetool/examples/recipes/",
1781
+ "packages/protocol/src/api-schemas/recipes.ts",
1782
+ "packages/websocket/src/lib/example-recipes.ts",
1783
+ "web/src/components/portal/DashboardRecipes.tsx",
1784
+ "web/src/hooks/useRecipeActions.ts",
1785
+ "marketing/scripts/generate-recipes.mjs",
1786
+ "marketing/scripts/recipes.mjs",
1787
+ "marketing/src/app/recipes/",
1788
+ "marketing/src/data/recipes.ts"
1789
+ ]
1790
+ },
1791
+ {
1792
+ id: "marketing-site",
1793
+ title: "Marketing site (nodetool.ai)",
1794
+ harnesses: [],
1795
+ paths: ["marketing/"],
1796
+ gap: "A separate npm project with its own lockfile, so the root gate cannot " +
1797
+ "install it: marketing-ci.yml runs its typecheck, lint, Next build, " +
1798
+ "generated-data --check steps, a Playwright smoke suite and a route " +
1799
+ "loader against its own tree. The one part the root gate does reach is " +
1800
+ "the recipe pages, whose data comes from the shipped manifests — that " +
1801
+ "is the `recipes` harness above. A fuller harness would drive the built " +
1802
+ "site the way the debug harness drives the graph canvas."
1803
+ },
1804
+ {
1805
+ id: "harness-registry",
1806
+ title: "Harness registry (this file, its tests, capability sync)",
1807
+ harnesses: ["harness-audit"],
1808
+ paths: [
1809
+ "packages/cli/src/harness/",
1810
+ "packages/cli/src/commands/harness.ts",
1811
+ "packages/cli/tests/harness-gate-cli.test.ts",
1812
+ "packages/cli/tests/harness-registry.test.ts",
1813
+ "packages/cli/tests/capability-coverage.test.ts",
1814
+ "scripts/sync-capability-coverage.mjs"
1815
+ ]
1816
+ }
1817
+ ];
1818
+ /**
1819
+ * Package/app directories with no `SurfaceEntry.paths` prefix pointing into
1820
+ * them, and why: what a diff there cannot verify headlessly today, and what
1821
+ * closing the gap would need. This is the layer below `SurfaceEntry.gap` — a
1822
+ * surface can be uncovered by a *harness* and still claim its paths (mobile,
1823
+ * electron-shell do exactly that); an entry here has no *surface* touching it
1824
+ * at all, so a diff under it selects nothing in `nodetool harness gate` and
1825
+ * `auditPathClaims` would report it silently otherwise.
1826
+ *
1827
+ * Every directory under `packages/`, plus `web/`, `electron/`, `mobile/`,
1828
+ * must appear in some `SurfaceEntry.paths` or here —
1829
+ * `tests/harness-registry.test.ts` walks the real repo and fails the build on
1830
+ * one that is in neither.
1831
+ */
1832
+ export const UNCLAIMED_PATHS = {
1833
+ "examples/nextjs-vercel/": "Deployment example app. CI typechecks it (`npm run typecheck:examples`); " +
1834
+ "its `next build` costs minutes and belongs to deploys, not the PR gate. " +
1835
+ "No harness drives it headlessly.",
1836
+ "examples/nextjs-cloudflare/": "Deployment example app, same standing as examples/nextjs-vercel/: " +
1837
+ "typechecked in CI, built only on deploy, no headless harness.",
1838
+ "packages/compute/": "Provisions and reaps real RunPod/Vast.ai GPU workers; only its hermetic " +
1839
+ "unit tests run headlessly today. A harness needs a recorded-fixture " +
1840
+ "mode against a fake provider API, the way `blender` and " +
1841
+ "`provider-contract` fake their externals.",
1842
+ "packages/deploy/": "The `nodetool deploy` toolkit (Docker/SSH/RunPod/GCP/Supabase " +
1843
+ "self-hosting) needs a real target to prove a rollout; only its " +
1844
+ "planning-logic unit tests run headlessly today.",
1845
+ "packages/sdk/": "Generated TypeScript client re-exporting the tRPC/WebSocket surface; " +
1846
+ "has no test script of its own (build + lint only) — exercised " +
1847
+ "indirectly through the `api-routes` suite it wraps.",
1848
+ "packages/system-skills/": "Not an npm workspace, just SKILL.md files staged into the packaged " +
1849
+ "backend by scripts/bundle-backend.mjs; verify-backend-bundle.mjs " +
1850
+ "checks every directory ships, shipped-skill-names.test.ts checks the " +
1851
+ "calls each one names against the registry, and check-agents-docs.mjs " +
1852
+ "checks the frontmatter name, the one-document rule and the " +
1853
+ ".claude/skills symlinks."
1854
+ };
1855
+ /**
1856
+ * Whether a repo-relative file sits under a directory {@link UNCLAIMED_PATHS}
1857
+ * already documents as having no harness. `nodetool harness gate` uses this so
1858
+ * a diff touching such a directory is not reported as an unmapped code file —
1859
+ * the judgement, and its reason, are already recorded above.
1860
+ */
1861
+ export function isUnclaimedPath(file) {
1862
+ return Object.keys(UNCLAIMED_PATHS).some((prefix) => file.startsWith(prefix));
1863
+ }
1864
+ export function auditHarnessCoverage(harnesses = HARNESSES, surfaces = SURFACES) {
1865
+ const known = new Set(harnesses.map((h) => h.id));
1866
+ const referenced = new Set();
1867
+ const unknownHarnessRefs = [];
1868
+ const undocumentedGaps = [];
1869
+ const rows = surfaces.map((s) => {
1870
+ for (const id of s.harnesses) {
1871
+ referenced.add(id);
1872
+ if (!known.has(id))
1873
+ unknownHarnessRefs.push(`${s.id} → ${id}`);
1874
+ }
1875
+ const covered = s.harnesses.length > 0;
1876
+ if (!covered && !s.gap)
1877
+ undocumentedGaps.push(s.id);
1878
+ return {
1879
+ id: s.id,
1880
+ title: s.title,
1881
+ harnesses: s.harnesses,
1882
+ covered,
1883
+ ...(s.gap && { gap: s.gap })
1884
+ };
1885
+ });
1886
+ return {
1887
+ surfaces: rows,
1888
+ coveredCount: rows.filter((r) => r.covered).length,
1889
+ gapCount: rows.filter((r) => !r.covered).length,
1890
+ undocumentedGaps,
1891
+ unknownHarnessRefs,
1892
+ orphanHarnesses: harnesses
1893
+ .map((h) => h.id)
1894
+ .filter((id) => !referenced.has(id) && id !== "affected")
1895
+ };
1896
+ }
1897
+ /**
1898
+ * Directories under `packages/` (plus `web/`, `electron/`, `mobile/`) that no
1899
+ * `SurfaceEntry.paths` prefix and no `UNCLAIMED_PATHS` entry references. A
1900
+ * non-empty result means a diff under one of them selects nothing in
1901
+ * `nodetool harness gate` — silently, since no surface even names the path.
1902
+ *
1903
+ * `rootDirs` are repo-relative directory paths (e.g. `"packages/models"`, a
1904
+ * trailing slash is added if missing). A directory is claimed when some
1905
+ * surface path or `UNCLAIMED_PATHS` key falls inside it, equals it, or is one
1906
+ * of its ancestors — the same "prefix either way" relationship `planGate`
1907
+ * uses to route a changed file to a surface.
1908
+ */
1909
+ export function auditPathClaims(rootDirs, surfaces = SURFACES, unclaimed = UNCLAIMED_PATHS) {
1910
+ const claims = [
1911
+ ...surfaces.flatMap((s) => s.paths),
1912
+ ...Object.keys(unclaimed)
1913
+ ];
1914
+ return rootDirs.filter((dir) => {
1915
+ const prefix = dir.endsWith("/") ? dir : `${dir}/`;
1916
+ return !claims.some((p) => p.startsWith(prefix) || prefix.startsWith(p));
1917
+ });
1918
+ }
1919
+ /**
1920
+ * Select checks for a diff. Without `packages`, a surface is touched only by a
1921
+ * changed path under one of its prefixes. With them, a surface is also touched
1922
+ * when one of its paths lies inside a workspace downstream of a changed one,
1923
+ * since its code then runs against changed code (`viaDependency`).
1924
+ */
1925
+ export function planGate(changedFiles, harnesses = HARNESSES, surfaces = SURFACES, packages) {
1926
+ const byId = new Map(harnesses.map((h) => [h.id, h]));
1927
+ const touched = new Map();
1928
+ const viaDependency = new Set();
1929
+ const unmappedFiles = [];
1930
+ const globalFiles = changedFiles.filter(isGlobalGateFile);
1931
+ for (const file of changedFiles) {
1932
+ if (isGlobalGateFile(file))
1933
+ continue;
1934
+ let matched = false;
1935
+ for (const s of surfaces) {
1936
+ if (s.paths.some((p) => file === p || file.startsWith(p))) {
1937
+ matched = true;
1938
+ const files = touched.get(s.id) ?? [];
1939
+ files.push(file);
1940
+ touched.set(s.id, files);
1941
+ }
1942
+ }
1943
+ if (!matched)
1944
+ unmappedFiles.push(file);
1945
+ }
1946
+ if (packages) {
1947
+ const dirs = computeAffected(changedFiles, packages)
1948
+ .affected.map((name) => packages.find((p) => p.name === name)?.dir)
1949
+ .filter((d) => d !== undefined)
1950
+ .map((d) => d.replace(/^\.\//, "").replace(/\/+$/, ""));
1951
+ for (const s of surfaces) {
1952
+ if (touched.has(s.id))
1953
+ continue;
1954
+ const inside = s.paths.some((p) => dirs.some((d) => p === d || p.startsWith(`${d}/`)));
1955
+ if (inside) {
1956
+ touched.set(s.id, []);
1957
+ viaDependency.add(s.id);
1958
+ }
1959
+ }
1960
+ }
1961
+ const checkByHarness = new Map();
1962
+ const manualByHarness = new Map();
1963
+ const uncoveredSurfaces = [];
1964
+ for (const s of surfaces) {
1965
+ if (!touched.has(s.id))
1966
+ continue;
1967
+ if (s.harnesses.length === 0) {
1968
+ uncoveredSurfaces.push(s.id);
1969
+ continue;
1970
+ }
1971
+ for (const id of s.harnesses) {
1972
+ const h = byId.get(id);
1973
+ if (!h)
1974
+ continue;
1975
+ if (h.selfcheck) {
1976
+ const existing = checkByHarness.get(id);
1977
+ if (existing) {
1978
+ existing.surfaces.push(s.id);
1979
+ }
1980
+ else {
1981
+ checkByHarness.set(id, {
1982
+ harnessId: id,
1983
+ command: h.selfcheck.command,
1984
+ cost: h.selfcheck.cost,
1985
+ suiteOnly: h.selfcheck.suiteOnly ?? false,
1986
+ surfaces: [s.id]
1987
+ });
1988
+ }
1989
+ }
1990
+ else {
1991
+ const existing = manualByHarness.get(id);
1992
+ if (existing) {
1993
+ existing.surfaces.push(s.id);
1994
+ }
1995
+ else {
1996
+ manualByHarness.set(id, {
1997
+ harnessId: id,
1998
+ command: h.command,
1999
+ surfaces: [s.id]
2000
+ });
2001
+ }
2002
+ }
2003
+ }
2004
+ }
2005
+ // A global file selects every selfcheck, as `--all` does; surfaces it
2006
+ // would not otherwise name stay with an empty list.
2007
+ if (globalFiles.length > 0) {
2008
+ for (const h of harnesses) {
2009
+ if (!h.selfcheck || checkByHarness.has(h.id))
2010
+ continue;
2011
+ checkByHarness.set(h.id, {
2012
+ harnessId: h.id,
2013
+ command: h.selfcheck.command,
2014
+ cost: h.selfcheck.cost,
2015
+ suiteOnly: h.selfcheck.suiteOnly ?? false,
2016
+ surfaces: []
2017
+ });
2018
+ }
2019
+ }
2020
+ return {
2021
+ changedFiles,
2022
+ surfaces: [...touched.entries()].map(([id, files]) => ({
2023
+ id,
2024
+ files,
2025
+ ...(viaDependency.has(id) && { viaDependency: true })
2026
+ })),
2027
+ checks: [...checkByHarness.values()],
2028
+ manual: [...manualByHarness.values()],
2029
+ uncoveredSurfaces,
2030
+ unmappedFiles,
2031
+ globalFiles
2032
+ };
2033
+ }
2034
+ //# sourceMappingURL=registry.js.map