@codespar/cli 0.18.1 → 0.20.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 (558) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/login.js +52 -12
  3. package/dist/commands/login.js.map +1 -1
  4. package/dist/index.js +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/surface.js +31 -13
  7. package/dist/surface.js.map +1 -1
  8. package/package.json +1 -1
  9. package/templates/bills-agent/README.md +2 -2
  10. package/templates/bills-agent/agents/bills-agent/.env.example +2 -2
  11. package/templates/bills-agent/agents/bills-agent/README.md +25 -18
  12. package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +13 -3
  13. package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -1
  14. package/templates/bills-agent/agents/bills-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  15. package/templates/bills-agent/agents/bills-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
  16. package/templates/bills-agent/agents/bills-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  17. package/templates/bills-agent/agents/bills-agent/mandate.example.json +1 -1
  18. package/templates/bills-agent/agents/bills-agent/runbook.md +1 -1
  19. package/templates/bills-agent/agents/bills-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  20. package/templates/bills-agent/agents/bills-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
  21. package/templates/bills-agent/agents/bills-agent/scenarios/escalated-above-threshold.transcript.jsonl +4 -4
  22. package/templates/bills-agent/agents/bills-agent/scenarios/happy-path.transcript.jsonl +1 -1
  23. package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.json +1 -1
  24. package/templates/bills-agent/agents/bills-agent/scenarios/mandate-revoked.transcript.jsonl +4 -4
  25. package/templates/bills-agent/agents/bills-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  26. package/templates/bills-agent/agents/bills-agent/src/bills.ts +1 -1
  27. package/templates/bills-agent/agents/bills-agent/src/kit.ts +15 -28
  28. package/templates/bills-agent/agents/bills-agent/src/modules/embedded-consent.ts +42 -15
  29. package/templates/bills-agent/agents/bills-agent/src/modules/pix-out.ts +21 -3
  30. package/templates/bills-agent/agents/bills-agent/src/strings.ts +68 -0
  31. package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +130 -2
  32. package/templates/bills-agent/agents/bills-agent/test/consent-money.test.ts +25 -0
  33. package/templates/bills-agent/agents/bills-agent/test/dates-and-approval.test.ts +98 -0
  34. package/templates/bills-agent/agents/bills-agent/test/eval-runs.test.ts +81 -0
  35. package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -2
  36. package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +1 -1
  37. package/templates/bills-agent/agents/bills-agent/test/locale.test.ts +161 -0
  38. package/templates/bills-agent/agents/bills-agent/test/mandate-state.test.ts +108 -0
  39. package/templates/bills-agent/agents/bills-agent/test/refused-before-draft.test.ts +81 -0
  40. package/templates/bills-agent/agents/bills-agent/test/replay.test.ts +76 -0
  41. package/templates/bills-agent/agents/bills-agent/test/reply-and-outcome.test.ts +84 -0
  42. package/templates/bills-agent/agents/bills-agent/test/reply-language.test.ts +95 -0
  43. package/templates/bills-agent/agents/bills-agent/test/rerun-and-missing-transcript.test.ts +120 -0
  44. package/templates/bills-agent/agents/bills-agent/test/rerun-world-events.test.ts +55 -0
  45. package/templates/bills-agent/agents/bills-agent/tools.json +1 -1
  46. package/templates/bills-agent/packages/agent-core/README.md +21 -2
  47. package/templates/bills-agent/packages/agent-core/package.json +1 -1
  48. package/templates/bills-agent/packages/agent-core/src/agent.ts +33 -6
  49. package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  50. package/templates/bills-agent/packages/agent-core/src/api/rail.ts +11 -5
  51. package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  52. package/templates/bills-agent/packages/agent-core/src/bundle.ts +2 -0
  53. package/templates/bills-agent/packages/agent-core/src/channels.ts +18 -8
  54. package/templates/bills-agent/packages/agent-core/src/check.ts +25 -3
  55. package/templates/bills-agent/packages/agent-core/src/engine.ts +90 -9
  56. package/templates/bills-agent/packages/agent-core/src/escalate.ts +10 -0
  57. package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
  58. package/templates/bills-agent/packages/agent-core/src/language.ts +52 -0
  59. package/templates/bills-agent/packages/agent-core/src/locale.ts +88 -0
  60. package/templates/bills-agent/packages/agent-core/src/manifest.ts +4 -1
  61. package/templates/bills-agent/packages/agent-core/src/rail.ts +29 -1
  62. package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  63. package/templates/bills-agent/packages/agent-core/src/secrets.ts +53 -8
  64. package/templates/bills-agent/packages/agent-core/src/state-machine.ts +14 -0
  65. package/templates/bills-agent/packages/agent-core/src/strings.ts +175 -0
  66. package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  67. package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  68. package/templates/bills-agent/packages/agent-core/src/types.ts +15 -2
  69. package/templates/bills-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  70. package/templates/bills-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  71. package/templates/bills-agent/packages/agent-core/test/engine.test.ts +23 -0
  72. package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
  73. package/templates/bills-agent/packages/agent-core/test/language.test.ts +40 -0
  74. package/templates/bills-agent/packages/agent-core/test/locale.test.ts +137 -0
  75. package/templates/bills-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  76. package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
  77. package/templates/bills-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  78. package/templates/bills-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  79. package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +49 -0
  80. package/templates/bills-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  81. package/templates/bills-agent/packages/agent-core/test/secrets.test.ts +40 -1
  82. package/templates/bills-agent/packages/agent-runtime/README.md +31 -4
  83. package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  84. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  85. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  86. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  87. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  88. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  89. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  90. package/templates/bills-agent/packages/agent-runtime/src/cli.ts +30 -4
  91. package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  92. package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  93. package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  94. package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  95. package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  96. package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  97. package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  98. package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  99. package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  100. package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  101. package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  102. package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  103. package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  104. package/templates/bills-agent/packages/agent-runtime/src/env.ts +64 -0
  105. package/templates/bills-agent/packages/agent-runtime/src/index.ts +2 -0
  106. package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +81 -10
  107. package/templates/bills-agent/packages/agent-runtime/src/kit.ts +34 -12
  108. package/templates/bills-agent/packages/agent-runtime/src/outcome.ts +118 -0
  109. package/templates/bills-agent/packages/agent-runtime/src/poll.ts +7 -7
  110. package/templates/bills-agent/packages/agent-runtime/src/runs.ts +51 -0
  111. package/templates/bills-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  112. package/templates/bills-agent/packages/agent-runtime/src/setup.ts +75 -5
  113. package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +71 -33
  114. package/templates/bills-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  115. package/templates/bills-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  116. package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  117. package/templates/bills-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  118. package/templates/bills-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  119. package/templates/bills-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  120. package/templates/bills-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  121. package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  122. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  123. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  124. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  125. package/templates/checkout-agent/README.md +2 -2
  126. package/templates/checkout-agent/agents/checkout-agent/.env.example +6 -4
  127. package/templates/checkout-agent/agents/checkout-agent/README.md +16 -8
  128. package/templates/checkout-agent/agents/checkout-agent/SYSTEM_PROMPT.md +17 -7
  129. package/templates/checkout-agent/agents/checkout-agent/agent.yaml +4 -3
  130. package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/README.md +2 -2
  131. package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/templates.json +48 -4
  132. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap-human.json +1 -1
  133. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.json +1 -1
  134. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +1 -1
  135. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.json +1 -1
  136. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  137. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.transcript.jsonl +1 -1
  138. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.json +1 -1
  139. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.transcript.jsonl +1 -1
  140. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.json +1 -1
  141. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  142. package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.transcript.jsonl +1 -1
  143. package/templates/checkout-agent/agents/checkout-agent/package.json +1 -1
  144. package/templates/checkout-agent/agents/checkout-agent/runbook.md +4 -4
  145. package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  146. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.transcript.jsonl +2 -2
  147. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.json +2 -2
  148. package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.transcript.jsonl +2 -2
  149. package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.json +1 -1
  150. package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.transcript.jsonl +2 -2
  151. package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.transcript.jsonl +1 -1
  152. package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.transcript.jsonl +1 -1
  153. package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.transcript.jsonl +2 -2
  154. package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.transcript.jsonl +1 -1
  155. package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.transcript.jsonl +3 -3
  156. package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.json +1 -1
  157. package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.transcript.jsonl +2 -2
  158. package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.transcript.jsonl +1 -1
  159. package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  160. package/templates/checkout-agent/agents/checkout-agent/src/catalog.ts +7 -7
  161. package/templates/checkout-agent/agents/checkout-agent/src/kit.ts +47 -43
  162. package/templates/checkout-agent/agents/checkout-agent/src/modules/bolepix-receivables.ts +20 -12
  163. package/templates/checkout-agent/agents/checkout-agent/src/modules/nfse-invoice.ts +4 -4
  164. package/templates/checkout-agent/agents/checkout-agent/src/modules/storefront-cart.ts +9 -6
  165. package/templates/checkout-agent/agents/checkout-agent/src/pricing.ts +44 -41
  166. package/templates/checkout-agent/agents/checkout-agent/src/strings.ts +179 -0
  167. package/templates/checkout-agent/agents/checkout-agent/test/check.test.ts +4 -1
  168. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/order-marina.transcript.jsonl +1 -1
  169. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/ordered-marina-awaiting-payer.transcript.jsonl +2 -2
  170. package/templates/checkout-agent/agents/checkout-agent/test/fixtures/tap-falar-agora-marina.transcript.jsonl +1 -1
  171. package/templates/checkout-agent/agents/checkout-agent/test/payable-instrument.test.ts +58 -0
  172. package/templates/checkout-agent/agents/checkout-agent/test/pricing.test.ts +2 -2
  173. package/templates/checkout-agent/agents/checkout-agent/test/rerun-unpaid.test.ts +47 -0
  174. package/templates/checkout-agent/agents/checkout-agent/test/scenario-reach-and-seconds.test.ts +55 -0
  175. package/templates/checkout-agent/agents/checkout-agent/test/whatsapp.test.ts +26 -10
  176. package/templates/checkout-agent/agents/checkout-agent/tools.json +1 -1
  177. package/templates/checkout-agent/packages/agent-core/README.md +21 -2
  178. package/templates/checkout-agent/packages/agent-core/package.json +1 -1
  179. package/templates/checkout-agent/packages/agent-core/src/agent.ts +33 -6
  180. package/templates/checkout-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  181. package/templates/checkout-agent/packages/agent-core/src/api/rail.ts +11 -5
  182. package/templates/checkout-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  183. package/templates/checkout-agent/packages/agent-core/src/bundle.ts +2 -0
  184. package/templates/checkout-agent/packages/agent-core/src/channels.ts +18 -8
  185. package/templates/checkout-agent/packages/agent-core/src/check.ts +25 -3
  186. package/templates/checkout-agent/packages/agent-core/src/engine.ts +90 -9
  187. package/templates/checkout-agent/packages/agent-core/src/escalate.ts +10 -0
  188. package/templates/checkout-agent/packages/agent-core/src/index.ts +3 -0
  189. package/templates/checkout-agent/packages/agent-core/src/language.ts +52 -0
  190. package/templates/checkout-agent/packages/agent-core/src/locale.ts +88 -0
  191. package/templates/checkout-agent/packages/agent-core/src/manifest.ts +4 -1
  192. package/templates/checkout-agent/packages/agent-core/src/rail.ts +29 -1
  193. package/templates/checkout-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  194. package/templates/checkout-agent/packages/agent-core/src/secrets.ts +53 -8
  195. package/templates/checkout-agent/packages/agent-core/src/state-machine.ts +14 -0
  196. package/templates/checkout-agent/packages/agent-core/src/strings.ts +175 -0
  197. package/templates/checkout-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  198. package/templates/checkout-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  199. package/templates/checkout-agent/packages/agent-core/src/types.ts +15 -2
  200. package/templates/checkout-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  201. package/templates/checkout-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  202. package/templates/checkout-agent/packages/agent-core/test/engine.test.ts +23 -0
  203. package/templates/checkout-agent/packages/agent-core/test/helpers.ts +1 -1
  204. package/templates/checkout-agent/packages/agent-core/test/language.test.ts +40 -0
  205. package/templates/checkout-agent/packages/agent-core/test/locale.test.ts +137 -0
  206. package/templates/checkout-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  207. package/templates/checkout-agent/packages/agent-core/test/manifest.test.ts +2 -2
  208. package/templates/checkout-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  209. package/templates/checkout-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  210. package/templates/checkout-agent/packages/agent-core/test/receivables.test.ts +49 -0
  211. package/templates/checkout-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  212. package/templates/checkout-agent/packages/agent-core/test/secrets.test.ts +40 -1
  213. package/templates/checkout-agent/packages/agent-runtime/README.md +31 -4
  214. package/templates/checkout-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  215. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  216. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  217. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  218. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  219. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  220. package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  221. package/templates/checkout-agent/packages/agent-runtime/src/cli.ts +30 -4
  222. package/templates/checkout-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  223. package/templates/checkout-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  224. package/templates/checkout-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  225. package/templates/checkout-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  226. package/templates/checkout-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  227. package/templates/checkout-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  228. package/templates/checkout-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  229. package/templates/checkout-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  230. package/templates/checkout-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  231. package/templates/checkout-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  232. package/templates/checkout-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  233. package/templates/checkout-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  234. package/templates/checkout-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  235. package/templates/checkout-agent/packages/agent-runtime/src/env.ts +64 -0
  236. package/templates/checkout-agent/packages/agent-runtime/src/index.ts +2 -0
  237. package/templates/checkout-agent/packages/agent-runtime/src/inspect.ts +81 -10
  238. package/templates/checkout-agent/packages/agent-runtime/src/kit.ts +34 -12
  239. package/templates/checkout-agent/packages/agent-runtime/src/outcome.ts +118 -0
  240. package/templates/checkout-agent/packages/agent-runtime/src/poll.ts +7 -7
  241. package/templates/checkout-agent/packages/agent-runtime/src/runs.ts +51 -0
  242. package/templates/checkout-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  243. package/templates/checkout-agent/packages/agent-runtime/src/setup.ts +75 -5
  244. package/templates/checkout-agent/packages/agent-runtime/src/terminal.ts +71 -33
  245. package/templates/checkout-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  246. package/templates/checkout-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  247. package/templates/checkout-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  248. package/templates/checkout-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  249. package/templates/checkout-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  250. package/templates/checkout-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  251. package/templates/checkout-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  252. package/templates/checkout-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  253. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  254. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  255. package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  256. package/templates/collections-agent/README.md +2 -2
  257. package/templates/collections-agent/agents/collections-agent/.env.example +6 -3
  258. package/templates/collections-agent/agents/collections-agent/README.md +14 -9
  259. package/templates/collections-agent/agents/collections-agent/SYSTEM_PROMPT.md +16 -5
  260. package/templates/collections-agent/agents/collections-agent/agent.yaml +4 -3
  261. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +21 -4
  262. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +49 -5
  263. package/templates/collections-agent/agents/collections-agent/mandate.example.json +1 -1
  264. package/templates/collections-agent/agents/collections-agent/runbook.md +3 -3
  265. package/templates/collections-agent/agents/collections-agent/src/agreements.ts +1 -1
  266. package/templates/collections-agent/agents/collections-agent/src/envelope.ts +15 -13
  267. package/templates/collections-agent/agents/collections-agent/src/kit.ts +38 -35
  268. package/templates/collections-agent/agents/collections-agent/src/modules/bolepix-receivables.ts +16 -8
  269. package/templates/collections-agent/agents/collections-agent/src/strings.ts +91 -0
  270. package/templates/collections-agent/agents/collections-agent/test/ambiguous-charge.test.ts +2 -2
  271. package/templates/collections-agent/agents/collections-agent/test/check.test.ts +4 -1
  272. package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +1 -1
  273. package/templates/collections-agent/agents/collections-agent/test/envelope.test.ts +2 -2
  274. package/templates/collections-agent/agents/collections-agent/test/fixtures/accept-1103.transcript.jsonl +1 -1
  275. package/templates/collections-agent/agents/collections-agent/test/fixtures/tap-emitir-nova-1042.transcript.jsonl +1 -1
  276. package/templates/collections-agent/agents/collections-agent/test/payable-instrument.test.ts +56 -0
  277. package/templates/collections-agent/agents/collections-agent/test/rerun-clock.test.ts +54 -0
  278. package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +69 -2
  279. package/templates/collections-agent/agents/collections-agent/test/whatsapp-status-replies.test.ts +16 -3
  280. package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +16 -4
  281. package/templates/collections-agent/agents/collections-agent/tools.json +2 -2
  282. package/templates/collections-agent/packages/agent-core/README.md +21 -2
  283. package/templates/collections-agent/packages/agent-core/package.json +1 -1
  284. package/templates/collections-agent/packages/agent-core/src/agent.ts +33 -6
  285. package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  286. package/templates/collections-agent/packages/agent-core/src/api/rail.ts +11 -5
  287. package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  288. package/templates/collections-agent/packages/agent-core/src/bundle.ts +2 -0
  289. package/templates/collections-agent/packages/agent-core/src/channels.ts +18 -8
  290. package/templates/collections-agent/packages/agent-core/src/check.ts +25 -3
  291. package/templates/collections-agent/packages/agent-core/src/engine.ts +90 -9
  292. package/templates/collections-agent/packages/agent-core/src/escalate.ts +10 -0
  293. package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
  294. package/templates/collections-agent/packages/agent-core/src/language.ts +52 -0
  295. package/templates/collections-agent/packages/agent-core/src/locale.ts +88 -0
  296. package/templates/collections-agent/packages/agent-core/src/manifest.ts +4 -1
  297. package/templates/collections-agent/packages/agent-core/src/rail.ts +29 -1
  298. package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  299. package/templates/collections-agent/packages/agent-core/src/secrets.ts +53 -8
  300. package/templates/collections-agent/packages/agent-core/src/state-machine.ts +14 -0
  301. package/templates/collections-agent/packages/agent-core/src/strings.ts +175 -0
  302. package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  303. package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  304. package/templates/collections-agent/packages/agent-core/src/types.ts +15 -2
  305. package/templates/collections-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  306. package/templates/collections-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  307. package/templates/collections-agent/packages/agent-core/test/engine.test.ts +23 -0
  308. package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
  309. package/templates/collections-agent/packages/agent-core/test/language.test.ts +40 -0
  310. package/templates/collections-agent/packages/agent-core/test/locale.test.ts +137 -0
  311. package/templates/collections-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  312. package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
  313. package/templates/collections-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  314. package/templates/collections-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  315. package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +49 -0
  316. package/templates/collections-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  317. package/templates/collections-agent/packages/agent-core/test/secrets.test.ts +40 -1
  318. package/templates/collections-agent/packages/agent-runtime/README.md +31 -4
  319. package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  320. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  321. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  322. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  323. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  324. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  325. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  326. package/templates/collections-agent/packages/agent-runtime/src/cli.ts +30 -4
  327. package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  328. package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  329. package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  330. package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  331. package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  332. package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  333. package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  334. package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  335. package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  336. package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  337. package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  338. package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  339. package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  340. package/templates/collections-agent/packages/agent-runtime/src/env.ts +64 -0
  341. package/templates/collections-agent/packages/agent-runtime/src/index.ts +2 -0
  342. package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +81 -10
  343. package/templates/collections-agent/packages/agent-runtime/src/kit.ts +34 -12
  344. package/templates/collections-agent/packages/agent-runtime/src/outcome.ts +118 -0
  345. package/templates/collections-agent/packages/agent-runtime/src/poll.ts +7 -7
  346. package/templates/collections-agent/packages/agent-runtime/src/runs.ts +51 -0
  347. package/templates/collections-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  348. package/templates/collections-agent/packages/agent-runtime/src/setup.ts +75 -5
  349. package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +71 -33
  350. package/templates/collections-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  351. package/templates/collections-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  352. package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  353. package/templates/collections-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  354. package/templates/collections-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  355. package/templates/collections-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  356. package/templates/collections-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  357. package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  358. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  359. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  360. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  361. package/templates/hello-agent/README.md +2 -2
  362. package/templates/hello-agent/agents/hello-agent/README.md +6 -0
  363. package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +27 -13
  364. package/templates/hello-agent/agents/hello-agent/agent.yaml +2 -1
  365. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  366. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  367. package/templates/hello-agent/agents/hello-agent/mandate.example.json +1 -1
  368. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +1 -1
  369. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +1 -1
  370. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +1 -1
  371. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  372. package/templates/hello-agent/agents/hello-agent/src/bills.ts +9 -5
  373. package/templates/hello-agent/agents/hello-agent/src/kit.ts +4 -1
  374. package/templates/hello-agent/agents/hello-agent/tools.json +1 -1
  375. package/templates/hello-agent/packages/agent-core/README.md +21 -2
  376. package/templates/hello-agent/packages/agent-core/package.json +1 -1
  377. package/templates/hello-agent/packages/agent-core/src/agent.ts +33 -6
  378. package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  379. package/templates/hello-agent/packages/agent-core/src/api/rail.ts +11 -5
  380. package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  381. package/templates/hello-agent/packages/agent-core/src/bundle.ts +2 -0
  382. package/templates/hello-agent/packages/agent-core/src/channels.ts +18 -8
  383. package/templates/hello-agent/packages/agent-core/src/check.ts +25 -3
  384. package/templates/hello-agent/packages/agent-core/src/engine.ts +90 -9
  385. package/templates/hello-agent/packages/agent-core/src/escalate.ts +10 -0
  386. package/templates/hello-agent/packages/agent-core/src/index.ts +3 -0
  387. package/templates/hello-agent/packages/agent-core/src/language.ts +52 -0
  388. package/templates/hello-agent/packages/agent-core/src/locale.ts +88 -0
  389. package/templates/hello-agent/packages/agent-core/src/manifest.ts +4 -1
  390. package/templates/hello-agent/packages/agent-core/src/rail.ts +29 -1
  391. package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  392. package/templates/hello-agent/packages/agent-core/src/secrets.ts +53 -8
  393. package/templates/hello-agent/packages/agent-core/src/state-machine.ts +14 -0
  394. package/templates/hello-agent/packages/agent-core/src/strings.ts +175 -0
  395. package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  396. package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  397. package/templates/hello-agent/packages/agent-core/src/types.ts +15 -2
  398. package/templates/hello-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  399. package/templates/hello-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  400. package/templates/hello-agent/packages/agent-core/test/engine.test.ts +23 -0
  401. package/templates/hello-agent/packages/agent-core/test/helpers.ts +1 -1
  402. package/templates/hello-agent/packages/agent-core/test/language.test.ts +40 -0
  403. package/templates/hello-agent/packages/agent-core/test/locale.test.ts +137 -0
  404. package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  405. package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +2 -2
  406. package/templates/hello-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  407. package/templates/hello-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  408. package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +49 -0
  409. package/templates/hello-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  410. package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +40 -1
  411. package/templates/hello-agent/packages/agent-runtime/README.md +31 -4
  412. package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  413. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  414. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  415. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  416. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  417. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  418. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  419. package/templates/hello-agent/packages/agent-runtime/src/cli.ts +30 -4
  420. package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  421. package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  422. package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  423. package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  424. package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  425. package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  426. package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  427. package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  428. package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  429. package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  430. package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  431. package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  432. package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  433. package/templates/hello-agent/packages/agent-runtime/src/env.ts +64 -0
  434. package/templates/hello-agent/packages/agent-runtime/src/index.ts +2 -0
  435. package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +81 -10
  436. package/templates/hello-agent/packages/agent-runtime/src/kit.ts +34 -12
  437. package/templates/hello-agent/packages/agent-runtime/src/outcome.ts +118 -0
  438. package/templates/hello-agent/packages/agent-runtime/src/poll.ts +7 -7
  439. package/templates/hello-agent/packages/agent-runtime/src/runs.ts +51 -0
  440. package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  441. package/templates/hello-agent/packages/agent-runtime/src/setup.ts +75 -5
  442. package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +71 -33
  443. package/templates/hello-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  444. package/templates/hello-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  445. package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  446. package/templates/hello-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  447. package/templates/hello-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  448. package/templates/hello-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  449. package/templates/hello-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  450. package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  451. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  452. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  453. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
  454. package/templates/kits.lock.json +12 -12
  455. package/templates/supplier-payments-agent/README.md +2 -2
  456. package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +2 -2
  457. package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +12 -7
  458. package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +14 -3
  459. package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +2 -1
  460. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +1 -1
  461. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +1 -1
  462. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +1 -1
  463. package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +3 -3
  464. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +1 -1
  465. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +1 -1
  466. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +5 -5
  467. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +1 -1
  468. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +5 -5
  469. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +1 -1
  470. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +1 -1
  471. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +1 -1
  472. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +37 -26
  473. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +41 -14
  474. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +12 -3
  475. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +8 -8
  476. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +75 -10
  477. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/locale.test.ts +101 -0
  478. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/run-outcome.test.ts +127 -0
  479. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +1 -1
  480. package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -2
  481. package/templates/supplier-payments-agent/packages/agent-core/package.json +1 -1
  482. package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +33 -6
  483. package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +15 -1
  484. package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +11 -5
  485. package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +36 -0
  486. package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +2 -0
  487. package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +18 -8
  488. package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +25 -3
  489. package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +90 -9
  490. package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +10 -0
  491. package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +3 -0
  492. package/templates/supplier-payments-agent/packages/agent-core/src/language.ts +52 -0
  493. package/templates/supplier-payments-agent/packages/agent-core/src/locale.ts +88 -0
  494. package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +4 -1
  495. package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +29 -1
  496. package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +30 -2
  497. package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +53 -8
  498. package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +14 -0
  499. package/templates/supplier-payments-agent/packages/agent-core/src/strings.ts +175 -0
  500. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +15 -2
  501. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +7 -4
  502. package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +15 -2
  503. package/templates/supplier-payments-agent/packages/agent-core/test/actor-on-the-wire.test.ts +144 -0
  504. package/templates/supplier-payments-agent/packages/agent-core/test/attempt-replay.test.ts +2 -2
  505. package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +23 -0
  506. package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +1 -1
  507. package/templates/supplier-payments-agent/packages/agent-core/test/language.test.ts +40 -0
  508. package/templates/supplier-payments-agent/packages/agent-core/test/locale.test.ts +137 -0
  509. package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +2 -2
  510. package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +2 -2
  511. package/templates/supplier-payments-agent/packages/agent-core/test/rail-errors.test.ts +74 -0
  512. package/templates/supplier-payments-agent/packages/agent-core/test/receipt-read-verification.test.ts +32 -0
  513. package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +49 -0
  514. package/templates/supplier-payments-agent/packages/agent-core/test/recorded-turns.ts +29 -0
  515. package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +40 -1
  516. package/templates/supplier-payments-agent/packages/agent-runtime/README.md +31 -4
  517. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +4 -2
  518. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +11 -5
  519. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +43 -21
  520. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +3 -0
  521. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +8 -12
  522. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -4
  523. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +12 -9
  524. package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +30 -4
  525. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +18 -2
  526. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +13 -4
  527. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +7 -2
  528. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +11 -13
  529. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +32 -24
  530. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +12 -5
  531. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +83 -10
  532. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +2 -1
  533. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +10 -5
  534. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +48 -17
  535. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +37 -12
  536. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +11 -3
  537. package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +52 -22
  538. package/templates/supplier-payments-agent/packages/agent-runtime/src/env.ts +64 -0
  539. package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +2 -0
  540. package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +81 -10
  541. package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +34 -12
  542. package/templates/supplier-payments-agent/packages/agent-runtime/src/outcome.ts +118 -0
  543. package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +7 -7
  544. package/templates/supplier-payments-agent/packages/agent-runtime/src/runs.ts +51 -0
  545. package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +55 -8
  546. package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +75 -5
  547. package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +71 -33
  548. package/templates/supplier-payments-agent/packages/agent-runtime/test/env-names.test.ts +56 -0
  549. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect-mandate-status.test.ts +80 -0
  550. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +63 -2
  551. package/templates/supplier-payments-agent/packages/agent-runtime/test/outcome.test.ts +72 -0
  552. package/templates/supplier-payments-agent/packages/agent-runtime/test/poll-payer.test.ts +64 -0
  553. package/templates/supplier-payments-agent/packages/agent-runtime/test/rerun-not-replayed.test.ts +46 -0
  554. package/templates/supplier-payments-agent/packages/agent-runtime/test/transition-line.test.ts +29 -0
  555. package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +99 -6
  556. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +8 -0
  557. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +77 -0
  558. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +27 -1
