/...`) is gone.
- The `init` scaffold ejects the root-relative form, which is incompatible with Go if uncommented
- (#6159/#6160).
-- `db remote changes --password `: since CLI-1970, an explicit
- `--password` beats the `SUPABASE_DB_PASSWORD` env var. Before the trim, Go's
- package-wide "last `viper.BindPFlag("DB_PASSWORD", …)` wins" behavior bound
- the key to `projects create --db-password` (lexically last `cmd/*.go` file),
- so `db remote`'s own `--password` flag was never the bound instance and env
- silently won over it — a latent bug. With `projects.go` deleted, the bind
- lands on `db remote`'s persistent `--password` and flag-beats-env applies as
- intended. Accepted (not restored) in the CLI-1970 parity audit. `db remote
-commit` is now native `db pull`, so it uses pull's flag-then-env-then-dotenv
- password order. `db pull` keeps that precedence unchanged.
-- `branches {list,create,get,update,delete,pause,unpause,disable}` resolve their project ref
- through a PARENT-scoped chain instead of plain `--project-ref` flag/env/file resolution: an
- explicit `--project-ref` still wins outright, but the fallback is env `SUPABASE_PROJECT_ID` →
- `supabase/.temp/linked-project.json`'s `ref` → `supabase/.temp/project-ref`, first ref-shaped
- candidate wins. This is a direct consequence of the `link` branch-name divergence above: after
- `supabase link `, `project-ref` holds the branch's own ref, and the Management API
- returns 403 for a branch ref on every branches-management endpoint. No-op when linked to a real
- (non-branch) project — the cache and the file hold the same ref — so this only changes behavior
- in the previously-403ing branch-linked state (CLI-2167 follow-up, no Go equivalent).
-- `branches list`'s pretty table (not `-o json|yaml|toml`, not `--output-format json|stream-json`)
- marks the row matching the CURRENTLY linked ref with a ` (active)` NAME cell. TS-only
- QoL, no Go equivalent (CLI-2167 follow-up).
-- `status` prints the current linked project/branch as a "Linked Project:" block on stdout in
- human text mode (Neon-style — `Org:`/`Project:`/`Branch:` lines, each omitted when unknown),
- before any daemon/stack work begins, and folds the same linked state into its machine-readable
- outputs — additive `linked_project: {...} | null` (with `org_slug`/`org_id`) in the TS
- `--output-format json`/`stream-json` payload, and additive `linked_project_ref`/
- `linked_project_name`/`linked_org_slug`/`linked_org_id`/`linked_branch`/
- `linked_parent_project_ref` keys (absent entirely when not linked) appended after the existing
- keys in `-o env|json|yaml|toml`. A confirmed branch-linked state (from `linked-project.json`)
- keeps showing the parent/org fields even when the branch-name lookup itself degrades (no
- token, offline, API error) — only the branch's own name is ever missing, so the user always
- sees they're on a branch. The Management API client for that lookup is acquired lazily
- (`CommandPlatformApiFactory`, not the eager `CommandPlatformApi`) so `status` stays fully
- functional offline/token-less. Intent: let an agent driving `status` discover which
- project/branch it's on without a separate `link`/`branches` call. Read-only, never affects
- `status`'s exit code, and never alters any of its existing failure behavior — a Docker/daemon
- connection failure still fails exactly as today, with the linked block already printed above it
- in text mode (CLI-2167 follow-up, no Go equivalent). The same `linked_project` object is also
- carried on the `--output-format json`/`stream-json` FAILURE envelope (top-level, next to
- `_tag`/`error` or `type`/`error`/`timestamp`) — the agent-discovery use case matters most when
- `status` fails to reach a stopped stack — via a new opt-in, shared mechanism
- (`shared/output/machine-error-context.service.ts`'s `MachineErrorContext`, read by
- `jsonOutputLayer`/`streamJsonOutputLayer`'s `fail`); `-o env|json|yaml|toml`'s failure output is
- deliberately unchanged (still no payload, matching Go). See `status/SIDE_EFFECTS.md`.
-- `projects list`'s `LINKED` marker (the `linked` boolean, rendered as the pretty table's `●`
- bullet) now falls back to the PARENT chain when the linked ref matches no row exactly — the same
- scenario as above, since a branch-linked ref never matches a real project row. **This changes
- the `linked` field in the `-o json|yaml|toml` Go-struct payloads too**: in the branch-linked
- state it was previously `false` on every row; it can now be `true` on the parent project's row.
- The truthful fix IS the behavior change (CLI-2167 follow-up, no Go equivalent).
-- `services` warns on a malformed linked project ref (matching Go's
- `flags.LoadProjectRef` validation message) but, unlike Go, does not then use
- that ref for the remote lookup. Go's `cmd/services.go` (deleted in CLI-1970;
- last present at commit 7b469f5b3) treats the validation failure as
- non-fatal and still calls `listRemoteImages` with the malformed
- value; TS skips the remote lookup instead, since the ref is embedded
- unescaped into the tenant gateway hostname and a malformed value could
- redirect the service-role key to an attacker-controlled host. Intentional
- TS-only hardening, not a parity bug — see
- [`services/SIDE_EFFECTS.md`](../src/commands/services/SIDE_EFFECTS.md).
-- `db pull` in-sync (`"No schema changes found"`) keeps Go's message and its non-zero
- exit code, but replaces the generic "Try rerunning the command with --debug to
- troubleshoot the error." stderr footer with an explanatory suggestion line
- ("The remote database is already in sync with your local migrations — nothing to
- pull."). An in-sync database is a finding, not a failure to troubleshoot, so the
- debug hint sent users chasing a non-existent bug. Message text and exit code — the
- parts scripts depend on — are unchanged.
-- Edge Runtime's Docker container `--ulimit nofile` value (`functions serve` and `start`): Go
- hardcodes `nofile=65536:65536`, raised from the daemon default to accommodate FD usage from
- many concurrent Deno isolates (supabase/cli#5151). TS clamps that value to the host's own hard
- nofile limit on Linux (`@supabase/stack`'s `edgeRuntimeNofileUlimit`, via
- `process.report`'s `userLimits`), so a constrained sandbox (hard cap below 65536) can still start the
- container instead of failing outright (CLI-2220). The CLI process's own limit is used as a
- proxy for the daemon's — exact in the sandboxes this targets, where both share the cap; a
- Linux client more constrained than its daemon (remote `DOCKER_HOST`, mounted socket) just
- gets a smaller fd budget, never a failed start. When the clamp lowers the request, the CLI's
- `functions serve`/`start` bring-up warns with the reduced limit. The `@supabase/stack` service
- builder (`stack start`) applies the same clamp silently: its defs are built without
- an output channel, and in managed mode inside the daemon process, so a user-visible warning
- there needs a diagnostics channel on `BuildResult` first; the applied value stays visible via
- `docker inspect`.
diff --git a/apps/cli/docs/go-cli-reference.md b/apps/cli/docs/go-cli-reference.md
deleted file mode 100644
index b38e5665b1..0000000000
--- a/apps/cli/docs/go-cli-reference.md
+++ /dev/null
@@ -1,2128 +0,0 @@
-# Old Go CLI Reference
-
-> Complete help output for the old Go-based `supabase` CLI.
-> Use this document as the raw parity reference for the TS divergences tracked in [`go-cli-divergences.md`](./go-cli-divergences.md).
-
-## Global Flags
-
-These flags are available on all commands:
-
-```
-Flags:
- --create-ticket create a support ticket for any CLI error
- --debug output debug logs to stderr
- --dns-resolver [ native | https ] lookup domain names using the specified resolver (default native)
- --experimental enable experimental features
- -h, --help help for supabase
- --network-id string use the specified docker network instead of a generated one
- -o, --output [ env | pretty | json | toml | yaml ] output format of status variables (default pretty)
- --profile string use a specific profile for connecting to Supabase API (default "supabase")
- --workdir string path to a Supabase project directory
- --yes answer yes to all prompts
-```
-
-## Table of Contents
-
-- [Quick Start](#quick-start)
- - [bootstrap](#bootstrap)
-- [Local Development](#local-development)
- - [init](#init)
- - [link](#link)
- - [unlink](#unlink)
- - [login](#login)
- - [logout](#logout)
- - [start](#start)
- - [stop](#stop)
- - [status](#status)
- - [services](#services)
- - [db](#db)
- - [gen](#gen)
- - [inspect](#inspect)
- - [migration](#migration)
- - [seed](#seed)
- - [test](#test)
-- [Management APIs](#management-apis)
- - [backups](#backups)
- - [branches](#branches)
- - [config](#config)
- - [domains](#domains)
- - [encryption](#encryption)
- - [functions](#functions)
- - [network-bans](#network-bans)
- - [network-restrictions](#network-restrictions)
- - [orgs](#orgs)
- - [postgres-config](#postgres-config)
- - [projects](#projects)
- - [secrets](#secrets)
- - [snippets](#snippets)
- - [ssl-enforcement](#ssl-enforcement)
- - [sso](#sso)
- - [storage](#storage)
- - [vanity-subdomains](#vanity-subdomains)
-- [Additional Commands](#additional-commands)
- - [completion](#completion)
- - [help](#help-1)
-
----
-
-## Quick Start
-
-### bootstrap
-
-```
-Bootstrap a Supabase project from a starter template
-
-Usage:
- supabase bootstrap [template] [flags]
-
-Flags:
- -h, --help help for bootstrap
- -p, --password string Password to your remote Postgres database.
-```
-
----
-
-## Local Development
-
-### init
-
-```
-Initialize a local project
-
-Usage:
- supabase init [flags]
-
-Flags:
- --force Overwrite existing supabase/config.toml.
- -h, --help help for init
- -i, --interactive Enables interactive mode to configure IDE settings.
- --use-orioledb Use OrioleDB storage engine for Postgres.
-```
-
-### link
-
-```
-Link to a Supabase project
-
-Usage:
- supabase link [flags]
-
-Flags:
- -h, --help help for link
- -p, --password string Password to your remote Postgres database.
- --project-ref string Project ref of the Supabase project.
- --skip-pooler Use direct connection instead of pooler.
-```
-
-### unlink
-
-```
-Unlink a Supabase project
-
-Usage:
- supabase unlink [flags]
-
-Flags:
- -h, --help help for unlink
-```
-
-### login
-
-```
-Authenticate using an access token
-
-Usage:
- supabase login [flags]
-
-Flags:
- -h, --help help for login
- --name string Name that will be used to store token in your settings (default "built-in token name generator")
- --no-browser Do not open browser automatically
- --token string Use provided token instead of automatic login flow
-```
-
-### logout
-
-```
-Log out and delete access tokens locally
-
-Usage:
- supabase logout [flags]
-
-Flags:
- -h, --help help for logout
-```
-
-### start
-
-```
-Start containers for Supabase local development
-
-Usage:
- supabase start [flags]
-
-Flags:
- -x, --exclude strings Names of containers to not start. [gotrue,realtime,storage-api,imgproxy,kong,mailpit,postgrest,postgres-meta,studio,edge-runtime,logflare,vector,supavisor]
- -h, --help help for start
- --ignore-health-check Ignore unhealthy services and exit 0
- --sandbox Run in sandbox mode using native binaries (experimental)
-```
-
-### stop
-
-```
-Stop all local Supabase containers
-
-Usage:
- supabase stop [flags]
-
-Flags:
- --all Stop all local Supabase instances from all projects across the machine.
- -h, --help help for stop
- --no-backup Deletes all data volumes after stopping.
- --project-id string Local project ID to stop.
-```
-
-### status
-
-```
-Show status of local Supabase containers
-
-Usage:
- supabase status [flags]
-
-Examples:
- supabase status -o env --override-name api.url=NEXT_PUBLIC_SUPABASE_URL
- supabase status -o json
-
-Flags:
- -h, --help help for status
- --override-name strings Override specific variable names.
-```
-
-### services
-
-```
-Show versions of all Supabase services
-
-Usage:
- supabase services [flags]
-
-Flags:
- -h, --help help for services
-```
-
-### db
-
-```
-Manage Postgres databases
-
-Usage:
- supabase db [command]
-
-Available Commands:
- diff Diffs the local database for schema changes
- dump Dumps data or schemas from the remote database
- lint Checks local database for typing error
- pull Pull schema from the remote database
- push Push new migrations to the remote database
- reset Resets the local database to current migrations
- start Starts local Postgres database
-
-Flags:
- -h, --help help for db
-```
-
-#### db diff
-
-```
-Diffs the local database for schema changes
-
-Usage:
- supabase db diff [flags]
-
-Flags:
- --db-url string Diffs against the database specified by the connection string (must be percent-encoded).
- -f, --file string Saves schema diff to a new migration file.
- -h, --help help for diff
- --linked Diffs local migration files against the linked project.
- --local Diffs local migration files against the local database. (default true)
- -s, --schema strings Comma separated list of schema to include.
- --use-migra Use migra to generate schema diff. (default true)
- --use-pg-delta Use pg-delta to generate schema diff.
- --use-pg-schema Use pg-schema-diff to generate schema diff.
- --use-pgadmin Use pgAdmin to generate schema diff.
-```
-
-#### db dump
-
-```
-Dumps data or schemas from the remote database
-
-Usage:
- supabase db dump [flags]
-
-Flags:
- --data-only Dumps only data records.
- --db-url string Dumps from the database specified by the connection string (must be percent-encoded).
- --dry-run Prints the pg_dump script that would be executed.
- -x, --exclude strings List of schema.tables to exclude from data-only dump.
- -f, --file string File path to save the dumped contents.
- -h, --help help for dump
- --keep-comments Keeps commented lines from pg_dump output.
- --linked Dumps from the linked project. (default true)
- --local Dumps from the local database.
- -p, --password string Password to your remote Postgres database.
- --role-only Dumps only cluster roles.
- -s, --schema strings Comma separated list of schema to include.
- --use-copy Use copy statements in place of inserts.
-```
-
-#### db lint
-
-```
-Checks local database for typing error
-
-Usage:
- supabase db lint [flags]
-
-Flags:
- --db-url string Lints the database specified by the connection string (must be percent-encoded).
- --fail-on [ none | warning | error ] Error level to exit with non-zero status. (default none)
- -h, --help help for lint
- --level [ warning | error ] Error level to emit. (default warning)
- --linked Lints the linked project for schema errors.
- --local Lints the local database for schema errors. (default true)
- -s, --schema strings Comma separated list of schema to include.
-```
-
-#### db pull
-
-```
-Pull schema from the remote database
-
-Usage:
- supabase db pull [migration name] [flags]
-
-Flags:
- --db-url string Pulls from the database specified by the connection string (must be percent-encoded).
- -h, --help help for pull
- --linked Pulls from the linked project. (default true)
- --local Pulls from the local database.
- -p, --password string Password to your remote Postgres database.
- -s, --schema strings Comma separated list of schema to include.
-```
-
-#### db push
-
-```
-Push new migrations to the remote database
-
-Usage:
- supabase db push [flags]
-
-Flags:
- --db-url string Pushes to the database specified by the connection string (must be percent-encoded).
- --dry-run Print the migrations that would be applied, but don't actually apply them.
- -h, --help help for push
- --include-all Include all migrations not found on remote history table.
- --include-roles Include custom roles from supabase/roles.sql.
- --include-seed Include seed data from your config.
- --linked Pushes to the linked project. (default true)
- --local Pushes to the local database.
- -p, --password string Password to your remote Postgres database.
-```
-
-#### db reset
-
-```
-Resets the local database to current migrations
-
-Usage:
- supabase db reset [flags]
-
-Flags:
- --db-url string Resets the database specified by the connection string (must be percent-encoded).
- -h, --help help for reset
- --last uint Reset up to the last n migration versions.
- --linked Resets the linked project with local migrations.
- --local Resets the local database with local migrations. (default true)
- --no-seed Skip running the seed script after reset.
- --version string Reset up to the specified version.
-```
-
-#### db start
-
-```
-Starts local Postgres database
-
-Usage:
- supabase db start [flags]
-
-Flags:
- --from-backup string Path to a logical backup file.
- -h, --help help for start
-```
-
-### gen
-
-```
-Run code generation tools
-
-Usage:
- supabase gen [command]
-
-Available Commands:
- bearer-jwt Generate a Bearer Auth JWT for accessing Data API
- signing-key Generate a JWT signing key
- types Generate types from Postgres schema
-
-Flags:
- -h, --help help for gen
-```
-
-#### gen bearer-jwt
-
-```
-Generate a Bearer Auth JWT for accessing Data API
-
-Usage:
- supabase gen bearer-jwt [flags]
-
-Flags:
- --exp time Expiry timestamp for this token.
- -h, --help help for bearer-jwt
- --payload string Custom claims in JSON format. (default "{}")
- --role string Postgres role to use.
- --sub string User ID to impersonate. (default "anonymous")
- --valid-for duration Validity duration for this token. (default 30m0s)
-```
-
-#### gen signing-key
-
-```
-Securely generate a private JWT signing key for use in the CLI or to import in the dashboard.
-
-Supported algorithms:
- ES256 - ECDSA with P-256 curve and SHA-256 (recommended)
- RS256 - RSA with SHA-256
-
-Usage:
- supabase gen signing-key [flags]
-
-Flags:
- --algorithm [ RS256 | ES256 ] Algorithm for signing key generation. (default ES256)
- --append Append new key to existing keys file instead of overwriting.
- -h, --help help for signing-key
-```
-
-#### gen types
-
-```
-Generate types from Postgres schema
-
-Usage:
- supabase gen types [flags]
-
-Examples:
- supabase gen types --local
- supabase gen types --linked --lang=go
- supabase gen types --project-id abc-def-123 --schema public --schema private
- supabase gen types --db-url 'postgresql://...' --schema public --schema auth
-
-Flags:
- --db-url string Generate types from a database url.
- -h, --help help for types
- --lang [ typescript | go | swift | python ] Output language of the generated types. (default typescript)
- --linked Generate types from the linked project.
- --local Generate types from the local dev database.
- --postgrest-v9-compat Generate types compatible with PostgREST v9 and below.
- --project-id string Generate types from a project ID.
- --query-timeout duration Maximum timeout allowed for the database query. (default 15s)
- -s, --schema strings Comma separated list of schema to include.
- --swift-access-control [ internal | public ] Access control for Swift generated types. (default internal)
-```
-
-### inspect
-
-```
-Tools to inspect your Supabase project
-
-Usage:
- supabase inspect [command]
-
-Available Commands:
- db Tools to inspect your Supabase database
- report Generate a CSV output for all inspect commands
-
-Flags:
- --db-url string Inspect the database specified by the connection string (must be percent-encoded).
- -h, --help help for inspect
- --linked Inspect the linked project. (default true)
- --local Inspect the local database.
-```
-
-#### inspect db
-
-```
-Tools to inspect your Supabase database
-
-Usage:
- supabase inspect db [command]
-
-Available Commands:
- bloat Estimates space allocated to a relation that is full of dead tuples
- blocking Show queries that are holding locks and the queries that are waiting for them to be released
- calls Show queries from pg_stat_statements ordered by total times called
- db-stats Show stats such as cache hit rates, total sizes, and WAL size
- index-stats Show combined index size, usage percent, scan counts, and unused status
- locks Show queries which have taken out an exclusive lock on a relation
- long-running-queries Show currently running queries running for longer than 5 minutes
- outliers Show queries from pg_stat_statements ordered by total execution time
- replication-slots Show information about replication slots on the database
- role-stats Show information about roles on the database
- table-stats Show combined table size, index size, and estimated row count
- traffic-profile Show read/write activity ratio for tables based on block I/O operations
- vacuum-stats Show statistics related to vacuum operations per table
-
-Flags:
- -h, --help help for db
-```
-
-##### inspect db bloat
-
-```
-Estimates space allocated to a relation that is full of dead tuples
-
-Usage:
- supabase inspect db bloat [flags]
-
-Flags:
- -h, --help help for bloat
-```
-
-##### inspect db blocking
-
-```
-Show queries that are holding locks and the queries that are waiting for them to be released
-
-Usage:
- supabase inspect db blocking [flags]
-
-Flags:
- -h, --help help for blocking
-```
-
-##### inspect db calls
-
-```
-Show queries from pg_stat_statements ordered by total times called
-
-Usage:
- supabase inspect db calls [flags]
-
-Flags:
- -h, --help help for calls
-```
-
-##### inspect db db-stats
-
-```
-Show stats such as cache hit rates, total sizes, and WAL size
-
-Usage:
- supabase inspect db db-stats [flags]
-
-Flags:
- -h, --help help for db-stats
-```
-
-##### inspect db index-stats
-
-```
-Show combined index size, usage percent, scan counts, and unused status
-
-Usage:
- supabase inspect db index-stats [flags]
-
-Flags:
- -h, --help help for index-stats
-```
-
-##### inspect db locks
-
-```
-Show queries which have taken out an exclusive lock on a relation
-
-Usage:
- supabase inspect db locks [flags]
-
-Flags:
- -h, --help help for locks
-```
-
-##### inspect db long-running-queries
-
-```
-Show currently running queries running for longer than 5 minutes
-
-Usage:
- supabase inspect db long-running-queries [flags]
-
-Flags:
- -h, --help help for long-running-queries
-```
-
-##### inspect db outliers
-
-```
-Show queries from pg_stat_statements ordered by total execution time
-
-Usage:
- supabase inspect db outliers [flags]
-
-Flags:
- -h, --help help for outliers
-```
-
-##### inspect db replication-slots
-
-```
-Show information about replication slots on the database
-
-Usage:
- supabase inspect db replication-slots [flags]
-
-Flags:
- -h, --help help for replication-slots
-```
-
-##### inspect db role-stats
-
-```
-Show information about roles on the database
-
-Usage:
- supabase inspect db role-stats [flags]
-
-Flags:
- -h, --help help for role-stats
-```
-
-##### inspect db table-stats
-
-```
-Show combined table size, index size, and estimated row count
-
-Usage:
- supabase inspect db table-stats [flags]
-
-Flags:
- -h, --help help for table-stats
-```
-
-##### inspect db traffic-profile
-
-```
-Show read/write activity ratio for tables based on block I/O operations
-
-Usage:
- supabase inspect db traffic-profile [flags]
-
-Flags:
- -h, --help help for traffic-profile
-```
-
-##### inspect db vacuum-stats
-
-```
-Show statistics related to vacuum operations per table
-
-Usage:
- supabase inspect db vacuum-stats [flags]
-
-Flags:
- -h, --help help for vacuum-stats
-```
-
-#### inspect report
-
-```
-Generate a CSV output for all inspect commands
-
-Usage:
- supabase inspect report [flags]
-
-Flags:
- -h, --help help for report
- --output-dir string Path to save CSV files in (default ".")
-```
-
-### migration
-
-```
-Manage database migration scripts
-
-Usage:
- supabase migration [command]
-
-Aliases:
- migration, migrations
-
-Available Commands:
- down Resets applied migrations up to the last n versions
- fetch Fetch migration files from history table
- list List local and remote migrations
- new Create an empty migration script
- repair Repair the migration history table
- squash Squash migrations to a single file
- up Apply pending migrations to local database
-
-Flags:
- -h, --help help for migration
-```
-
-#### migration down
-
-```
-Resets applied migrations up to the last n versions
-
-Usage:
- supabase migration down [flags]
-
-Flags:
- --db-url string Resets applied migrations on the database specified by the connection string (must be percent-encoded).
- -h, --help help for down
- --last uint Reset up to the last n migration versions. (default 1)
- --linked Resets applied migrations on the linked project.
- --local Resets applied migrations on the local database. (default true)
-```
-
-#### migration fetch
-
-```
-Fetch migration files from history table
-
-Usage:
- supabase migration fetch [flags]
-
-Flags:
- --db-url string Fetches migrations from the database specified by the connection string (must be percent-encoded).
- -h, --help help for fetch
- --linked Fetches migration history from the linked project. (default true)
- --local Fetches migration history from the local database.
-```
-
-#### migration list
-
-```
-List local and remote migrations
-
-Usage:
- supabase migration list [flags]
-
-Flags:
- --db-url string Lists migrations of the database specified by the connection string (must be percent-encoded).
- -h, --help help for list
- --linked Lists migrations applied to the linked project. (default true)
- --local Lists migrations applied to the local database.
- -p, --password string Password to your remote Postgres database.
-```
-
-#### migration new
-
-```
-Create an empty migration script
-
-Usage:
- supabase migration new [flags]
-
-Flags:
- -h, --help help for new
-```
-
-#### migration repair
-
-```
-Repair the migration history table
-
-Usage:
- supabase migration repair [version] ... [flags]
-
-Flags:
- --db-url string Repairs migrations of the database specified by the connection string (must be percent-encoded).
- -h, --help help for repair
- --linked Repairs the migration history of the linked project. (default true)
- --local Repairs the migration history of the local database.
- -p, --password string Password to your remote Postgres database.
- --status [ applied | reverted ] Version status to update.
-```
-
-#### migration squash
-
-```
-Squash migrations to a single file
-
-Usage:
- supabase migration squash [flags]
-
-Flags:
- --db-url string Squashes migrations of the database specified by the connection string (must be percent-encoded).
- -h, --help help for squash
- --linked Squashes the migration history of the linked project.
- --local Squashes the migration history of the local database. (default true)
- -p, --password string Password to your remote Postgres database.
- --version string Squash up to the specified version.
-```
-
-#### migration up
-
-```
-Apply pending migrations to local database
-
-Usage:
- supabase migration up [flags]
-
-Flags:
- --db-url string Applies migrations to the database specified by the connection string (must be percent-encoded).
- -h, --help help for up
- --include-all Include all migrations not found on remote history table.
- --linked Applies pending migrations to the linked project.
- --local Applies pending migrations to the local database. (default true)
-```
-
-### seed
-
-```
-Seed a Supabase project from supabase/config.toml
-
-Usage:
- supabase seed [command]
-
-Available Commands:
- buckets Seed buckets declared in [storage.buckets]
-
-Flags:
- -h, --help help for seed
- --linked Seeds the linked project.
- --local Seeds the local database. (default true)
-```
-
-#### seed buckets
-
-```
-Seed buckets declared in [storage.buckets]
-
-Usage:
- supabase seed buckets [flags]
-
-Flags:
- -h, --help help for buckets
-```
-
-### test
-
-```
-Run tests on local Supabase containers
-
-Usage:
- supabase test [command]
-
-Available Commands:
- db Tests local database with pgTAP
- new Create a new test file
-
-Flags:
- -h, --help help for test
-```
-
-#### test db
-
-```
-Tests local database with pgTAP
-
-Usage:
- supabase test db [path] ... [flags]
-
-Flags:
- --db-url string Tests the database specified by the connection string (must be percent-encoded).
- -h, --help help for db
- --linked Runs pgTAP tests on the linked project.
- --local Runs pgTAP tests on the local database. (default true)
-```
-
-#### test new
-
-```
-Create a new test file
-
-Usage:
- supabase test new [flags]
-
-Flags:
- -h, --help help for new
- -t, --template [ pgtap ] Template framework to generate. (default pgtap)
-```
-
----
-
-## Management APIs
-
-### backups
-
-```
-Manage Supabase physical backups
-
-Usage:
- supabase backups [command]
-
-Available Commands:
- list Lists available physical backups
- restore Restore to a specific timestamp using PITR
-
-Flags:
- -h, --help help for backups
- --project-ref string Project ref of the Supabase project.
-```
-
-#### backups list
-
-```
-Lists available physical backups
-
-Usage:
- supabase backups list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-#### backups restore
-
-```
-Restore to a specific timestamp using PITR
-
-Usage:
- supabase backups restore [flags]
-
-Flags:
- -h, --help help for restore
- -t, --timestamp int The recovery time target in seconds since epoch.
-```
-
-### branches
-
-```
-Manage Supabase preview branches
-
-Usage:
- supabase branches [command]
-
-Available Commands:
- create Create a preview branch
- delete Delete a preview branch
- get Retrieve details of a preview branch
- list List all preview branches
- pause Pause a preview branch
- unpause Unpause a preview branch
- update Update a preview branch
-
-Flags:
- -h, --help help for branches
- --project-ref string Project ref of the Supabase project.
-```
-
-#### branches create
-
-```
-Create a preview branch for the linked project.
-
-Usage:
- supabase branches create [name] [flags]
-
-Flags:
- -h, --help help for create
- --notify-url string URL to notify when branch is active healthy.
- --persistent Whether to create a persistent branch.
- --region string Select a region to deploy the branch database.
- --size string Select a desired instance size for the branch database.
- --with-data Whether to clone production data to the branch database.
-```
-
-#### branches delete
-
-```
-Delete a preview branch by its name or ID.
-
-Usage:
- supabase branches delete [name] [flags]
-
-Flags:
- -h, --help help for delete
-```
-
-#### branches get
-
-```
-Retrieve details of the specified preview branch.
-
-Usage:
- supabase branches get [name] [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### branches list
-
-```
-List all preview branches of the linked project.
-
-Usage:
- supabase branches list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-#### branches pause
-
-```
-Pause a preview branch
-
-Usage:
- supabase branches pause [name] [flags]
-
-Flags:
- -h, --help help for pause
-```
-
-#### branches unpause
-
-```
-Unpause a preview branch
-
-Usage:
- supabase branches unpause [name] [flags]
-
-Flags:
- -h, --help help for unpause
-```
-
-#### branches update
-
-```
-Update a preview branch by its name or ID.
-
-Usage:
- supabase branches update [name] [flags]
-
-Flags:
- --git-branch string Change the associated git branch.
- -h, --help help for update
- --name string Rename the preview branch.
- --notify-url string URL to notify when branch is active healthy.
- --persistent Switch between ephemeral and persistent branch.
- --status string Override the current branch status.
-```
-
-### config
-
-```
-Manage Supabase project configurations
-
-Usage:
- supabase config [command]
-
-Available Commands:
- push Pushes local config.toml to the linked project
-
-Flags:
- -h, --help help for config
- --project-ref string Project ref of the Supabase project.
-```
-
-#### config push
-
-```
-Pushes local config.toml to the linked project
-
-Usage:
- supabase config push [flags]
-
-Flags:
- -h, --help help for push
-```
-
-### domains
-
-```
-Manage custom domain names for Supabase projects.
-
-Use of custom domains and vanity subdomains is mutually exclusive.
-
-Usage:
- supabase domains [command]
-
-Available Commands:
- activate Activate the custom hostname for a project
- create Create a custom hostname
- delete Deletes the custom hostname config for your project
- get Get the current custom hostname config
- reverify Re-verify the custom hostname config for your project
-
-Flags:
- -h, --help help for domains
- --include-raw-output Include raw output (useful for debugging).
- --project-ref string Project ref of the Supabase project.
-```
-
-#### domains activate
-
-```
-Activates the custom hostname configuration for a project.
-
-This reconfigures your Supabase project to respond to requests on your custom hostname.
-After the custom hostname is activated, your project's auth services will no longer function on the Supabase-provisioned subdomain.
-
-Usage:
- supabase domains activate [flags]
-
-Flags:
- -h, --help help for activate
-```
-
-#### domains create
-
-```
-Create a custom hostname for your Supabase project.
-
-Expects your custom hostname to have a CNAME record to your Supabase project's subdomain.
-
-Usage:
- supabase domains create [flags]
-
-Flags:
- --custom-hostname string The custom hostname to use for your Supabase project.
- -h, --help help for create
-```
-
-#### domains delete
-
-```
-Deletes the custom hostname config for your project
-
-Usage:
- supabase domains delete [flags]
-
-Flags:
- -h, --help help for delete
-```
-
-#### domains get
-
-```
-Retrieve the custom hostname config for your project, as stored in the Supabase platform.
-
-Usage:
- supabase domains get [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### domains reverify
-
-```
-Re-verify the custom hostname config for your project
-
-Usage:
- supabase domains reverify [flags]
-
-Flags:
- -h, --help help for reverify
-```
-
-### encryption
-
-```
-Manage encryption keys of Supabase projects
-
-Usage:
- supabase encryption [command]
-
-Available Commands:
- get-root-key Get the root encryption key of a Supabase project
- update-root-key Update root encryption key of a Supabase project
-
-Flags:
- -h, --help help for encryption
- --project-ref string Project ref of the Supabase project.
-```
-
-#### encryption get-root-key
-
-```
-Get the root encryption key of a Supabase project
-
-Usage:
- supabase encryption get-root-key [flags]
-
-Flags:
- -h, --help help for get-root-key
-```
-
-#### encryption update-root-key
-
-```
-Update root encryption key of a Supabase project
-
-Usage:
- supabase encryption update-root-key [flags]
-
-Flags:
- -h, --help help for update-root-key
-```
-
-### functions
-
-```
-Manage Supabase Edge functions
-
-Usage:
- supabase functions [command]
-
-Available Commands:
- delete Delete a Function from Supabase
- deploy Deploy a Function to Supabase
- download Download a Function from Supabase
- list List all Functions in Supabase
- new Create a new Function locally
- serve Serve all Functions locally
-
-Flags:
- -h, --help help for functions
-```
-
-#### functions delete
-
-```
-Delete a Function from the linked Supabase project. This does NOT remove the Function locally.
-
-Usage:
- supabase functions delete [flags]
-
-Flags:
- -h, --help help for delete
- --project-ref string Project ref of the Supabase project.
-```
-
-#### functions deploy
-
-```
-Deploy a Function to the linked Supabase project.
-
-Usage:
- supabase functions deploy [Function name] [flags]
-
-Flags:
- -h, --help help for deploy
- --import-map string Path to import map file.
- -j, --jobs uint Maximum number of parallel jobs. (default 1)
- --no-verify-jwt Disable JWT verification for the Function.
- --project-ref string Project ref of the Supabase project.
- --prune Delete Functions that exist in Supabase project but not locally.
- --use-api Bundle functions server-side without using Docker.
-```
-
-#### functions download
-
-```
-Download the source code for a Function from the linked Supabase project. If no function name is provided, downloads all functions.
-
-Usage:
- supabase functions download [Function name] [flags]
-
-Flags:
- -h, --help help for download
- --project-ref string Project ref of the Supabase project.
- --use-api Unbundle functions server-side without using Docker.
-```
-
-#### functions list
-
-```
-List all Functions in the linked Supabase project.
-
-Usage:
- supabase functions list [flags]
-
-Flags:
- -h, --help help for list
- --project-ref string Project ref of the Supabase project.
-```
-
-#### functions new
-
-```
-Create a new Function locally
-
-Usage:
- supabase functions new [flags]
-
-Flags:
- -h, --help help for new
-```
-
-#### functions serve
-
-```
-Serve all Functions locally
-
-Usage:
- supabase functions serve [flags]
-
-Flags:
- --env-file string Path to an env file to be populated to the Function environment.
- -h, --help help for serve
- --import-map string Path to import map file.
- --inspect Alias of --inspect-mode brk.
- --inspect-main Allow inspecting the main worker.
- --inspect-mode [ run | brk | wait ] Activate inspector capability for debugging.
- --no-verify-jwt Disable JWT verification for the Function.
-```
-
-### network-bans
-
-```
-Network bans are IPs that get temporarily blocked if their traffic pattern looks abusive (e.g. multiple failed auth attempts).
-
-The subcommands help you view the current bans, and unblock IPs if desired.
-
-Usage:
- supabase network-bans [command]
-
-Available Commands:
- get Get the current network bans
- remove Remove a network ban
-
-Flags:
- -h, --help help for network-bans
- --project-ref string Project ref of the Supabase project.
-```
-
-#### network-bans get
-
-```
-Get the current network bans
-
-Usage:
- supabase network-bans get [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### network-bans remove
-
-```
-Remove a network ban
-
-Usage:
- supabase network-bans remove [flags]
-
-Flags:
- --db-unban-ip strings IP to allow DB connections from.
- -h, --help help for remove
-```
-
-### network-restrictions
-
-```
-Manage network restrictions
-
-Usage:
- supabase network-restrictions [command]
-
-Available Commands:
- get Get the current network restrictions
- update Update network restrictions
-
-Flags:
- -h, --help help for network-restrictions
- --project-ref string Project ref of the Supabase project.
-```
-
-#### network-restrictions get
-
-```
-Get the current network restrictions
-
-Usage:
- supabase network-restrictions get [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### network-restrictions update
-
-```
-Update network restrictions
-
-Usage:
- supabase network-restrictions update [flags]
-
-Flags:
- --append Append to existing restrictions instead of replacing them.
- --bypass-cidr-checks Bypass some of the CIDR validation checks.
- --db-allow-cidr strings CIDR to allow DB connections from.
- -h, --help help for update
-```
-
-### orgs
-
-```
-Manage Supabase organizations
-
-Usage:
- supabase orgs [command]
-
-Available Commands:
- create Create an organization
- list List all organizations
-
-Flags:
- -h, --help help for orgs
-```
-
-#### orgs create
-
-```
-Create an organization for the logged-in user.
-
-Usage:
- supabase orgs create [flags]
-
-Flags:
- -h, --help help for create
-```
-
-#### orgs list
-
-```
-List all organizations the logged-in user belongs.
-
-Usage:
- supabase orgs list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-### postgres-config
-
-```
-Manage Postgres database config
-
-Usage:
- supabase postgres-config [command]
-
-Available Commands:
- delete Delete specific Postgres database config overrides
- get Get the current Postgres database config overrides
- update Update Postgres database config
-
-Flags:
- -h, --help help for postgres-config
- --project-ref string Project ref of the Supabase project.
-```
-
-#### postgres-config delete
-
-```
-Delete specific config overrides, reverting them to their default values.
-
-Usage:
- supabase postgres-config delete [flags]
-
-Flags:
- --config strings Config keys to delete (comma-separated)
- -h, --help help for delete
- --no-restart Do not restart the database after deleting config.
-```
-
-#### postgres-config get
-
-```
-Get the current Postgres database config overrides
-
-Usage:
- supabase postgres-config get [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### postgres-config update
-
-```
-Overriding the default Postgres config could result in unstable database behavior.
-Custom configuration also overrides the optimizations generated based on the compute add-ons in use.
-
-Usage:
- supabase postgres-config update [flags]
-
-Flags:
- --config strings Config overrides specified as a 'key=value' pair
- -h, --help help for update
- --no-restart Do not restart the database after updating config.
- --replace-existing-overrides If true, replaces all existing overrides with the ones provided. If false (default), merges existing overrides with the ones provided.
-```
-
-### projects
-
-```
-Manage Supabase projects
-
-Usage:
- supabase projects [command]
-
-Available Commands:
- api-keys List all API keys for a Supabase project
- create Create a project on Supabase
- delete Delete a Supabase project
- list List all Supabase projects
-
-Flags:
- -h, --help help for projects
-```
-
-#### projects api-keys
-
-```
-List all API keys for a Supabase project
-
-Usage:
- supabase projects api-keys [flags]
-
-Flags:
- -h, --help help for api-keys
- --project-ref string Project ref of the Supabase project.
-```
-
-#### projects create
-
-```
-Create a project on Supabase
-
-Usage:
- supabase projects create [project name] [flags]
-
-Examples:
-supabase projects create my-project --org-id cool-green-pqdr0qc --db-password ******** --region us-east-1
-
-Flags:
- --db-password string Database password of the project.
- -h, --help help for create
- --org-id string Organization ID to create the project in.
- --region string Select a region close to you for the best performance.
- --size string Select a desired instance size for your project.
-```
-
-#### projects delete
-
-```
-Delete a Supabase project
-
-Usage:
- supabase projects delete [ref] [flags]
-
-Flags:
- -h, --help help for delete
-```
-
-#### projects list
-
-```
-List all Supabase projects the logged-in user can access.
-
-Usage:
- supabase projects list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-### secrets
-
-```
-Manage Supabase secrets
-
-Usage:
- supabase secrets [command]
-
-Available Commands:
- list List all secrets on Supabase
- set Set a secret(s) on Supabase
- unset Unset a secret(s) on Supabase
-
-Flags:
- -h, --help help for secrets
- --project-ref string Project ref of the Supabase project.
-```
-
-#### secrets list
-
-```
-List all secrets in the linked project.
-
-Usage:
- supabase secrets list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-#### secrets set
-
-```
-Set a secret(s) to the linked Supabase project.
-
-Usage:
- supabase secrets set ... [flags]
-
-Flags:
- --env-file string Read secrets from a .env file.
- -h, --help help for set
-```
-
-#### secrets unset
-
-```
-Unset a secret(s) from the linked Supabase project.
-
-Usage:
- supabase secrets unset [NAME] ... [flags]
-
-Flags:
- -h, --help help for unset
-```
-
-### snippets
-
-```
-Manage Supabase SQL snippets
-
-Usage:
- supabase snippets [command]
-
-Available Commands:
- download Download contents of a SQL snippet
- list List all SQL snippets
-
-Flags:
- -h, --help help for snippets
- --project-ref string Project ref of the Supabase project.
-```
-
-#### snippets download
-
-```
-Download contents of the specified SQL snippet.
-
-Usage:
- supabase snippets download [flags]
-
-Flags:
- -h, --help help for download
-```
-
-#### snippets list
-
-```
-List all SQL snippets of the linked project.
-
-Usage:
- supabase snippets list [flags]
-
-Flags:
- -h, --help help for list
-```
-
-### ssl-enforcement
-
-```
-Manage SSL enforcement configuration
-
-Usage:
- supabase ssl-enforcement [command]
-
-Available Commands:
- get Get the current SSL enforcement configuration
- update Update SSL enforcement configuration
-
-Flags:
- -h, --help help for ssl-enforcement
- --project-ref string Project ref of the Supabase project.
-```
-
-#### ssl-enforcement get
-
-```
-Get the current SSL enforcement configuration
-
-Usage:
- supabase ssl-enforcement get [flags]
-
-Flags:
- -h, --help help for get
-```
-
-#### ssl-enforcement update
-
-```
-Update SSL enforcement configuration
-
-Usage:
- supabase ssl-enforcement update [flags]
-
-Flags:
- --disable-db-ssl-enforcement Whether the DB should disable SSL enforcement for all external connections.
- --enable-db-ssl-enforcement Whether the DB should enable SSL enforcement for all external connections.
- -h, --help help for update
-```
-
-### sso
-
-```
-Manage Single Sign-On (SSO) authentication for projects
-
-Usage:
- supabase sso [command]
-
-Available Commands:
- add Add a new SSO identity provider
- info Returns the SAML SSO settings required for the identity provider
- list List all SSO identity providers for a project
- remove Remove an existing SSO identity provider
- show Show information about an SSO identity provider
- update Update information about an SSO identity provider
-
-Flags:
- -h, --help help for sso
- --project-ref string Project ref of the Supabase project.
-```
-
-#### sso add
-
-```
-Add and configure a new connection to a SSO identity provider to your Supabase project.
-
-Usage:
- supabase sso add [flags]
-
-Examples:
- supabase sso add --type saml --project-ref mwjylndxudmiehsxhmmz --metadata-url 'https://...' --domains example.com
-
-Flags:
- --attribute-mapping-file string File containing a JSON mapping between SAML attributes to custom JWT claims.
- --domains strings Comma separated list of email domains to associate with the added identity provider.
- -h, --help help for add
- --metadata-file string File containing a SAML 2.0 Metadata XML document describing the identity provider.
- --metadata-url string URL pointing to a SAML 2.0 Metadata XML document describing the identity provider.
- --name-id-format string URI reference representing the classification of string-based identifier information.
- --skip-url-validation Whether local validation of the SAML 2.0 Metadata URL should not be performed.
- -t, --type [ saml ] Type of identity provider (according to supported protocol).
-```
-
-#### sso info
-
-```
-Returns all of the important SSO information necessary for your project to be registered with a SAML 2.0 compatible identity provider.
-
-Usage:
- supabase sso info [flags]
-
-Examples:
- supabase sso info --project-ref mwjylndxudmiehsxhmmz
-
-Flags:
- -h, --help help for info
-```
-
-#### sso list
-
-```
-List all connections to a SSO identity provider to your Supabase project.
-
-Usage:
- supabase sso list [flags]
-
-Examples:
- supabase sso list --project-ref mwjylndxudmiehsxhmmz
-
-Flags:
- -h, --help help for list
-```
-
-#### sso remove
-
-```
-Remove a connection to an already added SSO identity provider. Removing the provider will prevent existing users from logging in. Please treat this command with care.
-
-Usage:
- supabase sso remove [flags]
-
-Examples:
- supabase sso remove b5ae62f9-ef1d-4f11-a02b-731c8bbb11e8 --project-ref mwjylndxudmiehsxhmmz
-
-Flags:
- -h, --help help for remove
-```
-
-#### sso show
-
-```
-Provides the information about an established connection to an identity provider. You can use --metadata to obtain the raw SAML 2.0 Metadata XML document stored in your project's configuration.
-
-Usage:
- supabase sso show [flags]
-
-Examples:
- supabase sso show b5ae62f9-ef1d-4f11-a02b-731c8bbb11e8 --project-ref mwjylndxudmiehsxhmmz
-
-Flags:
- -h, --help help for show
- --metadata Show SAML 2.0 XML Metadata only
-```
-
-#### sso update
-
-```
-Update the configuration settings of a already added SSO identity provider.
-
-Usage:
- supabase sso update [flags]
-
-Examples:
- supabase sso update b5ae62f9-ef1d-4f11-a02b-731c8bbb11e8 --project-ref mwjylndxudmiehsxhmmz --add-domains example.com
-
-Flags:
- --add-domains strings Add this comma separated list of email domains to the identity provider.
- --attribute-mapping-file string File containing a JSON mapping between SAML attributes to custom JWT claims.
- --domains strings Replace domains with this comma separated list of email domains.
- -h, --help help for update
- --metadata-file string File containing a SAML 2.0 Metadata XML document describing the identity provider.
- --metadata-url string URL pointing to a SAML 2.0 Metadata XML document describing the identity provider.
- --name-id-format string URI reference representing the classification of string-based identifier information.
- --remove-domains strings Remove this comma separated list of email domains from the identity provider.
- --skip-url-validation Whether local validation of the SAML 2.0 Metadata URL should not be performed.
-```
-
-### storage
-
-```
-Manage Supabase Storage objects
-
-Usage:
- supabase storage [command]
-
-Available Commands:
- cp Copy objects from src to dst path
- ls List objects by path prefix
- mv Move objects from src to dst path
- rm Remove objects by file path
-
-Flags:
- -h, --help help for storage
- --linked Connects to Storage API of the linked project. (default true)
- --local Connects to Storage API of the local database.
-```
-
-#### storage cp
-
-```
-Copy objects from src to dst path
-
-Usage:
- supabase storage cp [flags]
-
-Examples:
-cp readme.md ss:///bucket/readme.md
-cp -r docs ss:///bucket/docs
-cp -r ss:///bucket/docs .
-Flags:
- --cache-control string Custom Cache-Control header for HTTP upload. (default "max-age=3600")
- --content-type string Custom Content-Type header for HTTP upload. (default "auto-detect")
- -h, --help help for cp
- -j, --jobs uint Maximum number of parallel jobs. (default 1)
- -r, --recursive Recursively copy a directory.
-```
-
-#### storage ls
-
-```
-List objects by path prefix
-
-Usage:
- supabase storage ls [path] [flags]
-
-Examples:
-ls ss:///bucket/docs
-
-Flags:
- -h, --help help for ls
- -r, --recursive Recursively list a directory.
-```
-
-#### storage mv
-
-```
-Move objects from src to dst path
-
-Usage:
- supabase storage mv [flags]
-
-Examples:
-mv -r ss:///bucket/docs ss:///bucket/www/docs
-
-Flags:
- -h, --help help for mv
- -r, --recursive Recursively move a directory.
-```
-
-#### storage rm
-
-```
-Remove objects by file path
-
-Usage:
- supabase storage rm ... [flags]
-
-Examples:
-rm -r ss:///bucket/docs
-rm ss:///bucket/docs/example.md ss:///bucket/readme.md
-Flags:
- -h, --help help for rm
- -r, --recursive Recursively remove a directory.
-```
-
-### vanity-subdomains
-
-```
-Manage vanity subdomains for Supabase projects.
-
-Usage of vanity subdomains and custom domains is mutually exclusive.
-
-Usage:
- supabase vanity-subdomains [command]
-
-Available Commands:
- activate Activate a vanity subdomain
- check-availability Checks if a desired subdomain is available for use
- delete Deletes a project's vanity subdomain
- get Get the current vanity subdomain
-
-Flags:
- -h, --help help for vanity-subdomains
- --project-ref string Project ref of the Supabase project.
-```
-
-#### vanity-subdomains activate
-
-```
-Activate a vanity subdomain for your Supabase project.
-
-This reconfigures your Supabase project to respond to requests on your vanity subdomain.
-After the vanity subdomain is activated, your project's auth services will no longer function on the {project-ref}.{supabase-domain} hostname.
-
-Usage:
- supabase vanity-subdomains activate [flags]
-
-Flags:
- --desired-subdomain string The desired vanity subdomain to use for your Supabase project.
- -h, --help help for activate
-```
-
-#### vanity-subdomains check-availability
-
-```
-Checks if a desired subdomain is available for use
-
-Usage:
- supabase vanity-subdomains check-availability [flags]
-
-Flags:
- --desired-subdomain string The desired vanity subdomain to use for your Supabase project.
- -h, --help help for check-availability
-```
-
-#### vanity-subdomains delete
-
-```
-Deletes the vanity subdomain for a project, and reverts to using the project ref for routing.
-
-Usage:
- supabase vanity-subdomains delete [flags]
-
-Flags:
- -h, --help help for delete
-```
-
-#### vanity-subdomains get
-
-```
-Get the current vanity subdomain
-
-Usage:
- supabase vanity-subdomains get [flags]
-
-Flags:
- -h, --help help for get
-```
-
----
-
-## Additional Commands
-
-### completion
-
-```
-Generate the autocompletion script for supabase for the specified shell.
-See each sub-command's help for details on how to use the generated script.
-
-Usage:
- supabase completion [command]
-
-Available Commands:
- bash Generate the autocompletion script for bash
- fish Generate the autocompletion script for fish
- powershell Generate the autocompletion script for powershell
- zsh Generate the autocompletion script for zsh
-
-Flags:
- -h, --help help for completion
-```
-
-#### completion bash
-
-```
-Generate the autocompletion script for the bash shell.
-
-This script depends on the 'bash-completion' package.
-If it is not installed already, you can install it via your OS's package manager.
-
-To load completions in your current shell session:
-
- source <(supabase completion bash)
-
-To load completions for every new session, execute once:
-
-#### Linux:
-
- supabase completion bash > /etc/bash_completion.d/supabase
-
-#### macOS:
-
- supabase completion bash > $(brew --prefix)/etc/bash_completion.d/supabase
-
-You will need to start a new shell for this setup to take effect.
-
-Usage:
- supabase completion bash
-
-Flags:
- -h, --help help for bash
- --no-descriptions disable completion descriptions
-```
-
-#### completion fish
-
-```
-Generate the autocompletion script for the fish shell.
-
-To load completions in your current shell session:
-
- supabase completion fish | source
-
-To load completions for every new session, execute once:
-
- supabase completion fish > ~/.config/fish/completions/supabase.fish
-
-You will need to start a new shell for this setup to take effect.
-
-Usage:
- supabase completion fish [flags]
-
-Flags:
- -h, --help help for fish
- --no-descriptions disable completion descriptions
-```
-
-#### completion powershell
-
-```
-Generate the autocompletion script for powershell.
-
-To load completions in your current shell session:
-
- supabase completion powershell | Out-String | Invoke-Expression
-
-To load completions for every new session, add the output of the above command
-to your powershell profile.
-
-Usage:
- supabase completion powershell [flags]
-
-Flags:
- -h, --help help for powershell
- --no-descriptions disable completion descriptions
-```
-
-#### completion zsh
-
-```
-Generate the autocompletion script for the zsh shell.
-
-If shell completion is not already enabled in your environment you will need
-to enable it. You can execute the following once:
-
- echo "autoload -U compinit; compinit" >> ~/.zshrc
-
-To load completions in your current shell session:
-
- source <(supabase completion zsh)
-
-To load completions for every new session, execute once:
-
-#### Linux:
-
- supabase completion zsh > "${fpath[1]}/_supabase"
-
-#### macOS:
-
- supabase completion zsh > $(brew --prefix)/share/zsh/site-functions/_supabase
-
-You will need to start a new shell for this setup to take effect.
-
-Usage:
- supabase completion zsh [flags]
-
-Flags:
- -h, --help help for zsh
- --no-descriptions disable completion descriptions
-```
-
-### help
-
-```
-Help provides help for any command in the application.
-Simply type supabase help [path to command] for full details.
-
-Usage:
- supabase help [command] [flags]
-
-Flags:
- -h, --help help for help
-```
diff --git a/apps/cli/docs/release-process.md b/apps/cli/docs/release-process.md
index 9e2433ca6c..53b893813f 100644
--- a/apps/cli/docs/release-process.md
+++ b/apps/cli/docs/release-process.md
@@ -34,7 +34,6 @@ pnpm local-registry
Publish the CLI into it from another terminal (current platform only, faster than a cross-platform build):
```sh
-# CLI (Bun SFE + Go sidecar — requires Go on PATH and `pnpm repos:install`):
pnpm cli-release
```
@@ -44,7 +43,7 @@ Test it:
npx --registry http://localhost:4873 supabase@ --version
```
-`[tools/release/local-release.ts](../../../tools/release/local-release.ts)` does the heavy lifting: it builds the platform SFE (+ Go sidecar) and the umbrella `supabase` package, materialises them in a `tmp` dir (so no workspace `package.json` is modified), and publishes both to Verdaccio. The cleanup is automatic even on failure.
+`[tools/release/local-release.ts](../../../tools/release/local-release.ts)` does the heavy lifting: it builds the platform SFE and the umbrella `supabase` package, materialises them in a `tmp` dir (so no workspace `package.json` is modified), and publishes both to Verdaccio. The cleanup is automatic even on failure.
This is the right ring for:
@@ -60,7 +59,7 @@ It is **not** a valid test for Homebrew or Scoop — those paths are covered in
This is how you validate the Homebrew formula, Scoop manifest, and GitHub-Release-host resolution on real infrastructure without touching `supabase/`\* repos or risking a clash with an already-installed `supabase` CLI on the reviewer's machine.
-Both updater scripts support a `--name ` flag that pushes the formula / manifest under a different name (e.g., `supabase-shim-poc`) — that is, a different filename and Ruby class / scoop manifest. The installed binary is always `supabase` (matching the Go CLI), so PoC reviewers should `brew uninstall supabase` / `scoop uninstall supabase` first if they already have the official CLI installed.
+Both updater scripts support a `--name ` flag that pushes the formula / manifest under a different name (e.g., `supabase-shim-poc`) — that is, a different filename and Ruby class / scoop manifest. The installed binary is always `supabase`, so PoC reviewers should `brew uninstall supabase` / `scoop uninstall supabase` first if they already have the official CLI installed.
### One-time setup (per reviewer)
@@ -87,7 +86,6 @@ The `--dry-run` flag on both updater scripts produces the `Formula/.rb` an
```sh
# Build all eight platform archives + linux packages + checksums.txt.
-# Ships the Go sidecar alongside the Bun SFE.
bun apps/cli/scripts/build.ts --version 0.0.1
# Render the Homebrew formula against your PoC release host + tap.
@@ -176,13 +174,13 @@ Validated on Windows x64 (`v0.0.1`, 2026-04-21): installed with no SmartScreen b
### What to validate
-Beyond `--version` and `brew test`, exercise a Phase-0 proxied subcommand that requires the `supabase-go` sidecar:
+Beyond `--version` and `brew test`, exercise the actual command tree rather than only a flag resolved at build time:
```sh
-supabase completion bash
+supabase --help
```
-This must spawn the colocated `supabase-go` and print the generated completion script — not return `NotFound: ChildProcess.spawn (supabase ...)`. (`supabase --version` is served by the Bun wrapper and never touches the sidecar, so it is not a sufficient check on its own.) If it fails, the Homebrew install step is wrong: check that `[apps/cli/scripts/update-homebrew.ts](../scripts/update-homebrew.ts)`'s install-lines block ran `bin.install "supabase-go" if File.exist?("supabase-go")`, and that the built archive actually contains `supabase-go` (it should, for any release build).
+This must print the full command tree, not fail or truncate — a corrupted or partial binary can still resolve `--version` (a build-time `--define`) while failing on real command dispatch.
### Local-artifact testing (no GitHub Release upload)
@@ -287,12 +285,12 @@ Do not use `workflow_dispatch dry_run=false` as the normal hotfix path. Manual s
`**build` (ubuntu-latest):\*\*
1. `[pnpm exec bun apps/cli/scripts/sync-versions.ts --version X.Y.Z](../scripts/sync-versions.ts)` — writes the release version into every `package.json` (umbrella + eight platform packages) and resolves the umbrella's `workspace:`\* `optionalDependencies` to `X.Y.Z`.
-2. `[pnpm exec bun apps/cli/scripts/build.ts --version X.Y.Z](../scripts/build.ts)` — cross-compiles the Bun SFE for all eight targets (including windows-arm64), cross-compiles the Go sidecar, **ad-hoc signs the macOS binaries** (see [Code signing (macOS)](#code-signing-macos)), builds the six Linux packages via `nfpm`, produces the tar/zip archives, and writes `dist/checksums.txt`.
+2. `[pnpm exec bun apps/cli/scripts/build.ts --version X.Y.Z](../scripts/build.ts)` — cross-compiles the Bun SFE for all eight targets (including windows-arm64), **ad-hoc signs the macOS binaries** (see [Code signing (macOS)](#code-signing-macos)), builds the six Linux packages via `nfpm`, produces the tar/zip archives, and writes `dist/checksums.txt`.
3. `actions/upload-artifact` preserves `packages/cli-*/bin/` and `dist/` for the downstream jobs.
`**smoke-test` (matrix: `ubuntu-latest`, `macos-latest`, `macos-15-intel`, `windows-latest`):\*\*
-Downloads the build artifact, makes the SFE executable (`chmod +x` on non-Windows), installs Scoop on Windows, and runs `pnpm run test:smoke -- --version X.Y.Z --tag ` from `apps/cli`. On the macOS legs this also verifies each binary's signature (`codesign --verify --strict`, correct identifier, not linker-signed) and executes `supabase --version`, which is the real AMFI gate. Any failure blocks publishing.
+Downloads the build artifact, makes the SFE executable (`chmod +x` on non-Windows), installs Scoop on Windows, and runs `pnpm run test:smoke -- --version X.Y.Z --tag ` from `apps/cli`. On the macOS legs this also verifies the binary's signature (`codesign --verify --strict`, correct identifier, not linker-signed) and executes `supabase --version`, which is the real AMFI gate. Any failure blocks publishing.
The matrix does not yet include `windows-11-arm` (gate 6) or an Alpine musl runner (also gate 6). Until those land, arm64 / musl regressions only surface in Ring 2 validation.
@@ -316,13 +314,13 @@ Both updaters run automatically from `release-shared.yml`'s `publish-homebrew` a
Once the channels are live, two reusable workflows run automatically (last in `release-shared.yml`, non-gating — by the time they run the artifacts are already published, so a failure surfaces as a red post-release signal rather than blocking distribution):
- `[setup-cli-smoke-test.yml](../../../.github/workflows/setup-cli-smoke-test.yml)` (`setup-cli-smoke` job) — installs the released version through `supabase/setup-cli` (the GitHub Release download path) on Linux, macOS, Windows, and Alpine.
-- `[verify-install-channels.yml](../../../.github/workflows/verify-install-channels.yml)` (`verify-install-channels` job) — runs a **real** `brew install` (macOS **and** Linux, so both the `on_macos` and `on_linux` stanzas of the formula are exercised), `scoop install`, and `curl|bash` install of the **published** install script (fetched from the release asset, not the repo checkout) against the just-published Homebrew tap, Scoop bucket, and GitHub Release. Each leg then asserts `supabase --version` matches and runs `supabase completion bash` (a Go-proxied command) so a package that omits or misplaces the `supabase-go` sidecar fails too. brew, scoop, and the install script each verify the published `sha256`/`hash` against the downloaded tarball, so this is the signal that would have caught CLI v2.107.0 (where the brew/scoop manifests shipped checksums that did not match the release tarballs and every `brew install` / `scoop install` failed). It only runs for `beta`/`stable` (the channels that publish brew/scoop) and can be dispatched manually against any already-published version via the Actions tab.
+- `[verify-install-channels.yml](../../../.github/workflows/verify-install-channels.yml)` (`verify-install-channels` job) — runs a **real** `brew install` (macOS **and** Linux, so both the `on_macos` and `on_linux` stanzas of the formula are exercised), `scoop install`, and `curl|bash` install of the **published** install script (fetched from the release asset, not the repo checkout) against the just-published Homebrew tap, Scoop bucket, and GitHub Release. Each leg then asserts `supabase --version` matches and runs `supabase --help` to exercise the actual command tree. brew, scoop, and the install script each verify the published `sha256`/`hash` against the downloaded tarball, so this is the signal that would have caught CLI v2.107.0 (where the brew/scoop manifests shipped checksums that did not match the release tarballs and every `brew install` / `scoop install` failed). It only runs for `beta`/`stable` (the channels that publish brew/scoop) and can be dispatched manually against any already-published version via the Actions tab.
### Code signing (macOS)
-The macOS binaries (`supabase` Bun SFE + `supabase-go` sidecar, `darwin-arm64` and `darwin-x64`) are signed inside `build.ts` between compilation and archiving, so the signed bytes flow into every channel that consumes `packages/cli-darwin-*/bin/` — npm platform packages, Homebrew, and the GitHub Release tarballs (which also feed the `install` script and `setup-cli`). Background: [ADR 0014](../../../docs/adr/0014-macos-code-signing-and-notarization.md).
+The macOS binary (`supabase` Bun SFE, `darwin-arm64` and `darwin-x64`) is signed inside `build.ts` between compilation and archiving, so the signed bytes flow into every channel that consumes `packages/cli-darwin-*/bin/` — npm platform packages, Homebrew, and the GitHub Release tarballs (which also feed the `install` script and `setup-cli`). Background: [ADR 0014](../../../docs/adr/0014-macos-code-signing-and-notarization.md).
-Why this exists: `bun build --compile` and the Go linker emit only a degenerate "linker-signed" ad-hoc signature (identifier `a.out`, no requirements blob). macOS 26+ AMFI rejects it and SIGKILLs the process at launch ([CLI-1621](https://linear.app/supabase/issue/CLI-1621) / [#5556](https://github.com/supabase/cli/issues/5556)). A full ad-hoc signature fixes it.
+Why this exists: `bun build --compile` emits only a degenerate "linker-signed" ad-hoc signature (identifier `a.out`, no requirements blob). macOS 26+ AMFI rejects it and SIGKILLs the process at launch ([CLI-1621](https://linear.app/supabase/issue/CLI-1621) / [#5556](https://github.com/supabase/cli/issues/5556)). A full ad-hoc signature fixes it.
- **Signing runs on the Linux build runner** via [`rcodesign`](https://github.com/indygreg/apple-platform-rs) (the apple-codesign project), which signs Mach-O binaries without a macOS host. No macOS signing job exists, and **no Apple credentials are required for the current ad-hoc signing** (Phase 1). The version + sha256 are pinned in the "Install rcodesign" step of [`build-cli-artifacts.yml`](../../../.github/workflows/build-cli-artifacts.yml).
- **CI hard-fails if signing is unavailable**: the build job sets `SUPABASE_CLI_REQUIRE_SIGNING=1`, so a missing `rcodesign` fails the build rather than silently shipping unsigned binaries. Local builds without `rcodesign` degrade to a warning and skip signing.
@@ -374,7 +372,7 @@ Rollback is straightforward because each channel is its own commit / release. Th
## See Also
- [ADR 0011](../../../docs/adr/0011-cli-release-and-distribution-strategy.md) — the decision record. Channel choices, signing rationale, open pre-cutover gates.
-- `[apps/cli/docs/binary-distribution.md](./binary-distribution.md)` — why each platform package contains two binaries (`supabase` SFE + `supabase-go` sidecar) and how they're resolved at runtime.
+- `[apps/cli/docs/binary-distribution.md](./binary-distribution.md)` — how each platform package's `supabase` binary is built and resolved at runtime.
- `[tools/release/local-release.ts](../../../tools/release/local-release.ts)` — Ring 1 implementation.
- `[apps/cli/scripts/build.ts](../scripts/build.ts)`, `[publish.ts](../scripts/publish.ts)`, `[sync-versions.ts](../scripts/sync-versions.ts)`, `[update-homebrew.ts](../scripts/update-homebrew.ts)`, `[update-scoop.ts](../scripts/update-scoop.ts)` — release script implementations.
- `[.github/workflows/release.yml](../../../.github/workflows/release.yml)`, `[release-shared.yml](../../../.github/workflows/release-shared.yml)`, `[deploy.yml](../../../.github/workflows/deploy.yml)`, `[deploy-check.yml](../../../.github/workflows/deploy-check.yml)` — Ring 3 pipeline.
diff --git a/apps/cli/package.json b/apps/cli/package.json
index ec1dd44350..2d7c6f576f 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -24,8 +24,7 @@
"access": "public"
},
"scripts": {
- "build": "pnpm build:go-sidecar && pnpm build:binary && pnpm build:shim",
- "build:go-sidecar": "mkdir -p dist && cp ../cli-go/supabase-go dist/supabase-go",
+ "build": "pnpm build:binary && pnpm build:shim",
"build:binary": "bun scripts/build-binary.ts",
"build:shim": "bun build src/shared/cli/bin.ts --outfile dist/supabase.js --target node",
"docs:spec": "bun scripts/generate-docs-spec.ts",
diff --git a/apps/cli/scripts/build.ts b/apps/cli/scripts/build.ts
index 875b293f06..1e8aa72d1f 100644
--- a/apps/cli/scripts/build.ts
+++ b/apps/cli/scripts/build.ts
@@ -1,6 +1,6 @@
import { $ } from "bun";
import { createHash } from "node:crypto";
-import { copyFile, mkdir, readFile, rm, writeFile } from "node:fs/promises";
+import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
import path from "node:path";
import process from "node:process";
import { parseArgs } from "node:util";
@@ -86,24 +86,12 @@ const TARGETS = [
const entrypoint = path.join(root, "apps/cli/src/main.ts");
const distDir = path.join(root, "dist");
-const goSource = path.resolve(root, "apps/cli-go");
const buildDefines = {
SUPABASE_FUNCTIONS_SERVE_MAIN_TEMPLATE: JSON.stringify(await bundleServeMainTemplate()),
"process.env.SUPABASE_CLI_POSTHOG_KEY": JSON.stringify(process.env.POSTHOG_API_KEY ?? ""),
"process.env.SUPABASE_CLI_POSTHOG_HOST": JSON.stringify(process.env.POSTHOG_ENDPOINT ?? ""),
};
-type BunTarget = (typeof TARGETS)[number]["bunTarget"];
-
-const GO_TARGETS: Record = {
- "bun-darwin-arm64": { goos: "darwin", goarch: "arm64" },
- "bun-darwin-x64": { goos: "darwin", goarch: "amd64" },
- "bun-linux-arm64": { goos: "linux", goarch: "arm64" },
- "bun-linux-x64-baseline": { goos: "linux", goarch: "amd64" },
- "bun-windows-x64-baseline": { goos: "windows", goarch: "amd64" },
- "bun-windows-arm64": { goos: "windows", goarch: "arm64" },
-};
-
type SignMode = "adhoc" | "off";
function libcForBunTarget(target: string): "glibc" | "musl" | "" {
@@ -144,37 +132,6 @@ async function buildTarget(target: (typeof TARGETS)[number]) {
console.log(`[${target.pkg}] Done.`);
}
-async function buildGoTarget(target: (typeof TARGETS)[number]) {
- const binDir = path.join(root, "packages", target.pkg, "bin");
- await mkdir(binDir, { recursive: true });
-
- const { goos, goarch } = GO_TARGETS[target.bunTarget];
- const outfile = path.join(binDir, `supabase-go${target.ext}`);
-
- console.log(`[${target.pkg}] Compiling Go CLI (${goos}/${goarch})...`);
- const ldflagParts = ["-s", "-w", `-X github.com/supabase/cli/internal/utils.Version=${version}`];
- const { SENTRY_DSN, POSTHOG_API_KEY, POSTHOG_ENDPOINT } = process.env;
- if (SENTRY_DSN) {
- ldflagParts.push(`-X github.com/supabase/cli/internal/utils.SentryDsn=${SENTRY_DSN}`);
- }
- if (POSTHOG_API_KEY) {
- ldflagParts.push(`-X github.com/supabase/cli/internal/utils.PostHogAPIKey=${POSTHOG_API_KEY}`);
- }
- if (POSTHOG_ENDPOINT) {
- ldflagParts.push(
- `-X github.com/supabase/cli/internal/utils.PostHogEndpoint=${POSTHOG_ENDPOINT}`,
- );
- }
- const goLdflags = ldflagParts.join(" ");
- await $`go build -trimpath -ldflags=${goLdflags} -o ${outfile} .`.cwd(goSource).env({
- ...process.env,
- GOOS: goos,
- GOARCH: goarch,
- CGO_ENABLED: "0",
- });
- console.log(`[${target.pkg}] Go binary done.`);
-}
-
/**
* Decides how to sign macOS binaries. `rcodesign` signs Mach-O binaries from Linux, so signing
* runs inline on this build runner; falls back to "off" with a warning unless
@@ -216,11 +173,9 @@ async function signDarwinBinaries(mode: SignMode) {
console.log(`[${target.pkg}] Ad-hoc signing ${binary} (${identifier})...`);
// No key material, so rcodesign produces an ad-hoc signature, equivalent to
- // `codesign --sign -`, replacing Bun/Go's linker-signed one.
+ // `codesign --sign -`, replacing Bun's linker-signed one.
await $`rcodesign sign --binary-identifier ${identifier} ${binPath}`;
- // Matches the identifier's whole value, so the SFE's `com.supabase.cli` can't satisfy
- // the sidecar's `com.supabase.cli-go`, and confirms the signature is no longer linker-signed.
const info = await $`rcodesign print-signature-info ${binPath}`.text();
const signedIdentifier = info.match(/^\s*identifier:\s*(\S+)\s*$/m)?.[1];
if (signedIdentifier !== identifier) {
@@ -242,21 +197,18 @@ async function archiveTarget(target: (typeof TARGETS)[number]) {
console.log(`[${target.pkg}] Creating archive ${target.archive}...`);
if (target.archive.endsWith(".zip")) {
- const files = [
- path.join(binDir, `supabase${target.ext}`),
- path.join(binDir, `supabase-go${target.ext}`),
- ];
+ const files = [path.join(binDir, `supabase${target.ext}`)];
await $`zip -j ${archivePath} ${files}`;
// setup-cli and other download clients always fetch a .tar.gz, even on Windows, so
// publish one alongside the .zip. See #5257.
const tarArchive = target.archive.replace(/\.zip$/, ".tar.gz");
const tarArchivePath = path.join(distDir, tarArchive);
- const tarFiles = [`supabase${target.ext}`, `supabase-go${target.ext}`];
+ const tarFiles = [`supabase${target.ext}`];
console.log(`[${target.pkg}] Creating archive ${tarArchive}...`);
await $`tar -czf ${tarArchivePath} -C ${binDir} ${tarFiles}`;
} else {
- const files = [`supabase${target.ext}`, `supabase-go${target.ext}`];
+ const files = [`supabase${target.ext}`];
await $`tar -czf ${archivePath} -C ${binDir} ${files}`;
}
}
@@ -281,19 +233,6 @@ async function buildMuslBinaries() {
},
});
- // The Go binary is fully static (CGO_ENABLED=0), so the glibc build works on musl too;
- // copy it into the musl package since musl has no native Go build of its own.
- const glibcTarget = TARGETS.find(
- (candidate) => "nfpmArch" in candidate && candidate.nfpmArch === target.nfpmArch,
- );
- if (!glibcTarget) {
- throw new Error(`No glibc Linux target found for musl arch ${target.nfpmArch}`);
- }
- const src = path.join(root, "packages", glibcTarget.pkg, "bin", "supabase-go");
- const dst = path.join(binDir, "supabase-go");
- console.log(`[${target.pkg}] Copying Go binary from ${glibcTarget.pkg}...`);
- await copyFile(src, dst);
-
console.log(`[${target.pkg}] Done.`);
}),
);
@@ -313,11 +252,8 @@ async function buildLinuxPackages(version: string) {
const outPath = path.join(distDir, outFile);
const binDir = fmt === "apk" ? muslBinDir : glibcBinDir;
- // The Go binary is fully static, so apk (musl) still references supabase-go
- // from the glibc dir where it was built.
const contents: Array<{ src: string; dst: string }> = [
{ src: path.join(binDir, "supabase"), dst: "/usr/bin/supabase" },
- { src: path.join(glibcBinDir, "supabase-go"), dst: "/usr/bin/supabase-go" },
];
const nfpmConfig: Record = {
@@ -388,9 +324,6 @@ console.log(`Building the CLI for ${TARGETS.length} targets...\n`);
await Promise.all(TARGETS.map(buildTarget));
-console.log("\nCompiling Go CLI for all targets...");
-await Promise.all(TARGETS.map(buildGoTarget));
-
// Must run before archiveTarget / buildLinuxPackages / generateChecksums so every
// distribution channel ships the signed bytes.
const signMode = resolveSignMode();
diff --git a/apps/cli/scripts/macos-signing.ts b/apps/cli/scripts/macos-signing.ts
index 13b3037a63..b5d2656ae8 100644
--- a/apps/cli/scripts/macos-signing.ts
+++ b/apps/cli/scripts/macos-signing.ts
@@ -1,14 +1,12 @@
/**
* macOS code-signing identifiers, shared by the signer (`build.ts`) and its verifier so both
- * agree. `bun build --compile` and the Go linker emit an ad-hoc signature that macOS 26+ AMFI
- * SIGKILLs at launch (GitHub #5556); re-signing with a full ad-hoc signature fixes it without
- * Apple credentials.
+ * agree. `bun build --compile` emits an ad-hoc signature that macOS 26+ AMFI SIGKILLs at launch
+ * (GitHub #5556); re-signing with a full ad-hoc signature fixes it without Apple credentials.
*/
-export type MacBinaryName = "supabase" | "supabase-go";
+export type MacBinaryName = "supabase";
export const MACOS_IDENTIFIERS: Record = {
supabase: "com.supabase.cli",
- "supabase-go": "com.supabase.cli-go",
};
/**
@@ -16,10 +14,10 @@ export const MACOS_IDENTIFIERS: Record = {
* macOS binary, so callers verifying an arbitrary path fail closed.
*/
export function macIdentifierFor(binary: string): string | undefined {
- return binary === "supabase" || binary === "supabase-go" ? MACOS_IDENTIFIERS[binary] : undefined;
+ return binary === "supabase" ? MACOS_IDENTIFIERS[binary] : undefined;
}
-/** The macOS binaries shipped for the CLI: the Bun binary and its Go sidecar. */
+/** The macOS binaries shipped for the CLI. */
export function darwinBinaries(): MacBinaryName[] {
- return ["supabase", "supabase-go"];
+ return ["supabase"];
}
diff --git a/apps/cli/scripts/update-homebrew.ts b/apps/cli/scripts/update-homebrew.ts
index 6266fef0e7..3ca6e2ad1e 100644
--- a/apps/cli/scripts/update-homebrew.ts
+++ b/apps/cli/scripts/update-homebrew.ts
@@ -40,13 +40,7 @@ const className = name
.map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
.join("");
-// The Go sidecar is looked up by exact filename next to the running binary, so it must install
-// under its original name; `if File.exist?` keeps the formula working when a build ships only
-// the CLI binary.
-const installBlock = [
- ` bin.install "supabase"`,
- ` bin.install "supabase-go" if File.exist?("supabase-go")`,
-].join("\n");
+const installBlock = [` bin.install "supabase"`].join("\n");
const testInvocation = `#{bin}/supabase`;
diff --git a/apps/cli/src/command-internal/db-pull-run.errors.ts b/apps/cli/src/command-internal/db-pull-run.errors.ts
index 6717bf6520..0a61e61212 100644
--- a/apps/cli/src/command-internal/db-pull-run.errors.ts
+++ b/apps/cli/src/command-internal/db-pull-run.errors.ts
@@ -30,8 +30,7 @@ export class DbPullInSyncError extends Data.TaggedError("DbPullInSyncError")<{
/**
* Explains the non-zero exit instead of letting `Output.fail` append the generic "Try
* rerunning the command with --debug" footer: an in-sync database is a finding, not a failure
- * to troubleshoot. See `docs/go-cli-divergences.md` for the established message/exit-code
- * contract this preserves.
+ * to troubleshoot.
*/
readonly suggestion: string;
}> {
diff --git a/apps/cli/src/command-internal/db-pull-run.ts b/apps/cli/src/command-internal/db-pull-run.ts
index 25104e1d09..21d115dd60 100644
--- a/apps/cli/src/command-internal/db-pull-run.ts
+++ b/apps/cli/src/command-internal/db-pull-run.ts
@@ -90,8 +90,7 @@ const DEPRECATION_LINE =
/**
* Explains the in-sync non-zero exit instead of the generic "Try rerunning the command with
- * --debug…" footer, which would read like a crash for what is really a finding. See
- * `docs/go-cli-divergences.md` for the established message/exit-code contract.
+ * --debug…" footer, which would read like a crash for what is really a finding.
*/
const IN_SYNC_SUGGESTION =
"The remote database is already in sync with your local migrations — nothing to pull.";
diff --git a/apps/cli/src/commands/db/pull/SIDE_EFFECTS.md b/apps/cli/src/commands/db/pull/SIDE_EFFECTS.md
index 023cb1c078..2199b5112d 100644
--- a/apps/cli/src/commands/db/pull/SIDE_EFFECTS.md
+++ b/apps/cli/src/commands/db/pull/SIDE_EFFECTS.md
@@ -125,12 +125,10 @@ at all, so nothing is cached for it.
| `1` | `--project-ref` set with a resolved target other than linked |
> Note: unlike `db diff`, an empty diff (`No schema changes found`) is a **non-zero
-> exit** for `db pull`. The message and exit code match Go, but the stderr footer
-> does not: instead of Go's generic
-> `Try rerunning the command with --debug to troubleshoot the error.`, `db pull`
-> prints
+> exit** for `db pull`. Instead of the generic
+> `Try rerunning the command with --debug to troubleshoot the error.` stderr footer,
+> `db pull` prints
> `The remote database is already in sync with your local migrations — nothing to pull.`
-> (deliberate divergence — see `docs/go-cli-divergences.md`).
## Output
diff --git a/apps/cli/src/commands/db/pull/pull.integration.test.ts b/apps/cli/src/commands/db/pull/pull.integration.test.ts
index 36b07c5c5a..465b0f9daf 100644
--- a/apps/cli/src/commands/db/pull/pull.integration.test.ts
+++ b/apps/cli/src/commands/db/pull/pull.integration.test.ts
@@ -1220,7 +1220,7 @@ describe("db pull", () => {
const s = setup(tmp.current, { remoteVersions: ["20240101000000"], edgeStdout: "" });
return Effect.gen(function* () {
// The message and non-zero exit are the contract; the generic --debug footer is
- // replaced with this explanation instead (docs/go-cli-divergences.md).
+ // replaced with this explanation instead.
const error = yield* dbPull(flags()).pipe(Effect.flip);
expect(error).toMatchObject({
_tag: "DbPullInSyncError",
diff --git a/apps/cli/src/commands/db/schema/declarative/declarative.former-default.ts b/apps/cli/src/commands/db/schema/declarative/declarative.former-default.ts
index c97ba22492..97fc0cc655 100644
--- a/apps/cli/src/commands/db/schema/declarative/declarative.former-default.ts
+++ b/apps/cli/src/commands/db/schema/declarative/declarative.former-default.ts
@@ -19,7 +19,7 @@ const formerDeclarativeDefaultWarning = (formerDirRel: string, defaultDirRel: st
/**
* Warns when a project still has a declarative tree at the former default `supabase/database`
* while relying on the implicit default, which now resolves to `supabase/schemas` — otherwise an
- * upgraded project silently stops reading its existing tree. See docs/go-cli-divergences.md.
+ * upgraded project silently stops reading its existing tree.
*
* Fires only when `declarative_schema_path` is unset, the new default directory has no entries,
* and the former default contains `.sql` files or an export manifest; probe failures read as
diff --git a/apps/cli/src/commands/db/schema/declarative/generate/SIDE_EFFECTS.md b/apps/cli/src/commands/db/schema/declarative/generate/SIDE_EFFECTS.md
index db631bd37a..3ba98ede4b 100644
--- a/apps/cli/src/commands/db/schema/declarative/generate/SIDE_EFFECTS.md
+++ b/apps/cli/src/commands/db/schema/declarative/generate/SIDE_EFFECTS.md
@@ -84,9 +84,8 @@ always go to stderr, in every `--output-format`. On success:
- `--db-url` / `--linked` / `--local` are mutually exclusive; absent all three,
smart mode prompts (existing-files overwrite → Local/Custom choice + reset offer).
- `--output-dir ` selects a destination for this invocation without changing
- config or activating it for later syncs (TS-only; deliberately not
- `--output`/`-o`, which the legacy root reserves for the global machine-format
- flag — see `docs/go-cli-divergences.md`).
+ config or activating it for later syncs (deliberately not `--output`/`-o`, which
+ the root command reserves for the global machine-format flag).
- When `declarative_schema_path` is unset, the new `supabase/schemas` default is
empty, and the former `supabase/database` default still contains `.sql` files
or an export manifest, a WARNING on stderr explains the default move and how
diff --git a/apps/cli/src/commands/db/start/SIDE_EFFECTS.md b/apps/cli/src/commands/db/start/SIDE_EFFECTS.md
index feb465d504..abca163e8a 100644
--- a/apps/cli/src/commands/db/start/SIDE_EFFECTS.md
+++ b/apps/cli/src/commands/db/start/SIDE_EFFECTS.md
@@ -191,9 +191,9 @@ pooler artifact downloads.
## Notes
- **`pg_net` converges with `[experimental.webhooks]` on every non-backup start** (shared
- `startDatabase` behavior — see `supabase start`'s SIDE_EFFECTS.md note and
- `docs/go-cli-divergences.md`): fresh volumes install it only when webhooks are enabled or
- migration history owns it; existing volumes with webhooks disabled DROP a `pg_net` that
+ `startDatabase` behavior — see `supabase start`'s SIDE_EFFECTS.md note): fresh volumes
+ install it only when webhooks are enabled or migration history owns it; existing volumes
+ with webhooks disabled DROP a `pg_net` that
migration history does not own. `pg_net` installed outside migrations (Studio SQL editor)
is dropped on the next start — accepted, documented edge.
- `--from-backup` restores the database from a logical backup file on start; the health
diff --git a/apps/cli/src/commands/start/SIDE_EFFECTS.md b/apps/cli/src/commands/start/SIDE_EFFECTS.md
index e9ca78a009..1bc7b9f9fa 100644
--- a/apps/cli/src/commands/start/SIDE_EFFECTS.md
+++ b/apps/cli/src/commands/start/SIDE_EFFECTS.md
@@ -315,9 +315,9 @@ prose, not structured data.
## Notes
-- **`pg_net` converges with `[experimental.webhooks]` on every non-backup start** (see
- `docs/go-cli-divergences.md`): a fresh volume installs `pg_net` only when webhooks are
- enabled or migration history contains a `create extension … pg_net`; an existing volume
+- **`pg_net` converges with `[experimental.webhooks]` on every non-backup start**: a fresh
+ volume installs `pg_net` only when webhooks are enabled or migration history contains a
+ `create extension … pg_net`; an existing volume
additionally DROPS a `pg_net` that migration history does not own when webhooks are
disabled. Accepted, documented edge: `pg_net` installed outside migrations (local Studio
SQL editor / extension toggle) is dropped on the next start, and a tracked dependency on
diff --git a/apps/cli/src/shared/functions/deploy.ts b/apps/cli/src/shared/functions/deploy.ts
index 3b2a74d172..7624407f2a 100644
--- a/apps/cli/src/shared/functions/deploy.ts
+++ b/apps/cli/src/shared/functions/deploy.ts
@@ -665,7 +665,7 @@ function substituteImportMapValue(
continue;
}
// Import-maps spec (implemented by Deno): a key matches exactly, or as a prefix only when it
- // ends with "/" — see go-cli-divergences.md for why this differs from a naive prefix match.
+ // ends with "/", unlike a naive prefix match.
if (prefix.endsWith("/")) {
// Spec normalization: a `/`-suffixed key whose address lacks a trailing
// `/` is an invalid mapping — dropped, not concatenated.
diff --git a/apps/cli/src/shared/services/dockerfile-go-sync.unit.test.ts b/apps/cli/src/shared/services/dockerfile-go-sync.unit.test.ts
deleted file mode 100644
index d8d058c146..0000000000
--- a/apps/cli/src/shared/services/dockerfile-go-sync.unit.test.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { readFileSync } from "node:fs";
-import { fileURLToPath } from "node:url";
-import { describe, expect, test } from "vitest";
-import serviceImagesDockerfile from "./Dockerfile" with { type: "text" };
-
-// The Go tree still `go:embed`s its own copy for a dependency that hasn't been removed
-// yet; this keeps the two copies in sync until apps/cli-go is deleted, at which point
-// this test should be deleted alongside it.
-const GO_DOCKERFILE_PATH = fileURLToPath(
- new URL("../../../../cli-go/pkg/config/templates/Dockerfile", import.meta.url),
-);
-
-describe("Go Dockerfile sync guard", () => {
- test("keeps the Go tree's embedded Dockerfile byte-identical to the TS-owned copy", () => {
- const goDockerfile = readFileSync(GO_DOCKERFILE_PATH, "utf8");
- expect(goDockerfile).toBe(serviceImagesDockerfile);
- });
-});
diff --git a/apps/cli/tests/helpers/macos-signature.ts b/apps/cli/tests/helpers/macos-signature.ts
index 8663ee076f..572845a027 100644
--- a/apps/cli/tests/helpers/macos-signature.ts
+++ b/apps/cli/tests/helpers/macos-signature.ts
@@ -38,8 +38,7 @@ export async function verifyMacSignature(binPath: string): Promise` on its
- // own line) so the SFE's `com.supabase.cli` can't satisfy the sidecar's
- // `com.supabase.cli-go` by substring.
+ // own line) rather than substring-matching within the surrounding signature output.
const actualId = info.match(/^Identifier=(.+)$/m)?.[1]?.trim();
if (actualId !== expectedId) {
return { passed: false, detail: `expected Identifier=${expectedId}, got:\n${info}` };
diff --git a/apps/cli/tests/smoke-test-macos.ts b/apps/cli/tests/smoke-test-macos.ts
index b55d6f84e4..8285578683 100644
--- a/apps/cli/tests/smoke-test-macos.ts
+++ b/apps/cli/tests/smoke-test-macos.ts
@@ -1,5 +1,4 @@
import { $ } from "bun";
-import { existsSync } from "node:fs";
import { mkdir } from "node:fs/promises";
import path from "node:path";
import process from "node:process";
@@ -58,9 +57,6 @@ console.log("=".repeat(60));
const arch = process.arch;
const binDir = path.join(root, "packages", `cli-darwin-${arch}`, "bin");
const binaries = ["supabase"];
- if (existsSync(path.join(binDir, "supabase-go"))) {
- binaries.push("supabase-go");
- }
for (const binary of binaries) {
const name = `native-darwin-${arch}-signature-${binary}`;
diff --git a/commitlint.config.js b/commitlint.config.js
index e291f5072a..6187070558 100644
--- a/commitlint.config.js
+++ b/commitlint.config.js
@@ -2,7 +2,6 @@ const PROJECT_SCOPES = [
"api",
"cli",
"cli-e2e",
- "cli-go",
"cli-test-helpers",
"config",
"docs",
diff --git a/docs/adr/0011-cli-release-and-distribution-strategy.md b/docs/adr/0011-cli-release-and-distribution-strategy.md
index 613186eff3..39ec4be9e6 100644
--- a/docs/adr/0011-cli-release-and-distribution-strategy.md
+++ b/docs/adr/0011-cli-release-and-distribution-strategy.md
@@ -94,7 +94,7 @@ We intentionally avoid extra tags such as `next` or `canary` so install surfaces
### Why unsigned artifacts (matching the Go CLI)
-The current Go CLI release — [`apps/cli-go/.goreleaser.yml`](../../apps/cli-go/.goreleaser.yml) and [`release.yml`](../../apps/cli-go/.github/workflows/release.yml) / [`release-beta.yml`](../../apps/cli-go/.github/workflows/release-beta.yml) — does **no signing of any kind**:
+The current Go CLI release — `apps/cli-go/.goreleaser.yml` and `release.yml` / `release-beta.yml` — does **no signing of any kind**:
- No `signs:` or `notarize:` block in `.goreleaser.yml`
- No `codesign` / `notarytool submit` / macOS notarization in the release workflow
@@ -185,7 +185,7 @@ Production tap: `supabase/homebrew-tap`. A single `supabase` formula replaces th
#### Scoop
-[`apps/cli/scripts/update-scoop.ts`](../../apps/cli/scripts/update-scoop.ts) clones the bucket repo, writes `supabase.json` (with an `autoupdate` block keyed off GitHub Releases), commits, and pushes. The manifest ships an `architecture` block with both `64bit` (x64) and `arm64` entries — matching the Go CLI's current GoReleaser output, which already targets `windows_arm64` in [`apps/cli-go/.goreleaser.yml`](../../apps/cli-go/.goreleaser.yml). Dropping arm64 would be a user-visible regression for anyone on a Windows-on-ARM device (Surface Pro X, recent Copilot+ PCs, Windows-11-ARM VMs on Apple Silicon).
+[`apps/cli/scripts/update-scoop.ts`](../../apps/cli/scripts/update-scoop.ts) clones the bucket repo, writes `supabase.json` (with an `autoupdate` block keyed off GitHub Releases), commits, and pushes. The manifest ships an `architecture` block with both `64bit` (x64) and `arm64` entries — matching the Go CLI's current GoReleaser output, which already targets `windows_arm64` in `apps/cli-go/.goreleaser.yml`. Dropping arm64 would be a user-visible regression for anyone on a Windows-on-ARM device (Surface Pro X, recent Copilot+ PCs, Windows-11-ARM VMs on Apple Silicon).
Windows-arm64 is live in the TS pipeline as of this branch — `packages/cli-windows-arm64/`, `bun-windows-arm64` in [`apps/cli/scripts/build.ts`](../../apps/cli/scripts/build.ts), and the `win32: { arm64, x64 }` map in [`apps/cli/src/shared/cli/bin.ts`](../../apps/cli/src/shared/cli/bin.ts) all shipped together. Bun supports this target natively ([Bun — Single-file executable § Supported targets](https://bun.com/docs/bundler/executables#supported-targets)), so no cross-compilation toolchain changes were required. See [`apps/cli/docs/release-process.md`](../../apps/cli/docs/release-process.md) for the full channel walkthrough.
@@ -277,7 +277,7 @@ These split into **pre-cutover gates** (must complete before `latest` flips from
```
4. **GitHub Release artifact host for PoC.** [`avallete/supabase-cli-release-poc`](https://github.com/avallete/supabase-cli-release-poc) hosts the `dist/supabase__*.{tar.gz,zip,deb,rpm,apk}` + `checksums.txt` the PoC formula/manifest URLs resolve against. At cutover this is replaced by `supabase/cli` (the current Go CLI Release host). The repo's git _tree_ is effectively empty; only its Releases matter.
-5. **Wire updaters into `release-shared.yml`.** **Remaining largest item before cutover.** Today [`release-shared.yml`](../../.github/workflows/release-shared.yml) finishes at `gh release edit --draft=false`; no Homebrew/Scoop push happens from CI. Add a `post-publish` job that runs [`update-homebrew.ts`](../../apps/cli/scripts/update-homebrew.ts) and [`update-scoop.ts`](../../apps/cli/scripts/update-scoop.ts) behind the `!inputs.dry_run` gate, only when `npm_tag == 'latest'` (we do not push Homebrew/Scoop for alpha). Needs a GitHub App token (following the pattern in [`apps/cli-go/.github/workflows/release.yml`](../../apps/cli-go/.github/workflows/release.yml): `APP_ID` + `GH_APP_PRIVATE_KEY` secrets, scoped to `homebrew-tap` and `scoop-bucket` repos) so release tokens never hold broader access. Until this lands, the Ring 3 playbook in [`apps/cli/docs/release-process.md`](../../apps/cli/docs/release-process.md) documents the manual `bun apps/cli/scripts/update-{homebrew,scoop}.ts --version ` post-release step.
+5. **Wire updaters into `release-shared.yml`.** **Remaining largest item before cutover.** Today [`release-shared.yml`](../../.github/workflows/release-shared.yml) finishes at `gh release edit --draft=false`; no Homebrew/Scoop push happens from CI. Add a `post-publish` job that runs [`update-homebrew.ts`](../../apps/cli/scripts/update-homebrew.ts) and [`update-scoop.ts`](../../apps/cli/scripts/update-scoop.ts) behind the `!inputs.dry_run` gate, only when `npm_tag == 'latest'` (we do not push Homebrew/Scoop for alpha). Needs a GitHub App token (following the pattern in `apps/cli-go/.github/workflows/release.yml`: `APP_ID` + `GH_APP_PRIVATE_KEY` secrets, scoped to `homebrew-tap` and `scoop-bucket` repos) so release tokens never hold broader access. Until this lands, the Ring 3 playbook in [`apps/cli/docs/release-process.md`](../../apps/cli/docs/release-process.md) documents the manual `bun apps/cli/scripts/update-{homebrew,scoop}.ts --version ` post-release step.
6. **Bun `--compile` musl validation + Windows arm64 smoke-test.** [`buildMuslBinaries`](../../apps/cli/scripts/build.ts) produces musl SFEs but the [smoke-test matrix](../../.github/workflows/release-shared.yml) only runs `ubuntu-latest` (glibc). Add an Alpine container job. Same matrix gap applies to Windows arm64 now that gate 1 is DONE: add a `windows-11-arm` runner (GitHub-hosted preview) so we catch arm64 regressions in CI rather than post-release.
7. **Local vs pipeline release-logic consolidation.** Tracked in sub-issue [CLI-1344](https://linear.app/supabase/issue/CLI-1344/investigate-if-we-can-consolidate-local-release-logic-and-pipeline). Intent: `bun apps/cli/scripts/{build,publish}.ts --dry-run` produces the identical output CI does; `sync-versions.ts` is the single versioning entry point.
8. **`findConfigInRoot` `ENOTDIR` handling.** Discovered while validating gate 2: [`packages/config/src/paths.ts`](../../packages/config/src/paths.ts)'s `fs.exists(supabase/config.json)` throws `BadResource` (`ENOTDIR`) instead of returning `false` when `cwd` contains a _file_ named `supabase` (e.g., the extracted SFE in a scratch dir during local install tests). The walk-upward resolver should treat `ENOTDIR` the same as `ENOENT`. Does not block the production brew path (`/opt/homebrew/bin/supabase-shim-poc` has no colliding `supabase` file in any parent), but it's a latent bug for any user whose `$HOME` or a parent contains a `supabase` file. Low-effort fix.
@@ -294,7 +294,7 @@ These are **not** scheduled work. They activate only if the matching pre-cutover
### Note on PoC repo management
-The three PoC repos (`avallete/homebrew-supabase-shim-poc`, `avallete/scoop-bucket`, `avallete/supabase-cli-release-poc`) are _*explicitly not added as `.repos/`* submodules__, even though `[.gitmodules](../../.gitmodules)` already tracks eight vendored reference repos (`effect`, `supabase-cli-go`, `process-compose`, etc.). Existing `.repos/`_ entries are read-only source-code references for `grep` / inspection; the PoC repos contain one generated artifact each (`Formula/supabase.rb`, `supabase.json`) or no interesting tree content at all. The `update-*.ts` scripts `gh repo clone` on demand into a tmpdir, so a submodule would change nothing about the release pipeline. Since these repos are PoC-phase only, vendoring now means a `.gitmodules` edit + `git rm` at cutover for zero operational benefit.
+The three PoC repos (`avallete/homebrew-supabase-shim-poc`, `avallete/scoop-bucket`, `avallete/supabase-cli-release-poc`) are _*explicitly not added as `.repos/`* submodules__, even though `[.gitmodules](../../.gitmodules)` already tracks seven vendored reference repos (`effect`, `effect-patterns`, `effect-v3`, `lalph`, `cheffect`, `t3code`, `opencode`). Existing `.repos/`_ entries are read-only source-code references for `grep` / inspection; the PoC repos contain one generated artifact each (`Formula/supabase.rb`, `supabase.json`) or no interesting tree content at all. The `update-*.ts` scripts `gh repo clone` on demand into a tmpdir, so a submodule would change nothing about the release pipeline. Since these repos are PoC-phase only, vendoring now means a `.gitmodules` edit + `git rm` at cutover for zero operational benefit.
## Implementation progress
@@ -325,6 +325,6 @@ This section tracks the work that has landed against the pre-cutover gates. Deta
- [`apps/cli/docs/binary-distribution.md`](../../apps/cli/docs/binary-distribution.md) — runtime resolution details for the two-binary legacy model (TS SFE + Go binary).
- [`.github/workflows/release-shared.yml`](../../.github/workflows/release-shared.yml), [`release.yml`](../../.github/workflows/release.yml) — the pipeline implementation (`release.yml` selects stable / beta / alpha channel per trigger).
- [`apps/cli/scripts/build.ts`](../../apps/cli/scripts/build.ts), [`publish.ts`](../../apps/cli/scripts/publish.ts), [`sync-versions.ts`](../../apps/cli/scripts/sync-versions.ts), [`update-homebrew.ts`](../../apps/cli/scripts/update-homebrew.ts), [`update-scoop.ts`](../../apps/cli/scripts/update-scoop.ts) — release scripts.
-- [`apps/cli-go/.goreleaser.yml`](../../apps/cli-go/.goreleaser.yml), [`release.yml`](../../apps/cli-go/.github/workflows/release.yml), [`release-beta.yml`](../../apps/cli-go/.github/workflows/release-beta.yml) — the Go CLI release config we mirror (no signing, `windows_arm64` target, GitHub-App-scoped publish tokens).
+- `apps/cli-go/.goreleaser.yml`, `release.yml`, `release-beta.yml` — the Go CLI release config we mirror (no signing, `windows_arm64` target, GitHub-App-scoped publish tokens).
- [CLI-1330](https://linear.app/supabase/issue/CLI-1330) — origin ticket.
- [CLI-1344](https://linear.app/supabase/issue/CLI-1344/investigate-if-we-can-consolidate-local-release-logic-and-pipeline) — sub-issue: consolidate local and pipeline release logic.
diff --git a/docs/adr/0016-legacy-port-completion-and-go-cli-authority-scope.md b/docs/adr/0016-legacy-port-completion-and-go-cli-authority-scope.md
index b9328da098..945acebd90 100644
--- a/docs/adr/0016-legacy-port-completion-and-go-cli-authority-scope.md
+++ b/docs/adr/0016-legacy-port-completion-and-go-cli-authority-scope.md
@@ -1,6 +1,6 @@
# 0016. Legacy Port Completion and Go CLI Authority Scope
-**Status**: proposed
+**Status**: accepted (2026-08-11), superseded by [0026](0026-go-cli-removal.md)
**Date**: 2026-08-11
## Problem Statement
diff --git a/docs/adr/0026-go-cli-removal.md b/docs/adr/0026-go-cli-removal.md
new file mode 100644
index 0000000000..5e13d9ee56
--- /dev/null
+++ b/docs/adr/0026-go-cli-removal.md
@@ -0,0 +1,123 @@
+# 0026. Go CLI Removal
+
+**Status**: accepted
+**Date**: 2026-09-14
+
+## Problem Statement
+
+ADR 0016 described a residual Go delegation surface in `src/legacy/`: a handful of commands still
+proxying to the Go binary (`GoProxy`) while the rest of the CLI had already been natively ported to
+TypeScript. That surface has now been fully replaced natively (CLI-2432) — no command in the
+TypeScript CLI spawns `supabase-go` anymore.
+
+That leaves `apps/cli-go/` — roughly 300 tracked files across three Go modules (the root CLI
+module, the `fsevents` helper module, and the separately-tagged `pkg` module) — serving nothing.
+It still carries its own Go toolchain pin, CI (test/coverage/lint/CodeQL), Dependabot ecosystem,
+release packaging (a second binary per platform, signed and archived alongside the TS binary), and
+documentation, all to build and ship a binary nothing calls.
+
+## Decision
+
+Delete `apps/cli-go/` entirely. The CLI ships as a single compiled binary per platform
+(`packages/cli-/bin/supabase`), built by `apps/cli/scripts/build.ts` with no Go
+compilation step.
+
+The one file the Go tree owned that TypeScript still needed — the service-image Dockerfile
+manifest parsed by `dockerfileServiceImages` — was already relocated into the TS tree
+(`apps/cli/src/shared/services/Dockerfile`) by a prep commit on this branch before the tree was
+deleted, so no runtime behavior depends on `apps/cli-go/` by the time it's removed.
+
+The tree's own `pkg` module (`github.com/supabase/cli/pkg`, a separately-tagged, externally
+published Go module) already had a structurally broken publish path before this ADR, not merely
+one this ADR chooses not to continue. At `pkg/v1.2.3` (2026-04-16, `ae7642d508`) the module lived
+at repo-root `pkg/`, matching Go's subdirectory-module convention that a `pkg/vX.Y.Z` tag resolves
+by finding `pkg/go.mod` at the repository root. `cad095718` ("chore(monorepo): move CLI sources
+under apps/cli-go/", 2026-05-06) relocated it to `apps/cli-go/pkg/` while keeping the same module
+path, so from that point any new `pkg/vX` tag would have been unresolvable — the module path no
+longer matched where `go.mod` actually lived. `pkg/v1.2.3` is therefore the last resolvable
+version, and was already roughly five months stale relative to `apps/cli-go/pkg`'s actual content
+before this deletion. Deleting the tree makes that unresolvability permanent rather than causing
+it. The durability guarantee for existing importers rests on two things: `refs/tags/pkg/v*` is
+protected against deletion, creation, and force-push by a repository ruleset ("Protect pkg/v*
+release tags", id 23327496), and on top of that the Go module proxy (`proxy.golang.org`, the
+default `GOPROXY`) caches published module zips independently of this repository's current tree,
+so an importer already pinned to a version keeps resolving it through the proxy even without
+direct access to the tag.
+
+## Consequences
+
+### Positive
+
+- The repo ships zero Go: no toolchain pin, no CI surface, no packaging step, no documentation
+ drift between two implementations of the same CLI.
+- Release archives, install scripts, and the Homebrew formula carry one binary instead of two,
+ removing an entire class of "sidecar present but stale/missing" failure mode.
+- `cli-go-ci.yml`'s test/coverage/lint/codegen jobs, the per-PR Go module dependency cache in the
+ shared setup action, and Dependabot's `gomod` ecosystem entry are all gone — but these jobs were
+ path-filtered to `apps/cli-go/**` and so ran only on PRs that touched the Go tree already; most
+ ordinary PRs never paid this cost. CodeQL's shape changes rather than shrinking uniformly: its
+ `go` language matrix entry is gone entirely, including from the `merge_group` trigger it used to
+ run on, while the remaining `javascript-typescript` entry now runs on every `pull_request` push
+ — coverage it effectively never had before, since `merge_group` was CodeQL's only unfiltered
+ trigger — bounded by a new concurrency group so pushes to the same PR no longer queue up
+ uncancelled analysis runs.
+
+### Negative
+
+- No further `pkg` module releases. External importers pinned to existing tags are unaffected, but
+ anyone needing content newer than `pkg/v1.2.3` has no upgrade path within this module. Two
+ external importers are known from a code-search during planning: `supabase/terraform-provider-supabase`
+ (same org, pins `pkg v1.2.3`) and `turbot/steampipe-plugin-supabase` (third-party); both import
+ only `pkg/api`. Because `pkg/api` is pure `oapi-codegen` output, the concrete unblock for both is
+ to run `oapi-codegen` in the consuming repo against the Management API OpenAPI document —
+ the same one `packages/api` already consumes — and drop the dependency on
+ `github.com/supabase/cli/pkg` entirely. One caveat: the deleted `apps/cli-go/api/README.md`
+ documented the Go snapshot as generated from **staging** (`https://api.supabase.green/api/v1-yaml`),
+ while `packages/api` generates from **production** (`https://api.supabase.com`, see
+ `packages/api/scripts/download-openapi.ts`), so a consumer following this unblock gets a
+ different — production, not staging — surface than `pkg/api` had, which is worth knowing now
+ that the source doc explaining that distinction is gone. Beyond these two, this repository has
+ no visibility into other importers beyond the module proxy's own download counts, which aren't
+ queried here.
+- Go-specific CI ends entirely: Coveralls coverage upload (Go-side) had no TypeScript-side
+ equivalent and simply stops with this PR — there is no CI-enforced coverage threshold for the
+ TypeScript CLI today. This is a known gap, not something this PR fixes; it is a candidate for a
+ follow-up if coverage enforcement is wanted.
+- golangci-lint and the `go` CodeQL analysis both end, along with any lint/security coverage they
+ provided that had no TypeScript-side equivalent (e.g. Go-specific vulnerability classes CodeQL's
+ `javascript-typescript` matrix entry doesn't check for).
+- The four `*.go-payload.ts` output-encoding specs (which drive `-o yaml`/`-o toml` byte-compatible
+ output) become frozen, hand-maintained contracts with no live Go source left to diff against for
+ drift. A prior commit on this branch already retargeted their drift test at the OpenAPI schema
+ instead of Go source, so this is a note about the ongoing nature of that contract, not new work.
+ `7b469f5b3` (2026-08-12, the CLI-1970 pin) is the last commit with the full pre-shrink Go source
+ tree intact and remains the closest available provenance reference for that contract's origin,
+ but it does not reflect `apps/cli-go/pkg/api`'s final state: that package kept regenerating via
+ the API-sync workflow for roughly another month after that pin, until this PR's tree deletion.
+
+## Alternatives Considered
+
+1. **Keep `pkg/` alone as a standalone Go module in this repo.** Rejected — this reintroduces the
+ entire Go toolchain, CI, and Dependabot surface this PR removes, to serve at most a couple of
+ external consumers of a single module.
+2. **Extract `pkg/` to its own separate repository before deleting it here.** Not chosen for this
+ PR. Because the publish path was already structurally broken since the May 2026 monorepo move
+ (see Decision), this would be a restart from the last resolvable state (`pkg/v1.2.3`), not a
+ continuation of an active release cadence. The module shipped 14 packages (`api`, `cast`,
+ `config`, `diff`, `fetcher`, `function`, `migration`, `parser`, `pgtest`, `pgxv5`, `queue`,
+ `storage`, `vault`, plus the root module); "internal" audience is only evidenced for the two
+ known importers named above, both of which use only `pkg/api` — not for the module as a whole.
+
+## Related Decisions
+
+- Supersedes [ADR 0016](0016-legacy-port-completion-and-go-cli-authority-scope.md), whose
+ residual authority scope no longer applies now that `apps/cli-go/` is gone.
+- [ADR 0011](0011-cli-release-and-distribution-strategy.md) and
+ [ADR 0014](0014-macos-code-signing-and-notarization.md) remain historically accurate records of
+ decisions made while the Go CLI still existed; they are not updated by this ADR.
+- Linear: CLI-2432.
+
+## See Also
+
+- [`apps/cli/docs/binary-distribution.md`](../../apps/cli/docs/binary-distribution.md)
+- [`apps/cli/docs/release-process.md`](../../apps/cli/docs/release-process.md)
diff --git a/docs/adr/README.md b/docs/adr/README.md
index 083f7fb36e..67142a3ad5 100644
--- a/docs/adr/README.md
+++ b/docs/adr/README.md
@@ -56,7 +56,7 @@ When an ADR becomes outdated, mark it as `deprecated` or reference the supersedi
| 0011 | [CLI Release & Distribution Strategy](0011-cli-release-and-distribution-strategy.md) | proposed |
| 0013 | [Live E2E Tests Bypass the Replay Server](0013-live-e2e-bypasses-replay-server.md) | accepted |
| 0015 | [Managed Stack Contract Fixtures](0015-managed-stack-contract-fixtures.md) | superseded |
-| 0016 | [Legacy Port Completion and Go CLI Authority Scope](0016-legacy-port-completion-and-go-cli-authority-scope.md) | proposed |
+| 0016 | [Legacy Port Completion and Go CLI Authority Scope](0016-legacy-port-completion-and-go-cli-authority-scope.md) | superseded |
| 0017 | [Simplified Managed Stack Architecture](0017-simplified-managed-stack-architecture.md) | accepted |
| 0018 | [Sparse Config Subtraction](0018-sparse-config-subtraction.md) | proposed |
| 0019 | [Raw API-Response Passthrough on API-Sourced Config](0019-config-api-response-passthrough.md) | accepted |
@@ -66,6 +66,7 @@ When an ADR becomes outdated, mark it as `deprecated` or reference the supersedi
| 0023 | [Config Pull Write Strategy and Scope Resolution](0023-config-pull-write-strategy-and-scope-resolution.md) | accepted |
| 0024 | [Top-Level `pull` Orchestration](0024-top-level-pull-orchestration.md) | accepted |
| 0025 | [Ephemeral Postgres for Schema Tooling](0025-ephemeral-postgres-for-schema-tooling.md) | proposed |
+| 0026 | [Go CLI Removal](0026-go-cli-removal.md) | accepted |
## Template
diff --git a/docs/openapi-sync.md b/docs/openapi-sync.md
index b55e756161..c5b34cce9c 100644
--- a/docs/openapi-sync.md
+++ b/docs/openapi-sync.md
@@ -2,6 +2,8 @@
> Extracted from [ADR 0005](adr/0005-openapi-driven-code-generation.md). This document covers the GitHub Actions workflows that keep checked-in OpenAPI types in sync with the live Management API. For the three-layer generation strategy and architectural decisions, see the ADR.
+> This document describes an earlier iteration of the API sync pipeline; see [`.github/workflows/api-package-sync.yml`](../.github/workflows/api-package-sync.yml) for the current workflow.
+
Three GitHub Actions workflows keep the checked-in `v1.d.ts` in sync with the live Management API spec across the private API repo and the public CLI repo.
## 1. Sync workflow (CLI repo — `.github/workflows/openapi-sync.yml`)
diff --git a/install b/install
index 98f8105032..0b017de889 100755
--- a/install
+++ b/install
@@ -181,6 +181,13 @@ verify_checksum() {
fi
}
+# Removes the pre-2.x Go sidecar this script used to install alongside the CLI;
+# single-binary releases no longer ship it (CLI-2432).
+remove_legacy_sidecar() {
+ local ext="$1"
+ rm -f "${INSTALL_DIR}/${APP}-go${ext}"
+}
+
install_from_binary() {
local ext="$1"
@@ -192,12 +199,13 @@ install_from_binary() {
mkdir -p "$INSTALL_DIR"
cp "$BINARY_PATH" "${INSTALL_DIR}/${APP}${ext}"
chmod 755 "${INSTALL_DIR}/${APP}${ext}"
+ remove_legacy_sidecar "$ext"
}
download_and_install() {
local target="$1"
local ext="$2"
- local version filename base_url tmp_dir archive checksums source_dir companion_ext
+ local version filename base_url tmp_dir archive checksums source_dir
need curl
need tar
@@ -250,11 +258,7 @@ download_and_install() {
mv "${source_dir}/${APP}${ext}" "${INSTALL_DIR}/${APP}${ext}"
chmod 755 "${INSTALL_DIR}/${APP}${ext}"
- companion_ext="$ext"
- if [[ -f "${source_dir}/${APP}-go${companion_ext}" ]]; then
- mv "${source_dir}/${APP}-go${companion_ext}" "${INSTALL_DIR}/${APP}-go${companion_ext}"
- chmod 755 "${INSTALL_DIR}/${APP}-go${companion_ext}"
- fi
+ remove_legacy_sidecar "$ext"
}
path_command_for_shell() {
diff --git a/knip.jsonc b/knip.jsonc
index 2d52beafc1..8cb87a5aba 100644
--- a/knip.jsonc
+++ b/knip.jsonc
@@ -2,12 +2,9 @@
"$schema": "./node_modules/knip/schema.json",
// Required in the event that git submodules are present. Do not remove this, despite knip warnings.
"ignore": [".repos/**"],
- // `go` comes from mise.
- "ignoreBinaries": ["go"],
// Spawned through a node_modules/.bin path in tools/release/local-registry.ts and
// bunx in apps/cli/tests/helpers/npm-registry.ts, which knip cannot trace.
"ignoreDependencies": ["verdaccio"],
- "ignoreWorkspaces": ["apps/cli-go"],
"workspaces": {
"apps/cli": {
"entry": [
diff --git a/mise.lock b/mise.lock
index beb5bc0ac6..633b43a0d4 100644
--- a/mise.lock
+++ b/mise.lock
@@ -51,126 +51,6 @@ url = "https://github.com/oven-sh/bun/releases/download/bun-v1.4.1/bun-windows-x
checksum = "sha256:2d1871e72b28165a8574a9c91de867cbe499f55b8c75facf4fb9e42888eddba6"
url = "https://github.com/oven-sh/bun/releases/download/bun-v1.4.1/bun-windows-x64-baseline.zip"
-[[tools.go]]
-version = "1.26.5"
-backend = "core:go"
-specifiers = ["1.26.5"]
-
-[tools.go."platforms.linux-arm64"]
-checksum = "sha256:fe4789e92b1f33358680864bbe8704289e7bb5fc207d80623c308935bd696d49"
-url = "https://dl.google.com/go/go1.26.5.linux-arm64.tar.gz"
-
-[tools.go."platforms.linux-arm64-musl"]
-checksum = "sha256:fe4789e92b1f33358680864bbe8704289e7bb5fc207d80623c308935bd696d49"
-url = "https://dl.google.com/go/go1.26.5.linux-arm64.tar.gz"
-
-[tools.go."platforms.linux-x64"]
-checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
-url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
-
-[tools.go."platforms.linux-x64-baseline"]
-checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
-url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
-
-[tools.go."platforms.linux-x64-musl"]
-checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
-url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
-
-[tools.go."platforms.linux-x64-musl-baseline"]
-checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
-url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
-
-[tools.go."platforms.macos-arm64"]
-checksum = "sha256:efb87ff28af9a188d0536ef5d42e63dd52ba8263cd7344a993cc48dd11dedb6a"
-url = "https://dl.google.com/go/go1.26.5.darwin-arm64.tar.gz"
-
-[tools.go."platforms.macos-x64"]
-checksum = "sha256:6231d8d3b8f5552ec6cbf6d685bdd5482e1e703214b120e89b3bf0d7bf1ef725"
-url = "https://dl.google.com/go/go1.26.5.darwin-amd64.tar.gz"
-
-[tools.go."platforms.macos-x64-baseline"]
-checksum = "sha256:6231d8d3b8f5552ec6cbf6d685bdd5482e1e703214b120e89b3bf0d7bf1ef725"
-url = "https://dl.google.com/go/go1.26.5.darwin-amd64.tar.gz"
-
-[tools.go."platforms.windows-x64"]
-checksum = "sha256:97e6b2a833b6d89f9ff17d25419ac0a7e3b482a044e9ab18cdef834bd834fd38"
-url = "https://dl.google.com/go/go1.26.5.windows-amd64.zip"
-
-[tools.go."platforms.windows-x64-baseline"]
-checksum = "sha256:97e6b2a833b6d89f9ff17d25419ac0a7e3b482a044e9ab18cdef834bd834fd38"
-url = "https://dl.google.com/go/go1.26.5.windows-amd64.zip"
-
-[[tools.golangci-lint]]
-version = "2.12.2"
-backend = "aqua:golangci/golangci-lint"
-specifiers = ["2.12.2"]
-
-[tools.golangci-lint."platforms.linux-arm64"]
-checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470996"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.linux-arm64-musl"]
-checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470996"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.linux-x64"]
-checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.linux-x64-baseline"]
-checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.linux-x64-musl"]
-checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.linux-x64-musl-baseline"]
-checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471054"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.macos-arm64"]
-checksum = "sha256:a9c54498731b3128f79e090be6110f3e5fffccc617b08142ed244d4126c73f29"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-arm64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470950"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.macos-x64"]
-checksum = "sha256:f6f06d94b6241521c53d15450c5209b028270bf966f842afb11c030c79f5bc16"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470980"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.macos-x64-baseline"]
-checksum = "sha256:f6f06d94b6241521c53d15450c5209b028270bf966f842afb11c030c79f5bc16"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-amd64.tar.gz"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413470980"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.windows-x64"]
-checksum = "sha256:bd42e3ebc8cb4ececb86941983baaf1dc221bbb04d838e94ce63b49cc91e02bb"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-windows-amd64.zip"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471017"
-provenance = "github-attestations"
-
-[tools.golangci-lint."platforms.windows-x64-baseline"]
-checksum = "sha256:bd42e3ebc8cb4ececb86941983baaf1dc221bbb04d838e94ce63b49cc91e02bb"
-url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-windows-amd64.zip"
-url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/413471017"
-provenance = "github-attestations"
-
[[tools.node]]
version = "24.20.0"
backend = "core:node"
diff --git a/mise.toml b/mise.toml
index f76945f5a7..91ec4a0f74 100644
--- a/mise.toml
+++ b/mise.toml
@@ -1,9 +1,5 @@
min_version = '2026.9.0'
-[tools]
-go = "1.26.5"
-golangci-lint = "2.12.2"
-
[settings]
idiomatic_version_file_enable_tools = ["node", "bun", "pnpm"]
lockfile = true
diff --git a/package.json b/package.json
index 8f04159aa9..abac746d91 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"test:smoke": "pnpm exec turbo run supabase#test:smoke --",
"test:github-scripts": "bun test ./.github/scripts",
"dev:docs": "pnpm exec turbo run @supabase/docs#dev",
- "test:unit": "pnpm exec turbo run test:unit:run --filter=!@supabase/cli-go --",
+ "test:unit": "pnpm exec turbo run test:unit:run --",
"test:integration": "pnpm exec turbo run test:integration:run --",
"test:e2e": "pnpm exec turbo run supabase#build && pnpm exec turbo run test:e2e:run --only --concurrency=1 --",
"test:vitest": "bun --bun vitest run --project '!*e2e*' --project '!*live*'",
diff --git a/packages/cli-darwin-arm64/package.json b/packages/cli-darwin-arm64/package.json
index 9245b363b9..f2dd3b6d52 100644
--- a/packages/cli-darwin-arm64/package.json
+++ b/packages/cli-darwin-arm64/package.json
@@ -24,8 +24,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-darwin-x64/package.json b/packages/cli-darwin-x64/package.json
index f14a323770..4c89d3d696 100644
--- a/packages/cli-darwin-x64/package.json
+++ b/packages/cli-darwin-x64/package.json
@@ -24,8 +24,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-linux-arm64-musl/package.json b/packages/cli-linux-arm64-musl/package.json
index 0b95049d4c..03ed91112d 100644
--- a/packages/cli-linux-arm64-musl/package.json
+++ b/packages/cli-linux-arm64-musl/package.json
@@ -27,8 +27,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-linux-arm64/package.json b/packages/cli-linux-arm64/package.json
index cef64df964..a559fcc486 100644
--- a/packages/cli-linux-arm64/package.json
+++ b/packages/cli-linux-arm64/package.json
@@ -27,8 +27,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-linux-x64-musl/package.json b/packages/cli-linux-x64-musl/package.json
index 362f22edd1..8234394c7d 100644
--- a/packages/cli-linux-x64-musl/package.json
+++ b/packages/cli-linux-x64-musl/package.json
@@ -27,8 +27,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-linux-x64/package.json b/packages/cli-linux-x64/package.json
index aef98178c0..494867c9f2 100644
--- a/packages/cli-linux-x64/package.json
+++ b/packages/cli-linux-x64/package.json
@@ -27,8 +27,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase",
- "bin/supabase-go"
+ "bin/supabase"
]
},
"preferUnplugged": true
diff --git a/packages/cli-windows-arm64/package.json b/packages/cli-windows-arm64/package.json
index b0a19b2e39..f74cf42ce5 100644
--- a/packages/cli-windows-arm64/package.json
+++ b/packages/cli-windows-arm64/package.json
@@ -24,8 +24,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase.exe",
- "bin/supabase-go.exe"
+ "bin/supabase.exe"
]
},
"preferUnplugged": true
diff --git a/packages/cli-windows-x64/package.json b/packages/cli-windows-x64/package.json
index f04d229711..02be42f797 100644
--- a/packages/cli-windows-x64/package.json
+++ b/packages/cli-windows-x64/package.json
@@ -24,8 +24,7 @@
"publishConfig": {
"access": "public",
"executableFiles": [
- "bin/supabase.exe",
- "bin/supabase-go.exe"
+ "bin/supabase.exe"
]
},
"preferUnplugged": true
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e036f77f7d..9f952d2e24 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -472,8 +472,6 @@ importers:
specifier: 'catalog:'
version: 5.0.0(@types/node@26.4.1)(@vitest/coverage-v8@5.0.0)(vite@8.2.2(@types/node@26.4.1)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))
- apps/cli-go: {}
-
apps/docs:
dependencies:
fumadocs-core:
diff --git a/tools/release/local-release.ts b/tools/release/local-release.ts
index c2ae5891cf..3656c4b8ad 100644
--- a/tools/release/local-release.ts
+++ b/tools/release/local-release.ts
@@ -7,7 +7,6 @@
* pnpm cli-release [--version 0.0.0-local.1234567890]
*
* Requires `pnpm local-registry` to be running in another terminal.
- * Requires Go in PATH to build the `supabase-go` sidecar.
*/
import { $ } from "bun";
@@ -39,8 +38,6 @@ type PlatformInfo = {
bunTarget: string;
platformPkg: string;
ext: string;
- goos: string;
- goarch: string;
};
const PLATFORM_MAP: Record = {
@@ -48,43 +45,31 @@ const PLATFORM_MAP: Record = {
bunTarget: "bun-darwin-arm64",
platformPkg: "cli-darwin-arm64",
ext: "",
- goos: "darwin",
- goarch: "arm64",
},
"darwin-x64": {
bunTarget: "bun-darwin-x64",
platformPkg: "cli-darwin-x64",
ext: "",
- goos: "darwin",
- goarch: "amd64",
},
"linux-arm64": {
bunTarget: "bun-linux-arm64",
platformPkg: "cli-linux-arm64",
ext: "",
- goos: "linux",
- goarch: "arm64",
},
"linux-x64": {
bunTarget: "bun-linux-x64-baseline",
platformPkg: "cli-linux-x64",
ext: "",
- goos: "linux",
- goarch: "amd64",
},
"win32-x64": {
bunTarget: "bun-windows-x64-baseline",
platformPkg: "cli-windows-x64",
ext: ".exe",
- goos: "windows",
- goarch: "amd64",
},
"win32-arm64": {
bunTarget: "bun-windows-arm64",
platformPkg: "cli-windows-arm64",
ext: ".exe",
- goos: "windows",
- goarch: "arm64",
},
};
@@ -129,27 +114,6 @@ async function readToken(): Promise {
}
}
-async function checkGo(): Promise {
- try {
- await $`go version`.quiet();
- } catch {
- console.error("\nError: `go` not found in PATH.");
- console.error("Install Go from https://go.dev/dl/ to build the CLI.\n");
- process.exit(1);
- }
-}
-
-async function checkGoSource(): Promise {
- const goSource = path.join(root, "apps", "cli-go");
- const goMod = Bun.file(path.join(goSource, "go.mod"));
- if (!(await goMod.exists())) {
- console.error("\nError: Go CLI source not found at apps/cli-go");
- console.error("Run: pnpm repos:install\n");
- process.exit(1);
- }
- return goSource;
-}
-
async function main() {
const { values } = parseArgs({
options: {
@@ -163,9 +127,6 @@ async function main() {
const token = await readToken();
const platform = getPlatformInfo();
- await checkGo();
- const goSource = await checkGoSource();
-
if (process.platform === "linux") {
console.warn(
"Note: local-release builds the glibc variant only (cli-linux-*). " +
@@ -190,30 +151,16 @@ async function main() {
const bunBinary = path.join(tmpPlatformBinDir, `supabase${platform.ext}`);
const libc = libcForBunTarget(platform.bunTarget);
- console.log("[1/3] Compiling CLI binary...");
+ console.log("[1/2] Compiling CLI binary...");
await $`bun build ${entrypoint} --compile --target=${platform.bunTarget} --define=SUPABASE_LIBC=${JSON.stringify(libc)} --outfile=${bunBinary} ${oxfmtExternalArgs}`;
- {
- const goBinary = path.join(tmpPlatformBinDir, `supabase-go${platform.ext}`);
- console.log(`[2/3] Compiling Go CLI binary (${platform.goos}/${platform.goarch})...`);
- // go build must run from the Go source directory: passing an absolute path as a positional
- // arg makes Go resolve the module from CWD instead, which fails because the repo root has
- // no go.mod.
- await $`go build -trimpath -ldflags="-s -w" -o ${goBinary} .`.cwd(goSource).env({
- ...process.env,
- GOOS: platform.goos,
- GOARCH: platform.goarch,
- CGO_ENABLED: "0",
- });
- }
-
const tmpCliDir = path.join(tmpDir, "cli");
const tmpCliDistDir = path.join(tmpCliDir, "dist");
await mkdir(tmpCliDistDir, { recursive: true });
const shimSrc = path.join(root, "apps", "cli", "src", "shared", "cli", "bin.ts");
const shimOut = path.join(tmpCliDistDir, "supabase.js");
- console.log("[3/3] Building Node.js shim...");
+ console.log("[2/2] Building Node.js shim...");
await $`bun build ${shimSrc} --outfile=${shimOut} --target=node`;
const platformPkgJson = await Bun.file(
diff --git a/tools/release/release-notes-prompt.md b/tools/release/release-notes-prompt.md
index ba995dc2bf..5bcf2223cb 100644
--- a/tools/release/release-notes-prompt.md
+++ b/tools/release/release-notes-prompt.md
@@ -93,19 +93,10 @@ Earlier revisions carried an experimental `next/` (v3) shell and a `legacy/` wra
both are gone and `apps/cli/src/` is the single CLI tree. Never mention `next/`, v3, or a "legacy
shell" in release notes — describe every change as a change to the CLI.
-### Go → TypeScript port
-
-Ongoing port: `apps/cli-go/` → `apps/cli/src/`. Parity PRs are **not** features/fixes.
-
-- If leaf commands were ported: **one line** under **TypeScript port progress** — list leaf commands only (`db diff`, not `db`); behavior matches Go CLI; cite PRs. Omit section if none.
-- Port infra (services, tests, parity scripts) → tail count only.
-- Port PR that **also** fixes a real bug or adds a non-Go flag → promote that part to Bug fixes / New features; still list the command under port progress.
-
### Where user-visible changes usually live
-- `apps/cli/src/commands/**` — behavior, output, flags, errors (beyond pure porting)
+- `apps/cli/src/commands/**` — behavior, output, flags, errors
- `apps/cli/src/shared/**` — telemetry, global flags, output inherited by every command
-- `apps/cli-go/**` — while still the production binary
- `packages/cli-*`, `apps/cli/scripts/` — install/packaging (homebrew, scoop, build)
Everything else is usually internal.
@@ -181,11 +172,6 @@ From the header line extract `VERSION`, `COMPARE_URL`, `DATE`.
- . (#1234)
-### TypeScript port progress
-
-
-- **Now served by the TypeScript shell:** ``, ``. Behavior matches the Go CLI. (#1234)
-
---
Plus N internal improvements and dependency updates.
diff --git a/turbo.json b/turbo.json
index 3487f7723d..d39d865634 100644
--- a/turbo.json
+++ b/turbo.json
@@ -47,15 +47,9 @@
"cache": false,
"passThroughEnv": ["*"]
},
- "@supabase/cli-go#build": {
- "cache": true,
- "inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/mise.toml", "$TURBO_ROOT$/mise.lock"],
- "outputs": ["supabase-go"],
- "env": ["GO*", "CGO_*", "CC", "CXX"]
- },
"supabase#build": {
"cache": true,
- "dependsOn": ["@supabase/config#build", "@supabase/cli-go#build"],
+ "dependsOn": ["@supabase/config#build"],
"inputs": [
"$TURBO_DEFAULT$",
"$TURBO_ROOT$/.bun-version",