@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
@@ -1,9 +1,19 @@
1
1
  export const MCP_TOOL_POLICY_ENV = "PAYBOND_MCP_TOOL_POLICY";
2
2
  export const MCP_TOOL_ALLOWLIST_ENV = "PAYBOND_MCP_TOOL_ALLOWLIST";
3
+ export const DEFAULT_MCP_TOOL_POLICY = "spend-write";
3
4
  export const LIVE_MONEY_TOOL_NAMES = new Set([
4
5
  "paybond_fund_intent",
5
6
  "paybond_confirm_settlement",
6
7
  ]);
8
+ export function defaultMcpToolPolicyConfig() {
9
+ return { policy: DEFAULT_MCP_TOOL_POLICY, allowlist: [] };
10
+ }
11
+ export function resolveMcpToolPolicy(config) {
12
+ if (config.policy !== null) {
13
+ return config;
14
+ }
15
+ return defaultMcpToolPolicyConfig();
16
+ }
7
17
  export function parseMcpToolPolicy(raw) {
8
18
  const value = (raw ?? "").trim().toLowerCase();
9
19
  if (!value) {
@@ -38,14 +48,12 @@ export function mergeMcpToolPolicy(policy, allowlist) {
38
48
  return { policy: policy.policy, allowlist: [...mergedAllowlist] };
39
49
  }
40
50
  export function mcpToolPolicyEnv(config) {
41
- if (config.policy === null) {
42
- return {};
43
- }
51
+ const resolved = resolveMcpToolPolicy(config);
44
52
  const env = {
45
- [MCP_TOOL_POLICY_ENV]: config.policy,
53
+ [MCP_TOOL_POLICY_ENV]: resolved.policy ?? DEFAULT_MCP_TOOL_POLICY,
46
54
  };
47
- if (config.policy === "allowlist") {
48
- env[MCP_TOOL_ALLOWLIST_ENV] = config.allowlist.join(",");
55
+ if (resolved.policy === "allowlist") {
56
+ env[MCP_TOOL_ALLOWLIST_ENV] = resolved.allowlist.join(",");
49
57
  }
50
58
  return env;
51
59
  }
@@ -56,18 +64,16 @@ export function toolAnnotationsFlags(annotations) {
56
64
  };
57
65
  }
58
66
  export function toolAllowedByPolicy(name, annotations, config) {
59
- if (config.policy === null) {
60
- return true;
61
- }
67
+ const resolved = resolveMcpToolPolicy(config);
62
68
  const { readOnly, destructive } = toolAnnotationsFlags(annotations);
63
- if (config.policy === "readonly") {
69
+ if (resolved.policy === "readonly") {
64
70
  return readOnly;
65
71
  }
66
- if (config.policy === "spend-write") {
72
+ if (resolved.policy === "spend-write") {
67
73
  return !isLiveMoneyTool(name, annotations);
68
74
  }
69
- if (config.policy === "allowlist") {
70
- return new Set(config.allowlist).has(name);
75
+ if (resolved.policy === "allowlist") {
76
+ return new Set(resolved.allowlist).has(name);
71
77
  }
72
78
  return true;
73
79
  }
@@ -2,7 +2,7 @@ import { existsSync } from "node:fs";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { defaultMcpServerCommand, planMcpInstall, } from "./mcp-install.js";
5
- import { MCP_TOOL_ALLOWLIST_ENV, MCP_TOOL_POLICY_ENV, mergeMcpToolPolicy, parseMcpToolAllowlist, parseMcpToolPolicy, } from "./mcp-policy.js";
5
+ import { MCP_TOOL_ALLOWLIST_ENV, MCP_TOOL_POLICY_ENV, mergeMcpToolPolicy, parseMcpToolAllowlist, parseMcpToolPolicy, resolveMcpToolPolicy, } from "./mcp-policy.js";
6
6
  function validationMessage(ok, issues) {
7
7
  if (ok) {
8
8
  return "MCP host config is valid";
@@ -99,16 +99,14 @@ function validateEntry(entry, cwd, expectedEnvFile) {
99
99
  let toolPolicy;
100
100
  const rawPolicy = entry.env[MCP_TOOL_POLICY_ENV]?.trim() ?? "";
101
101
  const rawAllowlist = entry.env[MCP_TOOL_ALLOWLIST_ENV]?.trim() ?? "";
102
- if (rawPolicy || rawAllowlist) {
103
- try {
104
- toolPolicy = mergeMcpToolPolicy(parseMcpToolPolicy(rawPolicy || undefined), parseMcpToolAllowlist(rawAllowlist || undefined));
105
- }
106
- catch (err) {
107
- issues.push({
108
- field: "tool_policy",
109
- message: err instanceof Error ? err.message : String(err),
110
- });
111
- }
102
+ try {
103
+ toolPolicy = resolveMcpToolPolicy(mergeMcpToolPolicy(parseMcpToolPolicy(rawPolicy || undefined), parseMcpToolAllowlist(rawAllowlist || undefined)));
104
+ }
105
+ catch (err) {
106
+ issues.push({
107
+ field: "tool_policy",
108
+ message: err instanceof Error ? err.message : String(err),
109
+ });
112
110
  }
113
111
  return { issues, toolPolicy };
114
112
  }
@@ -1,3 +1,20 @@
1
+ const SENSITIVE_SEED_EXACT_FIELDS = new Set(["payee_signing_seed", "agent_recognition_signing_seed"]);
2
+ function isSensitiveSeedKey(key) {
3
+ const lowered = key.toLowerCase();
4
+ if (SENSITIVE_SEED_EXACT_FIELDS.has(lowered)) {
5
+ return true;
6
+ }
7
+ return lowered.endsWith("_seed") || lowered.endsWith("_seed_hex");
8
+ }
9
+ function hasRedactableScalarContent(value) {
10
+ if (typeof value === "string") {
11
+ return value.trim().length > 0;
12
+ }
13
+ if (value instanceof Uint8Array) {
14
+ return value.length > 0;
15
+ }
16
+ return false;
17
+ }
1
18
  export function maskApiKey(rawKey) {
2
19
  const trimmed = rawKey.trim();
3
20
  const parts = trimmed.split("_");
@@ -16,23 +33,27 @@ export function redactSensitiveFields(value) {
16
33
  if (value && typeof value === "object") {
17
34
  const out = {};
18
35
  for (const [key, child] of Object.entries(value)) {
19
- if (child && typeof child === "object") {
20
- out[key] = redactSensitiveFields(child);
21
- continue;
22
- }
23
36
  const lowered = key.toLowerCase();
24
37
  if (lowered === "capability_token" ||
25
38
  lowered === "access_token" ||
26
39
  lowered === "refresh_token" ||
27
40
  (lowered.endsWith("_token") && lowered !== "token_type")) {
28
- out[key] = typeof child === "string" && child.trim() ? "[redacted]" : child;
41
+ out[key] = hasRedactableScalarContent(child) ? "[redacted]" : child;
42
+ continue;
29
43
  }
30
- else if (lowered === "api_key" || lowered.endsWith("_api_key")) {
44
+ if (lowered === "api_key" || lowered.endsWith("_api_key")) {
31
45
  out[key] = typeof child === "string" ? maskApiKey(child) : child;
46
+ continue;
32
47
  }
33
- else {
34
- out[key] = child;
48
+ if (isSensitiveSeedKey(key)) {
49
+ out[key] = hasRedactableScalarContent(child) ? "[redacted]" : child;
50
+ continue;
51
+ }
52
+ if (child && typeof child === "object") {
53
+ out[key] = redactSensitiveFields(child);
54
+ continue;
35
55
  }
56
+ out[key] = child;
36
57
  }
37
58
  return out;
38
59
  }
@@ -1,6 +1,9 @@
1
1
  import { commandPath, createContext } from "./context.js";
2
2
  import { handleA2a, handleAuditExports, handleMandates, handleReceipts, handleSignal, } from "./commands/discovery.js";
3
- import { handleConfig, handleDoctor, handleDiagnose, handleInitGuardrail, handleLogin, handleMcpInstall, handleMcpServe, handleMcpTools, handleMcpVerifyConfig, handleVersion, handleWhoami, } from "./commands/setup.js";
3
+ import { handleConfig, handleDoctor, handleDiagnose, handleInitCompletion, handleInitAgentMiddleware, handleInitGuardrail, handleInitWizard, handleLogin, handleMcpInstall, handleMcpServe, handleMcpTools, handleMcpVerifyConfig, handleVersion, handleWhoami, } from "./commands/setup.js";
4
+ import { handlePolicyExtend, handlePolicyImportMcpReceipt, handlePolicyImportX402Receipt, handlePolicyInit, handlePolicyInitOrg, handlePolicyPresetsList, handlePolicyPresetsShow, handlePolicyPreview, handlePolicyTemplates, handlePolicyValidateEvidence, handlePolicyValidateTools, } from "./commands/policy.js";
5
+ import { handleAgent } from "./commands/agent.js";
6
+ import { handleDev } from "./commands/dev.js";
4
7
  import { handleGuardrails, handleIntents, handleKeys, handleSpendAuthorize, } from "./commands/workflows.js";
5
8
  import { failureEnvelope, prepareCommandOutput, successEnvelope, writeEnvelope, writeTableLines } from "./envelope.js";
6
9
  import { defaultGlobalOptions, parseCliArgv } from "./globals.js";
@@ -147,6 +150,18 @@ export async function runCli(argv, deps = {}) {
147
150
  canonical = "init guardrail";
148
151
  result = await handleInitGuardrail(ctx, command.slice(2));
149
152
  }
153
+ else if (head === "init" && second === "agent-middleware") {
154
+ canonical = "init agent-middleware";
155
+ result = await handleInitAgentMiddleware(ctx, command.slice(2));
156
+ }
157
+ else if (head === "init" && second === "completion") {
158
+ canonical = "init completion";
159
+ result = await handleInitCompletion(ctx, command.slice(2));
160
+ }
161
+ else if (head === "init") {
162
+ canonical = "init";
163
+ result = await handleInitWizard(ctx, command.slice(1));
164
+ }
150
165
  else if (head === "mcp" && second === "serve") {
151
166
  canonical = "mcp serve";
152
167
  result = await handleMcpServe(ctx, command.slice(2));
@@ -167,6 +182,10 @@ export async function runCli(argv, deps = {}) {
167
182
  canonical = "doctor";
168
183
  result = await handleDoctor(ctx, command.slice(1));
169
184
  }
185
+ else if (head === "dev" && second) {
186
+ canonical = commandPath(["dev", second]);
187
+ result = await handleDev(ctx, second, tail);
188
+ }
170
189
  else if (head === "version") {
171
190
  canonical = "version";
172
191
  result = await handleVersion(ctx, command.slice(1));
@@ -219,6 +238,54 @@ export async function runCli(argv, deps = {}) {
219
238
  canonical = commandPath(["audit", "exports", third]);
220
239
  result = await handleAuditExports(ctx, third, command.slice(3));
221
240
  }
241
+ else if (head === "policy" && second === "presets" && third === "list") {
242
+ canonical = "policy presets list";
243
+ result = await handlePolicyPresetsList(ctx, command.slice(3));
244
+ }
245
+ else if (head === "policy" && second === "presets" && third === "show") {
246
+ canonical = "policy presets show";
247
+ result = await handlePolicyPresetsShow(ctx, command.slice(3));
248
+ }
249
+ else if (head === "policy" && second === "templates") {
250
+ canonical = "policy templates";
251
+ result = await handlePolicyTemplates(ctx, command.slice(2));
252
+ }
253
+ else if (head === "policy" && second === "preview") {
254
+ canonical = "policy preview";
255
+ result = await handlePolicyPreview(ctx, command.slice(2));
256
+ }
257
+ else if (head === "policy" && second === "import-mcp-receipt") {
258
+ canonical = "policy import-mcp-receipt";
259
+ result = await handlePolicyImportMcpReceipt(ctx, command.slice(2));
260
+ }
261
+ else if (head === "policy" && second === "import-x402-receipt") {
262
+ canonical = "policy import-x402-receipt";
263
+ result = await handlePolicyImportX402Receipt(ctx, command.slice(2));
264
+ }
265
+ else if (head === "policy" && second === "validate-evidence") {
266
+ canonical = "policy validate-evidence";
267
+ result = await handlePolicyValidateEvidence(ctx, command.slice(2));
268
+ }
269
+ else if (head === "policy" && second === "init-org") {
270
+ canonical = "policy init-org";
271
+ result = await handlePolicyInitOrg(ctx, command.slice(2));
272
+ }
273
+ else if (head === "policy" && second === "extend") {
274
+ canonical = "policy extend";
275
+ result = await handlePolicyExtend(ctx, command.slice(2));
276
+ }
277
+ else if (head === "policy" && second === "init") {
278
+ canonical = "policy init";
279
+ result = await handlePolicyInit(ctx, command.slice(2));
280
+ }
281
+ else if (head === "policy" && second === "validate-tools") {
282
+ canonical = "policy validate-tools";
283
+ result = await handlePolicyValidateTools(ctx, command.slice(2));
284
+ }
285
+ else if (head === "agent" && second && third) {
286
+ canonical = commandPath(["agent", second, third]);
287
+ result = await handleAgent(ctx, second, third, command.slice(3));
288
+ }
222
289
  else {
223
290
  throw new CliError(formatUnknownCommandMessage(command.join(" ")), {
224
291
  category: "usage",
@@ -252,7 +319,43 @@ export async function runCli(argv, deps = {}) {
252
319
  ctx.stdout.write(`${line}\n`);
253
320
  }
254
321
  }
255
- else if (canonical !== "login" && canonical !== "mcp serve") {
322
+ else if (canonical === "agent sandbox smoke" && Array.isArray(result.data.checklist_lines)) {
323
+ writeTableLines(ctx.stdout, result.data.checklist_lines);
324
+ if (output.warnings.length) {
325
+ for (const warning of output.warnings) {
326
+ ctx.stderr.write(`${warning}\n`);
327
+ }
328
+ }
329
+ }
330
+ else if ((canonical === "dev smoke" || canonical === "dev loop") &&
331
+ Array.isArray(result.data.checklist_lines)) {
332
+ if (canonical === "dev loop" && Array.isArray(result.data.banner_lines)) {
333
+ writeTableLines(ctx.stdout, result.data.banner_lines);
334
+ }
335
+ writeTableLines(ctx.stdout, result.data.checklist_lines);
336
+ if (output.warnings.length) {
337
+ for (const warning of output.warnings) {
338
+ ctx.stderr.write(`${warning}\n`);
339
+ }
340
+ }
341
+ }
342
+ else if (canonical === "agent run trace" && Array.isArray(result.data.trace_lines)) {
343
+ writeTableLines(ctx.stdout, result.data.trace_lines);
344
+ if (output.warnings.length) {
345
+ for (const warning of output.warnings) {
346
+ ctx.stderr.write(`${warning}\n`);
347
+ }
348
+ }
349
+ }
350
+ else if (canonical === "policy presets show" && Array.isArray(result.data.yaml_lines)) {
351
+ writeTableLines(ctx.stdout, result.data.yaml_lines);
352
+ if (output.warnings.length) {
353
+ for (const warning of output.warnings) {
354
+ ctx.stderr.write(`${warning}\n`);
355
+ }
356
+ }
357
+ }
358
+ else if (canonical !== "login" && canonical !== "mcp serve" && canonical !== "dev trace") {
256
359
  writeTableLines(ctx.stdout, renderTable(canonical, result, globals));
257
360
  }
258
361
  return EXIT_SUCCESS;
@@ -0,0 +1,15 @@
1
+ import type { GlobalOptions } from "./types.js";
2
+ /** Deep links returned by `paybond agent sandbox smoke` for local trace and hosted replay. */
3
+ export type AgentSandboxSmokeDeepLinks = Readonly<{
4
+ trace_url: string;
5
+ console_url?: string;
6
+ agent_trace_url?: string;
7
+ }>;
8
+ /**
9
+ * Builds trace, console dossier, and hosted agent-trace replay URLs for sandbox smoke JSON.
10
+ */
11
+ export declare function buildAgentSandboxSmokeDeepLinks(input: {
12
+ bind: Record<string, unknown>;
13
+ }): AgentSandboxSmokeDeepLinks;
14
+ /** Inserts trace/console/replay checklist lines before the trailing Success row. */
15
+ export declare function appendSmokeDeepLinkChecklistLines(checklistLines: ReadonlyArray<string>, deepLinks: AgentSandboxSmokeDeepLinks, globals: GlobalOptions): string[];
@@ -0,0 +1,63 @@
1
+ import { devTraceUrl } from "../dev/trace-buffer.js";
2
+ import { colorize, shouldUseColor } from "./color.js";
3
+ const HARBOR_INTENT_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
4
+ const DEFAULT_LOCAL_PUBLIC_ORIGIN = "http://127.0.0.1:3000";
5
+ function stripTrailingSlashes(value) {
6
+ return value.replace(/\/+$/, "");
7
+ }
8
+ function resolvePublicOrigin() {
9
+ const configured = process.env.PAYBOND_PUBLIC_BASE_URL?.trim() ||
10
+ process.env.PAYBOND_CONSOLE_BASE_URL?.trim();
11
+ return stripTrailingSlashes(configured && configured.length > 0 ? configured : DEFAULT_LOCAL_PUBLIC_ORIGIN);
12
+ }
13
+ function resolveConsoleOrigin() {
14
+ const configured = process.env.PAYBOND_CONSOLE_BASE_URL?.trim() ||
15
+ process.env.PAYBOND_PUBLIC_BASE_URL?.trim();
16
+ return stripTrailingSlashes(configured && configured.length > 0 ? configured : DEFAULT_LOCAL_PUBLIC_ORIGIN);
17
+ }
18
+ function harborIntentId(bind) {
19
+ const raw = bind.intent_id;
20
+ if (typeof raw !== "string") {
21
+ return undefined;
22
+ }
23
+ const trimmed = raw.trim();
24
+ return HARBOR_INTENT_UUID.test(trimmed) ? trimmed : undefined;
25
+ }
26
+ /**
27
+ * Builds trace, console dossier, and hosted agent-trace replay URLs for sandbox smoke JSON.
28
+ */
29
+ export function buildAgentSandboxSmokeDeepLinks(input) {
30
+ const runId = String(input.bind.run_id ?? "smoke-1");
31
+ const links = {
32
+ trace_url: devTraceUrl(undefined, runId),
33
+ };
34
+ const intentId = harborIntentId(input.bind);
35
+ if (!intentId) {
36
+ return links;
37
+ }
38
+ const consoleOrigin = resolveConsoleOrigin();
39
+ const publicOrigin = resolvePublicOrigin();
40
+ return {
41
+ ...links,
42
+ console_url: `${consoleOrigin}/console/operations/intents/${encodeURIComponent(intentId)}`,
43
+ agent_trace_url: `${publicOrigin}/demo/agent-trace?intent=${encodeURIComponent(intentId)}`,
44
+ };
45
+ }
46
+ /** Inserts trace/console/replay checklist lines before the trailing Success row. */
47
+ export function appendSmokeDeepLinkChecklistLines(checklistLines, deepLinks, globals) {
48
+ const useColor = shouldUseColor(globals);
49
+ const mark = (line) => colorize(line, "green", useColor);
50
+ const linkLines = [
51
+ mark(`✓ Trace → ${deepLinks.trace_url}`),
52
+ ...(deepLinks.console_url ? [mark(`✓ Console → ${deepLinks.console_url}`)] : []),
53
+ ...(deepLinks.agent_trace_url ? [mark(`✓ Replay → ${deepLinks.agent_trace_url}`)] : []),
54
+ ];
55
+ if (checklistLines.length === 0) {
56
+ return linkLines;
57
+ }
58
+ const last = checklistLines.at(-1);
59
+ if (last === "Success" || last === mark("Success")) {
60
+ return [...checklistLines.slice(0, -1), ...linkLines, last];
61
+ }
62
+ return [...checklistLines, ...linkLines];
63
+ }
@@ -0,0 +1,17 @@
1
+ import type { CliContext } from "./context.js";
2
+ export type CliTelemetryCommand = "dev loop" | "dev smoke";
3
+ export declare function hashCliInstallId(installId: string): string;
4
+ export declare function resolveCliInstallId(): Promise<string>;
5
+ export declare function cliTelemetryEnabled(gateway: string): Promise<boolean>;
6
+ /**
7
+ * Fire-and-forget adoption telemetry for successful local dev commands.
8
+ * Failures are swallowed so CLI workflows never depend on analytics.
9
+ */
10
+ export declare function reportCliCommandSuccess(ctx: CliContext, input: Readonly<{
11
+ commandPath: CliTelemetryCommand;
12
+ offline: boolean;
13
+ }>): Promise<void>;
14
+ export declare function scheduleCliCommandTelemetry(ctx: CliContext, input: Readonly<{
15
+ commandPath: CliTelemetryCommand;
16
+ offline: boolean;
17
+ }>): void;
@@ -0,0 +1,94 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { platform } from "node:os";
3
+ import { loadConfigFile, saveConfigFile } from "./config.js";
4
+ import { packageVersion } from "./doctor-agent.js";
5
+ import { isLocalGatewayHost } from "../gateway-url.js";
6
+ const INSTALL_ID_HASH_PREFIX = "paybond-kit-cli:";
7
+ function telemetryEnvDisabled() {
8
+ const raw = process.env.PAYBOND_TELEMETRY?.trim().toLowerCase();
9
+ return raw === "0" || raw === "false" || raw === "off" || raw === "no";
10
+ }
11
+ function telemetryEnvForced() {
12
+ const raw = process.env.PAYBOND_TELEMETRY?.trim().toLowerCase();
13
+ return raw === "1" || raw === "true" || raw === "on" || raw === "yes";
14
+ }
15
+ function isCiEnvironment() {
16
+ const ci = process.env.CI?.trim().toLowerCase();
17
+ return ci === "true" || ci === "1";
18
+ }
19
+ function isLocalGateway(gateway) {
20
+ try {
21
+ return isLocalGatewayHost(new URL(gateway).hostname);
22
+ }
23
+ catch {
24
+ return true;
25
+ }
26
+ }
27
+ export function hashCliInstallId(installId) {
28
+ return createHash("sha256").update(`${INSTALL_ID_HASH_PREFIX}${installId}`).digest("hex");
29
+ }
30
+ export async function resolveCliInstallId() {
31
+ const config = await loadConfigFile();
32
+ const existing = config.install_id?.trim();
33
+ if (existing) {
34
+ return existing;
35
+ }
36
+ const installId = randomUUID();
37
+ await saveConfigFile({ ...config, install_id: installId });
38
+ return installId;
39
+ }
40
+ export async function cliTelemetryEnabled(gateway) {
41
+ if (telemetryEnvDisabled() || isCiEnvironment()) {
42
+ return false;
43
+ }
44
+ if (telemetryEnvForced()) {
45
+ return true;
46
+ }
47
+ const config = await loadConfigFile();
48
+ if (config.telemetry === false) {
49
+ return false;
50
+ }
51
+ return !isLocalGateway(gateway);
52
+ }
53
+ /**
54
+ * Fire-and-forget adoption telemetry for successful local dev commands.
55
+ * Failures are swallowed so CLI workflows never depend on analytics.
56
+ */
57
+ export async function reportCliCommandSuccess(ctx, input) {
58
+ if (!(await cliTelemetryEnabled(ctx.globals.gateway))) {
59
+ return;
60
+ }
61
+ const installId = await resolveCliInstallId();
62
+ const body = {
63
+ command_path: input.commandPath,
64
+ success: true,
65
+ offline: input.offline,
66
+ kit_version: packageVersion(),
67
+ runtime: "node",
68
+ install_id_sha256: hashCliInstallId(installId),
69
+ os_name: platform(),
70
+ client_context: {
71
+ format: ctx.globals.format,
72
+ },
73
+ };
74
+ const url = `${ctx.globals.gateway.replace(/\/+$/, "")}/v1/public/analytics/kit-cli`;
75
+ const controller = new AbortController();
76
+ const timeout = setTimeout(() => controller.abort(), 2_000);
77
+ try {
78
+ await ctx.fetch(url, {
79
+ method: "POST",
80
+ headers: { "content-type": "application/json" },
81
+ body: JSON.stringify(body),
82
+ signal: controller.signal,
83
+ });
84
+ }
85
+ catch {
86
+ // Telemetry must never block or fail the CLI command.
87
+ }
88
+ finally {
89
+ clearTimeout(timeout);
90
+ }
91
+ }
92
+ export function scheduleCliCommandTelemetry(ctx, input) {
93
+ void reportCliCommandSuccess(ctx, input);
94
+ }
@@ -0,0 +1,2 @@
1
+ /** Generated by kit/scripts/sync-completion-catalog.mjs — do not edit. */
2
+ export declare const BUNDLED_COMPLETION_CATALOG_SHA256_HEX: "6b3fc4f2c568bd9de61e96c18b345c815a4ffea73fc1212f2e6fe601817a8483";
@@ -0,0 +1,2 @@
1
+ /** Generated by kit/scripts/sync-completion-catalog.mjs — do not edit. */
2
+ export const BUNDLED_COMPLETION_CATALOG_SHA256_HEX = "6b3fc4f2c568bd9de61e96c18b345c815a4ffea73fc1212f2e6fe601817a8483";
@@ -0,0 +1,2 @@
1
+ /** Verifies raw catalog bytes against the bundled SHA-256 digest. */
2
+ export declare function verifyBundledCompletionCatalogIntegrity(raw: Buffer | string): void;
@@ -0,0 +1,17 @@
1
+ import { createHash } from "node:crypto";
2
+ import { BUNDLED_COMPLETION_CATALOG_SHA256_HEX } from "./completion-catalog-digest.js";
3
+ const INTEGRITY_SKIP = "skip";
4
+ function integrityCheckSkipped() {
5
+ return process.env.PAYBOND_COMPLETION_CATALOG_INTEGRITY?.trim().toLowerCase() === INTEGRITY_SKIP;
6
+ }
7
+ /** Verifies raw catalog bytes against the bundled SHA-256 digest. */
8
+ export function verifyBundledCompletionCatalogIntegrity(raw) {
9
+ if (integrityCheckSkipped()) {
10
+ return;
11
+ }
12
+ const bytes = typeof raw === "string" ? Buffer.from(raw, "utf8") : raw;
13
+ const digest = createHash("sha256").update(bytes).digest("hex");
14
+ if (digest !== BUNDLED_COMPLETION_CATALOG_SHA256_HEX) {
15
+ throw new Error(`completion preset catalog integrity check failed (sha256=${digest}, expected=${BUNDLED_COMPLETION_CATALOG_SHA256_HEX})`);
16
+ }
17
+ }
@@ -0,0 +1,49 @@
1
+ export type CompletionPreset = {
2
+ preset_id: string;
3
+ title: string;
4
+ description: string;
5
+ harbor_template_id: string;
6
+ parameters: Record<string, unknown>;
7
+ evidence_schema: Record<string, unknown>;
8
+ sample_evidence: Record<string, unknown>;
9
+ sample_failing_evidence: Record<string, unknown>;
10
+ human_summary: string;
11
+ recommended_amount_cents?: number;
12
+ spend_hints?: {
13
+ approval_threshold_cents?: number;
14
+ per_tool_max_cents?: number;
15
+ };
16
+ kind?: "archetype" | "vendor_pack";
17
+ archetype_preset_id?: string;
18
+ evidence_field_map?: Record<string, string>;
19
+ vendor_evidence_schema?: Record<string, unknown>;
20
+ vendor_sample_evidence?: Record<string, unknown>;
21
+ scope?: "tool_completion" | "sandbox_smoke";
22
+ rail_hints?: string[];
23
+ forbidden_evidence_fields?: string[];
24
+ anti_patterns?: string[];
25
+ deprecated?: boolean;
26
+ superseded_by?: string;
27
+ vendor_contract?: {
28
+ provider: "stripe" | "x402" | "mcp" | "generic";
29
+ api_version: string;
30
+ contract_kind: "json_schema" | "openapi_fragment" | "mapper_version";
31
+ schema_digest_hex: string;
32
+ canonical_schema_digest_hex: string;
33
+ quality_fields: string[];
34
+ supersedes?: string;
35
+ migration_notes?: string;
36
+ };
37
+ };
38
+ export type CompletionPresetCatalog = {
39
+ version: number;
40
+ presets: CompletionPreset[];
41
+ };
42
+ export declare function loadCompletionCatalog(): CompletionPresetCatalog;
43
+ export declare function listCompletionPresetIds(): string[];
44
+ export declare function getCompletionPreset(presetId: string): CompletionPreset;
45
+ export declare function getCompletionPresetByTemplateId(templateId: string): CompletionPreset | undefined;
46
+ export declare function listCompletionPresetsByTemplateId(templateId: string): CompletionPreset[];
47
+ export declare function jsonLiteral(value: unknown, indent?: number): string;
48
+ export declare function catalogPathForTests(): string;
49
+ export declare function catalogFileUrl(): string;
@@ -0,0 +1,62 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { verifyBundledCompletionCatalogIntegrity } from "./completion-catalog-integrity.js";
5
+ const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
6
+ function catalogCandidatePaths() {
7
+ return [
8
+ join(MODULE_DIR, "../completion-presets/catalog.json"),
9
+ join(MODULE_DIR, "../../../kit/completion-presets/catalog.json"),
10
+ join(MODULE_DIR, "../../completion-presets/catalog.json"),
11
+ ];
12
+ }
13
+ let cachedCatalog;
14
+ export function loadCompletionCatalog() {
15
+ if (cachedCatalog) {
16
+ return cachedCatalog;
17
+ }
18
+ let lastError;
19
+ for (const candidate of catalogCandidatePaths()) {
20
+ try {
21
+ const raw = readFileSync(candidate, "utf8");
22
+ verifyBundledCompletionCatalogIntegrity(raw);
23
+ cachedCatalog = JSON.parse(raw);
24
+ return cachedCatalog;
25
+ }
26
+ catch (err) {
27
+ lastError = err;
28
+ }
29
+ }
30
+ throw new Error(`completion preset catalog not found (${catalogCandidatePaths().join(", ")}): ${lastError instanceof Error ? lastError.message : String(lastError)}`);
31
+ }
32
+ export function listCompletionPresetIds() {
33
+ return loadCompletionCatalog().presets.map((preset) => preset.preset_id);
34
+ }
35
+ export function getCompletionPreset(presetId) {
36
+ const preset = loadCompletionCatalog().presets.find((entry) => entry.preset_id === presetId);
37
+ if (!preset) {
38
+ throw new Error(`unknown completion preset: ${presetId}`);
39
+ }
40
+ return preset;
41
+ }
42
+ export function getCompletionPresetByTemplateId(templateId) {
43
+ const matches = loadCompletionCatalog().presets.filter((entry) => entry.harbor_template_id === templateId);
44
+ if (matches.length === 0) {
45
+ return undefined;
46
+ }
47
+ return (matches.find((entry) => entry.kind !== "vendor_pack") ??
48
+ matches.find((entry) => entry.kind === "archetype") ??
49
+ matches[0]);
50
+ }
51
+ export function listCompletionPresetsByTemplateId(templateId) {
52
+ return loadCompletionCatalog().presets.filter((entry) => entry.harbor_template_id === templateId);
53
+ }
54
+ export function jsonLiteral(value, indent = 2) {
55
+ return JSON.stringify(value, null, indent);
56
+ }
57
+ export function catalogPathForTests() {
58
+ return join(MODULE_DIR, "../completion-presets/catalog.json");
59
+ }
60
+ export function catalogFileUrl() {
61
+ return pathToFileURL(catalogPathForTests()).href;
62
+ }