@@ -6,18 +6,29 @@
6
6
  *
7
7
  * `--json` puts machine data on stdout (valid JSON, nothing else) and the
8
8
  * human messages on stderr.
9
+ *
10
+ * A one-shot prints, after the reply, what the run did as the engine counts
11
+ * it (`outcome.ts`), and exits by it: see `EXIT_CODES`.
9
12
  */
13
+ import { statSync } from "node:fs";
10
14
  import { stderr, stdout } from "node:process";
11
15
  import { relative, resolve } from "node:path";
12
- import { NotATestKeyError, declaredReplies, isTestKey, loadManifest, resolveFixedClock, type ApprovalMode, type ChannelName } from "@codespar/agent-core";
16
+ import { CORE_STRINGS, NotATestKeyError, WHATSAPP_LANGUAGE, declaredReplies, loadManifest, parseLocale, resolveLocale, testKeyProblem, resolveFixedClock, type ApprovalMode, type ChannelName, type Locale } from "@codespar/agent-core";
13
17
  import { join } from "node:path";
14
18
  import type { Agent } from "../agent.js";
15
19
  import type { RailKind } from "../kit.js";
16
- import { resolveProvider, resolveRailKind, setup, type ProviderKind } from "../setup.js";
20
+ import { envFileOf, resolveProvider, resolveRailKind, setup, type ProviderKind } from "../setup.js";
17
21
  import { checkScenario, listScenarios, loadScenario, runScenario, scenariosDir } from "../scenarios.js";
