Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions apps/cli/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -40,11 +40,11 @@
},
"dependencies": {
"eciesjs": "^0.5.0",
"jose": "^6.2.4"
"jose": "^6.2.8"
},
"devDependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.3.220",
"@anthropic-ai/sdk": "^0.115.0",
"@anthropic-ai/claude-agent-sdk": "^0.3.227",
"@anthropic-ai/sdk": "^0.116.0",
"@clack/prompts": "^1.7.0",
"@effect/atom-react": "catalog:",
"@effect/platform-bun": "catalog:",
Expand All@@ -61,27 +61,27 @@
"@supabase/stack": "workspace:*",
"@tsconfig/bun": "catalog:",
"@types/bun": "catalog:",
"@types/pg": "^8.15.0",
"@types/pg": "^8.21.0",
"@types/pg-copy-streams": "^1.2.5",
"@types/react": "^19.2.17",
"@types/react": "^19.2.18",
"@typescript/native-preview": "catalog:",
"@vercel/detect-agent": "^1.2.3",
"@vercel/detect-agent": "^1.2.4",
"@vitest/coverage-istanbul": "catalog:",
"dotenv": "^17.4.2",
"effect": "catalog:",
"esbuild": "^0.28.1",
"esbuild": "^0.28.2",
"ink": "^7.1.1",
"ink-spinner": "^5.0.0",
"knip": "catalog:",
"oxfmt": "catalog:",
"oxlint": "catalog:",
"oxlint-tsgolint": "catalog:",
"pg": "^8.22.0",
"pg": "^8.23.0",
"pg-copy-streams": "^7.0.0",
"posthog-node": "^5.46.1",
"posthog-node": "^5.48.1",
"react": "^19.2.8",
"react-devtools-core": "^7.0.1",
"semantic-release": "^25.0.8",
"semantic-release": "^25.0.9",
"smol-toml": "^1.7.1",
"tldts": "catalog:",
"typescript": "npm:@typescript/typescript6@^6.0.2",
Expand Down
6 changes: 4 additions & 2 deletions apps/cli/src/legacy/cli/legacy-complete.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -1258,7 +1258,7 @@ function legacyHelpArgumentCandidates(
}

