Skip to content

feat(events): events + subscriptions top-level command groups (PR-1b)#50

Merged
mikemolinet merged 1 commit into
mainfrom
feat/events-and-subscriptions
May 11, 2026
Merged

feat(events): events + subscriptions top-level command groups (PR-1b)#50
mikemolinet merged 1 commit into
mainfrom
feat/events-and-subscriptions

Conversation

@mikemolinet
Copy link
Copy Markdown
Collaborator

Summary

Adds two top-level command groups for the event-emit primitive — third + final layer of PR-1b parity (cueapi-core #71 merged @ 03:53Z; cueapi-python #38 merged @ 03:55Z; this is the cli).

  • cueapi events list <ref> — pull events for an agent
  • cueapi subscriptions create <ref> — create a subscription
  • cueapi subscriptions list <ref> — list active subscriptions
  • cueapi subscriptions delete <ref> <subscription-id> — soft-detach

Closes Backlog row cmp0h2nzd000204l8acl5j6w0.

Top-level vs agents-nested

Top-level groups per primary's kickoff doc suggestion. Events + subscriptions are conceptually distinct primitives, not agent metadata. Same pattern as top-level messages and executions groups (also user-scoped operations on a sub-resource).

CLI architecture note

This port uses cueapi-cli's own httpx-based CueAPIClient, NOT the cueapi-python SDK. The kickoff doc said the cli port "uses cueapi-python SDK so blocked on #2 landing" — that's incorrect re: the actual cli architecture. cli has its own client.py with no runtime dependency on cueapi-python. cli port is INDEPENDENT of python SDK timing.

(Flagged to PM in the earlier status cue.)

Wire format pinned

Command HTTP
events list GET /v1/agents/{ref}/events?limit=100[&since=N&event_type=X]
subscriptions create POST /v1/agents/{ref}/subscriptions body {event_type, delivery_target, webhook_url?}
subscriptions list GET /v1/agents/{ref}/subscriptions
subscriptions delete DELETE /v1/agents/{ref}/subscriptions/{id} (idempotent)

Client-side guards

  • subscriptions create: --webhook-url required when --delivery-target=webhook. Raised as click.UsageError at parse time vs letting server 400.
  • Both subscriptions create and events list surface 404 agent-not-found with friendly error messages.

One-shot webhook secret discipline

When subscriptions create --delivery-target=webhook returns a webhook_secret, the cli surfaces it with "save now — only shown once" labeling. Same pattern as the existing agents webhook-secret regenerate command.

Tests

12 new tests in tests/test_cli.py:

  • events list: basic, with --since + --event-type, defaults only limit, 404 agent not found
  • subscriptions create: pull-minimal, webhook-with-url, webhook-without-url errors client-side
  • subscriptions list: basic, empty
  • subscriptions delete: basic
  • Help: events lists list subcommand, subscriptions lists create/list/delete
12 passed, 179 deselected

Full suite: 191 tests pass, zero regressions.

Depends on

Test plan

  • 12 new tests pass locally
  • Verified server contract (POST/GET/DELETE shapes + query semantics)
  • Client-side guards (webhook-url required, mutex enforcement)
  • 404 friendly error
  • Idempotent DELETE handled
  • CI green
  • Admin-merge per agents-merge-own-PRs directive

🤖 Generated with Claude Code

Adds two top-level command groups for the event-emit primitive
(cueapi-core PR #71, OSS counterpart of cueapi/cueapi#731):

- `cueapi events list <ref>` — pull events for an agent
- `cueapi subscriptions create <ref>` — create a subscription
- `cueapi subscriptions list <ref>` — list active subscriptions
- `cueapi subscriptions delete <ref> <subscription-id>` — soft-detach

Top-level groups per primary's kickoff doc suggestion (vs nesting
under `agents`) — events/subscriptions are conceptually distinct
primitives, not agent metadata. Same pattern as the top-level
`messages` and `executions` groups (which are also user-scoped
operations on a sub-resource).

## CLI architecture note

This port uses cueapi-cli's own httpx-based client (CueAPIClient),
NOT the cueapi-python SDK. The kickoff doc said the cli port "uses
cueapi-python SDK so blocked on #2 landing" — that's incorrect re:
the actual cli architecture (cli has its own client.py + no
runtime dependency on cueapi-python). cli port is INDEPENDENT of
python SDK timing. Flagged to PM.

## Wire format pinned

- `events list`: GET `/v1/agents/{ref}/events` with `limit` (default
  100) + optional `since` cursor + optional `event_type` filter.
- `subscriptions create`: POST body `{event_type, delivery_target,
  webhook_url?}` to `/v1/agents/{ref}/subscriptions`. Client-side
  guard: `--webhook-url` required when `--delivery-target=webhook`
  (surface at parse time vs server 400).
- `subscriptions list`: GET `/v1/agents/{ref}/subscriptions`.
- `subscriptions delete`: DELETE on `/subscriptions/{id}` (idempotent).

## Tests

12 new tests in `tests/test_cli.py`:

- events list: basic, with since+event_type, defaults only limit,
  404 agent not found
- subscriptions create: pull minimal, webhook with url, webhook
  without url errors client-side
- subscriptions list: basic, empty
- subscriptions delete: basic
- help: events lists `list` subcommand, subscriptions lists
  create/list/delete

12/12 pass. Full suite: 191 tests collected, all events/subscriptions
pass; no regressions.

## One-shot webhook secret discipline

When `subscriptions create --delivery-target=webhook` returns a
`webhook_secret`, the cli surfaces it with the "save now — only
shown once" label. Same pattern as `agents webhook-secret regenerate`.

Depends on cueapi-core PR #71 (merged 03:53Z, commit 50d2b2c2).

Closes Backlog row: cmp0h2nzd000204l8acl5j6w0
@govindkavaturi-art govindkavaturi-art enabled auto-merge (squash) May 11, 2026 03:58
@mikemolinet mikemolinet merged commit 2bd30a2 into main May 11, 2026
5 checks passed
@mikemolinet mikemolinet deleted the feat/events-and-subscriptions branch May 11, 2026 03:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant