percher 0.5.5 → 0.5.7

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.
@@ -5069,11 +5069,11 @@ var require_tslib = __commonJS((exports, module) => {
5069
5069
  };
5070
5070
  __awaiter = function(thisArg, _arguments, P, generator) {
5071
5071
  function adopt(value) {
5072
- return value instanceof P ? value : new P(function(resolve7) {
5073
- resolve7(value);
5072
+ return value instanceof P ? value : new P(function(resolve6) {
5073
+ resolve6(value);
5074
5074
  });
5075
5075
  }
5076
- return new (P || (P = Promise))(function(resolve7, reject) {
5076
+ return new (P || (P = Promise))(function(resolve6, reject) {
5077
5077
  function fulfilled(value) {
5078
5078
  try {
5079
5079
  step(generator.next(value));
@@ -5089,7 +5089,7 @@ var require_tslib = __commonJS((exports, module) => {
5089
5089
  }
5090
5090
  }
5091
5091
  function step(result) {
5092
- result.done ? resolve7(result.value) : adopt(result.value).then(fulfilled, rejected);
5092
+ result.done ? resolve6(result.value) : adopt(result.value).then(fulfilled, rejected);
5093
5093
  }
5094
5094
  step((generator = generator.apply(thisArg, _arguments || [])).next());
5095
5095
  });
@@ -5318,14 +5318,14 @@ var require_tslib = __commonJS((exports, module) => {
5318
5318
  }, i);
5319
5319
  function verb(n) {
5320
5320
  i[n] = o[n] && function(v) {
5321
- return new Promise(function(resolve7, reject) {
5322
- v = o[n](v), settle(resolve7, reject, v.done, v.value);
5321
+ return new Promise(function(resolve6, reject) {
5322
+ v = o[n](v), settle(resolve6, reject, v.done, v.value);
5323
5323
  });
5324
5324
  };
5325
5325
  }
5326
- function settle(resolve7, reject, d, v) {
5326
+ function settle(resolve6, reject, d, v) {
5327
5327
  Promise.resolve(v).then(function(v2) {
5328
- resolve7({ value: v2, done: d });
5328
+ resolve6({ value: v2, done: d });
5329
5329
  }, reject);
5330
5330
  }
5331
5331
  };
@@ -8824,7 +8824,7 @@ var require_util = __commonJS((exports) => {
8824
8824
  }
8825
8825
  path = url2.path;
8826
8826
  }
8827
- var isAbsolute3 = exports.isAbsolute(path);
8827
+ var isAbsolute2 = exports.isAbsolute(path);
8828
8828
  var parts = path.split(/\/+/);
8829
8829
  for (var part, up = 0, i = parts.length - 1;i >= 0; i--) {
8830
8830
  part = parts[i];
@@ -8844,7 +8844,7 @@ var require_util = __commonJS((exports) => {
8844
8844
  }
8845
8845
  path = parts.join("/");
8846
8846
  if (path === "") {
8847
- path = isAbsolute3 ? "/" : ".";
8847
+ path = isAbsolute2 ? "/" : ".";
8848
8848
  }
8849
8849
  if (url2) {
8850
8850
  url2.path = path;
@@ -8853,7 +8853,7 @@ var require_util = __commonJS((exports) => {
8853
8853
  return path;
8854
8854
  }
8855
8855
  exports.normalize = normalize2;
8856
- function join18(aRoot, aPath) {
8856
+ function join17(aRoot, aPath) {
8857
8857
  if (aRoot === "") {
8858
8858
  aRoot = ".";
8859
8859
  }
@@ -8885,11 +8885,11 @@ var require_util = __commonJS((exports) => {
8885
8885
  }
8886
8886
  return joined;
8887
8887
  }
8888
- exports.join = join18;
8888
+ exports.join = join17;
8889
8889
  exports.isAbsolute = function(aPath) {
8890
8890
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
8891
8891
  };
8892
- function relative4(aRoot, aPath) {
8892
+ function relative3(aRoot, aPath) {
8893
8893
  if (aRoot === "") {
8894
8894
  aRoot = ".";
8895
8895
  }
@@ -8908,7 +8908,7 @@ var require_util = __commonJS((exports) => {
8908
8908
  }
8909
8909
  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
8910
8910
  }
8911
- exports.relative = relative4;
8911
+ exports.relative = relative3;
8912
8912
  var supportsNullProto = function() {
8913
8913
  var obj = Object.create(null);
8914
8914
  return !("__proto__" in obj);
@@ -9058,7 +9058,7 @@ var require_util = __commonJS((exports) => {
9058
9058
  parsed.path = parsed.path.substring(0, index + 1);
9059
9059
  }
9060
9060
  }
9061
- sourceURL = join18(urlGenerate(parsed), sourceURL);
9061
+ sourceURL = join17(urlGenerate(parsed), sourceURL);
9062
9062
  }
9063
9063
  return normalize2(sourceURL);
9064
9064
  }
@@ -89384,10 +89384,10 @@ var require_browser = __commonJS((exports) => {
89384
89384
  text = canvas;
89385
89385
  canvas = undefined;
89386
89386
  }
89387
- return new Promise(function(resolve7, reject) {
89387
+ return new Promise(function(resolve9, reject) {
89388
89388
  try {
89389
89389
  const data2 = QRCode.create(text, opts);
89390
- resolve7(renderFunc(data2, canvas, opts));
89390
+ resolve9(renderFunc(data2, canvas, opts));
89391
89391
  } catch (e) {
89392
89392
  reject(e);
89393
89393
  }
@@ -89466,11 +89466,11 @@ var require_server = __commonJS((exports) => {
89466
89466
  }
89467
89467
  function render(renderFunc, text, params) {
89468
89468
  if (!params.cb) {
89469
- return new Promise(function(resolve7, reject) {
89469
+ return new Promise(function(resolve9, reject) {
89470
89470
  try {
89471
89471
  const data2 = QRCode.create(text, params.opts);
89472
89472
  return renderFunc(data2, params.opts, function(err, data3) {
89473
- return err ? reject(err) : resolve7(data3);
89473
+ return err ? reject(err) : resolve9(data3);
89474
89474
  });
89475
89475
  } catch (e) {
89476
89476
  reject(e);
@@ -89543,6 +89543,462 @@ var init_qr = __esm(() => {
89543
89543
  import_qrcode = __toESM(require_server(), 1);
89544
89544
  });
89545
89545
 
89546
+ // ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/windows.js
89547
+ var require_windows = __commonJS((exports, module) => {
89548
+ module.exports = isexe;
89549
+ isexe.sync = sync;
89550
+ var fs = __require("fs");
89551
+ function checkPathExt(path, options) {
89552
+ var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
89553
+ if (!pathext) {
89554
+ return true;
89555
+ }
89556
+ pathext = pathext.split(";");
89557
+ if (pathext.indexOf("") !== -1) {
89558
+ return true;
89559
+ }
89560
+ for (var i = 0;i < pathext.length; i++) {
89561
+ var p = pathext[i].toLowerCase();
89562
+ if (p && path.substr(-p.length).toLowerCase() === p) {
89563
+ return true;
89564
+ }
89565
+ }
89566
+ return false;
89567
+ }
89568
+ function checkStat(stat2, path, options) {
89569
+ if (!stat2.isSymbolicLink() && !stat2.isFile()) {
89570
+ return false;
89571
+ }
89572
+ return checkPathExt(path, options);
89573
+ }
89574
+ function isexe(path, options, cb) {
89575
+ fs.stat(path, function(er, stat2) {
89576
+ cb(er, er ? false : checkStat(stat2, path, options));
89577
+ });
89578
+ }
89579
+ function sync(path, options) {
89580
+ return checkStat(fs.statSync(path), path, options);
89581
+ }
89582
+ });
89583
+
89584
+ // ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/mode.js
89585
+ var require_mode2 = __commonJS((exports, module) => {
89586
+ module.exports = isexe;
89587
+ isexe.sync = sync;
89588
+ var fs = __require("fs");
89589
+ function isexe(path, options, cb) {
89590
+ fs.stat(path, function(er, stat2) {
89591
+ cb(er, er ? false : checkStat(stat2, options));
89592
+ });
89593
+ }
89594
+ function sync(path, options) {
89595
+ return checkStat(fs.statSync(path), options);
89596
+ }
89597
+ function checkStat(stat2, options) {
89598
+ return stat2.isFile() && checkMode(stat2, options);
89599
+ }
89600
+ function checkMode(stat2, options) {
89601
+ var mod = stat2.mode;
89602
+ var uid = stat2.uid;
89603
+ var gid = stat2.gid;
89604
+ var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
89605
+ var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
89606
+ var u = parseInt("100", 8);
89607
+ var g = parseInt("010", 8);
89608
+ var o = parseInt("001", 8);
89609
+ var ug = u | g;
89610
+ var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
89611
+ return ret;
89612
+ }
89613
+ });
89614
+
89615
+ // ../../node_modules/.bun/isexe@2.0.0/node_modules/isexe/index.js
89616
+ var require_isexe = __commonJS((exports, module) => {
89617
+ var fs = __require("fs");
89618
+ var core2;
89619
+ if (process.platform === "win32" || global.TESTING_WINDOWS) {
89620
+ core2 = require_windows();
89621
+ } else {
89622
+ core2 = require_mode2();
89623
+ }
89624
+ module.exports = isexe;
89625
+ isexe.sync = sync;
89626
+ function isexe(path, options, cb) {
89627
+ if (typeof options === "function") {
89628
+ cb = options;
89629
+ options = {};
89630
+ }
89631
+ if (!cb) {
89632
+ if (typeof Promise !== "function") {
89633
+ throw new TypeError("callback not provided");
89634
+ }
89635
+ return new Promise(function(resolve9, reject) {
89636
+ isexe(path, options || {}, function(er, is) {
89637
+ if (er) {
89638
+ reject(er);
89639
+ } else {
89640
+ resolve9(is);
89641
+ }
89642
+ });
89643
+ });
89644
+ }
89645
+ core2(path, options || {}, function(er, is) {
89646
+ if (er) {
89647
+ if (er.code === "EACCES" || options && options.ignoreErrors) {
89648
+ er = null;
89649
+ is = false;
89650
+ }
89651
+ }
89652
+ cb(er, is);
89653
+ });
89654
+ }
89655
+ function sync(path, options) {
89656
+ try {
89657
+ return core2.sync(path, options || {});
89658
+ } catch (er) {
89659
+ if (options && options.ignoreErrors || er.code === "EACCES") {
89660
+ return false;
89661
+ } else {
89662
+ throw er;
89663
+ }
89664
+ }
89665
+ }
89666
+ });
89667
+
89668
+ // ../../node_modules/.bun/which@2.0.2/node_modules/which/which.js
89669
+ var require_which = __commonJS((exports, module) => {
89670
+ var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
89671
+ var path = __require("path");
89672
+ var COLON = isWindows ? ";" : ":";
89673
+ var isexe = require_isexe();
89674
+ var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
89675
+ var getPathInfo = (cmd, opt) => {
89676
+ const colon = opt.colon || COLON;
89677
+ const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
89678
+ ...isWindows ? [process.cwd()] : [],
89679
+ ...(opt.path || process.env.PATH || "").split(colon)
89680
+ ];
89681
+ const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
89682
+ const pathExt = isWindows ? pathExtExe.split(colon) : [""];
89683
+ if (isWindows) {
89684
+ if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
89685
+ pathExt.unshift("");
89686
+ }
89687
+ return {
89688
+ pathEnv,
89689
+ pathExt,
89690
+ pathExtExe
89691
+ };
89692
+ };
89693
+ var which = (cmd, opt, cb) => {
89694
+ if (typeof opt === "function") {
89695
+ cb = opt;
89696
+ opt = {};
89697
+ }
89698
+ if (!opt)
89699
+ opt = {};
89700
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
89701
+ const found = [];
89702
+ const step = (i) => new Promise((resolve9, reject) => {
89703
+ if (i === pathEnv.length)
89704
+ return opt.all && found.length ? resolve9(found) : reject(getNotFoundError(cmd));
89705
+ const ppRaw = pathEnv[i];
89706
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
89707
+ const pCmd = path.join(pathPart, cmd);
89708
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
89709
+ resolve9(subStep(p, i, 0));
89710
+ });
89711
+ const subStep = (p, i, ii) => new Promise((resolve9, reject) => {
89712
+ if (ii === pathExt.length)
89713
+ return resolve9(step(i + 1));
89714
+ const ext = pathExt[ii];
89715
+ isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
89716
+ if (!er && is) {
89717
+ if (opt.all)
89718
+ found.push(p + ext);
89719
+ else
89720
+ return resolve9(p + ext);
89721
+ }
89722
+ return resolve9(subStep(p, i, ii + 1));
89723
+ });
89724
+ });
89725
+ return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
89726
+ };
89727
+ var whichSync = (cmd, opt) => {
89728
+ opt = opt || {};
89729
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
89730
+ const found = [];
89731
+ for (let i = 0;i < pathEnv.length; i++) {
89732
+ const ppRaw = pathEnv[i];
89733
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
89734
+ const pCmd = path.join(pathPart, cmd);
89735
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
89736
+ for (let j = 0;j < pathExt.length; j++) {
89737
+ const cur = p + pathExt[j];
89738
+ try {
89739
+ const is = isexe.sync(cur, { pathExt: pathExtExe });
89740
+ if (is) {
89741
+ if (opt.all)
89742
+ found.push(cur);
89743
+ else
89744
+ return cur;
89745
+ }
89746
+ } catch (ex) {}
89747
+ }
89748
+ }
89749
+ if (opt.all && found.length)
89750
+ return found;
89751
+ if (opt.nothrow)
89752
+ return null;
89753
+ throw getNotFoundError(cmd);
89754
+ };
89755
+ module.exports = which;
89756
+ which.sync = whichSync;
89757
+ });
89758
+
89759
+ // ../../node_modules/.bun/path-key@3.1.1/node_modules/path-key/index.js
89760
+ var require_path_key = __commonJS((exports, module) => {
89761
+ var pathKey = (options = {}) => {
89762
+ const environment = options.env || process.env;
89763
+ const platform = options.platform || process.platform;
89764
+ if (platform !== "win32") {
89765
+ return "PATH";
89766
+ }
89767
+ return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
89768
+ };
89769
+ module.exports = pathKey;
89770
+ module.exports.default = pathKey;
89771
+ });
89772
+
89773
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js
89774
+ var require_resolveCommand = __commonJS((exports, module) => {
89775
+ var path = __require("path");
89776
+ var which = require_which();
89777
+ var getPathKey = require_path_key();
89778
+ function resolveCommandAttempt(parsed, withoutPathExt) {
89779
+ const env = parsed.options.env || process.env;
89780
+ const cwd = process.cwd();
89781
+ const hasCustomCwd = parsed.options.cwd != null;
89782
+ const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
89783
+ if (shouldSwitchCwd) {
89784
+ try {
89785
+ process.chdir(parsed.options.cwd);
89786
+ } catch (err) {}
89787
+ }
89788
+ let resolved;
89789
+ try {
89790
+ resolved = which.sync(parsed.command, {
89791
+ path: env[getPathKey({ env })],
89792
+ pathExt: withoutPathExt ? path.delimiter : undefined
89793
+ });
89794
+ } catch (e) {} finally {
89795
+ if (shouldSwitchCwd) {
89796
+ process.chdir(cwd);
89797
+ }
89798
+ }
89799
+ if (resolved) {
89800
+ resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
89801
+ }
89802
+ return resolved;
89803
+ }
89804
+ function resolveCommand(parsed) {
89805
+ return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
89806
+ }
89807
+ module.exports = resolveCommand;
89808
+ });
89809
+
89810
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.js
89811
+ var require_escape = __commonJS((exports, module) => {
89812
+ var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
89813
+ function escapeCommand(arg) {
89814
+ arg = arg.replace(metaCharsRegExp, "^$1");
89815
+ return arg;
89816
+ }
89817
+ function escapeArgument(arg, doubleEscapeMetaChars) {
89818
+ arg = `${arg}`;
89819
+ arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
89820
+ arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
89821
+ arg = `"${arg}"`;
89822
+ arg = arg.replace(metaCharsRegExp, "^$1");
89823
+ if (doubleEscapeMetaChars) {
89824
+ arg = arg.replace(metaCharsRegExp, "^$1");
89825
+ }
89826
+ return arg;
89827
+ }
89828
+ exports.command = escapeCommand;
89829
+ exports.argument = escapeArgument;
89830
+ });
89831
+
89832
+ // ../../node_modules/.bun/shebang-regex@3.0.0/node_modules/shebang-regex/index.js
89833
+ var require_shebang_regex = __commonJS((exports, module) => {
89834
+ module.exports = /^#!(.*)/;
89835
+ });
89836
+
89837
+ // ../../node_modules/.bun/shebang-command@2.0.0/node_modules/shebang-command/index.js
89838
+ var require_shebang_command = __commonJS((exports, module) => {
89839
+ var shebangRegex = require_shebang_regex();
89840
+ module.exports = (string4 = "") => {
89841
+ const match = string4.match(shebangRegex);
89842
+ if (!match) {
89843
+ return null;
89844
+ }
89845
+ const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
89846
+ const binary = path.split("/").pop();
89847
+ if (binary === "env") {
89848
+ return argument;
89849
+ }
89850
+ return argument ? `${binary} ${argument}` : binary;
89851
+ };
89852
+ });
89853
+
89854
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js
89855
+ var require_readShebang = __commonJS((exports, module) => {
89856
+ var fs = __require("fs");
89857
+ var shebangCommand = require_shebang_command();
89858
+ function readShebang(command) {
89859
+ const size = 150;
89860
+ const buffer = Buffer.alloc(size);
89861
+ let fd;
89862
+ try {
89863
+ fd = fs.openSync(command, "r");
89864
+ fs.readSync(fd, buffer, 0, size, 0);
89865
+ fs.closeSync(fd);
89866
+ } catch (e) {}
89867
+ return shebangCommand(buffer.toString());
89868
+ }
89869
+ module.exports = readShebang;
89870
+ });
89871
+
89872
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js
89873
+ var require_parse2 = __commonJS((exports, module) => {
89874
+ var path = __require("path");
89875
+ var resolveCommand = require_resolveCommand();
89876
+ var escape = require_escape();
89877
+ var readShebang = require_readShebang();
89878
+ var isWin = process.platform === "win32";
89879
+ var isExecutableRegExp = /\.(?:com|exe)$/i;
89880
+ var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
89881
+ function detectShebang(parsed) {
89882
+ parsed.file = resolveCommand(parsed);
89883
+ const shebang = parsed.file && readShebang(parsed.file);
89884
+ if (shebang) {
89885
+ parsed.args.unshift(parsed.file);
89886
+ parsed.command = shebang;
89887
+ return resolveCommand(parsed);
89888
+ }
89889
+ return parsed.file;
89890
+ }
89891
+ function parseNonShell(parsed) {
89892
+ if (!isWin) {
89893
+ return parsed;
89894
+ }
89895
+ const commandFile = detectShebang(parsed);
89896
+ const needsShell = !isExecutableRegExp.test(commandFile);
89897
+ if (parsed.options.forceShell || needsShell) {
89898
+ const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
89899
+ parsed.command = path.normalize(parsed.command);
89900
+ parsed.command = escape.command(parsed.command);
89901
+ parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
89902
+ const shellCommand = [parsed.command].concat(parsed.args).join(" ");
89903
+ parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
89904
+ parsed.command = process.env.comspec || "cmd.exe";
89905
+ parsed.options.windowsVerbatimArguments = true;
89906
+ }
89907
+ return parsed;
89908
+ }
89909
+ function parse6(command, args, options) {
89910
+ if (args && !Array.isArray(args)) {
89911
+ options = args;
89912
+ args = null;
89913
+ }
89914
+ args = args ? args.slice(0) : [];
89915
+ options = Object.assign({}, options);
89916
+ const parsed = {
89917
+ command,
89918
+ args,
89919
+ options,
89920
+ file: undefined,
89921
+ original: {
89922
+ command,
89923
+ args
89924
+ }
89925
+ };
89926
+ return options.shell ? parsed : parseNonShell(parsed);
89927
+ }
89928
+ module.exports = parse6;
89929
+ });
89930
+
89931
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.js
89932
+ var require_enoent = __commonJS((exports, module) => {
89933
+ var isWin = process.platform === "win32";
89934
+ function notFoundError(original, syscall) {
89935
+ return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
89936
+ code: "ENOENT",
89937
+ errno: "ENOENT",
89938
+ syscall: `${syscall} ${original.command}`,
89939
+ path: original.command,
89940
+ spawnargs: original.args
89941
+ });
89942
+ }
89943
+ function hookChildProcess(cp, parsed) {
89944
+ if (!isWin) {
89945
+ return;
89946
+ }
89947
+ const originalEmit = cp.emit;
89948
+ cp.emit = function(name, arg1) {
89949
+ if (name === "exit") {
89950
+ const err = verifyENOENT(arg1, parsed);
89951
+ if (err) {
89952
+ return originalEmit.call(cp, "error", err);
89953
+ }
89954
+ }
89955
+ return originalEmit.apply(cp, arguments);
89956
+ };
89957
+ }
89958
+ function verifyENOENT(status, parsed) {
89959
+ if (isWin && status === 1 && !parsed.file) {
89960
+ return notFoundError(parsed.original, "spawn");
89961
+ }
89962
+ return null;
89963
+ }
89964
+ function verifyENOENTSync(status, parsed) {
89965
+ if (isWin && status === 1 && !parsed.file) {
89966
+ return notFoundError(parsed.original, "spawnSync");
89967
+ }
89968
+ return null;
89969
+ }
89970
+ module.exports = {
89971
+ hookChildProcess,
89972
+ verifyENOENT,
89973
+ verifyENOENTSync,
89974
+ notFoundError
89975
+ };
89976
+ });
89977
+
89978
+ // ../../node_modules/.bun/cross-spawn@7.0.6/node_modules/cross-spawn/index.js
89979
+ var require_cross_spawn = __commonJS((exports, module) => {
89980
+ var cp = __require("child_process");
89981
+ var parse6 = require_parse2();
89982
+ var enoent = require_enoent();
89983
+ function spawn(command, args, options) {
89984
+ const parsed = parse6(command, args, options);
89985
+ const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
89986
+ enoent.hookChildProcess(spawned, parsed);
89987
+ return spawned;
89988
+ }
89989
+ function spawnSync(command, args, options) {
89990
+ const parsed = parse6(command, args, options);
89991
+ const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
89992
+ result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
89993
+ return result;
89994
+ }
89995
+ module.exports = spawn;
89996
+ module.exports.spawn = spawn;
89997
+ module.exports.sync = spawnSync;
89998
+ module.exports._parse = parse6;
89999
+ module.exports._enoent = enoent;
90000
+ });
90001
+
89546
90002
  // ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
89547
90003
  var require_picocolors = __commonJS((exports, module) => {
89548
90004
  var p = process || {};
@@ -89725,7 +90181,7 @@ __export(exports_prompt_hidden, {
89725
90181
  });
89726
90182
  import { stdin, stdout } from "node:process";
89727
90183
  function promptHiddenWithStreams(question, input, output) {
89728
- return new Promise((resolve7, reject) => {
90184
+ return new Promise((resolve9, reject) => {
89729
90185
  output.write(`${question} `);
89730
90186
  let buf = "";
89731
90187
  let done = false;
@@ -89741,7 +90197,7 @@ function promptHiddenWithStreams(question, input, output) {
89741
90197
  input.removeListener("error", onError);
89742
90198
  output.write(`
89743
90199
  `);
89744
- resolve7(buf.replace(/\r$/, ""));
90200
+ resolve9(buf.replace(/\r$/, ""));
89745
90201
  return;
89746
90202
  }
89747
90203
  buf += ch;
@@ -89763,7 +90219,7 @@ function promptHiddenWithStreams(question, input, output) {
89763
90219
  input.removeListener("error", onError);
89764
90220
  output.write(`
89765
90221
  `);
89766
- resolve7(buf.replace(/\r$/, ""));
90222
+ resolve9(buf.replace(/\r$/, ""));
89767
90223
  };
89768
90224
  input.on("data", onData);
89769
90225
  input.on("error", onError);
@@ -89781,7 +90237,7 @@ async function promptHidden(question) {
89781
90237
  ttyStdin.resume();
89782
90238
  ttyStdin.setEncoding("utf8");
89783
90239
  try {
89784
- return await new Promise((resolve7, reject) => {
90240
+ return await new Promise((resolve9, reject) => {
89785
90241
  stdout.write(`${question} `);
89786
90242
  let buf = "";
89787
90243
  const onData = (key) => {
@@ -89791,7 +90247,7 @@ async function promptHidden(question) {
89791
90247
  ttyStdin.removeListener("data", onData);
89792
90248
  stdout.write(`
89793
90249
  `);
89794
- resolve7(buf);
90250
+ resolve9(buf);
89795
90251
  return;
89796
90252
  }
89797
90253
  if (ch === "\x03") {
@@ -105030,10 +105486,17 @@ function loadConfig() {
105030
105486
  const envToken = process.env.PERCHER_TOKEN;
105031
105487
  return {
105032
105488
  apiUrl: envUrl ?? file2.apiUrl ?? DEFAULT_API_URL,
105033
- token: envToken ?? file2.token ?? null,
105034
- anonClaim: file2.anonClaim ?? null
105489
+ token: envToken ?? file2.token ?? null
105035
105490
  };
105036
105491
  }
105492
+ function readAnonClaims() {
105493
+ const file2 = readFile2();
105494
+ const claims = { ...file2.anonClaims ?? {} };
105495
+ if (file2.anonClaim?.app && !claims[file2.anonClaim.app]) {
105496
+ claims[file2.anonClaim.app] = file2.anonClaim;
105497
+ }
105498
+ return claims;
105499
+ }
105037
105500
  function saveConfig(partial2) {
105038
105501
  const p = configPath();
105039
105502
  mkdirSync3(dirname3(p), { recursive: true });
@@ -105043,6 +105506,21 @@ function saveConfig(partial2) {
105043
105506
  writeFileSync3(tmp, JSON.stringify(merged, null, 2), "utf8");
105044
105507
  renameSync(tmp, p);
105045
105508
  }
105509
+ function getAnonClaim(app) {
105510
+ return readAnonClaims()[app] ?? null;
105511
+ }
105512
+ function setAnonClaim(state) {
105513
+ const claims = { ...readAnonClaims(), [state.app]: state };
105514
+ saveConfig({ anonClaims: claims, anonClaim: null });
105515
+ }
105516
+ function clearAnonClaim(app) {
105517
+ const claims = { ...readAnonClaims() };
105518
+ delete claims[app];
105519
+ saveConfig({ anonClaims: claims, anonClaim: null });
105520
+ }
105521
+ function listAnonClaimApps() {
105522
+ return Object.keys(readAnonClaims());
105523
+ }
105046
105524
 
105047
105525
  // ../client/dist/errors.js
105048
105526
  class PercherApiError extends Error {
@@ -106078,13 +106556,14 @@ var claimInputSchema = exports_external.object({
106078
106556
  claimToken: exports_external.string().optional().describe("The one-time claim token returned by the anonymous publish (pcl_…)")
106079
106557
  });
106080
106558
  async function claim(ctx, input = {}) {
106081
- const state = loadConfig().anonClaim;
106082
- const app = input.app ?? state?.app ?? readPercherTomlAppName(ctx.cwd) ?? undefined;
106083
- const claimToken = input.claimToken ?? state?.claimToken;
106559
+ const tomlApp = readPercherTomlAppName(ctx.cwd) ?? undefined;
106560
+ const remembered = listAnonClaimApps();
106561
+ const app = input.app ?? tomlApp ?? (remembered.length === 1 ? remembered[0] : undefined);
106562
+ const claimToken = input.claimToken ?? (app ? getAnonClaim(app)?.claimToken ?? undefined : undefined);
106084
106563
  if (!app) {
106085
106564
  return {
106086
106565
  status: "needs_token",
106087
- summary: "No app to claim. Pass --app (or run from the project that published it) and the claim token."
106566
+ summary: remembered.length > 1 ? `Multiple anonymous apps are remembered (${remembered.join(", ")}). Pass --app to choose one.` : "No app to claim. Pass --app (or run from the project that published it) and the claim token."
106088
106567
  };
106089
106568
  }
106090
106569
  if (!claimToken) {
@@ -106094,8 +106573,7 @@ async function claim(ctx, input = {}) {
106094
106573
  };
106095
106574
  }
106096
106575
  const result = await ctx.client.apps.claim(app, { claimToken });
106097
- if (state)
106098
- saveConfig({ anonClaim: null });
106576
+ clearAnonClaim(app);
106099
106577
  return {
106100
106578
  status: "claimed",
106101
106579
  app: result.name,
@@ -110410,9 +110888,1332 @@ function collectWarnings2(collections, rlsPolicies, unsupported) {
110410
110888
  }
110411
110889
  return warnings;
110412
110890
  }
110891
+ // ../core/dist/commands/migrate-supabase-rewrite.js
110892
+ import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
110893
+ import { dirname as dirname5, join as join18, relative as relative4, resolve as resolve7 } from "node:path";
110894
+
110895
+ // ../core/dist/commands/migrate-supabase-walker.js
110896
+ var import_ignore3 = __toESM(require_ignore(), 1);
110897
+ import { mkdir as mkdir2, readdir, readFile as readFile3, stat, writeFile as writeFile2 } from "node:fs/promises";
110898
+ import { dirname as dirname4, isAbsolute as isAbsolute2, join as join17, relative as relative3, resolve as resolve6, sep as sep3 } from "node:path";
110899
+
110900
+ // ../core/dist/commands/migrate-supabase-sdk.js
110901
+ var import_jscodeshift = __toESM(require_core3(), 1);
110902
+ var tsx = import_jscodeshift.default.withParser("tsx");
110903
+ function rewriteSupabaseSdk(input) {
110904
+ const pbName = input.pbIdentifier ?? "pb";
110905
+ const supabaseNames = new Set(input.supabaseIdentifiers ?? ["supabase"]);
110906
+ if (!sourceMentionsSupabase(input.source, supabaseNames)) {
110907
+ return { rewritten: input.source, flags: [], changed: false };
110908
+ }
110909
+ let root;
110910
+ try {
110911
+ root = tsx(input.source);
110912
+ } catch (err) {
110913
+ return {
110914
+ rewritten: input.source,
110915
+ flags: [],
110916
+ changed: false,
110917
+ parseError: err instanceof Error ? err.message : String(err)
110918
+ };
110919
+ }
110920
+ const flags = [];
110921
+ const state = { mutated: false };
110922
+ rewriteAuthCalls(root, supabaseNames, pbName, flags, state);
110923
+ rewriteFromCalls(root, supabaseNames, pbName, flags, state);
110924
+ flagUnsupportedPatterns(root, supabaseNames, flags);
110925
+ if (!state.mutated) {
110926
+ return { rewritten: input.source, flags, changed: false };
110927
+ }
110928
+ return {
110929
+ rewritten: root.toSource({ quote: "double" }),
110930
+ flags,
110931
+ changed: true
110932
+ };
110933
+ }
110934
+ function consumesDataErrorEnvelope(path) {
110935
+ let outer = path.node;
110936
+ let outerParent = path.parent?.node;
110937
+ if (outerParent?.type === "AwaitExpression") {
110938
+ const aw = outerParent;
110939
+ if (aw.argument === path.node) {
110940
+ outer = outerParent;
110941
+ outerParent = path.parent.parent?.node;
110942
+ }
110943
+ }
110944
+ if (!outerParent)
110945
+ return false;
110946
+ if (outerParent.type === "MemberExpression") {
110947
+ const m = outerParent;
110948
+ if (m.object === outer && m.property.type === "Identifier") {
110949
+ const propName = m.property.name;
110950
+ if (propName === "data" || propName === "error")
110951
+ return true;
110952
+ }
110953
+ return false;
110954
+ }
110955
+ if (outerParent.type === "VariableDeclarator") {
110956
+ const v = outerParent;
110957
+ if (v.init === outer && v.id.type === "ObjectPattern") {
110958
+ return objectPatternHasDataOrError(v.id);
110959
+ }
110960
+ return false;
110961
+ }
110962
+ if (outerParent.type === "AssignmentExpression") {
110963
+ const a = outerParent;
110964
+ if (a.right === outer && a.left.type === "ObjectPattern") {
110965
+ return objectPatternHasDataOrError(a.left);
110966
+ }
110967
+ return false;
110968
+ }
110969
+ return false;
110970
+ }
110971
+ function objectPatternHasDataOrError(pattern) {
110972
+ for (const prop of pattern.properties) {
110973
+ if ((prop.type === "Property" || prop.type === "ObjectProperty") && "key" in prop && prop.key.type === "Identifier") {
110974
+ const name = prop.key.name;
110975
+ if (name === "data" || name === "error")
110976
+ return true;
110977
+ }
110978
+ }
110979
+ return false;
110980
+ }
110981
+ function flagEnvelopeManualReview(path, pattern, flags) {
110982
+ flags.push(makeFlag(path, "manual_review", `${pattern}.envelope`, `Call site consumes the Supabase \`{ data, error }\` envelope — PocketBase returns plain values. Skipping rewrite; unwrap the destructure (or .data/.error access) manually, then re-run the migrator.`));
110983
+ }
110984
+ function sourceMentionsSupabase(source, supabaseNames) {
110985
+ if (source.includes("@supabase/supabase-js"))
110986
+ return true;
110987
+ for (const name of supabaseNames) {
110988
+ if (source.includes(name))
110989
+ return true;
110990
+ }
110991
+ return false;
110992
+ }
110993
+ function rewriteAuthCalls(root, supabaseNames, pbName, flags, state) {
110994
+ root.find(import_jscodeshift.default.CallExpression).filter((path) => isSupabaseAuthCall(path, supabaseNames)).forEach((path) => {
110995
+ const callee = path.node.callee;
110996
+ const method = callee.property.name;
110997
+ switch (method) {
110998
+ case "signInWithPassword":
110999
+ replaceAuthSignIn(path, pbName, flags, state);
111000
+ return;
111001
+ case "signUp":
111002
+ replaceAuthSignUp(path, pbName, flags, state);
111003
+ return;
111004
+ case "signOut":
111005
+ replaceAuthSignOut(path, pbName, flags, state);
111006
+ return;
111007
+ case "getUser":
111008
+ replaceAuthGetUser(path, pbName, flags, state);
111009
+ return;
111010
+ case "onAuthStateChange":
111011
+ replaceAuthOnChange(path, pbName, flags, state);
111012
+ return;
111013
+ }
111014
+ });
111015
+ }
111016
+ function replaceAuthOnChange(path, pbName, flags, state) {
111017
+ const callback = path.node.arguments[0];
111018
+ if (!callback) {
111019
+ flags.push(makeFlag(path, "manual_review", "auth.onAuthStateChange", "onAuthStateChange called with no args — manual review."));
111020
+ return;
111021
+ }
111022
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("authStore")), import_jscodeshift.default.identifier("onChange")), [callback]);
111023
+ applyRewrite(path, replacement, "manual_review", "auth.onAuthStateChange", "onAuthStateChange → pb.authStore.onChange — the callback signature changes: Supabase passes `(event, session)`, PB passes `(token, model)`. Rewrite the callback body.", flags, state);
111024
+ }
111025
+ function isSupabaseAuthCall(path, supabaseNames) {
111026
+ const callee = path.node.callee;
111027
+ if (callee.type !== "MemberExpression")
111028
+ return false;
111029
+ if (callee.property.type !== "Identifier")
111030
+ return false;
111031
+ const object2 = callee.object;
111032
+ if (object2.type !== "MemberExpression")
111033
+ return false;
111034
+ if (object2.property.type !== "Identifier" || object2.property.name !== "auth")
111035
+ return false;
111036
+ if (object2.object.type !== "Identifier")
111037
+ return false;
111038
+ return supabaseNames.has(object2.object.name);
111039
+ }
111040
+ function replaceAuthSignIn(path, pbName, flags, state) {
111041
+ const arg = path.node.arguments[0];
111042
+ if (arg?.type !== "ObjectExpression") {
111043
+ flags.push(makeFlag(path, "manual_review", "auth.signInWithPassword", "auth.signInWithPassword called with non-object argument — manual review needed."));
111044
+ return;
111045
+ }
111046
+ const emailExpr = findObjectProp(arg, "email");
111047
+ const passwordExpr = findObjectProp(arg, "password");
111048
+ if (!emailExpr || !passwordExpr) {
111049
+ flags.push(makeFlag(path, "manual_review", "auth.signInWithPassword", "auth.signInWithPassword object missing email or password — manual review needed."));
111050
+ return;
111051
+ }
111052
+ if (consumesDataErrorEnvelope(path)) {
111053
+ flagEnvelopeManualReview(path, "auth.signInWithPassword", flags);
111054
+ return;
111055
+ }
111056
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal("users")]), import_jscodeshift.default.identifier("authWithPassword")), [emailExpr, passwordExpr]);
111057
+ applyRewrite(path, replacement, "rewritten", "auth.signInWithPassword", 'signInWithPassword → pb.collection("users").authWithPassword', flags, state);
111058
+ }
111059
+ function replaceAuthSignUp(path, pbName, flags, state) {
111060
+ const arg = path.node.arguments[0];
111061
+ if (arg?.type !== "ObjectExpression") {
111062
+ flags.push(makeFlag(path, "manual_review", "auth.signUp", "auth.signUp called with non-object argument — manual review needed."));
111063
+ return;
111064
+ }
111065
+ const emailExpr = findObjectProp(arg, "email");
111066
+ const passwordExpr = findObjectProp(arg, "password");
111067
+ if (!emailExpr || !passwordExpr) {
111068
+ flags.push(makeFlag(path, "manual_review", "auth.signUp", "auth.signUp object missing email or password — manual review needed."));
111069
+ return;
111070
+ }
111071
+ if (consumesDataErrorEnvelope(path)) {
111072
+ flagEnvelopeManualReview(path, "auth.signUp", flags);
111073
+ return;
111074
+ }
111075
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal("users")]), import_jscodeshift.default.identifier("create")), [
111076
+ import_jscodeshift.default.objectExpression([
111077
+ import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("email"), emailExpr),
111078
+ import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("password"), passwordExpr),
111079
+ import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("passwordConfirm"), passwordExpr)
111080
+ ])
111081
+ ]);
111082
+ applyRewrite(path, replacement, "rewritten", "auth.signUp", 'signUp → pb.collection("users").create({...passwordConfirm})', flags, state);
111083
+ }
111084
+ function replaceAuthSignOut(path, pbName, flags, state) {
111085
+ if (consumesDataErrorEnvelope(path)) {
111086
+ flagEnvelopeManualReview(path, "auth.signOut", flags);
111087
+ return;
111088
+ }
111089
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("authStore")), import_jscodeshift.default.identifier("clear")), []);
111090
+ applyRewrite(path, replacement, "rewritten", "auth.signOut", "signOut → pb.authStore.clear()", flags, state);
111091
+ }
111092
+ function replaceAuthGetUser(path, pbName, flags, state) {
111093
+ if (consumesDataErrorEnvelope(path)) {
111094
+ flagEnvelopeManualReview(path, "auth.getUser", flags);
111095
+ return;
111096
+ }
111097
+ const replacement = import_jscodeshift.default.memberExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("authStore")), import_jscodeshift.default.identifier("model"));
111098
+ applyRewrite(path, replacement, "manual_review", "auth.getUser", "getUser → pb.authStore.model — note Supabase returned Promise<{ data: { user } }>, PB returns the record sync; remove awaits + .data.user access.", flags, state);
111099
+ }
111100
+ function rewriteFromCalls(root, supabaseNames, pbName, flags, state) {
111101
+ root.find(import_jscodeshift.default.CallExpression).filter((path) => isSupabaseFromTerminal(path, supabaseNames)).forEach((path) => {
111102
+ rewriteFromChain(path, supabaseNames, pbName, flags, state);
111103
+ });
111104
+ }
111105
+ function isSupabaseFromTerminal(path, supabaseNames) {
111106
+ let fromCall = null;
111107
+ let cursor = path.node;
111108
+ while (cursor.type === "CallExpression") {
111109
+ const call = cursor;
111110
+ if (call.callee.type !== "MemberExpression")
111111
+ break;
111112
+ const callee = call.callee;
111113
+ if (callee.property.type === "Identifier" && callee.property.name === "from") {
111114
+ fromCall = call;
111115
+ break;
111116
+ }
111117
+ cursor = callee.object;
111118
+ }
111119
+ if (!fromCall)
111120
+ return false;
111121
+ const fromCallee = fromCall.callee;
111122
+ if (fromCallee.object.type !== "Identifier")
111123
+ return false;
111124
+ if (!supabaseNames.has(fromCallee.object.name))
111125
+ return false;
111126
+ const parent = path.parent?.node;
111127
+ if (parent?.type === "MemberExpression") {
111128
+ const parentMember = parent;
111129
+ if (parentMember.object === path.node)
111130
+ return false;
111131
+ }
111132
+ return true;
111133
+ }
111134
+ function rewriteFromChain(path, _supabaseNames, pbName, flags, state) {
111135
+ const decomposed = decomposeFromChain(path.node);
111136
+ if (!decomposed) {
111137
+ flags.push(makeFlag(path, "manual_review", "from.chain", "Couldn't decompose .from() chain shape — manual review."));
111138
+ return;
111139
+ }
111140
+ const { table, steps } = decomposed;
111141
+ const terminal = steps[0];
111142
+ if (!terminal) {
111143
+ return;
111144
+ }
111145
+ switch (terminal.method) {
111146
+ case "select":
111147
+ rewriteSelect(path, pbName, table, steps, flags, state);
111148
+ return;
111149
+ case "insert":
111150
+ rewriteInsert(path, pbName, table, terminal, flags, state);
111151
+ return;
111152
+ case "update":
111153
+ rewriteUpdate(path, pbName, table, steps, flags, state);
111154
+ return;
111155
+ case "delete":
111156
+ rewriteDelete(path, pbName, table, steps, flags, state);
111157
+ return;
111158
+ case "upsert":
111159
+ flags.push(makeFlag(path, "unsupported", "from.upsert", `from(${JSON.stringify(table)}).upsert(...) — PB has no upsert primitive. Rewrite as getOne (catch 404) → update-or-create.`));
111160
+ return;
111161
+ default:
111162
+ flags.push(makeFlag(path, "manual_review", `from.${terminal.method}`, `from(${JSON.stringify(table)}).${terminal.method}(...) has no chunk-1 rewrite — manual review.`));
111163
+ }
111164
+ }
111165
+ function decomposeFromChain(outer) {
111166
+ const reversedSteps = [];
111167
+ let node = outer;
111168
+ while (node.type === "CallExpression") {
111169
+ const call = node;
111170
+ if (call.callee.type !== "MemberExpression")
111171
+ break;
111172
+ const callee = call.callee;
111173
+ const method = callee.property.type === "Identifier" ? callee.property.name : null;
111174
+ if (method === null)
111175
+ return null;
111176
+ if (method === "from") {
111177
+ const arg = call.arguments[0];
111178
+ if (!arg || arg.type !== "Literal" && arg.type !== "StringLiteral")
111179
+ return null;
111180
+ const table = arg.value;
111181
+ if (typeof table !== "string")
111182
+ return null;
111183
+ return { table, steps: reversedSteps.reverse() };
111184
+ }
111185
+ reversedSteps.push({ method, args: call.arguments });
111186
+ node = callee.object;
111187
+ }
111188
+ return null;
111189
+ }
111190
+ function rewriteSelect(path, pbName, table, steps, flags, state) {
111191
+ if (consumesDataErrorEnvelope(path)) {
111192
+ flagEnvelopeManualReview(path, "from.select", flags);
111193
+ return;
111194
+ }
111195
+ const select = steps[0];
111196
+ if (!select)
111197
+ return;
111198
+ const tail = steps.slice(1);
111199
+ const opts = {};
111200
+ let needsReview = false;
111201
+ const reviewNotes = [];
111202
+ let usePagination = false;
111203
+ let paginationPage = 1;
111204
+ let paginationPerPage = 0;
111205
+ const fieldsValue = extractSelectFields(select);
111206
+ if (fieldsValue !== null)
111207
+ opts.fields = import_jscodeshift.default.literal(fieldsValue);
111208
+ for (const step of tail) {
111209
+ switch (step.method) {
111210
+ case "eq": {
111211
+ const result = buildEqFilter(step);
111212
+ if (!result) {
111213
+ needsReview = true;
111214
+ reviewNotes.push(`.eq() arguments not in the (column-literal, value) shape — manual review.`);
111215
+ continue;
111216
+ }
111217
+ opts.filter = result.identifierValue ? combineFilterDynamic(opts.filter, result.expression) : combineFilterStatic(opts.filter, result.expression);
111218
+ if (result.identifierValue) {
111219
+ needsReview = true;
111220
+ reviewNotes.push(`.eq(${JSON.stringify(result.column)}, <identifier>) — verify the value is escape-safe for PB filter strings (no double-quotes / backslashes).`);
111221
+ }
111222
+ break;
111223
+ }
111224
+ case "order": {
111225
+ const sortFrag = buildSortFragment(step);
111226
+ if (!sortFrag) {
111227
+ needsReview = true;
111228
+ reviewNotes.push(`.order() arguments not in the recognised shape — manual review.`);
111229
+ continue;
111230
+ }
111231
+ opts.sort = import_jscodeshift.default.literal(opts.sort ? `${literalString(opts.sort)},${sortFrag}` : sortFrag);
111232
+ break;
111233
+ }
111234
+ case "limit": {
111235
+ const arg = step.args[0];
111236
+ const n = extractNumber(arg);
111237
+ if (n === null) {
111238
+ needsReview = true;
111239
+ reviewNotes.push(`.limit() argument isn't a literal number — manual review.`);
111240
+ continue;
111241
+ }
111242
+ if (n <= 0) {
111243
+ flags.push(makeFlag(path, "manual_review", "from.select.limit_invalid", `from(${JSON.stringify(table)}).select(...).limit(${n}) — non-positive limit doesn't translate to PB pagination. Manual review.`));
111244
+ return;
111245
+ }
111246
+ usePagination = true;
111247
+ paginationPerPage = Math.max(paginationPerPage, n);
111248
+ break;
111249
+ }
111250
+ case "range": {
111251
+ const startArg = step.args[0];
111252
+ const endArg = step.args[1];
111253
+ const startN = extractNumber(startArg);
111254
+ const endN = extractNumber(endArg);
111255
+ if (startN === null || endN === null) {
111256
+ needsReview = true;
111257
+ reviewNotes.push(`.range() arguments aren't literal numbers — manual review.`);
111258
+ continue;
111259
+ }
111260
+ const perPage = endN - startN + 1;
111261
+ if (perPage <= 0) {
111262
+ flags.push(makeFlag(path, "manual_review", "from.select.range_invalid", `from(${JSON.stringify(table)}).select(...).range(${startN}, ${endN}) — end < start; PB pagination has no equivalent. Manual review.`));
111263
+ return;
111264
+ }
111265
+ usePagination = true;
111266
+ paginationPerPage = Math.max(paginationPerPage, perPage);
111267
+ if (startN === 0) {
111268
+ paginationPage = 1;
111269
+ } else if (startN % perPage === 0) {
111270
+ paginationPage = Math.floor(startN / perPage) + 1;
111271
+ } else {
111272
+ needsReview = true;
111273
+ reviewNotes.push(`.range(${startN}, ${endN}) — start isn't on a page boundary; PB's page math doesn't translate cleanly. Manual review.`);
111274
+ }
111275
+ break;
111276
+ }
111277
+ case "single": {
111278
+ flags.push(makeFlag(path, "manual_review", "from.select.single", `from(${JSON.stringify(table)}).select(...).single() — PB's getFullList returns an array; getFirstListItem(filter) is the single-record equivalent but takes a filter string. Rewrite this chain by hand: pick getFirstListItem with the right filter OR [0]-index the array result.`));
111279
+ return;
111280
+ }
111281
+ default: {
111282
+ flags.push(makeFlag(path, "manual_review", `from.select.${step.method}`, `from(${JSON.stringify(table)}).select(...).${step.method}(...) has no chunk-2 rewrite — manual review.`));
111283
+ return;
111284
+ }
111285
+ }
111286
+ }
111287
+ let methodName;
111288
+ let methodArgs;
111289
+ if (usePagination) {
111290
+ methodName = "getList";
111291
+ const trailingOpts = buildOptionsObject(opts);
111292
+ methodArgs = [import_jscodeshift.default.literal(paginationPage), import_jscodeshift.default.literal(paginationPerPage)];
111293
+ if (trailingOpts)
111294
+ methodArgs.push(trailingOpts);
111295
+ } else {
111296
+ methodName = "getFullList";
111297
+ const optsObj = buildOptionsObject(opts);
111298
+ methodArgs = optsObj ? [optsObj] : [];
111299
+ }
111300
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal(table)]), import_jscodeshift.default.identifier(methodName)), methodArgs);
111301
+ const kind = needsReview ? "manual_review" : "rewritten";
111302
+ const baseNote = `from(${JSON.stringify(table)}).select(...) → pb.collection(...).${methodName}(...)`;
111303
+ const note = needsReview ? `${baseNote} — ${reviewNotes.join(" · ")}` : baseNote;
111304
+ applyRewrite(path, replacement, kind, "from.select", note, flags, state);
111305
+ }
111306
+ function extractSelectFields(select) {
111307
+ const first = select.args[0];
111308
+ if (!first)
111309
+ return null;
111310
+ if ((first.type === "Literal" || first.type === "StringLiteral") && typeof first.value === "string") {
111311
+ const val = first.value;
111312
+ if (val === "*" || val.length === 0)
111313
+ return null;
111314
+ return val;
111315
+ }
111316
+ return null;
111317
+ }
111318
+ function buildEqFilter(step) {
111319
+ const colArg = step.args[0];
111320
+ const valArg = step.args[1];
111321
+ if (!colArg || !valArg)
111322
+ return null;
111323
+ if (!(colArg.type === "Literal" || colArg.type === "StringLiteral") || typeof colArg.value !== "string") {
111324
+ return null;
111325
+ }
111326
+ const column = colArg.value;
111327
+ if (valArg.type === "Literal" || valArg.type === "StringLiteral" || valArg.type === "NumericLiteral" || valArg.type === "BooleanLiteral") {
111328
+ const v = valArg.value;
111329
+ if (typeof v === "string") {
111330
+ return {
111331
+ expression: import_jscodeshift.default.literal(`${column} = "${escapeFilterString(v)}"`),
111332
+ column,
111333
+ identifierValue: false
111334
+ };
111335
+ }
111336
+ if (typeof v === "number" || typeof v === "boolean") {
111337
+ return {
111338
+ expression: import_jscodeshift.default.literal(`${column} = ${v}`),
111339
+ column,
111340
+ identifierValue: false
111341
+ };
111342
+ }
111343
+ return null;
111344
+ }
111345
+ const template = import_jscodeshift.default.templateLiteral([
111346
+ import_jscodeshift.default.templateElement({ raw: `${column} = "`, cooked: `${column} = "` }, false),
111347
+ import_jscodeshift.default.templateElement({ raw: `"`, cooked: `"` }, true)
111348
+ ], [valArg]);
111349
+ return {
111350
+ expression: template,
111351
+ column,
111352
+ identifierValue: true
111353
+ };
111354
+ }
111355
+ function escapeFilterString(s) {
111356
+ return s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
111357
+ }
111358
+ function combineFilterStatic(current, next) {
111359
+ if (!current)
111360
+ return next;
111361
+ const a = literalString(current);
111362
+ const b = literalString(next);
111363
+ if (a !== null && b !== null) {
111364
+ return import_jscodeshift.default.literal(`(${a}) && (${b})`);
111365
+ }
111366
+ return combineFilterDynamic(current, next);
111367
+ }
111368
+ function combineFilterDynamic(current, next) {
111369
+ if (!current)
111370
+ return next;
111371
+ return import_jscodeshift.default.templateLiteral([
111372
+ import_jscodeshift.default.templateElement({ raw: "(", cooked: "(" }, false),
111373
+ import_jscodeshift.default.templateElement({ raw: ") && (", cooked: ") && (" }, false),
111374
+ import_jscodeshift.default.templateElement({ raw: ")", cooked: ")" }, true)
111375
+ ], [current, next]);
111376
+ }
111377
+ function literalString(node) {
111378
+ if (node?.type === "Literal" || node?.type === "StringLiteral") {
111379
+ const v = node.value;
111380
+ if (typeof v === "string")
111381
+ return v;
111382
+ }
111383
+ return null;
111384
+ }
111385
+ function buildSortFragment(step) {
111386
+ const colArg = step.args[0];
111387
+ if (!colArg)
111388
+ return null;
111389
+ if (!(colArg.type === "Literal" || colArg.type === "StringLiteral") || typeof colArg.value !== "string") {
111390
+ return null;
111391
+ }
111392
+ const column = colArg.value;
111393
+ let ascending = true;
111394
+ if (step.args.length >= 2) {
111395
+ const opts = step.args[1];
111396
+ if (opts?.type === "ObjectExpression") {
111397
+ const ascProp = findObjectProp(opts, "ascending");
111398
+ if (ascProp?.type === "Literal" || ascProp?.type === "BooleanLiteral") {
111399
+ ascending = ascProp.value === true;
111400
+ } else if (ascProp) {
111401
+ return null;
111402
+ }
111403
+ }
111404
+ }
111405
+ return ascending ? column : `-${column}`;
111406
+ }
111407
+ function extractNumber(node) {
111408
+ if (!node)
111409
+ return null;
111410
+ if (node.type === "Literal" || node.type === "NumericLiteral") {
111411
+ const v = node.value;
111412
+ if (typeof v === "number")
111413
+ return v;
111414
+ }
111415
+ if (node.type === "UnaryExpression") {
111416
+ const u = node;
111417
+ if (u.operator === "-") {
111418
+ const inner = extractNumber(u.argument);
111419
+ if (inner !== null)
111420
+ return -inner;
111421
+ }
111422
+ }
111423
+ return null;
111424
+ }
111425
+ function buildOptionsObject(opts) {
111426
+ const props = [];
111427
+ if (opts.fields !== undefined) {
111428
+ props.push(import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("fields"), opts.fields));
111429
+ }
111430
+ if (opts.filter !== undefined) {
111431
+ props.push(import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("filter"), opts.filter));
111432
+ }
111433
+ if (opts.sort !== undefined) {
111434
+ props.push(import_jscodeshift.default.property("init", import_jscodeshift.default.identifier("sort"), opts.sort));
111435
+ }
111436
+ if (props.length === 0)
111437
+ return null;
111438
+ return import_jscodeshift.default.objectExpression(props);
111439
+ }
111440
+ function rewriteInsert(path, pbName, table, insert, flags, state) {
111441
+ if (consumesDataErrorEnvelope(path)) {
111442
+ flagEnvelopeManualReview(path, "from.insert", flags);
111443
+ return;
111444
+ }
111445
+ const arg = insert.args[0];
111446
+ if (!arg) {
111447
+ flags.push(makeFlag(path, "manual_review", "from.insert", "from(...).insert() called with no args — manual review."));
111448
+ return;
111449
+ }
111450
+ if (arg.type === "ArrayExpression") {
111451
+ flags.push(makeFlag(path, "manual_review", "from.insert.array", `from(${JSON.stringify(table)}).insert([...]) — PB's create takes one record at a time; wrap in a loop.`));
111452
+ return;
111453
+ }
111454
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal(table)]), import_jscodeshift.default.identifier("create")), [arg]);
111455
+ applyRewrite(path, replacement, "rewritten", "from.insert", `from(${JSON.stringify(table)}).insert({...}) → pb.collection(...).create({...})`, flags, state);
111456
+ }
111457
+ function rewriteUpdate(path, pbName, table, steps, flags, state) {
111458
+ if (consumesDataErrorEnvelope(path)) {
111459
+ flagEnvelopeManualReview(path, "from.update", flags);
111460
+ return;
111461
+ }
111462
+ const update = steps[0];
111463
+ const eq = steps[1];
111464
+ if (steps.length !== 2 || !update || !eq || eq.method !== "eq") {
111465
+ flags.push(makeFlag(path, "manual_review", "from.update.shape", `from(${JSON.stringify(table)}).update(...) chain isn't the .update({...}).eq("id", v) shape — manual review.`));
111466
+ return;
111467
+ }
111468
+ const eqCol = eq.args[0];
111469
+ const eqVal = eq.args[1];
111470
+ if (!eqCol || !eqVal) {
111471
+ flags.push(makeFlag(path, "manual_review", "from.update.eq", "update().eq(...) call missing args — manual review."));
111472
+ return;
111473
+ }
111474
+ if (!((eqCol.type === "Literal" || eqCol.type === "StringLiteral") && eqCol.value === "id")) {
111475
+ flags.push(makeFlag(path, "manual_review", "from.update.eq_non_id", `from(${JSON.stringify(table)}).update().eq() filters on a non-id column — PB's update needs an id; chunk 2 will handle filter-based updates.`));
111476
+ return;
111477
+ }
111478
+ const updateArg = update.args[0];
111479
+ if (!updateArg) {
111480
+ flags.push(makeFlag(path, "manual_review", "from.update", "update() called with no args — manual review."));
111481
+ return;
111482
+ }
111483
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal(table)]), import_jscodeshift.default.identifier("update")), [eqVal, updateArg]);
111484
+ applyRewrite(path, replacement, "rewritten", "from.update", `from(${JSON.stringify(table)}).update({...}).eq("id", v) → pb.collection(...).update(v, {...})`, flags, state);
111485
+ }
111486
+ function rewriteDelete(path, pbName, table, steps, flags, state) {
111487
+ if (consumesDataErrorEnvelope(path)) {
111488
+ flagEnvelopeManualReview(path, "from.delete", flags);
111489
+ return;
111490
+ }
111491
+ const eq = steps[1];
111492
+ if (steps.length !== 2 || !eq || eq.method !== "eq") {
111493
+ flags.push(makeFlag(path, "manual_review", "from.delete.shape", `from(${JSON.stringify(table)}).delete() chain isn't the .delete().eq("id", v) shape — manual review.`));
111494
+ return;
111495
+ }
111496
+ const eqCol = eq.args[0];
111497
+ const eqVal = eq.args[1];
111498
+ if (!eqCol || !eqVal) {
111499
+ flags.push(makeFlag(path, "manual_review", "from.delete.eq", "delete().eq(...) call missing args — manual review."));
111500
+ return;
111501
+ }
111502
+ if (!((eqCol.type === "Literal" || eqCol.type === "StringLiteral") && eqCol.value === "id")) {
111503
+ flags.push(makeFlag(path, "manual_review", "from.delete.eq_non_id", `from(${JSON.stringify(table)}).delete().eq() filters on a non-id column — PB's delete needs an id; chunk 2 will handle filter-based deletes.`));
111504
+ return;
111505
+ }
111506
+ const replacement = import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.callExpression(import_jscodeshift.default.memberExpression(import_jscodeshift.default.identifier(pbName), import_jscodeshift.default.identifier("collection")), [import_jscodeshift.default.literal(table)]), import_jscodeshift.default.identifier("delete")), [eqVal]);
111507
+ applyRewrite(path, replacement, "rewritten", "from.delete", `from(${JSON.stringify(table)}).delete().eq("id", v) → pb.collection(...).delete(v)`, flags, state);
111508
+ }
111509
+ function flagUnsupportedPatterns(root, supabaseNames, flags) {
111510
+ root.find(import_jscodeshift.default.CallExpression).forEach((path) => {
111511
+ flagOneUnsupported(path, supabaseNames, flags);
111512
+ });
111513
+ }
111514
+ function flagOneUnsupported(path, supabaseNames, flags) {
111515
+ const root = findChainRoot(path.node);
111516
+ if (!root)
111517
+ return;
111518
+ if (root.type !== "Identifier")
111519
+ return;
111520
+ if (!supabaseNames.has(root.name))
111521
+ return;
111522
+ const parent = path.parent?.node;
111523
+ if (parent?.type === "MemberExpression") {
111524
+ const m = parent;
111525
+ if (m.object === path.node)
111526
+ return;
111527
+ }
111528
+ const steps = readChainSteps(path.node);
111529
+ const first = steps[0];
111530
+ if (!first)
111531
+ return;
111532
+ if (first.method === "storage") {
111533
+ const opStep = findStorageOperation(steps);
111534
+ const opName = opStep?.method ?? "from";
111535
+ flags.push(makeFlag(path, "unsupported", `storage.${opName}`, `supabase.storage.<bucket>.${opName}(...) — PocketBase models files as record-attached fields, not standalone buckets. Rewrite by hand: create a collection with a \`file\` field, then use pb.collection(c).create({ file: blob }) for uploads and pb.files.getURL(record, record.file) for URLs.`));
111536
+ return;
111537
+ }
111538
+ if (first.method === "channel") {
111539
+ flags.push(makeFlag(path, "unsupported", "channel.subscribe", `supabase.channel(...).on(...).subscribe(...) — PB has realtime via pb.collection(c).subscribe("*", cb) but the event shape and filter model differ from Supabase channels. Rewrite by hand.`));
111540
+ return;
111541
+ }
111542
+ if (first.method === "rpc") {
111543
+ const fnName = first.call ? readFirstStringArg(first.call) ?? "<unknown>" : "<unknown>";
111544
+ flags.push(makeFlag(path, "unsupported", "rpc", `supabase.rpc(${JSON.stringify(fnName)}, ...) — Postgres function calls don't have a PocketBase equivalent. Move the logic into your app server code OR a PB hook (.pb_hooks/).`));
111545
+ return;
111546
+ }
111547
+ const invokeStep = steps[1];
111548
+ if (first.method === "functions" && invokeStep?.method === "invoke") {
111549
+ const fnName = invokeStep.call ? readFirstStringArg(invokeStep.call) ?? "<unknown>" : "<unknown>";
111550
+ flags.push(makeFlag(path, "unsupported", "functions.invoke", `supabase.functions.invoke(${JSON.stringify(fnName)}, ...) — Edge Functions don't run on Percher. Move the function code into the Percher app server, or host it on a separate platform (Deno Deploy, Cloudflare Workers) and call it via fetch.`));
111551
+ return;
111552
+ }
111553
+ }
111554
+ var STORAGE_OPERATIONS = new Set([
111555
+ "upload",
111556
+ "uploadToSignedUrl",
111557
+ "download",
111558
+ "list",
111559
+ "remove",
111560
+ "move",
111561
+ "copy",
111562
+ "createSignedUrl",
111563
+ "createSignedUrls",
111564
+ "createSignedUploadUrl",
111565
+ "getPublicUrl",
111566
+ "update",
111567
+ "exists",
111568
+ "info"
111569
+ ]);
111570
+ var CHAIN_CONTINUATIONS = new Set(["then", "catch", "finally"]);
111571
+ function findStorageOperation(steps) {
111572
+ for (const step of steps) {
111573
+ if (STORAGE_OPERATIONS.has(step.method))
111574
+ return step;
111575
+ }
111576
+ for (let i = steps.length - 1;i >= 0; i--) {
111577
+ const step = steps[i];
111578
+ if (!step)
111579
+ continue;
111580
+ if (step.method === "storage" || step.method === "from")
111581
+ continue;
111582
+ if (CHAIN_CONTINUATIONS.has(step.method))
111583
+ continue;
111584
+ return step;
111585
+ }
111586
+ return null;
111587
+ }
111588
+ function findChainRoot(node) {
111589
+ let cursor = node;
111590
+ while (true) {
111591
+ if (cursor.type === "CallExpression") {
111592
+ const c = cursor;
111593
+ if (c.callee.type !== "MemberExpression")
111594
+ return null;
111595
+ cursor = c.callee.object;
111596
+ continue;
111597
+ }
111598
+ if (cursor.type === "MemberExpression") {
111599
+ cursor = cursor.object;
111600
+ continue;
111601
+ }
111602
+ return cursor;
111603
+ }
111604
+ }
111605
+ function readChainSteps(outer) {
111606
+ const reversed = [];
111607
+ let cursor = outer;
111608
+ while (true) {
111609
+ if (cursor.type === "CallExpression") {
111610
+ const call = cursor;
111611
+ if (call.callee.type !== "MemberExpression")
111612
+ break;
111613
+ const callee = call.callee;
111614
+ if (callee.property.type === "Identifier") {
111615
+ reversed.push({
111616
+ method: callee.property.name,
111617
+ call
111618
+ });
111619
+ }
111620
+ cursor = callee.object;
111621
+ continue;
111622
+ }
111623
+ if (cursor.type === "MemberExpression") {
111624
+ const m = cursor;
111625
+ if (m.property.type === "Identifier") {
111626
+ reversed.push({
111627
+ method: m.property.name,
111628
+ call: null
111629
+ });
111630
+ }
111631
+ cursor = m.object;
111632
+ continue;
111633
+ }
111634
+ break;
111635
+ }
111636
+ return reversed.reverse();
111637
+ }
111638
+ function readFirstStringArg(call) {
111639
+ const a = call.arguments[0];
111640
+ if (!a)
111641
+ return null;
111642
+ if (a.type === "Literal" || a.type === "StringLiteral") {
111643
+ const v = a.value;
111644
+ if (typeof v === "string")
111645
+ return v;
111646
+ }
111647
+ return null;
111648
+ }
111649
+ function findObjectProp(obj, name) {
111650
+ for (const prop of obj.properties) {
111651
+ if ((prop.type === "Property" || prop.type === "ObjectProperty") && "key" in prop && prop.key.type === "Identifier" && prop.key.name === name) {
111652
+ if (prop.shorthand === true) {
111653
+ return import_jscodeshift.default.identifier(name);
111654
+ }
111655
+ if ("value" in prop) {
111656
+ const val = prop.value;
111657
+ if (val.type !== "SpreadElement" && val.type !== "RestElement") {
111658
+ return val;
111659
+ }
111660
+ }
111661
+ }
111662
+ }
111663
+ return null;
111664
+ }
111665
+ function makeFlag(pathOrLoc, kind, pattern, note) {
111666
+ let line;
111667
+ let column;
111668
+ if ("node" in pathOrLoc) {
111669
+ const loc = pathOrLoc.node.loc;
111670
+ line = loc?.start.line;
111671
+ column = loc?.start.column;
111672
+ } else {
111673
+ line = pathOrLoc.line;
111674
+ column = pathOrLoc.column;
111675
+ }
111676
+ return { kind, pattern, line, column, note };
111677
+ }
111678
+ function captureLoc(path) {
111679
+ const loc = path.node.loc;
111680
+ return { line: loc?.start.line, column: loc?.start.column };
111681
+ }
111682
+ function applyRewrite(path, replacement, kind, pattern, note, flags, state) {
111683
+ const loc = captureLoc(path);
111684
+ path.replace(replacement);
111685
+ flags.push(makeFlag(loc, kind, pattern, note));
111686
+ state.mutated = true;
111687
+ }
111688
+
111689
+ // ../core/dist/commands/migrate-supabase-walker.js
111690
+ var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
111691
+ var DEFAULT_EXCLUDES = [
111692
+ "node_modules",
111693
+ ".git",
111694
+ "dist",
111695
+ "build",
111696
+ ".next",
111697
+ ".svelte-kit",
111698
+ ".astro",
111699
+ ".nuxt",
111700
+ ".output",
111701
+ "coverage",
111702
+ ".bun",
111703
+ ".cache",
111704
+ ".turbo",
111705
+ "migration-preview",
111706
+ "pb_data",
111707
+ "pb_migrations"
111708
+ ];
111709
+ async function walkSupabaseProject(input) {
111710
+ const rootAbs = resolve6(input.rootDir);
111711
+ const ig = import_ignore3.default().add(DEFAULT_EXCLUDES);
111712
+ if (input.extraExcludes && input.extraExcludes.length > 0) {
111713
+ ig.add(input.extraExcludes);
111714
+ }
111715
+ const files = [];
111716
+ const skipped = [];
111717
+ for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
111718
+ const rel = relative3(rootAbs, absPath).split(sep3).join("/");
111719
+ const kind = classifyFile2(rel);
111720
+ if (kind === null)
111721
+ continue;
111722
+ let source;
111723
+ try {
111724
+ source = await readFile3(absPath, "utf8");
111725
+ } catch (err) {
111726
+ skipped.push({
111727
+ relativePath: rel,
111728
+ reason: "read_error",
111729
+ detail: err instanceof Error ? err.message : String(err)
111730
+ });
111731
+ continue;
111732
+ }
111733
+ if (looksBinary(source)) {
111734
+ skipped.push({ relativePath: rel, reason: "binary" });
111735
+ continue;
111736
+ }
111737
+ if (kind === "code") {
111738
+ const sdkResult = rewriteSupabaseSdk({
111739
+ source,
111740
+ filePath: rel,
111741
+ pbIdentifier: input.pbIdentifier,
111742
+ supabaseIdentifiers: input.supabaseIdentifiers
111743
+ });
111744
+ if (sdkResult.parseError !== undefined) {
111745
+ skipped.push({
111746
+ relativePath: rel,
111747
+ reason: "parse_error",
111748
+ detail: sdkResult.parseError
111749
+ });
111750
+ continue;
111751
+ }
111752
+ files.push({
111753
+ relativePath: rel,
111754
+ kind,
111755
+ source,
111756
+ rewritten: sdkResult.rewritten,
111757
+ changed: sdkResult.changed,
111758
+ flags: sdkResult.flags
111759
+ });
111760
+ continue;
111761
+ }
111762
+ const configResult = kind === "package_json" ? rewritePackageJson(source) : rewriteEnvFile(source);
111763
+ files.push({
111764
+ relativePath: rel,
111765
+ kind,
111766
+ source,
111767
+ rewritten: configResult.rewritten,
111768
+ changed: configResult.changed,
111769
+ flags: configResult.flags
111770
+ });
111771
+ }
111772
+ const flagsByPattern = {};
111773
+ let flagCount = 0;
111774
+ let changedFiles = 0;
111775
+ let packageJsonChanged = false;
111776
+ let envFilesChanged = 0;
111777
+ for (const file2 of files) {
111778
+ if (file2.changed) {
111779
+ changedFiles += 1;
111780
+ if (file2.kind === "package_json")
111781
+ packageJsonChanged = true;
111782
+ if (file2.kind === "env")
111783
+ envFilesChanged += 1;
111784
+ }
111785
+ for (const flag of file2.flags) {
111786
+ flagCount += 1;
111787
+ flagsByPattern[flag.pattern] = (flagsByPattern[flag.pattern] ?? 0) + 1;
111788
+ }
111789
+ }
111790
+ return {
111791
+ files,
111792
+ skipped,
111793
+ flagsByPattern,
111794
+ summary: {
111795
+ totalFiles: files.length,
111796
+ changedFiles,
111797
+ flagCount,
111798
+ packageJsonChanged,
111799
+ envFilesChanged
111800
+ }
111801
+ };
111802
+ }
111803
+ async function* walkTree(dir, rootAbs, ig) {
111804
+ let entries;
111805
+ try {
111806
+ entries = await readdir(dir);
111807
+ } catch {
111808
+ return;
111809
+ }
111810
+ for (const name of entries) {
111811
+ const abs = join17(dir, name);
111812
+ const rel = relative3(rootAbs, abs).split(sep3).join("/");
111813
+ if (rel.length > 0 && ig.ignores(rel))
111814
+ continue;
111815
+ let st;
111816
+ try {
111817
+ st = await stat(abs);
111818
+ } catch {
111819
+ continue;
111820
+ }
111821
+ if (st.isDirectory()) {
111822
+ if (ig.ignores(`${rel}/`))
111823
+ continue;
111824
+ yield* walkTree(abs, rootAbs, ig);
111825
+ continue;
111826
+ }
111827
+ if (st.isFile()) {
111828
+ yield abs;
111829
+ }
111830
+ }
111831
+ }
111832
+ function classifyFile2(relPath) {
111833
+ const base = relPath.split("/").pop() ?? relPath;
111834
+ if (base === "package.json")
111835
+ return "package_json";
111836
+ if (base === ".env" || base.startsWith(".env."))
111837
+ return "env";
111838
+ const dot = base.lastIndexOf(".");
111839
+ if (dot < 0)
111840
+ return null;
111841
+ const ext = base.slice(dot);
111842
+ if (REWRITABLE_EXTENSIONS.has(ext))
111843
+ return "code";
111844
+ return null;
111845
+ }
111846
+ function looksBinary(source) {
111847
+ const limit = Math.min(source.length, 8192);
111848
+ for (let i = 0;i < limit; i++) {
111849
+ if (source.charCodeAt(i) === 0)
111850
+ return true;
111851
+ }
111852
+ return false;
111853
+ }
111854
+ function rewritePackageJson(source) {
111855
+ let pkg;
111856
+ try {
111857
+ pkg = JSON.parse(source);
111858
+ } catch {
111859
+ return { rewritten: source, changed: false, flags: [] };
111860
+ }
111861
+ const depSections = [
111862
+ "dependencies",
111863
+ "devDependencies",
111864
+ "peerDependencies",
111865
+ "optionalDependencies"
111866
+ ];
111867
+ let changed = false;
111868
+ const flags = [];
111869
+ for (const section of depSections) {
111870
+ const deps = pkg[section];
111871
+ if (!deps || typeof deps !== "object" || Array.isArray(deps))
111872
+ continue;
111873
+ const depsObj = deps;
111874
+ if ("@supabase/supabase-js" in depsObj) {
111875
+ delete depsObj["@supabase/supabase-js"];
111876
+ if (!("pocketbase" in depsObj)) {
111877
+ depsObj.pocketbase = "^0.21.0";
111878
+ }
111879
+ changed = true;
111880
+ flags.push({
111881
+ kind: "rewritten",
111882
+ pattern: `package.${section}`,
111883
+ note: `${section}: @supabase/supabase-js → pocketbase`
111884
+ });
111885
+ }
111886
+ }
111887
+ if (!changed) {
111888
+ return { rewritten: source, changed: false, flags: [] };
111889
+ }
111890
+ const rewritten = `${JSON.stringify(pkg, null, 2)}
111891
+ `;
111892
+ return { rewritten, changed: true, flags };
111893
+ }
111894
+ function rewriteEnvFile(source) {
111895
+ const lines = source.split(/\r?\n/);
111896
+ const flags = [];
111897
+ const seenPrefixes = new Set;
111898
+ const outLines = [];
111899
+ let changed = false;
111900
+ const HEADER_MARKER = "# === Percher migration: Supabase → PocketBase ===";
111901
+ if (source.includes(HEADER_MARKER)) {
111902
+ return { rewritten: source, changed: false, flags: [] };
111903
+ }
111904
+ for (const [i, line] of lines.entries()) {
111905
+ const match = line.match(/^\s*([A-Z][A-Z0-9_]*)\s*=(.*)$/);
111906
+ if (!match) {
111907
+ outLines.push(line);
111908
+ continue;
111909
+ }
111910
+ const key = match[1] ?? "";
111911
+ if (!key.includes("SUPABASE")) {
111912
+ outLines.push(line);
111913
+ continue;
111914
+ }
111915
+ const prefix = extractPublicPrefix(key);
111916
+ seenPrefixes.add(prefix);
111917
+ outLines.push(`# was: ${line.trim()}`);
111918
+ flags.push({
111919
+ kind: "rewritten",
111920
+ pattern: "env.supabase_key",
111921
+ line: i + 1,
111922
+ note: `${key} commented out — replace with the appropriate POCKETBASE_URL value.`
111923
+ });
111924
+ changed = true;
111925
+ }
111926
+ if (!changed) {
111927
+ return { rewritten: source, changed: false, flags: [] };
111928
+ }
111929
+ const stubLines = [];
111930
+ stubLines.push(HEADER_MARKER);
111931
+ stubLines.push("# Old SUPABASE_* keys are kept above as `# was:` comments.");
111932
+ stubLines.push("# Fill in the POCKETBASE_URL values below and remove the comments");
111933
+ stubLines.push("# once you've verified the migration.");
111934
+ for (const prefix of [...seenPrefixes].sort()) {
111935
+ const pbKey = prefix ? `${prefix}POCKETBASE_URL` : "POCKETBASE_URL";
111936
+ stubLines.push(`${pbKey}=`);
111937
+ }
111938
+ stubLines.push("");
111939
+ const rewritten = `${stubLines.join(`
111940
+ `)}
111941
+ ${outLines.join(`
111942
+ `)}`;
111943
+ return { rewritten, changed: true, flags };
111944
+ }
111945
+ function extractPublicPrefix(key) {
111946
+ for (const p of [
111947
+ "NEXT_PUBLIC_",
111948
+ "VITE_",
111949
+ "NUXT_PUBLIC_",
111950
+ "PUBLIC_",
111951
+ "REACT_APP_",
111952
+ "VUE_APP_",
111953
+ "EXPO_PUBLIC_"
111954
+ ]) {
111955
+ if (key.startsWith(p))
111956
+ return p;
111957
+ }
111958
+ return "";
111959
+ }
111960
+ async function writeWalkResult(input) {
111961
+ const targetAbs = resolve6(input.targetDir);
111962
+ const changedOnly = input.changedOnly !== false;
111963
+ const written = [];
111964
+ for (const file2 of input.result.files) {
111965
+ if (changedOnly && !file2.changed)
111966
+ continue;
111967
+ const abs = resolve6(targetAbs, file2.relativePath);
111968
+ const rel = relative3(targetAbs, abs);
111969
+ const isParentTraversal = rel === ".." || rel.startsWith(`..${sep3}`) || rel.startsWith("../");
111970
+ if (rel.length === 0 || isParentTraversal || isAbsolute2(rel)) {
111971
+ throw new Error(`writeWalkResult refused path-traversing file "${file2.relativePath}" → "${abs}" (would escape targetDir "${targetAbs}").`);
111972
+ }
111973
+ await mkdir2(dirname4(abs), { recursive: true });
111974
+ await writeFile2(abs, file2.rewritten, "utf8");
111975
+ written.push(file2.relativePath);
111976
+ }
111977
+ return { written };
111978
+ }
111979
+
111980
+ // ../core/dist/commands/migrate-supabase-rewrite.js
111981
+ var rewriteSupabaseClientInputSchema = exports_external.object({
111982
+ rootDir: exports_external.string().optional().describe("Project root to rewrite. Relative paths resolve against ctx.cwd. Defaults to ctx.cwd."),
111983
+ outputDir: exports_external.string().optional().describe("Where preview-mode writes the rewritten tree. Ignored when `apply` is true. Defaults to `<root>/migration-preview/rewritten`."),
111984
+ apply: exports_external.boolean().optional().describe("When true, overwrite changed files in place (originals backed up to `migration-preview/backup/` first). Default false = preview only."),
111985
+ pbIdentifier: exports_external.string().optional().describe("PocketBase client variable name to emit. Defaults to `pb`."),
111986
+ supabaseIdentifiers: exports_external.array(exports_external.string()).optional().describe("Extra Supabase client variable names to recognise (beyond `supabase`).")
111987
+ });
111988
+ async function rewriteSupabaseClient(ctx, input) {
111989
+ const rootAbs = input.rootDir ? resolve7(ctx.cwd, input.rootDir) : resolve7(ctx.cwd);
111990
+ const apply = input.apply === true;
111991
+ const mode = apply ? "apply" : "preview";
111992
+ ctx.status(`Scanning ${relative4(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
111993
+ let walk2;
111994
+ try {
111995
+ walk2 = await walkSupabaseProject({
111996
+ rootDir: rootAbs,
111997
+ pbIdentifier: input.pbIdentifier,
111998
+ supabaseIdentifiers: input.supabaseIdentifiers
111999
+ });
112000
+ } catch (err) {
112001
+ return failure2(rootAbs, mode, err, `Couldn't scan ${relative4(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
112002
+ }
112003
+ const changed = walk2.files.filter((f) => f.changed);
112004
+ const flags = collectManualFlags(walk2);
112005
+ if (changed.length === 0 && flags.length === 0 && walk2.skipped.length === 0) {
112006
+ return {
112007
+ status: "ok",
112008
+ mode,
112009
+ rootDir: rootAbs,
112010
+ writtenTo: rootAbs,
112011
+ backupDir: null,
112012
+ filesWritten: [],
112013
+ changedCount: 0,
112014
+ flags: [],
112015
+ flagsByPattern: {},
112016
+ packageJsonChanged: false,
112017
+ envFilesChanged: 0,
112018
+ skipped: [],
112019
+ recovery: recoveryNone(),
112020
+ summary: "No Supabase SDK calls found to rewrite. If you intend to keep Supabase as your backend, " + 'set `[data] mode = "supabase"` in percher.toml instead.'
112021
+ };
112022
+ }
112023
+ const reportNeeded = flags.length > 0 || walk2.skipped.length > 0;
112024
+ const backupDir = apply && changed.length > 0 ? join18(rootAbs, "migration-preview", "backup") : null;
112025
+ const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve7(ctx.cwd, input.outputDir) : join18(rootAbs, "migration-preview", "rewritten");
112026
+ const filesWritten = [];
112027
+ try {
112028
+ if (changed.length > 0) {
112029
+ if (apply && backupDir) {
112030
+ ctx.status(`Backing up ${changed.length} original file(s) to migration-preview/backup/...`);
112031
+ await writeWalkResult({
112032
+ result: { ...walk2, files: changed.map((f) => ({ ...f, rewritten: f.source })) },
112033
+ targetDir: backupDir,
112034
+ changedOnly: false
112035
+ });
112036
+ }
112037
+ ctx.status(apply ? `Rewriting ${changed.length} file(s) in place...` : `Writing ${changed.length} rewritten file(s) to migration-preview/rewritten/...`);
112038
+ const out = await writeWalkResult({
112039
+ result: walk2,
112040
+ targetDir: rewriteTarget,
112041
+ changedOnly: true
112042
+ });
112043
+ for (const rel of out.written) {
112044
+ filesWritten.push(relative4(ctx.cwd, join18(rewriteTarget, rel)));
112045
+ }
112046
+ }
112047
+ if (reportNeeded) {
112048
+ const reportAbs = join18(rootAbs, "migration-preview", "REWRITE_NOTES.md");
112049
+ await mkdir3(dirname5(reportAbs), { recursive: true });
112050
+ await writeFile3(reportAbs, renderReport({ flags, skipped: walk2.skipped }), "utf8");
112051
+ filesWritten.push(relative4(ctx.cwd, reportAbs));
112052
+ }
112053
+ } catch (err) {
112054
+ return failure2(rootAbs, mode, err, apply ? "The in-place rewrite failed partway. Your originals are safe — restore from `migration-preview/backup/` and re-run." : "Couldn't write the rewritten preview. Check the output directory is writeable and re-run.");
112055
+ }
112056
+ const flagsByPattern = {};
112057
+ for (const flag of flags) {
112058
+ flagsByPattern[flag.pattern] = (flagsByPattern[flag.pattern] ?? 0) + 1;
112059
+ }
112060
+ const recovery = reportNeeded ? recoveryAsk({ prompt: buildPrompt(flags, walk2.skipped.length), reasonCode: "unknown" }) : recoveryNone();
112061
+ return {
112062
+ status: "ok",
112063
+ mode,
112064
+ rootDir: rootAbs,
112065
+ writtenTo: changed.length > 0 ? rewriteTarget : rootAbs,
112066
+ backupDir,
112067
+ filesWritten,
112068
+ changedCount: changed.length,
112069
+ flags,
112070
+ flagsByPattern,
112071
+ packageJsonChanged: walk2.summary.packageJsonChanged,
112072
+ envFilesChanged: walk2.summary.envFilesChanged,
112073
+ skipped: walk2.skipped,
112074
+ recovery,
112075
+ summary: renderSummary2({ mode, changed: changed.length, walk: walk2, flagCount: flags.length })
112076
+ };
112077
+ }
112078
+ function collectManualFlags(walk2) {
112079
+ const out = [];
112080
+ for (const file2 of walk2.files) {
112081
+ for (const flag of file2.flags) {
112082
+ if (flag.kind === "manual_review" || flag.kind === "unsupported") {
112083
+ out.push({
112084
+ file: file2.relativePath,
112085
+ line: flag.line,
112086
+ column: flag.column,
112087
+ kind: flag.kind,
112088
+ pattern: flag.pattern,
112089
+ note: flag.note
112090
+ });
112091
+ }
112092
+ }
112093
+ }
112094
+ return out;
112095
+ }
112096
+ function buildPrompt(flags, skippedCount) {
112097
+ const rewritten = flags.filter((f) => f.kind === "manual_review").length;
112098
+ const untouched = flags.filter((f) => f.kind === "unsupported").length;
112099
+ const bits = [];
112100
+ if (rewritten > 0) {
112101
+ bits.push(`${rewritten} rewritten to PocketBase but with semantics that differ from Supabase`);
112102
+ }
112103
+ if (untouched > 0) {
112104
+ bits.push(`${untouched} left untouched (no PocketBase equivalent — storage, realtime, rpc, or edge functions)`);
112105
+ }
112106
+ if (skippedCount > 0) {
112107
+ bits.push(`${skippedCount} file${skippedCount === 1 ? "" : "s"} couldn't be parsed`);
112108
+ }
112109
+ return `Some locations need review: ${bits.join("; ")}. Each is listed with its file and line in migration-preview/REWRITE_NOTES.md — check them before deploying.`;
112110
+ }
112111
+ function renderSummary2(args) {
112112
+ const parts = [];
112113
+ if (args.changed > 0) {
112114
+ const where = args.mode === "apply" ? "rewritten in place (originals in `migration-preview/backup/`)" : "written to `migration-preview/rewritten/` for review";
112115
+ parts.push(`${args.changed} file${args.changed === 1 ? "" : "s"} ${where}.`);
112116
+ } else {
112117
+ parts.push("No files needed automatic rewriting.");
112118
+ }
112119
+ if (args.walk.summary.packageJsonChanged) {
112120
+ parts.push("`package.json` swapped `@supabase/supabase-js` → `pocketbase`.");
112121
+ }
112122
+ if (args.walk.summary.envFilesChanged > 0) {
112123
+ parts.push(`${args.walk.summary.envFilesChanged} .env file${args.walk.summary.envFilesChanged === 1 ? "" : "s"} stubbed with PocketBase keys.`);
112124
+ }
112125
+ if (args.flagCount > 0) {
112126
+ parts.push(`${args.flagCount} pattern${args.flagCount === 1 ? "" : "s"} need manual review — see \`migration-preview/REWRITE_NOTES.md\`.`);
112127
+ }
112128
+ if (args.walk.skipped.length > 0) {
112129
+ parts.push(`${args.walk.skipped.length} file${args.walk.skipped.length === 1 ? "" : "s"} couldn't be parsed (listed in \`REWRITE_NOTES.md\`).`);
112130
+ }
112131
+ return parts.join(" ");
112132
+ }
112133
+ function renderReport(args) {
112134
+ const lines = [];
112135
+ lines.push("# Supabase → PocketBase — review notes");
112136
+ lines.push("");
112137
+ lines.push("The automated rewrite handled auth and CRUD. The locations below still need a human: some were rewritten but their semantics differ from Supabase, others have no PocketBase equivalent and were left untouched. There are no inline markers — work from this list.");
112138
+ lines.push("");
112139
+ const rewritten = args.flags.filter((f) => f.kind === "manual_review");
112140
+ const untouched = args.flags.filter((f) => f.kind === "unsupported");
112141
+ if (rewritten.length > 0) {
112142
+ lines.push("## Rewritten — verify the semantics");
112143
+ lines.push("");
112144
+ lines.push("These calls were converted to PocketBase, but the behaviour isn't identical (event shapes, filter escaping, pagination). Confirm each still does what you intend.");
112145
+ lines.push("");
112146
+ appendFlagsByFile(lines, rewritten);
112147
+ }
112148
+ if (untouched.length > 0) {
112149
+ lines.push("## Left untouched — rewrite by hand");
112150
+ lines.push("");
112151
+ lines.push("These have no clean PocketBase equivalent, so they remain as Supabase calls in your source. Replace each one yourself.");
112152
+ lines.push("");
112153
+ appendFlagsByFile(lines, untouched);
112154
+ }
112155
+ if (args.skipped.length > 0) {
112156
+ lines.push("## Files that couldn't be parsed");
112157
+ lines.push("");
112158
+ lines.push("These were skipped — review them manually for Supabase calls the rewriter missed.");
112159
+ lines.push("");
112160
+ for (const file2 of args.skipped) {
112161
+ lines.push(`- \`${file2.relativePath}\` — ${file2.reason}${file2.detail ? `: ${file2.detail}` : ""}`);
112162
+ }
112163
+ lines.push("");
112164
+ }
112165
+ return lines.join(`
112166
+ `);
112167
+ }
112168
+ function appendFlagsByFile(lines, flags) {
112169
+ const byFile = new Map;
112170
+ for (const flag of flags) {
112171
+ const list = byFile.get(flag.file) ?? [];
112172
+ list.push(flag);
112173
+ byFile.set(flag.file, list);
112174
+ }
112175
+ for (const [file2, fileFlags] of byFile) {
112176
+ lines.push(`### \`${file2}\``);
112177
+ lines.push("");
112178
+ for (const flag of fileFlags) {
112179
+ const loc = flag.line !== undefined ? `L${flag.line}${flag.column !== undefined ? `:${flag.column}` : ""}` : "(location unknown)";
112180
+ lines.push(`- ${loc} \`${flag.pattern}\` — ${flag.note}`);
112181
+ }
112182
+ lines.push("");
112183
+ }
112184
+ }
112185
+ function failure2(rootAbs, mode, err, suggestion) {
112186
+ const message = err instanceof Error ? err.message : String(err);
112187
+ return {
112188
+ status: "failed",
112189
+ mode,
112190
+ rootDir: rootAbs,
112191
+ writtenTo: rootAbs,
112192
+ backupDir: null,
112193
+ filesWritten: [],
112194
+ changedCount: 0,
112195
+ flags: [],
112196
+ flagsByPattern: {},
112197
+ packageJsonChanged: false,
112198
+ envFilesChanged: 0,
112199
+ skipped: [],
112200
+ recovery: recoveryAsk({
112201
+ prompt: `${suggestion} (${message})`,
112202
+ reasonCode: "unknown",
112203
+ retryable: true
112204
+ }),
112205
+ summary: `Client rewrite failed: ${message}`,
112206
+ error: {
112207
+ code: "rewrite_failed",
112208
+ title: "Supabase client rewrite failed",
112209
+ explanation: message,
112210
+ suggestion
112211
+ }
112212
+ };
112213
+ }
110413
112214
  // ../core/dist/commands/migrate-supabase-schema.js
110414
- import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
110415
- import { isAbsolute as isAbsolute2, join as join17, relative as relative3, resolve as resolve6 } from "node:path";
112215
+ import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
112216
+ import { isAbsolute as isAbsolute3, join as join19, relative as relative5, resolve as resolve8 } from "node:path";
110416
112217
 
110417
112218
  // ../core/dist/commands/migrate-supabase-scripts.js
110418
112219
  function generateDataImportScripts(preview) {
@@ -110860,7 +112661,7 @@ var migrateSupabaseSchemaInputSchema = exports_external.object({
110860
112661
  });
110861
112662
  async function migrateSupabaseSchema(ctx, input) {
110862
112663
  const outputDirAbs = resolveOutputDir(ctx.cwd, input.outputDir);
110863
- const outputDirRel = relative3(ctx.cwd, outputDirAbs) || ".";
112664
+ const outputDirRel = relative5(ctx.cwd, outputDirAbs) || ".";
110864
112665
  ctx.status(`Inspecting Supabase project ${input.projectRef}...`);
110865
112666
  const inspection = await inspectSupabase(ctx, {
110866
112667
  projectRef: input.projectRef,
@@ -110906,7 +112707,7 @@ async function migrateSupabaseSchema(ctx, input) {
110906
112707
  }
110907
112708
  };
110908
112709
  }
110909
- const summary = renderSummary2({
112710
+ const summary = renderSummary3({
110910
112711
  projectRef: input.projectRef,
110911
112712
  outputDirRel,
110912
112713
  inspection,
@@ -110924,28 +112725,28 @@ async function migrateSupabaseSchema(ctx, input) {
110924
112725
  }
110925
112726
  function resolveOutputDir(cwd, requested) {
110926
112727
  const raw = requested ?? "./migration-preview";
110927
- return isAbsolute2(raw) ? raw : resolve6(cwd, raw);
112728
+ return isAbsolute3(raw) ? raw : resolve8(cwd, raw);
110928
112729
  }
110929
112730
  async function writePreviewFiles(ctx, outputDir, preview) {
110930
- await mkdir2(outputDir, { recursive: true });
112731
+ await mkdir4(outputDir, { recursive: true });
110931
112732
  const schemaJson = renderSchemaJson(preview);
110932
112733
  const notesMd = renderMigrationNotes(preview);
110933
112734
  const scripts = generateDataImportScripts(preview);
110934
- const schemaPath = join17(outputDir, "pb_schema.json");
110935
- const notesPath = join17(outputDir, "MIGRATION_NOTES.md");
110936
- const migratePath = join17(outputDir, "pb_migrate.js");
110937
- const storagePath = join17(outputDir, "pb_migrate_storage.js");
110938
- await writeFile2(schemaPath, schemaJson, "utf8");
110939
- await writeFile2(notesPath, notesMd, "utf8");
110940
- await writeFile2(migratePath, scripts.pbMigrate, "utf8");
112735
+ const schemaPath = join19(outputDir, "pb_schema.json");
112736
+ const notesPath = join19(outputDir, "MIGRATION_NOTES.md");
112737
+ const migratePath = join19(outputDir, "pb_migrate.js");
112738
+ const storagePath = join19(outputDir, "pb_migrate_storage.js");
112739
+ await writeFile4(schemaPath, schemaJson, "utf8");
112740
+ await writeFile4(notesPath, notesMd, "utf8");
112741
+ await writeFile4(migratePath, scripts.pbMigrate, "utf8");
110941
112742
  const written = [
110942
- relative3(ctx.cwd, schemaPath),
110943
- relative3(ctx.cwd, notesPath),
110944
- relative3(ctx.cwd, migratePath)
112743
+ relative5(ctx.cwd, schemaPath),
112744
+ relative5(ctx.cwd, notesPath),
112745
+ relative5(ctx.cwd, migratePath)
110945
112746
  ];
110946
112747
  if (scripts.pbMigrateStorage !== null) {
110947
- await writeFile2(storagePath, scripts.pbMigrateStorage, "utf8");
110948
- written.push(relative3(ctx.cwd, storagePath));
112748
+ await writeFile4(storagePath, scripts.pbMigrateStorage, "utf8");
112749
+ written.push(relative5(ctx.cwd, storagePath));
110949
112750
  }
110950
112751
  return written;
110951
112752
  }
@@ -111094,7 +112895,7 @@ function renderMigrationNotes(preview) {
111094
112895
  return lines.join(`
111095
112896
  `);
111096
112897
  }
111097
- function renderSummary2(args) {
112898
+ function renderSummary3(args) {
111098
112899
  const counts = args.preview.summary;
111099
112900
  return [
111100
112901
  `Wrote migration preview for Supabase project ${args.projectRef} to ${args.outputDirRel}/.`,
@@ -111104,29 +112905,6 @@ function renderSummary2(args) {
111104
112905
  "Review `MIGRATION_NOTES.md` before running the import step."
111105
112906
  ].join(" ");
111106
112907
  }
111107
- // ../core/dist/commands/migrate-supabase-sdk.js
111108
- var import_jscodeshift = __toESM(require_core3(), 1);
111109
- var tsx = import_jscodeshift.default.withParser("tsx");
111110
- var STORAGE_OPERATIONS = new Set([
111111
- "upload",
111112
- "uploadToSignedUrl",
111113
- "download",
111114
- "list",
111115
- "remove",
111116
- "move",
111117
- "copy",
111118
- "createSignedUrl",
111119
- "createSignedUrls",
111120
- "createSignedUploadUrl",
111121
- "getPublicUrl",
111122
- "update",
111123
- "exists",
111124
- "info"
111125
- ]);
111126
- var CHAIN_CONTINUATIONS = new Set(["then", "catch", "finally"]);
111127
- // ../core/dist/commands/migrate-supabase-walker.js
111128
- var import_ignore3 = __toESM(require_ignore(), 1);
111129
- var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
111130
112908
  // ../core/dist/commands/open.js
111131
112909
  var openInputSchema = exports_external.object({
111132
112910
  app: exports_external.string().optional()
@@ -111184,7 +112962,7 @@ async function previewBranchShow(ctx, input = {}) {
111184
112962
  }
111185
112963
  // ../core/dist/commands/publish.js
111186
112964
  import { existsSync as existsSync14 } from "node:fs";
111187
- import { join as join20 } from "node:path";
112965
+ import { join as join22 } from "node:path";
111188
112966
 
111189
112967
  // ../shared/dist/pow.js
111190
112968
  import { createHash as createHash3 } from "node:crypto";
@@ -111561,7 +113339,7 @@ async function runDeployWithRetry(opts) {
111561
113339
 
111562
113340
  // ../core/dist/commands/env-scan.js
111563
113341
  import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
111564
- import { join as join18 } from "node:path";
113342
+ import { join as join20 } from "node:path";
111565
113343
  var SOURCE_EXTS = new Set([
111566
113344
  ".ts",
111567
113345
  ".tsx",
@@ -111598,7 +113376,7 @@ function scanForMissingBuildEnvRefs(cwd, existingKeys) {
111598
113376
  continue;
111599
113377
  let content;
111600
113378
  try {
111601
- content = readFileSync10(join18(cwd, rel), "utf8");
113379
+ content = readFileSync10(join20(cwd, rel), "utf8");
111602
113380
  } catch {
111603
113381
  continue;
111604
113382
  }
@@ -111630,7 +113408,7 @@ function* walkDir(dir, base) {
111630
113408
  for (const name of entries) {
111631
113409
  if (SKIP_DIRS.has(name))
111632
113410
  continue;
111633
- const full = join18(dir, name);
113411
+ const full = join20(dir, name);
111634
113412
  let st;
111635
113413
  try {
111636
113414
  st = statSync3(full);
@@ -111991,9 +113769,9 @@ function titleFromCode(code) {
111991
113769
 
111992
113770
  // ../core/dist/commands/publish-node.js
111993
113771
  import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
111994
- import { join as join19 } from "node:path";
113772
+ import { join as join21 } from "node:path";
111995
113773
  function resolveNodeVersion(cwd) {
111996
- const nvmrc = join19(cwd, ".nvmrc");
113774
+ const nvmrc = join21(cwd, ".nvmrc");
111997
113775
  if (existsSync13(nvmrc)) {
111998
113776
  try {
111999
113777
  const v = readFileSync11(nvmrc, "utf8").trim();
@@ -112001,7 +113779,7 @@ function resolveNodeVersion(cwd) {
112001
113779
  return { value: v, source: ".nvmrc" };
112002
113780
  } catch {}
112003
113781
  }
112004
- const pkgPath = join19(cwd, "package.json");
113782
+ const pkgPath = join21(cwd, "package.json");
112005
113783
  if (!existsSync13(pkgPath))
112006
113784
  return null;
112007
113785
  try {
@@ -112027,7 +113805,7 @@ var publishInputSchema = exports_external.object({
112027
113805
  var SUSPICIOUS_BYTES = 50 * 1024 * 1024;
112028
113806
  var SUSPICIOUS_FILES = 1e4;
112029
113807
  function tomlPathFor2(cwd) {
112030
- return join20(cwd, "percher.toml");
113808
+ return join22(cwd, "percher.toml");
112031
113809
  }
112032
113810
  async function buildReplacedResult2(opts) {
112033
113811
  const { ctx, app, deployment, tarball, cwd } = opts;
@@ -112647,13 +114425,11 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
112647
114425
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
112648
114426
  };
112649
114427
  }
112650
- saveConfig({
112651
- token: created.token,
112652
- anonClaim: {
112653
- app: created.app.name,
112654
- claimToken: created.claimToken,
112655
- expiresAt: created.expiresAt
112656
- }
114428
+ saveConfig({ token: created.token });
114429
+ setAnonClaim({
114430
+ app: created.app.name,
114431
+ claimToken: created.claimToken,
114432
+ expiresAt: created.expiresAt
112657
114433
  });
112658
114434
  const newClient = new PercherClient({
112659
114435
  apiUrl: ctx.client.apiUrl,
@@ -112694,7 +114470,7 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
112694
114470
  };
112695
114471
  }
112696
114472
  async function loadOrGenerate(ctx) {
112697
- const tomlPath = join20(ctx.cwd, "percher.toml");
114473
+ const tomlPath = join22(ctx.cwd, "percher.toml");
112698
114474
  if (!existsSync14(tomlPath)) {
112699
114475
  ctx.status("No percher.toml found — detecting framework...");
112700
114476
  await init(ctx);
@@ -112745,7 +114521,7 @@ function emitPreflight(ctx, config2, tarball) {
112745
114521
  }
112746
114522
  // ../core/dist/commands/push.js
112747
114523
  import { existsSync as existsSync15 } from "node:fs";
112748
- import { join as join21 } from "node:path";
114524
+ import { join as join23 } from "node:path";
112749
114525
  var pushInputSchema = exports_external.object({
112750
114526
  dryRun: exports_external.boolean().optional(),
112751
114527
  force: exports_external.boolean().optional(),
@@ -112756,7 +114532,7 @@ var SUSPICIOUS_BYTES2 = 50 * 1024 * 1024;
112756
114532
  var SUSPICIOUS_FILES2 = 1e4;
112757
114533
  var PLACEHOLDER_PREFIXES = ["add-your-", "your-key-here"];
112758
114534
  async function loadOrGenerate2(ctx) {
112759
- const tomlPath = join21(ctx.cwd, "percher.toml");
114535
+ const tomlPath = join23(ctx.cwd, "percher.toml");
112760
114536
  if (!existsSync15(tomlPath)) {
112761
114537
  ctx.status("No percher.toml found — detecting framework...");
112762
114538
  const result = await init(ctx);
@@ -112868,7 +114644,7 @@ async function push(ctx, input = {}, internals = {}) {
112868
114644
  fileCount: tarball.fileCount,
112869
114645
  recovery: RECOVERY_NONE,
112870
114646
  summary: `Dry run for ${config2.app.name}: ${tarball.fileCount} files, ${(tarball.bytes / 1024).toFixed(1)} KB — no deploy performed.`,
112871
- configPath: join21(ctx.cwd, "percher.toml"),
114647
+ configPath: join23(ctx.cwd, "percher.toml"),
112872
114648
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
112873
114649
  };
112874
114650
  }
@@ -113051,7 +114827,7 @@ ${deployment.errorMessage}` : "";
113051
114827
  fileCount: tarball.fileCount,
113052
114828
  recovery: RECOVERY_NONE,
113053
114829
  summary,
113054
- configPath: join21(ctx.cwd, "percher.toml"),
114830
+ configPath: join23(ctx.cwd, "percher.toml"),
113055
114831
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
113056
114832
  };
113057
114833
  }
@@ -113381,7 +115157,7 @@ function failureResult(error48) {
113381
115157
  }
113382
115158
  // ../core/dist/commands/rename.js
113383
115159
  import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
113384
- import { join as join22 } from "node:path";
115160
+ import { join as join24 } from "node:path";
113385
115161
  var renameInputSchema = exports_external.object({
113386
115162
  app: exports_external.string().optional(),
113387
115163
  name: exports_external.string().min(3).max(40)
@@ -113401,7 +115177,7 @@ async function rename2(ctx, input) {
113401
115177
  };
113402
115178
  }
113403
115179
  function updateLocalTomlName(cwd, oldName, newName) {
113404
- const p = join22(cwd, "percher.toml");
115180
+ const p = join24(cwd, "percher.toml");
113405
115181
  if (!existsSync16(p))
113406
115182
  return false;
113407
115183
  try {
@@ -113418,18 +115194,18 @@ function updateLocalTomlName(cwd, oldName, newName) {
113418
115194
  }
113419
115195
  }
113420
115196
  // ../core/dist/commands/reproduce.js
113421
- import { spawn } from "node:child_process";
113422
115197
  import { mkdtempSync, writeFileSync as writeFileSync9 } from "node:fs";
113423
115198
  import { tmpdir } from "node:os";
113424
- import { join as join23 } from "node:path";
115199
+ import { join as join25 } from "node:path";
115200
+ var import_cross_spawn = __toESM(require_cross_spawn(), 1);
113425
115201
  function runProcessExit(cmd, args, opts = {}) {
113426
- return new Promise((resolve7, reject) => {
113427
- const child = spawn(cmd, args, {
115202
+ return new Promise((resolve9, reject) => {
115203
+ const child = import_cross_spawn.default(cmd, args, {
113428
115204
  cwd: opts.cwd,
113429
115205
  stdio: opts.inherit ? "inherit" : "ignore"
113430
115206
  });
113431
115207
  child.on("error", reject);
113432
- child.on("close", (code) => resolve7(code ?? 1));
115208
+ child.on("close", (code) => resolve9(code ?? 1));
113433
115209
  });
113434
115210
  }
113435
115211
  var reproduceInputSchema = exports_external.object({
@@ -113515,8 +115291,8 @@ async function reproduce(ctx, input) {
113515
115291
  const envMap = await ctx.client.env.list(app.id);
113516
115292
  currentAppEnvKeys = Object.keys(envMap).sort();
113517
115293
  } catch {}
113518
- const tmpDir = mkdtempSync(join23(tmpdir(), `percher-reproduce-${input.deployId}-`));
113519
- const tarballPath = join23(tmpDir, "source.tar.gz");
115294
+ const tmpDir = mkdtempSync(join25(tmpdir(), `percher-reproduce-${input.deployId}-`));
115295
+ const tarballPath = join25(tmpDir, "source.tar.gz");
113520
115296
  writeFileSync9(tarballPath, bytes);
113521
115297
  let extracted = false;
113522
115298
  try {
@@ -114856,8 +116632,8 @@ function registerAppsCommands(cli, ctx) {
114856
116632
  deployId,
114857
116633
  timeoutSeconds: Math.min(Math.ceil(remainingMs / 1000), 30)
114858
116634
  }, { signal: callController.signal }),
114859
- new Promise((resolve7) => {
114860
- raceTimer = setTimeout(() => resolve7(null), remainingMs);
116635
+ new Promise((resolve9) => {
116636
+ raceTimer = setTimeout(() => resolve9(null), remainingMs);
114861
116637
  })
114862
116638
  ]);
114863
116639
  } finally {
@@ -115323,8 +117099,8 @@ function registerDeploysCommands(cli, ctx, argv) {
115323
117099
  const { summary, files } = result;
115324
117100
  await writeLine(ctx, `${summary.filesChanged} file${summary.filesChanged === 1 ? "" : "s"} changed · ${import_picocolors7.default.green(`+${summary.additions}`)} ${import_picocolors7.default.red(`−${summary.deletions}`)} (${result.base.slice(0, 10)} → ${result.head.slice(0, 10)})`);
115325
117101
  for (const f of files) {
115326
- const stat = f.binary ? import_picocolors7.default.dim("binary") : `${import_picocolors7.default.green(`+${f.additions}`)} ${import_picocolors7.default.red(`−${f.deletions}`)}`;
115327
- await writeLine(ctx, ` ${f.status} ${f.path} ${stat}${f.truncated ? import_picocolors7.default.dim(" (truncated)") : ""}`);
117102
+ const stat2 = f.binary ? import_picocolors7.default.dim("binary") : `${import_picocolors7.default.green(`+${f.additions}`)} ${import_picocolors7.default.red(`−${f.deletions}`)}`;
117103
+ await writeLine(ctx, ` ${f.status} ${f.path} ${stat2}${f.truncated ? import_picocolors7.default.dim(" (truncated)") : ""}`);
115328
117104
  if (options.patch && f.patch) {
115329
117105
  await writeLine(ctx, f.patch.replace(/\n$/, ""));
115330
117106
  }
@@ -115396,7 +117172,7 @@ function registerEnvCommands(cli, ctx) {
115396
117172
  if (action === "set") {
115397
117173
  const { resolveEnvSetInputs: resolveEnvSetInputs2, EnvSetInputError: EnvSetInputError2 } = await Promise.resolve().then(() => (init_env_set_input(), exports_env_set_input));
115398
117174
  const { promptHidden: promptHidden2 } = await Promise.resolve().then(() => (init_prompt_hidden(), exports_prompt_hidden));
115399
- const { readFile: readFile3 } = await import("node:fs/promises");
117175
+ const { readFile: readFile4 } = await import("node:fs/promises");
115400
117176
  try {
115401
117177
  const values = await resolveEnvSetInputs2({
115402
117178
  args,
@@ -115408,7 +117184,7 @@ function registerEnvCommands(cli, ctx) {
115408
117184
  chunks.push(c);
115409
117185
  return Buffer.concat(chunks).toString("utf8");
115410
117186
  },
115411
- readFile: async (p) => readFile3(p, "utf8"),
117187
+ readFile: async (p) => readFile4(p, "utf8"),
115412
117188
  promptHidden: promptHidden2
115413
117189
  });
115414
117190
  await envSet(ctx, { app: options.app, values });
@@ -115522,9 +117298,13 @@ function registerGithubCommands(cli, ctx) {
115522
117298
  // src/commands/migrate.ts
115523
117299
  var import_picocolors11 = __toESM(require_picocolors(), 1);
115524
117300
  function registerMigrateCommands(cli, ctx) {
115525
- cli.command("migrate-from-supabase", "Migrate a Supabase project to PocketBase (FUTURE9 Phase A read-only + Phase B preview writes)").option("--project <ref>", "Supabase project reference (the 20-char id from the project URL)").option("--token <token>", "Supabase personal access token (sbp_...). Read from SUPABASE_ACCESS_TOKEN if omitted.").option("--inspect-only", "Run schema introspection only (Phase A — read-only, no file writes)").option("--output-dir <dir>", "Where to write the Phase B preview files (default: ./migration-preview/)").option("--json", "Output the structured result as JSON").action(async (options) => {
117301
+ cli.command("migrate-from-supabase", "Migrate a Supabase project to PocketBase: schema + data-import script, optionally rewrite SDK calls").option("--project <ref>", "Supabase project reference (the 20-char id from the project URL)").option("--token <token>", "Supabase personal access token (sbp_...). Read from SUPABASE_ACCESS_TOKEN if omitted.").option("--inspect-only", "Only print the schema that would migrate — read-only, no file writes").option("--output-dir <dir>", "Where to write the preview files (default: ./migration-preview/)").option("--rewrite-client", "Also convert your Supabase SDK calls to PocketBase across the project").option("--apply", "With --rewrite-client: overwrite files in place (originals backed up first). Default: preview only.").option("--root <dir>", "Project root to rewrite with --rewrite-client (default: current directory)").option("--json", "Output the structured result as JSON").action(async (options) => {
115526
117302
  const projectRef = options.project;
115527
117303
  const token = options.token ?? ctx.env.SUPABASE_ACCESS_TOKEN;
117304
+ if (options.apply && !options.rewriteClient) {
117305
+ await writeLine(ctx, `${import_picocolors11.default.red("✗")} --apply only applies to the client rewrite. Pass --rewrite-client --apply together.`);
117306
+ throw new SilentExitError(1);
117307
+ }
115528
117308
  if (!projectRef) {
115529
117309
  await writeLine(ctx, `${import_picocolors11.default.red("✗")} Missing --project. Pass your Supabase project ref (e.g. --project abcdefghijklmnopqrst).`);
115530
117310
  throw new SilentExitError(1);
@@ -115551,15 +117331,28 @@ function registerMigrateCommands(cli, ctx) {
115551
117331
  token,
115552
117332
  outputDir: options.outputDir
115553
117333
  });
117334
+ let rewrite;
117335
+ if (options.rewriteClient && result.status === "ok") {
117336
+ rewrite = await rewriteSupabaseClient(ctx, {
117337
+ rootDir: options.root,
117338
+ apply: options.apply === true
117339
+ });
117340
+ }
115554
117341
  if (options.json) {
115555
- await writeLine(ctx, JSON.stringify(result, null, 2));
115556
- if (result.status === "failed")
117342
+ await writeLine(ctx, JSON.stringify(rewrite ? { schema: result, rewrite } : result, null, 2));
117343
+ if (result.status === "failed" || rewrite?.status === "failed") {
115557
117344
  throw new SilentExitError(1);
117345
+ }
115558
117346
  return;
115559
117347
  }
115560
- await renderSchemaHuman(ctx, result);
115561
- if (result.status === "failed")
117348
+ await renderSchemaHuman(ctx, result, {
117349
+ clientRewriteRequested: options.rewriteClient === true
117350
+ });
117351
+ if (rewrite)
117352
+ await renderRewriteHuman(ctx, rewrite);
117353
+ if (result.status === "failed" || rewrite?.status === "failed") {
115562
117354
  throw new SilentExitError(1);
117355
+ }
115563
117356
  });
115564
117357
  }
115565
117358
  async function renderInspectHuman(ctx, result) {
@@ -115605,9 +117398,9 @@ async function renderInspectHuman(ctx, result) {
115605
117398
  }
115606
117399
  }
115607
117400
  await writeLine(ctx, "");
115608
- await writeLine(ctx, import_picocolors11.default.dim("--inspect-only is read-only. Drop the flag to also write the Phase B PocketBase-schema preview."));
117401
+ await writeLine(ctx, import_picocolors11.default.dim("--inspect-only is read-only. Drop the flag to also write the PocketBase schema preview + pb_migrate.js data-import script to ./migration-preview/."));
115609
117402
  }
115610
- async function renderSchemaHuman(ctx, result) {
117403
+ async function renderSchemaHuman(ctx, result, opts) {
115611
117404
  if (result.status === "failed") {
115612
117405
  const err = result.error;
115613
117406
  await writeLine(ctx, `${import_picocolors11.default.red("✗")} ${err?.title ?? "Migration preview failed"}`);
@@ -115646,7 +117439,55 @@ async function renderSchemaHuman(ctx, result) {
115646
117439
  }
115647
117440
  }
115648
117441
  await writeLine(ctx, "");
115649
- await writeLine(ctx, import_picocolors11.default.dim("Phase B is a preview. Phase C (data import) and Phase D (client rewrite) ship in later releases. Review MIGRATION_NOTES.md before any import."));
117442
+ await writeLine(ctx, import_picocolors11.default.dim("Preview only — nothing has touched your PocketBase yet. ./migration-preview/ includes pb_migrate.js, the data-import script: review MIGRATION_NOTES.md, then run it against your app's PocketBase to copy your rows over."));
117443
+ if (!opts.clientRewriteRequested) {
117444
+ await writeLine(ctx, import_picocolors11.default.dim("Add --rewrite-client to also convert your Supabase SDK calls to PocketBase (preview first; --apply writes in place)."));
117445
+ }
117446
+ }
117447
+ async function renderRewriteHuman(ctx, result) {
117448
+ await writeLine(ctx, "");
117449
+ if (result.status === "failed") {
117450
+ const err = result.error;
117451
+ await writeLine(ctx, `${import_picocolors11.default.red("✗")} ${err?.title ?? "Client rewrite failed"}`);
117452
+ if (err?.explanation)
117453
+ await writeLine(ctx, ` ${err.explanation}`);
117454
+ if (err?.suggestion)
117455
+ await writeLine(ctx, import_picocolors11.default.dim(` ${err.suggestion}`));
117456
+ return;
117457
+ }
117458
+ await writeLine(ctx, `${import_picocolors11.default.green("✓")} ${result.summary}`);
117459
+ if (result.filesWritten.length > 0) {
117460
+ await writeLine(ctx, "");
117461
+ await writeLine(ctx, import_picocolors11.default.bold("Files written"));
117462
+ for (const path of result.filesWritten.slice(0, 20)) {
117463
+ await writeLine(ctx, ` ${import_picocolors11.default.cyan(path)}`);
117464
+ }
117465
+ if (result.filesWritten.length > 20) {
117466
+ await writeLine(ctx, import_picocolors11.default.dim(` …and ${result.filesWritten.length - 20} more`));
117467
+ }
117468
+ }
117469
+ if (result.flags.length > 0) {
117470
+ await writeLine(ctx, "");
117471
+ await writeLine(ctx, import_picocolors11.default.bold("Needs review (see migration-preview/REWRITE_NOTES.md)"));
117472
+ for (const flag of result.flags.slice(0, 15)) {
117473
+ const loc = flag.line !== undefined ? `:${flag.line}` : "";
117474
+ const tag = flag.kind === "manual_review" ? "rewritten, verify semantics" : "left untouched";
117475
+ await writeLine(ctx, ` ${import_picocolors11.default.yellow("⚠")} ${import_picocolors11.default.cyan(`${flag.file}${loc}`)} ${flag.pattern} ${import_picocolors11.default.dim(`(${tag}) — ${flag.note}`)}`);
117476
+ }
117477
+ if (result.flags.length > 15) {
117478
+ await writeLine(ctx, import_picocolors11.default.dim(` …and ${result.flags.length - 15} more — see REWRITE_NOTES.md`));
117479
+ }
117480
+ }
117481
+ if (result.skipped.length > 0) {
117482
+ await writeLine(ctx, import_picocolors11.default.dim(`
117483
+ ${result.skipped.length} file(s) couldn't be parsed and were skipped — listed in REWRITE_NOTES.md.`));
117484
+ }
117485
+ await writeLine(ctx, "");
117486
+ if (result.mode === "apply") {
117487
+ await writeLine(ctx, import_picocolors11.default.dim(result.changedCount > 0 ? "Files rewritten in place. Originals are in ./migration-preview/backup/ — diff against them (or git) before committing." : "No files were rewritten — the work left is the manual review above."));
117488
+ } else {
117489
+ await writeLine(ctx, import_picocolors11.default.dim(result.changedCount > 0 ? "Preview only — diff ./migration-preview/rewritten/ against your project, then re-run with --rewrite-client --apply to write in place." : "Preview only — no files needed automatic rewriting; work through the manual review above."));
117490
+ }
115650
117491
  }
115651
117492
 
115652
117493
  // src/commands/sharing.ts
@@ -115871,16 +117712,16 @@ function registerTransfersCommands(cli, ctx) {
115871
117712
  }
115872
117713
 
115873
117714
  // src/open.ts
115874
- import { spawn as spawn2 } from "node:child_process";
117715
+ import { spawn } from "node:child_process";
115875
117716
  async function openUrl(url2) {
115876
117717
  const platform = process.platform;
115877
117718
  try {
115878
117719
  if (platform === "darwin")
115879
- spawn2("open", [url2], { detached: true, stdio: "ignore" }).unref();
117720
+ spawn("open", [url2], { detached: true, stdio: "ignore" }).unref();
115880
117721
  else if (platform === "win32")
115881
- spawn2("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore" }).unref();
117722
+ spawn("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore" }).unref();
115882
117723
  else
115883
- spawn2("xdg-open", [url2], { detached: true, stdio: "ignore" }).unref();
117724
+ spawn("xdg-open", [url2], { detached: true, stdio: "ignore" }).unref();
115884
117725
  } catch {}
115885
117726
  }
115886
117727
 
@@ -115987,7 +117828,7 @@ async function renderError(stderr, error48) {
115987
117828
  // package.json
115988
117829
  var package_default = {
115989
117830
  name: "percher",
115990
- version: "0.5.5",
117831
+ version: "0.5.7",
115991
117832
  description: "CLI for the Percher hosting platform — publish apps with one command",
115992
117833
  type: "module",
115993
117834
  bin: {
@@ -116069,9 +117910,9 @@ async function showTelemetryNotice() {
116069
117910
  return;
116070
117911
  const { homedir: homedir2 } = await import("node:os");
116071
117912
  const { existsSync: existsSync17, mkdirSync: mkdirSync6, writeFileSync: writeFileSync10 } = await import("node:fs");
116072
- const { join: join24 } = await import("node:path");
116073
- const configDir = join24(homedir2(), ".percher");
116074
- const markerFile = join24(configDir, ".telemetry-notice-shown");
117913
+ const { join: join26 } = await import("node:path");
117914
+ const configDir = join26(homedir2(), ".percher");
117915
+ const markerFile = join26(configDir, ".telemetry-notice-shown");
116075
117916
  if (existsSync17(markerFile))
116076
117917
  return;
116077
117918
  console.log("Percher sends non-account-linked usage stats (command, result, error type, OS, Bun version).");