@codespar/cli 0.14.0 → 0.16.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 (538) hide show
  1. package/README.md +44 -17
  2. package/dist/commands/audit-replay.js +267 -0
  3. package/dist/commands/audit-replay.js.map +1 -0
  4. package/dist/commands/init.js +28 -0
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/login.js +2 -1
  7. package/dist/commands/login.js.map +1 -1
  8. package/dist/commands/mandate-verify.js +75 -27
  9. package/dist/commands/mandate-verify.js.map +1 -1
  10. package/dist/config.js +17 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/did.js +262 -41
  13. package/dist/did.js.map +1 -1
  14. package/dist/index.js +33 -7
  15. package/dist/index.js.map +1 -1
  16. package/dist/surface.js +4 -1
  17. package/dist/surface.js.map +1 -1
  18. package/package.json +1 -1
  19. package/templates/bills-agent/README.md +8 -5
  20. package/templates/bills-agent/agents/bills-agent/.env.example +3 -3
  21. package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
  22. package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
  23. package/templates/bills-agent/agents/bills-agent/README.md +62 -22
  24. package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +1 -1
  25. package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -2
  26. package/templates/bills-agent/agents/bills-agent/package.json +14 -11
  27. package/templates/bills-agent/agents/bills-agent/src/kit.ts +193 -0
  28. package/templates/bills-agent/agents/bills-agent/test/adversarial.test.ts +8 -7
  29. package/templates/bills-agent/agents/bills-agent/test/check.test.ts +19 -2
  30. package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +72 -24
  31. package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -0
  32. package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +2 -0
  33. package/templates/bills-agent/agents/bills-agent/test/inspect.test.ts +124 -0
  34. package/templates/bills-agent/agents/bills-agent/test/provider.test.ts +25 -0
  35. package/templates/bills-agent/agents/bills-agent/test/scenarios.test.ts +10 -9
  36. package/templates/bills-agent/agents/bills-agent/tsconfig.json +0 -1
  37. package/templates/bills-agent/package.json +5 -2
  38. package/templates/bills-agent/packages/agent-core/README.md +2 -0
  39. package/templates/bills-agent/packages/agent-core/package.json +1 -1
  40. package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  41. package/templates/bills-agent/packages/agent-core/src/api/rail.ts +16 -0
  42. package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  43. package/templates/bills-agent/packages/agent-core/src/approval.ts +16 -2
  44. package/templates/bills-agent/packages/agent-core/src/bundle.ts +50 -4
  45. package/templates/bills-agent/packages/agent-core/src/channels.ts +140 -0
  46. package/templates/bills-agent/packages/agent-core/src/check.ts +90 -8
  47. package/templates/bills-agent/packages/agent-core/src/clock.ts +42 -0
  48. package/templates/bills-agent/packages/agent-core/src/engine.ts +119 -18
  49. package/templates/bills-agent/packages/agent-core/src/hash.ts +13 -0
  50. package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
  51. package/templates/bills-agent/packages/agent-core/src/manifest.ts +1 -1
  52. package/templates/bills-agent/packages/agent-core/src/rail.ts +16 -2
  53. package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  54. package/templates/bills-agent/packages/agent-core/src/state-machine.ts +3 -1
  55. package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  56. package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  57. package/templates/bills-agent/packages/agent-core/src/types.ts +28 -0
  58. package/templates/bills-agent/packages/agent-core/test/approval.test.ts +36 -2
  59. package/templates/bills-agent/packages/agent-core/test/bundle.test.ts +85 -0
  60. package/templates/bills-agent/packages/agent-core/test/clock.test.ts +25 -0
  61. package/templates/bills-agent/packages/agent-core/test/engine.test.ts +73 -1
  62. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  63. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  64. package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
  65. package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
  66. package/templates/bills-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  67. package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +51 -0
  68. package/templates/bills-agent/packages/agent-runtime/README.md +68 -0
  69. package/templates/bills-agent/packages/agent-runtime/bin.mjs +32 -0
  70. package/templates/bills-agent/packages/agent-runtime/package.json +23 -0
  71. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/adversarial.ts +36 -44
  72. package/templates/bills-agent/packages/agent-runtime/src/agent.ts +68 -0
  73. package/templates/bills-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  74. package/templates/bills-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  75. package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  76. package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  77. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  78. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  79. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  80. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  81. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  82. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  83. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  84. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  85. package/templates/bills-agent/packages/agent-runtime/src/cli.ts +98 -0
  86. package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  87. package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  88. package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  89. package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  90. package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  91. package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  92. package/templates/bills-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  93. package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  94. package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  95. package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  96. package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  97. package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  98. package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  99. package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  100. package/templates/bills-agent/packages/agent-runtime/src/index.ts +12 -0
  101. package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +797 -0
  102. package/templates/bills-agent/packages/agent-runtime/src/kit.ts +206 -0
  103. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/poll.ts +22 -11
  104. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/scenarios.ts +50 -34
  105. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/setup.ts +88 -66
  106. package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +154 -0
  107. package/templates/{collections-agent/agents/collections-agent/channels/webhook/index.ts → bills-agent/packages/agent-runtime/src/webhook.ts} +1 -1
  108. package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  109. package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  110. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  111. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  112. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  113. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  114. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  115. package/templates/bills-agent/packages/agent-runtime/tsconfig.json +9 -0
  116. package/templates/bills-agent/vitest.config.ts +1 -1
  117. package/templates/collections-agent/README.md +8 -5
  118. package/templates/collections-agent/agents/collections-agent/.env.example +14 -0
  119. package/templates/collections-agent/agents/collections-agent/AGENTS.md +6 -4
  120. package/templates/collections-agent/agents/collections-agent/CLAUDE.md +6 -4
  121. package/templates/collections-agent/agents/collections-agent/README.md +184 -16
  122. package/templates/collections-agent/agents/collections-agent/agent.yaml +3 -3
  123. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +111 -0
  124. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042.json +11 -0
  125. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1103.json +11 -0
  126. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +23 -0
  127. package/templates/collections-agent/agents/collections-agent/package.json +12 -10
  128. package/templates/collections-agent/agents/collections-agent/runbook.md +52 -1
  129. package/templates/collections-agent/agents/collections-agent/src/kit.ts +265 -0
  130. package/templates/collections-agent/agents/collections-agent/test/adversarial.test.ts +9 -8
  131. package/templates/collections-agent/agents/collections-agent/test/check.test.ts +43 -1
  132. package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +56 -18
  133. package/templates/collections-agent/agents/collections-agent/test/fixtures/agreed-1042-awaiting-payer.transcript.jsonl +4 -0
  134. package/templates/collections-agent/agents/collections-agent/test/scenarios.test.ts +11 -10
  135. package/templates/collections-agent/agents/collections-agent/test/webhook.test.ts +4 -7
  136. package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +271 -0
  137. package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +213 -0
  138. package/templates/collections-agent/agents/collections-agent/tsconfig.json +0 -1
  139. package/templates/collections-agent/package.json +3 -1
  140. package/templates/collections-agent/packages/agent-core/README.md +2 -0
  141. package/templates/collections-agent/packages/agent-core/package.json +1 -1
  142. package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  143. package/templates/collections-agent/packages/agent-core/src/api/rail.ts +16 -0
  144. package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  145. package/templates/collections-agent/packages/agent-core/src/approval.ts +16 -2
  146. package/templates/collections-agent/packages/agent-core/src/bundle.ts +50 -4
  147. package/templates/collections-agent/packages/agent-core/src/channels.ts +140 -0
  148. package/templates/collections-agent/packages/agent-core/src/check.ts +90 -8
  149. package/templates/collections-agent/packages/agent-core/src/clock.ts +42 -0
  150. package/templates/collections-agent/packages/agent-core/src/engine.ts +119 -18
  151. package/templates/collections-agent/packages/agent-core/src/hash.ts +13 -0
  152. package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
  153. package/templates/collections-agent/packages/agent-core/src/manifest.ts +1 -1
  154. package/templates/collections-agent/packages/agent-core/src/rail.ts +16 -2
  155. package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  156. package/templates/collections-agent/packages/agent-core/src/state-machine.ts +3 -1
  157. package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  158. package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  159. package/templates/collections-agent/packages/agent-core/src/types.ts +28 -0
  160. package/templates/collections-agent/packages/agent-core/test/approval.test.ts +36 -2
  161. package/templates/collections-agent/packages/agent-core/test/bundle.test.ts +85 -0
  162. package/templates/collections-agent/packages/agent-core/test/clock.test.ts +25 -0
  163. package/templates/collections-agent/packages/agent-core/test/engine.test.ts +73 -1
  164. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  165. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  166. package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
  167. package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
  168. package/templates/collections-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  169. package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +51 -0
  170. package/templates/collections-agent/packages/agent-runtime/README.md +68 -0
  171. package/templates/collections-agent/packages/agent-runtime/bin.mjs +32 -0
  172. package/templates/collections-agent/packages/agent-runtime/package.json +23 -0
  173. package/templates/collections-agent/{agents/collections-agent → packages/agent-runtime}/src/adversarial.ts +29 -50
  174. package/templates/collections-agent/packages/agent-runtime/src/agent.ts +68 -0
  175. package/templates/collections-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  176. package/templates/collections-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  177. package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  178. package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  179. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  180. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  181. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  182. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  183. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  184. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  185. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  186. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  187. package/templates/collections-agent/packages/agent-runtime/src/cli.ts +98 -0
  188. package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  189. package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  190. package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  191. package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  192. package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  193. package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  194. package/templates/collections-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  195. package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  196. package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  197. package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  198. package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  199. package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  200. package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  201. package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  202. package/templates/collections-agent/packages/agent-runtime/src/index.ts +12 -0
  203. package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +797 -0
  204. package/templates/collections-agent/packages/agent-runtime/src/kit.ts +206 -0
  205. package/templates/collections-agent/packages/agent-runtime/src/poll.ts +105 -0
  206. package/templates/{bills-agent/agents/bills-agent → collections-agent/packages/agent-runtime}/src/scenarios.ts +98 -26
  207. package/templates/collections-agent/packages/agent-runtime/src/setup.ts +229 -0
  208. package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +154 -0
  209. package/templates/collections-agent/packages/agent-runtime/src/webhook.ts +131 -0
  210. package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  211. package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  212. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  213. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  214. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  215. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  216. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  217. package/templates/collections-agent/packages/agent-runtime/tsconfig.json +9 -0
  218. package/templates/collections-agent/vitest.config.ts +1 -1
  219. package/templates/hello-agent/LICENSE +21 -0
  220. package/templates/hello-agent/README.md +23 -0
  221. package/templates/hello-agent/_gitignore +10 -0
  222. package/templates/hello-agent/agents/hello-agent/.env.example +5 -0
  223. package/templates/hello-agent/agents/hello-agent/AGENTS.md +15 -0
  224. package/templates/hello-agent/agents/hello-agent/CLAUDE.md +15 -0
  225. package/templates/hello-agent/agents/hello-agent/README.md +33 -0
  226. package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +19 -0
  227. package/templates/hello-agent/agents/hello-agent/agent.yaml +19 -0
  228. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.json +6 -0
  229. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  230. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.json +6 -0
  231. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +2 -0
  232. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.json +6 -0
  233. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.transcript.jsonl +2 -0
  234. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.json +6 -0
  235. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.transcript.jsonl +2 -0
  236. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.json +6 -0
  237. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  238. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.json +6 -0
  239. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  240. package/templates/hello-agent/agents/hello-agent/evals/adversarial/webhook-replay.json +6 -0
  241. package/templates/hello-agent/agents/hello-agent/evals/eval.yaml +7 -0
  242. package/templates/hello-agent/agents/hello-agent/guardrails.json +8 -0
  243. package/templates/hello-agent/agents/hello-agent/mandate.example.json +17 -0
  244. package/templates/hello-agent/agents/hello-agent/package.json +19 -0
  245. package/templates/hello-agent/agents/hello-agent/runbook.md +10 -0
  246. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +6 -0
  247. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +2 -0
  248. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +6 -0
  249. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  250. package/templates/hello-agent/agents/hello-agent/src/bills.ts +23 -0
  251. package/templates/hello-agent/agents/hello-agent/src/kit.ts +33 -0
  252. package/templates/hello-agent/agents/hello-agent/tools.json +11 -0
  253. package/templates/hello-agent/agents/hello-agent/tsconfig.json +9 -0
  254. package/templates/hello-agent/package.json +30 -0
  255. package/templates/hello-agent/packages/agent-core/README.md +21 -0
  256. package/templates/hello-agent/packages/agent-core/package.json +24 -0
  257. package/templates/hello-agent/packages/agent-core/src/agent.ts +125 -0
  258. package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  259. package/templates/hello-agent/packages/agent-core/src/api/client.ts +53 -0
  260. package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  261. package/templates/hello-agent/packages/agent-core/src/api/rail.ts +117 -0
  262. package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  263. package/templates/hello-agent/packages/agent-core/src/approval.ts +123 -0
  264. package/templates/hello-agent/packages/agent-core/src/bundle.ts +159 -0
  265. package/templates/hello-agent/packages/agent-core/src/channels.ts +140 -0
  266. package/templates/hello-agent/packages/agent-core/src/check.ts +253 -0
  267. package/templates/hello-agent/packages/agent-core/src/clock.ts +42 -0
  268. package/templates/hello-agent/packages/agent-core/src/engine.ts +885 -0
  269. package/templates/hello-agent/packages/agent-core/src/escalate.ts +85 -0
  270. package/templates/hello-agent/packages/agent-core/src/events.ts +40 -0
  271. package/templates/hello-agent/packages/agent-core/src/guardrails.ts +45 -0
  272. package/templates/hello-agent/packages/agent-core/src/hash.ts +62 -0
  273. package/templates/hello-agent/packages/agent-core/src/ids.ts +10 -0
  274. package/templates/hello-agent/packages/agent-core/src/index.ts +32 -0
  275. package/templates/hello-agent/packages/agent-core/src/mandate.ts +100 -0
  276. package/templates/hello-agent/packages/agent-core/src/manifest.ts +76 -0
  277. package/templates/hello-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  278. package/templates/hello-agent/packages/agent-core/src/providers/replay.ts +63 -0
  279. package/templates/hello-agent/packages/agent-core/src/providers/types.ts +39 -0
  280. package/templates/hello-agent/packages/agent-core/src/rail.ts +101 -0
  281. package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  282. package/templates/hello-agent/packages/agent-core/src/revocation.ts +30 -0
  283. package/templates/hello-agent/packages/agent-core/src/secrets.ts +30 -0
  284. package/templates/hello-agent/packages/agent-core/src/state/store.ts +307 -0
  285. package/templates/hello-agent/packages/agent-core/src/state-machine.ts +148 -0
  286. package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  287. package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  288. package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  289. package/templates/hello-agent/packages/agent-core/src/tools.ts +55 -0
  290. package/templates/hello-agent/packages/agent-core/src/types.ts +134 -0
  291. package/templates/hello-agent/packages/agent-core/test/approval.test.ts +117 -0
  292. package/templates/hello-agent/packages/agent-core/test/bundle.test.ts +85 -0
  293. package/templates/hello-agent/packages/agent-core/test/clock.test.ts +25 -0
  294. package/templates/hello-agent/packages/agent-core/test/engine.test.ts +596 -0
  295. package/templates/hello-agent/packages/agent-core/test/escalate.test.ts +42 -0
  296. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  297. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  298. package/templates/hello-agent/packages/agent-core/test/helpers.ts +139 -0
  299. package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  300. package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +45 -0
  301. package/templates/hello-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  302. package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +316 -0
  303. package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +28 -0
  304. package/templates/hello-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  305. package/templates/hello-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  306. package/templates/hello-agent/packages/agent-core/tsconfig.json +10 -0
  307. package/templates/hello-agent/packages/agent-runtime/README.md +68 -0
  308. package/templates/hello-agent/packages/agent-runtime/bin.mjs +32 -0
  309. package/templates/hello-agent/packages/agent-runtime/package.json +23 -0
  310. package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  311. package/templates/hello-agent/packages/agent-runtime/src/agent.ts +68 -0
  312. package/templates/hello-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  313. package/templates/hello-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  314. package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  315. package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  316. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  317. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  318. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  319. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  320. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  321. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  322. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  323. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  324. package/templates/hello-agent/packages/agent-runtime/src/cli.ts +98 -0
  325. package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  326. package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  327. package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  328. package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  329. package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  330. package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  331. package/templates/hello-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  332. package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  333. package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  334. package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  335. package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  336. package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  337. package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  338. package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  339. package/templates/hello-agent/packages/agent-runtime/src/index.ts +12 -0
  340. package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +797 -0
  341. package/templates/hello-agent/packages/agent-runtime/src/kit.ts +206 -0
  342. package/templates/hello-agent/packages/agent-runtime/src/poll.ts +105 -0
  343. package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  344. package/templates/hello-agent/packages/agent-runtime/src/setup.ts +229 -0
  345. package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +154 -0
  346. package/templates/hello-agent/packages/agent-runtime/src/webhook.ts +131 -0
  347. package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  348. package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  349. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  350. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  351. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  352. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  353. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  354. package/templates/hello-agent/packages/agent-runtime/tsconfig.json +9 -0
  355. package/templates/hello-agent/tsconfig.base.json +16 -0
  356. package/templates/hello-agent/vitest.config.ts +12 -0
  357. package/templates/kits.lock.json +60 -12
  358. package/templates/supplier-payments-agent/LICENSE +21 -0
  359. package/templates/supplier-payments-agent/README.md +23 -0
  360. package/templates/supplier-payments-agent/_gitignore +10 -0
  361. package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +7 -0
  362. package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +21 -0
  363. package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +21 -0
  364. package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +118 -0
  365. package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +29 -0
  366. package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +26 -0
  367. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.json +12 -0
  368. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.transcript.jsonl +3 -0
  369. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap-mandate.json +9 -0
  370. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.json +10 -0
  371. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  372. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.json +13 -0
  373. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
  374. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.json +9 -0
  375. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +3 -0
  376. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.json +15 -0
  377. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.transcript.jsonl +6 -0
  378. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.json +10 -0
  379. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  380. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.json +9 -0
  381. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  382. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/webhook-replay.json +9 -0
  383. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/eval.yaml +9 -0
  384. package/templates/supplier-payments-agent/agents/supplier-payments-agent/guardrails.json +15 -0
  385. package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +70 -0
  386. package/templates/supplier-payments-agent/agents/supplier-payments-agent/package.json +26 -0
  387. package/templates/supplier-payments-agent/agents/supplier-payments-agent/runbook.md +19 -0
  388. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.json +14 -0
  389. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +2 -0
  390. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.json +12 -0
  391. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +2 -0
  392. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.json +20 -0
  393. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +7 -0
  394. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.json +19 -0
  395. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +3 -0
  396. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.json +21 -0
  397. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +9 -0
  398. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +21 -0
  399. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +3 -0
  400. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.json +12 -0
  401. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  402. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +176 -0
  403. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +345 -0
  404. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +118 -0
  405. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +76 -0
  406. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/adversarial.test.ts +53 -0
  407. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +384 -0
  408. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/check.test.ts +109 -0
  409. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/scenarios.test.ts +81 -0
  410. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +53 -0
  411. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tsconfig.json +9 -0
  412. package/templates/supplier-payments-agent/package.json +36 -0
  413. package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -0
  414. package/templates/supplier-payments-agent/packages/agent-core/package.json +24 -0
  415. package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +125 -0
  416. package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  417. package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +53 -0
  418. package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  419. package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +117 -0
  420. package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  421. package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +123 -0
  422. package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +159 -0
  423. package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +140 -0
  424. package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +253 -0
  425. package/templates/supplier-payments-agent/packages/agent-core/src/clock.ts +42 -0
  426. package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +885 -0
  427. package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +85 -0
  428. package/templates/supplier-payments-agent/packages/agent-core/src/events.ts +40 -0
  429. package/templates/supplier-payments-agent/packages/agent-core/src/guardrails.ts +45 -0
  430. package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +62 -0
  431. package/templates/supplier-payments-agent/packages/agent-core/src/ids.ts +10 -0
  432. package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +32 -0
  433. package/templates/supplier-payments-agent/packages/agent-core/src/mandate.ts +100 -0
  434. package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +76 -0
  435. package/templates/supplier-payments-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  436. package/templates/supplier-payments-agent/packages/agent-core/src/providers/replay.ts +63 -0
  437. package/templates/supplier-payments-agent/packages/agent-core/src/providers/types.ts +39 -0
  438. package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +101 -0
  439. package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  440. package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +30 -0
  441. package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +30 -0
  442. package/templates/supplier-payments-agent/packages/agent-core/src/state/store.ts +307 -0
  443. package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +148 -0
  444. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  445. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  446. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  447. package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +55 -0
  448. package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +134 -0
  449. package/templates/supplier-payments-agent/packages/agent-core/test/approval.test.ts +117 -0
  450. package/templates/supplier-payments-agent/packages/agent-core/test/bundle.test.ts +85 -0
  451. package/templates/supplier-payments-agent/packages/agent-core/test/clock.test.ts +25 -0
  452. package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +596 -0
  453. package/templates/supplier-payments-agent/packages/agent-core/test/escalate.test.ts +42 -0
  454. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  455. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  456. package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +139 -0
  457. package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  458. package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +45 -0
  459. package/templates/supplier-payments-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  460. package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +316 -0
  461. package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +28 -0
  462. package/templates/supplier-payments-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  463. package/templates/supplier-payments-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  464. package/templates/supplier-payments-agent/packages/agent-core/tsconfig.json +10 -0
  465. package/templates/supplier-payments-agent/packages/agent-runtime/README.md +68 -0
  466. package/templates/supplier-payments-agent/packages/agent-runtime/bin.mjs +32 -0
  467. package/templates/supplier-payments-agent/packages/agent-runtime/package.json +23 -0
  468. package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  469. package/templates/supplier-payments-agent/packages/agent-runtime/src/agent.ts +68 -0
  470. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  471. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  472. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  473. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  474. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  475. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  476. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  477. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  478. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  479. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  480. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  481. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  482. package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +98 -0
  483. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  484. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  485. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  486. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  487. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  488. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  489. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  490. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  491. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  492. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  493. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  494. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  495. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  496. package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  497. package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +12 -0
  498. package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +797 -0
  499. package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +206 -0
  500. package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +105 -0
  501. package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  502. package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +229 -0
  503. package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +154 -0
  504. package/templates/supplier-payments-agent/packages/agent-runtime/src/webhook.ts +131 -0
  505. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  506. package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  507. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  508. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  509. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  510. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  511. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  512. package/templates/supplier-payments-agent/packages/agent-runtime/tsconfig.json +9 -0
  513. package/templates/supplier-payments-agent/tsconfig.base.json +16 -0
  514. package/templates/supplier-payments-agent/vitest.config.ts +12 -0
  515. package/templates/bills-agent/agents/bills-agent/channels/terminal/index.ts +0 -108
  516. package/templates/bills-agent/agents/bills-agent/src/commands/approve.ts +0 -9
  517. package/templates/bills-agent/agents/bills-agent/src/commands/check.ts +0 -13
  518. package/templates/bills-agent/agents/bills-agent/src/commands/consent.ts +0 -26
  519. package/templates/bills-agent/agents/bills-agent/src/commands/decide.ts +0 -45
  520. package/templates/bills-agent/agents/bills-agent/src/commands/deny.ts +0 -7
  521. package/templates/bills-agent/agents/bills-agent/src/commands/eval.ts +0 -37
  522. package/templates/bills-agent/agents/bills-agent/src/commands/reconcile.ts +0 -38
  523. package/templates/bills-agent/agents/bills-agent/src/commands/rerun.ts +0 -65
  524. package/templates/bills-agent/agents/bills-agent/src/commands/resume.ts +0 -30
  525. package/templates/bills-agent/agents/bills-agent/src/main.ts +0 -185
  526. package/templates/collections-agent/agents/collections-agent/channels/terminal/index.ts +0 -178
  527. package/templates/collections-agent/agents/collections-agent/src/commands/approve.ts +0 -10
  528. package/templates/collections-agent/agents/collections-agent/src/commands/check.ts +0 -13
  529. package/templates/collections-agent/agents/collections-agent/src/commands/decide.ts +0 -48
  530. package/templates/collections-agent/agents/collections-agent/src/commands/deny.ts +0 -7
  531. package/templates/collections-agent/agents/collections-agent/src/commands/eval.ts +0 -39
  532. package/templates/collections-agent/agents/collections-agent/src/commands/poll.ts +0 -35
  533. package/templates/collections-agent/agents/collections-agent/src/commands/reconcile.ts +0 -38
  534. package/templates/collections-agent/agents/collections-agent/src/commands/rerun.ts +0 -55
  535. package/templates/collections-agent/agents/collections-agent/src/commands/resume.ts +0 -30
  536. package/templates/collections-agent/agents/collections-agent/src/commands/webhook.ts +0 -36
  537. package/templates/collections-agent/agents/collections-agent/src/main.ts +0 -193
  538. package/templates/collections-agent/agents/collections-agent/src/setup.ts +0 -250
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The CodeSpar sandbox rail. With the signed envelope the consent returned
3
+ * (`mandate.canonical` + `mandate.signature`) it spends through
4
+ * `POST /v1/consumer-payments/execute`; without it, by mandate id through
5
+ * `POST /v1/consumers/mandates/{id}/spend`. Both are idempotent on
6
+ * `attempt_id`. The by-id route answered `bad_signature` on staging for a
7
+ * mandate carrying `periodic_cap` (OPEN_QUESTIONS §14), which is why the
8
+ * envelope is preferred when it exists. Receipts come back from
9
+ * `GET /v1/consumers/receipts/{id}`.
10
+ *
11
+ * The API has no `actor` field on the wire today (OPEN_QUESTIONS §2). The
12
+ * spend carries `agent_id`, which the mandate binds; the full actor is
13
+ * stamped on the local receipt copy and on every event of the bundle.
14
+ */
15
+ import type { ApiClient } from "@codespar/sdk";
16
+ import type { Mandate } from "../mandate.js";
17
+ import type { PaymentRail, RailLookup, RailOutcome, RailPayment, RailReceipt } from "../rail.js";
18
+ import type { Actor } from "../types.js";
19
+ import { describeApiError, isUncertain } from "./client.js";
20
+
21
+ /** The asymmetric seal as the API serves it, or nulls when this deployment
22
+ * does not serve one. Never throws on a shape it does not recognise: a
23
+ * receipt is evidence of a payment that already happened, and refusing to
24
+ * record it over an unexpected field would trade the record for the proof. */
25
+ function readEd25519Seal(body: unknown): { receipt_sig_ed25519: string | null; receipt_sig_kid: string | null } {
26
+ const r = body as { receipt_sig_ed25519?: unknown; receipt_sig_kid?: unknown };
27
+ const str = (v: unknown): string | null => (typeof v === "string" && v.length > 0 ? v : null);
28
+ return { receipt_sig_ed25519: str(r.receipt_sig_ed25519), receipt_sig_kid: str(r.receipt_sig_kid) };
29
+ }
30
+
31
+ export class CodeSparRail implements PaymentRail {
32
+ readonly name = "codespar" as const;
33
+
34
+ constructor(
35
+ private readonly api: ApiClient,
36
+ private readonly envelope?: Pick<Mandate, "canonical" | "signature"> | undefined,
37
+ ) {}
38
+
39
+ async pay(payment: RailPayment): Promise<RailOutcome> {
40
+ try {
41
+ const outcome =
42
+ this.envelope?.canonical && this.envelope.signature
43
+ ? await this.api.post("/v1/consumer-payments/execute", {
44
+ body: {
45
+ mandate: this.envelope.canonical,
46
+ signature: this.envelope.signature,
47
+ amount_minor: payment.amount_minor,
48
+ purpose: payment.purpose,
49
+ agent_id: payment.agent_id,
50
+ payee: payment.payee,
51
+ attempt_id: payment.attempt_id,
52
+ },
53
+ })
54
+ : await this.api.post("/v1/consumers/mandates/{id}/spend", {
55
+ path: { id: payment.mandate_id },
56
+ body: { amount_minor: payment.amount_minor, payee: payment.payee, agent_id: payment.agent_id, attempt_id: payment.attempt_id },
57
+ });
58
+ return {
59
+ status: "settled",
60
+ transaction_id: outcome.payment.transactionId,
61
+ receipt_id: outcome.receipt?.id ?? null,
62
+ money_moved: outcome.payment.moneyMoved,
63
+ sandbox: !outcome.payment.moneyMoved,
64
+ raw: outcome,
65
+ };
66
+ } catch (err) {
67
+ const failure = describeApiError(err);
68
+ if (isUncertain(failure)) return { status: "uncertain", code: failure.code, message: failure.message };
69
+ return { status: "failed", code: failure.code, message: failure.message };
70
+ }
71
+ }
72
+
73
+ /**
74
+ * There is no read route for an attempt. The documented way is to present
75
+ * the same `attempt_id` again: the lifecycle is idempotent on it and
76
+ * answers the state it reached. `psp_attempt_in_flight` means the first
77
+ * presentation is still running.
78
+ */
79
+ async lookup(_attemptId: string, payment: RailPayment): Promise<RailLookup> {
80
+ const outcome = await this.pay(payment);
81
+ if (outcome.status === "failed" && outcome.code === "psp_attempt_in_flight") return { status: "in_flight" };
82
+ return outcome;
83
+ }
84
+
85
+ async receipt(receiptId: string, actor: Actor): Promise<RailReceipt | undefined> {
86
+ try {
87
+ const r = await this.api.get("/v1/consumers/receipts/{id}", { path: { id: receiptId } });
88
+ return {
89
+ receipt_id: r.receipt_id,
90
+ state: r.state,
91
+ mandate: { id: r.mandate.id },
92
+ payment: {
93
+ amount_minor: r.payment.amount_minor,
94
+ payee: r.quote?.payee ?? null,
95
+ attempt_id: r.payment.attempt_id,
96
+ money_moved: r.payment.money_moved,
97
+ sandbox: r.payment.sandbox === true,
98
+ at: r.payment.at,
99
+ },
100
+ chain: r.chain,
101
+ receipt_sig: r.receipt_sig,
102
+ // ent#1633 landed after `@codespar/sdk@0.16.6` was generated, so the
103
+ // typed response does not carry these two yet. Read off the body
104
+ // defensively rather than pinning a new SDK for two nullable strings:
105
+ // a deployment that predates the change answers null, which is the
106
+ // same answer the columns hold and reads as `unsigned`.
107
+ ...readEd25519Seal(r),
108
+ actor,
109
+ raw: r,
110
+ };
111
+ } catch (err) {
112
+ const failure = describeApiError(err);
113
+ if (failure.status === 404) return undefined;
114
+ throw err;
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The sandbox PAYER: `POST /v1/test/charges/{chargeId}/pay` (alias
3
+ * `POST /v1/charges/{chargeId}/sandbox/pay`), test environment only. It
4
+ * plays the debtor: the charge goes through the same settlement path a
5
+ * provider `charge-in` webhook takes, `commerce.charge.paid` fans out to the
6
+ * project's triggers, and every record it leaves carries `simulated: true`
7
+ * plus `settled_against: "sandbox_fixture"`. No money moves anywhere. A
8
+ * live-environment key is refused with `sandbox_pay_not_permitted` before
9
+ * anything is read. Since `@codespar/sdk@0.16.5` the route is in the SDK's
10
+ * OpenAPI document, so this is the client's own typed call (same base URL,
11
+ * key and project header as every other call); until 0.16.4 it was a plain
12
+ * `fetch`, see docs/OPEN_QUESTIONS.md section 31c. The key is checked for
13
+ * the `csk_test_` prefix before a client exists, like every other call.
14
+ */
15
+ import { ApiClient } from "@codespar/sdk";
16
+ import type { ApiFailure } from "./client.js";
17
+ import { createCodeSparClient, describeApiError } from "./client.js";
18
+
19
+ export interface SandboxPaidState {
20
+ charge_id: string;
21
+ status: "paid";
22
+ local_status: string;
23
+ currency: string;
24
+ quoted_minor: number;
25
+ paid_minor: number;
26
+ payment: "full" | "partial" | "over";
27
+ paid_via: string;
28
+ wallet_id: string;
29
+ ledger_entry_id: string | null;
30
+ event: { id: string; type: string } | null;
31
+ simulated: boolean;
32
+ settled_against: string | null;
33
+ money_moved: false;
34
+ idempotent_replay: boolean;
35
+ }
36
+
37
+ export type SandboxPayResult = { ok: true; state: SandboxPaidState } | { ok: false; failure: ApiFailure };
38
+
39
+ /** Where the payer route lives when no client exists yet: the same three things `createCodeSparClient` takes. */
40
+ export interface SandboxPayerTarget {
41
+ apiKey: string | undefined;
42
+ baseUrl?: string | undefined;
43
+ projectId?: string | undefined;
44
+ timeoutMs?: number;
45
+ }
46
+
47
+ export async function paySandboxCharge(target: ApiClient | SandboxPayerTarget, chargeRef: string, amountMinor?: number): Promise<SandboxPayResult> {
48
+ const api = target instanceof ApiClient ? target : createCodeSparClient(target);
49
+ try {
50
+ const state = await api.post("/v1/test/charges/{chargeId}/pay", {
51
+ path: { chargeId: chargeRef },
52
+ body: amountMinor !== undefined ? { amount_minor: amountMinor } : {},
53
+ });
54
+ return { ok: true, state };
55
+ } catch (err) {
56
+ return { ok: false, failure: describeApiError(err) };
57
+ }
58
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Section 4.2: the approval artifact.
3
+ *
4
+ * STUB, on purpose: the artifact is signed with a LOCAL development key
5
+ * (`.codespar/approval.key`, generated on first use, never committed). The
6
+ * CodeSpar API does not sign approval lists; its HMAC is the mandate proof
7
+ * and the receipt seal. Until an API-side signature exists the artifact
8
+ * proves what was approved to whoever runs the agent, and to nobody else.
9
+ * See docs/OPEN_QUESTIONS.md.
10
+ */
11
+ import { randomBytes } from "node:crypto";
12
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
+ import { dirname, join } from "node:path";
14
+ import { canonicalJson, hexEqual, hmacSha256Hex, itemsHash } from "./hash.js";
15
+ import type { Execution } from "./state-machine.js";
16
+ import type { Actor, ApprovalArtifact, EscalationTrigger, ExecutionBatch } from "./types.js";
17
+ import { newId } from "./ids.js";
18
+
19
+ export const APPROVAL_KEY_ID = "local-dev-stub";
20
+ export const DEFAULT_APPROVAL_TTL_MS = 15 * 60 * 1000;
21
+
22
+ export interface ApprovalSigner {
23
+ keyId: string;
24
+ sign(payload: string): string;
25
+ verify(payload: string, signature: string): boolean;
26
+ }
27
+
28
+ export function loadOrCreateLocalApprovalKey(stateDir: string): ApprovalSigner {
29
+ const path = join(stateDir, "approval.key");
30
+ let key: Buffer;
31
+ if (existsSync(path)) {
32
+ key = Buffer.from(readFileSync(path, "utf8").trim(), "hex");
33
+ } else {
34
+ mkdirSync(dirname(path), { recursive: true });
35
+ key = randomBytes(32);
36
+ writeFileSync(path, key.toString("hex") + "\n", { mode: 0o600 });
37
+ chmodSync(path, 0o600);
38
+ }
39
+ return hmacSigner(APPROVAL_KEY_ID, key);
40
+ }
41
+
42
+ export function hmacSigner(keyId: string, key: Buffer): ApprovalSigner {
43
+ return {
44
+ keyId,
45
+ sign: (payload) => hmacSha256Hex(key, payload),
46
+ verify: (payload, signature) => hexEqual(hmacSha256Hex(key, payload), signature),
47
+ };
48
+ }
49
+
50
+ function unsignedPayload(artifact: Omit<ApprovalArtifact, "signature">): string {
51
+ return canonicalJson(artifact);
52
+ }
53
+
54
+ export interface CreateApprovalInput {
55
+ execution: Execution;
56
+ approver: ApprovalArtifact["approver"];
57
+ actor: Actor;
58
+ now: Date;
59
+ ttlMs?: number;
60
+ escalation?: { trigger: EscalationTrigger; detail: string };
61
+ }
62
+
63
+ export function createApprovalArtifact(signer: ApprovalSigner, input: CreateApprovalInput): ApprovalArtifact {
64
+ const { execution } = input;
65
+ const approvedAt = input.now.toISOString();
66
+ const expiresAt = new Date(input.now.getTime() + (input.ttlMs ?? DEFAULT_APPROVAL_TTL_MS)).toISOString();
67
+ const unsigned: Omit<ApprovalArtifact, "signature"> = {
68
+ approval_id: newId("apr"),
69
+ execution_id: execution.id,
70
+ mode: execution.mode,
71
+ approver: input.approver,
72
+ approved_at: approvedAt,
73
+ expires_at: expiresAt,
74
+ mandate: execution.mandate,
75
+ items: execution.items,
76
+ items_hash: itemsHash(execution.items),
77
+ // The SET this line belongs to, when it belongs to one. Omitted — never
78
+ // null — on an execution that is not part of a batch, so the payload a
79
+ // bills-agent artifact signs is unchanged by this field existing.
80
+ ...(execution.batch ? { batch: execution.batch } : {}),
81
+ ...(input.escalation ? { escalation: input.escalation } : {}),
82
+ actor: input.actor,
83
+ };
84
+ return {
85
+ ...unsigned,
86
+ signature: { alg: "HMAC-SHA256", key_id: signer.keyId, value: signer.sign(unsignedPayload(unsigned)) },
87
+ };
88
+ }
89
+
90
+ export type ApprovalCheck =
91
+ | { ok: true }
92
+ | { ok: false; problem: "signature_invalid" | "items_hash_mismatch" | "expired" | "wrong_execution" | "wrong_mandate" | "batch_mismatch" };
93
+
94
+ /** Two batch bindings are the same binding, or one is absent and so is the other. */
95
+ function sameBatch(a: ExecutionBatch | undefined, b: ExecutionBatch | undefined): boolean {
96
+ if (a === undefined || b === undefined) return a === b;
97
+ return a.ref === b.ref && a.batch_hash === b.batch_hash && a.index === b.index && a.count === b.count;
98
+ }
99
+
100
+ /**
101
+ * The rule that makes the artifact proof: before `executing`, recompute the
102
+ * hash of what is about to be executed and compare it with the artifact.
103
+ */
104
+ export function checkApprovalArtifact(
105
+ signer: ApprovalSigner,
106
+ artifact: ApprovalArtifact,
107
+ execution: Execution,
108
+ now: Date,
109
+ ): ApprovalCheck {
110
+ const { signature, ...unsigned } = artifact;
111
+ if (!signer.verify(unsignedPayload(unsigned), signature.value)) return { ok: false, problem: "signature_invalid" };
112
+ if (artifact.execution_id !== execution.id) return { ok: false, problem: "wrong_execution" };
113
+ if (artifact.mandate.id !== execution.mandate.id || artifact.mandate.version !== execution.mandate.version) {
114
+ return { ok: false, problem: "wrong_mandate" };
115
+ }
116
+ if (itemsHash(execution.items) !== artifact.items_hash) return { ok: false, problem: "items_hash_mismatch" };
117
+ // The line's own list is attested by the hash above; this is the list the
118
+ // line was one OF. An execution that gained, lost or moved its place in a
119
+ // batch after approval is not the one that was approved.
120
+ if (!sameBatch(artifact.batch, execution.batch)) return { ok: false, problem: "batch_mismatch" };
121
+ if (new Date(artifact.expires_at).getTime() <= now.getTime()) return { ok: false, problem: "expired" };
122
+ return { ok: true };
123
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Section 11: the proof bundle, one folder per run under `runs/<run-id>/`.
3
+ * It answers "why could the agent pay this". It holds no key and no secret;
4
+ * payee keys are masked the way a bank statement masks them.
5
+ */
6
+ import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { basename, join } from "node:path";
8
+ import type { Mandate } from "./mandate.js";
9
+ import type { RailReceipt } from "./rail.js";
10
+ import type { ApprovalArtifact } from "./types.js";
11
+
12
+ export interface TranscriptLine {
13
+ at: string;
14
+ kind: "user" | "assistant_step" | "tool_call" | "tool_result" | "assistant" | "system";
15
+ [key: string]: unknown;
16
+ }
17
+
18
+ export class ProofBundle {
19
+ readonly dir: string;
20
+
21
+ constructor(
22
+ runsDir: string,
23
+ readonly runId: string,
24
+ ) {
25
+ this.dir = join(runsDir, runId);
26
+ mkdirSync(join(this.dir, "receipts"), { recursive: true });
27
+ }
28
+
29
+ static open(runsDir: string, runId: string): ProofBundle | undefined {
30
+ return existsSync(join(runsDir, runId)) ? new ProofBundle(runsDir, runId) : undefined;
31
+ }
32
+
33
+ transcript(line: TranscriptLine): void {
34
+ appendFileSync(join(this.dir, "transcript.jsonl"), JSON.stringify(line) + "\n");
35
+ }
36
+
37
+ readTranscript(): TranscriptLine[] {
38
+ const path = join(this.dir, "transcript.jsonl");
39
+ if (!existsSync(path)) return [];
40
+ return readFileSync(path, "utf8")
41
+ .split("\n")
42
+ .filter(Boolean)
43
+ .map((l) => JSON.parse(l) as TranscriptLine);
44
+ }
45
+
46
+ event(event: Record<string, unknown>): void {
47
+ appendFileSync(join(this.dir, "events.jsonl"), JSON.stringify(event) + "\n");
48
+ }
49
+
50
+ /**
51
+ * The conversation, when the run had one: every message in and out of a
52
+ * channel, in order, with what the channel did with it. Separate from the
53
+ * transcript, which is the MODEL's side, because on a channel the two are
54
+ * not the same thing — a message the channel refused never reached the
55
+ * person, and the QR and the copy-and-paste were sent by the runner.
56
+ *
57
+ * It carries no contact in the clear: the channel masks it before it gets
58
+ * here, because the bundle travels.
59
+ */
60
+ channel(line: Record<string, unknown>): void {
61
+ appendFileSync(join(this.dir, "channel.jsonl"), JSON.stringify(line) + "\n");
62
+ }
63
+
64
+ readChannel(): Record<string, unknown>[] {
65
+ const path = join(this.dir, "channel.jsonl");
66
+ if (!existsSync(path)) return [];
67
+ return readFileSync(path, "utf8")
68
+ .split("\n")
69
+ .filter(Boolean)
70
+ .map((l) => JSON.parse(l) as Record<string, unknown>);
71
+ }
72
+
73
+ readEvents(): Record<string, unknown>[] {
74
+ const path = join(this.dir, "events.jsonl");
75
+ if (!existsSync(path)) return [];
76
+ return readFileSync(path, "utf8")
77
+ .split("\n")
78
+ .filter(Boolean)
79
+ .map((l) => JSON.parse(l) as Record<string, unknown>);
80
+ }
81
+
82
+ /** `approval.json` is the list of artifacts of this run, in approval order. */
83
+ approval(artifact: ApprovalArtifact): void {
84
+ const path = join(this.dir, "approval.json");
85
+ const current: ApprovalArtifact[] = existsSync(path) ? (JSON.parse(readFileSync(path, "utf8")) as ApprovalArtifact[]) : [];
86
+ if (!current.some((a) => a.approval_id === artifact.approval_id)) current.push(artifact);
87
+ writeFileSync(path, JSON.stringify(current, null, 2) + "\n");
88
+ }
89
+
90
+ readApprovals(): ApprovalArtifact[] {
91
+ const path = join(this.dir, "approval.json");
92
+ return existsSync(path) ? (JSON.parse(readFileSync(path, "utf8")) as ApprovalArtifact[]) : [];
93
+ }
94
+
95
+ mandateSnapshot(mandate: Mandate): void {
96
+ const { signature: _signature, canonical: _canonical, ...safe } = mandate;
97
+ writeFileSync(join(this.dir, "mandate.snapshot.json"), JSON.stringify({ ...safe, beneficiaries: safe.beneficiaries.map((b) => ({ ...b, payee: maskPayee(b.payee) })), merchant_allowlist: safe.merchant_allowlist.map(maskPayee) }, null, 2) + "\n");
98
+ }
99
+
100
+ /** Returns the path INSIDE the bundle (`receipts/<id>.json`): a bundle travels, and an absolute path names the machine that wrote it. */
101
+ receipt(receipt: RailReceipt): string {
102
+ const relative = join("receipts", `${receipt.receipt_id}.json`);
103
+ const { raw: _raw, ...safe } = receipt;
104
+ writeFileSync(join(this.dir, relative), JSON.stringify({ ...safe, payment: { ...safe.payment, payee: safe.payment.payee ? maskPayee(safe.payment.payee) : null } }, null, 2) + "\n");
105
+ return relative;
106
+ }
107
+
108
+ /** The masked mandate as it stood when the run started. Absent on a bundle whose run never got that far. */
109
+ readMandateSnapshot(): Record<string, unknown> | undefined {
110
+ const path = join(this.dir, "mandate.snapshot.json");
111
+ return existsSync(path) ? (JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>) : undefined;
112
+ }
113
+
114
+ /** One receipt by its file name, as `listReceipts()` returns it. */
115
+ readReceipt(file: string): Record<string, unknown> | undefined {
116
+ const path = join(this.dir, "receipts", basename(file));
117
+ return existsSync(path) ? (JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>) : undefined;
118
+ }
119
+
120
+ /**
121
+ * Section 11: `verify.json` is the output of `codespar audit replay`, which
122
+ * is not a registered command of the CLI, so nothing here writes it and
123
+ * nothing here reimplements the hash-chain check. The reader exists so a
124
+ * bundle that gains one later is noticed rather than ignored.
125
+ */
126
+ hasVerify(): boolean {
127
+ return existsSync(join(this.dir, "verify.json"));
128
+ }
129
+
130
+ listReceipts(): string[] {
131
+ const dir = join(this.dir, "receipts");
132
+ if (!existsSync(dir)) return [];
133
+ return readdirSorted(dir);
134
+ }
135
+
136
+ meta(meta: Record<string, unknown>): void {
137
+ writeFileSync(join(this.dir, "run.json"), JSON.stringify(meta, null, 2) + "\n");
138
+ }
139
+
140
+ readMeta(): Record<string, unknown> | undefined {
141
+ const path = join(this.dir, "run.json");
142
+ return existsSync(path) ? (JSON.parse(readFileSync(path, "utf8")) as Record<string, unknown>) : undefined;
143
+ }
144
+ }
145
+
146
+ function readdirSorted(dir: string): string[] {
147
+ return readdirSync(dir)
148
+ .filter((f) => f.endsWith(".json"))
149
+ .sort();
150
+ }
151
+
152
+ /** `escola@exemplo.com.br` -> `es***@exemplo.com.br`; `+5511999998888` -> `+55***8888`; a UUID keeps its first and last 4. */
153
+ export function maskPayee(payee: string): string {
154
+ if (payee === "*") return payee;
155
+ const at = payee.indexOf("@");
156
+ if (at > 0) return `${payee.slice(0, Math.min(2, at))}***${payee.slice(at)}`;
157
+ if (payee.length <= 8) return `${payee.slice(0, 2)}***`;
158
+ return `${payee.slice(0, 4)}***${payee.slice(-4)}`;
159
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * The channels an agent can be reached on, and the one artifact an agent
3
+ * ships per channel.
4
+ *
5
+ * The NAMES live here because `agent.yaml` declares them and `npm run check`
6
+ * has to confirm the declaration against what the agent ships; the BEHAVIOUR
7
+ * lives in `@codespar/agent-runtime`, which owns the runner. That split is
8
+ * the same one `tools.json` and `guardrails.json` already have: the core
9
+ * owns the shape, the runtime owns what happens.
10
+ *
11
+ * `terminal` is every agent's: `npm start` opens it and needs no account.
12
+ * `whatsapp` is the second channel, and an agent that declares it ships the
13
+ * conversations the local Cloud API emulator drives, under
14
+ * `channels/whatsapp/`.
15
+ */
16
+ import { z } from "zod";
17
+
18
+ export const CHANNELS = ["terminal", "whatsapp"] as const;
19
+ export type ChannelName = (typeof CHANNELS)[number];
20
+
21
+ /** E.164, the only contact shape WhatsApp addresses. */
22
+ export const E164 = /^\+[1-9]\d{6,14}$/;
23
+
24
+ /**
25
+ * A scripted conversation, which is what an agent ships for a channel whose
26
+ * other side is a person rather than a keyboard.
27
+ *
28
+ * It exists for two readers. A local emulator of the Cloud API drives it with
29
+ * no Meta account, which is what makes the WhatsApp gate runnable in the CI;
30
+ * and `npm run check` parses it, so a conversation that no longer names a
31
+ * contact or an agreement fails the manifest gate instead of failing a run.
32
+ *
33
+ * It scripts ONE side. What the agent answers comes from the model or from a
34
+ * recorded transcript, never from here, for the same reason a scenario pack
35
+ * asserts a final state and not a wording.
36
+ */
37
+ export const ConversationScriptSchema = z
38
+ .object({
39
+ name: z.string().regex(/^[a-z0-9-]+$/),
40
+ description: z.string().min(1),
41
+ channel: z.literal("whatsapp"),
42
+ /** The contact the conversation is bound to: the person who owes, and nobody else. */
43
+ contact: z.string().regex(E164, "contact must be E.164, e.g. +5511987654321"),
44
+ /**
45
+ * What this conversation is allowed to be about — an agreement alias for a
46
+ * collections agent. The channel refuses an outbound message that names a
47
+ * different one, which is the secrecy rule as code rather than as prose.
48
+ */
49
+ subject: z.string().min(1).optional(),
50
+ /** The person's turns, in order. */
51
+ turns: z
52
+ .array(
53
+ z
54
+ .object({
55
+ text: z.string().min(1),
56
+ /** Seconds after the previous inbound turn, on the run's clock. Keeps a scripted run deterministic. */
57
+ after_seconds: z.number().int().nonnegative().default(0),
58
+ })
59
+ .strict(),
60
+ )
61
+ .nonempty(),
62
+ })
63
+ .strict();
64
+
65
+ export type ConversationScript = z.infer<typeof ConversationScriptSchema>;
66
+
67
+ export function parseConversationScript(text: string): ConversationScript {
68
+ return ConversationScriptSchema.parse(JSON.parse(text));
69
+ }
70
+
71
+ /**
72
+ * The reserved file name inside `channels/whatsapp/`: the template registry,
73
+ * which is not a conversation. Everything else in that directory is one, so
74
+ * a conversation may not be called `templates`.
75
+ */
76
+ export const TEMPLATE_REGISTRY_FILE = "templates.json";
77
+
78
+ /**
79
+ * One template the agent declares it sends.
80
+ *
81
+ * `body` is here for a reader, not for a sender: it is the text AS SUBMITTED
82
+ * to Meta, and it is the only way somebody opening this repository can tell
83
+ * what `{{1}}` means. Nothing composes a message from it — Meta holds the
84
+ * approved copy and renders it — but the number of placeholders in it IS
85
+ * checked against the variables a send carries, because a count that does not
86
+ * match is a `132000` from the Cloud API and there is no reason to learn that
87
+ * in production.
88
+ */
89
+ export const WhatsAppTemplateSchema = z
90
+ .object({
91
+ /** Meta's own naming rule for a template. */
92
+ name: z.string().regex(/^[a-z0-9_]+$/, "a template name is lower-case letters, digits and underscores"),
93
+ /** Meta's language code, e.g. `pt_BR`. A template approved in one language does not exist in another. */
94
+ language: z.string().regex(/^[a-z]{2}(_[A-Z]{2})?$/, 'expected a language code, e.g. "pt_BR"'),
95
+ description: z.string().min(1),
96
+ body: z.string().min(1),
97
+ })
98
+ .strict();
99
+
100
+ export type WhatsAppTemplate = z.infer<typeof WhatsAppTemplateSchema>;
101
+
102
+ /**
103
+ * `channels/whatsapp/templates.json`: the LOCAL registry of the templates an
104
+ * agent uses.
105
+ *
106
+ * Outside the 24 hours that follow the person's last message WhatsApp carries
107
+ * an approved template and nothing else, so an agent that ever speaks after
108
+ * that has to own one. Whether META approved it is NOT knowable from here —
109
+ * it is a status inside a Business account, and this repository has none — so
110
+ * what this file proves is narrower and worth stating exactly: the agent
111
+ * declared the name, so a send of a name nobody declared is refused here
112
+ * instead of 400-ing at Meta. Registering the template and getting it approved
113
+ * stays the developer's, and the README says so.
114
+ */
115
+ export const TemplateRegistrySchema = z
116
+ .object({
117
+ channel: z.literal("whatsapp"),
118
+ templates: z.array(WhatsAppTemplateSchema).nonempty(),
119
+ })
120
+ .strict()
121
+ .superRefine((registry, ctx) => {
122
+ const seen = new Set<string>();
123
+ for (const [i, template] of registry.templates.entries()) {
124
+ if (seen.has(template.name)) ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["templates", i, "name"], message: `${template.name} is declared twice` });
125
+ seen.add(template.name);
126
+ }
127
+ });
128
+
129
+ export type TemplateRegistry = z.infer<typeof TemplateRegistrySchema>;
130
+
131
+ export function parseTemplateRegistry(text: string): TemplateRegistry {
132
+ return TemplateRegistrySchema.parse(JSON.parse(text));
133
+ }
134
+
135
+ /** The highest `{{n}}` in a template body, which is how many variables a send of it must carry. */
136
+ export function templateArity(body: string): number {
137
+ let highest = 0;
138
+ for (const match of body.matchAll(/\{\{\s*(\d+)\s*\}\}/g)) highest = Math.max(highest, Number(match[1]));
139
+ return highest;
140
+ }