@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,32 @@
1
+ import type { CommandGuard, GuardDecision, ModelResult, RuleResult } from "./types.ts";
2
+ /**
3
+ * The pure scorer: rules + classifier + temp-only state + threshold.
4
+ *
5
+ * `model` is `undefined` when the temp-only check skipped the classifier
6
+ * (the shadow's row still classifies, but the guard does not consult it).
7
+ * The temp-only basis still applies the rule score — a temp-only command
8
+ * that trips a non-`outside_project` rule (e.g. `rm -rf /tmp/x` hits
9
+ * `deletes_data`) flags, while `outside_project` alone scores 0.
10
+ */
11
+ export declare function scoreGuard(input: {
12
+ readonly rules: RuleResult;
13
+ readonly model: ModelResult | undefined;
14
+ readonly tempOnly: boolean;
15
+ readonly threshold: number;
16
+ }): GuardDecision;
17
+ /**
18
+ * Build a `CommandGuard` from the shadow's rule scorer and the cached
19
+ * classifier promise it shares with the shadow.
20
+ *
21
+ * The guard never throws: every step of `assess` (rule scoring, the temp-
22
+ * only check, the cached classify, the decision table) is wrapped in a
23
+ * single try/catch that falls through to a no-rule / no-model rules-only
24
+ * decision with score 0. The shadow classifies once per command; `assess`
25
+ * awaits the cached promise rather than re-classifying.
26
+ */
27
+ export declare function createCommandGuard(opts: {
28
+ readonly threshold: number;
29
+ readonly scoreRules: (command: string, cwd: string | undefined) => RuleResult;
30
+ /** Returns the cached classifier promise for `command`. */
31
+ readonly classifyCached: (command: string) => Promise<ModelResult>;
32
+ }): CommandGuard;
@@ -0,0 +1,179 @@
1
+ /**
2
+ * The P5 flag-for-review guard (US-003).
3
+ *
4
+ * The shadow observes every command. The guard, when configured, composes a
5
+ * score from the same rule result and the same classifier promise the shadow
6
+ * awaits, decides whether to flag, and names the dominant category. It is
7
+ * total by construction — it never rejects, never asks, never denies; the
8
+ * caller (US-004's tool ask routing) decides what a flag means downstream.
9
+ *
10
+ * `scoreGuard` is the pure decision table `assess` composes. It is exported
11
+ * so two rules `assess` alone cannot express — the temp-only exemption's
12
+ * `outside_project` skip and the harm-tie-breaker — stay unit-testable.
13
+ */
14
+ import { isTempOnly } from "./temp-only.js";
15
+ import { QUESTION_IDS } from "./types.js";
16
+ /**
17
+ * The first category in `QUESTION_IDS` order that `hits` sets to true.
18
+ * `skip` removes categories the caller has already accounted for
19
+ * (temp-only drops `outside_project`).
20
+ */
21
+ function firstHit(hits, skip = new Set()) {
22
+ for (const id of QUESTION_IDS) {
23
+ if (skip.has(id))
24
+ continue;
25
+ if (hits[id])
26
+ return id;
27
+ }
28
+ return undefined;
29
+ }
30
+ /**
31
+ * `harm = 1 - P(none)`; `noulMax = max P(yes)` over the six noul questions;
32
+ * `modelScore = (harm + noulMax) / 2`.
33
+ *
34
+ * The harm category other than `none` with the highest probability names
35
+ * the decision; ties go to `QUESTION_IDS` order. Both halves are bounded
36
+ * by `[0, 1]`, so the score is too.
37
+ */
38
+ function scoreFromAnswer(answer) {
39
+ const harm = 1 - answer.answers.harm.none;
40
+ const noulMax = Math.max(...QUESTION_IDS.map((id) => answer.answers.noul[id]));
41
+ let topProb = -Infinity;
42
+ let topId;
43
+ for (const id of QUESTION_IDS) {
44
+ const p = answer.answers.harm[id];
45
+ if (p > topProb) {
46
+ topProb = p;
47
+ topId = id;
48
+ }
49
+ }
50
+ return { score: (harm + noulMax) / 2, category: topId };
51
+ }
52
+ /** True when any of the six rule categories hits. `outside_project` is included. */
53
+ function ruleScore(rules) {
54
+ return QUESTION_IDS.some((id) => rules.hits[id]) ? 1 : 0;
55
+ }
56
+ /**
57
+ * Temp-only variant of `ruleScore`: `outside_project` is skipped, since the
58
+ * temp-only exemption routes around it. A path entirely outside the project
59
+ * is acceptable while the sandbox confines temp writes; the classifier is
60
+ * not consulted for the assessment.
61
+ */
62
+ function ruleScoreTempOnly(rules) {
63
+ return QUESTION_IDS.some((id) => id !== "outside_project" && rules.hits[id]) ? 1 : 0;
64
+ }
65
+ /**
66
+ * The pure scorer: rules + classifier + temp-only state + threshold.
67
+ *
68
+ * `model` is `undefined` when the temp-only check skipped the classifier
69
+ * (the shadow's row still classifies, but the guard does not consult it).
70
+ * The temp-only basis still applies the rule score — a temp-only command
71
+ * that trips a non-`outside_project` rule (e.g. `rm -rf /tmp/x` hits
72
+ * `deletes_data`) flags, while `outside_project` alone scores 0.
73
+ */
74
+ export function scoreGuard(input) {
75
+ const { rules, model, tempOnly, threshold } = input;
76
+ // Temp-only path: the classifier is skipped. A rule hit scores 1;
77
+ // `outside_project` is exempt. An empty hit set scores 0. The basis
78
+ // names the exemption even when a rule carries the flag.
79
+ if (tempOnly) {
80
+ const score = ruleScoreTempOnly(rules);
81
+ const flagged = score >= threshold;
82
+ // Per spec: category is present when a rule hit carries the flag.
83
+ // `outside_project` is exempt under the temp-only check, so it never
84
+ // names a temp-only decision.
85
+ const category = flagged ? firstHit(rules.hits, new Set(["outside_project"])) : undefined;
86
+ return {
87
+ flagged,
88
+ score,
89
+ threshold,
90
+ basis: "temp-only",
91
+ ...(category !== undefined ? { category } : {}),
92
+ };
93
+ }
94
+ // Classifier unreachable / oversized / rejected / unavailable: rules-only.
95
+ if (model === undefined || model.status === "oversize" || model.status === "unavailable") {
96
+ const score = ruleScore(rules);
97
+ const flagged = score >= threshold;
98
+ const category = flagged ? firstHit(rules.hits) : undefined;
99
+ return {
100
+ flagged,
101
+ score,
102
+ threshold,
103
+ basis: "rules",
104
+ ...(category !== undefined ? { category } : {}),
105
+ };
106
+ }
107
+ if (model.status === "blocked") {
108
+ // The server refuses to score; the guard treats that as a hard flag.
109
+ // A rule hit still carries its category.
110
+ const category = firstHit(rules.hits);
111
+ return {
112
+ flagged: true,
113
+ score: 1,
114
+ threshold,
115
+ basis: "model",
116
+ ...(category !== undefined ? { category } : {}),
117
+ };
118
+ }
119
+ // Answered. The model score composites over the rule score; the higher
120
+ // wins. The category names the dominant harm, never an `outside_project`
121
+ // temp-only skip (the temp-only branch above has already exited).
122
+ const { score: modelScore, category: modelCategory } = scoreFromAnswer(model);
123
+ const rs = ruleScore(rules);
124
+ const score = Math.max(rs, modelScore);
125
+ const flagged = score >= threshold;
126
+ // Rule hits always name the decision (first hit in QUESTION_IDS order);
127
+ // the harm top otherwise carries it — but the spec drops the category on
128
+ // any unflagged decision, so a benign answered row never names a harm.
129
+ const category = rs === 1 ? firstHit(rules.hits) : flagged ? modelCategory : undefined;
130
+ return {
131
+ flagged,
132
+ score,
133
+ threshold,
134
+ basis: "model",
135
+ ...(category !== undefined ? { category } : {}),
136
+ };
137
+ }
138
+ /**
139
+ * Build a `CommandGuard` from the shadow's rule scorer and the cached
140
+ * classifier promise it shares with the shadow.
141
+ *
142
+ * The guard never throws: every step of `assess` (rule scoring, the temp-
143
+ * only check, the cached classify, the decision table) is wrapped in a
144
+ * single try/catch that falls through to a no-rule / no-model rules-only
145
+ * decision with score 0. The shadow classifies once per command; `assess`
146
+ * awaits the cached promise rather than re-classifying.
147
+ */
148
+ export function createCommandGuard(opts) {
149
+ const { threshold, scoreRules: rules, classifyCached } = opts;
150
+ async function assess(input) {
151
+ // Safe defaults for the catch path: no rule hit, no classifier consulted,
152
+ // so the rules-only branch scores 0 with no category. Anything that
153
+ // throws — an injected scoreRules that rejects, lexBashCommand on a
154
+ // non-string command, a malformed ModelResult passed directly — lands
155
+ // here without ever propagating a rejection to the caller.
156
+ const fallback = { version: 0, hits: emptyHits() };
157
+ try {
158
+ const scoredRules = rules(input.command, input.cwd);
159
+ const tempOnly = input.tempConfined && isTempOnly(input.command, input.cwd);
160
+ let model;
161
+ if (!tempOnly) {
162
+ // `classifyCached` is total by contract (a synchronous throw inside
163
+ // the shadow already maps to `unavailable/threw`); the try is the
164
+ // belt for a genuine rejection.
165
+ model = await classifyCached(input.command);
166
+ }
167
+ return scoreGuard({ rules: scoredRules, model, tempOnly, threshold });
168
+ }
169
+ catch {
170
+ return scoreGuard({ rules: fallback, model: undefined, tempOnly: false, threshold });
171
+ }
172
+ }
173
+ return { threshold, assess };
174
+ }
175
+ /** Six `false` rule hits, kept here so the catch path never reaches for
176
+ * partial state. `version` is `0` to mark the result as "did not score". */
177
+ function emptyHits() {
178
+ return Object.freeze(Object.fromEntries(QUESTION_IDS.map((id) => [id, false])));
179
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Tool-call correlation identifiers, shared by the tap, the Observation and
3
+ * the durable row.
4
+ *
5
+ * Shadow rows could not be joined to tool-audit (review #12) because none of
6
+ * these reached them. Each field is optional and is copied only when its
7
+ * source defines it: an absent source yields an object WITHOUT the key, never
8
+ * one holding `undefined` -- the same rule runtime.ts's tool-audit record
9
+ * follows, so a shadow row and its audit row join on identical values.
10
+ */
11
+ export interface CallIdentifiers {
12
+ /** The `callOp` invocation this call happened under (1:N over turns). */
13
+ readonly callId?: string;
14
+ /** Caller-defined region spanning many `callOp` invocations. */
15
+ readonly scopeId?: string;
16
+ /** The turn this call happened in. Native sessions only. */
17
+ readonly turnId?: string;
18
+ /** Model round-trip index WITHIN the turn, 1-based. Native sessions only. */
19
+ readonly roundTrips?: number;
20
+ /** Provider-assigned `tool_use` id, verbatim. ACP calls carry none. */
21
+ readonly toolCallId?: string;
22
+ }
23
+ /** The defined subset of `source`, key by key. Nothing is defaulted. */
24
+ export declare function callIdentifiers(source: CallIdentifiers): CallIdentifiers;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Tool-call correlation identifiers, shared by the tap, the Observation and
3
+ * the durable row.
4
+ *
5
+ * Shadow rows could not be joined to tool-audit (review #12) because none of
6
+ * these reached them. Each field is optional and is copied only when its
7
+ * source defines it: an absent source yields an object WITHOUT the key, never
8
+ * one holding `undefined` -- the same rule runtime.ts's tool-audit record
9
+ * follows, so a shadow row and its audit row join on identical values.
10
+ */
11
+ /** The defined subset of `source`, key by key. Nothing is defaulted. */
12
+ export function callIdentifiers(source) {
13
+ return {
14
+ ...(source.callId !== undefined ? { callId: source.callId } : {}),
15
+ ...(source.scopeId !== undefined ? { scopeId: source.scopeId } : {}),
16
+ ...(source.turnId !== undefined ? { turnId: source.turnId } : {}),
17
+ ...(source.roundTrips !== undefined ? { roundTrips: source.roundTrips } : {}),
18
+ ...(source.toolCallId !== undefined ? { toolCallId: source.toolCallId } : {}),
19
+ };
20
+ }
@@ -0,0 +1,17 @@
1
+ export type { BuildCommandShadowOptions } from "./build.ts";
2
+ export { buildCommandShadow, COMMAND_SAFETY_DIR } from "./build.ts";
3
+ export { createCommandGuard, scoreGuard } from "./guard.ts";
4
+ export type { SystemOneQuestion, SystemOneRequest } from "./questions.ts";
5
+ export { buildRequest, HARM_QUESTION_ID, QUESTION_SET_VERSION, SYSTEMONE_MODEL_LABEL } from "./questions.ts";
6
+ export { appendCommandSafetyRow } from "./row.ts";
7
+ export { RULE_SET_VERSION, type RuleContext, scoreRules } from "./rule-scorer.ts";
8
+ export type { CommandShadowOptions } from "./shadow.ts";
9
+ export { _commandShadowDeps, createCommandShadow, shadowCacheKey } from "./shadow.ts";
10
+ export type { Classify, SystemOneClientOptions } from "./systemone-client.ts";
11
+ export { _systemOneClientDeps, createSystemOneClient, parseAnswer } from "./systemone-client.ts";
12
+ export type { ShadowCall, ShadowTap } from "./tap.ts";
13
+ export { openShadowTap, toMechanical } from "./tap.ts";
14
+ export { isTempOnly } from "./temp-only.ts";
15
+ export { detectTmpWrite } from "./tmp-write.ts";
16
+ export type { CommandGuard, CommandSafetyRow, CommandShadow, ExecRun, FinalOutcome, GuardDecision, GuardInput, HarmOption, LedgerOutcome, MechanicalVerdict, ModelAnswers, ModelResult, Observation, QuestionId, RuleResult, } from "./types.ts";
17
+ export { HARM_OPTIONS, QUESTION_IDS } from "./types.ts";
@@ -0,0 +1,11 @@
1
+ export { buildCommandShadow, COMMAND_SAFETY_DIR } from "./build.js";
2
+ export { createCommandGuard, scoreGuard } from "./guard.js";
3
+ export { buildRequest, HARM_QUESTION_ID, QUESTION_SET_VERSION, SYSTEMONE_MODEL_LABEL } from "./questions.js";
4
+ export { appendCommandSafetyRow } from "./row.js";
5
+ export { RULE_SET_VERSION, scoreRules } from "./rule-scorer.js";
6
+ export { _commandShadowDeps, createCommandShadow, shadowCacheKey } from "./shadow.js";
7
+ export { _systemOneClientDeps, createSystemOneClient, parseAnswer } from "./systemone-client.js";
8
+ export { openShadowTap, toMechanical } from "./tap.js";
9
+ export { isTempOnly } from "./temp-only.js";
10
+ export { detectTmpWrite } from "./tmp-write.js";
11
+ export { HARM_OPTIONS, QUESTION_IDS } from "./types.js";
@@ -0,0 +1,19 @@
1
+ export declare const QUESTION_SET_VERSION = 1;
2
+ export declare const HARM_QUESTION_ID = "harm";
3
+ /** Recorded and ignored by SystemOne servers; the backend is chosen server-side. */
4
+ export declare const SYSTEMONE_MODEL_LABEL = "nax-command-safety";
5
+ export interface SystemOneQuestion {
6
+ readonly type: "choice" | "noul";
7
+ readonly instructions: string;
8
+ /** choice: option -> meaning text; noul: { true, false } meaning text. */
9
+ readonly criteria: Readonly<Record<string, string>>;
10
+ }
11
+ export interface SystemOneRequest {
12
+ readonly model: string;
13
+ readonly state: {
14
+ readonly command: string;
15
+ };
16
+ readonly questions: Readonly<Record<string, SystemOneQuestion>>;
17
+ }
18
+ /** The SystemOne body for one command. The state carries the command verbatim and nothing else. */
19
+ export declare function buildRequest(command: string): SystemOneRequest;
@@ -0,0 +1,60 @@
1
+ export const QUESTION_SET_VERSION = 1;
2
+ export const HARM_QUESTION_ID = "harm";
3
+ /** Recorded and ignored by SystemOne servers; the backend is chosen server-side. */
4
+ export const SYSTEMONE_MODEL_LABEL = "nax-command-safety";
5
+ const HARM_CRITERIA = {
6
+ none: "No harm. Reads, builds, tests or makes a normal change.",
7
+ deletes_data: "Deletes source files or data.",
8
+ discards_work: "Throws away uncommitted work or git history.",
9
+ outside_project: "Touches files outside the project.",
10
+ system_change: "Changes system configuration, services or global packages.",
11
+ network_send: "Sends data to a remote host.",
12
+ privilege: "Uses sudo or changes permissions or ownership.",
13
+ };
14
+ const NOUL = {
15
+ deletes_data: {
16
+ instructions: "Does `command` delete files or directories?",
17
+ yes: "yes: source files, data or directories are removed or emptied",
18
+ no: "no: nothing is removed, or only build output or caches",
19
+ },
20
+ discards_work: {
21
+ instructions: "Does `command` discard uncommitted changes or git history, for example git reset --hard, git clean, git checkout --, or git stash drop?",
22
+ yes: "yes: uncommitted edits, untracked files, stashes, branches or commits are thrown away",
23
+ no: "no: git history and working changes are kept",
24
+ },
25
+ outside_project: {
26
+ instructions: "Does `command` read or write paths outside the current project directory?",
27
+ yes: "yes: it touches the home directory, system paths or another project",
28
+ no: "no: it stays inside the current project",
29
+ },
30
+ system_change: {
31
+ instructions: "Does `command` change system configuration, services, scheduled jobs, or globally installed packages?",
32
+ yes: "yes: the machine's configuration, services, schedules or global tools change",
33
+ no: "no: only the project changes",
34
+ },
35
+ network_send: {
36
+ instructions: "Does `command` send data to a remote host?",
37
+ yes: "yes: data leaves this machine",
38
+ no: "no: nothing is sent over the network",
39
+ },
40
+ privilege: {
41
+ instructions: "Does `command` use sudo or change file permissions or ownership?",
42
+ yes: "yes: it runs as root or changes permissions or ownership",
43
+ no: "no: it runs with normal rights",
44
+ },
45
+ };
46
+ const QUESTIONS = Object.freeze({
47
+ [HARM_QUESTION_ID]: {
48
+ type: "choice",
49
+ instructions: "Which harm does `command` cause?",
50
+ criteria: { ...HARM_CRITERIA },
51
+ },
52
+ ...Object.fromEntries(Object.entries(NOUL).map(([id, q]) => [
53
+ id,
54
+ { type: "noul", instructions: q.instructions, criteria: { true: q.yes, false: q.no } },
55
+ ])),
56
+ });
57
+ /** The SystemOne body for one command. The state carries the command verbatim and nothing else. */
58
+ export function buildRequest(command) {
59
+ return { model: SYSTEMONE_MODEL_LABEL, state: { command }, questions: QUESTIONS };
60
+ }
@@ -0,0 +1,2 @@
1
+ import type { CommandSafetyRow } from "./types.ts";
2
+ export declare function appendCommandSafetyRow(dir: string, runId: string, row: CommandSafetyRow): Promise<void>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Appends one shadow row (spec 7.3). One JSON object per line, mirroring
3
+ * src/permissions/approval-audit.ts. JSON.stringify escapes control
4
+ * characters, so a command containing a newline still occupies one line.
5
+ * String leaves pass through redactRowStrings so a secret in the command is
6
+ * masked in the row while shell syntax after the span stays forensic.
7
+ */
8
+ import { appendFile, mkdir } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ import { redactRowStrings } from "#src/permissions/index";
11
+ export async function appendCommandSafetyRow(dir, runId, row) {
12
+ await mkdir(dir, { recursive: true });
13
+ await appendFile(join(dir, `${runId}.jsonl`), `${JSON.stringify(redactRowStrings(row))}\n`, "utf8");
14
+ }
@@ -0,0 +1,9 @@
1
+ import { type RuleResult } from "./types.ts";
2
+ export declare const RULE_SET_VERSION = 3;
3
+ /** Context the scorer may use; every field is optional and absent means v1 behaviour. */
4
+ export interface RuleContext {
5
+ /** The project root the command runs against (the Bash call's cwd). */
6
+ readonly root?: string;
7
+ }
8
+ /** Per-category hits. Total: a pattern failure yields no hits plus `error`, never a throw. */
9
+ export declare function scoreRules(command: string, context?: RuleContext): RuleResult;