@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,325 @@
1
+ /**
2
+ * The package-manager knowledge table for the install-shaped exec branch.
3
+ *
4
+ * Each entry is DATA — a description of one manager's install verbs (and
5
+ * their aliases), its no-scripts mechanism, how to rewrite argv for a
6
+ * package-scoped versus repo-root-scoped call, and which incoming flags
7
+ * would smuggle in a second workspace member if we spliced our own scoping
8
+ * flag in beside them. No branching policy lives here; `normalizeExec` in
9
+ * `package-managers.ts` is the only place that interprets these fields.
10
+ *
11
+ * Facts this table encodes, verified against each tool's own documentation
12
+ * (see task-4 brief, 2026-09-06) plus two review-driven fix rounds:
13
+ *
14
+ * - Yarn 2+ ("Berry") has no `--ignore-scripts` flag; it honours the
15
+ * `enableScripts` setting, overridable per-invocation via the
16
+ * `YARN_ENABLE_SCRIPTS` environment variable. Yarn 1 ("Classic") takes
17
+ * `--ignore-scripts`. Passing `--ignore-scripts` to Yarn 2+ is a hard
18
+ * error, so version detection that is inconclusive must default to the
19
+ * Yarn 2+ branch — the env var is inert on Yarn 1, the flag is fatal on
20
+ * Yarn 2+, and failing toward the inert option is the safe direction.
21
+ * - pnpm's `--filter` requires the `./` prefix to select by path
22
+ * (`--filter ./packages/foo`); the bare form (`packages/foo`) is parsed as
23
+ * a package NAME and silently selects nothing.
24
+ * - `yarn workspace <name>` and `cargo add -p <name>` take the manifest
25
+ * NAME, not a path.
26
+ *
27
+ * pip and uv no-scripts mechanisms: I could not confirm a mechanism from
28
+ * either tool's own documentation that actually suppresses arbitrary code
29
+ * execution during an install the way `--ignore-scripts` does for npm/bun/
30
+ * yarn-classic:
31
+ *
32
+ * - pip has no `--ignore-scripts` equivalent at all. `--only-binary :all:`
33
+ * forces wheel-only resolution (no sdist, so no `setup.py` executes for
34
+ * any package pip resolves), but it is a resolution-strategy flag, not a
35
+ * scripts switch — it errors the whole install if a required dependency
36
+ * ships no wheel, rather than degrading gracefully. Wiring it in as if it
37
+ * were "the no-scripts flag" would look like protection where none was
38
+ * verified, and I have not confirmed it is safe as a blanket default
39
+ * here. Left as `{ none: true }`.
40
+ * - uv installs prebuilt wheels by default and only builds from source
41
+ * (running a build backend, e.g. `setup.py`/PEP 517 hooks) when a
42
+ * dependency has no wheel for the target platform, same as pip. There is
43
+ * no uv flag documented as suppressing that fallback build step itself —
44
+ * `--no-build-isolation` changes how a source build is isolated, it does
45
+ * not prevent one from happening, so it is not a substitute either. Left
46
+ * as `{ none: true }` per the brief's instruction not to invent a switch.
47
+ *
48
+ * Both gaps mean pip/uv installs get cwd/scoping normalization but no
49
+ * scripts-suppression hardening. This should be tracked as a follow-up
50
+ * rather than silently accepted.
51
+ *
52
+ * Install-verb ALIASES (fix round 1, Critical finding A): each manager's
53
+ * install verb has common short aliases the model can reach for just as
54
+ * easily as the canonical spelling (`npm i` is as ordinary an invocation as
55
+ * `npm install`). They are listed here as additional single-token verb
56
+ * sequences, matched by `classifyExec` exactly like the canonical verb in
57
+ * both its position-anchored match and its fail-closed scan — never as a
58
+ * special case in the matcher itself. Sources: npm's own `install` command
59
+ * aliases (`i`, `in`, `ins`, `inst`, `insta`, `instal`, `install`, `add`) and
60
+ * its `install-test`/`it` alias pair; pnpm's `i`/`install-test` aliases of
61
+ * `install`; bun's `i`/`a` aliases of `install`/`add`. Yarn Classic and
62
+ * Berry do not document a short alias for `install`/`add`, so none is
63
+ * added — checked and confirmed empty, not merely unresearched.
64
+ *
65
+ * Workspace-scoping SMUGGLING (fix round 1, Critical finding 2 + addendum
66
+ * A/C): before this table splices in its own scoping flag or no-scripts
67
+ * flag, `normalizeExec` screens the incoming argv for tokens that would
68
+ * change what gets targeted if left in place — a second `-w`/`--filter`
69
+ * naming another member, or a `--ignore-scripts`/`--no-ignore-scripts` the
70
+ * model added itself. `scopingConflict` is each entry's screen for the
71
+ * first kind; the second kind (`SCRIPTS_CONTROL_FLAG`) is universal and
72
+ * lives in `package-managers.ts` since it isn't manager-specific data. Both
73
+ * DENY rather than strip: dropping a flag the model wrote changes the
74
+ * request while reporting success, which is worse than a visible refusal.
75
+ * Coverage: npm `-w`/`--workspace`/`--workspaces`/`--workspace-root`/
76
+ * `--include-workspace-root`; pnpm `--filter`/`-f`/`-w`/`--workspace-root`/
77
+ * `--filter-prod`/`--include-workspace-root`; cargo `-p`/`--package`; uv
78
+ * `--package`/`--all-packages`. Yarn's `workspace`/`workspaces` leading
79
+ * subcommand is not screened here — see the comment on yarn's
80
+ * `scopingConflict` for why that path is already unreachable by
81
+ * construction.
82
+ *
83
+ * Directory-redirect CONTAINMENT (fix round 2): `target` is a closed enum
84
+ * precisely so no path can arrive from the model — `normalizeExec` computes
85
+ * cwd, the model never supplies one. A directory-redirect flag inside argv
86
+ * (`bun add --cwd /elsewhere x`) hands that choice straight back, ignoring
87
+ * whatever cwd this table computed. This is the containment property
88
+ * itself, not a scoping nicety, so it is screened for EVERY manager entry
89
+ * via `globalDirectoryFlags`/`installDirectoryFlags`, denied on the same
90
+ * deny-never-strip basis as scoping/scripts-control flags.
91
+ *
92
+ * A flag global to the manager (works with any subcommand, not just an
93
+ * install verb) is screened for BOTH install-shaped and generic calls —
94
+ * `normalizeExec` checks it before branching on classification kind at all,
95
+ * because a generic call (`bun x tsc --cwd /elsewhere`) escapes the same
96
+ * containment otherwise. An install-specific flag is screened only when the
97
+ * call is already install-shaped, since it has no effect (or no meaning) on
98
+ * a generic invocation of that manager.
99
+ *
100
+ * | manager | global (`globalDirectoryFlags`) | install-only (`installDirectoryFlags`) |
101
+ * |---|---|---|
102
+ * | bun | `--cwd` | — |
103
+ * | yarn | `--cwd`, `-C` (fix round 3 — `-C` is added for symmetry with pnpm; not confirmed as a documented yarn alias, but an over-denial here is the safe direction) | — |
104
+ * | pnpm | `--dir`, `-C` | — |
105
+ * | npm | — | — (`--prefix` changes npm's effective directory; already denied by `DENIED_FLAGS` in `exec-guard.ts` regardless of manager — not duplicated here) |
106
+ * | cargo | `--manifest-path` (accepted by nearly every cargo subcommand, `add`/`fetch` included) | — |
107
+ * | pip | `--python` (a general pip option, valid before or after the subcommand, that redirects which interpreter/environment gets installed into) | `--target`, `-t` (documented short alias, fix round 3), `--root` (install-destination overrides, meaningful only for `pip install`; `--prefix` is likewise install-scoped but already covered by the same shared `DENIED_FLAGS` entry as npm's, so also not duplicated) |
108
+ * | uv | `--directory`, `--project` (both are documented as general uv options, accepted ahead of the subcommand, that change what "the project" means for the whole invocation) | — |
109
+ * | go | `-C` (a general go flag: "change to dir before running the command") | — |
110
+ *
111
+ * `uv pip <anything>` (fix round 3, finding 3) is denied at classification
112
+ * time, not treated as a directory-redirect flag gap — see the comment on
113
+ * `isNestedPipInvocation` in `package-managers.ts` for why nesting one
114
+ * manager's semantics inside another's entry was rejected in favor of a
115
+ * flat denial.
116
+ */
117
+ import { normalizeFlagToken } from "./exec-guard.js";
118
+ const IGNORE_SCRIPTS_FLAG = { flag: "--ignore-scripts" };
119
+ const NO_MECHANISM = { none: true };
120
+ /** Shared by every `packageForm` that needs the member's manifest NAME (yarn, cargo, uv).
121
+ * `normalizeExec` already denies before calling `packageForm` when
122
+ * `entry.needsPackageName` is true and `input.packageName` is undefined —
123
+ * this exists so each `packageForm` can narrow `ctx.packageName` from
124
+ * `string | undefined` to `string` without a postfix `!` (banned in this
125
+ * repo), and as a second, independent guard rather than only a comment. */
126
+ function packageNameOrError(ctx, manager) {
127
+ if (ctx.packageName === undefined) {
128
+ return { error: `${manager} workspace scoping requires the member package's manifest name` };
129
+ }
130
+ return { name: ctx.packageName };
131
+ }
132
+ /** A token anywhere in argv (after the binary) that case/`=`-normalizes to one of `flags`. */
133
+ function flagConflict(argv, flags) {
134
+ const lowered = new Set(flags.map((flag) => normalizeFlagToken(flag)));
135
+ for (let i = 1; i < argv.length; i++) {
136
+ const token = argv[i];
137
+ const normalized = normalizeFlagToken(token);
138
+ if (lowered.has(normalized))
139
+ return token;
140
+ for (const flag of lowered) {
141
+ if (flag.length === 2 && normalized.startsWith(flag) && normalized.length > flag.length)
142
+ return token;
143
+ }
144
+ }
145
+ return undefined;
146
+ }
147
+ export const MANAGER_TABLE = {
148
+ bun: {
149
+ installVerbs: [["install"], ["i"], ["add"], ["a"]],
150
+ noScripts: () => IGNORE_SCRIPTS_FLAG,
151
+ needsPackageName: false,
152
+ // bun has no workspace-scoping flag in this table's model — nothing to smuggle.
153
+ scopingConflict: () => undefined,
154
+ // `--cwd` is global to bun (any subcommand), so it must be screened
155
+ // regardless of classification — see the file header table.
156
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--cwd"]),
157
+ installDirectoryConflict: () => undefined,
158
+ // bun resolves the workspace member purely from cwd — no scoping flag needed.
159
+ packageForm: (argv, ctx) => ({ argv, cwd: ctx.packageWorkdir }),
160
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
161
+ },
162
+ npm: {
163
+ installVerbs: [
164
+ ["install"],
165
+ ["i"],
166
+ ["in"],
167
+ ["ins"],
168
+ ["inst"],
169
+ ["insta"],
170
+ ["instal"],
171
+ ["install-test"],
172
+ ["it"],
173
+ ["add"],
174
+ ["ci"],
175
+ ],
176
+ noScripts: () => IGNORE_SCRIPTS_FLAG,
177
+ needsPackageName: false,
178
+ scopingConflict: (argv) => flagConflict(argv, ["-w", "--workspace", "--workspaces", "--workspace-root", "--include-workspace-root"]),
179
+ // npm's directory-redirect flag is `--prefix`, already denied by the
180
+ // shared, manager-agnostic `DENIED_FLAGS` in `exec-guard.ts` — not
181
+ // duplicated here (see the file header table).
182
+ globalDirectoryConflict: () => undefined,
183
+ installDirectoryConflict: () => undefined,
184
+ // `npm -w <relPath> <verb> ...` runs from the repo root; `-w` accepts a
185
+ // relative path.
186
+ packageForm: (argv, ctx) => ({
187
+ argv: [argv[0], "-w", ctx.packageRelPath, ...argv.slice(1)],
188
+ cwd: ctx.repoRoot,
189
+ }),
190
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
191
+ },
192
+ pnpm: {
193
+ installVerbs: [["install"], ["i"], ["install-test"], ["add"]],
194
+ noScripts: () => IGNORE_SCRIPTS_FLAG,
195
+ needsPackageName: false,
196
+ scopingConflict: (argv) => flagConflict(argv, ["--filter", "-f", "-w", "--workspace-root", "--filter-prod", "--include-workspace-root"]),
197
+ // `--dir`/`-C` are global to pnpm (any subcommand) — screened
198
+ // regardless of classification.
199
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--dir", "-C"]),
200
+ installDirectoryConflict: () => undefined,
201
+ // The `./` prefix is mandatory: pnpm parses a bare "packages/foo" as a
202
+ // package NAME, which silently selects nothing.
203
+ packageForm: (argv, ctx) => ({
204
+ argv: [argv[0], "--filter", `./${ctx.packageRelPath}`, ...argv.slice(1)],
205
+ cwd: ctx.repoRoot,
206
+ }),
207
+ // `pnpm add -w ...` targets the workspace root package explicitly.
208
+ rootForm: (argv, ctx) => ({
209
+ argv: [argv[0], argv[1], "-w", ...argv.slice(2)],
210
+ cwd: ctx.repoRoot,
211
+ }),
212
+ },
213
+ yarn: {
214
+ installVerbs: [["install"], ["add"]],
215
+ noScripts: (ctx) => (ctx.yarnMajor === 1 ? IGNORE_SCRIPTS_FLAG : { env: { YARN_ENABLE_SCRIPTS: "false" } }),
216
+ needsPackageName: true,
217
+ // `yarn workspace <name> ...`/`yarn workspaces ...` as a LEADING
218
+ // subcommand would be the smuggling vector here, but it is already
219
+ // unreachable: `classifyExec`'s position-anchored match only ever
220
+ // classifies a call as install-shaped when the very first non-flag
221
+ // token IS an install verb. A leading "workspace"/"workspaces" token
222
+ // fails that match, and the real verb further along the argv is then
223
+ // caught by the fail-closed scan instead (denied, not silently made
224
+ // generic) before this function is ever reached. No independent screen
225
+ // is needed on top of that.
226
+ scopingConflict: () => undefined,
227
+ // `--cwd` is global to yarn (any subcommand) — screened regardless of
228
+ // classification. `-C` is added for symmetry with pnpm's entry (fix
229
+ // round 3, finding 2) — yarn's own docs do not document a `-C` short
230
+ // alias, so this is an over-denial rather than a confirmed fact; that
231
+ // is the safe direction here, so it stays.
232
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--cwd", "-C"]),
233
+ installDirectoryConflict: () => undefined,
234
+ // `yarn workspace <name> ...` takes the manifest NAME, not a path.
235
+ packageForm: (argv, ctx) => {
236
+ const resolved = packageNameOrError(ctx, "yarn");
237
+ if ("error" in resolved)
238
+ return resolved;
239
+ return { argv: [argv[0], "workspace", resolved.name, ...argv.slice(1)], cwd: ctx.repoRoot };
240
+ },
241
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
242
+ },
243
+ pip: {
244
+ installVerbs: [["install"]],
245
+ // See file header: no confirmed ignore-scripts equivalent for pip.
246
+ noScripts: () => NO_MECHANISM,
247
+ needsPackageName: false,
248
+ // pip has no workspace concept in this table's model — nothing to smuggle.
249
+ scopingConflict: () => undefined,
250
+ // `--python` is a general pip option (valid before or after the
251
+ // subcommand) that redirects which interpreter/environment gets
252
+ // installed into — screened regardless of classification. `--prefix`
253
+ // would be the other general redirect, but it is already covered by
254
+ // the same shared `DENIED_FLAGS` entry as npm's, so not duplicated.
255
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--python"]),
256
+ // `--target`/`--root` only mean anything for `pip install`. `-t` is
257
+ // pip's own documented short alias for `--target` (fix round 3,
258
+ // finding 1) — checked pip's docs for a short alias of `--root` and
259
+ // `--python` too; neither documents one, so only `-t` is added here.
260
+ installDirectoryConflict: (argv) => flagConflict(argv, ["--target", "-t", "--root"]),
261
+ packageForm: (argv, ctx) => ({ argv, cwd: ctx.packageWorkdir }),
262
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
263
+ },
264
+ uv: {
265
+ installVerbs: [["sync"], ["add"]],
266
+ // See file header: no confirmed ignore-scripts equivalent for uv.
267
+ noScripts: () => NO_MECHANISM,
268
+ needsPackageName: true,
269
+ scopingConflict: (argv) => flagConflict(argv, ["--package", "--all-packages"]),
270
+ // `--directory`/`--project` are general uv options (accepted ahead of
271
+ // the subcommand) that change what "the project" means for the whole
272
+ // invocation — screened regardless of classification.
273
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--directory", "--project"]),
274
+ installDirectoryConflict: () => undefined,
275
+ // `uv <verb> --package <name> ...` restricts the operation to one
276
+ // workspace member; runs from the repo root.
277
+ packageForm: (argv, ctx) => {
278
+ const resolved = packageNameOrError(ctx, "uv");
279
+ if ("error" in resolved)
280
+ return resolved;
281
+ return {
282
+ argv: [argv[0], argv[1], "--package", resolved.name, ...argv.slice(2)],
283
+ cwd: ctx.repoRoot,
284
+ };
285
+ },
286
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
287
+ },
288
+ go: {
289
+ installVerbs: [["get"], ["mod", "download"]],
290
+ // Downloads only; runs nothing.
291
+ noScripts: () => NO_MECHANISM,
292
+ needsPackageName: false,
293
+ // go has no workspace-scoping flag in this table's model — nothing to smuggle.
294
+ scopingConflict: () => undefined,
295
+ // `-C dir` is a general go flag ("change to dir before running the
296
+ // command") — screened regardless of classification.
297
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["-C"]),
298
+ installDirectoryConflict: () => undefined,
299
+ packageForm: (argv, ctx) => ({ argv, cwd: ctx.packageWorkdir }),
300
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
301
+ },
302
+ cargo: {
303
+ installVerbs: [["add"], ["fetch"]],
304
+ // `cargo add` edits a manifest, `cargo fetch` downloads; neither runs a
305
+ // build script during the command itself.
306
+ noScripts: () => NO_MECHANISM,
307
+ needsPackageName: true,
308
+ scopingConflict: (argv) => flagConflict(argv, ["-p", "--package"]),
309
+ // `--manifest-path` is accepted by nearly every cargo subcommand,
310
+ // `add`/`fetch` included — screened regardless of classification.
311
+ globalDirectoryConflict: (argv) => flagConflict(argv, ["--manifest-path"]),
312
+ installDirectoryConflict: () => undefined,
313
+ // `cargo add -p <name> ...` takes the manifest NAME, not a path.
314
+ packageForm: (argv, ctx) => {
315
+ const resolved = packageNameOrError(ctx, "cargo");
316
+ if ("error" in resolved)
317
+ return resolved;
318
+ return {
319
+ argv: [argv[0], argv[1], "-p", resolved.name, ...argv.slice(2)],
320
+ cwd: ctx.repoRoot,
321
+ };
322
+ },
323
+ rootForm: (argv, ctx) => ({ argv, cwd: ctx.repoRoot }),
324
+ },
325
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Shared types between `package-managers.ts` (the public surface) and
3
+ * `package-managers-table.ts` (the per-manager data). Split out so the table
4
+ * does not need to import the module that imports it.
5
+ */
6
+ export type ExecTarget = "package" | "repoRoot";
7
+ /**
8
+ * The subset of `NormalizeInput` a manager entry's functions need, minus the
9
+ * argv/target already threaded explicitly through the call.
10
+ */
11
+ export interface WorkspaceContext {
12
+ readonly repoRoot: string;
13
+ readonly packageWorkdir: string;
14
+ readonly packageRelPath: string;
15
+ readonly packageName?: string;
16
+ readonly allowScripts: boolean;
17
+ /** Yarn major version, when known. Undefined means "inconclusive" — the
18
+ * Yarn entry's `noScripts` must default to the Yarn 2+ (env-var) branch,
19
+ * since the flag branch is a hard error on Yarn 2+ and the env var is
20
+ * merely inert on Yarn 1. */
21
+ readonly yarnMajor?: number;
22
+ }
23
+ export type NoScripts = {
24
+ readonly flag: string;
25
+ } | {
26
+ readonly env: Readonly<Record<string, string>>;
27
+ } | {
28
+ readonly none: true;
29
+ };
30
+ export type NormalizeResult = {
31
+ readonly argv: readonly string[];
32
+ readonly cwd: string;
33
+ readonly env?: Readonly<Record<string, string>>;
34
+ } | {
35
+ readonly error: string;
36
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared types between `package-managers.ts` (the public surface) and
3
+ * `package-managers-table.ts` (the per-manager data). Split out so the table
4
+ * does not need to import the module that imports it.
5
+ */
6
+ export {};
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Classification and normalization for the install-shaped exec branch.
3
+ *
4
+ * A call is install-shaped only when `argv[0]` is a known manager AND the
5
+ * verb is one of that manager's install verbs; such calls are hardened (a
6
+ * no-scripts mechanism, when one is known) and normalized (scoped to the
7
+ * story's own workspace member) by `normalizeExec`. Everything else is
8
+ * generic: it runs exactly as given, at the target cwd, with no rewriting
9
+ * and no mechanism — reachable only through an explicit `Exec(...)` grant
10
+ * elsewhere in the policy.
11
+ *
12
+ * Both directions matter. Without the generic class, something like
13
+ * `bun x tsc --noEmit` could never be permitted by any grant. Without the
14
+ * "known manager plus install verb" test, a loosely classified `bun add`
15
+ * could reach the generic path and skip its no-scripts mechanism entirely.
16
+ * Neither class may borrow the other's treatment — this module is pure
17
+ * classification/data lookup, no spawning, no policy, no I/O.
18
+ *
19
+ * Classification is FAIL-CLOSED (fix round 1, Critical finding 1). A global
20
+ * flag ahead of the verb (`npm --loglevel=silent install x`) must not push
21
+ * a real install onto the unhardened generic path, but a flag's own VALUE
22
+ * token must not be mistaken for the verb either. Three branches, in order:
23
+ *
24
+ * 1. Find the first token after argv[0] that does not start with "-". If
25
+ * it (or the token sequence starting there, for multi-token verbs
26
+ * like `go mod download`) matches one of this manager's install verbs
27
+ * (aliases included), the call is install-shaped.
28
+ * 2. Otherwise, if ANY token anywhere in argv equals one of this
29
+ * manager's install verb tokens, DENY, naming the token. This is the
30
+ * fail-closed branch: `npm --loglevel silent install x` has "silent"
31
+ * as its first non-flag token (branch 1 misses, because a flag's
32
+ * value is not the verb), so the "install" token later in argv trips
33
+ * this branch instead. That is deliberate — a visible refusal the
34
+ * model can retry without the global flag beats a silent unhardened
35
+ * install. Do not "improve" this into a fall-through to generic.
36
+ * 3. Otherwise the call is generic.
37
+ *
38
+ * A manager invocation can also be DISGUISED rather than merely flag-led
39
+ * (addendum finding B): `npx`/`bunx`/`pnpx` run an arbitrary package outside
40
+ * this table's model entirely, and `pnpm dlx npm install x` / `yarn dlx bun
41
+ * add x` launder a real manager invocation through a dlx-style verb. Both
42
+ * shapes are denied before verb classification even runs — there is no
43
+ * argv shape here this table can normalize safely, so neither may fall
44
+ * through to generic. `argv[0]` is also case- and executable-suffix-
45
+ * normalized (`NPM`, `npm.cmd`, `npm.exe` all resolve to the `npm` entry)
46
+ * before every manager lookup; the path-separator form (`./npm`) is already
47
+ * refused upstream by `validateArgv` in `exec-guard.ts` and is not
48
+ * duplicated here.
49
+ *
50
+ * A directory-redirect flag (`--cwd`, `--dir`, `--manifest-path`, ...) is
51
+ * denied on the same basis (fix round 2): `target` is a closed enum
52
+ * precisely so no path can arrive from the model, and a flag like this
53
+ * hands that choice straight back. Manager-global redirect flags are
54
+ * screened for install-shaped AND generic calls alike — see
55
+ * `package-managers-table.ts`'s file header for the full per-manager table
56
+ * of which flags are global versus install-only.
57
+ *
58
+ * `uv pip <anything>` is also denied at classification time (fix round 3,
59
+ * finding 3) — see `isNestedPipInvocation` for why nesting is rejected in
60
+ * favor of a flat denial.
61
+ *
62
+ * None of the fix-round-3 gaps (pip's `-t` alias, yarn's `-C`, `uv pip`
63
+ * nesting) is reachable under the built-in default allowlist, which is
64
+ * install-only and contains neither `uv pip *`, a bare `pip install`, nor
65
+ * a yarn form with `-C`. They become reachable only when a project writes
66
+ * a widening `Exec(...)` grant by hand — defense-in-depth, not a live hole
67
+ * under the shipped default.
68
+ */
69
+ import type { NormalizeResult, WorkspaceContext } from "./package-managers-types.ts";
70
+ export type { ExecTarget, NormalizeResult } from "./package-managers-types.ts";
71
+ import type { ExecTarget } from "./package-managers-types.ts";
72
+ export interface NormalizeInput extends WorkspaceContext {
73
+ readonly argv: readonly string[];
74
+ readonly target: ExecTarget;
75
+ }
76
+ /**
77
+ * Lowercases and strips a trailing executable suffix so `NPM`, `npm.cmd`
78
+ * and `npm.exe` all resolve to the same `MANAGER_TABLE` entry as `npm`.
79
+ * Path-separator forms (`./npm`, `..\npm.exe`) are refused upstream by
80
+ * `validateArgv` in `exec-guard.ts` and are not re-checked here.
81
+ */
82
+ export declare function normalizeManagerBinary(token: string): string;
83
+ export declare function isKnownManager(binary: string): boolean;
84
+ export declare function classifyExec(argv: readonly string[]): "install" | "generic" | "deny";
85
+ export declare function normalizeExec(input: NormalizeInput): NormalizeResult;