const resolved = commandChain[commandChain.length - 1] ?? root;
const visibleSubcommands = legacyFlattenSubcommands(resolved).filter((sub) => !sub.hidden);
const visibleSubcommands = legacyFlattenSubcommands(resolved).filter((sub) => !sub.unlisted);
const candidates: Array<LegacyCompletionCandidate> = visibleSubcommands.map((sub) => ({
name: sub.name,
description: sub.shortDescription ?? sub.description,
Expand DownExpand Up@@ -1483,7 +1483,9 @@ export function legacyClassifyCompletion(
// `len(finalArgs) == 0` gate) — including the directive it would otherwise
// set, which stays at `Default` in that case (`completions.go:489,499-522`).
if (leftoverArgs.length === 0) {
const visibleSubcommands = legacyFlattenSubcommands(finalCommand).filter((sub) => !sub.hidden);
const visibleSubcommands = legacyFlattenSubcommands(finalCommand).filter(
(sub) => !sub.unlisted,
);
if (visibleSubcommands.length > 0) {
directive = LegacyCompletionDirective.NoFileComp;
const subcommandCandidates: Array<LegacyCompletionCandidate> = visibleSubcommands.map(
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/legacy/commands/branches/branches.command.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,6 @@ export const legacyBranchesCommand = Command.make("branches").pipe(
legacyBranchesPauseCommand,
legacyBranchesUnpauseCommand,
legacyBranchesDeleteCommand,
legacyBranchesDisableCommand.pipe(Command.withHidden),
legacyBranchesDisableCommand.pipe(Command.unlisted),
]),
);
6 changes: 3 additions & 3 deletions apps/cli/src/legacy/commands/db/db.command.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,9 @@ export const legacyDbCommand = Command.make("db").pipe(
legacyDbStartCommand,
legacyDbQueryCommand,
legacyDbAdvisorsCommand,
legacyDbTestCommand.pipe(Command.withHidden),
legacyDbBranchCommand.pipe(Command.withHidden),
legacyDbRemoteCommand.pipe(Command.withHidden),
legacyDbTestCommand.pipe(Command.unlisted),
legacyDbBranchCommand.pipe(Command.unlisted),
legacyDbRemoteCommand.pipe(Command.unlisted),
legacyDbSchemaCommand,
]),
);
2 changes: 1 addition & 1 deletion apps/cli/src/legacy/commands/db/test/SIDE_EFFECTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -73,7 +73,7 @@ Identical to `test db`. See
## Notes

- Native TypeScript port (Phase 1+); no Go proxy (CLI-1962). Hidden command —
registered with `.pipe(Command.withHidden)` in `../db.command.ts`.
registered with `.pipe(Command.unlisted)` in `../db.command.ts`.
- `--local` defaults to `true` on both `db test` and `test db` — bare
`supabase db test` always targets the local stack. This resolves a former
proxy-only `--local` default-modelling caveat that existed while this
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/legacy/commands/db/test/test.command.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,7 @@ import { legacyTestDbRuntimeLayer } from "../../../shared/legacy-test-db.layers.

/**
* `db test` is a hidden alias for `test db` (registered hidden by the
* parent, `../db.command.ts`'s `legacyDbTestCommand.pipe(Command.withHidden)`).
* parent, `../db.command.ts`'s `legacyDbTestCommand.pipe(Command.unlisted)`).
*
* `db test` and `test db` share one implementation, registered as two
* separate commands with identical flags and Short text. The native TS port
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/src/legacy/docs/legacy-docs-spec.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -279,7 +279,7 @@ function legacyDocsVisibleChildren(
command: Command.Command.Any,
): ReadonlyArray<Command.Command.Any> {
return legacyFlattenSubcommands(command)
.filter((child) => !child.hidden)
.filter((child) => !child.unlisted)
.toSorted((a, b) => legacyDocsCompare(a.name, b.name));
}

Expand Down
4 changes: 3 additions & 1 deletion apps/cli/src/legacy/shared/legacy-local-config-values.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -1772,7 +1772,9 @@ interface LegacyResolvedAuthHook {
}

export type LegacyResolvedAuthHooks = {
readonly [K in (typeof LEGACY_HOOK_TYPE_TO_CAMEL)[keyof typeof LEGACY_HOOK_TYPE_TO_CAMEL]]: LegacyResolvedAuthHook;
readonly [
K in (typeof LEGACY_HOOK_TYPE_TO_CAMEL)[keyof typeof LEGACY_HOOK_TYPE_TO_CAMEL]
]: LegacyResolvedAuthHook;
};

/**
Expand Down
9 changes: 4 additions & 5 deletions apps/cli/src/shared/cli/hidden-flag.unit.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -317,11 +317,10 @@ describe("legacy hidden subcommands", () => {
Effect.exit,
) as Effect.Effect<unknown, never, never>,
);
// Effect CLI's own raw `_tag` for this error is misspelled "UnknownSubcomand"
// (`CliError.js`, upstream typo); `cliErrorCode()`/`normalize-error.ts` already
// correct it for user-facing output, but this assertion checks the raw,
// un-normalized tag, so it must match the upstream spelling as-is.
expect(JSON.stringify(unknownExit)).toContain("UnknownSubcomand");
// Effect CLI's raw `_tag` uses the corrected "UnknownSubcommand" spelling.
// This assertion checks the raw, un-normalized tag so it stays aligned with
// the upstream parser error value.
expect(JSON.stringify(unknownExit)).toContain("UnknownSubcommand");
expect(causeOf(unknownExit).reasons[0]?._tag).toBe("Fail"); // typed CliError, pre-handler — dispatch never reached a handler
});
});
6 changes: 3 additions & 3 deletions apps/cli/src/shared/cli/subcommand-flag-suggestions.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,7 @@ export interface FormattedCliErrors {
}

export function cliErrorCode(error: CliError.CliError): string {
return error._tag === "UnknownSubcomand" ? "UnknownSubcommand" : error._tag;
return error._tag;
}

interface CommandWithHelpDoc extends Command.Command.Any {
Expand DownExpand Up@@ -97,7 +97,7 @@ function collectDescendants(
const visit = (current: Command.Command.Any, path: ReadonlyArray<string>) => {
for (const group of current.subcommands) {
for (const child of group.commands) {
if (child.hidden) continue;
if (child.unlisted) continue;

const childPath = [...path, child.name];
const helpDoc = helpDocFor(child, childPath);
Expand DownExpand Up@@ -320,7 +320,7 @@ export function formatCliErrorsForDisplay(
}
}

if (error._tag === "UnknownSubcomand" && suppressedUnknownSubcommands.has(error.subcommand)) {
if (error._tag === "UnknownSubcommand" && suppressedUnknownSubcommands.has(error.subcommand)) {
changed = true;
continue;
}
Expand Down
5 changes: 2 additions & 3 deletions apps/cli/src/shared/output/normalize-error.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -95,7 +95,7 @@ const mappedError = (
}
return undefined;
}
case "UnknownSubcomand":
case "UnknownSubcommand":
return {
code: "UnknownSubcommand",
message: readString(error, "message") ?? "Unknown subcommand",
Expand DownExpand Up@@ -170,8 +170,7 @@ export function normalizeCliError(
return mapped;
}

const rawCode = readString(error, "_tag") ?? "UnknownError";
const code = rawCode === "UnknownSubcomand" ? "UnknownSubcommand" : rawCode;
const code = readString(error, "_tag") ?? "UnknownError";
const message = readString(error, "message") ?? readString(error, "detail") ?? code;
const detail = readString(error, "detail");
// Raw read: some producers' suggestion text is meaningful leading/trailing
Expand Down
7 changes: 2 additions & 5 deletions apps/cli/src/shared/telemetry/error-actionability.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -784,9 +784,7 @@ const effectCliActionabilityByTag = {
DuplicateOption: () => actionability.invalidInput,
UnexpectedArgument: () => actionability.invalidInput,
InvalidValue: () => actionability.invalidInput,
// Effect 4.0.0-beta.103 has this typo in the runtime tag. Keep the adapter
// keyed to reality; the emitted fingerprint is normalized below.
UnknownSubcomand: () => actionability.invalidInput,
UnknownSubcommand: () => actionability.invalidInput,
UnrecognizedOption: () => actionability.invalidInput,
} satisfies Record<EffectCliAdapterTag, ErrorActionabilityAdapter>;

Expand DownExpand Up@@ -1227,8 +1225,7 @@ function classifyAtDepth(error: unknown, depth: number): CliErrorActionability {
if (Object.hasOwn(externalActionabilityByTag, tag)) {
const external = externalActionabilityByTag[tag];
if (external !== undefined) {
const fingerprintTag = tag === "UnknownSubcomand" ? "UnknownSubcommand" : tag;
return toActionability(external(error), "tag", fingerprintTag);
return toActionability(external(error), "tag", tag);
}
}
return toActionability(actionability.unknown, "tag", undefined);
Expand Down
14 changes: 7 additions & 7 deletions apps/docs/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -8,18 +8,18 @@
"build": "bun run generate && next build"
},
"dependencies": {
"fumadocs-core": "^16.13.0",
"fumadocs-mdx": "^15.2.0",
"fumadocs-ui": "^16.13.0",
"next": "16.3.0-preview.10",
"fumadocs-core": "^16.14.3",
"fumadocs-mdx": "^15.2.3",
"fumadocs-ui": "^16.14.3",
"next": "16.3.0",
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@types/mdx": "^2.0.14",
"@types/node": "^26.1.2",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.1.6",
"@types/node": "^26.2.0",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4",
"typescript": "^7.0.2"
},
"nx": {
Expand Down
4 changes: 2 additions & 2 deletions docs/nx-inference-plugins.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,8 +22,8 @@ Infers `knip:check` and `knip:fix` targets for any workspace package that has a

| Target | Command | Cached | Inputs |
|--------|---------|--------|--------|
| `knip:check` | `knip-bun` | Yes | Entry files from `knip.entry` (or `default` if none defined), `sharedGlobals`, `knip` package version |
| `knip:fix` | `knip-bun --fix` | No | — |
| `knip:check` | `knip-bun --exclude catalogReferences` | Yes | Entry files from `knip.entry` (or `default` if none defined), `sharedGlobals`, `knip` package version |
| `knip:fix` | `knip-bun --fix --exclude catalogReferences` | No | — |

**Input resolution:** If `knip.entry` lists explicit file patterns (e.g. `["src/index.ts", "src/**/*.test.ts"]`), those patterns are used as the cache inputs instead of the broad `default` named input. This means the cache is only invalidated when those specific files change, rather than on any file change in the project. If no `entry` is defined, it falls back to `["default", "sharedGlobals"]`. In both cases, the `knip` package version is included so a version bump triggers a re-check.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -27,8 +27,8 @@
"oxfmt": "catalog:",
"oxlint": "catalog:",
"oxlint-tsgolint": "catalog:",
"pkg-pr-new": "0.0.82",
"pkg-pr-new": "0.0.87",
"typescript": "npm:@typescript/typescript6@^6.0.2",
"verdaccio": "^6.9.0"
"verdaccio": "^6.9.2"
}
}
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@
"@effect/platform-bun": "catalog:",
"@effect/platform-node": "catalog:",
"effect": "catalog:",
"undici": "^8.9.0"
"undici": "^8.10.0"
},
"devDependencies": {
"@tsconfig/bun": "catalog:",
Expand Down
1 change: 1 addition & 0 deletions packages/api/scripts/generate.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -784,6 +784,7 @@ function renderSchemaSource(
schemas,
},
{
patterns: "apply",
onEnter(schema) {
const next = { ...schema };
if (next.type === "object" && next.additionalProperties === undefined) {
Expand Down
38 changes: 16 additions & 22 deletions packages/api/src/generated/contracts.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -342,13 +342,17 @@ export const ThirdPartyAuth = Schema.Struct({
resolved_at: Schema.optionalKey(Schema.Union([Schema.String, Schema.Null])),
}).annotate({ identifier: "ThirdPartyAuth" });
// recursive definitions
export type Suspend_ = UpdateCustomHostnameResponseJsonValue;
export const Suspend_ = Schema.suspend(
(): Schema.Codec<UpdateCustomHostnameResponseJsonValue> => UpdateCustomHostnameResponseJsonValue,
);
export type UpdateCustomHostnameResponseJsonValue =
| string
| number
| boolean
| null
| ReadonlyArray<UpdateCustomHostnameResponseJsonValue>
| { readonly [x: string]: UpdateCustomHostnameResponseJsonValue };
| ReadonlyArray<Suspend_>
| { readonly [x: string]: Suspend_ };
export const UpdateCustomHostnameResponseJsonValue = Schema.Union([
Schema.Union([
Schema.Union([
Expand All@@ -358,30 +362,26 @@ export const UpdateCustomHostnameResponseJsonValue = Schema.Union([
]),
Schema.Null,
]),
Schema.Array(
Schema.suspend(
(): Schema.Codec<UpdateCustomHostnameResponseJsonValue> =>
UpdateCustomHostnameResponseJsonValue,
),
),
Schema.Array(Schema.suspend((): Schema.Codec<Suspend_> => Suspend_)),
Schema.Record(
Schema.String,
Schema.suspend(
(): Schema.Codec<UpdateCustomHostnameResponseJsonValue> =>
UpdateCustomHostnameResponseJsonValue,
),
Schema.suspend((): Schema.Codec<Suspend_> => Suspend_),
),
]).annotate({
description: "Any JSON-serializable value",
identifier: "UpdateCustomHostnameResponseJsonValue",
});
export type Suspend_1 = ListProjectAddonsResponseJsonValue;
export const Suspend_1 = Schema.suspend(
(): Schema.Codec<ListProjectAddonsResponseJsonValue> => ListProjectAddonsResponseJsonValue,
);
export type ListProjectAddonsResponseJsonValue =
| string
| number
| boolean
| null
| ReadonlyArray<ListProjectAddonsResponseJsonValue>
| { readonly [x: string]: ListProjectAddonsResponseJsonValue };
| ReadonlyArray<Suspend_1>
| { readonly [x: string]: Suspend_1 };
export const ListProjectAddonsResponseJsonValue = Schema.Union([
Schema.Union([
Schema.Union([
Expand All@@ -391,16 +391,10 @@ export const ListProjectAddonsResponseJsonValue = Schema.Union([
]),
Schema.Null,
]),
Schema.Array(
Schema.suspend(
(): Schema.Codec<ListProjectAddonsResponseJsonValue> => ListProjectAddonsResponseJsonValue,
),
),
Schema.Array(Schema.suspend((): Schema.Codec<Suspend_1> => Suspend_1)),
Schema.Record(
Schema.String,
Schema.suspend(
(): Schema.Codec<ListProjectAddonsResponseJsonValue> => ListProjectAddonsResponseJsonValue,
),
Schema.suspend((): Schema.Codec<Suspend_1> => Suspend_1),
),
]).annotate({
description: "Any JSON-serializable value",
Expand Down
21 changes: 19 additions & 2 deletions packages/config/scripts/build.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,24 @@ import { mkdir } from "node:fs/promises";
import { toProjectConfigJsonSchema } from "../src/base.ts";

const json = toProjectConfigJsonSchema();
const schema = `${JSON.stringify(json, null, 2)}\n`;

const formatter = Bun.spawn(["bun", "x", "oxfmt", "--stdin-filepath=./dist/schema.json"], {
stdin: "pipe",
stdout: "pipe",
stderr: "pipe",
});
formatter.stdin.write(schema);
formatter.stdin.end();

const [exitCode, formatted, stderr] = await Promise.all([
formatter.exited,
new Response(formatter.stdout).text(),
new Response(formatter.stderr).text(),
]);
if (exitCode !== 0) {
throw new Error(`oxfmt failed with exit code ${exitCode}: ${stderr.trim()}`);
}

await mkdir("./dist", { recursive: true });
await Bun.write("./dist/schema.json", `${JSON.stringify(json, null, 2)}\n`);
await Bun.$`bun x oxfmt ./dist/schema.json`.quiet();
await Bun.write("./dist/schema.json", formatted);
Loading
Loading