@wix/himalaya-cli 0.856.0 → 0.857.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -920,7 +920,7 @@ function hasUnterminatedComment(mobile) {
920
920
  i = close + 3;
921
921
  }
922
922
  }
923
- function mobileUxMarkerFindings(mobile) {
923
+ function mobileUxMarkerFindings(mobile, renderedWidths = []) {
924
924
  const text2 = mobileUxDocumentBody(mobile);
925
925
  const findings = [];
926
926
  if (!/^## Implementation acceptance\b/im.test(text2)) {
@@ -938,8 +938,8 @@ function mobileUxMarkerFindings(mobile) {
938
938
  });
939
939
  }
940
940
  }
941
- if (!hasWidthEvidence(text2)) {
942
- findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(text2) });
941
+ if (!hasWidthEvidence(text2, renderedWidths)) {
942
+ findings.push({ code: "missing-width-evidence", message: widthEvidenceMessage(text2, renderedWidths) });
943
943
  }
944
944
  if (findings.length && hasUnterminatedComment(mobile)) {
945
945
  return [{
@@ -987,13 +987,33 @@ function closestWidthPair(mentions) {
987
987
  }
988
988
  return best;
989
989
  }
990
- function hasWidthEvidence(mobile) {
990
+ function recordedWidthSpan(widths) {
991
+ const compact = widths.find((width) => inRange(width) && width <= COMPACT_MAX);
992
+ const wider = widths.find((width) => inRange(width) && width >= WIDER_MIN);
993
+ return compact !== void 0 && wider !== void 0 ? { compact, wider } : null;
994
+ }
995
+ function hasWidthEvidence(mobile, renderedWidths) {
996
+ if (recordedWidthSpan(renderedWidths)) return true;
991
997
  if (WIDTH_LITERAL.test(mobile)) return true;
992
998
  const pair = closestWidthPair(widthMentions(mobile));
993
999
  return pair !== null && pair.gap <= WIDTH_WINDOW;
994
1000
  }
995
- function widthEvidenceMessage(mobile) {
996
- const base = `MOBILE-UX.md has no width evidence. Record the widths you actually rendered \u2014 one at most ${COMPACT_MAX}px (compact) and one at least ${WIDER_MIN}px (medium or expanded), within ~${WIDTH_WINDOW} characters of each other so they read as one statement. A number counts only where it is spelled as a width on itself: a unit (\`320px\`, \`320 pt\`, \`320 dp\`, \`320 pixels\`, \`320 wide\`) or a screenshot filename (\`home-320.png\`). For example: \`Rendered 320px and 834px (home-320.png, home-834.png)\`. The scaffold's \`compact (320/360) \u2026 expanded\` sentence is still accepted as-is.`;
1001
+ function recordedRenderNote(renderedWidths) {
1002
+ if (renderedWidths.length === 0) return "";
1003
+ const list = (values) => {
1004
+ const unique = [...new Set(values)].sort((a, b) => a - b);
1005
+ const shown2 = unique.slice(0, 6).map((width) => `${width}px`).join(", ");
1006
+ return unique.length > 6 ? `${shown2}, \u2026` : shown2;
1007
+ };
1008
+ const plausible = renderedWidths.filter(inRange);
1009
+ const held = `The render record in \`${UX_EVIDENCE_PATH}\` holds`;
1010
+ if (plausible.length === 0) {
1011
+ return ` ${held} ${list(renderedWidths)}, and none of those is a plausible viewport (${PLAUSIBLE_WIDTH.min}-${PLAUSIBLE_WIDTH.max}px), so the record proves nothing about a size class.`;
1012
+ }
1013
+ return ` ${held} ${list(plausible)} \u2014 ` + (plausible.some((width) => width <= COMPACT_MAX) ? `compact only. Render the same screen again at ${WIDER_MIN}px or wider \u2014 \`himi render <screenId> --device ipad\`.` : `wider than compact only. Render the same screen again at ${COMPACT_MAX}px or less \u2014 \`himi render <screenId> --device iphone\`.`);
1014
+ }
1015
+ function widthEvidenceMessage(mobile, renderedWidths) {
1016
+ const base = `MOBILE-UX.md has no width evidence. The shortest way to supply it is to RENDER: \`himi render <screenId> --content <dir> --device iphone\` and again \`--device ipad\` (or any two \`--width\`s spanning the bands below) write the widths they rendered into \`${UX_EVIDENCE_PATH}\`, and a recorded compact render plus a wider one satisfy this marker with no prose at all. Otherwise write the widths you actually rendered into this document \u2014 one at most ${COMPACT_MAX}px (compact) and one at least ${WIDER_MIN}px (medium or expanded), within ~${WIDTH_WINDOW} characters of each other so they read as one statement. A number counts only where it is spelled as a width on itself: a unit (\`320px\`, \`320 pt\`, \`320 dp\`, \`320 pixels\`, \`320 wide\`) or a screenshot filename (\`home-320.png\`). For example: \`Rendered 320px and 834px (home-320.png, home-834.png)\`. The scaffold's \`compact (320/360) \u2026 expanded\` sentence is still accepted as-is.` + recordedRenderNote(renderedWidths);
997
1017
  if (/compact \(320\/360\)/i.test(mobile)) {
998
1018
  return base + " `compact (320/360)` is present, but no `expanded` follows it within ~400 characters \u2014 keep them in the same sentence.";
999
1019
  }
@@ -1012,9 +1032,10 @@ function widthEvidenceMessage(mobile) {
1012
1032
  }
1013
1033
  return base;
1014
1034
  }
1015
- var SPEC_TEMPLATE, MOBILE_UX_MARKER_NOTE, MOBILE_UX_TEMPLATE, section, DELIMITER_ROW, splitCells, WIDTH_LITERAL, COMPACT_MAX, WIDER_MIN, PLAUSIBLE_WIDTH, YEAR, inRange, looksLikeYear, UNIT_ATTACHED, UNIT_WORD_ATTACHED, WIDTH_WINDOW, EDGE_WINDOW, FILENAME_AFTER, ANTI_CUE_BEFORE, PAIR_HEIGHT_BEFORE, ANTI_CUE_AFTER, isCompact, isWider;
1035
+ var UX_EVIDENCE_PATH, SPEC_TEMPLATE, MOBILE_UX_MARKER_NOTE, MOBILE_UX_TEMPLATE, section, DELIMITER_ROW, splitCells, WIDTH_LITERAL, COMPACT_MAX, WIDER_MIN, PLAUSIBLE_WIDTH, YEAR, inRange, looksLikeYear, UNIT_ATTACHED, UNIT_WORD_ATTACHED, WIDTH_WINDOW, EDGE_WINDOW, FILENAME_AFTER, ANTI_CUE_BEFORE, PAIR_HEIGHT_BEFORE, ANTI_CUE_AFTER, isCompact, isWider;
1016
1036
  var init_mobile_ux_contract = __esm({
1017
1037
  "src/mobile-ux-contract.ts"() {
1038
+ UX_EVIDENCE_PATH = ".himi/ux-audit.json";
1018
1039
  SPEC_TEMPLATE = `# App specification
1019
1040
 
1020
1041
  ## User and outcome
@@ -1052,7 +1073,11 @@ var init_mobile_ux_contract = __esm({
1052
1073
  2. One primary CTA per state \u2014 EITHER the phrase \`one primary CTA per state\`, OR a
1053
1074
  \`Primary CTA\` column in the acceptance table below, with a row for every state you
1054
1075
  declare under \`## Screen contract\` and exactly one CTA named in each row's cell.
1055
- 3. Width evidence \u2014 EITHER the scaffold's own sentence, \`compact (320/360)\` followed by
1076
+ 3. Width evidence \u2014 EITHER a RECORDED RENDER, which is the shortest way and needs no prose
1077
+ at all: \`himi render <screenId> --device iphone\` and again \`--device ipad\` each append
1078
+ the width they rendered to \`.himi/ux-audit.json\`, and one below 600px plus one at 600px
1079
+ or wider satisfies this on their own. OR the scaffold's own sentence,
1080
+ \`compact (320/360)\` followed by
1056
1081
  \`expanded\`, OR two widths you actually rendered, EACH SPELLED AS A WIDTH ON ITSELF:
1057
1082
  one below 600px and one at 600px or wider, within about 400 characters of each other.
1058
1083
  A number is spelled as a width when it carries a unit (\`320px\`, \`834 pt\`,
@@ -2212,7 +2237,7 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
2212
2237
  tokenCache.set(cacheKey, fromEnv);
2213
2238
  return fromEnv;
2214
2239
  }
2215
- const token = await new Promise((resolve41, reject) => {
2240
+ const token = await new Promise((resolve42, reject) => {
2216
2241
  let child;
2217
2242
  try {
2218
2243
  child = spawnImpl("wix", [...args]);
@@ -2241,12 +2266,12 @@ async function mintToken(args, label2, cacheKey, spawnImpl) {
2241
2266
  child.stdout?.on("data", (d) => {
2242
2267
  out += String(d);
2243
2268
  const m = out.match(TOKEN_RE);
2244
- if (m) done(() => resolve41(m[0]));
2269
+ if (m) done(() => resolve42(m[0]));
2245
2270
  });
2246
2271
  child.stderr?.on("data", (d) => {
2247
2272
  out += String(d);
2248
2273
  const m = out.match(TOKEN_RE);
2249
- if (m) done(() => resolve41(m[0]));
2274
+ if (m) done(() => resolve42(m[0]));
2250
2275
  });
2251
2276
  child.on("error", (e) => done(() => reject(new Error(mintHelp(label2, e.message)))));
2252
2277
  child.on("exit", (code) => done(() => reject(new Error(
@@ -2427,8 +2452,8 @@ function committedProvisioningPath(name) {
2427
2452
  function committedShellFor(path) {
2428
2453
  const normalized = path.replace(/\\/g, "/");
2429
2454
  return SHELL_NAMES2.find((name) => {
2430
- const relative7 = committedProvisioningPath(name);
2431
- return normalized === relative7 || normalized.endsWith(`/${relative7}`);
2455
+ const relative8 = committedProvisioningPath(name);
2456
+ return normalized === relative8 || normalized.endsWith(`/${relative8}`);
2432
2457
  });
2433
2458
  }
2434
2459
  function isBrandable(repoRoot2, name) {
@@ -9131,8 +9156,8 @@ Lifetime used`) : new QuickJSUseAfterFree("Lifetime not alive");
9131
9156
  this.dispose = () => {
9132
9157
  this.handle.alive && this.handle.dispose(), this.disposeResolvers();
9133
9158
  };
9134
- this.context = args.context, this.owner = args.context.runtime, this.handle = args.promiseHandle, this.settled = new Promise((resolve41) => {
9135
- this.onSettled = resolve41;
9159
+ this.context = args.context, this.owner = args.context.runtime, this.handle = args.promiseHandle, this.settled = new Promise((resolve42) => {
9160
+ this.onSettled = resolve42;
9136
9161
  }), this.resolveHandle = args.resolveHandle, this.rejectHandle = args.rejectHandle;
9137
9162
  }
9138
9163
  get alive() {
@@ -9496,12 +9521,12 @@ Lifetime used`) : new QuickJSUseAfterFree("Lifetime not alive");
9496
9521
  let vmPromise = scope.manage(this.getProp(this.global, "Promise")), vmPromiseResolve = scope.manage(this.getProp(vmPromise, "resolve"));
9497
9522
  return this.callFunction(vmPromiseResolve, vmPromise, promiseLikeHandle);
9498
9523
  });
9499
- return vmResolveResult.error ? Promise.resolve(vmResolveResult) : new Promise((resolve41) => {
9524
+ return vmResolveResult.error ? Promise.resolve(vmResolveResult) : new Promise((resolve42) => {
9500
9525
  Scope.withScope((scope) => {
9501
9526
  let resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
9502
- resolve41(this.success(value && value.dup()));
9527
+ resolve42(this.success(value && value.dup()));
9503
9528
  })), rejectHandle = scope.manage(this.newFunction("reject", (error) => {
9504
- resolve41(this.fail(error && error.dup()));
9529
+ resolve42(this.fail(error && error.dup()));
9505
9530
  })), promiseHandle = scope.manage(vmResolveResult.value), promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
9506
9531
  this.callFunction(promiseThenHandle, promiseHandle, resolveHandle, rejectHandle).unwrap().dispose();
9507
9532
  });
@@ -10347,13 +10372,13 @@ async function QuickJSRaw(moduleArg = {}) {
10347
10372
  }
10348
10373
  readAsync = async (url) => {
10349
10374
  if (isFileURI(url)) {
10350
- return new Promise((resolve41, reject) => {
10375
+ return new Promise((resolve42, reject) => {
10351
10376
  var xhr = new XMLHttpRequest();
10352
10377
  xhr.open("GET", url, true);
10353
10378
  xhr.responseType = "arraybuffer";
10354
10379
  xhr.onload = () => {
10355
10380
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
10356
- resolve41(xhr.response);
10381
+ resolve42(xhr.response);
10357
10382
  return;
10358
10383
  }
10359
10384
  reject(xhr.status);
@@ -10641,10 +10666,10 @@ async function QuickJSRaw(moduleArg = {}) {
10641
10666
  }
10642
10667
  var info = getWasmImports();
10643
10668
  if (Module["instantiateWasm"]) {
10644
- return new Promise((resolve41, reject) => {
10669
+ return new Promise((resolve42, reject) => {
10645
10670
  try {
10646
10671
  Module["instantiateWasm"](info, (inst, mod) => {
10647
- resolve41(receiveInstance(inst, mod));
10672
+ resolve42(receiveInstance(inst, mod));
10648
10673
  });
10649
10674
  } catch (e) {
10650
10675
  err(`Module.instantiateWasm callback failed with error: ${e}`);
@@ -10817,15 +10842,15 @@ async function QuickJSRaw(moduleArg = {}) {
10817
10842
  return parts;
10818
10843
  },
10819
10844
  normalize: (path) => {
10820
- var isAbsolute4 = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/";
10821
- path = PATH.normalizeArray(path.split("/").filter((p) => !!p), !isAbsolute4).join("/");
10822
- if (!path && !isAbsolute4) {
10845
+ var isAbsolute5 = PATH.isAbs(path), trailingSlash = path.slice(-1) === "/";
10846
+ path = PATH.normalizeArray(path.split("/").filter((p) => !!p), !isAbsolute5).join("/");
10847
+ if (!path && !isAbsolute5) {
10823
10848
  path = ".";
10824
10849
  }
10825
10850
  if (path && trailingSlash) {
10826
10851
  path += "/";
10827
10852
  }
10828
- return (isAbsolute4 ? "/" : "") + path;
10853
+ return (isAbsolute5 ? "/" : "") + path;
10829
10854
  },
10830
10855
  dirname: (path) => {
10831
10856
  var result = PATH.splitPath(path), root = result[0], dir = result[1];
@@ -12291,12 +12316,12 @@ async function QuickJSRaw(moduleArg = {}) {
12291
12316
  throw new FS.ErrnoError(75);
12292
12317
  }
12293
12318
  var old_node = FS.lookupNode(old_dir, old_name);
12294
- var relative7 = PATH_FS.relative(old_path, new_dirname);
12295
- if (relative7.charAt(0) !== ".") {
12319
+ var relative8 = PATH_FS.relative(old_path, new_dirname);
12320
+ if (relative8.charAt(0) !== ".") {
12296
12321
  throw new FS.ErrnoError(28);
12297
12322
  }
12298
- relative7 = PATH_FS.relative(new_path, old_dirname);
12299
- if (relative7.charAt(0) !== ".") {
12323
+ relative8 = PATH_FS.relative(new_path, old_dirname);
12324
+ if (relative8.charAt(0) !== ".") {
12300
12325
  throw new FS.ErrnoError(55);
12301
12326
  }
12302
12327
  var new_node;
@@ -14705,8 +14730,8 @@ async function QuickJSRaw(moduleArg = {}) {
14705
14730
  if (runtimeInitialized) {
14706
14731
  moduleRtn = Module;
14707
14732
  } else {
14708
- moduleRtn = new Promise((resolve41, reject) => {
14709
- readyPromiseResolve = resolve41;
14733
+ moduleRtn = new Promise((resolve42, reject) => {
14734
+ readyPromiseResolve = resolve42;
14710
14735
  readyPromiseReject = reject;
14711
14736
  });
14712
14737
  }
@@ -15570,13 +15595,13 @@ async function QuickJSRaw3(moduleArg = {}) {
15570
15595
  }
15571
15596
  readAsync = async (url) => {
15572
15597
  if (isFileURI(url)) {
15573
- return new Promise((resolve41, reject) => {
15598
+ return new Promise((resolve42, reject) => {
15574
15599
  var xhr = new XMLHttpRequest();
15575
15600
  xhr.open("GET", url, true);
15576
15601
  xhr.responseType = "arraybuffer";
15577
15602
  xhr.onload = () => {
15578
15603
  if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
15579
- resolve41(xhr.response);
15604
+ resolve42(xhr.response);
15580
15605
  return;
15581
15606
  }
15582
15607
  reject(xhr.status);
@@ -15843,10 +15868,10 @@ async function QuickJSRaw3(moduleArg = {}) {
15843
15868
  }
15844
15869
  var info = getWasmImports();
15845
15870
  if (Module["instantiateWasm"]) {
15846
- return new Promise((resolve41, reject) => {
15871
+ return new Promise((resolve42, reject) => {
15847
15872
  try {
15848
15873
  Module["instantiateWasm"](info, (inst, mod) => {
15849
- resolve41(receiveInstance(inst, mod));
15874
+ resolve42(receiveInstance(inst, mod));
15850
15875
  });
15851
15876
  } catch (e) {
15852
15877
  err(`Module.instantiateWasm callback failed with error: ${e}`);
@@ -16274,8 +16299,8 @@ async function QuickJSRaw3(moduleArg = {}) {
16274
16299
  }, whenDone() {
16275
16300
  assert(Asyncify.currData, "Tried to wait for an async operation when none is in progress.");
16276
16301
  assert(!Asyncify.asyncPromiseHandlers, "Cannot have multiple async operations in flight at once");
16277
- return new Promise((resolve41, reject) => {
16278
- Asyncify.asyncPromiseHandlers = { resolve: resolve41, reject };
16302
+ return new Promise((resolve42, reject) => {
16303
+ Asyncify.asyncPromiseHandlers = { resolve: resolve42, reject };
16279
16304
  });
16280
16305
  }, allocateData() {
16281
16306
  var ptr = _malloc(12 + Asyncify.StackSize);
@@ -16903,8 +16928,8 @@ async function QuickJSRaw3(moduleArg = {}) {
16903
16928
  if (runtimeInitialized) {
16904
16929
  moduleRtn = Module;
16905
16930
  } else {
16906
- moduleRtn = new Promise((resolve41, reject) => {
16907
- readyPromiseResolve = resolve41;
16931
+ moduleRtn = new Promise((resolve42, reject) => {
16932
+ readyPromiseResolve = resolve42;
16908
16933
  readyPromiseReject = reject;
16909
16934
  });
16910
16935
  }
@@ -20597,6 +20622,101 @@ var init_wix_gateway_rules = __esm({
20597
20622
  }
20598
20623
  });
20599
20624
 
20625
+ // src/ux-evidence.ts
20626
+ import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync23, writeFileSync as writeFileSync9 } from "node:fs";
20627
+ import { dirname as dirname15, isAbsolute as isAbsolute2, join as join25, relative as relative3, resolve as resolve15 } from "node:path";
20628
+ function readText(path) {
20629
+ try {
20630
+ return existsSync21(path) ? readFileSync23(path, "utf8") : null;
20631
+ } catch {
20632
+ return null;
20633
+ }
20634
+ }
20635
+ function parseEvidence(path) {
20636
+ const raw = readText(path);
20637
+ if (raw === null) return { evidence: null };
20638
+ try {
20639
+ const value = JSON.parse(raw);
20640
+ if (value.version !== 1 || !value.platforms || typeof value.platforms !== "object") {
20641
+ return { evidence: null, error: "must be an object with version: 1 and a platforms object" };
20642
+ }
20643
+ return { evidence: value };
20644
+ } catch (error) {
20645
+ return { evidence: null, error: `is not valid JSON: ${error.message}` };
20646
+ }
20647
+ }
20648
+ function uxEvidencePath(content) {
20649
+ return join25(resolve15(content), UX_EVIDENCE_PATH);
20650
+ }
20651
+ function isRenderEntry(value) {
20652
+ if (!value || typeof value !== "object") return false;
20653
+ const entry = value;
20654
+ return typeof entry.screenId === "string" && entry.screenId.length > 0 && typeof entry.width === "number" && Number.isFinite(entry.width) && entry.width > 0 && typeof entry.recordedAt === "string" && entry.recordedAt.length > 0;
20655
+ }
20656
+ function renderEvidenceEntries(evidence) {
20657
+ const raw = evidence?.renders;
20658
+ return Array.isArray(raw) ? raw.filter(isRenderEntry) : [];
20659
+ }
20660
+ function recordedRenderWidths(content) {
20661
+ const { evidence } = parseEvidence(uxEvidencePath(content));
20662
+ return renderEvidenceEntries(evidence).map((entry) => entry.width);
20663
+ }
20664
+ function writeEvidence(path, evidence) {
20665
+ mkdirSync10(dirname15(path), { recursive: true });
20666
+ writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
20667
+ }
20668
+ function recordedFilePath(dir, file) {
20669
+ const rel = relative3(dir, resolve15(file));
20670
+ return rel && !rel.startsWith("..") && !isAbsolute2(rel) ? rel : file;
20671
+ }
20672
+ function recordRenderWidth(content, entry) {
20673
+ try {
20674
+ if (!entry.screenId || !Number.isFinite(entry.width) || entry.width <= 0) return null;
20675
+ const dir = resolve15(content);
20676
+ const path = join25(dir, UX_EVIDENCE_PATH);
20677
+ const parsed = parseEvidence(path);
20678
+ if (parsed.error) return null;
20679
+ const evidence = parsed.evidence ?? { version: 1, platforms: {} };
20680
+ const width = entry.width;
20681
+ const written = {
20682
+ screenId: entry.screenId,
20683
+ width,
20684
+ ...entry.device ? { device: entry.device } : {},
20685
+ ...entry.file ? { file: recordedFilePath(dir, entry.file) } : {},
20686
+ recordedAt: (/* @__PURE__ */ new Date()).toISOString()
20687
+ };
20688
+ const renders = renderEvidenceEntries(evidence);
20689
+ const at = renders.findIndex((existing) => existing.screenId === written.screenId && existing.width === width);
20690
+ if (at >= 0) renders[at] = written;
20691
+ else renders.push(written);
20692
+ evidence.renders = renders;
20693
+ writeEvidence(path, evidence);
20694
+ return written;
20695
+ } catch {
20696
+ return null;
20697
+ }
20698
+ }
20699
+ function recordNativeAudit(content, platform, status, checks, reason) {
20700
+ const normalizedChecks = status === "unavailable" ? [] : [...new Set(checks.map((check) => check.trim()).filter(Boolean))];
20701
+ if (status !== "unavailable" && !normalizedChecks.length) {
20702
+ throw new Error("--checks needs at least one comma-separated check (for example: back,keyboard,voiceover)");
20703
+ }
20704
+ if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
20705
+ const dir = resolve15(content);
20706
+ const path = join25(dir, UX_EVIDENCE_PATH);
20707
+ const parsed = parseEvidence(path);
20708
+ if (parsed.error) throw new Error(`${UX_EVIDENCE_PATH} ${parsed.error}`);
20709
+ const evidence = parsed.evidence ?? { version: 1, platforms: {} };
20710
+ evidence.platforms[platform] = { status, checks: normalizedChecks, ...reason?.trim() ? { reason: reason.trim() } : {}, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
20711
+ writeEvidence(path, evidence);
20712
+ return evidence;
20713
+ }
20714
+ var init_ux_evidence = __esm({
20715
+ "src/ux-evidence.ts"() {
20716
+ init_mobile_ux_contract();
20717
+ }
20718
+ });
20719
+
20600
20720
  // ../../core/sdk/capability-catalog/src/types.ts
20601
20721
  var init_types = __esm({
20602
20722
  "../../core/sdk/capability-catalog/src/types.ts"() {
@@ -21323,9 +21443,9 @@ var init_src2 = __esm({
21323
21443
  });
21324
21444
 
21325
21445
  // ../app-icons/plan.ts
21326
- import { existsSync as existsSync23, readFileSync as readFileSync25, readdirSync as readdirSync12 } from "node:fs";
21446
+ import { existsSync as existsSync24, readFileSync as readFileSync26, readdirSync as readdirSync12 } from "node:fs";
21327
21447
  import { createHash as createHash7 } from "node:crypto";
21328
- import { dirname as dirname16, join as join27, resolve as resolve17 } from "node:path";
21448
+ import { dirname as dirname17, join as join28, resolve as resolve18 } from "node:path";
21329
21449
  function stripComments(src) {
21330
21450
  let out = "";
21331
21451
  let i = 0;
@@ -21454,15 +21574,15 @@ function rotateHue(hex2, deg) {
21454
21574
  }
21455
21575
  function resolveTokensPath(app, configTs) {
21456
21576
  const literal = /^ {2}designTokensPath\s*:\s*["']([^"']+)["']/m.exec(stripComments(configTs))?.[1];
21457
- if (literal) return { path: resolve17(appDir(app), literal), source: "declared" };
21458
- return { path: join27(appDir(app), "tokens.json"), source: "assumed" };
21577
+ if (literal) return { path: resolve18(appDir(app), literal), source: "declared" };
21578
+ return { path: join28(appDir(app), "tokens.json"), source: "assumed" };
21459
21579
  }
21460
21580
  function resolveToken(app, token, tokensPathOverride) {
21461
- const tokensPath = tokensPathOverride ?? join27(appDir(app), "tokens.json");
21462
- if (!existsSync23(tokensPath)) {
21581
+ const tokensPath = tokensPathOverride ?? join28(appDir(app), "tokens.json");
21582
+ if (!existsSync24(tokensPath)) {
21463
21583
  throw new Error(`app-icons: ${app} has no tokens.json at ${tokensPath} (needed to resolve "${token}").`);
21464
21584
  }
21465
- const tokens = JSON.parse(readFileSync25(tokensPath, "utf8"));
21585
+ const tokens = JSON.parse(readFileSync26(tokensPath, "utf8"));
21466
21586
  const value = tokens.colors?.[token];
21467
21587
  if (value === void 0) {
21468
21588
  throw new Error(`app-icons: ${app} references icon colour token "${token}" but tokens.json has no such color.`);
@@ -21503,8 +21623,8 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
21503
21623
  assertIconContract(app, cfg);
21504
21624
  const tokens = tokensPathOverride ?? resolveTokensPath(app, configTs).path;
21505
21625
  if (cfg.source) {
21506
- const abs = resolve17(appDir(app), cfg.source);
21507
- if (!existsSync23(abs)) {
21626
+ const abs = resolve18(appDir(app), cfg.source);
21627
+ if (!existsSync24(abs)) {
21508
21628
  throw new Error(`app-icons: ${app} declares icon.source "${cfg.source}" but ${abs} does not exist.`);
21509
21629
  }
21510
21630
  return {
@@ -21541,17 +21661,17 @@ function iconSpec(app, configTs, id, tokensPathOverride) {
21541
21661
  };
21542
21662
  }
21543
21663
  function iosAssetCatalog2(app) {
21544
- return assetCatalogIn(join27(appDir(app), "ios"));
21664
+ return assetCatalogIn(join28(appDir(app), "ios"));
21545
21665
  }
21546
21666
  function assetCatalogIn(platformDir) {
21547
- if (!existsSync23(platformDir)) return void 0;
21667
+ if (!existsSync24(platformDir)) return void 0;
21548
21668
  const children = readdirSync12(platformDir).filter((c) => !c.startsWith("build")).sort();
21549
- const catalogs = children.map((c) => join27(platformDir, c, "Assets.xcassets")).filter(existsSync23);
21669
+ const catalogs = children.map((c) => join28(platformDir, c, "Assets.xcassets")).filter(existsSync24);
21550
21670
  if (catalogs.length === 1) return catalogs[0];
21551
21671
  if (catalogs.length > 1) return void 0;
21552
21672
  const targets = [];
21553
21673
  for (const child of children) {
21554
- const dir = join27(platformDir, child);
21674
+ const dir = join28(platformDir, child);
21555
21675
  let entries;
21556
21676
  try {
21557
21677
  entries = readdirSync12(dir);
@@ -21559,29 +21679,29 @@ function assetCatalogIn(platformDir) {
21559
21679
  continue;
21560
21680
  }
21561
21681
  if (entries.includes("Info.plist") || entries.some((e) => e.endsWith(".swift"))) {
21562
- targets.push(join27(dir, "Assets.xcassets"));
21682
+ targets.push(join28(dir, "Assets.xcassets"));
21563
21683
  }
21564
21684
  }
21565
21685
  return targets.length === 1 ? targets[0] : void 0;
21566
21686
  }
21567
21687
  function androidResDir2(manifestPath) {
21568
- return join27(dirname16(manifestPath), "res");
21688
+ return join28(dirname17(manifestPath), "res");
21569
21689
  }
21570
21690
  function androidManifestPath(app) {
21571
- const androidDir = join27(appDir(app), "android");
21572
- if (!existsSync23(androidDir)) return void 0;
21573
- const preferred = join27(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
21574
- if (existsSync23(preferred)) return preferred;
21575
- const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join27(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync23);
21691
+ const androidDir = join28(appDir(app), "android");
21692
+ if (!existsSync24(androidDir)) return void 0;
21693
+ const preferred = join28(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
21694
+ if (existsSync24(preferred)) return preferred;
21695
+ const candidates = readdirSync12(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join28(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync24);
21576
21696
  return candidates.length === 1 ? candidates[0] : void 0;
21577
21697
  }
21578
21698
  function androidOptedIn2(manifestPath) {
21579
- if (!manifestPath || !existsSync23(manifestPath)) return false;
21580
- return readFileSync25(manifestPath, "utf8").includes("@mipmap/ic_launcher");
21699
+ if (!manifestPath || !existsSync24(manifestPath)) return false;
21700
+ return readFileSync26(manifestPath, "utf8").includes("@mipmap/ic_launcher");
21581
21701
  }
21582
21702
  function templateIconSha256() {
21583
21703
  const cat = iosAssetCatalog2("_template");
21584
- return cat ? fileSha256(join27(cat, "AppIcon.appiconset", "icon_1024.png")) : null;
21704
+ return cat ? fileSha256(join28(cat, "AppIcon.appiconset", "icon_1024.png")) : null;
21585
21705
  }
21586
21706
  function placeholderHashes() {
21587
21707
  const current = templateIconSha256();
@@ -21589,7 +21709,7 @@ function placeholderHashes() {
21589
21709
  }
21590
21710
  function fileSha256(path) {
21591
21711
  try {
21592
- return createHash7("sha256").update(readFileSync25(path)).digest("hex");
21712
+ return createHash7("sha256").update(readFileSync26(path)).digest("hex");
21593
21713
  } catch {
21594
21714
  return null;
21595
21715
  }
@@ -21600,8 +21720,8 @@ function generationAllowed(app, configTs, opts = {}) {
21600
21720
  return { allowed: true, reason: "declares an icon block" };
21601
21721
  }
21602
21722
  const iosCat = iosAssetCatalog2(app);
21603
- const iosIcon = iosCat ? join27(iosCat, "AppIcon.appiconset", "icon_1024.png") : void 0;
21604
- if (!iosIcon || !existsSync23(iosIcon)) return { allowed: true, reason: "no icon yet" };
21723
+ const iosIcon = iosCat ? join28(iosCat, "AppIcon.appiconset", "icon_1024.png") : void 0;
21724
+ if (!iosIcon || !existsSync24(iosIcon)) return { allowed: true, reason: "no icon yet" };
21605
21725
  const hash = fileSha256(iosIcon);
21606
21726
  const placeholders = opts.placeholderHashes ?? placeholderHashes();
21607
21727
  if (app === "_template") return { allowed: true, reason: "the template itself" };
@@ -21625,8 +21745,8 @@ var init_plan2 = __esm({
21625
21745
  });
21626
21746
 
21627
21747
  // ../native-config/icon.ts
21628
- import { existsSync as existsSync24, readFileSync as readFileSync26 } from "node:fs";
21629
- import { join as join28 } from "node:path";
21748
+ import { existsSync as existsSync25, readFileSync as readFileSync27 } from "node:fs";
21749
+ import { join as join29 } from "node:path";
21630
21750
  function androidAdaptiveIconXml() {
21631
21751
  return [
21632
21752
  '<?xml version="1.0" encoding="utf-8"?>',
@@ -21653,8 +21773,8 @@ function androidIconArtifacts(app, configTs) {
21653
21773
  if (!androidOptedIn2(manifest)) return [];
21654
21774
  if (!generationAllowed(app, configTs).allowed) return [];
21655
21775
  const res = androidResDir2(manifest);
21656
- const foreground = join28(res, "mipmap-mdpi", "ic_launcher_foreground.png");
21657
- if (!existsSync24(foreground)) {
21776
+ const foreground = join29(res, "mipmap-mdpi", "ic_launcher_foreground.png");
21777
+ if (!existsSync25(foreground)) {
21658
21778
  throw new Error(
21659
21779
  `native-config icon: ${app} opts into @mipmap/ic_launcher but has no mipmap-*/ic_launcher_foreground.png. Run \`npm run app-icons -- ${app}\` first \u2014 the XML emitted here points at those rasters.`
21660
21780
  );
@@ -21663,11 +21783,11 @@ function androidIconArtifacts(app, configTs) {
21663
21783
  const spec = iconSpec(app, configTs, id, resolveTokensPath(app, configTs).path);
21664
21784
  return [
21665
21785
  ...ANDROID_ADAPTIVE_FILES.map((name) => ({
21666
- path: join28(res, "mipmap-anydpi-v26", name),
21786
+ path: join29(res, "mipmap-anydpi-v26", name),
21667
21787
  content: androidAdaptiveIconXml()
21668
21788
  })),
21669
21789
  {
21670
- path: join28(res, "values", ANDROID_ICON_BACKGROUND_FILE),
21790
+ path: join29(res, "values", ANDROID_ICON_BACKGROUND_FILE),
21671
21791
  content: androidIconBackgroundXml(spec.background)
21672
21792
  }
21673
21793
  ];
@@ -21901,8 +22021,8 @@ __export(gen_native_config_exports, {
21901
22021
  tvInfoPlan: () => tvInfoPlan,
21902
22022
  watchInfoPlan: () => watchInfoPlan
21903
22023
  });
21904
- import { existsSync as existsSync25, mkdirSync as mkdirSync12, readFileSync as readFileSync27, readdirSync as readdirSync13, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
21905
- import { dirname as dirname17, join as join29 } from "node:path";
22024
+ import { existsSync as existsSync26, mkdirSync as mkdirSync12, readFileSync as readFileSync28, readdirSync as readdirSync13, rmSync as rmSync3, writeFileSync as writeFileSync11 } from "node:fs";
22025
+ import { dirname as dirname18, join as join30 } from "node:path";
21906
22026
  function parseStringArray(configTs, field) {
21907
22027
  const m = new RegExp(`${field}:\\s*\\[([^\\]]*)\\]`).exec(configTs);
21908
22028
  if (!m) return [];
@@ -21974,9 +22094,9 @@ function buildSet(capabilities, envelope = []) {
21974
22094
  return [...new Set([...capabilities, ...envelope].map(catalogKey))].sort();
21975
22095
  }
21976
22096
  function loadOverrides(app) {
21977
- const p = join29(appDir(app), "native-config.overrides.json");
21978
- if (!existsSync25(p)) return {};
21979
- return JSON.parse(readFileSync27(p, "utf8"));
22097
+ const p = join30(appDir(app), "native-config.overrides.json");
22098
+ if (!existsSync26(p)) return {};
22099
+ return JSON.parse(readFileSync28(p, "utf8"));
21980
22100
  }
21981
22101
  function needsQuote(s) {
21982
22102
  if (s === "") return true;
@@ -22031,19 +22151,19 @@ function endText(kind, label2, indent) {
22031
22151
  return kind === "yaml" ? `${indent}# <<< ${label2} <<<` : `${indent}<!-- <<< ${label2} <<< -->`;
22032
22152
  }
22033
22153
  function hostAppliesDeferredWidgetActions(app) {
22034
- const root = join29(appDir(app), "ios");
22035
- if (!existsSync25(root)) return false;
22154
+ const root = join30(appDir(app), "ios");
22155
+ if (!existsSync26(root)) return false;
22036
22156
  const stack = [root];
22037
22157
  while (stack.length) {
22038
22158
  const dir = stack.pop();
22039
22159
  for (const entry of readdirSync13(dir, { withFileTypes: true })) {
22040
22160
  if (entry.name.startsWith(".") || entry.name === "GeneratedLiveActivity") continue;
22041
- const path = join29(dir, entry.name);
22161
+ const path = join30(dir, entry.name);
22042
22162
  if (entry.isDirectory()) {
22043
22163
  if (entry.name.endsWith(".xcodeproj") || entry.name === "build") continue;
22044
22164
  stack.push(path);
22045
22165
  } else if (entry.name.endsWith(".swift")) {
22046
- if (readFileSync27(path, "utf8").includes("WidgetActionRelay.drain(")) return true;
22166
+ if (readFileSync28(path, "utf8").includes("WidgetActionRelay.drain(")) return true;
22047
22167
  }
22048
22168
  }
22049
22169
  }
@@ -22065,18 +22185,18 @@ function injectBlock(text2, kind, label2, render) {
22065
22185
  return [...lines.slice(0, beginIdx), ...block, ...lines.slice(endIdx + 1)].join("\n");
22066
22186
  }
22067
22187
  function androidManifestPath2(app) {
22068
- const androidDir = join29(appDir(app), "android");
22069
- const preferred = join29(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
22070
- if (existsSync25(preferred)) return preferred;
22071
- const candidates = existsSync25(androidDir) ? readdirSync13(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join29(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync25) : [];
22188
+ const androidDir = join30(appDir(app), "android");
22189
+ const preferred = join30(androidDir, `${app}-app`, "src", "main", "AndroidManifest.xml");
22190
+ if (existsSync26(preferred)) return preferred;
22191
+ const candidates = existsSync26(androidDir) ? readdirSync13(androidDir, { withFileTypes: true }).filter((d) => d.isDirectory() && d.name.endsWith("-app")).map((d) => join30(androidDir, d.name, "src", "main", "AndroidManifest.xml")).filter(existsSync26) : [];
22072
22192
  return candidates.length === 1 ? candidates[0] : preferred;
22073
22193
  }
22074
22194
  function automotiveAppDescPath(app) {
22075
- return join29(dirname17(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
22195
+ return join30(dirname18(androidManifestPath2(app)), "res", "xml", "automotive_app_desc.xml");
22076
22196
  }
22077
22197
  function applyToFile(path, kind, label2, render, check) {
22078
- if (!existsSync25(path)) return { path, outcome: "skipped" };
22079
- const before = readFileSync27(path, "utf8");
22198
+ if (!existsSync26(path)) return { path, outcome: "skipped" };
22199
+ const before = readFileSync28(path, "utf8");
22080
22200
  if (!hasMarkers(before, kind, label2)) return { path, outcome: "skipped" };
22081
22201
  const after = injectBlock(before, kind, label2, render);
22082
22202
  if (after === before) return { path, outcome: "unchanged" };
@@ -22085,15 +22205,15 @@ function applyToFile(path, kind, label2, render, check) {
22085
22205
  return { path, outcome: "written" };
22086
22206
  }
22087
22207
  function applyWholeFile(path, content, check) {
22088
- const current = existsSync25(path) ? readFileSync27(path, "utf8") : null;
22208
+ const current = existsSync26(path) ? readFileSync28(path, "utf8") : null;
22089
22209
  if (current === content) return { path, outcome: "unchanged" };
22090
22210
  if (check) return { path, outcome: "drift" };
22091
- mkdirSync12(dirname17(path), { recursive: true });
22211
+ mkdirSync12(dirname18(path), { recursive: true });
22092
22212
  writeFileSync11(path, content);
22093
22213
  return { path, outcome: "written" };
22094
22214
  }
22095
22215
  function removeWholeFile(path, check) {
22096
- if (!existsSync25(path)) return { path, outcome: "skipped" };
22216
+ if (!existsSync26(path)) return { path, outcome: "skipped" };
22097
22217
  if (check) return { path, outcome: "drift" };
22098
22218
  rmSync3(path);
22099
22219
  return { path, outcome: "removed" };
@@ -22101,7 +22221,7 @@ function removeWholeFile(path, check) {
22101
22221
  function genNativeConfig(app, opts = {}) {
22102
22222
  const check = opts.check ?? false;
22103
22223
  const configPath = appConfigTs(app);
22104
- const configTs = existsSync25(configPath) ? readFileSync27(configPath, "utf8") : "";
22224
+ const configTs = existsSync26(configPath) ? readFileSync28(configPath, "utf8") : "";
22105
22225
  const capabilities = parseStringArray(configTs, "capabilities");
22106
22226
  const envelope = parseStringArray(configTs, "capabilityEnvelope");
22107
22227
  const ids = buildSet(capabilities, envelope);
@@ -22117,7 +22237,7 @@ function genNativeConfig(app, opts = {}) {
22117
22237
  const carBlock = applyToFile(carManifestPath, "xml", LABEL_CAR, (i) => renderCarManifestXml(carCategory, i), check);
22118
22238
  assertCarBlockLanded(app, carCategory, carManifestPath, carBlock.outcome, LABEL_CAR);
22119
22239
  const iosYml = iosProjectYml(app);
22120
- const project = existsSync25(iosYml) ? readFileSync27(iosYml, "utf8") : "";
22240
+ const project = existsSync26(iosYml) ? readFileSync28(iosYml, "utf8") : "";
22121
22241
  const targetManaged = hasMarkers(project, "yaml", LABEL_LIVE_TARGET);
22122
22242
  const embedManaged = hasMarkers(project, "yaml", LABEL_LIVE_EMBED);
22123
22243
  if (targetManaged !== embedManaged) throw new Error(`${app}: Live Activity target and embedding markers must be installed together`);
@@ -22171,12 +22291,12 @@ function genNativeConfig(app, opts = {}) {
22171
22291
  const plan = live2;
22172
22292
  files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_TARGET, (i) => plan.target.map((line) => i + line), check));
22173
22293
  files.push(applyToFile(iosYml, "yaml", LABEL_LIVE_EMBED, (i) => plan.embed.map((line) => i + line), check));
22174
- const source = join29(dirname17(iosYml), LIVE_SOURCE_PATH);
22294
+ const source = join30(dirname18(iosYml), LIVE_SOURCE_PATH);
22175
22295
  files.push(plan.source ? applyWholeFile(source, plan.source, check) : removeWholeFile(source, check));
22176
- const entitlements = join29(dirname17(iosYml), LIVE_ENTITLEMENTS_PATH);
22296
+ const entitlements = join30(dirname18(iosYml), LIVE_ENTITLEMENTS_PATH);
22177
22297
  files.push(plan.entitlements ? applyWholeFile(entitlements, plan.entitlements, check) : removeWholeFile(entitlements, check));
22178
22298
  }
22179
- const iosSplashManaged = existsSync25(iosYml) && hasMarkers(readFileSync27(iosYml, "utf8"), "yaml", LABEL_IOS_SPLASH);
22299
+ const iosSplashManaged = existsSync26(iosYml) && hasMarkers(readFileSync28(iosYml, "utf8"), "yaml", LABEL_IOS_SPLASH);
22180
22300
  const manifest = androidManifestPath2(app);
22181
22301
  const splash = splashPlan(app, configTs, manifest, iosSplashManaged);
22182
22302
  for (const artifact of splash.artifacts) files.push(applyWholeFile(artifact.path, artifact.content, check));
@@ -22264,8 +22384,8 @@ var init_app_module = __esm({
22264
22384
  });
22265
22385
 
22266
22386
  // ../../core/dev-server/src/loader.ts
22267
- import { resolve as resolve18, basename as basename7, dirname as dirname18 } from "node:path";
22268
- import { existsSync as existsSync26, readdirSync as readdirSync14, readFileSync as readFileSync28, mkdirSync as mkdirSync13 } from "node:fs";
22387
+ import { resolve as resolve19, basename as basename7, dirname as dirname19 } from "node:path";
22388
+ import { existsSync as existsSync27, readdirSync as readdirSync14, readFileSync as readFileSync29, mkdirSync as mkdirSync13 } from "node:fs";
22269
22389
  import { pathToFileURL as pathToFileURL5, fileURLToPath as fileURLToPath11 } from "node:url";
22270
22390
  function resolveWixWebAuthConfig(app) {
22271
22391
  const auth = app?.meta.auth;
@@ -22294,17 +22414,17 @@ function resolveWixClientId(app) {
22294
22414
  }
22295
22415
  function resolveDevEntry(name) {
22296
22416
  for (const base of APP_ROOTS2) {
22297
- const dir = resolve18(ROOT2, base, name);
22298
- const entry = resolve18(dir, "dev/index.ts");
22299
- if (existsSync26(entry)) return { entry, dir };
22417
+ const dir = resolve19(ROOT2, base, name);
22418
+ const entry = resolve19(dir, "dev/index.ts");
22419
+ if (existsSync27(entry)) return { entry, dir };
22300
22420
  }
22301
22421
  return null;
22302
22422
  }
22303
22423
  async function devModuleUrl(entry, dir) {
22304
22424
  const hasTypeScriptLoader = process.execArgv.some((arg) => arg.includes("tsx"));
22305
22425
  if (!isOffRepo() && hasTypeScriptLoader) return pathToFileURL5(entry).href;
22306
- const out = resolve18(dir, "dist/.himi/dev.mjs");
22307
- mkdirSync13(dirname18(out), { recursive: true });
22426
+ const out = resolve19(dir, "dist/.himi/dev.mjs");
22427
+ mkdirSync13(dirname19(out), { recursive: true });
22308
22428
  await buildAppEntry(entry, out, {
22309
22429
  // Plain Node must resolve the published-style umbrella entry points for
22310
22430
  // both standalone and in-repo CLI content. In-repo workspace packages
@@ -22326,7 +22446,7 @@ async function importDevModule(name, entry, dir) {
22326
22446
  }
22327
22447
  function readPlatformsJson(dir) {
22328
22448
  try {
22329
- const raw = JSON.parse(readFileSync28(resolve18(dir, "platforms.json"), "utf8"));
22449
+ const raw = JSON.parse(readFileSync29(resolve19(dir, "platforms.json"), "utf8"));
22330
22450
  return Object.fromEntries(
22331
22451
  Object.entries(raw).filter(([k, v]) => VALID_PLATFORM_KEYS2.has(k) && typeof v === "boolean")
22332
22452
  );
@@ -22335,17 +22455,17 @@ function readPlatformsJson(dir) {
22335
22455
  }
22336
22456
  }
22337
22457
  async function loadContent(dir) {
22338
- const absDir = resolve18(dir);
22339
- const entry = resolve18(absDir, "dev/index.ts");
22340
- if (!existsSync26(entry)) {
22458
+ const absDir = resolve19(dir);
22459
+ const entry = resolve19(absDir, "dev/index.ts");
22460
+ if (!existsSync27(entry)) {
22341
22461
  throw new Error(`No content package at "${absDir}": expected ${entry}.`);
22342
22462
  }
22343
22463
  let name = basename7(absDir);
22344
- const manifestPath = resolve18(absDir, "himalaya.content.json");
22345
- if (existsSync26(manifestPath)) {
22464
+ const manifestPath = resolve19(absDir, "himalaya.content.json");
22465
+ if (existsSync27(manifestPath)) {
22346
22466
  let manifest;
22347
22467
  try {
22348
- manifest = JSON.parse(readFileSync28(manifestPath, "utf8"));
22468
+ manifest = JSON.parse(readFileSync29(manifestPath, "utf8"));
22349
22469
  } catch (e) {
22350
22470
  throw new Error(`Invalid himalaya.content.json at ${manifestPath}: ${e.message}`);
22351
22471
  }
@@ -22371,11 +22491,11 @@ function listAvailableApps() {
22371
22491
  const out = [];
22372
22492
  const seen = /* @__PURE__ */ new Set();
22373
22493
  for (const base of APP_ROOTS2) {
22374
- const baseDir = resolve18(ROOT2, base);
22375
- if (!existsSync26(baseDir)) continue;
22494
+ const baseDir = resolve19(ROOT2, base);
22495
+ if (!existsSync27(baseDir)) continue;
22376
22496
  for (const name of readdirSync14(baseDir)) {
22377
22497
  if (name.startsWith("_") || name.startsWith(".") || seen.has(name)) continue;
22378
- if (existsSync26(resolve18(baseDir, name, "dev/index.ts"))) {
22498
+ if (existsSync27(resolve19(baseDir, name, "dev/index.ts"))) {
22379
22499
  seen.add(name);
22380
22500
  out.push({ name, root: base, kind: base === "test-apps" ? "test" : "app" });
22381
22501
  }
@@ -22389,7 +22509,7 @@ var init_loader = __esm({
22389
22509
  init_app_module();
22390
22510
  init_preview_surfaces();
22391
22511
  init_build_lib();
22392
- ROOT2 = resolve18(fileURLToPath11(new URL("../../..", import.meta.url)));
22512
+ ROOT2 = resolve19(fileURLToPath11(new URL("../../..", import.meta.url)));
22393
22513
  APP_ROOTS2 = ["apps", "test-apps"];
22394
22514
  VALID_PLATFORM_KEYS2 = /* @__PURE__ */ new Set([
22395
22515
  ...PREVIEW_SURFACES.map((s) => s.platformKey).filter((k) => k !== null),
@@ -22434,8 +22554,8 @@ var init_build_sha = __esm({
22434
22554
 
22435
22555
  // ../../core/dev-server/src/app-assets.ts
22436
22556
  import { createHash as createHash8 } from "node:crypto";
22437
- import { existsSync as existsSync27, lstatSync as lstatSync3, readFileSync as readFileSync29, readdirSync as readdirSync15, realpathSync as realpathSync3, statSync as statSync6 } from "node:fs";
22438
- import { join as join30, resolve as resolve19, sep as sep5 } from "node:path";
22557
+ import { existsSync as existsSync28, lstatSync as lstatSync3, readFileSync as readFileSync30, readdirSync as readdirSync15, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
22558
+ import { join as join31, resolve as resolve20, sep as sep5 } from "node:path";
22439
22559
  function contentTypeFor(name) {
22440
22560
  const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
22441
22561
  return CONTENT_TYPES[ext] ?? "application/octet-stream";
@@ -22449,19 +22569,19 @@ function assetSha256(bytes2) {
22449
22569
  function findAssetsDir(appDir2) {
22450
22570
  let declared;
22451
22571
  try {
22452
- declared = JSON.parse(readFileSync29(join30(appDir2, "himalaya.content.json"), "utf8")).assets;
22572
+ declared = JSON.parse(readFileSync30(join31(appDir2, "himalaya.content.json"), "utf8")).assets;
22453
22573
  } catch {
22454
22574
  declared = void 0;
22455
22575
  }
22456
22576
  const rel = typeof declared === "string" && declared ? declared : "assets";
22457
- const abs = resolve19(appDir2, rel);
22458
- const base = resolve19(appDir2);
22577
+ const abs = resolve20(appDir2, rel);
22578
+ const base = resolve20(appDir2);
22459
22579
  if (abs !== base && !abs.startsWith(base + sep5)) return null;
22460
- return existsSync27(abs) && statSync6(abs).isDirectory() ? abs : null;
22580
+ return existsSync28(abs) && statSync5(abs).isDirectory() ? abs : null;
22461
22581
  }
22462
22582
  function readOtaOnlyPatterns(appDir2) {
22463
22583
  try {
22464
- const raw = JSON.parse(readFileSync29(join30(appDir2, "assets.json"), "utf8"));
22584
+ const raw = JSON.parse(readFileSync30(join31(appDir2, "assets.json"), "utf8"));
22465
22585
  return Array.isArray(raw.otaOnly) ? raw.otaOnly.filter((p) => typeof p === "string") : [];
22466
22586
  } catch {
22467
22587
  return [];
@@ -22479,7 +22599,7 @@ function collectAssets(appDir2) {
22479
22599
  const walk2 = (abs, prefix) => {
22480
22600
  for (const entry of readdirSync15(abs, { withFileTypes: true })) {
22481
22601
  if (entry.name.startsWith(".")) continue;
22482
- const child = join30(abs, entry.name);
22602
+ const child = join31(abs, entry.name);
22483
22603
  const name = prefix ? `${prefix}/${entry.name}` : entry.name;
22484
22604
  if (entry.isDirectory()) {
22485
22605
  walk2(child, name);
@@ -22488,7 +22608,7 @@ function collectAssets(appDir2) {
22488
22608
  if (!entry.isFile()) continue;
22489
22609
  const ext = name.includes(".") ? name.slice(name.lastIndexOf(".") + 1).toLowerCase() : "";
22490
22610
  const baked = !OTA_ONLY_BY_DEFAULT.has(ext) && !otaOnly.some((p) => matchesPattern(name, p));
22491
- out.push({ name, path: child, bytes: statSync6(child).size, contentType: contentTypeFor(name), baked });
22611
+ out.push({ name, path: child, bytes: statSync5(child).size, contentType: contentTypeFor(name), baked });
22492
22612
  }
22493
22613
  };
22494
22614
  walk2(dir, "");
@@ -22497,7 +22617,7 @@ function collectAssets(appDir2) {
22497
22617
  function collectBrandFonts(appDir2) {
22498
22618
  let faces;
22499
22619
  try {
22500
- faces = JSON.parse(readFileSync29(join30(appDir2, "media/fonts/faces.json"), "utf8"));
22620
+ faces = JSON.parse(readFileSync30(join31(appDir2, "media/fonts/faces.json"), "utf8"));
22501
22621
  } catch {
22502
22622
  return [];
22503
22623
  }
@@ -22510,7 +22630,7 @@ function collectBrandFonts(appDir2) {
22510
22630
  const rel = typeof raw?.file === "string" ? raw.file : "";
22511
22631
  if (!family || !postscriptName || !rel) continue;
22512
22632
  if (rel.startsWith("/") || rel.split("/").includes("..")) continue;
22513
- const path = join30(appDir2, rel);
22633
+ const path = join31(appDir2, rel);
22514
22634
  try {
22515
22635
  if (!lstatSync3(path).isFile()) continue;
22516
22636
  const root = realpathSync3(appDir2);
@@ -22546,7 +22666,7 @@ function resolveAssetForBuild(appDir2, name, serverBaseUrl, appId2) {
22546
22666
  if (!hit) return null;
22547
22667
  let bytes2;
22548
22668
  try {
22549
- bytes2 = readFileSync29(hit.path);
22669
+ bytes2 = readFileSync30(hit.path);
22550
22670
  } catch {
22551
22671
  return null;
22552
22672
  }
@@ -22620,7 +22740,7 @@ async function injectRequest(listener, request) {
22620
22740
  req.headers.host ??= url.host;
22621
22741
  if (body && body.length > 0) req.push(body);
22622
22742
  req.push(null);
22623
- return await new Promise((resolve41, reject) => {
22743
+ return await new Promise((resolve42, reject) => {
22624
22744
  const streamed = () => {
22625
22745
  queueMicrotask(() => {
22626
22746
  req.emit("close");
@@ -22636,7 +22756,7 @@ async function injectRequest(listener, request) {
22636
22756
  else headers2.set(name, value);
22637
22757
  }
22638
22758
  const bodyless = out.status === 204 || out.status === 304 || request.method === "HEAD";
22639
- resolve41(new Response(bodyless ? null : out.body, { status: out.status, headers: headers2 }));
22759
+ resolve42(new Response(bodyless ? null : out.body, { status: out.status, headers: headers2 }));
22640
22760
  }, streamed);
22641
22761
  res.on("inject-error", reject);
22642
22762
  try {
@@ -22739,25 +22859,25 @@ var init_inject = __esm({
22739
22859
 
22740
22860
  // ../../core/dev-server/src/store.ts
22741
22861
  import { mkdirSync as mkdirSync14 } from "node:fs";
22742
- import { dirname as dirname19, resolve as resolve20 } from "node:path";
22862
+ import { dirname as dirname20, resolve as resolve21 } from "node:path";
22743
22863
  import { fileURLToPath as fileURLToPath12 } from "node:url";
22744
22864
  import { createRequire } from "node:module";
22745
22865
  var nodeRequire, ROOT3, Store;
22746
22866
  var init_store2 = __esm({
22747
22867
  "../../core/dev-server/src/store.ts"() {
22748
22868
  nodeRequire = createRequire(import.meta.url);
22749
- ROOT3 = resolve20(fileURLToPath12(new URL("../../..", import.meta.url)));
22869
+ ROOT3 = resolve21(fileURLToPath12(new URL("../../..", import.meta.url)));
22750
22870
  Store = class {
22751
22871
  _db;
22752
22872
  dbPath;
22753
22873
  constructor(appName) {
22754
- const dataRoot = process.env.HIMALAYA_DEV_STORE_DIR ? resolve20(process.env.HIMALAYA_DEV_STORE_DIR) : resolve20(ROOT3, "core/dev-server/data");
22755
- this.dbPath = resolve20(dataRoot, `${appName}.sqlite`);
22874
+ const dataRoot = process.env.HIMALAYA_DEV_STORE_DIR ? resolve21(process.env.HIMALAYA_DEV_STORE_DIR) : resolve21(ROOT3, "core/dev-server/data");
22875
+ this.dbPath = resolve21(dataRoot, `${appName}.sqlite`);
22756
22876
  }
22757
22877
  /** The node:sqlite handle — opened, bootstrapped, and seeded on first access. */
22758
22878
  get db() {
22759
22879
  if (this._db) return this._db;
22760
- mkdirSync14(dirname19(this.dbPath), { recursive: true });
22880
+ mkdirSync14(dirname20(this.dbPath), { recursive: true });
22761
22881
  const { DatabaseSync } = nodeRequire("node:sqlite");
22762
22882
  this._db = new DatabaseSync(this.dbPath, { timeout: 5e3 });
22763
22883
  this.bootstrap();
@@ -23096,15 +23216,15 @@ var init_store2 = __esm({
23096
23216
  });
23097
23217
 
23098
23218
  // ../../core/dev-server/src/derive-transport-capability.ts
23099
- import { readFileSync as readFileSync30 } from "node:fs";
23100
- import { resolve as resolve21 } from "node:path";
23219
+ import { readFileSync as readFileSync31 } from "node:fs";
23220
+ import { resolve as resolve22 } from "node:path";
23101
23221
  function bundleRidesWixTransport(bundleJs) {
23102
23222
  return /himalaya\.wixApi|wixApi\.call/.test(bundleJs);
23103
23223
  }
23104
23224
  function readFirst(roots, file) {
23105
23225
  for (const root of typeof roots === "string" ? [roots] : roots) {
23106
23226
  try {
23107
- return readFileSync30(resolve21(root, file), "utf8");
23227
+ return readFileSync31(resolve22(root, file), "utf8");
23108
23228
  } catch {
23109
23229
  }
23110
23230
  }
@@ -23272,7 +23392,7 @@ var init_wix_member_login = __esm({
23272
23392
  });
23273
23393
 
23274
23394
  // ../../core/dev-server/src/wix-gateway.ts
23275
- import { readFileSync as readFileSync31, existsSync as existsSync28 } from "node:fs";
23395
+ import { readFileSync as readFileSync32, existsSync as existsSync29 } from "node:fs";
23276
23396
  function redactJsonValue(v) {
23277
23397
  if (Array.isArray(v)) return v.map(redactJsonValue);
23278
23398
  if (v && typeof v === "object") {
@@ -23311,8 +23431,8 @@ function resolveNetMocks(fileMocks, appDeclared) {
23311
23431
  }
23312
23432
  function readNetMocksFile(path) {
23313
23433
  try {
23314
- if (!existsSync28(path)) return null;
23315
- const raw = JSON.parse(readFileSync31(path, "utf-8"));
23434
+ if (!existsSync29(path)) return null;
23435
+ const raw = JSON.parse(readFileSync32(path, "utf-8"));
23316
23436
  if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
23317
23437
  if (raw && typeof raw === "object") {
23318
23438
  const o = raw;
@@ -24112,13 +24232,13 @@ var init_l10n_catalog = __esm({
24112
24232
  });
24113
24233
 
24114
24234
  // ../../core/dev-server/src/l10n.ts
24115
- import { readFileSync as readFileSync32, existsSync as existsSync29 } from "node:fs";
24116
- import { resolve as resolve22 } from "node:path";
24235
+ import { readFileSync as readFileSync33, existsSync as existsSync30 } from "node:fs";
24236
+ import { resolve as resolve23 } from "node:path";
24117
24237
  import { fileURLToPath as fileURLToPath13 } from "node:url";
24118
24238
  function loadCatalog2(tag) {
24119
24239
  if (catalogCache.has(tag)) return catalogCache.get(tag);
24120
- const path = resolve22(ROOT4, `tools/l10n/catalog.${tag}.json`);
24121
- const map = existsSync29(path) ? sourceMap(parseCatalog(readFileSync32(path, "utf8"))) : /* @__PURE__ */ new Map();
24240
+ const path = resolve23(ROOT4, `tools/l10n/catalog.${tag}.json`);
24241
+ const map = existsSync30(path) ? sourceMap(parseCatalog(readFileSync33(path, "utf8"))) : /* @__PURE__ */ new Map();
24122
24242
  catalogCache.set(tag, map);
24123
24243
  return map;
24124
24244
  }
@@ -24127,8 +24247,8 @@ function pickLocale(acceptLanguage) {
24127
24247
  const tags = acceptLanguage.split(",").map((s) => s.split(";")[0].trim().toLowerCase()).map((s) => s.split("-")[0]).filter((s) => s.length > 0);
24128
24248
  for (const tag of tags) {
24129
24249
  if (tag === "en") continue;
24130
- const path = resolve22(ROOT4, `tools/l10n/catalog.${tag}.json`);
24131
- if (existsSync29(path)) return tag;
24250
+ const path = resolve23(ROOT4, `tools/l10n/catalog.${tag}.json`);
24251
+ if (existsSync30(path)) return tag;
24132
24252
  }
24133
24253
  return null;
24134
24254
  }
@@ -24184,7 +24304,7 @@ var init_l10n = __esm({
24184
24304
  "../../core/dev-server/src/l10n.ts"() {
24185
24305
  init_l10n_strings();
24186
24306
  init_l10n_catalog();
24187
- ROOT4 = resolve22(fileURLToPath13(new URL("../../..", import.meta.url)));
24307
+ ROOT4 = resolve23(fileURLToPath13(new URL("../../..", import.meta.url)));
24188
24308
  catalogCache = /* @__PURE__ */ new Map();
24189
24309
  }
24190
24310
  });
@@ -24248,13 +24368,13 @@ var init_stable_ids = __esm({
24248
24368
  // ../../core/dev-server/src/preview.ts
24249
24369
  import { spawn as spawn2 } from "node:child_process";
24250
24370
  import { createHash as createHash11 } from "node:crypto";
24251
- import { existsSync as existsSync30, createReadStream, statSync as statSync7, readFileSync as readFileSync33, renameSync, unlinkSync as unlinkSync2 } from "node:fs";
24371
+ import { existsSync as existsSync31, createReadStream, statSync as statSync6, readFileSync as readFileSync34, renameSync, unlinkSync as unlinkSync2 } from "node:fs";
24252
24372
  import { homedir as homedir5, tmpdir as tmpdir2 } from "node:os";
24253
- import { resolve as resolvePath, dirname as dirname20 } from "node:path";
24373
+ import { resolve as resolvePath, dirname as dirname21 } from "node:path";
24254
24374
  import { fileURLToPath as fileURLToPath14 } from "node:url";
24255
24375
  function firstExisting(paths) {
24256
24376
  for (const p of paths) {
24257
- if (p && existsSync30(p)) return p;
24377
+ if (p && existsSync31(p)) return p;
24258
24378
  }
24259
24379
  return null;
24260
24380
  }
@@ -24263,7 +24383,7 @@ function macosWinlistBin() {
24263
24383
  }
24264
24384
  function macosWinlistSourceHash() {
24265
24385
  try {
24266
- return createHash11("sha1").update(readFileSync33(MACOS_WINLIST)).digest("hex").slice(0, 12);
24386
+ return createHash11("sha1").update(readFileSync34(MACOS_WINLIST)).digest("hex").slice(0, 12);
24267
24387
  } catch {
24268
24388
  return "missing";
24269
24389
  }
@@ -24293,7 +24413,7 @@ function isHimalayaAppWindow(w) {
24293
24413
  }
24294
24414
  async function macosWinlistCommand() {
24295
24415
  const bin = macosWinlistBin();
24296
- if (existsSync30(bin)) return compiledWinlist(bin);
24416
+ if (existsSync31(bin)) return compiledWinlist(bin);
24297
24417
  if (macosWinlistCompileFailed) return interpretWinlist();
24298
24418
  if (!macosWinlistInFlight) {
24299
24419
  macosWinlistInFlight = buildMacosWinlist(bin).finally(() => {
@@ -24321,7 +24441,7 @@ async function buildMacosWinlist(bin) {
24321
24441
  unlinkSync2(staging);
24322
24442
  } catch {
24323
24443
  }
24324
- return existsSync30(bin) ? compiledWinlist(bin) : interpretWinlist();
24444
+ return existsSync31(bin) ? compiledWinlist(bin) : interpretWinlist();
24325
24445
  }
24326
24446
  return compiledWinlist(bin);
24327
24447
  }
@@ -24408,7 +24528,7 @@ async function captureFrame(params, format = "png") {
24408
24528
  const tmp = resolvePath(tmpdir2(), `himalaya-macos-preview-${windowId}-${process.pid}-${++macosCaptureSeq}.png`);
24409
24529
  try {
24410
24530
  await runner.capture(SCREENCAPTURE_BIN, ["-o", "-x", `-l${windowId}`, tmp]);
24411
- return { buf: readFileSync33(tmp), mime: "image/png" };
24531
+ return { buf: readFileSync34(tmp), mime: "image/png" };
24412
24532
  } finally {
24413
24533
  try {
24414
24534
  unlinkSync2(tmp);
@@ -24921,12 +25041,12 @@ function finalizeRecording(key2, rec) {
24921
25041
  if (rec.finalize) return rec.finalize;
24922
25042
  rec.finalize = (async () => {
24923
25043
  clearTimeout(rec.autoStop);
24924
- await new Promise((resolve41) => {
25044
+ await new Promise((resolve42) => {
24925
25045
  let done = false;
24926
25046
  const finish2 = () => {
24927
25047
  if (!done) {
24928
25048
  done = true;
24929
- resolve41();
25049
+ resolve42();
24930
25050
  }
24931
25051
  };
24932
25052
  rec.child.once("close", finish2);
@@ -24946,7 +25066,7 @@ function finalizeRecording(key2, rec) {
24946
25066
  } catch {
24947
25067
  }
24948
25068
  }
24949
- const sizeBytes = existsSync30(rec.localPath) ? statSync7(rec.localPath).size : 0;
25069
+ const sizeBytes = existsSync31(rec.localPath) ? statSync6(rec.localPath).size : 0;
24950
25070
  clips.set(rec.id, { path: rec.localPath, mime: rec.mime });
24951
25071
  recordings.delete(key2);
24952
25072
  return { sizeBytes };
@@ -25018,12 +25138,12 @@ async function handlePreviewClip(res, url) {
25018
25138
  const q = new URLSearchParams(url.split("?")[1] ?? "");
25019
25139
  const id = q.get("id") ?? "";
25020
25140
  const clip = clips.get(id);
25021
- if (!clip || !existsSync30(clip.path)) {
25141
+ if (!clip || !existsSync31(clip.path)) {
25022
25142
  res.statusCode = 404;
25023
25143
  res.setHeader("content-type", "application/json");
25024
25144
  return void res.end(JSON.stringify({ error: "clip_not_found", id }));
25025
25145
  }
25026
- const size = statSync7(clip.path).size;
25146
+ const size = statSync6(clip.path).size;
25027
25147
  res.statusCode = 200;
25028
25148
  res.setHeader("content-type", clip.mime);
25029
25149
  res.setHeader("content-length", String(size));
@@ -25037,7 +25157,7 @@ var init_preview = __esm({
25037
25157
  DEVICE_LIST_TIMEOUT_MS = 5e3;
25038
25158
  defaultRunner2 = {
25039
25159
  capture(cmd, args, timeoutMs = DEFAULT_CAPTURE_TIMEOUT_MS) {
25040
- return new Promise((resolve41, reject) => {
25160
+ return new Promise((resolve42, reject) => {
25041
25161
  const child = spawn2(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
25042
25162
  const out = [];
25043
25163
  const err = [];
@@ -25059,7 +25179,7 @@ var init_preview = __esm({
25059
25179
  child.stderr.on("data", (b) => err.push(b));
25060
25180
  child.on("error", (e) => settle(reject, e));
25061
25181
  child.on("close", (code) => {
25062
- if (code === 0) settle(resolve41, Buffer.concat(out));
25182
+ if (code === 0) settle(resolve42, Buffer.concat(out));
25063
25183
  else settle(reject, new Error(`${cmd} exited ${code}: ${Buffer.concat(err).toString("utf8")}`));
25064
25184
  });
25065
25185
  });
@@ -25079,7 +25199,7 @@ var init_preview = __esm({
25079
25199
  SWIFT_BIN = process.env.HIMALAYA_SWIFT_PATH ?? "swift";
25080
25200
  SWIFTC_BIN = process.env.HIMALAYA_SWIFTC_PATH ?? "swiftc";
25081
25201
  SCREENCAPTURE_BIN = process.env.HIMALAYA_SCREENCAPTURE_PATH ?? "screencapture";
25082
- MACOS_WINLIST = resolvePath(dirname20(fileURLToPath14(import.meta.url)), "../scripts/macos-winshot.swift");
25202
+ MACOS_WINLIST = resolvePath(dirname21(fileURLToPath14(import.meta.url)), "../scripts/macos-winshot.swift");
25083
25203
  MACOS_WINLIST_BUILD_TIMEOUT_MS = 12e4;
25084
25204
  MACOS_WINLIST_INTERPRET_TIMEOUT_MS = 3e4;
25085
25205
  HIMALAYA_MAC_BUNDLE_ID = /^(com\.himalaya\.|com\.wix\.himi\.|dev\.himalaya\.)/i;
@@ -25136,8 +25256,8 @@ var init_tier4_integrity = __esm({
25136
25256
  });
25137
25257
 
25138
25258
  // ../../core/dev-server/src/tier4-verifier.ts
25139
- import { readFileSync as readFileSync34, existsSync as existsSync31 } from "node:fs";
25140
- import { resolve as resolve23 } from "node:path";
25259
+ import { readFileSync as readFileSync35, existsSync as existsSync32 } from "node:fs";
25260
+ import { resolve as resolve24 } from "node:path";
25141
25261
  var TierFourVerifier;
25142
25262
  var init_tier4_verifier = __esm({
25143
25263
  "../../core/dev-server/src/tier4-verifier.ts"() {
@@ -25153,8 +25273,8 @@ var init_tier4_verifier = __esm({
25153
25273
  async verifyServedFile(bundleId, relPath, providedBytes) {
25154
25274
  const expected = this.expectedSri(bundleId, relPath);
25155
25275
  if (!expected) return { ok: true };
25156
- const path = resolve23(this.tier4Root, bundleId, relPath);
25157
- const bytes2 = providedBytes ?? (existsSync31(path) ? readFileSync34(path) : null);
25276
+ const path = resolve24(this.tier4Root, bundleId, relPath);
25277
+ const bytes2 = providedBytes ?? (existsSync32(path) ? readFileSync35(path) : null);
25158
25278
  if (!bytes2) return { ok: false, reason: "file not found" };
25159
25279
  if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
25160
25280
  return { ok: true };
@@ -25162,9 +25282,9 @@ var init_tier4_verifier = __esm({
25162
25282
  bundle(bundleId) {
25163
25283
  let cached3 = this.cache.get(bundleId);
25164
25284
  if (cached3) return cached3;
25165
- const manifestPath = resolve23(this.tier4Root, bundleId, "manifest.json");
25166
- if (!existsSync31(manifestPath)) return void 0;
25167
- const manifest = JSON.parse(readFileSync34(manifestPath, "utf8"));
25285
+ const manifestPath = resolve24(this.tier4Root, bundleId, "manifest.json");
25286
+ if (!existsSync32(manifestPath)) return void 0;
25287
+ const manifest = JSON.parse(readFileSync35(manifestPath, "utf8"));
25168
25288
  cached3 = { integrity: parseManifestIntegrity(manifest) };
25169
25289
  this.cache.set(bundleId, cached3);
25170
25290
  return cached3;
@@ -26603,6 +26723,7 @@ function shouldRevealError(args) {
26603
26723
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
26604
26724
  var init_validation = __esm({
26605
26725
  "../../core/ts/src/validation.ts"() {
26726
+ "use strict";
26606
26727
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
26607
26728
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
26608
26729
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -30025,6 +30146,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
30025
30146
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
30026
30147
  var init_worker_subtree = __esm({
30027
30148
  "../../core/ts/src/worker-subtree.ts"() {
30149
+ "use strict";
30028
30150
  init_worker_subtree_safe_types_generated();
30029
30151
  WORKER_SUBTREE_CEILINGS = Object.freeze({
30030
30152
  maxEncodedBytes: 65536,
@@ -35742,7 +35864,7 @@ async function stabilizePngPage(page, scheme) {
35742
35864
  const browser = globalThis;
35743
35865
  browser.document.documentElement.style.colorScheme = selected;
35744
35866
  await browser.document.fonts?.ready;
35745
- await new Promise((resolve41) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve41())));
35867
+ await new Promise((resolve42) => browser.requestAnimationFrame(() => browser.requestAnimationFrame(() => resolve42())));
35746
35868
  }, scheme);
35747
35869
  }
35748
35870
  async function renderPngBatch(items) {
@@ -36686,8 +36808,8 @@ var init_src5 = __esm({
36686
36808
  });
36687
36809
 
36688
36810
  // ../../core/dev-server/src/flags/index.ts
36689
- import { readFileSync as readFileSync35 } from "node:fs";
36690
- import { resolve as resolve24 } from "node:path";
36811
+ import { readFileSync as readFileSync36 } from "node:fs";
36812
+ import { resolve as resolve25 } from "node:path";
36691
36813
  function selectProvider(config, store) {
36692
36814
  const local = new LocalFlagProvider(store, () => config?.overrides);
36693
36815
  if (!config || config.provider === "local") return local;
@@ -36782,7 +36904,7 @@ var init_flags2 = __esm({
36782
36904
  if (now - this.lastFetch < this.ttlMs) return;
36783
36905
  this.lastFetch = now;
36784
36906
  try {
36785
- const defs = JSON.parse(readFileSync35(resolve24(appDir2, "flags.json"), "utf8"));
36907
+ const defs = JSON.parse(readFileSync36(resolve25(appDir2, "flags.json"), "utf8"));
36786
36908
  if (Array.isArray(defs) && defs.length > 0) store.replaceAll(defs);
36787
36909
  } catch {
36788
36910
  }
@@ -36832,19 +36954,19 @@ var init_motion_flags = __esm({
36832
36954
  });
36833
36955
 
36834
36956
  // ../../core/dev-server/src/kits.ts
36835
- import { readdirSync as readdirSync16, readFileSync as readFileSync36 } from "node:fs";
36836
- import { resolve as resolve25, join as join31 } from "node:path";
36957
+ import { readdirSync as readdirSync16, readFileSync as readFileSync37 } from "node:fs";
36958
+ import { resolve as resolve26, join as join32 } from "node:path";
36837
36959
  import { fileURLToPath as fileURLToPath15 } from "node:url";
36838
36960
  function listKits() {
36839
36961
  return readdirSync16(CATALOG).filter((f) => f.endsWith(".json")).map((f) => {
36840
- const { tokens, ...meta } = JSON.parse(readFileSync36(join31(CATALOG, f), "utf8"));
36962
+ const { tokens, ...meta } = JSON.parse(readFileSync37(join32(CATALOG, f), "utf8"));
36841
36963
  return meta;
36842
36964
  });
36843
36965
  }
36844
36966
  function readKit(id) {
36845
36967
  if (!/^[a-z0-9-]+$/.test(id)) return null;
36846
36968
  try {
36847
- return JSON.parse(readFileSync36(join31(CATALOG, `${id}.json`), "utf8"));
36969
+ return JSON.parse(readFileSync37(join32(CATALOG, `${id}.json`), "utf8"));
36848
36970
  } catch {
36849
36971
  return null;
36850
36972
  }
@@ -36852,8 +36974,8 @@ function readKit(id) {
36852
36974
  var ROOT5, CATALOG;
36853
36975
  var init_kits = __esm({
36854
36976
  "../../core/dev-server/src/kits.ts"() {
36855
- ROOT5 = resolve25(fileURLToPath15(new URL("../../..", import.meta.url)));
36856
- CATALOG = join31(ROOT5, "stdlib/design-kits");
36977
+ ROOT5 = resolve26(fileURLToPath15(new URL("../../..", import.meta.url)));
36978
+ CATALOG = join32(ROOT5, "stdlib/design-kits");
36857
36979
  }
36858
36980
  });
36859
36981
 
@@ -37221,12 +37343,12 @@ __export(validate_descriptor_exports, {
37221
37343
  validateScreenDescriptor: () => validateScreenDescriptor,
37222
37344
  workerSubtreeAllowed: () => workerSubtreeAllowed
37223
37345
  });
37224
- import { readFileSync as readFileSync37, existsSync as existsSync32, readdirSync as readdirSync17 } from "node:fs";
37225
- import { resolve as resolve26 } from "node:path";
37346
+ import { readFileSync as readFileSync38, existsSync as existsSync33, readdirSync as readdirSync17 } from "node:fs";
37347
+ import { resolve as resolve27 } from "node:path";
37226
37348
  import { runInNewContext as runInNewContext2 } from "node:vm";
37227
37349
  async function loadAllowedComponents(appDir2) {
37228
- const modPath = resolve26(appDir2, "components.ts");
37229
- if (!existsSync32(modPath)) return void 0;
37350
+ const modPath = resolve27(appDir2, "components.ts");
37351
+ if (!existsSync33(modPath)) return void 0;
37230
37352
  try {
37231
37353
  const { pathToFileURL: pathToFileURL8 } = await import("node:url");
37232
37354
  const mod = await import(pathToFileURL8(modPath).href);
@@ -37238,8 +37360,8 @@ async function loadAllowedComponents(appDir2) {
37238
37360
  return void 0;
37239
37361
  }
37240
37362
  function readBuiltBundle(tier5Root, bundleName) {
37241
- const p = resolve26(tier5Root, `${bundleName}.bundle.js`);
37242
- return existsSync32(p) ? readFileSync37(p, "utf8") : void 0;
37363
+ const p = resolve27(tier5Root, `${bundleName}.bundle.js`);
37364
+ return existsSync33(p) ? readFileSync38(p, "utf8") : void 0;
37243
37365
  }
37244
37366
  function bundleNameFromUrl(url) {
37245
37367
  if (typeof url !== "string") return null;
@@ -37266,11 +37388,11 @@ function appWorkerActionsFor(config, tier5Root) {
37266
37388
  }
37267
37389
  }
37268
37390
  function readBuiltBundleMap(tier5Root, bundleName) {
37269
- const p = resolve26(tier5Root, `${bundleName}.bundle.js.map`);
37270
- return existsSync32(p) ? readFileSync37(p, "utf8") : void 0;
37391
+ const p = resolve27(tier5Root, `${bundleName}.bundle.js.map`);
37392
+ return existsSync33(p) ? readFileSync38(p, "utf8") : void 0;
37271
37393
  }
37272
37394
  function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
37273
- if (!existsSync32(directory)) return [];
37395
+ if (!existsSync33(directory)) return [];
37274
37396
  let entries;
37275
37397
  try {
37276
37398
  entries = readdirSync17(directory, { withFileTypes: true });
@@ -37281,7 +37403,7 @@ function nativeSourceFiles(directory, extension, buildDirMaxDepth, depth = 1) {
37281
37403
  return entries.flatMap((entry) => {
37282
37404
  if (NATIVE_SCRATCH_DIRS.has(entry.name)) return [];
37283
37405
  if (entry.name === BUILD_OUTPUT_DIR && depth <= buildDirMaxDepth) return [];
37284
- const path = resolve26(directory, entry.name);
37406
+ const path = resolve27(directory, entry.name);
37285
37407
  if (entry.isDirectory()) return nativeSourceFiles(path, extension, buildDirMaxDepth, depth + 1);
37286
37408
  return entry.name.endsWith(extension) ? [path] : [];
37287
37409
  });
@@ -37290,12 +37412,12 @@ function registeredActions(source) {
37290
37412
  return [...source.matchAll(/ActionDispatcher(?:\.shared)?\s*\.\s*register\s*\(\s*"([A-Za-z0-9_.]+)"/g)].map((match) => match[1]);
37291
37413
  }
37292
37414
  function discoverNativeActions(appDir2) {
37293
- const roots = NATIVE_SOURCE_ROOTS.filter(({ directory }) => existsSync32(resolve26(appDir2, directory)));
37294
- const sources = roots.flatMap(({ directory, extension, buildDirMaxDepth }) => nativeSourceFiles(resolve26(appDir2, directory), extension, buildDirMaxDepth));
37415
+ const roots = NATIVE_SOURCE_ROOTS.filter(({ directory }) => existsSync33(resolve27(appDir2, directory)));
37416
+ const sources = roots.flatMap(({ directory, extension, buildDirMaxDepth }) => nativeSourceFiles(resolve27(appDir2, directory), extension, buildDirMaxDepth));
37295
37417
  const registered = sources.flatMap((source) => {
37296
37418
  let text2;
37297
37419
  try {
37298
- text2 = readFileSync37(source, "utf8");
37420
+ text2 = readFileSync38(source, "utf8");
37299
37421
  } catch (err) {
37300
37422
  if (!vanished(err)) throw err;
37301
37423
  return [];
@@ -37411,8 +37533,8 @@ __export(config_exports, {
37411
37533
  serializeRolloutYaml: () => serializeRolloutYaml,
37412
37534
  validateOverlayPatch: () => validateOverlayPatch
37413
37535
  });
37414
- import { mkdirSync as mkdirSync15, readFileSync as readFileSync38, writeFileSync as writeFileSync12 } from "node:fs";
37415
- import { dirname as dirname21, join as join32, resolve as resolve27 } from "node:path";
37536
+ import { mkdirSync as mkdirSync15, readFileSync as readFileSync39, writeFileSync as writeFileSync12 } from "node:fs";
37537
+ import { dirname as dirname22, join as join33, resolve as resolve28 } from "node:path";
37416
37538
  import { fileURLToPath as fileURLToPath16 } from "node:url";
37417
37539
  function strip(line) {
37418
37540
  const h = line.indexOf("#");
@@ -37477,14 +37599,14 @@ function parseRevocationsYaml(text2) {
37477
37599
  function appConfigPath(app, file, root = REPO_ROOT6) {
37478
37600
  assertAppId(app, "appConfigPath");
37479
37601
  for (const base of ["apps", "test-apps"]) {
37480
- const p = join32(root, base, app, file);
37602
+ const p = join33(root, base, app, file);
37481
37603
  try {
37482
- readFileSync38(p);
37604
+ readFileSync39(p);
37483
37605
  return p;
37484
37606
  } catch {
37485
37607
  }
37486
37608
  }
37487
- return join32(root, "apps", app, file);
37609
+ return join33(root, "apps", app, file);
37488
37610
  }
37489
37611
  function serializeRolloutYaml(cfg) {
37490
37612
  const lines = [`app: ${cfg.app}`, "rings:"];
@@ -37519,14 +37641,14 @@ function validateOverlayPatch(patch) {
37519
37641
  }
37520
37642
  function readJsonAt(app, file, root) {
37521
37643
  try {
37522
- return JSON.parse(readFileSync38(appConfigPath(app, file, root), "utf8"));
37644
+ return JSON.parse(readFileSync39(appConfigPath(app, file, root), "utf8"));
37523
37645
  } catch {
37524
37646
  return null;
37525
37647
  }
37526
37648
  }
37527
37649
  function writeJsonAt(app, file, root, value) {
37528
37650
  const path = appConfigPath(app, file, root);
37529
- mkdirSync15(dirname21(path), { recursive: true });
37651
+ mkdirSync15(dirname22(path), { recursive: true });
37530
37652
  writeFileSync12(path, JSON.stringify(value, null, 2) + "\n");
37531
37653
  return path;
37532
37654
  }
@@ -37549,14 +37671,14 @@ function saveLocalFlags(app, defs, root = REPO_ROOT6) {
37549
37671
  }
37550
37672
  function loadRollout(app) {
37551
37673
  try {
37552
- return parseRolloutYaml(readFileSync38(appConfigPath(app, "rollout.yaml"), "utf8"));
37674
+ return parseRolloutYaml(readFileSync39(appConfigPath(app, "rollout.yaml"), "utf8"));
37553
37675
  } catch {
37554
37676
  return null;
37555
37677
  }
37556
37678
  }
37557
37679
  function loadRevocations(app) {
37558
37680
  try {
37559
- return parseRevocationsYaml(readFileSync38(appConfigPath(app, "revocations.yaml"), "utf8")).revoked;
37681
+ return parseRevocationsYaml(readFileSync39(appConfigPath(app, "revocations.yaml"), "utf8")).revoked;
37560
37682
  } catch {
37561
37683
  return [];
37562
37684
  }
@@ -37566,7 +37688,7 @@ var init_config2 = __esm({
37566
37688
  "../../core/serve-control/src/config.ts"() {
37567
37689
  init_errors();
37568
37690
  init_contract();
37569
- REPO_ROOT6 = resolve27(dirname21(fileURLToPath16(import.meta.url)), "../../..");
37691
+ REPO_ROOT6 = resolve28(dirname22(fileURLToPath16(import.meta.url)), "../../..");
37570
37692
  OPERATIONAL_OVERLAY_KEYS = /* @__PURE__ */ new Set([
37571
37693
  "wixCachePolicy",
37572
37694
  "telemetryConfig",
@@ -37627,8 +37749,8 @@ var init_config2 = __esm({
37627
37749
  // ../../core/dev-server/src/index.ts
37628
37750
  import { createServer as createServer2 } from "node:http";
37629
37751
  import { readFile as readFile2, stat } from "node:fs/promises";
37630
- import { readFileSync as readFileSync39, existsSync as existsSync33, watch, mkdirSync as mkdirSync16, rmSync as rmSync4 } from "node:fs";
37631
- import { extname, resolve as resolve28, normalize as normalize3, sep as sep6, join as join33 } from "node:path";
37752
+ import { readFileSync as readFileSync40, existsSync as existsSync34, watch, mkdirSync as mkdirSync16, rmSync as rmSync4 } from "node:fs";
37753
+ import { extname, resolve as resolve29, normalize as normalize3, sep as sep6, join as join34 } from "node:path";
37632
37754
  import { createHash as createHash15, randomUUID } from "node:crypto";
37633
37755
  import { fileURLToPath as fileURLToPath17, pathToFileURL as pathToFileURL6 } from "node:url";
37634
37756
  function deepMerge2(base, patch) {
@@ -37677,8 +37799,8 @@ function makeEtag(body) {
37677
37799
  function readAppTokens(state) {
37678
37800
  if (!state.app) return null;
37679
37801
  try {
37680
- const tokenPath = state.app.module.designTokensPath ?? resolve28(state.app.dir, state.app.module.config.designTokensPath ?? "tokens.json");
37681
- const parsed = JSON.parse(readFileSync39(tokenPath, "utf8"));
37802
+ const tokenPath = state.app.module.designTokensPath ?? resolve29(state.app.dir, state.app.module.config.designTokensPath ?? "tokens.json");
37803
+ const parsed = JSON.parse(readFileSync40(tokenPath, "utf8"));
37682
37804
  delete parsed._meta;
37683
37805
  return parsed;
37684
37806
  } catch {
@@ -37690,7 +37812,7 @@ function effectiveAppConfigOverride(state) {
37690
37812
  if (state.app) {
37691
37813
  try {
37692
37814
  gitOverlay = JSON.parse(
37693
- readFileSync39(resolve28(state.app.dir, "app-config.overlay.json"), "utf8")
37815
+ readFileSync40(resolve29(state.app.dir, "app-config.overlay.json"), "utf8")
37694
37816
  );
37695
37817
  } catch {
37696
37818
  }
@@ -37746,8 +37868,8 @@ function handleL10nRequest(req, res, state) {
37746
37868
  if (!state.app || app !== state.app.name) {
37747
37869
  return sendJson(res, 404, { error: "unknown_app", app }, cors);
37748
37870
  }
37749
- const path = resolve28(state.app.dir, "l10n", `${tag}.json`);
37750
- if (!existsSync33(path)) {
37871
+ const path = resolve29(state.app.dir, "l10n", `${tag}.json`);
37872
+ if (!existsSync34(path)) {
37751
37873
  res.writeHead(204, cors);
37752
37874
  res.end();
37753
37875
  return;
@@ -37756,7 +37878,7 @@ function handleL10nRequest(req, res, state) {
37756
37878
  let messages;
37757
37879
  try {
37758
37880
  messages = Object.fromEntries(
37759
- keyMap(parseCatalog(readFileSync39(path, "utf8")), { sourceFallback: tag === sourceLocale })
37881
+ keyMap(parseCatalog(readFileSync40(path, "utf8")), { sourceFallback: tag === sourceLocale })
37760
37882
  );
37761
37883
  } catch {
37762
37884
  return sendJson(res, 500, { error: "catalog_unreadable", app, tag }, cors);
@@ -37803,8 +37925,8 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
37803
37925
  }
37804
37926
  function servedFontFaces(appDir2, tokens) {
37805
37927
  try {
37806
- const policyPath = join33(appDir2, "fonts.json");
37807
- const policy = existsSync33(policyPath) ? JSON.parse(readFileSync39(policyPath, "utf8")) : {};
37928
+ const policyPath = join34(appDir2, "fonts.json");
37929
+ const policy = existsSync34(policyPath) ? JSON.parse(readFileSync40(policyPath, "utf8")) : {};
37808
37930
  const plan = planFonts(tokens, policy);
37809
37931
  if (plan.families.length === 0) return void 0;
37810
37932
  return servedProjection(plan);
@@ -37819,7 +37941,7 @@ function fontFaceBytesBySha(_appDir, sha) {
37819
37941
  for (const face of family.faces) {
37820
37942
  if (face.sha256 !== sha) continue;
37821
37943
  const src = faceSource(face.file, face.sha256);
37822
- if (src) return readFileSync39(src);
37944
+ if (src) return readFileSync40(src);
37823
37945
  }
37824
37946
  }
37825
37947
  } catch {
@@ -38166,7 +38288,7 @@ async function buildDescriptorForScreenId(state, screenId, query = new URLSearch
38166
38288
  function bundleIntegritySync(name, dir) {
38167
38289
  for (const root of dir ? [dir, TIER5_ROOT] : [TIER5_ROOT]) {
38168
38290
  try {
38169
- const bytes2 = readFileSync39(resolve28(root, `${name}.bundle.js`));
38291
+ const bytes2 = readFileSync40(resolve29(root, `${name}.bundle.js`));
38170
38292
  return "sha256-" + createHash15("sha256").update(bytes2).digest("base64");
38171
38293
  } catch {
38172
38294
  }
@@ -38416,7 +38538,7 @@ function startBundleArtifactWatcher(state) {
38416
38538
  }
38417
38539
  }
38418
38540
  async function rebuildBundleSource(name) {
38419
- const lib = await import(pathToFileURL6(resolve28(TIER5_SRC_ROOT, "build-lib.mjs")).href);
38541
+ const lib = await import(pathToFileURL6(resolve29(TIER5_SRC_ROOT, "build-lib.mjs")).href);
38420
38542
  await lib.buildBundle(name);
38421
38543
  }
38422
38544
  function startBundleSourceWatcher(state) {
@@ -38471,11 +38593,11 @@ function applyTopBarDefault(descriptor, config) {
38471
38593
  async function reloadAppModule(state, opts) {
38472
38594
  const current = state.app;
38473
38595
  if (!current) return { ok: false, error: "no_app" };
38474
- const entry = resolve28(current.dir, "dev/index.ts");
38596
+ const entry = resolve29(current.dir, "dev/index.ts");
38475
38597
  mkdirSync16(HMR_TMP_DIR, { recursive: true });
38476
- const outfile = resolve28(HMR_TMP_DIR, `${current.name}-${++appReloadSeq}.mjs`);
38598
+ const outfile = resolve29(HMR_TMP_DIR, `${current.name}-${++appReloadSeq}.mjs`);
38477
38599
  try {
38478
- const lib = await import(pathToFileURL6(resolve28(TIER5_SRC_ROOT, "build-lib.mjs")).href);
38600
+ const lib = await import(pathToFileURL6(resolve29(TIER5_SRC_ROOT, "build-lib.mjs")).href);
38479
38601
  await lib.buildAppEntry(entry, outfile, { confineTo: current.dir });
38480
38602
  const mod = await import(pathToFileURL6(outfile).href);
38481
38603
  const next = mod.default;
@@ -38748,7 +38870,7 @@ async function handleWebWix(req, res, state) {
38748
38870
  }
38749
38871
  if (match && (match.rule.kind ?? "mock") === "mock") {
38750
38872
  const mocked = match.rule.response;
38751
- if (mocked.delayMs) await new Promise((resolve41) => setTimeout(resolve41, mocked.delayMs));
38873
+ if (mocked.delayMs) await new Promise((resolve42) => setTimeout(resolve42, mocked.delayMs));
38752
38874
  const responseBody = mocked.template ? renderTemplate(mocked.body, match.captures) : mocked.body;
38753
38875
  recordWixTraffic(state.wix, state.appName, state.adminUrl, {
38754
38876
  ts: started,
@@ -39239,7 +39361,7 @@ async function handleAdminPlayground(req, res, state) {
39239
39361
  const name = decodeURIComponent(sampleMatch[1]);
39240
39362
  if (!/^[a-zA-Z0-9._-]+$/.test(name)) return sendJson(res, 400, { error: "bad_name" });
39241
39363
  try {
39242
- const body = await readFile2(resolve28(SAMPLES_ROOT, name), "utf-8");
39364
+ const body = await readFile2(resolve29(SAMPLES_ROOT, name), "utf-8");
39243
39365
  return sendJson(res, 200, JSON.parse(body));
39244
39366
  } catch {
39245
39367
  return sendJson(res, 404, { error: "sample_not_found", name });
@@ -39509,9 +39631,9 @@ async function readBundleFile(name, dir) {
39509
39631
  if (!/^[A-Za-z0-9_.\-]+$/.test(name)) return null;
39510
39632
  const roots = dir ? [dir, TIER5_ROOT] : [TIER5_ROOT];
39511
39633
  const candidates = roots.flatMap((root) => [
39512
- resolve28(root, `${name}.bundle.js`),
39513
- resolve28(root, `${name}.js`),
39514
- resolve28(root, name)
39634
+ resolve29(root, `${name}.bundle.js`),
39635
+ resolve29(root, `${name}.js`),
39636
+ resolve29(root, name)
39515
39637
  ]);
39516
39638
  for (const path of candidates) {
39517
39639
  if (!roots.some((root) => path.startsWith(root))) continue;
@@ -39662,14 +39784,14 @@ async function handleWidgetClearPreview(res, state, widgetId) {
39662
39784
  }
39663
39785
  function readActionHandlerManifest(app) {
39664
39786
  if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return { handlers: [] };
39665
- const manifestPath = resolve28(ACTION_HANDLERS_ROOT, `${app}.manifest.json`);
39666
- const bundlePath = resolve28(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
39787
+ const manifestPath = resolve29(ACTION_HANDLERS_ROOT, `${app}.manifest.json`);
39788
+ const bundlePath = resolve29(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
39667
39789
  if (!manifestPath.startsWith(ACTION_HANDLERS_ROOT) || !bundlePath.startsWith(ACTION_HANDLERS_ROOT)) return { handlers: [] };
39668
39790
  let decls;
39669
39791
  let bytes2;
39670
39792
  try {
39671
- decls = JSON.parse(readFileSync39(manifestPath, "utf8"));
39672
- bytes2 = readFileSync39(bundlePath);
39793
+ decls = JSON.parse(readFileSync40(manifestPath, "utf8"));
39794
+ bytes2 = readFileSync40(bundlePath);
39673
39795
  } catch {
39674
39796
  return { handlers: [] };
39675
39797
  }
@@ -39682,7 +39804,7 @@ function handleActionHandlersManifest(res, app) {
39682
39804
  }
39683
39805
  async function handleActionHandlerBundleGet(res, app) {
39684
39806
  if (!/^[A-Za-z0-9_.\-]+$/.test(app)) return sendJson(res, 404, { error: "not_found" });
39685
- const path = resolve28(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
39807
+ const path = resolve29(ACTION_HANDLERS_ROOT, `${app}.handlers.js`);
39686
39808
  if (!path.startsWith(ACTION_HANDLERS_ROOT)) return sendJson(res, 404, { error: "not_found" });
39687
39809
  try {
39688
39810
  const bytes2 = await readFile2(path);
@@ -39699,9 +39821,9 @@ async function handleActionHandlerBundleGet(res, app) {
39699
39821
  }
39700
39822
  async function serveStatic(req, res, root, prefix) {
39701
39823
  const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
39702
- const relative7 = requested.replace(prefix, "").replace(/^\//, "");
39703
- const safe = normalize3(relative7).replace(/^(\.\.[\/\\])+/, "");
39704
- const fullPath = resolve28(root, safe);
39824
+ const relative8 = requested.replace(prefix, "").replace(/^\//, "");
39825
+ const safe = normalize3(relative8).replace(/^(\.\.[\/\\])+/, "");
39826
+ const fullPath = resolve29(root, safe);
39705
39827
  if (!fullPath.startsWith(root)) {
39706
39828
  return send(res, 403, "forbidden");
39707
39829
  }
@@ -39907,7 +40029,7 @@ function createDevServer(opts = {}) {
39907
40029
  };
39908
40030
  const netMocksDisabled = opts.netMocks === false;
39909
40031
  const explicitNetMocksPath = typeof opts.netMocks === "string" ? opts.netMocks : process.env.HIMALAYA_NET_MOCKS;
39910
- const netMocksPath = netMocksDisabled ? void 0 : explicitNetMocksPath ?? (state.app?.meta.devGateway?.enabled === false ? void 0 : state.app ? resolve28(state.app.dir, "dev/net-mocks.json") : void 0);
40032
+ const netMocksPath = netMocksDisabled ? void 0 : explicitNetMocksPath ?? (state.app?.meta.devGateway?.enabled === false ? void 0 : state.app ? resolve29(state.app.dir, "dev/net-mocks.json") : void 0);
39911
40033
  const resolved2 = netMocksDisabled ? null : resolveNetMocks(
39912
40034
  netMocksPath ? readNetMocksFile(netMocksPath) : null,
39913
40035
  state.app?.meta.devGateway
@@ -39967,7 +40089,7 @@ function createDevServer(opts = {}) {
39967
40089
  const q = new URLSearchParams(url.split("?")[1] ?? "");
39968
40090
  const assetApp = q.get("app") ?? state.appName;
39969
40091
  const assetDir = state.app && assetApp === state.app.name ? state.app.dir : resolveAppDir(assetApp);
39970
- const hit = assetDir ? collectAssets(assetDir).find((a) => assetSha256(readFileSync39(a.path)) === sha) : void 0;
40092
+ const hit = assetDir ? collectAssets(assetDir).find((a) => assetSha256(readFileSync40(a.path)) === sha) : void 0;
39971
40093
  if (!hit && assetDir) {
39972
40094
  const fontBytes = fontFaceBytesBySha(assetDir, sha);
39973
40095
  if (fontBytes) {
@@ -39990,7 +40112,7 @@ function createDevServer(opts = {}) {
39990
40112
  res.end(JSON.stringify({ error: "asset_not_found", app: assetApp, sha }));
39991
40113
  return;
39992
40114
  }
39993
- const bytes2 = readFileSync39(hit.path);
40115
+ const bytes2 = readFileSync40(hit.path);
39994
40116
  res.writeHead(200, {
39995
40117
  "content-type": hit.contentType,
39996
40118
  "content-length": String(bytes2.length),
@@ -40076,8 +40198,8 @@ function createDevServer(opts = {}) {
40076
40198
  }
40077
40199
  if (url === "/v1/schema/screen-descriptor.json" && req.method === "GET") {
40078
40200
  try {
40079
- const schemaPath = resolve28(ROOT6, "core/schema/generated/screen-descriptor.schema.json");
40080
- const body = readFileSync39(schemaPath, "utf8");
40201
+ const schemaPath = resolve29(ROOT6, "core/schema/generated/screen-descriptor.schema.json");
40202
+ const body = readFileSync40(schemaPath, "utf8");
40081
40203
  return send(res, 200, body, {
40082
40204
  "content-type": "application/schema+json; charset=utf-8",
40083
40205
  "cache-control": "no-store",
@@ -40111,7 +40233,7 @@ function createDevServer(opts = {}) {
40111
40233
  try {
40112
40234
  const { parseRevocationsYaml: parseRevocationsYaml2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
40113
40235
  revoked = parseRevocationsYaml2(
40114
- readFileSync39(resolve28(state.app.dir, "revocations.yaml"), "utf8")
40236
+ readFileSync40(resolve29(state.app.dir, "revocations.yaml"), "utf8")
40115
40237
  ).revoked;
40116
40238
  } catch {
40117
40239
  }
@@ -40343,18 +40465,18 @@ var init_src6 = __esm({
40343
40465
  init_src5();
40344
40466
  init_kits();
40345
40467
  init_widgets();
40346
- ROOT6 = resolve28(fileURLToPath17(new URL("../../..", import.meta.url)));
40347
- TIER3_ROOT = resolve28(ROOT6, "core/dev-server/web");
40348
- TIER4_ROOT = resolve28(ROOT6, "core/dev-server/tier4-bundles");
40468
+ ROOT6 = resolve29(fileURLToPath17(new URL("../../..", import.meta.url)));
40469
+ TIER3_ROOT = resolve29(ROOT6, "core/dev-server/web");
40470
+ TIER4_ROOT = resolve29(ROOT6, "core/dev-server/tier4-bundles");
40349
40471
  tier4Verifier = new TierFourVerifier(TIER4_ROOT);
40350
- TIER5_ROOT = resolve28(ROOT6, "core/dev-server/tier5-bundles");
40351
- ACTION_HANDLERS_ROOT = resolve28(ROOT6, "core/dev-server/action-handlers");
40352
- SAMPLES_ROOT = resolve28(ROOT6, "core/dev-server/sdui-samples");
40472
+ TIER5_ROOT = resolve29(ROOT6, "core/dev-server/tier5-bundles");
40473
+ ACTION_HANDLERS_ROOT = resolve29(ROOT6, "core/dev-server/action-handlers");
40474
+ SAMPLES_ROOT = resolve29(ROOT6, "core/dev-server/sdui-samples");
40353
40475
  TELEMETRY_BUFFER_CAP = 1e3;
40354
40476
  overrideHistorySeq = 0;
40355
40477
  CACHE_CONTROL = "max-age=600, stale-while-revalidate=86400";
40356
- TIER5_SRC_ROOT = resolve28(ROOT6, "core/dev-server/tier5-bundles-src");
40357
- HMR_TMP_DIR = resolve28(ROOT6, "node_modules/.cache/himalaya-hmr");
40478
+ TIER5_SRC_ROOT = resolve29(ROOT6, "core/dev-server/tier5-bundles-src");
40479
+ HMR_TMP_DIR = resolve29(ROOT6, "node_modules/.cache/himalaya-hmr");
40358
40480
  appReloadSeq = 0;
40359
40481
  WEBWIX_CLIENT_ID = process.env.DEMO_APP_WIX_CLIENT_ID ?? "4f58d461-c1f5-4a5d-a467-62cc2329e4dd";
40360
40482
  WEBWIX_REDIRECT = "himalaya-demo-app://oauth/callback";
@@ -40719,12 +40841,12 @@ var init_query = __esm({
40719
40841
  });
40720
40842
 
40721
40843
  // ../../core/dev-server/src/crawl-input.ts
40722
- function resolved(v, resolve41) {
40723
- if (typeof v === "string") return v.startsWith("$service:") ? resolve41(v) : v;
40844
+ function resolved(v, resolve42) {
40845
+ if (typeof v === "string") return v.startsWith("$service:") ? resolve42(v) : v;
40724
40846
  if (Array.isArray(v)) {
40725
40847
  const out = v.flatMap((el) => {
40726
40848
  if (typeof el !== "string" || !el.startsWith("$service:")) return [el];
40727
- const r = resolve41(el);
40849
+ const r = resolve42(el);
40728
40850
  return Array.isArray(r) ? r : [r];
40729
40851
  });
40730
40852
  return out;
@@ -40738,9 +40860,9 @@ function hasRowBinding(props) {
40738
40860
  return itemToken(v) || Array.isArray(v) && v.some(itemToken);
40739
40861
  });
40740
40862
  }
40741
- function declaredOptionIds(props, resolve41) {
40863
+ function declaredOptionIds(props, resolve42) {
40742
40864
  const literal = props.options ?? props.tabs ?? props.chips;
40743
- const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve41) : void 0;
40865
+ const bound = props.optionsPath !== void 0 ? resolved(props.optionsPath, resolve42) : void 0;
40744
40866
  const raw = Array.isArray(bound) ? bound : literal;
40745
40867
  if (!Array.isArray(raw)) return [];
40746
40868
  const out = [];
@@ -40783,24 +40905,24 @@ function seedTokens(state, limit = 48) {
40783
40905
  walk2(state, 0);
40784
40906
  return out;
40785
40907
  }
40786
- function synthesizeInput(control, resolve41, tokens) {
40908
+ function synthesizeInput(control, resolve42, tokens) {
40787
40909
  const id = `${control.type}.${control.callback}`;
40788
40910
  const row = SYNTHESIZED_CONTROLS[id];
40789
40911
  if (!row) return null;
40790
40912
  const props = control.props;
40791
40913
  if (hasRowBinding(props)) return null;
40792
40914
  if (row.from === "declared-options") {
40793
- const ids = declaredOptionIds(props, resolve41);
40915
+ const ids = declaredOptionIds(props, resolve42);
40794
40916
  if (!ids.length) return null;
40795
40917
  if (row.encoding === "string-array") {
40796
- const currentRaw2 = resolved(props.selectedIds, resolve41);
40918
+ const currentRaw2 = resolved(props.selectedIds, resolve42);
40797
40919
  const current3 = (Array.isArray(currentRaw2) ? currentRaw2 : []).filter((x) => typeof x === "string");
40798
40920
  const pick4 = ids.find((o) => !current3.includes(o));
40799
40921
  if (pick4 === void 0) return null;
40800
40922
  const value = props.multiSelect === true ? [...current3, pick4] : [pick4];
40801
40923
  return { key: row.key, value, from: row.from, current: current3, control: id };
40802
40924
  }
40803
- const currentRaw = resolved(props.selectedId, resolve41);
40925
+ const currentRaw = resolved(props.selectedId, resolve42);
40804
40926
  const current2 = typeof currentRaw === "string" ? currentRaw : void 0;
40805
40927
  const pick3 = ids.find((o) => o !== current2);
40806
40928
  if (pick3 === void 0) return null;
@@ -40808,7 +40930,7 @@ function synthesizeInput(control, resolve41, tokens) {
40808
40930
  }
40809
40931
  if (!acceptsWords(props) || !acceptsWords(control.wrapper ?? {})) return null;
40810
40932
  const binding2 = typeof props.valuePath === "string" ? props.valuePath : typeof props.value === "string" && props.value.startsWith("$service:") ? props.value : void 0;
40811
- const bound = binding2 === void 0 ? void 0 : resolve41(binding2);
40933
+ const bound = binding2 === void 0 ? void 0 : resolve42(binding2);
40812
40934
  const literal = typeof props.value === "string" && !props.value.startsWith("$") ? props.value : void 0;
40813
40935
  const current = typeof bound === "string" ? bound : typeof bound === "number" ? String(bound) : literal ?? "";
40814
40936
  const max = typeof props.maxLength === "number" && props.maxLength > 0 ? props.maxLength : void 0;
@@ -43025,8 +43147,8 @@ __export(build_exports2, {
43025
43147
  withStoreNavBundle: () => withStoreNavBundle
43026
43148
  });
43027
43149
  import { createHash as createHash18 } from "node:crypto";
43028
- import { readFileSync as readFileSync40, readdirSync as readdirSync18, existsSync as existsSync34 } from "node:fs";
43029
- import { dirname as dirname22, join as join34, resolve as resolve29 } from "node:path";
43150
+ import { readFileSync as readFileSync41, readdirSync as readdirSync18, existsSync as existsSync35 } from "node:fs";
43151
+ import { dirname as dirname23, join as join35, resolve as resolve30 } from "node:path";
43030
43152
  import { fileURLToPath as fileURLToPath18 } from "node:url";
43031
43153
  import { createRequire as createRequire2 } from "node:module";
43032
43154
  import { execFileSync as execFileSync4 } from "node:child_process";
@@ -43048,7 +43170,7 @@ function bundleMapFor(tier5Dir, bundleName) {
43048
43170
  if (!bundleName) return { bundleMap: null };
43049
43171
  const built = readBuiltBundleMap(tier5Dir, bundleName);
43050
43172
  if (built) return { bundleMap: built };
43051
- if (resolve29(tier5Dir) !== TIER5_DIR) return { bundleMap: null };
43173
+ if (resolve30(tier5Dir) !== TIER5_DIR) return { bundleMap: null };
43052
43174
  let r;
43053
43175
  try {
43054
43176
  const { sourcemapForCommittedBundleSync } = requireFromHere(SOURCEMAP_ON_DEMAND_PATH);
@@ -43064,10 +43186,10 @@ function l10nLintOptions(locale, appDir2) {
43064
43186
  const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
43065
43187
  const catalog = /* @__PURE__ */ new Set();
43066
43188
  for (const tag of tags) {
43067
- const path = join34(appDir2, "l10n", `${tag}.json`);
43068
- if (!existsSync34(path)) continue;
43189
+ const path = join35(appDir2, "l10n", `${tag}.json`);
43190
+ if (!existsSync35(path)) continue;
43069
43191
  try {
43070
- const parsed = JSON.parse(readFileSync40(path, "utf8"));
43192
+ const parsed = JSON.parse(readFileSync41(path, "utf8"));
43071
43193
  for (const m of Object.values(parsed.messages ?? {})) {
43072
43194
  if (typeof m?.source === "string" && typeof m.translation === "string" && m.translation.length > 0) {
43073
43195
  catalog.add(m.source);
@@ -43232,7 +43354,7 @@ function shellSha(root = REPO_ROOT7) {
43232
43354
  function isMonorepoCheckout(dir) {
43233
43355
  try {
43234
43356
  const top = execFileSync4("git", ["rev-parse", "--show-toplevel"], { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
43235
- return top.length > 0 && existsSync34(join34(top, "core", "schema", "core.proto"));
43357
+ return top.length > 0 && existsSync35(join35(top, "core", "schema", "core.proto"));
43236
43358
  } catch {
43237
43359
  return false;
43238
43360
  }
@@ -43365,8 +43487,8 @@ async function buildReleaseFromContent(contentDir2, dest, opts = {}) {
43365
43487
  }
43366
43488
  function readTokensForLint(preloaded) {
43367
43489
  try {
43368
- const tokenPath = preloaded.module.designTokensPath ?? resolve29(preloaded.dir, preloaded.module.config.designTokensPath ?? "tokens.json");
43369
- const parsed = JSON.parse(readFileSync40(tokenPath, "utf8"));
43490
+ const tokenPath = preloaded.module.designTokensPath ?? resolve30(preloaded.dir, preloaded.module.config.designTokensPath ?? "tokens.json");
43491
+ const parsed = JSON.parse(readFileSync41(tokenPath, "utf8"));
43370
43492
  delete parsed._meta;
43371
43493
  return parsed;
43372
43494
  } catch {
@@ -43503,7 +43625,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43503
43625
  if (addrCache.has(name)) return addrCache.get(name);
43504
43626
  let bytes2;
43505
43627
  try {
43506
- bytes2 = readFileSync40(join34(tier5Dir, `${name}.bundle.js`));
43628
+ bytes2 = readFileSync41(join35(tier5Dir, `${name}.bundle.js`));
43507
43629
  } catch {
43508
43630
  return null;
43509
43631
  }
@@ -43524,9 +43646,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43524
43646
  const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
43525
43647
  if (store.putDoc) {
43526
43648
  for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
43527
- const path = join34(preloaded.dir, file);
43528
- if (!existsSync34(path)) continue;
43529
- const bytes2 = readFileSync40(path);
43649
+ const path = join35(preloaded.dir, file);
43650
+ if (!existsSync35(path)) continue;
43651
+ const bytes2 = readFileSync41(path);
43530
43652
  if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
43531
43653
  throw new Error(`${file} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
43532
43654
  }
@@ -43541,7 +43663,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43541
43663
  const iconPath = resolveAppDirIcon(preloaded.dir);
43542
43664
  if (iconPath) {
43543
43665
  try {
43544
- const bytes2 = readFileSync40(iconPath);
43666
+ const bytes2 = readFileSync41(iconPath);
43545
43667
  await store.putIcon(app, bytes2);
43546
43668
  iconHash = sha2564(bytes2);
43547
43669
  } catch {
@@ -43563,7 +43685,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43563
43685
  }
43564
43686
  const seenAssetSha = /* @__PURE__ */ new Set();
43565
43687
  for (const a of collected) {
43566
- const bytes2 = readFileSync40(a.path);
43688
+ const bytes2 = readFileSync41(a.path);
43567
43689
  const hash = sha2564(bytes2);
43568
43690
  if (!seenAssetSha.has(hash)) {
43569
43691
  await store.putAsset(app, hash, bytes2, a.contentType);
@@ -43584,7 +43706,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43584
43706
  const canEmitFonts = hasVendoredFloor();
43585
43707
  try {
43586
43708
  const appTokens = readTokensForLint(preloaded) ?? {};
43587
- const policy = existsSync34(join34(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync40(join34(preloaded.dir, "fonts.json"), "utf8")) : {};
43709
+ const policy = existsSync35(join35(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync41(join35(preloaded.dir, "fonts.json"), "utf8")) : {};
43588
43710
  fontPlan = planFonts(appTokens, policy);
43589
43711
  } catch (err) {
43590
43712
  throw new Error(
@@ -43600,7 +43722,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43600
43722
  `[release-build] ${family.name} face ${face.postScriptName} has no local bytes (sha ${face.sha256.slice(0, 12)}\u2026), so the release would declare a face the asset route cannot serve. Run \`npm run fonts:catalog\` to warm the cache before publishing.`
43601
43723
  );
43602
43724
  }
43603
- const bytes2 = readFileSync40(src);
43725
+ const bytes2 = readFileSync41(src);
43604
43726
  const hash = sha2564(bytes2);
43605
43727
  if (hash !== face.sha256) {
43606
43728
  throw new Error(
@@ -43624,7 +43746,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
43624
43746
  if (store.putAsset) {
43625
43747
  for (const face of collectBrandFonts(preloaded.dir)) {
43626
43748
  try {
43627
- const bytes2 = readFileSync40(face.path);
43749
+ const bytes2 = readFileSync41(face.path);
43628
43750
  if (bytes2.length === 0) continue;
43629
43751
  const hash = sha2564(bytes2);
43630
43752
  await store.putAsset(app, hash, bytes2, "font/ttf");
@@ -44046,10 +44168,10 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
44046
44168
  await store.reset(app);
44047
44169
  const sources = {};
44048
44170
  for (const definition of config.functions.functions) {
44049
- const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join34(preloaded.dir, "functions", `${definition.name}${extension}`));
44050
- const source = candidates.find((candidate) => existsSync34(candidate));
44171
+ const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join35(preloaded.dir, "functions", `${definition.name}${extension}`));
44172
+ const source = candidates.find((candidate) => existsSync35(candidate));
44051
44173
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
44052
- sources[definition.name] = readFileSync40(source, "utf8");
44174
+ sources[definition.name] = readFileSync41(source, "utf8");
44053
44175
  }
44054
44176
  const built = await buildFunctions(config.functions.functions, sources);
44055
44177
  const bundles = {};
@@ -44077,7 +44199,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
44077
44199
  return { manifest, failedToBuild: [], missingBundles: [], auth: {} };
44078
44200
  }
44079
44201
  function listBuildableApps() {
44080
- const appsDir = join34(REPO_ROOT7, "apps");
44202
+ const appsDir = join35(REPO_ROOT7, "apps");
44081
44203
  return readdirSync18(appsDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_")).map((d) => d.name);
44082
44204
  }
44083
44205
  var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
@@ -44108,10 +44230,10 @@ var init_build3 = __esm({
44108
44230
  BAKE_OFFLINE_BASE = "http://himalaya-bake.invalid";
44109
44231
  KNOWN_ICON_NAMES = [...ICON_NAMES].sort();
44110
44232
  KNOWN_ICONS = new Set(KNOWN_ICON_NAMES);
44111
- REPO_ROOT7 = resolve29(dirname22(fileURLToPath18(import.meta.url)), "../..");
44112
- TIER5_DIR = join34(REPO_ROOT7, "core/dev-server/tier5-bundles");
44233
+ REPO_ROOT7 = resolve30(dirname23(fileURLToPath18(import.meta.url)), "../..");
44234
+ TIER5_DIR = join35(REPO_ROOT7, "core/dev-server/tier5-bundles");
44113
44235
  requireFromHere = createRequire2(import.meta.url);
44114
- SOURCEMAP_ON_DEMAND_PATH = join34(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
44236
+ SOURCEMAP_ON_DEMAND_PATH = join35(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
44115
44237
  BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
44116
44238
  }
44117
44239
  });
@@ -44288,18 +44410,18 @@ __export(captcha_exports, {
44288
44410
  captchaContentInput: () => captchaContentInput,
44289
44411
  runCaptcha: () => runCaptcha
44290
44412
  });
44291
- import { readFileSync as readFileSync41 } from "node:fs";
44292
- import { resolve as resolve30 } from "node:path";
44413
+ import { readFileSync as readFileSync42 } from "node:fs";
44414
+ import { resolve as resolve31 } from "node:path";
44293
44415
  function readObject(path) {
44294
44416
  try {
44295
- return JSON.parse(readFileSync41(path, "utf8"));
44417
+ return JSON.parse(readFileSync42(path, "utf8"));
44296
44418
  } catch {
44297
44419
  return {};
44298
44420
  }
44299
44421
  }
44300
44422
  function captchaContentInput(dir) {
44301
- const content = readObject(resolve30(dir, "himalaya.content.json"));
44302
- const provisioning = readObject(resolve30(dir, "provisioning.json"));
44423
+ const content = readObject(resolve31(dir, "himalaya.content.json"));
44424
+ const provisioning = readObject(resolve31(dir, "provisioning.json"));
44303
44425
  return {
44304
44426
  app: text(content.name),
44305
44427
  siteId: text(provisioning.siteId),
@@ -44951,8 +45073,8 @@ __export(pack_exports, {
44951
45073
  });
44952
45074
  import { createHash as createHash19 } from "node:crypto";
44953
45075
  import { deflateRawSync, inflateRawSync } from "node:zlib";
44954
- import { existsSync as existsSync35, mkdirSync as mkdirSync17, readFileSync as readFileSync42, readdirSync as readdirSync19, rmSync as rmSync5, statSync as statSync8, writeFileSync as writeFileSync13 } from "node:fs";
44955
- import { dirname as dirname23, join as join35, resolve as resolve31 } from "node:path";
45076
+ import { existsSync as existsSync36, mkdirSync as mkdirSync17, readFileSync as readFileSync43, readdirSync as readdirSync19, rmSync as rmSync5, statSync as statSync7, writeFileSync as writeFileSync13 } from "node:fs";
45077
+ import { dirname as dirname24, join as join36, resolve as resolve32 } from "node:path";
44956
45078
  function writeZip(entries) {
44957
45079
  const sorted = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
44958
45080
  const total = sorted.reduce((n, e) => n + e.bytes.length, 0);
@@ -45046,13 +45168,13 @@ function inflateEntry(buf, entry) {
45046
45168
  return bytes2;
45047
45169
  }
45048
45170
  function readIf(path) {
45049
- return existsSync35(path) && statSync8(path).isFile() ? readFileSync42(path) : null;
45171
+ return existsSync36(path) && statSync7(path).isFile() ? readFileSync43(path) : null;
45050
45172
  }
45051
45173
  function listDir(dir) {
45052
- return existsSync35(dir) ? readdirSync19(dir).filter((f) => statSync8(join35(dir, f)).isFile()) : [];
45174
+ return existsSync36(dir) ? readdirSync19(dir).filter((f) => statSync7(join36(dir, f)).isFile()) : [];
45053
45175
  }
45054
45176
  function gatherReleaseEntries(appDir2) {
45055
- const manifestPath = join35(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
45177
+ const manifestPath = join36(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
45056
45178
  const manifestBytes = readIf(manifestPath);
45057
45179
  if (!manifestBytes) throw new Error(`no ${HIMI_PACKAGE_MANIFEST_PATH} in ${appDir2} \u2014 build a release there first`);
45058
45180
  const manifest = JSON.parse(manifestBytes.toString("utf8"));
@@ -45076,7 +45198,7 @@ function gatherReleaseEntries(appDir2) {
45076
45198
  }
45077
45199
  const missing = [];
45078
45200
  for (const rel of wanted) {
45079
- const bytes2 = readIf(join35(appDir2, rel));
45201
+ const bytes2 = readIf(join36(appDir2, rel));
45080
45202
  if (bytes2) entries.push({ path: rel, bytes: bytes2 });
45081
45203
  else missing.push(rel);
45082
45204
  }
@@ -45087,12 +45209,12 @@ function gatherReleaseEntries(appDir2) {
45087
45209
  );
45088
45210
  }
45089
45211
  for (const name of SINGLETONS) {
45090
- const bytes2 = readIf(join35(appDir2, name));
45212
+ const bytes2 = readIf(join36(appDir2, name));
45091
45213
  if (bytes2) entries.push({ path: name, bytes: bytes2 });
45092
45214
  }
45093
45215
  const skipped = [];
45094
45216
  for (const sub of ["screens", "bundles", "assets", "widgets"]) {
45095
- for (const f of listDir(join35(appDir2, sub))) {
45217
+ for (const f of listDir(join36(appDir2, sub))) {
45096
45218
  if (!wanted.has(`${sub}/${f}`)) skipped.push(`${sub}/${f}`);
45097
45219
  }
45098
45220
  }
@@ -45125,18 +45247,18 @@ function buildEntries(appDir2, app, opts) {
45125
45247
  return { all, header, manifest, skipped };
45126
45248
  }
45127
45249
  function packRelease(releaseRoot, app, out, opts = {}) {
45128
- const appDir2 = join35(resolve31(releaseRoot), app);
45250
+ const appDir2 = join36(resolve32(releaseRoot), app);
45129
45251
  const { all, header, skipped } = buildEntries(appDir2, app, opts);
45130
45252
  const buf = writeZip(all);
45131
- const isDir = existsSync35(out) && statSync8(out).isDirectory();
45132
- const outFile = isDir ? join35(resolve31(out), packageFileName(app, header.releaseId)) : resolve31(out);
45133
- mkdirSync17(dirname23(outFile), { recursive: true });
45253
+ const isDir = existsSync36(out) && statSync7(out).isDirectory();
45254
+ const outFile = isDir ? join36(resolve32(out), packageFileName(app, header.releaseId)) : resolve32(out);
45255
+ mkdirSync17(dirname24(outFile), { recursive: true });
45134
45256
  writeFileSync13(outFile, buf);
45135
45257
  return { app, releaseId: header.releaseId, header, out: outFile, bytes: buf.length, entryCount: all.length, skipped };
45136
45258
  }
45137
45259
  function resolvePackageDirDest(outDir, app, releaseId) {
45138
45260
  const packagedApp = (dir) => {
45139
- const bytes2 = readIf(join35(dir, HIMI_PACKAGE_HEADER_PATH));
45261
+ const bytes2 = readIf(join36(dir, HIMI_PACKAGE_HEADER_PATH));
45140
45262
  if (!bytes2) return void 0;
45141
45263
  try {
45142
45264
  return JSON.parse(bytes2.toString("utf8")).app;
@@ -45145,15 +45267,15 @@ function resolvePackageDirDest(outDir, app, releaseId) {
45145
45267
  }
45146
45268
  };
45147
45269
  const replaceable = (dir) => {
45148
- if (!existsSync35(dir)) return true;
45149
- if (!statSync8(dir).isDirectory()) return false;
45270
+ if (!existsSync36(dir)) return true;
45271
+ if (!statSync7(dir).isDirectory()) return false;
45150
45272
  return readdirSync19(dir).length === 0 || packagedApp(dir) === app;
45151
45273
  };
45152
- if (existsSync35(outDir) && !statSync8(outDir).isDirectory()) {
45274
+ if (existsSync36(outDir) && !statSync7(outDir).isDirectory()) {
45153
45275
  throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
45154
45276
  }
45155
45277
  if (replaceable(outDir)) return outDir;
45156
- const child = join35(outDir, packageDirName(app, releaseId));
45278
+ const child = join36(outDir, packageDirName(app, releaseId));
45157
45279
  if (!replaceable(child)) {
45158
45280
  throw new Error(
45159
45281
  `refusing to replace ${child}: it is not empty and is not a ${app} package (no ${HIMI_PACKAGE_HEADER_PATH}). Pass --out to a new or empty directory.`
@@ -45167,14 +45289,14 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
45167
45289
  "a package carrying the app's source has no --format dir form: readers that predate the source entry drop it before hashing a directory and refuse the package as tampered. Pack it as a .himi archive."
45168
45290
  );
45169
45291
  }
45170
- const appDir2 = join35(resolve31(releaseRoot), app);
45292
+ const appDir2 = join36(resolve32(releaseRoot), app);
45171
45293
  const { all, header, skipped } = buildEntries(appDir2, app, opts);
45172
- const dest = resolvePackageDirDest(resolve31(outDir), app, header.releaseId);
45294
+ const dest = resolvePackageDirDest(resolve32(outDir), app, header.releaseId);
45173
45295
  rmSync5(dest, { recursive: true, force: true });
45174
45296
  let bytes2 = 0;
45175
45297
  for (const entry of all) {
45176
- const target = join35(dest, entry.path);
45177
- mkdirSync17(dirname23(target), { recursive: true });
45298
+ const target = join36(dest, entry.path);
45299
+ mkdirSync17(dirname24(target), { recursive: true });
45178
45300
  writeFileSync13(target, entry.bytes);
45179
45301
  bytes2 += entry.bytes.length;
45180
45302
  }
@@ -45196,21 +45318,21 @@ function openPackageBuffer(buf) {
45196
45318
  return openFromEntries(readZip(buf), { requireHeader: true });
45197
45319
  }
45198
45320
  function openPackageFile(file) {
45199
- return openPackageBuffer(readFileSync42(file));
45321
+ return openPackageBuffer(readFileSync43(file));
45200
45322
  }
45201
45323
  function openPackageDir(dir) {
45202
- const root = resolve31(dir);
45324
+ const root = resolve32(dir);
45203
45325
  const entries = /* @__PURE__ */ new Map();
45204
45326
  const walk2 = (rel) => {
45205
- const abs = rel ? join35(root, rel) : root;
45327
+ const abs = rel ? join36(root, rel) : root;
45206
45328
  for (const name of readdirSync19(abs)) {
45207
45329
  const childRel = rel ? `${rel}/${name}` : name;
45208
- const childAbs = join35(abs, name);
45209
- if (statSync8(childAbs).isDirectory()) walk2(childRel);
45210
- else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync42(childAbs));
45330
+ const childAbs = join36(abs, name);
45331
+ if (statSync7(childAbs).isDirectory()) walk2(childRel);
45332
+ else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync43(childAbs));
45211
45333
  }
45212
45334
  };
45213
- if (!existsSync35(root)) throw new Error(`no such package directory: ${root}`);
45335
+ if (!existsSync36(root)) throw new Error(`no such package directory: ${root}`);
45214
45336
  walk2("");
45215
45337
  const manifestBytes = entries.get(HIMI_PACKAGE_MANIFEST_PATH);
45216
45338
  if (manifestBytes) {
@@ -45251,12 +45373,12 @@ function unpackTo(buf, dest, appFallback) {
45251
45373
  const app = header.app ?? manifest?.app ?? appFallback;
45252
45374
  if (!app) throw new Error("package declares no app id (no himi-package.json and no manifest.app)");
45253
45375
  if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
45254
- const root = resolve31(dest);
45255
- const appDir2 = join35(root, app);
45376
+ const root = resolve32(dest);
45377
+ const appDir2 = join36(root, app);
45256
45378
  rmSync5(appDir2, { recursive: true, force: true });
45257
45379
  for (const [rel, bytes2] of entries) {
45258
- const target = join35(appDir2, rel);
45259
- mkdirSync17(dirname23(target), { recursive: true });
45380
+ const target = join36(appDir2, rel);
45381
+ mkdirSync17(dirname24(target), { recursive: true });
45260
45382
  writeFileSync13(target, bytes2);
45261
45383
  }
45262
45384
  return { root, appDir: appDir2, app };
@@ -45290,19 +45412,19 @@ __export(app_source_exports, {
45290
45412
  writeConflicts: () => writeConflicts,
45291
45413
  zipAppSource: () => zipAppSource
45292
45414
  });
45293
- import { readdirSync as readdirSync20, lstatSync as lstatSync4, readFileSync as readFileSync43, mkdirSync as mkdirSync18, writeFileSync as writeFileSync14, existsSync as existsSync36, rmSync as rmSync6, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
45294
- import { join as join36, resolve as resolve32, sep as sep7 } from "node:path";
45415
+ import { readdirSync as readdirSync20, lstatSync as lstatSync4, readFileSync as readFileSync44, mkdirSync as mkdirSync18, writeFileSync as writeFileSync14, existsSync as existsSync37, rmSync as rmSync6, rmdirSync, unlinkSync as unlinkSync3 } from "node:fs";
45416
+ import { join as join37, resolve as resolve33, sep as sep7 } from "node:path";
45295
45417
  function walkSourceTree(dir, file, skip) {
45296
45418
  const walk2 = (relDir) => {
45297
- for (const name of readdirSync20(join36(dir, relDir))) {
45298
- const rel = relDir ? join36(relDir, name) : name;
45299
- const st = lstatSync4(join36(dir, rel));
45419
+ for (const name of readdirSync20(join37(dir, relDir))) {
45420
+ const rel = relDir ? join37(relDir, name) : name;
45421
+ const st = lstatSync4(join37(dir, rel));
45300
45422
  if (st.isSymbolicLink()) {
45301
45423
  skip(rel);
45302
45424
  continue;
45303
45425
  }
45304
45426
  if (st.isDirectory()) {
45305
- if (isDeniedSourceDir(name) || existsSync36(join36(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
45427
+ if (isDeniedSourceDir(name) || existsSync37(join37(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
45306
45428
  else walk2(rel);
45307
45429
  continue;
45308
45430
  }
@@ -45320,7 +45442,7 @@ function collectAppSource(dir) {
45320
45442
  const skipped = [];
45321
45443
  walkSourceTree(
45322
45444
  dir,
45323
- (archivePath, hostRel) => entries.push({ path: archivePath, bytes: readFileSync43(join36(dir, hostRel)) }),
45445
+ (archivePath, hostRel) => entries.push({ path: archivePath, bytes: readFileSync44(join37(dir, hostRel)) }),
45324
45446
  (hostRel) => skipped.push(hostRel)
45325
45447
  );
45326
45448
  entries.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -45350,7 +45472,7 @@ function pathKind(p) {
45350
45472
  }
45351
45473
  }
45352
45474
  function writeAppSource(entries, destDir) {
45353
- const root = resolve32(destDir);
45475
+ const root = resolve33(destDir);
45354
45476
  if (pathKind(root)?.isSymbolicLink()) {
45355
45477
  throw new Error(
45356
45478
  `refusing to restore into ${root}: the destination itself is a symlink, so every file would be written outside it. Remove it, or pass --out/--name somewhere else.`
@@ -45363,13 +45485,13 @@ function writeAppSource(entries, destDir) {
45363
45485
  const segments = entry.path.split("/");
45364
45486
  let dir = root;
45365
45487
  for (const segment of segments.slice(0, -1)) {
45366
- dir = join36(dir, segment);
45488
+ dir = join37(dir, segment);
45367
45489
  const kind = pathKind(dir);
45368
45490
  if (kind?.isSymbolicLink()) unlinkSync3(dir);
45369
45491
  else if (kind) continue;
45370
45492
  mkdirSync18(dir);
45371
45493
  }
45372
- const target = join36(root, ...segments);
45494
+ const target = join37(root, ...segments);
45373
45495
  if (pathKind(target)?.isSymbolicLink()) unlinkSync3(target);
45374
45496
  writeFileSync14(target, entry.bytes);
45375
45497
  written.push(entry.path);
@@ -45377,7 +45499,7 @@ function writeAppSource(entries, destDir) {
45377
45499
  return written;
45378
45500
  }
45379
45501
  function staleSourcePaths(entries, destDir) {
45380
- if (!existsSync36(destDir)) return [];
45502
+ if (!existsSync37(destDir)) return [];
45381
45503
  const archived = new Set(entries.map((e) => e.path));
45382
45504
  const stale = [];
45383
45505
  walkSourceTree(destDir, (archivePath) => {
@@ -45390,7 +45512,7 @@ function deniedArchivePaths(entries) {
45390
45512
  return entries.filter((e) => isDeniedSourcePath(e.path)).map((e) => e.path).sort();
45391
45513
  }
45392
45514
  function writeConflicts(entries, destDir) {
45393
- const root = resolve32(destDir);
45515
+ const root = resolve33(destDir);
45394
45516
  const conflicts = [];
45395
45517
  const seen = /* @__PURE__ */ new Set();
45396
45518
  const say = (rel, what) => {
@@ -45404,7 +45526,7 @@ function writeConflicts(entries, destDir) {
45404
45526
  let dir = root;
45405
45527
  let stop = false;
45406
45528
  for (const [i, segment] of segments.slice(0, -1).entries()) {
45407
- dir = join36(dir, segment);
45529
+ dir = join37(dir, segment);
45408
45530
  const kind2 = pathKind(dir);
45409
45531
  if (!kind2 || kind2.isSymbolicLink()) {
45410
45532
  stop = true;
@@ -45416,7 +45538,7 @@ function writeConflicts(entries, destDir) {
45416
45538
  break;
45417
45539
  }
45418
45540
  if (stop) continue;
45419
- const kind = pathKind(join36(root, ...segments));
45541
+ const kind = pathKind(join37(root, ...segments));
45420
45542
  if (kind && !kind.isSymbolicLink() && kind.isDirectory()) {
45421
45543
  say(entry.path, "is a directory here, but the release has a file at that path");
45422
45544
  }
@@ -45424,24 +45546,24 @@ function writeConflicts(entries, destDir) {
45424
45546
  return conflicts;
45425
45547
  }
45426
45548
  function removeStaleSource(entries, destDir) {
45427
- const root = resolve32(destDir);
45549
+ const root = resolve33(destDir);
45428
45550
  const removed = staleSourcePaths(entries, root);
45429
- for (const rel of removed) rmSync6(join36(root, ...rel.split("/")), { force: true });
45551
+ for (const rel of removed) rmSync6(join37(root, ...rel.split("/")), { force: true });
45430
45552
  const needed = /* @__PURE__ */ new Set();
45431
45553
  for (const entry of entries) {
45432
45554
  if (isDeniedSourcePath(entry.path)) continue;
45433
45555
  const segments = entry.path.split("/");
45434
45556
  for (let i = 1; i < segments.length; i++) needed.add(segments.slice(0, i).join("/"));
45435
45557
  }
45436
- if (existsSync36(root)) pruneEmptyDirs(root, "", needed, removed);
45558
+ if (existsSync37(root)) pruneEmptyDirs(root, "", needed, removed);
45437
45559
  return removed.sort();
45438
45560
  }
45439
45561
  function pruneEmptyDirs(root, rel, needed, removed) {
45440
45562
  let empty = true;
45441
- for (const name of readdirSync20(rel ? join36(root, rel) : root)) {
45442
- const childRel = rel ? join36(rel, name) : name;
45563
+ for (const name of readdirSync20(rel ? join37(root, rel) : root)) {
45564
+ const childRel = rel ? join37(rel, name) : name;
45443
45565
  const posix3 = childRel.split(sep7).join("/");
45444
- const kind = lstatSync4(join36(root, childRel));
45566
+ const kind = lstatSync4(join37(root, childRel));
45445
45567
  if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name)) {
45446
45568
  empty = false;
45447
45569
  continue;
@@ -45451,7 +45573,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
45451
45573
  empty = false;
45452
45574
  continue;
45453
45575
  }
45454
- rmdirSync(join36(root, childRel));
45576
+ rmdirSync(join37(root, childRel));
45455
45577
  removed.push(`${posix3}/`);
45456
45578
  }
45457
45579
  return empty;
@@ -45479,13 +45601,13 @@ __export(eject_exports, {
45479
45601
  EJECTABLE: () => EJECTABLE,
45480
45602
  ejectModule: () => ejectModule
45481
45603
  });
45482
- import { existsSync as existsSync37, mkdirSync as mkdirSync19, readFileSync as readFileSync44, writeFileSync as writeFileSync15 } from "node:fs";
45483
- import { dirname as dirname24, join as join37, relative as relative4, resolve as resolve33, sep as sep8 } from "node:path";
45604
+ import { existsSync as existsSync38, mkdirSync as mkdirSync19, readFileSync as readFileSync45, writeFileSync as writeFileSync15 } from "node:fs";
45605
+ import { dirname as dirname25, join as join38, relative as relative5, resolve as resolve34, sep as sep8 } from "node:path";
45484
45606
  function locate(repoRootOrCwd, mod) {
45485
- const inRepo = resolve33(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
45486
- if (existsSync37(inRepo)) return { path: inRepo, form: "source" };
45487
- const dist = resolve33(repoRootOrCwd, `node_modules/@wix/himalaya/dist/${mod}.mjs`);
45488
- if (existsSync37(dist)) return { path: dist, form: "bundle" };
45607
+ const inRepo = resolve34(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
45608
+ if (existsSync38(inRepo)) return { path: inRepo, form: "source" };
45609
+ const dist = resolve34(repoRootOrCwd, `node_modules/@wix/himalaya/dist/${mod}.mjs`);
45610
+ if (existsSync38(dist)) return { path: dist, form: "bundle" };
45489
45611
  return null;
45490
45612
  }
45491
45613
  function specifiersFor(mod) {
@@ -45509,8 +45631,8 @@ function ejectModule(opts) {
45509
45631
  };
45510
45632
  }
45511
45633
  const ext = found.form === "source" ? "ts" : "mjs";
45512
- const target = join37(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
45513
- mkdirSync19(dirname24(target), { recursive: true });
45634
+ const target = join38(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
45635
+ mkdirSync19(dirname25(target), { recursive: true });
45514
45636
  const banner = `// EJECTED from @wix/himalaya/${mod}. This app owns this file now.
45515
45637
  //
45516
45638
  // Central fixes to @wix/himalaya/${mod} NO LONGER REACH THIS APP \u2014 including any
@@ -45523,17 +45645,17 @@ function ejectModule(opts) {
45523
45645
  // gate still applies. Ejecting buys layout and flow, never the floor.
45524
45646
 
45525
45647
  `;
45526
- const normalized = readFileSync44(found.path, "utf8").replace(
45648
+ const normalized = readFileSync45(found.path, "utf8").replace(
45527
45649
  /(["'])@himalaya\/([a-z0-9-]+(?:\/[a-z0-9-]+)?)\1/g,
45528
45650
  (_m, q, sub) => `${q}@wix/himalaya/${sub}${q}`
45529
45651
  );
45530
45652
  writeFileSync15(target, banner + normalized);
45531
45653
  const rewired = [];
45532
45654
  for (const f of files) {
45533
- if (!existsSync37(f)) continue;
45534
- const before = readFileSync44(f, "utf8");
45655
+ if (!existsSync38(f)) continue;
45656
+ const before = readFileSync45(f, "utf8");
45535
45657
  let after = before;
45536
- let rel = relative4(dirname24(f), target).split(sep8).join("/").replace(/\.tsx?$/, ".js");
45658
+ let rel = relative5(dirname25(f), target).split(sep8).join("/").replace(/\.tsx?$/, ".js");
45537
45659
  if (!rel.startsWith(".")) rel = `./${rel}`;
45538
45660
  for (const spec of specifiersFor(mod)) {
45539
45661
  const q = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -45579,14 +45701,14 @@ __export(test_exports, {
45579
45701
  scopeDescriptors: () => scopeDescriptors,
45580
45702
  writeRecordedMocks: () => writeRecordedMocks
45581
45703
  });
45582
- import { existsSync as existsSync38, mkdirSync as mkdirSync20, readFileSync as readFileSync45, writeFileSync as writeFileSync16 } from "node:fs";
45583
- import { join as join38, resolve as resolve34 } from "node:path";
45704
+ import { existsSync as existsSync39, mkdirSync as mkdirSync20, readFileSync as readFileSync46, writeFileSync as writeFileSync16 } from "node:fs";
45705
+ import { join as join39, resolve as resolve35 } from "node:path";
45584
45706
  function readTestConfig(dir) {
45585
- const p = resolve34(dir, TEST_CONFIG_FILE);
45586
- if (!existsSync38(p)) return {};
45707
+ const p = resolve35(dir, TEST_CONFIG_FILE);
45708
+ if (!existsSync39(p)) return {};
45587
45709
  let parsed;
45588
45710
  try {
45589
- parsed = JSON.parse(readFileSync45(p, "utf8"));
45711
+ parsed = JSON.parse(readFileSync46(p, "utf8"));
45590
45712
  } catch (e) {
45591
45713
  throw new Error(`${TEST_CONFIG_FILE} is not valid JSON \u2014 ${e.message}`);
45592
45714
  }
@@ -45629,7 +45751,7 @@ function readTestConfig(dir) {
45629
45751
  function readNetRules(path) {
45630
45752
  let parsed;
45631
45753
  try {
45632
- parsed = JSON.parse(readFileSync45(path, "utf8"));
45754
+ parsed = JSON.parse(readFileSync46(path, "utf8"));
45633
45755
  } catch (e) {
45634
45756
  throw new Error(`--net ${path} could not be read as JSON \u2014 ${e.message}`);
45635
45757
  }
@@ -45649,8 +45771,8 @@ function readNetRules(path) {
45649
45771
  }
45650
45772
  function defaultNetRules(dir) {
45651
45773
  for (const rel of ["dev/net-mocks.json", "tests/net-mocks.json"]) {
45652
- const p = resolve34(dir, rel);
45653
- if (existsSync38(p)) {
45774
+ const p = resolve35(dir, rel);
45775
+ if (existsSync39(p)) {
45654
45776
  const rules = readNetRules(p);
45655
45777
  if (rules.length) return { rules, from: rel };
45656
45778
  }
@@ -45666,7 +45788,7 @@ function readCannedResponses() {
45666
45788
  ];
45667
45789
  for (const url of candidates) {
45668
45790
  try {
45669
- const parsed = JSON.parse(readFileSync45(url, "utf8"));
45791
+ const parsed = JSON.parse(readFileSync46(url, "utf8"));
45670
45792
  const byKey = {};
45671
45793
  for (const [k, v] of Object.entries(parsed)) {
45672
45794
  if (!k.startsWith("//")) byKey[k] = v;
@@ -45758,8 +45880,8 @@ function writeRecordedMocks(opts) {
45758
45880
  mkdir: (p) => mkdirSync20(p, { recursive: true }),
45759
45881
  write: (p, s) => writeFileSync16(p, s)
45760
45882
  };
45761
- fs.mkdir(join38(opts.dir, "dev"));
45762
- fs.write(join38(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
45883
+ fs.mkdir(join39(opts.dir, "dev"));
45884
+ fs.write(join39(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
45763
45885
  return { ok: true, rules, to: "dev/net-mocks.json" };
45764
45886
  }
45765
45887
  function scopeDescriptors(descriptors, requestedIds, invalidScreens) {
@@ -45822,7 +45944,7 @@ async function runCrawl(opts) {
45822
45944
  if (list.length > 1) collapsed.push({ representative: rep.screenId, instances: list.length });
45823
45945
  }
45824
45946
  }
45825
- const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve34(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
45947
+ const net = opts.offline ? null : opts.netPath ? { rules: readNetRules(resolve35(opts.netPath)), from: opts.netPath } : defaultNetRules(opts.dir);
45826
45948
  const suppressions = opts.config?.skip ?? [];
45827
45949
  const suppressed = [];
45828
45950
  const matchSuppression = (screen, actionId, componentId, invariant) => suppressions.find((s) => (s.screen === void 0 || s.screen === screen) && (s.action === void 0 || s.action === actionId) && (s.component === void 0 || s.component === componentId) && (s.invariant === void 0 || s.invariant === invariant));
@@ -46216,19 +46338,19 @@ var mobile_ux_lint_exports = {};
46216
46338
  __export(mobile_ux_lint_exports, {
46217
46339
  mobileUxIssues: () => mobileUxIssues
46218
46340
  });
46219
- import { existsSync as existsSync39, readFileSync as readFileSync46 } from "node:fs";
46220
- import { join as join39 } from "node:path";
46341
+ import { existsSync as existsSync40, readFileSync as readFileSync47 } from "node:fs";
46342
+ import { join as join40 } from "node:path";
46221
46343
  function mobileUxIssues(dir, strict) {
46222
- const file = join39(dir, "MOBILE-UX.md");
46223
- if (!existsSync39(file)) return [];
46344
+ const file = join40(dir, "MOBILE-UX.md");
46345
+ if (!existsSync40(file)) return [];
46224
46346
  let text2;
46225
46347
  try {
46226
- text2 = readFileSync46(file, "utf8");
46348
+ text2 = readFileSync47(file, "utf8");
46227
46349
  } catch {
46228
46350
  return [];
46229
46351
  }
46230
46352
  if (!text2) return [];
46231
- return mobileUxMarkerFindings(text2).map((finding) => ({
46353
+ return mobileUxMarkerFindings(text2, recordedRenderWidths(dir)).map((finding) => ({
46232
46354
  screen: null,
46233
46355
  pass: "mobile-ux",
46234
46356
  ruleCode: finding.code,
@@ -46244,6 +46366,7 @@ function mobileUxIssues(dir, strict) {
46244
46366
  var init_mobile_ux_lint = __esm({
46245
46367
  "src/mobile-ux-lint.ts"() {
46246
46368
  init_mobile_ux_contract();
46369
+ init_ux_evidence();
46247
46370
  }
46248
46371
  });
46249
46372
 
@@ -46502,7 +46625,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
46502
46625
  const headers2 = Object.fromEntries(new Headers(init.headers).entries());
46503
46626
  const request = url.protocol === "https:" ? httpsRequest : httpRequest;
46504
46627
  const hostname = url.hostname.replace(/^\[|\]$/g, "");
46505
- return await new Promise((resolve41, reject) => {
46628
+ return await new Promise((resolve42, reject) => {
46506
46629
  let settled = false;
46507
46630
  const finish2 = (fn) => {
46508
46631
  if (settled) return;
@@ -46539,7 +46662,7 @@ async function pinnedFetch(url, init, addresses, maxResponseBytes) {
46539
46662
  }
46540
46663
  const responseHeaders = new Headers();
46541
46664
  for (const [key2, value] of Object.entries(response.headers)) if (value !== void 0) responseHeaders.set(key2, Array.isArray(value) ? value.join(", ") : value);
46542
- resolve41(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
46665
+ resolve42(new Response(bytes2, { status: response.statusCode, statusText: response.statusMessage, headers: responseHeaders }));
46543
46666
  }));
46544
46667
  });
46545
46668
  req.once("error", (error) => finish2(() => reject(error)));
@@ -46839,7 +46962,7 @@ function createLocalTestSandbox() {
46839
46962
  }
46840
46963
  })();
46841
46964
  `;
46842
- return await new Promise((resolve41, reject) => {
46965
+ return await new Promise((resolve42, reject) => {
46843
46966
  const { port1, port2 } = new MessageChannel();
46844
46967
  const serializableContext = {
46845
46968
  auth: context.auth,
@@ -46915,7 +47038,7 @@ function createLocalTestSandbox() {
46915
47038
  timer = setTimeout(() => finish2(() => reject(new SandboxError("timeout", `execution exceeded ${limits.timeoutMs}ms`))), Math.max(1, limits.timeoutMs));
46916
47039
  return;
46917
47040
  }
46918
- if (message.ok) finish2(() => resolve41({ value: message.value, durationMs: Date.now() - started }));
47041
+ if (message.ok) finish2(() => resolve42({ value: message.value, durationMs: Date.now() - started }));
46919
47042
  else finish2(() => reject(new SandboxError("execution_failed", message.message ?? "handler failed")));
46920
47043
  });
46921
47044
  worker.once("error", (error) => finish2(() => reject(new SandboxError("execution_failed", error.message))));
@@ -47882,8 +48005,8 @@ __export(functions_exports, {
47882
48005
  resolveFunctionsTarget: () => resolveFunctionsTarget,
47883
48006
  runRemoteFunctionOperation: () => runRemoteFunctionOperation
47884
48007
  });
47885
- import { readFileSync as readFileSync47, existsSync as existsSync40 } from "node:fs";
47886
- import { join as join40, resolve as resolve35 } from "node:path";
48008
+ import { readFileSync as readFileSync48, existsSync as existsSync41 } from "node:fs";
48009
+ import { join as join41, resolve as resolve36 } from "node:path";
47887
48010
  function resolveFunctionsTarget(input) {
47888
48011
  const explicitUrl = input.functionsUrl?.trim();
47889
48012
  if (explicitUrl) return { mode: "remote", baseUrl: explicitUrl };
@@ -47895,16 +48018,16 @@ function resolveFunctionsTarget(input) {
47895
48018
  return { mode: "local" };
47896
48019
  }
47897
48020
  async function loadFunctionsApp(dir) {
47898
- const loaded = await loadContent(resolve35(dir));
48021
+ const loaded = await loadContent(resolve36(dir));
47899
48022
  const config = loaded.module.config;
47900
48023
  if (config.kind !== "functions" || !Array.isArray(config.functions?.functions)) {
47901
48024
  throw new Error(`content package "${dir}" is not a functions-only app`);
47902
48025
  }
47903
48026
  const sources = {};
47904
48027
  for (const definition of config.functions.functions) {
47905
- const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join40(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync40);
48028
+ const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join41(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync41);
47906
48029
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
47907
- sources[definition.name] = readFileSync47(source, "utf8");
48030
+ sources[definition.name] = readFileSync48(source, "utf8");
47908
48031
  }
47909
48032
  const data = config.cms || config.data ? mergeDataResources(config) : void 0;
47910
48033
  const dataErrors = validateDataResources(data, loaded.name).filter((issue2) => issue2.severity === "error");
@@ -48059,9 +48182,9 @@ __export(native_decode_exports, {
48059
48182
  runNativeDecode: () => runNativeDecode
48060
48183
  });
48061
48184
  import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
48062
- import { existsSync as existsSync41, mkdtempSync as mkdtempSync2, readFileSync as readFileSync48, rmSync as rmSync7, writeFileSync as writeFileSync17 } from "node:fs";
48185
+ import { existsSync as existsSync42, mkdtempSync as mkdtempSync2, readFileSync as readFileSync49, rmSync as rmSync7, writeFileSync as writeFileSync17 } from "node:fs";
48063
48186
  import { tmpdir as tmpdir3 } from "node:os";
48064
- import { join as join41 } from "node:path";
48187
+ import { join as join42 } from "node:path";
48065
48188
  import { fileURLToPath as fileURLToPath19 } from "node:url";
48066
48189
  function nativeDecodePackageDir() {
48067
48190
  return fileURLToPath19(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
@@ -48071,8 +48194,8 @@ function nativeDecodeAndroidHarnessDir() {
48071
48194
  }
48072
48195
  function nativeOracleShipped() {
48073
48196
  return {
48074
- ios: existsSync41(join41(nativeDecodePackageDir(), "Package.swift")),
48075
- android: existsSync41(join41(nativeDecodeAndroidHarnessDir(), "gradlew"))
48197
+ ios: existsSync42(join42(nativeDecodePackageDir(), "Package.swift")),
48198
+ android: existsSync42(join42(nativeDecodeAndroidHarnessDir(), "gradlew"))
48076
48199
  };
48077
48200
  }
48078
48201
  function detectNativeDecode(options = {}) {
@@ -48083,7 +48206,7 @@ function detectNativeDecode(options = {}) {
48083
48206
  return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
48084
48207
  }
48085
48208
  if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
48086
- const packageAvailable = options.packageAvailable ?? existsSync41(join41(packageDir, "Package.swift"));
48209
+ const packageAvailable = options.packageAvailable ?? existsSync42(join42(packageDir, "Package.swift"));
48087
48210
  if (!packageAvailable) {
48088
48211
  return {
48089
48212
  platform: "ios",
@@ -48095,7 +48218,7 @@ function detectNativeDecode(options = {}) {
48095
48218
  }
48096
48219
  function localPropertiesSdk(harnessDir) {
48097
48220
  try {
48098
- const match = readFileSync48(join41(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
48221
+ const match = readFileSync49(join42(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
48099
48222
  return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
48100
48223
  } catch {
48101
48224
  return null;
@@ -48103,8 +48226,8 @@ function localPropertiesSdk(harnessDir) {
48103
48226
  }
48104
48227
  function detectAndroidNativeDecode(options = {}) {
48105
48228
  const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
48106
- const gradlew = join41(harnessDir, "gradlew");
48107
- const gradlewAvailable = options.gradlewAvailable ?? existsSync41(gradlew);
48229
+ const gradlew = join42(harnessDir, "gradlew");
48230
+ const gradlewAvailable = options.gradlewAvailable ?? existsSync42(gradlew);
48108
48231
  if (!gradlewAvailable) {
48109
48232
  return {
48110
48233
  platform: "android",
@@ -48114,7 +48237,7 @@ function detectAndroidNativeDecode(options = {}) {
48114
48237
  }
48115
48238
  const androidHome = options.androidHome ?? process.env.ANDROID_HOME ?? "";
48116
48239
  const sdk = androidHome.trim() || (options.localPropertiesSdk !== void 0 ? options.localPropertiesSdk : localPropertiesSdk(harnessDir));
48117
- const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 && existsSync41(sdk));
48240
+ const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 && existsSync42(sdk));
48118
48241
  if (!sdkAvailable) {
48119
48242
  return {
48120
48243
  platform: "android",
@@ -48186,14 +48309,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
48186
48309
  return verdicts;
48187
48310
  }
48188
48311
  function runNativeDecode(options) {
48189
- const descriptorDir = mkdtempSync2(join41(tmpdir3(), "himi-native-decode-"));
48312
+ const descriptorDir = mkdtempSync2(join42(tmpdir3(), "himi-native-decode-"));
48190
48313
  const startedAt = Date.now();
48191
48314
  try {
48192
48315
  for (const descriptor of options.descriptors) {
48193
48316
  if (typeof descriptor.descriptorJson !== "string") {
48194
48317
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
48195
48318
  }
48196
- writeFileSync17(join41(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48319
+ writeFileSync17(join42(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48197
48320
  }
48198
48321
  options.progress?.("building cached Swift oracle");
48199
48322
  execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
@@ -48205,7 +48328,7 @@ function runNativeDecode(options) {
48205
48328
  encoding: "utf8"
48206
48329
  }).trim();
48207
48330
  options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
48208
- const stdout = execFileSync5(join41(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
48331
+ const stdout = execFileSync5(join42(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
48209
48332
  stdio: ["ignore", "pipe", "pipe"],
48210
48333
  encoding: "utf8"
48211
48334
  });
@@ -48223,15 +48346,15 @@ function runNativeDecode(options) {
48223
48346
  }
48224
48347
  }
48225
48348
  function runAndroidNativeDecode(options) {
48226
- const descriptorDir = mkdtempSync2(join41(tmpdir3(), "himi-native-decode-android-"));
48227
- const outputPath = join41(descriptorDir, "verdicts.ndjson");
48349
+ const descriptorDir = mkdtempSync2(join42(tmpdir3(), "himi-native-decode-android-"));
48350
+ const outputPath = join42(descriptorDir, "verdicts.ndjson");
48228
48351
  const startedAt = Date.now();
48229
48352
  try {
48230
48353
  for (const descriptor of options.descriptors) {
48231
48354
  if (typeof descriptor.descriptorJson !== "string") {
48232
48355
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
48233
48356
  }
48234
- writeFileSync17(join41(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48357
+ writeFileSync17(join42(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48235
48358
  }
48236
48359
  options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
48237
48360
  execFileSync5(options.gradlew, [
@@ -48246,7 +48369,7 @@ function runAndroidNativeDecode(options) {
48246
48369
  stdio: ["ignore", "ignore", "pipe"],
48247
48370
  encoding: "utf8"
48248
48371
  });
48249
- const stdout = readFileSync48(outputPath, "utf8");
48372
+ const stdout = readFileSync49(outputPath, "utf8");
48250
48373
  return {
48251
48374
  platform: "android",
48252
48375
  verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
@@ -48317,13 +48440,13 @@ __export(browser_authoring_exports, {
48317
48440
  import { createServer as createServer3 } from "node:http";
48318
48441
  import { createHash as createHash22, randomBytes as randomBytes5 } from "node:crypto";
48319
48442
  import { execFile as execFile2 } from "node:child_process";
48320
- import { existsSync as existsSync42, readdirSync as readdirSync21, readFileSync as readFileSync49, realpathSync as realpathSync4, statSync as statSync9 } from "node:fs";
48321
- import { join as join42, posix, relative as relative5, sep as sep9 } from "node:path";
48443
+ import { existsSync as existsSync43, readdirSync as readdirSync21, readFileSync as readFileSync50, realpathSync as realpathSync4, statSync as statSync8 } from "node:fs";
48444
+ import { join as join43, posix, relative as relative6, sep as sep9 } from "node:path";
48322
48445
  function humanMs(ms) {
48323
48446
  return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
48324
48447
  }
48325
48448
  function collectWorkerSources(tier5SrcDir, bundleName) {
48326
- const root = join42(tier5SrcDir, bundleName);
48449
+ const root = join43(tier5SrcDir, bundleName);
48327
48450
  const files = {};
48328
48451
  const visitedDirs = /* @__PURE__ */ new Set();
48329
48452
  const walk2 = (abs, rel) => {
@@ -48331,16 +48454,16 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
48331
48454
  if (visitedDirs.has(real)) return;
48332
48455
  visitedDirs.add(real);
48333
48456
  for (const name of readdirSync21(abs).sort()) {
48334
- const childAbs = join42(abs, name);
48457
+ const childAbs = join43(abs, name);
48335
48458
  const childRel = posix.join(rel, name);
48336
- if (statSync9(childAbs).isDirectory()) {
48459
+ if (statSync8(childAbs).isDirectory()) {
48337
48460
  walk2(childAbs, childRel);
48338
48461
  } else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
48339
- files[childRel] = readFileSync49(childAbs, "utf8");
48462
+ files[childRel] = readFileSync50(childAbs, "utf8");
48340
48463
  }
48341
48464
  }
48342
48465
  };
48343
- if (!existsSync42(root)) return null;
48466
+ if (!existsSync43(root)) return null;
48344
48467
  walk2(root, `/tier5-src/${bundleName}`);
48345
48468
  const entry = [`/tier5-src/${bundleName}/index.ts`, `/tier5-src/${bundleName}/index.js`].find((p) => p in files);
48346
48469
  if (!entry) return null;
@@ -48357,20 +48480,20 @@ function collectRelativeSiblings(files, tier5SrcDir) {
48357
48480
  const spec = m[1];
48358
48481
  const virtual = posix.normalize(posix.join(dir, spec));
48359
48482
  if (!virtual.startsWith("/tier5-src/")) continue;
48360
- const onDisk = join42(tier5SrcDir, virtual.slice("/tier5-src/".length));
48483
+ const onDisk = join43(tier5SrcDir, virtual.slice("/tier5-src/".length));
48361
48484
  const candidates = [
48362
48485
  onDisk,
48363
48486
  `${onDisk}.ts`,
48364
48487
  `${onDisk}.js`,
48365
48488
  onDisk.replace(/\.js$/, ".ts"),
48366
- join42(onDisk, "index.ts"),
48367
- join42(onDisk, "index.js")
48489
+ join43(onDisk, "index.ts"),
48490
+ join43(onDisk, "index.js")
48368
48491
  ];
48369
48492
  for (const abs of candidates) {
48370
- if (!existsSync42(abs) || statSync9(abs).isDirectory()) continue;
48371
- const key2 = `/tier5-src/${relative5(tier5SrcDir, abs).split(sep9).join(posix.sep)}`;
48493
+ if (!existsSync43(abs) || statSync8(abs).isDirectory()) continue;
48494
+ const key2 = `/tier5-src/${relative6(tier5SrcDir, abs).split(sep9).join(posix.sep)}`;
48372
48495
  if (key2 in files) break;
48373
- files[key2] = readFileSync49(abs, "utf8");
48496
+ files[key2] = readFileSync50(abs, "utf8");
48374
48497
  queue.push(key2);
48375
48498
  break;
48376
48499
  }
@@ -48402,10 +48525,10 @@ function collectSdkModules(files, resolveSubpath) {
48402
48525
  for (const source of Object.values(files)) visit(source);
48403
48526
  return { modules, unsupported };
48404
48527
  }
48405
- function sdkSubpathReader(resolve41) {
48528
+ function sdkSubpathReader(resolve42) {
48406
48529
  return (sub) => {
48407
48530
  try {
48408
- return readFileSync49(resolve41(`@wix/himalaya/${sub}`), "utf8");
48531
+ return readFileSync50(resolve42(`@wix/himalaya/${sub}`), "utf8");
48409
48532
  } catch {
48410
48533
  return null;
48411
48534
  }
@@ -48486,7 +48609,7 @@ async function runBrowserAuthoring(opts) {
48486
48609
  const token = mintToken2(payload);
48487
48610
  const unusable = await probeAuthoringPage(opts.authoringBase, opts.fetchImpl, opts.probeTimeoutMs);
48488
48611
  if (unusable) throw new Error(unusable);
48489
- return await new Promise((resolve41, reject) => {
48612
+ return await new Promise((resolve42, reject) => {
48490
48613
  let settled = false;
48491
48614
  let url = "";
48492
48615
  const server = createServer3();
@@ -48538,7 +48661,7 @@ async function runBrowserAuthoring(opts) {
48538
48661
  }
48539
48662
  res.writeHead(200, { "content-type": "text/plain" }).end("ok");
48540
48663
  const report = body.result;
48541
- finish2(() => resolve41({ report, url }));
48664
+ finish2(() => resolve42({ report, url }));
48542
48665
  })();
48543
48666
  });
48544
48667
  server.on("error", (e) => finish2(() => reject(e)));
@@ -48579,8 +48702,8 @@ __export(coverage_exports, {
48579
48702
  suppressedNativeKeys: () => suppressedNativeKeys,
48580
48703
  trendAndStore: () => trendAndStore
48581
48704
  });
48582
- import { existsSync as existsSync43, mkdirSync as mkdirSync21, readFileSync as readFileSync50, writeFileSync as writeFileSync18 } from "node:fs";
48583
- import { dirname as dirname25, join as join43 } from "node:path";
48705
+ import { existsSync as existsSync44, mkdirSync as mkdirSync21, readFileSync as readFileSync51, writeFileSync as writeFileSync18 } from "node:fs";
48706
+ import { dirname as dirname26, join as join44 } from "node:path";
48584
48707
  function suppressedNativeKeys(oracle) {
48585
48708
  return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
48586
48709
  }
@@ -48750,11 +48873,11 @@ function assembleLedger(r, options = {}) {
48750
48873
  return out;
48751
48874
  }
48752
48875
  function trendAndStore(dir, entries, suppressed) {
48753
- const p = join43(dir, LEDGER_FILE);
48876
+ const p = join44(dir, LEDGER_FILE);
48754
48877
  let previous = null;
48755
48878
  try {
48756
- if (existsSync43(p)) {
48757
- const parsed = JSON.parse(readFileSync50(p, "utf8"));
48879
+ if (existsSync44(p)) {
48880
+ const parsed = JSON.parse(readFileSync51(p, "utf8"));
48758
48881
  if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k) => typeof k === "string");
48759
48882
  }
48760
48883
  } catch {
@@ -48762,7 +48885,7 @@ function trendAndStore(dir, entries, suppressed) {
48762
48885
  const current = entries.map((e) => e.key);
48763
48886
  const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key2) => (suppressed ?? []).includes(key2))])];
48764
48887
  try {
48765
- mkdirSync21(dirname25(p), { recursive: true });
48888
+ mkdirSync21(dirname26(p), { recursive: true });
48766
48889
  writeFileSync18(p, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
48767
48890
  } catch {
48768
48891
  return null;
@@ -48793,11 +48916,11 @@ function formatLedger(entries, trend) {
48793
48916
  return out.join("\n");
48794
48917
  }
48795
48918
  function diffAndStoreObservations(dir, current) {
48796
- const p = join43(dir, OBS_FILE);
48919
+ const p = join44(dir, OBS_FILE);
48797
48920
  let previous = null;
48798
48921
  try {
48799
- if (existsSync43(p)) {
48800
- const parsed = JSON.parse(readFileSync50(p, "utf8"));
48922
+ if (existsSync44(p)) {
48923
+ const parsed = JSON.parse(readFileSync51(p, "utf8"));
48801
48924
  if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
48802
48925
  (v) => Array.isArray(v) && v.every((l) => typeof l === "string")
48803
48926
  )) {
@@ -48807,7 +48930,7 @@ function diffAndStoreObservations(dir, current) {
48807
48930
  } catch {
48808
48931
  }
48809
48932
  try {
48810
- mkdirSync21(dirname25(p), { recursive: true });
48933
+ mkdirSync21(dirname26(p), { recursive: true });
48811
48934
  writeFileSync18(p, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
48812
48935
  } catch {
48813
48936
  return null;
@@ -48846,8 +48969,8 @@ var LEDGER_FILE, OBS_FILE;
48846
48969
  var init_coverage = __esm({
48847
48970
  "src/coverage.ts"() {
48848
48971
  init_native_decode();
48849
- LEDGER_FILE = join43(".himi", "test-ledger.json");
48850
- OBS_FILE = join43(".himi", "test-observations.json");
48972
+ LEDGER_FILE = join44(".himi", "test-ledger.json");
48973
+ OBS_FILE = join44(".himi", "test-observations.json");
48851
48974
  }
48852
48975
  });
48853
48976
 
@@ -48860,11 +48983,11 @@ __export(assets_exports, {
48860
48983
  removeAssetPayload: () => removeAssetPayload,
48861
48984
  verifyReport: () => verifyReport
48862
48985
  });
48863
- import { readFileSync as readFileSync51 } from "node:fs";
48986
+ import { readFileSync as readFileSync52 } from "node:fs";
48864
48987
  import { basename as basename8 } from "node:path";
48865
48988
  function declaredAssets(dir) {
48866
48989
  return collectAssets(dir).map((a) => {
48867
- const bytes2 = readFileSync51(a.path);
48990
+ const bytes2 = readFileSync52(a.path);
48868
48991
  return {
48869
48992
  name: a.name,
48870
48993
  sha256: assetSha256(bytes2),
@@ -48940,7 +49063,7 @@ function verifyReport(dir, app, manifest) {
48940
49063
  };
48941
49064
  }
48942
49065
  function addAssetPayload(manifest, filePath, opts) {
48943
- const bytes2 = readFileSync51(filePath);
49066
+ const bytes2 = readFileSync52(filePath);
48944
49067
  const name = opts.name ?? basename8(filePath);
48945
49068
  const sha2565 = assetSha256(bytes2);
48946
49069
  const record2 = {
@@ -50354,9 +50477,9 @@ __export(run_exports, {
50354
50477
  runPackage: () => runPackage,
50355
50478
  withoutProdServe: () => withoutProdServe
50356
50479
  });
50357
- import { cpSync, existsSync as existsSync44, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync3, readFileSync as readFileSync52, rmSync as rmSync8, statSync as statSync10 } from "node:fs";
50480
+ import { cpSync, existsSync as existsSync45, mkdirSync as mkdirSync22, mkdtempSync as mkdtempSync3, readFileSync as readFileSync53, rmSync as rmSync8, statSync as statSync9 } from "node:fs";
50358
50481
  import { tmpdir as tmpdir4 } from "node:os";
50359
- import { join as join44 } from "node:path";
50482
+ import { join as join45 } from "node:path";
50360
50483
  import { spawn as spawn3 } from "node:child_process";
50361
50484
  function makePackageRunHandler(opts) {
50362
50485
  return makeRunHandler({
@@ -50374,9 +50497,9 @@ async function fetchBytes(url) {
50374
50497
  }
50375
50498
  async function resolvePackage(source, workDir) {
50376
50499
  const isUrl2 = /^https?:\/\//i.test(source);
50377
- if (!isUrl2 && existsSync44(source) && statSync10(source).isDirectory()) {
50378
- const appDirManifest = join44(source, "release-manifest.json");
50379
- if (existsSync44(appDirManifest)) {
50500
+ if (!isUrl2 && existsSync45(source) && statSync9(source).isDirectory()) {
50501
+ const appDirManifest = join45(source, "release-manifest.json");
50502
+ if (existsSync45(appDirManifest)) {
50380
50503
  const opened2 = openPackageDir(source);
50381
50504
  if (!opened2.validation.ok) {
50382
50505
  throw new Error(`package is not valid:
@@ -50385,9 +50508,9 @@ async function resolvePackage(source, workDir) {
50385
50508
  const app2 = opened2.header?.app ?? opened2.manifest?.app;
50386
50509
  if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
50387
50510
  if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
50388
- const root2 = workDir ?? mkdtempSync3(join44(tmpdir4(), "himi-run-"));
50389
- const target = join44(root2, app2);
50390
- if (join44(source) !== target) {
50511
+ const root2 = workDir ?? mkdtempSync3(join45(tmpdir4(), "himi-run-"));
50512
+ const target = join45(root2, app2);
50513
+ if (join45(source) !== target) {
50391
50514
  mkdirSync22(root2, { recursive: true });
50392
50515
  rmSync8(target, { recursive: true, force: true });
50393
50516
  cpSync(source, target, { recursive: true });
@@ -50404,8 +50527,8 @@ async function resolvePackage(source, workDir) {
50404
50527
  }
50405
50528
  throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
50406
50529
  }
50407
- const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync52(source);
50408
- const root = workDir ?? mkdtempSync3(join44(tmpdir4(), "himi-run-"));
50530
+ const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync53(source);
50531
+ const root = workDir ?? mkdtempSync3(join45(tmpdir4(), "himi-run-"));
50409
50532
  const { app, appDir: appDir2 } = unpackTo(bytes2, root);
50410
50533
  const opened = openPackageDir(appDir2);
50411
50534
  if (!opened.validation.ok) {
@@ -50505,19 +50628,19 @@ __export(run_browser_exports, {
50505
50628
  runInBrowser: () => runInBrowser
50506
50629
  });
50507
50630
  import { createServer as createServer5 } from "node:http";
50508
- import { existsSync as existsSync45, readFileSync as readFileSync53 } from "node:fs";
50631
+ import { existsSync as existsSync46, readFileSync as readFileSync54 } from "node:fs";
50509
50632
  import { spawnSync as spawnSync3, execFile as execFile3 } from "node:child_process";
50510
- import { dirname as dirname26, resolve as resolve36 } from "node:path";
50633
+ import { dirname as dirname27, resolve as resolve37 } from "node:path";
50511
50634
  import { fileURLToPath as fileURLToPath20 } from "node:url";
50512
50635
  function stagedDir() {
50513
- return process.env.HIMI_BROWSER_PLANE_OUT ? resolve36(process.env.HIMI_BROWSER_PLANE_OUT) : resolve36(REPO, "packages", "serve", "dist", "browser-plane");
50636
+ return process.env.HIMI_BROWSER_PLANE_OUT ? resolve37(process.env.HIMI_BROWSER_PLANE_OUT) : resolve37(REPO, "packages", "serve", "dist", "browser-plane");
50514
50637
  }
50515
50638
  function missingStaged() {
50516
- return [...SERVED].filter((f) => !existsSync45(resolve36(stagedDir(), f))).sort();
50639
+ return [...SERVED].filter((f) => !existsSync46(resolve37(stagedDir(), f))).sort();
50517
50640
  }
50518
50641
  function ensureBrowserPlaneStaged() {
50519
50642
  if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
50520
- const r = spawnSync3(process.execPath, [resolve36(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
50643
+ const r = spawnSync3(process.execPath, [resolve37(REPO, "core/serve/scripts/stage-browser-plane.mjs")], {
50521
50644
  cwd: REPO,
50522
50645
  encoding: "utf8"
50523
50646
  });
@@ -50603,7 +50726,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
50603
50726
  }
50604
50727
  const name = path === "/" || path === "/index.html" ? "host.html" : path.slice(1);
50605
50728
  if (SERVED.has(name)) {
50606
- if (!existsSync45(resolve36(stagedDir(), name))) {
50729
+ if (!existsSync46(resolve37(stagedDir(), name))) {
50607
50730
  const restaged = ensureBrowserPlaneStaged();
50608
50731
  if (!restaged.ok) {
50609
50732
  res.writeHead(503, { "content-type": "application/json" });
@@ -50613,7 +50736,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
50613
50736
  }
50614
50737
  let bytes2;
50615
50738
  try {
50616
- bytes2 = readFileSync53(resolve36(stagedDir(), name));
50739
+ bytes2 = readFileSync54(resolve37(stagedDir(), name));
50617
50740
  } catch (e) {
50618
50741
  res.writeHead(503, { "content-type": "application/json" });
50619
50742
  res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
@@ -50656,8 +50779,8 @@ var HERE, REPO, SERVED;
50656
50779
  var init_run_browser = __esm({
50657
50780
  "src/run-browser.ts"() {
50658
50781
  init_file_store();
50659
- HERE = dirname26(fileURLToPath20(import.meta.url));
50660
- REPO = resolve36(HERE, "..", "..", "..");
50782
+ HERE = dirname27(fileURLToPath20(import.meta.url));
50783
+ REPO = resolve37(HERE, "..", "..", "..");
50661
50784
  SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
50662
50785
  }
50663
50786
  });
@@ -51031,11 +51154,11 @@ __export(preflight_exports, {
51031
51154
  parseStoreConfig: () => parseStoreConfig,
51032
51155
  requireEnv: () => requireEnv
51033
51156
  });
51034
- import { existsSync as existsSync46, readFileSync as readFileSync54 } from "node:fs";
51035
- import { isAbsolute as isAbsolute2, relative as relative6, resolve as resolve37 } from "node:path";
51157
+ import { existsSync as existsSync47, readFileSync as readFileSync55 } from "node:fs";
51158
+ import { isAbsolute as isAbsolute3, relative as relative7, resolve as resolve38 } from "node:path";
51036
51159
  function isInsideRepo(p) {
51037
- const rel = relative6(REPO_ROOT3, resolve37(p));
51038
- return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
51160
+ const rel = relative7(REPO_ROOT3, resolve38(p));
51161
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
51039
51162
  }
51040
51163
  function assertCredentialOutsideRepo(label2, p) {
51041
51164
  if (isInsideRepo(p)) {
@@ -51088,10 +51211,10 @@ function parseStoreConfig(text2) {
51088
51211
  }
51089
51212
  function loadStoreConfig(app) {
51090
51213
  const p = storeConfigPath(app);
51091
- if (!existsSync46(p)) {
51214
+ if (!existsSync47(p)) {
51092
51215
  throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
51093
51216
  }
51094
- return parseStoreConfig(readFileSync54(p, "utf8"));
51217
+ return parseStoreConfig(readFileSync55(p, "utf8"));
51095
51218
  }
51096
51219
  var init_preflight = __esm({
51097
51220
  "../store-release/preflight.ts"() {
@@ -51114,9 +51237,9 @@ __export(preflight_app_exports, {
51114
51237
  pngSize: () => pngSize,
51115
51238
  preflightApp: () => preflightApp
51116
51239
  });
51117
- import { readFileSync as readFileSync55, existsSync as existsSync47, readdirSync as readdirSync22, statSync as statSync11 } from "node:fs";
51240
+ import { readFileSync as readFileSync56, existsSync as existsSync48, readdirSync as readdirSync22, statSync as statSync10 } from "node:fs";
51118
51241
  import { createHash as createHash23 } from "node:crypto";
51119
- import { join as join45 } from "node:path";
51242
+ import { join as join46 } from "node:path";
51120
51243
  function analyze(projectYml, storeConfig, icon) {
51121
51244
  const f = [];
51122
51245
  const has = (re, s) => re.test(s);
@@ -51164,10 +51287,10 @@ function analyze(projectYml, storeConfig, icon) {
51164
51287
  return f;
51165
51288
  }
51166
51289
  async function preflightApp(app) {
51167
- const projectYml = existsSync47(iosProjectYml(app)) ? readFileSync55(iosProjectYml(app), "utf8") : "";
51168
- const storeConfig = existsSync47(storeConfigPath(app)) ? readFileSync55(storeConfigPath(app), "utf8") : "";
51290
+ const projectYml = existsSync48(iosProjectYml(app)) ? readFileSync56(iosProjectYml(app), "utf8") : "";
51291
+ const storeConfig = existsSync48(storeConfigPath(app)) ? readFileSync56(storeConfigPath(app), "utf8") : "";
51169
51292
  if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
51170
- const findings = analyze(projectYml, storeConfig, await appIconState(join45(appDir(app), "ios")));
51293
+ const findings = analyze(projectYml, storeConfig, await appIconState(join46(appDir(app), "ios")));
51171
51294
  findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
51172
51295
  findings.push(
51173
51296
  ...analyzePlayListing(playListingAssets(app)).map((finding) => ({ ...finding, level: "warn" }))
@@ -51194,17 +51317,17 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
51194
51317
  return f;
51195
51318
  }
51196
51319
  function appLevelMetadataFiles(app, locale = "en-US") {
51197
- const root = join45(storeDir(app), "metadata");
51320
+ const root = join46(storeDir(app), "metadata");
51198
51321
  const out = /* @__PURE__ */ new Set();
51199
- if (existsSync47(root)) {
51322
+ if (existsSync48(root)) {
51200
51323
  for (const n of readdirSync22(root)) if (n.endsWith(".txt")) out.add(n);
51201
51324
  }
51202
- if (existsSync47(join45(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
51325
+ if (existsSync48(join46(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
51203
51326
  return out;
51204
51327
  }
51205
51328
  function reviewInfoFiles(app) {
51206
- const dir = join45(storeDir(app), "review_information");
51207
- if (!existsSync47(dir)) return /* @__PURE__ */ new Set();
51329
+ const dir = join46(storeDir(app), "review_information");
51330
+ if (!existsSync48(dir)) return /* @__PURE__ */ new Set();
51208
51331
  return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
51209
51332
  }
51210
51333
  function isValidAppStoreSize(w, h) {
@@ -51314,12 +51437,12 @@ function analyzePlayListing(assets) {
51314
51437
  return f;
51315
51438
  }
51316
51439
  function playListingAssets(app, locale = "en-US") {
51317
- const dir = join45(storeDir(app), "play", locale, "images");
51440
+ const dir = join46(storeDir(app), "play", locale, "images");
51318
51441
  const read = (names) => {
51319
51442
  for (const name of names) {
51320
- const p = join45(dir, name);
51443
+ const p = join46(dir, name);
51321
51444
  try {
51322
- if (statSync11(p).isFile()) return { name, bytes: readFileSync55(p) };
51445
+ if (statSync10(p).isFile()) return { name, bytes: readFileSync56(p) };
51323
51446
  } catch {
51324
51447
  }
51325
51448
  }
@@ -51350,26 +51473,26 @@ function analyzeListing(metaFiles, shots) {
51350
51473
  return f;
51351
51474
  }
51352
51475
  function metadataFilesPresent(app, locale = "en-US") {
51353
- const dir = join45(storeDir(app), "metadata", locale);
51354
- if (!existsSync47(dir)) return /* @__PURE__ */ new Set();
51476
+ const dir = join46(storeDir(app), "metadata", locale);
51477
+ if (!existsSync48(dir)) return /* @__PURE__ */ new Set();
51355
51478
  return new Set(readdirSync22(dir).filter((n) => n.endsWith(".txt")));
51356
51479
  }
51357
51480
  function listScreenshots(app, locale = "en-US") {
51358
51481
  const out = [];
51359
- const flat = join45(storeDir(app), "screenshots", locale);
51360
- if (existsSync47(flat)) {
51482
+ const flat = join46(storeDir(app), "screenshots", locale);
51483
+ if (existsSync48(flat)) {
51361
51484
  for (const png of readdirSync22(flat).filter((n) => n.endsWith(".png"))) {
51362
- const sz = pngSize(readFileSync55(join45(flat, png)));
51485
+ const sz = pngSize(readFileSync56(join46(flat, png)));
51363
51486
  if (sz) out.push({ name: png, w: sz.w, h: sz.h });
51364
51487
  }
51365
51488
  }
51366
- const legacy = join45(storeDir(app), "metadata", locale, "screenshots");
51367
- if (existsSync47(legacy)) {
51489
+ const legacy = join46(storeDir(app), "metadata", locale, "screenshots");
51490
+ if (existsSync48(legacy)) {
51368
51491
  for (const deviceDir of readdirSync22(legacy)) {
51369
- const d = join45(legacy, deviceDir);
51370
- if (!statSync11(d).isDirectory()) continue;
51492
+ const d = join46(legacy, deviceDir);
51493
+ if (!statSync10(d).isDirectory()) continue;
51371
51494
  for (const png of readdirSync22(d).filter((n) => n.endsWith(".png"))) {
51372
- const sz = pngSize(readFileSync55(join45(d, png)));
51495
+ const sz = pngSize(readFileSync56(join46(d, png)));
51373
51496
  if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
51374
51497
  }
51375
51498
  }
@@ -51377,13 +51500,13 @@ function listScreenshots(app, locale = "en-US") {
51377
51500
  return out;
51378
51501
  }
51379
51502
  function placeholderHashes2() {
51380
- const templateIos = join45(appDir("_template"), "ios");
51381
- if (!existsSync47(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
51503
+ const templateIos = join46(appDir("_template"), "ios");
51504
+ if (!existsSync48(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
51382
51505
  for (const target of readdirSync22(templateIos)) {
51383
- const p = join45(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
51506
+ const p = join46(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
51384
51507
  try {
51385
- if (!statSync11(p).isFile()) continue;
51386
- return [LEGACY_PLACEHOLDER_SHA2562, createHash23("sha256").update(readFileSync55(p)).digest("hex")];
51508
+ if (!statSync10(p).isFile()) continue;
51509
+ return [LEGACY_PLACEHOLDER_SHA2562, createHash23("sha256").update(readFileSync56(p)).digest("hex")];
51387
51510
  } catch {
51388
51511
  }
51389
51512
  }
@@ -51414,12 +51537,12 @@ async function pixelIssues(bytes2) {
51414
51537
  }
51415
51538
  }
51416
51539
  async function appIconState(iosDir) {
51417
- if (!existsSync47(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
51540
+ if (!existsSync48(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
51418
51541
  for (const target of readdirSync22(iosDir)) {
51419
- const p = join45(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
51542
+ const p = join46(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
51420
51543
  try {
51421
- if (!statSync11(p).isFile()) continue;
51422
- const bytes2 = readFileSync55(p);
51544
+ if (!statSync10(p).isFile()) continue;
51545
+ const bytes2 = readFileSync56(p);
51423
51546
  const hash = createHash23("sha256").update(bytes2).digest("hex");
51424
51547
  const pixels = await pixelIssues(bytes2);
51425
51548
  return {
@@ -51489,14 +51612,14 @@ __export(credential_profile_exports, {
51489
51612
  profilePath: () => profilePath,
51490
51613
  resolveStoreCredentials: () => resolveStoreCredentials
51491
51614
  });
51492
- import { existsSync as existsSync48, readFileSync as readFileSync56 } from "node:fs";
51615
+ import { existsSync as existsSync49, readFileSync as readFileSync57 } from "node:fs";
51493
51616
  import { homedir as homedir6 } from "node:os";
51494
- import { join as join46 } from "node:path";
51617
+ import { join as join47 } from "node:path";
51495
51618
  function credentialsDir(home = homedir6()) {
51496
- return join46(home, ".himalaya", "store-credentials");
51619
+ return join47(home, ".himalaya", "store-credentials");
51497
51620
  }
51498
51621
  function profilePath(name, home = homedir6()) {
51499
- return join46(credentialsDir(home), `${name}.json`);
51622
+ return join47(credentialsDir(home), `${name}.json`);
51500
51623
  }
51501
51624
  function parseProfile(text2, label2) {
51502
51625
  let doc;
@@ -51523,8 +51646,8 @@ function resolveStoreCredentials(opts) {
51523
51646
  const { app, cfg } = opts;
51524
51647
  const env = opts.env ?? process.env;
51525
51648
  const home = opts.home ?? homedir6();
51526
- const read = opts.readProfile ?? ((p) => readFileSync56(p, "utf8"));
51527
- const exists = opts.profileExists ?? existsSync48;
51649
+ const read = opts.readProfile ?? ((p) => readFileSync57(p, "utf8"));
51650
+ const exists = opts.profileExists ?? existsSync49;
51528
51651
  const ios = cfg.ios ?? {};
51529
51652
  const flagName = opts.profileFlag?.trim();
51530
51653
  const named = flagName || ios.credentialProfile?.trim();
@@ -51598,7 +51721,7 @@ __export(version_exports, {
51598
51721
  setAndroidVersion: () => setAndroidVersion,
51599
51722
  setIosVersion: () => setIosVersion
51600
51723
  });
51601
- import { readFileSync as readFileSync57, writeFileSync as writeFileSync19 } from "node:fs";
51724
+ import { readFileSync as readFileSync58, writeFileSync as writeFileSync19 } from "node:fs";
51602
51725
  function readIosVersion(projectYml) {
51603
51726
  const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
51604
51727
  const build2 = matchScalar(projectYml, "CFBundleVersion");
@@ -51656,8 +51779,8 @@ function setAndroidVersion(gradle, v) {
51656
51779
  function bumpVersion(app, opts) {
51657
51780
  const iosPath = iosProjectYml(app);
51658
51781
  const gradlePath = androidGradle(app);
51659
- const iosYml = readFileSync57(iosPath, "utf8");
51660
- const gradle = readFileSync57(gradlePath, "utf8");
51782
+ const iosYml = readFileSync58(iosPath, "utf8");
51783
+ const gradle = readFileSync58(gradlePath, "utf8");
51661
51784
  const current = readIosVersion(iosYml);
51662
51785
  const next = {
51663
51786
  marketing: opts.marketing ?? current.marketing,
@@ -51674,7 +51797,7 @@ var init_version = __esm({
51674
51797
  });
51675
51798
 
51676
51799
  // ../store-release/register-bundle.ts
51677
- import { readFileSync as readFileSync58 } from "node:fs";
51800
+ import { readFileSync as readFileSync59 } from "node:fs";
51678
51801
  import { createPrivateKey, sign } from "node:crypto";
51679
51802
  function b64url2(b) {
51680
51803
  return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
@@ -51692,7 +51815,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
51692
51815
  async function registerBundleId(opts) {
51693
51816
  const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
51694
51817
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
51695
- const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync58(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
51818
+ const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync59(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
51696
51819
  const res = await fetch(`${ASC_API}/v1/bundleIds`, {
51697
51820
  method: "POST",
51698
51821
  headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
@@ -51746,7 +51869,7 @@ __export(asc_status_exports, {
51746
51869
  ascStatus: () => ascStatus,
51747
51870
  buildVerdict: () => buildVerdict
51748
51871
  });
51749
- import { readFileSync as readFileSync59 } from "node:fs";
51872
+ import { readFileSync as readFileSync60 } from "node:fs";
51750
51873
  function buildVerdict(builds) {
51751
51874
  if (!builds.length) {
51752
51875
  return "NO builds registered \u2014 if you uploaded recently and it's been >15 min, the binary was REJECTED IN PROCESSING (reason is email-only; run validate-binary.ts / scan-purpose-strings.ts to reproduce it).";
@@ -51760,7 +51883,7 @@ function buildVerdict(builds) {
51760
51883
  function client2(creds) {
51761
51884
  const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
51762
51885
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
51763
- const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync59(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
51886
+ const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync60(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
51764
51887
  return async (path) => {
51765
51888
  const r = await fetch(`${ASC}${path}`, { headers: { Authorization: `Bearer ${jwt}` } });
51766
51889
  return { status: r.status, json: await r.json().catch(() => ({})) };
@@ -54850,10 +54973,10 @@ function isFetchableFontUrl(raw) {
54850
54973
  return true;
54851
54974
  }
54852
54975
  function resolveAll(hostname) {
54853
- return new Promise((resolve41, reject) => {
54976
+ return new Promise((resolve42, reject) => {
54854
54977
  dnsLookup(hostname, { all: true, verbatim: true }, (err, addresses) => {
54855
54978
  if (err) reject(err);
54856
- else resolve41(addresses);
54979
+ else resolve42(addresses);
54857
54980
  });
54858
54981
  });
54859
54982
  }
@@ -54861,13 +54984,13 @@ function withAbort(start, signal, what) {
54861
54984
  if (signal?.aborted) return Promise.reject(new Error(`${what} aborted`));
54862
54985
  const work = start();
54863
54986
  if (!signal) return work;
54864
- return new Promise((resolve41, reject) => {
54987
+ return new Promise((resolve42, reject) => {
54865
54988
  const onAbort = () => reject(new Error(`${what} aborted`));
54866
54989
  signal.addEventListener("abort", onAbort, { once: true });
54867
- work.then(resolve41, reject).finally(() => signal.removeEventListener("abort", onAbort));
54990
+ work.then(resolve42, reject).finally(() => signal.removeEventListener("abort", onAbort));
54868
54991
  });
54869
54992
  }
54870
- async function pinAddress(url, resolve41 = resolveAll, signal) {
54993
+ async function pinAddress(url, resolve42 = resolveAll, signal) {
54871
54994
  const host = url.hostname.replace(/^\[|\]$/g, "");
54872
54995
  if (ipv4Octets(host)) {
54873
54996
  if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
@@ -54877,7 +55000,7 @@ async function pinAddress(url, resolve41 = resolveAll, signal) {
54877
55000
  if (isBlockedAddress(host)) throw new Error(`${host} is a blocked address`);
54878
55001
  return { address: host, family: 6 };
54879
55002
  }
54880
- const addresses = await withAbort(() => resolve41(host), signal, `${host} lookup`);
55003
+ const addresses = await withAbort(() => resolve42(host), signal, `${host} lookup`);
54881
55004
  if (!addresses.length) throw new Error(`${host} resolved to no address`);
54882
55005
  const blocked = addresses.filter((a) => isBlockedAddress(a.address)).map((a) => a.address);
54883
55006
  if (blocked.length) throw new Error(`${host} resolves to a blocked address (${blocked.join(", ")})`);
@@ -54900,7 +55023,7 @@ function decodedBody(res, hasBody) {
54900
55023
  return out;
54901
55024
  }
54902
55025
  function requestOnce(url, pinned, init) {
54903
- return new Promise((resolve41, reject) => {
55026
+ return new Promise((resolve42, reject) => {
54904
55027
  const headers2 = { host: url.host, "accept-encoding": "identity" };
54905
55028
  new Headers(init.headers ?? {}).forEach((value, key2) => {
54906
55029
  if (key2.toLowerCase() !== "host") headers2[key2] = value;
@@ -54934,7 +55057,7 @@ function requestOnce(url, pinned, init) {
54934
55057
  reject(err);
54935
55058
  return;
54936
55059
  }
54937
- resolve41(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
55060
+ resolve42(new Response(body, { status, statusText: res.statusMessage ?? "", headers: out }));
54938
55061
  }
54939
55062
  );
54940
55063
  req.on("error", reject);
@@ -55043,7 +55166,7 @@ var init_brand_font = __esm({
55043
55166
 
55044
55167
  // src/site-analyze/write-artifacts.ts
55045
55168
  import { mkdirSync as mkdirSync23, writeFileSync as writeFileSync20 } from "node:fs";
55046
- import { join as join47 } from "node:path";
55169
+ import { join as join48 } from "node:path";
55047
55170
  function attachVeloSources(book, sources, put) {
55048
55171
  const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
55049
55172
  for (const f of book.velo.files) {
@@ -55198,12 +55321,12 @@ async function downloadMedia(book, fetchImpl, put) {
55198
55321
  }
55199
55322
  async function writeBusinessBook(result, opts) {
55200
55323
  const out = opts.outDir;
55201
- mkdirSync23(join47(out, "evidence/pages"), { recursive: true });
55202
- mkdirSync23(join47(out, "media/catalog"), { recursive: true });
55324
+ mkdirSync23(join48(out, "evidence/pages"), { recursive: true });
55325
+ mkdirSync23(join48(out, "media/catalog"), { recursive: true });
55203
55326
  const files = [];
55204
55327
  const put = (rel, body) => {
55205
- const p = join47(out, rel);
55206
- mkdirSync23(join47(p, ".."), { recursive: true });
55328
+ const p = join48(out, rel);
55329
+ mkdirSync23(join48(p, ".."), { recursive: true });
55207
55330
  writeFileSync20(p, body);
55208
55331
  files.push(rel);
55209
55332
  };
@@ -55534,15 +55657,15 @@ var init_home_descriptor = __esm({
55534
55657
  });
55535
55658
 
55536
55659
  // src/site-analyze/apply.ts
55537
- import { existsSync as existsSync49, readFileSync as readFileSync60, writeFileSync as writeFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync24, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
55538
- import { dirname as dirname27, isAbsolute as isAbsolute3, join as join48, resolve as resolve38, sep as sep10 } from "node:path";
55660
+ import { existsSync as existsSync50, readFileSync as readFileSync61, writeFileSync as writeFileSync21, copyFileSync as copyFileSync3, mkdirSync as mkdirSync24, realpathSync as realpathSync5, statSync as statSync11 } from "node:fs";
55661
+ import { dirname as dirname28, isAbsolute as isAbsolute4, join as join49, resolve as resolve39, sep as sep10 } from "node:path";
55539
55662
  import { spawnSync as spawnSync4 } from "node:child_process";
55540
55663
  function unpairedRedirectNote(overlay) {
55541
55664
  if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
55542
55665
  return `no OAuth redirect paired with client ${overlay.wix.clientId} \u2014 the app (and prepare:customer) will refuse to start until one is set. Register it with \`himi site client ensure --site ${overlay.siteId?.trim() || "<msid>"} --redirect-uri <uri> --yes\`, then re-run analyze with \`--redirect-uri <uri>\` (or export HIMI_BRANDED_LITE_WIX_REDIRECT_URI)`;
55543
55666
  }
55544
55667
  function posix2(p) {
55545
- return resolve38(p).replace(/\\/g, "/");
55668
+ return resolve39(p).replace(/\\/g, "/");
55546
55669
  }
55547
55670
  function committedShellProvisioning(path) {
55548
55671
  return committedShellFor(posix2(path));
@@ -55550,8 +55673,8 @@ function committedShellProvisioning(path) {
55550
55673
  function findRepoRoot(cwd) {
55551
55674
  let dir = cwd;
55552
55675
  for (let i = 0; i < 8; i++) {
55553
- if (SHELL_NAMES2.some((name) => existsSync49(join48(dir, shellAppDir(name), "package.json")))) return dir;
55554
- const next = dirname27(dir);
55676
+ if (SHELL_NAMES2.some((name) => existsSync50(join49(dir, shellAppDir(name), "package.json")))) return dir;
55677
+ const next = dirname28(dir);
55555
55678
  if (next === dir) break;
55556
55679
  dir = next;
55557
55680
  }
@@ -55576,7 +55699,7 @@ function assertNotCommitted(path, forbidden) {
55576
55699
  `refusing to overwrite committed ${committedProvisioningPath(committed)} \u2014 use prepare:customer --contract`
55577
55700
  );
55578
55701
  }
55579
- if (forbidden && resolve38(path) === resolve38(forbidden)) {
55702
+ if (forbidden && resolve39(path) === resolve39(forbidden)) {
55580
55703
  const named = committedShellProvisioning(forbidden);
55581
55704
  throw new Error(
55582
55705
  `refusing to overwrite committed ${named ? committedProvisioningPath(named) : forbidden} \u2014 pass a content-package provisioning.json or use prepare:customer --contract`
@@ -55618,24 +55741,24 @@ function mergeCustomerOwned(committed, overlay) {
55618
55741
  }
55619
55742
  function buildMergedContract(options) {
55620
55743
  const { appDir: appDir2, packageDir, overlay } = options;
55621
- const committedPath = join48(appDir2, "provisioning.json");
55622
- if (!existsSync49(committedPath)) {
55744
+ const committedPath = join49(appDir2, "provisioning.json");
55745
+ if (!existsSync50(committedPath)) {
55623
55746
  throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
55624
55747
  }
55625
- const committed = JSON.parse(readFileSync60(committedPath, "utf8"));
55748
+ const committed = JSON.parse(readFileSync61(committedPath, "utf8"));
55626
55749
  const merged = mergeCustomerOwned(committed, overlay);
55627
55750
  const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
55628
55751
  const branding = merged.branding ?? {};
55629
55752
  const staged = [];
55630
55753
  const contained = (root, rel) => {
55631
- if (isAbsolute3(rel)) return void 0;
55632
- const full = resolve38(root, rel);
55633
- return full.startsWith(resolve38(root) + sep10) ? full : void 0;
55754
+ if (isAbsolute4(rel)) return void 0;
55755
+ const full = resolve39(root, rel);
55756
+ return full.startsWith(resolve39(root) + sep10) ? full : void 0;
55634
55757
  };
55635
55758
  const stage = (fromRel, toRel) => {
55636
55759
  const from = contained(packageDir, fromRel);
55637
- const to = contained(join48(appDir2, STAGED), toRel.slice(STAGED.length + 1));
55638
- if (!from || !to || !existsSync49(from)) return void 0;
55760
+ const to = contained(join49(appDir2, STAGED), toRel.slice(STAGED.length + 1));
55761
+ if (!from || !to || !existsSync50(from)) return void 0;
55639
55762
  let real;
55640
55763
  let realRoot;
55641
55764
  try {
@@ -55646,8 +55769,8 @@ function buildMergedContract(options) {
55646
55769
  }
55647
55770
  if (!real.startsWith(realRoot + sep10)) return void 0;
55648
55771
  try {
55649
- if (!statSync12(real).isFile()) return void 0;
55650
- mkdirSync24(dirname27(to), { recursive: true });
55772
+ if (!statSync11(real).isFile()) return void 0;
55773
+ mkdirSync24(dirname28(to), { recursive: true });
55651
55774
  copyFileSync3(real, to);
55652
55775
  } catch {
55653
55776
  return void 0;
@@ -55657,11 +55780,11 @@ function buildMergedContract(options) {
55657
55780
  };
55658
55781
  const icon = stage("media/icon.png", `${STAGED}/icon.png`);
55659
55782
  if (icon) branding.appIconPath = icon;
55660
- const facesPath = join48(packageDir, "media/fonts/faces.json");
55661
- if (existsSync49(facesPath)) {
55783
+ const facesPath = join49(packageDir, "media/fonts/faces.json");
55784
+ if (existsSync50(facesPath)) {
55662
55785
  let faces = [];
55663
55786
  try {
55664
- const parsed = JSON.parse(readFileSync60(facesPath, "utf8"));
55787
+ const parsed = JSON.parse(readFileSync61(facesPath, "utf8"));
55665
55788
  faces = Array.isArray(parsed) ? parsed : [];
55666
55789
  } catch {
55667
55790
  faces = [];
@@ -55682,20 +55805,20 @@ function buildMergedContract(options) {
55682
55805
  merged.branding = branding;
55683
55806
  const body = `${JSON.stringify(merged, null, 2)}
55684
55807
  `;
55685
- const path = join48(packageDir, "provisioning.contract.json");
55808
+ const path = join49(packageDir, "provisioning.contract.json");
55686
55809
  writeFileSync21(path, body);
55687
- const localPath = join48(appDir2, LOCAL_CONTRACT_REL);
55688
- mkdirSync24(dirname27(localPath), { recursive: true });
55810
+ const localPath = join49(appDir2, LOCAL_CONTRACT_REL);
55811
+ mkdirSync24(dirname28(localPath), { recursive: true });
55689
55812
  writeFileSync21(localPath, body);
55690
55813
  staged.push(localPath);
55691
55814
  return { path, staged };
55692
55815
  }
55693
55816
  async function applyOverlays(input) {
55694
- const cwd = resolve38(input.cwd);
55817
+ const cwd = resolve39(input.cwd);
55695
55818
  const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
55696
55819
  assertKnownShell(shell);
55697
- const overlay = JSON.parse(readFileSync60(input.overlayPath, "utf8"));
55698
- const tokens = JSON.parse(readFileSync60(input.tokensPath, "utf8"));
55820
+ const overlay = JSON.parse(readFileSync61(input.overlayPath, "utf8"));
55821
+ const tokens = JSON.parse(readFileSync61(input.tokensPath, "utf8"));
55699
55822
  const wrote = [];
55700
55823
  const notes = [];
55701
55824
  const repoRoot2 = findRepoRoot(cwd);
@@ -55705,8 +55828,8 @@ async function applyOverlays(input) {
55705
55828
  `shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
55706
55829
  );
55707
55830
  }
55708
- const appDir2 = join48(repoRoot2, shellAppDir(shell));
55709
- const packageDir = dirname27(resolve38(input.overlayPath));
55831
+ const appDir2 = join49(repoRoot2, shellAppDir(shell));
55832
+ const packageDir = dirname28(resolve39(input.overlayPath));
55710
55833
  const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
55711
55834
  wrote.push(...staged);
55712
55835
  const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
@@ -55727,10 +55850,10 @@ async function applyOverlays(input) {
55727
55850
  note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
55728
55851
  };
55729
55852
  }
55730
- const pkgProv = join48(cwd, "provisioning.json");
55853
+ const pkgProv = join49(cwd, "provisioning.json");
55731
55854
  assertNotCommitted(pkgProv, input.forbiddenProvisioning);
55732
- if (existsSync49(pkgProv)) {
55733
- const cur = JSON.parse(readFileSync60(pkgProv, "utf8"));
55855
+ if (existsSync50(pkgProv)) {
55856
+ const cur = JSON.parse(readFileSync61(pkgProv, "utf8"));
55734
55857
  const merged = deepMerge3(cur, overlay);
55735
55858
  writeFileSync21(pkgProv, JSON.stringify(merged, null, 2) + "\n");
55736
55859
  wrote.push(pkgProv);
@@ -55738,17 +55861,17 @@ async function applyOverlays(input) {
55738
55861
  writeFileSync21(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
55739
55862
  wrote.push(pkgProv);
55740
55863
  }
55741
- const pkgTokens = join48(cwd, "tokens.json");
55742
- if (existsSync49(pkgTokens) && (tokens.colors || tokens.typography)) {
55743
- const cur = JSON.parse(readFileSync60(pkgTokens, "utf8"));
55864
+ const pkgTokens = join49(cwd, "tokens.json");
55865
+ if (existsSync50(pkgTokens) && (tokens.colors || tokens.typography)) {
55866
+ const cur = JSON.parse(readFileSync61(pkgTokens, "utf8"));
55744
55867
  const merged = deepMerge3(cur, tokens);
55745
55868
  writeFileSync21(pkgTokens, JSON.stringify(merged, null, 2) + "\n");
55746
55869
  wrote.push(pkgTokens);
55747
55870
  }
55748
55871
  const homeAction = homeRefreshActionId(shell);
55749
- const homeSrc = join48(cwd, "dev/index.ts");
55750
- if (homeAction && existsSync49(homeSrc)) {
55751
- const prev = readFileSync60(homeSrc, "utf8");
55872
+ const homeSrc = join49(cwd, "dev/index.ts");
55873
+ if (homeAction && existsSync50(homeSrc)) {
55874
+ const prev = readFileSync61(homeSrc, "utf8");
55752
55875
  const patched = patchBrandParams(prev, overlay, homeAction);
55753
55876
  let next = patched.src;
55754
55877
  if (!patched.foreign && overlay.installedVerticals?.length) {
@@ -55768,13 +55891,13 @@ async function applyOverlays(input) {
55768
55891
  notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
55769
55892
  }
55770
55893
  }
55771
- if (!input.iconPath || !existsSync49(input.iconPath)) {
55772
- const book = input.iconPath ? dirname27(dirname27(resolve38(input.iconPath))) : void 0;
55894
+ if (!input.iconPath || !existsSync50(input.iconPath)) {
55895
+ const book = input.iconPath ? dirname28(dirname28(resolve39(input.iconPath))) : void 0;
55773
55896
  notes.push(
55774
55897
  book ? `no icon installed \u2014 ${siteLogoAbsence(book).hint}` : "no icon installed and no business book to say why \u2014 `himi icon generate` draws one from the accent, or `himi icon set <file.png>` installs the customer's own mark"
55775
55898
  );
55776
55899
  }
55777
- if (input.iconPath && existsSync49(input.iconPath)) {
55900
+ if (input.iconPath && existsSync50(input.iconPath)) {
55778
55901
  try {
55779
55902
  const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
55780
55903
  wrote.push(...installed.wrote);
@@ -56908,13 +57031,13 @@ __export(cli_exports, {
56908
57031
  runSiteAnalyze: () => runSiteAnalyze,
56909
57032
  runSiteFunctionCli: () => runSiteFunctionCli
56910
57033
  });
56911
- import { readFileSync as readFileSync61 } from "node:fs";
56912
- import { resolve as resolve39 } from "node:path";
57034
+ import { readFileSync as readFileSync62 } from "node:fs";
57035
+ import { resolve as resolve40 } from "node:path";
56913
57036
  async function runSiteAnalyze(opts) {
56914
57037
  const fetchImpl = opts.fetchImpl ?? fetch;
56915
57038
  const assetFetch = opts.fetchImpl ?? pinnedFetch2;
56916
57039
  const cwd = opts.cwd ?? process.cwd();
56917
- const outDir = resolve39(cwd, opts.outDir ?? ".himi/business-book");
57040
+ const outDir = resolve40(cwd, opts.outDir ?? ".himi/business-book");
56918
57041
  let ownerAuth;
56919
57042
  let msid;
56920
57043
  try {
@@ -56951,9 +57074,9 @@ async function runSiteAnalyze(opts) {
56951
57074
  if (opts.apply) {
56952
57075
  applied = await applyOverlays({
56953
57076
  cwd,
56954
- overlayPath: resolve39(outDir, "provisioning.overlay.json"),
56955
- tokensPath: resolve39(outDir, "tokens.overlay.json"),
56956
- iconPath: resolve39(outDir, "media/icon.png"),
57077
+ overlayPath: resolve40(outDir, "provisioning.overlay.json"),
57078
+ tokensPath: resolve40(outDir, "tokens.overlay.json"),
57079
+ iconPath: resolve40(outDir, "media/icon.png"),
56957
57080
  shell: opts.shell
56958
57081
  });
56959
57082
  const note = noteWithWarnings(applied.note, warnings);
@@ -56989,8 +57112,8 @@ async function runSiteFunctionCli(opts) {
56989
57112
  const token = opts.token ?? await siteToken(msid);
56990
57113
  let source;
56991
57114
  if (opts.sourcePath) {
56992
- const p = resolve39(opts.cwd ?? process.cwd(), opts.sourcePath);
56993
- source = readFileSync61(p, "utf8");
57115
+ const p = resolve40(opts.cwd ?? process.cwd(), opts.sourcePath);
57116
+ source = readFileSync62(p, "utf8");
56994
57117
  }
56995
57118
  let body;
56996
57119
  if (opts.bodyRaw != null) {
@@ -57041,7 +57164,7 @@ async function accountToken2(spawnImpl = spawn4) {
57041
57164
  cached2 = fromEnv;
57042
57165
  return fromEnv;
57043
57166
  }
57044
- const token = await new Promise((resolve41, reject) => {
57167
+ const token = await new Promise((resolve42, reject) => {
57045
57168
  let child;
57046
57169
  try {
57047
57170
  child = spawnImpl("wix", ["token"]);
@@ -57070,7 +57193,7 @@ async function accountToken2(spawnImpl = spawn4) {
57070
57193
  const scan = (d) => {
57071
57194
  out += String(d);
57072
57195
  const m = out.match(TOKEN_RE2);
57073
- if (m) done(() => resolve41(m[0]));
57196
+ if (m) done(() => resolve42(m[0]));
57074
57197
  };
57075
57198
  child.stdout?.on("data", scan);
57076
57199
  child.stderr?.on("data", scan);
@@ -57247,7 +57370,7 @@ __export(site_create_exports, {
57247
57370
  runSiteList: () => runSiteList,
57248
57371
  writeProvisioningBinding: () => writeProvisioningBinding
57249
57372
  });
57250
- import { existsSync as existsSync50, readFileSync as readFileSync62, writeFileSync as writeFileSync22 } from "node:fs";
57373
+ import { existsSync as existsSync51, readFileSync as readFileSync63, writeFileSync as writeFileSync22 } from "node:fs";
57251
57374
  import { resolve as resolvePath2 } from "node:path";
57252
57375
  function oauthClientName(projectName) {
57253
57376
  return `${projectName} client`;
@@ -57396,7 +57519,7 @@ async function runSiteCreate(opts) {
57396
57519
  if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
57397
57520
  return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
57398
57521
  }
57399
- function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync50, readFileSync: readFileSync62, writeFileSync: writeFileSync22 }) {
57522
+ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync51, readFileSync: readFileSync63, writeFileSync: writeFileSync22 }) {
57400
57523
  const msid = binding2.siteId;
57401
57524
  const path = resolvePath2(target);
57402
57525
  const committed = committedShellProvisioning(path);
@@ -57730,11 +57853,11 @@ var init_site_oauth_client = __esm({
57730
57853
  });
57731
57854
 
57732
57855
  // src/cli.ts
57733
- import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync63, mkdirSync as mkdirSync25, writeFileSync as writeFileSync23, existsSync as existsSync51, rmSync as rmSync9, readdirSync as readdirSync23, statSync as statSync13, lstatSync as lstatSync5 } from "node:fs";
57856
+ import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync64, mkdirSync as mkdirSync25, writeFileSync as writeFileSync23, existsSync as existsSync52, rmSync as rmSync9, readdirSync as readdirSync23, statSync as statSync12, lstatSync as lstatSync5 } from "node:fs";
57734
57857
  import { execFileSync as execFileSync6 } from "node:child_process";
57735
57858
  import { createHash as createHash24 } from "node:crypto";
57736
57859
  import { tmpdir as tmpdir5 } from "node:os";
57737
- import { join as join49, resolve as resolve40, basename as basename9, dirname as dirname28 } from "node:path";
57860
+ import { join as join50, resolve as resolve41, basename as basename9, dirname as dirname29 } from "node:path";
57738
57861
  import { fileURLToPath as fileURLToPath21 } from "node:url";
57739
57862
 
57740
57863
  // ../serve-cli/src/client.ts
@@ -59250,7 +59373,7 @@ async function browserLogin(opts) {
59250
59373
  const log = opts.log ?? (() => {
59251
59374
  });
59252
59375
  const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
59253
- return await new Promise((resolve41, reject) => {
59376
+ return await new Promise((resolve42, reject) => {
59254
59377
  let settled = false;
59255
59378
  let loginUrl = "";
59256
59379
  const server = createServer();
@@ -59314,7 +59437,7 @@ async function browserLogin(opts) {
59314
59437
  return;
59315
59438
  }
59316
59439
  res.writeHead(200, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", connection: "close" }).end(CLOSE_PAGE);
59317
- finish2(() => resolve41({ token, loginUrl }));
59440
+ finish2(() => resolve42({ token, loginUrl }));
59318
59441
  });
59319
59442
  });
59320
59443
  server.on("error", (err) => finish2(() => reject(err)));
@@ -60724,17 +60847,18 @@ init_crawl_layers();
60724
60847
  // src/ux-audit.ts
60725
60848
  init_wix_gateway_rules();
60726
60849
  init_mobile_ux_contract();
60727
- import { existsSync as existsSync21, mkdirSync as mkdirSync10, readFileSync as readFileSync23, readdirSync as readdirSync11, writeFileSync as writeFileSync9 } from "node:fs";
60728
- import { join as join25, relative as relative3, resolve as resolve15 } from "node:path";
60729
- var EVIDENCE_RELATIVE_PATH = ".himi/ux-audit.json";
60850
+ init_ux_evidence();
60851
+ init_ux_evidence();
60852
+ import { existsSync as existsSync22, readFileSync as readFileSync24, readdirSync as readdirSync11 } from "node:fs";
60853
+ import { join as join26, relative as relative4, resolve as resolve16 } from "node:path";
60730
60854
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".json"]);
60731
60855
  var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules", "dist", ".himi", "coverage"]);
60732
60856
  function issue(issues, strict, code, message, path) {
60733
60857
  issues.push({ code, message, ...path ? { path } : {}, severity: strict ? "error" : "warning" });
60734
60858
  }
60735
- function readText(path) {
60859
+ function readText2(path) {
60736
60860
  try {
60737
- return existsSync21(path) ? readFileSync23(path, "utf8") : null;
60861
+ return existsSync22(path) ? readFileSync24(path, "utf8") : null;
60738
60862
  } catch {
60739
60863
  return null;
60740
60864
  }
@@ -60743,30 +60867,17 @@ function walkSource(dir, root = dir) {
60743
60867
  const found = [];
60744
60868
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
60745
60869
  if (entry.isDirectory()) {
60746
- if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(join25(dir, entry.name), root));
60870
+ if (!IGNORED_DIRECTORIES.has(entry.name)) found.push(...walkSource(join26(dir, entry.name), root));
60747
60871
  continue;
60748
60872
  }
60749
60873
  const ext = entry.name.slice(entry.name.lastIndexOf("."));
60750
60874
  if (!SOURCE_EXTENSIONS.has(ext)) continue;
60751
- const absolute = join25(dir, entry.name);
60752
- const text2 = readText(absolute);
60753
- if (text2 !== null) found.push({ path: relative3(root, absolute), text: text2 });
60875
+ const absolute = join26(dir, entry.name);
60876
+ const text2 = readText2(absolute);
60877
+ if (text2 !== null) found.push({ path: relative4(root, absolute), text: text2 });
60754
60878
  }
60755
60879
  return found;
60756
60880
  }
60757
- function parseEvidence(path) {
60758
- const raw = readText(path);
60759
- if (raw === null) return { evidence: null };
60760
- try {
60761
- const value = JSON.parse(raw);
60762
- if (value.version !== 1 || !value.platforms || typeof value.platforms !== "object") {
60763
- return { evidence: null, error: "must be an object with version: 1 and a platforms object" };
60764
- }
60765
- return { evidence: value };
60766
- } catch (error) {
60767
- return { evidence: null, error: `is not valid JSON: ${error.message}` };
60768
- }
60769
- }
60770
60881
  function blankMatrixRows(text2) {
60771
60882
  const acceptance = mobileUxSection(mobileUxDocumentBody(text2), "Implementation acceptance") ?? "";
60772
60883
  return /\|\s*(?:Ready|Empty|Add\s*\/\s*edit|Saved\s*\/\s*completed|Error\s*\/\s*recovery)\s*\|\s*\|\s*\|\s*\|\s*\|/i.test(acceptance);
@@ -60776,40 +60887,41 @@ function usesAppNetwork(source) {
60776
60887
  return source.some(({ text: text2 }) => /\bwixApi\b|(?:from|import)\s*["']@(?:himalaya|wix\/himalaya)\/wix-[^"']+["']/.test(code(text2)));
60777
60888
  }
60778
60889
  function auditUx(content, strict = false) {
60779
- const dir = resolve15(content);
60890
+ const dir = resolve16(content);
60780
60891
  const issues = [];
60781
- const evidencePath = join25(dir, EVIDENCE_RELATIVE_PATH);
60782
- const spec = readText(join25(dir, "SPEC.md"));
60783
- const mobile = readText(join25(dir, "MOBILE-UX.md"));
60892
+ const evidencePath = join26(dir, UX_EVIDENCE_PATH);
60893
+ const parsed = parseEvidence(evidencePath);
60894
+ const renderedWidths = renderEvidenceEntries(parsed.evidence).map((entry) => entry.width);
60895
+ const spec = readText2(join26(dir, "SPEC.md"));
60896
+ const mobile = readText2(join26(dir, "MOBILE-UX.md"));
60784
60897
  if (!spec) issue(issues, strict, "missing-spec", "SPEC.md is missing; define the customer task before calling this UX-ready.", "SPEC.md");
60785
60898
  if (!mobile) {
60786
60899
  issue(issues, strict, "missing-mobile-ux", "MOBILE-UX.md is missing; add the mobile state and platform contract.", "MOBILE-UX.md");
60787
60900
  } else {
60788
- for (const finding of mobileUxMarkerFindings(mobile)) issue(issues, strict, finding.code, finding.message, "MOBILE-UX.md");
60901
+ for (const finding of mobileUxMarkerFindings(mobile, renderedWidths)) issue(issues, strict, finding.code, finding.message, "MOBILE-UX.md");
60789
60902
  if (blankMatrixRows(mobile)) issue(issues, strict, "blank-acceptance-matrix", "The seeded acceptance rows are still blank; replace them with this app's flows and visible results.", "MOBILE-UX.md");
60790
60903
  }
60791
- const parsed = parseEvidence(evidencePath);
60792
60904
  if (parsed.error) {
60793
- issues.push({ code: "invalid-native-evidence", message: `${EVIDENCE_RELATIVE_PATH} ${parsed.error}.`, path: EVIDENCE_RELATIVE_PATH, severity: "error" });
60905
+ issues.push({ code: "invalid-native-evidence", message: `${UX_EVIDENCE_PATH} ${parsed.error}.`, path: UX_EVIDENCE_PATH, severity: "error" });
60794
60906
  }
60795
60907
  for (const platform of ["ios", "android"]) {
60796
60908
  const record2 = parsed.evidence?.platforms[platform];
60797
60909
  if (!record2) {
60798
- issue(issues, strict, `missing-${platform}-audit`, `No ${platform} native audit is recorded. Use \`himi ux record --platform ${platform} \u2026\` after driving the installed app.`, EVIDENCE_RELATIVE_PATH);
60910
+ issue(issues, strict, `missing-${platform}-audit`, `No ${platform} native audit is recorded. Use \`himi ux record --platform ${platform} \u2026\` after driving the installed app.`, UX_EVIDENCE_PATH);
60799
60911
  continue;
60800
60912
  }
60801
60913
  if (!["passed", "failed", "unavailable"].includes(record2.status)) {
60802
- issues.push({ code: `invalid-${platform}-status`, message: `${platform} audit has an invalid status.`, path: EVIDENCE_RELATIVE_PATH, severity: "error" });
60914
+ issues.push({ code: `invalid-${platform}-status`, message: `${platform} audit has an invalid status.`, path: UX_EVIDENCE_PATH, severity: "error" });
60803
60915
  } else if (record2.status === "failed") {
60804
- issues.push({ code: `${platform}-audit-failed`, message: `${platform} native audit is recorded as failed; fix it or record a justified unavailable platform.`, path: EVIDENCE_RELATIVE_PATH, severity: "error" });
60916
+ issues.push({ code: `${platform}-audit-failed`, message: `${platform} native audit is recorded as failed; fix it or record a justified unavailable platform.`, path: UX_EVIDENCE_PATH, severity: "error" });
60805
60917
  }
60806
60918
  const malformedChecks = record2.checks !== void 0 && !Array.isArray(record2.checks);
60807
60919
  if (malformedChecks || record2.status !== "unavailable" && (record2.checks ?? []).length === 0) {
60808
60920
  const message = malformedChecks ? `${platform} audit has a malformed checks list; it must be an array.` : `${platform} audit needs the checks that were driven.`;
60809
- issues.push({ code: `missing-${platform}-checks`, message, path: EVIDENCE_RELATIVE_PATH, severity: "error" });
60921
+ issues.push({ code: `missing-${platform}-checks`, message, path: UX_EVIDENCE_PATH, severity: "error" });
60810
60922
  }
60811
60923
  if (record2.status === "unavailable" && !record2.reason?.trim()) {
60812
- issues.push({ code: `missing-${platform}-reason`, message: `${platform} is unavailable but has no reason.`, path: EVIDENCE_RELATIVE_PATH, severity: "error" });
60924
+ issues.push({ code: `missing-${platform}-reason`, message: `${platform} is unavailable but has no reason.`, path: UX_EVIDENCE_PATH, severity: "error" });
60813
60925
  }
60814
60926
  }
60815
60927
  const source = walkSource(dir);
@@ -60821,12 +60933,12 @@ function auditUx(content, strict = false) {
60821
60933
  const preview = matches(previewControl);
60822
60934
  if (preview) issue(issues, strict, "possible-preview-control", "Possible customer-visible test/demo state control found. Keep scenario controls out of shipping UI, or document a capability-limited fallback.", preview.path);
60823
60935
  if (usesAppNetwork(source)) {
60824
- const mocksPath = join25(dir, "dev", "net-mocks.json");
60825
- if (!existsSync21(mocksPath)) {
60936
+ const mocksPath = join26(dir, "dev", "net-mocks.json");
60937
+ if (!existsSync22(mocksPath)) {
60826
60938
  issue(issues, strict, "missing-app-mocks", "This package uses a Wix/network client but has no app-specific dev/net-mocks.json. Add fixtures for dynamic, entitlement, or recovery flows.", "dev/net-mocks.json");
60827
60939
  } else {
60828
60940
  try {
60829
- const parsed2 = JSON.parse(readFileSync23(mocksPath, "utf8"));
60941
+ const parsed2 = JSON.parse(readFileSync24(mocksPath, "utf8"));
60830
60942
  const errors2 = Array.isArray(parsed2?.rules) ? wixMockRuleErrors(parsed2.rules) : ['missing top-level "rules" array'];
60831
60943
  if (errors2.length) issue(issues, strict, "invalid-app-mocks", `dev/net-mocks.json cannot serve the flows it claims to mock: ${errors2.join("; ")}`, "dev/net-mocks.json");
60832
60944
  } catch (error) {
@@ -60836,49 +60948,33 @@ function auditUx(content, strict = false) {
60836
60948
  }
60837
60949
  const errors = issues.filter((item) => item.severity === "error");
60838
60950
  const warnings = issues.filter((item) => item.severity === "warning");
60839
- return { ok: errors.length === 0, strict, content: dir, evidencePath: EVIDENCE_RELATIVE_PATH, errors, warnings, counts: { errors: errors.length, warnings: warnings.length } };
60840
- }
60841
- function recordNativeAudit(content, platform, status, checks, reason) {
60842
- const normalizedChecks = status === "unavailable" ? [] : [...new Set(checks.map((check) => check.trim()).filter(Boolean))];
60843
- if (status !== "unavailable" && !normalizedChecks.length) {
60844
- throw new Error("--checks needs at least one comma-separated check (for example: back,keyboard,voiceover)");
60845
- }
60846
- if (status === "unavailable" && !reason?.trim()) throw new Error("--reason is required when --status unavailable");
60847
- const dir = resolve15(content);
60848
- const path = join25(dir, EVIDENCE_RELATIVE_PATH);
60849
- const parsed = parseEvidence(path);
60850
- if (parsed.error) throw new Error(`${EVIDENCE_RELATIVE_PATH} ${parsed.error}`);
60851
- const evidence = parsed.evidence ?? { version: 1, platforms: {} };
60852
- evidence.platforms[platform] = { status, checks: normalizedChecks, ...reason?.trim() ? { reason: reason.trim() } : {}, recordedAt: (/* @__PURE__ */ new Date()).toISOString() };
60853
- mkdirSync10(join25(dir, ".himi"), { recursive: true });
60854
- writeFileSync9(path, JSON.stringify(evidence, null, 2) + "\n");
60855
- return evidence;
60951
+ return { ok: errors.length === 0, strict, content: dir, evidencePath: UX_EVIDENCE_PATH, errors, warnings, counts: { errors: errors.length, warnings: warnings.length } };
60856
60952
  }
60857
60953
 
60858
60954
  // src/guides.ts
60859
60955
  init_mobile_ux_contract();
60860
- import { readFileSync as readFileSync24, existsSync as existsSync22, mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, copyFileSync as copyFileSync2 } from "node:fs";
60956
+ import { readFileSync as readFileSync25, existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync10, copyFileSync as copyFileSync2 } from "node:fs";
60861
60957
  import { fileURLToPath as fileURLToPath10 } from "node:url";
60862
- import { dirname as dirname15, join as join26, resolve as resolve16 } from "node:path";
60863
- var GUIDES_DIR = resolve16(dirname15(fileURLToPath10(import.meta.url)), "../guides");
60958
+ import { dirname as dirname16, join as join27, resolve as resolve17 } from "node:path";
60959
+ var GUIDES_DIR = resolve17(dirname16(fileURLToPath10(import.meta.url)), "../guides");
60864
60960
  function guidesAvailable() {
60865
- return existsSync22(join26(GUIDES_DIR, "index.json"));
60961
+ return existsSync23(join27(GUIDES_DIR, "index.json"));
60866
60962
  }
60867
60963
  function loadIndex() {
60868
- return JSON.parse(readFileSync24(join26(GUIDES_DIR, "index.json"), "utf8"));
60964
+ return JSON.parse(readFileSync25(join27(GUIDES_DIR, "index.json"), "utf8"));
60869
60965
  }
60870
60966
  function readGuide(id) {
60871
60967
  const meta = loadIndex().guides.find((g) => g.id === id);
60872
60968
  if (!meta) return null;
60873
- return readFileSync24(join26(GUIDES_DIR, meta.file), "utf8");
60969
+ return readFileSync25(join27(GUIDES_DIR, meta.file), "utf8");
60874
60970
  }
60875
60971
  function loadComponentReference() {
60876
60972
  const idx = loadIndex();
60877
- return JSON.parse(readFileSync24(join26(GUIDES_DIR, idx.componentReferenceFile), "utf8"));
60973
+ return JSON.parse(readFileSync25(join27(GUIDES_DIR, idx.componentReferenceFile), "utf8"));
60878
60974
  }
60879
60975
  function loadSdkReference() {
60880
60976
  const idx = loadIndex();
60881
- return JSON.parse(readFileSync24(join26(GUIDES_DIR, idx.sdkReferenceFile), "utf8"));
60977
+ return JSON.parse(readFileSync25(join27(GUIDES_DIR, idx.sdkReferenceFile), "utf8"));
60882
60978
  }
60883
60979
  function buildAgentPrimer() {
60884
60980
  const idx = loadIndex();
@@ -60987,19 +61083,19 @@ function writeAgentContext(targetDir) {
60987
61083
  const idx = loadIndex();
60988
61084
  const files = [];
60989
61085
  const write2 = (rel, body) => {
60990
- const p = join26(targetDir, rel);
60991
- mkdirSync11(dirname15(p), { recursive: true });
61086
+ const p = join27(targetDir, rel);
61087
+ mkdirSync11(dirname16(p), { recursive: true });
60992
61088
  writeFileSync10(p, body);
60993
61089
  files.push(rel);
60994
61090
  };
60995
61091
  const copy = (srcRel, destRel) => {
60996
- const p = join26(targetDir, destRel);
60997
- mkdirSync11(dirname15(p), { recursive: true });
60998
- copyFileSync2(join26(GUIDES_DIR, srcRel), p);
61092
+ const p = join27(targetDir, destRel);
61093
+ mkdirSync11(dirname16(p), { recursive: true });
61094
+ copyFileSync2(join27(GUIDES_DIR, srcRel), p);
60999
61095
  files.push(destRel);
61000
61096
  };
61001
61097
  const writeIfMissing = (rel, body) => {
61002
- if (existsSync22(join26(targetDir, rel))) return;
61098
+ if (existsSync23(join27(targetDir, rel))) return;
61003
61099
  write2(rel, body);
61004
61100
  };
61005
61101
  write2("HIMALAYA.md", buildAgentPrimer());
@@ -61060,8 +61156,8 @@ var str5 = (v) => typeof v === "string" ? v : void 0;
61060
61156
  var num = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
61061
61157
  function embeddedTemplateCatalog() {
61062
61158
  return availableTemplates().map((name) => {
61063
- const path = join49(templateSourceDir(name), TEMPLATE_META_FILE);
61064
- const meta = JSON.parse(readFileSync63(path, "utf8"));
61159
+ const path = join50(templateSourceDir(name), TEMPLATE_META_FILE);
61160
+ const meta = JSON.parse(readFileSync64(path, "utf8"));
61065
61161
  if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
61066
61162
  throw new Error(`${path} must be { title: string, description: string, tags: string[], category?: string }`);
61067
61163
  }
@@ -61564,7 +61660,7 @@ var COMMANDS = [
61564
61660
  ];
61565
61661
  function cliVersion() {
61566
61662
  try {
61567
- return JSON.parse(readFileSync63(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
61663
+ return JSON.parse(readFileSync64(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
61568
61664
  } catch {
61569
61665
  return "unknown";
61570
61666
  }
@@ -61580,18 +61676,18 @@ function compareVersions2(a, b) {
61580
61676
  }
61581
61677
  function packageVersion(path) {
61582
61678
  try {
61583
- const version = JSON.parse(readFileSync63(path, "utf8")).version;
61679
+ const version = JSON.parse(readFileSync64(path, "utf8")).version;
61584
61680
  return typeof version === "string" && version ? version : void 0;
61585
61681
  } catch {
61586
61682
  return void 0;
61587
61683
  }
61588
61684
  }
61589
61685
  function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
61590
- let dir = resolve40(fromDir);
61686
+ let dir = resolve41(fromDir);
61591
61687
  for (; ; ) {
61592
- const version = packageVersion(join49(dir, "node_modules", "@wix", "himalaya", "package.json"));
61688
+ const version = packageVersion(join50(dir, "node_modules", "@wix", "himalaya", "package.json"));
61593
61689
  if (version) return { version, source: "local" };
61594
- const parent = dirname28(dir);
61690
+ const parent = dirname29(dir);
61595
61691
  if (parent === dir) break;
61596
61692
  dir = parent;
61597
61693
  }
@@ -61599,7 +61695,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
61599
61695
  if (bundled) return { version: bundled, source: "bundled" };
61600
61696
  try {
61601
61697
  const root = execFileSync6("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
61602
- const version = root ? packageVersion(join49(root, "@wix", "himalaya", "package.json")) : void 0;
61698
+ const version = root ? packageVersion(join50(root, "@wix", "himalaya", "package.json")) : void 0;
61603
61699
  return version ? { version, source: "global" } : {};
61604
61700
  } catch {
61605
61701
  return {};
@@ -62013,7 +62109,7 @@ async function nativeConfigAdvisories(app, configSource) {
62013
62109
  const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
62014
62110
  const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
62015
62111
  const iosYmlPath = iosProjectYml2(app);
62016
- const iosYml = existsSync51(iosYmlPath) ? readFileSync63(iosYmlPath, "utf8") : "";
62112
+ const iosYml = existsSync52(iosYmlPath) ? readFileSync64(iosYmlPath, "utf8") : "";
62017
62113
  let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
62018
62114
  if (!optedIn) {
62019
62115
  const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
@@ -62027,19 +62123,19 @@ async function nativeConfigAdvisories(app, configSource) {
62027
62123
  }
62028
62124
  function readConfigSource(dir) {
62029
62125
  try {
62030
- return readFileSync63(join49(dir, "config.ts"), "utf8");
62126
+ return readFileSync64(join50(dir, "config.ts"), "utf8");
62031
62127
  } catch {
62032
62128
  return null;
62033
62129
  }
62034
62130
  }
62035
62131
  function writePngFile(path, base64) {
62036
- mkdirSync25(dirname28(path), { recursive: true });
62132
+ mkdirSync25(dirname29(path), { recursive: true });
62037
62133
  writeFileSync23(path, Buffer.from(base64, "base64"));
62038
62134
  return path;
62039
62135
  }
62040
62136
  async function initFromRemoteTemplate(name, parentDir, template, c) {
62041
- const dir = resolve40(parentDir, name);
62042
- if (existsSync51(join49(dir, "himalaya.content.json"))) {
62137
+ const dir = resolve41(parentDir, name);
62138
+ if (existsSync52(join50(dir, "himalaya.content.json"))) {
62043
62139
  throw new Error(`content package already exists at ${dir}`);
62044
62140
  }
62045
62141
  const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
@@ -62051,7 +62147,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
62051
62147
  return finishScaffold(materializeSource(archive.files, name, dir), template);
62052
62148
  }
62053
62149
  function contentDir(flags) {
62054
- return resolve40(str5(flags.content) ?? process.cwd());
62150
+ return resolve41(str5(flags.content) ?? process.cwd());
62055
62151
  }
62056
62152
  function renameRestoredSource(restored, declaredApp, renamed) {
62057
62153
  const text2 = {};
@@ -62082,8 +62178,8 @@ function symlinkDestinationIssue(dest) {
62082
62178
  function restoreDestinationIssue(dest, force) {
62083
62179
  const link = symlinkDestinationIssue(dest);
62084
62180
  if (link) return link;
62085
- if (!existsSync51(dest)) return null;
62086
- if (!statSync13(dest).isDirectory()) {
62181
+ if (!existsSync52(dest)) return null;
62182
+ if (!statSync12(dest).isDirectory()) {
62087
62183
  return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
62088
62184
  }
62089
62185
  if (readdirSync23(dest).length > 0 && !force) {
@@ -62095,10 +62191,10 @@ function restoreDestinationIssue(dest, force) {
62095
62191
  return null;
62096
62192
  }
62097
62193
  function isHimalayaMonorepoCheckout(start) {
62098
- let dir = resolve40(start);
62194
+ let dir = resolve41(start);
62099
62195
  for (; ; ) {
62100
- if (existsSync51(join49(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync51(join49(dir, "core", "serve", "src", "server.ts"))) return true;
62101
- const parent = dirname28(dir);
62196
+ if (existsSync52(join50(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync52(join50(dir, "core", "serve", "src", "server.ts"))) return true;
62197
+ const parent = dirname29(dir);
62102
62198
  if (parent === dir) return false;
62103
62199
  dir = parent;
62104
62200
  }
@@ -62128,8 +62224,8 @@ function materializeForPreview(appDir2, slug, displayName) {
62128
62224
  const forBuild = Object.fromEntries(
62129
62225
  Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
62130
62226
  );
62131
- const repoRoot2 = resolve40(fileURLToPath21(new URL("../../..", import.meta.url)));
62132
- const dest = join49(repoRoot2, "node_modules", ".cache", "himi-template-preview", slug);
62227
+ const repoRoot2 = resolve41(fileURLToPath21(new URL("../../..", import.meta.url)));
62228
+ const dest = join50(repoRoot2, "node_modules", ".cache", "himi-template-preview", slug);
62133
62229
  rmSync9(dest, { recursive: true, force: true });
62134
62230
  mkdirSync25(dest, { recursive: true });
62135
62231
  materializeSource(forBuild, displayName, dest, slug);
@@ -62137,8 +62233,8 @@ function materializeForPreview(appDir2, slug, displayName) {
62137
62233
  }
62138
62234
  async function appId(dir) {
62139
62235
  try {
62140
- const { readFileSync: readFileSync64 } = await import("node:fs");
62141
- const m = JSON.parse(readFileSync64(join49(dir, "himalaya.content.json"), "utf8"));
62236
+ const { readFileSync: readFileSync65 } = await import("node:fs");
62237
+ const m = JSON.parse(readFileSync65(join50(dir, "himalaya.content.json"), "utf8"));
62142
62238
  if (m.name) return m.name;
62143
62239
  } catch {
62144
62240
  }
@@ -62146,8 +62242,8 @@ async function appId(dir) {
62146
62242
  }
62147
62243
  async function contentVisibility(dir) {
62148
62244
  try {
62149
- const { readFileSync: readFileSync64 } = await import("node:fs");
62150
- const m = JSON.parse(readFileSync64(join49(dir, "himalaya.content.json"), "utf8"));
62245
+ const { readFileSync: readFileSync65 } = await import("node:fs");
62246
+ const m = JSON.parse(readFileSync65(join50(dir, "himalaya.content.json"), "utf8"));
62151
62247
  if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
62152
62248
  } catch {
62153
62249
  }
@@ -62348,7 +62444,7 @@ Seed your coding agent with \`himi agent-init\`. Portal: ${idx.portalUrl}`);
62348
62444
  return 0;
62349
62445
  }
62350
62446
  case "agent-init": {
62351
- const dir = resolve40(str5(flags.dir) ?? process.cwd());
62447
+ const dir = resolve41(str5(flags.dir) ?? process.cwd());
62352
62448
  const res = writeAgentContext(dir);
62353
62449
  print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
62354
62450
  return 0;
@@ -62434,7 +62530,7 @@ async function producedWidgetFamilies(dir) {
62434
62530
  let js;
62435
62531
  for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
62436
62532
  try {
62437
- js = readFileSync63(join49(outDir, candidate), "utf8");
62533
+ js = readFileSync64(join50(outDir, candidate), "utf8");
62438
62534
  break;
62439
62535
  } catch {
62440
62536
  }
@@ -62524,7 +62620,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62524
62620
  return 2;
62525
62621
  }
62526
62622
  const template = str5(flags.template);
62527
- const parentDir = resolve40(str5(flags.dir) ?? process.cwd());
62623
+ const parentDir = resolve41(str5(flags.dir) ?? process.cwd());
62528
62624
  if (template && flags.remote === true) {
62529
62625
  try {
62530
62626
  const res2 = await initFromRemoteTemplate(name, parentDir, template, client3());
@@ -62612,11 +62708,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62612
62708
  return 0;
62613
62709
  }
62614
62710
  if (sub === "publish") {
62615
- const appDir2 = resolve40(str5(flags.dir) ?? process.cwd());
62616
- const sourceDir = resolve40(str5(flags["source-dir"]) ?? appDir2);
62711
+ const appDir2 = resolve41(str5(flags.dir) ?? process.cwd());
62712
+ const sourceDir = resolve41(str5(flags["source-dir"]) ?? appDir2);
62617
62713
  let meta;
62618
62714
  try {
62619
- meta = JSON.parse(readFileSync63(join49(sourceDir, TEMPLATE_META_FILE), "utf8"));
62715
+ meta = JSON.parse(readFileSync64(join50(sourceDir, TEMPLATE_META_FILE), "utf8"));
62620
62716
  } catch {
62621
62717
  io.error(JSON.stringify({ error: `no ${TEMPLATE_META_FILE} in ${sourceDir} \u2014 a template must declare { title, description, tags } to be published`, hint: `add ${TEMPLATE_META_FILE} next to himalaya.content.json (or pass --source-dir <dir>)` }));
62622
62718
  return 2;
@@ -62626,7 +62722,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62626
62722
  return 2;
62627
62723
  }
62628
62724
  try {
62629
- const appearance = extractTemplateAppearance(JSON.parse(readFileSync63(join49(sourceDir, "tokens.json"), "utf8")));
62725
+ const appearance = extractTemplateAppearance(JSON.parse(readFileSync64(join50(sourceDir, "tokens.json"), "utf8")));
62630
62726
  meta = { ...appearance, ...meta };
62631
62727
  } catch {
62632
62728
  }
@@ -62638,13 +62734,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62638
62734
  const force = flags.force === true;
62639
62735
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
62640
62736
  const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
62641
- const out = mkdtempSync4(join49(tmpdir5(), "himi-template-"));
62737
+ const out = mkdtempSync4(join50(tmpdir5(), "himi-template-"));
62642
62738
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
62643
62739
  const outcome = await buildReleaseFromContent2(buildDir, out, {
62644
62740
  ...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
62645
62741
  collect: { lint: true, strict }
62646
62742
  });
62647
- const scaffoldSourceFindings = resolve40(sourceDir) === resolve40(appDir2) ? [] : [
62743
+ const scaffoldSourceFindings = resolve41(sourceDir) === resolve41(appDir2) ? [] : [
62648
62744
  ...tokenColorIssues(sourceDir),
62649
62745
  ...surfaceIssues(sourceDir, void 0, strict),
62650
62746
  ...fontIssues(sourceDir, strict),
@@ -62687,11 +62783,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62687
62783
  }));
62688
62784
  return 1;
62689
62785
  }
62690
- const iconPath = str5(flags.icon) ? resolve40(str5(flags.icon)) : templateIconPath(name);
62786
+ const iconPath = str5(flags.icon) ? resolve41(str5(flags.icon)) : templateIconPath(name);
62691
62787
  let iconHash;
62692
62788
  if (iconPath) {
62693
62789
  try {
62694
- const bytes2 = readFileSync63(iconPath);
62790
+ const bytes2 = readFileSync64(iconPath);
62695
62791
  payload.icon = bytes2.toString("base64");
62696
62792
  iconHash = createHash24("sha256").update(bytes2).digest("hex");
62697
62793
  } catch {
@@ -62890,7 +62986,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62890
62986
  const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
62891
62987
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
62892
62988
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
62893
- const out = mkdtempSync4(join49(tmpdir5(), "himi-validate-"));
62989
+ const out = mkdtempSync4(join50(tmpdir5(), "himi-validate-"));
62894
62990
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
62895
62991
  const outcome = await buildReleaseFromContent2(dir, out, {
62896
62992
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -62927,7 +63023,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
62927
63023
  const path = dpxSessionTokenPath();
62928
63024
  let raw;
62929
63025
  try {
62930
- raw = readFileSync63(path, "utf8");
63026
+ raw = readFileSync64(path, "utf8");
62931
63027
  } catch {
62932
63028
  throw new Error(`no DPX BO session at ${path}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
62933
63029
  }
@@ -63079,7 +63175,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63079
63175
  case "test": {
63080
63176
  const dir = contentDir(flags);
63081
63177
  const structuredOutput = flags.json === true || io.isTTY !== true;
63082
- if (existsSync51(join49(dir, "functions"))) {
63178
+ if (existsSync52(join50(dir, "functions"))) {
63083
63179
  const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
63084
63180
  const loaded = await loadFunctionsApp2(dir);
63085
63181
  const results = [];
@@ -63166,7 +63262,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63166
63262
  }
63167
63263
  }
63168
63264
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
63169
- const out = mkdtempSync4(join49(tmpdir5(), "himi-test-"));
63265
+ const out = mkdtempSync4(join50(tmpdir5(), "himi-test-"));
63170
63266
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
63171
63267
  const outcome = await buildReleaseFromContent2(dir, out, {
63172
63268
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -63211,7 +63307,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63211
63307
  io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
63212
63308
  return 2;
63213
63309
  }
63214
- const sources = collectWorkerSources2(join49(dir, "tier5-src"), screen.bundleName);
63310
+ const sources = collectWorkerSources2(join50(dir, "tier5-src"), screen.bundleName);
63215
63311
  if (!sources) {
63216
63312
  io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
63217
63313
  return 2;
@@ -63372,7 +63468,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63372
63468
  const sp = await runShotsPass2({
63373
63469
  descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
63374
63470
  tokens: outcome.tokens,
63375
- outDir: join49(dir, ".himi", "shots"),
63471
+ outDir: join50(dir, ".himi", "shots"),
63376
63472
  width: 390,
63377
63473
  layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
63378
63474
  ...budgetMs ? { budgetMs } : {},
@@ -63410,7 +63506,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63410
63506
  releaseId: result.releaseId,
63411
63507
  releasePayload: release,
63412
63508
  descriptors: attestedDescriptors,
63413
- screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join49(dir, ".himi", "shots", name)])),
63509
+ screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join50(dir, ".himi", "shots", name)])),
63414
63510
  coverage: {
63415
63511
  screens: crawledScreens.size,
63416
63512
  actionsDispatched: result.actions.exercised,
@@ -63499,7 +63595,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63499
63595
  return 2;
63500
63596
  }
63501
63597
  try {
63502
- const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync63(stateArg.replace(/^@/, ""), "utf8");
63598
+ const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync64(stateArg.replace(/^@/, ""), "utf8");
63503
63599
  injectedState = JSON.parse(raw);
63504
63600
  } catch (e) {
63505
63601
  io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
@@ -63514,7 +63610,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63514
63610
  return 2;
63515
63611
  }
63516
63612
  try {
63517
- const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync63(inputArg.replace(/^@/, ""), "utf8");
63613
+ const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync64(inputArg.replace(/^@/, ""), "utf8");
63518
63614
  const parsed = JSON.parse(raw);
63519
63615
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
63520
63616
  injectedInput = parsed;
@@ -63547,7 +63643,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63547
63643
  return 2;
63548
63644
  }
63549
63645
  } else if (typeof flags.width === "string" && flags.width) {
63550
- renderWidth = Number(flags.width);
63646
+ renderWidth = Math.round(Number(flags.width));
63551
63647
  if (!Number.isFinite(renderWidth) || renderWidth <= 0) {
63552
63648
  io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${str5(flags.width)}")` }));
63553
63649
  return 2;
@@ -63563,7 +63659,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63563
63659
  }
63564
63660
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
63565
63661
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
63566
- const out = mkdtempSync4(join49(tmpdir5(), "himi-render-"));
63662
+ const out = mkdtempSync4(join50(tmpdir5(), "himi-render-"));
63567
63663
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
63568
63664
  const outcome = await buildReleaseFromContent2(dir, out, {
63569
63665
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -63579,7 +63675,15 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
63579
63675
  let attestationPngFile;
63580
63676
  if (typeof flags.png === "string" && r.pngBase64) {
63581
63677
  pngFile = writePngFile(str5(flags.png), r.pngBase64);
63582
- attestationPngFile = writePngFile(join49(dir, ".himi", "shots", `${screenId}.png`), r.pngBase64);
63678
+ attestationPngFile = writePngFile(join50(dir, ".himi", "shots", `${screenId}.png`), r.pngBase64);
63679
+ }
63680
+ if (renderWidth !== void 0 && r.renderable) {
63681
+ recordRenderWidth(dir, {
63682
+ screenId,
63683
+ width: renderWidth,
63684
+ ...deviceName ? { device: deviceName } : {},
63685
+ ...pngFile ? { file: pngFile } : {}
63686
+ });
63583
63687
  }
63584
63688
  const legacyRender = {
63585
63689
  ok: r.renderable,
@@ -63884,7 +63988,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
63884
63988
  return 2;
63885
63989
  }
63886
63990
  const renamed = str5(flags.name);
63887
- const dest = resolve40(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
63991
+ const dest = resolve41(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
63888
63992
  const replace = flags.replace === true;
63889
63993
  const force = replace || flags.force === true;
63890
63994
  const linked = symlinkDestinationIssue(dest);
@@ -63892,8 +63996,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
63892
63996
  io.error(JSON.stringify(linked));
63893
63997
  return 1;
63894
63998
  }
63895
- if (existsSync51(dest)) {
63896
- if (!statSync13(dest).isDirectory()) {
63999
+ if (existsSync52(dest)) {
64000
+ if (!statSync12(dest).isDirectory()) {
63897
64001
  io.error(JSON.stringify({
63898
64002
  error: `${dest} exists and is not a directory`,
63899
64003
  hint: "pass --out/--name to land somewhere else, or remove the file"
@@ -63905,7 +64009,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
63905
64009
  io.error(JSON.stringify({ error: `${dest} already exists and is not empty`, hint: "pass --force to write into it anyway (merging, and naming what it keeps), --replace to restore exactly what was archived, or --out/--name to land somewhere else" }));
63906
64010
  return 1;
63907
64011
  }
63908
- if (replace && occupied && !existsSync51(join49(dest, "himalaya.content.json"))) {
64012
+ if (replace && occupied && !existsSync52(join50(dest, "himalaya.content.json"))) {
63909
64013
  io.error(JSON.stringify({
63910
64014
  error: `${dest} is not a content package \u2014 refusing to --replace it`,
63911
64015
  hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
@@ -63999,7 +64103,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
63999
64103
  const force = flags.force === true;
64000
64104
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
64001
64105
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
64002
- const out = mkdtempSync4(join49(tmpdir5(), "himi-push-"));
64106
+ const out = mkdtempSync4(join50(tmpdir5(), "himi-push-"));
64003
64107
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
64004
64108
  const outcome = await buildReleaseFromContent2(dir, out, {
64005
64109
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -64318,7 +64422,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64318
64422
  return 2;
64319
64423
  }
64320
64424
  try {
64321
- const res = writePack(resolve40(releaseDir), only, resolve40(str5(flags.out) ?? process.cwd()));
64425
+ const res = writePack(resolve41(releaseDir), only, resolve41(str5(flags.out) ?? process.cwd()));
64322
64426
  print({
64323
64427
  ok: true,
64324
64428
  app: res.app,
@@ -64367,7 +64471,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64367
64471
  }
64368
64472
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
64369
64473
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
64370
- const built = mkdtempSync4(join49(tmpdir5(), "himi-pack-"));
64474
+ const built = mkdtempSync4(join50(tmpdir5(), "himi-pack-"));
64371
64475
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
64372
64476
  const outcome = await buildReleaseFromContent2(dir, built, {
64373
64477
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -64389,7 +64493,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64389
64493
  return 1;
64390
64494
  }
64391
64495
  try {
64392
- const res = writePack(built, app, resolve40(str5(flags.out) ?? dir), sourceArchive);
64496
+ const res = writePack(built, app, resolve41(str5(flags.out) ?? dir), sourceArchive);
64393
64497
  print({
64394
64498
  ok: true,
64395
64499
  app: res.app,
@@ -64434,7 +64538,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64434
64538
  const { HIMI_PACKAGE_SOURCE_PATH: HIMI_PACKAGE_SOURCE_PATH2, isSafeAppId: isSafeAppId2, packageContents: packageContents2 } = await Promise.resolve().then(() => (init_himi_package(), himi_package_exports));
64435
64539
  let opened;
64436
64540
  try {
64437
- opened = openPackageFile2(resolve40(file));
64541
+ opened = openPackageFile2(resolve41(file));
64438
64542
  } catch (e) {
64439
64543
  io.error(JSON.stringify({ error: e.message }));
64440
64544
  return 1;
@@ -64447,7 +64551,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64447
64551
  io.error(JSON.stringify({
64448
64552
  ok: false,
64449
64553
  error: "app_source_not_in_package",
64450
- detail: `${resolve40(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
64554
+ detail: `${resolve41(file)} is a release package: it carries built output (screens, bundles, tokens) and no source`,
64451
64555
  hint: "re-pack it from the content package with `himi pack --dev`, or restore from the serve plane with `himi pull <app>`"
64452
64556
  }));
64453
64557
  return 1;
@@ -64470,7 +64574,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64470
64574
  return 1;
64471
64575
  }
64472
64576
  }
64473
- const dest = resolve40(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
64577
+ const dest = resolve41(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
64474
64578
  const issue2 = restoreDestinationIssue(dest, flags.force === true);
64475
64579
  if (issue2) {
64476
64580
  io.error(JSON.stringify(issue2));
@@ -64555,7 +64659,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64555
64659
  }
64556
64660
  try {
64557
64661
  const { openPackageFile: openPackageFile2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
64558
- const opened = openPackageFile2(resolve40(file));
64662
+ const opened = openPackageFile2(resolve41(file));
64559
64663
  if (!opened.validation.ok || !opened.header) {
64560
64664
  io.error(JSON.stringify({ error: "refusing to share an invalid package", issues: opened.validation.errors }));
64561
64665
  return 1;
@@ -64565,12 +64669,12 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64565
64669
  io.error(JSON.stringify({
64566
64670
  ok: false,
64567
64671
  error: "refusing to share a package that carries the app's source",
64568
- detail: `${resolve40(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
64672
+ detail: `${resolve41(file)} was packed with --dev, and a share link is public and unauthenticated \u2014 anyone with the URL could \`himi import\` your codebase`,
64569
64673
  hint: "share a release package instead (`himi pack` with no --dev), or hand the dev package over directly"
64570
64674
  }));
64571
64675
  return 1;
64572
64676
  }
64573
- const archive = readFileSync63(resolve40(file));
64677
+ const archive = readFileSync64(resolve41(file));
64574
64678
  const result = await client3().createPackageShare({
64575
64679
  app: opened.header.app,
64576
64680
  releaseId: opened.header.releaseId,
@@ -64607,10 +64711,10 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64607
64711
  const app = await appId(dir);
64608
64712
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
64609
64713
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
64610
- temp = mkdtempSync4(join49(tmpdir5(), "himi-run-build-"));
64714
+ temp = mkdtempSync4(join50(tmpdir5(), "himi-run-build-"));
64611
64715
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
64612
64716
  await buildReleaseFromContent2(dir, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {} });
64613
- source = join49(temp, app);
64717
+ source = join50(temp, app);
64614
64718
  }
64615
64719
  const chromeArg = str5(flags.chrome) ?? "preview";
64616
64720
  if (chromeArg !== "preview" && chromeArg !== "app") {
@@ -64635,9 +64739,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
64635
64739
  open: flags["no-open"] !== true
64636
64740
  });
64637
64741
  print({ ok: true, app: run2.app, url: run2.url, port: run2.port, plane: "browser" });
64638
- await new Promise((resolve41) => {
64742
+ await new Promise((resolve42) => {
64639
64743
  const stop = () => {
64640
- void run2.close().finally(() => resolve41());
64744
+ void run2.close().finally(() => resolve42());
64641
64745
  };
64642
64746
  process.once("SIGINT", stop);
64643
64747
  process.once("SIGTERM", stop);
@@ -65466,7 +65570,7 @@ ${label2}`);
65466
65570
  const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
65467
65571
  {
65468
65572
  const distDir = contentDir(flags);
65469
- if (existsSync51(join49(distDir, "himalaya.content.json"))) {
65573
+ if (existsSync52(join50(distDir, "himalaya.content.json"))) {
65470
65574
  const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
65471
65575
  const errors = issues.filter((i) => i.severity === "error");
65472
65576
  for (const i of issues.filter((i2) => i2.severity === "warning")) {
@@ -65736,7 +65840,7 @@ ${label2}`);
65736
65840
  const dpxPath = dpxSessionTokenPath();
65737
65841
  let dpx;
65738
65842
  try {
65739
- dpx = readFileSync63(dpxPath, "utf8").trim();
65843
+ dpx = readFileSync64(dpxPath, "utf8").trim();
65740
65844
  } catch {
65741
65845
  io.error(JSON.stringify({ error: `no dpx session at ${dpxPath} \u2014 run \`dpx auth login\` then \`dpx auth token > ${dpxPath}\` (dpx 2.x keeps its own state in ~/.dpx/auth.json and does NOT write the legacy session file), or omit --dpx` }));
65742
65846
  return 1;
@@ -66023,7 +66127,7 @@ ${report.ok ? "OK \u2014 data + serve plane reachable." : typeof report.hint ===
66023
66127
  const path = dpxSessionTokenPath();
66024
66128
  let raw;
66025
66129
  try {
66026
- raw = readFileSync63(path, "utf8");
66130
+ raw = readFileSync64(path, "utf8");
66027
66131
  } catch {
66028
66132
  io.error(JSON.stringify({ error: `no DPX BO session at ${path}` }));
66029
66133
  return 1;