@percher/core 0.4.10 → 0.4.11

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 (140) hide show
  1. package/dist/ai-files-manifest.d.ts +1 -1
  2. package/dist/commands/account.d.ts +1 -1
  3. package/dist/commands/account.js +2 -2
  4. package/dist/commands/admin-reconcile-routes.d.ts +1 -1
  5. package/dist/commands/ai-files.d.ts +2 -2
  6. package/dist/commands/ai-files.js +2 -2
  7. package/dist/commands/alerts.d.ts +1 -1
  8. package/dist/commands/app-resources.d.ts +1 -1
  9. package/dist/commands/app-resources.js +2 -2
  10. package/dist/commands/app-topology.d.ts +1 -1
  11. package/dist/commands/app-topology.js +2 -2
  12. package/dist/commands/billing.d.ts +1 -1
  13. package/dist/commands/billing.js +1 -1
  14. package/dist/commands/cache.d.ts +1 -1
  15. package/dist/commands/cache.js +2 -2
  16. package/dist/commands/capabilities.d.ts +1 -1
  17. package/dist/commands/claim.d.ts +1 -1
  18. package/dist/commands/claim.js +1 -1
  19. package/dist/commands/create.d.ts +2 -2
  20. package/dist/commands/create.js +2 -2
  21. package/dist/commands/dashboard.d.ts +1 -1
  22. package/dist/commands/dashboard.js +2 -2
  23. package/dist/commands/data-export.d.ts +1 -1
  24. package/dist/commands/data-export.js +3 -3
  25. package/dist/commands/data.d.ts +1 -1
  26. package/dist/commands/data.js +2 -2
  27. package/dist/commands/delete.d.ts +1 -1
  28. package/dist/commands/delete.js +2 -2
  29. package/dist/commands/deploys.d.ts +1 -1
  30. package/dist/commands/deploys.js +2 -2
  31. package/dist/commands/dev.d.ts +1 -1
  32. package/dist/commands/dev.js +3 -3
  33. package/dist/commands/diagnose.d.ts +1 -1
  34. package/dist/commands/diagnose.js +2 -2
  35. package/dist/commands/diff.d.ts +1 -1
  36. package/dist/commands/diff.js +2 -2
  37. package/dist/commands/doctor.d.ts +3 -3
  38. package/dist/commands/doctor.js +4 -4
  39. package/dist/commands/domains.d.ts +1 -1
  40. package/dist/commands/domains.js +2 -2
  41. package/dist/commands/env.d.ts +1 -1
  42. package/dist/commands/env.js +2 -2
  43. package/dist/commands/export.d.ts +1 -1
  44. package/dist/commands/export.js +2 -2
  45. package/dist/commands/forgejo.d.ts +1 -1
  46. package/dist/commands/forgejo.js +2 -2
  47. package/dist/commands/generate.d.ts +1 -1
  48. package/dist/commands/generate.js +1 -1
  49. package/dist/commands/github.d.ts +1 -1
  50. package/dist/commands/github.js +2 -2
  51. package/dist/commands/import-project.d.ts +1 -1
  52. package/dist/commands/import-project.js +2 -2
  53. package/dist/commands/init.d.ts +2 -2
  54. package/dist/commands/init.js +3 -3
  55. package/dist/commands/insights.d.ts +1 -1
  56. package/dist/commands/insights.js +2 -2
  57. package/dist/commands/inspect-link.d.ts +1 -1
  58. package/dist/commands/inspect-link.js +2 -2
  59. package/dist/commands/login.d.ts +1 -1
  60. package/dist/commands/login.js +1 -1
  61. package/dist/commands/logs.d.ts +1 -1
  62. package/dist/commands/logs.js +2 -2
  63. package/dist/commands/mcp.d.ts +1 -1
  64. package/dist/commands/migrate-supabase-map.d.ts +1 -1
  65. package/dist/commands/migrate-supabase-recipes.d.ts +28 -0
  66. package/dist/commands/migrate-supabase-recipes.d.ts.map +1 -0
  67. package/dist/commands/migrate-supabase-recipes.js +92 -0
  68. package/dist/commands/migrate-supabase-recipes.js.map +1 -0
  69. package/dist/commands/migrate-supabase-rewrite.d.ts +8 -3
  70. package/dist/commands/migrate-supabase-rewrite.d.ts.map +1 -1
  71. package/dist/commands/migrate-supabase-rewrite.js +155 -11
  72. package/dist/commands/migrate-supabase-rewrite.js.map +1 -1
  73. package/dist/commands/migrate-supabase-scaffold.d.ts +25 -0
  74. package/dist/commands/migrate-supabase-scaffold.d.ts.map +1 -0
  75. package/dist/commands/migrate-supabase-scaffold.js +234 -0
  76. package/dist/commands/migrate-supabase-scaffold.js.map +1 -0
  77. package/dist/commands/migrate-supabase-schema.d.ts +4 -4
  78. package/dist/commands/migrate-supabase-schema.js +4 -4
  79. package/dist/commands/migrate-supabase-scripts.d.ts +1 -1
  80. package/dist/commands/migrate-supabase-sdk.d.ts +34 -0
  81. package/dist/commands/migrate-supabase-sdk.d.ts.map +1 -1
  82. package/dist/commands/migrate-supabase-sdk.js +169 -0
  83. package/dist/commands/migrate-supabase-sdk.js.map +1 -1
  84. package/dist/commands/migrate-supabase-status.d.ts +92 -0
  85. package/dist/commands/migrate-supabase-status.d.ts.map +1 -0
  86. package/dist/commands/migrate-supabase-status.js +470 -0
  87. package/dist/commands/migrate-supabase-status.js.map +1 -0
  88. package/dist/commands/migrate-supabase-walker.d.ts +15 -1
  89. package/dist/commands/migrate-supabase-walker.d.ts.map +1 -1
  90. package/dist/commands/migrate-supabase-walker.js +49 -5
  91. package/dist/commands/migrate-supabase-walker.js.map +1 -1
  92. package/dist/commands/migrate-supabase.d.ts +2 -2
  93. package/dist/commands/migrate-supabase.js +1 -1
  94. package/dist/commands/open.d.ts +1 -1
  95. package/dist/commands/open.js +2 -2
  96. package/dist/commands/preview-branch.d.ts +1 -1
  97. package/dist/commands/preview-branch.js +2 -2
  98. package/dist/commands/publish-api-error.d.ts +1 -1
  99. package/dist/commands/publish-api-error.js +1 -1
  100. package/dist/commands/publish-failure.d.ts +3 -3
  101. package/dist/commands/publish-failure.js +3 -3
  102. package/dist/commands/publish.d.ts +3 -3
  103. package/dist/commands/publish.js +13 -13
  104. package/dist/commands/push.d.ts +2 -2
  105. package/dist/commands/push.js +8 -8
  106. package/dist/commands/redeploy.d.ts +2 -2
  107. package/dist/commands/redeploy.js +4 -4
  108. package/dist/commands/rename.d.ts +1 -1
  109. package/dist/commands/rename.js +2 -2
  110. package/dist/commands/reproduce.d.ts +1 -1
  111. package/dist/commands/reproduce.js +1 -1
  112. package/dist/commands/reset-superuser.d.ts +1 -1
  113. package/dist/commands/reset-superuser.js +2 -2
  114. package/dist/commands/restore.d.ts +1 -1
  115. package/dist/commands/restore.js +2 -2
  116. package/dist/commands/resume.d.ts +1 -1
  117. package/dist/commands/resume.js +2 -2
  118. package/dist/commands/rollback.d.ts +1 -1
  119. package/dist/commands/rollback.js +2 -2
  120. package/dist/commands/sharing.d.ts +1 -1
  121. package/dist/commands/sharing.js +2 -2
  122. package/dist/commands/status.d.ts +1 -1
  123. package/dist/commands/transfers.d.ts +1 -1
  124. package/dist/commands/transfers.js +2 -2
  125. package/dist/commands/unsuspend.d.ts +1 -1
  126. package/dist/commands/versions.d.ts +1 -1
  127. package/dist/commands/versions.js +2 -2
  128. package/dist/commands/wait-deploy.d.ts +3 -3
  129. package/dist/commands/wait-deploy.js +3 -3
  130. package/dist/commands/whoami.d.ts +1 -1
  131. package/dist/detect.js +1 -1
  132. package/dist/index.d.ts +77 -75
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +76 -74
  135. package/dist/index.js.map +1 -1
  136. package/dist/poll-deployment.d.ts +1 -1
  137. package/dist/recovery.d.ts +1 -1
  138. package/dist/structured-error-codes.d.ts +1 -1
  139. package/dist/templates/ai-files/index.js +2 -2
  140. package/package.json +6 -3
