Uh oh!
There was an error while loading. Please reload this page.
fix(cli): match Go machine-format encoder output for -o toml/yaml/json (CLI-1975) - #6002
Conversation
Coly010
commented
Jul 30, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:9b583fd807
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… (review: codex) - yamlIsTimestamp now mirrors time.Parse's calendar validation (days-in-month with proleptic-Gregorian leap years) and zone-offset range checks (hour > 24, minute > 60 rejected), so strings like "2025-02-31" stay plain exactly as yaml.v3 leaves them. - TOML map keys sort by UTF-8 byte order (sort.Strings) and yaml.v3's keyList.Less rune comparisons use code points, not JS UTF-16 units, fixing astral-vs-high-BMP key ordering in both encoders. - yamlHasSpecialChars/yamlDoubleQuoted now port libyaml's is_printable: astral characters, U+FEFF, and U+FFFE/U+FFFF double-quote with \x/\u/\U escapes. All new golden bytes captured from Go's own utils.EncodeOutput with the pinned BurntSushi toml v1.6.0 / yaml.v3 v3.0.1.
Coly010
commented
Jul 30, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:e020a45acf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Coly010
commented
Jul 30, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:a479e84f36
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Coly010
commented
Jul 30, 2026
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:c701b9ae64
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…erflow quoting (review: codex)
…5--o-toml-o-yaml-emit-wrong-key-casing-on-struct-payloads-o
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:b7522fec63
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Supabase CLI previewnpx --yes https://pkg.pr.new/supabase/cli/supabase@1d72d37c01b7a32690c7fe71781cf35ded9d8294Preview package for commit |
Coly010
commented
Jul 31, 2026
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:dddbf6b880
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Coly010
commented
Jul 31, 2026
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
kanadgupta
left a comment
There was a problem hiding this comment.
A couple of future-proofing suggestions from Claude but LGTM!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…gic (CLI-1975) Hoist the map-sort + direct/sub table partitioning shared by tomlTable and tomlArrayOfTables into tomlOrderedEntries; tomlInlineTable keeps its own copy since its position-based separator logic doesn't unify cleanly (review kanadgupta). Also notes in the Go Parity Checklist that a types.gen.go regen requires re-auditing every go-payload.ts spec.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:95d24f6b75
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Parses the real Go struct declarations out of types.gen.go and structurally compares them against the LegacyGoType specs the *.go-payload.ts files hand-declare, so a future field add/remove/reorder/rename in the Go API types desyncs a spec loudly instead of silently corrupting -o yaml/-o toml output (review kanadgupta, PR #6002).
…5--o-toml-o-yaml-emit-wrong-key-casing-on-struct-payloads-o # Conflicts: # apps/cli/src/legacy/commands/sso/add/add.handler.ts # apps/cli/src/legacy/commands/sso/update/update.handler.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:1d72d37c01
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…audit (CLI-1967) (supabase#6074) ## What Doc/comment-accuracy sweep from `apps/cli/docs/go-parity-audit-2026-07-24.md` §6 (untracked locally, not part of this repo). No runtime behavior changes — every item below was independently re-verified against current Go (`apps/cli-go/`) and TS source before fixing, since the audit is 12 days old and several items had drifted further in that time (in both directions). ## Fixed - **`docs/go-cli-porting-status.md`** — `functions list` legacy-shell status `wrapped` → `ported` (verified: zero `LegacyGoProxy` refs). `functions download` status corrected the other way, `ported` → `wrapped` (its handler still delegates wholesale via `LegacyGoProxy` for the default `--use-docker` path; only `--use-api` is native — noted as a hybrid in the row). Added a `ported` definition to the legacy-status legend (it only defined `wrapped`/`missing`, despite `ported` being ~90% of rows) and retitled that section from "Legacy Shell Wrapping Status" to "Legacy Shell Command Status" to match. Fixed the adjacent `functions delete/deploy/list/new/serve` legacy-shell notes, which all still said "Wrapped in legacy shell" despite being natively ported. - **`legacy-pgdelta.seam.service.ts`** — fixed two stale doc comments (`execInherit`, `ensureLocalDatabaseStarted`) that referenced things as "not yet ported" when they now are (`db reset`, `start`/`db start`). Did **not** touch `exportCatalog`'s doc comment / `LegacyCatalogMode`, which the audit also flagged — that exact hunk is already being rewritten more completely by the in-flight CLI-1959 PR (supabase#6061, open); fixing it here would guarantee a conflict with a strictly better version. `legacy-db-bootstrap.seam.service.ts` (the audit's other named file) was checked and found already accurate — CLI-1954/1955 (native `db start`/`db reset --local`) are still unmerged, so its "not yet ported" claim is currently true. - **`network-restrictions/{get,update}/SIDE_EFFECTS.md`** — the `-o {json,yaml,toml,env}` sections previously implied Go itself produces distinct byte-identical output per format. Verified against Go source: `restrictions/get`/`update` never read `OutputFormat` at all — they always print the same 3-line `fmt.Printf` template regardless of `-o`. Corrected both docs to state this plainly, documented that TS's format-specific output here is a deliberate TS-only enhancement with no real Go behavior to match (including no Go casing convention, since TS uses the map-shaped encoders rather than CLI-1975's struct-spec ones), and trimmed the resulting repetition. - **`inspect/report/SIDE_EFFECTS.md`** — added the empty/no-file divergence on `COPY` failure: Go's `copyToCSV` opens the output file with `O_TRUNC` before running the query, so a failing query still leaves a file (empty or partial); TS buffers in memory and only writes on success, leaving no file on a fresh run — and leaving the *previous* run's stale CSV in place on a same-day re-run (the more consequential case). Cross-referenced from `legacy-db-connection.errors.ts`'s `LegacyDbCopyError` doc comment, which already covered the message-text angle of the same divergence. - **`domains.cname.ts`** — the comment describing Go's CNAME "failed to locate" error dump wrongly implied Go embeds readable JSON. Verified against Go source and empirically (compiled the equivalent locally): Go JSON-marshals the answers to a `[]byte`, then formats that `[]byte` with `%+v`, which Go's `fmt` renders as an uncapped decimal byte-value array, not the JSON text — a `%+v`-on-`[]byte` footgun, not an intended format. Fixed both the function's JSDoc and the inline comment (they'd contradicted each other after an earlier pass), and cross-referenced the divergence from `domains/SIDE_EFFECTS.md`. - **`branches/orgs/projects/secrets` SIDE_EFFECTS `-o toml`/`-o yaml` claims**, **`functions deploy`'s `NPM_AUTH_TOKEN` env table entry**, and **`update-root-key.handler.ts`'s color comment** — all already fixed by CLI-1975 (supabase#6002), CLI-1985 (supabase#6005), and CLI-1990 (supabase#5978) respectively, which merged after the audit ran. Verified current state matches; no changes needed. - **`start/SIDE_EFFECTS.md`'s `--ignore-health-check` ruling** — already fully handled by CLI-1987 (supabase#6007, merged), whose own description explicitly says CLI-1967 should not re-document it. Left untouched. ## Left as noted, not fixed (out of scope for a docs-only pass) - The `network-restrictions get`/`update` TS-only `-o` support is a real, pre-existing behavioral divergence from Go (Go has no such behavior at all for these two commands) — documented accurately here, but whether it should be *removed* to enforce strict parity is a ruling this PR doesn't make. - `docs/go-cli-porting-status.md`'s "Functions" section (next/-shell table) has a larger, pre-existing inaccuracy discovered while fixing the adjacent legacy-shell notes: it claims there's "still no dedicated `functions` CLI surface" in `next/`, but `next/commands/functions/` already exists (list/delete/deploy/download/new/dev, registered in `next/cli/root.ts`). Added command-path links and flagged the section as needing its own flag-by-flag parity audit rather than silently reclassifying rows without one. Fixes CLI-1967
⚖ Parity ruling applied
This issue was decision-gated. Colum ruled (2026-07-30) to take the issue's recommended option: remap the
-o toml/-o yamlencoders to Go field-name casing and structure — full Go parity. The alternative (declaring the TS snake_case casing intentional) was rejected. The Go CLI (apps/cli-go/) is the byte-parity oracle: for every affected command the machine output now matches what the Go binary prints, including field-name casing, ordering, zero-value inclusion, datetime rendering, and null rendering.User-visible change: scripts consuming
-o toml/-o yamlfrom the affected commands will now see Go-shaped keys (ProjectRef/[[branches]]-style PascalCase in TOML,projectref-style lowercased names in YAML) instead of the snake_case keys the TS CLI emitted until now — i.e. scripts written against the long-lived Go CLI work again.-o jsonvalues additionally carry Go's default HTML escaping (<>&as\u003c-style escapes); any JSON parser decodes these transparently.Fixes CLI-1975
What changed
Go's
utils.EncodeOutputhands raw Go structs to BurntSushi TOML and yaml.v3, and neither library readsjson:tags — keys come from the Go struct field names. The TS legacy shell was instead re-encoding the decoded snake_case JSON. This PR closes that gap for every struct-payload command.New shared encoder (
legacy/shared/legacy-go-struct-output.encoders.ts)A pure, spec-driven pair of encoders that reproduce the Go binary byte-for-byte, driven by per-payload-family Go struct specs (field order = Go declaration order, mirrored from
apps/cli-go/pkg/api/types.gen.goand command-local structs):[[array-of-tables]]element, nil pointers/slices/maps omitted, empty decoded arrays askey = [],time.Timeas native RFC3339Nano datetimes, Go float'g'formatting with the TOML.0rule, BurntSushi's exact string-escape table, and Go's runtime failure for populatednullable.Nullablefields.nullfor nil pointers,[]/{}for nil slices/maps, yaml.v3's 4-column indentation algorithm (+2 inside sequence items), its scalar-quoting resolver (old-bools, base-0 ints, floats, base-60, timestamps → double-quoted; emitter-plain-disallowed → single-quoted), block literals with chomping/indentation indicators,map[bool]Trendering for oapinullablefields, yaml.v3's natural map-key sort, and Gostrconv.FormatFloat(_, 'g', -1, bits)float formatting incl. float32 rounding.Every golden byte string in the unit tests was captured empirically from a scratch Go program running the repo's own
utils.EncodeOutputwith the exact library versions pinned inapps/cli-go/go.mod.Commands rewired to the spec encoders
branches list/create/update(sharedbranches.go-payload.ts)orgs list/create(orgs.go-payload.ts)projects list(Go'slinkedProjectembed: inlinedV1ProjectWithDatabaseResponsefields first,Linkedlast),projects create(shared create core),projects api-keys(-o yamlonly — Go's-o toml|envencode theSUPABASE_*_KEYenv map, unchanged)secrets list,sso list/show/add/update/remove(sso.go-payload.ts),domains get/create/activate/reverify,ssl-enforcement get/update(ssl-enforcement.go-payload.ts),functions list(replaces its bespoke per-command key maps),backups list,snippets list,services,vanity-subdomains get/activate/check-availability(YAML was snake_case; TOML gains Go's declaration order)Nil-vs-empty slice semantics follow each Go command: append-built lists (
branches list,projects list) emit nothing for-o tomlwhen empty (Go nil slice), decoded lists emitkey = [].Bug-for-bug parity notes
snippets list -o tomlnow fails with Go's exact error (failed to output toml: toml: cannot encode a map with non-string key type) whenever a snippet carries adescription— BurntSushi cannot encodenullable.Nullable[string](map[bool]string), and the Management API always sends the key. Go fails identically.projects api-keys -o yamlrenders nullable fields as yaml.v3 rendersmap[bool]T:apikey:+ indentedtrue: <value>when set,{}when absent,false: ""for explicit JSON null.JSON HTML escaping
encodeGoJson(-o json) andencodeGoStructJsonBody(raw-HTTP request bodies forsso add/update) now produce Go'sencoding/jsondefault escaping:<>&→\u003c\u003e\u0026,\u0008/\u000cfor backspace/form feed, and escaped U+2028/U+2029 — materially visible insso … metadata_xml. Both now route through the shared Go-faithful JSON walker (legacy-go-json.ts, which gains a compact mode);functions list's bespoke post-escaper was deleted. The cli-e2e replay server compares parsed bodies, so recorded fixtures are unaffected.Tests & docs
-0, nullable shapes, nil/empty slices, natural key sort, hostnames nesting).-o tomlno-output case), sso show (json escape + yaml + toml), backups list (incl.[[Backups]]), snippets (both the Go failure and the description-absent success bytes), plus casing fixes across orgs/projects/secrets/services/ssl-enforcement/domains/vanity tests. The previously-wrongbranches listtoml assertion (name = "feat-1") is now the full Go-golden document.branches get -o toml(map payload) keeps its env-map keys verbatim — the struct remap must not apply to map payloads (sso info,status,postgres-config,network-bans,branches getare unchanged).Deliberately out of scope (pre-existing divergences, noted for the record)
network-restrictions get/update: Go never encodes-ooutput for these commands (it always prints three fixedPrintflines), so there is no Go byte oracle; the TS handlers' existing-o json|yaml|toml|envsupport is left untouched. Follow-up candidate.branches list -o jsonwith zero branches: TS emits[], Go emitsnull(append-built nil slice). JSON values were out of CLI-1975's scope (HTML escaping only).projects list -o json: TS sorts keys alphabetically solinkedsorts mid-object; Go emits it last. Same out-of-scope reasoning.domainsdata.errors/data.messagesare modeled as raw JSON values; Go's generated element type marshals as an empty struct — unobservable because these arrays are empty on every reachable path (both sides emit[]).