feat(cli): port orgs commands to native TypeScript#5379
Merged
Conversation
Promote `orgs list` and `orgs create` from Phase 0 Go-binary proxies to native TypeScript implementations in the legacy shell. Mirrors the just- landed branches port: shared HTTP error mapper, Go-compatible JSON/YAML/TOML/env encoders, Glamour-rendered pretty table, and the full five-mode `--output` flag with TS `--output-format` deferral. - `orgs list` rejects `--output env` with the byte-exact Go message and wraps TOML output as `[[organizations]]` per Go parity. - `orgs create` emits the `Created organization: <id>` preamble before every Go-output mode (json/yaml/toml/env supported; the env branch works here unlike on list, matching Go's encoder behaviour). - Telemetry flushes in `Effect.ensuring` on success and failure; no linked-project cache write because no `--project-ref` is resolved. Tests: 3 unit + 32 integration covering every output branch, the non-text-format + API-failure spinner-undefined path, and the `cli_command_executed` telemetry parity rules. Refs CLI-1290.
jgoux
approved these changes
May 28, 2026
Coly010
added a commit
that referenced
this pull request
May 29, 2026
…und-trip) The orgs port (#5379) documented an important parity rule: Go's `strings.ReplaceAll(value, "|", "\\|")` is a markdown-intermediate escape that Glamour decodes back to literal `|` in the rendered ASCII bytes. `renderGlamourTable` bypasses the markdown round-trip, so passing pre-escaped values produces `\|` in stdout where Go produces `|` — a byte-level parity divergence for any snippet name, visibility, or owner username containing a pipe. Fix: drop the `escapePipe` helper, pass raw values to renderGlamourTable. Updated unit + integration tests to assert literal `|` preservation (matching the pattern orgs.format.unit.test.ts uses). Also adopts the `yield* new ErrorClass(...)` shorthand from orgs handlers for tagged-error short-circuits.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes
supabase orgs listandsupabase orgs createfrom Phase 0 Go-binary proxies to native TypeScript implementations in the legacy shell. The handlers reuse the shared infrastructure introduced by the branches port — HTTP error mapper, Go-compatible JSON/YAML/TOML/env encoders, and Glamour-rendered pretty tables — so no new shared helpers were needed.Go source mirrored 1:1:
apps/cli-go/internal/orgs/list/list.goandapps/cli-go/internal/orgs/create/create.go. Error templates, output mode behaviour, and theCreated organization: <id>preamble byte-match the Go CLI.Notable parity rules
orgs list --output envis rejected with the byte-exact Go message--output env flag is not supported.orgs list --output tomlwraps the array as[[organizations]](Go uses a TOML envelope for arrays).orgs create --output envis supported here, unlike on list — matches Go'sEncodeOutputflattening of a single object intoID=… NAME=… SLUG=….Created organization: <id>preamble fires before every Go-output mode (json / yaml / toml / env / pretty) but is omitted from--output-format json/stream-json, where the message is delivered as a structured event field instead.Effect.ensuringon success and failure (CLAUDE.md PersistentPostRun parity rule). No linked-project cache write — these are user-level commands without a--project-ref.Manage Supabase organizations(no trailing period).Tests
renderOrgsListTable(header-only, multi-row, literal|passthrough).--output-over---output-formatprecedence, network and HTTP-503 error paths (including theformat !== "text"spinner-undefined branch), and telemetry flush on both success and failure.E2E coverage deliberately omitted — these are pure Management-API CRUD commands with no subprocess-specific behaviour to validate (per CLAUDE.md testing policy).
Reviewer-relevant context
legacyManagementApiRuntimeLayer, which constructs the project-ref resolver lazily. The orgs handlers simply don't yield those services. This is intentional: keeping a single shared runtime layer is cheaper than maintaining a user-vs-project layer split.orgs.errors.tsandorgs.format.tsare colocated at the family root, not hoisted tolegacy/shared/. Per CLAUDE.md hoist-before-duplicate, the threshold is "used across ≥2 families" — branches has its ownbranches.format.ts/branches.errors.ts, and these are the second instance of the pattern, not yet a third.id,name) without ANSI/control-character stripping. This is strict Go parity — bothSIDE_EFFECTS.mdfiles document the deliberate pass-through under "Security Notes" so a future renderer-level sanitization fix has a clear pointer.Refs CLI-1290.