@paybond/kit 0.9.8 → 0.11.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 (368) hide show
  1. package/completion-presets/catalog.json +1187 -0
  2. package/completion-presets/catalog.sha256 +1 -0
  3. package/dev/trace-ui/dashboard.html +617 -0
  4. package/dist/agent/adapter.d.ts +51 -0
  5. package/dist/agent/adapter.js +66 -0
  6. package/dist/agent/attach-bundle.d.ts +37 -0
  7. package/dist/agent/attach-bundle.js +118 -0
  8. package/dist/agent/authorization-cache.d.ts +22 -0
  9. package/dist/agent/authorization-cache.js +36 -0
  10. package/dist/agent/deferred-tools.d.ts +11 -0
  11. package/dist/agent/deferred-tools.js +62 -0
  12. package/dist/agent/discover.d.ts +41 -0
  13. package/dist/agent/discover.js +147 -0
  14. package/dist/agent/evidence.d.ts +9 -0
  15. package/dist/agent/evidence.js +28 -0
  16. package/dist/agent/facade.d.ts +48 -0
  17. package/dist/agent/facade.js +112 -0
  18. package/dist/agent/gateway-trace-reporter.d.ts +28 -0
  19. package/dist/agent/gateway-trace-reporter.js +49 -0
  20. package/dist/agent/generic-runner.d.ts +14 -0
  21. package/dist/agent/generic-runner.js +49 -0
  22. package/dist/agent/generic-sandbox-demo.d.ts +36 -0
  23. package/dist/agent/generic-sandbox-demo.js +82 -0
  24. package/dist/agent/guarded-agent.d.ts +49 -0
  25. package/dist/agent/guarded-agent.js +100 -0
  26. package/dist/agent/index.d.ts +13 -0
  27. package/dist/agent/index.js +13 -0
  28. package/dist/agent/instrument.d.ts +156 -0
  29. package/dist/agent/instrument.js +442 -0
  30. package/dist/agent/interceptor.d.ts +24 -0
  31. package/dist/agent/interceptor.js +440 -0
  32. package/dist/agent/lazy-context-tools.d.ts +15 -0
  33. package/dist/agent/lazy-context-tools.js +81 -0
  34. package/dist/agent/registry-file.d.ts +39 -0
  35. package/dist/agent/registry-file.js +219 -0
  36. package/dist/agent/registry.d.ts +37 -0
  37. package/dist/agent/registry.js +128 -0
  38. package/dist/agent/run.d.ts +124 -0
  39. package/dist/agent/run.js +301 -0
  40. package/dist/agent/types.d.ts +318 -0
  41. package/dist/agent/types.js +42 -0
  42. package/dist/agent-recognition.d.ts +72 -0
  43. package/dist/agent-recognition.js +165 -0
  44. package/dist/bincode-wire.d.ts +18 -0
  45. package/dist/bincode-wire.js +93 -0
  46. package/dist/claude-agents/config.d.ts +21 -0
  47. package/dist/claude-agents/config.js +145 -0
  48. package/dist/claude-agents/index.d.ts +2 -0
  49. package/dist/claude-agents/index.js +2 -0
  50. package/dist/claude-agents/sandbox-demo.d.ts +30 -0
  51. package/dist/claude-agents/sandbox-demo.js +91 -0
  52. package/dist/cli/agent/env-quote.d.ts +1 -0
  53. package/dist/cli/agent/env-quote.js +6 -0
  54. package/dist/cli/agent/env-write.d.ts +8 -0
  55. package/dist/cli/agent/env-write.js +47 -0
  56. package/dist/cli/agent/paybond.d.ts +16 -0
  57. package/dist/cli/agent/paybond.js +55 -0
  58. package/dist/cli/agent/policy-file.d.ts +29 -0
  59. package/dist/cli/agent/policy-file.js +61 -0
  60. package/dist/cli/agent/production-evidence.d.ts +24 -0
  61. package/dist/cli/agent/production-evidence.js +98 -0
  62. package/dist/cli/agent/run-store.d.ts +30 -0
  63. package/dist/cli/agent/run-store.js +42 -0
  64. package/dist/cli/agent/run-trace-store.d.ts +39 -0
  65. package/dist/cli/agent/run-trace-store.js +143 -0
  66. package/dist/cli/agent-run-trace-table.d.ts +9 -0
  67. package/dist/cli/agent-run-trace-table.js +24 -0
  68. package/dist/cli/agent-sandbox-smoke-checklist.d.ts +9 -0
  69. package/dist/cli/agent-sandbox-smoke-checklist.js +50 -0
  70. package/dist/cli/audit-export.d.ts +7 -0
  71. package/dist/cli/audit-export.js +120 -0
  72. package/dist/cli/automation.d.ts +25 -0
  73. package/dist/cli/automation.js +297 -0
  74. package/dist/cli/body.d.ts +7 -0
  75. package/dist/cli/body.js +22 -0
  76. package/dist/cli/color.d.ts +15 -0
  77. package/dist/cli/color.js +39 -0
  78. package/dist/cli/command-spec.d.ts +13 -0
  79. package/dist/cli/command-spec.js +611 -0
  80. package/dist/cli/commands/agent.d.ts +16 -0
  81. package/dist/cli/commands/agent.js +1135 -0
  82. package/dist/cli/commands/dev.d.ts +7 -0
  83. package/dist/cli/commands/dev.js +348 -0
  84. package/dist/cli/commands/discovery.d.ts +8 -0
  85. package/dist/cli/commands/discovery.js +194 -0
  86. package/dist/cli/commands/policy.d.ts +13 -0
  87. package/dist/cli/commands/policy.js +769 -0
  88. package/dist/cli/commands/setup.d.ts +18 -0
  89. package/dist/cli/commands/setup.js +513 -0
  90. package/dist/cli/commands/workflows.d.ts +7 -0
  91. package/dist/cli/commands/workflows.js +214 -0
  92. package/dist/cli/config.d.ts +16 -0
  93. package/dist/cli/config.js +98 -0
  94. package/dist/cli/context.d.ts +22 -0
  95. package/dist/cli/context.js +110 -0
  96. package/dist/cli/credentials.d.ts +21 -0
  97. package/dist/cli/credentials.js +141 -0
  98. package/dist/cli/doctor-agent-middleware.d.ts +5 -0
  99. package/dist/cli/doctor-agent-middleware.js +49 -0
  100. package/dist/cli/doctor-agent.d.ts +15 -0
  101. package/dist/cli/doctor-agent.js +311 -0
  102. package/dist/cli/envelope.d.ts +14 -0
  103. package/dist/cli/envelope.js +46 -0
  104. package/dist/cli/globals.d.ts +23 -0
  105. package/dist/cli/globals.js +248 -0
  106. package/dist/cli/help.d.ts +3 -0
  107. package/dist/cli/help.js +83 -0
  108. package/dist/cli/mcp-install.d.ts +41 -0
  109. package/dist/cli/mcp-install.js +95 -0
  110. package/dist/cli/mcp-policy.d.ts +26 -0
  111. package/dist/cli/mcp-policy.js +110 -0
  112. package/dist/cli/mcp-verify-config.d.ts +37 -0
  113. package/dist/cli/mcp-verify-config.js +172 -0
  114. package/dist/cli/redact.d.ts +4 -0
  115. package/dist/cli/redact.js +88 -0
  116. package/dist/cli/request-id.d.ts +2 -0
  117. package/dist/cli/request-id.js +5 -0
  118. package/dist/cli/router.d.ts +2 -0
  119. package/dist/cli/router.js +378 -0
  120. package/dist/cli/smoke-deep-links.d.ts +15 -0
  121. package/dist/cli/smoke-deep-links.js +63 -0
  122. package/dist/cli/suggest.d.ts +4 -0
  123. package/dist/cli/suggest.js +58 -0
  124. package/dist/cli/support-diagnostics.d.ts +19 -0
  125. package/dist/cli/support-diagnostics.js +47 -0
  126. package/dist/cli/telemetry.d.ts +17 -0
  127. package/dist/cli/telemetry.js +94 -0
  128. package/dist/cli/types.d.ts +72 -0
  129. package/dist/cli/types.js +60 -0
  130. package/dist/cli/ux.d.ts +8 -0
  131. package/dist/cli/ux.js +164 -0
  132. package/dist/cli.d.ts +2 -0
  133. package/dist/cli.js +38 -0
  134. package/dist/completion-catalog-digest.d.ts +2 -0
  135. package/dist/completion-catalog-digest.js +2 -0
  136. package/dist/completion-catalog-integrity.d.ts +2 -0
  137. package/dist/completion-catalog-integrity.js +17 -0
  138. package/dist/completion-catalog.d.ts +49 -0
  139. package/dist/completion-catalog.js +62 -0
  140. package/dist/completion-contract-digest.d.ts +37 -0
  141. package/dist/completion-contract-digest.js +73 -0
  142. package/dist/completion-forbidden-fields.d.ts +5 -0
  143. package/dist/completion-forbidden-fields.js +26 -0
  144. package/dist/completion-init.d.ts +8 -0
  145. package/dist/completion-init.js +334 -0
  146. package/dist/completion-resolve.d.ts +21 -0
  147. package/dist/completion-resolve.js +86 -0
  148. package/dist/completion-validate-evidence.d.ts +24 -0
  149. package/dist/completion-validate-evidence.js +145 -0
  150. package/dist/dev/offline-gateway.d.ts +24 -0
  151. package/dist/dev/offline-gateway.js +102 -0
  152. package/dist/dev/trace-buffer.d.ts +61 -0
  153. package/dist/dev/trace-buffer.js +330 -0
  154. package/dist/dev/trace-security-headers.d.ts +11 -0
  155. package/dist/dev/trace-security-headers.js +16 -0
  156. package/dist/dev/trace-server.d.ts +8 -0
  157. package/dist/dev/trace-server.js +38 -0
  158. package/dist/dev/trace-ui.d.ts +4 -0
  159. package/dist/dev/trace-ui.js +25 -0
  160. package/dist/dev/wiremock-up.d.ts +15 -0
  161. package/dist/dev/wiremock-up.js +118 -0
  162. package/dist/doctor-completion.d.ts +17 -0
  163. package/dist/doctor-completion.js +428 -0
  164. package/dist/gateway-url.d.ts +7 -0
  165. package/dist/gateway-url.js +69 -0
  166. package/dist/index.d.ts +119 -2
  167. package/dist/index.js +267 -6
  168. package/dist/init.js +380 -68
  169. package/dist/langgraph/awrap-tool-call.d.ts +25 -0
  170. package/dist/langgraph/awrap-tool-call.js +81 -0
  171. package/dist/langgraph/config.d.ts +13 -0
  172. package/dist/langgraph/config.js +11 -0
  173. package/dist/langgraph/index.d.ts +4 -0
  174. package/dist/langgraph/index.js +4 -0
  175. package/dist/langgraph/sandbox-demo.d.ts +40 -0
  176. package/dist/langgraph/sandbox-demo.js +96 -0
  177. package/dist/langgraph/tool-node.d.ts +10 -0
  178. package/dist/langgraph/tool-node.js +38 -0
  179. package/dist/login.d.ts +14 -1
  180. package/dist/login.js +130 -63
  181. package/dist/mcp/index.d.ts +1 -0
  182. package/dist/mcp/index.js +1 -0
  183. package/dist/mcp/tool-surface.d.ts +25 -0
  184. package/dist/mcp/tool-surface.js +17 -0
  185. package/dist/mcp-capability-token-cache.d.ts +24 -0
  186. package/dist/mcp-capability-token-cache.js +101 -0
  187. package/dist/mcp-evidence-policy.d.ts +48 -0
  188. package/dist/mcp-evidence-policy.js +117 -0
  189. package/dist/mcp-policy-reload.d.ts +79 -0
  190. package/dist/mcp-policy-reload.js +200 -0
  191. package/dist/mcp-sep2828-evidence.d.ts +36 -0
  192. package/dist/mcp-sep2828-evidence.js +65 -0
  193. package/dist/mcp-server.d.ts +10 -0
  194. package/dist/mcp-server.js +423 -115
  195. package/dist/openai-agents/index.d.ts +40 -0
  196. package/dist/openai-agents/index.js +151 -0
  197. package/dist/openai-agents/sandbox-demo.d.ts +34 -0
  198. package/dist/openai-agents/sandbox-demo.js +118 -0
  199. package/dist/payee-evidence.js +2 -29
  200. package/dist/policy/catalog.d.ts +31 -0
  201. package/dist/policy/catalog.js +48 -0
  202. package/dist/policy/compose-utils.d.ts +3 -0
  203. package/dist/policy/compose-utils.js +4 -0
  204. package/dist/policy/compose.d.ts +20 -0
  205. package/dist/policy/compose.js +240 -0
  206. package/dist/policy/digest.d.ts +7 -0
  207. package/dist/policy/digest.js +75 -0
  208. package/dist/policy/domain.d.ts +15 -0
  209. package/dist/policy/domain.js +28 -0
  210. package/dist/policy/guardrail-spec.d.ts +17 -0
  211. package/dist/policy/guardrail-spec.js +140 -0
  212. package/dist/policy/guardrails.d.ts +48 -0
  213. package/dist/policy/guardrails.js +72 -0
  214. package/dist/policy/index.d.ts +21 -0
  215. package/dist/policy/index.js +21 -0
  216. package/dist/policy/init.d.ts +102 -0
  217. package/dist/policy/init.js +351 -0
  218. package/dist/policy/intent-spec.d.ts +52 -0
  219. package/dist/policy/intent-spec.js +176 -0
  220. package/dist/policy/json-path.d.ts +4 -0
  221. package/dist/policy/json-path.js +23 -0
  222. package/dist/policy/layers-io.d.ts +7 -0
  223. package/dist/policy/layers-io.js +28 -0
  224. package/dist/policy/load-effective.d.ts +22 -0
  225. package/dist/policy/load-effective.js +77 -0
  226. package/dist/policy/load.d.ts +85 -0
  227. package/dist/policy/load.js +164 -0
  228. package/dist/policy/merge.d.ts +29 -0
  229. package/dist/policy/merge.js +297 -0
  230. package/dist/policy/parse-text.d.ts +2 -0
  231. package/dist/policy/parse-text.js +126 -0
  232. package/dist/policy/policy-api.d.ts +45 -0
  233. package/dist/policy/policy-api.js +61 -0
  234. package/dist/policy/presets.d.ts +19 -0
  235. package/dist/policy/presets.js +66 -0
  236. package/dist/policy/registry.d.ts +7 -0
  237. package/dist/policy/registry.js +33 -0
  238. package/dist/policy/reload.d.ts +86 -0
  239. package/dist/policy/reload.js +233 -0
  240. package/dist/policy/render-yaml.d.ts +3 -0
  241. package/dist/policy/render-yaml.js +69 -0
  242. package/dist/policy/sandbox-bootstrap.d.ts +19 -0
  243. package/dist/policy/sandbox-bootstrap.js +66 -0
  244. package/dist/policy/schema.d.ts +204 -0
  245. package/dist/policy/schema.js +255 -0
  246. package/dist/policy/snapshot.d.ts +33 -0
  247. package/dist/policy/snapshot.js +23 -0
  248. package/dist/policy/validate-remote.d.ts +43 -0
  249. package/dist/policy/validate-remote.js +104 -0
  250. package/dist/policy/validate.d.ts +36 -0
  251. package/dist/policy/validate.js +150 -0
  252. package/dist/policy/watcher.d.ts +29 -0
  253. package/dist/policy/watcher.js +112 -0
  254. package/dist/principal-intent.d.ts +52 -0
  255. package/dist/principal-intent.js +193 -37
  256. package/dist/project-init.d.ts +34 -0
  257. package/dist/project-init.js +898 -0
  258. package/dist/sep2828-signature.d.ts +10 -0
  259. package/dist/sep2828-signature.js +134 -0
  260. package/dist/solutions/api.d.ts +22 -0
  261. package/dist/solutions/api.js +40 -0
  262. package/dist/solutions/catalog.d.ts +34 -0
  263. package/dist/solutions/catalog.js +129 -0
  264. package/dist/solutions/index.d.ts +2 -0
  265. package/dist/solutions/index.js +2 -0
  266. package/dist/template-init.d.ts +54 -0
  267. package/dist/template-init.js +203 -0
  268. package/dist/vercel-ai/config.d.ts +15 -0
  269. package/dist/vercel-ai/config.js +13 -0
  270. package/dist/vercel-ai/index.d.ts +4 -0
  271. package/dist/vercel-ai/index.js +4 -0
  272. package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
  273. package/dist/vercel-ai/sandbox-demo.js +153 -0
  274. package/dist/vercel-ai/tool-approval.d.ts +16 -0
  275. package/dist/vercel-ai/tool-approval.js +41 -0
  276. package/dist/vercel-ai/wrap-tools.d.ts +9 -0
  277. package/dist/vercel-ai/wrap-tools.js +40 -0
  278. package/dist/x402-receipt-evidence.d.ts +29 -0
  279. package/dist/x402-receipt-evidence.js +97 -0
  280. package/dist/x402-receipt-signature.d.ts +12 -0
  281. package/dist/x402-receipt-signature.js +211 -0
  282. package/package.json +79 -4
  283. package/solutions/aws.json +17 -0
  284. package/solutions/saas.json +17 -0
  285. package/solutions/shopping.json +17 -0
  286. package/solutions/travel.json +18 -0
  287. package/templates/manifest.json +169 -0
  288. package/templates/openai-shopping-agent/.env.example +3 -0
  289. package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
  290. package/templates/openai-shopping-agent/LICENSE +201 -0
  291. package/templates/openai-shopping-agent/README.md +29 -0
  292. package/templates/openai-shopping-agent/package.json +22 -0
  293. package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
  294. package/templates/openai-shopping-agent/src/index.ts +22 -0
  295. package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
  296. package/templates/openai-shopping-agent/tsconfig.json +13 -0
  297. package/templates/paybond-aws-operator/.env.example +3 -0
  298. package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
  299. package/templates/paybond-aws-operator/LICENSE +201 -0
  300. package/templates/paybond-aws-operator/README.md +29 -0
  301. package/templates/paybond-aws-operator/package.json +20 -0
  302. package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
  303. package/templates/paybond-aws-operator/src/index.ts +54 -0
  304. package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
  305. package/templates/paybond-aws-operator/tsconfig.json +13 -0
  306. package/templates/paybond-claude-agents-demo/.env.example +3 -0
  307. package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
  308. package/templates/paybond-claude-agents-demo/LICENSE +201 -0
  309. package/templates/paybond-claude-agents-demo/README.md +29 -0
  310. package/templates/paybond-claude-agents-demo/package.json +22 -0
  311. package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
  312. package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
  313. package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
  314. package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
  315. package/templates/paybond-invoice-agent/.env.example +3 -0
  316. package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
  317. package/templates/paybond-invoice-agent/LICENSE +201 -0
  318. package/templates/paybond-invoice-agent/README.md +29 -0
  319. package/templates/paybond-invoice-agent/app.py +27 -0
  320. package/templates/paybond-invoice-agent/package.json +6 -0
  321. package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
  322. package/templates/paybond-invoice-agent/paybond_config.py +45 -0
  323. package/templates/paybond-invoice-agent/requirements.txt +2 -0
  324. package/templates/paybond-mcp-coding-agent/.env.example +3 -0
  325. package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
  326. package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
  327. package/templates/paybond-mcp-coding-agent/README.md +39 -0
  328. package/templates/paybond-mcp-coding-agent/package.json +20 -0
  329. package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
  330. package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
  331. package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
  332. package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
  333. package/templates/paybond-openai-agents-demo/.env.example +3 -0
  334. package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
  335. package/templates/paybond-openai-agents-demo/LICENSE +201 -0
  336. package/templates/paybond-openai-agents-demo/README.md +29 -0
  337. package/templates/paybond-openai-agents-demo/package.json +22 -0
  338. package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
  339. package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
  340. package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
  341. package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
  342. package/templates/paybond-procurement-agent/.env.example +3 -0
  343. package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
  344. package/templates/paybond-procurement-agent/LICENSE +201 -0
  345. package/templates/paybond-procurement-agent/README.md +29 -0
  346. package/templates/paybond-procurement-agent/package.json +20 -0
  347. package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
  348. package/templates/paybond-procurement-agent/src/index.ts +54 -0
  349. package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
  350. package/templates/paybond-procurement-agent/tsconfig.json +13 -0
  351. package/templates/paybond-travel-agent/.env.example +3 -0
  352. package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
  353. package/templates/paybond-travel-agent/LICENSE +201 -0
  354. package/templates/paybond-travel-agent/README.md +29 -0
  355. package/templates/paybond-travel-agent/package.json +23 -0
  356. package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
  357. package/templates/paybond-travel-agent/src/index.ts +22 -0
  358. package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
  359. package/templates/paybond-travel-agent/tsconfig.json +13 -0
  360. package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
  361. package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
  362. package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
  363. package/templates/paybond-vercel-shopping-agent/README.md +29 -0
  364. package/templates/paybond-vercel-shopping-agent/package.json +22 -0
  365. package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
  366. package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
  367. package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
  368. package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
