percher 0.5.8 → 0.5.9

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.
@@ -3604,8 +3604,8 @@ var require_streamx = __commonJS((exports, module) => {
3604
3604
  return this;
3605
3605
  },
3606
3606
  next() {
3607
- return new Promise(function(resolve6, reject) {
3608
- promiseResolve = resolve6;
3607
+ return new Promise(function(resolve7, reject) {
3608
+ promiseResolve = resolve7;
3609
3609
  promiseReject = reject;
3610
3610
  const data2 = stream.read();
3611
3611
  if (data2 !== null)
@@ -3642,14 +3642,14 @@ var require_streamx = __commonJS((exports, module) => {
3642
3642
  }
3643
3643
  function destroy(err) {
3644
3644
  stream.destroy(err);
3645
- return new Promise((resolve6, reject) => {
3645
+ return new Promise((resolve7, reject) => {
3646
3646
  if (stream._duplexState & DESTROYED)
3647
- return resolve6({ value: undefined, done: true });
3647
+ return resolve7({ value: undefined, done: true });
3648
3648
  stream.once("close", function() {
3649
3649
  if (err)
3650
3650
  reject(err);
3651
3651
  else
3652
- resolve6({ value: undefined, done: true });
3652
+ resolve7({ value: undefined, done: true });
3653
3653
  });
3654
3654
  });
3655
3655
  }
@@ -3701,8 +3701,8 @@ var require_streamx = __commonJS((exports, module) => {
3701
3701
  return Promise.resolve(true);
3702
3702
  if (state.drains === null)
3703
3703
  state.drains = [];
3704
- return new Promise((resolve6) => {
3705
- state.drains.push({ writes, resolve: resolve6 });
3704
+ return new Promise((resolve7) => {
3705
+ state.drains.push({ writes, resolve: resolve7 });
3706
3706
  });
3707
3707
  }
3708
3708
  write(data2) {
@@ -3816,11 +3816,11 @@ var require_streamx = __commonJS((exports, module) => {
3816
3816
  cb(null);
3817
3817
  }
3818
3818
  function pipelinePromise(...streams) {
3819
- return new Promise((resolve6, reject) => {
3819
+ return new Promise((resolve7, reject) => {
3820
3820
  return pipeline(...streams, (err) => {
3821
3821
  if (err)
3822
3822
  return reject(err);
3823
- resolve6();
3823
+ resolve7();
3824
3824
  });
3825
3825
  });
3826
3826
  }
@@ -4534,16 +4534,16 @@ var require_extract = __commonJS((exports, module) => {
4534
4534
  entryCallback = null;
4535
4535
  cb(err);
4536
4536
  }
4537
- function onnext(resolve6, reject) {
4537
+ function onnext(resolve7, reject) {
4538
4538
  if (error48) {
4539
4539
  return reject(error48);
4540
4540
  }
4541
4541
  if (entryStream) {
4542
- resolve6({ value: entryStream, done: false });
4542
+ resolve7({ value: entryStream, done: false });
4543
4543
  entryStream = null;
4544
4544
  return;
4545
4545
  }
4546
- promiseResolve = resolve6;
4546
+ promiseResolve = resolve7;
4547
4547
  promiseReject = reject;
4548
4548
  consumeCallback(null);
4549
4549
  if (extract._finished && promiseResolve) {
@@ -4574,14 +4574,14 @@ var require_extract = __commonJS((exports, module) => {
4574
4574
  function destroy(err) {
4575
4575
  extract.destroy(err);
4576
4576
  consumeCallback(err);
4577
- return new Promise((resolve6, reject) => {
4577
+ return new Promise((resolve7, reject) => {
4578
4578
  if (extract.destroyed)
4579
- return resolve6({ value: undefined, done: true });
4579
+ return resolve7({ value: undefined, done: true });
4580
4580
  extract.once("close", function() {
4581
4581
  if (err)
4582
4582
  reject(err);
4583
4583
  else
4584
- resolve6({ value: undefined, done: true });
4584
+ resolve7({ value: undefined, done: true });
4585
4585
  });
4586
4586
  });
4587
4587
  }
@@ -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(resolve6) {
5073
- resolve6(value);
5072
+ return value instanceof P ? value : new P(function(resolve7) {
5073
+ resolve7(value);
5074
5074
  });
5075
5075
  }
5076
- return new (P || (P = Promise))(function(resolve6, reject) {
5076
+ return new (P || (P = Promise))(function(resolve7, 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 ? resolve6(result.value) : adopt(result.value).then(fulfilled, rejected);
5092
+ result.done ? resolve7(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(resolve6, reject) {
5322
- v = o[n](v), settle(resolve6, reject, v.done, v.value);
5321
+ return new Promise(function(resolve7, reject) {
5322
+ v = o[n](v), settle(resolve7, reject, v.done, v.value);
5323
5323
  });
5324
5324
  };
5325
5325
  }
5326
- function settle(resolve6, reject, d, v) {
5326
+ function settle(resolve7, reject, d, v) {
5327
5327
  Promise.resolve(v).then(function(v2) {
5328
- resolve6({ value: v2, done: d });
5328
+ resolve7({ 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 isAbsolute2 = exports.isAbsolute(path);
8827
+ var isAbsolute3 = 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 = isAbsolute2 ? "/" : ".";
8847
+ path = isAbsolute3 ? "/" : ".";
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 join17(aRoot, aPath) {
8856
+ function join18(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 = join17;
8888
+ exports.join = join18;
8889
8889
  exports.isAbsolute = function(aPath) {
8890
8890
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
8891
8891
  };
8892
- function relative3(aRoot, aPath) {
8892
+ function relative4(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 = relative3;
8911
+ exports.relative = relative4;
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 = join17(urlGenerate(parsed), sourceURL);
9061
+ sourceURL = join18(urlGenerate(parsed), sourceURL);
9062
9062
  }
9063
9063
  return normalize2(sourceURL);
9064
9064
  }
@@ -19563,10 +19563,10 @@ else`, adjustClause(path.call(print, "alternate"), options));
19563
19563
  }
19564
19564
  case "ForStatement": {
19565
19565
  var init2 = path.call(print, "init");
19566
- var sep3 = init2.length > 1 ? `;
19566
+ var sep4 = init2.length > 1 ? `;
19567
19567
  ` : "; ";
19568
19568
  var forParen = "for (";
19569
- var indented = (0, lines_1.fromString)(sep3).join([init2, path.call(print, "test"), path.call(print, "update")]).indentTail(forParen.length);
19569
+ var indented = (0, lines_1.fromString)(sep4).join([init2, path.call(print, "test"), path.call(print, "update")]).indentTail(forParen.length);
19570
19570
  var head = (0, lines_1.concat)([forParen, indented, ")"]);
19571
19571
  var clause = adjustClause(path.call(print, "body"), options);
19572
19572
  parts.push(head);
@@ -85326,12 +85326,12 @@ var require_isexe = __commonJS((exports, module) => {
85326
85326
  if (typeof Promise !== "function") {
85327
85327
  throw new TypeError("callback not provided");
85328
85328
  }
85329
- return new Promise(function(resolve6, reject) {
85329
+ return new Promise(function(resolve7, reject) {
85330
85330
  isexe(path, options || {}, function(er, is) {
85331
85331
  if (er) {
85332
85332
  reject(er);
85333
85333
  } else {
85334
- resolve6(is);
85334
+ resolve7(is);
85335
85335
  }
85336
85336
  });
85337
85337
  });
@@ -85393,27 +85393,27 @@ var require_which = __commonJS((exports, module) => {
85393
85393
  opt = {};
85394
85394
  const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
85395
85395
  const found = [];
85396
- const step = (i) => new Promise((resolve6, reject) => {
85396
+ const step = (i) => new Promise((resolve7, reject) => {
85397
85397
  if (i === pathEnv.length)
85398
- return opt.all && found.length ? resolve6(found) : reject(getNotFoundError(cmd));
85398
+ return opt.all && found.length ? resolve7(found) : reject(getNotFoundError(cmd));
85399
85399
  const ppRaw = pathEnv[i];
85400
85400
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
85401
85401
  const pCmd = path.join(pathPart, cmd);
85402
85402
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
85403
- resolve6(subStep(p, i, 0));
85403
+ resolve7(subStep(p, i, 0));
85404
85404
  });
85405
- const subStep = (p, i, ii) => new Promise((resolve6, reject) => {
85405
+ const subStep = (p, i, ii) => new Promise((resolve7, reject) => {
85406
85406
  if (ii === pathExt.length)
85407
- return resolve6(step(i + 1));
85407
+ return resolve7(step(i + 1));
85408
85408
  const ext = pathExt[ii];
85409
85409
  isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
85410
85410
  if (!er && is) {
85411
85411
  if (opt.all)
85412
85412
  found.push(p + ext);
85413
85413
  else
85414
- return resolve6(p + ext);
85414
+ return resolve7(p + ext);
85415
85415
  }
85416
- return resolve6(subStep(p, i, ii + 1));
85416
+ return resolve7(subStep(p, i, ii + 1));
85417
85417
  });
85418
85418
  });
85419
85419
  return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
@@ -89840,10 +89840,10 @@ var require_browser = __commonJS((exports) => {
89840
89840
  text = canvas;
89841
89841
  canvas = undefined;
89842
89842
  }
89843
- return new Promise(function(resolve10, reject) {
89843
+ return new Promise(function(resolve11, reject) {
89844
89844
  try {
89845
89845
  const data2 = QRCode.create(text, opts);
89846
- resolve10(renderFunc(data2, canvas, opts));
89846
+ resolve11(renderFunc(data2, canvas, opts));
89847
89847
  } catch (e) {
89848
89848
  reject(e);
89849
89849
  }
@@ -89922,11 +89922,11 @@ var require_server = __commonJS((exports) => {
89922
89922
  }
89923
89923
  function render(renderFunc, text, params) {
89924
89924
  if (!params.cb) {
89925
- return new Promise(function(resolve10, reject) {
89925
+ return new Promise(function(resolve11, reject) {
89926
89926
  try {
89927
89927
  const data2 = QRCode.create(text, params.opts);
89928
89928
  return renderFunc(data2, params.opts, function(err, data3) {
89929
- return err ? reject(err) : resolve10(data3);
89929
+ return err ? reject(err) : resolve11(data3);
89930
89930
  });
89931
89931
  } catch (e) {
89932
89932
  reject(e);
@@ -90181,7 +90181,7 @@ __export(exports_prompt_hidden, {
90181
90181
  });
90182
90182
  import { stdin, stdout } from "node:process";
90183
90183
  function promptHiddenWithStreams(question, input, output) {
90184
- return new Promise((resolve10, reject) => {
90184
+ return new Promise((resolve11, reject) => {
90185
90185
  output.write(`${question} `);
90186
90186
  let buf = "";
90187
90187
  let done = false;
@@ -90197,7 +90197,7 @@ function promptHiddenWithStreams(question, input, output) {
90197
90197
  input.removeListener("error", onError);
90198
90198
  output.write(`
90199
90199
  `);
90200
- resolve10(buf.replace(/\r$/, ""));
90200
+ resolve11(buf.replace(/\r$/, ""));
90201
90201
  return;
90202
90202
  }
90203
90203
  buf += ch;
@@ -90219,7 +90219,7 @@ function promptHiddenWithStreams(question, input, output) {
90219
90219
  input.removeListener("error", onError);
90220
90220
  output.write(`
90221
90221
  `);
90222
- resolve10(buf.replace(/\r$/, ""));
90222
+ resolve11(buf.replace(/\r$/, ""));
90223
90223
  };
90224
90224
  input.on("data", onData);
90225
90225
  input.on("error", onError);
@@ -90237,7 +90237,7 @@ async function promptHidden(question) {
90237
90237
  ttyStdin.resume();
90238
90238
  ttyStdin.setEncoding("utf8");
90239
90239
  try {
90240
- return await new Promise((resolve10, reject) => {
90240
+ return await new Promise((resolve11, reject) => {
90241
90241
  stdout.write(`${question} `);
90242
90242
  let buf = "";
90243
90243
  const onData = (key) => {
@@ -90247,7 +90247,7 @@ async function promptHidden(question) {
90247
90247
  ttyStdin.removeListener("data", onData);
90248
90248
  stdout.write(`
90249
90249
  `);
90250
- resolve10(buf);
90250
+ resolve11(buf);
90251
90251
  return;
90252
90252
  }
90253
90253
  if (ch === "\x03") {
@@ -105399,6 +105399,181 @@ var appResourcesInputSchema = exports_external.object({
105399
105399
  var appTopologyInputSchema = exports_external.object({
105400
105400
  app: exports_external.string().optional()
105401
105401
  });
105402
+ // ../core/dist/commands/appstore-kit.js
105403
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
105404
+ import { basename, dirname as dirname3, isAbsolute, join as join5, relative, resolve as resolve3, sep } from "node:path";
105405
+
105406
+ // ../core/dist/appstore-artifacts.js
105407
+ var BRAND_GREEN = "#2d6a4f";
105408
+ var ICON_COLOUR_HEX = {
105409
+ green: BRAND_GREEN,
105410
+ terracotta: "#d0653a",
105411
+ blue: "#4a6fa4",
105412
+ purple: "#6e4dba",
105413
+ olive: "#b8923a"
105414
+ };
105415
+ function themeColorForToken(token) {
105416
+ if (token && token in ICON_COLOUR_HEX)
105417
+ return ICON_COLOUR_HEX[token] ?? BRAND_GREEN;
105418
+ return BRAND_GREEN;
105419
+ }
105420
+ function hostFromUrl(url2) {
105421
+ try {
105422
+ return new URL(url2).host;
105423
+ } catch {
105424
+ return url2.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
105425
+ }
105426
+ }
105427
+ function shortName(name) {
105428
+ const cleaned = name.replace(/[^A-Za-z0-9]/g, "");
105429
+ return (cleaned || "App").slice(0, 12);
105430
+ }
105431
+ function manifestStarter({ name, themeColorHex }) {
105432
+ return JSON.stringify({
105433
+ name,
105434
+ short_name: shortName(name),
105435
+ start_url: "/",
105436
+ display: "standalone",
105437
+ background_color: "#ffffff",
105438
+ theme_color: themeColorHex
105439
+ }, null, 2);
105440
+ }
105441
+ function serviceWorkerStarter() {
105442
+ return `// sw.js — minimal offline shell. Drop in at your app root and serve from /sw.js.
105443
+ const CACHE = "app-shell-v1";
105444
+ const SHELL = ["/"];
105445
+
105446
+ self.addEventListener("install", (event) => {
105447
+ event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(SHELL)));
105448
+ self.skipWaiting();
105449
+ });
105450
+
105451
+ self.addEventListener("activate", (event) => {
105452
+ event.waitUntil(
105453
+ caches.keys().then((keys) =>
105454
+ Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))),
105455
+ ),
105456
+ );
105457
+ self.clients.claim();
105458
+ });
105459
+
105460
+ self.addEventListener("fetch", (event) => {
105461
+ if (event.request.method !== "GET") return;
105462
+ event.respondWith(
105463
+ caches.match(event.request).then((cached) => cached || fetch(event.request)),
105464
+ );
105465
+ });`;
105466
+ }
105467
+ function swRegistrationSnippet() {
105468
+ return `if ("serviceWorker" in navigator) {
105469
+ navigator.serviceWorker.register("/sw.js");
105470
+ }`;
105471
+ }
105472
+ function bubblewrapCommand({ url: url2 }) {
105473
+ const host = hostFromUrl(url2);
105474
+ return `# generate the Android project, pointed at your manifest
105475
+ npx @bubblewrap/cli init --manifest https://${host}/manifest.json
105476
+ npx @bubblewrap/cli build`;
105477
+ }
105478
+ function capacitorConfig({ name, url: url2 }) {
105479
+ const host = hostFromUrl(url2);
105480
+ return `import type { CapacitorConfig } from "@capacitor/cli";
105481
+ const config: CapacitorConfig = {
105482
+ appId: "app.percher.yourapp",
105483
+ appName: ${JSON.stringify(name)},
105484
+ webDir: "dist",
105485
+ server: { url: "https://${host}", cleartext: false },
105486
+ };
105487
+ export default config;`;
105488
+ }
105489
+ function assetlinksJson({ packageName, sha256Fingerprint }) {
105490
+ const pkg = packageName.trim() || "app.percher.yourapp";
105491
+ const fp = sha256Fingerprint.trim() || "<your signing cert SHA-256>";
105492
+ return `[{
105493
+ "relation": ["delegate_permission/common.handle_all_urls"],
105494
+ "target": {
105495
+ "namespace": "android_app",
105496
+ "package_name": ${JSON.stringify(pkg)},
105497
+ "sha256_cert_fingerprints": [${JSON.stringify(fp)}]
105498
+ }
105499
+ }]`;
105500
+ }
105501
+ function appleAppSiteAssociation({ teamId, bundleId }) {
105502
+ const team = teamId.trim() || "TEAMID";
105503
+ const bundle = bundleId.trim() || "app.percher.yourapp";
105504
+ return `{
105505
+ "applinks": {
105506
+ "apps": [],
105507
+ "details": [{ "appID": ${JSON.stringify(`${team}.${bundle}`)}, "paths": ["*"] }]
105508
+ }
105509
+ }`;
105510
+ }
105511
+
105512
+ // ../core/dist/commands/appstore-kit.js
105513
+ var appstoreKitInputSchema = exports_external.object({
105514
+ name: exports_external.string().optional(),
105515
+ url: exports_external.string().optional(),
105516
+ packageName: exports_external.string().optional(),
105517
+ fingerprint: exports_external.string().optional(),
105518
+ teamId: exports_external.string().optional(),
105519
+ bundleId: exports_external.string().optional(),
105520
+ force: exports_external.boolean().optional(),
105521
+ outDir: exports_external.string().optional()
105522
+ });
105523
+ async function appstoreKit(ctx, input = {}) {
105524
+ const name = (input.name ?? readPercherTomlAppName(ctx.cwd) ?? basename(ctx.cwd) ?? "app").trim() || "app";
105525
+ const url2 = input.url?.trim() || `https://${name}.percher.run`;
105526
+ const themeHex = themeColorForToken(null);
105527
+ const base = resolve3(ctx.cwd, input.outDir ?? ".");
105528
+ const baseRel = relative(ctx.cwd, base);
105529
+ if (baseRel.startsWith("..") || isAbsolute(baseRel)) {
105530
+ throw new PercherCoreError("Output directory must stay inside the project", {
105531
+ code: "appstore-kit.bad-out-dir",
105532
+ hint: "Pass a path inside the current project (e.g. --out public), not an absolute or parent path."
105533
+ });
105534
+ }
105535
+ const files = [
105536
+ { rel: "manifest.json", content: manifestStarter({ name, themeColorHex: themeHex }) },
105537
+ { rel: "sw.js", content: serviceWorkerStarter() },
105538
+ { rel: "capacitor.config.ts", content: capacitorConfig({ name, url: url2 }) },
105539
+ {
105540
+ rel: ".well-known/assetlinks.json",
105541
+ content: assetlinksJson({
105542
+ packageName: input.packageName ?? "",
105543
+ sha256Fingerprint: input.fingerprint ?? ""
105544
+ })
105545
+ },
105546
+ {
105547
+ rel: ".well-known/apple-app-site-association",
105548
+ content: appleAppSiteAssociation({
105549
+ teamId: input.teamId ?? "",
105550
+ bundleId: input.bundleId ?? ""
105551
+ })
105552
+ }
105553
+ ];
105554
+ const written = [];
105555
+ const skipped = [];
105556
+ for (const f of files) {
105557
+ const abs = join5(base, ...f.rel.split("/"));
105558
+ const display = relative(ctx.cwd, abs).split(sep).join("/");
105559
+ if (existsSync3(abs) && !input.force) {
105560
+ skipped.push(display);
105561
+ continue;
105562
+ }
105563
+ mkdirSync3(dirname3(abs), { recursive: true });
105564
+ writeFileSync3(abs, `${f.content}
105565
+ `, "utf8");
105566
+ written.push(display);
105567
+ }
105568
+ return {
105569
+ appName: name,
105570
+ appUrl: url2,
105571
+ written,
105572
+ skipped,
105573
+ bubblewrapCommand: bubblewrapCommand({ url: url2 }),
105574
+ swRegistration: swRegistrationSnippet()
105575
+ };
105576
+ }
105402
105577
  // ../core/dist/commands/billing.js
105403
105578
  var billingUpgradeInputSchema = exports_external.object({
105404
105579
  plan: exports_external.enum(["starter", "maker", "pro"])
@@ -105422,22 +105597,22 @@ async function cacheReset(ctx, input = {}) {
105422
105597
  var capabilitiesInputSchema = exports_external.object({});
105423
105598
  // ../client/dist/abortable-sleep.js
105424
105599
  function abortableSleep(ms, signal) {
105425
- return new Promise((resolve3) => {
105600
+ return new Promise((resolve4) => {
105426
105601
  if (!signal) {
105427
- setTimeout(resolve3, ms);
105602
+ setTimeout(resolve4, ms);
105428
105603
  return;
105429
105604
  }
105430
105605
  if (signal.aborted) {
105431
- resolve3();
105606
+ resolve4();
105432
105607
  return;
105433
105608
  }
105434
105609
  const onAbort = () => {
105435
105610
  clearTimeout(t);
105436
- resolve3();
105611
+ resolve4();
105437
105612
  };
105438
105613
  const t = setTimeout(() => {
105439
105614
  signal.removeEventListener("abort", onAbort);
105440
- resolve3();
105615
+ resolve4();
105441
105616
  }, ms);
105442
105617
  signal.addEventListener("abort", onAbort, { once: true });
105443
105618
  });
@@ -105456,9 +105631,9 @@ function isAutoForwardedBuildKey(name) {
105456
105631
  return AUTO_FORWARD_PREFIXES.some((p) => name.startsWith(p));
105457
105632
  }
105458
105633
  // ../client/dist/config.js
105459
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync3 } from "node:fs";
105634
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "node:fs";
105460
105635
  import { homedir } from "node:os";
105461
- import { dirname as dirname3, join as join5 } from "node:path";
105636
+ import { dirname as dirname4, join as join6 } from "node:path";
105462
105637
  var DEFAULT_API_URL = "https://api.percher.run";
105463
105638
  function home() {
105464
105639
  return process.env.HOME ?? process.env.USERPROFILE ?? homedir();
@@ -105466,12 +105641,12 @@ function home() {
105466
105641
  function configPath() {
105467
105642
  const xdg = process.env.XDG_CONFIG_HOME;
105468
105643
  if (xdg)
105469
- return join5(xdg, "percher", "config.json");
105470
- return join5(home(), ".percher", "config.json");
105644
+ return join6(xdg, "percher", "config.json");
105645
+ return join6(home(), ".percher", "config.json");
105471
105646
  }
105472
105647
  function readFile2() {
105473
105648
  const p = configPath();
105474
- if (!existsSync3(p))
105649
+ if (!existsSync4(p))
105475
105650
  return {};
105476
105651
  try {
105477
105652
  const parsed = JSON.parse(readFileSync4(p, "utf8"));
@@ -105499,11 +105674,11 @@ function readAnonClaims() {
105499
105674
  }
105500
105675
  function saveConfig(partial2) {
105501
105676
  const p = configPath();
105502
- mkdirSync3(dirname3(p), { recursive: true });
105677
+ mkdirSync4(dirname4(p), { recursive: true });
105503
105678
  const current = readFile2();
105504
105679
  const merged = { ...current, ...partial2 };
105505
105680
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
105506
- writeFileSync3(tmp, JSON.stringify(merged, null, 2), "utf8");
105681
+ writeFileSync4(tmp, JSON.stringify(merged, null, 2), "utf8");
105507
105682
  renameSync(tmp, p);
105508
105683
  }
105509
105684
  function getAnonClaim(app) {
@@ -105907,6 +106082,15 @@ class AppsResource {
105907
106082
  unsetPreviewBranch(appRef) {
105908
106083
  return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/preview-branch`);
105909
106084
  }
106085
+ listWellKnown(appRef) {
106086
+ return this.http.get(`/apps/${encodeURIComponent(appRef)}/well-known`);
106087
+ }
106088
+ setWellKnown(appRef, kind, content) {
106089
+ return this.http.put(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`, { content });
106090
+ }
106091
+ clearWellKnown(appRef, kind) {
106092
+ return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`);
106093
+ }
105910
106094
  setDescription(appRef, description) {
105911
106095
  return this.http.patch(`/apps/${encodeURIComponent(appRef)}/description`, {
105912
106096
  description
@@ -106582,17 +106766,17 @@ async function claim(ctx, input = {}) {
106582
106766
  };
106583
106767
  }
106584
106768
  // ../core/dist/commands/create.js
106585
- import { join as join7, resolve as resolve4 } from "node:path";
106769
+ import { join as join8, resolve as resolve5 } from "node:path";
106586
106770
 
106587
106771
  // ../core/dist/templates.js
106588
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readdirSync, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync4 } from "node:fs";
106589
- import { basename, join as join6, normalize, relative, resolve as resolve3 } from "node:path";
106772
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "node:fs";
106773
+ import { basename as basename2, join as join7, normalize, relative as relative2, resolve as resolve4 } from "node:path";
106590
106774
  var __dirname = "C:\\dev\\Percher\\packages\\core\\dist";
106591
- var TEMPLATES_DIR = resolve3(import.meta.dirname ?? __dirname, "../templates");
106775
+ var TEMPLATES_DIR = resolve4(import.meta.dirname ?? __dirname, "../templates");
106592
106776
  var PLACEHOLDER = "__APP_NAME__";
106593
106777
  function listTemplates() {
106594
106778
  return readdirSync(TEMPLATES_DIR).filter((name) => {
106595
- const full = join6(TEMPLATES_DIR, name);
106779
+ const full = join7(TEMPLATES_DIR, name);
106596
106780
  return statSync(full).isDirectory();
106597
106781
  });
106598
106782
  }
@@ -106602,36 +106786,36 @@ function scaffoldTemplate(input) {
106602
106786
  if (!available.includes(template)) {
106603
106787
  throw new Error(`Unknown template "${template}". Available: ${available.join(", ")}`);
106604
106788
  }
106605
- const absTarget = resolve3(targetDir);
106606
- if (existsSync4(absTarget)) {
106789
+ const absTarget = resolve4(targetDir);
106790
+ if (existsSync5(absTarget)) {
106607
106791
  const entries = readdirSync(absTarget);
106608
106792
  if (entries.length > 0 && !force) {
106609
106793
  throw new Error(`Target directory "${absTarget}" is not empty. Use --force to overwrite.`);
106610
106794
  }
106611
106795
  }
106612
- const srcDir = join6(TEMPLATES_DIR, template);
106796
+ const srcDir = join7(TEMPLATES_DIR, template);
106613
106797
  const files = [];
106614
106798
  function copyDir(src, dest) {
106615
- mkdirSync4(dest, { recursive: true });
106799
+ mkdirSync5(dest, { recursive: true });
106616
106800
  for (const entry of readdirSync(src)) {
106617
- const srcPath = join6(src, entry);
106618
- const destPath = join6(dest, entry);
106619
- const rel = relative(absTarget, normalize(destPath));
106620
- if (rel.startsWith("..") || resolve3(destPath) === resolve3(absTarget, "..", basename(absTarget))) {
106801
+ const srcPath = join7(src, entry);
106802
+ const destPath = join7(dest, entry);
106803
+ const rel = relative2(absTarget, normalize(destPath));
106804
+ if (rel.startsWith("..") || resolve4(destPath) === resolve4(absTarget, "..", basename2(absTarget))) {
106621
106805
  throw new Error(`Template contains path traversal: ${entry}`);
106622
106806
  }
106623
106807
  if (statSync(srcPath).isDirectory()) {
106624
106808
  copyDir(srcPath, destPath);
106625
106809
  } else {
106626
- if (existsSync4(destPath) && !force) {
106810
+ if (existsSync5(destPath) && !force) {
106627
106811
  continue;
106628
106812
  }
106629
106813
  let content = readFileSync5(srcPath, "utf-8");
106630
106814
  content = content.replaceAll(PLACEHOLDER, appName);
106631
106815
  content = content.replace(/\r\n/g, `
106632
106816
  `);
106633
- writeFileSync4(destPath, content, "utf-8");
106634
- files.push(relative(absTarget, destPath).replace(/\\/g, "/"));
106817
+ writeFileSync5(destPath, content, "utf-8");
106818
+ files.push(relative2(absTarget, destPath).replace(/\\/g, "/"));
106635
106819
  }
106636
106820
  }
106637
106821
  }
@@ -106656,14 +106840,14 @@ async function create(ctx, input) {
106656
106840
  }
106657
106841
  let targetDir;
106658
106842
  if (input.directory) {
106659
- targetDir = resolve4(ctx.cwd, input.directory);
106660
- if (!targetDir.startsWith(resolve4(ctx.cwd))) {
106843
+ targetDir = resolve5(ctx.cwd, input.directory);
106844
+ if (!targetDir.startsWith(resolve5(ctx.cwd))) {
106661
106845
  throw new PercherCoreError("Directory must be within the current workspace", {
106662
106846
  code: "create.failed"
106663
106847
  });
106664
106848
  }
106665
106849
  } else {
106666
- targetDir = join7(ctx.cwd, input.name);
106850
+ targetDir = join8(ctx.cwd, input.name);
106667
106851
  }
106668
106852
  try {
106669
106853
  const result = scaffoldTemplate({
@@ -106759,7 +106943,7 @@ async function data(ctx, input = {}) {
106759
106943
  };
106760
106944
  }
106761
106945
  // ../core/dist/commands/data-export.js
106762
- import { resolve as resolve5 } from "node:path";
106946
+ import { resolve as resolve6 } from "node:path";
106763
106947
  var dataExportInputSchema = exports_external.object({
106764
106948
  app: exports_external.string().optional().describe("App name or id. Defaults to the app in percher.toml."),
106765
106949
  out: exports_external.string().optional().describe("Output file path. Defaults to ./<app>-pb-<timestamp>.tar.gz in the current directory.")
@@ -106775,7 +106959,7 @@ async function dataExport(ctx, input) {
106775
106959
  ctx.status?.(`Exporting ${appName} data...`);
106776
106960
  const stamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
106777
106961
  const fileName = input.out ?? `${appName}-pb-${stamp}.tar.gz`;
106778
- const path = resolve5(ctx.cwd, fileName);
106962
+ const path = resolve6(ctx.cwd, fileName);
106779
106963
  const res = await ctx.client.apps.streamDataExport(appName);
106780
106964
  const bytes = await writeResponseToFile(res, path);
106781
106965
  return {
@@ -106871,14 +107055,14 @@ async function deploysInspect(ctx, input) {
106871
107055
  return { deploy, buildLog };
106872
107056
  }
106873
107057
  // ../core/dist/commands/dev.js
106874
- import { existsSync as existsSync7 } from "node:fs";
106875
- import { join as join10 } from "node:path";
107058
+ import { existsSync as existsSync8 } from "node:fs";
107059
+ import { join as join11 } from "node:path";
106876
107060
 
106877
107061
  // ../core/dist/tarball.js
106878
107062
  var import_ignore = __toESM(require_ignore(), 1);
106879
107063
  import { createHash as createHash2 } from "node:crypto";
106880
- import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
106881
- import { join as join8, relative as relative2, sep } from "node:path";
107064
+ import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
107065
+ import { join as join9, relative as relative3, sep as sep2 } from "node:path";
106882
107066
  import { Readable } from "node:stream";
106883
107067
  import { createGzip } from "node:zlib";
106884
107068
 
@@ -106904,8 +107088,8 @@ var DEFAULT_IGNORE = [
106904
107088
  function* walk(dir, baseDir, ig) {
106905
107089
  const entries = readdirSync2(dir);
106906
107090
  for (const name of entries) {
106907
- const full = join8(dir, name);
106908
- const rel = relative2(baseDir, full).split(sep).join("/");
107091
+ const full = join9(dir, name);
107092
+ const rel = relative3(baseDir, full).split(sep2).join("/");
106909
107093
  if (ig.ignores(rel))
106910
107094
  continue;
106911
107095
  const stats = statSync2(full);
@@ -106921,15 +107105,15 @@ function* walk(dir, baseDir, ig) {
106921
107105
  async function createTarball(options) {
106922
107106
  const ig = import_ignore.default();
106923
107107
  ig.add(DEFAULT_IGNORE);
106924
- const gitignorePath = join8(options.cwd, ".gitignore");
106925
- if (existsSync5(gitignorePath)) {
107108
+ const gitignorePath = join9(options.cwd, ".gitignore");
107109
+ if (existsSync6(gitignorePath)) {
106926
107110
  ig.add(readFileSync6(gitignorePath, "utf8"));
106927
107111
  }
106928
107112
  if (options.extraIgnore)
106929
107113
  ig.add(options.extraIgnore);
106930
107114
  const fileBuffers = [];
106931
107115
  for (const rel of walk(options.cwd, options.cwd, ig)) {
106932
- const data2 = readFileSync6(join8(options.cwd, rel));
107116
+ const data2 = readFileSync6(join9(options.cwd, rel));
106933
107117
  fileBuffers.push({ path: rel, size: data2.length, data: data2 });
106934
107118
  }
106935
107119
  fileBuffers.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -106948,8 +107132,8 @@ async function createTarball(options) {
106948
107132
  const pack = $pack();
106949
107133
  (async () => {
106950
107134
  for (const file2 of fileBuffers) {
106951
- await new Promise((resolve6, reject) => {
106952
- pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) : resolve6());
107135
+ await new Promise((resolve7, reject) => {
107136
+ pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) : resolve7());
106953
107137
  });
106954
107138
  }
106955
107139
  pack.finalize();
@@ -106969,8 +107153,8 @@ async function createTarball(options) {
106969
107153
 
106970
107154
  // ../core/dist/watcher.js
106971
107155
  var import_ignore2 = __toESM(require_ignore(), 1);
106972
- import { existsSync as existsSync6, readFileSync as readFileSync7, watch } from "node:fs";
106973
- import { join as join9, sep as sep2 } from "node:path";
107156
+ import { existsSync as existsSync7, readFileSync as readFileSync7, watch } from "node:fs";
107157
+ import { join as join10, sep as sep3 } from "node:path";
106974
107158
  var DEFAULT_IGNORE2 = [
106975
107159
  "node_modules",
106976
107160
  ".git",
@@ -106990,8 +107174,8 @@ function createWatcher(options) {
106990
107174
  const debounceMs = options.debounceMs ?? 500;
106991
107175
  const ig = import_ignore2.default();
106992
107176
  ig.add(DEFAULT_IGNORE2);
106993
- const gitignorePath = join9(options.cwd, ".gitignore");
106994
- if (existsSync6(gitignorePath)) {
107177
+ const gitignorePath = join10(options.cwd, ".gitignore");
107178
+ if (existsSync7(gitignorePath)) {
106995
107179
  ig.add(readFileSync7(gitignorePath, "utf8"));
106996
107180
  }
106997
107181
  if (options.extraIgnore)
@@ -107001,7 +107185,7 @@ function createWatcher(options) {
107001
107185
  const fsWatcher = watch(options.cwd, { recursive: true }, (_event, filename) => {
107002
107186
  if (!filename)
107003
107187
  return;
107004
- const rel = filename.split(sep2).join("/");
107188
+ const rel = filename.split(sep3).join("/");
107005
107189
  if (ig.ignores(rel))
107006
107190
  return;
107007
107191
  pending.add(rel);
@@ -107030,8 +107214,8 @@ var devInputSchema = exports_external.object({
107030
107214
  app: exports_external.string().optional()
107031
107215
  });
107032
107216
  async function loadConfig2(ctx, appOverride) {
107033
- const tomlPath = join10(ctx.cwd, "percher.toml");
107034
- if (!existsSync7(tomlPath)) {
107217
+ const tomlPath = join11(ctx.cwd, "percher.toml");
107218
+ if (!existsSync8(tomlPath)) {
107035
107219
  throw new PercherCoreError("No percher.toml found. Run: percher init", {
107036
107220
  code: "dev.no-app",
107037
107221
  hint: "Create a percher.toml first with `percher init`."
@@ -107185,12 +107369,12 @@ async function dev(ctx, input, callbacks) {
107185
107369
  }
107186
107370
  });
107187
107371
  try {
107188
- await new Promise((resolve6) => {
107372
+ await new Promise((resolve7) => {
107189
107373
  if (callbacks.signal.aborted) {
107190
- resolve6();
107374
+ resolve7();
107191
107375
  return;
107192
107376
  }
107193
- callbacks.signal.addEventListener("abort", () => resolve6(), { once: true });
107377
+ callbacks.signal.addEventListener("abort", () => resolve7(), { once: true });
107194
107378
  });
107195
107379
  } finally {
107196
107380
  logStream.ctrl?.abort();
@@ -107225,8 +107409,8 @@ async function diff(ctx, input = {}) {
107225
107409
  });
107226
107410
  }
107227
107411
  // ../core/dist/commands/doctor.js
107228
- import { existsSync as existsSync8 } from "node:fs";
107229
- import { join as join12 } from "node:path";
107412
+ import { existsSync as existsSync9 } from "node:fs";
107413
+ import { join as join13 } from "node:path";
107230
107414
 
107231
107415
  // ../core/dist/error-classifier.js
107232
107416
  function extractEnvVarsFromLog(combined) {
@@ -107771,7 +107955,7 @@ function recoveryFromErrorClass(errorClass, failure = {}) {
107771
107955
  }
107772
107956
 
107773
107957
  // ../core/dist/commands/publish-failure.js
107774
- import { join as join11 } from "node:path";
107958
+ import { join as join12 } from "node:path";
107775
107959
 
107776
107960
  // ../core/dist/structured-error-codes.js
107777
107961
  var MAPPINGS = {
@@ -107849,7 +108033,7 @@ function trimMessage(raw) {
107849
108033
 
107850
108034
  // ../core/dist/commands/publish-failure.js
107851
108035
  function tomlPathFor(cwd) {
107852
- return join11(cwd, "percher.toml");
108036
+ return join12(cwd, "percher.toml");
107853
108037
  }
107854
108038
  async function buildFailureError(ctx, app, deployment, signal) {
107855
108039
  let buildLogTail;
@@ -108192,8 +108376,8 @@ async function doctor(ctx, input = {}) {
108192
108376
  });
108193
108377
  return summarize(checks3, { appProvided: !!input.app });
108194
108378
  }
108195
- const tomlPath = join12(ctx.cwd, "percher.toml");
108196
- const tomlExists = existsSync8(tomlPath);
108379
+ const tomlPath = join13(ctx.cwd, "percher.toml");
108380
+ const tomlExists = existsSync9(tomlPath);
108197
108381
  let tomlValid = false;
108198
108382
  if (!tomlExists) {
108199
108383
  checks3.push({
@@ -108973,7 +109157,7 @@ async function envList(ctx, input = {}) {
108973
109157
  import { randomUUID } from "node:crypto";
108974
109158
  import { createWriteStream } from "node:fs";
108975
109159
  import { rename, unlink } from "node:fs/promises";
108976
- import { isAbsolute, resolve as resolvePath } from "node:path";
109160
+ import { isAbsolute as isAbsolute2, resolve as resolvePath } from "node:path";
108977
109161
  var exportInputSchema = exports_external.object({
108978
109162
  app: exports_external.string().optional(),
108979
109163
  out: exports_external.string().optional(),
@@ -108997,7 +109181,7 @@ async function streamToFile(outPath, source) {
108997
109181
  const tmpPath = `${outPath}.part-${randomUUID()}`;
108998
109182
  const out = createWriteStream(tmpPath);
108999
109183
  const reader = source.getReader();
109000
- const closed = new Promise((resolve6) => out.once("close", () => resolve6()));
109184
+ const closed = new Promise((resolve7) => out.once("close", () => resolve7()));
109001
109185
  let onWriteError;
109002
109186
  const writeFailed = new Promise((_, reject) => {
109003
109187
  onWriteError = reject;
@@ -109014,14 +109198,14 @@ async function streamToFile(outPath, source) {
109014
109198
  bytes += value.byteLength;
109015
109199
  if (!out.write(value)) {
109016
109200
  await Promise.race([
109017
- new Promise((resolve6) => out.once("drain", resolve6)),
109201
+ new Promise((resolve7) => out.once("drain", resolve7)),
109018
109202
  writeFailed
109019
109203
  ]);
109020
109204
  }
109021
109205
  }
109022
109206
  }
109023
- await new Promise((resolve6, reject) => {
109024
- out.end((err) => err ? reject(err) : resolve6());
109207
+ await new Promise((resolve7, reject) => {
109208
+ out.end((err) => err ? reject(err) : resolve7());
109025
109209
  });
109026
109210
  await closed;
109027
109211
  } catch (err) {
@@ -109039,7 +109223,7 @@ async function streamToFile(outPath, source) {
109039
109223
  return { bytes };
109040
109224
  }
109041
109225
  function resolveOutPath(ctxCwd, filename) {
109042
- if (isAbsolute(filename))
109226
+ if (isAbsolute2(filename))
109043
109227
  return filename;
109044
109228
  return resolvePath(ctxCwd, filename);
109045
109229
  }
@@ -109100,8 +109284,8 @@ var forgejoSetupWebhookInputSchema = exports_external.object({
109100
109284
  app: exports_external.string().optional().describe("App name (overrides percher.toml)")
109101
109285
  });
109102
109286
  // ../core/dist/commands/generate.js
109103
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
109104
- import { join as join13 } from "node:path";
109287
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
109288
+ import { join as join14 } from "node:path";
109105
109289
  var generateInputSchema = exports_external.object({
109106
109290
  cwd: exports_external.string().optional()
109107
109291
  });
@@ -109187,8 +109371,8 @@ function generateTypeScript(config2) {
109187
109371
  }
109188
109372
  async function generate(ctx, input = {}) {
109189
109373
  const cwd = input.cwd ?? ctx.cwd;
109190
- const tomlPath = join13(cwd, "percher.toml");
109191
- if (!existsSync9(tomlPath)) {
109374
+ const tomlPath = join14(cwd, "percher.toml");
109375
+ if (!existsSync10(tomlPath)) {
109192
109376
  throw new PercherCoreError("No percher.toml found", {
109193
109377
  code: "dev.no-app",
109194
109378
  hint: "Run percher init first."
@@ -109197,14 +109381,14 @@ async function generate(ctx, input = {}) {
109197
109381
  const config2 = await parseFile(tomlPath);
109198
109382
  const files = [];
109199
109383
  const envExample = generateEnvExample(config2);
109200
- writeFileSync5(join13(cwd, ".env.example"), envExample);
109384
+ writeFileSync6(join14(cwd, ".env.example"), envExample);
109201
109385
  files.push(".env.example");
109202
109386
  const tsTypes = generateTypeScript(config2);
109203
- writeFileSync5(join13(cwd, "percher.generated.d.ts"), tsTypes);
109387
+ writeFileSync6(join14(cwd, "percher.generated.d.ts"), tsTypes);
109204
109388
  files.push("percher.generated.d.ts");
109205
109389
  const agentInstructions = generateAgentInstructions(config2);
109206
- mkdirSync5(join13(cwd, ".percher"), { recursive: true });
109207
- writeFileSync5(join13(cwd, ".percher", "agent-instructions.md"), agentInstructions);
109390
+ mkdirSync6(join14(cwd, ".percher"), { recursive: true });
109391
+ writeFileSync6(join14(cwd, ".percher", "agent-instructions.md"), agentInstructions);
109208
109392
  files.push(".percher/agent-instructions.md");
109209
109393
  return { files };
109210
109394
  }
@@ -109353,8 +109537,8 @@ async function githubSetupWebhook(ctx, input) {
109353
109537
  };
109354
109538
  }
109355
109539
  // ../core/dist/commands/import-project.js
109356
- import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "node:fs";
109357
- import { join as join14 } from "node:path";
109540
+ import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
109541
+ import { join as join15 } from "node:path";
109358
109542
 
109359
109543
  // ../core/dist/static-docker.js
109360
109544
  var STATIC_DOCKER_PORT = 8080;
@@ -109415,9 +109599,9 @@ var importInputSchema = exports_external.object({
109415
109599
  app: exports_external.string().optional().describe("App name to import into")
109416
109600
  });
109417
109601
  function detectProvider(cwd) {
109418
- if (existsSync10(join14(cwd, "vercel.json")))
109602
+ if (existsSync11(join15(cwd, "vercel.json")))
109419
109603
  return "vercel";
109420
- if (existsSync10(join14(cwd, "netlify.toml")))
109604
+ if (existsSync11(join15(cwd, "netlify.toml")))
109421
109605
  return "netlify";
109422
109606
  return null;
109423
109607
  }
@@ -109435,7 +109619,7 @@ function mapVercelFramework(framework) {
109435
109619
  return map2[framework ?? ""] ?? { runtime: "node" };
109436
109620
  }
109437
109621
  function parseVercelJson(cwd) {
109438
- const raw = readFileSync8(join14(cwd, "vercel.json"), "utf-8");
109622
+ const raw = readFileSync8(join15(cwd, "vercel.json"), "utf-8");
109439
109623
  const config2 = JSON.parse(raw);
109440
109624
  const warnings = [];
109441
109625
  const envVars = [];
@@ -109489,12 +109673,12 @@ health = "/api/health"
109489
109673
  return { toml, warnings, envVars, staticBuild };
109490
109674
  }
109491
109675
  function parseNetlifyToml(cwd) {
109492
- const raw = readFileSync8(join14(cwd, "netlify.toml"), "utf-8");
109676
+ const raw = readFileSync8(join15(cwd, "netlify.toml"), "utf-8");
109493
109677
  const warnings = [];
109494
109678
  const envVars = [];
109495
109679
  const buildCommand = raw.match(/command\s*=\s*"([^"]+)"/)?.[1] ?? "bun run build";
109496
109680
  const publishDir = raw.match(/publish\s*=\s*"([^"]+)"/)?.[1] ?? "dist";
109497
- const hasPackageJson = existsSync10(join14(cwd, "package.json"));
109681
+ const hasPackageJson = existsSync11(join15(cwd, "package.json"));
109498
109682
  const looksLikeStaticOutput = publishDir === "dist" || publishDir === "build" || publishDir === "public";
109499
109683
  let toml = `[app]
109500
109684
  name = "imported-app"
@@ -109565,11 +109749,11 @@ async function importProject(ctx, input = {}) {
109565
109749
  hint: "Supported providers: vercel, netlify"
109566
109750
  });
109567
109751
  }
109568
- const tomlPath = join14(ctx.cwd, "percher.toml");
109569
- if (existsSync10(tomlPath)) {
109752
+ const tomlPath = join15(ctx.cwd, "percher.toml");
109753
+ if (existsSync11(tomlPath)) {
109570
109754
  result.warnings.unshift("percher.toml already exists — overwriting with imported config");
109571
109755
  }
109572
- writeFileSync6(tomlPath, result.toml);
109756
+ writeFileSync7(tomlPath, result.toml);
109573
109757
  const scaffoldedFiles = [];
109574
109758
  if (result.staticBuild) {
109575
109759
  const targets = [
@@ -109583,12 +109767,12 @@ async function importProject(ctx, input = {}) {
109583
109767
  }
109584
109768
  ];
109585
109769
  for (const { name, content } of targets) {
109586
- const target = join14(ctx.cwd, name);
109587
- if (existsSync10(target)) {
109770
+ const target = join15(ctx.cwd, name);
109771
+ if (existsSync11(target)) {
109588
109772
  result.warnings.push(`${name} already exists — left untouched. The imported config expects a multi-stage static build; merge by hand if needed.`);
109589
109773
  continue;
109590
109774
  }
109591
- writeFileSync6(target, content, "utf-8");
109775
+ writeFileSync7(target, content, "utf-8");
109592
109776
  scaffoldedFiles.push(name);
109593
109777
  }
109594
109778
  }
@@ -109601,14 +109785,14 @@ async function importProject(ctx, input = {}) {
109601
109785
  };
109602
109786
  }
109603
109787
  // ../core/dist/commands/init.js
109604
- import { existsSync as existsSync12, writeFileSync as writeFileSync7 } from "node:fs";
109605
- import { basename as basename2, join as join16 } from "node:path";
109788
+ import { existsSync as existsSync13, writeFileSync as writeFileSync8 } from "node:fs";
109789
+ import { basename as basename3, join as join17 } from "node:path";
109606
109790
 
109607
109791
  // ../core/dist/detect.js
109608
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
109609
- import { join as join15 } from "node:path";
109792
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
109793
+ import { join as join16 } from "node:path";
109610
109794
  function exists(dir, ...names) {
109611
- return names.some((n) => existsSync11(join15(dir, n)));
109795
+ return names.some((n) => existsSync12(join16(dir, n)));
109612
109796
  }
109613
109797
  function readJson(path) {
109614
109798
  try {
@@ -109637,8 +109821,8 @@ function detectDataMode(pkg, cwd) {
109637
109821
  return { mode: "none" };
109638
109822
  }
109639
109823
  async function detectFramework(cwd) {
109640
- const pkgPath = join15(cwd, "package.json");
109641
- const pkg = existsSync11(pkgPath) ? readJson(pkgPath) : null;
109824
+ const pkgPath = join16(cwd, "package.json");
109825
+ const pkg = existsSync12(pkgPath) ? readJson(pkgPath) : null;
109642
109826
  if (exists(cwd, "Dockerfile")) {
109643
109827
  return {
109644
109828
  runtime: "docker",
@@ -109740,7 +109924,7 @@ async function detectFramework(cwd) {
109740
109924
  }
109741
109925
  const hasPython = exists(cwd, "requirements.txt", "pyproject.toml");
109742
109926
  if (hasPython) {
109743
- if (existsSync11(join15(cwd, "manage.py"))) {
109927
+ if (existsSync12(join16(cwd, "manage.py"))) {
109744
109928
  return {
109745
109929
  runtime: "python",
109746
109930
  framework: "django",
@@ -109748,7 +109932,7 @@ async function detectFramework(cwd) {
109748
109932
  data: detectDataMode(pkg, cwd)
109749
109933
  };
109750
109934
  }
109751
- const mainPy = existsSync11(join15(cwd, "main.py")) ? readFileSync9(join15(cwd, "main.py"), "utf8") : "";
109935
+ const mainPy = existsSync12(join16(cwd, "main.py")) ? readFileSync9(join16(cwd, "main.py"), "utf8") : "";
109752
109936
  if (/FastAPI\s*\(/.test(mainPy) || /from\s+fastapi/.test(mainPy)) {
109753
109937
  return {
109754
109938
  runtime: "python",
@@ -109757,7 +109941,7 @@ async function detectFramework(cwd) {
109757
109941
  data: detectDataMode(pkg, cwd)
109758
109942
  };
109759
109943
  }
109760
- const appPy = existsSync11(join15(cwd, "app.py")) ? readFileSync9(join15(cwd, "app.py"), "utf8") : "";
109944
+ const appPy = existsSync12(join16(cwd, "app.py")) ? readFileSync9(join16(cwd, "app.py"), "utf8") : "";
109761
109945
  if (/Flask\s*\(/.test(appPy) || /from\s+flask/.test(appPy)) {
109762
109946
  return {
109763
109947
  runtime: "python",
@@ -109772,7 +109956,7 @@ async function detectFramework(cwd) {
109772
109956
  data: detectDataMode(pkg, cwd)
109773
109957
  };
109774
109958
  }
109775
- if (existsSync11(join15(cwd, "index.html"))) {
109959
+ if (existsSync12(join16(cwd, "index.html"))) {
109776
109960
  return { runtime: "static" };
109777
109961
  }
109778
109962
  return null;
@@ -109822,8 +110006,8 @@ function scanEnvVars(_cwd) {
109822
110006
  return {};
109823
110007
  }
109824
110008
  async function init(ctx, input = {}) {
109825
- const path = join16(ctx.cwd, "percher.toml");
109826
- const exists2 = existsSync12(path);
110009
+ const path = join17(ctx.cwd, "percher.toml");
110010
+ const exists2 = existsSync13(path);
109827
110011
  if (exists2 && !input.force) {
109828
110012
  throw new PercherCoreError("percher.toml already exists", {
109829
110013
  code: "init.exists",
@@ -109836,7 +110020,7 @@ async function init(ctx, input = {}) {
109836
110020
  if (input.name) {
109837
110021
  name = input.name;
109838
110022
  } else {
109839
- const suggestion = generateName(basename2(ctx.cwd));
110023
+ const suggestion = generateName(basename3(ctx.cwd));
109840
110024
  const interactive = input.interactive ?? detectInteractive();
109841
110025
  if (isSuspiciousAutoName(suggestion) && interactive) {
109842
110026
  const answer = (await ctx.prompt(`Suggested app name: '${suggestion}'. Press Enter to accept, or type a different name: `, { default: suggestion })).trim();
@@ -109870,7 +110054,7 @@ async function init(ctx, input = {}) {
109870
110054
  if (Object.keys(envVars).length > 0) {
109871
110055
  config2.env = envVars;
109872
110056
  }
109873
- writeFileSync7(path, serialize(config2), "utf8");
110057
+ writeFileSync8(path, serialize(config2), "utf8");
109874
110058
  const scaffoldedFiles = [];
109875
110059
  if (detected?.staticBuild) {
109876
110060
  const targets = [
@@ -109886,10 +110070,10 @@ async function init(ctx, input = {}) {
109886
110070
  }
109887
110071
  ];
109888
110072
  for (const { name: name2, content } of targets) {
109889
- const target = join16(ctx.cwd, name2);
109890
- if (existsSync12(target) && !input.force)
110073
+ const target = join17(ctx.cwd, name2);
110074
+ if (existsSync13(target) && !input.force)
109891
110075
  continue;
109892
- writeFileSync7(target, content, "utf8");
110076
+ writeFileSync8(target, content, "utf8");
109893
110077
  scaffoldedFiles.push(name2);
109894
110078
  }
109895
110079
  }
@@ -109973,7 +110157,7 @@ async function login(ctx, input = {}) {
109973
110157
  return validateAndPersist(ctx, input.apiUrl, result.token);
109974
110158
  }
109975
110159
  if (code.interval > 0) {
109976
- await new Promise((resolve6) => setTimeout(resolve6, code.interval * 1000));
110160
+ await new Promise((resolve7) => setTimeout(resolve7, code.interval * 1000));
109977
110161
  }
109978
110162
  }
109979
110163
  throw new PercherCoreError("Login timed out. Re-run `percher login`.", {
@@ -110890,7 +111074,7 @@ function collectWarnings2(collections, rlsPolicies, unsupported) {
110890
111074
  }
110891
111075
  // ../core/dist/commands/migrate-supabase-rewrite.js
110892
111076
  import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
110893
- import { dirname as dirname5, join as join19, relative as relative5, resolve as resolve8, sep as sep4 } from "node:path";
111077
+ import { dirname as dirname6, join as join20, relative as relative6, resolve as resolve9, sep as sep5 } from "node:path";
110894
111078
 
110895
111079
  // ../core/dist/commands/migrate-supabase-recipes.js
110896
111080
  var AUTH_RECIPES = {
@@ -111156,7 +111340,7 @@ function isSupabaseClientModule(source) {
111156
111340
  // ../core/dist/commands/migrate-supabase-status.js
111157
111341
  var import_cross_spawn = __toESM(require_cross_spawn(), 1);
111158
111342
  import { readFile as readFile4 } from "node:fs/promises";
111159
- import { join as join18, relative as relative4, resolve as resolve7 } from "node:path";
111343
+ import { join as join19, relative as relative5, resolve as resolve8 } from "node:path";
111160
111344
 
111161
111345
  // ../core/dist/commands/migrate-supabase-sdk.js
111162
111346
  var import_jscodeshift2 = __toESM(require_core3(), 1);
@@ -112093,7 +112277,7 @@ function applyRewrite(path, replacement, kind, pattern, note, flags, state) {
112093
112277
  // ../core/dist/commands/migrate-supabase-walker.js
112094
112278
  var import_ignore3 = __toESM(require_ignore(), 1);
112095
112279
  import { mkdir as mkdir2, readdir, readFile as readFile3, stat, writeFile as writeFile2 } from "node:fs/promises";
112096
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join17, relative as relative3, resolve as resolve6, sep as sep3 } from "node:path";
112280
+ import { dirname as dirname5, isAbsolute as isAbsolute3, join as join18, relative as relative4, resolve as resolve7, sep as sep4 } from "node:path";
112097
112281
  var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
112098
112282
  var DEFAULT_EXCLUDES = [
112099
112283
  "node_modules",
@@ -112114,7 +112298,7 @@ var DEFAULT_EXCLUDES = [
112114
112298
  "pb_migrations"
112115
112299
  ];
112116
112300
  async function walkSupabaseProject(input) {
112117
- const rootAbs = resolve6(input.rootDir);
112301
+ const rootAbs = resolve7(input.rootDir);
112118
112302
  const ig = import_ignore3.default().add(DEFAULT_EXCLUDES);
112119
112303
  if (input.extraExcludes && input.extraExcludes.length > 0) {
112120
112304
  ig.add(input.extraExcludes);
@@ -112123,7 +112307,7 @@ async function walkSupabaseProject(input) {
112123
112307
  const skipped = [];
112124
112308
  const pendingConfig = [];
112125
112309
  for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
112126
- const rel = relative3(rootAbs, absPath).split(sep3).join("/");
112310
+ const rel = relative4(rootAbs, absPath).split(sep4).join("/");
112127
112311
  const kind = classifyFile2(rel);
112128
112312
  if (kind === null)
112129
112313
  continue;
@@ -112245,8 +112429,8 @@ async function* walkTree(dir, rootAbs, ig) {
112245
112429
  return;
112246
112430
  }
112247
112431
  for (const name of entries) {
112248
- const abs = join17(dir, name);
112249
- const rel = relative3(rootAbs, abs).split(sep3).join("/");
112432
+ const abs = join18(dir, name);
112433
+ const rel = relative4(rootAbs, abs).split(sep4).join("/");
112250
112434
  if (rel.length > 0 && ig.ignores(rel))
112251
112435
  continue;
112252
112436
  let st;
@@ -112395,19 +112579,19 @@ function extractPublicPrefix(key) {
112395
112579
  return "";
112396
112580
  }
112397
112581
  async function writeWalkResult(input) {
112398
- const targetAbs = resolve6(input.targetDir);
112582
+ const targetAbs = resolve7(input.targetDir);
112399
112583
  const changedOnly = input.changedOnly !== false;
112400
112584
  const written = [];
112401
112585
  for (const file2 of input.result.files) {
112402
112586
  if (changedOnly && !file2.changed)
112403
112587
  continue;
112404
- const abs = resolve6(targetAbs, file2.relativePath);
112405
- const rel = relative3(targetAbs, abs);
112406
- const isParentTraversal = rel === ".." || rel.startsWith(`..${sep3}`) || rel.startsWith("../");
112407
- if (rel.length === 0 || isParentTraversal || isAbsolute2(rel)) {
112588
+ const abs = resolve7(targetAbs, file2.relativePath);
112589
+ const rel = relative4(targetAbs, abs);
112590
+ const isParentTraversal = rel === ".." || rel.startsWith(`..${sep4}`) || rel.startsWith("../");
112591
+ if (rel.length === 0 || isParentTraversal || isAbsolute3(rel)) {
112408
112592
  throw new Error(`writeWalkResult refused path-traversing file "${file2.relativePath}" → "${abs}" (would escape targetDir "${targetAbs}").`);
112409
112593
  }
112410
- await mkdir2(dirname4(abs), { recursive: true });
112594
+ await mkdir2(dirname5(abs), { recursive: true });
112411
112595
  await writeFile2(abs, file2.rewritten, "utf8");
112412
112596
  written.push(file2.relativePath);
112413
112597
  }
@@ -112620,8 +112804,8 @@ var STATE_SUMMARY = {
112620
112804
  complete: "Migration looks complete — no Supabase usage remains."
112621
112805
  };
112622
112806
  async function migrationStatus(ctx, input) {
112623
- const rootAbs = input.rootDir ? resolve7(ctx.cwd, input.rootDir) : resolve7(ctx.cwd);
112624
- ctx.status(`Scanning ${relative4(ctx.cwd, rootAbs) || "."} for migration status...`);
112807
+ const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
112808
+ ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for migration status...`);
112625
112809
  let files;
112626
112810
  try {
112627
112811
  const walk2 = await walkSupabaseProject({ rootDir: rootAbs });
@@ -112682,7 +112866,7 @@ function buildPrompt(state, failing, warning, build) {
112682
112866
  async function readManualRlsCount(rootAbs) {
112683
112867
  for (const dir of ["migration-preview", "."]) {
112684
112868
  try {
112685
- const notes = await readFile4(join18(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
112869
+ const notes = await readFile4(join19(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
112686
112870
  const m = notes.match(/\*\*RLS policies:\*\*\s*\d+\s*\((\d+)\s*need manual review\)/);
112687
112871
  if (m?.[1] !== undefined)
112688
112872
  return Number.parseInt(m[1], 10);
@@ -112694,7 +112878,7 @@ async function readManualRlsCount(rootAbs) {
112694
112878
  async function runProjectBuild(rootAbs) {
112695
112879
  let hasBuildScript = false;
112696
112880
  try {
112697
- const pkg = JSON.parse(await readFile4(join18(rootAbs, "package.json"), "utf8"));
112881
+ const pkg = JSON.parse(await readFile4(join19(rootAbs, "package.json"), "utf8"));
112698
112882
  hasBuildScript = typeof pkg.scripts?.build === "string";
112699
112883
  } catch {
112700
112884
  return { ran: false, passed: false, detail: "No readable package.json — nothing to build." };
@@ -112726,7 +112910,7 @@ ${tail}` : ""}`
112726
112910
  async function detectPackageManager(rootAbs) {
112727
112911
  const has = async (name) => {
112728
112912
  try {
112729
- await readFile4(join18(rootAbs, name), "utf8");
112913
+ await readFile4(join19(rootAbs, name), "utf8");
112730
112914
  return true;
112731
112915
  } catch {
112732
112916
  return false;
@@ -112741,7 +112925,7 @@ async function detectPackageManager(rootAbs) {
112741
112925
  return "npm";
112742
112926
  }
112743
112927
  function spawnCapture(cmd, args, cwd, timeoutMs) {
112744
- return new Promise((resolve8) => {
112928
+ return new Promise((resolve9) => {
112745
112929
  const child = import_cross_spawn.default(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
112746
112930
  let output = "";
112747
112931
  const onData = (chunk) => {
@@ -112758,11 +112942,11 @@ function spawnCapture(cmd, args, cwd, timeoutMs) {
112758
112942
  }, timeoutMs);
112759
112943
  child.on("error", (err) => {
112760
112944
  clearTimeout(timer);
112761
- resolve8({ code: 1, output, timedOut, spawnError: err.message });
112945
+ resolve9({ code: 1, output, timedOut, spawnError: err.message });
112762
112946
  });
112763
112947
  child.on("close", (code) => {
112764
112948
  clearTimeout(timer);
112765
- resolve8({ code: code ?? 1, output, timedOut });
112949
+ resolve9({ code: code ?? 1, output, timedOut });
112766
112950
  });
112767
112951
  });
112768
112952
  }
@@ -112805,10 +112989,10 @@ var rewriteSupabaseClientInputSchema = exports_external.object({
112805
112989
  scaffoldClient: exports_external.boolean().optional().describe("Generate a PocketBase client module (src/lib/pocketbase.<ext>) and insert `import { pb }` into rewritten files. Default true when there are rewrites; pass false to opt out. Skips silently if a pb client already exists.")
112806
112990
  });
112807
112991
  async function rewriteSupabaseClient(ctx, input) {
112808
- const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
112992
+ const rootAbs = input.rootDir ? resolve9(ctx.cwd, input.rootDir) : resolve9(ctx.cwd);
112809
112993
  const apply = input.apply === true;
112810
112994
  const mode = apply ? "apply" : "preview";
112811
- ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
112995
+ ctx.status(`Scanning ${relative6(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
112812
112996
  let walk2;
112813
112997
  try {
112814
112998
  walk2 = await walkSupabaseProject({
@@ -112817,7 +113001,7 @@ async function rewriteSupabaseClient(ctx, input) {
112817
113001
  supabaseIdentifiers: input.supabaseIdentifiers
112818
113002
  });
112819
113003
  } catch (err) {
112820
- return failure3(rootAbs, mode, err, `Couldn't scan ${relative5(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
113004
+ return failure3(rootAbs, mode, err, `Couldn't scan ${relative6(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
112821
113005
  }
112822
113006
  const changed = walk2.files.filter((f) => f.changed);
112823
113007
  const flags = collectManualFlags(walk2);
@@ -112856,8 +113040,8 @@ async function rewriteSupabaseClient(ctx, input) {
112856
113040
  flags.push(...scaffold.flags);
112857
113041
  }
112858
113042
  const reportNeeded = hadRewrites || flags.length > 0 || walk2.skipped.length > 0;
112859
- const backupDir = apply && changed.length > 0 ? join19(rootAbs, "migration-preview", "backup") : null;
112860
- const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve8(ctx.cwd, input.outputDir) : join19(rootAbs, "migration-preview", "rewritten");
113043
+ const backupDir = apply && changed.length > 0 ? join20(rootAbs, "migration-preview", "backup") : null;
113044
+ const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve9(ctx.cwd, input.outputDir) : join20(rootAbs, "migration-preview", "rewritten");
112861
113045
  const filesWritten = [];
112862
113046
  let clientModuleWritten = null;
112863
113047
  try {
@@ -112877,19 +113061,19 @@ async function rewriteSupabaseClient(ctx, input) {
112877
113061
  changedOnly: true
112878
113062
  });
112879
113063
  for (const rel of out.written) {
112880
- filesWritten.push(relative5(ctx.cwd, join19(rewriteTarget, rel)));
113064
+ filesWritten.push(relative6(ctx.cwd, join20(rewriteTarget, rel)));
112881
113065
  }
112882
113066
  if (scaffold?.clientModule) {
112883
- const moduleAbs = join19(rewriteTarget, scaffold.clientModule.relativePath);
112884
- await mkdir3(dirname5(moduleAbs), { recursive: true });
113067
+ const moduleAbs = join20(rewriteTarget, scaffold.clientModule.relativePath);
113068
+ await mkdir3(dirname6(moduleAbs), { recursive: true });
112885
113069
  await writeFile3(moduleAbs, scaffold.clientModule.content, "utf8");
112886
- clientModuleWritten = relative5(ctx.cwd, moduleAbs).split(sep4).join("/");
113070
+ clientModuleWritten = relative6(ctx.cwd, moduleAbs).split(sep5).join("/");
112887
113071
  filesWritten.push(clientModuleWritten);
112888
113072
  }
112889
113073
  }
112890
113074
  if (reportNeeded) {
112891
- const reportAbs = join19(rootAbs, "migration-preview", "REWRITE_NOTES.md");
112892
- await mkdir3(dirname5(reportAbs), { recursive: true });
113075
+ const reportAbs = join20(rootAbs, "migration-preview", "REWRITE_NOTES.md");
113076
+ await mkdir3(dirname6(reportAbs), { recursive: true });
112893
113077
  const analysis = analyzeMigration(walk2.files.map((f) => ({
112894
113078
  relativePath: f.relativePath,
112895
113079
  kind: f.kind,
@@ -112905,7 +113089,7 @@ async function rewriteSupabaseClient(ctx, input) {
112905
113089
  scaffoldedClient: scaffold?.clientModule?.relativePath ?? null,
112906
113090
  scaffoldSkippedExisting: scaffold?.skippedReason === "pb_client_exists"
112907
113091
  }), "utf8");
112908
- filesWritten.push(relative5(ctx.cwd, reportAbs));
113092
+ filesWritten.push(relative6(ctx.cwd, reportAbs));
112909
113093
  }
112910
113094
  } catch (err) {
112911
113095
  return failure3(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.");
@@ -113141,7 +113325,7 @@ function failure3(rootAbs, mode, err, suggestion) {
113141
113325
  }
113142
113326
  // ../core/dist/commands/migrate-supabase-schema.js
113143
113327
  import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
113144
- import { isAbsolute as isAbsolute3, join as join20, relative as relative6, resolve as resolve9 } from "node:path";
113328
+ import { isAbsolute as isAbsolute4, join as join21, relative as relative7, resolve as resolve10 } from "node:path";
113145
113329
 
113146
113330
  // ../core/dist/commands/migrate-supabase-scripts.js
113147
113331
  function generateDataImportScripts(preview) {
@@ -113589,7 +113773,7 @@ var migrateSupabaseSchemaInputSchema = exports_external.object({
113589
113773
  });
113590
113774
  async function migrateSupabaseSchema(ctx, input) {
113591
113775
  const outputDirAbs = resolveOutputDir(ctx.cwd, input.outputDir);
113592
- const outputDirRel = relative6(ctx.cwd, outputDirAbs) || ".";
113776
+ const outputDirRel = relative7(ctx.cwd, outputDirAbs) || ".";
113593
113777
  ctx.status(`Inspecting Supabase project ${input.projectRef}...`);
113594
113778
  const inspection = await inspectSupabase(ctx, {
113595
113779
  projectRef: input.projectRef,
@@ -113653,28 +113837,28 @@ async function migrateSupabaseSchema(ctx, input) {
113653
113837
  }
113654
113838
  function resolveOutputDir(cwd, requested) {
113655
113839
  const raw = requested ?? "./migration-preview";
113656
- return isAbsolute3(raw) ? raw : resolve9(cwd, raw);
113840
+ return isAbsolute4(raw) ? raw : resolve10(cwd, raw);
113657
113841
  }
113658
113842
  async function writePreviewFiles(ctx, outputDir, preview) {
113659
113843
  await mkdir4(outputDir, { recursive: true });
113660
113844
  const schemaJson = renderSchemaJson(preview);
113661
113845
  const notesMd = renderMigrationNotes(preview);
113662
113846
  const scripts = generateDataImportScripts(preview);
113663
- const schemaPath = join20(outputDir, "pb_schema.json");
113664
- const notesPath = join20(outputDir, "MIGRATION_NOTES.md");
113665
- const migratePath = join20(outputDir, "pb_migrate.js");
113666
- const storagePath = join20(outputDir, "pb_migrate_storage.js");
113847
+ const schemaPath = join21(outputDir, "pb_schema.json");
113848
+ const notesPath = join21(outputDir, "MIGRATION_NOTES.md");
113849
+ const migratePath = join21(outputDir, "pb_migrate.js");
113850
+ const storagePath = join21(outputDir, "pb_migrate_storage.js");
113667
113851
  await writeFile4(schemaPath, schemaJson, "utf8");
113668
113852
  await writeFile4(notesPath, notesMd, "utf8");
113669
113853
  await writeFile4(migratePath, scripts.pbMigrate, "utf8");
113670
113854
  const written = [
113671
- relative6(ctx.cwd, schemaPath),
113672
- relative6(ctx.cwd, notesPath),
113673
- relative6(ctx.cwd, migratePath)
113855
+ relative7(ctx.cwd, schemaPath),
113856
+ relative7(ctx.cwd, notesPath),
113857
+ relative7(ctx.cwd, migratePath)
113674
113858
  ];
113675
113859
  if (scripts.pbMigrateStorage !== null) {
113676
113860
  await writeFile4(storagePath, scripts.pbMigrateStorage, "utf8");
113677
- written.push(relative6(ctx.cwd, storagePath));
113861
+ written.push(relative7(ctx.cwd, storagePath));
113678
113862
  }
113679
113863
  return written;
113680
113864
  }
@@ -113889,8 +114073,8 @@ async function previewBranchShow(ctx, input = {}) {
113889
114073
  };
113890
114074
  }
113891
114075
  // ../core/dist/commands/publish.js
113892
- import { existsSync as existsSync14 } from "node:fs";
113893
- import { join as join23 } from "node:path";
114076
+ import { existsSync as existsSync15 } from "node:fs";
114077
+ import { join as join24 } from "node:path";
113894
114078
 
113895
114079
  // ../shared/dist/pow.js
113896
114080
  import { createHash as createHash3 } from "node:crypto";
@@ -114267,7 +114451,7 @@ async function runDeployWithRetry(opts) {
114267
114451
 
114268
114452
  // ../core/dist/commands/env-scan.js
114269
114453
  import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
114270
- import { join as join21 } from "node:path";
114454
+ import { join as join22 } from "node:path";
114271
114455
  var SOURCE_EXTS = new Set([
114272
114456
  ".ts",
114273
114457
  ".tsx",
@@ -114304,7 +114488,7 @@ function scanForMissingBuildEnvRefs(cwd, existingKeys) {
114304
114488
  continue;
114305
114489
  let content;
114306
114490
  try {
114307
- content = readFileSync10(join21(cwd, rel), "utf8");
114491
+ content = readFileSync10(join22(cwd, rel), "utf8");
114308
114492
  } catch {
114309
114493
  continue;
114310
114494
  }
@@ -114336,7 +114520,7 @@ function* walkDir(dir, base) {
114336
114520
  for (const name of entries) {
114337
114521
  if (SKIP_DIRS.has(name))
114338
114522
  continue;
114339
- const full = join21(dir, name);
114523
+ const full = join22(dir, name);
114340
114524
  let st;
114341
114525
  try {
114342
114526
  st = statSync3(full);
@@ -114696,19 +114880,19 @@ function titleFromCode(code) {
114696
114880
  }
114697
114881
 
114698
114882
  // ../core/dist/commands/publish-node.js
114699
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
114700
- import { join as join22 } from "node:path";
114883
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
114884
+ import { join as join23 } from "node:path";
114701
114885
  function resolveNodeVersion(cwd) {
114702
- const nvmrc = join22(cwd, ".nvmrc");
114703
- if (existsSync13(nvmrc)) {
114886
+ const nvmrc = join23(cwd, ".nvmrc");
114887
+ if (existsSync14(nvmrc)) {
114704
114888
  try {
114705
114889
  const v = readFileSync11(nvmrc, "utf8").trim();
114706
114890
  if (v)
114707
114891
  return { value: v, source: ".nvmrc" };
114708
114892
  } catch {}
114709
114893
  }
114710
- const pkgPath = join22(cwd, "package.json");
114711
- if (!existsSync13(pkgPath))
114894
+ const pkgPath = join23(cwd, "package.json");
114895
+ if (!existsSync14(pkgPath))
114712
114896
  return null;
114713
114897
  try {
114714
114898
  const pkg = JSON.parse(readFileSync11(pkgPath, "utf8"));
@@ -114733,7 +114917,7 @@ var publishInputSchema = exports_external.object({
114733
114917
  var SUSPICIOUS_BYTES = 50 * 1024 * 1024;
114734
114918
  var SUSPICIOUS_FILES = 1e4;
114735
114919
  function tomlPathFor2(cwd) {
114736
- return join23(cwd, "percher.toml");
114920
+ return join24(cwd, "percher.toml");
114737
114921
  }
114738
114922
  async function buildReplacedResult2(opts) {
114739
114923
  const { ctx, app, deployment, tarball, cwd } = opts;
@@ -115398,8 +115582,8 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
115398
115582
  };
115399
115583
  }
115400
115584
  async function loadOrGenerate(ctx) {
115401
- const tomlPath = join23(ctx.cwd, "percher.toml");
115402
- if (!existsSync14(tomlPath)) {
115585
+ const tomlPath = join24(ctx.cwd, "percher.toml");
115586
+ if (!existsSync15(tomlPath)) {
115403
115587
  ctx.status("No percher.toml found — detecting framework...");
115404
115588
  await init(ctx);
115405
115589
  }
@@ -115448,8 +115632,8 @@ function emitPreflight(ctx, config2, tarball) {
115448
115632
  }
115449
115633
  }
115450
115634
  // ../core/dist/commands/push.js
115451
- import { existsSync as existsSync15 } from "node:fs";
115452
- import { join as join24 } from "node:path";
115635
+ import { existsSync as existsSync16 } from "node:fs";
115636
+ import { join as join25 } from "node:path";
115453
115637
  var pushInputSchema = exports_external.object({
115454
115638
  dryRun: exports_external.boolean().optional(),
115455
115639
  force: exports_external.boolean().optional(),
@@ -115460,8 +115644,8 @@ var SUSPICIOUS_BYTES2 = 50 * 1024 * 1024;
115460
115644
  var SUSPICIOUS_FILES2 = 1e4;
115461
115645
  var PLACEHOLDER_PREFIXES = ["add-your-", "your-key-here"];
115462
115646
  async function loadOrGenerate2(ctx) {
115463
- const tomlPath = join24(ctx.cwd, "percher.toml");
115464
- if (!existsSync15(tomlPath)) {
115647
+ const tomlPath = join25(ctx.cwd, "percher.toml");
115648
+ if (!existsSync16(tomlPath)) {
115465
115649
  ctx.status("No percher.toml found — detecting framework...");
115466
115650
  const result = await init(ctx);
115467
115651
  const answer = await ctx.prompt(`Generated percher.toml for ${result.detected?.framework ?? result.detected?.runtime ?? "node"}. Continue? [Y/n]`, { default: "y" });
@@ -115572,7 +115756,7 @@ async function push(ctx, input = {}, internals = {}) {
115572
115756
  fileCount: tarball.fileCount,
115573
115757
  recovery: RECOVERY_NONE,
115574
115758
  summary: `Dry run for ${config2.app.name}: ${tarball.fileCount} files, ${(tarball.bytes / 1024).toFixed(1)} KB — no deploy performed.`,
115575
- configPath: join24(ctx.cwd, "percher.toml"),
115759
+ configPath: join25(ctx.cwd, "percher.toml"),
115576
115760
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115577
115761
  };
115578
115762
  }
@@ -115755,7 +115939,7 @@ ${deployment.errorMessage}` : "";
115755
115939
  fileCount: tarball.fileCount,
115756
115940
  recovery: RECOVERY_NONE,
115757
115941
  summary,
115758
- configPath: join24(ctx.cwd, "percher.toml"),
115942
+ configPath: join25(ctx.cwd, "percher.toml"),
115759
115943
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115760
115944
  };
115761
115945
  }
@@ -116084,8 +116268,8 @@ function failureResult(error48) {
116084
116268
  };
116085
116269
  }
116086
116270
  // ../core/dist/commands/rename.js
116087
- import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
116088
- import { join as join25 } from "node:path";
116271
+ import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
116272
+ import { join as join26 } from "node:path";
116089
116273
  var renameInputSchema = exports_external.object({
116090
116274
  app: exports_external.string().optional(),
116091
116275
  name: exports_external.string().min(3).max(40)
@@ -116105,8 +116289,8 @@ async function rename2(ctx, input) {
116105
116289
  };
116106
116290
  }
116107
116291
  function updateLocalTomlName(cwd, oldName, newName) {
116108
- const p = join25(cwd, "percher.toml");
116109
- if (!existsSync16(p))
116292
+ const p = join26(cwd, "percher.toml");
116293
+ if (!existsSync17(p))
116110
116294
  return false;
116111
116295
  try {
116112
116296
  const src = readFileSync12(p, "utf8");
@@ -116115,25 +116299,25 @@ function updateLocalTomlName(cwd, oldName, newName) {
116115
116299
  const next = src.replace(new RegExp(`(name\\s*=\\s*")${oldName}(")`), `$1${newName}$2`);
116116
116300
  if (next === src || parse5(next).app.name !== newName)
116117
116301
  return false;
116118
- writeFileSync8(p, next);
116302
+ writeFileSync9(p, next);
116119
116303
  return true;
116120
116304
  } catch {
116121
116305
  return false;
116122
116306
  }
116123
116307
  }
116124
116308
  // ../core/dist/commands/reproduce.js
116125
- import { mkdtempSync, writeFileSync as writeFileSync9 } from "node:fs";
116309
+ import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
116126
116310
  import { tmpdir } from "node:os";
116127
- import { join as join26 } from "node:path";
116311
+ import { join as join27 } from "node:path";
116128
116312
  var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
116129
116313
  function runProcessExit(cmd, args, opts = {}) {
116130
- return new Promise((resolve10, reject) => {
116314
+ return new Promise((resolve11, reject) => {
116131
116315
  const child = import_cross_spawn2.default(cmd, args, {
116132
116316
  cwd: opts.cwd,
116133
116317
  stdio: opts.inherit ? "inherit" : "ignore"
116134
116318
  });
116135
116319
  child.on("error", reject);
116136
- child.on("close", (code) => resolve10(code ?? 1));
116320
+ child.on("close", (code) => resolve11(code ?? 1));
116137
116321
  });
116138
116322
  }
116139
116323
  var reproduceInputSchema = exports_external.object({
@@ -116219,9 +116403,9 @@ async function reproduce(ctx, input) {
116219
116403
  const envMap = await ctx.client.env.list(app.id);
116220
116404
  currentAppEnvKeys = Object.keys(envMap).sort();
116221
116405
  } catch {}
116222
- const tmpDir = mkdtempSync(join26(tmpdir(), `percher-reproduce-${input.deployId}-`));
116223
- const tarballPath = join26(tmpDir, "source.tar.gz");
116224
- writeFileSync9(tarballPath, bytes);
116406
+ const tmpDir = mkdtempSync(join27(tmpdir(), `percher-reproduce-${input.deployId}-`));
116407
+ const tarballPath = join27(tmpDir, "source.tar.gz");
116408
+ writeFileSync10(tarballPath, bytes);
116225
116409
  let extracted = false;
116226
116410
  try {
116227
116411
  extracted = await runProcessExit("tar", ["-xzf", tarballPath, "-C", tmpDir]) === 0;
@@ -116658,7 +116842,6 @@ var PLAN_CATALOG = {
116658
116842
  priceEur: 0,
116659
116843
  limits: {
116660
116844
  apps: 3,
116661
- deploysPerMonth: 50,
116662
116845
  deploysPerHour: 12,
116663
116846
  memory: "256mb",
116664
116847
  cpu: 0.25,
@@ -116690,7 +116873,6 @@ var PLAN_CATALOG = {
116690
116873
  priceEur: 3,
116691
116874
  limits: {
116692
116875
  apps: 10,
116693
- deploysPerMonth: 200,
116694
116876
  deploysPerHour: 30,
116695
116877
  memory: "512mb",
116696
116878
  cpu: 0.25,
@@ -116722,7 +116904,6 @@ var PLAN_CATALOG = {
116722
116904
  priceEur: 12,
116723
116905
  limits: {
116724
116906
  apps: 20,
116725
- deploysPerMonth: 500,
116726
116907
  deploysPerHour: 60,
116727
116908
  memory: "1gb",
116728
116909
  cpu: 0.5,
@@ -116754,7 +116935,6 @@ var PLAN_CATALOG = {
116754
116935
  priceEur: 29,
116755
116936
  limits: {
116756
116937
  apps: 40,
116757
- deploysPerMonth: "unlimited",
116758
116938
  deploysPerHour: 120,
116759
116939
  memory: "1gb",
116760
116940
  cpu: 1,
@@ -116787,7 +116967,6 @@ var PLAN_CATALOG = {
116787
116967
  hidden: true,
116788
116968
  limits: {
116789
116969
  apps: 1,
116790
- deploysPerMonth: 20,
116791
116970
  deploysPerHour: 6,
116792
116971
  memory: "128mb",
116793
116972
  cpu: 0.25,
@@ -117479,6 +117658,36 @@ function registerAppsCommands(cli, ctx) {
117479
117658
  await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
117480
117659
  }
117481
117660
  });
117661
+ cli.command("appstore-kit", "Write app-store starter files (PWA manifest, TWA/Capacitor, asset links)").option("--name <name>", "App name (defaults to percher.toml / directory)").option("--url <url>", "App URL (defaults to https://<name>.percher.run)").option("--package <pkg>", "Android package name for assetlinks.json").option("--fingerprint <sha256>", "Signing-cert SHA-256 for assetlinks.json").option("--team-id <id>", "Apple Team ID for apple-app-site-association").option("--bundle-id <id>", "Apple bundle ID for apple-app-site-association").option("--out <dir>", "Output directory (defaults to the current directory)").option("--force", "Overwrite files that already exist").action(async (options) => {
117662
+ const result = await appstoreKit(ctx, {
117663
+ name: options.name,
117664
+ url: options.url,
117665
+ packageName: options.package,
117666
+ fingerprint: options.fingerprint,
117667
+ teamId: options.teamId,
117668
+ bundleId: options.bundleId,
117669
+ outDir: options.out,
117670
+ force: options.force
117671
+ });
117672
+ for (const file2 of result.written) {
117673
+ await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
117674
+ }
117675
+ for (const file2 of result.skipped) {
117676
+ await writeLine(ctx, `${import_picocolors4.default.dim("•")} skipped ${file2} (exists — pass --force to overwrite)`);
117677
+ }
117678
+ await writeLine(ctx, "");
117679
+ await writeLine(ctx, `${import_picocolors4.default.bold("Make it an installable PWA:")} link the manifest from your HTML`);
117680
+ await writeLine(ctx, ` <link rel="manifest" href="/manifest.json">`);
117681
+ await writeLine(ctx, "and register the service worker from your app entry:");
117682
+ await writeLine(ctx, result.swRegistration);
117683
+ await writeLine(ctx, "");
117684
+ await writeLine(ctx, `${import_picocolors4.default.bold("Wrap for Google Play (TWA):")}`);
117685
+ await writeLine(ctx, result.bubblewrapCommand);
117686
+ await writeLine(ctx, "");
117687
+ await writeLine(ctx, `The two ${import_picocolors4.default.dim(".well-known")} files are trust assertions for your origin — add real values`);
117688
+ await writeLine(ctx, `after you sign the apps, then serve them yourself or let Percher serve them from the`);
117689
+ await writeLine(ctx, "App store kit at https://percher.app. Full guide: /docs/app-stores");
117690
+ });
117482
117691
  cli.command("publish", "Publish this project to Percher (recommended deploy command)").option("--force", "Skip size warnings").option("--preview", "Deploy as preview (does not replace the live version)").option("-m, --message <msg>", "Deploy note (visible in deploy history)").option("--dry-run", "Show what would be deployed (file count, bytes) without uploading").option("--no-cache", "Skip image-cache lookup and force a fresh build (use when you suspect cached image is stale)").option("--anonymous", "Publish without an account — a 72h sandbox you can claim later (where enabled)").action(async (options) => {
117483
117692
  const { detectCiBranchMessage: detectCiBranchMessage2 } = await Promise.resolve().then(() => exports_ci_env);
117484
117693
  let messageOverride = options.message;
@@ -117560,8 +117769,8 @@ function registerAppsCommands(cli, ctx) {
117560
117769
  deployId,
117561
117770
  timeoutSeconds: Math.min(Math.ceil(remainingMs / 1000), 30)
117562
117771
  }, { signal: callController.signal }),
117563
- new Promise((resolve10) => {
117564
- raceTimer = setTimeout(() => resolve10(null), remainingMs);
117772
+ new Promise((resolve11) => {
117773
+ raceTimer = setTimeout(() => resolve11(null), remainingMs);
117565
117774
  })
117566
117775
  ]);
117567
117776
  } finally {
@@ -118805,7 +119014,7 @@ async function renderError(stderr, error48) {
118805
119014
  // package.json
118806
119015
  var package_default = {
118807
119016
  name: "percher",
118808
- version: "0.5.8",
119017
+ version: "0.5.9",
118809
119018
  description: "CLI for the Percher hosting platform — publish apps with one command",
118810
119019
  type: "module",
118811
119020
  bin: {
@@ -118886,18 +119095,18 @@ async function showTelemetryNotice() {
118886
119095
  if (isDisabled())
118887
119096
  return;
118888
119097
  const { homedir: homedir2 } = await import("node:os");
118889
- const { existsSync: existsSync17, mkdirSync: mkdirSync6, writeFileSync: writeFileSync10 } = await import("node:fs");
118890
- const { join: join27 } = await import("node:path");
118891
- const configDir = join27(homedir2(), ".percher");
118892
- const markerFile = join27(configDir, ".telemetry-notice-shown");
118893
- if (existsSync17(markerFile))
119098
+ const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync11 } = await import("node:fs");
119099
+ const { join: join28 } = await import("node:path");
119100
+ const configDir = join28(homedir2(), ".percher");
119101
+ const markerFile = join28(configDir, ".telemetry-notice-shown");
119102
+ if (existsSync18(markerFile))
118894
119103
  return;
118895
119104
  console.log("Percher sends non-account-linked usage stats (command, result, error type, OS, Bun version).");
118896
119105
  console.log(`Disable with PERCHER_NO_TELEMETRY=1
118897
119106
  `);
118898
119107
  try {
118899
- mkdirSync6(configDir, { recursive: true });
118900
- writeFileSync10(markerFile, new Date().toISOString());
119108
+ mkdirSync7(configDir, { recursive: true });
119109
+ writeFileSync11(markerFile, new Date().toISOString());
118901
119110
  } catch {}
118902
119111
  }
118903
119112