18
22
  import { closeTerminal, defaultAsk, handleExecution, interactive } from "../terminal.js";
19
23
  import { loadTemplates, resolveConversation } from "../channels/index.js";
20
24
  import { startWhatsApp, type WhatsAppBackendName } from "./start-whatsapp.js";
25
+ import { outcomeExitCode, refusalLine, sayOutcome } from "../outcome.js";
26
+
27
+ const EXIT_CODES = `exit (--input): 0 nothing failed (settled, already paid, denied, expired or still open: the last line counts each payment); 1 a payment failed or a line was refused before a draft, and 1 wins over 3; 3 nothing failed and an execution of this run was left executing (npm run reconcile). A line an earlier run still holds is open and exits 0.`;
28
+
29
+ function isFile(path: string): boolean {
30
+ return statSync(path, { throwIfNoEntry: false })?.isFile() ?? false;
31
+ }
21
32
 
22
33
  interface Args {
23
34
  input?: string;
@@ -40,6 +51,8 @@ interface Args {
40
51
  conversation?: string;
41
52
  /** Replay the conversation's turns instead of reading them from the keyboard. */
42
53
  scripted: boolean;
54
+ /** The language of what the code prints; absent means agent.yaml's `locale`, else pt-BR. */
55
+ locale?: Locale;
43
56
  help: boolean;
44
57
  }
45
58
 
@@ -92,6 +105,7 @@ export function parseArgs(argv: string[], awaitsPayer: boolean): Args {
92
105
  args.backend = v;
93
106
  } else if (a === "--conversation") args.conversation = next();
94
107
  else if (a === "--scripted") args.scripted = true;
108
+ else if (a === "--locale") args.locale = parseLocale(next());
95
109
  else if (a === "--help" || a === "-h") args.help = true;
96
110
  else throw new Error(`unknown argument ${a}`);
97
111
  }
