Skip to content

feat(payment): add read-only imperative commands - #2276

Merged
aidandaly24 merged 15 commits into
refactorfrom
feat/payment-read-only
Sep 16, 2026
Merged

aidandaly24 merged 15 commits into
refactorfrom
feat/payment-read-only

Conversation

@aidandaly24

@aidandaly24 aidandaly24 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

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 refactor at 363bfb28 (CLI 1.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|list
  • payment connector get|list
  • payment session get|list
  • payment instrument get|list|balance
  • identity payment-credential-provider get|list

Primary selectors use IDs. For session/instrument reads, Core resolves the manager with
GetPaymentManager in 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

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

  • RECORD=0 bun test: 3,319 passed, 0 failed across 233 files.
  • bun run typecheck
  • bun run lint:check, bun run format:check, bun run secrets:check
  • bun run build
  • Focused handler read suite: 41 passed; help rendered for all 11 read commands without AWS clients.
  • Connector authentication statuses remain in JSON with no stderr warning, with or without --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 refactor Bun scripts rather than the npm scripts from the repository's main template.
No AWS resources were changed while preparing this split.

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

@github-actions github-actions Bot added the size/xl PR size: XL label Sep 10, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Sep 10, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 10, 2026

@agentcore-devx-automation agentcore-devx-automation Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. PaymentClient sits cleanly on top of the shared control/data client factories. Data-plane methods route through a single sendData helper that (a) rejects ARN-shaped managerId before any client is configured, (b) fetches the manager fresh on every call, (c) refuses CUSTOM_JWT managers with a USER-sourced InputValidationError that explains the bearer-token limitation, and (d) surfaces a MalformedServiceResponseError when the service omits the ARN. Each of these branches is asserted in payment.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 omitted and empty variants). ARN selectors and the removed --manager-arn flag are explicitly rejected.
  • Big-number fidelity. GetPaymentInstrumentBalance responses are handed straight to the JSON renderer, and balance.test.tsx pins down that the atomic amount string beyond MAX_SAFE_INTEGER and its decimals survive 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 the eu-west-1 + custom endpoint case.
  • Test style. Mocks live at the SDK send boundary and everything else — router, CoreClient, JSON rendering, IO — runs for real. Fixture replay via fixtureFactories gives realistic wire shapes without over-mocking.
  • Command tree. payment.read.test.tsx asserts the exact nine-leaf shape (manager get/list, connector get/list, session get/list, instrument get/list/balance) and that no leaf accepts --wait/--browser or exposes TUI, matching the "CLI only for now" stance in the README.
  • Identity surface. Only get and list are wired for payment-credential-provider, consistent with the read-only scope; the create/update/delete methods added to CoreIdentityClient are unexposed but ready for a follow-up.
  • Connector hints. connector get emits the AUTHENTICATION_EXPIRED / AUTHENTICATION_FAILED warning only in non-JSON mode and never suggests write commands that don't exist yet — tested for both --json and bare invocations.

Nothing blocking. Ship it.

@agentcore-devx-automation agentcore-devx-automation Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Sep 10, 2026
@codecov-commenter

codecov-commenter commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.37238% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.08%. Comparing base (363bfb2) to head (2a80958).

Files with missing lines Patch % Lines
src/core/identity.tsx 70.00% 3 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aidandaly24
aidandaly24 added this pull request to stack #2278 September 10, 2026 20:12
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 10, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 10, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 10, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 10, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 10, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 11, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 11, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 11, 2026
@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 15, 2026

@jariy17 jariy17 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left some nits otherwise clean pr

Comment thread src/core/payment.read.test.ts Outdated
@@ -0,0 +1,111 @@
import { expect, mock, test } from "bun:test";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this. Use golden tests in handlers

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks to @Hweinstock, we can now set the flags to required;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@aidandaly24
aidandaly24 force-pushed the feat/payment-read-only branch from ebe1358 to 2a80958 Compare September 16, 2026 18:02
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 16, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Sep 16, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Sep 16, 2026
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Sep 16, 2026
@aidandaly24
aidandaly24 dismissed jariy17’s stale review September 16, 2026 19:21

he verbally approved

@aidandaly24
aidandaly24 merged commit 62c88cb into refactor Sep 16, 2026
24 checks passed
@aidandaly24
aidandaly24 deleted the feat/payment-read-only branch September 16, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants