@nathapp/nax-agent 0.1.0

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 (398) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +49 -0
  4. package/dist/coding-tools/coding-tool-bash.d.ts +46 -0
  5. package/dist/coding-tools/coding-tool-bash.js +44 -0
  6. package/dist/coding-tools/coding-tool-extras.d.ts +35 -0
  7. package/dist/coding-tools/coding-tool-extras.js +56 -0
  8. package/dist/coding-tools/coding-tool-sandbox.d.ts +74 -0
  9. package/dist/coding-tools/coding-tool-sandbox.js +215 -0
  10. package/dist/coding-tools/coding-tool-support.d.ts +132 -0
  11. package/dist/coding-tools/coding-tool-support.js +159 -0
  12. package/dist/coding-tools/universal-coding-tools.d.ts +11 -0
  13. package/dist/coding-tools/universal-coding-tools.js +5 -0
  14. package/dist/command-interceptor/index.d.ts +55 -0
  15. package/dist/command-interceptor/index.js +60 -0
  16. package/dist/command-interceptor/shell.d.ts +36 -0
  17. package/dist/command-interceptor/shell.js +137 -0
  18. package/dist/command-safety/build.d.ts +19 -0
  19. package/dist/command-safety/build.js +47 -0
  20. package/dist/command-safety/guard.d.ts +32 -0
  21. package/dist/command-safety/guard.js +179 -0
  22. package/dist/command-safety/identifiers.d.ts +24 -0
  23. package/dist/command-safety/identifiers.js +20 -0
  24. package/dist/command-safety/index.d.ts +17 -0
  25. package/dist/command-safety/index.js +11 -0
  26. package/dist/command-safety/questions.d.ts +19 -0
  27. package/dist/command-safety/questions.js +60 -0
  28. package/dist/command-safety/row.d.ts +2 -0
  29. package/dist/command-safety/row.js +14 -0
  30. package/dist/command-safety/rule-scorer.d.ts +9 -0
  31. package/dist/command-safety/rule-scorer.js +391 -0
  32. package/dist/command-safety/shadow.d.ts +33 -0
  33. package/dist/command-safety/shadow.js +188 -0
  34. package/dist/command-safety/systemone-client.d.ts +16 -0
  35. package/dist/command-safety/systemone-client.js +92 -0
  36. package/dist/command-safety/tap.d.ts +37 -0
  37. package/dist/command-safety/tap.js +77 -0
  38. package/dist/command-safety/temp-only.d.ts +6 -0
  39. package/dist/command-safety/temp-only.js +215 -0
  40. package/dist/command-safety/tmp-write.d.ts +2 -0
  41. package/dist/command-safety/tmp-write.js +112 -0
  42. package/dist/command-safety/types.d.ts +185 -0
  43. package/dist/command-safety/types.js +21 -0
  44. package/dist/config/bash-approval.d.ts +33 -0
  45. package/dist/config/bash-approval.js +30 -0
  46. package/dist/config/catalog-overrides.d.ts +94 -0
  47. package/dist/config/catalog-overrides.js +7 -0
  48. package/dist/config/native-agent/index.d.ts +8 -0
  49. package/dist/config/native-agent/index.js +8 -0
  50. package/dist/config/schemas-sandbox.d.ts +31 -0
  51. package/dist/config/schemas-sandbox.js +45 -0
  52. package/dist/cost/core/index.d.ts +8 -0
  53. package/dist/cost/core/index.js +7 -0
  54. package/dist/cost/estimate.d.ts +34 -0
  55. package/dist/cost/estimate.js +65 -0
  56. package/dist/cost/model-spec.d.ts +28 -0
  57. package/dist/cost/model-spec.js +29 -0
  58. package/dist/cost/standard-types.d.ts +9 -0
  59. package/dist/cost/standard-types.js +1 -0
  60. package/dist/cost/usage-math.d.ts +18 -0
  61. package/dist/cost/usage-math.js +46 -0
  62. package/dist/index.d.ts +26 -0
  63. package/dist/index.js +21 -0
  64. package/dist/infra/agent-logger.d.ts +22 -0
  65. package/dist/infra/agent-logger.js +19 -0
  66. package/dist/infra/credentials-config.d.ts +20 -0
  67. package/dist/infra/credentials-config.js +15 -0
  68. package/dist/infra/errors.d.ts +9 -0
  69. package/dist/infra/errors.js +11 -0
  70. package/dist/infra/index.d.ts +7 -0
  71. package/dist/infra/index.js +7 -0
  72. package/dist/infra/nax-error.d.ts +10 -0
  73. package/dist/infra/nax-error.js +16 -0
  74. package/dist/infra/spin-breaker/hash.d.ts +2 -0
  75. package/dist/infra/spin-breaker/hash.js +5 -0
  76. package/dist/infra/spin-breaker/index.d.ts +120 -0
  77. package/dist/infra/spin-breaker/index.js +340 -0
  78. package/dist/internal/agent-output-env.d.ts +44 -0
  79. package/dist/internal/agent-output-env.js +57 -0
  80. package/dist/internal/argv-exec.d.ts +58 -0
  81. package/dist/internal/argv-exec.js +224 -0
  82. package/dist/internal/bounded-io.d.ts +24 -0
  83. package/dist/internal/bounded-io.js +51 -0
  84. package/dist/internal/command-spec/index.d.ts +29 -0
  85. package/dist/internal/command-spec/index.js +36 -0
  86. package/dist/internal/describe-value-type.d.ts +8 -0
  87. package/dist/internal/describe-value-type.js +14 -0
  88. package/dist/internal/exec-framing.d.ts +18 -0
  89. package/dist/internal/exec-framing.js +22 -0
  90. package/dist/internal/file-lock.d.ts +91 -0
  91. package/dist/internal/file-lock.js +212 -0
  92. package/dist/internal/file-size.d.ts +2 -0
  93. package/dist/internal/file-size.js +12 -0
  94. package/dist/internal/git-add.d.ts +43 -0
  95. package/dist/internal/git-add.js +59 -0
  96. package/dist/internal/git-env.d.ts +59 -0
  97. package/dist/internal/git-env.js +93 -0
  98. package/dist/internal/git-exec.d.ts +58 -0
  99. package/dist/internal/git-exec.js +115 -0
  100. package/dist/internal/path-file-lock.d.ts +23 -0
  101. package/dist/internal/path-file-lock.js +25 -0
  102. package/dist/internal/process-alive.d.ts +42 -0
  103. package/dist/internal/process-alive.js +56 -0
  104. package/dist/internal/process-kill.d.ts +27 -0
  105. package/dist/internal/process-kill.js +54 -0
  106. package/dist/internal/realpath.d.ts +29 -0
  107. package/dist/internal/realpath.js +52 -0
  108. package/dist/internal/redact.d.ts +40 -0
  109. package/dist/internal/redact.js +161 -0
  110. package/dist/internal/shell-quote.d.ts +2 -0
  111. package/dist/internal/shell-quote.js +4 -0
  112. package/dist/internal/sort.d.ts +20 -0
  113. package/dist/internal/sort.js +20 -0
  114. package/dist/internal/strip-control-chars.d.ts +19 -0
  115. package/dist/internal/strip-control-chars.js +38 -0
  116. package/dist/internal/thenable.d.ts +10 -0
  117. package/dist/internal/thenable.js +15 -0
  118. package/dist/internal.d.ts +91 -0
  119. package/dist/internal.js +91 -0
  120. package/dist/native/adapter-deps.d.ts +46 -0
  121. package/dist/native/adapter-deps.js +43 -0
  122. package/dist/native/auth-types.d.ts +70 -0
  123. package/dist/native/auth-types.js +13 -0
  124. package/dist/native/auth.d.ts +133 -0
  125. package/dist/native/auth.js +362 -0
  126. package/dist/native/client.d.ts +50 -0
  127. package/dist/native/client.js +174 -0
  128. package/dist/native/complete.d.ts +33 -0
  129. package/dist/native/complete.js +88 -0
  130. package/dist/native/credentials/chained-store.d.ts +30 -0
  131. package/dist/native/credentials/chained-store.js +68 -0
  132. package/dist/native/credentials/change-guard.d.ts +51 -0
  133. package/dist/native/credentials/change-guard.js +136 -0
  134. package/dist/native/credentials/exec-source.d.ts +50 -0
  135. package/dist/native/credentials/exec-source.js +222 -0
  136. package/dist/native/credentials/fingerprint.d.ts +26 -0
  137. package/dist/native/credentials/fingerprint.js +174 -0
  138. package/dist/native/credentials/helper-process.d.ts +79 -0
  139. package/dist/native/credentials/helper-process.js +259 -0
  140. package/dist/native/credentials/helper-protocol.d.ts +36 -0
  141. package/dist/native/credentials/helper-protocol.js +79 -0
  142. package/dist/native/credentials/index.d.ts +60 -0
  143. package/dist/native/credentials/index.js +184 -0
  144. package/dist/native/errors.d.ts +34 -0
  145. package/dist/native/errors.js +109 -0
  146. package/dist/native/index.d.ts +25 -0
  147. package/dist/native/index.js +23 -0
  148. package/dist/native/model-resolver.d.ts +57 -0
  149. package/dist/native/model-resolver.js +73 -0
  150. package/dist/native/models.d.ts +116 -0
  151. package/dist/native/models.js +183 -0
  152. package/dist/native/session/ask-human.d.ts +15 -0
  153. package/dist/native/session/ask-human.js +22 -0
  154. package/dist/native/session/compaction.d.ts +94 -0
  155. package/dist/native/session/compaction.js +170 -0
  156. package/dist/native/session/handle-invalid-tool-call.d.ts +111 -0
  157. package/dist/native/session/handle-invalid-tool-call.js +159 -0
  158. package/dist/native/session/loop-events/cache-boundary.d.ts +11 -0
  159. package/dist/native/session/loop-events/cache-boundary.js +29 -0
  160. package/dist/native/session/loop-events/external-handler.d.ts +38 -0
  161. package/dist/native/session/loop-events/external-handler.js +193 -0
  162. package/dist/native/session/loop-events/index.d.ts +16 -0
  163. package/dist/native/session/loop-events/index.js +15 -0
  164. package/dist/native/session/loop-events/payload-guard.d.ts +9 -0
  165. package/dist/native/session/loop-events/payload-guard.js +31 -0
  166. package/dist/native/session/loop-events/registry.d.ts +84 -0
  167. package/dist/native/session/loop-events/registry.js +305 -0
  168. package/dist/native/session/loop-events/types.d.ts +251 -0
  169. package/dist/native/session/loop-events/types.js +14 -0
  170. package/dist/native/session/loop-handlers.d.ts +73 -0
  171. package/dist/native/session/loop-handlers.js +137 -0
  172. package/dist/native/session/nudge.d.ts +29 -0
  173. package/dist/native/session/nudge.js +35 -0
  174. package/dist/native/session/rate-provenance.d.ts +17 -0
  175. package/dist/native/session/rate-provenance.js +39 -0
  176. package/dist/native/session/session.d.ts +139 -0
  177. package/dist/native/session/session.js +208 -0
  178. package/dist/native/session/tool-input-exemplar.d.ts +2 -0
  179. package/dist/native/session/tool-input-exemplar.js +66 -0
  180. package/dist/native/session/tool-input-validation.d.ts +15 -0
  181. package/dist/native/session/tool-input-validation.js +146 -0
  182. package/dist/native/session/tool-mapping.d.ts +18 -0
  183. package/dist/native/session/tool-mapping.js +27 -0
  184. package/dist/native/session/tool-result.d.ts +37 -0
  185. package/dist/native/session/tool-result.js +25 -0
  186. package/dist/native/session/transcript-store.d.ts +77 -0
  187. package/dist/native/session/transcript-store.js +200 -0
  188. package/dist/native/session/truncation-handler.d.ts +47 -0
  189. package/dist/native/session/truncation-handler.js +83 -0
  190. package/dist/native/session/turn-accumulator.d.ts +45 -0
  191. package/dist/native/session/turn-accumulator.js +67 -0
  192. package/dist/native/session/turn-ask-human.d.ts +23 -0
  193. package/dist/native/session/turn-ask-human.js +41 -0
  194. package/dist/native/session/turn-compaction-step.d.ts +74 -0
  195. package/dist/native/session/turn-compaction-step.js +128 -0
  196. package/dist/native/session/turn-complete-step.d.ts +77 -0
  197. package/dist/native/session/turn-complete-step.js +159 -0
  198. package/dist/native/session/turn-end-event.d.ts +3 -0
  199. package/dist/native/session/turn-end-event.js +17 -0
  200. package/dist/native/session/turn-events.d.ts +63 -0
  201. package/dist/native/session/turn-events.js +48 -0
  202. package/dist/native/session/turn-loop-round-trip.d.ts +116 -0
  203. package/dist/native/session/turn-loop-round-trip.js +318 -0
  204. package/dist/native/session/turn-loop.d.ts +23 -0
  205. package/dist/native/session/turn-loop.js +250 -0
  206. package/dist/native/session/turn-result.d.ts +39 -0
  207. package/dist/native/session/turn-result.js +64 -0
  208. package/dist/native/session/turn-retry.d.ts +120 -0
  209. package/dist/native/session/turn-retry.js +182 -0
  210. package/dist/native/session/turn-tool-batch.d.ts +61 -0
  211. package/dist/native/session/turn-tool-batch.js +259 -0
  212. package/dist/native/session/turn-types.d.ts +164 -0
  213. package/dist/native/session/turn-types.js +36 -0
  214. package/dist/native/session-adapter.d.ts +56 -0
  215. package/dist/native/session-adapter.js +369 -0
  216. package/dist/native/session-affinity.d.ts +36 -0
  217. package/dist/native/session-affinity.js +43 -0
  218. package/dist/native/tier-providers.d.ts +18 -0
  219. package/dist/native/tier-providers.js +20 -0
  220. package/dist/permissions/approval-audit.d.ts +10 -0
  221. package/dist/permissions/approval-audit.js +22 -0
  222. package/dist/permissions/approvals-link.d.ts +20 -0
  223. package/dist/permissions/approvals-link.js +62 -0
  224. package/dist/permissions/approvals-store.d.ts +168 -0
  225. package/dist/permissions/approvals-store.js +259 -0
  226. package/dist/permissions/approvals-taint.d.ts +33 -0
  227. package/dist/permissions/approvals-taint.js +138 -0
  228. package/dist/permissions/ask-chain.d.ts +69 -0
  229. package/dist/permissions/ask-chain.js +32 -0
  230. package/dist/permissions/ask.d.ts +23 -0
  231. package/dist/permissions/ask.js +25 -0
  232. package/dist/permissions/bash-lex.d.ts +59 -0
  233. package/dist/permissions/bash-lex.js +279 -0
  234. package/dist/permissions/grammar.d.ts +12 -0
  235. package/dist/permissions/grammar.js +24 -0
  236. package/dist/permissions/index.d.ts +11 -0
  237. package/dist/permissions/index.js +9 -0
  238. package/dist/permissions/secret-spans.d.ts +19 -0
  239. package/dist/permissions/secret-spans.js +88 -0
  240. package/dist/permissions/types.d.ts +85 -0
  241. package/dist/permissions/types.js +1 -0
  242. package/dist/runtime/index.d.ts +3 -0
  243. package/dist/runtime/index.js +2 -0
  244. package/dist/runtime/node-glob.d.ts +3 -0
  245. package/dist/runtime/node-glob.js +83 -0
  246. package/dist/runtime/node-runtime.d.ts +3 -0
  247. package/dist/runtime/node-runtime.js +126 -0
  248. package/dist/runtime/slot.d.ts +11 -0
  249. package/dist/runtime/slot.js +17 -0
  250. package/dist/runtime/types.d.ts +51 -0
  251. package/dist/runtime/types.js +1 -0
  252. package/dist/runtime/which.d.ts +8 -0
  253. package/dist/runtime/which.js +32 -0
  254. package/dist/sandbox/argv-quote.d.ts +11 -0
  255. package/dist/sandbox/argv-quote.js +13 -0
  256. package/dist/sandbox/defaults.d.ts +27 -0
  257. package/dist/sandbox/defaults.js +47 -0
  258. package/dist/sandbox/git-guards.d.ts +64 -0
  259. package/dist/sandbox/git-guards.js +161 -0
  260. package/dist/sandbox/index.d.ts +11 -0
  261. package/dist/sandbox/index.js +10 -0
  262. package/dist/sandbox/launcher.d.ts +37 -0
  263. package/dist/sandbox/launcher.js +160 -0
  264. package/dist/sandbox/messages.d.ts +17 -0
  265. package/dist/sandbox/messages.js +46 -0
  266. package/dist/sandbox/policy-builder.d.ts +44 -0
  267. package/dist/sandbox/policy-builder.js +149 -0
  268. package/dist/sandbox/policy-inputs.d.ts +53 -0
  269. package/dist/sandbox/policy-inputs.js +76 -0
  270. package/dist/sandbox/probe.d.ts +8 -0
  271. package/dist/sandbox/probe.js +66 -0
  272. package/dist/sandbox/registry.d.ts +17 -0
  273. package/dist/sandbox/registry.js +57 -0
  274. package/dist/sandbox/session-tmp.d.ts +20 -0
  275. package/dist/sandbox/session-tmp.js +95 -0
  276. package/dist/sandbox/srt-backend.d.ts +21 -0
  277. package/dist/sandbox/srt-backend.js +99 -0
  278. package/dist/sandbox/types.d.ts +102 -0
  279. package/dist/sandbox/types.js +1 -0
  280. package/dist/session/adapter-failure.d.ts +60 -0
  281. package/dist/session/adapter-failure.js +11 -0
  282. package/dist/session/agent-stream-events.d.ts +103 -0
  283. package/dist/session/agent-stream-events.js +6 -0
  284. package/dist/session/interaction-handler.d.ts +53 -0
  285. package/dist/session/interaction-handler.js +2 -0
  286. package/dist/session/no-op-interaction-handler.d.ts +9 -0
  287. package/dist/session/no-op-interaction-handler.js +11 -0
  288. package/dist/session/protocol-types.d.ts +12 -0
  289. package/dist/session/protocol-types.js +1 -0
  290. package/dist/session/session-types.d.ts +456 -0
  291. package/dist/session/session-types.js +64 -0
  292. package/dist/session/tool-descriptor.d.ts +23 -0
  293. package/dist/session/tool-descriptor.js +5 -0
  294. package/dist/session/turn-deadline.d.ts +17 -0
  295. package/dist/session/turn-deadline.js +23 -0
  296. package/dist/tools/ask-request.d.ts +35 -0
  297. package/dist/tools/ask-request.js +57 -0
  298. package/dist/tools/bash-cwd.d.ts +82 -0
  299. package/dist/tools/bash-cwd.js +55 -0
  300. package/dist/tools/bash.d.ts +69 -0
  301. package/dist/tools/bash.js +283 -0
  302. package/dist/tools/delete.d.ts +57 -0
  303. package/dist/tools/delete.js +154 -0
  304. package/dist/tools/denial-redirect.d.ts +42 -0
  305. package/dist/tools/denial-redirect.js +266 -0
  306. package/dist/tools/deny-paths.d.ts +35 -0
  307. package/dist/tools/deny-paths.js +76 -0
  308. package/dist/tools/edit-region.d.ts +50 -0
  309. package/dist/tools/edit-region.js +90 -0
  310. package/dist/tools/edit.d.ts +25 -0
  311. package/dist/tools/edit.js +114 -0
  312. package/dist/tools/exec-allowlist-text.d.ts +18 -0
  313. package/dist/tools/exec-allowlist-text.js +24 -0
  314. package/dist/tools/exec-guard.d.ts +69 -0
  315. package/dist/tools/exec-guard.js +151 -0
  316. package/dist/tools/git-commit.d.ts +59 -0
  317. package/dist/tools/git-commit.js +220 -0
  318. package/dist/tools/git-flags/index.d.ts +10 -0
  319. package/dist/tools/git-flags/index.js +10 -0
  320. package/dist/tools/git.d.ts +88 -0
  321. package/dist/tools/git.js +397 -0
  322. package/dist/tools/glob.d.ts +29 -0
  323. package/dist/tools/glob.js +153 -0
  324. package/dist/tools/grep.d.ts +21 -0
  325. package/dist/tools/grep.js +162 -0
  326. package/dist/tools/index.d.ts +36 -0
  327. package/dist/tools/index.js +28 -0
  328. package/dist/tools/narrow-grants.d.ts +19 -0
  329. package/dist/tools/narrow-grants.js +54 -0
  330. package/dist/tools/nax-owned-writes.d.ts +135 -0
  331. package/dist/tools/nax-owned-writes.js +259 -0
  332. package/dist/tools/package-managers-table.d.ts +146 -0
  333. package/dist/tools/package-managers-table.js +325 -0
  334. package/dist/tools/package-managers-types.d.ts +36 -0
  335. package/dist/tools/package-managers-types.js +6 -0
  336. package/dist/tools/package-managers.d.ts +85 -0
  337. package/dist/tools/package-managers.js +391 -0
  338. package/dist/tools/path-list.d.ts +38 -0
  339. package/dist/tools/path-list.js +62 -0
  340. package/dist/tools/policy-bash-raw.d.ts +19 -0
  341. package/dist/tools/policy-bash-raw.js +210 -0
  342. package/dist/tools/policy-bash.d.ts +64 -0
  343. package/dist/tools/policy-bash.js +232 -0
  344. package/dist/tools/policy-command-branch.d.ts +32 -0
  345. package/dist/tools/policy-command-branch.js +63 -0
  346. package/dist/tools/policy-input.d.ts +2 -0
  347. package/dist/tools/policy-input.js +10 -0
  348. package/dist/tools/policy-match.d.ts +75 -0
  349. package/dist/tools/policy-match.js +117 -0
  350. package/dist/tools/policy-paths-branch.d.ts +97 -0
  351. package/dist/tools/policy-paths-branch.js +314 -0
  352. package/dist/tools/policy.d.ts +65 -0
  353. package/dist/tools/policy.js +232 -0
  354. package/dist/tools/protected-paths.d.ts +26 -0
  355. package/dist/tools/protected-paths.js +8 -0
  356. package/dist/tools/provider-adapt.d.ts +4 -0
  357. package/dist/tools/provider-adapt.js +32 -0
  358. package/dist/tools/provider-advertise.d.ts +39 -0
  359. package/dist/tools/provider-advertise.js +50 -0
  360. package/dist/tools/provider-grants.d.ts +36 -0
  361. package/dist/tools/provider-grants.js +72 -0
  362. package/dist/tools/provider-sanitize.d.ts +19 -0
  363. package/dist/tools/provider-sanitize.js +53 -0
  364. package/dist/tools/provider-types.d.ts +41 -0
  365. package/dist/tools/provider-types.js +26 -0
  366. package/dist/tools/read-continuation.d.ts +147 -0
  367. package/dist/tools/read-continuation.js +176 -0
  368. package/dist/tools/read-file.d.ts +32 -0
  369. package/dist/tools/read-file.js +85 -0
  370. package/dist/tools/read.d.ts +25 -0
  371. package/dist/tools/read.js +182 -0
  372. package/dist/tools/registry.d.ts +125 -0
  373. package/dist/tools/registry.js +67 -0
  374. package/dist/tools/request-capability.d.ts +13 -0
  375. package/dist/tools/request-capability.js +23 -0
  376. package/dist/tools/run-command-exec.d.ts +14 -0
  377. package/dist/tools/run-command-exec.js +161 -0
  378. package/dist/tools/run-command.d.ts +107 -0
  379. package/dist/tools/run-command.js +398 -0
  380. package/dist/tools/runtime-calltool.d.ts +146 -0
  381. package/dist/tools/runtime-calltool.js +223 -0
  382. package/dist/tools/runtime.d.ts +149 -0
  383. package/dist/tools/runtime.js +345 -0
  384. package/dist/tools/scratchpad.d.ts +20 -0
  385. package/dist/tools/scratchpad.js +197 -0
  386. package/dist/tools/spill.d.ts +81 -0
  387. package/dist/tools/spill.js +251 -0
  388. package/dist/tools/tool-audit.d.ts +171 -0
  389. package/dist/tools/tool-audit.js +183 -0
  390. package/dist/tools/truncate.d.ts +98 -0
  391. package/dist/tools/truncate.js +297 -0
  392. package/dist/tools/types.d.ts +145 -0
  393. package/dist/tools/types.js +24 -0
  394. package/dist/tools/verb-denial-argv-hint.d.ts +35 -0
  395. package/dist/tools/verb-denial-argv-hint.js +40 -0
  396. package/dist/tools/write.d.ts +9 -0
  397. package/dist/tools/write.js +45 -0
  398. package/package.json +54 -0
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Name-to-tool registry, mirroring PULL_TOOL_REGISTRY in the context engine.
3
+ *
4
+ * Open to third-party registration, with two rules that make that safe:
5
+ * built-in names are reserved (a registered "Write" would shadow the gated
6
+ * implementation), and a verb-gated tool must declare the verbs it permits so
7
+ * the policy can never be granted a subcommand the tool itself disallows.
8
+ *
9
+ * Registration is in-process — another nax module or plugin. This is an
10
+ * extension point, not a plugin download path.
11
+ */
12
+ import type { CommandInterceptor } from "#src/command-interceptor/index";
13
+ import type { JSONSchema } from "#src/session/tool-descriptor";
14
+ import type { SandboxRecord } from "../sandbox/index.ts";
15
+ import type { ProtectedPathsPolicy } from "./protected-paths.ts";
16
+ import type { CodingToolName, ToolScope } from "./types.ts";
17
+ export interface ToolResult {
18
+ readonly content: string;
19
+ readonly isError?: boolean;
20
+ /**
21
+ * Set only by RunCommand's argv branch (`Exec`), which is the one call
22
+ * shape whose executed argv can differ from what the model requested
23
+ * (normalization scopes it to a workspace member and may append a
24
+ * no-scripts mechanism). Returned here rather than re-derived by the
25
+ * runtime so the ledger records the argv that actually ran. Task 7 reads
26
+ * this to write `executed`/`target` onto the ledger row; this task only
27
+ * defines and returns it.
28
+ *
29
+ * The `Git` tool also sets `audit` when a command interceptor rewrote its
30
+ * argv — there `target` is absent, because the repoRoot/package distinction
31
+ * does not apply to a git read.
32
+ */
33
+ readonly audit?: {
34
+ readonly executed: readonly string[];
35
+ readonly target?: "repoRoot" | "package";
36
+ /** Exec only: the directory the argv ran in. Read by the command-safety shadow, not the ledger. */
37
+ readonly cwd?: string;
38
+ /** P4: how an agent-authored Bash/Exec command ran; absent for every other tool. */
39
+ readonly sandbox?: SandboxRecord;
40
+ /**
41
+ * Bash only: the shell's exit code, present when nax did NOT kill the
42
+ * process group -- absent under `timedOut` (deadline kill) and `aborted`
43
+ * (turn cancellation), present under `orphansKilled` (the shell exited by
44
+ * itself; only background processes were reaped). What N means depends on
45
+ * the command in `executed` (exit 1 is "no match" for grep, "failures" for
46
+ * a test runner), and N >= 128 may still be a signal nax did not send.
47
+ */
48
+ readonly exitCode?: number;
49
+ };
50
+ /**
51
+ * Result size in bytes BEFORE the tool truncated to `ctx.maxBytes`. Set by
52
+ * tools whose payload is unbounded by nature — an MCP graph query can return
53
+ * megabytes. `resultBytes` on the ledger is measured after the slice, so
54
+ * without this a 2 MB result and a 40 KB one are indistinguishable and "how
55
+ * much did we discard" is unanswerable.
56
+ */
57
+ readonly resultBytesPreTruncation?: number;
58
+ }
59
+ export interface ToolRunContext {
60
+ /** Absolute, symlink-resolved permitted root. */
61
+ readonly root: string;
62
+ /** Paths the policy already resolved and approved, in pathFields order. */
63
+ readonly resolvedPaths: readonly string[];
64
+ /** Output ceiling in bytes; the tool truncates rather than the caller. */
65
+ readonly maxBytes: number;
66
+ /**
67
+ * Largest file this tool may read whole or write. Bounds the work, where
68
+ * maxBytes bounds only what the model is told -- see src/tools/bounded.ts.
69
+ */
70
+ readonly maxFileBytes: number;
71
+ /**
72
+ * Tool-layer I/O bound. Optional so existing `ToolRunContext` literals
73
+ * compile unchanged; resolves to `READ_CEILING` when absent. Distinct
74
+ * from `maxFileBytes` (whole-file Edit/Write cap) and `maxBytes` (the
75
+ * model-facing ceiling owned by `after_tool`).
76
+ */
77
+ readonly readCeiling?: number;
78
+ /**
79
+ * Repo-configurable glob denylist (nax#1972, `execution.denyPaths` in
80
+ * config), narrowing what a tool may act on beyond containment and grants.
81
+ * Currently consumed by Delete only -- see src/tools/deny-paths.ts. Absent
82
+ * or empty means no additional narrowing.
83
+ */
84
+ readonly denyPaths?: readonly string[];
85
+ /**
86
+ * Aborts the turn's process execution; Bash and Exec forward it to the
87
+ * launcher and runArgv, which SIGKILL the process group. US-001.
88
+ */
89
+ readonly signal?: AbortSignal;
90
+ /**
91
+ * The run's command interceptor (US-003; S1 spec section 4.2, port 7). The
92
+ * same object for every tool of a run, so the Git and Bash sites share one
93
+ * binary probe and one mode. Absent when the run installed none: interception
94
+ * then does not apply, the fail-safe both sites state.
95
+ */
96
+ readonly interceptor?: CommandInterceptor;
97
+ /** Host-owned paths (S1 spec port 6). Absent: the Git tools exclude and skip nothing extra. */
98
+ readonly protectedPaths?: ProtectedPathsPolicy;
99
+ }
100
+ export interface CodingTool {
101
+ readonly name: string;
102
+ readonly description: string;
103
+ readonly inputSchema: JSONSchema;
104
+ readonly scope: ToolScope;
105
+ /**
106
+ * True when an `isError` result is a routine part of using this tool rather
107
+ * than a fault worth an operator's attention. Only `RunCommand` sets it: a
108
+ * non-zero exit from a project command is the agent's own red/green loop, and
109
+ * on the acpx transport that loop runs inside the spawned agent where nax
110
+ * never observes it. Such calls are recorded at debug — the JSONL and the
111
+ * audit sink still get them, the console does not. Everything else defaults
112
+ * to false, so a malformed Read or a failed GitCommit stays visible.
113
+ */
114
+ readonly routineErrors?: boolean;
115
+ run(input: Record<string, unknown>, ctx: ToolRunContext): Promise<ToolResult>;
116
+ }
117
+ /** Built-in names may never be re-registered. */
118
+ export declare const RESERVED_TOOL_NAMES: readonly CodingToolName[];
119
+ export declare function registerCodingTool(tool: CodingTool): void;
120
+ /** Register a nax built-in, bypassing the reserved-name check by design. */
121
+ export declare function registerBuiltinTool(tool: CodingTool): void;
122
+ export declare function getCodingTool(name: string): CodingTool | undefined;
123
+ export declare function listCodingTools(): readonly CodingTool[];
124
+ /** @internal Test-only: clears registrations between cases. */
125
+ export declare function _resetRegistryForTest(): void;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Name-to-tool registry, mirroring PULL_TOOL_REGISTRY in the context engine.
3
+ *
4
+ * Open to third-party registration, with two rules that make that safe:
5
+ * built-in names are reserved (a registered "Write" would shadow the gated
6
+ * implementation), and a verb-gated tool must declare the verbs it permits so
7
+ * the policy can never be granted a subcommand the tool itself disallows.
8
+ *
9
+ * Registration is in-process — another nax module or plugin. This is an
10
+ * extension point, not a plugin download path.
11
+ */
12
+ import { NaxError } from "#src/infra/index";
13
+ /** Built-in names may never be re-registered. */
14
+ export const RESERVED_TOOL_NAMES = [
15
+ "Read",
16
+ "Glob",
17
+ "Grep",
18
+ "Write",
19
+ "Edit",
20
+ "Delete",
21
+ "Git",
22
+ "GitCommit",
23
+ "RunCommand",
24
+ "RequestCapability",
25
+ "Exec",
26
+ "Bash",
27
+ "ScratchpadWrite",
28
+ "ScratchpadRead",
29
+ "ScratchpadList",
30
+ ];
31
+ const registry = new Map();
32
+ export function registerCodingTool(tool) {
33
+ if (RESERVED_TOOL_NAMES.includes(tool.name) && !internalRegistration) {
34
+ throw new NaxError(`Tool name "${tool.name}" is reserved for a nax built-in and cannot be re-registered.`, "TOOL_NAME_RESERVED", { stage: "tools", tool: tool.name });
35
+ }
36
+ if (registry.has(tool.name)) {
37
+ throw new NaxError(`Tool "${tool.name}" is already registered.`, "TOOL_ALREADY_REGISTERED", {
38
+ stage: "tools",
39
+ tool: tool.name,
40
+ });
41
+ }
42
+ if (tool.scope.verbField !== undefined && tool.scope.allowedVerbs === undefined) {
43
+ throw new NaxError(`Tool "${tool.name}" declares verbField but no allowedVerbs; the policy would have no bound to enforce.`, "TOOL_SCOPE_INCOMPLETE", { stage: "tools", tool: tool.name });
44
+ }
45
+ registry.set(tool.name, tool);
46
+ }
47
+ let internalRegistration = false;
48
+ /** Register a nax built-in, bypassing the reserved-name check by design. */
49
+ export function registerBuiltinTool(tool) {
50
+ internalRegistration = true;
51
+ try {
52
+ registerCodingTool(tool);
53
+ }
54
+ finally {
55
+ internalRegistration = false;
56
+ }
57
+ }
58
+ export function getCodingTool(name) {
59
+ return registry.get(name);
60
+ }
61
+ export function listCodingTools() {
62
+ return [...registry.values()];
63
+ }
64
+ /** @internal Test-only: clears registrations between cases. */
65
+ export function _resetRegistryForTest() {
66
+ registry.clear();
67
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Declares a capability the model wanted and could not reach. Runs nothing.
3
+ *
4
+ * A denial is only produced if the model attempts a call, and a model told it
5
+ * has no shell will not attempt one -- so the absence of denials would be
6
+ * indistinguishable from the absence of need. Issue #1800 is the worked
7
+ * example: a reviewer said in prose "I have no file/shell access tool in this
8
+ * environment" and then returned a pass, and nothing structured captured it.
9
+ *
10
+ * The refusal is the point. The value is the row it leaves behind.
11
+ */
12
+ import type { CodingTool } from "./registry.ts";
13
+ export declare const requestCapabilityTool: CodingTool;
@@ -0,0 +1,23 @@
1
+ export const requestCapabilityTool = {
2
+ name: "RequestCapability",
3
+ description: "Declare a capability you need but do not have (for example a shell command you would have run). This grants nothing and runs nothing; it records the need so the tool set can be widened later.",
4
+ inputSchema: {
5
+ type: "object",
6
+ properties: {
7
+ capability: { type: "string", description: "What you would have run or reached, verbatim" },
8
+ reason: { type: "string", description: "Why you needed it, in one sentence" },
9
+ },
10
+ required: ["capability"],
11
+ },
12
+ scope: { pathFields: [] },
13
+ async run(input, _ctx) {
14
+ const capability = input.capability;
15
+ if (typeof capability !== "string" || capability.trim() === "") {
16
+ return { content: "capability must be a non-empty string", isError: true };
17
+ }
18
+ return {
19
+ content: `Recorded: "${capability}" is not available on this path. Continue without it, or stop and say you cannot proceed.`,
20
+ isError: true,
21
+ };
22
+ },
23
+ };
@@ -0,0 +1,14 @@
1
+ import type { ToolResult, ToolRunContext } from "./registry.ts";
2
+ import type { RunCommandToolOptions } from "./run-command.ts";
3
+ /**
4
+ * Deadline for the argv branch's spawn (`runExecBranch`).
5
+ *
6
+ * Deliberately longer than the declared branch's own default deadline
7
+ * (120_000ms, in the project's quality-command runner): a declared quality
8
+ * command runs entirely on code already on disk, while an install-shaped
9
+ * argv call here talks to a package registry over the network and may run
10
+ * a vendor postinstall script — both routinely take longer than a
11
+ * project's own test/lint/typecheck command.
12
+ */
13
+ export declare const EXEC_TIMEOUT_MS = 300000;
14
+ export declare function runExecBranch(input: Record<string, unknown>, ctx: ToolRunContext, opts: RunCommandToolOptions): Promise<ToolResult>;
@@ -0,0 +1,161 @@
1
+ /**
2
+ * RunCommand's second, allowlisted call shape (`Exec`): a model-authored argv
3
+ * rather than a declared command key.
4
+ *
5
+ * Split out of run-command.ts (fix round 1, Minor) so the no-shell guarantee
6
+ * is structural rather than a comment pinned to file layout: this file must
7
+ * never import the declared branch's shell-templated command executor
8
+ * (the RunCommand sibling module resolves and spawns those through a real
9
+ * shell) or its shell-argument quoting helper (there is no shell string
10
+ * here to quote). `test/unit/tools/run-command-exec.test.ts` reads this
11
+ * file WHOLE and asserts neither one appears anywhere in it — a whole-file
12
+ * check that cannot be defeated by moving functions around within it,
13
+ * unlike the prior slice-from-a-known-function-name guard.
14
+ *
15
+ * Order matters and is fixed: `validateArgv` (shape/metacharacters) runs
16
+ * before `runExecBranch` is even reached — the runtime's policy check
17
+ * already ran it against the raw argv before `run()` was called at all, see
18
+ * `src/tools/policy.ts`. It is re-checked here too, because this function
19
+ * must also be safe to call directly, bypassing the runtime (as this file's
20
+ * own tests do). Then `deniedFlag` (source/destination-redirecting flags a
21
+ * verb-prefix grant cannot see), then `normalizeExec` (install-shaped
22
+ * hardening and workspace scoping), then `runArgv`.
23
+ */
24
+ import { relative } from "node:path";
25
+ import { agentOutputOverlay } from "#src/internal/agent-output-env";
26
+ import { runArgv } from "#src/internal/argv-exec";
27
+ import { formatExecBody } from "#src/internal/exec-framing";
28
+ import { deniedFlag, validateArgv } from "./exec-guard.js";
29
+ import { normalizeExec } from "./package-managers.js";
30
+ import { cutToByteCap, READ_CEILING } from "./truncate.js";
31
+ /**
32
+ * Deadline for the argv branch's spawn (`runExecBranch`).
33
+ *
34
+ * Deliberately longer than the declared branch's own default deadline
35
+ * (120_000ms, in the project's quality-command runner): a declared quality
36
+ * command runs entirely on code already on disk, while an install-shaped
37
+ * argv call here talks to a package registry over the network and may run
38
+ * a vendor postinstall script — both routinely take longer than a
39
+ * project's own test/lint/typecheck command.
40
+ */
41
+ export const EXEC_TIMEOUT_MS = 300_000;
42
+ /**
43
+ * Layer the AGENT=1 overlay onto an existing Exec env (or build a fresh env
44
+ * with just the overlay). Returns undefined when both inputs are undefined
45
+ * so the caller can omit the `env` key entirely and let `Bun.spawn` inherit
46
+ * the parent's environment on its own — the same shape `withAgentOutputEnv`
47
+ * applied via `normalizeEnvironment` in the verification runner, but here the
48
+ * inputs are partial: the Exec env is optional and the overlay may also be
49
+ * undefined when a marker is inherited or AGENT is stripped.
50
+ */
51
+ function mergedExecEnv(execEnv, strippedVars) {
52
+ const agentOverlay = agentOutputOverlay(strippedVars);
53
+ if (agentOverlay === undefined)
54
+ return execEnv !== undefined ? { ...execEnv } : undefined;
55
+ return { ...(execEnv ?? {}), ...agentOverlay };
56
+ }
57
+ /**
58
+ * Spawn the normalized argv through the launcher when one is configured and
59
+ * fall back to a direct `runArgv` call otherwise. The launcher branch carries
60
+ * the `stripEnvVars` as a shared array (Bun.spawn reads it once), while the
61
+ * direct branch spreads it so the deps seam sees the same shape every other
62
+ * `_argvExecDeps.spawn` test stubs.
63
+ */
64
+ async function launchExec(req) {
65
+ if (req.launcher !== undefined) {
66
+ return await req.launcher.run({
67
+ spec: { kind: "argv", argv: req.argv },
68
+ root: req.root,
69
+ cwd: req.cwd,
70
+ timeoutMs: EXEC_TIMEOUT_MS,
71
+ stripEnvVars: req.stripEnvVars,
72
+ ...(req.mergedEnv !== undefined ? { env: req.mergedEnv } : {}),
73
+ ...(req.signal !== undefined ? { signal: req.signal } : {}),
74
+ });
75
+ }
76
+ return {
77
+ ...(await runArgv({
78
+ argv: req.argv,
79
+ cwd: req.cwd,
80
+ timeoutMs: EXEC_TIMEOUT_MS,
81
+ stripEnvVars: [...req.stripEnvVars],
82
+ // Yarn 2+ carries its no-scripts mechanism here rather than in argv.
83
+ ...(req.mergedEnv !== undefined ? { env: req.mergedEnv } : {}),
84
+ ...(req.signal !== undefined ? { signal: req.signal } : {}),
85
+ })),
86
+ sandbox: undefined,
87
+ };
88
+ }
89
+ export async function runExecBranch(input, ctx, opts) {
90
+ if (opts.exec === undefined)
91
+ return { content: "argv is not available on this path", isError: true };
92
+ const invalid = validateArgv(input.argv);
93
+ if (invalid !== undefined)
94
+ return { content: invalid, isError: true };
95
+ const argv = input.argv;
96
+ // Real narrowing, not a cast: validateArgv above already rejected an
97
+ // empty argv, so this destructure cannot actually miss -- kept as a
98
+ // defensive fallback (matching package-managers.ts's own "unreachable"
99
+ // comments) rather than a postfix `!` or an `as string`.
100
+ const [binary] = argv;
101
+ if (binary === undefined)
102
+ return { content: "argv must not be empty", isError: true };
103
+ const flag = deniedFlag(argv);
104
+ if (flag !== undefined)
105
+ return { content: `flag ${flag} is not permitted`, isError: true };
106
+ const target = input.target === "repoRoot" ? "repoRoot" : "package";
107
+ const packageRelPath = relative(opts.exec.repoRoot, opts.exec.packageWorkdir);
108
+ const normalized = normalizeExec({
109
+ argv,
110
+ target,
111
+ repoRoot: opts.exec.repoRoot,
112
+ packageWorkdir: opts.exec.packageWorkdir,
113
+ packageRelPath,
114
+ allowScripts: opts.exec.allowScripts,
115
+ ...(opts.exec.packageName !== undefined ? { packageName: opts.exec.packageName } : {}),
116
+ });
117
+ if ("error" in normalized)
118
+ return { content: normalized.error, isError: true };
119
+ // US-004: opt the child into agent-friendly output. The Exec branch never
120
+ // rewrites the argv (that's the model's command), and the overlay is only
121
+ // `AGENT=1` — same rule the quality and verification runners apply. An
122
+ // inherited marker (`CLAUDECODE`/`REPL_ID`) speaks for itself, and a
123
+ // stripped AGENT stays stripped. The overlay is layered on top of any Exec
124
+ // env (the Yarn no-scripts key) so the latter survives wrapping alongside.
125
+ const mergedEnv = mergedExecEnv(normalized.env, opts.stripEnvVars ?? []);
126
+ try {
127
+ const launched = await launchExec({
128
+ argv: normalized.argv,
129
+ root: ctx.root,
130
+ cwd: normalized.cwd,
131
+ launcher: opts.exec.launcher,
132
+ mergedEnv,
133
+ stripEnvVars: opts.stripEnvVars ?? [],
134
+ signal: ctx.signal,
135
+ });
136
+ // US-001: match Bash's framing so an aborted Exec is rendered as an
137
+ // error with the cancellation banner (AC14 mirror) and an orphansKilled
138
+ // Exec appends the same `[nax]` footer (AC15 mirror).
139
+ const text = formatExecBody(launched, EXEC_TIMEOUT_MS);
140
+ return {
141
+ content: cutToByteCap(text, ctx.readCeiling ?? READ_CEILING),
142
+ isError: launched.timedOut || launched.exitCode !== 0 || launched.aborted === true,
143
+ // Task 7 reads this to write `executed` and `target` onto the ledger
144
+ // row. Returning it here, rather than re-deriving it in the runtime,
145
+ // keeps the recorded argv the one that actually ran.
146
+ audit: {
147
+ executed: normalized.argv,
148
+ target,
149
+ cwd: normalized.cwd,
150
+ ...(launched.sandbox !== undefined ? { sandbox: launched.sandbox } : {}),
151
+ },
152
+ };
153
+ }
154
+ catch (err) {
155
+ // A spawn-time failure (e.g. an unresolvable cwd) throws rather than
156
+ // resolving with a non-zero exit; surfaced as a normal tool error so it
157
+ // is indistinguishable, to the caller, from any other refusal above.
158
+ const message = err instanceof Error ? err.message : String(err);
159
+ return { content: message, isError: true };
160
+ }
161
+ }
@@ -0,0 +1,107 @@
1
+ import type { QualityCommandSpec } from "#src/internal/command-spec/index";
2
+ import { type CommandLauncher } from "../sandbox/index.ts";
3
+ import type { CodingTool } from "./registry.ts";
4
+ /**
5
+ * Context for RunCommand's allowlisted, model-authored argv branch (`Exec`).
6
+ *
7
+ * Populated only when the operation declared the `Exec` marker
8
+ * (`buildCodingToolSupport` in `src/agents/coding-tool-support.ts`).
9
+ */
10
+ export interface RunCommandExecOptions {
11
+ readonly repoRoot: string;
12
+ readonly packageWorkdir: string;
13
+ /** Manifest name, required by yarn/cargo's package-scoping form; absent when unresolvable. */
14
+ readonly packageName?: string;
15
+ readonly allowScripts: boolean;
16
+ /**
17
+ * The Exec tool's compiled grant patterns, as `resolvePermissions` produced
18
+ * them for THIS project/stage -- not `BUILT_IN_EXEC_PATTERNS` imported
19
+ * directly, because a project's own `Exec(...)` expression REPLACES that
20
+ * built-in list rather than extending it (see the comment on
21
+ * `BUILT_IN_EXEC_PATTERNS` in src/config/permissions.ts). Read only to
22
+ * render the tool description (#1937): the policy check itself still runs
23
+ * against the runtime's own compiled grant in policy.ts, so this field
24
+ * being stale or absent could make the description wrong but can never
25
+ * widen what actually executes.
26
+ */
27
+ readonly patterns: readonly string[];
28
+ /** P4: how the argv runs. Absent = direct runArgv (unit tests). */
29
+ readonly launcher?: CommandLauncher;
30
+ }
31
+ /** What RunCommand hands the runner for one declared command. */
32
+ export interface DeclaredCommandRequest {
33
+ readonly commandName: string;
34
+ readonly command: QualityCommandSpec;
35
+ readonly workdir: string;
36
+ readonly stripEnvVars: string[];
37
+ readonly origin: "agent-tool";
38
+ }
39
+ /** What RunCommand reads back. */
40
+ export interface DeclaredCommandResult {
41
+ readonly success: boolean;
42
+ readonly exitCode: number;
43
+ readonly output: string;
44
+ }
45
+ /** Runs one declared command; nax supplies `runQualityCommand` (S1 spec port 7). */
46
+ export type DeclaredCommandRunner = (request: DeclaredCommandRequest) => Promise<DeclaredCommandResult>;
47
+ export interface RunCommandToolOptions {
48
+ /** Secret environment variables excluded from agent-triggered commands. */
49
+ readonly stripEnvVars?: readonly string[];
50
+ /** See `RunCommandExecOptions`. */
51
+ readonly exec?: RunCommandExecOptions;
52
+ /**
53
+ * Execution cwd for the DECLARED (non-Exec) branch below, independent of
54
+ * `ctx.root` (tool containment). Falls back to `ctx.root` when absent —
55
+ * post-PR2 (single-frame redesign) `ctx.root` is the story's repo-rooted
56
+ * execution root, so an omitted `commandCwd` runs the declared command at
57
+ * the repo root, NOT the package dir. Every production caller threads
58
+ * `commandCwd` (see the `buildCodingToolSupport` producer below); the
59
+ * fallback is effectively unreachable in production and only fires from
60
+ * tests that bypass the support seam — see the use site for the exact
61
+ * behavior.
62
+ *
63
+ * PRODUCER: src/agents/coding-tool-support.ts (`buildCodingToolSupport`'s
64
+ * `commandCwd` arg).
65
+ */
66
+ readonly commandCwd?: string;
67
+ /**
68
+ * Runs a DECLARED (non-Exec) command (S1 spec section 4.2, port 7). nax
69
+ * supplies `runQualityCommand` through `resolveCodingToolSupport`; absent,
70
+ * the tool answers `exit 1` and spawns nothing.
71
+ */
72
+ readonly runDeclaredCommand?: DeclaredCommandRunner;
73
+ }
74
+ /**
75
+ * An ARRAY value is quoted per element and joined; a string value is quoted
76
+ * whole. The distinction carries the element boundaries through substitution,
77
+ * which a pre-joined string cannot: the join would be re-split and a path
78
+ * under `/tmp/my dir/` would become two arguments (nax#1998).
79
+ */
80
+ export declare function substituteCommand(template: string, values: Record<string, string | readonly string[]>): string | {
81
+ error: string;
82
+ };
83
+ /**
84
+ * Apply placeholder substitution across a spec. A list substitutes into every
85
+ * entry and fails as a whole if any entry fails, so a partially-substituted
86
+ * list can never reach the shell.
87
+ *
88
+ * Each entry only receives the subset of `values` it actually declares
89
+ * placeholders for -- list entries commonly have different placeholder needs
90
+ * (e.g. `["tsc --noEmit", "bun test {{files}}"]`), and `substituteCommand`
91
+ * rejects a value that isn't a placeholder in the template it's checking, by
92
+ * design (it's what stops a value silently going nowhere). Passing the full
93
+ * shared `values` object to every entry would make every entry without
94
+ * {{files}} fail that check.
95
+ *
96
+ * But per-entry filtering alone would let a value that no entry in the whole
97
+ * spec declares vanish silently (every entry's filtered set would just be
98
+ * empty, and every entry would substitute cleanly) -- so before filtering
99
+ * per entry, every key in `values` is checked against the UNION of
100
+ * placeholders declared across the whole spec, and rejected with the same
101
+ * "unrecognized value" contract `substituteCommand` gives the single-string
102
+ * case if it isn't declared anywhere.
103
+ */
104
+ export declare function substituteCommandSpec(spec: QualityCommandSpec, values: Record<string, string | readonly string[]>): QualityCommandSpec | {
105
+ error: string;
106
+ };
107
+ export declare function createRunCommandTool(declared: ReadonlyMap<string, QualityCommandSpec>, opts?: RunCommandToolOptions): CodingTool;