@@ -109,10 +123,12 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
109
123
  return 2;
110
124
  }
111
125
  if (args.help) {
112
- stderr.write(usage + "\n");
126
+ stderr.write(`${usage}\n${EXIT_CODES}\n`);
113
127
  return 0;
114
128
  }
115
129
  const say = (line: string) => stderr.write(line + "\n");
130
+ // Fixed for the run, and for a conversation: the proposal and its approval are asked in the same language.
131
+ const locale = resolveLocale(args.locale, loadManifest(join(agent.dir, "agent.yaml")).manifest);
116
132
 
117
133
  // A pinned instant makes the guardrails deterministic: the CI runs the fixture inside the declared hours whatever the hour is.
118
134
  let now: (() => Date) | undefined;
@@ -125,12 +141,19 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
125
141
 
126
142
  // Sandbox by construction: a live key dies here, before anything else runs.
127
143
  const railKind = resolveRailKind(process.env, args.rail);
128
- if (railKind === "api" && !isTestKey(process.env["CODESPAR_API_KEY"])) {
129
- say(new NotATestKeyError().message);
144
+ const keyProblem = railKind === "api" ? testKeyProblem(process.env["CODESPAR_API_KEY"]) : undefined;
145
+ if (keyProblem) {
146
+ say(new NotATestKeyError(keyProblem, envFileOf(agent.dir)).message);
147
+ return 1;
148
+ }
149
+
150
+ // A recording that is not there is said by its path, before a mandate is asked for or a run is opened.
151
+ if (args.transcript !== undefined && !isFile(args.transcript)) {
152
+ say(`no transcript at ${args.transcript}`);
130
153
  return 1;
131
154
  }
132
155
 
133
- if (args.scenario) return runScenarioCommand(agent, args, railKind, say);
156
+ if (args.scenario) return runScenarioCommand(agent, args, railKind, locale, say);
134
157
 
135
158
  // A channel is a conversation, so the flags a one-shot and a scenario pack use have no meaning on one.
136
159
  if (args.channel === "whatsapp" && (args.input !== undefined || args.scenario !== undefined)) {
@@ -147,7 +170,7 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
147
170
  }
148
171
 
149
172
  if (agent.kit.ensureMandate) {
150
- const ok = await agent.kit.ensureMandate({ agentDir: agent.dir, argv, say, railKind, oneShot: args.input !== undefined, ask: defaultAsk });
173
+ const ok = await agent.kit.ensureMandate({ agentDir: agent.dir, argv, locale, say, railKind, oneShot: args.input !== undefined, ask: defaultAsk });
151
174
  if (!ok) return 1;
152
175
  }
153
176
 
@@ -159,9 +182,9 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
159
182
  say(err instanceof Error ? err.message : String(err));
160
183
  return 2;
161
184
  }
