Repository navigation
feat(cli): data-plane commands for agents (contacts, segments, broadcasts, workflows, templates, metrics, health, approvals) - #219
Merged
Conversation
…oadcasts, workflows, templates, metrics, health, approvals) Tier 1 of the agent surface parity plan: CLI commands over API routes that already exist, following the `email logs` pattern (resolveApiTarget, --json envelope, --token, --limit/--cursor/nextCursor, actionable errors). - contacts list|get|create|update|delete - segments list|get|create|update|delete|preview - broadcasts create|send|status|recipients|resume - workflows trigger|enable|disable|retry|cancel - email templates list|get|pull|publish|duplicate - email metrics, email health - email agent approvals list|approve|reject (id via --id) Mutating commands require --yes. Errors set exit code 1. Registered in cli.ts help, did-you-mean, and the telemetry command-name pairs so word-shaped ids never reach event names. Documented in llms-full.txt and the CLI reference. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd
…lth and approvals `email metrics`, `email health` and `email agent approvals` answered a 401 with UNAUTHORIZED while every other command answers NOT_AUTHENTICATED. Found by running the CLI against the real API. Each test file asserted only its own code, so nothing caught it. Add agent-surface-contract.test.ts: 23 commands through the same four failure modes (401, no API target, network error, hostile id), asserting one --json envelope with a message and suggestion and exitCode 1. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd
…copy Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
This was referenced Oct 28, 2026
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tier 1 of the agent-surface parity plan: the data-plane API routes that agents could only reach over HTTP are now
wrapscommands. All support--jsonand followlogs.ts; destructive ones need--yes.Every command resolves its target through
resolveApiTarget/checkApiTargetand shares one error contract:The last commit fixes a break in that contract found by the e2e run:
email metrics,email healthandemail agent approvalsreturnedUNAUTHORIZEDfor a rejected key. A newagent-surface-contract.test.tsdrives 23 commands through the same four failure modes so a single command cannot drift again.Also touched:
cli.ts,arg-parser.ts,did-you-mean.ts(new commands only, additive),repo-map.md,llms-full.txt, the two CLI reference pages, and regeneratedpage-dates.ts.Evidence
health.tschanged nothing in the suite.After:
agent-surface-contract.test.tsfails on that regression (expected 'UNAUTHORIZED' to be 'NOT_AUTHENTICATED') and on droppingencodeURIComponentfrom an id. Both were checked, then restored.Real API: about 150 CLI invocations against
apps/apion a disposable Neon test branch (SQS/AWS blanked). Covered contacts and segments lifecycles, template reads and pull overwrite protection, no/bogus/malformed/expired keys,--tokenprecedence, free-planPLAN_REQUIRED, org-1 key against org-2 ids (NOT_FOUND, org 2 untouched), and hostile ids such ascontacts delete ../segments/<id> --yes(the segment survived). Every run printed one JSON document with empty stderr.Not exercised, because they reach AWS:
broadcasts send/resume/unscheduledcreate, success paths ofworkflows trigger|enable|disable|retry|cancel,templates publish --yes, andapprovals approve|reject. Metrics/health values were not checked against CloudWatch/SES.Three problems found by the e2e run are not fixed here and are tracked as separate branches: API accepts another org's
segmentIdonPOST /v1/batch; malformed templates--cursorreturns 200 with page one;--limit -1(space form) is ignored by the shared parser.Merge Danger
Door: two-way
New commands and additive parser/help entries only. No API, schema, or infra change. Reverting the merge removes the commands.
Blast Radius: CLI
arg-parser.tsanddid-you-mean.tsare shared by every command, but the diff only adds lines.page-dates.tsis regenerated, so it may need a re-run ifmainmoves.🤖 Generated with Claude Code
https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd