percher 0.5.8 → 0.5.10

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") {
@@ -90873,10 +90873,6 @@ var CAC = class extends EventTarget {
90873
90873
  };
90874
90874
  var cac = (name = "") => new CAC(name);
90875
90875
 
90876
- // ../core/dist/app-name.js
90877
- import { existsSync, readFileSync } from "node:fs";
90878
- import { join } from "node:path";
90879
-
90880
90876
  // ../toml/dist/errors.js
90881
90877
  class PercherTomlError extends Error {
90882
90878
  code;
@@ -104801,6 +104797,8 @@ function serialize(config2) {
104801
104797
  return import_toml2.default.stringify(config2);
104802
104798
  }
104803
104799
  // ../core/dist/app-name.js
104800
+ import { existsSync, readFileSync } from "node:fs";
104801
+ import { join } from "node:path";
104804
104802
  function readPercherTomlAppName(cwd) {
104805
104803
  const p = join(cwd, "percher.toml");
104806
104804
  if (!existsSync(p))
@@ -105399,6 +105397,181 @@ var appResourcesInputSchema = exports_external.object({
105399
105397
  var appTopologyInputSchema = exports_external.object({
105400
105398
  app: exports_external.string().optional()
105401
105399
  });
105400
+ // ../core/dist/commands/appstore-kit.js
105401
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "node:fs";
105402
+ import { basename, dirname as dirname3, isAbsolute, join as join5, relative, resolve as resolve3, sep } from "node:path";
105403
+
105404
+ // ../core/dist/appstore-artifacts.js
105405
+ var BRAND_GREEN = "#2d6a4f";
105406
+ var ICON_COLOUR_HEX = {
105407
+ green: BRAND_GREEN,
105408
+ terracotta: "#d0653a",
105409
+ blue: "#4a6fa4",
105410
+ purple: "#6e4dba",
105411
+ olive: "#b8923a"
105412
+ };
105413
+ function themeColorForToken(token) {
105414
+ if (token && token in ICON_COLOUR_HEX)
105415
+ return ICON_COLOUR_HEX[token] ?? BRAND_GREEN;
105416
+ return BRAND_GREEN;
105417
+ }
105418
+ function hostFromUrl(url2) {
105419
+ try {
105420
+ return new URL(url2).host;
105421
+ } catch {
105422
+ return url2.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
105423
+ }
105424
+ }
105425
+ function shortName(name) {
105426
+ const cleaned = name.replace(/[^A-Za-z0-9]/g, "");
105427
+ return (cleaned || "App").slice(0, 12);
105428
+ }
105429
+ function manifestStarter({ name, themeColorHex }) {
105430
+ return JSON.stringify({
105431
+ name,
105432
+ short_name: shortName(name),
105433
+ start_url: "/",
105434
+ display: "standalone",
105435
+ background_color: "#ffffff",
105436
+ theme_color: themeColorHex
105437
+ }, null, 2);
105438
+ }
105439
+ function serviceWorkerStarter() {
105440
+ return `// sw.js — minimal offline shell. Drop in at your app root and serve from /sw.js.
105441
+ const CACHE = "app-shell-v1";
105442
+ const SHELL = ["/"];
105443
+
105444
+ self.addEventListener("install", (event) => {
105445
+ event.waitUntil(caches.open(CACHE).then((cache) => cache.addAll(SHELL)));
105446
+ self.skipWaiting();
105447
+ });
105448
+
105449
+ self.addEventListener("activate", (event) => {
105450
+ event.waitUntil(
105451
+ caches.keys().then((keys) =>
105452
+ Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k))),
105453
+ ),
105454
+ );
105455
+ self.clients.claim();
105456
+ });
105457
+
105458
+ self.addEventListener("fetch", (event) => {
105459
+ if (event.request.method !== "GET") return;
105460
+ event.respondWith(
105461
+ caches.match(event.request).then((cached) => cached || fetch(event.request)),
105462
+ );
105463
+ });`;
105464
+ }
105465
+ function swRegistrationSnippet() {
105466
+ return `if ("serviceWorker" in navigator) {
105467
+ navigator.serviceWorker.register("/sw.js");
105468
+ }`;
105469
+ }
105470
+ function bubblewrapCommand({ url: url2 }) {
105471
+ const host = hostFromUrl(url2);
105472
+ return `# generate the Android project, pointed at your manifest
105473
+ npx @bubblewrap/cli init --manifest https://${host}/manifest.json
105474
+ npx @bubblewrap/cli build`;
105475
+ }
105476
+ function capacitorConfig({ name, url: url2 }) {
105477
+ const host = hostFromUrl(url2);
105478
+ return `import type { CapacitorConfig } from "@capacitor/cli";
105479
+ const config: CapacitorConfig = {
105480
+ appId: "app.percher.yourapp",
105481
+ appName: ${JSON.stringify(name)},
105482
+ webDir: "dist",
105483
+ server: { url: "https://${host}", cleartext: false },
105484
+ };
105485
+ export default config;`;
105486
+ }
105487
+ function assetlinksJson({ packageName, sha256Fingerprint }) {
105488
+ const pkg = packageName.trim() || "app.percher.yourapp";
105489
+ const fp = sha256Fingerprint.trim() || "<your signing cert SHA-256>";
105490
+ return `[{
105491
+ "relation": ["delegate_permission/common.handle_all_urls"],
105492
+ "target": {
105493
+ "namespace": "android_app",
105494
+ "package_name": ${JSON.stringify(pkg)},
105495
+ "sha256_cert_fingerprints": [${JSON.stringify(fp)}]
105496
+ }
105497
+ }]`;
105498
+ }
105499
+ function appleAppSiteAssociation({ teamId, bundleId }) {
105500
+ const team = teamId.trim() || "TEAMID";
105501
+ const bundle = bundleId.trim() || "app.percher.yourapp";
105502
+ return `{
105503
+ "applinks": {
105504
+ "apps": [],
105505
+ "details": [{ "appID": ${JSON.stringify(`${team}.${bundle}`)}, "paths": ["*"] }]
105506
+ }
105507
+ }`;
105508
+ }
105509
+
105510
+ // ../core/dist/commands/appstore-kit.js
105511
+ var appstoreKitInputSchema = exports_external.object({
105512
+ name: exports_external.string().optional(),
105513
+ url: exports_external.string().optional(),
105514
+ packageName: exports_external.string().optional(),
105515
+ fingerprint: exports_external.string().optional(),
105516
+ teamId: exports_external.string().optional(),
105517
+ bundleId: exports_external.string().optional(),
105518
+ force: exports_external.boolean().optional(),
105519
+ outDir: exports_external.string().optional()
105520
+ });
105521
+ async function appstoreKit(ctx, input = {}) {
105522
+ const name = (input.name ?? readPercherTomlAppName(ctx.cwd) ?? basename(ctx.cwd) ?? "app").trim() || "app";
105523
+ const url2 = input.url?.trim() || `https://${name}.percher.run`;
105524
+ const themeHex = themeColorForToken(null);
105525
+ const base = resolve3(ctx.cwd, input.outDir ?? ".");
105526
+ const baseRel = relative(ctx.cwd, base);
105527
+ if (baseRel === ".." || baseRel.startsWith(`..${sep}`) || isAbsolute(baseRel)) {
105528
+ throw new PercherCoreError("Output directory must stay inside the project", {
105529
+ code: "appstore-kit.bad-out-dir",
105530
+ hint: "Pass a path inside the current project (e.g. --out public), not an absolute or parent path."
105531
+ });
105532
+ }
105533
+ const files = [
105534
+ { rel: "manifest.json", content: manifestStarter({ name, themeColorHex: themeHex }) },
105535
+ { rel: "sw.js", content: serviceWorkerStarter() },
105536
+ { rel: "capacitor.config.ts", content: capacitorConfig({ name, url: url2 }) },
105537
+ {
105538
+ rel: ".well-known/assetlinks.json",
105539
+ content: assetlinksJson({
105540
+ packageName: input.packageName ?? "",
105541
+ sha256Fingerprint: input.fingerprint ?? ""
105542
+ })
105543
+ },
105544
+ {
105545
+ rel: ".well-known/apple-app-site-association",
105546
+ content: appleAppSiteAssociation({
105547
+ teamId: input.teamId ?? "",
105548
+ bundleId: input.bundleId ?? ""
105549
+ })
105550
+ }
105551
+ ];
105552
+ const written = [];
105553
+ const skipped = [];
105554
+ for (const f of files) {
105555
+ const abs = join5(base, ...f.rel.split("/"));
105556
+ const display = relative(ctx.cwd, abs).split(sep).join("/");
105557
+ if (existsSync3(abs) && !input.force) {
105558
+ skipped.push(display);
105559
+ continue;
105560
+ }
105561
+ mkdirSync3(dirname3(abs), { recursive: true });
105562
+ writeFileSync3(abs, `${f.content}
105563
+ `, "utf8");
105564
+ written.push(display);
105565
+ }
105566
+ return {
105567
+ appName: name,
105568
+ appUrl: url2,
105569
+ written,
105570
+ skipped,
105571
+ bubblewrapCommand: bubblewrapCommand({ url: url2 }),
105572
+ swRegistration: swRegistrationSnippet()
105573
+ };
105574
+ }
105402
105575
  // ../core/dist/commands/billing.js
105403
105576
  var billingUpgradeInputSchema = exports_external.object({
105404
105577
  plan: exports_external.enum(["starter", "maker", "pro"])
@@ -105422,22 +105595,22 @@ async function cacheReset(ctx, input = {}) {
105422
105595
  var capabilitiesInputSchema = exports_external.object({});
105423
105596
  // ../client/dist/abortable-sleep.js
105424
105597
  function abortableSleep(ms, signal) {
105425
- return new Promise((resolve3) => {
105598
+ return new Promise((resolve4) => {
105426
105599
  if (!signal) {
105427
- setTimeout(resolve3, ms);
105600
+ setTimeout(resolve4, ms);
105428
105601
  return;
105429
105602
  }
105430
105603
  if (signal.aborted) {
105431
- resolve3();
105604
+ resolve4();
105432
105605
  return;
105433
105606
  }
105434
105607
  const onAbort = () => {
105435
105608
  clearTimeout(t);
105436
- resolve3();
105609
+ resolve4();
105437
105610
  };
105438
105611
  const t = setTimeout(() => {
105439
105612
  signal.removeEventListener("abort", onAbort);
105440
- resolve3();
105613
+ resolve4();
105441
105614
  }, ms);
105442
105615
  signal.addEventListener("abort", onAbort, { once: true });
105443
105616
  });
@@ -105456,9 +105629,9 @@ function isAutoForwardedBuildKey(name) {
105456
105629
  return AUTO_FORWARD_PREFIXES.some((p) => name.startsWith(p));
105457
105630
  }
105458
105631
  // ../client/dist/config.js
105459
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync3 } from "node:fs";
105632
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync4 } from "node:fs";
105460
105633
  import { homedir } from "node:os";
105461
- import { dirname as dirname3, join as join5 } from "node:path";
105634
+ import { dirname as dirname4, join as join6 } from "node:path";
105462
105635
  var DEFAULT_API_URL = "https://api.percher.run";
105463
105636
  function home() {
105464
105637
  return process.env.HOME ?? process.env.USERPROFILE ?? homedir();
@@ -105466,12 +105639,12 @@ function home() {
105466
105639
  function configPath() {
105467
105640
  const xdg = process.env.XDG_CONFIG_HOME;
105468
105641
  if (xdg)
105469
- return join5(xdg, "percher", "config.json");
105470
- return join5(home(), ".percher", "config.json");
105642
+ return join6(xdg, "percher", "config.json");
105643
+ return join6(home(), ".percher", "config.json");
105471
105644
  }
105472
105645
  function readFile2() {
105473
105646
  const p = configPath();
105474
- if (!existsSync3(p))
105647
+ if (!existsSync4(p))
105475
105648
  return {};
105476
105649
  try {
105477
105650
  const parsed = JSON.parse(readFileSync4(p, "utf8"));
@@ -105499,11 +105672,11 @@ function readAnonClaims() {
105499
105672
  }
105500
105673
  function saveConfig(partial2) {
105501
105674
  const p = configPath();
105502
- mkdirSync3(dirname3(p), { recursive: true });
105675
+ mkdirSync4(dirname4(p), { recursive: true });
105503
105676
  const current = readFile2();
105504
105677
  const merged = { ...current, ...partial2 };
105505
105678
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
105506
- writeFileSync3(tmp, JSON.stringify(merged, null, 2), "utf8");
105679
+ writeFileSync4(tmp, JSON.stringify(merged, null, 2), "utf8");
105507
105680
  renameSync(tmp, p);
105508
105681
  }
105509
105682
  function getAnonClaim(app) {
@@ -105907,6 +106080,15 @@ class AppsResource {
105907
106080
  unsetPreviewBranch(appRef) {
105908
106081
  return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/preview-branch`);
105909
106082
  }
106083
+ listWellKnown(appRef) {
106084
+ return this.http.get(`/apps/${encodeURIComponent(appRef)}/well-known`);
106085
+ }
106086
+ setWellKnown(appRef, kind, content) {
106087
+ return this.http.put(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`, { content });
106088
+ }
106089
+ clearWellKnown(appRef, kind) {
106090
+ return this.http.deleteJson(`/apps/${encodeURIComponent(appRef)}/well-known/${encodeURIComponent(kind)}`);
106091
+ }
105910
106092
  setDescription(appRef, description) {
105911
106093
  return this.http.patch(`/apps/${encodeURIComponent(appRef)}/description`, {
105912
106094
  description
@@ -106582,17 +106764,17 @@ async function claim(ctx, input = {}) {
106582
106764
  };
106583
106765
  }
106584
106766
  // ../core/dist/commands/create.js
106585
- import { join as join7, resolve as resolve4 } from "node:path";
106767
+ import { join as join8, resolve as resolve5 } from "node:path";
106586
106768
 
106587
106769
  // ../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";
106770
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "node:fs";
106771
+ import { basename as basename2, join as join7, normalize, relative as relative2, resolve as resolve4 } from "node:path";
106590
106772
  var __dirname = "C:\\dev\\Percher\\packages\\core\\dist";
106591
- var TEMPLATES_DIR = resolve3(import.meta.dirname ?? __dirname, "../templates");
106773
+ var TEMPLATES_DIR = resolve4(import.meta.dirname ?? __dirname, "../templates");
106592
106774
  var PLACEHOLDER = "__APP_NAME__";
106593
106775
  function listTemplates() {
106594
106776
  return readdirSync(TEMPLATES_DIR).filter((name) => {
106595
- const full = join6(TEMPLATES_DIR, name);
106777
+ const full = join7(TEMPLATES_DIR, name);
106596
106778
  return statSync(full).isDirectory();
106597
106779
  });
106598
106780
  }
@@ -106602,36 +106784,36 @@ function scaffoldTemplate(input) {
106602
106784
  if (!available.includes(template)) {
106603
106785
  throw new Error(`Unknown template "${template}". Available: ${available.join(", ")}`);
106604
106786
  }
106605
- const absTarget = resolve3(targetDir);
106606
- if (existsSync4(absTarget)) {
106787
+ const absTarget = resolve4(targetDir);
106788
+ if (existsSync5(absTarget)) {
106607
106789
  const entries = readdirSync(absTarget);
106608
106790
  if (entries.length > 0 && !force) {
106609
106791
  throw new Error(`Target directory "${absTarget}" is not empty. Use --force to overwrite.`);
106610
106792
  }
106611
106793
  }
106612
- const srcDir = join6(TEMPLATES_DIR, template);
106794
+ const srcDir = join7(TEMPLATES_DIR, template);
106613
106795
  const files = [];
106614
106796
  function copyDir(src, dest) {
106615
- mkdirSync4(dest, { recursive: true });
106797
+ mkdirSync5(dest, { recursive: true });
106616
106798
  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))) {
106799
+ const srcPath = join7(src, entry);
106800
+ const destPath = join7(dest, entry);
106801
+ const rel = relative2(absTarget, normalize(destPath));
106802
+ if (rel.startsWith("..") || resolve4(destPath) === resolve4(absTarget, "..", basename2(absTarget))) {
106621
106803
  throw new Error(`Template contains path traversal: ${entry}`);
106622
106804
  }
106623
106805
  if (statSync(srcPath).isDirectory()) {
106624
106806
  copyDir(srcPath, destPath);
106625
106807
  } else {
106626
- if (existsSync4(destPath) && !force) {
106808
+ if (existsSync5(destPath) && !force) {
106627
106809
  continue;
106628
106810
  }
106629
106811
  let content = readFileSync5(srcPath, "utf-8");
106630
106812
  content = content.replaceAll(PLACEHOLDER, appName);
106631
106813
  content = content.replace(/\r\n/g, `
106632
106814
  `);
106633
- writeFileSync4(destPath, content, "utf-8");
106634
- files.push(relative(absTarget, destPath).replace(/\\/g, "/"));
106815
+ writeFileSync5(destPath, content, "utf-8");
106816
+ files.push(relative2(absTarget, destPath).replace(/\\/g, "/"));
106635
106817
  }
106636
106818
  }
106637
106819
  }
@@ -106656,14 +106838,14 @@ async function create(ctx, input) {
106656
106838
  }
106657
106839
  let targetDir;
106658
106840
  if (input.directory) {
106659
- targetDir = resolve4(ctx.cwd, input.directory);
106660
- if (!targetDir.startsWith(resolve4(ctx.cwd))) {
106841
+ targetDir = resolve5(ctx.cwd, input.directory);
106842
+ if (!targetDir.startsWith(resolve5(ctx.cwd))) {
106661
106843
  throw new PercherCoreError("Directory must be within the current workspace", {
106662
106844
  code: "create.failed"
106663
106845
  });
106664
106846
  }
106665
106847
  } else {
106666
- targetDir = join7(ctx.cwd, input.name);
106848
+ targetDir = join8(ctx.cwd, input.name);
106667
106849
  }
106668
106850
  try {
106669
106851
  const result = scaffoldTemplate({
@@ -106759,7 +106941,7 @@ async function data(ctx, input = {}) {
106759
106941
  };
106760
106942
  }
106761
106943
  // ../core/dist/commands/data-export.js
106762
- import { resolve as resolve5 } from "node:path";
106944
+ import { resolve as resolve6 } from "node:path";
106763
106945
  var dataExportInputSchema = exports_external.object({
106764
106946
  app: exports_external.string().optional().describe("App name or id. Defaults to the app in percher.toml."),
106765
106947
  out: exports_external.string().optional().describe("Output file path. Defaults to ./<app>-pb-<timestamp>.tar.gz in the current directory.")
@@ -106775,7 +106957,7 @@ async function dataExport(ctx, input) {
106775
106957
  ctx.status?.(`Exporting ${appName} data...`);
106776
106958
  const stamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
106777
106959
  const fileName = input.out ?? `${appName}-pb-${stamp}.tar.gz`;
106778
- const path = resolve5(ctx.cwd, fileName);
106960
+ const path = resolve6(ctx.cwd, fileName);
106779
106961
  const res = await ctx.client.apps.streamDataExport(appName);
106780
106962
  const bytes = await writeResponseToFile(res, path);
106781
106963
  return {
@@ -106871,14 +107053,14 @@ async function deploysInspect(ctx, input) {
106871
107053
  return { deploy, buildLog };
106872
107054
  }
106873
107055
  // ../core/dist/commands/dev.js
106874
- import { existsSync as existsSync7 } from "node:fs";
106875
- import { join as join10 } from "node:path";
107056
+ import { existsSync as existsSync8 } from "node:fs";
107057
+ import { join as join11 } from "node:path";
106876
107058
 
106877
107059
  // ../core/dist/tarball.js
106878
107060
  var import_ignore = __toESM(require_ignore(), 1);
106879
107061
  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";
107062
+ import { existsSync as existsSync6, readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync2 } from "node:fs";
107063
+ import { join as join9, relative as relative3, sep as sep2 } from "node:path";
106882
107064
  import { Readable } from "node:stream";
106883
107065
  import { createGzip } from "node:zlib";
106884
107066
 
@@ -106904,8 +107086,8 @@ var DEFAULT_IGNORE = [
106904
107086
  function* walk(dir, baseDir, ig) {
106905
107087
  const entries = readdirSync2(dir);
106906
107088
  for (const name of entries) {
106907
- const full = join8(dir, name);
106908
- const rel = relative2(baseDir, full).split(sep).join("/");
107089
+ const full = join9(dir, name);
107090
+ const rel = relative3(baseDir, full).split(sep2).join("/");
106909
107091
  if (ig.ignores(rel))
106910
107092
  continue;
106911
107093
  const stats = statSync2(full);
@@ -106921,15 +107103,15 @@ function* walk(dir, baseDir, ig) {
106921
107103
  async function createTarball(options) {
106922
107104
  const ig = import_ignore.default();
106923
107105
  ig.add(DEFAULT_IGNORE);
106924
- const gitignorePath = join8(options.cwd, ".gitignore");
106925
- if (existsSync5(gitignorePath)) {
107106
+ const gitignorePath = join9(options.cwd, ".gitignore");
107107
+ if (existsSync6(gitignorePath)) {
106926
107108
  ig.add(readFileSync6(gitignorePath, "utf8"));
106927
107109
  }
106928
107110
  if (options.extraIgnore)
106929
107111
  ig.add(options.extraIgnore);
106930
107112
  const fileBuffers = [];
106931
107113
  for (const rel of walk(options.cwd, options.cwd, ig)) {
106932
- const data2 = readFileSync6(join8(options.cwd, rel));
107114
+ const data2 = readFileSync6(join9(options.cwd, rel));
106933
107115
  fileBuffers.push({ path: rel, size: data2.length, data: data2 });
106934
107116
  }
106935
107117
  fileBuffers.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -106948,8 +107130,8 @@ async function createTarball(options) {
106948
107130
  const pack = $pack();
106949
107131
  (async () => {
106950
107132
  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());
107133
+ await new Promise((resolve7, reject) => {
107134
+ pack.entry({ name: file2.path, size: file2.data.length }, file2.data, (err) => err ? reject(err) : resolve7());
106953
107135
  });
106954
107136
  }
106955
107137
  pack.finalize();
@@ -106969,8 +107151,8 @@ async function createTarball(options) {
106969
107151
 
106970
107152
  // ../core/dist/watcher.js
106971
107153
  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";
107154
+ import { existsSync as existsSync7, readFileSync as readFileSync7, watch } from "node:fs";
107155
+ import { join as join10, sep as sep3 } from "node:path";
106974
107156
  var DEFAULT_IGNORE2 = [
106975
107157
  "node_modules",
106976
107158
  ".git",
@@ -106990,8 +107172,8 @@ function createWatcher(options) {
106990
107172
  const debounceMs = options.debounceMs ?? 500;
106991
107173
  const ig = import_ignore2.default();
106992
107174
  ig.add(DEFAULT_IGNORE2);
106993
- const gitignorePath = join9(options.cwd, ".gitignore");
106994
- if (existsSync6(gitignorePath)) {
107175
+ const gitignorePath = join10(options.cwd, ".gitignore");
107176
+ if (existsSync7(gitignorePath)) {
106995
107177
  ig.add(readFileSync7(gitignorePath, "utf8"));
106996
107178
  }
106997
107179
  if (options.extraIgnore)
@@ -107001,7 +107183,7 @@ function createWatcher(options) {
107001
107183
  const fsWatcher = watch(options.cwd, { recursive: true }, (_event, filename) => {
107002
107184
  if (!filename)
107003
107185
  return;
107004
- const rel = filename.split(sep2).join("/");
107186
+ const rel = filename.split(sep3).join("/");
107005
107187
  if (ig.ignores(rel))
107006
107188
  return;
107007
107189
  pending.add(rel);
@@ -107030,8 +107212,8 @@ var devInputSchema = exports_external.object({
107030
107212
  app: exports_external.string().optional()
107031
107213
  });
107032
107214
  async function loadConfig2(ctx, appOverride) {
107033
- const tomlPath = join10(ctx.cwd, "percher.toml");
107034
- if (!existsSync7(tomlPath)) {
107215
+ const tomlPath = join11(ctx.cwd, "percher.toml");
107216
+ if (!existsSync8(tomlPath)) {
107035
107217
  throw new PercherCoreError("No percher.toml found. Run: percher init", {
107036
107218
  code: "dev.no-app",
107037
107219
  hint: "Create a percher.toml first with `percher init`."
@@ -107185,12 +107367,12 @@ async function dev(ctx, input, callbacks) {
107185
107367
  }
107186
107368
  });
107187
107369
  try {
107188
- await new Promise((resolve6) => {
107370
+ await new Promise((resolve7) => {
107189
107371
  if (callbacks.signal.aborted) {
107190
- resolve6();
107372
+ resolve7();
107191
107373
  return;
107192
107374
  }
107193
- callbacks.signal.addEventListener("abort", () => resolve6(), { once: true });
107375
+ callbacks.signal.addEventListener("abort", () => resolve7(), { once: true });
107194
107376
  });
107195
107377
  } finally {
107196
107378
  logStream.ctrl?.abort();
@@ -107225,8 +107407,8 @@ async function diff(ctx, input = {}) {
107225
107407
  });
107226
107408
  }
107227
107409
  // ../core/dist/commands/doctor.js
107228
- import { existsSync as existsSync8 } from "node:fs";
107229
- import { join as join12 } from "node:path";
107410
+ import { existsSync as existsSync9 } from "node:fs";
107411
+ import { join as join13 } from "node:path";
107230
107412
 
107231
107413
  // ../core/dist/error-classifier.js
107232
107414
  function extractEnvVarsFromLog(combined) {
@@ -107771,7 +107953,7 @@ function recoveryFromErrorClass(errorClass, failure = {}) {
107771
107953
  }
107772
107954
 
107773
107955
  // ../core/dist/commands/publish-failure.js
107774
- import { join as join11 } from "node:path";
107956
+ import { join as join12 } from "node:path";
107775
107957
 
107776
107958
  // ../core/dist/structured-error-codes.js
107777
107959
  var MAPPINGS = {
@@ -107849,7 +108031,7 @@ function trimMessage(raw) {
107849
108031
 
107850
108032
  // ../core/dist/commands/publish-failure.js
107851
108033
  function tomlPathFor(cwd) {
107852
- return join11(cwd, "percher.toml");
108034
+ return join12(cwd, "percher.toml");
107853
108035
  }
107854
108036
  async function buildFailureError(ctx, app, deployment, signal) {
107855
108037
  let buildLogTail;
@@ -108192,8 +108374,8 @@ async function doctor(ctx, input = {}) {
108192
108374
  });
108193
108375
  return summarize(checks3, { appProvided: !!input.app });
108194
108376
  }
108195
- const tomlPath = join12(ctx.cwd, "percher.toml");
108196
- const tomlExists = existsSync8(tomlPath);
108377
+ const tomlPath = join13(ctx.cwd, "percher.toml");
108378
+ const tomlExists = existsSync9(tomlPath);
108197
108379
  let tomlValid = false;
108198
108380
  if (!tomlExists) {
108199
108381
  checks3.push({
@@ -108973,7 +109155,7 @@ async function envList(ctx, input = {}) {
108973
109155
  import { randomUUID } from "node:crypto";
108974
109156
  import { createWriteStream } from "node:fs";
108975
109157
  import { rename, unlink } from "node:fs/promises";
108976
- import { isAbsolute, resolve as resolvePath } from "node:path";
109158
+ import { isAbsolute as isAbsolute2, resolve as resolvePath } from "node:path";
108977
109159
  var exportInputSchema = exports_external.object({
108978
109160
  app: exports_external.string().optional(),
108979
109161
  out: exports_external.string().optional(),
@@ -108997,7 +109179,7 @@ async function streamToFile(outPath, source) {
108997
109179
  const tmpPath = `${outPath}.part-${randomUUID()}`;
108998
109180
  const out = createWriteStream(tmpPath);
108999
109181
  const reader = source.getReader();
109000
- const closed = new Promise((resolve6) => out.once("close", () => resolve6()));
109182
+ const closed = new Promise((resolve7) => out.once("close", () => resolve7()));
109001
109183
  let onWriteError;
109002
109184
  const writeFailed = new Promise((_, reject) => {
109003
109185
  onWriteError = reject;
@@ -109014,14 +109196,14 @@ async function streamToFile(outPath, source) {
109014
109196
  bytes += value.byteLength;
109015
109197
  if (!out.write(value)) {
109016
109198
  await Promise.race([
109017
- new Promise((resolve6) => out.once("drain", resolve6)),
109199
+ new Promise((resolve7) => out.once("drain", resolve7)),
109018
109200
  writeFailed
109019
109201
  ]);
109020
109202
  }
109021
109203
  }
109022
109204
  }
109023
- await new Promise((resolve6, reject) => {
109024
- out.end((err) => err ? reject(err) : resolve6());
109205
+ await new Promise((resolve7, reject) => {
109206
+ out.end((err) => err ? reject(err) : resolve7());
109025
109207
  });
109026
109208
  await closed;
109027
109209
  } catch (err) {
@@ -109039,7 +109221,7 @@ async function streamToFile(outPath, source) {
109039
109221
  return { bytes };
109040
109222
  }
109041
109223
  function resolveOutPath(ctxCwd, filename) {
109042
- if (isAbsolute(filename))
109224
+ if (isAbsolute2(filename))
109043
109225
  return filename;
109044
109226
  return resolvePath(ctxCwd, filename);
109045
109227
  }
@@ -109100,8 +109282,8 @@ var forgejoSetupWebhookInputSchema = exports_external.object({
109100
109282
  app: exports_external.string().optional().describe("App name (overrides percher.toml)")
109101
109283
  });
109102
109284
  // ../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";
109285
+ import { existsSync as existsSync10, mkdirSync as mkdirSync6, writeFileSync as writeFileSync6 } from "node:fs";
109286
+ import { join as join14 } from "node:path";
109105
109287
  var generateInputSchema = exports_external.object({
109106
109288
  cwd: exports_external.string().optional()
109107
109289
  });
@@ -109187,8 +109369,8 @@ function generateTypeScript(config2) {
109187
109369
  }
109188
109370
  async function generate(ctx, input = {}) {
109189
109371
  const cwd = input.cwd ?? ctx.cwd;
109190
- const tomlPath = join13(cwd, "percher.toml");
109191
- if (!existsSync9(tomlPath)) {
109372
+ const tomlPath = join14(cwd, "percher.toml");
109373
+ if (!existsSync10(tomlPath)) {
109192
109374
  throw new PercherCoreError("No percher.toml found", {
109193
109375
  code: "dev.no-app",
109194
109376
  hint: "Run percher init first."
@@ -109197,14 +109379,14 @@ async function generate(ctx, input = {}) {
109197
109379
  const config2 = await parseFile(tomlPath);
109198
109380
  const files = [];
109199
109381
  const envExample = generateEnvExample(config2);
109200
- writeFileSync5(join13(cwd, ".env.example"), envExample);
109382
+ writeFileSync6(join14(cwd, ".env.example"), envExample);
109201
109383
  files.push(".env.example");
109202
109384
  const tsTypes = generateTypeScript(config2);
109203
- writeFileSync5(join13(cwd, "percher.generated.d.ts"), tsTypes);
109385
+ writeFileSync6(join14(cwd, "percher.generated.d.ts"), tsTypes);
109204
109386
  files.push("percher.generated.d.ts");
109205
109387
  const agentInstructions = generateAgentInstructions(config2);
109206
- mkdirSync5(join13(cwd, ".percher"), { recursive: true });
109207
- writeFileSync5(join13(cwd, ".percher", "agent-instructions.md"), agentInstructions);
109388
+ mkdirSync6(join14(cwd, ".percher"), { recursive: true });
109389
+ writeFileSync6(join14(cwd, ".percher", "agent-instructions.md"), agentInstructions);
109208
109390
  files.push(".percher/agent-instructions.md");
109209
109391
  return { files };
109210
109392
  }
@@ -109353,8 +109535,8 @@ async function githubSetupWebhook(ctx, input) {
109353
109535
  };
109354
109536
  }
109355
109537
  // ../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";
109538
+ import { existsSync as existsSync11, readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "node:fs";
109539
+ import { join as join15 } from "node:path";
109358
109540
 
109359
109541
  // ../core/dist/static-docker.js
109360
109542
  var STATIC_DOCKER_PORT = 8080;
@@ -109382,7 +109564,8 @@ FROM caddy:2-alpine AS caddy-source
109382
109564
  FROM alpine:3.21
109383
109565
  COPY --from=caddy-source /usr/bin/caddy /usr/bin/caddy
109384
109566
  RUN apk add --no-cache libcap \\
109385
- && setcap -r /usr/bin/caddy \\
109567
+ && (setcap -r /usr/bin/caddy 2>/dev/null || true) \\
109568
+ && test -z "$(getcap /usr/bin/caddy)" \\
109386
109569
  && apk del libcap \\
109387
109570
  && rm -rf /var/cache/apk/*
109388
109571
  COPY Caddyfile /etc/caddy/Caddyfile
@@ -109415,9 +109598,9 @@ var importInputSchema = exports_external.object({
109415
109598
  app: exports_external.string().optional().describe("App name to import into")
109416
109599
  });
109417
109600
  function detectProvider(cwd) {
109418
- if (existsSync10(join14(cwd, "vercel.json")))
109601
+ if (existsSync11(join15(cwd, "vercel.json")))
109419
109602
  return "vercel";
109420
- if (existsSync10(join14(cwd, "netlify.toml")))
109603
+ if (existsSync11(join15(cwd, "netlify.toml")))
109421
109604
  return "netlify";
109422
109605
  return null;
109423
109606
  }
@@ -109435,7 +109618,7 @@ function mapVercelFramework(framework) {
109435
109618
  return map2[framework ?? ""] ?? { runtime: "node" };
109436
109619
  }
109437
109620
  function parseVercelJson(cwd) {
109438
- const raw = readFileSync8(join14(cwd, "vercel.json"), "utf-8");
109621
+ const raw = readFileSync8(join15(cwd, "vercel.json"), "utf-8");
109439
109622
  const config2 = JSON.parse(raw);
109440
109623
  const warnings = [];
109441
109624
  const envVars = [];
@@ -109489,12 +109672,12 @@ health = "/api/health"
109489
109672
  return { toml, warnings, envVars, staticBuild };
109490
109673
  }
109491
109674
  function parseNetlifyToml(cwd) {
109492
- const raw = readFileSync8(join14(cwd, "netlify.toml"), "utf-8");
109675
+ const raw = readFileSync8(join15(cwd, "netlify.toml"), "utf-8");
109493
109676
  const warnings = [];
109494
109677
  const envVars = [];
109495
109678
  const buildCommand = raw.match(/command\s*=\s*"([^"]+)"/)?.[1] ?? "bun run build";
109496
109679
  const publishDir = raw.match(/publish\s*=\s*"([^"]+)"/)?.[1] ?? "dist";
109497
- const hasPackageJson = existsSync10(join14(cwd, "package.json"));
109680
+ const hasPackageJson = existsSync11(join15(cwd, "package.json"));
109498
109681
  const looksLikeStaticOutput = publishDir === "dist" || publishDir === "build" || publishDir === "public";
109499
109682
  let toml = `[app]
109500
109683
  name = "imported-app"
@@ -109565,11 +109748,11 @@ async function importProject(ctx, input = {}) {
109565
109748
  hint: "Supported providers: vercel, netlify"
109566
109749
  });
109567
109750
  }
109568
- const tomlPath = join14(ctx.cwd, "percher.toml");
109569
- if (existsSync10(tomlPath)) {
109751
+ const tomlPath = join15(ctx.cwd, "percher.toml");
109752
+ if (existsSync11(tomlPath)) {
109570
109753
  result.warnings.unshift("percher.toml already exists — overwriting with imported config");
109571
109754
  }
109572
- writeFileSync6(tomlPath, result.toml);
109755
+ writeFileSync7(tomlPath, result.toml);
109573
109756
  const scaffoldedFiles = [];
109574
109757
  if (result.staticBuild) {
109575
109758
  const targets = [
@@ -109583,12 +109766,12 @@ async function importProject(ctx, input = {}) {
109583
109766
  }
109584
109767
  ];
109585
109768
  for (const { name, content } of targets) {
109586
- const target = join14(ctx.cwd, name);
109587
- if (existsSync10(target)) {
109769
+ const target = join15(ctx.cwd, name);
109770
+ if (existsSync11(target)) {
109588
109771
  result.warnings.push(`${name} already exists — left untouched. The imported config expects a multi-stage static build; merge by hand if needed.`);
109589
109772
  continue;
109590
109773
  }
109591
- writeFileSync6(target, content, "utf-8");
109774
+ writeFileSync7(target, content, "utf-8");
109592
109775
  scaffoldedFiles.push(name);
109593
109776
  }
109594
109777
  }
@@ -109601,14 +109784,14 @@ async function importProject(ctx, input = {}) {
109601
109784
  };
109602
109785
  }
109603
109786
  // ../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";
109787
+ import { existsSync as existsSync13, writeFileSync as writeFileSync8 } from "node:fs";
109788
+ import { basename as basename3, join as join17 } from "node:path";
109606
109789
 
109607
109790
  // ../core/dist/detect.js
109608
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
109609
- import { join as join15 } from "node:path";
109791
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "node:fs";
109792
+ import { join as join16 } from "node:path";
109610
109793
  function exists(dir, ...names) {
109611
- return names.some((n) => existsSync11(join15(dir, n)));
109794
+ return names.some((n) => existsSync12(join16(dir, n)));
109612
109795
  }
109613
109796
  function readJson(path) {
109614
109797
  try {
@@ -109637,8 +109820,8 @@ function detectDataMode(pkg, cwd) {
109637
109820
  return { mode: "none" };
109638
109821
  }
109639
109822
  async function detectFramework(cwd) {
109640
- const pkgPath = join15(cwd, "package.json");
109641
- const pkg = existsSync11(pkgPath) ? readJson(pkgPath) : null;
109823
+ const pkgPath = join16(cwd, "package.json");
109824
+ const pkg = existsSync12(pkgPath) ? readJson(pkgPath) : null;
109642
109825
  if (exists(cwd, "Dockerfile")) {
109643
109826
  return {
109644
109827
  runtime: "docker",
@@ -109740,7 +109923,7 @@ async function detectFramework(cwd) {
109740
109923
  }
109741
109924
  const hasPython = exists(cwd, "requirements.txt", "pyproject.toml");
109742
109925
  if (hasPython) {
109743
- if (existsSync11(join15(cwd, "manage.py"))) {
109926
+ if (existsSync12(join16(cwd, "manage.py"))) {
109744
109927
  return {
109745
109928
  runtime: "python",
109746
109929
  framework: "django",
@@ -109748,7 +109931,7 @@ async function detectFramework(cwd) {
109748
109931
  data: detectDataMode(pkg, cwd)
109749
109932
  };
109750
109933
  }
109751
- const mainPy = existsSync11(join15(cwd, "main.py")) ? readFileSync9(join15(cwd, "main.py"), "utf8") : "";
109934
+ const mainPy = existsSync12(join16(cwd, "main.py")) ? readFileSync9(join16(cwd, "main.py"), "utf8") : "";
109752
109935
  if (/FastAPI\s*\(/.test(mainPy) || /from\s+fastapi/.test(mainPy)) {
109753
109936
  return {
109754
109937
  runtime: "python",
@@ -109757,7 +109940,7 @@ async function detectFramework(cwd) {
109757
109940
  data: detectDataMode(pkg, cwd)
109758
109941
  };
109759
109942
  }
109760
- const appPy = existsSync11(join15(cwd, "app.py")) ? readFileSync9(join15(cwd, "app.py"), "utf8") : "";
109943
+ const appPy = existsSync12(join16(cwd, "app.py")) ? readFileSync9(join16(cwd, "app.py"), "utf8") : "";
109761
109944
  if (/Flask\s*\(/.test(appPy) || /from\s+flask/.test(appPy)) {
109762
109945
  return {
109763
109946
  runtime: "python",
@@ -109772,7 +109955,7 @@ async function detectFramework(cwd) {
109772
109955
  data: detectDataMode(pkg, cwd)
109773
109956
  };
109774
109957
  }
109775
- if (existsSync11(join15(cwd, "index.html"))) {
109958
+ if (existsSync12(join16(cwd, "index.html"))) {
109776
109959
  return { runtime: "static" };
109777
109960
  }
109778
109961
  return null;
@@ -109822,8 +110005,8 @@ function scanEnvVars(_cwd) {
109822
110005
  return {};
109823
110006
  }
109824
110007
  async function init(ctx, input = {}) {
109825
- const path = join16(ctx.cwd, "percher.toml");
109826
- const exists2 = existsSync12(path);
110008
+ const path = join17(ctx.cwd, "percher.toml");
110009
+ const exists2 = existsSync13(path);
109827
110010
  if (exists2 && !input.force) {
109828
110011
  throw new PercherCoreError("percher.toml already exists", {
109829
110012
  code: "init.exists",
@@ -109836,7 +110019,7 @@ async function init(ctx, input = {}) {
109836
110019
  if (input.name) {
109837
110020
  name = input.name;
109838
110021
  } else {
109839
- const suggestion = generateName(basename2(ctx.cwd));
110022
+ const suggestion = generateName(basename3(ctx.cwd));
109840
110023
  const interactive = input.interactive ?? detectInteractive();
109841
110024
  if (isSuspiciousAutoName(suggestion) && interactive) {
109842
110025
  const answer = (await ctx.prompt(`Suggested app name: '${suggestion}'. Press Enter to accept, or type a different name: `, { default: suggestion })).trim();
@@ -109870,7 +110053,7 @@ async function init(ctx, input = {}) {
109870
110053
  if (Object.keys(envVars).length > 0) {
109871
110054
  config2.env = envVars;
109872
110055
  }
109873
- writeFileSync7(path, serialize(config2), "utf8");
110056
+ writeFileSync8(path, serialize(config2), "utf8");
109874
110057
  const scaffoldedFiles = [];
109875
110058
  if (detected?.staticBuild) {
109876
110059
  const targets = [
@@ -109886,10 +110069,10 @@ async function init(ctx, input = {}) {
109886
110069
  }
109887
110070
  ];
109888
110071
  for (const { name: name2, content } of targets) {
109889
- const target = join16(ctx.cwd, name2);
109890
- if (existsSync12(target) && !input.force)
110072
+ const target = join17(ctx.cwd, name2);
110073
+ if (existsSync13(target) && !input.force)
109891
110074
  continue;
109892
- writeFileSync7(target, content, "utf8");
110075
+ writeFileSync8(target, content, "utf8");
109893
110076
  scaffoldedFiles.push(name2);
109894
110077
  }
109895
110078
  }
@@ -109973,7 +110156,7 @@ async function login(ctx, input = {}) {
109973
110156
  return validateAndPersist(ctx, input.apiUrl, result.token);
109974
110157
  }
109975
110158
  if (code.interval > 0) {
109976
- await new Promise((resolve6) => setTimeout(resolve6, code.interval * 1000));
110159
+ await new Promise((resolve7) => setTimeout(resolve7, code.interval * 1000));
109977
110160
  }
109978
110161
  }
109979
110162
  throw new PercherCoreError("Login timed out. Re-run `percher login`.", {
@@ -110890,7 +111073,7 @@ function collectWarnings2(collections, rlsPolicies, unsupported) {
110890
111073
  }
110891
111074
  // ../core/dist/commands/migrate-supabase-rewrite.js
110892
111075
  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";
111076
+ import { dirname as dirname6, join as join20, relative as relative6, resolve as resolve9, sep as sep5 } from "node:path";
110894
111077
 
110895
111078
  // ../core/dist/commands/migrate-supabase-recipes.js
110896
111079
  var AUTH_RECIPES = {
@@ -111156,7 +111339,7 @@ function isSupabaseClientModule(source) {
111156
111339
  // ../core/dist/commands/migrate-supabase-status.js
111157
111340
  var import_cross_spawn = __toESM(require_cross_spawn(), 1);
111158
111341
  import { readFile as readFile4 } from "node:fs/promises";
111159
- import { join as join18, relative as relative4, resolve as resolve7 } from "node:path";
111342
+ import { join as join19, relative as relative5, resolve as resolve8 } from "node:path";
111160
111343
 
111161
111344
  // ../core/dist/commands/migrate-supabase-sdk.js
111162
111345
  var import_jscodeshift2 = __toESM(require_core3(), 1);
@@ -112093,7 +112276,7 @@ function applyRewrite(path, replacement, kind, pattern, note, flags, state) {
112093
112276
  // ../core/dist/commands/migrate-supabase-walker.js
112094
112277
  var import_ignore3 = __toESM(require_ignore(), 1);
112095
112278
  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";
112279
+ import { dirname as dirname5, isAbsolute as isAbsolute3, join as join18, relative as relative4, resolve as resolve7, sep as sep4 } from "node:path";
112097
112280
  var REWRITABLE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
112098
112281
  var DEFAULT_EXCLUDES = [
112099
112282
  "node_modules",
@@ -112114,7 +112297,7 @@ var DEFAULT_EXCLUDES = [
112114
112297
  "pb_migrations"
112115
112298
  ];
112116
112299
  async function walkSupabaseProject(input) {
112117
- const rootAbs = resolve6(input.rootDir);
112300
+ const rootAbs = resolve7(input.rootDir);
112118
112301
  const ig = import_ignore3.default().add(DEFAULT_EXCLUDES);
112119
112302
  if (input.extraExcludes && input.extraExcludes.length > 0) {
112120
112303
  ig.add(input.extraExcludes);
@@ -112123,7 +112306,7 @@ async function walkSupabaseProject(input) {
112123
112306
  const skipped = [];
112124
112307
  const pendingConfig = [];
112125
112308
  for await (const absPath of walkTree(rootAbs, rootAbs, ig)) {
112126
- const rel = relative3(rootAbs, absPath).split(sep3).join("/");
112309
+ const rel = relative4(rootAbs, absPath).split(sep4).join("/");
112127
112310
  const kind = classifyFile2(rel);
112128
112311
  if (kind === null)
112129
112312
  continue;
@@ -112245,8 +112428,8 @@ async function* walkTree(dir, rootAbs, ig) {
112245
112428
  return;
112246
112429
  }
112247
112430
  for (const name of entries) {
112248
- const abs = join17(dir, name);
112249
- const rel = relative3(rootAbs, abs).split(sep3).join("/");
112431
+ const abs = join18(dir, name);
112432
+ const rel = relative4(rootAbs, abs).split(sep4).join("/");
112250
112433
  if (rel.length > 0 && ig.ignores(rel))
112251
112434
  continue;
112252
112435
  let st;
@@ -112395,19 +112578,19 @@ function extractPublicPrefix(key) {
112395
112578
  return "";
112396
112579
  }
112397
112580
  async function writeWalkResult(input) {
112398
- const targetAbs = resolve6(input.targetDir);
112581
+ const targetAbs = resolve7(input.targetDir);
112399
112582
  const changedOnly = input.changedOnly !== false;
112400
112583
  const written = [];
112401
112584
  for (const file2 of input.result.files) {
112402
112585
  if (changedOnly && !file2.changed)
112403
112586
  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)) {
112587
+ const abs = resolve7(targetAbs, file2.relativePath);
112588
+ const rel = relative4(targetAbs, abs);
112589
+ const isParentTraversal = rel === ".." || rel.startsWith(`..${sep4}`) || rel.startsWith("../");
112590
+ if (rel.length === 0 || isParentTraversal || isAbsolute3(rel)) {
112408
112591
  throw new Error(`writeWalkResult refused path-traversing file "${file2.relativePath}" → "${abs}" (would escape targetDir "${targetAbs}").`);
112409
112592
  }
112410
- await mkdir2(dirname4(abs), { recursive: true });
112593
+ await mkdir2(dirname5(abs), { recursive: true });
112411
112594
  await writeFile2(abs, file2.rewritten, "utf8");
112412
112595
  written.push(file2.relativePath);
112413
112596
  }
@@ -112620,8 +112803,8 @@ var STATE_SUMMARY = {
112620
112803
  complete: "Migration looks complete — no Supabase usage remains."
112621
112804
  };
112622
112805
  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...`);
112806
+ const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
112807
+ ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for migration status...`);
112625
112808
  let files;
112626
112809
  try {
112627
112810
  const walk2 = await walkSupabaseProject({ rootDir: rootAbs });
@@ -112682,7 +112865,7 @@ function buildPrompt(state, failing, warning, build) {
112682
112865
  async function readManualRlsCount(rootAbs) {
112683
112866
  for (const dir of ["migration-preview", "."]) {
112684
112867
  try {
112685
- const notes = await readFile4(join18(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
112868
+ const notes = await readFile4(join19(rootAbs, dir, "MIGRATION_NOTES.md"), "utf8");
112686
112869
  const m = notes.match(/\*\*RLS policies:\*\*\s*\d+\s*\((\d+)\s*need manual review\)/);
112687
112870
  if (m?.[1] !== undefined)
112688
112871
  return Number.parseInt(m[1], 10);
@@ -112694,7 +112877,7 @@ async function readManualRlsCount(rootAbs) {
112694
112877
  async function runProjectBuild(rootAbs) {
112695
112878
  let hasBuildScript = false;
112696
112879
  try {
112697
- const pkg = JSON.parse(await readFile4(join18(rootAbs, "package.json"), "utf8"));
112880
+ const pkg = JSON.parse(await readFile4(join19(rootAbs, "package.json"), "utf8"));
112698
112881
  hasBuildScript = typeof pkg.scripts?.build === "string";
112699
112882
  } catch {
112700
112883
  return { ran: false, passed: false, detail: "No readable package.json — nothing to build." };
@@ -112726,7 +112909,7 @@ ${tail}` : ""}`
112726
112909
  async function detectPackageManager(rootAbs) {
112727
112910
  const has = async (name) => {
112728
112911
  try {
112729
- await readFile4(join18(rootAbs, name), "utf8");
112912
+ await readFile4(join19(rootAbs, name), "utf8");
112730
112913
  return true;
112731
112914
  } catch {
112732
112915
  return false;
@@ -112741,7 +112924,7 @@ async function detectPackageManager(rootAbs) {
112741
112924
  return "npm";
112742
112925
  }
112743
112926
  function spawnCapture(cmd, args, cwd, timeoutMs) {
112744
- return new Promise((resolve8) => {
112927
+ return new Promise((resolve9) => {
112745
112928
  const child = import_cross_spawn.default(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
112746
112929
  let output = "";
112747
112930
  const onData = (chunk) => {
@@ -112758,11 +112941,11 @@ function spawnCapture(cmd, args, cwd, timeoutMs) {
112758
112941
  }, timeoutMs);
112759
112942
  child.on("error", (err) => {
112760
112943
  clearTimeout(timer);
112761
- resolve8({ code: 1, output, timedOut, spawnError: err.message });
112944
+ resolve9({ code: 1, output, timedOut, spawnError: err.message });
112762
112945
  });
112763
112946
  child.on("close", (code) => {
112764
112947
  clearTimeout(timer);
112765
- resolve8({ code: code ?? 1, output, timedOut });
112948
+ resolve9({ code: code ?? 1, output, timedOut });
112766
112949
  });
112767
112950
  });
112768
112951
  }
@@ -112805,10 +112988,10 @@ var rewriteSupabaseClientInputSchema = exports_external.object({
112805
112988
  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
112989
  });
112807
112990
  async function rewriteSupabaseClient(ctx, input) {
112808
- const rootAbs = input.rootDir ? resolve8(ctx.cwd, input.rootDir) : resolve8(ctx.cwd);
112991
+ const rootAbs = input.rootDir ? resolve9(ctx.cwd, input.rootDir) : resolve9(ctx.cwd);
112809
112992
  const apply = input.apply === true;
112810
112993
  const mode = apply ? "apply" : "preview";
112811
- ctx.status(`Scanning ${relative5(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
112994
+ ctx.status(`Scanning ${relative6(ctx.cwd, rootAbs) || "."} for Supabase SDK calls...`);
112812
112995
  let walk2;
112813
112996
  try {
112814
112997
  walk2 = await walkSupabaseProject({
@@ -112817,7 +113000,7 @@ async function rewriteSupabaseClient(ctx, input) {
112817
113000
  supabaseIdentifiers: input.supabaseIdentifiers
112818
113001
  });
112819
113002
  } 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.`);
113003
+ return failure3(rootAbs, mode, err, `Couldn't scan ${relative6(ctx.cwd, rootAbs) || "."}: check the path exists and is readable, then re-run.`);
112821
113004
  }
112822
113005
  const changed = walk2.files.filter((f) => f.changed);
112823
113006
  const flags = collectManualFlags(walk2);
@@ -112856,8 +113039,8 @@ async function rewriteSupabaseClient(ctx, input) {
112856
113039
  flags.push(...scaffold.flags);
112857
113040
  }
112858
113041
  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");
113042
+ const backupDir = apply && changed.length > 0 ? join20(rootAbs, "migration-preview", "backup") : null;
113043
+ const rewriteTarget = apply ? rootAbs : input.outputDir ? resolve9(ctx.cwd, input.outputDir) : join20(rootAbs, "migration-preview", "rewritten");
112861
113044
  const filesWritten = [];
112862
113045
  let clientModuleWritten = null;
112863
113046
  try {
@@ -112877,19 +113060,19 @@ async function rewriteSupabaseClient(ctx, input) {
112877
113060
  changedOnly: true
112878
113061
  });
112879
113062
  for (const rel of out.written) {
112880
- filesWritten.push(relative5(ctx.cwd, join19(rewriteTarget, rel)));
113063
+ filesWritten.push(relative6(ctx.cwd, join20(rewriteTarget, rel)));
112881
113064
  }
112882
113065
  if (scaffold?.clientModule) {
112883
- const moduleAbs = join19(rewriteTarget, scaffold.clientModule.relativePath);
112884
- await mkdir3(dirname5(moduleAbs), { recursive: true });
113066
+ const moduleAbs = join20(rewriteTarget, scaffold.clientModule.relativePath);
113067
+ await mkdir3(dirname6(moduleAbs), { recursive: true });
112885
113068
  await writeFile3(moduleAbs, scaffold.clientModule.content, "utf8");
112886
- clientModuleWritten = relative5(ctx.cwd, moduleAbs).split(sep4).join("/");
113069
+ clientModuleWritten = relative6(ctx.cwd, moduleAbs).split(sep5).join("/");
112887
113070
  filesWritten.push(clientModuleWritten);
112888
113071
  }
112889
113072
  }
112890
113073
  if (reportNeeded) {
112891
- const reportAbs = join19(rootAbs, "migration-preview", "REWRITE_NOTES.md");
112892
- await mkdir3(dirname5(reportAbs), { recursive: true });
113074
+ const reportAbs = join20(rootAbs, "migration-preview", "REWRITE_NOTES.md");
113075
+ await mkdir3(dirname6(reportAbs), { recursive: true });
112893
113076
  const analysis = analyzeMigration(walk2.files.map((f) => ({
112894
113077
  relativePath: f.relativePath,
112895
113078
  kind: f.kind,
@@ -112905,7 +113088,7 @@ async function rewriteSupabaseClient(ctx, input) {
112905
113088
  scaffoldedClient: scaffold?.clientModule?.relativePath ?? null,
112906
113089
  scaffoldSkippedExisting: scaffold?.skippedReason === "pb_client_exists"
112907
113090
  }), "utf8");
112908
- filesWritten.push(relative5(ctx.cwd, reportAbs));
113091
+ filesWritten.push(relative6(ctx.cwd, reportAbs));
112909
113092
  }
112910
113093
  } catch (err) {
112911
113094
  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 +113324,7 @@ function failure3(rootAbs, mode, err, suggestion) {
113141
113324
  }
113142
113325
  // ../core/dist/commands/migrate-supabase-schema.js
113143
113326
  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";
113327
+ import { isAbsolute as isAbsolute4, join as join21, relative as relative7, resolve as resolve10 } from "node:path";
113145
113328
 
113146
113329
  // ../core/dist/commands/migrate-supabase-scripts.js
113147
113330
  function generateDataImportScripts(preview) {
@@ -113589,7 +113772,7 @@ var migrateSupabaseSchemaInputSchema = exports_external.object({
113589
113772
  });
113590
113773
  async function migrateSupabaseSchema(ctx, input) {
113591
113774
  const outputDirAbs = resolveOutputDir(ctx.cwd, input.outputDir);
113592
- const outputDirRel = relative6(ctx.cwd, outputDirAbs) || ".";
113775
+ const outputDirRel = relative7(ctx.cwd, outputDirAbs) || ".";
113593
113776
  ctx.status(`Inspecting Supabase project ${input.projectRef}...`);
113594
113777
  const inspection = await inspectSupabase(ctx, {
113595
113778
  projectRef: input.projectRef,
@@ -113653,28 +113836,28 @@ async function migrateSupabaseSchema(ctx, input) {
113653
113836
  }
113654
113837
  function resolveOutputDir(cwd, requested) {
113655
113838
  const raw = requested ?? "./migration-preview";
113656
- return isAbsolute3(raw) ? raw : resolve9(cwd, raw);
113839
+ return isAbsolute4(raw) ? raw : resolve10(cwd, raw);
113657
113840
  }
113658
113841
  async function writePreviewFiles(ctx, outputDir, preview) {
113659
113842
  await mkdir4(outputDir, { recursive: true });
113660
113843
  const schemaJson = renderSchemaJson(preview);
113661
113844
  const notesMd = renderMigrationNotes(preview);
113662
113845
  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");
113846
+ const schemaPath = join21(outputDir, "pb_schema.json");
113847
+ const notesPath = join21(outputDir, "MIGRATION_NOTES.md");
113848
+ const migratePath = join21(outputDir, "pb_migrate.js");
113849
+ const storagePath = join21(outputDir, "pb_migrate_storage.js");
113667
113850
  await writeFile4(schemaPath, schemaJson, "utf8");
113668
113851
  await writeFile4(notesPath, notesMd, "utf8");
113669
113852
  await writeFile4(migratePath, scripts.pbMigrate, "utf8");
113670
113853
  const written = [
113671
- relative6(ctx.cwd, schemaPath),
113672
- relative6(ctx.cwd, notesPath),
113673
- relative6(ctx.cwd, migratePath)
113854
+ relative7(ctx.cwd, schemaPath),
113855
+ relative7(ctx.cwd, notesPath),
113856
+ relative7(ctx.cwd, migratePath)
113674
113857
  ];
113675
113858
  if (scripts.pbMigrateStorage !== null) {
113676
113859
  await writeFile4(storagePath, scripts.pbMigrateStorage, "utf8");
113677
- written.push(relative6(ctx.cwd, storagePath));
113860
+ written.push(relative7(ctx.cwd, storagePath));
113678
113861
  }
113679
113862
  return written;
113680
113863
  }
@@ -113889,8 +114072,8 @@ async function previewBranchShow(ctx, input = {}) {
113889
114072
  };
113890
114073
  }
113891
114074
  // ../core/dist/commands/publish.js
113892
- import { existsSync as existsSync14 } from "node:fs";
113893
- import { join as join23 } from "node:path";
114075
+ import { existsSync as existsSync15 } from "node:fs";
114076
+ import { join as join24 } from "node:path";
113894
114077
 
113895
114078
  // ../shared/dist/pow.js
113896
114079
  import { createHash as createHash3 } from "node:crypto";
@@ -114265,9 +114448,20 @@ async function runDeployWithRetry(opts) {
114265
114448
  throw lastErr;
114266
114449
  }
114267
114450
 
114451
+ // ../core/dist/toml-recovery.js
114452
+ function tomlErrorToRecoveryProblems(err) {
114453
+ if (err.issues?.length) {
114454
+ return err.issues.map((i) => ({
114455
+ file: "percher.toml",
114456
+ message: `${i.path.join(".") || "(root)"}: ${i.message}`
114457
+ }));
114458
+ }
114459
+ return [{ file: "percher.toml", message: err.message }];
114460
+ }
114461
+
114268
114462
  // ../core/dist/commands/env-scan.js
114269
114463
  import { readdirSync as readdirSync3, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
114270
- import { join as join21 } from "node:path";
114464
+ import { join as join22 } from "node:path";
114271
114465
  var SOURCE_EXTS = new Set([
114272
114466
  ".ts",
114273
114467
  ".tsx",
@@ -114304,7 +114498,7 @@ function scanForMissingBuildEnvRefs(cwd, existingKeys) {
114304
114498
  continue;
114305
114499
  let content;
114306
114500
  try {
114307
- content = readFileSync10(join21(cwd, rel), "utf8");
114501
+ content = readFileSync10(join22(cwd, rel), "utf8");
114308
114502
  } catch {
114309
114503
  continue;
114310
114504
  }
@@ -114336,7 +114530,7 @@ function* walkDir(dir, base) {
114336
114530
  for (const name of entries) {
114337
114531
  if (SKIP_DIRS.has(name))
114338
114532
  continue;
114339
- const full = join21(dir, name);
114533
+ const full = join22(dir, name);
114340
114534
  let st;
114341
114535
  try {
114342
114536
  st = statSync3(full);
@@ -114696,19 +114890,19 @@ function titleFromCode(code) {
114696
114890
  }
114697
114891
 
114698
114892
  // ../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";
114893
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "node:fs";
114894
+ import { join as join23 } from "node:path";
114701
114895
  function resolveNodeVersion(cwd) {
114702
- const nvmrc = join22(cwd, ".nvmrc");
114703
- if (existsSync13(nvmrc)) {
114896
+ const nvmrc = join23(cwd, ".nvmrc");
114897
+ if (existsSync14(nvmrc)) {
114704
114898
  try {
114705
114899
  const v = readFileSync11(nvmrc, "utf8").trim();
114706
114900
  if (v)
114707
114901
  return { value: v, source: ".nvmrc" };
114708
114902
  } catch {}
114709
114903
  }
114710
- const pkgPath = join22(cwd, "package.json");
114711
- if (!existsSync13(pkgPath))
114904
+ const pkgPath = join23(cwd, "package.json");
114905
+ if (!existsSync14(pkgPath))
114712
114906
  return null;
114713
114907
  try {
114714
114908
  const pkg = JSON.parse(readFileSync11(pkgPath, "utf8"));
@@ -114733,7 +114927,7 @@ var publishInputSchema = exports_external.object({
114733
114927
  var SUSPICIOUS_BYTES = 50 * 1024 * 1024;
114734
114928
  var SUSPICIOUS_FILES = 1e4;
114735
114929
  function tomlPathFor2(cwd) {
114736
- return join23(cwd, "percher.toml");
114930
+ return join24(cwd, "percher.toml");
114737
114931
  }
114738
114932
  async function buildReplacedResult2(opts) {
114739
114933
  const { ctx, app, deployment, tarball, cwd } = opts;
@@ -114780,9 +114974,9 @@ function buildLiveSummary(opts) {
114780
114974
  const replaced = opts.replacedPreview ? " — replaced previous preview" : "";
114781
114975
  return `${opts.appName} ${verb}${fwSuffix} → ${opts.url}${replaced}`;
114782
114976
  }
114783
- async function publish(ctx, input = {}) {
114977
+ async function publish(ctx, input = {}, preParsedConfig) {
114784
114978
  try {
114785
- return await publishInner(ctx, input);
114979
+ return await publishInner(ctx, input, preParsedConfig);
114786
114980
  } catch (err) {
114787
114981
  const classified = classifyPublishApiError(err, {
114788
114982
  configPath: tomlPathFor2(ctx.cwd),
@@ -114811,7 +115005,7 @@ async function publish(ctx, input = {}) {
114811
115005
  };
114812
115006
  }
114813
115007
  }
114814
- async function publishInner(ctx, input) {
115008
+ async function publishInner(ctx, input, preParsedConfig) {
114815
115009
  const t0 = Date.now();
114816
115010
  if (!input.dryRun) {
114817
115011
  try {
@@ -114822,7 +115016,7 @@ async function publishInner(ctx, input) {
114822
115016
  ctx.status("[1/4] Reading config...");
114823
115017
  let config2;
114824
115018
  try {
114825
- config2 = await loadOrGenerate(ctx);
115019
+ config2 = await loadOrGenerate(ctx, preParsedConfig);
114826
115020
  } catch (err) {
114827
115021
  if (err instanceof PercherTomlError) {
114828
115022
  if (err.code === "PARSE_ERROR") {
@@ -114836,7 +115030,7 @@ async function publishInner(ctx, input) {
114836
115030
  suggestion: "Fix the syntax error and retry publish."
114837
115031
  },
114838
115032
  recovery: recoveryFixConfig({
114839
- problems: [{ file: "percher.toml", message: err.message }],
115033
+ problems: tomlErrorToRecoveryProblems(err),
114840
115034
  reasonCode: "config_invalid"
114841
115035
  }),
114842
115036
  summary: "percher.toml has invalid TOML syntax — fix and retry.",
@@ -114845,10 +115039,7 @@ async function publishInner(ctx, input) {
114845
115039
  };
114846
115040
  }
114847
115041
  if (err.code === "VALIDATION_ERROR") {
114848
- const problems = (err.issues ?? []).map((i) => ({
114849
- file: "percher.toml",
114850
- message: `${i.path.join(".") || "(root)"}: ${i.message}`
114851
- }));
115042
+ const problems = tomlErrorToRecoveryProblems(err);
114852
115043
  const bullets = problems.map((p) => ` - ${p.message}`).join(`
114853
115044
  `);
114854
115045
  const count = problems.length;
@@ -114892,6 +115083,30 @@ ${bullets}`,
114892
115083
  bundle: { fileCount: 0, bytes: 0 }
114893
115084
  };
114894
115085
  }
115086
+ if (preParsedConfig && !input.dryRun && !existsSync15(join24(ctx.cwd, "percher.toml"))) {
115087
+ return {
115088
+ status: "failed",
115089
+ fileCount: 0,
115090
+ bytes: 0,
115091
+ error: {
115092
+ title: "percher.toml missing from the project",
115093
+ explanation: "A pre-parsed config was supplied, but no percher.toml exists in the project directory. The file is packaged into the upload, so it must be present on disk for a real deploy.",
115094
+ suggestion: "Run `percher init` (or write percher.toml) before publishing."
115095
+ },
115096
+ recovery: recoveryFixConfig({
115097
+ problems: [
115098
+ {
115099
+ file: "percher.toml",
115100
+ message: "percher.toml must exist on disk for a real upload (it ships in the tarball)."
115101
+ }
115102
+ ],
115103
+ reasonCode: "config_missing"
115104
+ }),
115105
+ summary: "percher.toml missing — required on disk for a real upload.",
115106
+ configPath: tomlPathFor2(ctx.cwd),
115107
+ bundle: { fileCount: 0, bytes: 0 }
115108
+ };
115109
+ }
114895
115110
  ctx.status("[2/4] Packaging files...");
114896
115111
  const tarball = await createTarball({ cwd: ctx.cwd, config: config2 });
114897
115112
  const packageMs = Date.now() - t0;
@@ -115397,11 +115612,14 @@ async function handleAnonymousPublish(ctx, config2, input, tarball) {
115397
115612
  ]
115398
115613
  };
115399
115614
  }
115400
- async function loadOrGenerate(ctx) {
115401
- const tomlPath = join23(ctx.cwd, "percher.toml");
115402
- if (!existsSync14(tomlPath)) {
115615
+ async function loadOrGenerate(ctx, preParsed) {
115616
+ if (preParsed)
115617
+ return structuredClone(preParsed);
115618
+ const tomlPath = join24(ctx.cwd, "percher.toml");
115619
+ if (!existsSync15(tomlPath)) {
115403
115620
  ctx.status("No percher.toml found — detecting framework...");
115404
- await init(ctx);
115621
+ const generated = await init(ctx);
115622
+ return validate(generated.config);
115405
115623
  }
115406
115624
  return parseFile(tomlPath);
115407
115625
  }
@@ -115448,8 +115666,8 @@ function emitPreflight(ctx, config2, tarball) {
115448
115666
  }
115449
115667
  }
115450
115668
  // ../core/dist/commands/push.js
115451
- import { existsSync as existsSync15 } from "node:fs";
115452
- import { join as join24 } from "node:path";
115669
+ import { existsSync as existsSync16 } from "node:fs";
115670
+ import { join as join25 } from "node:path";
115453
115671
  var pushInputSchema = exports_external.object({
115454
115672
  dryRun: exports_external.boolean().optional(),
115455
115673
  force: exports_external.boolean().optional(),
@@ -115460,8 +115678,8 @@ var SUSPICIOUS_BYTES2 = 50 * 1024 * 1024;
115460
115678
  var SUSPICIOUS_FILES2 = 1e4;
115461
115679
  var PLACEHOLDER_PREFIXES = ["add-your-", "your-key-here"];
115462
115680
  async function loadOrGenerate2(ctx) {
115463
- const tomlPath = join24(ctx.cwd, "percher.toml");
115464
- if (!existsSync15(tomlPath)) {
115681
+ const tomlPath = join25(ctx.cwd, "percher.toml");
115682
+ if (!existsSync16(tomlPath)) {
115465
115683
  ctx.status("No percher.toml found — detecting framework...");
115466
115684
  const result = await init(ctx);
115467
115685
  const answer = await ctx.prompt(`Generated percher.toml for ${result.detected?.framework ?? result.detected?.runtime ?? "node"}. Continue? [Y/n]`, { default: "y" });
@@ -115572,7 +115790,7 @@ async function push(ctx, input = {}, internals = {}) {
115572
115790
  fileCount: tarball.fileCount,
115573
115791
  recovery: RECOVERY_NONE,
115574
115792
  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"),
115793
+ configPath: join25(ctx.cwd, "percher.toml"),
115576
115794
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115577
115795
  };
115578
115796
  }
@@ -115755,7 +115973,7 @@ ${deployment.errorMessage}` : "";
115755
115973
  fileCount: tarball.fileCount,
115756
115974
  recovery: RECOVERY_NONE,
115757
115975
  summary,
115758
- configPath: join24(ctx.cwd, "percher.toml"),
115976
+ configPath: join25(ctx.cwd, "percher.toml"),
115759
115977
  bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115760
115978
  };
115761
115979
  }
@@ -116084,8 +116302,8 @@ function failureResult(error48) {
116084
116302
  };
116085
116303
  }
116086
116304
  // ../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";
116305
+ import { existsSync as existsSync17, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "node:fs";
116306
+ import { join as join26 } from "node:path";
116089
116307
  var renameInputSchema = exports_external.object({
116090
116308
  app: exports_external.string().optional(),
116091
116309
  name: exports_external.string().min(3).max(40)
@@ -116105,8 +116323,8 @@ async function rename2(ctx, input) {
116105
116323
  };
116106
116324
  }
116107
116325
  function updateLocalTomlName(cwd, oldName, newName) {
116108
- const p = join25(cwd, "percher.toml");
116109
- if (!existsSync16(p))
116326
+ const p = join26(cwd, "percher.toml");
116327
+ if (!existsSync17(p))
116110
116328
  return false;
116111
116329
  try {
116112
116330
  const src = readFileSync12(p, "utf8");
@@ -116115,25 +116333,25 @@ function updateLocalTomlName(cwd, oldName, newName) {
116115
116333
  const next = src.replace(new RegExp(`(name\\s*=\\s*")${oldName}(")`), `$1${newName}$2`);
116116
116334
  if (next === src || parse5(next).app.name !== newName)
116117
116335
  return false;
116118
- writeFileSync8(p, next);
116336
+ writeFileSync9(p, next);
116119
116337
  return true;
116120
116338
  } catch {
116121
116339
  return false;
116122
116340
  }
116123
116341
  }
116124
116342
  // ../core/dist/commands/reproduce.js
116125
- import { mkdtempSync, writeFileSync as writeFileSync9 } from "node:fs";
116343
+ import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
116126
116344
  import { tmpdir } from "node:os";
116127
- import { join as join26 } from "node:path";
116345
+ import { join as join27 } from "node:path";
116128
116346
  var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
116129
116347
  function runProcessExit(cmd, args, opts = {}) {
116130
- return new Promise((resolve10, reject) => {
116348
+ return new Promise((resolve11, reject) => {
116131
116349
  const child = import_cross_spawn2.default(cmd, args, {
116132
116350
  cwd: opts.cwd,
116133
116351
  stdio: opts.inherit ? "inherit" : "ignore"
116134
116352
  });
116135
116353
  child.on("error", reject);
116136
- child.on("close", (code) => resolve10(code ?? 1));
116354
+ child.on("close", (code) => resolve11(code ?? 1));
116137
116355
  });
116138
116356
  }
116139
116357
  var reproduceInputSchema = exports_external.object({
@@ -116219,9 +116437,9 @@ async function reproduce(ctx, input) {
116219
116437
  const envMap = await ctx.client.env.list(app.id);
116220
116438
  currentAppEnvKeys = Object.keys(envMap).sort();
116221
116439
  } catch {}
116222
- const tmpDir = mkdtempSync(join26(tmpdir(), `percher-reproduce-${input.deployId}-`));
116223
- const tarballPath = join26(tmpDir, "source.tar.gz");
116224
- writeFileSync9(tarballPath, bytes);
116440
+ const tmpDir = mkdtempSync(join27(tmpdir(), `percher-reproduce-${input.deployId}-`));
116441
+ const tarballPath = join27(tmpDir, "source.tar.gz");
116442
+ writeFileSync10(tarballPath, bytes);
116225
116443
  let extracted = false;
116226
116444
  try {
116227
116445
  extracted = await runProcessExit("tar", ["-xzf", tarballPath, "-C", tmpDir]) === 0;
@@ -116658,7 +116876,6 @@ var PLAN_CATALOG = {
116658
116876
  priceEur: 0,
116659
116877
  limits: {
116660
116878
  apps: 3,
116661
- deploysPerMonth: 50,
116662
116879
  deploysPerHour: 12,
116663
116880
  memory: "256mb",
116664
116881
  cpu: 0.25,
@@ -116690,7 +116907,6 @@ var PLAN_CATALOG = {
116690
116907
  priceEur: 3,
116691
116908
  limits: {
116692
116909
  apps: 10,
116693
- deploysPerMonth: 200,
116694
116910
  deploysPerHour: 30,
116695
116911
  memory: "512mb",
116696
116912
  cpu: 0.25,
@@ -116722,7 +116938,6 @@ var PLAN_CATALOG = {
116722
116938
  priceEur: 12,
116723
116939
  limits: {
116724
116940
  apps: 20,
116725
- deploysPerMonth: 500,
116726
116941
  deploysPerHour: 60,
116727
116942
  memory: "1gb",
116728
116943
  cpu: 0.5,
@@ -116754,7 +116969,6 @@ var PLAN_CATALOG = {
116754
116969
  priceEur: 29,
116755
116970
  limits: {
116756
116971
  apps: 40,
116757
- deploysPerMonth: "unlimited",
116758
116972
  deploysPerHour: 120,
116759
116973
  memory: "1gb",
116760
116974
  cpu: 1,
@@ -116787,7 +117001,6 @@ var PLAN_CATALOG = {
116787
117001
  hidden: true,
116788
117002
  limits: {
116789
117003
  apps: 1,
116790
- deploysPerMonth: 20,
116791
117004
  deploysPerHour: 6,
116792
117005
  memory: "128mb",
116793
117006
  cpu: 0.25,
@@ -117479,6 +117692,36 @@ function registerAppsCommands(cli, ctx) {
117479
117692
  await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
117480
117693
  }
117481
117694
  });
117695
+ 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) => {
117696
+ const result = await appstoreKit(ctx, {
117697
+ name: options.name,
117698
+ url: options.url,
117699
+ packageName: options.package,
117700
+ fingerprint: options.fingerprint,
117701
+ teamId: options.teamId,
117702
+ bundleId: options.bundleId,
117703
+ outDir: options.out,
117704
+ force: options.force
117705
+ });
117706
+ for (const file2 of result.written) {
117707
+ await writeLine(ctx, `${import_picocolors4.default.green("✓")} wrote ${file2}`);
117708
+ }
117709
+ for (const file2 of result.skipped) {
117710
+ await writeLine(ctx, `${import_picocolors4.default.dim("•")} skipped ${file2} (exists — pass --force to overwrite)`);
117711
+ }
117712
+ await writeLine(ctx, "");
117713
+ await writeLine(ctx, `${import_picocolors4.default.bold("Make it an installable PWA:")} link the manifest from your HTML`);
117714
+ await writeLine(ctx, ` <link rel="manifest" href="/manifest.json">`);
117715
+ await writeLine(ctx, "and register the service worker from your app entry:");
117716
+ await writeLine(ctx, result.swRegistration);
117717
+ await writeLine(ctx, "");
117718
+ await writeLine(ctx, `${import_picocolors4.default.bold("Wrap for Google Play (TWA):")}`);
117719
+ await writeLine(ctx, result.bubblewrapCommand);
117720
+ await writeLine(ctx, "");
117721
+ await writeLine(ctx, `The two ${import_picocolors4.default.dim(".well-known")} files are trust assertions for your origin — add real values`);
117722
+ await writeLine(ctx, `after you sign the apps, then serve them yourself or let Percher serve them from the`);
117723
+ await writeLine(ctx, "App store kit at https://percher.app. Full guide: /docs/app-stores");
117724
+ });
117482
117725
  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
117726
  const { detectCiBranchMessage: detectCiBranchMessage2 } = await Promise.resolve().then(() => exports_ci_env);
117484
117727
  let messageOverride = options.message;
@@ -117560,8 +117803,8 @@ function registerAppsCommands(cli, ctx) {
117560
117803
  deployId,
117561
117804
  timeoutSeconds: Math.min(Math.ceil(remainingMs / 1000), 30)
117562
117805
  }, { signal: callController.signal }),
117563
- new Promise((resolve10) => {
117564
- raceTimer = setTimeout(() => resolve10(null), remainingMs);
117806
+ new Promise((resolve11) => {
117807
+ raceTimer = setTimeout(() => resolve11(null), remainingMs);
117565
117808
  })
117566
117809
  ]);
117567
117810
  } finally {
@@ -118805,7 +119048,7 @@ async function renderError(stderr, error48) {
118805
119048
  // package.json
118806
119049
  var package_default = {
118807
119050
  name: "percher",
118808
- version: "0.5.8",
119051
+ version: "0.5.10",
118809
119052
  description: "CLI for the Percher hosting platform — publish apps with one command",
118810
119053
  type: "module",
118811
119054
  bin: {
@@ -118886,18 +119129,18 @@ async function showTelemetryNotice() {
118886
119129
  if (isDisabled())
118887
119130
  return;
118888
119131
  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))
119132
+ const { existsSync: existsSync18, mkdirSync: mkdirSync7, writeFileSync: writeFileSync11 } = await import("node:fs");
119133
+ const { join: join28 } = await import("node:path");
119134
+ const configDir = join28(homedir2(), ".percher");
119135
+ const markerFile = join28(configDir, ".telemetry-notice-shown");
119136
+ if (existsSync18(markerFile))
118894
119137
  return;
118895
119138
  console.log("Percher sends non-account-linked usage stats (command, result, error type, OS, Bun version).");
118896
119139
  console.log(`Disable with PERCHER_NO_TELEMETRY=1
118897
119140
  `);
118898
119141
  try {
118899
- mkdirSync6(configDir, { recursive: true });
118900
- writeFileSync10(markerFile, new Date().toISOString());
119142
+ mkdirSync7(configDir, { recursive: true });
119143
+ writeFileSync11(markerFile, new Date().toISOString());
118901
119144
  } catch {}
118902
119145
  }
118903
119146