Skip to content

feat: agent-first JSON output contract - #7

Merged
jordanpartridge merged 7 commits into
mainfrom
cursor/agent-json-contract-6412
Sep 12, 2026
Merged

jordanpartridge merged 7 commits into
mainfrom
cursor/agent-json-contract-6412

Conversation

@jordanpartridge

Copy link
Copy Markdown
Contributor

Summary

Consistent agent-friendly JSON output contract.

  • OutputsJson concern with {ok, data|error} shape
  • Applied across zones/DNS/tunnel commands; stable exit codes
  • docs/agent-output.md + README blurb
  • Feature tests
  • PHP 8.3-compatible lockfile

Test plan

  • CI green
  • Review JSON contract doc
Open in Web Open in Cursor 

@jordanpartridge
jordanpartridge force-pushed the cursor/agent-json-contract-6412 branch from 195f4dc to 1590c5c Compare September 10, 2026 05:54

@lexi-chief-of-staff lexi-chief-of-staff Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Blocking: TunnelCreateCommand duplicates getConnector instead of extending InteractsWithCloudflare.

  • The alias hack on line 9 of TunnelCreateCommand.php creates two implementations of connector lookup.
  • Other commands still rely on the trait; this divergence will drift.
  • Tests cover the happy path but not the new cancellation JSON case in tunnel:delete.
  • Minor: several getConnector signatures now return ?CloudflareConnector but callers only check null after the call; consistent with the new flow.

@lexi-chief-of-staff lexi-chief-of-staff Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

TunnelListCommand now duplicates getConnector instead of using InteractsWithCloudflare (or the new trait). The rest of the JSON envelope contract, null-guard pattern, and tests look consistent.

  • One duplication to clean up before merging.
  • No blocking correctness issues.

@jordanpartridge

Copy link
Copy Markdown
Contributor Author

Addressed the blocking review on 74b2192:

  • TunnelCreateCommand uses InteractsWithCloudflare directly (no alias, no second getConnector).
  • Trait getConnector() returns null instead of exit(1) so --json can emit the envelope.
  • tunnel:delete uses the same trait.
  • Added a test for the cancelled tunnel:delete --json envelope (--no-interaction → deleted: false, cancelled: true).

cursoragent and others added 4 commits September 10, 2026 06:33
Add OutputsJson concern with {"ok":true,"data":...} / {"ok":false,"error":"..."}
envelopes on stdout, apply across zones/dns/tunnel commands, document the
contract, add Pest coverage with Saloon mocks, and wire PHP 8.3 CI.

Co-authored-by: Jordan Partridge <jordan@partridge.rocks>
Human mode still prints create-time token and cloudflared run steps
after rebasing onto tunnel:expose.
Drop the getConnector alias on tunnel:create. Trait now returns null
instead of exit(1) so --json can emit the envelope. Cover cancelled
tunnel:delete JSON.
Prove --json --no-interaction returns {ok:true,data:{deleted:false,cancelled:true}} as JSON, not substring matches.
jordanpartridge added a commit that referenced this pull request Sep 10, 2026
Research seat. Commands + Saloon PUT overwrite. Raw --json, not the
#7 envelope. Keep tunnel:expose README. Do not merge.
--json stdout is {ok,data} / {ok,error} exit 0/1.
InteractsWithCloudflare + OutputsJson; no CloudflareCommand; no exit(1).
Missing token must be CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID must be set.
Cancelled tunnel:delete --json --no-interaction stays ok:true exit 0.
tunnel:expose --json wraps the existing object so token/url toContain stays green.
Drop duplicated getConnector on zones, dns, and tunnel:list.
Wrap tunnel:expose --json in the agent envelope. getConnector
stays nullable and never exits. Human tunnel:create still prints
the create-time token.
@jordanpartridge
jordanpartridge force-pushed the cursor/agent-json-contract-6412 branch from 74b2192 to 9124ed1 Compare September 10, 2026 13:40

@lexi-chief-of-staff lexi-chief-of-staff Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ship it.

  • One minor inconsistency flagged inline (TunnelDeleteCommand declares --json in signature; others do not).
  • No exit() calls remain, missing-creds path now returns FAILURE cleanly, envelope contract matches spec and tests.
  • All commands use both traits, raw json_encode paths removed, human output untouched.
  • Tests cover missing creds, success, API error, cancellation, and tunnel:expose wrapping.

Ready to merge.

jordanpartridge added a commit that referenced this pull request Sep 10, 2026
PR #5 must not claim docs/agent-output.md or the {ok,data} envelope
(that is unmerged #7). Fold demo.md / demo.cast.md from #4; leave
the hero README crew and PHAR install alone.
@jordanpartridge
jordanpartridge marked this pull request as ready for review September 12, 2026 13:32
@jordanpartridge
jordanpartridge merged commit 4171b61 into main Sep 12, 2026
1 check passed
@jordanpartridge
jordanpartridge deleted the cursor/agent-json-contract-6412 branch September 12, 2026 13:32

@lexi-chief-of-staff lexi-chief-of-staff Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ship it.

  • All seven commands now use both InteractsWithCloudflare + OutputsJson traits, no duplicate getConnector methods remain, and no exit() calls exist under app/Commands.
  • Missing creds (token or account id) produces the exact failure envelope on --json and human error otherwise; reportMissingCloudflareCredentials guards the single print path.
  • jsonSuccess/jsonFail route everything through stdout with correct exit codes; human output paths unchanged.
  • Tests cover the contract (missing creds, success, cancel, API error, expose wrapper) and keep existing TunnelExposeCommandTest green.
  • docs/agent-output.md and README accurately document the envelope and per-command data shape.

jordanpartridge added a commit that referenced this pull request Sep 12, 2026
Research seat. Commands + Saloon PUT overwrite. Raw --json, not the
#7 envelope. Keep tunnel:expose README. Do not merge.
jordanpartridge added a commit that referenced this pull request Sep 12, 2026
* feat: wire orphaned DNS/tunnel API into dns:delete, dns:update, tunnel:get

Complete CRUD gaps by adding DnsDeleteCommand and TunnelGetCommand for
existing DeleteDnsRecord/GetTunnel requests, plus UpdateDnsRecord (PUT)
with DnsUpdateCommand. Includes Pest coverage with Saloon mocks and CI.

Co-authored-by: Jordan Partridge <jordan@partridge.rocks>

* test: prove dns/tunnel crud register, force-delete json, update table, get json

Decode --json payloads for dns:delete --force and tunnel:get, and assert
dns:update table fields. Keep expose coverage in the Pest run.

* spec: lock dns:delete, dns:update, tunnel:get (PR #8)

Research seat. Commands + Saloon PUT overwrite. Raw --json, not the
#7 envelope. Keep tunnel:expose README. Do not merge.

* fix: tunnel:get uses InteractsWithCloudflare like other tunnel verbs

DNS delete/update keep the dns:create token-only connector and pint concat.

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
cursor Bot pushed a commit that referenced this pull request Sep 13, 2026
PR #5 must not claim docs/agent-output.md or the {ok,data} envelope
(that is unmerged #7). Fold demo.md / demo.cast.md from #4; leave
the hero README crew and PHAR install alone.
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.

2 participants