@paybond/kit 0.10.0 → 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 (335) 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/command-spec.d.ts +1 -0
  71. package/dist/cli/command-spec.js +286 -5
  72. package/dist/cli/commands/agent.d.ts +16 -0
  73. package/dist/cli/commands/agent.js +1135 -0
  74. package/dist/cli/commands/dev.d.ts +7 -0
  75. package/dist/cli/commands/dev.js +348 -0
  76. package/dist/cli/commands/discovery.js +3 -3
  77. package/dist/cli/commands/policy.d.ts +13 -0
  78. package/dist/cli/commands/policy.js +769 -0
  79. package/dist/cli/commands/setup.d.ts +3 -0
  80. package/dist/cli/commands/setup.js +124 -8
  81. package/dist/cli/commands/workflows.js +9 -4
  82. package/dist/cli/config.d.ts +2 -0
  83. package/dist/cli/config.js +4 -2
  84. package/dist/cli/context.js +2 -1
  85. package/dist/cli/credentials.js +2 -2
  86. package/dist/cli/doctor-agent-middleware.d.ts +5 -0
  87. package/dist/cli/doctor-agent-middleware.js +49 -0
  88. package/dist/cli/globals.d.ts +1 -0
  89. package/dist/cli/globals.js +11 -1
  90. package/dist/cli/help.d.ts +1 -1
  91. package/dist/cli/help.js +35 -3
  92. package/dist/cli/mcp-install.js +2 -2
  93. package/dist/cli/mcp-policy.d.ts +3 -0
  94. package/dist/cli/mcp-policy.js +19 -13
  95. package/dist/cli/mcp-verify-config.js +9 -11
  96. package/dist/cli/redact.js +29 -8
  97. package/dist/cli/router.js +105 -2
  98. package/dist/cli/smoke-deep-links.d.ts +15 -0
  99. package/dist/cli/smoke-deep-links.js +63 -0
  100. package/dist/cli/telemetry.d.ts +17 -0
  101. package/dist/cli/telemetry.js +94 -0
  102. package/dist/completion-catalog-digest.d.ts +2 -0
  103. package/dist/completion-catalog-digest.js +2 -0
  104. package/dist/completion-catalog-integrity.d.ts +2 -0
  105. package/dist/completion-catalog-integrity.js +17 -0
  106. package/dist/completion-catalog.d.ts +49 -0
  107. package/dist/completion-catalog.js +62 -0
  108. package/dist/completion-contract-digest.d.ts +37 -0
  109. package/dist/completion-contract-digest.js +73 -0
  110. package/dist/completion-forbidden-fields.d.ts +5 -0
  111. package/dist/completion-forbidden-fields.js +26 -0
  112. package/dist/completion-init.d.ts +8 -0
  113. package/dist/completion-init.js +334 -0
  114. package/dist/completion-resolve.d.ts +21 -0
  115. package/dist/completion-resolve.js +86 -0
  116. package/dist/completion-validate-evidence.d.ts +24 -0
  117. package/dist/completion-validate-evidence.js +145 -0
  118. package/dist/dev/offline-gateway.d.ts +24 -0
  119. package/dist/dev/offline-gateway.js +102 -0
  120. package/dist/dev/trace-buffer.d.ts +61 -0
  121. package/dist/dev/trace-buffer.js +330 -0
  122. package/dist/dev/trace-security-headers.d.ts +11 -0
  123. package/dist/dev/trace-security-headers.js +16 -0
  124. package/dist/dev/trace-server.d.ts +8 -0
  125. package/dist/dev/trace-server.js +38 -0
  126. package/dist/dev/trace-ui.d.ts +4 -0
  127. package/dist/dev/trace-ui.js +25 -0
  128. package/dist/dev/wiremock-up.d.ts +15 -0
  129. package/dist/dev/wiremock-up.js +118 -0
  130. package/dist/doctor-completion.d.ts +17 -0
  131. package/dist/doctor-completion.js +428 -0
  132. package/dist/gateway-url.d.ts +7 -0
  133. package/dist/gateway-url.js +69 -0
  134. package/dist/index.d.ts +119 -2
  135. package/dist/index.js +267 -6
  136. package/dist/init.js +374 -57
  137. package/dist/langgraph/awrap-tool-call.d.ts +25 -0
  138. package/dist/langgraph/awrap-tool-call.js +81 -0
  139. package/dist/langgraph/config.d.ts +13 -0
  140. package/dist/langgraph/config.js +11 -0
  141. package/dist/langgraph/index.d.ts +4 -0
  142. package/dist/langgraph/index.js +4 -0
  143. package/dist/langgraph/sandbox-demo.d.ts +40 -0
  144. package/dist/langgraph/sandbox-demo.js +96 -0
  145. package/dist/langgraph/tool-node.d.ts +10 -0
  146. package/dist/langgraph/tool-node.js +38 -0
  147. package/dist/login.js +7 -0
  148. package/dist/mcp/index.d.ts +1 -0
  149. package/dist/mcp/index.js +1 -0
  150. package/dist/mcp/tool-surface.d.ts +25 -0
  151. package/dist/mcp/tool-surface.js +17 -0
  152. package/dist/mcp-capability-token-cache.d.ts +24 -0
  153. package/dist/mcp-capability-token-cache.js +101 -0
  154. package/dist/mcp-evidence-policy.d.ts +48 -0
  155. package/dist/mcp-evidence-policy.js +117 -0
  156. package/dist/mcp-policy-reload.d.ts +79 -0
  157. package/dist/mcp-policy-reload.js +200 -0
  158. package/dist/mcp-sep2828-evidence.d.ts +36 -0
  159. package/dist/mcp-sep2828-evidence.js +65 -0
  160. package/dist/mcp-server.d.ts +6 -0
  161. package/dist/mcp-server.js +224 -44
  162. package/dist/openai-agents/index.d.ts +40 -0
  163. package/dist/openai-agents/index.js +151 -0
  164. package/dist/openai-agents/sandbox-demo.d.ts +34 -0
  165. package/dist/openai-agents/sandbox-demo.js +118 -0
  166. package/dist/payee-evidence.js +2 -29
  167. package/dist/policy/catalog.d.ts +31 -0
  168. package/dist/policy/catalog.js +48 -0
  169. package/dist/policy/compose-utils.d.ts +3 -0
  170. package/dist/policy/compose-utils.js +4 -0
  171. package/dist/policy/compose.d.ts +20 -0
  172. package/dist/policy/compose.js +240 -0
  173. package/dist/policy/digest.d.ts +7 -0
  174. package/dist/policy/digest.js +75 -0
  175. package/dist/policy/domain.d.ts +15 -0
  176. package/dist/policy/domain.js +28 -0
  177. package/dist/policy/guardrail-spec.d.ts +17 -0
  178. package/dist/policy/guardrail-spec.js +140 -0
  179. package/dist/policy/guardrails.d.ts +48 -0
  180. package/dist/policy/guardrails.js +72 -0
  181. package/dist/policy/index.d.ts +21 -0
  182. package/dist/policy/index.js +21 -0
  183. package/dist/policy/init.d.ts +102 -0
  184. package/dist/policy/init.js +351 -0
  185. package/dist/policy/intent-spec.d.ts +52 -0
  186. package/dist/policy/intent-spec.js +176 -0
  187. package/dist/policy/json-path.d.ts +4 -0
  188. package/dist/policy/json-path.js +23 -0
  189. package/dist/policy/layers-io.d.ts +7 -0
  190. package/dist/policy/layers-io.js +28 -0
  191. package/dist/policy/load-effective.d.ts +22 -0
  192. package/dist/policy/load-effective.js +77 -0
  193. package/dist/policy/load.d.ts +85 -0
  194. package/dist/policy/load.js +164 -0
  195. package/dist/policy/merge.d.ts +29 -0
  196. package/dist/policy/merge.js +297 -0
  197. package/dist/policy/parse-text.d.ts +2 -0
  198. package/dist/policy/parse-text.js +126 -0
  199. package/dist/policy/policy-api.d.ts +45 -0
  200. package/dist/policy/policy-api.js +61 -0
  201. package/dist/policy/presets.d.ts +19 -0
  202. package/dist/policy/presets.js +66 -0
  203. package/dist/policy/registry.d.ts +7 -0
  204. package/dist/policy/registry.js +33 -0
  205. package/dist/policy/reload.d.ts +86 -0
  206. package/dist/policy/reload.js +233 -0
  207. package/dist/policy/render-yaml.d.ts +3 -0
  208. package/dist/policy/render-yaml.js +69 -0
  209. package/dist/policy/sandbox-bootstrap.d.ts +19 -0
  210. package/dist/policy/sandbox-bootstrap.js +66 -0
  211. package/dist/policy/schema.d.ts +204 -0
  212. package/dist/policy/schema.js +255 -0
  213. package/dist/policy/snapshot.d.ts +33 -0
  214. package/dist/policy/snapshot.js +23 -0
  215. package/dist/policy/validate-remote.d.ts +43 -0
  216. package/dist/policy/validate-remote.js +104 -0
  217. package/dist/policy/validate.d.ts +36 -0
  218. package/dist/policy/validate.js +150 -0
  219. package/dist/policy/watcher.d.ts +29 -0
  220. package/dist/policy/watcher.js +112 -0
  221. package/dist/principal-intent.d.ts +52 -0
  222. package/dist/principal-intent.js +193 -37
  223. package/dist/project-init.d.ts +34 -0
  224. package/dist/project-init.js +898 -0
  225. package/dist/sep2828-signature.d.ts +10 -0
  226. package/dist/sep2828-signature.js +134 -0
  227. package/dist/solutions/api.d.ts +22 -0
  228. package/dist/solutions/api.js +40 -0
  229. package/dist/solutions/catalog.d.ts +34 -0
  230. package/dist/solutions/catalog.js +129 -0
  231. package/dist/solutions/index.d.ts +2 -0
  232. package/dist/solutions/index.js +2 -0
  233. package/dist/template-init.d.ts +54 -0
  234. package/dist/template-init.js +203 -0
  235. package/dist/vercel-ai/config.d.ts +15 -0
  236. package/dist/vercel-ai/config.js +13 -0
  237. package/dist/vercel-ai/index.d.ts +4 -0
  238. package/dist/vercel-ai/index.js +4 -0
  239. package/dist/vercel-ai/sandbox-demo.d.ts +44 -0
  240. package/dist/vercel-ai/sandbox-demo.js +153 -0
  241. package/dist/vercel-ai/tool-approval.d.ts +16 -0
  242. package/dist/vercel-ai/tool-approval.js +41 -0
  243. package/dist/vercel-ai/wrap-tools.d.ts +9 -0
  244. package/dist/vercel-ai/wrap-tools.js +40 -0
  245. package/dist/x402-receipt-evidence.d.ts +29 -0
  246. package/dist/x402-receipt-evidence.js +97 -0
  247. package/dist/x402-receipt-signature.d.ts +12 -0
  248. package/dist/x402-receipt-signature.js +211 -0
  249. package/package.json +75 -3
  250. package/solutions/aws.json +17 -0
  251. package/solutions/saas.json +17 -0
  252. package/solutions/shopping.json +17 -0
  253. package/solutions/travel.json +18 -0
  254. package/templates/manifest.json +169 -0
  255. package/templates/openai-shopping-agent/.env.example +3 -0
  256. package/templates/openai-shopping-agent/.github/workflows/smoke.yml +20 -0
  257. package/templates/openai-shopping-agent/LICENSE +201 -0
  258. package/templates/openai-shopping-agent/README.md +29 -0
  259. package/templates/openai-shopping-agent/package.json +22 -0
  260. package/templates/openai-shopping-agent/paybond.policy.yaml +22 -0
  261. package/templates/openai-shopping-agent/src/index.ts +22 -0
  262. package/templates/openai-shopping-agent/src/paybond.config.ts +51 -0
  263. package/templates/openai-shopping-agent/tsconfig.json +13 -0
  264. package/templates/paybond-aws-operator/.env.example +3 -0
  265. package/templates/paybond-aws-operator/.github/workflows/smoke.yml +20 -0
  266. package/templates/paybond-aws-operator/LICENSE +201 -0
  267. package/templates/paybond-aws-operator/README.md +29 -0
  268. package/templates/paybond-aws-operator/package.json +20 -0
  269. package/templates/paybond-aws-operator/paybond.policy.yaml +22 -0
  270. package/templates/paybond-aws-operator/src/index.ts +54 -0
  271. package/templates/paybond-aws-operator/src/paybond.config.ts +51 -0
  272. package/templates/paybond-aws-operator/tsconfig.json +13 -0
  273. package/templates/paybond-claude-agents-demo/.env.example +3 -0
  274. package/templates/paybond-claude-agents-demo/.github/workflows/smoke.yml +20 -0
  275. package/templates/paybond-claude-agents-demo/LICENSE +201 -0
  276. package/templates/paybond-claude-agents-demo/README.md +29 -0
  277. package/templates/paybond-claude-agents-demo/package.json +22 -0
  278. package/templates/paybond-claude-agents-demo/paybond.policy.yaml +22 -0
  279. package/templates/paybond-claude-agents-demo/src/index.ts +22 -0
  280. package/templates/paybond-claude-agents-demo/src/paybond.config.ts +51 -0
  281. package/templates/paybond-claude-agents-demo/tsconfig.json +13 -0
  282. package/templates/paybond-invoice-agent/.env.example +3 -0
  283. package/templates/paybond-invoice-agent/.github/workflows/smoke.yml +19 -0
  284. package/templates/paybond-invoice-agent/LICENSE +201 -0
  285. package/templates/paybond-invoice-agent/README.md +29 -0
  286. package/templates/paybond-invoice-agent/app.py +27 -0
  287. package/templates/paybond-invoice-agent/package.json +6 -0
  288. package/templates/paybond-invoice-agent/paybond.policy.yaml +22 -0
  289. package/templates/paybond-invoice-agent/paybond_config.py +45 -0
  290. package/templates/paybond-invoice-agent/requirements.txt +2 -0
  291. package/templates/paybond-mcp-coding-agent/.env.example +3 -0
  292. package/templates/paybond-mcp-coding-agent/.github/workflows/smoke.yml +20 -0
  293. package/templates/paybond-mcp-coding-agent/LICENSE +201 -0
  294. package/templates/paybond-mcp-coding-agent/README.md +39 -0
  295. package/templates/paybond-mcp-coding-agent/package.json +20 -0
  296. package/templates/paybond-mcp-coding-agent/paybond.policy.yaml +25 -0
  297. package/templates/paybond-mcp-coding-agent/src/index.ts +40 -0
  298. package/templates/paybond-mcp-coding-agent/src/paybond.config.ts +51 -0
  299. package/templates/paybond-mcp-coding-agent/tsconfig.json +13 -0
  300. package/templates/paybond-openai-agents-demo/.env.example +3 -0
  301. package/templates/paybond-openai-agents-demo/.github/workflows/smoke.yml +20 -0
  302. package/templates/paybond-openai-agents-demo/LICENSE +201 -0
  303. package/templates/paybond-openai-agents-demo/README.md +29 -0
  304. package/templates/paybond-openai-agents-demo/package.json +22 -0
  305. package/templates/paybond-openai-agents-demo/paybond.policy.yaml +22 -0
  306. package/templates/paybond-openai-agents-demo/src/index.ts +22 -0
  307. package/templates/paybond-openai-agents-demo/src/paybond.config.ts +51 -0
  308. package/templates/paybond-openai-agents-demo/tsconfig.json +13 -0
  309. package/templates/paybond-procurement-agent/.env.example +3 -0
  310. package/templates/paybond-procurement-agent/.github/workflows/smoke.yml +20 -0
  311. package/templates/paybond-procurement-agent/LICENSE +201 -0
  312. package/templates/paybond-procurement-agent/README.md +29 -0
  313. package/templates/paybond-procurement-agent/package.json +20 -0
  314. package/templates/paybond-procurement-agent/paybond.policy.yaml +25 -0
  315. package/templates/paybond-procurement-agent/src/index.ts +54 -0
  316. package/templates/paybond-procurement-agent/src/paybond.config.ts +51 -0
  317. package/templates/paybond-procurement-agent/tsconfig.json +13 -0
  318. package/templates/paybond-travel-agent/.env.example +3 -0
  319. package/templates/paybond-travel-agent/.github/workflows/smoke.yml +20 -0
  320. package/templates/paybond-travel-agent/LICENSE +201 -0
  321. package/templates/paybond-travel-agent/README.md +29 -0
  322. package/templates/paybond-travel-agent/package.json +23 -0
  323. package/templates/paybond-travel-agent/paybond.policy.yaml +22 -0
  324. package/templates/paybond-travel-agent/src/index.ts +22 -0
  325. package/templates/paybond-travel-agent/src/paybond.config.ts +51 -0
  326. package/templates/paybond-travel-agent/tsconfig.json +13 -0
  327. package/templates/paybond-vercel-shopping-agent/.env.example +3 -0
  328. package/templates/paybond-vercel-shopping-agent/.github/workflows/smoke.yml +20 -0
  329. package/templates/paybond-vercel-shopping-agent/LICENSE +201 -0
  330. package/templates/paybond-vercel-shopping-agent/README.md +29 -0
  331. package/templates/paybond-vercel-shopping-agent/package.json +22 -0
  332. package/templates/paybond-vercel-shopping-agent/paybond.policy.yaml +22 -0
  333. package/templates/paybond-vercel-shopping-agent/src/index.ts +22 -0
  334. package/templates/paybond-vercel-shopping-agent/src/paybond.config.ts +51 -0
  335. package/templates/paybond-vercel-shopping-agent/tsconfig.json +13 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Verifies SEP-2828 MCP decision/outcome record signatures before evidence mapping.
