Skip to content

feat(cli): data-plane commands for agents (contacts, segments, broadcasts, workflows, templates, metrics, health, approvals) - #219

Merged
stewartjarod merged 5 commits into
mainfrom
agent-cli-tier1
Oct 28, 2026
Merged

stewartjarod merged 5 commits into
mainfrom
agent-cli-tier1

Conversation

@stewartjarod

@stewartjarod stewartjarod commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Tier 1 of the agent-surface parity plan: the data-plane API routes that agents could only reach over HTTP are now wraps commands. All support --json and follow logs.ts; destructive ones need --yes.

wraps
├── contacts    list | get | update | delete
├── segments    list | get | update | delete | preview
├── broadcasts  status | recipients | create | send | resume
├── workflows   trigger | enable | disable | retry | cancel
├── email
│   ├── templates   list | get | pull | duplicate | publish
│   ├── metrics
│   ├── health
│   └── agent approvals   list | approve | reject

Every command resolves its target through resolveApiTarget/checkApiTarget and shares one error contract:

401 / no key      -> NOT_AUTHENTICATED
unreachable API   -> NETWORK_ERROR
plan gate         -> PLAN_REQUIRED
missing --yes     -> CONFIRMATION_REQUIRED
unknown id        -> NOT_FOUND
ids               -> encodeURIComponent, always one path segment

The last commit fixes a break in that contract found by the e2e run: email metrics, email health and email agent approvals returned UNAUTHORIZED for a rejected key. A new agent-surface-contract.test.ts drives 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 regenerated page-dates.ts.

Evidence

  • Before: the contract was asserted per file. Putting the old code back in health.ts changed nothing in the suite.
    After: agent-surface-contract.test.ts fails on that regression (expected 'UNAUTHORIZED' to be 'NOT_AUTHENTICATED') and on dropping encodeURIComponent from an id. Both were checked, then restored.
typecheck                         exit 0
vitest (packages/cli)             149 files / 2685 tests pass
built CLI vs local mock API       147/147 smoke cases pass

Real API: about 150 CLI invocations against apps/api on a disposable Neon test branch (SQS/AWS blanked). Covered contacts and segments lifecycles, template reads and pull overwrite protection, no/bogus/malformed/expired keys, --token precedence, free-plan PLAN_REQUIRED, org-1 key against org-2 ids (NOT_FOUND, org 2 untouched), and hostile ids such as contacts 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/unscheduled create, success paths of workflows trigger|enable|disable|retry|cancel, templates publish --yes, and approvals 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 segmentId on POST /v1/batch; malformed templates --cursor returns 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.ts and did-you-mean.ts are shared by every command, but the diff only adds lines. page-dates.ts is regenerated, so it may need a re-run if main moves.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GxJAQNUP4FKZHL1yzPDsGd

stewartjarod and others added 3 commits October 28, 2026 12:12
…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
@vercel

vercel Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated
wraps-web Skipped Skipped Oct 28, 2026 6:37pm UTC
wraps-website Skipped Skipped Oct 28, 2026 6:37pm UTC

Request Review

stewartjarod and others added 2 commits October 28, 2026 12:36
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
@vercel
vercel Bot temporarily deployed to Preview – wraps-web October 28, 2026 18:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – wraps-website October 28, 2026 18:36 Inactive
@vercel
vercel Bot temporarily deployed to Preview – wraps-website October 28, 2026 18:37 Inactive
@vercel
vercel Bot temporarily deployed to Preview – wraps-web October 28, 2026 18:37 Inactive
@stewartjarod
stewartjarod merged commit 1e68153 into main Oct 28, 2026
19 of 21 checks passed
@stewartjarod
stewartjarod deleted the agent-cli-tier1 branch October 28, 2026 19:45

This branch was previously deployed

2 inactive deployments
Preview – wraps-website — 4781d247 Deployed Oct 28, 2026 by vercel[bot]
Preview – wraps-web — 4781d247 Deployed Oct 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant