Skip to content

chore: production deploy - #6514

Open
supabase-cli-releaser[bot] wants to merge 117 commits into
mainfrom
develop
Open

supabase-cli-releaser[bot] wants to merge 117 commits into
mainfrom
develop

Conversation

@supabase-cli-releaser

Copy link
Copy Markdown
Contributor

Coly010 and others added 9 commits September 7, 2026 17:03
)

## What kind of change does this PR introduce?

Tooling/chore — adds commitlint, tied to a fixed scope list.

## What is the current behavior?

There is no commitlint or commitizen setup. PR titles must follow
conventional-commits format (checked in CI by
`amannn/action-semantic-pull-request`), but scopes are unrestricted free
text, enforced only by human review.

## What is the new behavior?

- Adds `commitlint.config.js` with a `scope-enum` rule: one scope per
real turbo/pnpm workspace project (`api`, `cli`, `cli-e2e`, `cli-go`,
`cli-test-helpers`, `config`, `docs`, `process-compose`, `stack` —
verified against `pnpm -r list`) plus escape scopes for changes that
don't map to a single project (`ci`, `repo`, `misc`, `release`). The 8
per-platform `packages/cli-{platform}` binary-wrapper packages are
folded into `cli`. `release` isn't a turbo project (`tools/release` has
no `package.json`) but is kept as an escape scope because
`propose-release-notes.ts` genuinely commits with that scope.
- Adds a local `commit-msg` git hook via husky that runs commitlint on
every commit. CI checkouts skip installing this hook (`HUSKY=0` in the
shared setup action) so bot-authored commits are never gated by it —
scope enforcement for those stays on the PR-title CI check.
- Mirrors the same scope list into the
`amannn/action-semantic-pull-request` step in `lint-pull-request.yml`,
so PR titles are held to the same list in CI.
- Updates `.github/dependabot.yml`: the `npm` and `docker` ecosystems
previously auto-generated scopes (`deps`/`deps-dev`/`docker`) that
aren't in the new fixed list, which would have started failing their own
PR-title check — both remapped to `misc`. The `gomod` ecosystem had no
`commit-message` config at all, so it fell back to a repository-detected
scope also outside the allowlist — mapped to `chore(cli-go): ` since
that's precisely the project those updates belong to. `github-actions`
(already `ci`) is untouched.
- Documents the local commit-msg hook in `CONTRIBUTING.md`, and adds one
clarifying sentence to `AGENTS.md` pointing at `commitlint.config.js` as
the source of truth for allowed scopes.

No commitizen/interactive prompt added — commitlint validates whatever
message is typed.
…2285) (#6497)

## Summary

An explicit `--workdir`/`SUPABASE_WORKDIR` could silently let
`loadCliConfig`/`findCliProjectRoot` climb ancestor directories to find
`supabase/config.{toml,json}` — so `--workdir ./sub` where
`sub/supabase/` doesn't exist could silently load, or **push**, an
unrelated parent project's config instead of failing. A defaulted
(unset) workdir still climbs exactly as before.

Linear:
[CLI-2285](https://linear.app/supabase/issue/CLI-2285/explicit-workdir-must-not-climb-to-a-parent-project-config-diffpush).

## What changed

- `LegacyCliSettings` gains `explicitWorkdir: boolean`; a new
`legacyShouldSearchAncestors(cliSettings)` helper
(`command-internal/legacy-workdir-search.ts`) gates the ancestor search
at every affected call site: `config diff/push/pull`, `gen types`, `seed
buckets`, `storage ls/mv/rm/cp`, `functions new`, `experimental
workers`, and `functions serve/deploy`.
- `packages/config`'s `findCliProjectRoot` gains an optional
`FindCliProjectPathsOptions` parameter (additive), matching
`findCliProjectPaths`'s existing `search: false` support.
- `config diff/push/pull`, `gen types`, `storage`, and `seed buckets`
now hard-fail with a clear error instead of silently falling back to
embedded defaults (or an unrelated ancestor's config) when an explicit
workdir has no project.
- The same commands now validate the workdir is an existing directory up
front (reusing the existing `start`/`stop`/`status` pattern), so a
typo'd path fails with "no such directory" instead of a confusing "file
not found".
- The missing-project message
(`command-internal/legacy-workdir-project.ts`) no longer suggests
`supabase init` for an explicit workdir — which could scaffold a fresh
config at the wrong path, leading to a subsequent `push` overwriting the
real project — and instead names the resolved path, suggesting an
ancestor's path when one genuinely has a project.
- `gen types` no longer leaks a raw `CliConfigParseError` tag as its
error message on a malformed config.
- `experimental workers new` gained the same workdir-existence guard
`functions new` already had, closing an identical
scaffold-at-a-nonexistent-path gap.

## Follow-ups filed separately (explicitly out of scope here)

- `secrets set` ignores `--workdir` entirely (loads from
`runtimeInfo.cwd`).
- Extending the explicit-workdir hard-fail policy to the
`db`/`migration` TOML-only loaders.
- `--debug` workdir logging, `--workdir` help-text tightening, and a
couple of smaller consistency nits (error-code unification across the
`config` family, `workers push`'s hardcoded error paths).
….4 in /apps/cli-go in the go-minor group across 1 directory (#6504)

Bumps the go-minor group with 1 update in the /apps/cli-go directory:
[github.com/posthog/posthog-go](https://github.com/posthog/posthog-go).

Updates `github.com/posthog/posthog-go` from 1.24.3 to 1.24.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/posthog/posthog-go/releases">github.com/posthog/posthog-go's
releases</a>.</em></p>
<blockquote>
<h2>1.24.4</h2>
<h2>Unreleased</h2>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/PostHog/posthog-go/blob/main/CHANGELOG.md">github.com/posthog/posthog-go's
changelog</a>.</em></p>
<blockquote>
<h2>1.24.4</h2>
<h3>Patch Changes</h3>
<ul>
<li>c3270b6: Align local feature flag property matching with the flags
service, including boolean-array precedence, canonical JSON
stringification, and operator-specific case folding.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/PostHog/posthog-go/commit/0216c2384b67ef39914e20fd0065c57243fb42d2"><code>0216c23</code></a>
chore: release v1.24.4 [version bump] [skip ci]</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/c3270b6bd8138865c0f0d0a57affaceb7a2bb6cb"><code>c3270b6</code></a>
fix(flags): align local exact matching with the flags service (<a
href="https://redirect.github.com/posthog/posthog-go/issues/300">#300</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/d5152ea6c4155c781cbdc0512eb99b60977fe90e"><code>d5152ea</code></a>
chore(deps): bump the github-actions group with 2 updates (<a
href="https://redirect.github.com/posthog/posthog-go/issues/304">#304</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/518931f315c1ff5bb2786d4b53b0c9fc316a1d1b"><code>518931f</code></a>
chore(deps-dev): bump <code>@​changesets/cli</code> from 3.0.0 to 3.0.1
in the release-tool...</li>
<li>See full diff in <a
href="https://github.com/posthog/posthog-go/compare/v1.24.3...v1.24.4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/posthog/posthog-go&package-manager=go_modules&previous-version=1.24.3&new-version=1.24.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…sumer (CLI-2339) (#6498)

## Summary

CLI-2320 confined
`auth.email.template.*.content_path`/`auth.email.notification.*.content_path`
resolution to the project root, but only inside `config push`'s own
content loader. This
centralizes that containment into the shared resolver
`legacyResolveEmailTemplateContentPath`
(`legacy-config-validate.ts`), so it now protects every consumer, with
no flag and no opt-out:
`config push`, `start` (an eager pre-Docker validation pass covering
every configured template
plus every enabled notification — the same set Kong's mount builder
consumes), and the shared
config-validation path reached by
`db`/`migration`/`status`/`stop`/`functions deploy`/`functions
serve`/`functions download`/`gen types`/`inspect`/`bootstrap`.

Linear: CLI-2339 (follow-up from CLI-2320's own PR review, #6489).

While extending the check's reach, two bugs surfaced and are fixed in
the same change:

- The canonicalization helper treated any `realpath` failure as "this
path doesn't exist yet" and
fell back to lexical resolution — which also covers a dangling symlink,
an `EACCES`-blocked
target, or a symlink loop, all of which exist on disk but couldn't be
canonicalized. That let an
in-root symlink pointing outside the project root bypass containment
silently, most seriously for
`start`'s Kong mount (a root-privileged, `rw` Docker bind mount). Fixed
by distinguishing
"genuinely absent" from "exists but uncanonicalizable" and following a
symlink to its real target
before checking it. The ancestor walk was also rewritten iteratively to
remove a stack-depth
  limit on deeply nested missing paths.
- `start`'s Kong mount resolved and validated a path early, then
independently re-derived and used
a second, unresolved path much later when building the Docker bind mount
— a check/use gap and
duplicated resolution logic. The validated, read-verified path is now
threaded straight through
  to the bind-mount builder instead of being re-derived.

The rejection message now includes the declared `content_path` value and
the project root (not the
fully symlink-dereferenced target, to avoid echoing back where an
escaping symlink actually
points).

## What changed

- `legacy-config-validate.ts` — `legacyResolveEmailTemplateContentPath`
now canonicalizes and
containment-checks its result before returning; new
`canonicalPathForContainment`/
  `canonicalizeExistingPath`/`isPathContainedInRoot` helpers.
- `push.auth-email-content.ts` — deleted its local, now-redundant
containment helpers; both
  template and notification loading route through the shared resolver.
- `start.handler.ts`/`kong.service.ts` —
`resolveKongEmailTemplateMounts` resolves, containment-
checks, and read-verifies every Kong-mounted template/notification once,
early, before any
Docker work; `LegacyKongEmailTemplateMount` carries the resolved path,
and
`legacyBuildKongEmailTemplateBind` is now a pure formatter with no
resolution logic of its own.
- `SIDE_EFFECTS.md` updates across `start`, `status`, `stop`, `db diff`,
`migration squash`,
`functions deploy/serve/download`, and one line in
`apps/cli/AGENTS.md`'s "config validation has
  one home" section.

Follow-ups filed for the adjacent untrusted-path fields this ticket
didn't touch (CLI-2344), and a
message-polish gap where an `EACCES` behind a followed symlink surfaces
a raw filesystem error
instead of the usual containment message (CLI-2345) — in both cases the
path is still rejected,
just with a less specific error.
## TL;DR

Adds live e2e coverage for `branches get`, `branches update` and
`branches disable`

## whats introduced?

- `branches get`: creates a branch, fetches it by name and asserts the
pretty connection table renders
- `branches update`: creates a branch, renames it with `--name --output
json`, asserts the confirmation and payload, then proves the new name
resolves through `branches get`
- `branches disable`: creates and deletes a branch so branching is
enabled with no preview branches left, disables preview branching for
the project and asserts the confirmation on stdout

## ref:

- closes: CLI-2327
- passed here: https://github.com/supabase/cli/actions/runs/34112181467
## TL;DR
fixes `supabase sso update --log-level error <id>` failing with 
`accepts 1 arg(s), received 2` by registering the built-in `--log-level`
as value taking in the raw argv scanners..

## whats biting the user?
`--log-level` shows up in every command's help and the parser accepts
it, but the raw argv scanners did not know it consumes a value
so `error` was counted as an extra positional and the command refused to
run. A typed `--log-level` also killed shell completion for the rest of
the line.

## now fixed by:
- registering `log-level` in `PERSISTENT_VALUE_FLAG_NAMES` and
`globalFlagsWithValues`, so positional counting consumes its value like
every other global
- registering the built-in flags where output format and shell
completion resolve, so `--version` output and tab completion keep
working around them

also added regression tests for the issue's exact spelling plus the
pre-path, inline, completion, and version spellings

## ref: 
- closes CLI-2329
- closes #6482
## Summary

Rewrites `@supabase/stack` around one managed-only runtime shared by
strict native and container execution modes. The package owns durable
configuration and secrets, sticky ports, artifact preparation, lifecycle
arbitration, per-service eager or lazy activation, service migrations,
ingress, retained and live logs, and exact resource cleanup.

A stopped stack has no resident supervisor or runtime resources: status
and retained logs come from durable state, while a later start creates a
fresh owner and performs clean recovery. PostgreSQL 17 is the only eager
service by default; other enabled services activate through stack
ingress, and callers can configure eager activation. Dependency-ready
workloads start concurrently. Docker-compatible engines, including
Podman, share the same container path.

Enabled lazy services prepare their artifacts in the background after
startup by default. `preparation: "on-demand"` retains full lazy
downloading, while explicit `prepare()` remains available in either
mode. Foreground activation prepares its dependency closure concurrently
and shares in-flight downloads with background preparation. All selected
workload downloads can run concurrently. Native archives are streamed to
disk while hashing, verified before extraction, and decompressed without
retaining whole archives in memory. Runtime cleanup cancels unfinished
transfers and retains completed cache entries. Status exposes artifact
preparation separately from service readiness, and explicit preparation
reports progress through `onProgress`.

Edge Functions are served through the stack-owned Edge Runtime for
package consumers. The package runs independently of the CLI and accepts
normalized `StackConfig` values without reading `config.toml`. All CLI
integration, including `supabase functions serve` and lifecycle commands
under `experimental start`, belongs to M5 in separate PRs. Existing CLI
Functions behavior is preserved. The deleted `next` CLI was a disposable
proving ground and is not part of this PR.

Service preparation now lives in the published runtime artifacts:
PostgreSQL owns first boot and bundled migrations, service helpers own
migration and Pooler tenant provisioning, and Node services expose
public launchers shared with their images. The stack supplies instance
settings and sequences those commands. Default images use the configured
slim-services tags or digests, including the artifacts from
[slim-services #299](supabase/slim-services#299)
and the BEAM versions republished after [slim-services
#302](supabase/slim-services#302). Native
downloads are checked against the checksum published with the same
release. BEAM launchers own the shared runtime defaults in native and
container modes; Vector configuration and Edge Functions bootstrap
remain stack-owned.

Unix control sockets bind inside owner-private directories. Container
mount paths preserve CSV special characters, and default state paths use
the user home directory when `HOME` is absent.

Obsolete process-compose integration and superseded runtime helpers are
removed.

Supersedes #6385
)

## TL;DR
adds live e2e coverage for `network-restrictions get` and `update`,
covering the command family

## whats introduced?
- `network-restrictions get`: reads the target project's restrictions
and proves the json payload carries `entitlement`, `config` and `status`
- `network-restrictions update`: captures the current allowlist,
replaces it with documentation ranges, proves the replacement in its own
output and through get, then restore
s...
## ref:
- closes: CLI-2288
- tested here: https://github.com/supabase/cli/actions/runs/33969368307
Bumps the actions-major group with 2 updates:
[docker/setup-qemu-action](https://github.com/docker/setup-qemu-action)
and
[linear/linear-release-action](https://github.com/linear/linear-release-action).

Updates `docker/setup-qemu-action` from 4.2.0 to 4.3.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-qemu-action/releases">docker/setup-qemu-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.3.0</h2>
<ul>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.92.0 to 0.96.0 in
<a
href="https://redirect.github.com/docker/setup-qemu-action/pull/336">docker/setup-qemu-action#336</a></li>
<li>Bump <code>@​sigstore/verify</code> from 3.1.0 to 3.1.1 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/316">docker/setup-qemu-action#316</a></li>
<li>Bump brace-expansion from 1.1.15 to 1.1.18 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/332">docker/setup-qemu-action#332</a></li>
<li>Bump js-yaml from 4.2.0 to 4.3.1 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/334">docker/setup-qemu-action#334</a></li>
<li>Bump postcss from 8.5.10 to 8.5.25 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/331">docker/setup-qemu-action#331</a></li>
<li>Bump sigstore from 4.1.0 to 4.1.1 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/317">docker/setup-qemu-action#317</a></li>
<li>Bump undici from 6.27.0 to 6.28.0 in <a
href="https://redirect.github.com/docker/setup-qemu-action/pull/333">docker/setup-qemu-action#333</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-qemu-action/compare/v4.2.0...v4.3.0">https://github.com/docker/setup-qemu-action/compare/v4.2.0...v4.3.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/1f40c72289eff860ee54a304f1438e3cff362e0a"><code>1f40c72</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/336">#336</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/932216e29e2417c3aa0bc5aec3c57089030cef2c"><code>932216e</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/a39e895360e601ae54e9ac97b8ea3b99e5f40491"><code>a39e895</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.92.0 to
0.96.0</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/a98ae9ffe777adf16ca44873bab9926427b262fa"><code>a98ae9f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/333">#333</a>
from docker/dependabot/npm_and_yarn/undici-6.28.0</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/8ebc9d118344dda0af3e25d2a7330010dd33e951"><code>8ebc9d1</code></a>
[dependabot skip] chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/c41e3fcbc0d6742101e0310c3b008ac3b16a9529"><code>c41e3fc</code></a>
build(deps): bump undici from 6.27.0 to 6.28.0</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/5fc60dfac60f723a3386e73530ff8067f2848f60"><code>5fc60df</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/332">#332</a>
from docker/dependabot/npm_and_yarn/brace-expansion-1...</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/a26e892bb646b50218299a9b391e7a4b0322d96a"><code>a26e892</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/328">#328</a>
from docker/dependabot/github_actions/actions/checkou...</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/aa6d04232374700651c6e7be400e859600041423"><code>aa6d042</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/324">#324</a>
from docker/dependabot/github_actions/actions/setup-n...</li>
<li><a
href="https://github.com/docker/setup-qemu-action/commit/d381ce5c16de15c000da8929fd1fc6e8fdef19e1"><code>d381ce5</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-qemu-action/issues/317">#317</a>
from docker/dependabot/npm_and_yarn/sigstore-4.1.1</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-qemu-action/compare/96fe6ef7f33517b61c61be40b68a1882f3264fb8...1f40c72289eff860ee54a304f1438e3cff362e0a">compare
view</a></li>
</ul>
</details>
<br />

Updates `linear/linear-release-action` from 0.17.1 to 0.17.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/linear/linear-release-action/releases">linear/linear-release-action's
releases</a>.</em></p>
<blockquote>
<h2>v0.17.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Release v0.17.2 by <a
href="https://github.com/axelniklasson"><code>@​axelniklasson</code></a>
in <a
href="https://redirect.github.com/linear/linear-release-action/pull/67">linear/linear-release-action#67</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/linear/linear-release-action/compare/v0.17.1...v0.17.2">https://github.com/linear/linear-release-action/compare/v0.17.1...v0.17.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/linear/linear-release-action/commit/53ad0f863963e7f8e270fba18426bbb55ef55384"><code>53ad0f8</code></a>
Release v0.17.2 (<a
href="https://redirect.github.com/linear/linear-release-action/issues/67">#67</a>)</li>
<li>See full diff in <a
href="https://github.com/linear/linear-release-action/compare/3f31fcf14c110cc53579fcc3575a26d469c413b4...53ad0f863963e7f8e270fba18426bbb55ef55384">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@supabase-cli-releaser
supabase-cli-releaser Bot requested a review from a team as a code owner September 8, 2026 02:24
@supabase-cli-releaser supabase-cli-releaser Bot added the do not merge Approve to apply; do not merge. label Sep 8, 2026
Comment thread packages/stack/src/gateway/gateway.integration.test.ts Dismissed
Comment thread packages/stack/src/runtime/native-runtime.integration.test.ts Dismissed
Coly010 and others added 18 commits September 8, 2026 11:59
…stat throws (CLI-2345) (#6518)

## What kind of change does this PR introduce?

Bug fix.

## What is the current behavior?

`canonicalizeExistingPath` in
`apps/cli/src/command-internal/legacy-config-validate.ts` follows an
in-root symlink one hop by hand (via `readlinkSync`) when `realpathSync`
fails, so a `content_path` containment check can catch a
dangling/looping/unsearchable-target symlink escaping the project root.
When the symlink's target sits one hop inside a directory that's
unsearchable (`EACCES`, e.g. `chmod 000`), the fallback `lstatSync(path,
{ throwIfNoEntry: false })` call itself throws — `throwIfNoEntry: false`
only suppresses `ENOENT`, not `EACCES` — and that throw was unguarded,
escaping as a raw filesystem `Error` instead of the polished
`LegacyConfigValidateError` ("resolves outside the project root") every
other containment-rejection case produces.

Not a security regression — the path was still rejected in every tested
environment — it was a message-polish gap.

Code review while fixing this surfaced the identical bug in
`legacyIsExistingFile` (the `"notification"` email-content section's
twin resolution path, via `statSync`), which had the same unguarded
`throwIfNoEntry: false` gap.

Fixes CLI-2345.

## What is the new behavior?

- `canonicalizeExistingPath`'s `lstatSync` fallback is now guarded: any
non-`ENOENT` throw there returns the path as-is (same fallback already
used for a non-symlink entry or too-deep symlink chain), so the caller's
containment check still runs and rejects normally.
- `legacyIsExistingFile` is guarded the same way: an unstattable dirent
is treated as present, so the declared path keeps winning over the
legacy `supabase/`-relative fallback and the real cause surfaces instead
of a raw fs error or a silent retarget.
- Updated the `canonicalizeExistingPath` JSDoc to accurately describe
what this guard does and doesn't guarantee (the lexical comparison isn't
fully fail-closed on its own; every caller's own read of the resolved
file's bytes is the actual backstop).
- Tightened the existing EACCES regression test to assert the specific
error/message, parametrized the three symlink-containment tests across
both `template`/`notification` sections, and added a permission-free
`ENAMETOOLONG` regression test so this code path stays covered in
environments where `chmod 000` isn't enforced (root, some containers,
Windows).
…he slim-services feed (#6521)

## Summary

Dependabot's docker updates on
`apps/cli-go/pkg/config/templates/Dockerfile` have been landing red —
see #6502 (realtime) and #6503 (postgres). Two independent causes, plus
the automation the second one leaves behind.

**1. A unit test asserted the exact current pins while reading them from
the live manifest.**

`slim-images.unit.test.ts` had a `maps current docker.io pins onto the
published slim tags` case that fed `dockerfileServiceImageRaw(alias)` in
and asserted a spelled-out version for `pg`, `supavisor`, `realtime`,
and `storage`. Any bump of those four failed the unit suite by
construction.

The assertions that must track the manifest — which slim repository each
alias maps to — already live in the `it.each` above and slice the tag
off before comparing, so they stay. Live-tag validation also survives
more strongly elsewhere: `start.slim-images.e2e.test.ts` translates the
current manifest pins and actually pulls them, so an unpublished
translated tag fails CI on the registry rather than on a hand-typed
string. The version-bearing block only encoded the per-service
tag-prefix scheme, so it is replaced with fixed pins covering the same
scheme, plus the uppercase-`V` normalization arm in `slimTagForService`
that had no coverage.

**2. `sync-stack-service-versions.yml` targeted files that no longer
exist.**

It ran `pnpm sync:versions` in `packages/stack` and committed
`packages/stack/src/ServiceCatalog.ts`. #6440 deleted both the script
and that file, so the workflow would have hard-failed on the next
dependabot Dockerfile PR. It survived #6502/#6503 only because those
were opened about two hours before #6440 merged.

**3. The stack's pins now ride the feed that can actually maintain
them.**

Deleting that workflow leaves `WorkloadCatalog.ts` —
`ServiceCatalog.ts`'s replacement — with no automation, so this adds it.
The catalog pins each workload to an exact slim-services artifact
release: a version **plus its `ghcr.io/supabase/cli` image digest**, per
ADR 0017, which makes the artifact release the boundary for service
startup defaults. Dependabot owns the Dockerfile and structurally cannot
own this table — it resolves registry tags and never produces a
`sha256:` digest, which is why repointing the old workflow was not an
option.

slim-services already sends this repo a `mirror-slim-image`
`repository_dispatch` per release carrying `service`/`version`/`digest`,
to drive the ECR mirror. `sync-stack-workload-catalog.yml` subscribes to
that same dispatch and opens a PR pinning the release. It is
deliberately a separate workflow from `mirror-slim-image.yml`: that
mirror runs against the sender's 15-minute verification poll, and a
catalog PR must never delay it or turn its run red.

## Reviewer notes

Only two source values change per release. `artifactFor` derives
`releaseTag`, `assetName`, and every download URL from `service` +
`version`, and `releases` is derived from `defaultVersion` plus the
container image, so rewriting the `native(...)` positional version and
image is the whole change.

**postgres is the one service carrying two supported release lines**
(17.x and 15.x via `additionalReleases`), so the plan picks its target
by release line — a 15.x release moves the additional entry and can
never overwrite the 17.x default. That is the main correctness risk here
and it has a dedicated test. A release on a line the catalog does not
carry, a service it does not model, and a re-dispatch of an
already-pinned release are all successful no-ops, so the sender's retry
path does not open duplicate PRs.

The dispatch payload arrives with whatever authority holds the dispatch
token, so `sync-workload-catalog.ts` revalidates
`service`/`version`/`digest` against the same patterns
`mirror-slim-image.yml` uses rather than trusting the workflow. Those
patterns are what stop a version or digest breaking out of the
TypeScript string literals it writes into.

`planCatalogUpdate` is pure and covered by 21 `bun:test` cases in
`.github/scripts/`, which `github-scripts-ci.yml` already tests and
type-checks. One of them sweeps every service the real catalog models,
so a newly modelled workload is covered without editing a fixture list.

`WorkloadCatalog.ts` also gains a provenance comment: it and the
Dockerfile list overlapping service versions and are meant to diverge,
so the next reader needs to know not to "reconcile" them.

## Linked issue

No Linear ticket — repository maintenance prompted by the two failing
dependabot PRs above.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01PWXmTVTiQCwuyjZ8Mfw9NL

---------

Co-authored-by: Claude <noreply@anthropic.com>
…#6519)

## Summary

The `Codegen` check fetched the live staging spec on every pull request
and diffed the result against the committed `pkg/api`. That conflated
two questions: whether the pull request left generated code
inconsistent, and whether staging had drifted ahead of the repository.
The second dominated, so a spec change turned every open pull request
touching `apps/cli-go` red at once — none of which the authors caused or
could fix — and it made all of those runs depend on staging being
reachable.

This pins the spec instead:

- `apps/cli-go/api/v1-openapi.yaml` is a committed snapshot of the
staging spec, and `go generate` reads it instead of
`https://api.supabase.green/api/v1-yaml`. The per-PR `Codegen` check is
now hermetic: it fails only when `pkg/api` no longer matches the
snapshot it was generated from, and it reproduces offline.
- The API Sync workflow becomes the sole reader of the live spec. It
refreshes the snapshot and regenerates the client together in one pull
request, so upstream drift produces that one pull request instead of a
failure on every open one. Its diff now shows the upstream API change
rather than only generated Go.
- Its change detection covers the snapshot as well as `pkg/api`, so an
upstream edit that codegen ignores (a description, an example) is
committed rather than refetched and discarded on every run.
- `api/README.md` is rewritten. It still documented the pre-URL
`beta.yaml` flow, and its links to the generated files were broken
relative paths.

This restores the model `packages/api` already uses, where `pnpm
generate` runs only in the sync workflow and per-PR drift is checked
against the committed `openapi.json`.

## Drift the snapshot exposed

Seeding the snapshot was expected to regenerate `pkg/api`
byte-identically. It did not: staging had drifted ahead of the committed
client, which is exactly the accumulation the old check could never
land. Two changes came in, and they are worth a look:

- `StorageConfigResponseOutput.MigrationVersion` is now
`nullable.Nullable[string]`. Assigning it to the `string` field
`storage.TargetMigration` no longer compiles, so
`FromRemoteStorageConfig` unwraps it with the same `Get()` guard
`FromRemoteAuthConfig` already uses. Behavior change worth noting: when
the platform omits the field, the local value is left untouched rather
than overwritten with `""`, consistent with the surrounding intent that
unset config should not change platform defaults.
- Several `UpdateCustomHostnameResponseOutput` result fields became
optional pointers. Nothing outside `pkg/api` consumes that type, so no
call sites needed changes.

## Generated-file marking

Committing a 468 KB spec snapshot raised the question of generated-file
marking, and `.gitattributes` carried no `linguist-*` entries at all, so
the repository's roughly 3.5 MB of generated output was skewing GitHub's
language statistics and expanding in diffs. All of it is now marked
`linguist-generated`: the Go client and spec snapshot,
`packages/api/src/generated/`, the docs config schemas, and the
lockfiles.

`turbo.json`'s `generate` outputs and the `go generate` directives are
the source of truth for that list, so only generated files are marked.
Hand-written codegen inputs (`pkg/api/*.cfg.yaml`, `api/overlay.yaml`)
are untouched, as are large but authored files such as the integration
test suites. The attribute is GitHub-only — git, CI, and local diffs
behave identically, and the files are collapsed behind a click rather
than hidden, so the sync PR's spec diff and lockfile changes remain
reviewable.

## Linked issue

N/A — CI reliability change, no linked issue.

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/).

## Reviewer notes

One open decision: the snapshot's file name. `v1-openapi.yaml` matches
the `/api/v1-yaml` endpoint; `beta.yaml` was the name before codegen
moved to the live URL, if continuity is preferred.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01TKDPB9bwSx5WM7juDAM7CT

---------

Co-authored-by: Claude <noreply@anthropic.com>
## Summary

#6465 removed the `next/` shell and #6486 flattened `legacy/` into
`src/`, but the two-shell world lived on in the names: every exported
symbol in the CLI tree still carried the mandatory
`Legacy`/`legacy`/`LEGACY` prefix, 368 files were named `legacy-*.ts`,
`apps/cli/AGENTS.md` still told agents the prefix was required, and the
harness, build, and release tooling still selected a "shell". This PR
removes the concept end to end so `src/` reads as the one CLI it is.

### The rename (`bad664be1`)

- ~3,050 identifiers lose the prefix (`LegacyBranchesCreateFlags` →
`BranchesCreateFlags`, `legacyRoot` → `rootCommand`, …), together with
their `Data.TaggedError` tags, `Effect.fn` span names
(`legacy.branches.create` → `branches.create`), and service tags
(`supabase/legacy/*` → `supabase/cli/*`).
- 368 files are renamed (`legacy-foo.ts` → `foo.ts`);
`src/shared/legacy/*` moves into `src/command-internal/`;
`tests/helpers/legacy-mocks.ts` becomes `command-mocks.ts` because
`mocks.ts` already existed.
- Where a CLI-tree service collides with a same-named `src/shared/`
service, the CLI-tree one is qualified with `Command` rather than
getting a new shell prefix: `CommandSettings` (was `LegacyCliSettings`),
`CommandCredentials`, `CommandPlatformApi`. AGENTS.md documents this and
marks the pairs as slated to consolidate. Other clash-driven names:
`withCommandTelemetry` (vs shared `withCommandInstrumentation`),
`AccessTokenRequiredError`, `ProjectRefNotLinkedError`,
`GoOutputFormat`.
- Wrappers and aliases that existed only to satisfy the prefix rule are
deleted instead of renamed (`functions serve` re-exports,
`usesSlimRuntime`, the `formatDebugId` alias).
- Three variable shadows the rename would have introduced silently
(`lang`, `globalFlagValues`, `resolved`) were caught with an oxlint
`no-shadow` before/after diff and renamed.

Genuine product concepts keep the word: `--legacy-bundle`, legacy API
keys and signing keys, the pre-profile keyring account fallback, the
pre-consent `telemetry.json` format, the migra "legacy engine" vs the
pg-delta "next" engine, and the pg-delta legacy-tree export.

### The rule and the framing (`442bc60b1`)

- `apps/cli/AGENTS.md`: the "Mandatory `Legacy`/`legacy` prefix on all
exports" section is replaced by a short "Naming" section; the header
note now says the prefix and both shell trees are gone; the `next/`
dual-write and "legacy-only" guidance is removed.
- README, CONTRIBUTING, the lint config comment, `packages/config/docs`,
`SIDE_EFFECTS.md` files and ~300 code comments drop "legacy
shell"/"legacy command" wording.

### The remaining shell plumbing (`994f75685`)

- Compiled binary is `dist/supabase` (was `dist/supabase-legacy`).
- `@supabase/cli-test-helpers`: `createHarness(options)` — the
`CLITarget`/`CLI_HARNESS_TARGET` axis (`ts-legacy`/`ts-next`) is gone
from the harness, `apps/cli-e2e`, `test.yml`, and the `live-e2e.yml`
matrix. The harness always uses the profile-file path, which is the one
the CLI actually reads.
- `runSupabase`/`spawnSupabase` drop the `entrypoint: "legacy"` option
(111 call sites).
- `scripts/build.ts` drops `--shell`; the `shell` input is removed from
`build-cli-artifacts`, `release-shared`, `release`,
`release-smoke-test`, and `publish-preview-cli-packages`, and the
artifact cache keys drop the shell segment on both the producer and
consumer side.
- `pnpm cli-release` drops `--legacy|--next`. It was also still
compiling `src/<shell>/main.ts`, a path that stopped existing in #6486,
so the local release ring works again.
- `pnpm dev:legacy` → `pnpm dev`, `pnpm build:legacy` → `pnpm
build:binary`.
- `docs/platform-command-generation.md` (a `next/`-only feature) is
deleted; the `next/`-only rows are dropped from `go-cli-divergences.md`;
"`undefined` in `next`"-style comments in `shared/` are reworded to
describe library callers.

## Reviewer notes

- **User-visible:** `--output-format json` error `code` values are the
tagged-error tags, so they lose the `Legacy` prefix (e.g.
`LegacyPlatformAuthRequiredError` → `AccessTokenRequiredError`). Span
names lose `legacy.` and service tags move, but neither leaves the
machine.
- The `Command*` qualifier for the three shared/CLI service pairs is the
one naming judgment call worth a look; each is a single-token rename if
a different name is preferred.
- `@supabase/cli-go#lint:check` fails on this branch exactly as it does
on `develop` under a current local golangci-lint (gosec G115/G118); no
Go source is touched here.
`supabase experimental stack start` creates or resumes a managed stack
for the current project and branch, with named-stack and explicit-ID
targeting, Docker/native selection, and eager activation or background
artifact preparation.

Translate project configuration at the CLI boundary and embed the
supervisor and native-process dispatch in the compiled binary. The stack
package owns lifecycle and persistent state, and resolves PostgreSQL
major versions through its release catalog.

---------

Co-authored-by: Colum Ferry <cferry09@gmail.com>
…plates with 5 updates (#6533)

Bumps the docker-minor group in /apps/cli-go/pkg/config/templates with 5
updates:

| Package | From | To |
| --- | --- | --- |
| supabase/studio | `2026.08.24-sha-8ec45b2` | `2026.09.07-sha-7996410`
|
| supabase/edge-runtime | `v1.74.3` | `v1.76.2` |
| supabase/realtime | `v2.130.0` | `v2.134.12` |
| supabase/storage-api | `v1.72.1` | `v1.74.1` |
| supabase/logflare | `1.50.6` | `1.50.11` |

Updates `supabase/studio` from 2026.08.24-sha-8ec45b2 to
2026.09.07-sha-7996410

Updates `supabase/edge-runtime` from v1.74.3 to v1.76.2

Updates `supabase/realtime` from v2.130.0 to v2.134.12

Updates `supabase/storage-api` from v1.72.1 to v1.74.1

Updates `supabase/logflare` from 1.50.6 to 1.50.11


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…dates (#6532)

Bumps the go-minor group with 2 updates in the /apps/cli-go directory:
[golang.org/x/mod](https://github.com/golang/mod) and
[golang.org/x/oauth2](https://github.com/golang/oauth2).
Bumps the go-minor group with 1 update in the /apps/cli-go/pkg
directory: [golang.org/x/mod](https://github.com/golang/mod).

Updates `golang.org/x/mod` from 0.40.0 to 0.41.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/mod/commit/d0a27b2d4a48460806692bf5c87fc157c3c65292"><code>d0a27b2</code></a>
modfile: fix Cleanup and DropTool documentation</li>
<li><a
href="https://github.com/golang/mod/commit/d12008c62d74c94d91b58e8bc6c3eb168eda8381"><code>d12008c</code></a>
all: upgrade go directive to at least 1.26.0 [generated]</li>
<li>See full diff in <a
href="https://github.com/golang/mod/compare/v0.40.0...v0.41.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/oauth2` from 0.36.0 to 0.37.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/oauth2/commit/c624b89dadc3221560b7345c090bbe69e90808ee"><code>c624b89</code></a>
google: change the snake case endpoint to kebab-case</li>
<li><a
href="https://github.com/golang/oauth2/commit/09a82f63d4c718720369edfee3c7d0ff953c0b6f"><code>09a82f6</code></a>
all: upgrade go directive to at least 1.26.0 [generated]</li>
<li>See full diff in <a
href="https://github.com/golang/oauth2/compare/v0.36.0...v0.37.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `golang.org/x/mod` from 0.40.0 to 0.41.0
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/golang/mod/commit/d0a27b2d4a48460806692bf5c87fc157c3c65292"><code>d0a27b2</code></a>
modfile: fix Cleanup and DropTool documentation</li>
<li><a
href="https://github.com/golang/mod/commit/d12008c62d74c94d91b58e8bc6c3eb168eda8381"><code>d12008c</code></a>
all: upgrade go directive to at least 1.26.0 [generated]</li>
<li>See full diff in <a
href="https://github.com/golang/mod/compare/v0.40.0...v0.41.0">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…pps/cli-go/pkg/config/templates (#6534)

Bumps supabase/postgres from 17.6.1.167 to 17.6.1.169.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=supabase/postgres&package-manager=docker&previous-version=17.6.1.167&new-version=17.6.1.169)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Port allocation could change an existing automatic assignment when an
earlier listener was enabled, or let a fresh candidate collide with an
exact or retained private assignment. Validate all retained and exact
claims first, then acquire public listeners and temporary private
reservations inside one registry transaction. Commit assignments once
acquisition succeeds and let scopes release unsuccessful attempts,
removing the probe/replan/rollback path.

Use a shared, randomized port pool with bounded retries for occupied or
inaccessible candidates. Allocate native listener resources separately
for each Effect evaluation, avoid duplicate internal API listeners when
a public wildcard already covers the address, and preflight only private
bindings still requested by the candidate plan. Document the reservation
guarantees and add a focused Bun CI matrix for macOS, Linux, and
Windows.
## TL;DR

fixes `supabase start` and `functions serve` dying since 2.116.0 with

```
failed to copy edge runtime main service into container: destination "supabase_edge_runtime_<id>:/" must be a directory
```

on projects whose functions import local workspace packages through
import map directory mappings

- the trigger is #6273 moving the bootstrap onto docker create + cp +
start: the daemon refuses to resolve the copy target when a file bind is
nested inside a read only parent bind
- the overlapping binds themselves are much older, the import walker
adds a file bind per imported module while import map target enumeration
adds the package directory that already contains them, harmless until a
cp step landed between create and start

so now the mount list is pruned before `docker create`, a bind is
dropped only when another bind of the same mode already supplies the
same content at the same container path, so the container sees the same
files at the same paths and the cp delivery from #6273 stays intact...

## ref:
- closes: supabase/supabase#50088
- extends: #6273

---------

Co-authored-by: Colum Ferry <cferry09@gmail.com>
Derive stack identity from the canonical project root, Git branch
context, and stack name.

Supported parallel-stack use cases:

- **A worktree per LLM chat session:** each distinct worktree directory
gets a separate stack, including worktrees on the same branch or
detached commit.
- **Branch-specific stacks in one clone:** switching from `main` to
`feat-a` selects a separate stack; switching back to `main` selects its
previous stack.
- **Multiple Supabase projects in a monorepo:** each project has its own
project-root directory and therefore its own stack.
- **Named stacks for one project:** different names create separate
stacks within the same project and branch context, for both Git and
non-Git projects.

Repeated calls with the same canonical project root, branch context, and
name select the same stack. An omitted name is `default`.

Remove the redundant repository and checkout identity fields, common Git
directory resolution, and ordinary-folder identity module. Moving a
project selects a new stack. The unreleased private state uses the new
hash directly without migration or legacy-hash support.
<!--
Before opening this PR, confirm the linked issue is open and carries the
`open-for-contribution` label. PRs from external contributors that don't
follow
the workflow in CONTRIBUTING.md are closed automatically.
@supabase members working from Linear tickets are exempt.
-->

## Summary

pnpm/pnpm#14557 is resolved so we no longer
need the workaround in `.gitattributes` that i added in
#6461 (but I kept it just in case
and updated the comment accordingly). this pnpm bump should also speed
up dependency resolution/installation.
…el (#6524)

<!--
Before opening this PR, confirm the linked issue is open and carries the
`open-for-contribution` label. PRs from external contributors that don't
follow
the workflow in CONTRIBUTING.md are closed automatically.
@supabase members working from Linear tickets are exempt.
-->

## Summary

- Gate `pkg.pr.new` preview CLI package publishes behind the
`run-preview-packages` label (re-publish on push while labeled; remove
label to cancel).
- Stop publishing on every ready `develop` PR and remove preview from
the `run-ci` suite so large binaries are only uploaded when someone
needs a shareable install.
- Document the opt-in in `MAINTAINERS.md` and sync related workflow
comments.

## Linked issue

No linked GitHub issue (maintainer follow-up from Slack).

- [x] The linked issue is **open** and carries the
`open-for-contribution` label (or I'm a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Tests added or updated for the change.
- [x] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).
## What kind of change does this PR introduce?

CI reliability fix.

## What is the current behavior?

AI Review's Codex jobs (`codex-review`, `adjudicate`) intermittently
hang and get killed on job timeout, discarding a completed review. Most
recently: [run
34323125644](https://github.com/supabase/cli/actions/runs/34323125644)
on #6535 died at ~55 minutes against a 45-minute timeout.

This is a regression. #6380 deliberately pinned `openai/codex-action` to
v1.11 because v1.12 had a confirmed hang bug (openai/codex-action#150).
#6484 — a Dependabot `actions-major` group bump bundling 6 unrelated
action updates — silently reverted that pin back to v1.12; the
workflow's own comments (still saying "pinned to v1.11, NOT v1.12") went
stale rather than catching the drift, since nothing diffed them against
the actual `uses:` line.

Checking upstream today turned up two separate, still-open v1.12
regressions, both matching this workflow's exact config
(`safety-strategy: drop-sudo`, `sandbox: read-only`,
`output-schema-file`):
- openai/codex-action#151 — the v1.12 wrapper waits on the child
process's `close` event with inherited stdio; a lingering descendant
keeps the step alive forever after Codex has already written its output
and finished.
- openai/codex-action#160 — v1.12's `drop-sudo` rewrite chmods
root-owned `/run` service sockets, breaking `systemd-resolved` on the
GitHub-hosted runner itself, which kills the job 52-65 minutes in
regardless of the job's own timeout — matching our job's 55-minute death
exactly.

Neither has a released fix. Both are action-level bugs independent of
the pinned Codex CLI version (reproduced across CLI versions
0.147.0-0.150.1 in the upstream threads). This is not a diff-size or
token-limit problem: #6535's diff was only ~2200 lines, and v1.11 has
cleanly handled 130k-270k-token diffs in under 15 minutes per the
upstream reports and our own prior testing.

## What is the new behavior?

- Re-pin `openai/codex-action` to v1.11
(`52fe01ec70a42f454c9d2ebd47598f9fd6893d56`) in both Codex jobs —
verified it's a safe drop-in, since v1.11's `action.yml` supports every
input this workflow uses.
- Refresh the stale inline comments to cite the actual issues (#151,
#160) instead of just the original #150.
- Add `openai/codex-action` to `.github/dependabot.yml`'s `ignore` list
(no `update-types` restriction, so it blocks all automated bumps) so a
grouped bump can't silently regress this pin again. Any future bump now
requires a deliberate PR that checks the upstream changelog/issue
tracker first.
….1 in /apps/cli-go in the go-minor group across 1 directory (#6539)

Bumps the go-minor group with 1 update in the /apps/cli-go directory:
[github.com/posthog/posthog-go](https://github.com/posthog/posthog-go).

Updates `github.com/posthog/posthog-go` from 1.24.4 to 1.25.1
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/posthog/posthog-go/releases">github.com/posthog/posthog-go's
releases</a>.</em></p>
<blockquote>
<h2>1.25.1</h2>
<h2>Unreleased</h2>
<h2>1.25.0</h2>
<h2>Unreleased</h2>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/PostHog/posthog-go/blob/main/CHANGELOG.md">github.com/posthog/posthog-go's
changelog</a>.</em></p>
<blockquote>
<h2>1.25.1</h2>
<h3>Patch Changes</h3>
<ul>
<li>c159621: Fix <code>not_regex</code> local flag evaluation erroring
on non-string/int property values. The <code>not_regex</code> operator
used a manual string/int type switch and returned an error for other
types, most notably <code>float64</code>, which is what JSON numbers
deserialize to, so it failed on a numeric property value even though
<code>regex</code> handled it. <code>not_regex</code> now coerces both
sides with <code>valueToString</code>, mirroring <code>regex</code>. An
explicit <code>nil</code> property value is represented as
<code>null</code>, matching the feature flags evaluation service rather
than Go's default <code>&lt;nil&gt;</code> representation.</li>
</ul>
<h2>1.25.0</h2>
<h3>Minor Changes</h3>
<ul>
<li>897a0b4: Add the OpenTelemetry bridge for AI observability as an
independently installable nested Go module.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/PostHog/posthog-go/commit/a5e539c68b8471a86dd746a4bff64601340f4e9f"><code>a5e539c</code></a>
chore: release v1.25.1 [version bump] [skip ci]</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/c1596215af2b186a870871e2d169b198851ed150"><code>c159621</code></a>
fix: not_regex should handle all value types like regex (<a
href="https://redirect.github.com/posthog/posthog-go/issues/305">#305</a>)</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/50569874ea80f8f28f3318962668218d34eb9a64"><code>5056987</code></a>
chore: release v1.25.0 [version bump] [skip ci]</li>
<li><a
href="https://github.com/PostHog/posthog-go/commit/897a0b4e5f2e9b49bc58b4ace7d5080502525b18"><code>897a0b4</code></a>
feat: add OpenTelemetry bridge for AI observability (<a
href="https://redirect.github.com/posthog/posthog-go/issues/306">#306</a>)</li>
<li>See full diff in <a
href="https://github.com/posthog/posthog-go/compare/v1.24.4...v1.25.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/posthog/posthog-go&package-manager=go_modules&previous-version=1.24.4&new-version=1.25.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
`supabase experimental stack stop` stops the current or named managed
stack, or an explicit stack ID, while preserving its identity and data.
Selection works without loading project configuration, including when
the config file has been removed or changed.

Use the stack package’s lifecycle API and report whether a stack was
found in both human and structured output. This PR builds on the
experimental stack start integration.
## What kind of change does this PR introduce?

CI reliability fix (follow-up to #6538).

## What is the current behavior?

#6538 re-pinned `openai/codex-action` to v1.11 and added a Dependabot
ignore entry scoped to `versions: ["1.12.x"]`, intending to still let
Dependabot propose v1.13+ once the upstream hang bugs
(openai/codex-action#151, #160) are fixed, while blocking the known-bad
v1.12 line specifically.

That scoping never actually worked. 9 minutes after #6538 merged,
Dependabot opened #6541 proposing the exact v1.12 bump we were trying to
block — config propagation wasn't the issue; the `versions` syntax was.
The `github-actions` ecosystem's `ignore.versions` strings are parsed as
Ruby `Gem::Requirement` (RubyGems comparator syntax: `>= x`, `~> x`,
etc.), not npm-style semver ranges. `"1.12.x"` isn't a wildcard in that
grammar — it parses as a literal version string with an implicit `=`
operator, which never equals the real dependency version (`"1.12"`), so
the ignore condition silently never matched anything.

Verified directly against the actual parsing logic dependabot-core uses
(`Dependabot::GithubActions::Requirement`, a thin wrapper around
`Gem::Requirement`):
```
GithubActionsRequirement.new("1.12.x").satisfied_by?(Gem::Version.new("1.12"))   # => false (bug)
GithubActionsRequirement.new(">= 1.12, < 1.13").satisfied_by?(Gem::Version.new("1.12"))    # => true
GithubActionsRequirement.new(">= 1.12, < 1.13").satisfied_by?(Gem::Version.new("1.12.5"))  # => true
GithubActionsRequirement.new(">= 1.12, < 1.13").satisfied_by?(Gem::Version.new("1.11"))    # => false
GithubActionsRequirement.new(">= 1.12, < 1.13").satisfied_by?(Gem::Version.new("1.13"))    # => false
```

## What is the new behavior?

Replace `versions: ["1.12.x"]` with `versions: [">= 1.12, < 1.13"]` — a
real Gem::Requirement comparator range, confirmed to correctly match the
1.12 line (including any 1.12.x patch) while excluding v1.11 and v1.13+.
#6541 should be closed as superseded once this merges.
…/cli-go/pkg/config/templates in the docker-minor group (#6545)

Bumps the docker-minor group in /apps/cli-go/pkg/config/templates with 1
update: supabase/storage-api.

Updates `supabase/storage-api` from v1.74.1 to v1.74.3


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=supabase/storage-api&package-manager=docker&previous-version=v1.74.1&new-version=v1.74.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
jgoux and others added 8 commits September 16, 2026 07:36
Tracing currently writes files synchronously when a span ends, while
telemetry setup reads environment variables and generates identifiers
outside Effect services.

Use a scoped queue worker to export spans sequentially and drain pending
exports during shutdown, including command failure and interruption,
with a two-second deadline for stalled exporters. Filesystem writes,
retention timestamps, encoding, environment signals, and session
identifiers now use Effect services and schemas. Debug output and file
export keep independent best-effort failure handling, and analytics
destinations continue to come from ambient configuration.

Based on #6634.
The CLI and stack Functions bootstraps read environment values directly
and mix Promise control flow with Effect execution, hiding worker
failures and cancellation boundaries.

Load bootstrap configuration through an explicit Effect configuration
provider, decode function and signing-key documents with schemas, and
use `Option` for optional authentication results. Wrap foreign worker
and JWT operations at their leaves, with one Promise boundary per HTTP
request so cancellation stops subsequent work without reporting client
disconnects as internal failures, and worker failures retain their
existing HTTP responses.

Preserve the CLI’s required configuration, the stack’s lenient defaults,
live environment forwarding to each worker, request bodies and headers,
and local-versus-remote signing-key behavior.

Pass the embedded Functions bundle directly to Bun’s build API in local
and release builds, avoiding Linux’s command-line argument size limit
while preserving compilation targets and build constants.
## TL;DR

fixes the stale claim that `db reset` bucket seeding takes confirmation
defaults silently,
which was caused by the call site comment and
`SIDE_EFFECTS.md` never describing the real print and scan contract and
is now fixed by correcting both and pinning the behavior with four
integration tests covering the overwrite and prune defaults, the
`SUPABASE_YES` dotenv path, and the piped answer path...

## ref:
- closes: #6607
CLI-2436, CLI-2437) (#6625)

## TL;DR

brings the `postgres-config` and `projects` command families under the
effect lint

## whats introduced?

effect lint applied to `postgres-config` and `projects`:

- one allow list entry per family in `.oxlintrc.effect.json`
- api payloads decoded through schemas instead of raw `JSON.parse`,
cause assertions moved to `Cause.pretty`
- the experimental gate tests ask the error type directly instead of
scanning serialized output
- async tests moved onto `it.live` with the `FileSystem`/`Path` services
- live test promise helpers wrapped once at the leaf into typed errors

## ref:

- closes: CLI-2436 & CLI-2437
…LI-2440) (#6629)

## TL;DR

brings the `secrets` and `pull` command families under the effect lint

## whats introduced?

effect lint applied to `secrets` and `pull`:

- one allow list entry per family in `.oxlintrc.effect.json`
- json envelope pins decoded through module level schema codecs, cause
assertions moved to `Cause.pretty` or the error type directly
- the sequential catch chain in `secrets set` folded into one
`catchTags`, and decode calls narrowed to the typed variants
- `pull` drops `node:path` for the `Path` service and its layer coverage
check now derives the error and service types from the layer itself
- pull integration fixture seeding moved onto the `FileSystem`/`Path`
services inside the effect, e2e and live tests run through the effect
native harness

## ref:

- closes: CLI-2438 & CLI-2440
Project environment files currently affect image resolution by
temporarily copying registry settings into the process environment.
Concurrent commands can observe those temporary values, and
configuration reads bypass the supplied Effect provider.

Resolve registry settings through Effect Config and pass each project's
environment to its Docker consumers explicitly. Keep ambient values
ahead of dotenv files, preserve empty overrides and registry fallback
order, and report configuration failures separately from image
inspection failures.

Local type generation continues honoring project-only slim-image
settings and forwarding its project environment to container
subprocesses, with the existing database-password exclusion. Other
commands use the project map for registry selection without forwarding
unrelated project variables to Docker. Remove the temporary environment
installer and its callers.

Map registry configuration failures to Docker domain errors, keep
configuration failures ahead of pull failures in aggregate diagnostics,
and skip shadow caching when job image settings cannot be resolved.

Based on #6637.
## TL;DR

brings the `supabase bootstrap` command family under the effect lint

## whats introduced?

effect lint applied to `bootstrap`:

- one allow list entry in `.oxlintrc.effect.json`
- the ambient `SUPABASE_DB_PASSWORD` and `GITHUB_TOKEN` reads move onto
`CommandSettings` as redacted optional fields, and the raw
`SUPABASE_WORKDIR` value rides along verbatim, all captured the same way
as the access token
- the `.env.example` parse failure becomes a typed error with its
telemetry tag registered
- the samples listing decodes through a schema codec
- integration tests pin the settings sourced create password and the env
configured workdir

## ref:

- closes: CLI-2439
)

## Summary

When `[experimental].stack` / `SUPABASE_EXPERIMENTAL_STACK=1` is on:

- **`supabase stack` is gated on the flag**, including help and
completion. Top-level `start`/`stop`/`status` become stack aliases.
Invalid project config leaves the feature off; invalid env overrides are
still errors. Flag off keeps legacy Compose start/stop/status and Docker
SQL-template shadows.
- **`--local` uses the project stack.** `db`, `migration`, `test db`,
`gen types`, and `inspect` resolve `--local` through stack credentials
instead of Compose names (`supabase_db_*`, `db:5432`). `gen types
--local` and `inspect db … --local` do not start a stack. Linked and
explicit `--db-url` stay URL / Management API targets for engine and
runtime selection (`connType`). A `--db-url` that matches `config.toml`
host and port is still `isLocal` for dump's tool-container host rewrite.
Functions and storage stay on their existing backends. Top-level `pull`
uses the same stack shadow as `db pull`.
- **Schema tooling uses `EphemeralPostgres`.** `db diff`, `db pull`,
declarative generate/sync, and `migration squash` provision throwaway
shadows through `@supabase/stack`. The cluster is a scoped second
instance (native host PGDATA or a named volume). Snapshots are
runtime-kind specific (`stack-shadow-baseline-*.tar`, same keep-3 /
2-day TTL as the legacy namespace). The runtime marker carries
`snapshotKey` on the CLI cache path; a keyless marker is rejected when a
key is expected. Archive flags are portable (GNU tar and Darwin bsdtar).
Ephemeral env files are `0600`; the cache dir is `0700`. Working state
is `$SUPABASE_HOME/managed/ephemeral-postgres/<identity>/`.
- **The stack backend requires in-process pg-delta.** `--use-migra`,
`--use-pgadmin`, `--use-pg-schema`, and `db pull --diff-engine migra`
are rejected for every stack runtime because the shadow is always
`EphemeralPostgres`, including `--linked` / `--db-url`.
- **Live start is Compose-faithful.** First create (`unconfigured`):
schema init, overlay (webhooks, grants, vault, `roles.sql`), then
migrate-and-seed. Existing cluster: webhooks only — no second overlay or
migrate-and-seed. A failed first setup leaves the engine up and does not
retry on the next start; recover with `db reset`. Disabled capabilities
keep nested pins (`version`, settings).
- **`db start` is postgres-only on first create.** Ingress follows
listener intents, so a database-only plan does not require API-key
material. An existing stack resumes its persisted services. `supabase
start` while that postgres-only stack is running stops it and starts the
full configured stack, keeping data. `--from-backup` is unsupported. `db
reset --local` and declarative `--apply` wipe through `resetDatabase` (a
failed wipe stays start-eligible), then migrate or seed on stack
credentials. Bucket seed talks to the stack API endpoint and waits only
while storage is enabled and bouncing.
- **Native tool clients.** `db dump --local`, `db test` / `test db`, and
`migration squash` use PATH `pg_dump` / `pg_prove` on native engines
(must match the stack Postgres major). Docker/Podman keeps the one-shot
tool container against published credentials, never `PGHOST=db`. On
Linux, omit / empty / `host` `--network-id` keeps loopback instead of
rewriting to `host.docker.internal`.
- **Native second stack.** Realtime `rpc` / `GEN_RPC_*` binds a unique
host port on native runtimes only. Docker publications omit `rpc`.
- **Catalog overlay for shadows and first create.** Local first-create
and shadow Postgres get the auth, storage, and realtime schema Compose
would after migrate, without starting those services. `--exclude` does
not skip that catalog set. Docker catalog SQL matches Compose; native
schema-init is migrate-only (Realtime `bin/prepare` omits
`SEED_SELF_HOST`).
- **Shadow cache / teardown.** Keys resolve the same default runtime as
create (Docker if installed). Remotes `*EnabledForSetup` overlay onto
ephemeral catalog config so `db pull` does not schema-init services
remotes turned off. Interrupted Postgres is torn down with the start
fiber; in-flight Docker/Podman network, volume, and container identities
are registered so Ctrl-C cannot orphan them. Native spawn drains pipes.

Docs: [ADR
0025](docs/adr/0025-ephemeral-postgres-for-schema-tooling.md),
[stack-commands](apps/cli/docs/stack-commands.md), and the
`SIDE_EFFECTS.md` pages for the switched commands (including
`$SUPABASE_HOME/managed/ephemeral-postgres/<identity>/`).
jgoux and others added 21 commits September 16, 2026 11:14
Supervisor lifecycle decisions were spread across orchestration and
settlement helpers, making ownership and completion ordering difficult
to follow. Consolidate command admission, workload claims, startup
outcomes, cleanup, traffic leases, and idle retirement into local pure
transitions, with one ordered path for committing state, reconciling
timers, and notifying callers.

Keep resource operations in Effect orchestration, share the active
lifecycle projection, and replace the separate settlement module and
cleanup fallback with owner-fenced transitions and local cleanup
ownership. Register activation settlement before restoring interruption
after workload claims, and settle lifecycle outcomes before releasing
execution permits. Preserve closed-owner recovery, existing diagnostics,
and saved-state behavior.

Follow-up to #6613.
## What kind of change does this PR introduce?

Chore — no shipped-behavior change.

## What is the current behavior?

The CLI's local-dev service image versions (`postgres`, `kong`,
`gotrue`, …) are defined in a
Dockerfile that lives inside `apps/cli-go/pkg/config/templates/`, and
are parsed into the TS CLI
via a text import that reaches into the Go tree. Several TS tests also
read Go source files
(`apps/cli-go/pkg/api/types.gen.go`, `pkg/migration/scripts/*.sh`,
`internal/db/diff/templates/`,
`pkg/config/templates/config.toml`) as drift/parity fixtures.

This is prep for CLI-2432 (removing the residual Go delegation and
eventually deleting
`apps/cli-go/` entirely) — those TS-side dependencies on the Go tree
have to move first so the
tree can be deleted later without breaking anything.

## What is the new behavior?

- The service-image Dockerfile now lives at
`apps/cli/src/shared/services/Dockerfile`, owned by
the TS CLI. `apps/cli-go/` keeps its own byte-identical copy for now (it
has a `go:embed`
dependency on it), until it's deleted in a follow-up PR. Dependabot,
CODEOWNERS, and the image
  mirror workflow are repointed at the new path.
- The Go-struct output drift test now compares the `*.go-payload.ts`
specs against the published
OpenAPI schema (`packages/api/src/generated/openapi.json`) instead of
parsing a Go struct
  directly — same guarantee, no Go source dependency.
- Two tests that byte-compared embedded scripts/templates against Go
source files now assert only
the behavior that isn't Go-tree-dependent; a third (init scaffold
parity) got its Go fixture
vendored into the test's own `testdata/` directory instead of reading it
live from `apps/cli-go/`.
- Removed the meta-test that guarded "some TS file still references
`apps/cli-go` via `new URL(...)`" — it would fail now that this PR
removes the last one.

Part of CLI-2432

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…cket seeding (CLI-2369) (#6633)

## What kind of change does this PR introduce?

Feature (M5 stack integration). Closes CLI-2369. Builds on #6540 (now
merged into `develop`), which provides `StackBackendContext`, `StackApi`
and `stack-local-database.ts`.

## What is the current behavior?

With the stack backend selected (`[experimental] stack = true` /
`SUPABASE_EXPERIMENTAL_STACK=1`), `storage ls/cp/mv/rm --local` and
`seed buckets --local` still derive a legacy Kong URL from `[api] port`
/ `SUPABASE_API_*` / the Docker hostname and mint a service-role JWT
from `auth.jwt_secret`, so they miss the managed stack entirely. `db
reset --local`'s stack path gated bucket seeding on Storage being
`ready`, but Storage is lazy (`dormant`) by default, so buckets were
never seeded. `stack start` never seeded `[storage.buckets]`.

## What is the new behavior?

- `storage` and `seed` now consult the stack feature flag
(`STACK_BACKEND_COMMANDS`).
- New `command-internal/stack-storage.ts`: resolves the Storage REST
endpoint from the stack's `status.endpoints.api.url` and authenticates
with `credentials.api.serviceRoleJwt`. `resolveStorageCredentials`
branches to it after the linked block; the legacy inputs (`[api]`,
`SUPABASE_API_*`, `SUPABASE_AUTH_JWT_SECRET`,
`SUPABASE_SERVICES_HOSTNAME`, Kong CA) are never read on the stack path
and there is no legacy fallback.
- Capability policy via one exhaustive classifier: `disabled` →
`StackStorageCapabilityError` with config/`-x storage` guidance;
`failed`/`stopped` → same class with the (sanitized) capability error;
`dormant`/`starting`/`ready`/`stopping` → proceed, the stack HTTP
gateway activates Storage on the first request and wakes a stopping one
once its cleanup completes. Not running / not registered / missing
endpoint or credentials → `StackStorageUnavailableError` with
lifecycle-aware suggestions. No HTTP request is sent before these checks
pass. Stack-gateway 502/503 during activation is remapped to guidance
for **local** targets only; `--linked` errors are untouched.
- `seed buckets`: skips legacy-only config validation on the stack path;
gained `credentials`/`workdir` options for callers holding an open stack
handle.
- `db reset --local` (stack): seeds on `ready|dormant|starting|stopping`
(30s `starting` poll removed), uses the shared resolver instead of a
synthesized legacy config, and warns-and-skips on any Storage problem
(the DB is already rebuilt).
- `stack start` / top-level `start` under the flag: seeds
`[storage.buckets]` on the stack's first configured start
(`desiredLifecycle` unconfigured, incl. after `stack prepare`), never on
resume. Capability problems warn; genuine seeding failures fail with
`reason: "seed"` and leave the stack running. Start gets its own runtime
layer (`HttpClient`, deferred platform API factory) so sibling `stack`
subcommands are unaffected.
- Effect lint covers `stack-storage.ts`; two new telemetry error tags;
SIDE_EFFECTS.md for storage ls/cp/mv/rm, seed buckets, db reset, stack
start and `docs/stack-commands.md` updated.

### Tests
`tests/helpers/storage.ts` gained a fake `StackApi`/backend option.
Scenario coverage: endpoint + JWT headers; negative proof that `[api]
port` and every legacy env override are ignored;
disabled/stopped/missing/unavailable errors with zero requests; dormant
proceeds; 503 remap local-only; linked path unchanged; legacy default
unchanged; seed buckets create+upload and validate-only skip; reset
dormant/starting/stopping/ready seeding and warn-and-skip; stack start
first-start vs resume, disabled/failed/503 warnings, `reason: "seed"`
without stop/destroy.

### Live dogfood (macOS, native runtime)
- `start -x realtime,functions,studio,mail,analytics,pooler` → `Creating
Storage bucket: assets` / upload while Storage was `dormant` (gateway
lazy activation); API endpoint on a dynamic port (e.g.
`http://127.0.0.1:30047`).
- `seed buckets --local`, `storage ls/cp/mv/rm --local` → all against
the stack gateway (`--debug` shows `HTTP GET:
http://127.0.0.1:30047/storage/v1/bucket`), confirm prompt on `rm`
intact.
- `storage cp` an extra object → `stop` → `start` → no re-seeding, extra
object preserved; `db reset --local` → bucket re-created and re-seeded.
- Sibling project: its own stack on another port, `storage ls --local` →
empty (isolated).
- `stop` → `storage ls --local` → `StackStorageUnavailableError: The
stack is stopped, not running.` Suggestion: `Run supabase start.`
- `start -x storage,...` → `storage ls --local` / `seed buckets --local`
→ `StackStorageCapabilityError: Storage is disabled for this stack.`
with the `[storage] enabled = true` / `stack restart` suggestion, zero
requests.
- `SUPABASE_EXPERIMENTAL_STACK=0 storage ls --local` → legacy path
unchanged.

### Review adjudication (engineer, security, DX passes)
Fixed in this PR: seeding gate (`created` → `firstCreate`; the old gate
re-seeded and auto-pruned on every start), guidance remap scoped to
local targets, single `Match` classifier,
`stackStorageEndpointFor(stack, status)` (no post-start re-read race),
`capability.error` sanitized, reset warn-and-skip for all storage errors
+ `resolvedConfig`/`projectEnvValues` threaded, `workdir` override
disables ancestor search, messages/suggestions rewritten
(lifecycle-aware, plain sentences), comment trims, `cause` kept on the
remapped error.
Deliberately not changed: `StackApi` stays a `serviceOption` read so
`resolveStorageCredentials`'s `R` is unchanged (a compile-time
requirement would ripple into every storage test layer); no loopback
assertion on `endpoints.api.url` (the listener address is user
configuration and the legacy path has no such check); `storage` with
neither `--local` nor `--linked` still targets the linked project
(inherited Go surface, flagged for a separate decision); `stack start`
fails on genuine seeding errors while `db reset` only warns (documented
policy split).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
## TL;DR

fixes three e2e flakes. 
Branch tests read a branch right after create or rename and could still
get a 404, and the sweep counted a refused delete as a leak when the
suite had already removed the project, so both now wait for the platform
state they depend on.
The serve runtime template test burned its whole 60s budget on a bare
TimeoutError when the edge runtime container died mid cold start, so it
now bounds each attempt, stops once a container exits, and reports the
exit state with the logs..

## ref:
- spotted in: https://github.com/supabase/cli/actions/runs/34784903225
- spotted in:
https://github.com/supabase/cli/actions/runs/35075923071/job/104728197989
- passing now: https://github.com/supabase/cli/actions/runs/35069640723
## TL;DR

brings the `supabase stop` command family under the effect lint

## whats introduced?

effect lint applied to `stop`:

- one allow list entry in `.oxlintrc.effect.json`
- the flag conflict failure moves onto the yieldable error form
- e2e tests run through the effect native harness, with the stack
teardown owned by a scoped release
- integration fixtures move onto the `FileSystem`/`Path` services inside
the effect

## ref:

- closes: CLI-2441
## TL;DR

brings the `supabase branches` command family under the effect lint

## whats introduced?

effect lint applied to `branches`:

- one allow list entry in `.oxlintrc.effect.json`
- cause assertions moved to `Cause.pretty`, json payload pins decoded
through schemas
- integration tests move onto the `FileSystem`/`Path` services, and the
env cases run through the shared sandbox helper
- live tests run through the effect fixture, keeping the original
cleanup ordering and the existing skip conditions

## ref:

- closes: CLI-2446
…LI-2448) (#6654)

## TL;DR

brings the `supabase link` and `supabase status` command families under
the effect lint

## whats introduced?

effect lint applied to `link` and `status`:

- one allow list entry per family in `.oxlintrc.effect.json`
- cause assertions moved to `Cause.pretty`, json payload pins decoded
through schemas, and the linked project cache writes encode through a
schema on the existing best effort path
- the branch listing stubs carry the http error type they already
produced, replacing an unknown error channel
- integration tests move onto the `FileSystem`/`Path` services with
fixture writes inside the effect, and the env cases run through the
shared sandbox helper
- e2e tests run through the effect native harness, live tests through
the effect fixture

## ref:

- closes: CLI-2447 & CLI-2448
## TL;DR

brings the `supabase storage` command family under the effect lint

## whats introduced?

effect lint applied to `storage`:

- one allow list entry in `.oxlintrc.effect.json`
- remote object keys now build through an injected posix `Path` service
instead of the `node:path` posix namespace, so a windows host can never
shape a key with backslashes
- three flag validation tests returned an effect from a plain `it`, so
their bodies never ran; they are now `it.effect` and execute
- cause assertions moved to `Cause.pretty`, and the ones that read a
`suggestion` field or assert a negative moved to typed predicates
instead, since `Cause.pretty` drops payload fields
- integration tests move onto the `FileSystem`/`Path` services, and the
env cases run through the shared sandbox helper
- e2e and live tests run through the effect native harness

## ref:

- closes: CLI-2449
<!--
Before opening this PR, confirm the linked issue is open and carries the
`open-for-contribution` label. PRs from external contributors that don't
follow
the workflow in CONTRIBUTING.md are closed automatically.
@supabase members working from Linear tickets are exempt.
-->

## Summary

noticed that our typescript LSP errors out when loading the scripts in
the `tools/` directory, so this PR fixes a couple things

- [x] converts our root-level package from CommonJS to ESM
  - [x] converts a couple root-level configuration files over to ESM
- [x] modernizes our top-level `tsconfig.json`

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).
…) (#6652)

## Summary

`gen types` no longer spawns a `postgres-meta` container. Introspection
and code generation run
in-process through
[`@supabase/postgrest-typegen`](https://github.com/supabase/sdk/tree/main/packages/postgrest-typegen)
over a direct PostgreSQL connection.

This is what `--local` on the managed stack needs: the stack exposes no
pg-meta capability, and it
supports a native runtime with no container engine at all, so the old
path required a Docker daemon
to generate types for a database that isn't in Docker. #6540 already
resolved the stack's real
endpoint here; this removes the container that resolution still fed.

Generation goes through the shared `DbConnection` seam that `db query`
uses, so there is no second
driver path — TLS mode, DoH resolution, pooler fallback and
connect-error classification are the
ones already in place.

**TLS.** The SSL probe is gone. Linked, project-ref and preview-branch
targets are known Supabase
hosts and pin the bundled CA with `sslmode=require`, preserving the
stricter posture `gen types`
already had. `--db-url` honours the DSN's own `sslmode`/`sslrootcert`
and otherwise pins only for
known Supabase hosts; `--local` stays plaintext. `PgConnInput` gains an
optional inline-CA field so
pinning needs no temp file.

**`--query-timeout`** now maps to a server-enforced `statement_timeout`
rather than a container env
var, so a stalled introspection is aborted by the server rather than
only client-side.

### Behaviour changes

**`--network-id` is rejected on this command.** In-process generation
cannot join a Docker network.
Both argv positions are covered, including the persistent form before
the command path.

**A `--db-url` pointing at a plain-TCP server now needs
`?sslmode=disable`.** The shared connection
layer intentionally does not downgrade from `prefer` to plaintext, and
`gen types` no longer probes.
This matches every other `--db-url` command; a connect-error suggestion
names the fix.

**Generated output**, measured against `postgres-meta` v0.99.0 on the
same schema:

| Language | Result |
| --- | --- |
| Go | byte-identical |
| Swift | byte-identical |
| TypeScript | a `NOT NULL` jsonb column is `NonNullable<Json>` rather
than `Json` |
| Python | jsonb columns are `JsonValue` rather than `Json[Any]`;
`NotRequired`/`TypeAlias` import from `typing_extensions` |

Both differences are upstream corrections: the old TypeScript type
admitted `null` for a `NOT NULL`
column, and pydantic's `Json[Any]` expects an unparsed JSON *string*
rather than a decoded row
value. `--linked`/`--project-id` TypeScript is generated server-side by
the Management API and is
unaffected, so it can differ from local output on these jsonb cases
until the hosted service adopts
the same engine. Recorded in the command's `SIDE_EFFECTS.md`.

### Credit

Supersedes #6404 by @avallete, which first proved this out and worked
through the
`bun build --compile` problems with `oxfmt` — the optional-plugin
externals and the statically
embedded napi binding here are that PR's design. Restarted from
`develop` because #6525 moved every
path it touched.

## Linked issue

Resolves [CLI-2366](https://linear.app/supabase/issue/CLI-2366). Also
covers
[CLI-2279](https://linear.app/supabase/issue/CLI-2279) (no GitHub
issue).

- [x] The linked issue is **open** and carries the
`open-for-contribution` label (or I'm a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Tests added or updated for the change.
- [x] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…6663)

## Summary

Aligns contributor docs for the experimental local stack with the
runtime resolver and the registered command tree:

- **ADR-0017** and **`packages/stack` README**: an omitted runtime
probes the Docker daemon and selects Docker only when it is reachable.
An installed client with an unreachable daemon selects native, and the
Effect handle carries a notice that the selection is persisted. Native
is refused as uid 0, and explicit runtimes do not fall back. ADR-0017
links to ADR-0025 for the probe.
- **`stack start` help text**: no longer says a stopped daemon still
selects Docker.
- **`apps/cli/docs/supabase-home.md`**: drops the nonexistent `supabase
stack update` command and describes the persisted materialized
definition instead of a `launch` field.
- **`packages/config/docs/cli-config-loading.md`**: drops the last
`stack update` mention.

## Linked issue

Closes #

- [ ] The linked issue is **open** and carries the
`open-for-contribution` label (or I'm a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Documentation and help-text only; no tests needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01BkvawC4it3LqVrnxvt48Ja

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
…#6648)

## Summary

Follow-up to #6540. Stack `db dump`, `migration squash`, and `test db`
launch `pg_dump` / `pg_dumpall` / `pg_prove` from the catalog Postgres
artifact or the same catalog image through `@supabase/stack`
`runPostgresClient`, not host PATH.

Native `--linked` / `--db-url` keep the resolved host; `--local` native
rewrites loopback to `127.0.0.1`. Platforms without a native artifact
(Windows, Intel Mac) use a one-shot Docker client of that image. Catalog
pins `15.14.1.168` / `17.6.1.168` to the slim-services #306 republish,
which includes `pg_prove` in the image. Catalog Postgres also ships
`plpgsql_check`, so native and container `db lint --local` can `CREATE
EXTENSION` inside the rolled-back lint transaction.

Companion: supabase/slim-services#306
## TL;DR

fixes `supabase start` deleting vector buckets without consent during
fresh volume seeding.

## whats hurting?

both `seedBucketsRun` call sites in `start.handler.ts` hardcode `yes:
true`
force answering the prune prompt whose default is no. any vector bucket
missing from `config.toml` is deleted whenever the vector store outlives
the local volume, silently and irreversibly, and `--yes`/`SUPABASE_YES`
are dead for start seeding..

## sol:

drop the hardcoded value at both call sites so consent resolves from
`--yes` and `SUPABASE_YES` exactly like
`db reset`, with integration tests pinning the declined default and the
consented prune..

## ref:
- closes: CLI-2443
## TL;DR

brings the `supabase unlink` command family under the effect lint

## whats introduced?

effect lint applied to `unlink`:

- one allow list entry in `.oxlintrc.effect.json`
- the handler's three failures yield their tagged error directly instead
of wrapping it in `Effect.fail`
- integration tests move onto the `FileSystem`/`Path` services, with the
project ref fixture written inside the effect
- cause assertions encode through a schema codec instead of
`JSON.stringify`, keeping the full serialized surface
- e2e tests run through the effect native harness with a scoped temp dir
per test, live tests through the effect fixture

## ref:

- closes: CLI-2453
## TL;DR

brings the `supabase seed` command family under the effect lint

## whats introduced?

effect lint applied to `seed`:

- one allow list entry in `.oxlintrc.effect.json`
- remote object keys build through injected `Path` services instead of
the `node:path` posix namespace, so the os native half and the posix
half stay explicit rather than riding on one module
- the shared upload call site in `command-internal` passes both
services, built once per call rather than once per file
- the mutually exclusive flags failure yields its tagged error directly
- the buckets integration suite writes its fixtures inside the effect,
and the ambient env pin moved from a `beforeEach` onto the shared
sandbox helper
- cause assertions moved to `Cause.pretty`, and the two that read a
`suggestion` field use typed predicates instead, since `Cause.pretty`
drops payload fields
- e2e tests run through the effect native harness with a scoped temp
project dir per test

## ref:

- closes: CLI-2452
Live branch tests can observe stale reads after creation or deletion,
and the project sweep can report a cleanup failure after teardown has
already started. Capture each created branch reference, wait for the
read surface used by the test, and reconcile project cleanup against
fresh authenticated listings without treating authorization failures
alone as success.

Include endpoint, status, and safe correlation IDs in terminal
project-setup errors while omitting response bodies.

Depends on #6649.
… compute routes (#6645)

Depends on supabase/platform#38464

The Management API answers 404 on the compute routes for several
distinct conditions, and the CLI was collapsing them into the wrong
message:

- A project outside the private alpha was told `No project <ref> was
found for this account` on the collection routes, and `"<name>" is not
deployed` on `status` and `delete` — sending someone to re-link or
re-push a project that was never the problem.
- A route this CLI build asks for but the API does not serve was
reported the same two ways.
- A project that does not exist was told `"<name>" is not deployed` on
`status`, and `delete` reported removing it.

Each condition carries its own `error.code`, so each now gets its own
error, on every route including the named-compute `status` and `delete`
ones:

| condition | code | error |
| --- | --- | --- |
| project outside the alpha | `not_found.compute.not_enabled` |
`ComputeUnavailableError`, pointing at the public alpha rather than
asking the reader to seek enrolment |
| no such route | `not_found`, with the router's `Cannot GET /…` message
| `ComputeRouteNotFoundError`, naming the route |
| no such project | `not_found` | `ComputeProjectNotFoundError`, which
now means only what it says |
| no compute under that name | `not_found.compute.instance` |
`ComputeNotDeployedError`, the only one the named routes can mean |

The poll behind `push` no longer retries the three permanent verdicts
for its full 30-second window, and the analytics logs route — which is
not gated on the alpha's allow-list — classifies its own 404 body
instead of blaming the alpha for every one.

Also extracts `bodyText`, `unexpectedStatus(operation, response)`,
`decodeJsonBody` and the 404 body reader in `compute-api-status.ts` so
`compute-api.ts` and `compute-logs-api.ts` share one place to read a
response body, instead of threading status and body through every call
site.

The enrolment split depends on the Management API emitting
`not_found.compute.not_enabled`, which is not deployed yet. Until it is,
an unenrolled project answers a bare `generic_not_found`, which no
branch claims and which falls back to the alpha refusal — so the
enrolment message is already right, and only its precision waits on the
API. FUNC-897 should stay open until the API side is live.


https://linear.app/supabase/issue/FUNC-897/fix-no-project-ref-was-found-for-unenrolled-compute-projects
…) (#6664)

## Summary

Follow-up to #6652, addressing @avallete's post-merge review

([review](#6652 (review))).

#6652 stopped `sslConfigsFor` from silently downgrading an explicit
`sslmode=require` /
`verify-full` to plaintext on a target classified local. The predicate
it introduced was too broad:
it treated **any** populated `sslmode` as a TLS demand.

That is not the same as the DSN asking for TLS:

- `prefer` and `allow` name a TLS/plaintext fallback that libpq performs
and `sslConfigsFor`
deliberately does not — it maps `prefer` and unset to TLS-only. Local
classification used to force
plaintext *before* that mapping ran, so reading `prefer` as a demand
turns a plaintext-capable
  target into a handshake failure.
- `sslmode` is also filled from `PGSSLMODE` and libpq service files when
the DSN omits it, so a
merely present value can come from the environment rather than the
connection string.

The result was a regression on the shared `DbConnection` seam: a
developer with `PGSSLMODE=prefer`
exported, or a DSN carrying `?sslmode=prefer`, could no longer reach a
local plaintext Postgres —
affecting `db query --db-url`, dump and pull as well as `gen types`.

Only `require`, `verify-ca`, `verify-full`, or a supplied `sslrootcert`
/ inline CA now count as a
demand.

### Verified against a plaintext Postgres on the local-classified port

| Connection | merged `develop` | this branch |
| --- | --- | --- |
| bare loopback DSN | connects | connects |
| `PGSSLMODE=prefer` | **fails** | connects |
| `PGSSLMODE=allow` | **fails** | connects |
| `?sslmode=prefer` | **fails** | connects |
| `?sslmode=disable` | connects | connects |
| `?sslmode=require` | fails closed | fails closed |
| `PGSSLMODE=verify-full` | fails closed | fails closed |

The TLS-tunnel behaviour #6652 set out to fix is unchanged: an explicit
demand still puts an
SSLRequest on the wire against a loopback target, and a supplied root
cert still opens the CA gate.

Coverage is behavioural rather than shape-only — the integration tests
assert whether an SSLRequest
actually reaches a fake Postgres server, and a unit test composes the
real DSN parser with the
predicate so the `PGSSLMODE`-filled case is covered end to end rather
than assumed.

## Linked issue

Follow-up to [CLI-2366](https://linear.app/supabase/issue/CLI-2366) (no
GitHub issue).

- [x] The linked issue is **open** and carries the
`open-for-contribution` label (or I'm a Supabase maintainer).

## Checklist

- [x] The PR title follows [Conventional
Commits](https://www.conventionalcommits.org/) (e.g. `fix(cli): …`).
- [x] Tests added or updated for the change.
- [x] From the repository root, `pnpm check:all` passes; relevant
package tests pass for every touched workspace, and `pnpm types:check`
passes for each touched TypeScript workspace (or workspace declaring
it).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
## TL;DR

Fixes `config push` applying remote changes after a piped `n` in agent
mode.

## whats wrong?

JSON and stream JSON confirmations return the default before reading
stdin. With `config push` defaulting to yes, an explicit decline is
ignored.

## now fixed by

Honor piped answers in machine output.

> [!WARNING]
>     **Breaking change:** 
unattended `config push` now skips updates without affirmative input or
`--yes`/`SUPABASE_YES`
text mode explains skipped confirmations. Interactive text confirmations
retain their yes default...

## ref:

- closes #6657
related: #6647
## TL;DR

brings the `supabase migration` command family under the effect lint

## whats introduced?

effect lint applied to `migration`:

- two allow list entries in `.oxlintrc.effect.json` for the command
family and its live test helper
- handler failures yield their tagged errors directly instead of
wrapping them in `Effect.fail`
- down and repair acquire cache dependencies directly, keeping the same
finalizer ordering
- integration tests move onto the `FileSystem`/`Path` services, with
fixtures written inside the effect
- env cases run through the shared sandbox helper
- cause assertions use typed predicates to check failure tags and
payload fields
- e2e tests run through the effect native harness with a scoped temp
project dir per test
- live tests run through the effect fixture, with typed DB promise
errors and owned cleanup

## ref:

- closes: CLI-2413
## TL;DR

brings the `sso` command family under the effect lint

## whats introduced?

effect lint applied to `sso`:

- one allow list entry in `.oxlintrc.effect.json`
- two documented native JSON parser exceptions preserve exact CLI
errors; both files remain covered by every other Effect lint rule
- handler failures yield tagged errors directly; timestamp parsing keeps
native date semantics
- fixture and env tests use injected `FileSystem`/`Path` services and
shared sandbox helpers; cause assertions use `Cause.pretty` and typed
predicates
- JSON output assertions preserve excess fields so exact-shape checks
catch leaks
- e2e tests use the effect native harness with scoped temp project dirs

## ref:

- closes: CLI-2411
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do not merge Approve to apply; do not merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants