@codespar/cli 0.14.1 → 0.17.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 (534) 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/mandate-verify.js +98 -19
  7. package/dist/commands/mandate-verify.js.map +1 -1
  8. package/dist/index.js +17 -3
  9. package/dist/index.js.map +1 -1
  10. package/dist/mandate-codec.js +31 -20
  11. package/dist/mandate-codec.js.map +1 -1
  12. package/dist/surface.js +4 -1
  13. package/dist/surface.js.map +1 -1
  14. package/package.json +1 -1
  15. package/templates/bills-agent/README.md +8 -5
  16. package/templates/bills-agent/agents/bills-agent/.env.example +3 -3
  17. package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
  18. package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
  19. package/templates/bills-agent/agents/bills-agent/README.md +62 -22
  20. package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +1 -1
  21. package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -2
  22. package/templates/bills-agent/agents/bills-agent/package.json +14 -11
  23. package/templates/bills-agent/agents/bills-agent/src/kit.ts +193 -0
  24. package/templates/bills-agent/agents/bills-agent/test/adversarial.test.ts +8 -7
  25. package/templates/bills-agent/agents/bills-agent/test/check.test.ts +19 -2
  26. package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +72 -24
  27. package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -0
  28. package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +2 -0
  29. package/templates/bills-agent/agents/bills-agent/test/inspect.test.ts +124 -0
  30. package/templates/bills-agent/agents/bills-agent/test/provider.test.ts +25 -0
  31. package/templates/bills-agent/agents/bills-agent/test/scenarios.test.ts +10 -9
  32. package/templates/bills-agent/agents/bills-agent/tsconfig.json +0 -1
  33. package/templates/bills-agent/package.json +5 -2
  34. package/templates/bills-agent/packages/agent-core/README.md +2 -0
  35. package/templates/bills-agent/packages/agent-core/package.json +1 -1
  36. package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  37. package/templates/bills-agent/packages/agent-core/src/api/rail.ts +16 -0
  38. package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  39. package/templates/bills-agent/packages/agent-core/src/approval.ts +16 -2
  40. package/templates/bills-agent/packages/agent-core/src/bundle.ts +50 -4
  41. package/templates/bills-agent/packages/agent-core/src/channels.ts +140 -0
  42. package/templates/bills-agent/packages/agent-core/src/check.ts +90 -8
  43. package/templates/bills-agent/packages/agent-core/src/clock.ts +42 -0
  44. package/templates/bills-agent/packages/agent-core/src/engine.ts +119 -18
  45. package/templates/bills-agent/packages/agent-core/src/hash.ts +13 -0
  46. package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
  47. package/templates/bills-agent/packages/agent-core/src/manifest.ts +1 -1
  48. package/templates/bills-agent/packages/agent-core/src/rail.ts +16 -2
  49. package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  50. package/templates/bills-agent/packages/agent-core/src/state-machine.ts +3 -1
  51. package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  52. package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  53. package/templates/bills-agent/packages/agent-core/src/types.ts +28 -0
  54. package/templates/bills-agent/packages/agent-core/test/approval.test.ts +36 -2
  55. package/templates/bills-agent/packages/agent-core/test/bundle.test.ts +85 -0
  56. package/templates/bills-agent/packages/agent-core/test/clock.test.ts +25 -0
  57. package/templates/bills-agent/packages/agent-core/test/engine.test.ts +73 -1
  58. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  59. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  60. package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
  61. package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
  62. package/templates/bills-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  63. package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +51 -0
  64. package/templates/bills-agent/packages/agent-runtime/README.md +68 -0
  65. package/templates/bills-agent/packages/agent-runtime/bin.mjs +32 -0
  66. package/templates/bills-agent/packages/agent-runtime/package.json +23 -0
  67. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/adversarial.ts +36 -44
  68. package/templates/bills-agent/packages/agent-runtime/src/agent.ts +68 -0
  69. package/templates/bills-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  70. package/templates/bills-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  71. package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  72. package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  73. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  74. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  75. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  76. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  77. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  78. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  79. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  80. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  81. package/templates/bills-agent/packages/agent-runtime/src/cli.ts +98 -0
  82. package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  83. package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  84. package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  85. package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  86. package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  87. package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  88. package/templates/bills-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  89. package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  90. package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  91. package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  92. package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  93. package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  94. package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  95. package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  96. package/templates/bills-agent/packages/agent-runtime/src/index.ts +12 -0
  97. package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +797 -0
  98. package/templates/bills-agent/packages/agent-runtime/src/kit.ts +206 -0
  99. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/poll.ts +22 -11
  100. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/scenarios.ts +50 -34
  101. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/setup.ts +88 -66
  102. package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +154 -0
  103. package/templates/{collections-agent/agents/collections-agent/channels/webhook/index.ts → bills-agent/packages/agent-runtime/src/webhook.ts} +1 -1
  104. package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  105. package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  106. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  107. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  108. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  109. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  110. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  111. package/templates/bills-agent/packages/agent-runtime/tsconfig.json +9 -0
  112. package/templates/bills-agent/vitest.config.ts +1 -1
  113. package/templates/collections-agent/README.md +8 -5
  114. package/templates/collections-agent/agents/collections-agent/.env.example +14 -0
  115. package/templates/collections-agent/agents/collections-agent/AGENTS.md +6 -4
  116. package/templates/collections-agent/agents/collections-agent/CLAUDE.md +6 -4
  117. package/templates/collections-agent/agents/collections-agent/README.md +184 -16
  118. package/templates/collections-agent/agents/collections-agent/agent.yaml +3 -3
  119. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +111 -0
  120. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042.json +11 -0
  121. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1103.json +11 -0
  122. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +23 -0
  123. package/templates/collections-agent/agents/collections-agent/package.json +12 -10
  124. package/templates/collections-agent/agents/collections-agent/runbook.md +52 -1
  125. package/templates/collections-agent/agents/collections-agent/src/kit.ts +265 -0
  126. package/templates/collections-agent/agents/collections-agent/test/adversarial.test.ts +9 -8
  127. package/templates/collections-agent/agents/collections-agent/test/check.test.ts +43 -1
  128. package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +56 -18
  129. package/templates/collections-agent/agents/collections-agent/test/fixtures/agreed-1042-awaiting-payer.transcript.jsonl +4 -0
  130. package/templates/collections-agent/agents/collections-agent/test/scenarios.test.ts +11 -10
  131. package/templates/collections-agent/agents/collections-agent/test/webhook.test.ts +4 -7
  132. package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +271 -0
  133. package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +213 -0
  134. package/templates/collections-agent/agents/collections-agent/tsconfig.json +0 -1
  135. package/templates/collections-agent/package.json +3 -1
  136. package/templates/collections-agent/packages/agent-core/README.md +2 -0
  137. package/templates/collections-agent/packages/agent-core/package.json +1 -1
  138. package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  139. package/templates/collections-agent/packages/agent-core/src/api/rail.ts +16 -0
  140. package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  141. package/templates/collections-agent/packages/agent-core/src/approval.ts +16 -2
  142. package/templates/collections-agent/packages/agent-core/src/bundle.ts +50 -4
  143. package/templates/collections-agent/packages/agent-core/src/channels.ts +140 -0
  144. package/templates/collections-agent/packages/agent-core/src/check.ts +90 -8
  145. package/templates/collections-agent/packages/agent-core/src/clock.ts +42 -0
  146. package/templates/collections-agent/packages/agent-core/src/engine.ts +119 -18
  147. package/templates/collections-agent/packages/agent-core/src/hash.ts +13 -0
  148. package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
  149. package/templates/collections-agent/packages/agent-core/src/manifest.ts +1 -1
  150. package/templates/collections-agent/packages/agent-core/src/rail.ts +16 -2
  151. package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  152. package/templates/collections-agent/packages/agent-core/src/state-machine.ts +3 -1
  153. package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  154. package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  155. package/templates/collections-agent/packages/agent-core/src/types.ts +28 -0
  156. package/templates/collections-agent/packages/agent-core/test/approval.test.ts +36 -2
  157. package/templates/collections-agent/packages/agent-core/test/bundle.test.ts +85 -0
  158. package/templates/collections-agent/packages/agent-core/test/clock.test.ts +25 -0
  159. package/templates/collections-agent/packages/agent-core/test/engine.test.ts +73 -1
  160. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  161. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  162. package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
  163. package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
  164. package/templates/collections-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  165. package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +51 -0
  166. package/templates/collections-agent/packages/agent-runtime/README.md +68 -0
  167. package/templates/collections-agent/packages/agent-runtime/bin.mjs +32 -0
  168. package/templates/collections-agent/packages/agent-runtime/package.json +23 -0
  169. package/templates/collections-agent/{agents/collections-agent → packages/agent-runtime}/src/adversarial.ts +29 -50
  170. package/templates/collections-agent/packages/agent-runtime/src/agent.ts +68 -0
  171. package/templates/collections-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  172. package/templates/collections-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  173. package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  174. package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  175. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  176. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  177. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  178. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  179. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  180. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  181. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  182. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  183. package/templates/collections-agent/packages/agent-runtime/src/cli.ts +98 -0
  184. package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  185. package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  186. package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  187. package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  188. package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  189. package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  190. package/templates/collections-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  191. package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  192. package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  193. package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  194. package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  195. package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  196. package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  197. package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  198. package/templates/collections-agent/packages/agent-runtime/src/index.ts +12 -0
  199. package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +797 -0
  200. package/templates/collections-agent/packages/agent-runtime/src/kit.ts +206 -0
  201. package/templates/collections-agent/packages/agent-runtime/src/poll.ts +105 -0
  202. package/templates/{bills-agent/agents/bills-agent → collections-agent/packages/agent-runtime}/src/scenarios.ts +98 -26
  203. package/templates/collections-agent/packages/agent-runtime/src/setup.ts +229 -0
  204. package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +154 -0
  205. package/templates/collections-agent/packages/agent-runtime/src/webhook.ts +131 -0
  206. package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  207. package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  208. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  209. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  210. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  211. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  212. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  213. package/templates/collections-agent/packages/agent-runtime/tsconfig.json +9 -0
  214. package/templates/collections-agent/vitest.config.ts +1 -1
  215. package/templates/hello-agent/LICENSE +21 -0
  216. package/templates/hello-agent/README.md +23 -0
  217. package/templates/hello-agent/_gitignore +10 -0
  218. package/templates/hello-agent/agents/hello-agent/.env.example +5 -0
  219. package/templates/hello-agent/agents/hello-agent/AGENTS.md +15 -0
  220. package/templates/hello-agent/agents/hello-agent/CLAUDE.md +15 -0
  221. package/templates/hello-agent/agents/hello-agent/README.md +33 -0
  222. package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +19 -0
  223. package/templates/hello-agent/agents/hello-agent/agent.yaml +19 -0
  224. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.json +6 -0
  225. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  226. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.json +6 -0
  227. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +2 -0
  228. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.json +6 -0
  229. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.transcript.jsonl +2 -0
  230. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.json +6 -0
  231. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.transcript.jsonl +2 -0
  232. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.json +6 -0
  233. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  234. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.json +6 -0
  235. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  236. package/templates/hello-agent/agents/hello-agent/evals/adversarial/webhook-replay.json +6 -0
  237. package/templates/hello-agent/agents/hello-agent/evals/eval.yaml +7 -0
  238. package/templates/hello-agent/agents/hello-agent/guardrails.json +8 -0
  239. package/templates/hello-agent/agents/hello-agent/mandate.example.json +17 -0
  240. package/templates/hello-agent/agents/hello-agent/package.json +19 -0
  241. package/templates/hello-agent/agents/hello-agent/runbook.md +10 -0
  242. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +6 -0
  243. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +2 -0
  244. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +6 -0
  245. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  246. package/templates/hello-agent/agents/hello-agent/src/bills.ts +23 -0
  247. package/templates/hello-agent/agents/hello-agent/src/kit.ts +33 -0
  248. package/templates/hello-agent/agents/hello-agent/tools.json +11 -0
  249. package/templates/hello-agent/agents/hello-agent/tsconfig.json +9 -0
  250. package/templates/hello-agent/package.json +30 -0
  251. package/templates/hello-agent/packages/agent-core/README.md +21 -0
  252. package/templates/hello-agent/packages/agent-core/package.json +24 -0
  253. package/templates/hello-agent/packages/agent-core/src/agent.ts +125 -0
  254. package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  255. package/templates/hello-agent/packages/agent-core/src/api/client.ts +53 -0
  256. package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  257. package/templates/hello-agent/packages/agent-core/src/api/rail.ts +117 -0
  258. package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  259. package/templates/hello-agent/packages/agent-core/src/approval.ts +123 -0
  260. package/templates/hello-agent/packages/agent-core/src/bundle.ts +159 -0
  261. package/templates/hello-agent/packages/agent-core/src/channels.ts +140 -0
  262. package/templates/hello-agent/packages/agent-core/src/check.ts +253 -0
  263. package/templates/hello-agent/packages/agent-core/src/clock.ts +42 -0
  264. package/templates/hello-agent/packages/agent-core/src/engine.ts +885 -0
  265. package/templates/hello-agent/packages/agent-core/src/escalate.ts +85 -0
  266. package/templates/hello-agent/packages/agent-core/src/events.ts +40 -0
  267. package/templates/hello-agent/packages/agent-core/src/guardrails.ts +45 -0
  268. package/templates/hello-agent/packages/agent-core/src/hash.ts +62 -0
  269. package/templates/hello-agent/packages/agent-core/src/ids.ts +10 -0
  270. package/templates/hello-agent/packages/agent-core/src/index.ts +32 -0
  271. package/templates/hello-agent/packages/agent-core/src/mandate.ts +100 -0
  272. package/templates/hello-agent/packages/agent-core/src/manifest.ts +76 -0
  273. package/templates/hello-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  274. package/templates/hello-agent/packages/agent-core/src/providers/replay.ts +63 -0
  275. package/templates/hello-agent/packages/agent-core/src/providers/types.ts +39 -0
  276. package/templates/hello-agent/packages/agent-core/src/rail.ts +101 -0
  277. package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  278. package/templates/hello-agent/packages/agent-core/src/revocation.ts +30 -0
  279. package/templates/hello-agent/packages/agent-core/src/secrets.ts +30 -0
  280. package/templates/hello-agent/packages/agent-core/src/state/store.ts +307 -0
  281. package/templates/hello-agent/packages/agent-core/src/state-machine.ts +148 -0
  282. package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  283. package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  284. package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  285. package/templates/hello-agent/packages/agent-core/src/tools.ts +55 -0
  286. package/templates/hello-agent/packages/agent-core/src/types.ts +134 -0
  287. package/templates/hello-agent/packages/agent-core/test/approval.test.ts +117 -0
  288. package/templates/hello-agent/packages/agent-core/test/bundle.test.ts +85 -0
  289. package/templates/hello-agent/packages/agent-core/test/clock.test.ts +25 -0
  290. package/templates/hello-agent/packages/agent-core/test/engine.test.ts +596 -0
  291. package/templates/hello-agent/packages/agent-core/test/escalate.test.ts +42 -0
  292. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  293. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  294. package/templates/hello-agent/packages/agent-core/test/helpers.ts +139 -0
  295. package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  296. package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +45 -0
  297. package/templates/hello-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  298. package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +316 -0
  299. package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +28 -0
  300. package/templates/hello-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  301. package/templates/hello-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  302. package/templates/hello-agent/packages/agent-core/tsconfig.json +10 -0
  303. package/templates/hello-agent/packages/agent-runtime/README.md +68 -0
  304. package/templates/hello-agent/packages/agent-runtime/bin.mjs +32 -0
  305. package/templates/hello-agent/packages/agent-runtime/package.json +23 -0
  306. package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  307. package/templates/hello-agent/packages/agent-runtime/src/agent.ts +68 -0
  308. package/templates/hello-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  309. package/templates/hello-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  310. package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  311. package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  312. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  313. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  314. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  315. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  316. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  317. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  318. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  319. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  320. package/templates/hello-agent/packages/agent-runtime/src/cli.ts +98 -0
  321. package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  322. package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  323. package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  324. package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  325. package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  326. package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  327. package/templates/hello-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  328. package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  329. package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  330. package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  331. package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  332. package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  333. package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  334. package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  335. package/templates/hello-agent/packages/agent-runtime/src/index.ts +12 -0
  336. package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +797 -0
  337. package/templates/hello-agent/packages/agent-runtime/src/kit.ts +206 -0
  338. package/templates/hello-agent/packages/agent-runtime/src/poll.ts +105 -0
  339. package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  340. package/templates/hello-agent/packages/agent-runtime/src/setup.ts +229 -0
  341. package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +154 -0
  342. package/templates/hello-agent/packages/agent-runtime/src/webhook.ts +131 -0
  343. package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  344. package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  345. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  346. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  347. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  348. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  349. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  350. package/templates/hello-agent/packages/agent-runtime/tsconfig.json +9 -0
  351. package/templates/hello-agent/tsconfig.base.json +16 -0
  352. package/templates/hello-agent/vitest.config.ts +12 -0
  353. package/templates/kits.lock.json +60 -12
  354. package/templates/supplier-payments-agent/LICENSE +21 -0
  355. package/templates/supplier-payments-agent/README.md +23 -0
  356. package/templates/supplier-payments-agent/_gitignore +10 -0
  357. package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +7 -0
  358. package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +21 -0
  359. package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +21 -0
  360. package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +118 -0
  361. package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +29 -0
  362. package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +26 -0
  363. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.json +12 -0
  364. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.transcript.jsonl +3 -0
  365. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap-mandate.json +9 -0
  366. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.json +10 -0
  367. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  368. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.json +13 -0
  369. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
  370. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.json +9 -0
  371. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +3 -0
  372. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.json +15 -0
  373. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.transcript.jsonl +6 -0
  374. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.json +10 -0
  375. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  376. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.json +9 -0
  377. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  378. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/webhook-replay.json +9 -0
  379. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/eval.yaml +9 -0
  380. package/templates/supplier-payments-agent/agents/supplier-payments-agent/guardrails.json +15 -0
  381. package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +70 -0
  382. package/templates/supplier-payments-agent/agents/supplier-payments-agent/package.json +26 -0
  383. package/templates/supplier-payments-agent/agents/supplier-payments-agent/runbook.md +19 -0
  384. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.json +14 -0
  385. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +2 -0
  386. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.json +12 -0
  387. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +2 -0
  388. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.json +20 -0
  389. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +7 -0
  390. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.json +19 -0
  391. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +3 -0
  392. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.json +21 -0
  393. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +9 -0
  394. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +21 -0
  395. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +3 -0
  396. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.json +12 -0
  397. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  398. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +176 -0
  399. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +345 -0
  400. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +118 -0
  401. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +76 -0
  402. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/adversarial.test.ts +53 -0
  403. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +384 -0
  404. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/check.test.ts +109 -0
  405. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/scenarios.test.ts +81 -0
  406. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +53 -0
  407. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tsconfig.json +9 -0
  408. package/templates/supplier-payments-agent/package.json +36 -0
  409. package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -0
  410. package/templates/supplier-payments-agent/packages/agent-core/package.json +24 -0
  411. package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +125 -0
  412. package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  413. package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +53 -0
  414. package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  415. package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +117 -0
  416. package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  417. package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +123 -0
  418. package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +159 -0
  419. package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +140 -0
  420. package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +253 -0
  421. package/templates/supplier-payments-agent/packages/agent-core/src/clock.ts +42 -0
  422. package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +885 -0
  423. package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +85 -0
  424. package/templates/supplier-payments-agent/packages/agent-core/src/events.ts +40 -0
  425. package/templates/supplier-payments-agent/packages/agent-core/src/guardrails.ts +45 -0
  426. package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +62 -0
  427. package/templates/supplier-payments-agent/packages/agent-core/src/ids.ts +10 -0
  428. package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +32 -0
  429. package/templates/supplier-payments-agent/packages/agent-core/src/mandate.ts +100 -0
  430. package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +76 -0
  431. package/templates/supplier-payments-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  432. package/templates/supplier-payments-agent/packages/agent-core/src/providers/replay.ts +63 -0
  433. package/templates/supplier-payments-agent/packages/agent-core/src/providers/types.ts +39 -0
  434. package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +101 -0
  435. package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  436. package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +30 -0
  437. package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +30 -0
  438. package/templates/supplier-payments-agent/packages/agent-core/src/state/store.ts +307 -0
  439. package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +148 -0
  440. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  441. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  442. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  443. package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +55 -0
  444. package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +134 -0
  445. package/templates/supplier-payments-agent/packages/agent-core/test/approval.test.ts +117 -0
  446. package/templates/supplier-payments-agent/packages/agent-core/test/bundle.test.ts +85 -0
  447. package/templates/supplier-payments-agent/packages/agent-core/test/clock.test.ts +25 -0
  448. package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +596 -0
  449. package/templates/supplier-payments-agent/packages/agent-core/test/escalate.test.ts +42 -0
  450. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  451. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  452. package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +139 -0
  453. package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  454. package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +45 -0
  455. package/templates/supplier-payments-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  456. package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +316 -0
  457. package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +28 -0
  458. package/templates/supplier-payments-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  459. package/templates/supplier-payments-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  460. package/templates/supplier-payments-agent/packages/agent-core/tsconfig.json +10 -0
  461. package/templates/supplier-payments-agent/packages/agent-runtime/README.md +68 -0
  462. package/templates/supplier-payments-agent/packages/agent-runtime/bin.mjs +32 -0
  463. package/templates/supplier-payments-agent/packages/agent-runtime/package.json +23 -0
  464. package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  465. package/templates/supplier-payments-agent/packages/agent-runtime/src/agent.ts +68 -0
  466. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  467. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  468. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  469. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  470. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  471. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  472. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  473. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  474. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  475. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  476. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  477. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  478. package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +98 -0
  479. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  480. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  481. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  482. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  483. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  484. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  485. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  486. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  487. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  488. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  489. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  490. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  491. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  492. package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  493. package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +12 -0
  494. package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +797 -0
  495. package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +206 -0
  496. package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +105 -0
  497. package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  498. package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +229 -0
  499. package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +154 -0
  500. package/templates/supplier-payments-agent/packages/agent-runtime/src/webhook.ts +131 -0
  501. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  502. package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  503. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  504. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  505. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  506. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  507. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  508. package/templates/supplier-payments-agent/packages/agent-runtime/tsconfig.json +9 -0
  509. package/templates/supplier-payments-agent/tsconfig.base.json +16 -0
  510. package/templates/supplier-payments-agent/vitest.config.ts +12 -0
  511. package/templates/bills-agent/agents/bills-agent/channels/terminal/index.ts +0 -108
  512. package/templates/bills-agent/agents/bills-agent/src/commands/approve.ts +0 -9
  513. package/templates/bills-agent/agents/bills-agent/src/commands/check.ts +0 -13
  514. package/templates/bills-agent/agents/bills-agent/src/commands/consent.ts +0 -26
  515. package/templates/bills-agent/agents/bills-agent/src/commands/decide.ts +0 -45
  516. package/templates/bills-agent/agents/bills-agent/src/commands/deny.ts +0 -7
  517. package/templates/bills-agent/agents/bills-agent/src/commands/eval.ts +0 -37
  518. package/templates/bills-agent/agents/bills-agent/src/commands/reconcile.ts +0 -38
  519. package/templates/bills-agent/agents/bills-agent/src/commands/rerun.ts +0 -65
  520. package/templates/bills-agent/agents/bills-agent/src/commands/resume.ts +0 -30
  521. package/templates/bills-agent/agents/bills-agent/src/main.ts +0 -185
  522. package/templates/collections-agent/agents/collections-agent/channels/terminal/index.ts +0 -178
  523. package/templates/collections-agent/agents/collections-agent/src/commands/approve.ts +0 -10
  524. package/templates/collections-agent/agents/collections-agent/src/commands/check.ts +0 -13
  525. package/templates/collections-agent/agents/collections-agent/src/commands/decide.ts +0 -48
  526. package/templates/collections-agent/agents/collections-agent/src/commands/deny.ts +0 -7
  527. package/templates/collections-agent/agents/collections-agent/src/commands/eval.ts +0 -39
  528. package/templates/collections-agent/agents/collections-agent/src/commands/poll.ts +0 -35
  529. package/templates/collections-agent/agents/collections-agent/src/commands/reconcile.ts +0 -38
  530. package/templates/collections-agent/agents/collections-agent/src/commands/rerun.ts +0 -55
  531. package/templates/collections-agent/agents/collections-agent/src/commands/resume.ts +0 -30
  532. package/templates/collections-agent/agents/collections-agent/src/commands/webhook.ts +0 -36
  533. package/templates/collections-agent/agents/collections-agent/src/main.ts +0 -193
  534. package/templates/collections-agent/agents/collections-agent/src/setup.ts +0 -250
