@codespar/cli 0.17.0 → 0.18.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.
- package/README.md +1 -0
- package/package.json +1 -1
- package/templates/bills-agent/README.md +1 -1
- package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
- package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
- package/templates/bills-agent/agents/bills-agent/README.md +6 -5
- package/templates/bills-agent/agents/bills-agent/src/modules/embedded-consent.ts +5 -4
- package/templates/bills-agent/packages/agent-core/README.md +14 -1
- package/templates/bills-agent/packages/agent-core/package.json +1 -1
- package/templates/bills-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/bills-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/bills-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/bills-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/bills-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/bills-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/bills-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/bills-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/bills-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/bills-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/bills-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/bills-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/bills-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/bills-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/bills-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/bills-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/bills-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/bills-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/bills-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/bills-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/bills-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/bills-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/bills-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/bills-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/bills-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/bills-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/bills-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/bills-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/bills-agent/packages/agent-runtime/README.md +12 -0
- package/templates/bills-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/bills-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/bills-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/bills-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/bills-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/checkout-agent/LICENSE +21 -0
- package/templates/checkout-agent/README.md +28 -0
- package/templates/checkout-agent/_gitignore +10 -0
- package/templates/checkout-agent/agents/checkout-agent/.env.example +5 -0
- package/templates/checkout-agent/agents/checkout-agent/AGENTS.md +20 -0
- package/templates/checkout-agent/agents/checkout-agent/CLAUDE.md +20 -0
- package/templates/checkout-agent/agents/checkout-agent/README.md +94 -0
- package/templates/checkout-agent/agents/checkout-agent/SYSTEM_PROMPT.md +36 -0
- package/templates/checkout-agent/agents/checkout-agent/agent.yaml +30 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/README.md +28 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-beatriz.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-marina-retomada.json +10 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/pedido-marina.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/channels/whatsapp/templates.json +49 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap-human.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/coupon-unknown.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.json +26 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/false-authority.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/false-authority.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/fractioning.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/model-total.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/model-total.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/payment-claimed.transcript.jsonl +7 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.json +12 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/price-injected.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.json +13 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/prompt-injection.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped-human.json +16 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped-human.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/quantity-swapped.transcript.jsonl +8 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/adversarial/webhook-replay.json +11 -0
- package/templates/checkout-agent/agents/checkout-agent/evals/eval.yaml +11 -0
- package/templates/checkout-agent/agents/checkout-agent/guardrails.json +25 -0
- package/templates/checkout-agent/agents/checkout-agent/mandate.example.json +28 -0
- package/templates/checkout-agent/agents/checkout-agent/package.json +33 -0
- package/templates/checkout-agent/agents/checkout-agent/runbook.md +19 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.json +42 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cap-exceeded.json +32 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cap-exceeded.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.json +61 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-recomposed.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.json +61 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/cart-replaced.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.json +36 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/charge-expired.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.json +23 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/coupon-unknown.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.json +72 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/escalated-above-threshold.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.json +15 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/happy-path.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.json +23 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/item-unavailable.transcript.jsonl +3 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.json +42 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/mandate-revoked.transcript.jsonl +12 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/nfse-failed.json +14 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/nfse-failed.transcript.jsonl +9 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.json +34 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/payment-claimed.transcript.jsonl +7 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.json +33 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/price-injected.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.json +32 -0
- package/templates/checkout-agent/agents/checkout-agent/scenarios/prompt-injection.transcript.jsonl +4 -0
- package/templates/checkout-agent/agents/checkout-agent/src/catalog.ts +92 -0
- package/templates/checkout-agent/agents/checkout-agent/src/kit.ts +338 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/bolepix-receivables.ts +179 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/nfse-invoice.ts +374 -0
- package/templates/checkout-agent/agents/checkout-agent/src/modules/storefront-cart.ts +220 -0
- package/templates/checkout-agent/agents/checkout-agent/src/pricing.ts +297 -0
- package/templates/checkout-agent/agents/checkout-agent/test/adversarial.test.ts +117 -0
- package/templates/checkout-agent/agents/checkout-agent/test/check.test.ts +67 -0
- package/templates/checkout-agent/agents/checkout-agent/test/cli.test.ts +169 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/order-marina.transcript.jsonl +5 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/ordered-marina-awaiting-payer.transcript.jsonl +6 -0
- package/templates/checkout-agent/agents/checkout-agent/test/fixtures/tap-falar-agora-marina.transcript.jsonl +2 -0
- package/templates/checkout-agent/agents/checkout-agent/test/nfse.test.ts +170 -0
- package/templates/checkout-agent/agents/checkout-agent/test/pricing.test.ts +138 -0
- package/templates/checkout-agent/agents/checkout-agent/test/scenarios.test.ts +113 -0
- package/templates/checkout-agent/agents/checkout-agent/test/whatsapp.test.ts +171 -0
- package/templates/checkout-agent/agents/checkout-agent/tools.json +68 -0
- package/templates/checkout-agent/agents/checkout-agent/tsconfig.json +10 -0
- package/templates/checkout-agent/package.json +38 -0
- package/templates/checkout-agent/packages/agent-core/README.md +34 -0
- package/templates/checkout-agent/packages/agent-core/package.json +24 -0
- package/templates/checkout-agent/packages/agent-core/src/agent.ts +163 -0
- package/templates/checkout-agent/packages/agent-core/src/api/charge-rail.ts +195 -0
- package/templates/checkout-agent/packages/agent-core/src/api/client.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/api/mandate-status.ts +74 -0
- package/templates/checkout-agent/packages/agent-core/src/api/rail.ts +153 -0
- package/templates/checkout-agent/packages/agent-core/src/api/sandbox-payer.ts +43 -0
- package/templates/checkout-agent/packages/agent-core/src/approval.ts +135 -0
- package/templates/checkout-agent/packages/agent-core/src/bundle.ts +191 -0
- package/templates/checkout-agent/packages/agent-core/src/channels.ts +186 -0
- package/templates/checkout-agent/packages/agent-core/src/check.ts +276 -0
- package/templates/checkout-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/checkout-agent/packages/agent-core/src/engine.ts +1074 -0
- package/templates/checkout-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/checkout-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/checkout-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/checkout-agent/packages/agent-core/src/hash.ts +118 -0
- package/templates/checkout-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/checkout-agent/packages/agent-core/src/index.ts +34 -0
- package/templates/checkout-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/checkout-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/checkout-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/checkout-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/checkout-agent/packages/agent-core/src/rail.ts +186 -0
- package/templates/checkout-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/checkout-agent/packages/agent-core/src/receipt-verification.ts +577 -0
- package/templates/checkout-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/checkout-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/checkout-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/checkout-agent/packages/agent-core/src/state-machine.ts +157 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/mandate-status.ts +58 -0
- package/templates/checkout-agent/packages/agent-core/src/stubs/rail.ts +209 -0
- package/templates/checkout-agent/packages/agent-core/src/tools.ts +66 -0
- package/templates/checkout-agent/packages/agent-core/src/types.ts +187 -0
- package/templates/checkout-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/checkout-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/checkout-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/checkout-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/checkout-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/checkout-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/checkout-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/checkout-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/checkout-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/checkout-agent/packages/agent-core/test/helpers.ts +142 -0
- package/templates/checkout-agent/packages/agent-core/test/mandate-status.test.ts +229 -0
- package/templates/checkout-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/checkout-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/checkout-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/checkout-agent/packages/agent-core/test/receivables.test.ts +416 -0
- package/templates/checkout-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/checkout-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/checkout-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/checkout-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/checkout-agent/packages/agent-runtime/README.md +80 -0
- package/templates/checkout-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/checkout-agent/packages/agent-runtime/package.json +23 -0
- package/templates/checkout-agent/packages/agent-runtime/src/adversarial.ts +199 -0
- package/templates/checkout-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/types.ts +173 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +459 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +216 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +350 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +180 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +120 -0
- package/templates/checkout-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +127 -0
- package/templates/checkout-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +367 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/poll.ts +145 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/resume.ts +49 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +134 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/start.ts +248 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/verify.ts +330 -0
- package/templates/checkout-agent/packages/agent-runtime/src/commands/webhook.ts +40 -0
- package/templates/checkout-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/checkout-agent/packages/agent-runtime/src/index.ts +13 -0
- package/templates/checkout-agent/packages/agent-runtime/src/inspect.ts +801 -0
- package/templates/checkout-agent/packages/agent-runtime/src/kit.ts +229 -0
- package/templates/checkout-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/checkout-agent/packages/agent-runtime/src/scenarios.ts +274 -0
- package/templates/checkout-agent/packages/agent-runtime/src/setup.ts +239 -0
- package/templates/checkout-agent/packages/agent-runtime/src/terminal.ts +263 -0
- package/templates/checkout-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/checkout-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/checkout-agent/packages/agent-runtime/test/verify-cli.test.ts +329 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +277 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-session.test.ts +167 -0
- package/templates/checkout-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/checkout-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/checkout-agent/scripts/whatsapp-emulator.mjs +84 -0
- package/templates/checkout-agent/tsconfig.base.json +16 -0
- package/templates/checkout-agent/vitest.config.ts +12 -0
- package/templates/collections-agent/README.md +6 -1
- package/templates/collections-agent/agents/collections-agent/README.md +12 -8
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +8 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042-retomada.json +10 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +27 -1
- package/templates/collections-agent/agents/collections-agent/src/kit.ts +2 -0
- package/templates/collections-agent/agents/collections-agent/src/modules/bolepix-receivables.ts +12 -2
- package/templates/collections-agent/agents/collections-agent/test/ambiguous-charge.test.ts +55 -0
- package/templates/collections-agent/agents/collections-agent/test/fixtures/tap-emitir-nova-1042.transcript.jsonl +2 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +12 -6
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-status-replies.test.ts +148 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +5 -0
- package/templates/collections-agent/package.json +1 -0
- package/templates/collections-agent/packages/agent-core/README.md +14 -1
- package/templates/collections-agent/packages/agent-core/package.json +1 -1
- package/templates/collections-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/collections-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/collections-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/collections-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/collections-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/collections-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/collections-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/collections-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/collections-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/collections-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/collections-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/collections-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/collections-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/collections-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/collections-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/collections-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/collections-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/collections-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/collections-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/collections-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/collections-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/collections-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/collections-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/collections-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/collections-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/collections-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/collections-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/collections-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/collections-agent/packages/agent-runtime/README.md +12 -0
- package/templates/collections-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/collections-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/collections-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/collections-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/collections-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/collections-agent/scripts/whatsapp-emulator.mjs +84 -0
- package/templates/hello-agent/README.md +1 -1
- package/templates/hello-agent/packages/agent-core/README.md +14 -1
- package/templates/hello-agent/packages/agent-core/package.json +1 -1
- package/templates/hello-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/hello-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/hello-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/hello-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/hello-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/hello-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/hello-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/hello-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/hello-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/hello-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/hello-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/hello-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/hello-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/hello-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/hello-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/hello-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/hello-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/hello-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/hello-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/hello-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/hello-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/hello-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/hello-agent/packages/agent-runtime/README.md +12 -0
- package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/hello-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/hello-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/hello-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/kits.lock.json +29 -6
- package/templates/supplier-payments-agent/README.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +11 -9
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +1 -1
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +67 -20
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +504 -5
- package/templates/supplier-payments-agent/packages/agent-core/README.md +14 -1
- package/templates/supplier-payments-agent/packages/agent-core/package.json +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +39 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +54 -34
- package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +28 -5
- package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +28 -12
- package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +62 -26
- package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +3 -18
- package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +14 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +35 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +49 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +25 -2
- package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +235 -46
- package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +57 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +2 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/quote.ts +50 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +89 -4
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-chain.ts +270 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +194 -18
- package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +1 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +10 -1
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +4 -3
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +100 -32
- package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +17 -6
- package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +54 -1
- package/templates/supplier-payments-agent/packages/agent-core/test/approval-seal.test.ts +233 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/attempt-replay.test.ts +265 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/composition.test.ts +204 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/production-receipt-keys.json +1 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +4 -1
- package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +85 -9
- package/templates/supplier-payments-agent/packages/agent-core/test/quote.test.ts +198 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-chain.test.ts +220 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-read-verification.test.ts +197 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +103 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/README.md +12 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +32 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +53 -4
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +123 -22
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +30 -20
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +146 -21
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +40 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +8 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +16 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +70 -20
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +2 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +8 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +3 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +6 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +239 -38
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +3 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +1 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +5 -1
- package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +25 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +8 -2
- package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +13 -3
- package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +127 -18
- package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +211 -9
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +32 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-status-replies.test.ts +182 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +0 -204
package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What the emulator does, measured rather than assumed — and what it does NOT
|
|
3
|
-
* do, which is the more useful half.
|
|
4
|
-
*
|
|
5
|
-
* These run against `dyvit-wa-sim` (https://github.com/fabianocruz/whatsapp-simulator,
|
|
6
|
-
* MIT) at the version `scripts/whatsapp-emulator.mjs` pins. They SKIP when it is
|
|
7
|
-
* not listening, so `npm test` is green on a machine that never started it; the
|
|
8
|
-
* CI starts it, and `npm run whatsapp:gate` fails loudly rather than skipping,
|
|
9
|
-
* so nothing important hides behind a skip.
|
|
10
|
-
*
|
|
11
|
-
* Two kinds of assertion live here and they are not the same thing.
|
|
12
|
-
*
|
|
13
|
-
* What the emulator gets RIGHT, which our adapter depends on: the Cloud API
|
|
14
|
-
* response shape, the signed webhook, the controllable clock. If one of these
|
|
15
|
-
* breaks, our channel breaks.
|
|
16
|
-
*
|
|
17
|
-
* What the emulator does NOT do, which our channel has to cover itself. Those
|
|
18
|
-
* assertions are written to FAIL the day the emulator closes the gap — which
|
|
19
|
-
* is what we want, because the pin means it can only change when we move it,
|
|
20
|
-
* and the failure is the notification. They are a spec for the repo's owner,
|
|
21
|
-
* not a complaint: `docs/OPEN_QUESTIONS.md` §46 carries the same list in
|
|
22
|
-
* prose with the payloads.
|
|
23
|
-
*/
|
|
24
|
-
import { describe, expect, it } from "vitest";
|
|
25
|
-
import { EmulatorDriver } from "../src/channels/whatsapp/emulator.js";
|
|
26
|
-
import { buildSendRequest, type CloudApiConfig } from "../src/channels/whatsapp/cloud-api.js";
|
|
27
|
-
|
|
28
|
-
const URL_BASE = process.env["WHATSAPP_SIM_URL"] ?? "http://127.0.0.1:4290";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Probed at MODULE level, not in a `beforeAll`: `describe.skipIf` is read when
|
|
32
|
-
* the file is collected, which is before any hook has run, so a flag set in a
|
|
33
|
-
* hook would skip every case on a machine where the emulator is up.
|
|
34
|
-
*/
|
|
35
|
-
const up = await (async () => {
|
|
36
|
-
try {
|
|
37
|
-
return (await fetch(`${URL_BASE}/health`, { signal: AbortSignal.timeout(2000) })).ok;
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
})();
|
|
42
|
-
if (!up) process.stderr.write(`[whatsapp] no emulator at ${URL_BASE}; its integration cases are skipped. Start it with \`npm run whatsapp:emulator\`.\n`);
|
|
43
|
-
|
|
44
|
-
/** A fresh phone-number id per case, because the emulator keys a conversation on it. */
|
|
45
|
-
const pnid = () => `9${String(Math.floor(Math.random() * 1e11)).padStart(11, "0")}`;
|
|
46
|
-
const TO = "5511987654321";
|
|
47
|
-
|
|
48
|
-
const config = (phoneNumberId: string): CloudApiConfig => ({
|
|
49
|
-
baseUrl: URL_BASE,
|
|
50
|
-
phoneNumberId,
|
|
51
|
-
accessToken: "emulator",
|
|
52
|
-
verifyToken: "emulator",
|
|
53
|
-
appSecret: "dev",
|
|
54
|
-
apiVersion: "v22.0",
|
|
55
|
-
webhookPort: 0,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
async function send(phoneNumberId: string, body: Parameters<typeof buildSendRequest>[2]) {
|
|
59
|
-
const request = buildSendRequest(config(phoneNumberId), `+${TO}`, body);
|
|
60
|
-
if ("unsupported" in request) return { status: 0, unsupported: request.unsupported, body: null as unknown };
|
|
61
|
-
const response = await fetch(request.url, { method: request.method, headers: request.headers, body: request.body });
|
|
62
|
-
return { status: response.status, unsupported: null, body: (await response.json()) as Record<string, unknown> };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function raw(path: string, init?: RequestInit) {
|
|
66
|
-
const response = await fetch(`${URL_BASE}${path}`, init);
|
|
67
|
-
return { status: response.status, body: (await response.json().catch(() => null)) as Record<string, unknown> | null };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
describe.skipIf(!up)("what our adapter depends on, and the emulator provides", () => {
|
|
71
|
-
it("answers our text send with the Cloud API's own response shape", async () => {
|
|
72
|
-
const id = pnid();
|
|
73
|
-
const result = await send(id, { kind: "text", text: "Oi, Joana!" });
|
|
74
|
-
expect(result.status).toBe(200);
|
|
75
|
-
expect(result.body).toMatchObject({ messaging_product: "whatsapp" });
|
|
76
|
-
const messages = (result.body as { messages: Array<{ id: string; message_status: string }> }).messages;
|
|
77
|
-
expect(messages[0]!.id).toMatch(/^wamid\./);
|
|
78
|
-
expect(messages[0]!.message_status).toBe("accepted");
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("takes the Pix copy-and-paste as a plain text message: the string that pays goes through unchanged", async () => {
|
|
82
|
-
const brcode = "00020126580014br.gov.bcb.pix0136stub-chg_abc5204000053039865802BR5909CODESPAR6009SAO PAULO62070503***6304STUB";
|
|
83
|
-
const result = await send(pnid(), { kind: "instrument", instrument: "pix_copy_paste", value: brcode });
|
|
84
|
-
expect(result.status).toBe(200);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("takes a template with its body parameters", async () => {
|
|
88
|
-
const result = await send(pnid(), { kind: "template", template: "cobranca_lembrete", language: "pt_BR", variables: ["Joana"] });
|
|
89
|
-
expect(result.status).toBe(200);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("has a conversation clock we can pin and move, which is the only way a 24h window ever closes in a replay", async () => {
|
|
93
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
94
|
-
const pinned = (await driver.pin(new Date("2026-09-23T17:00:00.000Z"))) as { now: string };
|
|
95
|
-
expect(pinned.now).toBe("2026-09-23T17:00:00.000Z");
|
|
96
|
-
const moved = (await driver.advanceHours(26)) as { now: string };
|
|
97
|
-
expect(Date.parse(moved.now) - Date.parse(pinned.now)).toBeGreaterThanOrEqual(26 * 3600 * 1000);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("delivers an inbound message as a webhook our own parser reads", async () => {
|
|
101
|
-
const id = pnid();
|
|
102
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
103
|
-
await driver.inbound({ phoneNumberId: id, from: `+${TO}`, text: "oi, recebi a mensagem" });
|
|
104
|
-
const { body } = await raw("/_sim/webhooks");
|
|
105
|
-
const deliveries = (body as { deliveries: Array<{ body: unknown }> }).deliveries;
|
|
106
|
-
const mine = deliveries.map((d) => d.body).filter((b) => JSON.stringify(b).includes(id));
|
|
107
|
-
expect(mine.length).toBeGreaterThan(0);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* The gaps. Each one is the exact payload that failed, so the assertion doubles
|
|
113
|
-
* as the report. They are written against the PINNED sha: a green run here
|
|
114
|
-
* means the gap is still open, and a red one means it was closed and our own
|
|
115
|
-
* cover for it can be reconsidered.
|
|
116
|
-
*/
|
|
117
|
-
describe.skipIf(!up)("what the emulator does not do, measured", () => {
|
|
118
|
-
it("GAP: accepts a free-form message outside the 24h window that Meta refuses with 131047 — and it already knows", async () => {
|
|
119
|
-
const id = pnid();
|
|
120
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
121
|
-
await driver.pin(new Date("2026-09-23T17:00:00.000Z"));
|
|
122
|
-
await driver.inbound({ phoneNumberId: id, from: `+${TO}`, text: "oi" });
|
|
123
|
-
expect((await send(id, { kind: "text", text: "dentro da janela" })).status).toBe(200);
|
|
124
|
-
|
|
125
|
-
await driver.advanceHours(26);
|
|
126
|
-
const outside = await send(id, { kind: "text", text: "Recebemos, acordo quitado." });
|
|
127
|
-
// The real Cloud API answers 400 with error 131047 and sends nothing.
|
|
128
|
-
expect(outside.status).toBe(200);
|
|
129
|
-
|
|
130
|
-
// And this is what makes it a one-line fix rather than a feature: the
|
|
131
|
-
// pricing engine has ALREADY decided the message is invalid there.
|
|
132
|
-
const state = (await raw(`/_sim/state?key=${id}:${TO}`)).body as {
|
|
133
|
-
messages: Array<{ id: string }>;
|
|
134
|
-
priced: { byMessageId: Record<string, { reasonCode: string }> };
|
|
135
|
-
};
|
|
136
|
-
const last = state.messages[state.messages.length - 1]!;
|
|
137
|
-
expect(state.priced.byMessageId[last.id]!.reasonCode).toBe("INVALID_NON_TEMPLATE_OUTSIDE_CSW");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("GAP: has no way to redeliver or reorder a webhook, so duplicate and out-of-order delivery cannot be driven", async () => {
|
|
141
|
-
for (const path of ["/_sim/replay", "/_sim/webhooks/replay", "/_sim/redeliver"]) {
|
|
142
|
-
const { status } = await raw(path, { method: "POST", headers: { "content-type": "application/json" }, body: "{}" });
|
|
143
|
-
expect(status, path).toBe(404);
|
|
144
|
-
}
|
|
145
|
-
// `GET /_sim/webhooks` is a read-only log; nothing re-dispatches from it.
|
|
146
|
-
const { status, body } = await raw("/_sim/webhooks");
|
|
147
|
-
expect(status).toBe(200);
|
|
148
|
-
expect(Array.isArray((body as { deliveries: unknown[] }).deliveries)).toBe(true);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("GAP: an inbound interactive reply degrades to an empty text message, so a debtor cannot tap a button", async () => {
|
|
152
|
-
const id = pnid();
|
|
153
|
-
const { status, body } = await raw("/_sim/inbound", {
|
|
154
|
-
method: "POST",
|
|
155
|
-
headers: { "content-type": "application/json" },
|
|
156
|
-
body: JSON.stringify({
|
|
157
|
-
phone_number_id: id,
|
|
158
|
-
from: `+${TO}`,
|
|
159
|
-
type: "interactive",
|
|
160
|
-
interactive: { type: "button_reply", button_reply: { id: "avista", title: "À vista" } },
|
|
161
|
-
}),
|
|
162
|
-
});
|
|
163
|
-
expect(status).toBe(200);
|
|
164
|
-
const message = (body as { message: { contentType: string; bodyPreview: string } }).message;
|
|
165
|
-
// The interactive payload is dropped: outbound buttons work, the reply to one does not exist.
|
|
166
|
-
expect(message.contentType).toBe("text");
|
|
167
|
-
expect(message.bodyPreview).toBe("");
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("GAP: only `sent` and `delivered` are ever emitted, so a channel cannot observe a read receipt or a failure", async () => {
|
|
171
|
-
const id = pnid();
|
|
172
|
-
await send(id, { kind: "text", text: "uma mensagem" });
|
|
173
|
-
const { body } = await raw("/_sim/webhooks");
|
|
174
|
-
const statuses = (body as { deliveries: Array<{ body: unknown }> }).deliveries
|
|
175
|
-
.map((d) => d.body as { entry?: Array<{ id?: string; changes?: Array<{ value?: { statuses?: Array<{ status: string }> } }> }> })
|
|
176
|
-
.filter((b) => b.entry?.[0]?.id === id)
|
|
177
|
-
.flatMap((b) => b.entry?.[0]?.changes?.[0]?.value?.statuses ?? [])
|
|
178
|
-
.map((s) => s.status);
|
|
179
|
-
expect(statuses).toEqual(["sent", "delivered"]);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("GAP: a `+` on one side and none on the other splits one person into two conversations", async () => {
|
|
183
|
-
const id = pnid();
|
|
184
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
185
|
-
// Our driver strips the `+` precisely to avoid this; done by hand here, it splits.
|
|
186
|
-
await raw("/_sim/inbound", {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: { "content-type": "application/json" },
|
|
189
|
-
body: JSON.stringify({ phone_number_id: id, from: `+${TO}`, text: "oi" }),
|
|
190
|
-
});
|
|
191
|
-
await send(id, { kind: "text", text: "resposta" });
|
|
192
|
-
const miss = await raw(`/_sim/state?key=${id}:not-a-conversation`);
|
|
193
|
-
const keys = (miss.body as { keys: string[] }).keys;
|
|
194
|
-
expect(keys).toContain(`${id}:+${TO}`);
|
|
195
|
-
expect(keys).toContain(`${id}:${TO}`);
|
|
196
|
-
|
|
197
|
-
// With our driver, which strips it, there is one conversation and the window opens.
|
|
198
|
-
const same = pnid();
|
|
199
|
-
await driver.inbound({ phoneNumberId: same, from: `+${TO}`, text: "oi" });
|
|
200
|
-
await send(same, { kind: "text", text: "resposta" });
|
|
201
|
-
const keysAfter = ((await raw(`/_sim/state?key=${same}:not-a-conversation`)).body as { keys: string[] }).keys;
|
|
202
|
-
expect(keysAfter.filter((k) => k.startsWith(`${same}:`))).toEqual([`${same}:${TO}`]);
|
|
203
|
-
});
|
|
204
|
-
});
|
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* What the emulator does, measured rather than assumed — and what it does NOT
|
|
3
|
-
* do, which is the more useful half.
|
|
4
|
-
*
|
|
5
|
-
* These run against `dyvit-wa-sim` (https://github.com/fabianocruz/whatsapp-simulator,
|
|
6
|
-
* MIT) at the version `scripts/whatsapp-emulator.mjs` pins. They SKIP when it is
|
|
7
|
-
* not listening, so `npm test` is green on a machine that never started it; the
|
|
8
|
-
* CI starts it, and `npm run whatsapp:gate` fails loudly rather than skipping,
|
|
9
|
-
* so nothing important hides behind a skip.
|
|
10
|
-
*
|
|
11
|
-
* Two kinds of assertion live here and they are not the same thing.
|
|
12
|
-
*
|
|
13
|
-
* What the emulator gets RIGHT, which our adapter depends on: the Cloud API
|
|
14
|
-
* response shape, the signed webhook, the controllable clock. If one of these
|
|
15
|
-
* breaks, our channel breaks.
|
|
16
|
-
*
|
|
17
|
-
* What the emulator does NOT do, which our channel has to cover itself. Those
|
|
18
|
-
* assertions are written to FAIL the day the emulator closes the gap — which
|
|
19
|
-
* is what we want, because the pin means it can only change when we move it,
|
|
20
|
-
* and the failure is the notification. They are a spec for the repo's owner,
|
|
21
|
-
* not a complaint: `docs/OPEN_QUESTIONS.md` §46 carries the same list in
|
|
22
|
-
* prose with the payloads.
|
|
23
|
-
*/
|
|
24
|
-
import { describe, expect, it } from "vitest";
|
|
25
|
-
import { EmulatorDriver } from "../src/channels/whatsapp/emulator.js";
|
|
26
|
-
import { buildSendRequest, type CloudApiConfig } from "../src/channels/whatsapp/cloud-api.js";
|
|
27
|
-
|
|
28
|
-
const URL_BASE = process.env["WHATSAPP_SIM_URL"] ?? "http://127.0.0.1:4290";
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Probed at MODULE level, not in a `beforeAll`: `describe.skipIf` is read when
|
|
32
|
-
* the file is collected, which is before any hook has run, so a flag set in a
|
|
33
|
-
* hook would skip every case on a machine where the emulator is up.
|
|
34
|
-
*/
|
|
35
|
-
const up = await (async () => {
|
|
36
|
-
try {
|
|
37
|
-
return (await fetch(`${URL_BASE}/health`, { signal: AbortSignal.timeout(2000) })).ok;
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
})();
|
|
42
|
-
if (!up) process.stderr.write(`[whatsapp] no emulator at ${URL_BASE}; its integration cases are skipped. Start it with \`npm run whatsapp:emulator\`.\n`);
|
|
43
|
-
|
|
44
|
-
/** A fresh phone-number id per case, because the emulator keys a conversation on it. */
|
|
45
|
-
const pnid = () => `9${String(Math.floor(Math.random() * 1e11)).padStart(11, "0")}`;
|
|
46
|
-
const TO = "5511987654321";
|
|
47
|
-
|
|
48
|
-
const config = (phoneNumberId: string): CloudApiConfig => ({
|
|
49
|
-
baseUrl: URL_BASE,
|
|
50
|
-
phoneNumberId,
|
|
51
|
-
accessToken: "emulator",
|
|
52
|
-
verifyToken: "emulator",
|
|
53
|
-
appSecret: "dev",
|
|
54
|
-
apiVersion: "v22.0",
|
|
55
|
-
webhookPort: 0,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
async function send(phoneNumberId: string, body: Parameters<typeof buildSendRequest>[2]) {
|
|
59
|
-
const request = buildSendRequest(config(phoneNumberId), `+${TO}`, body);
|
|
60
|
-
if ("unsupported" in request) return { status: 0, unsupported: request.unsupported, body: null as unknown };
|
|
61
|
-
const response = await fetch(request.url, { method: request.method, headers: request.headers, body: request.body });
|
|
62
|
-
return { status: response.status, unsupported: null, body: (await response.json()) as Record<string, unknown> };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function raw(path: string, init?: RequestInit) {
|
|
66
|
-
const response = await fetch(`${URL_BASE}${path}`, init);
|
|
67
|
-
return { status: response.status, body: (await response.json().catch(() => null)) as Record<string, unknown> | null };
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
describe.skipIf(!up)("what our adapter depends on, and the emulator provides", () => {
|
|
71
|
-
it("answers our text send with the Cloud API's own response shape", async () => {
|
|
72
|
-
const id = pnid();
|
|
73
|
-
const result = await send(id, { kind: "text", text: "Oi, Joana!" });
|
|
74
|
-
expect(result.status).toBe(200);
|
|
75
|
-
expect(result.body).toMatchObject({ messaging_product: "whatsapp" });
|
|
76
|
-
const messages = (result.body as { messages: Array<{ id: string; message_status: string }> }).messages;
|
|
77
|
-
expect(messages[0]!.id).toMatch(/^wamid\./);
|
|
78
|
-
expect(messages[0]!.message_status).toBe("accepted");
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("takes the Pix copy-and-paste as a plain text message: the string that pays goes through unchanged", async () => {
|
|
82
|
-
const brcode = "00020126580014br.gov.bcb.pix0136stub-chg_abc5204000053039865802BR5909CODESPAR6009SAO PAULO62070503***6304STUB";
|
|
83
|
-
const result = await send(pnid(), { kind: "instrument", instrument: "pix_copy_paste", value: brcode });
|
|
84
|
-
expect(result.status).toBe(200);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("takes a template with its body parameters", async () => {
|
|
88
|
-
const result = await send(pnid(), { kind: "template", template: "cobranca_lembrete", language: "pt_BR", variables: ["Joana"] });
|
|
89
|
-
expect(result.status).toBe(200);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("has a conversation clock we can pin and move, which is the only way a 24h window ever closes in a replay", async () => {
|
|
93
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
94
|
-
const pinned = (await driver.pin(new Date("2026-09-23T17:00:00.000Z"))) as { now: string };
|
|
95
|
-
expect(pinned.now).toBe("2026-09-23T17:00:00.000Z");
|
|
96
|
-
const moved = (await driver.advanceHours(26)) as { now: string };
|
|
97
|
-
expect(Date.parse(moved.now) - Date.parse(pinned.now)).toBeGreaterThanOrEqual(26 * 3600 * 1000);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("delivers an inbound message as a webhook our own parser reads", async () => {
|
|
101
|
-
const id = pnid();
|
|
102
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
103
|
-
await driver.inbound({ phoneNumberId: id, from: `+${TO}`, text: "oi, recebi a mensagem" });
|
|
104
|
-
const { body } = await raw("/_sim/webhooks");
|
|
105
|
-
const deliveries = (body as { deliveries: Array<{ body: unknown }> }).deliveries;
|
|
106
|
-
const mine = deliveries.map((d) => d.body).filter((b) => JSON.stringify(b).includes(id));
|
|
107
|
-
expect(mine.length).toBeGreaterThan(0);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* The gaps. Each one is the exact payload that failed, so the assertion doubles
|
|
113
|
-
* as the report. They are written against the PINNED sha: a green run here
|
|
114
|
-
* means the gap is still open, and a red one means it was closed and our own
|
|
115
|
-
* cover for it can be reconsidered.
|
|
116
|
-
*/
|
|
117
|
-
describe.skipIf(!up)("what the emulator does not do, measured", () => {
|
|
118
|
-
it("GAP: accepts a free-form message outside the 24h window that Meta refuses with 131047 — and it already knows", async () => {
|
|
119
|
-
const id = pnid();
|
|
120
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
121
|
-
await driver.pin(new Date("2026-09-23T17:00:00.000Z"));
|
|
122
|
-
await driver.inbound({ phoneNumberId: id, from: `+${TO}`, text: "oi" });
|
|
123
|
-
expect((await send(id, { kind: "text", text: "dentro da janela" })).status).toBe(200);
|
|
124
|
-
|
|
125
|
-
await driver.advanceHours(26);
|
|
126
|
-
const outside = await send(id, { kind: "text", text: "Recebemos, acordo quitado." });
|
|
127
|
-
// The real Cloud API answers 400 with error 131047 and sends nothing.
|
|
128
|
-
expect(outside.status).toBe(200);
|
|
129
|
-
|
|
130
|
-
// And this is what makes it a one-line fix rather than a feature: the
|
|
131
|
-
// pricing engine has ALREADY decided the message is invalid there.
|
|
132
|
-
const state = (await raw(`/_sim/state?key=${id}:${TO}`)).body as {
|
|
133
|
-
messages: Array<{ id: string }>;
|
|
134
|
-
priced: { byMessageId: Record<string, { reasonCode: string }> };
|
|
135
|
-
};
|
|
136
|
-
const last = state.messages[state.messages.length - 1]!;
|
|
137
|
-
expect(state.priced.byMessageId[last.id]!.reasonCode).toBe("INVALID_NON_TEMPLATE_OUTSIDE_CSW");
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it("GAP: has no way to redeliver or reorder a webhook, so duplicate and out-of-order delivery cannot be driven", async () => {
|
|
141
|
-
for (const path of ["/_sim/replay", "/_sim/webhooks/replay", "/_sim/redeliver"]) {
|
|
142
|
-
const { status } = await raw(path, { method: "POST", headers: { "content-type": "application/json" }, body: "{}" });
|
|
143
|
-
expect(status, path).toBe(404);
|
|
144
|
-
}
|
|
145
|
-
// `GET /_sim/webhooks` is a read-only log; nothing re-dispatches from it.
|
|
146
|
-
const { status, body } = await raw("/_sim/webhooks");
|
|
147
|
-
expect(status).toBe(200);
|
|
148
|
-
expect(Array.isArray((body as { deliveries: unknown[] }).deliveries)).toBe(true);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("GAP: an inbound interactive reply degrades to an empty text message, so a debtor cannot tap a button", async () => {
|
|
152
|
-
const id = pnid();
|
|
153
|
-
const { status, body } = await raw("/_sim/inbound", {
|
|
154
|
-
method: "POST",
|
|
155
|
-
headers: { "content-type": "application/json" },
|
|
156
|
-
body: JSON.stringify({
|
|
157
|
-
phone_number_id: id,
|
|
158
|
-
from: `+${TO}`,
|
|
159
|
-
type: "interactive",
|
|
160
|
-
interactive: { type: "button_reply", button_reply: { id: "avista", title: "À vista" } },
|
|
161
|
-
}),
|
|
162
|
-
});
|
|
163
|
-
expect(status).toBe(200);
|
|
164
|
-
const message = (body as { message: { contentType: string; bodyPreview: string } }).message;
|
|
165
|
-
// The interactive payload is dropped: outbound buttons work, the reply to one does not exist.
|
|
166
|
-
expect(message.contentType).toBe("text");
|
|
167
|
-
expect(message.bodyPreview).toBe("");
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("GAP: only `sent` and `delivered` are ever emitted, so a channel cannot observe a read receipt or a failure", async () => {
|
|
171
|
-
const id = pnid();
|
|
172
|
-
await send(id, { kind: "text", text: "uma mensagem" });
|
|
173
|
-
const { body } = await raw("/_sim/webhooks");
|
|
174
|
-
const statuses = (body as { deliveries: Array<{ body: unknown }> }).deliveries
|
|
175
|
-
.map((d) => d.body as { entry?: Array<{ id?: string; changes?: Array<{ value?: { statuses?: Array<{ status: string }> } }> }> })
|
|
176
|
-
.filter((b) => b.entry?.[0]?.id === id)
|
|
177
|
-
.flatMap((b) => b.entry?.[0]?.changes?.[0]?.value?.statuses ?? [])
|
|
178
|
-
.map((s) => s.status);
|
|
179
|
-
expect(statuses).toEqual(["sent", "delivered"]);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it("GAP: a `+` on one side and none on the other splits one person into two conversations", async () => {
|
|
183
|
-
const id = pnid();
|
|
184
|
-
const driver = new EmulatorDriver(URL_BASE);
|
|
185
|
-
// Our driver strips the `+` precisely to avoid this; done by hand here, it splits.
|
|
186
|
-
await raw("/_sim/inbound", {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: { "content-type": "application/json" },
|
|
189
|
-
body: JSON.stringify({ phone_number_id: id, from: `+${TO}`, text: "oi" }),
|
|
190
|
-
});
|
|
191
|
-
await send(id, { kind: "text", text: "resposta" });
|
|
192
|
-
const miss = await raw(`/_sim/state?key=${id}:not-a-conversation`);
|
|
193
|
-
const keys = (miss.body as { keys: string[] }).keys;
|
|
194
|
-
expect(keys).toContain(`${id}:+${TO}`);
|
|
195
|
-
expect(keys).toContain(`${id}:${TO}`);
|
|
196
|
-
|
|
197
|
-
// With our driver, which strips it, there is one conversation and the window opens.
|
|
198
|
-
const same = pnid();
|
|
199
|
-
await driver.inbound({ phoneNumberId: same, from: `+${TO}`, text: "oi" });
|
|
200
|
-
await send(same, { kind: "text", text: "resposta" });
|
|
201
|
-
const keysAfter = ((await raw(`/_sim/state?key=${same}:not-a-conversation`)).body as { keys: string[] }).keys;
|
|
202
|
-
expect(keysAfter.filter((k) => k.startsWith(`${same}:`))).toEqual([`${same}:${TO}`]);
|
|
203
|
-
});
|
|
204
|
-
});
|