162
- // A first turn that is a TAP is looked up by the intent the tap stands for, which is what the model is handed.
185
+ // A first turn that is a TAP is looked up by the intent the tap stands for in the run's language, which is what the model is handed.
163
186
  const firstTurn = args.scripted ? conversationScript?.turns[0] : undefined;
164
- const firstInput = args.input ?? firstTurn?.text ?? (firstTurn?.reply ? declaredReplies(loadTemplates(agent)).get(firstTurn.reply.id)?.intent : undefined);
187
+ const firstInput = args.input ?? firstTurn?.text ?? (firstTurn?.reply ? declaredReplies(loadTemplates(agent), WHATSAPP_LANGUAGE[locale]).get(firstTurn.reply.id)?.intent : undefined);
165
188
 
166
189
  // No model: replay the recorded scenario whose first turn is what the person said first.
167
190
  let transcript = args.transcript;
@@ -175,7 +198,7 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
175
198
  }
176
199
  }
177
200
 
178
- const s = setup(agent, { mode: args.mode, rail: railKind, provider, transcript, now, say });
201
+ const s = setup(agent, { mode: args.mode, rail: railKind, provider, transcript, now, say, locale });
179
202
  if (args.payer) s.payer?.behave(args.payer);
180
203
  const approver = { id: args.user ?? s.kit.labels.defaultUser, channel: "terminal" };
181
204
  const startedAt = Date.now();
@@ -207,18 +230,23 @@ export async function start(agent: Agent, argv: string[]): Promise<number> {
207
230
  handleExecution(execution, { setup: s, approver, decision: args.decision ?? "none", say, waitSeconds: args.wait, simulatePayer: args.simulatePayer, ...(args.json ? { tell: say } : {}) }),
208
231
  );
209
232
  const result = await loop.turn(args.input);
210
- const executions = s.engine.list().filter((e) => e.run_id === s.runId);
233
+ // Counted from the engine, printed whatever the reply says: a recorded reply cannot know what this run found.
234
+ const { executions, refusals, outcome, line } = sayOutcome(s, result.not_run);
235
+ // A request refused before a draft left no execution to describe: said here with the engine's own reason, or the terminal would be silent about it.
236
+ for (const refusal of refusals) say(refusalLine(refusal));
211
237
  const payload = s.kit.oneShotPayload({ setup: s, reply: result.reply, toolCalls: result.tool_calls, executions, startedAt });
212
- if (args.json) stdout.write(JSON.stringify(payload) + "\n");
213
- else stdout.write(result.reply + "\n");
214
- return executions.some((e) => e.state === "executing") ? 3 : 0;
238
+ // `run_outcome`, not `outcome`: the payload is the kit's, and a kit may name a field of its own that.
239
+ if (args.json) stdout.write(JSON.stringify({ ...payload, run_outcome: outcome, refused_before_draft: refusals }) + "\n");
240
+ else stdout.write(`${result.reply}\n${line}\n`);
241
+ return outcomeExitCode(outcome, executions);
215
242
  } finally {
216
243
  closeTerminal();
217
244
  s.close();
218
245
  }
219
246
  }
220
247
 
221
- async function runScenarioCommand(agent: Agent, args: Args, railKind: RailKind, say: (l: string) => void): Promise<number> {
248
+ async function runScenarioCommand(agent: Agent, args: Args, railKind: RailKind, locale: Locale, say: (l: string) => void): Promise<number> {
249
+ const text = CORE_STRINGS[locale];
222
250
  const scenario = loadScenario(agent, args.scenario!);
223
251
  const picksRail = agent.kit.scenarioRail === "requested";
224
252
  const rail: RailKind = picksRail ? railKind : "stub";
@@ -237,10 +265,13 @@ async function runScenarioCommand(agent: Agent, args: Args, railKind: RailKind,
237
265
  say: args.json ? () => undefined : say,
238
266
  ...(picksRail ? { tell: args.json ? () => undefined : (l: string) => void stdout.write(l + "\n") } : {}),
239
267
  waitSeconds: args.wait,
268
+ locale,
240
269
  });
241
270
  const check = checkScenario(scenario, run);
242
- for (const reply of run.replies) say(`agente: ${reply}`);
243
- say(check.ok ? `== ok — ${agent.settlement === "await-payer" ? `${run.cycle_seconds}s — ` : ""}bundle em ${relative(process.cwd(), run.bundle_dir)}` : `== FAIL: ${check.failures.join("; ")}`);
271
+ for (const reply of run.replies) say(text.scenarioReply(reply));
272
+ // Seconds are said only where a clock measured them. On the stub the clock is the scenario's, ticking a second per read: its "16s" is a count of reads in a run that took under one.
273
+ const measured = agent.settlement === "await-payer" && run.rail === "api" ? run.cycle_seconds : undefined;
274
+ say(check.ok ? text.scenarioOk(measured, relative(process.cwd(), run.bundle_dir)) : `== FAIL: ${check.failures.join("; ")}`);
244
275
  results.push({ mode, ok: check.ok, failures: check.failures, run });
245
276
  }
246
277
  if (args.json) stdout.write(JSON.stringify({ scenario: scenario.name, ...(picksRail ? { rail } : {}), results }) + "\n");
@@ -18,12 +18,17 @@
18
18
  * party, payee unmasked; checked with no credential at all — or a copy from a
19
19
  * run's `runs/<run-id>/receipts/`, which masks the payee and carries none of
20
20
  * the links. A copy reaches check 2 only with `--from-api`: the tenant's
21
- * `CODESPAR_API_KEY` (the environment, or the `.env` of the agent the copy
22
- * sits in) reads the receipt from the API, in memory, and nothing unmasked is
21
+ * `CODESPAR_API_KEY`, against the deployment `CODESPAR_API_URL` names (each
22
+ * from the environment, or else from the `.env` of the agent the copy sits
23
+ * in), reads the receipt from the API, in memory, and nothing unmasked is
23
24
  * written anywhere. Without it a copy answers `signature_only`, which is the
24
25
  * truth about what a masked copy can prove. The approval artifact of a copy
25
26
  * is the one its `approval_id` names in the run's own `approval.json`.
26
27
  *
28
+ * Of the read, the output carries only `sealed_payment` (`sandbox`,
29
+ * `money_moved`) off a body that bound. The tenant's read still carries
30
+ * `mandate.sig`, a spend credential, and it is never printed.
31
+ *
27
32
  * It is the one command here that does NOT need an agent — `cli.ts`
28
33
  * dispatches it before it looks for an `agent.yaml` — because the file it
29
34
  * reads has usually been copied off the machine that produced it.
@@ -40,6 +45,7 @@ import { stderr, stdout } from "node:process";
40
45
  import {
41
46
  DEFAULT_BASE_URL,
42
47
  DEFAULT_RECEIPT_KEYS_URL,
48
+ NotATestKeyError,
43
49
  VERDICT_EXIT_CODES,
44
50
  copyDisagreesWithRead,
45
51
  createCodeSparClient,
@@ -55,7 +61,8 @@ import {
55
61
  type ReceiptVerification,
56
62
  } from "@codespar/agent-core";
57
63
  import { findAgentDir } from "../agent.js";
58
- import { readDotEnv } from "../setup.js";
64
+ import { readAgentEnv } from "../env.js";
65
+ import { envFileOf } from "../setup.js";
59
66
 
60
67
  const USAGE =
61
68
  "usage: npm run verify <receipt-file> [--json] [--keys <key-set.json> | --url <https://.../.well-known/codespar-receipt-keys.json>] [--approval <approval.json> [--approval-id <apr_...>]] [--from-api]";
@@ -109,7 +116,7 @@ export async function verify(argv: string[]): Promise<number> {
109
116
  say(`the key set is public and needs no credential; its default is ${DEFAULT_RECEIPT_KEYS_URL}`);
110
117
  say("--keys reads a saved copy of that document instead, so the check runs with no network at all");
111
118
  say("the receipt file is the API's read (GET /v1/consumers/receipts/{id}), whose body is recomputed against the signed chain, or a run's copy, which proves the signature only");
112
- say("--from-api reads a run's copy from the API with CODESPAR_API_KEY (in memory, nothing written), so its body and its approval are checked too; the key set then defaults to that deployment's");
119
+ say("--from-api reads a run's copy from the API with CODESPAR_API_KEY (in memory, nothing written), so its body and its approval are checked too; the key set then defaults to that deployment's. CODESPAR_API_KEY and CODESPAR_API_URL come from the environment, or else from the .env of the agent the copy sits in; the CodeSpar CLI's name CODESPAR_BASE_URL is read too, and the two must agree");
113
120
  say("--approval holds a v4 receipt's sealed approval link against an approval artifact (a run's copy uses its own approval.json)");
114
121
  return 0;
115
122
  } else if (a.startsWith("-")) {
@@ -139,6 +146,20 @@ export async function verify(argv: string[]): Promise<number> {
139
146
  const receipt = readJson(args.receiptFile, say);
140
147
  if (receipt === undefined) return 2;
141
148
 
149
+ // Before the deployment is chosen, not only before the key is read: a
150
+ // staging key in that `.env` sits next to the staging URL, and a read sent
151
+ // to production with it is a 401 (#66). Only `--from-api` touches it; the
152
+ // other paths are the verifier who holds nothing.
153
+ const agentDir = args.fromApi ? findAgentDir(dirname(resolve(args.receiptFile))) : undefined;
154
+ // `--from-api` is also the one path that reads the deployment and the project, so it is the one that reconciles the CLI's names for them; a check against `--keys` or the default key set holds no opinion on either. Two names that disagree are a usage error (2), never 1: 1 means the receipt does not verify.
155
+ if (args.fromApi) {
156
+ const disagreement = readAgentEnv(agentDir);
157
+ if (disagreement) {
158
+ say(`${disagreement.message}\n${USAGE}`);
159
+ return 2;
160
+ }
161
+ }
162
+
142
163
  // The read and the key set must come from ONE deployment: the recipe that
143
164
  // binds the body is the key document's, and a staging read checked under
144
165
  // production's document is the §47 trap again.
@@ -161,14 +182,14 @@ export async function verify(argv: string[]): Promise<number> {
161
182
  if (keysDocument === undefined) return 2;
162
183
  }
163
184
 
164
- const report = await check(receipt, args, apiBase, approval, keysDocument);
185
+ const report = await check(receipt, args, apiBase, agentDir, approval, keysDocument);
165
186
  if (args.json) stdout.write(JSON.stringify(report) + "\n");
166
187
  else stdout.write(render(report));
167
188
  say(report.message);
168
189
  return VERDICT_EXIT_CODES[report.verdict];
169
190
  }
170
191
 
171
- async function check(receipt: unknown, args: Args, apiBase: string, approval: ApprovalClaim | undefined, keysDocument: unknown): Promise<ReceiptVerification> {
192
+ async function check(receipt: unknown, args: Args, apiBase: string, agentDir: string | undefined, approval: ApprovalClaim | undefined, keysDocument: unknown): Promise<ReceiptVerification> {
172
193
  // Answered before the network is touched, as before: an unsigned or
173
194
  // malformed file needs no key set, and fetching one to check a signature
174
195
  // that is not there would turn an offline answer into an outage.
@@ -202,7 +223,7 @@ async function check(receipt: unknown, args: Args, apiBase: string, approval: Ap
202
223
  return signatureOnly(signature, "read_required", "this is a run's copy, which masks the payee and carries none of the chain's links. Recompute from the API's read: run this again with --from-api (the tenant's key, read-only, nothing written), or verify the read itself");
203
224
  }
204
225
 
205
- const read = await readFromApi(signed.fields.receipt_id, args.receiptFile!, apiBase);
226
+ const read = await readFromApi(signed.fields.receipt_id, apiBase, agentDir);
206
227
  if (!read.ok) return signatureOnly(signature, "read_unavailable", `the API's read of it could not be fetched (${read.detail}), so nothing is proved and nothing is disproved about the body`);
207
228
  const differs = copyDisagreesWithRead(receipt as Record<string, unknown>, read.body);
208
229
  if (differs.includes("chain")) {
@@ -229,18 +250,18 @@ function unreachable(receiptId: string, label: string, message: string): Receipt
229
250
  /**
230
251
  * The receipt as the API reads it, for a copy, with the tenant's key. The key
231
252
  * is the environment's, or the `.env` of the agent the copy sits in — the
232
- * same place `npm start` reads it from — and only a `csk_test_` key is
233
- * accepted, like everywhere else in this repository.
253
+ * same place `npm start` reads it from, loaded by `verify` before it chose
254
+ * `apiBase` — and only a `csk_test_` key is accepted, like everywhere else in
255
+ * this repository.
234
256
  */
235
- async function readFromApi(receiptId: string, receiptFile: string, apiBase: string): Promise<{ ok: true; body: Record<string, unknown> } | { ok: false; detail: string }> {
236
- const agentDir = findAgentDir(dirname(resolve(receiptFile)));
237
- if (agentDir) readDotEnv(agentDir);
257
+ async function readFromApi(receiptId: string, apiBase: string, agentDir: string | undefined): Promise<{ ok: true; body: Record<string, unknown> } | { ok: false; detail: string }> {
238
258
  try {
239
259
  const api = createCodeSparClient({ apiKey: process.env["CODESPAR_API_KEY"], baseUrl: apiBase, projectId: process.env["CODESPAR_PROJECT_ID"], timeoutMs: 15_000 });
240
260
  const body: unknown = await api.get("/v1/consumers/receipts/{id}", { path: { id: receiptId } });
241
261
  if (!isReceiptRead(body)) return { ok: false, detail: "the API answered something that is not a receipt read" };
242
262
  return { ok: true, body };
243
263
  } catch (err) {
264
+ if (err instanceof NotATestKeyError) return { ok: false, detail: new NotATestKeyError(err.problem, agentDir ? envFileOf(agentDir) : undefined).message };
244
265
  const failure = describeApiError(err);
245
266
  return { ok: false, detail: `${failure.code}: ${failure.message}` };
246
267
  }
@@ -325,6 +346,10 @@ function render(report: ReceiptVerification): string {
325
346
  lines.push(` approval ${a.status}: sealed ${a.sealed.items_hash}${a.sealed.batch_hash ? ` batch ${a.sealed.batch_hash}` : ""}`);
326
347
  if (a.artifact) lines.push(` artifact ${a.artifact.approval_id} ${a.artifact.items_hash}${a.artifact.batch_hash ? ` batch ${a.artifact.batch_hash}` : ""}`);
327
348
  }
349
+ if (report.sealed_payment) {
350
+ const shown = (v: boolean | null) => (v === null ? "not sealed" : String(v));
351
+ lines.push(` payment sandbox ${shown(report.sealed_payment.sandbox)}, money_moved ${shown(report.sealed_payment.money_moved)}`);
352
+ }
328
353
  lines.push(` reason ${report.reason}`);
329
354
  return lines.join("\n") + "\n";
330
355
  }
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { stderr, stdout } from "node:process";
9
9
  import { envName, type Agent } from "../agent.js";
10
- import { setup } from "../setup.js";
10
+ import { inLocaleOf, localeFlag, setup } from "../setup.js";
11
11
  import { announceOutcome, followUp } from "../terminal.js";
12
12
  import { startWebhookServer } from "../webhook.js";
13
13
 
@@ -15,14 +15,22 @@ export async function webhook(agent: Agent, argv: string[]): Promise<number> {
15
15
  const port = Number(argv.includes("--port") ? argv[argv.indexOf("--port") + 1] : process.env[envName(agent, "WEBHOOK_PORT")] ?? "8787");
16
16
  const secret = argv.includes("--secret") ? argv[argv.indexOf("--secret") + 1] : process.env[envName(agent, "TRIGGER_SECRET")];
17
17
  const say = (l: string) => stderr.write(l + "\n");
18
- const s = setup(agent, { say, runId: `run_webhook_${Date.now().toString(36)}` });
18
+ let locale;
19
+ try {
20
+ locale = localeFlag(argv);
21
+ } catch (err) {
22
+ say(err instanceof Error ? err.message : String(err));
23
+ return 2;
24
+ }
25
+ const s = setup(agent, { say, runId: `run_webhook_${Date.now().toString(36)}`, locale });
19
26
  const server = startWebhookServer(
20
27
  port,
21
28
  {
22
29
  engine: s.engine,
23
30
  secret,
24
31
  onClosed: async (execution) => {
25
- announceOutcome(execution, s, (l) => void stdout.write(l + "\n"));
32
+ // Told in the locale of the run that issued the charge, whatever this receiver's own is.
33
+ announceOutcome(execution, inLocaleOf(s, execution), (l) => void stdout.write(l + "\n"));
26
34
  await followUp(execution, s, say);
27
35
  },
28
36
  },
@@ -3,9 +3,32 @@
3
3
  * example mandate, the generic console words, and no tools. A read-only agent
4
4
  * spreads this and adds its handlers; a payer or a collector replaces the rail.
5
5
  */
6
- import { StubRail, loadMandate, type Execution } from "@codespar/agent-core";
6
+ import { StubRail, formatBRL, isReplayedSettlement, loadMandate, railErrorOf, type Execution, type LocaleTable } from "@codespar/agent-core";
7
7
  import { relative } from "node:path";
8
- import type { AgentKit } from "./kit.js";
8
+ import type { AgentKit, KitStrings } from "./kit.js";
9
+ import type { Setup } from "./setup.js";
10
+
11
+ /**
12
+ * The lines a payment execution reads as on the console, in the run's locale:
13
+ * the default kit's, and the bills and supplier agents', which pay the same
14
+ * way and describe it the same way.
15
+ */
16
+ export function describePayment(execution: Execution, setup: Setup): string[] {
17
+ const text = setup.coreStrings;
18
+ const words = setup.strings;
19
+ const lines: string[] = [];
20
+ lines.push(` ${text.execution} ${execution.id}: ${execution.state}${execution.reason ? ` (${execution.reason})` : ""}`);
21
+ for (const item of execution.items) lines.push(` - ${item.beneficiary}: ${formatBRL(item.amount, setup.locale)}${item.description ? ` — ${item.description}` : ""}`);
22
+ lines.push(` ${text.totalByCore}: ${formatBRL(execution.total, setup.locale)}`);
23
+ if (execution.escalation) lines.push(` ${text.escalatedBy}: ${execution.escalation.trigger} — ${execution.escalation.detail}`);
24
+ if (execution.blocking_reasons.length) lines.push(` ${text.blocked(execution.blocking_reasons.join(", "), words.notAuthorized)}`);
25
+ if (execution.detail && execution.state !== "awaiting_approval") lines.push(` ${execution.detail}`);
26
+ if (isReplayedSettlement(execution)) lines.push(` ${text.replayedSettlement}`);
27
+ for (const outcome of execution.outcomes) {
28
+ if (outcome.receipt_id) lines.push(` ${words.receiptWord}: ${relative(process.cwd(), `${setup.bundle.dir}/receipts/${outcome.receipt_id}.json`)}`);
29
+ }
30
+ return lines;
31
+ }
9
32
 
10
33
  export function formatMinor(minor: number): string {
11
34
  const sign = minor < 0 ? "-" : "";
@@ -13,28 +36,45 @@ export function formatMinor(minor: number): string {
13
36
  return `${sign}R$ ${Math.floor(abs / 100).toLocaleString("pt-BR")},${String(abs % 100).padStart(2, "0")}`;
14
37
  }
15
38
 
39
+ export const DEFAULT_STRINGS: LocaleTable<KitStrings> = {
40
+ "pt-BR": {
41
+ mandateWord: "mandato",
42
+ receiptWord: "recibo",
43
+ intro: 'Diga o que precisa. Ctrl+D ou "sair" encerra.',
44
+ prompt: "> ",
45
+ approveQuestion: " Aprovar? [s/N] ",
46
+ uncertainDispatch: " desfecho desconhecido no trilho; rode `npm run resume` para reconciliar (nunca repita a operação)",
47
+ notAuthorized: "o mandato não autoriza",
48
+ },
49
+ en: {
50
+ mandateWord: "mandate",
51
+ receiptWord: "receipt",
52
+ intro: 'Say what you need. Ctrl+D or "exit" ends.',
53
+ prompt: "> ",
54
+ approveQuestion: " Approve? [y/N] ",
55
+ uncertainDispatch: " outcome unknown on the rail; run `npm run resume` to reconcile (never repeat the operation)",
56
+ notAuthorized: "the mandate does not authorize it",
57
+ },
58
+ };
59
+
16
60
  export const defaultKit: AgentKit = {
17
61
  settlement: "immediate",
18
62
  scenarioRail: "stub",
19
63
  labels: {
20
64
  defaultUser: "usr_terminal",
21
65
  evalUser: "usr_demo_titular",
22
- mandateWord: "mandato",
23
- receiptWord: "recibo",
24
- intro: 'Diga o que precisa. Ctrl+D ou "sair" encerra.',
25
- prompt: "> ",
26
- approveQuestion: " Aprovar? [s/N] ",
27
- uncertainDispatch: " desfecho desconhecido no trilho; rode `npm run resume` para reconciliar (nunca repita a operacao)",
28
66
  missingReceiptKind: "receipt_missing_locally",
29
67
  missingReceiptDetail: (receiptId, runId) => `receipt ${receiptId} is not in runs/${runId}/receipts`,
30
68
  stillExecuting: (e) => `${e.id}: still executing — ${e.detail}; nothing was re-sent`,
31
69
  },
70
+ strings: DEFAULT_STRINGS,
32
71
  usage: (manifest) => `${manifest.manifest.name}
33
72
  npm start interactive terminal
34
73
  npm start -- --input "..." one turn (add --approve/--deny to decide, --json for machine output)
35
74
  npm start -- --scenario <name> run a scenario pack (see scenarios/)
36
75
  options: --mode human|mandate --provider anthropic|replay --transcript <file> --rail stub|api --user <id> --json
37
- --now <ISO 8601> pin the run to that instant; env CODESPAR_AGENT_NOW is the same thing`,
76
+ --now <ISO 8601> pin the run to that instant; env CODESPAR_AGENT_NOW is the same thing
77
+ --locale pt-BR|en the language of what the code prints; default: agent.yaml \`locale\`, else pt-BR`,
38
78
  buildRail: (ctx) => {
39
79
  // A read-only agent has no rail to reach: the stub answers offline, whatever key the environment carries.
40
80
  const killAfterDispatch = ctx.envVar("KILL_AFTER_DISPATCH") === "1" ? { afterDispatch: () => process.exit(137) } : {};
@@ -45,19 +85,7 @@ options: --mode human|mandate --provider anthropic|replay --transcript <file>
45
85
  };
46
86
  },
47
87
  handlers: () => ({}),
48
- describeExecution: (execution, setup) => {
49
- const lines: string[] = [];
50
- lines.push(` execucao ${execution.id}: ${execution.state}${execution.reason ? ` (${execution.reason})` : ""}`);
51
- for (const item of execution.items) lines.push(` - ${item.beneficiary}: ${formatMinor(item.amount)}${item.description ? ` — ${item.description}` : ""}`);
52
- lines.push(` total (calculado pelo core): ${formatMinor(execution.total)}`);
53
- if (execution.escalation) lines.push(` escalado por: ${execution.escalation.trigger} — ${execution.escalation.detail}`);
54
- if (execution.blocking_reasons.length) lines.push(` bloqueado: ${execution.blocking_reasons.join(", ")} — o mandato nao autoriza; nao ha o que aprovar`);
55
- if (execution.detail && execution.state !== "awaiting_approval") lines.push(` ${execution.detail}`);
56
- for (const outcome of execution.outcomes) {
57
- if (outcome.receipt_id) lines.push(` recibo: ${relative(process.cwd(), `${setup.bundle.dir}/receipts/${outcome.receipt_id}.json`)}`);
58
- }
59
- return lines;
60
- },
88
+ describeExecution: (execution, setup) => describePayment(execution, setup),
61
89
  oneShotPayload: ({ setup: s, reply, toolCalls, executions }) => ({
62
90
  run_id: s.runId,
63
91
  agent: `${s.manifest.manifest.name}@${s.manifest.manifest.version}`,
@@ -71,11 +99,13 @@ options: --mode human|mandate --provider anthropic|replay --transcript <file>
71
99
  id: e.id,
72
100
  state: e.state,
73
101
  reason: e.reason ?? null,
102
+ rail_error: railErrorOf(e),
74
103
  escalation: e.escalation ?? null,
75
104
  total_minor: e.total,
76
105
  items: e.items.map((i) => ({ beneficiary: i.beneficiary, amount_minor: i.amount })),
77
106
  approval_id: e.approval_id ?? null,
78
107
  receipt_ids: e.outcomes.filter((o) => o.receipt_id).map((o) => o.receipt_id),
108
+ replayed: isReplayedSettlement(e),
79
109
  })),
80
110
  receipts: s.bundle.listReceipts().map((f) => relative(process.cwd(), `${s.bundle.dir}/receipts/${f}`)),
81
111
  bundle_dir: relative(process.cwd(), s.bundle.dir),
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Two names for the same two settings. The kit reads `CODESPAR_API_URL` and
3
+ * `CODESPAR_PROJECT_ID`; the CodeSpar CLI (`@codespar/cli`) reads
4
+ * `CODESPAR_BASE_URL` and `CODESPAR_PROJECT`. A shell prepared for one of them
5
+ * left the other on its default, production, with nothing said: a staging key
6
+ * then meets the wrong deployment.
7
+ *
8
+ * The kit takes the CLI's names as aliases of its own, and a command that
9
+ * talks to the API refuses to start when the two disagree. Only the
10
+ * environment and the agent's `.env` are read: the CLI's own config file
11
+ * (`~/.codespar/config.json`, what `codespar login` writes) is not.
12
+ */
13
+ import { readDotEnv } from "./setup.js";
14
+
15
+ const PAIRS: ReadonlyArray<{ kit: string; cli: string; same: (a: string, b: string) => boolean }> = [
16
+ { kit: "CODESPAR_API_URL", cli: "CODESPAR_BASE_URL", same: (a, b) => a.replace(/\/+$/, "") === b.replace(/\/+$/, "") },
17
+ { kit: "CODESPAR_PROJECT_ID", cli: "CODESPAR_PROJECT", same: (a, b) => a === b },
18
+ ];
19
+
20
+ export class EnvNamesDisagreeError extends Error {
21
+ constructor(kit: string, kitValue: string, cli: string, cliValue: string) {
22
+ super(`${kit}=${kitValue} and ${cli}=${cliValue} disagree. The kit reads ${kit} and the CodeSpar CLI reads ${cli}; they must name the same thing. Set one of them, or both to the same value.`);
23
+ this.name = "EnvNamesDisagreeError";
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Makes the two names of each pair say one thing: whichever is set fills the
29
+ * other, and two that are set and differ throw. Both are left set, so a later
30
+ * reader of either name, and a later `.env`, finds the pair already decided.
31
+ * An empty value counts as unset, as it does in the CLI.
32
+ */
33
+ export function reconcileEnvNames(env: NodeJS.ProcessEnv = process.env): void {
34
+ for (const { kit, cli, same } of PAIRS) {
35
+ const kitValue = env[kit]?.trim() || undefined;
36
+ const cliValue = env[cli]?.trim() || undefined;
37
+ if (kitValue && cliValue && !same(kitValue, cliValue)) throw new EnvNamesDisagreeError(kit, kitValue, cli, cliValue);
38
+ const value = kitValue ?? cliValue;
39
+ if (value !== undefined) env[kit] = env[cli] = value;
40
+ }
41
+ }
42
+
43
+ /**
44
+ * The agent's `.env` under the rule `readDotEnv` already has, extended to the
45
+ * aliases: what the shell exported wins, and the file fills only what is
46
+ * unset. The shell is reconciled first, so a name it set under either spelling
47
+ * closes the pair before the file is read; then the file's own names are.
48
+ *
49
+ * It returns the disagreement instead of throwing it: only a command that is
50
+ * about to use the URL or the project should stop on it.
51
+ */
52
+ export function readAgentEnv(agentDir: string | undefined): EnvNamesDisagreeError | undefined {
53
+ try {
54
+ reconcileEnvNames();
55
+ if (agentDir) readDotEnv(agentDir);
56
+ reconcileEnvNames();
57
+ return undefined;
58
+ } catch (err) {
59
+ if (!(err instanceof EnvNamesDisagreeError)) throw err;
60
+ // The shell disagreed with itself before the file was read: the file is still owed, for the key it may hold.
61
+ if (agentDir) readDotEnv(agentDir);
62
+ return err;
63
+ }
64
+ }
@@ -2,6 +2,7 @@ export * from "./agent.js";
2
2
  export * from "./kit.js";
3
3
  export * from "./default-kit.js";
4
4
  export * from "./setup.js";
5
+ export * from "./runs.js";
5
6
  export * from "./terminal.js";
6
7
  export * from "./channels/index.js";
7
8
  export * from "./poll.js";
@@ -10,4 +11,5 @@ export * from "./scenarios.js";
10
11
  export * from "./adversarial.js";
11
12
  export * from "./inspect.js";
12
13
  export { main } from "./cli.js";
14
+ export { checkStrings } from "./commands/check.js";
13
15
  export { pollWhatsApp, type PollWhatsAppOptions } from "./commands/poll-whatsapp.js";