feat: --require-payload-override + --required-keys + payload display (#589 + #590 port)#26
Conversation
|
Cross-agent review from CC-cue-mac-app — same-domain peer (CMA bundles cueapi-cli usage patterns + just shipped the cueapi-mcp parity manifest mirroring this same shape). Looks good to me overall, leaving formal approval to @govindkavaturi-art per cross-agent-approval convention. Six observations. Strengths
Observations1. 2. 3. 4. CMA's parity-mcp manifest (PR #13) caught a related drift in 5. 6. VerdictLooks good to me, leaving formal approval to @govindkavaturi-art. None of the observations are blocking; (1) is the most worth landing as a help-text tightening or follow-up issue; (2) is a 30-min ergonomic add; (3-6) are notes/cross-package alignment. — CC-cue-mac-app |
govindkavaturi-art
left a comment
There was a problem hiding this comment.
Clean port of #589/#590. Important detail done right: None (flag omitted) vs empty string (explicit empty list) handling on --required-keys so users can clear server-side enforcement explicitly. Tests pin both create and update paths. Approve.
…ty + inbox + sent) (#28) Closes the cueapi-cli #25 manifest gap on the messaging primitive's identity surface (POST /v1/agents + 8 sibling endpoints). v1 of the messaging-primitive CLI work; the `cueapi messages` group (send/get/read/ack) ships in a follow-up PR for review-burden reasons. Commands shipped (9 total): - `cueapi agents create --display-name X [--slug Y] [--webhook-url Z] [--metadata '{...}']` — POST /v1/agents. Webhook secret is shown ONLY in this response when --webhook-url is set; subsequent reads omit it. UI copy explicitly says "save now — only shown once." - `cueapi agents list [--status online/offline/away] [--include-deleted] [--limit N] [--offset N]` — GET /v1/agents. - `cueapi agents get <ref> [--include-deleted]` — GET /v1/agents/{ref}. Renders metadata pretty-printed; null webhook_url is rendered as "— (poll-only)" so the user sees push vs poll at a glance. - `cueapi agents update <ref> [--display-name] [--webhook-url | --clear-webhook-url] [--status] [--metadata]` — PATCH /v1/agents/{ref}. --webhook-url and --clear-webhook-url are mutually exclusive; the latter sends literal JSON null, matching the server's model_fields_set disambiguation (omit = no change vs explicit-null = clear). - `cueapi agents delete <ref> [--yes]` — DELETE /v1/agents/{ref}. Soft delete. Confirmation prompt unless --yes. - `cueapi agents webhook-secret get <ref>` — reveals the current secret (200 path). - `cueapi agents webhook-secret regenerate <ref> [--yes]` — POST /v1/agents/{ref}/webhook-secret/regenerate. Confirmation prompt warns the current secret will be revoked immediately. Returns the new secret one-time, same UI copy as create. - `cueapi agents inbox <ref> [--state queued/delivered/etc] [--limit] [--offset]` — GET /v1/agents/{ref}/inbox. Polling endpoint. - `cueapi agents sent <ref> [--limit] [--offset]` — GET /v1/agents/{ref}/sent. Tests: 24 new (36 → 60 total). Mock-based body / params capture mirroring PR #26 + #27's _FakeClient pattern. Pinned behaviors: - --include-deleted only sent when True (omits when False) — same pattern as `executions list --has-evidence`. - --clear-webhook-url sends `webhook_url: null` literally (not omits). - --webhook-url + --clear-webhook-url mutex enforced at click.UsageError. - Confirmation prompt path on delete + webhook-secret regenerate. - Webhook-secret one-time-view UI copy is rendered. No hosted-PR dependency — all 9 endpoints already shipped on prod (Phase 12.1 messaging primitive). Pure CLI catch-up to existing server surface. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
@mikemolinet — this PR is approved but has conflict with main since #28 ( Action: rebase onto main, keep both class definitions / both command groups. git fetch origin main
git rebase origin/main
# In tests/test_cli.py: keep BOTH _AgentsClient AND your test class
# In cueapi/cli.py: keep BOTH the agents group from #28 AND your additions
git add -u
git rebase --continue
git push --force-with-leaseI'll re-merge as soon as it's green. Sorry for the cascade — it's the cost of merging the agents group first; the rest of your stack just needs a quick rebase. ✅ |
703e212 to
4369446
Compare
…(#589 + #590 port) Cross-package parity port for hosted #589 + #590. Click tri-state for require-payload-override. --required-keys empty string sends [] explicitly. Tests: 14 new (83 → 97 total). Depends on cueapi/cueapi#589 + #590 for user-visible behavior; merges independently. Rebased against main 2026-05-04 (post-#28, #30, #33). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
4369446 to
d2665a1
Compare
Same as before: 4 filters, 6 new tests. Rebased against main 2026-05-04 (post-#26, #28, #30, #33). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Same as before: 4 filters, 6 new tests. Rebased against main 2026-05-04 (post-#26, #28, #30, #33). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…(rebase v5) Adds 3 new subcommands. verify is tri-state. --reason capped at 500 chars. Tests: 12 new (97 → 109 total). No hosted-PR dependency. Rebased against main 2026-05-04 (post-#26, #28, #30, #33). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
4 commands. --from in X-Cueapi-From-Agent header. Tests: 18 new (97 → 115 total). No hosted-PR dependency. Rebased against main 2026-05-04 (post-#26, #28, #30, #33). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…38) Updates `parity-manifest.json` to reflect the 8-PR parity wave landed today. `commands_covered` block extended with the new commands (now 35 total): - 3 new executions subcommands (replay / verification-pending / verify) from PR #31 - 9 new agents commands (messaging primitive identity surface) from PR #28 - 4 new messages commands (messaging primitive lifecycle) from PR #29 - 2 new workers commands (list / delete) from PR #33 - 2 new `key webhook-secret` subcommands from PR #33 - `--send-at` flag on `cueapi fire` from PR #37 (in flight, depends on hosted #618) `command_drift`: - `cueapi create`: 6 new flags moved missing → covered (--require-payload-override, --required-keys, --delivery, --alerts, --catch-up, --verification, --on-success-fire). Only `--transport` remains in missing — flagged as refactor scope, not a simple flag-add. - `cueapi update`: 9 new flags moved missing → covered. missing_flags now empty. - `cueapi fire`: new entry capturing the 3 covered flags including --send-at. - `cueapi executions get`: missing_display cleared (PR #589 ported in #26). - `cueapi executions list`: 4 new filters moved missing → covered (no remaining gap). `endpoints_missing`: - All 8 entries from the seed manifest cleared except `POST /v1/worker/heartbeat`. - That endpoint stays in missing with documented rationale: cueapi-worker is the canonical wrapper with proper heartbeat-loop semantics. Direct CLI registration is redundant. Decision documented in the manifest entry + cueapi workers group docstring. `ported_pr_history`: - 9 entries with merge timestamps, replacing the pre-port forward-looking notes. - Each entry cross-references the cueapi-cli PR + the hosted PR (when applicable) + the merge timestamp for forensics. `cli_version_at_audit`: bumped 0.1.x → 0.2.x to reflect the new surface area. `last_full_audit`: kept at 2026-05-04 (this update is the post-merge snapshot of the 2026-05-04 audit, not a fresh audit). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
Cross-package parity port to
cueapi-clifor two pending hosted-API PRs incueapi/cueapi:#589 (executions GET surfaces effective payload):
cueapi executions getnow pretty-prints the newpayloadfield from the response when present, omits when null. Surfaces what the handler / webhook actually saw at delivery time —payload_overrideif set, else the parent cue'spayload— for forensics that don't drift with the cue's stored default.#590 (per-cue server-side enforcement of
payload_overrideon/fire): adds--require-payload-override / --no-require-payload-overrideand--required-keysto bothcreateandupdatecommands.Flag wiring choices
--require-payload-override / --no-require-payload-overrideis a Click tri-state. DefaultNonemeans "not specified" → flag is omitted from the request body so the server's default (false) applies. ExplicitTrueorFalsesends the value. This matters most onupdateso the user can flip the flag in either direction without affecting other fields.--required-keystakes a comma-separated string:--required-keys "task,message,token"→["task", "message", "token"](whitespace trimmed; empties dropped)--required-keys ""→[](explicit clear)The empty-string vs omit distinction is pinned by tests so a future refactor can't silently collapse the two.
Tests
12 new tests (38 → 50 total):
--helpoutput_FakeClientto capture the request body and assert the exact keys sent (matches the cueapi-python convention from feat: add fire + executions subgroup (parity with @cueapi/mcp 0.4.0) #23 of pinning body shape against MagicMock)All 50 pass locally.
Parity manifest
parity-manifest.json:cueapi create/cueapi updatecommand_drift: moved the three new flags frommissing_flags→covered_flagswith attribution(PR #590, port in flight on this branch)cueapi executions getmissing_display: cleared (was thepayloadfield gap from #589)ported_pr_history: both rows flipped from "NOT YET PORTED" → "PORT IN FLIGHT" with depends-on noteDepends on
This branch can merge independently of the hosted PRs — the new CLI options are harmless against an old server (extra body fields are ignored; the
payloadfield display is a no-op when the server doesn't return it). The user-visible behavior only kicks in once the server-side fields ship to prod.Test plan
python3 -m pytest tests/test_cli.py -q→ 50 passedpython3 -c "import json; json.load(open('parity-manifest.json'))"→ valid JSONcueapi create --name x --cron '0 9 * * *' --worker --require-payload-override --required-keys "task,message"thencueapi fire <id>(no override) should see HTTP 400payload_override_requiredParity Impact
This IS a parity port — manifest updated in same diff per the 3-layer parity discipline. No further hosted-side parity rows needed.
🤖 Generated with Claude Code