@@ -0,0 +1,470 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join, relative, resolve } from "node:path";
3
+ import crossSpawn from "cross-spawn";
4
+ import { z } from "zod";
5
+ import { recoveryAsk, recoveryNone } from "../recovery.js";
6
+ import { scanSupabaseUsage } from "./migrate-supabase-sdk.js";
7
+ import { walkSupabaseProject } from "./migrate-supabase-walker.js";
8
+ /**
9
+ * Phase B — migration status doctor.
10
+ *
11
+ * Turns "what's left in a Supabase→PocketBase migration" from prose buried in
12
+ * REWRITE_NOTES.md into a runnable scoreboard. Read-only: it scans the project
13
+ * AS IT SITS (so it reflects manual edits + a prior `--apply`), never the
14
+ * Supabase project, never a token. It mirrors the rewriter's hybrid model —
15
+ * a migration legitimately stops in a HYBRID state (some calls PocketBase,
16
+ * some still Supabase because storage/rpc/realtime have no clean equivalent),
17
+ * and in that state keeping both SDKs + both env sets is CORRECT, not a miss.
18
+ */
19
+ export const migrationStatusInputSchema = z.object({
20
+ rootDir: z
21
+ .string()
22
+ .optional()
23
+ .describe("Project root to scan. Relative paths resolve against ctx.cwd. Defaults to ctx.cwd."),
24
+ build: z
25
+ .boolean()
26
+ .optional()
27
+ .describe("Also run the project's build as a final gate. Off by default — a half-migrated project legitimately fails to build, so the noise is opt-in."),
28
+ pbIdentifier: z
29
+ .string()
30
+ .optional()
31
+ .describe("PocketBase client identifier the rewrite used (defaults to `pb`). Pass the same value here that `rewrite_client` used, or the undefined-reference check can't see a custom identifier (e.g. `db`)."),
32
+ supabaseIdentifiers: z
33
+ .array(z.string())
34
+ .optional()
35
+ .describe("Supabase client variable names to recognise (beyond `supabase`)."),
36
+ });
37
+ /**
38
+ * Pure analysis over a set of files. Used by the standalone doctor (on-disk
39
+ * source) AND by the rewrite report embed (the rewriter's output), so the
40
+ * artifact and the live command can't disagree.
41
+ */
42
+ export function analyzeMigration(files, opts = {}) {
43
+ const pbName = opts.pbIdentifier ?? "pb";
44
+ const supabaseImportFiles = [];
45
+ const danglingPbFiles = [];
46
+ let authCalls = 0;
47
+ let storage = 0;
48
+ let rpc = 0;
49
+ let realtime = 0;
50
+ let edgeFunctions = 0;
51
+ let anyPbUsage = false;
52
+ let pocketbaseDepDeclared = false;
53
+ let supabaseDepDeclared = false;
54
+ let pocketbaseUrlEnv = false;
55
+ let supabaseEnvPresent = false;
56
+ for (const file of files) {
57
+ if (file.kind === "code") {
58
+ const scan = scanSupabaseUsage({
59
+ source: file.source,
60
+ supabaseIdentifiers: opts.supabaseIdentifiers,
61
+ pbIdentifier: pbName,
62
+ });
63
+ if (scan.importsSupabase)
64
+ supabaseImportFiles.push(file.relativePath);
65
+ if (scan.danglingPb)
66
+ danglingPbFiles.push(file.relativePath);
67
+ if (scan.usesPb)
68
+ anyPbUsage = true;
69
+ authCalls += scan.authCalls;
70
+ storage += scan.storage;
71
+ rpc += scan.rpc;
72
+ realtime += scan.realtime;
73
+ edgeFunctions += scan.edgeFunctions;
74
+ continue;
75
+ }
76
+ if (file.kind === "package_json") {
77
+ const deps = readDeps(file.source);
78
+ if ("pocketbase" in deps)
79
+ pocketbaseDepDeclared = true;
80
+ if ("@supabase/supabase-js" in deps || "@supabase/ssr" in deps)
81
+ supabaseDepDeclared = true;
82
+ continue;
83
+ }
84
+ // env
85
+ if (/^\s*[A-Z][A-Z0-9_]*POCKETBASE_URL\s*=/m.test(file.source))
86
+ pocketbaseUrlEnv = true;
87
+ if (/^\s*[A-Z][A-Z0-9_]*SUPABASE[A-Z0-9_]*\s*=/m.test(file.source))
88
+ supabaseEnvPresent = true;
89
+ }
90
+ const remaining = supabaseImportFiles.length + authCalls + storage + rpc + realtime + edgeFunctions;
91
+ const migrationComplete = remaining === 0;
92
+ const checks = [];
93
+ checks.push({
94
+ id: "supabaseImportsRemaining",
95
+ label: "Supabase imports removed",
96
+ status: supabaseImportFiles.length === 0 ? "pass" : "warn",
97
+ count: supabaseImportFiles.length,
98
+ detail: supabaseImportFiles.length === 0
99
+ ? "No files import @supabase/*."
100
+ : `${supabaseImportFiles.length} file(s) still import @supabase/* — migrate them, or keep them if this is intentionally hybrid.`,
101
+ ...(supabaseImportFiles.length > 0 ? { files: supabaseImportFiles } : {}),
102
+ });
103
+ checks.push({
104
+ id: "undefinedPbReferences",
105
+ label: "PocketBase client wired",
106
+ status: danglingPbFiles.length === 0 ? "pass" : "fail",
107
+ count: danglingPbFiles.length,
108
+ detail: danglingPbFiles.length === 0
109
+ ? `Every \`${pbName}\` reference resolves to an imported client.`
110
+ : `${danglingPbFiles.length} file(s) use \`${pbName}\` with no import in scope — the app won't run. Scaffold + import a client: percher migrate-from-supabase --rewrite-client --scaffold-client.`,
111
+ ...(danglingPbFiles.length > 0 ? { files: danglingPbFiles } : {}),
112
+ });
113
+ checks.push(usageCheck("authCallsRemaining", "Auth calls migrated", authCalls, "supabase.auth.* call(s) still to map — see the auth recipes in REWRITE_NOTES.md."));
114
+ checks.push(usageCheck("storageUsage", "Storage migrated", storage, "supabase.storage.* call(s) remain — PocketBase models files as record fields; rewrite by hand."));
115
+ checks.push(usageCheck("rpcUsage", "RPC migrated", rpc, "supabase.rpc(...) call(s) remain — move the logic into app code or a PB hook."));
116
+ checks.push(usageCheck("realtimeUsage", "Realtime migrated", realtime, "supabase.channel(...) call(s) remain — PB realtime uses pb.collection(c).subscribe(); the event shape differs."));
117
+ checks.push(usageCheck("edgeFunctionUsage", "Edge functions migrated", edgeFunctions, "supabase.functions.invoke(...) call(s) remain — host the function elsewhere and fetch it."));
118
+ // PocketBase dependency.
119
+ checks.push({
120
+ id: "pocketbaseDepDeclared",
121
+ label: "pocketbase dependency declared",
122
+ status: pocketbaseDepDeclared ? "pass" : anyPbUsage ? "warn" : "n/a",
123
+ count: 0,
124
+ detail: pocketbaseDepDeclared
125
+ ? "package.json depends on pocketbase."
126
+ : anyPbUsage
127
+ ? "Your code uses `pb` but package.json has no `pocketbase` dependency — add it."
128
+ : "No PocketBase client in use yet.",
129
+ });
130
+ // Supabase cleanup (hybrid-aware): keeping the dep while usage remains is
131
+ // correct; dropping it while usage remains is broken.
132
+ checks.push(cleanupCheck({ migrationComplete, supabaseDepDeclared, remaining, anyPbUsage }));
133
+ // Env wiring — POCKETBASE_URL is injected by Percher in prod, so its absence
134
+ // in a local env file is a gentle warn, not a failure. Only relevant when
135
+ // PocketBase is ACTUALLY in use: a project with no pb usage (incl. a
136
+ // non-Supabase project that's vacuously "complete") needs no POCKETBASE_URL,
137
+ // so this is n/a — warning there is a false alarm.
138
+ checks.push({
139
+ id: "envWired",
140
+ label: "POCKETBASE_URL in env",
141
+ status: pocketbaseUrlEnv ? "pass" : anyPbUsage ? "warn" : "n/a",
142
+ count: 0,
143
+ detail: pocketbaseUrlEnv
144
+ ? "POCKETBASE_URL is set for local dev."
145
+ : anyPbUsage
146
+ ? "No POCKETBASE_URL in your env files. Percher injects it automatically in production; add it to .env for local dev."
147
+ : "No PocketBase env needed yet.",
148
+ });
149
+ // RLS rules to translate — parsed from MIGRATION_NOTES.md when present.
150
+ const rls = opts.rlsManualCount ?? null;
151
+ checks.push({
152
+ id: "rlsRulesToWrite",
153
+ label: "RLS → PB API rules",
154
+ status: rls === null ? "n/a" : rls === 0 ? "pass" : "warn",
155
+ count: rls ?? 0,
156
+ detail: rls === null
157
+ ? "No migration-preview/MIGRATION_NOTES.md — run migrate-from-supabase to generate the schema + RLS report."
158
+ : rls === 0
159
+ ? "No RLS policies need manual translation."
160
+ : `${rls} RLS policy/policies still need PB API rules — see migration-preview/MIGRATION_NOTES.md.`,
161
+ });
162
+ let supabaseEnvNote = "";
163
+ if (!migrationComplete && !supabaseEnvPresent && supabaseDepDeclared) {
164
+ // The dep is present but the SUPABASE_* env was dropped while usage
165
+ // remains — flag it on the env check's detail (don't fail outright; the
166
+ // env may be platform-injected).
167
+ supabaseEnvNote =
168
+ " Note: Supabase calls remain but no SUPABASE_* env was found — make sure those keys are still set.";
169
+ }
170
+ if (supabaseEnvNote) {
171
+ const envCheck = checks.find((c) => c.id === "envWired");
172
+ if (envCheck)
173
+ envCheck.detail += supabaseEnvNote;
174
+ }
175
+ const state = deriveState(checks, migrationComplete, anyPbUsage, remaining);
176
+ return { checks, migrationComplete, state };
177
+ }
178
+ function usageCheck(id, label, count, remainingDetail) {
179
+ return {
180
+ id,
181
+ label,
182
+ status: count === 0 ? "pass" : "warn",
183
+ count,
184
+ detail: count === 0 ? "None remaining." : `${count} ${remainingDetail}`,
185
+ };
186
+ }
187
+ function cleanupCheck(args) {
188
+ const base = { id: "supabaseCleanup", label: "Supabase removed", count: args.remaining };
189
+ if (args.migrationComplete) {
190
+ if (args.supabaseDepDeclared) {
191
+ return {
192
+ ...base,
193
+ status: "warn",
194
+ detail: "Migration looks complete — you can now drop @supabase/supabase-js and the Supabase env keys.",
195
+ };
196
+ }
197
+ return { ...base, status: "pass", detail: "Supabase fully removed." };
198
+ }
199
+ // Migration NOT complete.
200
+ if (!args.supabaseDepDeclared && args.remaining > 0) {
201
+ return {
202
+ ...base,
203
+ status: "fail",
204
+ detail: `@supabase/supabase-js was dropped but ${args.remaining} Supabase reference(s) still need it — restore the dependency or finish migrating them.`,
205
+ };
206
+ }
207
+ return {
208
+ ...base,
209
+ status: "warn",
210
+ detail: `Hybrid: ${args.remaining} Supabase reference(s) remain (storage/rpc/realtime/edge/un-mapped auth or @supabase imports). Keep @supabase/supabase-js + Supabase env until they're migrated.`,
211
+ };
212
+ }
213
+ function deriveState(checks, migrationComplete, anyPbUsage, remaining) {
214
+ if (checks.some((c) => c.status === "fail"))
215
+ return "broken";
216
+ if (migrationComplete)
217
+ return "complete";
218
+ if (anyPbUsage)
219
+ return "hybrid";
220
+ // Supabase usage present, nothing migrated to pb yet.
221
+ return remaining > 0 ? "not_started" : "complete";
222
+ }
223
+ /** Parse a package.json's dependency names across all dep sections. */
224
+ function readDeps(source) {
225
+ let pkg;
226
+ try {
227
+ pkg = JSON.parse(source);
228
+ }
229
+ catch {
230
+ return {};
231
+ }
232
+ const out = {};
233
+ for (const section of [
234
+ "dependencies",
235
+ "devDependencies",
236
+ "peerDependencies",
237
+ "optionalDependencies",
238
+ ]) {
239
+ const deps = pkg[section];
240
+ if (deps && typeof deps === "object" && !Array.isArray(deps)) {
241
+ Object.assign(out, deps);
242
+ }
243
+ }
244
+ return out;
245
+ }
246
+ const STATUS_GLYPH = {
247
+ pass: "✓",
248
+ fail: "✗",
249
+ warn: "⚠",
250
+ "n/a": "•",
251
+ };
252
+ /** Render the checklist as a plain ✓/✗/⚠ block (CLI output + report embed). */
253
+ export function renderMigrationChecklist(checks) {
254
+ const lines = [];
255
+ for (const check of checks) {
256
+ const glyph = STATUS_GLYPH[check.status];
257
+ const countSuffix = check.count > 0 ? ` (${check.count})` : "";
258
+ lines.push(`${glyph} ${check.label}${countSuffix} — ${check.detail}`);
259
+ if (check.files && check.files.length > 0) {
260
+ for (const f of check.files.slice(0, 10))
261
+ lines.push(` - ${f}`);
262
+ if (check.files.length > 10)
263
+ lines.push(` …and ${check.files.length - 10} more`);
264
+ }
265
+ }
266
+ return lines.join("\n");
267
+ }
268
+ const STATE_SUMMARY = {
269
+ broken: "Migration is in a broken state — fix the ✗ items before deploying.",
270
+ hybrid: "Hybrid migration — some calls are on PocketBase, some still on Supabase (both SDKs needed).",
271
+ not_started: "Supabase is still in use — nothing migrated to PocketBase yet.",
272
+ complete: "Migration looks complete — no Supabase usage remains.",
273
+ };
274
+ export async function migrationStatus(ctx, input) {
275
+ const rootAbs = input.rootDir ? resolve(ctx.cwd, input.rootDir) : resolve(ctx.cwd);
276
+ ctx.status(`Scanning ${relative(ctx.cwd, rootAbs) || "."} for migration status...`);
277
+ let files;
278
+ try {
279
+ const walk = await walkSupabaseProject({ rootDir: rootAbs });
280
+ // Scan the CURRENT on-disk source (file.source), not the rewriter's
281
+ // projection — the doctor reports the project as it actually sits.
282
+ files = walk.files.map((f) => ({
283
+ relativePath: f.relativePath,
284
+ kind: f.kind,
285
+ source: f.source,
286
+ }));
287
+ }
288
+ catch (err) {
289
+ return failure(rootAbs, err);
290
+ }
291
+ const rlsManualCount = await readManualRlsCount(rootAbs);
292
+ const analysis = analyzeMigration(files, {
293
+ rlsManualCount,
294
+ pbIdentifier: input.pbIdentifier,
295
+ supabaseIdentifiers: input.supabaseIdentifiers,
296
+ });
297
+ let build;
298
+ if (input.build === true) {
299
+ build = await runProjectBuild(rootAbs);
300
+ }
301
+ const checklist = renderMigrationChecklist(analysis.checks);
302
+ const failing = analysis.checks.filter((c) => c.status === "fail");
303
+ const warning = analysis.checks.filter((c) => c.status === "warn");
304
+ const buildFailed = build?.ran === true && !build.passed;
305
+ const allGreen = failing.length === 0 && warning.length === 0 && !buildFailed;
306
+ const recovery = allGreen
307
+ ? recoveryNone()
308
+ : recoveryAsk({
309
+ prompt: buildPrompt(analysis.state, failing, warning, build),
310
+ reasonCode: "unknown",
311
+ });
312
+ const summary = `${STATE_SUMMARY[analysis.state]}${build ? ` Build: ${build.ran ? (build.passed ? "passed" : "FAILED") : "skipped"}.` : ""}`;
313
+ return {
314
+ status: "ok",
315
+ rootDir: rootAbs,
316
+ state: analysis.state,
317
+ migrationComplete: analysis.migrationComplete,
318
+ checks: analysis.checks,
319
+ ...(build ? { build } : {}),
320
+ recovery,
321
+ summary,
322
+ checklist,
323
+ };
324
+ }
325
+ function buildPrompt(state, failing, warning, build) {
326
+ const bits = [];
327
+ if (failing.length > 0) {
328
+ bits.push(`fix first: ${failing.map((c) => `${c.label} — ${c.detail}`).join("; ")}`);
329
+ }
330
+ if (warning.length > 0) {
331
+ bits.push(`still to do: ${warning.map((c) => `${c.label} (${c.count || "n/a"})`).join(", ")}`);
332
+ }
333
+ if (build?.ran && !build.passed) {
334
+ bits.push(`the build failed: ${build.detail}`);
335
+ }
336
+ const lead = state === "broken" ? "The migration is in a broken state." : "The migration isn't finished.";
337
+ return `${lead} ${bits.join(". ")}. Work through migration-preview/REWRITE_NOTES.md, then re-run --status.`;
338
+ }
339
+ /** Read migration-preview/MIGRATION_NOTES.md and pull the manual-RLS count
340
+ * from its stable summary line. Null when the file isn't present. */
341
+ async function readManualRlsCount(rootAbs) {
342
+ for (const dir of ["migration-preview", "."]) {
343
+ try {
344
+ const notes = await readFile(join(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
345
+ const m = notes.match(/\*\*RLS policies:\*\*\s*\d+\s*\((\d+)\s*need manual review\)/);
346
+ if (m?.[1] !== undefined)
347
+ return Number.parseInt(m[1], 10);
348
+ return 0; // file present but no RLS line — treat as zero
349
+ }
350
+ catch {
351
+ // not in this dir — try the next
352
+ }
353
+ }
354
+ return null;
355
+ }
356
+ /**
357
+ * Opt-in build gate. Detects the package manager from the lockfile and runs
358
+ * its `build` script, capturing exit code + a tail of output. Best-effort:
359
+ * a missing build script or absent node_modules surfaces as a failed/ skipped
360
+ * gate, never throws.
361
+ */
362
+ async function runProjectBuild(rootAbs) {
363
+ let hasBuildScript = false;
364
+ try {
365
+ const pkg = JSON.parse(await readFile(join(rootAbs, "package.json"), "utf8"));
366
+ hasBuildScript = typeof pkg.scripts?.build === "string";
367
+ }
368
+ catch {
369
+ return { ran: false, passed: false, detail: "No readable package.json — nothing to build." };
370
+ }
371
+ if (!hasBuildScript) {
372
+ return { ran: false, passed: false, detail: "No `build` script in package.json." };
373
+ }
374
+ const pm = await detectPackageManager(rootAbs);
375
+ const result = await spawnCapture(pm, ["run", "build"], rootAbs, 300_000);
376
+ if (result.timedOut) {
377
+ return { ran: true, passed: false, detail: `\`${pm} run build\` timed out after 5 min.` };
378
+ }
379
+ if (result.spawnError) {
380
+ return {
381
+ ran: false,
382
+ passed: false,
383
+ detail: `Couldn't run \`${pm} run build\` (${result.spawnError}). Is ${pm} installed?`,
384
+ };
385
+ }
386
+ const passed = result.code === 0;
387
+ const tail = lastLines(result.output, 12);
388
+ return {
389
+ ran: true,
390
+ passed,
391
+ detail: passed
392
+ ? `\`${pm} run build\` succeeded.`
393
+ : `\`${pm} run build\` exited ${result.code}.${tail ? `\n${tail}` : ""}`,
394
+ };
395
+ }
396
+ async function detectPackageManager(rootAbs) {
397
+ const has = async (name) => {
398
+ try {
399
+ await readFile(join(rootAbs, name), "utf8");
400
+ return true;
401
+ }
402
+ catch {
403
+ return false;
404
+ }
405
+ };
406
+ if ((await has("bun.lock")) || (await has("bun.lockb")))
407
+ return "bun";
408
+ if (await has("pnpm-lock.yaml"))
409
+ return "pnpm";
410
+ if (await has("yarn.lock"))
411
+ return "yarn";
412
+ return "npm";
413
+ }
414
+ /** Spawn via cross-spawn (Windows .cmd-shim safe, no shell), capture combined
415
+ * output, enforce a timeout. */
416
+ function spawnCapture(cmd, args, cwd, timeoutMs) {
417
+ return new Promise((resolve) => {
418
+ const child = crossSpawn(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
419
+ let output = "";
420
+ const onData = (chunk) => {
421
+ output += chunk.toString();
422
+ // Cap retained output so a chatty build doesn't balloon memory.
423
+ if (output.length > 64_000)
424
+ output = output.slice(-64_000);
425
+ };
426
+ child.stdout?.on("data", onData);
427
+ child.stderr?.on("data", onData);
428
+ let timedOut = false;
429
+ const timer = setTimeout(() => {
430
+ timedOut = true;
431
+ child.kill("SIGTERM");
432
+ }, timeoutMs);
433
+ child.on("error", (err) => {
434
+ clearTimeout(timer);
435
+ resolve({ code: 1, output, timedOut, spawnError: err.message });
436
+ });
437
+ child.on("close", (code) => {
438
+ clearTimeout(timer);
439
+ resolve({ code: code ?? 1, output, timedOut });
440
+ });
441
+ });
442
+ }
443
+ function lastLines(text, n) {
444
+ const lines = text.split(/\r?\n/).filter((l) => l.trim().length > 0);
445
+ return lines.slice(-n).join("\n");
446
+ }
447
+ function failure(rootAbs, err) {
448
+ const message = err instanceof Error ? err.message : String(err);
449
+ return {
450
+ status: "failed",
451
+ rootDir: rootAbs,
452
+ state: "broken",
453
+ migrationComplete: false,
454
+ checks: [],
455
+ recovery: recoveryAsk({
456
+ prompt: `Couldn't scan the project for migration status (${message}). Check the path exists and is readable, then re-run.`,
457
+ reasonCode: "unknown",
458
+ retryable: true,
459
+ }),
460
+ summary: `Migration status scan failed: ${message}`,
461
+ checklist: "",
462
+ error: {
463
+ code: "status_failed",
464
+ title: "Migration status scan failed",
465
+ explanation: message,
466
+ suggestion: "Check the project path exists and is readable, then re-run.",
467
+ },
468
+ };
469
+ }
470
+ //# sourceMappingURL=migrate-supabase-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-supabase-status.js","sourceRoot":"","sources":["../../src/commands/migrate-supabase-status.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { type RewriteFlag } from "./migrate-supabase-sdk";
1
+ import { type RewriteFlag } from "./migrate-supabase-sdk.js";
2
2
  export type WalkedFileKind = "code" | "package_json" | "env";
3
3
  export interface WalkedFile {
4
4
  /** Path relative to `rootDir`, forward-slash-normalised. */
@@ -42,6 +42,20 @@ export interface WalkSupabaseProjectResult {
42
42
  flagCount: number;
43
43
  packageJsonChanged: boolean;
44
44
  envFilesChanged: number;
45
+ /**
46
+ * True when nothing Supabase remains after the rewrite — zero
47
+ * `@supabase/*` imports AND zero remaining auth/storage/rpc/realtime/
48
+ * edge-function calls. Only then is dropping the dep + stubbing the
49
+ * env safe. A hybrid project (some calls left untouched on purpose)
50
+ * reports false, and the walker keeps the Supabase dep + env intact.
51
+ */
52
+ migrationComplete: boolean;
53
+ /**
54
+ * Count behind `migrationComplete`: remaining auth/storage/rpc/realtime/
55
+ * edge calls plus files still importing `@supabase/*`. Surfaced so the
56
+ * caller can explain WHY the dep/env were kept.
57
+ */
58
+ supabaseUsageRemaining: number;
45
59
  };
46
60
  }
47
61
  export declare function walkSupabaseProject(input: WalkSupabaseProjectInput): Promise<WalkSupabaseProjectResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-supabase-walker.d.ts","sourceRoot":"","sources":["../../src/commands/migrate-supabase-walker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAsB,MAAM,wBAAwB,CAAC;AAuD9E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,IAAI,EAAE,cAAc,CAAC;IACrB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mEAAmE;IACnE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CA+GpC;AA8DD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAgDA;AAID;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAgEA;AA8BD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,yBAAyB,CAAC;IAClC,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsCjG"}
1
+ {"version":3,"file":"migrate-supabase-walker.d.ts","sourceRoot":"","sources":["../../src/commands/migrate-supabase-walker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAyC,MAAM,wBAAwB,CAAC;AAuDjG,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,cAAc,GAAG,KAAK,CAAC;AAE7D,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,IAAI,EAAE,cAAc,CAAC;IACrB,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,mEAAmE;IACnE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,uCAAuC;IACvC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,eAAe,EAAE,MAAM,CAAC;QACxB;;;;;;WAMG;QACH,iBAAiB,EAAE,OAAO,CAAC;QAC3B;;;;WAIG;QACH,sBAAsB,EAAE,MAAM,CAAC;KAChC,CAAC;CACH;AAED,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CA+JpC;AA8DD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAgDA;AAID;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB,CAgEA;AA8BD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,yBAAyB,CAAC;IAClC,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsCjG"}
@@ -1,7 +1,7 @@
1
1
  import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
2
2
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
3
  import ignore from "ignore";
4
- import { rewriteSupabaseSdk } from "./migrate-supabase-sdk";
4
+ import { rewriteSupabaseSdk, scanSupabaseUsage } from "./migrate-supabase-sdk.js";
5
5
  /**
6
6
  * FUTURE9 Phase D chunk 3.2 — project-wide Supabase rewrite.
7
7
  *
@@ -60,6 +60,12 @@ export async function walkSupabaseProject(input) {
60
60
  }
61
61
  const files = [];
62
62
  const skipped = [];
63
+ // Config files (package.json / .env*) are held until the code-file scan
64
+ // tells us whether the migration is complete — dropping the Supabase dep
65
+ // or stubbing the env while untouched Supabase calls remain breaks a
66
+ // hybrid app. Rewriting them per-file in the loop (the old behaviour)
67
+ // couldn't see the project-wide picture.
68
+ const pendingConfig = [];
63
69
  for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
64
70
  const rel = relative(rootAbs, absPath).split(sep).join("/");
65
71
  const kind = classifyFile(rel);
@@ -118,11 +124,47 @@ export async function walkSupabaseProject(input) {
118
124
  });
119
125
  continue;
120
126
  }
121
- const configResult = kind === "package_json" ? rewritePackageJson(source) : rewriteEnvFile(source);
127
+ // Hold config files rewrite them only after the migration-complete
128
+ // decision below.
129
+ pendingConfig.push({ relativePath: rel, kind, source });
130
+ }
131
+ // Decide migration-complete from the REWRITTEN code files: scan each for
132
+ // any Supabase surface that would survive the rewrite. The dep/env are
133
+ // only safe to drop when nothing is left.
134
+ let supabaseUsageRemaining = 0;
135
+ for (const file of files) {
136
+ if (file.kind !== "code")
137
+ continue;
138
+ const scan = scanSupabaseUsage({
139
+ source: file.rewritten,
140
+ supabaseIdentifiers: input.supabaseIdentifiers,
141
+ });
142
+ supabaseUsageRemaining +=
143
+ scan.authCalls + scan.storage + scan.rpc + scan.realtime + scan.edgeFunctions;
144
+ if (scan.importsSupabase)
145
+ supabaseUsageRemaining += 1;
146
+ }
147
+ const migrationComplete = supabaseUsageRemaining === 0;
148
+ // Apply the held config rewrites only when the migration is complete.
149
+ // Otherwise keep them byte-for-byte (the hybrid app still needs the
150
+ // Supabase dep + env); the caller surfaces the "kept on purpose" note.
151
+ for (const cfg of pendingConfig) {
152
+ if (!migrationComplete) {
153
+ files.push({
154
+ relativePath: cfg.relativePath,
155
+ kind: cfg.kind,
156
+ source: cfg.source,
157
+ rewritten: cfg.source,
158
+ changed: false,
159
+ flags: [],
160
+ });
161
+ continue;
162
+ }
163
+ const configResult = cfg.kind === "package_json" ? rewritePackageJson(cfg.source) : rewriteEnvFile(cfg.source);
122
164
  files.push({
123
- relativePath: rel,
124
- kind,
125
- source,
165
+ relativePath: cfg.relativePath,
166
+ kind: cfg.kind,
167
+ source: cfg.source,
126
168
  rewritten: configResult.rewritten,
127
169
  changed: configResult.changed,
128
170
  flags: configResult.flags,
@@ -156,6 +198,8 @@ export async function walkSupabaseProject(input) {
156
198
  flagCount,
157
199
  packageJsonChanged,
158
200
  envFilesChanged,
201
+ migrationComplete,
202
+ supabaseUsageRemaining,
159
203
  },
160
204
  };
161
205
  }