@rebasepro/cli 0.23.0 → 0.24.1-canary.g19596ef
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -3
- package/bin/rebase.js +4 -1
- package/dist/agent-setup-B31F00DC.js +324 -0
- package/dist/agent-setup-B31F00DC.js.map +1 -0
- package/dist/api-keys-Bl1I9q7M.js +525 -0
- package/dist/api-keys-Bl1I9q7M.js.map +1 -0
- package/dist/apps-CNgQJjg5.js +340 -0
- package/dist/apps-CNgQJjg5.js.map +1 -0
- package/dist/args-BnmsEXvu.js +109 -0
- package/dist/args-BnmsEXvu.js.map +1 -0
- package/dist/atlas-dev-database-D_LP_Woq.js +62 -0
- package/dist/atlas-dev-database-D_LP_Woq.js.map +1 -0
- package/dist/auth-aySHEF45.js +414 -0
- package/dist/auth-aySHEF45.js.map +1 -0
- package/dist/branch-pointer-DvSHBjjz.js +2 -0
- package/dist/build-DIHWIqO4.js +336 -0
- package/dist/build-DIHWIqO4.js.map +1 -0
- package/dist/bundle-CqURVN-K.js +1621 -0
- package/dist/bundle-CqURVN-K.js.map +1 -0
- package/dist/bundle.d.ts +12 -3
- package/dist/cli.d.ts +23 -2
- package/dist/cloud-DjByQlkW.js +9667 -0
- package/dist/cloud-DjByQlkW.js.map +1 -0
- package/dist/collection-drift-BKj_BoMq.js +106 -0
- package/dist/collection-drift-BKj_BoMq.js.map +1 -0
- package/dist/commands/__test_support__/parser-specs.d.ts +13 -0
- package/dist/commands/agent-setup.d.ts +116 -0
- package/dist/commands/api-keys.d.ts +86 -23
- package/dist/commands/apps.d.ts +17 -0
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/build.d.ts +5 -1
- package/dist/commands/cloud/auth.d.ts +4 -3
- package/dist/commands/cloud/bundle-deploy.d.ts +45 -0
- package/dist/commands/cloud/context.d.ts +44 -5
- package/dist/commands/cloud/cron.d.ts +53 -0
- package/dist/commands/cloud/debug.d.ts +134 -0
- package/dist/commands/cloud/index.d.ts +89 -12
- package/dist/commands/cloud/token-capabilities.d.ts +76 -0
- package/dist/commands/cloud/tokens.d.ts +23 -0
- package/dist/commands/console.d.ts +12 -0
- package/dist/commands/db.d.ts +79 -25
- package/dist/commands/dev.d.ts +181 -13
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/generate_sdk.d.ts +29 -2
- package/dist/commands/init.d.ts +115 -14
- package/dist/commands/schema.d.ts +6 -0
- package/dist/commands/skills.d.ts +126 -7
- package/dist/commands/start.d.ts +44 -0
- package/dist/commands/storage.d.ts +46 -0
- package/dist/commands/upgrade.d.ts +1 -0
- package/dist/consent-ClRHmcxf.js +76 -0
- package/dist/consent-ClRHmcxf.js.map +1 -0
- package/dist/console-D6SJf8k_.js +102 -0
- package/dist/console-D6SJf8k_.js.map +1 -0
- package/dist/context-BqhRydBg.js +1234 -0
- package/dist/context-BqhRydBg.js.map +1 -0
- package/dist/{daemon-entry-LTFKtpHy.js → daemon-entry-Da-D3rmH.js} +3 -4
- package/dist/daemon-entry-Da-D3rmH.js.map +1 -0
- package/dist/daemon-pzsQwDHa.js +2 -0
- package/dist/db-B7RuNuaQ.js +1312 -0
- package/dist/db-B7RuNuaQ.js.map +1 -0
- package/dist/derive-Dl0z2OWi.js +484 -0
- package/dist/derive-Dl0z2OWi.js.map +1 -0
- package/dist/dev-CYr_WXan.js +1599 -0
- package/dist/dev-CYr_WXan.js.map +1 -0
- package/dist/dev-db/atlas-dev-database.d.ts +32 -0
- package/dist/dev-db/daemon-entry.d.ts +13 -0
- package/dist/dev-db/daemon.d.ts +10 -0
- package/dist/dev-db/last-dev-database.d.ts +41 -0
- package/dist/dev-db/prepare.d.ts +29 -3
- package/dist/dev-db/pull.d.ts +90 -5
- package/dist/dev-db/resolve.d.ts +26 -2
- package/dist/dev-preflight-B-LYyBf1.js +2 -0
- package/dist/dev-server-DG8Tt-uf.js +96 -0
- package/dist/dev-server-DG8Tt-uf.js.map +1 -0
- package/dist/doctor-BP8cZ-7F.js +771 -0
- package/dist/doctor-BP8cZ-7F.js.map +1 -0
- package/dist/eject-DizdoecV.js +335 -0
- package/dist/eject-DizdoecV.js.map +1 -0
- package/dist/fold-static-BC9CYicw.js +201 -0
- package/dist/fold-static-BC9CYicw.js.map +1 -0
- package/dist/fold-static.d.ts +26 -3
- package/dist/function-portability-BIvlvR9q.js +265 -0
- package/dist/function-portability-BIvlvR9q.js.map +1 -0
- package/dist/generate_sdk-BPqdJc3Q.js +489 -0
- package/dist/generate_sdk-BPqdJc3Q.js.map +1 -0
- package/dist/index.es.js +199 -22095
- package/dist/index.es.js.map +1 -1
- package/dist/init-Utstvh2Q.js +1149 -0
- package/dist/init-Utstvh2Q.js.map +1 -0
- package/dist/last-dev-database-B58g89uA.js +2 -0
- package/dist/manifest-DRp0UVTj.js +880 -0
- package/dist/manifest-DRp0UVTj.js.map +1 -0
- package/dist/manifest.d.ts +56 -4
- package/dist/normalize-imports-X0Tgze9y.js +107 -0
- package/dist/normalize-imports-X0Tgze9y.js.map +1 -0
- package/dist/package-manager-DSEOwTqM.js +193 -0
- package/dist/package-manager-DSEOwTqM.js.map +1 -0
- package/dist/path-flags-BFgG9V6y.js +91 -0
- package/dist/path-flags-BFgG9V6y.js.map +1 -0
- package/dist/precompress.d.ts +17 -0
- package/dist/prepare-CDN6lSpz.js +1236 -0
- package/dist/prepare-CDN6lSpz.js.map +1 -0
- package/dist/{project-3WCbrrfW.js → project-Wp2zoyeN.js} +34 -184
- package/dist/project-Wp2zoyeN.js.map +1 -0
- package/dist/pull-CrGYMEsy.js +458 -0
- package/dist/pull-CrGYMEsy.js.map +1 -0
- package/dist/resolve-B2O-wKKk.js +2 -0
- package/dist/resources-FD7AfZx8.js +183 -0
- package/dist/resources-FD7AfZx8.js.map +1 -0
- package/dist/schema-DMdr431S.js +125 -0
- package/dist/schema-DMdr431S.js.map +1 -0
- package/dist/skills-DTFibT1m.js +642 -0
- package/dist/skills-DTFibT1m.js.map +1 -0
- package/dist/start-DEa-hOBh.js +267 -0
- package/dist/start-DEa-hOBh.js.map +1 -0
- package/dist/{state-C59Elrnt.js → state-Do7ZJYkF.js} +49 -4
- package/dist/state-Do7ZJYkF.js.map +1 -0
- package/dist/status-DxnJTekv.js +352 -0
- package/dist/status-DxnJTekv.js.map +1 -0
- package/dist/storage-DyVq-f_F.js +303 -0
- package/dist/storage-DyVq-f_F.js.map +1 -0
- package/dist/telemetry/identity.d.ts +10 -1
- package/dist/telemetry-C8Uq8phb.js +129 -0
- package/dist/telemetry-C8Uq8phb.js.map +1 -0
- package/dist/telemetry-EMFRVRQi.js +351 -0
- package/dist/telemetry-EMFRVRQi.js.map +1 -0
- package/dist/unknown-command-DNwDcX3w.js +98 -0
- package/dist/unknown-command-DNwDcX3w.js.map +1 -0
- package/dist/upgrade-CtZtRkTE.js +1332 -0
- package/dist/upgrade-CtZtRkTE.js.map +1 -0
- package/dist/upgrade.d.ts +38 -5
- package/dist/utils/dev-preflight.d.ts +47 -5
- package/dist/utils/dev-server.d.ts +30 -0
- package/dist/utils/path-flags.d.ts +31 -0
- package/dist/utils/project.d.ts +16 -0
- package/dist/utils/temp-archive.d.ts +9 -0
- package/dist/version-Buyyo1ut.js +58 -0
- package/dist/version-Buyyo1ut.js.map +1 -0
- package/package.json +7 -7
- package/templates/eject/Dockerfile +4 -2
- package/templates/eject/backend/src/env.ts +1 -1
- package/templates/eject/backend/src/index.ts +42 -4
- package/templates/eject/docker-compose.custom.yml +8 -4
- package/templates/generated-schemas/blank.ts +40 -0
- package/templates/generated-schemas/blog.ts +127 -0
- package/templates/generated-schemas/ecommerce.ts +93 -0
- package/templates/overlays/baas/ai-instructions.md +1 -1
- package/templates/overlays/baas/config/package.json +1 -0
- package/templates/overlays/baas/config/storage.ts +5 -3
- package/templates/overlays/baas/package.json +1 -0
- package/templates/template/.cursorrules +1 -1
- package/templates/template/.env.example +20 -10
- package/templates/template/.github/copilot-instructions.md +1 -1
- package/templates/template/.mcp.json +2 -2
- package/templates/template/.windsurfrules +1 -1
- package/templates/template/AGENTS.md +1 -1
- package/templates/template/CLAUDE.md +1 -1
- package/templates/template/README.md +21 -15
- package/templates/template/ai-instructions.md +5 -4
- package/templates/template/backend/functions/hello.ts +8 -0
- package/templates/template/backend/package.json +1 -1
- package/templates/template/config/resources.ts +7 -6
- package/templates/template/config/storage.ts +5 -3
- package/templates/template/docker-compose.yml +15 -9
- package/templates/template/frontend/vite.config.ts +13 -3
- package/templates/template/gitignore +6 -1
- package/templates/template/package.json +5 -3
- package/templates/template/scripts/example.ts +6 -4
- package/templates/template/tsconfig.json +25 -0
- package/dist/branch-pointer-dBiClJ0p.js +0 -111
- package/dist/branch-pointer-dBiClJ0p.js.map +0 -1
- package/dist/constraints-DKGbNfUW.js +0 -48
- package/dist/constraints-DKGbNfUW.js.map +0 -1
- package/dist/daemon-DR9Tk0La.js +0 -355
- package/dist/daemon-DR9Tk0La.js.map +0 -1
- package/dist/daemon-entry-LTFKtpHy.js.map +0 -1
- package/dist/dev-preflight-CNLl4rdo.js +0 -367
- package/dist/dev-preflight-CNLl4rdo.js.map +0 -1
- package/dist/project-3WCbrrfW.js.map +0 -1
- package/dist/pull-Dywm5FWP.js +0 -232
- package/dist/pull-Dywm5FWP.js.map +0 -1
- package/dist/resolve-BAeRUBhg.js +0 -74
- package/dist/resolve-BAeRUBhg.js.map +0 -1
- package/dist/state-C59Elrnt.js.map +0 -1
- package/templates/template/backend/src/schema.generated.ts +0 -13
package/dist/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","names":[],"sources":["../src/utils/version.ts","../src/utils/args.ts","../src/commands/cloud/errors.ts","../src/commands/cloud/context.ts","../src/telemetry/payload.ts","../src/telemetry/identity.ts","../src/telemetry/project.ts","../src/telemetry/index.ts","../src/telemetry/consent.ts","../src/commands/init.ts","../src/commands/generate_sdk.ts","../src/utils/spawn-error.ts","../src/utils/unknown-command.ts","../src/utils/command-words.ts","../src/dev-db/prepare.ts","../src/commands/db.ts","../src/commands/schema.ts","../src/manifest.ts","../src/utils/collection-drift.ts","../src/commands/dev.ts","../src/utils/tool-stdio.ts","../src/function-portability.ts","../src/bundle.ts","../src/fold-static.ts","../src/resources/derive.ts","../src/commands/build.ts","../src/commands/eject.ts","../src/commands/start.ts","../src/commands/auth.ts","../src/utils/libpq-url.ts","../src/doctor-environment.ts","../src/commands/doctor.ts","../src/commands/resources.ts","../src/resources/status.ts","../src/commands/status.ts","../src/commands/normalize-imports.ts","../src/commands/skills.ts","../src/commands/api-keys.ts","../src/commands/telemetry.ts","../src/commands/cloud/auth.ts","../src/commands/cloud/link.ts","../src/commands/cloud/resources.ts","../src/commands/cloud/db-connect.ts","../src/commands/cloud/databases.ts","../src/commands/cloud/projects.ts","../src/commands/cloud/bundle-deploy.ts","../src/commands/cloud/rebuild-source.ts","../src/commands/cloud/deploy.ts","../src/commands/cloud/orgs.ts","../src/commands/cloud/env.ts","../src/commands/cloud/domains.ts","../src/commands/cloud/extensions.ts","../src/commands/cloud/settings.ts","../src/commands/cloud/deployments.ts","../src/commands/cloud/power.ts","../src/commands/cloud/debug.ts","../src/commands/cloud/declared-resources.ts","../src/commands/cloud/action-help.ts","../src/commands/cloud/index.ts","../src/commands/apps.ts","../src/upgrade.ts","../src/commands/upgrade.ts","../src/cli.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * This CLI's own version, and the User-Agent built from it.\n *\n * Four call sites used to answer \"what version am I?\" and each answered it\n * differently. `cli.ts` walked one directory up from `__dirname`. `init.ts`\n * walked up looking for a folder literally named `cli`. `bundle.ts` had\n * `resolveCliVersion`, which walked up at most five levels for a manifest whose\n * `name` matched — the only one of the three that was actually correct, and the\n * one the other two did not know existed. Every HTTP request to the control\n * plane answered it not at all, which is the expensive gap: a control plane\n * cannot refuse a CLI that is too old for its wire format if no request ever\n * says which CLI is calling.\n *\n * One answer now, and it is `bundle.ts`'s: walk up for the manifest that names\n * this package, rather than counting directories or matching a folder name.\n * `dist/` is one level down in a published install and two in a source\n * checkout, and a folder called `cli` is not guaranteed to be ours. Two\n * differences from that original — `fileURLToPath` instead of `new\n * URL().pathname`, which is what makes it survive a path containing a space,\n * and no five-level ceiling.\n */\nfunction readVersion(): string {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n const root = path.parse(dir).root;\n while (dir && dir !== root) {\n const manifest = path.join(dir, \"package.json\");\n if (fs.existsSync(manifest)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(manifest, \"utf-8\"));\n if (pkg.name === \"@rebasepro/cli\" && typeof pkg.version === \"string\") return pkg.version;\n } catch {\n // A malformed manifest on the way up is not ours to complain\n // about; keep walking.\n }\n }\n dir = path.dirname(dir);\n }\n return \"unknown\";\n}\n\nlet cached: string | undefined;\n\n/** The CLI's version, or `\"unknown\"` when it cannot be read. Memoized. */\nexport function cliVersion(): string {\n if (cached === undefined) cached = readVersion();\n return cached;\n}\n\n/**\n * `rebase-cli/0.17.3` — sent on every control-plane request.\n *\n * The control plane needs it to answer `CLI_TOO_OLD` with a minimum version\n * instead of failing somewhere further in with a shape error. A client that\n * does not identify itself can only ever be refused generically.\n */\nexport function cliUserAgent(): string {\n return `rebase-cli/${cliVersion()}`;\n}\n","/**\n * Argument parsing for the commands that take positional arguments.\n *\n * Every command in the small group used to parse its own line the same way:\n * `arg(spec, { argv: rawArgs.slice(4), permissive: true })`, then read `_[0]`\n * and `_[1]`. Both halves of that are wrong in a way that costs data.\n *\n * - **`permissive: true` turns an unknown flag into a positional.** `arg`\n * pushes an undeclared flag into `_` as a bare token, so `_[1]` is whatever\n * came second on the line, flag or not. `rebase auth reset-password\n * bob@example.com --debug` set Bob's password to the literal `--debug` — and\n * `--debug` is what `bin/rebase.js` prints after *every* failure as the thing\n * to re-run with, so the single most likely next keystroke after a failed\n * reset was the one that reset the account to a two-word string.\n * - **`slice(4)` assumes the command words are at fixed indices.** They are\n * not: a flag before the command shifts everything, so `rebase --debug auth\n * reset-password bob@example.com NewPass1!` read the email as\n * `reset-password` and the password as `bob@example.com`.\n *\n * So: parse the *whole* line — `rawArgs` is `process.argv` — against a spec\n * strictly, with no permissive mode. `arg` then consumes every flag wherever it\n * appears and rejects the ones nobody declared, which leaves `_` holding the\n * command words followed by the real positionals, in order and at a known\n * offset. An unrecognised flag becomes an error naming the command's help,\n * which is the only safe answer: the alternative is guessing that it was meant\n * as a value.\n *\n * `commands/cloud/index.ts` resolves its positionals against its own spec for\n * the same reason; this is that idea for the commands whose positionals are\n * credentials rather than resource names.\n */\nimport arg from \"arg\";\n\n/**\n * Flags accepted on top of whatever a command declares.\n *\n * `--debug` is read by `bin/rebase.js` off `process.argv` and never by a\n * command, but it has to be *declared* somewhere or strict parsing rejects the\n * exact flag the CLI tells people to add. `--help`/`-h` are answered by each\n * command's dispatcher before any work happens.\n */\nexport const GLOBAL_COMMAND_FLAGS = {\n \"--debug\": Boolean,\n \"--help\": Boolean,\n \"-h\": \"--help\"\n} as const;\n\nexport interface ParsedCommand<S extends arg.Spec> {\n /** The declared flags, as `arg` resolved them. */\n flags: arg.Result<S>;\n /** What is left after the command words — never a flag. */\n positionals: string[];\n /** `--help` or `-h` appeared anywhere on the line. */\n help: boolean;\n}\n\n/** Did the line ask for help? Answered before dispatch, never by a handler. */\nexport function wantsHelp(rawArgs: string[]): boolean {\n return rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\");\n}\n\n/**\n * The command line was wrong — nothing ran, and there is no stack to want.\n *\n * `bin/rebase.js` ends every failure with \"Re-run with --debug for the stack\n * trace.\", which is right when something broke inside a command and absurd for\n * a typo: the stack points at `arg` and this file, neither of which the person\n * who mistyped `--ouput` has any interest in. Worse, `--debug` is a flag, so\n * the suggested next command is *another* command line — and the one thing we\n * have just established is that the command line is what went wrong.\n *\n * Marked with a property rather than left to `instanceof`, because the reader\n * is `bin/rebase.js`: it imports the bundle, so the class object it would test\n * against is not the one this file compiled to.\n */\nexport class UsageError extends Error {\n readonly isUsageError = true;\n\n constructor(message: string) {\n super(message);\n this.name = \"UsageError\";\n }\n}\n\n/**\n * Resolve a command's flags and positionals from the full `process.argv`.\n *\n * `commandWords` is how many words name the command itself — 2 for\n * `auth reset-password`, 1 for `start` — and is applied to the *parsed*\n * positionals rather than to `argv`, so a flag placed before the command no\n * longer shifts them.\n *\n * `command` names the command in error messages, e.g. `auth reset-password`.\n *\n * Throws on an unknown flag, on a positional that looks like a flag, and on\n * more positionals than the command takes. `bin/rebase.js` turns each into a\n * one-line `✗ …` and exit 1.\n */\nexport function parseCommandArgs<S extends arg.Spec>({\n spec,\n rawArgs,\n commandWords,\n command,\n maxPositionals\n}: {\n spec: S;\n rawArgs: string[];\n commandWords: number;\n command: string;\n maxPositionals?: number;\n}): ParsedCommand<S> {\n let parsed: arg.Result<S> & { \"--help\"?: boolean };\n try {\n const merged = {\n ...GLOBAL_COMMAND_FLAGS,\n ...spec\n };\n parsed = arg(merged, { argv: rawArgs.slice(2) }) as arg.Result<S> & { \"--help\"?: boolean };\n } catch (err) {\n if (err instanceof Error && (err as arg.ArgError).code === \"ARG_UNKNOWN_OPTION\") {\n throw new UsageError(\n `${err.message} — run \\`rebase ${command} --help\\` for the options it takes.`\n );\n }\n throw err;\n }\n\n const positionals = parsed._.slice(commandWords);\n\n for (const value of positionals) {\n // Only reachable past a `--` separator or for a bare `-`, since anything\n // else beginning with `-` was either declared or already rejected above.\n // Still refused rather than accepted: a value that looks like a flag is\n // as likely to be a typo as an argument, and one of these positions is a\n // password.\n if (value.startsWith(\"-\")) {\n throw new UsageError(\n `\\`${value}\\` looks like an option, not a value — pass it with an explicit flag ` +\n `(\\`rebase ${command} --help\\`).`\n );\n }\n }\n\n if (maxPositionals !== undefined && positionals.length > maxPositionals) {\n throw new UsageError(\n `rebase ${command} takes ${maxPositionals} argument${maxPositionals === 1 ? \"\" : \"s\"}, ` +\n `got ${positionals.length}: ${positionals.join(\" \")}`\n );\n }\n\n return {\n flags: parsed,\n positionals,\n help: Boolean(parsed[\"--help\"])\n };\n}\n","/**\n * Turning a control-plane failure into something the caller can act on.\n *\n * The control plane talks to Kubernetes, and when Kubernetes refuses it, the\n * refusal travels back verbatim: a whole `Status` object, the request headers,\n * an `audit-id`, an `x-kubernetes-pf-flowschema-uid`. That reached the user's\n * terminal unedited. Two things are wrong with it beyond the noise.\n *\n * The first is that the one sentence that matters is buried in the middle of a\n * JSON blob, so the remedy — if there is one — is the hardest part to find.\n *\n * The second is worse, and is the reason this file exists rather than a\n * `slice(0, 200)`. A `403` naming a `system:serviceaccount:` is a statement\n * about the PLATFORM's own credentials: some role the control plane runs as is\n * missing a grant. Nothing in the user's project can change that — not the\n * collections, not `rebase.json`, not the deploy flags — and the error, printed\n * raw in the middle of `rebase cloud deploy`, reads exactly like a project\n * fault. Someone acting on that reading deletes working code looking for the\n * cause. (That is not hypothetical: three cron jobs were removed from a project\n * to test whether they caused a `cronjobs.batch` 403. They did not.)\n *\n * So this classifies before it summarises, and says whose problem it is.\n */\n\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\n/** What a Kubernetes API refusal carries, once it is found. */\nexport interface KubernetesStatus {\n message?: string;\n reason?: string;\n code?: number;\n details?: { group?: string; kind?: string; name?: string };\n}\n\nexport interface ErrorSummary {\n /** One line, safe to print. Never the raw body. */\n message: string;\n /** A remedy, when one exists — or the reason there is none. */\n hint?: string;\n /** A stable code for `--json` callers to branch on. */\n code: string;\n /**\n * Whether the failure is the platform's rather than the project's.\n *\n * The whole point of the summary: a caller that retries or mutates the\n * project on a platform-side refusal makes things worse, and an agent\n * cannot tell from the prose.\n */\n platform: boolean;\n /** The untouched original, printed only under `--debug`. */\n raw: string;\n}\n\n/**\n * The service accounts a Kubernetes 403 can name, and what each means.\n *\n * `system:serviceaccount:` is the platform's own identity — the control plane's\n * pod, or a tenant's operator. A project cannot grant it anything, because the\n * grant lives in a cluster the project does not own. `system:anonymous` is the\n * same fact with the credential missing entirely.\n */\nconst PLATFORM_PRINCIPAL_RE = /system:(?:serviceaccount:|anonymous|node:)/;\n\n/**\n * A Kubernetes `Status` object embedded anywhere in a message.\n *\n * Scanned for rather than parsed off the front: the control plane wraps it\n * (\"Failed to create the tenant namespace: …\"), the client library appends\n * headers after it, and both halves are worth keeping out of the summary.\n * Balanced-brace scanning rather than a regex, because `details.causes` nests\n * and a lazy `\\{.*?\\}` truncates the object at the first inner brace — which\n * parses to nothing and silently falls through to the raw message.\n */\nexport function extractKubernetesStatus(text: string): KubernetesStatus | undefined {\n for (let start = text.indexOf(\"{\"); start !== -1; start = text.indexOf(\"{\", start + 1)) {\n let depth = 0;\n let inString = false;\n let escaped = false;\n for (let i = start; i < text.length; i++) {\n const ch = text[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (ch === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (ch === '\"') {\n inString = !inString;\n continue;\n }\n if (inString) continue;\n if (ch === \"{\") depth++;\n else if (ch === \"}\") {\n depth--;\n if (depth !== 0) continue;\n const candidate = text.slice(start, i + 1);\n let parsed: unknown;\n try {\n parsed = JSON.parse(candidate);\n } catch {\n break; // Not JSON; try the next opening brace.\n }\n const obj = parsed as Record<string, unknown> & KubernetesStatus;\n // `kind: \"Status\"` is the marker the API server always sets on a\n // refusal. Requiring it means an ordinary JSON body in an error\n // message — a validation report, say — is left alone.\n if (obj?.kind === \"Status\" || (obj?.status === \"Failure\" && typeof obj.code === \"number\")) {\n return {\n message: typeof obj.message === \"string\" ? obj.message : undefined,\n reason: typeof obj.reason === \"string\" ? obj.reason : undefined,\n code: typeof obj.code === \"number\" ? obj.code : undefined,\n details: (obj.details as KubernetesStatus[\"details\"]) ?? undefined\n };\n }\n break;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Strip the transport noise a Kubernetes client appends to its own message.\n *\n * Only ever applied to the fallback path — when no `Status` was found, the\n * message is all there is, and cutting it at the first header keeps the\n * sentence while dropping the `audit-id` and the flowschema uid nobody outside\n * the cluster can use.\n */\nfunction trimTransportNoise(message: string): string {\n const cut = message.search(\n /\\s*(?:headers:|HTTP request failed|audit-id|x-kubernetes-pf-|\\{\"kind\":\"Status\")/i\n );\n const trimmed = (cut > 0 ? message.slice(0, cut) : message).trim();\n return trimmed.replace(/[\\s:,-]+$/, \"\");\n}\n\n/** The longest a summary may be before it stops being one. */\nconst MAX_SUMMARY = 300;\n\n/**\n * One actionable line (plus a hint) from whatever the control plane returned.\n *\n * `status` is the HTTP status of the control-plane call itself, which is a\n * different number from the `code` inside an embedded Kubernetes `Status` — the\n * control plane routinely answers 500 while the cluster answered 403, and it is\n * the inner one that says what happened.\n */\nexport function summarizeError(error: unknown, context: string): ErrorSummary {\n const err = error as { status?: number; message?: string; code?: string };\n const raw = err?.message ?? String(error);\n const k8s = extractKubernetesStatus(raw);\n\n if (k8s) {\n const inner = k8s.message?.trim() ?? \"\";\n const forbidden = k8s.code === 403 || k8s.reason === \"Forbidden\";\n const platform = forbidden && PLATFORM_PRINCIPAL_RE.test(inner);\n\n if (platform) {\n return {\n // Named as the platform's before the sentence that follows, so\n // the first thing read is whose problem it is.\n message: `${context}: the platform's own cluster credentials were refused by Kubernetes.`,\n hint:\n `${truncate(inner)}\\n`\n + \" This is a platform-side permission, not something your project can grant. \"\n + \"Nothing in your code, collections or deploy flags will change it — \"\n + \"report it with the message above rather than retrying or changing the project.\",\n code: \"platform_permission_denied\",\n platform: true,\n raw\n };\n }\n\n return {\n message: `${context}: ${truncate(inner || k8s.reason || \"the cluster refused the request\")}`,\n hint: k8s.code ? `Kubernetes answered ${k8s.code}${k8s.reason ? ` (${k8s.reason})` : \"\"}.` : undefined,\n code: k8s.reason ? `k8s_${k8s.reason.toLowerCase()}` : \"k8s_error\",\n platform: false,\n raw\n };\n }\n\n // Not a Kubernetes refusal. Still worth trimming: the same transport dumps\n // its headers onto plenty of errors that carry no `Status` at all.\n const trimmed = trimTransportNoise(raw);\n return {\n message: `${context}${err?.status ? ` (${err.status})` : \"\"}: ${truncate(trimmed || raw)}`,\n code: err?.code ?? (err?.status ? `http_${err.status}` : \"request_failed\"),\n platform: false,\n raw\n };\n}\n\nfunction truncate(text: string): string {\n const flat = text.replace(/\\s+/g, \" \").trim();\n return flat.length > MAX_SUMMARY ? `${flat.slice(0, MAX_SUMMARY - 1)}…` : flat;\n}\n\n/**\n * Whether the caller asked for the untouched body.\n *\n * `--debug` is already what `bin/rebase.js` prints after every failure as the\n * thing to add, so the raw payload hangs off the flag people are told to reach\n * for rather than off one invented here.\n *\n * The one reader of `REBASE_DEBUG` in the commands, spelled as the bin spells\n * it. It used to be `=== \"1\"` here while the quote fallbacks in `resources.ts`\n * tested the raw string for truthiness, so `=true` hid the body and `=0`\n * printed the fallback.\n */\nexport function wantsRawError(argv: readonly string[] = process.argv): boolean {\n return argv.includes(\"--debug\") || parseEnvBoolean(process.env.REBASE_DEBUG) === true;\n}\n","/**\n * Shared foundation for the `rebase cloud` command family.\n *\n * Everything cloud subcommands need in common lives here:\n * - credential storage (~/.rebase/credentials.json, keyed per control-plane host)\n * - project link file (.rebase/cloud.json in the project dir)\n * - control-plane URL resolution\n * - an authenticated `@rebasepro/client` instance (createCloudClient / requireClient)\n * - small output helpers shared across subcommands\n *\n * The control plane is itself a Rebase app, so we reuse the same SDK the web\n * console uses (`@rebasepro/client`). Auth, token refresh, the data REST client\n * and function invocation all come from the SDK — the CLI only supplies a\n * file-backed AuthStorage so a login persists across invocations.\n */\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport { spawn } from \"child_process\";\nimport chalk from \"chalk\";\nimport arg from \"arg\";\nimport inquirer from \"inquirer\";\nimport { createRebaseClient, type AuthStorage } from \"@rebasepro/client\";\nimport { findProjectRoot } from \"../../utils/project\";\nimport { parseCommandArgs } from \"../../utils/args\";\nimport { cliUserAgent } from \"../../utils/version\";\nimport { summarizeError, wantsRawError } from \"./errors\";\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\n/* ═══════════════════════════════════════════════════════════════\n Constants & paths\n ═══════════════════════════════════════════════════════════════ */\n\n/** Default hosted control plane (the Rebase Cloud console origin). */\nconst DEFAULT_CLOUD_URL = \"https://app.rebase.pro\";\n\n/** The storage key the SDK's auth module reads/writes the session under. */\nconst SDK_SESSION_KEY = \"rebase_auth\";\n\n/** ~/.rebase/credentials.json — one file, many hosts. */\nfunction credentialsPath(): string {\n return path.join(os.homedir(), \".rebase\", \"credentials.json\");\n}\n\n/** Project-local link file: <project>/.rebase/cloud.json */\n/**\n * The billing account an organization row points at, whichever key it arrived under.\n *\n * REST serves every column under its own property name, so the relation comes\n * back as `billingAccountId`. Both readers in this CLI checked\n * `billing_account_id` and `billingAccount` — neither is what arrives — so\n * `rebase cloud billing` answered \"no billing account\" for every organization,\n * and the deploy pre-check never saw an internal plan. The other two spellings\n * are still accepted: older servers and fixtures send them.\n */\nexport function billingAccountIdOf(org: unknown): string | number | undefined {\n if (typeof org !== \"object\" || org === null) return undefined;\n for (const key of [\"billingAccountId\", \"billing_account_id\", \"billingAccount\"]) {\n const value = (org as Record<string, unknown>)[key];\n if (typeof value === \"string\" || typeof value === \"number\") return value;\n }\n return undefined;\n}\n\nexport function projectLinkPath(cwd: string = process.cwd()): string {\n const root = findProjectRoot(cwd) || cwd;\n return path.join(root, \".rebase\", \"cloud.json\");\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Credentials file model\n ═══════════════════════════════════════════════════════════════\n\n {\n \"current\": \"https://app.rebase.pro\",\n \"contexts\": {\n \"https://app.rebase.pro\": { \"auth\": \"<sdk session json>\", \"org\": \"42\" }\n }\n }\n*/\n\ninterface CloudContextEntry {\n /** Raw JSON blob the SDK auth module persists (the RebaseSession). */\n auth?: string;\n /** Active organization id for this host, if the user selected one. */\n org?: string;\n}\n\ninterface CredentialsFile {\n current?: string;\n contexts: Record<string, CloudContextEntry>;\n}\n\nfunction readCredentials(): CredentialsFile {\n try {\n const raw = fs.readFileSync(credentialsPath(), \"utf-8\");\n const parsed = JSON.parse(raw) as CredentialsFile;\n if (!parsed.contexts) parsed.contexts = {};\n return parsed;\n } catch {\n return { contexts: {} };\n }\n}\n\nfunction writeCredentials(data: CredentialsFile): void {\n const file = credentialsPath();\n fs.mkdirSync(path.dirname(file), { recursive: true });\n // Written with private perms — this file holds refresh tokens.\n fs.writeFileSync(file, JSON.stringify(data, null, 2), { mode: 0o600 });\n try {\n fs.chmodSync(file, 0o600);\n } catch {\n // best effort on platforms without chmod semantics\n }\n}\n\n/** Host that a bare `rebase cloud` command should target, if any. */\nfunction currentContextUrl(): string | undefined {\n return readCredentials().current;\n}\n\n/** Persist the active organization id for a host. */\nexport function setContextOrg(url: string, org: string | undefined): void {\n const creds = readCredentials();\n const entry = creds.contexts[url] || {};\n if (org) entry.org = org;\n else delete entry.org;\n creds.contexts[url] = entry;\n writeCredentials(creds);\n}\n\nexport function getContextOrg(url: string): string | undefined {\n return readCredentials().contexts[url]?.org;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n File-backed AuthStorage (per host)\n ═══════════════════════════════════════════════════════════════ */\n\nfunction createFileAuthStorage(url: string): AuthStorage {\n return {\n getItem(key) {\n if (key !== SDK_SESSION_KEY) return null;\n return readCredentials().contexts[url]?.auth ?? null;\n },\n setItem(key, value) {\n if (key !== SDK_SESSION_KEY) return;\n const creds = readCredentials();\n const entry = creds.contexts[url] || {};\n entry.auth = value;\n creds.contexts[url] = entry;\n if (!creds.current) creds.current = url;\n writeCredentials(creds);\n },\n removeItem(key) {\n if (key !== SDK_SESSION_KEY) return;\n const creds = readCredentials();\n if (creds.contexts[url]) {\n delete creds.contexts[url].auth;\n delete creds.contexts[url].org;\n }\n writeCredentials(creds);\n }\n };\n}\n\n/** Mark a host as the active context (called on login). */\nexport function setCurrentContext(url: string): void {\n const creds = readCredentials();\n creds.current = url;\n if (!creds.contexts[url]) creds.contexts[url] = {};\n writeCredentials(creds);\n}\n\n/* ═══════════════════════════════════════════════════════════════\n URL resolution\n ═══════════════════════════════════════════════════════════════\n\n Priority: --url flag > REBASE_CLOUD_URL env > CLOUD link's url\n > stored current context > default hosted URL.\n\n A **direct** link is deliberately absent from that list; see below.\n*/\n\n/**\n * Where the control-plane URL came from. `link` is the one a repository chose\n * rather than the user — see {@link isKnownControlPlane}.\n */\nexport type CloudUrlSource = \"flag\" | \"env\" | \"link\" | \"context\" | \"default\";\n\nexport function resolveCloudUrl(rawArgs: string[]): string {\n return resolveCloudTarget(rawArgs).url;\n}\n\n/** The control-plane URL, and which rung of the ladder above supplied it. */\nexport function resolveCloudTarget(rawArgs: string[]): { url: string; source: CloudUrlSource } {\n const parsed = arg({ \"--url\": String }, { argv: rawArgs.slice(2),\npermissive: true });\n if (parsed[\"--url\"]) return { url: normalizeUrl(parsed[\"--url\"]),\nsource: \"flag\" };\n if (process.env.REBASE_CLOUD_URL) return { url: normalizeUrl(process.env.REBASE_CLOUD_URL),\nsource: \"env\" };\n\n const link = readLink();\n /*\n * A direct link is a tenant, not a control plane.\n *\n * `rebase cloud link <url>` points this checkout at ONE running Rebase API\n * — \"no control plane, no login\", as its own help page puts it — so its URL\n * is the customer's own backend. Returning it here made it the control\n * plane for the entire `cloud` family: `whoami` reported \"Not logged in to\n * https://api.example.com\", and following that printed remedy POSTed the\n * user's *control-plane* email and password to the tenant host.\n *\n * Commands that genuinely need a control plane refuse instead — see\n * `refuseDirectLink`, which every one of them reaches through\n * `requireClient` (and `login`, which builds its client directly).\n */\n if (link?.url && link.mode !== \"direct\") return { url: normalizeUrl(link.url),\nsource: \"link\" };\n\n const current = currentContextUrl();\n if (current) return { url: normalizeUrl(current),\nsource: \"context\" };\n\n return { url: DEFAULT_CLOUD_URL,\nsource: \"default\" };\n}\n\n/**\n * Whether a control-plane host is one the user chose: the platform's own, or a\n * host already in their credentials file because they signed in to it.\n *\n * A link file is part of the repository, and a cloned repository is not the\n * user's to trust with their password. `login` asks before sending one to a\n * linked host that is neither.\n */\nexport function isKnownControlPlane(url: string): boolean {\n return url === DEFAULT_CLOUD_URL || Object.hasOwn(readCredentials().contexts, url);\n}\n\n/**\n * Refuse to run a control-plane command in a directory linked straight at a\n * backend.\n *\n * The alternative — quietly using the default control plane — would be worse\n * than the bug it replaces: the user asked for `https://api.example.com` and\n * would get an answer about `app.rebase.pro` with nothing saying so. Naming the\n * link, and both ways out of it, is the whole message.\n *\n * `--project` and `--url` are the ways out, so a line carrying either passes\n * through: both say, explicitly, which control-plane subject the caller means.\n */\nexport function refuseDirectLink(rawArgs: string[]): void {\n const link = readLink();\n if (link?.mode !== \"direct\") return;\n\n const parsed = arg(\n { \"--project\": String,\n\"-p\": \"--project\",\n\"--url\": String },\n { argv: rawArgs.slice(2),\npermissive: true }\n );\n if (parsed[\"--project\"] || parsed[\"--url\"]) return;\n\n fail(\n `This directory is linked directly to ${chalk.cyan(link.url)} — `\n + `${chalk.bold(\"rebase cloud unlink\")} first, or pass ${chalk.bold(\"--project\")}.`,\n \"A direct link is one backend, not a control plane: it has no projects, no organizations and no session.\",\n \"direct_link\"\n );\n}\n\nfunction normalizeUrl(url: string): string {\n let u = url.trim().replace(/\\/+$/, \"\");\n if (!/^https?:\\/\\//.test(u)) u = `https://${u}`;\n return u;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Rebase client factory + auth guard\n ═══════════════════════════════════════════════════════════════ */\n\nexport type CloudClient = ReturnType<typeof createRebaseClient>;\n\n/**\n * Build an SDK client bound to a control-plane host, backed by the on-disk\n * credential store. `autoRefresh` is disabled so we never leave a dangling\n * setTimeout that keeps the CLI process alive; token refresh is done on demand\n * by `requireClient`.\n */\nexport function createCloudClient(url: string): CloudClient {\n return createRebaseClient({\n baseUrl: url,\n // No cloud subcommand needs a socket. The one that looks like it might —\n // `logs -f` — polls `deployments.findById` on a timer (see\n // `streamBuildLogs`), so nothing here ever opens a channel or an\n // `observe()`.\n //\n // This used to say `websocketUrl: \"\"` and mean the same thing. It stopped\n // meaning it when the client grew a diagnostic for the case it produces:\n // realtime is on unless you switch it off, so \"on, with no usable URL\"\n // reads as a misconfiguration and warns. The warning is right — and it\n // was firing on every single `rebase cloud` invocation, telling the user\n // to fix the CLI's own client construction, in prose they had no way to\n // act on. `realtime: false` is the escape it names: it is the difference\n // between \"no socket, because I never asked for one\" and \"no socket, and\n // I do not know why\".\n realtime: false,\n // Every control-plane request says which CLI is calling. The control\n // plane's wire format moves ahead of what is published to npm, so it\n // has to be able to answer an old client with `CLI_TOO_OLD` and the\n // minimum version — and it cannot do that for a caller that never\n // identified itself. Until this line, none of them did.\n headers: { \"User-Agent\": cliUserAgent() },\n auth: {\n storage: createFileAuthStorage(url),\n persistSession: true,\n autoRefresh: false\n }\n });\n}\n\n/** Two minutes of head-room before a token is treated as expired. */\nconst EXPIRY_BUFFER_MS = 120_000;\n\n/** The half of a client that holds its session — all {@link freshAccessToken} reads. */\nexport interface SessionHolder {\n auth: {\n getSession(): { accessToken: string; expiresAt: number } | null;\n refreshSession(): Promise<{ accessToken: string }>;\n };\n}\n\n/**\n * An access token with time left on it, refreshed first if it is close to\n * expiry. Rejects when there is no session, or it cannot be refreshed.\n *\n * For the requests the SDK does not make itself. Its own calls refresh and\n * retry on a 401; a raw `fetch` or a tunnel handshake presents whatever token\n * it was handed, and `createCloudClient` never refreshes in the background. A\n * token read once at the start of a command that runs for longer than it\n * lives — a deploy's build, a `db connect` left open — is refused by the time\n * it is used, so it is read here at the moment it is sent.\n */\nexport async function freshAccessToken(client: SessionHolder): Promise<string> {\n const session = client.auth.getSession();\n if (session?.accessToken && session.expiresAt > Date.now() + EXPIRY_BUFFER_MS) return session.accessToken;\n return (await client.auth.refreshSession()).accessToken;\n}\n\n/**\n * Return an authenticated client for the resolved host, refreshing the access\n * token if it is close to expiry. Exits with a helpful message when there is no\n * usable session (never logged in, or the refresh token was revoked).\n */\nexport async function requireClient(rawArgs: string[]): Promise<{ client: CloudClient; url: string }> {\n // Before anything else: everything downstream of here is a control-plane\n // call, and a direct-linked directory has no control plane to make it\n // against.\n refuseDirectLink(rawArgs);\n const url = resolveCloudUrl(rawArgs);\n const client = createCloudClient(url);\n const session = client.auth.getSession();\n\n if (!session || !session.accessToken) {\n fail(\n `Not logged in to ${chalk.cyan(url)}.`,\n `Run ${chalk.bold(\"rebase cloud login\")} first.`,\n \"not_logged_in\"\n );\n }\n\n if (session.expiresAt <= Date.now() + EXPIRY_BUFFER_MS) {\n try {\n await client.auth.refreshSession();\n } catch {\n fail(\n `Your session for ${chalk.cyan(url)} has expired.`,\n `Run ${chalk.bold(\"rebase cloud login\")} to sign in again.`,\n // Distinct from `not_logged_in`: a caller retrying on a stale\n // session should re-authenticate, not conclude it was never set\n // up. Same remedy, different diagnosis.\n \"session_expired\"\n );\n }\n }\n\n return { client,\nurl };\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Platform configuration\n ═══════════════════════════════════════════════════════════════ */\n\n/** One place a deploy can actually land, as the control plane describes it. */\nexport interface DeployTarget {\n clusterId?: string | null;\n provider: string;\n region?: string;\n label?: string;\n baseDomain?: string;\n}\n\nexport interface PlatformConfig {\n tenantBaseDomain?: string;\n deployTargets?: DeployTarget[];\n}\n\n/**\n * The control plane's public, non-secret self-description (`platform-config`).\n *\n * None of it is knowable from the CLI side: it is per-deployment configuration —\n * production serves tenants at `rebase.website` on GKE, a dev control plane at\n * `localhost` on Docker. Guessing produced two separate lies: a congratulation\n * URL that resolved nowhere near the app, and a `provider` the project does not\n * run on (see `createProject`).\n *\n * Cached per host for the process: it is fixed for a control plane's lifetime,\n * and `projects list` formats one host per row off a single fetch.\n *\n * @returns the config, or `undefined` if the control plane doesn't serve\n * `platform-config` (an older deployment) or the request failed. A failure is\n * cached too — a short-lived CLI should not retry once per row. Note the\n * distinction callers rely on: `undefined` means \"this control plane cannot\n * tell us\", whereas `deployTargets: []` is a control plane stating that it has\n * no infrastructure configured.\n */\nconst platformConfigCache = new Map<string, Promise<PlatformConfig | undefined>>();\n\nexport function fetchPlatformConfig(client: CloudClient, url: string): Promise<PlatformConfig | undefined> {\n let pending = platformConfigCache.get(url);\n if (!pending) {\n pending = client.functions\n .invoke<PlatformConfig>(\"platform-config\", undefined, { method: \"GET\" })\n .then((cfg) => cfg ?? undefined)\n .catch(() => undefined);\n platformConfigCache.set(url, pending);\n }\n return pending;\n}\n\n/**\n * The base domain tenant projects are served at, derived from the same\n * TENANT_BASE_DOMAIN the ingress and the console read (see\n * saas/backend/src/utils/tenant-domain.ts).\n */\nexport function fetchTenantBaseDomain(client: CloudClient, url: string): Promise<string | undefined> {\n return fetchPlatformConfig(client, url).then((cfg) => cfg?.tenantBaseDomain?.trim() || undefined);\n}\n\n/**\n * The infrastructure a deploy for this control plane would ACTUALLY use, in the\n * resolver's own preference order (saas/backend/src/k8s/resolve.ts).\n *\n * @returns the targets, or `undefined` when the control plane cannot say.\n */\nexport function fetchDeployTargets(client: CloudClient, url: string): Promise<DeployTarget[] | undefined> {\n return fetchPlatformConfig(client, url).then((cfg) =>\n Array.isArray(cfg?.deployTargets) ? cfg.deployTargets : undefined\n );\n}\n\n/**\n * Public host for a project — `<subdomain>.<base>`, or the bare subdomain when\n * the base domain is unknown.\n *\n * It deliberately never falls back to a guessed domain. The user copies this\n * string into a browser, so a plausible-but-wrong hostname is worse than an\n * obviously incomplete one: `acme.rebase.pro` looks reachable and isn't, while\n * `acme` reads as \"the subdomain is acme\" and prompts no wasted debugging.\n */\nexport function formatTenantHost(\n subdomain: string | undefined,\n baseDomain: string | undefined\n): string | undefined {\n if (!subdomain) return undefined;\n return baseDomain ? `${subdomain}.${baseDomain}` : subdomain;\n}\n\n/** The fields of a project row this module needs to render a host. */\nexport interface HostableProject {\n subdomain?: string;\n /** Resolved server-side; absent on control planes older than the host hook. */\n host?: string;\n}\n\n/**\n * The host to display for a project.\n *\n * Prefers `host` off the record: the control plane resolves it through the same\n * `tenantHost()` the ingress uses, so it accounts for the project's *cluster*\n * base domain. The CLI cannot compute that itself — `clusters` is admin-only\n * under RLS, so a normal user's token cannot read `baseDomain`, and a project on\n * a second cluster is served somewhere the platform default does not name.\n *\n * `baseDomain` (from `platform-config`) remains the fallback for a control plane\n * that predates the hook — right for the single-cluster case, which is every\n * project today.\n */\nexport function projectHost(\n project: HostableProject,\n baseDomain: string | undefined\n): string | undefined {\n return project.host || formatTenantHost(project.subdomain, baseDomain);\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Project link file (.rebase/cloud.json)\n ═══════════════════════════════════════════════════════════════ */\n\nexport interface ProjectLink {\n url: string;\n projectId: string;\n /** The project's subdomain — the slug users see in console URLs and type into --project. */\n slug?: string;\n projectName?: string;\n orgId?: string;\n /**\n * Base URL of the project's own API.\n *\n * For a cloud project this is a convenience derived from the subdomain. For\n * a **self-hosted** project it is the entire link: there is no control plane\n * to look anything up in, so `projectId` is empty and this is what commands\n * resolve against.\n *\n * Keeping both kinds of link in one file is deliberate. A second link file\n * for self-hosting would fork every command that reads one, and the tooling\n * would drift into being cloud-only by accident.\n */\n apiUrl?: string;\n /**\n * How this checkout is linked. Absent means `cloud` — which is every link\n * written before this field existed.\n */\n mode?: \"cloud\" | \"direct\";\n}\n\nexport function readLink(cwd: string = process.cwd()): ProjectLink | null {\n try {\n return JSON.parse(fs.readFileSync(projectLinkPath(cwd), \"utf-8\")) as ProjectLink;\n } catch {\n return null;\n }\n}\n\nexport function writeLink(link: ProjectLink, cwd: string = process.cwd()): void {\n const file = projectLinkPath(cwd);\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(file, JSON.stringify(link, null, 2));\n}\n\nexport function removeLink(cwd: string = process.cwd()): boolean {\n const file = projectLinkPath(cwd);\n if (fs.existsSync(file)) {\n fs.rmSync(file);\n return true;\n }\n return false;\n}\n\n/**\n * Flags that may appear anywhere on a `rebase cloud` line, including *before*\n * the resource group.\n *\n * They have to be declared wherever positionals are resolved, because `arg`'s\n * `permissive: true` does not merely tolerate an undeclared flag — it pushes it\n * into `_` alongside the positionals, and for a flag that takes a value it\n * pushes the value in too. So `cloud --project acme storage create` parsed\n * without this spec yields `_` of `[\"--project\", \"acme\", \"storage\", \"create\"]`,\n * and the group reads as `\"acme\"`: a real project name, in the group position,\n * dispatching to nothing. Skipping tokens that start with `-` does not save you\n * there — the damage is the orphaned value, which looks exactly like a\n * positional.\n *\n * Only genuinely global flags belong here. Group-specific ones (`--bucket`,\n * `--region`, …) are declared by the handler that owns them and always follow\n * the group, so they cannot shift the group or action.\n *\n * `-p` is `--project` in eighteen places and `--password` in `login`. That\n * ambiguity does not matter to the one caller that reads this spec: it resolves\n * positionals and never looks at a flag's value, so all it needs to know is\n * that `-p` takes one. Anything that wants the value must keep declaring it\n * itself, with the meaning its own command gives it.\n */\nexport const GLOBAL_CLOUD_FLAGS = {\n \"--json\": Boolean,\n \"--yes\": Boolean,\n \"--help\": Boolean,\n \"--project\": String,\n /* `resolveCloudUrl` reads this off the raw line for EVERY command in the\n family — it is the first entry in the URL priority list — so a strict\n parse that did not declare it would reject a flag the CLI itself honours\n on the command being parsed. */\n \"--url\": String,\n \"-p\": \"--project\",\n \"-y\": \"--yes\",\n \"-h\": \"--help\"\n} as const;\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/**\n * The raw project reference to operate on: explicit `--project` flag wins,\n * otherwise the linked project. Exits with guidance when neither is present.\n * The value is a slug (the project's subdomain, as shown in console URLs) or,\n * for old scripts and link files, a raw project UUID.\n */\nexport function requireProjectRef(rawArgs: string[]): string {\n const parsed = arg({ \"--project\": String,\n\"-p\": \"--project\" }, { argv: rawArgs.slice(2),\npermissive: true });\n if (parsed[\"--project\"]) return parsed[\"--project\"];\n const link = readLink();\n if (link?.projectId) return link.projectId;\n fail(\n \"No project specified and this directory is not linked.\",\n `Pass ${chalk.bold(\"--project <slug>\")} or run ${chalk.bold(\"rebase cloud link\")}.`,\n \"no_project\"\n );\n}\n\n/**\n * Resolve a project reference — slug or UUID — to the internal id the API\n * takes, or undefined when no such project is visible. Slugs cost one lookup;\n * UUIDs pass through untouched so linked directories and old scripts skip the\n * round-trip.\n */\nexport async function lookupProjectId(ref: string, client: CloudClient): Promise<string | undefined> {\n if (UUID_RE.test(ref)) return ref;\n const res = await client.data.collection(\"projects\").find({\n where: { subdomain: [\"==\", ref] },\n limit: 1\n });\n const row = res.data[0] as { id?: string | number } | undefined;\n return row?.id === undefined ? undefined : String(row.id);\n}\n\n/** Like `lookupProjectId`, but exits with guidance when the ref matches nothing. */\nexport async function resolveProjectRef(ref: string, client: CloudClient): Promise<string> {\n const id = await lookupProjectId(ref, client);\n if (id === undefined) {\n fail(\n `No project with slug ${chalk.bold(ref)}.`,\n `List yours with ${chalk.bold(\"rebase cloud projects\")}.`,\n \"project_not_found\"\n );\n }\n return id;\n}\n\n/** `requireProjectRef` + `resolveProjectRef` in one step. */\nexport async function requireProject(rawArgs: string[], client: CloudClient): Promise<string> {\n return resolveProjectRef(requireProjectRef(rawArgs), client);\n}\n\n/**\n * The project reference to SHOW: the slug the user typed or the linked slug.\n * Never resolves — for human output only. Old link files predate `slug` and\n * fall back to the stored id.\n */\nexport function displayProjectRef(rawArgs: string[]): string {\n const parsed = arg({ \"--project\": String,\n\"-p\": \"--project\" }, { argv: rawArgs.slice(2),\npermissive: true });\n if (parsed[\"--project\"]) return parsed[\"--project\"];\n const link = readLink();\n return link?.slug || link?.projectId || \"\";\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Machine-readable output mode\n ═══════════════════════════════════════════════════════════════\n\n Rebase is built for agents, and the CLI is their primary interface. An agent\n must never scrape a colorized table, so every cloud command can emit a single\n JSON value instead of human output.\n\n JSON mode is on when ANY of these hold:\n • `--json` was passed,\n • `REBASE_JSON=1` is set, or\n • stdout is not a TTY (piped/redirected — i.e. a program is reading it).\n\n In JSON mode a command prints exactly one JSON value to stdout and nothing\n else; errors print `{\"error\":{...}}` and exit non-zero. The mode is a\n process-global set once, at dispatch, by `initOutputMode` — every helper here\n (fail, reportError, emit) reads it so the whole family is consistent.\n\n ── The stream contract ─────────────────────────────────────────────────────\n\n The mode decides the SHAPE of the result. It does not decide which stream\n anything lands on; that rule is fixed and holds in both modes:\n\n stdout the command's result, and nothing else — one human rendering or\n one JSON value. A caller may redirect it into a parser.\n stderr everything that is not the result: progress, advice, warnings,\n errors, and the interactive prompts.\n\n Nothing is written to both. That is the whole rule, and it is worth stating\n because the family drifted off it in a way that reads as a bug in the report\n itself: a warning from the SDK went to stderr while the report went to\n stdout, so `whoami 2>&1` interleaved two unrelated voices and the header\n looked like it had been printed twice.\n\n The practical consequence for a new command: the ONLY things that may call\n `console.log` are inside an `emit` human closure. Progress and next-step\n advice go through `note`, cautions through `warn`, outcomes through\n `success` — all of which write to stderr. `keyValues` prints result rows and\n so stays on stdout, which is why it belongs inside the `emit` closure too.\n*/\n\nlet JSON_MODE = false;\n\n/**\n * Resolve and latch the output mode for this invocation. Call once at the top of\n * `cloudCommand`, before anything can print or `fail`. Returns the resolved mode\n * (handy for tests, which otherwise leave it at its `false` default).\n */\nexport function initOutputMode(rawArgs: string[]): boolean {\n const parsed = arg({ \"--json\": Boolean }, { argv: rawArgs.slice(2),\npermissive: true });\n // Most explicit wins. `REBASE_JSON=0` is the half that was missing: the\n // \"stdout is not a TTY\" rule is right for a result, and wrong for the reader\n // who ran `rebase cloud env --help | less` and got a JSON object. There was\n // no way to say so — `--json` could only turn the mode ON, and `REBASE_JSON`\n // was tested against \"1\" alone, so any other value including \"0\" fell\n // through to the TTY test and set it anyway. Any spelling of yes or no now\n // decides; only an unset or unrecognised value leaves it to the TTY.\n if (parsed[\"--json\"]) JSON_MODE = true;\n else JSON_MODE = parseEnvBoolean(process.env.REBASE_JSON) ?? process.stdout.isTTY !== true;\n return JSON_MODE;\n}\n\n/** Whether the current invocation is emitting machine-readable JSON. */\nexport function isJsonMode(): boolean {\n return JSON_MODE;\n}\n\n/** Force the mode (tests only — production latches it via `initOutputMode`). */\nexport function setJsonModeForTest(value: boolean): void {\n JSON_MODE = value;\n}\n\n/** Strip ANSI colour codes — JSON output must never carry terminal escapes. */\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\u001b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, \"\");\n}\n\n/**\n * Write one JSON value to stdout, followed by a newline.\n *\n * Indented, because the overwhelmingly common reader is a person or an agent\n * looking at a terminal — JSON mode is entered automatically whenever stdout is\n * not a TTY, so `rebase cloud deployments list` piped anywhere at all produced\n * a project's entire deployment history as one unwrapped line. `JSON.parse`\n * does not care about the whitespace; everything else does.\n */\nexport function printJson(value: unknown): void {\n process.stdout.write(JSON.stringify(value, null, 2) + \"\\n\");\n}\n\n/**\n * The one output primitive every new command uses: in JSON mode emit `json`\n * (and nothing else); otherwise run `human`. Keeping the two behind a single\n * call is what guarantees a command can never print a table AND a JSON blob.\n */\nexport function emit<T>(human: () => void, json: JsonArg<T>): void {\n if (JSON_MODE) printJson(json);\n else human();\n}\n\n/**\n * The JSON payload, which must be a value and not a producer of one.\n *\n * `json: unknown` accepted a function without complaint, and four call sites in\n * `resources.ts` passed `() => ({ … })` — mirroring the human argument beside\n * it, which *is* a thunk. In JSON mode `printJson` then stringified a function,\n * which is `undefined`. So `rebase cloud compute`, `compute set` and two\n * cluster commands printed the single word `undefined` on every piped or\n * `--json` run — and since this family forces JSON mode off a TTY, that is\n * every scripted use of them.\n *\n * Typed so the mistake cannot be made again: a function resolves the parameter\n * to `never`, and the call site fails to compile.\n */\nexport type JsonArg<T> = T extends (...args: never[]) => unknown ? never : T;\n\n/**\n * Print a help page — the human one, or a machine-readable description of the\n * same command in JSON mode.\n *\n * `--help` is the one place where \"stdout is not a TTY\" is a weak signal: a\n * person runs `rebase cloud db --help | less` and wants the page. But the rule\n * this family promises is that stdout carries one JSON value whenever it is not\n * a terminal, and a help page is the easiest possible thing to describe\n * structurally — so rather than carve out an exception, help answers the same\n * question in the reader's own language. For an agent, `--help` piped is then a\n * discovery call rather than 60 lines of ANSI to scrape.\n *\n * `env` shipped this shape first, alone; this generalises it so every group\n * answers the same way.\n */\nexport function emitHelp(\n command: string,\n actions: Array<string | HelpAction>,\n human: () => void,\n extra: Record<string, unknown> = {}\n): void {\n emit(human, { command,\nactions: actions.map(entry => describeAction(entry, command)),\n...extra });\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Group help pages\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * One action on a group's help page.\n *\n * The page used to exist twice: a hand-formatted template literal for a\n * terminal, and a bare list of action WORDS for everything else. So the two\n * answers to `--help` were not the same answer — piped, `rebase cloud env\n * --help` said `[\"list\",\"set\",\"unset\",\"reveal\",\"pull\"]` and not one description,\n * not one flag, and not the sentence about build-time variables that is the\n * whole reason the page exists. This family forces JSON mode off a TTY, so that\n * was every scripted and every agent-driven read of it.\n *\n * One description, rendered twice.\n */\nexport interface HelpAction {\n /** The action word: `set`, `backup restore`. */\n action: string;\n /** The usage tail after the word: `KEY=VALUE`, `<domain>`, `[-y]`. */\n args?: string;\n /** One line: what it does. */\n description: string;\n /** Flags this action takes of its own, `[flag, description]`. */\n flags?: Array<[string, string]>;\n /** The heading it sits under, on a page that groups its actions. */\n section?: string;\n}\n\n/** A whole group page — `rebase cloud env --help`. */\nexport interface GroupHelp {\n /** The command words, no leading `rebase`: `cloud env`, or `cloud` itself. */\n command: string;\n /** The title's tail: \"Environment variables\". */\n title: string;\n actions: HelpAction[];\n /** Options that belong to the group rather than to one action. */\n options?: Array<[string, string]>;\n /** Closing paragraphs — the things a reader gets wrong more than once. */\n notes?: string[];\n}\n\n/**\n * Normalise an action for the JSON form. Strings stay legal — the index page\n * lists group names, which are not actions of the command being described.\n *\n * `command` is the page's own command (`cloud env`), so the usage line a caller\n * reads is a line it can run: without it the answer said `rebase cloud set\n * KEY=VALUE`, which is a command that does not exist.\n */\nfunction describeAction(entry: string | HelpAction, command: string): Record<string, unknown> {\n if (typeof entry === \"string\") return { action: entry,\ndescription: \"\",\nflags: [] };\n return {\n action: entry.action,\n usage: `rebase ${command} ${entry.action}${entry.args ? ` ${entry.args}` : \"\"}`,\n description: entry.description,\n flags: (entry.flags ?? []).map(([flag, description]) => ({ flag,\ndescription }))\n };\n}\n\n/**\n * Flags every cloud command accepts, documented once.\n *\n * Lives here rather than in `action-help.ts` because both help renderers print\n * it and `action-help` imports this module, not the other way round.\n */\nexport const GLOBAL_HELP_FLAGS: Array<[string, string]> = [\n [\"--project, -p <slug>\", \"Operate on a project without linking this directory\"],\n [\"--json\", \"Machine-readable output (also when piped, or REBASE_JSON=1)\"],\n [\"--url <origin>\", \"Target a specific control plane (or REBASE_CLOUD_URL)\"],\n [\"--yes, -y\", \"Skip confirmation prompts\"],\n [\"--debug\", \"Print the untouched error body after a failure\"]\n];\n\n/**\n * Flag names `parseCloudArgs` adds to every command in the family.\n *\n * Derived from `GLOBAL_CLOUD_FLAGS` rather than listed again — a second copy is\n * how a global gains a spelling that the collision sweep does not know about.\n * `--debug` is the one addition: `bin/rebase.js` takes it off `process.argv`\n * itself, so no cloud spec declares it and every command still accepts it.\n */\nexport const GLOBAL_SPEC_KEYS = new Set([...Object.keys(GLOBAL_CLOUD_FLAGS), \"--debug\"]);\n\n/** Column width for an action word (+ its args) before its description. */\nconst HELP_COLUMN = 28;\n\n/**\n * The gap after `text` in a `width`-wide column, never less than one space.\n *\n * `padEnd` returns the string unchanged when it is already at the width, which\n * glues the description onto the flag: `--connection-string <url>The external…`.\n */\nfunction pad(text: string, width: number): string {\n return \" \".repeat(Math.max(1, width - text.length));\n}\n\n/**\n * Print a group's page — the human one, and the same content as JSON when piped.\n */\nexport function printGroupHelp(page: GroupHelp): void {\n emitHelp(\n page.command,\n page.actions,\n () => {\n console.log(\"\");\n console.log(`${chalk.bold(`rebase ${page.command}`)} — ${page.title}`);\n console.log(\"\");\n console.log(chalk.green.bold(\"Usage\"));\n console.log(` rebase ${page.command} ${chalk.blue(\"<action>\")} [options]`);\n\n let section: string | undefined;\n for (const entry of page.actions) {\n const heading = entry.section ?? \"Commands\";\n if (heading !== section) {\n section = heading;\n console.log(\"\");\n console.log(chalk.green.bold(heading));\n }\n const word = `${entry.action}${entry.args ? ` ${entry.args}` : \"\"}`;\n console.log(\n ` ${chalk.blue.bold(entry.action)}${entry.args ? ` ${chalk.gray(entry.args)}` : \"\"}`\n + `${pad(word, HELP_COLUMN)}${entry.description}`\n );\n for (const [flag, description] of entry.flags ?? []) {\n console.log(` ${chalk.blue(flag)}${pad(flag, HELP_COLUMN - 4)}${chalk.gray(description)}`);\n }\n }\n\n if (page.options?.length) {\n console.log(\"\");\n console.log(chalk.green.bold(\"Options\"));\n for (const [flag, description] of page.options) {\n console.log(` ${chalk.blue(flag)}${pad(flag, HELP_COLUMN)}${description}`);\n }\n }\n\n console.log(\"\");\n console.log(chalk.green.bold(\"Global options\"));\n for (const [flag, description] of GLOBAL_HELP_FLAGS) {\n console.log(` ${chalk.blue(flag)}${pad(flag, HELP_COLUMN)}${chalk.gray(description)}`);\n }\n\n if (page.notes?.length) {\n console.log(\"\");\n for (const note of page.notes) console.log(chalk.gray(` ${note}`));\n }\n console.log(\"\");\n },\n {\n usage: `rebase ${page.command} <action> [options]`,\n summary: page.title,\n options: (page.options ?? []).map(([flag, description]) => ({ flag,\ndescription })),\n globalFlags: GLOBAL_HELP_FLAGS.map(([flag, description]) => ({ flag,\ndescription })),\n notes: page.notes ?? []\n }\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Output helpers\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Print a warning (+ optional hint) — in every output mode, always to stderr.\n *\n * `emit` is for a command's *result*, and JSON mode legitimately replaces the\n * human rendering of one. A warning is not a result: it says the command is\n * about to do something the caller may not have meant, and that is exactly as\n * true when the output is piped. Gating one on `!isJsonMode()` deleted it\n * precisely where nobody was watching the terminal — a `--source` deploy ejected\n * a live project off the managed runtime and said so only to a TTY that wasn't\n * there.\n *\n * stdout carries the JSON value and nothing else, so warnings go to stderr:\n * a machine parser reading stdout cannot be corrupted by one. Only the\n * *formatting* may depend on the mode — colour and indentation for a terminal,\n * plain ASCII otherwise. Whether a warning is emitted at all may not.\n *\n * Anything a caller might branch on belongs in the JSON payload as well; stderr\n * is for whoever reads the transcript afterwards.\n */\nexport function warn(message: string, hint?: string): void {\n if (JSON_MODE) {\n process.stderr.write(`warning: ${stripAnsi(message)}\\n`);\n if (hint) process.stderr.write(` ${stripAnsi(hint)}\\n`);\n return;\n }\n console.error(\"\");\n console.error(chalk.yellow(` ⚠ ${message}`));\n if (hint) console.error(chalk.gray(` ${hint}`));\n}\n\n/**\n * Print an error (+ optional hint) and exit non-zero. Never returns.\n *\n * `code` is the field a caller branches on, and it defaults to `\"error\"` rather\n * than `null`. An envelope whose only machine-readable field is null is not\n * machine-readable — `{\"error\":{\"message\":\"No project specified…\",\"code\":null}}`\n * forced the very substring-matching on `message` that the envelope exists to\n * make unnecessary, and `message` is the field most likely to be reworded.\n *\n * `\"error\"` is deliberately a poor code: it says \"this refusal has not been\n * classified yet\" without ever being absent. Anything a caller might plausibly\n * want to distinguish — `usage`, `not_found`, `unauthenticated` — passes a real\n * one. Codes are part of the CLI's contract once shipped; see\n * `cloud-reporting.test.ts`, which pins the ones commands are documented to\n * return.\n */\nexport function fail(message: string, hint?: string, code?: string): never {\n if (JSON_MODE) {\n printJson({ error: { message: stripAnsi(message),\ncode: code ?? \"error\",\nhint: hint ? stripAnsi(hint) : undefined } });\n process.exit(1);\n }\n console.error(\"\");\n console.error(chalk.red(` ✗ ${message}`));\n if (hint) console.error(chalk.gray(` ${hint}`));\n console.error(\"\");\n process.exit(1);\n}\n\n/**\n * Confirm a destructive/irreversible action, respecting non-interactive use.\n *\n * With `--yes`/`-y` it proceeds silently. In JSON mode or a non-TTY it REFUSES\n * to prompt — a prompt that can hang is a known repo landmine — and fails,\n * telling the caller to pass `--yes`. Only an interactive terminal gets a real\n * confirm prompt; declining there aborts cleanly (exit 0).\n */\nexport async function confirmDestructive(opts: { yes: boolean; prompt: string }): Promise<void> {\n if (opts.yes) return;\n if (JSON_MODE || process.stdin.isTTY !== true) {\n fail(\n \"This action is destructive and needs confirmation.\",\n `Re-run with ${chalk.bold(\"--yes\")} to proceed.`,\n \"confirmation_required\"\n );\n }\n const { confirmed } = (await inquirer.prompt([\n { type: \"confirm\",\nname: \"confirmed\",\ndefault: false,\nmessage: opts.prompt }\n ] as Parameters<typeof inquirer.prompt>[0])) as { confirmed: boolean };\n if (!confirmed) {\n // stderr: declining is not a result. Unreachable in JSON mode — the\n // guard above already refused rather than prompt — so stdout stays\n // empty and the exit code carries the outcome.\n console.error(chalk.gray(\" Aborted.\"));\n process.exit(0);\n }\n}\n\n/**\n * Refuse, rather than prompt, when there is nobody to answer.\n *\n * `confirmDestructive` has always done this for yes/no confirmations. The\n * *value* prompts had no such guard: `cloud login`, `cloud link`, `cloud use`,\n * `cloud orgs create` and `cloud db create` all called `inquirer.prompt`\n * unconditionally, so piping any of them — which is how an agent runs every\n * command in this family — parked the process on a prompt reading from a stdin\n * that was never going to produce a line. A hang is the worst failure mode\n * available here: no output, no exit code, nothing to retry on.\n *\n * @param what what the prompt would have asked for, e.g. \"an email and password\"\n * @param flags the flags that supply it non-interactively\n */\nexport function requireInteractive(what: string, flags: string): void {\n if (JSON_MODE || process.stdin.isTTY !== true) {\n fail(\n `This command needs ${what}, and there is no terminal to ask on.`,\n `Pass ${chalk.bold(flags)}.`,\n \"input_required\"\n );\n }\n}\n\n/**\n * Resolve one cloud command's flags and ARGUMENTS from the full `process.argv`.\n *\n * This replaces `cloudPositionals`, which was `rawArgs.slice(3).filter(a =>\n * !a.startsWith(\"-\"))`. Dropping `-`-prefixed tokens looks like it solves the\n * permissive-parse problem and does not: a flag that takes a VALUE leaves the\n * value behind, an ordinary word in the argument position that no filter can\n * tell from a real one. `--project` is the flag every one of these commands\n * documents, so the failure was reachable from the help page:\n *\n * rebase cloud env unset -p acme → removed the variable \"acme\"\n * rebase cloud env set KEY -p acme → stored the value \"acme\"\n * rebase cloud domains add -p acme → registered the domain \"acme\"\n * rebase cloud webhooks delete -p acme 42 → deleted webhook \"acme\", not 42\n * rebase cloud cancel -p acme → cancelled deployment id \"acme\"\n *\n * The filter's other half is quieter. A flag nobody declared *is* dropped by\n * it — but only from the operands, never from the run: nothing rejects it, so\n * the command proceeds with the argument missing or defaulted. `db backup\n * --dry-run` listed backups, `domains remove --dry-run` detached the domain,\n * and `env set KEY=v --secrett` stored the value as an ordinary variable that\n * `env reveal` will hand back. The one place an undeclared flag became the\n * argument outright is `projects info|delete`, which resolved its id through\n * `positionals()` instead — that skips only LEADING `-` tokens, so `projects\n * delete --force` looked up a project named \"--force\".\n *\n * So: parse the whole line strictly, through the same `parseCommandArgs` the\n * non-cloud commands use — `arg` then consumes each declared flag *with its\n * value* wherever it appears, and rejects the undeclared, leaving `_` holding\n * the command words followed by the real arguments. `commandWords` counts from\n * `cloud` itself (`cloud env set` ⇒ 3), and is applied to the parsed\n * positionals, so a flag written before the group shifts nothing.\n *\n * Two things this adds over calling `parseCommandArgs` directly, and the reason\n * it is worth a wrapper:\n *\n * - `GLOBAL_CLOUD_FLAGS` is merged in. `--json`, `--yes` and `--project` may\n * appear anywhere on a cloud line including before the group, so a strict\n * parse that did not declare them would reject the CLI's own documented\n * usage. (`parseCommandArgs` adds `--debug`/`--help` on top of that.)\n * - A parse error is reported through `fail`, not thrown. A throw reaches\n * `bin/rebase.js`, which prints `✗ …` to stderr — which is right for every\n * other command and wrong here: `rebase cloud` is in JSON mode whenever\n * stdout is not a TTY, i.e. always for the agents this family is built for,\n * and it promises them exactly one JSON value. `fail` keeps that promise,\n * with the same `usage` code the other refusals in this family use.\n */\nexport function parseCloudArgs<S extends arg.Spec>(opts: {\n spec: S;\n rawArgs: string[];\n commandWords: number;\n /** Names the command in errors, e.g. `cloud env set` (no leading `rebase`). */\n command: string;\n maxPositionals?: number;\n}): { flags: arg.Result<S & typeof GLOBAL_CLOUD_FLAGS>; positionals: string[] } {\n const spec = { ...GLOBAL_CLOUD_FLAGS,\n...opts.spec };\n try {\n const parsed = parseCommandArgs({ ...opts,\nspec });\n return { flags: parsed.flags,\npositionals: parsed.positionals };\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err), undefined, \"usage\");\n }\n}\n\n/**\n * Refuse an action word its group does not dispatch. Returns for `undefined`,\n * which is every group's default action.\n *\n * The groups that switch on their action already do this in a `default:` case.\n * The groups written as a chain of `if (action === \"x\") return …` did not: a\n * word that matched nothing fell out of the chain into the *default* action, so\n * `rebase cloud storage creat` listed the buckets and exited 0, and\n * `rebase cloud billing usage` printed the account. Reporting a typo as a\n * successful run of a different command is the failure mode this family exists\n * to not have — an agent branching on the exit code learns nothing, and a person\n * reads the output of a command they did not ask for.\n *\n * One spelling, so the code is `unknown_command` everywhere rather than the\n * default `\"error\"` half of them used, and the hint always names the group's own\n * `--help` rather than the index page.\n */\nexport function requireKnownAction(\n group: string,\n action: string | undefined,\n known: readonly string[]\n): void {\n if (action === undefined || known.includes(action)) return;\n fail(\n `Unknown ${group} command: ${action}`,\n `Run \\`rebase cloud ${group} --help\\`. Actions: ${known.join(\", \")}.`,\n \"unknown_command\"\n );\n}\n\n/**\n * `--timeout <seconds>` as milliseconds, or `fallbackMs` when it was not given.\n *\n * One function rather than one per command, because two commands take this flag\n * and a second copy is where the two would come to disagree about what\n * `--timeout 0` means.\n *\n * A value this cannot read is a refusal, not a fall back to the default. The\n * whole reason a caller passes a timeout is that it has a deadline of its own;\n * quietly substituting a different one is how a fifteen-minute wait turns up\n * inside a five-minute CI step, having been asked for `--timeout 30s`.\n */\nexport function resolveTimeoutMs(\n value: string | undefined,\n opts: { fallbackMs: number; command: string }\n): number {\n if (value === undefined) return opts.fallbackMs;\n const seconds = Number(value);\n if (!Number.isFinite(seconds) || seconds <= 0) {\n fail(\n `--timeout takes a number of seconds (got \"${value}\").`,\n `Run \\`rebase ${opts.command} --help\\`.`,\n \"usage\"\n );\n }\n return seconds * 1000;\n}\n\n/**\n * Announce an outcome — \"Logged in as …\", \"Deleted project …\".\n *\n * On **stderr**, in both modes. It reads like a result and is not one: the\n * result is the JSON value (or the table) on stdout, and every JSON payload in\n * this family already carries `success: true`. Leaving this on stdout meant a\n * successful `rebase cloud link | jq` was handed a green tick followed by an\n * object — one stream, two syntaxes, and only the second parseable.\n *\n * It stays visible in JSON mode, unlike `note`: an agent that got a `success`\n * line on a command it expected to refuse has learned something.\n */\nexport function success(message: string): void {\n if (JSON_MODE) {\n process.stderr.write(`${stripAnsi(message)}\\n`);\n return;\n }\n console.error(\"\");\n console.error(chalk.bold.green(` ✓ ${message}`));\n console.error(\"\");\n}\n\n/**\n * Narrate progress, or point at the next step — \"Signing in to …\", \"Redeploy\n * for the tenant to pick this up\".\n *\n * stderr, and **suppressed entirely in JSON mode**. This is the one helper that\n * a mode may silence, and the distinction from `warn` is worth keeping sharp:\n *\n * - A warning is a *condition*. It is as true when piped as when watched, so\n * silencing it hides something the caller would want to know. `warn` never\n * silences.\n * - A note is *hand-holding*. \"Next: run `rebase generate-sdk`\" tells a person\n * what to type; the agent reading the JSON already has the same information\n * structurally, or does not need it. Printing it anyway is transcript noise.\n *\n * When in doubt it is a warning. The cost of a needless warning is a line; the\n * cost of a swallowed one is the deploy that ejected a project off the managed\n * runtime and said so only to a terminal nobody was looking at.\n */\nexport function note(message: string, indent = \" \"): void {\n if (JSON_MODE) return;\n console.error(`${indent}${message}`);\n}\n\n/** A blank spacer line on the narration stream. No-op in JSON mode. */\nexport function noteBlank(): void {\n if (JSON_MODE) return;\n console.error(\"\");\n}\n\n/** Colorize a deployment / resource status token. */\nexport function colorStatus(status: string | undefined): string {\n switch (status) {\n case \"active\":\n case \"success\":\n case \"connected\":\n return chalk.green(status);\n case \"deploying\":\n case \"provisioning\":\n case \"pending_billing\":\n case \"untested\":\n return chalk.yellow(status ?? \"\");\n case \"failed\":\n return chalk.red(status);\n case \"stopped\":\n return chalk.gray(status);\n default:\n return chalk.gray(status ?? \"unknown\");\n }\n}\n\n/**\n * Render a two-column key/value block with aligned keys. Empty rows are skipped\n * — including `null`, which the API sends for an unset column and which used to\n * print the literal string \"null\" (e.g. `Custom domain: null`).\n */\nexport function keyValues(rows: Array<[string, string | null | undefined]>): void {\n const width = Math.max(...rows.map(([k]) => k.length));\n for (const [k, v] of rows) {\n if (v === undefined || v === null || v === \"\") continue;\n console.log(` ${chalk.gray(`${k}:`.padEnd(width + 1))} ${v}`);\n }\n}\n\n/**\n * Surface an SDK/HTTP error consistently. The SDK throws RebaseApiError with\n * a `.status` and `.message`; anything else falls back to its string form.\n *\n * The message is summarised rather than printed — see `summarizeError`. What\n * arrives here is routinely a whole Kubernetes `Status` object with the request\n * headers appended, and the one sentence worth reading is inside it. The\n * untouched body is still available, behind `--debug`, on stderr where it\n * cannot corrupt the JSON value on stdout.\n */\nexport function reportError(e: unknown, context: string): never {\n const err = e as { status?: number; message?: string; code?: string };\n const summary = summarizeError(e, context);\n\n if (wantsRawError()) {\n process.stderr.write(`\\n${summary.raw}\\n\\n`);\n }\n\n if (JSON_MODE) {\n printJson({\n error: {\n message: stripAnsi(summary.message),\n // The SDK supplies a code for errors the API classified. When it\n // does not, the HTTP status still classifies it well enough to\n // branch on — `http_401` and `http_502` want very different\n // handling, and both used to arrive as `null`. A cluster\n // refusal classifies itself, and `platform` below says whether\n // acting on it is even the caller's business.\n code: summary.code,\n status: err?.status ?? null,\n hint: summary.hint ? stripAnsi(summary.hint) : undefined,\n platform: summary.platform,\n context\n }\n });\n process.exit(1);\n }\n fail(summary.message, summary.hint, summary.code);\n}\n\n/**\n * Open a URL in the user's default browser (best effort). Always announces the\n * URL first so it stays usable over SSH or when no browser is available.\n *\n * The announcement is narration, not the result — it goes to stderr, and in\n * JSON mode it is silent. Every caller `emit`s the same URL in its payload, so\n * a machine reader gets it from the one place it is guaranteed to be parseable\n * rather than from a line that happens to end in a URL.\n */\nexport function openUrl(target: string, label = \"Opening\"): void {\n noteBlank();\n note(`${label} ${chalk.cyan(target)}`);\n noteBlank();\n const opener =\n process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n try {\n const child = spawn(opener, [target], {\n stdio: \"ignore\",\n detached: true,\n shell: process.platform === \"win32\"\n });\n child.on(\"error\", () => {\n /* URL already printed for manual copy */\n });\n child.unref();\n } catch {\n /* URL already printed */\n }\n}\n\n/**\n * The one thing every control-plane row is required to have.\n *\n * The subcommands each declare their own row shape — `OrgRow`, `ProjectRow`,\n * `DatabaseRow`, `DeploymentRow` — and every one of them is an `id` plus\n * fields that are all optional, because a control plane older than a given\n * column simply does not send it. The reads are written that way too\n * (`o.name ?? \"(unnamed)\"`, `row.slug ? … : \"\"`).\n */\nexport interface CloudRow {\n id: string | number;\n}\n\n/**\n * Read the control plane's rows as a subcommand's row shape.\n *\n * `client.data.collection(...)` is typed against the *generated* schema of the\n * project the SDK is pointed at, and the control-plane collections this CLI\n * reads are not in one — so every row arrives as an open\n * `Record<string, unknown>`. A declared `interface` gets no implicit index\n * signature, so it does not overlap that, and a direct `as` is refused: which\n * is how ten call sites came to write `as unknown as XRow[]`, an assertion\n * about a wire payload with nothing checking it in either direction.\n *\n * There is exactly one invariant to check and this checks it. Everything else\n * the shapes declare is optional and already read as such, so there is nothing\n * further to verify — but a row with no usable `id` is not a row any of these\n * commands can act on, and passing it through was how a listing came to print\n * `[undefined]` and a lookup came to compare against the string `\"undefined\"`.\n */\nexport function cloudRows<T extends CloudRow>(rows: readonly Record<string, unknown>[] | undefined): T[] {\n return (rows ?? []).filter((row): row is Record<string, unknown> & T =>\n typeof row?.id === \"string\" || typeof row?.id === \"number\");\n}\n\n/** {@link cloudRows} for an endpoint that returns a single row. */\nexport function cloudRow<T extends CloudRow>(row: Record<string, unknown> | undefined): T | undefined {\n return cloudRows<T>(row ? [row] : [])[0];\n}\n\n/**\n * {@link cloudRows} for a write that must have produced a row.\n *\n * `create()` returning something with no usable `id` means the control plane\n * accepted the write and then described it in a way this CLI cannot act on.\n * The callers all go straight on to use that id — `setContextOrg(url,\n * String(created.id))` — so asserting the shape, which is what stood here,\n * turned a control-plane fault into an organization whose active id is the\n * seven-letter string `\"undefined\"`, stored in the user's config file.\n */\nexport function requireCloudRow<T extends CloudRow>(\n row: Record<string, unknown> | undefined,\n what: string\n): T {\n const parsed = cloudRow<T>(row);\n if (!parsed) throw new Error(`The control plane accepted the ${what} but returned no id for it.`);\n return parsed;\n}\n","import os from \"os\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Every field that may ever leave the machine, and nothing else.\n *\n * ## The rule this file exists to enforce\n *\n * **No value here may be free text.** Every property is either a number, a\n * boolean, or a string drawn from a set enumerated in this file. That is not\n * fussiness — free text is the mechanism by which telemetry leaks. An error\n * message carries `/Users/francesco/rebase/...`, which is a real person's name.\n * A collection name carries a customer's product vocabulary. A database URL\n * carries a password. None of those are things anyone intends to send; they\n * arrive by being interpolated into a string that a well-meaning field was\n * happy to accept.\n *\n * So the payload is closed by construction. Adding a field means adding it\n * here, where the review question — \"can this ever contain something the user\n * typed?\" — is unavoidable.\n *\n * ## What is deliberately absent\n *\n * Project names, directory paths, collection or table names, hostnames,\n * database URLs, error messages, stack traces, email addresses, exact row or\n * user counts. Anything that would let a payload be traced to an organisation\n * rather than to an anonymous id.\n */\n\n/**\n * Bumped whenever a field is added, removed or changes meaning.\n *\n * Sent with every event so the receiving end can reject or migrate old shapes,\n * and so `rebase telemetry show` can state which contract the user agreed to.\n */\nexport const TELEMETRY_SCHEMA_VERSION = 1;\n\n/** The events the CLI reports. Closed set — a name not listed cannot be sent. */\nexport type TelemetryEventName =\n | \"cli.init\"\n | \"cli.dev\"\n | \"cli.deploy\"\n // Named for the command group, not for one of its subcommands. These were\n // `cli.schema_generate` and `cli.db_push` and were sent for *every*\n // subcommand of their group — so `rebase db restore` was recorded as a\n // push, and anything counting pushes counted every database command. The\n // subcommand travels as a property, where it can be read.\n | \"cli.schema\"\n | \"cli.db\"\n | \"cli.error\";\n\n/** A single non-free-text value. */\nexport type TelemetryValue = string | number | boolean;\n\nexport type TelemetryEvent = {\n schema: number;\n event: TelemetryEventName;\n /** Random per machine — see identity.ts on why it is not derived. */\n machineId: string;\n /** Random per checkout. Absent when the command ran outside a project. */\n projectId?: string;\n /** The CLI's own version, so old releases can be told apart. */\n cliVersion: string;\n /** Coarse platform facts, for the support matrix. */\n nodeMajor: number;\n platform: NodeJS.Platform;\n arch: string;\n /** UTC, second precision. Not a device clock reading anyone can fingerprint. */\n at: string;\n properties: Record<string, TelemetryValue>;\n};\n\n/**\n * Buckets rather than exact counts.\n *\n * An exact figure is a surprisingly good fingerprint — \"this install has 37\n * collections\" narrows the field a great deal when combined with a version and\n * a driver. A bucket answers \"roughly how big\" without doing that.\n */\nexport function bucket(value: number): string {\n if (!Number.isFinite(value) || value < 0) return \"unknown\";\n if (value === 0) return \"0\";\n if (value <= 5) return \"1-5\";\n if (value <= 20) return \"6-20\";\n if (value <= 50) return \"21-50\";\n if (value <= 200) return \"51-200\";\n return \"200+\";\n}\n\n/** Duration in coarse bands — enough to see \"slow\", not enough to fingerprint. */\nexport function durationBucket(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return \"unknown\";\n if (ms < 5_000) return \"<5s\";\n if (ms < 30_000) return \"5-30s\";\n if (ms < 120_000) return \"30-120s\";\n return \"120s+\";\n}\n\n/**\n * An error reduced to something safe to transmit.\n *\n * The message and the stack are discarded, always. What survives is the\n * constructor name and, for the errors that carry one, a `code` — both of which\n * come from the program rather than from anything the user typed or named.\n * `EACCES` is useful and safe; \"cannot write /Users/francesco/clients/acme\" is\n * neither.\n */\nexport function errorClass(error: unknown): string {\n if (error && typeof error === \"object\") {\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"string\" && /^[A-Z][A-Z0-9_]{1,31}$/.test(code)) return code;\n const name = (error as { name?: unknown }).name;\n if (typeof name === \"string\" && /^[A-Za-z][A-Za-z0-9]{0,31}$/.test(name)) return name;\n }\n return \"Unknown\";\n}\n\n/**\n * Drop anything that is not a permitted value type, and clamp strings.\n *\n * The last line of defence rather than the first. Every call site is supposed\n * to pass enumerated values; this is what stops a future one that forgets from\n * turning into an incident. Strings are capped at 64 characters because no\n * legitimate enumerated value is longer, and a path or a message always is.\n */\n/**\n * Key names that shadow an `Object.prototype` member.\n *\n * `__proto__` is already excluded by the pattern (it starts with an\n * underscore), and assigning any of these to an object literal shadows rather\n * than pollutes — so nothing is exploitable here. They are refused because a\n * stored property called `constructor` is a trap for every consumer downstream\n * that reaches for `properties.constructor` and gets a string.\n */\nconst RESERVED_KEYS = new Set([\"constructor\", \"prototype\", \"hasownproperty\", \"tostring\", \"valueof\"]);\n\nexport function sanitize(properties: Record<string, unknown>): Record<string, TelemetryValue> {\n const out: Record<string, TelemetryValue> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (!/^[a-z][a-z0-9_]{0,31}$/.test(key) || RESERVED_KEYS.has(key.toLowerCase())) continue;\n if (typeof value === \"boolean\" || (typeof value === \"number\" && Number.isFinite(value))) {\n out[key] = value;\n } else if (typeof value === \"string\" && value.length > 0 && value.length <= 64) {\n // Anything with a separator in it is a path, a URL or a sentence —\n // never one of our enumerated tokens.\n if (!/[/\\\\@:\\s]/.test(value)) out[key] = value;\n }\n }\n return out;\n}\n\n/**\n * The CLI's own version, read by walking up to this package's manifest.\n *\n * The obvious `require(\"../../package.json\")` was wrong everywhere, not only on\n * one install path: `vite build` bundles this module into `dist/index.es.js`, so\n * the specifier resolves relative to `<pkg>/dist/` and lands on\n * `<parent-of-pkg>/package.json` — a file that does not exist under npm, pnpm or\n * the monorepo. Every event ever sent carried `cliVersion: \"unknown\"`, which is\n * the one field that makes the rest of a payload interpretable.\n *\n * So walk up and check the manifest's `name` rather than counting directory\n * levels: the count differs between `src/telemetry/` and the bundled `dist/`,\n * and a wrong count fails silently by finding *some* package.json — the nearest\n * dependency's, under a hoisted layout. Matching the name cannot do that.\n */\nfunction cliVersion(): string {\n try {\n let dir = path.dirname(fileURLToPath(import.meta.url));\n const root = path.parse(dir).root;\n while (dir && dir !== root) {\n const manifest = path.join(dir, \"package.json\");\n if (fs.existsSync(manifest)) {\n const pkg = JSON.parse(fs.readFileSync(manifest, \"utf-8\"));\n if (pkg?.name === \"@rebasepro/cli\" && typeof pkg.version === \"string\" && pkg.version) {\n return pkg.version;\n }\n }\n dir = path.dirname(dir);\n }\n } catch {\n // Fall through — a version we cannot read is reported as such.\n }\n return \"unknown\";\n}\n\nexport function buildEvent(\n event: TelemetryEventName,\n properties: Record<string, unknown>,\n identity: { machineId: string; projectId?: string }\n): TelemetryEvent {\n return {\n schema: TELEMETRY_SCHEMA_VERSION,\n event,\n machineId: identity.machineId,\n projectId: identity.projectId,\n cliVersion: cliVersion(),\n nodeMajor: Number(process.versions.node.split(\".\")[0]) || 0,\n platform: os.platform(),\n arch: os.arch(),\n at: new Date().toISOString().replace(/\\.\\d{3}Z$/, \"Z\"),\n properties: sanitize(properties)\n };\n}\n","import fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport crypto from \"crypto\";\n\n/**\n * Who is reporting, and where that is remembered.\n *\n * Two identifiers, because they answer two different questions and conflating\n * them would make the answers wrong:\n *\n * - `machineId` — one developer's machine. Lives beside the cloud credentials\n * in `~/.rebase/`, so it survives across every project they scaffold.\n * - `projectId` — one *checkout*. Lives in the project's gitignored\n * `.rebase/`, next to `cloud.json` and `state.json`.\n *\n * Without the split, a developer trying five templates in an afternoon reads as\n * five installations. With it, that is one machine and five projects, which is\n * the shape the funnel actually needs.\n *\n * ## Why `projectId` is not committed\n *\n * `rebase.json` is checked in, and a stable identifier sitting in a public\n * repository is a correlation handle for anyone who finds it — it ties a named\n * organisation to whatever that id did. `.rebase/` is gitignored, so the id\n * stays on the machine that generated it. It also makes the unit honest: what\n * is being counted is a developer working on a project, not the project.\n *\n * ## Why both are random\n *\n * Neither is derived from a hostname, a database name, an email or a machine\n * fingerprint. Hashing any of those only *looks* anonymous — the space of real\n * hostnames is small enough to brute-force a salted hash back to the original\n * in minutes. A random UUID carries no information at all and does the same job.\n */\n\n/** Bumped when the stored shape changes in a way old CLIs cannot read. */\nexport const TELEMETRY_CONFIG_VERSION = 1;\n\nexport type TelemetryConfig = {\n version: number;\n /**\n * `undefined` means never asked — which is *not* the same as declining, and\n * is the only state in which anything may prompt.\n */\n enabled?: boolean;\n machineId?: string;\n /** When the choice was made, so a later release can tell stale consent from fresh. */\n decidedAt?: string;\n};\n\nexport function configPath(): string {\n return path.join(os.homedir(), \".rebase\", \"telemetry.json\");\n}\n\nexport function readConfig(): TelemetryConfig {\n try {\n const raw = JSON.parse(fs.readFileSync(configPath(), \"utf-8\"));\n if (raw && typeof raw === \"object\") {\n return {\n version: typeof raw.version === \"number\" ? raw.version : TELEMETRY_CONFIG_VERSION,\n enabled: typeof raw.enabled === \"boolean\" ? raw.enabled : undefined,\n machineId: typeof raw.machineId === \"string\" ? raw.machineId : undefined,\n decidedAt: typeof raw.decidedAt === \"string\" ? raw.decidedAt : undefined\n };\n }\n } catch {\n // Missing, unreadable or corrupt all mean the same thing: we have no\n // record of a decision, so nothing may be sent.\n }\n return { version: TELEMETRY_CONFIG_VERSION };\n}\n\nexport function writeConfig(config: TelemetryConfig): void {\n const file = configPath();\n fs.mkdirSync(path.dirname(file), { recursive: true });\n // 0600: it sits beside `credentials.json`, and a world-readable identifier\n // on a shared machine is a way to link one developer's activity to another's.\n fs.writeFileSync(file, JSON.stringify({ ...config,\nversion: TELEMETRY_CONFIG_VERSION }, null, 2), {\n encoding: \"utf-8\",\n mode: 0o600\n });\n}\n\n/**\n * The machine's id, generating and persisting one on first use.\n *\n * Only called once consent exists — an id written before the user agreed would\n * be a record we had no right to create, even unsent.\n */\nexport function ensureMachineId(): string {\n const config = readConfig();\n if (config.machineId) return config.machineId;\n const machineId = crypto.randomUUID();\n writeConfig({ ...config,\nmachineId });\n return machineId;\n}\n\n/**\n * The checkout's id, generating one if this project has none.\n *\n * The directory is created when it is missing, but **only** where a\n * `rebase.json` proves this really is a project root. An earlier version\n * required `.rebase/` to already exist, on the assumption that `rebase init`\n * created it — it does not. It is written only when a scaffold is linked to\n * Rebase Cloud, so every self-hosted project reported no `projectId` at all,\n * for ever. That silently broke the funnel this id exists for, on exactly the\n * population the telemetry is meant to learn about.\n *\n * The `rebase.json` check is what keeps the fix from being \"scatter `.rebase/`\n * wherever a command happens to run\": no manifest, no project, no directory,\n * and the event simply reports no project.\n */\nexport function ensureProjectId(projectRoot: string): string | undefined {\n if (!fs.existsSync(path.join(projectRoot, \"rebase.json\"))) return undefined;\n\n const dir = path.join(projectRoot, \".rebase\");\n try {\n fs.mkdirSync(dir, { recursive: true });\n } catch {\n return undefined;\n }\n\n const file = path.join(dir, \"state.json\");\n let state: Record<string, unknown> = {};\n if (fs.existsSync(file)) {\n try {\n const raw = JSON.parse(fs.readFileSync(file, \"utf-8\"));\n if (raw && typeof raw === \"object\") state = raw;\n } catch {\n // `state.json` is shared with other commands. A parse failure here\n // must not destroy their keys, so we do not write in that case.\n return undefined;\n }\n }\n\n if (typeof state.telemetryProjectId === \"string\") return state.telemetryProjectId;\n\n const projectId = crypto.randomUUID();\n try {\n fs.writeFileSync(file, JSON.stringify({ ...state,\ntelemetryProjectId: projectId }, null, 2), \"utf-8\");\n } catch {\n return undefined;\n }\n return projectId;\n}\n","import fs from \"fs\";\nimport path from \"path\";\n\nimport { findProjectRoot, MANIFEST_FILENAME } from \"../utils/project\";\n\n/**\n * A repository's own policy on usage sharing.\n *\n * ## Why this is deliberately one-directional\n *\n * `rebase.json` is committed, so whatever it says applies to everyone who\n * clones the repository — including people who have never seen our prompt. That\n * makes it the right place for exactly one of the two answers:\n *\n * - **`false` is honoured**, and beats an individual's opt-in. An organisation\n * restricting its own repository is setting policy for work done on its\n * behalf, which is theirs to set. It is the same shape as a committed\n * `.npmrc`.\n * - **`true` is ignored**, and says so. It would be one developer answering a\n * privacy question for every colleague who later clones the repo — consent\n * by proxy, which is the precise thing opt-in exists to prevent.\n *\n * The asymmetry is the whole feature. A symmetric flag would be a worse version\n * of the machine-level setting, and a quietly-obeyed `true` would be a way to\n * enrol people without asking them.\n *\n * Read straight from the file rather than through `parseManifest`, for two\n * reasons: the parser builds a typed object and drops keys it does not model,\n * and a manifest too malformed to parse must still be able to switch telemetry\n * off. A repository that says no should be obeyed even when it is broken.\n */\nexport type ProjectTelemetryPolicy =\n /** `\"telemetry\": false` — suppress, regardless of the machine setting. */\n | \"opt_out\"\n /** `\"telemetry\": true` — refused; the machine setting still decides. */\n | \"ignored_opt_in\"\n /** No manifest, no key, or an unreadable one. */\n | \"unset\";\n\nexport function readProjectPolicy(startDir: string = process.cwd()): ProjectTelemetryPolicy {\n try {\n const root = findProjectRoot(startDir);\n if (!root) return \"unset\";\n\n const file = path.join(root, MANIFEST_FILENAME);\n if (!fs.existsSync(file)) return \"unset\";\n\n // A regex rather than JSON.parse: a manifest with a trailing comma or a\n // half-finished edit still parses badly but reads clearly, and \"your\n // JSON is malformed\" is not a reason to start sending data the file\n // plainly asks us not to send.\n const raw = fs.readFileSync(file, \"utf-8\");\n const match = /\"telemetry\"\\s*:\\s*(true|false)/.exec(raw);\n if (!match) return \"unset\";\n return match[1] === \"false\" ? \"opt_out\" : \"ignored_opt_in\";\n } catch {\n return \"unset\";\n }\n}\n","import { ensureMachineId, ensureProjectId, readConfig, writeConfig } from \"./identity\";\nimport { buildEvent, TelemetryEvent, TelemetryEventName } from \"./payload\";\nimport { readProjectPolicy } from \"./project\";\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\nexport { TELEMETRY_SCHEMA_VERSION, bucket, durationBucket, errorClass, buildEvent, sanitize } from \"./payload\";\nexport type { TelemetryEvent, TelemetryEventName, TelemetryValue } from \"./payload\";\nexport { configPath, readConfig, writeConfig } from \"./identity\";\nexport type { TelemetryConfig } from \"./identity\";\nexport { readProjectPolicy } from \"./project\";\nexport type { ProjectTelemetryPolicy } from \"./project\";\n\n/**\n * Where events go. Overridable so a fork can point at its own collector, and so\n * the tests never touch the network.\n */\nexport const DEFAULT_TELEMETRY_ENDPOINT = \"https://app.rebase.pro/api/functions/telemetry\";\n\nexport function endpoint(): string {\n return process.env.REBASE_TELEMETRY_ENDPOINT?.trim() || DEFAULT_TELEMETRY_ENDPOINT;\n}\n\n/**\n * Set to anything but a spelled no.\n *\n * The conventions behind these variables make presence the signal —\n * `CI=woodpecker` is a CI run, `DO_NOT_TRACK=please` is an answer — so a value\n * the parser does not recognise still counts, and the refusal holds. Only the\n * platform's spellings of no turn one off. It was `!== \"0\"` for two of them and\n * `!== \"false\"` for `CI`, so `CI=0` read as a runner.\n */\nfunction setAndNotNo(value: string | undefined): boolean {\n return value !== undefined && value.trim() !== \"\" && parseEnvBoolean(value) !== false;\n}\n\n/** Why nothing would be sent right now, or `null` when it would. */\nexport type SuppressionReason =\n | \"not_asked\"\n | \"declined\"\n | \"do_not_track\"\n | \"rebase_telemetry_disabled\"\n | \"ci\"\n | \"project_opt_out\";\n\n/**\n * The one function that decides whether anything leaves the machine.\n *\n * Every path is a refusal except the last, which is the point: consent is\n * opt-in, so the default answer at every branch — never asked, unreadable\n * config, a set env var, a CI runner — is no.\n *\n * `DO_NOT_TRACK` is honoured because it is the cross-tool convention\n * (consoledonottrack.com); a user who has set it globally has already answered\n * this question and should not be asked again by us.\n *\n * `CI` is refused for a different reason: a build runner is not a person, and\n * counting one is both useless and misleading. A single pipeline re-running on\n * every push would otherwise outweigh every real developer in the data.\n *\n * A project's own `\"telemetry\": false` is checked *before* the machine setting,\n * because it has to beat an individual opt-in to be worth anything — see\n * project.ts on why the reverse is refused.\n */\nexport function suppressionReason(\n env: NodeJS.ProcessEnv = process.env,\n cwd: string = process.cwd()\n): SuppressionReason | null {\n if (setAndNotNo(env.DO_NOT_TRACK)) return \"do_not_track\";\n if (setAndNotNo(env.REBASE_TELEMETRY_DISABLED)) return \"rebase_telemetry_disabled\";\n if (setAndNotNo(env.CI)) return \"ci\";\n if (readProjectPolicy(cwd) === \"opt_out\") return \"project_opt_out\";\n\n const config = readConfig();\n if (config.enabled === undefined) return \"not_asked\";\n if (!config.enabled) return \"declined\";\n return null;\n}\n\nexport function isEnabled(env: NodeJS.ProcessEnv = process.env, cwd: string = process.cwd()): boolean {\n return suppressionReason(env, cwd) === null;\n}\n\n/**\n * Record the user's answer. `false` is final — nothing prompts again.\n *\n * Returns whether the choice could actually be persisted. A read-only or full\n * home directory makes `writeConfig` throw, and the direction of that failure\n * matters enormously: someone turning sharing **off** who sees a stack trace,\n * or worse sees nothing, is left sharing. The caller is expected to say so and\n * point at `REBASE_TELEMETRY_DISABLED`, which needs no disk.\n */\nexport function setConsent(enabled: boolean): boolean {\n const config = readConfig();\n try {\n writeConfig({\n ...config,\n enabled,\n decidedAt: new Date().toISOString(),\n // An id is minted only on acceptance. Generating one at decline\n // time would create the very record the user just refused.\n machineId: enabled ? (config.machineId ?? undefined) : undefined\n });\n if (enabled) ensureMachineId();\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Build the event that *would* be sent, without sending it.\n *\n * This is what `rebase telemetry show` prints, and it is deliberately the same\n * function the sender uses — a preview assembled by separate code is a promise\n * that drifts. Returns `null` when nothing would be sent, so the command can\n * say why instead of showing a payload that is never going anywhere.\n */\nexport function previewEvent(\n event: TelemetryEventName,\n properties: Record<string, unknown> = {},\n projectRoot?: string\n): TelemetryEvent | null {\n const config = readConfig();\n if (!config.machineId) return null;\n return buildEvent(event, properties, {\n machineId: config.machineId,\n projectId: projectRoot ? ensureProjectId(projectRoot) : undefined\n });\n}\n\n/**\n * Send one event, or quietly do nothing.\n *\n * Three properties this must hold, in order of importance:\n *\n * 1. **It never throws.** Telemetry failing is not a reason for `rebase dev`\n * to fail. Every error is swallowed.\n * 2. **It never blocks meaningfully.** A two-second ceiling, after which the\n * command carries on regardless — a collector having a bad day must not\n * become the CLI hanging.\n * 3. **It never sends without consent.** Enforced here rather than at the call\n * sites, so a new call site cannot get it wrong.\n */\nexport async function recordEvent(\n event: TelemetryEventName,\n properties: Record<string, unknown> = {},\n options: { projectRoot?: string; timeoutMs?: number } = {}\n): Promise<void> {\n try {\n // The project's own policy is read relative to the project being acted\n // on, not the shell's cwd — `rebase dev` run from a subdirectory must\n // still see its own repository's opt-out.\n if (!isEnabled(process.env, options.projectRoot ?? process.cwd())) return;\n\n const machineId = ensureMachineId();\n const projectId = options.projectRoot ? ensureProjectId(options.projectRoot) : undefined;\n const payload = buildEvent(event, properties, { machineId,\nprojectId });\n\n const abort = new AbortController();\n const timer = setTimeout(() => abort.abort(), options.timeoutMs ?? 2000);\n try {\n await fetch(endpoint(), {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n signal: abort.signal\n });\n } finally {\n clearTimeout(timer);\n }\n } catch {\n // Deliberately silent. A warning here would be worse than useless: it\n // draws attention to a subsystem the user opted into and cannot act on,\n // in the middle of output they were actually reading.\n }\n}\n","import chalk from \"chalk\";\nimport inquirer from \"inquirer\";\n\nimport { buildEvent, TELEMETRY_SCHEMA_VERSION, TelemetryEventName } from \"./payload\";\nimport { readConfig } from \"./identity\";\nimport { setConsent, suppressionReason } from \"./index\";\n\n/**\n * Asking, and what the question looks like.\n *\n * ## Why the prompt comes *after* the work\n *\n * The first `rebase init` on a machine is the event most worth having, and it\n * is the one where no consent exists yet. Asking before scaffolding puts a\n * privacy negotiation in front of someone who has not yet seen the tool do\n * anything — the worst possible moment, and a reliable way to get a reflexive\n * no.\n *\n * So the question is asked once the project exists and the user has seen it\n * work. The event's data is still in memory at that point, so nothing is lost\n * by waiting, and — this is the part that matters — **nothing has been\n * transmitted or written**. Declining leaves no id, no file, no record.\n *\n * ## Why the payload is shown rather than described\n *\n * \"Anonymous usage data\" is a phrase that has been used to mean almost\n * anything. Printing the exact JSON costs four lines of output and replaces a\n * claim the user has to take on faith with something they can read. It is also\n * the same builder the sender uses, so it cannot drift into a comfortable\n * fiction.\n */\n\n/** Where the question is being asked from, which decides how often it may be. */\nexport interface PromptOptions {\n /**\n * Ask again even though this machine already declined.\n *\n * Set by `rebase init`, and only there. Scaffolding a project is a\n * deliberate, occasional act with a natural pause in it — not something\n * anyone does in a loop — so asking each time is an offer rather than\n * nagging, and it reaches the person whose first answer was a reflex before\n * they had seen the tool do anything.\n *\n * It does **not** re-ask someone who accepted: they are already sharing, so\n * the only thing another prompt could do is talk them out of it.\n *\n * Nothing else changes. `DO_NOT_TRACK`, `REBASE_TELEMETRY_DISABLED`, `CI`\n * and a project's `\"telemetry\": false` are answers, not questions, and they\n * still suppress the prompt entirely — a re-ask that could override a\n * committed repository policy would be exactly the consent-by-proxy the\n * policy exists to prevent.\n */\n reAskDeclined?: boolean;\n}\n\n/** True when we may ask: nothing forbids it, and there is a question to ask. */\nexport function shouldPrompt(\n env: NodeJS.ProcessEnv = process.env,\n { reAskDeclined = false }: PromptOptions = {}\n): boolean {\n if (!process.stdin.isTTY) return false;\n\n const reason = suppressionReason(env);\n // `not_asked` is the only reason that is a question rather than an answer.\n // A user who set DO_NOT_TRACK, or is on CI, has already told us — and so\n // has one who is already sharing (`null`), whom we never re-ask.\n if (reason === \"not_asked\") return true;\n return reAskDeclined && reason === \"declined\";\n}\n\nexport function renderPreview(event: TelemetryEventName, properties: Record<string, unknown>): string {\n const preview = buildEvent(event, properties, {\n machineId: \"<random uuid, generated only if you say yes>\",\n projectId: \"<random uuid, per checkout>\"\n });\n return JSON.stringify(preview, null, 2);\n}\n\n/**\n * Ask, record the answer, and report it.\n *\n * Never throws and never blocks a non-interactive run: `rebase init --yes` in\n * CI must behave exactly as it does today, which means not asking and not\n * sending.\n */\nexport async function promptForConsent(options: PromptOptions = {}): Promise<boolean> {\n if (!shouldPrompt(process.env, options)) return false;\n\n // Only true when this is a second (or later) asking, which the closing line\n // needs to know: \"you will not be asked again\" is false at `init`.\n const askedBefore = suppressionReason(process.env) === \"declined\";\n\n try {\n console.log(\"\");\n console.log(chalk.bold(\"Help improve Rebase?\"));\n console.log(\"\");\n console.log(chalk.gray(\" Rebase is self-hosted, so we only learn what works if you tell us.\"));\n console.log(chalk.gray(\" Anonymous: random ids, the CLI version, your OS, and which template and\"));\n console.log(chalk.gray(\" package manager you used. Never project names, paths, schemas, URLs or\"));\n console.log(chalk.gray(\" error messages.\"));\n console.log(\"\");\n console.log(chalk.gray(` Print the exact payload with ${chalk.cyan(\"rebase telemetry show\")}; change your mind`));\n console.log(chalk.gray(` any time with ${chalk.cyan(\"rebase telemetry disable\")}.`));\n if (askedBefore) {\n console.log(\"\");\n console.log(chalk.gray(\" You declined before; that stands unless you change it here.\"));\n }\n console.log(\"\");\n\n const { accepted } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"accepted\",\n message: \"Share anonymous usage data?\",\n // Defaults to yes: this is the question the project most needs\n // answered, and a bare Enter is the commonest answer to any\n // prompt. It is still a question — nothing is sent until it is\n // answered, `n` is one keystroke, and the decision is\n // reversible with the command named two lines above. What it\n // is NOT is \"off by default\" any more; anything that used to\n // say so had to change with it.\n default: true\n }\n ] as Parameters<typeof inquirer.prompt>[0]) as { accepted: boolean };\n\n setConsent(Boolean(accepted));\n\n console.log(\n accepted\n ? chalk.green(\" Thank you — sharing enabled.\")\n : chalk.gray(\n \" Nothing will be sent.\"\n + (options.reAskDeclined\n ? \" You will be asked again the next time you scaffold a project.\"\n : \" You will not be asked again.\")\n )\n );\n console.log(\"\");\n return Boolean(accepted);\n } catch {\n // A prompt that fails (piped stdin, a terminal that went away) is a\n // decline, and specifically a decline we do not persist — the user\n // never actually saw the question, so they should still get to answer\n // it another day.\n return false;\n }\n}\n\n/** Human-readable current state, for `rebase telemetry status`. */\nexport function describeState(env: NodeJS.ProcessEnv = process.env): string {\n const reason = suppressionReason(env);\n const config = readConfig();\n switch (reason) {\n case null:\n return `${chalk.green(\"enabled\")} — schema v${TELEMETRY_SCHEMA_VERSION}, machine id ${chalk.gray(config.machineId ?? \"unset\")}`;\n case \"not_asked\":\n return `${chalk.yellow(\"not configured\")} — nothing has been sent, and you have not been asked yet`;\n case \"declined\":\n return `${chalk.gray(\"disabled\")} — you declined${config.decidedAt ? ` on ${config.decidedAt.slice(0, 10)}` : \"\"}`;\n case \"do_not_track\":\n return `${chalk.gray(\"disabled\")} — the ${chalk.cyan(\"DO_NOT_TRACK\")} environment variable is set`;\n case \"rebase_telemetry_disabled\":\n return `${chalk.gray(\"disabled\")} — the ${chalk.cyan(\"REBASE_TELEMETRY_DISABLED\")} environment variable is set`;\n case \"ci\":\n return `${chalk.gray(\"disabled\")} — this looks like CI (${chalk.cyan(\"CI\")} is set), which is never counted`;\n case \"project_opt_out\":\n return `${chalk.gray(\"disabled\")} — this project's ${chalk.cyan(\"rebase.json\")} sets ${chalk.cyan('\"telemetry\": false')}`;\n }\n}\n","import inquirer from \"inquirer\";\nimport chalk from \"chalk\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport net from \"net\";\nimport { promisify } from \"util\";\nimport { execa } from \"execa\";\nimport { cp } from \"fs/promises\";\nimport { fileURLToPath } from \"url\";\nimport crypto from \"crypto\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { cliVersion } from \"../utils/version\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { resolveCloudUrl, writeLink } from \"./cloud/context\";\nimport type { PackageManager, PMCommands } from \"../utils/package-manager\";\nimport { promptForConsent } from \"../telemetry/consent\";\nimport { durationBucket, recordEvent } from \"../telemetry\";\nimport { parseEnvBoolean } from \"@rebasepro/types\";\n\nconst access = promisify(fs.access);\n\n\n// Resolve template path relative to this file\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nfunction findParentDir(currentDir: string, targetName: string): string | null {\n const root = path.parse(currentDir).root;\n while (currentDir && currentDir !== root) {\n if (path.basename(currentDir) === targetName) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return null;\n}\n\nconst cliRoot = findParentDir(__dirname, \"cli\");\n\nconst PROJECT_NAME_RE = /^[a-z0-9][a-z0-9._-]*$/;\n\n/**\n * Every scaffolded file that carries a `{{PLACEHOLDER}}`.\n *\n * Exported because it is the single source of truth: `init.test.ts` reads it and\n * asserts that every template file containing `{{` appears here. It used to be a\n * local, with the test harness keeping a *second* copy — so the two drifted, and\n * a test built on the copy could not observe the production list at all.\n *\n * The drift shipped: `docker-compose.yml` arrived with the self-host work\n * (26fd5259c) and was added to neither, so every scaffolded project got a literal\n * `name: {{PROJECT_NAME}}`. In YAML `{{...}}` is a map, not a string, so the\n * documented `docker compose up` path failed on the file before doing anything:\n *\n * yaml: unmarshal errors: line 28: cannot unmarshal !!map into string\n */\nexport const TEMPLATE_PLACEHOLDER_FILES = [\n \"package.json\",\n \"frontend/package.json\",\n \"backend/package.json\",\n \"config/package.json\",\n \"frontend/index.html\",\n \"pnpm-workspace.yaml\",\n \"docker-compose.yml\",\n \"README.md\"\n];\n\n/** Returns an error message, or null when the name is a valid package name. */\nexport function validateProjectName(name: string): string | null {\n if (!name.trim()) return \"Project name is required\";\n if (!PROJECT_NAME_RE.test(name)) {\n return \"Project name must start with a lowercase letter or number and contain only lowercase letters, numbers, hyphens, dots, or underscores\";\n }\n return null;\n}\n\nexport type TemplatePreset = \"blog\" | \"ecommerce\" | \"blank\";\n\n/**\n * Whether to scaffold the admin panel alongside the backend.\n *\n * A boolean, not a named pair. It was `--flavor cms|baas`, and neither word\n * survived what they described: \"cms\" is a product category rather than a thing\n * this tool builds, and \"baas\" was the same value that used to appear as\n * `backend.mode` — which is now derived from whether collections are declared.\n * What is left is one question: does this project get an admin UI?\n */\nconst HEADLESS_CHOICES: Array<{ name: string; value: boolean; short: string }> = [\n { name: \"Backend + admin — API plus an admin UI, driven by collections you define (like Payload/Directus)\",\nvalue: false,\nshort: \"Backend + admin\" },\n { name: \"Backend only — headless API over your database. No collections, no UI (like Supabase)\",\nvalue: true,\nshort: \"Backend only\" }\n];\n\nconst PRESET_CHOICES: Array<{ name: string; value: TemplatePreset; short: string }> = [\n { name: \"Blog — Posts, Authors, Tags (with markdown editor)\",\nvalue: \"blog\",\nshort: \"Blog\" },\n { name: \"E-commerce — Products, Categories, Orders\",\nvalue: \"ecommerce\",\nshort: \"E-commerce\" },\n { name: \"Blank — Empty project, just authentication\",\nvalue: \"blank\",\nshort: \"Blank\" }\n];\n\nexport interface InitOptions {\n projectName: string;\n git: boolean;\n installDeps: boolean;\n targetDirectory: string;\n templateDirectory: string;\n databaseUrl?: string;\n introspect?: boolean;\n /** Starter template preset. */\n preset: TemplatePreset;\n /** Whether `preset` came from an explicit --template rather than the default. */\n explicitPreset?: boolean;\n /** Scaffold the backend alone, with no admin panel and no collections. */\n headless: boolean;\n /** Detected package manager (pnpm or npm). */\n pm: PackageManager;\n /** Command helpers for the detected PM. */\n pmCommands: PMCommands;\n /** Cloud project slug (its subdomain) to link the scaffold to. */\n cloudProject?: string;\n /** One-time setup key that authenticates the cloud link. */\n setupKey?: string;\n /** Control-plane URL the setup key is redeemed against. */\n cloudUrl?: string;\n}\n\nexport interface BuildQuestionsParams {\n nameArg?: string;\n templateArg?: TemplatePreset;\n headlessArg?: boolean;\n hasGitFlag: boolean;\n hasInstallFlag: boolean;\n pm: PackageManager;\n}\n\n/**\n * Builds the interactive prompt questions for `rebase init`.\n * Exported for testability — all prompt `type` values must match\n * types registered by the installed version of inquirer.\n */\n/**\n * The questions this command asks, as inquirer types them.\n *\n * Declared, rather than left as `Record<string, unknown>` and asserted into\n * `Parameters<typeof inquirer.prompt>[0]` at the call. Inquirer infers the\n * answer shape from the array it is handed, so an array of open records matches\n * none of its overloads — which is the refusal that assertion was there to get\n * past, at the cost of every question in this file being unchecked: a\n * misspelled `mesage`, a `choices` on a `confirm`, a `default` of the wrong\n * type for its question kind all compiled.\n */\nexport type InitQuestion =\n | { type: \"input\"; name: string; message: string; default: string; validate?: (input: string) => string | true }\n | { type: \"confirm\"; name: string; message: string; default: boolean; when?: (answers: Record<string, unknown>) => boolean }\n | { type: \"select\"; name: string; message: string; choices: ReadonlyArray<{ name: string; value: unknown; short: string }>; default: unknown; when?: (answers: Record<string, unknown>) => boolean };\n\nexport function buildInitQuestions(params: BuildQuestionsParams): InitQuestion[] {\n const { nameArg, templateArg, headlessArg, hasGitFlag, hasInstallFlag, pm } = params;\n const questions: InitQuestion[] = [];\n\n if (!nameArg) {\n questions.push({\n type: \"input\",\n name: \"projectName\",\n message: \"Project name:\",\n default: \"my-app\",\n validate: (input: string) => validateProjectName(input) ?? true\n });\n }\n\n if (headlessArg === undefined) {\n questions.push({\n type: \"select\",\n name: \"headless\",\n message: \"What do you want to build?\",\n choices: HEADLESS_CHOICES,\n default: false\n });\n }\n\n if (!templateArg) {\n questions.push({\n type: \"select\",\n name: \"preset\",\n message: \"Choose a starter template:\",\n choices: PRESET_CHOICES,\n default: \"blog\",\n // A headless project has no collection files, so a preset is moot.\n when: (answers: Record<string, unknown>) => !(headlessArg ?? answers.headless)\n });\n }\n\n if (!hasGitFlag) {\n questions.push({\n type: \"confirm\",\n name: \"git\",\n message: \"Initialize a git repository?\",\n default: true\n });\n }\n\n if (!hasInstallFlag) {\n questions.push({\n type: \"confirm\",\n name: \"installDeps\",\n message: `Install dependencies with ${pm}?`,\n default: true\n });\n }\n\n questions.push({\n type: \"input\",\n name: \"databaseUrl\",\n message: \"PostgreSQL connection string (blank = a managed database for this project, no setup):\",\n default: \"\",\n validate: (input: string) => {\n if (input.trim() && /[\\r\\n]/.test(input)) {\n return \"Database URL cannot contain newline characters.\";\n }\n return true;\n }\n });\n\n questions.push({\n type: \"confirm\",\n name: \"introspect\",\n message: \"Would you like to introspect this database to automatically generate collections?\",\n default: true,\n when: (answers: Record<string, unknown>) => !!(answers.databaseUrl as string)?.trim()\n });\n\n return questions;\n}\n\n/**\n * The `cd` a user must type to enter the new project.\n *\n * Not the project's basename: `init apps/my-app` has to say `cd apps/my-app`,\n * and `init .` returns \"\" because they are already in the project.\n */\nexport function formatCdTarget(cwd: string, targetDirectory: string): string {\n return path.relative(cwd, targetDirectory);\n}\n\n/** Help for `rebase init` — the flags were previously only discoverable by\n * triggering the non-TTY error. */\nexport function printInitHelp(): void {\n console.log(`\n${chalk.bold(\"rebase init\")} — Create a new Rebase project\n\n${chalk.bold(\"Usage\")}\n rebase init ${chalk.blue(\"[name]\")} [options]\n\n ${chalk.gray(\"The name may be a nested path (apps/my-app) or \\\".\\\" for the current directory.\")}\n ${chalk.gray(\"Asks when omitted; defaults to \\\"my-app\\\", and takes it without asking under --yes.\")}\n\n${chalk.bold(\"Options\")}\n ${chalk.blue(\"-t, --template\")} ${chalk.gray(\"<preset>\")} blog | ecommerce | blank ${chalk.gray(\"(default: blog)\")}\n ${chalk.blue(\"--headless\")} Backend only — no admin panel, no collections\n ${chalk.blue(\"-y, --yes\")} Never prompt ${chalk.gray(\"(required for CI / non-TTY)\")}\n ${chalk.gray(\"Skips git init and dependency install — the interactive\")}\n ${chalk.gray(\"defaults say yes to both. Pass --git / --install for those.\")}\n ${chalk.blue(\"-i, --install\")} Install dependencies after scaffolding\n ${chalk.blue(\"--no-install\")} Scaffold only, install nothing ${chalk.gray(\"(the default)\")}\n ${chalk.blue(\"-g, --git\")} Initialize a git repository and make an initial commit\n ${chalk.blue(\"--database-url\")} ${chalk.gray(\"<url>\")} Use an existing database instead of the generated one\n ${chalk.blue(\"--introspect\")} Generate collections from that database ${chalk.gray(\"(implies --template blank; needs --install)\")}\n ${chalk.blue(\"--project\")} ${chalk.gray(\"<slug>\")} Link the scaffold to a Rebase Cloud project\n ${chalk.blue(\"--setup-key\")} ${chalk.gray(\"<key>\")} One-time key authenticating the cloud link ${chalk.gray(\"(use with --project)\")}\n\n${chalk.bold(\"What gets scaffolded\")}\n ${chalk.gray(\"default\")} Backend + an admin UI, driven by collections you define ${chalk.gray(\"(like Payload/Directus)\")}\n ${chalk.blue(\"--headless\")} Backend only, over your existing database ${chalk.gray(\"(like Supabase)\")}\n ${chalk.gray(\"--template has no effect: there are no collections to seed.\")}\n\n${chalk.bold(\"Examples\")}\n ${chalk.gray(\"$\")} rebase init my-shop --template ecommerce --install\n ${chalk.gray(\"$\")} rebase init my-api --headless --yes\n ${chalk.gray(\"$\")} rebase init . --yes --git\n`);\n}\n\nexport async function createRebaseApp(rawArgs: string[]) {\n if (wantsHelp(rawArgs)) {\n printInitHelp();\n return;\n }\n\n console.log(`\n${chalk.bold(\"Rebase\")} — Create a new project 🚀\n`);\n\n const pm = detectPackageManager();\n const options = await promptForOptions(rawArgs, pm);\n await createProject(options);\n}\n\n/** The flags `rebase init` takes. */\nexport const INIT_FLAGS = {\n \"--git\": Boolean,\n \"--install\": Boolean,\n // The default, spelled out. `arg` has no negation, so without this entry a\n // CI script that writes what reads naturally — `rebase init app --yes\n // --no-install` — died on \"Unknown or unexpected option\", and both the\n // README and the Quickstart documented a flag the parser rejected. When\n // both are passed, the explicit \"no\" wins.\n \"--no-install\": Boolean,\n \"--database-url\": String,\n \"--introspect\": Boolean,\n \"--template\": String,\n \"--headless\": Boolean,\n \"--project\": String,\n \"--setup-key\": String,\n \"--yes\": Boolean,\n \"-g\": \"--git\",\n \"-i\": \"--install\",\n \"-t\": \"--template\",\n \"-y\": \"--yes\"\n} as const;\n\nasync function promptForOptions(rawArgs: string[], pm: PackageManager): Promise<InitOptions> {\n const { flags: args, positionals } = parseCommandArgs({\n spec: INIT_FLAGS,\n rawArgs,\n commandWords: 1,\n command: \"init\",\n maxPositionals: 1\n });\n\n // The first positional arg after \"init\" is the project name. Under the old\n // permissive parse a mistyped flag took that slot — `rebase init --headles\n // shop` scaffolded a directory called `--headles` — and the misspelling that\n // caused it was accepted in silence.\n const nameArg = positionals[0];\n const isNonInteractive = args[\"--yes\"] || false;\n\n // The interactive prompt validates typed names; a name passed as an\n // argument must pass the same check or it becomes an invalid package.json\n // \"name\" that only fails later, at install time. Validate the basename so\n // nested paths (\"apps/my-app\") and \".\" still work.\n if (nameArg) {\n const resolvedName = path.basename(path.resolve(process.cwd(), nameArg));\n const nameError = validateProjectName(resolvedName);\n if (nameError) {\n console.error(chalk.red(`Invalid project name \"${resolvedName}\": ${nameError}`));\n process.exit(1);\n }\n }\n\n const templateArg = args[\"--template\"] as TemplatePreset | undefined;\n if (templateArg && !PRESET_CHOICES.some(p => p.value === templateArg)) {\n console.error(chalk.red(`Unknown template \"${templateArg}\". Available: ${PRESET_CHOICES.map(p => p.value).join(\", \")}`));\n process.exit(1);\n }\n\n const headlessArg = args[\"--headless\"] === true ? true : undefined;\n\n // `--no-install` is an explicit \"no\", not merely the absence of a \"yes\": it\n // suppresses the interactive question too, so `rebase init app --no-install`\n // asks one fewer thing rather than asking and ignoring the answer.\n const noInstall = args[\"--no-install\"] === true;\n const installFlag = noInstall ? false : (args[\"--install\"] ?? false);\n const hasInstallFlag = noInstall || args[\"--install\"] === true;\n\n if (isNonInteractive) {\n // Non-interactive: nothing to ask, so the prompt's default stands in.\n const projectName = nameArg || \"my-app\";\n const targetDirectory = path.resolve(process.cwd(), projectName);\n const templateDirectory = path.resolve(cliRoot!, \"templates\", \"template\");\n const pmCommands = getPMCommands(pm);\n\n return {\n projectName: path.basename(targetDirectory),\n git: args[\"--git\"] ?? false,\n installDeps: installFlag,\n targetDirectory,\n templateDirectory,\n databaseUrl: args[\"--database-url\"] || undefined,\n introspect: args[\"--introspect\"] || false,\n preset: templateArg || \"blog\",\n explicitPreset: !!templateArg,\n headless: headlessArg ?? false,\n pm,\n pmCommands,\n cloudProject: args[\"--project\"] || undefined,\n setupKey: args[\"--setup-key\"] || undefined,\n cloudUrl: resolveCloudUrl(rawArgs)\n };\n }\n\n // A non-interactive stdin (CI, a pipe, no TTY) can't answer prompts:\n // inquirer either blocks forever waiting for input or aborts with a raw\n // ExitPromptError stack trace. Fail fast with actionable guidance instead.\n if (!process.stdin.isTTY) {\n console.error(chalk.red(\"Cannot prompt: this is a non-interactive terminal (no TTY).\"));\n console.error(chalk.yellow(\" Re-run with --yes to accept defaults, passing any choices as flags, e.g.:\"));\n console.error(chalk.yellow(` rebase init ${nameArg || \"my-app\"} --yes --template blog`));\n console.error(chalk.gray(\" Options: --template <blog|ecommerce|blank> --headless --database-url <url> --install --git\"));\n process.exit(1);\n }\n\n const questions = buildInitQuestions({\n nameArg,\n templateArg,\n headlessArg,\n hasGitFlag: !!args[\"--git\"],\n hasInstallFlag,\n pm\n });\n\n\n const answers = await inquirer.prompt(questions);\n\n const targetDirectory = path.resolve(process.cwd(), nameArg || answers.projectName);\n const projectName = path.basename(targetDirectory);\n const templateDirectory = path.resolve(cliRoot!, \"templates\", \"template\");\n const pmCommands = getPMCommands(pm);\n\n return {\n projectName,\n git: args[\"--git\"] || answers.git || false,\n installDeps: noInstall ? false : (args[\"--install\"] || answers.installDeps || false),\n targetDirectory,\n templateDirectory,\n databaseUrl: (answers.databaseUrl as string)?.trim() || undefined,\n introspect: answers.introspect || false,\n preset: templateArg || (answers.preset as TemplatePreset) || \"blog\",\n // Only a flag is \"explicit\" here: the interactive path never asks for a\n // preset once baas is chosen, so it can't produce a conflicting answer.\n explicitPreset: !!templateArg,\n headless: headlessArg ?? Boolean(answers.headless),\n pm,\n pmCommands,\n cloudProject: args[\"--project\"] || undefined,\n setupKey: args[\"--setup-key\"] || undefined,\n cloudUrl: resolveCloudUrl(rawArgs)\n };\n}\n\n/**\n * Redeem the one-time setup key from the console's setup page and write the\n * `.rebase/cloud.json` link into the scaffold, so `rebase cloud deploy` etc.\n * work in the new directory with no further flags. `--project` carries the\n * project's slug (its subdomain, as shown in console URLs); the control plane\n * also accepts a raw id for old copies of the command.\n *\n * Best-effort by design: a failed link must never fail the scaffold, so every\n * exit path other than success is a warning plus instructions to link later.\n */\nasync function linkScaffoldToCloud(options: InitOptions): Promise<void> {\n if (!options.cloudProject && !options.setupKey) return;\n\n const linkLater = `Link it later with ${chalk.bold(\"rebase cloud login\")} then ${chalk.bold(\"rebase cloud link\")}.`;\n if (!options.cloudProject || !options.setupKey) {\n console.warn(chalk.yellow(\" --project and --setup-key go together; skipping the cloud link.\"));\n console.warn(chalk.yellow(` ${linkLater}`));\n return;\n }\n\n try {\n const res = await fetch(`${options.cloudUrl}/api/functions/setup-key/validate`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ projectId: options.cloudProject,\nsetupKey: options.setupKey })\n });\n const body = (await res.json().catch(() => ({}))) as {\n error?: { message?: string };\n project?: { id?: string | number; subdomain?: string; name?: string };\n };\n if (!res.ok || body.project?.id === undefined) {\n console.warn(chalk.yellow(` Could not verify the setup key: ${body.error?.message || res.statusText}`));\n console.warn(chalk.yellow(` ${linkLater}`));\n return;\n }\n writeLink(\n {\n url: String(options.cloudUrl),\n projectId: String(body.project.id),\n slug: body.project.subdomain,\n projectName: body.project.name\n },\n options.targetDirectory\n );\n console.log(\"\");\n console.log(` ${chalk.green(\"✓\")} Linked to cloud project ${chalk.bold(body.project.subdomain ?? options.cloudProject)}`);\n } catch (e) {\n console.warn(chalk.yellow(` Could not reach the control plane: ${e instanceof Error ? e.message : String(e)}`));\n console.warn(chalk.yellow(` ${linkLater}`));\n }\n}\n\n/**\n * Make the initial commit, after everything that writes into the project has run.\n *\n * It used to happen immediately after `git init`, which is before dependency\n * installation and before introspection — so `init --git --install` ended on a\n * dirty tree whose only untracked file was `pnpm-lock.yaml`. A lockfile is\n * precisely the thing that should be in a project's first commit, and a brand\n * new scaffold whose first `git status` is dirty invites the reader to conclude\n * the lockfile is deliberately ignored and never commit it at all.\n *\n * Introspection has the same shape: it generates `config/collections` and\n * `schema.generated.ts`, which belong in the commit describing the scaffold that\n * produced them.\n *\n * `git init` stays where it was. Creating the repository early costs nothing and\n * means a failed install still leaves the user a repository to commit into.\n */\nasync function commitScaffold(targetDirectory: string): Promise<void> {\n try {\n // Leaving the tree uncommitted makes the very first `git diff`\n // useless and hides the scaffold in a wall of untracked files.\n // .gitignore is already in place, so .env is never committed.\n await execa(\"git\", [\"add\", \"-A\"], { cwd: targetDirectory });\n // A machine with no user.email configured cannot commit at all.\n // Supply an identity only in that case, so a configured user still\n // authors their own initial commit.\n let identity: Record<string, string> = {};\n try {\n await execa(\"git\", [\"config\", \"user.email\"], { cwd: targetDirectory });\n } catch {\n identity = {\n GIT_AUTHOR_NAME: \"Rebase\",\n GIT_AUTHOR_EMAIL: \"noreply@rebase.pro\",\n GIT_COMMITTER_NAME: \"Rebase\",\n GIT_COMMITTER_EMAIL: \"noreply@rebase.pro\"\n };\n }\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit from Rebase\"], {\n cwd: targetDirectory,\n env: identity\n });\n } catch {\n console.warn(chalk.yellow(\" Warning: Failed to create the initial commit\"));\n }\n}\n\nasync function createProject(options: InitOptions) {\n const startedAt = Date.now();\n // Check if directory already exists and is not empty\n if (fs.existsSync(options.targetDirectory)) {\n if (fs.readdirSync(options.targetDirectory).length !== 0) {\n console.error(`${chalk.red.bold(\"ERROR\")} Directory \"${options.projectName}\" already exists and is not empty`);\n process.exit(1);\n }\n } else {\n fs.mkdirSync(options.targetDirectory, { recursive: true });\n }\n\n // Verify template exists\n try {\n await access(options.templateDirectory, fs.constants.R_OK);\n } catch {\n console.error(`${chalk.red.bold(\"ERROR\")} Template not found at ${options.templateDirectory}`);\n process.exit(1);\n }\n\n // Copy template files\n console.log(chalk.gray(\" Copying project files...\"));\n try {\n await cp(options.templateDirectory, options.targetDirectory, {\n recursive: true,\n filter: (source: string) => {\n const basename = path.basename(source);\n // Skip node_modules and .DS_Store\n return basename !== \"node_modules\" && basename !== \".DS_Store\";\n }\n });\n } catch (err: unknown) {\n console.error(`${chalk.red.bold(\"ERROR\")} Failed to copy template files: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n // npm/pnpm always strip files named .gitignore and .npmrc from published\n // tarballs, so the template ships them un-dotted and we restore the real\n // names here.\n for (const [from, to] of [[\"gitignore\", \".gitignore\"], [\"npmrc\", \".npmrc\"]] as const) {\n const shipped = path.join(options.targetDirectory, from);\n if (fs.existsSync(shipped)) {\n fs.renameSync(shipped, path.join(options.targetDirectory, to));\n }\n }\n\n // Apply the selected template preset (swap collection files)\n if (options.headless && options.explicitPreset) {\n // baas has no collections, so there is nothing for a preset to swap.\n // Say so rather than accepting the flag and silently dropping it.\n console.log(chalk.yellow(` Ignoring --template ${options.preset}: a headless project declares no collections.`));\n }\n if (!options.headless) {\n // When introspecting, the database is the source of truth: start from\n // the blank preset so example collections never register on top of\n // tables the database doesn't have.\n if (options.introspect && options.preset !== \"blank\") {\n console.log(chalk.gray(\" Using the blank template: collections will come from your database.\"));\n }\n await applyPreset(options.targetDirectory, options.introspect ? \"blank\" : options.preset);\n }\n\n // Reduce the project to the selected shape\n await applyHeadless(options.targetDirectory, options.headless);\n\n // Replace placeholder project name in package.json files\n await replacePlaceholders(options);\n\n // Rename .env.example to .env if it exists and randomize secrets\n await configureEnvFile(options.targetDirectory, options.databaseUrl);\n\n // The manifest's build command is the project's package manager, not npm.\n // The template has to spell one of them, and `npm run build --workspace\n // frontend` in a pnpm project is a second package manager reading a\n // lockfile it did not write.\n await writeProjectPackageManagerIntoManifest(options.targetDirectory, options.pmCommands);\n\n // Create the repository now, but commit at the very end — see\n // commitScaffold below for why the two halves are separated.\n let gitInitialized = false;\n if (options.git) {\n console.log(chalk.gray(\" Initializing git repository...\"));\n try {\n await execa(\"git\", [\"init\"], { cwd: options.targetDirectory });\n // Name the branch `main` rather than inheriting whatever\n // `init.defaultBranch` is (often still `master`). `git init -b` would\n // be the obvious way, but it needs git >= 2.28; rewriting HEAD works\n // on every version and is safe before the first commit.\n try {\n await execa(\"git\", [\"symbolic-ref\", \"HEAD\", \"refs/heads/main\"], { cwd: options.targetDirectory });\n } catch {\n // Leave the default branch name; not worth failing the scaffold.\n }\n gitInitialized = true;\n } catch {\n console.warn(chalk.yellow(\" Warning: Failed to initialize git repository\"));\n }\n }\n\n const { pm, pmCommands } = options;\n const installCmd = pmCommands.install;\n const execCmd = pmCommands.exec(\"rebase\", [\"schema\", \"introspect\", \"--force\"]);\n const generateCmd = pmCommands.exec(\"rebase\", [\"schema\", \"generate\", \"--collections\", \"../config/collections\"]);\n\n if (options.installDeps) {\n console.log(\"\");\n console.log(chalk.gray(` Installing dependencies with ${pm}...`));\n console.log(\"\");\n try {\n await execa(installCmd[0], installCmd.slice(1), {\n cwd: options.targetDirectory,\n stdio: \"inherit\"\n });\n } catch {\n console.warn(chalk.yellow(` Warning: Failed to install dependencies. You may need to run \\`${installCmd.join(\" \")}\\` manually.`));\n }\n }\n\n // Whether introspection actually ran and produced collections. The next\n // steps below report what really happened, so a skipped or failed\n // introspection is never announced as a success.\n let introspected = false;\n\n if (options.introspect) {\n console.log(\"\");\n if (options.installDeps) {\n console.log(chalk.gray(\" Introspecting database and generating collections...\"));\n console.log(\"\");\n try {\n // --force overwrites template example collections with real ones\n await execa(execCmd[0], execCmd.slice(1), {\n cwd: options.targetDirectory,\n stdio: \"inherit\"\n });\n // The template ships a schema.generated.ts for the example blog\n // collections; regenerate it from the introspected collections or\n // the backend serves a schema that doesn't match the database.\n await execa(generateCmd[0], generateCmd.slice(1), {\n cwd: options.targetDirectory,\n stdio: \"inherit\"\n });\n console.log(chalk.green(\" Database successfully introspected!\"));\n introspected = true;\n } catch {\n console.warn(chalk.yellow(\" Warning: Failed to introspect database automatically.\"));\n console.warn(chalk.yellow(` You can run \\`${execCmd.join(\" \")}\\` then \\`${generateCmd.join(\" \")}\\` manually after setup.`));\n }\n } else {\n console.warn(chalk.yellow(\" Skipping introspection because dependencies were not installed.\"));\n console.warn(chalk.yellow(` Run \\`${installCmd.join(\" \")}\\` then \\`${execCmd.join(\" \")}\\` manually.`));\n }\n }\n\n if (gitInitialized) await commitScaffold(options.targetDirectory);\n\n await linkScaffoldToCloud(options);\n\n // Success message\n console.log(\"\");\n console.log(`${chalk.green.bold(\"✓\")} Project ${chalk.bold(options.projectName)} created successfully!`);\n console.log(\"\");\n console.log(chalk.bold(\"Next steps:\"));\n console.log(\"\");\n const runDev = pmCommands.run(\"dev\");\n const runDbPush = pmCommands.run(\"db:push\");\n const isBaas = options.headless;\n // The path the user has to type, not the project's basename: `init\n // apps/my-app` must say `cd apps/my-app`, and `init .` needs no cd at all\n // because they are already standing in the project.\n const cdTarget = formatCdTarget(process.cwd(), options.targetDirectory);\n if (cdTarget) {\n console.log(` ${chalk.cyan(\"cd\")} ${cdTarget}`);\n }\n if (!options.installDeps) {\n console.log(` ${chalk.cyan(installCmd.join(\" \"))}`);\n }\n console.log(\"\");\n\n if (options.databaseUrl) {\n if (introspected) {\n console.log(chalk.gray(\" # Database has been introspected & collections generated!\"));\n console.log(chalk.gray(\" # Start the development server (frontend + backend):\"));\n console.log(` ${chalk.cyan(runDev.join(\" \"))}`);\n } else if (options.introspect) {\n // Introspection was requested but did not run. Point at the steps\n // that finish the job rather than claiming collections exist.\n console.log(chalk.gray(\" # Introspection did not run — finish it with:\"));\n console.log(` ${chalk.cyan(execCmd.join(\" \"))}`);\n console.log(` ${chalk.cyan(generateCmd.join(\" \"))}`);\n console.log(\"\");\n console.log(chalk.gray(\" # Then start the development server:\"));\n console.log(` ${chalk.cyan(runDev.join(\" \"))}`);\n } else {\n console.log(chalk.gray(\" # Your custom database is configured in .env.\"));\n console.log(chalk.gray(\" # If the database is empty, push the Rebase schema to initialize it:\"));\n console.log(` ${chalk.cyan(runDbPush.join(\" \"))}`);\n console.log(\"\");\n console.log(chalk.gray(\" # Then start the development server:\"));\n console.log(` ${chalk.cyan(runDev.join(\" \"))}`);\n }\n } else if (isBaas) {\n // One step, then the thing that is actually this mode's job. `dev`\n // starts the database itself; a headless project has no collections, so\n // there is no schema to push and the tables are the developer's to\n // create.\n console.log(chalk.gray(\" # A local database configuration has been generated in .env.\"));\n console.log(chalk.gray(\" # 1. Start everything — the database comes up with it:\"));\n console.log(` ${chalk.cyan(runDev.join(\" \"))}`);\n console.log(\"\");\n console.log(chalk.gray(\" # 2. Create your tables (migrations, SQL, any tool you like).\"));\n console.log(chalk.gray(\" # A table is served once it has an authorization model, i.e.\"));\n console.log(chalk.gray(\" # row-level security enabled plus at least one policy:\"));\n console.log(` ${chalk.cyan(\"ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;\")}`);\n console.log(chalk.gray(\" # The API logs any table it skips, and why.\"));\n } else {\n // The whole first run, in one command.\n //\n // Deliberately does NOT say \"container\". This branch is the one a new\n // project takes, and it is precisely the branch with no container in it:\n // `.env` ships DATABASE_URL commented out, so `dev` starts the managed\n // PGlite database rather than Docker. Saying otherwise sent a reader who\n // had no Docker installed off to install it, to satisfy a step that was\n // never going to run — and made the whole quickstart look like it\n // required a daemon it does not.\n //\n // \"schema\" covers two things `dev` now does before serving: generating\n // the Drizzle schema from the collections, and applying the collections\n // to the database. The push-and-Docker steps that used to be printed\n // here are still documented under `rebase dev --help`.\n console.log(chalk.gray(\" # A local database configuration has been generated in .env.\"));\n console.log(chalk.gray(\" # Start everything — the database and schema are set up for you,\"));\n console.log(chalk.gray(\" # with no Docker and nothing else to install:\"));\n console.log(` ${chalk.cyan(runDev.join(\" \"))}`);\n console.log(\"\");\n console.log(chalk.gray(\" # To use a Postgres of your own instead, uncomment DATABASE_URL in .env.\"));\n }\n\n console.log(\"\");\n // Both halves of the first-admin rule, once, here.\n //\n // `init` has just written REBASE_ADMIN_EMAIL and a generated password into\n // `.env`, and they belong to the *production* boot — the compose stack, where\n // the first-registration window is shut. `rebase dev` reads the same file, so\n // without this line the honest reading of that `.env` is \"these are my\n // credentials\", and the first documented step (register, become the admin)\n // reads as broken.\n console.log(chalk.gray(\" # Sign in: the first account you register becomes the admin.\"));\n console.log(chalk.gray(\" # In production (docker compose) that window is shut and the account named by\"));\n console.log(chalk.gray(\" # REBASE_ADMIN_EMAIL in .env is created at boot instead.\"));\n\n console.log(\"\");\n // `--headless --introspect` had these two claims fighting: the step above\n // announced \"collections generated!\" and this line then said there are none.\n // Both were reachable at once, and the reader has to believe one of them.\n console.log(isBaas\n ? introspected\n ? chalk.gray(\"This starts a headless API (Hono + PostgreSQL) over the collections just \")\n + chalk.gray(\"generated from your database in config/collections. Edit them to change what the \")\n + chalk.gray(\"API exposes; docs are at /api/swagger.\")\n : chalk.gray(\"This starts a headless API (Hono + PostgreSQL). There are no collection files: \")\n + chalk.gray(\"the API is derived from your database schema. Once it serves a table, docs are at /api/swagger.\")\n : chalk.gray(\"This starts both the backend (Hono + PostgreSQL)\")\n + chalk.gray(\" and the frontend (Vite + React) concurrently.\"));\n console.log(\"\");\n console.log(chalk.gray(\"Docs: https://rebase.pro/docs\"));\n console.log(chalk.gray(\"GitHub: https://github.com/rebasepro/rebase\"));\n console.log(\"\");\n console.log(chalk.bold(\"🤖 AI Agent Skills\"));\n console.log(\"\");\n console.log(chalk.gray(\" Install Rebase agent skills for your AI coding assistant:\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(\"rebase skills install\")} ${chalk.gray(\"or\")} ${chalk.cyan(pmCommands.run(\"skills:install\").join(\" \"))}`);\n console.log(\"\");\n\n // Asked here, at the very end, and never before: the project exists, it\n // worked, and the user has something to judge us on. Nothing has been\n // written or transmitted up to this line — declining leaves no id and no\n // file. See telemetry/consent.ts for why the order matters.\n //\n // `--yes` and non-TTY runs never reach the prompt, so CI behaviour is\n // unchanged.\n const initProperties = {\n preset: options.headless ? \"none\" : options.preset,\n headless: Boolean(options.headless),\n package_manager: options.pm,\n installed_deps: Boolean(options.installDeps),\n introspected,\n own_database: Boolean(options.databaseUrl),\n cloud_linked: Boolean(options.cloudProject),\n git: Boolean(options.git),\n duration: durationBucket(Date.now() - startedAt)\n };\n // `reAskDeclined`: scaffolding is the one moment where asking again is an\n // offer rather than nagging. See PromptOptions.\n if (await promptForConsent({ reAskDeclined: true })) {\n await recordEvent(\"cli.init\", initProperties, { projectRoot: options.targetDirectory });\n }\n}\n\n/**\n * Apply a template preset by replacing the default collection files.\n *\n * The template ships with blog collections at the top level and\n * preset alternatives under `config/collections/presets/<name>/`.\n * This function swaps the active collection files and removes the\n * presets directory so the final project is clean.\n */\n/**\n * Reduce the scaffolded project to the chosen shape.\n *\n * The base template is the full triad. `--headless` drops the frontend and the\n * declared collections — there is nothing to define, since the server derives\n * its API from the database — and overlays the files that differ.\n *\n * The config *package* stays, holding only `storageAuthorize`. Storage is not\n * under row-level security, so a deployment with file storage enabled and no\n * access model serves every user's files to every signed-in user; the server\n * refuses to boot in that state. Deleting the package outright would leave a\n * headless project with nowhere to put the hook, and the scaffold's own\n * docker-compose.yml enables storage — so the first `docker compose up` would\n * crash-loop.\n */\nasync function applyHeadless(targetDirectory: string, headless: boolean): Promise<void> {\n if (!headless) return;\n\n fs.rmSync(path.join(targetDirectory, \"frontend\"), { recursive: true,\nforce: true });\n // Collections only. `rebase build` reads the absence of this directory as\n // \"introspect from the database\", and the overlay replaces config/index.ts\n // with one that exports the storage hook alone.\n fs.rmSync(path.join(targetDirectory, \"config\", \"collections\"), { recursive: true,\nforce: true });\n for (const stray of [\"cms.d.ts\", \"frontend-assets.d.ts\"]) {\n fs.rmSync(path.join(targetDirectory, \"config\", stray), { force: true });\n }\n // Generated from collection files; a headless project reads the live schema.\n fs.rmSync(path.join(targetDirectory, \"backend\", \"src\", \"schema.generated.ts\"), { force: true });\n\n const overlayDir = path.resolve(cliRoot!, \"templates\", \"overlays\", \"baas\");\n if (!fs.existsSync(overlayDir)) {\n console.error(`${chalk.red.bold(\"ERROR\")} BaaS template overlay not found at ${overlayDir}`);\n process.exit(1);\n }\n\n await cp(overlayDir, targetDirectory, {\n recursive: true,\n force: true,\n filter: (source: string) => {\n const basename = path.basename(source);\n return basename !== \"node_modules\" && basename !== \".DS_Store\";\n }\n });\n}\n\n/**\n * Rewrite `rebase.json`'s static-app build command for this project's package manager.\n *\n * The template must spell one of them, and it spells npm. In a pnpm project\n * that is a second package manager invoked against a lockfile it did not\n * write — `rebase build` then either installs a second tree or fails on a\n * workspace flag npm and pnpm spell differently.\n */\nasync function writeProjectPackageManagerIntoManifest(\n targetDirectory: string,\n pmCommands: PMCommands\n): Promise<void> {\n const manifestPath = path.join(targetDirectory, \"rebase.json\");\n if (!fs.existsSync(manifestPath)) return;\n\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as {\n apps?: Record<string, { type?: string; root?: string; build?: string }>;\n };\n let changed = false;\n for (const app of Object.values(manifest.apps ?? {})) {\n if (app.type !== \"static\" || !app.root || !app.build) continue;\n const rewritten = pmCommands.runWorkspace(app.root, \"build\").join(\" \");\n if (rewritten !== app.build) {\n app.build = rewritten;\n changed = true;\n }\n }\n if (changed) {\n fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 4)}\\n`, \"utf8\");\n }\n } catch {\n // A manifest that will not parse is `rebase build`'s problem to report,\n // and scaffolding must not fail on a cosmetic rewrite.\n }\n}\n\nasync function applyPreset(targetDirectory: string, preset: TemplatePreset): Promise<void> {\n const collectionsDir = path.join(targetDirectory, \"config\", \"collections\");\n const presetsDir = path.join(collectionsDir, \"presets\");\n\n if (preset !== \"blog\") {\n const presetDir = path.join(presetsDir, preset);\n if (!fs.existsSync(presetDir)) {\n console.warn(chalk.yellow(` Warning: Preset \"${preset}\" not found, falling back to blog template.`));\n cleanupPresets(presetsDir);\n return;\n }\n\n // Remove the default blog collection files (keep users.ts — it's shared)\n const blogFiles = [\"posts.ts\", \"authors.ts\", \"tags.ts\", \"index.ts\"];\n for (const file of blogFiles) {\n const filePath = path.join(collectionsDir, file);\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n }\n\n // Copy preset files into the collections directory\n const presetFiles = fs.readdirSync(presetDir).filter(f => f.endsWith(\".ts\"));\n for (const file of presetFiles) {\n fs.copyFileSync(\n path.join(presetDir, file),\n path.join(collectionsDir, file)\n );\n }\n }\n\n // Always clean up the presets directory — it shouldn't ship with the final project\n cleanupPresets(presetsDir);\n}\n\nfunction cleanupPresets(presetsDir: string): void {\n if (fs.existsSync(presetsDir)) {\n fs.rmSync(presetsDir, { recursive: true,\nforce: true });\n }\n}\n\n/**\n * The one registry call `init` makes, and what it is for.\n *\n * Every `@rebasepro/*` package in this repository carries the same version —\n * `check:publishable-set` fails the build on the first PR after a bump if any\n * of them drifts — so the version to pin is known before the network is\n * touched: it is this CLI's own. Asking npm eleven times, once per package,\n * bought nothing but eleven chances to hang. On a slow connection that was the\n * slowest part of `init`; on no connection it was eleven timeouts before a\n * fallback to `\"latest\"`, which is the one answer that produces a project\n * mixing framework eras.\n *\n * One call remains, and it asks a different question. Lockstep is enforced in\n * the repository, not on the registry: a release can still ship the CLI and\n * leave a package behind, which is exactly what happened to\n * `@rebasepro/agent-skills` across three releases. So this probes a single\n * package — `@rebasepro/server`, the one a project cannot run without — to see\n * whether this version really made it out. A gap is a refusal, because the\n * alternative is scaffolding a project that cannot install.\n *\n * Unreachable is NOT a refusal. `init` offline is a legitimate thing to do,\n * and the pin it would write is the same pin the probe would have confirmed.\n * It says so and carries on.\n */\ntype ReleaseProbe =\n | { kind: \"published\" }\n | { kind: \"gap\"; found: string }\n | { kind: \"unreachable\"; reason: string };\n\n/** The package the probe asks about. Not the CLI: the CLI is what is running. */\nconst RELEASE_PROBE_PACKAGE = \"@rebasepro/server\";\n\nasync function probeRelease(version: string): Promise<ReleaseProbe> {\n try {\n const { stdout } = await execa(\"npm\", [\"view\", `${RELEASE_PROBE_PACKAGE}@${version}`, \"version\"]);\n if (stdout.trim() === version) return { kind: \"published\" };\n // npm answers an unpublished version with empty output rather than an\n // error on some registries. Empty is a gap, not a success.\n return { kind: \"gap\", found: stdout.trim() || \"nothing\" };\n } catch (error) {\n const text = `${(error as { stderr?: string }).stderr ?? \"\"}${(error as Error).message ?? \"\"}`;\n if (/E404|404 Not Found|No match(ing)? version/i.test(text)) {\n return { kind: \"gap\", found: \"nothing\" };\n }\n return { kind: \"unreachable\", reason: firstLine(text) || \"the registry could not be reached\" };\n }\n}\n\nfunction firstLine(text: string): string {\n return text.split(\"\\n\").map(l => l.trim()).filter(Boolean)[0] ?? \"\";\n}\n\nasync function replacePlaceholders(options: InitOptions) {\n const filesToProcess = TEMPLATE_PLACEHOLDER_FILES;\n\n // `unknown` only when the manifest could not be read at all, which is the\n // same \"nothing to pin, nothing to confirm\" case `latest` used to stand for.\n const version = cliVersion();\n\n const fileContents = new Map<string, string>();\n const allPackages = new Set<string>();\n\n for (const file of filesToProcess) {\n const fullPath = path.resolve(options.targetDirectory, file);\n if (!fs.existsSync(fullPath)) continue;\n const content = fs.readFileSync(fullPath, \"utf-8\");\n fileContents.set(fullPath, content);\n\n const matches = [...content.matchAll(/\"(@rebasepro\\/[^\"]+)\":\\s*\"workspace:\\*\"/g)];\n for (const match of matches) allPackages.add(match[1]);\n }\n\n // `latest` means this CLI could not read its own manifest — there is no\n // version to confirm, and nothing to gain from asking.\n const skipProbe = parseEnvBoolean(process.env.REBASE_E2E) === true || version === \"unknown\";\n const probe: ReleaseProbe = skipProbe ? { kind: \"published\" } : await probeRelease(version);\n\n if (probe.kind === \"gap\") {\n throw new Error(\n `Rebase ${version} is not fully published to npm.\\n\\n` +\n `${RELEASE_PROBE_PACKAGE} has no ${version} release — the registry has ${probe.found}.\\n` +\n `Every @rebasepro package ships at one version, so scaffolding would pin ${allPackages.size}\\n` +\n `dependencies at a version that is not there, and the install would fail.\\n\\n` +\n \"That is a release gap in Rebase itself — not a problem with your machine,\\n\" +\n \"your network, or your package manager.\\n\\n\" +\n \"Stopped before writing dependency versions or installing anything. The\\n\" +\n `project directory ${path.basename(options.targetDirectory)}/ was created and is safe to delete.\\n` +\n \"Please report this.\"\n );\n }\n\n if (probe.kind === \"published\") {\n console.log(chalk.gray(` Pinning ${allPackages.size} @rebasepro package(s) to ${version}...`));\n }\n\n if (probe.kind === \"unreachable\") {\n console.log(chalk.gray(` Pinning @rebasepro packages to ${version} (this CLI's version).`));\n console.log(chalk.yellow(` Could not reach npm to confirm the release: ${probe.reason}`));\n console.log(chalk.gray(\" The pin is right either way — install will say so if the version is missing.\"));\n }\n\n for (const [fullPath, originalContent] of fileContents.entries()) {\n let content = originalContent.replace(/\\{\\{PROJECT_NAME\\}\\}/g, options.projectName);\n for (const pkgName of allPackages) {\n content = content.replace(\n new RegExp(`\"${pkgName}\":\\\\s*\"workspace:\\\\*\"`, \"g\"),\n `\"${pkgName}\": \"${version}\"`\n );\n }\n fs.writeFileSync(fullPath, content, \"utf-8\");\n }\n}\n\n\n/** `undefined` binds the wildcard address, which is a different question — see isPortAvailable. */\nfunction canBind(port: number, host?: string): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once(\"error\", (err: NodeJS.ErrnoException) => {\n // The host has no such address family at all — a v4-only machine\n // asked about `::1`. Nothing can be listening on an address that\n // cannot exist, so this is free rather than taken.\n resolve(err.code === \"EAFNOSUPPORT\" || err.code === \"EADDRNOTAVAIL\");\n });\n server.once(\"listening\", () => {\n server.close(() => resolve(true));\n });\n if (host === undefined) server.listen(port);\n else server.listen(port, host);\n });\n}\n\n/**\n * Whether `port` is free — on the wildcard address *and* on both loopback addresses.\n *\n * All three, because on macOS/BSD a successful bind does not mean the port is\n * unused. Sockets carry `SO_REUSEADDR` (Node sets it), under which a wildcard\n * bind and a specific-address bind on the same port do not conflict — in either\n * direction. So each probe alone has a blind spot, and they are different ones:\n *\n * - **Wildcard only** (what this used to do) misses a server bound to\n * `127.0.0.1` and `[::1]` — a Homebrew or Postgres.app install, i.e. most\n * developer machines. 5432 was reported free while it was already serving\n * another project's database. Docker then published `*:5432` for the same\n * reason and the container started cleanly, with no \"port already allocated\"\n * error anywhere to hint at the collision. `DATABASE_URL` pointed at\n * `localhost:5432`, `localhost` resolves to `::1` first, and every command\n * reported success while reading and writing the *pre-existing* database — a\n * `db push` would have created tables, roles and RLS policies inside it.\n *\n * - **Loopback only** misses the opposite case: Docker Desktop publishes a\n * container's port on `*`, and a specific-address bind succeeds right past it.\n * That port is free to probe and unusable to publish, so `docker compose up -d\n * db` fails on \"Bind for 0.0.0.0:PORT failed: port is already allocated\" —\n * loudly, but only after the project has been generated around the bad port.\n *\n * Requiring all three costs three sockets and leaves neither gap. The wildcard\n * bind is the one the container itself has to make; the loopback binds are the\n * addresses `DATABASE_URL` will actually name.\n */\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return (await canBind(port)) && (await canBind(port, \"127.0.0.1\")) && (await canBind(port, \"::1\"));\n}\n\nasync function findAvailablePort(startPort: number): Promise<number> {\n let port = startPort;\n while (!(await isPortAvailable(port))) {\n port++;\n }\n return port;\n}\n\n/**\n * The CLI's own version, which is the runtime image tag a scaffolded project\n * pins. They move together: the CLI, the packages and the runtime image are cut\n * from one release, so the version that installed the project is the version\n * whose runtime can boot its bundle.\n *\n * Falls back to `latest` only when the CLI cannot read its own manifest — a\n * floating tag is worse than a pinned one, but better than a compose file that\n * names a version that was never published.\n */\nfunction readCliVersion(): string {\n const version = cliVersion();\n return version === \"unknown\" ? \"latest\" : version;\n}\n\n/**\n * The runtime image tag to pin, given the version of the CLI doing the scaffolding.\n *\n * Only a stable release publishes `rebasepro/server` — a multi-arch build on\n * every push to main would cost minutes per commit for an image nobody pulls.\n * So pinning a prerelease CLI's own version writes a tag that cannot exist, and\n * `docker compose up` fails on `manifest unknown`, which is the same dead end\n * as the missing-repository bug this pinning was added to prevent.\n *\n * A prerelease therefore falls back to `latest`, which is correct rather than\n * merely available: a bundle's manifest declares the runtime range it needs\n * (`^1`), the image supplies only `@rebasepro/server`, and the framework a\n * bundle runs is installed from its own `deps.declared` at boot. The current\n * stable runtime boots a canary bundle by design.\n *\n * A floating tag is a real cost — it is what pinning exists to avoid — so say\n * so in the file rather than leaving a reader to discover it.\n */\nexport function resolveRuntimeImageTag(cliVersion: string): { tag: string; note?: string } {\n // Semver prerelease: everything after the first `-`. `0.13.1-canary.gcd6689e`.\n if (/^\\d+\\.\\d+\\.\\d+-/.test(cliVersion)) {\n return {\n tag: \"latest\",\n note: `# Scaffolded by a prerelease CLI (${cliVersion}), which publishes no runtime image,\\n` +\n \"# so this floats to the newest stable runtime. Pin an exact version once you\\n\" +\n \"# deploy: a moving tag changes what you are running with no version changing.\"\n };\n }\n return { tag: cliVersion };\n}\n\n/**\n * Set `KEY=value` in a .env body, whether the key ships set, commented out or\n * missing entirely.\n *\n * The missing case is not hypothetical: `configureEnvFile` runs against\n * whatever `.env.example` is in the target directory, which for a project\n * scaffolded from an older template — or from one somebody edited — may not\n * carry a key this version of `init` is expected to write. Silently skipping it\n * produces a `.env` that satisfies no `${VAR:?…}` in the compose file, which\n * surfaces as a stack that refuses to interpolate rather than as anything\n * pointing back here.\n */\nfunction setEnvValue(content: string, key: string, value: string, header?: string): string {\n const line = new RegExp(`^#?\\\\s*${key}=.*$`, \"m\");\n if (line.test(content)) return content.replace(line, `${key}=${value}`);\n return `${content.trimEnd()}\\n\\n${header ? `${header}\\n` : \"\"}${key}=${value}\\n`;\n}\n\nexport async function configureEnvFile(targetDirectory: string, databaseUrl?: string) {\n const envExamplePath = path.join(targetDirectory, \".env.example\");\n const envPath = path.join(targetDirectory, \".env\");\n if (fs.existsSync(envExamplePath) && !fs.existsSync(envPath)) {\n // Copy .env.example → .env (keep .env.example as a reference in the repo)\n fs.copyFileSync(envExamplePath, envPath);\n // Owner-only from the first byte. `copyFileSync` copies the *source's*\n // permissions and the packaged `.env.example` is 0644, so the file that\n // is about to receive a generated JWT_SECRET, the database password and\n // REBASE_SERVICE_KEY was world-readable for the whole of `init` — on a\n // shared build box or a multi-user machine, any local account could read\n // another project's service key, which the API treats as a full admin\n // credential. `.rebase/state.json` (dev-port.ts) and `telemetry.json`\n // are both 0600 for the same reason; this file holds strictly more.\n fs.chmodSync(envPath, 0o600);\n\n // Generate secure random strings\n const jwtSecret = crypto.randomBytes(32).toString(\"hex\");\n const dbPassword = crypto.randomBytes(16).toString(\"hex\");\n const serviceKey = crypto.randomBytes(48).toString(\"base64\");\n // base64url rather than base64 or hex: 24 characters, comfortably past\n // the runtime's 12-character floor, and every character it can produce\n // is one dotenv and Compose interpolation read back unchanged. `+`, `/`\n // and `=` are fine in a .env value but not obviously so to a reader\n // about to paste one into a shell, and `#` — which hex cannot produce\n // but a passphrase generator might — would truncate the line.\n const adminPassword = crypto.randomBytes(18).toString(\"base64url\");\n\n let envContent = fs.readFileSync(envPath, \"utf-8\");\n\n // The banner is written for the file being read as a template. This\n // copy *is* the filled-in one — it already carries a generated\n // JWT_SECRET, service key and database password — and telling its\n // reader to \"copy this file to .env and fill in the values\" invites\n // exactly the overwrite the README warns against two paragraphs later.\n envContent = envContent.replace(\n /^(# ║ {2})(Copy this file to \\.env and fill in the values)( +║)$/m,\n (_match, open: string, old: string, close: string) => {\n const replacement = \"Generated by `rebase init` — the secrets below are already set\";\n // Keep the box drawn: pad or clip to the width the line had.\n const width = old.length + close.length - 1;\n return open + replacement.slice(0, width).padEnd(width, \" \") + \"║\";\n }\n );\n\n envContent = envContent.replace(\n /^JWT_SECRET=.*$/m,\n `JWT_SECRET=${jwtSecret}`\n );\n\n // Ships commented out in .env.example. Left unset, the server generates\n // one on every boot and silently invalidates the previous run's tokens,\n // so write a stable one now rather than making each restart a logout.\n envContent = envContent.replace(\n /^#\\s*REBASE_SERVICE_KEY=.*$/m,\n `REBASE_SERVICE_KEY=${serviceKey}`\n );\n\n // Read back rather than hardcoded, so this tracks whatever PORT the\n // generated .env ends up carrying. `docker-compose.yml` publishes the\n // api as `${PORT:-3001}:3001`.\n const composeApiPort = /^PORT=(\\d+)/m.exec(envContent)?.[1] ?? \"3001\";\n\n // Also ships commented out, and left that way the very first command\n // this project tells you to run does not work.\n //\n // `docker-compose.yml` declares `CORS_ORIGINS: ${CORS_ORIGINS:?…}` on\n // the `api` service — deliberately required, because an API that\n // guesses its allowed origins eventually allows the wrong one. But\n // Compose interpolates the WHOLE file before selecting services, so\n // `docker compose up -d db` — step 1 of the \"Next steps\" printed at the\n // end of `rebase init` — failed on a variable the `db` service does not\n // use. So did `docker compose config`: the file could not be read at all.\n //\n // The guard is right; a generated project should satisfy it. The compose\n // stack serves the bundled admin from the `api` container on ${PORT},\n // so that is the origin a browser loads it from. A deployment still has\n // to set its own, and gets a visible CORS failure rather than a silent\n // one if it forgets.\n envContent = envContent.replace(\n /^#\\s*CORS_ORIGINS=.*$/m,\n `CORS_ORIGINS=http://localhost:${composeApiPort}`\n );\n\n // The first admin, named rather than raced for.\n //\n // `docker-compose.yml` runs the api service with NODE_ENV=production,\n // and in production the first-registration-becomes-admin window is\n // shut — deliberately, because the compose stack is serving before its\n // operator has typed anything and whoever found the sign-up form first\n // would own it. A closed window needs a way in that is not a race, and\n // this is it: the account is named in the same file that already holds\n // the JWT secret and the database password.\n //\n // Written by `init` rather than left for the reader, because the\n // compose file declares both with `${VAR:?…}`: unset, `docker compose\n // up` does not produce a deployment without an admin, it produces a\n // file that refuses to interpolate — and it refuses for `docker compose\n // up -d db` too, which is step 1 of the \"Next steps\" printed below.\n //\n // The address is a placeholder the login route accepts. Not\n // `admin@localhost`: `POST /auth/login` parses its body with\n // `z.string().email()`, which rejects a domain with no dot, so that\n // address seeds an account and then 400s on every attempt to use it.\n // The runtime now refuses it at boot; this default is one it accepts.\n envContent = setEnvValue(\n envContent,\n \"REBASE_ADMIN_EMAIL\",\n \"admin@example.com\",\n \"# ── The first admin account, in production only ──────────────────────\\n\" +\n \"# `rebase dev` ignores both of these: on a laptop the first account to\\n\" +\n \"# register becomes the admin, and it says so at boot. In production —\\n\" +\n \"# `docker compose up`, or anything with NODE_ENV=production — that\\n\" +\n \"# window is shut, because the server answers on a hostname before you\\n\" +\n \"# have typed anything. So the operator names the account here instead.\\n\" +\n \"# Created once, while the user table is empty. Change the email to\\n\" +\n \"# yours, sign in, and change the password below.\"\n );\n envContent = setEnvValue(envContent, \"REBASE_ADMIN_PASSWORD\", adminPassword);\n\n // Blank the build-time API URL rather than shipping `http://localhost:3001`.\n //\n // This is the one environment-specific value `init` used to leave alone,\n // and the chain that made it dangerous is fully closed: `.env.example`\n // ships the literal, `frontend/vite.config.ts` sets `envDir: \"..\"` so\n // `vite build` reads *this* file, and the managed bundle is built on the\n // developer's own machine — so `.env` being gitignored does not save\n // anyone. A stock scaffold deployed with `rebase cloud deploy` served\n // HTML that passed every health check while every XHR from the live site\n // went to the developer's laptop. `rebase cloud env set VITE_API_URL=…`\n // refuses build-time variables, so there was no recovery from the\n // platform side either.\n //\n // Empty is not a missing value, it is the correct one: the client falls\n // back to `window.location.origin`, which is the right shape for a\n // single-origin bundle and the only one that keeps working when a custom\n // domain is added. `rebase dev` injects the port it actually bound, so\n // local development is unaffected.\n // The template ships it blank, so this is belt-and-braces for a project\n // whose .env.example was edited or predates that change.\n envContent = envContent.replace(/^#?\\s*VITE_API_URL=.*$/m, \"VITE_API_URL=\");\n\n // Pin the runtime image `docker-compose.yml` pulls.\n //\n // The compose file reads `rebasepro/server:${REBASE_VERSION:-latest}`,\n // and unset it resolves to `latest` — a tag that moves under a running\n // deployment. That is precisely the hazard `cloudbuild-runtime.yaml`\n // designed away for the managed fleet, which pins releases by digest\n // because \"re-pushing a tag silently changes what the fleet is running\n // with no version anywhere changing\". A self-hoster deserves the same\n // guarantee, and it costs one line here.\n //\n // It also makes the compose header's upgrade instruction true: \"To\n // upgrade Rebase, change REBASE_VERSION and restart\" is a no-op while\n // the value is unset and the tag floats.\n const { tag: runtimeVersion, note } = resolveRuntimeImageTag(readCliVersion());\n const pinned = `${note ? `${note}\\n` : \"\"}REBASE_VERSION=${runtimeVersion}`;\n envContent = /^#?\\s*REBASE_VERSION=.*$/m.test(envContent)\n ? envContent.replace(/^#?\\s*REBASE_VERSION=.*$/m, pinned)\n : `${envContent.trimEnd()}\\n\\n# The Rebase runtime image tag docker-compose.yml pulls.\\n# Change this and restart to upgrade; your project bundle is untouched.\\n${pinned}\\n`;\n\n if (databaseUrl) {\n if (/[\\r\\n]/.test(databaseUrl)) {\n throw new Error(\"Invalid DATABASE_URL: multiline values are not allowed.\");\n }\n // A supplied URL used to be written through verbatim, which quietly\n // dropped the `search_path=public` pin the generated URL below has\n // always carried. Postgres defaults `search_path` to `\"$user\",\n // public`, and this project creates a `rebase` schema — so on any\n // database whose role happens to be named `rebase` (the name every\n // template, compose file and deployment doc uses), unqualified SQL\n // resolves to `$user` and the project's tables get created in\n // `rebase` instead of `public`. Pinning here makes the two branches\n // agree; a URL that already pins something keeps it.\n // Imported lazily: this is the only line in `init` that needs the\n // Postgres package, and a static import would load pg + drizzle on\n // every CLI invocation.\n const { pinSearchPath } = await import(\"@rebasepro/server-postgres\");\n const pinnedUrl = pinSearchPath(databaseUrl);\n // DATABASE_PASSWORD is still written even though the URL points\n // elsewhere: docker-compose.yml interpolates it into both\n // POSTGRES_PASSWORD and the backend's own DATABASE_URL, defaulting\n // to `${DATABASE_PASSWORD:-changeme}`. Omitting it here shipped a\n // compose stack whose database password was literally \"changeme\",\n // on a service that publishes a host port by default.\n //\n // A replacer function, not a replacement string: in a string, `$$`,\n // `$&` and `$'` are patterns, and a password is free to contain\n // them — `pa$$w0rd` reached .env as `pa$w0rd`.\n envContent = envContent.replace(\n /^DATABASE_URL=.*$/m,\n () => `DATABASE_URL=${pinnedUrl}\\nDATABASE_PASSWORD=${dbPassword}`\n );\n } else {\n const dbPort = await findAvailablePort(5432);\n envContent = envContent.replace(\n /^DATABASE_URL=.*$/m,\n // sslmode=disable: the paired docker-compose Postgres has no TLS,\n // and Go-based tooling (atlas, via `rebase db push`) defaults to\n // requiring SSL when the URL doesn't say otherwise.\n //\n // 127.0.0.1 rather than `localhost`: the name resolves to `::1`\n // first on macOS, so on a machine that already runs Postgres on\n // loopback the two addresses can reach two different servers.\n // An address cannot be ambiguous the way a name can.\n //\n // `%3D`, not a literal `=`, inside the `options` value. libpq\n // splits a URI query parameter on the FIRST `=` and rejects any\n // further one outright:\n // extra key/value separator \"=\" in URI query parameter: \"options\"\n // That is every libpq caller — `pg_dump`/`pg_restore` behind\n // `rebase db backup|restore`, and a plain `psql \"$DATABASE_URL\"`\n // copied out of this very file. It is not a version quirk; 15\n // through 18 all refuse it. node-postgres parses URLs itself and\n // accepts the literal form, which is why `rebase dev` and\n // `rebase db push` worked and this shipped broken for so long.\n // `pinSearchPath` (the --database-url branch above) has always\n // emitted the encoded form; this line is what disagreed.\n // Commented out, not omitted. `rebase dev` starts a managed\n // PostgreSQL when nothing names a database, which is what makes\n // a fresh project one command rather than four. The compose URL\n // stays here, one `#` away, because the alternative — a project\n // that mentions Docker nowhere — makes switching to it a\n // documentation lookup instead of an edit.\n // Deliberately short: the header copied from `.env.example`\n // sits directly above and already says what unset means. Saying\n // it twice, in the first section of the first file a new\n // developer opens, is how a generated file starts reading like\n // boilerplate nobody wrote on purpose.\n [\n \"# Commented out on purpose — that is what selects the managed database.\",\n \"# To use the docker-compose Postgres this project ships instead:\",\n \"# docker compose up -d db, then uncomment the line below.\",\n `# DATABASE_URL=postgresql://rebase_app:${dbPassword}@127.0.0.1:${dbPort}/rebase?options=-c%20search_path%3Dpublic&sslmode=disable`,\n `DATABASE_PASSWORD=${dbPassword}`\n ].join(\"\\n\")\n );\n\n // `.env.example` is copied to `.env` and then kept, as the reference\n // that gets committed — so it is the one file in the project that\n // still carries the template's defaults after everything else has\n // been rewritten. Two of them are actively dangerous once the port\n // is derived per project:\n //\n // - its `DATABASE_URL` is UNCOMMENTED, contradicting the rule the\n // rest of the scaffold now states (\"unset means the managed\n // database\"), and\n // - it names `localhost:5432`, while this project's compose\n // publishes ${dbPort}.\n //\n // Copying `.env.example` to `.env` is a near-universal habit, and on\n // a machine that already runs Postgres on 5432 — most developer\n // machines — the result is not a connection failure. It is a\n // successful connection to somebody else's database, which boot will\n // then provision. Comment it out and give it this project's port.\n const envExampleReference = path.join(targetDirectory, \".env.example\");\n if (fs.existsSync(envExampleReference)) {\n let exampleContent = fs.readFileSync(envExampleReference, \"utf-8\");\n exampleContent = exampleContent.replace(\n /^DATABASE_URL=postgresql:\\/\\/[^\\n]*$/m,\n [\n \"# Commented out on purpose — that is what selects the managed database.\",\n \"# To use the docker-compose Postgres this project ships instead:\",\n \"# docker compose up -d db, then uncomment the line below in .env\",\n \"# (with DATABASE_PASSWORD from that file, not the placeholder here).\",\n `# DATABASE_URL=postgresql://rebase_app:changeme@127.0.0.1:${dbPort}/rebase?options=-c%20search_path%3Dpublic&sslmode=disable`\n ].join(\"\\n\")\n );\n // The prose further down illustrates `sslmode=disable` with a\n // full DSN. It is commented and not meant to be copied whole,\n // but a file that names two different ports for one database\n // teaches the reader to distrust both.\n exampleContent = exampleContent.replaceAll(\n \"@localhost:5432/rebase\",\n `@127.0.0.1:${dbPort}/rebase`\n );\n fs.writeFileSync(envExampleReference, exampleContent, \"utf-8\");\n }\n\n // Also update docker-compose.yml with the dynamic host port if it has the default 5432 port mapping\n const dockerComposePath = path.join(targetDirectory, \"docker-compose.yml\");\n if (fs.existsSync(dockerComposePath)) {\n let dockerComposeContent = fs.readFileSync(dockerComposePath, \"utf-8\");\n dockerComposeContent = dockerComposeContent.replace(\n /-\\s*\"5432:5432\"/g,\n `- \"${dbPort}:5432\"`\n );\n fs.writeFileSync(dockerComposePath, dockerComposeContent, \"utf-8\");\n }\n }\n\n // `mode` only applies when the file is created, and this one exists\n // already — so chmod as well, exactly as `writeStateFile` does.\n fs.writeFileSync(envPath, envContent, {\n encoding: \"utf-8\",\n mode: 0o600\n });\n fs.chmodSync(envPath, 0o600);\n }\n}\n","/**\n * CLI command: generate-sdk\n *\n * Reads collection definitions from a specified directory (default: ./config/collections),\n * generates a typed TypeScript SDK, and writes it to the output directory (default: ./generated/sdk).\n *\n * Uses jiti for dynamic TypeScript import of collection files.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { CollectionConfig, computeSchemaVersion, deserializeCollections } from \"@rebasepro/types\";\nimport { CodegenError, generateSDK, GeneratedFile, toSafeIdentifier } from \"@rebasepro/codegen\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { findProjectRoot } from \"../utils/project\";\nimport { readLink } from \"./cloud/context\";\n\ninterface GenerateSDKArgs {\n collectionsDir: string;\n output: string;\n cwd: string;\n /**\n * Where to read the schema from instead of local source.\n *\n * `link` uses this checkout's linked project; anything else is treated as\n * the base URL of a Rebase backend. This is what lets a repository that\n * contains no collections — a separate frontend, a second web app — generate\n * a typed client from the project it talks to.\n */\n from?: string;\n /** Bearer token for the contract endpoint. Falls back to REBASE_SERVICE_KEY. */\n token?: string;\n help?: boolean;\n}\n\n/**\n * Dynamically load collection definitions from a directory.\n *\n * Expects the directory to have an index.ts/index.js that exports a default\n * array of CollectionConfig objects (matching the app/config/collections pattern).\n */\nasync function loadCollections(collectionsDir: string): Promise<CollectionConfig[]> {\n const absDir = path.resolve(collectionsDir);\n\n if (!fs.existsSync(absDir)) {\n throw new Error(`Collections directory not found: ${absDir}`);\n }\n\n // Try to import the index file using jiti (supports TypeScript natively)\n let jiti: (id: string, userOptions?: Record<string, unknown>) => (modulePath: string) => Record<string, unknown>;\n try {\n const jitiModule = await import(\"jiti\");\n jiti = (jitiModule.default || jitiModule) as typeof jiti;\n } catch {\n const installCmd = [...getPMCommands(detectPackageManager()).install, \"-D\", \"jiti\"].join(\" \");\n throw new Error(\n `Could not load 'jiti'. Install it with: ${installCmd}\\n` +\n \"jiti is required to dynamically import TypeScript collection definitions.\"\n );\n }\n\n const jitiInstance = jiti(absDir, {\n interopDefault: true,\n esmResolve: true\n });\n\n // Look for index file\n const indexCandidates = [\"index.ts\", \"index.js\", \"index.mjs\"];\n let indexPath: string | null = null;\n\n for (const candidate of indexCandidates) {\n const p = path.join(absDir, candidate);\n if (fs.existsSync(p)) {\n indexPath = p;\n break;\n }\n }\n\n if (!indexPath) {\n // Fallback: load each .ts/.js file individually\n console.log(chalk.yellow(\" No index file found, scanning individual collection files...\"));\n const collections: CollectionConfig[] = [];\n const files = fs.readdirSync(absDir).filter(f =>\n (f.endsWith(\".ts\") || f.endsWith(\".js\")) && !f.startsWith(\".\")\n );\n\n for (const file of files) {\n try {\n const mod = jitiInstance(path.join(absDir, file));\n const exported = mod.default || mod;\n if (exported && typeof exported === \"object\" && \"slug\" in exported) {\n collections.push(exported as CollectionConfig);\n } else if (Array.isArray(exported)) {\n collections.push(...exported);\n }\n } catch (err) {\n console.warn(chalk.yellow(` ⚠ Skipping ${file}: ${(err as Error).message}`));\n }\n }\n\n return collections;\n }\n\n // Import the index\n const mod = jitiInstance(indexPath);\n const exported = mod.default || mod;\n\n if (Array.isArray(exported)) {\n return exported as CollectionConfig[];\n } else if (typeof exported === \"object\" && exported !== null) {\n // Could be a named export like { collections: [...] }\n if (\"collections\" in exported && Array.isArray(exported.collections)) {\n return exported.collections;\n }\n // Or individual named exports\n const collections: CollectionConfig[] = [];\n for (const value of Object.values(exported)) {\n if (value && typeof value === \"object\" && \"slug\" in (value as CollectionConfig)) {\n collections.push(value as CollectionConfig);\n }\n }\n if (collections.length > 0) return collections;\n }\n\n throw new Error(\n `Could not extract collections from ${indexPath}.\\n` +\n \"Expected a default export of CollectionConfig[] or an object with named collection exports.\"\n );\n}\n\n/**\n * Write generated files to the output directory.\n */\nfunction writeFiles(outputDir: string, files: GeneratedFile[]): void {\n const absOutput = path.resolve(outputDir);\n\n // Create output directory\n fs.mkdirSync(absOutput, { recursive: true });\n\n for (const file of files) {\n const filePath = path.join(absOutput, file.path);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, file.content, \"utf-8\");\n }\n}\n\nfunction printSdkHelp(): void {\n console.log(`\n${chalk.bold(\"rebase generate-sdk\")} — generate a typed client from a project's schema\n\n${chalk.bold(\"Usage\")}\n rebase generate-sdk [options]\n\n${chalk.bold(\"Options\")}\n -c, --collections-dir <dir> Local collections directory (default: ./config/collections)\n -o, --output <dir> Where to write the SDK (default: ./generated/sdk)\n (--out is accepted too, as on 'rebase build')\n --from <link|url> Fetch the schema from a running project instead of\n local source. \"link\" uses this checkout's linked project.\n --token <token> Bearer token for the contract endpoint\n (default: $REBASE_SERVICE_KEY)\n -h, --help Show this help\n\n${chalk.bold(\"Examples\")}\n rebase generate-sdk From local collections\n rebase generate-sdk --from link From the linked project\n rebase generate-sdk --from https://api.acme.com From any Rebase backend\n`.trim());\n}\n\n/**\n * Fetch collections from a running project's contract endpoint.\n *\n * The payload replaces relation `target` functions with slug references, so it\n * has to be rehydrated before the generator sees it — the generator *calls*\n * `target()` to decide whether a foreign key is a string or a number, and a\n * missing target silently degrades that to a union rather than failing.\n */\nasync function fetchRemoteCollections(\n baseUrl: string,\n token: string | undefined\n): Promise<{ collections: CollectionConfig[]; schemaVersion: string }> {\n const url = `${baseUrl.replace(/\\/+$/, \"\")}/api/meta/contract`;\n\n const headers: Record<string, string> = { accept: \"application/json\" };\n if (token) headers.authorization = `Bearer ${token}`;\n\n let response: Response;\n try {\n response = await fetch(url, { headers });\n } catch (err) {\n console.log(chalk.red(` ✗ Could not reach ${url}`));\n console.log(chalk.gray(` ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n }\n\n if (response.status === 401 || response.status === 403) {\n console.log(chalk.red(` ✗ Not authorized to read the project contract (${response.status}).`));\n console.log(chalk.gray(\" The contract describes every table and relation, so it is admin-only.\"));\n console.log(chalk.gray(\" Pass --token, or set REBASE_SERVICE_KEY.\"));\n process.exit(1);\n }\n\n if (response.status === 404) {\n console.log(chalk.red(\" ✗ This server has no contract endpoint.\"));\n console.log(chalk.gray(\" It needs to be running Rebase 0.11 or newer.\"));\n process.exit(1);\n }\n\n if (!response.ok) {\n console.log(chalk.red(` ✗ Contract request failed with ${response.status}.`));\n process.exit(1);\n }\n\n const contract = await response.json() as {\n collections?: unknown[];\n schemaVersion?: string;\n };\n\n if (!Array.isArray(contract.collections)) {\n console.log(chalk.red(\" ✗ The contract response did not contain collections.\"));\n process.exit(1);\n }\n\n return {\n collections: deserializeCollections(contract.collections),\n schemaVersion: contract.schemaVersion ?? \"unknown\"\n };\n}\n\n/**\n * Decide whether the ambient service key may be sent to this host.\n *\n * `REBASE_SERVICE_KEY` grants full admin bypass. Attaching it to whatever URL\n * happened to be passed — or, worse, to whatever a committed `.rebase/cloud.json`\n * points at — would hand the project's most powerful credential to a host nobody\n * vetted. An explicit `--token` is a decision the caller made; the ambient\n * variable is not, so it only travels to the project this checkout is linked to.\n */\nfunction mayUseAmbientKey(target: string, cwd: string): boolean {\n const link = readLink(findProjectRoot(cwd) ?? cwd);\n if (!link?.apiUrl) return false;\n try {\n // Origin, not host: with a link recorded as https, an `http://` target\n // for the same host would otherwise pass and send the key in cleartext.\n return new URL(link.apiUrl).origin === new URL(target).origin;\n } catch {\n return false;\n }\n}\n\n/**\n * The base URL to show in the printed usage example.\n *\n * `rebase dev` binds a port derived from the project path, not 3001, and writes\n * the one it actually got to `.rebase/state.json`. Printing a hardcoded\n * `localhost:3001` sent people to a port nothing was listening on — or, with\n * several projects on one machine, to a different project's backend. Prefer the\n * port this project last ran on; fall back to the literal only when the project\n * has never been started.\n */\nexport function resolveExampleBaseUrl(cwd: string): string {\n const projectRoot = findProjectRoot(cwd) ?? cwd;\n try {\n const state = JSON.parse(fs.readFileSync(path.join(projectRoot, \".rebase\", \"state.json\"), \"utf-8\"));\n if (typeof state.baseUrl === \"string\" && state.baseUrl) return state.baseUrl;\n if (typeof state.port === \"number\") return `http://localhost:${state.port}`;\n } catch {\n // Never started, or the file is unreadable — fall through.\n }\n return \"http://localhost:3001\";\n}\n\n/** Whether a slug can be written as `rebase.data.<slug>` rather than a lookup. */\nexport function isIdentifierLike(slug: string): boolean {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(slug);\n}\n\n/** Resolve `--from` into a base URL, following the link file when asked. */\nfunction resolveSchemaSource(from: string, cwd: string): string {\n if (from !== \"link\") {\n // A bare hostname or a typo would otherwise be handed to `fetch` and fail\n // with something unhelpful; a non-http scheme has no business here at all.\n let parsed: URL;\n try {\n parsed = new URL(from);\n } catch {\n console.log(chalk.red(` ✗ \"${from}\" is not a valid URL.`));\n console.log(chalk.gray(\" Pass a full URL, e.g. https://api.example.com, or \\\"link\\\".\"));\n process.exit(1);\n }\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n console.log(chalk.red(\" ✗ The project URL must be http or https.\"));\n process.exit(1);\n }\n return from;\n }\n\n const projectRoot = findProjectRoot(cwd) ?? cwd;\n const link = readLink(projectRoot);\n\n if (!link) {\n console.log(chalk.red(\" ✗ This checkout is not linked to a project.\"));\n console.log(chalk.gray(\" Run `rebase cloud link <url>`, or pass --from <url>.\"));\n process.exit(1);\n }\n\n const apiUrl = link.apiUrl;\n if (!apiUrl) {\n console.log(chalk.red(\" ✗ The project link has no API URL.\"));\n console.log(chalk.gray(\" Re-link with `rebase cloud link <url>` to record one.\"));\n process.exit(1);\n }\n\n return apiUrl;\n}\n\n/**\n * Main entry point for the generate-sdk command.\n */\nexport async function generateSdkCommand(args: GenerateSDKArgs): Promise<void> {\n const { collectionsDir, output, cwd } = args;\n\n if (args.help) {\n printSdkHelp();\n return;\n }\n\n const resolvedCollectionsDir = path.isAbsolute(collectionsDir)\n ? collectionsDir\n : path.join(cwd, collectionsDir);\n\n const resolvedOutput = path.isAbsolute(output)\n ? output\n : path.join(cwd, output);\n\n console.log(\"\");\n console.log(chalk.bold(\" 🔧 Rebase SDK Generator\"));\n console.log(\"\");\n\n let collections: CollectionConfig[];\n let remoteSchemaVersion: string | undefined;\n\n if (args.from) {\n const baseUrl = resolveSchemaSource(args.from, cwd);\n console.log(` ${chalk.gray(\"Project:\")} ${baseUrl}`);\n console.log(` ${chalk.gray(\"Output:\")} ${resolvedOutput}`);\n console.log(\"\");\n console.log(chalk.cyan(\" → Fetching the project contract...\"));\n\n const ambient = mayUseAmbientKey(baseUrl, cwd)\n ? process.env.REBASE_SERVICE_KEY\n : undefined;\n\n if (!args.token && !ambient && process.env.REBASE_SERVICE_KEY) {\n console.log(chalk.dim(\n \" (not sending REBASE_SERVICE_KEY — this host is not the linked project; pass --token to override)\"\n ));\n }\n\n const remote = await fetchRemoteCollections(baseUrl, args.token || ambient);\n collections = remote.collections;\n remoteSchemaVersion = remote.schemaVersion;\n } else {\n // A headless project has no collections directory by design: its API is\n // introspected from the live database at boot, and there is nothing here\n // to generate a client from. The scaffold ships `pnpm generate:sdk`\n // anyway, so the documented headless path had a script that could only\n // ever fail — and it failed with a path, which reads as a broken install\n // rather than a question with an answer.\n if (!fs.existsSync(resolvedCollectionsDir)) {\n console.log(chalk.gray(\n \" ○ This project derives its API from the database — \"\n + \"run `rebase schema introspect` first.\"\n ));\n console.log(chalk.gray(\n ` Nothing to generate from: ${resolvedCollectionsDir} does not exist.`\n ));\n console.log(\"\");\n return;\n }\n console.log(` ${chalk.gray(\"Collections:\")} ${resolvedCollectionsDir}`);\n console.log(` ${chalk.gray(\"Output:\")} ${resolvedOutput}`);\n console.log(\"\");\n console.log(chalk.cyan(\" → Loading collection definitions...\"));\n collections = await loadCollections(resolvedCollectionsDir);\n }\n\n // Sort collections alphabetically by slug to ensure deterministic SDK generation\n collections.sort((a, b) => a.slug.localeCompare(b.slug));\n\n if (collections.length === 0) {\n console.log(chalk.red(\" ✗ No collections found. Nothing to generate.\"));\n process.exit(1);\n }\n\n console.log(chalk.green(` ✓ Found ${collections.length} collection(s): ${collections.map(c => c.slug).join(\", \")}`));\n console.log(\"\");\n\n // 2. Generate SDK files\n console.log(chalk.cyan(\" → Generating SDK files...\"));\n let files: GeneratedFile[];\n try {\n files = generateSDK(collections);\n } catch (err) {\n // A schema that cannot be expressed as valid TypeScript — two slugs\n // that collide on one accessor, a slug with no usable name. The\n // generator refuses rather than emitting a file that does not compile,\n // or one that silently routes a collection's reads to another's table.\n if (err instanceof CodegenError) {\n console.log(\"\");\n console.log(chalk.red(` ✗ ${err.message}`));\n process.exit(1);\n }\n throw err;\n }\n\n // Stamp the schema this SDK was built from.\n //\n // Without it, an app in a separate repository has no way to know its client\n // is stale: the backend moves on, the frontend keeps compiling against types\n // captured weeks ago, and the mismatch only surfaces as a runtime error. With\n // it, CI can compare against `/api/meta/schema-version` and say so.\n //\n // No generation timestamp. Collections are sorted above precisely so that\n // the same schema produces the same bytes; a timestamp put that back,\n // turning every regeneration into a diff and making the obvious staleness\n // gate — `rebase generate-sdk && git diff --exit-code` — impossible to pass.\n // `SCHEMA_VERSION` already identifies what this was built from, and does it\n // in a way that can be compared against a running project.\n const schemaVersion = remoteSchemaVersion ?? computeSchemaVersion(collections);\n files.push({\n path: \"schema.meta.ts\",\n content: `// Auto-generated by \\`rebase generate-sdk\\`. Do not edit.\n//\n// The schema version this SDK was generated from. Compare it against the\n// project's current version to detect drift:\n//\n// curl -s <api-url>/api/meta/schema-version\n//\n// Pass it to the client as \\`schemaVersion\\` and every request carries it in\n// the \\`x-rebase-schema\\` header, so the server can name the drift instead of\n// answering a renamed field with a bare 400.\nexport const SCHEMA_VERSION = ${JSON.stringify(schemaVersion)};\n`\n });\n\n console.log(chalk.green(` ✓ Generated ${files.length} file(s)`));\n console.log(chalk.gray(` schema ${schemaVersion}`));\n\n // 3. Write to disk\n console.log(chalk.cyan(` → Writing to ${resolvedOutput}...`));\n writeFiles(resolvedOutput, files);\n\n console.log(\"\");\n console.log(chalk.green.bold(\" ✓ SDK generated successfully!\"));\n console.log(\"\");\n const typesImport = `./${path.relative(cwd, path.join(resolvedOutput, \"database.types\"))}`;\n const metaImport = `./${path.relative(cwd, path.join(resolvedOutput, \"schema.meta\"))}`;\n const exampleSlug = collections[0]?.slug || \"my_collection\";\n\n console.log(chalk.gray(\" Usage:\"));\n console.log(chalk.gray(\" import { createRebaseClient } from '@rebasepro/client';\"));\n console.log(chalk.gray(` import { collectionsDictionary, type Database } from '${typesImport}';`));\n console.log(chalk.gray(` import { SCHEMA_VERSION } from '${metaImport}';`));\n console.log(\"\");\n console.log(chalk.gray(\" const rebase = createRebaseClient<Database>({\"));\n console.log(chalk.gray(` baseUrl: '${resolveExampleBaseUrl(cwd)}',`));\n // Sent as `x-rebase-schema` on every request. Costs one line here and is\n // the difference between a server that can say \"this client is three\n // deploys behind\" and one that can only reject a field it does not know.\n console.log(chalk.gray(\" schemaVersion: SCHEMA_VERSION,\"));\n // Without the dictionary a hyphenated slug is not resolvable from the\n // property name alone, and the request 404s at runtime.\n console.log(chalk.gray(\" collections: collectionsDictionary,\"));\n console.log(chalk.gray(\" // token: 'your-jwt-token',\"));\n console.log(chalk.gray(\" });\"));\n console.log(\"\");\n // `rebase.data.<accessor>` is the typed surface, so it is what gets printed.\n // `rebase.data.collection(slug)` exists too, but it is generic over\n // `Record<string, unknown>` and has no link to `Database` — it was the\n // headline example here for a while, which advertised the one call shape\n // that throws away the types this command just generated.\n const exampleAccessor = toSafeIdentifier(exampleSlug);\n const exampleAccess = isIdentifierLike(exampleAccessor)\n ? `rebase.data.${exampleAccessor}`\n : `rebase.data[${JSON.stringify(exampleAccessor)}]`;\n console.log(chalk.gray(` const { data } = await ${exampleAccess}.find();`));\n console.log(\"\");\n}\n","/**\n * What to say when a spawned child process fails.\n *\n * Two failures arrive through the same `catch` and need opposite treatment:\n *\n * - **The child ran and exited non-zero.** It had inherited stdio, so it has\n * already printed its own diagnostics. execa's \"Command failed with exit\n * code 1: …\" is a second, worse copy of the same news with the whole argv\n * appended.\n * - **The child never started.** ENOENT on the tsx binary, EACCES on a script\n * that lost its permissions, ENOMEM on a full machine. Nobody printed\n * anything, because nothing ran. `schema.ts` and `doctor.ts` both swallowed\n * these — `catch { process.exit(1); }`, the error not even bound — so\n * `rebase schema generate` against a broken tsx exited 1 in silence, and so\n * did `rebase doctor`, the command whose entire job is to say what is wrong.\n *\n * The tsx symlink surviving a cleaned pnpm store is the ordinary way to get\n * here: `resolveLocalBin` finds the symlink, so \"dependencies are not\n * installed\" never fires, and the spawn is where it breaks.\n *\n * ## Why the message is not what decides it\n *\n * `db.ts` did make this distinction, by testing the message against\n * `/Command failed|exited with code/i` — and that test is wrong for every case\n * it was written to catch. execa prefixes **all** of them the same way:\n *\n * Command failed with exit code 3: /bin/sh -c 'exit 3'\n * Command failed with ENOENT: /…/tsx x⏎spawn /…/tsx ENOENT\n * Command failed with EACCES: /…/tsx x⏎spawn /…/tsx EACCES\n *\n * So the filter matched the spawn failures too and `db push` was as silent as\n * the other two. The structured fields do distinguish them: a child that ran\n * has a numeric `exitCode` (or a `signal`, if something killed it), and a child\n * that never started has neither — only an errno in `code`.\n */\nimport chalk from \"chalk\";\n\ninterface ChildProcessFailure {\n exitCode?: unknown;\n signal?: unknown;\n /** execa's message without the \"Command failed with …: <argv>\" preamble. */\n originalMessage?: unknown;\n}\n\n/** Did the process start? Only then has anything else already been printed. */\nfunction childRan(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const failure = error as Error & ChildProcessFailure;\n return typeof failure.exitCode === \"number\" || typeof failure.signal === \"string\";\n}\n\nexport function reportSpawnFailure(error: unknown): void {\n if (childRan(error) || !(error instanceof Error)) return;\n\n // `originalMessage` is \"spawn /…/tsx ENOENT\" — the same fact as `message`\n // without a second copy of the argv the user just typed. Absent on the\n // errors these commands raise themselves, which are already one sentence.\n const failure = error as Error & ChildProcessFailure;\n const message = typeof failure.originalMessage === \"string\"\n ? failure.originalMessage\n : error.message;\n if (message) console.error(chalk.red(`✗ ${message}`));\n}\n","/**\n * What every command family says when it does not recognise a subcommand.\n *\n * Six families each did it differently, and the differences were not stylistic:\n *\n * rebase statsu \"Unknown command: statsu\" + the whole top-level help\n * rebase auth foo \"Unknown auth command: foo\" + the whole auth help\n * rebase apps foo \"Unknown subcommand: foo\" — which command's?\n * rebase skills foo \"Unknown skills subcommand: foo\" + the whole help\n * rebase telemetry x the help, silently, with exit code 1 and no error line\n * rebase cloud debug x both a JSON error *and* the human one, in JSON mode\n *\n * Dumping a screen of help after an error is the wrong shape: the one line that\n * says what happened scrolls off the top, and in a CI log it is buried in\n * forty. None of them offered the correction, which for a typo is the entire\n * answer — `statsu` is one transposition from `status`.\n *\n * So: one line, the near-miss when there is one, and where to read the rest.\n */\nimport chalk from \"chalk\";\n\n/**\n * Damerau–Levenshtein distance, capped by the caller.\n *\n * The transposition is the reason this is not plain Levenshtein: `statsu` for\n * `status` and `craete` for `create` are the two most common typing errors\n * there are, and both are distance 2 without it — the same as two unrelated\n * edits, which is too far to suggest anything at all.\n */\nfunction editDistance(a: string, b: string): number {\n const rows = a.length + 1;\n const cols = b.length + 1;\n const d: number[][] = Array.from({ length: rows }, () => new Array<number>(cols).fill(0));\n\n for (let i = 0; i < rows; i++) d[i][0] = i;\n for (let j = 0; j < cols; j++) d[0][j] = j;\n\n for (let i = 1; i < rows; i++) {\n for (let j = 1; j < cols; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n d[i][j] = Math.min(\n d[i - 1][j] + 1,\n d[i][j - 1] + 1,\n d[i - 1][j - 1] + cost\n );\n if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {\n d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);\n }\n }\n }\n return d[a.length][b.length];\n}\n\n/**\n * The one command the user probably meant, or nothing.\n *\n * Tight on purpose. A suggestion that is wrong is worse than none: it sends\n * someone to read the help for a command that was never the answer, and on a\n * family like `db` — where `push` and `pull` are one edit apart — a loose\n * threshold would confidently propose the destructive neighbour of what they\n * typed. So: one edit for a short word, two for a long one, and a prefix match\n * always counts (`rebase cloud dep` for `deploy`).\n */\nexport function suggestCommand(typed: string, known: readonly string[]): string | undefined {\n const word = typed.toLowerCase();\n if (!word) return undefined;\n\n // An abbreviation, but only when it names exactly one command. \"res\" is a\n // prefix of both `reset` and `restore`, and picking whichever comes first\n // in the list would be a coin toss dressed up as an answer.\n if (word.length >= 3) {\n const prefixed = known.filter(name => name.toLowerCase().startsWith(word));\n if (prefixed.length === 1) return prefixed[0];\n }\n\n const budget = word.length <= 4 ? 1 : 2;\n let best: { name: string; distance: number } | undefined;\n\n for (const candidate of known) {\n const distance = editDistance(word, candidate.toLowerCase());\n if (distance > budget) continue;\n if (!best || distance < best.distance) best = { name: candidate, distance };\n }\n\n return best?.name;\n}\n\n/**\n * The line itself, without printing it — so callers that must answer in JSON\n * (the cloud family, whose `fail()` writes a machine-readable envelope) use the\n * same words as the ones that print.\n *\n * `family` is empty for the top level: `rebase --help`, not `rebase --help`.\n */\nexport function unknownCommandMessage(\n typed: string | undefined,\n known: readonly string[],\n family = \"\"\n): string {\n const what = family ? `${family} command` : \"command\";\n const suggestion = typed ? suggestCommand(typed, known) : undefined;\n const help = family ? `rebase ${family} --help` : \"rebase --help\";\n\n return suggestion\n ? `Unknown ${what} \"${typed}\" — did you mean \\`${suggestion}\\`? Run \\`${help}\\` for the rest.`\n : `Unknown ${what} \"${typed ?? \"\"}\". Run \\`${help}\\` for the ones there are.`;\n}\n\n/**\n * Print the line to stderr and exit 1.\n *\n * stderr, not stdout: a mistyped command is a failure, and the families with a\n * `--json` mode guarantee that stdout holds only their envelope.\n */\nexport function unknownCommand(\n typed: string | undefined,\n known: readonly string[],\n family = \"\"\n): never {\n console.error(chalk.red(`✗ ${unknownCommandMessage(typed, known, family)}`));\n process.exit(1);\n}\n","/**\n * The words that name a command, with the flags taken back out.\n *\n * `rawArgs` is the whole of `process.argv`, and reading the command's words at\n * fixed indices off it assumes nothing precedes them. Something routinely does:\n * `--debug` is what `bin/rebase.js` prints after every failure as the thing to\n * re-run with, so it is the single most likely token to appear before a command\n * word, and it shifted every index by one.\n *\n * What that cost is not a bad error message. `rebase db branch switch feature`\n * writes a per-checkout pointer that the CLI owns; the driver, running as a\n * child process, cannot persist it and does not try. The dispatch found\n * `switch` by position, so `rebase --debug db branch switch feature` missed the\n * CLI's branch and handed the line to the driver — which reported success and\n * left the checkout on the main database. Every subsequent `dev`, `push` and\n * `backup` then ran against the wrong database, believing it was the branch,\n * which is the exact failure branching exists to prevent.\n *\n * The words are anchored on the command name rather than taken from position\n * zero, because a flag written in the space form (`--database-url <url>`) leaves\n * its value behind as a bare token and no parser at this level knows which\n * flags take values. Anchoring survives that: the value would have to be the\n * literal command name to fool it.\n *\n * Returns `[]` when the command name is not on the line at all.\n */\nexport function commandWords(rawArgs: readonly string[], command: string): string[] {\n const words = rawArgs.slice(2).filter(token => !token.startsWith(\"-\"));\n const start = words.indexOf(command);\n return start === -1 ? [] : words.slice(start);\n}\n\n/**\n * The line to hand a spawned driver, starting at the command word.\n *\n * The same defect one layer down, and it does not degrade gracefully: the\n * driver reads its domain from `args[0]`, so `rebase --debug db push` spawned\n * it with `[\"--debug\", \"db\", \"push\"]` and it answered \"Unknown domain command:\n * --debug\" — for a flag the CLI itself tells you to add after any failure.\n *\n * Tokens written *before* the command word are moved after it rather than\n * dropped. Dropping them would be the same class of bug in the other direction:\n * `rebase --database-url postgres://… db push` would silently lose the flag that\n * says which database to touch. Appending keeps each flag next to its value, and\n * `arg` reads flags wherever they appear.\n *\n * Falls back to `rawArgs.slice(2)` when the command word is not on the line,\n * which is what an internally synthesised argv looks like.\n */\nexport function argsFromCommand(rawArgs: readonly string[], command: string): string[] {\n const tail = rawArgs.slice(2);\n const start = tail.findIndex(token => token === command);\n if (start <= 0) return [...tail];\n return [...tail.slice(start), ...tail.slice(0, start)];\n}\n","/**\n * The one place a command asks \"which database, and how do I reach it?\".\n *\n * Every command that touches Postgres — `dev`, and the whole `db` namespace\n * through the driver plugin — goes through {@link prepareDatabaseEnv}. It\n * resolves the ordering in `resolve.ts`, starts the managed database if that is\n * what the ordering chose, and hands back the environment additions the child\n * process needs.\n *\n * Two things it deliberately does *not* do:\n *\n * - **It never overwrites an existing `DATABASE_URL`.** When the developer has\n * named a database, the returned environment is empty and the child inherits\n * exactly what it would have inherited before this feature existed. A\n * migration must never be redirected away from the database its author meant.\n *\n * - **It never starts anything for a command that is not going to connect.**\n * `--help` and argument errors are handled by the caller before this is\n * reached, because booting a Postgres to print usage would be absurd.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\n\nimport { composeDatabaseUrl } from \"../utils/dev-preflight\";\nimport { findProjectRoot, readEnvFile } from \"../utils/project\";\nimport { resourceEnvSuffix } from \"@rebasepro/types\";\nimport { branchUrl, readActiveBranch } from \"./branch-pointer\";\nimport { MANAGED_LIMITATIONS, MANAGED_POOL_MAX } from \"./constraints\";\nimport { ensureManagedDatabase } from \"./daemon\";\nimport { type DevDatabase, describeDevDatabase, resolveDevDatabase } from \"./resolve\";\n\nexport interface PrepareOptions {\n /** `--database-url <url>`. */\n flagUrl?: string | null;\n /** `--docker`. */\n flagDocker?: boolean;\n /** Suppress the \"starting…\" progress line. */\n quiet?: boolean;\n /** Where human-facing lines go. Defaults to stdout via the caller. */\n onProgress?: (message: string) => void;\n /**\n * Keys of the additional databases the project declares —\n * `database(\"analytics\")` → `analytics`. On the managed path each gets\n * its own PGlite instance and a `DATABASE_URL__<KEY>` in the child's\n * environment, unless the developer set that variable themselves. On an\n * external database nothing is added: whoever chose the database binds\n * the rest of them.\n */\n additionalKeys?: readonly string[];\n}\n\nexport interface PreparedDatabase {\n /** What the resolver chose, for the banner and for tests. */\n database: DevDatabase;\n /**\n * Variables to add to a child process's environment.\n *\n * Empty for an external database: the child already has what it needs, and\n * adding to it could only do harm.\n */\n env: Record<string, string>;\n /** One line naming the database, suitable for a startup banner. */\n description: string;\n /** Absolute path of the managed data directory, when there is one. */\n dataDir?: string;\n /** True when this call started the managed database rather than finding it. */\n startedDaemon?: boolean;\n /** The additional managed databases, by declared key, when any were asked for. */\n additional?: Record<string, string>;\n}\n\n/**\n * The branch this checkout is switched to, as a connection string.\n *\n * Derived rather than stored: the pointer holds a name, and the credentials\n * stay in the one place the developer wrote them. The base is the project's\n * `.env` — a switch is a statement about *this project's* database, so a\n * `DATABASE_URL` that happens to be in the shell is not the thing being\n * branched, and it outranks the branch anyway.\n *\n * Returns null when there is no branch, and also when there is no base to swap\n * the database name on: a project with no `DATABASE_URL` is on the managed\n * database, where branching does not work at all.\n *\n * Exported for its tests. Asserting this through {@link prepareDatabaseEnv}\n * would start a real PGlite daemon to check a decision made before any daemon\n * is involved.\n */\nexport function resolveActiveBranch(\n projectRoot: string,\n envFile: Record<string, string>\n): { name: string; url: string } | null {\n const active = readActiveBranch(projectRoot);\n if (!active) return null;\n\n const base = envFile.DATABASE_URL?.trim();\n if (!base) return null;\n\n const url = branchUrl(base, active.database);\n\n return url ? { name: active.name, url } : null;\n}\n\n/**\n * The compose `db` service's connection string for this project, or null.\n *\n * Read here rather than in `resolve.ts` so the ordering there stays pure, and\n * exported so `rebase dev` can hand the same URL to the preflight that starts\n * the container — the preflight decides \"local, and not running\" from a DSN,\n * so without one `--docker` asked for a container nothing ever started.\n */\nexport function resolveComposeUrl(projectRoot: string, envFile: Record<string, string>): string | null {\n const composePath = path.join(projectRoot, \"docker-compose.yml\");\n if (!fs.existsSync(composePath)) return null;\n try {\n return composeDatabaseUrl(fs.readFileSync(composePath, \"utf8\"), envFile);\n } catch {\n return null;\n }\n}\n\n/**\n * Which database a project is on, decided without starting anything.\n *\n * `resolveDevDatabase` is pure, so the answer is available to help text and to\n * a driver child alike — and neither should pay for a daemon to learn it. The\n * driver cannot work it out for itself: on the managed path `DATABASE_URL` is a\n * perfectly ordinary connection string to a Postgres on loopback, so a child\n * handed only that has no way to know that `rebase db generate` will be refused.\n *\n * Null when there is no project here, which is legal — `rebase db --help` is\n * answered outside one — and when anything at all goes wrong reading the\n * project, because help text must not fail to print over an unreadable `.env`.\n */\nexport function devDatabaseKind(projectRoot?: string | null): DevDatabase[\"kind\"] | null {\n try {\n const root = projectRoot ?? findProjectRoot();\n if (!root) return null;\n const envFile = readEnvFile(root);\n\n return resolveDevDatabase({\n env: process.env,\n envFile,\n branch: resolveActiveBranch(root, envFile),\n composeUrl: resolveComposeUrl(root, envFile)\n }).kind;\n } catch {\n return null;\n }\n}\n\n/**\n * The variable a driver child reads {@link devDatabaseKind} from.\n *\n * One name, exported, because three commands build that child's environment and\n * a fourth reads it in another package.\n */\nexport const DEV_DATABASE_KIND_ENV = \"REBASE_DEV_DATABASE_KIND\";\n\n/**\n * Resolve, start if needed, and describe the database for this command.\n *\n * `projectRoot` is where the managed database's data lives, so two projects on\n * one machine get two databases without either being told about the other.\n */\nexport async function prepareDatabaseEnv(\n projectRoot: string,\n options: PrepareOptions = {}\n): Promise<PreparedDatabase> {\n const envFile = readEnvFile(projectRoot);\n const database = resolveDevDatabase({\n flagUrl: options.flagUrl,\n flagDocker: options.flagDocker,\n env: process.env,\n envFile,\n branch: resolveActiveBranch(projectRoot, envFile),\n composeUrl: resolveComposeUrl(projectRoot, envFile)\n });\n\n const description = describeDevDatabase(database);\n\n if (database.kind === \"external\" && (database.source === \"branch\" || database.source === \"flag\")) {\n // The two external cases that MUST be exported. `environment` and\n // `env-file` are already somewhere the child will look — the shell it\n // inherits, or `.env` via DOTENV_CONFIG_PATH — but a branch URL is\n // derived here and exists nowhere else, and `--database-url` lives only\n // in this process's argv. Without this the pointer resolves correctly\n // and then changes nothing: `rebase db backup` on a switched checkout\n // still reported `Database: leadgen`, and `rebase dev --database-url …`\n // announced the database and then died on `DATABASE_URL: is required`.\n //\n // Safe to set: `dotenv` does not overwrite a variable that is already\n // in the environment, so the child's own `.env` load cannot undo it.\n return { database, env: { DATABASE_URL: database.url }, description };\n }\n\n if (database.kind === \"docker\") {\n // Docker is the one case where nothing has named a connection string:\n // `.env` leaves DATABASE_URL commented out, so without this the child\n // booted with no database at all and failed on the message a project\n // that configured nothing gets — while the container it had just been\n // asked for was never started either.\n if (!database.url) {\n throw new Error(\n \"--docker needs a docker-compose.yml with a db service in this project, \" +\n \"and this one has none that names POSTGRES_USER, POSTGRES_DB and a published port. \" +\n \"Set DATABASE_URL in .env to point at the database you mean instead.\"\n );\n }\n return { database, env: { DATABASE_URL: database.url }, description };\n }\n\n if (database.kind !== \"managed\") {\n // `environment` or `env-file`: the connection string is already in a\n // place the child reads for itself, so this adds nothing to it.\n return { database, env: {}, description };\n }\n\n // Only the keys nobody bound by hand. A developer who set\n // DATABASE_URL__ANALYTICS to a warehouse of their own has said which\n // database that is, and the managed one fills a vacuum, never a choice.\n const unbound = (options.additionalKeys ?? []).filter((key) => {\n const name = `DATABASE_URL${resourceEnvSuffix(key)}`;\n return !process.env[name] && !envFile[name];\n });\n\n const managed = await ensureManagedDatabase(projectRoot, {\n quiet: options.quiet,\n onProgress: options.onProgress,\n additionalKeys: unbound\n });\n\n const additionalEnv: Record<string, string> = {};\n for (const [key, url] of Object.entries(managed.additional)) {\n additionalEnv[`DATABASE_URL${resourceEnvSuffix(key)}`] = url;\n }\n\n return {\n database,\n description,\n dataDir: managed.dataDir,\n startedDaemon: managed.started,\n additional: managed.additional,\n env: {\n DATABASE_URL: managed.url,\n // PGlite is one session behind a multiplexer: two pooled clients in\n // overlapping transactions deadlock there. This is the ceiling that\n // turns that into ordinary queueing — see `constraints.ts`.\n REBASE_DB_POOL_MAX: String(MANAGED_POOL_MAX),\n ...additionalEnv\n }\n };\n}\n\n/**\n * The lines to print about a managed database, in the order to print them.\n *\n * Returned rather than printed so the caller decides where they go — `dev` has\n * a banner, `db push` has a single line above its own output — and so a test can\n * assert on them without capturing a stream.\n */\nexport function managedNotices(prepared: PreparedDatabase): string[] {\n if (prepared.database.kind !== \"managed\") return [];\n\n const lines = [`Using ${prepared.description}.`];\n if (prepared.dataDir) lines.push(`Data: ${prepared.dataDir}`);\n for (const key of Object.keys(prepared.additional ?? {})) {\n lines.push(`Also serving database \"${key}\" as DATABASE_URL${resourceEnvSuffix(key)}`);\n }\n\n // Stated every time rather than discovered. A developer who does not know\n // requests are serialized here will read a concurrency difference as a bug\n // in their own code.\n for (const limitation of MANAGED_LIMITATIONS) {\n lines.push(`${limitation.summary} ${limitation.remedy}`);\n }\n lines.push(\"To use your own Postgres instead, set DATABASE_URL in .env.\");\n\n return lines;\n}\n","/**\n * CLI command: rebase db <action>\n */\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport inquirer from \"inquirer\";\nimport os from \"os\";\nimport path from \"path\";\nimport { execa } from \"execa\";\nimport {\n requireProjectRoot,\n requireBackendDir,\n getActiveBackendPlugin,\n resolvePluginCliScript,\n resolveTsx,\n findEnvFile,\n dependenciesNotInstalled\n} from \"../utils/project\";\nimport { reportSpawnFailure } from \"../utils/spawn-error\";\nimport { parseCommandArgs } from \"../utils/args\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport { argsFromCommand, commandWords } from \"../utils/command-words\";\nimport { recordEvent } from \"../telemetry\";\nimport { DEV_DATABASE_KIND_ENV, devDatabaseKind, type PreparedDatabase } from \"../dev-db/prepare\";\nimport { type DevDatabase } from \"../dev-db/resolve\";\n\n/**\n * The connection string a prepared database actually answers on.\n *\n * One function, because `db url` and `db pull` disagreed about it and the\n * disagreement was a dead command: `prepareDatabaseEnv` returns `env: {}` for a\n * plain external database — the connection string is already somewhere the\n * child looks — so `db pull`'s `prepared.env.DATABASE_URL ?? process.env\n * .DATABASE_URL` was empty for the standard `.env` configuration and answered\n * `✗ No local database to pull into.` on a project whose `rebase db url` had\n * just printed one. Exporting the same URL in the shell made it work, which is\n * the shape of a bug nobody reports as one.\n *\n * `readEnvFile` is passed in rather than imported: this module loads\n * `../utils/project` dynamically everywhere else, and the callers already have\n * it open.\n */\nexport function databaseUrlOf(\n prepared: Pick<PreparedDatabase, \"env\" | \"database\">,\n envFile: Record<string, string>\n): string | undefined {\n // An empty string is \"nothing named a database\", not \"the database is the\n // empty string\" — `docker` resolves to `url: null` when the compose file\n // declares no usable db service.\n const named = (value: string | null | undefined) => (value && value.trim() ? value : undefined);\n\n return named(prepared.env.DATABASE_URL)\n ?? named(prepared.database.kind === \"managed\" ? undefined : prepared.database.url)\n ?? named(envFile.DATABASE_URL)\n ?? named(process.env.DATABASE_URL);\n}\n\n/**\n * A destination that names a remote store rather than a local path.\n *\n * Matched as \"scheme://\" generally, not as a list of the schemes we support:\n * an unknown scheme is still not something to join onto a filesystem path, and\n * a Windows drive letter (\"C:\\backups\") has no \"//\" so it stays a path.\n */\nconst REMOTE_DESTINATION_RE = /^[a-z][a-z0-9+.-]*:\\/\\//i;\n\n/**\n * Rewrite local path arguments so they mean what the user typed.\n *\n * The plugin CLI is spawned with `cwd: backendDir` — it has to be, because that\n * is where the plugin and its dependencies resolve from. But the developer runs\n * `rebase db` from the project root, so a relative `--out ./backups` was being\n * resolved against `backend/` and landed in `backend/backups`, while the\n * success line echoed the path as typed. The file was real and the reported\n * location was wrong, which is the worst way for a backup command to behave.\n * `rebase db --help` documents exactly this invocation.\n *\n * Absolutising here rather than inside the plugin keeps the fix where the cwd\n * is actually changed, and leaves the plugin usable on its own terms.\n */\nexport function absolutizeLocalPathArgs(args: string[], cwd: string): string[] {\n /**\n * All three spellings of the destination, because the driver accepts all\n * three: `backup-cli.ts` maps `--output` and `-o` onto `--out`, and `rebase\n * db backup --help` advertises `--output` as an alias. Only `--out` and\n * `-o` were absolutised, so the one spelling the help page names was the\n * one that landed in `backend/` — and the success line still echoed the\n * path as typed.\n */\n const takesPath = (flag: string) => flag === \"--out\" || flag === \"--output\" || flag === \"-o\";\n /**\n * Flags whose next token is a value, not a positional.\n *\n * Mirrors the `arg` specs in `@rebasepro/server-postgres`'s backup CLI.\n * Needed only to find the `db restore` dump argument: without it,\n * `restore --target-db app_restored ./x.dump` treats `app_restored` as the\n * positional — it is the first token not starting with `-` — and turns a\n * database name into a path while leaving the real dump path unresolved.\n */\n const VALUE_FLAGS = new Set([\n \"--out\", \"--output\", \"-o\", \"--target-db\", \"--exclude-schema\", \"--row-security-role\"\n ]);\n const out = [...args];\n\n for (let i = 0; i < out.length; i++) {\n const arg = out[i];\n\n // `--out=<value>`\n const eq = arg.indexOf(\"=\");\n if (eq > 0 && takesPath(arg.slice(0, eq))) {\n const value = arg.slice(eq + 1);\n if (value && !REMOTE_DESTINATION_RE.test(value)) {\n out[i] = `${arg.slice(0, eq)}=${path.resolve(cwd, value)}`;\n }\n continue;\n }\n\n // `--out <value>`\n if (takesPath(arg)) {\n const value = out[i + 1];\n if (value && !value.startsWith(\"-\") && !REMOTE_DESTINATION_RE.test(value)) {\n out[i + 1] = path.resolve(cwd, value);\n i++;\n }\n }\n }\n\n // `db restore <file>` — the dump to read is a positional, and a relative one\n // was resolved against `backend/` too, so the path printed by a preceding\n // `db backup` could not be pasted into `db restore`.\n const restoreAt = out.indexOf(\"restore\");\n if (restoreAt !== -1) {\n for (let i = restoreAt + 1; i < out.length; i++) {\n const arg = out[i];\n if (arg.startsWith(\"-\")) {\n // `--flag=value` carries its value inline; `--flag value` eats\n // the next token only when the flag actually takes one.\n if (!arg.includes(\"=\") && VALUE_FLAGS.has(arg)) i++;\n continue;\n }\n // First true positional: the dump to restore.\n if (!REMOTE_DESTINATION_RE.test(arg)) out[i] = path.resolve(cwd, arg);\n break;\n }\n }\n\n return out;\n}\n\n/**\n/**\n * Read `--flag value` or `--flag=value` out of the raw argv.\n *\n * This command forwards its arguments to the driver plugin rather than parsing\n * them, so the two flags the CLI itself acts on are picked out by hand instead\n * of adding a spec that would then have to strip them back out again.\n */\nfunction readFlagValue(rawArgs: readonly string[], flag: string): string | null {\n for (let index = 0; index < rawArgs.length; index += 1) {\n const arg = rawArgs[index];\n if (arg === flag) return rawArgs[index + 1] ?? null;\n if (arg.startsWith(`${flag}=`)) return arg.slice(flag.length + 1);\n }\n\n return null;\n}\n\n/**\n * Run a database subcommand through the active driver's CLI, throwing on\n * failure instead of exiting.\n *\n * `dbCommand` below turns every failure into `process.exit(1)`, which is right\n * for a command the user invoked directly and wrong for a caller that has more\n * to do afterwards — `rebase dev` runs a schema push during start-up and must\n * survive it failing. Exiting is therefore the wrapper's job, not this\n * function's.\n *\n * The database is resolved *here* rather than in the wrapper, so the schema\n * push `rebase dev` performs during start-up reaches the managed database too.\n */\n/**\n * The `db` subcommands that plan their work with Atlas.\n *\n * Atlas computes a diff by replaying the desired schema into a **second, empty\n * database** and comparing. That is why these three are listed and `backup` and\n * `restore` are not — those shell out to `pg_dump`, which fails loudly on its\n * own. `branch` is refused too, but for its own reason and with its own\n * message: see {@link refuseBranchOnManagedDatabase}.\n */\nconst ATLAS_BACKED_SUBCOMMANDS = new Set([\"push\", \"generate\", \"migrate\"]);\n\n/**\n * A managed-database refusal, raised so the caller decides what it costs.\n *\n * These two guards used to `process.exit(1)` where they stood. That is right\n * for `rebase db push`, typed by a person, and catastrophic for the same code\n * reached from inside `rebase dev`: the dev server's first-boot schema push\n * runs in-process, so an exit there took the whole dev server down — with a\n * `try/catch` around it written expressly to prevent that, which could never\n * run. The first `rebase dev --docker` of every scaffold died this way.\n *\n * So the refusal is a value now. It carries the block it wants printed rather\n * than printing it, because who prints (and whether printing is even right) is\n * the caller's question: `dbCommand` prints it and exits 1, and `rebase dev`\n * keeps serving.\n */\nexport class ManagedDatabaseRefusal extends Error {\n /** The lines to print, in order, already coloured. */\n readonly lines: readonly string[];\n\n constructor(summary: string, lines: readonly string[]) {\n super(summary);\n this.name = \"ManagedDatabaseRefusal\";\n this.lines = lines;\n }\n}\n\n/** Print a refusal exactly as the guards used to print it themselves. */\nexport function printManagedDatabaseRefusal(refusal: ManagedDatabaseRefusal): void {\n for (const line of refusal.lines) console.error(line);\n}\n\n/**\n * Stop an Atlas-backed subcommand before it fails inside Atlas on the managed\n * development database.\n *\n * **PGlite serves exactly one database.** `CREATE DATABASE \"postgres_dev_diff\"`\n * against it reports success and creates nothing, so Atlas connects its dev-url\n * straight back to the database it is meant to be comparing against, finds the\n * project's own tables there, and stops with\n * `connected database is not clean: found schema \"public\"`. Verified on a\n * completely fresh scaffold, so this is not a leftover-state problem that a\n * reset would fix — the model does not fit the engine.\n *\n * Before this guard the failure was worse than unhelpful. The first thing the\n * reader hit was `pq: SSL is not enabled on the server`, whose remedy box said\n * to append `sslmode=disable` to `DATABASE_URL` — a variable `rebase init`\n * deliberately leaves unset, which is the very reason the managed database was\n * in use. Two errors deep, about a variable that does not exist, for a command\n * the quickstart told them to run.\n *\n * There is nothing to fix by trying harder here: Atlas's other dev-url option\n * is `docker://`, and needing Docker is precisely what the managed database\n * exists to avoid. So this says what the managed database can and cannot do,\n * and names the two things that work.\n */\nexport function refuseAtlasOnManagedDatabase(rawArgs: string[], kind: string): void {\n if (kind !== \"managed\") return;\n const [domain, subcommand] = commandWords(rawArgs, \"db\");\n if (domain !== \"db\" || !ATLAS_BACKED_SUBCOMMANDS.has(subcommand ?? \"\")) return;\n\n const summary = `rebase db ${subcommand} does not work on the managed development database.`;\n\n throw new ManagedDatabaseRefusal(summary, [\n \"\",\n chalk.red(` ✗ ${summary}`),\n \"\",\n chalk.gray(\" It plans changes with Atlas, which needs a second empty database to\"),\n chalk.gray(\" compare against. The managed database is PGlite, which serves exactly one.\"),\n \"\",\n chalk.gray(\" You almost certainly do not need this command:\"),\n chalk.gray(` ${chalk.cyan(\"rebase dev\")} already applies your collections to it at boot, additively.`),\n \"\",\n chalk.gray(\" For migrations, or to drop and rename columns, point the project at a real\"),\n chalk.gray(\" Postgres — uncomment DATABASE_URL in .env — and run this command again.\"),\n \"\"\n ]);\n}\n\n/**\n * Stop `rebase db branch` before it reports a branch that is not one.\n *\n * **PGlite serves exactly one database**, and this is the second thing that\n * follows from it. `CREATE DATABASE \"rb_feature_x\" TEMPLATE \"postgres\"` there\n * writes a `pg_database` catalog row and nothing else. Nothing errors, so the\n * whole feature reports success end to end:\n *\n * $ rebase db branch create feature_x\n * ✓ Branch \"feature_x\" created successfully.\n * $ rebase db branch list\n * ● feature_x (7.1 MB) — created just now\n *\n * `listBranches` joins `pg_database`, the catalog row is there, and\n * `pg_database_size` answers with the one database's size — so the listing\n * corroborates the lie. Then connecting to `rb_feature_x` reports\n * `current_database()` = `postgres`, and a table created \"in the branch\" is\n * visible in the parent immediately. Measured on a fresh `rebase init` scaffold.\n *\n * **The branch is the parent.** Every write made in the belief that it is\n * sandboxed lands in the developer's real development database — which is the\n * exact failure branching exists to prevent, announced as a success.\n *\n * So this refuses the whole `branch` domain rather than `create` alone: `list`\n * on the managed database ends with \"Create one with: rebase db branch create\",\n * an invitation to do the broken thing, and `info` would confirm a size for a\n * database that was never made.\n *\n * `refuseAtlasOnManagedDatabase` above is the same shape for a different\n * reason, and its comment named `branch` as one of the subcommands it does not\n * cover. It does now.\n */\nexport function refuseBranchOnManagedDatabase(rawArgs: string[], kind: string): void {\n if (kind !== \"managed\") return;\n const [domain, subcommand] = commandWords(rawArgs, \"db\");\n if (domain !== \"db\" || subcommand !== \"branch\") return;\n\n const summary = \"rebase db branch does not work on the managed development database.\";\n\n throw new ManagedDatabaseRefusal(summary, [\n \"\",\n chalk.red(` ✗ ${summary}`),\n \"\",\n chalk.gray(\" Branching copies a database with CREATE DATABASE ... TEMPLATE. The managed\"),\n chalk.gray(\" database is PGlite, which serves exactly one — the copy would be the\"),\n chalk.gray(\" original, and every write you meant to sandbox would land in it.\"),\n \"\",\n chalk.gray(\" Branching needs a real Postgres. Either:\"),\n chalk.gray(` ${chalk.cyan(\"rebase dev --docker\")} starts one, and branches work against it`),\n chalk.gray(\" or uncomment DATABASE_URL in .env to point at your own.\"),\n \"\"\n ]);\n}\n\n/**\n * Resolve the active driver's CLI and the environment it should run in.\n *\n * Shared by the two runners below. Deliberately does NOT resolve a database:\n * `schema generate` reads collection files and writes one file, and starting a\n * database to run it would be a side effect nobody asked for.\n */\nasync function resolveDriverCli(): Promise<{\n projectRoot: string;\n backendDir: string;\n pluginCli: string;\n env: Record<string, string>;\n}> {\n const projectRoot = requireProjectRoot();\n const backendDir = requireBackendDir(projectRoot);\n\n const activePlugin = getActiveBackendPlugin(backendDir);\n if (!activePlugin) {\n throw new Error(\n \"Could not detect an active database plugin. Make sure a package like \"\n + \"@rebasepro/server-postgres is installed in backend/package.json.\"\n );\n }\n const pluginCli = resolvePluginCliScript(backendDir, activePlugin);\n if (!pluginCli) {\n throw new Error(dependenciesNotInstalled(projectRoot));\n }\n\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n env[DEV_DATABASE_KIND_ENV] = devDatabaseKind(projectRoot) ?? \"\";\n\n return { projectRoot, backendDir, pluginCli, env };\n}\n\n/**\n * The one place this CLI spawns the driver's own CLI.\n *\n * There were three, each with its own copy of \"tsx for a `.ts` entry, `node`\n * otherwise\". That rule was right only while the driver shipped `src/`; once it\n * shipped `dist/cli.js` all three quietly switched to plain `node`, and the\n * driver loads the PROJECT's TypeScript in process:\n *\n * - `schema stale` reads the collections, could not resolve `./authors` onto\n * `authors.ts`, and answered \"⏭ Not checked\" while exiting 0;\n * - `db push` does the same in `ensureAuthTables`, so `rebase.users` was never\n * created and the push died at \"Applying RLS policies\" with\n * `relation \"rebase.users\" does not exist` — on a virgin database, which is\n * the documented bring-your-own-Postgres first run.\n *\n * Two were fixed and the third was missed, because three copies of a decision\n * are three chances to miss one. There is one now, and a gate holds it at one.\n *\n * tsx whenever it is installed — a devDependency of every scaffold, for exactly\n * this reason. Without it a `.ts` entry cannot run at all; a built entry still\n * runs, and the subcommands that never touch the project's TypeScript still work.\n */\nexport async function spawnDriverCli(\n resolved: { projectRoot: string; backendDir: string; pluginCli: string; env: Record<string, string> },\n childArgs: string[],\n options: { quiet?: boolean } = {}\n): Promise<void> {\n const { projectRoot, backendDir, pluginCli, env } = resolved;\n const stdio = options.quiet ? \"pipe\" : \"inherit\";\n\n const tsxBin = resolveTsx(projectRoot);\n if (!tsxBin && pluginCli.endsWith(\".ts\")) {\n throw new Error(dependenciesNotInstalled(projectRoot));\n }\n\n await execa(tsxBin ?? \"node\", [pluginCli, ...childArgs], { cwd: backendDir, stdio, env });\n}\n\n/** @deprecated Use {@link spawnDriverCli}. Kept as the internal name callers use. */\nconst execDriverCli = spawnDriverCli;\n\n/**\n * Run a `schema` subcommand through the active driver's CLI.\n *\n * Separate from {@link runDriverDbCommand} because it must NOT resolve a\n * database. `rebase dev` calls this before the database exists, which is the\n * whole point: the generated schema has to be right before anything reads it.\n * Throws rather than exiting — the caller has more to do.\n */\nexport async function runDriverSchemaCommand(\n rawArgs: string[],\n options: { quiet?: boolean } = {}\n): Promise<void> {\n const resolved = await resolveDriverCli();\n await execDriverCli(resolved, rawArgs.slice(2), options);\n}\n\nexport async function runDriverDbCommand(\n rawArgs: string[],\n options: { quiet?: boolean } = {}\n): Promise<void> {\n const projectRoot = requireProjectRoot();\n const backendDir = requireBackendDir(projectRoot);\n\n const activePlugin = getActiveBackendPlugin(backendDir);\n if (!activePlugin) {\n throw new Error(\n \"Could not detect an active database plugin. Make sure a package like \"\n + \"@rebasepro/server-postgres is installed in backend/package.json.\"\n );\n }\n\n const pluginCli = resolvePluginCliScript(backendDir, activePlugin);\n if (!pluginCli) {\n throw new Error(dependenciesNotInstalled(projectRoot));\n }\n\n // Set up environment with DOTENV_CONFIG_PATH\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n env[DEV_DATABASE_KIND_ENV] = devDatabaseKind(projectRoot) ?? \"\";\n\n // Every `db` subcommand reaches Postgres through the driver plugin, which\n // reads DATABASE_URL from this environment — so resolving the database once\n // here covers push, generate, migrate, backup and restore alike, and any\n // subcommand a driver adds later. When the developer has named their own\n // database this adds nothing at all.\n // Refused before anything is started. `prepareDatabaseEnv` below *boots*\n // the managed database, and booting PGlite in order to say that PGlite\n // cannot branch is latency spent on an answer already known — the resolver\n // is a pure function and settles it. It also keeps the refusal working when\n // the managed database would have failed to start, where the developer\n // would otherwise be told about a daemon rather than about branching.\n const { resolveDevDatabase } = await import(\"../dev-db/resolve\");\n const { readEnvFile } = await import(\"../utils/project\");\n refuseBranchOnManagedDatabase(rawArgs, resolveDevDatabase({\n flagUrl: readFlagValue(rawArgs, \"--database-url\"),\n flagDocker: rawArgs.includes(\"--docker\"),\n env: process.env,\n envFile: readEnvFile(projectRoot)\n }).kind);\n\n const { prepareDatabaseEnv, managedNotices } = await import(\"../dev-db/prepare\");\n const prepared = await prepareDatabaseEnv(projectRoot, {\n flagUrl: readFlagValue(rawArgs, \"--database-url\"),\n flagDocker: rawArgs.includes(\"--docker\"),\n onProgress: (message) => { if (!options.quiet) console.log(chalk.gray(` ${message}`)); }\n });\n Object.assign(env, prepared.env);\n // Suppressed for an internal caller. `rebase dev` runs a schema push during\n // start-up and has already said all of this in its own banner; repeating it\n // mid-boot reads as something having gone wrong.\n if (!options.quiet) {\n for (const line of managedNotices(prepared)) console.log(chalk.gray(` ${line}`));\n }\n\n refuseAtlasOnManagedDatabase(rawArgs, prepared.database.kind);\n\n // Resolved against the directory the developer is standing in, before the\n // child is handed a different one. See absolutizeLocalPathArgs.\n //\n // From the command word, not from index 2: the driver reads its domain out\n // of `args[0]`, so `rebase --debug db push` spawned it with [\"--debug\",\n // \"db\", \"push\"] and it answered \"Unknown domain command: --debug\" — for a\n // flag this CLI prints after every failure as the thing to re-run with.\n const childArgs = absolutizeLocalPathArgs(argsFromCommand(rawArgs, \"db\"), process.cwd());\n\n await spawnDriverCli({ projectRoot, backendDir, pluginCli, env }, childArgs, options);\n}\n\nexport async function dbCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // `--help` is answered here, before anything else, and never by a\n // subcommand.\n //\n // `cli.ts` rewrites the subcommand to `\"--help\"` only when the user named\n // none, so `rebase db --help` was covered and `rebase db push --help` was\n // not: the flag went through to `runDriverDbCommand`, which resolves (and\n // will START) the development database and then hands the whole line to the\n // driver, whose own dispatch has no `--help` case for `push`. **It ran the\n // push.** A flag whose entire job is to print text applied a schema to a\n // database — the single most dangerous shape a help flag can have, and the\n // same class as `skills install --help` writing files and `auth\n // reset-password --help` running an UPDATE.\n //\n // Answering before `requireProjectRoot` and before the driver spawn makes\n // it structurally impossible rather than conditionally safe: no subcommand\n // can act on `--help`, because no subcommand is reached.\n if (!subcommand || subcommand === \"--help\" || rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\")) {\n printDbHelp(subcommand === \"--help\" ? undefined : subcommand);\n return;\n }\n\n // A typo is answered here, not by the driver, and not after a database has\n // been started for it.\n //\n // `rebase db psh` used to reach `runDriverDbCommand`, which resolves the\n // database first — so it **booted the managed PGlite**, a 180 MB daemon,\n // in order to hand the driver an argv it then rejected with `Unknown db\n // command. Valid: push, generate, migrate, branch, backup, restore,\n // backups`: a list missing `url`, `pull`, `stop` and `reset`, all four of\n // which `rebase db --help` lists and this CLI implements itself. The driver\n // cannot know about them, which is exactly why the answer does not belong\n // to the driver.\n //\n // The set comes from the help table, so the list a typo is measured against\n // and the list `--help` prints cannot drift apart.\n if (!DB_ACTION_HELP[subcommand]) unknownCommand(subcommand, Object.keys(DB_ACTION_HELP), \"db\");\n\n const projectRoot = requireProjectRoot();\n\n // Fire-and-forget, and a no-op unless the developer opted in. Never awaited:\n // the command is what the user is waiting for, and a slow collector must not\n // sit in front of it.\n void recordEvent(\"cli.db\", { subcommand: subcommand ?? \"none\" }, { projectRoot });\n\n // Handled here rather than by the driver plugin: these are about the\n // *managed* database's process and data directory, which is a CLI concern.\n // A project pointed at its own Postgres has nothing here to stop or reset,\n // and is told so rather than silently doing nothing.\n if (subcommand === \"stop\" || subcommand === \"reset\") {\n await manageLocalDatabase(subcommand, projectRoot, rawArgs);\n\n return;\n }\n\n // `--docker` on a `db` subcommand meant \"resolve the compose URL\", and\n // nothing started it: `rebase db branch list --docker` on a stock scaffold\n // answered `✗ Failed query: CREATE SCHEMA IF NOT EXISTS rebase` and\n // `connect ECONNREFUSED 127.0.0.1:5436` — two lines, no diagnosis — while\n // the managed-database refusal that sends the reader here says \"`rebase dev\n // --docker` starts one, and branches work against it\".\n //\n // The same ensure step `rebase dev --docker` runs, not a second one.\n await ensureDockerDatabase(projectRoot, rawArgs);\n\n if (subcommand === \"pull\") {\n await pullIntoLocal(projectRoot, rawArgs);\n\n return;\n }\n\n if (subcommand === \"url\") {\n await printDatabaseUrl(projectRoot, rawArgs);\n\n return;\n }\n\n // Handled here rather than by the driver, for the same reason `stop` and\n // `reset` are: it writes per-checkout CLI state. The driver creates and\n // drops the databases; which one this checkout talks to is not its\n // business, and it runs as a child process that could not persist the\n // answer anyway.\n if (subcommand === \"branch\" && commandWords(rawArgs, \"db\")[2] === \"switch\") {\n await switchBranch(projectRoot, rawArgs);\n\n return;\n }\n\n // The other two branch actions that need to know where this checkout is\n // standing, for reasons the driver — a child process with no idea a pointer\n // exists — cannot answer.\n let driverArgs = rawArgs;\n if (subcommand === \"branch\") {\n const action = commandWords(rawArgs, \"db\")[2];\n if (action === \"delete\") await refuseDeletingActiveBranch(projectRoot, rawArgs);\n if (action === \"list\") driverArgs = await listFromParentDatabase(projectRoot, rawArgs);\n }\n\n try {\n await runDriverDbCommand(driverArgs);\n } catch (error) {\n // The CLI entry point is where a managed-database refusal becomes an\n // exit code. The guards raise it instead of exiting so that `rebase dev`,\n // which runs `db push` in-process, survives one; here, where a person\n // typed the command, it is exactly as fatal as it always was.\n if (error instanceof ManagedDatabaseRefusal) {\n printManagedDatabaseRefusal(error);\n process.exit(1);\n }\n // A child that exited non-zero already printed its diagnostics through\n // inherited stdio; only the errors raised above have a message worth\n // adding here.\n reportSpawnFailure(error);\n process.exit(1);\n }\n}\n\n/**\n * `rebase db url` — the connection string this project is using, on stdout.\n *\n * The managed database is the one case where nothing on disk names it: `.env`\n * ships `DATABASE_URL` commented out on purpose, the port is derived from the\n * project path, and the data lives under `.rebase/`. A headless project has no\n * admin panel to open either, so before this there was no way to point `psql`,\n * a GUI client or a seeding script at the database `rebase dev` had just\n * created — short of reading the CLI's source.\n *\n * Resolution is the same ordered rule every other command uses, so this prints\n * your own `DATABASE_URL` when you have set one rather than inventing a second\n * answer. Nothing but the URL goes to stdout, so it pipes:\n *\n * psql \"$(rebase db url)\"\n *\n * It starts the managed database if it is not running, because a connection\n * string for a database nobody is serving is not an answer.\n */\nasync function printDatabaseUrl(projectRoot: string, rawArgs: readonly string[]): Promise<void> {\n // Strict about its flags, like every other command.\n //\n // The `db` family's strictness lives in the driver, and `url` is answered\n // here, before the driver is ever spawned — so it accepted anything.\n // `rebase db url --bogus` printed the URL and exited 0, and so did\n // `rebase db url --json`, which is worse: a flag that looks like it asks\n // for a different output format, silently ignored, hands a script a bare\n // string it will try to parse as JSON.\n parseCommandArgs({\n spec: { \"--database-url\": String, \"--docker\": Boolean },\n rawArgs: [...rawArgs],\n commandWords: 2,\n command: \"db url\",\n maxPositionals: 0\n });\n\n const { prepareDatabaseEnv } = await import(\"../dev-db/prepare\");\n const { readEnvFile } = await import(\"../utils/project\");\n\n const prepared = await prepareDatabaseEnv(projectRoot, {\n flagUrl: readFlagValue(rawArgs, \"--database-url\"),\n flagDocker: rawArgs.includes(\"--docker\"),\n quiet: true,\n // Progress goes to stderr: stdout is the URL and nothing else.\n onProgress: message => console.error(chalk.gray(` ${message}`))\n });\n\n const url = databaseUrlOf(prepared, readEnvFile(projectRoot));\n if (!url) {\n console.error(chalk.red(\" ✗ This project has no database URL to print.\"));\n console.error(chalk.gray(\" Set DATABASE_URL in .env, or run `rebase dev` to start the managed one.\"));\n process.exit(1);\n }\n\n console.log(url);\n}\n\n/**\n * `rebase db stop` and `rebase db reset`, for the managed database only.\n *\n * `reset` deletes the data directory rather than dropping schemas: \"give me an\n * empty database\" is the only thing anyone means by it, and doing it by\n * removing the directory cannot leave a half-dropped schema behind.\n */\nasync function manageLocalDatabase(\n subcommand: \"stop\" | \"reset\",\n projectRoot: string,\n rawArgs: readonly string[]\n): Promise<void> {\n const { resetManagedDatabase, stopManagedDatabase, findRunningDaemon } = await import(\"../dev-db/daemon\");\n const { dataDir } = await import(\"../dev-db/state\");\n\n // What \"nothing here\" means, in the words of the project it is said to.\n //\n // \"No development database was running\" / \"No development database to\n // reset\" is true of the managed one and reads as being about the reader's\n // own Postgres — which these commands do not touch and could not stop.\n // On a project that named its own database, the sentence they need is that\n // it was not what this command was about.\n const nothingHere = (): string => {\n const kind = devDatabaseKind(projectRoot);\n const verb = subcommand === \"stop\" ? \"was not running\" : \"does not exist\";\n if (kind && kind !== \"managed\") {\n return ` The managed development database (PGlite) ${verb}; `\n + `this project uses its own DATABASE_URL, which is untouched.`;\n }\n\n return subcommand === \"stop\"\n ? \" The managed development database (PGlite) was not running.\"\n : \" There is no managed development database (PGlite) to reset.\";\n };\n\n if (subcommand === \"stop\") {\n const stopped = await stopManagedDatabase(projectRoot);\n console.log(stopped\n ? chalk.green(\"✓ Development database stopped. Data is kept — `rebase dev` will start it again.\")\n : chalk.gray(nothingHere()));\n\n return;\n }\n\n const running = await findRunningDaemon(projectRoot);\n const hasData = fs.existsSync(dataDir(projectRoot));\n if (!running && !hasData) {\n console.log(chalk.gray(nothingHere()));\n\n return;\n }\n\n // Destructive, and the data is not backed up anywhere: it only ever existed\n // on this machine. So it asks, unless the caller has said not to — and\n // without a TTY there is nobody to ask, which is a refusal rather than an\n // assumption.\n if (!rawArgs.includes(\"--yes\") && !rawArgs.includes(\"-y\")) {\n if (!process.stdin.isTTY) {\n console.error(chalk.red(\"✗ `rebase db reset` deletes the local database and cannot prompt here.\"));\n console.error(chalk.yellow(\" Re-run with --yes if that is what you intend.\"));\n process.exit(1);\n }\n\n const { confirmed } = await inquirer.prompt([{\n type: \"confirm\",\n name: \"confirmed\",\n message: `Delete the development database at ${dataDir(projectRoot)}? This cannot be undone.`,\n default: false\n }]);\n if (!confirmed) {\n console.log(chalk.gray(\" Left alone.\"));\n\n return;\n }\n }\n\n await resetManagedDatabase(projectRoot);\n console.log(chalk.green(\"✓ Development database deleted. `rebase dev` will create a fresh one.\"));\n}\n\n/**\n * `rebase db pull --from <url>` — copy another database's contents into local\n * development.\n *\n * Deliberately one-directional. There is no flag that makes this push, because\n * a tool that can copy in both directions eventually copies in the wrong one,\n * and the wrong one here means overwriting production with a laptop.\n */\nasync function pullIntoLocal(projectRoot: string, rawArgs: readonly string[]): Promise<void> {\n const { anonymizeStatements, describeTarget, dumpArgs, findPgTool, restoreArgs, restoreOutcome } =\n await import(\"../dev-db/pull\");\n const { prepareDatabaseEnv } = await import(\"../dev-db/prepare\");\n const { readEnvFile } = await import(\"../utils/project\");\n\n const source = readFlagValue(rawArgs, \"--from\");\n if (!source) {\n console.error(chalk.red(\"✗ `rebase db pull` needs a source: --from <connection-string>\"));\n console.error(chalk.gray(\" Example: rebase db pull --from \\\"$PRODUCTION_DATABASE_URL\\\"\"));\n process.exit(1);\n }\n\n const schemas = rawArgs.flatMap((arg, index) =>\n arg === \"--schema\" && rawArgs[index + 1] ? [rawArgs[index + 1]] : []);\n const anonymize = rawArgs.includes(\"--anonymize\");\n\n // Both checked before anything destructive: discovering either is missing\n // after dropping the local database would be the worst possible ordering.\n for (const tool of [\"pg_dump\", \"pg_restore\"] as const) {\n if (!await findPgTool(tool)) {\n console.error(chalk.red(`✗ \\`${tool}\\` is not on PATH, and this command cannot run without it.`));\n console.error(chalk.gray(\" Install the PostgreSQL client tools, e.g. `brew install libpq`.\"));\n process.exit(1);\n }\n }\n\n // `--database-url` is refused rather than honoured, and refused rather than\n // ignored — which is what it was.\n //\n // Ignored is the dangerous one. The flag was accepted, dropped on the floor,\n // and the pull went ahead against the `.env` database: someone writing\n // `rebase db pull --from prod --database-url scratch --yes` destroyed their\n // working database while naming a different one. A flag that changes nothing\n // is a bug; a destructive flag that changes nothing is a data-loss bug.\n //\n // Honoured is the other tempting answer, and it breaks the one guarantee\n // this command makes. The target is always the local development database\n // *by construction* — there is no `--to`, and no flag that reverses the\n // direction — because a tool that can copy both ways eventually copies the\n // wrong way, and the wrong way here is a laptop over production.\n // `--database-url prod` is exactly that instruction written as a target.\n //\n // `--docker` is a different question and is passed through: it says how to\n // get a local database, not which database to overwrite.\n const targetFlag = readFlagValue(rawArgs, \"--database-url\");\n if (targetFlag !== null) {\n console.error(chalk.red(\"✗ `rebase db pull` does not take --database-url.\"));\n console.error(\"\");\n console.error(chalk.gray(\" The target is always this project's local development database. There is\"));\n console.error(chalk.gray(\" no flag that makes this write somewhere else, deliberately: a command that\"));\n console.error(chalk.gray(\" can copy in both directions eventually copies in the wrong one.\"));\n console.error(\"\");\n console.error(chalk.gray(` To read from another database, that is ${chalk.cyan(\"--from\")}:`));\n console.error(chalk.gray(` rebase db pull --from ${targetFlag}`));\n process.exit(1);\n }\n\n const prepared = await prepareDatabaseEnv(projectRoot, {\n flagDocker: rawArgs.includes(\"--docker\"),\n onProgress: (message) => console.log(chalk.gray(` ${message}`))\n });\n // The database `rebase db url` prints, resolved the one way — see\n // `databaseUrlOf`. Reading only `prepared.env` missed the commonest\n // configuration there is: `DATABASE_URL` in `.env` and nowhere else.\n const target = databaseUrlOf(prepared, readEnvFile(projectRoot)) ?? \"\";\n if (!target) {\n console.error(chalk.red(\"✗ No local database to pull into.\"));\n console.error(chalk.gray(\" Set DATABASE_URL in .env, or run `rebase dev` to start the managed one.\"));\n process.exit(1);\n }\n\n const plan = { source, target, anonymize, schemas };\n\n // Said in full, before anything happens. The target is destroyed, and where\n // the data comes to rest on disk is the part people forget.\n console.log(\"\");\n console.log(chalk.bold(\" This will replace your local database.\"));\n console.log(` ${chalk.gray(\"From\")} ${describeTarget(source)}`);\n console.log(` ${chalk.gray(\"Into\")} ${describeTarget(target)}${prepared.dataDir ? chalk.gray(` (${prepared.dataDir})`) : \"\"}`);\n console.log(` ${chalk.gray(\"Data\")} ${anonymize\n ? \"personal-looking columns will be overwritten after the copy\"\n : chalk.yellow(\"copied as-is, including any personal data\")}`);\n if (schemas.length > 0) console.log(` ${chalk.gray(\"Schemas\")} ${schemas.join(\", \")}`);\n console.log(\"\");\n\n if (!rawArgs.includes(\"--yes\") && !rawArgs.includes(\"-y\")) {\n if (!process.stdin.isTTY) {\n console.error(chalk.red(\"✗ This replaces the local database and cannot prompt here.\"));\n console.error(chalk.yellow(\" Re-run with --yes if that is what you intend.\"));\n process.exit(1);\n }\n const { confirmed } = await inquirer.prompt([{\n type: \"confirm\", name: \"confirmed\", message: \"Continue?\", default: false\n }]);\n if (!confirmed) {\n console.log(chalk.gray(\" Nothing was changed.\"));\n\n return;\n }\n }\n\n const dumpFile = path.join(os.tmpdir(), `rebase-pull-${process.pid}.dump`);\n let failure: string | null = null;\n try {\n console.log(chalk.gray(\" Dumping…\"));\n await execa(\"pg_dump\", [...dumpArgs(plan), \"--file\", dumpFile], { stdio: [\"ignore\", \"inherit\", \"inherit\"] });\n\n console.log(chalk.gray(\" Restoring…\"));\n // stderr is shown as it arrives and kept, for the count in its summary\n // line. Not rejected: every way this ends is judged by `restoreOutcome`,\n // and a failure is reported only after whatever did arrive has been\n // anonymized.\n const restored = restoreOutcome(await execa(\"pg_restore\", restoreArgs(plan, dumpFile), {\n stdin: \"ignore\",\n stdout: \"inherit\",\n stderr: [\"pipe\", \"inherit\"],\n reject: false\n }));\n failure = restored.failure;\n\n // Before the verdict: a partial copy of personal data on a laptop is\n // still personal data on a laptop.\n if (anonymize && restored.started) {\n const { Client } = await import(\"pg\");\n const client = new Client({ connectionString: target });\n await client.connect();\n try {\n const { rows } = await client.query<{ schema: string; table: string; column: string; dataType: string }>(\n `SELECT table_schema AS \"schema\", table_name AS \"table\",\n column_name AS \"column\", data_type AS \"dataType\"\n FROM information_schema.columns\n WHERE table_schema NOT IN ('pg_catalog','information_schema')`\n );\n const statements = anonymizeStatements(rows);\n for (const statement of statements) await client.query(statement);\n console.log(chalk.green(` ✓ Anonymized ${statements.length} table(s).`));\n console.log(chalk.gray(\" Name-based and best-effort: a free-text column may still hold personal data.\"));\n } finally {\n await client.end();\n }\n }\n\n if (!failure) await restoreAppRole(target);\n } finally {\n fs.rmSync(dumpFile, { force: true });\n }\n\n if (failure) {\n console.error(chalk.red(`✗ ${failure}`));\n console.error(chalk.yellow(` The local database holds an incomplete copy of ${describeTarget(source)}.`));\n console.error(chalk.gray(\" Fix what the errors above name — often an extension or a role the source has — and pull again.\"));\n process.exit(1);\n }\n\n console.log(chalk.green(\"✓ Local database now holds a copy of \" + describeTarget(source)));\n}\n\n/**\n * Give the restored copy back the privileges `pg_dump` stripped.\n *\n * A pull without this ends on a green tick and hands over a database the\n * application cannot read: `--no-privileges` removes every GRANT, so the copy\n * has the source's RLS policies and none of the grants behind them, and the\n * first query as `rebase_user` fails with `permission denied`. Measured — 68\n * policies and 60 grants in, 68 policies and 0 grants out.\n *\n * `ensureAppRole` is the routine boot runs and `rebase db push` runs, so the\n * pulled database ends up in the state a booted one is in, and there is no\n * second description of these grants to drift. `detectConnectionPosture` gates\n * it the same way `db push` does: a connection that cannot create roles reports\n * that rather than failing the pull, which has already succeeded by this point.\n *\n * Failure here is a warning, not an error. The data is restored and correct; a\n * missing grant is repaired by the next `rebase dev` or `rebase db push`, and\n * saying so beats unwinding a copy that is fine.\n */\nasync function restoreAppRole(target: string): Promise<void> {\n const { Client } = await import(\"pg\");\n const { detectConnectionPosture, ensureAppRole, REBASE_USER_ROLE } =\n await import(\"@rebasepro/server-postgres\");\n const { provisionableSchemas } = await import(\"../dev-db/pull\");\n\n const client = new Client({ connectionString: target });\n await client.connect();\n try {\n const runSql = async (text: string) => (await client.query(text)).rows as Record<string, unknown>[];\n const posture = await detectConnectionPosture(runSql);\n if (!posture.privileged) {\n console.log(chalk.yellow(\n ` ⚠ Could not re-grant the \"${REBASE_USER_ROLE}\" role — this connection may not create roles.`\n ));\n console.log(chalk.gray(\" The copy has its RLS policies but no privileges behind them;\"));\n console.log(chalk.gray(\" `rebase dev` or `rebase db push` will provision them.\"));\n\n return;\n }\n\n const { rows } = await client.query<{ schema: string }>(\n \"SELECT nspname AS \\\"schema\\\" FROM pg_namespace\"\n );\n const schemas = provisionableSchemas(rows);\n await ensureAppRole(runSql, schemas);\n console.log(chalk.gray(\n ` ✓ Re-granted \"${REBASE_USER_ROLE}\" on ${schemas.length} schema(s) — pg_dump strips privileges.`\n ));\n } catch (error) {\n console.log(chalk.yellow(\n ` ⚠ Restored, but could not re-grant \"rebase_user\": ${error instanceof Error ? error.message : String(error)}`\n ));\n console.log(chalk.gray(\" Run `rebase db push` (or start `rebase dev`) to provision it.\"));\n } finally {\n await client.end();\n }\n}\n\n/**\n * Start the compose database a `db … --docker` was asked to talk to.\n *\n * `--docker` resolved the compose URL and stopped there, so every `db`\n * subcommand carrying it reached a container nobody had started —\n * `ECONNREFUSED 127.0.0.1:5436`, two lines, no diagnosis — including the\n * commands the managed-database refusals send readers to `--docker` for.\n *\n * `rebase dev --docker`'s preflight, called with the compose URL and nothing\n * to push: this is not a schema step, and `rebase db push --docker` is the\n * push. A failure here is reported and not fatal — the command runs and its\n * own connection error follows, which is the same contract `dev` keeps.\n */\nasync function ensureDockerDatabase(projectRoot: string, rawArgs: readonly string[]): Promise<void> {\n if (!rawArgs.includes(\"--docker\")) return;\n\n const { ensureDevDatabase } = await import(\"../utils/dev-preflight\");\n const { readEnvFile } = await import(\"../utils/project\");\n const { resolveComposeUrl } = await import(\"../dev-db/prepare\");\n\n const composeUrl = resolveComposeUrl(projectRoot, readEnvFile(projectRoot));\n if (!composeUrl) {\n // `prepareDatabaseEnv` raises the full message a moment later; saying\n // it twice would be worse than saying it once, in its own words.\n return;\n }\n\n await ensureDevDatabase({\n projectRoot,\n databaseUrl: composeUrl,\n disabled: false,\n // Never a push. `rebase db push --docker` is one, and it runs next.\n hasCollections: false,\n pushSchema: async () => undefined,\n log: message => console.log(message)\n });\n}\n\n/**\n * You cannot delete the branch you are standing on.\n *\n * Not a new rule — it was always refused, by a message about a database the\n * developer had never named. After `switch feature_x` the resolved DSN *is*\n * `rb_feature_x`, so `BranchService.deleteBranch` compared it against the\n * connected database, found them equal, and answered `✗ Cannot delete the main\n * database.` The main database is precisely what the developer was not on.\n *\n * Answered here because the pointer is the CLI's: the driver runs as a child\n * process that has never heard of it, and cannot tell \"the branch you are on\"\n * from \"the main database\" — those are the same connection string to it.\n */\nasync function refuseDeletingActiveBranch(projectRoot: string, rawArgs: readonly string[]): Promise<void> {\n const [, , , name] = commandWords(rawArgs, \"db\");\n if (!name) return;\n\n const { readActiveBranch } = await import(\"../dev-db/branch-pointer\");\n const active = readActiveBranch(projectRoot);\n if (active?.name !== name) return;\n\n const off = \"rebase db branch switch --off\";\n const del = `rebase db branch delete ${name}`;\n const column = Math.max(off.length, del.length) + 4;\n\n console.error(\"\");\n console.error(chalk.red(`✗ You are on branch \"${name}\" — leave it before deleting it.`));\n console.error(\"\");\n console.error(chalk.gray(` Every database command in this checkout is pointed at ${active.database},`));\n console.error(chalk.gray(\" including this one, so the delete would be asking that database to drop\"));\n console.error(chalk.gray(\" itself.\"));\n console.error(\"\");\n console.error(` ${chalk.cyan(off)}${\" \".repeat(column - off.length)}back to the main database`);\n console.error(` ${chalk.cyan(del)}${\" \".repeat(column - del.length)}then this works`);\n console.error(\"\");\n process.exit(1);\n}\n\n/**\n * `branch list` reads the branch registry, which lives in the parent.\n *\n * `rebase.branches` is written in the database branches are made *from*, and a\n * branch is a `CREATE DATABASE … TEMPLATE` copy — so the copy carries a\n * snapshot of that table taken at branch time, and every branch made since is\n * missing from it. After `switch feature_x`, `branch list` connected to\n * `rb_feature_x` and answered `No branches found. Create one with: rebase db\n * branch create <name>` while `branch switch` with no argument, one command\n * earlier, had said `● On branch feature_x`.\n *\n * Resolved with `branch: null` — the same rule `switch` uses to find what to\n * branch *from* — and relayed as `--database-url`, which the driver honours\n * over anything it would resolve for itself.\n */\nasync function listFromParentDatabase(projectRoot: string, rawArgs: string[]): Promise<string[]> {\n // An explicit `--database-url` is the developer naming the database; this\n // never overrides one.\n if (readFlagValue(rawArgs, \"--database-url\") !== null) return rawArgs;\n\n const { readActiveBranch } = await import(\"../dev-db/branch-pointer\");\n const active = readActiveBranch(projectRoot);\n if (!active) return rawArgs;\n\n const { readEnvFile } = await import(\"../utils/project\");\n const { resolveDevDatabase } = await import(\"../dev-db/resolve\");\n const { resolveComposeUrl } = await import(\"../dev-db/prepare\");\n\n const envFile = readEnvFile(projectRoot);\n const parent = resolveDevDatabase({\n flagDocker: rawArgs.includes(\"--docker\"),\n env: process.env,\n envFile,\n branch: null,\n composeUrl: resolveComposeUrl(projectRoot, envFile)\n });\n const url = (parent.kind === \"managed\" ? null : parent.url)?.trim();\n if (!url) return rawArgs;\n\n console.log(chalk.gray(` ● On branch ${active.name} — listing from the main database, where the registry lives.`));\n\n return [...rawArgs, \"--database-url\", url];\n}\n\n/**\n * `rebase db branch switch <name>` — point this checkout at a branch.\n *\n * The step branching was missing. `create` copied the database in about a\n * second and then printed `Database: rb_feature_auth` and stopped: there was no\n * `switch`, no `--branch` on `rebase dev`, and no `REBASE_BRANCH`. The only way\n * to use a branch was to hand-edit `DATABASE_URL`, while the documentation said\n * \"the CLI updates your local development configuration\" — it did not, and the\n * `.env` was byte-identical afterwards.\n *\n * Three things it insists on:\n *\n * - **The branch has to exist.** Writing a pointer to a database that was never\n * created turns a typo into a connection error on the *next* command, which\n * is the one place it cannot be explained. Checked against\n * `rebase.branches` and `pg_database` both, because a branch dropped outside\n * Rebase leaves the metadata row behind.\n *\n * - **It says what changed, and how to undo it.** A command that silently\n * redirects every subsequent database operation owes the reader the database\n * name it moved to and the words that move it back.\n *\n * - **It never edits `.env`.** See `branch-pointer.ts`.\n */\nasync function switchBranch(projectRoot: string, rawArgs: readonly string[]): Promise<void> {\n const { branchDatabaseName, clearActiveBranch, databaseNameOf, readActiveBranch, writeActiveBranch } =\n await import(\"../dev-db/branch-pointer\");\n const { readEnvFile } = await import(\"../utils/project\");\n const { resolveDevDatabase } = await import(\"../dev-db/resolve\");\n const { resolveComposeUrl } = await import(\"../dev-db/prepare\");\n\n // Read as a flag rather than as the name in the third position, so\n // `switch --off` and `switch feature --off` mean the same thing. The doc\n // verifier reads a command's flags out of exactly this shape, which is the\n // other reason: a flag it cannot see is one it reports as unrunnable in\n // every page that documents it.\n const goingOff = rawArgs.includes(\"--off\") || rawArgs.includes(\"--main\");\n\n // [\"db\", \"branch\", \"switch\", <name>], with any flags taken back out —\n // `rebase --debug db branch switch feature` read the name as \"switch\".\n const name = commandWords(rawArgs, \"db\")[3];\n\n // The database to branch from, resolved by the ordered rule every sibling\n // uses. This read `readEnvFile(projectRoot).DATABASE_URL` and nothing else,\n // so `export DATABASE_URL=…; rebase db branch create x` created a branch and\n // `rebase db branch switch x` then answered \"This project has no\n // DATABASE_URL, so there is no database to branch from\" — about a project\n // that had one, in the shell, where `branching.md` documents it as rule (2)\n // and `create` had just read it.\n //\n // `branch: null`, deliberately: this command is what sets the pointer, and\n // the pointer that exists must never become the base of the next switch —\n // that is how a branch of a branch of a branch happens by accident.\n const envFile = readEnvFile(projectRoot);\n const resolved = resolveDevDatabase({\n flagUrl: readFlagValue(rawArgs, \"--database-url\"),\n flagDocker: rawArgs.includes(\"--docker\"),\n env: process.env,\n envFile,\n branch: null,\n composeUrl: resolveComposeUrl(projectRoot, envFile)\n });\n const base = (resolved.kind === \"managed\" ? null : resolved.url)?.trim() || undefined;\n\n // `switch` with no argument reports rather than changes. \"Which branch am I\n // on\" is asked far more often than \"move me\", and answering it should not\n // require guessing a flag.\n if (!name && !goingOff) {\n const active = readActiveBranch(projectRoot);\n console.log(\"\");\n if (active) {\n console.log(` ${chalk.green(\"●\")} On branch ${chalk.bold(active.name)} ${chalk.gray(`(${active.database})`)}`);\n console.log(chalk.gray(` Back to the main database: ${chalk.cyan(\"rebase db branch switch --off\")}`));\n } else {\n const main = base ? databaseNameOf(base) : null;\n console.log(` ${chalk.gray(\"●\")} On the main database${main ? chalk.gray(` (${main})`) : \"\"}`);\n console.log(chalk.gray(` Switch to a branch: ${chalk.cyan(\"rebase db branch switch <name>\")}`));\n }\n console.log(\"\");\n\n return;\n }\n\n if (goingOff) {\n const active = readActiveBranch(projectRoot);\n clearActiveBranch(projectRoot);\n console.log(\"\");\n console.log(active\n ? chalk.green(` ✓ Back on the main database${base ? ` (${databaseNameOf(base)})` : \"\"}.`)\n : chalk.gray(\" Already on the main database.\"));\n console.log(\"\");\n\n return;\n }\n\n if (!base) {\n console.error(chalk.red(\"✗ There is no database to branch from.\"));\n console.error(chalk.gray(resolved.kind === \"managed\"\n ? \" This project is on the managed development database, which serves exactly one —\"\n : \" --docker needs a docker-compose.yml with a db service, and this project has none —\"));\n console.error(chalk.gray(\" and branching copies a database. Set DATABASE_URL in .env or in your\"));\n console.error(chalk.gray(\" shell, or run `rebase dev --docker`.\"));\n process.exit(1);\n }\n\n const database = branchDatabaseName(name);\n\n // Verified before the pointer is written, not after.\n const { Client } = await import(\"pg\");\n const client = new Client({ connectionString: base });\n try {\n await client.connect();\n } catch (error) {\n console.error(chalk.red(`✗ Could not reach the database to check that branch \"${name}\" exists.`));\n console.error(chalk.gray(` ${error instanceof Error ? error.message : String(error)}`));\n process.exit(1);\n }\n try {\n const { rows } = await client.query<{ registered: boolean; present: boolean }>(\n `SELECT EXISTS (SELECT 1 FROM rebase.branches WHERE name = $1) AS registered,\n EXISTS (SELECT 1 FROM pg_database WHERE datname = $2) AS present`,\n [name, database]\n ).catch(() => ({ rows: [{ registered: false, present: false }] }));\n\n const { registered, present } = rows[0] ?? { registered: false, present: false };\n if (!present) {\n console.error(chalk.red(`✗ Branch \"${name}\" does not exist.`));\n console.error(registered\n // The metadata row outlives a database dropped with plain SQL.\n ? chalk.gray(` It is registered but its database (${database}) is gone — someone dropped it outside Rebase.`)\n : chalk.gray(` ${chalk.cyan(\"rebase db branch list\")} shows the ones that do.`));\n process.exit(1);\n }\n } finally {\n await client.end();\n }\n\n writeActiveBranch(projectRoot, { name, database });\n\n console.log(\"\");\n console.log(chalk.green(` ✓ Switched to branch \"${name}\".`));\n console.log(chalk.gray(` Database: ${database}`));\n console.log(chalk.gray(\" Every rebase command in this checkout now uses it — dev, db push, migrate.\"));\n console.log(chalk.gray(` Back to the main database: ${chalk.cyan(\"rebase db branch switch --off\")}`));\n console.log(\"\");\n}\n\n/**\n * What each `rebase db <action>` does and takes.\n *\n * Kept here rather than delegated to the driver because the driver is reached\n * by *running* it — which is exactly what `--help` must not do. The page is\n * deliberately short: the authority on a flag is the command's own spec, and\n * `check-doc-commands.mjs` holds every command written in this repository's\n * markdown to it. What a reader needs from here is which subcommands exist and\n * what the destructive ones want before they will run.\n */\nconst DB_ACTION_HELP: Record<string, { usage: string; summary: string; notes?: string[] }> = {\n push: {\n usage: \"rebase db push [--collections <dir>] [--dry-run] [--allow-destructive] [--yes]\",\n summary: \"Apply the schema straight to the database. Development only — it does not write a migration.\",\n notes: [\n \"--dry-run prints the SQL and applies nothing. Read it before you approve it.\",\n \"A change that would drop data needs --allow-destructive.\"\n ]\n },\n generate: {\n usage: \"rebase db generate [--collections <dir>]\",\n summary: \"Generate the Drizzle schema, the Postgres DDL and a SQL migration file from the collections.\"\n },\n migrate: {\n usage: \"rebase db migrate [--baseline <version>] [amount]\",\n summary: \"Run the pending migration files against the database.\",\n notes: [\n \"--baseline <version> records that version as already applied and starts from the next one.\",\n \"It is what a database Rebase has already booted against needs: boot ensures the schema, so the first migration would try to create tables that are already there.\",\n \"The version is the numeric prefix of a file in drizzle/migrations.\"\n ]\n },\n branch: {\n // Every action the dispatch answers and every flag its specs declare.\n // The page is kept here rather than delegated because reaching the\n // driver's own `printBranchHelp` means *running* the driver, which is\n // what `--help` must not do — so `help-coverage.test.ts` holds the two\n // to each other instead. It went two releases without learning `prune`,\n // `--from`, `--force` or `--older-than`, all four of which the dispatch\n // answers and the docs teach.\n usage: \"rebase db branch <create|list|switch|delete|info|prune> [name]\",\n summary: \"Database branching.\",\n notes: [\n \"create <name> [--from <source>] copies an existing database, files and all.\",\n \"switch <name> points this checkout at a branch; every later command uses it.\",\n \"switch with no name reports where you are; switch --off returns to the main database.\",\n \"prune [--older-than <14|14d|2w>] removes branches nothing is using, and the entries that drifted.\",\n \"prune --include-dev-diff also removes the Atlas scratch databases `db push` leaves behind.\",\n \"prune asks before it drops anything; --yes, -y answers for you, which is the form a CI job wants.\",\n \"--force disconnects other sessions first — Postgres refuses to copy or drop a database anything is connected to, usually your own `rebase dev`.\"\n ]\n },\n backup: {\n usage: \"rebase db backup [--out <path|s3://…>]\",\n summary: \"Create a pg_dump backup. --out is resolved against the directory you are standing in.\",\n notes: [\n \"--output is accepted as an alias, as it is on `rebase build`.\",\n \"`rebase db backup list` lists them, the way `rebase cloud db backup list` does.\"\n ]\n },\n backups: {\n usage: \"rebase db backups list [--out <path|s3://…>]\",\n summary: \"List stored backups.\",\n notes: [\"`rebase db backup list` is the same command, spelled the cloud family's way.\"]\n },\n url: {\n usage: \"rebase db url\",\n summary: \"Print the connection string this project uses. Nothing else goes to stdout, so it pipes.\",\n notes: [\n \"psql \\\"$(rebase db url)\\\"\",\n \"Starts the managed database if it is not already running.\"\n ]\n },\n restore: {\n usage: \"rebase db restore <dump> [--target-db <name>] [--create-db] --yes\",\n summary: \"Restore a backup with pg_restore.\",\n notes: [\"Destructive, and refuses to run without --yes.\"]\n },\n pull: {\n usage: \"rebase db pull --from <url> [--schema <name>] [--anonymize] [--yes]\",\n summary: \"Copy another database into local development. One-directional by design — it can never push.\",\n notes: [\"The target is not selectable: --database-url is refused, so this can never write to a remote database.\"]\n },\n stop: { usage: \"rebase db stop\", summary: \"Stop the managed development database. Data is kept.\" },\n reset: {\n usage: \"rebase db reset [--yes]\",\n summary: \"Delete the managed development database and start over.\",\n notes: [\"Destructive, and the data exists only on this machine.\"]\n }\n};\n\n/** Every subcommand the family dispatches — the help table's keys. */\nexport const DB_SUBCOMMANDS = Object.keys(DB_ACTION_HELP);\n\nfunction printDbHelp(action?: string) {\n const entry = action ? DB_ACTION_HELP[action] : undefined;\n if (entry) {\n console.log(`\n${chalk.bold(`rebase db ${action}`)}\n\n ${entry.summary}\n\n${chalk.green.bold(\"Usage\")}\n ${chalk.blue(entry.usage)}\n${entry.notes?.length ? `\\n${chalk.green.bold(\"Notes\")}\\n${entry.notes.map(n => ` ${chalk.gray(`• ${n}`)}`).join(\"\\n\")}\\n` : \"\"}\n${chalk.gray(\"Run `rebase db --help` for every subcommand.\")}\n`);\n return;\n }\n\n console.log(`\n${chalk.bold(\"rebase db\")} — Database management commands\n\n${chalk.green.bold(\"Usage\")}\n rebase db ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.gray(\"(Commands are provided by your active database driver plugin)\")}\n ${chalk.blue.bold(\"url\")} Print the connection string this project uses (pipes into psql)\n ${chalk.blue.bold(\"pull\")} Copy another database into local dev (--from <url>, --anonymize)\n ${chalk.blue.bold(\"stop\")} Stop the managed development database (data is kept)\n ${chalk.blue.bold(\"reset\")} Delete the managed development database and start over\n ${chalk.blue.bold(\"push\")} Apply schema directly to database (development)\n ${chalk.blue.bold(\"generate\")} Generate migration files\n ${chalk.blue.bold(\"migrate\")} Run pending migrations\n ${chalk.blue.bold(\"branch\")} Database branching (create, list, switch, delete, info, prune)\n ${chalk.blue.bold(\"backup\")} Create a backup with pg_dump (--out <path|s3://…>)\n ${chalk.blue.bold(\"restore\")} Restore a backup with pg_restore (destructive; needs --yes)\n ${chalk.blue.bold(\"backups\")} List stored backups (db backup list is the same)\n\n${chalk.green.bold(\"Examples\")}\n${dbExamples(devDatabaseKind())}\n ${chalk.gray(\"# Back up to a local directory, then to object storage\")}\n rebase db backup --out ./backups\n rebase db backup --out s3://my-private-bucket/backups\n\n ${chalk.gray(\"# Restore into a fresh database (safe: does not touch the live one)\")}\n rebase db restore ./backups/rebase-app-20260714T030000Z.dump --create-db --target-db app_restored\n`);\n}\n\n/**\n * The examples, which are not the same on the managed development database.\n *\n * Every one of the four the help used to lead with — `db push`, `db generate`,\n * `db migrate`, `db branch` — is refused there, by guards in this same file\n * that explain exactly why. So on the project the CLI had just scaffolded, the\n * first thing `rebase db --help` offered was a command that answers with a\n * refusal, and the reader's most likely conclusion is that their install is\n * broken.\n *\n * Exported for its test.\n */\nexport function dbExamples(kind: DevDatabase[\"kind\"] | null): string {\n if (kind === \"managed\") {\n return ` ${chalk.gray(\"# Quick development workflow (this project is on the managed database)\")}\n rebase schema generate\n rebase dev ${chalk.gray(\"# boot applies your collections to it, additively\")}\n\n ${chalk.gray(\"# push, generate, migrate and branch need a Postgres of your own\")}\n rebase dev --docker ${chalk.gray(\"# starts one; or uncomment DATABASE_URL in .env\")}\n\n`;\n }\n\n return ` ${chalk.gray(\"# Quick development workflow\")}\n rebase schema generate && rebase db push\n\n ${chalk.gray(\"# Production migration workflow\")}\n rebase db generate\n rebase db migrate\n\n ${chalk.gray(\"# Create a database branch and work on it\")}\n rebase db branch create feature_auth\n rebase db branch switch feature_auth\n rebase db branch switch --off\n\n`;\n}\n","/**\n * CLI command: rebase schema <action>\n */\nimport chalk from \"chalk\";\nimport { spawnDriverCli } from \"./db\";\nimport {\n requireProjectRoot,\n requireBackendDir,\n getActiveBackendPlugin,\n resolvePluginCliScript,\n resolveTsx,\n findEnvFile,\n exitDependenciesNotInstalled\n} from \"../utils/project\";\nimport { recordEvent } from \"../telemetry\";\nimport { wantsHelp } from \"../utils/args\";\nimport { reportSpawnFailure } from \"../utils/spawn-error\";\nimport { argsFromCommand } from \"../utils/command-words\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport { DEV_DATABASE_KIND_ENV, devDatabaseKind } from \"../dev-db/prepare\";\n\nexport async function schemaCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // `--help` is answered here, before `requireProjectRoot` and before the\n // driver is spawned — the same shape `db.ts` already uses, and for the same\n // reason.\n //\n // `cli.ts` rewrites the subcommand to `\"--help\"` only when the user named\n // none, so `rebase schema --help` was covered and `rebase schema generate\n // --help` was not: the flag travelled into `rawArgs.slice(2)` and reached\n // the driver, whose own `schemaCommand` has no `--help` case. It *ran the\n // generator* — overwriting `src/schema.generated.ts` — for a flag whose\n // entire job is to print text. Worse, the first thing it hit outside a\n // project was `requireProjectRoot`, so `rebase schema introspect --help` in\n // an empty directory exited 1 with \"Could not find a Rebase project root\":\n // help you cannot read until you already have a project is help for nobody.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printSchemaHelp(subcommand === \"--help\" ? undefined : subcommand);\n return;\n }\n\n // A typo is answered here, in the same words every other family uses.\n //\n // It used to travel to the driver, which said the bare line `Unknown schema\n // command.` — no list, no pointer, no did-you-mean, for a family with three\n // subcommands. The set comes from the help table, so what a typo is measured\n // against and what `--help` prints cannot drift apart.\n if (!SCHEMA_ACTION_HELP[subcommand]) {\n unknownCommand(subcommand, Object.keys(SCHEMA_ACTION_HELP), \"schema\");\n }\n\n const projectRoot = requireProjectRoot();\n\n // Fire-and-forget, and a no-op unless the developer opted in. Never awaited:\n // the command is what the user is waiting for, and a slow collector must not\n // sit in front of it.\n void recordEvent(\"cli.schema\", { subcommand: subcommand ?? \"none\" }, { projectRoot });\n const backendDir = requireBackendDir(projectRoot);\n\n const activePlugin = getActiveBackendPlugin(backendDir);\n if (!activePlugin) {\n console.error(chalk.red(\"✗ Could not detect an active database plugin.\"));\n console.error(chalk.gray(\" Make sure a package like @rebasepro/server-postgres is installed in backend/package.json.\"));\n process.exit(1);\n }\n\n const pluginCli = resolvePluginCliScript(backendDir, activePlugin);\n if (!pluginCli) {\n exitDependenciesNotInstalled(projectRoot);\n }\n\n // Set up environment with DOTENV_CONFIG_PATH\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n // Which database this project is on, so the driver's closing line does not\n // recommend a command that database refuses. A pure decision — nothing is\n // started, which matters here above all: `schema generate` reads collection\n // files and writes one file, and booting a database to run it would be a\n // side effect nobody asked for.\n env[DEV_DATABASE_KIND_ENV] = devDatabaseKind(projectRoot) ?? \"\";\n\n try {\n // The one spawn, shared with `db`. This file used to carry its own copy\n // of the tsx-or-node decision; three copies of that rule existed and two\n // were fixed while the third went on spawning plain node.\n await spawnDriverCli(\n { projectRoot, backendDir, pluginCli, env },\n argsFromCommand(rawArgs, \"schema\")\n );\n } catch (error) {\n // A child that ran and exited non-zero already printed its diagnostics\n // through inherited stdio; a child that never started (ENOENT on tsx,\n // EACCES on the script) printed nothing at all, and this used to exit 1\n // in silence.\n reportSpawnFailure(error);\n process.exit(1);\n }\n}\n\n/** One page per subcommand, so `rebase schema <action> --help` says something. */\nconst SCHEMA_ACTION_HELP: Record<string, { usage: string; summary: string; notes?: string[] }> = {\n generate: {\n usage: \"rebase schema generate [--collections <dir>] [--output <file>] [--watch]\",\n summary: \"Generate the Drizzle schema from the collection definitions.\",\n notes: [\"--watch regenerates on every change to a collection file.\"]\n },\n introspect: {\n usage: \"rebase schema introspect [--collections <dir>] [--output <dir>] [--schema <name>] [--force]\",\n summary: \"Read an existing database and write Rebase collection definitions from it.\",\n notes: [\"--force overwrites collection files that are already there.\"]\n },\n stale: {\n usage: \"rebase schema stale [--collections <dir>] [--output <file>] [--fix]\",\n summary: \"Report generated schema files that no longer match the collections.\",\n notes: [\"--fix regenerates them instead of only reporting.\"]\n }\n};\n\n/** Every subcommand the family dispatches — the help table's keys. */\nexport const SCHEMA_SUBCOMMANDS = Object.keys(SCHEMA_ACTION_HELP);\n\nfunction printSchemaHelp(action?: string) {\n const entry = action ? SCHEMA_ACTION_HELP[action] : undefined;\n if (entry) {\n console.log(`\n${chalk.bold(`rebase schema ${action}`)}\n\n ${entry.summary}\n\n${chalk.green.bold(\"Usage\")}\n ${chalk.blue(entry.usage)}\n${entry.notes?.length ? `\\n${chalk.green.bold(\"Notes\")}\\n${entry.notes.map(n => ` ${chalk.gray(`• ${n}`)}`).join(\"\\n\")}\\n` : \"\"}\n${chalk.gray(\"Run `rebase schema --help` for every subcommand.\")}\n`);\n return;\n }\n\n console.log(`\n${chalk.bold(\"rebase schema\")} — Schema management commands\n\n${chalk.green.bold(\"Usage\")}\n rebase schema ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.gray(\"(Commands are provided by your active database driver plugin)\")}\n ${chalk.blue.bold(\"generate\")} Generate Schema from collection definitions\n ${chalk.blue.bold(\"introspect\")} Introspect an existing database to generate collection definitions\n ${chalk.blue.bold(\"stale\")} Report generated schema files that no longer match the collections\n\n${chalk.green.bold(\"generate Options\")}\n ${chalk.blue(\"--collections, -c\")} Path to collections directory\n ${chalk.blue(\"--output, -o\")} Output path for generated schema\n ${chalk.blue(\"--watch, -w\")} Watch for changes and regenerate automatically\n\n${chalk.green.bold(\"introspect Options\")}\n ${chalk.blue(\"--output, -o\")} Output directory for generated collection files\n ${chalk.blue(\"--schema\")} Postgres schema to read (default: public)\n ${chalk.blue(\"--force, -f\")} Overwrite collection files that already exist\n\n${chalk.green.bold(\"stale Options\")}\n ${chalk.blue(\"--fix\")} Regenerate the stale files instead of only reporting them\n`);\n}\n","/**\n * Loading, validating and synthesizing `rebase.json`.\n *\n * The manifest declares *topology*: which runtime major a project targets and\n * which apps this repository contributes. It is deliberately small — schema,\n * security rules, hooks and functions stay in TypeScript, where a type system\n * can check them.\n *\n * Two properties matter more than the file format itself:\n *\n * - **A missing manifest is never an error.** Every project that exists today\n * predates this file. One is synthesized from the conventions the template\n * already follows, so nothing breaks and nobody is forced to migrate.\n * - **Validation reports every problem at once**, with the path to each. A\n * config file that surfaces its mistakes one run at a time is a bad config\n * file.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport {\n findStorageSuffixCollision,\n reservedPrefixFor,\n type ManagedCompatibility,\n type RebaseAppConfig,\n type RebaseBackendAppConfig,\n type RebaseProjectManifest,\n type RebaseStaticAppConfig\n} from \"@rebasepro/types\";\nimport { MANIFEST_FILENAME } from \"./utils/project\";\n\n/** Runtime range written into new manifests. */\nexport const CURRENT_RUNTIME_RANGE = \"^1\";\n\n/** Conventional locations, matching what `rebase init` scaffolds. */\nexport const DEFAULT_CONFIG_DIR = \"config\";\nexport const DEFAULT_FUNCTIONS_DIR = \"backend/functions\";\nexport const DEFAULT_CRONS_DIR = \"backend/crons\";\nexport const DEFAULT_SCHEMA_FILE = \"backend/src/schema.generated.ts\";\n\nexport interface ManifestValidationIssue {\n /** Dotted path to the offending value, e.g. `apps.web.output`. */\n path: string;\n message: string;\n}\n\nexport interface LoadedManifest {\n manifest: RebaseProjectManifest;\n /** Where it came from — a real file, or inferred from the directory layout. */\n source: \"file\" | \"synthesized\";\n /** Absolute path to `rebase.json`, when one exists. */\n filePath?: string;\n}\n\nexport class ManifestError extends Error {\n constructor(message: string, readonly issues: ManifestValidationIssue[] = []) {\n super(message);\n this.name = \"ManifestError\";\n }\n}\n\nconst APP_TYPES = [\"backend\", \"static\"] as const;\n\n/**\n * App types that used to exist, and what replaced each one.\n *\n * Kept so a manifest written against the old vocabulary fails with the fix in\n * hand rather than with `must be one of: backend, static`, which tells a reader\n * what is wrong but not what to write instead.\n */\nconst REMOVED_APP_TYPES: Record<string, string> = {\n admin:\n \"the admin panel is an ordinary static app now — declare it as \" +\n '{ \"type\": \"static\", \"root\": \"frontend\", \"output\": \"frontend/dist\", \"path\": \"/admin\" }',\n custom:\n \"who owns the server is a property of the backend now — declare \" +\n '{ \"type\": \"backend\", \"runtime\": \"custom\" } instead of a separate app',\n mobile:\n \"mobile apps are no longer declared in the manifest — nothing consumed this type. \" +\n \"Remove the entry\"\n};\n\n/** Reserved because they name things in URLs and CLI output. */\nconst RESERVED_APP_NAMES = new Set([\"api\", \"health\", \"metrics\", \"livez\", \"_rebase\"]);\n\n/**\n * Validate a static app's public base path.\n *\n * Normalizes to \"no trailing slash, except for the root\" so that mounting and\n * the `REBASE_APP_BASE` build variable have one shape to reason about.\n */\nfunction checkAppPath(\n value: unknown,\n fieldPath: string,\n issues: ManifestValidationIssue[]\n): string | undefined {\n if (value === undefined) return undefined;\n if (typeof value !== \"string\" || !value.startsWith(\"/\") || value.includes(\"..\")) {\n issues.push({\n path: fieldPath,\n message: 'must be an absolute path like \"/admin\"'\n });\n return undefined;\n }\n if (value !== \"/\" && value.endsWith(\"/\")) {\n issues.push({\n path: fieldPath,\n message: 'must not end with a slash — write \"/admin\", not \"/admin/\"'\n });\n return undefined;\n }\n // Mounting is longest-path-first, so an app at `/api` outranks the API and\n // every request to it is answered with that app's index.html — a 200 of HTML\n // where the caller wanted JSON, from a deployment that looks healthy.\n const reserved = reservedPrefixFor(value);\n if (reserved) {\n issues.push({\n path: fieldPath,\n message: `cannot be \"${reserved}\" or nest under it — the backend serves that path, ` +\n \"and an app mounted there would answer the API's requests with its own index.html\"\n });\n return undefined;\n }\n return value;\n}\n\n/**\n * Is `candidate` the path `parent`, or something beneath it?\n *\n * Segment-aware for the same reason `isForbiddenStaticPath` is: a plain\n * `startsWith` reads `/admin` as living under `/adm`.\n */\nfunction isUnderPath(candidate: string, parent: string): boolean {\n if (parent === \"/\") return true;\n return candidate === parent || candidate.startsWith(`${parent}/`);\n}\n\n/**\n * Validate where an app says it mounts the Rebase CMS.\n *\n * The same shape as {@link checkAppPath} — it is a URL path and ends up in the\n * same places — plus one rule of its own: it has to be inside the app declaring\n * it. The app's SPA fallback is what answers that URL, so a `cms` outside its\n * `path` names an address this app will never serve. That is a link the console\n * would then offer to a 404, which is worse than the missing link it replaces.\n */\nfunction checkCmsPath(\n value: unknown,\n appPath: string,\n fieldPath: string,\n issues: ManifestValidationIssue[]\n): string | undefined {\n if (value === undefined) return undefined;\n const cms = checkAppPath(value, fieldPath, issues);\n if (cms === undefined) return undefined;\n if (!isUnderPath(cms, appPath)) {\n issues.push({\n path: fieldPath,\n message: `must be inside this app's path — it is at \"${appPath}\", so it cannot serve \"${cms}\". ` +\n \"The CMS is a route of this app, not a separate deployment; if it really lives elsewhere, \" +\n \"declare that app and put `cms` on it instead\"\n });\n return undefined;\n }\n return cms;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Reject paths that escape the repository.\n *\n * A manifest is committed and reviewed, so this is not a security boundary so\n * much as a guard against `../../` typos that would otherwise have `rebase build`\n * writing outside the project.\n *\n * `mayEscape` is for `context`, and only for `context`. Every other path here\n * names something Rebase *reads* — collections, functions, the generated\n * schema, the built assets to serve — and those have to be inside the project\n * or the bundle cannot carry them. A Docker build context is the one field that\n * names something Rebase never opens: it is handed to `docker build`, and in\n * any workspace repository the thing it has to name is the workspace root,\n * above the app. That is not exotic. It is what pnpm, turbo and nx layouts all\n * look like, and it is what this repository's own reference project needs — its\n * Dockerfile's first instruction copies `pnpm-lock.yaml`, which does not exist\n * beside `rebase.json` and never will.\n *\n * Refusing it did not prevent the escape; it only stopped anyone declaring it.\n * `app/rebase.json` built from the monorepo root the whole time — via\n * `infra/cloudbuild.yaml`, which says `-f app/backend/Dockerfile .` — while the\n * manifest said the context was `app/` and `rebase build` printed a command\n * that dies on its first `COPY`.\n */\nfunction checkRelativePath(\n value: unknown,\n fieldPath: string,\n issues: ManifestValidationIssue[],\n { required, mayEscape = false }: { required: boolean; mayEscape?: boolean }\n): string | undefined {\n if (value === undefined) {\n if (required) issues.push({ path: fieldPath,\nmessage: \"is required\" });\n return undefined;\n }\n if (typeof value !== \"string\" || value.trim() === \"\") {\n issues.push({ path: fieldPath,\nmessage: \"must be a non-empty string\" });\n return undefined;\n }\n if (path.isAbsolute(value)) {\n issues.push({ path: fieldPath,\nmessage: \"must be a relative path, not absolute\" });\n return undefined;\n }\n const normalized = path.normalize(value);\n if (!mayEscape && (normalized === \"..\" || normalized.startsWith(`..${path.sep}`))) {\n issues.push({ path: fieldPath,\nmessage: \"must stay inside the project directory\" });\n return undefined;\n }\n return value;\n}\n\n/** Fields each app type understands. Anything else is a typo or a newer CLI. */\nconst KNOWN_APP_FIELDS: Record<string, readonly string[]> = {\n backend: [\"type\", \"runtime\", \"config\", \"functions\", \"crons\", \"schema\",\n \"usersCollection\", \"dockerfile\", \"context\", \"port\"],\n static: [\"type\", \"root\", \"build\", \"output\", \"path\", \"spa\", \"cms\"]\n};\n\n/**\n * Report a field this CLI does not recognise.\n *\n * A warning rather than an error, and the distinction matters in both\n * directions. `\"pathh\": \"/admin\"` is a typo that would otherwise be silently\n * dropped — the app builds for `/`, mounts at `/`, and the only symptom is that\n * it is not where you put it. But an unknown field is also what an *older* CLI\n * sees when it opens a manifest written for a newer one, and refusing to build\n * over a field that is simply from the future would make every manifest addition\n * a breaking change.\n *\n * So: name it, suggest the near-miss, and carry on.\n */\nfunction warnUnknownFields(name: string, raw: Record<string, unknown>, type: string): void {\n const known = KNOWN_APP_FIELDS[type];\n if (!known) return;\n\n for (const field of Object.keys(raw)) {\n if (known.includes(field)) continue;\n const suggestion = known.find(candidate => isNearMiss(candidate, field));\n console.warn(\n `⚠ rebase.json: apps.${name}.${field} is not a field this CLI knows.` +\n (suggestion ? ` Did you mean \"${suggestion}\"?` : \" It is ignored — your CLI may be older than this manifest.\")\n );\n }\n}\n\n/**\n * One edit apart, ignoring case: enough for a typo, tight enough to stay quiet.\n *\n * The same rule as `isNearMiss` in `@rebasepro/utils`, which the collection\n * validator uses for unknown `admin` keys. It is a copy rather than an import\n * because the CLI does not depend on `@rebasepro/utils`, and adding the\n * dependency is a lockfile change; collapsing the two is worth doing the next\n * time this package's dependencies are touched.\n */\nfunction isNearMiss(a: string, b: string): boolean {\n const x = a.toLowerCase();\n const y = b.toLowerCase();\n if (x === y) return true;\n if (Math.abs(x.length - y.length) > 1) return false;\n\n const [shorter, longer] = x.length <= y.length ? [x, y] : [y, x];\n let i = 0;\n let j = 0;\n let edits = 0;\n while (i < shorter.length && j < longer.length) {\n if (shorter[i] === longer[j]) { i++; j++; continue; }\n if (++edits > 1) return false;\n if (shorter.length === longer.length) i++;\n j++;\n }\n return edits + (longer.length - j) + (shorter.length - i) <= 1;\n}\n\nfunction validateApp(\n name: string,\n raw: unknown,\n issues: ManifestValidationIssue[]\n): RebaseAppConfig | undefined {\n const base = `apps.${name}`;\n\n if (!isRecord(raw)) {\n issues.push({ path: base,\nmessage: \"must be an object\" });\n return undefined;\n }\n\n const type = raw.type;\n if (typeof type === \"string\" && REMOVED_APP_TYPES[type]) {\n issues.push({ path: `${base}.type`,\nmessage: `\"${type}\" is no longer an app type — ${REMOVED_APP_TYPES[type]}` });\n return undefined;\n }\n if (typeof type !== \"string\" || !(APP_TYPES as readonly string[]).includes(type)) {\n issues.push({\n path: `${base}.type`,\n message: `must be one of: ${APP_TYPES.join(\", \")}`\n });\n return undefined;\n }\n\n warnUnknownFields(name, raw, type);\n\n switch (type) {\n case \"backend\": {\n checkRelativePath(raw.config, `${base}.config`, issues, { required: false });\n checkRelativePath(raw.functions, `${base}.functions`, issues, { required: false });\n checkRelativePath(raw.crons, `${base}.crons`, issues, { required: false });\n checkRelativePath(raw.schema, `${base}.schema`, issues, { required: false });\n checkRelativePath(raw.usersCollection, `${base}.usersCollection`, issues, { required: false });\n\n if (raw.mode !== undefined) {\n issues.push({\n path: `${base}.mode`,\n message:\n \"is no longer a field — collections come from the config directory when \" +\n \"it exists, and are introspected from the database when it does not\"\n });\n }\n\n const custom = raw.runtime === \"custom\";\n if (raw.runtime !== \"managed\" && !custom) {\n issues.push({\n path: `${base}.runtime`,\n message: 'is required, and must be \"managed\" or \"custom\"'\n });\n }\n\n // The image fields describe an image this repository builds. Under a\n // managed backend there is no such image, so accepting them silently\n // would be accepting a Dockerfile that never gets built.\n for (const field of [\"dockerfile\", \"context\", \"port\"] as const) {\n if (raw[field] !== undefined && !custom) {\n issues.push({\n path: `${base}.${field}`,\n message: 'only applies to a custom runtime — set \"runtime\": \"custom\" to build your own image'\n });\n }\n }\n checkRelativePath(raw.dockerfile, `${base}.dockerfile`, issues, { required: false });\n // `dockerfile` stays project-relative even when the context is\n // above the project: it names a file in THIS repository, and moving\n // the context should not rewrite it. `rebase build` re-expresses it\n // against the context when it prints the command.\n checkRelativePath(raw.context, `${base}.context`, issues, { required: false, mayEscape: true });\n if (raw.port !== undefined && (typeof raw.port !== \"number\" || !Number.isInteger(raw.port))) {\n issues.push({ path: `${base}.port`,\nmessage: \"must be an integer\" });\n }\n // Constructed, not asserted. Everything above pushes an issue for a\n // field it does not like and then leaves the field alone, so\n // `raw as unknown as RebaseAppConfig` handed the caller the *whole\n // parsed object* under a type describing only these fields — an\n // unknown key that `warnUnknownFields` merely warned about travelled\n // on as if it were part of the config, and a field that failed its\n // check above travelled on with the type saying it had passed.\n // Naming them is also what keeps this list and the interface in step:\n // a field added to `RebaseBackendAppConfig` and not validated here\n // now fails to compile instead of silently arriving unchecked.\n return {\n type: \"backend\",\n runtime: custom ? \"custom\" : \"managed\",\n config: raw.config as string | undefined,\n functions: raw.functions as string | undefined,\n crons: raw.crons as string | undefined,\n schema: raw.schema as string | undefined,\n usersCollection: raw.usersCollection as string | undefined,\n dockerfile: raw.dockerfile as string | undefined,\n context: raw.context as string | undefined,\n port: raw.port as number | undefined\n };\n }\n case \"static\": {\n checkRelativePath(raw.root, `${base}.root`, issues, { required: true });\n checkRelativePath(raw.output, `${base}.output`, issues, { required: true });\n if (raw.build !== undefined && typeof raw.build !== \"string\") {\n issues.push({ path: `${base}.build`,\nmessage: \"must be a string command\" });\n }\n if (raw.spa !== undefined && typeof raw.spa !== \"boolean\") {\n issues.push({ path: `${base}.spa`,\nmessage: \"must be a boolean\" });\n }\n const appPath = checkAppPath(raw.path, `${base}.path`, issues);\n checkCmsPath(raw.cms, appPath ?? \"/\", `${base}.cms`, issues);\n // See the backend branch: constructed for the same reasons.\n return {\n type: \"static\",\n root: raw.root as string,\n build: raw.build as string | undefined,\n output: raw.output as string,\n path: appPath,\n spa: raw.spa as boolean | undefined,\n cms: raw.cms as string | undefined\n };\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Validate a parsed manifest, collecting every problem.\n */\nexport function validateManifest(raw: unknown): {\n manifest?: RebaseProjectManifest;\n issues: ManifestValidationIssue[];\n} {\n const issues: ManifestValidationIssue[] = [];\n\n if (!isRecord(raw)) {\n return { issues: [{ path: \"\",\nmessage: `${MANIFEST_FILENAME} must contain a JSON object` }] };\n }\n\n if (typeof raw.rebase !== \"string\" || raw.rebase.trim() === \"\") {\n // `runtime` used to be this key. It now means who owns the backend\n // process, so a manifest still using it at the top level is naming the\n // wrong thing rather than merely missing a field.\n const message = typeof raw.runtime === \"string\"\n ? `is required, e.g. \"${CURRENT_RUNTIME_RANGE}\" — this is the top-level \"runtime\" key renamed, ` +\n 'because \"runtime\" now means \"managed\" or \"custom\" on the backend app'\n : `is required, e.g. \"${CURRENT_RUNTIME_RANGE}\"`;\n issues.push({ path: \"rebase\",\nmessage });\n }\n\n if (!isRecord(raw.apps)) {\n issues.push({ path: \"apps\",\nmessage: \"is required and must be an object\" });\n return { issues };\n }\n\n const apps: Record<string, RebaseAppConfig> = {};\n let backendCount = 0;\n\n for (const [name, value] of Object.entries(raw.apps)) {\n if (!/^[a-z0-9][a-z0-9-]*$/.test(name)) {\n issues.push({\n path: `apps.${name}`,\n message: \"name must be lowercase alphanumeric with dashes (it appears in URLs)\"\n });\n continue;\n }\n if (RESERVED_APP_NAMES.has(name)) {\n issues.push({ path: `apps.${name}`,\nmessage: \"name is reserved\" });\n continue;\n }\n\n const app = validateApp(name, value, issues);\n if (!app) continue;\n if (app.type === \"backend\") backendCount++;\n apps[name] = app;\n }\n\n // One backend per *project*. A repository declaring two would have two sets\n // of collections claiming the same database and the same API surface.\n if (backendCount > 1) {\n issues.push({\n path: \"apps\",\n message: \"a project may declare at most one backend app\"\n });\n }\n\n // Two apps at one path is not a preference conflict — the first one mounted\n // swallows the other's URLs, and the loser looks like it deployed fine.\n const byPath = new Map<string, string>();\n for (const [name, app] of Object.entries(apps)) {\n if (app.type !== \"static\") continue;\n const at = app.path ?? \"/\";\n const owner = byPath.get(at);\n if (owner) {\n issues.push({\n path: `apps.${name}.path`,\n message: `two apps cannot serve the same path — \"${owner}\" is already at \"${at}\"`\n });\n continue;\n }\n byPath.set(at, name);\n }\n\n // One CMS per project. Not a taste ruling: everything downstream — the\n // console's button, `rebase apps list`, the app row that records it — talks\n // about \"the project's CMS\", and two of them would make every one of those\n // pick arbitrarily. A repository that genuinely wants a second admin surface\n // has two apps and can say so by name.\n const withCms = Object.entries(apps).filter(\n ([, app]) => app.type === \"static\" && typeof app.cms === \"string\"\n );\n if (withCms.length > 1) {\n for (const [name] of withCms.slice(1)) {\n issues.push({\n path: `apps.${name}.cms`,\n message: `a project has one CMS — \"${withCms[0][0]}\" already declares one`\n });\n }\n }\n\n refuseStorageBlock(raw.storage, issues);\n\n // Carried rather than dropped. This key is the only repository-wide privacy\n // control the CLI honours, and a key that does not survive a parse does not\n // survive a rewrite either: `writeManifest` builds its output from what this\n // returned, so `rebase eject` deleted a committed `\"telemetry\": false` and\n // every developer who had ever opted in silently resumed sending events.\n //\n // Only a boolean is a value here — `true` is ignored elsewhere, loudly, but\n // it is still valid. A string `\"false\"` is the mistake that would leave\n // sharing on while looking like it was off, so it is named rather than\n // quietly discarded.\n let telemetry: boolean | undefined;\n if (raw.telemetry !== undefined) {\n if (typeof raw.telemetry === \"boolean\") {\n telemetry = raw.telemetry;\n } else {\n issues.push({\n path: \"telemetry\",\n message: \"must be a boolean — only `false` does anything, and it opts this repository out of usage sharing\"\n });\n }\n }\n\n if (issues.length > 0) return { issues };\n\n return {\n manifest: {\n $schema: typeof raw.$schema === \"string\" ? raw.$schema : undefined,\n rebase: raw.rebase as string,\n apps,\n ...(telemetry !== undefined ? { telemetry } : {})\n },\n issues\n };\n}\n\n/**\n * Refuse a hand-written `storage` block.\n *\n * Buckets are declared in config code now — `bucket(\"media\")` — and the graph\n * is generated from those declarations into `rebase.resources.json`. Two homes\n * for one concept is what this replaced, and the reason it had to go is that\n * the runtime *merged* them: a bucket declared in both had one engine kept and\n * the other silently discarded.\n *\n * Refused rather than ignored. A key that still parses and no longer does\n * anything is the same failure wearing a nicer hat — the author sees valid\n * JSON, the platform sees a bucket, and the runtime has neither.\n */\nfunction refuseStorageBlock(raw: unknown, issues: ManifestValidationIssue[]): undefined {\n if (raw === undefined) return undefined;\n issues.push({\n path: \"storage\",\n message:\n \"is no longer read. Declare each bucket in your config's resources.ts — \" +\n 'bucket(\"media\", { engine: \"s3\" }) — then run `rebase resources --write`, ' +\n \"which generates rebase.resources.json. Refused rather than ignored: this \" +\n \"block used to be merged with the code's declarations and silently win.\"\n });\n return undefined;\n}\n\n/**\n * Infer a manifest from a directory that does not have one.\n *\n * This mirrors exactly what the template scaffolds, which is what makes adopting\n * the manifest a no-op for existing projects: the synthesized result is what\n * they would have written by hand.\n *\n * The backend's `runtime` is inferred from whether the repository declares a\n * **Dockerfile** — the thing that actually builds an image — and from nothing\n * else. It used to be inferred from the presence of `backend/src/index.ts`,\n * which every scaffolded project had whether or not it wanted its own server, so\n * projects predating the manifest silently landed on the custom runtime and paid\n * for it.\n */\nexport function synthesizeManifest(projectRoot: string): RebaseProjectManifest {\n const exists = (relative: string): boolean => fs.existsSync(path.join(projectRoot, relative));\n const apps: Record<string, RebaseAppConfig> = {};\n\n const hasConfig = exists(DEFAULT_CONFIG_DIR);\n const hasBackend = exists(\"backend\");\n const dockerfile = [\"Dockerfile\", \"backend/Dockerfile\"].find(exists);\n\n if (hasBackend || hasConfig) {\n const backend: RebaseBackendAppConfig = dockerfile\n ? { type: \"backend\",\nruntime: \"custom\",\ndockerfile,\ncontext: \".\" }\n : { type: \"backend\",\nruntime: \"managed\" };\n if (exists(DEFAULT_FUNCTIONS_DIR)) backend.functions = DEFAULT_FUNCTIONS_DIR;\n if (exists(DEFAULT_CRONS_DIR)) backend.crons = DEFAULT_CRONS_DIR;\n apps.backend = backend;\n\n // Say it out loud. The file looks exactly like the server and is never\n // loaded, which used to be discovered only after a deploy answered 404\n // on every route defined in it.\n if (!dockerfile && exists(\"backend/src/index.ts\")) {\n console.warn(\n \"⚠ backend/src/index.ts exists but this project's backend is managed — it is\\n\" +\n \" never loaded. Delete it, or move it aside and run `rebase eject`, which\\n\" +\n \" writes an entrypoint of its own and owns the image. Eject does not adopt\\n\" +\n \" this file: it refuses to replace it unless you pass --force.\"\n );\n }\n }\n\n if (exists(\"frontend\")) {\n apps.web = {\n type: \"static\",\n root: \"frontend\",\n build: \"npm run build --workspace frontend\",\n output: \"frontend/dist\",\n path: \"/\",\n spa: true\n };\n }\n\n return { rebase: CURRENT_RUNTIME_RANGE,\napps };\n}\n\nexport function manifestPath(projectRoot: string): string {\n return path.join(projectRoot, MANIFEST_FILENAME);\n}\n\nexport function manifestExists(projectRoot: string): boolean {\n return fs.existsSync(manifestPath(projectRoot));\n}\n\n/**\n * Read the manifest, falling back to a synthesized one.\n *\n * A malformed manifest throws — unlike a missing one. Silently ignoring a file\n * the developer wrote, and building something else instead, is the worst\n * available behaviour.\n */\nexport function loadManifest(projectRoot: string): LoadedManifest {\n const filePath = manifestPath(projectRoot);\n\n if (!fs.existsSync(filePath)) {\n return { manifest: synthesizeManifest(projectRoot),\nsource: \"synthesized\" };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(filePath, \"utf8\"));\n } catch (err) {\n throw new ManifestError(\n `${MANIFEST_FILENAME} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n const { manifest, issues } = validateManifest(parsed);\n if (!manifest) {\n throw new ManifestError(`${MANIFEST_FILENAME} is invalid`, issues);\n }\n\n return { manifest,\nsource: \"file\",\nfilePath };\n}\n\n/** The keys `writeManifest` knows how to write. Everything else is carried through. */\nconst MODELLED_MANIFEST_KEYS = [\"$schema\", \"rebase\", \"apps\", \"storage\", \"telemetry\"];\n\n/**\n * What is on disk right now, or `{}` — this is a *rewrite*, so the file that is\n * about to be replaced is the only record of the keys the caller did not model.\n * Unparseable is treated as absent: `loadManifest` refuses malformed JSON long\n * before anything gets here, and a writer is not the place to fail on it.\n */\nfunction readManifestObject(filePath: string): Record<string, unknown> {\n try {\n const parsed: unknown = JSON.parse(fs.readFileSync(filePath, \"utf8\"));\n return isRecord(parsed) ? parsed : {};\n } catch {\n return {};\n }\n}\n\n/**\n * Write a manifest, with a trailing newline so it plays well with other tools.\n *\n * **Every key on disk survives.** This used to emit exactly `$schema`, `rebase`\n * and `apps`, so a rewrite deleted the rest of the file — and two commands with\n * no visible relationship to either key rewrite it: `rebase eject` and\n * `rebase apps init --force`. A repository that had committed\n * `\"telemetry\": false` lost its opt-out, and a multi-bucket project lost its\n * whole `storage` block, in a commit whose stated change was `runtime: custom`.\n *\n * So: the caller's manifest wins for what it models, the file supplies the rest.\n * `storage` and `telemetry` fall back to the file because the callers that\n * synthesize a manifest (`apps init --force`) cannot know them — they are\n * authored, not inferred — and unknown top-level keys are copied verbatim\n * rather than listed, since a hand-listed set loses the next key too.\n */\nexport function writeManifest(projectRoot: string, manifest: RebaseProjectManifest): string {\n const filePath = manifestPath(projectRoot);\n const existing = readManifestObject(filePath);\n\n const carried: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(existing)) {\n if (!MODELLED_MANIFEST_KEYS.includes(key)) carried[key] = value;\n }\n\n const schema = manifest.$schema\n ?? (typeof existing.$schema === \"string\" ? existing.$schema : undefined)\n ?? \"https://rebase.pro/schemas/rebase.json\";\n const telemetry = manifest.telemetry ?? (typeof existing.telemetry === \"boolean\" ? existing.telemetry : undefined);\n\n const ordered = {\n $schema: schema,\n rebase: manifest.rebase,\n apps: manifest.apps,\n ...(telemetry !== undefined ? { telemetry } : {}),\n ...carried\n };\n fs.writeFileSync(filePath, `${JSON.stringify(ordered, null, 4)}\\n`, \"utf8\");\n return filePath;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Queries\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Find the single backend app, if this repository declares one. */\nexport function findBackendApp(\n manifest: RebaseProjectManifest\n): { name: string; app: RebaseBackendAppConfig } | undefined {\n for (const [name, app] of Object.entries(manifest.apps)) {\n if (app.type === \"backend\") return { name,\napp: app as RebaseBackendAppConfig };\n }\n return undefined;\n}\n\n/**\n * Where this project mounts the Rebase CMS, if it says.\n *\n * The CMS is a component inside a developer's own app, so its address is a\n * client-side route: no build artifact, no running server and no control plane\n * can observe it. {@link RebaseStaticAppConfig.cms} is the only place that fact\n * is ever written down, and this is the one reader of it — so that \"the\n * project's CMS\" means the same thing to `rebase dev`, `rebase apps list`, the\n * bundle it builds and the console that shows it.\n *\n * Returns the *serving* app alongside the path, because a caller with a base URL\n * needs to know which app answers there — and because the path alone cannot say\n * whether the CMS is the whole of an app or one route of it.\n */\nexport function cmsMountOf(\n manifest: RebaseProjectManifest\n): { appName: string; app: RebaseStaticAppConfig; path: string } | undefined {\n for (const [name, app] of Object.entries(manifest.apps)) {\n if (app.type !== \"static\" || typeof app.cms !== \"string\") continue;\n return { appName: name, app: app as RebaseStaticAppConfig, path: app.cms };\n }\n return undefined;\n}\n\n/**\n * The app a deploy targets: the one named, or the obvious one.\n *\n * A repository declares apps; a project owns them. So \"which app\" is a question\n * a multi-repo setup asks routinely and a single-app repository should never\n * have to answer — hence the fallbacks, in the order that makes each of them\n * unambiguous:\n *\n * - A name, when one is given. Wrong names fail loudly, listing what is there;\n * guessing past a typo would deploy the wrong app to a live project.\n * - The backend, when this repository declares one. It is the app whose deploy\n * people mean when they do not say, and it is what every existing invocation\n * already did.\n * - The only app, when there is exactly one. This is what makes a static-only\n * repository — an admin panel, a marketing site — deploy with no argument.\n * - Otherwise a refusal that lists the choices. A repository with two static\n * apps and no backend has no obvious default, and picking one would publish\n * somebody's admin panel at their marketing domain.\n */\nexport function selectDeployApp(\n manifest: RebaseProjectManifest,\n requested?: string\n): { name: string; app: RebaseAppConfig } {\n const entries = Object.entries(manifest.apps).map(([name, app]) => ({ name,\napp }));\n\n if (requested) {\n const match = entries.find(entry => entry.name === requested);\n if (!match) {\n const known = entries.map(e => e.name).join(\", \") || \"none\";\n throw new ManifestError(\n `This repository declares no app named \"${requested}\". It declares: ${known}.`\n );\n }\n return match;\n }\n\n const backend = findBackendApp(manifest);\n if (backend) return { name: backend.name,\napp: backend.app };\n\n if (entries.length === 1) return entries[0];\n\n if (entries.length === 0) {\n throw new ManifestError(\n `${MANIFEST_FILENAME} declares no apps, so there is nothing to deploy.`\n );\n }\n\n throw new ManifestError(\n \"This repository declares several apps and no backend, so there is no obvious one to deploy. \" +\n `Name one: ${entries.map(e => e.name).join(\", \")}.`\n );\n}\n\n/** Apps that produce build output, in the order they should be built. */\nexport function buildableApps(\n manifest: RebaseProjectManifest\n): { name: string; app: RebaseAppConfig }[] {\n // Backend first: a static app's build may consume an SDK generated from the\n // backend's collections, so building it second is the order that works.\n const entries = Object.entries(manifest.apps).map(([name, app]) => ({ name,\napp }));\n const rank = (app: RebaseAppConfig): number => (app.type === \"backend\" ? 0 : 1);\n return entries.sort((a, b) => rank(a.app) - rank(b.app));\n}\n\n/**\n * Decide whether a project can run on the managed runtime, and say why not.\n *\n * \"Not eligible\" is never a dead end — it selects the custom-runtime path, which\n * still deploys. The reasons exist so the answer is actionable rather than a\n * verdict.\n */\nexport function assessManagedCompatibility(\n manifest: RebaseProjectManifest\n): ManagedCompatibility {\n const backend = findBackendApp(manifest);\n\n if (!backend) {\n return {\n eligible: false,\n reasons: [\n \"No backend app is declared in this repository. Only the repository that \" +\n \"declares the backend selects the runtime.\"\n ]\n };\n }\n\n // Declared, not deduced. A project on the custom runtime is there because\n // somebody wrote it down, which is the whole point of the field.\n if (backend.app.runtime === \"custom\") {\n return {\n eligible: false,\n reasons: [\n `App \"${backend.name}\" declares runtime: \"custom\", so it builds and runs its ` +\n \"own image. The managed runtime boots the platform image with your bundle; \" +\n \"the custom runtime deploys exactly the same way, from your Dockerfile.\"\n ]\n };\n }\n\n return { eligible: true,\nreasons: [] };\n}\n\n/**\n * Resolve a backend app's directories against the conventions it omits.\n *\n * `hasCollections` replaces the old `mode: \"cms\" | \"baas\"` field. Where the\n * collections come from was never an independent choice: either they are\n * declared in code and the bundle ships them, or they are not and the runtime\n * introspects the live database at boot. Declaring it separately only created\n * the contradictory state — code-first declared, no collections anywhere.\n *\n * `hasConfig` is deliberately a **separate** question. A headless project has no\n * `config/collections`, but it may still ship a config package — that is where\n * the `storageAuthorize` hook lives, and storage is not under row-level\n * security, so without one the server refuses to boot with storage enabled.\n * Collapsing the two would leave a headless project nowhere to put it.\n */\nexport function resolveBackendPaths(\n app: RebaseBackendAppConfig,\n projectRoot: string\n): {\n config: string;\n functions: string;\n crons: string;\n schema: string;\n usersCollection: string;\n /** Whether a config package exists — hooks, storage authorization. */\n hasConfig: boolean;\n /** Whether collections are declared in code, under `<config>/collections`. */\n hasCollections: boolean;\n} {\n const config = app.config ?? DEFAULT_CONFIG_DIR;\n return {\n config,\n functions: app.functions ?? DEFAULT_FUNCTIONS_DIR,\n crons: app.crons ?? DEFAULT_CRONS_DIR,\n schema: app.schema ?? DEFAULT_SCHEMA_FILE,\n usersCollection: app.usersCollection ?? \"collections/users\",\n hasConfig: fs.existsSync(path.join(projectRoot, config)),\n hasCollections: fs.existsSync(path.join(projectRoot, config, \"collections\"))\n };\n}\n","/**\n * Which edits under `config/collections` can put the *SQL* schema out of date.\n *\n * `rebase dev` watches that directory and, on any change, either tells the\n * developer to run `rebase schema generate` / `rebase db push` or runs them.\n * The watcher is recursive and knows nothing about what it is watching, so it\n * said that about every file under the directory — including a\n * `collections/firestore/exercises.ts`, whose documents live in Firestore and\n * for which there is no Drizzle schema to regenerate and no database to push\n * to. Advice that is wrong on every edit is advice a developer learns to\n * ignore, which is worse than none: the same box is the only warning for the\n * Postgres collection next to it, where it is real.\n *\n * Two independent reasons a change cannot affect the SQL schema, both checked\n * here:\n *\n * 1. **The loader would never read the file.** `loadCollectionsFromDirectory`\n * reads the top level of the collections directory only — no recursion, no\n * `index`, no tests, no declarations. A file it does not read cannot change\n * what it returns, and the watcher must not claim otherwise.\n * 2. **Every collection in it is served by another engine.** A Firestore or\n * MongoDB collection has no table, no migration and no policies.\n *\n * The engine check reads the source text rather than importing the module: the\n * CLI runs as plain Node and cannot evaluate a project's TypeScript, and a\n * watcher must answer in the time between two keystrokes. Anything it cannot\n * read confidently counts as SQL-affecting — a spurious warning is a nuisance,\n * a suppressed one hides real drift.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { DEFAULT_DATA_SOURCE_KEY, getDataSourceCapabilities } from \"@rebasepro/types\";\n\n/**\n * Would `loadCollectionsFromDirectory` load this file?\n *\n * Mirrors that loader's own `isCollectionFile` plus its flat (non-recursive)\n * scan. `relativePath` is relative to the collections directory, as `fs.watch`\n * reports it.\n */\nexport function isLoadedCollectionFile(relativePath: string): boolean {\n const normalized = relativePath.split(path.sep).join(\"/\");\n // A nested path is a subdirectory, which the loader does not descend into.\n if (normalized.includes(\"/\")) return false;\n\n const file = normalized;\n if (!file.endsWith(\".ts\") && !file.endsWith(\".js\")) return false;\n if (file.startsWith(\".\")) return false;\n if (file.includes(\".test.\")) return false;\n if (file.endsWith(\".d.ts\")) return false;\n // The directory's own module: defaults live there, not a collection.\n if (file === \"index.ts\" || file === \"index.js\") return false;\n return true;\n}\n\nconst ENGINE_LITERAL = /\\bengine\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/g;\nconst DATA_SOURCE_LITERAL = /\\bdataSource\\s*:\\s*[\"'`]([^\"'`]+)[\"'`]/g;\n\n/**\n * Drop comments, so a `// engine: \"firestore\"` in a docblock cannot silence a\n * warning about the Postgres collection the file actually declares.\n *\n * Deliberately naive — it does not understand strings, so a `//` inside one\n * (a URL in a default value) eats the rest of that line. That only ever removes\n * text, and removing an engine literal makes this file *more* likely to warn,\n * which is the side to be wrong on.\n */\nfunction stripComments(source: string): string {\n return source.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \" \").replace(/\\/\\/[^\\n]*/g, \" \");\n}\n\nfunction literals(source: string, pattern: RegExp): string[] {\n const found: string[] = [];\n for (const match of source.matchAll(pattern)) found.push(match[1]);\n return found;\n}\n\n/**\n * Does this collection source declare anything a SQL toolchain would own?\n *\n * The fallback order matches `resolveDataSource`: an explicit `engine` wins,\n * and a collection that only names a `dataSource` is resolved as if the key\n * were the engine — which is what that function does when no registry is\n * available, and the CLI has none. An engine nobody recognises counts as\n * relational, for the reason `isRelationalCollection` gives.\n *\n * A file declaring several collections is SQL-affecting if *any* of them is.\n */\nexport function declaresRelationalCollection(rawSource: string): boolean {\n const source = stripComments(rawSource);\n const engines = literals(source, ENGINE_LITERAL);\n const declared = engines.length > 0\n ? engines\n : literals(source, DATA_SOURCE_LITERAL).filter(key => key !== DEFAULT_DATA_SOURCE_KEY);\n\n if (declared.length === 0) return true;\n return declared.some(engine => getDataSourceCapabilities(engine).supportsRelations);\n}\n\n/**\n * Can this edit have changed the generated SQL schema?\n *\n * Answers `true` when it cannot tell — an unreadable file is a reason to warn,\n * not a reason to go quiet.\n */\nexport function affectsSqlSchema(collectionsDir: string, relativePath: string): boolean {\n if (!isLoadedCollectionFile(relativePath)) return false;\n try {\n return declaresRelationalCollection(\n fs.readFileSync(path.join(collectionsDir, relativePath), \"utf8\")\n );\n } catch {\n // Deleted between the event and the read, or unreadable. Both leave the\n // schema genuinely in question.\n return true;\n }\n}\n","/**\n * CLI command: rebase dev\n *\n * Starts the full development environment:\n * - Backend: tsx watch with auto-reload\n * - Frontend: vite dev server\n *\n * Both processes stream output with color-coded prefixes.\n *\n * When the backend uses port-retry (i.e. the configured port is busy and it\n * binds to the next free one), the CLI detects the actual port from stdout\n * and injects VITE_API_URL into the frontend so it connects automatically.\n *\n * Each project gets a deterministic default port derived from the project\n * root path, so multiple Rebase instances never collide.\n */\nimport chalk from \"chalk\";\nimport { DEFAULT_RESOURCE_KEY, parseEnvBoolean } from \"@rebasepro/types\";\nimport { execa, execaCommandSync, type ResultPromise } from \"execa\";\n\nimport {\n DEV_DATABASE_KIND_ENV,\n managedNotices,\n prepareDatabaseEnv,\n resolveComposeUrl,\n type PreparedDatabase\n} from \"../dev-db/prepare\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { cmsMountOf, findBackendApp, loadManifest, resolveBackendPaths } from \"../manifest\";\nimport {\n requireProjectRoot,\n findBackendDir,\n findFrontendDir,\n findEnvFile,\n readEnvFile,\n resolveTsx,\n validateTsxInstallation,\n getActiveBackendPlugin,\n resolvePluginCliScript,\n dependenciesNotInstalled\n} from \"../utils/project\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { affectsSqlSchema } from \"../utils/collection-drift\";\nimport { ensureDevDatabase, probeTcp } from \"../utils/dev-preflight\";\nimport { runDriverDbCommand, runDriverSchemaCommand } from \"./db\";\nimport dotenv from \"dotenv\";\nimport { recordEvent } from \"../telemetry\";\n\n/**\n * The line the watcher prints when it is about to run the entry again.\n *\n * `rebase dev` has no exit code to read: the watcher outlives the process it\n * started, so a backend that dies leaves it running and the CLI printing\n * \"Press Ctrl+C to stop all servers.\" under the stack trace, as if everything\n * were fine.\n *\n * What used to be here was `/Waiting for file changes before restarting/` —\n * **Node's** message, on the theory that `--watch=…` was passed through to\n * Node. It is not: the backend is spawned as `tsx watch …` (see `watchArgs`),\n * so tsx does the watching and Node's line is never printed. The marker\n * matched nothing at all — and the test guarding it ran `node --watch`\n * directly, so it kept proving that Node's wording was intact while the CLI\n * watched a stream that never contained it. That is precisely the silent death\n * the old comment warned about, reached by a different route.\n *\n * So this is tsx's, captured from tsx 4.23.1:\n *\n * 6:26:11 AM [tsx] change in ./src/index.ts Rerunning...\n * 6:26:11 AM [tsx] change in ./src/index.ts Restarting...\n *\n * \"Rerunning\" when the previous run had already exited, \"Restarting\" when it\n * was still up and had to be killed first. Both mean the same thing here: the\n * backend that was announced is gone, and whether another one arrives is an\n * open question again — so the readiness deadline is re-armed.\n *\n * Exported so `dev-crash-marker.test.ts` can hold the running tsx to it.\n */\nexport const WATCHER_RESTART_MARKER = /\\[tsx\\][^\\n]*\\b(?:Rerunning|Restarting)\\b/i;\n\n/**\n * How often to ask whether the announced backend is still listening.\n *\n * The watcher says nothing when its child is killed outright, so a poll is the\n * only signal there is. Five seconds is chosen against the thing it must not\n * do — report a healthy server as dead — rather than against detection speed:\n * two consecutive misses are needed, so it takes ten seconds of a genuinely\n * closed port to say anything.\n */\nconst LIVENESS_INTERVAL_MS = 5_000;\n\n/**\n * Strip ANSI codes before matching.\n *\n * At module scope so `portMovedNotice` below can use the same one the stream\n * handlers do: a second copy of this regex is a second thing to keep in step.\n */\n// eslint-disable-next-line no-control-regex\nconst stripAnsi = (str: string) => str.replace(/[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, \"\");\n\n/**\n * The corrected banner line, when the backend says it moved port.\n *\n * `↳ PORT = 3014` is printed before the server binds — the backend's\n * environment has to be fixed before it spawns — so when the port turns out to\n * be taken and the server moves, the banner two inches up is simply wrong. The\n * true number then appears in a `[backend]` line a hundred lines of DDL later,\n * which nobody scrolls back through, and the banner is where a reader looks for\n * the port.\n *\n * A correction rather than a rewrite: the terminal is a transcript, and a line\n * that changes after the fact is a line nobody can trust. So the old number is\n * named too.\n *\n * Exported for its test.\n */\nexport function portMovedNotice(line: string): { from: string; to: string } | null {\n const moved = stripAnsi(line).match(/Port (\\d+) is in use — trying (\\d+)/);\n\n return moved ? { from: moved[1], to: moved[2] } : null;\n}\n\n/**\n * Quote a path for the shell `execa` runs the backend through.\n *\n * The dev runtime's path is absolute and therefore contains whatever the\n * developer's directories are called. Double quotes do not neutralize `$`,\n * backticks or backslashes in a POSIX shell, so a checkout under a directory\n * named `$(...)` would execute it. Single quotes disable all expansion; on\n * Windows, `cmd.exe` performs no such expansion and wants double quotes.\n */\nfunction quoteForShell(value: string): string {\n if (process.platform === \"win32\") return `\"${value.replace(/\"/g, \"\\\\\\\"\")}\"`;\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * Locate the dev runtime shim shipped with the CLI.\n *\n * Published under `runtime/` in the package rather than compiled into `dist/`,\n * because tsx executes it as a file and it must exist on disk at a stable path.\n */\nfunction resolveDevRuntimeEntry(): string {\n const here = path.dirname(fileURLToPath(import.meta.url));\n // Walk up from wherever this module ended up (src/ in development, dist/ in\n // a published install) until the package root with `runtime/` is found.\n let dir = here;\n for (let i = 0; i < 5; i++) {\n const candidate = path.join(dir, \"runtime\", \"dev-server.mjs\");\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n throw new Error(\n \"Could not find the Rebase dev runtime (runtime/dev-server.mjs). \" +\n \"Reinstall @rebasepro/cli, or add a backend/src/index.ts to run your own entrypoint.\"\n );\n}\n\n/**\n * Tell the dev runtime where this project keeps its parts.\n *\n * Read from `rebase.json` when there is one, so a project that moved its config\n * directory is honoured; otherwise the conventional layout.\n */\nfunction devRuntimeEnv(projectRoot: string): Record<string, string> {\n const result: Record<string, string> = {\n REBASE_DEV_PROJECT_ROOT: projectRoot,\n REBASE_DEV_CONFIG: \"config\",\n REBASE_DEV_FUNCTIONS: \"backend/functions\",\n REBASE_DEV_CRONS: \"backend/crons\",\n REBASE_DEV_SCHEMA: \"backend/src/schema.generated.ts\"\n };\n\n try {\n const loaded = loadManifest(projectRoot);\n const backend = findBackendApp(loaded.manifest);\n if (backend) {\n const paths = resolveBackendPaths(backend.app, projectRoot);\n result.REBASE_DEV_CONFIG = paths.config;\n result.REBASE_DEV_FUNCTIONS = paths.functions;\n result.REBASE_DEV_CRONS = paths.crons;\n result.REBASE_DEV_SCHEMA = paths.schema;\n result.REBASE_DEV_APP = backend.name;\n }\n } catch {\n // An invalid manifest is reported by `rebase build`; dev falls back to\n // the conventional layout rather than refusing to start.\n }\n\n // Nothing here says whether collections are declared or introspected, and\n // nothing should: `createSourceBundle` drops a config directory that does\n // not exist, and the server derives the answer from that. A REBASE_DEV_MODE\n // env var said it a second time, and a second place to say it is a second\n // place for it to disagree.\n return result;\n}\n\n/**\n * Directories `tsx watch` must be told about explicitly, as absolute paths.\n *\n * tsx restarts on a change to anything the entrypoint *imports*. Functions and\n * crons are not imported: the runtime scans their directories at boot. So\n * adding `backend/functions/new.ts` while `rebase dev` ran did nothing —\n * `GET /api/functions/new` stayed 404, and a new cron never registered — until\n * somebody restarted by hand. The same is true of `config/`, which is read as\n * data.\n *\n * `--include` is tsx's own answer to this, it takes a directory rather than a\n * glob, and it tolerates a directory that does not exist yet: a `crons/`\n * created mid-session starts being watched when it appears.\n *\n * @param projectRoot Absolute path the relative entries are resolved against.\n * @param paths The `REBASE_DEV_*` map from {@link devRuntimeEnv}.\n * @param includeConfig Whether `config/` is watched here. It is only when\n * auto-generation is off; with `--generate` a dedicated\n * watcher already regenerates the schema and SDK, and tsx\n * restarts on the files that produces.\n */\nexport function devWatchIncludes(\n projectRoot: string,\n paths: { REBASE_DEV_FUNCTIONS?: string; REBASE_DEV_CRONS?: string },\n includeConfig: boolean\n): string[] {\n const dirs = [paths.REBASE_DEV_FUNCTIONS, paths.REBASE_DEV_CRONS]\n .filter((entry): entry is string => Boolean(entry))\n .map(entry => path.resolve(projectRoot, entry));\n if (includeConfig) dirs.push(path.join(projectRoot, \"config\"));\n return dirs;\n}\n\n/**\n * The databases the project declares beyond the default, by key.\n *\n * Read from the graph, so `database(\"analytics\")` in `config/resources.ts`\n * is enough for `rebase dev` to serve a second database — the declaration is\n * the request. A config that does not evaluate is the backend's problem to\n * report, in the terms it already uses; here it means \"no additional\n * databases\", not a refusal to start.\n */\nasync function declaredAdditionalDatabases(projectRoot: string): Promise<string[]> {\n try {\n const loaded = loadManifest(projectRoot);\n const backend = findBackendApp(loaded.manifest);\n if (!backend) return [];\n const { deriveResourceGraph, deriveOptionsFor } = await import(\"../resources/derive\");\n const { graph } = await deriveResourceGraph({ ...deriveOptionsFor(projectRoot, backend.app), cronsDir: undefined, functionsDir: undefined });\n return graph.resources\n .filter(r => r.kind === \"database\" && r.transport === \"server\" && r.key !== DEFAULT_RESOURCE_KEY)\n .map(r => r.key);\n } catch {\n return [];\n }\n}\n\n/** Well-known filename the backend writes its actual port to. */\nexport const DEV_PORT_FILENAME = \".rebase-dev-port\";\n\n/**\n * The `PORT` the scaffold's own `.env.example` ships.\n *\n * `rebase init` copies that file into `.env` verbatim, so every new project has\n * this value whether or not anyone meant it. `init.test.ts` asserts the\n * template still says this number, so the two cannot drift apart in silence.\n */\nexport const SCAFFOLD_DEFAULT_PORT = 3001;\n\n/**\n * Compute a deterministic port from the project root path.\n * Range: 3001–3999 (avoids privileged ports and common services).\n * Two different project directories will almost always get different ports.\n */\nexport function getProjectPort(projectRoot: string): number {\n let hash = 0;\n for (let i = 0; i < projectRoot.length; i++) {\n hash = ((hash << 5) - hash + projectRoot.charCodeAt(i)) | 0;\n }\n return 3001 + (Math.abs(hash) % 999);\n}\n\n/**\n * Which rung of the ladder below decided the port.\n *\n * Reported because the ladder is invisible from the outside and the two middle\n * rungs look identical from where the developer stands: `PORT` in the shell\n * wins, `PORT` in `.env` does not — `rebase dev` never reads the file for it —\n * and a saved affinity port looks exactly like a derived one. A developer who\n * sets `PORT=3001` in `.env`, sees 3774, and has nothing to read but the number\n * concludes the setting is broken rather than out of scope.\n */\nexport type StartPortSource = \"--port\" | \"PORT\" | \"affinity\" | \"derived\";\n\n/** What the banner says after the port, naming the rung. */\nexport const START_PORT_SOURCE_LABELS: Record<StartPortSource, string> = {\n \"--port\": \"from --port\",\n PORT: \"from PORT\",\n affinity: \"kept from the last run\",\n derived: \"derived\"\n};\n\n/**\n * A TCP port, or `undefined` for anything that is not one.\n *\n * One predicate for both sources below. The port file was already checked for\n * range, and `PORT` — the source a human or a platform actually sets — was not,\n * so `PORT=oops` reached `parseInt` and was returned as `NaN`: the dev server\n * then bound to whatever the OS handed out and the CLI printed a URL for a port\n * nothing was listening on.\n */\nfunction parsePort(raw: string | undefined): number | undefined {\n if (raw === undefined) return undefined;\n const port = Number(raw.trim());\n if (!Number.isInteger(port) || port <= 0 || port >= 65536) return undefined;\n return port;\n}\n\n/**\n * The port this project's backend starts on, and the rung that decided it:\n * 1. `--port` (highest priority)\n * 2. `PORT` **in the shell environment** — a `PORT` in `.env` is not read here\n * 3. the port a previous run saved in `.rebase-dev-port` (affinity)\n * 4. a port derived from the project path, unique per project\n */\nexport function resolveStartPort(\n projectRoot: string,\n explicitPort?: number\n): { port: number; source: StartPortSource } {\n // 1. Explicit flag\n if (explicitPort) return { port: explicitPort, source: \"--port\" };\n\n // 2. PORT env var. `process.env` only: the CLI does not load `.env` before\n // resolving the port, so a `PORT=` line in that file never reaches here —\n // it is handed to the child, which this then overrides. Both facts are in\n // `getting-started/configuration.md` and in `rebase dev --help`.\n if (process.env.PORT) {\n const fromEnv = parsePort(process.env.PORT);\n if (fromEnv !== undefined) return { port: fromEnv, source: \"PORT\" };\n // Set deliberately and unusable: falling through silently would start a\n // server on a port nobody asked for and say nothing about why.\n console.warn(chalk.yellow(\n ` ⚠ Ignoring PORT=\"${process.env.PORT}\" — not a port between 1 and 65535.`\n ));\n }\n\n // 3. Port affinity — check if we wrote a port file from a previous run\n try {\n const portFile = path.join(projectRoot, DEV_PORT_FILENAME);\n if (fs.existsSync(portFile)) {\n const saved = parsePort(fs.readFileSync(portFile, \"utf-8\"));\n if (saved !== undefined) return { port: saved, source: \"affinity\" };\n }\n } catch { /* ignore */ }\n\n // 4. Deterministic hash\n return { port: getProjectPort(projectRoot), source: \"derived\" };\n}\n\n/**\n * Where a connection string actually points, as `host:port/name`.\n *\n * The banner used to name the database only by *provenance* — \"your database\n * (DATABASE_URL in the environment)\" — and the boot that follows it writes\n * thirty DDL statements. Which host, which port, which database name appeared\n * nowhere on the success path; only a *failed* connection printed an address.\n * So the one question after pointing a project at staging by accident — did it\n * touch staging? — had no answer in a hundred and twenty lines of output.\n *\n * The password is never in it. `new URL` keeps the credentials in their own\n * fields, so building the string out of `hostname`, `port` and `pathname`\n * cannot carry them by accident, which string surgery on a DSN reliably does.\n *\n * A DSN with no host is a UNIX socket (`postgresql:///app?host=/tmp`), and the\n * socket directory is the address there.\n *\n * Returns null for anything that is not a parseable URL rather than guessing:\n * a banner line that is wrong about the database is worse than one that is\n * missing.\n *\n * Exported for its test.\n */\nexport function databaseEndpoint(url: string | null | undefined): string | null {\n if (!url) return null;\n\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return null;\n }\n\n const host = parsed.hostname || parsed.searchParams.get(\"host\");\n if (!host) return null;\n\n const name = parsed.pathname.replace(/^\\//, \"\");\n\n return `${host}${parsed.port ? `:${parsed.port}` : \"\"}${name ? `/${name}` : \"\"}`;\n}\n\n/**\n * The `↳ Database =` line: which database, why it was chosen, and where it is.\n *\n * Provenance alone was what this line said, and the boot underneath it applies\n * schema. \"your database (DATABASE_URL in the environment)\" and \"Applied 30\n * additive schema change(s) before boot\" together still do not answer the\n * question somebody asks after pointing a project at staging by accident.\n *\n * The managed database gets its address too — the daemon's port is what a\n * `psql` in another terminal needs, and it is nowhere else in the banner.\n *\n * Exported for its test.\n */\nexport function databaseBannerValue(prepared: PreparedDatabase | null): string {\n if (!prepared) return \"none (--no-db) — the backend needs DATABASE_URL\";\n\n const endpoint = databaseEndpoint(\n prepared.database.kind === \"managed\" ? prepared.env.DATABASE_URL : prepared.database.url\n );\n\n return endpoint ? `${prepared.description} · ${endpoint}` : prepared.description;\n}\n\n/**\n * Refuse a port the developer named and something else already answers on.\n *\n * `--port` used to be advice, not an instruction: `resolveStartPort` returned\n * the number, the banner printed it, and the server then walked past the\n * collision to 3141, 3142. Because dev ports are derived per project, the\n * number typed into `--port` is very often *another Rebase backend*, so the\n * curl that followed answered 200 from the wrong project rather than refusing\n * — the one failure mode a port collision is supposed to rule out.\n *\n * Asked here as well as in the server (`listenWithPortRetry`'s `explicit`\n * option, which `REBASE_DEV_PORT_EXPLICIT` below turns on) so the refusal\n * arrives before a database is started and a schema is pushed, rather than a\n * minute later underneath them.\n *\n * Both loopback addresses, because a listener on `::1` alone is the same\n * collision and costs one more connect to rule out. Returns the sentence to\n * print, or `null` when there is nothing to refuse.\n *\n * Exported for its test.\n */\nexport async function pinnedPortRefusal(port: number, pinned: boolean): Promise<string | null> {\n if (!pinned) return null;\n const taken = await Promise.all([probeTcp(\"127.0.0.1\", port), probeTcp(\"::1\", port)]);\n if (!taken.some(Boolean)) return null;\n return `Port ${port} is in use, and you asked for it with --port. ` +\n `Stop whatever is listening on ${port}, or pass a different port. ` +\n \"(Without --port, dev derives a port for this project and walks past a collision.)\";\n}\n\n/**\n * The frontend port for this project, derived the same way the backend's is.\n *\n * `rebase dev` used to leave this entirely to Vite, which takes 5173 and, when\n * that is busy, silently walks to 5174, 5175 and onward. The backend was then\n * started with whatever `FRONTEND_URL` the scaffold's `.env` happened to say —\n * `http://localhost:5173` — so the welcome email linked a port the app was not\n * on. Deriving it here means the value handed to the backend describes the\n * server we are about to start rather than a default nobody checked.\n *\n * Range 5173–5372, so the familiar port is still the common case for a single\n * project and two projects rarely collide.\n *\n * Note this is passed to Vite WITHOUT `--strictPort` unless the developer\n * pinned it explicitly. Vite keeps its fallback, so a busy port still starts —\n * it just starts somewhere the email link does not name, which is exactly\n * today's behaviour and no worse. Pinning REBASE_FRONTEND_PORT makes both\n * exact.\n */\nexport function getProjectFrontendPort(projectRoot: string): number {\n let hash = 0;\n for (let i = 0; i < projectRoot.length; i++) {\n hash = ((hash << 5) - hash + projectRoot.charCodeAt(i)) | 0;\n }\n return 5173 + (Math.abs(hash) % 200);\n}\n\n/**\n * The flags `rebase dev` takes.\n *\n * Exported so `dev.test.ts` can assert that every short alias the help\n * advertises is declared here: the help said `--port, -p` while the spec has\n * only ever declared `-P`, so `rebase dev -p 4000` typed straight off the help\n * page passed `4000` as a positional and started on the default port.\n */\nexport const DEV_FLAGS = {\n \"--backend-only\": Boolean,\n \"--frontend-only\": Boolean,\n \"--port\": Number,\n \"--generate\": Boolean,\n /**\n * Point this run at a database of your own, ahead of everything else.\n *\n * The managed development database fills a vacuum; it never redirects a\n * project that has said which Postgres it wants. This flag is the loudest\n * way to say it, and outranks DATABASE_URL in the environment and in .env.\n */\n \"--database-url\": String,\n /** Use Postgres in Docker rather than the managed database. */\n \"--docker\": Boolean,\n \"-b\": \"--backend-only\",\n \"-f\": \"--frontend-only\",\n // `-P` for port, not `-p`. `-p` is `--project` across all ~20 cloud\n // commands — by a wide margin the most-typed short flag in the CLI — and it\n // also means `--password` in `auth`. One letter with three meanings is a\n // flag you have to look up every time, which is the opposite of what a short\n // flag is for. `--project` keeps `-p`; port moves here.\n \"-P\": \"--port\",\n \"-g\": \"--generate\",\n // Opts out of the database preflight in `ensureDevDatabase`. Named for what\n // it withholds rather than for the mechanism: a reader reaching for this\n // wants \"leave my database alone\", not \"skip step one of three\".\n \"--no-db\": Boolean\n} as const;\n\n/**\n * Read one variable out of the project's env file.\n *\n * `dotenv.parse` rather than `dotenv.config`, because this must not put the\n * project's secrets into the CLI process's own environment — the child\n * processes are given the env file by path and read it themselves.\n */\nfunction readEnvVar(projectRoot: string, name: string): string | undefined {\n const envFile = findEnvFile(projectRoot);\n if (!envFile || !fs.existsSync(envFile)) return undefined;\n try {\n return dotenv.parse(fs.readFileSync(envFile))[name] || undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether this project declares collections at all.\n *\n * A project with none has no schema to generate or push — the headless BaaS\n * mode serves whatever the database already has.\n */\nfunction projectHasCollections(projectRoot: string): boolean {\n const collectionsDir = path.join(projectRoot, \"config\", \"collections\");\n return fs.existsSync(collectionsDir)\n && fs.readdirSync(collectionsDir).some(name => /\\.(ts|js|mts|mjs)$/.test(name) && !name.startsWith(\"index.\"));\n}\n\n/**\n * Make the generated Drizzle schema match the collections before anything reads it.\n *\n * ## The bug this exists for\n *\n * The scaffold ships `backend/src/schema.generated.ts` as a stub — `export const\n * tables = {}` — and something has to replace it. On the Docker path\n * `rebase db push` did, as step one of three. On the **managed PGlite path\n * nothing did**, and that is the path a new project takes, because `rebase init`\n * deliberately leaves `DATABASE_URL` commented out.\n *\n * The result was the worst shape a first run can have: the database was fine.\n * Boot created all 30 tables through the additive ensure, `/health` answered\n * 200, auth worked, the admin panel loaded — and every single\n * `GET /api/data/*` returned a 500, `Table not found for collection 'posts'`,\n * because the driver looked the table up in the generated file rather than in\n * the database. A stranger following the README had no way to guess that\n * `pnpm run schema:generate` was the missing step, and the README told them the\n * schema was pushed for them.\n *\n * That failure is fixed at the root — the driver builds its tables from\n * `information_schema` now, so a stub `schema.generated.ts` cannot empty the\n * API. This still runs, because the file is a real artifact for everything\n * around the server: `db push` diffs it, Atlas plans from it, `eject` writes it\n * out, and application code imports it.\n *\n * ## Why it runs unconditionally\n *\n * Generation reads collection files and writes one file. It needs no database,\n * it is idempotent, and it takes about two seconds. Making it a precondition of\n * starting the dev server — rather than a side effect of one database path —\n * is what makes \"the generated schema matches the collections\" true by\n * construction instead of true by remembering. The same staleness bites a\n * project whose database was already running, where the push never ran either.\n *\n * Failure is not fatal: the server still starts, and it will report the real\n * problem itself. A dev server that refuses to boot because codegen failed is\n * worse than one that boots and says so.\n */\nasync function ensureGeneratedSchema(projectRoot: string): Promise<void> {\n if (!projectHasCollections(projectRoot)) return;\n try {\n await runDriverSchemaCommand([\"node\", \"rebase\", \"schema\", \"generate\"], { quiet: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.log(` ${chalk.yellow(\"⚠\")} ${chalk.gray(`Could not regenerate the database schema: ${message}`)}`);\n console.log(` ${chalk.gray(`Run ${chalk.cyan(\"rebase schema generate\")} to see why. Collection reads will fail until it succeeds.`)}`);\n }\n}\n\n/**\n * One variable's value out of `.env` text, or undefined when it has none.\n *\n * The obvious `\\s*(.+?)\\s*$` does not do this, because `\\s` matches a newline\n * and `$` under /m matches at every line end: on `VITE_API_URL=` followed by\n * `# VITE_GOOGLE_CLIENT_ID=`, the leading `\\s*` ate the line break and the\n * capture returned the *next* line. The scaffold ships `VITE_API_URL=` empty,\n * so every first `rebase dev` read a comment as its value, decided it differed\n * from the derived URL, and warned that a variable the developer had not set\n * was being ignored.\n *\n * Horizontal whitespace only, so a value stops at its own line.\n */\nexport function readEnvValue(envText: string, key: string): string | undefined {\n const match = envText.match(\n new RegExp(`^[^\\\\S\\\\r\\\\n]*${key}[^\\\\S\\\\r\\\\n]*=[^\\\\S\\\\r\\\\n]*(.*?)[^\\\\S\\\\r\\\\n]*$`, \"m\")\n );\n if (!match) return undefined;\n\n const value = match[1].replace(/^[\"']|[\"']$/g, \"\");\n\n return value.length > 0 ? value : undefined;\n}\n\n/**\n * The argv the first-boot schema push runs with.\n *\n * The database is named on the command line rather than left to be re-resolved.\n * `runDriverDbCommand` runs the resolver again for whatever argv it is handed,\n * and the argv it used to be handed (`[\"node\",\"rebase\",\"db\",\"push\"]`) carried\n * nothing at all — so on the `--docker` path it read a `.env` whose\n * `DATABASE_URL` is commented out, concluded \"managed PGlite\", and refused the\n * push for a database that was not the one the preflight had just started.\n *\n * Exported for its test: the missing pair of arguments is the whole defect, and\n * it is invisible in any assertion about the push's *outcome*.\n */\nexport function schemaPushArgv(databaseUrl: string | undefined): string[] {\n const argv = [\"node\", \"rebase\", \"db\", \"push\"];\n if (databaseUrl) argv.push(\"--database-url\", databaseUrl);\n\n return argv;\n}\n\n/**\n * The database half of `rebase dev` starting up.\n *\n * Separated from `ensureDevDatabase` so that everything needing a project on\n * disk lives here and the decision logic stays testable without one.\n */\nasync function runDatabasePreflight(options: {\n projectRoot: string;\n disabled: boolean;\n /**\n * The DSN the preflight decides from, when the caller resolved one that is\n * not in `.env`. `--docker` is exactly that case: the compose URL is\n * derived, so reading `.env` here saw nothing and the container the flag\n * asked for was never started.\n */\n databaseUrl?: string;\n}): Promise<void> {\n const { projectRoot, disabled } = options;\n\n const hasCollections = projectHasCollections(projectRoot);\n\n // The one DSN this preflight is about. `ensureDevDatabase` decides from it,\n // and the push has to run against the same one — re-resolving inside the\n // push saw a `.env` with DATABASE_URL commented out, chose the managed\n // PGlite, and refused, on the first `rebase dev --docker` of every scaffold.\n const databaseUrl = options.databaseUrl ?? readEnvVar(projectRoot, \"DATABASE_URL\");\n\n const outcome = await ensureDevDatabase({\n projectRoot,\n databaseUrl,\n disabled,\n hasCollections,\n pushSchema: async () => {\n // The same driver entry point `rebase db push` uses, called with the\n // argv layout every command in this CLI receives — the full process\n // argument vector, which the callee slices. `--database-url` names\n // the database the preflight just started, so the push cannot\n // resolve its way to a different one. The throwing variant: a failed\n // push must not take the dev server down with it.\n // Quiet: the database was resolved and announced in the banner above.\n await runDriverDbCommand(schemaPushArgv(databaseUrl), { quiet: true });\n }\n });\n\n if (outcome.action === \"started\") console.log(\"\");\n}\n\nexport async function devCommand(rawArgs: string[]): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printDevHelp();\n return;\n }\n\n const { flags: args } = parseCommandArgs({\n spec: DEV_FLAGS,\n rawArgs,\n commandWords: 1,\n command: \"dev\",\n maxPositionals: 0\n });\n\n const projectRoot = requireProjectRoot();\n\n // Fire-and-forget, and a no-op unless the developer opted in. Deliberately\n // not awaited: `rebase dev` starting is the thing the user is waiting for,\n // and a slow collector must never be in front of it.\n void recordEvent(\"cli.dev\", {\n backend_only: Boolean(args[\"--backend-only\"]),\n frontend_only: Boolean(args[\"--frontend-only\"]),\n generate: Boolean(args[\"--generate\"])\n }, { projectRoot });\n const backendDir = findBackendDir(projectRoot);\n const frontendDir = findFrontendDir(projectRoot);\n const backendOnly = args[\"--backend-only\"] || false;\n const frontendOnly = args[\"--frontend-only\"] || false;\n /**\n * Start no database at all — not the compose container, and not the managed\n * one either. Read once, here, because both halves of `dev` have to agree:\n * gating only the preflight left the managed PGlite starting anyway, which\n * is the one database a scaffolded project would otherwise get.\n */\n const noDb = Boolean(args[\"--no-db\"]) || parseEnvBoolean(process.env.REBASE_DEV_NO_DB) === true;\n const shouldGenerate = args[\"--generate\"]\n || parseEnvBoolean(process.env.REBASE_AUTO_GENERATE) === true\n || parseEnvBoolean(process.env.REBASE_GENERATE) === true;\n\n // Resolve the ports ONCE, before starting anything. Both, because the\n // backend is told where the frontend will be and cannot be told later: its\n // environment is fixed when it spawns.\n const { port: startPort, source: startPortSource } = resolveStartPort(projectRoot, args[\"--port\"]);\n // Named, not derived — see `pinnedPortRefusal`. Only the flag counts: the\n // .env's `PORT` is deliberately overridden by this command, and the shell's\n // is what a test harness sets when it wants a port that may still move.\n // `startPortSource === \"--port\"` says the same thing; kept as its own read\n // because this one is about the *flag*, not about which rung answered.\n const portIsPinned = args[\"--port\"] !== undefined;\n const pinnedFrontendPort = process.env.REBASE_FRONTEND_PORT;\n if (pinnedFrontendPort && !/^\\d+$/.test(pinnedFrontendPort)) {\n throw new Error(`REBASE_FRONTEND_PORT must be a number, got ${JSON.stringify(pinnedFrontendPort)}.`);\n }\n const frontendPort = pinnedFrontendPort\n ? Number(pinnedFrontendPort)\n : getProjectFrontendPort(projectRoot);\n\n // Before the banner, and before anything is started: a pinned port that is\n // already answering is a refusal, not a warning, and the developer should\n // get it in the first second rather than after a database and a schema push.\n if (!frontendOnly) {\n const refusal = await pinnedPortRefusal(startPort, portIsPinned);\n if (refusal) {\n console.error(chalk.red(` ✗ ${refusal}`));\n process.exit(1);\n }\n }\n\n console.log(\"\");\n console.log(chalk.bold(\" 🚀 Rebase Dev Server\"));\n console.log(\"\");\n\n // Start the development database and give it a schema, when this project\n // has one that is plainly local and plainly not running. Everything about\n // when it declines is in `ensureDevDatabase`; the frontend-only case is\n // decided here because there is no backend to need a database at all.\n if (!frontendOnly) {\n // Before the database, because it needs no database and because the\n // push below regenerates anyway on the one path that reaches it.\n await ensureGeneratedSchema(projectRoot);\n await runDatabasePreflight({\n projectRoot,\n disabled: noDb,\n // `--docker` names a container, not a connection string, and the\n // preflight is what starts it. Derived from the compose file so the\n // two halves agree on which database \"the docker one\" is.\n databaseUrl: args[\"--docker\"]\n ? resolveComposeUrl(projectRoot, readEnvFile(projectRoot)) ?? undefined\n : undefined\n });\n }\n\n const children: ResultPromise[] = [];\n\n /**\n * Whether this project has an admin panel to serve at all.\n *\n * A headless project declares one app, of type \"backend\", so there is no\n * `frontend/` and never will be. Warning that a directory is \"missing\" for\n * a shape that has no such directory reads as a broken scaffold on the\n * very first run of the very command the headless quickstart names.\n */\n const staticShape = (() => {\n try {\n const { manifest } = loadManifest(projectRoot);\n return {\n declaresStaticApp: Object.values(manifest.apps ?? {}).some(app => app.type === \"static\"),\n // Where the banner's \"Admin\" link actually reaches the CMS. For\n // the scaffolded project that is the frontend's root and the two\n // are the same URL; for a project that mounts the CMS as one\n // route of a larger app they are not, and the banner was sending\n // the reader to the product's home page.\n cmsPath: cmsMountOf(manifest)?.path\n };\n } catch {\n // A manifest that will not load is a different problem, reported\n // elsewhere. Fall back to the directory, which is what this check\n // used to be.\n return { declaresStaticApp: Boolean(frontendDir), cmsPath: undefined };\n }\n })();\n const declaresStaticApp = staticShape.declaresStaticApp;\n\n // --- State for printing the banner ---\n let frontendUrl = \"\";\n let backendUrl = \"\";\n let debounceSummary: NodeJS.Timeout | null = null;\n let bannerPrinted = false;\n\n /** Actual backend port, resolved once the server prints its URL. */\n let resolvedBackendPort: number | null = null;\n\n /**\n * The connection string of the database this run started, when it started\n * one. Filled in below; read by the headless banner, which is the only\n * place a headless project could learn it — there is no admin panel to\n * open, and `.env` deliberately does not name the managed database.\n */\n let managedConnectionString: string | null = null;\n\n /**\n * Where the backend mounted Swagger, if it mounted it at all.\n *\n * Read from the backend's own log rather than assumed: a headless project\n * with no tables yet serves no data API and no Swagger, and the banner must\n * not name a URL that answers 404.\n */\n let swaggerPath: string | null = null;\n\n function printSummary() {\n if (!backendUrl) return;\n // A headless project has no frontend URL to wait for, and waiting for\n // one meant it got no banner at all: the first run of `rebase dev`\n // ended in log lines, with the API URL, the Swagger path and the\n // database it had just created all unstated.\n if (declaresStaticApp && !frontendUrl) return;\n if (debounceSummary) clearTimeout(debounceSummary);\n debounceSummary = setTimeout(() => {\n if (bannerPrinted) return;\n\n const api = `http://localhost:${resolvedBackendPort}`;\n /** `[label, value]` per line; an empty pair is a blank line. */\n const lines: Array<[string, string]> = declaresStaticApp\n ? [\n [\"\", \"\"],\n [\"✦ Rebase Admin App is ready!\", \"\"],\n [\"➜ Admin: \", stripAnsi(frontendUrl)],\n // Both, because both are needed and only one was printed.\n // The admin URL is where you log in; the API URL is what\n // every SDK client, curl and Swagger link needs — and it is\n // not derivable from the other, since the two ports are\n // derived separately from this project's path.\n [\"➜ API: \", api]\n ]\n : [[\"\", \"\"], [\"✦ Rebase API is ready!\", \"\"], [\"➜ API: \", api]];\n\n // The CMS, when it is not simply the frontend's home page. Printed\n // rather than assumed: a project that mounts `<RebaseCMS>` at\n // `/admin` inside its product app has an admin URL that appears\n // nowhere — not in the build, not in the running server, not here —\n // and finding it meant reading the frontend's source.\n if (declaresStaticApp && staticShape.cmsPath && staticShape.cmsPath !== \"/\") {\n lines.push([\"➜ CMS: \", `${stripAnsi(frontendUrl).replace(/\\/$/, \"\")}${staticShape.cmsPath}`]);\n }\n\n if (!declaresStaticApp) {\n // Only when it is actually mounted. A project with no tables\n // yet mounts no data API and no Swagger, and printing a URL\n // that 404s is worse than printing nothing — the reader spends\n // the next ten minutes deciding whether their install is\n // broken. The backend says which; this reads its own child.\n if (swaggerPath) {\n lines.push([\"➜ Swagger: \", `${api}${swaggerPath}`]);\n } else {\n // Say why, in the box the reader is actually looking at.\n // \"No docs\" with no reason reads as a broken install.\n lines.push([\" \", \"(no tables served yet, so no data API and no docs)\"]);\n }\n if (managedConnectionString) {\n lines.push([\"\", \"\"]);\n lines.push([\"Database (managed, this project only):\", \"\"]);\n lines.push([\" \", managedConnectionString]);\n lines.push([\" \", \"also: rebase db url\"]);\n }\n }\n\n // Both halves of the first-admin rule, in the box the reader is\n // looking at when they go to sign in.\n //\n // `rebase init` writes REBASE_ADMIN_EMAIL and a generated password\n // into `.env` — for the compose stack, which runs in production,\n // where the first-registration window is shut. Nothing said so, and\n // `rebase dev` reads the same file, so the honest reading of that\n // `.env` was \"these are my credentials\" and the documented first\n // step — register, become the admin — looked broken.\n lines.push([\"\", \"\"]);\n lines.push([\"First login: \", \"the first account to register becomes admin\"]);\n lines.push([\" \", \"(a production boot seeds REBASE_ADMIN_EMAIL from .env instead)\"]);\n lines.push([\"\", \"\"]);\n\n // Sized to its contents. A fixed width silently pushed the right\n // border off the moment a value was longer than the cell, and a\n // managed connection string — port and all — always is.\n const inner = Math.max(...lines.map(([label, value]) => label.length + value.length)) + 4;\n\n console.log(\"\");\n console.log(chalk.cyan(\"┌\" + \"─\".repeat(inner) + \"┐\"));\n for (const [label, value] of lines) {\n console.log(\n chalk.cyan(\"│ \") + label + chalk.white(value) +\n \" \".repeat(inner - 2 - label.length - value.length) +\n chalk.cyan(\"│\")\n );\n }\n console.log(chalk.cyan(\"└\" + \"─\".repeat(inner) + \"┘\"));\n console.log(\"\");\n bannerPrinted = true;\n }, 500);\n }\n\n /**\n * Set once Ctrl+C has been seen, so a child dying on the way out is not\n * reported as a crash. Everything below distinguishes \"the backend fell\n * over\" from \"you asked me to stop\" by this flag alone — an exit code of\n * `null` with a signal is the shape of both.\n */\n let shuttingDown = false;\n\n // Handle graceful shutdown\n const cleanup = () => {\n shuttingDown = true;\n // Clean up dev port file\n try {\n const portFile = path.join(projectRoot, DEV_PORT_FILENAME);\n if (fs.existsSync(portFile)) fs.unlinkSync(portFile);\n\n const urlFile = path.join(projectRoot, \".rebase-dev-url\");\n if (fs.existsSync(urlFile)) fs.unlinkSync(urlFile);\n } catch { /* ignore */ }\n\n children.forEach((child) => {\n if (child.pid && !child.killed) {\n try {\n if (process.platform === \"win32\") {\n execaCommandSync(`taskkill /pid ${child.pid} /T /F`);\n } else {\n process.kill(-child.pid, \"SIGKILL\");\n }\n } catch (e) {\n try {\n child.kill(\"SIGKILL\");\n } catch (err) {\n // ignore\n }\n }\n }\n });\n // Not a hard-coded 0. Ctrl+C is how `rebase dev` normally ends, so\n // exiting 0 unconditionally threw away the one thing `--backend-only`\n // has to report: whether the backend it was asked to run is up. A\n // healthy run still exits 0 — nothing sets the code in that case.\n process.exit(typeof process.exitCode === \"number\" ? process.exitCode : 0);\n };\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n /**\n * Start the Vite frontend, optionally injecting the backend port.\n */\n function startFrontend(backendPort: number | null) {\n if (!frontendDir) return;\n\n console.log(` ${chalk.magenta(\"▶\")} Frontend: ${chalk.gray(frontendDir)}`);\n\n const frontendEnv: Record<string, string> = { ...process.env as Record<string, string> };\n\n // Inject the resolved backend URL so Vite picks it up\n if (backendPort) {\n frontendEnv.VITE_API_URL = `http://localhost:${backendPort}`;\n console.log(` ${chalk.gray(\"↳ VITE_API_URL\")} = ${chalk.white(`http://localhost:${backendPort}`)}`);\n }\n\n const pm = detectPackageManager(projectRoot);\n const pmCmds = getPMCommands(pm);\n const runDevCmd = pmCmds.run(\"dev\");\n\n /**\n * Pin the frontend's port when asked.\n *\n * Vite takes 5173 and hands it to the first asker, so a machine already\n * running one dev server gives the second either a bind failure or —\n * worse — somebody else's app on the address you expected. The backend\n * port has been pinnable since it had the same problem; this is the\n * other half.\n *\n * npm needs `--` before script arguments and pnpm does not, which is\n * the kind of difference that silently passes `--port` to the package\n * manager instead of to Vite.\n */\n if (pm === \"npm\") runDevCmd.push(\"--\");\n runDevCmd.push(\"--port\", String(frontendPort));\n // `--strictPort` only when the developer pinned the port: they asked for\n // that exact one and a silent move defeats the point. Unpinned, Vite\n // keeps its own fallback, so a busy port still starts the frontend.\n if (pinnedFrontendPort) runDevCmd.push(\"--strictPort\");\n console.log(` ${chalk.gray(\"↳ frontend port\")} = ${chalk.white(String(frontendPort))}`);\n\n const frontendChild = execa(\n runDevCmd[0],\n runDevCmd.slice(1),\n {\n cwd: frontendDir,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n env: frontendEnv,\n shell: true,\n detached: process.platform !== \"win32\"\n }\n );\n frontendChild.catch(() => {}); // prevent unhandled promise rejection on exit\n\n frontendChild.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().split(\"\\n\").filter(Boolean);\n lines.forEach((line: string) => {\n console.log(`${chalk.magenta.bold(\"[admin]\")} ${line}`);\n const cleanLine = stripAnsi(line);\n const urlMatch = cleanLine.match(/(http:\\/\\/(?:localhost|127\\.0\\.0\\.1):\\d+)/);\n if (cleanLine.includes(\"Local:\") && urlMatch) {\n frontendUrl = urlMatch[1];\n printSummary();\n }\n });\n });\n\n frontendChild.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().split(\"\\n\").filter(Boolean);\n lines.forEach((line: string) => {\n console.log(`${chalk.magenta.bold(\"[admin]\")} ${line}`);\n });\n });\n\n children.push(frontendChild);\n }\n\n // Start backend\n if (!frontendOnly && backendDir) {\n const tsxBin = resolveTsx(projectRoot);\n if (!tsxBin) {\n console.error(chalk.red(` ✗ ${dependenciesNotInstalled(projectRoot)}`));\n process.exit(1);\n }\n\n // Verify the tsx installation is intact (not just the symlink)\n const tsxValidationError = validateTsxInstallation(tsxBin);\n if (tsxValidationError) {\n const pmCmdsLocal = getPMCommands(detectPackageManager(projectRoot));\n const installCmd = pmCmdsLocal.install.join(\" \");\n console.error(chalk.red(\" ✗ tsx installation appears corrupted.\"));\n console.error(chalk.gray(` ${tsxValidationError}`));\n console.error(\"\");\n console.error(chalk.gray(\" To fix, run:\"));\n console.error(chalk.cyan(` rm -rf node_modules && ${installCmd}`));\n process.exit(1);\n }\n\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n\n // The database, before anything that needs one starts. A project with a\n // DATABASE_URL is untouched; a project without one gets a managed\n // Postgres started here, which is what makes `rebase dev` the only\n // command a new project needs.\n // `--no-db` means start nothing, and that includes the managed\n // database. It used to gate only the preflight, so the one path that\n // actually starts a database on a scaffolded project — the managed\n // PGlite, started here — ran anyway: `rebase dev --no-db` wrote\n // `.rebase/pglite/`, booted a daemon and served against it, which is\n // the opposite of what a reader asking for no database expects. The\n // backend is left to fail on the DATABASE_URL it cannot find, which is\n // the failure the flag exists to produce.\n const prepared = noDb ? null : await prepareDatabaseEnv(projectRoot, {\n flagUrl: typeof args[\"--database-url\"] === \"string\" ? args[\"--database-url\"] : null,\n flagDocker: Boolean(args[\"--docker\"]),\n onProgress: (message) => console.log(chalk.gray(` ${message}`)),\n additionalKeys: await declaredAdditionalDatabases(projectRoot)\n });\n if (prepared) Object.assign(env, prepared.env);\n /**\n * Whether this run is on the managed database.\n *\n * `db push` is the remedy for what boot leaves alone, and it cannot run\n * against the managed one at all — Atlas plans by diffing against a\n * second, empty database, and PGlite serves exactly one. So every\n * remedy that names it has to know which database is under this run.\n */\n const managed = prepared?.database.kind === \"managed\";\n if (managed) managedConnectionString = prepared?.env.DATABASE_URL ?? null;\n // …and the backend needs the same answer, for the same reason. Its\n // schema-drift remedy said `pnpm db:push` whatever database it was\n // serving, and on the managed one that command is refused. `db`,\n // `schema` and `doctor` already pass this to their driver children;\n // the backend is the one that had to guess.\n if (prepared) env[DEV_DATABASE_KIND_ENV] = prepared.database.kind;\n\n // Always inject PORT so the backend uses our resolved port instead of\n // its hardcoded default (3001). This prevents cross-project collisions\n // when multiple Rebase instances run simultaneously.\n env.PORT = String(startPort);\n // …and whether that number was typed or derived, which decides whether\n // the server may walk past a collision. Always stated, never merely\n // set: `env` starts as a copy of this process's, so leaving the key\n // alone would let an inherited value pin a port nobody asked for.\n env.REBASE_DEV_PORT_EXPLICIT = String(portIsPinned);\n\n // And where the frontend will be, for the same reason. `FRONTEND_URL`\n // is the base of every emailed link and one of the two things CORS is\n // derived from, and the scaffold's `.env` states a fixed\n // `http://localhost:5173` that this command overrides — so the welcome\n // email linked a port the app was not running on. The frontend-only\n // case never reaches here, and there the .env value is still right.\n if (!backendOnly && frontendDir) {\n env.FRONTEND_URL = `http://localhost:${frontendPort}`;\n }\n\n console.log(` ${chalk.cyan(\"▶\")} Backend: ${chalk.gray(backendDir)}`);\n console.log(` ${chalk.gray(\"↳ PORT\")} = ${chalk.white(String(startPort))} ${chalk.gray(`(${START_PORT_SOURCE_LABELS[startPortSource]})`)}`);\n console.log(` ${chalk.gray(\"↳ Database\")} = ${chalk.white(databaseBannerValue(prepared))}`);\n // Stated on every start rather than left to be discovered. A developer\n // who does not know requests are serialized here will read the\n // difference as a bug in their own code.\n if (prepared) {\n for (const line of managedNotices(prepared).slice(1)) console.log(` ${chalk.gray(line)}`);\n }\n\n // The .env's PORT / VITE_API_URL look authoritative but are overridden in\n // dev: we derive a per-project port to avoid cross-project collisions and\n // point the frontend at it. Surface that so a mismatched .env doesn't turn\n // into a silent \"connecting to the wrong port\" debugging loop.\n if (envFile) {\n try {\n const envText = fs.readFileSync(envFile, \"utf-8\");\n const envPort = readEnvValue(envText, \"PORT\");\n const envApiUrl = readEnvValue(envText, \"VITE_API_URL\");\n // Only name the keys — never echo a raw `http://localhost:<port>`\n // value, so log scrapers don't mistake it for the dev server URL.\n const overridden: string[] = [];\n // A value equal to the scaffold's own default was written by\n // the scaffold, not chosen by anyone, so there is nothing to\n // warn about: this fired on the very first `rebase dev` of\n // every new project, about a line the developer had not read\n // yet, for a setting that applies to a command they had not\n // run. A warning that is always there is a warning nobody\n // reads when it matters.\n const portWasChosen = Boolean(envPort) && envPort !== String(SCAFFOLD_DEFAULT_PORT);\n if (portWasChosen && envPort !== String(startPort)) overridden.push(\"PORT\");\n if (envApiUrl && envApiUrl !== `http://localhost:${startPort}`) overridden.push(\"VITE_API_URL\");\n if (overridden.length > 0) {\n console.log(chalk.yellow(\n ` ⚠ dev uses a derived per-project port (${startPort}); your .env ${overridden.join(\" / \")} ` +\n `${overridden.length > 1 ? \"are\" : \"is\"} ignored here (avoids cross-project collisions). ` +\n `Pass ${chalk.white(\"--port\")} to pin a port.`\n ));\n }\n } catch { /* ignore — best-effort notice */ }\n }\n\n /** Whether the frontend has been launched (we only launch it once). */\n let frontendLaunched = false;\n\n // A generated schema that a *library upgrade* invalidated, repaired before\n // the backend sees it.\n //\n // Distinct from the drift warning further down, which watches\n // `config/collections` and so only fires when the developer edits\n // something. This case has no edit: 0.13 derives `category_id` where 0.12\n // derived `categorie_id`, from an unchanged collection. Boot-ensure renames\n // the database column, relation validation reads the stale generated module\n // and refuses to start — on this boot and every boot after, since the\n // rename does not run twice. Regenerating is the whole fix, and the release\n // note promises the rename is handled, so do it rather than announce it.\n //\n // Runs regardless of `--generate`: this is not \"keep my schema fresh\", it\n // is \"do not hand the runtime a file that cannot boot\".\n try {\n const activePlugin = getActiveBackendPlugin(backendDir);\n const pluginCli = activePlugin ? resolvePluginCliScript(backendDir, activePlugin) : null;\n if (pluginCli) {\n await execa(tsxBin, [pluginCli, \"schema\", \"stale\", \"--fix\"], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n }\n } catch {\n // Never block `dev` on this. A project with no generated schema, a\n // driver too old to know the subcommand, or a collections directory\n // that will not load all land here, and the boot itself reports each\n // of them better than a preflight can.\n }\n\n // Initial schema and SDK generation (disabled by default, enabled via --generate or env var)\n if (shouldGenerate) {\n console.log(chalk.gray(\" → Ensuring schema and SDK are generated on start...\"));\n try {\n const activePlugin = getActiveBackendPlugin(backendDir);\n const pluginCli = activePlugin ? resolvePluginCliScript(backendDir, activePlugin) : null;\n if (pluginCli) {\n await execa(tsxBin, [pluginCli, \"schema\", \"generate\"], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n }\n const sdkCmd = getPMCommands(detectPackageManager(projectRoot)).exec(\"rebase\", [\"generate-sdk\"]);\n await execa(sdkCmd[0], sdkCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\",\n env\n });\n console.log(chalk.green(\" ✓ Initial schema and SDK generated successfully.\\n\"));\n } catch (err: unknown) {\n console.error(chalk.red(` ✗ Initial schema/SDK generation failed: ${err instanceof Error ? err.message : err}\\n`));\n }\n\n // Watch collections folder for changes\n const collectionsDir = path.join(projectRoot, \"config\", \"collections\");\n if (fs.existsSync(collectionsDir)) {\n let watchDebounce: NodeJS.Timeout | null = null;\n // The SQL schema and the SDK do not answer to the same edits.\n // The SDK is generated from the collections `index` module, which\n // can re-export anything the project puts under this directory,\n // so every change is a reason to rebuild it. The Drizzle schema\n // covers only the SQL-backed collections the loader reads — see\n // `affectsSqlSchema`. Tracked across the debounce window because\n // one burst can touch both kinds of file.\n let sqlSchemaAffected = false;\n fs.watch(collectionsDir, { recursive: true }, (eventType, filename) => {\n if (!filename || filename.startsWith(\".\") || filename.endsWith(\".tmp\")) return;\n\n sqlSchemaAffected = sqlSchemaAffected || affectsSqlSchema(collectionsDir, filename);\n if (watchDebounce) clearTimeout(watchDebounce);\n watchDebounce = setTimeout(async () => {\n const regenerateSchema = sqlSchemaAffected;\n sqlSchemaAffected = false;\n console.log(chalk.yellow(\n `\\n 🔄 Collection change detected (${filename}). Regenerating ${regenerateSchema ? \"schema & SDK\" : \"SDK\"}...`\n ));\n try {\n const activePlugin = getActiveBackendPlugin(backendDir);\n const pluginCli = regenerateSchema && activePlugin ? resolvePluginCliScript(backendDir, activePlugin) : null;\n if (pluginCli) {\n await execa(tsxBin, [pluginCli, \"schema\", \"generate\"], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n }\n const sdkCmd = getPMCommands(detectPackageManager(projectRoot)).exec(\"rebase\", [\"generate-sdk\"]);\n await execa(sdkCmd[0], sdkCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\",\n env\n });\n console.log(chalk.green(\n ` ✓ ${regenerateSchema ? \"Schema & SDK\" : \"SDK\"} regenerated successfully. Hono will reload.`\n ));\n } catch (err: unknown) {\n console.error(chalk.red(` ✗ Failed to regenerate schema/SDK: ${err instanceof Error ? err.message : err}`));\n }\n }, 300);\n });\n }\n }\n\n // A project with its own `backend/src/index.ts` runs it, exactly as\n // before. Without one, dev boots the stock runtime over the project's\n // TypeScript source — the same boot path a deployment takes, so what runs\n // locally is what will run deployed. This is what makes the hand-written\n // entrypoint optional instead of something every project must carry.\n const ejectedEntry = path.join(backendDir, \"src\", \"index.ts\");\n const usesStockRuntime = !fs.existsSync(ejectedEntry);\n const entryTarget = usesStockRuntime ? resolveDevRuntimeEntry() : \"src/index.ts\";\n\n // Computed even for an ejected backend: the paths are where the *project*\n // keeps its functions and crons, which is what dev has to watch, and an\n // ejected entrypoint reads the same directories.\n const runtimePaths = devRuntimeEnv(projectRoot);\n if (usesStockRuntime) {\n Object.assign(env, runtimePaths);\n }\n\n const watchArgs = [\"watch\", \"--conditions\", \"development\", quoteForShell(entryTarget)];\n for (const dir of devWatchIncludes(projectRoot, runtimePaths, !shouldGenerate)) {\n watchArgs.splice(1, 0, \"--include\", quoteForShell(dir));\n }\n\n if (!shouldGenerate) {\n // Watch the collections folder and regenerate the schema from it.\n //\n // This used to print a box telling the reader to run `rebase schema\n // generate` themselves, which made the documented first edit fail\n // in a way nothing named. tsx restarts the backend on a config\n // change, boot's additive ensure adds the new column to the\n // database — and then the very first save of a row carrying it\n // answered 400 VALIDATION_UNKNOWN_FIELDS, because the driver looked\n // its columns up in `backend/src/schema.generated.ts` and that file\n // was still the one generated before the edit.\n //\n // The driver reads the database now, so that particular 400 is gone\n // at the root. This stays because the file is still what `db push`,\n // Atlas, `eject` and the developer's own imports read, and a file\n // that silently falls behind the collections during a dev session is\n // a surprise waiting at the next deploy. It is the same call `dev`\n // already makes at startup: no database, idempotent, about two\n // seconds. The reader's single instruction is still \"save the file\".\n const collectionsDir = path.join(projectRoot, \"config\", \"collections\");\n if (fs.existsSync(collectionsDir)) {\n let driftDebounce: NodeJS.Timeout | null = null;\n fs.watch(collectionsDir, { recursive: true }, (_eventType, filename) => {\n if (!filename || filename.startsWith(\".\") || filename.endsWith(\".tmp\")) return;\n // Only a change to a SQL-backed collection can put the\n // generated schema out of sync — a Firestore collection has\n // nothing to generate, push or check for drift.\n if (!affectsSqlSchema(collectionsDir, filename)) return;\n if (driftDebounce) clearTimeout(driftDebounce);\n driftDebounce = setTimeout(() => {\n void (async () => {\n // The box is drawn at a fixed width, so a name longer\n // than the cell would push the right border off.\n const shown = filename!.length > 31 ? `…${filename!.slice(-30)}` : filename!.padEnd(31);\n console.log([\n \"\",\n chalk.yellow(\" ┌──────────────────────────────────────────────────────────────┐\"),\n chalk.yellow(\" │ 🔄 Collection file changed: \") + chalk.white(shown) + chalk.yellow(\"│\"),\n chalk.yellow(\" │ Regenerating the schema… │\"),\n chalk.yellow(\" └──────────────────────────────────────────────────────────────┘\")\n ].join(\"\\n\"));\n\n await ensureGeneratedSchema(projectRoot);\n\n console.log([\n chalk.green(\" ✓ Schema regenerated. The backend restarts and boot creates what\"),\n chalk.green(\" is missing — a new collection, a new property.\"),\n // `db push` is the remedy for what boot leaves alone, and it\n // cannot run against the managed database at all: Atlas plans\n // by diffing against a second, empty database, and PGlite\n // serves exactly one. Naming it there sends the reader to a\n // command that answers with a refusal.\n ...(managed\n ? [chalk.gray(\" A renamed column, a narrowed type or a removed field needs your\"),\n chalk.gray(\" own PostgreSQL: set DATABASE_URL, then rebase db push.\")]\n : [chalk.gray(\" For what boot leaves alone — a renamed column, a narrowed type,\"),\n chalk.gray(` a removed field — run ${chalk.cyan(\"rebase db push\")}.`)]),\n \"\"\n ].join(\"\\n\"));\n })();\n }, 500);\n });\n }\n }\n\n const backendChild = execa(\n tsxBin,\n watchArgs,\n {\n cwd: backendDir,\n stdio: [\"inherit\", \"pipe\", \"pipe\"],\n env,\n shell: true,\n detached: process.platform !== \"win32\"\n }\n );\n backendChild.catch(() => {}); // prevent unhandled promise rejection on exit\n\n /**\n * Whether the backend ever said \"Server running at\".\n *\n * The one fact this command has about whether the thing it started\n * works. Without it, a backend that threw on boot left `rebase dev`\n * printing \"Press Ctrl+C to stop all servers.\" under a stack trace, as\n * if everything were fine — and `tsx watch` keeps its own process alive\n * after the entry crashes, so nothing exits to contradict it.\n */\n let backendAnnounced = false;\n\n /** The verdict, printed once per failure rather than once per line. */\n let backendDownReported = false;\n const reportBackendDown = (headline: string) => {\n if (shuttingDown || backendDownReported) return;\n backendDownReported = true;\n console.log(\"\");\n console.error(chalk.red(` ✗ ${headline}`));\n console.error(chalk.gray(\" Fix the error above; the watcher restarts it on the next change.\"));\n console.log(\"\");\n // With a frontend still running there is a server to keep serving,\n // so the run continues and only the message is owed. `--backend-only`\n // has nothing left to do, and a zero exit there tells a script the\n // backend ran fine. Cleared again by the next \"Server running at\".\n if (backendOnly) process.exitCode = 1;\n };\n\n /**\n * Say so when the backend is not up.\n *\n * A deadline rather than an exit code, because there is usually no exit\n * to watch: the watcher survives its child and waits for a file change,\n * so a crash is visible only as an absence.\n *\n * Armed once at spawn and **re-armed on every restart**, which is the\n * half that was missing. The old timer fired once, thirty seconds after\n * start-up, and its body began `if (backendAnnounced) return` — so a\n * backend that came up and then died on the next save was covered by\n * nothing at all. Breaking `config/resources.ts` under a running\n * `rebase dev` printed a stack trace, took `/health` to nothing, and\n * left the CLI saying \"Press Ctrl+C to stop all servers.\"\n */\n const readyTimeoutMs = Number(env.REBASE_DEV_READY_TIMEOUT_MS ?? process.env.REBASE_DEV_READY_TIMEOUT_MS ?? 30_000);\n let readyDeadline: NodeJS.Timeout | undefined;\n const disarmReadyDeadline = () => {\n if (readyDeadline) clearTimeout(readyDeadline);\n readyDeadline = undefined;\n };\n const armReadyDeadline = (headline: string) => {\n disarmReadyDeadline();\n if (readyTimeoutMs <= 0) return;\n readyDeadline = setTimeout(() => {\n if (backendAnnounced) return;\n reportBackendDown(headline);\n }, readyTimeoutMs);\n readyDeadline.unref?.();\n };\n const readySeconds = Math.round(readyTimeoutMs / 1000);\n armReadyDeadline(`The backend has not started after ${readySeconds}s.`);\n\n const noticePortMoved = (line: string): void => {\n const moved = portMovedNotice(line);\n if (!moved) return;\n console.log(` ${chalk.gray(\"↳ PORT\")} = ${chalk.white(moved.to)} ${chalk.gray(`(${moved.from} was in use)`)}`);\n };\n\n /**\n * The restart line, on either stream.\n *\n * A restart means the announced backend is gone: it either exited on\n * its own (tsx says \"Rerunning\") or is being killed (tsx says\n * \"Restarting\"). Either way the question \"is there a server?\" is open\n * again, so readiness is un-announced and the deadline re-armed. Without\n * this the flag stayed true forever after the first successful boot.\n *\n * Checked on both streams because which pipe it lands on is tsx's\n * business, and a marker watched on the wrong one never fires.\n */\n const noticeWatcherRestart = (line: string): void => {\n if (!WATCHER_RESTART_MARKER.test(stripAnsi(line))) return;\n backendAnnounced = false;\n backendDownReported = false;\n armReadyDeadline(`The backend did not come back up after ${readySeconds}s.`);\n };\n\n /**\n * And notice a backend that dies without tsx saying anything.\n *\n * `kill -9` of the server process is the plain case: tsx stays alive,\n * prints nothing, and waits for a file change that may never come.\n * Measured on tsx 4.23.1 — the watcher's transcript after the kill is\n * empty. So the only honest question left is whether anything is still\n * listening on the port the backend announced, and this asks it.\n *\n * Only runs between an announcement and the next restart, so an\n * ordinary restart (where the port is legitimately closed for a second)\n * cannot trip it: `noticeWatcherRestart` clears `backendAnnounced`\n * before the process is killed. Two misses rather than one, because a\n * single refused connect under load is not yet news.\n */\n let missedProbes = 0;\n const liveness = setInterval(() => {\n if (shuttingDown || !backendAnnounced || !resolvedBackendPort) {\n missedProbes = 0;\n return;\n }\n const port = resolvedBackendPort;\n void probeTcp(\"127.0.0.1\", port, 1_000).then(alive => {\n if (!backendAnnounced || resolvedBackendPort !== port) return;\n if (alive) {\n missedProbes = 0;\n return;\n }\n if (++missedProbes < 2) return;\n backendAnnounced = false;\n missedProbes = 0;\n reportBackendDown(`The backend stopped listening on port ${port}.`);\n });\n }, LIVENESS_INTERVAL_MS);\n liveness.unref?.();\n\n /**\n * And say so when tsx itself gives up.\n *\n * Distinct from the deadline above: this is the watcher exiting, not\n * the app under it. It happens when the entry cannot be resolved at\n * all, when node_modules is broken, or when something kills the\n * process — none of which tsx will retry, so the run is over and the\n * exit code should say so.\n */\n backendChild.on(\"exit\", (code: number | null, signal: NodeJS.Signals | null) => {\n disarmReadyDeadline();\n clearInterval(liveness);\n backendAnnounced = false;\n // The watcher itself is gone, so this is terminal in a way a failed\n // run is not — worth saying even if a crash was already reported.\n backendDownReported = false;\n reportBackendDown(signal\n ? `Backend was killed by ${signal}.`\n : `Backend exited with code ${code ?? 1}.`);\n if (backendOnly) process.exitCode = code ?? 1;\n });\n\n backendChild.stdout?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().split(\"\\n\").filter(Boolean);\n lines.forEach((line: string) => {\n console.log(`${chalk.cyan.bold(\"[backend]\")} ${line}`);\n noticeWatcherRestart(line);\n noticePortMoved(line);\n const cleanLine = stripAnsi(line);\n const swaggerMatch = cleanLine.match(/Swagger UI available.*\"path\":\"([^\"]+)\"/);\n if (swaggerMatch) swaggerPath = swaggerMatch[1];\n\n const serverMatch = cleanLine.match(/Server running at http:\\/\\/(?:localhost|127\\.0\\.0\\.1):(\\d+)/);\n if (serverMatch) {\n backendAnnounced = true;\n backendDownReported = false;\n missedProbes = 0;\n // The backend is up, so an earlier failure is no longer the\n // answer this run gives.\n if (backendOnly) process.exitCode = 0;\n disarmReadyDeadline();\n resolvedBackendPort = parseInt(serverMatch[1], 10);\n backendUrl = \"started\";\n printSummary();\n\n // Save the url to a temp file for scripts to pick up\n const urlFile = path.join(projectRoot, \".rebase-dev-url\");\n fs.writeFileSync(urlFile, `http://localhost:${resolvedBackendPort}`, \"utf-8\");\n\n // Save the port to .rebase-dev-port for port affinity\n const portFile = path.join(projectRoot, DEV_PORT_FILENAME);\n fs.writeFileSync(portFile, String(resolvedBackendPort), \"utf-8\");\n\n // Start frontend now that we know the real port\n if (!backendOnly && frontendDir && !frontendLaunched) {\n frontendLaunched = true;\n startFrontend(resolvedBackendPort);\n }\n }\n });\n });\n\n /** Whether we've already shown a corrupted-modules recovery hint. */\n let corruptedModulesWarned = false;\n\n backendChild.stderr?.on(\"data\", (data: Buffer) => {\n const lines = data.toString().split(\"\\n\").filter(Boolean);\n lines.forEach((line: string) => {\n console.log(`${chalk.cyan.bold(\"[backend]\")} ${line}`);\n\n noticeWatcherRestart(line);\n noticePortMoved(line);\n\n // Detect corrupted node_modules at runtime\n // (covers tsx and any other dependency whose pnpm store entry is broken)\n if (!corruptedModulesWarned) {\n const cleanLine = stripAnsi(line);\n if (\n cleanLine.includes(\"Cannot find module\") &&\n cleanLine.includes(\"node_modules/.pnpm/\")\n ) {\n corruptedModulesWarned = true;\n // Delay slightly so the full Node.js error stack prints first\n setTimeout(() => {\n const pm = detectPackageManager(projectRoot);\n const installCmd = getPMCommands(pm).install.join(\" \");\n console.error(\"\");\n console.error(chalk.red(\" ✗ node_modules appears corrupted — a required file is missing.\"));\n console.error(chalk.gray(\" This usually happens when a previous install was interrupted\"));\n console.error(chalk.gray(\" or the package manager store was cleaned.\"));\n console.error(\"\");\n console.error(chalk.gray(\" To fix, stop the dev server and run:\"));\n console.error(chalk.cyan(` rm -rf node_modules && ${installCmd}`));\n console.error(\"\");\n }, 200);\n }\n }\n });\n });\n\n children.push(backendChild);\n } else if (!frontendOnly && !backendDir) {\n console.warn(chalk.yellow(\" ⚠ No backend/ directory found, skipping backend.\"));\n }\n\n // Start frontend immediately if backend-only mode or no backend\n if (!backendOnly && frontendDir && (frontendOnly || !backendDir)) {\n startFrontend(null);\n } else if (!backendOnly && !frontendDir && declaresStaticApp) {\n console.warn(chalk.yellow(\" ⚠ No frontend/ directory found, skipping frontend.\"));\n }\n\n if (children.length === 0) {\n console.error(chalk.red(\" ✗ Nothing to start. Check your project structure.\"));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.gray(\" Press Ctrl+C to stop all servers.\"));\n console.log(\"\");\n\n // Wait for all children to exit\n await Promise.all(\n children.map(\n (child) =>\n new Promise<void>((resolve) => {\n child.finally(() => resolve());\n })\n )\n );\n}\n\nfunction printDevHelp() {\n console.log(`\n${chalk.bold(\"rebase dev\")} — Start the development server\n\n${chalk.green.bold(\"Usage\")}\n rebase dev [options]\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--backend-only, -b\")} Only start the backend server\n ${chalk.blue(\"--frontend-only, -f\")} Only start the frontend server\n ${chalk.blue(\"--port, -P\")} Backend port (default: auto-detected per project)\n ${chalk.blue(\"--generate, -g\")} Enable automatic schema and SDK generation on startup and file changes\n ${chalk.blue(\"--database-url\")} ${chalk.gray(\"<url>\")} Use this Postgres, ahead of everything else\n ${chalk.blue(\"--docker\")} Use the project's docker-compose ${chalk.gray(\"db\")} service\n ${chalk.blue(\"--no-db\")} Start no database at all\n\n${chalk.green.bold(\"Which database\")}\n Ordered, and the order is the promise. The first of these that says\n something wins:\n\n 1. ${chalk.blue(\"--database-url <url>\")} on this command line\n 2. ${chalk.gray(\"DATABASE_URL\")} in the shell environment\n 3. the branch this checkout is switched to ${chalk.gray(\"(rebase db branch switch)\")}\n 4. ${chalk.gray(\"DATABASE_URL\")} in the project's .env\n 5. ${chalk.blue(\"--docker\")} on this command line\n 6. the managed development database ${chalk.gray(\"(PGlite, data in .rebase/)\")}\n\n A scaffolded project sets none of 1–5, so it lands on (6): no Docker,\n nothing to install, and the collections' tables are created at boot.\n\n ${chalk.blue(\"--docker\")} reaches the ${chalk.gray(\"db\")} service in this project's docker-compose.yml,\n starting the container if nothing is listening on its port, and pushing\n the schema when this command is what started it. Its connection string\n is derived from the compose file and ${chalk.gray(\"DATABASE_PASSWORD\")} in .env — the same\n string .env carries, commented out, as ${chalk.gray(\"DATABASE_URL\")}.\n\n A database that is already running is never touched: no schema push,\n no connection. A DATABASE_URL pointing anywhere other than this machine\n is left alone entirely. Pass ${chalk.blue(\"--no-db\")}, or set REBASE_DEV_NO_DB=1, to\n start nothing — the backend then fails on the database it cannot reach,\n which is the point.\n\n${chalk.green.bold(\"Which port\")}\n Ordered like the database, and the order is the promise. The first of\n these that says something wins, and the start banner names which one did:\n\n 1. ${chalk.blue(\"--port <n>\")} on this command line\n 2. ${chalk.gray(\"PORT\")} in the shell environment\n 3. the port the last ${chalk.gray(\"rebase dev\")} used ${chalk.gray(\"(.rebase-dev-port)\")}\n 4. a port derived from this project's path\n\n ${chalk.gray(\"PORT\")} in the project's .env is ${chalk.bold(\"not\")} read here: this command resolves\n its port before .env is loaded and then sets ${chalk.gray(\"PORT\")} for the backend from\n what it resolved. Export it in your shell, or pass ${chalk.blue(\"--port\")}.\n\n${chalk.green.bold(\"Description\")}\n Starts both the backend (tsx watch + Hono) and frontend (Vite)\n dev servers concurrently with color-coded output prefixes.\n\n Each project automatically receives a unique default port derived\n from its directory path, preventing collisions when running multiple\n Rebase instances simultaneously.\n\n If the assigned port is already in use, the server will automatically\n try the next available port. The frontend is started only after the\n backend is ready, and VITE_API_URL is injected automatically.\n\n By default, automatic schema and SDK generation is disabled on startup\n and file changes. Pass --generate (-g) or set REBASE_AUTO_GENERATE=true\n in your environment to enable it.\n`);\n}\n","/**\n * The stdio a build tool the CLI runs in the foreground gets: a static app's\n * build command, `tsc`, `tar`.\n *\n * Inherited, so its output streams as it happens. With `quietStdout` its stdout\n * goes to stderr instead, for a command whose own stdout carries a result:\n * `rebase cloud deploy` in JSON mode — every piped run — owes stdout exactly one\n * JSON value, and a `vite v6 building…` line in front of it is a result no\n * parser can read. The tool's output still reaches the person watching.\n */\nexport function toolStdio(quietStdout: boolean | undefined): \"inherit\" | [\"ignore\", 2, \"inherit\"] {\n return quietStdout ? [\"ignore\", 2, \"inherit\"] : \"inherit\";\n}\n","/**\n * What each of a project's custom functions depends on the *host* for.\n *\n * A custom function is a Hono app, and Hono runs on every JavaScript server\n * runtime there is. So the question of whether a given function could run\n * somewhere other than a Node process is not about the framework — it is\n * entirely about what the function's own file imports and touches. This answers\n * that, per file, from source.\n *\n * It is a **report, not a rule.** Nothing here fails a build. A function that\n * opens a file, shells out, or runs raw SQL is a perfectly good function, and\n * on a Node deployment — which is every deployment today — it costs nothing.\n * The value is in knowing which ones those are *before* it matters, and in the\n * one finding that is genuinely a latent bug on any host:\n * `process.env` read at module scope.\n *\n * Why bother now: the alternative is discovering it per-file, later, across a\n * codebase already written against the assumption. The scan is cheap, the\n * output is short, and the habits it nudges — importing from\n * `@rebasepro/server/functions`, reading configuration inside the handler — are\n * better on Node too.\n *\n * @module\n */\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n/** Node built-ins, bare and `node:`-prefixed alike. */\nconst NODE_BUILTINS = new Set([\n \"assert\", \"async_hooks\", \"buffer\", \"child_process\", \"cluster\", \"console\",\n \"constants\", \"crypto\", \"dgram\", \"diagnostics_channel\", \"dns\", \"domain\",\n \"events\", \"fs\", \"http\", \"http2\", \"https\", \"inspector\", \"module\", \"net\",\n \"os\", \"path\", \"perf_hooks\", \"process\", \"punycode\", \"querystring\",\n \"readline\", \"repl\", \"stream\", \"string_decoder\", \"sys\", \"timers\", \"tls\",\n \"trace_events\", \"tty\", \"url\", \"util\", \"v8\", \"vm\", \"wasi\", \"worker_threads\",\n \"zlib\"\n]);\n\n/**\n * Packages that need Node, with the reason. Not exhaustive and cannot be —\n * an unknown package is reported as unknown rather than guessed at, because\n * claiming a dependency is portable when it is not is worse than saying nothing.\n */\nconst NODE_ONLY_PACKAGES = new Map<string, string>([\n [\"@hono/node-server\", \"the Node HTTP adapter\"],\n [\"ws\", \"Node sockets\"],\n [\"jsonwebtoken\", \"node:crypto\"],\n [\"drizzle-orm\", \"a database TCP socket\"],\n [\"pg\", \"a database TCP socket\"],\n [\"postgres\", \"a database TCP socket\"],\n [\"mysql2\", \"a database TCP socket\"],\n [\"mongodb\", \"a database TCP socket\"],\n [\"nodemailer\", \"SMTP sockets\"],\n [\"sharp\", \"a native addon\"],\n [\"bcrypt\", \"a native addon\"],\n [\"puppeteer\", \"a browser subprocess\"],\n [\"fs-extra\", \"the filesystem\"],\n [\"chokidar\", \"the filesystem\"],\n [\"dotenv\", \"reading a file at import time\"],\n [\"archiver\", \"Node streams\"],\n [\"ioredis\", \"Node sockets\"]\n]);\n\n/** What a single finding is about. */\nexport type PortabilityIssueKind =\n | \"node-builtin\"\n | \"node-only-package\"\n | \"module-scope-env\"\n | \"root-barrel-import\"\n | \"unknown-package\";\n\nexport interface PortabilityIssue {\n kind: PortabilityIssueKind;\n /** 1-based line in the function file. */\n line: number;\n /** One sentence, already phrased for a terminal. */\n message: string;\n /**\n * Whether this is a problem *today*, on Node, rather than only a constraint\n * on where the function could run. Exactly one kind is:\n * `module-scope-env`, which is a latent crash on any host where a variable\n * happens to be unset at import time, and takes every other function in the\n * same directory down with it — the loader reports a file that throws on\n * import as simply \"skipped\".\n */\n actionable: boolean;\n}\n\nexport interface FunctionPortability {\n /** Function name — the filename without extension, as it mounts. */\n name: string;\n /** Path relative to the project root. */\n file: string;\n /** Empty when the function depends on nothing host-specific. */\n issues: PortabilityIssue[];\n /** True when `issues` contains nothing that pins it to Node. */\n portable: boolean;\n /**\n * Names imported from the project's resources module — `import { media }\n * from \"../../config/resources\"` — so the graph can record that this\n * function reaches `media` without evaluating it. Export names, not keys:\n * the derive step maps them through the evaluated module.\n */\n resourceImports: string[];\n}\n\n/** Files the functions loader would serve. Mirrors `function-loader.ts`. */\nfunction functionFiles(directory: string): string[] {\n if (!fs.existsSync(directory)) return [];\n return fs.readdirSync(directory, { withFileTypes: true })\n .filter(entry => entry.isFile())\n .map(entry => entry.name)\n .filter(name =>\n (name.endsWith(\".ts\") || name.endsWith(\".js\"))\n && !name.startsWith(\".\")\n && !name.includes(\".test.\")\n && !name.endsWith(\".d.ts\")\n && name !== \"index.ts\"\n && name !== \"index.js\")\n .sort();\n}\n\n/**\n * Blank out comments, preserving line structure so reported line numbers stay\n * true. Strings are left alone: an import specifier *is* a string, and blanking\n * them before reading imports is how a scan reports that a file imports `\"\"`.\n */\nfunction stripComments(source: string): string {\n return source\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, match => match.replace(/[^\\n]/g, \" \"))\n .replace(/(^|[^:])\\/\\/[^\\n]*/g, (match, lead) => lead + \" \".repeat(match.length - lead.length));\n}\n\n/**\n * Comments *and* string bodies, for scans that look for identifiers rather than\n * specifiers — where `\"process.env.FOO\"` inside a message is not a read.\n */\nfunction stripNonCode(source: string): string {\n return stripComments(source)\n .replace(/`(?:[^`\\\\]|\\\\.)*`/g, match => match.replace(/[^\\n]/g, \" \"))\n .replace(/\"(?:[^\"\\\\\\n]|\\\\.)*\"/g, match => `\"${\" \".repeat(Math.max(0, match.length - 2))}\"`)\n .replace(/'(?:[^'\\\\\\n]|\\\\.)*'/g, match => `'${\" \".repeat(Math.max(0, match.length - 2))}'`);\n}\n\n/** Import specifiers, keeping the raw line so the report can point at it. */\nfunction imports(source: string): Array<{ specifier: string; line: number; typeOnly: boolean }> {\n const found: Array<{ specifier: string; line: number; typeOnly: boolean }> = [];\n const lines = source.split(\"\\n\");\n\n lines.forEach((line, index) => {\n const match = /(?:^|[\\s;}])(?:import|export)(\\s+type)?\\s[^;]*?from\\s*[\"']([^\"']+)[\"']/.exec(line)\n ?? /(?:^|[\\s;}])import\\s*[\"']([^\"']+)[\"']/.exec(line);\n if (!match) return;\n const specifier = match[2] ?? match[1];\n if (!specifier) return;\n found.push({\n specifier,\n line: index + 1,\n // `import type` is erased before anything runs, so it constrains\n // nothing at runtime — flagging it would be noise that trains people\n // to ignore the report.\n typeOnly: Boolean(match[1]) || /\\bimport\\s+type\\b/.test(line)\n });\n });\n\n return found;\n}\n\n/**\n * The names a file imports from the project's resources module.\n *\n * Matched on the specifier's last path segment — `../config/resources`,\n * `../../config/resources.js`, `@app/config/resources` — because that is the\n * one convention `rebase resources` reads declarations from, and a function\n * importing a handle from anywhere else has put its declaration somewhere\n * the graph does not look. Type-only imports are skipped: they reach nothing\n * at runtime.\n */\nfunction resourceImports(source: string): string[] {\n const names = new Set<string>();\n for (const line of source.split(\"\\n\")) {\n const match = /(?:^|[\\s;}])import\\s+(?!type\\b)\\{([^}]*)\\}\\s*from\\s*[\"']([^\"']+)[\"']/.exec(line);\n if (!match) continue;\n const specifier = match[2].replace(/\\.[cm]?[jt]s$/, \"\");\n if (!/(?:^|\\/)resources(?:\\/index)?$/.test(specifier)) continue;\n for (const part of match[1].split(\",\")) {\n const name = part.trim().replace(/^type\\s+/, \"\");\n if (!name || part.trim().startsWith(\"type \")) continue;\n // `media as photos` imports `media`; the local alias is not the export.\n names.add(name.split(/\\s+as\\s+/)[0].trim());\n }\n }\n return [...names].sort();\n}\n\n/**\n * `process.env` (and friends) read where the module is *evaluated*.\n *\n * Indentation is the heuristic for \"inside something that runs later\", which is\n * exact for every formatter anyone uses on a function file and wrong only for\n * code nobody writes. The cost of being wrong is one line of advisory output.\n */\nfunction moduleScopeEnvReads(source: string): number[] {\n const lines = stripNonCode(source).split(\"\\n\");\n const hits: number[] = [];\n lines.forEach((line, index) => {\n if (/^\\s/.test(line) || line.trim() === \"\") return;\n if (/\\bprocess\\.env\\b/.test(line)) hits.push(index + 1);\n });\n return hits;\n}\n\nfunction packageOf(specifier: string): string {\n return specifier.startsWith(\"@\")\n ? specifier.split(\"/\").slice(0, 2).join(\"/\")\n : specifier.split(\"/\")[0];\n}\n\n/** Analyse one function file's source. Exported for testing. */\nexport function analyseFunctionSource(source: string, name: string, file: string): FunctionPortability {\n const issues: PortabilityIssue[] = [];\n // Two views of the same file: imports need their string literals intact,\n // identifier scans need them gone. Both keep line numbers.\n const withStrings = stripComments(source);\n const code = stripNonCode(source);\n\n for (const { specifier, line, typeOnly } of imports(withStrings)) {\n if (typeOnly) continue;\n if (specifier.startsWith(\".\") || specifier.startsWith(\"/\")) continue;\n\n const bare = specifier.replace(/^node:/, \"\");\n if (specifier.startsWith(\"node:\") || NODE_BUILTINS.has(bare.split(\"/\")[0])) {\n issues.push({\n kind: \"node-builtin\",\n line,\n message: `imports the Node built-in \"${specifier}\"`,\n actionable: false\n });\n continue;\n }\n\n const pkg = packageOf(specifier);\n\n // The exact specifier, not the package: `@rebasepro/server/functions`\n // is the portable subpath and is the thing being recommended.\n if (specifier === \"@rebasepro/server\") {\n // Not a portability problem in itself — the root barrel works\n // perfectly on Node — but it is the single edit that would let this\n // file move, and it is one line.\n issues.push({\n kind: \"root-barrel-import\",\n line,\n message: \"imports from \\\"@rebasepro/server\\\" — the whole framework, Node-only. \"\n + \"Use \\\"@rebasepro/server/functions\\\" for the authoring surface.\",\n actionable: false\n });\n continue;\n }\n\n const why = NODE_ONLY_PACKAGES.get(pkg);\n if (why) {\n issues.push({\n kind: \"node-only-package\",\n line,\n message: `imports \"${specifier}\", which needs ${why}`,\n actionable: false\n });\n }\n }\n\n for (const line of moduleScopeEnvReads(code)) {\n issues.push({\n kind: \"module-scope-env\",\n line,\n message: \"reads process.env at module scope. If the variable is unset the whole file \"\n + \"fails to import, and the loader reports that as a skipped function — read it \"\n + \"inside the handler instead (`requireEnv(c, \\\"NAME\\\")`, or `lazyResource`).\",\n actionable: true\n });\n }\n\n return {\n name,\n file,\n issues,\n // The advisory import-path finding does not make a function unportable —\n // it is the same code either way, reachable through a heavier door.\n portable: issues.every(issue => issue.kind === \"root-barrel-import\"),\n resourceImports: resourceImports(withStrings)\n };\n}\n\n/**\n * Analyse every function in a directory.\n *\n * @param functionsDir Absolute path to the functions directory.\n * @param projectRoot For rendering paths people recognise.\n */\nexport function analyseFunctionsDirectory(functionsDir: string, projectRoot: string): FunctionPortability[] {\n return functionFiles(functionsDir).map(fileName => {\n const absolute = path.join(functionsDir, fileName);\n const source = fs.readFileSync(absolute, \"utf8\");\n return analyseFunctionSource(\n source,\n path.basename(fileName, path.extname(fileName)),\n path.relative(projectRoot, absolute)\n );\n });\n}\n\n/**\n * The lines to print after a build, or nothing at all.\n *\n * Silent when every function is portable and nothing is actionable, because a\n * report that always prints is a report nobody reads. Actionable findings are\n * always shown; the rest collapse to a single count with a pointer.\n */\nexport function summarisePortability(results: FunctionPortability[]): string[] {\n if (results.length === 0) return [];\n\n const actionable = results.flatMap(result =>\n result.issues.filter(issue => issue.actionable).map(issue => ({ result, issue })));\n const nodeOnly = results.filter(result => !result.portable);\n\n const lines: string[] = [];\n\n for (const { result, issue } of actionable) {\n lines.push(` ⚠ ${result.file}:${issue.line} — ${issue.message}`);\n }\n\n if (nodeOnly.length > 0) {\n const names = nodeOnly.map(result => result.name).join(\", \");\n lines.push(\n ` ℹ ${nodeOnly.length} of ${results.length} function(s) depend on Node: ${names}`\n );\n lines.push(\" Fine for any Node deployment — recorded in the manifest so a host knows.\");\n }\n\n return lines;\n}\n","/**\n * Building a project bundle.\n *\n * A bundle is the deployable form of a project: compiled collections, functions,\n * crons and schema, plus a generated manifest describing exactly what it needs\n * to run. It contains no Dockerfile and no repository — the runtime is supplied\n * separately, which is what allows a project to be moved onto a patched runtime\n * without being rebuilt.\n *\n * Compilation runs through a generated tsconfig rooted at the project directory,\n * so the output mirrors the source layout (`config/…`, `backend/functions/…`)\n * and every path in the manifest is predictable. Letting each workspace package\n * emit into its own `dist/` would have meant guessing at three different\n * layouts, since `rootDir` differs between the template flavours.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { createRequire } from \"module\";\nimport { spawnSync } from \"child_process\";\nimport { execa } from \"execa\";\nimport chalk from \"chalk\";\nimport {\n BUNDLE_FORMAT_VERSION,\n RUNTIME_CONTRACT_VERSION,\n computeSchemaVersion,\n findStorageSuffixCollision,\n parseEnvBoolean,\n type CollectionConfig,\n type ResourceGraph,\n type NativeDependency,\n type RebaseBundleManifest,\n type RebaseBundleFunction,\n type RebaseBackendAppConfig\n} from \"@rebasepro/types\";\nimport { resolveBackendPaths } from \"./manifest\";\nimport { cliVersion } from \"./utils/version\";\nimport { toolStdio } from \"./utils/tool-stdio\";\nimport { analyseFunctionsDirectory, summarisePortability } from \"./function-portability\";\nimport {\n getActiveBackendPlugin,\n resolveLocalBin,\n resolvePluginCliScript,\n resolveTsx\n} from \"./utils/project\";\n\nexport const DEFAULT_BUNDLE_DIR = \"dist-bundle\";\n\nexport interface BuildBundleOptions {\n projectRoot: string;\n appName: string;\n app: RebaseBackendAppConfig;\n /** Output directory, absolute or relative to the project root. */\n outDir?: string;\n /** Runtime range from the manifest, recorded for compatibility checks. */\n runtimeRange: string;\n /**\n * The `storage` block of `rebase.json` — which buckets this project uses.\n *\n * Passed in rather than re-read here so `rebase.json` is parsed and validated\n * once, by the command that owns it.\n */\n /**\n * The project's resource graph, derived from its config.\n *\n * Recorded in the bundle manifest so a host can read what the project needs\n * without running it — which is what lets a console show \"wants a `media`\n * bucket, has none\" before a first deploy has produced anything.\n */\n resources?: ResourceGraph;\n /**\n * Install the declared dependencies into the bundle at build time.\n *\n * Omitted means \"when it is safe to\" — which is every bundle whose closure\n * has no native code. `false` is the escape hatch for a build that must not\n * shell out to npm at all (an air-gapped CI, a offline reproducibility\n * check); the bundle still works, it simply installs at boot as before.\n */\n vendor?: boolean;\n /** Skip type checking. Faster, and strictly worse — for iteration only. */\n skipTypeCheck?: boolean;\n /** Skip regenerating the Drizzle schema from the collections. */\n skipSchema?: boolean;\n /** Emit progress. */\n log?: (message: string) => void;\n /**\n * Keep stdout for the caller's result: the compiler's output, and every\n * warning the build prints, go to stderr. See `toolStdio`.\n */\n quietStdout?: boolean;\n}\n\nexport interface BuildBundleResult {\n outDir: string;\n manifest: RebaseBundleManifest;\n collectionCount: number;\n /**\n * Whether the dependency tree was installed into the bundle, and why not\n * when it was not. Reported rather than silent: \"your pods will take a\n * minute to start\" is a consequence a developer should hear at build time,\n * not discover during an incident.\n */\n vendor: VendorResult;\n}\n\n/** Packages whose presence means the bundle cannot run on a stock runtime image. */\nconst KNOWN_NATIVE_PACKAGES = new Set([\n \"sharp\",\n \"canvas\",\n \"bcrypt\",\n \"argon2\",\n \"node-sass\",\n \"sqlite3\",\n \"better-sqlite3\",\n \"grpc\",\n \"@grpc/grpc-js-native\",\n \"re2\",\n \"sodium-native\",\n \"libpq\",\n \"pg-native\"\n]);\n\n/** Dependencies supplied by the runtime image itself, not by the bundle. */\nconst RUNTIME_PROVIDED = new Set([\n \"@rebasepro/server\",\n \"@rebasepro/types\",\n \"@rebasepro/client\",\n \"@rebasepro/common\",\n \"@rebasepro/utils\",\n \"hono\",\n \"@hono/node-server\",\n \"typescript\",\n \"tsx\",\n // See entrypoint.mjs: a second zod makes `loadEnv({ extend })` reject every\n // value carrying a `.default()`, and the deploy reports success with no\n // crons running.\n \"zod\"\n]);\n\nfunction log(options: BuildBundleOptions, message: string): void {\n (options.log ?? ((m: string) => console.log(m)))(message);\n}\n\n/**\n * A line the build says to the person running it — a warning, or what it left\n * out — which progress callbacks may drop and this does not: stdout, or stderr\n * when stdout carries the caller's result.\n */\nfunction say(options: BuildBundleOptions, line: string): void {\n if (options.quietStdout) console.error(line);\n else console.log(line);\n}\n\n/**\n * Every `node_modules/@types` directory the project can see.\n *\n * Type roots normally resolve by walking up from the tsconfig's own directory,\n * which breaks here for two reasons: the generated config lives in `.rebase/`,\n * and a pnpm workspace puts `@types/node` inside the *package* that depends on\n * it (`config/node_modules/@types`) rather than at the project root. Listing them\n * explicitly, as absolute paths, sidesteps both.\n */\nfunction discoverTypeRoots(projectRoot: string): string[] {\n const candidates: string[] = [];\n\n for (const relative of [\".\", \"config\", \"backend\", \"frontend\"]) {\n candidates.push(path.join(projectRoot, relative, \"node_modules\", \"@types\"));\n }\n\n // Walk up as well, for a project nested inside a larger workspace.\n let dir = projectRoot;\n for (let i = 0; i < 4; i++) {\n const parent = path.dirname(dir);\n if (parent === dir) break;\n candidates.push(path.join(parent, \"node_modules\", \"@types\"));\n dir = parent;\n }\n\n return candidates.filter(candidate => fs.existsSync(candidate));\n}\n\n/**\n * Read a tsconfig's own `compilerOptions`.\n *\n * Parsed with the project's own TypeScript, because a tsconfig is not JSON: it\n * permits comments and trailing commas. Hand-rolled comment stripping gets this\n * wrong in a way that is easy to miss — a `paths` entry like\n * `\"@acme/types/*\": [\"src/*\"]` contains the character sequence that opens a\n * block comment, so a regex happily eats the rest of the file and the result\n * parses as *something*, just not the config the developer wrote.\n *\n * One level only, and only `paths` is used from it.\n */\nasync function readCompilerOptions(\n projectRoot: string,\n file: string\n): Promise<Record<string, unknown> | undefined> {\n if (!fs.existsSync(file)) return undefined;\n\n const text = fs.readFileSync(file, \"utf8\");\n\n try {\n const require = createRequire(path.join(projectRoot, \"package.json\"));\n const ts = require(\"typescript\") as {\n parseConfigFileTextToJson(fileName: string, text: string): {\n config?: { compilerOptions?: Record<string, unknown> };\n error?: unknown;\n };\n };\n const { config } = ts.parseConfigFileTextToJson(file, text);\n return config?.compilerOptions;\n } catch {\n // TypeScript is not resolvable from the project root. Fall back to\n // stripping whole-line comments only — never block comments, for the\n // reason above — and give up quietly if that still is not valid JSON.\n try {\n const parsed = JSON.parse(text.replace(/^\\s*\\/\\/.*$/gm, \"\")) as {\n compilerOptions?: Record<string, unknown>;\n };\n return parsed.compilerOptions;\n } catch {\n return undefined;\n }\n }\n}\n\n/**\n * Drop path aliases that resolve outside the project.\n *\n * A monorepo commonly aliases its workspace packages to their **source**\n * (`\"@acme/types\": [\"packages/types/src/index.ts\"]`) so editors jump to real\n * files. That is right for developing the monorepo and wrong for building a\n * bundle: it drags foreign `.ts` files into the program, none of which are under\n * the project's `rootDir`, and the compile fails on files the developer never\n * asked to build.\n *\n * A bundle is built against *installed packages*. Aliases pointing inside the\n * project are kept, because those are the project's own code.\n */\nfunction filterProjectPaths(\n baseDir: string,\n projectRoot: string,\n paths: Record<string, string[]>,\n baseUrl: string\n): { kept: Record<string, string[]>; dropped: string[] } {\n const kept: Record<string, string[]> = {};\n const dropped: string[] = [];\n\n for (const [alias, targets] of Object.entries(paths)) {\n if (!Array.isArray(targets)) continue;\n const resolved = targets.map(target => path.resolve(baseUrl, target));\n const allInside = resolved.every(target => {\n const relative = path.relative(projectRoot, target);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n });\n if (allInside) {\n kept[alias] = resolved.map(target => {\n const relative = path.relative(baseDir, target);\n return relative.split(path.sep).join(\"/\");\n });\n } else {\n dropped.push(alias);\n }\n }\n\n return { kept,\ndropped };\n}\n\n/**\n * Compose the tsconfig used to compile the bundle.\n *\n * Extends the config package's own tsconfig when there is one, so the project's\n * choices about target, JSX and strictness are respected. It has to be `extends`\n * rather than a copy of `compilerOptions`: TypeScript resolves relative paths\n * against the file they were written in, so copying a value like\n * `baseUrl: \"../../\"` into a config in a different directory silently repoints\n * it at the wrong place.\n */\nasync function writeBundleTsconfig(\n projectRoot: string,\n outDir: string,\n includes: string[],\n options: BuildBundleOptions\n): Promise<string> {\n const skipTypeCheck = options.skipTypeCheck === true;\n // Paths written *here* resolve against this file's directory. Posix\n // separators, because tsconfig wants them on every platform.\n const tsconfigDir = path.join(projectRoot, \".rebase\");\n const fromTsconfig = (target: string): string => {\n const relative = path.relative(tsconfigDir, path.resolve(projectRoot, target));\n return relative.split(path.sep).join(\"/\");\n };\n\n const configTsconfigPath = path.join(projectRoot, \"config\", \"tsconfig.json\");\n const extendsFrom = fs.existsSync(configTsconfigPath)\n ? fromTsconfig(path.join(\"config\", \"tsconfig.json\"))\n : undefined;\n\n // Neutralize aliases that escape the project (see `filterProjectPaths`).\n let pathOverrides: Record<string, unknown> = {};\n const baseOptions = await readCompilerOptions(projectRoot, configTsconfigPath);\n if (baseOptions?.paths && typeof baseOptions.paths === \"object\") {\n const baseDir = path.dirname(configTsconfigPath);\n const baseUrl = path.resolve(\n baseDir,\n typeof baseOptions.baseUrl === \"string\" ? baseOptions.baseUrl : \".\"\n );\n const { kept, dropped } = filterProjectPaths(\n tsconfigDir,\n projectRoot,\n baseOptions.paths as Record<string, string[]>,\n baseUrl\n );\n pathOverrides = { baseUrl: fromTsconfig(\".\"),\npaths: kept };\n if (dropped.length > 0) {\n say(options, chalk.dim(\n ` ignoring ${dropped.length} path alias(es) pointing outside the project ` +\n `(${dropped.join(\", \")}) — resolving those from node_modules instead`\n ));\n }\n }\n\n const compilerOptions: Record<string, unknown> = {\n // Defaults, used when there is no project tsconfig to extend. When there\n // is one, its values win over these and are overridden only by the block\n // below.\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n lib: [\"ES2022\"],\n jsx: \"react-jsx\",\n allowSyntheticDefaultImports: true,\n esModuleInterop: true,\n resolveJsonModule: true,\n forceConsistentCasingInFileNames: true,\n\n // Everything below is the bundle's contract and is not negotiable.\n rootDir: fromTsconfig(\".\"),\n outDir: fromTsconfig(path.relative(projectRoot, outDir) || \".\"),\n typeRoots: discoverTypeRoots(projectRoot),\n ...pathOverrides,\n declaration: false,\n declarationMap: false,\n sourceMap: true,\n noEmit: false,\n skipLibCheck: true,\n // The runtime imports the emitted files directly with Node's ESM loader,\n // so they stay ES modules regardless of what the project targets for its\n // own builds.\n allowJs: true,\n ...(skipTypeCheck ? { noCheck: true } : {})\n };\n\n const tsconfig = {\n ...(extendsFrom ? { extends: extendsFrom } : {}),\n compilerOptions,\n include: includes.map(fromTsconfig),\n exclude: [\n \"node_modules\",\n \"**/*.test.ts\",\n \"**/*.spec.ts\",\n \"**/dist/**\",\n DEFAULT_BUNDLE_DIR\n ].map(pattern => (pattern.startsWith(\"**\") ? pattern : fromTsconfig(pattern)))\n };\n\n fs.mkdirSync(tsconfigDir, { recursive: true });\n const tsconfigPath = path.join(tsconfigDir, \"tsconfig.bundle.json\");\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2), \"utf8\");\n return tsconfigPath;\n}\n\n/**\n * Whether the compiled config package exports a `storageAuthorize` hook.\n *\n * Recorded in the manifest so a host can refuse a deploy that would enable file\n * storage with no access model, rather than let the runtime's boot guard turn it\n * into a crash loop the developer cannot read.\n *\n * Read from the *compiled* index, deliberately: that is the exact module the\n * runtime imports and reads the export off, so this cannot disagree with what\n * actually happens at boot. It is a textual check rather than an import because\n * a freshly built bundle cannot resolve its own dependencies until it is\n * deployed — the same reason schema hashing reads source.\n *\n * Errs toward `false`: a missed detection costs a deploy rejection whose message\n * says exactly how to proceed, while a false positive would hand back the crash\n * loop this exists to prevent.\n */\nexport function detectStorageAuthorize(compiledConfigDir: string, depth = 0): boolean {\n const indexPath = [\".js\", \".mjs\", \".ts\"]\n .map(ext => path.join(compiledConfigDir, `index${ext}`))\n .find(candidate => fs.existsSync(candidate));\n if (!indexPath) return false;\n return moduleExportsStorageAuthorize(indexPath, depth);\n}\n\n/**\n * Whether one compiled module re-exports or defines `storageAuthorize`.\n *\n * Split out from {@link detectStorageAuthorize} so a wildcard re-export can be\n * followed. `export * from \"./storage.js\"` is an ordinary way to write a config\n * barrel, and treating it as \"no hook\" rejected deploys that were correct — with\n * a message telling the developer to add a hook they had already written.\n */\nfunction moduleExportsStorageAuthorize(modulePath: string, depth: number): boolean {\n let source: string;\n try {\n source = fs.readFileSync(modulePath, \"utf8\");\n } catch {\n return false;\n }\n\n // `export const/let/var/function/async function storageAuthorize`\n if (/\\bexport\\s+(?:async\\s+)?(?:const|let|var|function)\\s+storageAuthorize\\b/.test(source)) {\n return true;\n }\n // `export { storageAuthorize }` / `export { x as storageAuthorize }`,\n // including re-export forms (`export { storageAuthorize } from \"./storage\"`).\n for (const clause of source.matchAll(/\\bexport\\s*\\{([^}]*)\\}/g)) {\n const names = clause[1].split(\",\").map(entry => {\n const parts = entry.split(/\\bas\\b/);\n return parts[parts.length - 1].trim();\n });\n if (names.includes(\"storageAuthorize\")) return true;\n }\n\n // `export * from \"./storage.js\"` — follow it. Bounded to a few levels: a\n // barrel of barrels is realistic, an infinite chain is not, and the cost of\n // giving up is a rejection message rather than a wrong answer.\n if (depth < 3) {\n for (const clause of source.matchAll(/\\bexport\\s*\\*\\s*from\\s*[\"']([^\"']+)[\"']/g)) {\n const specifier = clause[1];\n if (!specifier.startsWith(\".\")) continue;\n const resolved = resolveRelativeModule(path.dirname(modulePath), specifier);\n if (resolved && moduleExportsStorageAuthorize(resolved, depth + 1)) return true;\n }\n }\n return false;\n}\n\n/**\n * Resolve a relative ESM specifier to a file on disk.\n *\n * Compiled output carries explicit `.js` extensions, but the same function reads\n * TypeScript sources during a source boot, where the specifier may be\n * extensionless or point at a directory index.\n */\nfunction resolveRelativeModule(fromDir: string, specifier: string): string | null {\n const base = path.resolve(fromDir, specifier);\n const candidates = [\n base,\n `${base}.js`,\n `${base}.mjs`,\n `${base}.ts`,\n path.join(base, \"index.js\"),\n path.join(base, \"index.mjs\"),\n path.join(base, \"index.ts\")\n ];\n for (const candidate of candidates) {\n try {\n if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return candidate;\n } catch {\n continue;\n }\n }\n // A `.js` specifier that only exists as `.ts` — the shape every compiled-from-\n // TypeScript barrel has when this runs against sources rather than output.\n if (/\\.js$/.test(base)) {\n const asTs = base.replace(/\\.js$/, \".ts\");\n try {\n if (fs.existsSync(asTs) && fs.statSync(asTs).isFile()) return asTs;\n } catch {\n return null;\n }\n }\n return null;\n}\n\n/**\n * Detect native code in the dependency closure.\n *\n * Walks declared runtime dependencies breadth-first through `node_modules`,\n * flagging anything with a `binding.gyp`, a prebuilt `.node` binary, or an\n * install script that builds one. The managed runtime cannot run these: a\n * binary compiled for one image will not load in another, and finding that out\n * at deploy time is far better than in a crash loop.\n *\n * The walk is bounded. A dependency graph can be enormous, and this is a\n * heuristic gate whose false negatives are caught at deploy time anyway.\n */\nexport function detectNativeDependencies(\n projectRoot: string,\n declared: Record<string, string>,\n limit = 2000\n): NativeDependency[] {\n const found: NativeDependency[] = [];\n const seen = new Set<string>();\n const queue = Object.keys(declared);\n let visited = 0;\n\n const searchRoots = [\n path.join(projectRoot, \"node_modules\"),\n path.join(projectRoot, \"backend\", \"node_modules\"),\n path.join(projectRoot, \"config\", \"node_modules\")\n ].filter(dir => fs.existsSync(dir));\n\n while (queue.length > 0 && visited < limit) {\n const name = queue.shift()!;\n if (seen.has(name)) continue;\n seen.add(name);\n visited++;\n\n if (KNOWN_NATIVE_PACKAGES.has(name)) {\n found.push({ name,\nreason: \"known native module\" });\n continue;\n }\n\n const packageDir = searchRoots\n .map(root => path.join(root, ...name.split(\"/\")))\n .find(dir => fs.existsSync(path.join(dir, \"package.json\")));\n\n if (!packageDir) continue;\n\n let pkg: {\n dependencies?: Record<string, string>;\n scripts?: Record<string, string>;\n gypfile?: boolean;\n };\n try {\n pkg = JSON.parse(fs.readFileSync(path.join(packageDir, \"package.json\"), \"utf8\"));\n } catch {\n continue;\n }\n\n if (pkg.gypfile || fs.existsSync(path.join(packageDir, \"binding.gyp\"))) {\n found.push({ name,\nreason: \"builds a native addon (binding.gyp)\" });\n continue;\n }\n\n const install = `${pkg.scripts?.install ?? \"\"} ${pkg.scripts?.preinstall ?? \"\"} ${pkg.scripts?.postinstall ?? \"\"}`;\n if (/node-gyp|prebuild|node-pre-gyp|cmake-js/.test(install)) {\n found.push({ name,\nreason: \"install script compiles native code\" });\n continue;\n }\n\n if (hasNodeBinary(packageDir)) {\n found.push({ name,\nreason: \"ships a prebuilt .node binary\" });\n continue;\n }\n\n for (const dep of Object.keys(pkg.dependencies ?? {})) {\n if (!seen.has(dep)) queue.push(dep);\n }\n }\n\n return found;\n}\n\n/** Shallow scan for `.node` binaries — deep enough for the usual `build/Release`. */\nfunction hasNodeBinary(dir: string, depth = 0): boolean {\n if (depth > 3) return false;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return false;\n }\n for (const entry of entries) {\n if (entry.isFile() && entry.name.endsWith(\".node\")) return true;\n if (entry.isDirectory() && entry.name !== \"node_modules\" && entry.name !== \".bin\") {\n if (hasNodeBinary(path.join(dir, entry.name), depth + 1)) return true;\n }\n }\n return false;\n}\n\n/**\n * Whether a dependency name resolves to a package *inside this repository* — a\n * workspace package rather than a registry one.\n *\n * The bundle's declared deps are installed with `npm install` from the public\n * registry beside the bundle at boot. A workspace package is not there, so\n * declaring it guarantees a boot-time install failure. The most common case is\n * the standard `config` package: the backend depends on it by name, but it is\n * *carried in the bundle* (as `entry.config`), so it must never also be an npm\n * dependency. Projects often express this as a `workspace:` range — caught\n * separately — but a plain `\"*\"` against a workspace symlink is just as common\n * and looks like a registry range, so the symlink is what actually settles it.\n *\n * Detection: the installed `node_modules/<name>` is a symlink whose real path is\n * inside the project and not within a pnpm virtual store (`.pnpm`). That is\n * exactly a workspace link and nothing else.\n */\nfunction resolvesToWorkspacePackage(projectRoot: string, name: string): boolean {\n // Resolve the root's own symlinks too: on macOS a temp/checkout path under\n // `/var/...` realpaths to `/private/var/...`, so comparing a realpath'd link\n // target against a non-realpath'd root would never match.\n let realRoot: string;\n try {\n realRoot = fs.realpathSync(projectRoot);\n } catch {\n realRoot = projectRoot;\n }\n\n for (const base of [projectRoot, path.join(projectRoot, \"backend\"), path.join(projectRoot, \"config\")]) {\n const link = path.join(base, \"node_modules\", name);\n try {\n // A workspace link is a *symlink*; a normal (non-pnpm) registry\n // install is a real directory inside node_modules, which would also\n // sit \"inside the repo\" — so the symlink is what separates the two.\n if (!fs.lstatSync(link).isSymbolicLink()) continue;\n const real = fs.realpathSync(link);\n const insideRepo = real.startsWith(realRoot + path.sep);\n // pnpm links registry packages into its virtual store; those live\n // under node_modules/.pnpm and are not workspace packages.\n const inStore = real.includes(`${path.sep}.pnpm${path.sep}`)\n || real.includes(`${path.sep}node_modules${path.sep}`);\n if (insideRepo && !inStore) return true;\n } catch {\n // No such entry, broken link, or race: let it be declared.\n }\n }\n return false;\n}\n\n/**\n * The manifests a bundle's declared dependencies come from, least specific first.\n *\n * Order is the whole point. `collectDeclaredDependencies` lets a later manifest\n * win, and the app — `backend/` — is the one whose code was written and\n * typechecked against the range it names. The project root is a workspace root:\n * it exists to hold scripts and the tooling every workspace shares, and its\n * ranges were never exercised by the code that ends up in the bundle. It used to\n * be read last, so a scaffold declaring `dotenv ^16` at the root and `^17.4.2`\n * in the backend shipped a manifest telling the managed runtime to install 16.\n */\nconst BUNDLE_DEP_MANIFESTS = [\"package.json\", \"config/package.json\", \"backend/package.json\"];\n\n/**\n * Specifiers the registry the managed runtime installs from cannot resolve.\n *\n * `workspace:` is handled separately (it is normal and expected inside this\n * repo's own projects); everything here is a specifier that works on the\n * developer's disk and nowhere else. The runtime installs `deps.declared` from\n * npm with no access to the machine the bundle was built on, so a `file:` or a\n * `git+` range is a deploy-time install failure — the worst place to find out.\n */\nconst NON_REGISTRY_PROTOCOLS = [\"file:\", \"link:\", \"portal:\", \"git+\", \"git:\", \"github:\"];\n\n/** Whether a range names something npm could not install from the registry. */\nfunction nonRegistrySpecifier(version: string): string | null {\n const trimmed = version.trim();\n for (const protocol of NON_REGISTRY_PROTOCOLS) {\n if (trimmed.startsWith(protocol)) return protocol;\n }\n // A bare path — `../shared`, `./vendor/lib`, `/opt/lib` — which npm accepts\n // as a local directory and the registry has never heard of.\n if (/^\\.{0,2}\\//.test(trimmed)) return \"a filesystem path\";\n return null;\n}\n\n/**\n * Collect the runtime dependencies a bundle needs installed beside it.\n *\n * Packages the runtime image already provides are excluded — reinstalling a\n * second copy of the server next to the one running the process is at best\n * wasted space and at worst a version conflict. Workspace packages are excluded\n * too: they are not on the registry the runtime installs from, and the project's\n * own config package already travels inside the bundle.\n *\n * Throws when a declared range is not something the registry can resolve, or\n * when two manifests declare a name at ranges nothing satisfies. The\n * alternative is a bundle that builds green and fails at the deploy's install\n * step, minutes later and on a machine the developer cannot see. `rebase build`\n * reports both in its own words first; this is the backstop for every other\n * caller, `rebase cloud deploy` included.\n */\nexport function collectDeclaredDependencies(projectRoot: string): Record<string, string> {\n const declared: Record<string, string> = {};\n\n const conflicts = detectDeclaredDepConflicts(projectRoot);\n if (conflicts.length > 0) {\n const described = conflicts\n .map(c => {\n const [a, b] = c.declarations;\n return `${c.name}: ${a.range} (${a.file}) vs ${b.range} (${b.file})`;\n })\n .join(\"; \");\n throw new Error(\n `No single version satisfies every range this project declares — ${described}. `\n + \"The bundle installs one of them and the rest of the project was built against \"\n + \"the other. Declare one range, in the app that uses it.\"\n );\n }\n\n for (const relative of BUNDLE_DEP_MANIFESTS) {\n const file = path.join(projectRoot, relative);\n if (!fs.existsSync(file)) continue;\n let pkg: { dependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(fs.readFileSync(file, \"utf8\")) as typeof pkg;\n } catch {\n // Unparseable package.json: nothing to declare from it.\n continue;\n }\n for (const [name, version] of Object.entries(pkg.dependencies ?? {})) {\n if (RUNTIME_PROVIDED.has(name)) continue;\n // A workspace protocol means nothing outside this repository.\n if (typeof version === \"string\" && version.startsWith(\"workspace:\")) continue;\n // A plain range that nonetheless resolves to an in-repo workspace\n // package (e.g. `\"config\": \"*\"` symlinked to `../../config`) —\n // the runtime cannot install it from the registry.\n if (resolvesToWorkspacePackage(projectRoot, name)) continue;\n const protocol = typeof version === \"string\" ? nonRegistrySpecifier(version) : null;\n // The registry-install e2e stands packed tarballs in for versions\n // that were never published, as `file:` ranges the scaffold and its\n // Dockerfile both carry, and then builds and boots the result. The\n // flag is the same one `init` reads to skip its release probe; it\n // is set by that harness and by nothing a user runs.\n if (protocol && parseEnvBoolean(process.env.REBASE_E2E) === true && protocol === \"file:\") {\n declared[name] = version;\n continue;\n }\n if (protocol) {\n throw new Error(\n `${relative} declares \"${name}\": \"${version}\", which the managed runtime `\n + `cannot install — ${protocol} resolves only on this machine. Publish the `\n + \"package to a registry and depend on it by version, or vendor its source \"\n + \"into the backend.\"\n );\n }\n declared[name] = version;\n }\n }\n\n return declared;\n}\n\n/** One dependency as some package.json in the project declares it. */\nexport interface DeclaredFrameworkDep {\n name: string;\n range: string;\n /** Project-relative package.json it was declared in. */\n file: string;\n}\n\n/** One name two of the bundle's manifests declare at ranges nothing satisfies. */\nexport interface DeclaredDepConflict {\n name: string;\n /** The two declarations, in manifest order. */\n declarations: [DeclaredFrameworkDep, DeclaredFrameworkDep];\n}\n\nexport interface FrameworkDepDrift {\n /** Declared at a version that can never reach the CLI's own. */\n behind: DeclaredFrameworkDep[];\n /**\n * The distinct lower bounds found across all declared `@rebasepro/*`, when\n * there is more than one — the project is pinning mixed-era framework\n * packages against each other.\n */\n disagreeing: string[];\n /**\n * Third-party names two bundle manifests declare at ranges no single version\n * satisfies. One of the two wins in `deps.declared` and the loser's code was\n * typechecked against a version the runtime will never install.\n */\n conflicting: DeclaredDepConflict[];\n}\n\n/**\n * Lowest version a range could resolve to, or null if it is not a range.\n *\n * Kept deliberately tiny and local. The published range grammar here is a caret,\n * a tilde, an exact version or a `>=` floor, and the alternative — a semver\n * dependency in the CLI — buys breadth this does not need.\n */\nfunction lowerBoundOf(range: string): [number, number, number] | null {\n const raw = range.trim().replace(/^[\\^~]/, \"\").replace(/^>=\\s*/, \"\").replace(/^v/, \"\");\n if (!/^\\d+(\\.\\d+){0,2}$/.test(raw)) return null;\n const [major, minor = 0, patch = 0] = raw.split(\".\").map(Number);\n return [major, minor, patch];\n}\n\n/** Highest version a range could resolve to (exclusive), or null. */\nfunction upperBoundOf(range: string): [number, number, number] | null {\n const trimmed = range.trim();\n const min = lowerBoundOf(trimmed);\n if (!min) return null;\n if (trimmed.startsWith(\">=\")) return null; // open — reaches anything\n const [major, minor, patch] = min;\n if (trimmed.startsWith(\"^\")) {\n if (major > 0) return [major + 1, 0, 0];\n if (minor > 0) return [0, minor + 1, 0];\n return [0, 0, patch + 1];\n }\n if (trimmed.startsWith(\"~\")) {\n return trimmed.replace(/^~v?/, \"\").split(\".\").length >= 2\n ? [major, minor + 1, 0]\n : [major + 1, 0, 0];\n }\n const parts = trimmed.replace(/^v/, \"\").split(\".\").length;\n if (parts === 1) return [major + 1, 0, 0];\n if (parts === 2) return [major, minor + 1, 0];\n return [major, minor, patch + 1];\n}\n\nfunction compareTriples(a: [number, number, number], b: [number, number, number]): number {\n for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] < b[i] ? -1 : 1;\n return 0;\n}\n\n/**\n * Whether a declared range could EVER resolve at or above `target`.\n *\n * The same question the control plane asks at intake, asked here first. Only a\n * range whose entire span sits below the target is reported — `^0.10.0` can\n * never cross to 0.12 whatever npm publishes — because a false alarm on a build\n * that would have worked trains people to ignore the warning that matters.\n */\nfunction canReach(range: string, target: string): boolean | null {\n const ceiling = upperBoundOf(range);\n const floor = lowerBoundOf(target);\n if (!floor || !lowerBoundOf(range)) return null;\n if (!ceiling) return true;\n return compareTriples(ceiling, floor) > 0;\n}\n\n/**\n * Whether no single published version can satisfy both ranges.\n *\n * Only a provable disagreement counts. Anything this tiny grammar cannot read —\n * a tag, an `||`, a `*` — returns false, because a build refused over a range\n * the CLI merely failed to parse is worse than the drift it was looking for.\n */\nfunction rangesDisjoint(a: string, b: string): boolean {\n const loA = lowerBoundOf(a);\n const loB = lowerBoundOf(b);\n if (!loA || !loB) return false;\n const hiA = upperBoundOf(a);\n const hiB = upperBoundOf(b);\n if (hiA && compareTriples(hiA, loB) <= 0) return true;\n if (hiB && compareTriples(hiB, loA) <= 0) return true;\n return false;\n}\n\n/**\n * Names two of the bundle's manifests declare at ranges nothing satisfies.\n *\n * `collectDeclaredDependencies` has to pick one — the app's — and the loser is\n * silent: the bundle tells the managed runtime to install a version the other\n * half of the project was never compiled against. The stock scaffold shipped\n * exactly that (`dotenv ^16` at the root, `^17.4.2` in `backend/`), so every\n * bundle built from a default project asked for dotenv 16.\n *\n * Scoped to the three manifests that feed `deps.declared`, and to their\n * `dependencies`: a `frontend/` that wants a different major of a build tool is\n * not this problem, and `devDependencies` never reach the bundle.\n */\nexport function detectDeclaredDepConflicts(projectRoot: string): DeclaredDepConflict[] {\n const seen = new Map<string, DeclaredFrameworkDep>();\n const conflicts: DeclaredDepConflict[] = [];\n\n for (const relative of BUNDLE_DEP_MANIFESTS) {\n const file = path.join(projectRoot, relative);\n if (!fs.existsSync(file)) continue;\n let pkg: { dependencies?: Record<string, string> };\n try {\n pkg = JSON.parse(fs.readFileSync(file, \"utf8\")) as typeof pkg;\n } catch {\n continue;\n }\n for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {\n if (typeof range !== \"string\") continue;\n // The image supplies these; a disagreement about them never reaches\n // the manifest, and `disagreeing` already reports the framework ones.\n if (RUNTIME_PROVIDED.has(name)) continue;\n if (range.startsWith(\"workspace:\")) continue;\n const first = seen.get(name);\n if (!first) {\n seen.set(name, { name,\nrange,\nfile: relative });\n continue;\n }\n if (first.range === range) continue;\n if (!rangesDisjoint(first.range, range)) continue;\n conflicts.push({ name,\ndeclarations: [first, { name,\nrange,\nfile: relative }] });\n }\n }\n\n return conflicts;\n}\n\n/**\n * Find `@rebasepro/*` dependencies pinned to a version older than this CLI.\n *\n * This is the only place a developer can be told. In development, every\n * `@rebasepro/*` resolves through pnpm's `link:`/`workspace:` overrides to the\n * checkout, so the version STRINGS in package.json are never exercised — the\n * project runs fine locally on whatever is on disk, and the declared numbers are\n * first honoured when the runtime npm-installs them from a bundle in the cloud.\n * A project scaffolded at 0.10.0 therefore keeps working on a developer's\n * machine indefinitely while being, in the cloud, a 0.10.0 driver.\n *\n * That matters because the image supplies only `@rebasepro/server`; the database\n * driver comes from these declarations and a newer runtime never updates it.\n * Every package.json is scanned, `dependencies` and `devDependencies` both,\n * because they have to be bumped together and the one that gets forgotten is the\n * one nobody looks at.\n */\nexport function detectFrameworkDepDrift(projectRoot: string, cliVersion: string): FrameworkDepDrift {\n const found: DeclaredFrameworkDep[] = [];\n\n for (const relative of [\n \"package.json\",\n \"backend/package.json\",\n \"config/package.json\",\n \"frontend/package.json\"\n ]) {\n const file = path.join(projectRoot, relative);\n if (!fs.existsSync(file)) continue;\n try {\n const pkg = JSON.parse(fs.readFileSync(file, \"utf8\")) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n for (const block of [pkg.dependencies, pkg.devDependencies]) {\n for (const [name, range] of Object.entries(block ?? {})) {\n if (!name.startsWith(\"@rebasepro/\")) continue;\n if (typeof range !== \"string\") continue;\n found.push({ name,\nrange,\nfile: relative });\n }\n }\n } catch {\n // Unparseable package.json: nothing to judge from it.\n }\n }\n\n const behind = found.filter(d => canReach(d.range, cliVersion) === false);\n\n // Mixed-era pins. Compared by lower bound rather than by string so `^0.12.0`\n // and `0.12.0` are not reported as a disagreement — they are not one.\n const bounds = new Set(\n found\n .map(d => lowerBoundOf(d.range))\n .filter((b): b is [number, number, number] => b != null)\n .map(b => b.join(\".\"))\n );\n\n return { behind,\ndisagreeing: bounds.size > 1 ? [...bounds].sort() : [],\nconflicting: detectDeclaredDepConflicts(projectRoot) };\n}\n\n/**\n * The `[start, end)` ranges of `//` and block comments in JavaScript source.\n *\n * `normalizeEsmSpecifiers` scans emitted output with a regular expression, and a\n * regular expression cannot tell a specifier from a specifier somebody wrote\n * about. The stock template ships one: `config/resources.ts` documents\n * `import { media } from \"../resources\";` inside a docblock, tsc preserves the\n * comment, and every `rebase build` of an untouched scaffold printed\n * `⚠ 1 import(s) could not be resolved`. A warning that is wrong on the default\n * project teaches people to ignore the warning that predicts a boot failure.\n *\n * Strings are tracked only so a `//` inside one — every `http://` in the tree —\n * does not open a comment that swallows the rest of the line. A `'` or `\"` span\n * ends at the newline as well as at its closing quote: a JavaScript string\n * cannot contain a raw newline, so a quote that reaches one was never a string\n * (a regex literal's, most likely) and the mistake must not run on.\n */\nexport function commentSpans(source: string): Array<[number, number]> {\n const spans: Array<[number, number]> = [];\n let quote: string | null = null;\n let i = 0;\n\n while (i < source.length) {\n const c = source[i];\n\n if (quote) {\n if (c === \"\\\\\") { i += 2; continue; }\n if (c === quote || (c === \"\\n\" && quote !== \"`\")) quote = null;\n i++;\n continue;\n }\n if (c === \"\\\"\" || c === \"'\" || c === \"`\") { quote = c; i++; continue; }\n\n if (c === \"/\" && source[i + 1] === \"/\") {\n const newline = source.indexOf(\"\\n\", i);\n const end = newline === -1 ? source.length : newline;\n spans.push([i, end]);\n i = end;\n continue;\n }\n if (c === \"/\" && source[i + 1] === \"*\") {\n const close = source.indexOf(\"*/\", i + 2);\n const end = close === -1 ? source.length : close + 2;\n spans.push([i, end]);\n i = end;\n continue;\n }\n i++;\n }\n return spans;\n}\n\n/**\n * Rewrite relative import specifiers in emitted JavaScript so Node can resolve them.\n *\n * TypeScript deliberately does not touch specifiers: `moduleResolution: \"bundler\"`\n * lets a project write `from \"./posts\"` or `from \"./collections\"`, and TypeScript\n * emits them unchanged on the assumption that a bundler will finish the job.\n * Nothing bundles a Rebase bundle — the runtime imports these files directly with\n * Node's ESM loader, which requires a full path with an extension and refuses\n * directory imports outright.\n *\n * Without this, adopting the bundle would mean asking every project written in\n * the (extremely common) extensionless style to rewrite all of its imports. The\n * rewrite is mechanical and verifiable: only relative specifiers are touched, and\n * only when the target file actually exists on disk.\n */\nexport function normalizeEsmSpecifiers(outDir: string): { rewritten: number; unresolved: string[] } {\n const unresolved: string[] = [];\n let rewritten = 0;\n\n // The specifier of a static import/export, a bare side-effect import, or a\n // dynamic import. Emitted output is not minified, so these forms are stable.\n const SPECIFIER = /(\\bfrom\\s*|\\bimport\\s*\\(\\s*|\\bimport\\s+)([\"'])(\\.[^\"']*)\\2/g;\n\n const walk = (dir: string): void => {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const full = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n if (entry.name === \"node_modules\") continue;\n walk(full);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n rewriteFile(full);\n }\n }\n };\n\n const rewriteFile = (file: string): void => {\n const original = fs.readFileSync(file, \"utf8\");\n const dir = path.dirname(file);\n const comments = commentSpans(original);\n const inComment = (at: number) => comments.some(([start, end]) => at >= start && at < end);\n\n const updated = original.replace(SPECIFIER, (match, prefix, quote, specifier, offset: number) => {\n // Prose, not code. Neither rewritten nor reported — see commentSpans.\n if (inComment(offset)) return match;\n\n // Already resolvable: has a real extension.\n if (/\\.(js|mjs|cjs|json|node)$/.test(specifier)) return match;\n\n const target = path.resolve(dir, specifier);\n\n if (fs.existsSync(`${target}.js`)) {\n rewritten++;\n return `${prefix}${quote}${specifier}.js${quote}`;\n }\n if (fs.existsSync(path.join(target, \"index.js\"))) {\n rewritten++;\n const suffix = specifier.endsWith(\"/\") ? \"index.js\" : \"/index.js\";\n return `${prefix}${quote}${specifier}${suffix}${quote}`;\n }\n\n // A `.ts` extension written explicitly in source becomes `.js` on disk.\n if (specifier.endsWith(\".ts\") && fs.existsSync(`${target.slice(0, -3)}.js`)) {\n rewritten++;\n return `${prefix}${quote}${specifier.slice(0, -3)}.js${quote}`;\n }\n\n unresolved.push(`${path.basename(file)} → ${specifier}`);\n return match;\n });\n\n if (updated !== original) {\n fs.writeFileSync(file, updated, \"utf8\");\n }\n };\n\n if (fs.existsSync(outDir)) walk(outDir);\n return { rewritten,\nunresolved };\n}\n\n/**\n * Remove a previous build so stale output cannot masquerade as current.\n *\n * The containment check matters because this is a recursive force-delete of a\n * path that came from a command-line flag: `rebase build --out ../..` would\n * otherwise erase the parent of the project. The manifest's own paths are\n * checked the same way; a flag deserves no less.\n */\nfunction cleanOutDir(projectRoot: string, outDir: string): void {\n const relative = path.relative(projectRoot, outDir);\n if (relative === \"\" || relative.startsWith(\"..\") || path.isAbsolute(relative)) {\n throw new Error(\n `Refusing to build into \"${outDir}\": the output directory must be inside the project.`\n );\n }\n\n if (fs.existsSync(outDir)) {\n fs.rmSync(outDir, { recursive: true,\nforce: true });\n }\n fs.mkdirSync(outDir, { recursive: true });\n}\n\n/**\n * Regenerate the Drizzle schema from the collections.\n *\n * Delegated to the database driver's own CLI — the same code `rebase schema\n * generate` runs — so there is one implementation of what a schema is. When no\n * driver is resolvable the build continues with a warning rather than failing:\n * a `baas` project has no schema to generate, and a project mid-install should\n * get a clear message rather than a hard stop.\n */\nasync function regenerateSchema(\n projectRoot: string,\n configDir: string,\n options: BuildBundleOptions\n): Promise<void> {\n const backendDir = path.join(projectRoot, \"backend\");\n if (!fs.existsSync(backendDir)) return;\n\n const plugin = getActiveBackendPlugin(backendDir);\n const script = plugin ? resolvePluginCliScript(backendDir, plugin) : null;\n if (!script) {\n log(options, chalk.dim(\" (no database driver found — skipping schema generation)\"));\n return;\n }\n\n const runner = script.endsWith(\".ts\") ? resolveTsx(projectRoot) : \"node\";\n if (!runner) {\n log(options, chalk.dim(\" (tsx not installed — skipping schema generation)\"));\n return;\n }\n\n const collectionsPath = path.join(\"..\", configDir, \"collections\");\n try {\n await execa(\n runner,\n [script, \"schema\", \"generate\", \"--collections\", collectionsPath],\n { cwd: backendDir,\nstdio: \"pipe\" }\n );\n log(options, chalk.dim(\" regenerated database schema from collections\"));\n } catch (err) {\n // A schema that cannot be generated means the bundle would carry a stale\n // one, and a stale schema is how a deploy quietly writes to the wrong\n // columns. Fail rather than ship it.\n const detail = err instanceof Error ? err.message : String(err);\n throw new Error(\n `Schema generation failed, so the bundle was not written.\\n${detail}\\n` +\n \"Run `rebase schema generate` to see the full output, or pass --skip-schema \" +\n \"if the committed schema is deliberately hand-maintained.\"\n );\n }\n}\n\n/**\n * A hand-written server entrypoint that a bundle does not use.\n *\n * `rebase dev` runs `backend/src/index.ts` whenever a project has one, so for\n * the whole of local development that file *is* the server and every route\n * written in it works. A bundle has no entrypoint of its own: the runtime boots\n * the bundle and mounts what the manifest points at — the config package,\n * functions, crons and the schema. The file is not compiled, not shipped, and\n * never imported.\n *\n * Nothing said so. A project with custom routes in its entrypoint built clean,\n * deployed green, and answered 404 on every one of them, with the file still\n * sitting in the repository looking exactly like the server.\n *\n * A project that means to own its server process runs `rebase eject`, which\n * writes an entrypoint, a Dockerfile and a compose file together and flips the\n * backend to `runtime: \"custom\"`. The warning names that route rather than\n * implying the file is a mistake — but eject writes *its* entrypoint, so the\n * warning must not read as \"eject will keep what you wrote here\".\n */\nexport function findUnusedServerEntry(projectRoot: string, functionsDir: string): string | undefined {\n // A project that relocated its functions keeps the entrypoint beside them,\n // so the second candidate is derived rather than only the default known.\n const candidates = [\n path.join(\"backend\", \"src\", \"index.ts\"),\n path.join(path.dirname(functionsDir), \"src\", \"index.ts\")\n ];\n\n const found = candidates.find(candidate => fs.existsSync(path.join(projectRoot, candidate)));\n return found ? found.split(path.sep).join(\"/\") : undefined;\n}\n\n/**\n * Compile and assemble a bundle.\n */\n/** What `composeBundleManifest` needs: every input, already resolved. */\nexport interface ComposeManifestInput {\n runtimeRange: string;\n builtAgainst: string;\n schemaVersion: string;\n appName: string;\n entry: RebaseBundleManifest[\"entry\"];\n collectionSlugs: string[];\n functions: RebaseBundleFunction[];\n nativeModules: NativeDependency[];\n declaresStorageAuthorize: boolean;\n resources: ResourceGraph | undefined;\n declaredDeps: Record<string, string>;\n build: RebaseBundleManifest[\"build\"];\n}\n\n/**\n * The bundle manifest, as a pure function of its inputs.\n *\n * Separated from `buildBundle` so the SHAPE a host reads can be pinned by a\n * test without compiling a project: `tooling/contracts/bundle-manifest.json`\n * is written from this with fixed inputs, and the control plane's own tests\n * read that file to prove they consume what the CLI emits. That contract is\n * what was missing when buckets moved from `storage.sources` into `resources`\n * and the control plane went on reading the old field for two weeks — every\n * declared bucket arriving as nothing, with both suites green.\n */\nexport function composeBundleManifest(input: ComposeManifestInput): RebaseBundleManifest {\n return {\n bundleFormat: BUNDLE_FORMAT_VERSION,\n runtime: {\n range: input.runtimeRange,\n builtAgainst: input.builtAgainst,\n contract: RUNTIME_CONTRACT_VERSION\n },\n schemaVersion: input.schemaVersion,\n app: input.appName,\n kind: \"backend\",\n entry: input.entry,\n collections: [...input.collectionSlugs].sort(),\n ...(input.functions.length > 0 ? { functions: input.functions } : {}),\n hooks: {\n native: input.nativeModules.length > 0,\n nativeModules: input.nativeModules.length > 0 ? input.nativeModules : undefined\n },\n storage: {\n // The hook, not the buckets. Those live in `resources` now, with\n // every other kind, so a host reads one list instead of one per\n // kind — which is what let databases and buckets drift apart.\n authorize: input.declaresStorageAuthorize\n },\n resources: input.resources,\n deps: { declared: input.declaredDeps },\n build: input.build\n };\n}\n\n/**\n * What a build refusing on {@link detectDeclaredDepConflicts} says: every name,\n * both ranges and where each is declared.\n */\nexport function describeDepConflicts(conflicts: DeclaredDepConflict[]): string {\n const lines = [`${conflicts.length} dependency range(s) no single version satisfies:`];\n for (const { name, declarations: [first, second] } of conflicts) {\n lines.push(` ${name}`, ` ${first.range} (${first.file})`, ` ${second.range} (${second.file})`);\n }\n lines.push(\n \" The bundle installs one range; the other half of the project was built against the other.\",\n \" Declare one range, in the app that uses it.\"\n );\n return lines.join(\"\\n\");\n}\n\nexport async function buildBundle(options: BuildBundleOptions): Promise<BuildBundleResult> {\n const { projectRoot, app, appName } = options;\n\n /* Two of this project's manifests want versions of one package that no\n single release satisfies.\n\n Fatal, and fatal before anything is built, because the bundle can only\n carry one of them: whichever manifest is read last wins, and the other\n half of the project was compiled against something the runtime will\n never install. There is no correct bundle to produce. Here rather than\n in a command, because every command that builds a bundle has to refuse\n it: `rebase cloud deploy` builds its own, and shipped what `rebase\n build` refused. */\n const conflicts = detectDeclaredDepConflicts(projectRoot);\n if (conflicts.length > 0) throw new Error(describeDepConflicts(conflicts));\n\n const paths = resolveBackendPaths(app, projectRoot);\n const outDir = path.resolve(projectRoot, options.outDir ?? DEFAULT_BUNDLE_DIR);\n\n const includes: string[] = [];\n const addIfExists = (relative: string, pattern: string): void => {\n if (fs.existsSync(path.join(projectRoot, relative))) includes.push(pattern);\n };\n\n // The whole config package, not just its collections: a headless project\n // has no `config/collections` but still ships `storageAuthorize` here.\n if (paths.hasConfig) {\n addIfExists(paths.config, `${paths.config}/**/*.ts`);\n }\n addIfExists(paths.functions, `${paths.functions}/**/*.ts`);\n addIfExists(paths.crons, `${paths.crons}/**/*.ts`);\n if (fs.existsSync(path.join(projectRoot, paths.schema))) {\n includes.push(paths.schema);\n }\n\n if (includes.length === 0) {\n throw new Error(\n `Nothing to build for app \"${appName}\". Expected a config directory at ` +\n `\"${paths.config}\" or functions at \"${paths.functions}\".`\n );\n }\n\n // Regenerate the Drizzle schema from the collections first.\n //\n // The template's backend build did this, so a project moving to the bundle\n // flow would otherwise silently ship whatever `schema.generated.ts` happened\n // to be on disk — stale by exactly the edits just made.\n if (paths.hasCollections && options.skipSchema !== true) {\n await regenerateSchema(projectRoot, paths.config, options);\n }\n\n // Say out loud what this build is NOT going to include. See\n // `findUnusedServerEntry` for why silence here was expensive.\n const unusedEntry = findUnusedServerEntry(projectRoot, paths.functions);\n if (unusedEntry) {\n const parts = [\n ...(paths.hasCollections ? [`${paths.config}/`] : []),\n `${paths.functions}/`,\n \"the schema\"\n ];\n const compiled = `${parts.slice(0, -1).join(\", \")} and ${parts[parts.length - 1]}`;\n say(options, chalk.yellow(` ⚠ ${unusedEntry} is not the bundle's entry point — it is not compiled or shipped.`));\n say(options, chalk.dim(` The runtime boots the bundle itself and mounts ${compiled}.`));\n say(options, chalk.dim(` Routes defined there will not exist once deployed: move them to ${paths.functions}/,`));\n say(options, chalk.dim(\" or run `rebase eject`, which writes an entrypoint of its own and owns\"));\n say(options, chalk.dim(\" the image — it does not adopt this file, and will not replace it\"));\n say(options, chalk.dim(\" without --force.\"));\n }\n\n log(options, chalk.dim(` compiling ${includes.length} source group(s) → ${path.relative(projectRoot, outDir)}/`));\n\n cleanOutDir(projectRoot, outDir);\n const tsconfigPath = await writeBundleTsconfig(projectRoot, outDir, includes, options);\n\n const tsc = resolveLocalBin(projectRoot, \"tsc\");\n if (!tsc) {\n throw new Error(\n \"TypeScript is not installed in this project. Run your package manager's install first.\"\n );\n }\n\n try {\n await execa(tsc, [\"-p\", tsconfigPath], { cwd: projectRoot,\nstdio: toolStdio(options.quietStdout) });\n } catch {\n throw new Error(\"TypeScript compilation failed — the bundle was not written.\");\n }\n\n // Node resolves these files directly, so their specifiers must be complete.\n const normalized = normalizeEsmSpecifiers(outDir);\n if (normalized.rewritten > 0) {\n log(options, chalk.dim(` resolved ${normalized.rewritten} relative import(s) for Node ESM`));\n }\n if (normalized.unresolved.length > 0) {\n say(options, chalk.yellow(\n ` ⚠ ${normalized.unresolved.length} import(s) could not be resolved to a file:`\n ));\n for (const item of normalized.unresolved.slice(0, 5)) {\n say(options, chalk.dim(` ${item}`));\n }\n if (normalized.unresolved.length > 5) {\n say(options, chalk.dim(` … and ${normalized.unresolved.length - 5} more`));\n }\n }\n\n // ── Inspect what was produced ────────────────────────────────────────────\n const compiledConfigDir = path.join(outDir, paths.config);\n const compiledCollectionsDir = path.join(compiledConfigDir, \"collections\");\n\n let collections: CollectionConfig[] = [];\n if (paths.hasCollections) {\n collections = await loadSourceCollections(path.join(projectRoot, paths.config, \"collections\"));\n if (collections.length === 0) {\n throw new Error(\n \"No collections were found in \" +\n `${path.join(paths.config, \"collections\")}. ` +\n \"Define at least one collection there, or remove the directory to have the \" +\n \"runtime introspect collections from the live database instead.\"\n );\n }\n if (!fs.existsSync(compiledCollectionsDir)) {\n throw new Error(\n \"Compilation produced no collections directory at \" +\n `${path.relative(projectRoot, compiledCollectionsDir)}.`\n );\n }\n }\n\n const declared = collectDeclaredDependencies(projectRoot);\n const nativeModules = detectNativeDependencies(projectRoot, declared);\n const declaresStorageAuthorize = detectStorageAuthorize(path.join(outDir, paths.config));\n\n // Resolve the declared buckets now, and refuse the build if two of them would\n // read the same environment variables. Catching it here means a rename, not a\n // tenant that silently served one bucket's files from another's credentials.\n const resourceGraph: ResourceGraph = options.resources ?? { version: 1, resources: [] };\n const storageSources = resourceGraph.resources\n .filter(r => r.kind === \"bucket\")\n .map(r => ({\n key: r.key,\n engine: r.engine,\n transport: r.transport,\n ...(r.label !== undefined ? { label: r.label } : {})\n }));\n const collision = findStorageSuffixCollision(storageSources.map(s => s.key));\n if (collision) {\n throw new Error(\n `Buckets \"${collision.a}\" and \"${collision.b}\" both map to the environment variable ` +\n `suffix \"${collision.suffix || \"(none)\"}\", so they would read each other's ` +\n \"configuration. Rename one of them.\"\n );\n }\n\n const schemaOut = paths.schema.replace(/\\.ts$/, \".js\");\n const relative = (target: string): string | undefined =>\n fs.existsSync(path.join(outDir, target)) ? target : undefined;\n\n // What is in the functions directory, and what each one needs from its\n // host. Read from the *source*, not the compiled output, because the answer\n // is about imports and `tsc` has already resolved some of them away.\n const functionReports = analyseFunctionsDirectory(\n path.join(projectRoot, paths.functions),\n projectRoot\n );\n const bundledFunctions: RebaseBundleFunction[] = functionReports.map(report => {\n const requires = [...new Set(\n report.issues\n .filter(issue => issue.kind === \"node-builtin\" || issue.kind === \"node-only-package\")\n .map(issue => issue.message)\n )];\n return {\n name: report.name,\n // The path as it exists *in the bundle*: sources are compiled 1:1,\n // so this is the same relative path with a `.js` extension.\n file: report.file.replace(/\\.ts$/, \".js\"),\n portable: report.portable,\n ...(requires.length > 0 ? { requires } : {})\n };\n });\n\n for (const line of summarisePortability(functionReports)) {\n say(options, line.trimStart().startsWith(\"⚠\") ? chalk.yellow(line) : chalk.dim(line));\n }\n\n const manifest = composeBundleManifest({\n runtimeRange: options.runtimeRange,\n builtAgainst: resolveServerVersion(projectRoot),\n // A build with no config directory genuinely does not know the schema —\n // collections are introspected from the live database at boot. Recording\n // a version here would stamp the hash of an empty list, and the runtime\n // would then serve that as the identity of whatever it actually found.\n // Empty means \"ask the runtime\", which is the honest answer.\n schemaVersion: paths.hasCollections ? computeSchemaVersion(collections) : \"\",\n appName,\n entry: {\n config: paths.hasConfig ? relative(paths.config) : undefined,\n collections: paths.hasCollections ? relative(path.join(paths.config, \"collections\")) : undefined,\n functions: relative(paths.functions),\n crons: relative(paths.crons),\n schema: relative(schemaOut),\n usersCollection: paths.hasCollections\n ? relative(path.join(paths.config, `${paths.usersCollection}.js`))\n : undefined\n },\n collectionSlugs: collections\n .map(collection => collection.slug)\n .filter((slug): slug is string => Boolean(slug)),\n functions: bundledFunctions,\n nativeModules,\n declaresStorageAuthorize,\n resources: resourceGraph,\n declaredDeps: declared,\n build: {\n cli: cliVersion(),\n node: process.versions.node.split(\".\")[0],\n createdAt: new Date().toISOString()\n }\n });\n\n fs.writeFileSync(\n path.join(outDir, \"manifest.json\"),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\"\n );\n\n // A package.json beside the bundle lets a deployment install exactly the\n // dependencies the project declared, with no access to the repository.\n fs.writeFileSync(\n path.join(outDir, \"package.json\"),\n `${JSON.stringify({\n name: \"rebase-bundle\",\n private: true,\n type: \"module\",\n dependencies: declared\n }, null, 2)}\\n`,\n \"utf8\"\n );\n\n const vendor = vendorDependencies({\n outDir,\n declared,\n nativeModules,\n // The driver is the one package the image does not supply, so it is the\n // one a vendored tree must actually contain.\n required: [getActiveBackendPlugin(path.join(projectRoot, \"backend\"))].filter(\n (name): name is string => Boolean(name)),\n requested: options.vendor\n });\n if (vendor.vendored) {\n manifest.deps.vendored = true;\n manifest.deps.vendorTarget = vendor.target;\n // Rewritten rather than assembled differently above: the install needs\n // the package.json this function already wrote, so the manifest cannot\n // know the answer until afterwards.\n fs.writeFileSync(\n path.join(outDir, \"manifest.json\"),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\"\n );\n }\n\n return { outDir,\nmanifest,\ncollectionCount: collections.length,\nvendor };\n}\n\n/** Default install target: what the published runtime image runs. */\nexport const VENDOR_TARGET_OS = \"linux\";\nexport const VENDOR_TARGET_CPU = \"x64\";\n\nexport interface VendorResult {\n vendored: boolean;\n target?: { os: string; cpu: string; node: string };\n /** Why nothing was installed. Present exactly when `vendored` is false. */\n skipped?: string;\n /** Size of the installed tree on disk, when one was installed. */\n bytes?: number;\n}\n\n/**\n * Where a vendored bundle starts being too big to upload.\n *\n * The control plane refuses a bundle over 100 MB, and that ceiling is not\n * arbitrary or easily raised: its pod has a 512Mi memory limit and the upload\n * route holds the body while it writes it, so the cap protects the process that\n * also serves the console, deploys and billing. Vendoring is the one change that\n * can push a bundle near it.\n *\n * So the warning is here, at build time, where the remedy is one flag away —\n * rather than at deploy time as a 413 nobody can act on without rebuilding. The\n * threshold sits below the real cap because this measures the tree on disk and\n * the upload is compressed: crossing it means \"getting close\", not \"will fail\".\n */\nexport const VENDOR_SIZE_WARN_BYTES = 150 * 1024 * 1024;\n\n/**\n * Where vendoring stops being an optimisation and becomes a bundle nobody can\n * deploy.\n *\n * Past this, shipping the tree anyway trades a faster cold start for a 413 — and\n * the 413 arrives at deploy time, after a build nobody watches, with a remedy\n * (`--no-vendor`) that requires knowing this happened. Unvendoring here costs\n * 40–60s of cold start and produces a bundle that uploads; that is the better\n * side of the trade to be on by default.\n *\n * 200 MB assumes a **2x** floor on compression, which is pessimistic for a tree\n * of JavaScript (3–5x is typical) and deliberately so: source maps and prebuilt\n * binaries compress far worse than source, and the failure this prevents is\n * asymmetric — a bundle refused at the door versus a minute of cold start.\n * `--vendor` overrides it, for a deploy path with no upload at all (a Dockerfile\n * built from source, where the tree is copied into an image and the control\n * plane never sees it).\n */\nexport const VENDOR_SIZE_MAX_BYTES = 200 * 1024 * 1024;\n\n/** Bytes on disk under `dir`. Bounded so a pathological tree cannot hang a build. */\nfunction directorySize(dir: string, budget = 200_000): number {\n let total = 0;\n let visited = 0;\n const stack = [dir];\n while (stack.length > 0 && visited < budget) {\n const current = stack.pop()!;\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(current, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n visited++;\n const full = path.join(current, entry.name);\n if (entry.isDirectory()) {\n stack.push(full);\n } else if (entry.isFile()) {\n try {\n total += fs.statSync(full).size;\n } catch {\n // A file that vanished between readdir and stat contributes\n // nothing; it is not worth failing a build over.\n }\n }\n }\n }\n return total;\n}\n\n/**\n * Install the bundle's declared dependencies into the bundle itself.\n *\n * ## What this buys\n *\n * A managed pod's bundle lives on an `emptyDir`, so it is re-fetched and\n * re-installed on **every** start — an eviction, a node failure, an OOM, a\n * runtime rollout. The install is 35–55 seconds of a 40–60 second cold start,\n * which makes it the price of every unplanned restart a tenant suffers. Doing it\n * once at build time instead of every time at boot takes that to roughly the\n * cost of untarring.\n *\n * The pod side needs no change to benefit: the init container already skips\n * installing when `node_modules` is present, a guard that existed for\n * pre-baked images and turns out to be exactly the hook this needs.\n *\n * ## Why it refuses to vendor native code\n *\n * A compiled binary is valid only for the platform it was built for, and a\n * developer's machine is rarely the deployment's. The managed runtime already\n * refuses bundles containing native modules for the same reason, so this refusal\n * costs nothing there — but a self-hosted project may legitimately use them, and\n * for those the honest answer is to install in the container, where the platform\n * is known.\n *\n * ## Why `--os` and `--cpu` are not optional\n *\n * The dangerous case is not native code, which is detectable. It is a pure-JS\n * package whose real work lives in a **platform-specific optional dependency** —\n * `esbuild` being the one everybody meets. Installing on an Apple Silicon Mac\n * resolves `@esbuild/darwin-arm64`, produces a tree that looks complete, and\n * fails at import inside a linux/amd64 pod. npm resolves optional dependencies\n * for the declared target rather than the host when told to, so it is told to.\n */\nexport function vendorDependencies(options: {\n outDir: string;\n declared: Record<string, string>;\n nativeModules: NativeDependency[];\n /**\n * Packages the runtime resolves *from the bundle* and cannot boot without —\n * in practice the database driver, which the image deliberately does not\n * supply. A vendored tree missing one of these is refused; see below.\n */\n required?: string[];\n /** `false` disables; `undefined` means \"when it is safe to\". */\n requested?: boolean;\n /** Injected in tests. */\n run?: (cmd: string, args: string[], cwd: string) => void;\n}): VendorResult {\n if (options.requested === false) {\n return { vendored: false, skipped: \"disabled with --no-vendor\" };\n }\n if (Object.keys(options.declared).length === 0) {\n // Not a failure and not worth a warning: a project using only what the\n // runtime already provides installs nothing at boot either way.\n return { vendored: false, skipped: \"the bundle declares no dependencies\" };\n }\n if (options.nativeModules.length > 0) {\n const names = options.nativeModules.map(m => m.name).join(\", \");\n return {\n vendored: false,\n skipped:\n `the dependency closure contains native code (${names}), which is only valid on the ` +\n \"platform it was compiled for\"\n };\n }\n\n const target = {\n os: VENDOR_TARGET_OS,\n cpu: VENDOR_TARGET_CPU,\n node: process.versions.node.split(\".\")[0]\n };\n\n const run = options.run ?? ((cmd, args, cwd) => {\n const result = spawnSync(cmd, args, { cwd, stdio: \"pipe\", encoding: \"utf8\" });\n if (result.error) throw result.error;\n if (result.status !== 0) {\n throw new Error(\n `${cmd} ${args.join(\" \")} exited ${result.status}\\n${result.stderr || result.stdout || \"\"}`.trim()\n );\n }\n });\n\n try {\n run(\n \"npm\",\n [\n \"install\",\n \"--omit=dev\",\n // Matches what the runtime image's entrypoint insists on, and\n // what the init container passes. A bundle whose dependencies\n // ran lifecycle scripts at build time would arrive at the pod\n // carrying whatever they produced.\n \"--ignore-scripts\",\n \"--no-audit\",\n \"--no-fund\",\n `--os=${target.os}`,\n `--cpu=${target.cpu}`\n ],\n options.outDir\n );\n } catch (error: unknown) {\n // Never fatal. A bundle that could not be vendored is exactly the bundle\n // every project shipped before this existed — slower to start, entirely\n // functional — and failing the build over a speed optimisation would\n // trade a working deploy for a faster one that does not happen.\n return {\n vendored: false,\n skipped: `npm install failed: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n\n const installed = path.join(options.outDir, \"node_modules\");\n if (!fs.existsSync(installed)) {\n return { vendored: false, skipped: \"npm install produced no node_modules\" };\n }\n\n // An *incomplete* vendored tree is worse than none, because of the very\n // guard that makes vendoring free: the init container skips installing when\n // `node_modules` is present. So a tree missing the database driver does not\n // start slowly — it does not start at all, with the boot dying on\n // `Cannot find package \"@rebasepro/server-postgres\"`, and the step that\n // would have installed it declining to run precisely because this directory\n // exists.\n //\n // A driver goes missing whenever the project declares it in a way the\n // registry cannot serve — `workspace:*` in a monorepo, a `link:` override —\n // since `collectDeclaredDependencies` drops exactly those. Such a project\n // could never deploy this bundle anyway; what it must not do is have a\n // *build-time* optimisation quietly remove its ability to boot from source.\n // Refusing leaves the bundle in the state every project shipped before\n // vendoring existed.\n const missing = (options.required ?? []).filter(name =>\n !fs.existsSync(path.join(installed, ...name.split(\"/\"), \"package.json\")));\n if (missing.length > 0) {\n fs.rmSync(installed, { recursive: true, force: true });\n fs.rmSync(path.join(options.outDir, \"package-lock.json\"), { force: true });\n return {\n vendored: false,\n skipped:\n `the installed tree is missing ${missing.join(\", \")}, which the runtime resolves from ` +\n \"the bundle — the bundle declares it at a version no registry can serve (a workspace \" +\n \"link), so nothing was vendored rather than shipping a tree that boots without a driver\"\n };\n }\n\n const bytes = directorySize(installed);\n if (bytes > VENDOR_SIZE_MAX_BYTES && options.requested !== true) {\n fs.rmSync(installed, { recursive: true, force: true });\n fs.rmSync(path.join(options.outDir, \"package-lock.json\"), { force: true });\n return {\n vendored: false,\n skipped:\n `the installed tree is ${Math.round(bytes / (1024 * 1024))} MB, past the point where the ` +\n \"upload can be expected to fit under the control plane's 100 MB limit — a bundle that \" +\n \"is refused at the door is worse than one that installs at boot. Pass --vendor to keep \" +\n \"it anyway (a deploy that builds from source never uploads the tree), or shrink the \" +\n \"declared dependencies\"\n };\n }\n\n return { vendored: true, target, bytes };\n}\n\n/**\n * Package a built static app (a `static` or bundled-`admin` app) into a bundle.\n *\n * A static bundle is the counterpart to a backend bundle: the same shape, the\n * same runtime image runs it, but its manifest says `mode: \"static\"` and it\n * carries only the built assets under `static/`. That is what lets a frontend or\n * admin app be its own deployable, scalable unit rather than something baked into\n * the backend container.\n *\n * `assetsDir` is the app's built output (e.g. `frontend/dist`), already produced\n * by its own build command. This copies it into the bundle and writes the\n * manifest — no compilation, no dependency closure (a static bundle installs\n * nothing at boot).\n */\n/**\n * Fold a built static app into a backend bundle, so one runtime serves both.\n *\n * ## Why this exists\n *\n * A managed tenant runs one pod, and `bootFromBundle` on the backend path already\n * knows how to serve a SPA — it looks for `entry.static` and mounts `serveSPA`\n * last, behind `REBASE_SERVE_STATIC`. What was missing was anything putting the\n * assets there.\n *\n * The consequence was not subtle. A project whose custom image served its website\n * at `/` and its API at `/api` — the shape the scaffolded template produces — lost\n * the website the moment it moved to the managed runtime: the API answered\n * perfectly and every page 404'd. Managed could not be a drop-in replacement for\n * custom while the frontend simply vanished.\n *\n * Folding restores parity with the container it replaces, which is the only\n * honest baseline. It is deliberately the FIRST implementation and not the last:\n * a static app on its own bucket behind a CDN is better for cache behaviour and\n * lets the frontend deploy independently. But that needs infrastructure that does\n * not exist yet, and \"your site is gone\" is not an acceptable state to leave a\n * project in while it gets built.\n *\n * The trade it makes, stated plainly: frontend and backend now deploy together\n * and the bundle carries the built assets. For a project that was shipping both\n * in one image already, that is exactly what it had.\n */\nexport function foldStaticIntoBundle(options: {\n /** The backend bundle directory, already written. */\n bundleDir: string;\n /** Directory of built frontend assets (the static app's `output`). */\n assetsDir: string;\n /** The app's name in `rebase.json`. Names its directory inside the bundle. */\n appName: string;\n /** Public base path this app is served under. */\n path: string;\n /** Serve `index.html` for unmatched paths under `path`. */\n spa: boolean;\n /** Where this app mounts the Rebase CMS, if it does. */\n cms?: string;\n}): { fileCount: number; dir: string } {\n const { bundleDir, assetsDir, appName, path: basePath, spa, cms } = options;\n const manifestPath = path.join(bundleDir, \"manifest.json\");\n if (!fs.existsSync(manifestPath)) {\n throw new Error(`No manifest at ${manifestPath} — build the backend bundle first.`);\n }\n if (!fs.existsSync(assetsDir)) {\n throw new Error(`No built assets at ${assetsDir}.`);\n }\n\n // Each app gets its own directory, and only its own is cleared. Folding used\n // to wipe `static/` wholesale and write a single `entry.static` string, so a\n // second app silently replaced the first — both in the tree and in the\n // manifest — and the bundle deployed looking complete.\n const dir = path.posix.join(\"static\", appName);\n const staticOut = path.join(bundleDir, \"static\", appName);\n fs.rmSync(staticOut, { recursive: true,\nforce: true });\n fs.mkdirSync(staticOut, { recursive: true });\n fs.cpSync(assetsDir, staticOut, { recursive: true });\n\n let fileCount = 0;\n const count = (target: string): void => {\n for (const entry of fs.readdirSync(target, { withFileTypes: true })) {\n if (entry.isDirectory()) count(path.join(target, entry.name));\n else fileCount++;\n }\n };\n count(staticOut);\n\n // Record it, because the runtime finds the assets through the manifest —\n // not by guessing a directory name.\n const manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as RebaseBundleManifest;\n const existing = (manifest.entry?.static ?? []).filter(entry => entry.dir !== dir);\n manifest.entry = {\n ...manifest.entry,\n static: [...existing, { path: basePath,\ndir,\nspa,\nname: appName,\n...(cms ? { cms } : {}) }]\n };\n fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\");\n\n return { fileCount,\ndir };\n}\n\nexport function buildStaticBundle(options: {\n projectRoot: string;\n appName: string;\n assetsDir: string;\n outDir: string;\n runtimeRange: string;\n /** Public base path. Default `/` — a standalone bundle owns its origin. */\n path?: string;\n /** Serve `index.html` for unmatched paths. Default `true`. */\n spa?: boolean;\n /** Where this app mounts the Rebase CMS, if it does. */\n cms?: string;\n}): { outDir: string; manifest: RebaseBundleManifest; fileCount: number } {\n const { projectRoot, appName, assetsDir, outDir, runtimeRange } = options;\n const basePath = options.path ?? \"/\";\n\n cleanOutDir(projectRoot, outDir);\n\n const staticOut = path.join(outDir, \"static\");\n fs.mkdirSync(staticOut, { recursive: true });\n fs.cpSync(assetsDir, staticOut, { recursive: true });\n\n let fileCount = 0;\n const count = (dir: string): void => {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) count(path.join(dir, entry.name));\n else fileCount++;\n }\n };\n count(staticOut);\n\n const manifest: RebaseBundleManifest = {\n bundleFormat: BUNDLE_FORMAT_VERSION,\n runtime: {\n range: runtimeRange,\n builtAgainst: resolveServerVersion(projectRoot),\n contract: RUNTIME_CONTRACT_VERSION\n },\n // A static app has no collections and therefore no schema contract.\n schemaVersion: \"\",\n app: appName,\n kind: \"static\",\n // Normally `/` — a standalone bundle owns its origin. It carries the\n // app's declared path rather than hardcoding one so that the bundle\n // agrees with what the assets were actually *built* for; serving a\n // `/admin`-built app at `/` is the blank-page failure in reverse.\n entry: { static: [{ path: basePath,\ndir: \"static\",\nspa: options.spa ?? true,\nname: appName,\n...(options.cms ? { cms: options.cms } : {}) }] },\n hooks: { native: false },\n // Nothing to install beside a static bundle — it is just files.\n deps: { declared: {} },\n build: {\n cli: cliVersion(),\n node: process.versions.node.split(\".\")[0],\n createdAt: new Date().toISOString()\n }\n };\n\n fs.writeFileSync(\n path.join(outDir, \"manifest.json\"),\n `${JSON.stringify(manifest, null, 2)}\\n`,\n \"utf8\"\n );\n // An empty package.json keeps the runtime's boot-time install a clean no-op.\n fs.writeFileSync(\n path.join(outDir, \"package.json\"),\n `${JSON.stringify({ name: \"rebase-bundle\",\nprivate: true,\ntype: \"module\",\ndependencies: {} }, null, 2)}\\n`,\n \"utf8\"\n );\n\n return { outDir,\nmanifest,\nfileCount };\n}\n\n/**\n * Which files in a collections directory are collections.\n *\n * Mirrors the runtime loader's rules exactly, and must keep mirroring them: the\n * set of files counted here decides the schema version, and the runtime decides\n * what it serves the same way. A divergence would show up as a client that is\n * permanently \"out of date\" against a server that agrees with it.\n *\n * (`._*` guards macOS AppleDouble files, which look like sources and are not.)\n */\nfunction isCollectionSourceFile(name: string): boolean {\n if (name.startsWith(\".\")) return false;\n if (name.includes(\".test.\") || name.includes(\".spec.\")) return false;\n if (name.endsWith(\".d.ts\")) return false;\n if (name === \"index.ts\" || name === \"index.js\") return false;\n return name.endsWith(\".ts\") || name.endsWith(\".js\");\n}\n\n/**\n * Load collections from **source**, for hashing and for the manifest's slug list.\n *\n * Deliberately not the compiled output. A compiled bundle imports its\n * dependencies from beside itself — that is the whole point of shipping a\n * `package.json` with it — but at build time nothing has been installed there\n * yet, and under pnpm the project's own `node_modules` lives one directory per\n * package, so the emitted files genuinely cannot resolve their imports until\n * they are deployed.\n *\n * Reading source costs nothing in fidelity: compilation erases types, it does\n * not change the values a collection module exports, so the hash is the same\n * either way.\n */\nasync function loadSourceCollections(collectionsDir: string): Promise<CollectionConfig[]> {\n if (!fs.existsSync(collectionsDir)) return [];\n\n const { createJiti } = await import(\"jiti\") as {\n createJiti: (filename: string, options?: Record<string, unknown>) => {\n import: (id: string) => Promise<unknown>;\n };\n };\n const jiti = createJiti(path.join(collectionsDir, \"index.ts\"), {\n interopDefault: true,\n esmResolve: true\n });\n\n const files = fs.readdirSync(collectionsDir)\n .filter(isCollectionSourceFile)\n .sort();\n\n const collections: CollectionConfig[] = [];\n const failures: string[] = [];\n\n for (const file of files) {\n try {\n const mod = await jiti.import(path.join(collectionsDir, file)) as\n { default?: CollectionConfig } | CollectionConfig;\n const collection = (mod as { default?: CollectionConfig }).default\n ?? (mod as CollectionConfig);\n if (collection && typeof collection === \"object\" && \"slug\" in collection) {\n collections.push(collection);\n } else {\n failures.push(`${file}: no default-exported collection`);\n }\n } catch (err) {\n failures.push(`${file}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (failures.length > 0) {\n throw new Error(\n `Could not read ${failures.length} collection file(s):\\n` +\n failures.map(f => ` • ${f}`).join(\"\\n\")\n );\n }\n\n return collections;\n}\n\n/** The `@rebasepro/server` version the project resolves — what it was built against. */\nfunction resolveServerVersion(projectRoot: string): string {\n const candidates = [\n path.join(projectRoot, \"node_modules\", \"@rebasepro\", \"server\", \"package.json\"),\n path.join(projectRoot, \"backend\", \"node_modules\", \"@rebasepro\", \"server\", \"package.json\")\n ];\n for (const candidate of candidates) {\n if (!fs.existsSync(candidate)) continue;\n try {\n return (JSON.parse(fs.readFileSync(candidate, \"utf8\")) as { version: string }).version;\n } catch {\n // fall through\n }\n }\n return \"unknown\";\n}\n","/**\n * Folding a project's static apps into its backend bundle.\n *\n * Shared by `rebase build` and `rebase cloud deploy` deliberately. It lived in\n * the build *command* first, and `deploy` rebuilds the bundle itself — so a\n * deploy silently produced a bundle without the frontend, packed 164 KB where\n * 39 MB was expected, and the site 404'd on the managed runtime exactly as if\n * folding had never been written. Two callers building the same artefact must\n * share the step that completes it.\n *\n * Why fold at all: `bootFromBundle` serves static apps from `entry.static`\n * behind `REBASE_SERVE_STATIC` (default on). A managed tenant runs one pod, so\n * putting the built assets in the bundle gives it the shape a custom container\n * already had — site at `/`, admin at `/admin`, API at `/api` — which is the\n * only honest baseline for calling the managed runtime a drop-in replacement.\n *\n * **Every** static app is folded, each at its declared path. Folding used to\n * pick exactly one and refuse when it found two, which meant a project with a\n * site and an admin panel deployed with neither.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execa } from \"execa\";\nimport chalk from \"chalk\";\nimport { foldStaticIntoBundle } from \"./bundle\";\nimport { toolStdio } from \"./utils/tool-stdio\";\n\n/** The apps section of a project manifest, as much of it as folding needs. */\nexport interface FoldableManifest {\n apps?: Record<string, {\n type?: string;\n build?: string;\n output?: string;\n path?: string;\n spa?: boolean;\n cms?: string;\n }>;\n}\n\nexport interface FoldOptions {\n projectRoot: string;\n manifest: FoldableManifest;\n /** The backend bundle directory, already written. */\n bundleDir: string;\n /** Skip running each app's own build command; fold what is already built. */\n skipBuild?: boolean;\n log?: (message: string) => void;\n /** Send each app's build output to stderr: the caller's stdout carries a result. See `toolStdio`. */\n quietStdout?: boolean;\n}\n\nexport interface FoldOutcome {\n appName: string;\n fileCount: number;\n /** Public base path this app was folded in at. */\n path: string;\n}\n\n/** A static app as folding sees it, with the manifest's defaults applied. */\nexport interface FoldableApp {\n name: string;\n build?: string;\n output?: string;\n /** Public base path, defaulted to `/`. */\n path: string;\n /** SPA fallback, defaulted to `true`. */\n spa: boolean;\n /** Where this app mounts the Rebase CMS, if it does. */\n cms?: string;\n}\n\n/**\n * Every static app in the manifest, in mount order.\n *\n * Longest path first, so the `/`-rooted app is registered last — its catch-all\n * would otherwise claim its siblings' URLs. Pure, so the ordering is testable\n * without a filesystem.\n */\nexport function foldableApps(manifest: FoldableManifest): {\n apps: FoldableApp[];\n /** Apps that cannot be folded, and why. */\n skipped: { name: string; reason: string }[];\n} {\n const apps: FoldableApp[] = [];\n const skipped: { name: string; reason: string }[] = [];\n\n for (const [name, app] of Object.entries(manifest.apps ?? {})) {\n if (app?.type !== \"static\") continue;\n if (!app.output) {\n skipped.push({ name,\nreason: `\"${name}\" declares no output directory — not folded in.` });\n continue;\n }\n apps.push({\n name,\n build: app.build,\n output: app.output,\n path: app.path ?? \"/\",\n spa: app.spa ?? true,\n cms: app.cms\n });\n }\n\n apps.sort((a, b) => b.path.length - a.path.length);\n return { apps,\nskipped };\n}\n\n/**\n * Assert a built app's assets are actually rooted at the path it is served from.\n *\n * An app mounted at `/admin` but built with Vite's default `base: \"/\"` emits\n * `<script src=\"/assets/index-a1b2.js\">`. The server serves `index.html` fine\n * and 404s every asset: a blank page, no server error, nothing in the logs. It\n * is the single most expensive silent failure in this design, so it is a build\n * error rather than a runtime surprise.\n *\n * Only `<script src>` and `<link href>` are inspected — those are what a bundler\n * rewrites through `base`. Author-written anchors and canonical URLs are not\n * evidence of a misbuild.\n */\nexport function assertBuiltForPath(\n indexHtml: string,\n basePath: string,\n appName: string\n): void {\n if (basePath === \"/\") return;\n\n const offenders: string[] = [];\n const pattern = /<(?:script|link)\\b[^>]*?\\b(?:src|href)\\s*=\\s*[\"']([^\"']+)[\"']/gi;\n for (const match of indexHtml.matchAll(pattern)) {\n const ref = match[1];\n if (!ref.startsWith(\"/\")) continue;\n if (ref === `${basePath}` || ref.startsWith(`${basePath}/`)) continue;\n offenders.push(ref);\n }\n\n if (offenders.length === 0) return;\n\n throw new Error(\n `\"${appName}\" is declared at ${basePath} but its build emitted assets rooted at /.\\n` +\n ` index.html references: ${offenders.slice(0, 3).join(\", \")}\\n` +\n \" The app would load a blank page. Set `base` from REBASE_APP_BASE in its\\n\" +\n \" build config — see docs/apps-and-runtimes.md §4.2.\"\n );\n}\n\n/**\n * The environment every static app is built with, wherever that build is driven from.\n *\n * Shared because there are two drivers — `foldFrontendIntoBundle` here, and\n * `buildAssetApp` in `build.ts` for a standalone `type: \"static\"` app — and they\n * had already drifted: the path variables were duplicated into both, so a fix\n * applied to one shipped a bundle built the old way from the other. One function\n * makes that impossible rather than merely unlikely.\n *\n * ## REBASE_APP_*\n *\n * The declared path is a build-time input, not only a serving concern: Vite\n * reads `base` from REBASE_APP_BASE, and the trailing slash is that field's\n * convention. See `assertBuiltForPath`.\n *\n * ## NODE_ENV\n *\n * A built app is a production artifact by construction, so build it as one. Not\n * a formality: the scaffold's `.env` carries `NODE_ENV=development` for the dev\n * backend, and Vite's `loadEnv` promotes a `NODE_ENV` found in an env file into\n * the build unless the environment already sets one. So `rebase build` and\n * `rebase cloud deploy` shipped a *development* bundle — `import.meta.env.DEV\n * === true`, development React, dev-only branches live — from commands whose\n * whole purpose is to produce something deployable. Setting it here is what\n * closes it: Vite consults the env file's NODE_ENV only when `process.env`\n * has none.\n *\n * ## VITE_API_URL\n *\n * An app served by the backend it talks to has its API on its own origin by\n * construction, so a baked-in absolute URL can only be wrong. It was: that same\n * `.env` carries `VITE_API_URL=http://localhost:3001` and\n * `frontend/vite.config.ts` reads the project root via `envDir: \"..\"`, so a\n * stock deploy shipped a site whose every request went to whoever ran the build\n * — passing every server-side health check on the way out. Blanking it here\n * fixes the bundle even for a project whose `.env` predates the `init` fix, or\n * was written by hand. Empty is the right value rather than a missing one: the\n * client falls back to `window.location.origin`, which keeps working when a\n * custom domain is added.\n *\n * Vite prioritises `process.env.VITE_*` over `.env` files, so an explicit\n * `VITE_API_URL=https://api.example.com rebase cloud deploy` still wins — the\n * cross-origin escape hatch stays open, it just has to be deliberate. Nothing on\n * this path loads the project `.env` into `process.env`, so a value inherited\n * here really was set by the caller.\n */\nexport function staticBuildEnv(appPath: string, appName: string): Record<string, string> {\n return {\n REBASE_APP_PATH: appPath,\n REBASE_APP_BASE: appPath === \"/\" ? \"/\" : `${appPath}/`,\n REBASE_APP_NAME: appName,\n NODE_ENV: \"production\",\n VITE_API_URL: process.env.VITE_API_URL ?? \"\"\n };\n}\n\n/**\n * Build the project's static apps and fold them into the backend bundle.\n *\n * Throws rather than exiting, so the caller decides whether a missing frontend\n * should fail its command — a `build` may reasonably want to stop, and so should\n * a deploy, but that is not this function's call to make.\n */\nexport async function foldFrontendIntoBundle(options: FoldOptions): Promise<FoldOutcome[]> {\n const { projectRoot, manifest, bundleDir, skipBuild } = options;\n const log = options.log ?? ((m: string) => console.log(m));\n\n const { apps, skipped } = foldableApps(manifest);\n for (const { reason } of skipped) log(chalk.yellow(` ⚠ ${reason}`));\n if (apps.length === 0) return [];\n\n const outcomes: FoldOutcome[] = [];\n\n for (const app of apps) {\n if (app.build && !skipBuild) {\n await execa(app.build, {\n cwd: projectRoot,\n stdio: toolStdio(options.quietStdout),\n shell: true,\n env: staticBuildEnv(app.path, app.name)\n });\n }\n\n const assetsDir = path.join(projectRoot, app.output as string);\n if (!fs.existsSync(assetsDir)) {\n // Exited 0 and produced nothing where the manifest says it should.\n // Folding that ships an empty site, which from the outside is\n // indistinguishable from a broken deploy.\n throw new Error(\n `\"${app.name}\" declared output \"${app.output}\" does not exist after building — ` +\n \"the bundle would ship without a frontend.\"\n );\n }\n\n const indexHtml = path.join(assetsDir, \"index.html\");\n if (fs.existsSync(indexHtml)) {\n assertBuiltForPath(fs.readFileSync(indexHtml, \"utf8\"), app.path, app.name);\n }\n\n const { fileCount } = foldStaticIntoBundle({\n bundleDir,\n assetsDir,\n appName: app.name,\n path: app.path,\n spa: app.spa,\n cms: app.cms\n });\n outcomes.push({ appName: app.name,\nfileCount,\npath: app.path });\n }\n\n return outcomes;\n}\n","/**\n * Deriving the resource graph from a project's config, and recording it.\n *\n * ## Why the graph is derived rather than authored\n *\n * A resource is declared once, in code. But a host has to know what a project\n * needs *before* it runs anything — that is how a console can say \"this project\n * wants a `media` bucket and has none\" on a first deploy, and it is the reason\n * storage topology used to be hand-written into `rebase.json` in the first\n * place. A `custom` runtime makes it sharper still: it emits no bundle\n * manifest, so without a committed artifact there is nothing to read at all.\n *\n * So the graph is derived by evaluating the config and written to\n * `rebase.resources.json`, which is committed. Same arrangement as\n * `schema.generated.ts`: authored in one place, generated into another, and a\n * gate fails if the two disagree. The file is an *output*, never an input —\n * which is what removes the old silent merge, because there is no longer a\n * second declaration for anything to be merged with.\n *\n * ## Why evaluation rather than static analysis\n *\n * Encore parses the source and builds the graph from the AST. Rebase already\n * evaluates config to load collections, and evaluation is exact where a parser\n * is approximate — a resource declared in a loop, or behind a helper, is\n * invisible to a parser and obvious to an interpreter. The cost is running user\n * code at build time, which this project already accepts everywhere else.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { createRequire } from \"module\";\nimport { pathToFileURL } from \"url\";\nimport {\n DEFAULT_RESOURCE_KEY,\n buildResourceGraph,\n declareFunction,\n declaredQueueConsumers,\n declaredResources,\n declaredSubscriptions,\n findEnvSuffixCollision,\n isResourceHandle,\n resetDeclaredQueueConsumers,\n resetDeclaredResources,\n resetDeclaredSubscriptions,\n resolveResourceRefs,\n resourceId,\n resourceKeyOf,\n type CollectionConfig,\n type RebaseBackendAppConfig,\n type ResourceDeclaration,\n type ResourceGraph\n} from \"@rebasepro/types\";\nimport { analyseFunctionsDirectory } from \"../function-portability\";\nimport { resolveBackendPaths } from \"../manifest\";\nimport { cliVersion } from \"../utils/version\";\n\n/** The committed, generated record of what a project needs. */\nexport const RESOURCE_GRAPH_FILENAME = \"rebase.resources.json\";\n\n/** A problem found while deriving, reported with the rest rather than thrown one at a time. */\nexport interface ResourceIssue {\n path: string;\n message: string;\n}\n\n/**\n * Which `@rebasepro/*` package a module error is about, when it is about one.\n *\n * Both directions of a version skew arrive as an error about the *user's* file:\n * `resources.ts The requested module '@rebasepro/types' does not provide an\n * export named 'queue'`. Nothing in that says which copy of `@rebasepro/types`\n * is installed, what version this CLI is, or that the two disagree — so the\n * reader goes looking for a typo in code they just copied out of the docs.\n *\n * Two shapes, because the two directions produce different errors: a named\n * export the installed copy is too old for, and a package the installed tree\n * does not have at all.\n */\nconst NAMED_EXPORT_MISSING = /does not provide an export named ['\"]([^'\"]+)['\"]/;\nconst SPECIFIER = /(@rebasepro\\/[a-z0-9-]+)/;\n\n/** The version of a package as resolved from the project, or null. */\nfunction installedVersion(specifier: string, from: string): string | null {\n try {\n const require = createRequire(path.join(from, \"noop.js\"));\n const manifest = require.resolve(`${specifier}/package.json`);\n const version: unknown = JSON.parse(fs.readFileSync(manifest, \"utf-8\")).version;\n return typeof version === \"string\" ? version : null;\n } catch {\n return null;\n }\n}\n\n/**\n * The message an issue carries, with the skew named when there is one.\n *\n * `main` runs 497 commits ahead of npm `latest` and the docs site publishes from\n * `main`, so the shape this exists for is routine: a scaffold pinned to the\n * published version, config code written against today's documentation, and an\n * error about the config file. The fix is one command and the error named none\n * of it — the same failure as `404 No PUT route on collection 'projects'`, one\n * layer down.\n *\n * Says nothing extra when the two versions agree, or when either is unreadable:\n * a sentence naming one version twice is worse than no sentence.\n */\nexport function describeIssue(err: unknown, projectRoot: string, ownVersion = cliVersion()): string {\n const message = err instanceof Error ? err.message : String(err);\n const code = (err as { code?: unknown } | null)?.code;\n const missingExport = NAMED_EXPORT_MISSING.exec(message);\n const isSkewShaped = missingExport !== null || code === \"ERR_MODULE_NOT_FOUND\";\n if (!isSkewShaped) return message;\n\n const specifier = SPECIFIER.exec(message)?.[1];\n if (!specifier) return message;\n\n // One line, not two: every caller renders an issue as `path message` on a\n // single row, so a newline here would land the useful half unindented under\n // the file name.\n const lead = /[.!?]$/.test(message.trim()) ? message.trim() : `${message.trim()}.`;\n\n const installed = installedVersion(specifier, projectRoot);\n if (installed === null) {\n return `${lead} ${specifier} is not installed in this project; this CLI is ${ownVersion}. `\n + `Run pnpm add ${specifier}@${ownVersion}`;\n }\n if (ownVersion === \"unknown\" || installed === ownVersion) return message;\n\n // Which side to move is the question the reader actually has, and it has a\n // right answer: the CLI is what evaluates this file, so the packages follow\n // it — unless the CLI is the older one, in which case following it would\n // move the project backwards.\n const cliIsNewer = compareVersions(ownVersion, installed) > 0;\n return cliIsNewer\n ? `${lead} ${specifier} ${installed} is installed; this CLI is ${ownVersion}. `\n + `Run pnpm add ${specifier}@${ownVersion}`\n : `${lead} ${specifier} ${installed} is installed; this CLI is ${ownVersion}, which is older. `\n + `Update the CLI to ${installed}, or pin ${specifier} back to ${ownVersion}`;\n}\n\n/** -1 / 0 / 1 on the numeric parts, ignoring any prerelease tail. */\nfunction compareVersions(a: string, b: string): number {\n const parts = (v: string): number[] => v.split(\"-\")[0].split(\".\").map(n => Number(n) || 0);\n const [x, y] = [parts(a), parts(b)];\n for (let i = 0; i < 3; i++) {\n if ((x[i] ?? 0) !== (y[i] ?? 0)) return (x[i] ?? 0) < (y[i] ?? 0) ? -1 : 1;\n }\n return 0;\n}\n\n/** Files that declare resources, in the order they are loaded. */\nconst RESOURCE_ENTRY_NAMES = [\"resources.ts\", \"resources.js\", \"resources/index.ts\", \"resources/index.js\"];\n\n/** Collection files, which may also declare a resource beside the collection using it. */\nfunction collectionFiles(configDir: string): string[] {\n const dir = path.join(configDir, \"collections\");\n if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory()) return [];\n return fs.readdirSync(dir)\n .filter(f => /\\.(ts|js|mts|mjs)$/.test(f) && !/\\.(test|spec|d)\\./.test(f))\n .sort()\n .map(f => path.join(dir, f));\n}\n\n/**\n * Make the project's own TypeScript loader active in this process.\n *\n * `import()` below relies on tsx's resolver, and nothing had registered it:\n * `rebase build` runs from `node_modules/.bin/rebase`, which is plain Node.\n * On a modern Node that *looks* like it works — native type stripping imports\n * `collections/index.ts` happily — right up to the first relative specifier\n * inside it. The scaffolded template writes `import posts from \"./posts.js\"`,\n * which is the correct thing for TypeScript to emit and which native stripping\n * does not remap back to `posts.ts`. So `rebase build` failed on every\n * scaffolded project with `Cannot find module …/posts.js`, and the failure\n * looked like a broken template rather than a missing loader.\n *\n * Resolved from the project, not from this package, exactly as `resolveTsx`\n * does for the schema-generation subprocess: tsx is the project's dependency\n * (the scaffold declares it), and taking it from anywhere else would mean\n * evaluating a project's config with a loader it did not choose.\n *\n * Best-effort by design. A project with no tsx keeps the previous behaviour —\n * which is correct for one whose config is plain JavaScript, or whose imports\n * carry no extension — rather than failing on a dependency it never needed.\n * Registered once per process; `register` is cheap but not free, and deriving\n * twice in one process is an ordinary thing for a watch mode to do.\n */\nlet tsxRegistered = false;\n\nasync function registerProjectTsx(configDir: string): Promise<void> {\n if (tsxRegistered) return;\n tsxRegistered = true;\n\n // Where tsx might be, in the order most likely to find it. The scaffold\n // declares tsx in the *backend* workspace, and pnpm's isolated layout puts\n // it in `backend/node_modules` rather than hoisting it — so resolving only\n // from the config directory finds nothing on exactly the project shape this\n // exists to serve.\n const projectRoot = path.dirname(configDir);\n const bases = [configDir, projectRoot, path.join(projectRoot, \"backend\")];\n\n for (const base of bases) {\n try {\n // Resolved against a file *inside* the project so Node walks that\n // project's `node_modules`, not this package's.\n const requireFromProject = createRequire(path.join(base, \"noop.js\"));\n const api = await import(pathToFileURL(requireFromProject.resolve(\"tsx/esm/api\")).href) as\n { register?: () => unknown; default?: { register?: () => unknown } };\n\n // tsx's own `register`, not `module.register`. `tsx/esm/api` is the\n // API module; the loader is `tsx/esm`. Handing the API module to\n // `module.register` registers something with no hooks and reports\n // success — a worse failure than throwing, because the import below\n // then resolves exactly as it did before and the bug looks unfixed.\n const register = api.register ?? api.default?.register;\n if (typeof register === \"function\") {\n register();\n return;\n }\n } catch {\n // Not here. Try the next base.\n }\n }\n\n // No tsx anywhere in the project. The import below still runs; it simply\n // resolves the way Node alone would, which is correct for a config written\n // in plain JavaScript or whose imports carry no extension.\n}\n\n/**\n * Import a module for its side effects.\n *\n * Plain `import()` so tsx's loader hooks resolve `.ts` and workspace\n * specifiers, exactly as the collection loader does.\n */\nasync function evaluate(filePath: string): Promise<Record<string, unknown>> {\n return await import(pathToFileURL(filePath).href) as Record<string, unknown>;\n}\n\nexport interface DeriveOptions {\n /** Absolute path to the project's config directory. */\n configDir: string;\n /**\n * Whether to evaluate collection files too. Resources are conventionally\n * declared in `resources.ts`, but nothing stops a bucket being declared\n * beside the collection that stores into it, and a graph that missed it\n * would under-report what the project needs.\n */\n includeCollections?: boolean;\n /**\n * Absolute path to the crons directory. Each file is evaluated through the\n * same loader the runtime uses, which declares the cron under the same id\n * the scheduler runs it as. Absent, or missing on disk: no crons.\n */\n cronsDir?: string;\n /**\n * Absolute path to the functions directory. Read statically — the\n * bundler's portability analysis — never evaluated: a function's module\n * scope belongs to a running backend, not a build.\n */\n functionsDir?: string;\n /** The project root, for the paths a graph records. Defaults to the config directory's parent. */\n projectRoot?: string;\n}\n\n/** The derive options for a backend app, from its manifest entry. */\nexport function deriveOptionsFor(projectRoot: string, app: RebaseBackendAppConfig): DeriveOptions {\n const paths = resolveBackendPaths(app, projectRoot);\n return {\n projectRoot,\n configDir: path.join(projectRoot, paths.config),\n cronsDir: path.join(projectRoot, paths.crons),\n functionsDir: path.join(projectRoot, paths.functions)\n };\n}\n\n/** Whether a module's default export looks like a collection. */\nfunction isCollectionLike(value: unknown): value is CollectionConfig {\n return typeof value === \"object\" && value !== null\n && typeof (value as { slug?: unknown }).slug === \"string\"\n && typeof (value as { properties?: unknown }).properties === \"object\";\n}\n\n/**\n * The resources a collection reaches: its database, and every bucket a\n * storage property stores into. Only resources the graph declares get an\n * edge — the implicit default database is not in the graph, so a collection\n * that names no `dataSource` records nothing.\n */\nfunction collectionEdges(collection: CollectionConfig, declared: Set<string>): Array<[string, string]> {\n const edges: Array<[string, string]> = [];\n const from = `collection:${collection.slug}`;\n const databaseId = resourceId(\"database\", collection.dataSource ?? DEFAULT_RESOURCE_KEY);\n if (declared.has(databaseId)) edges.push([databaseId, from]);\n\n const walk = (properties: Record<string, unknown> | undefined, prefix: string): void => {\n for (const [name, raw] of Object.entries(properties ?? {})) {\n const property = raw as {\n storage?: { storageSource?: unknown };\n of?: unknown;\n properties?: Record<string, unknown>;\n };\n if (!property || typeof property !== \"object\") continue;\n if (property.storage) {\n const key = property.storage.storageSource === undefined\n ? DEFAULT_RESOURCE_KEY\n : resourceKeyOf(property.storage.storageSource as string);\n const bucketId = resourceId(\"bucket\", key);\n if (declared.has(bucketId)) edges.push([bucketId, `property:${collection.slug}.${prefix}${name}`]);\n }\n if (property.properties) walk(property.properties, `${prefix}${name}.`);\n if (property.of && typeof property.of === \"object\") walk({ [name]: property.of }, `${prefix}`);\n }\n };\n walk(collection.properties as Record<string, unknown>, \"\");\n return edges;\n}\n\n/**\n * A cron file that would not import, said in terms somebody can act on.\n *\n * The graph is derived by evaluating each cron module, in a process with none\n * of the deployment's environment — so a cron that reaches a module validating\n * `DATABASE_URL` at import fails here and works perfectly at boot. The raw\n * message is a Zod error about a variable, which reads as \"the environment is\n * wrong\" when the environment is not the point.\n */\nfunction cronLoadIssue(problem: string): string {\n return `${summariseCronProblem(problem)}\\n` +\n \" `rebase resources` evaluates each cron file to read its schedule, and it is a build \" +\n \"step: no .env, no secrets. Move work that needs the deployment's environment inside the \" +\n \"handler — `const { x } = await import(\\\"…\\\")` — so the module scope imports nothing that \" +\n \"reads configuration.\";\n}\n\n/**\n * The cron loader's `<file> (threw: <message>)`, as one line.\n *\n * The message is whatever the module threw, and the common case is a schema\n * validator: `loadEnv()` at module scope with no `.env` present throws a\n * `ZodError`, whose `.message` is the JSON array of its issues. That arrived\n * here verbatim — ten lines of `{ \"expected\": \"string\", \"code\":\n * \"invalid_type\", … }` — with the sentence that says what to do underneath it,\n * so the reader met \"Invalid input: expected string, received undefined\" twice\n * before reaching the explanation.\n *\n * A validator's own sentences are the useful half of that object, so they are\n * kept and the serialisation is dropped.\n */\nfunction summariseCronProblem(problem: string): string {\n const match = problem.match(/^(.*) \\(threw: ([\\s\\S]*)\\)$/);\n if (!match) return problem.split(\"\\n\")[0];\n const [, file, thrown] = match;\n return `${file}: ${summariseThrownMessage(thrown)}`;\n}\n\n/** One sentence out of a thrown message, whatever shape it arrived in. */\nfunction summariseThrownMessage(message: string): string {\n const trimmed = message.trim();\n if (trimmed.startsWith(\"[\") || trimmed.startsWith(\"{\")) {\n try {\n const parsed: unknown = JSON.parse(trimmed);\n const issues = Array.isArray(parsed) ? parsed : [parsed];\n const sentences = [...new Set(\n issues\n .map(issue => (issue as { message?: unknown } | null)?.message)\n .filter((m): m is string => typeof m === \"string\" && m.length > 0)\n )];\n if (sentences.length > 0) return sentences.join(\"; \");\n } catch {\n // Not JSON after all — fall through to the first line.\n }\n }\n return trimmed.split(\"\\n\")[0];\n}\n\n/**\n * Evaluate a project's config and return the graph it declares.\n *\n * Clears any previously registered declarations first, so deriving twice in one\n * process — a watch mode, a test — describes the project rather than the union\n * of every project seen so far.\n */\nexport async function deriveResourceGraph(options: DeriveOptions): Promise<{ graph: ResourceGraph; issues: ResourceIssue[] }> {\n const { configDir, includeCollections = true, cronsDir, functionsDir } = options;\n const projectRoot = options.projectRoot ?? path.dirname(configDir);\n // Before anything is evaluated: the loader has to be in place for the very\n // first import, and the first import is a collection file.\n await registerProjectTsx(configDir);\n\n // All three registries, and the side lists are the easy ones to forget:\n // resetting only the resources leaves one project's handlers attached\n // while its topics are gone — every one of them then reads as orphaned\n // against the *next* project. Caught by deriving twice in one process,\n // which is what a watch mode does.\n resetDeclaredResources();\n resetDeclaredSubscriptions();\n resetDeclaredQueueConsumers();\n\n const issues: ResourceIssue[] = [];\n const usedBy = new Map<string, string[]>();\n // `recordUse`, not `use`: React 19 made `use` a hook name, and\n // `react-hooks/rules-of-hooks` refuses a call to one from a plain function\n // — a lint error on a file with no React in it.\n const recordUse = (resource: string, by: string): void => {\n const list = usedBy.get(resource) ?? [];\n if (!list.includes(by)) list.push(by);\n usedBy.set(resource, list);\n };\n\n // ── Declarations ─────────────────────────────────────────────────────\n // Which export name is which resource, so a function's `import { media }`\n // can be recorded as reaching `bucket:media` without evaluating the\n // function. The export name and the key are usually the same word and\n // nothing requires them to be.\n const handleExports = new Map<string, string>();\n for (const name of RESOURCE_ENTRY_NAMES) {\n const candidate = path.join(configDir, name);\n if (!fs.existsSync(candidate)) continue;\n try {\n const mod = await evaluate(candidate);\n for (const [exportName, value] of Object.entries(mod)) {\n if (isResourceHandle(value)) handleExports.set(exportName, resourceId(value.kind, value.key));\n }\n } catch (err) {\n issues.push({ path: path.relative(configDir, candidate), message: describeIssue(err, projectRoot) });\n }\n break;\n }\n\n // ── Collections ──────────────────────────────────────────────────────\n const collections: CollectionConfig[] = [];\n if (includeCollections) {\n for (const entry of collectionFiles(configDir)) {\n try {\n const mod = await evaluate(entry);\n // As the loader sees it at boot: a handle written where a key\n // belongs is its key here too.\n if (isCollectionLike(mod.default)) collections.push(resolveResourceRefs(mod.default));\n } catch (err) {\n // Named individually: \"could not derive the graph\" with no file in\n // it sends somebody reading every module in the directory.\n issues.push({\n path: path.relative(configDir, entry),\n message: describeIssue(err, projectRoot)\n });\n }\n }\n }\n\n // ── Crons ────────────────────────────────────────────────────────────\n // Through the runtime's own loader, so the id the graph records is the id\n // the scheduler runs — the filename — and a cron that would not load at\n // boot does not load here either.\n //\n // Which means the module is EVALUATED, in a build step that has none of the\n // deployment's environment. A cron whose module scope reaches something that\n // validates `DATABASE_URL` at import therefore derives on a laptop with a\n // `.env` and nowhere else. That is worth an explicit sentence rather than a\n // stack, so `cronLoadIssue` adds one.\n if (cronsDir && fs.existsSync(cronsDir)) {\n // The runtime's loader logs each job as it loads, to stdout, as JSON\n // — which is also where `rebase resources --json` writes the graph.\n // Its problems come back as a list, so the log adds nothing here.\n const previousLevel = process.env.LOG_LEVEL;\n process.env.LOG_LEVEL = \"error\";\n try {\n const { loadCronJobsWithDiagnostics } = await import(\"@rebasepro/server\");\n // This process's own `import()`, not the loader's `new Function`\n // one: tsx's hooks are registered here, and a test runner's module\n // sandbox answers the other with \"a dynamic import callback was\n // not specified\" — the same trap the split-roles e2e records.\n const { problems } = await loadCronJobsWithDiagnostics(cronsDir, url => import(url));\n for (const problem of problems) {\n issues.push({ path: path.relative(projectRoot, cronsDir), message: cronLoadIssue(problem) });\n }\n } catch (err) {\n issues.push({\n path: path.relative(projectRoot, cronsDir),\n message: cronLoadIssue(err instanceof Error ? err.message : String(err))\n });\n } finally {\n if (previousLevel === undefined) delete process.env.LOG_LEVEL;\n else process.env.LOG_LEVEL = previousLevel;\n }\n }\n\n // ── Functions ────────────────────────────────────────────────────────\n if (functionsDir && fs.existsSync(functionsDir)) {\n for (const report of analyseFunctionsDirectory(functionsDir, projectRoot)) {\n const requires = [...new Set(\n report.issues\n .filter(issue => issue.kind === \"node-builtin\" || issue.kind === \"node-only-package\")\n .map(issue => issue.message)\n )];\n try {\n declareFunction(report.name, {\n file: report.file,\n portable: report.portable,\n ...(requires.length > 0 ? { requires } : {})\n });\n } catch (err) {\n issues.push({ path: report.file, message: describeIssue(err, projectRoot) });\n }\n for (const imported of report.resourceImports) {\n const resource = handleExports.get(imported);\n if (resource) recordUse(resource, `function:${report.name}`);\n }\n }\n }\n\n // ── Edges ────────────────────────────────────────────────────────────\n const declared = new Set(declaredResources().map(r => resourceId(r.kind, r.key)));\n for (const collection of collections) {\n for (const [resource, by] of collectionEdges(collection, declared)) recordUse(resource, by);\n }\n for (const sub of declaredSubscriptions()) {\n const id = resourceId(\"topic\", sub.topic);\n if (declared.has(id)) recordUse(id, `subscription:${sub.topic}.${sub.name}`);\n }\n for (const consumer of declaredQueueConsumers()) {\n const id = resourceId(\"queue\", consumer.queue);\n if (declared.has(id)) recordUse(id, `handler:${consumer.queue}`);\n }\n\n const graph = buildResourceGraph(usedBy);\n\n // Two resources of a kind whose env suffixes collide would silently read\n // each other's configuration, which is indistinguishable from a\n // misconfigured deployment.\n const byKind = new Map<string, string[]>();\n for (const r of graph.resources) {\n byKind.set(r.kind, [...(byKind.get(r.kind) ?? []), r.key]);\n }\n for (const [kind, keys] of byKind) {\n const collision = findEnvSuffixCollision(keys);\n if (collision) {\n issues.push({\n path: `${kind}.${collision.b}`,\n message:\n `\"${collision.a}\" and \"${collision.b}\" both bind from ${collision.suffix}, so one would ` +\n \"read the other's configuration. Rename one.\"\n });\n }\n }\n\n // A subscription on a topic nobody declared is a handler that will never\n // run, and nothing else would ever say so.\n const topics = new Set(graph.resources.filter(r => r.kind === \"topic\").map(r => r.key));\n for (const sub of declaredSubscriptions()) {\n if (!topics.has(sub.topic)) {\n issues.push({\n path: `topic.${sub.topic}`,\n message:\n `Subscription \"${sub.name}\" is declared on topic \"${sub.topic}\", which nothing declares. ` +\n \"The handler would never run.\"\n });\n }\n }\n\n // A collection routed to a database nothing declares boots into a\n // refusal, and a property stored in a bucket nothing declares answers 501\n // on its first upload. Both are cheaper to hear about here.\n const databases = new Set(graph.resources.filter(r => r.kind === \"database\").map(r => r.key));\n const buckets = new Set(graph.resources.filter(r => r.kind === \"bucket\").map(r => r.key));\n for (const collection of collections) {\n if (collection.dataSource && collection.dataSource !== DEFAULT_RESOURCE_KEY && !databases.has(collection.dataSource)) {\n issues.push({\n path: `collection.${collection.slug}`,\n message:\n `routes to dataSource \"${collection.dataSource}\", which nothing declares. ` +\n `Add database(\"${collection.dataSource}\") to resources.ts, or import the handle and use it here.`\n });\n }\n for (const [name, raw] of Object.entries(collection.properties ?? {})) {\n const key = (raw as { storage?: { storageSource?: unknown } })?.storage?.storageSource;\n if (typeof key === \"string\" && key !== DEFAULT_RESOURCE_KEY && buckets.size > 0 && !buckets.has(key)) {\n issues.push({\n path: `collection.${collection.slug}.${name}`,\n message: `stores into bucket \"${key}\", which nothing declares. Add bucket(\"${key}\") to resources.ts.`\n });\n }\n }\n }\n\n return { graph, issues };\n}\n\n/** The graph as it is written to disk: stable key order, trailing newline. */\nexport function serializeResourceGraph(graph: ResourceGraph): string {\n const resources = graph.resources.map(r => ({\n kind: r.kind,\n key: r.key,\n engine: r.engine,\n transport: r.transport,\n ...(r.label !== undefined ? { label: r.label } : {}),\n ...(Object.keys(r.options).length > 0 ? { options: r.options } : {}),\n ...(r.usedBy && r.usedBy.length > 0 ? { usedBy: r.usedBy } : {})\n }));\n return JSON.stringify({\n $generated: `Generated from config by \\`rebase resources\\`. Edit the declarations, not this file.`,\n version: graph.version,\n resources\n }, null, 4) + \"\\n\";\n}\n\n/** Read the committed graph, or null when a project has none yet. */\nexport function readResourceGraphFile(projectRoot: string): string | null {\n const file = path.join(projectRoot, RESOURCE_GRAPH_FILENAME);\n return fs.existsSync(file) ? fs.readFileSync(file, \"utf-8\") : null;\n}\n\n/**\n * Write the graph, and say whether the file changed.\n *\n * The boolean is what a `--check` mode reports on: a project whose committed\n * graph disagrees with its config has a host reading one thing and a runtime\n * doing another.\n */\nexport function writeResourceGraphFile(projectRoot: string, graph: ResourceGraph): { changed: boolean; file: string } {\n const file = path.join(projectRoot, RESOURCE_GRAPH_FILENAME);\n const next = serializeResourceGraph(graph);\n const previous = fs.existsSync(file) ? fs.readFileSync(file, \"utf-8\") : null;\n if (previous === next) return { changed: false, file };\n fs.writeFileSync(file, next);\n return { changed: true, file };\n}\n\n/** Parse a committed graph file, tolerating the `$generated` banner. */\nexport function parseResourceGraph(contents: string): ResourceGraph {\n const raw = JSON.parse(contents) as { version?: number; resources?: unknown };\n if (raw.version !== 1) {\n throw new Error(\n `Unsupported resource graph version ${String(raw.version)}. ` +\n \"This project was generated by a newer Rebase; upgrade rather than provisioning half of it.\"\n );\n }\n const entries = Array.isArray(raw.resources) ? raw.resources as Record<string, unknown>[] : [];\n // `options` is omitted from the file when empty; a reader of the graph\n // expects it present, so it is restored here.\n return { version: 1, resources: entries.map(r => ({ options: {}, ...r })) as ResourceGraph[\"resources\"] };\n}\n\n/**\n * Add the resources a project has without declaring them.\n *\n * A backend has a database whether or not anyone said so, and a project that\n * declares no buckets still gets one default storage source from the plain\n * unsuffixed variables. Both are load-bearing defaults and both are invisible\n * in the graph, so a status view built only from declarations would show an\n * empty screen to the majority of projects — the ones that most need to be told\n * which variable their one database reads.\n */\nexport function withImplicitDefaults(graph: ResourceGraph): {\n declaration: ResourceDeclaration;\n implicit: boolean;\n}[] {\n const entries = graph.resources.map(declaration => ({ declaration, implicit: false }));\n const has = (kind: string) => graph.resources.some(r => r.kind === kind);\n\n if (!has(\"database\")) {\n entries.unshift({\n declaration: {\n kind: \"database\",\n key: DEFAULT_RESOURCE_KEY,\n engine: \"postgres\",\n transport: \"server\",\n options: {}\n },\n implicit: true\n });\n }\n if (!has(\"bucket\")) {\n entries.push({\n declaration: {\n kind: \"bucket\",\n key: DEFAULT_RESOURCE_KEY,\n // `local` is what an unconfigured default source resolves to,\n // and naming it here keeps the row honest about what a project\n // with no S3 variables actually gets: a directory that a\n // container erases on restart, which production then drops.\n engine: \"local\",\n transport: \"server\",\n options: {}\n },\n implicit: true\n });\n }\n return entries;\n}\n\n/**\n * The resources a project *has*, which is what a person is asking about.\n *\n * One projection, because two of them disagreed. `rebase status` built its\n * rows from {@link withImplicitDefaults} and listed `buckets ✓ (default) local\n * · implicit`; `rebase resources` and `rebase resources --json` built theirs\n * from the raw graph and listed only the database and the function. Two\n * commands whose whole job is to answer \"what does this project need\", on the\n * same stock scaffold, giving different answers.\n *\n * The implicit entries are marked rather than hidden, because the distinction\n * is real and load-bearing: a declared resource is recorded in\n * `rebase.resources.json` for a host to provision, and an implicit one is a\n * default the runtime supplies whether or not anyone wrote it down. That file\n * still holds declarations only — it is a wire contract a host reads, and\n * putting defaults in it would ask for something to be provisioned that\n * nobody declared.\n */\nexport type ProjectedResource = ResourceDeclaration & { implicit?: true };\n\nexport function projectResourceGraph(graph: ResourceGraph): ProjectedResource[] {\n return withImplicitDefaults(graph).map(({ declaration, implicit }) =>\n (implicit ? { ...declaration, implicit: true as const } : declaration));\n}\n","/**\n * CLI command: rebase build [app...]\n *\n * Builds the apps a repository declares in `rebase.json`.\n *\n * For a `backend` app this produces a **bundle** — compiled collections,\n * functions and schema plus a manifest — which is the artifact the runtime\n * loads. For `static` and bundled `admin` apps it runs the declared build\n * command and reports where the output landed.\n *\n * A project with no manifest, or one whose backend has been ejected to its own\n * entrypoint, falls back to the previous behaviour: run every workspace's own\n * `build` script. Nothing that built before stops building.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport type { RebaseAppConfig, RebaseStaticAppConfig } from \"@rebasepro/types\";\nimport { requireProjectRoot } from \"../utils/project\";\nimport { parseCommandArgs, UsageError, wantsHelp } from \"../utils/args\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { cliVersion } from \"../utils/version\";\nimport { toolStdio } from \"../utils/tool-stdio\";\nimport { buildableApps, findBackendApp, loadManifest, ManifestError, resolveBackendPaths } from \"../manifest\";\nimport {\n buildBundle,\n buildStaticBundle,\n detectFrameworkDepDrift,\n DEFAULT_BUNDLE_DIR,\n VENDOR_SIZE_WARN_BYTES\n} from \"../bundle\";\nimport { assertBuiltForPath, foldFrontendIntoBundle, staticBuildEnv } from \"../fold-static\";\nimport { deriveOptionsFor, deriveResourceGraph, writeResourceGraphFile } from \"../resources/derive\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase build\")} — build the apps declared in rebase.json\n\n${chalk.bold(\"Usage\")}\n rebase build [app...] Build the named apps (default: all)\n\n${chalk.bold(\"Options\")}\n --out <dir> Bundle output directory (default: ${DEFAULT_BUNDLE_DIR})\n --skip-type-check Compile without type checking (faster; use for iteration only)\n --skip-schema Do not regenerate the database schema from collections\n --no-vendor Do not install dependencies into the bundle (they\n install on every pod start instead, ~40-60s slower)\n --vendor Install them whatever the tree's size — for a\n deploy that builds from source and never uploads it\n --workspace Run every workspace's own build script instead\n -h, --help Show this help\n\n${chalk.bold(\"Examples\")}\n rebase build Build every app in this repository\n rebase build backend Build only the backend bundle\n rebase build web Build only the \"web\" static app\n`.trim());\n}\n\n/**\n * The two commands that turn a custom-runtime app into an image.\n *\n * Exported for the test, because the failure this replaced was in the printed\n * text and nowhere else. It said:\n *\n * docker build -f backend/Dockerfile .\n *\n * for every custom backend, and the `.` was a guess — `context` was validated,\n * stored on the config, and read by nothing. For the reference project that\n * guess is wrong: `app/backend/Dockerfile` opens by copying `pnpm-lock.yaml`\n * and `pnpm-workspace.yaml`, which live at the monorepo root, so the command\n * `rebase build` handed you died on its first instruction. The deploy that\n * actually works, `infra/cloudbuild.yaml`, has always said\n * `-f app/backend/Dockerfile .` from the root.\n *\n * `dockerfile` is relative to `rebase.json`; `context` is too, and may point\n * above it. Docker resolves `-f` against the working directory, not the\n * context, so the path has to be re-expressed against wherever the command\n * runs — which is what the old line never did and is the whole reason it\n * could not be right for both.\n */\nexport function dockerBuildHint(\n projectRoot: string,\n name: string,\n app: { dockerfile?: string; context?: string }\n): string[] {\n const dockerfile = app.dockerfile ?? \"Dockerfile\";\n const context = app.context ?? \".\";\n const contextDir = path.resolve(projectRoot, context);\n const fromContext = path.relative(contextDir, path.resolve(projectRoot, dockerfile));\n\n const build = `${chalk.cyan(`npm run build --workspace ${name}`)}`;\n\n // A Dockerfile outside its own context is legal to `docker build` but means\n // nothing it copies is reachable, so there is no command to offer. Say what\n // is wrong instead of printing one that cannot work.\n if (fromContext.startsWith(\"..\")) {\n return [\n chalk.dim(` ${build}`),\n chalk.yellow(` ⚠ ${dockerfile} is outside the build context (${context}) — nothing it COPYs is reachable.`),\n chalk.dim(` Widen \"context\" in rebase.json, or move the Dockerfile inside it.`)\n ];\n }\n\n const docker = chalk.cyan(`docker build -f ${fromContext} .`);\n return context === \".\"\n ? [chalk.dim(` ${build} then ${docker}`)]\n : [chalk.dim(` ${build}`), chalk.dim(` ${chalk.cyan(`cd ${context}`)} && ${docker}`)];\n}\n\nexport async function buildCommand(rawArgs: string[] = []): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags: args, positionals: requested } = parseCommandArgs({\n spec: {\n \"--output\": String,\n // `--out` kept as an accepted alias. `generate-sdk` has always\n // spelled this `--output`, and two names for one concept across one\n // CLI is a thing you have to remember rather than know. `--output`\n // is canonical now; `--out` still works so no script breaks.\n \"--out\": \"--output\",\n \"--skip-type-check\": Boolean,\n /* Do not install the declared dependencies into the bundle. The\n bundle still works — it installs them at boot, as every bundle did\n before vendoring existed — so this is for a build that must not\n shell out to npm, not for a smaller artifact. */\n \"--no-vendor\": Boolean,\n /* Keep the installed tree whatever its size. The size ceiling\n protects an upload that a source-built deploy never performs, so\n that path needs a way to say so. */\n \"--vendor\": Boolean,\n \"--skip-schema\": Boolean,\n /* Do not fold the frontend into the backend bundle. For a project\n that publishes its frontend elsewhere and does not want the assets\n travelling with its API. */\n \"--no-static\": Boolean,\n /* Fold assets that are already built, without re-running the app's\n build command — for a CI job that built the frontend in an earlier\n step. */\n \"--skip-static-build\": Boolean,\n \"--workspace\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"build\"\n });\n\n const projectRoot = requireProjectRoot();\n\n if (args[\"--workspace\"]) {\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n let loaded;\n try {\n loaded = loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n\n const { manifest, source } = loaded;\n\n let targets = buildableApps(manifest);\n if (requested.length > 0) {\n const known = new Set(targets.map(t => t.name));\n const unknown = requested.filter(name => !known.has(name));\n if (unknown.length > 0) {\n console.error(chalk.red(`✗ Unknown app(s): ${unknown.join(\", \")}`));\n console.error(chalk.dim(` This repository declares: ${targets.map(t => t.name).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n targets = targets.filter(t => requested.includes(t.name));\n }\n\n if (targets.length === 0) {\n console.log(chalk.yellow(\"No buildable apps declared. Nothing to do.\"));\n return;\n }\n\n // An ejected backend owns its own build; the workspace scripts are the only\n // thing that knows how to run it.\n const backend = findBackendApp(manifest);\n if (!backend && source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json found — building workspace packages.\\n\"));\n await runWorkspaceBuilds(projectRoot);\n return;\n }\n\n // `--output` names one bundle directory, resolved from where it was typed.\n // It is refused for a build that produces several bundles rather than\n // handed to each: every bundle build empties its directory first, so the\n // last app built deleted the others' and the build still reported success.\n const output = args[\"--output\"] ? path.resolve(process.cwd(), args[\"--output\"]) : undefined;\n const bundled = targets.filter(({ app }) =>\n (app.type === \"backend\" && app.runtime !== \"custom\") ||\n (app.type === \"static\" && Boolean(app.build) && Boolean(app.output)));\n if (output && bundled.length > 1) {\n throw new UsageError(\n `--output names one bundle directory, and this build produces ${bundled.length}: ` +\n `${bundled.map(t => t.name).join(\", \")}. Build one app into it: ` +\n `rebase build ${bundled[0].name} --output ${args[\"--output\"]}`\n );\n }\n\n console.log(`${chalk.bold(\"Rebase\")} — building ${targets.length} app(s)\\n`);\n\n for (const { name, app } of targets) {\n console.log(chalk.cyan(`▸ ${name}`) + chalk.dim(` (${app.type})`));\n\n if (app.type === \"backend\" && app.runtime === \"custom\") {\n // An ejected backend's artifact is an IMAGE, not a bundle. Building\n // one anyway produced a `dist-bundle/` the project never deploys,\n // which is worse than doing nothing: it looks like the thing that\n // ships. The workspace's own `build` script compiles this app, and\n // the Dockerfile turns it into the image.\n console.log(chalk.dim(\" custom runtime — this project builds its own image, not a bundle\"));\n for (const line of dockerBuildHint(projectRoot, name, app)) console.log(line);\n console.log(\"\");\n continue;\n }\n\n if (app.type === \"backend\") {\n // Derived per backend app, because each has its own config\n // directory. Issues are fatal here rather than reported: a bundle\n // whose manifest is missing a bucket the code declares would deploy\n // into a tenant with nothing provisioned for it, and the first sign\n // would be uploads failing in production.\n const { graph: resourceGraph, issues } = await deriveResourceGraph(deriveOptionsFor(projectRoot, app));\n if (issues.length > 0) {\n console.error(chalk.red(`\\n ✗ ${issues.length} problem(s) in the declared resources:\\n`));\n for (const issue of issues) console.error(` ${chalk.bold(issue.path)} ${issue.message}`);\n console.error(\"\");\n process.exitCode = 1;\n return;\n }\n // Written alongside the bundle so the repository records what this\n // project needs. `rebase resources --check` is what keeps it honest.\n writeResourceGraphFile(projectRoot, resourceGraph);\n\n /* The framework pins, read before the build and reported after it.\n Ranges no single version satisfies are refused by `buildBundle`\n itself, before it builds anything, for every command that builds\n a bundle. */\n const drift = detectFrameworkDepDrift(projectRoot, cliVersion());\n\n const result = await buildBundle({\n projectRoot,\n appName: name,\n app,\n outDir: output,\n runtimeRange: manifest.rebase,\n resources: resourceGraph,\n skipTypeCheck: args[\"--skip-type-check\"],\n skipSchema: args[\"--skip-schema\"],\n vendor: args[\"--no-vendor\"] ? false : (args[\"--vendor\"] ? true : undefined)\n });\n const rel = path.relative(projectRoot, result.outDir);\n console.log(chalk.green(` ✓ bundle → ${rel}/`));\n // A headless build has no schema version — the API is introspected\n // from the live database at boot — and interpolating it anyway left\n // the summary ending in a dangling `schema `, which reads as a value\n // that failed to render rather than one that does not exist.\n const schemaVersion = result.manifest.schemaVersion;\n console.log(chalk.dim(\n ` ${result.collectionCount} collection(s)${schemaVersion ? `, schema ${schemaVersion}` : \"\"}`\n ));\n /* Say what the bundle's cold start will be, at the one moment\n anyone is listening.\n\n A vendored bundle starts in about five seconds; one that installs\n at boot takes forty to sixty, on EVERY pod start — an eviction, a\n node failure, an OOM, a runtime rollout. That is not a build\n detail, it is what each of those events costs in downtime, and it\n is invisible until an incident unless it is said here. */\n if (result.vendor.vendored) {\n console.log(chalk.dim(` dependencies installed into the bundle (${result.vendor.target?.os}/${result.vendor.target?.cpu})`));\n if ((result.vendor.bytes ?? 0) > VENDOR_SIZE_WARN_BYTES) {\n const mb = Math.round((result.vendor.bytes ?? 0) / (1024 * 1024));\n /* The limit is on the *compressed* upload and this is the\n tree on disk, so a number above 100 does not mean the\n upload fails — but \"201 MB, close to the 100 MB limit\"\n reads as nonsense and got ignored for exactly that\n reason. Say which quantity is which. */\n console.log(chalk.yellow(\n ` ⚠ the installed tree is ${mb} MB on disk — enough to risk the control plane's 100 MB ` +\n \"limit on the compressed upload\"));\n console.log(chalk.dim(\" Shrink the declared dependencies, or rebuild with --no-vendor.\"));\n }\n } else if (Object.keys(result.manifest.deps.declared).length === 0) {\n // Nothing to install is not a degraded state — this bundle\n // already starts as fast as a vendored one. Warning here would\n // train people to ignore the warning that matters.\n console.log(chalk.dim(\" no dependencies to install — nothing to bundle\"));\n } else {\n console.log(chalk.yellow(` ⚠ dependencies not bundled: ${result.vendor.skipped}`));\n console.log(chalk.dim(\" They install on every pod start instead, which is ~40-60s of cold start.\"));\n }\n\n if (result.manifest.hooks.native) {\n const names = (result.manifest.hooks.nativeModules ?? []).map(m => m.name).join(\", \");\n console.log(chalk.yellow(` ⚠ native dependencies detected: ${names}`));\n console.log(chalk.dim(\" These cannot run on the managed runtime. See `rebase doctor`.\"));\n }\n\n /* Framework pins older than this CLI.\n\n Warned here because this is the only moment anyone can be told.\n Locally every `@rebasepro/*` resolves through pnpm's workspace and\n `link:` overrides to the checkout, so the version strings in\n package.json are never exercised — the project runs fine on a\n developer's machine while declaring something years old. Those\n strings are first honoured when the runtime npm-installs them in\n the cloud, and by then the symptom is a tenant that boots and then\n misbehaves against its database.\n\n A warning rather than a hard failure: the CLI cannot know that a\n newer package has actually been published, and refusing to build\n over a guess would be worse than saying it out loud. (`drift` was\n read before the build, above.) */\n if (drift.behind.length > 0) {\n console.log(chalk.yellow(` ⚠ framework dependencies older than this CLI (${cliVersion()}):`));\n for (const dep of drift.behind) {\n console.log(chalk.dim(` ${dep.name}@${dep.range} (${dep.file})`));\n }\n console.log(chalk.dim(\" The image supplies the server, but your bundle supplies the database\"));\n console.log(chalk.dim(\" driver — a newer runtime does not update it.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\`, then rebuild.`));\n } else if (drift.disagreeing.length > 0) {\n console.log(chalk.yellow(` ⚠ mixed @rebasepro versions declared: ${drift.disagreeing.join(\", \")}`));\n console.log(chalk.dim(\" These are published together and expect to run together.\"));\n console.log(chalk.dim(` Run \\`${upgradeToThisCli()}\\` to pin them alike, then rebuild.`));\n }\n\n /* Fold the project's static apps into the backend bundle, so ONE\n runtime serves the site at `/`, the admin at `/admin` and the API\n at `/api` — the shape the scaffolded template produces and the\n shape a custom container already had.\n\n Without this, moving a project to the managed runtime silently\n removed its website: the API answered perfectly and every page\n 404'd, because the managed pod runs the backend bundle and nothing\n else. Parity with the container being replaced is the only honest\n baseline for calling managed a drop-in.\n\n `--no-static` opts out, for a project that publishes its frontend\n somewhere else and does not want the assets in its bundle. */\n if (!args[\"--no-static\"]) {\n const folded = await foldFrontendIntoBundle({\n projectRoot,\n manifest,\n bundleDir: result.outDir,\n skipBuild: args[\"--skip-static-build\"] === true,\n log: (m) => console.log(m)\n }).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n for (const outcome of folded ?? []) {\n console.log(\n chalk.green(` ✓ ${outcome.appName} folded in`) +\n chalk.dim(` (${outcome.fileCount} file(s) → served at ${outcome.path})`)\n );\n }\n }\n } else if (app.type === \"static\") {\n await buildAssetApp(projectRoot, name, app, manifest.rebase, output).catch((err: unknown) => {\n console.error(chalk.red(` ✗ ${err instanceof Error ? err.message : String(err)}`));\n process.exit(1);\n });\n }\n\n console.log(\"\");\n }\n\n console.log(chalk.green(\"✓ Build complete.\"));\n}\n\n/**\n * Build a static app and package it into a static bundle.\n *\n * Runs the app's own build command, checks it produced the declared output, then\n * packages that output into a `static`-kind bundle — the same deployable shape as\n * a backend bundle, so a frontend or admin app deploys through the identical\n * path and runs on the identical image, just serving files instead of an API.\n *\n * Throws when the build fails or produces nothing usable, so the caller answers\n * in its own way: `rebase build` with a red line, `rebase cloud deploy --json`\n * with its JSON error.\n */\nexport async function buildAssetApp(\n projectRoot: string,\n name: string,\n app: RebaseAppConfig,\n runtimeRange: string,\n outOverride?: string,\n /** `quietStdout`: every line, the build command's included, goes to stderr. See `toolStdio`. */\n options: { quietStdout?: boolean } = {}\n): Promise<string | undefined> {\n const asset = app as RebaseStaticAppConfig;\n const basePath = asset.path ?? \"/\";\n const say = (line: string): void => {\n if (options.quietStdout) console.error(line);\n else console.log(line);\n };\n\n if (!asset.build) {\n say(chalk.dim(\" no build command declared — skipping\"));\n return undefined;\n }\n\n try {\n await execa(asset.build, {\n cwd: projectRoot,\n stdio: toolStdio(options.quietStdout),\n shell: true,\n env: staticBuildEnv(basePath, name)\n });\n } catch {\n throw new Error(`build command failed for \"${name}\"`);\n }\n\n if (!asset.output) {\n say(chalk.yellow(\" no output directory declared — built, but nothing to bundle\"));\n return undefined;\n }\n\n const outputPath = path.join(projectRoot, asset.output);\n if (!fs.existsSync(outputPath)) {\n // The command exited 0 but produced nothing where the manifest says it\n // should. Bundling that would ship an empty site.\n throw new Error(`declared output \"${asset.output}\" does not exist after building`);\n }\n\n // The assets were built for `basePath`; refusing here is the difference\n // between a build error and a blank page nobody can diagnose.\n const indexHtml = path.join(outputPath, \"index.html\");\n if (fs.existsSync(indexHtml)) {\n assertBuiltForPath(fs.readFileSync(indexHtml, \"utf8\"), basePath, name);\n }\n\n // Per-app bundle directory, so a project's several static apps do not clobber\n // one another or the backend's `dist-bundle`.\n const outDir = outOverride\n ? path.resolve(process.cwd(), outOverride)\n : path.join(projectRoot, `dist-bundle-${name}`);\n const result = buildStaticBundle({\n projectRoot,\n appName: name,\n assetsDir: outputPath,\n outDir,\n runtimeRange,\n path: basePath,\n spa: asset.spa ?? true,\n cms: asset.cms\n });\n const rel = path.relative(projectRoot, result.outDir);\n say(\n chalk.green(` ✓ static bundle → ${rel}/`) +\n chalk.dim(` (${result.fileCount} file(s) → served at ${basePath})`)\n );\n return result.outDir;\n}\n\n/**\n * The `rebase upgrade` line the drift warnings print.\n *\n * Aimed at this CLI's own version, because that is what the warning measured\n * against: \"older than this CLI\" is answered by moving to exactly this CLI, not\n * to whatever `latest` happens to be — which, on a canary, is older still.\n */\nfunction upgradeToThisCli(): string {\n const version = cliVersion();\n return version === \"unknown\" ? \"rebase upgrade\" : `rebase upgrade --to ${version}`;\n}\n\n/** The pre-manifest behaviour: build every workspace package. */\nasync function runWorkspaceBuilds(projectRoot: string): Promise<void> {\n const pm = detectPackageManager(projectRoot);\n const cmds = getPMCommands(pm);\n const buildCmd = cmds.runAll(\"build\");\n\n console.log(`${chalk.bold(\"Rebase\")} — Building all workspaces with ${chalk.cyan(pm)}...\\n`);\n\n try {\n await execa(buildCmd[0], buildCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\"\n });\n } catch {\n console.error(chalk.red(\"\\n✗ Build failed.\"));\n process.exit(1);\n }\n}\n","/**\n * CLI command: rebase eject\n *\n * The supported route from the managed runtime to a custom one.\n *\n * Without it, `runtime: \"custom\"` is a mode a user can only reach by\n * hand-writing an entrypoint they have never seen. The template used to solve\n * that by scaffolding `backend/src/index.ts` into every project — ~190 lines\n * configuring CORS, auth, cookies, storage and history, which the managed\n * runtime never loads. It was the most important-looking file in a new project\n * and editing it did nothing.\n *\n * So the file moved here. A managed project does not carry it; a project that\n * asks for it gets it together with the Dockerfile and the manifest change that\n * make it actually run.\n *\n * There is deliberately no `rebase uneject`. Going back is deleting two files\n * and editing one line, and a command that silently discarded a user's server\n * code would be worse than its absence.\n */\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\nimport type { RebaseBackendAppConfig } from \"@rebasepro/types\";\nimport { requireProjectRoot } from \"../utils/project\";\nimport { findBackendApp, loadManifest, ManifestError, resolveBackendPaths, writeManifest } from \"../manifest\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/** Walk up to the package root, which holds `templates/`. */\nfunction findCliRoot(from: string): string | null {\n const root = path.parse(from).root;\n let dir = from;\n while (dir && dir !== root) {\n if (fs.existsSync(path.join(dir, \"templates\", \"eject\"))) return dir;\n dir = path.dirname(dir);\n }\n return null;\n}\n\n/**\n * The two ways one project's payload differs from another's.\n *\n * Neither is a flag: both were decided at `rebase init` time. `--headless`\n * deletes `config/collections`, `backend/src/schema.generated.ts` and\n * `frontend/`, so a payload that assumes them emits an entrypoint importing\n * three files that are not there and a Dockerfile whose first `COPY` fails.\n */\ninterface ProjectShape {\n /**\n * Collections declared in code, under `<config>/collections`. Without them\n * the server derives its API from the live database instead — the same\n * signal `rebase build` reads.\n */\n collections: boolean;\n /** A `frontend` workspace for the image to build and the entrypoint to serve. */\n frontend: boolean;\n}\n\n/**\n * The block names the payload may switch on. A typo has to be an error.\n *\n * Typed as keys of {@link ProjectShape}, which is what makes that true: `as\n * const` alone gave these two string literals and tied them to nothing, so a\n * flag renamed on the interface left this list naming a block that no longer\n * exists, and the template kept switching on it.\n */\nconst SHAPE_FLAGS: readonly (keyof ProjectShape)[] = [\"collections\", \"frontend\"];\n\n/** Narrow a marker name to a flag, having checked it is one. */\nfunction isShapeFlag(name: string): name is keyof ProjectShape {\n return (SHAPE_FLAGS as readonly string[]).includes(name);\n}\n\n/**\n * Render one payload file for this project.\n *\n * The payload is one set of files rather than one per flavour, because the\n * flavours differ by about a dozen lines and two copies of a 230-line\n * entrypoint are how copies drift — the payload had already drifted from\n * `app/backend/src/index.ts` over `cronsDir`, which silently stopped every cron\n * job in an ejected project. So both branches live in the file, marked with\n * lines that are comments in TypeScript, YAML and Dockerfiles alike:\n *\n * // {{#collections}}\n * import { tables } from \"./schema.generated.js\";\n * // {{/collections}}\n * // {{^collections}}\n * // No schema module: this project introspects the database.\n * // {{/collections}}\n *\n * `{{#name}}` keeps its block when the flag is on, `{{^name}}` when it is off,\n * and the marker lines themselves never reach the user. The template stays\n * valid TypeScript with every marker line removed, which is the flavour a\n * typechecker would see.\n */\nexport function renderPayload(contents: string, shape: ProjectShape, projectName: string): string {\n const out: string[] = [];\n let open: { name: string; keep: boolean } | null = null;\n\n for (const line of contents.split(\"\\n\")) {\n const marker = /^\\s*(?:\\/\\/|#)\\s*\\{\\{([#^/])([A-Za-z]+)\\}\\}\\s*$/.exec(line);\n if (!marker) {\n if (!open || open.keep) out.push(line);\n continue;\n }\n const [, kind, name] = marker;\n if (kind === \"/\") {\n if (!open || open.name !== name) {\n throw new Error(`Eject template: {{/${name}}} does not close an open block.`);\n }\n open = null;\n continue;\n }\n if (open) throw new Error(`Eject template: {{${kind}${name}}} inside an open ${open.name} block.`);\n if (!isShapeFlag(name)) {\n throw new Error(`Eject template: unknown block {{${kind}${name}}}.`);\n }\n // `shape[name]` directly: the check above narrows `name` to a key of\n // `ProjectShape`, which is what the `as unknown as Record<string,\n // boolean>` on the shape was standing in for — and that cast also meant\n // nothing checked that the block names and the interface agree.\n open = { name,\nkeep: kind === \"#\" ? shape[name] === true : shape[name] !== true };\n }\n\n if (open) throw new Error(`Eject template: {{#${open.name}}} was never closed.`);\n // A replacer function: the name is read from package.json unchecked, and a\n // replacement string would expand any `$&`, `$'` or `$$` in it.\n return out.join(\"\\n\").replace(/\\{\\{PROJECT_NAME\\}\\}/g, () => projectName);\n}\n\n/** Files the eject payload contributes, as `<source> → <destination>`. */\nconst PAYLOAD: { from: string; to: string; overwrite: boolean }[] = [\n // The entrypoint IS the point of ejecting, so it replaces whatever is\n // there — but only with `--force`, and only after keeping the old file as\n // `.bak`. `runtime: \"custom\"` (the guard below) means \"already ejected\",\n // not \"nobody wrote a server here\": a managed project can have a\n // hand-written `backend/src/index.ts` that `rebase dev` has been running.\n { from: \"backend/src/index.ts\",\nto: \"backend/src/index.ts\",\noverwrite: true },\n { from: \"backend/src/env.ts\",\nto: \"backend/src/env.ts\",\noverwrite: true },\n // The declarations the emitted server imports. Never overwritten — a\n // project that already declares its resources owns that file, and replacing\n // it would silently drop every bucket and database it named. Written when\n // absent because the entrypoint imports it unconditionally: an ejected\n // server that cannot resolve its own resources does not start.\n { from: \"config/resources.ts\",\nto: \"config/resources.ts\",\noverwrite: false },\n // Never overwritten: a Dockerfile someone already wrote is theirs, and so is\n // a compose file they have edited. The scaffolded `docker-compose.yml` is\n // deliberately left alone — it runs the managed shape, and going back should\n // stay a one-line change rather than a restore from git.\n { from: \"Dockerfile\",\nto: \"Dockerfile\",\noverwrite: false },\n { from: \"docker-compose.custom.yml\",\nto: \"docker-compose.custom.yml\",\noverwrite: false }\n];\n\n/**\n * The project's name, for the `{{PROJECT_NAME}}` the payload carries.\n *\n * Falls back to the directory name — a compose project name is cosmetic, and a\n * missing or unreadable package.json is not a reason to refuse to eject.\n */\nfunction projectNameOf(projectRoot: string): string {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(projectRoot, \"package.json\"), \"utf8\"));\n if (typeof pkg.name === \"string\" && pkg.name.trim()) return pkg.name.trim();\n } catch {\n // fall through\n }\n return path.basename(projectRoot);\n}\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase eject\")} — take ownership of the server process\n\nWrites the backend entrypoint and a Dockerfile into this project, and flips its\nbackend to ${chalk.cyan('runtime: \"custom\"')}. From then on this repository builds its own\nimage: platform runtime upgrades no longer reach it, and CORS, auth wiring,\nstorage and shutdown become yours to configure.\n\n${chalk.bold(\"Usage\")}\n rebase eject [app] Take ownership of the server process\n\n${chalk.bold(\"Options\")}\n --dry-run List what would change, and change nothing\n --force Replace an existing backend/src/index.ts or\n env.ts, keeping the current file as <name>.bak\n -h, --help Show this help\n`.trim());\n}\n\nexport async function ejectCommand(rawArgs: string[] = []): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags: args, positionals } = parseCommandArgs({\n spec: {\n \"--dry-run\": Boolean,\n \"--force\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"eject\",\n maxPositionals: 1\n });\n\n const projectRoot = requireProjectRoot();\n const dryRun = Boolean(args[\"--dry-run\"]);\n const force = Boolean(args[\"--force\"]);\n // Strict parsing rejects an undeclared flag rather than filing it under the\n // positionals, so the first one is the app — there is nothing to filter out.\n const requested = positionals[0];\n\n let loaded;\n try {\n loaded = loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.dim(` ${issue.path}: ${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n\n const { manifest } = loaded;\n\n let appName: string;\n let app: RebaseBackendAppConfig;\n\n if (requested) {\n const declared = manifest.apps[requested];\n if (!declared) {\n console.error(chalk.red(`✗ No app named \"${requested}\" in rebase.json.`));\n console.error(chalk.dim(` Declared: ${Object.keys(manifest.apps).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n if (declared.type !== \"backend\") {\n // Ejecting is about who runs the server. A static app has no server.\n console.error(chalk.red(`✗ \"${requested}\" is a ${declared.type} app — only a backend can be ejected.`));\n process.exit(1);\n }\n appName = requested;\n app = declared;\n } else {\n const backend = findBackendApp(manifest);\n if (!backend) {\n console.error(chalk.red(\"✗ This repository declares no backend app.\"));\n console.error(chalk.dim(\" Only the repository that declares the backend chooses its runtime.\"));\n process.exit(1);\n }\n appName = backend.name;\n app = backend.app;\n }\n\n if (app.runtime === \"custom\") {\n console.error(chalk.red(`✗ \"${appName}\" is already ejected — it declares runtime: \"custom\".`));\n console.error(chalk.dim(` Its entrypoint is ${app.dockerfile ?? \"Dockerfile\"} and backend/src/index.ts.`));\n process.exit(1);\n }\n\n const cliRoot = findCliRoot(__dirname);\n if (!cliRoot) {\n console.error(chalk.red(\"✗ Could not locate the eject templates. Reinstall @rebasepro/cli.\"));\n process.exit(1);\n }\n const payloadDir = path.join(cliRoot!, \"templates\", \"eject\");\n\n // What the payload has to look like here. Read from the project rather than\n // asked for: `--headless` left no collections and no frontend, and an\n // entrypoint importing either would not compile.\n const paths = resolveBackendPaths(app, projectRoot);\n const shape: ProjectShape = {\n collections: paths.hasCollections,\n frontend: fs.existsSync(path.join(projectRoot, \"frontend\"))\n };\n\n // Decide everything before writing anything, so --dry-run and the real run\n // report the same list and a mid-way failure cannot leave a half-ejected\n // project.\n const planned: { to: string; action: \"write\" | \"keep\" | \"overwrite\" }[] = [];\n const blocked: string[] = [];\n for (const file of PAYLOAD) {\n const source = path.join(payloadDir, file.from);\n if (!fs.existsSync(source)) {\n console.error(chalk.red(`✗ The eject template is missing ${file.from}. Reinstall @rebasepro/cli.`));\n process.exit(1);\n }\n const exists = fs.existsSync(path.join(projectRoot, file.to));\n if (exists && file.overwrite && !force) blocked.push(file.to);\n planned.push({\n to: file.to,\n action: !exists ? \"write\" : file.overwrite ? \"overwrite\" : \"keep\"\n });\n }\n\n if (blocked.length > 0) {\n // A managed backend never loads `backend/src/index.ts`, but `rebase dev`\n // does — it picks the entrypoint by file existence — so this file is very\n // often a server someone is running and editing. Replacing it without\n // being asked is the one unrecoverable thing this command could do.\n console.error(chalk.red(\"✗ Ejecting would replace a file this project already has:\"));\n for (const item of blocked) console.error(chalk.red(` ${item}`));\n console.error(chalk.dim(\" Eject writes its own entrypoint — it does not adopt yours.\"));\n console.error(chalk.dim(\" Move the file aside, or re-run with --force, which keeps the current\"));\n console.error(chalk.dim(\" contents as <name>.bak.\"));\n process.exit(1);\n }\n\n if (dryRun) {\n console.log(chalk.bold(`Would eject \"${appName}\" to a custom runtime:`));\n console.log(\"\");\n for (const item of planned) {\n if (item.action === \"write\") console.log(` ${chalk.green(\"write\")} ${item.to}`);\n else if (item.action === \"overwrite\") {\n console.log(` ${chalk.yellow(\"overwrite\")} ${item.to} ${chalk.dim(`(kept as ${item.to}.bak)`)}`);\n } else console.log(` ${chalk.dim(\"keep\")} ${item.to} ${chalk.dim(\"(already exists)\")}`);\n }\n console.log(` ${chalk.green(\"write\")} rebase.json ${chalk.dim('(runtime: \"custom\")')}`);\n // Not part of the payload table, but it is changed on the real run, and\n // a dry run's whole purpose is to enumerate what changes.\n if (fs.existsSync(path.join(projectRoot, \"backend\", \"package.json\"))) {\n console.log(` ${chalk.green(\"write\")} backend/package.json ${chalk.dim(\"(main, dev and start scripts)\")}`);\n }\n console.log(\"\");\n console.log(chalk.dim(\"Nothing was changed.\"));\n return;\n }\n\n const projectName = projectNameOf(projectRoot);\n const backups: string[] = [];\n for (const [index, file] of PAYLOAD.entries()) {\n if (planned[index].action === \"keep\") continue;\n const destination = path.join(projectRoot, file.to);\n if (planned[index].action === \"overwrite\") {\n fs.copyFileSync(destination, `${destination}.bak`);\n backups.push(`${file.to}.bak`);\n }\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n const contents = renderPayload(\n fs.readFileSync(path.join(payloadDir, file.from), \"utf8\"),\n shape,\n projectName\n );\n fs.writeFileSync(destination, contents, \"utf8\");\n }\n\n const dockerfile = app.dockerfile ?? \"Dockerfile\";\n manifest.apps[appName] = {\n ...app,\n runtime: \"custom\",\n dockerfile,\n port: app.port ?? 8080\n };\n writeManifest(projectRoot, manifest);\n\n // The backend workspace stops being a package the runtime reads and becomes\n // one that is run. Its scripts have to say so, or `npm start` in the image\n // has nothing to call.\n restoreBackendScripts(projectRoot);\n\n console.log(\"\");\n console.log(chalk.green(`✓ Ejected \"${appName}\" to a custom runtime.`));\n console.log(\"\");\n console.log(` ${chalk.cyan(\"backend/src/index.ts\".padEnd(26))} your entrypoint — the runtime no longer boots the bundle`);\n console.log(` ${chalk.cyan(\"backend/src/env.ts\".padEnd(26))} the environment it reads`);\n console.log(` ${chalk.cyan(dockerfile.padEnd(26))} your image`);\n console.log(` ${chalk.cyan(\"docker-compose.custom.yml\".padEnd(26))} runs it`);\n console.log(` ${chalk.cyan(\"rebase.json\".padEnd(26))} runtime: custom`);\n for (const backup of backups) {\n console.log(` ${chalk.cyan(backup.padEnd(26))} what was there before`);\n }\n console.log(\"\");\n console.log(chalk.yellow(\" You now own CORS, auth wiring, storage and shutdown. Platform runtime\"));\n console.log(chalk.yellow(\" upgrades no longer reach this project.\"));\n if (!shape.collections) {\n console.log(chalk.yellow(\" This project declares no collections, so the entrypoint derives them\"));\n console.log(chalk.yellow(\" from the live database, as the managed runtime did.\"));\n }\n console.log(\"\");\n console.log(chalk.dim(` ${chalk.cyan(\"docker compose -f docker-compose.custom.yml up --build\")}`));\n console.log(chalk.dim(\" docker-compose.yml is untouched — it still runs the managed shape if you go back.\"));\n console.log(\"\");\n}\n\n/**\n * Point the backend workspace's scripts at the entrypoint that now exists.\n *\n * A managed project's backend package deliberately declares no `main` and no\n * `start`: there is no entrypoint to name. Ejecting creates one.\n */\nfunction restoreBackendScripts(projectRoot: string): void {\n const packagePath = path.join(projectRoot, \"backend\", \"package.json\");\n if (!fs.existsSync(packagePath)) return;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(fs.readFileSync(packagePath, \"utf8\"));\n } catch {\n // A malformed package.json is the user's to fix, and refusing to finish\n // the eject over it would leave the project half-changed.\n console.log(chalk.yellow(\" ⚠ backend/package.json is not valid JSON — its scripts were left alone.\"));\n return;\n }\n\n const scripts = (parsed.scripts ?? {}) as Record<string, string>;\n parsed.main ??= \"src/index.ts\";\n scripts.dev ??= 'tsx watch --include=\"../config/**/*\" --include=\"./functions/**/*\" src/index.ts';\n scripts.start ??= \"node dist/backend/src/index.js\";\n parsed.scripts = scripts;\n\n fs.writeFileSync(packagePath, `${JSON.stringify(parsed, null, 4)}\\n`, \"utf8\");\n}\n","/**\n * CLI command: rebase start\n *\n * Runs a built bundle through the Rebase runtime — the same path the official\n * container image takes, so what you test locally is what a deployment runs.\n *\n * When there is no bundle (an ejected backend, or a project that has not adopted\n * `rebase.json`) this falls back to the backend workspace's own `start` script,\n * which is what such a project has always used.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport { requireProjectRoot, findEnvFile } from \"../utils/project\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { detectPackageManager, getPMCommands } from \"../utils/package-manager\";\nimport { DEFAULT_BUNDLE_DIR } from \"../bundle\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase start\")} — run a built bundle\n\n${chalk.bold(\"Usage\")}\n rebase start [options]\n\n${chalk.bold(\"Options\")}\n --bundle <dir> Bundle directory (default: ${DEFAULT_BUNDLE_DIR})\n --workspace Run the backend workspace's own start script\n -h, --help Show this help\n\nBuild first with ${chalk.cyan(\"rebase build\")}.\n`.trim());\n}\n\nexport async function startCommand(rawArgs: string[] = []): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags: args } = parseCommandArgs({\n spec: {\n \"--bundle\": String,\n \"--workspace\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"start\",\n maxPositionals: 0\n });\n\n const projectRoot = requireProjectRoot();\n\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n\n const bundleDir = path.resolve(projectRoot, args[\"--bundle\"] ?? DEFAULT_BUNDLE_DIR);\n const hasBundle = fs.existsSync(path.join(bundleDir, \"manifest.json\"));\n\n if (args[\"--workspace\"] || !hasBundle) {\n if (!args[\"--workspace\"] && !hasBundle) {\n console.log(chalk.dim(\n `No bundle at ${path.relative(projectRoot, bundleDir)}/ — ` +\n \"starting the backend workspace instead.\\n\"\n ));\n }\n await startWorkspaceBackend(projectRoot, env);\n return;\n }\n\n ensureBundleDependencies(projectRoot, bundleDir);\n\n console.log(`${chalk.bold(\"Rebase\")} — starting runtime from ${chalk.cyan(path.relative(projectRoot, bundleDir))}/\\n`);\n\n // Loaded in-process rather than spawned: the runtime is a library here, so\n // signals, exit codes and stdio need no forwarding, and there is one less\n // process between the developer and a stack trace.\n if (envFile && fs.existsSync(envFile)) {\n const dotenv = await import(\"dotenv\");\n dotenv.config({ path: envFile, quiet: true });\n }\n\n process.env.REBASE_BUNDLE = bundleDir;\n\n try {\n const { runFromBundle } = await import(\"@rebasepro/server\");\n await runFromBundle({ bundleDir });\n } catch (err) {\n console.error(chalk.red(\"\\n✗ Failed to start the runtime.\"));\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\n/**\n * Make a bundle's imports resolvable for a local run.\n *\n * Node resolves a module by walking up from the *importing file*, so compiled\n * code sitting in `dist-bundle/` no longer sees the per-package `node_modules`\n * its source could: pnpm and npm both install a workspace package's\n * dependencies inside that package, and the bundle is not inside any of them.\n *\n * A deployment solves this by installing the bundle's own `package.json` beside\n * it — that is what the generated `package.json` is for. Locally, doing a second\n * install to run code whose dependencies are already on disk would be wasteful,\n * so this links what is already there instead.\n *\n * Only ever created when absent, and only under the bundle directory, so a real\n * install always wins and nothing here is ever uploaded (`rebase build` cleans\n * the directory and never writes this).\n */\nfunction ensureBundleDependencies(projectRoot: string, bundleDir: string): void {\n const target = path.join(bundleDir, \"node_modules\");\n if (fs.existsSync(target)) return;\n\n // Later sources fill gaps left by earlier ones; the backend's tree wins\n // because it holds the server and driver the runtime itself needs.\n const sources = [\"backend/node_modules\", \"config/node_modules\", \"node_modules\"]\n .map(relative => path.join(projectRoot, relative))\n .filter(dir => fs.existsSync(dir));\n\n if (sources.length === 0) return;\n\n let linked = 0;\n fs.mkdirSync(target, { recursive: true });\n\n const linkInto = (sourceDir: string, targetDir: string): void => {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(sourceDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name === \".bin\" || entry.name.startsWith(\".\")) continue;\n const from = path.join(sourceDir, entry.name);\n const to = path.join(targetDir, entry.name);\n\n // A scope is a directory of packages, not a package — merge into it\n // so `@a/one` from one tree and `@a/two` from another both resolve.\n if (entry.name.startsWith(\"@\") && entry.isDirectory()) {\n fs.mkdirSync(to, { recursive: true });\n linkInto(from, to);\n continue;\n }\n\n if (fs.existsSync(to)) continue;\n try {\n fs.symlinkSync(fs.realpathSync(from), to, \"junction\");\n linked++;\n } catch {\n // A package that cannot be linked simply stays unresolved, and\n // the runtime will say so by name if it actually needed it.\n }\n }\n };\n\n for (const source of sources) linkInto(source, target);\n\n if (linked > 0) {\n console.log(chalk.dim(\n ` linked ${linked} package(s) into the bundle for this local run\\n` +\n \" (a deployment installs the bundle's package.json instead)\\n\"\n ));\n }\n}\n\nasync function startWorkspaceBackend(projectRoot: string, env: Record<string, string>): Promise<void> {\n const pm = detectPackageManager(projectRoot);\n const cmds = getPMCommands(pm);\n const startCmd = cmds.runWorkspace(\"backend\", \"start\");\n\n console.log(`${chalk.bold(\"Rebase\")} — Starting backend server...\\n`);\n\n try {\n await execa(startCmd[0], startCmd.slice(1), {\n cwd: projectRoot,\n stdio: \"inherit\",\n env\n });\n } catch {\n console.error(chalk.red(\"\\n✗ Failed to start server.\"));\n process.exit(1);\n }\n}\n","/**\n * CLI command: rebase auth <action>\n *\n * Subcommands:\n * reset-password — Reset a user's password\n */\nimport chalk from \"chalk\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { spawn } from \"child_process\";\nimport { randomBytes } from \"node:crypto\";\nimport {\n requireProjectRoot,\n requireBackendDir,\n findEnvFile,\n readEnvFile,\n resolveTsx,\n exitDependenciesNotInstalled\n} from \"../utils/project\";\nimport { unknownCommand } from \"../utils/unknown-command\";\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const AUTH_SUBCOMMANDS = [\"reset-password\"] as const;\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\n\n/** A user as the admin API returns it, reduced to what this command needs. */\nexport interface ResolvedUser {\n id: string;\n email: string;\n}\n\n/**\n * Pick the user with exactly this email out of a search response.\n *\n * `/api/admin/users?search=` is an `ILIKE '%…%'` over email **or display\n * name**, ordered by role count descending. This used to take row `[0]` and\n * reset it, then print the email it had been *given* as confirmation — so two\n * ordinary situations ended in a successful-looking reset of somebody else's\n * account:\n *\n * - a substring collision: `bob@example.com` also matches\n * `robert.bob@example.com`;\n * - a display name, which is user-controlled and accepted up to 255\n * characters with no constraint on its content, containing an address\n * belonging to someone else.\n *\n * The ordering makes it worse rather than better — `array_length(roles) DESC\n * NULLS LAST` puts the most privileged match first, so the account most likely\n * to be reset by mistake is an admin's.\n *\n * Returns `undefined` when nothing matched exactly, which the caller reports\n * rather than falling through to a guess. The direct-database fallback below\n * has always matched with `eq(usersTable.email, email)`; this is the same\n * definition, so the command no longer resets different accounts depending on\n * whether the backend happened to be running.\n */\nexport function selectUserForEmail(payload: unknown, email: string): ResolvedUser | undefined {\n const wanted = email.trim().toLowerCase();\n if (!wanted) return undefined;\n\n const rows: unknown[] = Array.isArray(payload)\n ? payload\n : (payload && typeof payload === \"object\" && Array.isArray((payload as { users?: unknown }).users)\n ? (payload as { users: unknown[] }).users\n : []);\n\n for (const row of rows) {\n if (!row || typeof row !== \"object\") continue;\n const record = row as Record<string, unknown>;\n const rowEmail = typeof record.email === \"string\" ? record.email.trim().toLowerCase() : undefined;\n if (!rowEmail || rowEmail !== wanted) continue;\n\n const id = typeof record.id === \"string\"\n ? record.id\n : (typeof record.uid === \"string\" ? record.uid : undefined);\n if (!id) continue;\n\n return { id, email: record.email as string };\n }\n\n return undefined;\n}\n\nexport async function authCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // `--help` is answered here and never reaches a handler. `cli.ts` only\n // rewrites the subcommand to `\"--help\"` when no subcommand was named, so\n // `rebase auth reset-password --help` used to *run the reset*: `--help`\n // became the email, the backend was contacted, `.tmp-reset-password.ts` was\n // written into the user's `backend/`, and a database UPDATE ran for a user\n // named `--help`. A flag whose whole job is to print text cannot be allowed\n // to reach code that writes.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printAuthHelp();\n return;\n }\n\n switch (subcommand) {\n case \"reset-password\":\n await resetPassword(rawArgs);\n break;\n default:\n unknownCommand(subcommand, AUTH_SUBCOMMANDS, \"auth\");\n }\n}\n\n/**\n * The flags `rebase auth reset-password` takes.\n *\n * `-p` was advertised in this command's own help and never declared here, so\n * `arg` — running permissively — pushed it into the positionals and the value\n * *after* it shifted out of reach: anyone following the help set the account's\n * password to the two-character string `-p`. Declared now, and `auth.test.ts`\n * asserts that the help and this spec list the same aliases.\n */\nexport const RESET_PASSWORD_FLAGS = {\n \"--email\": String,\n \"--password\": String,\n \"-e\": \"--email\",\n \"-p\": \"--password\"\n} as const;\n\n/**\n * Which account, and which password, this invocation names.\n *\n * Both may still be absent — the caller reports a missing email — but neither\n * can be a flag. `parseCommandArgs` parses the whole line strictly, so an\n * undeclared flag is an error rather than a positional. That is what stops\n * `rebase auth reset-password bob@example.com --debug` from setting Bob's\n * password to `--debug`, which is the flag the CLI itself prints after every\n * failure as the thing to re-run with.\n *\n * Exported so its tests can drive the real parser rather than a copy of it.\n */\nexport function resolveResetPasswordArgs(rawArgs: string[]): {\n email?: string;\n password?: string;\n} {\n const { flags, positionals } = parseCommandArgs({\n spec: RESET_PASSWORD_FLAGS,\n rawArgs,\n commandWords: 2,\n command: \"auth reset-password\",\n maxPositionals: 2\n });\n\n // Both spellings are supported: `<email> [password]` and `--email/--password`.\n return {\n email: flags[\"--email\"] || positionals[0],\n password: flags[\"--password\"] || positionals[1]\n };\n}\n\n/**\n * A password for a reset that was not given one.\n *\n * This used to be a constant, and `--help` printed it as the default. Reset is\n * the documented way back into an account nobody can sign in to — an admin,\n * usually — so the recovery path set every such account to a fixed string that\n * ships inside a public repository and a published npm package, and left it\n * there until somebody remembered to change it.\n *\n * base64url of 18 random bytes: 24 characters, ~144 bits, no shell-quoting\n * hazard, and nothing that reads like a placeholder somebody might keep.\n */\nexport function generatePassword(): string {\n return randomBytes(18).toString(\"base64url\");\n}\n\nasync function resetPassword(rawArgs: string[]): Promise<void> {\n const { email, password: providedPassword } = resolveResetPasswordArgs(rawArgs);\n // Generated once, so both reset paths set and report the same thing.\n const wasGenerated = !providedPassword;\n const newPassword = providedPassword || generatePassword();\n\n if (!email) {\n console.error(chalk.red(\"✗ Email is required.\"));\n console.log(\"\");\n console.log(chalk.gray(\" Usage: rebase auth reset-password <email> [new-password]\"));\n console.log(chalk.gray(\" rebase auth reset-password --email user@example.com --password NewPass123!\"));\n process.exit(1);\n }\n\n const projectRoot = requireProjectRoot();\n\n // 1. Try API-first reset\n // Was a single-key regex, which did not match `export REBASE_SERVICE_KEY=…`\n // and kept a trailing `# comment` in the value. The command then fell\n // through to the direct-database path as though no key were configured.\n const envFile = findEnvFile(projectRoot);\n const envServiceKey: string | undefined = readEnvFile(projectRoot).REBASE_SERVICE_KEY;\n\n let baseUrl = process.env.REBASE_BASE_URL;\n let serviceKey = process.env.REBASE_SERVICE_KEY || envServiceKey;\n\n const statePath = path.join(projectRoot, \".rebase\", \"state.json\");\n if (fs.existsSync(statePath)) {\n try {\n const state = JSON.parse(fs.readFileSync(statePath, \"utf8\")) as Record<string, unknown>;\n if (state && typeof state === \"object\") {\n if (typeof state.baseUrl === \"string\" && !baseUrl) {\n baseUrl = state.baseUrl;\n }\n if (typeof state.serviceKey === \"string\" && !serviceKey) {\n serviceKey = state.serviceKey;\n }\n }\n } catch {\n // Ignore\n }\n }\n\n const devUrlPath = path.join(projectRoot, \".rebase-dev-url\");\n if (fs.existsSync(devUrlPath) && !baseUrl) {\n try {\n baseUrl = fs.readFileSync(devUrlPath, \"utf8\").trim();\n } catch {\n // Ignore\n }\n }\n\n if (baseUrl && serviceKey) {\n console.log(\"Trying API-first reset via running backend...\");\n try {\n const finalPass = newPassword;\n const cleanBaseUrl = baseUrl.replace(/\\/+$/, \"\");\n // Not `limit=1`: the search is fuzzy and ordered by role count, so\n // the exact match is not necessarily first — asking for one row can\n // make it unreachable. Ask for a page, then match exactly.\n const searchUrl = `${cleanBaseUrl}/api/admin/users?search=${encodeURIComponent(email)}&limit=50`;\n const searchRes = await fetch(searchUrl, {\n headers: {\n \"Authorization\": `Bearer ${serviceKey}`,\n \"Accept\": \"application/json\"\n }\n });\n if (!searchRes.ok) {\n throw new Error(`Failed to list users: ${searchRes.statusText}`);\n }\n const searchData = await searchRes.json() as unknown;\n if (!searchData || typeof searchData !== \"object\") {\n throw new Error(\"Invalid response format from user search API.\");\n }\n\n const matched = selectUserForEmail(searchData, email);\n if (!matched) {\n throw new Error(`No user has the email ${email}.`);\n }\n\n const resetUrl = `${cleanBaseUrl}/api/admin/users/${matched.id}/reset-password`;\n const resetRes = await fetch(resetUrl, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${serviceKey}`,\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n },\n body: JSON.stringify({ password: finalPass })\n });\n\n if (!resetRes.ok) {\n const errText = await resetRes.text();\n throw new Error(`Password reset endpoint failed: ${errText || resetRes.statusText}`);\n }\n\n console.log(\"API reset successful.\");\n console.log(chalk.bold(\" 🔑 Rebase Auth — Reset Password (via API)\"));\n console.log(\"\");\n // The address as stored, not as typed — they differ in case often\n // enough that echoing the input hides which account was touched.\n console.log(` ${chalk.gray(\"Email:\")} ${matched.email}`);\n // Echoed only when we invented it. A password the operator typed\n // is already theirs; printing it again only adds scrollback.\n console.log(` ${chalk.gray(\"Password:\")} ${wasGenerated ? finalPass : \"*\".repeat(finalPass.length)}`);\n console.log(\"\");\n return;\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n console.warn(chalk.yellow(\"API reset failed, falling back to direct database update...\"));\n console.warn(chalk.gray(` Details: ${errMsg}`));\n }\n }\n\n // 2. Direct-DB Fallback\n const backendDir = requireBackendDir(projectRoot);\n const tsxBin = resolveTsx(projectRoot);\n\n if (!tsxBin) {\n exitDependenciesNotInstalled(projectRoot);\n }\n\n try {\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n env.REBASE_RESET_EMAIL = email;\n env.REBASE_RESET_PASSWORD = newPassword;\n env.REBASE_ENV_FILE_PATH = envFile || path.join(projectRoot, \".env\");\n\n // The database the `db` family would use, resolved the same way. A\n // stock scaffold leaves DATABASE_URL commented out and runs on the\n // managed database, which only exists in a child's environment when\n // something puts it there — without this the script connected with\n // libpq's defaults, localhost:5432 as the OS user. An external\n // DATABASE_URL adds nothing here: the child already reads it.\n const { prepareDatabaseEnv } = await import(\"../dev-db/prepare\");\n const prepared = await prepareDatabaseEnv(projectRoot, {\n onProgress: (message) => console.log(chalk.gray(` ${message}`))\n });\n Object.assign(env, prepared.env);\n\n const scriptContent = resetPasswordScript(wasGenerated);\n\n const tmpScriptPath = path.join(backendDir, \".tmp-reset-password.ts\");\n fs.writeFileSync(tmpScriptPath, scriptContent, \"utf-8\");\n\n console.log(\"\");\n console.log(chalk.bold(\" 🔑 Rebase Auth — Reset Password (Direct DB Fallback)\"));\n console.log(\"\");\n console.log(` ${chalk.gray(\"Email:\")} ${email}`);\n console.log(` ${chalk.gray(\"Database:\")} ${prepared.description}`);\n if (!wasGenerated) {\n console.log(` ${chalk.gray(\"Password:\")} ${\"*\".repeat(newPassword.length)}`);\n }\n console.log(\"\");\n\n const child = spawn(tsxBin, [tmpScriptPath], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n\n // The script is written into the user's backend directory, so every\n // exit has to remove it. Without an `error` handler a failed spawn\n // raises an unhandled event, the process dies before `close`, and\n // `.tmp-reset-password.ts` is left behind to be committed.\n const cleanup = () => {\n try { fs.unlinkSync(tmpScriptPath); } catch { /* already gone */ }\n };\n\n return new Promise((resolve) => {\n child.on(\"error\", (err) => {\n cleanup();\n console.error(chalk.red(\"✗ Could not run the reset script.\"));\n console.error(chalk.gray(` ${err.message}`));\n process.exit(1);\n });\n child.on(\"close\", (code) => {\n cleanup();\n if (code !== 0) {\n process.exit(code ?? 1);\n }\n resolve();\n });\n });\n } catch (err) {\n console.error(chalk.red(\"✗ Direct database update failed.\"));\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\n/**\n * The script the direct-database fallback runs under the project's own tsx, so\n * it resolves the project's `@rebasepro/server-postgres` and schema.\n *\n * It exits 0 only when a row was updated: a missing user and a thrown error are\n * both exit 1. `echoPassword` prints the new password, for a generated one.\n *\n * Exported so its tests can run it.\n */\nexport function resetPasswordScript(echoPassword: boolean): string {\n return `\nimport { createPostgresDatabaseConnection } from \"@rebasepro/server-postgres\";\nimport { hashPassword } from \"@rebasepro/server\";\nimport { eq } from \"drizzle-orm\";\nimport * as dotenv from \"dotenv\";\nimport path from \"path\";\nimport fs from \"fs\";\n\ndotenv.config({ path: process.env.REBASE_ENV_FILE_PATH, quiet: true });\n\nconst email = process.env.REBASE_RESET_EMAIL!;\nconst newPassword = process.env.REBASE_RESET_PASSWORD!;\n\nasync function resetPassword() {\n const { db } = createPostgresDatabaseConnection(process.env.DATABASE_URL!);\n const hash = await hashPassword(newPassword);\n\n let usersTable;\n try {\n const schemaPath = path.resolve(\"./src/schema.generated.ts\");\n if (fs.existsSync(schemaPath)) {\n const schema = await import(\"file://\" + schemaPath);\n usersTable = schema.users || schema.tables?.users;\n }\n } catch (e) {\n // ignore and fallback\n }\n\n if (!usersTable) {\n const pgServer = await import(\"@rebasepro/server-postgres\");\n usersTable = pgServer.users;\n }\n\n const passwordHashKey = (usersTable.passwordHash || \"passwordHash\" in usersTable) ? \"passwordHash\" : \"password_hash\";\n\n const result = await db.update(usersTable)\n .set({ [passwordHashKey]: hash })\n .where(eq(usersTable.email, email))\n .returning({\n id: usersTable.id,\n email: usersTable.email\n });\n\n if (result.length > 0) {\n console.log(\"✅ Password reset for: \" + result[0].email);\n ${echoPassword ? 'console.log(\" New password: \" + newPassword);' : \"\"}\n process.exit(0);\n }\n // Nothing was updated, so nothing was reset. Exiting 0 here reported\n // success for a no-op, which is what a script would have believed.\n console.error(\"✗ User not found: \" + email);\n process.exit(1);\n}\n\n// A thrown error is a failed reset, and exits like one — a refused connection\n// that exits 0 reads as a reset to anything checking the exit code.\nresetPassword().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n`;\n}\n\nfunction printAuthHelp() {\n console.log(`\n${chalk.bold(\"rebase auth\")} — Authentication management commands\n\n${chalk.green.bold(\"Usage\")}\n rebase auth ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"reset-password\")} Reset a user's password\n\n${chalk.green.bold(\"reset-password Options\")}\n ${chalk.blue(\"--email, -e\")} User's email address\n ${chalk.blue(\"--password, -p\")} New password (default: one is generated and printed)\n\n${chalk.green.bold(\"Examples\")}\n rebase auth reset-password user@example.com\n rebase auth reset-password --email user@example.com --password MyNewPass!\n`);\n}\n","/**\n * Detect Postgres connection strings that libpq refuses to parse.\n *\n * libpq splits a URI query parameter on the FIRST `=` and rejects any further\n * one in the same parameter:\n *\n * extra key/value separator \"=\" in URI query parameter: \"options\"\n *\n * That makes a URL like\n *\n * postgresql://u:p@h:5432/db?options=-c%20search_path=public&sslmode=disable\n *\n * unusable by every libpq caller — `pg_dump`/`pg_restore` behind\n * `rebase db backup|restore`, and a plain `psql \"$DATABASE_URL\"`. It is not a\n * version quirk: Postgres 15 through 18 all refuse it.\n *\n * `rebase init` generated exactly that string until 2026-08-18, and the failure\n * is invisible day to day because node-postgres parses URLs itself and accepts\n * it — so `rebase dev` and `rebase db push` work while backups do not. Fixing\n * the generator does nothing for projects that already exist, which is what\n * these functions are for: `rebase doctor` reads them off disk and reports.\n */\n\n/** A query parameter whose value carries a literal `=`. */\nexport interface UnparseableParam {\n /** The parameter name, e.g. \"options\". */\n name: string;\n /** The raw `name=value` text as it appears in the URL. */\n raw: string;\n}\n\n/** Postgres URI schemes. A key/value DSN (\"host=… dbname=…\") is not one. */\nconst POSTGRES_URI_RE = /^postgres(ql)?:\\/\\//i;\n\n/**\n * Return the query parameters libpq would reject, or an empty array.\n *\n * Deliberately not built on `new URL()`: that parser is happy to accept the\n * broken form (it splits on the first `=` and keeps the rest as the value),\n * so it cannot see the defect at all. The rule being checked is libpq's, and\n * it is about the raw text.\n */\nexport function findUnparseableParams(connectionString: string): UnparseableParam[] {\n if (!POSTGRES_URI_RE.test(connectionString)) return [];\n\n const q = connectionString.indexOf(\"?\");\n if (q === -1) return [];\n\n // A fragment is not part of the query.\n const query = connectionString.slice(q + 1).split(\"#\")[0];\n if (!query) return [];\n\n const found: UnparseableParam[] = [];\n for (const part of query.split(\"&\")) {\n if (!part) continue;\n // One separator is the parameter's own; any further one is the defect.\n if (part.split(\"=\").length > 2) {\n found.push({ name: part.slice(0, part.indexOf(\"=\")), raw: part });\n }\n }\n return found;\n}\n\n/**\n * Percent-encode the offending `=` characters, leaving everything else byte for\n * byte as it was.\n *\n * Only the second and later `=` in a parameter are rewritten — the first is the\n * real separator. Nothing else is touched: re-serialising through `URL` would\n * also reorder parameters and turn spaces into `+`, which libpq does not decode,\n * so a \"tidy up\" would trade one unparseable string for another.\n */\nexport function encodeExtraEquals(connectionString: string): string {\n if (findUnparseableParams(connectionString).length === 0) return connectionString;\n\n const q = connectionString.indexOf(\"?\");\n const head = connectionString.slice(0, q + 1);\n const rest = connectionString.slice(q + 1);\n const hash = rest.indexOf(\"#\");\n const query = hash === -1 ? rest : rest.slice(0, hash);\n const fragment = hash === -1 ? \"\" : rest.slice(hash);\n\n const fixed = query\n .split(\"&\")\n .map((part) => {\n const first = part.indexOf(\"=\");\n if (first === -1) return part;\n const name = part.slice(0, first);\n const value = part.slice(first + 1).replace(/=/g, \"%3D\");\n return `${name}=${value}`;\n })\n .join(\"&\");\n\n return `${head}${fixed}${fragment}`;\n}\n\n/** One connection string, found somewhere on disk, that libpq cannot parse. */\nexport interface LibpqUrlFinding {\n /** File it came from, relative to the project root. */\n file: string;\n /** The variable holding it, e.g. \"DATABASE_URL\". */\n variable: string;\n /** Parameter names libpq objects to. */\n params: string[];\n /** The same string with the offending `=` encoded. */\n suggested: string;\n}\n\n/** Variables whose value is a Postgres connection string. */\nconst CONNECTION_VARIABLES = [\"DATABASE_URL\", \"ADMIN_CONNECTION_STRING\"];\n\n/**\n * Scan one file's text for connection strings libpq would reject.\n *\n * Handles both shapes a scaffolded project uses, because both shipped with the\n * defect and a deployed stack is broken by the compose one alone:\n *\n * .env DATABASE_URL=postgresql://…\n * docker-compose.yml DATABASE_URL: postgresql://…\n */\nexport function scanTextForLibpqUrls(file: string, text: string): LibpqUrlFinding[] {\n const findings: LibpqUrlFinding[] = [];\n\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n // Commented-out examples are not what the project runs on.\n if (trimmed.startsWith(\"#\")) continue;\n\n for (const variable of CONNECTION_VARIABLES) {\n // `NAME=value` or `NAME: value`, optionally exported/indented.\n const match = trimmed.match(\n new RegExp(`^(?:export\\\\s+)?${variable}\\\\s*[:=]\\\\s*(.+)$`)\n );\n if (!match) continue;\n\n // Strip surrounding quotes and any trailing comment-free whitespace.\n let value = match[1].trim();\n const quoted = value.match(/^(['\"])(.*)\\1$/);\n if (quoted) value = quoted[2];\n if (!value) continue;\n\n const params = findUnparseableParams(value);\n if (params.length === 0) continue;\n\n findings.push({\n file,\n variable,\n params: params.map((p) => p.name),\n suggested: encodeExtraEquals(value)\n });\n }\n }\n\n return findings;\n}\n","/**\n * The checks that need no database, and that catch what breaks a first run.\n *\n * `rebase doctor` compared three descriptions of a schema, which is the right\n * check for a project that is working and the wrong one for a project that has\n * never worked. Everything that stops a first run — the wrong Node, two\n * lockfiles disagreeing, two collections claiming one slug, a `JWT_SECRET`\n * short enough to be guessed, a half-installed workspace with three versions of\n * `@rebasepro/server` in it — happens before a single table is compared, and\n * doctor said nothing about any of it.\n *\n * Every function here is pure: it takes what it read and returns findings. The\n * reading and the printing are at the edges, in `commands/doctor.ts`, so each\n * check has a fixture that fails it without a filesystem, a project or a\n * database.\n */\n\n/** One thing that is wrong, and what to do about it. */\nexport interface EnvironmentFinding {\n /** Which check produced it, for grouping in the report. */\n check: \"node\" | \"package-manager\" | \"collections\" | \"env\" | \"versions\" | \"atlas\";\n severity: \"error\" | \"warning\";\n message: string;\n fix: string;\n}\n\n// ── Atlas ────────────────────────────────────────────────────────────────\n\n/** What is on disk for `@ariga/atlas`, read by `commands/doctor.ts`. */\nexport interface AtlasBinaryState {\n /** A `node_modules/.bin/atlas` the project's commands would find. */\n onPath: boolean;\n /** `@ariga/atlas/package.json` resolves from the project. */\n packageInstalled: boolean;\n /** The binary the package's `bin` names exists as a file. */\n binaryOnDisk: boolean;\n /** For the remedy: the reader's own package manager. */\n manager: string;\n}\n\n/**\n * Whether `db push`, `db generate` and `db migrate` can run at all.\n *\n * They shell out to `atlas`, and its absence is invisible until one of them is\n * run: `@ariga/atlas` downloads its platform binary in `preinstall`, pnpm 10+\n * and npm 12+ refuse a dependency's lifecycle scripts unless allowlisted, and\n * the install exits 0 either way. The scaffold allowlists it, so this is a\n * problem for the person who added `@rebasepro/server-postgres` to a project\n * they already had — five lines of `ERR_PNPM_IGNORED_BUILDS` and\n * `Failed to create bin … ENOENT`, several screens up, with nothing saying that\n * a schema push will fail later.\n *\n * Three states, because two of them need opposite advice. The package absent is\n * an install; the package present with no binary is an allowlist; the binary\n * present with no `.bin` shim is a re-install, and telling that reader their\n * build scripts are blocked sends them to a command that does nothing.\n */\nexport function checkAtlasBinary(state: AtlasBinaryState | null): EnvironmentFinding[] {\n if (!state || state.onPath) return [];\n\n if (!state.packageInstalled) {\n return [{\n check: \"atlas\",\n severity: \"warning\",\n message: \"The atlas binary is not on PATH and @ariga/atlas is not installed — \"\n + \"`db push`, `db generate` and `db migrate` will fail.\",\n fix: `Install it: ${state.manager} add -D @ariga/atlas, and allow its install script.`\n }];\n }\n\n if (!state.binaryOnDisk) {\n return [{\n check: \"atlas\",\n severity: \"warning\",\n message: \"@ariga/atlas is installed and its binary is missing — its `preinstall` \"\n + \"script was blocked, so `db push` and `db migrate` will fail.\",\n fix: \"Allow the build script (pnpm: `allowBuilds` in pnpm-workspace.yaml or \"\n + \"`pnpm approve-builds`; npm: `allowScripts` in package.json), then re-install.\"\n }];\n }\n\n return [{\n check: \"atlas\",\n severity: \"warning\",\n message: \"The atlas binary is on disk but node_modules/.bin/atlas is missing, \"\n + \"so nothing can invoke it.\",\n fix: \"Re-resolve the tree so the link is recreated: `pnpm install --force`, or delete \"\n + \"node_modules and install again.\"\n }];\n}\n\n// ── Node ─────────────────────────────────────────────────────────────────\n\n/**\n * `20.11.0` → `[20, 11, 0]`, ignoring anything after the patch.\n *\n * A bare major is a version: `>=20` is how every `engines.node` in this repo is\n * written, and requiring a minor here made the whole check return nothing —\n * silently, which is the only way a check like this ever fails.\n */\nfunction parseVersion(raw: string): [number, number, number] | null {\n const match = raw.trim().replace(/^v/, \"\").match(/^(\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))?/);\n if (!match) return null;\n return [Number(match[1]), Number(match[2] ?? 0), Number(match[3] ?? 0)];\n}\n\n/** The lowest version a `>=x.y.z` range admits, or null for anything else. */\nexport function minimumFromRange(range: string): [number, number, number] | null {\n const match = range.match(/>=\\s*v?(\\d+(?:\\.\\d+)?(?:\\.\\d+)?)/);\n return match ? parseVersion(match[1]) : null;\n}\n\nfunction isBelow(actual: [number, number, number], minimum: [number, number, number]): boolean {\n for (let i = 0; i < 3; i++) {\n if (actual[i] < minimum[i]) return true;\n if (actual[i] > minimum[i]) return false;\n }\n return false;\n}\n\n/**\n * Is the running Node old enough to break things that will not say so?\n *\n * The symptoms are not \"unsupported Node\". They are a syntax error inside a\n * dependency, a missing global, or — the one that costs the most time — a\n * `node:` builtin that resolves and then behaves differently. Naming the\n * version is the whole check.\n */\nexport function checkNodeVersion(running: string, required: string | undefined): EnvironmentFinding[] {\n if (!required) return [];\n const minimum = minimumFromRange(required);\n const actual = parseVersion(running);\n if (!minimum || !actual) return [];\n if (!isBelow(actual, minimum)) return [];\n\n return [{\n check: \"node\",\n severity: \"error\",\n message: `Node ${running} is running, and Rebase needs ${required}.`,\n fix: `Install Node ${minimum[0]} or newer (nvm install ${minimum[0]}), then reinstall dependencies.`\n }];\n}\n\n// ── Package manager ──────────────────────────────────────────────────────\n\n/** The lockfiles a project may have, and the manager each one belongs to. */\nexport const LOCKFILES: Record<string, string> = {\n \"pnpm-lock.yaml\": \"pnpm\",\n \"package-lock.json\": \"npm\",\n \"yarn.lock\": \"yarn\",\n \"bun.lockb\": \"bun\"\n};\n\n/**\n * Two package managers in one project.\n *\n * A Rebase project is a pnpm workspace, and running `npm install` inside one\n * rewrites `node_modules` into a hoisted layout that pnpm then disagrees with.\n * The result is not an install error: it is `Cannot find module` from inside a\n * dependency, hours later, on a machine where it worked yesterday. The\n * leftover `package-lock.json` is the only durable evidence, and nothing looked\n * at it.\n */\nexport function checkPackageManager(\n lockfilesPresent: string[],\n declared: string | undefined\n): EnvironmentFinding[] {\n const known = lockfilesPresent.filter(file => file in LOCKFILES);\n if (known.length < 2) {\n // One lockfile, or none. A single one that disagrees with\n // `packageManager` is worth saying too.\n const declaredName = declared?.split(\"@\")[0];\n if (known.length === 1 && declaredName && LOCKFILES[known[0]] !== declaredName) {\n return [{\n check: \"package-manager\",\n severity: \"warning\",\n message: `This project declares packageManager \"${declared}\" and has a ${LOCKFILES[known[0]]} lockfile (${known[0]}).`,\n fix: `Delete ${known[0]} and node_modules, then install with ${declaredName}.`\n }];\n }\n return [];\n }\n\n const managers = known.map(file => LOCKFILES[file]);\n return [{\n check: \"package-manager\",\n severity: \"error\",\n message: `Two package managers have installed here: ${known.join(\" and \")}.`,\n fix: `Keep one. Delete the others and node_modules, then reinstall with ${declared?.split(\"@\")[0] ?? managers[0]}.`\n }];\n}\n\n// ── Collections ──────────────────────────────────────────────────────────\n\n/**\n * Two collections claiming one slug.\n *\n * The slug is the route, the table lookup and the registry key, and the\n * registry keeps the last one registered. So the loser is not reported missing:\n * it is served as the winner, with the winner's properties, under its own name.\n * Every symptom of this points somewhere else.\n */\nexport function checkDuplicateSlugs(\n collections: Array<{ slug?: string; name?: string }>\n): EnvironmentFinding[] {\n const byslug = new Map<string, number>();\n for (const collection of collections) {\n if (!collection.slug) continue;\n byslug.set(collection.slug, (byslug.get(collection.slug) ?? 0) + 1);\n }\n\n return [...byslug]\n .filter(([, count]) => count > 1)\n .map(([slug, count]) => ({\n check: \"collections\" as const,\n severity: \"error\" as const,\n message: `${count} collections declare the slug \"${slug}\". Only the last one registered is served.`,\n fix: `Give each collection its own slug. The one that loses is not reported missing — it answers as the winner.`\n }));\n}\n\n// ── .env ─────────────────────────────────────────────────────────────────\n\n/** What `loadEnv` requires of a JWT secret. Mirrors `rebaseEnvSchema`. */\nexport const MIN_JWT_SECRET_LENGTH = 32;\n\n/**\n * The two `.env` facts that fail late and confusingly.\n *\n * A short `JWT_SECRET` boots fine and is refused by `loadEnv` only in\n * production, which is the worst place to find out. Missing CORS in production\n * is the opposite shape — it does not fail at all; the API simply accepts\n * requests from anywhere.\n *\n * Values are never echoed. This reads a file that holds every credential the\n * project has, and doctor's output goes wherever a terminal goes.\n */\nexport function checkEnvSanity(values: Record<string, string>): EnvironmentFinding[] {\n const findings: EnvironmentFinding[] = [];\n const production = values.NODE_ENV === \"production\";\n\n const secret = values.JWT_SECRET;\n if (secret !== undefined && secret.length > 0 && secret.length < MIN_JWT_SECRET_LENGTH) {\n findings.push({\n check: \"env\",\n severity: production ? \"error\" : \"warning\",\n message: `JWT_SECRET is ${secret.length} characters. The runtime requires at least ${MIN_JWT_SECRET_LENGTH}, and refuses to boot below it in production.`,\n fix: \"Generate one: openssl rand -hex 32\"\n });\n }\n\n if (production && !values.CORS_ORIGINS && !values.FRONTEND_URL) {\n findings.push({\n check: \"env\",\n severity: \"error\",\n message: \"NODE_ENV=production with neither CORS_ORIGINS nor FRONTEND_URL set — the API will accept requests from any origin.\",\n fix: \"Set CORS_ORIGINS to the origins that may call this API.\"\n });\n }\n\n return findings;\n}\n\n/**\n * Parse a `.env` into a plain object.\n *\n * Deliberately not `dotenv`: this must not touch `process.env`, and doctor may\n * be reading a file for a different environment than the one it is running in.\n */\nexport function parseEnvFile(text: string): Record<string, string> {\n const values: Record<string, string> = {};\n for (const line of text.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eq = trimmed.indexOf(\"=\");\n if (eq <= 0) continue;\n const key = trimmed.slice(0, eq).replace(/^export\\s+/, \"\").trim();\n let value = trimmed.slice(eq + 1).trim();\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1);\n }\n values[key] = value;\n }\n return values;\n}\n\n// ── Version skew ─────────────────────────────────────────────────────────\n\n/** One `@rebasepro/*` dependency, and where it was declared. */\nexport interface DeclaredDependency {\n /** Where it was declared, relative to the project root. */\n file: string;\n name: string;\n /** The range exactly as written. */\n range: string;\n}\n\n/**\n * The same `@rebasepro/*` package pinned to different versions in one project.\n *\n * A Rebase project declares them in several package.json files — the root, the\n * backend, the frontend, the config workspace — and nothing has ever compared\n * them. The failure that produces is not an install error: pnpm installs both,\n * `instanceof` stops working across the two copies, and the symptom is a\n * `CollectionConfig` that fails a type guard written against an identical type.\n *\n * `workspace:` ranges are excluded: inside this repo's own workspaces they all\n * resolve to the same build by construction.\n */\nexport function checkVersionSkew(declared: DeclaredDependency[]): EnvironmentFinding[] {\n const byPackage = new Map<string, Map<string, string[]>>();\n\n for (const dependency of declared) {\n if (!dependency.name.startsWith(\"@rebasepro/\")) continue;\n if (dependency.range.startsWith(\"workspace:\") || dependency.range.startsWith(\"link:\")) continue;\n if (dependency.range === \"*\" || dependency.range === \"latest\") continue;\n\n const ranges = byPackage.get(dependency.name) ?? new Map<string, string[]>();\n ranges.set(dependency.range, [...(ranges.get(dependency.range) ?? []), dependency.file]);\n byPackage.set(dependency.name, ranges);\n }\n\n const findings: EnvironmentFinding[] = [];\n for (const [name, ranges] of byPackage) {\n if (ranges.size < 2) continue;\n const described = [...ranges]\n .map(([range, files]) => `${range} (${files.join(\", \")})`)\n .join(\", \");\n findings.push({\n check: \"versions\",\n severity: \"error\",\n message: `${name} is pinned to different versions in this project: ${described}.`,\n fix: \"Run `rebase upgrade` to pin every @rebasepro package to one release and reinstall. Two copies of a Rebase package break `instanceof` between them, which fails as a type guard rejecting its own type.\"\n });\n }\n return findings;\n}\n","/**\n * CLI command: rebase doctor\n *\n * Detects three-way schema drift between collection definitions,\n * the generated Drizzle schema, and the live PostgreSQL database.\n */\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execa } from \"execa\";\nimport {\n requireProjectRoot,\n requireBackendDir,\n getActiveBackendPlugin,\n resolvePluginCliScript,\n resolveTsx,\n findEnvFile,\n exitDependenciesNotInstalled\n} from \"../utils/project\";\nimport { fileURLToPath, pathToFileURL } from \"url\";\nimport { createRequire } from \"module\";\nimport { scanTextForLibpqUrls, type LibpqUrlFinding } from \"../utils/libpq-url\";\nimport { analyseFunctionsDirectory, summarisePortability } from \"../function-portability\";\nimport { reportSpawnFailure } from \"../utils/spawn-error\";\nimport { argsFromCommand } from \"../utils/command-words\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { loadManifest, findBackendApp, resolveBackendPaths } from \"../manifest\";\nimport { DEV_DATABASE_KIND_ENV, devDatabaseKind, managedNotices, prepareDatabaseEnv } from \"../dev-db/prepare\";\nimport {\n checkDuplicateSlugs,\n checkEnvSanity,\n checkAtlasBinary,\n checkNodeVersion,\n checkPackageManager,\n checkVersionSkew,\n LOCKFILES,\n parseEnvFile,\n type AtlasBinaryState,\n type DeclaredDependency,\n type EnvironmentFinding\n} from \"../doctor-environment\";\n\n/**\n * Files that can hold a connection string the project actually runs on.\n *\n * `.env` is what local commands read; the compose files are what a self-hosted\n * stack and its scheduled backup cron read. Both shipped with the defect, and a\n * deployed stack is broken by the compose one even when `.env` has been fixed.\n * `.env.example` is deliberately absent: nothing runs on it.\n */\nconst CONNECTION_FILES = [\n \".env\",\n \".env.local\",\n \"docker-compose.yml\",\n \"docker-compose.yaml\",\n \"docker-compose.custom.yml\"\n];\n\n/**\n * Find connection strings libpq cannot parse, anywhere in the project.\n *\n * Exported for the tests; `envFile` is passed separately because a project may\n * keep its `.env` outside the root (see `findEnvFile`).\n */\nexport function findLibpqUrlProblems(projectRoot: string, envFile?: string | null): LibpqUrlFinding[] {\n const candidates = CONNECTION_FILES.map((f) => path.join(projectRoot, f));\n if (envFile) candidates.push(envFile);\n\n const findings: LibpqUrlFinding[] = [];\n const seen = new Set<string>();\n\n for (const file of candidates) {\n if (seen.has(file)) continue;\n seen.add(file);\n let text: string;\n try {\n if (!fs.existsSync(file)) continue;\n text = fs.readFileSync(file, \"utf-8\");\n } catch {\n // Unreadable is not a finding — doctor reports what it can see.\n continue;\n }\n findings.push(...scanTextForLibpqUrls(path.relative(projectRoot, file) || path.basename(file), text));\n }\n\n return findings;\n}\n\n/**\n * Report unparseable connection strings, if any. Returns true when there were,\n * so the finding reaches the exit code like the environment errors do.\n *\n * Runs before the plugin's drift check and never blocks it. The plugin connects\n * through node-postgres, which parses these URLs happily — so it cannot see this\n * defect, and a project with it will otherwise get a clean bill of health while\n * `rebase db backup` fails.\n */\nfunction reportLibpqUrlProblems(findings: LibpqUrlFinding[]): boolean {\n if (findings.length === 0) return false;\n\n console.log(\"\");\n console.log(chalk.red.bold(\" ✗ Connection string that PostgreSQL's own tools cannot parse\"));\n console.log(\"\");\n for (const f of findings) {\n console.log(` ${chalk.bold(f.file)} → ${chalk.bold(f.variable)}`);\n console.log(chalk.gray(` the \"${f.params.join('\", \"')}\" parameter contains an unencoded \"=\".`));\n console.log(chalk.gray(\" Replace the value with:\"));\n console.log(` ${chalk.cyan(f.suggested)}`);\n console.log(\"\");\n }\n console.log(chalk.gray(\" libpq splits a query parameter on the first \\\"=\\\" and rejects any further\"));\n console.log(chalk.gray(\" one, so this fails:\"));\n console.log(chalk.gray(\" extra key/value separator \\\"=\\\" in URI query parameter\"));\n console.log(\"\");\n console.log(chalk.gray(\" Affects rebase db backup / restore, scheduled backups, and psql.\"));\n console.log(chalk.gray(\" NOT rebase dev or db push — those use a driver that accepts it, which\"));\n console.log(chalk.gray(\" is why a project can look healthy and still have no working backups.\"));\n console.log(chalk.gray(\" Projects scaffolded before 2026-08-18 all carry it.\"));\n console.log(\"\");\n return true;\n}\n\n/**\n * `--help` is answered before the project guard, not after.\n *\n * `doctor` declared no `--help` at all, so the flag fell through to the command\n * body and hit `requireProjectRoot()` — and `rebase doctor --help` outside a\n * project answered \"✗ Could not find a Rebase project root.\" Asking a command\n * what it does is the one question that cannot require being somewhere\n * particular to ask.\n */\n/**\n * What each custom function needs from its host.\n *\n * Prints nothing when there is nothing to say — which is the common case, and\n * the reason it can afford to run every time. When it does print, the ordering\n * is deliberate: the one finding that is a bug *today* comes first, and the\n * rest is a single descriptive line about where these functions could run.\n */\nfunction reportFunctionPortability(projectRoot: string): void {\n let results: ReturnType<typeof analyseFunctionsDirectory>;\n try {\n const backend = findBackendApp(loadManifest(projectRoot).manifest);\n if (!backend) return;\n const paths = resolveBackendPaths(backend.app, projectRoot);\n results = analyseFunctionsDirectory(path.join(projectRoot, paths.functions), projectRoot);\n } catch {\n // A project with no manifest, or one shaped differently — doctor has\n // plenty else to report, and this section is advisory.\n return;\n }\n\n const lines = summarisePortability(results);\n if (lines.length === 0) return;\n\n console.log(chalk.bold(\"\\nCustom functions\"));\n for (const line of lines) {\n console.log(line.trimStart().startsWith(\"⚠\") ? chalk.yellow(line) : chalk.gray(line));\n }\n console.log(chalk.gray(\" See https://rebase.pro/docs/backend/custom-functions#runtime-portability\"));\n}\n\n/**\n * Read everything the environment checks need, then run them.\n *\n * The reading is here and the deciding is in `doctor-environment.ts`, so every\n * check has a fixture that fails it without a project on disk.\n */\nexport function collectEnvironmentFindings(\n projectRoot: string,\n envFile: string | null | undefined\n): EnvironmentFinding[] {\n const findings: EnvironmentFinding[] = [];\n\n // Node, against the engines range the installed CLI declares.\n findings.push(...checkNodeVersion(process.versions.node, readCliEngines()));\n\n // Two package managers in one project.\n const rootPackage = readJson(path.join(projectRoot, \"package.json\"));\n findings.push(...checkPackageManager(\n Object.keys(LOCKFILES).filter(file => fs.existsSync(path.join(projectRoot, file))),\n typeof rootPackage?.packageManager === \"string\" ? rootPackage.packageManager : undefined\n ));\n\n // Two collections claiming one slug. Read as text rather than imported: a\n // collection file can import anything, and doctor must not execute a\n // project's code to tell it two slugs collide.\n findings.push(...checkDuplicateSlugs(readDeclaredSlugs(projectRoot)));\n\n // `.env`, values never echoed.\n if (envFile && fs.existsSync(envFile)) {\n try {\n findings.push(...checkEnvSanity(parseEnvFile(fs.readFileSync(envFile, \"utf-8\"))));\n } catch { /* unreadable is not a finding */ }\n }\n\n // One `@rebasepro/*` package, two versions.\n findings.push(...checkVersionSkew(readDeclaredRebaseDeps(projectRoot)));\n\n // The atlas binary, which every schema command shells out to and whose\n // absence is invisible until one of them is run.\n findings.push(...checkAtlasBinary(readAtlasBinaryState(projectRoot)));\n\n return findings;\n}\n\n/**\n * What is actually on disk for `@ariga/atlas`, from the project's point of view.\n *\n * Three separate questions, because the three states they distinguish need\n * three different remedies — see `checkAtlasBinary`. Directories are searched\n * from the project root upwards and through the workspaces a scaffold has,\n * because `db push` runs from `backend/` and the install may be hoisted to the\n * root.\n */\nexport function readAtlasBinaryState(projectRoot: string): AtlasBinaryState | null {\n const roots = [projectRoot, path.join(projectRoot, \"backend\"), path.join(projectRoot, \"config\")];\n\n const findUpwards = (starts: string[], relative: string): string | null => {\n for (const start of starts) {\n let dir = start;\n for (let i = 0; i < 8; i++) {\n const candidate = path.join(dir, \"node_modules\", relative);\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n }\n return null;\n };\n\n // `@ariga/atlas` is a dependency of `@rebasepro/server-postgres`, not of the\n // project, so under pnpm's isolated layout — the scaffold default — it lives\n // in `.pnpm/` and a directory walk over `node_modules/` never sees it.\n // Resolve through the module graph the way the driver itself does.\n const resolveFrom = (from: string, request: string): string | null => {\n try {\n return createRequire(pathToFileURL(from)).resolve(request);\n } catch {\n return null;\n }\n };\n const bases = roots.map(dir => path.join(dir, \"package.json\")).filter(file => fs.existsSync(file));\n const driverManifests = bases\n .map(base => resolveFrom(base, \"@rebasepro/server-postgres/package.json\"))\n .filter((file): file is string => file !== null);\n\n let manifest: string | null = findUpwards(roots, path.join(\"@ariga\", \"atlas\", \"package.json\"));\n if (!manifest) {\n for (const base of [...bases, ...driverManifests]) {\n manifest = resolveFrom(base, \"@ariga/atlas/package.json\");\n if (manifest) break;\n }\n }\n\n // The `.bin` shim is written beside whichever package declared the\n // dependency, so the driver's own directory is a search root too.\n const onPath = findUpwards(\n [...roots, ...driverManifests.map(file => path.dirname(file))],\n path.join(\".bin\", \"atlas\")\n ) !== null;\n\n let binaryOnDisk = false;\n if (manifest) {\n try {\n const pkg = JSON.parse(fs.readFileSync(manifest, \"utf-8\")) as {\n bin?: string | Record<string, string>;\n };\n const dir = path.dirname(manifest);\n const targets = typeof pkg.bin === \"string\"\n ? [pkg.bin]\n : Object.values(pkg.bin ?? {}).filter((t): t is string => typeof t === \"string\");\n binaryOnDisk = targets.some(target => fs.existsSync(path.resolve(dir, target)));\n } catch { /* unreadable manifest: treat the binary as absent */ }\n }\n\n return {\n onPath,\n packageInstalled: manifest !== null,\n binaryOnDisk,\n manager: readPackageManagerName(projectRoot)\n };\n}\n\n/** The reader's own package manager, from the lockfile beside their project. */\nfunction readPackageManagerName(projectRoot: string): string {\n for (const [file, manager] of Object.entries(LOCKFILES)) {\n if (fs.existsSync(path.join(projectRoot, file))) return manager;\n }\n return \"pnpm\";\n}\n\n/** The `engines.node` range of the CLI actually running. */\nfunction readCliEngines(): string | undefined {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n for (let dir = here, i = 0; i < 5; i++) {\n const candidate = path.join(dir, \"package.json\");\n if (fs.existsSync(candidate)) {\n const parsed = readJson(candidate);\n if (parsed?.name === \"@rebasepro/cli\") {\n const engines = parsed.engines as { node?: string } | undefined;\n return engines?.node;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n } catch { /* the check is advisory */ }\n return undefined;\n}\n\nfunction readJson(file: string): Record<string, unknown> | undefined {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf-8\")) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\n/** Where a project's package.json files live, relative to its root. */\nconst PACKAGE_JSON_LOCATIONS = [\"package.json\", \"backend/package.json\", \"frontend/package.json\", \"config/package.json\"];\n\nfunction readDeclaredRebaseDeps(projectRoot: string): DeclaredDependency[] {\n const declared: DeclaredDependency[] = [];\n for (const relative of PACKAGE_JSON_LOCATIONS) {\n const parsed = readJson(path.join(projectRoot, relative));\n if (!parsed) continue;\n for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const block = parsed[field] as Record<string, string> | undefined;\n if (!block) continue;\n for (const [name, range] of Object.entries(block)) {\n if (typeof range === \"string\") declared.push({ file: relative, name, range });\n }\n }\n }\n return declared;\n}\n\n/**\n * Does this project declare its collections in code?\n *\n * `resolveBackendPaths` answers it against the manifest's own `config` path\n * rather than the convention, because a project may move the directory. A\n * project with no manifest, or one shaped differently, is treated as declaring\n * them: the wrong answer there would silently skip the drift report, which is\n * the reason the command exists.\n */\nexport function hasDeclaredCollections(projectRoot: string): boolean {\n try {\n const backend = findBackendApp(loadManifest(projectRoot).manifest);\n if (!backend) return true;\n return resolveBackendPaths(backend.app, projectRoot).hasCollections;\n } catch {\n return true;\n }\n}\n\n/**\n * Every `slug:` a collection file declares, read as text.\n *\n * Deliberately not by importing them: a collection file may import anything the\n * project depends on, and doctor must not run a project's code to tell it two\n * slugs collide. A regex over `slug: \"...\"` finds the literal in every shape\n * the scaffold and the docs use; a computed slug is simply not seen, which is\n * the right failure for a check that only ever reports.\n */\nfunction readDeclaredSlugs(projectRoot: string): Array<{ slug: string }> {\n const dir = path.join(projectRoot, \"config\", \"collections\");\n if (!fs.existsSync(dir)) return [];\n const slugs: Array<{ slug: string }> = [];\n let entries: string[];\n try {\n entries = fs.readdirSync(dir);\n } catch {\n return [];\n }\n for (const entry of entries) {\n if (!/\\.(ts|js|mts|mjs)$/.test(entry) || entry.startsWith(\"index.\")) continue;\n try {\n const text = fs.readFileSync(path.join(dir, entry), \"utf-8\");\n for (const match of text.matchAll(/\\bslug:\\s*[\"'`]([^\"'`]+)[\"'`]/g)) {\n slugs.push({ slug: match[1] });\n }\n } catch { /* unreadable is not a finding */ }\n }\n return slugs;\n}\n\n/** Print what the environment checks found, grouped, or nothing at all. */\nfunction reportEnvironmentFindings(findings: EnvironmentFinding[]): boolean {\n if (findings.length === 0) return false;\n\n console.log(\"\");\n console.log(chalk.bold(\" Environment\"));\n for (const finding of findings) {\n const mark = finding.severity === \"error\" ? chalk.red(\" ✗\") : chalk.yellow(\" ⚠\");\n console.log(`${mark} ${finding.message}`);\n console.log(chalk.gray(` ${finding.fix}`));\n }\n console.log(\"\");\n return findings.some(finding => finding.severity === \"error\");\n}\n\n/**\n * The flags `rebase doctor` takes, and what each is for.\n *\n * One table, read by both the parser and the help page, because they were two\n * things that had to agree and did not: the page listed no flags at all, so\n * `--policies` — the form `cli/index.md` calls \"the form to use as a CI gate\" —\n * was invisible to anyone who ran `rebase doctor --help` to find it. And with\n * nothing parsing the line here, a typo travelled to the driver's permissive\n * parser and was silently dropped, so `rebase doctor --polices` ran the ordinary\n * doctor and reported success on a gate that never ran.\n *\n * The spec mirrors the driver's own (`doctorPluginCommand` in\n * `server-postgres/src/cli.ts`), because the line is relayed to it verbatim.\n */\nexport const DOCTOR_FLAGS = {\n \"--policies\": Boolean,\n \"--collections\": String,\n \"-c\": \"--collections\",\n \"--schema\": String,\n \"-s\": \"--schema\",\n \"--sdk\": String,\n \"-k\": \"--sdk\"\n} as const;\n\n/** What each long flag above does, for the Options block. */\nconst DOCTOR_FLAG_HELP: Record<string, string> = {\n \"--policies\": \"Also audit the row-level security policies. The form to use as a CI gate.\",\n \"--collections\": \"Path to the collections directory (default: ../config/collections)\",\n \"--schema\": \"Path to the generated Drizzle schema (default: src/schema.generated.ts)\",\n \"--sdk\": \"Path to the generated SDK types (default: ../generated/sdk/database.types.ts)\"\n};\n\n/** `--collections, -c` — the aliases, resolved from the spec rather than retyped. */\nfunction doctorFlagLabel(flag: string): string {\n const aliases = Object.entries(DOCTOR_FLAGS)\n .filter(([, target]) => target === flag)\n .map(([alias]) => alias);\n return [flag, ...aliases].join(\", \");\n}\n\nfunction printDoctorHelp(): void {\n console.log(`\n${chalk.bold(\"rebase doctor\")} — Check a project for drift and misconfiguration\n\n${chalk.green.bold(\"Usage\")}\n rebase doctor [options]\n\n${chalk.green.bold(\"Options\")}\n${Object.keys(DOCTOR_FLAG_HELP)\n .map(flag => ` ${chalk.blue(doctorFlagLabel(flag).padEnd(22))} ${DOCTOR_FLAG_HELP[flag]}`)\n .join(\"\\n\")}\n\nCompares the collections you declare, the generated Drizzle schema, and the\ntables that actually exist, then reports what disagrees and how to reconcile it.\n\nAlso checks the connection strings in .env and the compose files for the\nunencoded \"=\" that makes PostgreSQL's own tools refuse to parse them — which\nbreaks backups and psql while leaving the app itself working.\n\nRun from inside a Rebase project — it reads the project's collections and\nconnects to its database.\n`);\n}\n\nexport async function doctorCommand(rawArgs: string[]): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printDoctorHelp();\n return;\n }\n\n // Strictly, before the line is relayed. The driver's own parser is\n // `permissive`, which turns an undeclared flag into a positional rather\n // than an error, so `rebase doctor --polices` ran the ordinary doctor and\n // exited 0 — a CI gate that reported success because the flag asking for it\n // was dropped on the way.\n parseCommandArgs({\n spec: DOCTOR_FLAGS,\n rawArgs,\n commandWords: 1,\n command: \"doctor\",\n maxPositionals: 0\n });\n\n const projectRoot = requireProjectRoot();\n const backendDir = requireBackendDir(projectRoot);\n\n const activePlugin = getActiveBackendPlugin(backendDir);\n if (!activePlugin) {\n console.error(chalk.red(\"✗ Could not detect an active database plugin.\"));\n console.error(chalk.gray(\" Make sure a package like @rebasepro/server-postgres is installed in backend/package.json.\"));\n process.exit(1);\n }\n\n const pluginCli = resolvePluginCliScript(backendDir, activePlugin);\n if (!pluginCli) {\n exitDependenciesNotInstalled(projectRoot);\n }\n\n // Set up environment with DOTENV_CONFIG_PATH\n const envFile = findEnvFile(projectRoot);\n const env: Record<string, string> = { ...process.env as Record<string, string> };\n if (envFile) {\n env.DOTENV_CONFIG_PATH = envFile;\n }\n env[DEV_DATABASE_KIND_ENV] = devDatabaseKind(projectRoot) ?? \"\";\n\n // Reported before the plugin runs: this one needs no database, and if the\n // URL is the problem then anything that tries to connect with it first will\n // fail with a worse message.\n const connectionFailed = reportLibpqUrlProblems(findLibpqUrlProblems(projectRoot, envFile));\n\n // Same reasoning: no database needed, and one of these findings — a\n // `process.env` read at module scope — is a live failure whose only symptom\n // today is a function quietly missing from `GET /api/functions`.\n reportFunctionPortability(projectRoot);\n\n // Everything that breaks a first run happens before a table is compared:\n // the wrong Node, two lockfiles disagreeing, two collections claiming one\n // slug, a JWT_SECRET short enough to be refused in production, three\n // versions of @rebasepro/server in one workspace. Doctor said nothing about\n // any of it. Reported before the plugin runs, and non-blocking — a project\n // with one of these still deserves its drift report.\n const environmentFailed = reportEnvironmentFindings(collectEnvironmentFindings(projectRoot, envFile));\n // Either is an error a CI gate must see: a connection string libpq cannot\n // parse is a project whose backups have never run.\n const failed = connectionFailed || environmentFailed;\n\n // Which database, resolved the way every other command resolves it.\n //\n // Two of doctor's three phases need one, and both used to key on\n // `DATABASE_URL` alone. On the documented first-run path that variable does\n // not exist — `rebase init` leaves it commented out and the managed\n // database fills the vacuum — so a stock scaffold always ended with\n // `⏭ Collections → Database: skipped (DATABASE_URL not set)` and\n // `⚠ No DATABASE_URL — RLS policies were NOT checked`, then told the reader\n // to set the one variable the quickstart tells them to leave alone. For the\n // command `ai-instructions.md` names as the thing to run before guessing.\n //\n // The managed daemon is started here, exactly as `rebase db url` starts it:\n // a doctor that will not start the database it is asked about can only ever\n // answer \"I did not look\".\n //\n // Last, and never fatal. Everything above needs no database, and a doctor\n // that cannot report what it *can* see because a database would not start\n // is the opposite of the job. A failure here is said out loud and the run\n // continues; the driver then reports its two database phases as skipped,\n // which is the truth.\n try {\n const prepared = await prepareDatabaseEnv(projectRoot, {\n onProgress: (message) => console.log(chalk.gray(` ${message}`))\n });\n Object.assign(env, prepared.env);\n for (const line of managedNotices(prepared)) console.log(chalk.gray(` ${line}`));\n } catch (error) {\n console.log(\"\");\n console.error(chalk.yellow(` ⚠ Could not resolve this project's database: ${\n error instanceof Error ? error.message : String(error)}`));\n console.error(chalk.gray(\" The checks that need one are reported below as not run.\"));\n }\n\n // A headless project has no `config/collections` by design — its API is\n // introspected from the live database at boot — and the driver's doctor\n // opens by loading them, finds none, and exits 1. So `rebase doctor` failed\n // on the documented headless path, in 0.17.3 and on main, while every check\n // above it had just passed. Its three phases all compare *against* declared\n // collections, so there is nothing for them to do here; the environment\n // findings are the whole report.\n if (!hasDeclaredCollections(projectRoot)) {\n console.log(\"\");\n console.log(chalk.gray(\n \" ○ Schema drift not checked: this project derives its API from the database — \"\n + \"run `rebase schema introspect` first.\"\n ));\n if (failed) process.exit(1);\n return;\n }\n\n try {\n const isTs = pluginCli.endsWith(\".ts\");\n if (isTs) {\n const tsxBin = resolveTsx(projectRoot);\n if (!tsxBin) {\n exitDependenciesNotInstalled(projectRoot);\n }\n await execa(tsxBin, [pluginCli, ...argsFromCommand(rawArgs, \"doctor\")], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n } else {\n await execa(\"node\", [pluginCli, ...argsFromCommand(rawArgs, \"doctor\")], {\n cwd: backendDir,\n stdio: \"inherit\",\n env\n });\n }\n } catch (error) {\n // A child that ran and exited non-zero already printed its diagnostics\n // through inherited stdio. A child that never started did not — and\n // \"the tsx symlink is broken\" is exactly the state `doctor` exists to\n // report, so exiting 1 in silence was the worst possible answer.\n reportSpawnFailure(error);\n process.exit(1);\n }\n\n // The plugin exited clean, so the schema agrees with itself. That is not\n // the same as the project being able to run: an environment error is still\n // an error, and a doctor that exits 0 over one is a doctor nobody can gate\n // on.\n if (failed) process.exit(1);\n}\n","/**\n * CLI command: rebase resources\n *\n * Shows what a project declares, and keeps the committed graph honest.\n *\n * The graph is generated, so it can drift the moment somebody adds a bucket and\n * does not regenerate. Drift here is not cosmetic: the committed file is what a\n * host reads to decide what to provision, so a stale one means the console\n * offers a project one set of resources while the runtime asks for another.\n * `--check` is the gate that makes that impossible to land.\n */\nimport chalk from \"chalk\";\nimport path from \"path\";\nimport { failAsJson, requireProjectRoot } from \"../utils/project\";\nimport { findBackendApp, loadManifest, ManifestError } from \"../manifest\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport {\n RESOURCE_GRAPH_FILENAME,\n deriveOptionsFor, deriveResourceGraph,\n projectResourceGraph,\n readResourceGraphFile,\n serializeResourceGraph,\n writeResourceGraphFile,\n type ProjectedResource\n} from \"../resources/derive\";\nimport { declaredSubscriptions, type RebaseBackendAppConfig } from \"@rebasepro/types\";\n\nfunction usage(): void {\n console.log(`\n${chalk.bold(\"rebase resources\")} — what this project needs\n\n ${chalk.blue(\"rebase resources\")} List them, declared and implicit\n ${chalk.blue(\"rebase resources --write\")} Regenerate ${RESOURCE_GRAPH_FILENAME}\n ${chalk.blue(\"rebase resources --check\")} Fail if the committed graph is stale\n ${chalk.blue(\"rebase resources --json\")} The same set, machine-readable\n\nA resource is declared in config code — ${chalk.gray('database(\"analytics\"), bucket(\"media\"), topic(\"signups\")')} —\nand never in ${RESOURCE_GRAPH_FILENAME}, which is generated from those declarations so a host\ncan read what a project needs without building it. A backend also has a default\ndatabase and a default storage source nobody declared; both are listed here,\nmarked ${chalk.gray(\"implicit\")}, and neither is written to that file — the host supplies them.\n`);\n}\n\n/**\n * Render the projection the way somebody reads it: grouped by kind, key first.\n *\n * The projection, not the raw graph. `rebase status` has always included the\n * implicit default database and bucket and this listing did not, so the two\n * commands answered \"what does this project need\" differently on the same stock\n * scaffold. There is no \"no resources declared\" case any more: a backend has a\n * database and a storage source whether or not anyone wrote them down.\n */\nfunction print(resources: ProjectedResource[]): void {\n // Infrastructure first, then code: what needs binding is what a reader\n // is here to check.\n const order = [\"database\", \"bucket\", \"topic\", \"queue\", \"cron\", \"function\"];\n const kinds = [...new Set(resources.map(r => r.kind))]\n .sort((a, b) => (order.indexOf(a) === -1 ? 99 : order.indexOf(a)) - (order.indexOf(b) === -1 ? 99 : order.indexOf(b)));\n for (const kind of kinds) {\n console.log(`\\n ${chalk.bold(kind)}`);\n for (const r of resources.filter(x => x.kind === kind)) {\n const bits: string[] = [];\n if (kind === \"cron\") {\n bits.push(chalk.cyan(String(r.options.schedule)));\n bits.push(chalk.gray(r.options.timezone ? String(r.options.timezone) : \"local time\"));\n } else if (kind === \"function\") {\n bits.push(chalk.gray(String(r.options.file ?? \"\")));\n if (r.options.portable === false) bits.push(chalk.yellow(\"node-only\"));\n } else {\n bits.push(chalk.gray(r.engine));\n if (r.transport !== \"server\") bits.push(chalk.yellow(r.transport));\n for (const [k, v] of Object.entries(r.options)) bits.push(chalk.gray(`${k}=${String(v)}`));\n }\n // Marked, not hidden: a declared resource is recorded in\n // `rebase.resources.json` for a host to provision, and an implicit\n // one is a default the runtime supplies regardless.\n if (r.implicit) bits.push(chalk.gray(\"implicit\"));\n console.log(` ${r.key.padEnd(24)} ${bits.join(\" · \")}`);\n if (kind === \"topic\") {\n for (const sub of declaredSubscriptions(r.key)) {\n console.log(` ${chalk.gray(\"→\")} ${sub.name}`);\n }\n }\n if (r.usedBy && r.usedBy.length > 0) {\n console.log(` ${chalk.gray(\"used by\")} ${chalk.gray(r.usedBy.join(\", \"))}`);\n }\n }\n }\n console.log(\"\");\n}\n\nexport async function resourcesCommand(rawArgs: string[]): Promise<void> {\n if (wantsHelp(rawArgs)) return usage();\n\n const { flags } = parseCommandArgs({\n spec: {\n \"--write\": Boolean,\n \"--check\": Boolean,\n \"--json\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"resources\",\n maxPositionals: 0\n });\n\n const projectRoot = requireProjectRoot();\n\n // Every exit below has a `--json` arm, for the reason in `failAsJson`:\n // `--json` is a promise about stdout, and a promise kept on one exit of a\n // command and broken on the next is not one.\n const asJson = Boolean(flags[\"--json\"]);\n\n let backendApp: RebaseBackendAppConfig;\n try {\n const loaded = loadManifest(projectRoot);\n const backend = findBackendApp(loaded.manifest);\n if (!backend) {\n if (asJson) {\n failAsJson(\n \"This project declares no backend app, so it declares no resources.\",\n \"no_backend_app\",\n \"Add a backend app to rebase.json, or run `rebase apps init`.\"\n );\n }\n console.error(chalk.red(\"This project declares no backend app, so it declares no resources.\"));\n process.exitCode = 1;\n return;\n }\n backendApp = backend.app;\n } catch (err) {\n if (err instanceof ManifestError) {\n if (asJson) {\n failAsJson(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n console.error(chalk.red(err.message));\n for (const issue of err.issues) console.error(` ${chalk.gray(issue.path)} ${issue.message}`);\n process.exitCode = 1;\n return;\n }\n throw err;\n }\n\n const { graph, issues } = await deriveResourceGraph(deriveOptionsFor(projectRoot, backendApp));\n\n if (issues.length > 0) {\n if (asJson) {\n failAsJson(\n `${issues.length} problem(s) in the declared resources.`,\n \"resource_declaration_invalid\",\n \"Fix the declarations the issues name, then run this again.\",\n issues.map(issue => ({ path: issue.path, message: issue.message }))\n );\n }\n console.error(chalk.red(`\\n✗ ${issues.length} problem(s) in the declared resources:\\n`));\n for (const issue of issues) console.error(` ${chalk.bold(issue.path)} ${issue.message}`);\n console.error(\"\");\n process.exitCode = 1;\n return;\n }\n\n if (asJson) {\n // The projection, so this and `rebase status --json` describe the same\n // set. `version` is kept so a reader of either can tell them apart from\n // a future shape.\n console.log(JSON.stringify({ version: graph.version, resources: projectResourceGraph(graph) }, null, 2));\n return;\n }\n\n if (flags[\"--check\"]) {\n const committed = readResourceGraphFile(projectRoot);\n const expected = serializeResourceGraph(graph);\n if (committed === expected) {\n console.log(chalk.green(`✓ ${RESOURCE_GRAPH_FILENAME} matches the declarations.`));\n return;\n }\n // Declaring nothing and having no file is a consistent state, not a\n // stale one. The file records declarations; a project with none has\n // nothing to record, and its default database and bucket are implicit\n // by design — that is the overwhelmingly common project and it must not\n // be required to commit an empty file saying so.\n //\n // This mattered the moment the check was put in a gate: it would have\n // failed this repository's own reference app, which declares nothing,\n // and every scaffolded project until someone declared a second bucket.\n if (committed === null && graph.resources.length === 0) {\n console.log(chalk.gray(\"✓ Nothing declared, so there is nothing to record.\"));\n return;\n }\n console.error(chalk.red(`\\n✗ ${RESOURCE_GRAPH_FILENAME} is ${committed === null ? \"missing\" : \"stale\"}.\\n`));\n console.error(\n \" A host reads this file to decide what to provision, so a stale one means the\\n\" +\n \" console offers one set of resources while the runtime asks for another.\\n\"\n );\n console.error(` Regenerate it: ${chalk.blue(\"rebase resources --write\")}\\n`);\n process.exitCode = 1;\n return;\n }\n\n if (flags[\"--write\"]) {\n const { changed, file } = writeResourceGraphFile(projectRoot, graph);\n console.log(changed\n ? chalk.green(`✓ Wrote ${path.relative(projectRoot, file)}`)\n : chalk.gray(`${path.relative(projectRoot, file)} already matched the declarations.`));\n return;\n }\n\n print(projectResourceGraph(graph));\n}\n","/**\n * What a project declared, what the environment binds it to, and whether the\n * two meet.\n *\n * ## Why this exists\n *\n * Every piece of this was already knowable and none of it was visible in one\n * place. `rebase resources` lists what you declared. The environment holds the\n * variables. The resolvers decide whether a source is usable. So the question a\n * developer actually has — *\"why does uploading to `media` answer 501\"* — could\n * only be answered by knowing the suffix rule, deriving the variable name by\n * hand, and checking it against a `.env` they had to find first.\n *\n * The answer is mechanical, so it should be printed rather than taught.\n *\n * ## Why it calls the resolvers instead of re-deciding\n *\n * The verdict comes from `resolveDataSources` and `resolveStorageBackend` — the\n * same functions that run at boot. A status view that decided for itself what\n * \"configured\" means would be a second implementation of the rule, and the\n * first time it disagreed it would be reassuring a developer about a deployment\n * that is about to refuse to start.\n *\n * The variable *names* come from each kind's `envBases`, and the verdicts from\n * the resolver `@rebasepro/server` registers per kind — one object per kind,\n * held to `envBases` by `resource-env-bases.test.ts`. A kind this view has\n * never heard of is judged by whatever resolver its package registered.\n */\nimport { withImplicitDefaults } from \"./derive\";\nimport {\n DEFAULT_RESOURCE_KEY,\n envBasesForResource,\n resourceEnvSuffix,\n resourceToDataSource,\n type ResourceDeclaration,\n type ResourceGraph\n} from \"@rebasepro/types\";\n\n/** One environment variable a resource reads, and whether it is there. */\nexport interface ResourceBinding {\n /** The variable this resource reads, suffix included. */\n name: string;\n set: boolean;\n /**\n * The account-scoped name consulted when `name` is unset.\n *\n * Only provider-level bindings have one, and only when the resource named\n * an `account`. Shown because a developer looking at an unset\n * `S3_ACCESS_KEY_ID__MEDIA` needs to know it is not the whole story.\n */\n fallback?: { name: string; set: boolean };\n}\n\n/** Whether a declared resource can actually be reached. */\nexport type ResourceState =\n /** Bound and usable. */\n | \"ready\"\n /** Nothing set for it. Legal for a bucket, fatal for a database. */\n | \"unconfigured\"\n /** Set, and set wrongly. The deployment refuses to start. */\n | \"broken\";\n\nexport interface ResourceStatus {\n kind: string;\n key: string;\n engine: string;\n transport: string;\n /** Present when this resource shares another's credentials. */\n account?: string;\n /** True for a resource nobody declared, which exists anyway. */\n implicit: boolean;\n bindings: ResourceBinding[];\n state: ResourceState;\n /** What this means, in the terms the developer will meet it in. */\n detail: string;\n /** Set when a local directory stands in for this engine, in development. */\n standsIn?: string;\n /** What in the project reaches this resource, from the graph. */\n usedBy?: readonly string[];\n}\n\nexport type EnvBag = Record<string, string | undefined>;\n\n/** Set, and not set to the empty string — which the resolvers treat as absent. */\nfunction isSet(env: EnvBag, name: string): boolean {\n const value = env[name];\n return typeof value === \"string\" && value !== \"\";\n}\n\n/**\n * The bindings one declaration reads, in the order a reader should scan them.\n *\n * A `direct`-transport resource gets none: the browser reaches it with a\n * provider SDK and the backend binds nothing for it, so listing variables would\n * invite someone to set variables that are never read.\n */\nexport function bindingsFor(\n declaration: ResourceDeclaration,\n env: EnvBag,\n accountScopedBases: readonly string[]\n): ResourceBinding[] {\n if (declaration.transport !== \"server\") return [];\n\n const suffix = resourceEnvSuffix(declaration.key);\n const account = typeof declaration.options.account === \"string\"\n ? resourceEnvSuffix(declaration.options.account)\n : undefined;\n\n return envBasesForResource(declaration).map((base) => {\n const name = `${base}${suffix}`;\n const binding: ResourceBinding = { name, set: isSet(env, name) };\n\n // Only the provider-level bindings fall back, and only for a resource\n // that named an account. The bucket name never does — it is what\n // distinguishes one source from another.\n if (account !== undefined && !binding.set && accountScopedBases.includes(base)) {\n binding.fallback = { name: `${base}${account}`, set: isSet(env, `${base}${account}`) };\n }\n return binding;\n });\n}\n\n/**\n * What the managed development database covers, when a project is on it.\n *\n * `rebase init` leaves `DATABASE_URL` commented out on purpose and the managed\n * PGlite fills the vacuum — the documented first-run state. Judging that state\n * by the environment alone produced `○ (default) postgres · DATABASE_URL not\n * set` and the remedy \"set DATABASE_URL\", at the same moment `rebase db url`\n * was printing a working connection string for the same project and\n * `rebase dev` was serving from it. The status view was reading the one place\n * the answer deliberately is not.\n *\n * Resolved by the caller, because deciding it needs the project's `.env`, its\n * branch pointer and its compose file, and this module stays free of all three.\n */\nexport interface ManagedDatabaseStatus {\n /**\n * The daemon's connection string, or null when it is not running.\n *\n * Null is not an error: the managed database exists per project and starts\n * on demand. It only means there is nothing to run the whole-set check\n * against, and the row says so rather than implying a misconfiguration.\n */\n url: string | null;\n}\n\n/**\n * The resolver-side of status, as `@rebasepro/server` registers it per kind.\n *\n * Passed in rather than imported so this module stays testable without a\n * server, and so a kind registered by a plugin is judged by the resolver the\n * plugin brought with it rather than by a switch here.\n */\nexport interface StatusResolvers {\n /** `resourceResolver(kind)` from `@rebasepro/server`. */\n resolverFor: (kind: string) => {\n accountScoped?: readonly string[];\n resolve: (\n declaration: ResourceDeclaration,\n env: EnvBag,\n context: { production: boolean; defaultBasePath: string }\n ) => { state: \"ready\" | \"unbound\" | \"blocked\" | \"code\"; detail?: string; standsIn?: string };\n } | undefined;\n /** `resolveDataSources` from `@rebasepro/server`, for the whole-set check. */\n resolveDataSources: (env: EnvBag, definitions: unknown) => unknown;\n /** Whether the process being judged is production. Status judges for development by default. */\n production?: boolean;\n /**\n * Set when this project runs on the managed development database.\n *\n * Absent for a project that named its own connection string, and absent in\n * production — where an unset `DATABASE_URL` is the failure it has always\n * been.\n */\n managedDatabase?: ManagedDatabaseStatus;\n}\n\n/**\n * The environment plus the managed database's URL, for the whole-set check.\n *\n * A copy: the bindings a reader sees are computed against the real `.env`, so\n * nothing here can make the view claim a variable is set that is not. This is\n * only what `resolveDataSources` is handed, and it is handed it so the check\n * judges the environment the runtime would actually get rather than throwing\n * \"Data source \"(default)\" has no connection string\" about a database that is\n * running and reachable.\n */\nfunction withManagedUrls(env: EnvBag, graph: ResourceGraph, url: string): EnvBag {\n const filled: EnvBag = { ...env };\n const keys = [\n DEFAULT_RESOURCE_KEY,\n ...graph.resources.filter(r => r.kind === \"database\").map(r => r.key)\n ];\n for (const key of keys) {\n const name = `DATABASE_URL${resourceEnvSuffix(key)}`;\n if (!isSet(filled, name)) filled[name] = url;\n }\n\n return filled;\n}\n\n/**\n * Resolve every declared resource against an environment.\n *\n * Each kind's verdict comes from the resolver `@rebasepro/server` registered\n * for it — the same one boot calls — so this view cannot say \"ready\" about a\n * binding boot would refuse. A kind with no resolver is reported as such\n * rather than skipped: a resource nobody shows is one nobody remembers to\n * configure, and a kind this runtime cannot bind is exactly what boot will\n * refuse by name.\n *\n * `resolveDataSources` is then run once over the whole set, so anything it\n * would refuse across sources (a driver package it cannot resolve for a custom\n * engine) is reported rather than missed by a view that only looked per row.\n */\nexport function computeStatus(\n graph: ResourceGraph,\n env: EnvBag,\n resolvers: StatusResolvers\n): { resources: ResourceStatus[]; blocked?: string } {\n const resources: ResourceStatus[] = [];\n const production = resolvers.production ?? false;\n const managed = resolvers.managedDatabase;\n /** Database rows the managed database answered for, so `blocked` can skip them. */\n let managedCovered = 0;\n\n for (const { declaration, implicit } of withImplicitDefaults(graph)) {\n const resolver = resolvers.resolverFor(declaration.kind);\n const bindings = bindingsFor(declaration, env, resolver?.accountScoped ?? []);\n const base: Omit<ResourceStatus, \"state\" | \"detail\"> = {\n kind: declaration.kind,\n key: declaration.key,\n engine: declaration.engine,\n transport: declaration.transport,\n ...(typeof declaration.options.account === \"string\"\n ? { account: declaration.options.account }\n : {}),\n implicit,\n bindings,\n ...(declaration.usedBy && declaration.usedBy.length > 0 ? { usedBy: declaration.usedBy } : {})\n };\n\n if (!resolver) {\n resources.push({\n ...base,\n state: \"broken\",\n detail: `this runtime has no resolver for a \"${declaration.kind}\" — boot refuses it by name. ` +\n \"Upgrade @rebasepro/server, or remove the declaration.\"\n });\n continue;\n }\n\n // Answered before the resolver, because the resolver reads the\n // environment and the whole point of the managed database is that the\n // environment is deliberately empty. Only for a database nobody bound:\n // a developer who set `DATABASE_URL__ANALYTICS` to a warehouse of their\n // own has said which database that is, and the managed one fills a\n // vacuum, never a choice.\n if (managed && declaration.kind === \"database\" && bindings.every(b => !b.set && !b.fallback?.set)) {\n managedCovered += 1;\n resources.push({\n ...base,\n state: \"ready\",\n detail: managed.url\n ? \"the managed development database (PGlite), this project only\"\n : \"the managed development database (PGlite), this project only — \"\n + \"not running; start it with `rebase dev`\"\n });\n continue;\n }\n\n const verdict = resolver.resolve(declaration, env, { production, defaultBasePath: \"uploads\" });\n switch (verdict.state) {\n case \"ready\":\n resources.push({\n ...base,\n state: \"ready\",\n ...(verdict.standsIn ? { standsIn: verdict.standsIn } : {}),\n detail: verdict.detail ?? \"\"\n });\n break;\n case \"code\":\n resources.push({ ...base, state: \"ready\", detail: verdict.detail ?? \"needs no environment configuration\" });\n break;\n case \"unbound\":\n resources.push({ ...base, state: \"unconfigured\", detail: verdict.detail ?? \"declared, not configured\" });\n break;\n case \"blocked\":\n resources.push({\n ...base,\n // A database the environment names nothing for is the\n // ordinary first-run state, and reads as unconfigured; a\n // binding that is set and set wrongly is broken.\n state: implicit || bindings.every(b => !b.set && !b.fallback?.set) ? \"unconfigured\" : \"broken\",\n detail: verdict.detail ?? \"boot refuses this binding\"\n });\n break;\n }\n }\n\n // Only asked when every row already looks fine. Its failures overlap with\n // the per-resource ones, and a banner repeating a line printed two rows\n // above teaches nothing — what it is here for is the failure no row models,\n // such as a custom engine whose driver package cannot be resolved.\n let blocked: string | undefined;\n // Not run when the managed database answered for a row and is not running:\n // there is no connection string to check the set against, and inventing one\n // to keep the check formally \"run\" is how a green tick gets printed for\n // work nobody did. The row says the daemon is down; that is the finding.\n const managedSetUnknown = managedCovered > 0 && !managed?.url;\n if (resources.every(r => r.state === \"ready\") && !managedSetUnknown) {\n try {\n resolvers.resolveDataSources(\n // The managed URL for the rows it answered for, so the whole-set\n // check judges the same environment the runtime would get.\n managed?.url ? withManagedUrls(env, graph, managed.url) : env,\n graph.resources.filter(r => r.kind === \"database\").map(resourceToDataSource)\n );\n } catch (err) {\n blocked = err instanceof Error ? err.message : String(err);\n }\n }\n\n return { resources, ...(blocked !== undefined ? { blocked } : {}) };\n}\n","/**\n * `rebase status` — what this project is, and whether it can reach its things.\n *\n * The model a developer has to hold is small and was nowhere visible:\n *\n * rebase.json where the code is, and who runs the server\n * config/resources.ts what the project needs\n * the environment how to reach each of them\n *\n * Everything else — `rebase.resources.json`, the bundle manifest — is a\n * generated copy of the middle one, for readers that cannot run the code. A\n * developer never writes them and should not have to think about them.\n *\n * This command prints the three together, resolved. It exists because the\n * question people actually arrive with — \"why does uploading to `media` answer\n * 501\" — was answerable only by knowing the `<BASE>__<KEY>` suffix rule,\n * deriving the variable name by hand, and checking it against a `.env` they had\n * to find first. Every step of that is mechanical, so it is printed instead.\n */\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { failAsJson, readEnvFile, requireProjectRoot } from \"../utils/project\";\nimport { findBackendApp, loadManifest, ManifestError, resolveBackendPaths } from \"../manifest\";\nimport { deriveOptionsFor, deriveResourceGraph, RESOURCE_GRAPH_FILENAME, readResourceGraphFile, serializeResourceGraph } from \"../resources/derive\";\nimport { computeStatus, type ResourceStatus } from \"../resources/status\";\nimport { findRunningDaemon, managedUrl } from \"../dev-db/daemon\";\nimport { resolveActiveBranch, resolveComposeUrl } from \"../dev-db/prepare\";\nimport { resolveDevDatabase } from \"../dev-db/resolve\";\nimport type { RebaseBackendAppConfig } from \"@rebasepro/types\";\n\nfunction usage(): void {\n console.log(`\n${chalk.bold(\"rebase status\")} — what this project declares, and whether it is configured\n\n${chalk.bold(\"Usage\")}\n rebase status Show every resource and the variables it reads\n rebase status --json The same, as JSON\n\n${chalk.bold(\"Reads\")}\n rebase.json which apps exist, and who owns the server process\n <config>/resources.ts the databases, buckets, topics and queues declared\n backend/crons, backend/functions the crons and functions, by filename\n .env whether each one's variables are set\n`);\n}\n\nconst MARK = {\n ready: chalk.green(\"✓\"),\n unconfigured: chalk.yellow(\"○\"),\n broken: chalk.red(\"✗\")\n} as const;\n\nfunction printResource(status: ResourceStatus): void {\n const name = status.key === \"(default)\" ? chalk.bold(\"(default)\") : chalk.bold(status.key);\n const tags = [chalk.gray(status.engine)];\n if (status.transport !== \"server\") tags.push(chalk.yellow(status.transport));\n if (status.account) tags.push(chalk.gray(`account:${status.account}`));\n if (status.implicit) tags.push(chalk.gray(\"implicit\"));\n // A stand-in is not a binding. It is shown in yellow beside a green tick:\n // uploads work here, and the same declaration answers 501 in production\n // until the variable is set.\n if (status.standsIn) tags.push(chalk.yellow(`local stand-in for ${status.standsIn}`));\n\n console.log(` ${MARK[status.state]} ${name} ${tags.join(\" · \")}`);\n if (status.usedBy && status.usedBy.length > 0) {\n console.log(` ${chalk.gray(\"used by\")} ${chalk.gray(status.usedBy.join(\", \"))}`);\n }\n\n let hiddenOptional = 0;\n for (const binding of status.bindings) {\n if (binding.set) {\n console.log(` ${chalk.green(\"✓\")} ${chalk.gray(binding.name)}`);\n } else if (binding.fallback?.set) {\n // Not a gap: the account form is the variable this bucket is\n // actually reading, and showing only the unset per-key name would\n // send someone to set the one they were deliberately avoiding.\n console.log(` ${chalk.green(\"✓\")} ${chalk.gray(binding.fallback.name)} ${chalk.gray(`(shared, for ${binding.name})`)}`);\n } else if (status.state === \"ready\") {\n // It resolved without this one, so this one is optional — which is\n // the resolver's answer, not a second table of required names kept\n // here. Listing seven unset optionals under a working database is\n // how a status view teaches people to skim past the line that\n // matters.\n hiddenOptional += 1;\n } else {\n const also = binding.fallback ? chalk.gray(` or ${binding.fallback.name}`) : \"\";\n console.log(` ${chalk.gray(\"·\")} ${chalk.gray(binding.name)}${also} ${chalk.gray(\"not set\")}`);\n }\n }\n if (hiddenOptional > 0) {\n console.log(chalk.gray(` ${hiddenOptional} optional variable${hiddenOptional === 1 ? \"\" : \"s\"} not set`));\n }\n\n if (status.detail) {\n const colour = status.state === \"broken\" ? chalk.red : status.state === \"unconfigured\" ? chalk.yellow : chalk.gray;\n console.log(` ${colour(`└ ${status.detail}`)}`);\n }\n}\n\nexport async function statusCommand(rawArgs: string[]): Promise<void> {\n if (wantsHelp(rawArgs)) return usage();\n\n const { flags } = parseCommandArgs({\n spec: { \"--json\": Boolean },\n rawArgs,\n commandWords: 1,\n command: \"status\",\n maxPositionals: 0\n });\n\n const projectRoot = requireProjectRoot();\n\n // Every exit below has a `--json` arm, because `--json` means stdout holds\n // one JSON object on *every* exit of the command. It used to mean that for\n // the one failure `requireProjectRoot` owns and nothing else, so a caller\n // parsing stdout got an envelope outside a project and an empty stream\n // inside a broken one — the case it actually has to handle.\n const asJson = Boolean(flags[\"--json\"]);\n\n let backend: { name: string; app: RebaseBackendAppConfig };\n try {\n const loaded = loadManifest(projectRoot);\n const found = findBackendApp(loaded.manifest);\n if (!found) {\n if (asJson) {\n failAsJson(\n \"This project declares no backend app, so it declares no resources.\",\n \"no_backend_app\",\n \"Add a backend app to rebase.json, or run `rebase apps init`.\"\n );\n }\n console.error(chalk.red(\"This project declares no backend app, so it declares no resources.\"));\n process.exitCode = 1;\n return;\n }\n backend = found;\n } catch (err) {\n if (err instanceof ManifestError) {\n if (asJson) {\n failAsJson(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n console.error(chalk.red(err.message));\n for (const issue of err.issues) console.error(` ${chalk.gray(issue.path)} ${issue.message}`);\n process.exitCode = 1;\n return;\n }\n throw err;\n }\n\n const { name: backendName, app: backendApp } = backend;\n const paths = resolveBackendPaths(backendApp, projectRoot);\n\n const { graph, issues } = await deriveResourceGraph(deriveOptionsFor(projectRoot, backendApp));\n if (issues.length > 0) {\n if (asJson) {\n failAsJson(\n `${issues.length} problem(s) in the declared resources.`,\n \"resource_declaration_invalid\",\n \"Fix the declarations the issues name, then run this again.\",\n issues.map(issue => ({ path: issue.path, message: issue.message }))\n );\n }\n console.error(chalk.red(`\\n✗ ${issues.length} problem(s) in the declared resources:\\n`));\n for (const issue of issues) console.error(` ${chalk.bold(issue.path)} ${issue.message}`);\n console.error(\"\");\n process.exitCode = 1;\n return;\n }\n\n // The project's own `.env`, not this process's environment: `rebase status`\n // is asking what a deployment of THIS repository would do, and the shell a\n // developer happens to be standing in is not that.\n const env = readEnvFile(projectRoot);\n\n // Which database this project is on, decided by the same ordered rule\n // `rebase dev` and `rebase db url` use — and read from the same `.env`, not\n // from this shell, for the reason above.\n //\n // Nothing is started. `status` is a question, and a question that boots a\n // 180 MB Postgres to answer itself is a different command. So a managed\n // database that is not running is reported as exactly that, rather than as\n // a project with no database — which is what this view used to say while\n // `rebase db url` printed a working connection string for it.\n const production = env.NODE_ENV === \"production\";\n const database = resolveDevDatabase({\n env: {},\n envFile: env,\n branch: resolveActiveBranch(projectRoot, env),\n composeUrl: resolveComposeUrl(projectRoot, env)\n });\n const daemon = database.kind === \"managed\" ? await findRunningDaemon(projectRoot) : null;\n const managedDatabase = !production && database.kind === \"managed\"\n ? { url: daemon ? managedUrl(daemon.port) : null }\n : undefined;\n\n const server = await import(\"@rebasepro/server\");\n const { resources, blocked } = computeStatus(graph, env, {\n resolverFor: server.resourceResolver as never,\n resolveDataSources: server.resolveDataSources as never,\n // Judged as production when the .env says so; a stand-in local\n // directory for an unbound bucket is only ever offered to development.\n production,\n ...(managedDatabase ? { managedDatabase } : {})\n });\n\n if (asJson) {\n console.log(JSON.stringify({ backend: backendName, runtime: backendApp.runtime, resources, blocked }, null, 2));\n return;\n }\n\n const ownership = backendApp.runtime === \"managed\"\n ? \"Rebase's runtime boots your bundle\"\n : \"this project builds its own image and entrypoint\";\n\n console.log(\"\");\n console.log(` ${chalk.bold(backendName)} ${chalk.gray(\"·\")} ${chalk.cyan(backendApp.runtime)} ${chalk.gray(ownership)}`);\n // Named whether or not it exists, and said plainly when it does not. A\n // project with no `resources.ts` is legal — it has one default database and\n // one default bucket — but \"declared in <a file you do not have>\" reads as\n // a broken install rather than as the default it is.\n const resourcesFile = path.join(paths.config, \"resources.ts\");\n const declaresAnything = fs.existsSync(path.join(projectRoot, resourcesFile));\n console.log(` ${chalk.gray(\"declared in\")} ${chalk.gray(resourcesFile)}${\n declaresAnything ? \"\" : chalk.gray(\" (none — the defaults below are implicit)\")}`);\n console.log(` ${chalk.gray(\"configured by\")} ${chalk.gray(\".env\")}`);\n\n const kinds = [...new Set(resources.map(r => r.kind))];\n for (const kind of kinds) {\n console.log(\"\");\n console.log(` ${chalk.bold.underline(`${kind}s`)}`);\n for (const status of resources.filter(r => r.kind === kind)) printResource(status);\n }\n\n if (blocked) {\n console.log(\"\");\n console.log(` ${chalk.red(\"✗\")} ${chalk.red(blocked)}`);\n }\n\n // Only worth a line when it is wrong. A generated file that matches its\n // declarations is not news, and a status view that reports its own\n // bookkeeping as an item trains people to skim past the items that matter.\n const committed = readResourceGraphFile(projectRoot);\n const expected = serializeResourceGraph(graph);\n if (committed !== expected && !(committed === null && graph.resources.length === 0)) {\n console.log(\"\");\n console.log(` ${chalk.yellow(\"○\")} ${RESOURCE_GRAPH_FILENAME} is ${committed === null ? \"missing\" : \"stale\"} — ${chalk.blue(\"rebase resources --write\")}`);\n console.log(chalk.gray(\" a host reads it to decide what to provision before it runs anything\"));\n }\n\n console.log(\"\");\n}\n","import path from \"path\";\nimport fs from \"fs\";\n\nimport chalk from \"chalk\";\n\nimport { normalizeEsmSpecifiers } from \"../bundle\";\nimport { parseCommandArgs } from \"../utils/args\";\n\n/**\n * Give compiled output the relative-import extensions Node's ESM loader needs.\n *\n * ## Why a project needs this at all\n *\n * TypeScript does not rewrite module specifiers, deliberately and by long-stated\n * policy: what you write is what it emits. Node's ESM loader, equally\n * deliberately, resolves no extensions — `./authors` is not a module, only\n * `./authors.js` is. Between those two positions sits every project that writes\n * extensionless relative imports, which is most of them, and which\n * `moduleResolution: \"bundler\"` — what this scaffold ships — is designed for.\n *\n * The usual escape is to write the *output* extension in the *source*:\n * `import x from \"./authors.js\"` in a file called `authors.ts`. It works, and it\n * is a tax on every import in the project to satisfy a step the toolchain could\n * take itself. This is that step.\n *\n * ## Why it is a command\n *\n * `rebase build` has always done this to its own bundle — the specifiers in\n * `dist-bundle` are complete because {@link normalizeEsmSpecifiers} completes\n * them. Nothing did it for the plain `tsc` output that `rebase eject` runs\n * (`node dist/backend/src/index.js`) or that a self-hoster runs after\n * `pnpm build`. So the templates wrote `.js` in source, which is the tax, and\n * removing it silently broke eject at `pnpm start` while `check:eject` — which\n * typechecks with `noEmit` — stayed green.\n *\n * One implementation, on both paths, callable from a package.json script.\n *\n * Mechanical and verifiable: only relative specifiers are touched, and only when\n * the target resolves to a file that exists. Idempotent, so a build that runs it\n * twice is a build that runs it once.\n */\nexport const NORMALIZE_IMPORTS_FLAGS = {\n /** Report what would change without writing anything. */\n \"--check\": Boolean\n} as const;\n\nconst HELP = `\n${chalk.bold(\"rebase normalize-imports\")} — complete the relative imports in compiled output\n\n${chalk.green.bold(\"Usage\")}\n rebase normalize-imports ${chalk.blue(\"<dir>\")} [--check]\n\n${chalk.green.bold(\"What it does\")}\n TypeScript emits your module specifiers verbatim, and Node's ESM loader does\n not guess extensions — so \\`./authors\\` compiles fine and fails at run time.\n This rewrites each relative specifier in the emitted JavaScript to the file it\n actually resolves to, so your source can stay extensionless.\n\n Only relative specifiers, only when the target exists on disk, and idempotent.\n\n${chalk.green.bold(\"Arguments\")}\n ${chalk.blue(\"<dir>\")} The directory tsc emitted into, e.g. ${chalk.cyan(\"dist\")}\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--check\")} Report what would change and exit 1 if anything would\n ${chalk.gray(\"(for CI — the build itself should just run the rewrite)\")}\n\n${chalk.green.bold(\"Where it runs\")}\n The scaffold's ${chalk.cyan(\"config\")} and ${chalk.cyan(\"backend\")} build scripts, after ${chalk.cyan(\"tsc\")}.\n ${chalk.cyan(\"rebase build\")} already does the same to the bundle it writes.\n`;\n\nexport async function normalizeImportsCommand(rawArgs: string[]): Promise<void> {\n const { flags, positionals, help } = parseCommandArgs({\n spec: NORMALIZE_IMPORTS_FLAGS,\n rawArgs,\n commandWords: 1,\n command: \"normalize-imports\",\n maxPositionals: 1\n });\n\n if (help) {\n console.log(HELP);\n return;\n }\n\n const target = positionals[0] ?? \"dist\";\n const outDir = path.resolve(process.cwd(), target);\n\n // A missing directory is the common shape of \"tsc did not run\", and saying\n // so beats a rewrite that reports zero changes and looks like success.\n if (!fs.existsSync(outDir)) {\n throw new Error(\n `${target} does not exist — run your build first. `\n + \"This step rewrites what the compiler emitted; it does not compile.\"\n );\n }\n\n const { rewritten, unresolved } = normalizeEsmSpecifiers(outDir);\n\n if (unresolved.length > 0) {\n console.log(chalk.yellow(` ⚠ ${unresolved.length} relative import(s) resolve to no file:`));\n for (const specifier of unresolved.slice(0, 10)) {\n console.log(chalk.dim(` ${specifier}`));\n }\n if (unresolved.length > 10) {\n console.log(chalk.dim(` …and ${unresolved.length - 10} more`));\n }\n console.log(chalk.dim(\" These will throw ERR_MODULE_NOT_FOUND at run time.\"));\n }\n\n if (flags[\"--check\"]) {\n if (rewritten > 0 || unresolved.length > 0) {\n throw new Error(\n `${rewritten} import(s) are incomplete for Node ESM. `\n + `Run \\`rebase normalize-imports ${target}\\` as part of the build.`\n );\n }\n console.log(chalk.green(`✓ every relative import in ${target} is complete`));\n return;\n }\n\n console.log(\n rewritten > 0\n ? chalk.dim(` completed ${rewritten} relative import(s) in ${target}/ for Node ESM`)\n : chalk.dim(` ${target}/ — every relative import was already complete`)\n );\n}\n","import chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport inquirer from \"inquirer\";\nimport { createRequire } from \"module\";\nimport { findProjectRoot } from \"../utils/project\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { unknownCommand } from \"../utils/unknown-command\";\n\nconst require = createRequire(import.meta.url);\n\n/**\n * Supported agent environments and their target directories.\n *\n * Every agent `rebase init` writes a pointer file for has an entry here. That\n * was not true: `rebase init` writes `CLAUDE.md`, `AGENTS.md`, `.cursorrules`,\n * `.windsurfrules` and `.github/copilot-instructions.md`, and the installer\n * covered four of the five — so a Codex or Copilot user was told, by a file in\n * their own repository, to run an installer that had nothing to offer them.\n *\n * `flatLayout` marks the agents whose rules directory is loaded *whole*, into\n * every request. Writing 21 skills there put ~84,000 characters of always-on\n * context in front of every question a person asked Cursor — more than the task\n * itself, on every turn, most of it about parts of Rebase they were not\n * touching. Those agents get one short index rule instead, and the skill bodies\n * go in per-skill subdirectories the index names, which the agent reads when it\n * needs one. `indexFile` is the name of that rule.\n *\n * A subdirectory layout has no such problem: the rule file already sits beside\n * its own assets, so `references/x.md` resolves as written and nothing is\n * loaded until it is opened.\n */\nconst AGENTS = {\n cursor: {\n label: \"Cursor\",\n detectDir: \".cursor\",\n targetDir: \".cursor/rules\",\n flatLayout: true,\n indexFile: \"rebase.mdc\",\n /** The body is not a rule file here — `indexFile` is. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n claude: {\n label: \"Claude Code\",\n detectDir: \".claude\",\n targetDir: \".claude/skills\",\n flatLayout: false,\n /** Claude Code uses the standard SKILL.md format in subdirectories. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n windsurf: {\n label: \"Windsurf\",\n detectDir: \".windsurf\",\n targetDir: \".windsurf/rules\",\n flatLayout: true,\n indexFile: \"rebase.md\",\n /** The body is not a rule file here — `indexFile` is. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n gemini: {\n label: \"Gemini CLI / Antigravity\",\n detectDir: \".agents\",\n targetDir: \".agents/skills\",\n flatLayout: false,\n /** Gemini uses the standard SKILL.md format in subdirectories. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n codex: {\n label: \"Codex CLI\",\n detectDir: \".codex\",\n targetDir: \".codex/skills\",\n flatLayout: false,\n /** Codex reads AGENTS.md; the skills sit beside its own config. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n kiro: {\n label: \"Kiro\",\n detectDir: \".kiro\",\n targetDir: \".kiro/steering\",\n flatLayout: true,\n indexFile: \"rebase.md\",\n /** The body is not a rule file here — `indexFile` is. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n },\n copilot: {\n label: \"GitHub Copilot\",\n // Deliberately undetectable. `.github/` is the one directory in this\n // table that is not evidence of an assistant: `rebase init` writes\n // `.github/copilot-instructions.md` into every scaffold, and half the\n // repositories on the internet have a `.github/` for workflows and\n // issue templates. Listing it made bare `rebase skills install` resolve\n // to `[copilot]` in every project — so a Claude Code user who ran the\n // command `rebase init` printed got a success message and nothing in\n // `.claude/skills`. Copilot is `--agent copilot`.\n detectDir: null,\n targetDir: \".github/instructions\",\n flatLayout: true,\n indexFile: \"rebase.instructions.md\",\n /** The body is not a rule file here — `indexFile` is. */\n transformFile: (skillName: string, content: string) => ({\n fileName: path.join(skillName, \"SKILL.md\"),\n content\n })\n }\n} as const;\n\ntype AgentKey = keyof typeof AGENTS;\n\n/**\n * Resolve the path to the skills directory from @rebasepro/agent-skills.\n * Works in both workspace (symlink) and published (real files) layouts.\n */\nfunction getSkillsSourceDir(): string {\n const pkgJsonPath = require.resolve(\"@rebasepro/agent-skills/package.json\");\n const pkgRoot = path.dirname(pkgJsonPath);\n const skillsDir = path.join(pkgRoot, \"skills\");\n\n if (!fs.existsSync(skillsDir)) {\n throw new Error(\n `Skills directory not found at ${skillsDir}. ` +\n \"Make sure @rebasepro/agent-skills is installed.\"\n );\n }\n\n return skillsDir;\n}\n\nexport interface LoadedSkill {\n name: string;\n /** Absolute path of the skill's source directory. */\n dir: string;\n content: string;\n /** Every file the skill ships besides SKILL.md, relative to `dir`. */\n assets: string[];\n}\n\n/**\n * Everything a skill ships alongside its SKILL.md — the `references/` tree the\n * Agent Skills format uses for progressive disclosure.\n *\n * These used to be dropped on install, because the installer read exactly\n * `<skill>/SKILL.md` and nothing else. That left `rebase-design-language`\n * telling the agent three separate times to read `references/view-patterns.md`\n * — 379 lines of view skeletons — in a project where the file had never\n * landed, and the instruction it carries is \"extend an existing pattern; do not\n * invent a layout\".\n */\nfunction loadSkillAssets(skillDir: string): string[] {\n const found: string[] = [];\n\n const walk = (dir: string, prefix: string) => {\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n // Dotfiles are bookkeeping — `.gitkeep` is what holds the empty\n // `references/` directories in git — and install nothing.\n if (entry.name.startsWith(\".\")) continue;\n const rel = prefix ? path.join(prefix, entry.name) : entry.name;\n if (entry.isDirectory()) walk(path.join(dir, entry.name), rel);\n else if (rel !== \"SKILL.md\") found.push(rel);\n }\n };\n\n walk(skillDir, \"\");\n return found.sort();\n}\n\n/** Read all skill directories and return their names, content and assets. */\nexport function loadSkills(skillsDir: string): LoadedSkill[] {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true });\n const skills: LoadedSkill[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const skillDir = path.join(skillsDir, entry.name);\n const skillMdPath = path.join(skillDir, \"SKILL.md\");\n if (!fs.existsSync(skillMdPath)) continue;\n skills.push({\n name: entry.name,\n dir: skillDir,\n content: fs.readFileSync(skillMdPath, \"utf-8\"),\n assets: loadSkillAssets(skillDir)\n });\n }\n\n return skills;\n}\n\n/**\n * The one always-on rule a flat-layout agent gets, in place of every skill.\n *\n * Cursor and Windsurf load their whole rules directory into each request. With\n * a rule file per skill that was ~84,000 characters of Rebase reference in\n * front of every question, whether or not the question was about Rebase — and\n * an instruction an assistant skims is an instruction it does not follow.\n *\n * So the always-on part is this: a table of what exists and where to read it.\n * `alwaysApply: true` because knowing the skills are there costs a few hundred\n * characters and is the whole point; the bodies stay on disk until the agent\n * opens one.\n */\nexport function renderSkillIndex(skills: LoadedSkill[], agentKey: AgentKey): string {\n const agent = AGENTS[agentKey];\n const bodyPath = (name: string) => agent.transformFile(name, \"\").fileName.split(path.sep).join(\"/\");\n const rows = skills\n .map((skill) => `| \\`${skill.name}\\` | ${describe(skill)} | \\`${bodyPath(skill.name)}\\` |`)\n .join(\"\\n\");\n\n return [\n \"---\",\n \"description: Rebase — the skills index. Read the file named for the task before writing Rebase code.\",\n \"alwaysApply: true\",\n \"---\",\n \"\",\n \"# Rebase skills\",\n \"\",\n `This project uses [Rebase](https://rebase.pro). ${skills.length} reference skills are`,\n \"installed beside this file. **Read the one that covers the task before writing\",\n \"code** — they are the difference between a collection that compiles and one that\",\n \"does not.\",\n \"\",\n \"| Skill | Covers | Read |\",\n \"|---|---|---|\",\n rows,\n \"\",\n \"Start with `rebase-basics` if you are not sure: it opens with the recipes for\",\n \"adding a collection, a function and an RLS rule, and names the commands.\",\n \"\"\n ].join(\"\\n\");\n}\n\n/**\n * The body of a YAML block scalar, given the offset of its `description:` line.\n *\n * Everything indented more than the key belongs to the value; the first line\n * that is not blank and not indented ends it.\n */\nfunction blockScalarBody(frontMatter: string, keyOffset: number): string {\n const lines = frontMatter.slice(keyOffset).split(\"\\n\").slice(1);\n const body: string[] = [];\n for (const line of lines) {\n if (line.trim() === \"\") { body.push(\"\"); continue; }\n if (!/^[ \\t]/.test(line)) break;\n body.push(line.trim());\n }\n return body.join(\" \");\n}\n\n/**\n * A skill's one-line summary, from its own front matter.\n *\n * Read rather than written here so a new skill needs no edit in this file, and\n * truncated because the index is only worth having while it stays short.\n */\nfunction describe(skill: LoadedSkill): string {\n const frontMatter = skill.content.split(\"---\")[1] ?? \"\";\n const described = /^description:[ \\t]*(.*)$/m.exec(frontMatter);\n // `description: |` (or `>`) is a YAML block scalar: the value is the\n // indented lines that follow, and capturing the line itself captured the\n // `|`. That rendered an empty \"Covers\" cell for `rebase-design-language`,\n // the one skill whose description says agents MUST read it.\n const raw = /^[|>][-+]?$/.test((described?.[1] ?? \"\").trim())\n ? blockScalarBody(frontMatter, described?.index ?? 0)\n : (described?.[1] ?? \"\");\n const text = raw.trim().replace(/\\s+/g, \" \").replace(/\\|/g, \"\\\\|\");\n const firstSentence = /^.*?\\.(?:\\s|$)/.exec(text)?.[0]?.trim() ?? text;\n const fallback = skill.name.replace(/^rebase-/, \"\").replace(/-/g, \" \");\n if (!firstSentence) return fallback;\n if (firstSentence.length <= 140) return firstSentence;\n // Cut at a word boundary. A description sliced mid-word (\"using the collect\")\n // reads as a corrupted file rather than as a summary.\n const cut = firstSentence.slice(0, 140);\n return `${cut.slice(0, cut.lastIndexOf(\" \")).replace(/[,;:]$/, \"\")}…`;\n}\n\n/**\n * Detect which agent environments already exist in the project.\n *\n * A `detectDir` has to be evidence *the user* created, not something a scaffold\n * ships. An agent whose only marker fails that test declares `detectDir: null`\n * and is reachable by `--agent` alone; guessing wrong here is worse than not\n * guessing, because the wrong guess installs 21 files and reports success.\n */\nexport function detectAgents(projectDir: string): AgentKey[] {\n const detected: AgentKey[] = [];\n for (const [key, agent] of Object.entries(AGENTS)) {\n if (!agent.detectDir) continue;\n if (fs.existsSync(path.join(projectDir, agent.detectDir))) {\n detected.push(key as AgentKey);\n }\n }\n return detected;\n}\n\n/** Install skills for a specific agent into the project directory. */\nexport function installForAgent(\n agentKey: AgentKey,\n skills: LoadedSkill[],\n projectDir: string\n): { skills: number; assets: number } {\n const agent = AGENTS[agentKey];\n const targetBase = path.join(projectDir, agent.targetDir);\n\n // Ensure the target directory exists\n fs.mkdirSync(targetBase, { recursive: true });\n\n let count = 0;\n let assetCount = 0;\n for (const skill of skills) {\n // Every layout now writes the body into a per-skill subdirectory, so a\n // link the skill spells `references/x.md` resolves as written and no\n // rewriting is needed. What differs is whether that file is also the\n // agent's *rule* file (subdirectory layouts) or something the index\n // points at (flat ones).\n const { fileName, content } = agent.transformFile(skill.name, skill.content);\n const targetPath = path.join(targetBase, fileName);\n\n // Ensure parent directory exists (for subdirectory-based formats)\n fs.mkdirSync(path.dirname(targetPath), { recursive: true });\n fs.writeFileSync(targetPath, content, \"utf-8\");\n count++;\n\n // A skill's assets always land in a directory named after the skill,\n // whatever the rule file's layout, so two skills' `references/` trees\n // cannot collide in a flat target directory.\n for (const asset of skill.assets) {\n const assetTarget = path.join(targetBase, skill.name, asset);\n fs.mkdirSync(path.dirname(assetTarget), { recursive: true });\n fs.copyFileSync(path.join(skill.dir, asset), assetTarget);\n assetCount++;\n }\n }\n\n if (agent.flatLayout && agent.indexFile) {\n fs.writeFileSync(path.join(targetBase, agent.indexFile), renderSkillIndex(skills, agentKey), \"utf-8\");\n }\n\n return { skills: count, assets: assetCount };\n}\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const SKILLS_SUBCOMMANDS = [\"install\"] as const;\n\nexport async function skillsCommand(subcommand: string | undefined, rawArgs: string[]) {\n // `--help` cannot reach `skillsInstall`. `cli.ts` only rewrites the\n // subcommand to `\"--help\"` when none was named, so `rebase skills install\n // --help` used to run the install: it detected the agents and overwrote\n // `.claude/skills/*/SKILL.md`, `.cursor/rules/*.mdc` and the rest. A flag\n // that prints text must not write files.\n if (wantsHelp(rawArgs)) {\n printSkillsHelp();\n return;\n }\n\n switch (subcommand) {\n case \"install\":\n await skillsInstall(rawArgs);\n break;\n case \"--help\":\n case undefined:\n printSkillsHelp();\n break;\n default:\n unknownCommand(subcommand, SKILLS_SUBCOMMANDS, \"skills\");\n }\n}\n\n/**\n * Agents named explicitly on the command line, e.g. `--agent claude --agent cursor`\n * (also accepts a comma-separated list, and `all`). Returns null when none were\n * given.\n */\nexport function parseAgentFlags(rawArgs: string[]): AgentKey[] | null {\n // Strict, and before anything is written. This used to scan `rawArgs` for\n // `--agent` and ignore every other token, so `rebase skills install\n // --frobnicate --agent claude` exited 0 after writing 21 files — the CLI's\n // other families reject an unknown flag, and an installer is the last place\n // to guess what the person meant.\n const { flags } = parseCommandArgs({\n spec: { \"--agent\": [String], \"-a\": \"--agent\" },\n rawArgs,\n commandWords: 2,\n command: \"skills install\",\n maxPositionals: 0\n });\n\n const requested = (flags[\"--agent\"] ?? [])\n .flatMap(value => value.split(\",\").map(v => v.trim()))\n .filter(Boolean);\n if (requested.length === 0) return null;\n\n // `all` exists for the non-interactive case. Detection cannot help there: a\n // scaffolded project ships `.cursorrules`, `CLAUDE.md`, `.windsurfrules`,\n // `AGENTS.md` and `.github/copilot-instructions.md` all at once, so every\n // pointer file is present and none of them says which assistant the\n // developer actually uses. Guessing from them would install several agents'\n // skills unasked; refusing leaves a scripted setup with no way through.\n // Naming `all` is the developer saying it out loud.\n if (requested.includes(\"all\")) return Object.keys(AGENTS) as AgentKey[];\n\n const valid = Object.keys(AGENTS);\n const unknown = requested.filter(a => !valid.includes(a));\n if (unknown.length > 0) {\n console.error(chalk.red(`Unknown agent(s): ${unknown.join(\", \")}. Available: ${valid.join(\", \")}`));\n process.exit(1);\n }\n return requested as AgentKey[];\n}\n\nasync function skillsInstall(rawArgs: string[] = []) {\n // Parse the line before anything else touches the disk: a bad flag must\n // cost nothing, and everything below this writes or resolves paths.\n const namedAgents = parseAgentFlags(rawArgs);\n\n // The project root, not the cwd. Agent skills belong beside the repository's\n // other agent configuration — `.claude/`, `.cursor/` — which is both what\n // `detectAgents` looks for and where an assistant reads them from. Resolving\n // against wherever the command happened to be typed put them in\n // `backend/.claude/skills` when run from `backend/`, detected no agent\n // there, and left the skills somewhere nothing would look. Outside a project\n // the cwd is still the honest answer: this command is useful in a repository\n // that is not a Rebase one.\n const projectDir = findProjectRoot() ?? process.cwd();\n\n // 1. Load skills from @rebasepro/agent-skills\n let skillsDir: string;\n try {\n skillsDir = getSkillsSourceDir();\n } catch (err) {\n console.error(`${chalk.red.bold(\"ERROR\")} ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n const skills = loadSkills(skillsDir);\n if (skills.length === 0) {\n console.error(`${chalk.red.bold(\"ERROR\")} No skills found in ${skillsDir}`);\n process.exit(1);\n }\n\n // 2. Explicit --agent wins; otherwise detect existing agent environments\n let agents = namedAgents ?? detectAgents(projectDir);\n\n // 3. If none detected, ask the user\n if (agents.length === 0) {\n // A scaffolded project ships `.cursorrules`, `CLAUDE.md`, `AGENTS.md`\n // and `.github/copilot-instructions.md`, but none of the *directories*\n // detectAgents looks for, so a fresh project always lands here — which\n // is correct: those files say what `rebase init` writes, not what the\n // developer uses. On a non-TTY that used to abort with a raw\n // ExitPromptError.\n if (!process.stdin.isTTY) {\n console.error(chalk.red(\"Cannot prompt: this is a non-interactive terminal (no TTY).\"));\n console.error(chalk.yellow(` Name the agents explicitly, e.g. rebase skills install --agent ${Object.keys(AGENTS)[0]}`));\n console.error(chalk.yellow(\" Or install for every supported agent: rebase skills install --agent all\"));\n console.error(chalk.gray(` Available: ${Object.keys(AGENTS).join(\", \")}`));\n process.exit(1);\n }\n\n const choices = Object.entries(AGENTS).map(([key, agent]) => ({\n name: agent.label,\n value: key,\n checked: false\n }));\n\n const { selectedAgents } = await inquirer.prompt([{\n type: \"checkbox\",\n name: \"selectedAgents\",\n message: \"No AI agent configuration detected. Which agents do you use?\",\n choices,\n validate: (input: string[]) => {\n if (input.length === 0) return \"Please select at least one agent.\";\n return true;\n }\n }]);\n\n agents = selectedAgents as AgentKey[];\n }\n\n // 4. Install skills for each agent\n console.log(\"\");\n console.log(chalk.gray(` Found ${chalk.white(skills.length)} Rebase skills`));\n console.log(\"\");\n\n for (const agentKey of agents) {\n const agent = AGENTS[agentKey];\n const { skills: count, assets } = installForAgent(agentKey, skills, projectDir);\n // Relative to where the command was typed, now that the destination is\n // the project root rather than the cwd — otherwise `.claude/skills`\n // names a directory that is not the one it wrote to.\n const shown = path.relative(process.cwd(), path.join(projectDir, agent.targetDir)) || agent.targetDir;\n const withAssets = assets > 0 ? ` (+ ${assets} reference file${assets === 1 ? \"\" : \"s\"})` : \"\";\n console.log(` ${chalk.green(\"✓\")} ${chalk.bold(agent.label)} — ${count} skills installed${withAssets} to ${chalk.gray(shown)}`);\n }\n\n console.log(\"\");\n console.log(chalk.gray(\" Skills are project-local. Commit them to share with your team.\"));\n console.log(chalk.gray(\" Re-run this command anytime to update to the latest skills.\"));\n console.log(\"\");\n}\n\nfunction printSkillsHelp() {\n console.log(`\n${chalk.bold(\"rebase skills\")} — Manage AI agent skills\n\n${chalk.green.bold(\"Usage\")}\n rebase skills ${chalk.blue(\"<subcommand>\")}\n\n${chalk.green.bold(\"Subcommands\")}\n ${chalk.blue.bold(\"install\")} Install Rebase agent skills for your AI coding assistant\n Supports: ${Object.values(AGENTS).map(a => a.label).join(\", \")}\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--agent, -a\")} Agent(s) to install for, skipping detection and the prompt.\n Repeat the flag or pass a comma-separated list, or ${chalk.bold(\"all\")}.\n Required without a TTY: detection looks for an agent's own\n directory (${Object.values(AGENTS).filter(a => a.detectDir).map(a => a.detectDir).join(\", \")}),\n and a fresh scaffold has none. GitHub Copilot is never detected\n — ${chalk.gray(\".github/\")} is not evidence anyone uses it — so name it.\n Available: ${Object.keys(AGENTS).join(\", \")}, all\n\n${chalk.green.bold(\"Examples\")}\n ${chalk.cyan(\"rebase skills install\")}\n ${chalk.cyan(\"rebase skills install --agent claude\")}\n ${chalk.cyan(\"rebase skills install --agent claude,cursor\")}\n ${chalk.cyan(\"rebase skills install --agent all\")} ${chalk.gray(\"# scripted / CI\")}\n`);\n}\n","/**\n * CLI command: rebase api-keys <action>\n *\n * Subcommands:\n * list — List all API keys (masked)\n * create — Create a new API key\n * revoke — Revoke an existing API key\n */\nimport chalk from \"chalk\";\nimport {\n requireProjectRoot,\n readEnvFile\n} from \"../utils/project\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { unknownCommand } from \"../utils/unknown-command\";\nimport fs from \"fs\";\nimport path from \"path\";\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const API_KEYS_SUBCOMMANDS = [\"list\", \"create\", \"revoke\"] as const;\n\n/* ═══════════════════════════════════════════════════════════════\n Env helper — reads SERVICE_KEY and PORT from .env\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Was a hand-rolled `indexOf(\"=\")` loop. It keyed `export KEY=value` as\n * `export KEY` and carried a trailing `# comment` into the value — so a key\n * that was present read as absent, or reached an `Authorization` header with a\n * comment attached and came back 401. See `readEnvFile`.\n */\nconst loadEnv = readEnvFile;\n\nfunction resolveBaseUrl(env: Record<string, string>, projectRoot?: string): string {\n // An explicit override always wins.\n if (env.REBASE_BASE_URL) return env.REBASE_BASE_URL;\n\n // `rebase dev` runs on a derived per-project port, not the .env PORT, and\n // records the URL it actually bound. Without this, these commands default to\n // :3001 and report \"Is the Rebase server running?\" while it is running.\n if (projectRoot) {\n try {\n const urlFile = path.join(projectRoot, \".rebase-dev-url\");\n if (fs.existsSync(urlFile)) {\n const devUrl = fs.readFileSync(urlFile, \"utf-8\").trim();\n if (devUrl) return devUrl;\n }\n } catch { /* fall through to the configured port */ }\n }\n\n const port = env.PORT || env.REBASE_PORT || \"3001\";\n return `http://localhost:${port}`;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Entry\n ═══════════════════════════════════════════════════════════════ */\n\nexport async function apiKeysCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // `--help` is answered before dispatch, never by a handler. `cli.ts` only\n // rewrites the subcommand to `\"--help\"` when none was named, so\n // `rebase api-keys list --help` used to *list the keys* and\n // `rebase api-keys revoke --help` sent `DELETE /api/admin/api-keys/--help`.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printApiKeysHelp();\n return;\n }\n\n switch (subcommand) {\n case \"list\":\n await listKeys(rawArgs);\n break;\n case \"create\":\n await createKey(rawArgs);\n break;\n case \"revoke\":\n await revokeKey(rawArgs);\n break;\n default:\n // The shape every other family uses. This one printed a bare line\n // to stderr *and* the whole help page to stdout, so a typo wrote\n // twenty lines to a stream a `--json` caller reads, with no `✗`, no\n // pointer at `--help`, and no did-you-mean — `craete` is one\n // transposition from `create`.\n unknownCommand(subcommand, API_KEYS_SUBCOMMANDS, \"api-keys\");\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n list\n ═══════════════════════════════════════════════════════════════ */\n\nasync function listKeys(_rawArgs: string[]): Promise<void> {\n const projectRoot = requireProjectRoot();\n const env = loadEnv(projectRoot);\n const baseUrl = resolveBaseUrl(env, projectRoot);\n const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;\n\n if (!serviceKey) {\n console.error(chalk.red(\"✗ SERVICE_KEY not found in .env — required for admin operations.\"));\n process.exit(1);\n }\n\n try {\n const res = await fetch(`${baseUrl}/api/admin/api-keys`, {\n headers: { Authorization: `Bearer ${serviceKey}` }\n });\n if (!res.ok) {\n const body = await res.text();\n console.error(chalk.red(`✗ Failed to list API keys: ${res.status} ${body}`));\n process.exit(1);\n }\n\n const { keys } = await res.json() as { keys: Array<{\n id: string; name: string; key_prefix: string;\n permissions: Array<{ collection: string; operations: string[] }>;\n rate_limit: number | null; revoked_at: string | null;\n expires_at: string | null; last_used_at: string | null;\n created_at: string;\n }>};\n\n console.log(\"\");\n console.log(chalk.bold(\" 🔑 API Keys\"));\n console.log(\"\");\n\n if (keys.length === 0) {\n console.log(chalk.gray(\" No API keys found.\"));\n console.log(\"\");\n return;\n }\n\n for (const key of keys) {\n const status = key.revoked_at ? chalk.red(\"revoked\")\n : (key.expires_at && new Date(key.expires_at) < new Date()) ? chalk.yellow(\"expired\")\n : chalk.green(\"active\");\n\n const perms = key.permissions.map(p =>\n `${p.collection}(${p.operations.join(\",\")})`\n ).join(\", \");\n\n console.log(` ${chalk.bold(key.name)} ${chalk.gray(`[${key.key_prefix}•••]`)} ${status}`);\n console.log(` ${chalk.gray(\"ID:\")} ${key.id}`);\n console.log(` ${chalk.gray(\"Permissions:\")} ${perms || \"none\"}`);\n console.log(` ${chalk.gray(\"Created:\")} ${new Date(key.created_at).toLocaleDateString()}`);\n if (key.last_used_at) {\n console.log(` ${chalk.gray(\"Last used:\")} ${new Date(key.last_used_at).toLocaleDateString()}`);\n }\n console.log(\"\");\n }\n } catch (e: unknown) {\n console.error(chalk.red(`✗ ${e instanceof Error ? e.message : String(e)}`));\n console.error(chalk.gray(\" Is the Rebase server running?\"));\n process.exit(1);\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n create\n ═══════════════════════════════════════════════════════════════ */\n\n/** The flags `rebase api-keys create` takes. */\nexport const CREATE_KEY_FLAGS = {\n \"--name\": String,\n \"--permissions\": String,\n \"--full-access\": Boolean,\n \"--admin\": Boolean,\n \"--rate-limit\": Number,\n \"--expires\": String,\n \"-n\": \"--name\"\n} as const;\n\n/**\n * What this invocation asks to be created.\n *\n * The name may be given either way — `--name \"My Key\"` or as the single\n * positional — and under the old permissive parse an undeclared flag became\n * that positional: `rebase api-keys create --debug --full-access` created a\n * key called `--debug` with read/write/delete on every collection, and\n * `--debug` is what the CLI prints after every failure as the thing to re-run\n * with. Strict parsing makes the flag an error instead of a name.\n *\n * Exported so its tests can drive the real parser rather than a copy of it.\n */\nexport function resolveCreateKeyArgs(rawArgs: string[]) {\n const { flags, positionals } = parseCommandArgs({\n spec: CREATE_KEY_FLAGS,\n rawArgs,\n commandWords: 2,\n command: \"api-keys create\",\n maxPositionals: 1\n });\n\n return { flags,\nname: flags[\"--name\"] || positionals[0] };\n}\n\nasync function createKey(rawArgs: string[]): Promise<void> {\n const { flags: args, name } = resolveCreateKeyArgs(rawArgs);\n\n const permissionsRaw = args[\"--permissions\"];\n\n if (!name) {\n console.error(chalk.red(\"✗ Name is required.\"));\n console.log(\"\");\n console.log(chalk.gray(' Usage: rebase api-keys create --name \"My Key\" --permissions \\'[{\"collection\":\"*\",\"operations\":[\"read\"]}]\\''));\n process.exit(1);\n }\n\n let permissions: Array<{ collection: string; operations: string[] }>;\n if (permissionsRaw) {\n try {\n permissions = JSON.parse(permissionsRaw);\n } catch {\n console.error(chalk.red(\"✗ Invalid --permissions JSON.\"));\n console.log(chalk.gray(' Example: \\'[{\"collection\":\"*\",\"operations\":[\"read\",\"write\"]}]\\''));\n process.exit(1);\n return; // unreachable but satisfies TS\n }\n } else if (args[\"--full-access\"]) {\n permissions = [{ collection: \"*\",\noperations: [\"read\", \"write\", \"delete\"] }];\n } else {\n // No silent full-access default: a \"scoped keys\" feature should not\n // hand out read/write/delete on every collection when the flag is\n // simply forgotten. Full access must be asked for by name.\n console.error(chalk.red(\"✗ Specify what the key may access: --permissions '<json>' or --full-access.\"));\n console.log(\"\");\n console.log(chalk.gray(' Scoped: rebase api-keys create -n \"Analytics\" --permissions \\'[{\"collection\":\"events\",\"operations\":[\"read\"]}]\\''));\n console.log(chalk.gray(' Functions: add {\"collection\":\"functions/<name>\",\"operations\":[\"write\"]} to invoke a custom function'));\n console.log(chalk.gray(' Storage: add {\"collection\":\"storage\",\"operations\":[\"read\",\"write\"]} for file storage'));\n console.log(chalk.gray(' Full access: rebase api-keys create -n \"CI\" --full-access'));\n process.exit(1);\n return; // unreachable but satisfies TS\n }\n\n let expires_at: string | null = null;\n const expiresFlag = args[\"--expires\"];\n if (expiresFlag) {\n const days: Record<string, number> = { \"7d\": 7,\n\"30d\": 30,\n\"90d\": 90,\n\"1y\": 365 };\n if (days[expiresFlag]) {\n expires_at = new Date(Date.now() + days[expiresFlag] * 86400000).toISOString();\n } else {\n const parsed = new Date(expiresFlag);\n if (isNaN(parsed.getTime())) {\n console.error(chalk.red(\"✗ Invalid --expires value. Use 7d, 30d, 90d, 1y, or an ISO date.\"));\n process.exit(1);\n }\n expires_at = parsed.toISOString();\n }\n }\n\n const projectRoot = requireProjectRoot();\n const env = loadEnv(projectRoot);\n const baseUrl = resolveBaseUrl(env, projectRoot);\n const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;\n\n if (!serviceKey) {\n console.error(chalk.red(\"✗ SERVICE_KEY not found in .env — required for admin operations.\"));\n process.exit(1);\n }\n\n try {\n const body: Record<string, unknown> = {\n name,\n permissions,\n admin: args[\"--admin\"] ?? false,\n rate_limit: args[\"--rate-limit\"] ?? null,\n expires_at\n };\n\n const res = await fetch(`${baseUrl}/api/admin/api-keys`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${serviceKey}`,\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify(body)\n });\n\n if (!res.ok) {\n const errBody = await res.text();\n console.error(chalk.red(`✗ Failed to create API key: ${res.status} ${errBody}`));\n process.exit(1);\n }\n\n const { key } = await res.json() as { key: { name: string; key: string; key_prefix: string; id: string } };\n\n console.log(\"\");\n console.log(chalk.bold.green(\" ✓ API key created successfully\"));\n console.log(\"\");\n console.log(` ${chalk.gray(\"Name:\")} ${key.name}`);\n console.log(` ${chalk.gray(\"ID:\")} ${key.id}`);\n console.log(` ${chalk.gray(\"Prefix:\")} ${key.key_prefix}`);\n console.log(\"\");\n console.log(chalk.bold.yellow(\" ⚠ Copy your key now — it won't be shown again:\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(key.key)}`);\n console.log(\"\");\n } catch (e: unknown) {\n console.error(chalk.red(`✗ ${e instanceof Error ? e.message : String(e)}`));\n console.error(chalk.gray(\" Is the Rebase server running?\"));\n process.exit(1);\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n revoke\n ═══════════════════════════════════════════════════════════════ */\n\n/** The flags `rebase api-keys revoke` takes. */\nexport const REVOKE_KEY_FLAGS = {\n \"--id\": String\n} as const;\n\n/**\n * Which key this invocation names.\n *\n * The id is a positional, so the permissive parse handed one straight to the\n * DELETE: `rebase api-keys revoke --foo` sent\n * `DELETE /api/admin/api-keys/--foo`, and `rebase --debug api-keys revoke <id>`\n * shifted the words along and revoked the key named `revoke`.\n *\n * Exported so its tests can drive the real parser rather than a copy of it.\n */\nexport function resolveRevokeKeyArgs(rawArgs: string[]): { id?: string } {\n const { flags, positionals } = parseCommandArgs({\n spec: REVOKE_KEY_FLAGS,\n rawArgs,\n commandWords: 2,\n command: \"api-keys revoke\",\n maxPositionals: 1\n });\n\n return { id: flags[\"--id\"] || positionals[0] };\n}\n\nasync function revokeKey(rawArgs: string[]): Promise<void> {\n const { id } = resolveRevokeKeyArgs(rawArgs);\n\n if (!id) {\n console.error(chalk.red(\"✗ Key ID is required.\"));\n console.log(\"\");\n console.log(chalk.gray(\" Usage: rebase api-keys revoke <key-id>\"));\n process.exit(1);\n }\n\n const projectRoot = requireProjectRoot();\n const env = loadEnv(projectRoot);\n const baseUrl = resolveBaseUrl(env, projectRoot);\n const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;\n\n if (!serviceKey) {\n console.error(chalk.red(\"✗ SERVICE_KEY not found in .env — required for admin operations.\"));\n process.exit(1);\n }\n\n try {\n const res = await fetch(`${baseUrl}/api/admin/api-keys/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${serviceKey}` }\n });\n\n if (!res.ok) {\n const errBody = await res.text();\n console.error(chalk.red(`✗ Failed to revoke API key: ${res.status} ${errBody}`));\n process.exit(1);\n }\n\n console.log(\"\");\n console.log(chalk.bold.green(\" ✓ API key revoked successfully\"));\n console.log(` ${chalk.gray(\"ID:\")} ${id}`);\n console.log(\"\");\n } catch (e: unknown) {\n console.error(chalk.red(`✗ ${e instanceof Error ? e.message : String(e)}`));\n console.error(chalk.gray(\" Is the Rebase server running?\"));\n process.exit(1);\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Help\n ═══════════════════════════════════════════════════════════════ */\n\nfunction printApiKeysHelp() {\n console.log(`\n${chalk.bold(\"rebase api-keys\")} — Manage Service API Keys\n\n${chalk.green.bold(\"Usage\")}\n rebase api-keys ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"list\")} List all API keys\n ${chalk.blue.bold(\"create\")} Create a new API key\n ${chalk.blue.bold(\"revoke\")} Revoke an API key\n\n${chalk.green.bold(\"create Options\")}\n ${chalk.blue(\"--name, -n\")} Key name ${chalk.gray(\"(required)\")}\n ${chalk.blue(\"--permissions\")} JSON array of permissions ${chalk.gray(\"(required unless --full-access)\")}\n ${chalk.gray('Collections by slug; custom functions as \"functions\" or \"functions/<name>\"')}\n ${chalk.blue(\"--full-access\")} Grant read/write/delete on every collection and function\n ${chalk.blue(\"--admin\")} Grant admin role (admin routes + RLS admin policies)\n ${chalk.blue(\"--rate-limit\")} Requests per 15-min window ${chalk.gray(\"(default: 1000)\")}\n ${chalk.blue(\"--expires\")} Expiration: 7d, 30d, 90d, 1y, or ISO date\n\n${chalk.green.bold(\"revoke Options\")}\n ${chalk.blue(\"--id\")} API key ID to revoke ${chalk.gray(\"(or positional arg)\")}\n\n${chalk.green.bold(\"Examples\")}\n rebase api-keys list\n rebase api-keys create --name \"Analytics\" --permissions '[{\"collection\":\"events\",\"operations\":[\"read\"]}]'\n rebase api-keys create -n \"Full Access\" --full-access --expires 90d\n rebase api-keys revoke abc123-def456\n`);\n}\n","import chalk from \"chalk\";\n\nimport { describeState, renderPreview } from \"../telemetry/consent\";\nimport { configPath, endpoint, previewEvent, readConfig, readProjectPolicy, setConsent } from \"../telemetry\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { unknownCommand } from \"../utils/unknown-command\";\n\n/**\n * `rebase telemetry` — the command that makes the rest of it inspectable.\n *\n * The whole subsystem asks for trust it cannot otherwise earn, and the cheapest\n * way to earn it is to stop describing the payload and print it. `show` runs\n * the same builder the sender uses, so what appears here is what would go, not\n * a documentation comment that quietly fell out of date two releases ago.\n */\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const TELEMETRY_SUBCOMMANDS = [\"status\", \"show\", \"enable\", \"disable\"] as const;\n\nexport async function telemetryCommand(rawArgs: string[]): Promise<void> {\n // Checked before parsing, because `--help` is answered by the dispatcher\n // and never by a handler. It used to be checked after a `filter(a =>\n // !a.startsWith(\"-\"))` that stripped every flag off the line, so `rebase\n // telemetry --help` reached `case undefined` and printed the status page.\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n // Strictly, like every other family. That `filter` was not \"be lenient\": it\n // deleted every `-`-prefixed token before dispatch, so `rebase telemetry\n // --frobnicate` printed the status page and exited 0, and a mistyped\n // `--disable` looked exactly like asking for the status. `parseCommandArgs`\n // is the CLI's one rule for an undeclared flag, and the comment at the top\n // of `utils/args.ts` is why: guessing that an unknown flag was meant as\n // something else is the unsafe branch.\n const { positionals } = parseCommandArgs({\n spec: {},\n rawArgs,\n commandWords: 1,\n command: \"telemetry\",\n maxPositionals: 1\n });\n const subcommand = positionals[0];\n\n switch (subcommand) {\n case \"status\":\n case undefined:\n printStatus();\n return;\n case \"show\":\n printPayload();\n return;\n case \"enable\":\n if (!setConsent(true)) {\n console.error(chalk.red(`Could not write ${configPath()} — sharing was not enabled.`));\n process.exitCode = 1;\n return;\n }\n console.log(chalk.green(\"Anonymous usage sharing enabled.\"));\n console.log(chalk.gray(`Inspect what gets sent with ${chalk.cyan(\"rebase telemetry show\")}.`));\n return;\n case \"disable\":\n if (!setConsent(false)) {\n // The failure direction that matters. Someone turning sharing\n // off must never be left believing it worked — so this is loud,\n // non-zero, and points at the switch that needs no disk.\n console.error(chalk.red(`Could not write ${configPath()} — sharing is still ON.`));\n console.error(chalk.yellow(`Set ${chalk.cyan(\"REBASE_TELEMETRY_DISABLED=1\")} in your environment instead; it needs no file.`));\n process.exitCode = 1;\n return;\n }\n console.log(chalk.gray(\"Anonymous usage sharing disabled. Nothing further will be sent.\"));\n return;\n default:\n // Printing the help and setting exit 1 said nothing about *why*:\n // the page that came back looked like the page `rebase telemetry\n // --help` prints, and the only difference was an exit code nobody\n // reads at a prompt.\n unknownCommand(subcommand, TELEMETRY_SUBCOMMANDS, \"telemetry\");\n }\n}\n\nfunction printStatus(): void {\n console.log(\"\");\n console.log(` Status: ${describeState()}`);\n if (readProjectPolicy() === \"ignored_opt_in\") {\n // Said out loud rather than silently ignored: a maintainer who wrote\n // `\"telemetry\": true` believes they turned something on, and leaving\n // them to believe it is worse than refusing.\n console.log(\"\");\n console.log(chalk.yellow(\" Note: this project's rebase.json sets \\\"telemetry\\\": true, which is ignored.\"));\n console.log(chalk.gray(\" A committed file cannot consent on behalf of everyone who clones it.\"));\n console.log(chalk.gray(` Only \"telemetry\": false is honoured there. Use ${chalk.cyan(\"rebase telemetry enable\")}.`));\n }\n console.log(` Endpoint: ${chalk.gray(endpoint())}`);\n console.log(` Config: ${chalk.gray(configPath())}`);\n console.log(\"\");\n console.log(chalk.gray(` ${chalk.cyan(\"rebase telemetry show\")} prints the exact payload.`));\n console.log(\"\");\n}\n\nfunction printPayload(): void {\n const config = readConfig();\n if (config.enabled !== true) {\n // Deliberately still prints one. The consent prompt points here so the\n // question can stay short, and someone deciding whether to say yes is\n // exactly the person who most needs to see the payload — telling them\n // to enable sharing first, in order to find out what sharing sends,\n // is the wrong way round.\n console.log(\"\");\n console.log(` ${describeState()}`);\n console.log(\"\");\n console.log(chalk.gray(\" Nothing is being sent. This is what WOULD be sent if you said yes:\"));\n console.log(\"\");\n console.log(renderPreview(\"cli.dev\", { first_run: false }).split(\"\\n\").map((l) => \" \" + l).join(\"\\n\"));\n console.log(\"\");\n console.log(chalk.gray(` Start sharing with ${chalk.cyan(\"rebase telemetry enable\")}.`));\n console.log(\"\");\n return;\n }\n\n // A representative event rather than a synthetic one: `cli.dev` is the\n // event that fires most often, so it is the one worth being sure about.\n const event = previewEvent(\"cli.dev\", { first_run: false }, process.cwd());\n console.log(\"\");\n console.log(chalk.gray(\" Sent to \") + chalk.gray(endpoint()) + chalk.gray(\", for example:\"));\n console.log(\"\");\n console.log(JSON.stringify(event, null, 2).split(\"\\n\").map((l) => \" \" + l).join(\"\\n\"));\n console.log(\"\");\n console.log(chalk.gray(\" Both ids are random. Neither is derived from your machine, your\"));\n console.log(chalk.gray(\" hostname, your project name or anything you have typed.\"));\n console.log(\"\");\n}\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase telemetry\")} — anonymous usage sharing (asked once per project)\n\n${chalk.bold(\"Commands\")}\n ${chalk.blue(\"status\")} Whether anything is being shared, and why ${chalk.gray(\"(default)\")}\n ${chalk.blue(\"show\")} Print the exact payload that would be sent\n ${chalk.blue(\"enable\")} Start sharing\n ${chalk.blue(\"disable\")} Stop sharing, permanently\n\n${chalk.bold(\"Project policy\")}\n ${chalk.blue('\"telemetry\": false')} in ${chalk.blue(\"rebase.json\")} disables sharing for everyone who\n clones the repository, overriding each developer's own choice.\n ${chalk.gray('\"telemetry\": true is ignored — a committed file cannot consent for others.')}\n\n${chalk.bold(\"Environment\")}\n ${chalk.blue(\"DO_NOT_TRACK\")} Set to disable, across every tool that honours it\n ${chalk.blue(\"REBASE_TELEMETRY_DISABLED\")} Set to disable Rebase specifically\n ${chalk.blue(\"REBASE_TELEMETRY_ENDPOINT\")} Send elsewhere — your own collector, for instance\n\n${chalk.gray(\"Never shared: project names, paths, collection or table names, database\")}\n${chalk.gray(\"URLs, hostnames, error messages, stack traces, or exact record counts.\")}\n`);\n}\n","/**\n * `rebase cloud` auth subcommands: login, logout, whoami.\n */\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport {\n resolveCloudUrl,\n resolveCloudTarget,\n isKnownControlPlane,\n isJsonMode,\n refuseDirectLink,\n parseCloudArgs,\n createCloudClient,\n requireClient,\n setCurrentContext,\n setContextOrg,\n getContextOrg,\n readLink,\n success,\n fail,\n keyValues,\n reportError,\n emit,\n note,\n noteBlank,\n warn,\n requireInteractive\n} from \"./context\";\n\n/**\n * Every flag `rebase cloud login` accepts.\n *\n * Hoisted out of the `arg` call so one declaration serves the parser,\n * `action-help.ts`'s page for this command, and the test that holds the two to\n * each other — the same arrangement `DEPLOY_FLAGS` and `CREATE_PROJECT_FLAGS`\n * already use.\n */\nexport const LOGIN_FLAGS = {\n \"--email\": String,\n \"--password\": String,\n \"-e\": \"--email\"\n} as const;\n\n/**\n * Where credentials may come from, in the order this command prefers them.\n *\n * The environment is the non-interactive route, and it exists so `--password`\n * does not have to be. A password written as an argument is in the shell's\n * history file and in the process table for as long as the command runs, and\n * neither is something this CLI can redact after the fact — the same reasoning\n * `rls-check` states for its connection string, which carries one too.\n *\n * There is no machine token yet, so CI genuinely does need a human's password;\n * `REBASE_CLOUD_PASSWORD` is how a secret store hands it over without it\n * appearing on a command line.\n */\nexport const PASSWORD_ENV = \"REBASE_CLOUD_PASSWORD\";\nexport const EMAIL_ENV = \"REBASE_CLOUD_EMAIL\";\n\n/**\n * Whether this line put a password in the shell's history.\n *\n * Exported for its test: the warning is the whole feature, so \"it warns exactly\n * when the flag was used\" is the thing worth pinning.\n */\nexport function passwordOnTheCommandLine(args: { \"--password\"?: string }): boolean {\n return typeof args[\"--password\"] === \"string\" && args[\"--password\"] !== \"\";\n}\n\nexport async function loginCommand(rawArgs: string[]): Promise<void> {\n // Strictly, through the family's own parser. `arg(…, { permissive: true })`\n // dropped an undeclared flag on the floor, so `rebase cloud login --emial\n // me@example.com` prompted for an email as though nothing had been typed.\n const { flags: args } = parseCloudArgs({\n spec: LOGIN_FLAGS,\n rawArgs,\n commandWords: 2, // cloud login\n command: \"cloud login\",\n maxPositionals: 0\n });\n // `login` builds its own client, so it does not pass through\n // `requireClient`'s guard — and it is the one command where getting this\n // wrong sends a password somewhere it should never go.\n refuseDirectLink(rawArgs);\n const { url, source } = resolveCloudTarget(rawArgs);\n if (source === \"link\" && !isKnownControlPlane(url)) await confirmLinkedControlPlane(url);\n\n noteBlank();\n note(`Signing in to ${chalk.cyan(url)}`);\n noteBlank();\n\n // Once, and before the request: by the time this succeeds the password is\n // already in the history file, and a warning after the fact is advice about\n // something that has happened.\n if (passwordOnTheCommandLine(args)) {\n warn(\n \"--password puts your password in your shell history and in the process table.\",\n `Prefer the prompt, or pass it as ${PASSWORD_ENV} from a secret store.`\n );\n }\n\n const envEmail = (process.env[EMAIL_ENV] ?? \"\").trim();\n const envPassword = process.env[PASSWORD_ENV] ?? \"\";\n\n // Collect any missing credentials interactively — but only where a terminal\n // can supply them. Piped, this used to hang on a password prompt.\n const needsEmail = !args[\"--email\"] && !envEmail;\n const needsPassword = !args[\"--password\"] && !envPassword;\n if (needsEmail || needsPassword) {\n requireInteractive(\"credentials\", `--email and --password, or ${EMAIL_ENV} and ${PASSWORD_ENV}`);\n }\n\n // The questions' real type, not `Record<string, unknown>`. Inquirer infers\n // the answer shape from the array it is given, so an array of open records\n // matches no overload — which is what the\n // `as unknown as Parameters<typeof inquirer.prompt>[0]` here was answering.\n // Naming the two question kinds this command asks makes the call check.\n const prompts: Array<\n | { type: \"input\"; name: string; message: string }\n | { type: \"password\"; name: string; message: string; mask: string }\n > = [];\n if (needsEmail) {\n prompts.push({ type: \"input\",\nname: \"email\",\nmessage: \"Email:\" });\n }\n if (needsPassword) {\n prompts.push({ type: \"password\",\nname: \"password\",\nmessage: \"Password:\",\nmask: \"•\" });\n }\n const answers = prompts.length\n ? await inquirer.prompt(prompts)\n : {};\n\n const email = (args[\"--email\"] || envEmail || (answers as { email?: string }).email || \"\").trim();\n const password = args[\"--password\"] || envPassword || (answers as { password?: string }).password || \"\";\n\n if (!email || !password) {\n fail(\"Email and password are required.\");\n }\n\n const client = createCloudClient(url);\n try {\n const { user } = await client.auth.signInWithEmail(email, password);\n setCurrentContext(url);\n\n // Convenience: if the account belongs to exactly one org, make it active.\n try {\n const orgs = await client.data.collection(\"organizations\").find({ limit: 2 });\n if (orgs.data.length === 1 && !getContextOrg(url)) {\n setContextOrg(url, String(orgs.data[0].id));\n }\n } catch {\n // non-fatal — org selection is optional\n }\n\n success(`Logged in as ${chalk.bold(user.email ?? email)}`);\n emit(\n () => {\n keyValues([\n [\"Host\", url],\n [\"User\", user.email ?? undefined],\n [\"Active org\", getContextOrg(url)]\n ]);\n console.log(\"\");\n },\n {\n success: true,\n host: url,\n user: user.email ?? null,\n activeOrg: getContextOrg(url) ?? null\n }\n );\n } catch (e) {\n // Auth failures are the common case — give a clean message, not a stack.\n const err = e as { status?: number; message?: string };\n if (err?.status === 401) {\n fail(\"Invalid email or password.\", undefined, \"invalid_credentials\");\n }\n reportError(e, \"Login failed\");\n }\n}\n\n/**\n * Ask before sending a password to a control plane a repository named.\n *\n * `.rebase/cloud.json` is committed with the code, so a cloned repository can\n * point its cloud commands at any host — and \"Not logged in to <host>\" invites\n * the login that would hand that host the user's email and password. A host\n * the user has signed in to before, or the platform's own, is theirs; any other\n * one is named and confirmed at a terminal, and refused without one: `--url`\n * is how a script says it means that host.\n */\nasync function confirmLinkedControlPlane(url: string): Promise<void> {\n const message = `This directory's .rebase/cloud.json names the control plane ${url}, which you have not signed in to before.`;\n if (isJsonMode() || process.stdin.isTTY !== true) {\n fail(\n message,\n `Your email and password would be sent there. To sign in to it on purpose, pass --url ${url}.`,\n \"unknown_control_plane\"\n );\n }\n warn(message, \"Your Rebase Cloud email and password will be sent to it.\");\n const { confirmed } = await inquirer.prompt([\n { type: \"confirm\", name: \"confirmed\", default: false, message: `Sign in to ${url}?` }\n ]);\n if (!confirmed) {\n console.error(chalk.gray(\" Aborted.\"));\n process.exit(0);\n }\n}\n\nexport async function logoutCommand(rawArgs: string[]): Promise<void> {\n // Only the globals, but parsed. `rebase cloud logout --frobnicate` exited 0\n // and signed the session out anyway — the one shape of this bug that also\n // destroys something.\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud logout\",\nmaxPositionals: 0 });\n const url = resolveCloudUrl(rawArgs);\n const client = createCloudClient(url);\n if (!client.auth.getSession()) {\n // Not an error: `logout` is idempotent and a script should be able to\n // run it unconditionally. `wasLoggedIn` is how a caller tells the two\n // outcomes apart without reading the prose.\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.gray(` Not logged in to ${url}.`));\n console.log(\"\");\n },\n { success: true,\nhost: url,\nwasLoggedIn: false }\n );\n return;\n }\n try {\n await client.auth.signOut();\n } catch {\n // signOut clears local state even if the network call fails\n }\n success(`Logged out of ${url}`);\n emit(() => {}, { success: true,\nhost: url,\nwasLoggedIn: true });\n}\n\nexport async function whoamiCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud whoami\",\nmaxPositionals: 0 });\n const { client, url } = await requireClient(rawArgs);\n try {\n const user = await client.auth.getUser();\n if (!user) {\n fail(\"Session is no longer valid.\", \"Run `rebase cloud login` again.\", \"session_invalid\");\n }\n const link = readLink();\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(\" 🔐 Rebase Cloud session\"));\n console.log(\"\");\n keyValues([\n [\"Host\", url],\n [\"User\", user.email ?? undefined],\n [\"User ID\", user.uid],\n [\"Roles\", user.roles?.length ? user.roles.join(\", \") : undefined],\n [\"Active org\", getContextOrg(url)],\n [\n \"Linked project\",\n link ? `${link.projectName ?? \"\"} (${link.projectId})`.trim() : undefined\n ]\n ]);\n console.log(\"\");\n },\n {\n host: url,\n user: {\n email: user.email ?? null,\n uid: user.uid,\n roles: user.roles ?? []\n },\n activeOrg: getContextOrg(url) ?? null,\n linkedProject: link\n ? { id: link.projectId,\nname: link.projectName ?? null,\nslug: link.slug ?? null }\n : null\n }\n );\n } catch (e) {\n reportError(e, \"Failed to fetch session\");\n }\n}\n","/**\n * `rebase cloud` context subcommands: link, unlink, use, open.\n *\n * `link` associates the current directory with a cloud project by writing\n * `.rebase/cloud.json`; deploy/logs/status then operate on it with no flags.\n */\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport {\n requireClient,\n resolveProjectRef,\n resolveCloudUrl,\n parseCloudArgs,\n writeLink,\n removeLink,\n readLink,\n projectLinkPath,\n setContextOrg,\n getContextOrg,\n openUrl,\n success,\n fail,\n reportError,\n emit,\n note,\n noteBlank,\n warn,\n requireInteractive,\n cloudRows\n} from \"./context\";\n\ninterface ProjectRow {\n id: string | number;\n name?: string;\n subdomain?: string;\n organization?: string | number;\n status?: string;\n}\n\n/**\n * Link this checkout straight at a running backend.\n *\n * No control plane, no authentication, no project id — just the URL of a Rebase\n * API. This is what makes the multi-repo workflow available to self-hosters: a\n * frontend repository links to `https://api.example.com` and then generates its\n * typed SDK from that project exactly as a cloud-linked repository would.\n *\n * The URL is verified before it is written. Recording an unreachable address and\n * failing later, in a different command, would be a worse experience than\n * failing here where the user can see what they typed.\n */\nasync function linkDirect(target: string, rawArgs: string[]): Promise<void> {\n let base: URL;\n try {\n base = new URL(target);\n } catch {\n fail(`\"${target}\" is not a valid URL.`, undefined, \"invalid_url\");\n return;\n }\n\n if (base.protocol !== \"http:\" && base.protocol !== \"https:\") {\n fail(\"A project URL must be http or https.\", undefined, \"invalid_url\");\n }\n\n const apiUrl = base.toString().replace(/\\/+$/, \"\");\n const probe = `${apiUrl}/api/meta/schema-version`;\n\n let reachable = false;\n let detail = \"\";\n try {\n const response = await fetch(probe, { headers: { accept: \"application/json\" } });\n reachable = response.ok;\n if (!response.ok) detail = `responded ${response.status}`;\n } catch (err) {\n detail = err instanceof Error ? err.message : String(err);\n }\n\n if (!reachable) {\n // A real warning, not narration: the link is being written against an\n // address that did not answer, and that is as worth saying when piped as\n // when watched. It used to be `console.log(chalk.yellow(…))` — a caution\n // rendered in warning colours on the results stream, which put it inside\n // whatever a caller was parsing.\n warn(\n `Could not reach ${probe}${detail ? ` (${detail})` : \"\"}.`,\n \"Linking anyway — the server may not be running yet. It must be a Rebase backend of version 0.11 or newer.\"\n );\n }\n\n writeLink({\n url: apiUrl,\n projectId: \"\",\n apiUrl,\n mode: \"direct\",\n projectName: base.host\n });\n\n success(`Linked to ${apiUrl}`);\n emit(\n () => {\n note(chalk.dim(`Written to ${projectLinkPath()}`));\n noteBlank();\n note(`Next: ${chalk.cyan(\"rebase generate-sdk --from link\")}`, \"\");\n },\n {\n success: true,\n mode: \"direct\",\n apiUrl,\n reachable,\n projectName: base.host,\n linkPath: projectLinkPath()\n }\n );\n void rawArgs;\n}\n\nexport async function linkCommand(rawArgs: string[]): Promise<void> {\n // `--project` is a global, so the spec is empty: declaring it here would\n // replace the global in the merge while the global's other readers went on\n // reading the raw line. Strict rather than permissive — a mistyped flag\n // used to be dropped, and `link` then opened the interactive picker as\n // though nothing had been asked for.\n const { flags: args, positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 2, // cloud link\n command: \"cloud link\",\n maxPositionals: 1 // [url]\n });\n\n // A positional URL means \"this exact backend\", which needs no login and no\n // control plane. `rebase cloud link https://api.example.com`\n const positional = positionals.find(value => /^https?:\\/\\//i.test(value));\n if (positional) {\n await linkDirect(positional, rawArgs);\n return;\n }\n\n const { client, url } = await requireClient(rawArgs);\n\n try {\n let project: ProjectRow | undefined;\n\n if (args[\"--project\"]) {\n const projectId = await resolveProjectRef(args[\"--project\"], client);\n project = (await client.data.collection(\"projects\").findById(projectId)) as ProjectRow | undefined;\n if (!project) {\n fail(`Project ${args[\"--project\"]} not found.`, undefined, \"project_not_found\");\n }\n } else {\n // The picker needs a terminal. Without this, `rebase cloud link`\n // run by an agent parked on a select prompt forever.\n requireInteractive(\"a project to link\", \"--project <slug>\");\n const org = getContextOrg(url);\n const projects = cloudRows<ProjectRow>((await client.data.collection(\"projects\").find({\n where: org ? { organization: [\"==\", org] } : undefined,\n limit: 100\n })).data);\n\n if (projects.length === 0) {\n fail(\n \"No projects found for your account.\",\n `Create one with ${chalk.bold(\"rebase cloud projects create\")}.`,\n \"no_projects\"\n );\n }\n\n const { picked } = await inquirer.prompt([\n {\n type: \"select\",\n name: \"picked\",\n message: \"Select a project to link:\",\n choices: projects.map((p) => ({\n name: `${p.name ?? \"(unnamed)\"} ${chalk.gray(String(p.subdomain ?? \"\"))}`,\n value: p\n }))\n }\n ] as Parameters<typeof inquirer.prompt>[0]);\n project = picked as ProjectRow;\n }\n\n if (!project) fail(\"No project selected.\", undefined, \"no_project\");\n\n const orgId = project.organization !== undefined ? String(project.organization) : undefined;\n writeLink({\n url,\n projectId: String(project.id),\n slug: project.subdomain,\n projectName: project.name,\n orgId\n });\n\n success(`Linked to ${chalk.bold(project.name ?? project.subdomain ?? \"\")}`);\n emit(\n () => {\n note(chalk.gray(`Wrote ${projectLinkPath()}`));\n noteBlank();\n },\n {\n success: true,\n mode: \"cloud\",\n host: url,\n projectId: String(project.id),\n slug: project.subdomain ?? null,\n projectName: project.name ?? null,\n org: orgId ?? null,\n linkPath: projectLinkPath()\n }\n );\n } catch (e) {\n reportError(e, \"Failed to link project\");\n }\n}\n\nexport function unlinkCommand(rawArgs: string[]): void {\n // It took no arguments at all, so `rebase cloud unlink --frobnicate`\n // removed the link and exited 0.\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud unlink\",\nmaxPositionals: 0 });\n const link = readLink();\n if (!link) {\n // Idempotent, like `logout`: `unlinked: false` is how a caller tells\n // \"there was nothing to remove\" from \"removed it\".\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.gray(\" This directory is not linked to a cloud project.\"));\n console.log(\"\");\n },\n { success: true,\nunlinked: false,\nlinkPath: projectLinkPath() }\n );\n return;\n }\n removeLink();\n success(\"Unlinked from cloud project\");\n emit(() => {}, { success: true,\nunlinked: true,\nlinkPath: projectLinkPath() });\n}\n\nexport async function selectOrgCommand(rawArgs: string[]): Promise<void> {\n // Was `rawArgs.slice(3).filter(a => !a.startsWith(\"-\"))[1]` — a hand-rolled\n // positional scan that skipped flag-shaped tokens and therefore accepted\n // any flag at all, including the value of one it did not declare.\n const { positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 2, // cloud use\n command: \"cloud use\",\n maxPositionals: 1 // [org]\n });\n const target = positionals[0];\n const { client, url } = await requireClient(rawArgs);\n\n try {\n const orgs = (await client.data.collection(\"organizations\").find({ limit: 100 })).data as Array<{\n id: string | number;\n name?: string;\n slug?: string;\n }>;\n\n if (orgs.length === 0) {\n fail(\"You are not a member of any organization.\", undefined, \"no_orgs\");\n }\n\n let chosen = target\n ? orgs.find((o) => String(o.id) === target || o.slug === target)\n : undefined;\n\n if (!chosen && !target) {\n requireInteractive(\"an organization\", \"rebase cloud use <org-id|slug>\");\n const { picked } = await inquirer.prompt([\n {\n type: \"select\",\n name: \"picked\",\n message: \"Select the active organization:\",\n choices: orgs.map((o) => ({\n name: `${o.name ?? \"(unnamed)\"} ${chalk.gray(`${o.slug ?? \"\"} · ${o.id}`)}`,\n value: o\n }))\n }\n ] as Parameters<typeof inquirer.prompt>[0]);\n chosen = picked;\n }\n\n if (!chosen) fail(`Organization \"${target}\" not found.`, undefined, \"org_not_found\");\n\n setContextOrg(url, String(chosen.id));\n success(`Active organization set to ${chalk.bold(chosen.name ?? chosen.id)}`);\n emit(() => {}, {\n success: true,\n host: url,\n org: { id: String(chosen.id),\nname: chosen.name ?? null,\nslug: chosen.slug ?? null }\n });\n } catch (e) {\n reportError(e, \"Failed to set organization\");\n }\n}\n\n/** Open the Rebase Cloud dashboard (or the linked project) in a browser. */\nexport function openCommand(rawArgs: string[]): void {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud open\",\nmaxPositionals: 0 });\n const url = resolveCloudUrl(rawArgs);\n const link = readLink();\n const target = link ? `${url}/projects/${link.projectId}` : url;\n openUrl(target);\n // The URL is the result. `openUrl` only narrates it (on stderr, and not at\n // all in JSON mode), so it has to be emitted here or a piped `cloud open`\n // produces nothing at all to act on.\n emit(() => {}, { url: target,\nprojectId: link?.projectId ?? null });\n}\n","import fs from \"fs\";\n/**\n * `rebase cloud` resource subcommands: status, metrics, webhooks, storage,\n * clusters, billing.\n */\nimport arg from \"arg\";\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n lookupProjectId,\n displayProjectRef,\n getContextOrg,\n readLink,\n colorStatus,\n emit,\n printGroupHelp,\n keyValues,\n fetchTenantBaseDomain,\n projectHost,\n openUrl,\n parseCloudArgs,\n requireKnownAction,\n success,\n fail,\n reportError,\n note,\n noteBlank,\n requireCloudRow,\n billingAccountIdOf\n} from \"./context\";\nimport { DEFAULT_STORAGE_SOURCE_KEY } from \"@rebasepro/types\";\nimport { firstRow, latestDeployment, fmtDate } from \"./projects\";\nimport { wantsRawError } from \"./errors\";\n\n/* ─── status: quick project dashboard ──────────────────────────── */\n\n/** The control plane's verdict on what a tenant's uploads actually do. */\ninterface StorageState {\n effective?: { kind?: string; summary?: string; storageType?: string; missing?: string[] };\n source?: string;\n configured?: string;\n overridden?: boolean;\n}\n\n/**\n * One line describing this project's storage — or `undefined` when the control\n * plane could not be asked, which prints as a blank rather than a guess.\n *\n * `status` used to render the `storages` row and nothing else, so a project\n * whose bucket is configured through its own `STORAGE_TYPE`/`S3_*` variables —\n * the supported path, and the one `mergeStorageEnv` deliberately lets WIN over\n * the row — was reported as `Storage: none` while its pod logged `Initialized\n * storage backends count: 1` against a live bucket. Storage is the thing an app\n * refuses to boot without, so that false negative sends someone off to\n * provision a bucket they already have. The row is not the answer; the tenant's\n * resolved environment is, and the control plane computes it with the same two\n * functions the build log uses.\n */\nexport function describeStorageState(state: StorageState | undefined): string | undefined {\n const verdict = state?.effective;\n if (!verdict?.kind) return undefined;\n const via = state?.overridden ? chalk.gray(\" · from env vars\") : \"\";\n switch (verdict.kind) {\n case \"durable\":\n return `${chalk.green(\"durable\")}${verdict.summary ? ` · ${verdict.summary}` : \"\"}${via}`;\n case \"ephemeral\":\n // Not \"none\": nothing is configured, so uploads land on the pod\n // filesystem and are lost at the next restart. That is a state, and\n // a bad one — saying \"none\" makes it sound merely unset.\n return `${chalk.yellow(\"ephemeral\")} ${chalk.gray(\"· uploads are lost on restart\")}`;\n case \"incomplete\":\n return `${chalk.red(\"incomplete\")} ${chalk.gray(`· missing ${(verdict.missing ?? []).join(\", \")}`)}`;\n case \"unrecognized\":\n return `${chalk.red(\"unrecognized\")} ${chalk.gray(`· STORAGE_TYPE=${verdict.storageType ?? \"?\"}`)}`;\n default:\n return undefined;\n }\n}\n\n/**\n * One line describing the database.\n *\n * `connectionStatus` is written `\"untested\"` at creation and only ever changed\n * by `rebase cloud db test`, so `managed (untested)` was reporting the absence\n * of a manual test as though it were the database's condition — on a project\n * that had just deployed against it. A never-tested database says only its\n * type; the verdict appears once there is one.\n */\nexport function describeDatabaseState(db: Record<string, unknown> | undefined): string | undefined {\n if (!db) return undefined;\n const type = typeof db.type === \"string\" ? db.type : \"database\";\n const connection = db.connectionStatus;\n if (connection === \"connected\" || connection === \"failed\") {\n return `${type} (${colorStatus(connection)})`;\n }\n return `${type} ${chalk.gray(\"· not tested (`rebase cloud db test`)\")}`;\n}\n\n/* ─── what a project is waiting for ────────────────────────────── */\n\n/**\n * The one thing standing between this project and a live URL, if anything is.\n *\n * `status` alone cannot answer that, and the gap is not cosmetic. A project\n * created through `projects create` is written `status: \"provisioning\"` and has\n * no database until one is attached — so the platform is not provisioning\n * anything, it is waiting for a second command that nothing in the output names.\n * \"Provisioning\" reads as *work in progress*, and the correct response to work\n * in progress is to wait. So the correct response to this state, for a person\n * and an agent alike, is the one thing that is guaranteed never to resolve it.\n *\n * That cost 43 minutes of polling on a first deploy, and an unattended agent\n * would still be polling: nothing about the state changes, ever, so there is no\n * timeout short enough to be wrong and no timeout long enough to be right.\n *\n * `blockedOn: null` is therefore load-bearing — it is the CLI saying \"waiting is\n * the correct thing to do here\", which is the only condition under which a\n * caller should poll. Everything else names a command.\n */\nexport interface BlockedState {\n /** A stable slug, or `null` when the platform genuinely is working. */\n blockedOn: string | null;\n /** The exact command that unblocks it. `null` when nothing is blocked. */\n nextAction: string | null;\n}\n\n/** Deployment states that mean the platform is still doing something. */\nconst IN_FLIGHT = new Set([\"deploying\", \"building\", \"pending\", \"queued\"]);\n\n/**\n * Did this deploy get past its build and die booting?\n *\n * Matched on the control plane's own sentence, which is text this project emits\n * (`awaitRolloutOrRollback`) rather than anything a customer's build can produce\n * — so it is a signal about our state machine, not a guess about a log. Being\n * wrong points a reader at the other log, which is recoverable; not answering at\n * all pointed everyone at the empty one.\n */\nfunction bootFailed(logs: string | null | undefined): boolean {\n return typeof logs === \"string\" && /did not become ready within/i.test(logs);\n}\n\nexport function resolveBlockedState(input: {\n projectStatus?: string | null;\n /** The project's database row, or undefined when none is attached. */\n database?: { connectionStatus?: string | null } | undefined;\n lastDeploy?: { status?: string | null; logs?: string | null } | undefined;\n}): BlockedState {\n // First, because it is the state that never resolves itself. A project\n // with no database cannot deploy, and no amount of waiting attaches one.\n //\n // Unless it already did. A project whose last deploy SUCCEEDED has a\n // database by definition — the deploy path provisions the managed stack and\n // the runtime ensures the schema at boot, neither of which can happen\n // without one. For a long time that path wrote no `databases` row, so this\n // branch fired on projects that were serving traffic: it reported\n // `blockedOn: no_database` beside `status: active`, and named `db create`\n // as the remedy — the one command that could provision a SECOND database\n // and repoint the app at it, away from the rows.\n //\n // So the absence of a row is only conclusive before anything has deployed.\n // Afterwards it describes the control plane's bookkeeping, not the project,\n // and `db create` must never be suggested for it.\n if (!input.database && input.lastDeploy?.status !== \"success\") {\n return {\n blockedOn: \"no_database\",\n nextAction: \"rebase cloud db create --type managed\"\n };\n }\n\n // A deploy in flight is the one case where waiting is right. Said\n // explicitly rather than by omission, so a caller can tell \"nothing to do\"\n // apart from \"this CLI has no opinion\".\n if (input.lastDeploy && IN_FLIGHT.has(String(input.lastDeploy.status))) {\n return { blockedOn: null,\nnextAction: null };\n }\n\n if (!input.lastDeploy) {\n return { blockedOn: \"never_deployed\",\nnextAction: \"rebase cloud deploy\" };\n }\n\n // A failed deploy is not a wait either: the project stays exactly as it is\n // until someone reads the log and deploys again. WHICH log is the whole\n // question, and `rebase cloud logs` is the build one.\n //\n // A readiness timeout means the build succeeded — the image was pushed and\n // the pod was started — and the process then died on boot. So the build log\n // this named is clean, and reads as a deploy that failed for no reason. The\n // reason is in the container's log, behind a flag nothing mentioned. Four\n // failures on one project were diagnosed that way, at five minutes each.\n if (input.lastDeploy.status && input.lastDeploy.status !== \"success\") {\n return {\n blockedOn: \"last_deploy_failed\",\n nextAction: bootFailed(input.lastDeploy.logs)\n ? \"rebase cloud logs --runtime\"\n : \"rebase cloud logs\"\n };\n }\n\n // A database that has been attached but never reached — the deploy\n // succeeded and the app cannot talk to its own store.\n if (input.database?.connectionStatus === \"failed\") {\n return { blockedOn: \"database_unreachable\",\nnextAction: \"rebase cloud db test\" };\n }\n\n return { blockedOn: null,\nnextAction: null };\n}\n\n/**\n * One line describing what engine is serving this project.\n *\n * Three numbers are in play and they are easy to conflate — I have watched it\n * happen. The **runtime version** (`1.2.0`) is the contract line a bundle's\n * range resolves against; its major IS the contract major. The **framework\n * version** (`0.11.0`) is the `@rebasepro` release the runtime image ships. They\n * move independently on purpose: tying the contract line to the framework would\n * make `^1` become `^0.11`, and pre-1.0 caret is restrictive, so every framework\n * minor would fall outside every project's range and force a rebuild to receive\n * an engine upgrade — the opposite of what the bundle/runtime split is for.\n *\n * So both are printed, rather than leaving anyone to infer one from a Docker tag.\n */\nexport function describeRuntime(project: {\n runtimeMode?: string | null;\n runtimeVersion?: string | null;\n runtimeFrameworkVersion?: string | null;\n runtimeVersionPin?: string | null;\n}): string {\n // Absent is a third state, not a synonym for custom. `runtime_mode` stopped\n // defaulting to `custom` in migration 0040, so a project that has never\n // deployed has no mode at all — and \"your own image\" about one of those\n // asserts a container that was never built. The first deploy decides.\n if (project.runtimeMode == null || project.runtimeMode.trim() === \"\") {\n return `not deployed yet ${chalk.gray(\"· the first deploy decides (`--bundle` keeps it managed)\")}`;\n }\n if (project.runtimeMode !== \"managed\") {\n return `custom ${chalk.gray(\"· your own image\")}`;\n }\n const version = project.runtimeVersion ?? \"unknown\";\n const framework = project.runtimeFrameworkVersion;\n const pin = project.runtimeVersionPin ? chalk.gray(` · pinned to ${project.runtimeVersionPin}`) : \"\";\n // \"image framework\", not \"framework\". This one is what the IMAGE ships (the\n // server half); `cloud deployments` reports what each BUNDLE installed (the\n // driver half). Two facts about the two sides of the boundary the intake\n // floor exists to police — and while both were printed as \"framework\n // version\", the only way to read them was as one number contradicting\n // itself, which is exactly how it was reported.\n //\n // Absent rather than guessed: a release whose image tag is not a semver\n // (a `latest`, a branch build) records no framework version, and inventing\n // one here would defeat the point of storing it.\n const frameworkPart = framework ? chalk.gray(` · image framework ${framework}`) : \"\";\n return `managed ${version}${frameworkPart}${pin}`;\n}\n\nexport async function statusCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud status\",\nmaxPositionals: 0 });\n const { client, url } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n try {\n const project = (await client.data.collection(\"projects\").findById(projectId)) as\n | {\n id: string | number; name?: string; subdomain?: string; host?: string; status?: string;\n gitBranch?: string; runtimeMode?: string | null; runtimeVersion?: string | null;\n runtimeFrameworkVersion?: string | null; runtimeContract?: number | null;\n runtimeRange?: string | null; runtimeVersionPin?: string | null;\n }\n | undefined;\n if (!project) fail(`Project ${displayProjectRef(rawArgs)} not found.`, undefined, \"not_found\");\n\n const [db, storage, deploy, baseDomain] = await Promise.all([\n firstRow(client, \"databases\", projectId),\n // A control plane that does not have this route yet, or a lookup\n // that fails, yields `undefined` — which prints as a blank. A blank\n // is a better answer than a wrong one for exactly this field.\n client.functions\n .invoke<StorageState>(\"storage-provision\", undefined, { method: \"GET\",\npath: projectId })\n .catch(() => undefined),\n latestDeployment(client, projectId),\n fetchTenantBaseDomain(client, url)\n ]);\n\n const storageLine = describeStorageState(storage);\n const databaseLine = describeDatabaseState(db);\n const blocked = resolveBlockedState({\n projectStatus: project.status,\n database: db as { connectionStatus?: string | null } | undefined,\n lastDeploy: deploy as { status?: string | null; logs?: string | null } | undefined\n });\n\n emit(\n () => {\n console.log(\"\");\n console.log(` ${chalk.bold(project.name ?? project.subdomain ?? \"\")} ${chalk.gray(`[${project.subdomain ?? displayProjectRef(rawArgs)}]`)} ${colorStatus(project.status)}`);\n console.log(\"\");\n keyValues([\n [\"URL\", projectHost(project, baseDomain)],\n [\"Branch\", project.gitBranch],\n [\"Last deploy\", deploy ? `${colorStatus(deploy.status)} · ${fmtDate(deploy.createdAt)}` : \"never\"],\n [\"Runtime\", describeRuntime(project)],\n [\"Database\", databaseLine],\n [\"Storage\", storageLine]\n ]);\n // The same fact the JSON carries, in the place a person reads.\n // Below the rows rather than inside them: it is not another\n // property of the project, it is what to do next.\n if (blocked.blockedOn) {\n console.log(\"\");\n console.log(` ${chalk.yellow(\"Waiting on you\")} ${chalk.gray(`— ${blocked.blockedOn}`)}`);\n console.log(` ${chalk.bold(blocked.nextAction ?? \"\")}`);\n }\n console.log(\"\");\n },\n {\n projectId: String(project.id),\n name: project.name ?? null,\n subdomain: project.subdomain ?? null,\n status: project.status ?? null,\n // Siblings of `status` on purpose: a caller reading `status`\n // has to read these to know what it means. `blockedOn: null` is\n // the only value under which polling `status` is correct.\n blockedOn: blocked.blockedOn,\n nextAction: blocked.nextAction,\n url: projectHost(project, baseDomain) ?? null,\n branch: project.gitBranch ?? null,\n lastDeploy: deploy ? { id: String(deploy.id),\nstatus: deploy.status ?? null,\ncreatedAt: deploy.createdAt ?? null } : null,\n runtime: {\n mode: project.runtimeMode ?? \"custom\",\n version: project.runtimeVersion ?? null,\n // `imageFrameworkVersion`, not `frameworkVersion`: this is\n // the framework the IMAGE ships, while a row from\n // `cloud deployments` carries `builtAgainst`, the framework\n // that BUNDLE installed. They are routinely different (the\n // image supplies the server, the bundle supplies the\n // driver) and were both called `frameworkVersion`, so the\n // two commands read as the control plane contradicting\n // itself about one number.\n imageFrameworkVersion: project.runtimeFrameworkVersion ?? null,\n contract: project.runtimeContract ?? null,\n range: project.runtimeRange ?? null,\n pin: project.runtimeVersionPin ?? null\n },\n database: db ? { type: db.type ?? null,\nconnectionStatus: db.connectionStatus ?? null } : null,\n storage: storage ?? null\n }\n );\n } catch (e) {\n reportError(e, \"Failed to load status\");\n }\n}\n\n/* ─── metrics: live compute metrics ────────────────────────────── */\n\n/** What `/api/functions/metrics/:projectId` returns. Mirrors saas metrics.ts. */\ninterface TenantMetrics {\n status?: string;\n cpu?: string;\n memory?: string;\n memoryPercent?: string;\n disk?: string | null;\n /** What the figures are OF — a project is not one machine. */\n subject?: { workload?: string; kind?: string; sampledInstances?: number } | null;\n /** The ceiling the percentages are measured against, per instance. */\n allocation?: {\n cpuLimitMillicores?: number | null;\n memoryLimitBytes?: number | null;\n cpuRequestMillicores?: number | null;\n memoryRequestBytes?: number | null;\n } | null;\n instances?: {\n name?: string;\n phase?: string;\n ready?: boolean;\n restarts?: number;\n cpuMillicores?: number | null;\n memoryBytes?: number | null;\n /** Why the previous container died. The whole story of a crashloop. */\n lastTerminationReason?: string | null;\n lastTerminationExitCode?: number | null;\n /** Why it has not started yet — ImagePullBackOff, CreateContainerError. */\n waitingReason?: string | null;\n }[] | null;\n condition?: { reason?: string; message?: string } | null;\n}\n\n/**\n * CPU with the ceiling it is a percentage of.\n *\n * A bare \"0.2%\" is unreadable without knowing 0.2% of what, and on a burstable\n * pod the answer is not obvious: these request 250m and may burst to 2 vCPU, so\n * a pod at 40% of its LIMIT is at over three times its guaranteed share and may\n * still be throttled. Naming both is the difference between a number and a\n * number that means something.\n */\nfunction cpuLine(m: TenantMetrics): string | undefined {\n if (!m.cpu) return undefined;\n const limit = m.allocation?.cpuLimitMillicores;\n const request = m.allocation?.cpuRequestMillicores;\n if (limit == null && request == null) return m.cpu;\n const parts = [\n request != null ? `${request}m guaranteed` : null,\n limit != null ? `bursts to ${limit}m` : null\n ].filter(Boolean).join(\", \");\n return `${m.cpu} ${chalk.gray(`(${parts}, per instance)`)}`;\n}\n\nexport async function metricsCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 2,\ncommand: \"cloud metrics\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n try {\n const m = await client.functions.invoke<TenantMetrics>(\n \"metrics\", undefined, { method: \"GET\", path: projectId }\n );\n\n // What the numbers are OF. The endpoint has reported this since it\n // learned to, and this command threw it away — printing bare\n // \"CPU / Memory\" over figures that only ever cover the backend\n // Deployment. A reader had every reason to think the database was in\n // them; `metrics.ts` says in its own comment that it is not.\n const of = m.subject?.workload\n ? `${m.subject.workload}${m.subject.kind === \"deployment\" ? \" (backend only — not the database)\" : \"\"}`\n : undefined;\n\n // Sampled, not desired. A pod that has not reported to metrics-server\n // yet is absent from the sum, so \"89 MiB\" across one instance of two is\n // half a picture and should say so.\n const sampled = m.subject?.sampledInstances;\n const coverage = sampled === undefined\n ? undefined\n : sampled === 0\n ? chalk.yellow(\"no instances reported yet\")\n : `${sampled} instance${sampled === 1 ? \"\" : \"s\"}`;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 📊 Metrics — project ${displayProjectRef(rawArgs)}`));\n console.log(\"\");\n keyValues([\n [\"Status\", m.status ? colorStatus(m.status === \"running\" ? \"active\" : m.status) : undefined],\n [\"Measuring\", of],\n [\"Sampled\", coverage],\n [\"CPU\", cpuLine(m)],\n [\"Memory\", m.memory ? `${m.memory}${m.memoryPercent ? ` (${m.memoryPercent})` : \"\"}` : undefined],\n [\"Disk\", m.disk]\n ]);\n\n // Why it is unhealthy, when it is. Straight from the workload's\n // own conditions — the endpoint does not interpret it and\n // neither does this.\n if (m.condition) {\n console.log(\"\");\n console.error(chalk.red(` ✗ ${m.condition.reason ?? \"Not healthy\"}`));\n if (m.condition.message) note(` ${m.condition.message}`);\n }\n\n // Per instance, because an average hides the pod that is hot.\n if (m.instances?.length) {\n console.log(\"\");\n note(\" Instances\");\n for (const i of m.instances) {\n const cpu = i.cpuMillicores != null ? `${Math.round(i.cpuMillicores)}m` : \"—\";\n const mem = i.memoryBytes != null ? `${(i.memoryBytes / 1024 / 1024).toFixed(0)} MiB` : \"—\";\n const health = i.ready === false ? chalk.yellow(\" not ready\") : \"\";\n // Restarts are the first thing anyone wants when a\n // tenant is misbehaving, and a silent 0 is noise — so it\n // only appears when there are any.\n const restarts = i.restarts ? chalk.yellow(` ${i.restarts}×restarted`) : \"\";\n note(` ${(i.name ?? \"?\").padEnd(34)} ${cpu.padStart(6)} ${mem.padStart(9)}${health}${restarts}`);\n // Why the last one died, when one did. This is the line\n // that turns \"it keeps restarting\" into a diagnosis, and\n // it was being fetched and discarded.\n if (i.lastTerminationReason) {\n note(chalk.gray(\n ` last exit: ${i.lastTerminationReason}` +\n (i.lastTerminationExitCode != null ? ` (code ${i.lastTerminationExitCode})` : \"\")\n ));\n }\n if (i.waitingReason) note(chalk.gray(` waiting: ${i.waitingReason}`));\n }\n }\n console.log(\"\");\n },\n {\n projectId,\n status: m.status ?? null,\n cpu: m.cpu ?? null,\n memory: m.memory ?? null,\n memoryPercent: m.memoryPercent ?? null,\n disk: m.disk ?? null,\n // Passed through rather than reshaped: a script that wants the\n // ceiling to compute its own percentage should get the same\n // numbers the server sent.\n subject: m.subject ?? null,\n allocation: m.allocation ?? null,\n instances: m.instances ?? null,\n condition: m.condition ?? null\n }\n );\n } catch (e) {\n reportError(e, \"Failed to fetch metrics\");\n }\n}\n\n/* ─── webhooks ─────────────────────────────────────────────────── */\n\n/**\n * The webhook `webhooks delete` names.\n *\n * The worst instance of the operand-filter bug in this family, because the\n * argument is consumed by a DELETE and the wrong value looks entirely\n * plausible: `rebase cloud webhooks delete --project acme 42` filtered out\n * `--project` and kept \"acme\", so the id it deleted was the project slug rather\n * than the 42 the caller wrote. Strict parsing consumes the flag with its\n * value, leaving `[\"42\"]`.\n *\n * Exported so its tests drive the real parser.\n */\nexport function resolveWebhookIdArg(rawArgs: string[]): string | undefined {\n return parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud webhooks delete\n command: \"cloud webhooks delete\",\n maxPositionals: 1\n }).positionals[0];\n}\n\n/** The action words `rebase cloud webhooks` dispatches. No word means `list`. */\nexport const WEBHOOKS_ACTIONS = [\"list\", \"create\", \"delete\"] as const;\n\nexport async function webhooksCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // Before the parse and before the client: `webhooks creat` used to fall past\n // both `if`s and LIST the webhooks, exit 0, and leave the caller believing\n // one had been created.\n requireKnownAction(\"webhooks\", subcommand, WEBHOOKS_ACTIONS);\n\n // Both lines are parsed BEFORE the client is built. A line the parser will\n // refuse is refused without first spending a login round-trip on it — and\n // for `delete`, without the ambiguity of a refusal that arrives after the\n // command has already started talking to the control plane.\n const create = subcommand === \"create\"\n ? parseCloudArgs({\n // `--endpoint`, not `--url`.\n //\n // Every command in this family inherits a global `--url`, which\n // names the CONTROL PLANE — `resolveCloudUrl` reads it straight off\n // the raw line, before any per-command spec exists. A second\n // `--url` here did not shadow it, because the two parses are\n // independent: `webhooks create --url https://example.com/hook`\n // sent the customer's webhook endpoint to `requireClient` as the\n // control plane to authenticate against, so the documented example\n // could not create a webhook. Renaming is the fix; a per-command\n // flag cannot be a global's spelling, and `action-help.test.ts`\n // now sweeps for the class.\n spec: { \"--name\": String,\n\"--table\": String,\n\"--endpoint\": String,\n\"--events\": String },\n rawArgs,\n commandWords: 3, // cloud webhooks create\n command: \"cloud webhooks create\",\n maxPositionals: 0\n }).flags\n : undefined;\n const deleteId = subcommand === \"delete\" ? resolveWebhookIdArg(rawArgs) : undefined;\n if (subcommand === \"delete\" && !deleteId) {\n fail(\"Usage: rebase cloud webhooks delete <id>\", undefined, \"usage\");\n }\n // The listing takes only the globals, and took them permissively: `webhooks\n // list --tabel orders` listed every webhook and exited 0.\n if (!create && !deleteId) {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud webhooks\",\nmaxPositionals: 0 });\n }\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n try {\n if (subcommand === \"create\") {\n const args = create!;\n const name = args[\"--name\"] || fail(\"--name is required.\", undefined, \"usage\");\n const table = args[\"--table\"] || fail(\"--table is required.\", undefined, \"usage\");\n const url = args[\"--endpoint\"] || fail(\"--endpoint is required.\", \"Where the POST goes.\", \"usage\");\n const events = (args[\"--events\"] || \"insert,update,delete\").split(\",\").map((s) => s.trim());\n\n const created = requireCloudRow(await client.data.collection(\"webhooks\").create({\n project: projectId,\n name,\n table,\n url,\n events,\n enabled: true\n }), \"webhook\");\n success(`Created webhook ${chalk.bold(name)} [${created.id}]`);\n emit(() => {}, {\n success: true,\n id: String(created.id),\n projectId,\n name,\n table,\n url,\n events,\n enabled: true\n });\n return;\n }\n\n if (subcommand === \"delete\") {\n await client.data.collection(\"webhooks\").delete(deleteId!);\n success(`Deleted webhook ${deleteId}`);\n emit(() => {}, { success: true,\nid: deleteId!,\nprojectId });\n return;\n }\n\n // list\n const hooks = (await client.data.collection(\"webhooks\").find({\n where: { project: [\"==\", projectId] },\n limit: 100\n })).data as Array<{ id: string | number; name?: string; table?: string; url?: string; enabled?: boolean; events?: string[] }>;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🔗 Webhooks — project ${displayProjectRef(rawArgs)}`));\n console.log(\"\");\n if (hooks.length === 0) {\n console.log(chalk.gray(\" No webhooks. Add one with `rebase cloud webhooks create`.\"));\n console.log(\"\");\n return;\n }\n for (const h of hooks) {\n const state = h.enabled ? chalk.green(\"enabled\") : chalk.gray(\"disabled\");\n console.log(` ${chalk.bold(h.name ?? \"(unnamed)\")} ${chalk.gray(`[${h.id}]`)} ${state}`);\n console.log(` ${chalk.gray(`${h.table ?? \"?\"} → ${h.url ?? \"?\"} (${(h.events ?? []).join(\", \")})`)}`);\n }\n console.log(\"\");\n },\n {\n projectId,\n webhooks: hooks.map((h) => ({\n id: String(h.id),\n name: h.name ?? null,\n table: h.table ?? null,\n url: h.url ?? null,\n events: h.events ?? [],\n enabled: h.enabled ?? null\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Webhook operation failed\");\n }\n}\n\n/* ─── storage ──────────────────────────────────────────────────── */\n\n/** The action words `rebase cloud storage` dispatches. No word means `list`. */\nexport const STORAGE_ACTIONS = [\"list\", \"create\", \"attach\"] as const;\n\nexport async function storageCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n // `rebase cloud storage` used to only ever list. A tenant could therefore\n // reach durable storage only by creating a bucket by hand in a cloud\n // console, minting credentials, and pasting them into the web UI — and\n // until they did, the project simply had no file storage. These make it a\n // thing the platform can do for you.\n //\n // `action` is the positional the dispatcher already resolved, as for every\n // other resource group. Re-deriving it here by index was wrong — the group\n // sits at rawArgs[3], so rawArgs[2] is always the literal \"cloud\" and no\n // subcommand ever matched.\n if (action === \"create\") return storageCreateCommand(rawArgs);\n if (action === \"attach\") return storageAttachCommand(rawArgs);\n if (action === \"help\") return printStorageHelp();\n // Everything that is not one of those, and is not `list` or nothing, is a\n // typo — and used to LIST, exit 0, and read as a bucket that was created.\n requireKnownAction(\"storage\", action, STORAGE_ACTIONS);\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud storage\",\nmaxPositionals: 0 });\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n try {\n const stores = (await client.data.collection(\"storages\").find({\n where: { project: [\"==\", projectId] },\n limit: 50\n })).data as Array<{\n id: string | number;\n sourceKey?: string;\n type?: string;\n provider?: string;\n bucketName?: string;\n s3Bucket?: string;\n status?: string;\n }>;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🪣 Storage — project ${displayProjectRef(rawArgs)}`));\n console.log(\"\");\n if (stores.length === 0) {\n console.log(chalk.gray(\" No storage buckets attached.\"));\n console.log(\"\");\n return;\n }\n for (const s of stores) {\n // `bucketName` is written by managed provisioning only, so\n // a bucket attached from the console or by `attach` listed\n // as \"byos\" — the type, printed where the name goes. The\n // name the tenant actually reads is `s3Bucket`.\n const name = s.bucketName || s.s3Bucket || \"(no bucket)\";\n const key = s.sourceKey || DEFAULT_STORAGE_SOURCE_KEY;\n console.log(` ${chalk.bold(name)} ${chalk.gray(`[${s.id}]`)} ${colorStatus(s.status)}`);\n keyValues([[\"Source\", key], [\"Provider\", s.provider], [\"Type\", s.type]]);\n }\n console.log(\"\");\n },\n {\n projectId,\n stores: stores.map((s) => ({\n id: String(s.id),\n sourceKey: s.sourceKey || DEFAULT_STORAGE_SOURCE_KEY,\n bucketName: s.bucketName || s.s3Bucket || null,\n type: s.type ?? null,\n provider: s.provider ?? null,\n status: s.status ?? null\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list storage\");\n }\n}\n\nexport function printStorageHelp(): void {\n printGroupHelp({\n command: \"cloud storage\",\n title: \"The project's object storage\",\n actions: [\n { action: \"list\",\ndescription: \"The buckets this project has, and their state\" },\n { action: \"create\",\ndescription: \"Provision platform-managed storage. Takes no options\" },\n {\n action: \"attach\",\n description: \"Attach your own S3-compatible bucket\",\n flags: [\n [\"--bucket <name>\", \"Bucket name. Required\"],\n [\"--access-key-id <id>\", \"Access key ID. Required\"],\n [\"--secret-access-key <s>\", \"Secret access key. Required\"],\n [\"--endpoint <url>\", \"S3 endpoint. Omit for AWS\"],\n [\"--region <region>\", \"Region\"],\n [\"--force-path-style\", \"Required by MinIO and some gateways\"],\n [\"--source <key>\", \"Which declared bucket. Default: the default one\"]\n ]\n }\n ],\n notes: [\n \"Without either, file storage stays off: uploads are refused with 501\",\n \"STORAGE_NOT_CONFIGURED rather than written to a container filesystem that is\",\n \"erased on the next restart.\",\n \"Redeploy after `attach` for the tenant to pick the credentials up.\"\n ]\n });\n}\n\n/* ─── storage create: platform-managed ─────────────────────────── */\n\nasync function storageCreateCommand(rawArgs: string[]): Promise<void> {\n // Takes no options of its own, and provisions billable infrastructure: an\n // unrecognised flag here (`storage create --region eu`, borrowed from\n // `attach`) provisioned in the default region and said nothing.\n parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud storage create\n command: \"cloud storage create\",\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n try {\n noteBlank();\n note(chalk.gray(\"Provisioning managed storage — this creates a bucket and its credentials...\"));\n\n const res = await client.functions.invoke<{\n data: { bucketName: string; region: string; endpoint: string; accessKeyId: string };\n // The project id is a SUB-PATH, not part of the function name.\n // `invoke` runs `encodeURIComponent` over the name — correct, since\n // a function name is one path segment — so folding the id into it\n // sent `POST /api/functions/storage-provision%2F<id>`, which matches\n // no route. The control plane answered a bare 404 and\n // `rebase cloud storage create` read as an unimplemented feature for\n // six weeks. `invoke` now refuses a name containing `/` outright.\n }>(\"storage-provision\", undefined, { method: \"POST\", path: projectId });\n\n // `res.data`, once. What stood here was\n // `(res as unknown as { data?: typeof res.data }).data ?? res.data` —\n // both halves read the same property off the same object, so the `??`\n // could never reach its right-hand side. The cast made it look like a\n // fallback between two response shapes by making `data` optional on one\n // of them; `invoke<T>` returns `T`, and `T` here declares `data`.\n const info = res.data;\n\n success(`Managed storage provisioned for ${displayProjectRef(rawArgs)}.`);\n emit(\n () => {\n keyValues([\n [\"Bucket\", info.bucketName],\n [\"Region\", info.region],\n [\"Endpoint\", info.endpoint],\n [\"Access key\", info.accessKeyId]\n ]);\n noteBlank();\n // The secret is never returned by the endpoint — it goes to the\n // row and to the tenant's environment. Say so, or the absence\n // reads as a bug.\n note(chalk.gray(\"The secret key is stored encrypted and injected at deploy time; it is not displayed.\"));\n note(chalk.gray(\"Redeploy for the tenant to pick it up: \") + chalk.bold(\"rebase cloud deploy\"));\n noteBlank();\n },\n {\n success: true,\n projectId,\n bucketName: info.bucketName,\n region: info.region,\n endpoint: info.endpoint,\n accessKeyId: info.accessKeyId,\n // Stated, not omitted: a caller that finds no secret in the\n // payload should know it was withheld, not lost.\n secretAccessKey: null,\n pendingRedeploy: true\n }\n );\n } catch (e) {\n reportError(e, \"Failed to provision managed storage\");\n }\n}\n\n/* ─── storage attach: bring your own ───────────────────────────── */\n\nasync function storageAttachCommand(rawArgs: string[]): Promise<void> {\n // Strict: every value here is credentials or the bucket they open, and the\n // permissive parse turned a mistyped `--acces-key-id` into the \"missing\n // --access-key-id\" refusal below — the right refusal for the wrong reason,\n // and one that says nothing about the flag that was actually wrong.\n const { flags: parsed } = parseCloudArgs({\n spec: {\n \"--bucket\": String,\n \"--access-key-id\": String,\n \"--secret-access-key\": String,\n \"--endpoint\": String,\n \"--region\": String,\n \"--force-path-style\": Boolean,\n // Which declared bucket this configures. A project has one row per\n // source, and without this the command took `limit: 1` off an\n // unordered find and updated whichever row came back — so\n // attaching a bucket to a two-bucket project could overwrite\n // `media`'s credentials while reporting success.\n \"--source\": String\n },\n rawArgs,\n commandWords: 3, // cloud storage attach\n command: \"cloud storage attach\",\n maxPositionals: 0\n });\n\n const bucket = parsed[\"--bucket\"];\n const accessKeyId = parsed[\"--access-key-id\"];\n const secretAccessKey = parsed[\"--secret-access-key\"];\n\n // All three or none. A bucket carrying no credentials is the state that\n // reads as configured in the console and fails on the first upload.\n const missing = [\n !bucket && \"--bucket\",\n !accessKeyId && \"--access-key-id\",\n !secretAccessKey && \"--secret-access-key\"\n ].filter(Boolean) as string[];\n if (missing.length > 0) {\n fail(\n `Missing ${missing.join(\", \")}.`,\n \"A bucket without credentials cannot be used, and would be stored as though it could. \" +\n \"Run `rebase cloud storage --help` for the full list.\",\n \"usage\"\n );\n }\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n const sourceKey = (parsed[\"--source\"] ?? \"\").trim() || DEFAULT_STORAGE_SOURCE_KEY;\n\n try {\n const existing = (await client.data.collection(\"storages\").find({\n where: { project: [\"==\", projectId] },\n limit: 50\n })).data.find((r) => {\n const key = (r as { sourceKey?: unknown }).sourceKey;\n return (typeof key === \"string\" && key ? key : DEFAULT_STORAGE_SOURCE_KEY) === sourceKey;\n }) as { id?: string | number } | undefined;\n\n const row: Record<string, unknown> = {\n project: projectId,\n // Written, not left to the column default: a row that does not say\n // which source it configures is a row the console and the deploy\n // path both have to guess about.\n sourceKey,\n type: \"byos\",\n status: \"active\",\n s3Bucket: bucket,\n s3AccessKeyId: accessKeyId,\n s3SecretAccessKey: secretAccessKey,\n bucketName: bucket\n };\n if (parsed[\"--endpoint\"]) row.s3Endpoint = parsed[\"--endpoint\"];\n if (parsed[\"--region\"]) {\n row.s3Region = parsed[\"--region\"];\n row.region = parsed[\"--region\"];\n }\n // Only when set: AWS rejects path style, so an unconditional false\n // would be noise in every project that does not need it.\n if (parsed[\"--force-path-style\"]) row.s3ForcePathStyle = true;\n\n const replaced = Boolean(existing?.id);\n if (existing?.id) {\n await client.data.collection(\"storages\").update(String(existing.id), row);\n } else {\n await client.data.collection(\"storages\").create(row);\n }\n\n success(`Storage attached to ${displayProjectRef(rawArgs)}.`);\n emit(\n () => {\n keyValues([\n [\"Bucket\", bucket],\n [\"Endpoint\", parsed[\"--endpoint\"] ?? \"AWS S3\"],\n [\"Region\", parsed[\"--region\"] ?? \"(default)\"]\n ]);\n noteBlank();\n note(chalk.gray(\"Redeploy for the tenant to pick it up: \") + chalk.bold(\"rebase cloud deploy\"));\n noteBlank();\n },\n {\n success: true,\n projectId,\n bucket,\n endpoint: parsed[\"--endpoint\"] ?? null,\n region: parsed[\"--region\"] ?? null,\n forcePathStyle: Boolean(parsed[\"--force-path-style\"]),\n // The one fact the human rendering does not carry: `attach` over\n // an existing row is an overwrite, and a caller re-running it in\n // a script should be able to tell that it replaced something.\n replaced,\n pendingRedeploy: true\n }\n );\n } catch (e) {\n reportError(e, \"Failed to attach storage\");\n }\n}\n\n/* ─── clusters ─────────────────────────────────────────────────── */\n\n/** The action words `rebase cloud clusters` dispatches. No word means `list`. */\nexport const CLUSTERS_ACTIONS = [\"list\", \"add\", \"verify\"] as const;\n\n/**\n * `rebase cloud clusters` — list, register and verify the clusters tenants run on.\n *\n * Registration is deliberately an operator action: the `clusters` collection is\n * admin-only, and a cluster record carries a credential with enough power to\n * create namespaces and read every secret in them. A self-serve \"bring your own\n * cluster\" flow is a different feature with a different threat model.\n */\nexport async function clustersCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n if (action === \"verify\") return clustersVerifyCommand(rawArgs);\n if (action === \"add\") return clustersAddCommand(rawArgs);\n // `clusters verifyy` used to LIST the clusters and exit 0 — the one command\n // whose whole purpose is to answer a yes/no question about a specific one.\n requireKnownAction(\"clusters\", action, CLUSTERS_ACTIONS);\n return clustersListCommand(rawArgs);\n}\n\n/**\n * Ask a registered cluster whether it can actually host a tenant.\n *\n * The question this exists to answer early is the one that otherwise gets\n * answered by a customer's first deploy failing halfway through provisioning,\n * with an error they cannot act on and half a tenant already created.\n */\n/**\n * Which cluster `clusters verify` was asked about, and whether `--baseline`\n * was given.\n *\n * Resolved against a real spec, not scanned out of `rawArgs` by hand — and this\n * is not a tidy-up. `rawArgs` is the whole `process.argv`, so the old scan\n * (\"the first token that is not `--…` and is neither `clusters` nor `verify`\")\n * matched `argv[0]`, the **node binary path**. Every `rebase cloud clusters\n * verify <id>` therefore asked the control plane about a cluster called\n * `/usr/local/bin/node`, and came back 404.\n *\n * So the one diagnostic that reports `permissions.allowed` /\n * `permissions.denied` was unreachable, and its 404 read as \"this command is\n * not deployed yet\" rather than \"the id never left this machine intact\". It is\n * the command that names a missing `cronjobs.batch` grant in a single call\n * instead of a twenty-minute A/B against a live project.\n *\n * Same failure as `cloud deploy` reading `_[0]` as `\"cloud\"`, and the same fix:\n * one parser, exported so its test drives the real thing rather than a copy.\n */\nexport function resolveClusterVerifyArgs(rawArgs: string[]): { id?: string; baseline: boolean } {\n const { flags, positionals } = parseCloudArgs({\n spec: { \"--baseline\": Boolean },\n rawArgs,\n commandWords: 2, // cloud clusters — `verify` is the action positional\n command: \"cloud clusters verify\",\n maxPositionals: 2\n });\n return { id: positionals[1],\nbaseline: flags[\"--baseline\"] === true };\n}\n\nasync function clustersVerifyCommand(rawArgs: string[]): Promise<void> {\n const { id, baseline: withBaseline } = resolveClusterVerifyArgs(rawArgs);\n if (!id) fail(\"Usage: rebase cloud clusters verify <cluster-id> [--baseline]\", undefined, \"bad_request\");\n\n // Parsed before authenticating: a usage error is answerable without a\n // session, and asking for one first turns \"you forgot the id\" into \"log in\".\n const { client } = await requireClient(rawArgs);\n\n let report: {\n reachable: boolean; version?: string; unreachableReason?: string;\n permissions: { allowed: string[]; denied: { permission: string; consequence: string }[];\n unknown: { permission: string; error: string }[] };\n verdict: \"ready\" | \"degraded\" | \"unusable\"; blockers: string[];\n };\n try {\n report = await client.functions.invoke(\"cluster-baseline\", undefined, {\n method: \"GET\",\n // Encoded: the id is user input landing in a URL path, and `path`\n // is appended verbatim by the SDK (only the *function name* is\n // encoded for it).\n path: `verify/${encodeURIComponent(id)}${withBaseline ? \"?baseline=1\" : \"\"}`\n }) as never;\n } catch (error: unknown) {\n reportError(error, \"Could not verify the cluster\");\n return;\n }\n\n emit(\n () => {\n console.log(\"\");\n const tone = report.verdict === \"ready\" ? chalk.green\n : report.verdict === \"degraded\" ? chalk.yellow : chalk.red;\n console.log(` ${tone(chalk.bold(report.verdict.toUpperCase()))} ${chalk.gray(String(id))}`);\n console.log(\"\");\n keyValues([\n [\"Reachable\", report.reachable ? \"yes\" : chalk.red(\"no\")],\n [\"Permissions\", `${report.permissions.allowed.length} allowed, ${report.permissions.denied.length} denied`]\n ]);\n if (report.blockers.length > 0) {\n console.log(\"\");\n // Each blocker already says what breaks, so they are printed\n // whole rather than summarised into a count.\n for (const b of report.blockers) console.log(` ${chalk.red(\"✗\")} ${b}`);\n }\n console.log(\"\");\n if (!withBaseline && report.verdict !== \"unusable\") {\n note(\"Add --baseline to also check ingress-nginx, cert-manager and CloudNativePG.\");\n console.log(\"\");\n }\n },\n report\n );\n\n // Non-zero so this is usable as a gate in a script or a runbook step.\n if (report.verdict === \"unusable\") process.exitCode = 1;\n}\n\n/**\n * Register a cluster from a kubeconfig file.\n *\n * Verifies immediately rather than reporting a successful insert: a row that\n * names an unreachable cluster is worse than no row, because a project pointed\n * at it fails at deploy instead of at registration.\n */\n/** The columns a `clusters` row is registered with. Exported for its test. */\nexport interface ClusterAddArgs {\n name: string;\n provider: \"gcp\" | \"aws\" | \"hetzner\";\n region: string;\n kubeconfigPath: string;\n baseDomain?: string;\n ingressAddress?: string;\n /** This is capacity we operate: projects placed in its region deploy here. */\n platformCapacity: boolean;\n backupBucket?: string;\n backupEndpoint?: string;\n backupAccessKeyId?: string;\n backupSecretAccessKey?: string;\n}\n\n/**\n * What `clusters add` was asked to register.\n *\n * Everything a row needs to serve tenants is settable HERE, at insert, because\n * the control plane installs the cluster baseline on insert and reads the row\n * to do it: the name is what the Hetzner load balancer is adopted by, the\n * address is what the ingress is pinned to. Registering with the four\n * required flags and patching the rest afterwards would install a baseline\n * that knew neither.\n *\n * The backup fields travel together: a bucket with no key, or a key with no\n * bucket, is a row `resolveBackupStore` deliberately treats as \"no store\" —\n * so it is refused here, where the operator can still fix the command.\n */\nexport function resolveClusterAddArgs(rawArgs: string[]): ClusterAddArgs {\n const { flags } = parseCloudArgs({\n spec: {\n \"--name\": String,\n \"--provider\": String,\n \"--region\": String,\n \"--kubeconfig\": String,\n \"--base-domain\": String,\n \"--ingress-address\": String,\n \"--platform-capacity\": Boolean,\n \"--backup-bucket\": String,\n \"--backup-endpoint\": String,\n \"--backup-access-key-id\": String,\n \"--backup-secret-access-key\": String\n },\n rawArgs,\n commandWords: 2, // cloud clusters — `add` is the action positional\n command: \"cloud clusters add\",\n maxPositionals: 1\n });\n\n const name = flags[\"--name\"];\n const provider = flags[\"--provider\"];\n const region = flags[\"--region\"];\n const kubeconfigPath = flags[\"--kubeconfig\"];\n if (!name || !provider || !region || !kubeconfigPath) {\n fail(\n \"Usage: rebase cloud clusters add --name <n> --provider <gcp|aws|hetzner> --region <r> --kubeconfig <path> \" +\n \"[--base-domain <d>] [--ingress-address <ip>] [--platform-capacity] \" +\n \"[--backup-bucket <b> --backup-endpoint <url> --backup-access-key-id <k> --backup-secret-access-key <s>]\",\n undefined,\n \"bad_request\"\n );\n }\n if (provider !== \"gcp\" && provider !== \"aws\" && provider !== \"hetzner\") {\n fail(`--provider must be gcp, aws or hetzner (got \"${provider}\")`, undefined, \"bad_request\");\n }\n\n const backup = {\n backupBucket: flags[\"--backup-bucket\"],\n backupEndpoint: flags[\"--backup-endpoint\"],\n backupAccessKeyId: flags[\"--backup-access-key-id\"],\n backupSecretAccessKey: flags[\"--backup-secret-access-key\"]\n };\n const anyBackup = Boolean(backup.backupBucket || backup.backupAccessKeyId || backup.backupSecretAccessKey);\n if (anyBackup && !(backup.backupBucket && backup.backupAccessKeyId && backup.backupSecretAccessKey)) {\n fail(\n \"--backup-bucket, --backup-access-key-id and --backup-secret-access-key go together: a bucket \" +\n \"without a key, or a key without a bucket, is a cluster with NO backup store.\",\n undefined,\n \"bad_request\"\n );\n }\n if (provider === \"hetzner\" && flags[\"--platform-capacity\"] && !backup.backupBucket) {\n fail(\n \"A Hetzner cluster we operate needs its own backup store (--backup-bucket ... on Hetzner Object \" +\n \"Storage): without one its databases archive nowhere, or — worse — into the GCP default from \" +\n \"another provider.\",\n undefined,\n \"bad_request\"\n );\n }\n\n return {\n name: name!,\n provider,\n region: region!,\n kubeconfigPath: kubeconfigPath!,\n baseDomain: flags[\"--base-domain\"],\n ingressAddress: flags[\"--ingress-address\"],\n platformCapacity: flags[\"--platform-capacity\"] === true,\n ...(anyBackup ? backup : {})\n };\n}\n\nasync function clustersAddCommand(rawArgs: string[]): Promise<void> {\n const args = resolveClusterAddArgs(rawArgs);\n // Parsed before authenticating: a usage error is answerable without a\n // session, and asking for one first turns \"you forgot the id\" into \"log in\".\n const { client } = await requireClient(rawArgs);\n\n let kubeConfigData: string;\n try {\n kubeConfigData = fs.readFileSync(args.kubeconfigPath, \"utf8\");\n } catch {\n fail(`Could not read ${args.kubeconfigPath}`, undefined, \"bad_request\");\n return;\n }\n\n const { kubeconfigPath: _path, ...columns } = args;\n let created: { id: string | number };\n try {\n created = await client.data.collection(\"clusters\").create({\n ...columns,\n authType: \"kubeconfig\",\n kubeConfigData\n }) as never;\n } catch (error: unknown) {\n reportError(error, \"Could not register the cluster\");\n return;\n }\n\n emit(\n () => {\n success(`Registered ${args.name} (${created.id}).`);\n noteBlank();\n note(\"The cluster baseline (ingress, certificates, the database operator) is installing in the background.\");\n note(\"Verify it can host tenants:\");\n note(chalk.cyan(` rebase cloud clusters verify ${created.id} --baseline`));\n if (args.platformCapacity) {\n noteBlank();\n note(`Projects placed in ${args.region} now deploy here. Point *.${args.baseDomain ?? \"<baseDomain>\"} at ${args.ingressAddress ?? \"its ingress address\"} first.`);\n }\n },\n { id: created.id, name: args.name, provider: args.provider, region: args.region, platformCapacity: args.platformCapacity }\n );\n}\n\nasync function clustersListCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud clusters\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n try {\n const clusters = (await client.data.collection(\"clusters\").find({ limit: 100 })).data as Array<{\n id: string | number;\n name?: string;\n provider?: string;\n region?: string;\n status?: string;\n }>;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(\" ☸ Clusters\"));\n console.log(\"\");\n if (clusters.length === 0) {\n console.log(chalk.gray(\" No clusters registered.\"));\n console.log(\"\");\n return;\n }\n for (const c of clusters) {\n console.log(` ${chalk.bold(c.name ?? \"(unnamed)\")} ${chalk.gray(`[${c.id}]`)} ${colorStatus(c.status)}`);\n keyValues([[\"Provider\", c.provider], [\"Region\", c.region]]);\n }\n console.log(\"\");\n },\n {\n clusters: clusters.map((c) => ({\n id: String(c.id),\n name: c.name ?? null,\n provider: c.provider ?? null,\n region: c.region ?? null,\n status: c.status ?? null\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list clusters\");\n }\n}\n\n/* ─── billing ──────────────────────────────────────────────────── */\n\n/**\n * The action words `rebase cloud billing` dispatches. No word at all is the\n * account view, which is why it is not in the list.\n *\n * Exported because `action-help.test.ts` holds the page's usage line to it: the\n * page said `cloud billing [portal|usage]` and the dispatch answered `setup` and\n * `checkout`, so both documented words fell through to the default and printed\n * the account — a help page describing a command that does not exist, and a typo\n * exiting 0.\n */\nexport const BILLING_ACTIONS = [\"setup\", \"checkout\"] as const;\n\nexport async function billingCommand(rawArgs: string[]): Promise<void> {\n // Parsed before the client is built: an unusable line should be refused\n // without first spending a login round-trip on it.\n const action = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 2, // cloud billing\n command: \"cloud billing\",\n maxPositionals: 1\n }).positionals[0];\n requireKnownAction(\"billing\", action, BILLING_ACTIONS);\n\n const { client, url } = await requireClient(rawArgs);\n const org = getContextOrg(url);\n\n // `rebase cloud billing setup` — attach a card to the org (one-time, opens a\n // browser). Once done, project create/deploy work headlessly (off_session).\n if (action === \"setup\") {\n if (!org) fail(\"No active organization.\", \"Run `rebase cloud use` first.\", \"no_org\");\n try {\n const res = await client.functions.invoke<{ url?: string; simulated?: boolean }>(\n \"stripe-billing\",\n { organizationId: org },\n { path: \"setup-session\" }\n );\n if (!res.url) fail(\"Could not start billing setup.\", undefined, \"billing_setup_failed\");\n openUrl(res.url, \"Add a payment method in your browser:\");\n emit(\n () => {\n note(chalk.gray(res.simulated\n ? \"(dev mode — Stripe not configured; complete setup from the console)\"\n : \"Once you've added a card, `rebase cloud deploy` runs without further prompts.\"));\n noteBlank();\n },\n { url: res.url,\norg,\nsimulated: Boolean(res.simulated) }\n );\n } catch (e) {\n reportError(e, \"Failed to start billing setup\");\n }\n return;\n }\n\n // `rebase cloud billing checkout --project <slug>` opens a Stripe session.\n if (action === \"checkout\") {\n const projectId = await requireProject(rawArgs, client);\n try {\n const res = await client.functions.invoke<{ url?: string }>(\n \"stripe-billing\",\n { projectId },\n { path: \"session\" }\n );\n if (!res.url) fail(\"Billing session could not be created.\", undefined, \"checkout_failed\");\n emit(\n () => {\n console.log(\"\");\n console.log(\" Complete checkout in your browser:\");\n console.log(` ${chalk.cyan(res.url)}`);\n console.log(\"\");\n },\n { url: res.url,\nprojectId }\n );\n } catch (e) {\n reportError(e, \"Failed to start checkout\");\n }\n return;\n }\n\n // default: show the active org's billing account.\n if (!org) fail(\"No active organization.\", \"Run `rebase cloud use` first.\", \"no_org\");\n try {\n const billingId = billingAccountIdOf(await client.data.collection(\"organizations\").findById(org));\n if (!billingId) {\n // Not an error — an org simply may not have been billed yet.\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.gray(` Organization ${org} has no billing account yet.`));\n console.log(\"\");\n },\n { org,\naccount: null,\nmonthlyEur: null,\npaymentMethod: null }\n );\n return;\n }\n const acct = (await client.data.collection(\"billing-accounts\").findById(billingId)) as\n | { id: string | number; billingEmail?: string; status?: string; stripeCustomerId?: string }\n | undefined;\n\n // Card-on-file lives in Stripe; the control plane reports it for us.\n let card: { hasPaymentMethod?: boolean; brand?: string; last4?: string; expMonth?: number; expYear?: number } = {};\n try {\n card = await client.functions.invoke<typeof card>(\n \"stripe-billing\",\n undefined,\n { method: \"GET\",\npath: `payment-method/${org}` }\n );\n } catch {\n // status endpoint optional — fall back to the local account record\n }\n\n // Best-effort: what the linked/`--project` project costs per month.\n //\n // This used to name a plan, and before that a `compute_<provider>_<vmSize>`\n // price — a key for a machine on a price list this platform does not buy\n // from, which stopped resolving when `vmSize` was removed and printed a\n // bare label ever since. A project is priced from its dials now, so the\n // honest thing to show is the number the control plane would invoice.\n let monthly: string | undefined;\n try {\n const parsed = arg({ \"--project\": String,\n\"-p\": \"--project\" }, { argv: rawArgs.slice(2),\npermissive: true });\n const ref = parsed[\"--project\"] || readLink()?.projectId;\n const projectId = ref ? await lookupProjectId(ref, client) : undefined;\n if (projectId) {\n const proj = (await client.data.collection(\"projects\").findById(projectId)) as\n | Record<string, unknown>\n | undefined;\n const hasCluster = proj?.cluster_id != null || proj?.cluster != null;\n // `path` rather than a slash in the NAME: the SDK URL-encodes\n // the function name, so \"pricing/quote\" became \"pricing%2Fquote\"\n // and the route 404'd — every time, since this shipped. The\n // console's copy of this call carries the same note and gets it\n // right.\n const quote = await client.functions.invoke<ResourceQuote>(\n \"pricing\",\n proj,\n { method: \"POST\", path: \"quote\" }\n );\n monthly = `€${quote.totalEur.toFixed(2)}/mo`;\n if (hasCluster) monthly = `${monthly} — platform fee, your own cluster`;\n }\n } catch (err: unknown) {\n // Say which of the two it was. A bare `catch {}` reporting \"a\n // control plane without the quote endpoint\" is what made a\n // permanent 404 look like an expected condition for this command's\n // whole life.\n if (wantsRawError()) {\n console.error(` (no price: ${err instanceof Error ? err.message : String(err)})`);\n }\n }\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 💳 Billing — org ${org}`));\n console.log(\"\");\n keyValues([\n [\"Account\", acct ? String(acct.id) : undefined],\n [\"Email\", acct?.billingEmail],\n [\"Status\", acct?.status ? colorStatus(acct.status) : undefined],\n [\"Resources\", monthly],\n [\n \"Payment method\",\n card.hasPaymentMethod\n ? `${card.brand ?? \"card\"} •••• ${card.last4 ?? \"????\"}${card.expMonth ? ` (exp ${card.expMonth}/${card.expYear})` : \"\"}`\n : chalk.yellow(\"none — run `rebase cloud billing setup`\")\n ]\n ]);\n console.log(\"\");\n },\n {\n org,\n account: acct\n ? { id: String(acct.id),\nbillingEmail: acct.billingEmail ?? null,\nstatus: acct.status ?? null }\n : null,\n monthlyEur: monthly ?? null,\n paymentMethod: {\n hasPaymentMethod: Boolean(card.hasPaymentMethod),\n brand: card.brand ?? null,\n last4: card.last4 ?? null,\n expMonth: card.expMonth ?? null,\n expYear: card.expYear ?? null\n }\n }\n );\n } catch (e) {\n reportError(e, \"Failed to load billing\");\n }\n}\n\n/* ─── compute: what this project reserves ───────────────────────── */\n\n/**\n * The action words `rebase cloud compute` dispatches. No word, or `show`,\n * prints the dials and the quote.\n */\nexport const COMPUTE_ACTIONS = [\"show\", \"set\"] as const;\n\n/** The dials, and the flag that sets each. */\nconst DIAL_FLAGS = {\n \"--cpu\": \"cpu\",\n \"--memory\": \"memory\",\n \"--replicas\": \"replicaCount\",\n \"--spot\": \"preemptible\",\n \"--scale-to-zero\": \"scaleToZero\",\n // No `--db-mode`. The shared tier was retired, so a managed database is a\n // CloudNativePG cluster of the project's own and there is nothing left to\n // choose — a flag whose only legal value is the default is a flag that\n // changes nothing. The database is still dialable, by size and instances.\n \"--db-instances\": \"databaseInstances\",\n \"--db-cpu\": \"databaseCpu\",\n \"--db-memory\": \"databaseMemory\",\n \"--storage\": \"storageMode\",\n // Autoscaling is a RANGE, and `--replicas` is its floor rather than a\n // separate concept: with a max set, the floor is what always exists and what\n // the project is billed for at rest, and the max is the ceiling it may reach\n // and the worst case it may be billed. Deliberately not a `--autoscale\n // on|off` boolean — that would admit the incoherent state where autoscaling\n // is enabled and the range is a single point. A max at or below the floor\n // turns it off, which is the one rule `resolveAutoscaling` enforces.\n \"--autoscale-max\": \"autoscaleMaxReplicas\",\n \"--autoscale-cpu-target\": \"autoscaleTargetCpuPercent\"\n} as const;\n\n/**\n * The flags `resources set` accepts, in the shape a spec is written in.\n *\n * Derived from `DIAL_FLAGS` rather than written out beside it: `action-help.ts`\n * documents this command and `action-help.test.ts` pairs the page against this\n * constant, so a dial added above is a dial the help page has to describe on the\n * same commit. A hand-copied second list is how the page and the parser drift.\n *\n * `buildDialPatch` still scans `rawArgs` itself — it has to, because\n * `--no-autoscale` is value-less and a dial's value may not be consumed as one\n * — so this is a description of that line, not a second parser for it.\n */\nexport const COMPUTE_SET_FLAGS: Record<string, unknown> = {\n ...Object.fromEntries(Object.keys(DIAL_FLAGS).map((flag) => [flag, String])),\n \"--no-autoscale\": Boolean\n};\n\n/** Dials whose column is a number, not the text a flag carries. */\nconst NUMERIC_DIALS = new Set([\n \"databaseInstances\",\n \"replicaCount\",\n \"autoscaleMaxReplicas\",\n \"autoscaleTargetCpuPercent\"\n]);\n/** Dials that are a yes/no. `--spot false` has to reach the row as `false`. */\nconst BOOLEAN_DIALS = new Set([\"preemptible\", \"scaleToZero\"]);\n\n/**\n * `rebase cloud compute` — show what a project reserves, and change it.\n *\n * Named for what it shows — CPU, memory, replicas, the database's shape, and\n * what those cost — because `rebase resources` already means the graph a\n * project declares, and two commands called \"resources\" that show different\n * things is a support ticket.\n *\n * ## Why nothing is validated here\n *\n * The rules are the *target cluster's*, not the CLI's: GKE Autopilot bills a\n * 250m/512Mi floor and rewrites anything outside a 1:1–6.5:1 memory:CPU band,\n * while a Hetzner or EKS node has neither constraint. A CLI that carried those\n * numbers would be wrong for two of the three providers the moment it shipped,\n * and would drift from the control plane the first time either changed.\n *\n * So the control plane validates and this reports what it said. The same\n * boundary refuses a raw PATCH and a console save, which is the property worth\n * having — a check in a client only covers the clients that run it.\n */\nexport async function computeCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n // `compute et --cpu 500m` used to SHOW the dials and exit 0, so a caller\n // that meant to change one was told what it currently is and nothing else.\n requireKnownAction(\"compute\", action, COMPUTE_ACTIONS);\n // `set` is described by `COMPUTE_SET_FLAGS`, which is derived from\n // `DIAL_FLAGS`; `buildDialPatch` still reads the values itself, because\n // `--no-autoscale` is value-less. This parse is only the refusal: without\n // it `compute set --cpu-request 500m` set nothing and reported success.\n parseCloudArgs({\n spec: (action === \"set\" ? COMPUTE_SET_FLAGS : {}) as Record<string, never>,\n rawArgs,\n commandWords: 3,\n command: action === \"set\" ? \"cloud compute set\" : \"cloud compute\",\n maxPositionals: 0\n });\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n const project = (await client.data.collection(\"projects\").findById(projectId)) as\n | Record<string, unknown>\n | undefined;\n if (!project) fail(`Project ${displayProjectRef(rawArgs)} not found.`, undefined, \"not_found\");\n\n if (action !== \"set\") {\n // What this costs, priced by the control plane. Best-effort: an older\n // control plane has no quote endpoint, and a resources listing that\n // fails because a price could not be fetched would be worse than one\n // without the price.\n let quote: ResourceQuote | undefined;\n try {\n // See the note at the other call site: the name is \"pricing\" and the\n // sub-path is an option, because the SDK encodes the name.\n quote = await client.functions.invoke<ResourceQuote>(\n \"pricing\", project, { method: \"POST\", path: \"quote\" });\n } catch (err: unknown) {\n // No quote — the dials below are still the answer to the question\n // asked. Visible under REBASE_DEBUG, so a permanent failure cannot\n // masquerade as a control plane that simply does not price.\n if (wantsRawError()) {\n console.error(` (no price: ${err instanceof Error ? err.message : String(err)})`);\n }\n }\n\n emit(\n () => {\n console.log(\"\");\n console.log(` ${chalk.bold(String(project!.name ?? \"\"))} ${chalk.gray(`[${String(project!.subdomain ?? \"\")}]`)}`);\n console.log(\"\");\n keyValues([\n [\"App CPU\", dialLine(project!.cpu)],\n [\"App memory\", dialLine(project!.memory)],\n [\"App replicas\", dialLine(project!.replicaCount)],\n [\"Capacity\", dialLine(project!.preemptible, { true: \"spot\", false: \"on demand\" })],\n [\"When idle\", dialLine(project!.scaleToZero, { true: \"scale to zero\", false: \"stay warm\" })],\n [\"Database instances\", dialLine(project!.databaseInstances)],\n [\"Database CPU\", dialLine(project!.databaseCpu)],\n [\"Database memory\", dialLine(project!.databaseMemory)],\n [\"Object storage\", dialLine(project!.storageMode)],\n [\"Per month\", quote ? `€${quote.totalEur.toFixed(2)}` : undefined]\n ]);\n // Itemised, because a total nobody can decompose is a number\n // someone has to trust rather than check.\n if (quote) {\n console.log(\"\");\n for (const line of quote.lines) {\n const qty = line.unit ? chalk.gray(`${line.quantity} × €${line.unitEur}`) : \"\";\n note(` ${line.label.padEnd(24)} ${qty.padEnd(28)} €${line.amountEur.toFixed(2)}`);\n }\n }\n console.log(\"\");\n noteBlank();\n note(\"Empty means the platform default. Change one with:\");\n note(chalk.cyan(\" rebase cloud compute set --cpu 500m --memory 2Gi\"));\n console.log(\"\");\n },\n {\n monthlyEur: quote?.totalEur ?? null,\n lines: quote?.lines ?? null,\n cpu: project!.cpu ?? null,\n memory: project!.memory ?? null,\n replicaCount: project!.replicaCount ?? null,\n preemptible: project!.preemptible ?? null,\n scaleToZero: project!.scaleToZero ?? null,\n databaseInstances: project!.databaseInstances ?? null,\n databaseCpu: project!.databaseCpu ?? null,\n databaseMemory: project!.databaseMemory ?? null,\n storageMode: project!.storageMode ?? null\n }\n );\n return;\n }\n\n const built = buildDialPatch(rawArgs);\n if (built.error) fail(built.error, undefined, \"bad_request\");\n const patch = built.patch;\n\n try {\n await client.data.collection(\"projects\").update(projectId, patch);\n } catch (error: unknown) {\n // The control plane's refusals are written to be read by whoever chose\n // the number — a ratio named, a field named — so they are surfaced\n // verbatim rather than replaced with a generic failure.\n reportError(error, \"Could not change resources\");\n return;\n }\n\n emit(\n () => {\n success(\"Resources updated.\");\n noteBlank();\n for (const [field, value] of Object.entries(patch)) {\n note(` ${field} → ${String(value)}`);\n }\n noteBlank();\n note(\"Applied now: the app rolls its pods and your subscription is prorated from today.\");\n note(\"A change that restarts the database waits for a maintenance window.\");\n },\n { updated: patch }\n );\n}\n\n/** What the control plane says a set of dials costs, itemised. */\ninterface ResourceQuote {\n lines: { lookupKey: string; label: string; quantity: number; unit?: string; unitEur: number; amountEur: number }[];\n totalEur: number;\n}\n\n/**\n * A dial's value, or a marker that the platform default decides it.\n *\n * The two are different states and the distinction is not cosmetic: an unset\n * dial follows the default and moves if it does, while one pinned to the same\n * number will not. Printing the inherited value would make them identical on\n * screen.\n */\nfunction dialLine(value: unknown, labels?: Record<string, string>): string {\n if (value === null || value === undefined || value === \"\") return chalk.gray(\"default\");\n const key = String(value);\n return labels?.[key] ?? key;\n}\n\n/**\n * Turn `--cpu 500m --db-instances 2` into the patch to send.\n *\n * Pure, and exported, so the flag handling is testable without a control plane —\n * the same shape `buildSettingsPatch` uses. Returns an error string rather than\n * throwing, because the caller owns how a refusal is printed in JSON mode.\n */\nexport function buildDialPatch(\n rawArgs: string[],\n /**\n * `requireOne: false` for `projects create`, where naming no dial is the\n * ordinary case — a new project takes the platform default. On\n * `compute set` a patch with nothing in it is a typo, and saying so beats\n * a success message for a change nobody made.\n */\n opts?: { requireOne?: boolean }\n): { patch: Record<string, unknown>; error?: string } {\n const patch: Record<string, unknown> = {};\n\n // A value-less flag, and the only way to turn autoscaling off.\n //\n // Setting the ceiling down to the floor would also disable it, but the\n // control plane refuses that now: a row naming a ceiling that resolves to no\n // autoscaler is a state nothing reads back correctly, and it used to happen\n // silently — `--replicas 5` on a project whose ceiling was 5 deleted the\n // HPA, left the ceiling on the row, and said nothing.\n if (rawArgs.includes(\"--no-autoscale\")) {\n patch.autoscaleMaxReplicas = null;\n patch.autoscaleTargetCpuPercent = null;\n }\n\n for (const [flag, field] of Object.entries(DIAL_FLAGS)) {\n const idx = rawArgs.indexOf(flag);\n if (idx === -1) continue;\n const value = rawArgs[idx + 1];\n // A flag followed by another flag is a missing value, not an empty one.\n // Silently sending \"\" would clear the dial — the opposite of what\n // someone who fumbled a flag meant.\n if (value === undefined || value.startsWith(\"--\")) {\n return { patch: {}, error: `${flag} needs a value.` };\n }\n if (NUMERIC_DIALS.has(field)) {\n const n = Number(value);\n if (!Number.isInteger(n)) {\n return { patch: {}, error: `${flag} takes a whole number, not \"${value}\".` };\n }\n // Sent as a number, not a string. The control plane decides whether\n // anything CHANGED by comparing against the stored value — and it\n // re-syncs a Stripe subscription and rolls a tenant's pods when\n // something did. \"2\" against 2 differs, so a string here would turn\n // every unrelated save into a resize.\n patch[field] = n;\n } else if (BOOLEAN_DIALS.has(field)) {\n if (value !== \"true\" && value !== \"false\") {\n return { patch: {}, error: `${flag} takes true or false, not \"${value}\".` };\n }\n // The string \"false\" is truthy, and would put a project that asked\n // for on-demand capacity onto preemptible nodes at a third of the\n // price — with restarts it explicitly declined.\n patch[field] = value === \"true\";\n } else {\n patch[field] = value;\n }\n }\n\n if (opts?.requireOne !== false && Object.keys(patch).length === 0) {\n return {\n patch: {},\n error: `Nothing to set. Pass one of: ${Object.keys(DIAL_FLAGS).join(\", \")}, --no-autoscale.`\n };\n }\n return { patch };\n}\n","/**\n * `rebase cloud db connect` — a local port that is your cloud database.\n *\n * ## What this replaces\n *\n * A managed database lives in a namespace of the platform's cluster, and its\n * address (`postgres-rw.rebase-tenant-….svc.cluster.local`) resolves to nothing\n * on a developer's machine. The console used to bridge that gap by printing\n *\n * kubectl port-forward svc/postgres-rw -n rebase-tenant-… 5432:5432\n *\n * which nobody outside the platform can run: a tenant of Rebase Cloud has no\n * kubeconfig for our cluster, and there is no product that sells one. So the\n * platform reaches into the cluster instead, and this command is the local end\n * of that reach.\n *\n * ## How it works\n *\n * A listener on 127.0.0.1. Every TCP connection it accepts opens its own\n * WebSocket to the control plane, authenticates in-band with the console session\n * this CLI already holds, and from `ready` onwards the two are a byte pipe. The\n * database still asks for a password — the tunnel is a network path, not a\n * credential — so `psql` behaves exactly as it would against a local Postgres.\n *\n * One WebSocket per connection rather than one multiplexed socket: `psql` is one\n * connection and a pool is a handful, and per-connection sockets keep the\n * framing at \"these bytes are those bytes\" with no stream ids to get wrong.\n *\n * Node's global `WebSocket` is used rather than `ws`, which is why the token\n * goes in the first frame instead of an `Authorization` header — the WHATWG\n * client cannot set request headers, and a header-only endpoint would be\n * unreachable from a browser too.\n */\nimport net from \"node:net\";\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n fail,\n freshAccessToken,\n note,\n noteBlank,\n reportError,\n warn,\n type SessionHolder\n} from \"./context\";\n\n/** Documented in `action-help.ts`, and paired with it by `action-help.test.ts`. */\nexport const DB_CONNECT_FLAGS = {\n \"--port\": Number,\n \"--reveal\": Boolean\n} as const;\n\n/** What `db-info` answers. Mirrors `saas/backend/functions/db-info.ts`. */\ninterface DbInfoResponse {\n type: \"managed\" | \"byodb\";\n host: string | null;\n port: string | null;\n database: string | null;\n username: string | null;\n passwordAvailable: boolean;\n directAccess: {\n via: \"tunnel\";\n kubectl?: { namespace: string; service: string; localPort: number; remotePort: number };\n } | null;\n unavailableReason: string | null;\n}\n\n/** The default, because it is what every Postgres client assumes. */\nconst DEFAULT_LOCAL_PORT = 5432;\n\n/**\n * The handshake, which is the only thing the tunnel says in words.\n *\n * After `ready` every frame is bytes, so a text frame arriving later is not a\n * frame of ours at all — it is a proxy answering in the control plane's place.\n */\ntype TunnelFrame =\n | { type: \"ready\" }\n | { type: \"error\"; code?: string; message?: string };\n\n/** `https://app.rebase.pro` → `wss://app.rebase.pro/api/db-tunnel/p1`. */\nexport function tunnelUrl(cloudUrl: string, projectId: string): string {\n const url = new URL(cloudUrl);\n url.protocol = url.protocol === \"http:\" ? \"ws:\" : \"wss:\";\n // Replaced rather than appended: a control-plane URL carrying a path would\n // otherwise produce `/base/api/db-tunnel/...`, and the route is mounted at\n // the root of the host.\n url.pathname = `/api/db-tunnel/${encodeURIComponent(projectId)}`;\n url.search = \"\";\n return url.toString();\n}\n\n/**\n * A local DSN for the tunnel, with the password only if the caller asked.\n *\n * Built here and nowhere else. The server reports the *cluster's* URI, which is\n * the one thing that must not be printed as the way to connect — it is exactly\n * the address that does not work from here.\n */\nexport function localDsn(opts: {\n port: number;\n username: string | null;\n database: string | null;\n password?: string;\n}): string {\n const user = opts.username ? encodeURIComponent(opts.username) : \"postgres\";\n const auth = opts.password ? `${user}:${encodeURIComponent(opts.password)}` : user;\n const database = opts.database ?? \"rebase\";\n return `postgresql://${auth}@127.0.0.1:${opts.port}/${database}`;\n}\n\nexport async function dbConnect(rawArgs: string[]): Promise<void> {\n const { flags: args } = parseCloudArgs({\n spec: DB_CONNECT_FLAGS,\n rawArgs,\n commandWords: 3, // cloud db connect\n command: \"cloud db connect\",\n maxPositionals: 0\n });\n const { client, url } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n let info: DbInfoResponse;\n try {\n info = await client.functions.invoke<DbInfoResponse>(\"db-info\", undefined, {\n method: \"GET\",\n path: projectId\n });\n } catch (e) {\n return reportError(e, \"Failed to load database info\");\n }\n\n if (info.type === \"byodb\") {\n fail(\n \"This project uses your own database.\",\n \"Connect to it directly — there is nothing for the platform to tunnel.\",\n \"byodb\"\n );\n }\n if (!info.directAccess) {\n fail(\n \"The platform could not resolve this project's database, so it cannot open a path to it.\",\n info.unavailableReason ??\n \"A managed database is provisioned at the project's first deploy; before then there is nothing to connect to.\",\n \"db_unavailable\"\n );\n }\n\n // Asked for before the listener opens: a prompt-free failure is better than\n // a tunnel that works and a URL the caller cannot use.\n let password: string | undefined;\n if (args[\"--reveal\"]) {\n if (!info.passwordAvailable) {\n fail(\n \"No password is available to reveal for this database.\",\n info.unavailableReason ?? undefined,\n \"password_unavailable\"\n );\n }\n try {\n password = (\n await client.functions.invoke<{ password: string }>(\"db-info\", { projectId }, { path: \"reveal\" })\n ).password;\n } catch (e) {\n return reportError(e, \"Failed to reveal the database password\");\n }\n }\n\n const requested = args[\"--port\"] ?? DEFAULT_LOCAL_PORT;\n if (!Number.isInteger(requested) || requested < 0 || requested > 65535) {\n fail(`--port must be a port number, not ${requested}.`, undefined, \"bad_port\");\n }\n\n const server = tunnelListener(client, tunnelUrl(url, projectId));\n\n server.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n fail(\n `Port ${requested} on 127.0.0.1 is already in use.`,\n \"Pass --port to choose another, or stop whatever is listening there.\",\n \"port_in_use\"\n );\n }\n fail(`Could not open a local listener: ${err.message}`, undefined, \"listen_failed\");\n });\n\n await new Promise<void>((resolve) => {\n server.listen(requested, \"127.0.0.1\", () => resolve());\n });\n\n const address = server.address();\n const port = address && typeof address !== \"string\" ? address.port : requested;\n const dsn = localDsn({ port, username: info.username, database: info.database, password });\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🔌 Tunnel open — project ${projectRef}`));\n console.log(\"\");\n console.log(` ${chalk.green(dsn)}`);\n console.log(\"\");\n if (!password) {\n console.log(\n chalk.gray(\" The password is hidden. Re-run with --reveal to print it in the URL,\")\n );\n console.log(chalk.gray(\" or read it with `rebase cloud db info --reveal`.\"));\n console.log(\"\");\n }\n console.log(chalk.gray(\" Leave this running, and point any Postgres client at it.\"));\n console.log(chalk.gray(\" Ctrl-C closes the tunnel.\"));\n console.log(\"\");\n },\n {\n projectId,\n host: \"127.0.0.1\",\n port,\n database: info.database,\n username: info.username,\n connectionString: dsn,\n // Only present when explicitly revealed, exactly as `db info` does.\n ...(password ? { password } : {})\n }\n );\n\n // The command IS the tunnel: it holds the terminal until the developer is\n // done. `once` rather than `on`, so a second Ctrl-C kills the process\n // instead of queueing another shutdown.\n await new Promise<void>((resolve) => {\n process.once(\"SIGINT\", () => {\n noteBlank();\n note(chalk.gray(\"Tunnel closed.\"));\n // Not awaited: `server.close` waits for established connections to\n // end, and the developer just asked to stop rather than to drain.\n server.close();\n resolve();\n });\n });\n}\n\n/**\n * The local listener: each connection it accepts gets its own tunnel, signed in\n * with a token that is current when the connection arrives.\n *\n * The command is left running for as long as the developer works, and the\n * access token it started with lapses within the hour. Every connection is\n * authenticated on its own, so each one reads the token then, refreshing it\n * first when it is close to expiry — rather than the one read at startup, which\n * the control plane refuses for every connection opened after it expires.\n *\n * The socket is paused while the token is read, so a client's first bytes wait\n * for the tunnel exactly as they do once it is being established.\n */\nexport function tunnelListener(client: SessionHolder, endpoint: string): net.Server {\n return net.createServer((socket) => {\n socket.pause();\n freshAccessToken(client).then(\n (token) => {\n if (!socket.destroyed) pipeThroughTunnel(socket, endpoint, token);\n },\n () => {\n warn(\n \"A connection was closed: the session this tunnel signs in with has expired and could not be refreshed.\",\n \"Run `rebase cloud login`, then connect again.\"\n );\n socket.destroy();\n }\n );\n });\n}\n\n/**\n * One accepted connection, carried over one WebSocket.\n *\n * The local socket is paused until the tunnel says `ready`, so a client that\n * sends its startup packet the instant it connects — which every Postgres\n * client does — cannot have those bytes arrive before there is a database to\n * send them to.\n *\n * Exported for `db-connect.pipe.test.ts`, which drives it with a real socket\n * against a real WebSocket: this is the half a developer's client actually\n * talks to, and a pipe is the one component whose bugs are silent — a dropped\n * or reordered chunk does not throw, it corrupts a Postgres message and\n * surfaces as a protocol error nowhere near here.\n */\nexport function pipeThroughTunnel(socket: net.Socket, endpoint: string, token: string): void {\n socket.pause();\n socket.setNoDelay(true);\n\n const ws = new WebSocket(endpoint);\n ws.binaryType = \"arraybuffer\";\n let ready = false;\n\n const closeBoth = (reason?: string) => {\n if (reason && !ready) {\n // Only worth saying while the tunnel is being established: after\n // that, a close is a client disconnecting and is not news. A\n // warning, so it reaches stderr in JSON mode too: the connection\n // that was dropped belongs to a client nobody else is watching.\n warn(`A connection was refused: ${reason}`);\n }\n try {\n if (ws.readyState === WebSocket.OPEN || ws.readyState === WebSocket.CONNECTING) ws.close();\n } catch {\n /* already gone */\n }\n socket.destroy();\n };\n\n ws.onopen = () => {\n ws.send(JSON.stringify({ type: \"authenticate\", token }));\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (typeof event.data === \"string\") {\n // Text frames are the handshake, and the server sends none after\n // `ready` — so anything unparseable here is a proxy or a gateway\n // answering in place of the control plane.\n let frame: TunnelFrame | null = null;\n try {\n frame = JSON.parse(event.data) as TunnelFrame;\n } catch {\n return closeBoth(`the tunnel endpoint answered with ${event.data.slice(0, 80)}`);\n }\n if (frame.type === \"ready\") {\n ready = true;\n socket.resume();\n return;\n }\n const refusal = frame.type === \"error\" ? frame : null;\n return closeBoth(\n refusal?.message ?? `the tunnel was refused (${refusal?.code ?? \"unknown\"})`\n );\n }\n socket.write(Buffer.from(event.data as ArrayBuffer));\n };\n\n ws.onerror = () => {\n closeBoth(\"could not reach the control plane's tunnel endpoint\");\n };\n ws.onclose = () => {\n socket.destroy();\n };\n\n socket.on(\"data\", (chunk: Buffer) => {\n if (ws.readyState !== WebSocket.OPEN) return;\n // The Uint8Array view is copied rather than sent as-is: `chunk` is a\n // slice of a shared read buffer, and sending the underlying\n // ArrayBuffer would put the whole of it on the wire.\n ws.send(new Uint8Array(chunk));\n if (ws.bufferedAmount > 1024 * 1024) {\n socket.pause();\n const drain = setInterval(() => {\n if (ws.readyState !== WebSocket.OPEN) return clearInterval(drain);\n if (ws.bufferedAmount < 256 * 1024) {\n clearInterval(drain);\n socket.resume();\n }\n }, 5);\n }\n });\n socket.on(\"close\", () => closeBoth());\n socket.on(\"error\", () => closeBoth());\n}\n","/**\n * `rebase cloud db` — database + backup management for a project.\n *\n * db list List databases attached to the project\n * db create Attach a managed or bring-your-own database\n * db info Where the database is, and what it is called\n * db connect A local port that IS the project's database\n * db test Test connectivity to the project's database\n * db backup list|create|restore\n */\nimport arg from \"arg\";\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport {\n requireClient,\n requireProject,\n requireKnownAction,\n displayProjectRef,\n parseCloudArgs,\n emit,\n printGroupHelp,\n confirmDestructive,\n colorStatus,\n keyValues,\n success,\n fail,\n reportError,\n note,\n noteBlank,\n requireInteractive,\n resolveTimeoutMs,\n type CloudClient,\n cloudRows,\n requireCloudRow\n} from \"./context\";\nimport { dbConnect } from \"./db-connect\";\n\ninterface DatabaseRow {\n id: string | number;\n type?: string;\n connectionStatus?: string;\n useSshTunnel?: boolean;\n pitrEnabled?: boolean;\n}\n\n/**\n * One backup, as the control plane's `backup` function describes it.\n *\n * `name` is the filename `restore` and `download` take. `size` arrives already\n * formatted — \"12.34 MB\", or \"unknown\" when the platform could not read it —\n * and is printed as given. `filename` and a numeric `size` are read too, so a\n * row from any control plane renders.\n */\ninterface BackupRow {\n id?: string;\n name?: string;\n filename?: string;\n size?: string | number;\n type?: string;\n date?: string;\n status?: string;\n}\n\n/** The filename a backup is restored and downloaded by. */\nfunction backupName(row: BackupRow | undefined): string | undefined {\n return row?.name ?? row?.filename;\n}\n\n/** A backup's size for a person: the control plane's own string, or bytes as MB. */\nfunction backupSize(row: BackupRow): string | undefined {\n if (typeof row.size === \"string\") return row.size;\n if (typeof row.size === \"number\" && Number.isFinite(row.size)) return `${(row.size / 1024 / 1024).toFixed(1)} MB`;\n return undefined;\n}\n\nexport async function dbCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n switch (subcommand) {\n case \"list\":\n case undefined:\n await listDatabases(rawArgs);\n break;\n case \"create\":\n await createDatabase(rawArgs);\n break;\n case \"info\":\n await dbInfo(rawArgs);\n break;\n case \"connect\":\n await dbConnect(rawArgs);\n break;\n case \"test\":\n await testDatabase(rawArgs);\n break;\n case \"backup\":\n await backupCommand(rawArgs);\n break;\n case \"pitr\":\n await pitrCommand(rawArgs);\n break;\n case \"--help\":\n printDbHelp();\n break;\n default:\n fail(`Unknown db command: ${subcommand}`, \"Run `rebase cloud db --help`.\", \"unknown_command\");\n }\n}\n\nasync function listDatabases(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud db\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const dbs = cloudRows<DatabaseRow>((await client.data.collection(\"databases\").find({\n where: { project: [\"==\", projectId] },\n limit: 50\n })).data);\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🗄 Databases — project ${projectRef}`));\n console.log(\"\");\n if (dbs.length === 0) {\n console.log(chalk.gray(\" No database attached. Add one with `rebase cloud db create`.\"));\n console.log(\"\");\n return;\n }\n for (const d of dbs) {\n console.log(` ${chalk.bold(d.type ?? \"unknown\")} ${chalk.gray(`[${d.id}]`)} ${colorStatus(d.connectionStatus)}`);\n keyValues([\n [\"SSH tunnel\", d.useSshTunnel ? \"yes\" : undefined],\n [\"PITR\", d.pitrEnabled ? \"enabled\" : undefined]\n ]);\n }\n console.log(\"\");\n },\n {\n projectId,\n databases: dbs.map((d) => ({\n id: String(d.id),\n type: d.type ?? null,\n connectionStatus: d.connectionStatus ?? null,\n useSshTunnel: Boolean(d.useSshTunnel),\n pitrEnabled: Boolean(d.pitrEnabled)\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list databases\");\n }\n}\n\n/**\n * The database already attached to a project, if any.\n *\n * `limit: 1` deliberately mirrors what the control plane's own `db-test`,\n * `db-info` and `backup` do — asking the same question the same way is the\n * point, since the answer decides which row a deploy will actually use.\n */\nasync function firstAttachedDatabase(\n client: CloudClient,\n projectId: string\n): Promise<DatabaseRow | undefined> {\n const rows = cloudRows<DatabaseRow>((await client.data.collection(\"databases\").find({\n where: { project: [\"==\", projectId] },\n limit: 1\n })).data);\n return rows[0];\n}\n\n/**\n * Attach a database row to a project.\n *\n * Extracted so `rebase cloud projects create` can do it in the same breath as\n * creating the project — see `--db` there. Two call sites, one insert, so the\n * shape of the row cannot drift between \"attached at creation\" and \"attached\n * afterwards\".\n */\nexport async function attachDatabaseRow(\n client: CloudClient,\n input: { projectId: string; type: string; connectionString?: string }\n): Promise<DatabaseRow> {\n return requireCloudRow<DatabaseRow>(await client.data.collection(\"databases\").create({\n project: input.projectId,\n type: input.type,\n connectionString: input.type === \"byodb\" ? input.connectionString : undefined,\n connectionStatus: \"untested\"\n }), \"database\");\n}\n\n/** What `rebase cloud db create` parses. Exported so its help page cannot drift. */\nexport const CREATE_DATABASE_FLAGS = {\n \"--type\": String,\n \"--connection-string\": String,\n \"--wait\": Boolean,\n \"--timeout\": String,\n \"--project\": String,\n \"-p\": \"--project\"\n} as const;\n\nasync function createDatabase(rawArgs: string[]): Promise<void> {\n // Strict, and through the family's parser: an undeclared flag used to be\n // dropped, so `db create --typ managed` opened the interactive picker —\n // or, off a terminal, refused for a type that had been given.\n const { flags: args } = parseCloudArgs({\n spec: CREATE_DATABASE_FLAGS,\n rawArgs,\n commandWords: 3, // cloud db create\n command: \"cloud db create\",\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n // A project has exactly one database, and the platform is built on that:\n // `db-test`, `db-info` and `backup` all read `databases` with `limit: 1`\n // and take whichever row comes back first. A second row therefore does not\n // add a database — it makes it *undefined* which one the project is\n // deployed against, silently, with no error anywhere.\n //\n // Cheap to reach now that `projects create` attaches one by default: the\n // obvious way to move a project to a bring-your-own database was to run\n // `db create --type byodb`, which used to be the only row and is now the\n // second. So this refuses rather than inserts, and names what is already\n // there.\n const existing = await firstAttachedDatabase(client, projectId);\n if (existing) {\n fail(\n `Project ${projectRef} already has a ${existing.type ?? \"database\"} attached (${existing.id}).`,\n \"A project has exactly one database. Remove that one first, or run \"\n + \"`rebase cloud db info` to see what it points at.\",\n \"database_exists\"\n );\n }\n\n let type = args[\"--type\"];\n if (!type) {\n requireInteractive(\"a database type\", \"--type <managed|byodb>\");\n const { picked } = await inquirer.prompt([\n {\n type: \"select\",\n name: \"picked\",\n message: \"Database type:\",\n choices: [\n { name: \"SaaS Managed (provisioned for you)\",\nvalue: \"managed\" },\n { name: \"Bring Your Own DB (external PostgreSQL)\",\nvalue: \"byodb\" }\n ]\n }\n ] as Parameters<typeof inquirer.prompt>[0]);\n type = picked as string;\n }\n\n let connectionString = args[\"--connection-string\"];\n if (type === \"byodb\" && !connectionString) {\n requireInteractive(\"a connection string\", \"--connection-string <url>\");\n const { cs } = await inquirer.prompt([\n { type: \"input\",\nname: \"cs\",\nmessage: \"PostgreSQL connection string:\" }\n ] as Parameters<typeof inquirer.prompt>[0]);\n connectionString = (cs as string)?.trim();\n if (!connectionString) {\n fail(\n \"A connection string is required for bring-your-own databases.\",\n \"Pass `--connection-string <url>`.\",\n \"input_required\"\n );\n }\n }\n\n let created: DatabaseRow;\n try {\n created = await attachDatabaseRow(client, { projectId,\ntype: type!,\nconnectionString });\n } catch (e) {\n reportError(e, \"Failed to attach database\");\n }\n\n // `--wait`, and the one honest thing it can do per type.\n //\n // A managed database is NOT provisioned here: the CloudNativePG cluster is\n // materialised at the project's first deploy. So there is nothing to poll,\n // and a `--wait` that polled would be the same trap this flag exists to\n // remove — a loop over a value that cannot change. It reports that instead,\n // and exits 0, because the attach did succeed.\n //\n // A bring-your-own database is the opposite: it exists right now, and\n // whether it is reachable is a real question with a real answer, so `--wait`\n // asks it until it gets one.\n const waited = args[\"--wait\"] === true\n ? await waitForDatabase(client, {\n projectId,\n type: type!,\n timeoutMs: resolveTimeoutMs(args[\"--timeout\"], {\n fallbackMs: DEFAULT_WAIT_MS,\n command: \"cloud db create\"\n })\n })\n : undefined;\n\n success(`Attached ${type} database to project ${projectRef}`);\n emit(\n () => {\n keyValues([[\"ID\", String(created.id)]]);\n if (waited?.note) note(chalk.gray(waited.note));\n else if (type === \"byodb\") note(chalk.gray(\"Verify it with `rebase cloud db test`.\"));\n else note(chalk.gray(\"It is created at your first deploy — run `rebase cloud deploy` next.\"));\n noteBlank();\n },\n {\n success: true,\n id: String(created.id),\n projectId,\n type,\n connectionStatus: waited?.connectionStatus ?? \"untested\",\n // What `--wait` actually waited for, so a caller can tell an\n // answered question from an unanswerable one.\n waited: waited ? waited.waited : false,\n materializedAt: type === \"managed\" ? \"first_deploy\" : \"now\"\n }\n );\n}\n\n/** How long `db create --wait` waits by default, and `--timeout` overrides. */\nconst DEFAULT_WAIT_MS = 5 * 60 * 1000;\n\nconst WAIT_POLL_MS = 3000;\n\n/**\n * Wait for an attached database to become usable, where \"usable\" means\n * something.\n *\n * Returns `waited: false` for the managed case, and says why — the caller then\n * knows the state it is looking at is final rather than early.\n */\nexport async function waitForDatabase(\n client: CloudClient,\n opts: { projectId: string; type: string; timeoutMs: number; pollMs?: number }\n): Promise<{ waited: boolean; connectionStatus: string; note?: string }> {\n if (opts.type !== \"byodb\") {\n return {\n waited: false,\n connectionStatus: \"untested\",\n note: \"Nothing to wait for: a managed database is created at the project's first deploy. \"\n + \"Run `rebase cloud deploy` next; `rebase cloud db test` only answers after that.\"\n };\n }\n\n const started = Date.now();\n for (;;) {\n try {\n const res = await client.functions.invoke<{ success: boolean }>(\"db-test\", { projectId: opts.projectId });\n if (res.success) return { waited: true,\nconnectionStatus: \"connected\" };\n } catch {\n // A transport failure is indistinguishable from a database that is\n // not up yet, and both are answered by trying again until the\n // deadline. The deadline is what makes that safe.\n }\n if (Date.now() - started > opts.timeoutMs) {\n fail(\n `The database did not become reachable within ${Math.round(opts.timeoutMs / 1000)}s.`,\n \"Run `rebase cloud db test` for the connection log.\",\n \"timeout\"\n );\n }\n await new Promise(resolve => setTimeout(resolve, opts.pollMs ?? WAIT_POLL_MS));\n }\n}\n\nasync function testDatabase(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud db\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n noteBlank();\n note(`Testing database connectivity for project ${chalk.bold(projectRef)}...`);\n try {\n const res = await client.functions.invoke<{ success: boolean; logs?: string }>(\"db-test\", { projectId });\n\n // The connection log is diagnostics, not the result, so it goes to\n // stderr — in both modes. Echoing it to stdout put arbitrary\n // server-generated text in front of whatever was parsing the output,\n // and on the failure path it is the only thing that explains WHY, so\n // suppressing it in JSON mode would have left the refusal below\n // pointing at logs that were never printed.\n if (res.logs) console.error(`\\n${res.logs}`);\n\n if (!res.success) {\n fail(\n \"Database connection failed.\",\n \"The connection log above (stderr) has the reason.\",\n \"db_connection_failed\"\n );\n }\n success(\"Database connection succeeded\");\n emit(() => {}, { success: true,\nprojectId,\nlogs: res.logs ?? null });\n } catch (e) {\n reportError(e, \"Failed to test database\");\n }\n}\n\n/* ─── db info ──────────────────────────────────────────────────── */\n\ninterface DbInfoResponse {\n type: \"managed\" | \"byodb\";\n host: string | null;\n port: string | null;\n database: string | null;\n username: string | null;\n passwordAvailable: boolean;\n /**\n * How the customer reaches this database from their own machine.\n *\n * This replaced a `portForward` field that was rendered as a `kubectl\n * port-forward -n rebase-tenant-…` line — a command whose prerequisite is a\n * kubeconfig for the platform's cluster, which no customer has and which\n * nothing here has ever issued. `kubectl` is present now only when the\n * cluster is the customer's own.\n */\n directAccess: {\n via: \"tunnel\";\n kubectl?: { namespace: string; service: string; localPort: number; remotePort: number };\n } | null;\n unavailableReason: string | null;\n}\n\n/**\n * `rebase cloud db info [--reveal]` — where a project's database actually lives.\n *\n * The password is NEVER in the default output; `--reveal` fetches it through the\n * separate reveal call, and it appears in JSON only when `--reveal` is given.\n * Any field the server could not resolve comes back `null` and is rendered as\n * unavailable, never a placeholder.\n */\nasync function dbInfo(rawArgs: string[]): Promise<void> {\n // `--project`/`-p` are globals and are not redeclared. Strict, so\n // `db info --revel` refuses instead of quietly masking the password it\n // was asked to show.\n const { flags: args } = parseCloudArgs({\n spec: { \"--reveal\": Boolean },\n rawArgs,\n commandWords: 3, // cloud db info\n command: \"cloud db\",\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n try {\n const info = await client.functions.invoke<DbInfoResponse>(\"db-info\", undefined, { method: \"GET\",\npath: projectId });\n\n let password: string | undefined;\n let connectionString: string | undefined;\n if (args[\"--reveal\"]) {\n if (!info.passwordAvailable) {\n fail(\"No password is available to reveal for this database.\", info.unavailableReason ?? undefined, \"password_unavailable\");\n }\n const revealed = await client.functions.invoke<{ password: string; connectionString: string }>(\n \"db-info\",\n { projectId },\n { path: \"reveal\" }\n );\n password = revealed.password;\n connectionString = revealed.connectionString;\n }\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🗄 Database — project ${projectRef}`) + chalk.gray(` (${info.type})`));\n console.log(\"\");\n keyValues([\n [\"Host\", info.host],\n [\"Port\", info.port],\n [\"Database\", info.database],\n [\"Username\", info.username],\n [\"Password\", info.passwordAvailable ? (password ?? chalk.gray(\"hidden — pass --reveal\")) : chalk.gray(\"unavailable\")],\n [\"Connection\", connectionString]\n ]);\n if (info.unavailableReason) {\n console.log(chalk.gray(` ${info.unavailableReason}`));\n }\n if (info.directAccess) {\n console.log(\"\");\n console.log(chalk.gray(\" The host above is inside the platform's cluster: it is the address your\"));\n console.log(chalk.gray(\" deployed backend uses, and it resolves to nothing from here. To reach this\"));\n console.log(chalk.gray(\" database from this machine, open a tunnel:\"));\n console.log(\"\");\n console.log(` ${chalk.cyan(\"rebase cloud db connect\")}`);\n const pf = info.directAccess.kubectl;\n if (pf) {\n // Only ever present for a cluster the customer owns,\n // where they hold the credentials this needs.\n console.log(\"\");\n console.log(chalk.gray(\" Or, on your own cluster:\"));\n console.log(chalk.gray(` kubectl -n ${pf.namespace} port-forward svc/${pf.service} ${pf.localPort}:${pf.remotePort}`));\n }\n }\n console.log(\"\");\n },\n {\n projectId,\n type: info.type,\n host: info.host,\n port: info.port,\n database: info.database,\n username: info.username,\n passwordAvailable: info.passwordAvailable,\n directAccess: info.directAccess,\n unavailableReason: info.unavailableReason,\n // Only present when explicitly revealed.\n ...(args[\"--reveal\"] ? { password,\nconnectionString } : {})\n }\n );\n } catch (e) {\n reportError(e, \"Failed to load database info\");\n }\n}\n\n/* ─── backups ──────────────────────────────────────────────────── */\n\n/**\n * What `db backup` dispatches. `list` is the default for a bare invocation.\n *\n * Fed to `requireKnownAction` before the client is built, like every other\n * group in this family. Both dispatchers here used to end in an unguarded\n * default instead, so `db backup lst` and `db backup restre` listed the backups\n * and read as \"ran, nothing to do\" — on a command whose other actions overwrite\n * the live database. `db pitr` did have a refusal, but at the tail, behind a\n * login and a project lookup: a typo answered `not_logged_in` and never named\n * the typo.\n *\n * The lists are the ones each `--help` page's usage line carries;\n * `action-help.test.ts` holds the two together.\n */\nconst BACKUP_ACTIONS = [\"list\", \"create\", \"restore\", \"status\", \"download\"] as const;\n\n/** What `db pitr` dispatches. `status` is the default for a bare invocation. */\nconst PITR_ACTIONS = [\"status\", \"restore\", \"cutover\", \"discard\"] as const;\n\n/**\n * `db backup [action] [filename]`, resolved in one strict parse.\n *\n * Both halves were reachable by the old operand filter, and both are\n * destructive: `rebase cloud db backup -p acme` read `--project`'s value as the\n * ACTION (falling through to a list, so the flag silently changed what ran),\n * and `db backup restore -p acme` read it as the FILENAME — a restore staged\n * over the live database, named after the project slug. An undeclared flag was\n * dropped instead of refused, which is the same failure one step quieter: `db\n * backup --dry-run` ran a list, having silently discarded the flag that was\n * supposed to change what it did.\n *\n * Exported so its tests drive the real parser.\n */\nexport function resolveBackupArgs(rawArgs: string[]) {\n const { flags, positionals } = parseCloudArgs({\n // `--yes` is not declared here: `parseCloudArgs` merges the global spec\n // in, and a per-command key that repeats a global one OVERRIDES it in\n // that merge. Identical here, so it was harmless — but it is the same\n // shape as `webhooks create --url`, which was not.\n spec: {},\n rawArgs,\n commandWords: 3, // cloud db backup\n command: \"cloud db backup\",\n maxPositionals: 2 // <action> [filename]\n });\n return { flags,\naction: positionals[0] || \"list\",\nfilename: positionals[1] };\n}\n\nasync function backupCommand(rawArgs: string[]): Promise<void> {\n const { flags: args, action, filename: backupFile } = resolveBackupArgs(rawArgs);\n requireKnownAction(\"db backup\", action, BACKUP_ACTIONS);\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n try {\n if (action === \"create\") {\n const res = await client.functions.invoke<{ success: boolean; backup?: BackupRow; error?: string }>(\n \"backup\",\n { projectId,\ntype: \"manual\" },\n { path: \"create\" }\n );\n if (!res.success) fail(res.error || \"Backup failed.\");\n emit(\n () => success(`Backup created: ${backupName(res.backup) ?? \"(unnamed)\"}`),\n { success: true,\nbackup: res.backup ?? null }\n );\n return;\n }\n\n if (action === \"restore\") {\n const filename = backupFile;\n if (!filename) fail(\"Usage: rebase cloud db backup restore <filename>\", undefined, \"usage\");\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Restore \"${filename}\" over the current database for project ${projectRef}?`\n });\n const res = await client.functions.invoke<{ success: boolean; message?: string; error?: string }>(\n \"backup\",\n { projectId,\nfilename },\n { path: \"restore\" }\n );\n if (!res.success) fail(res.error || \"Restore failed.\");\n emit(() => success(res.message || \"Restore complete\"), { success: true,\nmessage: res.message ?? null });\n return;\n }\n\n if (action === \"status\") {\n const res = await client.functions.invoke<Record<string, unknown>>(\"backup\", undefined, {\n method: \"GET\",\n path: `backup-status/${projectId}`\n });\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 💾 Automated backups — project ${projectRef}`));\n console.log(\"\");\n keyValues([\n [\"Enabled\", res.enabled ? chalk.green(\"yes\") : chalk.yellow(\"no\")],\n [\"Reason\", String(res.reason ?? \"\")],\n [\"Database type\", String(res.databaseType ?? \"\")],\n [\"Last backup\", (res.lastSuccessfulBackup as string) ?? undefined],\n [\n \"Recovery window\",\n res.recoveryWindow\n ? `${(res.recoveryWindow as { from: string }).from} → ${(res.recoveryWindow as { to: string }).to}`\n : undefined\n ]\n ]);\n console.log(\"\");\n },\n res\n );\n return;\n }\n\n if (action === \"download\") {\n const filename = backupFile;\n if (!filename) fail(\"Usage: rebase cloud db backup download <filename>\", undefined, \"usage\");\n const res = await client.functions.invoke<{ url: string; name: string; size: number }>(\"backup\", undefined, {\n method: \"GET\",\n path: `download/${projectId}/${encodeURIComponent(filename)}`\n });\n // Print the signed URL rather than downloading the file — downloading\n // is a user-consented action, and the URL is what the operator/agent\n // needs to fetch it themselves.\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` ${res.name}`) + chalk.gray(` ${(res.size / 1024 / 1024).toFixed(1)} MB`));\n console.log(` ${chalk.cyan(res.url)}`);\n console.log(\"\");\n console.log(chalk.gray(\" Short-lived signed URL — fetch it with curl/wget.\"));\n console.log(\"\");\n },\n { name: res.name,\nsize: res.size,\nurl: res.url }\n );\n return;\n }\n\n // default: list — the only word that reaches here, because\n // `requireKnownAction` refused every other one before the client was\n // built.\n const res = await client.functions.invoke<{ backups: BackupRow[] }>(\n \"backup\",\n undefined,\n { method: \"GET\",\npath: `list/${projectId}` }\n );\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 💾 Backups — project ${projectRef}`));\n console.log(\"\");\n if (!res.backups?.length) {\n console.log(chalk.gray(\" No backups yet. Create one with `rebase cloud db backup create`.\"));\n console.log(\"\");\n return;\n }\n for (const b of res.backups) {\n const detail = [b.type, backupSize(b), b.date].filter(Boolean).join(\" \");\n console.log(` ${chalk.bold(backupName(b) ?? \"(unnamed)\")} ${chalk.gray(detail)}`);\n }\n console.log(\"\");\n },\n { projectId,\nbackups: res.backups ?? [] }\n );\n } catch (e) {\n reportError(e, \"Backup operation failed\");\n }\n}\n\n/* ─── PITR (point-in-time recovery) ────────────────────────────── */\n\n/**\n * `rebase cloud db pitr <status|restore|cutover|discard>`.\n *\n * A PITR restore is STAGED, not applied: `restore` creates a recovered copy of\n * the database beside the live one — the application is NOT repointed and the\n * original is left running and unchanged. `cutover` is the separate, explicit\n * step that repoints the app at the recovered copy (and restarts it). `discard`\n * removes a staged copy; the server refuses to discard a copy that has been cut\n * over to (it is now the live database). Every mutating step requires `--yes` in\n * non-interactive use, and the CLI surfaces these staged semantics honestly.\n */\nasync function pitrCommand(rawArgs: string[]): Promise<void> {\n // Same shape as `db backup`: `db pitr -p acme` used to read the project slug\n // as the action, and a PITR action decides between reporting, staging a\n // recovered copy, and repointing the live app at one.\n const { flags: args, positionals } = parseCloudArgs({\n // `--yes` comes from the global spec — see `resolveBackupArgs`.\n spec: { \"--target\": String },\n rawArgs,\n commandWords: 3, // cloud db pitr\n command: \"cloud db pitr\",\n maxPositionals: 1\n });\n const action = positionals[0] || \"status\";\n requireKnownAction(\"db pitr\", action, PITR_ACTIONS);\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n try {\n if (action === \"status\") {\n const res = await client.functions.invoke<Record<string, unknown>>(\"backup\", undefined, {\n method: \"GET\",\n path: `pitr-status/${projectId}`\n });\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` ⏱ Point-in-time recovery — project ${projectRef}`));\n console.log(\"\");\n keyValues([\n [\"Available\", res.available ? chalk.green(\"yes\") : chalk.yellow(\"no\")],\n [\"First recoverable\", (res.firstRecoverabilityPoint as string) ?? undefined],\n [\"Last backup\", (res.lastSuccessfulBackup as string) ?? undefined],\n [\"Message\", (res.message as string) ?? undefined]\n ]);\n console.log(\"\");\n },\n res\n );\n return;\n }\n\n if (action === \"restore\") {\n const target = args[\"--target\"];\n if (!target) fail(\"Usage: rebase cloud db pitr restore --target <ISO timestamp>\", undefined, \"usage\");\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Stage a point-in-time recovery of project ${projectRef} at ${target}? (stages a copy; does not repoint your app)`\n });\n const res = await client.functions.invoke<Record<string, unknown>>(\n \"backup\",\n // acknowledgeNoCutover is required by the server: the caller must\n // affirm this only STAGES a copy. The confirm prompt above says so.\n { projectId,\ntargetTime: target,\nacknowledgeNoCutover: true },\n { path: \"pitr-restore\" }\n );\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.yellow(` ⏳ ${String(res.message ?? \"Recovery staged.\")}`));\n console.log(chalk.gray(\" Watch progress with `rebase cloud db pitr status`, then `rebase cloud db pitr cutover --yes`.\"));\n console.log(\"\");\n },\n res\n );\n return;\n }\n\n if (action === \"cutover\") {\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Cut project ${projectRef} over to the staged recovery? This repoints and restarts your application.`\n });\n const res = await client.functions.invoke<Record<string, unknown>>(\"backup\", { projectId }, { path: \"pitr-restore-cutover\" });\n emit(\n () => {\n console.log(\"\");\n console.log(String(res.message ?? \"Cutover requested.\"));\n console.log(\"\");\n },\n res\n );\n return;\n }\n\n if (action === \"discard\") {\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Discard the staged recovery for project ${projectRef}? This deletes the staged copy and its storage.`\n });\n const res = await client.functions.invoke<Record<string, unknown>>(\"backup\", { projectId }, { path: \"pitr-restore-discard\" });\n emit(\n () => success(String(res.message ?? \"Staged restore discarded.\")),\n res\n );\n return;\n }\n\n // No tail: `requireKnownAction` refused every word that is not one of\n // the four, before the client was built. The refusal that used to sit\n // here was behind a login and a project lookup, so a typo answered\n // `not_logged_in` rather than naming the typo.\n } catch (e) {\n reportError(e, \"PITR operation failed\");\n }\n}\n\nexport function printDbHelp(): void {\n printGroupHelp({\n command: \"cloud db\",\n title: \"Database & backups\",\n actions: [\n { action: \"list\",\nsection: \"Database\",\ndescription: \"List databases attached to the project\" },\n {\n action: \"create\",\n section: \"Database\",\n description: \"Attach a managed or bring-your-own database\",\n flags: [\n [\"--type <managed|byodb>\", \"Which kind to attach\"],\n [\"--connection-string <url>\", \"The external PostgreSQL URL, for byodb\"],\n [\"--wait\", \"Wait for the managed database to be reachable\"],\n [\"--timeout <seconds>\", \"Ceiling on that wait\"]\n ]\n },\n {\n action: \"info\",\n section: \"Database\",\n description: \"Connection details\",\n flags: [[\"--reveal\", \"Include the password (owner or admin). Without it, the value is masked\"]]\n },\n {\n action: \"connect\",\n section: \"Database\",\n description: \"Open a local port that IS the project's database\",\n flags: [\n [\"--port <n>\", \"Local port to listen on. Default: 5432\"],\n [\"--reveal\", \"Print the password in the connection URL\"]\n ]\n },\n { action: \"test\",\nsection: \"Database\",\ndescription: \"Test database connectivity\" },\n\n { action: \"backup list\",\nsection: \"Backups\",\ndescription: \"List backups\" },\n { action: \"backup create\",\nsection: \"Backups\",\ndescription: \"Create a manual backup\" },\n { action: \"backup restore\",\nargs: \"<file>\",\nsection: \"Backups\",\ndescription: \"Restore a backup\" },\n { action: \"backup status\",\nsection: \"Backups\",\ndescription: \"Automated-backup health\" },\n { action: \"backup download\",\nargs: \"<file>\",\nsection: \"Backups\",\ndescription: \"Signed URL for a backup\" },\n\n { action: \"pitr status\",\nsection: \"Point-in-time recovery\",\ndescription: \"The window a recovery can target\" },\n {\n action: \"pitr restore\",\n section: \"Point-in-time recovery\",\n description: \"Stage a recovery. Does NOT repoint the app\",\n flags: [[\"--target <ISO>\", \"The instant to recover to\"]]\n },\n { action: \"pitr cutover\",\nsection: \"Point-in-time recovery\",\ndescription: \"Repoint the app at the staged recovery\" },\n { action: \"pitr discard\",\nsection: \"Point-in-time recovery\",\ndescription: \"Delete a staged recovery\" }\n ],\n notes: [\n \"A project has exactly one database: `create` refuses rather than attaching a second, because\",\n \"which of two rows a deploy uses is undefined.\",\n \"A managed database is provisioned at the project's FIRST DEPLOY, so `test` failing before then\",\n \"is not a fault.\",\n \"The host `info` reports is inside the platform's cluster — your backend's address for it, not\",\n \"one your laptop can resolve. `connect` is what makes it reachable from here.\"\n ]\n });\n}\n","/**\n * `rebase cloud projects` — list / create / info / delete.\n */\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport {\n requireClient,\n parseCloudArgs,\n requireProjectRef,\n resolveProjectRef,\n getContextOrg,\n readLink,\n writeLink,\n colorStatus,\n keyValues,\n fetchTenantBaseDomain,\n fetchDeployTargets,\n type DeployTarget,\n projectHost,\n success,\n fail,\n warn,\n reportError,\n emit,\n note,\n noteBlank,\n confirmDestructive,\n type CloudClient,\n cloudRows,\n requireCloudRow\n} from \"./context\";\nimport { buildDialPatch } from \"./resources\";\nimport { attachDatabaseRow } from \"./databases\";\n\ninterface ProjectRow {\n id: string | number;\n name?: string;\n subdomain?: string;\n /**\n * Where the project is actually served. Computed by the control plane from\n * the project's cluster, which the CLI cannot read itself (admin-only RLS).\n * Absent on control planes older than that hook — `projectHost` falls back.\n */\n host?: string;\n customDomain?: string;\n gitRepoUrl?: string;\n gitBranch?: string;\n provider?: string;\n region?: string;\n status?: string;\n organization?: string | number;\n createdById?: string;\n}\n\n/* ─── list ─────────────────────────────────────────────────────── */\n\nexport async function listProjects(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud projects\",\nmaxPositionals: 0 });\n const { client, url } = await requireClient(rawArgs);\n const org = getContextOrg(url);\n try {\n const [projects, baseDomain] = await Promise.all([\n client.data.collection(\"projects\").find({\n where: org ? { organization: [\"==\", org] } : undefined,\n orderBy: [\"name\", \"asc\"],\n limit: 100\n }).then((res) => cloudRows<ProjectRow>(res.data)),\n fetchTenantBaseDomain(client, url)\n ]);\n\n const linkedId = readLink()?.projectId;\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(\" 📦 Projects\") + (org ? chalk.gray(` (org ${org})`) : \"\"));\n console.log(\"\");\n\n if (projects.length === 0) {\n console.log(\n chalk.gray(\" No projects yet. Create one with `rebase cloud projects create`.\")\n );\n console.log(\"\");\n return;\n }\n\n for (const p of projects) {\n const marker = String(p.id) === linkedId ? chalk.green(\" ●\") : \" \";\n console.log(`${marker}${chalk.bold(p.name ?? \"(unnamed)\")} ${chalk.gray(`[${p.subdomain ?? p.id}]`)} ${colorStatus(p.status)}`);\n console.log(` ${chalk.gray(projectHost(p, baseDomain) ?? \"—\")}${p.provider ? chalk.gray(` · ${p.provider}`) : \"\"}`);\n }\n console.log(\"\");\n },\n {\n org: org ?? null,\n projects: projects.map((p) => ({\n id: String(p.id),\n name: p.name ?? null,\n slug: p.subdomain ?? null,\n host: projectHost(p, baseDomain) ?? null,\n status: p.status ?? null,\n provider: p.provider ?? null,\n linked: String(p.id) === linkedId\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list projects\");\n }\n}\n\n/* ─── create ───────────────────────────────────────────────────── */\n\n/**\n * Default region per provider. Required on create; the rest is dialled.\n *\n * There used to be a `vmSize` here too — `e2-small`, `cx21` — naming a machine\n * on a price list this platform does not buy from. The column was dropped on\n * 2026-08-20 and this went on sending it, which a control plane can only ignore\n * or refuse. What a project reserves is a set of dials now, and a project that\n * sets none takes the platform default.\n */\nfunction providerDefaults(provider: string): { region: string } {\n switch (provider) {\n case \"gcp\":\n return { region: \"europe-west1\" };\n case \"aws\":\n return { region: \"us-east-1\" };\n default:\n // fsn1, not nbg1: Falkenstein is the Hetzner region the control\n // plane prices and stands capacity in; Nuremberg is in neither list,\n // so a project defaulted there was refused as an unknown region.\n return { region: \"fsn1\" };\n }\n}\n\n/**\n * Where this project says it runs.\n *\n * `provider`/`region` are a *request*: no code downstream reads them to pick a\n * deploy target — that comes from the project's cluster record or the ambient\n * in-cluster context (saas/backend/src/k8s/resolve.ts). So a wrong value here is\n * never contradicted by a failure; it just sits in the record. The CLI used to\n * default to `hetzner`/`nbg1` unconditionally, which is how projects running on\n * our GKE cluster came to describe themselves as Hetzner in the console — and\n * `provider` also decides which substrate's rules a project's dials are clamped\n * to — Autopilot's 250m floor and 1:1-6.5:1 band do not apply on Hetzner or EKS\n * — so a wrong value here resizes pods, it is not a cosmetic slip.\n *\n * The control plane already publishes the infrastructure that actually exists,\n * and the console's create wizard reads it. Ask the same question here.\n *\n * Exported for tests: the decision is pure, so it can be pinned without a\n * control plane. The fetching and the exit live in `resolveRequestedTarget`.\n *\n * @param requested `--provider`, if the caller named one. An explicit flag wins:\n * it is the caller stating intent, and `deploy` corrects the record anyway.\n * @param targets What the control plane says exists, or `undefined` when it\n * cannot say — an older deployment with no `platform-config`, or a failed\n * request. That is different from an empty list, which is a control plane\n * stating it has no infrastructure at all.\n * @returns the target to record, or `null` when the control plane answered that\n * there is none.\n */\nexport function chooseRequestedTarget(\n requested: string | undefined,\n targets: DeployTarget[] | undefined\n): { provider: string; region?: string } | null {\n if (requested) {\n // An explicit provider takes the region of the first target the control\n // plane offers on it: `--provider hetzner` means \"the Hetzner region\n // we have capacity in\", which the control plane knows and a\n // per-provider guess does not. No such target, no region — the caller\n // may still name one, or the per-provider default applies.\n const offered = targets?.find((t) => t.provider === requested);\n return { provider: requested,\nregion: offered?.region?.trim() || undefined };\n }\n\n // Keep the historical default against a control plane that cannot answer,\n // rather than refusing to create a project against it.\n if (!targets) return { provider: \"hetzner\",\nregion: undefined };\n\n if (targets.length === 0) return null;\n\n // The resolver returns targets in its own preference order, and the first is\n // the one a deploy would use.\n const [target] = targets;\n return { provider: target.provider,\nregion: target.region?.trim() || undefined };\n}\n\nasync function resolveRequestedTarget(\n client: CloudClient,\n url: string,\n requested: string | undefined\n): Promise<{ provider: string; region?: string }> {\n const chosen = chooseRequestedTarget(requested, await fetchDeployTargets(client, url));\n if (!chosen) {\n fail(\n \"This control plane has no deploy targets configured.\",\n `Register a cluster, or pass ${chalk.bold(\"--provider\")} and ${chalk.bold(\"--region\")} to record one anyway.`,\n \"no_deploy_targets\"\n );\n }\n return chosen;\n}\n\n/** The flags `rebase cloud projects create` takes. */\nexport const CREATE_PROJECT_FLAGS = {\n \"--name\": String,\n \"--subdomain\": String,\n \"--repo\": String,\n \"--branch\": String,\n \"--provider\": String,\n \"--region\": String,\n \"--org\": String,\n \"--link\": Boolean,\n /**\n * Which database the new project gets — `managed` (the default), `byodb`,\n * or `none`.\n *\n * A default rather than a prompt, and `managed` rather than `none`, because\n * the state this removes is not a missing convenience: a project with no\n * database is written `status: \"provisioning\"` and can never deploy, and\n * nothing in that word says a second command is owed. Attaching one here\n * means the two-command sequence that every project needs is one command,\n * and `--db none` is there for the case that genuinely wants to decide later.\n *\n * Distinct from `--db-cpu`/`--db-instances` next to it, which are resource\n * dials on a database that exists. This is whether there is one.\n */\n \"--db\": String,\n /** For `--db byodb`. Same spelling as `rebase cloud db create` uses. */\n \"--connection-string\": String,\n \"-n\": \"--name\",\n // The resource dials, same spelling as `rebase cloud compute set`. Every\n // one is optional: a project that names none takes the platform default.\n // `--vm-size` used to sit here and named a machine on a price list this\n // platform does not buy from; the column it wrote was dropped on 2026-08-20.\n \"--cpu\": String,\n \"--memory\": String,\n \"--replicas\": String,\n \"--spot\": String,\n \"--scale-to-zero\": String,\n \"--db-instances\": String,\n \"--db-cpu\": String,\n \"--db-memory\": String,\n \"--storage\": String\n} as const;\n\nexport async function createProject(rawArgs: string[]): Promise<void> {\n // Strict: every value here ends up in the project record, and the permissive\n // parse dropped a mistyped one silently — `--subdomian shop` created a\n // project on a generated subdomain, and a subdomain is not editable in\n // passing afterwards.\n const { flags: args } = parseCloudArgs({\n spec: CREATE_PROJECT_FLAGS,\n rawArgs,\n commandWords: 3, // cloud projects create\n command: \"cloud projects create\",\n maxPositionals: 0\n });\n\n const { client, url } = await requireClient(rawArgs);\n const org = args[\"--org\"] || getContextOrg(url);\n if (!org) {\n fail(\n \"No organization selected.\",\n `Pass ${chalk.bold(\"--org <id>\")} or run ${chalk.bold(\"rebase cloud use\")}.`,\n \"no_org\"\n );\n }\n\n // Prompt only for the essentials, and only when attached to a terminal —\n // a headless `projects create --name X --subdomain Y` must never block.\n // repo/branch/provider are optional and default sensibly.\n const prompts: Array<{ type: \"input\"; name: string; message: string }> = [];\n if (!args[\"--name\"]) prompts.push({ type: \"input\",\nname: \"name\",\nmessage: \"Project name:\" });\n if (!args[\"--subdomain\"]) prompts.push({ type: \"input\",\nname: \"subdomain\",\nmessage: \"Subdomain:\" });\n const answers = prompts.length && process.stdin.isTTY\n ? await inquirer.prompt(prompts)\n : {};\n const a = answers as Record<string, string>;\n\n const name = (args[\"--name\"] || a.name || \"\").trim();\n const subdomain = (args[\"--subdomain\"] || a.subdomain || \"\").trim().toLowerCase();\n const gitRepoUrl = (args[\"--repo\"] || a.repo || \"\").trim();\n const gitBranch = (args[\"--branch\"] || a.branch || \"main\").trim();\n const target = await resolveRequestedTarget(\n client,\n url,\n (args[\"--provider\"] || a.provider)?.trim() || undefined\n );\n const provider = target.provider;\n // region is required by the control plane; default sensibly per provider so\n // a headless `projects create` needs only name + subdomain. The target's own\n // region wins where it has one: a per-provider guess is how a GKE project\n // ended up recorded in `nbg1`.\n const defaults = providerDefaults(provider);\n const region = (args[\"--region\"] || target.region || defaults.region).trim();\n\n // Compute, if the caller named any. The same flags `compute set` takes,\n // parsed by the same function — a second parser here would be the place the\n // two spellings of a dial drift apart. Nothing is required: a project that\n // names no dial takes the platform default and can change it afterwards.\n const dials = buildDialPatch(rawArgs, { requireOne: false });\n if (dials.error) fail(dials.error, undefined, \"bad_request\");\n\n // Validated before the project row is written, not after: a typo'd `--db`\n // discovered afterwards leaves a project that exists and cannot deploy —\n // exactly the state this flag is here to remove.\n const dbChoice = (args[\"--db\"] ?? \"managed\").trim().toLowerCase();\n if (![\"managed\", \"byodb\", \"none\"].includes(dbChoice)) {\n fail(`--db must be managed, byodb or none (got \"${args[\"--db\"]}\").`, undefined, \"bad_request\");\n }\n if (dbChoice === \"byodb\" && !args[\"--connection-string\"]) {\n fail(\n \"--db byodb needs the database to point at.\",\n `Pass ${chalk.bold(\"--connection-string <url>\")}.`,\n \"input_required\"\n );\n }\n\n if (!name || !subdomain) {\n fail(\n \"Name and subdomain are required.\",\n `Pass ${chalk.bold(\"--name <name>\")} and ${chalk.bold(\"--subdomain <slug>\")}.`,\n \"input_required\"\n );\n }\n\n // Validate subdomain availability up front for a clean error.\n try {\n const check = await client.functions.invoke<{ available: boolean; reason?: string }>(\n \"check-subdomain\",\n { subdomain }\n );\n if (!check.available) {\n fail(\n `Subdomain \"${subdomain}\" is not available${check.reason ? ` (${check.reason})` : \"\"}.`,\n undefined,\n \"subdomain_unavailable\"\n );\n }\n } catch {\n // If the control plane has no such function, skip the pre-check —\n // the collection hook still enforces uniqueness on create.\n }\n\n try {\n const user = await client.auth.getUser();\n if (!user) {\n fail(\"Session is no longer valid.\", \"Run `rebase cloud login` again.\", \"session_invalid\");\n }\n const created = requireCloudRow<ProjectRow>(await client.data.collection(\"projects\").create({\n name,\n subdomain,\n gitRepoUrl,\n gitBranch,\n provider,\n region,\n ...dials.patch,\n organization: org,\n createdById: user.uid,\n status: \"provisioning\"\n }), \"project\");\n\n const host = projectHost(created, await fetchTenantBaseDomain(client, url));\n const linked = Boolean(args[\"--link\"]);\n if (linked) {\n writeLink({ url,\nprojectId: String(created.id),\nslug: created.subdomain,\nprojectName: name,\norgId: String(org) });\n }\n\n // Attached in its own try, and reported separately, because the two\n // halves fail independently. A project that exists with no database is\n // the state worth naming loudly — reporting the whole command as failed\n // would hide a project that was in fact created, and reporting it as\n // succeeded would hide that the project cannot deploy.\n const database = await attachRequestedDatabase(client, {\n projectId: String(created.id),\n choice: dbChoice,\n connectionString: args[\"--connection-string\"],\n projectRef: created.subdomain ?? String(created.id)\n });\n\n if (database.warning) warn(database.warning[0], database.warning[1]);\n\n success(`Created project ${chalk.bold(name)}`);\n emit(\n () => {\n keyValues([\n [\"Slug\", String(created.subdomain ?? \"\")],\n [\"URL\", host],\n [\"Provider\", provider],\n [\"Branch\", gitBranch],\n [\"Database\", database.line]\n ]);\n if (linked) note(chalk.gray(\"Linked this directory to the new project.\"));\n noteBlank();\n for (const line of database.notes) note(chalk.gray(line));\n note(chalk.gray(`Deploy it with: ${chalk.bold(`rebase cloud deploy --project ${created.subdomain ?? created.id}`)}`));\n noteBlank();\n },\n {\n success: true,\n id: String(created.id),\n name,\n slug: created.subdomain ?? null,\n host: host ?? null,\n provider,\n region,\n dials: dials.patch,\n branch: gitBranch,\n org: String(org),\n linked,\n database: database.payload\n }\n );\n } catch (e) {\n reportError(e, \"Failed to create project\");\n }\n}\n\n/**\n * Attach the database `--db` asked for, and describe what happened.\n *\n * Never throws. The project already exists by the time this runs, so a failure\n * here is a *partial* success and has to be reported as one — with the exact\n * command that finishes the job. Turning it into an exception would report the\n * whole `projects create` as failed and leave a real project behind, which is\n * the worst of both readings.\n */\nasync function attachRequestedDatabase(\n client: CloudClient,\n input: { projectId: string; choice: string; connectionString?: string; projectRef: string }\n): Promise<{\n line: string;\n notes: string[];\n /** `[message, hint]` — raised through `warn`, so it survives JSON mode. */\n warning?: [string, string];\n payload: Record<string, unknown>;\n}> {\n if (input.choice === \"none\") {\n return {\n line: chalk.yellow(\"none\"),\n // A note, not a warning: the caller asked for this, and the only\n // thing owed is the command that undoes it.\n notes: [\n \"No database attached (--db none). This project cannot deploy until one is:\",\n \" rebase cloud db create --type managed\"\n ],\n payload: { attached: false,\ntype: null,\nreason: \"requested_none\" }\n };\n }\n\n try {\n const row = await attachDatabaseRow(client, {\n projectId: input.projectId,\n type: input.choice,\n connectionString: input.connectionString\n });\n return {\n line: input.choice === \"managed\"\n ? `managed ${chalk.gray(\"· created at the first deploy\")}`\n : `byodb ${chalk.gray(\"· not tested (`rebase cloud db test`)\")}`,\n notes: [],\n payload: { attached: true,\nid: String(row.id),\ntype: input.choice,\nmaterializedAt: input.choice === \"managed\" ? \"first_deploy\" : \"now\" }\n };\n } catch (e) {\n const message = e instanceof Error ? e.message : String(e);\n return {\n line: chalk.red(\"not attached\"),\n notes: [],\n // A warning, because the caller did NOT ask for this: they now hold\n // a project that exists and cannot deploy. `warn` writes to stderr\n // in every output mode, so a piped run still sees it beside the\n // `database.attached: false` in the payload.\n warning: [\n `The project was created, but attaching its ${input.choice} database failed: ${message}`,\n `Finish it with: rebase cloud db create --type ${input.choice} --project ${input.projectRef}`\n ],\n payload: { attached: false,\ntype: input.choice,\nreason: \"attach_failed\",\nerror: message }\n };\n }\n}\n\n/* ─── info ─────────────────────────────────────────────────────── */\n\n/**\n * Which project `projects info` / `projects delete` acts on.\n *\n * The id is optional — omitted, it falls back to `--project` or the link file —\n * and the dispatcher used to read it off `positionals()`, which skips only\n * LEADING `-` tokens and declares only the global cloud flags. So an undeclared\n * flag written after the action became the id: `rebase cloud projects delete\n * --force` looked up a project named \"--force\" and reported it missing, rather\n * than saying there is no such flag. Benign next to the deletes and writes the\n * rest of this family aimed at the wrong resource, but the same mistake, and\n * `positionals()` has no spec with which to do better — the handler's own\n * module does.\n *\n * Exported so its tests drive the real parser rather than a copy of it.\n */\nexport function resolveProjectArg(rawArgs: string[], action: \"info\" | \"delete\"): string {\n const { positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud projects <action>\n command: `cloud projects ${action}`,\n maxPositionals: 1\n });\n return positionals[0] || requireProjectRef(rawArgs);\n}\n\n/** What `capacity` reports for a project's database, when it reports anything. */\ninterface DatabaseCapacity {\n usedMb: number;\n limitMb: number;\n usedFraction: number | null;\n locked: boolean;\n state: \"locked\" | \"warning\" | \"ok\";\n detail: string;\n}\n\n/**\n * A project's database capacity, or null.\n *\n * Swallows every failure on purpose. This decorates `status`; a control plane\n * that predates the `capacity` function 404s here, and an older CLI talking to a\n * newer one must still print the project. Losing the capacity line is a missing\n * nicety — failing the whole command over it would be the bug.\n */\nasync function fetchCapacity(client: CloudClient, projectId: string): Promise<DatabaseCapacity | null> {\n try {\n const res = await client.functions.invoke<{ database?: DatabaseCapacity | null }>(\n \"capacity\",\n undefined,\n { method: \"GET\", path: projectId }\n );\n return res?.database ?? null;\n } catch {\n return null;\n }\n}\n\nexport async function projectInfo(rawArgs: string[], projectRef: string): Promise<void> {\n const { client, url } = await requireClient(rawArgs);\n try {\n const projectId = await resolveProjectRef(projectRef, client);\n const p = (await client.data.collection(\"projects\").findById(projectId)) as ProjectRow | undefined;\n if (!p) fail(`Project ${projectRef} not found.`, undefined, \"project_not_found\");\n\n const [db, lastDeploy, baseDomain, capacity] = await Promise.all([\n firstRow(client, \"databases\", projectId),\n latestDeployment(client, projectId),\n fetchTenantBaseDomain(client, url),\n fetchCapacity(client, projectId)\n ]);\n\n emit(\n () => {\n console.log(\"\");\n console.log(` ${chalk.bold(p.name ?? \"(unnamed)\")} ${chalk.gray(`[${p.subdomain ?? p.id}]`)} ${colorStatus(p.status)}`);\n console.log(\"\");\n keyValues([\n [\"Subdomain\", projectHost(p, baseDomain)],\n [\"Custom domain\", p.customDomain],\n [\"Repository\", p.gitRepoUrl],\n [\"Branch\", p.gitBranch],\n [\"Provider\", p.provider],\n [\"Region\", p.region],\n [\"Organization\", p.organization !== undefined ? String(p.organization) : undefined],\n [\"Database\", db ? `${db.type} (${colorStatus(db.connectionStatus as string)})` : \"none\"],\n // Only when there is a ceiling to report against. A project\n // on a dedicated database has none, and printing \"0 MB / 0 MB\"\n // for it would read as full.\n [\"Storage\", capacity && capacity.limitMb > 0\n ? `${capacity.usedMb} MB / ${capacity.limitMb} MB${\n capacity.usedFraction !== null ? ` (${(capacity.usedFraction * 100).toFixed(0)}%)` : \"\"\n }`\n : undefined],\n [\"Last deploy\", lastDeploy ? `${colorStatus(lastDeploy.status)} · ${fmtDate(lastDeploy.createdAt)}` : \"never\"]\n ]);\n // The whole point of the feature: a tenant hitting the ceiling\n // used to find out because their app stopped answering. Say it\n // here, where they already look, and say what happens next.\n if (capacity && capacity.state !== \"ok\") {\n console.log(\"\");\n console.log(\n capacity.state === \"locked\"\n ? ` ${chalk.red.bold(\"✗ Database locked — over its storage limit\")}`\n : ` ${chalk.yellow.bold(\"⚠ Database approaching its storage limit\")}`\n );\n console.log(` ${chalk.gray(capacity.detail)}`);\n }\n console.log(\"\");\n },\n {\n id: String(p.id),\n name: p.name ?? null,\n slug: p.subdomain ?? null,\n host: projectHost(p, baseDomain) ?? null,\n customDomain: p.customDomain ?? null,\n repository: p.gitRepoUrl ?? null,\n branch: p.gitBranch ?? null,\n provider: p.provider ?? null,\n region: p.region ?? null,\n status: p.status ?? null,\n org: p.organization !== undefined ? String(p.organization) : null,\n database: db ? { type: db.type ?? null,\nconnectionStatus: db.connectionStatus ?? null,\ncapacity: capacity ?? null } : null,\n lastDeploy: lastDeploy\n ? { id: String(lastDeploy.id),\nstatus: lastDeploy.status ?? null,\ncreatedAt: lastDeploy.createdAt ?? null }\n : null\n }\n );\n } catch (e) {\n reportError(e, \"Failed to load project\");\n }\n}\n\n/* ─── delete ───────────────────────────────────────────────────── */\n\nexport async function deleteProject(rawArgs: string[], projectRef: string): Promise<void> {\n const { flags: args } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud projects delete\n command: \"cloud projects delete\",\n maxPositionals: 1 // [id]\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await resolveProjectRef(projectRef, client);\n\n const p = (await client.data.collection(\"projects\").findById(projectId).catch(() => undefined)) as\n | ProjectRow\n | undefined;\n if (!p) fail(`Project ${projectRef} not found.`, undefined, \"project_not_found\");\n\n // Through the shared guard, not a bare `inquirer.prompt`. This was the one\n // destructive command in the family that rolled its own confirm, and it was\n // the only one that could HANG: piped or agent-run, the other nine refuse\n // with `confirmation_required` while this one sat on a prompt reading a\n // stdin that would never answer — on the single command whose whole job is\n // to tear a project down.\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Permanently delete project \"${p.name ?? projectRef}\" (${p.subdomain ?? projectRef})? This tears down its deployment.`\n });\n\n try {\n await client.data.collection(\"projects\").delete(projectId);\n success(`Deleted project ${chalk.bold(p.name ?? projectId)}`);\n emit(() => {}, {\n success: true,\n id: projectId,\n name: p.name ?? null,\n slug: p.subdomain ?? null\n });\n } catch (e) {\n reportError(e, \"Failed to delete project\");\n }\n}\n\n/* ─── shared helpers (used by other subcommands too) ───────────── */\n\nexport async function firstRow(\n client: CloudClient,\n collection: string,\n projectId: string\n): Promise<Record<string, unknown> | undefined> {\n const res = await client.data.collection(collection).find({\n where: { project: [\"==\", projectId] },\n limit: 1\n });\n return res.data[0];\n}\n\nexport async function latestDeployment(\n client: CloudClient,\n projectId: string\n): Promise<{ id: string | number; status?: string; createdAt?: string; logs?: string } | undefined> {\n const res = await client.data.collection(\"deployments\").find({\n where: { project: [\"==\", projectId] },\n orderBy: [\"createdAt\", \"desc\"],\n limit: 1\n });\n return res.data[0] as { id: string | number; status?: string; createdAt?: string; logs?: string } | undefined;\n}\n\nexport function fmtDate(value: string | undefined): string {\n if (!value) return \"—\";\n const d = new Date(value);\n return isNaN(d.getTime()) ? value : d.toLocaleString();\n}\n","/**\n * Deploying a project as a managed **bundle** rather than a source build.\n *\n * `rebase cloud deploy --bundle` builds the bundle, tars it, uploads it to the\n * control plane's bundle endpoint, and triggers a deploy carrying the bundle id\n * and its generated manifest. The control plane resolves a runtime from the\n * manifest's range and runs the platform image with this bundle — the managed\n * path. A project not in managed mode, or one whose bundle fails intake, is told\n * so by the control plane; this side just packages and hands it over.\n *\n * The pieces here are separated from the network calls so they can be tested: the\n * manifest read, the tar packaging, and the request body assembly are pure enough\n * to check without a control plane.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { spawn, execFileSync } from \"child_process\";\nimport type { RebaseBundleManifest } from \"@rebasepro/types\";\nimport type { RebuildSource } from \"./rebuild-source\";\nimport { toolStdio } from \"../../utils/tool-stdio\";\n\n/** Read and shallow-validate a built bundle's manifest. */\nexport function readBundleManifest(bundleDir: string): RebaseBundleManifest {\n const manifestPath = path.join(bundleDir, \"manifest.json\");\n if (!fs.existsSync(manifestPath)) {\n throw new Error(\n `No manifest.json in ${bundleDir}. Run \\`rebase build\\` first.`\n );\n }\n let manifest: RebaseBundleManifest;\n try {\n manifest = JSON.parse(fs.readFileSync(manifestPath, \"utf8\")) as RebaseBundleManifest;\n } catch (err) {\n throw new Error(`${manifestPath} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`);\n }\n if (typeof manifest.bundleFormat !== \"number\" || !manifest.runtime?.range) {\n throw new Error(`${manifestPath} is not a valid bundle manifest.`);\n }\n return manifest;\n}\n\n/**\n * The control plane's cap on an uploaded bundle: its `MAX_BUNDLE_BYTES`, which\n * it checks before reading the body.\n */\nexport const MAX_BUNDLE_UPLOAD_BYTES = 100 * 1024 * 1024;\n\n/**\n * Tar a built bundle into a gzipped archive.\n *\n * `node_modules` goes in only with `withModules`: a tree the build vendored for\n * the runtime's platform is the point of vendoring, while one installed into a\n * prebuilt bundle by hand was installed for whatever machine ran it.\n */\nexport function packBundle(bundleDir: string, outPath: string, options: { withModules?: boolean } = {}): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\n \"tar\",\n // `--no-xattrs` (plus COPYFILE_DISABLE) keeps macOS from writing\n // `LIBARCHIVE.xattr.com.apple.provenance` headers into the archive,\n // which GNU tar on the runtime image then warns about once per file.\n // Harmless, but it buries real extraction errors in noise.\n [\"-czf\", outPath, \"--no-xattrs\", ...(options.withModules ? [] : [\"--exclude\", \"node_modules\"]), \"-C\", bundleDir, \".\"],\n // Only a deploy packs a bundle, and a deploy's stdout may be its JSON result.\n { stdio: toolStdio(true),\nenv: { ...process.env,\nCOPYFILE_DISABLE: \"1\" } }\n );\n child.on(\"error\", reject);\n child.on(\"close\", (code) => (code === 0 ? resolve() : reject(new Error(`tar exited ${code}`))));\n });\n}\n\n/**\n * Pack a bundle for upload — without `node_modules`, even a vendored tree.\n *\n * Vendoring exists so a pod untars and boots rather than spending 35-55s of\n * every start in `npm install`, and a deploy did carry the tree for one night\n * (c36ea4637). It is left out again because of what the control plane does\n * with the archive: `GET /bundle/:projectId/:bundleId` reads the whole object\n * into memory on every pod start, and a runtime rollout restarts every tenant's\n * pods at once. Bundles it was sized against are a few hundred kB; a vendored\n * one is tens of MB, up to the 100 MB cap — N pods starting together would hold\n * N of them. A slower cold start per pod is the status quo every deploy has\n * shipped with; a control plane out of memory is every tenant's outage. The\n * platform's own rebuilds build with `--no-vendor` for the same shape of\n * reason. When the control plane streams bundles, this is the one switch to\n * flip, and `rebase cloud deploy` builds with `vendor: false` until then.\n *\n * `modulesLeftOut` says a tree the build DID vendor was not uploaded — a\n * prebuilt `--bundle-dir` from a plain `rebase build`, which vendors by default.\n */\nexport async function packBundleForUpload(\n bundleDir: string,\n outPath: string,\n manifest: RebaseBundleManifest,\n maxBytes: number = MAX_BUNDLE_UPLOAD_BYTES\n): Promise<{ bytes: number; modulesLeftOut: boolean }> {\n const vendored = manifest.deps?.vendored === true;\n await packBundle(bundleDir, outPath, { withModules: false });\n const bytes = fs.statSync(outPath).size;\n if (bytes > maxBytes) {\n throw new Error(\n `The bundle is ${(bytes / 1024 / 1024).toFixed(1)} MB without its dependencies, over the ` +\n `${Math.round(maxBytes / 1024 / 1024)} MB upload limit.`\n );\n }\n return { bytes, modulesLeftOut: vendored };\n}\n\n/**\n * Assemble the deploy-trigger body for a bundle deploy.\n *\n * The manifest travels with the trigger so the control plane can validate intake\n * without unpacking the uploaded archive first — a rejection (native deps, no\n * matching runtime) is then a fast, cheap answer.\n */\n/** The commit a bundle was built from, as far as the working directory knows. */\nexport interface BundleCommit {\n hash: string;\n message: string;\n}\n\n/**\n * The commit HEAD is on, read here because here is the only place it exists.\n *\n * A bundle deploy has no repository anywhere near the control plane: the CLI\n * builds a tarball and uploads it, so the three paths `deploy.ts` documents for\n * learning a commit — clone, `ls-remote`, or \"there is no repo at all\" — all\n * resolve to the third. Every bundle deployment therefore recorded an empty\n * hash, which is 291 of the 305 rows in production: a Deployments list where\n * almost nothing says what it shipped.\n *\n * But the CLI is standing IN the repository. `git -C <dir> log -1` answers\n * exactly, message included — the one thing even the git-build path cannot get\n * from `ls-remote`.\n *\n * Returns null rather than guessing, for every reason it can fail: no git, not a\n * repository, no commits yet. The server records what it is given and nothing\n * more, so null here stays `UNKNOWN_COMMIT_HASH` there.\n *\n * A dirty tree is NOT reported as a different commit. The bundle may contain\n * uncommitted work, and the honest statement about that is \"built from a tree at\n * <hash>\", not a fabricated identifier — the same rule the rest of this file\n * follows about inventing values.\n */\nexport function bundleCommit(cwd: string, run: (args: string[]) => string = gitIn(cwd)): BundleCommit | null {\n try {\n const hash = run([\"rev-parse\", \"--short=7\", \"HEAD\"]).trim();\n if (!/^[0-9a-f]{7,40}$/.test(hash)) return null;\n // `%s` is the subject alone. A full body would put newlines into a\n // single-line column that the console renders in a table row.\n const message = run([\"log\", \"-1\", \"--pretty=%s\"]).trim();\n return { hash, message };\n } catch {\n return null;\n }\n}\n\n/** `git -C <cwd> …`, as a function, so `bundleCommit` is testable without a repo. */\nfunction gitIn(cwd: string): (args: string[]) => string {\n return (args) => execFileSync(\"git\", [\"-C\", cwd, ...args], { encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"] });\n}\n\nexport function bundleDeployBody(input: {\n projectId: string;\n bundleId: string;\n manifest: RebaseBundleManifest;\n app?: string;\n message?: string;\n /**\n * Every app this repository declares in `rebase.json`, so the platform can\n * register the whole set rather than only the one being deployed.\n */\n declaredApps?: DeclaredApp[];\n /**\n * What HEAD said when this bundle was built, or null outside a repository.\n *\n * Omitted from the body entirely when null — an absent field and an empty\n * one are the same to the server, and sending `\"\"` would make \"we did not\n * look\" indistinguishable from \"we looked and there was nothing\".\n */\n commit?: BundleCommit | null;\n /**\n * The source this bundle was built from, uploaded so a platform upgrade can\n * rebuild it on a newer release. Omitted when none was uploaded — `--no-source`,\n * a static app, or an upload that failed — never sent empty.\n */\n rebuildSource?: RebuildSource | null;\n /** `--allow-downgrade`: deploy a bundle built on an older release than the project runs. */\n allowFrameworkDowngrade?: boolean;\n}): Record<string, unknown> {\n return {\n projectId: input.projectId,\n bundleId: input.bundleId,\n bundleManifest: input.manifest,\n app: input.app ?? input.manifest.app ?? \"backend\",\n client: \"cli\",\n frameworkVersion: input.manifest.runtime?.builtAgainst,\n ...(input.declaredApps?.length ? { declaredApps: input.declaredApps } : {}),\n ...(input.message ? { message: input.message } : {}),\n ...(input.commit\n ? { gitCommitHash: input.commit.hash, gitCommitMessage: input.commit.message }\n : {}),\n ...(input.rebuildSource\n ? {\n rebuildSource: {\n sourceId: input.rebuildSource.sourceId,\n projectPath: input.rebuildSource.projectPath,\n buildEnv: input.rebuildSource.buildEnv\n }\n }\n : {}),\n ...(input.allowFrameworkDowngrade ? { allowFrameworkDowngrade: true } : {})\n };\n}\n\n/** An app as `rebase.json` declares it, reduced to what the registry stores. */\nexport interface DeclaredApp {\n name: string;\n type: string;\n}\n\n/**\n * The apps a project manifest declares.\n *\n * A deploy only ever ships ONE app's bundle, so the trigger alone could never\n * tell the platform that the repository also contains a web frontend and an\n * admin panel — and the Apps page, whose whole job is to show the set, listed a\n * single entry called \"backend\". Sending the declared set fixes that without\n * pretending the others are deployed: the platform registers them, and their\n * status says what is actually true.\n */\nexport function declaredAppsFrom(manifest: { apps?: Record<string, { type?: string }> } | null | undefined): DeclaredApp[] {\n const apps = manifest?.apps;\n if (!apps || typeof apps !== \"object\") return [];\n return Object.entries(apps)\n .filter(([name]) => name.trim().length > 0)\n // Two types, and the control plane accepts exactly those — anything else\n // is a registration it would reject, which shows up as deploy noise\n // rather than as the manifest error it actually is. `backend` is the\n // narrow case; everything a repository declares that is not the backend\n // is served as files.\n .map(([name, value]) => ({ name,\ntype: value?.type === \"backend\" ? \"backend\" : \"static\" }));\n}\n\n/** Upload a bundle archive; returns the control-plane bundle id. */\nexport async function uploadBundle(\n url: string,\n token: string,\n projectId: string,\n tarPath: string\n): Promise<string> {\n const bytes = fs.readFileSync(tarPath);\n const res = await fetch(\n `${url}/api/functions/deploy/bundle/upload?projectId=${encodeURIComponent(projectId)}`,\n {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}`,\n\"Content-Type\": \"application/gzip\" },\n body: bytes\n }\n );\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`Bundle upload failed (${res.status}): ${body || res.statusText}`);\n }\n const data = (await res.json()) as { bundleId?: string };\n if (!data.bundleId) throw new Error(\"Bundle upload endpoint did not return a bundle id.\");\n return data.bundleId;\n}\n","/**\n * The project's source, uploaded beside its bundle so the platform can rebuild it.\n *\n * A managed deploy ships a built bundle, and a bundle is fixed to the framework\n * release it was built on. When the platform rolls a newer release across the\n * fleet it has to rebuild each project from source — and the bundle path never\n * uploaded any: the control plane held a tarball of compiled output and\n * nothing it could compile again. So every bundle deploy now also packs the\n * source the bundle was built from, uploads it, and names it in the trigger.\n *\n * Three rules shape what goes in:\n *\n * - **Git decides, when there is a repository.** `git ls-files --cached\n * --others --exclude-standard` at the repository's top level is exactly what\n * the developer considers source: `.gitignore` honoured the way git honours\n * it, and a sibling package the project links (`link:../../packages/editor`)\n * included, because it is outside the project directory but inside the\n * repository. Outside a repository — or inside one that ignores the project —\n * the project is walked, and its `.gitignore` files still decide.\n * - **Secrets never leave the machine, whatever git says.** A committed `.env`\n * is still a `.env`. {@link neverUploaded} is applied after git, not instead\n * of it.\n * - **It never costs the deploy.** The bundle is what runs; the source only\n * lets a later platform upgrade rebuild it. Too large, unpackable, refused by\n * the control plane — each is a warning, and the deploy goes on without it.\n */\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport { execFileSync, spawn } from \"child_process\";\nimport dotenv from \"dotenv\";\nimport type { RebaseProjectManifest } from \"@rebasepro/types\";\nimport { cliUserAgent } from \"../../utils/version\";\n\n/**\n * The control plane's cap on an uploaded source archive.\n *\n * Keep in sync with its build-context cap (deploy/upload `MAX_BYTES` and the\n * backend's `maxBodySize`). Checked before uploading, so an oversized archive is\n * a message in milliseconds rather than a bare 413 after the upload.\n */\nexport const MAX_SOURCE_UPLOAD_BYTES = 100 * 1024 * 1024;\n\n/** Env files that are templates by convention, and safe to ship. */\nconst ENV_TEMPLATES = new Set([\".env.example\", \".env.sample\", \".env.template\"]);\n\n/**\n * Whether a file must never be uploaded, whatever the ignore rules said.\n *\n * `relativePath` is POSIX. Installed packages, git's own directory and built\n * bundles are never source. Every `.env` and `.env.*` is excluded except the\n * three template names, and so is direnv's `.envrc`, which is the same thing\n * under another name.\n *\n * So is what the CLI keeps on this machine: `.rebase/`, which holds the\n * development database, and the `.rebase-dev-*` files beside it, one of which\n * is the development signing secrets. And so is a `*.dump`, which is what\n * `rebase db backup` writes: every row of the database, `rebase.users`\n * password hashes included.\n */\nexport function neverUploaded(relativePath: string): boolean {\n const segments = relativePath.split(\"/\");\n if (segments.some(segment =>\n segment === \"node_modules\" || segment === \".git\" || segment === \".rebase\" || segment.startsWith(\"dist-bundle\"))) {\n return true;\n }\n const base = segments[segments.length - 1];\n if (base === \".envrc\" || base.startsWith(\".rebase-dev-\") || base.endsWith(\".dump\")) return true;\n if ((base === \".env\" || base.startsWith(\".env.\")) && !ENV_TEMPLATES.has(base)) return true;\n return false;\n}\n\n/** Directories the walk outside a repository never enters. */\nconst WALK_SKIP = new Set([\"node_modules\", \".git\", \".rebase\", \".turbo\", \".next\", \"coverage\"]);\n\n/** The same directories as `ls-files` excludes, plus every `dist*` build directory. */\nconst WALK_EXCLUDES = [...[...WALK_SKIP].map(name => `--exclude=${name}/`), \"--exclude=dist*/\"];\n\n/** The file that says what a directory's source is not, which a walk has to honour. */\nconst IGNORE_FILE = \".gitignore\";\n\nexport interface SourceListing {\n /** The directory the archive is rooted at: the repository's top level, or the project root. */\n root: string;\n /** Regular files to pack, relative to `root`, POSIX, sorted. */\n files: string[];\n /** The project root relative to `root`, POSIX; `\"\"` when they are the same directory. */\n projectPath: string;\n /** Whether git chose the files. */\n fromGit: boolean;\n}\n\n/** `git -C <cwd> …`, returning stdout. Throws when git is missing or refuses. */\nexport type GitRunner = (cwd: string, args: string[]) => string;\n\nconst runGit: GitRunner = (cwd, args) => execFileSync(\"git\", [\"-C\", cwd, ...args], {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n // `ls-files` on a large monorepo is megabytes; the default 1 MiB buffer\n // would kill it and silently fall back to the walk.\n maxBuffer: 256 * 1024 * 1024\n});\n\nfunction toPosix(relative: string): string {\n return relative.split(path.sep).join(\"/\");\n}\n\n/** A regular file on disk: not missing, not a directory or submodule, not a symlink. */\nfunction isRegularFile(absolute: string): boolean {\n try {\n return fs.lstatSync(absolute).isFile();\n } catch {\n return false;\n }\n}\n\n/** One tree the archive carries: a repository's files, or a walked directory's. */\ninterface SourceUnit {\n root: string;\n /** Relative to `root`, POSIX. */\n files: string[];\n fromGit: boolean;\n}\n\n/** Split `-z` output into its entries. */\nfunction nulSeparated(output: string): string[] {\n return [...new Set(output.split(\"\\0\").filter(Boolean))];\n}\n\n/**\n * Run `fn` with the git directory of a throwaway, empty repository.\n *\n * `git ls-files` reads `.gitignore` files only inside a repository. Pointed at\n * an empty one with `--git-dir`, and at a directory with `--work-tree`, it lists\n * that directory's files the way git would — nested ignore files, negations and\n * the user's global excludes included — without the directory being a\n * repository, or `git init` touching it.\n */\nfunction withScratchRepository<T>(git: GitRunner, fn: (gitDir: string) => T): T {\n const scratch = fs.mkdtempSync(path.join(os.tmpdir(), \"rebase-ignore-\"));\n try {\n git(scratch, [\"init\", \"-q\"]);\n return fn(path.join(scratch, \".git\"));\n } finally {\n fs.rmSync(scratch, { recursive: true, force: true });\n }\n}\n\n/**\n * The files of the repository `dir` belongs to — tracked and unignored, the way\n * git sees them — or, when no repository holds it, `dir` walked.\n *\n * A repository that lists nothing under `dir` does not hold it: a project in a\n * directory the surrounding repository ignores (`tmp/my-app` under a repository\n * ignoring `tmp/`) has no repository of its own. Uploading that repository sent\n * everything except the project, so the project is walked instead.\n */\nfunction listUnit(dir: string, git: GitRunner): SourceUnit {\n try {\n const toplevel = git(dir, [\"rev-parse\", \"--show-toplevel\"]).trim();\n if (toplevel) {\n const root = fs.realpathSync(toplevel);\n const listed = git(root, [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\"]);\n // `--cached` lists a file once per merge stage during a conflict,\n // and a file deleted from the working tree but still in the index;\n // the set and the disk check take care of both. Submodules and\n // symlinks are listed too, and are not regular files.\n const files = nulSeparated(listed)\n .filter(relative => !neverUploaded(relative) && isRegularFile(path.join(root, relative)));\n const inside = toPosix(path.relative(root, dir));\n if (inside === \"\" || files.some(file => file.startsWith(`${inside}/`))) {\n return { root, files, fromGit: true };\n }\n }\n } catch {\n // Not a repository, no git, or git refusing the directory: the walk.\n }\n return { root: dir, files: walkFiles(dir, git), fromGit: false };\n}\n\n/**\n * `dir`'s files, walked, with its `.gitignore` files honoured.\n *\n * A scaffold made without `git init` still carries the stock `.gitignore`, and\n * it is the only statement of what in the directory is not source: `backups/`\n * with its database dumps, `uploads/` with the users' files. Git reads it,\n * through a throwaway repository (see {@link withScratchRepository}); a\n * repository nested in `dir` lists as one directory entry, and is listed as the\n * repository it is.\n *\n * Without git the walk has fixed excludes alone, and those cannot read an\n * ignore file. So a directory holding one is refused rather than walked past\n * it — the developer wrote down what must stay on this machine.\n */\nfunction walkFiles(dir: string, git: GitRunner): string[] {\n let listed: string[];\n try {\n listed = withScratchRepository(git, gitDir => nulSeparated(git(dir, [\n `--git-dir=${gitDir}`,\n `--work-tree=${dir}`,\n \"ls-files\", \"-z\", \"--others\", \"--exclude-standard\", ...WALK_EXCLUDES\n ])));\n } catch {\n return walkWithoutGit(dir);\n }\n\n const files: string[] = [];\n for (const relative of listed) {\n if (relative.endsWith(\"/\")) {\n // A repository of its own inside the walked directory.\n const nested = listUnit(path.join(dir, relative), git);\n const prefix = toPosix(path.relative(dir, nested.root));\n if (prefix.startsWith(\"..\") || path.isAbsolute(prefix)) continue;\n for (const file of nested.files) files.push(prefix ? `${prefix}/${file}` : file);\n } else if (!neverUploaded(relative) && isRegularFile(path.join(dir, relative))) {\n files.push(relative);\n }\n }\n return files;\n}\n\n/** The walk with fixed excludes, for a machine with no git. Refuses a tree with an ignore file in it. */\nfunction walkWithoutGit(dir: string): string[] {\n const files: string[] = [];\n const walk = (current: string, prefix: string): void => {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(current, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n const relative = prefix ? `${prefix}/${entry.name}` : entry.name;\n if (entry.isDirectory()) {\n if (WALK_SKIP.has(entry.name) || entry.name.startsWith(\"dist\")) continue;\n walk(path.join(current, entry.name), relative);\n } else if (entry.isFile() && entry.name === IGNORE_FILE) {\n throw new Error(\n `${relative} says what is not source, and reading it takes git, which is not available here`\n );\n } else if (entry.isFile() && !neverUploaded(relative)) {\n files.push(relative);\n }\n }\n };\n walk(dir, \"\");\n return files;\n}\n\n/** Whether `candidate` is `dir` or inside it. */\nfunction isWithin(dir: string, candidate: string): boolean {\n const relative = path.relative(dir, candidate);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\n/** The deepest directory containing every path given. */\nfunction commonAncestor(paths: string[]): string {\n let ancestor = paths[0];\n for (const p of paths.slice(1)) {\n while (!isWithin(ancestor, p)) ancestor = path.dirname(ancestor);\n }\n return ancestor;\n}\n\nconst DEPENDENCY_FIELDS = [\"dependencies\", \"devDependencies\", \"optionalDependencies\"] as const;\n\n/**\n * Directories outside every unit that a unit's `package.json` files link to\n * with `link:` or `file:`.\n *\n * `@rebasepro/*` links are not followed. They point at a local framework\n * checkout, which is not the project's source and would drag a whole monorepo\n * into the archive; a rebuild moves those packages to a published release\n * anyway.\n */\nfunction externalLinkTargets(units: SourceUnit[]): string[] {\n const targets = new Set<string>();\n for (const unit of units) {\n for (const relative of unit.files) {\n if (path.posix.basename(relative) !== \"package.json\") continue;\n let manifest: unknown;\n try {\n manifest = JSON.parse(fs.readFileSync(path.join(unit.root, relative), \"utf8\"));\n } catch {\n continue;\n }\n if (typeof manifest !== \"object\" || manifest === null) continue;\n for (const field of DEPENDENCY_FIELDS) {\n const deps = (manifest as Record<string, unknown>)[field];\n if (typeof deps !== \"object\" || deps === null) continue;\n for (const [name, spec] of Object.entries(deps)) {\n if (name.startsWith(\"@rebasepro/\") || typeof spec !== \"string\") continue;\n const match = /^(?:link|file):(.+)$/.exec(spec);\n if (!match) continue;\n const target = path.resolve(unit.root, path.posix.dirname(relative), match[1]);\n let real: string;\n try {\n real = fs.realpathSync(target);\n if (!fs.statSync(real).isDirectory()) continue;\n } catch {\n continue;\n }\n if (!units.some(u => isWithin(u.root, real))) targets.add(real);\n }\n }\n }\n }\n return [...targets];\n}\n\n/**\n * The files a source upload carries, and where they are rooted.\n *\n * The project's repository first — or the project walked, outside git. Then\n * every repository a local `link:`/`file:` dependency reaches outside it, until\n * nothing new is reached, rooted together at their deepest common directory.\n * That is dadaki's shape: its Rebase project is a repository of its own, nested\n * inside the editor's repository (which ignores it), and its frontend links\n * `../../packages/editor` from there. A listing of the project's repository\n * alone rebuilt into \"Rollup failed to resolve import @dadaki/editor\".\n *\n * Paths are resolved through `realpath` first: git reports its top level with\n * symlinks resolved (`/private/var/…` for a macOS temp directory), and a\n * project path computed against the unresolved one would climb out of the\n * archive with `../`.\n */\nexport function listSourceFiles(projectRoot: string, git: GitRunner = runGit): SourceListing {\n const realRoot = fs.realpathSync(projectRoot);\n const units: SourceUnit[] = [listUnit(realRoot, git)];\n for (let reached = externalLinkTargets(units); reached.length > 0; reached = externalLinkTargets(units)) {\n for (const target of reached) {\n if (units.some(u => isWithin(u.root, target))) continue;\n units.push(listUnit(target, git));\n }\n }\n\n const root = commonAncestor(units.map(u => u.root));\n const files = new Set<string>();\n for (const unit of units) {\n const prefix = toPosix(path.relative(root, unit.root));\n for (const file of unit.files) files.add(prefix ? `${prefix}/${file}` : file);\n }\n return {\n root,\n files: [...files].sort(),\n projectPath: toPosix(path.relative(root, realRoot)),\n fromGit: units.every(u => u.fromGit)\n };\n}\n\n/** The per-directory file of patterns a `--source` build context leaves out, beside `.gitignore`. */\nconst CONTEXT_IGNORE_FILE = \".rebaseignore\";\n\n/**\n * The files of a `--source` build context: `dir` and what is under it, relative\n * to it, POSIX, sorted.\n *\n * The same rules as the rebuild source — git decides, and {@link neverUploaded}\n * after it — restricted to `dir`, which is the context's root, so a Dockerfile\n * in it still reads its paths from there. A `dir` that is a subfolder of a\n * repository is held to that repository's `.gitignore`, which is where a\n * monorepo keeps it.\n *\n * `.rebaseignore` in `dir` leaves out more, read with `.gitignore` syntax and\n * anchored at `dir`. It needs git to be read, like `.gitignore` outside a\n * repository; without git, a context that has one is refused.\n */\nexport function listContextFiles(dir: string, git: GitRunner = runGit): string[] {\n const root = fs.realpathSync(dir);\n const unit = listUnit(root, git);\n const prefix = toPosix(path.relative(unit.root, root));\n let files = prefix === \"\"\n ? unit.files\n : unit.files.filter(file => file.startsWith(`${prefix}/`)).map(file => file.slice(prefix.length + 1));\n\n const contextIgnore = path.join(root, CONTEXT_IGNORE_FILE);\n if (fs.existsSync(contextIgnore)) {\n // Everything under `dir` the patterns match — the only patterns read,\n // since `--exclude-standard` is not passed — through a throwaway\n // repository, so they anchor at `dir` whatever repository holds it.\n const ignored = new Set(withScratchRepository(git, gitDir => nulSeparated(git(root, [\n `--git-dir=${gitDir}`,\n `--work-tree=${root}`,\n \"ls-files\", \"-z\", \"--others\", \"--ignored\", `--exclude-from=${contextIgnore}`\n ]))));\n files = files.filter(file => !ignored.has(file));\n }\n return [...files].sort();\n}\n\n/**\n * Pack a listing into a gzipped tarball at `outPath`.\n *\n * The list goes to tar as a NUL-separated file (`--null -T`), so a path with a\n * space or a newline in it is one path. `--no-xattrs` and `COPYFILE_DISABLE`\n * keep macOS's extended attributes and AppleDouble `._*` sidecars out of the\n * archive, as `packBundle` does; GNU tar accepts both. Every path handed to tar\n * is absolute, because GNU tar resolves a `-T` file after it has applied `-C`.\n */\nexport function packSource(listing: Pick<SourceListing, \"root\" | \"files\">, outPath: string): Promise<void> {\n const listPath = `${outPath}.files`;\n fs.writeFileSync(listPath, listing.files.map(file => `${file}\\0`).join(\"\"));\n return new Promise<void>((resolve, reject) => {\n const child = spawn(\n \"tar\",\n [\"-czf\", path.resolve(outPath), \"--no-xattrs\", \"--null\", \"-C\", listing.root, \"-T\", path.resolve(listPath)],\n { stdio: [\"ignore\", \"ignore\", \"pipe\"], env: { ...process.env, COPYFILE_DISABLE: \"1\" } }\n );\n let stderr = \"\";\n child.stderr.on(\"data\", chunk => (stderr += String(chunk)));\n child.on(\"error\", reject);\n child.on(\"close\", code => (code === 0 ? resolve() : reject(new Error(stderr.trim() || `tar exited ${code}`))));\n }).finally(() => fs.rmSync(listPath, { force: true }));\n}\n\n/** Upload a source archive; returns the control plane's id for it. */\nexport async function uploadRebuildSource(url: string, token: string, projectId: string, tarPath: string): Promise<string> {\n const bytes = fs.readFileSync(tarPath);\n const res = await fetch(`${url}/api/functions/deploy/source/upload?projectId=${encodeURIComponent(projectId)}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/gzip\",\n \"User-Agent\": cliUserAgent()\n },\n body: bytes\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n throw new Error(`the upload was refused (${res.status}): ${body || res.statusText}`);\n }\n const data: unknown = await res.json();\n const sourceId = typeof data === \"object\" && data !== null && \"sourceId\" in data ? data.sourceId : undefined;\n if (typeof sourceId !== \"string\" || !/^[0-9a-f]{32}$/i.test(sourceId)) {\n throw new Error(\"the control plane did not return a source id\");\n }\n return sourceId;\n}\n\n/** The env files Vite reads for a production build, lowest precedence first. */\nconst PRODUCTION_ENV_FILES = [\".env\", \".env.local\", \".env.production\", \".env.production.local\"];\n\n/**\n * The `VITE_*` values a rebuild of this project's frontend needs.\n *\n * The `.env` files are never uploaded, so the values a static app is built with\n * have to travel separately — and only the `VITE_*` ones, which Vite inlines\n * into the client bundle and are public by construction. Nothing else is read.\n *\n * Read the way Vite reads them for `vite build`: `.env`, `.env.local`,\n * `.env.production`, `.env.production.local`, later winning — from the project\n * root, then from each static app's own `root`, which is where its Vite config\n * usually points. `process.env` wins over every file, as it does in Vite.\n *\n * `VITE_API_URL` is the one exception, taken from `process.env` only.\n * `staticBuildEnv` sets it to `process.env.VITE_API_URL ?? \"\"` for every\n * static build, so a value in a `.env` file never reaches a deployed bundle —\n * it is the `http://localhost:3001` of local development. Sending it would make\n * the rebuild bake in exactly the address the local build refuses to.\n */\nexport function collectBuildEnv(\n projectRoot: string,\n appRoots: string[],\n env: NodeJS.ProcessEnv = process.env\n): Record<string, string> {\n const collected: Record<string, string> = {};\n const seen = new Set<string>();\n for (const dir of [projectRoot, ...appRoots.map(root => path.resolve(projectRoot, root))]) {\n const resolved = path.resolve(dir);\n if (seen.has(resolved) || !fs.existsSync(resolved)) continue;\n seen.add(resolved);\n for (const name of PRODUCTION_ENV_FILES) {\n let parsed: Record<string, string>;\n try {\n parsed = dotenv.parse(fs.readFileSync(path.join(resolved, name), \"utf8\"));\n } catch {\n continue;\n }\n for (const [key, value] of Object.entries(parsed)) {\n if (key.startsWith(\"VITE_\")) collected[key] = value;\n }\n }\n }\n delete collected.VITE_API_URL;\n for (const [key, value] of Object.entries(env)) {\n if (key.startsWith(\"VITE_\") && value !== undefined) collected[key] = value;\n }\n return collected;\n}\n\n/** The `root` of every static app a manifest declares, in declaration order. */\nexport function staticAppRoots(manifest: RebaseProjectManifest | undefined): string[] {\n if (!manifest) return [];\n const roots: string[] = [];\n for (const app of Object.values(manifest.apps)) {\n if (app.type === \"static\" && typeof app.root === \"string\" && app.root !== \"\") roots.push(app.root);\n }\n return roots;\n}\n\n/** What the deploy trigger carries about an uploaded source. */\nexport interface RebuildSource {\n sourceId: string;\n projectPath: string;\n buildEnv: Record<string, string>;\n}\n\n/** The steps, injectable so a test can fail any one of them. */\nexport interface RebuildSourceSteps {\n list: (projectRoot: string) => SourceListing;\n pack: (listing: SourceListing, outPath: string) => Promise<void>;\n upload: (url: string, token: string, projectId: string, tarPath: string) => Promise<string>;\n}\n\nconst DEFAULT_STEPS: RebuildSourceSteps = {\n list: projectRoot => listSourceFiles(projectRoot),\n pack: packSource,\n upload: uploadRebuildSource\n};\n\n/**\n * List, pack and upload the project's source. Never throws.\n *\n * Returns what the trigger should carry, or null — after a warning saying why\n * and what it costs — when the source could not be sent. The caller deploys\n * either way.\n */\nexport async function prepareRebuildSource(opts: {\n projectRoot: string;\n url: string;\n /** The access token, read when the upload is sent rather than before the packing. */\n token: () => Promise<string>;\n projectId: string;\n manifest?: RebaseProjectManifest;\n progress: (line: string) => void;\n warn: (message: string, hint?: string) => void;\n steps?: Partial<RebuildSourceSteps>;\n maxBytes?: number;\n}): Promise<RebuildSource | null> {\n const steps = { ...DEFAULT_STEPS, ...opts.steps };\n const maxBytes = opts.maxBytes ?? MAX_SOURCE_UPLOAD_BYTES;\n const tarPath = path.join(os.tmpdir(), `rebase-rebuild-src-${process.pid}-${Date.now()}.tar.gz`);\n const cost = \"Platform upgrades will not rebuild this project until a later deploy uploads its source.\";\n\n try {\n const listing = steps.list(opts.projectRoot);\n await steps.pack(listing, tarPath);\n const size = fs.statSync(tarPath).size;\n const mb = (bytes: number): string => (bytes / 1024 / 1024).toFixed(1);\n if (size > maxBytes) {\n opts.warn(\n `The project source is ${mb(size)} MB compressed, over the ${Math.round(maxBytes / 1024 / 1024)} MB ` +\n `upload limit, so it was not uploaded. ${cost}`,\n listing.fromGit\n ? \"Stop tracking large assets and build output in git, or pass --no-source to skip it on purpose.\"\n : \"Initialise a git repository with a .gitignore to choose what is source, or pass --no-source.\"\n );\n return null;\n }\n opts.progress(` Uploading source (${listing.files.length} files, ${mb(size)} MB)...`);\n const sourceId = await steps.upload(opts.url, await opts.token(), opts.projectId, tarPath);\n return {\n sourceId,\n projectPath: listing.projectPath,\n buildEnv: collectBuildEnv(opts.projectRoot, staticAppRoots(opts.manifest))\n };\n } catch (err) {\n opts.warn(\n `The project source was not uploaded: ${err instanceof Error ? err.message : String(err)}. ${cost}`,\n \"The deploy continues with the bundle alone.\"\n );\n return null;\n } finally {\n fs.rmSync(tarPath, { force: true });\n }\n}\n","/**\n * `rebase cloud deploy` and `rebase cloud logs`.\n *\n * `deploy` triggers the control-plane `deploy` function, then tails the build\n * logs from the deployment record until it succeeds or fails. `logs` shows the\n * latest build log, or runtime logs with `--runtime`.\n *\n * There are three deploys behind the one verb, and which one runs depends on the\n * flags: `--bundle` builds and uploads a managed bundle, `--source .` uploads\n * this directory as a build context, and the bare form uploads nothing and asks\n * the control plane to rebuild what it already holds. That last one is the\n * dangerous one — see `planBareDeploy`.\n */\nimport arg from \"arg\";\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport path from \"path\";\nimport { durationBucket, recordEvent } from \"../../telemetry\";\nimport {\n requireClient,\n resolveProjectRef,\n parseCloudArgs,\n colorStatus,\n emit,\n isJsonMode,\n printJson,\n fail,\n freshAccessToken,\n warn,\n reportError,\n resolveTimeoutMs,\n fetchTenantBaseDomain,\n projectHost,\n type CloudClient,\n billingAccountIdOf\n} from \"./context\";\nimport { latestDeployment, fmtDate } from \"./projects\";\nimport {\n readBundleManifest,\n packBundleForUpload,\n uploadBundle,\n bundleDeployBody,\n bundleCommit,\n declaredAppsFrom\n} from \"./bundle-deploy\";\nimport { listContextFiles, MAX_SOURCE_UPLOAD_BYTES, packSource, prepareRebuildSource, type RebuildSource } from \"./rebuild-source\";\nimport { buildBundle } from \"../../bundle\";\nimport { buildAssetApp } from \"../build\";\nimport { foldFrontendIntoBundle } from \"../../fold-static\";\nimport { loadManifest, findBackendApp, resolveBackendPaths, selectDeployApp } from \"../../manifest\";\nimport { findProjectRoot, requireProjectRoot } from \"../../utils/project\";\nimport { deriveOptionsFor, deriveResourceGraph } from \"../../resources/derive\";\nimport type { RebaseAppConfig, RebaseBackendAppConfig, RebaseProjectManifest } from \"@rebasepro/types\";\n\ninterface Deployment {\n id: string | number;\n status?: string;\n logs?: string;\n createdAt?: string;\n}\n\n/**\n * What the control plane says about the deployment holding the lock, when it\n * refuses a trigger. Absent on control planes older than that change.\n */\ninterface BlockingDeployment {\n id?: string;\n createdAt?: string | null;\n status?: string | null;\n triggerSource?: string;\n /**\n * Whether the same user triggered the blocking deployment. Never that it\n * is this trigger's own: a replay of that is answered 200 `deduplicated`.\n */\n mine?: boolean;\n}\n\nconst POLL_INTERVAL_MS = 1500;\nconst POLL_TIMEOUT_MS = 15 * 60 * 1000; // 15 min hard stop\n/** How long a follow keeps retrying a status it cannot read before it says so. */\nconst UNREADABLE_STATUS_MS = 60 * 1000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n/**\n * Package `sourceDir` into a gzipped tarball; returns the temp archive path.\n *\n * What goes in is {@link listContextFiles}: `.gitignore` read the way git reads\n * it, `.rebaseignore` beside it, and never an env file, a database dump or the\n * CLI's local state, whatever either says. The control plane keeps the archive\n * as the project's source, so this is the last point anything can be kept back.\n */\nasync function createSourceTarball(sourceDir: string): Promise<string> {\n const dir = path.resolve(sourceDir);\n if (!fs.existsSync(dir)) fail(`Source directory not found: ${dir}`);\n\n const tarPath = path.join(os.tmpdir(), `rebase-src-${Date.now()}.tar.gz`);\n try {\n const files = listContextFiles(dir);\n await packSource({ root: fs.realpathSync(dir), files }, tarPath);\n } catch (e) {\n fs.rmSync(tarPath, { force: true });\n fail(`Failed to package source: ${e instanceof Error ? e.message : String(e)}`);\n }\n return tarPath;\n}\n\n/**\n * The `@rebasepro/*` version this source directory actually resolves.\n *\n * Recorded on the deployment so a row in Deployment History says which\n * framework build shipped. Nothing else on the platform knows: an app that\n * links the framework locally pins it at package time, and a silent bump is\n * invisible afterwards — it has already cost one debugging session.\n *\n * `@rebasepro/server` first, because that is what the deployed backend runs;\n * `@rebasepro/client` is the fallback for a frontend-only bundle. Resolution is\n * a plain walk up from the source directory rather than `require.resolve`,\n * which would answer for the CLI's own install tree instead of the app's.\n *\n * Best effort by construction: a version that cannot be read is simply not\n * recorded. Nothing about a deploy should fail over a bookkeeping string.\n */\nfunction resolveFrameworkVersion(sourceDir: string): string | undefined {\n let dir = path.resolve(sourceDir);\n for (;;) {\n for (const pkg of [\"@rebasepro/server\", \"@rebasepro/client\"]) {\n try {\n const manifest = path.join(dir, \"node_modules\", ...pkg.split(\"/\"), \"package.json\");\n const version = (JSON.parse(fs.readFileSync(manifest, \"utf8\")) as { version?: unknown }).version;\n if (typeof version === \"string\" && version.trim() !== \"\") return version.trim();\n } catch {\n /* not here — keep walking */\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return undefined;\n dir = parent;\n }\n}\n\n/**\n * A progress line for a human — dropped entirely in JSON mode.\n *\n * Progress is not a result. In JSON mode stdout carries the one result value\n * and nothing else, so every unguarded `console.log` on a deploy path was a\n * line printed in front of the JSON, breaking the parser meant to read it.\n * Warnings are the other half of this rule and go the other way: they are\n * `warn`, which prints in every mode, to stderr. See `warn` in `context.ts`.\n */\nfunction progress(line: string): void {\n if (!isJsonMode()) console.log(line);\n}\n\n/**\n * The token for one of the raw uploads below, read as it is sent.\n *\n * They are plain `fetch` calls, which never refresh a session the way the\n * SDK's own requests do, and each is sent after work that can outlive a token:\n * a type check and a build, or packing a large directory. Read once at the\n * start, the token had lapsed by then, the upload was refused with a 401, and\n * the build was thrown away.\n */\nasync function uploadToken(client: CloudClient, url: string): Promise<string> {\n try {\n return await freshAccessToken(client);\n } catch {\n fail(\n `Your session for ${url} has expired.`,\n \"Run `rebase cloud login` to sign in again, then deploy again.\",\n \"session_expired\"\n );\n }\n}\n\n/** Upload a build-context tarball; returns the opaque `source` ref for deploy. */\nasync function uploadSource(url: string, token: string, projectId: string, tarPath: string): Promise<string> {\n const bytes = fs.readFileSync(tarPath);\n const sizeMb = (bytes.length / 1024 / 1024).toFixed(1);\n if (bytes.length > MAX_SOURCE_UPLOAD_BYTES) {\n fail(\n `Source context is ${sizeMb} MB — the upload cap is ${Math.round(MAX_SOURCE_UPLOAD_BYTES / 1024 / 1024)} MB.`,\n \"Trim the build context: exclude sourcemaps (*.map), build output and large assets via .rebaseignore or .gitignore.\"\n );\n }\n progress(chalk.gray(` Uploading source (${sizeMb} MB)...`));\n const res = await fetch(`${url}/api/functions/deploy/upload?projectId=${encodeURIComponent(projectId)}`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}`,\n\"Content-Type\": \"application/gzip\" },\n body: bytes\n });\n if (!res.ok) {\n const body = await res.text().catch(() => \"\");\n fail(`Source upload failed (${res.status}): ${body || res.statusText}`);\n }\n const data = (await res.json()) as { source?: string };\n if (!data.source) fail(\"Upload endpoint did not return a source reference.\");\n return data.source;\n}\n\n/**\n * Build, upload and deploy a project as a managed bundle.\n *\n * Builds the backend app into `dist-bundle` (unless one is pointed at with\n * `--bundle-dir`), packs it with the dependency tree the build vendored into it,\n * uploads it, and triggers a deploy carrying the manifest so the control plane\n * can validate intake fast.\n */\nasync function deployBundle(opts: {\n client: CloudClient;\n url: string;\n projectId: string;\n projectRef: string;\n bundleDir?: string;\n message?: string;\n /** Which app to deploy, when this repository declares more than one. */\n appName?: string;\n /** Compile without type checking, exactly as `rebase build` does. */\n skipTypeCheck?: boolean;\n /** Keep the committed Drizzle schema rather than regenerating it, as `rebase build --skip-schema` does. */\n skipSchema?: boolean;\n /** Leave the static apps out of the backend bundle, as `rebase build --no-static` does. */\n noStatic?: boolean;\n /** Follow the deployment to a terminal state. Default on; `--no-follow` off. */\n follow: boolean;\n /** Ceiling on the follow, in milliseconds. */\n timeoutMs: number;\n /** Upload the project's source beside a backend bundle. Default on; `--no-source` off. */\n uploadSource: boolean;\n /** `--allow-downgrade`: deploy a bundle built on an older release than the project runs. */\n allowDowngrade: boolean;\n /** When the command started, for the `cli.deploy` event's duration. */\n startedAt: number;\n}): Promise<void> {\n // Nothing here reads client/url/projectId/projectRef any more: everything\n // that needs them is reached through `uploadAndTrigger({ ...opts })`, which\n // takes the whole object. Destructuring them anyway is four values computed\n // and dropped.\n const projectRoot = requireProjectRoot();\n\n let bundleDir = opts.bundleDir\n ? path.resolve(process.cwd(), opts.bundleDir)\n : path.join(projectRoot, \"dist-bundle\");\n\n // Build the bundle unless the caller pointed at a prebuilt one.\n if (!opts.bundleDir) {\n // Every refusal before the build goes through `fail`: a throw reached\n // stdout in JSON mode as nothing at all.\n let loaded: ReturnType<typeof loadManifest>;\n try {\n loaded = loadManifest(projectRoot);\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err), undefined, \"invalid_manifest\");\n }\n\n // Which app, decided once and by the manifest. A repository declares\n // apps and a project owns them, so a repository holding only an admin\n // panel is an ordinary thing rather than a repository with a missing\n // backend — which is what this used to call it, refusing the deploy.\n let target: { name: string; app: RebaseAppConfig };\n try {\n target = selectDeployApp(loaded.manifest, opts.appName);\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err));\n return;\n }\n\n if (target.app.type === \"static\" && opts.noStatic) {\n fail(\n `--no-static leaves a backend's frontend out of its bundle, and \"${target.name}\" is a static app: ` +\n \"its bundle is nothing but its frontend.\",\n \"Deploy it without --no-static.\",\n \"usage\"\n );\n }\n\n if (target.app.type === \"static\") {\n // A static app deploys through the identical path — upload, trigger,\n // same endpoint — and differs only in what it builds and in the\n // `kind` its manifest carries. The control plane routes on that.\n progress(chalk.gray(` Building static app \"${target.name}\"...`));\n let staticDir: string | undefined;\n try {\n staticDir = await buildAssetApp(\n projectRoot,\n target.name,\n target.app,\n loaded.manifest.rebase,\n undefined,\n { quietStdout: isJsonMode() }\n );\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err));\n }\n if (!staticDir) {\n fail(\n `App \"${target.name}\" produced no bundle.`,\n \"A static app needs both a `build` command and an `output` directory in rebase.json.\"\n );\n return;\n }\n bundleDir = staticDir;\n await uploadAndTrigger({ ...opts,\nprojectRoot,\nbundleDir,\nappName: target.name });\n return;\n }\n\n progress(chalk.gray(\" Building bundle...\"));\n // `target` is decided above, by the manifest. Naming it `backend` here\n // is what the rest of this block reads.\n const backend = { name: target.name,\napp: target.app as RebaseBackendAppConfig };\n\n // Same derivation `rebase build` does, and fatal for the same reason: a\n // bundle whose manifest is missing a bucket the code declares deploys\n // into a tenant with nothing provisioned for it. After `backend` on\n // purpose — the config directory it reads comes from that app.\n const { graph: resourceGraph, issues: resourceIssues } = await deriveResourceGraph(\n deriveOptionsFor(projectRoot, backend.app)\n );\n if (resourceIssues.length > 0) {\n fail(\n `${resourceIssues.length} problem(s) in the declared resources:\\n` +\n resourceIssues.map(i => ` ${i.path} ${i.message}`).join(\"\\n\"),\n undefined,\n \"build_failed\"\n );\n }\n // A build that fails is the deploy's answer, in either output mode: in\n // JSON mode an error thrown past here reached stdout as nothing at all.\n let result: Awaited<ReturnType<typeof buildBundle>>;\n try {\n result = await buildBundle({\n projectRoot,\n appName: backend.name,\n app: backend.app,\n runtimeRange: loaded.manifest.rebase,\n resources: resourceGraph,\n skipTypeCheck: opts.skipTypeCheck,\n skipSchema: opts.skipSchema,\n // The upload leaves `node_modules` out (see packBundleForUpload),\n // so installing it here would be 35-55s spent on a tree nobody ships.\n vendor: false,\n log: (m: string) => progress(chalk.gray(m)),\n quietStdout: isJsonMode()\n });\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err), undefined, \"build_failed\");\n }\n bundleDir = result.outDir;\n\n /* Fold the frontend in, exactly as `rebase build` does. This path builds\n its own bundle, so without the same step a deploy shipped a bundle with\n no site in it — the managed pod then served the API perfectly and 404'd\n every page, which is precisely the failure folding exists to prevent.\n Two callers producing the same artefact have to share the step that\n completes it, and the same way out of it: `--no-static`. */\n if (!opts.noStatic) {\n try {\n const folded = await foldFrontendIntoBundle({\n projectRoot,\n manifest: loaded.manifest as never,\n bundleDir,\n log: (m: string) => progress(m),\n quietStdout: isJsonMode()\n });\n for (const outcome of folded) {\n progress(chalk.gray(\n ` folded ${outcome.appName} in (${outcome.fileCount} file(s), served at ${outcome.path})`\n ));\n }\n } catch (err) {\n fail(\n err instanceof Error ? err.message : String(err),\n \"Fix the frontend build, or pass --no-static to deploy the API alone.\"\n );\n }\n }\n }\n\n await uploadAndTrigger({ ...opts,\nprojectRoot,\nbundleDir });\n}\n\n/**\n * Pack a built bundle, upload it, and trigger the deploy.\n *\n * Shared by every managed deploy, whichever kind of app produced the bundle: a\n * backend and a static app differ in what is built and in the `kind` their\n * manifest carries, and in nothing after that. Keeping one tail is what makes\n * that true rather than nearly true — the folding step was once missing from\n * one of two callers producing the same artifact, and the deploy shipped a\n * bundle with no site in it.\n */\nasync function uploadAndTrigger(opts: {\n client: CloudClient;\n url: string;\n projectId: string;\n projectRef: string;\n /**\n * The directory holding `rebase.json`. Everything about the project — its\n * declared apps, its commit, its source — is read from here, never from\n * the working directory, which may be `backend/` or anywhere else inside it.\n */\n projectRoot: string;\n bundleDir: string;\n message?: string;\n appName?: string;\n follow: boolean;\n timeoutMs: number;\n uploadSource: boolean;\n allowDowngrade: boolean;\n /** When the command started, for the `cli.deploy` event's duration. */\n startedAt: number;\n}): Promise<void> {\n const { client, url, projectId, projectRef, projectRoot, bundleDir } = opts;\n let manifest: ReturnType<typeof readBundleManifest>;\n try {\n manifest = readBundleManifest(bundleDir);\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err), undefined, \"invalid_bundle\");\n }\n // `cli.deploy`, recorded for a bundle deploy as for a source build: this is\n // the default deploy of every scaffold, and it recorded nothing.\n const record = (followed: boolean, status: string): Promise<void> => recordDeploy({\n followed,\n status,\n deduplicated: false,\n frameworkVersion: manifest.runtime?.builtAgainst,\n startedAt: opts.startedAt,\n projectRoot\n });\n\n // Native modules cannot run on the managed runtime — the server rejects them\n // at intake anyway, but catching it here saves a pointless upload of a bundle\n // that cannot be deployed. Checked against the manifest, so it covers a\n // prebuilt `--bundle-dir` bundle just as much as one we just built.\n if (manifest.hooks?.native) {\n const names = (manifest.hooks.nativeModules ?? []).map(m => m.name).join(\", \");\n fail(\n `This bundle depends on native modules${names ? ` (${names})` : \"\"}, which the managed runtime cannot run.`,\n \"Remove the native dependency, or deploy on the custom runtime.\"\n );\n }\n\n // Pack + upload.\n const tarPath = path.join(os.tmpdir(), `rebase-bundle-${Date.now()}.tar.gz`);\n\n let bundleId: string;\n try {\n const packed = await packBundleForUpload(bundleDir, tarPath, manifest);\n if (packed.modulesLeftOut) {\n warn(\n \"This bundle's installed dependencies are not uploaded: a managed pod installs them when it starts.\",\n \"Build it with `rebase build --no-vendor` to skip installing a tree the upload leaves out.\"\n );\n }\n const sizeMb = (packed.bytes / 1024 / 1024).toFixed(1);\n progress(chalk.gray(` Uploading bundle (${sizeMb} MB)...`));\n bundleId = await uploadBundle(url, await uploadToken(client, url), projectId, tarPath);\n } catch (e) {\n fail(e instanceof Error ? e.message : String(e));\n return;\n } finally {\n fs.rmSync(tarPath, { force: true });\n }\n\n // Guarded for the same reason as the source-deploy banner below: the JSON\n // result on this path is printed to stdout too.\n if (!isJsonMode()) {\n console.log(\"\");\n console.log(` 🚀 Triggering managed deployment for ${chalk.bold(projectRef)} (schema ${manifest.schemaVersion})...`);\n }\n\n // Tell the platform about every app this repo declares, not only the one\n // whose bundle is being uploaded. A deploy ships one app; the Apps page is\n // meant to show the set, and without this it only ever knew about the backend.\n let projectManifest: RebaseProjectManifest | undefined;\n try {\n projectManifest = loadManifest(projectRoot).manifest;\n } catch {\n // A project with no readable rebase.json still deploys; it just cannot\n // describe its other apps.\n }\n const declaredApps = declaredAppsFrom(projectManifest);\n\n // The source this bundle was built from, so a platform upgrade can rebuild\n // it on a newer release. A backend only: a static app's bundle is its\n // built files and nothing more, and has nothing to rebuild against.\n // Best effort — see `prepareRebuildSource`, which warns and returns null\n // rather than fail a deploy over it.\n let rebuildSource: RebuildSource | null = null;\n if (opts.uploadSource && manifest.kind !== \"static\" && await platformRebuildsOff(client, projectId)) {\n // The owner turned platform rebuilds off: the platform keeps no copy\n // of this app's source, so none leaves the machine. Asked before\n // packing anything; the control plane refuses the upload regardless.\n progress(chalk.gray(\n \" Platform rebuilds are off for this project, so its source is not uploaded \" +\n \"(turn them on with `rebase cloud settings set --platform-rebuilds on`).\"\n ));\n } else if (opts.uploadSource && manifest.kind !== \"static\") {\n rebuildSource = await prepareRebuildSource({\n projectRoot,\n url,\n // Read after packing, just before the upload — see `uploadToken`. A\n // session that cannot be refreshed costs the source, as a warning.\n token: () => freshAccessToken(client),\n projectId,\n manifest: projectManifest,\n progress: (line) => progress(chalk.gray(line)),\n warn\n });\n }\n\n const body = bundleDeployBody({\n projectId,\n bundleId,\n manifest,\n app: opts.appName,\n message: opts.message,\n declaredApps,\n // Read here because here is the only place it exists: a bundle deploy\n // uploads a tarball, so nothing near the control plane has a repository\n // to ask. See `bundleCommit`.\n commit: bundleCommit(projectRoot),\n rebuildSource,\n allowFrameworkDowngrade: opts.allowDowngrade\n });\n\n let deploymentId: string;\n let managed: boolean;\n try {\n const res = await client.functions.invoke<{\n success: boolean;\n deployment: { id: string | number };\n managed?: boolean;\n }>(\"deploy\", body);\n if (!res?.deployment?.id) fail(\"Control plane did not return a deployment id.\");\n deploymentId = String(res.deployment.id);\n managed = res.managed === true;\n } catch (e) {\n // A refused bundle is a decision with a code and a remedy, not a\n // transport failure — the same branch `resolveTriggerFailure` takes\n // for a source build, which this path never reached.\n const refusal = intakeRefusal(e);\n if (refusal) fail(refusal.message, refusal.hint, refusal.code);\n reportError(e, \"Managed deploy failed to start\");\n }\n\n // Followed to a terminal state, like the source path beside it.\n //\n // This half used to stop at \"deploy started\" and print \"track it with\n // `rebase cloud logs`\", so `rebase cloud deploy` meant two different things\n // depending on which runtime the project happened to declare: on one path\n // it waited and the exit code was the verdict, on the other it returned 0\n // the moment the trigger was accepted — including for builds that went on\n // to fail. Every caller then wrote its own poll loop, with its own timeout,\n // against the same two fields this function already had in hand.\n //\n // One rule now: `deploy` follows unless told not to. `--no-follow` is that\n // instruction and keeps the old shape for anyone who wants it.\n if (!opts.follow) {\n emit(\n () => {\n console.log(chalk.green(` ✓ Managed deploy started (deployment ${deploymentId}).`));\n console.log(chalk.gray(\" Not following (--no-follow). Track it with `rebase cloud logs`.\"));\n },\n { success: true,\ndeploymentId,\nmanaged,\nsourceUploaded: rebuildSource !== null,\nfollowing: false }\n );\n await record(false, \"not_followed\");\n return;\n }\n\n if (!isJsonMode()) {\n console.log(chalk.green(` ✓ Managed deploy started (deployment ${deploymentId}).`));\n console.log(chalk.gray(\" Streaming build logs (Ctrl-C to stop watching — the build keeps running):\"));\n console.log(\"\");\n }\n\n const { status } = await streamBuildLogs(client, deploymentId, {\n quiet: isJsonMode(),\n timeoutMs: opts.timeoutMs,\n projectId,\n url,\n onTerminal: (ended) => record(true, ended)\n });\n emit(() => {}, { success: true,\ndeploymentId,\nmanaged,\nsourceUploaded: rebuildSource !== null,\nfollowing: true,\nstatus });\n}\n\n/* ─── what a deploy with nothing attached is actually going to build ─────────\n *\n * `rebase cloud deploy` with neither `--source` nor `--bundle` uploads nothing.\n * It asks the control plane to rebuild what it already holds — a git checkout,\n * or the newest source archive some earlier `--source` deploy left in object\n * storage. Both are legitimate; neither is this working directory, and the\n * command said nothing about which one it meant, so a deploy that shipped\n * month-old code was indistinguishable from one that shipped today's.\n *\n * For a project on the managed runtime it is worse than stale: a successful\n * source build sets `runtimeMode: \"custom\"` server-side, so the bare form\n * silently swaps a managed project back onto a container image. That one is a\n * refusal rather than a note — `--bundle` is what was meant, and `--eject`\n * ejects on purpose.\n */\n\n/** A project row, reduced to what says how it deploys (camel or snake columns). */\nexport interface DeployProjectRow {\n runtimeMode?: string;\n runtime_mode?: string;\n gitRepoUrl?: string;\n git_repo_url?: string;\n gitBranch?: string;\n git_branch?: string;\n}\n\n/** A deployment row, reduced to what says what it was built from. */\nexport interface DeploySourceRow {\n id?: string | number;\n status?: string;\n createdAt?: string | Date;\n created_at?: string | Date;\n sourceRef?: string;\n source_ref?: string;\n bundleId?: string;\n bundle_id?: string;\n}\n\nexport interface BareDeployPlan {\n /**\n * Whether the project runs the platform runtime — in which case any source\n * build here ejects it back onto a container image.\n */\n managed: boolean;\n /**\n * `git` — the control plane will clone the configured repository.\n * `snapshot` — it will rebuild the newest uploaded source archive.\n * `none` — it holds neither, and will refuse.\n */\n source: \"git\" | \"snapshot\" | \"none\";\n /** Lines describing the build, printed before it is triggered. */\n lines: string[];\n}\n\nfunction pick(row: Record<string, unknown> | undefined, ...keys: string[]): string | undefined {\n for (const key of keys) {\n const raw = row?.[key];\n if (typeof raw === \"string\" && raw.trim() !== \"\") return raw.trim();\n }\n return undefined;\n}\n\n/** Rough age of a timestamp, for \"…uploaded 6d ago\". Undefined if unreadable. */\nexport function timeAgo(value: string | Date | undefined, now: Date): string | undefined {\n if (value === undefined) return undefined;\n const then = value instanceof Date ? value.getTime() : new Date(value).getTime();\n if (Number.isNaN(then)) return undefined;\n const ms = now.getTime() - then;\n // A clock skewed into the future is not an age; saying nothing beats a lie.\n if (ms < 0) return undefined;\n const minutes = Math.floor(ms / 60_000);\n if (minutes < 1) return \"just now\";\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.floor(hours / 24)}d ago`;\n}\n\n/**\n * Whether this project runs on the managed runtime.\n *\n * `runtimeMode` on the project row is the authority — the control plane writes\n * it. The bundle-id fallback covers a control plane that does not return the\n * field: a successful deploy that served a bundle only happens on the managed\n * path.\n */\nexport function isManagedProject(\n project: DeployProjectRow | undefined,\n latest: DeploySourceRow | undefined\n): boolean {\n if (pick(project as Record<string, unknown> | undefined, \"runtimeMode\", \"runtime_mode\") === \"managed\") return true;\n return latest?.status === \"success\"\n && pick(latest as Record<string, unknown> | undefined, \"bundleId\", \"bundle_id\") !== undefined;\n}\n\n/** A row's own `createdAt`, in ms; 0 when it has none that parses. */\nfunction createdAtMs(row: DeploySourceRow): number {\n const raw = row.createdAt ?? row.created_at;\n const at = raw instanceof Date ? raw.getTime() : typeof raw === \"string\" ? new Date(raw).getTime() : NaN;\n return Number.isNaN(at) ? 0 : at;\n}\n\n/**\n * The deployment whose uploaded archive a bare deploy rebuilds, if any.\n *\n * The control plane's own rule (`reusableSourceRef`, over the newest 25 rows):\n * the newest row, by its own `createdAt`, carrying a build-context ref. Not the\n * newest row — a rollback or a bundle deploy carries none, and the upload\n * rebuilt then is the one before it.\n */\nexport function snapshotDeployment(recent: readonly DeploySourceRow[]): DeploySourceRow | undefined {\n let best: { row: DeploySourceRow; at: number } | undefined;\n for (const row of recent) {\n const ref = pick(row as Record<string, unknown>, \"sourceRef\", \"source_ref\");\n if (!ref || ref.includes(\"..\") || !ref.endsWith(\".tar.gz\")) continue;\n const at = createdAtMs(row);\n if (!best || at > best.at) best = { row, at };\n }\n return best?.row;\n}\n\n/**\n * What a `deploy` with nothing attached will build, in the words to print.\n *\n * `recent` is the project's newest deployments, newest first — the same page\n * the control plane reads to choose an archive.\n */\nexport function planBareDeploy(\n project: DeployProjectRow | undefined,\n recent: readonly DeploySourceRow[],\n now: Date\n): BareDeployPlan {\n const projectRow = project as Record<string, unknown> | undefined;\n const latest = recent[0];\n const managed = isManagedProject(project, latest);\n\n const repo = pick(projectRow, \"gitRepoUrl\", \"git_repo_url\");\n if (repo) {\n const branch = pick(projectRow, \"gitBranch\", \"git_branch\");\n return { managed,\nsource: \"git\",\nlines: [`Building from git: ${repo}${branch ? ` (${branch})` : \"\"}.`] };\n }\n\n const snapshot = snapshotDeployment(recent);\n if (snapshot) {\n const age = timeAgo(snapshot.createdAt ?? snapshot.created_at, now);\n const lines = [\n `Rebuilding the stored source archive${snapshot.id !== undefined ? ` from deployment ${snapshot.id}` : \"\"}` +\n `${age ? `, uploaded ${age}` : \"\"}.`\n ];\n if (latest && snapshot !== latest && latest.id !== undefined) {\n lines.push(`Deployment ${latest.id}, the newest, carried no archive of its own, so this is not what it deployed.`);\n }\n lines.push(\"This directory is NOT uploaded — pass `--source .` to build what is on disk.\");\n return { managed,\nsource: \"snapshot\",\nlines };\n }\n\n return {\n managed,\n source: \"none\",\n lines: [\n \"This project has no git repository configured and no stored source archive to rebuild.\",\n \"Upload this directory with `--source .`, or set a repository URL in the project settings.\"\n ]\n };\n}\n\n/**\n * A warning attached to a deploy: printed for the human, carried in the JSON.\n *\n * `code` is the stable half — the message is prose and will be reworded, so it\n * is the code that CI or an agent branches on.\n */\nexport interface DeployWarning {\n code: string;\n message: string;\n hint?: string;\n}\n\n/** `code` of the warning below, and the field name it sets in the payload. */\nexport const EJECTS_MANAGED_RUNTIME = \"ejects_managed_runtime\";\n\n/** The one sentence that says a source build undoes `runtimeMode: managed`. */\nexport function ejectWarning(projectRef: string): DeployWarning {\n return {\n code: EJECTS_MANAGED_RUNTIME,\n message: `${projectRef} runs on the managed runtime — this build ejects it to a custom container.`,\n hint: \"Use `rebase cloud deploy --bundle` to stay on managed.\"\n };\n}\n\n/** How a container-image deploy was asked for — the input to both rules below. */\nexport interface EjectContext {\n /** The project currently runs on the managed runtime. */\n managed: boolean;\n /** `--source` was passed: build this directory. */\n source: boolean;\n /** `--eject` was passed: leave the managed runtime on purpose. */\n eject: boolean;\n}\n\n/**\n * Why a container-image deploy of a managed project is refused — or `undefined`\n * to let it through.\n *\n * Every path below this point builds a container image, and a successful one\n * sets `runtimeMode: \"custom\"` server-side. So the question is never \"which flag\n * was used\" but \"did the caller ask to leave the managed runtime\", and only\n * `--eject` answers it.\n *\n * The flag was `--force` until the 2026-09-06 sweep. `--force` means four\n * different things across this CLI — overwrite a file, disconnect other\n * Postgres sessions, set a build-time key anyway — and three of them are\n * recoverable in a minute. This one moves a live project off the managed\n * runtime, which is the least recoverable thing the CLI can be asked to do,\n * and it had the same name as \"overwrite this file\". Renamed rather than\n * aliased: an alias would leave the dangerous spelling working.\n *\n * `--source` used to be read as answering it too, on the theory that uploading a\n * build context is self-evidently a deliberate eject. It is not: `--source`\n * picks *which source* gets built — this directory, rather than the stale\n * archive the control plane is holding — and the eject is a side effect of the\n * answer. That is exactly how a live project got flipped to `custom` by someone\n * whose actual intent was \"deploy what I have here\", and it is the same\n * ignorance the bare form is refused for. Same ignorance, same refusal.\n */\nexport function ejectRefusal(\n opts: EjectContext,\n projectRef: string\n): { message: string; hint: string; code: string } | undefined {\n if (!opts.managed || opts.eject) return undefined;\n const eject = \"To eject on purpose, add `--eject`.\";\n if (opts.source) {\n return {\n message:\n `${projectRef} runs on the managed runtime, and \\`--source\\` builds a container image from ` +\n \"this directory — which ejects it from managed. Picking a build method is not the same as \" +\n \"asking to leave the runtime.\",\n hint: `Deploy this directory to the managed runtime with \\`rebase cloud deploy --bundle\\`. ${eject}`,\n code: \"managed_project\"\n };\n }\n return {\n message:\n `${projectRef} runs on the managed runtime, and a plain \\`rebase cloud deploy\\` builds a ` +\n \"container image instead — ejecting it from managed, from source the control plane \" +\n \"already holds rather than this directory.\",\n hint:\n `Redeploy it with \\`rebase cloud deploy --bundle\\`. ${eject} ` +\n \"`--source . --eject` builds this directory; `--eject` alone builds what the control plane holds.\",\n code: \"managed_project\"\n };\n}\n\n/**\n * Which warnings a container-image deploy has earned.\n *\n * Pure, and separate from the printing, because the printing is what went\n * wrong: the eject warning used to be written inline behind `!isJsonMode()`, so\n * the fact that a deploy ejects a managed project existed only as a side effect\n * of a TTY being attached. Deciding here, emitting once at the call site, means\n * the decision cannot be output-mode-dependent again.\n *\n * The condition is just `managed`: anything reaching this point is a container\n * image build that `ejectRefusal` has already let through, and on a managed\n * project that is an eject however it was spelled. A caller who passed `--eject`\n * knows — the warning is for the transcript and the payload, which is what\n * anyone reviewing the deploy afterwards actually reads.\n */\nexport function deployWarnings(opts: EjectContext, projectRef: string): DeployWarning[] {\n return opts.managed ? [ejectWarning(projectRef)] : [];\n}\n\n/** The warning half of a deploy's JSON payload — merged into whatever it emits. */\nexport function warningPayload(warnings: DeployWarning[]): Record<string, unknown> {\n return {\n warnings: warnings.map((w) => ({\n code: w.code,\n message: w.message,\n hint: w.hint ?? null\n })),\n // Denormalised from `warnings` on purpose: a boolean is what a CI step\n // can test without walking an array, and this is the one consequence\n // worth failing a pipeline over.\n ejectsManagedRuntime: warnings.some((w) => w.code === EJECTS_MANAGED_RUNTIME)\n };\n}\n\n/**\n * Read what the preflight needs: the project row and its newest deployments.\n *\n * `readable: false` when either read failed. The plan lines are best effort and\n * say nothing then; the managed refusal is not — see the caller.\n */\nasync function readDeployContext(\n client: CloudClient,\n projectId: string\n): Promise<{ project?: DeployProjectRow; recent: DeploySourceRow[]; readable: boolean }> {\n try {\n const [project, recent] = await Promise.all([\n client.data.collection(\"projects\").findById(projectId),\n // The page the control plane chooses an archive from — see\n // `snapshotDeployment`.\n client.data.collection(\"deployments\").find({\n where: { project: [\"==\", projectId] },\n orderBy: [\"createdAt\", \"desc\"],\n limit: 25\n })\n ]);\n return {\n project: project as DeployProjectRow | undefined,\n recent: recent.data as DeploySourceRow[],\n readable: true\n };\n } catch {\n return { recent: [],\nreadable: false };\n }\n}\n\n/* ─── billing, asked before the build rather than after the upload ─────────── */\n\n/**\n * What the billing pre-check managed to learn about the organization paying for\n * this project. `null` means \"could not tell\", and is never a refusal.\n */\nexport interface BillingState {\n /** The billing account's plan, or null when the row could not be read. */\n plan: string | null;\n /** Whether the control plane reports a card on file, or null when it could not be asked. */\n hasPaymentMethod: boolean | null;\n /** The control plane has no Stripe configured — a local or staging control plane. */\n simulated: boolean;\n}\n\n/**\n * Whether a deploy should be refused here, before anything is built or uploaded.\n *\n * The server's gate (`ensureProjectComputeBilling`) is the authority and stays\n * the authority; this only moves the same refusal earlier in the sequence. A\n * managed deploy type-checks, builds a bundle, packs it and uploads it before it\n * triggers anything, so a 402 arrived after several minutes of work whose only\n * outcome was a discarded tarball.\n *\n * One direction only. A positive \"no card\" refuses; every other answer proceeds,\n * including every answer we could not obtain. That asymmetry is the whole design:\n * a pre-check that guesses wrong in the refusing direction blocks a deploy the\n * platform would have accepted, and there are two states this client cannot see —\n * an internal billing account (skipped server-side) and `REBASE_BYO_FREE` — so\n * \"unknown\" has to mean \"carry on and let the server decide\".\n */\nexport function billingBlocksDeploy(state: BillingState): boolean {\n // No Stripe behind the control plane: `hasPaymentMethod` is inferred from a\n // simulated setup, and a false there is not a card that is missing.\n if (state.simulated) return false;\n // Platform-internal projects skip billing entirely, server-side.\n if (state.plan === \"internal\") return false;\n return state.hasPaymentMethod === false;\n}\n\n/**\n * Ask the control plane whether the organization behind this project has a card.\n *\n * Best-effort throughout, for the reason above: every failure resolves to a\n * state that {@link billingBlocksDeploy} lets through.\n */\nexport async function readBillingState(client: CloudClient, projectId: string): Promise<BillingState> {\n const unknown: BillingState = { plan: null,\nhasPaymentMethod: null,\nsimulated: false };\n try {\n const project = (await client.data.collection(\"projects\").findById(projectId)) as\n | Record<string, unknown>\n | undefined;\n const orgRaw = project?.organization ?? project?.organizationId ?? project?.organization_id;\n const org = orgRaw == null ? \"\" : String(orgRaw);\n if (!org) return unknown;\n\n const card = await client.functions\n .invoke<{ hasPaymentMethod?: boolean; simulated?: boolean }>(\n \"stripe-billing\",\n undefined,\n { method: \"GET\",\npath: `payment-method/${encodeURIComponent(org)}` }\n )\n .catch(() => undefined);\n if (!card) return unknown;\n\n // The plan lives on the billing account, and an org that has none has no\n // plan to read — which is not \"internal\", so it does not exempt anything.\n let plan: string | null = null;\n try {\n const billingId = billingAccountIdOf(await client.data.collection(\"organizations\").findById(org));\n if (billingId != null) {\n const acct = (await client.data.collection(\"billing-accounts\").findById(billingId)) as\n | { plan?: string }\n | undefined;\n plan = typeof acct?.plan === \"string\" ? acct.plan : null;\n }\n } catch {\n // Unreadable: `plan: null`, which exempts nothing and refuses nothing\n // on its own.\n }\n\n return {\n plan,\n hasPaymentMethod: typeof card.hasPaymentMethod === \"boolean\" ? card.hasPaymentMethod : null,\n simulated: card.simulated === true\n };\n } catch {\n return unknown;\n }\n}\n\n/** Refuse a deploy the control plane would 402, before the build starts. */\nasync function requirePaymentMethod(client: CloudClient, projectId: string): Promise<void> {\n if (!billingBlocksDeploy(await readBillingState(client, projectId))) return;\n fail(\n \"This project's organization has no payment method on file, so the deploy would be refused.\",\n \"Attach a card once with `rebase cloud billing setup`, then deploy again.\",\n \"payment_required\"\n );\n}\n\n/**\n * Whether this repository's backend declares the managed runtime.\n *\n * Deliberately quiet: a directory that is not a Rebase project, or whose\n * manifest does not parse, simply does not route this way — `rebase build` is\n * where a broken manifest gets reported, and a deploy refusing on one before it\n * has even said what it is doing would be the wrong place to find out.\n */\nfunction declaresManagedRuntime(appName?: string): boolean {\n try {\n const projectRoot = findProjectRoot();\n if (!projectRoot) return false;\n const manifest = loadManifest(projectRoot).manifest;\n\n // A static app has no runtime to declare and never builds an image. It\n // is always a bundle deploy, so it takes this branch on its own — which\n // is what lets a repository with no backend at all reach the platform.\n if (appName) {\n const app = manifest.apps[appName];\n if (app?.type === \"static\") return true;\n if (app?.type === \"backend\") return app.runtime === \"managed\";\n }\n\n const backend = findBackendApp(manifest);\n // A repository declaring no backend has nothing that could be a source\n // build, so its apps are bundles by construction.\n if (!backend) return Object.keys(manifest.apps).length > 0;\n return backend.app.runtime === \"managed\";\n } catch {\n return false;\n }\n}\n\n/**\n * Every flag `rebase cloud deploy` accepts.\n *\n * Hoisted out of the `parseCloudArgs` call so that one declaration serves three\n * readers: the parser, `action-help.ts`'s page for this command, and the test\n * that holds the two to each other. A flag added here with no line in the help\n * page is a failing test rather than a flag nobody can discover.\n */\nexport const DEPLOY_FLAGS = {\n \"--no-follow\": Boolean,\n /* `--wait` is the explicit spelling of what this command already does — it\n follows the deployment to a terminal state and exits non-zero if that\n state is a failure. It exists because *asking* for that was the only way\n to find out it was the default, and because the managed-bundle path did\n not do it: that half returned as soon as the trigger was accepted, so\n every caller wrote its own poll loop against `cloud logs`. Both paths\n follow now; `--wait` is here so a script can say so, and so a reader\n looking for it in `--help` finds it rather than concluding it is absent. */\n \"--wait\": Boolean,\n /* Seconds. Bounds the follow on both paths — without it the only ceiling\n was a hardcoded 15 minutes, which is the wrong number for a CI step and\n for an overnight build alike. */\n \"--timeout\": String,\n \"--source\": String,\n \"--message\": String,\n \"--bundle\": Boolean,\n \"--bundle-dir\": String,\n /* Same flag `rebase build` has, for the same reason. Without it here, the\n only way to deploy a bundle without type checking was to run the build\n by hand and then point `--bundle-dir` at the result. */\n \"--skip-type-check\": Boolean,\n /* `rebase build`'s other two, which the deploy's own remedies name: a\n frontend that fails to fold says to deploy the API alone with\n `--no-static`, and a schema that fails to generate says `--skip-schema`\n for one that is hand-maintained. */\n \"--no-static\": Boolean,\n \"--skip-schema\": Boolean,\n /* Leave the managed runtime on purpose. The ONLY way to build a container\n image for a project the platform runs as managed — for the bare form and\n for `--source` alike, because neither of those says so by itself. See\n `ejectRefusal`.\n\n Spelled `--force` until 2026-09-06, which put the CLI's least reversible\n action under the same word as \"overwrite this file\". No alias: the old\n spelling is an unknown option now, so a script carrying it stops rather\n than ejecting a project on a name it no longer means. */\n \"--eject\": Boolean,\n /* Do not upload the project's source beside a backend bundle. The deploy\n is the same; what it gives up is being rebuilt by a platform upgrade,\n until a later deploy uploads the source. */\n \"--no-source\": Boolean,\n /* Deploy a bundle built on an older framework release than the project\n runs. The control plane refuses that by default (FRAMEWORK_DOWNGRADE),\n because it is usually a stale checkout, not a decision. */\n \"--allow-downgrade\": Boolean,\n \"-m\": \"--message\"\n} as const;\n\n/**\n * `rebase cloud deploy [app]` — its flags, and which app of this repository the\n * line named.\n *\n * Parsed through `parseCloudArgs` rather than `arg` directly, and the reason is\n * the positional. This command used to parse `rawArgs.slice(2)` permissively\n * and read `_[0]` as the app name — but `rawArgs` is the WHOLE `process.argv`,\n * so `_` opens with the command words themselves. `_[0]` was therefore the\n * literal string `\"cloud\"` on every run, which then went to `selectDeployApp`\n * and came back as:\n *\n * This repository declares no app named \"cloud\". It declares: backend, web.\n *\n * So the documented `rebase cloud deploy --bundle` failed on every project that\n * did not happen to declare an app called `cloud`, `rebase cloud deploy web`\n * could not reach `web`, and the refusal named the user's real apps — reading\n * as a fault in their `rebase.json` rather than in the CLI's own parse.\n *\n * `commandWords` counts from `cloud` itself, so `cloud deploy` is 2, and it is\n * applied to the PARSED positionals: a flag written before the group no longer\n * shifts the app name either.\n */\nexport function resolveDeployArgs(rawArgs: string[]) {\n const { flags, positionals } = parseCloudArgs({\n spec: DEPLOY_FLAGS,\n rawArgs,\n commandWords: 2, // cloud deploy\n command: \"cloud deploy\",\n maxPositionals: 1\n });\n return { flags,\nappName: positionals[0] as string | undefined };\n}\n\n/**\n * `cli.deploy` — the event that says whether anyone ever ships.\n *\n * Declared in `TelemetryEventName` from the start and recorded nowhere, so a\n * consenting user reported scaffolding, dev servers and schema pushes and never\n * the one act the product exists for.\n *\n * What it carries is deliberately thin. No project id, no app name, no\n * deployment id, no URL: those are the \"project names\" and \"URLs\" the consent\n * screen promises are never sent, and a deployment id is a durable handle on\n * somebody's infrastructure. `frameworkVersion` is *our* version, not the\n * user's data, and it is the one field that makes the rest legible — a failure\n * rate means nothing without knowing which release it is a rate for.\n */\nasync function recordDeploy(o: {\n followed: boolean;\n status: string;\n deduplicated: boolean;\n frameworkVersion?: string | null;\n startedAt: number;\n /** The project deployed; the working directory when the command has none. */\n projectRoot?: string;\n}): Promise<void> {\n await recordEvent(\"cli.deploy\", {\n followed: o.followed,\n status: o.status,\n deduplicated: o.deduplicated,\n framework_version: o.frameworkVersion ?? null,\n duration: durationBucket(Date.now() - o.startedAt)\n }, { projectRoot: o.projectRoot ?? process.cwd() });\n}\n\nexport async function deployCommand(rawArgs: string[], projectRef: string): Promise<void> {\n const startedAt = Date.now();\n const { flags: args, appName } = resolveDeployArgs(rawArgs);\n\n // Refused rather than resolved in one direction or the other: they are\n // opposite instructions, and either interpretation makes the command do\n // something the line explicitly asked it not to.\n if (args[\"--wait\"] && args[\"--no-follow\"]) {\n fail(\n \"--wait and --no-follow ask for opposite things.\",\n \"`deploy` follows by default — pass neither, or `--no-follow` to return as soon as the build is triggered.\",\n \"usage\"\n );\n }\n if (args[\"--source\"] && args[\"--no-source\"]) {\n fail(\n \"--source and --no-source ask for opposite things.\",\n \"`--source <path>` builds a container image from a directory; `--no-source` skips uploading the source \"\n + \"beside a managed bundle. Pass one.\",\n \"usage\"\n );\n }\n\n const { client, url } = await requireClient(rawArgs);\n const projectId = await resolveProjectRef(projectRef, client);\n\n // Before the build, not after the upload. The managed path type-checks,\n // builds, packs and uploads a bundle before it triggers anything, so a\n // billing 402 used to arrive at the end of all of it — with nothing to show\n // for the wait but a discarded tarball.\n await requirePaymentMethod(client, projectId);\n\n // Managed bundle deploy. Builds the project into a bundle, uploads it, and\n // lets the control plane run the platform runtime with it.\n //\n // Taken either because `--bundle` said so, or because this repository's\n // backend *declares* `runtime: \"managed\"`. That declaration is the whole\n // point of the field: a project that has written down which runtime it wants\n // should not also have to remember a flag, and forgetting the flag used to\n // mean a plain `deploy` tried to build a container image and eject the\n // project — which is why the refusal further down exists.\n //\n // `--source` and `--bundle-dir` are explicit acts and still route away from\n // here — though on a project the platform *runs* as managed, routing away\n // is now where `ejectRefusal` stops them without `--eject`.\n // `rebase cloud deploy <app>` — which app of the project this repository is\n // shipping. Positional because it is the subject of the sentence, not an\n // option: a repository holding only an admin panel deploys it by name, and a\n // repository with one backend keeps saying nothing at all. Resolved by\n // `resolveDeployArgs` above, off the parsed positionals.\n\n const declaredManaged = !args[\"--source\"] && !args[\"--bundle\"] && declaresManagedRuntime(appName);\n if (args[\"--bundle\"] || declaredManaged) {\n if (args[\"--bundle\"] && args[\"--source\"]) {\n fail(\"--bundle and --source cannot be combined: one is a managed bundle, the other a source build.\");\n }\n if (declaredManaged && !isJsonMode()) {\n console.log(chalk.gray(\" rebase.json declares runtime: managed — deploying a bundle.\"));\n }\n await deployBundle({\n client,\n url,\n projectId,\n projectRef,\n bundleDir: args[\"--bundle-dir\"],\n message: args[\"--message\"],\n appName,\n skipTypeCheck: args[\"--skip-type-check\"] === true,\n skipSchema: args[\"--skip-schema\"] === true,\n noStatic: args[\"--no-static\"] === true,\n follow: args[\"--no-follow\"] !== true,\n timeoutMs: resolveDeployTimeout(args[\"--timeout\"]),\n uploadSource: args[\"--no-source\"] !== true,\n allowDowngrade: args[\"--allow-downgrade\"] === true,\n startedAt\n });\n return;\n }\n\n // Everything below builds a container image from source. Say what that\n // source is before anything is uploaded or triggered, and refuse the one\n // case where the command would quietly undo the project's runtime.\n const { project, recent, readable } = await readDeployContext(client, projectId);\n const plan = planBareDeploy(project, recent, new Date());\n\n // The refusal below is the only thing between a managed project and a\n // container build: the control plane does not refuse one, and a\n // successful build moves the project to `custom`. So a read that failed\n // is not \"not managed\" — it is not knowing, and only `--eject` says the\n // answer does not matter.\n if (!readable && args[\"--eject\"] !== true) {\n fail(\n `Could not read ${projectRef}, so this deploy cannot tell whether it would eject the project from the managed runtime.`,\n \"Try again in a moment. If leaving the managed runtime is intended, pass `--eject`.\",\n \"preflight_unreadable\"\n );\n }\n\n const eject: EjectContext = {\n managed: plan.managed,\n source: Boolean(args[\"--source\"]),\n eject: args[\"--eject\"] === true\n };\n const refusal = ejectRefusal(eject, projectRef);\n if (refusal) fail(refusal.message, refusal.hint, refusal.code);\n\n // What survived that refusal is a deliberate eject, and still worth saying.\n // Warn in every output mode — `warn` writes to stderr, which is not the JSON\n // stream — and carry the same fact into the payload, the half CI reads.\n const warnings = deployWarnings(eject, projectRef);\n for (const w of warnings) warn(w.message, w.hint);\n\n if (!args[\"--source\"] && !isJsonMode()) {\n console.log(\"\");\n for (const line of plan.lines) console.log(chalk.gray(` ${line}`));\n }\n\n // Optional fly-style local source upload: `deploy --source .`\n let source: string | undefined;\n if (args[\"--source\"]) {\n const tarPath = await createSourceTarball(args[\"--source\"]);\n try {\n source = await uploadSource(url, await uploadToken(client, url), projectId, tarPath);\n } finally {\n fs.rmSync(tarPath, { force: true });\n }\n }\n\n // Guarded: this is stdout, and in JSON mode stdout carries the one JSON\n // value and nothing else — an unguarded banner here put a 🚀 line in front\n // of it and broke every parser reading the result.\n if (!isJsonMode()) {\n console.log(\"\");\n console.log(` 🚀 Triggering deployment for project ${chalk.bold(projectRef)}${source ? \" from uploaded source\" : \"\"}...`);\n }\n\n const body: Record<string, unknown> = { projectId };\n if (source) body.source = source;\n if (args[\"--message\"]) body.message = args[\"--message\"];\n // `client` is what the control plane records as `triggerSource`. Omitting it\n // is why every deployment this command has ever created reads `unknown` in\n // Deployment History — `rollback` next door has always sent it.\n body.client = \"cli\";\n const frameworkVersion = resolveFrameworkVersion(args[\"--source\"] ?? process.cwd());\n if (frameworkVersion) body.frameworkVersion = frameworkVersion;\n\n let triggered: { deploymentId: string; deduplicated: boolean };\n try {\n const res = await client.functions.invoke<{\n success: boolean;\n deployment: { id: string | number };\n deduplicated?: boolean;\n }>(\"deploy\", body);\n if (!res?.deployment?.id) fail(\"Control plane did not return a deployment id.\");\n triggered = { deploymentId: String(res.deployment.id),\ndeduplicated: res.deduplicated === true };\n } catch (e) {\n resolveTriggerFailure(e);\n }\n const { deploymentId, deduplicated } = triggered;\n\n if (!isJsonMode()) {\n console.log(\n chalk.gray(\n deduplicated\n ? ` Deployment ${deploymentId} is already running — following it.`\n : ` Deployment ${deploymentId} created.${frameworkVersion ? ` (@rebasepro/* ${frameworkVersion})` : \"\"}`\n )\n );\n }\n\n if (args[\"--no-follow\"]) {\n emit(\n () => {\n console.log(chalk.gray(\" Not following logs (--no-follow). Check status with `rebase cloud logs`.\"));\n console.log(\"\");\n },\n { deploymentId,\ndeduplicated,\nframeworkVersion: frameworkVersion ?? null,\nfollowing: false,\n...warningPayload(warnings) }\n );\n await recordDeploy({ followed: false, status: \"not_followed\", deduplicated, frameworkVersion, startedAt });\n return;\n }\n\n if (!isJsonMode()) {\n console.log(chalk.gray(\" Streaming build logs (Ctrl-C to stop watching — the build keeps running):\"));\n console.log(\"\");\n }\n\n // In JSON mode the build log is not streamed: interleaving it with the\n // result object would make neither parseable. The deploy is still followed\n // to completion — a caller waiting on the exit code still waits — and the\n // one object printed at the end carries the outcome.\n //\n // Recorded as the follow ends, whatever it ends in: a failed build exits\n // non-zero from inside the follow, and recording after it only ever\n // recorded successes.\n const { status } = await streamBuildLogs(client, deploymentId, {\n quiet: isJsonMode(),\n timeoutMs: resolveDeployTimeout(args[\"--timeout\"]),\n projectId,\n url,\n onTerminal: (ended) => recordDeploy({ followed: true, status: ended, deduplicated, frameworkVersion, startedAt })\n });\n emit(\n () => {},\n { deploymentId,\ndeduplicated,\nframeworkVersion: frameworkVersion ?? null,\nfollowing: true,\nstatus,\n...warningPayload(warnings) }\n );\n}\n\n/** `--timeout <seconds>` for a deploy, or the 15-minute default. */\nexport function resolveDeployTimeout(value: string | undefined): number {\n return resolveTimeoutMs(value, { fallbackMs: POLL_TIMEOUT_MS,\ncommand: \"cloud deploy\" });\n}\n\n/**\n * Turn a failed trigger into an exit that says why.\n *\n * A 409 is a refusal, whoever holds the lock. The control plane answers a\n * replay of this very trigger — the same user sending the same uploaded\n * archive — with a 200 carrying `deduplicated: true`, which the success path\n * follows. So the deployment a 409 names is always a different one, and\n * `mine` means only that the same user started it: an earlier deploy, building\n * earlier code. Following it reported that deploy's verdict as this one's, and\n * the code just uploaded was never built.\n *\n * The refusal names the blocker, because \"which one, since when, from where\"\n * is the difference between an actionable refusal and a dead end.\n */\nfunction resolveTriggerFailure(e: unknown): never {\n const err = e as {\n status?: number;\n message?: string;\n code?: string;\n details?: { deployment?: BlockingDeployment };\n };\n\n if (err?.status === 409) {\n const blocking = err.details?.deployment;\n const where = blocking?.triggerSource && blocking.triggerSource !== \"unknown\"\n ? ` from the ${blocking.triggerSource}`\n : \"\";\n const who = blocking?.mine ? \", triggered by you\" : where ? \", triggered\" : \"\";\n // Older control planes send a bare 409 with no `details`; the message\n // then stays the honest general one rather than a fabricated id.\n fail(\n blocking?.id\n ? `Deployment ${blocking.id} is already in progress for this project${who}${where}` +\n `${blocking.createdAt ? ` at ${fmtDate(blocking.createdAt)}` : \"\"}.`\n : \"A deployment is already in progress for this project.\",\n blocking?.id\n ? `Nothing was deployed. Wait for it (\\`rebase cloud logs -f\\`) or stop it with \\`rebase cloud cancel ${blocking.id}\\`, then deploy again.`\n : \"Nothing was deployed. Wait for it (`rebase cloud logs -f`), then deploy again.\",\n \"deploy_in_progress\"\n );\n }\n\n if (err?.status === 402) {\n // Billing gate: no card on file, card declined, or needs auth.\n fail(\n err.message || \"Payment required before deploying.\",\n \"Attach a card once with `rebase cloud billing setup`, then deploy again.\",\n \"payment_required\"\n );\n }\n\n const refusal = intakeRefusal(e);\n if (refusal) fail(refusal.message, refusal.hint, refusal.code);\n\n reportError(e, \"Failed to trigger deployment\");\n}\n\n/**\n * Whether the project's owner turned platform rebuilds off.\n *\n * Only an explicit `false` counts: a project row that predates the switch, or\n * one that could not be read, is on — which is the default, and the control\n * plane refuses an upload it should not have anyway.\n */\nexport async function platformRebuildsOff(client: CloudClient, projectId: string): Promise<boolean> {\n try {\n const row: unknown = await client.data.collection(\"projects\").findById(projectId);\n return typeof row === \"object\" && row !== null && \"platformRebuilds\" in row && row.platformRebuilds === false;\n } catch {\n return false;\n }\n}\n\n/** The intake code for a bundle built on an older framework release than the project runs. */\nexport const FRAMEWORK_DOWNGRADE = \"FRAMEWORK_DOWNGRADE\";\n\n/**\n * An intake refusal, which is a decision about what was deployed rather than a\n * transport error — or undefined for anything else.\n *\n * It carries a stable code in `details.intakeCode` and usually a remedy in\n * `details.hint`, and both used to be discarded: the deploy printed `Failed to\n * trigger deployment (400): …` and threw the hint away. The managed path, where\n * bundles are refused, never looked for either. Both paths answer through this\n * now, in the three-argument shape `fail` takes, so `--json` carries the code\n * and a person sees the fix.\n *\n * A downgrade gets one more line, because its two remedies are both in this\n * CLI: move the project forward, or say the step back is meant.\n */\nexport function intakeRefusal(e: unknown): { message: string; hint: string; code: string } | undefined {\n if (typeof e !== \"object\" || e === null) return undefined;\n const status = \"status\" in e && typeof e.status === \"number\" ? e.status : undefined;\n const details = \"details\" in e && typeof e.details === \"object\" && e.details !== null ? e.details : undefined;\n const code = details && \"intakeCode\" in details && typeof details.intakeCode === \"string\" ? details.intakeCode : undefined;\n if (status === undefined || status < 400 || status >= 500 || !code) return undefined;\n\n const message = \"message\" in e && typeof e.message === \"string\" && e.message !== \"\" ? e.message : \"This bundle was refused.\";\n const serverHint = details && \"hint\" in details && typeof details.hint === \"string\" && details.hint !== \"\"\n ? details.hint\n : undefined;\n if (code === FRAMEWORK_DOWNGRADE) {\n const remedy = \"Run `rebase upgrade` to move this project's @rebasepro packages forward and deploy again, \"\n + \"or pass `--allow-downgrade` to deploy the older release on purpose.\";\n return { message, hint: serverHint ? `${serverHint}\\n ${remedy}` : remedy, code };\n }\n return { message, hint: serverHint ?? \"Run `rebase cloud compute` to see what this project reserves.\", code };\n}\n\n/**\n * Poll a deployment record and print new log output as it arrives. Returns the\n * terminal status; a non-success still exits non-zero, as it always has.\n *\n * `quiet` follows without printing — JSON mode, where the log stream would\n * corrupt the one object the caller is parsing.\n */\n/**\n * The host a project answers on — the same one `cloud status` prints, resolved\n * the same way, so the two commands cannot disagree about where the app is.\n *\n * `undefined` on any failure: the control plane may not report a base domain,\n * and a deploy that just succeeded must not be reported as anything else\n * because a cosmetic lookup did not.\n */\nexport async function deployedUrl(\n client: CloudClient,\n opts: { projectId?: string; url?: string }\n): Promise<string | undefined> {\n if (!opts.projectId || !opts.url) return undefined;\n try {\n const [project, baseDomain] = await Promise.all([\n client.data.collection(\"projects\").findById(opts.projectId),\n fetchTenantBaseDomain(client, opts.url)\n ]);\n if (!project) return undefined;\n return projectHost(project as { subdomain?: string; host?: string }, baseDomain);\n } catch {\n return undefined;\n }\n}\n\n/**\n * The line an in-progress build keeps rewriting at the end of its log, to prove\n * to the control plane that it is still alive.\n *\n * The control plane's own format — `HEARTBEAT_MARKER` and `heartbeatSuffix` in\n * its `functions/deploy.ts` — which appends `\\n<marker><ISO time>\\n` to the log\n * on every write and every 30 seconds, and drops it on the terminal write.\n */\nexport const BUILD_HEARTBEAT_MARKER = \"⏳ Build in progress — control-plane heartbeat \";\n\n/**\n * A deployment's log without its trailing heartbeat line: the build log itself.\n *\n * Only a heartbeat that is the last line is one. The same text anywhere else is\n * the build quoting it.\n */\nexport function withoutHeartbeat(logs: string): string {\n const at = logs.lastIndexOf(`\\n${BUILD_HEARTBEAT_MARKER}`);\n if (at < 0) return logs;\n const newline = logs.indexOf(\"\\n\", at + 1);\n return newline === -1 || newline === logs.length - 1 ? logs.slice(0, at) : logs;\n}\n\n/**\n * What to print of a deployment's log, given everything printed so far.\n *\n * The `logs` column is not append-only. Its heartbeat line is rewritten at the\n * end on every write, and a failed static deploy replaces its whole log with\n * one line. Diffing the raw column by length therefore cut the start off every\n * new chunk — as many characters as the heartbeat that had been there — and\n * printed heartbeat fragments in their place: a failed managed deploy lost the\n * first half of its reason.\n *\n * So the heartbeat is stripped first, and the log printed so far is compared\n * with the log now. When it has only grown, the new text is printed. When it\n * was rewritten, printing resumes from the start of the first line that\n * differs, on a line of its own.\n */\nexport function nextLogChunk(printed: string, rowLogs: string): { chunk: string; printed: string } {\n const logs = withoutHeartbeat(rowLogs);\n if (logs.startsWith(printed)) return { chunk: logs.slice(printed.length), printed: logs };\n // Shorter and already printed: nothing new to say.\n if (printed.startsWith(logs)) return { chunk: \"\", printed };\n\n let same = 0;\n while (same < logs.length && logs[same] === printed[same]) same++;\n const lineStart = logs.lastIndexOf(\"\\n\", same - 1) + 1;\n return { chunk: `${printed.endsWith(\"\\n\") ? \"\" : \"\\n\"}${logs.slice(lineStart)}`, printed: logs };\n}\n\nasync function streamBuildLogs(\n client: CloudClient,\n deploymentId: string,\n opts: {\n quiet?: boolean;\n timeoutMs?: number;\n projectId?: string;\n url?: string;\n /**\n * Called once with the state the follow ended in (a terminal status, or\n * `timeout`) before anything else happens, a non-zero exit included.\n */\n onTerminal?: (status: string) => Promise<void>;\n } = {}\n): Promise<{ status: string; logs: string }> {\n const quiet = opts.quiet === true;\n const timeoutMs = opts.timeoutMs ?? POLL_TIMEOUT_MS;\n let printed = \"\";\n const started = Date.now();\n /** When the current run of failed status reads began. */\n let unreadableSince: number | undefined;\n const stopIfTimedOut = async (): Promise<void> => {\n if (Date.now() - started <= timeoutMs) return;\n await opts.onTerminal?.(\"timeout\");\n if (!quiet) console.log(\"\");\n fail(\n `Timed out after ${Math.round(timeoutMs / 1000)}s waiting for the build to finish.`,\n \"The deployment may still be running — check `rebase cloud logs`.\",\n \"timeout\"\n );\n };\n\n for (;;) {\n let dep: Deployment | undefined;\n try {\n dep = (await client.data.collection(\"deployments\").findById(deploymentId)) as Deployment | undefined;\n unreadableSince = undefined;\n } catch (e) {\n // A read that failed says nothing about the build. A control plane\n // mid-rollout answers a request or two with a 502, and a connection\n // drops; ending the follow there reported a deploy that went on to\n // succeed as a failure, through the exit code that is its verdict.\n // So those are read again, for a while. A refusal is not transient.\n if (!transientReadFailure(e)) reportError(e, \"Failed to read deployment status\");\n unreadableSince ??= Date.now();\n if (Date.now() - unreadableSince > UNREADABLE_STATUS_MS) {\n await opts.onTerminal?.(\"status_unreadable\");\n fail(\n `Could not read deployment ${deploymentId}'s status for over a minute: ` +\n `${e instanceof Error ? e.message : String(e)}`,\n \"The deployment may still be running — check `rebase cloud logs`.\",\n \"status_unreadable\"\n );\n }\n await stopIfTimedOut();\n await sleep(POLL_INTERVAL_MS);\n continue;\n }\n if (!dep) fail(`Deployment ${deploymentId} disappeared.`, undefined, \"not_found\");\n\n const next = nextLogChunk(printed, dep.logs ?? \"\");\n if (!quiet && next.chunk !== \"\") process.stdout.write(next.chunk);\n printed = next.printed;\n\n if (dep.status && dep.status !== \"deploying\") {\n await opts.onTerminal?.(dep.status);\n if (dep.status !== \"success\") {\n if (quiet) {\n // The failure still has to be reportable, and in JSON mode\n // the build log is the only place that says why.\n printJson({\n error: {\n message: `Deployment ${deploymentId} ${dep.status}.`,\n code: \"deploy_failed\",\n status: null,\n deploymentId,\n logs: withoutHeartbeat(dep.logs ?? \"\")\n }\n });\n process.exit(1);\n }\n console.log(\"\");\n console.log(chalk.bold.red(` ✗ Deployment ${dep.status}`));\n console.log(\"\");\n process.exit(1);\n }\n if (!quiet) {\n console.log(\"\");\n console.log(chalk.bold.green(\" ✓ Deployment succeeded\"));\n // The URL. A deploy that says only \"succeeded\" leaves the one\n // thing the whole command was for — the address the app now\n // answers on — to a second command (`cloud status`), and the\n // person who just watched a build finish has to go and ask.\n //\n // Best-effort and silent when it cannot be resolved: a URL is\n // not worth failing a successful deploy over, and a fabricated\n // host is worse than none.\n const url = await deployedUrl(client, opts);\n if (url) console.log(` ${chalk.cyan(`https://${url}`)}`);\n console.log(\"\");\n }\n return { status: dep.status, logs: withoutHeartbeat(dep.logs ?? \"\") };\n }\n\n await stopIfTimedOut();\n await sleep(POLL_INTERVAL_MS);\n }\n}\n\n/**\n * Whether a failed status read is worth reading again: no answer at all (the\n * connection failed), or one saying the control plane could not answer now.\n * Anything else — a 401, a 403, a 404 — will say the same next time.\n */\nfunction transientReadFailure(e: unknown): boolean {\n const status = typeof e === \"object\" && e !== null && \"status\" in e && typeof e.status === \"number\"\n ? e.status\n : undefined;\n return status === undefined || status === 408 || status === 429 || status >= 500;\n}\n\n/** What `rebase cloud logs` parses. Its page pairs against this. */\nexport const LOGS_FLAGS = {\n \"--runtime\": Boolean,\n \"--follow\": Boolean,\n \"-f\": \"--follow\"\n} as const;\n\nexport async function logsCommand(rawArgs: string[], projectRef: string): Promise<void> {\n // Strict: `--folow` used to be dropped, so a caller that asked to follow\n // the log got one snapshot and an exit code.\n const { flags: args } = parseCloudArgs({\n spec: LOGS_FLAGS,\n rawArgs,\n commandWords: 2, // cloud logs\n command: \"cloud logs\",\n maxPositionals: 0\n });\n const { client, url } = await requireClient(rawArgs);\n const projectId = await resolveProjectRef(projectRef, client);\n\n if (args[\"--runtime\"]) {\n try {\n const res = await client.functions.invoke<{ logs?: string; error?: string }>(\n \"runtime-logs\",\n undefined,\n { method: \"GET\",\npath: projectId }\n );\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 📄 Runtime logs — project ${projectRef}`));\n console.log(\"\");\n console.log(res.logs ?? chalk.gray(\" (no logs)\"));\n console.log(\"\");\n },\n { runtime: true,\nlogs: res.logs ?? null }\n );\n } catch (e) {\n reportError(e, \"Failed to fetch runtime logs\");\n }\n return;\n }\n\n // Build logs: latest deployment, optionally follow if still running.\n //\n // In JSON mode the page is one object, `{ deploymentId, status, logs }`: it\n // used to be the human page whatever the mode, so `cloud logs --json | jq`\n // failed on every run. The log is the build's, without the heartbeat line a\n // running build keeps rewriting at its end.\n try {\n const dep = (await latestDeployment(client, projectId)) as Deployment | undefined;\n if (!dep) {\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.gray(\" No deployments yet for this project.\"));\n console.log(\"\");\n },\n { deploymentId: null,\nstatus: null,\nlogs: null }\n );\n return;\n }\n\n const deploymentId = String(dep.id);\n if (args[\"--follow\"] && dep.status === \"deploying\") {\n if (!isJsonMode()) {\n console.log(\"\");\n console.log(chalk.bold(` 📄 Build logs — deployment ${dep.id}`) + ` ${colorStatus(dep.status)}`);\n console.log(\"\");\n }\n // Hand off to the streamer, which prints from the top and tails live.\n const { status, logs } = await streamBuildLogs(client, deploymentId, { quiet: isJsonMode(),\nprojectId,\nurl });\n emit(() => {}, { deploymentId,\nstatus,\nlogs });\n return;\n }\n\n const logs = dep.logs == null ? null : withoutHeartbeat(dep.logs);\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 📄 Build logs — deployment ${dep.id}`) + ` ${colorStatus(dep.status)}`);\n console.log(\"\");\n console.log(logs ?? chalk.gray(\" (no logs)\"));\n console.log(\"\");\n },\n { deploymentId,\nstatus: dep.status ?? null,\nlogs }\n );\n } catch (e) {\n reportError(e, \"Failed to fetch build logs\");\n }\n}\n","/**\n * `rebase cloud orgs` — list / create / members.\n */\nimport chalk from \"chalk\";\nimport inquirer from \"inquirer\";\nimport {\n requireClient,\n parseCloudArgs,\n getContextOrg,\n setContextOrg,\n colorStatus,\n success,\n fail,\n reportError,\n emit,\n printGroupHelp,\n note,\n requireInteractive,\n cloudRows,\n requireCloudRow\n} from \"./context\";\n\ninterface OrgRow {\n id: string | number;\n name?: string;\n slug?: string;\n description?: string;\n createdAt?: string;\n}\n\nexport async function orgsCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n switch (subcommand) {\n case \"list\":\n case undefined:\n await listOrgs(rawArgs);\n break;\n case \"create\":\n await createOrg(rawArgs);\n break;\n case \"members\":\n await listMembers(rawArgs);\n break;\n case \"--help\":\n printOrgsHelp();\n break;\n default:\n fail(`Unknown orgs command: ${subcommand}`, \"Run `rebase cloud orgs --help`.\", \"unknown_command\");\n }\n}\n\nasync function listOrgs(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud orgs\",\nmaxPositionals: 0 });\n const { client, url } = await requireClient(rawArgs);\n try {\n const orgs = cloudRows<OrgRow>((await client.data.collection(\"organizations\").find({ limit: 100 })).data);\n const active = getContextOrg(url);\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(\" 🏢 Organizations\"));\n console.log(\"\");\n if (orgs.length === 0) {\n console.log(chalk.gray(\" You are not a member of any organization.\"));\n console.log(\"\");\n return;\n }\n for (const o of orgs) {\n const marker = String(o.id) === active ? chalk.green(\" ●\") : \" \";\n console.log(`${marker}${chalk.bold(o.name ?? \"(unnamed)\")} ${chalk.gray(`[${o.id}]`)}${o.slug ? chalk.gray(` ${o.slug}`) : \"\"}`);\n }\n console.log(\"\");\n // The legend explains the ● glyph, which only exists in the\n // human rendering — `active: true` needs no legend.\n note(chalk.gray(\"● = active organization. Switch with `rebase cloud use <id>`.\"));\n console.log(\"\");\n },\n {\n activeOrg: active ?? null,\n organizations: orgs.map((o) => ({\n id: String(o.id),\n name: o.name ?? null,\n slug: o.slug ?? null,\n active: String(o.id) === active\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list organizations\");\n }\n}\n\n/** What `rebase cloud orgs create` parses. Its page is the group's own. */\nexport const CREATE_ORG_FLAGS = {\n \"--name\": String,\n \"--slug\": String,\n \"-n\": \"--name\"\n} as const;\n\nasync function createOrg(rawArgs: string[]): Promise<void> {\n // Strict: `--nmae \"Acme\"` used to be dropped, and the command then prompted\n // for a name — or, off a terminal, refused for one that had been given.\n const { flags: args } = parseCloudArgs({\n spec: CREATE_ORG_FLAGS,\n rawArgs,\n commandWords: 3, // cloud orgs create\n command: \"cloud orgs\",\n maxPositionals: 0\n });\n const { client, url } = await requireClient(rawArgs);\n\n const prompts: Array<{ type: \"input\"; name: string; message: string }> = [];\n if (!args[\"--name\"]) {\n requireInteractive(\"an organization name\", \"--name <name>\");\n prompts.push({ type: \"input\",\nname: \"name\",\nmessage: \"Organization name:\" });\n }\n const answers = prompts.length\n ? await inquirer.prompt(prompts)\n : {};\n\n const name = (args[\"--name\"] || (answers as { name?: string }).name || \"\").trim();\n if (!name) fail(\"Organization name is required.\", \"Pass `--name <name>`.\", \"input_required\");\n const slug = (args[\"--slug\"] || slugify(name)).trim();\n\n try {\n const created = requireCloudRow<OrgRow>(await client.data.collection(\"organizations\").create({\n name,\n slug,\n createdAt: new Date().toISOString()\n }), \"organization\");\n setContextOrg(url, String(created.id));\n success(`Created organization ${chalk.bold(name)} and set it active`);\n emit(() => {}, {\n success: true,\n id: String(created.id),\n name,\n slug,\n setActive: true\n });\n } catch (e) {\n reportError(e, \"Failed to create organization\");\n }\n}\n\nasync function listMembers(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud orgs\",\nmaxPositionals: 0 });\n const { client, url } = await requireClient(rawArgs);\n const org = getContextOrg(url);\n if (!org) fail(\"No active organization.\", \"Run `rebase cloud use` first.\", \"no_org\");\n\n try {\n const members = (await client.data.collection(\"organization-members\").find({\n where: { organization: [\"==\", org] },\n limit: 200\n })).data as Array<{ id: string | number; userId?: string; role?: string }>;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 👥 Members — org ${org}`));\n console.log(\"\");\n if (members.length === 0) {\n console.log(chalk.gray(\" No members found.\"));\n console.log(\"\");\n return;\n }\n for (const m of members) {\n console.log(` ${chalk.bold(m.userId ?? \"?\")} ${colorStatus(m.role)}`);\n }\n console.log(\"\");\n },\n {\n org,\n members: members.map((m) => ({\n id: String(m.id),\n userId: m.userId ?? null,\n role: m.role ?? null\n }))\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list members\");\n }\n}\n\nfunction slugify(s: string): string {\n return s\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\n\nexport function printOrgsHelp(): void {\n printGroupHelp({\n command: \"cloud orgs\",\n title: \"Organizations\",\n actions: [\n { action: \"list\",\ndescription: \"List organizations you belong to\" },\n {\n action: \"create\",\n description: \"Create a new organization\",\n flags: [\n [\"--name <name>\", \"Display name\"],\n [\"--slug <slug>\", \"URL slug. Derived from the name when omitted\"]\n ]\n },\n { action: \"members\",\ndescription: \"List members of the active organization\" }\n ],\n notes: [\"The active one is what `rebase cloud use` selects, and what billing is scoped to.\"]\n });\n}\n","/**\n * `rebase cloud env` — a project's environment variables.\n *\n * env list Keys only — a value is NEVER printed here\n * env set KEY=VALUE Create/replace one variable (`--secret` ⇒ write-only)\n * env unset KEY Remove one variable\n * env reveal KEY Release one non-secret value (a secret var 403s)\n * env pull [--out .env] Write revealable values to a local dotenv file\n *\n * Values are the sharp edge here. The list endpoint returns keys and never\n * values by design (a page load is not consent to spray a customer's secrets\n * through caches and logs), and a `--secret` variable is write-only: it can be\n * replaced but never read back. This mirrors `env-vars` exactly and refuses to\n * offer reveal for a secret variable rather than letting the server 403.\n */\nimport chalk from \"chalk\";\nimport fs from \"fs\";\nimport path from \"path\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n printGroupHelp,\n confirmDestructive,\n keyValues,\n success,\n fail,\n reportError,\n type CloudClient\n} from \"./context\";\n\n/**\n * Reserved names the control plane will release the value of.\n *\n * They carry no row, so the listing above cannot see them, and a CLI that\n * required a row refused them before the server got a say. Kept as a list here\n * only so the refusal is skipped — the server is what decides, and it holds the\n * same allowlist for the reasons set out there.\n */\nconst PLATFORM_REVEALABLE_KEYS = [\"REBASE_SERVICE_KEY\"];\n\ninterface EnvVarView {\n id: string;\n key: string;\n secret: boolean;\n valueSet: boolean;\n createdAt: string | null;\n updatedAt: string | null;\n}\n\ninterface EnvVarListResponse {\n vars: EnvVarView[];\n pendingRedeploy: boolean | null;\n pendingSince: string | null;\n limits: {\n maxVars: number;\n maxValueBytes: number;\n maxTotalBytes: number;\n keyPattern: string;\n reservedKeys: string[];\n };\n}\n\nasync function fetchEnvVars(client: CloudClient, projectId: string): Promise<EnvVarListResponse> {\n return client.functions.invoke<EnvVarListResponse>(\"env-vars\", undefined, {\n method: \"GET\",\n path: projectId\n });\n}\n\nexport async function envCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"list\":\n case undefined:\n await listEnv(rawArgs);\n break;\n case \"set\":\n await setEnv(rawArgs);\n break;\n case \"unset\":\n case \"delete\":\n case \"rm\":\n await unsetEnv(rawArgs, action);\n break;\n case \"reveal\":\n await revealEnv(rawArgs);\n break;\n case \"pull\":\n await pullEnv(rawArgs);\n break;\n case \"--help\":\n printEnvHelp();\n break;\n default:\n fail(`Unknown env command: ${action}`, \"Run `rebase cloud env --help`.\", \"unknown_command\");\n }\n}\n\n/** A short human hint about redeploy state (the JSON carries `pendingRedeploy`). */\nfunction pendingHint(pending: boolean | null): string | undefined {\n if (pending === true) return chalk.yellow(\"A variable changed since the last deploy — run `rebase cloud deploy` to apply it.\");\n if (pending === null) return chalk.gray(\"Redeploy state is unknown (deployment history unavailable).\");\n return undefined;\n}\n\nasync function listEnv(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud env\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const res = await fetchEnvVars(client, projectId);\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🔑 Environment — project ${projectRef}`));\n console.log(\"\");\n if (!res.vars.length) {\n console.log(chalk.gray(\" No variables. Add one with `rebase cloud env set KEY=VALUE`.\"));\n console.log(\"\");\n return;\n }\n for (const v of res.vars) {\n const badges = [\n v.secret ? chalk.magenta(\"secret\") : undefined,\n v.valueSet ? undefined : chalk.gray(\"empty\")\n ]\n .filter(Boolean)\n .join(\" \");\n // Deliberately no value — reveal is the only way to read one.\n console.log(` ${chalk.bold(v.key)}${badges ? ` ${badges}` : \"\"}`);\n }\n const hint = pendingHint(res.pendingRedeploy);\n if (hint) {\n console.log(\"\");\n console.log(` ${hint}`);\n }\n console.log(\"\");\n },\n {\n projectId,\n pendingRedeploy: res.pendingRedeploy,\n pendingSince: res.pendingSince,\n // Never a value: keys + shape only.\n vars: res.vars.map((v) => ({\n key: v.key,\n secret: v.secret,\n valueSet: v.valueSet,\n createdAt: v.createdAt,\n updatedAt: v.updatedAt\n })),\n limits: res.limits\n }\n );\n } catch (e) {\n reportError(e, \"Failed to list environment variables\");\n }\n}\n\n/** Parse `KEY=VALUE` or `KEY VALUE` from the positional operands. */\nexport function parseEnvAssignment(operands: string[]): { key: string; value: string } | null {\n const first = operands[0];\n if (!first) return null;\n const eq = first.indexOf(\"=\");\n if (eq > 0) {\n return { key: first.slice(0, eq).trim(),\nvalue: first.slice(eq + 1) };\n }\n // `set KEY VALUE` form — VALUE is the next operand (may be absent ⇒ empty).\n return { key: first.trim(),\nvalue: operands[1] ?? \"\" };\n}\n\n/**\n * Prefixes whose variables are read by a BUNDLER at build time, not by the\n * process at run time.\n *\n * These are the ones this command cannot deliver. A project's environment is\n * applied at rollout — after Kaniko has already built the image — so a\n * `VITE_API_URL` set here is present in the running container and absent from\n * the JavaScript that was compiled minutes earlier. Nothing fails: the variable\n * exists, the deploy succeeds, and the bundle carries `undefined` where the\n * value should be. The bug then presents in the browser as missing\n * configuration, which is several steps away from the cause.\n *\n * `import.meta.env` inlining is Vite's; `NEXT_PUBLIC_`/`PUBLIC_`/`REACT_APP_`\n * are the same contract in Next, Astro/SvelteKit and CRA.\n */\nconst BUILD_TIME_ENV_PREFIXES = [\"VITE_\", \"NEXT_PUBLIC_\", \"PUBLIC_\", \"REACT_APP_\"];\n\n/** The prefix that makes `key` a build-time variable, or undefined. */\nexport function buildTimeEnvPrefix(key: string): string | undefined {\n return BUILD_TIME_ENV_PREFIXES.find((prefix) => key.toUpperCase().startsWith(prefix));\n}\n\n/** The flags `rebase cloud env set` takes, on top of the global cloud ones. */\nexport const ENV_SET_FLAGS = {\n \"--secret\": Boolean,\n \"--force\": Boolean\n} as const;\n\n/**\n * What `env set` was asked to store.\n *\n * The sharp one in this family: the old operand filter left `--project`'s value\n * in the operand list, so `rebase cloud env set KEY -p acme` parsed as the\n * `KEY VALUE` form and stored the project slug as KEY's value — a write that\n * succeeds, reports success, and is wrong. Strict parsing consumes `-p` with\n * its value, leaving `[\"KEY\"]` and the documented empty value.\n *\n * A value beginning with `-` must use the `KEY=-v` form; the bare `KEY -v` form\n * is refused rather than guessed at, as everywhere else strict parsing is used.\n *\n * Exported so its tests drive the real parser rather than a copy of it.\n */\nexport function resolveEnvSetArgs(rawArgs: string[]) {\n const { flags, positionals } = parseCloudArgs({\n spec: ENV_SET_FLAGS,\n rawArgs,\n commandWords: 3, // cloud env set\n command: \"cloud env set\",\n maxPositionals: 2 // KEY=VALUE, or KEY VALUE\n });\n return { flags,\nassignment: parseEnvAssignment(positionals) };\n}\n\nasync function setEnv(rawArgs: string[]): Promise<void> {\n const { flags: args, assignment: parsed } = resolveEnvSetArgs(rawArgs);\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n if (!parsed || !parsed.key) {\n fail(\"Usage: rebase cloud env set KEY=VALUE [--secret]\", undefined, \"usage\");\n }\n\n // Refused rather than warned. A warning is the wrong instrument here: this\n // command is most often run non-interactively, where a warning scrolls past\n // and the variable is stored anyway — leaving a project that looks\n // configured, deploys clean, and is broken in the browser. `--force` exists\n // because a custom build could legitimately read one of these at run time.\n const buildTimePrefix = buildTimeEnvPrefix(parsed!.key);\n if (buildTimePrefix && !args[\"--force\"]) {\n fail(\n `${parsed!.key} is read by your bundler at BUILD time, and project variables are applied at ` +\n \"rollout — after the image is built. Setting it here would not reach the bundle.\",\n // Per deploy path, because the two read it in different places. A\n // managed deploy builds the frontend on this machine; a `--source`\n // build runs on the platform from an upload that never carries an\n // `.env` file (see `neverUploaded`).\n // `VITE_API_URL` is the exception: the local build reads it from the\n // shell alone (`staticBuildEnv`), never from a file.\n \"A managed deploy builds the frontend on this machine: set it in your shell when you run \" +\n `\\`rebase cloud deploy\\`${parsed!.key === \"VITE_API_URL\" ? \"\" : \", or in the app's .env.production\"}. ` +\n \"A --source build runs on the platform and \" +\n \"never receives .env files: set it in the build itself — an ENV line in your Dockerfile, or \" +\n \"`define` in your bundler config. Pass --force if your build genuinely reads this at run time.\",\n \"build_time_variable\"\n );\n }\n\n const body: { key: string; value: string; secret?: boolean } = { key: parsed!.key,\nvalue: parsed!.value };\n if (args[\"--secret\"]) body.secret = true;\n\n try {\n const res = await client.functions.invoke<{ success: boolean; var: EnvVarView; pendingRedeploy: true }>(\n \"env-vars\",\n body,\n { path: projectId }\n );\n emit(\n () => {\n success(`Set ${chalk.bold(res.var.key)}${res.var.secret ? chalk.magenta(\" (secret)\") : \"\"}`);\n console.log(` ${chalk.yellow(\"Pending redeploy\")} — run \\`rebase cloud deploy\\` to apply it.`);\n console.log(\"\");\n },\n {\n success: true,\n key: res.var.key,\n secret: res.var.secret,\n valueSet: res.var.valueSet,\n pendingRedeploy: res.pendingRedeploy\n }\n );\n } catch (e) {\n reportError(e, \"Failed to set environment variable\");\n }\n}\n\n/**\n * The variable `env unset` / `env reveal` names.\n *\n * `unset` is a delete, and the operand filter aimed it at the wrong variable:\n * `rebase cloud env unset -p acme` removed a variable called \"acme\" from the\n * linked project instead of reporting a missing KEY, and `env unset -p acme\n * KEY` removed \"acme\" instead of KEY. Both read `--project`'s value as the\n * operand — a plain word in the right position that no flag filter can catch.\n *\n * `action` is the word the caller used (`unset`, `rm`, `delete`, `reveal`); the\n * count of command words is the same for all of them.\n */\nexport function resolveEnvKeyArg(rawArgs: string[], action: string): string | undefined {\n return parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud env <action>\n command: `cloud env ${action}`,\n maxPositionals: 1\n }).positionals[0];\n}\n\nasync function unsetEnv(rawArgs: string[], action: string): Promise<void> {\n const key = resolveEnvKeyArg(rawArgs, action);\n // Refused before the login round-trip: an unusable line is unusable whether\n // or not there is a session behind it.\n if (!key) fail(\"Usage: rebase cloud env unset KEY\", undefined, \"usage\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n try {\n const res = await client.functions.invoke<{ success: boolean; pendingRedeploy: true }>(\"env-vars\", undefined, {\n method: \"DELETE\",\n path: `${projectId}/${encodeURIComponent(key!)}`\n });\n emit(\n () => {\n success(`Removed ${chalk.bold(key!)}`);\n console.log(` ${chalk.yellow(\"Pending redeploy\")} — run \\`rebase cloud deploy\\` to apply it.`);\n console.log(\"\");\n },\n { success: true,\nkey,\npendingRedeploy: res.pendingRedeploy }\n );\n } catch (e) {\n reportError(e, \"Failed to remove environment variable\");\n }\n}\n\nasync function revealEnv(rawArgs: string[]): Promise<void> {\n const key = resolveEnvKeyArg(rawArgs, \"reveal\");\n if (!key) fail(\"Usage: rebase cloud env reveal KEY\", undefined, \"usage\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n // Pre-check: a secret variable is write-only. Don't even ask the server — it\n // would 403 — say so plainly and never offer reveal for it. Done OUTSIDE the\n // reveal try so a deliberate refusal is not re-wrapped as a server error.\n let list: EnvVarListResponse;\n try {\n list = await fetchEnvVars(client, projectId);\n } catch (e) {\n reportError(e, \"Failed to reveal environment variable\");\n }\n const found = list!.vars.find((v) => v.key === key);\n // A platform-managed name has no row in the listing, because the platform\n // computes it and injects it at deploy time rather than storing it. Refusing\n // here on the strength of an absent row is how `env reveal\n // REBASE_SERVICE_KEY` came to answer \"No variable named REBASE_SERVICE_KEY\"\n // for a value that very much exists — and that the tenant API recommends by\n // name as the way out of \"API keys cannot manage API keys\". The server\n // decides which of these it will release; this only stops pre-empting it.\n if (!found && !PLATFORM_REVEALABLE_KEYS.includes(key!)) {\n fail(`No variable named ${key} in project ${projectRef}.`, undefined, \"not_found\");\n }\n if (found?.secret) {\n fail(\n `${key} is a secret (write-only) variable; its value cannot be revealed.`,\n \"Replace it with `rebase cloud env set KEY=VALUE` if you need to change it.\",\n \"secret_write_only\"\n );\n }\n\n try {\n const res = await client.functions.invoke<{ key: string; value: string }>(\n \"env-vars\",\n { projectId,\nkey },\n { path: \"reveal\" }\n );\n emit(\n () => {\n console.log(\"\");\n console.log(` ${chalk.bold(res.key)}=${res.value}`);\n console.log(\"\");\n },\n { key: res.key,\nvalue: res.value }\n );\n } catch (e) {\n reportError(e, \"Failed to reveal environment variable\");\n }\n}\n\n/**\n * One `KEY=value` line that dotenv reads back as exactly `value`, or null when\n * no quoting can carry it.\n *\n * dotenv's quoting is not JSON's, and `JSON.stringify` was what this used: a\n * double-quoted value has only `\\n` and `\\r` unescaped, so every other\n * backslash stayed and `{\"a\":1}` came back as `{\\\"a\\\":1}`. Single quotes and\n * backticks are literal — nothing inside is unescaped, and either may span\n * lines — so they carry any value without their own quote character. Double\n * quotes come last: they cannot hold a `\"` or a literal backslash-n, and they\n * are the only way to carry a carriage return, which dotenv folds into a\n * newline everywhere else.\n */\nexport function dotenvLine(key: string, value: string): string | null {\n // Unquoted, a value is cut at `#`, trimmed, and read as quoted when it\n // starts with a quote character.\n if (!/[\\s#'\"`\\\\]/.test(value)) return `${key}=${value}`;\n if (!value.includes(\"\\r\")) {\n if (!value.includes(\"'\")) return `${key}='${value}'`;\n if (!value.includes(\"`\")) return `${key}=\\`${value}\\``;\n }\n if (!value.includes(\"\\\"\") && !/\\\\[nr]/.test(value)) {\n return `${key}=\"${value.replace(/\\r/g, \"\\\\r\").replace(/\\n/g, \"\\\\n\")}\"`;\n }\n return null;\n}\n\nasync function pullEnv(rawArgs: string[]): Promise<void> {\n // Strict: this writes a file, and the permissive parse accepted\n // `env pull --ouput creds.env` by ignoring the typo and overwriting `.env`.\n const { flags: args } = parseCloudArgs({\n spec: { \"--output\": String,\n\"--out\": \"--output\" },\n rawArgs,\n commandWords: 3, // cloud env pull\n command: \"cloud env pull\",\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n const outPath = path.resolve(args[\"--output\"] || \".env\");\n\n try {\n const list = await fetchEnvVars(client, projectId);\n\n if (fs.existsSync(outPath)) {\n await confirmDestructive({ yes: Boolean(args[\"--yes\"]),\nprompt: `Overwrite ${outPath}?` });\n }\n\n // Only non-secret, value-set variables can be written — a secret var is\n // write-only and reveal 403s, so it is honestly skipped, not faked.\n const written: string[] = [];\n const skipped: Array<{ key: string; reason: string }> = [];\n const lines: string[] = [];\n for (const v of list.vars) {\n if (v.secret) {\n skipped.push({ key: v.key,\nreason: \"secret (write-only)\" });\n continue;\n }\n if (!v.valueSet) {\n lines.push(`${v.key}=`);\n written.push(v.key);\n continue;\n }\n const revealed = await client.functions.invoke<{ key: string; value: string }>(\n \"env-vars\",\n { projectId,\nkey: v.key },\n { path: \"reveal\" }\n );\n const line = dotenvLine(v.key, revealed.value);\n if (line === null) {\n skipped.push({ key: v.key,\nreason: \"no .env quoting carries this value unchanged\" });\n continue;\n }\n lines.push(line);\n written.push(v.key);\n }\n\n fs.writeFileSync(outPath, lines.length ? lines.join(\"\\n\") + \"\\n\" : \"\", { mode: 0o600 });\n\n emit(\n () => {\n success(`Wrote ${written.length} variable${written.length === 1 ? \"\" : \"s\"} to ${outPath}`);\n if (skipped.length) {\n for (const s of skipped) console.log(chalk.gray(` Skipped ${s.key}: ${s.reason}`));\n console.log(\"\");\n }\n },\n { success: true,\npath: outPath,\nwritten,\nskipped }\n );\n } catch (e) {\n reportError(e, \"Failed to pull environment variables\");\n }\n}\n\nexport function printEnvHelp(): void {\n printGroupHelp({\n command: \"cloud env\",\n title: \"Environment variables\",\n actions: [\n { action: \"list\",\ndescription: \"List keys — values are never printed\" },\n {\n action: \"set\",\n args: \"KEY=VALUE\",\n description: \"Create or replace a variable\",\n flags: [\n [\"--secret\", \"Mark it write-only: it can be set and used, never read back\"],\n [\"--force\", \"Set a build-time key anyway\"]\n ]\n },\n { action: \"unset\",\nargs: \"KEY\",\ndescription: \"Remove a variable\" },\n { action: \"reveal\",\nargs: \"KEY\",\ndescription: \"Print one non-secret value\" },\n {\n action: \"pull\",\n description: \"Write revealable values to a dotenv file\",\n flags: [[\"--output, --out <file>\", \"Where to write it. Default: .env\"]]\n }\n ],\n notes: [\n \"Values are encrypted at rest (AES-256-GCM) and only decrypted at deploy time.\",\n \"VITE_* / NEXT_PUBLIC_* / PUBLIC_* / REACT_APP_* are read by your bundler at BUILD time;\",\n \"these are applied at rollout, after the image is built, so they never reach the bundle.\"\n ]\n });\n}\n","/**\n * `rebase cloud domains` — the hostnames a project is served on.\n *\n * domains list Every host, its status, and the DNS records it needs\n * domains add <domain> Register a host (starts, does not finish, setup)\n * domains verify [domain] Check the host's published DNS now; live only if it passes\n * domains remove <domain> Stop serving a host\n *\n * A project's hosts are rows of the control plane's `project_domains` table,\n * managed through its `domains` function — the same one the console uses. The\n * Ingress is built from those rows, one verified host at a time, so every\n * action here addresses a row. The single `projects.customDomain` column is a\n * projection the control plane keeps in step with them; writing it directly\n * changes nothing that is served.\n *\n * Two cases still go through that column, because the control plane still\n * serves them from it: a project with no rows at all, whose one domain lives\n * only in the column, and a control plane that has no `domains` function.\n *\n * The DNS record set comes from the server, never composed here: whether to\n * publish an A or a CNAME depends on apex-vs-subdomain and on the ingress\n * address behind the tenant host, which the CLI cannot know. Adding a host only\n * registers it — it is unverified until the records are published and `verify`\n * passes.\n */\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n printGroupHelp,\n confirmDestructive,\n keyValues,\n success,\n fail,\n warn,\n reportError,\n type CloudClient\n} from \"./context\";\n\ninterface DomainRecord {\n type: \"A\" | \"CNAME\" | \"TXT\";\n name: string;\n values: string[];\n}\n\ninterface DomainInstructions {\n pointing?: DomainRecord;\n ownership: DomainRecord;\n}\n\n/**\n * One host, as the `domains` function describes a row.\n *\n * `id` is null for the domain a project holds only in its single column: it\n * has no row, and is verified and removed through that column instead.\n */\ninterface DomainEntry {\n id: string | null;\n host: string;\n primary: boolean;\n status: \"pending\" | \"verified\";\n verifiedAt: string | null;\n isApex?: boolean;\n tenantHost?: string;\n instructions?: DomainInstructions;\n}\n\n/** What `verify-domain` answers about the single column. */\ninterface ColumnSetup {\n domain: string | null;\n status: \"none\" | \"pending\" | \"verified\";\n isApex?: boolean;\n tenantHost?: string;\n verifiedAt?: string | null;\n instructions?: DomainInstructions;\n}\n\n/** A row as the `domains` function sends it. */\ninterface DomainRow {\n id?: string;\n host?: string;\n primary?: boolean;\n status?: string;\n verifiedAt?: string | null;\n isApex?: boolean;\n tenantHost?: string;\n instructions?: DomainInstructions;\n}\n\ninterface DomainCheck {\n ok: boolean;\n expected: string[];\n observed: string[];\n error?: string;\n}\n\ninterface DomainChecks {\n ownership: DomainCheck;\n pointing: DomainCheck;\n}\n\n/** What either door answers a verification with: the host as it is now, and the checks. */\ninterface VerifyAnswer {\n verified?: boolean;\n checks?: DomainChecks;\n status?: string;\n verifiedAt?: string | null;\n instructions?: DomainInstructions;\n}\n\n/** A project's hosts, and which door changes them. */\ninterface DomainSet {\n /**\n * `rows` — the `domains` function answers, and each host with an id is a row.\n * `column` — the control plane has no `domains` function; everything goes\n * through the single column.\n */\n model: \"rows\" | \"column\";\n tenantHost?: string;\n domains: DomainEntry[];\n}\n\n/** The column's one domain as an entry, or none. */\nfunction columnEntry(setup: ColumnSetup): DomainEntry[] {\n if (!setup.domain) return [];\n return [{\n id: null,\n host: setup.domain,\n primary: true,\n status: setup.status === \"verified\" ? \"verified\" : \"pending\",\n verifiedAt: setup.verifiedAt ?? null,\n isApex: setup.isApex,\n tenantHost: setup.tenantHost,\n instructions: setup.instructions\n }];\n}\n\n/**\n * A row, or null for one with no id or host — it cannot be verified or removed,\n * so it is not offered as a domain. Anything but `verified` is pending: an\n * unreadable status must not read as live.\n */\nfunction rowEntry(row: DomainRow | null | undefined): DomainEntry | null {\n if (typeof row?.id !== \"string\" || typeof row.host !== \"string\") return null;\n return {\n id: row.id,\n host: row.host,\n primary: row.primary === true,\n status: row.status === \"verified\" ? \"verified\" : \"pending\",\n verifiedAt: row.verifiedAt ?? null,\n isApex: row.isApex,\n tenantHost: row.tenantHost,\n instructions: row.instructions\n };\n}\n\n/**\n * Whether a failed `domains` call means the control plane has no such function\n * — as opposed to refusing this project, which the function answers `not_found`.\n */\nfunction noDomainsFunction(e: unknown): boolean {\n if (typeof e !== \"object\" || e === null) return false;\n const status = \"status\" in e ? e.status : undefined;\n const code = \"code\" in e ? e.code : undefined;\n return status === 404 && code !== \"not_found\";\n}\n\nasync function fetchColumnSetup(client: CloudClient, projectId: string): Promise<ColumnSetup> {\n return client.functions.invoke<ColumnSetup>(\"verify-domain\", undefined, { method: \"GET\",\npath: projectId });\n}\n\n/** Every host this project is served on, or may be once verified. */\nasync function loadDomains(client: CloudClient, projectId: string): Promise<DomainSet> {\n let listed: { tenantHost?: string; domains?: DomainRow[] };\n try {\n listed = await client.functions.invoke<{ tenantHost?: string; domains?: DomainRow[] }>(\n \"domains\",\n undefined,\n { method: \"GET\",\npath: projectId }\n );\n } catch (e) {\n if (!noDomainsFunction(e)) throw e;\n const setup = await fetchColumnSetup(client, projectId);\n return { model: \"column\",\ntenantHost: setup.tenantHost,\ndomains: columnEntry(setup) };\n }\n\n const domains = (listed.domains ?? []).map(rowEntry).filter((d): d is DomainEntry => d !== null);\n if (domains.length > 0) return { model: \"rows\",\ntenantHost: listed.tenantHost,\ndomains };\n\n // No rows: the control plane serves the column's domain, if it holds one.\n const setup = await fetchColumnSetup(client, projectId);\n return { model: \"rows\",\ntenantHost: listed.tenantHost ?? setup.tenantHost,\ndomains: columnEntry(setup) };\n}\n\n/**\n * The host an action names, or the only one there is to name.\n *\n * Refuses to guess among several: removing or verifying the wrong host of a\n * live site is not a mistake worth saving a word over.\n */\nfunction pickDomain(set: DomainSet, named: string | undefined, action: string): DomainEntry {\n if (named) {\n const wanted = named.trim().toLowerCase().replace(/\\.$/, \"\");\n const found = set.domains.find(d => d.host.toLowerCase() === wanted);\n if (!found) {\n fail(\n `This project has no domain ${named}.`,\n set.domains.length\n ? `Its domains: ${set.domains.map(d => d.host).join(\", \")}.`\n : \"It has no custom domains. Add one with `rebase cloud domains add <domain>`.\",\n \"not_found\"\n );\n }\n return found;\n }\n if (set.domains.length === 1) return set.domains[0];\n if (set.domains.length === 0) {\n fail(\"This project has no custom domains.\", \"Add one with `rebase cloud domains add <domain>`.\", \"not_found\");\n }\n // `verify` with no host means the one waiting to be verified, when only one is.\n const pending = set.domains.filter(d => d.status !== \"verified\");\n if (action === \"verify\" && pending.length === 1) return pending[0];\n fail(\n `This project has ${set.domains.length} domains; name the one to ${action}.`,\n `Run \\`rebase cloud domains ${action} <domain>\\` with one of: ${set.domains.map(d => d.host).join(\", \")}.`,\n \"usage\"\n );\n}\n\nfunction printRecords(instructions: DomainInstructions | undefined): void {\n const recs = [instructions?.pointing, instructions?.ownership].filter(Boolean) as DomainRecord[];\n if (!recs.length) return;\n console.log(chalk.bold(\" DNS records to publish:\"));\n for (const r of recs) {\n console.log(` ${chalk.cyan(r.type)} ${r.name} → ${r.values.join(\", \")}`);\n }\n console.log(\"\");\n}\n\nexport async function domainsCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"list\":\n case \"status\":\n case undefined:\n await listDomains(rawArgs);\n break;\n case \"add\":\n case \"set\":\n await addDomain(rawArgs);\n break;\n case \"verify\":\n await verifyDomain(rawArgs);\n break;\n case \"remove\":\n case \"rm\":\n case \"delete\":\n await removeDomain(rawArgs);\n break;\n case \"--help\":\n printDomainsHelp();\n break;\n default:\n fail(`Unknown domains command: ${action}`, \"Run `rebase cloud domains --help`.\", \"unknown_command\");\n }\n}\n\nasync function listDomains(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud domains\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const set = await loadDomains(client, projectId);\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🌐 Custom domains — project ${projectRef}`));\n console.log(\"\");\n if (!set.domains.length) {\n console.log(chalk.gray(\" No custom domains. Add one with `rebase cloud domains add <domain>`.\"));\n console.log(\"\");\n return;\n }\n if (set.tenantHost) {\n keyValues([[\"Tenant host\", set.tenantHost]]);\n console.log(\"\");\n }\n for (const d of set.domains) {\n const status = d.status === \"verified\" ? chalk.green(d.status) : chalk.yellow(d.status);\n console.log(` ${chalk.bold(d.host)} ${status}${d.primary && set.domains.length > 1 ? chalk.gray(\" primary\") : \"\"}`);\n if (d.verifiedAt) console.log(chalk.gray(` verified ${d.verifiedAt}`));\n if (d.status !== \"verified\") printRecords(d.instructions);\n }\n console.log(\"\");\n },\n { projectId,\ntenantHost: set.tenantHost ?? null,\ndomains: set.domains }\n );\n } catch (e) {\n reportError(e, \"Failed to load custom domains\");\n }\n}\n\n/**\n * The domain an action was given, or undefined.\n *\n * Exported so its tests drive the real parser. Under the old operand filter\n * `rebase cloud domains add -p acme` registered a domain called \"acme\" — the\n * project slug, read out of `--project`'s own value — and a registered domain\n * is a project-record write, not a no-op.\n */\nexport function resolveDomainArg(rawArgs: string[], action = \"add\"): string | undefined {\n return parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud domains <action>\n command: `cloud domains ${action}`,\n maxPositionals: 1\n }).positionals[0];\n}\n\nasync function addDomain(rawArgs: string[]): Promise<void> {\n const domain = resolveDomainArg(rawArgs);\n if (!domain) fail(\"Usage: rebase cloud domains add <domain>\", undefined, \"usage\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n let added: DomainEntry | undefined;\n try {\n const set = await loadDomains(client, projectId);\n if (set.model === \"column\") {\n // No `domains` function: the column is the project's one domain.\n await client.data.collection(\"projects\").update(projectId, { customDomain: domain });\n added = columnEntry(await fetchColumnSetup(client, projectId))[0];\n } else {\n const legacy = set.domains.find(d => d.id === null);\n if (legacy && legacy.host.toLowerCase() !== domain.trim().toLowerCase()) {\n // The column's domain is served only while the project has no\n // host rows; this adds the first, and once a row is verified\n // the Ingress carries the rows alone.\n warn(\n `${legacy.host} is held outside this project's host list, and stops being served once another host is verified.`,\n `Keep it by adding it too: \\`rebase cloud domains add ${legacy.host}\\`, then \\`rebase cloud domains verify ${legacy.host}\\`.`\n );\n }\n added = rowEntry(await client.functions.invoke<DomainRow>(\"domains\", { host: domain }, { path: projectId })) ?? undefined;\n }\n } catch (e) {\n reportError(e, \"Failed to register domain\");\n }\n if (!added) fail(`The control plane did not return ${domain}, so whether it was registered is unknown.`, \"Run `rebase cloud domains list`.\");\n const registered = added;\n emit(\n () => {\n success(`Registered ${chalk.bold(registered.host)} — not yet verified`);\n printRecords(registered.instructions);\n console.log(chalk.gray(` Publish the records above, then run \\`rebase cloud domains verify ${registered.host}\\`.`));\n console.log(\"\");\n },\n { success: true,\nprojectId,\n...registered }\n );\n}\n\nasync function verifyDomain(rawArgs: string[]): Promise<void> {\n const named = resolveDomainArg(rawArgs, \"verify\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n let set: DomainSet;\n try {\n set = await loadDomains(client, projectId);\n } catch (e) {\n reportError(e, \"Failed to load custom domains\");\n }\n const target = pickDomain(set, named, \"verify\");\n try {\n const res = verifyOutcome(\n target.id === null\n ? await client.functions.invoke<VerifyAnswer>(\"verify-domain\", {}, { path: projectId })\n : await client.functions.invoke<VerifyAnswer>(\"domains\", {}, { path: `${projectId}/${target.id}/verify` }),\n target\n );\n emit(\n () => {\n console.log(\"\");\n if (res.verified) success(`${target.host} is verified and live`);\n else {\n console.log(chalk.yellow(` ⚠ ${target.host} is not verified yet`));\n console.log(\"\");\n const rows: Array<[string, DomainCheck]> = [\n [\"Ownership\", res.checks.ownership],\n [\"Pointing\", res.checks.pointing]\n ];\n for (const [label, check] of rows) {\n const mark = check.ok ? chalk.green(\"ok\") : chalk.red(\"missing\");\n console.log(` ${label}: ${mark}`);\n console.log(chalk.gray(` expected: ${check.expected.join(\", \") || \"—\"}`));\n console.log(chalk.gray(` observed: ${check.observed.join(\", \") || \"—\"}`));\n if (check.error) console.log(chalk.gray(` error: ${check.error}`));\n }\n console.log(\"\");\n printRecords(res.entry.instructions);\n }\n },\n { projectId,\nid: res.entry.id,\nhost: res.entry.host,\nverified: res.verified,\nstatus: res.entry.status,\nchecks: res.checks,\ninstructions: res.entry.instructions ?? null }\n );\n if (!res.verified) process.exit(1);\n } catch (e) {\n reportError(e, \"Failed to verify domain\");\n }\n}\n\n/** A verify answer from either door, as one shape. */\nfunction verifyOutcome(\n res: VerifyAnswer,\n target: DomainEntry\n): { verified: boolean; checks: DomainChecks; entry: DomainEntry } {\n const verified = res.verified === true;\n const unchecked: DomainCheck = { ok: false, expected: [], observed: [] };\n return {\n verified,\n checks: res.checks ?? { ownership: unchecked, pointing: unchecked },\n entry: {\n ...target,\n status: verified || res.status === \"verified\" ? \"verified\" : \"pending\",\n verifiedAt: res.verifiedAt ?? target.verifiedAt,\n instructions: res.instructions ?? target.instructions\n }\n };\n}\n\nasync function removeDomain(rawArgs: string[]): Promise<void> {\n // Strict: detaching a host is destructive, and the permissive parse\n // accepted `domains remove --dry-run` by ignoring the flag and detaching\n // anyway.\n const { flags: args, positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud domains remove\n command: \"cloud domains remove\",\n maxPositionals: 1\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n let set: DomainSet;\n try {\n set = await loadDomains(client, projectId);\n } catch (e) {\n reportError(e, \"Failed to load custom domains\");\n }\n const target = pickDomain(set, positionals[0], \"remove\");\n\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Stop serving ${target.host} on project ${projectRef}?`\n });\n\n try {\n let removed = true;\n if (target.id === null) {\n await client.data.collection(\"projects\").update(projectId, { customDomain: \"\" });\n } else {\n const res = await client.functions.invoke<{ removed?: boolean }>(\n \"domains\",\n undefined,\n { method: \"DELETE\",\npath: `${projectId}/${target.id}` }\n );\n // `removed: false` is the server saying it was already gone — the\n // outcome asked for, and reported as it is.\n removed = res?.removed !== false;\n }\n emit(\n () => success(removed\n ? `${target.host} is no longer served by project ${projectRef}`\n : `${target.host} was already gone from project ${projectRef}`),\n { success: true,\nprojectId,\nhost: target.host,\nremoved }\n );\n } catch (e) {\n reportError(e, \"Failed to remove domain\");\n }\n}\n\nexport function printDomainsHelp(): void {\n printGroupHelp({\n command: \"cloud domains\",\n title: \"Custom domains\",\n actions: [\n { action: \"list\",\ndescription: \"Every host, its status, and the DNS records it needs\" },\n { action: \"add\",\nargs: \"<domain>\",\ndescription: \"Register a host\" },\n { action: \"verify\",\nargs: \"[domain]\",\ndescription: \"Check a host's DNS and put it live\" },\n { action: \"remove\",\nargs: \"<domain>\",\ndescription: \"Stop serving a host\" }\n ],\n notes: [\n \"A project can be served on several hosts; each is verified on its own.\",\n \"A CNAME is invalid at a zone apex: use an A record there and a CNAME below it.\",\n \"`list` prints the exact records to add — copy them rather than deriving them.\"\n ]\n });\n}\n","/**\n * `rebase cloud extensions` — allowlisted Postgres extensions.\n *\n * extensions list Every allowlisted extension + its real state\n * extensions enable <name> [-y] Install one (may restart the DB ⇒ needs -y)\n * extensions disable <name> Drop one (and remove any preload library)\n *\n * `manageable === false` is the anti-brick guard reaching the CLI: the server\n * has already said it will refuse, so enable/disable is never offered for such an\n * extension — its `manageableReason` is surfaced instead. Enabling one that\n * restarts the customer's database requires `--yes` in non-interactive use. The\n * `pgvector` alias resolves to `vector`, and a 202 (`pending`) means the database\n * is restarting and the extension is not installed yet — re-drive later.\n */\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n printGroupHelp,\n confirmDestructive,\n keyValues,\n success,\n fail,\n reportError,\n type CloudClient\n} from \"./context\";\n\ninterface ExtensionStatus {\n name: string;\n displayName: string;\n description: string;\n requiresRestart: boolean;\n enabled: boolean;\n version: string | null;\n enabledAt: string | null;\n available: boolean;\n pendingRestart: boolean;\n manageable: boolean;\n manageableReason: string | null;\n}\n\ninterface ExtensionListResponse {\n databaseType: \"managed\" | \"byodb\" | \"none\";\n reason: string;\n source: \"database\" | \"record\";\n extensions: ExtensionStatus[];\n}\n\ninterface EnableResult {\n success: boolean;\n extension: string;\n pending?: boolean;\n restarted?: boolean;\n requiresRestart?: boolean;\n alreadyEnabled?: boolean;\n version?: string | null;\n recordWritten?: boolean;\n message: string;\n}\n\ninterface DisableResult {\n success: boolean;\n extension: string;\n dropped: boolean;\n preloadRemoved: boolean;\n restarted?: boolean;\n message: string;\n}\n\n/** The identifier CREATE EXTENSION takes. `pgvector` is a common alias. */\nexport function resolveExtensionAlias(name: string): string {\n return name.toLowerCase() === \"pgvector\" ? \"vector\" : name;\n}\n\nasync function fetchExtensions(client: CloudClient, projectId: string): Promise<ExtensionListResponse> {\n return client.functions.invoke<ExtensionListResponse>(\"extensions\", undefined, {\n method: \"GET\",\n path: `list/${projectId}`\n });\n}\n\nexport async function extensionsCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"list\":\n case undefined:\n await listExtensions(rawArgs);\n break;\n case \"enable\":\n await enableExtension(rawArgs);\n break;\n case \"disable\":\n await disableExtension(rawArgs);\n break;\n case \"--help\":\n printExtensionsHelp();\n break;\n default:\n fail(`Unknown extensions command: ${action}`, \"Run `rebase cloud extensions --help`.\", \"unknown_command\");\n }\n}\n\nasync function listExtensions(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud extensions\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const res = await fetchExtensions(client, projectId);\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🧩 Extensions — project ${projectRef}`) + chalk.gray(` (${res.databaseType}, source: ${res.source})`));\n console.log(\"\");\n if (res.source === \"record\") {\n console.log(chalk.yellow(\" ⚠ Database unreachable — showing cached state, not live catalog.\"));\n console.log(\"\");\n }\n for (const e of res.extensions) {\n const state = e.enabled ? chalk.green(\"enabled\") : chalk.gray(\"disabled\");\n const restart = e.requiresRestart ? chalk.yellow(\" ⟳ restarts DB\") : \"\";\n const locked = !e.manageable ? chalk.gray(\" [not manageable]\") : \"\";\n console.log(` ${chalk.bold(e.name)} ${state}${e.version ? chalk.gray(` v${e.version}`) : \"\"}${restart}${locked}`);\n if (!e.manageable && e.manageableReason) console.log(chalk.gray(` ${e.manageableReason}`));\n }\n console.log(\"\");\n },\n { projectId,\ndatabaseType: res.databaseType,\nreason: res.reason,\nsource: res.source,\nextensions: res.extensions }\n );\n } catch (e) {\n reportError(e, \"Failed to list extensions\");\n }\n}\n\n/**\n * The extension `enable`/`disable` names, plus the flags that gate it.\n *\n * Under the old operand filter `rebase cloud extensions enable -p acme` read\n * `--project`'s value as the extension name and asked the server to install one\n * called \"acme\"; `extensions disable -p acme vector` dropped \"acme\" rather than\n * vector. Strict parsing consumes the flag with its value.\n */\nexport function resolveExtensionArgs(rawArgs: string[], action: \"enable\" | \"disable\") {\n const { flags, positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud extensions <action>\n command: `cloud extensions ${action}`,\n maxPositionals: 1\n });\n return { flags,\nname: positionals[0] };\n}\n\nasync function enableExtension(rawArgs: string[]): Promise<void> {\n const { flags: args, name: raw } = resolveExtensionArgs(rawArgs, \"enable\");\n if (!raw) fail(\"Usage: rebase cloud extensions enable <name>\", undefined, \"usage\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const name = resolveExtensionAlias(raw!);\n\n try {\n // Consult the catalog first: never offer enable where the server says it\n // is not manageable, and gate a DB-restarting enable behind --yes.\n const list = await fetchExtensions(client, projectId);\n const ext = list.extensions.find((e) => e.name === name);\n if (ext && !ext.manageable) {\n fail(\n `Extension ${name} cannot be managed on this project.`,\n ext.manageableReason ?? undefined,\n \"not_manageable\"\n );\n }\n if (ext?.requiresRestart && !ext.enabled) {\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Enabling ${name} restarts the project's database. Continue?`\n });\n }\n\n const res = await client.functions.invoke<EnableResult>(\"extensions\", { projectId,\nextensionName: name }, { path: \"enable\" });\n emit(\n () => {\n if (res.pending) {\n console.log(\"\");\n console.log(chalk.yellow(` ⏳ ${res.message}`));\n console.log(chalk.gray(\" The database is restarting; re-run this once it is back to finish installing.\"));\n console.log(\"\");\n } else {\n success(res.message || `Enabled ${name}`);\n keyValues([[\"Version\", res.version ?? undefined]]);\n }\n },\n {\n success: res.success,\n extension: res.extension,\n pending: res.pending ?? false,\n restarted: res.restarted ?? false,\n alreadyEnabled: res.alreadyEnabled ?? false,\n version: res.version ?? null,\n message: res.message\n }\n );\n } catch (e) {\n reportError(e, \"Failed to enable extension\");\n }\n}\n\nasync function disableExtension(rawArgs: string[]): Promise<void> {\n const { flags: args, name: raw } = resolveExtensionArgs(rawArgs, \"disable\");\n if (!raw) fail(\"Usage: rebase cloud extensions disable <name>\", undefined, \"usage\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const name = resolveExtensionAlias(raw!);\n\n try {\n const list = await fetchExtensions(client, projectId);\n const ext = list.extensions.find((e) => e.name === name);\n if (ext && !ext.manageable) {\n fail(\n `Extension ${name} cannot be managed on this project.`,\n ext.manageableReason ?? undefined,\n \"not_manageable\"\n );\n }\n if (ext?.requiresRestart && ext.enabled) {\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Disabling ${name} restarts the project's database. Continue?`\n });\n }\n\n const res = await client.functions.invoke<DisableResult>(\"extensions\", { projectId,\nextensionName: name }, { path: \"disable\" });\n emit(\n () => success(res.message || `Disabled ${name}`),\n {\n success: res.success,\n extension: res.extension,\n dropped: res.dropped,\n preloadRemoved: res.preloadRemoved,\n restarted: res.restarted ?? false,\n message: res.message\n }\n );\n } catch (e) {\n reportError(e, \"Failed to disable extension\");\n }\n}\n\nexport function printExtensionsHelp(): void {\n printGroupHelp({\n command: \"cloud extensions\",\n title: \"Postgres extensions\",\n actions: [\n { action: \"list\",\ndescription: \"List extensions and their state\" },\n { action: \"enable\",\nargs: \"<name>\",\ndescription: \"Enable one — `pgvector` is accepted for `vector`\" },\n { action: \"disable\",\nargs: \"<name>\",\ndescription: \"Disable one\" }\n ],\n notes: [\"Enabling or disabling one restarts the database, so it needs --yes when nothing can prompt.\"]\n });\n}\n","/**\n * `rebase cloud settings` — a project's editable configuration.\n *\n * settings Show the current settings\n * settings set [flags] Update name / branch / repo / subdomain / platform rebuilds\n *\n * These are plain `projects` updates. A subdomain change is validated against\n * `check-subdomain` up front so the CLI fails with the real reason rather than a\n * generic collection error.\n */\nimport chalk from \"chalk\";\nimport { requireClient, requireProject, displayProjectRef, parseCloudArgs, emit, printGroupHelp, keyValues, success, fail, reportError } from \"./context\";\n\ninterface ProjectSettings {\n id: string | number;\n name?: string;\n subdomain?: string;\n gitRepoUrl?: string;\n gitBranch?: string;\n customDomain?: string;\n provider?: string;\n region?: string;\n platformRebuilds?: boolean | null;\n}\n\nexport async function settingsCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"set\":\n await setSettings(rawArgs);\n break;\n case undefined:\n case \"show\":\n case \"list\":\n await showSettings(rawArgs);\n break;\n case \"--help\":\n printSettingsHelp();\n break;\n default:\n fail(`Unknown settings command: ${action}`, \"Run `rebase cloud settings --help`.\", \"unknown_command\");\n }\n}\n\nasync function showSettings(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud settings\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const p = (await client.data.collection(\"projects\").findById(projectId)) as ProjectSettings | undefined;\n if (!p) fail(`Project ${projectRef} not found.`, undefined, \"not_found\");\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` ⚙️ Settings — project ${projectRef}`));\n console.log(\"\");\n keyValues([\n [\"Name\", p!.name],\n [\"Subdomain\", p!.subdomain],\n [\"Repository\", p!.gitRepoUrl],\n [\"Branch\", p!.gitBranch],\n [\"Custom domain\", p!.customDomain],\n [\"Provider\", p!.provider],\n [\"Region\", p!.region],\n [\"Platform rebuilds\", p!.platformRebuilds === false ? \"off\" : \"on\"]\n ]);\n console.log(\"\");\n },\n {\n projectId: String(p!.id),\n name: p!.name ?? null,\n subdomain: p!.subdomain ?? null,\n gitRepoUrl: p!.gitRepoUrl ?? null,\n gitBranch: p!.gitBranch ?? null,\n customDomain: p!.customDomain ?? null,\n provider: p!.provider ?? null,\n region: p!.region ?? null,\n platformRebuilds: p!.platformRebuilds !== false\n }\n );\n } catch (e) {\n reportError(e, \"Failed to load settings\");\n }\n}\n\n/** `on`/`off` (or `true`/`false`) as a boolean, or null for anything else. */\nexport function parseOnOff(value: string): boolean | null {\n const v = value.trim().toLowerCase();\n if (v === \"on\" || v === \"true\") return true;\n if (v === \"off\" || v === \"false\") return false;\n return null;\n}\n\n/** Build the update patch from the flags actually supplied (pure/testable). */\nexport function buildSettingsPatch(args: {\n name?: string;\n subdomain?: string;\n repo?: string;\n branch?: string;\n /** Already parsed with {@link parseOnOff}. */\n platformRebuilds?: boolean;\n}): Record<string, string | boolean> {\n const patch: Record<string, string | boolean> = {};\n if (args.name !== undefined) patch.name = args.name;\n if (args.subdomain !== undefined) patch.subdomain = args.subdomain.toLowerCase();\n if (args.repo !== undefined) patch.gitRepoUrl = args.repo;\n if (args.branch !== undefined) patch.gitBranch = args.branch;\n if (args.platformRebuilds !== undefined) patch.platformRebuilds = args.platformRebuilds;\n return patch;\n}\n\n/** What `rebase cloud settings set` parses. Its page is the group's own. */\nexport const SET_SETTINGS_FLAGS = {\n \"--name\": String,\n \"--subdomain\": String,\n \"--repo\": String,\n \"--branch\": String,\n /* Whether fleet upgrades rebuild this app from its source on each new\n framework release (on by default). Off keeps every deploy as built,\n and the platform deletes the copy of the source it holds. */\n \"--platform-rebuilds\": String\n} as const;\n\nasync function setSettings(rawArgs: string[]): Promise<void> {\n // `--project`/`-p` are globals and are not redeclared here; the rest is this\n // command's own. Strict rather than permissive: `--brnach main` used to be\n // dropped, and the command then reported \"nothing to change\".\n const { flags: args } = parseCloudArgs({\n spec: SET_SETTINGS_FLAGS,\n rawArgs,\n commandWords: 3, // cloud settings set\n command: \"cloud settings\",\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n let platformRebuilds: boolean | undefined;\n if (args[\"--platform-rebuilds\"] !== undefined) {\n const parsed = parseOnOff(args[\"--platform-rebuilds\"]);\n if (parsed === null) {\n fail(`--platform-rebuilds takes on or off (got \"${args[\"--platform-rebuilds\"]}\").`, undefined, \"usage\");\n }\n platformRebuilds = parsed;\n }\n\n const patch = buildSettingsPatch({\n name: args[\"--name\"],\n subdomain: args[\"--subdomain\"],\n repo: args[\"--repo\"],\n branch: args[\"--branch\"],\n platformRebuilds\n });\n if (Object.keys(patch).length === 0) {\n fail(\"Nothing to update.\", \"Pass --name, --subdomain, --repo, --branch, or --platform-rebuilds.\", \"usage\");\n }\n\n try {\n if (typeof patch.subdomain === \"string\" && patch.subdomain) {\n const check = await client.functions\n .invoke<{ available: boolean; reason?: string }>(\"check-subdomain\", { subdomain: patch.subdomain })\n .catch(() => undefined);\n if (check && !check.available) {\n fail(`Subdomain \"${patch.subdomain}\" is not available${check.reason ? ` (${check.reason})` : \"\"}.`, undefined, \"subdomain_taken\");\n }\n }\n\n await client.data.collection(\"projects\").update(projectId, patch);\n emit(\n () => success(`Updated ${Object.keys(patch).join(\", \")} for project ${projectRef}`),\n { success: true,\nprojectId,\nupdated: patch }\n );\n } catch (e) {\n reportError(e, \"Failed to update settings\");\n }\n}\n\nexport function printSettingsHelp(): void {\n printGroupHelp({\n command: \"cloud settings\",\n title: \"Project configuration\",\n actions: [\n { action: \"show\",\ndescription: \"Name, subdomain, repository, branch and platform rebuilds as recorded\" },\n {\n action: \"set\",\n description: \"Change one or more of them\",\n flags: [\n [\"--name <name>\", \"Display name\"],\n [\"--subdomain <sub>\", \"The <slug>.rebase.website host\"],\n [\"--repo <git url>\", \"Repository to build from\"],\n [\"--branch <branch>\", \"Branch to build\"],\n [\"--platform-rebuilds <on|off>\", \"Rebuild this app on new framework releases (default on)\"]\n ]\n }\n ]\n });\n}\n","/**\n * Deployment lifecycle: `rebase cloud deployments list`, `rollback`, `cancel`.\n *\n * The rollback rule is the load-bearing part. A rollback is only honoured for a\n * SUCCESSFUL deploy that recorded an artefact — an `imageUrl` from a custom\n * build, or a `bundleId` from a managed deploy; anything else 409s\n * `deploy_not_rollbackable` server-side. So this module never offers — and\n * refuses to invoke — a rollback the server would reject, exactly mirroring the\n * console's `isRollbackable`.\n */\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n confirmDestructive,\n colorStatus,\n keyValues,\n success,\n fail,\n reportError,\n type CloudClient,\n cloudRows,\n cloudRow\n} from \"./context\";\n\n/** A deployment row, as the data API hands it back (camel or snake columns). */\nexport interface DeploymentRow {\n id: string | number;\n status?: string;\n createdAt?: string | Date;\n created_at?: string | Date;\n finishedAt?: string | Date;\n finished_at?: string | Date;\n imageUrl?: string;\n image_url?: string;\n bundleId?: string;\n bundle_id?: string;\n rollbackOf?: string;\n rollback_of?: string;\n triggeredBy?: string;\n triggered_by?: string;\n triggerSource?: string;\n trigger_source?: string;\n triggeredByUserId?: string;\n triggered_by_user_id?: string;\n gitCommitHash?: string;\n gitCommitMessage?: string;\n deployMessage?: string;\n deploy_message?: string;\n frameworkVersion?: string;\n framework_version?: string;\n}\n\nfunction str(dep: DeploymentRow, camel: keyof DeploymentRow, snake: keyof DeploymentRow): string | null {\n const raw = (dep[camel] ?? dep[snake]) as unknown;\n return typeof raw === \"string\" && raw.trim() !== \"\" ? raw.trim() : null;\n}\n\nfunction isoOf(dep: DeploymentRow, camel: keyof DeploymentRow, snake: keyof DeploymentRow): string | null {\n const raw = (dep[camel] ?? dep[snake]) as unknown;\n if (raw instanceof Date) return Number.isNaN(raw.getTime()) ? null : raw.toISOString();\n return typeof raw === \"string\" && raw.trim() !== \"\" ? raw.trim() : null;\n}\n\nfunction deploymentImage(dep: DeploymentRow): string | null {\n return str(dep, \"imageUrl\", \"image_url\");\n}\n\n/**\n * The bundle a managed deploy shipped, or null.\n *\n * A managed deploy publishes no image — the platform image is the platform's\n * half of the runtime — so this is the artefact a rollback restores there.\n */\nfunction deploymentBundle(dep: DeploymentRow): string | null {\n return str(dep, \"bundleId\", \"bundle_id\");\n}\n\n/**\n * The backend's rule EXACTLY (`rollbackTargetOf`): a rollback is honoured only\n * for a successful deploy that recorded an image or a bundle. Any other row\n * 409s `deploy_not_rollbackable`.\n *\n * The bundle half was missing, and it took the whole managed tier with it: a\n * managed deploy records no image, so `rebase cloud rollback` refused every\n * managed project before it even asked the server.\n */\nexport function isRollbackable(dep: DeploymentRow): boolean {\n return dep.status === \"success\" && (deploymentImage(dep) !== null || deploymentBundle(dep) !== null);\n}\n\n/** What a rollback needs, said the way a refusal should say it. */\nconst ROLLBACKABLE_RULE = \"needs a successful deploy that recorded an image or a bundle\";\n\n/** finishedAt − createdAt in ms, or null (still running / missing / skewed). */\nexport function deploymentDurationMs(dep: DeploymentRow): number | null {\n const created = isoOf(dep, \"createdAt\", \"created_at\");\n const finished = isoOf(dep, \"finishedAt\", \"finished_at\");\n if (!created || !finished) return null;\n const a = new Date(created).getTime();\n const b = new Date(finished).getTime();\n if (Number.isNaN(a) || Number.isNaN(b)) return null;\n const ms = b - a;\n return ms >= 0 ? ms : null;\n}\n\nfunction formatDuration(ms: number): string {\n const totalSec = Math.max(0, Math.round(ms / 1000));\n if (totalSec < 60) return `${totalSec}s`;\n const m = Math.floor(totalSec / 60);\n const s = totalSec % 60;\n if (m < 60) return s ? `${m}m ${s}s` : `${m}m`;\n const h = Math.floor(m / 60);\n const mm = m % 60;\n return mm ? `${h}h ${mm}m` : `${h}h`;\n}\n\nconst TRIGGERED_BY = [\"user\", \"automation\", \"unknown\"] as const;\nconst TRIGGER_SOURCES = [\"console\", \"cli\", \"webhook\", \"unknown\"] as const;\n\nexport function triggerInfo(dep: DeploymentRow): { by: string; source: string; userId: string } {\n const byRaw = (dep.triggeredBy ?? dep.triggered_by) as unknown;\n const srcRaw = (dep.triggerSource ?? dep.trigger_source) as unknown;\n const by = typeof byRaw === \"string\" && (TRIGGERED_BY as readonly string[]).includes(byRaw) ? byRaw : \"unknown\";\n const source =\n typeof srcRaw === \"string\" && (TRIGGER_SOURCES as readonly string[]).includes(srcRaw) ? srcRaw : \"unknown\";\n return { by,\nsource,\nuserId: str(dep, \"triggeredByUserId\", \"triggered_by_user_id\") ?? \"\" };\n}\n\n/** Shape one deployment row into the stable JSON view the CLI publishes. */\nexport function deploymentView(dep: DeploymentRow): Record<string, unknown> {\n const durationMs = deploymentDurationMs(dep);\n return {\n id: String(dep.id),\n status: dep.status ?? null,\n createdAt: isoOf(dep, \"createdAt\", \"created_at\"),\n finishedAt: isoOf(dep, \"finishedAt\", \"finished_at\"),\n durationMs,\n image: deploymentImage(dep),\n // Published beside `image` rather than folded into it: they are\n // different artefacts from different halves of the platform, and a\n // script that pinned one would silently match the other.\n bundle: deploymentBundle(dep),\n rollbackOf: str(dep, \"rollbackOf\", \"rollback_of\"),\n isRollback: str(dep, \"rollbackOf\", \"rollback_of\") !== null,\n rollbackable: isRollbackable(dep),\n trigger: triggerInfo(dep),\n // The caller's own label for this deploy, and the framework THIS BUNDLE\n // installed. Without them a `--source` project's history is N rows\n // carrying an identical placeholder commit message, distinguishable only\n // by timestamp — which is not enough to answer \"did mine go out?\".\n //\n // Published as `builtAgainst` — the manifest field it comes from\n // (`runtime.builtAgainst`, read off the installed `@rebasepro/server`) —\n // and NOT as `frameworkVersion`, which is what `cloud status` calls the\n // framework the runtime IMAGE ships. The two are routinely different:\n // the image supplies the server, the bundle supplies the driver. Under\n // one name they read as the control plane disagreeing with itself, and\n // that is how this was reported as a bug.\n message: str(dep, \"deployMessage\", \"deploy_message\"),\n builtAgainst: str(dep, \"frameworkVersion\", \"framework_version\"),\n commit: {\n hash: str(dep, \"gitCommitHash\", \"gitCommitHash\"),\n message: str(dep, \"gitCommitMessage\", \"gitCommitMessage\")\n }\n };\n}\n\n/** What `POST /api/functions/deploy/cancel` answers. */\nexport interface CancelResponse {\n success: boolean;\n /**\n * The deployment that was cancelled — `null` when there was none.\n *\n * Nullable because \"nothing was in flight\" is a real, successful outcome\n * and not an error: a project's `status` column can claim `deploying` while\n * no deployment row backs the claim, and cancelling is what clears it.\n */\n deploymentId: string | null;\n buildJobDeleted: boolean;\n /** The request cleared a stuck `deploying` claim rather than stopping a build. */\n unstranded?: boolean;\n /** The status the project settled on when it did. */\n projectStatus?: string | null;\n}\n\n/**\n * What `rebase cloud cancel` says it did.\n *\n * Split out of the command because there are now two outcomes behind one\n * `success: true`, and only one of them is \"a build was stopped\". The control\n * plane learned to clear a project stranded at `deploying` with no deployment\n * row behind it — the state `prospector` was wedged in for five days — and it\n * reports that through this same endpoint. An unbranched caller printed\n * \"Cancelled deployment null\" for it, which reads as a bug in the thing that\n * had just fixed the bug.\n *\n * The ABSENT ID is what decides, not the `unstranded` flag: the flag is the\n * server being explicit, and it is the newer half of the contract. Branching on\n * the id means a client that meets a control plane which grew the behaviour\n * without the flag still says something true.\n */\nexport function cancelView(res: CancelResponse): {\n /** The headline, for `success()`. */\n headline: string;\n /** Dimmed follow-ups, printed under it. */\n notes: string[];\n /** The stable JSON view, which is what a piped run gets. */\n json: Record<string, unknown>;\n} {\n const deploymentId = res.deploymentId ? String(res.deploymentId) : null;\n const projectStatus =\n typeof res.projectStatus === \"string\" && res.projectStatus.length > 0 ? res.projectStatus : null;\n\n if (!deploymentId) {\n return {\n headline:\n \"No deploy was in flight — cleared this project's stuck 'deploying' status\" +\n (projectStatus ? ` (now ${chalk.bold(projectStatus)})` : \"\"),\n notes: [\"Its status claimed a deploy that no deployment backed. Redeploy is available again.\"],\n json: { success: true,\ndeploymentId: null,\nbuildJobDeleted: false,\nunstranded: true,\nprojectStatus }\n };\n }\n\n return {\n headline: `Cancelled deployment ${chalk.bold(deploymentId)}`,\n notes: res.buildJobDeleted ? [\"The build job was deleted.\"] : [],\n json: { success: true,\ndeploymentId,\nbuildJobDeleted: Boolean(res.buildJobDeleted),\nunstranded: Boolean(res.unstranded),\nprojectStatus }\n };\n}\n\nasync function fetchDeployments(client: CloudClient, projectId: string, limit = 100): Promise<DeploymentRow[]> {\n const res = await client.data.collection(\"deployments\").find({\n where: { project: [\"==\", projectId] },\n orderBy: [\"createdAt\", \"desc\"],\n limit\n });\n return cloudRows<DeploymentRow>(res.data);\n}\n\n/**\n * Rows shown when `--limit` is not given.\n *\n * History is unbounded and grows one row per deploy, so \"all of it\" is the\n * wrong default in both directions: a wall of near-identical lines in a\n * terminal, and — since JSON mode is entered automatically for any non-TTY\n * stdout — a project's entire history dumped at anything that pipes the\n * command. Recent deploys are what the question is almost always about.\n */\nexport const DEFAULT_DEPLOYMENTS_LIMIT = 20;\n\n/** Hard ceiling on `--limit`, matching the backend's own page size. */\nconst MAX_DEPLOYMENTS_LIMIT = 100;\n\n/** `--limit N`, bounded. A garbage value is a refusal, never a silent default. */\nexport function parseDeploymentsLimit(raw: number | undefined): number {\n if (raw === undefined) return DEFAULT_DEPLOYMENTS_LIMIT;\n if (!Number.isInteger(raw) || raw < 1 || raw > MAX_DEPLOYMENTS_LIMIT) {\n fail(`--limit must be a whole number between 1 and ${MAX_DEPLOYMENTS_LIMIT}.`, undefined, \"usage\");\n }\n return raw;\n}\n\nexport async function deploymentsListCommand(rawArgs: string[]): Promise<void> {\n // `--limit` is validated below and a typo of it must not silently fall back\n // to the default page — the refusal is the whole point of the bound.\n const { flags: args } = parseCloudArgs({\n spec: { \"--limit\": Number,\n\"--all\": Boolean },\n rawArgs,\n commandWords: 2, // cloud deployments\n command: \"cloud deployments list\",\n maxPositionals: 1 // the `list` action word, when written out\n });\n const limit = args[\"--all\"] ? MAX_DEPLOYMENTS_LIMIT : parseDeploymentsLimit(args[\"--limit\"]);\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const rows = await fetchDeployments(client, projectId, limit);\n const views = rows.map(deploymentView);\n // Never let a truncated list read as a complete one. `truncated` is in\n // the JSON for the same reason the note is in the human output.\n const truncated = views.length === limit;\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🚀 Deployments — project ${projectRef}`));\n console.log(\"\");\n if (!views.length) {\n console.log(chalk.gray(\" No deployments yet. Deploy with `rebase cloud deploy`.\"));\n console.log(\"\");\n return;\n }\n for (const v of views) {\n const dur = v.durationMs !== null ? formatDuration(v.durationMs as number) : chalk.gray(\"running\");\n const trig = (v.trigger as { source: string }).source;\n const roll = v.rollbackable ? chalk.green(\" ↺ rollbackable\") : \"\";\n console.log(\n ` ${chalk.gray(`[${v.id}]`)} ${colorStatus(v.status as string)} ${chalk.gray(String(v.createdAt ?? \"—\"))} ${dur} ${chalk.gray(trig)}${roll}`\n );\n // The label and the framework this bundle was built against\n // are what make one row distinguishable from the next;\n // indented under it so the status line stays scannable when\n // they are absent. Spelled \"built against\" so it cannot be\n // read as the framework `cloud status` reports, which is the\n // image's.\n const label = [v.message, v.builtAgainst ? `built against @rebasepro/* ${v.builtAgainst}` : null]\n .filter(Boolean)\n .join(\" · \");\n if (label) console.log(` ${chalk.gray(label)}`);\n }\n if (truncated) {\n console.log(\"\");\n console.log(chalk.gray(` Showing the ${limit} most recent. Use \\`--limit N\\` or \\`--all\\` for more.`));\n }\n console.log(\"\");\n },\n { projectId,\nlimit,\ntruncated,\ndeployments: views }\n );\n } catch (e) {\n reportError(e, \"Failed to list deployments\");\n }\n}\n\n/**\n * The deployment id `rollback`/`cancel` was given, if any.\n *\n * Both take an optional id, which is what made the old operand filter so easy\n * to trip: `rebase cloud rollback -p acme` — the documented way to act on an\n * unlinked project — read `--project`'s value as the id and refused with\n * \"Deployment acme not found\", and `cancel -p acme` sent \"acme\" to the server\n * as the deployment to cancel. Strict parsing consumes the flag with its value,\n * so an id given as a flag value is never mistaken for an argument.\n */\nexport function resolveDeploymentIdArg(rawArgs: string[], command: string) {\n const { flags, positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 2, // cloud <rollback|cancel>\n command,\n maxPositionals: 1\n });\n return { flags,\nid: positionals[0] };\n}\n\n/**\n * One deployment by id, when it belongs to `projectId`; undefined otherwise.\n *\n * A read that fails is \"not found\" too: the caller's refusal says so, and the\n * control plane checks the same ownership again before rolling back.\n */\nasync function deploymentOfProject(\n client: CloudClient,\n deploymentId: string,\n projectId: string\n): Promise<DeploymentRow | undefined> {\n let row: Record<string, unknown> | undefined;\n try {\n row = (await client.data.collection(\"deployments\").findById(deploymentId)) as Record<string, unknown> | undefined;\n } catch {\n return undefined;\n }\n if (!row) return undefined;\n const owner = row.project ?? row.projectId ?? row.project_id;\n const ownerId = typeof owner === \"object\" && owner !== null && \"id\" in owner ? owner.id : owner;\n if (ownerId !== undefined && ownerId !== null && String(ownerId) !== projectId) return undefined;\n return cloudRow<DeploymentRow>(row);\n}\n\nexport async function rollbackCommand(rawArgs: string[]): Promise<void> {\n // `rollback [deploymentId]` — the id, when given, is the only argument.\n const { flags: args, id: explicitId } = resolveDeploymentIdArg(rawArgs, \"cloud rollback\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n // Fetch history — the only step here that can fail with a server error.\n let rows: DeploymentRow[];\n try {\n rows = await fetchDeployments(client, projectId);\n } catch (e) {\n reportError(e, \"Failed to read deployment history\");\n }\n if (!rows!.length) fail(\"No deployments to roll back to.\", undefined, \"no_deployments\");\n\n // Select + validate the target OUTSIDE any catch — a refusal here is a\n // deliberate exit, never a server error to re-wrap.\n let target: DeploymentRow | undefined;\n if (explicitId) {\n // The page is the newest 100. An id named outright may be older, so it\n // is read on its own before it is called missing.\n target = rows!.find((d) => String(d.id) === explicitId) ?? await deploymentOfProject(client, explicitId, projectId);\n if (!target) fail(`Deployment ${explicitId} not found for project ${projectRef}.`, undefined, \"not_found\");\n // Refuse locally rather than let the server 409 — this is the safety\n // contract, mirrored from the backend's rollback rule.\n if (!isRollbackable(target!)) {\n fail(\n `Deployment ${explicitId} is not rollbackable (${ROLLBACKABLE_RULE}).`,\n \"List candidates with `rebase cloud deployments list`.\",\n \"deploy_not_rollbackable\"\n );\n }\n } else {\n const rollbackable = rows!.filter(isRollbackable);\n if (!rollbackable.length) {\n fail(\n `No rollbackable deployment found (${ROLLBACKABLE_RULE}).`,\n \"List history with `rebase cloud deployments list`.\",\n \"deploy_not_rollbackable\"\n );\n }\n // Prefer the previous good image when the newest deploy is itself good\n // (rolling back to the live image is a no-op); otherwise the most recent\n // good one.\n target = rollbackable.find((d) => String(d.id) !== String(rows![0].id)) ?? rollbackable[0];\n }\n\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Roll project ${projectRef} back to deployment ${target!.id}? This starts a new deployment.`\n });\n\n try {\n const res = await client.functions.invoke<{\n success: boolean;\n deployment: { id: string };\n rolledBackTo: string;\n // Exactly one is non-null, and which one says whether a custom\n // build's image or a managed deploy's bundle is being restored.\n imageUrl: string | null;\n bundleId: string | null;\n }>(\"deploy\", { projectId,\ndeploymentId: String(target!.id),\nclient: \"cli\" }, { path: \"rollback\" });\n\n emit(\n () => {\n success(`Rolling back to deployment ${chalk.bold(String(target!.id))}`);\n keyValues([\n [\"New deployment\", res.deployment?.id ? String(res.deployment.id) : undefined],\n [\"Rolled back to\", res.rolledBackTo],\n // Only the one that applies. Printing \"Image: —\" at somebody\n // who has never had an image is the same wrong answer the\n // refusal used to give.\n [\"Image\", res.imageUrl ?? undefined],\n [\"Bundle\", res.bundleId ?? undefined]\n ]);\n console.log(chalk.gray(\" Follow it with `rebase cloud logs -f`.\"));\n console.log(\"\");\n },\n {\n success: true,\n deploymentId: res.deployment?.id ?? null,\n rolledBackTo: res.rolledBackTo,\n imageUrl: res.imageUrl ?? null,\n bundleId: res.bundleId ?? null\n }\n );\n } catch (e) {\n reportError(e, \"Failed to roll back\");\n }\n}\n\nexport async function cancelCommand(rawArgs: string[]): Promise<void> {\n const { flags: args, id: explicitId } = resolveDeploymentIdArg(rawArgs, \"cloud cancel\");\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Cancel the in-flight build for project ${projectRef}?`\n });\n\n try {\n const res = await client.functions.invoke<CancelResponse>(\n \"deploy\",\n explicitId ? { projectId,\ndeploymentId: explicitId } : { projectId },\n { path: \"cancel\" }\n );\n const view = cancelView(res);\n emit(\n () => {\n success(view.headline);\n for (const note of view.notes) console.log(chalk.gray(` ${note}`));\n console.log(\"\");\n },\n view.json\n );\n } catch (e) {\n const err = e as { status?: number };\n if (err?.status === 404) {\n fail(\"No deployment in progress to cancel.\", undefined, \"not_found\");\n }\n reportError(e, \"Failed to cancel deployment\");\n }\n}\n","/**\n * `rebase cloud start | stop | restart` — power operations.\n *\n * These flip the project's `status`, exactly as the console's `handleServerAction`\n * does: stop → `stopped`, start → `active`, restart → stop then start with a\n * brief pause in between (a real stop→start with genuine downtime). Stop and\n * restart cause downtime, so they require `--yes` in non-interactive use.\n */\nimport { requireClient, requireProject, displayProjectRef, parseCloudArgs, emit, confirmDestructive, success, reportError, type CloudClient } from \"./context\";\n\ntype PowerAction = \"start\" | \"stop\" | \"restart\";\n\nasync function setStatus(client: CloudClient, projectId: string, status: \"active\" | \"stopped\"): Promise<void> {\n await client.data.collection(\"projects\").update(projectId, { status });\n}\n\nexport async function powerCommand(action: PowerAction, rawArgs: string[]): Promise<void> {\n // Every key here is a global, so the spec is empty — declaring one would\n // replace the global in the merge while the global's other readers went on\n // reading the raw line. Strict rather than permissive: `stop --yse` used to\n // drop the flag and then refuse off a terminal for want of it.\n const { flags: args } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 2, // cloud start|stop|restart\n command: `cloud ${action}`,\n maxPositionals: 0\n });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n // start is benign; stop and restart cause downtime and are gated.\n if (action !== \"start\") {\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `${action === \"stop\" ? \"Stop\" : \"Restart\"} project ${projectRef}? This causes downtime.`\n });\n }\n\n try {\n if (action === \"stop\") {\n await setStatus(client, projectId, \"stopped\");\n emit(() => success(`Stopped project ${projectRef}`), { success: true,\nprojectId,\nstatus: \"stopped\" });\n } else if (action === \"start\") {\n await setStatus(client, projectId, \"active\");\n emit(() => success(`Started project ${projectRef}`), { success: true,\nprojectId,\nstatus: \"active\" });\n } else {\n await setStatus(client, projectId, \"stopped\");\n await new Promise((r) => setTimeout(r, 1500));\n await setStatus(client, projectId, \"active\");\n emit(() => success(`Restarted project ${projectRef}`), { success: true,\nprojectId,\nstatus: \"active\" });\n }\n } catch (e) {\n reportError(e, `Failed to ${action} project`);\n }\n}\n","/**\n * `rebase cloud debug <subcommand>` — one entry point for \"why is my deployed\n * app not behaving\".\n *\n * ## Why this exists\n *\n * The useful signals for a deployed project live in four different places — the\n * control plane, the workload's pods, the tenant database, and the public URL —\n * and each is normally reached with a different tool and a different set of\n * flags. Getting to a log should not be a research task. This started life as a\n * hand-rolled `prod-debug.sh` for a single project, with the namespace and the\n * URL hardcoded at the top; it earned its place twice in one week, so it is\n * generalised here to any project the CLI can already resolve.\n *\n * ## Read-only by default\n *\n * Every subcommand here only reads. The two things the original script could do\n * that mutate are deliberately NOT reproduced as-is:\n *\n * - restarting the workload lives at `rebase cloud restart`, which already\n * gates downtime behind `--yes`; duplicating it here would give the same\n * destructive act a second, ungated spelling.\n * - `debug db` prints the port-forward recipe and the connection's *shape*.\n * It opens no session and prints no password — `rebase cloud db info\n * --reveal` is the explicit, auditable way to get one.\n *\n * ## The probes are the point\n *\n * `debug health` is the highest-value piece and the reason the script existed.\n * A bare status code is not a diagnosis: a 404 from a functions route means\n * something completely different from a 404 at the root, and a 200 on an\n * unauthenticated read is a finding rather than a success. So every probe ships\n * with the interpretation of what it got, not just the number — see\n * {@link PROBES}.\n */\nimport arg from \"arg\";\nimport chalk from \"chalk\";\nimport { unknownCommandMessage } from \"../../utils/unknown-command\";\nimport {\n requireClient,\n requireProject,\n parseCloudArgs,\n displayProjectRef,\n fetchTenantBaseDomain,\n projectHost,\n colorStatus,\n keyValues,\n emit,\n printGroupHelp,\n fail,\n reportError,\n type CloudClient\n} from \"./context\";\n\n/* ═══════════════════════════════════════════════════════════════\n Health probes\n ═══════════════════════════════════════════════════════════════ */\n\n/** How a probe's outcome should be read. */\nexport type Verdict =\n /** Behaving as a healthy deployment should. */\n | \"ok\"\n /** Reachable and legal, but worth a human look (e.g. a public read). */\n | \"warn\"\n /** Broken, or wired up wrong. */\n | \"fail\"\n /** We could not classify the response. */\n | \"unknown\";\n\nexport interface ProbeReading {\n verdict: Verdict;\n /** What this status code *means for this endpoint*, in one sentence. */\n meaning: string;\n}\n\nexport interface ProbeSpec {\n id: string;\n /** Column label in human output. */\n label: string;\n method: \"GET\" | \"POST\";\n /** Path relative to the project origin. */\n path: (opts: ProbeTargets) => string;\n body?: unknown;\n /** One-line statement of what a healthy deployment answers here. */\n healthy: string;\n interpret: (status: number | null) => ProbeReading;\n /**\n * Read the response body as well. Set only where the body carries a fact the\n * status code cannot — today, the function listing.\n */\n needsBody?: boolean;\n /**\n * Sharpen the status-code reading using the parsed body. Returning null\n * keeps {@link interpret}'s verdict.\n */\n refine?: (body: unknown, targets: ProbeTargets) => ProbeReading | null;\n}\n\nexport interface ProbeTargets {\n /** Collection used for the unauthenticated-read probe. */\n collection: string;\n /** Function to confirm exists, if the caller named one. */\n fn?: string;\n}\n\n/** A response never arrived: DNS, TLS, ingress, or the pod. */\nconst NO_RESPONSE: ProbeReading = {\n verdict: \"fail\",\n meaning:\n \"nothing answered — the hostname does not resolve, the ingress has no route, or no pod is running\"\n};\n\nfunction serverError(what: string): ProbeReading {\n return { verdict: \"fail\",\nmeaning: `the server is running but ${what}` };\n}\n\n/**\n * The probe set, in the order a failure cascades: if `health` is down, nothing\n * below it is meaningful, so it is checked first and reported first.\n */\nexport const PROBES: ProbeSpec[] = [\n {\n id: \"health\",\n label: \"health\",\n method: \"GET\",\n path: () => \"/health\",\n healthy: \"200 — the backend is up\",\n interpret: (status) => {\n if (status === null) return NO_RESPONSE;\n if (status === 200) return { verdict: \"ok\",\nmeaning: \"the backend is up and serving\" };\n if (status === 404) {\n return {\n verdict: \"fail\",\n meaning:\n \"something answered but it is not a Rebase backend — the ingress is routing this host elsewhere\"\n };\n }\n if (status >= 500) return serverError(\"its health endpoint is failing\");\n return { verdict: \"unknown\",\nmeaning: \"unexpected for a health endpoint\" };\n }\n },\n {\n id: \"spa\",\n label: \"spa\",\n method: \"GET\",\n path: () => \"/\",\n healthy: \"200 — the frontend is being served\",\n interpret: (status) => {\n if (status === null) return NO_RESPONSE;\n if (status === 200) return { verdict: \"ok\",\nmeaning: \"the frontend bundle is being served\" };\n if (status === 404) {\n return {\n verdict: \"warn\",\n meaning:\n \"no frontend at the root — expected for a backend-only project, otherwise the SPA assets were not bundled into the image\"\n };\n }\n if (status >= 500) return serverError(\"the root route throws\");\n return { verdict: \"unknown\",\nmeaning: \"unexpected at the site root\" };\n }\n },\n {\n id: \"auth\",\n label: \"auth\",\n method: \"POST\",\n path: () => \"/api/auth/login\",\n body: {},\n healthy: \"400 — auth is mounted and rejects an empty body\",\n interpret: (status) => {\n if (status === null) return NO_RESPONSE;\n // The probe deliberately posts an empty body: a healthy auth route\n // must reject it. Reachability is what is being tested, not a login.\n if (status === 400 || status === 422) {\n return { verdict: \"ok\",\nmeaning: \"auth is mounted and rejected the empty body, as it should\" };\n }\n if (status === 401 || status === 403) {\n return { verdict: \"ok\",\nmeaning: \"auth is mounted and refused the credentials\" };\n }\n if (status === 404) {\n return {\n verdict: \"fail\",\n meaning: \"the auth routes are NOT mounted — this project cannot sign anyone in\"\n };\n }\n if (status === 200) {\n return {\n verdict: \"fail\",\n meaning: \"an EMPTY login body was accepted — a login with no credentials must never succeed\"\n };\n }\n if (status >= 500) return serverError(\"the login route throws — often a missing or unmigrated auth table\");\n return { verdict: \"unknown\",\nmeaning: \"unexpected for a login route\" };\n }\n },\n {\n id: \"unauthRead\",\n label: \"unauth read\",\n method: \"GET\",\n path: (t) => `/api/data/${encodeURIComponent(t.collection)}`,\n healthy: \"401 — reads require authentication\",\n interpret: (status) => {\n if (status === null) return NO_RESPONSE;\n if (status === 401 || status === 403) {\n return { verdict: \"ok\",\nmeaning: \"unauthenticated reads are refused — row-level security is enforced\" };\n }\n if (status === 200) {\n // Legal, and sometimes intended. Never silently called healthy.\n return {\n verdict: \"warn\",\n meaning:\n \"this collection is readable with NO authentication — correct only if it is deliberately public\"\n };\n }\n if (status === 404) {\n return {\n verdict: \"warn\",\n meaning: \"no such collection on this deployment — check the name, or pass --collection\"\n };\n }\n if (status >= 500) {\n return serverError(\n \"the read reached the database and failed — most often an RLS policy naming a column or table that is not there\"\n );\n }\n return { verdict: \"unknown\",\nmeaning: \"unexpected for a data read\" };\n }\n },\n {\n id: \"functions\",\n label: \"functions\",\n method: \"GET\",\n /**\n * The router's own listing endpoint, NOT a function's path.\n *\n * This matters, and it is the one place the original script got a wrong\n * answer. A function is a Hono sub-app mounted at `/<name>`, and it\n * usually defines only sub-routes (`/get`, `/list`) — so\n * `/api/functions/<name>` 404s **even when everything is mounted and\n * healthy**. Probing there cannot separate \"the router is missing\" from\n * \"that function defines no root route\", and reporting the first is how\n * you send someone to debug a deployment that was fine.\n *\n * `GET /api/functions` is unambiguous: the router registers a listing\n * route at its own root (see `createFunctionRoutes`), so a 200 proves\n * the mount *and* names every function that loaded.\n */\n path: () => \"/api/functions\",\n healthy: \"200 — the functions router is mounted and lists its functions\",\n interpret: (status) => {\n if (status === null) return NO_RESPONSE;\n if (status === 200) return { verdict: \"ok\",\nmeaning: \"the functions router is mounted\" };\n if (status === 401 || status === 403) {\n // The listing is behind auth on this deployment. That still\n // proves the router is there, which is what is being tested.\n return { verdict: \"ok\",\nmeaning: \"the functions router is mounted (its listing requires auth)\" };\n }\n if (status === 404) {\n return {\n verdict: \"fail\",\n meaning:\n \"the functions router did not mount — no functions directory was found at build time, or it held no functions, so every function on this project is unreachable\"\n };\n }\n if (status >= 500) return serverError(\"the functions router throws\");\n return { verdict: \"unknown\",\nmeaning: \"unexpected for the functions listing\" };\n },\n needsBody: true,\n refine: (body, t) => {\n const names = functionNames(body);\n if (!names) return null;\n if (t.fn && !names.includes(t.fn)) {\n // Definitive, because the listing is authoritative — no guessing\n // from a 404 that could equally mean the router is absent.\n return {\n verdict: \"fail\",\n meaning:\n `the router is mounted but no function is named \"${t.fn}\" — it loaded ${names.length}: ` +\n `${names.join(\", \")}`\n };\n }\n const found = t.fn ? `, including ${t.fn}` : \"\";\n return {\n verdict: \"ok\",\n meaning: `the functions router is mounted and loaded ${names.length} function${names.length === 1 ? \"\" : \"s\"}${found}`\n };\n }\n }\n];\n\n/** The function names out of a listing body, or null when it is not one. */\nexport function functionNames(body: unknown): string[] | null {\n const list = (body as { functions?: unknown } | null | undefined)?.functions;\n if (!Array.isArray(list)) return null;\n const names = list\n .map((f) => (f as { name?: unknown })?.name)\n .filter((n): n is string => typeof n === \"string\");\n return names.length === list.length ? names : null;\n}\n\nexport interface ProbeResult {\n id: string;\n label: string;\n method: string;\n url: string;\n status: number | null;\n ms: number;\n verdict: Verdict;\n meaning: string;\n healthy: string;\n /**\n * Whether the STATUS CODE alone looked healthy. False means the code itself\n * was wrong; true with a failing `verdict` means the code was fine and the\n * body carried the bad news (a named function that did not load). The\n * summary uses this so it never tells you to expect a 200 you already got.\n */\n statusOk: boolean;\n}\n\n/** Milliseconds before a probe is treated as unanswered. */\nconst PROBE_TIMEOUT_MS = 10_000;\n\n/**\n * Ceiling on a probe body we will parse. The only body read is the function\n * listing; anything larger is a page we have no use for, and a debug command\n * must not be the thing that runs a machine out of memory.\n */\nconst MAX_PROBE_BODY_BYTES = 256 * 1024;\n\n/**\n * Run one probe. A transport failure is a `null` status, never a thrown error:\n * \"nothing answered\" is a diagnosis in its own right and the other probes still\n * need to run.\n */\nexport async function runProbe(origin: string, spec: ProbeSpec, targets: ProbeTargets): Promise<ProbeResult> {\n const url = `${origin}${spec.path(targets)}`;\n const started = Date.now();\n let status: number | null = null;\n let body: unknown;\n try {\n const res = await fetch(url, {\n method: spec.method,\n headers: spec.body ? { \"Content-Type\": \"application/json\" } : undefined,\n body: spec.body ? JSON.stringify(spec.body) : undefined,\n redirect: \"manual\",\n signal: AbortSignal.timeout(PROBE_TIMEOUT_MS)\n });\n status = res.status;\n if (spec.needsBody && res.ok) {\n const text = await res.text();\n if (text.length <= MAX_PROBE_BODY_BYTES) {\n try {\n body = JSON.parse(text);\n } catch {\n // Not JSON — `refine` returns null and the status reading stands.\n }\n }\n }\n } catch {\n status = null;\n }\n const statusReading = spec.interpret(status);\n // The body can only sharpen a reading, never invent one where the request\n // failed outright.\n const reading = (status !== null && spec.refine?.(body, targets)) || statusReading;\n return {\n statusOk: statusReading.verdict === \"ok\",\n id: spec.id,\n label: spec.label,\n method: spec.method,\n url,\n status,\n ms: Date.now() - started,\n verdict: reading.verdict,\n meaning: reading.meaning,\n healthy: spec.healthy\n };\n}\n\n/** The worst verdict across probes — what the command's exit code keys off. */\nexport function overallVerdict(results: ProbeResult[]): Verdict {\n if (results.some((r) => r.verdict === \"fail\")) return \"fail\";\n if (results.some((r) => r.verdict === \"unknown\")) return \"unknown\";\n if (results.some((r) => r.verdict === \"warn\")) return \"warn\";\n return \"ok\";\n}\n\nfunction verdictMark(v: Verdict): string {\n switch (v) {\n case \"ok\":\n return chalk.green(\"✓\");\n case \"warn\":\n return chalk.yellow(\"!\");\n case \"fail\":\n return chalk.red(\"✗\");\n default:\n return chalk.gray(\"?\");\n }\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Log parsing\n ═══════════════════════════════════════════════════════════════\n\n `runtime-logs` renders each line as `<rfc3339> [<pod>] <text>`, where <text>\n is normally the application's structured JSON. These helpers unwrap that so\n the derived views (errors / requests / boot) work on the payload rather than\n on the transport's formatting.\n*/\n\nexport interface ParsedLogLine {\n ts: string | null;\n pod: string | null;\n text: string;\n}\n\nconst LOG_PREFIX_RE = /^(?:(\\d{4}-\\d{2}-\\d{2}T[\\d:.]+Z?)\\s+)?(?:\\[([^\\]]+)\\]\\s+)?([\\s\\S]*)$/;\n\nexport function parseLogLine(line: string): ParsedLogLine {\n const m = LOG_PREFIX_RE.exec(line);\n if (!m) return { ts: null,\npod: null,\ntext: line };\n return { ts: m[1] ?? null,\npod: m[2] ?? null,\ntext: m[3] ?? \"\" };\n}\n\n/**\n * Lines an operator scanning for a fault wants to see.\n *\n * Matches the structured `severity` field first, then the shapes that show up\n * in unstructured output. `refus`/`denied` are in the list because a permission\n * failure often logs at info level and is exactly what one is hunting for.\n */\nexport function isErrorLine(text: string): boolean {\n return /\"(?:severity|level)\":\\s*\"(?:ERROR|WARN(?:ING)?|error|warn)\"|\\bError:|\\bERR!|refus|denied|EACCES|ECONNREFUSED/i.test(\n text\n );\n}\n\nexport interface RequestLogEntry {\n status: number | null;\n method: string;\n path: string;\n latencyMs: number | null;\n}\n\n/**\n * Pull an HTTP request record out of a log line, or null when it is not one.\n *\n * Only structured request lines are recognised. Guessing at prose would produce\n * a table with invented columns, which is worse than a short one.\n */\nexport function parseRequestLine(text: string): RequestLogEntry | null {\n const start = text.indexOf(\"{\");\n if (start === -1) return null;\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(text.slice(start)) as Record<string, unknown>;\n } catch {\n return null;\n }\n if (parsed.message !== \"request\" && parsed.msg !== \"request\") return null;\n\n const num = (v: unknown): number | null => {\n const n = typeof v === \"string\" ? Number(v) : typeof v === \"number\" ? v : NaN;\n return Number.isFinite(n) ? n : null;\n };\n return {\n status: num(parsed.status),\n method: typeof parsed.method === \"string\" ? parsed.method : \"\",\n path: typeof parsed.path === \"string\" ? parsed.path : \"\",\n latencyMs: num(parsed.latencyMs ?? parsed.durationMs)\n };\n}\n\n/**\n * Startup lines: what the server *decided* it was going to do. Which storage\n * backend it bound, which functions it loaded, whether auth tables were found.\n * This is the fastest way to tell a misconfiguration from a runtime fault.\n */\nexport function isBootLine(text: string): boolean {\n return /storage|Loaded function|Mounted|Auth tables|Server running|listening|Refusing|migrat/i.test(text);\n}\n\n/** Render a number of seconds back as the compact duration a user would type. */\nexport function formatDuration(seconds: number): string {\n if (seconds % 86400 === 0 && seconds >= 86400) return `${seconds / 86400}d`;\n if (seconds % 3600 === 0 && seconds >= 3600) return `${seconds / 3600}h`;\n if (seconds % 60 === 0 && seconds >= 60) return `${seconds / 60}m`;\n return `${seconds}s`;\n}\n\n/**\n * Parse a duration like `15m`, `2h`, `90s`, `1d` (or a bare number of seconds)\n * into seconds. Returns null when it is not a duration.\n */\nexport function parseSince(input: string | undefined): number | null {\n if (!input) return null;\n const m = /^(\\d+(?:\\.\\d+)?)\\s*([smhd])?$/i.exec(input.trim());\n if (!m) return null;\n const value = parseFloat(m[1]);\n const unit = (m[2] || \"s\").toLowerCase();\n const mult = unit === \"s\" ? 1 : unit === \"m\" ? 60 : unit === \"h\" ? 3600 : 86400;\n return Math.round(value * mult);\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Shared fetches\n ═══════════════════════════════════════════════════════════════ */\n\ninterface RuntimeLogsResponse {\n logs?: string;\n pods?: Array<{ pod: string; state: string; lines: number; message: string | null; hint: string | null }>;\n ordering?: string;\n truncated?: boolean;\n state?: string;\n message?: string | null;\n}\n\nasync function fetchRuntimeLogs(\n client: CloudClient,\n projectId: string,\n opts: { sinceSeconds?: number; tailLines?: number; previous?: boolean }\n): Promise<RuntimeLogsResponse> {\n const params = new URLSearchParams();\n if (opts.sinceSeconds !== undefined) params.set(\"sinceSeconds\", String(opts.sinceSeconds));\n if (opts.tailLines !== undefined) params.set(\"tailLines\", String(opts.tailLines));\n if (opts.previous) params.set(\"previous\", \"true\");\n params.set(\"timestamps\", \"true\");\n const qs = params.toString();\n return client.functions.invoke<RuntimeLogsResponse>(\"runtime-logs\", undefined, {\n method: \"GET\",\n path: `${projectId}${qs ? `?${qs}` : \"\"}`\n });\n}\n\n/** Print the per-pod states runtime-logs reports, including its hints. */\nfunction printPodStates(res: RuntimeLogsResponse): void {\n if (res.state === \"no_pods\") {\n console.log(chalk.yellow(` ${res.message ?? \"No pods are running for this project.\"}`));\n console.log(\"\");\n return;\n }\n for (const p of res.pods ?? []) {\n if (p.state === \"ok\") continue;\n console.log(` ${chalk.yellow(p.pod)} ${chalk.gray(`(${p.state})`)}`);\n if (p.message) console.log(chalk.gray(` ${p.message}`));\n // The hint is the actionable half — a crash-looping container's reason\n // is in its PREVIOUS instance, and that is only discoverable if we say so.\n if (p.hint) console.log(chalk.cyan(` → ${p.hint}`));\n }\n if (res.truncated) console.log(chalk.gray(\" (output truncated — narrow the window with --since)\"));\n}\n\n/** Resolve the public origin a project is served at. */\nasync function resolveOrigin(\n rawArgs: string[],\n client: CloudClient,\n url: string,\n projectId: string\n): Promise<string> {\n const parsed = arg({ \"--host\": String }, { argv: rawArgs.slice(3),\npermissive: true });\n if (parsed[\"--host\"]) {\n const h = parsed[\"--host\"].trim().replace(/\\/+$/, \"\");\n return /^https?:\\/\\//.test(h) ? h : `https://${h}`;\n }\n\n const [project, baseDomain] = await Promise.all([\n client.data.collection(\"projects\").findById(projectId) as Promise<\n { subdomain?: string; host?: string; customDomain?: string } | undefined\n >,\n fetchTenantBaseDomain(client, url)\n ]);\n if (!project) fail(`Project ${displayProjectRef(rawArgs)} not found.`);\n\n const host = projectHost(project, baseDomain);\n if (!host) {\n fail(\n \"Could not determine the public URL for this project.\",\n \"It may never have been deployed. Pass --host <hostname> to probe an address directly.\"\n );\n }\n return `https://${host}`;\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Subcommand: health\n ═══════════════════════════════════════════════════════════════ */\n\nasync function healthCommand(rawArgs: string[]): Promise<void> {\n // Strict: `--collecton users` used to be dropped and the probe then ran\n // against the default collection while reporting on the one asked for.\n const { flags: parsed } = parseCloudArgs({\n // `--host` is read again inside `resolveOrigin`, which needs it before\n // the client exists; declared here because THIS is the parse that\n // decides whether the line is accepted at all.\n spec: { \"--collection\": String,\n\"--function\": String,\n\"--host\": String },\n rawArgs,\n commandWords: 3, // cloud debug health\n command: \"cloud debug\",\n maxPositionals: 0\n });\n const targets: ProbeTargets = {\n collection: parsed[\"--collection\"] || \"users\",\n // Optional: the listing endpoint proves the mount on its own. A name\n // here additionally asserts that this particular function loaded.\n fn: parsed[\"--function\"]\n };\n\n const { client, url } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const origin = await resolveOrigin(rawArgs, client, url, projectId);\n\n // Sequential, not Promise.all: five simultaneous requests to a struggling\n // pod is a small load test, and the latency column would then measure our\n // own contention rather than the endpoint's.\n const results: ProbeResult[] = [];\n for (const spec of PROBES) results.push(await runProbe(origin, spec, targets));\n\n const overall = overallVerdict(results);\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🩺 Health — ${displayProjectRef(rawArgs)}`) + chalk.gray(` ${origin}`));\n console.log(\"\");\n const width = Math.max(...results.map((r) => r.label.length));\n for (const r of results) {\n const code = r.status === null ? chalk.red(\"---\") : String(r.status);\n console.log(\n ` ${verdictMark(r.verdict)} ${chalk.bold(r.label.padEnd(width))} ${code.padStart(3)} ${chalk.gray(`${r.ms}ms`)}`\n );\n console.log(` ${chalk.gray(r.meaning)}`);\n }\n console.log(\"\");\n if (overall === \"ok\") {\n console.log(chalk.green(\" Everything reachable and wired as expected.\"));\n } else {\n const bad = results.filter((r) => r.verdict === \"fail\" || r.verdict === \"warn\");\n console.log(chalk.gray(` ${bad.length} of ${results.length} check${bad.length === 1 ? \"\" : \"s\"} need attention.`));\n // Only where the status code itself was wrong — restating\n // \"expected 200\" under a probe that returned 200 reads as a bug.\n const wrongStatus = bad.filter((r) => !r.statusOk);\n if (wrongStatus.length > 0) {\n console.log(chalk.gray(\" A healthy deployment answers:\"));\n for (const r of wrongStatus) {\n console.log(chalk.gray(` ${r.label.padEnd(width)} ${r.healthy}`));\n }\n }\n }\n console.log(\"\");\n },\n { origin,\noverall,\nprobes: results }\n );\n\n // A failing probe is a failing command — this is meant to be usable in a\n // deploy script's `if`, not only read by a human.\n if (overall === \"fail\") process.exit(1);\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Subcommand: logs / errors / requests / boot\n ═══════════════════════════════════════════════════════════════ */\n\ninterface LogViewOptions {\n /** Keep only lines matching this. Omit to keep everything. */\n filter?: (text: string) => boolean;\n /** Default lookback when --since is not given. */\n defaultSinceSeconds: number;\n /** Max lines rendered. */\n limit: number;\n title: string;\n}\n\nasync function logView(rawArgs: string[], view: LogViewOptions): Promise<void> {\n const { flags: parsed } = parseCloudArgs({\n spec: { \"--since\": String,\n\"--tail\": Number,\n\"--previous\": Boolean },\n rawArgs,\n commandWords: 3, // cloud debug logs|errors|boot\n command: \"cloud debug\",\n maxPositionals: 0\n });\n\n const sinceArg = parsed[\"--since\"];\n if (sinceArg !== undefined && parseSince(sinceArg) === null) {\n fail(`--since must be a duration like 15m, 2h or 90s; received \"${sinceArg}\".`);\n }\n const sinceSeconds = parseSince(sinceArg) ?? view.defaultSinceSeconds;\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n let res: RuntimeLogsResponse;\n try {\n res = await fetchRuntimeLogs(client, projectId, {\n sinceSeconds,\n tailLines: parsed[\"--tail\"] ?? 500,\n previous: Boolean(parsed[\"--previous\"])\n });\n } catch (e) {\n reportError(e, \"Failed to fetch runtime logs\");\n }\n\n const all = (res.logs ?? \"\").split(\"\\n\").filter((l) => l !== \"\");\n const parsedLines = all.map(parseLogLine);\n const kept = view.filter ? parsedLines.filter((l) => view.filter!(l.text)) : parsedLines;\n const shown = kept.slice(-view.limit);\n\n emit(\n () => {\n console.log(\"\");\n console.log(\n chalk.bold(` ${view.title} — ${displayProjectRef(rawArgs)}`) +\n chalk.gray(` last ${formatDuration(sinceSeconds)}`)\n );\n console.log(\"\");\n printPodStates(res);\n if (shown.length === 0) {\n console.log(chalk.gray(\" (nothing matched in this window)\"));\n console.log(\"\");\n return;\n }\n for (const l of shown) console.log(` ${l.pod ? chalk.gray(`[${l.pod}] `) : \"\"}${l.text}`);\n console.log(\"\");\n if (kept.length > shown.length) {\n console.log(chalk.gray(` (showing the last ${shown.length} of ${kept.length} matching lines)`));\n console.log(\"\");\n }\n },\n {\n sinceSeconds,\n state: res.state ?? null,\n pods: res.pods ?? [],\n truncated: Boolean(res.truncated),\n matched: kept.length,\n lines: shown\n }\n );\n}\n\nasync function requestsCommand(rawArgs: string[]): Promise<void> {\n const { flags: parsed } = parseCloudArgs({\n spec: { \"--since\": String,\n\"--tail\": Number },\n rawArgs,\n commandWords: 3, // cloud debug requests\n command: \"cloud debug\",\n maxPositionals: 0\n });\n const sinceArg = parsed[\"--since\"];\n if (sinceArg !== undefined && parseSince(sinceArg) === null) {\n fail(`--since must be a duration like 15m, 2h or 90s; received \"${sinceArg}\".`);\n }\n const sinceSeconds = parseSince(sinceArg) ?? 900;\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n let res: RuntimeLogsResponse;\n try {\n res = await fetchRuntimeLogs(client, projectId, { sinceSeconds,\ntailLines: parsed[\"--tail\"] ?? 1000 });\n } catch (e) {\n reportError(e, \"Failed to fetch runtime logs\");\n }\n\n const entries = (res.logs ?? \"\")\n .split(\"\\n\")\n .filter((l) => l !== \"\")\n .map((l) => parseRequestLine(parseLogLine(l).text))\n .filter((e): e is RequestLogEntry => e !== null);\n const shown = entries.slice(-40);\n\n emit(\n () => {\n console.log(\"\");\n console.log(\n chalk.bold(` 🌐 Requests — ${displayProjectRef(rawArgs)}`) +\n chalk.gray(` last ${formatDuration(sinceSeconds)}`)\n );\n console.log(\"\");\n printPodStates(res);\n if (shown.length === 0) {\n console.log(chalk.gray(\" No structured request lines in this window.\"));\n console.log(chalk.gray(\" (this view needs the server's request logging; try `debug logs`)\"));\n console.log(\"\");\n return;\n }\n for (const e of shown) {\n const status = e.status ?? 0;\n const color = status >= 500 ? chalk.red : status >= 400 ? chalk.yellow : chalk.green;\n console.log(\n ` ${color(String(e.status ?? \"---\").padStart(3))} ${e.method.padEnd(6)} ${e.path.slice(0, 70).padEnd(70)} ${chalk.gray(\n e.latencyMs === null ? \"\" : `${e.latencyMs}ms`\n )}`\n );\n }\n console.log(\"\");\n },\n { sinceSeconds,\nrequests: shown }\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Subcommand: pod\n ═══════════════════════════════════════════════════════════════ */\n\nasync function podCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud debug\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n interface MetricsResponse {\n status?: string;\n cpu?: string | null;\n memory?: string | null;\n placement?: {\n cluster?: string | null;\n provider?: string | null;\n region?: string | null;\n namespace?: string | null;\n host?: string | null;\n image?: string | null;\n replicas?: { available?: number; desired?: number };\n };\n }\n\n let m: MetricsResponse;\n try {\n m = await client.functions.invoke<MetricsResponse>(\"metrics\", undefined, {\n method: \"GET\",\n path: projectId\n });\n } catch (e) {\n reportError(e, \"Failed to read workload placement\");\n }\n\n const p = m.placement ?? {};\n const replicas = p.replicas ?? {};\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` ☸ Workload — ${displayProjectRef(rawArgs)}`));\n console.log(\"\");\n keyValues([\n [\"Status\", m.status ? colorStatus(m.status === \"running\" ? \"active\" : m.status) : undefined],\n [\n \"Replicas\",\n replicas.desired === undefined\n ? undefined\n : `${replicas.available ?? 0} / ${replicas.desired} available`\n ],\n [\"Namespace\", p.namespace],\n [\"Cluster\", p.cluster],\n [\"Region\", [p.provider, p.region].filter(Boolean).join(\" · \") || undefined],\n [\"Host\", p.host],\n [\"Image\", p.image],\n // Reported as-is: the metrics function returns null for \"not\n // measurable\", which must not render as a number.\n [\"CPU\", m.cpu ?? undefined],\n [\"Memory\", m.memory ?? undefined]\n ]);\n console.log(\"\");\n if ((replicas.available ?? 0) === 0 && (replicas.desired ?? 0) > 0) {\n console.log(chalk.yellow(\" No replica is available — the pod is not passing its readiness check.\"));\n console.log(chalk.gray(\" See why with: \") + chalk.bold(\"rebase cloud debug logs --previous\"));\n console.log(\"\");\n }\n },\n { status: m.status ?? null,\nplacement: p }\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Subcommand: db\n ═══════════════════════════════════════════════════════════════ */\n\nasync function dbDebugCommand(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud debug\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n\n interface DbInfo {\n type?: string;\n host?: string | null;\n port?: string | null;\n database?: string | null;\n username?: string | null;\n passwordAvailable?: boolean;\n unavailableReason?: string | null;\n directAccess?: {\n via: \"tunnel\";\n kubectl?: { namespace: string; service: string; localPort: number; remotePort: number };\n } | null;\n }\n\n let info: DbInfo;\n try {\n info = await client.functions.invoke<DbInfo>(\"db-info\", undefined, { method: \"GET\",\npath: projectId });\n } catch (e) {\n reportError(e, \"Failed to read database connection info\");\n }\n\n // The host above is a Service inside the platform's cluster, so `debug db`\n // has to say what to do about that. It used to print `kubectl port-forward\n // -n rebase-tenant-…`, which needs a kubeconfig for OUR cluster: a customer\n // has none, and nothing in the platform issues one. The tunnel is the\n // remedy a reader can actually run.\n const access = info.directAccess;\n const connectCmd = access ? \"rebase cloud db connect\" : null;\n const LOCAL_PORT = 5432;\n const psqlCmd =\n access && info.username && info.database\n ? `psql -h 127.0.0.1 -p ${LOCAL_PORT} -U ${info.username} -d ${info.database}`\n : null;\n // Only for a cluster the customer owns, where the credentials are theirs.\n const kubectlCmd = access?.kubectl\n ? `kubectl port-forward -n ${access.kubectl.namespace} svc/${access.kubectl.service} `\n + `${access.kubectl.localPort}:${access.kubectl.remotePort}`\n : null;\n\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` 🐘 Database — ${displayProjectRef(rawArgs)}`));\n console.log(\"\");\n if (info.unavailableReason) {\n console.log(chalk.yellow(` ${info.unavailableReason}`));\n console.log(\"\");\n return;\n }\n keyValues([\n [\"Type\", info.type],\n [\"Host\", info.host],\n [\"Port\", info.port],\n [\"Database\", info.database],\n [\"Username\", info.username],\n [\"Password\", info.passwordAvailable ? chalk.gray(\"stored — not shown here\") : chalk.yellow(\"none stored\")]\n ]);\n console.log(\"\");\n if (connectCmd) {\n // Printed rather than run. Opening a tunnel and a database shell\n // is not something a command called `debug` should do implicitly.\n console.log(chalk.gray(\" That host is inside the platform's cluster and does not resolve here.\"));\n console.log(chalk.gray(\" To reach the database from this machine:\"));\n console.log(\"\");\n console.log(` ${connectCmd}`);\n if (psqlCmd) console.log(` ${psqlCmd}`);\n console.log(\"\");\n if (kubectlCmd) {\n console.log(chalk.gray(\" Or, on your own cluster:\"));\n console.log(` ${kubectlCmd}`);\n console.log(\"\");\n }\n if (info.passwordAvailable) {\n console.log(\n chalk.gray(\" Get the password with: \") + chalk.bold(\"rebase cloud db info --reveal\")\n );\n console.log(\"\");\n }\n }\n },\n {\n type: info.type ?? null,\n host: info.host ?? null,\n port: info.port ?? null,\n database: info.database ?? null,\n username: info.username ?? null,\n passwordAvailable: Boolean(info.passwordAvailable),\n connectCommand: connectCmd,\n kubectlCommand: kubectlCmd,\n psqlCommand: psqlCmd\n }\n );\n}\n\n/* ═══════════════════════════════════════════════════════════════\n Dispatch\n ═══════════════════════════════════════════════════════════════ */\n\n/**\n * Everything the switch below dispatches, for the did-you-mean. `workload` is\n * the older spelling of `pod` and stays out of it: suggesting the name we no\n * longer print in the help would teach the wrong one.\n */\nconst DEBUG_SUBCOMMANDS = [\"health\", \"logs\", \"errors\", \"boot\", \"requests\", \"pod\", \"db\"] as const;\n\nexport async function debugCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case undefined:\n case \"health\":\n // Bare `rebase cloud debug` runs the probes: it is the answer to\n // \"something is wrong\" more often than any other view here.\n await healthCommand(rawArgs);\n break;\n case \"logs\":\n await logView(rawArgs, { defaultSinceSeconds: 900,\nlimit: 200,\ntitle: \"📄 Logs\" });\n break;\n case \"errors\":\n await logView(rawArgs, {\n filter: isErrorLine,\n defaultSinceSeconds: 3600,\n limit: 40,\n title: \"🔥 Errors\"\n });\n break;\n case \"boot\":\n await logView(rawArgs, {\n filter: isBootLine,\n // The whole log, not a window: startup happened when the pod\n // started, which may have been days ago.\n defaultSinceSeconds: 7 * 24 * 3600,\n limit: 25,\n title: \"🚀 Boot\"\n });\n break;\n case \"requests\":\n await requestsCommand(rawArgs);\n break;\n case \"pod\":\n case \"workload\":\n await podCommand(rawArgs);\n break;\n case \"db\":\n await dbDebugCommand(rawArgs);\n break;\n case \"help\":\n case \"--help\":\n printDebugHelp();\n break;\n default:\n // One refusal path in both modes. The terminal branch used to print\n // the whole help page to STDOUT — the results stream — after a\n // command that produced no result, which is the same shape the\n // index dispatcher was fixed out of. `fail` writes the machine\n // envelope under `--json` and one red line to stderr otherwise, and\n // the words come from the shared builder so the human line and the\n // machine one cannot drift apart: it carries the near-miss when\n // there is one, and names the page for the rest.\n fail(unknownCommandMessage(action, DEBUG_SUBCOMMANDS, \"cloud debug\"), undefined, \"unknown_command\");\n }\n}\n\nexport function printDebugHelp(): void {\n printGroupHelp({\n command: \"cloud debug\",\n title: \"Find out why a deployed project is misbehaving\",\n actions: [\n {\n action: \"health\",\n section: \"End-to-end\",\n description: \"Probe the live URL and explain every status code (the default)\",\n flags: [\n [\"--host <hostname>\", \"Probe this address instead of the project's own\"],\n [\"--collection <name>\", \"Collection for the unauth-read probe. Default: users\"],\n [\"--function <name>\", \"Also assert this function loaded, against the listing\"]\n ]\n },\n { action: \"logs\",\nsection: \"Runtime\",\ndescription: \"Recent application logs\" },\n { action: \"errors\",\nsection: \"Runtime\",\ndescription: \"Error and warning lines only\" },\n { action: \"requests\",\nsection: \"Runtime\",\ndescription: \"HTTP requests the server logged: status, path, latency\" },\n { action: \"boot\",\nsection: \"Runtime\",\ndescription: \"What the server decided at startup: storage, functions, auth\" },\n { action: \"pod\",\nsection: \"Runtime\",\ndescription: \"Replicas, image, namespace, cluster placement\" },\n { action: \"db\",\nsection: \"Data\",\ndescription: \"Connection shape and the port-forward recipe. Never the password\" }\n ],\n options: [\n [\"--since <dur>\", \"Lookback window: 90s, 15m, 2h, 1d\"],\n [\"--tail <n>\", \"Lines to read per pod. Default: 500\"],\n [\"--previous\", \"Read the CRASHED container instance, where the reason lives\"]\n ],\n notes: [\n \"Everything here is read-only. `health` exits non-zero when a check fails, so it works in a\",\n \"deploy script. To restart a workload, use `rebase cloud restart`.\"\n ]\n });\n}\n","/**\n * `rebase cloud resources` — what a project declares against what the platform\n * holds for it, and the one removal a deploy is not allowed to make.\n *\n * `rebase resources` reads the code. This reads the platform: each database\n * and bucket the project's deploys recorded, whether the last deploy's code\n * still declares it, and whether the platform made it. The two disagree in\n * exactly two ways worth a line — declared and not configured, which is a 501\n * waiting to happen, and provisioned and no longer declared, which is a\n * database the platform keeps, binds and bills until somebody prunes it.\n *\n * Pruning is here rather than in the deploy on purpose. A deploy that deleted\n * a database because a line went missing from a commit would be data deleted\n * by a push; this asks, names the key, and needs the project's admin role.\n */\nimport chalk from \"chalk\";\nimport {\n requireClient,\n requireProject,\n displayProjectRef,\n parseCloudArgs,\n emit,\n confirmDestructive,\n requireKnownAction,\n success,\n fail,\n reportError\n} from \"./context\";\n\ninterface ResourceRow {\n kind: \"database\" | \"bucket\";\n key: string;\n engine?: string;\n declared: boolean;\n provisioned: boolean;\n note?: string;\n}\n\n/** The action words `rebase cloud resources` dispatches. No word lists. */\nexport const DECLARED_RESOURCES_ACTIONS = [\"list\", \"prune\"] as const;\n\nexport async function declaredResourcesCommand(action: string | undefined, rawArgs: string[]): Promise<void> {\n // Through `requireKnownAction`, like every other group: a mistyped word\n // used to reach `fail`'s default code, so `resources lst` and a control\n // plane that fell over answered with the same `\"error\"`.\n requireKnownAction(\"resources\", action, DECLARED_RESOURCES_ACTIONS);\n if (action === \"prune\") {\n await pruneResource(rawArgs);\n return;\n }\n await listResources(rawArgs);\n}\n\nasync function listResources(rawArgs: string[]): Promise<void> {\n parseCloudArgs({ spec: {},\nrawArgs,\ncommandWords: 3,\ncommand: \"cloud resources\",\nmaxPositionals: 0 });\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n try {\n const res = await client.functions.invoke<{ resources: ResourceRow[] }>(\"resources\", undefined, {\n method: \"GET\",\n path: projectId\n });\n emit(\n () => {\n console.log(\"\");\n console.log(chalk.bold(` Resources — project ${projectRef}`));\n if (res.resources.length === 0) {\n console.log(chalk.gray(\" Nothing recorded beyond the default database. Deploy once and this fills in.\"));\n console.log(\"\");\n return;\n }\n for (const kind of [\"database\", \"bucket\"] as const) {\n const rows = res.resources.filter(r => r.kind === kind);\n if (rows.length === 0) continue;\n console.log(\"\");\n console.log(` ${chalk.bold.underline(`${kind}s`)}`);\n for (const row of rows) {\n const mark = row.declared && (row.provisioned || row.kind === \"bucket\")\n ? chalk.green(\"✓\")\n : row.note ? chalk.yellow(\"○\") : chalk.gray(\"·\");\n const tags = [\n row.engine ? chalk.gray(row.engine) : \"\",\n row.declared ? chalk.gray(\"declared\") : chalk.yellow(\"not declared\"),\n row.provisioned ? chalk.gray(\"platform-provisioned\") : chalk.gray(\"your own\")\n ].filter(Boolean);\n console.log(` ${mark} ${chalk.bold(row.key)} ${tags.join(\" · \")}`);\n if (row.note) console.log(chalk.yellow(` └ ${row.note}`));\n }\n }\n console.log(\"\");\n },\n { projectId, resources: res.resources }\n );\n } catch (e) {\n reportError(e, \"Failed to list resources\");\n }\n}\n\nasync function pruneResource(rawArgs: string[]): Promise<void> {\n const { flags: args, positionals } = parseCloudArgs({\n spec: {},\n rawArgs,\n commandWords: 3, // cloud resources prune\n command: \"cloud resources prune\",\n maxPositionals: 2 // <kind> <key>\n });\n const [kind, key] = positionals;\n if (kind !== \"database\" || !key) {\n fail(\n \"Say what to prune: `rebase cloud resources prune database <key>`.\",\n \"Only a database can be pruned here; a bucket and its files are removed in the project's storage settings.\",\n \"invalid_argument\"\n );\n }\n\n const { client } = await requireClient(rawArgs);\n const projectId = await requireProject(rawArgs, client);\n const projectRef = displayProjectRef(rawArgs);\n\n await confirmDestructive({\n yes: Boolean(args[\"--yes\"]),\n prompt: `Drop database \"${key}\" from project ${projectRef}? Its rows are gone for good; the platform keeps no copy.`\n });\n\n try {\n const res = await client.functions.invoke<{ removed: boolean; pendingRedeploy?: boolean }>(\n \"resources\",\n { projectId, kind, key },\n { path: \"prune\" }\n );\n success(`Removed database ${chalk.bold(key)} from project ${projectRef}.`);\n if (res.pendingRedeploy) {\n console.log(chalk.gray(\" Its connection string leaves the running backend at the next deploy.\"));\n }\n emit(() => {}, { projectId, kind, key, removed: res.removed });\n } catch (e) {\n reportError(e, `Failed to prune database \"${key}\"`);\n }\n}\n","/**\n * Per-action help for `rebase cloud`.\n *\n * `--help` was already answered centrally, but only per *group*: `rebase cloud\n * projects create --help` and `rebase cloud deploy --help` both fell through to\n * the index page, which lists groups and no flags at all. So the flags that\n * decide what those commands do — `--name`, `--subdomain`, `--type`, `--bundle`\n * — had no discoverable spelling anywhere. The way they were found on a real\n * first deploy was by reading `dist/index.es.js.map`. An agent cannot do that,\n * and neither should a person.\n *\n * Two rules hold this file honest:\n *\n * 1. **The spec is the source of truth, not this page.** `action-help.test.ts`\n * pairs every entry with the `arg` spec its command actually parses and\n * asserts they agree in both directions. A flag added to a command without\n * a line here is a failing test, not a page that is quietly a year old.\n * The pairing lives in the test rather than here on purpose: importing the\n * command modules to describe them would make `--help` depend on the code\n * it is meant to be readable without.\n * 2. **It answers in the reader's language.** Like every other page in this\n * family it goes through `emitHelp`, so a piped `--help` is a structured\n * description of the command rather than sixty lines of ANSI to scrape.\n */\nimport chalk from \"chalk\";\nimport { emitHelp, GLOBAL_HELP_FLAGS } from \"./context\";\n\nexport interface ActionHelp {\n /** `cloud projects create` — no leading `rebase`. */\n command: string;\n /** The usage line, minus the `rebase ` prefix. */\n usage: string;\n /** One paragraph: what the command does, and what it does not. */\n summary: string;\n /** `[flag, description]`, in the order a reader needs them. */\n flags: Array<[string, string]>;\n examples: string[];\n /** Anything a caller gets wrong more than once. */\n notes?: string[];\n}\n\n/*\n * `GLOBAL_HELP_FLAGS` and `GLOBAL_SPEC_KEYS` moved to `context.ts`, next to the\n * `GLOBAL_CLOUD_FLAGS` they describe — the group pages print them too, and\n * `context` cannot import this module (this one imports it). `GLOBAL_SPEC_KEYS`\n * is derived from the spec now rather than listed a second time.\n */\n\nexport const ACTION_HELP: Record<string, ActionHelp> = {\n projects: {\n command: \"cloud projects\",\n usage: \"cloud projects <list|create|info|delete> [options]\",\n summary: \"List, create, inspect and delete projects in the selected organization.\",\n flags: [],\n examples: [\n \"rebase cloud projects list\",\n \"rebase cloud projects create --help\",\n \"rebase cloud projects info shop\",\n \"rebase cloud projects delete shop --yes\"\n ]\n },\n\n clusters: {\n command: \"cloud clusters\",\n usage: \"cloud clusters [list|add|verify] [options]\",\n summary: \"The compute clusters tenants run on. Platform-admin only.\",\n flags: [],\n examples: [\n \"rebase cloud clusters\",\n \"rebase cloud clusters verify <cluster-id> --baseline\",\n \"rebase cloud clusters add --name gke-eu --provider gcp --region europe-west1 --kubeconfig ./kubeconfig\"\n ]\n },\n\n \"projects create\": {\n command: \"cloud projects create\",\n usage: \"cloud projects create --name <name> --subdomain <slug> [options]\",\n summary:\n \"Create a project. Unless --db says otherwise a managed database is attached in the \"\n + \"same call, because a project without one can never deploy — it sits at \"\n + \"status \\\"provisioning\\\" indefinitely, and that word does not mean work is underway.\",\n flags: [\n [\"--name, -n <name>\", \"Display name. Required (prompted only on a terminal)\"],\n [\"--subdomain <slug>\", \"The <slug>.rebase.website host. Required, and not editable afterwards\"],\n [\"--db <managed|byodb|none>\", \"Which database to attach. Default: managed\"],\n [\"--connection-string <url>\", \"The PostgreSQL URL, for --db byodb\"],\n [\"--org <id>\", \"Organization to create it in (default: the selected one)\"],\n [\"--link\", \"Link this directory to the new project\"],\n [\"--repo <url>\", \"Git repository to build from\"],\n [\"--branch <name>\", \"Git branch. Default: main\"],\n // Not a region picker. See the note below — the flags record where\n // the project is placed, and the beta has one place to put it.\n [\"--provider <gcp|hetzner|…>\", \"Which deploy target to record. Default: the one this control plane would use\"],\n [\"--region <region>\", \"Region recorded on the project. Default: that target's own region\"],\n [\"--cpu <n>\", \"vCPU per instance\"],\n [\"--memory <size>\", \"Memory per instance, e.g. 512Mi\"],\n [\"--replicas <n>\", \"Instance count\"],\n [\"--spot <true|false>\", \"Run on preemptible capacity\"],\n [\"--scale-to-zero <true|false>\", \"Stop the instances when idle\"],\n [\"--db-instances <n>\", \"Database instance count\"],\n [\"--db-cpu <n>\", \"vCPU per database instance\"],\n [\"--db-memory <size>\", \"Memory per database instance\"],\n [\"--storage <size>\", \"Database volume size\"]\n ],\n examples: [\n \"rebase cloud projects create --name \\\"Shop\\\" --subdomain shop --link\",\n \"rebase cloud projects create --name Shop --subdomain shop --db none\",\n \"rebase cloud projects create --name Shop --subdomain shop --db byodb --connection-string \\\"$DATABASE_URL\\\"\"\n ],\n notes: [\n \"The subdomain cannot be changed in passing later — a typo here is a new project.\",\n \"A managed database is created at the project's FIRST DEPLOY, not here.\",\n \"--provider and --region are not a region picker. They record which of the control plane's \"\n + \"registered deploy targets this project belongs to; the private beta has one, so both \"\n + \"default to it and neither moves a project anywhere else.\"\n ]\n },\n\n \"db create\": {\n command: \"cloud db create\",\n usage: \"cloud db create --type <managed|byodb> [options]\",\n summary:\n \"Attach a database to the project. Required before the first deploy: a project with no \"\n + \"database stays at status \\\"provisioning\\\" forever, waiting for this command. \"\n + \"`rebase cloud projects create` now does it for you unless you passed --db none.\",\n flags: [\n [\"--type <managed|byodb>\", \"Platform-provisioned Postgres, or your own\"],\n [\"--connection-string <url>\", \"The PostgreSQL URL, for --type byodb\"],\n [\"--wait\", \"Wait for the database to answer (byodb only — see below)\"],\n [\"--timeout <seconds>\", \"Ceiling on --wait. Default: 300\"]\n ],\n examples: [\n \"rebase cloud db create --type managed\",\n \"rebase cloud db create --type byodb --connection-string \\\"$DATABASE_URL\\\" --wait\"\n ],\n notes: [\n \"A managed database is a CloudNativePG cluster of the project's own, in the project's \"\n + \"own namespace and backed up on its own schedule. It is created at the project's first \"\n + \"deploy: there is nothing to poll before then, so --wait says so and returns rather \"\n + \"than looping.\",\n \"`rebase cloud db test` legitimately fails before the first deploy.\",\n \"A project has exactly one database — attaching a second is refused, because the \"\n + \"platform reads one row and it becomes undefined which it deploys against.\"\n ]\n },\n\n \"db connect\": {\n command: \"cloud db connect\",\n usage: \"cloud db connect [--port <n>] [--reveal]\",\n summary:\n \"Open a local port that is the project's managed database, and hold it open until Ctrl-C. \"\n + \"A managed database lives inside the platform's cluster, so the host `db info` reports is \"\n + \"your backend's address for it and resolves to nothing on your machine; this is what makes \"\n + \"it reachable from here. Point psql, TablePlus, Drizzle Studio or pg_dump at the URL it \"\n + \"prints. The database still asks for its password — the tunnel is a network path, not a \"\n + \"credential.\",\n flags: [\n [\"--port <n>\", \"Local port to listen on. Default: 5432\"],\n [\"--reveal\", \"Print the password inside the connection URL\"]\n ],\n examples: [\n \"rebase cloud db connect\",\n \"rebase cloud db connect --port 6543\",\n \"rebase cloud db connect --reveal --project shop\"\n ],\n notes: [\n \"Requires the organization's owner or admin role — the same gate as the console's SQL \"\n + \"console, because it is the same capability.\",\n \"Piped or with --json it prints one object — host, port, database, username, \"\n + \"connectionString — and keeps serving, so a script can read the URL and connect.\",\n \"Connections go through the control plane, so they count against the project's own \"\n + \"database connection limit like any other client.\",\n \"Bring-your-own databases are refused: that host is already yours to reach, and there is \"\n + \"nothing for the platform to tunnel.\"\n ]\n },\n\n deploy: {\n command: \"cloud deploy\",\n usage: \"cloud deploy [app] [options]\",\n summary:\n \"Deploy an app of the linked project and follow the build to a terminal state, exiting \"\n + \"non-zero if it failed. With no app named, the repository's backend is deployed.\",\n flags: [\n [\"--wait\", \"Follow to a terminal state. Already the default; here to be explicit\"],\n [\"--timeout <seconds>\", \"Ceiling on the follow. Default: 900\"],\n [\"--no-follow\", \"Return as soon as the build is triggered\"],\n [\"--message, -m <text>\", \"Label the release\"],\n [\"--bundle\", \"Force a managed-bundle deploy (the default for runtime: managed)\"],\n [\"--bundle-dir <path>\", \"Deploy a bundle that is already built\"],\n [\"--source <path>\", \"Upload this directory and build a container image from it\"],\n [\"--skip-type-check\", \"Compile without type checking, as `rebase build` does\"],\n [\"--skip-schema\", \"Keep the committed database schema instead of regenerating it\"],\n [\"--no-static\", \"Deploy the backend without folding the static apps into its bundle\"],\n [\"--no-source\", \"Do not upload the project's source beside a backend bundle\"],\n [\"--allow-downgrade\", \"Deploy a bundle built on an older framework release than the project runs\"],\n [\"--eject\", \"Leave the managed runtime on purpose (ejects to a container image)\"]\n ],\n examples: [\n \"rebase cloud deploy\",\n \"rebase cloud deploy web --message \\\"add search\\\"\",\n \"rebase cloud deploy --timeout 300 --json\"\n ],\n notes: [\n \"A project whose rebase.json declares runtime: managed deploys a bundle without --bundle.\",\n \"--source on a managed project is refused: it would swap the project onto a container image.\",\n \"A backend bundle deploy also uploads the project's source (what git tracks, never a .env), so a \"\n + \"platform upgrade can rebuild it on a newer release. If it is over 100 MB or the upload fails, \"\n + \"the deploy goes on without it and says so.\",\n \"A bundle older than the release the project runs is refused as FRAMEWORK_DOWNGRADE. Run \"\n + \"`rebase upgrade` and deploy again, or pass --allow-downgrade.\"\n ]\n },\n\n logs: {\n command: \"cloud logs\",\n usage: \"cloud logs [--runtime] [--follow]\",\n summary: \"The latest build log, or the running container's log with --runtime.\",\n flags: [\n [\"--runtime\", \"The running app's log instead of the build log\"],\n [\"--follow, -f\", \"Tail a build that is still running\"]\n ],\n examples: [\"rebase cloud logs\", \"rebase cloud logs --runtime\", \"rebase cloud logs -f\"]\n },\n\n status: {\n command: \"cloud status\",\n usage: \"cloud status\",\n summary:\n \"One-glance project status: URL, last deploy, runtime, database, storage — and \"\n + \"blockedOn/nextAction, which say whether the platform is working or waiting for you.\",\n flags: [],\n examples: [\"rebase cloud status\", \"rebase cloud status --project shop --json\"],\n notes: [\n \"Poll `status` only while blockedOn is null. Any other value names a command, and the \"\n + \"state will not change until you run it.\"\n ]\n },\n\n \"clusters add\": {\n command: \"cloud clusters add\",\n usage: \"cloud clusters add --name <n> --provider <gcp|aws|hetzner> --region <r> --kubeconfig <path> [options]\",\n summary:\n \"Register a cluster. Everything the row needs to serve tenants is set here, at insert, \"\n + \"because the control plane installs the cluster baseline on insert and reads the row to do it: \"\n + \"the name is what a Hetzner load balancer is adopted by, the address is what the ingress is pinned to.\",\n flags: [\n [\"--name <n>\", \"The cluster's name. On Hetzner, its load balancer is `<name>-ingress`\"],\n [\"--provider <gcp|aws|hetzner>\", \"Where it runs\"],\n [\"--region <r>\", \"Its region id (europe-west1, fsn1, hel1). Projects placed here deploy to it\"],\n [\"--kubeconfig <path>\", \"A kubeconfig for the control plane's identity on it\"],\n [\"--base-domain <d>\", \"Tenants on it are served at <subdomain>.<d>. Convention: <region>.rebase.website\"],\n [\"--ingress-address <ip>\", \"Its pinned ingress address — what the wildcard DNS record points at\"],\n [\"--platform-capacity\", \"This is capacity Rebase operates: projects placed in its region deploy here. Leave off for a customer's own cluster\"],\n [\"--backup-bucket <b>\", \"Its own object-storage bucket for database backups (with the three below)\"],\n [\"--backup-endpoint <url>\", \"S3 endpoint of that bucket, e.g. https://fsn1.your-objectstorage.com\"],\n [\"--backup-access-key-id <k>\", \"Key for the bucket\"],\n [\"--backup-secret-access-key <s>\", \"Secret for the bucket. Encrypted at rest\"]\n ],\n examples: [\n \"rebase cloud clusters add --name gke-eu --provider gcp --region europe-west1 --kubeconfig ./kubeconfig\",\n \"rebase cloud clusters add --name rebase-fsn1 --provider hetzner --region fsn1 --kubeconfig ./control-plane.kubeconfig \"\n + \"--base-domain fsn1.rebase.website --ingress-address 49.13.1.1 --platform-capacity \"\n + \"--backup-bucket rebase-fsn1-db-backups --backup-endpoint https://fsn1.your-objectstorage.com \"\n + \"--backup-access-key-id … --backup-secret-access-key …\"\n ],\n notes: [\n \"The backup flags go together; a bucket without a key is a cluster with no backup store.\",\n \"A Hetzner cluster registered with --platform-capacity must bring its own backup store.\"\n ]\n },\n\n \"clusters verify\": {\n command: \"cloud clusters verify\",\n usage: \"cloud clusters verify <cluster-id> [--baseline]\",\n summary:\n \"Ask a registered cluster whether it can host tenants. Reports permissions.allowed and \"\n + \"permissions.denied, which is what names a missing RBAC grant.\",\n flags: [[\"--baseline\", \"Also check ingress-nginx, cert-manager and CloudNativePG\"]],\n examples: [\"rebase cloud clusters verify gke-europe-west1 --baseline\"],\n notes: [\"Exits non-zero when the verdict is `unusable`, so it works as a gate.\"]\n },\n\n /* ── The leaves that were undiscoverable ───────────────────────────\n *\n * Every entry below existed as a command with its own flag spec and no page\n * of its own, so `--help` fell through to its group's index — a list of\n * sibling actions and not one flag. `storage attach`'s six flags were read\n * out of `dist/index.es.js` by somebody deploying a real project, and the\n * only way to learn that `storage create` takes no flags at all was the\n * same one. The completeness check in `action-help.test.ts` now requires a\n * page for every command that names itself to `parseCloudArgs`.\n */\n\n \"resources prune\": {\n command: \"cloud resources prune\",\n usage: \"cloud resources prune database <key> [--yes]\",\n summary:\n \"Drop a platform-provisioned database that this project's code no longer declares. \"\n + \"A deploy never removes one — it keeps, binds and bills it — so this is where it goes. \"\n + \"Only a database: a bucket and its files are removed in the project's storage settings.\",\n flags: [],\n examples: [\"rebase cloud resources prune database analytics --yes\"],\n notes: [\n \"`--yes` is the global flag, listed below. Off a terminal this command refuses rather than assuming it.\",\n \"Refused while the code still declares the database, and for one the platform never made.\",\n \"Its connection string leaves the running backend at the next deploy.\"\n ]\n },\n\n \"projects delete\": {\n command: \"cloud projects delete\",\n usage: \"cloud projects delete <slug|id> [--yes]\",\n summary:\n \"Delete a project: its deployments, its database and its subdomain. The subdomain is \"\n + \"not reusable afterwards. Takes no options of its own — `--yes` is the global one.\",\n flags: [],\n examples: [\"rebase cloud projects delete shop --yes\"],\n notes: [\"Irreversible. Without --yes it prompts, and off a terminal it refuses rather than assuming.\"]\n },\n\n \"db backup\": {\n command: \"cloud db backup\",\n usage: \"cloud db backup <list|create|restore|status|download> [filename] [--yes]\",\n summary:\n \"Take, list, inspect, download and restore this project's database backups. \"\n + \"`list` is the default when no action is given.\",\n flags: [],\n examples: [\n \"rebase cloud db backup\",\n \"rebase cloud db backup create\",\n \"rebase cloud db backup status\",\n \"rebase cloud db backup restore base-20260831 --yes\",\n \"rebase cloud db backup download base-20260831\"\n ],\n notes: [\n \"`restore` replaces the live database. Nothing about it is undoable from here — `--yes`, the global flag listed below, is what skips that confirmation.\",\n \"Backups are the project's own: a base backup on a schedule, plus continuous WAL archiving for point-in-time recovery.\"\n ]\n },\n\n \"db pitr\": {\n command: \"cloud db pitr\",\n usage: \"cloud db pitr <status|restore|cutover|discard> [--target <timestamp>] [--yes]\",\n summary:\n \"Point-in-time recovery. `status` reports the recoverable window; `restore` stages a \"\n + \"recovered copy beside the live database; `cutover` repoints the app at that copy; \"\n + \"`discard` throws it away. `status` is the default.\",\n flags: [\n [\"--target <timestamp>\", \"The instant to recover to, ISO-8601. Defaults to the latest recoverable point\"]\n ],\n examples: [\n \"rebase cloud db pitr\",\n \"rebase cloud db pitr restore --target 2026-08-30T14:00:00Z\",\n \"rebase cloud db pitr cutover --yes\",\n \"rebase cloud db pitr discard\"\n ],\n notes: [\n \"`restore` does not touch the live database — `cutover` is the step that does. `--yes`, the global flag listed below, skips the confirmation on both.\",\n \"Recovery is only possible inside the window `status` reports. Check it first.\"\n ]\n },\n\n \"deployments list\": {\n command: \"cloud deployments list\",\n usage: \"cloud deployments [list] [--limit <n>] [--all]\",\n summary: \"The project's deployment history, newest first, with the status and image of each.\",\n flags: [\n [\"--limit <n>\", \"How many to return. Bounded; a value over the maximum is refused, not clamped\"],\n [\"--all\", \"Return the maximum instead of naming a limit\"]\n ],\n examples: [\n \"rebase cloud deployments\",\n \"rebase cloud deployments list --limit 5\",\n \"rebase cloud deployments --all --json\"\n ]\n },\n\n \"domains add\": {\n command: \"cloud domains add\",\n usage: \"cloud domains add <domain>\",\n summary:\n \"Register a custom domain on this project, beside any it already has, and print the DNS records to publish. \"\n + \"Registering is not verifying — run `domains verify <domain>` once the records are live.\",\n flags: [],\n examples: [\"rebase cloud domains add app.example.com\"],\n notes: [\n \"At a zone apex use the A record this prints, not a CNAME: a CNAME is invalid at an apex.\",\n \"Verification is a separate command because DNS propagation is not instant.\"\n ]\n },\n\n \"domains remove\": {\n command: \"cloud domains remove\",\n usage: \"cloud domains remove <domain>\",\n summary:\n \"Stop serving one custom domain. The project keeps its other domains and its <slug>.rebase.website host. \"\n + \"The domain may be left out when the project has only one. Aliases: `rm`, `delete`.\",\n flags: [],\n examples: [\"rebase cloud domains remove app.example.com\"]\n },\n\n \"env set\": {\n command: \"cloud env set\",\n usage: \"cloud env set KEY=VALUE | KEY VALUE [--secret] [--force]\",\n summary:\n \"Set one environment variable on the project. Takes effect on the next deploy — \"\n + \"a running instance does not pick it up.\",\n flags: [\n [\"--secret\", \"Store it encrypted and never return it in a listing\"],\n [\"--force\", \"Set a build-time key (VITE_*, NEXT_PUBLIC_*, …) anyway, for a build that reads it at run time\"]\n ],\n examples: [\n \"rebase cloud env set STRIPE_KEY=sk_live_… --secret\",\n \"rebase cloud env set LOG_LEVEL debug\",\n \"rebase cloud env set FEATURE_X= \"\n ],\n notes: [\n \"A value starting with `-` must use the KEY=VALUE form; the KEY VALUE form refuses it.\",\n \"Variables the platform sets for every project cannot be overridden — `env reveal` reads them.\"\n ]\n },\n\n \"env pull\": {\n command: \"cloud env pull\",\n usage: \"cloud env pull [--output <path>]\",\n summary:\n \"Write the project's variables to a local .env file. Secrets come through, so the file \"\n + \"this produces is a credential.\",\n flags: [[\"--output, --out <path>\", \"Where to write. Default: .env\"]],\n examples: [\n \"rebase cloud env pull\",\n \"rebase cloud env pull --output .env.production\"\n ],\n notes: [\"Add the file it writes to .gitignore before running it, not after.\"]\n },\n\n \"storage create\": {\n command: \"cloud storage create\",\n usage: \"cloud storage create\",\n summary:\n \"Provision platform-managed storage: a bucket and its credentials, written onto the \"\n + \"project and injected into the tenant at deploy time. Takes no options of its own — \"\n + \"region and naming come from the platform.\",\n flags: [],\n examples: [\"rebase cloud storage create\"],\n notes: [\n \"Creates billable infrastructure, and requires org admin rather than membership.\",\n \"The secret key is never displayed: it goes to the project record and to the tenant's environment.\",\n \"Redeploy afterwards — a running instance has no credentials for a bucket created after it started.\"\n ]\n },\n\n \"storage attach\": {\n command: \"cloud storage attach\",\n usage:\n \"cloud storage attach --bucket <name> --access-key-id <id> --secret-access-key <secret> \"\n + \"[--endpoint <url>] [--region <region>] [--force-path-style] [--source <key>]\",\n summary:\n \"Point the project at storage you already own — S3, R2, MinIO, any S3-compatible bucket. \"\n + \"The alternative to `storage create`, for a bucket the platform does not manage.\",\n flags: [\n [\"--bucket <name>\", \"The bucket name. Required\"],\n [\"--access-key-id <id>\", \"Required\"],\n [\"--secret-access-key <secret>\", \"Required. Stored encrypted and never returned\"],\n [\"--endpoint <url>\", \"For anything that is not AWS S3 — R2, MinIO, Backblaze\"],\n [\"--region <region>\", \"Bucket region. Default: the provider's own default\"],\n [\"--force-path-style\", \"Address as endpoint/bucket rather than bucket.endpoint. Needed by MinIO\"],\n [\"--source <key>\", \"Which declared bucket to configure. Default: the project's default bucket\"]\n ],\n examples: [\n \"rebase cloud storage attach --bucket assets --access-key-id … --secret-access-key …\",\n \"rebase cloud storage attach --source media --bucket media-eu --access-key-id … --secret-access-key …\",\n \"rebase cloud storage attach --bucket assets --access-key-id … --secret-access-key … \\\\\\n\"\n + \" --endpoint https://<account>.r2.cloudflarestorage.com --region auto\"\n ],\n notes: [\n \"All three of --bucket, --access-key-id and --secret-access-key, or none: a bucket with no \"\n + \"credentials reads as configured and fails on the first upload.\",\n \"Redeploy for the tenant to pick the credentials up.\"\n ]\n },\n\n \"webhooks create\": {\n command: \"cloud webhooks create\",\n usage:\n \"cloud webhooks create --name <name> --table <table> --endpoint <url> [--events <list>]\",\n summary: \"Register an outbound webhook on a table's row changes.\",\n flags: [\n [\"--name <name>\", \"Required. What it is called in listings\"],\n [\"--table <table>\", \"Required. The table whose changes fire it\"],\n [\"--endpoint <url>\", \"Required. Where the POST goes\"],\n [\"--events <list>\", \"Comma-separated: insert, update, delete. Default: all three\"]\n ],\n examples: [\n \"rebase cloud webhooks create --name notify --table orders --endpoint https://example.com/hook\",\n \"rebase cloud webhooks create --name audit --table users --endpoint https://example.com/hook --events insert,delete\"\n ],\n notes: [\n \"`--endpoint`, not `--url`: every cloud command's `--url` names the control plane, and one written here would be authenticated against instead of called.\"\n ]\n },\n\n \"webhooks delete\": {\n command: \"cloud webhooks delete\",\n usage: \"cloud webhooks delete <id>\",\n summary: \"Remove one webhook by the id `webhooks list` prints.\",\n flags: [],\n examples: [\"rebase cloud webhooks delete 42\"]\n },\n\n deployments: {\n command: \"cloud deployments\",\n usage: \"cloud deployments [list] [options]\",\n summary: \"The project's deployment history. `list` is the only action, and the default.\",\n flags: [],\n examples: [\"rebase cloud deployments\", \"rebase cloud deployments list --limit 5\"]\n },\n\n webhooks: {\n command: \"cloud webhooks\",\n usage: \"cloud webhooks <list|create|delete> [options]\",\n summary: \"Outbound webhooks on a table's row changes.\",\n flags: [],\n examples: [\n \"rebase cloud webhooks list\",\n \"rebase cloud webhooks create --help\",\n \"rebase cloud webhooks delete 42\"\n ]\n },\n\n billing: {\n command: \"cloud billing\",\n usage: \"cloud billing [setup|checkout]\",\n summary:\n \"The selected organization's billing. Bare, it prints the billing account, the card on \"\n + \"file and what the linked project costs per month; `setup` attaches a card (one-time, \"\n + \"opens a browser); `checkout` opens a Stripe session for one project. \"\n + \"Organization-scoped, not project-scoped.\",\n flags: [],\n examples: [\n \"rebase cloud billing\",\n \"rebase cloud billing setup\",\n \"rebase cloud billing checkout --project shop\"\n ],\n notes: [\n \"`setup` comes before the first deploy: without a card the control plane answers 402, and `deploy` refuses before it builds.\"\n ]\n },\n\n /* ── The graph, and the dials ───────────────────────────────────────\n *\n * `resources` is what the project declares against what the platform\n * holds; `compute` is CPU, memory, replicas and what they cost. They were\n * one word once, which is how `rebase cloud resources` came to mean the\n * dials and `rebase resources` the graph — the same word for two things,\n * one letter of context apart.\n *\n * `compute` is two pages rather than one, because they answer different\n * questions: bare is \"what does this project have, and what does it cost\",\n * `set` is \"what may I change it to\". The prices are not repeated here —\n * the control plane quotes them and both pages say so, which is the only\n * version of this that cannot go stale. */\n\n resources: {\n command: \"cloud resources\",\n usage: \"cloud resources [list|prune] [options]\",\n summary:\n \"Each database and bucket this project's deploys recorded: whether the last deploy's \"\n + \"code still declares it, and whether the platform made it. A deploy never removes a \"\n + \"provisioned database when its declaration goes — that would be data deleted by a \"\n + \"push — so it keeps, binds and bills it until `prune` names it.\",\n flags: [],\n examples: [\n \"rebase cloud resources\",\n \"rebase cloud resources --json\",\n \"rebase cloud resources prune database analytics\"\n ],\n notes: [\n \"`rebase resources` reads the code; this reads the platform. The two disagreeing is the point of the page.\",\n \"For CPU, memory, replicas and cost, that is `rebase cloud compute`.\"\n ]\n },\n\n compute: {\n command: \"cloud compute\",\n usage: \"cloud compute [set] [options]\",\n summary:\n \"What this project reserves, and what the control plane would invoice for it. Bare, it \"\n + \"prints every dial and an itemised €/month; `set` changes one. An empty dial means the \"\n + \"platform default, which moves when the default moves — a dial pinned to the same \"\n + \"number does not.\",\n flags: [],\n examples: [\n \"rebase cloud compute\",\n \"rebase cloud compute --json\",\n \"rebase cloud compute set --help\"\n ],\n notes: [\n \"The price is the control plane's own quote for these dials, itemised line by line — not a tier, and not a number this CLI computes.\"\n ]\n },\n\n \"compute set\": {\n command: \"cloud compute set\",\n usage: \"cloud compute set [--cpu <n>] [--memory <size>] [--replicas <n>] [...]\",\n summary:\n \"Change one or more of a project's dials. At least one is required: a patch with nothing \"\n + \"in it is a typo, and reporting success for a change nobody made is worse than refusing.\",\n flags: [\n [\"--cpu <n>\", \"App CPU request per instance, e.g. 500m or 2. Default: 250m\"],\n [\"--memory <size>\", \"App memory request per instance, e.g. 512Mi or 2Gi. Default: 512Mi\"],\n [\"--replicas <n>\", \"Instances that always exist — the autoscaler's floor, and what is billed at rest\"],\n [\"--spot <true|false>\", \"Preemptible capacity: cheaper, and restarted without notice\"],\n [\"--scale-to-zero <true|false>\", \"Request-billed compute that stops when idle, at the cost of a cold start\"],\n [\"--db-instances <n>\", \"1–3. 1 is a single instance with no failover; 2 adds an automatic standby\"],\n [\"--db-cpu <n>\", \"Database CPU request per instance. Default: 500m\"],\n [\"--db-memory <size>\", \"Database memory request per instance. Default: 2Gi\"],\n [\"--storage <size>\", \"Database volume size\"],\n [\"--autoscale-max <n>\", \"1–16. The ceiling the app may reach, and the worst case it may be billed\"],\n [\"--autoscale-cpu-target <pct>\", \"10–95. CPU utilisation the autoscaler holds, against the request. Default: 70\"],\n [\"--no-autoscale\", \"Turn autoscaling off. The only way to: a ceiling at or below --replicas is refused\"]\n ],\n examples: [\n \"rebase cloud compute set --cpu 500m --memory 2Gi\",\n \"rebase cloud compute set --replicas 2 --autoscale-max 6\",\n \"rebase cloud compute set --db-instances 2 --db-memory 4Gi\"\n ],\n notes: [\n \"Run `rebase cloud compute` first — it prints the current dials and the €/month this project is quoted.\",\n \"Applied immediately: the app rolls its pods and the subscription is prorated from today. A change that restarts the database waits for a maintenance window.\",\n \"The valid ranges are the target cluster's, not this CLI's — GKE Autopilot bills a 250m/512Mi floor and rewrites a memory:CPU ratio outside 1:1–6.5:1, a Hetzner node has neither constraint. The control plane refuses what it cannot honour and names the field.\"\n ]\n },\n\n /* ── Session, link, and the operations with no flags of their own ────\n *\n * Every one of these fell through to the index page, which lists groups\n * and not one flag — so `login --password`, `link`'s positional URL and\n * the `-y` that `stop` requires had no discoverable spelling. They take\n * few options, and that is exactly what a reader needs told. */\n\n login: {\n command: \"cloud login\",\n usage: \"cloud login [--email <address>] [--password <password>]\",\n summary:\n \"Sign in to the control plane and write the session to ~/.rebase/credentials.json. \"\n + \"Prompts for whatever is missing when attached to a terminal, and refuses rather than \"\n + \"hangs when it is not.\",\n flags: [\n [\"--email, -e <address>\", \"The account's email. Prompted when omitted, or REBASE_CLOUD_EMAIL\"],\n [\"--password <password>\", \"Discouraged: a password written here is recorded in your shell history and visible in the process table. Prefer the prompt, or REBASE_CLOUD_PASSWORD\"]\n ],\n examples: [\n \"rebase cloud login\",\n \"rebase cloud login --email me@example.com\",\n \"rebase cloud login --url https://cloud.example.com\"\n ],\n notes: [\n \"--password warns, once, before the request: by the time a login succeeds the password is already in the history file.\",\n \"There is no machine token yet, so CI genuinely needs a human's credentials. REBASE_CLOUD_EMAIL and \"\n + \"REBASE_CLOUD_PASSWORD are how a secret store hands them over without them appearing on a command line.\",\n \"In a directory whose .rebase/cloud.json names a control plane you have not signed in to before, login \"\n + \"names it and asks first, and refuses without a terminal: a cloned repository does not choose where \"\n + \"your password goes. Pass --url <that host> to sign in there on purpose.\"\n ]\n },\n\n logout: {\n command: \"cloud logout\",\n usage: \"cloud logout [--url <origin>]\",\n summary:\n \"Forget the session for a control plane. Idempotent — logging out when you are not \"\n + \"logged in is a success, and `wasLoggedIn` in the JSON is how a script tells the two apart.\",\n flags: [],\n examples: [\"rebase cloud logout\"]\n },\n\n whoami: {\n command: \"cloud whoami\",\n usage: \"cloud whoami\",\n summary: \"Who this session is, which control plane it is against, and what this directory is linked to.\",\n flags: [],\n examples: [\"rebase cloud whoami\", \"rebase cloud whoami --json\"]\n },\n\n link: {\n command: \"cloud link\",\n usage: \"cloud link [<url>] [--project <slug>]\",\n summary:\n \"Bind this directory to a backend, by writing .rebase/cloud.json. With a cloud project \"\n + \"(picked interactively, or named with --project) the rest of the family needs no flags. \"\n + \"With a positional URL it links straight at a running Rebase API — no control plane, no \"\n + \"login — which is what makes the multi-repo workflow available to self-hosters.\",\n flags: [],\n examples: [\n \"rebase cloud link\",\n \"rebase cloud link --project shop\",\n \"rebase cloud link https://api.example.com\"\n ],\n notes: [\n \"A positional URL is verified before it is written: an address that does not answer is still linked, but you are told.\",\n \"A direct link is one backend, not a control plane. The rest of the `cloud` family refuses in a directory linked that way — unlink first, or pass `--project` — so that `login` can never send your control-plane password to the linked host.\",\n \".rebase/cloud.json is not a secret and is not your credentials — those live in ~/.rebase/credentials.json.\"\n ]\n },\n\n unlink: {\n command: \"cloud unlink\",\n usage: \"cloud unlink\",\n summary:\n \"Remove this directory's link. Idempotent, like logout: `unlinked: false` says there was \"\n + \"nothing to remove.\",\n flags: [],\n examples: [\"rebase cloud unlink\"]\n },\n\n use: {\n command: \"cloud use\",\n usage: \"cloud use [<org>]\",\n summary:\n \"Select the active organization — the one `projects create`, `billing` and `orgs` act on. \"\n + \"Named, it is set; omitted, you pick from the ones this account belongs to.\",\n flags: [],\n examples: [\"rebase cloud use\", \"rebase cloud use acme\"]\n },\n\n open: {\n command: \"cloud open\",\n usage: \"cloud open\",\n summary:\n \"Open the console in a browser — the linked project's page when this directory is linked, \"\n + \"the dashboard otherwise. The URL is the result, so a piped run prints it instead.\",\n flags: [],\n examples: [\"rebase cloud open\"]\n },\n\n rollback: {\n command: \"cloud rollback\",\n usage: \"cloud rollback [<deploymentId>] [--yes]\",\n summary:\n \"Put a previous successful deployment back into service. Without an id, the most recent \"\n + \"rollbackable deployment that is not the live one. History is appended, never rewound: \"\n + \"a rollback is a new deployment row pointing back at the old one.\",\n flags: [],\n examples: [\n \"rebase cloud rollback\",\n \"rebase cloud deployments list\",\n \"rebase cloud rollback 214 --yes\"\n ],\n notes: [\n \"`rebase cloud deployments list` marks which rows are rollbackable. One that is not is refused here rather than by a 409 from the control plane.\"\n ]\n },\n\n cancel: {\n command: \"cloud cancel\",\n usage: \"cloud cancel [<deploymentId>] [--yes]\",\n summary:\n \"Stop the build in flight for this project. Without an id, whichever one is deploying. \"\n + \"Also the way out of a project whose status claims a deploy that no deployment row backs.\",\n flags: [],\n examples: [\"rebase cloud cancel\", \"rebase cloud cancel 214 --yes\"]\n },\n\n start: {\n command: \"cloud start\",\n usage: \"cloud start\",\n summary: \"Bring a stopped project back into service.\",\n flags: [],\n examples: [\"rebase cloud start\"]\n },\n\n stop: {\n command: \"cloud stop\",\n usage: \"cloud stop [--yes]\",\n summary:\n \"Stop the project. This is downtime, so it is confirmed — pass --yes to skip the prompt, \"\n + \"which a non-interactive run must.\",\n flags: [],\n examples: [\"rebase cloud stop\", \"rebase cloud stop --yes\"]\n },\n\n restart: {\n command: \"cloud restart\",\n usage: \"cloud restart [--yes]\",\n summary:\n \"Stop the project and start it again. A real stop and start, with genuine downtime in \"\n + \"between, so it is confirmed like `stop`.\",\n flags: [],\n examples: [\"rebase cloud restart --yes\"]\n },\n\n metrics: {\n command: \"cloud metrics\",\n usage: \"cloud metrics\",\n summary: \"Live CPU, memory and disk for the project's running units, as the control plane reports them.\",\n flags: [],\n examples: [\"rebase cloud metrics\", \"rebase cloud metrics --json\"]\n }\n};\n\n/** Print one action's page — human, or its JSON description when piped. */\nexport function printActionHelp(entry: ActionHelp): void {\n emitHelp(\n entry.command,\n [],\n () => {\n console.log(\"\");\n console.log(`${chalk.bold(`rebase ${entry.command}`)}`);\n console.log(\"\");\n console.log(` ${entry.summary}`);\n console.log(\"\");\n console.log(chalk.green.bold(\"Usage\"));\n console.log(` rebase ${chalk.blue(entry.usage.replace(/^cloud /, \"cloud \"))}`);\n if (entry.flags.length > 0) {\n console.log(\"\");\n console.log(chalk.green.bold(\"Options\"));\n for (const [flag, description] of entry.flags) {\n console.log(` ${chalk.blue(flag.padEnd(30))} ${description}`);\n }\n }\n console.log(\"\");\n console.log(chalk.green.bold(\"Global options\"));\n for (const [flag, description] of GLOBAL_HELP_FLAGS) {\n console.log(` ${chalk.blue(flag.padEnd(30))} ${chalk.gray(description)}`);\n }\n if (entry.notes?.length) {\n console.log(\"\");\n console.log(chalk.green.bold(\"Notes\"));\n for (const note of entry.notes) console.log(` ${chalk.gray(`• ${note}`)}`);\n }\n console.log(\"\");\n console.log(chalk.green.bold(\"Examples\"));\n for (const example of entry.examples) console.log(` ${chalk.gray(example)}`);\n console.log(\"\");\n },\n {\n usage: `rebase ${entry.usage}`,\n summary: entry.summary,\n flags: [...entry.flags, ...GLOBAL_HELP_FLAGS].map(([flag, description]) => ({ flag,\ndescription })),\n notes: entry.notes ?? [],\n examples: entry.examples\n }\n );\n}\n","/**\n * CLI command: `rebase cloud <group> [action] [options]`\n *\n * A single entry point for everything you do against Rebase Cloud — the hosted\n * control plane. Auth, project link, deploys, databases, and the rest are all\n * dispatched from here. Individual groups live in sibling modules; this file\n * only routes and prints help.\n */\nimport arg from \"arg\";\nimport chalk from \"chalk\";\nimport { loginCommand, logoutCommand, whoamiCommand } from \"./auth\";\nimport { linkCommand, unlinkCommand, selectOrgCommand, openCommand } from \"./link\";\nimport { listProjects, createProject, projectInfo, deleteProject, resolveProjectArg } from \"./projects\";\nimport { deployCommand, logsCommand } from \"./deploy\";\nimport { orgsCommand, printOrgsHelp } from \"./orgs\";\nimport { dbCommand, printDbHelp } from \"./databases\";\nimport { envCommand, printEnvHelp } from \"./env\";\nimport { domainsCommand, printDomainsHelp } from \"./domains\";\nimport { extensionsCommand, printExtensionsHelp } from \"./extensions\";\nimport { settingsCommand, printSettingsHelp } from \"./settings\";\nimport { deploymentsListCommand, rollbackCommand, cancelCommand } from \"./deployments\";\nimport { powerCommand } from \"./power\";\nimport { debugCommand, printDebugHelp } from \"./debug\";\nimport {\n statusCommand,\n metricsCommand,\n webhooksCommand,\n storageCommand,\n computeCommand,\n clustersCommand,\n billingCommand,\n printStorageHelp\n} from \"./resources\";\nimport { declaredResourcesCommand } from \"./declared-resources\";\nimport {\n requireProjectRef,\n initOutputMode,\n printGroupHelp,\n fail,\n GLOBAL_CLOUD_FLAGS,\n type HelpAction\n} from \"./context\";\nimport { ACTION_HELP, printActionHelp } from \"./action-help\";\n\n/**\n * Positional tokens after `rebase cloud` (group, action, …).\n *\n * Two things stop a flag being mistaken for the group. `GLOBAL_CLOUD_FLAGS` is\n * declared so `arg` *consumes* the flags that may precede it — critically\n * together with their values, which is the half that filtering cannot do. The\n * leading-`-` skip then covers a flag nobody declared, so an unrecognised\n * boolean shifts nothing.\n *\n * Only leading tokens are skipped: past the group and action, an undeclared\n * flag and its value are somebody else's positionals and none of our business.\n * A flag this file has never heard of, that takes a value, placed before the\n * group, is the one shape still unresolvable here — there is no way to know\n * whether the token after it is its value or the group, and guessing either way\n * is worse than the handler reporting an unknown group.\n *\n * Exported so its tests can drive the real thing. The dispatch test used to\n * re-implement it locally as `slice(3).filter(a => !a.startsWith(\"-\"))` — which\n * filtered flags, while this function did not — so the test asserted the\n * behaviour we wanted against a copy that had it, and stayed green for as long\n * as the real dispatcher was broken.\n */\nexport function positionals(rawArgs: string[]): string[] {\n const rest = arg(GLOBAL_CLOUD_FLAGS, { argv: rawArgs.slice(3),\npermissive: true })._;\n let i = 0;\n while (i < rest.length && rest[i].startsWith(\"-\")) i++;\n return rest.slice(i);\n}\n\n/**\n * The help page for each group, keyed by every alias the dispatch below accepts.\n *\n * Aliases are listed explicitly rather than normalised first, so a group that\n * gains one and forgets it here degrades to the index page — wrong, but a page.\n * `cloud-help.test.ts` asserts the two stay in step.\n *\n * A group absent from this map has no page of its own; the index lists it.\n */\n/**\n * The second spelling of a group, mapped to the one the pages are keyed on.\n *\n * The dispatch below accepts both (`case \"db\": case \"database\":`), so help has\n * to as well, or half the spellings of a command have no page.\n */\nexport const GROUP_ALIASES: Record<string, string> = {\n database: \"db\",\n domain: \"domains\",\n extension: \"extensions\",\n org: \"orgs\",\n project: \"projects\"\n};\n\nexport const GROUP_HELP: Record<string, () => void> = {\n env: printEnvHelp,\n domains: printDomainsHelp,\n domain: printDomainsHelp,\n extensions: printExtensionsHelp,\n extension: printExtensionsHelp,\n settings: printSettingsHelp,\n orgs: printOrgsHelp,\n org: printOrgsHelp,\n db: printDbHelp,\n database: printDbHelp,\n debug: printDebugHelp,\n storage: printStorageHelp\n};\n\nexport async function cloudCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void> {\n // Latch the output mode FIRST — before anything can print or `fail` — so the\n // whole command family agrees on human vs. machine-readable output.\n initOutputMode(rawArgs);\n\n const pos = positionals(rawArgs);\n // The positionals win over the `subcommand` the top-level parser handed us.\n // Both describe the same token, but only this one is resolved against a\n // flag spec: `cli.ts` is generic across every command and cannot know which\n // flags `cloud` takes, so with `cloud --json storage create` it reported the\n // subcommand as `\"--json\"`. Falling back to it keeps the parameter useful\n // when a caller passes a group that is not in `rawArgs` at all.\n const group = pos[0] ?? (subcommand !== \"--help\" ? subcommand : undefined);\n\n // `--help` has to be recovered from `rawArgs` rather than read off `pos`.\n // `positionals()` resolves against `GLOBAL_CLOUD_FLAGS`, which declares\n // `--help`, so `arg` *consumes* it — correct for `--project` and `--json`,\n // which modify a command, but wrong for `--help`, which replaces it.\n const wantsHelp = rawArgs.includes(\"--help\") || rawArgs.includes(\"-h\");\n // A flag is never an action. `rebase cloud env --frobnicate` used to read\n // the flag as the action and refuse it as an unknown *command* — a refusal,\n // but about the wrong half of the line; the group's own parser is what\n // knows the flag is undeclared, and it never got the chance to say so.\n // Skipped here rather than in `positionals()`, whose contract past the\n // action is deliberately \"these are somebody else's positionals\".\n const action = pos.slice(1).find(token => !token.startsWith(\"-\"));\n\n // The index help is for `rebase cloud` and `rebase cloud --help` — that is,\n // when no group was named. It used to also fire whenever `subcommand` was\n // the literal `\"--help\"`, which `cli.ts` set for *any* `--help` anywhere in\n // the line, so `rebase cloud env --help` printed this page instead of env's\n // and the per-group help in seven modules was unreachable. Keyed on the\n // group now, which is the thing that actually decides whose help this is.\n if (!group) {\n printCloudHelp();\n return;\n }\n\n // `--help` is answered here, before dispatch, and never by the command.\n //\n // Routing it as an action instead only worked for the groups that happened\n // to have a `case \"--help\"`. The others took `rawArgs` and ignored the\n // action entirely, so the flag did nothing and the command ran: `rebase\n // cloud env --help` tried to list variables and failed on \"No project\n // specified\", `rebase cloud deploy --help` started resolving a project, and\n // `rebase cloud link --help` opened an *interactive project picker* — a\n // prompt, from a flag whose entire job is to print text and exit.\n //\n // Answering centrally makes that structurally impossible: `--help` cannot\n // reach a handler, so it cannot prompt, call the API, or need a linked\n // project. A group without its own page falls back to the index rather than\n // to running something.\n //\n // Resolved most-specific-first. Group-level was all there was, so `rebase\n // cloud projects create --help` and `rebase cloud deploy --help` printed the\n // index — a list of groups, no flags — and `--name`, `--subdomain` and\n // `--type` had no discoverable spelling anywhere in the CLI. They were found\n // on a real first deploy by reading `dist/index.es.js.map`.\n if (wantsHelp) {\n // Through the alias, because the dispatch accepts both spellings and a\n // page keyed on one of them is not a page for the other: `rebase cloud\n // database create --help` reached the group index while\n // `rebase cloud db create --help` printed the flags.\n const canonical = GROUP_ALIASES[group] ?? group;\n const forAction = action ? ACTION_HELP[`${canonical} ${action}`] : undefined;\n const page = forAction ?? ACTION_HELP[canonical];\n if (page) {\n printActionHelp(page);\n return;\n }\n (GROUP_HELP[group] ?? printCloudHelp)();\n return;\n }\n\n switch (group) {\n /* auth */\n case \"login\":\n await loginCommand(rawArgs);\n break;\n case \"logout\":\n await logoutCommand(rawArgs);\n break;\n case \"whoami\":\n await whoamiCommand(rawArgs);\n break;\n\n /* context / link */\n case \"link\":\n await linkCommand(rawArgs);\n break;\n case \"unlink\":\n unlinkCommand(rawArgs);\n break;\n case \"use\":\n await selectOrgCommand(rawArgs);\n break;\n case \"open\":\n openCommand(rawArgs);\n break;\n\n /* projects */\n case \"projects\":\n case \"project\":\n await projectsGroup(action, rawArgs);\n break;\n\n /* deploy + logs (operate on linked/--project) */\n case \"deploy\":\n await deployCommand(rawArgs, requireProjectRef(rawArgs));\n break;\n case \"logs\":\n await logsCommand(rawArgs, requireProjectRef(rawArgs));\n break;\n case \"deployments\":\n case \"releases\":\n await deploymentsGroup(action, rawArgs);\n break;\n case \"rollback\":\n await rollbackCommand(rawArgs);\n break;\n case \"cancel\":\n await cancelCommand(rawArgs);\n break;\n case \"start\":\n case \"stop\":\n case \"restart\":\n await powerCommand(group, rawArgs);\n break;\n case \"status\":\n await statusCommand(rawArgs);\n break;\n case \"metrics\":\n await metricsCommand(rawArgs);\n break;\n case \"debug\":\n await debugCommand(action, rawArgs);\n break;\n\n /* env / domains / extensions / settings */\n case \"env\":\n await envCommand(action, rawArgs);\n break;\n case \"domains\":\n case \"domain\":\n await domainsCommand(action, rawArgs);\n break;\n case \"extensions\":\n case \"extension\":\n await extensionsCommand(action, rawArgs);\n break;\n case \"settings\":\n await settingsCommand(action, rawArgs);\n break;\n\n /* orgs */\n case \"orgs\":\n case \"org\":\n await orgsCommand(action, rawArgs);\n break;\n\n /* databases */\n case \"db\":\n case \"database\":\n await dbCommand(action, rawArgs);\n break;\n\n /* other resources */\n case \"webhooks\":\n await webhooksCommand(action, rawArgs);\n break;\n case \"storage\":\n await storageCommand(action, rawArgs);\n break;\n case \"compute\":\n await computeCommand(action, rawArgs);\n break;\n case \"resources\":\n // The word means the graph now, on both sides of the wire: what the\n // code declares against what the platform holds. What it used to\n // show — CPU, memory, cost — is `compute`, and a dial flag arriving\n // here is the one thing worth a pointed refusal.\n if (action === \"set\") {\n fail(\n \"`rebase cloud resources set` is now `rebase cloud compute set` — CPU, memory, replicas and cost.\",\n \"`rebase cloud resources` lists what this project declares against what the platform provisioned.\",\n \"renamed\"\n );\n }\n await declaredResourcesCommand(action, rawArgs);\n break;\n case \"clusters\":\n await clustersCommand(action, rawArgs);\n break;\n case \"billing\":\n await billingCommand(rawArgs);\n break;\n\n default:\n // Through `fail`, like every other refusal in the family — and like\n // the two group dispatchers below, which now match.\n //\n // It used to print a red line to stderr and then the ENTIRE help\n // page to stdout before exiting 1. Two things wrong with that: a\n // piped `rebase cloud typo` handed its caller ~60 lines of\n // ANSI-coloured help where the contract promises one JSON value,\n // and even on a terminal it put the remedy on the RESULTS stream of\n // a command that produced no result. The hint names `--help`, which\n // is the one command whose result the page actually is.\n fail(`Unknown cloud command: ${group}`, \"Run `rebase cloud --help`.\", \"unknown_command\");\n }\n}\n\nasync function projectsGroup(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"list\":\n case undefined:\n await listProjects(rawArgs);\n break;\n case \"create\":\n await createProject(rawArgs);\n break;\n // The id is resolved by the handlers' own module, against their own flag\n // spec. `positionals()` cannot do it: it declares only the global cloud\n // flags and skips only LEADING `-` tokens, so any other flag written\n // after the action became the id — `projects delete --force` looked up\n // a project named \"--force\".\n case \"info\":\n await projectInfo(rawArgs, resolveProjectArg(rawArgs, \"info\"));\n break;\n case \"delete\":\n await deleteProject(rawArgs, resolveProjectArg(rawArgs, \"delete\"));\n break;\n case \"--help\":\n printCloudHelp();\n break;\n default:\n fail(`Unknown projects command: ${action}`, \"Run `rebase cloud --help`.\", \"unknown_command\");\n }\n}\n\nasync function deploymentsGroup(action: string | undefined, rawArgs: string[]): Promise<void> {\n switch (action) {\n case \"list\":\n case undefined:\n await deploymentsListCommand(rawArgs);\n break;\n case \"--help\":\n printCloudHelp();\n break;\n default:\n fail(`Unknown deployments command: ${action}`, \"Run `rebase cloud --help`.\", \"unknown_command\");\n }\n}\n\n/**\n * Every group `cloudCommand` dispatches, canonical name first, with the line the\n * index page prints for it.\n *\n * One list, rendered twice. It used to be two: a bare array of words for the\n * JSON form and a hand-formatted template literal for the terminal — which is\n * how `clusters` came to be listed on the page twice, under two different\n * descriptions, in the same section. The page is generated from this now, so a\n * group appears exactly as often as it appears here, and `cloud-help.test.ts`\n * holds the list to the dispatch switch and to the pages.\n *\n * Sub-actions are deliberately not here. Every group answers `--help` with its\n * own page now, listing its actions, their arguments and their flags; repeating\n * a subset of that on the index is the duplication this replaced.\n */\nexport const CLOUD_GROUPS: HelpAction[] = [\n { action: \"login\", section: \"Auth\", description: \"Sign in to the control plane\" },\n { action: \"logout\", section: \"Auth\", description: \"Sign out\" },\n { action: \"whoami\", section: \"Auth\", description: \"Show the current session\" },\n\n { action: \"link\", section: \"Project link\", args: \"[url]\", description: \"Bind this directory to a cloud project, or straight to a backend URL\" },\n { action: \"unlink\", section: \"Project link\", description: \"Remove the link\" },\n { action: \"use\", section: \"Project link\", args: \"[org]\", description: \"Select the active organization\" },\n { action: \"open\", section: \"Project link\", description: \"Open the console in a browser\" },\n\n { action: \"projects\", section: \"Projects\", description: \"Create, list, inspect and delete projects\" },\n\n { action: \"deploy\", section: \"Deploy & observe\", args: \"[app]\", description: \"Build, upload and ship an app, following it to a terminal state\" },\n { action: \"logs\", section: \"Deploy & observe\", description: \"Build logs, or the runtime's with --runtime\" },\n { action: \"deployments\", section: \"Deploy & observe\", description: \"Deployment history: status, duration, trigger\" },\n { action: \"rollback\", section: \"Deploy & observe\", args: \"[id]\", description: \"Put a previous successful deployment back into service\" },\n { action: \"cancel\", section: \"Deploy & observe\", description: \"Stop the build in flight\" },\n { action: \"start\", section: \"Deploy & observe\", description: \"Bring a stopped project back\" },\n { action: \"stop\", section: \"Deploy & observe\", description: \"Stop the project. Downtime, so it confirms\" },\n { action: \"restart\", section: \"Deploy & observe\", description: \"Stop and start it again\" },\n { action: \"status\", section: \"Deploy & observe\", description: \"One glance: URL, last deploy, and what it is waiting on\" },\n { action: \"metrics\", section: \"Deploy & observe\", description: \"Live CPU, memory and disk\" },\n { action: \"debug\", section: \"Deploy & observe\", description: \"Diagnose a misbehaving deployment. Read-only\" },\n\n { action: \"env\", section: \"Config\", description: \"Environment variables\" },\n { action: \"domains\", section: \"Config\", description: \"Custom domains, their DNS records, and verification\" },\n { action: \"extensions\", section: \"Config\", description: \"The Postgres extension allowlist\" },\n { action: \"settings\", section: \"Config\", description: \"Name, subdomain, repository, branch\" },\n\n { action: \"orgs\", section: \"Organizations\", description: \"Organizations you belong to, and their members\" },\n\n { action: \"db\", section: \"Data\", description: \"Attach a database, back it up, restore, point-in-time recovery\" },\n { action: \"storage\", section: \"Data\", description: \"The project's object storage\" },\n\n { action: \"webhooks\", section: \"Other resources\", description: \"Outbound webhooks on a table's row changes\" },\n // Both of these dispatch and have a page, and both were absent from this\n // list — so the command that names what a project costs, and the one that\n // names what it declares, were undiscoverable from `rebase cloud --help`,\n // which is where an agent finds the family.\n { action: \"resources\", section: \"Other resources\", description: \"What the code declares against what the platform provisioned\" },\n { action: \"compute\", section: \"Other resources\", description: \"What this project reserves, what it costs, and how to change it\" },\n { action: \"clusters\", section: \"Other resources\", description: \"The clusters tenants run on. Platform-admin only\" },\n { action: \"billing\", section: \"Other resources\", description: \"The organization's billing account and card on file\" }\n];\n\n/** The dispatch words alone — what `--help` routing and the tests iterate. */\nexport const CLOUD_GROUP_NAMES = CLOUD_GROUPS.map(g => g.action);\n\nfunction printCloudHelp(): void {\n printGroupHelp({\n command: \"cloud\",\n title: \"Manage your apps on Rebase Cloud\",\n actions: CLOUD_GROUPS,\n notes: [\n \"Most commands act on the linked project (.rebase/cloud.json) unless --project is given.\",\n \"Every group answers `--help` with its own page: actions, arguments and flags.\",\n \"Docs: https://rebase.pro/docs\"\n ]\n });\n}\n","/**\n * CLI command: rebase apps\n *\n * Inspect the apps this repository contributes to a project, adopt a\n * `rebase.json` for a project that predates it, and print the client bootstrap\n * an app needs to reach its backend.\n *\n * The distinction that runs through all of this: a *repository* declares apps,\n * a *project* owns them. Two repositories can contribute to the same project and\n * never know about each other, which is what makes a separate frontend repo — or\n * a mobile app with no repo relationship at all — an ordinary thing rather than\n * a special case.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport chalk from \"chalk\";\nimport type { RebaseAppConfig } from \"@rebasepro/types\";\nimport { failAsJson, requireProjectRoot } from \"../utils/project\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport {\n assessManagedCompatibility,\n loadManifest,\n ManifestError,\n manifestExists,\n synthesizeManifest,\n writeManifest\n} from \"../manifest\";\nimport { readLink } from \"./cloud/context\";\nimport { unknownCommand } from \"../utils/unknown-command\";\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase apps\")} — the apps this repository contributes\n\n${chalk.bold(\"Usage\")}\n rebase apps list List declared apps and their build outputs\n rebase apps init Write a rebase.json inferred from this project\n rebase apps config <app> Print the client configuration for an app\n\n${chalk.bold(\"Options\")}\n --json Machine-readable output\n --force Overwrite an existing rebase.json (apps init)\n -h, --help Show this help\n`.trim());\n}\n\n/** Everything the switch below dispatches, for the did-you-mean. */\nexport const APPS_SUBCOMMANDS = [\"list\", \"init\", \"config\"] as const;\n\nexport async function appsCommand(subcommand: string | undefined, rawArgs: string[] = []): Promise<void> {\n // Help is answered before parsing, so `rebase apps config --help` prints the\n // page rather than being rejected for naming no app.\n if (!subcommand || subcommand === \"--help\" || wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n // Only `apps` is a command word here: this one parser serves every\n // subcommand, so the subcommand stays in the positionals and the app name\n // `apps config` takes follows it.\n const { flags: args, positionals } = parseCommandArgs({\n spec: {\n \"--json\": Boolean,\n \"--force\": Boolean\n },\n rawArgs,\n commandWords: 1,\n command: \"apps\",\n maxPositionals: 2\n });\n\n switch (subcommand) {\n case \"list\":\n await listApps(Boolean(args[\"--json\"]));\n break;\n case \"init\":\n await initManifest(Boolean(args[\"--force\"]));\n break;\n case \"config\":\n await printAppConfig(positionals[1], Boolean(args[\"--json\"]));\n break;\n default:\n unknownCommand(subcommand, APPS_SUBCOMMANDS, \"apps\");\n }\n}\n\nfunction describeApp(app: RebaseAppConfig): string {\n switch (app.type) {\n case \"backend\":\n return app.runtime === \"custom\"\n // The context is named only when it is not the project, which is\n // the case where it changes what you would type. A workspace app\n // builds from the workspace root, and a listing that showed only\n // the Dockerfile implied a `docker build .` beside it that fails.\n ? `custom runtime — ${app.dockerfile ?? \"Dockerfile\"}`\n + (app.context && app.context !== \".\" ? ` (context: ${app.context})` : \"\")\n : `managed runtime, config: ${app.config ?? \"config\"}`;\n case \"static\":\n return `${app.root} → ${app.output} @ ${app.path ?? \"/\"}`\n + (app.cms ? ` ${chalk.magenta(`CMS at ${app.cms}`)}` : \"\");\n default:\n return \"\";\n }\n}\n\nasync function listApps(asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n const compatibility = assessManagedCompatibility(loaded.manifest);\n\n if (asJson) {\n console.log(JSON.stringify(\n {\n source: loaded.source,\n rebase: loaded.manifest.rebase,\n apps: loaded.manifest.apps,\n managed: compatibility\n },\n null,\n 2\n ));\n return;\n }\n\n if (loaded.source === \"synthesized\") {\n console.log(chalk.dim(\"No rebase.json — showing the layout inferred from this project.\"));\n console.log(chalk.dim(`Run ${chalk.cyan(\"rebase apps init\")} to write it down.\\n`));\n }\n\n console.log(chalk.bold(`Rebase ${loaded.manifest.rebase}`));\n console.log(\"\");\n\n const entries = Object.entries(loaded.manifest.apps);\n if (entries.length === 0) {\n console.log(chalk.yellow(\"No apps declared.\"));\n return;\n }\n\n const width = Math.max(...entries.map(([name]) => name.length));\n for (const [name, app] of entries) {\n console.log(\n ` ${chalk.cyan(name.padEnd(width))} ${chalk.dim(app.type.padEnd(8))} ${describeApp(app)}`\n );\n }\n\n console.log(\"\");\n if (compatibility.eligible) {\n console.log(chalk.green(\"✓ Eligible for the managed runtime.\"));\n } else {\n console.log(chalk.yellow(\"• Uses the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\nasync function initManifest(force: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n\n if (manifestExists(projectRoot) && !force) {\n console.error(chalk.red(\"✗ rebase.json already exists.\"));\n console.error(chalk.dim(\" Pass --force to overwrite it.\"));\n process.exit(1);\n }\n\n const manifest = synthesizeManifest(projectRoot);\n const filePath = writeManifest(projectRoot, manifest);\n\n console.log(chalk.green(`✓ Wrote ${path.relative(projectRoot, filePath)}`));\n console.log(\"\");\n for (const [name, app] of Object.entries(manifest.apps)) {\n console.log(` ${chalk.cyan(name)} ${chalk.dim(`(${app.type})`)}`);\n }\n\n const compatibility = assessManagedCompatibility(manifest);\n if (!compatibility.eligible) {\n console.log(\"\");\n console.log(chalk.yellow(\"This project will use the custom runtime:\"));\n for (const reason of compatibility.reasons) {\n console.log(chalk.dim(` ${reason}`));\n }\n }\n}\n\n/**\n * Print what a client needs to reach this project.\n *\n * Never prints a secret. The API URL and an app's publishable identity are meant\n * to ship inside a client bundle; anything that is not safe there does not belong\n * in output that will inevitably be pasted into a `.env` that gets committed.\n */\nasync function printAppConfig(appName: string | undefined, asJson: boolean): Promise<void> {\n const projectRoot = requireProjectRoot();\n const loaded = loadManifestOrExit(projectRoot, asJson);\n\n if (!appName) {\n if (asJson) {\n failAsJson(\"Which app? Usage: rebase apps config <app>\", \"app_not_named\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(\"✗ Which app? Usage: rebase apps config <app>\"));\n process.exit(1);\n }\n\n const app = loaded.manifest.apps[appName];\n if (!app) {\n if (asJson) {\n failAsJson(`No app named \"${appName}\" in rebase.json.`, \"app_not_found\",\n `Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`);\n }\n console.error(chalk.red(`✗ No app named \"${appName}\" in rebase.json.`));\n console.error(chalk.dim(` Declared: ${Object.keys(loaded.manifest.apps).join(\", \") || \"(none)\"}`));\n process.exit(1);\n }\n\n const link = readLink(projectRoot);\n const apiUrl = resolveApiUrl(projectRoot, link);\n\n const config = {\n app: appName,\n type: app.type,\n apiUrl: apiUrl ?? null,\n project: link?.projectId ?? link?.slug ?? null\n };\n\n if (asJson) {\n console.log(JSON.stringify(config, null, 2));\n return;\n }\n\n if (!apiUrl) {\n console.log(chalk.yellow(\"This checkout is not linked to a project yet.\"));\n // `rebase cloud link`, not `rebase link`. There has never been a\n // top-level `link` command — `cli.ts` dispatches `cloud`, and the link\n // lives inside that family — so this hint named something that exits 1\n // on the very screen that exists to tell you what to run next.\n console.log(chalk.dim(` Run ${chalk.cyan(\"rebase cloud link\")} (cloud) or ${chalk.cyan(\"rebase cloud link <url>\")} (self-hosted).`));\n console.log(\"\");\n }\n\n console.log(chalk.bold(`# ${appName}`));\n console.log(\"\");\n console.log(`VITE_API_URL=${apiUrl ?? \"http://localhost:3001\"}`);\n console.log(\"\");\n console.log(chalk.dim(\"Then, in the app:\"));\n console.log(chalk.dim(\" const rebase = createRebaseClient({ baseUrl: import.meta.env.VITE_API_URL });\"));\n}\n\n/**\n * Work out the API base URL for this checkout.\n *\n * Prefers an explicit link, then the dev server's own record of where it bound.\n * The dev port is chosen dynamically, so a hardcoded default would be wrong on\n * any machine running more than one project.\n */\nfunction resolveApiUrl(projectRoot: string, link: ReturnType<typeof readLink>): string | undefined {\n if (link?.apiUrl) return link.apiUrl;\n\n const statePath = path.join(projectRoot, \".rebase\", \"state.json\");\n if (fs.existsSync(statePath)) {\n try {\n const state = JSON.parse(fs.readFileSync(statePath, \"utf8\")) as { baseUrl?: string };\n if (state.baseUrl) return state.baseUrl;\n } catch {\n // Stale or partially written state file: fall through.\n }\n }\n\n return undefined;\n}\n\nfunction loadManifestOrExit(projectRoot: string, asJson = false): ReturnType<typeof loadManifest> {\n try {\n return loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n // A caller that asked for JSON gets one on this exit too. It used\n // to get the human bullet list on stderr and an empty stdout —\n // `apps list --json` against the one manifest a caller most needs\n // to be told about.\n if (asJson) {\n failAsJson(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n console.error(chalk.red(`✗ ${err.message}`));\n for (const issue of err.issues) {\n console.error(chalk.red(` ${issue.path ? `${issue.path}: ` : \"\"}${issue.message}`));\n }\n process.exit(1);\n }\n throw err;\n }\n}\n","/**\n * Moving a project's `@rebasepro/*` pins to one release.\n *\n * Every `@rebasepro/*` package ships at one version, and a project declares them\n * in several `package.json` files — the root, `backend/`, `frontend/`,\n * `config/`, and whatever else the repository holds. Bumping them by hand means\n * finding every one, keeping each range's `^` or `~`, and noticing the override\n * that quietly wins over all of them. `rebase upgrade` is that job, done the same\n * way every time; the control plane runs it too, when it rebuilds a managed\n * project on a newer release.\n *\n * Everything here is pure file work, so it can be tested against a temporary\n * directory: which specs move, the rewrite itself, and what overrides say. The\n * command in `commands/upgrade.ts` adds the registry lookup, the install and the\n * printing.\n *\n * ## The rewrite is textual\n *\n * A `package.json` is authored. Parsing it and writing `JSON.stringify` back\n * reformats the file, reorders nothing but reindents everything, and drops a\n * trailing newline or a two-space indent somebody chose — a one-line version\n * bump that arrives as a whole-file diff. So the file is scanned for the exact\n * byte range of each value, only those bytes are replaced, and the result is\n * parsed again and compared against what was intended. A file whose rewrite\n * does not parse back to exactly the intended values is not written.\n */\nimport fs from \"fs\";\nimport path from \"path\";\nimport { isDeepStrictEqual } from \"util\";\nimport { getPMCommands } from \"./utils/package-manager\";\n\n/** The dependency blocks a pin is moved in. `peerDependencies` is not one. */\nexport const PIN_FIELDS = [\"dependencies\", \"devDependencies\", \"optionalDependencies\"] as const;\nexport type PinField = typeof PIN_FIELDS[number];\n\n/** Every framework package lives under this scope. */\nexport const FRAMEWORK_SCOPE = \"@rebasepro/\";\n\n/** The package whose published versions stand for the release as a whole. */\nexport const RELEASE_PACKAGE = \"@rebasepro/cli\";\n\n/** `MAJOR.MINOR.PATCH`, with an optional prerelease and build, and nothing else. */\nconst SEMVER =\n /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\n\n/** Whether `value` is one exact version — `0.21.0`, `0.21.1-canary.g8c5a265`. */\nexport function isExactVersion(value: string): boolean {\n return SEMVER.test(value);\n}\n\n/** An error that carries the `--json` envelope's code and a remedy. */\nexport class UpgradeError extends Error {\n constructor(message: string, readonly code: string, readonly hint?: string) {\n super(message);\n this.name = \"UpgradeError\";\n }\n}\n\n/* ─── which specs move ─────────────────────────────────────────────────────── */\n\nexport type SpecClass =\n /** A plain version, optionally `^` or `~`: moved, keeping the prefix. */\n | { kind: \"movable\"; prefix: \"\" | \"^\" | \"~\"; version: string }\n /** A path on this machine. As a pin it is left alone; as an override it wins over every pin. */\n | { kind: \"local\"; protocol: \"link:\" | \"file:\" | \"portal:\" }\n /** A pnpm `catalog:` reference: the version is in pnpm-workspace.yaml's catalog, and moves there. */\n | { kind: \"catalog\"; catalog: string }\n /** Anything else, with the reason it is left alone. */\n | { kind: \"other\"; reason: string };\n\n/**\n * What a dependency spec is, as far as moving it goes.\n *\n * Only a plain version is moved, because only a plain version has an obvious\n * answer: `^0.19.1` becomes `^0.21.0`. A `>=` floor, a `||` union or a partial\n * `^0.19` could each be rewritten several ways, and a tag or a workspace link\n * already means something other than \"this release\" — so each is reported with\n * its reason and left as written.\n */\nexport function classifySpec(spec: string): SpecClass {\n const movable = /^([\\^~]?)(.+)$/.exec(spec);\n if (movable && isExactVersion(movable[2])) {\n return { kind: \"movable\", prefix: movable[1] as \"\" | \"^\" | \"~\", version: movable[2] };\n }\n for (const protocol of [\"link:\", \"file:\", \"portal:\"] as const) {\n if (spec.startsWith(protocol)) return { kind: \"local\", protocol };\n }\n const catalog = /^catalog:(.*)$/.exec(spec.trim());\n if (catalog) return { kind: \"catalog\", catalog: catalog[1].trim() || \"default\" };\n return { kind: \"other\", reason: otherReason(spec) };\n}\n\n/** Why a spec that does not move is left alone, as the report says it. */\nfunction leftAloneReason(cls: Exclude<SpecClass, { kind: \"movable\" }>): string {\n if (cls.kind === \"local\") {\n return `a local ${cls.protocol} path, which points at a checkout on this machine rather than a release`;\n }\n if (cls.kind === \"catalog\") return \"a catalog: reference inside a catalog, which pnpm does not resolve\";\n return cls.reason;\n}\n\nfunction otherReason(spec: string): string {\n const trimmed = spec.trim();\n if (trimmed.startsWith(\"workspace:\")) return \"a workspace: link, resolved inside this repository rather than from the registry\";\n if (trimmed.startsWith(\"npm:\")) return \"an npm: alias; move the aliased version by hand\";\n if (/^(git\\+|git:|github:|gitlab:|bitbucket:|git@)/.test(trimmed) || /^https?:\\/\\//.test(trimmed)) {\n return \"a git or URL dependency, not a registry version\";\n }\n if (trimmed === \"\" || trimmed === \"*\" || /^[xX]$/.test(trimmed)) return \"a wildcard, which already takes whatever the registry has\";\n if (trimmed.includes(\"||\")) return \"a union of ranges, with no single version to move\";\n if (/^[<>=]/.test(trimmed) || /\\s-\\s/.test(trimmed)) return \"a comparator range, with no single version to move\";\n if (/^[\\^~]?v?\\d/.test(trimmed)) return \"not a plain MAJOR.MINOR.PATCH version\";\n return \"a dist-tag, not a version\";\n}\n\n/**\n * The `@rebasepro/*` package an override key targets, or null.\n *\n * pnpm and npm key an override by name, optionally narrowed: `@rebasepro/x@<1`,\n * `parent>@rebasepro/x`; yarn's `resolutions` by a path, `**\\/@rebasepro/x`. The\n * target is the last segment either way.\n */\nexport function overrideTarget(key: string): string | null {\n const match = /(?:^|[/>])(@rebasepro\\/[^/@>\\s]+)(?:@[^/>]*)?$/.exec(key);\n return match ? match[1] : null;\n}\n\n/* ─── finding the files ────────────────────────────────────────────────────── */\n\nexport interface ProjectFiles {\n /** Absolute paths, in a stable order. */\n packageJsons: string[];\n workspaceYamls: string[];\n}\n\n/**\n * Directories the walk never enters: installed packages, build output (`dist`,\n * `dist-bundle`, `dist-bundle-admin`, …) and anything hidden (`.git`,\n * `.rebase`, an editor's worktrees). None of them hold a manifest anybody\n * authored for this project, and `dist-bundle/package.json` in particular is a\n * generated copy that `rebase build` rewrites anyway.\n */\nfunction skipDirectory(name: string): boolean {\n return name === \"node_modules\" || name.startsWith(\"dist\") || name.startsWith(\".\");\n}\n\n/** Every `package.json` and `pnpm-workspace.yaml` under the project root. */\nexport function discoverProjectFiles(projectRoot: string): ProjectFiles {\n const found: ProjectFiles = { packageJsons: [], workspaceYamls: [] };\n const walk = (dir: string): void => {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n // `isDirectory()` is false for a symlink, so a linked workspace\n // package is not walked twice and a cycle cannot form.\n if (entry.isDirectory()) {\n if (!skipDirectory(entry.name)) walk(full);\n } else if (entry.isFile()) {\n if (entry.name === \"package.json\") found.packageJsons.push(full);\n else if (entry.name === \"pnpm-workspace.yaml\") found.workspaceYamls.push(full);\n }\n }\n };\n walk(projectRoot);\n return found;\n}\n\n/* ─── the result ───────────────────────────────────────────────────────────── */\n\n/** Where a catalog pin sits: `catalog`, or `catalogs.<name>` for a named one. */\nexport type CatalogField = \"catalog\" | `catalogs.${string}`;\n\nexport interface ChangedPin {\n /** Relative to the project root, POSIX separators. */\n file: string;\n name: string;\n field: PinField | CatalogField;\n from: string;\n to: string;\n}\n\nexport interface SkippedSpec {\n file: string;\n name: string;\n /** A dependency block, or the override block the entry sits in. */\n field: string;\n spec: string;\n reason: string;\n}\n\nexport type OverrideAction = \"bumped\" | \"kept-local\" | \"removed-local\";\n\nexport interface OverrideFinding {\n file: string;\n /** The override key as written — `@rebasepro/types`, or a narrowed one. */\n name: string;\n spec: string;\n action: OverrideAction;\n /** The new value, for a bumped override. */\n to?: string;\n}\n\nexport interface UnreadableFile {\n file: string;\n reason: string;\n}\n\nexport interface UpgradePlan {\n target: string;\n changed: ChangedPin[];\n skipped: SkippedSpec[];\n overrides: OverrideFinding[];\n unreadable: UnreadableFile[];\n /** The files whose content changes, with the new content. */\n writes: Array<{ file: string; absolute: string; content: string }>;\n /** Pins, overrides and catalog entries that were already on the target. */\n unchanged: number;\n}\n\n/**\n * The `catalog:` references a plan met, and the catalog entries it found.\n *\n * A reference names no version, so it is not a pin to move: the catalog entry\n * it resolves to is. But the catalog may not be anywhere this looked — a\n * project inside a larger workspace keeps it above the project root — and a\n * reference to an entry nobody moved must be reported, not passed over.\n */\ninterface CatalogLedger {\n refs: Array<{ file: string; name: string; field: string; spec: string; catalog: string; pkg: string }>;\n /** `catalogKey(catalog, package)` for every framework entry of every catalog read. */\n defined: Set<string>;\n}\n\nfunction catalogKey(catalog: string, pkg: string): string {\n return `${catalog}\\u0000${pkg}`;\n}\n\nexport interface PlanOptions {\n /** Remove `link:`/`file:` overrides of framework packages instead of reporting them. */\n dropLocalOverrides?: boolean;\n}\n\n/** Project-relative, POSIX. What every file path in the output looks like. */\nfunction relativeTo(projectRoot: string, absolute: string): string {\n return path.relative(projectRoot, absolute).split(path.sep).join(\"/\");\n}\n\n/**\n * Work out every change the upgrade makes, without writing anything.\n *\n * `--dry-run` prints this; a real run writes `writes` and nothing else.\n */\nexport function planUpgrade(projectRoot: string, target: string, options: PlanOptions = {}): UpgradePlan {\n if (!isExactVersion(target)) {\n throw new UpgradeError(`\"${target}\" is not an exact version.`, \"target_invalid\");\n }\n const plan: UpgradePlan = { target, changed: [], skipped: [], overrides: [], unreadable: [], writes: [], unchanged: 0 };\n const ledger: CatalogLedger = { refs: [], defined: new Set() };\n const files = discoverProjectFiles(projectRoot);\n\n for (const absolute of files.packageJsons) {\n const file = relativeTo(projectRoot, absolute);\n const original = fs.readFileSync(absolute, \"utf8\");\n const content = planPackageJson(file, original, target, options, plan, ledger);\n if (content !== null && content !== original) plan.writes.push({ file, absolute, content });\n }\n\n for (const absolute of files.workspaceYamls) {\n const file = relativeTo(projectRoot, absolute);\n const original = fs.readFileSync(absolute, \"utf8\");\n const content = planWorkspaceYaml(file, original, target, options, plan, ledger);\n if (content !== original) plan.writes.push({ file, absolute, content });\n }\n\n for (const ref of ledger.refs) {\n if (ledger.defined.has(catalogKey(ref.catalog, ref.pkg))) continue;\n plan.skipped.push({\n file: ref.file,\n name: ref.name,\n field: ref.field,\n spec: ref.spec,\n reason: `a pnpm catalog: reference, and no catalog under this project defines it — move the version where the \"${ref.catalog}\" catalog is declared`\n });\n }\n\n return plan;\n}\n\n/** Write what the plan changes. Nothing else on disk is touched. */\nexport function applyUpgradePlan(plan: UpgradePlan): void {\n for (const write of plan.writes) fs.writeFileSync(write.absolute, write.content, \"utf8\");\n}\n\n/* ─── package.json ─────────────────────────────────────────────────────────── */\n\n/** Override blocks in a `package.json`, as paths from the root object. */\nconst JSON_OVERRIDE_BLOCKS: ReadonlyArray<readonly string[]> = [[\"pnpm\", \"overrides\"], [\"overrides\"], [\"resolutions\"]];\n\nfunction planPackageJson(\n file: string,\n original: string,\n target: string,\n options: PlanOptions,\n plan: UpgradePlan,\n ledger: CatalogLedger\n): string | null {\n const bom = original.startsWith(\"\") ? \"\" : \"\";\n const text = original.slice(bom.length);\n\n let parsed: unknown;\n let tree: JsonNode;\n try {\n parsed = JSON.parse(text);\n tree = scanJson(text);\n } catch (err) {\n plan.unreadable.push({ file, reason: `not valid JSON: ${err instanceof Error ? err.message : String(err)}` });\n return null;\n }\n if (!isRecord(parsed) || tree.kind !== \"object\") {\n plan.unreadable.push({ file, reason: \"not a JSON object\" });\n return null;\n }\n\n const expected = structuredClone(parsed);\n const edits: TextEdit[] = [];\n /** Override members to remove, as [block path, key]. */\n const removals: Array<[readonly string[], string]> = [];\n\n for (const field of PIN_FIELDS) {\n const block = memberValue(tree, [field]);\n if (block?.kind !== \"object\") continue;\n for (const member of block.members) {\n if (!member.key.startsWith(FRAMEWORK_SCOPE)) continue;\n if (member.value.kind !== \"string\") {\n plan.skipped.push({ file, name: member.key, field, spec: text.slice(member.value.start, member.value.end), reason: \"not a string\" });\n continue;\n }\n const spec = member.value.value;\n const cls = classifySpec(spec);\n if (cls.kind === \"movable\") {\n const to = `${cls.prefix}${target}`;\n if (to === spec) {\n plan.unchanged++;\n continue;\n }\n edits.push({ start: member.value.start, end: member.value.end, replacement: JSON.stringify(to) });\n setPath(expected, [field, member.key], to);\n plan.changed.push({ file, name: member.key, field, from: spec, to });\n } else if (cls.kind === \"catalog\") {\n ledger.refs.push({ file, name: member.key, field, spec, catalog: cls.catalog, pkg: member.key });\n } else {\n plan.skipped.push({ file, name: member.key, field, spec, reason: leftAloneReason(cls) });\n }\n }\n }\n\n for (const blockPath of JSON_OVERRIDE_BLOCKS) {\n const block = memberValue(tree, blockPath);\n if (block?.kind !== \"object\") continue;\n const field = blockPath.join(\".\");\n for (const member of block.members) {\n if (!overrideTarget(member.key)) continue;\n if (member.value.kind !== \"string\") {\n plan.skipped.push({\n file,\n name: member.key,\n field,\n spec: text.slice(member.value.start, member.value.end),\n reason: \"a nested override, which has no single version to move; edit it by hand\"\n });\n continue;\n }\n const spec = member.value.value;\n const cls = classifySpec(spec);\n const pkg = overrideTarget(member.key);\n if (cls.kind === \"movable\") {\n const to = `${cls.prefix}${target}`;\n if (to === spec) {\n plan.unchanged++;\n continue;\n }\n edits.push({ start: member.value.start, end: member.value.end, replacement: JSON.stringify(to) });\n setPath(expected, [...blockPath, member.key], to);\n plan.overrides.push({ file, name: member.key, spec, action: \"bumped\", to });\n } else if (cls.kind === \"catalog\" && pkg) {\n ledger.refs.push({ file, name: member.key, field, spec, catalog: cls.catalog, pkg });\n } else if (cls.kind === \"local\") {\n if (options.dropLocalOverrides) {\n removals.push([blockPath, member.key]);\n deletePath(expected, [...blockPath, member.key]);\n plan.overrides.push({ file, name: member.key, spec, action: \"removed-local\" });\n } else {\n plan.overrides.push({ file, name: member.key, spec, action: \"kept-local\" });\n }\n } else {\n plan.skipped.push({ file, name: member.key, field, spec, reason: leftAloneReason(cls) });\n }\n }\n }\n\n if (edits.length === 0 && removals.length === 0) return original;\n\n let next = applyEdits(text, edits);\n for (const [blockPath, key] of removals) {\n next = removeJsonMember(next, blockPath, key);\n }\n // An override block that only held local links is removed with them, and\n // `pnpm` with it when nothing else was in it — an empty `{}` left behind is\n // a line of diff that says nothing.\n for (const blockPath of JSON_OVERRIDE_BLOCKS) {\n if (!removals.some(([removedFrom]) => removedFrom === blockPath)) continue;\n for (let depth = blockPath.length; depth > 0; depth--) {\n const containerPath = blockPath.slice(0, depth);\n const node = memberValue(scanJson(next), containerPath);\n if (node?.kind !== \"object\" || node.members.length > 0) break;\n next = removeJsonMember(next, containerPath.slice(0, -1), containerPath[containerPath.length - 1]);\n deletePath(expected, containerPath);\n }\n }\n\n // The rewrite is only kept if it says exactly what was meant — every value\n // that was supposed to change, and nothing else.\n let reparsed: unknown;\n try {\n reparsed = JSON.parse(next);\n } catch {\n reparsed = undefined;\n }\n if (!isDeepStrictEqual(reparsed, expected)) {\n throw new UpgradeError(\n `Could not rewrite ${file} without disturbing it; nothing was written.`,\n \"rewrite_failed\",\n \"Move its @rebasepro versions by hand, then run `rebase upgrade` again.\"\n );\n }\n return bom + next;\n}\n\n/* ─── a JSON scanner that keeps byte offsets ───────────────────────────────── */\n\ninterface JsonMember {\n key: string;\n keyStart: number;\n value: JsonNode;\n}\n\ntype JsonNode =\n | { kind: \"object\"; start: number; end: number; members: JsonMember[] }\n | { kind: \"array\"; start: number; end: number }\n | { kind: \"string\"; start: number; end: number; value: string }\n | { kind: \"scalar\"; start: number; end: number };\n\n/**\n * The structure of a JSON document, with where each value starts and ends.\n *\n * `JSON.parse` answers what a file says; this answers where it says it, which is\n * what a rewrite that leaves every other byte alone needs. Throws on anything\n * that is not JSON — callers have already parsed the same text, so that never\n * happens in practice.\n */\nfunction scanJson(text: string): JsonNode {\n let i = 0;\n const WHITESPACE = \" \\t\\n\\r\";\n const skipWhitespace = (): void => {\n while (i < text.length && WHITESPACE.includes(text[i])) i++;\n };\n const unexpected = (): never => {\n throw new Error(`unexpected ${i < text.length ? `\"${text[i]}\"` : \"end of input\"} at offset ${i}`);\n };\n const readString = (): { kind: \"string\"; start: number; end: number; value: string } => {\n const start = i;\n if (text[i] !== \"\\\"\") unexpected();\n i++;\n while (i < text.length && text[i] !== \"\\\"\") i += text[i] === \"\\\\\" ? 2 : 1;\n if (i >= text.length) unexpected();\n i++;\n return { kind: \"string\", start, end: i, value: JSON.parse(text.slice(start, i)) as string };\n };\n const readValue = (): JsonNode => {\n skipWhitespace();\n const start = i;\n if (text[i] === \"{\") {\n i++;\n const members: JsonMember[] = [];\n skipWhitespace();\n if (text[i] === \"}\") {\n i++;\n return { kind: \"object\", start, end: i, members };\n }\n for (;;) {\n skipWhitespace();\n const key = readString();\n skipWhitespace();\n if (text[i] !== \":\") unexpected();\n i++;\n members.push({ key: key.value, keyStart: key.start, value: readValue() });\n skipWhitespace();\n if (text[i] === \",\") {\n i++;\n continue;\n }\n if (text[i] === \"}\") {\n i++;\n return { kind: \"object\", start, end: i, members };\n }\n unexpected();\n }\n }\n if (text[i] === \"[\") {\n i++;\n skipWhitespace();\n if (text[i] === \"]\") {\n i++;\n return { kind: \"array\", start, end: i };\n }\n for (;;) {\n readValue();\n skipWhitespace();\n if (text[i] === \",\") {\n i++;\n continue;\n }\n if (text[i] === \"]\") {\n i++;\n return { kind: \"array\", start, end: i };\n }\n unexpected();\n }\n }\n if (text[i] === \"\\\"\") return readString();\n while (i < text.length && !\",:{}[]\\\"\".includes(text[i]) && !WHITESPACE.includes(text[i])) i++;\n if (i === start) unexpected();\n return { kind: \"scalar\", start, end: i };\n };\n const root = readValue();\n skipWhitespace();\n if (i !== text.length) unexpected();\n return root;\n}\n\n/** The value at a path of object keys, or undefined. The last duplicate wins, as in `JSON.parse`. */\nfunction memberValue(root: JsonNode, keys: readonly string[]): JsonNode | undefined {\n let node: JsonNode | undefined = root;\n for (const key of keys) {\n if (node?.kind !== \"object\") return undefined;\n const members: JsonMember[] = node.members.filter(m => m.key === key);\n node = members[members.length - 1]?.value;\n }\n return node;\n}\n\ninterface TextEdit {\n start: number;\n end: number;\n replacement: string;\n}\n\n/** Apply non-overlapping edits, last first so the earlier offsets stay valid. */\nfunction applyEdits(text: string, edits: TextEdit[]): string {\n let out = text;\n for (const edit of [...edits].sort((a, b) => b.start - a.start)) {\n out = out.slice(0, edit.start) + edit.replacement + out.slice(edit.end);\n }\n return out;\n}\n\n/**\n * Remove one member from the object at `objectPath`, taking its comma with it.\n *\n * Rescans rather than trusting offsets from before an earlier edit. A middle or\n * first member takes everything up to the next key, so the next member inherits\n * its indentation; the last takes the comma and whitespace after the previous\n * value, so the closing brace keeps its line; an only member leaves `{}`.\n */\nfunction removeJsonMember(text: string, objectPath: readonly string[], key: string): string {\n const container = memberValue(scanJson(text), objectPath);\n if (container?.kind !== \"object\") return text;\n const index = container.members.findIndex(m => m.key === key);\n if (index === -1) return text;\n const members = container.members;\n const member = members[index];\n if (members.length === 1) {\n return text.slice(0, container.start + 1) + text.slice(container.end - 1);\n }\n if (index < members.length - 1) {\n return text.slice(0, member.keyStart) + text.slice(members[index + 1].keyStart);\n }\n return text.slice(0, members[index - 1].value.end) + text.slice(member.value.end);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction setPath(root: Record<string, unknown>, keys: string[], value: unknown): void {\n let node: Record<string, unknown> = root;\n for (const key of keys.slice(0, -1)) {\n const next = node[key];\n if (!isRecord(next)) return;\n node = next;\n }\n node[keys[keys.length - 1]] = value;\n}\n\nfunction deletePath(root: Record<string, unknown>, keys: readonly string[]): void {\n let node: Record<string, unknown> = root;\n for (const key of keys.slice(0, -1)) {\n const next = node[key];\n if (!isRecord(next)) return;\n node = next;\n }\n delete node[keys[keys.length - 1]];\n}\n\n/* ─── pnpm-workspace.yaml ──────────────────────────────────────────────────── */\n\ninterface YamlOverride {\n /** Index into the file's lines. */\n line: number;\n key: string;\n value: string;\n /** Where the value's text sits within the line, quotes excluded. */\n valueStart: number;\n valueEnd: number;\n}\n\ninterface YamlOverridesBlock {\n /** The block's key line — `overrides:`, `catalog:`. */\n keyLine: number;\n /** The block's lines, `keyLine` excluded: indented, blank or comment-only. */\n lines: number[];\n entries: YamlOverride[];\n /** Lines in the block that are neither an entry, nor blank, nor a comment. */\n otherContent: number;\n}\n\n/** Lines, each without its `\\r`, and whether the file used them. */\nfunction splitLines(text: string): string[] {\n return text.split(\"\\n\").map(line => (line.endsWith(\"\\r\") ? line.slice(0, -1) : line));\n}\n\n/**\n * A YAML scalar at the start of `rest`: its text, and where that text sits.\n *\n * Double- and single-quoted and plain scalars, which is every shape an override\n * value is written in. A double-quoted one with an escape in it is refused\n * rather than decoded: no version or path needs one, and getting the decoding\n * wrong would rewrite a value this does not understand.\n */\nfunction readYamlScalar(rest: string): { value: string; start: number; end: number } | null {\n if (rest.startsWith(\"\\\"\")) {\n const close = rest.indexOf(\"\\\"\", 1);\n if (close === -1 || rest.slice(1, close).includes(\"\\\\\")) return null;\n if (!/^\\s*(#.*)?$/.test(rest.slice(close + 1))) return null;\n return { value: rest.slice(1, close), start: 1, end: close };\n }\n if (rest.startsWith(\"'\")) {\n const close = rest.indexOf(\"'\", 1);\n if (close === -1 || rest[close + 1] === \"'\") return null;\n if (!/^\\s*(#.*)?$/.test(rest.slice(close + 1))) return null;\n return { value: rest.slice(1, close), start: 1, end: close };\n }\n const comment = rest.search(/\\s#/);\n const plain = (comment === -1 ? rest : rest.slice(0, comment)).trimEnd();\n if (plain === \"\" || /^[[{&*!|>%@`]/.test(plain)) return null;\n return { value: plain, start: 0, end: plain.length };\n}\n\n/**\n * A top-level block mapping of a `pnpm-workspace.yaml` — `overrides:`,\n * `catalog:` — read line by line.\n *\n * Deliberately narrow. The file is YAML, and the CLI carries no YAML parser; the\n * shape pnpm documents and every project writes is a block mapping of one\n * scalar per line, which a line reader handles exactly. Anything else in the\n * block is counted rather than guessed at, and an inline `overrides: { … }` is\n * reported as not handled.\n */\nfunction readYamlBlock(lines: string[], key: \"overrides\" | \"catalog\"): YamlOverridesBlock | null {\n const keyLine = lines.findIndex(line => new RegExp(`^${key}:\\\\s*(#.*)?$`).test(line));\n if (keyLine === -1) return null;\n\n const block: YamlOverridesBlock = { keyLine, lines: [], entries: [], otherContent: 0 };\n for (let index = keyLine + 1; index < lines.length; index++) {\n const line = lines[index];\n if (line.trim() !== \"\" && !/^\\s/.test(line) && !line.startsWith(\"#\")) break;\n block.lines.push(index);\n if (line.trim() === \"\" || /^\\s*#/.test(line)) continue;\n\n const entry = readYamlEntry(line, index);\n if (entry) block.entries.push(entry);\n else block.otherContent++;\n }\n return block;\n}\n\n/** One `key: scalar` line of a block mapping, or null when it is anything else. */\nfunction readYamlEntry(line: string, index: number): YamlOverride | null {\n const entry = /^(\\s+)(\"[^\"]*\"|'[^']*'|[^\\s\"'#][^:#]*?)\\s*:(\\s+|$)/.exec(line);\n const valueOffset = entry ? entry[0].length : -1;\n const scalar = entry ? readYamlScalar(line.slice(valueOffset)) : null;\n if (!entry || !scalar) return null;\n const rawKey = entry[2];\n return {\n line: index,\n key: /^[\"']/.test(rawKey) ? rawKey.slice(1, -1) : rawKey,\n value: scalar.value,\n valueStart: valueOffset + scalar.start,\n valueEnd: valueOffset + scalar.end\n };\n}\n\n/** One pnpm catalog: `catalog:` is the one named \"default\". */\ninterface YamlCatalog {\n name: string;\n field: CatalogField;\n entries: YamlOverride[];\n}\n\n/**\n * Every catalog a `pnpm-workspace.yaml` declares: the top-level `catalog:`\n * block, and each named block under `catalogs:`.\n *\n * `catalogs:` is one level deeper — a header line per catalog, its entries\n * indented under it — and is read with the same one-scalar-per-line rule.\n */\nfunction readYamlCatalogs(lines: string[]): YamlCatalog[] {\n const catalogs: YamlCatalog[] = [];\n const single = readYamlBlock(lines, \"catalog\");\n if (single) catalogs.push({ name: \"default\", field: \"catalog\", entries: single.entries });\n\n const keyLine = lines.findIndex(line => /^catalogs:\\s*(#.*)?$/.test(line));\n if (keyLine === -1) return catalogs;\n\n let current: YamlCatalog | null = null;\n let headerIndent = -1;\n for (let index = keyLine + 1; index < lines.length; index++) {\n const line = lines[index];\n if (line.trim() !== \"\" && !/^\\s/.test(line) && !line.startsWith(\"#\")) break;\n if (line.trim() === \"\" || /^\\s*#/.test(line)) continue;\n\n const indent = line.length - line.trimStart().length;\n const header = /^\\s+(\"[^\"]*\"|'[^']*'|[^\\s\"'#][^:#]*?)\\s*:\\s*(#.*)?$/.exec(line);\n if (header && (headerIndent === -1 || indent === headerIndent)) {\n headerIndent = indent;\n const name = /^[\"']/.test(header[1]) ? header[1].slice(1, -1) : header[1];\n current = { name, field: `catalogs.${name}`, entries: [] };\n catalogs.push(current);\n continue;\n }\n if (!current || indent <= headerIndent) continue;\n const entry = readYamlEntry(line, index);\n if (entry) current.entries.push(entry);\n }\n return catalogs;\n}\n\n/** A `pnpm-workspace.yaml`, with its overrides and then its catalogs moved. */\nfunction planWorkspaceYaml(\n file: string,\n original: string,\n target: string,\n options: PlanOptions,\n plan: UpgradePlan,\n ledger: CatalogLedger\n): string {\n const overridden = planYamlOverrides(file, original, target, options, plan, ledger);\n return planYamlCatalogs(file, overridden, target, plan, ledger);\n}\n\n/**\n * Move the framework entries of every catalog. Entries are rewritten in place\n * — a catalog loses no line — and the result is read back and held to what was\n * meant, like every other rewrite here.\n */\nfunction planYamlCatalogs(\n file: string,\n original: string,\n target: string,\n plan: UpgradePlan,\n ledger: CatalogLedger\n): string {\n const lines = splitLines(original);\n const catalogs = readYamlCatalogs(lines);\n\n for (const key of [\"catalog\", \"catalogs\"]) {\n const inline = lines.find(line => new RegExp(`^${key}:\\\\s*[^\\\\s#]`).test(line));\n if (inline && inline.includes(FRAMEWORK_SCOPE)) {\n plan.skipped.push({\n file,\n name: key,\n field: key,\n spec: inline.slice(key.length + 1).trim(),\n reason: `an inline ${key} map, which this does not rewrite; write it as a block, or edit it by hand`\n });\n }\n }\n if (catalogs.length === 0) return original;\n\n const next = [...lines];\n const expected: Array<[string, string, string]> = [];\n for (const catalog of catalogs) {\n for (const entry of catalog.entries) {\n const meant: [string, string, string] = [catalog.field, entry.key, entry.value];\n expected.push(meant);\n if (!entry.key.startsWith(FRAMEWORK_SCOPE)) continue;\n ledger.defined.add(catalogKey(catalog.name, entry.key));\n\n const cls = classifySpec(entry.value);\n if (cls.kind !== \"movable\") {\n plan.skipped.push({ file, name: entry.key, field: catalog.field, spec: entry.value, reason: leftAloneReason(cls) });\n continue;\n }\n const to = `${cls.prefix}${target}`;\n if (to === entry.value) {\n plan.unchanged++;\n continue;\n }\n meant[2] = to;\n const line = next[entry.line];\n next[entry.line] = line.slice(0, entry.valueStart) + to + line.slice(entry.valueEnd);\n plan.changed.push({ file, name: entry.key, field: catalog.field, from: entry.value, to });\n }\n }\n\n const content = next.join(original.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\");\n const after = readYamlCatalogs(splitLines(content))\n .flatMap(catalog => catalog.entries.map(e => [catalog.field, e.key, e.value]));\n if (!isDeepStrictEqual(after, expected)) {\n throw new UpgradeError(\n `Could not rewrite ${file} without disturbing it; nothing was written.`,\n \"rewrite_failed\",\n \"Move its @rebasepro catalog entries by hand, then run `rebase upgrade` again.\"\n );\n }\n return content;\n}\n\nfunction planYamlOverrides(\n file: string,\n original: string,\n target: string,\n options: PlanOptions,\n plan: UpgradePlan,\n ledger: CatalogLedger\n): string {\n const lines = splitLines(original);\n const crlf = original.includes(\"\\r\\n\");\n const block = readYamlBlock(lines, \"overrides\");\n\n if (!block) {\n const inline = lines.find(line => /^overrides:\\s*[^\\s#]/.test(line));\n if (inline && inline.includes(FRAMEWORK_SCOPE)) {\n plan.skipped.push({\n file,\n name: \"overrides\",\n field: \"overrides\",\n spec: inline.slice(\"overrides:\".length).trim(),\n reason: \"an inline overrides map, which this does not rewrite; write it as a block, or edit it by hand\"\n });\n }\n return original;\n }\n\n const next = [...lines];\n const removed = new Set<number>();\n const expected = new Map<string, string>();\n\n for (const entry of block.entries) {\n if (!overrideTarget(entry.key)) {\n expected.set(entry.key, entry.value);\n continue;\n }\n const cls = classifySpec(entry.value);\n const pkg = overrideTarget(entry.key);\n if (cls.kind === \"movable\") {\n const to = `${cls.prefix}${target}`;\n expected.set(entry.key, to);\n if (to === entry.value) {\n plan.unchanged++;\n continue;\n }\n const line = lines[entry.line];\n next[entry.line] = line.slice(0, entry.valueStart) + to + line.slice(entry.valueEnd);\n plan.overrides.push({ file, name: entry.key, spec: entry.value, action: \"bumped\", to });\n } else if (cls.kind === \"catalog\" && pkg) {\n expected.set(entry.key, entry.value);\n ledger.refs.push({ file, name: entry.key, field: \"overrides\", spec: entry.value, catalog: cls.catalog, pkg });\n } else if (cls.kind === \"local\") {\n if (options.dropLocalOverrides) {\n removed.add(entry.line);\n plan.overrides.push({ file, name: entry.key, spec: entry.value, action: \"removed-local\" });\n } else {\n expected.set(entry.key, entry.value);\n plan.overrides.push({ file, name: entry.key, spec: entry.value, action: \"kept-local\" });\n }\n } else {\n expected.set(entry.key, entry.value);\n plan.skipped.push({ file, name: entry.key, field: \"overrides\", spec: entry.value, reason: leftAloneReason(cls) });\n }\n }\n\n // A block the removals emptied goes too, key line included: `overrides:`\n // with nothing under it is `overrides: null`, which pnpm reads as a value.\n const survivors = block.entries.filter(entry => !removed.has(entry.line)).length + block.otherContent;\n if (removed.size > 0 && survivors === 0) removed.add(block.keyLine);\n\n const kept = next.filter((_, index) => !removed.has(index));\n const content = kept.join(crlf ? \"\\r\\n\" : \"\\n\");\n\n // Read back with the same reader, and hold it to what was meant: the same\n // entries, in the same order, with only the intended values changed, and\n // every line outside the block untouched.\n const after = readYamlBlock(splitLines(content), \"overrides\");\n const afterEntries = after ? after.entries.map(e => [e.key, e.value]) : [];\n if (!isDeepStrictEqual(afterEntries, [...expected.entries()])) {\n throw new UpgradeError(\n `Could not rewrite ${file} without disturbing it; nothing was written.`,\n \"rewrite_failed\",\n \"Move its @rebasepro overrides by hand, then run `rebase upgrade` again.\"\n );\n }\n return content;\n}\n\n/* ─── the install ──────────────────────────────────────────────────────────── */\n\nexport type Installer = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\n/** Lockfiles, in the order they are looked for in each directory. */\nconst LOCKFILES: ReadonlyArray<[string, Installer]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"package-lock.json\", \"npm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"bun.lockb\", \"bun\"],\n [\"bun.lock\", \"bun\"]\n];\n\n/**\n * The package manager this project installs with, from what is on disk.\n *\n * A lockfile is the project's own statement, so it wins. The search starts at\n * the project root and walks up, because a project inside a workspace has its\n * lockfile at the workspace root; it stops at the repository's root, so a stray\n * lockfile in a home directory is never read as this project's choice. With no\n * lockfile anywhere, a `pnpm-workspace.yaml` still says pnpm; otherwise npm,\n * the one every Node install has.\n */\nexport function detectInstaller(projectRoot: string): Installer {\n let dir = path.resolve(projectRoot);\n let workspaceYaml = false;\n for (;;) {\n for (const [lockfile, installer] of LOCKFILES) {\n if (fs.existsSync(path.join(dir, lockfile))) return installer;\n }\n if (fs.existsSync(path.join(dir, \"pnpm-workspace.yaml\"))) workspaceYaml = true;\n const parent = path.dirname(dir);\n if (parent === dir || fs.existsSync(path.join(dir, \".git\"))) break;\n dir = parent;\n }\n return workspaceYaml ? \"pnpm\" : \"npm\";\n}\n\n/**\n * The install command for each package manager — pnpm's and npm's from the\n * helpers every other command uses, yarn's and bun's spelled the same way.\n */\nexport function installCommand(installer: Installer): [string, string[]] {\n const [bin, ...args] = installer === \"pnpm\" || installer === \"npm\"\n ? getPMCommands(installer).install\n : [installer, \"install\"];\n return [bin, args];\n}\n\n/* ─── the target ───────────────────────────────────────────────────────────── */\n\n/**\n * The exact version `--to` names.\n *\n * An exact version is used as written, with no network call: the control plane\n * passes one when it rebuilds a project, and that rebuild must not depend on a\n * registry lookup succeeding for anything but the install itself. Anything\n * else is a dist-tag, asked of the registry through `npmView` — which runs npm\n * in the project, so its `.npmrc` and the user's registry config apply.\n */\nexport async function resolveTarget(\n requested: string,\n npmView: (spec: string) => Promise<string>\n): Promise<string> {\n const trimmed = requested.trim();\n const bare = trimmed.replace(/^v(?=\\d)/, \"\");\n if (isExactVersion(bare)) return bare;\n\n if (!/^[A-Za-z][\\w.-]*$/.test(trimmed)) {\n throw new UpgradeError(\n `\"${requested}\" is neither an exact version nor a dist-tag.`,\n \"target_invalid\",\n \"Pass an exact version such as 0.21.0, or a dist-tag such as latest or canary.\"\n );\n }\n\n let answer: string;\n try {\n answer = (await npmView(`${RELEASE_PACKAGE}@${trimmed}`)).trim();\n } catch (err) {\n const detail = err instanceof Error ? firstLine(err.message) : String(err);\n throw new UpgradeError(\n `Could not resolve \"${trimmed}\" on the npm registry${detail ? `: ${detail}` : \".\"}`,\n \"target_unresolved\",\n \"Check the tag and your registry access, or pass an exact version with --to.\"\n );\n }\n if (!isExactVersion(answer)) {\n throw new UpgradeError(\n `The registry has no single version for ${RELEASE_PACKAGE}@${trimmed}` +\n `${answer ? ` (it answered \"${firstLine(answer)}\")` : \"\"}.`,\n \"target_unresolved\",\n \"Check the tag, or pass an exact version with --to.\"\n );\n }\n return answer;\n}\n\nfunction firstLine(text: string): string {\n return text.split(\"\\n\").map(line => line.trim()).filter(Boolean)[0] ?? \"\";\n}\n\n/**\n * Whether moving from `from` to `to` goes backwards, for the one-word note the\n * summary prints. Prerelease identifiers compare as SemVer orders them: a\n * release outranks its own prereleases.\n */\nexport function isDowngrade(from: string, to: string): boolean {\n const a = SEMVER.exec(from.replace(/^[\\^~]/, \"\"));\n const b = SEMVER.exec(to.replace(/^[\\^~]/, \"\"));\n if (!a || !b) return false;\n for (let i = 1; i <= 3; i++) {\n const diff = Number(a[i]) - Number(b[i]);\n if (diff !== 0) return diff > 0;\n }\n const preA = a[4];\n const preB = b[4];\n if (preA === preB) return false;\n if (preA === undefined) return true;\n if (preB === undefined) return false;\n const partsA = preA.split(\".\");\n const partsB = preB.split(\".\");\n for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {\n const x = partsA[i];\n const y = partsB[i];\n if (x === undefined) return false;\n if (y === undefined) return true;\n if (x === y) continue;\n const nx = /^\\d+$/.test(x) ? Number(x) : NaN;\n const ny = /^\\d+$/.test(y) ? Number(y) : NaN;\n if (!Number.isNaN(nx) && !Number.isNaN(ny)) return nx > ny;\n if (!Number.isNaN(nx)) return false;\n if (!Number.isNaN(ny)) return true;\n return x > y;\n }\n return false;\n}\n","/**\n * CLI command: rebase upgrade [--to <version|tag>]\n *\n * Moves every `@rebasepro/*` package the project pins to one release, then\n * installs. The file work — which specs move, the rewrite, what overrides say —\n * is `../upgrade.ts`; this adds the registry lookup for a tag, the install, and\n * the two ways of saying what happened.\n */\nimport chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport { parseCommandArgs, wantsHelp } from \"../utils/args\";\nimport { failAsJson, requireProjectRoot, type JsonFailureIssue } from \"../utils/project\";\nimport { loadManifest, ManifestError } from \"../manifest\";\nimport {\n applyUpgradePlan,\n detectInstaller,\n installCommand,\n isDowngrade,\n planUpgrade,\n resolveTarget,\n UpgradeError,\n type ChangedPin,\n type OverrideFinding,\n type SkippedSpec,\n type UnreadableFile,\n type UpgradePlan\n} from \"../upgrade\";\n\n/** Every flag `rebase upgrade` accepts. Its help page and the docs verifier read this. */\nexport const UPGRADE_FLAGS = {\n \"--to\": String,\n \"--drop-local-overrides\": Boolean,\n \"--no-install\": Boolean,\n \"--dry-run\": Boolean,\n \"--json\": Boolean\n} as const;\n\nfunction printHelp(): void {\n console.log(`\n${chalk.bold(\"rebase upgrade\")} — move every @rebasepro package this project pins to one release\n\n${chalk.bold(\"Usage\")}\n rebase upgrade [--to <version|tag>] [options]\n\n${chalk.bold(\"Options\")}\n --to <version|tag> The release: an exact version (0.21.0) or a dist-tag\n (latest, canary). Default: latest\n --drop-local-overrides Remove link: and file: overrides of @rebasepro packages,\n which win over every pin\n --no-install Rewrite the package.json files, but do not install\n --dry-run Print what would change, and write nothing\n --json One JSON document on stdout\n -h, --help Show this help\n\n${chalk.bold(\"What it changes\")}\n Every @rebasepro/* entry in dependencies, devDependencies and optionalDependencies,\n in every package.json under the project (node_modules, dist* and hidden\n directories excepted). ^ and ~ are kept. peerDependencies are left alone, and so\n are workspace:, link:, file:, git and tag specs, which are listed with the reason.\n Overrides in pnpm-workspace.yaml and package.json are bumped the same way, and so\n are the entries of pnpm-workspace.yaml's catalog: and catalogs: blocks, which is\n where a catalog: pin's version lives.\n\n${chalk.bold(\"Examples\")}\n rebase upgrade Move to the latest release and install\n rebase upgrade --to canary --dry-run See what the canary would change\n rebase upgrade --to 0.21.0 --no-install --json\n`.trim());\n}\n\n/** What the command reports, human or `--json`. */\nexport interface UpgradeResult {\n target: string;\n changed: ChangedPin[];\n skipped: SkippedSpec[];\n overrides: OverrideFinding[];\n unreadable: UnreadableFile[];\n installed: boolean;\n dryRun: boolean;\n}\n\n/**\n * The two things this command does outside the project's files: ask the\n * registry what a tag points at, and install. Injectable, so a test runs the\n * whole command without either.\n */\nexport interface UpgradeIo {\n npmView: (spec: string, cwd: string) => Promise<string>;\n /** `quietStdout`: route the installer's stdout to stderr, so `--json` keeps stdout to itself. */\n install: (command: [string, string[]], cwd: string, quietStdout: boolean) => Promise<void>;\n}\n\nconst defaultIo: UpgradeIo = {\n // Run in the project, so its `.npmrc` — a private registry, a scope\n // mapping — answers the question rather than whatever the CLI was run from.\n npmView: async (spec, cwd) => {\n try {\n return (await execa(\"npm\", [\"view\", spec, \"version\"], { cwd })).stdout;\n } catch (err) {\n throw new Error(npmFailure(err));\n }\n },\n install: async ([bin, args], cwd, quietStdout) => {\n await execa(bin, args, { cwd, stdio: quietStdout ? [\"ignore\", 2, \"inherit\"] : \"inherit\" });\n }\n};\n\n/**\n * The one line of a failed `npm view` worth printing.\n *\n * execa's own message is the command line that failed, which says nothing the\n * reader does not know. npm's stderr says why — `404 No match found for version\n * nosuchtag` — under an `npm error code E404` line that says less.\n */\nexport function npmFailure(err: unknown): string {\n const stderr = typeof err === \"object\" && err !== null && \"stderr\" in err && typeof err.stderr === \"string\"\n ? err.stderr\n : \"\";\n const reason = stderr\n .split(\"\\n\")\n .map(line => line.replace(/^npm (?:error|ERR!)\\s*/, \"\").trim())\n .find(line => line !== \"\" && !/^code\\s/.test(line) && !/^\\d{3}$/.test(line));\n return reason ?? (err instanceof Error ? err.message : String(err));\n}\n\nexport async function upgradeCommand(rawArgs: string[], io: UpgradeIo = defaultIo): Promise<void> {\n if (wantsHelp(rawArgs)) {\n printHelp();\n return;\n }\n\n const { flags } = parseCommandArgs({\n spec: UPGRADE_FLAGS,\n rawArgs,\n commandWords: 1,\n command: \"upgrade\",\n maxPositionals: 0\n });\n const json = flags[\"--json\"] === true;\n const dryRun = flags[\"--dry-run\"] === true;\n\n const projectRoot = requireProjectRoot();\n\n /** Every refusal, in whichever of the two languages was asked for. */\n const refuse = (message: string, code: string, hint?: string, issues?: JsonFailureIssue[]): never => {\n if (json) failAsJson(message, code, hint, issues);\n console.error(chalk.red(`✗ ${message}`));\n for (const issue of issues ?? []) console.error(` ${chalk.gray(issue.path ?? \"\")} ${issue.message}`);\n if (hint) console.error(chalk.gray(` ${hint}`));\n process.exit(1);\n };\n\n // A project whose rebase.json does not load cannot be built on any release,\n // so moving its pins would only move the failure. Said first, and in the\n // same envelope `rebase status` uses.\n try {\n loadManifest(projectRoot);\n } catch (err) {\n if (err instanceof ManifestError) {\n refuse(err.message, \"manifest_invalid\", \"Fix rebase.json, then run this again.\",\n err.issues.map(issue => ({ path: issue.path, message: issue.message })));\n }\n throw err;\n }\n\n let plan: UpgradePlan;\n try {\n const target = await resolveTarget(flags[\"--to\"] ?? \"latest\", spec => io.npmView(spec, projectRoot));\n plan = planUpgrade(projectRoot, target, { dropLocalOverrides: flags[\"--drop-local-overrides\"] === true });\n } catch (err) {\n if (err instanceof UpgradeError) refuse(err.message, err.code, err.hint);\n throw err;\n }\n\n if (!dryRun) applyUpgradePlan(plan);\n const wrote = !dryRun && plan.writes.length > 0;\n const install = wrote && flags[\"--no-install\"] !== true;\n const installer = detectInstaller(projectRoot);\n const [bin, args] = installCommand(installer);\n const installLine = [bin, ...args].join(\" \");\n\n if (!json) printSummary(plan, dryRun);\n\n let installed = false;\n if (install) {\n if (!json) console.log(chalk.gray(` Installing with ${installer}...\\n`));\n try {\n await io.install([bin, args], projectRoot, json);\n installed = true;\n } catch {\n refuse(\n `\\`${installLine}\\` failed.`,\n \"install_failed\",\n `The package.json edits were kept. Fix what the install reported and run \\`${installLine}\\` again, ` +\n \"or revert the edits with git.\"\n );\n }\n }\n\n const result: UpgradeResult = {\n target: plan.target,\n changed: plan.changed,\n skipped: plan.skipped,\n overrides: plan.overrides,\n unreadable: plan.unreadable,\n installed,\n dryRun\n };\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printOutcome(plan, { dryRun, wrote, installed, installLine });\n}\n\n/** Changes grouped by file, then what was left alone and why, then overrides. */\nfunction printSummary(plan: UpgradePlan, dryRun: boolean): void {\n console.log(\"\");\n console.log(`${chalk.bold(\"Rebase\")} — ${dryRun ? \"what upgrading\" : \"upgrading\"} @rebasepro packages to ${chalk.cyan(plan.target)}${dryRun ? \" would change\" : \"\"}`);\n\n const byFile = new Map<string, ChangedPin[]>();\n for (const pin of plan.changed) byFile.set(pin.file, [...(byFile.get(pin.file) ?? []), pin]);\n const nameWidth = Math.max(0, ...plan.changed.map(pin => pin.name.length));\n for (const [file, pins] of byFile) {\n console.log(\"\");\n console.log(` ${chalk.bold(file)}`);\n for (const pin of pins) {\n const field = pin.field === \"dependencies\" ? \"\" : chalk.gray(` ${pin.field}`);\n const older = isDowngrade(pin.from, pin.to) ? chalk.yellow(\" (older)\") : \"\";\n console.log(` ${pin.name.padEnd(nameWidth)} ${chalk.gray(pin.from)} → ${chalk.green(pin.to)}${field}${older}`);\n }\n }\n\n if (plan.skipped.length > 0) {\n console.log(\"\");\n console.log(` ${chalk.bold(\"Left alone\")}`);\n for (const skip of plan.skipped) {\n console.log(` ${skip.name} ${chalk.gray(skip.spec)} ${chalk.gray(`(${skip.file}, ${skip.field})`)}`);\n console.log(chalk.gray(` ${skip.reason}`));\n }\n }\n\n if (plan.overrides.length > 0) {\n console.log(\"\");\n console.log(` ${chalk.bold(\"Overrides\")}`);\n for (const override of plan.overrides) {\n const where = chalk.gray(`(${override.file})`);\n if (override.action === \"bumped\") {\n console.log(` ${override.name} ${chalk.gray(override.spec)} → ${chalk.green(override.to ?? \"\")} ${where}`);\n } else if (override.action === \"removed-local\") {\n console.log(` ${override.name} ${chalk.gray(override.spec)} ${where} ${chalk.green(dryRun ? \"would be removed\" : \"removed\")}`);\n } else {\n console.log(` ${chalk.yellow(\"⚠\")} ${override.name} → ${override.spec} ${where}`);\n console.log(chalk.yellow(\" local override — wins over every pin, the upgrade will not reach these packages\"));\n }\n }\n if (plan.overrides.some(o => o.action === \"kept-local\")) {\n console.log(chalk.gray(\" Run again with --drop-local-overrides to remove them.\"));\n }\n }\n\n if (plan.unreadable.length > 0) {\n console.log(\"\");\n console.log(` ${chalk.bold(\"Not read\")}`);\n for (const entry of plan.unreadable) {\n console.log(` ${entry.file} ${chalk.gray(entry.reason)}`);\n }\n }\n console.log(\"\");\n}\n\nfunction printOutcome(\n plan: UpgradePlan,\n outcome: { dryRun: boolean; wrote: boolean; installed: boolean; installLine: string }\n): void {\n const moved = plan.changed.length + plan.overrides.filter(o => o.action !== \"kept-local\").length;\n // What the project is not moved off by this command: every pin it left\n // alone, and every local override that wins over the pins it did move.\n const leftAlone = plan.skipped.length + plan.overrides.filter(o => o.action === \"kept-local\").length;\n const entries = (n: number): string => `${n} entr${n === 1 ? \"y\" : \"ies\"}`;\n\n // Nothing moved is only \"already on\" the target when nothing was left\n // alone either. A project whose every pin was skipped — a dist-tag, a\n // `workspace:` link, a catalog it could not find — is on whatever those\n // resolve to, and saying otherwise is the one sentence it must not print.\n if (moved === 0 && leftAlone > 0) {\n if (plan.unchanged > 0) {\n console.log(chalk.green(\n `✓ Every pin this can move is already on ${plan.target}; ${entries(leftAlone)} ${leftAlone === 1 ? \"was\" : \"were\"} left alone, above.`));\n } else if (outcome.dryRun) {\n console.log(chalk.yellow(\n ` Nothing to move to ${plan.target}: ${entries(leftAlone)} ${leftAlone === 1 ? \"is\" : \"are\"} left alone, above.`));\n } else {\n console.log(chalk.yellow(\n `⚠ Nothing moved to ${plan.target}: ${entries(leftAlone)} ${leftAlone === 1 ? \"was\" : \"were\"} left alone, above.`));\n }\n console.log(\"\");\n return;\n }\n\n if (outcome.dryRun) {\n console.log(chalk.gray(moved === 0\n ? ` Nothing to change: this project is already on ${plan.target}.`\n : \" Dry run — nothing was written. Run it without --dry-run to apply.\"));\n console.log(\"\");\n return;\n }\n\n if (!outcome.wrote) {\n console.log(chalk.green(`✓ This project is already on ${plan.target}.`));\n console.log(\"\");\n return;\n }\n\n const files = plan.writes.length;\n console.log(chalk.green(\n `✓ Moved ${moved} entr${moved === 1 ? \"y\" : \"ies\"} in ${files} file${files === 1 ? \"\" : \"s\"} to ${plan.target}` +\n `${outcome.installed ? \" and installed\" : \"\"}.`\n ));\n if (!outcome.installed) {\n console.log(chalk.gray(` Install with \\`${outcome.installLine}\\`, then run \\`rebase build\\`, then \\`rebase cloud deploy\\`.`));\n } else {\n console.log(chalk.gray(\" Run `rebase build`, then `rebase cloud deploy`.\"));\n }\n console.log(\"\");\n}\n","import chalk from \"chalk\";\nimport arg from \"arg\";\nimport { createRebaseApp } from \"./commands/init\";\nimport { generateSdkCommand } from \"./commands/generate_sdk\";\nimport { SCHEMA_SUBCOMMANDS, schemaCommand } from \"./commands/schema\";\nimport { DB_SUBCOMMANDS, dbCommand } from \"./commands/db\";\nimport { devCommand } from \"./commands/dev\";\nimport { buildCommand } from \"./commands/build\";\nimport { ejectCommand } from \"./commands/eject\";\nimport { startCommand } from \"./commands/start\";\nimport { AUTH_SUBCOMMANDS, authCommand } from \"./commands/auth\";\nimport { doctorCommand } from \"./commands/doctor\";\nimport { resourcesCommand } from \"./commands/resources\";\nimport { statusCommand } from \"./commands/status\";\nimport { normalizeImportsCommand } from \"./commands/normalize-imports\";\nimport { SKILLS_SUBCOMMANDS, skillsCommand } from \"./commands/skills\";\nimport { API_KEYS_SUBCOMMANDS, apiKeysCommand } from \"./commands/api-keys\";\nimport { TELEMETRY_SUBCOMMANDS, telemetryCommand } from \"./commands/telemetry\";\nimport { errorClass, isEnabled, recordEvent } from \"./telemetry\";\nimport { CLOUD_GROUP_NAMES, GROUP_ALIASES, cloudCommand } from \"./commands/cloud\";\nimport { APPS_SUBCOMMANDS, appsCommand } from \"./commands/apps\";\nimport { upgradeCommand } from \"./commands/upgrade\";\nimport { requireProjectRoot } from \"./utils/project\";\nimport { parseCommandArgs } from \"./utils/args\";\nimport { unknownCommand } from \"./utils/unknown-command\";\nimport { cliVersion } from \"./utils/version\";\nimport path from \"path\";\n\n/**\n * Silence dotenv's own banner, for this process and everything it spawns.\n *\n * dotenv 17 prints `injected env (13) from .env // tip: ◈ encrypted .env\n * [www.dotenvx.com]` on every `config()` — a third-party advertisement that\n * appeared in `rebase dev`, `rebase build` and, because `rebase start` loads\n * the same way, in production server logs. `DOTENV_CONFIG_QUIET` is dotenv's\n * documented switch (`lib/main.js` reads it before `options.quiet`), and\n * setting it in `process.env` also reaches the backend, Vite and Atlas child\n * processes, which inherit it. Errors are unaffected — `quiet` gates the\n * success banner only.\n *\n * Not forced: an explicit `DOTENV_CONFIG_QUIET=false` still turns it back on.\n */\nfunction silenceDotenvBanner(): void {\n if (process.env.DOTENV_CONFIG_QUIET === undefined) {\n process.env.DOTENV_CONFIG_QUIET = \"true\";\n }\n}\n\n/**\n * The flags that mean the same thing wherever they appear.\n *\n * `--debug` is in here even though this file does not act on it: it is\n * implemented one level up, in `bin/rebase.js`, which prints the stack of a\n * failed command instead of the one-line message. That is exactly why it went\n * missing from the help for as long as it did — the flag lived in the\n * launcher, the Options block lived here, and neither knew about the other.\n * Declaring it here puts both under one spec, which `cli.test.ts` holds\n * against the printed help.\n *\n * Exported for that test.\n */\nexport const ROOT_FLAGS = {\n \"--version\": Boolean,\n \"--help\": Boolean,\n \"--debug\": Boolean,\n \"-v\": \"--version\",\n \"-h\": \"--help\"\n} as const;\n\n/**\n * Every command the dispatch below answers and the help lists. Declared as a\n * literal under this name: `help-coverage.test.ts`, `printed-commands.test.ts`\n * and the docs verifier read it out of this file's source.\n */\nconst namespacedCommands = [\"init\", \"schema\", \"db\", \"dev\", \"build\", \"start\", \"auth\", \"doctor\", \"skills\", \"api-keys\", \"cloud\", \"apps\", \"eject\", \"generate-sdk\", \"telemetry\", \"resources\", \"status\", \"upgrade\"];\n\n/**\n * The subcommands each command group dispatches, from the lists those groups\n * dispatch on. A command absent from here takes no subcommand.\n */\nfunction knownSubcommands(command: string): readonly string[] {\n switch (command) {\n case \"schema\": return SCHEMA_SUBCOMMANDS;\n case \"db\": return DB_SUBCOMMANDS;\n case \"auth\": return AUTH_SUBCOMMANDS;\n case \"skills\": return SKILLS_SUBCOMMANDS;\n case \"api-keys\": return API_KEYS_SUBCOMMANDS;\n case \"apps\": return APPS_SUBCOMMANDS;\n case \"telemetry\": return TELEMETRY_SUBCOMMANDS;\n case \"cloud\": return CLOUD_GROUP_NAMES;\n default: return [];\n }\n}\n\n/**\n * The command and subcommand words as `cli.error` may send them: each one is a\n * word this CLI dispatches, `\"none\"` when nothing was typed, or `\"other\"`.\n *\n * The words come from what was typed, and what is typed after a command is\n * only sometimes a subcommand. `rebase init acme-payroll-internal`, `rebase\n * cloud --project acme-prod deploy` and `rebase db psuh` put a project name, a\n * slug and a typo in the subcommand's position — the consent screen promises\n * \"never project names\", and `sanitize` cannot tell one of those from a\n * subcommand because neither has a separator in it. So the words are held\n * against the vocabulary here, where it is known, and nothing else survives.\n *\n * Exported for `cli.test.ts`.\n */\nexport function telemetryCommandWords(\n command: string | undefined,\n subcommand: string | undefined\n): { command: string; subcommand: string } {\n if (!command) return { command: \"none\", subcommand: \"none\" };\n const dispatched = namespacedCommands.includes(command) || command === \"normalize-imports\" || command === \"__dev-db-daemon\";\n if (!dispatched) return { command: \"other\", subcommand: subcommand ? \"other\" : \"none\" };\n\n if (!subcommand) return { command, subcommand: \"none\" };\n if (subcommand === \"--help\") return { command, subcommand };\n const canonical = command === \"cloud\" ? GROUP_ALIASES[subcommand] ?? subcommand : subcommand;\n return { command, subcommand: knownSubcommands(command).includes(canonical) ? canonical : \"other\" };\n}\n\nexport async function entry(args: string[]) {\n silenceDotenvBanner();\n\n const parsedArgs = arg(\n { ...ROOT_FLAGS },\n {\n argv: args.slice(2),\n permissive: true\n }\n );\n\n if (parsedArgs[\"--version\"]) {\n console.log(cliVersion());\n return;\n }\n\n // `permissive: true` is load-bearing here — each command parses its own\n // flags, so this parser must pass anything it does not recognise through\n // rather than reject it. The cost is that `arg` puts those flags into `_`,\n // mixed in with the positionals: for `rebase cloud --json storage create`,\n // `_` is [\"cloud\", \"--json\", \"storage\", \"create\"] and the subcommand read as\n // \"--json\". Skip the flags when naming the command and its subcommand.\n //\n // This cannot be complete at this level: a flag that takes a value leaves\n // the value behind as a bare token, and which flags take values is a fact\n // only the individual command knows. So a command whose dispatch has to be\n // exact resolves its own positionals against its own spec — see\n // `positionals()` in commands/cloud/index.ts — and this is the coarse pass.\n const words = parsedArgs._.filter(a => !a.startsWith(\"-\"));\n const command = words[0];\n const subcommand = words[1];\n\n // Show global help only when no command given, or --help with no recognized command\n if (!command || (parsedArgs[\"--help\"] && !namespacedCommands.includes(command))) {\n printHelp();\n return;\n }\n\n // For a namespaced command, `--help` becomes the subcommand *only when the\n // user did not name one*. `rebase db --help` wants the db help; `rebase\n // cloud env --help` wants env's, and overwriting \"env\" with \"--help\" was\n // what made every `rebase cloud <group> --help` print the same index page —\n // the group never reached the dispatcher. Seven cloud modules declare their\n // own `\"--help\": Boolean` and none of it could run, so ~44 flags had no way\n // to be listed.\n //\n // A group still gets its `--help` in `rawArgs` either way, so a handler that\n // parses its own flags sees the request whichever branch this takes.\n const effectiveSubcommand = parsedArgs[\"--help\"] && !subcommand ? \"--help\" : subcommand;\n\n try {\n await dispatch(command, effectiveSubcommand, args, parsedArgs, namespacedCommands);\n } catch (error) {\n // What failed, never why. `cli.error` records the command that threw and\n // a classification of the error — never its message, and never anything\n // derived from one. The consent screen promises \"no project names,\n // paths, schemas, URLs or error messages\", and a failure is exactly\n // where those leak: a message is usually a path, a connection string or\n // a column name. Which command fails, and how often, is the signal\n // worth having and costs none of that.\n //\n // The classification is `errorClass`, not `error.constructor.name`.\n // Both are safe, but the constructor name is almost always the useless\n // half of the answer: Node reports a refused connection, a missing file\n // and a permission denial all as plain `Error` carrying a `code`, so\n // every ECONNREFUSED, ENOENT and EACCES arrived here as the word\n // \"Error\" and the one question this event exists to answer — what is\n // actually going wrong out there — had no answer in the data.\n // `errorClass` prefers the `code` and falls back to the name, and it\n // is already the classifier the payload contract is written around.\n //\n // `recordEvent` is fire-and-forget and swallows its own failures, but it\n // is awaited so a short-lived CLI does not exit before the request is\n // made. The error is re-thrown untouched — `bin/rebase.js` owns how a\n // failure is printed and what the exit code is.\n //\n // The command words go through `telemetryCommandWords`, never raw: a\n // word typed after a command is as often a project name or a typo as a\n // subcommand, and neither has a separator for `sanitize` to catch.\n await recordEvent(\"cli.error\", {\n ...telemetryCommandWords(command, effectiveSubcommand),\n error_type: errorClass(error),\n usage: Boolean(error && typeof error === \"object\" && (error as { isUsageError?: unknown }).isUsageError)\n }, { projectRoot: process.cwd() });\n throw error;\n }\n}\n\n/**\n * The dispatch, lifted out of {@link entry} so the whole of it sits inside one\n * `try`. Inlining the switch there would have put the `catch` around the flag\n * parsing too, which throws its own usage errors before a command is even named.\n */\nasync function dispatch(\n command: string | undefined,\n effectiveSubcommand: string | undefined,\n args: string[],\n parsedArgs: Record<string, unknown>,\n namespacedCommands: string[]\n): Promise<void> {\n switch (command) {\n // Hidden: the managed development database's own process, spawned by\n // `ensureManagedDatabase` re-invoking this CLI. Not in\n // `namespacedCommands` and not in the help, because it is never typed\n // by a person — it exists so the daemon resolves the same way from\n // `src` under tsx and from a bundled `dist`.\n case \"__dev-db-daemon\": {\n const { parseDaemonArgs, runDaemon } = await import(\"./dev-db/daemon-entry\");\n await runDaemon(parseDaemonArgs(args));\n // Deliberately no `break`-and-return: the daemon owns this process\n // from here and exits through its own signal handlers.\n return;\n }\n\n case \"init\":\n await createRebaseApp(args);\n break;\n\n case \"generate-sdk\": {\n // Strict, and parsed from the whole line rather than `slice(3)`.\n // Permissive parsing turned a typo into silence: `rebase\n // generate-sdk --ouput ./sdk` wrote the SDK to the default path and\n // said nothing, so the next build imported a stale one. And the\n // fixed slice meant `rebase --debug generate-sdk -o ./sdk` read\n // `generate-sdk` as the first token of the flag line, dropping the\n // flags entirely. `parseCommandArgs` fixes both: it consumes flags\n // wherever they appear and rejects the ones nobody declared.\n const { flags: sdkArgs, help: sdkHelp } = parseCommandArgs({\n spec: {\n \"--collections-dir\": String,\n \"--output\": String,\n // The alias `build`, `cloud env pull` and `db backup` carry.\n // Two names for one concept across one CLI is a thing you\n // have to remember rather than know.\n \"--out\": \"--output\",\n \"--from\": String,\n \"--token\": String,\n \"-c\": \"--collections-dir\",\n \"-o\": \"--output\"\n },\n rawArgs: args,\n commandWords: 1,\n command: \"generate-sdk\",\n maxPositionals: 0\n });\n // Defaults hang off the project root, not the cwd. `./config/\n // collections` relative to wherever you happen to be standing meant\n // `rebase generate-sdk` worked from the repository root and threw\n // \"Collections directory not found\" one directory down — from\n // `backend/`, from `frontend/`, from anywhere a developer actually\n // sits — while `rebase db push` and `rebase dev` worked from all of\n // them. An explicitly passed path still resolves against the cwd,\n // which is where the person typing it means it.\n const sdkRoot = sdkHelp ? process.cwd() : requireProjectRoot();\n await generateSdkCommand({\n collectionsDir: sdkArgs[\"--collections-dir\"] || path.join(sdkRoot, \"config/collections\"),\n output: sdkArgs[\"--output\"] || path.join(sdkRoot, \"generated/sdk\"),\n from: sdkArgs[\"--from\"],\n token: sdkArgs[\"--token\"],\n help: sdkHelp,\n cwd: process.cwd()\n });\n break;\n }\n\n case \"schema\":\n await schemaCommand(effectiveSubcommand, args);\n break;\n\n case \"db\":\n await dbCommand(effectiveSubcommand, args);\n break;\n\n case \"dev\":\n await devCommand(args);\n break;\n\n case \"normalize-imports\":\n await normalizeImportsCommand(args);\n break;\n case \"build\":\n await buildCommand(args);\n break;\n\n case \"start\":\n await startCommand(args);\n break;\n\n case \"upgrade\":\n await upgradeCommand(args);\n break;\n\n case \"apps\":\n await appsCommand(effectiveSubcommand, args);\n break;\n\n case \"eject\":\n await ejectCommand(args);\n break;\n\n case \"auth\":\n await authCommand(effectiveSubcommand, args);\n break;\n\n case \"status\":\n await statusCommand(args);\n break;\n case \"resources\":\n await resourcesCommand(args);\n break;\n case \"doctor\":\n await doctorCommand(args);\n break;\n\n case \"skills\":\n await skillsCommand(effectiveSubcommand, args);\n break;\n\n case \"api-keys\":\n await apiKeysCommand(effectiveSubcommand, args);\n break;\n\n case \"cloud\":\n await cloudCommand(effectiveSubcommand, args);\n break;\n\n case \"telemetry\":\n await telemetryCommand(args);\n break;\n\n default:\n // One line, with the correction, and no screen of help after it: the\n // sentence that says what happened must not scroll off the top of a\n // CI log. `namespacedCommands` is the dispatch itself, so the\n // suggestion can never name a command that is not there.\n //\n // A mistyped command must not look like success to a shell or CI.\n unknownCommand(command, namespacedCommands);\n }\n}\n\n/** The global help. Exported so its Options block can be held against {@link ROOT_FLAGS}. */\nexport function printHelp() {\n console.log(`\n${chalk.bold(\"Rebase CLI\")} — Developer tools for Rebase projects\n\n${chalk.green.bold(\"Usage\")}\n rebase ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"init\")} Create a new Rebase project\n ${chalk.blue.bold(\"dev\")} Start the development server\n ${chalk.blue.bold(\"build\")} Build the apps declared in rebase.json into a bundle\n ${chalk.blue.bold(\"normalize-imports\")} Complete compiled output's relative imports for Node ESM\n ${chalk.blue.bold(\"start\")} Start the backend server ${chalk.gray(\"(production)\")}\n ${chalk.blue.bold(\"upgrade\")} Move every @rebasepro package to one release, then install\n ${chalk.blue.bold(\"apps list\")} Show the apps this repository declares\n\n${chalk.green.bold(\"Schema\")}\n ${chalk.blue.bold(\"schema generate\")} Generate Drizzle schema from collections\n ${chalk.blue.bold(\"schema introspect\")} Introspect database → Rebase collections\n ${chalk.blue.bold(\"schema stale\")} Report generated schema files the collections have moved past\n ${chalk.blue.bold(\"schema\")} ${chalk.gray(\"--help\")} Show schema command help\n\n${chalk.green.bold(\"Database\")}\n ${chalk.blue.bold(\"db push\")} Apply schema directly to database ${chalk.gray(\"(dev)\")}\n ${chalk.blue.bold(\"db generate\")} Generate SQL migration files\n ${chalk.blue.bold(\"db migrate\")} Run pending migrations\n ${chalk.blue.bold(\"db pull\")} Copy another database into local development\n ${chalk.blue.bold(\"db branch\")} Create, list, switch and delete database branches\n ${chalk.blue.bold(\"db stop\")} Stop the managed development database ${chalk.gray(\"(data is kept)\")}\n ${chalk.blue.bold(\"db reset\")} Delete the managed development database and start over\n ${chalk.blue.bold(\"db\")} ${chalk.gray(\"--help\")} Backup, restore, and every flag\n\n${chalk.green.bold(\"SDK\")}\n ${chalk.blue.bold(\"generate-sdk\")} Generate a typed TypeScript SDK from collections\n\n${chalk.green.bold(\"Auth\")}\n ${chalk.blue.bold(\"auth reset-password\")} Reset a user's password\n ${chalk.blue.bold(\"auth\")} ${chalk.gray(\"--help\")} Show auth command help\n\n${chalk.green.bold(\"Diagnostics\")}\n ${chalk.blue.bold(\"status\")} Show every resource and whether its variables are set\n ${chalk.blue.bold(\"doctor\")} Detect schema drift between collections, schema, and DB\n ${chalk.blue.bold(\"resources\")} List the databases, buckets and topics this project declares\n\n${chalk.green.bold(\"Take ownership\")}\n ${chalk.blue.bold(\"eject\")} Own the server process and the image ${chalk.gray(\"(one-way)\")}\n\n${chalk.green.bold(\"AI Agent Skills\")}\n ${chalk.blue.bold(\"skills install\")} Install Rebase agent skills for your AI coding assistant\n\n${chalk.green.bold(\"API Keys\")}\n ${chalk.blue.bold(\"api-keys list\")} List all service API keys\n ${chalk.blue.bold(\"api-keys create\")} Create a new scoped API key\n ${chalk.blue.bold(\"api-keys revoke\")} Revoke an existing API key\n ${chalk.blue.bold(\"api-keys\")} ${chalk.gray(\"--help\")} Show API key command help\n\n${chalk.green.bold(\"Usage sharing\")}\n ${chalk.blue.bold(\"telemetry\")} Anonymous usage sharing (opt-in, off by default)\n\n${chalk.green.bold(\"Rebase Cloud\")}\n ${chalk.blue.bold(\"cloud login\")} Sign in to the hosted control plane\n ${chalk.blue.bold(\"cloud link\")} Link this directory to a cloud project\n ${chalk.blue.bold(\"cloud deploy\")} Deploy the linked project + stream logs\n ${chalk.blue.bold(\"cloud\")} ${chalk.gray(\"--help\")} Show all cloud commands\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--version, -v\")} Show version number\n ${chalk.blue(\"--help, -h\")} Show this help message\n ${chalk.blue(\"--debug\")} Print the stack trace when a command fails ${chalk.gray(\"(or REBASE_DEBUG=1)\")}\n\n${chalk.gray(\"Documentation: https://rebase.pro/docs\")}\n${telemetryNotice()}`);\n}\n\n/**\n * One line about usage sharing, in the global help.\n *\n * Every other tool that collects anything prints a first-run notice. Ours asks\n * at the end of `rebase init` — but someone who installs the CLI and never runs\n * `init`, or who joins a project someone else scaffolded, would otherwise never\n * learn the subsystem exists. This is the cheapest place to close that: the\n * help is what an unfamiliar user reads first.\n *\n * It states the current setting rather than a generic sentence, so it is also\n * the fastest answer to \"is this thing on?\".\n */\nfunction telemetryNotice(): string {\n const sharing = isEnabled();\n return chalk.gray(\n `Usage sharing: ${sharing ? \"on\" : \"off\"} — ${chalk.cyan(\"rebase telemetry\")} to inspect or change\\n`\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport arg from \"arg\";\nimport { errorClass, isEnabled, recordEvent } from \"./telemetry\";\nimport { requireProjectRoot } from \"./utils/project\";\nimport { parseCommandArgs } from \"./utils/args\";\nimport { unknownCommand } from \"./utils/unknown-command\";\nimport { cliVersion } from \"./utils/version\";\nimport path from \"path\";\n\n/**\n * Silence dotenv's own banner, for this process and everything it spawns.\n *\n * dotenv 17 prints `injected env (13) from .env // tip: ◈ encrypted .env\n * [www.dotenvx.com]` on every `config()` — a third-party advertisement that\n * appeared in `rebase dev`, `rebase build` and, because `rebase start` loads\n * the same way, in production server logs. `DOTENV_CONFIG_QUIET` is dotenv's\n * documented switch (`lib/main.js` reads it before `options.quiet`), and\n * setting it in `process.env` also reaches the backend, Vite and Atlas child\n * processes, which inherit it. Errors are unaffected — `quiet` gates the\n * success banner only.\n *\n * Not forced: an explicit `DOTENV_CONFIG_QUIET=false` still turns it back on.\n */\nfunction silenceDotenvBanner(): void {\n if (process.env.DOTENV_CONFIG_QUIET === undefined) {\n process.env.DOTENV_CONFIG_QUIET = \"true\";\n }\n}\n\n/**\n * The flags that mean the same thing wherever they appear.\n *\n * `--debug` is in here even though this file does not act on it: it is\n * implemented one level up, in `bin/rebase.js`, which prints the stack of a\n * failed command instead of the one-line message. That is exactly why it went\n * missing from the help for as long as it did — the flag lived in the\n * launcher, the Options block lived here, and neither knew about the other.\n * Declaring it here puts both under one spec, which `cli.test.ts` holds\n * against the printed help.\n *\n * Exported for that test.\n */\nexport const ROOT_FLAGS = {\n \"--version\": Boolean,\n \"--help\": Boolean,\n \"--debug\": Boolean,\n \"-v\": \"--version\",\n \"-h\": \"--help\"\n} as const;\n\n/**\n * Every command the dispatch below answers and the help lists. Declared as a\n * literal under this name: `help-coverage.test.ts`, `printed-commands.test.ts`\n * and the docs verifier read it out of this file's source.\n */\nconst namespacedCommands = [\"init\", \"schema\", \"db\", \"console\", \"dev\", \"build\", \"start\", \"auth\", \"doctor\", \"skills\", \"api-keys\", \"storage\", \"cloud\", \"apps\", \"eject\", \"generate-sdk\", \"telemetry\", \"resources\", \"status\", \"upgrade\", \"normalize-imports\"];\n\n/** The words a command group dispatches, and the other spellings it accepts for them. */\ninterface CommandVocabulary {\n subcommands: readonly string[];\n aliases: Readonly<Record<string, string>>;\n}\n\nconst NO_VOCABULARY: CommandVocabulary = { subcommands: [], aliases: {} };\n\n/**\n * The subcommands each command group dispatches, from the lists those groups\n * dispatch on. A command absent from here takes no subcommand.\n *\n * Read from the group's own module, which is loaded here rather than at\n * startup: every command module is imported when its command runs (see\n * {@link dispatch}), and this is only ever asked about the command being run,\n * whose module the dispatch is about to load anyway.\n */\nasync function commandVocabulary(command: string): Promise<CommandVocabulary> {\n switch (command) {\n case \"schema\": return { subcommands: (await import(\"./commands/schema\")).SCHEMA_SUBCOMMANDS, aliases: {} };\n case \"db\": return { subcommands: (await import(\"./commands/db\")).DB_SUBCOMMANDS, aliases: {} };\n case \"auth\": return { subcommands: (await import(\"./commands/auth\")).AUTH_SUBCOMMANDS, aliases: {} };\n case \"skills\": return { subcommands: (await import(\"./commands/skills\")).SKILLS_SUBCOMMANDS, aliases: {} };\n case \"api-keys\": return { subcommands: (await import(\"./commands/api-keys\")).API_KEYS_SUBCOMMANDS, aliases: {} };\n case \"storage\": return { subcommands: (await import(\"./commands/storage\")).STORAGE_SUBCOMMANDS, aliases: {} };\n case \"apps\": return { subcommands: (await import(\"./commands/apps\")).APPS_SUBCOMMANDS, aliases: {} };\n case \"telemetry\": return { subcommands: (await import(\"./commands/telemetry\")).TELEMETRY_SUBCOMMANDS, aliases: {} };\n case \"cloud\": {\n const cloud = await import(\"./commands/cloud\");\n return { subcommands: cloud.CLOUD_GROUP_NAMES, aliases: cloud.GROUP_ALIASES };\n }\n default: return NO_VOCABULARY;\n }\n}\n\n/**\n * The subcommand in the words after a command, read against the subcommands the\n * group dispatches.\n *\n * The first word that is not a flag is not always the subcommand: after a flag\n * that takes a value it is that value. `rebase db --collections ./c push` was\n * refused as an unknown db command `./c`, `rebase api-keys --name ci create` as\n * one called `ci`, and `rebase skills --agent claude install` as `claude` —\n * lines every one of those commands parses happily once it is reached.\n *\n * Which flags take a value is not known at this level, so the vocabulary decides\n * instead: a word the group dispatches is the subcommand; a word straight after\n * a flag (and not glued to it with `=`) may be that flag's value and is passed\n * over. When no word is a known subcommand, the first word is returned as\n * before, so a typo — `rebase db psuh`, `rebase db --dry-run psuh` — still\n * reaches the group and is refused by name. A command with no vocabulary keeps\n * the first word.\n *\n * Exported for its tests.\n */\nexport function resolveSubcommand(after: readonly string[], known: readonly string[]): string | undefined {\n const words = after.filter(token => !token.startsWith(\"-\"));\n if (known.length === 0) return words[0];\n for (let i = 0; i < after.length; i++) {\n const token = after[i];\n if (token.startsWith(\"-\")) continue;\n if (known.includes(token)) return token;\n const previous = after[i - 1];\n const mayBeAValue = previous !== undefined && previous.startsWith(\"-\") && !previous.includes(\"=\");\n if (!mayBeAValue) return token;\n }\n return words[0];\n}\n\n/**\n * The command and subcommand words as `cli.error` may send them: each one is a\n * word this CLI dispatches, `\"none\"` when nothing was typed, or `\"other\"`.\n *\n * The words come from what was typed, and what is typed after a command is\n * only sometimes a subcommand. `rebase init acme-payroll-internal`, `rebase\n * cloud --project acme-prod deploy` and `rebase db psuh` put a project name, a\n * slug and a typo in the subcommand's position — the consent screen promises\n * \"never project names\", and `sanitize` cannot tell one of those from a\n * subcommand because neither has a separator in it. So the words are held\n * against the vocabulary here, where it is known, and nothing else survives.\n *\n * Exported for `cli.test.ts`.\n */\nexport async function telemetryCommandWords(\n command: string | undefined,\n subcommand: string | undefined\n): Promise<{ command: string; subcommand: string }> {\n if (!command) return { command: \"none\", subcommand: \"none\" };\n const dispatched = namespacedCommands.includes(command) || command === \"__dev-db-daemon\";\n if (!dispatched) return { command: \"other\", subcommand: subcommand ? \"other\" : \"none\" };\n\n if (!subcommand) return { command, subcommand: \"none\" };\n if (subcommand === \"--help\") return { command, subcommand };\n const { subcommands, aliases } = await commandVocabulary(command);\n const canonical = aliases[subcommand] ?? subcommand;\n return { command, subcommand: subcommands.includes(canonical) ? canonical : \"other\" };\n}\n\nexport async function entry(args: string[]) {\n silenceDotenvBanner();\n\n const parsedArgs = arg(\n { ...ROOT_FLAGS },\n {\n argv: args.slice(2),\n permissive: true\n }\n );\n\n if (parsedArgs[\"--version\"]) {\n console.log(cliVersion());\n return;\n }\n\n // `permissive: true` is load-bearing here — each command parses its own\n // flags, so this parser must pass anything it does not recognise through\n // rather than reject it. The cost is that `arg` puts those flags into `_`,\n // mixed in with the positionals: for `rebase cloud --json storage create`,\n // `_` is [\"cloud\", \"--json\", \"storage\", \"create\"] and the subcommand read as\n // \"--json\". Skip the flags when naming the command and its subcommand.\n //\n // A flag that takes a value leaves the value behind as a bare token, and\n // which flags take values is a fact only the individual command knows — for\n // `db` and `schema`, only the database driver's own CLI. So the subcommand\n // is named against the group's vocabulary instead: see `resolveSubcommand`.\n // `cloud` resolves its own group and action against the family's flag\n // specs — `positionals()` in commands/cloud/index.ts.\n const commandAt = parsedArgs._.findIndex(a => !a.startsWith(\"-\"));\n const command = commandAt === -1 ? undefined : parsedArgs._[commandAt];\n const subcommand = command === undefined\n ? undefined\n : resolveSubcommand(parsedArgs._.slice(commandAt + 1), (await commandVocabulary(command)).subcommands);\n\n // Show global help only when no command given, or --help with no recognized command\n if (!command || (parsedArgs[\"--help\"] && !namespacedCommands.includes(command))) {\n printHelp();\n return;\n }\n\n // For a namespaced command, `--help` becomes the subcommand *only when the\n // user did not name one*. `rebase db --help` wants the db help; `rebase\n // cloud env --help` wants env's, and overwriting \"env\" with \"--help\" was\n // what made every `rebase cloud <group> --help` print the same index page —\n // the group never reached the dispatcher. Seven cloud modules declare their\n // own `\"--help\": Boolean` and none of it could run, so ~44 flags had no way\n // to be listed.\n //\n // A group still gets its `--help` in `rawArgs` either way, so a handler that\n // parses its own flags sees the request whichever branch this takes.\n const effectiveSubcommand = parsedArgs[\"--help\"] && !subcommand ? \"--help\" : subcommand;\n\n try {\n await dispatch(command, effectiveSubcommand, args, parsedArgs, namespacedCommands);\n } catch (error) {\n // What failed, never why. `cli.error` records the command that threw and\n // a classification of the error — never its message, and never anything\n // derived from one. The consent screen promises \"no project names,\n // paths, schemas, URLs or error messages\", and a failure is exactly\n // where those leak: a message is usually a path, a connection string or\n // a column name. Which command fails, and how often, is the signal\n // worth having and costs none of that.\n //\n // The classification is `errorClass`, not `error.constructor.name`.\n // Both are safe, but the constructor name is almost always the useless\n // half of the answer: Node reports a refused connection, a missing file\n // and a permission denial all as plain `Error` carrying a `code`, so\n // every ECONNREFUSED, ENOENT and EACCES arrived here as the word\n // \"Error\" and the one question this event exists to answer — what is\n // actually going wrong out there — had no answer in the data.\n // `errorClass` prefers the `code` and falls back to the name, and it\n // is already the classifier the payload contract is written around.\n //\n // `recordEvent` is fire-and-forget and swallows its own failures, but it\n // is awaited so a short-lived CLI does not exit before the request is\n // made. The error is re-thrown untouched — `bin/rebase.js` owns how a\n // failure is printed and what the exit code is.\n //\n // The command words go through `telemetryCommandWords`, never raw: a\n // word typed after a command is as often a project name or a typo as a\n // subcommand, and neither has a separator for `sanitize` to catch.\n await recordEvent(\"cli.error\", {\n ...(await telemetryCommandWords(command, effectiveSubcommand)),\n error_type: errorClass(error),\n usage: Boolean(error && typeof error === \"object\" && (error as { isUsageError?: unknown }).isUsageError)\n }, { projectRoot: process.cwd() });\n throw error;\n }\n}\n\n/**\n * The dispatch, lifted out of {@link entry} so the whole of it sits inside one\n * `try`. Inlining the switch there would have put the `catch` around the flag\n * parsing too, which throws its own usage errors before a command is even named.\n *\n * Each command's module is imported here, when its command runs. Imported at\n * the top of this file, every invocation (`rebase --version` and `--help`\n * included, and the CLI `rebase dev` re-runs for itself) loaded all of them:\n * inquirer, execa, the SDK client, the code generator and the server\n * packages, 231 modules and 125–144 ms before the first line of output.\n */\nasync function dispatch(\n command: string | undefined,\n effectiveSubcommand: string | undefined,\n args: string[],\n parsedArgs: Record<string, unknown>,\n namespacedCommands: string[]\n): Promise<void> {\n switch (command) {\n // Hidden: the managed development database's own process, spawned by\n // `ensureManagedDatabase` re-invoking this CLI. Not in\n // `namespacedCommands` and not in the help, because it is never typed\n // by a person — it exists so the daemon resolves the same way from\n // `src` under tsx and from a bundled `dist`.\n case \"__dev-db-daemon\": {\n const { parseDaemonArgs, runDaemon } = await import(\"./dev-db/daemon-entry\");\n await runDaemon(parseDaemonArgs(args));\n // Deliberately no `break`-and-return: the daemon owns this process\n // from here and exits through its own signal handlers.\n return;\n }\n\n case \"init\": {\n const { createRebaseApp } = await import(\"./commands/init\");\n await createRebaseApp(args);\n break;\n }\n\n case \"generate-sdk\": {\n // Strict, and parsed from the whole line rather than `slice(3)`.\n // Permissive parsing turned a typo into silence: `rebase\n // generate-sdk --ouput ./sdk` wrote the SDK to the default path and\n // said nothing, so the next build imported a stale one. And the\n // fixed slice meant `rebase --debug generate-sdk -o ./sdk` read\n // `generate-sdk` as the first token of the flag line, dropping the\n // flags entirely. `parseCommandArgs` fixes both: it consumes flags\n // wherever they appear and rejects the ones nobody declared.\n const { flags: sdkArgs, help: sdkHelp } = parseCommandArgs({\n spec: {\n // `--collections`, as every other command spells it; the\n // older name stays an alias.\n \"--collections\": String,\n \"--collections-dir\": \"--collections\",\n \"--output\": String,\n // The alias `build`, `cloud env pull` and `db backup` carry.\n // Two names for one concept across one CLI is a thing you\n // have to remember rather than know.\n \"--out\": \"--output\",\n \"--from\": String,\n \"--token\": String,\n \"--register\": Boolean,\n \"-c\": \"--collections\",\n \"-o\": \"--output\"\n },\n rawArgs: args,\n commandWords: 1,\n command: \"generate-sdk\",\n maxPositionals: 0\n });\n // Defaults hang off the project root, not the cwd. `./config/\n // collections` relative to wherever you happen to be standing meant\n // `rebase generate-sdk` worked from the repository root and threw\n // \"Collections directory not found\" one directory down — from\n // `backend/`, from `frontend/`, from anywhere a developer actually\n // sits — while `rebase db push` and `rebase dev` worked from all of\n // them. An explicitly passed path still resolves against the cwd,\n // which is where the person typing it means it.\n const sdkRoot = sdkHelp ? process.cwd() : requireProjectRoot();\n const { generateSdkCommand } = await import(\"./commands/generate_sdk\");\n await generateSdkCommand({\n collectionsDir: sdkArgs[\"--collections\"] || path.join(sdkRoot, \"config/collections\"),\n output: sdkArgs[\"--output\"] || path.join(sdkRoot, \"generated/sdk\"),\n from: sdkArgs[\"--from\"],\n token: sdkArgs[\"--token\"],\n register: sdkArgs[\"--register\"],\n projectRoot: sdkHelp ? undefined : sdkRoot,\n help: sdkHelp,\n cwd: process.cwd()\n });\n break;\n }\n\n case \"schema\": {\n const { schemaCommand } = await import(\"./commands/schema\");\n await schemaCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"db\": {\n const { dbCommand } = await import(\"./commands/db\");\n await dbCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"console\": {\n const { consoleCommand } = await import(\"./commands/console\");\n await consoleCommand(args);\n break;\n }\n\n case \"dev\": {\n const { devCommand } = await import(\"./commands/dev\");\n await devCommand(args);\n break;\n }\n\n case \"normalize-imports\": {\n const { normalizeImportsCommand } = await import(\"./commands/normalize-imports\");\n await normalizeImportsCommand(args);\n break;\n }\n case \"build\": {\n const { buildCommand } = await import(\"./commands/build\");\n await buildCommand(args);\n break;\n }\n\n case \"start\": {\n const { startCommand } = await import(\"./commands/start\");\n await startCommand(args);\n break;\n }\n\n case \"upgrade\": {\n const { upgradeCommand } = await import(\"./commands/upgrade\");\n await upgradeCommand(args);\n break;\n }\n\n case \"apps\": {\n const { appsCommand } = await import(\"./commands/apps\");\n await appsCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"eject\": {\n const { ejectCommand } = await import(\"./commands/eject\");\n await ejectCommand(args);\n break;\n }\n\n case \"auth\": {\n const { authCommand } = await import(\"./commands/auth\");\n await authCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"status\": {\n const { statusCommand } = await import(\"./commands/status\");\n await statusCommand(args);\n break;\n }\n case \"resources\": {\n const { resourcesCommand } = await import(\"./commands/resources\");\n await resourcesCommand(args);\n break;\n }\n case \"doctor\": {\n const { doctorCommand } = await import(\"./commands/doctor\");\n await doctorCommand(args);\n break;\n }\n\n case \"skills\": {\n const { skillsCommand } = await import(\"./commands/skills\");\n await skillsCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"api-keys\": {\n const { apiKeysCommand } = await import(\"./commands/api-keys\");\n await apiKeysCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"storage\": {\n const { storageCommand } = await import(\"./commands/storage\");\n await storageCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"cloud\": {\n const { cloudCommand } = await import(\"./commands/cloud\");\n await cloudCommand(effectiveSubcommand, args);\n break;\n }\n\n case \"telemetry\": {\n const { telemetryCommand } = await import(\"./commands/telemetry\");\n await telemetryCommand(args);\n break;\n }\n\n default:\n // One line, with the correction, and no screen of help after it: the\n // sentence that says what happened must not scroll off the top of a\n // CI log. `namespacedCommands` is the dispatch itself, so the\n // suggestion can never name a command that is not there.\n //\n // A mistyped command must not look like success to a shell or CI.\n unknownCommand(command, namespacedCommands);\n }\n}\n\n/** The global help. Exported so its Options block can be held against {@link ROOT_FLAGS}. */\nexport function printHelp() {\n console.log(`\n${chalk.bold(\"Rebase CLI\")} — Developer tools for Rebase projects\n\n${chalk.green.bold(\"Usage\")}\n rebase ${chalk.blue(\"<command>\")} [options]\n\n${chalk.green.bold(\"Commands\")}\n ${chalk.blue.bold(\"init\")} Create a new Rebase project\n ${chalk.blue.bold(\"dev\")} Start the development server\n ${chalk.blue.bold(\"build\")} Build the apps declared in rebase.json into a bundle\n ${chalk.blue.bold(\"normalize-imports\")} Complete compiled output's relative imports for Node ESM\n ${chalk.blue.bold(\"start\")} Run the built bundle, as a deployment does ${chalk.gray(\"(in the NODE_ENV you set)\")}\n ${chalk.blue.bold(\"upgrade\")} Move every @rebasepro package to one release, then install\n ${chalk.blue.bold(\"apps list\")} Show the apps this repository declares\n\n${chalk.green.bold(\"Schema\")}\n ${chalk.blue.bold(\"schema generate\")} Generate Drizzle schema from collections\n ${chalk.blue.bold(\"schema introspect\")} Introspect database → Rebase collections\n ${chalk.blue.bold(\"schema stale\")} Report generated schema files the collections have moved past\n ${chalk.blue.bold(\"schema\")} ${chalk.gray(\"--help\")} Show schema command help\n\n${chalk.green.bold(\"Database\")}\n ${chalk.blue.bold(\"db push\")} Apply schema directly to database ${chalk.gray(\"(dev)\")}\n ${chalk.blue.bold(\"db generate\")} Generate SQL migration files\n ${chalk.blue.bold(\"db migrate\")} Run pending migrations\n ${chalk.blue.bold(\"db pull\")} Copy another database into local development\n ${chalk.blue.bold(\"db branch\")} Create, list, switch and delete database branches\n ${chalk.blue.bold(\"db stop\")} Stop the managed development database ${chalk.gray(\"(data is kept)\")}\n ${chalk.blue.bold(\"db reset\")} Delete the managed development database and start over\n ${chalk.blue.bold(\"db\")} ${chalk.gray(\"--help\")} Backup, restore, and every flag\n\n${chalk.green.bold(\"Explore\")}\n ${chalk.blue.bold(\"console\")} A REPL with the project's data in scope ${chalk.gray(\"(-e <code> runs one snippet)\")}\n\n${chalk.green.bold(\"SDK\")}\n ${chalk.blue.bold(\"generate-sdk\")} Generate a typed TypeScript SDK from collections\n\n${chalk.green.bold(\"Auth\")}\n ${chalk.blue.bold(\"auth reset-password\")} Reset a user's password\n ${chalk.blue.bold(\"auth\")} ${chalk.gray(\"--help\")} Show auth command help\n\n${chalk.green.bold(\"Diagnostics\")}\n ${chalk.blue.bold(\"status\")} Show every resource and whether its variables are set\n ${chalk.blue.bold(\"doctor\")} Detect schema drift between collections, schema, and DB\n ${chalk.blue.bold(\"resources\")} List the databases, buckets and topics this project declares\n\n${chalk.green.bold(\"Take ownership\")}\n ${chalk.blue.bold(\"eject\")} Own the server process and the image ${chalk.gray(\"(one-way)\")}\n\n${chalk.green.bold(\"AI Agent Skills\")}\n ${chalk.blue.bold(\"skills install\")} Install Rebase agent skills for your AI coding assistant\n\n${chalk.green.bold(\"API Keys\")}\n ${chalk.blue.bold(\"api-keys list\")} List the service API keys: kind, scopes, roles\n ${chalk.blue.bold(\"api-keys get\")} ${chalk.gray(\"<id>\")} Show one key\n ${chalk.blue.bold(\"api-keys create\")} Create a service key holding the scopes you name\n ${chalk.blue.bold(\"api-keys revoke\")} Revoke an API key\n ${chalk.blue.bold(\"api-keys scopes\")} List the scopes a key can hold\n ${chalk.blue.bold(\"api-keys\")} ${chalk.gray(\"--help\")} Show API key command help\n\n${chalk.green.bold(\"Stored files\")}\n ${chalk.blue.bold(\"storage orphans\")} List the stored files no row names ${chalk.gray(\"(--delete to delete)\")}\n ${chalk.blue.bold(\"storage move\")} Copy a folder of files to another storage source\n\n${chalk.green.bold(\"Usage sharing\")}\n ${chalk.blue.bold(\"telemetry\")} Anonymous usage sharing (opt-in, off by default)\n\n${chalk.green.bold(\"Rebase Cloud\")}\n ${chalk.blue.bold(\"cloud login\")} Sign in to the hosted control plane\n ${chalk.blue.bold(\"cloud link\")} Link this directory to a cloud project\n ${chalk.blue.bold(\"cloud deploy\")} Deploy the linked project + stream logs\n ${chalk.blue.bold(\"cloud tokens create\")} A token for CI and agents ${chalk.gray(\"(used as REBASE_TOKEN)\")}\n ${chalk.blue.bold(\"cloud\")} ${chalk.gray(\"--help\")} Show all cloud commands\n\n${chalk.green.bold(\"Options\")}\n ${chalk.blue(\"--version, -v\")} Show version number\n ${chalk.blue(\"--help, -h\")} Show this help message\n ${chalk.blue(\"--debug\")} Print the stack trace when a command fails ${chalk.gray(\"(or REBASE_DEBUG=1)\")}\n\n${chalk.gray(\"Documentation: https://rebase.pro/docs\")}\n${telemetryNotice()}`);\n}\n\n/**\n * One line about usage sharing, in the global help.\n *\n * Every other tool that collects anything prints a first-run notice. Ours asks\n * at the end of `rebase init` — but someone who installs the CLI and never runs\n * `init`, or who joins a project someone else scaffolded, would otherwise never\n * learn the subsystem exists. This is the cheapest place to close that: the\n * help is what an unfamiliar user reads first.\n *\n * It states the current setting rather than a generic sentence, so it is also\n * the fastest answer to \"is this thing on?\".\n */\nfunction telemetryNotice(): string {\n const sharing = isEnabled();\n return chalk.gray(\n `Usage sharing: ${sharing ? \"on\" : \"off\"} — ${chalk.cyan(\"rebase telemetry\")} to inspect or change\\n`\n );\n}\n"],"mappings":"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"}
|