feat(payment): add read-only imperative commands - #2276
Conversation
|
Claude Security Review: no high-confidence findings. (run) |
There was a problem hiding this comment.
AgentCore Harness Review
Verdict: Looks good
This is a well-scoped read-only surface for AgentCore Payments. I reviewed the diff end-to-end and did not find issues that need to change before merging.
Highlights that made this easy to sign off on:
- Boundaries.
PaymentClientsits cleanly on top of the shared control/data client factories. Data-plane methods route through a singlesendDatahelper that (a) rejects ARN-shapedmanagerIdbefore any client is configured, (b) fetches the manager fresh on every call, (c) refusesCUSTOM_JWTmanagers with aUSER-sourcedInputValidationErrorthat explains the bearer-token limitation, and (d) surfaces aMalformedServiceResponseErrorwhen the service omits the ARN. Each of these branches is asserted inpayment.read.test.ts. - Handlers. Required-flag validation happens before Core is touched, and the tests confirm no SDK client is ever constructed on the failure path (both
omittedandemptyvariants). ARN selectors and the removed--manager-arnflag are explicitly rejected. - Big-number fidelity.
GetPaymentInstrumentBalanceresponses are handed straight to the JSON renderer, andbalance.test.tsxpins down that the atomicamountstring beyondMAX_SAFE_INTEGERand itsdecimalssurvive round-tripping, including the"0"case. The handler correctly does not convert service errors to a zero balance. - Region/endpoint propagation. Both control and data client factories receive the same
{ region, endpoint }derived from context; verified for theeu-west-1+ custom endpoint case. - Test style. Mocks live at the SDK
sendboundary and everything else — router, CoreClient, JSON rendering, IO — runs for real. Fixture replay viafixtureFactoriesgives realistic wire shapes without over-mocking. - Command tree.
payment.read.test.tsxasserts the exact nine-leaf shape (manager get/list,connector get/list,session get/list,instrument get/list/balance) and that no leaf accepts--wait/--browseror exposes TUI, matching the "CLI only for now" stance in the README. - Identity surface. Only
getandlistare wired forpayment-credential-provider, consistent with the read-only scope; the create/update/delete methods added toCoreIdentityClientare unexposed but ready for a follow-up. - Connector hints.
connector getemits theAUTHENTICATION_EXPIRED/AUTHENTICATION_FAILEDwarning only in non-JSON mode and never suggests write commands that don't exist yet — tested for both--jsonand bare invocations.
Nothing blocking. Ship it.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## refactor #2276 +/- ##
============================================
+ Coverage 97.03% 97.08% +0.05%
============================================
Files 584 602 +18
Lines 39865 40338 +473
============================================
+ Hits 38682 39164 +482
+ Misses 1183 1174 -9 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Claude Security Review: no high-confidence findings. (run) |
|
Claude Security Review: no high-confidence findings. (run) |
jariy17
left a comment
There was a problem hiding this comment.
left some nits otherwise clean pr
| @@ -0,0 +1,111 @@ | |||
| import { expect, mock, test } from "bun:test"; | |||
There was a problem hiding this comment.
We don't need this. Use golden tests in handlers
There was a problem hiding this comment.
Removed src/core/payment.read.test.ts in 2a80958. Get/List coverage uses the existing handler goldens through the real root and Core. The small set of manager-preflight and service-error checks now reuses the handler setup; no separate Core test harness or new fixtures.
| description: "get a payment credential provider", | ||
| flags: [flag("name", "the payment credential provider name (required)", z.string().optional())], | ||
| handle: async (ctx, flags) => { | ||
| if (!flags.name) { |
There was a problem hiding this comment.
Thanks to @Hweinstock, we can now set the flags to required;
There was a problem hiding this comment.
Updated required selectors across all payment and payment-provider read handlers to non-optional schemas, using .min(1) to retain empty-value rejection. The shared router now handles missing-option errors and required help labels; handwritten presence checks and duplicate labels are removed. Optional filters and pagination remain optional.
|
|
||
| // A lapsed or failed OAuth consent is terminal for a Quick Create | ||
| // connector: the service issues no second authorization URL. | ||
| if ( |
There was a problem hiding this comment.
I removed this for now. We cannot be 100% sure that AUTHENTICATION_EXPIRED or AUTHENTICATION_FAILED was caused by a OAUTH failure. Also, I'm a little confused why a OAuth Url is generated here.
There was a problem hiding this comment.
Removed the status-based warning, its warning-only test, and unused IO wiring in cc67ddc. Get now only fetches and renders the API response. The CLI does not generate or renew an OAuth URL here; any authorizationUrl remains service-returned data in the response.
ebe1358 to
2a80958
Compare
|
Claude Security Review: no high-confidence findings. (run) |
Description
First layer of the AgentCore Payments command stack, targeting
refactor.Mutation follow-ups #2277 (identity providers), #2280 (managers/connectors), and
#2281 (sessions/instruments) are temporarily closed with their branches preserved.
The current focus is the read CLI, followed by a separate read-only TUI PR.
Rebased onto
refactorat363bfb28(CLI1.0.0-rc.2).Read help now distinguishes application-user scope from optional observability labels,
orders required selectors before optional inputs, and uses the existing Gateway/Identity
pagination wording. README examples connect manager selection, instrument list/get, and
balance. Required selectors use nonempty schemas and the router's shared validation;
optional filters and pagination remain optional. Connector get renders the service response
without inferring OAuth failures from its status or emitting a separate warning.
Adds 11 project-free, headless read commands:
payment manager get|listpayment connector get|listpayment session get|listpayment instrument get|list|balanceidentity payment-credential-provider get|listPrimary selectors use IDs. For session/instrument reads, Core resolves the manager with
GetPaymentManagerin the configured region and supplies the returned ARN to the data plane.Callers therefore need the manager-read permission as well as the requested data-plane action.
JWT-only managers are rejected before data-plane access.
Balance requires an explicit chain, defaults to USDC, preserves atomic amount strings/decimals,
and propagates service errors rather than converting them to zero.
The layer includes read-side Core contracts, injected client wiring, read-only tests, and recorded
Get/List fixtures. It adds no payment mutation handlers, IAM provisioning, credential-write input
handling, or dedicated TUI screens.
Related Issue
Part of #2272. The preserved mutation branches cover the remaining headless scope.
Documentation PR
N/A. README command tree, read examples, and permission requirements are updated here.
Type of Change
Testing
RECORD=0 bun test: 3,319 passed, 0 failed across 233 files.bun run typecheckbun run lint:check,bun run format:check,bun run secrets:checkbun run build--json.Read coverage lives in handler tests over the real root and Core. Get/List paths use recorded
goldens; pagination, manager-preflight failures, and service errors are checked at the SDK boundary.
Balance retains its chain/default-token/precision/zero/error checks. The separate Core test file
and the connector warning-only tests were removed. No fixtures were added or re-recorded.
Uses the
refactorBun scripts rather than the npm scripts from the repository'smaintemplate.No AWS resources were changed while preparing this split.
Checklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.