@@ -57,10 +57,27 @@ describe("npm run check: the manifest is the index", () => {
57
57
  }
58
58
  });
59
59
 
60
- it("fails when a README claims third-party verifiability or .env.example grows a third key", () => {
60
+ it("fails when a doc claims third-party verifiability and never says which signature it means", () => {
61
61
  const dir = copyAgent();
62
- writeFileSync(join(dir, "README.md"), readFileSync(join(dir, "README.md"), "utf8") + "\nO recibo é verificável por terceiro.\n");
62
+ // The claim with no mechanism named: true of the Ed25519 seal on a receipt, false of the approval artifact and of every receipt sealed before it.
63
+ writeFileSync(join(dir, "README.md"), "# bills-agent\n\nO recibo é verificável por terceiro.\n");
63
64
  expect(codes(dir)).toContain("doc_overclaims");
65
+ // The same claim, with the mechanism named: allowed, and what the shipped README does.
66
+ writeFileSync(join(dir, "README.md"), "# bills-agent\n\nO recibo é verificável por terceiro: a assinatura Ed25519 confere contra as chaves públicas.\n");
67
+ expect(codes(dir)).not.toContain("doc_overclaims");
68
+ });
69
+
70
+
71
+ it("refuses the claim, mechanism named and all, when the agent itself says receipt-verification is blocked", () => {
72
+ const dir = copyAgent();
73
+ writeFileSync(join(dir, "README.md"), readFileSync(join(dir, "README.md"), "utf8") + "\nThe receipt is third-party verifiable: the Ed25519 signature checks against the published keys.\n");
74
+ expect(codes(dir)).not.toContain("doc_overclaims");
75
+ writeFileSync(join(dir, "agent.yaml"), readFileSync(join(dir, "agent.yaml"), "utf8").replace("receipt-verification: sandbox", "receipt-verification: blocked"));
76
+ expect(codes(dir)).toContain("doc_overclaims");
77
+ });
78
+
79
+ it("fails when .env.example grows a third key", () => {
80
+ const dir = copyAgent();
64
81
  writeFileSync(join(dir, ".env.example"), readFileSync(join(dir, ".env.example"), "utf8") + "APPROVAL_KEY=x\n");
65
82
  expect(codes(dir)).toContain("env_example_extra");
66
83
  });
@@ -11,9 +11,10 @@ import { describe, expect, it } from "vitest";
11
11
 
12
12
  const AGENT_DIR = resolve(import.meta.dirname, "..");
13
13
  const NODE = process.execPath;
14
+ const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
14
15
 
15
- function run(script: string, args: string[], env: Record<string, string>) {
16
- const result = spawnSync(NODE, ["--disable-warning=ExperimentalWarning", "--import", "tsx", script, ...args], {
16
+ function run(command: string, args: string[], env: Record<string, string>) {
17
+ const result = spawnSync(NODE, [BIN, command, ...args], {
17
18
  cwd: AGENT_DIR,
18
19
  env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", ...env },
19
20
  encoding: "utf8",
@@ -25,7 +26,7 @@ function run(script: string, args: string[], env: Record<string, string>) {
25
26
  describe("npm start -- --input ... --json", () => {
26
27
  it("prints valid JSON on stdout and nothing else; people go to stderr", () => {
27
28
  const stateDir = mkdtempSync(join(tmpdir(), "bills-json-"));
28
- const out = run("src/main.ts", ["--input", "pague a escola de outubro", "--approve", "--json"], { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") });
29
+ const out = run("start", ["--input", "pague a escola de outubro", "--approve", "--json"], { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") });
29
30
  expect(out.code).toBe(0);
30
31
  const lines = out.stdout.split("\n").filter(Boolean);
31
32
  expect(lines).toHaveLength(1);
@@ -37,22 +38,66 @@ describe("npm start -- --input ... --json", () => {
37
38
  expect(out.stderr).toContain("replay");
38
39
  });
39
40
 
41
+ it("replays when ANTHROPIC_API_KEY still holds the .env.example placeholder", () => {
42
+ const stateDir = mkdtempSync(join(tmpdir(), "bills-placeholder-"));
43
+ const out = run("start", ["--input", "pague a escola de outubro", "--approve", "--json"], { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs"), ANTHROPIC_API_KEY: "sk-ant-your_key_here" });
44
+ expect(out.code).toBe(0);
45
+ expect(out.stderr).toContain("[replay] no ANTHROPIC_API_KEY");
46
+ const payload = JSON.parse(out.stdout.trim()) as { executions: Array<{ state: string }> };
47
+ expect(payload.executions.map((e) => e.state)).toEqual(["settled"]);
48
+ });
49
+
40
50
  it("refuses a key outside csk_test_ before anything else", () => {
41
51
  const stateDir = mkdtempSync(join(tmpdir(), "bills-live-"));
42
- const out = run("src/main.ts", ["--input", "pague a escola de outubro", "--json"], { BILLS_STATE_DIR: stateDir, CODESPAR_API_KEY: ["csk", "live", "0000000000"].join("_") });
52
+ const out = run("start", ["--input", "pague a escola de outubro", "--json"], { BILLS_STATE_DIR: stateDir, CODESPAR_API_KEY: ["csk", "live", "0000000000"].join("_") });
43
53
  expect(out.code).toBe(1);
44
54
  expect(out.stdout).toBe("");
45
55
  expect(out.stderr).toContain("csk_test_");
46
56
  });
47
57
  });
48
58
 
59
+ // #16: `escalate_above.outside_hours` (22:00-07:00) reads the engine clock too. The escalation order is amount, new_beneficiary,
60
+ // outside_hours, so the hour can only be the trigger on a payee the mandate already knows, below the amount threshold: the
61
+ // state is seeded with one settled payment to the school first, in its own process, the way a real day would.
62
+ describe("--now pins the clock the mandate-mode escalation reads", () => {
63
+ function seedKnownPayee(label: string): Record<string, string> {
64
+ const stateDir = mkdtempSync(join(tmpdir(), `bills-now-${label}-`));
65
+ const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
66
+ const seed = run("start", ["--mode", "mandate", "--input", "paga 400 reais pra escola (material)", "--transcript", "test/fixtures/material-400.transcript.jsonl", "--approve", "--json", "--now", "2026-09-23T14:00:00-03:00"], env);
67
+ expect(seed.code).toBe(0);
68
+ const payload = JSON.parse(seed.stdout.trim()) as { executions: Array<{ state: string; escalation: { trigger: string } | null }> };
69
+ expect(payload.executions[0]).toMatchObject({ state: "settled", escalation: { trigger: "new_beneficiary" } });
70
+ return env;
71
+ }
72
+ const EXCURSAO = ["--mode", "mandate", "--input", "e mais 300 reais pra escola, a excursao", "--transcript", "test/fixtures/excursao-300.transcript.jsonl", "--json"];
73
+ type Payload = { executions: Array<{ state: string; escalation: { trigger: string; detail: string } | null; receipt_ids: string[] }> };
74
+
75
+ it("at 23:00 America/Sao_Paulo a payment inside the mandate is escalated (outside_hours) and waits for a human", () => {
76
+ const out = run("start", [...EXCURSAO, "--now", "2026-09-23T23:00:00-03:00"], seedKnownPayee("night"));
77
+ expect(out.code).toBe(0);
78
+ const payload = JSON.parse(out.stdout.trim()) as Payload;
79
+ expect(payload.executions).toHaveLength(1);
80
+ expect(payload.executions[0]).toMatchObject({ state: "awaiting_approval", escalation: { trigger: "outside_hours" } });
81
+ expect(payload.executions[0]?.escalation?.detail).toContain("23:00");
82
+ expect(payload.executions[0]?.receipt_ids).toEqual([]);
83
+ });
84
+
85
+ it("at 14:00 America/Sao_Paulo the same payment runs alone: no trigger, one receipt", () => {
86
+ const out = run("start", [...EXCURSAO, "--now", "2026-09-23T14:00:00-03:00"], seedKnownPayee("day"));
87
+ expect(out.code).toBe(0);
88
+ const payload = JSON.parse(out.stdout.trim()) as Payload;
89
+ expect(payload.executions[0]).toMatchObject({ state: "settled", escalation: null });
90
+ expect(payload.executions[0]?.receipt_ids).toHaveLength(1);
91
+ });
92
+ });
93
+
49
94
  describe("section 10: restart in executing, then resume", () => {
50
95
  it("one payment, one receipt, never two", () => {
51
96
  const stateDir = mkdtempSync(join(tmpdir(), "bills-restart-"));
52
97
  const runsDir = join(stateDir, "runs");
53
98
  const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir };
54
99
 
55
- const killed = run("src/main.ts", ["--input", "pague a escola de outubro", "--approve", "--json"], { ...env, BILLS_KILL_AFTER_DISPATCH: "1" });
100
+ const killed = run("start", ["--input", "pague a escola de outubro", "--approve", "--json"], { ...env, BILLS_KILL_AFTER_DISPATCH: "1" });
56
101
  expect(killed.code).toBe(137);
57
102
  expect(killed.stdout).toBe("");
58
103
 
@@ -62,7 +107,7 @@ describe("section 10: restart in executing, then resume", () => {
62
107
  expect((db.prepare("SELECT COUNT(*) AS n FROM stub_rail_attempts").get() as { n: number }).n).toBe(1);
63
108
  db.close();
64
109
 
65
- const resumed = run("src/commands/resume.ts", ["--json"], env);
110
+ const resumed = run("resume", ["--json"], env);
66
111
  expect(resumed.code).toBe(0);
67
112
  const payload = JSON.parse(resumed.stdout.trim()) as { resumed: Array<{ state: string; receipt_ids: string[] }> };
68
113
  expect(payload.resumed).toHaveLength(1);
@@ -78,7 +123,7 @@ describe("section 10: restart in executing, then resume", () => {
78
123
  const receipts = readdirSync(runsDir).flatMap((r) => (existsSync(join(runsDir, r, "receipts")) ? readdirSync(join(runsDir, r, "receipts")) : []));
79
124
  expect(receipts).toHaveLength(1);
80
125
 
81
- const again = run("src/commands/resume.ts", ["--json"], env);
126
+ const again = run("resume", ["--json"], env);
82
127
  expect(JSON.parse(again.stdout.trim())).toMatchObject({ resumed: [] });
83
128
  });
84
129
  });
@@ -88,10 +133,10 @@ describe("npm run rerun <run-id>", () => {
88
133
  const stateDir = mkdtempSync(join(tmpdir(), "bills-rerun-"));
89
134
  const runsDir = join(stateDir, "runs");
90
135
  const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir };
91
- const first = run("src/main.ts", ["--input", "pague a escola de outubro", "--approve", "--json"], env);
136
+ const first = run("start", ["--input", "pague a escola de outubro", "--approve", "--json"], env);
92
137
  expect(first.code).toBe(0);
93
138
  const { run_id } = JSON.parse(first.stdout.trim()) as { run_id: string };
94
- const rerun = run("src/commands/rerun.ts", [run_id, "--json"], env);
139
+ const rerun = run("rerun", [run_id, "--json"], env);
95
140
  expect(rerun.code).toBe(0);
96
141
  const payload = JSON.parse(rerun.stdout.trim()) as { same_states: boolean; original: string[]; rerun: string[] };
97
142
  expect(payload.same_states).toBe(true);
@@ -102,7 +147,7 @@ describe("npm run rerun <run-id>", () => {
102
147
 
103
148
  describe("npm run check", () => {
104
149
  it("is green for the shipped agent and prints JSON with --json", () => {
105
- const out = run("src/commands/check.ts", ["--json"], {});
150
+ const out = run("check", ["--json"], {});
106
151
  expect(out.code).toBe(0);
107
152
  const report = JSON.parse(out.stdout.trim()) as { ok: boolean; agent: string; findings: unknown[] };
108
153
  expect(report).toMatchObject({ ok: true, agent: "bills-agent" });
@@ -115,16 +160,16 @@ describe("npm run approve / deny <execution-id>", () => {
115
160
  const stateDir = mkdtempSync(join(tmpdir(), "bills-decide-"));
116
161
  const runsDir = join(stateDir, "runs");
117
162
  const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir };
118
- const left = run("src/main.ts", ["--input", "pague a escola de outubro", "--json"], env);
163
+ const left = run("start", ["--input", "pague a escola de outubro", "--json"], env);
119
164
  expect(left.code).toBe(0);
120
165
  const payload = JSON.parse(left.stdout.trim()) as { executions: Array<{ id: string; state: string }> };
121
166
  expect(payload.executions[0]?.state).toBe("awaiting_approval");
122
167
  const id = payload.executions[0]!.id;
123
168
 
124
- const denied = run("src/commands/deny.ts", ["nope_unknown", "--json"], env);
169
+ const denied = run("deny", ["nope_unknown", "--json"], env);
125
170
  expect(denied.code).toBe(1);
126
171
 
127
- const approved = run("src/commands/approve.ts", [id, "--user", "usr_titular", "--json"], env);
172
+ const approved = run("approve", [id, "--user", "usr_titular", "--json"], env);
128
173
  expect(approved.code).toBe(0);
129
174
  const out = JSON.parse(approved.stdout.trim()) as { state: string; approval_id: string | null; receipt_ids: string[]; bundle_dir: string };
130
175
  expect(out.state).toBe("settled");
@@ -133,7 +178,7 @@ describe("npm run approve / deny <execution-id>", () => {
133
178
  const artifacts = JSON.parse(readFileSync(join(AGENT_DIR, out.bundle_dir, "approval.json"), "utf8")) as Array<{ approver: { type: string; id: string } }>;
134
179
  expect(artifacts[0]?.approver).toEqual({ type: "person", id: "usr_titular", channel: "terminal" });
135
180
 
136
- const again = run("src/commands/approve.ts", [id, "--json"], env);
181
+ const again = run("approve", [id, "--json"], env);
137
182
  expect(again.code).toBe(1);
138
183
  expect(again.stderr).toContain("not awaiting_approval");
139
184
  });
@@ -141,9 +186,9 @@ describe("npm run approve / deny <execution-id>", () => {
141
186
  it("deny leaves a terminal denied execution and sends nothing", () => {
142
187
  const stateDir = mkdtempSync(join(tmpdir(), "bills-deny-"));
143
188
  const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: join(stateDir, "runs") };
144
- const left = run("src/main.ts", ["--input", "pague a escola de outubro", "--json"], env);
189
+ const left = run("start", ["--input", "pague a escola de outubro", "--json"], env);
145
190
  const id = (JSON.parse(left.stdout.trim()) as { executions: Array<{ id: string }> }).executions[0]!.id;
146
- const denied = run("src/commands/deny.ts", [id, "--json"], env);
191
+ const denied = run("deny", [id, "--json"], env);
147
192
  expect(denied.code).toBe(0);
148
193
  expect(JSON.parse(denied.stdout.trim())).toMatchObject({ state: "denied", reason: "denied_by_approver", receipt_ids: [] });
149
194
  const db = new DatabaseSync(join(stateDir, "state.db"));
@@ -153,25 +198,28 @@ describe("npm run approve / deny <execution-id>", () => {
153
198
  });
154
199
 
155
200
  describe("partial failure of a multi-item execution, and rerun reproducing it", () => {
156
- it("names what settled and what failed, and rerun replays the rail's refusal", () => {
201
+ it("pays every bill the rail accepted, names the one it refused, and rerun replays the refusal", () => {
157
202
  const stateDir = mkdtempSync(join(tmpdir(), "bills-partial-"));
158
203
  const runsDir = join(stateDir, "runs");
159
204
  const env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir, BILLS_STUB_REFUSE: "+5511999990001" };
160
- const first = run("src/main.ts", ["--input", "libera o lote do mes", "--transcript", "evals/adversarial/false-authority.transcript.jsonl", "--approve", "--json"], env);
205
+ const first = run("start", ["--input", "libera o lote do mes", "--transcript", "evals/adversarial/false-authority.transcript.jsonl", "--approve", "--json"], env);
161
206
  expect(first.code).toBe(0);
162
207
  const payload = JSON.parse(first.stdout.trim()) as { run_id: string; executions: Array<{ state: string; receipt_ids: string[] }>; receipts: string[] };
208
+ // Four bills, the SECOND refused by the rail. The execution closes `failed`
209
+ // because one attempt failed, and the two bills after the refused one are
210
+ // paid all the same: an attempt's outcome is that attempt's business.
163
211
  expect(payload.executions[0]?.state).toBe("failed");
164
- expect(payload.executions[0]?.receipt_ids).toHaveLength(1);
165
- expect(payload.receipts).toHaveLength(1);
212
+ expect(payload.executions[0]?.receipt_ids).toHaveLength(3);
213
+ expect(payload.receipts).toHaveLength(3);
166
214
  const events = readFileSync(join(runsDir, payload.run_id, "events.jsonl"), "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l) as { type: string; payload: { status?: string } });
167
- expect(events.filter((e) => e.type === "rail.outcome").map((e) => e.payload.status)).toEqual(["settled", "failed"]);
215
+ expect(events.filter((e) => e.type === "rail.outcome").map((e) => e.payload.status)).toEqual(["settled", "failed", "settled", "settled"]);
168
216
 
169
- const rerun = run("src/commands/rerun.ts", [payload.run_id, "--json"], { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir });
217
+ const rerun = run("rerun", [payload.run_id, "--json"], { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runsDir });
170
218
  expect(rerun.code).toBe(0);
171
219
  const r = JSON.parse(rerun.stdout.trim()) as { same_states: boolean; original: string[]; rerun: string[]; original_outcomes: string[]; rerun_outcomes: string[] };
172
220
  expect(r.same_states).toBe(true);
173
221
  expect(r.original).toEqual(["awaiting_approval", "approved", "executing", "failed"]);
174
- expect(r.original_outcomes).toEqual(["settled", "failed"]);
175
- expect(r.rerun_outcomes).toEqual(["settled", "failed"]);
222
+ expect(r.original_outcomes).toEqual(["settled", "failed", "settled", "settled"]);
223
+ expect(r.rerun_outcomes).toEqual(["settled", "failed", "settled", "settled"]);
176
224
  });
177
225
  });
@@ -0,0 +1,2 @@
1
+ {"kind":"assistant_step","tool_calls":[{"id":"tc_4","name":"codespar_pay","input":{"action":"pix","items":[{"payee":"escola","amount_minor":30000,"description":"excursao"}]}}]}
2
+ {"kind":"assistant_step","reply":"Paguei R$ 300,00 para a Escola Aurora (excursao) dentro da alcada; o recibo esta no terminal."}
@@ -0,0 +1,2 @@
1
+ {"kind":"assistant_step","tool_calls":[{"id":"tc_1","name":"codespar_pay","input":{"action":"pix","items":[{"payee":"escola","amount_minor":40000,"description":"material"}]}}]}
2
+ {"kind":"assistant_step","reply":"Propus R$ 400,00 para a Escola Aurora (material). Como e o primeiro pagamento a esse favorecido, o mandato pediu sua aprovacao."}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * `inspect` through a real process: the section 14.5 rule (`--json` puts valid
3
+ * JSON on stdout and nothing else), the refusal on a run id that is not there,
4
+ * and the HTML file that opens from disk with nothing fetched.
5
+ */
6
+ import { spawnSync } from "node:child_process";
7
+ import { mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
8
+ import { tmpdir } from "node:os";
9
+ import { join, resolve } from "node:path";
10
+ import { beforeAll, describe, expect, it } from "vitest";
11
+
12
+ const AGENT_DIR = resolve(import.meta.dirname, "..");
13
+ const NODE = process.execPath;
14
+ const BIN = resolve(AGENT_DIR, "../../packages/agent-runtime/bin.mjs");
15
+
16
+ function run(command: string, args: string[], env: Record<string, string>) {
17
+ const result = spawnSync(NODE, [BIN, command, ...args], {
18
+ cwd: AGENT_DIR,
19
+ env: { ...process.env, ANTHROPIC_API_KEY: "", CODESPAR_API_KEY: "", ...env },
20
+ encoding: "utf8",
21
+ timeout: 60_000,
22
+ });
23
+ return { code: result.status, stdout: result.stdout, stderr: result.stderr };
24
+ }
25
+
26
+ describe("codespar-agent inspect", () => {
27
+ let env: Record<string, string>;
28
+ let runId: string;
29
+ let runs: string;
30
+
31
+ beforeAll(() => {
32
+ const stateDir = mkdtempSync(join(tmpdir(), "bills-inspect-"));
33
+ runs = join(stateDir, "runs");
34
+ env = { BILLS_STATE_DIR: stateDir, BILLS_RUNS_DIR: runs };
35
+ const paid = run("start", ["--input", "pague a escola de outubro", "--approve", "--json", "--now", "2026-09-23T14:00:00-03:00"], env);
36
+ expect(paid.code).toBe(0);
37
+ runId = (JSON.parse(paid.stdout.trim()) as { run_id: string }).run_id;
38
+ });
39
+
40
+ it("--json puts valid JSON on stdout and nothing else", () => {
41
+ const out = run("inspect", [runId, "--json"], env);
42
+ expect(out.code).toBe(0);
43
+ const lines = out.stdout.split("\n").filter(Boolean);
44
+ expect(lines).toHaveLength(1);
45
+ const report = JSON.parse(lines[0]!) as {
46
+ run: { run_id: string; mode: string; rail: string; mandate_id: string; mandate_version: number };
47
+ executions: Array<{ final_state: string; approval: { items_hash: string } | null; transitions: Array<{ to: string; actor: string }>; attempts: Array<{ idempotency_key: string; answer: { status: string; receipt_id: string } }> }>;
48
+ receipts: Array<{ receipt_id: string }>;
49
+ verify: { present: boolean; note: string };
50
+ };
51
+ expect(report.run).toMatchObject({ run_id: runId, mode: "human", rail: "stub" });
52
+ expect(report.run.mandate_version).toBe(1);
53
+ const execution = report.executions[0]!;
54
+ expect(execution.final_state).toBe("settled");
55
+ expect(execution.transitions.map((t) => t.to)).toEqual(["awaiting_approval", "approved", "executing", "settled"]);
56
+ expect(execution.approval?.items_hash).toMatch(/^sha256:/);
57
+ expect(execution.attempts[0]?.idempotency_key).toMatch(/^idk_/);
58
+ expect(execution.attempts[0]?.answer.status).toBe("settled");
59
+ expect(report.receipts).toHaveLength(1);
60
+ expect(report.verify.present).toBe(false);
61
+ });
62
+
63
+ it("the default rendering is for a person and names the approver, the hash and the receipt", () => {
64
+ const out = run("inspect", [runId], env);
65
+ expect(out.code).toBe(0);
66
+ expect(out.stdout).toContain(runId);
67
+ expect(out.stdout).toContain("bills-agent@0.1.0");
68
+ expect(out.stdout).toContain("items_hash sha256:");
69
+ expect(out.stdout).toContain("rail says");
70
+ expect(out.stdout).toContain("receipts/rcpt_");
71
+ // Masked exactly as the bundle masks it.
72
+ expect(out.stdout).toContain("fi***@escola-aurora.example.com.br");
73
+ expect(out.stdout).not.toContain("financeiro@escola-aurora.example.com.br");
74
+ });
75
+
76
+ it("refuses a run id that is not there, cleanly, and says which ones are", () => {
77
+ const out = run("inspect", ["run_does_not_exist"], env);
78
+ expect(out.code).toBe(1);
79
+ expect(out.stdout).toBe("");
80
+ expect(out.stderr).toContain("no proof bundle for run run_does_not_exist");
81
+ expect(out.stderr).toContain(runId);
82
+ expect(out.stderr).not.toMatch(/at Object\.|at async |Error:/);
83
+ });
84
+
85
+ it("refuses with a usage line when no run id is given", () => {
86
+ const out = run("inspect", [], env);
87
+ expect(out.code).toBe(2);
88
+ expect(out.stdout).toBe("");
89
+ expect(out.stderr).toContain("usage: npm run inspect <run-id>");
90
+ });
91
+
92
+ it("--html writes one standalone file: no script, no external src or href", () => {
93
+ const target = join(mkdtempSync(join(tmpdir(), "bills-inspect-html-")), "run.html");
94
+ const out = run("inspect", [runId, "--html", target], env);
95
+ expect(out.code).toBe(0);
96
+ const html = readFileSync(target, "utf8");
97
+ expect(html).toMatch(/^<!doctype html>/);
98
+ expect(html).not.toMatch(/<script/i);
99
+ expect(html).not.toMatch(/(src|href)\s*=\s*["']?(https?:)?\/\//i);
100
+ expect(html).not.toMatch(/https?:\/\//i);
101
+ expect(html).not.toMatch(/<link\b/i);
102
+ expect(html).toContain(runId);
103
+ expect(html).toContain("items_hash sha256:");
104
+ expect(html).not.toContain("financeiro@escola-aurora.example.com.br");
105
+ });
106
+
107
+ it("a bundle a killed run left half-written is a message, not a stack trace", () => {
108
+ const broken = join(runs, "run_broken_bundle");
109
+ mkdirSync(join(broken, "receipts"), { recursive: true });
110
+ writeFileSync(join(broken, "approval.json"), "{ this is not json");
111
+ const out = run("inspect", ["run_broken_bundle"], env);
112
+ expect(out.code).toBe(1);
113
+ expect(out.stdout).toBe("");
114
+ expect(out.stderr).toContain("could not be read");
115
+ expect(out.stderr).not.toMatch(/at Object\.|at async |\.ts:\d+/);
116
+ rmSync(broken, { recursive: true, force: true });
117
+ });
118
+
119
+ it("works on any bundle in the runs folder, whatever produced it", () => {
120
+ const ids = readdirSync(runs, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
121
+ expect(ids).toContain(runId);
122
+ for (const id of ids) expect(run("inspect", [id, "--json"], env).code).toBe(0);
123
+ });
124
+ });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Which model runs: the Anthropic provider only with a real key. The
3
+ * `.env.example` placeholder, an empty value and an absent variable all
4
+ * mean "replay the recorded transcript", so a copied example never calls
5
+ * Anthropic with a fake key (issue #8).
6
+ */
7
+ import { describe, expect, it } from "vitest";
8
+ import { ANTHROPIC_KEY_PLACEHOLDER, resolveProvider } from "@codespar/agent-runtime";
9
+
10
+ const REAL_LOOKING_KEY = ["sk", "ant", "x".repeat(24)].join("-");
11
+
12
+ describe("resolveProvider", () => {
13
+ it("treats the .env.example placeholder, an empty value and an absent variable as no key", () => {
14
+ expect(resolveProvider({ ANTHROPIC_API_KEY: ANTHROPIC_KEY_PLACEHOLDER }, undefined)).toBe("replay");
15
+ expect(resolveProvider({ ANTHROPIC_API_KEY: "" }, undefined)).toBe("replay");
16
+ expect(resolveProvider({ ANTHROPIC_API_KEY: " " }, undefined)).toBe("replay");
17
+ expect(resolveProvider({}, undefined)).toBe("replay");
18
+ });
19
+
20
+ it("picks Anthropic on a real-looking key, and an explicit --provider wins over the environment", () => {
21
+ expect(resolveProvider({ ANTHROPIC_API_KEY: REAL_LOOKING_KEY }, undefined)).toBe("anthropic");
22
+ expect(resolveProvider({ ANTHROPIC_API_KEY: REAL_LOOKING_KEY }, "replay")).toBe("replay");
23
+ expect(resolveProvider({}, "anthropic")).toBe("anthropic");
24
+ });
25
+ });
@@ -2,7 +2,8 @@ import { existsSync, mkdtempSync, readFileSync, readdirSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { describe, expect, it } from "vitest";
5
- import { checkScenario, listScenarios, loadScenario, runScenario, type ScenarioRun } from "../src/scenarios.js";
5
+ import { checkScenario, listScenarios, loadScenario, runScenario, type ScenarioRun } from "@codespar/agent-runtime";
6
+ import { agent } from "../src/kit.js";
6
7
 
7
8
  const runsDir = mkdtempSync(join(tmpdir(), "bills-runs-"));
8
9
 
@@ -10,14 +11,14 @@ describe("section 12: scenario packs, on the replay provider", () => {
10
11
  const required = ["happy-path", "cap-exceeded", "beneficiary-not-allowed", "prompt-injection", "escalated-above-threshold", "mandate-revoked"];
11
12
 
12
13
  it("ships every scenario the spec asks for", () => {
13
- for (const name of required) expect(listScenarios()).toContain(name);
14
+ for (const name of required) expect(listScenarios(agent)).toContain(name);
14
15
  });
15
16
 
16
17
  for (const name of required) {
17
- const scenario = loadScenario(name);
18
+ const scenario = loadScenario(agent, name);
18
19
  for (const mode of scenario.modes) {
19
20
  it(`${name} [${mode}] ends in the states the pack declares`, async () => {
20
- const run = await runScenario(scenario, { mode, runsDir });
21
+ const run = await runScenario(agent, scenario, { mode, runsDir });
21
22
  const check = checkScenario(scenario, run);
22
23
  expect(check.failures).toEqual([]);
23
24
  expect(check.ok).toBe(true);
@@ -36,9 +37,9 @@ describe("section 12: scenario packs, on the replay provider", () => {
36
37
  }
37
38
 
38
39
  it("happy-path: the same trail and the same receipts in human and in mandate", async () => {
39
- const scenario = loadScenario("happy-path");
40
- const human = await runScenario(scenario, { mode: "human", runsDir });
41
- const mandate = await runScenario(scenario, { mode: "mandate", runsDir });
40
+ const scenario = loadScenario(agent, "happy-path");
41
+ const human = await runScenario(agent, scenario, { mode: "human", runsDir });
42
+ const mandate = await runScenario(agent, scenario, { mode: "mandate", runsDir });
42
43
  expect(human.executions.map((e) => e.trail)).toEqual(mandate.executions.map((e) => e.trail));
43
44
  expect(normalizeReceipts(human)).toEqual(normalizeReceipts(mandate));
44
45
  // In human, the artifact is a person's; in mandate the person still decided because the amount escalated.
@@ -51,9 +52,9 @@ describe("section 12: scenario packs, on the replay provider", () => {
51
52
 
52
53
  it("nothing reaches executing without an approval artifact carrying its items_hash", async () => {
53
54
  for (const name of required) {
54
- const scenario = loadScenario(name);
55
+ const scenario = loadScenario(agent, name);
55
56
  for (const mode of scenario.modes) {
56
- const run = await runScenario(scenario, { mode, runsDir });
57
+ const run = await runScenario(agent, scenario, { mode, runsDir });
57
58
  const approvalPath = join(run.bundle_dir, "approval.json");
58
59
  const artifacts = existsSync(approvalPath) ? (JSON.parse(readFileSync(approvalPath, "utf8")) as Array<{ execution_id: string; items_hash: string }>) : [];
59
60
  for (const e of run.executions) {
@@ -5,7 +5,6 @@
5
5
  },
6
6
  "include": [
7
7
  "src/**/*.ts",
8
- "channels/**/*.ts",
9
8
  "test/**/*.ts"
10
9
  ]
11
10
  }
@@ -7,20 +7,23 @@
7
7
  "type": "module",
8
8
  "workspaces": [
9
9
  "packages/agent-core",
10
+ "packages/agent-runtime",
10
11
  "agents/bills-agent"
11
12
  ],
12
13
  "scripts": {
13
14
  "start": "npm start --workspace=agents/bills-agent --",
14
15
  "check": "npm run check --workspaces --if-present --",
15
16
  "test": "vitest run --pool=forks --maxWorkers=1",
16
- "typecheck": "tsc --noEmit -p packages/agent-core/tsconfig.json && tsc --noEmit -p agents/bills-agent/tsconfig.json",
17
+ "typecheck": "tsc --noEmit -p packages/agent-core/tsconfig.json && tsc --noEmit -p packages/agent-runtime/tsconfig.json && tsc --noEmit -p agents/bills-agent/tsconfig.json",
17
18
  "approve": "npm run approve --workspace=agents/bills-agent --",
18
19
  "consent": "npm run consent --workspace=agents/bills-agent --",
19
20
  "deny": "npm run deny --workspace=agents/bills-agent --",
20
21
  "eval": "npm run eval --workspace=agents/bills-agent --",
22
+ "inspect": "npm run inspect --workspace=agents/bills-agent --",
21
23
  "reconcile": "npm run reconcile --workspace=agents/bills-agent --",
22
24
  "rerun": "npm run rerun --workspace=agents/bills-agent --",
23
- "resume": "npm run resume --workspace=agents/bills-agent --"
25
+ "resume": "npm run resume --workspace=agents/bills-agent --",
26
+ "verify": "npm run verify --workspace=agents/bills-agent --"
24
27
  },
25
28
  "devDependencies": {
26
29
  "@types/node": "22.20.4",
@@ -2,6 +2,8 @@
2
2
 
3
3
  The primitives every CodeSpar starter-kit agent inherits (spec v5.1.1, section 4): the execution state machine, the approval artifact, the `agent.yaml` manifest, `escalate_above`, `actor`, local state in SQLite, the proof bundle, the rail contract and the two providers.
4
4
 
5
+ This package is the decisions. The RUNNER around them — the terminal channel, `codespar-agent start|consent|approve|deny|resume|rerun|reconcile|poll|webhook|check|eval`, the setup that wires this package to an agent directory, and the scenario and adversarial runners — is [`@codespar/agent-runtime`](../agent-runtime), which depends on this one and is what an agent's `package.json` scripts call (#13). Nothing here knows an agent's name.
6
+
5
7
  ## The state machine, and what the types do and do not prove
6
8
 
7
9
  `transition(execution, to, input)` accepts only a `to` that the table in `state-machine.ts` lists for `execution.state`. On a **narrowed** value (`Execution<"drafted">`, `Execution<"executing">`, ...) a transition outside the table is a compile error, and `test/transitions.type-test.ts` keeps that true with `@ts-expect-error` lines that `tsc` refuses to leave unused. An **un-narrowed** `Execution` (the union, which is what a row read back from SQLite is) compiles for any target; the engine narrows with casts at its call sites. So the guard that always holds is the runtime one: `transition()` throws `IllegalTransitionError` on any pair the table does not list, whatever the static type said. The type test proves the table is closed; the runtime check enforces it.
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@anthropic-ai/sdk": "0.128.0",
20
- "@codespar/sdk": "0.16.4",
20
+ "@codespar/sdk": "0.16.6",
21
21
  "yaml": "2.9.1",
22
22
  "zod": "3.25.76"
23
23
  }
@@ -79,10 +79,12 @@ export class CodeSparChargeRail implements PaymentRail {
79
79
 
80
80
  async pay(payment: RailPayment): Promise<RailOutcome> {
81
81
  if (!payment.due_date) return { status: "failed", code: "due_date_required", message: "a receivable needs a due_date; the immediate Pix charge cannot be read back or replayed" };
82
+ if (!payment.consumer_id) return { status: "failed", code: "consumer_id_required", message: "a receivable settles into the principal's account; the policy names no consumer_id" };
82
83
  let view: ChargeView;
83
84
  try {
84
85
  view = (await this.api.post("/v1/charges", {
85
86
  body: {
87
+ consumer_id: payment.consumer_id,
86
88
  amount: payment.amount_minor / 100,
87
89
  currency: payment.currency,
88
90
  method: "boleto",
@@ -108,15 +110,32 @@ export class CodeSparChargeRail implements PaymentRail {
108
110
  return outcome.status === "in_flight" ? { status: "uncertain", code: "issuance_unconfirmed", message: "the create answered no readable state" } : outcome;
109
111
  }
110
112
 
111
- async lookup(attemptId: string, _payment: RailPayment): Promise<RailLookup> {
113
+ /**
114
+ * By the charge id when the create handed one back; by our idempotency key only when it did not (the create's answer was lost).
115
+ * The route's doc says the read accepts the caller's key as the id; on staging (2026-09-23) it answered `charge_not_found` for
116
+ * the key and the charge for the id, so the id comes first and the key is the fallback, not the other way round.
117
+ */
118
+ async lookup(attemptId: string, _payment: RailPayment, transactionId?: string): Promise<RailLookup> {
119
+ const byId = transactionId ? await this.read(transactionId) : { kind: "missing" as const };
120
+ if (byId.kind === "view") return outcomeOf(byId.view);
121
+ if (byId.kind === "in_flight") return { status: "in_flight" };
122
+ if (byId.kind === "uncertain") return byId.outcome;
123
+ const byKey = await this.read(attemptId);
124
+ if (byKey.kind === "view") return outcomeOf(byKey.view);
125
+ if (byKey.kind === "in_flight") return { status: "in_flight" };
126
+ if (byKey.kind === "uncertain") return byKey.outcome;
127
+ return undefined;
128
+ }
129
+
130
+ private async read(chargeRef: string): Promise<{ kind: "view"; view: ChargeView } | { kind: "missing" } | { kind: "in_flight" } | { kind: "uncertain"; outcome: Extract<RailOutcome, { status: "uncertain" }> }> {
112
131
  try {
113
- const view = (await this.api.get("/v1/charges/{chargeId}", { path: { chargeId: attemptId } })) as ChargeView;
114
- return outcomeOf(view);
132
+ const view = (await this.api.get("/v1/charges/{chargeId}", { path: { chargeId: chargeRef } })) as ChargeView;
133
+ return { kind: "view", view };
115
134
  } catch (err) {
116
135
  const failure = describeApiError(err);
117
- if (failure.status === 404) return undefined;
118
- if (failure.status === 409) return { status: "in_flight" };
119
- return { status: "uncertain", code: failure.code, message: failure.message };
136
+ if (failure.status === 404) return { kind: "missing" };
137
+ if (failure.status === 409) return { kind: "in_flight" };
138
+ return { kind: "uncertain", outcome: { status: "uncertain", code: failure.code, message: failure.message } };
120
139
  }
121
140
  }
122
141
 
@@ -133,6 +152,8 @@ export class CodeSparChargeRail implements PaymentRail {
133
152
  payment: { amount_minor: view.amount_minor, payee: null, attempt_id: chargeId, money_moved: false, sandbox: true, at: raw.settled_at ?? new Date().toISOString() },
134
153
  chain: null,
135
154
  receipt_sig: null,
155
+ receipt_sig_ed25519: null,
156
+ receipt_sig_kid: null,
136
157
  actor,
137
158
  raw: view,
138
159
  };
@@ -18,6 +18,16 @@ import type { PaymentRail, RailLookup, RailOutcome, RailPayment, RailReceipt } f
18
18
  import type { Actor } from "../types.js";
19
19
  import { describeApiError, isUncertain } from "./client.js";
20
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
+
21
31
  export class CodeSparRail implements PaymentRail {
22
32
  readonly name = "codespar" as const;
23
33
 
@@ -89,6 +99,12 @@ export class CodeSparRail implements PaymentRail {
89
99
  },
90
100
  chain: r.chain,
91
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),
92
108
  actor,
93
109
  raw: r,
94
110
  };