@wix/himalaya-cli 0.1441.0 → 0.1442.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
@@ -18091,6 +18091,64 @@ function configuredTokensPath(dir) {
18091
18091
  }
18092
18092
  return {};
18093
18093
  }
18094
+ function tokenNumericIssues(tokens2, tokensPath = "tokens.json") {
18095
+ const issues = [];
18096
+ const isRecord3 = (v2) => v2 !== null && typeof v2 === "object" && !Array.isArray(v2);
18097
+ if (!isRecord3(tokens2)) return issues;
18098
+ const shown2 = (v2) => typeof v2 === "string" ? JSON.stringify(v2) : JSON.stringify(v2) ?? String(v2);
18099
+ const bad2 = (v2) => !(typeof v2 === "number" && Number.isInteger(v2));
18100
+ const check = (layer, where) => {
18101
+ if (!isRecord3(layer)) return;
18102
+ const loses = where ? `the ${where.slice(0, -1)} overlay is dropped on device and the base look is used instead` : 'iOS and Android reject the WHOLE tokens.json otherwise ("Theme unavailable" on iOS, the default palette and fonts on Android)';
18103
+ for (const { group, field, unit } of INTEGER_TOKEN_FIELDS) {
18104
+ const entries = layer[group];
18105
+ if (!isRecord3(entries)) continue;
18106
+ for (const [name, token] of Object.entries(entries)) {
18107
+ if (!isRecord3(token) || !(field in token)) continue;
18108
+ const value = token[field];
18109
+ if (!bad2(value)) continue;
18110
+ const path2 = `${where}${group}.${name}.${field}`;
18111
+ const fix = typeof value !== "number" || !Number.isFinite(value) ? "" : field === "duration" ? ` Durations are milliseconds (${value} \u2192 ${value < 10 ? Math.round(value * 1e3) : Math.round(value)}).` : ` Write ${Math.round(value)}.`;
18112
+ issues.push({
18113
+ screen: null,
18114
+ pass: "tokens",
18115
+ severity: "error",
18116
+ message: `${tokensPath}: ${path2} is ${shown2(value)} \u2014 it must be an integer (${unit}); ${loses}.${fix}`,
18117
+ path: path2
18118
+ });
18119
+ }
18120
+ }
18121
+ for (const group of INTEGER_TOKEN_MAPS) {
18122
+ const entries = layer[group];
18123
+ if (!isRecord3(entries)) continue;
18124
+ for (const [name, value] of Object.entries(entries)) {
18125
+ if (!bad2(value)) continue;
18126
+ const fix = typeof value === "number" && Number.isFinite(value) ? ` Write ${Math.round(value)}.` : "";
18127
+ issues.push({
18128
+ screen: null,
18129
+ pass: "tokens",
18130
+ severity: "error",
18131
+ message: `${tokensPath}: ${where}${group}.${name} is ${shown2(value)} \u2014 it must be an integer (points); ${loses}.${fix}`,
18132
+ path: `${where}${group}.${name}`
18133
+ });
18134
+ }
18135
+ }
18136
+ };
18137
+ check(tokens2, "");
18138
+ const idiom = tokens2.idiom;
18139
+ if (isRecord3(idiom)) {
18140
+ for (const [overlay, layer] of Object.entries(idiom)) check(layer, `idiom.${overlay}.`);
18141
+ }
18142
+ return issues;
18143
+ }
18144
+ function tokenNumericIssuesFor(dir) {
18145
+ const tokensPath = configuredTokensPath(dir).path ?? "tokens.json";
18146
+ try {
18147
+ return tokenNumericIssues(JSON.parse(readFileSync19(join19(dir, tokensPath), "utf8")), tokensPath);
18148
+ } catch {
18149
+ return [];
18150
+ }
18151
+ }
18094
18152
  function tokenColorIssues(dir, tokensPathOverride) {
18095
18153
  const issues = [];
18096
18154
  const error = (message) => issues.push({ screen: null, pass: "tokens", severity: "error", message });
@@ -18120,6 +18178,7 @@ function tokenColorIssues(dir, tokensPathOverride) {
18120
18178
  error(`${tokensPath}: must be an object`);
18121
18179
  return issues;
18122
18180
  }
18181
+ issues.push(...tokenNumericIssues(raw, tokensPath));
18123
18182
  const kitScheme = raw.kit?.colorScheme;
18124
18183
  if (kitScheme !== void 0 && kitScheme !== null && typeof kitScheme !== "string") {
18125
18184
  error(
@@ -18379,12 +18438,18 @@ function accentOnSurfacesFor(fgName, role, colors, declared, findings) {
18379
18438
  }
18380
18439
  }
18381
18440
  }
18382
- var AA_TEXT, CONTRAST_PAIRS, SCHEMES, channels, toHex2, mixHex, onLightSide;
18441
+ var INTEGER_TOKEN_FIELDS, INTEGER_TOKEN_MAPS, AA_TEXT, CONTRAST_PAIRS, SCHEMES, channels, toHex2, mixHex, onLightSide;
18383
18442
  var init_token_lint = __esm({
18384
18443
  "src/token-lint.ts"() {
18385
18444
  init_token_colors();
18386
18445
  init_idiom();
18387
18446
  init_brand_color_math();
18447
+ INTEGER_TOKEN_FIELDS = [
18448
+ { group: "typography", field: "size", unit: "points" },
18449
+ { group: "typography", field: "weight", unit: "a font weight such as 400 or 700" },
18450
+ { group: "motions", field: "duration", unit: "milliseconds" }
18451
+ ];
18452
+ INTEGER_TOKEN_MAPS = ["spacing", "radius"];
18388
18453
  AA_TEXT = 4.5;
18389
18454
  CONTRAST_PAIRS = [
18390
18455
  {
@@ -29906,6 +29971,67 @@ var init_capabilities = __esm({
29906
29971
  }
29907
29972
  });
29908
29973
 
29974
+ // src/authoring-unavailable.ts
29975
+ var authoring_unavailable_exports = {};
29976
+ __export(authoring_unavailable_exports, {
29977
+ AuthoringUnavailable: () => AuthoringUnavailable,
29978
+ authoringUnavailableFields: () => authoringUnavailableFields,
29979
+ isSourceCheckout: () => isSourceCheckout,
29980
+ namedAuthoringImport: () => namedAuthoringImport
29981
+ });
29982
+ import { existsSync as existsSync41 } from "node:fs";
29983
+ import { fileURLToPath as fileURLToPath16 } from "node:url";
29984
+ function namedAuthoringImport(module, load3) {
29985
+ return load3.catch((cause) => {
29986
+ throw new AuthoringUnavailable({ cause, module });
29987
+ });
29988
+ }
29989
+ function isSourceCheckout(env = process.env) {
29990
+ if (env.HIMI_OFF_REPO === "1") return false;
29991
+ return existsSync41(fileURLToPath16(new URL("../../../core/sdk/state/src/index.ts", import.meta.url)));
29992
+ }
29993
+ function causeMessage(cause) {
29994
+ if (cause === void 0 || cause === null) return void 0;
29995
+ if (cause instanceof Error) return cause.message;
29996
+ return String(cause);
29997
+ }
29998
+ function authoringUnavailableFields(err, context) {
29999
+ const cause = causeMessage(err.cause);
30000
+ const what = `the himi authoring runtime failed to load (himi v${context.version})` + (err.module ? ` \u2014 importing ${err.module}` : "") + (cause ? `: ${cause}` : "");
30001
+ const base = {
30002
+ version: context.version,
30003
+ portal: context.portal,
30004
+ ...cause ? { cause } : {},
30005
+ ...err.module ? { module: err.module } : {},
30006
+ sourceCheckout: context.sourceCheckout
30007
+ };
30008
+ if (context.sourceCheckout) {
30009
+ return {
30010
+ error: `${what}. This is a source checkout, so the usual cause is out-of-date dependencies, not the CLI \u2014 run \`yarn install\` at the repo root and retry.`,
30011
+ ...base,
30012
+ fix: "yarn install"
30013
+ };
30014
+ }
30015
+ return {
30016
+ error: `${what}. Off-repo this almost always means an out-of-date CLI, NOT a platform limitation \u2014 upgrade: \`npm i -g @wix/himalaya-cli@latest\`. If you meant to run in-repo, run from a monorepo checkout.`,
30017
+ ...base,
30018
+ upgrade: "npm i -g @wix/himalaya-cli@latest"
30019
+ };
30020
+ }
30021
+ var AuthoringUnavailable;
30022
+ var init_authoring_unavailable = __esm({
30023
+ "src/authoring-unavailable.ts"() {
30024
+ AuthoringUnavailable = class extends Error {
30025
+ module;
30026
+ constructor(options = {}) {
30027
+ super(`the himi authoring runtime failed to load${options.module ? ` (${options.module})` : ""}`, { cause: options.cause });
30028
+ this.name = "AuthoringUnavailable";
30029
+ this.module = options.module;
30030
+ }
30031
+ };
30032
+ }
30033
+ });
30034
+
29909
30035
  // src/site-analyze/site-view-metadata.ts
29910
30036
  function pages(site) {
29911
30037
  if (!site || typeof site !== "object" || !("pages" in site)) return [];
@@ -30404,13 +30530,13 @@ var init_l10n_catalog = __esm({
30404
30530
  });
30405
30531
 
30406
30532
  // ../../core/dev-server/src/l10n.ts
30407
- import { readFileSync as readFileSync42, existsSync as existsSync41 } from "node:fs";
30533
+ import { readFileSync as readFileSync42, existsSync as existsSync42 } from "node:fs";
30408
30534
  import { resolve as resolve31 } from "node:path";
30409
- import { fileURLToPath as fileURLToPath16 } from "node:url";
30535
+ import { fileURLToPath as fileURLToPath17 } from "node:url";
30410
30536
  function loadCatalog2(tag) {
30411
30537
  if (catalogCache.has(tag)) return catalogCache.get(tag);
30412
30538
  const path2 = resolve31(ROOT3, `tools/l10n/catalog.${tag}.json`);
30413
- const map = existsSync41(path2) ? sourceMap(parseCatalog(readFileSync42(path2, "utf8"))) : /* @__PURE__ */ new Map();
30539
+ const map = existsSync42(path2) ? sourceMap(parseCatalog(readFileSync42(path2, "utf8"))) : /* @__PURE__ */ new Map();
30414
30540
  catalogCache.set(tag, map);
30415
30541
  return map;
30416
30542
  }
@@ -30420,7 +30546,7 @@ function pickLocale(acceptLanguage) {
30420
30546
  for (const tag of tags) {
30421
30547
  if (tag === "en") continue;
30422
30548
  const path2 = resolve31(ROOT3, `tools/l10n/catalog.${tag}.json`);
30423
- if (existsSync41(path2)) return tag;
30549
+ if (existsSync42(path2)) return tag;
30424
30550
  }
30425
30551
  return null;
30426
30552
  }
@@ -30476,7 +30602,7 @@ var init_l10n = __esm({
30476
30602
  "../../core/dev-server/src/l10n.ts"() {
30477
30603
  init_l10n_strings();
30478
30604
  init_l10n_catalog();
30479
- ROOT3 = resolve31(fileURLToPath16(new URL("../../..", import.meta.url)));
30605
+ ROOT3 = resolve31(fileURLToPath17(new URL("../../..", import.meta.url)));
30480
30606
  catalogCache = /* @__PURE__ */ new Map();
30481
30607
  }
30482
30608
  });
@@ -30803,6 +30929,21 @@ function deriveNavigationConfig(app, bundleCtx) {
30803
30929
  if (app.dataSchema !== void 0) config.dataSchema = app.dataSchema;
30804
30930
  return config;
30805
30931
  }
30932
+ function withDevNetMocks(config, declared, fileMocks) {
30933
+ const rules = fileMocks?.rules;
30934
+ if (!Array.isArray(rules) || rules.length === 0 && fileMocks?.unmatched !== "fail") return config;
30935
+ if (declared?.enabled === false) return config;
30936
+ if (Array.isArray(declared?.rules) || declared?.scenarioRef !== void 0) return config;
30937
+ return {
30938
+ ...config,
30939
+ devGatewayConfig: {
30940
+ mode: fileMocks?.mode ?? "mock",
30941
+ ...fileMocks?.unmatched !== void 0 ? { unmatched: fileMocks.unmatched } : {},
30942
+ ...declared ?? {},
30943
+ rules
30944
+ }
30945
+ };
30946
+ }
30806
30947
  function mergeConfig(base, patch) {
30807
30948
  if (patch === null || typeof patch !== "object" || Array.isArray(patch)) return patch;
30808
30949
  const out2 = { ...base };
@@ -30824,8 +30965,9 @@ function withCompleteLinkables(cfg) {
30824
30965
  const list = cfg.linkableScreens;
30825
30966
  return Array.isArray(list) ? { ...cfg, linkableScreens: completeLinkableScreens(list) } : cfg;
30826
30967
  }
30827
- function buildAppConfigDocument(req, meta, override, bundleCtx) {
30828
- const merged = override ? withCompleteLinkables(mergeConfig(deriveNavigationConfig(meta, bundleCtx), override)) : deriveNavigationConfig(meta, bundleCtx);
30968
+ function buildAppConfigDocument(req, meta, override, bundleCtx, devNetMocks) {
30969
+ const derived = withDevNetMocks(deriveNavigationConfig(meta, bundleCtx), meta.devGateway, devNetMocks);
30970
+ const merged = override ? withCompleteLinkables(mergeConfig(derived, override)) : derived;
30829
30971
  const baseline = override ? { ...merged, wixCachePolicy: sanitizeServedOfflineQueue(merged.wixCachePolicy) } : merged;
30830
30972
  const acceptLanguage = req.headers["accept-language"];
30831
30973
  const locale = pickLocale(typeof acceptLanguage === "string" ? acceptLanguage : null);
@@ -30834,7 +30976,7 @@ function buildAppConfigDocument(req, meta, override, bundleCtx) {
30834
30976
  const etag = `"${createHash14("sha1").update(`${locale ?? "en"}:${body}`).digest("hex")}"`;
30835
30977
  return { config, body, etag, locale };
30836
30978
  }
30837
- function handleAppConfigRequest(req, res, meta, override, bundleCtx) {
30979
+ function handleAppConfigRequest(req, res, meta, override, bundleCtx, devNetMocks) {
30838
30980
  const appName2 = decodeURIComponent(
30839
30981
  (req.url ?? "").replace(/^\/v1\/app-config\//, "").split("?")[0]
30840
30982
  );
@@ -30843,7 +30985,7 @@ function handleAppConfigRequest(req, res, meta, override, bundleCtx) {
30843
30985
  res.end(JSON.stringify({ error: "unknown_app", appName: appName2 }));
30844
30986
  return;
30845
30987
  }
30846
- const { body, etag, locale } = buildAppConfigDocument(req, meta, override, bundleCtx);
30988
+ const { body, etag, locale } = buildAppConfigDocument(req, meta, override, bundleCtx, devNetMocks);
30847
30989
  if (req.headers["if-none-match"] === etag) {
30848
30990
  res.writeHead(304, { ETag: etag, "Cache-Control": "max-age=60, stale-while-revalidate=86400" });
30849
30991
  res.end();
@@ -31021,13 +31163,13 @@ var init_inject = __esm({
31021
31163
  // ../../core/dev-server/src/store.ts
31022
31164
  import { mkdirSync as mkdirSync21 } from "node:fs";
31023
31165
  import { dirname as dirname26, resolve as resolve32 } from "node:path";
31024
- import { fileURLToPath as fileURLToPath17 } from "node:url";
31166
+ import { fileURLToPath as fileURLToPath18 } from "node:url";
31025
31167
  import { createRequire } from "node:module";
31026
31168
  var nodeRequire, ROOT4, Store;
31027
31169
  var init_store2 = __esm({
31028
31170
  "../../core/dev-server/src/store.ts"() {
31029
31171
  nodeRequire = createRequire(import.meta.url);
31030
- ROOT4 = resolve32(fileURLToPath17(new URL("../../..", import.meta.url)));
31172
+ ROOT4 = resolve32(fileURLToPath18(new URL("../../..", import.meta.url)));
31031
31173
  Store = class {
31032
31174
  _db;
31033
31175
  dbPath;
@@ -35546,7 +35688,7 @@ var init_wix_member_login = __esm({
35546
35688
  });
35547
35689
 
35548
35690
  // ../../core/dev-server/src/wix-gateway.ts
35549
- import { readFileSync as readFileSync44, existsSync as existsSync42 } from "node:fs";
35691
+ import { readFileSync as readFileSync44, existsSync as existsSync43 } from "node:fs";
35550
35692
  function isSensitiveBodyName(name) {
35551
35693
  const segments = name.split(/[^A-Za-z0-9]+/).filter(Boolean);
35552
35694
  for (let i2 = 0; i2 < segments.length; i2++) {
@@ -35613,7 +35755,7 @@ function resolveNetMocks(fileMocks, appDeclared) {
35613
35755
  }
35614
35756
  function readNetMocksFile(path2) {
35615
35757
  try {
35616
- if (!existsSync42(path2)) return null;
35758
+ if (!existsSync43(path2)) return null;
35617
35759
  const raw = JSON.parse(readFileSync44(path2, "utf-8"));
35618
35760
  if (Array.isArray(raw)) return wixMockRuleErrors(raw).length ? null : { rules: raw };
35619
35761
  if (raw && typeof raw === "object") {
@@ -36574,13 +36716,13 @@ var init_stable_ids = __esm({
36574
36716
  // ../../core/dev-server/src/preview.ts
36575
36717
  import { spawn as spawn4 } from "node:child_process";
36576
36718
  import { createHash as createHash18 } from "node:crypto";
36577
- import { existsSync as existsSync43, createReadStream, statSync as statSync11, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync3 } from "node:fs";
36719
+ import { existsSync as existsSync44, createReadStream, statSync as statSync11, readFileSync as readFileSync46, renameSync as renameSync9, unlinkSync as unlinkSync3 } from "node:fs";
36578
36720
  import { homedir as homedir7, tmpdir as tmpdir2 } from "node:os";
36579
36721
  import { resolve as resolvePath, dirname as dirname27 } from "node:path";
36580
- import { fileURLToPath as fileURLToPath18 } from "node:url";
36722
+ import { fileURLToPath as fileURLToPath19 } from "node:url";
36581
36723
  function firstExisting(paths) {
36582
36724
  for (const p2 of paths) {
36583
- if (p2 && existsSync43(p2)) return p2;
36725
+ if (p2 && existsSync44(p2)) return p2;
36584
36726
  }
36585
36727
  return null;
36586
36728
  }
@@ -36619,7 +36761,7 @@ function isHimalayaAppWindow(w2) {
36619
36761
  }
36620
36762
  async function macosWinlistCommand() {
36621
36763
  const bin = macosWinlistBin();
36622
- if (existsSync43(bin)) return compiledWinlist(bin);
36764
+ if (existsSync44(bin)) return compiledWinlist(bin);
36623
36765
  if (macosWinlistCompileFailed) return interpretWinlist();
36624
36766
  if (!macosWinlistInFlight) {
36625
36767
  macosWinlistInFlight = buildMacosWinlist(bin).finally(() => {
@@ -36647,7 +36789,7 @@ async function buildMacosWinlist(bin) {
36647
36789
  unlinkSync3(staging);
36648
36790
  } catch {
36649
36791
  }
36650
- return existsSync43(bin) ? compiledWinlist(bin) : interpretWinlist();
36792
+ return existsSync44(bin) ? compiledWinlist(bin) : interpretWinlist();
36651
36793
  }
36652
36794
  return compiledWinlist(bin);
36653
36795
  }
@@ -37272,7 +37414,7 @@ function finalizeRecording(key3, rec) {
37272
37414
  } catch {
37273
37415
  }
37274
37416
  }
37275
- const sizeBytes = existsSync43(rec.localPath) ? statSync11(rec.localPath).size : 0;
37417
+ const sizeBytes = existsSync44(rec.localPath) ? statSync11(rec.localPath).size : 0;
37276
37418
  clips.set(rec.id, { path: rec.localPath, mime: rec.mime });
37277
37419
  recordings.delete(key3);
37278
37420
  return { sizeBytes };
@@ -37344,7 +37486,7 @@ async function handlePreviewClip(res, url) {
37344
37486
  const q2 = new URLSearchParams(url.split("?")[1] ?? "");
37345
37487
  const id = q2.get("id") ?? "";
37346
37488
  const clip3 = clips.get(id);
37347
- if (!clip3 || !existsSync43(clip3.path)) {
37489
+ if (!clip3 || !existsSync44(clip3.path)) {
37348
37490
  res.statusCode = 404;
37349
37491
  res.setHeader("content-type", "application/json");
37350
37492
  return void res.end(JSON.stringify({ error: "clip_not_found", id }));
@@ -37405,7 +37547,7 @@ var init_preview2 = __esm({
37405
37547
  SWIFT_BIN = process.env.HIMALAYA_SWIFT_PATH ?? "swift";
37406
37548
  SWIFTC_BIN = process.env.HIMALAYA_SWIFTC_PATH ?? "swiftc";
37407
37549
  SCREENCAPTURE_BIN = process.env.HIMALAYA_SCREENCAPTURE_PATH ?? "screencapture";
37408
- MACOS_WINLIST = resolvePath(dirname27(fileURLToPath18(import.meta.url)), "../scripts/macos-winshot.swift");
37550
+ MACOS_WINLIST = resolvePath(dirname27(fileURLToPath19(import.meta.url)), "../scripts/macos-winshot.swift");
37409
37551
  MACOS_WINLIST_BUILD_TIMEOUT_MS = 12e4;
37410
37552
  MACOS_WINLIST_INTERPRET_TIMEOUT_MS = 3e4;
37411
37553
  HIMALAYA_MAC_BUNDLE_ID = /^(com\.himalaya\.|com\.wix\.himi\.|dev\.himalaya\.)/i;
@@ -37462,7 +37604,7 @@ var init_tier4_integrity = __esm({
37462
37604
  });
37463
37605
 
37464
37606
  // ../../core/dev-server/src/tier4-verifier.ts
37465
- import { readFileSync as readFileSync47, existsSync as existsSync44 } from "node:fs";
37607
+ import { readFileSync as readFileSync47, existsSync as existsSync45 } from "node:fs";
37466
37608
  import { resolve as resolve34 } from "node:path";
37467
37609
  var TierFourVerifier;
37468
37610
  var init_tier4_verifier = __esm({
@@ -37480,7 +37622,7 @@ var init_tier4_verifier = __esm({
37480
37622
  const expected = this.expectedSri(bundleId, relPath);
37481
37623
  if (!expected) return { ok: true };
37482
37624
  const path2 = resolve34(this.tier4Root, bundleId, relPath);
37483
- const bytes2 = providedBytes ?? (existsSync44(path2) ? readFileSync47(path2) : null);
37625
+ const bytes2 = providedBytes ?? (existsSync45(path2) ? readFileSync47(path2) : null);
37484
37626
  if (!bytes2) return { ok: false, reason: "file not found" };
37485
37627
  if (computeSri(bytes2) !== expected) return { ok: false, reason: "sri mismatch" };
37486
37628
  return { ok: true };
@@ -37489,7 +37631,7 @@ var init_tier4_verifier = __esm({
37489
37631
  let cached3 = this.cache.get(bundleId);
37490
37632
  if (cached3) return cached3;
37491
37633
  const manifestPath = resolve34(this.tier4Root, bundleId, "manifest.json");
37492
- if (!existsSync44(manifestPath)) return void 0;
37634
+ if (!existsSync45(manifestPath)) return void 0;
37493
37635
  const manifest = JSON.parse(readFileSync47(manifestPath, "utf8"));
37494
37636
  cached3 = { integrity: parseManifestIntegrity(manifest) };
37495
37637
  this.cache.set(bundleId, cached3);
@@ -37557,7 +37699,7 @@ var init_net_mocks_rollover = __esm({
37557
37699
  import { readFileSync as readFileSync48 } from "node:fs";
37558
37700
  import { homedir as homedir8 } from "node:os";
37559
37701
  import { dirname as dirname28, join as join43 } from "node:path";
37560
- import { fileURLToPath as fileURLToPath19 } from "node:url";
37702
+ import { fileURLToPath as fileURLToPath20 } from "node:url";
37561
37703
  function readJson2(path2) {
37562
37704
  try {
37563
37705
  return JSON.parse(readFileSync48(path2, "utf8"));
@@ -37566,7 +37708,7 @@ function readJson2(path2) {
37566
37708
  }
37567
37709
  }
37568
37710
  function ledgerDevServerPort(tenant) {
37569
- const here = dirname28(fileURLToPath19(import.meta.url));
37711
+ const here = dirname28(fileURLToPath20(import.meta.url));
37570
37712
  const ledger = readJson2(join43(here, "..", "..", "..", "tools", "dev-cli", "ports.json"));
37571
37713
  const port = ledger?.apps?.[tenant]?.devServer;
37572
37714
  return typeof port === "number" ? port : void 0;
@@ -132088,12 +132230,12 @@ var init_png_egress = __esm({
132088
132230
  });
132089
132231
 
132090
132232
  // ../../core/dev-server/src/render-fonts.ts
132091
- import { existsSync as existsSync45, readFileSync as readFileSync49 } from "node:fs";
132233
+ import { existsSync as existsSync46, readFileSync as readFileSync49 } from "node:fs";
132092
132234
  import { extname, join as join44 } from "node:path";
132093
132235
  function servedFontFaces(appDir3, tokens2) {
132094
132236
  try {
132095
132237
  const policyPath = join44(appDir3, "fonts.json");
132096
- const policy = existsSync45(policyPath) ? JSON.parse(readFileSync49(policyPath, "utf8")) : {};
132238
+ const policy = existsSync46(policyPath) ? JSON.parse(readFileSync49(policyPath, "utf8")) : {};
132097
132239
  let plan = planFonts(tokens2, policy);
132098
132240
  if (!hasVendoredFloor()) plan = { ...plan, families: plan.families.filter((f2) => !isHostProvided(f2.name)) };
132099
132241
  if (plan.families.length === 0) return void 0;
@@ -132371,7 +132513,7 @@ var init_motion_flags = __esm({
132371
132513
  // ../../core/dev-server/src/kits.ts
132372
132514
  import { readdirSync as readdirSync24, readFileSync as readFileSync51 } from "node:fs";
132373
132515
  import { resolve as resolve36, join as join45 } from "node:path";
132374
- import { fileURLToPath as fileURLToPath20 } from "node:url";
132516
+ import { fileURLToPath as fileURLToPath21 } from "node:url";
132375
132517
  function listKits() {
132376
132518
  return readdirSync24(CATALOG).filter((f2) => f2.endsWith(".json")).map((f2) => {
132377
132519
  const { tokens: tokens2, ...meta } = JSON.parse(readFileSync51(join45(CATALOG, f2), "utf8"));
@@ -132389,7 +132531,7 @@ function readKit(id) {
132389
132531
  var ROOT5, CATALOG;
132390
132532
  var init_kits = __esm({
132391
132533
  "../../core/dev-server/src/kits.ts"() {
132392
- ROOT5 = resolve36(fileURLToPath20(new URL("../../..", import.meta.url)));
132534
+ ROOT5 = resolve36(fileURLToPath21(new URL("../../..", import.meta.url)));
132393
132535
  CATALOG = join45(ROOT5, "stdlib/design-kits");
132394
132536
  }
132395
132537
  });
@@ -133118,7 +133260,7 @@ __export(config_exports2, {
133118
133260
  });
133119
133261
  import { mkdirSync as mkdirSync22, readFileSync as readFileSync52, writeFileSync as writeFileSync19 } from "node:fs";
133120
133262
  import { dirname as dirname29, join as join46, resolve as resolve37 } from "node:path";
133121
- import { fileURLToPath as fileURLToPath21 } from "node:url";
133263
+ import { fileURLToPath as fileURLToPath22 } from "node:url";
133122
133264
  function strip(line) {
133123
133265
  const h2 = line.indexOf("#");
133124
133266
  return (h2 >= 0 ? line.slice(0, h2) : line).replace(/\s+$/, "");
@@ -133292,7 +133434,7 @@ var init_config2 = __esm({
133292
133434
  "../../core/serve-control/src/config.ts"() {
133293
133435
  init_errors();
133294
133436
  init_contract();
133295
- REPO_ROOT6 = resolve37(dirname29(fileURLToPath21(import.meta.url)), "../../..");
133437
+ REPO_ROOT6 = resolve37(dirname29(fileURLToPath22(import.meta.url)), "../../..");
133296
133438
  OPERATIONAL_OVERLAY_KEYS = /* @__PURE__ */ new Set([
133297
133439
  "wixCachePolicy",
133298
133440
  "telemetryConfig",
@@ -133360,10 +133502,10 @@ var init_config2 = __esm({
133360
133502
  // ../../core/dev-server/src/index.ts
133361
133503
  import { createServer as createServer3 } from "node:http";
133362
133504
  import { readFile, stat } from "node:fs/promises";
133363
- import { readFileSync as readFileSync53, existsSync as existsSync46, watch, mkdirSync as mkdirSync23, rmSync as rmSync11 } from "node:fs";
133505
+ import { readFileSync as readFileSync53, existsSync as existsSync47, watch, mkdirSync as mkdirSync23, rmSync as rmSync11 } from "node:fs";
133364
133506
  import { basename as basename10, dirname as dirname30, extname as extname2, join as join47, relative as relative8, resolve as resolve38, normalize as normalize3, sep as sep10 } from "node:path";
133365
133507
  import { createHash as createHash21, randomUUID as randomUUID5 } from "node:crypto";
133366
- import { fileURLToPath as fileURLToPath22, pathToFileURL as pathToFileURL6 } from "node:url";
133508
+ import { fileURLToPath as fileURLToPath23, pathToFileURL as pathToFileURL6 } from "node:url";
133367
133509
  function readLogicBundle(read, tier5Dir, name) {
133368
133510
  return read(tier5Dir ?? TIER5_ROOT2, name) ?? (tier5Dir && tier5Dir !== TIER5_ROOT2 ? read(TIER5_ROOT2, name) : void 0);
133369
133511
  }
@@ -133423,6 +133565,9 @@ function readAppTokens(state) {
133423
133565
  return null;
133424
133566
  }
133425
133567
  }
133568
+ function deviceNetMocks(state) {
133569
+ return state.deviceNetMocks ?? null;
133570
+ }
133426
133571
  function effectiveAppConfigOverride(state) {
133427
133572
  let gitOverlay;
133428
133573
  if (state.app) {
@@ -133488,7 +133633,7 @@ function handleL10nRequest(req, res, state) {
133488
133633
  return sendJson(res, 404, { error: "unknown_app", app }, cors);
133489
133634
  }
133490
133635
  const path2 = resolve38(state.app.dir, "l10n", `${tag}.json`);
133491
- if (!existsSync46(path2)) {
133636
+ if (!existsSync47(path2)) {
133492
133637
  res.writeHead(204, cors);
133493
133638
  res.end();
133494
133639
  return;
@@ -133629,7 +133774,8 @@ async function handleBootRequest(req, res, state) {
133629
133774
  req,
133630
133775
  state.app.meta,
133631
133776
  effectiveAppConfigOverride(state),
133632
- bundleCtx
133777
+ bundleCtx,
133778
+ deviceNetMocks(state)
133633
133779
  );
133634
133780
  const tokenDocument = effectiveAppTokens(req, state);
133635
133781
  const homeScreenId = config.homeScreenId ?? state.app.meta.homeScreenId ?? null;
@@ -134415,7 +134561,7 @@ async function primeAppDependencyWatchers(state) {
134415
134561
  const current = state.app;
134416
134562
  if (!current) return;
134417
134563
  const entry = resolve38(current.dir, "dev/index.ts");
134418
- if (!existsSync46(entry)) return;
134564
+ if (!existsSync47(entry)) return;
134419
134565
  mkdirSync23(HMR_TMP_DIR, { recursive: true });
134420
134566
  const outfile = resolve38(HMR_TMP_DIR, `${current.name}-deps-${++appReloadSeq}.mjs`);
134421
134567
  try {
@@ -136259,6 +136405,9 @@ function createDevServer(opts = {}) {
136259
136405
  const seeded = applyNetMocks(state.wix, resolved2.mocks);
136260
136406
  state.wixSeededOn = todayYmd();
136261
136407
  state.wixSeededFromApp = resolved2.source !== "file";
136408
+ if (resolved2.source === "file" && state.app && existsSync47(resolve38(state.app.dir, "himalaya.content.json"))) {
136409
+ state.deviceNetMocks = resolved2.mocks;
136410
+ }
136262
136411
  const from = resolved2.source === "file" ? netMocksPath : `${state.appName} devGateway.rules`;
136263
136412
  console.error(`[himalaya-dev] net-mocks: seeded ${seeded.rules} rule(s), mode=${seeded.mode} from ${from}`);
136264
136413
  }
@@ -136517,7 +136666,7 @@ function createDevServer(opts = {}) {
136517
136666
  // Through a tenant host's proxy, the nav bundle routes back through that host, as screens do.
136518
136667
  serverBaseUrl: forwardedBaseUrl(req) ?? state.serverBaseUrl,
136519
136668
  bundleIntegrity: (name) => bundleIntegritySync(name, state.tier5Dir)
136520
- });
136669
+ }, deviceNetMocks(state));
136521
136670
  }
136522
136671
  {
136523
136672
  const appRoutes = state.app?.module.dataRoutes;
@@ -136773,7 +136922,7 @@ var init_src6 = __esm({
136773
136922
  init_kits();
136774
136923
  init_widgets();
136775
136924
  init_descriptor_postprocess();
136776
- ROOT6 = resolve38(fileURLToPath22(new URL("../../..", import.meta.url)));
136925
+ ROOT6 = resolve38(fileURLToPath23(new URL("../../..", import.meta.url)));
136777
136926
  setPngFontCss(async (tokens2, idiomContext) => await pngFontFaceCss(tokens2) + (idiomContext ? await idiomFontFaceCss(idiomContext) : ""));
136778
136927
  setPngEgress(startEgressProxy);
136779
136928
  TIER3_ROOT = resolve38(ROOT6, "core/dev-server/web");
@@ -140069,9 +140218,9 @@ __export(build_exports2, {
140069
140218
  withoutDevOnlyAppConfig: () => withoutDevOnlyAppConfig
140070
140219
  });
140071
140220
  import { createHash as createHash25 } from "node:crypto";
140072
- import { readFileSync as readFileSync54, readdirSync as readdirSync25, existsSync as existsSync47 } from "node:fs";
140221
+ import { readFileSync as readFileSync54, readdirSync as readdirSync25, existsSync as existsSync48 } from "node:fs";
140073
140222
  import { dirname as dirname31, join as join48, resolve as resolve39 } from "node:path";
140074
- import { fileURLToPath as fileURLToPath23 } from "node:url";
140223
+ import { fileURLToPath as fileURLToPath24 } from "node:url";
140075
140224
  import { createRequire as createRequire2 } from "node:module";
140076
140225
  import { execFileSync as execFileSync4 } from "node:child_process";
140077
140226
  import { gzipSync as gzipSync2 } from "node:zlib";
@@ -140113,7 +140262,7 @@ function l10nLintOptions(locale, appDir3) {
140113
140262
  const catalog3 = /* @__PURE__ */ new Set();
140114
140263
  for (const tag of tags) {
140115
140264
  const path2 = join48(appDir3, "l10n", `${tag}.json`);
140116
- if (!existsSync47(path2)) continue;
140265
+ if (!existsSync48(path2)) continue;
140117
140266
  try {
140118
140267
  const parsed = JSON.parse(readFileSync54(path2, "utf8"));
140119
140268
  for (const m2 of Object.values(parsed.messages ?? {})) {
@@ -140295,7 +140444,7 @@ function shellSha(root = REPO_ROOT7) {
140295
140444
  function isMonorepoCheckout(dir) {
140296
140445
  try {
140297
140446
  const top = execFileSync4("git", ["rev-parse", "--show-toplevel"], { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
140298
- return top.length > 0 && existsSync47(join48(top, "core", "schema", "core.proto"));
140447
+ return top.length > 0 && existsSync48(join48(top, "core", "schema", "core.proto"));
140299
140448
  } catch {
140300
140449
  return false;
140301
140450
  }
@@ -140546,9 +140695,9 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140546
140695
  const tier5Dir = opts.tier5Dir ?? TIER5_DIR;
140547
140696
  const bundlePath = (name) => {
140548
140697
  const own5 = join48(tier5Dir, `${name}.bundle.js`);
140549
- if (existsSync47(own5)) return own5;
140698
+ if (existsSync48(own5)) return own5;
140550
140699
  const shared = join48(TIER5_DIR, `${name}.bundle.js`);
140551
- return resolve39(tier5Dir) !== TIER5_DIR && existsSync47(shared) ? shared : void 0;
140700
+ return resolve39(tier5Dir) !== TIER5_DIR && existsSync48(shared) ? shared : void 0;
140552
140701
  };
140553
140702
  const bundleDirFor = (name) => {
140554
140703
  const path2 = name ? bundlePath(name) : void 0;
@@ -140709,11 +140858,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140709
140858
  };
140710
140859
  checkRegistry(preloaded.module.actions);
140711
140860
  const contentManifestPath2 = join48(preloaded.dir, "himalaya.content.json");
140712
- const contentManifest = existsSync47(contentManifestPath2) ? JSON.parse(readFileSync54(contentManifestPath2, "utf8")) : void 0;
140861
+ const contentManifest = existsSync48(contentManifestPath2) ? JSON.parse(readFileSync54(contentManifestPath2, "utf8")) : void 0;
140713
140862
  let screenMetadata = parseScreenMetadata(contentManifest?.screens);
140714
140863
  if (contentManifest?.shell === "brandy" && screenMetadata) {
140715
140864
  const provisioningPath2 = join48(preloaded.dir, "provisioning.json");
140716
- if (existsSync47(provisioningPath2)) screenMetadata = siteViewMetadataForBuild(screenMetadata, JSON.parse(readFileSync54(provisioningPath2, "utf8")).site);
140865
+ if (existsSync48(provisioningPath2)) screenMetadata = siteViewMetadataForBuild(screenMetadata, JSON.parse(readFileSync54(provisioningPath2, "utf8")).site);
140717
140866
  }
140718
140867
  await store.reset(app);
140719
140868
  const bundles = {};
@@ -140773,7 +140922,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140773
140922
  if (store.putDoc) {
140774
140923
  for (const [name, file2] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
140775
140924
  const path2 = join48(preloaded.dir, file2);
140776
- if (!existsSync47(path2)) continue;
140925
+ if (!existsSync48(path2)) continue;
140777
140926
  const bytes2 = readFileSync54(path2);
140778
140927
  if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
140779
140928
  throw new Error(`${file2} must be non-empty and at most ${MAX_AUTHORING_DOC_BYTES} bytes to ship with a release.`);
@@ -140833,7 +140982,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
140833
140982
  const fontWarnings = [];
140834
140983
  try {
140835
140984
  const appTokens = readTokensForLint(preloaded) ?? {};
140836
- const policy = existsSync47(join48(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync54(join48(preloaded.dir, "fonts.json"), "utf8")) : {};
140985
+ const policy = existsSync48(join48(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync54(join48(preloaded.dir, "fonts.json"), "utf8")) : {};
140837
140986
  fontPlan = planFonts(appTokens, policy);
140838
140987
  } catch (err) {
140839
140988
  throw new Error(
@@ -141405,7 +141554,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
141405
141554
  const sources = {};
141406
141555
  for (const definition of config.functions.functions) {
141407
141556
  const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join48(preloaded.dir, "functions", `${definition.name}${extension}`));
141408
- const source = candidates.find((candidate) => existsSync47(candidate));
141557
+ const source = candidates.find((candidate) => existsSync48(candidate));
141409
141558
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
141410
141559
  sources[definition.name] = readFileSync54(source, "utf8");
141411
141560
  }
@@ -141479,7 +141628,7 @@ var init_build3 = __esm({
141479
141628
  BAKE_OFFLINE_BASE = "http://himalaya-bake.invalid";
141480
141629
  KNOWN_ICON_NAMES = [...ICON_NAMES].sort();
141481
141630
  KNOWN_ICONS = new Set(KNOWN_ICON_NAMES);
141482
- REPO_ROOT7 = resolve39(dirname31(fileURLToPath23(import.meta.url)), "../..");
141631
+ REPO_ROOT7 = resolve39(dirname31(fileURLToPath24(import.meta.url)), "../..");
141483
141632
  TIER5_DIR = join48(REPO_ROOT7, "core/dev-server/tier5-bundles");
141484
141633
  requireFromHere = createRequire2(import.meta.url);
141485
141634
  SOURCEMAP_ON_DEMAND_PATH = join48(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
@@ -142043,7 +142192,7 @@ __export(build_changes_exports, {
142043
142192
  diffTokens: () => diffTokens,
142044
142193
  headline: () => headline
142045
142194
  });
142046
- import { existsSync as existsSync48, readdirSync as readdirSync26, readFileSync as readFileSync55 } from "node:fs";
142195
+ import { existsSync as existsSync49, readdirSync as readdirSync26, readFileSync as readFileSync55 } from "node:fs";
142047
142196
  import { join as join49 } from "node:path";
142048
142197
  function componentsOf(descriptor) {
142049
142198
  const out2 = /* @__PURE__ */ new Map();
@@ -142109,7 +142258,7 @@ function diffTokens(before, after) {
142109
142258
  return out2;
142110
142259
  }
142111
142260
  function describeChanges(oldTree, newTree, diff, opts = {}) {
142112
- if (!existsSync48(oldTree) || !existsSync48(newTree)) return { items: [], more: 0 };
142261
+ if (!existsSync49(oldTree) || !existsSync49(newTree)) return { items: [], more: 0 };
142113
142262
  const all = [];
142114
142263
  const before = screensIn(oldTree);
142115
142264
  const after = screensIn(newTree);
@@ -142200,7 +142349,7 @@ var init_build_changes = __esm({
142200
142349
  });
142201
142350
 
142202
142351
  // src/studio-timeline.ts
142203
- import { existsSync as existsSync49, readFileSync as readFileSync56 } from "node:fs";
142352
+ import { existsSync as existsSync50, readFileSync as readFileSync56 } from "node:fs";
142204
142353
  import { join as join50 } from "node:path";
142205
142354
  function stateOf(view) {
142206
142355
  const j2 = view.journal[0];
@@ -142269,7 +142418,7 @@ function validFrame(f2) {
142269
142418
  }
142270
142419
  function readTimeline(dir) {
142271
142420
  const file2 = join50(dir, TIMELINE_FILE);
142272
- if (!existsSync49(file2)) return [];
142421
+ if (!existsSync50(file2)) return [];
142273
142422
  const out2 = [];
142274
142423
  for (const line of readFileSync56(file2, "utf8").split("\n")) {
142275
142424
  if (!line.trim()) continue;
@@ -142295,7 +142444,7 @@ function appendFrame(dir, view, reveal = null) {
142295
142444
  const frames = readTimeline(dir);
142296
142445
  const last = frames[frames.length - 1];
142297
142446
  if (last && last.v === view.v && !reveal) {
142298
- if (!existsSync49(join50(dir, TIMELINE_JS))) writeTimelineJs(dir, frames);
142447
+ if (!existsSync50(join50(dir, TIMELINE_JS))) writeTimelineJs(dir, frames);
142299
142448
  return frames.length;
142300
142449
  }
142301
142450
  let prev = null;
@@ -142367,7 +142516,7 @@ __export(studio_exports, {
142367
142516
  writeStudioRecord: () => writeStudioRecord
142368
142517
  });
142369
142518
  import { createHash as createHash26 } from "node:crypto";
142370
- import { existsSync as existsSync50, readdirSync as readdirSync27, readFileSync as readFileSync57, realpathSync as realpathSync8, statSync as statSync12 } from "node:fs";
142519
+ import { existsSync as existsSync51, readdirSync as readdirSync27, readFileSync as readFileSync57, realpathSync as realpathSync8, statSync as statSync12 } from "node:fs";
142371
142520
  import { basename as basename11, extname as extname3, join as join51, relative as relative9, resolve as resolve40, sep as sep11 } from "node:path";
142372
142521
  import { pathToFileURL as pathToFileURL7 } from "node:url";
142373
142522
  function realInside(dir, abs) {
@@ -142393,7 +142542,7 @@ function archiveFile(dir, memory, abs) {
142393
142542
  if (size === 0) return null;
142394
142543
  const key3 = relative9(dir, abs);
142395
142544
  const hit = memory.files?.[key3];
142396
- if (hit && hit.size === size && hit.mtimeMs === mtimeMs && hit.ino === ino && existsSync50(join51(dir, HISTORY_DIR, `${hit.sha}.${hit.ext}`))) {
142545
+ if (hit && hit.size === size && hit.mtimeMs === mtimeMs && hit.ino === ino && existsSync51(join51(dir, HISTORY_DIR, `${hit.sha}.${hit.ext}`))) {
142397
142546
  return { sha: hit.sha, ext: hit.ext, file: `${hit.sha}.${hit.ext}` };
142398
142547
  }
142399
142548
  let archived;
@@ -142414,7 +142563,7 @@ function loadMemory(dir, now) {
142414
142563
  function observeShots(dir, memory, now) {
142415
142564
  const shotsDir = join51(dir, ".himi", "shots");
142416
142565
  const seen = /* @__PURE__ */ new Set();
142417
- const files = existsSync50(shotsDir) ? readdirSync27(shotsDir).filter((f2) => /\.(png|jpe?g)$/i.test(f2)).sort() : [];
142566
+ const files = existsSync51(shotsDir) ? readdirSync27(shotsDir).filter((f2) => /\.(png|jpe?g)$/i.test(f2)).sort() : [];
142418
142567
  for (const f2 of files) {
142419
142568
  const id = basename11(f2, extname3(f2));
142420
142569
  const archived = archiveFile(dir, memory, join51(shotsDir, f2));
@@ -142432,7 +142581,7 @@ function observeShots(dir, memory, now) {
142432
142581
  memory.shots[id] = { ...prev, present: true };
142433
142582
  }
142434
142583
  }
142435
- if (existsSync50(shotsDir)) {
142584
+ if (existsSync51(shotsDir)) {
142436
142585
  for (const [id, shot] of Object.entries(memory.shots)) if (!seen.has(id) && shot.present) memory.shots[id] = { ...shot, present: false };
142437
142586
  }
142438
142587
  if (memory.timeline.length > MAX_TIMELINE) memory.timeline = memory.timeline.slice(-MAX_TIMELINE);
@@ -142458,7 +142607,7 @@ function appIdentity(dir) {
142458
142607
  }
142459
142608
  function testRuns(dir) {
142460
142609
  const att = join51(dir, ".himi", "attestations");
142461
- if (!existsSync50(att)) return [];
142610
+ if (!existsSync51(att)) return [];
142462
142611
  const runs = [];
142463
142612
  for (const f2 of readdirSync27(att)) {
142464
142613
  if (!f2.endsWith(".json") || f2 === "latest.json") continue;
@@ -142479,7 +142628,7 @@ function testRuns(dir) {
142479
142628
  }
142480
142629
  function siteHome(dir) {
142481
142630
  for (const pages2 of [join51(dir, ".himi", "business-book", "evidence", "pages"), join51(dir, "evidence", "pages")]) {
142482
- if (!existsSync50(pages2)) continue;
142631
+ if (!existsSync51(pages2)) continue;
142483
142632
  const home = readdirSync27(pages2).filter((f2) => /^home.*\.(png|jpe?g)$/i.test(f2)).sort()[0];
142484
142633
  if (home) return join51(pages2, home);
142485
142634
  }
@@ -142685,7 +142834,7 @@ function writeBoard(dir, now) {
142685
142834
  }
142686
142835
  function refreshStudio(dir, now = /* @__PURE__ */ new Date()) {
142687
142836
  try {
142688
- if (!existsSync50(join51(dir, STUDIO_PAGE))) return { refreshed: false };
142837
+ if (!existsSync51(join51(dir, STUDIO_PAGE))) return { refreshed: false };
142689
142838
  return { refreshed: true, view: writeBoard(dir, now.toISOString()) };
142690
142839
  } catch {
142691
142840
  return { refreshed: false };
@@ -143368,7 +143517,7 @@ __export(preflight_exports, {
143368
143517
  parseStoreConfig: () => parseStoreConfig,
143369
143518
  requireEnv: () => requireEnv
143370
143519
  });
143371
- import { existsSync as existsSync51, readFileSync as readFileSync59 } from "node:fs";
143520
+ import { existsSync as existsSync52, readFileSync as readFileSync59 } from "node:fs";
143372
143521
  import { isAbsolute as isAbsolute4, relative as relative10, resolve as resolve42 } from "node:path";
143373
143522
  function isInsideRepo(p2) {
143374
143523
  const rel = relative10(REPO_ROOT3, resolve42(p2));
@@ -143425,7 +143574,7 @@ function parseStoreConfig(text9) {
143425
143574
  }
143426
143575
  function loadStoreConfig(app) {
143427
143576
  const p2 = storeConfigPath(app);
143428
- if (!existsSync51(p2)) {
143577
+ if (!existsSync52(p2)) {
143429
143578
  throw new Error(`No store config at ${p2}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
143430
143579
  }
143431
143580
  return parseStoreConfig(readFileSync59(p2, "utf8"));
@@ -150157,7 +150306,7 @@ var init_customer_signing_inspect = __esm({
150157
150306
  });
150158
150307
 
150159
150308
  // src/push-onboarding.ts
150160
- import { existsSync as existsSync52, mkdirSync as mkdirSync24, readFileSync as readFileSync60, statSync as statSync13, writeFileSync as writeFileSync20, chmodSync as chmodSync2 } from "node:fs";
150309
+ import { existsSync as existsSync53, mkdirSync as mkdirSync24, readFileSync as readFileSync60, statSync as statSync13, writeFileSync as writeFileSync20, chmodSync as chmodSync2 } from "node:fs";
150161
150310
  import { basename as basename12, dirname as dirname32, join as join52, resolve as resolve43 } from "node:path";
150162
150311
  function readJson5(path2) {
150163
150312
  try {
@@ -150169,7 +150318,7 @@ function readJson5(path2) {
150169
150318
  }
150170
150319
  function pushInputsFromContent(dir) {
150171
150320
  const root = resolve43(dir);
150172
- if (!existsSync52(join52(root, "himalaya.content.json"))) return { initialized: false };
150321
+ if (!existsSync53(join52(root, "himalaya.content.json"))) return { initialized: false };
150173
150322
  const content = readJson5(join52(root, "himalaya.content.json"));
150174
150323
  const provisioning = readJson5(join52(root, "provisioning.json"));
150175
150324
  const native = provisioning.native ?? {};
@@ -150301,7 +150450,7 @@ function buildPushSetupBody(i2, keys) {
150301
150450
  }
150302
150451
  function readPushOnboarding(dir) {
150303
150452
  const path2 = join52(resolve43(dir), PUSH_ONBOARDING_PATH);
150304
- if (!existsSync52(path2)) return { version: 1 };
150453
+ if (!existsSync53(path2)) return { version: 1 };
150305
150454
  const parsed = readJson5(path2);
150306
150455
  return { version: 1, ...parsed };
150307
150456
  }
@@ -150336,7 +150485,7 @@ function recordPushDeferral(dir, d2) {
150336
150485
  }
150337
150486
  function clearPushDeferral(dir) {
150338
150487
  const path2 = join52(resolve43(dir), PUSH_ONBOARDING_PATH);
150339
- if (!existsSync52(path2)) return;
150488
+ if (!existsSync53(path2)) return;
150340
150489
  const { push: _dropped, ...rest } = readPushOnboarding(dir);
150341
150490
  writeFile(dir, { ...rest, version: 1 });
150342
150491
  }
@@ -150404,7 +150553,7 @@ var signing_inspect_exports = {};
150404
150553
  __export(signing_inspect_exports, {
150405
150554
  runSigningInspect: () => runSigningInspect
150406
150555
  });
150407
- import { existsSync as existsSync53, readFileSync as readFileSync61, statSync as statSync14 } from "node:fs";
150556
+ import { existsSync as existsSync54, readFileSync as readFileSync61, statSync as statSync14 } from "node:fs";
150408
150557
  import { isAbsolute as isAbsolute5, resolve as resolve44 } from "node:path";
150409
150558
  function fail4(io2, code, fields = {}) {
150410
150559
  io2.error(JSON.stringify({ ok: false, code, ...fields }));
@@ -150494,7 +150643,7 @@ async function runSigningInspect(pos, flags, io2, deps = {}) {
150494
150643
  } catch (error) {
150495
150644
  return fail4(io2, "signing_inspect_key_inside_repo", { error: error.message });
150496
150645
  }
150497
- if (!existsSync53(certPath) || !existsSync53(profilePath2)) {
150646
+ if (!existsSync54(certPath) || !existsSync54(profilePath2)) {
150498
150647
  return fail4(io2, "signing_inspect_local_assets_unreadable", { error: "cannot read --cert-file or --profile-file" });
150499
150648
  }
150500
150649
  if (statSync14(certPath).size > 1048576 || statSync14(profilePath2).size > 1048576) {
@@ -151237,7 +151386,7 @@ __export(pack_exports, {
151237
151386
  });
151238
151387
  import { createHash as createHash29 } from "node:crypto";
151239
151388
  import { deflateRawSync, inflateRawSync } from "node:zlib";
151240
- import { existsSync as existsSync54, mkdirSync as mkdirSync25, readFileSync as readFileSync63, readdirSync as readdirSync28, rmSync as rmSync12, statSync as statSync15, writeFileSync as writeFileSync21 } from "node:fs";
151389
+ import { existsSync as existsSync55, mkdirSync as mkdirSync25, readFileSync as readFileSync63, readdirSync as readdirSync28, rmSync as rmSync12, statSync as statSync15, writeFileSync as writeFileSync21 } from "node:fs";
151241
151390
  import { dirname as dirname33, join as join54, resolve as resolve46 } from "node:path";
151242
151391
  function writeZip(entries) {
151243
151392
  const sorted2 = entries.slice().sort((a2, b2) => a2.path < b2.path ? -1 : a2.path > b2.path ? 1 : 0);
@@ -151332,10 +151481,10 @@ function inflateEntry(buf, entry) {
151332
151481
  return bytes2;
151333
151482
  }
151334
151483
  function readIf(path2) {
151335
- return existsSync54(path2) && statSync15(path2).isFile() ? readFileSync63(path2) : null;
151484
+ return existsSync55(path2) && statSync15(path2).isFile() ? readFileSync63(path2) : null;
151336
151485
  }
151337
151486
  function listDir(dir) {
151338
- return existsSync54(dir) ? readdirSync28(dir).filter((f2) => statSync15(join54(dir, f2)).isFile()) : [];
151487
+ return existsSync55(dir) ? readdirSync28(dir).filter((f2) => statSync15(join54(dir, f2)).isFile()) : [];
151339
151488
  }
151340
151489
  function gatherReleaseEntries(appDir3) {
151341
151490
  const manifestPath = join54(appDir3, HIMI_PACKAGE_MANIFEST_PATH);
@@ -151414,7 +151563,7 @@ function packRelease(releaseRoot, app, out2, opts = {}) {
151414
151563
  const appDir3 = join54(resolve46(releaseRoot), app);
151415
151564
  const { all, header, skipped } = buildEntries(appDir3, app, opts);
151416
151565
  const buf = writeZip(all);
151417
- const isDir2 = existsSync54(out2) && statSync15(out2).isDirectory();
151566
+ const isDir2 = existsSync55(out2) && statSync15(out2).isDirectory();
151418
151567
  const outFile = isDir2 ? join54(resolve46(out2), packageFileName(app, header.releaseId)) : resolve46(out2);
151419
151568
  mkdirSync25(dirname33(outFile), { recursive: true });
151420
151569
  writeFileSync21(outFile, buf);
@@ -151431,11 +151580,11 @@ function resolvePackageDirDest(outDir, app, releaseId) {
151431
151580
  }
151432
151581
  };
151433
151582
  const replaceable = (dir) => {
151434
- if (!existsSync54(dir)) return true;
151583
+ if (!existsSync55(dir)) return true;
151435
151584
  if (!statSync15(dir).isDirectory()) return false;
151436
151585
  return readdirSync28(dir).length === 0 || packagedApp(dir) === app;
151437
151586
  };
151438
- if (existsSync54(outDir) && !statSync15(outDir).isDirectory()) {
151587
+ if (existsSync55(outDir) && !statSync15(outDir).isDirectory()) {
151439
151588
  throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
151440
151589
  }
151441
151590
  if (replaceable(outDir)) return outDir;
@@ -151496,7 +151645,7 @@ function openPackageDir(dir) {
151496
151645
  else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync63(childAbs));
151497
151646
  }
151498
151647
  };
151499
- if (!existsSync54(root)) throw new Error(`no such package directory: ${root}`);
151648
+ if (!existsSync55(root)) throw new Error(`no such package directory: ${root}`);
151500
151649
  walk2("");
151501
151650
  const manifestBytes = entries.get(HIMI_PACKAGE_MANIFEST_PATH);
151502
151651
  if (manifestBytes) {
@@ -151581,7 +151730,7 @@ __export(app_source_exports, {
151581
151730
  zipAppSource: () => zipAppSource
151582
151731
  });
151583
151732
  import { createHash as createHash30 } from "node:crypto";
151584
- import { readdirSync as readdirSync29, lstatSync as lstatSync15, readFileSync as readFileSync64, mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, existsSync as existsSync55, rmSync as rmSync13, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
151733
+ import { readdirSync as readdirSync29, lstatSync as lstatSync15, readFileSync as readFileSync64, mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, existsSync as existsSync56, rmSync as rmSync13, rmdirSync as rmdirSync2, unlinkSync as unlinkSync4 } from "node:fs";
151585
151734
  import { join as join55, resolve as resolve47, sep as sep13 } from "node:path";
151586
151735
  import { createRequire as createRequire3 } from "node:module";
151587
151736
  import { deflateRawSync as deflateRawSync2 } from "node:zlib";
@@ -151597,7 +151746,7 @@ function walkSourceTree(dir, file2, skip, enter = () => {
151597
151746
  continue;
151598
151747
  }
151599
151748
  if (st2.isDirectory()) {
151600
- if (isDeniedSourceDir(name, relDir) || existsSync55(join55(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
151749
+ if (isDeniedSourceDir(name, relDir) || existsSync56(join55(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
151601
151750
  else walk2(rel);
151602
151751
  continue;
151603
151752
  }
@@ -151765,7 +151914,7 @@ function writeAppSource(entries, destDir) {
151765
151914
  return written;
151766
151915
  }
151767
151916
  function staleSourcePaths(entries, destDir) {
151768
- if (!existsSync55(destDir)) return [];
151917
+ if (!existsSync56(destDir)) return [];
151769
151918
  const archived = new Set(entries.map((e2) => e2.path));
151770
151919
  const stale = [];
151771
151920
  walkSourceTree(destDir, (archivePath) => {
@@ -151821,7 +151970,7 @@ function removeStaleSource(entries, destDir) {
151821
151970
  const segments = entry.path.split("/");
151822
151971
  for (let i2 = 1; i2 < segments.length; i2++) needed.add(segments.slice(0, i2).join("/"));
151823
151972
  }
151824
- if (existsSync55(root)) pruneEmptyDirs(root, "", needed, removed);
151973
+ if (existsSync56(root)) pruneEmptyDirs(root, "", needed, removed);
151825
151974
  return removed.sort();
151826
151975
  }
151827
151976
  function pruneEmptyDirs(root, rel, needed, removed) {
@@ -151909,7 +152058,7 @@ __export(run_watch_exports, {
151909
152058
  watchedContentDir: () => watchedContentDir,
151910
152059
  writeRunRecord: () => writeRunRecord
151911
152060
  });
151912
- import { closeSync as closeSync4, constants as constants2, existsSync as existsSync56, fstatSync, lstatSync as lstatSync16, statSync as statSync16, readdirSync as readdirSync30, mkdirSync as mkdirSync27, openSync as openSync4, readFileSync as readFileSync65, realpathSync as realpathSync9, renameSync as renameSync10, rmSync as rmSync14, writeFileSync as writeFileSync23, watch as fsWatch } from "node:fs";
152061
+ import { closeSync as closeSync4, constants as constants2, existsSync as existsSync57, fstatSync, lstatSync as lstatSync16, statSync as statSync16, readdirSync as readdirSync30, mkdirSync as mkdirSync27, openSync as openSync4, readFileSync as readFileSync65, realpathSync as realpathSync9, renameSync as renameSync10, rmSync as rmSync14, writeFileSync as writeFileSync23, watch as fsWatch } from "node:fs";
151913
152062
  import { randomUUID as randomUUID6 } from "node:crypto";
151914
152063
  import { extname as extname4, join as join56, resolve as resolve48, sep as sep14 } from "node:path";
151915
152064
  function diffReleases(prev, next) {
@@ -152016,7 +152165,7 @@ function watchedContentDir(source) {
152016
152165
  if (!source || /^https?:\/\//i.test(source)) return null;
152017
152166
  const dir = resolve48(source);
152018
152167
  try {
152019
- return statSync16(dir).isDirectory() && existsSync56(join56(dir, "himalaya.content.json")) ? dir : null;
152168
+ return statSync16(dir).isDirectory() && existsSync57(join56(dir, "himalaya.content.json")) ? dir : null;
152020
152169
  } catch {
152021
152170
  return null;
152022
152171
  }
@@ -152671,7 +152820,7 @@ __export(milestones_exports, {
152671
152820
  });
152672
152821
  import { createHash as createHash33, randomUUID as randomUUID7 } from "node:crypto";
152673
152822
  import { spawn as spawn5 } from "node:child_process";
152674
- import { closeSync as closeSync5, existsSync as existsSync57, lstatSync as lstatSync19, readFileSync as readFileSync69, statSync as statSync17 } from "node:fs";
152823
+ import { closeSync as closeSync5, existsSync as existsSync58, lstatSync as lstatSync19, readFileSync as readFileSync69, statSync as statSync17 } from "node:fs";
152675
152824
  import { createServer as createServer4 } from "node:net";
152676
152825
  import { basename as basename15, dirname as dirname34, isAbsolute as isAbsolute6, join as join60, relative as relative11, resolve as resolve49, sep as sep15 } from "node:path";
152677
152826
  function homeShotPath(dir, home) {
@@ -152784,7 +152933,7 @@ function autoPictureGate(dir) {
152784
152933
  }
152785
152934
  async function homePictureAtValidate(dir, opts) {
152786
152935
  if (!opts.ok) return { skipped: "validate found errors, so the picture was left as it is" };
152787
- if (!existsSync57(join60(dir, "himalaya.content.json"))) return { skipped: "not a content package" };
152936
+ if (!existsSync58(join60(dir, "himalaya.content.json"))) return { skipped: "not a content package" };
152788
152937
  const env = opts.env ?? process.env;
152789
152938
  if (ciSet(env)) return { skipped: "the CI environment variable is set" };
152790
152939
  if (env.NODE_TEST_CONTEXT) return { skipped: "running under `node --test`" };
@@ -152854,7 +153003,7 @@ function stillBuilding(dir, image, now) {
152854
153003
  }
152855
153004
  }
152856
153005
  function firstLookBeforeOwnPostcard(dir, image, now) {
152857
- if (!image || !existsSync57(image) || initDivergence(dir).state !== "diverged") return void 0;
153006
+ if (!image || !existsSync58(image) || initDivergence(dir).state !== "diverged") return void 0;
152858
153007
  return journal(dir, "first-look", withHomeCaveat(yourFirstLookMessage(dir), homeCaveat(dir, image)), { image, ...now ? { now } : {} });
152859
153008
  }
152860
153009
  function afterRenderPng(dir, input) {
@@ -152919,13 +153068,13 @@ function testChangeNote(headline2, change) {
152919
153068
  }
152920
153069
  function afterTestRun(dir, input) {
152921
153070
  const firstLook = firstLookBeforeOwnPostcard(dir, input.homeShot, input.now);
152922
- const shot = input.homeShot && existsSync57(input.homeShot) ? input.homeShot : void 0;
153071
+ const shot = input.homeShot && existsSync58(input.homeShot) ? input.homeShot : void 0;
152923
153072
  const caveat = shot ? homeCaveat(dir, shot) : void 0;
152924
153073
  const counts = testPostcardMessage(input);
152925
153074
  const headline2 = caveat ? `${counts} But ${caveat}.` : counts;
152926
153075
  const postcard = journal(dir, "test", headline2, {
152927
153076
  ref: input.runId,
152928
- ...input.homeShot && existsSync57(input.homeShot) ? { image: input.homeShot } : {},
153077
+ ...input.homeShot && existsSync58(input.homeShot) ? { image: input.homeShot } : {},
152929
153078
  ...input.now ? { now: input.now } : {},
152930
153079
  unlessUnchanged: true,
152931
153080
  changeNote: (change) => testChangeNote(headline2, change)
@@ -152968,7 +153117,7 @@ function draftPictureGap(input) {
152968
153117
  if (!input.home) return { reason: "the app's dev/index.ts names no literal homeScreenId, so there is no home screen to picture" };
152969
153118
  if (!input.homeShot) return { reason: "the homeScreenId does not name a file under .himi/shots" };
152970
153119
  const render = `himi render ${shellQuote(input.home)} --png${contentArg(input.content)}`;
152971
- if (!existsSync57(input.homeShot)) return { reason: "there is no home shot yet", render };
153120
+ if (!existsSync58(input.homeShot)) return { reason: "there is no home shot yet", render };
152972
153121
  if (input.sourceChangedAtMs === void 0) return { reason: "the source's last change could not be read, so the home shot cannot be shown to be current", render };
152973
153122
  if (!shotIsCurrent(input.homeShot, input.sourceChangedAtMs)) return { reason: "the home shot is older than the last source edit, so it is not a picture of this draft", render };
152974
153123
  return null;
@@ -153046,7 +153195,7 @@ function draftChangeNote(dir, input) {
153046
153195
  if (!previous) return void 0;
153047
153196
  const shaOf = (i2) => i2 && typeof i2 === "object" && typeof i2.sha256 === "string" ? i2.sha256 : void 0;
153048
153197
  const had = Array.isArray(previous.images) ? previous.images.map(shaOf).find(Boolean) : void 0;
153049
- const has = input.picture && existsSync57(input.picture) ? sha256Of2(input.picture) : void 0;
153198
+ const has = input.picture && existsSync58(input.picture) ? sha256Of2(input.picture) : void 0;
153050
153199
  if (had && has) parts.push(had === has ? "the home screen looks the same" : "the home screen changed");
153051
153200
  else if (has) parts.push("a home picture this time");
153052
153201
  else return void 0;
@@ -153112,7 +153261,7 @@ function homeShotForPostcard(dir, opts = {}) {
153112
153261
  const shot = homeShotPath(dir, home);
153113
153262
  if (!shot) return { skipped: "the homeScreenId does not name a file under .himi/shots" };
153114
153263
  const render = `\`himi render ${shellQuote(home)} --png\``;
153115
- if (!existsSync57(shot)) return { skipped: `no home shot yet \u2014 ${render} makes one, and the next postcard carries it` };
153264
+ if (!existsSync58(shot)) return { skipped: `no home shot yet \u2014 ${render} makes one, and the next postcard carries it` };
153116
153265
  let changed;
153117
153266
  try {
153118
153267
  changed = newestSourceChangeMs(dir);
@@ -153192,7 +153341,7 @@ function liveWatchRunning(dir, isAlive = pidAlive, now) {
153192
153341
  }
153193
153342
  function watchReminder(dir, opts = {}) {
153194
153343
  try {
153195
- if (!existsSync57(join60(dir, "himalaya.content.json"))) return void 0;
153344
+ if (!existsSync58(join60(dir, "himalaya.content.json"))) return void 0;
153196
153345
  const nowDate = opts.now ?? /* @__PURE__ */ new Date();
153197
153346
  const live3 = liveWatch(dir, opts.isAlive, nowDate);
153198
153347
  const now = nowDate.getTime();
@@ -153748,17 +153897,17 @@ __export(template_recommend_exports, {
153748
153897
  recommendTemplates: () => recommendTemplates,
153749
153898
  verticalsFromBook: () => verticalsFromBook
153750
153899
  });
153751
- import { existsSync as existsSync58, readFileSync as readFileSync71 } from "node:fs";
153900
+ import { existsSync as existsSync59, readFileSync as readFileSync71 } from "node:fs";
153752
153901
  import { join as join62 } from "node:path";
153753
153902
  function verticalsFromBook(path2) {
153754
- const dir = existsSync58(join62(path2, "book.json")) || existsSync58(join62(path2, "provisioning.overlay.json")) ? path2 : join62(path2, ".himi", "business-book");
153903
+ const dir = existsSync59(join62(path2, "book.json")) || existsSync59(join62(path2, "provisioning.overlay.json")) ? path2 : join62(path2, ".himi", "business-book");
153755
153904
  const overlay = join62(dir, "provisioning.overlay.json");
153756
- if (existsSync58(overlay)) {
153905
+ if (existsSync59(overlay)) {
153757
153906
  const v2 = JSON.parse(readFileSync71(overlay, "utf8")).installedVerticals;
153758
153907
  if (Array.isArray(v2) && v2.length) return v2.filter((x2) => typeof x2 === "string");
153759
153908
  }
153760
153909
  const book = join62(dir, "book.json");
153761
- if (existsSync58(book)) {
153910
+ if (existsSync59(book)) {
153762
153911
  const probes = JSON.parse(readFileSync71(book, "utf8")).probes;
153763
153912
  if (Array.isArray(probes)) return installedFromProbes(probes);
153764
153913
  }
@@ -154176,7 +154325,7 @@ __export(base44_types_exports, {
154176
154325
  renderBase44Types: () => renderBase44Types,
154177
154326
  writeBase44Types: () => writeBase44Types
154178
154327
  });
154179
- import { existsSync as existsSync59, mkdirSync as mkdirSync28, readFileSync as readFileSync72, writeFileSync as writeFileSync25 } from "node:fs";
154328
+ import { existsSync as existsSync60, mkdirSync as mkdirSync28, readFileSync as readFileSync72, writeFileSync as writeFileSync25 } from "node:fs";
154180
154329
  import { dirname as dirname35, join as join63 } from "node:path";
154181
154330
  function logicalName(spec) {
154182
154331
  return (isAdoptedEntity(spec) ? spec.base44Name : spec.name) ?? "";
@@ -154256,7 +154405,7 @@ async function writeBase44Types(dir, app) {
154256
154405
  if (!list?.length) throw new Base44TypesError("no_base44_entities", "config.ts declares no base44.entities \u2014 nothing to type. Declare them (or run `himi base44 adopt`) first.");
154257
154406
  const text9 = renderBase44Types(list, app);
154258
154407
  const path2 = join63(dir, BASE44_TYPES_PATH);
154259
- const changed = !existsSync59(path2) || readFileSync72(path2, "utf8") !== text9;
154408
+ const changed = !existsSync60(path2) || readFileSync72(path2, "utf8") !== text9;
154260
154409
  if (changed) {
154261
154410
  mkdirSync28(dirname35(path2), { recursive: true });
154262
154411
  writeFileSync25(path2, text9);
@@ -154265,7 +154414,7 @@ async function writeBase44Types(dir, app) {
154265
154414
  }
154266
154415
  async function base44TypesIssues(dir, app, strict) {
154267
154416
  const path2 = join63(dir, BASE44_TYPES_PATH);
154268
- if (!existsSync59(path2)) return [];
154417
+ if (!existsSync60(path2)) return [];
154269
154418
  let list;
154270
154419
  try {
154271
154420
  list = await declaredEntities(dir);
@@ -154408,13 +154557,13 @@ __export(eject_exports, {
154408
154557
  EJECTABLE: () => EJECTABLE,
154409
154558
  ejectModule: () => ejectModule
154410
154559
  });
154411
- import { existsSync as existsSync60, mkdirSync as mkdirSync29, readFileSync as readFileSync73, writeFileSync as writeFileSync26 } from "node:fs";
154560
+ import { existsSync as existsSync61, mkdirSync as mkdirSync29, readFileSync as readFileSync73, writeFileSync as writeFileSync26 } from "node:fs";
154412
154561
  import { dirname as dirname36, join as join64, relative as relative12, resolve as resolve50, sep as sep16 } from "node:path";
154413
154562
  function locate(repoRootOrCwd, mod) {
154414
154563
  const inRepo = resolve50(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
154415
- if (existsSync60(inRepo)) return { path: inRepo, form: "source" };
154564
+ if (existsSync61(inRepo)) return { path: inRepo, form: "source" };
154416
154565
  const dist = resolve50(repoRootOrCwd, `node_modules/@wix/himalaya/dist/${mod}.mjs`);
154417
- if (existsSync60(dist)) return { path: dist, form: "bundle" };
154566
+ if (existsSync61(dist)) return { path: dist, form: "bundle" };
154418
154567
  return null;
154419
154568
  }
154420
154569
  function specifiersFor(mod) {
@@ -154459,7 +154608,7 @@ function ejectModule(opts) {
154459
154608
  writeFileSync26(target, banner + normalized);
154460
154609
  const rewired = [];
154461
154610
  for (const f2 of files) {
154462
- if (!existsSync60(f2)) continue;
154611
+ if (!existsSync61(f2)) continue;
154463
154612
  const before = readFileSync73(f2, "utf8");
154464
154613
  let after = before;
154465
154614
  let rel = relative12(dirname36(f2), target).split(sep16).join("/").replace(/\.tsx?$/, ".js");
@@ -154580,7 +154729,7 @@ var init_app_map = __esm({
154580
154729
  });
154581
154730
 
154582
154731
  // src/wix-writes.ts
154583
- import { existsSync as existsSync61, readFileSync as readFileSync74 } from "node:fs";
154732
+ import { existsSync as existsSync62, readFileSync as readFileSync74 } from "node:fs";
154584
154733
  import { join as join65 } from "node:path";
154585
154734
  function isProvenRead(method, path2) {
154586
154735
  if (/[#\x00-\x1F\x7F]/.test(path2)) return false;
@@ -154700,7 +154849,7 @@ function parseDataAccess(text9, from) {
154700
154849
  function readDataAccess(dir) {
154701
154850
  for (const name of ["SPEC.md", "MOBILE-UX.md"]) {
154702
154851
  const p2 = join65(dir, name);
154703
- if (!existsSync61(p2)) continue;
154852
+ if (!existsSync62(p2)) continue;
154704
154853
  let text9;
154705
154854
  try {
154706
154855
  text9 = readFileSync74(p2, "utf8");
@@ -154819,11 +154968,11 @@ __export(test_exports, {
154819
154968
  scopeDescriptors: () => scopeDescriptors,
154820
154969
  writeRecordedMocks: () => writeRecordedMocks
154821
154970
  });
154822
- import { existsSync as existsSync62, mkdirSync as mkdirSync30, readFileSync as readFileSync75, writeFileSync as writeFileSync27 } from "node:fs";
154971
+ import { existsSync as existsSync63, mkdirSync as mkdirSync30, readFileSync as readFileSync75, writeFileSync as writeFileSync27 } from "node:fs";
154823
154972
  import { join as join66, resolve as resolve51 } from "node:path";
154824
154973
  function readTestConfig(dir) {
154825
154974
  const p2 = resolve51(dir, TEST_CONFIG_FILE);
154826
- if (!existsSync62(p2)) return {};
154975
+ if (!existsSync63(p2)) return {};
154827
154976
  let parsed;
154828
154977
  try {
154829
154978
  parsed = JSON.parse(readFileSync75(p2, "utf8"));
@@ -154894,7 +155043,7 @@ function readNetRules(path2) {
154894
155043
  function defaultNetRules(dir) {
154895
155044
  for (const rel of ["dev/net-mocks.json", "tests/net-mocks.json"]) {
154896
155045
  const p2 = resolve51(dir, rel);
154897
- if (existsSync62(p2)) {
155046
+ if (existsSync63(p2)) {
154898
155047
  const rules = readNetRules(p2);
154899
155048
  if (rules.length) return { rules, from: rel };
154900
155049
  }
@@ -155328,7 +155477,17 @@ async function runCrawl(opts) {
155328
155477
  const unreachedWrites = targets.flatMap((d2) => unreachedNativeWrites(d2.screenId, d2.bundleJs, inventory));
155329
155478
  const plan = readDataAccess(opts.dir);
155330
155479
  const writeFindings = unapprovedWriteFindings([...inventory, ...unreachedWrites], plan);
155331
- const all = [...results.flatMap((r2) => r2.findings), ...hostileFindings, ...deepFindings, ...journeyFindings, ...edgeFindings, ...relationFindings, ...writeFindings].filter((f2) => {
155480
+ const tokenFindings = tokenNumericIssuesFor(opts.dir).map((issue2) => ({
155481
+ screen: TOKENS_FINDING_SCREEN,
155482
+ trigger: "boot",
155483
+ invariant: "token-type-invalid",
155484
+ severity: "error",
155485
+ // The token path keeps each finding's stable id distinct (findingId hashes `at`).
155486
+ ...issue2.path ? { at: issue2.path } : {},
155487
+ message: issue2.message,
155488
+ hint: "Fix the value in the tokens file; `himi validate` reports the same finding."
155489
+ }));
155490
+ const all = [...results.flatMap((r2) => r2.findings), ...hostileFindings, ...deepFindings, ...journeyFindings, ...edgeFindings, ...relationFindings, ...writeFindings, ...tokenFindings].filter((f2) => {
155332
155491
  if (f2.invariant === "no-request-issued" && !f2.axis && fetchProven.has(f2.screen)) {
155333
155492
  const by = fetchProven.get(f2.screen);
155334
155493
  if (!retired.some((x2) => x2.screen === f2.screen)) retired.push({ screen: f2.screen, from: by.from, params: by.params });
@@ -155338,7 +155497,7 @@ async function runCrawl(opts) {
155338
155497
  }).filter(keep);
155339
155498
  const failures = all.filter((f2) => f2.severity === "error");
155340
155499
  const warnings = all.filter((f2) => f2.severity === "warning");
155341
- const failedScreens = new Set(failures.map((f2) => f2.screen));
155500
+ const failedScreens = new Set(failures.map((f2) => f2.screen).filter((screen) => screen !== TOKENS_FINDING_SCREEN));
155342
155501
  const blockedReasons = [];
155343
155502
  if (unknownScreens.length) blockedReasons.push(`not in this release: ${unknownScreens.join(", ")}`);
155344
155503
  if (notCrawled.length) blockedReasons.push(`${notCrawled.length} screen(s) skipped because they fail \`himi validate\` \u2014 fix those first`);
@@ -155412,9 +155571,12 @@ function formatReport(r2) {
155412
155571
  for (const platform of ["ios", "android"]) {
155413
155572
  const summary2 = r2.nativeDecode[platform];
155414
155573
  if (!summary2) continue;
155415
- out2.push("unavailable" in summary2 ? `native decode ${platform}: unavailable \u2014 ${summary2.reason}` : `native decode ${platform}: ${summary2.checked} checked, ${summary2.failed} failed in ${r2.nativeDecode.wallMs}ms`);
155574
+ out2.push("unavailable" in summary2 ? `native decode ${platform}: unavailable \u2014 ${summary2.reason}` : `native decode ${platform}: ${summary2.checked} checked, ${summary2.failed} failed${summary2.tokens ? `, tokens.json ${summary2.tokens}` : ""} in ${r2.nativeDecode.wallMs}ms`);
155416
155575
  }
155417
155576
  }
155577
+ if (r2.skippedPlatforms?.length) {
155578
+ out2.push(`SKIPPED native platforms (NOT checked, not passing): ${r2.skippedPlatforms.map((skip) => skip.platform).join(", ")}`);
155579
+ }
155418
155580
  out2.push("");
155419
155581
  const grouped = /* @__PURE__ */ new Map();
155420
155582
  const rest = [];
@@ -155532,17 +155694,19 @@ function formatReport(r2) {
155532
155694
  }
155533
155695
  return out2.join("\n");
155534
155696
  }
155535
- var TEST_CONFIG_FILE, mapResult, triggerLabel;
155697
+ var TEST_CONFIG_FILE, mapResult, TOKENS_FINDING_SCREEN, triggerLabel;
155536
155698
  var init_test = __esm({
155537
155699
  "src/test.ts"() {
155538
155700
  init_app_map();
155539
155701
  init_screen_crawl();
155540
155702
  init_wix_gateway_rules();
155541
155703
  init_crawl_layers();
155704
+ init_token_lint();
155542
155705
  init_screen_state();
155543
155706
  init_wix_writes();
155544
155707
  TEST_CONFIG_FILE = "himi-test.json";
155545
155708
  mapResult = (r2) => ({ screen: r2.screen, navEdges: r2.navEdges ?? [], navUnfollowed: r2.navUnfollowed ?? 0, failed: (r2.findings ?? []).some((x2) => x2.severity === "error") });
155709
+ TOKENS_FINDING_SCREEN = "tokens.json";
155546
155710
  triggerLabel = (f2) => (f2.trigger === "boot" ? "on appear" : `${f2.trigger.key} ${f2.trigger.tap ?? "(no id)"} \u2192 ${f2.trigger.action}`) + (f2.axis ? ` [${f2.axis}]` : "");
155547
155711
  }
155548
155712
  });
@@ -155552,11 +155716,11 @@ var mobile_ux_lint_exports = {};
155552
155716
  __export(mobile_ux_lint_exports, {
155553
155717
  mobileUxIssues: () => mobileUxIssues
155554
155718
  });
155555
- import { existsSync as existsSync63, readFileSync as readFileSync76 } from "node:fs";
155719
+ import { existsSync as existsSync64, readFileSync as readFileSync76 } from "node:fs";
155556
155720
  import { join as join67 } from "node:path";
155557
155721
  function mobileUxIssues(dir, strict) {
155558
155722
  const file2 = join67(dir, "MOBILE-UX.md");
155559
- if (!existsSync63(file2)) return [];
155723
+ if (!existsSync64(file2)) return [];
155560
155724
  let text9;
155561
155725
  try {
155562
155726
  text9 = readFileSync76(file2, "utf8");
@@ -157240,7 +157404,7 @@ __export(functions_exports, {
157240
157404
  resolveFunctionsTarget: () => resolveFunctionsTarget,
157241
157405
  runRemoteFunctionOperation: () => runRemoteFunctionOperation
157242
157406
  });
157243
- import { readFileSync as readFileSync77, existsSync as existsSync64 } from "node:fs";
157407
+ import { readFileSync as readFileSync77, existsSync as existsSync65 } from "node:fs";
157244
157408
  import { join as join68, resolve as resolve52 } from "node:path";
157245
157409
  function resolveFunctionsTarget(input) {
157246
157410
  const explicitUrl = input.functionsUrl?.trim();
@@ -157260,7 +157424,7 @@ async function loadFunctionsApp(dir) {
157260
157424
  }
157261
157425
  const sources = {};
157262
157426
  for (const definition of config.functions.functions) {
157263
- const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join68(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync64);
157427
+ const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join68(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync65);
157264
157428
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
157265
157429
  sources[definition.name] = readFileSync77(source, "utf8");
157266
157430
  }
@@ -157450,7 +157614,7 @@ var init_cli_bridge = __esm({
157450
157614
  });
157451
157615
 
157452
157616
  // src/mcp/file-tools.ts
157453
- import { closeSync as closeSync6, constants as constants3, lstatSync as lstatSync20, mkdirSync as mkdirSync31, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync78, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync15, statSync as statSync18, writeSync, existsSync as existsSync65 } from "node:fs";
157617
+ import { closeSync as closeSync6, constants as constants3, lstatSync as lstatSync20, mkdirSync as mkdirSync31, openSync as openSync5, readdirSync as readdirSync31, readFileSync as readFileSync78, realpathSync as realpathSync10, renameSync as renameSync11, rmSync as rmSync15, statSync as statSync18, writeSync, existsSync as existsSync66 } from "node:fs";
157454
157618
  import { randomBytes as randomBytes4 } from "node:crypto";
157455
157619
  import { dirname as dirname37, isAbsolute as isAbsolute7, join as join69, relative as relative13, resolve as resolve53, sep as sep17 } from "node:path";
157456
157620
  import * as z2 from "zod";
@@ -157460,7 +157624,7 @@ function within(root, p2) {
157460
157624
  function realish(p2) {
157461
157625
  let cur = p2;
157462
157626
  const tail = [];
157463
- while (!existsSync65(cur)) {
157627
+ while (!existsSync66(cur)) {
157464
157628
  const up = dirname37(cur);
157465
157629
  if (up === cur) break;
157466
157630
  tail.unshift(cur.slice(up.length + (up.endsWith(sep17) ? 0 : 1)));
@@ -157483,7 +157647,7 @@ function symlinkComponent(base, abs) {
157483
157647
  function workspaceRefusal(root, target) {
157484
157648
  const r2 = resolve53(root);
157485
157649
  const t2 = resolve53(r2, target);
157486
- if (!existsSync65(r2)) return `the workspace folder ${r2} does not exist`;
157650
+ if (!existsSync66(r2)) return `the workspace folder ${r2} does not exist`;
157487
157651
  if (!within(r2, t2) || !within(realpathSync10(r2), realish(t2))) return `"${target}" is outside the workspace folder ${r2}`;
157488
157652
  const link = symlinkComponent(r2, t2);
157489
157653
  if (link) return `"${link}" is a symlink \u2014 paths must stay in real folders inside the workspace`;
@@ -157492,13 +157656,13 @@ function workspaceRefusal(root, target) {
157492
157656
  async function confinedAppDir(args, deps) {
157493
157657
  const root = resolve53(await deps.defaultDir());
157494
157658
  const dir = typeof args.dir === "string" && args.dir ? resolve53(root, args.dir) : root;
157495
- if (!existsSync65(root)) return refuse5("no_workspace", `the workspace folder ${root} does not exist`);
157659
+ if (!existsSync66(root)) return refuse5("no_workspace", `the workspace folder ${root} does not exist`);
157496
157660
  if (!within(root, dir) || !within(realpathSync10(root), realish(dir))) return refuse5("outside_workspace", `"${String(args.dir)}" is outside the workspace folder`);
157497
157661
  const link = symlinkComponent(root, dir);
157498
157662
  if (link) return refuse5("outside_workspace", `"${link}" is a symlink \u2014 the app folder must be a real folder in the workspace`);
157499
157663
  const rel = relative13(root, dir);
157500
157664
  if (rel && (isDeniedSourcePath(`${rel}/x`) || isDeniedSourcePath(`${rel.toLowerCase()}/x`))) return refuse5("denied", `"${rel}" is a folder this tool does not touch`);
157501
- if (!existsSync65(join69(dir, CONTENT_MARKER))) {
157665
+ if (!existsSync66(join69(dir, CONTENT_MARKER))) {
157502
157666
  return refuse5("not_an_app", `"${rel || "."}" is not an app folder (no ${CONTENT_MARKER}) \u2014 see himi_list_apps, or create one with himi_init`);
157503
157667
  }
157504
157668
  return dir;
@@ -157506,7 +157670,7 @@ async function confinedAppDir(args, deps) {
157506
157670
  function onDiskSpelling(abs) {
157507
157671
  let cur = abs;
157508
157672
  const tail = [];
157509
- while (!existsSync65(cur)) {
157673
+ while (!existsSync66(cur)) {
157510
157674
  const up = dirname37(cur);
157511
157675
  if (up === cur) break;
157512
157676
  tail.unshift(cur.slice(up.length + (up.endsWith(sep17) ? 0 : 1)));
@@ -157530,7 +157694,7 @@ function confinedPath(appDir3, rel) {
157530
157694
  const abs = resolve53(appDir3, rel);
157531
157695
  if (!within(appDir3, abs) || abs === appDir3) return { error: `"${rel}" is outside the app folder` };
157532
157696
  const real = realish(abs);
157533
- const base = existsSync65(appDir3) ? realpathSync10(appDir3) : realish(appDir3);
157697
+ const base = existsSync66(appDir3) ? realpathSync10(appDir3) : realish(appDir3);
157534
157698
  if (!within(base, real) || real === base) return { error: `"${rel}" is outside the app folder` };
157535
157699
  const link = symlinkComponent(appDir3, abs);
157536
157700
  if (link) return { error: `"${link}" is a symlink, which this tool does not follow` };
@@ -157587,11 +157751,11 @@ function fileTools() {
157587
157751
  inputSchema: z2.object({}),
157588
157752
  handler: async (_a3, d2) => {
157589
157753
  const root = resolve53(await d2.defaultDir());
157590
- if (!existsSync65(root)) return ok({ ok: true, workspace: root, apps: [] });
157754
+ if (!existsSync66(root)) return ok({ ok: true, workspace: root, apps: [] });
157591
157755
  const apps = [];
157592
- if (existsSync65(join69(root, CONTENT_MARKER))) apps.push(".");
157756
+ if (existsSync66(join69(root, CONTENT_MARKER))) apps.push(".");
157593
157757
  for (const e2 of readdirSync31(root, { withFileTypes: true })) {
157594
- if (e2.isDirectory() && !e2.name.startsWith(".") && existsSync65(join69(root, e2.name, CONTENT_MARKER))) apps.push(e2.name);
157758
+ if (e2.isDirectory() && !e2.name.startsWith(".") && existsSync66(join69(root, e2.name, CONTENT_MARKER))) apps.push(e2.name);
157595
157759
  }
157596
157760
  return ok({ ok: true, workspace: root, apps: apps.sort() });
157597
157761
  }
@@ -157605,7 +157769,7 @@ function fileTools() {
157605
157769
  handler: async (a2, d2) => {
157606
157770
  const app = await confinedAppDir(a2, d2);
157607
157771
  if (typeof app !== "string") return app;
157608
- if (!existsSync65(app) || !statSync18(app).isDirectory()) return refuse5("no_app", `no folder at ${app}`);
157772
+ if (!existsSync66(app) || !statSync18(app).isDirectory()) return refuse5("no_app", `no folder at ${app}`);
157609
157773
  return ok({ ok: true, dir: app, ...listFiles(app) });
157610
157774
  }
157611
157775
  },
@@ -157620,7 +157784,7 @@ function fileTools() {
157620
157784
  if (typeof app !== "string") return app;
157621
157785
  const p2 = confinedPath(app, a2.path);
157622
157786
  if (typeof p2 !== "string") return refuse5("bad_path", p2.error);
157623
- if (!existsSync65(p2) || !lstatSync20(p2).isFile()) return refuse5("not_found", `no file "${String(a2.path)}"`);
157787
+ if (!existsSync66(p2) || !lstatSync20(p2).isFile()) return refuse5("not_found", `no file "${String(a2.path)}"`);
157624
157788
  const size = statSync18(p2).size;
157625
157789
  if (size > MAX_FILE_BYTES) return refuse5("too_large", `"${String(a2.path)}" is ${size} bytes \u2014 over the ${MAX_FILE_BYTES}-byte read limit`);
157626
157790
  return ok({ ok: true, path: a2.path, bytes: size, content: readFileSync78(p2, "utf8") });
@@ -157647,7 +157811,7 @@ function fileTools() {
157647
157811
  if (typeof p2 !== "string") refused2.push({ path: f2.path, error: p2.error });
157648
157812
  else if (typeof f2.content !== "string") refused2.push({ path: f2.path, error: "content must be text" });
157649
157813
  else if (Buffer.byteLength(f2.content) > MAX_FILE_BYTES) refused2.push({ path: f2.path, error: `over the ${MAX_FILE_BYTES}-byte limit` });
157650
- else if (existsSync65(p2) && !lstatSync20(p2).isFile()) refused2.push({ path: f2.path, error: "not a regular file" });
157814
+ else if (existsSync66(p2) && !lstatSync20(p2).isFile()) refused2.push({ path: f2.path, error: "not a regular file" });
157651
157815
  else if (planned2.some((q2) => q2.abs === p2)) refused2.push({ path: f2.path, error: "the same file twice in one call" });
157652
157816
  else planned2.push({ abs: p2, rel: String(f2.path), content: f2.content });
157653
157817
  }
@@ -157680,7 +157844,7 @@ function fileTools() {
157680
157844
  for (const rel of paths) {
157681
157845
  const p2 = confinedPath(app, rel);
157682
157846
  if (typeof p2 !== "string") refused2.push({ path: rel, error: p2.error });
157683
- else if (!existsSync65(p2)) refused2.push({ path: rel, error: "no such file" });
157847
+ else if (!existsSync66(p2)) refused2.push({ path: rel, error: "no such file" });
157684
157848
  else if (!lstatSync20(p2).isFile()) refused2.push({ path: rel, error: "not a regular file" });
157685
157849
  else if (!planned2.includes(p2)) {
157686
157850
  planned2.push(p2);
@@ -158236,7 +158400,7 @@ __export(server_exports, {
158236
158400
  startMcpServer: () => startMcpServer
158237
158401
  });
158238
158402
  import { mkdirSync as mkdirSync32, readFileSync as readFileSync79 } from "node:fs";
158239
- import { fileURLToPath as fileURLToPath24 } from "node:url";
158403
+ import { fileURLToPath as fileURLToPath25 } from "node:url";
158240
158404
  import { McpServer } from "@modelcontextprotocol/server";
158241
158405
  import { serveStdio, StdioServerTransport } from "@modelcontextprotocol/server/stdio";
158242
158406
  function protectStdout() {
@@ -158261,7 +158425,7 @@ async function firstRoot(server) {
158261
158425
  if (!server.server.getClientCapabilities()?.roots) return void 0;
158262
158426
  const { roots } = await server.server.listRoots();
158263
158427
  const uri = roots.find((r2) => r2.uri.startsWith("file://"))?.uri;
158264
- return uri ? fileURLToPath24(uri) : void 0;
158428
+ return uri ? fileURLToPath25(uri) : void 0;
158265
158429
  } catch {
158266
158430
  return void 0;
158267
158431
  }
@@ -158327,32 +158491,36 @@ var init_server = __esm({
158327
158491
  // src/native-decode.ts
158328
158492
  var native_decode_exports = {};
158329
158493
  __export(native_decode_exports, {
158494
+ NATIVE_TOKENS_DOCUMENT: () => NATIVE_TOKENS_DOCUMENT,
158495
+ defaultAndroidSdkDir: () => defaultAndroidSdkDir,
158330
158496
  detectAndroidNativeDecode: () => detectAndroidNativeDecode,
158331
158497
  detectNativeDecode: () => detectNativeDecode,
158498
+ markNativeSkipped: () => markNativeSkipped,
158332
158499
  mergeNativeDecode: () => mergeNativeDecode,
158333
158500
  nativeDecodeAndroidHarnessDir: () => nativeDecodeAndroidHarnessDir,
158334
158501
  nativeDecodePackageDir: () => nativeDecodePackageDir,
158335
158502
  nativeDecodePlatforms: () => nativeDecodePlatforms,
158336
158503
  nativeOracleShipped: () => nativeOracleShipped,
158337
158504
  parseNativeDecodeOutput: () => parseNativeDecodeOutput,
158505
+ parseNativeDecodeRun: () => parseNativeDecodeRun,
158338
158506
  runAndroidNativeDecode: () => runAndroidNativeDecode,
158339
158507
  runNativeDecode: () => runNativeDecode
158340
158508
  });
158341
158509
  import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
158342
- import { existsSync as existsSync66, mkdtempSync as mkdtempSync2, readFileSync as readFileSync80, rmSync as rmSync16, writeFileSync as writeFileSync28 } from "node:fs";
158343
- import { tmpdir as tmpdir3 } from "node:os";
158510
+ import { existsSync as existsSync67, mkdirSync as mkdirSync33, mkdtempSync as mkdtempSync2, readFileSync as readFileSync80, rmSync as rmSync16, writeFileSync as writeFileSync28 } from "node:fs";
158511
+ import { homedir as homedir9, tmpdir as tmpdir3 } from "node:os";
158344
158512
  import { join as join70 } from "node:path";
158345
- import { fileURLToPath as fileURLToPath25 } from "node:url";
158513
+ import { fileURLToPath as fileURLToPath26 } from "node:url";
158346
158514
  function nativeDecodePackageDir() {
158347
- return fileURLToPath25(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
158515
+ return fileURLToPath26(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
158348
158516
  }
158349
158517
  function nativeDecodeAndroidHarnessDir() {
158350
- return fileURLToPath25(new URL("../../../tools/wix-sdk-android-tests/", import.meta.url));
158518
+ return fileURLToPath26(new URL("../../../tools/wix-sdk-android-tests/", import.meta.url));
158351
158519
  }
158352
158520
  function nativeOracleShipped() {
158353
158521
  return {
158354
- ios: existsSync66(join70(nativeDecodePackageDir(), "Package.swift")),
158355
- android: existsSync66(join70(nativeDecodeAndroidHarnessDir(), "gradlew"))
158522
+ ios: existsSync67(join70(nativeDecodePackageDir(), "Package.swift")),
158523
+ android: existsSync67(join70(nativeDecodeAndroidHarnessDir(), "gradlew"))
158356
158524
  };
158357
158525
  }
158358
158526
  function detectNativeDecode(options = {}) {
@@ -158363,7 +158531,7 @@ function detectNativeDecode(options = {}) {
158363
158531
  return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
158364
158532
  }
158365
158533
  if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
158366
- const packageAvailable = options.packageAvailable ?? existsSync66(join70(packageDir, "Package.swift"));
158534
+ const packageAvailable = options.packageAvailable ?? existsSync67(join70(packageDir, "Package.swift"));
158367
158535
  if (!packageAvailable) {
158368
158536
  return {
158369
158537
  platform: "ios",
@@ -158381,10 +158549,15 @@ function localPropertiesSdk(harnessDir) {
158381
158549
  return null;
158382
158550
  }
158383
158551
  }
158552
+ function defaultAndroidSdkDir(hostPlatform, home) {
158553
+ if (hostPlatform === "darwin") return join70(home, "Library", "Android", "sdk");
158554
+ if (hostPlatform === "linux") return join70(home, "Android", "Sdk");
158555
+ return null;
158556
+ }
158384
158557
  function detectAndroidNativeDecode(options = {}) {
158385
158558
  const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
158386
158559
  const gradlew = join70(harnessDir, "gradlew");
158387
- const gradlewAvailable = options.gradlewAvailable ?? existsSync66(gradlew);
158560
+ const gradlewAvailable = options.gradlewAvailable ?? existsSync67(gradlew);
158388
158561
  if (!gradlewAvailable) {
158389
158562
  return {
158390
158563
  platform: "android",
@@ -158392,17 +158565,23 @@ function detectAndroidNativeDecode(options = {}) {
158392
158565
  reason: "the in-repo Android Gradle harness is unavailable (off-repo installs do not ship the decoder oracle)"
158393
158566
  };
158394
158567
  }
158395
- const androidHome = options.androidHome ?? process.env.ANDROID_HOME ?? "";
158396
- const sdk = androidHome.trim() || (options.localPropertiesSdk !== void 0 ? options.localPropertiesSdk : localPropertiesSdk(harnessDir));
158397
- const sdkAvailable = options.sdkAvailable ?? (typeof sdk === "string" && sdk.length > 0 && existsSync66(sdk));
158398
- if (!sdkAvailable) {
158568
+ const exists = typeof options.sdkAvailable === "function" ? options.sdkAvailable : typeof options.sdkAvailable === "boolean" ? /* @__PURE__ */ ((answer) => () => answer)(options.sdkAvailable) : existsSync67;
158569
+ const defaultDir = defaultAndroidSdkDir(options.hostPlatform ?? process.platform, options.homeDir ?? homedir9());
158570
+ const candidates = [
158571
+ options.androidHome ?? process.env.ANDROID_HOME,
158572
+ options.androidSdkRoot ?? process.env.ANDROID_SDK_ROOT,
158573
+ options.localPropertiesSdk !== void 0 ? options.localPropertiesSdk : localPropertiesSdk(harnessDir),
158574
+ defaultDir
158575
+ ].map((candidate) => candidate?.trim() ?? "").filter((candidate) => candidate.length > 0);
158576
+ const sdkDir = candidates.find((candidate) => exists(candidate));
158577
+ if (sdkDir === void 0) {
158399
158578
  return {
158400
158579
  platform: "android",
158401
158580
  available: false,
158402
- reason: "the Android SDK is unavailable (set ANDROID_HOME or sdk.dir in tools/wix-sdk-android-tests/local.properties)"
158581
+ reason: `the Android SDK is unavailable (set ANDROID_HOME or ANDROID_SDK_ROOT, sdk.dir in tools/wix-sdk-android-tests/local.properties, or install it at the default path${defaultDir ? ` ${defaultDir}` : ""})`
158403
158582
  };
158404
158583
  }
158405
- return { platform: "android", available: true, harnessDir, gradlew };
158584
+ return { platform: "android", available: true, harnessDir, gradlew, sdkDir };
158406
158585
  }
158407
158586
  function nativeDecodePlatforms(value) {
158408
158587
  if (value === true) return ["ios", "android"];
@@ -158436,10 +158615,14 @@ function parseError(value, line, platform) {
158436
158615
  };
158437
158616
  }
158438
158617
  function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
158618
+ return parseNativeDecodeRun(stdout, expectedScreenIds, platform, false).verdicts;
158619
+ }
158620
+ function parseNativeDecodeRun(stdout, expectedScreenIds, platform, expectTokens) {
158439
158621
  const platformLabel = platform === "ios" ? "iOS" : "Android";
158440
158622
  const expected = new Set(expectedScreenIds);
158441
158623
  if (expected.size !== expectedScreenIds.length) throw new Error("native decode input contains duplicate screen ids");
158442
158624
  const verdicts = [];
158625
+ let tokens2;
158443
158626
  const seen = /* @__PURE__ */ new Set();
158444
158627
  const lines = stdout.split(/\r?\n/).filter((line) => line.trim() !== "");
158445
158628
  for (let index = 0; index < lines.length; index++) {
@@ -158449,6 +158632,19 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
158449
158632
  } catch (error) {
158450
158633
  throw new Error(`malformed NDJSON from ${platformLabel} decoder oracle at line ${index + 1}: ${error.message}`);
158451
158634
  }
158635
+ if (record(value) && "document" in value) {
158636
+ if (value.document !== "tokens" || value.platform !== platform || typeof value.ok !== "boolean" || !Array.isArray(value.errors)) {
158637
+ throw new Error(`malformed NDJSON from ${platformLabel} decoder oracle at line ${index + 1}: document verdict must be { document:"tokens", platform:"${platform}", ok, errors }`);
158638
+ }
158639
+ rejectUnknownKeys(value, DOCUMENT_VERDICT_KEYS, "document verdict", index + 1, platformLabel);
158640
+ if (!expectTokens) throw new Error(`${platformLabel} decoder oracle returned a tokens verdict it was not asked for`);
158641
+ if (tokens2) throw new Error(`${platformLabel} decoder oracle returned a duplicate tokens verdict`);
158642
+ const errors2 = value.errors.map((item) => parseError(item, index + 1, platform));
158643
+ if (value.ok && errors2.length) throw new Error(`malformed NDJSON from ${platformLabel} decoder oracle at line ${index + 1}: ok=true must have no errors`);
158644
+ if (!value.ok && !errors2.length) throw new Error(`malformed NDJSON from ${platformLabel} decoder oracle at line ${index + 1}: ok=false must have at least one error`);
158645
+ tokens2 = { platform, ok: value.ok, errors: errors2 };
158646
+ continue;
158647
+ }
158452
158648
  if (!record(value) || typeof value.screenId !== "string" || value.platform !== platform || typeof value.ok !== "boolean" || !Array.isArray(value.errors)) {
158453
158649
  throw new Error(`malformed NDJSON from ${platformLabel} decoder oracle at line ${index + 1}: verdict must be { screenId, platform:"${platform}", ok, errors }`);
158454
158650
  }
@@ -158463,18 +158659,27 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
158463
158659
  }
158464
158660
  const missing = expectedScreenIds.filter((screenId) => !seen.has(screenId));
158465
158661
  if (missing.length) throw new Error(`${platformLabel} decoder oracle output is missing verdict${missing.length === 1 ? "" : "s"} for: ${missing.join(", ")}`);
158466
- return verdicts;
158662
+ if (expectTokens && !tokens2) throw new Error(`${platformLabel} decoder oracle output is missing the tokens verdict`);
158663
+ return tokens2 ? { verdicts, tokens: tokens2 } : { verdicts };
158664
+ }
158665
+ function writeDecodeInputs(descriptorDir, descriptors, tokensJson) {
158666
+ for (const descriptor of descriptors) {
158667
+ if (typeof descriptor.descriptorJson !== "string") {
158668
+ throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
158669
+ }
158670
+ writeFileSync28(join70(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
158671
+ }
158672
+ if (tokensJson === void 0) return void 0;
158673
+ mkdirSync33(join70(descriptorDir, "tokens"));
158674
+ const tokensPath = join70(descriptorDir, "tokens", NATIVE_TOKENS_DOCUMENT);
158675
+ writeFileSync28(tokensPath, tokensJson);
158676
+ return tokensPath;
158467
158677
  }
158468
158678
  function runNativeDecode(options) {
158469
158679
  const descriptorDir = mkdtempSync2(join70(tmpdir3(), "himi-native-decode-"));
158470
158680
  const startedAt = Date.now();
158471
158681
  try {
158472
- for (const descriptor of options.descriptors) {
158473
- if (typeof descriptor.descriptorJson !== "string") {
158474
- throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
158475
- }
158476
- writeFileSync28(join70(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
158477
- }
158682
+ const tokensPath = writeDecodeInputs(descriptorDir, options.descriptors, options.tokensJson);
158478
158683
  options.progress?.("building cached Swift oracle");
158479
158684
  execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
158480
158685
  stdio: ["ignore", "ignore", "pipe"],
@@ -158485,13 +158690,13 @@ function runNativeDecode(options) {
158485
158690
  encoding: "utf8"
158486
158691
  }).trim();
158487
158692
  options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
158488
- const stdout = execFileSync5(join70(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
158693
+ const stdout = execFileSync5(join70(binPath, "himi-decode-oracle"), ["--dir", descriptorDir, ...tokensPath ? ["--tokens", tokensPath] : []], {
158489
158694
  stdio: ["ignore", "pipe", "pipe"],
158490
158695
  encoding: "utf8"
158491
158696
  });
158492
158697
  return {
158493
158698
  platform: "ios",
158494
- verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId)),
158699
+ ...parseNativeDecodeRun(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "ios", tokensPath !== void 0),
158495
158700
  wallMs: Date.now() - startedAt
158496
158701
  };
158497
158702
  } catch (error) {
@@ -158507,12 +158712,7 @@ function runAndroidNativeDecode(options) {
158507
158712
  const outputPath = join70(descriptorDir, "verdicts.ndjson");
158508
158713
  const startedAt = Date.now();
158509
158714
  try {
158510
- for (const descriptor of options.descriptors) {
158511
- if (typeof descriptor.descriptorJson !== "string") {
158512
- throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
158513
- }
158514
- writeFileSync28(join70(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
158515
- }
158715
+ const tokensPath = writeDecodeInputs(descriptorDir, options.descriptors, options.tokensJson);
158516
158716
  options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
158517
158717
  execFileSync5(options.gradlew, [
158518
158718
  "-p",
@@ -158521,15 +158721,17 @@ function runAndroidNativeDecode(options) {
158521
158721
  "--tests",
158522
158722
  "io.himalaya.core.NativeDecodeOracleRunner",
158523
158723
  `-PhimiDecodeDir=${descriptorDir}`,
158524
- `-PhimiDecodeOut=${outputPath}`
158724
+ `-PhimiDecodeOut=${outputPath}`,
158725
+ ...tokensPath ? [`-PhimiDecodeTokens=${tokensPath}`] : []
158525
158726
  ], {
158526
158727
  stdio: ["ignore", "ignore", "pipe"],
158527
- encoding: "utf8"
158728
+ encoding: "utf8",
158729
+ ...options.sdkDir ? { env: { ...process.env, ANDROID_HOME: options.sdkDir, ANDROID_SDK_ROOT: options.sdkDir } } : {}
158528
158730
  });
158529
158731
  const stdout = readFileSync80(outputPath, "utf8");
158530
158732
  return {
158531
158733
  platform: "android",
158532
- verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
158734
+ ...parseNativeDecodeRun(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android", tokensPath !== void 0),
158533
158735
  wallMs: Date.now() - startedAt
158534
158736
  };
158535
158737
  } catch (error) {
@@ -158540,6 +158742,17 @@ function runAndroidNativeDecode(options) {
158540
158742
  rmSync16(descriptorDir, { recursive: true, force: true });
158541
158743
  }
158542
158744
  }
158745
+ function markNativeSkipped(report3, skipped) {
158746
+ return {
158747
+ ...report3,
158748
+ nativeDecode: {
158749
+ ...report3.nativeDecode,
158750
+ [skipped.platform]: { unavailable: true, reason: skipped.reason },
158751
+ wallMs: report3.nativeDecode?.wallMs ?? 0
158752
+ },
158753
+ skippedPlatforms: [...report3.skippedPlatforms ?? [], { platform: skipped.platform, reason: skipped.reason }]
158754
+ };
158755
+ }
158543
158756
  function fieldAt(path2) {
158544
158757
  if (path2 === null) return void 0;
158545
158758
  return path2.match(/\.([^.[\]]+)$/)?.[1];
@@ -158557,8 +158770,20 @@ function mergeNativeDecode(report3, run2) {
158557
158770
  ...error.actual ? { actual: error.actual } : {},
158558
158771
  hint: `This descriptor ships as a full-screen \u201CCouldn't load\u201D; fix the typed field and rerun \`himi test --native ${run2.platform}\`.`
158559
158772
  })));
158773
+ const tokenFailures = (run2.tokens?.errors ?? []).map((error) => ({
158774
+ screen: NATIVE_TOKENS_DOCUMENT,
158775
+ trigger: "boot",
158776
+ invariant: "native-decode-failed",
158777
+ severity: "error",
158778
+ message: `${platformLabel} ${error.kind} decoding ${NATIVE_TOKENS_DOCUMENT}: ${error.message}${error.expected ? ` (expected ${error.expected})` : ""}`,
158779
+ ...error.path ? { at: error.path } : {},
158780
+ ...fieldAt(error.path) ? { field: fieldAt(error.path) } : {},
158781
+ ...error.actual ? { actual: error.actual } : {},
158782
+ hint: `${platformLabel} decodes tokens.json in one strict pass, so this one value drops the WHOLE theme on device (iOS shows \u201CTheme unavailable\u201D; Android falls back to its default palette and fonts). Typography \`size\`, spacing, radius and motion \`duration\` (milliseconds: 0.3 \u2192 300) are integers. Fix it and rerun \`himi test --native ${run2.platform}\`.`
158783
+ }));
158784
+ nativeFailures.push(...tokenFailures);
158560
158785
  const failures = [...report3.failures, ...nativeFailures];
158561
- const failedScreens = new Set(failures.map((finding) => finding.screen));
158786
+ const failedScreens = new Set(failures.map((finding) => finding.screen).filter((screen) => screen !== NATIVE_TOKENS_DOCUMENT));
158562
158787
  return {
158563
158788
  ...report3,
158564
158789
  ok: report3.ok && nativeFailures.length === 0,
@@ -158567,17 +158792,23 @@ function mergeNativeDecode(report3, run2) {
158567
158792
  screens: { ...report3.screens, clean: report3.screens.total - failedScreens.size, failed: failedScreens.size },
158568
158793
  nativeDecode: {
158569
158794
  ...report3.nativeDecode,
158570
- [run2.platform]: { checked: run2.verdicts.length, failed: run2.verdicts.filter((verdict) => !verdict.ok).length },
158795
+ [run2.platform]: {
158796
+ checked: run2.verdicts.length,
158797
+ failed: run2.verdicts.filter((verdict) => !verdict.ok).length,
158798
+ ...run2.tokens ? { tokens: run2.tokens.ok ? "ok" : "rejected" } : {}
158799
+ },
158571
158800
  wallMs: (report3.nativeDecode?.wallMs ?? 0) + run2.wallMs
158572
158801
  }
158573
158802
  };
158574
158803
  }
158575
- var KINDS, record, VERDICT_KEYS, ERROR_KEYS;
158804
+ var NATIVE_TOKENS_DOCUMENT, KINDS, record, VERDICT_KEYS, DOCUMENT_VERDICT_KEYS, ERROR_KEYS;
158576
158805
  var init_native_decode = __esm({
158577
158806
  "src/native-decode.ts"() {
158807
+ NATIVE_TOKENS_DOCUMENT = "tokens.json";
158578
158808
  KINDS = /* @__PURE__ */ new Set(["typeMismatch", "valueNotFound", "keyNotFound", "dataCorrupted"]);
158579
158809
  record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
158580
158810
  VERDICT_KEYS = /* @__PURE__ */ new Set(["screenId", "platform", "ok", "errors"]);
158811
+ DOCUMENT_VERDICT_KEYS = /* @__PURE__ */ new Set(["document", "platform", "ok", "errors"]);
158581
158812
  ERROR_KEYS = /* @__PURE__ */ new Set(["kind", "path", "message", "expected", "actual"]);
158582
158813
  }
158583
158814
  });
@@ -158596,7 +158827,7 @@ __export(browser_authoring_exports, {
158596
158827
  });
158597
158828
  import { createServer as createServer5 } from "node:http";
158598
158829
  import { createHash as createHash36, randomBytes as randomBytes5 } from "node:crypto";
158599
- import { existsSync as existsSync67, readdirSync as readdirSync32, readFileSync as readFileSync81, realpathSync as realpathSync11, statSync as statSync19 } from "node:fs";
158830
+ import { existsSync as existsSync68, readdirSync as readdirSync32, readFileSync as readFileSync81, realpathSync as realpathSync11, statSync as statSync19 } from "node:fs";
158600
158831
  import { join as join71, posix as posix3, relative as relative14, sep as sep18 } from "node:path";
158601
158832
  function humanMs(ms2) {
158602
158833
  return ms2 < 1e3 ? `${ms2}ms` : `${Math.round(ms2 / 1e3)}s`;
@@ -158619,7 +158850,7 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
158619
158850
  }
158620
158851
  }
158621
158852
  };
158622
- if (!existsSync67(root)) return null;
158853
+ if (!existsSync68(root)) return null;
158623
158854
  walk2(root, `/tier5-src/${bundleName}`);
158624
158855
  const entry = [`/tier5-src/${bundleName}/index.ts`, `/tier5-src/${bundleName}/index.js`].find((p2) => p2 in files);
158625
158856
  if (!entry) return null;
@@ -158646,7 +158877,7 @@ function collectRelativeSiblings(files, tier5SrcDir) {
158646
158877
  join71(onDisk, "index.js")
158647
158878
  ];
158648
158879
  for (const abs of candidates) {
158649
- if (!existsSync67(abs) || statSync19(abs).isDirectory()) continue;
158880
+ if (!existsSync68(abs) || statSync19(abs).isDirectory()) continue;
158650
158881
  const key3 = `/tier5-src/${relative14(tier5SrcDir, abs).split(sep18).join(posix3.sep)}`;
158651
158882
  if (key3 in files) break;
158652
158883
  files[key3] = readFileSync81(abs, "utf8");
@@ -158856,7 +159087,7 @@ __export(coverage_exports, {
158856
159087
  suppressedNativeKeys: () => suppressedNativeKeys,
158857
159088
  trendAndStore: () => trendAndStore
158858
159089
  });
158859
- import { existsSync as existsSync68, mkdirSync as mkdirSync33, readFileSync as readFileSync82, writeFileSync as writeFileSync29 } from "node:fs";
159090
+ import { existsSync as existsSync69, mkdirSync as mkdirSync34, readFileSync as readFileSync82, writeFileSync as writeFileSync29 } from "node:fs";
158860
159091
  import { dirname as dirname38, join as join72 } from "node:path";
158861
159092
  function suppressedNativeKeys(oracle) {
158862
159093
  return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
@@ -159040,7 +159271,7 @@ function trendAndStore(dir, entries, suppressed) {
159040
159271
  const p2 = join72(dir, LEDGER_FILE);
159041
159272
  let previous = null;
159042
159273
  try {
159043
- if (existsSync68(p2)) {
159274
+ if (existsSync69(p2)) {
159044
159275
  const parsed = JSON.parse(readFileSync82(p2, "utf8"));
159045
159276
  if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k2) => typeof k2 === "string");
159046
159277
  }
@@ -159049,7 +159280,7 @@ function trendAndStore(dir, entries, suppressed) {
159049
159280
  const current = entries.map((e2) => e2.key);
159050
159281
  const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key3) => (suppressed ?? []).includes(key3))])];
159051
159282
  try {
159052
- mkdirSync33(dirname38(p2), { recursive: true });
159283
+ mkdirSync34(dirname38(p2), { recursive: true });
159053
159284
  writeFileSync29(p2, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
159054
159285
  } catch {
159055
159286
  return null;
@@ -159083,7 +159314,7 @@ function diffAndStoreObservations(dir, current) {
159083
159314
  const p2 = join72(dir, OBS_FILE);
159084
159315
  let previous = null;
159085
159316
  try {
159086
- if (existsSync68(p2)) {
159317
+ if (existsSync69(p2)) {
159087
159318
  const parsed = JSON.parse(readFileSync82(p2, "utf8"));
159088
159319
  if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
159089
159320
  (v2) => Array.isArray(v2) && v2.every((l2) => typeof l2 === "string")
@@ -159094,7 +159325,7 @@ function diffAndStoreObservations(dir, current) {
159094
159325
  } catch {
159095
159326
  }
159096
159327
  try {
159097
- mkdirSync33(dirname38(p2), { recursive: true });
159328
+ mkdirSync34(dirname38(p2), { recursive: true });
159098
159329
  writeFileSync29(p2, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
159099
159330
  } catch {
159100
159331
  return null;
@@ -159145,11 +159376,11 @@ __export(design_kits_exports, {
159145
159376
  kitsDir: () => kitsDir,
159146
159377
  listKits: () => listKits2
159147
159378
  });
159148
- import { existsSync as existsSync69, readFileSync as readFileSync83, readdirSync as readdirSync33 } from "node:fs";
159379
+ import { existsSync as existsSync70, readFileSync as readFileSync83, readdirSync as readdirSync33 } from "node:fs";
159149
159380
  import { join as join73, basename as basename16 } from "node:path";
159150
- import { fileURLToPath as fileURLToPath26 } from "node:url";
159381
+ import { fileURLToPath as fileURLToPath27 } from "node:url";
159151
159382
  function kitsDir() {
159152
- return KIT_DIR_CANDIDATES.find((p2) => existsSync69(p2));
159383
+ return KIT_DIR_CANDIDATES.find((p2) => existsSync70(p2));
159153
159384
  }
159154
159385
  function listKits2() {
159155
159386
  const dir = kitsDir();
@@ -159197,9 +159428,9 @@ var init_design_kits = __esm({
159197
159428
  "src/design-kits.ts"() {
159198
159429
  KIT_DIR_CANDIDATES = [
159199
159430
  // in-repo: tools/himi-cli/src/design-kits.ts → <repo>/stdlib/design-kits/
159200
- join73(fileURLToPath26(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
159431
+ join73(fileURLToPath27(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
159201
159432
  // published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/design-kits/
159202
- join73(fileURLToPath26(new URL("..", import.meta.url)), "stdlib", "design-kits")
159433
+ join73(fileURLToPath27(new URL("..", import.meta.url)), "stdlib", "design-kits")
159203
159434
  ];
159204
159435
  }
159205
159436
  });
@@ -161309,6 +161540,7 @@ var init_preview_assets_generated = __esm({
161309
161540
  var run_exports = {};
161310
161541
  __export(run_exports, {
161311
161542
  NO_SPA_MESSAGE: () => NO_SPA_MESSAGE,
161543
+ RUN_CONTENT_BUILD: () => RUN_CONTENT_BUILD,
161312
161544
  lanAddress: () => lanAddress,
161313
161545
  lanFlagConflict: () => lanFlagConflict,
161314
161546
  loadPreviewAssets: () => loadPreviewAssets,
@@ -161318,10 +161550,10 @@ __export(run_exports, {
161318
161550
  runPackage: () => runPackage,
161319
161551
  withoutProdServe: () => withoutProdServe
161320
161552
  });
161321
- import { cpSync as cpSync2, existsSync as existsSync70, mkdirSync as mkdirSync34, mkdtempSync as mkdtempSync3, readFileSync as readFileSync85, rmSync as rmSync17, statSync as statSync20 } from "node:fs";
161553
+ import { cpSync as cpSync2, existsSync as existsSync71, mkdirSync as mkdirSync35, mkdtempSync as mkdtempSync3, readFileSync as readFileSync85, rmSync as rmSync17, statSync as statSync20 } from "node:fs";
161322
161554
  import { networkInterfaces as osNetworkInterfaces, tmpdir as tmpdir4 } from "node:os";
161323
161555
  import { dirname as dirname39, join as join74 } from "node:path";
161324
- import { fileURLToPath as fileURLToPath27 } from "node:url";
161556
+ import { fileURLToPath as fileURLToPath28 } from "node:url";
161325
161557
  function makePackageRunHandler(opts) {
161326
161558
  const store = new FileReleaseStore(opts.releaseRoot);
161327
161559
  const webwixDirect = async () => {
@@ -161348,9 +161580,9 @@ async function fetchBytes(url) {
161348
161580
  }
161349
161581
  async function resolvePackage(source, workDir) {
161350
161582
  const isUrl2 = /^https?:\/\//i.test(source);
161351
- if (!isUrl2 && existsSync70(source) && statSync20(source).isDirectory()) {
161583
+ if (!isUrl2 && existsSync71(source) && statSync20(source).isDirectory()) {
161352
161584
  const appDirManifest = join74(source, "release-manifest.json");
161353
- if (existsSync70(appDirManifest)) {
161585
+ if (existsSync71(appDirManifest)) {
161354
161586
  const opened2 = openPackageDir(source);
161355
161587
  if (!opened2.validation.ok) {
161356
161588
  throw new Error(`package is not valid:
@@ -161362,7 +161594,7 @@ async function resolvePackage(source, workDir) {
161362
161594
  const root2 = workDir ?? mkdtempSync3(join74(tmpdir4(), "himi-run-"));
161363
161595
  const target = join74(root2, app2);
161364
161596
  if (join74(source) !== target) {
161365
- mkdirSync34(root2, { recursive: true });
161597
+ mkdirSync35(root2, { recursive: true });
161366
161598
  rmSync17(target, { recursive: true, force: true });
161367
161599
  cpSync2(source, target, { recursive: true });
161368
161600
  }
@@ -161400,7 +161632,7 @@ async function resolvePackage(source, workDir) {
161400
161632
  async function loadPreviewAssets() {
161401
161633
  try {
161402
161634
  const mod = await Promise.resolve().then(() => (init_preview_assets_generated(), preview_assets_generated_exports));
161403
- const here = dirname39(fileURLToPath27(import.meta.url));
161635
+ const here = dirname39(fileURLToPath28(import.meta.url));
161404
161636
  const candidates = [
161405
161637
  join74(here, "preview-assets.generated.bin"),
161406
161638
  // published: copied next to the bundled CLI
@@ -161408,7 +161640,7 @@ async function loadPreviewAssets() {
161408
161640
  // in-repo checkout
161409
161641
  ];
161410
161642
  for (const path2 of candidates) {
161411
- if (!existsSync70(path2)) continue;
161643
+ if (!existsSync71(path2)) continue;
161412
161644
  const blob = readFileSync85(path2);
161413
161645
  return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
161414
161646
  }
@@ -161521,7 +161753,7 @@ async function runPackage(source, opts = {}) {
161521
161753
  }
161522
161754
  };
161523
161755
  }
161524
- var NO_SPA_MESSAGE, UNREACHABLE_IFACE, LIKELY_LAN_IFACE;
161756
+ var RUN_CONTENT_BUILD, NO_SPA_MESSAGE, UNREACHABLE_IFACE, LIKELY_LAN_IFACE;
161525
161757
  var init_run = __esm({
161526
161758
  "src/run.ts"() {
161527
161759
  init_open_url();
@@ -161532,6 +161764,7 @@ var init_run = __esm({
161532
161764
  init_pack();
161533
161765
  init_himi_package();
161534
161766
  init_himi_package();
161767
+ RUN_CONTENT_BUILD = { keepDevOnlyAppConfig: true };
161535
161768
  NO_SPA_MESSAGE = "the web-host SPA is not embedded in this build \u2014 run `node packages/serve/scripts/embed-preview-assets.mjs` (in a monorepo checkout), or pass --spa <url> to use a hosted preview host instead";
161536
161769
  UNREACHABLE_IFACE = /^(utun|tun|tap|ppp|ipsec|wg|gif|stf|bridge|vmnet|vboxnet|virbr|docker|br-|veth|awdl|llw|anpi|tailscale|zt|zerotier|nordlynx)|vpn/i;
161537
161770
  LIKELY_LAN_IFACE = /^(en|eth|wlan|wl|wifi)/i;
@@ -161546,15 +161779,15 @@ __export(run_browser_exports, {
161546
161779
  runInBrowser: () => runInBrowser
161547
161780
  });
161548
161781
  import { createServer as createServer7 } from "node:http";
161549
- import { existsSync as existsSync71, readFileSync as readFileSync86 } from "node:fs";
161782
+ import { existsSync as existsSync72, readFileSync as readFileSync86 } from "node:fs";
161550
161783
  import { spawnSync as spawnSync3 } from "node:child_process";
161551
161784
  import { dirname as dirname40, resolve as resolve55 } from "node:path";
161552
- import { fileURLToPath as fileURLToPath28 } from "node:url";
161785
+ import { fileURLToPath as fileURLToPath29 } from "node:url";
161553
161786
  function stagedDir() {
161554
161787
  return process.env.HIMI_BROWSER_PLANE_OUT ? resolve55(process.env.HIMI_BROWSER_PLANE_OUT) : resolve55(REPO2, "packages", "serve", "dist", "browser-plane");
161555
161788
  }
161556
161789
  function missingStaged() {
161557
- return [...SERVED].filter((f2) => !existsSync71(resolve55(stagedDir(), f2))).sort();
161790
+ return [...SERVED].filter((f2) => !existsSync72(resolve55(stagedDir(), f2))).sort();
161558
161791
  }
161559
161792
  function ensureBrowserPlaneStaged() {
161560
161793
  if (missingStaged().length === 0) return { ok: true, detail: "already staged" };
@@ -161644,7 +161877,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
161644
161877
  }
161645
161878
  const name = path2 === "/" || path2 === "/index.html" ? "host.html" : path2.slice(1);
161646
161879
  if (SERVED.has(name)) {
161647
- if (!existsSync71(resolve55(stagedDir(), name))) {
161880
+ if (!existsSync72(resolve55(stagedDir(), name))) {
161648
161881
  const restaged = ensureBrowserPlaneStaged();
161649
161882
  if (!restaged.ok) {
161650
161883
  res.writeHead(503, { "content-type": "application/json" });
@@ -161696,7 +161929,7 @@ var init_run_browser = __esm({
161696
161929
  init_open_url();
161697
161930
  init_file_store();
161698
161931
  init_wix_client_id();
161699
- HERE2 = dirname40(fileURLToPath28(import.meta.url));
161932
+ HERE2 = dirname40(fileURLToPath29(import.meta.url));
161700
161933
  REPO2 = resolve55(HERE2, "..", "..", "..");
161701
161934
  SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
161702
161935
  }
@@ -161707,14 +161940,14 @@ var hhp_preview_exports = {};
161707
161940
  __export(hhp_preview_exports, {
161708
161941
  hhpPreviewResponse: () => hhpPreviewResponse
161709
161942
  });
161710
- import { existsSync as existsSync72, readFileSync as readFileSync87 } from "node:fs";
161943
+ import { existsSync as existsSync73, readFileSync as readFileSync87 } from "node:fs";
161711
161944
  import { join as join75 } from "node:path";
161712
161945
  function hhpPreviewResponse(root, request) {
161713
- if (new URL(request.url).pathname !== "/__himi/hhp-preview" || !existsSync72(join75(root, "hhp.json"))) return null;
161946
+ if (new URL(request.url).pathname !== "/__himi/hhp-preview" || !existsSync73(join75(root, "hhp.json"))) return null;
161714
161947
  if (request.method !== "GET") return new Response(null, { status: 405 });
161715
161948
  try {
161716
161949
  const file2 = localPath(root, ".himi/hhp-preview.json");
161717
- const authored2 = existsSync72(file2) ? JSON.parse(readFileSync87(file2, "utf8")) : {};
161950
+ const authored2 = existsSync73(file2) ? JSON.parse(readFileSync87(file2, "utf8")) : {};
161718
161951
  if (authored2.mockCapabilities && (!Array.isArray(authored2.mockCapabilities) || authored2.mockCapabilities.some((v2) => typeof v2 !== "string"))) throw new Error("mockCapabilities must be a string array.");
161719
161952
  const fixtures = authored2.fixtures ?? {};
161720
161953
  if (typeof fixtures !== "object" || Array.isArray(fixtures) || fixtures === null) throw new Error("fixtures must be an object.");
@@ -163762,13 +163995,13 @@ __export(credential_profile_exports, {
163762
163995
  profilePath: () => profilePath,
163763
163996
  resolveStoreCredentials: () => resolveStoreCredentials
163764
163997
  });
163765
- import { existsSync as existsSync73, readFileSync as readFileSync89 } from "node:fs";
163766
- import { homedir as homedir9 } from "node:os";
163998
+ import { existsSync as existsSync74, readFileSync as readFileSync89 } from "node:fs";
163999
+ import { homedir as homedir10 } from "node:os";
163767
164000
  import { join as join76 } from "node:path";
163768
- function credentialsDir(home = homedir9()) {
164001
+ function credentialsDir(home = homedir10()) {
163769
164002
  return join76(home, ".himalaya", "store-credentials");
163770
164003
  }
163771
- function profilePath(name, home = homedir9()) {
164004
+ function profilePath(name, home = homedir10()) {
163772
164005
  if (!PROFILE_NAME.test(name)) {
163773
164006
  throw new Error(
163774
164007
  `credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join76(credentialsDir(home), "<name>.json")}; it is never a path.`
@@ -163804,9 +164037,9 @@ function namedProfile(cfg, profileFlag) {
163804
164037
  function resolveStoreCredentials(opts) {
163805
164038
  const { app, cfg } = opts;
163806
164039
  const env = opts.env ?? process.env;
163807
- const home = opts.home ?? homedir9();
164040
+ const home = opts.home ?? homedir10();
163808
164041
  const read = opts.readProfile ?? ((p2) => readFileSync89(p2, "utf8"));
163809
- const exists = opts.profileExists ?? existsSync73;
164042
+ const exists = opts.profileExists ?? existsSync74;
163810
164043
  const ios = cfg.ios ?? {};
163811
164044
  const flagName = opts.profileFlag?.trim();
163812
164045
  const named = namedProfile(cfg, opts.profileFlag);
@@ -163872,8 +164105,8 @@ var init_credential_profile = __esm({
163872
164105
 
163873
164106
  // ../store-release/iap-credentials.ts
163874
164107
  import { createHash as createHash39 } from "node:crypto";
163875
- import { existsSync as existsSync74, readFileSync as readFileSync90, realpathSync as realpathSync12 } from "node:fs";
163876
- import { homedir as homedir10 } from "node:os";
164108
+ import { existsSync as existsSync75, readFileSync as readFileSync90, realpathSync as realpathSync12 } from "node:fs";
164109
+ import { homedir as homedir11 } from "node:os";
163877
164110
  function accountFingerprint(keyId, issuerId) {
163878
164111
  return `sha256:${createHash39("sha256").update(`${issuerId}:${keyId}`).digest("hex").slice(0, 16)}`;
163879
164112
  }
@@ -163905,7 +164138,7 @@ function canonicalKeyPath(path2, profile, realpath) {
163905
164138
  }
163906
164139
  function resolveIapCredentials(options) {
163907
164140
  const { target } = options;
163908
- const home = options.home ?? homedir10();
164141
+ const home = options.home ?? homedir11();
163909
164142
  const readFile3 = options.readFile ?? ((p2) => readFileSync90(p2, "utf8"));
163910
164143
  const realpath = options.realpath ?? realpathSync12;
163911
164144
  const profile = requireExplicitProfile(options.profileFlag, target);
@@ -163916,7 +164149,7 @@ function resolveIapCredentials(options) {
163916
164149
  env: {},
163917
164150
  home,
163918
164151
  readProfile: readFile3,
163919
- profileExists: options.exists ?? existsSync74
164152
+ profileExists: options.exists ?? existsSync75
163920
164153
  });
163921
164154
  assertCredentialOutsideRepo(`credential profile "${profile}"`, realpath(profilePath(profile, home)));
163922
164155
  assertCredentialOutsideRepo(`credential profile "${profile}" ascKeyPath`, canonicalKeyPath(creds.ascKeyPath, profile, realpath));
@@ -164437,7 +164670,7 @@ var init_store_spec = __esm({
164437
164670
  });
164438
164671
 
164439
164672
  // src/iap-config-edit.ts
164440
- import { existsSync as existsSync75, readFileSync as readFileSync92 } from "node:fs";
164673
+ import { existsSync as existsSync76, readFileSync as readFileSync92 } from "node:fs";
164441
164674
  import { basename as basename20, join as join77 } from "node:path";
164442
164675
  import ts8 from "typescript";
164443
164676
  function bindPurchasesAppInConfig(source, options) {
@@ -164518,7 +164751,7 @@ function capabilityFinding(app, fileName) {
164518
164751
  function withStoreBundle(dir, options) {
164519
164752
  if (options.storeBundleId) return options;
164520
164753
  const path2 = join77(dir, "store", "store.config.yaml");
164521
- if (!existsSync75(path2)) return options;
164754
+ if (!existsSync76(path2)) return options;
164522
164755
  const storeBundleId = parseStoreConfig(readFileSync92(path2, "utf8")).ios?.bundleId;
164523
164756
  return storeBundleId ? { ...options, storeBundleId } : options;
164524
164757
  }
@@ -165169,7 +165402,7 @@ var init_store_iap_screenshots = __esm({
165169
165402
  });
165170
165403
 
165171
165404
  // src/store-iap-screenshot-render.ts
165172
- import { existsSync as existsSync76, mkdtempSync as mkdtempSync4, readFileSync as readFileSync93, rmSync as rmSync18 } from "node:fs";
165405
+ import { existsSync as existsSync77, mkdtempSync as mkdtempSync4, readFileSync as readFileSync93, rmSync as rmSync18 } from "node:fs";
165173
165406
  import { tmpdir as tmpdir5 } from "node:os";
165174
165407
  import { join as join79 } from "node:path";
165175
165408
  function renderProblems(render, entityId) {
@@ -165232,7 +165465,7 @@ function createReviewScreenRenderer() {
165232
165465
  async capture(html, contentDir2) {
165233
165466
  const { pngPageHtml: pngPageHtml2, stabilizePngPage: stabilizePngPage2 } = await Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports));
165234
165467
  const tokensPath = join79(contentDir2, "tokens.json");
165235
- const tokens2 = existsSync76(tokensPath) ? JSON.parse(readFileSync93(tokensPath, "utf8")) : null;
165468
+ const tokens2 = existsSync77(tokensPath) ? JSON.parse(readFileSync93(tokensPath, "utf8")) : null;
165236
165469
  const { width, height, scale } = REVIEW_SCREENSHOT_FRAME;
165237
165470
  const page = await (await (browser ??= launch())).newPage({ viewport: { width, height }, deviceScaleFactor: scale, colorScheme: "light" });
165238
165471
  try {
@@ -165313,8 +165546,8 @@ __export(store_iap_exports, {
165313
165546
  runStoreIap: () => runStoreIap
165314
165547
  });
165315
165548
  import { randomUUID as randomUUID8 } from "node:crypto";
165316
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync35, readFileSync as readFileSync94, realpathSync as realpathSync13, renameSync as renameSync12, rmSync as rmSync19, writeFileSync as writeFileSync31 } from "node:fs";
165317
- import { homedir as homedir11, hostname } from "node:os";
165549
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync36, readFileSync as readFileSync94, realpathSync as realpathSync13, renameSync as renameSync12, rmSync as rmSync19, writeFileSync as writeFileSync31 } from "node:fs";
165550
+ import { homedir as homedir12, hostname } from "node:os";
165318
165551
  import { dirname as dirname42, join as join80, resolve as resolve57 } from "node:path";
165319
165552
  function scrubDeep(value, scrub) {
165320
165553
  if (typeof value === "string") return scrub(value);
@@ -165838,7 +166071,7 @@ async function screenshotsCommand(flags, deps, out2) {
165838
166071
  return report3.complete ? 0 : 1;
165839
166072
  }
165840
166073
  function writeBinaryFile(path2, bytes2) {
165841
- mkdirSync35(dirname42(path2), { recursive: true });
166074
+ mkdirSync36(dirname42(path2), { recursive: true });
165842
166075
  const partial = `${path2}.${process.pid}.partial`;
165843
166076
  writeFileSync31(partial, bytes2);
165844
166077
  renameSync12(partial, path2);
@@ -165891,8 +166124,8 @@ function acquireApplyLock(dir, appleAppId) {
165891
166124
  };
165892
166125
  }
165893
166126
  function stateDir(appleAppId) {
165894
- const dir = join80(homedir11(), ".himalaya", "store-iap", appleAppId);
165895
- mkdirSync35(dir, { recursive: true, mode: 448 });
166127
+ const dir = join80(homedir12(), ".himalaya", "store-iap", appleAppId);
166128
+ mkdirSync36(dir, { recursive: true, mode: 448 });
165896
166129
  return dir;
165897
166130
  }
165898
166131
  async function confirmOnTerminal(question) {
@@ -166395,7 +166628,7 @@ __export(preflight_app_exports, {
166395
166628
  profileAccount: () => profileAccount,
166396
166629
  readXcconfigVars: () => readXcconfigVars
166397
166630
  });
166398
- import { readFileSync as readFileSync95, existsSync as existsSync77, readdirSync as readdirSync34, statSync as statSync21 } from "node:fs";
166631
+ import { readFileSync as readFileSync95, existsSync as existsSync78, readdirSync as readdirSync34, statSync as statSync21 } from "node:fs";
166399
166632
  import { createHash as createHash41 } from "node:crypto";
166400
166633
  import { dirname as dirname43, join as join81 } from "node:path";
166401
166634
  function analyze(projectYml, storeConfig, icon, account) {
@@ -166522,7 +166755,7 @@ function readXcconfigVars(iosDir, projectYml) {
166522
166755
  const vars = {};
166523
166756
  const seen = /* @__PURE__ */ new Set();
166524
166757
  const read = (path2) => {
166525
- if (seen.has(path2) || !existsSync77(path2)) return;
166758
+ if (seen.has(path2) || !existsSync78(path2)) return;
166526
166759
  seen.add(path2);
166527
166760
  for (const raw of readFileSync95(path2, "utf8").split("\n")) {
166528
166761
  const inc = /^\s*#include\??\s+"([^"]+)"/.exec(raw);
@@ -166551,8 +166784,8 @@ function profileAccount(app, storeConfig, opts = {}) {
166551
166784
  }
166552
166785
  }
166553
166786
  async function preflightApp(app, opts = {}) {
166554
- const projectYml = existsSync77(iosProjectYml(app)) ? readFileSync95(iosProjectYml(app), "utf8") : "";
166555
- const storeConfig = existsSync77(storeConfigPath(app)) ? readFileSync95(storeConfigPath(app), "utf8") : "";
166787
+ const projectYml = existsSync78(iosProjectYml(app)) ? readFileSync95(iosProjectYml(app), "utf8") : "";
166788
+ const storeConfig = existsSync78(storeConfigPath(app)) ? readFileSync95(storeConfigPath(app), "utf8") : "";
166556
166789
  const identity = projectYml ? analyzeStoreIdentity(projectYml, storeConfig, readXcconfigVars(join81(appDir(app), "ios"), projectYml)) : [];
166557
166790
  if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }, ...identity];
166558
166791
  const findings = analyze(
@@ -166590,15 +166823,15 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
166590
166823
  function appLevelMetadataFiles(app, locale = "en-US") {
166591
166824
  const root = join81(storeDir(app), "metadata");
166592
166825
  const out2 = /* @__PURE__ */ new Set();
166593
- if (existsSync77(root)) {
166826
+ if (existsSync78(root)) {
166594
166827
  for (const n2 of readdirSync34(root)) if (n2.endsWith(".txt")) out2.add(n2);
166595
166828
  }
166596
- if (existsSync77(join81(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
166829
+ if (existsSync78(join81(root, locale, "privacy_url.txt"))) out2.add("privacy_url.txt");
166597
166830
  return out2;
166598
166831
  }
166599
166832
  function reviewInfoFiles(app) {
166600
166833
  const dir = join81(storeDir(app), "review_information");
166601
- if (!existsSync77(dir)) return /* @__PURE__ */ new Set();
166834
+ if (!existsSync78(dir)) return /* @__PURE__ */ new Set();
166602
166835
  return new Set(readdirSync34(dir).filter((n2) => n2.endsWith(".txt")));
166603
166836
  }
166604
166837
  function isValidAppStoreSize(w2, h2) {
@@ -166745,20 +166978,20 @@ function analyzeListing(metaFiles, shots) {
166745
166978
  }
166746
166979
  function metadataFilesPresent(app, locale = "en-US") {
166747
166980
  const dir = join81(storeDir(app), "metadata", locale);
166748
- if (!existsSync77(dir)) return /* @__PURE__ */ new Set();
166981
+ if (!existsSync78(dir)) return /* @__PURE__ */ new Set();
166749
166982
  return new Set(readdirSync34(dir).filter((n2) => n2.endsWith(".txt")));
166750
166983
  }
166751
166984
  function listScreenshots(app, locale = "en-US") {
166752
166985
  const out2 = [];
166753
166986
  const flat = join81(storeDir(app), "screenshots", locale);
166754
- if (existsSync77(flat)) {
166987
+ if (existsSync78(flat)) {
166755
166988
  for (const png of readdirSync34(flat).filter((n2) => n2.endsWith(".png"))) {
166756
166989
  const sz = pngSize2(readFileSync95(join81(flat, png)));
166757
166990
  if (sz) out2.push({ name: png, w: sz.w, h: sz.h });
166758
166991
  }
166759
166992
  }
166760
166993
  const legacy = join81(storeDir(app), "metadata", locale, "screenshots");
166761
- if (existsSync77(legacy)) {
166994
+ if (existsSync78(legacy)) {
166762
166995
  for (const deviceDir of readdirSync34(legacy)) {
166763
166996
  const d2 = join81(legacy, deviceDir);
166764
166997
  if (!statSync21(d2).isDirectory()) continue;
@@ -166772,7 +167005,7 @@ function listScreenshots(app, locale = "en-US") {
166772
167005
  }
166773
167006
  function placeholderHashes2() {
166774
167007
  const templateIos = join81(appDir("_template"), "ios");
166775
- if (!existsSync77(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
167008
+ if (!existsSync78(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
166776
167009
  for (const target of readdirSync34(templateIos)) {
166777
167010
  const p2 = join81(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
166778
167011
  try {
@@ -166808,7 +167041,7 @@ async function pixelIssues(bytes2) {
166808
167041
  }
166809
167042
  }
166810
167043
  async function appIconState(iosDir) {
166811
- if (!existsSync77(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
167044
+ if (!existsSync78(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
166812
167045
  for (const target of readdirSync34(iosDir)) {
166813
167046
  const p2 = join81(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
166814
167047
  try {
@@ -167721,11 +167954,11 @@ __export(notify_exports, {
167721
167954
  runNotify: () => runNotify,
167722
167955
  saveAdminSession: () => saveAdminSession
167723
167956
  });
167724
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync36, readFileSync as readFileSync98, writeFileSync as writeFileSync32 } from "node:fs";
167725
- import { homedir as homedir12 } from "node:os";
167957
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync37, readFileSync as readFileSync98, writeFileSync as writeFileSync32 } from "node:fs";
167958
+ import { homedir as homedir13 } from "node:os";
167726
167959
  import { dirname as dirname45, join as join82 } from "node:path";
167727
167960
  function defaultSessionsPath() {
167728
- return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join82(homedir12(), ".himalaya", "admin-sessions.json");
167961
+ return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join82(homedir13(), ".himalaya", "admin-sessions.json");
167729
167962
  }
167730
167963
  function loadSessionsFile(path2 = defaultSessionsPath()) {
167731
167964
  try {
@@ -167737,7 +167970,7 @@ function loadSessionsFile(path2 = defaultSessionsPath()) {
167737
167970
  function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
167738
167971
  const file2 = loadSessionsFile(path2);
167739
167972
  file2.sessions = { ...file2.sessions, [adminUrl]: session };
167740
- mkdirSync36(dirname45(path2), { recursive: true, mode: 448 });
167973
+ mkdirSync37(dirname45(path2), { recursive: true, mode: 448 });
167741
167974
  writeFileSync32(path2, JSON.stringify(file2, null, 2) + "\n", { mode: 384 });
167742
167975
  try {
167743
167976
  chmodSync3(dirname45(path2), 448);
@@ -168098,7 +168331,7 @@ __export(base44_adopt_exports, {
168098
168331
  renderAdoptModule: () => renderAdoptModule,
168099
168332
  runBase44Adopt: () => runBase44Adopt
168100
168333
  });
168101
- import { existsSync as existsSync78, readFileSync as readFileSync99, writeFileSync as writeFileSync33 } from "node:fs";
168334
+ import { existsSync as existsSync79, readFileSync as readFileSync99, writeFileSync as writeFileSync33 } from "node:fs";
168102
168335
  import { join as join83, resolve as resolve59 } from "node:path";
168103
168336
  function prop(entity, key3) {
168104
168337
  const props = entity.schema?.properties;
@@ -168207,7 +168440,7 @@ function runBase44Adopt(opts) {
168207
168440
  const issues = validateBase44Entities({ entities: result.entities, functions: result.functions }, opts.app);
168208
168441
  if (opts.write === void 0 || opts.write === false || issues.some((i2) => i2.severity === "error")) return { result, module, issues };
168209
168442
  const target = typeof opts.write === "string" ? resolve59(opts.cwd, opts.write) : join83(opts.cwd, ADOPT_MODULE_FILENAME);
168210
- if (existsSync78(target)) {
168443
+ if (existsSync79(target)) {
168211
168444
  throw new AdoptError("adopt_target_exists", `${target} already exists \u2014 adopt never overwrites. Delete or rename it, or pass --write <other path>.`, 1, { path: target });
168212
168445
  }
168213
168446
  writeFileSync33(target, module);
@@ -168456,7 +168689,7 @@ __export(generate_exports, {
168456
168689
  writeGenerated: () => writeGenerated
168457
168690
  });
168458
168691
  import { createHash as createHash43 } from "node:crypto";
168459
- import { existsSync as existsSync79, mkdirSync as mkdirSync37, readdirSync as readdirSync35, readFileSync as readFileSync100, writeFileSync as writeFileSync34 } from "node:fs";
168692
+ import { existsSync as existsSync80, mkdirSync as mkdirSync38, readdirSync as readdirSync35, readFileSync as readFileSync100, writeFileSync as writeFileSync34 } from "node:fs";
168460
168693
  import { dirname as dirname46, join as join84 } from "node:path";
168461
168694
  function withHeader(body) {
168462
168695
  return `${GENERATED_HEADER}${sha2566(body)}
@@ -168583,7 +168816,7 @@ function writeGenerated(dir, files, opts = {}) {
168583
168816
  const abs = join84(dir, f2.path);
168584
168817
  const next = withHeader(f2.body);
168585
168818
  let outcome;
168586
- if (!existsSync79(abs)) outcome = "written";
168819
+ if (!existsSync80(abs)) outcome = "written";
168587
168820
  else {
168588
168821
  const cur = readFileSync100(abs, "utf8");
168589
168822
  if (cur === next) outcome = "unchanged";
@@ -168591,7 +168824,7 @@ function writeGenerated(dir, files, opts = {}) {
168591
168824
  else outcome = "written";
168592
168825
  }
168593
168826
  if (outcome === "written" && !opts.dryRun) {
168594
- mkdirSync37(dirname46(abs), { recursive: true });
168827
+ mkdirSync38(dirname46(abs), { recursive: true });
168595
168828
  writeFileSync34(abs, next);
168596
168829
  }
168597
168830
  out2.push({ path: f2.path, outcome });
@@ -168602,14 +168835,14 @@ function orphanedFiles(dir, current) {
168602
168835
  const keep = new Set(current.map((f2) => f2.path));
168603
168836
  const found = [];
168604
168837
  const t5 = join84(dir, "tier5-src");
168605
- if (!existsSync79(t5)) return found;
168838
+ if (!existsSync80(t5)) return found;
168606
168839
  const candidates = readdirSync35(t5).filter((d2) => d2.startsWith("b44-")).map((d2) => `tier5-src/${d2}/index.ts`);
168607
168840
  const shared = join84(t5, "_shared");
168608
- if (existsSync79(shared)) {
168841
+ if (existsSync80(shared)) {
168609
168842
  for (const f2 of readdirSync35(shared)) if (/^b44-.*-plan\.ts$/.test(f2)) candidates.push(`tier5-src/_shared/${f2}`);
168610
168843
  }
168611
168844
  for (const rel of candidates.sort()) {
168612
- if (keep.has(rel) || !existsSync79(join84(dir, rel))) continue;
168845
+ if (keep.has(rel) || !existsSync80(join84(dir, rel))) continue;
168613
168846
  if (readFileSync100(join84(dir, rel), "utf8").startsWith(GENERATED_HEADER)) found.push(rel);
168614
168847
  }
168615
168848
  return found;
@@ -168648,18 +168881,18 @@ __export(base44_auth_exports, {
168648
168881
  usableBase44Auth: () => usableBase44Auth,
168649
168882
  writeBase44Session: () => writeBase44Session
168650
168883
  });
168651
- import { chmodSync as chmodSync4, existsSync as existsSync80, mkdirSync as mkdirSync38, readFileSync as readFileSync101, rmSync as rmSync20, writeFileSync as writeFileSync35 } from "node:fs";
168652
- import { homedir as homedir13 } from "node:os";
168884
+ import { chmodSync as chmodSync4, existsSync as existsSync81, mkdirSync as mkdirSync39, readFileSync as readFileSync101, rmSync as rmSync20, writeFileSync as writeFileSync35 } from "node:fs";
168885
+ import { homedir as homedir14 } from "node:os";
168653
168886
  import { dirname as dirname47, join as join85 } from "node:path";
168654
168887
  function base44ApiBase(env = process.env) {
168655
168888
  return (env.BASE44_API_URL?.trim() || "https://app.base44.com").replace(/\/+$/, "");
168656
168889
  }
168657
- function base44SessionPath(home = homedir13()) {
168890
+ function base44SessionPath(home = homedir14()) {
168658
168891
  return join85(home, ".himi", "base44", "session.json");
168659
168892
  }
168660
168893
  function readBase44Session(home) {
168661
168894
  const p2 = base44SessionPath(home);
168662
- if (!existsSync80(p2)) return void 0;
168895
+ if (!existsSync81(p2)) return void 0;
168663
168896
  try {
168664
168897
  const s2 = JSON.parse(readFileSync101(p2, "utf8"));
168665
168898
  return typeof s2.accessToken === "string" && s2.accessToken ? s2 : void 0;
@@ -168669,7 +168902,7 @@ function readBase44Session(home) {
168669
168902
  }
168670
168903
  function writeBase44Session(session, home) {
168671
168904
  const p2 = base44SessionPath(home);
168672
- mkdirSync38(dirname47(p2), { recursive: true, mode: 448 });
168905
+ mkdirSync39(dirname47(p2), { recursive: true, mode: 448 });
168673
168906
  writeFileSync35(p2, `${JSON.stringify(session, null, 2)}
168674
168907
  `, { mode: 384 });
168675
168908
  chmodSync4(p2, 384);
@@ -168677,7 +168910,7 @@ function writeBase44Session(session, home) {
168677
168910
  }
168678
168911
  function deleteBase44Session(home) {
168679
168912
  const p2 = base44SessionPath(home);
168680
- if (!existsSync80(p2)) return false;
168913
+ if (!existsSync81(p2)) return false;
168681
168914
  rmSync20(p2, { force: true });
168682
168915
  return true;
168683
168916
  }
@@ -168778,9 +169011,9 @@ function hasBase44WriteScope(auth) {
168778
169011
  if (!scopes) return "unknown";
168779
169012
  return scopes.includes("apps:write");
168780
169013
  }
168781
- function importBase44CliSession(home = homedir13(), env = process.env) {
169014
+ function importBase44CliSession(home = homedir14(), env = process.env) {
168782
169015
  const src = join85(home, ".base44", "auth", "auth.json");
168783
- if (!existsSync80(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
169016
+ if (!existsSync81(src)) throw new Error(`no Base44 CLI session at ${src} \u2014 run \`npx base44 login\` first, or use \`himi base44 login\``);
168784
169017
  const a2 = JSON.parse(readFileSync101(src, "utf8"));
168785
169018
  if (typeof a2.accessToken !== "string" || !a2.accessToken) throw new Error(`${src} holds no access token`);
168786
169019
  const session = {
@@ -168878,11 +169111,11 @@ __export(seed_exports, {
168878
169111
  seedBase44Entities: () => seedBase44Entities,
168879
169112
  writeBase44SeedRows: () => writeBase44SeedRows
168880
169113
  });
168881
- import { existsSync as existsSync81, readFileSync as readFileSync102, writeFileSync as writeFileSync36 } from "node:fs";
169114
+ import { existsSync as existsSync82, readFileSync as readFileSync102, writeFileSync as writeFileSync36 } from "node:fs";
168882
169115
  import { join as join86 } from "node:path";
168883
169116
  function readBase44SeedFile(dir) {
168884
169117
  const file2 = join86(dir, BASE44_SEED_FILE);
168885
- if (!existsSync81(file2)) return {};
169118
+ if (!existsSync82(file2)) return {};
168886
169119
  let parsed;
168887
169120
  try {
168888
169121
  parsed = JSON.parse(readFileSync102(file2, "utf8"));
@@ -169042,7 +169275,7 @@ function writeBase44SeedRows(opts) {
169042
169275
  return { ok: false, path: path2, entities: {}, agentPrompt: "", next: [], note: opts.only ? `--only ${opts.only.join(",")} matched no owned entity` : `no owned Base44 entities declared \u2014 add one with \`name\` (physically ${base44Prefix(app)}<Name>). Adopted entities are never seeded.` };
169043
169276
  }
169044
169277
  let existing = {};
169045
- if (existsSync81(path2)) {
169278
+ if (existsSync82(path2)) {
169046
169279
  let parsed;
169047
169280
  try {
169048
169281
  parsed = JSON.parse(readFileSync102(path2, "utf8"));
@@ -169397,7 +169630,7 @@ __export(functions_exports2, {
169397
169630
  markerContent: () => markerContent,
169398
169631
  readFunctionSource: () => readFunctionSource
169399
169632
  });
169400
- import { existsSync as existsSync82, lstatSync as lstatSync21 } from "node:fs";
169633
+ import { existsSync as existsSync83, lstatSync as lstatSync21 } from "node:fs";
169401
169634
  import { join as join87 } from "node:path";
169402
169635
  function markerContent(app) {
169403
169636
  return `${JSON.stringify({ app, by: "himi" })}
@@ -169406,7 +169639,7 @@ function markerContent(app) {
169406
169639
  function readFunctionSource(appDir3, name, app) {
169407
169640
  const rel = `base44/functions/${name}/`;
169408
169641
  const folder = join87(appDir3, "base44", "functions", name);
169409
- if (!existsSync82(folder) || !lstatSync21(folder).isDirectory()) throw new FunctionSourceError("function_source_missing", `no source folder at ${rel}`);
169642
+ if (!existsSync83(folder) || !lstatSync21(folder).isDirectory()) throw new FunctionSourceError("function_source_missing", `no source folder at ${rel}`);
169410
169643
  const { entries, skipped } = collectAppSource(folder);
169411
169644
  if (skipped.length) throw new FunctionSourceError("function_source_unsafe", `${rel} holds paths himi will not upload (symlinks or denied names): ${skipped.join(", ")} \u2014 remove them`);
169412
169645
  const secrets = secretFindings(entries);
@@ -169744,12 +169977,12 @@ __export(apply_exports, {
169744
169977
  createBase44Entities: () => createBase44Entities,
169745
169978
  fileLedger: () => fileLedger
169746
169979
  });
169747
- import { existsSync as existsSync83, readFileSync as readFileSync103, writeFileSync as writeFileSync37 } from "node:fs";
169980
+ import { existsSync as existsSync84, readFileSync as readFileSync103, writeFileSync as writeFileSync37 } from "node:fs";
169748
169981
  import { join as join88 } from "node:path";
169749
169982
  function fileLedger(dir, appId2) {
169750
169983
  const path2 = join88(dir, LEDGER_FILE2);
169751
169984
  const load3 = () => {
169752
- if (!existsSync83(path2)) return {};
169985
+ if (!existsSync84(path2)) return {};
169753
169986
  let v2;
169754
169987
  try {
169755
169988
  v2 = JSON.parse(readFileSync103(path2, "utf8"));
@@ -172122,7 +172355,7 @@ var init_brand_font = __esm({
172122
172355
  });
172123
172356
 
172124
172357
  // src/site-analyze/write-artifacts.ts
172125
- import { mkdirSync as mkdirSync39, rmSync as rmSync21, writeFileSync as writeFileSync38 } from "node:fs";
172358
+ import { mkdirSync as mkdirSync40, rmSync as rmSync21, writeFileSync as writeFileSync38 } from "node:fs";
172126
172359
  import { join as join89 } from "node:path";
172127
172360
  function attachVeloSources(book, sources, put) {
172128
172361
  const byPath = new Map((sources ?? []).map((s2) => [s2.path, s2.text]));
@@ -172278,12 +172511,12 @@ async function downloadMedia(book, fetchImpl, put) {
172278
172511
  }
172279
172512
  async function writeBusinessBook(result, opts) {
172280
172513
  const out2 = opts.outDir;
172281
- mkdirSync39(join89(out2, "evidence/pages"), { recursive: true });
172282
- mkdirSync39(join89(out2, "media/catalog"), { recursive: true });
172514
+ mkdirSync40(join89(out2, "evidence/pages"), { recursive: true });
172515
+ mkdirSync40(join89(out2, "media/catalog"), { recursive: true });
172283
172516
  const files = [];
172284
172517
  const put = (rel, body) => {
172285
172518
  const p2 = join89(out2, rel);
172286
- mkdirSync39(join89(p2, ".."), { recursive: true });
172519
+ mkdirSync40(join89(p2, ".."), { recursive: true });
172287
172520
  writeFileSync38(p2, body);
172288
172521
  files.push(rel);
172289
172522
  };
@@ -172909,7 +173142,7 @@ var init_analyze = __esm({
172909
173142
  });
172910
173143
 
172911
173144
  // src/base44-analyze/write-artifacts.ts
172912
- import { existsSync as existsSync84, mkdirSync as mkdirSync40, readFileSync as readFileSync104, rmSync as rmSync22, writeFileSync as writeFileSync39 } from "node:fs";
173145
+ import { existsSync as existsSync85, mkdirSync as mkdirSync41, readFileSync as readFileSync104, rmSync as rmSync22, writeFileSync as writeFileSync39 } from "node:fs";
172913
173146
  import { dirname as dirname48, join as join90, resolve as resolve60, sep as sep19 } from "node:path";
172914
173147
  function isBookFolder(dir) {
172915
173148
  try {
@@ -173000,17 +173233,17 @@ function writeBase44Book(result, outDir, opts = {}) {
173000
173233
  const md = renderBookMd(book);
173001
173234
  assertNoSecrets(json8);
173002
173235
  assertNoSecrets(md);
173003
- const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync84(join90(out2, n2)));
173236
+ const owned = ["book.json", "BOOK.md", "source", "screenshots"].filter((n2) => existsSync85(join90(out2, n2)));
173004
173237
  if (owned.length) {
173005
173238
  if (!isBookFolder(out2)) throw new Error(`refusing to write the app book into ${out2}: it already has ${owned.join(", ")} that ${owned.length === 1 ? "is" : "are"} not from an app book \u2014 pick an empty --out`);
173006
173239
  for (const d2 of ["source", "screenshots"]) rmSync22(join90(out2, d2), { recursive: true, force: true });
173007
173240
  }
173008
- mkdirSync40(out2, { recursive: true });
173241
+ mkdirSync41(out2, { recursive: true });
173009
173242
  writeFileSync39(join90(out2, "book.json"), json8);
173010
173243
  writeFileSync39(join90(out2, "BOOK.md"), md);
173011
173244
  files.push("book.json", "BOOK.md");
173012
173245
  for (const s2 of shots) {
173013
- mkdirSync40(join90(out2, "screenshots"), { recursive: true });
173246
+ mkdirSync41(join90(out2, "screenshots"), { recursive: true });
173014
173247
  writeFileSync39(join90(out2, "screenshots", s2.filename), s2.bytes);
173015
173248
  files.push(`screenshots/${s2.filename}`);
173016
173249
  }
@@ -173019,7 +173252,7 @@ function writeBase44Book(result, outDir, opts = {}) {
173019
173252
  if (!safeRel(f2.path)) continue;
173020
173253
  const dest = join90(sourceRoot, ...f2.path.split("/"));
173021
173254
  if (!dest.startsWith(sourceRoot + sep19)) continue;
173022
- mkdirSync40(dirname48(dest), { recursive: true });
173255
+ mkdirSync41(dirname48(dest), { recursive: true });
173023
173256
  writeFileSync39(dest, f2.bytes);
173024
173257
  }
173025
173258
  if (result.sourceFiles.length) files.push(`source/ (${result.sourceFiles.length} files)`);
@@ -176561,7 +176794,7 @@ __export(cli_exports, {
176561
176794
  systemTar: () => systemTar
176562
176795
  });
176563
176796
  import { execFile } from "node:child_process";
176564
- import { mkdirSync as mkdirSync41, mkdtempSync as mkdtempSync5, rmSync as rmSync23, writeFileSync as writeFileSync40 } from "node:fs";
176797
+ import { mkdirSync as mkdirSync42, mkdtempSync as mkdtempSync5, rmSync as rmSync23, writeFileSync as writeFileSync40 } from "node:fs";
176565
176798
  import { tmpdir as tmpdir6 } from "node:os";
176566
176799
  import { join as join91, resolve as resolve61 } from "node:path";
176567
176800
  import { promisify } from "node:util";
@@ -176582,7 +176815,7 @@ function projectDownloader(apiFetch, apiBase, token, extract = systemTar) {
176582
176815
  const archive = join91(root, "project.tar");
176583
176816
  const dir = join91(root, "project");
176584
176817
  writeFileSync40(archive, bytes2);
176585
- mkdirSync41(dir);
176818
+ mkdirSync42(dir);
176586
176819
  await extract(archive, dir);
176587
176820
  return { dir, cleanup };
176588
176821
  } catch (e2) {
@@ -177497,7 +177730,7 @@ __export(cli_exports2, {
177497
177730
  ONE_APP_WORKFLOW: () => ONE_APP_WORKFLOW,
177498
177731
  runOneAppCommand: () => runOneAppCommand
177499
177732
  });
177500
- import { closeSync as closeSync7, constants as constants4, lstatSync as lstatSync22, mkdirSync as mkdirSync42, openSync as openSync6, readFileSync as readFileSync105, realpathSync as realpathSync14, writeFileSync as writeFileSync41 } from "node:fs";
177733
+ import { closeSync as closeSync7, constants as constants4, lstatSync as lstatSync22, mkdirSync as mkdirSync43, openSync as openSync6, readFileSync as readFileSync105, realpathSync as realpathSync14, writeFileSync as writeFileSync41 } from "node:fs";
177501
177734
  import { createHash as createHash45 } from "node:crypto";
177502
177735
  import { dirname as dirname49, join as join92, parse as parse3, resolve as resolve62 } from "node:path";
177503
177736
  function readOptions(argv, cwd, commandIncluded) {
@@ -177648,12 +177881,12 @@ Collect the source mobile app and hand it to the current coding agent. The agent
177648
177881
  try {
177649
177882
  options = readOptions(argv, deps.cwd ?? process.cwd(), commandIncluded);
177650
177883
  try {
177651
- mkdirSync42(options.parentDir, { recursive: true, mode: 448 });
177884
+ mkdirSync43(options.parentDir, { recursive: true, mode: 448 });
177652
177885
  assertSafeParents(options.parentDir);
177653
- mkdirSync42(options.workspace, { mode: 448 });
177886
+ mkdirSync43(options.workspace, { mode: 448 });
177654
177887
  if (realpathSync14(options.workspace) !== options.workspace) throw new Error("destination changed");
177655
177888
  evidenceDir = join92(options.workspace, ".himi", "one-app");
177656
- mkdirSync42(evidenceDir, { recursive: true, mode: 448 });
177889
+ mkdirSync43(evidenceDir, { recursive: true, mode: 448 });
177657
177890
  } catch (error) {
177658
177891
  if (error.code === "EEXIST") {
177659
177892
  throw new OneAppError("output_exists", "The destination already exists. Choose a new --name or --dir.");
@@ -179789,7 +180022,7 @@ var init_customer_build = __esm({
179789
180022
  });
179790
180023
 
179791
180024
  // src/site-analyze/apply.ts
179792
- import { existsSync as existsSync85, readFileSync as readFileSync106, writeFileSync as writeFileSync42, copyFileSync as copyFileSync2, mkdirSync as mkdirSync43, realpathSync as realpathSync15, statSync as statSync22 } from "node:fs";
180025
+ import { existsSync as existsSync86, readFileSync as readFileSync106, writeFileSync as writeFileSync42, copyFileSync as copyFileSync2, mkdirSync as mkdirSync44, realpathSync as realpathSync15, statSync as statSync22 } from "node:fs";
179793
180026
  import { dirname as dirname50, isAbsolute as isAbsolute8, join as join93, resolve as resolve63, sep as sep20 } from "node:path";
179794
180027
  import { spawnSync as spawnSync4 } from "node:child_process";
179795
180028
  function unpairedRedirectNote(overlay) {
@@ -179805,7 +180038,7 @@ function committedShellProvisioning(path2) {
179805
180038
  function findRepoRoot(cwd) {
179806
180039
  let dir = cwd;
179807
180040
  for (let i2 = 0; i2 < 8; i2++) {
179808
- if (SHELL_NAMES2.some((name) => existsSync85(join93(dir, shellAppDir(name), "package.json")))) return dir;
180041
+ if (SHELL_NAMES2.some((name) => existsSync86(join93(dir, shellAppDir(name), "package.json")))) return dir;
179809
180042
  const next = dirname50(dir);
179810
180043
  if (next === dir) break;
179811
180044
  dir = next;
@@ -179909,7 +180142,7 @@ function sameKnownSite(previous, next) {
179909
180142
  function buildMergedContract(options) {
179910
180143
  const { appDir: appDir3, packageDir, overlay } = options;
179911
180144
  const committedPath = join93(appDir3, "provisioning.json");
179912
- if (!existsSync85(committedPath)) {
180145
+ if (!existsSync86(committedPath)) {
179913
180146
  throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
179914
180147
  }
179915
180148
  const committed = JSON.parse(readFileSync106(committedPath, "utf8"));
@@ -179925,7 +180158,7 @@ function buildMergedContract(options) {
179925
180158
  const stage = (fromRel, toRel) => {
179926
180159
  const from = contained(packageDir, fromRel);
179927
180160
  const to2 = contained(join93(appDir3, STAGED), toRel.slice(STAGED.length + 1));
179928
- if (!from || !to2 || !existsSync85(from)) return void 0;
180161
+ if (!from || !to2 || !existsSync86(from)) return void 0;
179929
180162
  let real;
179930
180163
  let realRoot;
179931
180164
  try {
@@ -179937,7 +180170,7 @@ function buildMergedContract(options) {
179937
180170
  if (!real.startsWith(realRoot + sep20)) return void 0;
179938
180171
  try {
179939
180172
  if (!statSync22(real).isFile()) return void 0;
179940
- mkdirSync43(dirname50(to2), { recursive: true });
180173
+ mkdirSync44(dirname50(to2), { recursive: true });
179941
180174
  copyFileSync2(real, to2);
179942
180175
  } catch {
179943
180176
  return void 0;
@@ -179948,7 +180181,7 @@ function buildMergedContract(options) {
179948
180181
  const icon = stage("media/icon.png", `${STAGED}/icon.png`);
179949
180182
  if (icon) branding.appIconPath = icon;
179950
180183
  const facesPath = join93(packageDir, "media/fonts/faces.json");
179951
- if (existsSync85(facesPath)) {
180184
+ if (existsSync86(facesPath)) {
179952
180185
  let faces = [];
179953
180186
  try {
179954
180187
  const parsed = JSON.parse(readFileSync106(facesPath, "utf8"));
@@ -179975,7 +180208,7 @@ function buildMergedContract(options) {
179975
180208
  const path2 = join93(packageDir, "provisioning.contract.json");
179976
180209
  writeFileSync42(path2, body);
179977
180210
  const localPath2 = join93(appDir3, LOCAL_CONTRACT_REL);
179978
- mkdirSync43(dirname50(localPath2), { recursive: true });
180211
+ mkdirSync44(dirname50(localPath2), { recursive: true });
179979
180212
  writeFileSync42(localPath2, body);
179980
180213
  staged.push(localPath2);
179981
180214
  return { path: path2, staged };
@@ -180010,7 +180243,7 @@ function staticFaqFor(overlay, overlayPath) {
180010
180243
  const own5 = overlay.faq;
180011
180244
  if (own5 !== void 0) return deriveStaticFaq(own5);
180012
180245
  const bookPath = join93(dirname50(resolve63(overlayPath)), "book.json");
180013
- if (!existsSync85(bookPath)) return void 0;
180246
+ if (!existsSync86(bookPath)) return void 0;
180014
180247
  try {
180015
180248
  const book = JSON.parse(readFileSync106(bookPath, "utf8"));
180016
180249
  const copy = book?.copy;
@@ -180027,7 +180260,7 @@ function staticGalleriesFor(overlay, overlayPath) {
180027
180260
  overlay.galleries.map((gallery) => ({ role: "gallery", title: gallery.title, galleryImageUrls: gallery.photos }))
180028
180261
  );
180029
180262
  const bookPath = join93(dirname50(resolve63(overlayPath)), "book.json");
180030
- if (!existsSync85(bookPath)) return void 0;
180263
+ if (!existsSync86(bookPath)) return void 0;
180031
180264
  try {
180032
180265
  const book = JSON.parse(readFileSync106(bookPath, "utf8"));
180033
180266
  if (!book.look || book.look.unavailable || !Array.isArray(book.look.pages)) return void 0;
@@ -180061,7 +180294,7 @@ async function applyOverlays(input) {
180061
180294
  }
180062
180295
  const appDir3 = join93(repoRoot2, shellAppDir(shell));
180063
180296
  const committedPath = join93(appDir3, "provisioning.json");
180064
- const committedSite = existsSync85(committedPath) ? JSON.parse(readFileSync106(committedPath, "utf8")).site : void 0;
180297
+ const committedSite = existsSync86(committedPath) ? JSON.parse(readFileSync106(committedPath, "utf8")).site : void 0;
180065
180298
  if (committedSite !== void 0 && overlay.site === void 0) {
180066
180299
  throw new Error(
180067
180300
  `shell "${shell}" is a site shell: its contract names the customer's website (a \`site\` block), and this overlay has none. Re-run \`himi site analyze --url <site> --shell ${shell}\` to derive the site's page map (edit \`site.pages\` in provisioning.overlay.json if needed), then --apply.`
@@ -180102,7 +180335,7 @@ async function applyOverlays(input) {
180102
180335
  };
180103
180336
  let packageFaq = faq;
180104
180337
  let packageGalleries = galleries;
180105
- if (existsSync85(pkgProv)) {
180338
+ if (existsSync86(pkgProv)) {
180106
180339
  const cur = JSON.parse(readFileSync106(pkgProv, "utf8"));
180107
180340
  if (galleries === void 0 && !sameKnownSite(cur, overlay)) overlay.galleries = [];
180108
180341
  const merged = deepMerge4(cur, overlay);
@@ -180120,7 +180353,7 @@ async function applyOverlays(input) {
180120
180353
  overlay.installedVerticals.push("galleries");
180121
180354
  }
180122
180355
  const pkgTokens = join93(cwd, "tokens.json");
180123
- if (existsSync85(pkgTokens) && (tokens2.colors || tokens2.typography)) {
180356
+ if (existsSync86(pkgTokens) && (tokens2.colors || tokens2.typography)) {
180124
180357
  const cur = JSON.parse(readFileSync106(pkgTokens, "utf8"));
180125
180358
  let tokensIn = tokens2;
180126
180359
  if (tokens2.typography) {
@@ -180147,7 +180380,7 @@ async function applyOverlays(input) {
180147
180380
  }
180148
180381
  const homeAction = homeRefreshActionId(shell);
180149
180382
  const homeSrc = join93(cwd, "dev/index.ts");
180150
- if (homeAction && existsSync85(homeSrc)) {
180383
+ if (homeAction && existsSync86(homeSrc)) {
180151
180384
  const prev = readFileSync106(homeSrc, "utf8");
180152
180385
  const patched = patchBrandParams(prev, overlay, homeAction);
180153
180386
  let next = patched.src;
@@ -180183,13 +180416,13 @@ async function applyOverlays(input) {
180183
180416
  notes.push(`${patched.unparsed} onAppear params block(s) in ${homeSrc} could not be read \u2014 any brand values inside them were not applied`);
180184
180417
  }
180185
180418
  }
180186
- if (!input.iconPath || !existsSync85(input.iconPath)) {
180419
+ if (!input.iconPath || !existsSync86(input.iconPath)) {
180187
180420
  const book = input.iconPath ? dirname50(dirname50(resolve63(input.iconPath))) : void 0;
180188
180421
  notes.push(
180189
180422
  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"
180190
180423
  );
180191
180424
  }
180192
- if (input.iconPath && existsSync85(input.iconPath)) {
180425
+ if (input.iconPath && existsSync86(input.iconPath)) {
180193
180426
  try {
180194
180427
  const installed = await installIcon(cwd, input.iconPath, { derivePlay: true });
180195
180428
  wrote.push(...installed.wrote);
@@ -181148,7 +181381,7 @@ __export(cli_exports3, {
181148
181381
  runSiteAnalyze: () => runSiteAnalyze,
181149
181382
  runSiteFunctionCli: () => runSiteFunctionCli
181150
181383
  });
181151
- import { existsSync as existsSync86, readFileSync as readFileSync107 } from "node:fs";
181384
+ import { existsSync as existsSync87, readFileSync as readFileSync107 } from "node:fs";
181152
181385
  import { resolve as resolve64 } from "node:path";
181153
181386
  function applyNeedsClient(shell) {
181154
181387
  if (shell === void 0 || !SHELL_NAMES2.includes(shell)) return true;
@@ -181216,7 +181449,7 @@ async function runSiteAnalyze(opts) {
181216
181449
  if (book?.skipped) result.warnings = [...result.warnings ?? [], book.skipped];
181217
181450
  const derived = deriveSiteShell({ siteUrl: result.book.input.siteUrl, look: result.book.look, kind, routes });
181218
181451
  const prevOverlayPath = resolve64(outDir, "provisioning.overlay.json");
181219
- const prevSite = existsSync86(prevOverlayPath) ? (() => {
181452
+ const prevSite = existsSync87(prevOverlayPath) ? (() => {
181220
181453
  try {
181221
181454
  return JSON.parse(readFileSync107(prevOverlayPath, "utf8")).site;
181222
181455
  } catch {
@@ -181237,7 +181470,7 @@ async function runSiteAnalyze(opts) {
181237
181470
  }
181238
181471
  const previousOverlay = resolve64(outDir, "provisioning.overlay.json");
181239
181472
  carryOverGoals(
181240
- existsSync86(previousOverlay) ? readFileSync107(previousOverlay, "utf8") : void 0,
181473
+ existsSync87(previousOverlay) ? readFileSync107(previousOverlay, "utf8") : void 0,
181241
181474
  result.provisioningOverlay
181242
181475
  );
181243
181476
  const ownerCall = ownerAuth ? ownerTransportFrom(fetchImpl, ownerAuth) : void 0;
@@ -181323,7 +181556,7 @@ async function runSiteFunctionCli(opts) {
181323
181556
  });
181324
181557
  }
181325
181558
  function base44BookRoutes(bookPath, siteUrl) {
181326
- if (!existsSync86(bookPath)) return void 0;
181559
+ if (!existsSync87(bookPath)) return void 0;
181327
181560
  try {
181328
181561
  const book = JSON.parse(readFileSync107(bookPath, "utf8"));
181329
181562
  if (book.kind !== "base44-app-book" || !Array.isArray(book.routes)) return void 0;
@@ -181580,7 +181813,7 @@ __export(site_create_exports, {
181580
181813
  runSiteList: () => runSiteList,
181581
181814
  writeProvisioningBinding: () => writeProvisioningBinding
181582
181815
  });
181583
- import { existsSync as existsSync87, readFileSync as readFileSync108, writeFileSync as writeFileSync43 } from "node:fs";
181816
+ import { existsSync as existsSync88, readFileSync as readFileSync108, writeFileSync as writeFileSync43 } from "node:fs";
181584
181817
  import { resolve as resolvePath2 } from "node:path";
181585
181818
  function oauthClientName(projectName) {
181586
181819
  return `${projectName} client`;
@@ -181729,7 +181962,7 @@ async function runSiteCreate(opts) {
181729
181962
  if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
181730
181963
  return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
181731
181964
  }
181732
- function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync87, readFileSync: readFileSync108, writeFileSync: writeFileSync43 }) {
181965
+ function writeProvisioningBinding(target, binding2, fs2 = { existsSync: existsSync88, readFileSync: readFileSync108, writeFileSync: writeFileSync43 }) {
181733
181966
  const msid = binding2.siteId;
181734
181967
  const path2 = resolvePath2(target);
181735
181968
  const committed = committedShellProvisioning(path2);
@@ -182426,13 +182659,13 @@ var init_context = __esm({
182426
182659
  });
182427
182660
 
182428
182661
  // src/cli.ts
182429
- import { mkdtempSync as mkdtempSync6, readFileSync as readFileSync109, mkdirSync as mkdirSync44, writeFileSync as writeFileSync44, existsSync as existsSync88, rmSync as rmSync24, readdirSync as readdirSync36, statSync as statSync23, lstatSync as lstatSync23, accessSync, constants as constants5, renameSync as renameSync13, cpSync as cpSync3 } from "node:fs";
182662
+ import { mkdtempSync as mkdtempSync6, readFileSync as readFileSync109, mkdirSync as mkdirSync45, writeFileSync as writeFileSync44, existsSync as existsSync89, rmSync as rmSync24, readdirSync as readdirSync36, statSync as statSync23, lstatSync as lstatSync23, accessSync, constants as constants5, renameSync as renameSync13, cpSync as cpSync3 } from "node:fs";
182430
182663
  import { execFile as execFile2, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn7 } from "node:child_process";
182431
182664
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
182432
182665
  import { createHash as createHash46, randomUUID as randomUUID11 } from "node:crypto";
182433
- import { tmpdir as tmpdir7, homedir as homedir14, hostname as hostname2 } from "node:os";
182666
+ import { tmpdir as tmpdir7, homedir as homedir15, hostname as hostname2 } from "node:os";
182434
182667
  import { join as join94, resolve as resolve65, relative as relative16, basename as basename21, dirname as dirname51 } from "node:path";
182435
- import { fileURLToPath as fileURLToPath29 } from "node:url";
182668
+ import { fileURLToPath as fileURLToPath30 } from "node:url";
182436
182669
 
182437
182670
  // ../serve-cli/src/client.ts
182438
182671
  import { gzipSync } from "node:zlib";
@@ -185491,7 +185724,7 @@ function createScopedRegistryResolver(exec = execNpmConfig) {
185491
185724
  const configured = async (key3) => {
185492
185725
  const timeout = deadline - Date.now();
185493
185726
  if (timeout <= 0) throw new Error("npm config: out of budget");
185494
- const raw = String(await exec("npm", ["config", "get", key3], { cwd: homedir14(), timeout })).trim();
185727
+ const raw = String(await exec("npm", ["config", "get", key3], { cwd: homedir15(), timeout })).trim();
185495
185728
  return raw && raw !== "undefined" ? raw : void 0;
185496
185729
  };
185497
185730
  const effective = normalizeRegistry(await configured("@wix:registry") ?? await configured("registry"));
@@ -185644,7 +185877,7 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
185644
185877
  var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
185645
185878
  var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
185646
185879
  function updateCachePath(env = process.env) {
185647
- return env.HIMI_UPDATE_CACHE_FILE ?? join94(homedir14(), ".himalaya", "update-check.json");
185880
+ return env.HIMI_UPDATE_CACHE_FILE ?? join94(homedir15(), ".himalaya", "update-check.json");
185648
185881
  }
185649
185882
  function readUpdateCache(path2) {
185650
185883
  try {
@@ -185656,7 +185889,7 @@ function readUpdateCache(path2) {
185656
185889
  }
185657
185890
  function writeUpdateCache(path2, cache) {
185658
185891
  try {
185659
- mkdirSync44(dirname51(path2), { recursive: true, mode: 448 });
185892
+ mkdirSync45(dirname51(path2), { recursive: true, mode: 448 });
185660
185893
  writeFileSync44(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
185661
185894
  } catch {
185662
185895
  }
@@ -185710,7 +185943,7 @@ function createUpdateRunner(spawn8 = spawnSync5) {
185710
185943
  // parse — the agent case this whole feature exists for (#2985 review). And no stdin: an
185711
185944
  // install needs none, and must not consume input piped to the command we are about to re-run.
185712
185945
  stdio: ["ignore", 2, 2],
185713
- cwd: homedir14()
185946
+ cwd: homedir15()
185714
185947
  });
185715
185948
  if (result.error) return { ok: false, detail: result.error.message };
185716
185949
  return result.status === 0 ? { ok: true } : { ok: false, detail: `npm exited ${result.status}` };
@@ -185722,7 +185955,7 @@ function createUpdateRunner(spawn8 = spawnSync5) {
185722
185955
  reexec: (argv) => {
185723
185956
  const root = globalNodeModulesRoot();
185724
185957
  const entry = root ? join94(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
185725
- if (!entry || !existsSync88(entry)) return void 0;
185958
+ if (!entry || !existsSync89(entry)) return void 0;
185726
185959
  const result = spawnSync5(process.execPath, [entry, ...argv], {
185727
185960
  // inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
185728
185961
  stdio: "inherit",
@@ -185813,7 +186046,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
185813
186046
  };
185814
186047
  const release2 = () => removeIfMine(lockPath);
185815
186048
  try {
185816
- mkdirSync44(dirname51(lockPath), { recursive: true, mode: 448 });
186049
+ mkdirSync45(dirname51(lockPath), { recursive: true, mode: 448 });
185817
186050
  } catch {
185818
186051
  return () => {
185819
186052
  };
@@ -185880,10 +186113,10 @@ function supersededInCache(current, latest, now) {
185880
186113
  function createUpdateRefreshSpawner(spawnFn = spawn7, execArgv = process.execArgv) {
185881
186114
  return () => {
185882
186115
  try {
185883
- const child = spawnFn(process.execPath, [...loaderArgs(execArgv), fileURLToPath29(import.meta.url), UPDATE_REFRESH_COMMAND], {
186116
+ const child = spawnFn(process.execPath, [...loaderArgs(execArgv), fileURLToPath30(import.meta.url), UPDATE_REFRESH_COMMAND], {
185884
186117
  detached: true,
185885
186118
  stdio: "ignore",
185886
- cwd: homedir14(),
186119
+ cwd: homedir15(),
185887
186120
  env: process.env
185888
186121
  });
185889
186122
  child.on("error", () => {
@@ -185935,7 +186168,7 @@ function createTrimValidator(deps = {}, spawnFn = spawn7) {
185935
186168
  }
185936
186169
  const { code, stdout, stderr } = await new Promise((done) => {
185937
186170
  const chunks = { out: [], err: [] };
185938
- const child = spawnFn(process.execPath, [...loaderArgs(process.execArgv), fileURLToPath29(import.meta.url), ...argv], {
186171
+ const child = spawnFn(process.execPath, [...loaderArgs(process.execArgv), fileURLToPath30(import.meta.url), ...argv], {
185939
186172
  cwd: process.cwd(),
185940
186173
  env: process.env,
185941
186174
  stdio: ["ignore", "pipe", "pipe"]
@@ -186493,7 +186726,7 @@ async function nativeConfigAdvisories(app, configSource) {
186493
186726
  const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths2(), paths_exports));
186494
186727
  const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
186495
186728
  const iosYmlPath = iosProjectYml2(app);
186496
- const iosYml = existsSync88(iosYmlPath) ? readFileSync109(iosYmlPath, "utf8") : "";
186729
+ const iosYml = existsSync89(iosYmlPath) ? readFileSync109(iosYmlPath, "utf8") : "";
186497
186730
  let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
186498
186731
  if (!optedIn) {
186499
186732
  const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
@@ -186513,7 +186746,7 @@ function readConfigSource(dir) {
186513
186746
  }
186514
186747
  }
186515
186748
  function writePngFile(path2, base64) {
186516
- mkdirSync44(dirname51(path2), { recursive: true });
186749
+ mkdirSync45(dirname51(path2), { recursive: true });
186517
186750
  writeFileSync44(path2, Buffer.from(base64, "base64"));
186518
186751
  return path2;
186519
186752
  }
@@ -186561,7 +186794,7 @@ var NoBase44SlotError = class extends Error {
186561
186794
  };
186562
186795
  async function initFromRemoteTemplate(name, parentDir, template, c2, opts = {}) {
186563
186796
  const dir = resolve65(parentDir, name);
186564
- if (existsSync88(join94(dir, "himalaya.content.json"))) {
186797
+ if (existsSync89(join94(dir, "himalaya.content.json"))) {
186565
186798
  throw new Error(`content package already exists at ${dir}`);
186566
186799
  }
186567
186800
  const r2 = await c2.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
@@ -186607,7 +186840,7 @@ function symlinkDestinationIssue(dest) {
186607
186840
  function restoreDestinationIssue(dest, force) {
186608
186841
  const link = symlinkDestinationIssue(dest);
186609
186842
  if (link) return link;
186610
- if (!existsSync88(dest)) return null;
186843
+ if (!existsSync89(dest)) return null;
186611
186844
  if (!statSync23(dest).isDirectory()) {
186612
186845
  return { error: `${dest} exists and is not a directory`, hint: "pass --out/--name to land somewhere else, or remove the file" };
186613
186846
  }
@@ -186622,7 +186855,7 @@ function restoreDestinationIssue(dest, force) {
186622
186855
  function isHimalayaMonorepoCheckout(start) {
186623
186856
  let dir = resolve65(start);
186624
186857
  for (; ; ) {
186625
- if (existsSync88(join94(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync88(join94(dir, "core", "serve", "src", "server.ts"))) return true;
186858
+ if (existsSync89(join94(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync89(join94(dir, "core", "serve", "src", "server.ts"))) return true;
186626
186859
  const parent = dirname51(dir);
186627
186860
  if (parent === dir) return false;
186628
186861
  dir = parent;
@@ -186682,7 +186915,7 @@ function materializeForPreview(appDir3, slug, displayName3) {
186682
186915
  const forBuild = Object.fromEntries(
186683
186916
  Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
186684
186917
  );
186685
- const repoRoot2 = resolve65(fileURLToPath29(new URL("../../..", import.meta.url)));
186918
+ const repoRoot2 = resolve65(fileURLToPath30(new URL("../../..", import.meta.url)));
186686
186919
  const root = join94(repoRoot2, "node_modules", ".cache", "himi-template-preview");
186687
186920
  const stillRunning = (pid) => {
186688
186921
  try {
@@ -186704,7 +186937,7 @@ function materializeForPreview(appDir3, slug, displayName3) {
186704
186937
  }
186705
186938
  const dest = join94(root, `${slug}-${process.pid}`);
186706
186939
  rmSync24(dest, { recursive: true, force: true });
186707
- mkdirSync44(dest, { recursive: true });
186940
+ mkdirSync45(dest, { recursive: true });
186708
186941
  try {
186709
186942
  materializeSource(forBuild, displayName3, dest, slug);
186710
186943
  } catch (e2) {
@@ -187017,7 +187250,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
187017
187250
  ...res.removed.length ? { removed: res.removed, note: "older copies at the app root, moved to .himi/legacy-agent-files/ (a backup, in case one became app code) \u2014 the current ones live in .agents/skills/himalaya/" } : {},
187018
187251
  // In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
187019
187252
  // hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
187020
- ...existsSync88(join94(dir, ".himi", "attestations", "latest.json")) ? { next: "if `himi push` then refuses the attestation as stale, re-run `himi test` \u2014 in a git checkout this refresh changed the tree it covered" } : {},
187253
+ ...existsSync89(join94(dir, ".himi", "attestations", "latest.json")) ? { next: "if `himi push` then refuses the attestation as stale, re-run `himi test` \u2014 in a git checkout this refresh changed the tree it covered" } : {},
187021
187254
  ...res.skipped.length ? { skipped: res.skipped } : {},
187022
187255
  portalUrl: idx.portalUrl
187023
187256
  });
@@ -187028,8 +187261,6 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
187028
187261
  return 2;
187029
187262
  }
187030
187263
  }
187031
- var AuthoringUnavailable = class extends Error {
187032
- };
187033
187264
  function resolutionFlag(flags) {
187034
187265
  if (flags.binary === true) return "node_modules";
187035
187266
  if (flags.source === true) return "source";
@@ -187150,16 +187381,17 @@ function uxHandoverOverride(uxEvidence, ctx) {
187150
187381
  return { uxEvidence, uxEvidenceNote: uxHandoverNote(uxEvidence, ctx) };
187151
187382
  }
187152
187383
  async function loadAuthoring() {
187384
+ const { AuthoringUnavailable: AuthoringUnavailable2, namedAuthoringImport: namedAuthoringImport2 } = await Promise.resolve().then(() => (init_authoring_unavailable(), authoring_unavailable_exports));
187153
187385
  try {
187154
187386
  const [b2, rb, crawl, vd, cov, wml, nf2, rd] = await Promise.all([
187155
- Promise.resolve().then(() => (init_build(), build_exports)),
187156
- Promise.resolve().then(() => (init_build3(), build_exports2)),
187157
- Promise.resolve().then(() => (init_screen_crawl(), screen_crawl_exports)),
187158
- Promise.resolve().then(() => (init_validate_descriptor(), validate_descriptor_exports)),
187159
- Promise.resolve().then(() => (init_vm_coverage(), vm_coverage_exports)),
187160
- Promise.resolve().then(() => (init_wix_member_login(), wix_member_login_exports)),
187161
- Promise.resolve().then(() => (init_net_freeze(), net_freeze_exports)),
187162
- Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports))
187387
+ namedAuthoringImport2("./build.js", Promise.resolve().then(() => (init_build(), build_exports))),
187388
+ namedAuthoringImport2("../../release-build/build.js", Promise.resolve().then(() => (init_build3(), build_exports2))),
187389
+ namedAuthoringImport2("../../../core/dev-server/src/screen-crawl.js", Promise.resolve().then(() => (init_screen_crawl(), screen_crawl_exports))),
187390
+ namedAuthoringImport2("../../../core/dev-server/src/validate-descriptor.js", Promise.resolve().then(() => (init_validate_descriptor(), validate_descriptor_exports))),
187391
+ namedAuthoringImport2("../../../core/dev-server/src/vm-coverage.js", Promise.resolve().then(() => (init_vm_coverage(), vm_coverage_exports))),
187392
+ namedAuthoringImport2("../../../core/dev-server/src/wix-member-login.js", Promise.resolve().then(() => (init_wix_member_login(), wix_member_login_exports))),
187393
+ namedAuthoringImport2("../../../core/dev-server/src/net-freeze.js", Promise.resolve().then(() => (init_net_freeze(), net_freeze_exports))),
187394
+ namedAuthoringImport2("../../../core/dev-server/src/render-descriptor.js", Promise.resolve().then(() => (init_render_descriptor(), render_descriptor_exports)))
187163
187395
  ]);
187164
187396
  return {
187165
187397
  buildContentBundles: b2.buildContentBundles,
@@ -187189,8 +187421,9 @@ async function loadAuthoring() {
187189
187421
  readBuiltBundle: vd.readBuiltBundle,
187190
187422
  crawlBlockingPasses: vd.CRAWL_BLOCKING_PASSES
187191
187423
  };
187192
- } catch {
187193
- throw new AuthoringUnavailable();
187424
+ } catch (cause) {
187425
+ if (cause instanceof AuthoringUnavailable2) throw cause;
187426
+ throw new AuthoringUnavailable2({ cause });
187194
187427
  }
187195
187428
  }
187196
187429
  async function producedWidgetFamilies(dir) {
@@ -187250,7 +187483,7 @@ async function producedWidgetFamilies(dir) {
187250
187483
  }
187251
187484
  return { families, source: "dist/bundles" };
187252
187485
  }
187253
- var boardOpen = (dir) => existsSync88(join94(dir, ".himi", "studio", "index.html"));
187486
+ var boardOpen = (dir) => existsSync89(join94(dir, ".himi", "studio", "index.html"));
187254
187487
  var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
187255
187488
  async function leaveForBoard(dir, record2, value) {
187256
187489
  if (!boardOpen(dir)) return;
@@ -187628,7 +187861,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
187628
187861
  const owed = openApprovals2(readApprovals2(dir).events).length;
187629
187862
  next.push(`carried the planning journal into the app (${carried.join(", ")}${owed ? `; ${owed} approval${owed === 1 ? "" : "s"} still owed` : ""}) \u2014 \`himi progress --brief\` there shows it`);
187630
187863
  }
187631
- const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync88(join94(parentDir, f2)));
187864
+ const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f2) => existsSync89(join94(parentDir, f2)));
187632
187865
  if (planInParent.length) {
187633
187866
  next.push(`${planInParent.join(" and ")} in ${parentDir} ${planInParent.length > 1 ? "are" : "is"} not the app's \u2014 if that is the approved plan, move it over the template's boilerplate in ${dir}`);
187634
187867
  }
@@ -187639,12 +187872,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
187639
187872
  const board = await openBoardForSession2(dir);
187640
187873
  const home = homeScreenIdOf2(dir);
187641
187874
  recordInitSource2(dir, { template: template ?? null, source });
187642
- const firstLook = flags["no-first-look"] === true ? { skipped: "--no-first-look" } : await firstLookAtInit2(dir, { source, home, entry: fileURLToPath29(import.meta.url), loader: loaderArgs(process.execArgv) });
187875
+ const firstLook = flags["no-first-look"] === true ? { skipped: "--no-first-look" } : await firstLookAtInit2(dir, { source, home, entry: fileURLToPath30(import.meta.url), loader: loaderArgs(process.execArgv) });
187643
187876
  const pictured = "image" in firstLook;
187644
187877
  const watch2 = await startWatchAtInit2(dir, {
187645
187878
  source,
187646
187879
  app: await appId(dir),
187647
- entry: fileURLToPath29(import.meta.url),
187880
+ entry: fileURLToPath30(import.meta.url),
187648
187881
  loader: loaderArgs(process.execArgv),
187649
187882
  noWatch: flags["no-watch"] === true
187650
187883
  });
@@ -187918,7 +188151,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
187918
188151
  const result = { ...outcome.result, ...fromSpec };
187919
188152
  const adoptDir = contentDir(flags);
187920
188153
  const kept = flags["dry-run"] !== true && (outcome.code === 0 || outcome.result.forcedKeep === true);
187921
- if (kept && existsSync88(join94(adoptDir, adoptBits.ADOPT_FILE))) {
188154
+ if (kept && existsSync89(join94(adoptDir, adoptBits.ADOPT_FILE))) {
187922
188155
  try {
187923
188156
  const inv = adoptBits.inspectApp(adoptDir);
187924
188157
  adoptBits.writeInventory(adoptDir, inv, { companions: "if-missing" });
@@ -188331,7 +188564,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
188331
188564
  const homePicture = await homePictureAtValidate2(dir, {
188332
188565
  ok: !hasErrors,
188333
188566
  home: outcome.homeScreenId,
188334
- entry: fileURLToPath29(import.meta.url),
188567
+ entry: fileURLToPath30(import.meta.url),
188335
188568
  loader: loaderArgs(process.execArgv)
188336
188569
  });
188337
188570
  const { postcard: picturePostcard, ...picture } = homePicture;
@@ -188476,7 +188709,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
188476
188709
  const dir2 = resolve65(out2);
188477
188710
  const files2 = himiStudioPluginFiles2();
188478
188711
  for (const f2 of files2) {
188479
- mkdirSync44(dirname51(join94(dir2, f2.path)), { recursive: true });
188712
+ mkdirSync45(dirname51(join94(dir2, f2.path)), { recursive: true });
188480
188713
  writeFileSync44(join94(dir2, f2.path), f2.text);
188481
188714
  }
188482
188715
  print({ ok: true, dir: dir2, files: files2.map((f2) => f2.path), next: [`claude plugin validate ${dir2}`, `claude --plugin-dir ${dir2}`] });
@@ -188492,7 +188725,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
188492
188725
  const dir = resolve65(out2);
188493
188726
  const files = himiPluginFiles2(skills.skillMd);
188494
188727
  for (const f2 of files) {
188495
- mkdirSync44(dirname51(join94(dir, f2.path)), { recursive: true });
188728
+ mkdirSync45(dirname51(join94(dir, f2.path)), { recursive: true });
188496
188729
  writeFileSync44(join94(dir, f2.path), f2.text);
188497
188730
  }
188498
188731
  print({ ok: true, dir, files: files.map((f2) => f2.path), next: [`claude plugin validate ${dir}`, `claude --plugin-dir ${dir}`] });
@@ -188510,7 +188743,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
188510
188743
  case "studio": {
188511
188744
  const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
188512
188745
  const dir = contentDir(flags);
188513
- if (!existsSync88(join94(dir, "himalaya.content.json"))) {
188746
+ if (!existsSync89(join94(dir, "himalaya.content.json"))) {
188514
188747
  io2.error(JSON.stringify({ ok: false, error: "not_a_content_package", dir, hint: "run from the app directory (or pass --content <dir>) \u2014 the board reads that package's .himi/" }));
188515
188748
  return 2;
188516
188749
  }
@@ -188518,7 +188751,7 @@ ${doNow.map((l2) => ` ${l2}`).join("\n")}`);
188518
188751
  const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
188519
188752
  const out2 = resolve65(str10(flags.out) ?? join94(dir, ".himi", "making-of.html"));
188520
188753
  const { html, plan } = buildReel2(dir);
188521
- mkdirSync44(dirname51(out2), { recursive: true });
188754
+ mkdirSync45(dirname51(out2), { recursive: true });
188522
188755
  writeFileSync44(out2, html);
188523
188756
  const { pathToFileURL: pathToFileURL9 } = await import("node:url");
188524
188757
  const url2 = pathToFileURL9(out2).href;
@@ -188588,7 +188821,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
188588
188821
  } = await Promise.resolve().then(() => (init_progress(), progress_exports));
188589
188822
  const dir = contentDir(flags);
188590
188823
  const journal2 = journalPath2(dir);
188591
- const isContentPackage = existsSync88(join94(dir, "himalaya.content.json"));
188824
+ const isContentPackage = existsSync89(join94(dir, "himalaya.content.json"));
188592
188825
  const hint = isContentPackage ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
188593
188826
  const message = pos.slice(1).join(" ").trim();
188594
188827
  const approvalFlags = ["approve", "done", "drop"].filter((f2) => flags[f2] !== void 0);
@@ -188740,7 +188973,7 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
188740
188973
  case "test": {
188741
188974
  const dir = contentDir(flags);
188742
188975
  const structuredOutput = flags.json === true || io2.isTTY !== true;
188743
- if (existsSync88(join94(dir, "functions"))) {
188976
+ if (existsSync89(join94(dir, "functions"))) {
188744
188977
  const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
188745
188978
  const loaded = await loadFunctionsApp2(dir);
188746
188979
  const results = [];
@@ -188877,8 +189110,8 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
188877
189110
  io2.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
188878
189111
  return 2;
188879
189112
  }
188880
- const { fileURLToPath: fileURLToPath30 } = await import("node:url");
188881
- const sdk = collectSdkModules2(sources.files, sdkSubpathReader2((s2) => fileURLToPath30(import.meta.resolve(s2))));
189113
+ const { fileURLToPath: fileURLToPath31 } = await import("node:url");
189114
+ const sdk = collectSdkModules2(sources.files, sdkSubpathReader2((s2) => fileURLToPath31(import.meta.resolve(s2))));
188882
189115
  if (sdk.unsupported.length) {
188883
189116
  io2.error(JSON.stringify({
188884
189117
  error: `this worker imports ${sdk.unsupported.map((u2) => `@himalaya/${u2.sub}`).join(", ")}, which the browser loop cannot build: ${sdk.unsupported.map((u2) => `${u2.sub} needs ${u2.builtin}`).join("; ")}. The page compiles in a tab with no node builtins. Run \`himi test\` without --browser for this screen.`,
@@ -189020,21 +189253,20 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
189020
189253
  io2.error(JSON.stringify({ error: e2.message }));
189021
189254
  return 2;
189022
189255
  }
189256
+ const release2 = await loadReleaseFromDir(app, out2);
189023
189257
  if (nativeAvailabilities.length > 0) {
189024
- const { runAndroidNativeDecode: runAndroidNativeDecode2, runNativeDecode: runNativeDecode2, mergeNativeDecode: mergeNativeDecode2 } = await Promise.resolve().then(() => (init_native_decode(), native_decode_exports));
189258
+ const { runAndroidNativeDecode: runAndroidNativeDecode2, runNativeDecode: runNativeDecode2, mergeNativeDecode: mergeNativeDecode2, markNativeSkipped: markNativeSkipped2 } = await Promise.resolve().then(() => (init_native_decode(), native_decode_exports));
189025
189259
  const descriptors = scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens);
189260
+ const tokensJson = release2.tokens;
189026
189261
  for (const availability of nativeAvailabilities) {
189027
189262
  if (!availability.available) {
189028
- result.nativeDecode = {
189029
- ...result.nativeDecode,
189030
- [availability.platform]: { unavailable: true, reason: availability.reason },
189031
- wallMs: result.nativeDecode?.wallMs ?? 0
189032
- };
189263
+ result = markNativeSkipped2(result, availability);
189264
+ io2.error(`[native ${availability.platform}] SKIPPED \u2014 not checked: ${availability.reason}`);
189033
189265
  continue;
189034
189266
  }
189035
189267
  try {
189036
189268
  const progress = (message) => io2.error(`[native ${availability.platform} ${(/* @__PURE__ */ new Date()).toISOString()}] ${message}`);
189037
- const nativeRun = availability.platform === "ios" ? runNativeDecode2({ descriptors, packageDir: availability.packageDir, progress }) : runAndroidNativeDecode2({ descriptors, harnessDir: availability.harnessDir, gradlew: availability.gradlew, progress });
189269
+ const nativeRun = availability.platform === "ios" ? runNativeDecode2({ descriptors, tokensJson, packageDir: availability.packageDir, progress }) : runAndroidNativeDecode2({ descriptors, tokensJson, harnessDir: availability.harnessDir, gradlew: availability.gradlew, sdkDir: availability.sdkDir, progress });
189038
189270
  result = mergeNativeDecode2(result, nativeRun);
189039
189271
  } catch (error) {
189040
189272
  io2.error(JSON.stringify({ error: error.message }));
@@ -189078,7 +189310,6 @@ ${handover.hint[0].toUpperCase()}${handover.hint.slice(1)}.`);
189078
189310
  const trend = trendAndStore2(dir, ledger, suppressedNativeKeys2(nativeOracle));
189079
189311
  const delta = diffAndStoreObservations2(dir, result.observations ?? {});
189080
189312
  const legacy = { ...result, ledger, ...trend ? { trend } : {}, ...delta ? { delta } : {}, ...recorded ? { recorded } : {} };
189081
- const release2 = await loadReleaseFromDir(app, out2);
189082
189313
  const gitDiffHash = currentGitDiffHash(dir);
189083
189314
  const crawledScreens = new Set((result.crawled ?? []).map((screen) => screen.screen));
189084
189315
  const attestedDescriptors = Object.fromEntries(
@@ -189675,7 +189906,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
189675
189906
  io2.error(JSON.stringify(linked));
189676
189907
  return 1;
189677
189908
  }
189678
- if (existsSync88(dest)) {
189909
+ if (existsSync89(dest)) {
189679
189910
  if (!statSync23(dest).isDirectory()) {
189680
189911
  io2.error(JSON.stringify({
189681
189912
  error: `${dest} exists and is not a directory`,
@@ -189688,7 +189919,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
189688
189919
  io2.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" }));
189689
189920
  return 1;
189690
189921
  }
189691
- if (replace && occupied && !existsSync88(join94(dest, "himalaya.content.json"))) {
189922
+ if (replace && occupied && !existsSync89(join94(dest, "himalaya.content.json"))) {
189692
189923
  io2.error(JSON.stringify({
189693
189924
  error: `${dest} is not a content package \u2014 refusing to --replace it`,
189694
189925
  hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
@@ -190642,7 +190873,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
190642
190873
  // ---- himi run — serve a package on localhost and open it in a browser ----
190643
190874
  // Blocks until interrupted, like any dev server.
190644
190875
  case "run": {
190645
- const { runPackage: runPackage2, lanFlagConflict: lanFlagConflict2 } = await Promise.resolve().then(() => (init_run(), run_exports));
190876
+ const { runPackage: runPackage2, lanFlagConflict: lanFlagConflict2, RUN_CONTENT_BUILD: RUN_CONTENT_BUILD2 } = await Promise.resolve().then(() => (init_run(), run_exports));
190646
190877
  const spaFlag = flags.spa;
190647
190878
  const lanConflict = lanFlagConflict2({ lan: flags.lan === true, browser: flags.browser === true, spa: typeof spaFlag === "string" || Array.isArray(spaFlag) ? String(spaFlag) : void 0 });
190648
190879
  if (lanConflict) {
@@ -190713,7 +190944,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
190713
190944
  const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
190714
190945
  temp = mkdtempSync6(join94(tmpdir7(), "himi-run-build-"));
190715
190946
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
190716
- const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
190947
+ const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {}, ...RUN_CONTENT_BUILD2 });
190717
190948
  servedMissing = initial.missingBundles;
190718
190949
  source = join94(temp, app);
190719
190950
  }
@@ -190841,7 +191072,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
190841
191072
  return;
190842
191073
  }
190843
191074
  const hasWorkers = bres.built.length > 0;
190844
- const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, freshModule: true });
191075
+ const outcome = await buildReleaseFromContent2(dir, next, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, freshModule: true, ...RUN_CONTENT_BUILD2 });
190845
191076
  const blocker = watchKit.rebuildBlocker(outcome, servedMissing);
190846
191077
  if (blocker) {
190847
191078
  await failed3(blocker);
@@ -191484,7 +191715,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
191484
191715
  io2.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
191485
191716
  return 2;
191486
191717
  }
191487
- if (!existsSync88(file2)) {
191718
+ if (!existsSync89(file2)) {
191488
191719
  io2.error(JSON.stringify({ error: `no such file: ${file2}` }));
191489
191720
  return 2;
191490
191721
  }
@@ -192038,7 +192269,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
192038
192269
  const rememberLastDist = async (jobs2) => {
192039
192270
  try {
192040
192271
  const dir = contentDir(flags);
192041
- if (!existsSync88(join94(dir, "himalaya.content.json"))) return;
192272
+ if (!existsSync89(join94(dir, "himalaya.content.json"))) return;
192042
192273
  const { lastDistFromJob: lastDistFromJob2, writeLastDist: writeLastDist2 } = await Promise.resolve().then(() => (init_capabilities(), capabilities_exports));
192043
192274
  const own5 = await appId(dir);
192044
192275
  for (const job of jobs2) {
@@ -192278,7 +192509,7 @@ ${label3}`);
192278
192509
  const platform = str10(flags.platform)?.split(",").map((p2) => p2.trim()).filter(Boolean);
192279
192510
  {
192280
192511
  const distDir = contentDir(flags);
192281
- if (existsSync88(join94(distDir, "himalaya.content.json"))) {
192512
+ if (existsSync89(join94(distDir, "himalaya.content.json"))) {
192282
192513
  const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
192283
192514
  const errors = issues.filter((i2) => i2.severity === "error");
192284
192515
  for (const i2 of issues.filter((i3) => i3.severity === "warning")) {
@@ -193329,7 +193560,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
193329
193560
  return 1;
193330
193561
  };
193331
193562
  const gen = await Promise.resolve().then(() => (init_generate(), generate_exports));
193332
- const missing = gen.ENGINE_FILES.filter((f2) => !existsSync88(join94(dir, f2)));
193563
+ const missing = gen.ENGINE_FILES.filter((f2) => !existsSync89(join94(dir, f2)));
193333
193564
  if (missing.length) {
193334
193565
  return fail6("content_dir_not_base44_starter", `${dir} is not a base44-starter content package: the generated screens import a shared engine it does not have (${missing.join(", ")})`, { missing, hint: "scaffold one with `himi init <name> --template base44-starter --base44-app-id <id>`" });
193335
193566
  }
@@ -193415,7 +193646,7 @@ ${report3.ok ? "OK \u2014 data + serve plane reachable." : typeof report3.hint =
193415
193646
  if (!provisioning || str10(flags.content) !== void 0 || !slug) return contentDir(flags);
193416
193647
  if (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) return void 0;
193417
193648
  const dir = resolve65("apps", slug);
193418
- return existsSync88(join94(dir, "config.ts")) || existsSync88(join94(dir, "config.mjs")) ? dir : void 0;
193649
+ return existsSync89(join94(dir, "config.ts")) || existsSync89(join94(dir, "config.mjs")) ? dir : void 0;
193419
193650
  };
193420
193651
  if (sub === "entities" || sub === "functions") {
193421
193652
  if (sub === "entities" && !["query", "create", "seed"].includes(pos[2] ?? "")) {
@@ -193804,13 +194035,13 @@ Code: ${userCode}`);
193804
194035
  return 2;
193805
194036
  }
193806
194037
  } catch (err) {
193807
- if (err instanceof AuthoringUnavailable) {
193808
- io2.error(JSON.stringify(pushFailure2("authoring_unavailable", {
193809
- error: `the himi authoring runtime failed to load (himi v${cliVersion()}). Off-repo this almost always means an out-of-date CLI, NOT a platform limitation \u2014 upgrade: \`npm i -g @wix/himalaya-cli@latest\`. If you meant to run in-repo, run from a monorepo checkout.`,
194038
+ if (err instanceof Error && err.name === "AuthoringUnavailable") {
194039
+ const { authoringUnavailableFields: authoringUnavailableFields2, isSourceCheckout: isSourceCheckout2 } = await Promise.resolve().then(() => (init_authoring_unavailable(), authoring_unavailable_exports));
194040
+ io2.error(JSON.stringify(pushFailure2("authoring_unavailable", authoringUnavailableFields2(err, {
193810
194041
  version: cliVersion(),
193811
- upgrade: "npm i -g @wix/himalaya-cli@latest",
193812
- portal: DEVELOPER_PORTAL_URL
193813
- })));
194042
+ portal: DEVELOPER_PORTAL_URL,
194043
+ sourceCheckout: isSourceCheckout2()
194044
+ }))));
193814
194045
  return 1;
193815
194046
  }
193816
194047
  io2.error(JSON.stringify(pushFailure2("push_failed", { error: err.message })));