3
+ *
4
+ * Uses Ed25519-over-SHA-256(JCS-style canonical JSON with signature fields stripped),
5
+ * matching Paybond Kit audit-export verification and SEP-2787 detached signatures.
6
+ */
7
+ /** Verifies a single SEP-2828 decision or outcome record signature. */
8
+ export declare function verifySep2828RecordSignature(record: Record<string, unknown>): void;
9
+ /** Verifies signatures and backLink / decisionDigest pairing before mapping to evidence. */
10
+ export declare function verifySep2828ReceiptPair(decision: Record<string, unknown>, outcome: Record<string, unknown>): void;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Verifies SEP-2828 MCP decision/outcome record signatures before evidence mapping.
3
+ *
4
+ * Uses Ed25519-over-SHA-256(JCS-style canonical JSON with signature fields stripped),
5
+ * matching Paybond Kit audit-export verification and SEP-2787 detached signatures.
6
+ */
7
+ import { createHash } from "node:crypto";
8
+ import { verify as ed25519Verify } from "@noble/ed25519";
9
+ import { ensureEd25519Sha512Sync } from "./ed25519-sync.js";
10
+ import { normalizeJson } from "./json-digest.js";
11
+ const SIGNATURE_KEYS = new Set([
12
+ "signature",
13
+ "ed25519_signature_hex",
14
+ "message_digest_sha256_hex",
15
+ "signing_public_key_ed25519_hex",
16
+ ]);
17
+ const ASSERTED_BLOCKS = ["issuerAsserted", "receiptAsserted"];
18
+ function readObject(value) {
19
+ if (value !== null && typeof value === "object" && !Array.isArray(value)) {
20
+ return value;
21
+ }
22
+ return undefined;
23
+ }
24
+ function stripDigestPrefix(digest) {
25
+ return digest.replace(/^(sha256|blake3):/i, "");
26
+ }
27
+ function canonicalJsonBytes(value) {
28
+ const normalized = normalizeJson(value);
29
+ return new TextEncoder().encode(JSON.stringify(normalized));
30
+ }
31
+ function sha256Hex(data) {
32
+ const digest = createHash("sha256").update(Buffer.from(data)).digest();
33
+ return Buffer.from(digest).toString("hex");
34
+ }
35
+ function hexToBytes(hex) {
36
+ const trimmed = hex.trim();
37
+ if (trimmed.length % 2 !== 0) {
38
+ throw new Error("invalid hex length");
39
+ }
40
+ const out = new Uint8Array(trimmed.length / 2);
41
+ for (let i = 0; i < out.length; i++) {
42
+ out[i] = Number.parseInt(trimmed.slice(i * 2, i * 2 + 2), 16);
43
+ }
44
+ return out;
45
+ }
46
+ function stripSignatureFields(record) {
47
+ const out = {};
48
+ for (const [key, value] of Object.entries(record)) {
49
+ if (SIGNATURE_KEYS.has(key)) {
50
+ continue;
51
+ }
52
+ if (ASSERTED_BLOCKS.includes(key)) {
53
+ const asserted = readObject(value);
54
+ if (!asserted) {
55
+ continue;
56
+ }
57
+ const stripped = {};
58
+ for (const [innerKey, innerValue] of Object.entries(asserted)) {
59
+ if (!SIGNATURE_KEYS.has(innerKey)) {
60
+ stripped[innerKey] = innerValue;
61
+ }
62
+ }
63
+ if (Object.keys(stripped).length > 0) {
64
+ out[key] = stripped;
65
+ }
66
+ continue;
67
+ }
68
+ out[key] = value;
69
+ }
70
+ return out;
71
+ }
72
+ function extractSignatureMaterial(record) {
73
+ for (const blockName of ASSERTED_BLOCKS) {
74
+ const block = readObject(record[blockName]);
75
+ if (!block) {
76
+ continue;
77
+ }
78
+ const signature = block.ed25519_signature_hex ?? block.signature;
79
+ const publicKey = block.signing_public_key_ed25519_hex;
80
+ if (typeof signature === "string" && signature.length > 0 && typeof publicKey === "string" && publicKey.length > 0) {
81
+ return { signatureHex: signature.trim(), publicKeyHex: publicKey.trim() };
82
+ }
83
+ }
84
+ const signature = record.ed25519_signature_hex ?? record.signature;
85
+ const publicKey = record.signing_public_key_ed25519_hex;
86
+ if (typeof signature === "string" && signature.length > 0 && typeof publicKey === "string" && publicKey.length > 0) {
87
+ return { signatureHex: signature.trim(), publicKeyHex: publicKey.trim() };
88
+ }
89
+ throw new Error("SEP-2828 record missing ed25519 signature and signing_public_key_ed25519_hex");
90
+ }
91
+ /** Verifies a single SEP-2828 decision or outcome record signature. */
92
+ export function verifySep2828RecordSignature(record) {
93
+ ensureEd25519Sha512Sync();
94
+ const { signatureHex, publicKeyHex } = extractSignatureMaterial(record);
95
+ const digest = hexToBytes(sha256Hex(canonicalJsonBytes(stripSignatureFields(record))));
96
+ const signature = hexToBytes(signatureHex);
97
+ const publicKey = hexToBytes(publicKeyHex);
98
+ if (!ed25519Verify(signature, digest, publicKey)) {
99
+ throw new Error("SEP-2828 record signature verification failed");
100
+ }
101
+ }
102
+ function recordContentDigestHex(record) {
103
+ return sha256Hex(canonicalJsonBytes(stripSignatureFields(record)));
104
+ }
105
+ /** Verifies signatures and backLink / decisionDigest pairing before mapping to evidence. */
106
+ export function verifySep2828ReceiptPair(decision, outcome) {
107
+ verifySep2828RecordSignature(decision);
108
+ verifySep2828RecordSignature(outcome);
109
+ const decisionBackLink = readObject(decision.backLink);
110
+ const outcomeBackLink = readObject(outcome.backLink);
111
+ if (!decisionBackLink || !outcomeBackLink) {
112
+ throw new Error("SEP-2828 decision and outcome records must both include backLink");
113
+ }
114
+ const decisionDigest = decisionBackLink.attestationDigest;
115
+ const outcomeDigest = outcomeBackLink.attestationDigest;
116
+ if (typeof decisionDigest !== "string" || decisionDigest.length === 0) {
117
+ throw new Error("SEP-2828 decision backLink.attestationDigest is required");
118
+ }
119
+ if (decisionDigest !== outcomeDigest) {
120
+ throw new Error("SEP-2828 decision and outcome backLink.attestationDigest must match");
121
+ }
122
+ const outcomeDerived = readObject(outcome.outcomeDerived);
123
+ if (!outcomeDerived) {
124
+ throw new Error("SEP-2828 outcome record must include outcomeDerived");
125
+ }
126
+ const expectedDecisionDigest = stripDigestPrefix(recordContentDigestHex(decision));
127
+ const decisionDigestField = outcomeDerived.decisionDigest;
128
+ if (typeof decisionDigestField !== "string" || decisionDigestField.length === 0) {
129
+ throw new Error("SEP-2828 outcomeDerived.decisionDigest is required for pairing");
130
+ }
131
+ if (stripDigestPrefix(decisionDigestField) !== expectedDecisionDigest) {
132
+ throw new Error("SEP-2828 outcomeDerived.decisionDigest does not match signed decision record");
133
+ }
134
+ }
@@ -0,0 +1,22 @@
1
+ import { PaybondPolicy } from "../policy/load.js";
2
+ import { type VerticalPolicyOptions } from "../policy/policy-api.js";
3
+ import { getSolutionSmokeDefaults, loadSolutionManifest, type SolutionId, type SolutionSmokeDefaults } from "./catalog.js";
4
+ export type PaybondSolutionBundle = {
5
+ id: SolutionId;
6
+ title: string;
7
+ policy: PaybondPolicy;
8
+ smokeDefaults: SolutionSmokeDefaults;
9
+ completionPreset: string;
10
+ vendorPack?: string;
11
+ operations: string[];
12
+ };
13
+ /** Programmatic solution bundle API (`paybond.solution.*`). */
14
+ export declare const paybondSolutionPresets: {
15
+ readonly travel: (options?: VerticalPolicyOptions) => PaybondSolutionBundle;
16
+ readonly shopping: (options?: VerticalPolicyOptions) => PaybondSolutionBundle;
17
+ readonly saas: (options?: VerticalPolicyOptions) => PaybondSolutionBundle;
18
+ readonly aws: (options?: VerticalPolicyOptions) => PaybondSolutionBundle;
19
+ readonly loadManifest: typeof loadSolutionManifest;
20
+ readonly smokeDefaults: typeof getSolutionSmokeDefaults;
21
+ };
22
+ export type PaybondSolutionPresets = typeof paybondSolutionPresets;
@@ -0,0 +1,40 @@
1
+ import { paybondPolicyPresets } from "../policy/policy-api.js";
2
+ import { getSolutionSmokeDefaults, loadSolutionManifest } from "./catalog.js";
3
+ function listSideEffectingOperations(document) {
4
+ return Object.entries(document.tools)
5
+ .filter(([, entry]) => entry.side_effecting)
6
+ .map(([toolName, entry]) => entry.operation?.trim() || toolName);
7
+ }
8
+ function resolveSolutionBundle(solutionId, options) {
9
+ const manifest = loadSolutionManifest(solutionId);
10
+ const policy = options === undefined
11
+ ? paybondPolicyPresets[solutionId]()
12
+ : paybondPolicyPresets[solutionId](options);
13
+ const document = policy.document;
14
+ return {
15
+ id: solutionId,
16
+ title: manifest.title,
17
+ policy,
18
+ smokeDefaults: getSolutionSmokeDefaults(solutionId),
19
+ completionPreset: manifest.completion_preset,
20
+ ...(manifest.vendor_pack ? { vendorPack: manifest.vendor_pack } : {}),
21
+ operations: listSideEffectingOperations(document),
22
+ };
23
+ }
24
+ /** Programmatic solution bundle API (`paybond.solution.*`). */
25
+ export const paybondSolutionPresets = {
26
+ travel(options) {
27
+ return resolveSolutionBundle("travel", options);
28
+ },
29
+ shopping(options) {
30
+ return resolveSolutionBundle("shopping", options);
31
+ },
32
+ saas(options) {
33
+ return resolveSolutionBundle("saas", options);
34
+ },
35
+ aws(options) {
36
+ return resolveSolutionBundle("aws", options);
37
+ },
38
+ loadManifest: loadSolutionManifest,
39
+ smokeDefaults: getSolutionSmokeDefaults,
40
+ };
@@ -0,0 +1,34 @@
1
+ export type SolutionPolicyDefault = {
2
+ domain: string;
3
+ guardrails: string[];
4
+ };
5
+ export type SolutionSmokeManifest = {
6
+ result_body: Record<string, unknown>;
7
+ evidence_preset: string;
8
+ };
9
+ export type SolutionManifest = {
10
+ id: string;
11
+ title: string;
12
+ policy_default: SolutionPolicyDefault;
13
+ primary_operation: string;
14
+ completion_preset: string;
15
+ vendor_pack?: string;
16
+ smoke: SolutionSmokeManifest;
17
+ };
18
+ export type SolutionSmokeDefaults = {
19
+ operation: string;
20
+ requestedSpendCents: number;
21
+ evidencePreset: string;
22
+ resultBody: Record<string, unknown>;
23
+ };
24
+ declare const KNOWN_SOLUTION_IDS: readonly ["travel", "shopping", "saas", "aws"];
25
+ export type SolutionId = (typeof KNOWN_SOLUTION_IDS)[number];
26
+ /** True when `value` is a bundled solution id (travel, shopping, saas, aws). */
27
+ export declare function isKnownSolutionId(value: string): value is SolutionId;
28
+ /** List bundled solution ids shipped with Paybond Kit. */
29
+ export declare function listSolutionIds(): SolutionId[];
30
+ /** Load a bundled solution manifest from disk. */
31
+ export declare function loadSolutionManifest(solutionId: string): SolutionManifest;
32
+ /** Resolve CLI smoke defaults from a bundled solution manifest. */
33
+ export declare function getSolutionSmokeDefaults(solutionId: string): SolutionSmokeDefaults;
34
+ export {};
@@ -0,0 +1,129 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const KNOWN_SOLUTION_IDS = ["travel", "shopping", "saas", "aws"];
5
+ const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
6
+ function solutionCandidatePaths(solutionId) {
7
+ const fileName = `${solutionId}.json`;
8
+ const roots = [
9
+ join(MODULE_DIR, "../../solutions"),
10
+ join(MODULE_DIR, "../../../solutions"),
11
+ join(MODULE_DIR, "../../../../kit/solutions"),
12
+ ];
13
+ return roots.map((root) => join(root, fileName));
14
+ }
15
+ function parseSolutionManifest(raw, sourceLabel) {
16
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
17
+ throw new Error(`invalid solution manifest at ${sourceLabel}`);
18
+ }
19
+ const record = raw;
20
+ const smoke = record.smoke;
21
+ if (!smoke || typeof smoke !== "object" || Array.isArray(smoke)) {
22
+ throw new Error(`solution manifest ${sourceLabel} missing smoke block`);
23
+ }
24
+ const smokeRecord = smoke;
25
+ const resultBody = smokeRecord.result_body;
26
+ if (!resultBody || typeof resultBody !== "object" || Array.isArray(resultBody)) {
27
+ throw new Error(`solution manifest ${sourceLabel} missing smoke.result_body object`);
28
+ }
29
+ const evidencePreset = smokeRecord.evidence_preset;
30
+ if (typeof evidencePreset !== "string" || !evidencePreset.trim()) {
31
+ throw new Error(`solution manifest ${sourceLabel} missing smoke.evidence_preset`);
32
+ }
33
+ const policyDefault = record.policy_default;
34
+ if (!policyDefault || typeof policyDefault !== "object" || Array.isArray(policyDefault)) {
35
+ throw new Error(`solution manifest ${sourceLabel} missing policy_default block`);
36
+ }
37
+ const policyDefaultRecord = policyDefault;
38
+ const domain = policyDefaultRecord.domain;
39
+ const guardrails = policyDefaultRecord.guardrails;
40
+ if (typeof domain !== "string" || !domain.trim()) {
41
+ throw new Error(`solution manifest ${sourceLabel} missing policy_default.domain`);
42
+ }
43
+ if (!Array.isArray(guardrails) || guardrails.some((entry) => typeof entry !== "string")) {
44
+ throw new Error(`solution manifest ${sourceLabel} missing policy_default.guardrails`);
45
+ }
46
+ const id = record.id;
47
+ const title = record.title;
48
+ const primaryOperation = record.primary_operation;
49
+ const completionPreset = record.completion_preset;
50
+ if (typeof id !== "string" || !id.trim()) {
51
+ throw new Error(`solution manifest ${sourceLabel} missing id`);
52
+ }
53
+ if (typeof title !== "string" || !title.trim()) {
54
+ throw new Error(`solution manifest ${sourceLabel} missing title`);
55
+ }
56
+ if (typeof primaryOperation !== "string" || !primaryOperation.trim()) {
57
+ throw new Error(`solution manifest ${sourceLabel} missing primary_operation`);
58
+ }
59
+ if (typeof completionPreset !== "string" || !completionPreset.trim()) {
60
+ throw new Error(`solution manifest ${sourceLabel} missing completion_preset`);
61
+ }
62
+ const vendorPack = record.vendor_pack;
63
+ if (vendorPack !== undefined && (typeof vendorPack !== "string" || !vendorPack.trim())) {
64
+ throw new Error(`solution manifest ${sourceLabel} has invalid vendor_pack`);
65
+ }
66
+ return {
67
+ id: id.trim(),
68
+ title: title.trim(),
69
+ policy_default: {
70
+ domain: domain.trim(),
71
+ guardrails: guardrails.map((entry) => entry.trim()),
72
+ },
73
+ primary_operation: primaryOperation.trim(),
74
+ completion_preset: completionPreset.trim(),
75
+ ...(vendorPack ? { vendor_pack: vendorPack.trim() } : {}),
76
+ smoke: {
77
+ result_body: resultBody,
78
+ evidence_preset: evidencePreset.trim(),
79
+ },
80
+ };
81
+ }
82
+ /** True when `value` is a bundled solution id (travel, shopping, saas, aws). */
83
+ export function isKnownSolutionId(value) {
84
+ return KNOWN_SOLUTION_IDS.includes(value.trim());
85
+ }
86
+ /** List bundled solution ids shipped with Paybond Kit. */
87
+ export function listSolutionIds() {
88
+ return [...KNOWN_SOLUTION_IDS];
89
+ }
90
+ /** Load a bundled solution manifest from disk. */
91
+ export function loadSolutionManifest(solutionId) {
92
+ const trimmed = solutionId.trim();
93
+ if (!isKnownSolutionId(trimmed)) {
94
+ throw new Error(`unknown solution: ${trimmed}`);
95
+ }
96
+ let lastError;
97
+ for (const candidate of solutionCandidatePaths(trimmed)) {
98
+ try {
99
+ const raw = JSON.parse(readFileSync(candidate, "utf8"));
100
+ const manifest = parseSolutionManifest(raw, candidate);
101
+ if (manifest.id !== trimmed) {
102
+ throw new Error(`manifest id "${manifest.id}" does not match file name "${trimmed}"`);
103
+ }
104
+ return manifest;
105
+ }
106
+ catch (err) {
107
+ lastError = err;
108
+ }
109
+ }
110
+ throw new Error(`solution manifest not found for: ${trimmed} (${solutionCandidatePaths(trimmed).join(", ")}): ${lastError instanceof Error ? lastError.message : String(lastError)}`);
111
+ }
112
+ function resolveRequestedSpendCents(resultBody) {
113
+ const costCents = resultBody.cost_cents;
114
+ if (typeof costCents === "number" && Number.isFinite(costCents) && costCents >= 0) {
115
+ return Math.trunc(costCents);
116
+ }
117
+ throw new Error("solution smoke.result_body must include non-negative cost_cents");
118
+ }
119
+ /** Resolve CLI smoke defaults from a bundled solution manifest. */
120
+ export function getSolutionSmokeDefaults(solutionId) {
121
+ const manifest = loadSolutionManifest(solutionId);
122
+ const resultBody = { ...manifest.smoke.result_body };
123
+ return {
124
+ operation: manifest.primary_operation,
125
+ requestedSpendCents: resolveRequestedSpendCents(resultBody),
126
+ evidencePreset: manifest.smoke.evidence_preset,
127
+ resultBody,
128
+ };
129
+ }
@@ -0,0 +1,2 @@
1
+ export { getSolutionSmokeDefaults, isKnownSolutionId, listSolutionIds, loadSolutionManifest, type SolutionId, type SolutionManifest, type SolutionPolicyDefault, type SolutionSmokeDefaults, type SolutionSmokeManifest, } from "./catalog.js";
2
+ export { paybondSolutionPresets, type PaybondSolutionBundle, type PaybondSolutionPresets, } from "./api.js";
@@ -0,0 +1,2 @@
1
+ export { getSolutionSmokeDefaults, isKnownSolutionId, listSolutionIds, loadSolutionManifest, } from "./catalog.js";
2
+ export { paybondSolutionPresets, } from "./api.js";
@@ -0,0 +1,54 @@
1
+ import type { PolicyPresetId } from "./policy/presets.js";
2
+ export type TemplateId = "travel-agent" | "vercel-shopping-agent" | "openai-agents-demo" | "openai-shopping-agent" | "claude-agents-demo" | "mcp-coding-agent" | "procurement-agent" | "invoice-agent" | "aws-operator";
3
+ export type TemplateManifestEntry = {
4
+ id: TemplateId;
5
+ repo: string;
6
+ title: string;
7
+ language: "typescript" | "python";
8
+ framework: string;
9
+ preset: PolicyPresetId | null;
10
+ primary_operation: string;
11
+ requested_spend_cents: number;
12
+ evidence_preset: string;
13
+ smoke_result_body: Record<string, unknown>;
14
+ };
15
+ type TemplateManifest = {
16
+ version: number;
17
+ templates: TemplateManifestEntry[];
18
+ };
19
+ export type TemplateFramework = "generic" | "langgraph" | "vercel-ai" | "openai-agents" | "claude-agents" | "mcp";
20
+ /** Normalize CLI `--framework` values to bundled template framework ids. */
21
+ export declare function normalizeTemplateFramework(raw: string): TemplateFramework;
22
+ /** Load the bundled starter-template manifest shipped with @paybond/kit. */
23
+ export declare function loadTemplateManifest(): Promise<TemplateManifest>;
24
+ /** Normalize template id or repo slug to a canonical template id. */
25
+ export declare function normalizeTemplateId(raw: string): TemplateId;
26
+ /** List bundled starter templates for CLI and docs. */
27
+ export declare function listTemplateEntries(): Promise<TemplateManifestEntry[]>;
28
+ export declare function resolveTemplateEntry(templateId: TemplateId): Promise<TemplateManifestEntry>;
29
+ /** Resolve a bundled template and optionally validate `--framework`. */
30
+ export declare function resolveTemplateForInit(input: {
31
+ templateId: TemplateId;
32
+ framework?: string;
33
+ }): Promise<TemplateManifestEntry>;
34
+ export type CopyTemplateOptions = {
35
+ cwd: string;
36
+ templateId: TemplateId;
37
+ framework?: string;
38
+ force?: boolean;
39
+ writeStdout?: (line: string) => void;
40
+ };
41
+ export type CopyTemplateResult = {
42
+ template_id: TemplateId;
43
+ repo: string;
44
+ title: string;
45
+ language: TemplateManifestEntry["language"];
46
+ framework: string;
47
+ preset: PolicyPresetId | null;
48
+ files: string[];
49
+ smoke_command: string;
50
+ };
51
+ /** Copy a bundled starter template tree into the target directory. */
52
+ export declare function copyTemplateToDirectory(options: CopyTemplateOptions): Promise<CopyTemplateResult>;
53
+ export declare function templateInitUsage(): string;
54
+ export {};
@@ -0,0 +1,203 @@
1
+ import { access, cp, readFile, readdir } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const TEMPLATE_FRAMEWORK_ALIASES = {
6
+ generic: "generic",
7
+ langgraph: "langgraph",
8
+ "vercel-ai": "vercel-ai",
9
+ vercel: "vercel-ai",
10
+ openai: "openai-agents",
11
+ "openai-agents": "openai-agents",
12
+ claude: "claude-agents",
13
+ "claude-agents": "claude-agents",
14
+ mcp: "mcp",
15
+ };
16
+ /** Normalize CLI `--framework` values to bundled template framework ids. */
17
+ export function normalizeTemplateFramework(raw) {
18
+ const normalized = TEMPLATE_FRAMEWORK_ALIASES[raw.trim().toLowerCase()];
19
+ if (!normalized) {
20
+ throw new Error(`invalid --framework for template init: ${raw}`);
21
+ }
22
+ return normalized;
23
+ }
24
+ function frameworkForEntry(entry) {
25
+ return normalizeTemplateFramework(entry.framework);
26
+ }
27
+ const TEMPLATE_ALIASES = {
28
+ "travel-agent": "travel-agent",
29
+ "paybond-travel-agent": "travel-agent",
30
+ "vercel-shopping-agent": "vercel-shopping-agent",
31
+ "paybond-vercel-shopping-agent": "vercel-shopping-agent",
32
+ "openai-agents-demo": "openai-agents-demo",
33
+ "paybond-openai-agents-demo": "openai-agents-demo",
34
+ "openai-shopping-agent": "openai-shopping-agent",
35
+ "claude-agents-demo": "claude-agents-demo",
36
+ "paybond-claude-agents-demo": "claude-agents-demo",
37
+ "mcp-coding-agent": "mcp-coding-agent",
38
+ "paybond-mcp-coding-agent": "mcp-coding-agent",
39
+ "procurement-agent": "procurement-agent",
40
+ "paybond-procurement-agent": "procurement-agent",
41
+ "invoice-agent": "invoice-agent",
42
+ "paybond-invoice-agent": "invoice-agent",
43
+ "aws-operator": "aws-operator",
44
+ "paybond-aws-operator": "aws-operator",
45
+ };
46
+ function moduleDir() {
47
+ return dirname(fileURLToPath(import.meta.url));
48
+ }
49
+ function resolveTemplatesRoots() {
50
+ const dir = moduleDir();
51
+ return [
52
+ join(dir, "../templates"),
53
+ join(dir, "../../templates"),
54
+ join(dir, "../../../kit/ts/templates"),
55
+ ];
56
+ }
57
+ async function firstExistingDir(candidates) {
58
+ for (const candidate of candidates) {
59
+ try {
60
+ await access(candidate, constants.F_OK);
61
+ return candidate;
62
+ }
63
+ catch {
64
+ // try next
65
+ }
66
+ }
67
+ throw new Error("bundled Paybond templates directory not found");
68
+ }
69
+ let cachedManifest = null;
70
+ /** Load the bundled starter-template manifest shipped with @paybond/kit. */
71
+ export async function loadTemplateManifest() {
72
+ if (cachedManifest) {
73
+ return cachedManifest;
74
+ }
75
+ const root = await firstExistingDir(resolveTemplatesRoots());
76
+ const raw = await readFile(join(root, "manifest.json"), "utf8");
77
+ cachedManifest = JSON.parse(raw);
78
+ return cachedManifest;
79
+ }
80
+ /** Normalize template id or repo slug to a canonical template id. */
81
+ export function normalizeTemplateId(raw) {
82
+ const normalized = TEMPLATE_ALIASES[raw.trim().toLowerCase()];
83
+ if (!normalized) {
84
+ throw new Error(`invalid --template: ${raw}`);
85
+ }
86
+ return normalized;
87
+ }
88
+ /** List bundled starter templates for CLI and docs. */
89
+ export async function listTemplateEntries() {
90
+ const manifest = await loadTemplateManifest();
91
+ return [...manifest.templates];
92
+ }
93
+ export async function resolveTemplateEntry(templateId) {
94
+ const manifest = await loadTemplateManifest();
95
+ const entry = manifest.templates.find((candidate) => candidate.id === templateId);
96
+ if (!entry) {
97
+ throw new Error(`unknown template: ${templateId}`);
98
+ }
99
+ return entry;
100
+ }
101
+ /** Resolve a bundled template and optionally validate `--framework`. */
102
+ export async function resolveTemplateForInit(input) {
103
+ const entry = await resolveTemplateEntry(input.templateId);
104
+ if (input.framework) {
105
+ const normalized = normalizeTemplateFramework(input.framework);
106
+ if (frameworkForEntry(entry) !== normalized) {
107
+ throw new Error(`template ${entry.id} uses framework ${entry.framework}; --framework ${input.framework} does not match`);
108
+ }
109
+ }
110
+ return entry;
111
+ }
112
+ function smokeCommandForEntry(entry) {
113
+ const resultBody = JSON.stringify(entry.smoke_result_body);
114
+ return [
115
+ "paybond agent sandbox smoke",
116
+ "--policy-file paybond.policy.yaml",
117
+ `--operation ${entry.primary_operation}`,
118
+ `--requested-spend-cents ${entry.requested_spend_cents}`,
119
+ `--evidence-preset ${entry.evidence_preset}`,
120
+ `--result-body '${resultBody}'`,
121
+ "--format json",
122
+ ].join(" ");
123
+ }
124
+ async function pathExists(path) {
125
+ try {
126
+ await access(path, constants.F_OK);
127
+ return true;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
133
+ /** Copy a bundled starter template tree into the target directory. */
134
+ export async function copyTemplateToDirectory(options) {
135
+ const entry = await resolveTemplateForInit({
136
+ templateId: options.templateId,
137
+ framework: options.framework,
138
+ });
139
+ const templatesRoot = await firstExistingDir(resolveTemplatesRoots());
140
+ const sourceDir = join(templatesRoot, entry.repo);
141
+ try {
142
+ await access(sourceDir, constants.F_OK);
143
+ }
144
+ catch {
145
+ throw new Error(`template source missing: ${entry.repo}`);
146
+ }
147
+ const writeStdout = options.writeStdout;
148
+ const copied = [];
149
+ const entries = await readdir(sourceDir, { withFileTypes: true });
150
+ for (const dirent of entries) {
151
+ const relativePath = dirent.name;
152
+ const sourcePath = join(sourceDir, relativePath);
153
+ const targetPath = join(options.cwd, relativePath);
154
+ if (await pathExists(targetPath) && !options.force) {
155
+ throw new Error(`${relativePath} already exists (pass --force to overwrite)`);
156
+ }
157
+ await cp(sourcePath, targetPath, {
158
+ recursive: true,
159
+ force: options.force ?? false,
160
+ errorOnExist: !options.force,
161
+ });
162
+ copied.push(relativePath);
163
+ writeStdout?.(`Created ${relativePath}`);
164
+ }
165
+ const smokeCommand = smokeCommandForEntry(entry);
166
+ writeStdout?.("");
167
+ writeStdout?.("Ready to run:");
168
+ writeStdout?.(" paybond login");
169
+ if (entry.language === "python") {
170
+ writeStdout?.(" pip install -r requirements.txt");
171
+ }
172
+ else {
173
+ writeStdout?.(" npm install");
174
+ }
175
+ writeStdout?.(` ${entry.language === "typescript" ? "npm run smoke" : smokeCommand}`);
176
+ return {
177
+ template_id: entry.id,
178
+ repo: entry.repo,
179
+ title: entry.title,
180
+ language: entry.language,
181
+ framework: entry.framework,
182
+ preset: entry.preset,
183
+ files: copied,
184
+ smoke_command: smokeCommand,
185
+ };
186
+ }
187
+ export function templateInitUsage() {
188
+ return [
189
+ "Usage: paybond init [--template <id>|--repo <slug>] [--framework <name>] [--force]",
190
+ " paybond init [--solution ...] [--framework ...] (wizard scaffold)",
191
+ "",
192
+ "Templates:",
193
+ " travel-agent, vercel-shopping-agent, openai-agents-demo, openai-shopping-agent,",
194
+ " claude-agents-demo, mcp-coding-agent, procurement-agent, invoice-agent, aws-operator",
195
+ "",
196
+ "Frameworks (with --template): generic|langgraph|vercel-ai|openai|openai-agents|claude-agents|mcp",
197
+ "",
198
+ "Examples:",
199
+ " paybond init --template travel-agent --framework langgraph",
200
+ " paybond init --template paybond-vercel-shopping-agent --force",
201
+ " paybond init --solution travel --framework langgraph --non-interactive",
202
+ ].join("\n");
203
+ }
@@ -0,0 +1,15 @@
1
+ import type { ToolSet } from "ai";
2
+ import type { PaybondAgentRun } from "../agent/run.js";
3
+ import { paybondVercelToolApproval, type PaybondVercelToolApprovalOptions } from "./tool-approval.js";
4
+ /** Vercel AI SDK runner config: guarded tools plus centralized `toolApproval`. */
5
+ export type PaybondVercelAgentConfig<TOOLS extends ToolSet = ToolSet> = {
6
+ tools: TOOLS;
7
+ toolApproval: ReturnType<typeof paybondVercelToolApproval<TOOLS>>;
8
+ };
9
+ export type PaybondVercelAgentConfigOptions = PaybondVercelToolApprovalOptions;
10
+ /**
11
+ * Framework runner helper for Vercel AI SDK `generateText` / `streamText`.
12
+ *
13
+ * Returns guarded `tools` and a `toolApproval` bridge for Harbor pre-checks.
14
+ */
15
+ export declare function createPaybondVercelAgentConfig<TOOLS extends ToolSet>(run: PaybondAgentRun, tools: TOOLS, options?: PaybondVercelAgentConfigOptions): PaybondVercelAgentConfig<TOOLS>;
@@ -0,0 +1,13 @@
1
+ import { paybondVercelToolApproval, } from "./tool-approval.js";
2
+ import { paybondVercelWrapTools } from "./wrap-tools.js";
3
+ /**
4
+ * Framework runner helper for Vercel AI SDK `generateText` / `streamText`.
5
+ *
6
+ * Returns guarded `tools` and a `toolApproval` bridge for Harbor pre-checks.
7
+ */
8
+ export function createPaybondVercelAgentConfig(run, tools, options) {
9
+ return {
10
+ tools: paybondVercelWrapTools(run, tools),
11
+ toolApproval: paybondVercelToolApproval(run, options),
12
+ };
13
+ }
@@ -0,0 +1,4 @@
1
+ export { createPaybondVercelAgentConfig, type PaybondVercelAgentConfig, type PaybondVercelAgentConfigOptions, } from "./config.js";
2
+ export { mapPaybondDecisionToVercelToolApproval, paybondVercelToolApproval, type PaybondVercelToolApprovalOptions, } from "./tool-approval.js";
3
+ export { paybondVercelWrapTools } from "./wrap-tools.js";
4
+ export { runVercelAiSandboxDemo, type RunVercelAiSandboxDemoInput, type RunVercelAiSandboxDemoResult, } from "./sandbox-demo.js";