@pome-sh/cli 0.1.1 → 0.2.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 +5 -6
- package/dist/build-info.json +3 -3
- package/dist/src/cli/eval.js +26 -8
- package/dist/src/cli/init-sdk.d.ts +0 -3
- package/dist/src/cli/init-sdk.js +117 -24
- package/dist/src/cli/main.js +23 -69
- package/dist/src/cli/register.d.ts +9 -0
- package/dist/src/cli/register.js +51 -5
- package/dist/src/cli/session.d.ts +7 -1
- package/dist/src/cli/session.js +87 -27
- package/dist/src/demo/runDemo.js +3 -2
- package/dist/src/hosted/client.d.ts +41 -5
- package/dist/src/hosted/client.js +333 -19
- package/dist/src/hosted/errors.d.ts +11 -1
- package/dist/src/hosted/errors.js +8 -1
- package/dist/src/hosted/evalResultView.d.ts +2 -0
- package/dist/src/hosted/evalResultView.js +22 -0
- package/dist/src/hosted/uploadAndFinalize.d.ts +18 -1
- package/dist/src/hosted/uploadAndFinalize.js +51 -3
- package/dist/src/recorder/inspect.js +20 -2
- package/dist/src/runner/mergeAdapterSignals.js +2 -2
- package/dist/src/runner/ports.js +3 -0
- package/dist/src/runner/runScenario.d.ts +79 -2
- package/dist/src/runner/runScenario.js +94 -36
- package/dist/src/runner/runScenarioHosted.d.ts +37 -0
- package/dist/src/runner/runScenarioHosted.js +257 -58
- package/dist/src/runner/runTrialGroup.d.ts +1 -3
- package/dist/src/runner/runTrialGroup.js +1 -3
- package/dist/src/scenario/parseScenario.d.ts +5 -0
- package/dist/src/scenario/parseScenario.js +135 -8
- package/dist/src/scenario/scenarioSchema.d.ts +200 -3
- package/dist/src/scenario/scenarioSchema.js +12 -1
- package/dist/src/twin/twinHarness.d.ts +10 -0
- package/dist/src/twin/twinHarness.js +6 -2
- package/dist/src/twin/twinStart.d.ts +19 -0
- package/dist/src/twin/twinStart.js +156 -0
- package/node_modules/@pome-sh/sdk/dist/fidelity-inventory.d.ts +121 -0
- package/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js +204 -0
- package/node_modules/@pome-sh/sdk/dist/fidelity-inventory.js.map +1 -0
- package/node_modules/@pome-sh/sdk/dist/parity.d.ts +55 -0
- package/node_modules/@pome-sh/sdk/dist/parity.js +112 -0
- package/node_modules/@pome-sh/sdk/dist/parity.js.map +1 -0
- package/node_modules/@pome-sh/sdk/dist/server-helpers.d.ts +15 -0
- package/node_modules/@pome-sh/sdk/dist/server-helpers.js +96 -0
- package/node_modules/@pome-sh/sdk/dist/server-helpers.js.map +1 -1
- package/node_modules/@pome-sh/sdk/dist/server.d.ts +1 -1
- package/node_modules/@pome-sh/sdk/dist/server.js +9 -7
- package/node_modules/@pome-sh/sdk/dist/server.js.map +1 -1
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/errors.d.ts +39 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/errors.js +33 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/errors.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/evaluator-hooks.d.ts +13 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/evaluator-hooks.js +6 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/evaluator-hooks.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/finalize-shapes.d.ts +215 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js +83 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/github-access-control.d.ts +175 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/github-access-control.js +182 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/github-access-control.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/identity.d.ts +90 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/identity.js +72 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/identity.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/index.d.ts +27 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/index.js +34 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/index.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/event-schema.d.ts +286 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js +33 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/event-schema.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.d.ts +65 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js +455 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/data.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.d.ts +39 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js +47 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/fixtures/index.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/index.d.ts +25 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/index.js +27 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/index.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.d.ts +100 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js +185 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/map-span.d.ts +64 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/map-span.js +112 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/map-span.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/nano.d.ts +26 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/nano.js +61 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/nano.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/project.d.ts +42 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/project.js +96 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/project.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/semconv.d.ts +51 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/semconv.js +74 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/semconv.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/span-event.d.ts +134 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/span-event.js +152 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/otel/span-event.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/recorder-events.d.ts +418 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/recorder-events.js +234 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/recorder-events.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/redaction.d.ts +2 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/redaction.js +152 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/redaction.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/rest.d.ts +198 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/rest.js +225 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/rest.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/run.d.ts +201 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/run.js +166 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/run.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +446 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/seed-state.js +167 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/sessions.d.ts +53 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/sessions.js +51 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/sessions.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task-vocab.d.ts +66 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task-vocab.js +84 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task-vocab.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task.d.ts +483 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task.js +60 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/dist/task.js.map +1 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/package.json +54 -0
- package/node_modules/@pome-sh/sdk/node_modules/@pome-sh/shared-types/trace-contract.json +41 -0
- package/node_modules/@pome-sh/sdk/package.json +6 -2
- package/node_modules/@pome-sh/shared-types/dist/errors.d.ts +39 -0
- package/node_modules/@pome-sh/shared-types/dist/errors.js +33 -0
- package/node_modules/@pome-sh/shared-types/dist/errors.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/finalize-shapes.d.ts +252 -0
- package/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js +122 -0
- package/node_modules/@pome-sh/shared-types/dist/finalize-shapes.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/identity.d.ts +90 -0
- package/node_modules/@pome-sh/shared-types/dist/identity.js +72 -0
- package/node_modules/@pome-sh/shared-types/dist/identity.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/index.d.ts +13 -1353
- package/node_modules/@pome-sh/shared-types/dist/index.js +14 -568
- package/node_modules/@pome-sh/shared-types/dist/index.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/otel/event-schema.d.ts +45 -0
- package/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js +8 -0
- package/node_modules/@pome-sh/shared-types/dist/otel/legacy-shim.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/otel/semconv.js +7 -0
- package/node_modules/@pome-sh/shared-types/dist/otel/semconv.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/recorder-events.d.ts +62 -0
- package/node_modules/@pome-sh/shared-types/dist/recorder-events.js +36 -0
- package/node_modules/@pome-sh/shared-types/dist/recorder-events.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/rest.d.ts +245 -0
- package/node_modules/@pome-sh/shared-types/dist/rest.js +303 -0
- package/node_modules/@pome-sh/shared-types/dist/rest.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/run.d.ts +7 -0
- package/node_modules/@pome-sh/shared-types/dist/run.js +4 -0
- package/node_modules/@pome-sh/shared-types/dist/run.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/seed-envelope.d.ts +14 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-envelope.js +46 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-envelope.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +446 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js +167 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/sessions.d.ts +53 -0
- package/node_modules/@pome-sh/shared-types/dist/sessions.js +51 -0
- package/node_modules/@pome-sh/shared-types/dist/sessions.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/dist/task.d.ts +485 -0
- package/node_modules/@pome-sh/shared-types/dist/task.js +60 -0
- package/node_modules/@pome-sh/shared-types/dist/task.js.map +1 -0
- package/node_modules/@pome-sh/shared-types/package.json +2 -1
- package/node_modules/@pome-sh/shared-types/trace-contract.json +1 -1
- package/node_modules/@pome-sh/twin-github/FIDELITY.md +127 -67
- package/node_modules/@pome-sh/twin-github/README.md +3 -7
- package/node_modules/@pome-sh/twin-github/dist/examples/claude-github-agent.js +4 -20
- package/node_modules/@pome-sh/twin-github/dist/examples/claude-github-agent.js.map +1 -1
- package/node_modules/@pome-sh/twin-github/dist/src/access-control.d.ts +3 -3
- package/node_modules/@pome-sh/twin-github/dist/src/domain.d.ts +141 -3
- package/node_modules/@pome-sh/twin-github/dist/src/domain.js +0 -0
- package/node_modules/@pome-sh/twin-github/dist/src/domain.js.map +1 -1
- package/node_modules/@pome-sh/twin-github/dist/src/routes.js +2 -0
- package/node_modules/@pome-sh/twin-github/dist/src/routes.js.map +1 -1
- package/node_modules/@pome-sh/twin-github/dist/src/seed.d.ts +1 -1
- package/node_modules/@pome-sh/twin-github/dist/src/serializers.d.ts +2 -2
- package/node_modules/@pome-sh/twin-github/dist/src/server.js +7 -6
- package/node_modules/@pome-sh/twin-github/dist/src/server.js.map +1 -1
- package/node_modules/@pome-sh/twin-github/dist/src/tools.d.ts +168 -18
- package/node_modules/@pome-sh/twin-github/dist/src/tools.js +23 -0
- package/node_modules/@pome-sh/twin-github/dist/src/tools.js.map +1 -1
- package/node_modules/@pome-sh/twin-github/fidelity.inventory.json +773 -0
- package/node_modules/@pome-sh/twin-github/package.json +5 -4
- package/node_modules/@pome-sh/twin-slack/FIDELITY.md +121 -35
- package/node_modules/@pome-sh/twin-slack/README.md +2 -6
- package/node_modules/@pome-sh/twin-slack/dist/scripts/fidelity-parity.d.ts +1 -0
- package/node_modules/@pome-sh/twin-slack/dist/scripts/fidelity-parity.js +92 -0
- package/node_modules/@pome-sh/twin-slack/dist/scripts/fidelity-parity.js.map +1 -0
- package/node_modules/@pome-sh/twin-slack/dist/scripts/smoke.js +3 -3
- package/node_modules/@pome-sh/twin-slack/dist/scripts/smoke.js.map +1 -1
- package/node_modules/@pome-sh/twin-slack/dist/scripts/validate-mcp.js +1 -1
- package/node_modules/@pome-sh/twin-slack/dist/scripts/validate-mcp.js.map +1 -1
- package/node_modules/@pome-sh/twin-slack/dist/src/server.js +7 -6
- package/node_modules/@pome-sh/twin-slack/dist/src/server.js.map +1 -1
- package/node_modules/@pome-sh/twin-slack/dist/src/tools.d.ts +30 -4
- package/node_modules/@pome-sh/twin-slack/dist/src/tools.js +48 -1
- package/node_modules/@pome-sh/twin-slack/dist/src/tools.js.map +1 -1
- package/node_modules/@pome-sh/twin-slack/fidelity.inventory.json +377 -0
- package/node_modules/@pome-sh/twin-slack/package.json +5 -4
- package/node_modules/@pome-sh/twin-stripe/FIDELITY.md +151 -50
- package/node_modules/@pome-sh/twin-stripe/README.md +42 -45
- package/node_modules/@pome-sh/twin-stripe/dist/scripts/fidelity-parity.d.ts +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/scripts/fidelity-parity.js +186 -0
- package/node_modules/@pome-sh/twin-stripe/dist/scripts/fidelity-parity.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/scripts/smoke.js +8 -4
- package/node_modules/@pome-sh/twin-stripe/dist/scripts/smoke.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/db.js +26 -2
- package/node_modules/@pome-sh/twin-stripe/dist/src/db.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/billing.d.ts +101 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/billing.js +195 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/billing.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/charges.d.ts +15 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/charges.js +17 -5
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/charges.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/customers.d.ts +47 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/customers.js +103 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/customers.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/events.d.ts +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/events.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/index.d.ts +6 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/index.js +3 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/index.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-intents.d.ts +61 -2
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-intents.js +214 -52
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-intents.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-methods.d.ts +45 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-methods.js +159 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/payment-methods.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/refunds.d.ts +6 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/refunds.js +16 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/refunds.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/schema.d.ts +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/schema.js +144 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/schema.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/stripe-domain.d.ts +420 -43
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/stripe-domain.js +442 -13
- package/node_modules/@pome-sh/twin-stripe/dist/src/domain/stripe-domain.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/errors.d.ts +19 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/errors.js +15 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/errors.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/ids.d.ts +2 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/ids.js +2 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/ids.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/_helpers.d.ts +8 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/_helpers.js +105 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/_helpers.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/billing.d.ts +4 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/billing.js +117 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/billing.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/customers.d.ts +4 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/customers.js +47 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/customers.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/index.js +6 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/index.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/payment-intents.js +28 -102
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/payment-intents.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/payment-methods.d.ts +4 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/payment-methods.js +33 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/routes/payment-methods.js.map +1 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/seed.d.ts +10 -8
- package/node_modules/@pome-sh/twin-stripe/dist/src/seed.js +3 -2
- package/node_modules/@pome-sh/twin-stripe/dist/src/seed.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/serializers.d.ts +181 -21
- package/node_modules/@pome-sh/twin-stripe/dist/src/serializers.js +257 -34
- package/node_modules/@pome-sh/twin-stripe/dist/src/serializers.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/server.js +7 -6
- package/node_modules/@pome-sh/twin-stripe/dist/src/server.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/tools.d.ts +107 -5
- package/node_modules/@pome-sh/twin-stripe/dist/src/tools.js +139 -6
- package/node_modules/@pome-sh/twin-stripe/dist/src/tools.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/types.d.ts +73 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/upstream-types.d.ts +8 -0
- package/node_modules/@pome-sh/twin-stripe/dist/src/x402.js +6 -1
- package/node_modules/@pome-sh/twin-stripe/dist/src/x402.js.map +1 -1
- package/node_modules/@pome-sh/twin-stripe/fidelity.inventory.json +425 -0
- package/node_modules/@pome-sh/twin-stripe/package.json +5 -4
- package/package.json +8 -8
- package/skills/pome-setup/SKILL.md +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
page documents exactly which surfaces are faithful to real Stripe today,
|
|
6
6
|
at what tier, and how fidelity is verified.
|
|
7
7
|
|
|
8
|
-
Last verified: 2026-
|
|
8
|
+
Last verified: 2026-07-12.
|
|
9
9
|
Stripe API version pinned: `2026-03-04.preview`.
|
|
10
10
|
|
|
11
11
|
## What "fidelity" means here
|
|
@@ -16,13 +16,23 @@ Each REST route and MCP tool is classified into one of three tiers:
|
|
|
16
16
|
covered by tests. PaymentIntent state-machine transitions, balance
|
|
17
17
|
arithmetic, idempotency-key dedupe, and the rest behave the way agents
|
|
18
18
|
expect when they call real Stripe.
|
|
19
|
-
- **`shape`** — the response shape is
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
- **`shape`** — the response shape is faithful (compile-anchored against
|
|
20
|
+
the official `stripe` types, FDRS-478) but the underlying behavior is
|
|
21
|
+
deliberately not semantic. The billing surfaces (products, prices,
|
|
22
|
+
subscriptions, invoice reads — F-734, ruled warm by F-729) sit here:
|
|
23
|
+
stored rows served back in Stripe shape, with referential 404s, but no
|
|
24
|
+
events emitted, no invoices minted, no billing-cycle arithmetic.
|
|
22
25
|
- **`unsupported`** — not implemented. The clone returns a loud 501
|
|
23
26
|
envelope (see below) so an agent never silently succeeds against a
|
|
24
27
|
missing route.
|
|
25
28
|
|
|
29
|
+
Fidelity ("how deep a surface *is*") is one of two orthogonal dimensions;
|
|
30
|
+
the other is **heat** ("how deep it *should* be", `hot`/`warm`/`cold`,
|
|
31
|
+
ruled per milestone). The engine-level rubric — tier criteria, target
|
|
32
|
+
mapping, gap and tier-mismatch semantics — lives at
|
|
33
|
+
[`packages/sdk/ENDPOINT-TIERS.md`](../sdk/ENDPOINT-TIERS.md). The `Tier`
|
|
34
|
+
column below means fidelity.
|
|
35
|
+
|
|
26
36
|
The bar Pome aims for: **agents written against real Stripe x402 run
|
|
27
37
|
unchanged against this twin**, and trip a loud failure for anything
|
|
28
38
|
outside the documented surface.
|
|
@@ -34,27 +44,68 @@ build depends on (port `:3333`, `/healthz`, `STRIPE_CLONE_HOST`,
|
|
|
34
44
|
in the package README. Changing any of those is a breaking change for
|
|
35
45
|
`pome-cloud` and requires a matching cloud consumer PR.
|
|
36
46
|
|
|
37
|
-
## REST routes (v1 =
|
|
38
|
-
|
|
39
|
-
| Route | Tier | Tests | Notes |
|
|
40
|
-
| --- | --- | --- | --- |
|
|
41
|
-
| `POST /s/:sid/v1/payment_intents` | semantic | `pi.test.ts`, `tools.test.ts` |
|
|
42
|
-
| `GET /s/:sid/v1/payment_intents/:id` | semantic | `pi.test.ts` | |
|
|
43
|
-
| `GET /s/:sid/v1/payment_intents` | semantic | `pi.test.ts` | Cursor pagination on `(created, id)` via `starting_after` / `ending_before` (matches Stripe's cursor model). |
|
|
44
|
-
| `POST /s/:sid/v1/payment_intents/:id/confirm` | semantic | `pi.test.ts` |
|
|
45
|
-
| `POST /s/:sid/v1/payment_intents/:id
|
|
46
|
-
| `POST /s/:sid/v1/
|
|
47
|
-
| `
|
|
48
|
-
| `GET /s/:sid/v1/charges` | semantic | `charges.test.ts` |
|
|
49
|
-
| `GET /s/:sid/v1/
|
|
50
|
-
| `
|
|
51
|
-
| `GET /s/:sid/v1/
|
|
52
|
-
| `GET /s/:sid/v1/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
## REST routes (v1 = 26 semantic + 13 shape + everything else loud 501)
|
|
48
|
+
|
|
49
|
+
| Route | Heat | Tier | Tests | Notes |
|
|
50
|
+
| --- | --- | --- | --- | --- |
|
|
51
|
+
| `POST /s/:sid/v1/payment_intents` | hot | semantic | `pi.test.ts`, `pi-card.test.ts`, `tools.test.ts` | Two rails (F-731): crypto deposit mode (deterministic Base USDC deposit address, starts at `requires_action`) and card (starts at `requires_payment_method`, or `requires_confirmation` with a `payment_method`; `confirm: true` runs the one-shot attempt). |
|
|
52
|
+
| `GET /s/:sid/v1/payment_intents/:id` | hot | semantic | `pi.test.ts`, `pi-card.test.ts` | Card PIs surface `last_payment_error` after a declined attempt. |
|
|
53
|
+
| `GET /s/:sid/v1/payment_intents` | hot | semantic | `pi.test.ts` | Cursor pagination on `(created, id)` via `starting_after` / `ending_before` (matches Stripe's cursor model). |
|
|
54
|
+
| `POST /s/:sid/v1/payment_intents/:id/confirm` | hot | semantic | `pi.test.ts`, `pi-card.test.ts` | Card PIs (F-731): synchronous attempt — success mints charge + balance txn + events; magic test PMs decline with a 402 `card_error` embedding the post-attempt PI. Crypto PIs: idempotent no-op. CAS picks exactly one winner among parallel confirms. |
|
|
55
|
+
| `POST /s/:sid/v1/payment_intents/:id` | hot | semantic | `pi-card.test.ts` | Update (F-731, ruled in scope by F-729 point 1) — the retry-with-new-PM step. Metadata merges per-key; attaching a PM moves `requires_payment_method → requires_confirmation`. Refused once terminal. |
|
|
56
|
+
| `POST /s/:sid/v1/payment_intents/:id/cancel` | hot | semantic | `pi.test.ts`, `pi-card.test.ts` | CAS-on-status; refused once `succeeded`. |
|
|
57
|
+
| `POST /s/:sid/v1/test_helpers/payment_intents/:id/simulate_crypto_deposit` | hot | semantic | `pi.test.ts`, `pi-concurrency.test.ts`, `events.test.ts` | The x402 settlement entry point. CAS `requires_action → processing → succeeded`; mints charge + balance txn + 5 events synchronously. |
|
|
58
|
+
| `GET /s/:sid/v1/charges/:id` | hot | semantic | `charges.test.ts` | Latest charge of a settled PI. |
|
|
59
|
+
| `GET /s/:sid/v1/charges` | hot | semantic | `charges.test.ts` | Filter by `payment_intent`, `customer`. |
|
|
60
|
+
| `POST /s/:sid/v1/refunds` | hot | semantic | `refunds.test.ts`, `refund-abuse-trap.test.ts` | F-733 (heat: hot, ruled F-729). Full or partial; `amount` defaults to the remaining refundable. Refuses over-refunds (`charge_already_refunded`) and failed charges (`charge_not_refundable`). Mints a negative `refund`-type balance transaction and emits `charge.refunded` + `refund.created` in the same transaction. |
|
|
61
|
+
| `GET /s/:sid/v1/refunds/:id` | hot | semantic | `refunds.test.ts` | |
|
|
62
|
+
| `GET /s/:sid/v1/refunds` | hot | semantic | `refunds.test.ts` | Filter by `charge`, `payment_intent`. Omits the legacy `count` field (divergence #9). |
|
|
63
|
+
| `GET /s/:sid/v1/balance` | hot | semantic | `balance.test.ts` | Available + pending; updated as PIs settle. |
|
|
64
|
+
| `GET /s/:sid/v1/balance_transactions` | hot | semantic | `balance.test.ts` | Ledger entries. |
|
|
65
|
+
| `GET /s/:sid/v1/events/:id` | hot | semantic | `events.test.ts` | |
|
|
66
|
+
| `GET /s/:sid/v1/events` | hot | semantic | `events.test.ts` | Filter by `type`, `created`. **No webhook delivery in v1** — agents poll this. |
|
|
67
|
+
| `POST /s/:sid/v1/customers` | hot | semantic | `customers.test.ts` | F-732 (heat: hot, ruled F-729). Every field optional, like real Stripe. Emits `customer.created`. |
|
|
68
|
+
| `GET /s/:sid/v1/customers/:id` | hot | semantic | `customers.test.ts` | Deleted customers serve the `{deleted: true}` stub, like real Stripe. |
|
|
69
|
+
| `GET /s/:sid/v1/customers` | hot | semantic | `customers.test.ts` | Cursor pagination on `(created, id)`; `email` filter; deleted rows excluded. |
|
|
70
|
+
| `POST /s/:sid/v1/customers/:id` | hot | semantic | `customers.test.ts` | Update. Metadata merges per-key; an empty value unsets the key (Stripe's metadata contract). |
|
|
71
|
+
| `DELETE /s/:sid/v1/customers/:id` | hot | semantic | `customers.test.ts` | Soft delete; detaches the customer's payment methods in the same transaction. Idempotent. |
|
|
72
|
+
| `GET /s/:sid/v1/customers/:id/payment_methods` | hot | semantic | `payment-methods.test.ts` | The hot card-on-file read. `type` filter. 404 for deleted customers. |
|
|
73
|
+
| `POST /s/:sid/v1/payment_methods` | hot | semantic | `payment-methods.test.ts` | Card only (F-731 adds card PIs). Test card numbers → brand/last4; Luhn + expiry `card_error`s; PAN never stored. |
|
|
74
|
+
| `GET /s/:sid/v1/payment_methods/:id` | hot | semantic | `payment-methods.test.ts` | Top-level `GET /v1/payment_methods` (list) stays loud 501 per the F-729 ruling. |
|
|
75
|
+
| `POST /s/:sid/v1/payment_methods/:id/attach` | hot | semantic | `payment-methods.test.ts` | One customer per PM; a previously-detached PM can never be reattached. Emits `payment_method.attached`. |
|
|
76
|
+
| `POST /s/:sid/v1/payment_methods/:id/detach` | hot | semantic | `payment-methods.test.ts` | Emits `payment_method.detached`. |
|
|
77
|
+
| `POST /s/:sid/v1/products` | warm | shape | `billing-shape.test.ts` | F-734 (heat: warm, ruled F-729). `name` required; unknown params accepted-and-ignored per the twin's v1 policy. Product/price updates stay unlisted-cold (501). |
|
|
78
|
+
| `GET /s/:sid/v1/products/:id` | warm | shape | `billing-shape.test.ts` | 404 `resource_missing` for unknown ids. |
|
|
79
|
+
| `GET /s/:sid/v1/products` | warm | shape | `billing-shape.test.ts` | Cursor pagination on `(created, id)`; `active` filter. |
|
|
80
|
+
| `POST /s/:sid/v1/prices` | warm | shape | `billing-shape.test.ts` | `currency` + `product` required; the product must exist (referential 404). `recurring.interval` makes it a `recurring` price, otherwise `one_time`. |
|
|
81
|
+
| `GET /s/:sid/v1/prices/:id` | warm | shape | `billing-shape.test.ts` | |
|
|
82
|
+
| `GET /s/:sid/v1/prices` | warm | shape | `billing-shape.test.ts` | Cursor pagination; `product` + `active` filters. |
|
|
83
|
+
| `POST /s/:sid/v1/subscriptions` | warm | shape | `billing-shape.test.ts` | `customer` (live) + `items[][price]` required, both referentially checked. Created `active` immediately — no invoice minted, no event emitted (shape tier). |
|
|
84
|
+
| `GET /s/:sid/v1/subscriptions/:id` | warm | shape | `billing-shape.test.ts` | `items.data[].price` is the expanded Price object, like real Stripe. |
|
|
85
|
+
| `GET /s/:sid/v1/subscriptions` | warm | shape | `billing-shape.test.ts` | Excludes canceled by default; `status=canceled` selects them, `status=all` lifts the filter; `customer` filter. |
|
|
86
|
+
| `POST /s/:sid/v1/subscriptions/:id` | warm | shape | `billing-shape.test.ts` | Update: metadata merges per-key (empty value unsets), `cancel_at_period_end` flips. Canceled subscriptions accept metadata-only updates and refuse everything else, like real Stripe. |
|
|
87
|
+
| `DELETE /s/:sid/v1/subscriptions/:id` | warm | shape | `billing-shape.test.ts` | Immediate cancel: `status → canceled`, `canceled_at`/`ended_at` stamped. Idempotent; no proration, no final invoice (shape tier). |
|
|
88
|
+
| `GET /s/:sid/v1/invoices/:id` | warm | shape | `billing-shape.test.ts` | Always 404 `resource_missing`: invoices are reads-only (F-729 ruling point 2) and nothing in the twin mints one. |
|
|
89
|
+
| `GET /s/:sid/v1/invoices` | warm | shape | `billing-shape.test.ts` | Always the empty Stripe list envelope — see the invoice note under Known divergences. |
|
|
90
|
+
|
|
91
|
+
### Named cold surfaces (loud 501, test-backed)
|
|
92
|
+
|
|
93
|
+
Per the F-729 ruling these families are cold — outside the twin's
|
|
94
|
+
machine-payments product scope — but agents plausibly probe them, so the
|
|
95
|
+
501 is documented here and pinned by `unsupported.test.ts` (and the
|
|
96
|
+
`fidelity:parity` 501 probe for checkout sessions):
|
|
97
|
+
|
|
98
|
+
| Route | Heat | Tier | Tests | Notes |
|
|
99
|
+
| --- | --- | --- | --- | --- |
|
|
100
|
+
| `ALL /s/:sid/v1/checkout/sessions*` | cold | unsupported | `unsupported.test.ts` | PS: human-redirect flow. |
|
|
101
|
+
| `ALL /s/:sid/v1/payment_links*` | cold | unsupported | `unsupported.test.ts` | PS: human-redirect flow. |
|
|
102
|
+
| `ALL /s/:sid/v1/setup_intents*` | cold | unsupported | `unsupported.test.ts` | PS: card-on-file is modeled via direct PM attach (F-732). |
|
|
103
|
+
| `ALL /s/:sid/v1/webhook_endpoints*` | cold | unsupported | `unsupported.test.ts` | PS: no webhook delivery loop in v1 (divergence #5); agents poll `GET /v1/events`. |
|
|
104
|
+
|
|
105
|
+
Anything else under `/v1/*` (`/v1/shared_payment/*`, `/v1/profiles`,
|
|
106
|
+
invoice writes like `POST /v1/invoices` or `.../finalize`/`.../pay`,
|
|
107
|
+
product/price updates, the top-level `GET /v1/payment_methods` list,
|
|
108
|
+
etc.) is the unlisted cold tail and returns:
|
|
58
109
|
|
|
59
110
|
```json
|
|
60
111
|
{
|
|
@@ -75,27 +126,50 @@ Anything else under `/v1/*` (`/v1/customers`,
|
|
|
75
126
|
|
|
76
127
|
HTTP status: 501.
|
|
77
128
|
|
|
78
|
-
## MCP tools (
|
|
79
|
-
|
|
80
|
-
| Tool | Backing route | Tier |
|
|
81
|
-
| --- | --- | --- |
|
|
82
|
-
| `create_payment_intent` | POST /v1/payment_intents | semantic |
|
|
83
|
-
| `retrieve_payment_intent` | GET /v1/payment_intents/:id | semantic |
|
|
84
|
-
| `list_payment_intents` | GET /v1/payment_intents | semantic |
|
|
85
|
-
| `confirm_payment_intent` | POST /v1/payment_intents/:id/confirm | semantic |
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
129
|
+
## MCP tools (26, 1:1 with the live tool list — names match `stripe-node` method names)
|
|
130
|
+
|
|
131
|
+
| Tool | Backing route | Heat | Tier |
|
|
132
|
+
| --- | --- | --- | --- |
|
|
133
|
+
| `create_payment_intent` | POST /v1/payment_intents | hot | semantic |
|
|
134
|
+
| `retrieve_payment_intent` | GET /v1/payment_intents/:id | hot | semantic |
|
|
135
|
+
| `list_payment_intents` | GET /v1/payment_intents | hot | semantic |
|
|
136
|
+
| `confirm_payment_intent` | POST /v1/payment_intents/:id/confirm | hot | semantic |
|
|
137
|
+
| `update_payment_intent` | POST /v1/payment_intents/:id | hot | semantic |
|
|
138
|
+
| `cancel_payment_intent` | POST /v1/payment_intents/:id/cancel | hot | semantic |
|
|
139
|
+
| `simulate_crypto_deposit` | POST /v1/test_helpers/.../simulate_crypto_deposit | hot | semantic |
|
|
140
|
+
| `retrieve_charge` | GET /v1/charges/:id | hot | semantic |
|
|
141
|
+
| `list_charges` | GET /v1/charges | hot | semantic |
|
|
142
|
+
| `create_refund` | POST /v1/refunds | hot | semantic |
|
|
143
|
+
| `retrieve_refund` | GET /v1/refunds/:id | hot | semantic |
|
|
144
|
+
| `list_refunds` | GET /v1/refunds | hot | semantic |
|
|
145
|
+
| `retrieve_balance` | GET /v1/balance | hot | semantic |
|
|
146
|
+
| `list_balance_transactions` | GET /v1/balance_transactions | hot | semantic |
|
|
147
|
+
| `retrieve_event` | GET /v1/events/:id | hot | semantic |
|
|
148
|
+
| `list_events` | GET /v1/events | hot | semantic |
|
|
149
|
+
| `create_customer` | POST /v1/customers | hot | semantic |
|
|
150
|
+
| `retrieve_customer` | GET /v1/customers/:id | hot | semantic |
|
|
151
|
+
| `update_customer` | POST /v1/customers/:id | hot | semantic |
|
|
152
|
+
| `delete_customer` | DELETE /v1/customers/:id | hot | semantic |
|
|
153
|
+
| `list_customers` | GET /v1/customers | hot | semantic |
|
|
154
|
+
| `list_customer_payment_methods` | GET /v1/customers/:id/payment_methods | hot | semantic |
|
|
155
|
+
| `create_payment_method` | POST /v1/payment_methods | hot | semantic |
|
|
156
|
+
| `retrieve_payment_method` | GET /v1/payment_methods/:id | hot | semantic |
|
|
157
|
+
| `attach_payment_method` | POST /v1/payment_methods/:id/attach | hot | semantic |
|
|
158
|
+
| `detach_payment_method` | POST /v1/payment_methods/:id/detach | hot | semantic |
|
|
94
159
|
|
|
95
160
|
Every MCP tool is callable via both `POST /s/:sid/mcp/call` (with
|
|
96
161
|
`{tool, arguments}` body) and `POST /s/:sid/mcp/tools/:name` (with the
|
|
97
162
|
arguments as the body). Coverage in `tools.test.ts`.
|
|
98
163
|
|
|
164
|
+
The tables above are 1:1-linted against the structured inventory
|
|
165
|
+
[`fidelity.inventory.json`](fidelity.inventory.json) (which also carries the
|
|
166
|
+
hot/warm/cold heat tier per F-729) by `test/fidelity-contract.test.ts`, and
|
|
167
|
+
`npm run fidelity:parity` (shared runner in `@pome-sh/sdk/parity`, F-730)
|
|
168
|
+
exercises every inventoried tool end-to-end. Known gaps between code and
|
|
169
|
+
these tables must be declared in the inventory's `doc_drift` with their
|
|
170
|
+
owning ticket, and the lint fails the moment the docs catch up. None are
|
|
171
|
+
declared today — F-733 reconciled the refunds chain, the last such gap.
|
|
172
|
+
|
|
99
173
|
## x402 middleware (`src/x402.ts`)
|
|
100
174
|
|
|
101
175
|
`paymentMiddleware(routeMap, twinOptions)` is a Hono helper that:
|
|
@@ -126,7 +200,9 @@ plus the `examples/buyer-agent/` end-to-end demo against a running twin.
|
|
|
126
200
|
exactly one 200 (winner of the `requires_action → processing` CAS)
|
|
127
201
|
and seven 400s with `payment_intent_unexpected_state`. Single
|
|
128
202
|
`charges` row, single `balance_transactions` row, balance reflects
|
|
129
|
-
the PI amount once.
|
|
203
|
+
the PI amount once. The card rail carries the same guarantee
|
|
204
|
+
(`pi-card.test.ts`): 8 parallel confirms → one winner of the
|
|
205
|
+
`requires_confirmation → processing` CAS, single charge.
|
|
130
206
|
- **Idempotency-Key** (`idempotency.test.ts`): same key + same body →
|
|
131
207
|
cached response. Same key + different body → 400
|
|
132
208
|
`idempotency_key_in_use`. Caches 2xx/3xx; skips 4xx and 5xx so a
|
|
@@ -195,12 +271,23 @@ not exposed at the root mount — those remain at `/s/:sid/_pome/*` and
|
|
|
195
271
|
|
|
196
272
|
## Known divergences from real Stripe (v1)
|
|
197
273
|
|
|
198
|
-
1. **PI currency restricted to `usd
|
|
274
|
+
1. **PI currency restricted to `usd`** on both rails. Non-USD returns
|
|
199
275
|
`currency_not_supported`. (Real Stripe accepts many currencies but
|
|
200
|
-
x402's USD-priced/USDC-paid model is the v1 wedge
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
276
|
+
x402's USD-priced/USDC-paid model is the v1 wedge; card PIs keep the
|
|
277
|
+
same restriction.)
|
|
278
|
+
2. **`payment_method_types` restricted to exactly `["crypto"]` or `["card"]`**
|
|
279
|
+
(F-731 added the card rail). Multi-type lists and other types return a
|
|
280
|
+
loud 400. Card attempts settle synchronously with no 3DS /
|
|
281
|
+
`requires_action` step; declines are driven by Stripe's magic test PMs
|
|
282
|
+
(`4000000000000002` generic_decline, `4000000000009995`
|
|
283
|
+
insufficient_funds, `4000000000000069` expired_card, `4000000000000127`
|
|
284
|
+
incorrect_cvc — the decline is keyed off the stored card fingerprint,
|
|
285
|
+
the PAN is never persisted). A declined confirm answers 402 with a
|
|
286
|
+
`card_error` envelope that embeds `decline_code` and the post-attempt
|
|
287
|
+
`payment_intent`, mints a `failed` charge, and records
|
|
288
|
+
`last_payment_error` — the ruled retry step is
|
|
289
|
+
`POST /v1/payment_intents/:id` with a new `payment_method`, then
|
|
290
|
+
confirm again.
|
|
204
291
|
3. **Single deposit network and token**. One network (`base`), one token
|
|
205
292
|
(`usdc`). Tempo and Solana from Stripe's published matrix are deferred.
|
|
206
293
|
4. **`available_on` equals `created`** for balance transactions (no
|
|
@@ -210,8 +297,11 @@ not exposed at the root mount — those remain at `/s/:sid/_pome/*` and
|
|
|
210
297
|
6. **EIP-3009 signature verification not enforced** (x402 deviation).
|
|
211
298
|
7. **`simulate_crypto_deposit` settles synchronously**; no chain-delay
|
|
212
299
|
simulation.
|
|
213
|
-
8. **`confirm_payment_intent` is a no-op for crypto
|
|
214
|
-
state machine doesn't need a separate confirm step
|
|
300
|
+
8. **`confirm_payment_intent` is a no-op for crypto PIs only** (the
|
|
301
|
+
deposit-mode state machine doesn't need a separate confirm step).
|
|
302
|
+
Card confirms are real synchronous attempts (F-731) — and unlike the
|
|
303
|
+
crypto no-op, re-confirming a settled card PI is refused with
|
|
304
|
+
`payment_intent_unexpected_state`.
|
|
215
305
|
9. **`/v1/refunds` omits the legacy `count` field**. Real Stripe's
|
|
216
306
|
refunds list envelope still carries a top-level `count`; the twin (like
|
|
217
307
|
its other list surfaces, which match real Stripe exactly) omits this
|
|
@@ -258,6 +348,16 @@ not exposed at the root mount — those remain at `/s/:sid/_pome/*` and
|
|
|
258
348
|
anchor). Bumping `stripe` re-runs the anchor — the FDRS-476 bump → tsc →
|
|
259
349
|
cover-or-register loop — surfacing every upstream shape change by name.
|
|
260
350
|
|
|
351
|
+
16. **Billing surfaces are shape tier — no billing machine behind them**
|
|
352
|
+
(F-734, ruled warm by F-729). Creating a product / price / subscription
|
|
353
|
+
emits **no events** and mints **no invoices**; real Stripe emits
|
|
354
|
+
`product.created` etc. and invoices a new subscription immediately.
|
|
355
|
+
`GET /v1/invoices` is therefore always the empty list and
|
|
356
|
+
`GET /v1/invoices/:id` always 404s (invoice writes are unlisted-cold per
|
|
357
|
+
ruling point 2). Subscription items omit `current_period_start/end` —
|
|
358
|
+
the shape tier carries no billing-cycle arithmetic, so no period is
|
|
359
|
+
fabricated. Cancellation is an immediate status flip with no proration.
|
|
360
|
+
|
|
261
361
|
> Pagination is **not** a divergence: `GET /v1/payment_intents` (and the
|
|
262
362
|
> other list surfaces) use real cursor pagination keyed on `(created, id)`
|
|
263
363
|
> via `starting_after` / `ending_before`, matching Stripe's cursor model.
|
|
@@ -265,7 +365,8 @@ not exposed at the root mount — those remain at `/s/:sid/_pome/*` and
|
|
|
265
365
|
## Verification commands
|
|
266
366
|
|
|
267
367
|
```bash
|
|
268
|
-
npm run test #
|
|
368
|
+
npm run test # 32 files / 237 tests, all green
|
|
269
369
|
npm run smoke # full x402 flow against built server
|
|
370
|
+
npm run fidelity:parity # every inventoried MCP tool end-to-end
|
|
270
371
|
npm run typecheck
|
|
271
372
|
```
|
|
@@ -7,9 +7,11 @@ x402 machine payments**. Real Stripe sandbox doesn't auto-settle crypto
|
|
|
7
7
|
deposits, the CDP facilitator settles on real Base, and `stripe-mock`
|
|
8
8
|
has no x402 support — so without this twin there is nowhere to run agent
|
|
9
9
|
tests against the x402 protocol that aren't either flaky, slow, or
|
|
10
|
-
expensive.
|
|
11
|
-
`paymentMiddleware()` Hono helper
|
|
12
|
-
|
|
10
|
+
expensive. Today it ships **26 semantic REST routes + 26 MCP tools + the
|
|
11
|
+
`paymentMiddleware()` Hono helper** (card and crypto PaymentIntents,
|
|
12
|
+
customers, payment methods, refunds, charges, balance, events), plus 13
|
|
13
|
+
shape-tier billing routes — all stateful, all tested, all loud about what
|
|
14
|
+
they don't do.
|
|
13
15
|
|
|
14
16
|
## Quickstart
|
|
15
17
|
|
|
@@ -20,17 +22,16 @@ twin URL. Skip ahead to [Auth](#auth--works-with-real-stripe-sdks) for
|
|
|
20
22
|
how to wire your existing Stripe SDK.
|
|
21
23
|
|
|
22
24
|
To run the twin yourself locally (e.g., in CI or against an offline
|
|
23
|
-
agent),
|
|
25
|
+
agent), the zero-install path needs only Node ≥ 24:
|
|
24
26
|
|
|
25
27
|
```bash
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
npm run -w @pome-sh/twin-stripe dev & # starts on :3333
|
|
29
|
-
sleep 2
|
|
28
|
+
npx @pome-sh/cli twin start stripe # starts on :3333
|
|
29
|
+
curl http://127.0.0.1:3333/healthz
|
|
30
30
|
|
|
31
|
-
# Or
|
|
32
|
-
#
|
|
33
|
-
#
|
|
31
|
+
# Or, to develop the twin from source:
|
|
32
|
+
# git clone https://github.com/pome-sh/pome-twins.git
|
|
33
|
+
# cd pome-twins && npm install
|
|
34
|
+
# npm run -w @pome-sh/twin-stripe dev
|
|
34
35
|
|
|
35
36
|
# Real Stripe SDKs work via host override — they hit /v1/* directly
|
|
36
37
|
# (no /s/:sid prefix) and the bearer alone resolves the session:
|
|
@@ -58,22 +59,17 @@ deployments (e.g., the pome-cloud per-session proxy, where the `:sid`
|
|
|
58
59
|
in the URL must match the bearer). Pick whichever shape your client
|
|
59
60
|
prefers — they share handlers and produce identical responses.
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
> `package.json` pending OSS Stage 1 + legal review (see plan §22). After
|
|
63
|
-
> Stage 1, `npx @pome-sh/twin-stripe` will be the one-line install path;
|
|
64
|
-
> until then, the monorepo clone above or the hosted twin on
|
|
65
|
-
> pome.sh is the supported route.
|
|
66
|
-
|
|
67
|
-
## What ships in v1
|
|
62
|
+
## What ships today
|
|
68
63
|
|
|
69
64
|
| Surface | Count | Tier |
|
|
70
65
|
| --- | --- | --- |
|
|
71
|
-
| REST
|
|
72
|
-
|
|
|
66
|
+
| REST routes under `/s/:sid/v1/*` (payments, customers, payment methods, refunds, charges, balance, events) | 26 | semantic |
|
|
67
|
+
| Billing reads/writes (products, prices, subscriptions, invoice reads) | 13 | shape |
|
|
68
|
+
| MCP tools (1:1 with stripe-node) | 26 | semantic |
|
|
73
69
|
| `paymentMiddleware()` Hono helper | 1 | semantic |
|
|
74
70
|
| Pome introspection (`_pome/{health,state,events}`) | 3 | n/a |
|
|
75
71
|
| Admin (`/admin/{reset,seed}`, localhost-only) | 2 | n/a |
|
|
76
|
-
|
|
|
72
|
+
| Named cold surfaces (checkout, payment links, setup intents, webhook endpoints) + anything else under `/v1/*` | many | **loud 501 with `fidelity:"unsupported"`** |
|
|
77
73
|
|
|
78
74
|
See [FIDELITY.md](./FIDELITY.md) for the full route table and known
|
|
79
75
|
deviations from real Stripe.
|
|
@@ -137,19 +133,20 @@ Either way, the resolved session id must match the `:sid` in the URL.
|
|
|
137
133
|
|
|
138
134
|
## MCP
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
26 tools available at `GET /s/:sid/mcp/tools`. Tool names match
|
|
141
137
|
`stripe-node` method names so an agent's mental model translates 1:1:
|
|
142
138
|
|
|
143
139
|
```
|
|
144
|
-
create_payment_intent
|
|
145
|
-
retrieve_payment_intent
|
|
146
|
-
list_payment_intents
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
140
|
+
create_payment_intent create_customer
|
|
141
|
+
retrieve_payment_intent retrieve_customer
|
|
142
|
+
list_payment_intents update_customer
|
|
143
|
+
update_payment_intent delete_customer
|
|
144
|
+
confirm_payment_intent list_customers
|
|
145
|
+
cancel_payment_intent list_customer_payment_methods
|
|
146
|
+
simulate_crypto_deposit create_payment_method
|
|
147
|
+
retrieve_charge retrieve_payment_method
|
|
148
|
+
list_charges attach_payment_method
|
|
149
|
+
retrieve_balance detach_payment_method
|
|
153
150
|
list_balance_transactions
|
|
154
151
|
retrieve_event
|
|
155
152
|
list_events
|
|
@@ -205,14 +202,19 @@ that pins and verifies the new signed digest.
|
|
|
205
202
|
- The snapshot manifest at `pome-cloud/infra/twin-stripe-snapshot.json`
|
|
206
203
|
records the OSS git sha and signed OCI digest each snapshot was built from.
|
|
207
204
|
|
|
208
|
-
## What
|
|
205
|
+
## What it does NOT do
|
|
206
|
+
|
|
207
|
+
Shape tier (faithful response shape, deliberately no billing semantics —
|
|
208
|
+
no events emitted, no invoices minted, no billing-cycle arithmetic):
|
|
209
|
+
|
|
210
|
+
- Products, prices, subscriptions, invoice reads (F-734).
|
|
209
211
|
|
|
210
212
|
Loud 501 with `fidelity: "unsupported"`:
|
|
211
213
|
|
|
212
|
-
-
|
|
213
|
-
|
|
214
|
-
-
|
|
215
|
-
- Webhook delivery loop — agents poll `GET /v1/events
|
|
214
|
+
- Checkout sessions, payment links, setup intents, webhook endpoints —
|
|
215
|
+
named cold surfaces, test-backed.
|
|
216
|
+
- All `/v1/shared_payment/*` (SPT) — deferred.
|
|
217
|
+
- Webhook delivery loop — agents poll `GET /v1/events`.
|
|
216
218
|
- Profiles, Connect, Issuing, Treasury, Tax, Climate, Identity — out forever
|
|
217
219
|
for this twin.
|
|
218
220
|
|
|
@@ -235,26 +237,21 @@ Other deviations from real Stripe:
|
|
|
235
237
|
npm install
|
|
236
238
|
npm run dev # boot on :3333 with default seed
|
|
237
239
|
npm run typecheck # tsc --noEmit
|
|
238
|
-
npm run test # vitest,
|
|
240
|
+
npm run test # vitest, 32 files / 237 tests
|
|
239
241
|
npm run build # tsc → dist/src/server.js
|
|
240
242
|
node dist/src/server.js # production-shape boot
|
|
241
243
|
```
|
|
242
244
|
|
|
243
245
|
## Use it as a Stripe test double in your tests
|
|
244
246
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
+
The cleanest way is to boot the published twin from your test setup; all
|
|
248
|
+
it needs is Node ≥ 24:
|
|
247
249
|
|
|
248
250
|
```ts
|
|
249
251
|
// In your test setup
|
|
250
252
|
import { spawn } from "node:child_process";
|
|
251
|
-
import { join } from "node:path";
|
|
252
|
-
|
|
253
|
-
// Path to where you cloned pome-sh/pome-twins on disk
|
|
254
|
-
const POME_REPO = process.env.POME_REPO ?? "/path/to/pome-twins";
|
|
255
253
|
|
|
256
|
-
const twin = spawn("
|
|
257
|
-
cwd: join(POME_REPO, "packages/twin-stripe"),
|
|
254
|
+
const twin = spawn("npx", ["@pome-sh/cli", "twin", "start", "stripe"], {
|
|
258
255
|
env: { ...process.env, PORT: "3333", STRIPE_CLONE_DB: ":memory:" },
|
|
259
256
|
});
|
|
260
257
|
// wait for /healthz before running your suite
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
//
|
|
3
|
+
// fidelity:parity — declarative parity scenario for twin-stripe (F-730).
|
|
4
|
+
// The runner lives in @pome-sh/sdk/parity; this file is scenario data only:
|
|
5
|
+
// the crypto-deposit money chain (create PI → confirm → settle → charge →
|
|
6
|
+
// refund → ledger → events), a second PI for the cancel path, the
|
|
7
|
+
// customer-management chain (F-732: customer CRUD + card-on-file
|
|
8
|
+
// attach/detach), and the card collect-payment chain (F-731: card PI →
|
|
9
|
+
// update-with-PM → confirm → succeeded), covering every MCP tool in
|
|
10
|
+
// fidelity.inventory.json. The refund steps assert the F-733 semantics:
|
|
11
|
+
// the ledger link on the refund body and the post-refund available
|
|
12
|
+
// balance. The loud-501 probe pins the
|
|
13
|
+
// Stripe-shaped unsupported envelope on /v1/checkout/sessions (it moved
|
|
14
|
+
// off /v1/customers when F-732 made customers a supported surface).
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { loadFidelityInventory, runParityCli } from "@pome-sh/sdk/parity";
|
|
17
|
+
import { createTwinStripeApp } from "../src/twin.js";
|
|
18
|
+
import { listTools } from "../src/tools.js";
|
|
19
|
+
const createPi = {
|
|
20
|
+
amount: 20000,
|
|
21
|
+
currency: "usd",
|
|
22
|
+
payment_method_types: ["crypto"],
|
|
23
|
+
payment_method_options: { crypto: { mode: "deposit", deposit_options: { networks: ["base"] } } },
|
|
24
|
+
};
|
|
25
|
+
const steps = [
|
|
26
|
+
{
|
|
27
|
+
tool: "create_payment_intent",
|
|
28
|
+
arguments: createPi,
|
|
29
|
+
capture: (body, state) => {
|
|
30
|
+
state.pi = body.id;
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
{ tool: "retrieve_payment_intent", arguments: (state) => ({ id: state.pi }) },
|
|
34
|
+
{ tool: "confirm_payment_intent", arguments: (state) => ({ id: state.pi }) },
|
|
35
|
+
{
|
|
36
|
+
tool: "simulate_crypto_deposit",
|
|
37
|
+
arguments: (state) => ({ id: state.pi }),
|
|
38
|
+
capture: (body, state) => {
|
|
39
|
+
state.charge = body.latest_charge;
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{ tool: "list_payment_intents", arguments: { limit: 10 } },
|
|
43
|
+
{ tool: "retrieve_charge", arguments: (state) => ({ id: state.charge }) },
|
|
44
|
+
{ tool: "list_charges", arguments: (state) => ({ payment_intent: state.pi }) },
|
|
45
|
+
{
|
|
46
|
+
tool: "create_refund",
|
|
47
|
+
arguments: (state) => ({ charge: state.charge, amount: 7500 }),
|
|
48
|
+
capture: (body, state) => {
|
|
49
|
+
state.refund = body.id;
|
|
50
|
+
},
|
|
51
|
+
verify: (body) => typeof body.balance_transaction === "string"
|
|
52
|
+
? undefined
|
|
53
|
+
: "a refund should link its negative refund-type balance transaction (F-733)",
|
|
54
|
+
},
|
|
55
|
+
{ tool: "retrieve_refund", arguments: (state) => ({ id: state.refund }) },
|
|
56
|
+
{ tool: "list_refunds", arguments: (state) => ({ charge: state.charge }) },
|
|
57
|
+
{
|
|
58
|
+
tool: "retrieve_balance",
|
|
59
|
+
verify: (body) => {
|
|
60
|
+
const usd = body.available?.find((b) => b.currency === "usd");
|
|
61
|
+
// 20000 settled minus the 7500 refund above.
|
|
62
|
+
return usd?.amount === 12500
|
|
63
|
+
? undefined
|
|
64
|
+
: `available balance should reflect the refund (expected 12500, got ${usd?.amount})`;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
tool: "list_balance_transactions",
|
|
69
|
+
arguments: { limit: 10 },
|
|
70
|
+
verify: (body) => {
|
|
71
|
+
const data = body.data ?? [];
|
|
72
|
+
return data.some((t) => t.type === "refund" && t.amount === -7500)
|
|
73
|
+
? undefined
|
|
74
|
+
: "the ledger should carry the negative refund-type entry (F-733)";
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
tool: "list_events",
|
|
79
|
+
arguments: { limit: 10 },
|
|
80
|
+
capture: (body, state) => {
|
|
81
|
+
state.event = body.data?.[0]?.id;
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{ tool: "retrieve_event", arguments: (state) => ({ id: state.event }) },
|
|
85
|
+
// Second PI: the cancel path (a settled PI refuses cancellation)
|
|
86
|
+
{
|
|
87
|
+
tool: "create_payment_intent",
|
|
88
|
+
arguments: createPi,
|
|
89
|
+
capture: (body, state) => {
|
|
90
|
+
state.pi2 = body.id;
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
{ tool: "cancel_payment_intent", arguments: (state) => ({ id: state.pi2 }) },
|
|
94
|
+
// Customer-management chain (F-732): CRUD + card-on-file attach/detach.
|
|
95
|
+
{
|
|
96
|
+
tool: "create_customer",
|
|
97
|
+
arguments: { name: "Parity Customer", email: "parity@example.com", metadata: { a: "1" } },
|
|
98
|
+
capture: (body, state) => {
|
|
99
|
+
state.customer = body.id;
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{ tool: "retrieve_customer", arguments: (state) => ({ id: state.customer }) },
|
|
103
|
+
{
|
|
104
|
+
tool: "update_customer",
|
|
105
|
+
arguments: (state) => ({ id: state.customer, name: "Parity Customer II", metadata: { a: "", b: "2" } }),
|
|
106
|
+
verify: (body) => {
|
|
107
|
+
const metadata = body.metadata ?? {};
|
|
108
|
+
if (metadata.a !== undefined)
|
|
109
|
+
return "metadata key 'a' should have been unset by the empty value";
|
|
110
|
+
if (metadata.b !== "2")
|
|
111
|
+
return "metadata key 'b' should have been merged in";
|
|
112
|
+
return undefined;
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
{ tool: "list_customers", arguments: { limit: 10 } },
|
|
116
|
+
{
|
|
117
|
+
tool: "create_payment_method",
|
|
118
|
+
arguments: { type: "card", card: { number: "4242424242424242", exp_month: 12, exp_year: 2032 } },
|
|
119
|
+
capture: (body, state) => {
|
|
120
|
+
state.pm = body.id;
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{ tool: "retrieve_payment_method", arguments: (state) => ({ id: state.pm }) },
|
|
124
|
+
{
|
|
125
|
+
tool: "attach_payment_method",
|
|
126
|
+
arguments: (state) => ({ id: state.pm, customer: state.customer }),
|
|
127
|
+
verify: (body) => body.customer ? undefined : "attach should set customer",
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
tool: "list_customer_payment_methods",
|
|
131
|
+
arguments: (state) => ({ customer: state.customer }),
|
|
132
|
+
verify: (body) => (body.data?.length ?? 0) === 1
|
|
133
|
+
? undefined
|
|
134
|
+
: "customer should list exactly the attached PM",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
tool: "detach_payment_method",
|
|
138
|
+
arguments: (state) => ({ id: state.pm }),
|
|
139
|
+
verify: (body) => body.customer === null ? undefined : "detach should clear customer",
|
|
140
|
+
},
|
|
141
|
+
{ tool: "delete_customer", arguments: (state) => ({ id: state.customer }) },
|
|
142
|
+
// Card collect-payment chain (F-731): create bare card PI → attach a PM
|
|
143
|
+
// via update (the ruled retry step) → confirm → synchronous settle.
|
|
144
|
+
{
|
|
145
|
+
tool: "create_payment_intent",
|
|
146
|
+
arguments: { amount: 12000, currency: "usd", payment_method_types: ["card"] },
|
|
147
|
+
capture: (body, state) => {
|
|
148
|
+
state.cardPi = body.id;
|
|
149
|
+
},
|
|
150
|
+
verify: (body) => body.status === "requires_payment_method"
|
|
151
|
+
? undefined
|
|
152
|
+
: "a card PI without a PM should start in requires_payment_method",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
tool: "create_payment_method",
|
|
156
|
+
arguments: { type: "card", card: { number: "4242424242424242", exp_month: 12, exp_year: 2033 } },
|
|
157
|
+
capture: (body, state) => {
|
|
158
|
+
state.cardPm = body.id;
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
tool: "update_payment_intent",
|
|
163
|
+
arguments: (state) => ({ id: state.cardPi, payment_method: state.cardPm }),
|
|
164
|
+
verify: (body) => body.status === "requires_confirmation"
|
|
165
|
+
? undefined
|
|
166
|
+
: "attaching a PM should move the card PI to requires_confirmation",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
tool: "confirm_payment_intent",
|
|
170
|
+
arguments: (state) => ({ id: state.cardPi }),
|
|
171
|
+
verify: (body) => body.status === "succeeded"
|
|
172
|
+
? undefined
|
|
173
|
+
: "confirming a good card should settle synchronously",
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
await runParityCli({
|
|
177
|
+
app: createTwinStripeApp(),
|
|
178
|
+
twin: "stripe",
|
|
179
|
+
inventory: loadFidelityInventory(join(import.meta.dirname, "..", "fidelity.inventory.json")),
|
|
180
|
+
liveToolNames: listTools().map((tool) => tool.name),
|
|
181
|
+
steps,
|
|
182
|
+
restProbes: [
|
|
183
|
+
{ surface: "unsupported-rest", path: "/v1/checkout/sessions", status: 501, expectUnsupportedEnvelope: true },
|
|
184
|
+
],
|
|
185
|
+
});
|
|
186
|
+
//# sourceMappingURL=fidelity-parity.js.map
|