@rebasepro/cli 0.25.0 → 0.26.0

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.
Files changed (190) hide show
  1. package/README.md +2 -1
  2. package/bin/rebase.js +143 -4
  3. package/dist/{agent-setup-B5AKHOgt.js → agent-setup-D9mHRZ5R.js} +125 -3
  4. package/dist/agent-setup-D9mHRZ5R.js.map +1 -0
  5. package/dist/{api-keys-Tm7zvAPe.js → api-keys-CyJ26KEJ.js} +41 -10
  6. package/dist/api-keys-CyJ26KEJ.js.map +1 -0
  7. package/dist/{apps-BsU_ILbP.js → apps-CnLDV5b6.js} +6 -7
  8. package/dist/{apps-BsU_ILbP.js.map → apps-CnLDV5b6.js.map} +1 -1
  9. package/dist/{atlas-dev-database-OWtqnG7W.js → atlas-dev-database-BODqdCWt.js} +4 -4
  10. package/dist/{atlas-dev-database-OWtqnG7W.js.map → atlas-dev-database-BODqdCWt.js.map} +1 -1
  11. package/dist/{auth-Vl2hFKXP.js → auth-dII2jCO1.js} +10 -8
  12. package/dist/auth-dII2jCO1.js.map +1 -0
  13. package/dist/{branch-pointer-9DnwkFJJ.js → branch-pointer-BQUF6lYa.js} +1 -1
  14. package/dist/{build-BBgT8EJZ.js → build-Cza7ZQrp.js} +6 -7
  15. package/dist/{build-BBgT8EJZ.js.map → build-Cza7ZQrp.js.map} +1 -1
  16. package/dist/{bundle-DtCCCr4w.js → bundle-C6yEtMJ-.js} +53 -5
  17. package/dist/bundle-C6yEtMJ-.js.map +1 -0
  18. package/dist/bundle.d.ts +14 -0
  19. package/dist/{cloud-BpH0_bmV.js → cloud-BdnmqQaZ.js} +8528 -4342
  20. package/dist/cloud-BdnmqQaZ.js.map +1 -0
  21. package/dist/collections-dir-DlvDhime.js +69 -0
  22. package/dist/collections-dir-DlvDhime.js.map +1 -0
  23. package/dist/commands/agent-setup.d.ts +58 -0
  24. package/dist/commands/api-keys.d.ts +13 -0
  25. package/dist/commands/cloud/activity.d.ts +25 -0
  26. package/dist/commands/cloud/app-key.d.ts +18 -0
  27. package/dist/commands/cloud/auth.d.ts +1 -0
  28. package/dist/commands/cloud/billing-invoices.d.ts +39 -0
  29. package/dist/commands/cloud/claim.d.ts +7 -0
  30. package/dist/commands/cloud/context.d.ts +115 -6
  31. package/dist/commands/cloud/deploy-summary.d.ts +162 -0
  32. package/dist/commands/cloud/deploy.d.ts +64 -0
  33. package/dist/commands/cloud/env.d.ts +24 -0
  34. package/dist/commands/cloud/index.d.ts +13 -1
  35. package/dist/commands/cloud/init.d.ts +143 -0
  36. package/dist/commands/cloud/login-flow.d.ts +51 -0
  37. package/dist/commands/cloud/notifications.d.ts +28 -0
  38. package/dist/commands/cloud/orgs.d.ts +13 -0
  39. package/dist/commands/cloud/previews.d.ts +123 -0
  40. package/dist/commands/cloud/resources.d.ts +68 -14
  41. package/dist/commands/cloud/runtime-logs.d.ts +176 -0
  42. package/dist/commands/cloud/service-key.d.ts +15 -0
  43. package/dist/commands/cloud/token-capabilities.d.ts +61 -8
  44. package/dist/commands/cloud/tokens.d.ts +18 -3
  45. package/dist/commands/cloud/usage.d.ts +63 -0
  46. package/dist/commands/dev.d.ts +22 -0
  47. package/dist/commands/doctor.d.ts +1 -1
  48. package/dist/commands/generate-view.d.ts +94 -0
  49. package/dist/commands/generate_sdk.d.ts +19 -2
  50. package/dist/commands/init.d.ts +20 -0
  51. package/dist/commands/skills.d.ts +4 -3
  52. package/dist/commands/start.d.ts +10 -0
  53. package/dist/commands/storage.d.ts +4 -0
  54. package/dist/commands/upgrade.d.ts +12 -0
  55. package/dist/commands/verify.d.ts +96 -0
  56. package/dist/{consent-ClRHmcxf.js → consent-BD7F29T3.js} +2 -2
  57. package/dist/{consent-ClRHmcxf.js.map → consent-BD7F29T3.js.map} +1 -1
  58. package/dist/{console-CEGm0XNc.js → console-BXB6-8GT.js} +12 -6
  59. package/dist/console-BXB6-8GT.js.map +1 -0
  60. package/dist/{context-CyflUrKg.js → context-GUxkZm-S.js} +482 -26
  61. package/dist/context-GUxkZm-S.js.map +1 -0
  62. package/dist/{daemon-CknkDjd6.js → daemon-Cp7oNXth.js} +160 -5
  63. package/dist/daemon-Cp7oNXth.js.map +1 -0
  64. package/dist/{daemon-entry-CbLRrgzy.js → daemon-entry-zOC1revO.js} +6 -3
  65. package/dist/daemon-entry-zOC1revO.js.map +1 -0
  66. package/dist/{db-CRNpA5mH.js → db-KzlqddGD.js} +101 -54
  67. package/dist/db-KzlqddGD.js.map +1 -0
  68. package/dist/{derive-CsoFGAnK.js → derive-ae9UOoOB.js} +2 -2
  69. package/dist/{derive-CsoFGAnK.js.map → derive-ae9UOoOB.js.map} +1 -1
  70. package/dist/{dev-C0pbMmhS.js → dev-DTqVMgB3.js} +231 -44
  71. package/dist/dev-DTqVMgB3.js.map +1 -0
  72. package/dist/dev-db/daemon.d.ts +41 -0
  73. package/dist/dev-db/pull.d.ts +33 -5
  74. package/dist/dev-db/state.d.ts +9 -0
  75. package/dist/{dev-preflight-unHpiYO1.js → dev-preflight-Cxv3TiD1.js} +73 -27
  76. package/dist/dev-preflight-Cxv3TiD1.js.map +1 -0
  77. package/dist/{dev-server-B1UYifZJ.js → dev-server-OJsUGZEB.js} +14 -3
  78. package/dist/dev-server-OJsUGZEB.js.map +1 -0
  79. package/dist/{doctor-CATRdWm6.js → doctor-BRWOlqeG.js} +14 -12
  80. package/dist/doctor-BRWOlqeG.js.map +1 -0
  81. package/dist/{eject-DuasTr-F.js → eject-DABcDnPN.js} +3 -4
  82. package/dist/{eject-DuasTr-F.js.map → eject-DABcDnPN.js.map} +1 -1
  83. package/dist/{fold-static-hDHtDfTq.js → fold-static-BnAK-anQ.js} +3 -3
  84. package/dist/{fold-static-hDHtDfTq.js.map → fold-static-BnAK-anQ.js.map} +1 -1
  85. package/dist/generate-view-IFwCADvb.js +662 -0
  86. package/dist/generate-view-IFwCADvb.js.map +1 -0
  87. package/dist/{generate_sdk-Cvg5jjJF.js → generate_sdk-BvcWvoUh.js} +49 -13
  88. package/dist/generate_sdk-BvcWvoUh.js.map +1 -0
  89. package/dist/index.es.js +58 -40
  90. package/dist/index.es.js.map +1 -1
  91. package/dist/{init-BWAwHPtz.js → init-CaU6GhwI.js} +50 -62
  92. package/dist/init-CaU6GhwI.js.map +1 -0
  93. package/dist/invoked-command-CG_rIa_o.js +55 -0
  94. package/dist/invoked-command-CG_rIa_o.js.map +1 -0
  95. package/dist/last-dev-database-DpW5dfoX.js +2 -0
  96. package/dist/{manifest-DRp0UVTj.js → manifest-BtzDy7KQ.js} +36 -3
  97. package/dist/{manifest-DRp0UVTj.js.map → manifest-BtzDy7KQ.js.map} +1 -1
  98. package/dist/{normalize-imports-BoBVh5tU.js → normalize-imports-D0zXlM6g.js} +3 -3
  99. package/dist/{normalize-imports-BoBVh5tU.js.map → normalize-imports-D0zXlM6g.js.map} +1 -1
  100. package/dist/{path-flags-BFgG9V6y.js → path-flags-DNvtEi2-.js} +5 -4
  101. package/dist/path-flags-DNvtEi2-.js.map +1 -0
  102. package/dist/{prepare-DdnU70z8.js → prepare-CTw9NEkh.js} +5 -4
  103. package/dist/{prepare-DdnU70z8.js.map → prepare-CTw9NEkh.js.map} +1 -1
  104. package/dist/project-CasK56vN.js +701 -0
  105. package/dist/project-CasK56vN.js.map +1 -0
  106. package/dist/{pull-C3PXduzl.js → pull-DDMpsZ5r.js} +131 -24
  107. package/dist/pull-DDMpsZ5r.js.map +1 -0
  108. package/dist/refusal-ReeeGP8a.js +26 -0
  109. package/dist/refusal-ReeeGP8a.js.map +1 -0
  110. package/dist/resolve-D647F1LA.js +2 -0
  111. package/dist/{resources-BdNRDEAy.js → resources-CPSC5Kcu.js} +4 -5
  112. package/dist/{resources-BdNRDEAy.js.map → resources-CPSC5Kcu.js.map} +1 -1
  113. package/dist/{schema-B0-p6T1O.js → schema-BSXwZSiI.js} +9 -8
  114. package/dist/schema-BSXwZSiI.js.map +1 -0
  115. package/dist/{skills-DfnTeyRz.js → skills-BU2flMOy.js} +52 -8
  116. package/dist/skills-BU2flMOy.js.map +1 -0
  117. package/dist/{start-BmEZkS0n.js → start-mVb6upwY.js} +20 -7
  118. package/dist/start-mVb6upwY.js.map +1 -0
  119. package/dist/{state-CCB-FAQ9.js → state-CYdBvnwA.js} +3 -2
  120. package/dist/state-CYdBvnwA.js.map +1 -0
  121. package/dist/static-syntax-check.d.ts +64 -0
  122. package/dist/{status-BJ26yZOo.js → status-BREvtzJm.js} +8 -9
  123. package/dist/{status-BJ26yZOo.js.map → status-BREvtzJm.js.map} +1 -1
  124. package/dist/{storage-DKPUBTWG.js → storage-DtOXGflp.js} +159 -16
  125. package/dist/storage-DtOXGflp.js.map +1 -0
  126. package/dist/{telemetry-EMFRVRQi.js → telemetry-CgwJPVMO.js} +2 -2
  127. package/dist/{telemetry-EMFRVRQi.js.map → telemetry-CgwJPVMO.js.map} +1 -1
  128. package/dist/{telemetry-m9czTNGR.js → telemetry-DwK5RQJl.js} +4 -4
  129. package/dist/{telemetry-m9czTNGR.js.map → telemetry-DwK5RQJl.js.map} +1 -1
  130. package/dist/{upgrade-DjihWuZL.js → upgrade-B7sVwL8S.js} +26 -4
  131. package/dist/{upgrade-DjihWuZL.js.map → upgrade-B7sVwL8S.js.map} +1 -1
  132. package/dist/utils/args.d.ts +32 -3
  133. package/dist/utils/boot-retry.d.ts +41 -0
  134. package/dist/utils/collections-dir.d.ts +14 -0
  135. package/dist/utils/dev-preflight.d.ts +34 -1
  136. package/dist/utils/dev-server.d.ts +11 -0
  137. package/dist/utils/path-flags.d.ts +2 -1
  138. package/dist/utils/project.d.ts +5 -1
  139. package/dist/utils/tool-stdio.d.ts +1 -1
  140. package/dist/utils/unknown-command.d.ts +4 -0
  141. package/dist/verify-D7UsV_qe.js +730 -0
  142. package/dist/verify-D7UsV_qe.js.map +1 -0
  143. package/package.json +9 -7
  144. package/templates/eject/backend/src/index.ts +9 -1
  145. package/templates/generated-schemas/ecommerce.ts +3 -0
  146. package/templates/overlays/baas/ai-instructions.md +13 -0
  147. package/templates/resource-graphs/blank.json +25 -0
  148. package/templates/resource-graphs/blog.json +28 -0
  149. package/templates/resource-graphs/ecommerce.json +28 -0
  150. package/templates/resource-graphs/headless.json +22 -0
  151. package/templates/template/.claude/hooks/post-edit-collection.sh +99 -0
  152. package/templates/template/.claude/settings.json +17 -0
  153. package/templates/template/.env.example +15 -5
  154. package/templates/template/ai-instructions.md +21 -1
  155. package/templates/template/config/collections/presets/ecommerce/index.ts +23 -0
  156. package/templates/template/docker-compose.yml +4 -1
  157. package/templates/template/frontend/package.json +1 -0
  158. package/templates/template/frontend/src/App.tsx +10 -9
  159. package/templates/views/AppView.tsx.tmpl +138 -0
  160. package/templates/views/EntityView.tsx.tmpl +64 -0
  161. package/templates/views/index.ts.tmpl +8 -0
  162. package/dist/agent-setup-B5AKHOgt.js.map +0 -1
  163. package/dist/api-keys-Tm7zvAPe.js.map +0 -1
  164. package/dist/args-BX0YD14a.js +0 -266
  165. package/dist/args-BX0YD14a.js.map +0 -1
  166. package/dist/auth-Vl2hFKXP.js.map +0 -1
  167. package/dist/bundle-DtCCCr4w.js.map +0 -1
  168. package/dist/cloud-BpH0_bmV.js.map +0 -1
  169. package/dist/console-CEGm0XNc.js.map +0 -1
  170. package/dist/context-CyflUrKg.js.map +0 -1
  171. package/dist/daemon-CknkDjd6.js.map +0 -1
  172. package/dist/daemon-entry-CbLRrgzy.js.map +0 -1
  173. package/dist/db-CRNpA5mH.js.map +0 -1
  174. package/dist/dev-C0pbMmhS.js.map +0 -1
  175. package/dist/dev-preflight-unHpiYO1.js.map +0 -1
  176. package/dist/dev-server-B1UYifZJ.js.map +0 -1
  177. package/dist/doctor-CATRdWm6.js.map +0 -1
  178. package/dist/generate_sdk-Cvg5jjJF.js.map +0 -1
  179. package/dist/init-BWAwHPtz.js.map +0 -1
  180. package/dist/last-dev-database-c_dKz1S3.js +0 -2
  181. package/dist/path-flags-BFgG9V6y.js.map +0 -1
  182. package/dist/project-Wp2zoyeN.js +0 -349
  183. package/dist/project-Wp2zoyeN.js.map +0 -1
  184. package/dist/pull-C3PXduzl.js.map +0 -1
  185. package/dist/resolve-CNQjsatH.js +0 -2
  186. package/dist/schema-B0-p6T1O.js.map +0 -1
  187. package/dist/skills-DfnTeyRz.js.map +0 -1
  188. package/dist/start-BmEZkS0n.js.map +0 -1
  189. package/dist/state-CCB-FAQ9.js.map +0 -1
  190. package/dist/storage-DKPUBTWG.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade-DjihWuZL.js","names":[],"sources":["../src/upgrade.ts","../src/commands/upgrade.ts"],"sourcesContent":["/**\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 file work — git is asked only which files are the\n * project's — so it can be tested against a temporary directory: which files\n * are read, 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 { execFileSync } from \"child_process\";\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. They are skipped whether\n * or not git ignores them.\n */\nfunction skipDirectory(name: string): boolean {\n return name === \"node_modules\" || name.startsWith(\"dist\") || name.startsWith(\".\");\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\n/**\n * The files git counts as part of the project — tracked, or untracked and not\n * ignored — relative to `projectRoot`, POSIX. Null when git has no say: no git,\n * no repository, or a repository that lists nothing under the project root.\n *\n * Listing nothing means the repository ignores the project as a whole: a copy\n * of it under a gitignored scratch directory, say. Running the upgrade in that\n * copy is asking for the copy to move, and the repository's rules would leave\n * nothing in it to move. Asked with `git ls-files` rather than\n * `git check-ignore`, which answers differently across git versions for a\n * directory and for a negated pattern.\n */\nfunction gitProjectFiles(projectRoot: string, git: GitRunner): Set<string> | null {\n let listed: string;\n try {\n listed = git(projectRoot, [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\"]);\n } catch {\n return null;\n }\n const files = new Set(listed.split(\"\\0\").filter(Boolean));\n return files.size > 0 ? files : null;\n}\n\n/**\n * Every `package.json` and `pnpm-workspace.yaml` under the project root that\n * belongs to the project.\n *\n * In a git repository that means what git lists: a gitignored build context,\n * scratch copy or vendored package is not the project's, and rewriting it\n * would change files nobody committed. The walk enters only directories that\n * hold a listed file, so an ignored tree is not read at all. Outside a\n * repository every directory is walked. {@link skipDirectory} applies either\n * way.\n */\nexport function discoverProjectFiles(projectRoot: string, git: GitRunner = runGit): ProjectFiles {\n const found: ProjectFiles = { packageJsons: [], workspaceYamls: [] };\n const listed = gitProjectFiles(projectRoot, git);\n /** Every directory a listed file sits in, at any depth. */\n const listedDirectories = new Set<string>();\n for (const file of listed ?? []) {\n for (let dir = path.posix.dirname(file); dir !== \".\" && !listedDirectories.has(dir); dir = path.posix.dirname(dir)) {\n listedDirectories.add(dir);\n }\n }\n\n const walk = (dir: string, relativeDir: 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 const relative = relativeDir ? `${relativeDir}/${entry.name}` : 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) && (!listed || listedDirectories.has(relative))) walk(full, relative);\n } else if (entry.isFile() && (!listed || listed.has(relative))) {\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 — the note the summary\n * prints, and what `rebase upgrade` refuses without `--allow-downgrade`.\n *\n * Prerelease identifiers compare as SemVer orders them: a release outranks its\n * own prereleases, numbers compare as numbers, and the channel (`alpha` <\n * `beta` < `rc`) compares as text. One case SemVer orders and this does not:\n * two builds on one channel told apart by a non-numeric identifier. A canary\n * is `0.24.1-canary.g<git hash>`, and hashes sort in no order at all — so\n * `canary.gcb918fc` → `canary.g8c5a265` is neither forwards nor backwards as\n * far as the version can say, and the `canary` tag, which points at the newest\n * build, is the only thing that knows.\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 // Past the channel, two words are a build id, not an order.\n if (i > 0) return false;\n return x > y;\n }\n return false;\n}\n\n/**\n * The prerelease channel a project's pins are on — `canary` for\n * `0.24.1-canary.gcb918fc` — or null when none is on a prerelease, or they are\n * on more than one channel.\n *\n * The channel is the prerelease's first identifier, which is also the dist-tag\n * it is published under. `rebase upgrade` with no `--to` stays on it rather than\n * defaulting to `latest`, which for a canary project is usually older than the\n * build it already has.\n */\nexport function prereleaseChannel(versions: readonly string[]): string | null {\n const channels = new Set<string>();\n for (const version of versions) {\n const prerelease = SEMVER.exec(version.replace(/^[\\^~]/, \"\"))?.[4];\n const channel = prerelease?.split(\".\")[0];\n if (channel && /^[A-Za-z][0-9A-Za-z-]*$/.test(channel)) channels.add(channel);\n }\n return channels.size === 1 ? [...channels][0] : null;\n}\n\n/** The pins a plan moves to an older release. */\nexport function downgradedPins(plan: UpgradePlan): ChangedPin[] {\n return plan.changed.filter(pin => isDowngrade(pin.from, pin.to));\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 downgradedPins,\n installCommand,\n isDowngrade,\n isExactVersion,\n planUpgrade,\n prereleaseChannel,\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 \"--allow-downgrade\": Boolean,\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 — or, for a project\n on a prerelease, its channel (canary), unless latest\n is newer\n --allow-downgrade Let a dist-tag move pins to an older release. Without\n it that is refused; an exact --to version is taken\n as asked\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 that git does not ignore (node_modules,\n dist* and hidden directories excepted, in a repository or not). ^ and ~ are kept.\n peerDependencies are left alone, and so are workspace:, link:, file:, git and tag\n 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 newest release on this project's channel\n rebase upgrade --to latest --allow-downgrade Move a canary project back to stable\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 * What the same command without `--dry-run` would refuse with, in the\n * `{ error }` envelope's terms; `null` when it would go ahead. Only a dry\n * run sets it: a real run that refuses prints that envelope instead.\n */\n wouldRefuse: UpgradeRefusal | null;\n}\n\n/** A refusal `rebase upgrade` answers with, as its `--json` envelope carries it. */\nexport interface UpgradeRefusal {\n code: string;\n message: string;\n hint?: string;\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\n/**\n * The one release every moved pin came from, or `null` when they disagreed.\n * A range's `^`/`~` is not part of it: `upgrade --to` keeps each pin's operator.\n */\nfunction previousRelease(plan: UpgradePlan): string | null {\n const versions = new Set(plan.changed.map(pin => pin.from.replace(/^[\\^~]/, \"\")));\n if (versions.size !== 1) return null;\n const [version] = versions;\n return /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(version) ? version : null;\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 const requested = flags[\"--to\"];\n let plan: UpgradePlan;\n let channel: string | null = null;\n try {\n const npmView = (spec: string) => io.npmView(spec, projectRoot);\n const planFor = (target: string) =>\n planUpgrade(projectRoot, target, { dropLocalOverrides: flags[\"--drop-local-overrides\"] === true });\n plan = planFor(await resolveTarget(requested ?? \"latest\", npmView));\n channel = prereleaseChannel(plan.changed.map(pin => pin.from));\n // A project on a prerelease stays on its channel by default: for a\n // canary scaffold `latest` is usually the release *before* it. The\n // channel wins only when it is ahead, so a stable release that has\n // overtaken the channel is still where \"upgrade\" goes.\n if (requested === undefined && channel) {\n const onChannel = await resolveTarget(channel, npmView).catch(() => null);\n if (onChannel && isDowngrade(onChannel, plan.target)) {\n if (!json) {\n console.log(chalk.gray(` This project is on the ${channel} channel, so this stays on it: ${channel} is ${onChannel}.`));\n console.log(chalk.gray(` \\`rebase upgrade --to latest\\` is the stable release, ${plan.target}.`));\n }\n plan = planFor(onChannel);\n }\n }\n } catch (err) {\n if (err instanceof UpgradeError) refuse(err.message, err.code, err.hint);\n throw err;\n }\n\n // Going backwards is never a side effect. A dist-tag — `latest` above all,\n // the default — that names an older release than the project is on is\n // refused unless asked for; an exact `--to` version already is asking.\n const backwards = downgradedPins(plan);\n const exactRequest = requested !== undefined && isExactVersion(requested.trim().replace(/^v(?=\\d)/, \"\"));\n let downgradeRefusal: UpgradeRefusal | null = null;\n if (backwards.length > 0 && !exactRequest && flags[\"--allow-downgrade\"] !== true) {\n const tag = requested?.trim() ?? \"latest\";\n const current = [...new Set(backwards.map(pin => pin.from.replace(/^[\\^~]/, \"\")))].join(\", \");\n downgradeRefusal = {\n code: \"downgrade_refused\",\n message: `\\`${tag}\\` is ${plan.target}, older than this project's ${current}: ` +\n `upgrading to it would move ${backwards.length} pin${backwards.length === 1 ? \"\" : \"s\"} backwards.`,\n hint: channel\n ? `Stay on the ${channel} channel with \\`rebase upgrade --to ${channel}\\`, or pass --allow-downgrade to move to ${plan.target}.`\n : `Pass --allow-downgrade to move to ${plan.target} anyway, or --to <version> for an exact release.`\n };\n }\n // A dry run goes on to show what would move, and says the real run would\n // stop here — in its document too, where an agent asking \"would this work?\"\n // reads the answer. Exit 0 either way, as the human output's warning does.\n if (downgradeRefusal && !dryRun) {\n refuse(`${downgradeRefusal.message} Nothing was changed.`, downgradeRefusal.code, downgradeRefusal.hint);\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) {\n printSummary(plan, dryRun);\n if (backwards.length > 0) {\n const pins = `${backwards.length} pin${backwards.length === 1 ? \"\" : \"s\"}`;\n console.log(chalk.yellow(exactRequest || flags[\"--allow-downgrade\"] === true\n ? ` ⚠ ${plan.target} is an older release than ${pins} here ${dryRun ? \"are\" : \"were\"} on: this is a downgrade.`\n : ` ⚠ ${plan.target} is an older release than ${pins} here are on. A real run refuses it without --allow-downgrade.`));\n console.log(\"\");\n }\n }\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 // The undo is a command this one already knows, when every pin it\n // moved came from one release: a mistyped `--to` (0.99.0 for\n // 0.29.0) is the commonest way here, and \"revert with git\" is no\n // answer in a project `rebase init --yes` never made a repository.\n const previous = previousRelease(plan);\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 (previous\n ? `or put every pin back with \\`rebase upgrade --to ${previous}\\`.`\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 wouldRefuse: dryRun ? downgradeRefusal : null\n };\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n printOutcome(plan, { dryRun, wrote, installed, installLine, wouldRefuse: dryRun ? downgradeRefusal : null });\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; wouldRefuse: UpgradeRefusal | null }\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 // \"Run it without --dry-run\" is the one thing not to say after the\n // warning above that a real run refuses it: the last line is the one\n // acted on, so it names what to type instead.\n console.log(chalk.gray(moved === 0\n ? ` Nothing to change: this project is already on ${plan.target}.`\n : outcome.wouldRefuse\n ? ` Dry run — nothing was written, and a real run refuses it. ${outcome.wouldRefuse.hint}`\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"],"mappings":"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"}
1
+ {"version":3,"file":"upgrade-B7sVwL8S.js","names":[],"sources":["../src/upgrade.ts","../src/commands/upgrade.ts"],"sourcesContent":["/**\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 file work — git is asked only which files are the\n * project's — so it can be tested against a temporary directory: which files\n * are read, 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 { execFileSync } from \"child_process\";\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. They are skipped whether\n * or not git ignores them.\n */\nfunction skipDirectory(name: string): boolean {\n return name === \"node_modules\" || name.startsWith(\"dist\") || name.startsWith(\".\");\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\n/**\n * The files git counts as part of the project — tracked, or untracked and not\n * ignored — relative to `projectRoot`, POSIX. Null when git has no say: no git,\n * no repository, or a repository that lists nothing under the project root.\n *\n * Listing nothing means the repository ignores the project as a whole: a copy\n * of it under a gitignored scratch directory, say. Running the upgrade in that\n * copy is asking for the copy to move, and the repository's rules would leave\n * nothing in it to move. Asked with `git ls-files` rather than\n * `git check-ignore`, which answers differently across git versions for a\n * directory and for a negated pattern.\n */\nfunction gitProjectFiles(projectRoot: string, git: GitRunner): Set<string> | null {\n let listed: string;\n try {\n listed = git(projectRoot, [\"ls-files\", \"-z\", \"--cached\", \"--others\", \"--exclude-standard\"]);\n } catch {\n return null;\n }\n const files = new Set(listed.split(\"\\0\").filter(Boolean));\n return files.size > 0 ? files : null;\n}\n\n/**\n * Every `package.json` and `pnpm-workspace.yaml` under the project root that\n * belongs to the project.\n *\n * In a git repository that means what git lists: a gitignored build context,\n * scratch copy or vendored package is not the project's, and rewriting it\n * would change files nobody committed. The walk enters only directories that\n * hold a listed file, so an ignored tree is not read at all. Outside a\n * repository every directory is walked. {@link skipDirectory} applies either\n * way.\n */\nexport function discoverProjectFiles(projectRoot: string, git: GitRunner = runGit): ProjectFiles {\n const found: ProjectFiles = { packageJsons: [], workspaceYamls: [] };\n const listed = gitProjectFiles(projectRoot, git);\n /** Every directory a listed file sits in, at any depth. */\n const listedDirectories = new Set<string>();\n for (const file of listed ?? []) {\n for (let dir = path.posix.dirname(file); dir !== \".\" && !listedDirectories.has(dir); dir = path.posix.dirname(dir)) {\n listedDirectories.add(dir);\n }\n }\n\n const walk = (dir: string, relativeDir: 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 const relative = relativeDir ? `${relativeDir}/${entry.name}` : 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) && (!listed || listedDirectories.has(relative))) walk(full, relative);\n } else if (entry.isFile() && (!listed || listed.has(relative))) {\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 — the note the summary\n * prints, and what `rebase upgrade` refuses without `--allow-downgrade`.\n *\n * Prerelease identifiers compare as SemVer orders them: a release outranks its\n * own prereleases, numbers compare as numbers, and the channel (`alpha` <\n * `beta` < `rc`) compares as text. One case SemVer orders and this does not:\n * two builds on one channel told apart by a non-numeric identifier. A canary\n * is `0.24.1-canary.g<git hash>`, and hashes sort in no order at all — so\n * `canary.gcb918fc` → `canary.g8c5a265` is neither forwards nor backwards as\n * far as the version can say, and the `canary` tag, which points at the newest\n * build, is the only thing that knows.\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 // Past the channel, two words are a build id, not an order.\n if (i > 0) return false;\n return x > y;\n }\n return false;\n}\n\n/**\n * The prerelease channel a project's pins are on — `canary` for\n * `0.24.1-canary.gcb918fc` — or null when none is on a prerelease, or they are\n * on more than one channel.\n *\n * The channel is the prerelease's first identifier, which is also the dist-tag\n * it is published under. `rebase upgrade` with no `--to` stays on it rather than\n * defaulting to `latest`, which for a canary project is usually older than the\n * build it already has.\n */\nexport function prereleaseChannel(versions: readonly string[]): string | null {\n const channels = new Set<string>();\n for (const version of versions) {\n const prerelease = SEMVER.exec(version.replace(/^[\\^~]/, \"\"))?.[4];\n const channel = prerelease?.split(\".\")[0];\n if (channel && /^[A-Za-z][0-9A-Za-z-]*$/.test(channel)) channels.add(channel);\n }\n return channels.size === 1 ? [...channels][0] : null;\n}\n\n/** The pins a plan moves to an older release. */\nexport function downgradedPins(plan: UpgradePlan): ChangedPin[] {\n return plan.changed.filter(pin => isDowngrade(pin.from, pin.to));\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 downgradedPins,\n installCommand,\n isDowngrade,\n isExactVersion,\n planUpgrade,\n prereleaseChannel,\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 \"--allow-downgrade\": Boolean,\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 — or, for a project\n on a prerelease, its channel (canary), unless latest\n is newer\n --allow-downgrade Let a dist-tag move pins to an older release. Without\n it that is refused; an exact --to version is taken\n as asked\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 that git does not ignore (node_modules,\n dist* and hidden directories excepted, in a repository or not). ^ and ~ are kept.\n peerDependencies are left alone, and so are workspace:, link:, file:, git and tag\n 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 newest release on this project's channel\n rebase upgrade --to latest --allow-downgrade Move a canary project back to stable\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 * What the same command without `--dry-run` would refuse with, in the\n * `{ error }` envelope's terms; `null` when it would go ahead. Only a dry\n * run sets it: a real run that refuses prints that envelope instead.\n */\n wouldRefuse: UpgradeRefusal | null;\n}\n\n/** A refusal `rebase upgrade` answers with, as its `--json` envelope carries it. */\nexport interface UpgradeRefusal {\n code: string;\n message: string;\n hint?: string;\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\n/**\n * The one release every moved pin came from, or `null` when they disagreed.\n * A range's `^`/`~` is not part of it: `upgrade --to` keeps each pin's operator.\n */\nfunction previousRelease(plan: UpgradePlan): string | null {\n const versions = new Set(plan.changed.map(pin => pin.from.replace(/^[\\^~]/, \"\")));\n if (versions.size !== 1) return null;\n const [version] = versions;\n return /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/.test(version) ? version : null;\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 const requested = flags[\"--to\"];\n let plan: UpgradePlan;\n let channel: string | null = null;\n try {\n const npmView = (spec: string) => io.npmView(spec, projectRoot);\n const planFor = (target: string) =>\n planUpgrade(projectRoot, target, { dropLocalOverrides: flags[\"--drop-local-overrides\"] === true });\n plan = planFor(await resolveTarget(requested ?? \"latest\", npmView));\n channel = prereleaseChannel(plan.changed.map(pin => pin.from));\n // A project on a prerelease stays on its channel by default: for a\n // canary scaffold `latest` is usually the release *before* it. The\n // channel wins only when it is ahead, so a stable release that has\n // overtaken the channel is still where \"upgrade\" goes.\n if (requested === undefined && channel) {\n const onChannel = await resolveTarget(channel, npmView).catch(() => null);\n if (onChannel && isDowngrade(onChannel, plan.target)) {\n if (!json) {\n console.log(chalk.gray(` This project is on the ${channel} channel, so this stays on it: ${channel} is ${onChannel}.`));\n console.log(chalk.gray(` \\`rebase upgrade --to latest\\` is the stable release, ${plan.target}.`));\n }\n plan = planFor(onChannel);\n }\n }\n } catch (err) {\n if (err instanceof UpgradeError) refuse(err.message, err.code, err.hint);\n throw err;\n }\n\n // Going backwards is never a side effect. A dist-tag — `latest` above all,\n // the default — that names an older release than the project is on is\n // refused unless asked for; an exact `--to` version already is asking.\n const backwards = downgradedPins(plan);\n const exactRequest = requested !== undefined && isExactVersion(requested.trim().replace(/^v(?=\\d)/, \"\"));\n let downgradeRefusal: UpgradeRefusal | null = null;\n if (backwards.length > 0 && !exactRequest && flags[\"--allow-downgrade\"] !== true) {\n const tag = requested?.trim() ?? \"latest\";\n const current = [...new Set(backwards.map(pin => pin.from.replace(/^[\\^~]/, \"\")))].join(\", \");\n downgradeRefusal = {\n code: \"downgrade_refused\",\n message: `\\`${tag}\\` is ${plan.target}, older than this project's ${current}: ` +\n `upgrading to it would move ${backwards.length} pin${backwards.length === 1 ? \"\" : \"s\"} backwards.`,\n hint: channel\n ? `Stay on the ${channel} channel with \\`rebase upgrade --to ${channel}\\`, or pass --allow-downgrade to move to ${plan.target}.`\n : `Pass --allow-downgrade to move to ${plan.target} anyway, or --to <version> for an exact release.`\n };\n }\n // A dry run goes on to show what would move, and says the real run would\n // stop here — in its document too, where an agent asking \"would this work?\"\n // reads the answer. Exit 0 either way, as the human output's warning does.\n if (downgradeRefusal && !dryRun) {\n refuse(`${downgradeRefusal.message} Nothing was changed.`, downgradeRefusal.code, downgradeRefusal.hint);\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) {\n printSummary(plan, dryRun);\n if (backwards.length > 0) {\n const pins = `${backwards.length} pin${backwards.length === 1 ? \"\" : \"s\"}`;\n console.log(chalk.yellow(exactRequest || flags[\"--allow-downgrade\"] === true\n ? ` ⚠ ${plan.target} is an older release than ${pins} here ${dryRun ? \"are\" : \"were\"} on: this is a downgrade.`\n : ` ⚠ ${plan.target} is an older release than ${pins} here are on. A real run refuses it without --allow-downgrade.`));\n console.log(\"\");\n }\n }\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 // The undo is a command this one already knows, when every pin it\n // moved came from one release: a mistyped `--to` (0.99.0 for\n // 0.29.0) is the commonest way here, and \"revert with git\" is no\n // answer in a project `rebase init --yes` never made a repository.\n const previous = previousRelease(plan);\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 (previous\n ? `or put every pin back with \\`rebase upgrade --to ${previous}\\`.`\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 wouldRefuse: dryRun ? downgradeRefusal : null\n };\n\n const databaseNotice = wrote ? await runningDatabaseNotice(projectRoot, plan.target) : [];\n\n if (json) {\n console.log(JSON.stringify(result, null, 2));\n for (const line of databaseNotice) console.error(line);\n return;\n }\n\n printOutcome(plan, { dryRun, wrote, installed, installLine, wouldRefuse: dryRun ? downgradeRefusal : null });\n if (databaseNotice.length > 0) {\n for (const line of databaseNotice) console.log(chalk.yellow(line));\n console.log(\"\");\n }\n}\n\n/**\n * What to say about this project's managed database when an older CLI started\n * it, or nothing.\n *\n * The daemon outlives every command and the database proxy runs inside it, so\n * moving the pins does not move the proxy: the old one, with whatever the\n * upgrade fixed in it, kept serving until `rebase db stop` or thirty idle\n * minutes — and under a running `rebase dev` it never idles. The upgraded CLI\n * restarts it when nothing is connected (`daemonOutdated`); this says so, and\n * what to do while something is.\n */\nexport async function runningDatabaseNotice(projectRoot: string, target: string): Promise<string[]> {\n const { daemonOutdated, findRunningDaemon } = await import(\"../dev-db/daemon\");\n const state = await findRunningDaemon(projectRoot);\n if (!state || !daemonOutdated(state.cliVersion, target)) return [];\n const startedBy = state.cliVersion ? `Rebase CLI ${state.cliVersion}` : \"an earlier Rebase CLI\";\n return [\n `⚠ This project's development database is still running, started by ${startedBy}, and its database proxy is that CLI's until it restarts.`,\n ` The next command that needs it restarts it on ${target} when nothing is connected to it. ` +\n \"While `rebase dev` runs, stop it, then run `rebase db stop`. Data is kept.\"\n ];\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; wouldRefuse: UpgradeRefusal | null }\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 // \"Run it without --dry-run\" is the one thing not to say after the\n // warning above that a real run refuses it: the last line is the one\n // acted on, so it names what to type instead.\n console.log(chalk.gray(moved === 0\n ? ` Nothing to change: this project is already on ${plan.target}.`\n : outcome.wouldRefuse\n ? ` Dry run — nothing was written, and a real run refuses it. ${outcome.wouldRefuse.hint}`\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"],"mappings":"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"}
@@ -53,9 +53,37 @@ export declare const GLOBAL_COMMAND_FLAGS: {
53
53
  * With nothing close it lists what the command takes, when that list is short
54
54
  * enough to read.
55
55
  *
56
+ * `typed` is the argument as `arg` refused it, and only its flag part is
57
+ * repeated: a value given inline (`--fro=postgres://u:pw@h/db`) is not. One
58
+ * argument holding a flag and its value, quoted together, is named as that,
59
+ * and what it quotes is password-masked: `"--fro postgres://u:pw@h/db"` was
60
+ * refused with the whole URL, password included, in the middle of a garbled
61
+ * sentence.
62
+ *
56
63
  * Exported for the commands that refuse a flag outside `parseCommandArgs`.
57
64
  */
58
65
  export declare function unknownOptionMessage(command: string, typed: string, spec: Readonly<Record<string, unknown>>): string;
66
+ /**
67
+ * A line with every `--switch=value` resolved: `=true` or `=1` is the switch
68
+ * alone, `=false` or `=0` drops it, and any other value is refused.
69
+ *
70
+ * `arg` drops the value of a flag that takes none and turns the flag on, so
71
+ * `--anonymize=false` anonymized and `--yes=false` answered yes. `=true` kept
72
+ * working by that same accident, and scripts write it, so the two readings a
73
+ * value can have are honoured and nothing else is guessed at. Past `--` every
74
+ * word is a positional, so nothing there is read.
75
+ *
76
+ * @throws UsageError naming the switch and the values it takes.
77
+ */
78
+ export declare function resolveSwitchValues(spec: Readonly<Record<string, unknown>>, argv: readonly string[], command: string): string[];
79
+ /**
80
+ * Whether a switch is on in a line read by hand: given alone, or as `=true`
81
+ * or `=1`, before any `--`. The reading {@link resolveSwitchValues} gives the
82
+ * parsed flags, for the code that looks at `rawArgs` itself.
83
+ */
84
+ export declare function switchOn(rawArgs: readonly string[], flag: string): boolean;
85
+ /** The sentence a switch given a value it cannot read is refused with. */
86
+ export declare function switchValueMessage(command: string, flag: string, typed: string): string;
59
87
  export interface ParsedCommand<S extends arg.Spec> {
60
88
  /** The declared flags, as `arg` resolved them. */
61
89
  flags: arg.Result<S>;
@@ -94,9 +122,10 @@ export declare class UsageError extends Error {
94
122
  *
95
123
  * `command` names the command in error messages, e.g. `auth reset-password`.
96
124
  *
97
- * Throws on an unknown flag, on a positional that looks like a flag, and on
98
- * more positionals than the command takes. `bin/rebase.js` turns each into a
99
- * one-line `✗ …` and exit 1.
125
+ * Throws on an unknown flag, on a switch given a value other than true,
126
+ * false, 1 or 0 (`--yes=maybe`), on a positional that looks like a flag, and
127
+ * on more positionals than the command takes. `bin/rebase.js` turns each into
128
+ * a one-line `✗ …` and exit 1.
100
129
  */
101
130
  export declare function parseCommandArgs<S extends arg.Spec>({ spec, rawArgs, commandWords, command, maxPositionals }: {
102
131
  spec: S;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * A backend boot that lost its database part-way, which booting again fixes.
3
+ *
4
+ * `rebase db branch create --force` closes the database it copies: it ends
5
+ * every connection to it and refuses new ones until the copy is done. A
6
+ * backend booting at that moment failed with `Failed to start the Rebase
7
+ * runtime … terminating connection due to administrator command (57P01)`, and
8
+ * `rebase dev` then said "Fix the error above; the watcher restarts it on the
9
+ * next change", about an error nobody could fix and that the next boot would
10
+ * not have. The same holds for a database that is restarting.
11
+ *
12
+ * This reads the backend's output and says when a failed boot is worth another
13
+ * try, and after how long: a few tries, each waiting twice as long as the one
14
+ * before, and none once the backend has failed for a reason of its own.
15
+ */
16
+ /** One more boot, and how long to wait for it. */
17
+ export interface BootRetryPlan {
18
+ /** 1 for the first retry. */
19
+ attempt: number;
20
+ /** Of {@link BootRetry}'s `maxAttempts`. */
21
+ of: number;
22
+ delayMs: number;
23
+ /** The line that said why, as the backend printed it. */
24
+ reason: string;
25
+ }
26
+ export declare class BootRetry {
27
+ private readonly maxAttempts;
28
+ private readonly firstDelayMs;
29
+ private failing;
30
+ private planned;
31
+ private attempts;
32
+ constructor(maxAttempts?: number, firstDelayMs?: number);
33
+ /**
34
+ * Read one line of the backend's output, colour removed. Returns a plan
35
+ * the first time a failing boot names a passing cause, and null otherwise,
36
+ * including once the tries are spent.
37
+ */
38
+ line(text: string): BootRetryPlan | null;
39
+ /** The backend is serving: a later failure is a new one, with every try left. */
40
+ up(): void;
41
+ }
@@ -0,0 +1,14 @@
1
+ /** The config package directory, relative to the project root, as the backend app declares it. */
2
+ export declare function resolveConfigDir(projectRoot: string): string;
3
+ /** `<config>/collections`, absolute. */
4
+ export declare function resolveCollectionsDir(projectRoot: string): string;
5
+ /**
6
+ * `["--collections", <dir>]` to append to a driver command line, or nothing.
7
+ *
8
+ * `driverArgs` is the line as the driver gets it (`["db", "push", …]`,
9
+ * `["doctor", …]`). Nothing for a command that does not read collections, nothing
10
+ * when the line already names a directory, and nothing when the project keeps
11
+ * its collections where the driver looks by default, so a conventional
12
+ * project's command lines are unchanged.
13
+ */
14
+ export declare function collectionsDirArgs(projectRoot: string, driverArgs: readonly string[]): string[];