Powers /setup-gbrain --cleanup-orphans. list-orphans filters the
authenticated user's Supabase projects by name prefix (default
"gbrain") and excludes the project the local ~/.gbrain/config.json
currently points at, so only unclaimed gbrain-shaped projects come
back. Active-ref detection parses the pooler URL's user portion
(postgres.<ref>:<pw>@...).
delete-project is a thin DELETE /v1/projects/{ref} wrapper with no
confirmation of its own — the skill's UI layer owns the per-project
confirm AskUserQuestion loop. Keeps responsibilities clean: the bin
manages HTTP; the skill manages user intent.
Both subcommands reuse the existing api_call retry+backoff and the
same PAT discipline (env only, never argv).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four subcommands: list-orgs, create, wait, pooler-url. Built against
the verified Supabase Management API shape (Pre-Impl Gate 1):
- POST /v1/projects with {name, db_pass, organization_slug, region}
— not the original plan's /v1/organizations/{ref}/projects
- No `plan` field; subscription tier is org-level per the OpenAPI
description ("Subscription Plan is now set on organization level
and is ignored in this request")
- GET /v1/projects/{ref}/config/database/pooler for pooler config
— not /config/database
Secrets discipline: SUPABASE_ACCESS_TOKEN (PAT) and DB_PASS read from
env only, never from argv (D8 grep test enforces this). `set +x` at
the top as a defensive default so debug tracing never leaks secrets.
Management API hostname hardcoded to SUPABASE_API_BASE env override —
no user-controlled URL portion (SSRF guard).
HTTP error paths: 401/403 → exit 3 (auth), 402 → 4 (quota), 409 → 5
(conflict), 429 + 5xx → exponential-backoff retry up to 3 attempts,
then exit 8. Wait subcommand polls every 5s until ACTIVE_HEALTHY
with a configurable timeout; terminal states (INIT_FAILED, REMOVED,
etc.) exit 7 immediately with a clear message. Timeout emits the
--resume-provision hint so the skill can recover.
Pooler-url constructs the URL locally from db_user/host/port/name +
DB_PASS rather than trusting the API response's connection_string
field, which is templated with [PASSWORD] rather than the real value.
Handles both object and array response shapes, preferring session
pool_mode when Supabase returns multiple pooler configs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>