@@ -0,0 +1,1135 @@
1
+ import { resolve } from "node:path";
2
+ import { readFile } from "node:fs/promises";
3
+ import { PaybondAgentRun, PaybondAutoEvidenceSubmitError, PaybondToolRegistryValidationError, PaybondUnregisteredSideEffectingToolError, } from "../../agent/index.js";
4
+ import { runVercelAiSandboxDemo } from "../../vercel-ai/sandbox-demo.js";
5
+ import { runLangGraphSandboxDemo } from "../../langgraph/sandbox-demo.js";
6
+ import { runGenericSandboxDemo } from "../../agent/generic-sandbox-demo.js";
7
+ import { runClaudeAgentsSandboxDemo } from "../../claude-agents/sandbox-demo.js";
8
+ import { runOpenAIAgentsSandboxDemo } from "../../openai-agents/sandbox-demo.js";
9
+ import { buildSmokeRegistry, loadAgentRegistryFile, validateAgentRegistryDocument, } from "../../agent/registry-file.js";
10
+ import { createPaybondToolRegistry } from "../../agent/registry.js";
11
+ import { devTraceStepsFromEvents, devTraceUrl, findDevTraceEventForRun, resolveDevTraceSink, recordSmokeTraceEvent, } from "../../dev/trace-buffer.js";
12
+ import { PaybondSpendApprovalRequiredError, PaybondSpendDeniedError, } from "../../index.js";
13
+ import { readJsonBody } from "../automation.js";
14
+ import { formatAgentSandboxSmokeChecklist } from "../agent-sandbox-smoke-checklist.js";
15
+ import { appendSmokeDeepLinkChecklistLines, buildAgentSandboxSmokeDeepLinks, } from "../smoke-deep-links.js";
16
+ import { appendAgentRunEnvVars } from "../agent/env-write.js";
17
+ import { productionEvidenceToPersisted, resolveProductionEvidenceForReattach, resolveProductionEvidenceFromCli, } from "../agent/production-evidence.js";
18
+ import { resolveAgentPolicyBind, resolveAgentPolicyBindFromContent } from "../agent/policy-file.js";
19
+ import { resolvePolicyPresetPath } from "../../policy/presets.js";
20
+ import { getSolutionSmokeDefaults, isKnownSolutionId } from "../../solutions/catalog.js";
21
+ import { withPaybondAgentCli } from "../agent/paybond.js";
22
+ import { loadAgentRunContext, persistAgentRunContext, } from "../agent/run-store.js";
23
+ import { agentRunTraceFilePath, loadAgentRunTraceIfExists, resolveAgentRunTraceSink, createGatewayAgentRunTraceSink, registerGatewayAgentRun, } from "../agent/run-trace-store.js";
24
+ import { formatAgentRunTraceTable } from "../agent-run-trace-table.js";
25
+ import { PaybondPolicySandboxBootstrapError } from "../../policy/sandbox-bootstrap.js";
26
+ import { PaybondPolicyReloadError, } from "../../policy/reload.js";
27
+ import { consumeBooleanFlag, consumeFlag, parseOptionalNonNegativeInt, parseRequiredNonNegativeInt, } from "../globals.js";
28
+ import { CliError } from "../types.js";
29
+ function agentCliError(message, options) {
30
+ return new CliError(message, {
31
+ category: options.category ?? "validation",
32
+ code: options.code,
33
+ exitCode: options.exitCode ?? 1,
34
+ details: options.details,
35
+ });
36
+ }
37
+ function resolveBindTraceSink(ctx, runId, paybond) {
38
+ const devSink = resolveDevTraceSink();
39
+ const gatewaySink = paybond && runId?.trim() ? createGatewayAgentRunTraceSink(paybond, runId) : undefined;
40
+ if (!runId?.trim()) {
41
+ return gatewaySink ?? devSink;
42
+ }
43
+ return resolveAgentRunTraceSink(ctx.cwd, runId, undefined, devSink, gatewaySink);
44
+ }
45
+ async function resolveRegistryFromFile(registryFile, cwd) {
46
+ const path = resolve(cwd, registryFile);
47
+ const doc = await loadAgentRegistryFile(path);
48
+ const validation = validateAgentRegistryDocument(doc);
49
+ if (!validation.ok || !validation.registry) {
50
+ const message = validation.issues
51
+ .filter((issue) => issue.code !== "registry.default_deny_documented")
52
+ .map((issue) => issue.message)
53
+ .join("; ");
54
+ throw agentCliError(message || "registry validation failed", {
55
+ code: "cli.agent.registry_invalid",
56
+ details: { issues: validation.issues },
57
+ });
58
+ }
59
+ return { registry: validation.registry, doc, path, validation };
60
+ }
61
+ async function resolveRegistryForRun(ctx, runId) {
62
+ const stored = await loadAgentRunContext(ctx.cwd, runId);
63
+ if (stored.registry_file) {
64
+ const loaded = await resolveRegistryFromFile(stored.registry_file, ctx.cwd);
65
+ return { stored, registry: loaded.registry };
66
+ }
67
+ if (stored.completion_preset) {
68
+ return {
69
+ stored,
70
+ registry: buildSmokeRegistry(stored.operation, stored.completion_preset),
71
+ };
72
+ }
73
+ throw agentCliError(`run ${runId} has no registry_file; re-bind with --registry-file`, { code: "cli.agent.missing_registry" });
74
+ }
75
+ async function attachAgentRunFromStore(paybond, ctx, runId, options) {
76
+ const stored = await loadAgentRunContext(ctx.cwd, runId);
77
+ const policyPath = options?.policyFile ?? stored.registry_file;
78
+ let registry;
79
+ let policySnapshot;
80
+ let policyFilePath;
81
+ if (stored.policy_digest && policyPath) {
82
+ const absolutePolicyPath = resolve(ctx.cwd, policyPath);
83
+ const resolved = stored.policy_bind_content
84
+ ? resolveAgentPolicyBindFromContent({
85
+ policyPath: absolutePolicyPath,
86
+ content: stored.policy_bind_content,
87
+ forAttach: true,
88
+ })
89
+ : await resolveAgentPolicyBind({
90
+ cwd: ctx.cwd,
91
+ policyFile: policyPath,
92
+ forAttach: true,
93
+ });
94
+ registry = resolved.registry;
95
+ policySnapshot = resolved.policySnapshot;
96
+ policyFilePath = resolved.policyPath;
97
+ }
98
+ else {
99
+ const resolved = await resolveRegistryForRun(ctx, runId);
100
+ registry = resolved.registry;
101
+ }
102
+ const sandbox = stored.sandbox
103
+ ? {
104
+ operation: stored.operation,
105
+ requestedSpendCents: stored.requested_spend_cents ?? 0,
106
+ sandboxLifecycleStatus: stored.sandbox_lifecycle_status ?? "",
107
+ }
108
+ : undefined;
109
+ let productionEvidence;
110
+ if (!sandbox) {
111
+ if (!stored.production_evidence) {
112
+ throw agentCliError(`run ${runId} is missing production_evidence; re-bind with production attach flags`, { code: "cli.agent.missing_production_evidence", category: "validation" });
113
+ }
114
+ productionEvidence = await resolveProductionEvidenceForReattach({
115
+ cwd: ctx.cwd,
116
+ envFile: ctx.globals.envFile,
117
+ persisted: stored.production_evidence,
118
+ payeeSigningSeedHex: options?.payeeSigningSeedHex,
119
+ agentRecognitionSigningSeedHex: options?.agentRecognitionSigningSeedHex,
120
+ command: options?.reattachCommand,
121
+ });
122
+ }
123
+ const run = await PaybondAgentRun.bind(paybond, {
124
+ runId: stored.run_id,
125
+ registry,
126
+ policySnapshot,
127
+ policyFile: policyFilePath,
128
+ traceSink: resolveBindTraceSink(ctx, stored.run_id, paybond),
129
+ attach: {
130
+ intentId: stored.intent_id,
131
+ capabilityToken: stored.capability_token,
132
+ allowedTools: stored.allowed_tools,
133
+ sandbox,
134
+ productionEvidence,
135
+ },
136
+ });
137
+ registerGatewayAgentRun(paybond, run, { completionPreset: stored.completion_preset });
138
+ return run;
139
+ }
140
+ function parseProductionSigningSeedFlags(argv) {
141
+ const payeeFlag = consumeFlag(argv, "--payee-signing-seed-hex");
142
+ const agentFlag = consumeFlag(payeeFlag.rest, "--agent-recognition-signing-seed-hex");
143
+ return {
144
+ payeeSigningSeedHex: payeeFlag.value,
145
+ agentRecognitionSigningSeedHex: agentFlag.value,
146
+ rest: agentFlag.rest,
147
+ };
148
+ }
149
+ function buildReloadStatus(stored) {
150
+ if (!stored.reload_watch && !stored.reload_poll && !stored.last_reload_at) {
151
+ return undefined;
152
+ }
153
+ return {
154
+ watch: stored.reload_watch ?? false,
155
+ poll: stored.reload_poll ?? false,
156
+ last_reload_at: stored.last_reload_at ?? null,
157
+ };
158
+ }
159
+ function mapPolicyReloadError(err) {
160
+ if (err instanceof PaybondPolicyReloadError) {
161
+ return agentCliError(err.message, {
162
+ code: `cli.agent.policy_reload.${err.code}`,
163
+ category: "validation",
164
+ details: { reload_code: err.code },
165
+ });
166
+ }
167
+ if (err instanceof CliError) {
168
+ return err;
169
+ }
170
+ return agentCliError(err instanceof Error ? err.message : String(err), {
171
+ code: "cli.agent.policy_reload_failed",
172
+ });
173
+ }
174
+ function mapAuthorizationDecision(decision) {
175
+ if (decision.kind === "allow") {
176
+ return {
177
+ allow: true,
178
+ operation: decision.operation,
179
+ audit_id: decision.auditId,
180
+ decision_id: decision.decisionId,
181
+ };
182
+ }
183
+ return {
184
+ allow: false,
185
+ operation: decision.operation,
186
+ audit_id: decision.auditId,
187
+ decision_id: decision.decisionId,
188
+ message: decision.message,
189
+ code: decision.code,
190
+ };
191
+ }
192
+ async function parseInlineJson(argv, flagName, fileFlagName) {
193
+ const inlineFlag = consumeFlag(argv, flagName);
194
+ const fileFlag = consumeFlag(inlineFlag.rest, fileFlagName);
195
+ if (inlineFlag.value) {
196
+ try {
197
+ const parsed = JSON.parse(inlineFlag.value);
198
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
199
+ throw new Error("expected JSON object");
200
+ }
201
+ return { payload: parsed, rest: fileFlag.rest };
202
+ }
203
+ catch (err) {
204
+ throw agentCliError(`invalid ${flagName} JSON`, {
205
+ code: "cli.agent.invalid_json",
206
+ category: "usage",
207
+ details: { error: err instanceof Error ? err.message : String(err) },
208
+ });
209
+ }
210
+ }
211
+ if (fileFlag.value) {
212
+ const payload = await readJsonBody(fileFlag.value, process.stdin);
213
+ return { payload, rest: fileFlag.rest };
214
+ }
215
+ return { payload: {}, rest: fileFlag.rest };
216
+ }
217
+ export async function handleAgentRunBind(ctx, argv) {
218
+ const productionFlag = consumeBooleanFlag(argv, "--production");
219
+ const sandboxFlag = consumeBooleanFlag(productionFlag.rest, "--sandbox");
220
+ const policyFlag = consumeFlag(sandboxFlag.rest, "--policy-file");
221
+ const operationFlag = consumeFlag(policyFlag.rest, "--operation");
222
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
223
+ const presetFlag = consumeFlag(spendFlag.rest, "--completion-preset");
224
+ const registryFlag = consumeFlag(presetFlag.rest, "--registry-file");
225
+ const runIdFlag = consumeFlag(registryFlag.rest, "--run-id");
226
+ const attachIntentFlag = consumeFlag(runIdFlag.rest, "--attach-intent-id");
227
+ const capabilityFlag = consumeFlag(attachIntentFlag.rest, "--capability-token");
228
+ const payeeDidFlag = consumeFlag(capabilityFlag.rest, "--payee-did");
229
+ const payeeSeedFlag = consumeFlag(payeeDidFlag.rest, "--payee-signing-seed-hex");
230
+ const recognitionKeyFlag = consumeFlag(payeeSeedFlag.rest, "--agent-recognition-key-id");
231
+ const recognitionSeedFlag = consumeFlag(recognitionKeyFlag.rest, "--agent-recognition-signing-seed-hex");
232
+ const writeEnvFlag = consumeBooleanFlag(recognitionSeedFlag.rest, "--write-env");
233
+ const envOutFlag = consumeFlag(writeEnvFlag.rest, "--env-file");
234
+ const watchFlag = consumeBooleanFlag(envOutFlag.rest, "--watch");
235
+ const attachIntentId = attachIntentFlag.value?.trim();
236
+ const capabilityToken = capabilityFlag.value?.trim();
237
+ const hasAttach = Boolean(attachIntentId || capabilityToken);
238
+ if (hasAttach && (!attachIntentId || !capabilityToken)) {
239
+ throw agentCliError("attach requires both --attach-intent-id and --capability-token", { code: "cli.agent.attach_incomplete", category: "usage" });
240
+ }
241
+ if (policyFlag.value && registryFlag.value) {
242
+ throw agentCliError("agent run bind accepts --policy-file or --registry-file, not both", {
243
+ code: "cli.usage.conflicting_args",
244
+ category: "usage",
245
+ });
246
+ }
247
+ if (watchFlag.present && !policyFlag.value) {
248
+ throw agentCliError("--watch requires --policy-file", {
249
+ code: "cli.usage.missing_args",
250
+ category: "usage",
251
+ });
252
+ }
253
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
254
+ let registry;
255
+ let registryPath;
256
+ let policyPath;
257
+ let defaultDeny = false;
258
+ let policyBootstrap;
259
+ let policySnapshot;
260
+ let resolvedOperation = operationFlag.value?.trim() ?? "";
261
+ let resolvedCompletionPreset = presetFlag.value?.trim();
262
+ if (policyFlag.value) {
263
+ try {
264
+ const resolved = await resolveAgentPolicyBind({
265
+ cwd: ctx.cwd,
266
+ policyFile: policyFlag.value,
267
+ operation: operationFlag.value,
268
+ requestedSpendCents: spendFlag.value
269
+ ? parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents")
270
+ : undefined,
271
+ forAttach: hasAttach,
272
+ });
273
+ registry = resolved.registry;
274
+ policyPath = resolved.policyPath;
275
+ defaultDeny = resolved.defaultDeny;
276
+ policyBootstrap = resolved.bootstrap;
277
+ policySnapshot = resolved.policySnapshot;
278
+ resolvedOperation = resolved.operation;
279
+ if (!resolvedCompletionPreset && resolved.completionPreset) {
280
+ resolvedCompletionPreset = resolved.completionPreset;
281
+ }
282
+ }
283
+ catch (err) {
284
+ if (err instanceof PaybondPolicySandboxBootstrapError) {
285
+ throw agentCliError(err.message, {
286
+ code: "cli.agent.policy_bootstrap_failed",
287
+ category: "validation",
288
+ });
289
+ }
290
+ throw err;
291
+ }
292
+ }
293
+ else if (registryFlag.value) {
294
+ const loaded = await resolveRegistryFromFile(registryFlag.value, ctx.cwd);
295
+ registry = loaded.registry;
296
+ registryPath = loaded.path;
297
+ defaultDeny = loaded.validation.default_deny;
298
+ }
299
+ else if (!hasAttach) {
300
+ if (!operationFlag.value) {
301
+ throw agentCliError("agent run bind requires --operation, --policy-file, or --attach-intent-id with --capability-token", { code: "cli.usage.missing_args", category: "usage" });
302
+ }
303
+ const preset = presetFlag.value?.trim() || "cost_and_completion";
304
+ registry = buildSmokeRegistry(operationFlag.value, preset);
305
+ defaultDeny = true;
306
+ }
307
+ else {
308
+ registry = createPaybondToolRegistry({ defaultDeny: false, sideEffecting: {} });
309
+ }
310
+ let run;
311
+ const bindReload = watchFlag.present && policyPath ? { watch: true } : undefined;
312
+ let persistedProductionEvidence;
313
+ if (hasAttach) {
314
+ const productionEvidence = await resolveProductionEvidenceFromCli({
315
+ cwd: ctx.cwd,
316
+ envFile: envOutFlag.value ?? ctx.globals.envFile,
317
+ payeeDid: payeeDidFlag.value,
318
+ payeeSigningSeedHex: payeeSeedFlag.value,
319
+ agentRecognitionKeyId: recognitionKeyFlag.value,
320
+ agentRecognitionSigningSeedHex: recognitionSeedFlag.value,
321
+ });
322
+ persistedProductionEvidence = productionEvidenceToPersisted(productionEvidence);
323
+ run = await PaybondAgentRun.bind(session.paybond, {
324
+ runId: runIdFlag.value,
325
+ registry,
326
+ policySnapshot,
327
+ policyFile: policyPath,
328
+ reload: bindReload,
329
+ traceSink: resolveBindTraceSink(ctx, runIdFlag.value, session.paybond),
330
+ attach: {
331
+ intentId: attachIntentId,
332
+ capabilityToken: capabilityToken,
333
+ productionEvidence,
334
+ },
335
+ });
336
+ }
337
+ else {
338
+ if (policyBootstrap) {
339
+ run = await PaybondAgentRun.bind(session.paybond, {
340
+ runId: runIdFlag.value,
341
+ registry,
342
+ policySnapshot,
343
+ policyFile: policyPath,
344
+ reload: bindReload,
345
+ traceSink: resolveBindTraceSink(ctx, runIdFlag.value, session.paybond),
346
+ bootstrap: policyBootstrap,
347
+ });
348
+ }
349
+ else {
350
+ if (!operationFlag.value || !spendFlag.value) {
351
+ throw agentCliError("sandbox bind requires --operation and --requested-spend-cents (or --policy-file)", { code: "cli.usage.missing_args", category: "usage" });
352
+ }
353
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
354
+ run = await PaybondAgentRun.bind(session.paybond, {
355
+ runId: runIdFlag.value,
356
+ registry,
357
+ policySnapshot,
358
+ policyFile: policyPath,
359
+ reload: bindReload,
360
+ traceSink: resolveBindTraceSink(ctx, runIdFlag.value, session.paybond),
361
+ bootstrap: {
362
+ kind: "sandbox",
363
+ operation: operationFlag.value,
364
+ requestedSpendCents,
365
+ completionPreset: presetFlag.value,
366
+ },
367
+ });
368
+ }
369
+ }
370
+ const sandbox = run.binding.sandbox;
371
+ const data = {
372
+ run_id: run.runId,
373
+ tenant_id: run.tenantId,
374
+ intent_id: run.intentId,
375
+ capability_token: run.capabilityToken,
376
+ operation: sandbox?.operation ?? resolvedOperation ?? run.allowedTools[0] ?? "",
377
+ sandbox_lifecycle_status: sandbox?.sandboxLifecycleStatus ?? "",
378
+ allowed_tools: [...run.allowedTools],
379
+ };
380
+ if (policyPath) {
381
+ data.policy_file = policyPath;
382
+ }
383
+ if (run.policyDigest) {
384
+ data.policy_digest = run.policyDigest;
385
+ data.policy_version = run.policyVersion;
386
+ data.policy_loaded_at = run.policyLoadedAt;
387
+ }
388
+ if (watchFlag.present && policyPath) {
389
+ data.reload = { watch: true };
390
+ }
391
+ let policyBindContent;
392
+ if (policyPath) {
393
+ policyBindContent = await readFile(policyPath, "utf8");
394
+ }
395
+ await persistAgentRunContext(ctx.cwd, {
396
+ run_id: run.runId,
397
+ tenant_id: run.tenantId,
398
+ intent_id: run.intentId,
399
+ capability_token: run.capabilityToken,
400
+ operation: String(data.operation),
401
+ allowed_tools: [...run.allowedTools],
402
+ sandbox: Boolean(sandbox),
403
+ sandbox_lifecycle_status: sandbox?.sandboxLifecycleStatus,
404
+ requested_spend_cents: sandbox?.requestedSpendCents,
405
+ completion_preset: resolvedCompletionPreset || (!registryPath && !policyPath && !hasAttach ? "cost_and_completion" : undefined),
406
+ registry_file: registryPath ?? policyPath,
407
+ default_deny: defaultDeny,
408
+ policy_digest: run.policyDigest,
409
+ policy_version: run.policyVersion,
410
+ policy_loaded_at: run.policyLoadedAt,
411
+ reload_watch: watchFlag.present && policyPath ? true : undefined,
412
+ policy_bind_content: policyBindContent,
413
+ production_evidence: persistedProductionEvidence,
414
+ created_at: new Date().toISOString(),
415
+ });
416
+ registerGatewayAgentRun(session.paybond, run, {
417
+ completionPreset: resolvedCompletionPreset || (!registryPath && !policyPath && !hasAttach ? "cost_and_completion" : undefined),
418
+ });
419
+ if (writeEnvFlag.present) {
420
+ const envFile = envOutFlag.value ?? ctx.globals.envFile;
421
+ const written = await appendAgentRunEnvVars({
422
+ envFile,
423
+ cwd: ctx.cwd,
424
+ intentId: run.intentId,
425
+ capabilityToken: run.capabilityToken,
426
+ runId: run.runId,
427
+ });
428
+ data.env_file = written;
429
+ }
430
+ return { data, warnings: session.warnings };
431
+ });
432
+ }
433
+ export async function handleAgentRunStatus(ctx, argv) {
434
+ const runIdFlag = consumeFlag(argv, "--run-id");
435
+ if (!runIdFlag.value) {
436
+ throw agentCliError("agent run status requires --run-id", {
437
+ code: "cli.usage.missing_args",
438
+ category: "usage",
439
+ });
440
+ }
441
+ const stored = await loadAgentRunContext(ctx.cwd, runIdFlag.value);
442
+ const reload = buildReloadStatus(stored);
443
+ return {
444
+ data: {
445
+ run_id: stored.run_id,
446
+ tenant_id: stored.tenant_id,
447
+ intent_id: stored.intent_id,
448
+ operation: stored.operation,
449
+ allowed_tools: stored.allowed_tools,
450
+ sandbox: stored.sandbox,
451
+ sandbox_lifecycle_status: stored.sandbox_lifecycle_status ?? "",
452
+ registry_file: stored.registry_file ?? null,
453
+ policy_digest: stored.policy_digest ?? null,
454
+ policy_version: stored.policy_version ?? null,
455
+ policy_loaded_at: stored.policy_loaded_at ?? null,
456
+ ...(reload ? { reload } : {}),
457
+ },
458
+ };
459
+ }
460
+ export async function handleAgentRunTrace(ctx, argv) {
461
+ const runIdFlag = consumeFlag(argv, "--run-id");
462
+ if (!runIdFlag.value) {
463
+ throw agentCliError("agent run trace requires --run-id", {
464
+ code: "cli.usage.missing_args",
465
+ category: "usage",
466
+ });
467
+ }
468
+ const stored = await loadAgentRunContext(ctx.cwd, runIdFlag.value);
469
+ const persisted = await loadAgentRunTraceIfExists(ctx.cwd, runIdFlag.value);
470
+ const devEvent = findDevTraceEventForRun(runIdFlag.value);
471
+ const traceEvents = persisted?.trace_events ?? devEvent?.trace_events ?? [];
472
+ if (traceEvents.length === 0) {
473
+ throw agentCliError(`no trace events for run "${runIdFlag.value}"; run paybond agent tool execute first`, {
474
+ code: "cli.agent.trace_not_found",
475
+ category: "validation",
476
+ details: { run_id: runIdFlag.value },
477
+ });
478
+ }
479
+ const steps = devEvent?.steps ?? devTraceStepsFromEvents(traceEvents);
480
+ const traceLines = formatAgentRunTraceTable({
481
+ runId: stored.run_id,
482
+ intentId: stored.intent_id,
483
+ steps,
484
+ globals: ctx.globals,
485
+ });
486
+ return {
487
+ data: {
488
+ run_id: stored.run_id,
489
+ intent_id: stored.intent_id,
490
+ trace_events: traceEvents,
491
+ steps,
492
+ trace_lines: traceLines,
493
+ trace_url: devTraceUrl(undefined, stored.run_id),
494
+ trace_file: persisted ? agentRunTraceFilePath(ctx.cwd, stored.run_id) : undefined,
495
+ updated_at: persisted?.updated_at ?? devEvent?.recorded_at,
496
+ },
497
+ };
498
+ }
499
+ export async function handleAgentRunReloadPolicy(ctx, argv) {
500
+ const productionFlag = consumeBooleanFlag(argv, "--production");
501
+ const runIdFlag = consumeFlag(productionFlag.rest, "--run-id");
502
+ const policyFlag = consumeFlag(runIdFlag.rest, "--policy-file");
503
+ const remoteFlag = consumeBooleanFlag(policyFlag.rest, "--remote");
504
+ const resolveInheritanceFlag = consumeBooleanFlag(remoteFlag.rest, "--resolve-inheritance");
505
+ const allowLoosenFlag = consumeBooleanFlag(resolveInheritanceFlag.rest, "--allow-loosen");
506
+ const seedFlags = parseProductionSigningSeedFlags(allowLoosenFlag.rest);
507
+ if (!runIdFlag.value) {
508
+ throw agentCliError("agent run reload-policy requires --run-id", {
509
+ code: "cli.usage.missing_args",
510
+ category: "usage",
511
+ });
512
+ }
513
+ const stored = await loadAgentRunContext(ctx.cwd, runIdFlag.value);
514
+ const policyPath = policyFlag.value ?? stored.registry_file;
515
+ if (!stored.policy_digest || !policyPath) {
516
+ throw agentCliError("agent run reload-policy requires a policy-bound run; bind with --policy-file first", { code: "cli.agent.missing_policy", category: "usage" });
517
+ }
518
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
519
+ const run = await attachAgentRunFromStore(session.paybond, ctx, runIdFlag.value, {
520
+ policyFile: policyFlag.value ?? policyPath,
521
+ payeeSigningSeedHex: seedFlags.payeeSigningSeedHex,
522
+ agentRecognitionSigningSeedHex: seedFlags.agentRecognitionSigningSeedHex,
523
+ reattachCommand: "agent run reload-policy",
524
+ });
525
+ let result;
526
+ try {
527
+ const useGateway = remoteFlag.present || resolveInheritanceFlag.present;
528
+ result = await run.reloadPolicy({
529
+ file: policyFlag.value ? resolve(ctx.cwd, policyFlag.value) : undefined,
530
+ remote: remoteFlag.present,
531
+ resolveInheritance: resolveInheritanceFlag.present,
532
+ allowLoosen: allowLoosenFlag.present,
533
+ gateway: useGateway ? session.paybond.harbor : undefined,
534
+ });
535
+ }
536
+ catch (err) {
537
+ throw mapPolicyReloadError(err);
538
+ }
539
+ const lastReloadAt = result.applied ? new Date().toISOString() : stored.last_reload_at;
540
+ const policyFileOnDisk = resolve(ctx.cwd, policyFlag.value ?? policyPath);
541
+ const policyBindContent = result.applied
542
+ ? await readFile(policyFileOnDisk, "utf8")
543
+ : stored.policy_bind_content;
544
+ await persistAgentRunContext(ctx.cwd, {
545
+ ...stored,
546
+ policy_digest: run.policyDigest,
547
+ policy_version: run.policyVersion,
548
+ policy_loaded_at: run.policyLoadedAt,
549
+ last_reload_at: lastReloadAt,
550
+ policy_bind_content: policyBindContent,
551
+ });
552
+ return {
553
+ data: {
554
+ run_id: run.runId,
555
+ applied: result.applied,
556
+ unchanged: result.unchanged ?? false,
557
+ previous_digest: result.previousDigest ?? null,
558
+ new_digest: result.newDigest ?? null,
559
+ policy_digest: run.policyDigest ?? null,
560
+ policy_version: run.policyVersion ?? null,
561
+ policy_loaded_at: run.policyLoadedAt ?? null,
562
+ },
563
+ warnings: session.warnings,
564
+ };
565
+ });
566
+ }
567
+ export async function handleAgentToolExecute(ctx, argv) {
568
+ const productionFlag = consumeBooleanFlag(argv, "--production");
569
+ const runIdFlag = consumeFlag(productionFlag.rest, "--run-id");
570
+ const operationFlag = consumeFlag(runIdFlag.rest, "--operation");
571
+ const toolCallFlag = consumeFlag(operationFlag.rest, "--tool-call-id");
572
+ if (!runIdFlag.value || !operationFlag.value || !toolCallFlag.value) {
573
+ throw agentCliError("agent tool execute requires --run-id, --operation, and --tool-call-id", { code: "cli.usage.missing_args", category: "usage" });
574
+ }
575
+ const argsParsed = await parseInlineJson(toolCallFlag.rest, "--arguments", "--arguments-file");
576
+ const resultParsed = await parseInlineJson(argsParsed.rest, "--result-body", "--result-file");
577
+ const seedFlags = parseProductionSigningSeedFlags(resultParsed.rest);
578
+ const args = argsParsed.payload;
579
+ const resultBody = resultParsed.payload;
580
+ if (Object.keys(resultBody).length === 0) {
581
+ throw agentCliError("agent tool execute requires --result-body or --result-file", { code: "cli.usage.missing_args", category: "usage" });
582
+ }
583
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
584
+ const run = await attachAgentRunFromStore(session.paybond, ctx, runIdFlag.value, {
585
+ payeeSigningSeedHex: seedFlags.payeeSigningSeedHex,
586
+ agentRecognitionSigningSeedHex: seedFlags.agentRecognitionSigningSeedHex,
587
+ reattachCommand: "agent tool execute",
588
+ });
589
+ try {
590
+ const wrapped = await run.interceptor.wrapExecute({
591
+ toolName: operationFlag.value,
592
+ toolCallId: toolCallFlag.value,
593
+ operation: operationFlag.value,
594
+ arguments: args,
595
+ execute: async () => resultBody,
596
+ });
597
+ return {
598
+ data: {
599
+ authorization: wrapped.authorization
600
+ ? {
601
+ allow: true,
602
+ audit_id: wrapped.authorization.auditId,
603
+ decision_id: wrapped.authorization.decisionId,
604
+ }
605
+ : undefined,
606
+ tool_result: wrapped.toolResult,
607
+ evidence: wrapped.evidence
608
+ ? {
609
+ submitted: wrapped.evidence.submitted,
610
+ intent_state: wrapped.evidence.intentState,
611
+ predicate_passed: wrapped.evidence.predicatePassed,
612
+ sandbox_lifecycle_status: wrapped.evidence.sandboxLifecycleStatus,
613
+ }
614
+ : undefined,
615
+ },
616
+ warnings: session.warnings,
617
+ };
618
+ }
619
+ catch (err) {
620
+ throw mapToolExecuteError(err, {
621
+ tool_result: resultBody,
622
+ });
623
+ }
624
+ });
625
+ }
626
+ export async function handleAgentToolValidate(ctx, argv) {
627
+ const productionFlag = consumeBooleanFlag(argv, "--production");
628
+ const runIdFlag = consumeFlag(productionFlag.rest, "--run-id");
629
+ const operationFlag = consumeFlag(runIdFlag.rest, "--operation");
630
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
631
+ if (!runIdFlag.value || !operationFlag.value) {
632
+ throw agentCliError("agent tool validate requires --run-id and --operation", { code: "cli.usage.missing_args", category: "usage" });
633
+ }
634
+ const requestedSpendCents = spendFlag.value
635
+ ? parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents")
636
+ : parseOptionalNonNegativeInt(undefined, "--requested-spend-cents");
637
+ const argsParsed = await parseInlineJson(spendFlag.rest, "--arguments", "--arguments-file");
638
+ const seedFlags = parseProductionSigningSeedFlags(argsParsed.rest);
639
+ const args = argsParsed.payload;
640
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
641
+ const run = await attachAgentRunFromStore(session.paybond, ctx, runIdFlag.value, {
642
+ payeeSigningSeedHex: seedFlags.payeeSigningSeedHex,
643
+ agentRecognitionSigningSeedHex: seedFlags.agentRecognitionSigningSeedHex,
644
+ reattachCommand: "agent tool validate",
645
+ });
646
+ const decision = await run.interceptor.authorizeToolCall({
647
+ toolName: operationFlag.value,
648
+ toolCallId: `validate-${Date.now()}`,
649
+ operation: operationFlag.value,
650
+ requestedSpendCents,
651
+ arguments: args,
652
+ });
653
+ const authorization = mapAuthorizationDecision(decision);
654
+ if (authorization.allow) {
655
+ return { data: { authorization }, warnings: session.warnings };
656
+ }
657
+ throw agentCliError(authorization.message ?? "spend authorization denied", {
658
+ code: "cli.agent.authorization_denied",
659
+ exitCode: 3,
660
+ category: "forbidden",
661
+ details: { authorization },
662
+ });
663
+ });
664
+ }
665
+ export async function handleAgentRegistryValidate(ctx, argv) {
666
+ const fileFlag = consumeFlag(argv, "--file");
667
+ if (!fileFlag.value) {
668
+ throw agentCliError("agent registry validate requires --file", {
669
+ code: "cli.usage.missing_args",
670
+ category: "usage",
671
+ });
672
+ }
673
+ const doc = await loadAgentRegistryFile(resolve(ctx.cwd, fileFlag.value));
674
+ const validation = validateAgentRegistryDocument(doc);
675
+ return {
676
+ data: {
677
+ ok: validation.ok,
678
+ version: validation.version,
679
+ default_deny: validation.default_deny,
680
+ tool_count: validation.tool_count,
681
+ side_effecting_count: validation.side_effecting_count,
682
+ issues: validation.issues,
683
+ },
684
+ };
685
+ }
686
+ export async function handleAgentSandboxSmoke(ctx, argv) {
687
+ const productionFlag = consumeBooleanFlag(argv, "--production");
688
+ const policyPresetFlag = consumeFlag(productionFlag.rest, "--preset");
689
+ const policyFlag = consumeFlag(policyPresetFlag.rest, "--policy-file");
690
+ const operationFlag = consumeFlag(policyFlag.rest, "--operation");
691
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
692
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
693
+ let resolvedPolicyFile = policyFlag.value?.trim();
694
+ const solutionPresetId = policyPresetFlag.value?.trim() ?? "";
695
+ let solutionSmokeDefaults;
696
+ if (solutionPresetId) {
697
+ if (resolvedPolicyFile) {
698
+ throw agentCliError("agent sandbox smoke accepts --preset or --policy-file, not both", {
699
+ code: "cli.usage.conflicting_args",
700
+ category: "usage",
701
+ });
702
+ }
703
+ try {
704
+ resolvedPolicyFile = resolvePolicyPresetPath(solutionPresetId);
705
+ if (isKnownSolutionId(solutionPresetId)) {
706
+ solutionSmokeDefaults = getSolutionSmokeDefaults(solutionPresetId);
707
+ }
708
+ }
709
+ catch (err) {
710
+ throw agentCliError(err instanceof Error ? err.message : String(err), {
711
+ code: "cli.agent.policy_preset_invalid",
712
+ category: "validation",
713
+ });
714
+ }
715
+ }
716
+ const resolvedOperation = operationFlag.value?.trim() || solutionSmokeDefaults?.operation;
717
+ const resolvedSpend = spendFlag.value?.trim() || (solutionSmokeDefaults ? String(solutionSmokeDefaults.requestedSpendCents) : undefined);
718
+ const resolvedEvidencePreset = presetFlag.value?.trim() || solutionSmokeDefaults?.evidencePreset;
719
+ if (!resolvedPolicyFile &&
720
+ (!resolvedOperation || !resolvedSpend || !resolvedEvidencePreset)) {
721
+ throw agentCliError("agent sandbox smoke requires --preset, --policy-file, or (--operation, --requested-spend-cents, and --evidence-preset)", { code: "cli.usage.missing_args", category: "usage" });
722
+ }
723
+ const resultParsed = await parseInlineJson(presetFlag.rest, "--result-body", "--result-file");
724
+ let resultBody = resultParsed.payload;
725
+ if (Object.keys(resultBody).length === 0) {
726
+ if (solutionSmokeDefaults) {
727
+ resultBody = { ...solutionSmokeDefaults.resultBody };
728
+ }
729
+ else {
730
+ throw agentCliError("agent sandbox smoke requires --result-body or --result-file", { code: "cli.usage.missing_args", category: "usage" });
731
+ }
732
+ }
733
+ let smokeOperation = resolvedOperation ?? "";
734
+ const bindArgv = [...(productionFlag.present ? ["--production"] : [])];
735
+ if (resolvedPolicyFile) {
736
+ bindArgv.push("--policy-file", resolvedPolicyFile);
737
+ if (resolvedOperation) {
738
+ bindArgv.push("--operation", resolvedOperation);
739
+ }
740
+ if (resolvedSpend) {
741
+ bindArgv.push("--requested-spend-cents", resolvedSpend);
742
+ }
743
+ if (resolvedEvidencePreset) {
744
+ bindArgv.push("--completion-preset", resolvedEvidencePreset);
745
+ }
746
+ }
747
+ else {
748
+ bindArgv.push("--operation", resolvedOperation, "--requested-spend-cents", resolvedSpend, "--completion-preset", resolvedEvidencePreset);
749
+ }
750
+ const bindResult = await handleAgentRunBind(ctx, bindArgv);
751
+ smokeOperation = String(bindResult.data.operation ?? smokeOperation);
752
+ const runId = String(bindResult.data.run_id ?? "");
753
+ try {
754
+ const executeResult = await handleAgentToolExecute(ctx, [
755
+ ...(productionFlag.present ? ["--production"] : []),
756
+ "--run-id",
757
+ runId,
758
+ "--operation",
759
+ smokeOperation,
760
+ "--tool-call-id",
761
+ "smoke-1",
762
+ "--result-body",
763
+ JSON.stringify(resultBody),
764
+ ]);
765
+ const stored = await loadAgentRunContext(ctx.cwd, runId);
766
+ const bindForChecklist = {
767
+ ...bindResult.data,
768
+ completion_preset: stored.completion_preset,
769
+ requested_spend_cents: stored.requested_spend_cents,
770
+ };
771
+ const checklistLines = appendSmokeDeepLinkChecklistLines(formatAgentSandboxSmokeChecklist({
772
+ presetId: policyPresetFlag.value?.trim(),
773
+ bind: bindForChecklist,
774
+ execute: executeResult.data,
775
+ resultBody,
776
+ globals: ctx.globals,
777
+ }), buildAgentSandboxSmokeDeepLinks({ bind: bindForChecklist }), ctx.globals);
778
+ const deepLinks = buildAgentSandboxSmokeDeepLinks({ bind: bindForChecklist });
779
+ recordSmokeTraceEvent({
780
+ preset: policyPresetFlag.value?.trim() || "travel",
781
+ bind: bindForChecklist,
782
+ execute: executeResult.data,
783
+ resultBody,
784
+ }, ctx.cwd);
785
+ return {
786
+ data: {
787
+ bind: bindResult.data,
788
+ execute: executeResult.data,
789
+ checklist_lines: checklistLines,
790
+ ...deepLinks,
791
+ },
792
+ warnings: bindResult.warnings,
793
+ };
794
+ }
795
+ catch (err) {
796
+ if (err instanceof CliError) {
797
+ throw new CliError(err.message, {
798
+ category: err.category,
799
+ code: err.code,
800
+ exitCode: err.exitCode,
801
+ details: {
802
+ ...(err.details ?? {}),
803
+ bind: bindResult.data,
804
+ },
805
+ });
806
+ }
807
+ throw err;
808
+ }
809
+ }
810
+ export async function handleAgentDemoVercelAiSmoke(ctx, argv) {
811
+ const productionFlag = consumeBooleanFlag(argv, "--production");
812
+ const operationFlag = consumeFlag(productionFlag.rest, "--operation");
813
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
814
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
815
+ if (!operationFlag.value || !spendFlag.value || !presetFlag.value) {
816
+ throw agentCliError("agent demo vercel-ai smoke requires --operation, --requested-spend-cents, and --evidence-preset", { code: "cli.usage.missing_args", category: "usage" });
817
+ }
818
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
819
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
820
+ const demo = await runVercelAiSandboxDemo({
821
+ paybond: session.paybond,
822
+ operation: operationFlag.value,
823
+ requestedSpendCents,
824
+ evidencePreset: presetFlag.value,
825
+ });
826
+ if (demo.tool_approval !== "approved") {
827
+ throw agentCliError("tool approval did not pass in Vercel AI sandbox demo", {
828
+ code: "cli.agent.authorization_denied",
829
+ exitCode: 3,
830
+ category: "forbidden",
831
+ details: { tool_approval: demo.tool_approval },
832
+ });
833
+ }
834
+ if (!demo.execute.tool_result) {
835
+ throw agentCliError("Vercel AI sandbox demo did not produce a paid tool result", {
836
+ code: "cli.agent.tool_execute_failed",
837
+ details: { generate_text: demo.generate_text },
838
+ });
839
+ }
840
+ return {
841
+ data: demo,
842
+ warnings: session.warnings,
843
+ };
844
+ });
845
+ }
846
+ export async function handleAgentDemoLanggraphSmoke(ctx, argv) {
847
+ const productionFlag = consumeBooleanFlag(argv, "--production");
848
+ const runtimeFlag = consumeFlag(productionFlag.rest, "--runtime");
849
+ const operationFlag = consumeFlag(runtimeFlag.rest, "--operation");
850
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
851
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
852
+ if (!operationFlag.value || !spendFlag.value || !presetFlag.value) {
853
+ throw agentCliError("agent demo langgraph smoke requires --operation, --requested-spend-cents, and --evidence-preset", { code: "cli.usage.missing_args", category: "usage" });
854
+ }
855
+ const runtime = (runtimeFlag.value ?? "typescript").trim().toLowerCase();
856
+ if (runtime !== "typescript") {
857
+ throw agentCliError(`agent demo langgraph smoke --runtime ${runtime} is not supported in the TypeScript CLI; use paybond-kit Python CLI`, { code: "cli.usage.unsupported_runtime", category: "usage" });
858
+ }
859
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
860
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
861
+ const demo = await runLangGraphSandboxDemo({
862
+ paybond: session.paybond,
863
+ operation: operationFlag.value,
864
+ requestedSpendCents,
865
+ evidencePreset: presetFlag.value,
866
+ });
867
+ if (!demo.authorization.allow) {
868
+ throw agentCliError("LangGraph sandbox demo authorization did not pass", {
869
+ code: "cli.agent.authorization_denied",
870
+ exitCode: 3,
871
+ category: "forbidden",
872
+ details: { tool_message: demo.tool_message },
873
+ });
874
+ }
875
+ if (demo.tool_message.status === "error") {
876
+ throw agentCliError("LangGraph sandbox demo returned an error tool message", {
877
+ code: "cli.agent.tool_execute_failed",
878
+ details: { tool_message: demo.tool_message },
879
+ });
880
+ }
881
+ return {
882
+ data: demo,
883
+ warnings: session.warnings,
884
+ };
885
+ });
886
+ }
887
+ export async function handleAgentDemoGenericSmoke(ctx, argv) {
888
+ const productionFlag = consumeBooleanFlag(argv, "--production");
889
+ const runtimeFlag = consumeFlag(productionFlag.rest, "--runtime");
890
+ const operationFlag = consumeFlag(runtimeFlag.rest, "--operation");
891
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
892
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
893
+ if (!operationFlag.value || !spendFlag.value || !presetFlag.value) {
894
+ throw agentCliError("agent demo generic smoke requires --operation, --requested-spend-cents, and --evidence-preset", { code: "cli.usage.missing_args", category: "usage" });
895
+ }
896
+ const runtime = (runtimeFlag.value ?? "typescript").trim().toLowerCase();
897
+ if (runtime !== "typescript") {
898
+ throw agentCliError(`agent demo generic smoke --runtime ${runtime} is not supported in the TypeScript CLI; use paybond-kit Python CLI`, { code: "cli.usage.unsupported_runtime", category: "usage" });
899
+ }
900
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
901
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
902
+ const demo = await runGenericSandboxDemo({
903
+ paybond: session.paybond,
904
+ operation: operationFlag.value,
905
+ requestedSpendCents,
906
+ evidencePreset: presetFlag.value,
907
+ });
908
+ if (!demo.authorization.allow) {
909
+ throw agentCliError("generic sandbox demo authorization did not pass", {
910
+ code: "cli.agent.authorization_denied",
911
+ exitCode: 3,
912
+ category: "forbidden",
913
+ details: { authorization: demo.authorization },
914
+ });
915
+ }
916
+ if (!demo.execute.tool_result) {
917
+ throw agentCliError("generic sandbox demo did not produce a paid tool result", {
918
+ code: "cli.agent.tool_execute_failed",
919
+ details: { execute: demo.execute },
920
+ });
921
+ }
922
+ return {
923
+ data: demo,
924
+ warnings: session.warnings,
925
+ };
926
+ });
927
+ }
928
+ export async function handleAgentDemoClaudeAgentsSmoke(ctx, argv) {
929
+ const productionFlag = consumeBooleanFlag(argv, "--production");
930
+ const runtimeFlag = consumeFlag(productionFlag.rest, "--runtime");
931
+ const operationFlag = consumeFlag(runtimeFlag.rest, "--operation");
932
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
933
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
934
+ if (!operationFlag.value || !spendFlag.value || !presetFlag.value) {
935
+ throw agentCliError("agent demo claude-agents smoke requires --operation, --requested-spend-cents, and --evidence-preset", { code: "cli.usage.missing_args", category: "usage" });
936
+ }
937
+ const runtime = (runtimeFlag.value ?? "typescript").trim().toLowerCase();
938
+ if (runtime !== "typescript") {
939
+ throw agentCliError(`agent demo claude-agents smoke --runtime ${runtime} is not supported in the TypeScript CLI; use paybond-kit Python CLI`, { code: "cli.usage.unsupported_runtime", category: "usage" });
940
+ }
941
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
942
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
943
+ const demo = await runClaudeAgentsSandboxDemo({
944
+ paybond: session.paybond,
945
+ operation: operationFlag.value,
946
+ requestedSpendCents,
947
+ evidencePreset: presetFlag.value,
948
+ });
949
+ if (!demo.evidence.submitted) {
950
+ throw agentCliError("Claude Agents sandbox demo did not submit evidence", {
951
+ code: "cli.agent.evidence_failed",
952
+ exitCode: 5,
953
+ category: "gateway",
954
+ details: { tool_result: demo.tool_result },
955
+ });
956
+ }
957
+ if (!demo.tool_result) {
958
+ throw agentCliError("Claude Agents sandbox demo did not produce a paid tool result", {
959
+ code: "cli.agent.tool_execute_failed",
960
+ details: { allowed_tools: demo.allowed_tools },
961
+ });
962
+ }
963
+ return {
964
+ data: demo,
965
+ warnings: session.warnings,
966
+ };
967
+ });
968
+ }
969
+ export async function handleAgentDemoOpenAIAgentsSmoke(ctx, argv) {
970
+ const productionFlag = consumeBooleanFlag(argv, "--production");
971
+ const operationFlag = consumeFlag(productionFlag.rest, "--operation");
972
+ const spendFlag = consumeFlag(operationFlag.rest, "--requested-spend-cents");
973
+ const presetFlag = consumeFlag(spendFlag.rest, "--evidence-preset");
974
+ if (!operationFlag.value || !spendFlag.value || !presetFlag.value) {
975
+ throw agentCliError("agent demo openai-agents smoke requires --operation, --requested-spend-cents, and --evidence-preset", { code: "cli.usage.missing_args", category: "usage" });
976
+ }
977
+ const requestedSpendCents = parseRequiredNonNegativeInt(spendFlag.value, "--requested-spend-cents");
978
+ return withPaybondAgentCli(ctx, productionFlag.present, async (session) => {
979
+ const demo = await runOpenAIAgentsSandboxDemo({
980
+ paybond: session.paybond,
981
+ operation: operationFlag.value,
982
+ requestedSpendCents,
983
+ evidencePreset: presetFlag.value,
984
+ });
985
+ if (demo.guardrail.behavior !== "allow" && demo.guardrail.behavior !== "not-applicable") {
986
+ throw agentCliError("OpenAI Agents sandbox demo guardrail did not allow execution", {
987
+ code: "cli.agent.authorization_denied",
988
+ exitCode: 3,
989
+ category: "forbidden",
990
+ details: { guardrail: demo.guardrail },
991
+ });
992
+ }
993
+ if (!demo.execute.tool_result) {
994
+ throw agentCliError("OpenAI Agents sandbox demo did not produce a paid tool result", {
995
+ code: "cli.agent.tool_execute_failed",
996
+ details: { execute: demo.execute },
997
+ });
998
+ }
999
+ return {
1000
+ data: demo,
1001
+ warnings: session.warnings,
1002
+ };
1003
+ });
1004
+ }
1005
+ function mapToolExecuteError(err, partial) {
1006
+ if (err instanceof PaybondSpendDeniedError) {
1007
+ return agentCliError(err.message, {
1008
+ code: "cli.agent.authorization_denied",
1009
+ exitCode: 3,
1010
+ category: "forbidden",
1011
+ details: {
1012
+ authorization: { ...(err.result ?? {}), allow: false },
1013
+ tool_result: partial.tool_result,
1014
+ },
1015
+ });
1016
+ }
1017
+ if (err instanceof PaybondSpendApprovalRequiredError) {
1018
+ return agentCliError(err.message, {
1019
+ code: "cli.agent.approval_required",
1020
+ exitCode: 3,
1021
+ category: "forbidden",
1022
+ details: {
1023
+ authorization: { ...(err.result ?? {}), allow: false, approval_required: true },
1024
+ tool_result: partial.tool_result,
1025
+ },
1026
+ });
1027
+ }
1028
+ if (err instanceof PaybondUnregisteredSideEffectingToolError) {
1029
+ return agentCliError(err.message, {
1030
+ code: "cli.agent.unregistered_tool",
1031
+ exitCode: 3,
1032
+ category: "forbidden",
1033
+ details: { tool_result: partial.tool_result },
1034
+ });
1035
+ }
1036
+ if (err instanceof PaybondAutoEvidenceSubmitError) {
1037
+ return agentCliError(err.message, {
1038
+ code: "cli.agent.evidence_failed",
1039
+ exitCode: 5,
1040
+ category: "gateway",
1041
+ details: {
1042
+ tool_result: partial.tool_result,
1043
+ evidence: { submitted: false },
1044
+ },
1045
+ });
1046
+ }
1047
+ if (err instanceof PaybondToolRegistryValidationError) {
1048
+ return agentCliError(err.message, {
1049
+ code: "cli.agent.registry_invalid",
1050
+ details: { tool_result: partial.tool_result },
1051
+ });
1052
+ }
1053
+ if (err instanceof CliError) {
1054
+ return err;
1055
+ }
1056
+ return agentCliError(err instanceof Error ? err.message : String(err), {
1057
+ code: "cli.agent.tool_execute_failed",
1058
+ details: { tool_result: partial.tool_result },
1059
+ });
1060
+ }
1061
+ export async function handleAgent(ctx, group, subcommand, argv) {
1062
+ if (group === "run" && subcommand === "bind") {
1063
+ return handleAgentRunBind(ctx, argv);
1064
+ }
1065
+ if (group === "run" && subcommand === "status") {
1066
+ return handleAgentRunStatus(ctx, argv);
1067
+ }
1068
+ if (group === "run" && subcommand === "trace") {
1069
+ return handleAgentRunTrace(ctx, argv);
1070
+ }
1071
+ if (group === "run" && subcommand === "reload-policy") {
1072
+ return handleAgentRunReloadPolicy(ctx, argv);
1073
+ }
1074
+ if (group === "tool" && subcommand === "execute") {
1075
+ return handleAgentToolExecute(ctx, argv);
1076
+ }
1077
+ if (group === "tool" && subcommand === "validate") {
1078
+ return handleAgentToolValidate(ctx, argv);
1079
+ }
1080
+ if (group === "registry" && subcommand === "validate") {
1081
+ return handleAgentRegistryValidate(ctx, argv);
1082
+ }
1083
+ if (group === "sandbox" && subcommand === "smoke") {
1084
+ return handleAgentSandboxSmoke(ctx, argv);
1085
+ }
1086
+ if (group === "demo" && subcommand === "vercel-ai") {
1087
+ if (argv[0] !== "smoke") {
1088
+ throw agentCliError("agent demo vercel-ai requires smoke subcommand", {
1089
+ code: "cli.usage.unknown_command",
1090
+ category: "usage",
1091
+ });
1092
+ }
1093
+ return handleAgentDemoVercelAiSmoke(ctx, argv.slice(1));
1094
+ }
1095
+ if (group === "demo" && subcommand === "langgraph") {
1096
+ if (argv[0] !== "smoke") {
1097
+ throw agentCliError("agent demo langgraph requires smoke subcommand", {
1098
+ code: "cli.usage.unknown_command",
1099
+ category: "usage",
1100
+ });
1101
+ }
1102
+ return handleAgentDemoLanggraphSmoke(ctx, argv.slice(1));
1103
+ }
1104
+ if (group === "demo" && subcommand === "generic") {
1105
+ if (argv[0] !== "smoke") {
1106
+ throw agentCliError("agent demo generic requires smoke subcommand", {
1107
+ code: "cli.usage.unknown_command",
1108
+ category: "usage",
1109
+ });
1110
+ }
1111
+ return handleAgentDemoGenericSmoke(ctx, argv.slice(1));
1112
+ }
1113
+ if (group === "demo" && subcommand === "claude-agents") {
1114
+ if (argv[0] !== "smoke") {
1115
+ throw agentCliError("agent demo claude-agents requires smoke subcommand", {
1116
+ code: "cli.usage.unknown_command",
1117
+ category: "usage",
1118
+ });
1119
+ }
1120
+ return handleAgentDemoClaudeAgentsSmoke(ctx, argv.slice(1));
1121
+ }
1122
+ if (group === "demo" && subcommand === "openai-agents") {
1123
+ if (argv[0] !== "smoke") {
1124
+ throw agentCliError("agent demo openai-agents requires smoke subcommand", {
1125
+ code: "cli.usage.unknown_command",
1126
+ category: "usage",
1127
+ });
1128
+ }
1129
+ return handleAgentDemoOpenAIAgentsSmoke(ctx, argv.slice(1));
1130
+ }
1131
+ throw agentCliError(`unknown agent subcommand: agent ${group} ${subcommand}`, {
1132
+ code: "cli.usage.unknown_command",
1133
+ category: "usage",
1134
+ });
1135
+ }