@wix/himalaya-cli 0.1048.0 → 0.1050.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
@@ -2829,8 +2829,8 @@ function committedProvisioningPath(name) {
2829
2829
  function committedShellFor(path2) {
2830
2830
  const normalized = path2.replace(/\\/g, "/");
2831
2831
  return SHELL_NAMES2.find((name) => {
2832
- const relative11 = committedProvisioningPath(name);
2833
- return normalized === relative11 || normalized.endsWith(`/${relative11}`);
2832
+ const relative12 = committedProvisioningPath(name);
2833
+ return normalized === relative12 || normalized.endsWith(`/${relative12}`);
2834
2834
  });
2835
2835
  }
2836
2836
  function isBrandable(repoRoot2, name) {
@@ -3610,11 +3610,14 @@ async function buildBundleFromEntry(entry, outfile, opts = {}) {
3610
3610
  return outfile;
3611
3611
  }
3612
3612
  async function buildAppEntry(entry, outfile, opts = {}) {
3613
- const { umbrella = false, resolveTsExtensions = false, absWorkingDir = REPO_ROOT4, confineTo } = opts;
3613
+ const { umbrella = false, resolveTsExtensions = false, absWorkingDir = REPO_ROOT4, confineTo, inputs } = opts;
3614
3614
  const confine = confinementFor(confineTo, "buildAppEntry", entry);
3615
3615
  if (!existsSync8(entry)) throw new Error(`unknown app entry: ${entry}`);
3616
- await build({
3616
+ const result = await build({
3617
3617
  entryPoints: [entry],
3618
+ // `inputs` (a Set) receives every source file the bundle read, as absolute paths — the
3619
+ // dev-server watches that import closure so an edit to shared screen code reloads (#3307).
3620
+ metafile: !!inputs,
3618
3621
  outfile,
3619
3622
  bundle: true,
3620
3623
  format: "esm",
@@ -3644,6 +3647,11 @@ async function buildAppEntry(entry, outfile, opts = {}) {
3644
3647
  ...umbrella && !process.env.HIMI_CLI_RUNTIME_DIR ? [umbrellaRewritePlugin({ external: true })] : []
3645
3648
  ]
3646
3649
  });
3650
+ if (inputs && result.metafile) {
3651
+ for (const rel of Object.keys(result.metafile.inputs)) {
3652
+ if (!rel.includes(":")) inputs.add(resolve8(absWorkingDir, rel));
3653
+ }
3654
+ }
3647
3655
  return outfile;
3648
3656
  }
3649
3657
  async function buildContainedAppConfig(entry, opts = {}) {
@@ -33669,7 +33677,7 @@ var init_config2 = __esm({
33669
33677
  import { createServer as createServer2 } from "node:http";
33670
33678
  import { readFile, stat } from "node:fs/promises";
33671
33679
  import { readFileSync as readFileSync41, existsSync as existsSync38, watch, mkdirSync as mkdirSync18, rmSync as rmSync7 } from "node:fs";
33672
- import { extname as extname2, resolve as resolve31, normalize as normalize3, sep as sep8 } from "node:path";
33680
+ import { basename as basename9, dirname as dirname22, extname as extname2, join as join36, relative as relative6, resolve as resolve31, normalize as normalize3, sep as sep8 } from "node:path";
33673
33681
  import { createHash as createHash16, randomUUID as randomUUID2 } from "node:crypto";
33674
33682
  import { fileURLToPath as fileURLToPath18, pathToFileURL as pathToFileURL6 } from "node:url";
33675
33683
  function deepMerge3(base, patch) {
@@ -34565,7 +34573,8 @@ async function reloadAppModuleNow(state, opts) {
34565
34573
  const outfile = resolve31(HMR_TMP_DIR, `${current.name}-${++appReloadSeq}.mjs`);
34566
34574
  try {
34567
34575
  const lib = await import(pathToFileURL6(resolve31(TIER5_SRC_ROOT, "build-lib.mjs")).href);
34568
- await lib.buildAppEntry(entry, outfile, { confineTo: current.dir });
34576
+ const inputs = /* @__PURE__ */ new Set();
34577
+ await lib.buildAppEntry(entry, outfile, { confineTo: current.dir, inputs });
34569
34578
  const mod = await import(pathToFileURL6(outfile).href);
34570
34579
  const next = mod.default;
34571
34580
  if (!next || !next.config || typeof next.homeScreenId !== "string" || !next.screens || typeof next.screens.exact !== "object" || Object.keys(next.screens.exact).length === 0 || !Array.isArray(next.actions) || !next.seed) {
@@ -34603,6 +34612,7 @@ async function reloadAppModuleNow(state, opts) {
34603
34612
  state.announcedTokensHash = tokensHash;
34604
34613
  publishSSE(state, "tokens.changed", { reason: opts.reason, at: Date.now() });
34605
34614
  }
34615
+ if (state.hotReloadEnabled) syncAppDependencyWatchers(state, inputs);
34606
34616
  console.log(`[himalaya-dev] reloaded app module in-process: ${current.name} (${opts.reason})`);
34607
34617
  return { ok: true };
34608
34618
  } catch (err) {
@@ -34627,6 +34637,77 @@ function servedTokensHash(app) {
34627
34637
  return "";
34628
34638
  }
34629
34639
  }
34640
+ function appDependencyFiles(inputs, appDir2) {
34641
+ const inside = (root, p) => p === root || p.startsWith(root + sep8);
34642
+ const out = /* @__PURE__ */ new Set();
34643
+ for (const raw of inputs) {
34644
+ const p = resolve31(raw);
34645
+ if (!inside(ROOT6, p) || inside(resolve31(appDir2), p) || inside(HMR_TMP_DIR, p)) continue;
34646
+ if (p.split(sep8).includes("node_modules")) continue;
34647
+ out.add(p);
34648
+ }
34649
+ return [...out].sort();
34650
+ }
34651
+ function syncAppDependencyWatchers(state, inputs) {
34652
+ if (!state.app || state.closed) return;
34653
+ for (const w of state.appDepWatchers ?? []) {
34654
+ try {
34655
+ w.close();
34656
+ } catch {
34657
+ }
34658
+ }
34659
+ const byDir = /* @__PURE__ */ new Map();
34660
+ for (const file of appDependencyFiles(inputs, state.app.dir)) {
34661
+ const dir = dirname22(file);
34662
+ if (!byDir.has(dir)) byDir.set(dir, /* @__PURE__ */ new Set());
34663
+ byDir.get(dir).add(basename9(file));
34664
+ }
34665
+ let timer;
34666
+ const changed = /* @__PURE__ */ new Set();
34667
+ const watchers = [];
34668
+ for (const [dir, names] of byDir) {
34669
+ try {
34670
+ const w = watch(dir, { persistent: false }, (_event, filename) => {
34671
+ if (!filename || !names.has(String(filename))) return;
34672
+ changed.add(join36(dir, String(filename)));
34673
+ if (timer) clearTimeout(timer);
34674
+ timer = setTimeout(() => {
34675
+ timer = void 0;
34676
+ const files = [...changed].map((f) => relative6(ROOT6, f));
34677
+ changed.clear();
34678
+ console.log(`[himalaya-dev] app dependency changed: ${files.join(", ")}`);
34679
+ void reloadAppModule(state, { reason: "dependency_changed" });
34680
+ }, 200);
34681
+ });
34682
+ w.on("error", () => {
34683
+ });
34684
+ watchers.push(w);
34685
+ } catch {
34686
+ }
34687
+ }
34688
+ state.appDepWatchers = watchers;
34689
+ }
34690
+ async function primeAppDependencyWatchers(state) {
34691
+ const current = state.app;
34692
+ if (!current) return;
34693
+ const entry = resolve31(current.dir, "dev/index.ts");
34694
+ if (!existsSync38(entry)) return;
34695
+ mkdirSync18(HMR_TMP_DIR, { recursive: true });
34696
+ const outfile = resolve31(HMR_TMP_DIR, `${current.name}-deps-${++appReloadSeq}.mjs`);
34697
+ try {
34698
+ const lib = await import(pathToFileURL6(resolve31(TIER5_SRC_ROOT, "build-lib.mjs")).href);
34699
+ const inputs = /* @__PURE__ */ new Set();
34700
+ await lib.buildAppEntry(entry, outfile, { confineTo: current.dir, inputs });
34701
+ if (state.app === current && !state.appDepWatchers) syncAppDependencyWatchers(state, inputs);
34702
+ } catch (err) {
34703
+ console.warn(`[himalaya-dev] app dependency watch unavailable: ${err.message}`);
34704
+ } finally {
34705
+ try {
34706
+ rmSync7(outfile, { force: true });
34707
+ } catch {
34708
+ }
34709
+ }
34710
+ }
34630
34711
  function classifyAppPath(rel) {
34631
34712
  if (!rel || rel.startsWith("..")) return null;
34632
34713
  if (rel === "tokens.json") return "tokens";
@@ -35884,8 +35965,8 @@ async function handleActionHandlerBundleGet(res, app) {
35884
35965
  }
35885
35966
  async function serveStatic(req, res, root, prefix) {
35886
35967
  const requested = decodeURIComponent((req.url ?? "").split("?")[0]);
35887
- const relative11 = requested.replace(prefix, "").replace(/^\//, "");
35888
- const safe = normalize3(relative11).replace(/^(\.\.[\/\\])+/, "");
35968
+ const relative12 = requested.replace(prefix, "").replace(/^\//, "");
35969
+ const safe = normalize3(relative12).replace(/^(\.\.[\/\\])+/, "");
35889
35970
  const fullPath = resolve31(root, safe);
35890
35971
  if (!fullPath.startsWith(root)) {
35891
35972
  return send(res, 403, "forbidden");
@@ -36116,6 +36197,7 @@ function createDevServer(opts = {}) {
36116
36197
  state.bundleSourceWatcher = startBundleSourceWatcher(state);
36117
36198
  if (state.app) state.announcedTokensHash = servedTokensHash(state.app);
36118
36199
  state.appWatcher = startAppSourceWatcher(state);
36200
+ void primeAppDependencyWatchers(state);
36119
36201
  }
36120
36202
  const handleRequest = (req, res) => {
36121
36203
  logRequest(req, res, Date.now());
@@ -36506,12 +36588,20 @@ ${err.message}`);
36506
36588
  }
36507
36589
  });
36508
36590
  httpServer.on("close", () => {
36591
+ state.closed = true;
36509
36592
  state.bundleWatcher?.close();
36510
36593
  state.bundleWatcher = void 0;
36511
36594
  state.bundleSourceWatcher?.close();
36512
36595
  state.bundleSourceWatcher = void 0;
36513
36596
  state.appWatcher?.close();
36514
36597
  state.appWatcher = void 0;
36598
+ for (const w of state.appDepWatchers ?? []) {
36599
+ try {
36600
+ w.close();
36601
+ } catch {
36602
+ }
36603
+ }
36604
+ state.appDepWatchers = void 0;
36515
36605
  for (const client2 of [...state.sseClients, ...state.adminClients]) {
36516
36606
  try {
36517
36607
  client2.end();
@@ -39516,11 +39606,12 @@ __export(build_exports2, {
39516
39606
  snapshotTokens: () => snapshotTokens,
39517
39607
  tokensSnapshotMessage: () => tokensSnapshotMessage,
39518
39608
  withPinnedRelease: () => withPinnedRelease,
39519
- withStoreNavBundle: () => withStoreNavBundle
39609
+ withStoreNavBundle: () => withStoreNavBundle,
39610
+ withoutDevOnlyAppConfig: () => withoutDevOnlyAppConfig
39520
39611
  });
39521
39612
  import { createHash as createHash19 } from "node:crypto";
39522
39613
  import { readFileSync as readFileSync42, readdirSync as readdirSync21, existsSync as existsSync39 } from "node:fs";
39523
- import { dirname as dirname22, join as join36, resolve as resolve32 } from "node:path";
39614
+ import { dirname as dirname23, join as join37, resolve as resolve32 } from "node:path";
39524
39615
  import { fileURLToPath as fileURLToPath19 } from "node:url";
39525
39616
  import { createRequire as createRequire2 } from "node:module";
39526
39617
  import { execFileSync as execFileSync4 } from "node:child_process";
@@ -39558,7 +39649,7 @@ function l10nLintOptions(locale, appDir2) {
39558
39649
  const tags = (locale.translations ?? []).filter((t) => t !== locale.default);
39559
39650
  const catalog = /* @__PURE__ */ new Set();
39560
39651
  for (const tag of tags) {
39561
- const path2 = join36(appDir2, "l10n", `${tag}.json`);
39652
+ const path2 = join37(appDir2, "l10n", `${tag}.json`);
39562
39653
  if (!existsSync39(path2)) continue;
39563
39654
  try {
39564
39655
  const parsed = JSON.parse(readFileSync42(path2, "utf8"));
@@ -39727,7 +39818,7 @@ function shellSha(root = REPO_ROOT7) {
39727
39818
  function isMonorepoCheckout(dir) {
39728
39819
  try {
39729
39820
  const top = execFileSync4("git", ["rev-parse", "--show-toplevel"], { cwd: dir, stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
39730
- return top.length > 0 && existsSync39(join36(top, "core", "schema", "core.proto"));
39821
+ return top.length > 0 && existsSync39(join37(top, "core", "schema", "core.proto"));
39731
39822
  } catch {
39732
39823
  return false;
39733
39824
  }
@@ -39805,6 +39896,17 @@ function linkableScreenIdsFrom(text5) {
39805
39896
  }
39806
39897
  return [...ids];
39807
39898
  }
39899
+ function withoutDevOnlyAppConfig(text5) {
39900
+ let cfg;
39901
+ try {
39902
+ cfg = JSON.parse(text5);
39903
+ } catch {
39904
+ return text5;
39905
+ }
39906
+ if (!cfg || typeof cfg !== "object" || !("devGatewayConfig" in cfg)) return text5;
39907
+ delete cfg.devGatewayConfig;
39908
+ return JSON.stringify(cfg);
39909
+ }
39808
39910
  function withProdServeAppConfig(text5, prod) {
39809
39911
  if (!prod?.serve) return text5;
39810
39912
  let cfg;
@@ -39826,7 +39928,8 @@ async function buildRelease(app, dest, opts = {}) {
39826
39928
  const tier5Dir = hasBuiltBundles(loaded.dir) ? bundleOutDir(loaded.dir) : void 0;
39827
39929
  return (await buildFromLoaded(loaded, dest, {
39828
39930
  ...tier5Dir ? { tier5Dir } : {},
39829
- ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {}
39931
+ ...opts.fetchFace ? { fetchFace: opts.fetchFace } : {},
39932
+ ...opts.keepDevOnlyAppConfig ? { keepDevOnlyAppConfig: true } : {}
39830
39933
  })).manifest;
39831
39934
  }
39832
39935
  function countingWixCall(base) {
@@ -40003,7 +40106,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
40003
40106
  if (addrCache.has(name)) return addrCache.get(name);
40004
40107
  let bytes2;
40005
40108
  try {
40006
- bytes2 = readFileSync42(join36(tier5Dir, `${name}.bundle.js`));
40109
+ bytes2 = readFileSync42(join37(tier5Dir, `${name}.bundle.js`));
40007
40110
  } catch {
40008
40111
  return null;
40009
40112
  }
@@ -40024,7 +40127,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
40024
40127
  const MAX_AUTHORING_DOC_BYTES = 128 * 1024;
40025
40128
  if (store.putDoc) {
40026
40129
  for (const [name, file] of [["spec", "SPEC.md"], ["mobile-ux", "MOBILE-UX.md"]]) {
40027
- const path2 = join36(preloaded.dir, file);
40130
+ const path2 = join37(preloaded.dir, file);
40028
40131
  if (!existsSync39(path2)) continue;
40029
40132
  const bytes2 = readFileSync42(path2);
40030
40133
  if (bytes2.length === 0 || bytes2.length > MAX_AUTHORING_DOC_BYTES) {
@@ -40085,7 +40188,7 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
40085
40188
  const fontWarnings = [];
40086
40189
  try {
40087
40190
  const appTokens = readTokensForLint(preloaded) ?? {};
40088
- const policy = existsSync39(join36(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync42(join36(preloaded.dir, "fonts.json"), "utf8")) : {};
40191
+ const policy = existsSync39(join37(preloaded.dir, "fonts.json")) ? JSON.parse(readFileSync42(join37(preloaded.dir, "fonts.json"), "utf8")) : {};
40089
40192
  fontPlan = planFonts(appTokens, policy);
40090
40193
  } catch (err) {
40091
40194
  throw new Error(
@@ -40428,7 +40531,11 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
40428
40531
  ));
40429
40532
  const cfgRes = await devFetch(`${base}/v1/app-config/${encodeURIComponent(app)}`, { headers: { "X-Himalaya-App": app } });
40430
40533
  if (cfgRes.ok) {
40431
- const prodText = withProdServeAppConfig(await cfgRes.text(), preloaded.module.config.environments?.prod);
40534
+ const served = await cfgRes.text();
40535
+ const prodText = withProdServeAppConfig(
40536
+ opts.keepDevOnlyAppConfig ? served : withoutDevOnlyAppConfig(served),
40537
+ preloaded.module.config.environments?.prod
40538
+ );
40432
40539
  const streamPolicyErrors = validateReleaseStreamPolicyConfig(prodText);
40433
40540
  if (streamPolicyErrors.length) {
40434
40541
  throw new Error(`invalid streamPolicy for release ${app}: ${streamPolicyErrors.join("; ")}`);
@@ -40584,7 +40691,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
40584
40691
  await store.reset(app);
40585
40692
  const sources = {};
40586
40693
  for (const definition of config.functions.functions) {
40587
- const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join36(preloaded.dir, "functions", `${definition.name}${extension}`));
40694
+ const candidates = [".ts", ".js", ".mts", ".mjs"].map((extension) => join37(preloaded.dir, "functions", `${definition.name}${extension}`));
40588
40695
  const source = candidates.find((candidate) => existsSync39(candidate));
40589
40696
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
40590
40697
  sources[definition.name] = readFileSync42(source, "utf8");
@@ -40615,7 +40722,7 @@ async function buildFunctionsOnlyRelease(preloaded, dest) {
40615
40722
  return { manifest, failedToBuild: [], missingBundles: [], auth: {} };
40616
40723
  }
40617
40724
  function listBuildableApps() {
40618
- const appsDir = join36(REPO_ROOT7, "apps");
40725
+ const appsDir = join37(REPO_ROOT7, "apps");
40619
40726
  return readdirSync21(appsDir, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("_")).map((d) => d.name);
40620
40727
  }
40621
40728
  var BAKE_OFFLINE_BASE, KNOWN_ICON_NAMES, KNOWN_ICONS, REPO_ROOT7, TIER5_DIR, requireFromHere, SOURCEMAP_ON_DEMAND_PATH, BAKED_SERVER_BASE_URL;
@@ -40649,10 +40756,10 @@ var init_build3 = __esm({
40649
40756
  BAKE_OFFLINE_BASE = "http://himalaya-bake.invalid";
40650
40757
  KNOWN_ICON_NAMES = [...ICON_NAMES].sort();
40651
40758
  KNOWN_ICONS = new Set(KNOWN_ICON_NAMES);
40652
- REPO_ROOT7 = resolve32(dirname22(fileURLToPath19(import.meta.url)), "../..");
40653
- TIER5_DIR = join36(REPO_ROOT7, "core/dev-server/tier5-bundles");
40759
+ REPO_ROOT7 = resolve32(dirname23(fileURLToPath19(import.meta.url)), "../..");
40760
+ TIER5_DIR = join37(REPO_ROOT7, "core/dev-server/tier5-bundles");
40654
40761
  requireFromHere = createRequire2(import.meta.url);
40655
- SOURCEMAP_ON_DEMAND_PATH = join36(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
40762
+ SOURCEMAP_ON_DEMAND_PATH = join37(REPO_ROOT7, "core/dev-server/tier5-bundles-src/sourcemap-on-demand.mjs");
40656
40763
  BAKED_SERVER_BASE_URL = "http://baked.himalaya.invalid";
40657
40764
  }
40658
40765
  });
@@ -41121,7 +41228,7 @@ var init_studio_page = __esm({
41121
41228
 
41122
41229
  // src/studio-timeline.ts
41123
41230
  import { existsSync as existsSync40, readFileSync as readFileSync43 } from "node:fs";
41124
- import { join as join37 } from "node:path";
41231
+ import { join as join38 } from "node:path";
41125
41232
  function stateOf(view) {
41126
41233
  const j = view.journal[0];
41127
41234
  const h = view.health;
@@ -41188,7 +41295,7 @@ function validFrame(f) {
41188
41295
  return true;
41189
41296
  }
41190
41297
  function readTimeline(dir) {
41191
- const file = join37(dir, TIMELINE_FILE);
41298
+ const file = join38(dir, TIMELINE_FILE);
41192
41299
  if (!existsSync40(file)) return [];
41193
41300
  const out = [];
41194
41301
  for (const line of readFileSync43(file, "utf8").split("\n")) {
@@ -41208,14 +41315,14 @@ function trim(frames) {
41208
41315
  return frames.slice(-MAX_FRAMES);
41209
41316
  }
41210
41317
  function writeTimelineJs(dir, frames) {
41211
- writeFileAtomic(join37(dir, TIMELINE_JS), `window.__himiTimeline && window.__himiTimeline(${scriptJson(frames)});
41318
+ writeFileAtomic(join38(dir, TIMELINE_JS), `window.__himiTimeline && window.__himiTimeline(${scriptJson(frames)});
41212
41319
  `);
41213
41320
  }
41214
41321
  function appendFrame(dir, view, reveal = null) {
41215
41322
  const frames = readTimeline(dir);
41216
41323
  const last = frames[frames.length - 1];
41217
41324
  if (last && last.v === view.v && !reveal) {
41218
- if (!existsSync40(join37(dir, TIMELINE_JS))) writeTimelineJs(dir, frames);
41325
+ if (!existsSync40(join38(dir, TIMELINE_JS))) writeTimelineJs(dir, frames);
41219
41326
  return frames.length;
41220
41327
  }
41221
41328
  let prev = null;
@@ -41223,7 +41330,7 @@ function appendFrame(dir, view, reveal = null) {
41223
41330
  const frame = frameFor(stateOf(view), prev, view.generatedAt, view.v, frames.length % KEYFRAME_EVERY === 0);
41224
41331
  if (reveal) frame.reveal = reveal;
41225
41332
  const kept = trim([...frames, frame]);
41226
- writeFileAtomic(join37(dir, TIMELINE_FILE), kept.map((f) => JSON.stringify(f)).join("\n") + "\n");
41333
+ writeFileAtomic(join38(dir, TIMELINE_FILE), kept.map((f) => JSON.stringify(f)).join("\n") + "\n");
41227
41334
  writeTimelineJs(dir, kept);
41228
41335
  return kept.length;
41229
41336
  }
@@ -41245,8 +41352,8 @@ var init_studio_timeline = __esm({
41245
41352
  "src/studio-timeline.ts"() {
41246
41353
  init_progress();
41247
41354
  init_studio_page();
41248
- TIMELINE_FILE = join37(".himi", "studio", "timeline.jsonl");
41249
- TIMELINE_JS = join37(".himi", "studio", "timeline.js");
41355
+ TIMELINE_FILE = join38(".himi", "studio", "timeline.jsonl");
41356
+ TIMELINE_JS = join38(".himi", "studio", "timeline.js");
41250
41357
  MAX_FRAMES = 2e3;
41251
41358
  KEYFRAME_EVERY = 50;
41252
41359
  same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
@@ -41284,7 +41391,7 @@ __export(studio_exports, {
41284
41391
  });
41285
41392
  import { createHash as createHash20 } from "node:crypto";
41286
41393
  import { existsSync as existsSync41, readdirSync as readdirSync22, readFileSync as readFileSync44, realpathSync as realpathSync5, statSync as statSync8 } from "node:fs";
41287
- import { basename as basename9, extname as extname3, join as join38, relative as relative6, resolve as resolve33, sep as sep9 } from "node:path";
41394
+ import { basename as basename10, extname as extname3, join as join39, relative as relative7, resolve as resolve33, sep as sep9 } from "node:path";
41288
41395
  import { pathToFileURL as pathToFileURL7 } from "node:url";
41289
41396
  function realInside(dir, abs) {
41290
41397
  try {
@@ -41307,9 +41414,9 @@ function archiveFile(dir, memory, abs) {
41307
41414
  return null;
41308
41415
  }
41309
41416
  if (size === 0) return null;
41310
- const key2 = relative6(dir, abs);
41417
+ const key2 = relative7(dir, abs);
41311
41418
  const hit = memory.files?.[key2];
41312
- if (hit && hit.size === size && hit.mtimeMs === mtimeMs && hit.ino === ino && existsSync41(join38(dir, HISTORY_DIR, `${hit.sha}.${hit.ext}`))) {
41419
+ if (hit && hit.size === size && hit.mtimeMs === mtimeMs && hit.ino === ino && existsSync41(join39(dir, HISTORY_DIR, `${hit.sha}.${hit.ext}`))) {
41313
41420
  return { sha: hit.sha, ext: hit.ext, file: `${hit.sha}.${hit.ext}` };
41314
41421
  }
41315
41422
  let archived;
@@ -41323,17 +41430,17 @@ function archiveFile(dir, memory, abs) {
41323
41430
  return { sha: archived.sha256, ext: archived.ext, file: `${archived.sha256}.${archived.ext}` };
41324
41431
  }
41325
41432
  function loadMemory(dir, now) {
41326
- const raw = obj(readJson2(join38(dir, MEMORY_FILE)));
41433
+ const raw = obj(readJson2(join39(dir, MEMORY_FILE)));
41327
41434
  if (raw && raw.version === 1 && obj(raw.shots) && Array.isArray(raw.timeline)) return raw;
41328
41435
  return { version: 1, createdAt: now, shots: {}, timeline: [] };
41329
41436
  }
41330
41437
  function observeShots(dir, memory, now) {
41331
- const shotsDir = join38(dir, ".himi", "shots");
41438
+ const shotsDir = join39(dir, ".himi", "shots");
41332
41439
  const seen = /* @__PURE__ */ new Set();
41333
41440
  const files = existsSync41(shotsDir) ? readdirSync22(shotsDir).filter((f) => /\.(png|jpe?g)$/i.test(f)).sort() : [];
41334
41441
  for (const f of files) {
41335
- const id = basename9(f, extname3(f));
41336
- const archived = archiveFile(dir, memory, join38(shotsDir, f));
41442
+ const id = basename10(f, extname3(f));
41443
+ const archived = archiveFile(dir, memory, join39(shotsDir, f));
41337
41444
  if (!archived) continue;
41338
41445
  seen.add(id);
41339
41446
  const { sha, ext } = archived;
@@ -41355,7 +41462,7 @@ function observeShots(dir, memory, now) {
41355
41462
  return memory;
41356
41463
  }
41357
41464
  function palette(dir) {
41358
- const colors = obj(obj(readJson2(join38(dir, "tokens.json")))?.colors);
41465
+ const colors = obj(obj(readJson2(join39(dir, "tokens.json")))?.colors);
41359
41466
  if (!colors) return [];
41360
41467
  const pick2 = (key2) => {
41361
41468
  const v = colors[key2];
@@ -41365,20 +41472,20 @@ function palette(dir) {
41365
41472
  return ["accentPrimary", "accentSecondary", "accentSurface", "surfacePrimary", "textPrimary"].map(pick2).filter((x) => !!x);
41366
41473
  }
41367
41474
  function appIdentity(dir) {
41368
- const manifest = obj(readJson2(join38(dir, "himalaya.content.json")));
41369
- const name = text(manifest?.name) ?? basename9(resolve33(dir));
41475
+ const manifest = obj(readJson2(join39(dir, "himalaya.content.json")));
41476
+ const name = text(manifest?.name) ?? basename10(resolve33(dir));
41370
41477
  const icon = text(manifest?.icon)?.trim();
41371
41478
  const iconPath = icon ? resolve33(dir, icon) : null;
41372
41479
  const real = iconPath ? realInside(dir, iconPath) : null;
41373
41480
  return { name, iconFile: real && statSync8(real).isFile() ? iconPath : null };
41374
41481
  }
41375
41482
  function testRuns(dir) {
41376
- const att = join38(dir, ".himi", "attestations");
41483
+ const att = join39(dir, ".himi", "attestations");
41377
41484
  if (!existsSync41(att)) return [];
41378
41485
  const runs = [];
41379
41486
  for (const f of readdirSync22(att)) {
41380
41487
  if (!f.endsWith(".json") || f === "latest.json") continue;
41381
- const r = obj(readJson2(join38(att, f)));
41488
+ const r = obj(readJson2(join39(att, f)));
41382
41489
  if (!r || r.tool !== "himi-test" || typeof r.runId !== "string") continue;
41383
41490
  const report2 = obj(r.report);
41384
41491
  const coverage = obj(r.coverage);
@@ -41394,20 +41501,20 @@ function testRuns(dir) {
41394
41501
  return runs.sort((a, b) => a.runId.localeCompare(b.runId));
41395
41502
  }
41396
41503
  function siteHome(dir) {
41397
- for (const pages of [join38(dir, ".himi", "business-book", "evidence", "pages"), join38(dir, "evidence", "pages")]) {
41504
+ for (const pages of [join39(dir, ".himi", "business-book", "evidence", "pages"), join39(dir, "evidence", "pages")]) {
41398
41505
  if (!existsSync41(pages)) continue;
41399
41506
  const home = readdirSync22(pages).filter((f) => /^home.*\.(png|jpe?g)$/i.test(f)).sort()[0];
41400
- if (home) return join38(pages, home);
41507
+ if (home) return join39(pages, home);
41401
41508
  }
41402
41509
  return null;
41403
41510
  }
41404
41511
  function uxStatuses(dir) {
41405
- const platforms = obj(obj(readJson2(join38(dir, ".himi", "ux-audit.json")))?.platforms);
41512
+ const platforms = obj(obj(readJson2(join39(dir, ".himi", "ux-audit.json")))?.platforms);
41406
41513
  if (!platforms) return [];
41407
41514
  return Object.entries(platforms).map(([platform, rec]) => ({ platform, status: text(obj(rec)?.status) ?? "" })).filter((p) => p.status);
41408
41515
  }
41409
41516
  function liveRun(dir) {
41410
- const rec = obj(readJson2(join38(dir, RUN_RECORD)));
41517
+ const rec = obj(readJson2(join39(dir, RUN_RECORD)));
41411
41518
  const url = text(rec?.url);
41412
41519
  const pid = rec?.pid;
41413
41520
  if (!url || !/^https?:\/\//i.test(url) || typeof pid !== "number") return null;
@@ -41457,9 +41564,9 @@ function buildView(dir, memory, now) {
41457
41564
  const runs = testRuns(dir);
41458
41565
  const last = runs[runs.length - 1];
41459
41566
  const prev = runs[runs.length - 2];
41460
- const validate3 = obj(readJson2(join38(dir, VALIDATE_RECORD)));
41461
- const push = obj(readJson2(join38(dir, PUSH_RECORD)));
41462
- const edges = readJson2(join38(dir, EDGES_RECORD));
41567
+ const validate3 = obj(readJson2(join39(dir, VALIDATE_RECORD)));
41568
+ const push = obj(readJson2(join39(dir, PUSH_RECORD)));
41569
+ const edges = readJson2(join39(dir, EDGES_RECORD));
41463
41570
  const nav = [];
41464
41571
  if (Array.isArray(edges)) {
41465
41572
  const seen = /* @__PURE__ */ new Set();
@@ -41485,7 +41592,7 @@ function buildView(dir, memory, now) {
41485
41592
  message: e.message,
41486
41593
  step: e.step ?? null,
41487
41594
  stepNumber: e.stepNumber ?? null,
41488
- images: (e.images ?? []).map((i) => historyUrl(basename9(i.file)))
41595
+ images: (e.images ?? []).map((i) => historyUrl(basename10(i.file)))
41489
41596
  })),
41490
41597
  screens,
41491
41598
  focus,
@@ -41530,15 +41637,15 @@ function writeBoard(dir, now) {
41530
41637
  } catch {
41531
41638
  view.timelineFrames = 0;
41532
41639
  }
41533
- writeAtomic(join38(dir, MEMORY_FILE), JSON.stringify(memory));
41534
- writeAtomic(join38(dir, STATE_FILE), `window.__himiStudio && window.__himiStudio(${scriptJson(view)});
41640
+ writeAtomic(join39(dir, MEMORY_FILE), JSON.stringify(memory));
41641
+ writeAtomic(join39(dir, STATE_FILE), `window.__himiStudio && window.__himiStudio(${scriptJson(view)});
41535
41642
  `);
41536
- writeAtomic(join38(dir, STUDIO_PAGE), renderStudioHtml(view));
41643
+ writeAtomic(join39(dir, STUDIO_PAGE), renderStudioHtml(view));
41537
41644
  return view;
41538
41645
  }
41539
41646
  function refreshStudio(dir, now = /* @__PURE__ */ new Date()) {
41540
41647
  try {
41541
- if (!existsSync41(join38(dir, STUDIO_PAGE))) return { refreshed: false };
41648
+ if (!existsSync41(join39(dir, STUDIO_PAGE))) return { refreshed: false };
41542
41649
  return { refreshed: true, view: writeBoard(dir, now.toISOString()) };
41543
41650
  } catch {
41544
41651
  return { refreshed: false };
@@ -41546,13 +41653,13 @@ function refreshStudio(dir, now = /* @__PURE__ */ new Date()) {
41546
41653
  }
41547
41654
  function openStudio(dir, now = /* @__PURE__ */ new Date()) {
41548
41655
  const view = writeBoard(dir, now.toISOString());
41549
- const page = join38(dir, STUDIO_PAGE);
41656
+ const page = join39(dir, STUDIO_PAGE);
41550
41657
  return { page, url: pathToFileURL7(page).href, view };
41551
41658
  }
41552
41659
  function writeStudioRecord(dir, record2, value) {
41553
41660
  try {
41554
41661
  if (!realDirIn(dir, ".himi")) return;
41555
- writeAtomic(join38(dir, record2), `${JSON.stringify(value, null, 2)}
41662
+ writeAtomic(join39(dir, record2), `${JSON.stringify(value, null, 2)}
41556
41663
  `);
41557
41664
  } catch {
41558
41665
  }
@@ -41564,14 +41671,14 @@ var init_studio = __esm({
41564
41671
  init_studio_timeline();
41565
41672
  init_progress();
41566
41673
  init_studio_page();
41567
- STUDIO_DIR = join38(".himi", "studio");
41568
- STUDIO_PAGE = join38(STUDIO_DIR, "index.html");
41569
- STATE_FILE = join38(STUDIO_DIR, "state.js");
41570
- MEMORY_FILE = join38(STUDIO_DIR, "memory.json");
41571
- VALIDATE_RECORD = join38(".himi", "validate.json");
41572
- PUSH_RECORD = join38(".himi", "last-push.json");
41573
- EDGES_RECORD = join38(".himi", "test-edges.json");
41574
- RUN_RECORD = join38(".himi", "run.json");
41674
+ STUDIO_DIR = join39(".himi", "studio");
41675
+ STUDIO_PAGE = join39(STUDIO_DIR, "index.html");
41676
+ STATE_FILE = join39(STUDIO_DIR, "state.js");
41677
+ MEMORY_FILE = join39(STUDIO_DIR, "memory.json");
41678
+ VALIDATE_RECORD = join39(".himi", "validate.json");
41679
+ PUSH_RECORD = join39(".himi", "last-push.json");
41680
+ EDGES_RECORD = join39(".himi", "test-edges.json");
41681
+ RUN_RECORD = join39(".himi", "run.json");
41575
41682
  MAX_TIMELINE = 500;
41576
41683
  MAX_JOURNAL = 80;
41577
41684
  MAX_NAV_EDGES = 40;
@@ -42214,7 +42321,7 @@ var init_push_setup_apple_credentials = __esm({
42214
42321
 
42215
42322
  // src/push-onboarding.ts
42216
42323
  import { existsSync as existsSync42, mkdirSync as mkdirSync19, readFileSync as readFileSync46, statSync as statSync9, writeFileSync as writeFileSync15, chmodSync as chmodSync2 } from "node:fs";
42217
- import { basename as basename10, dirname as dirname23, join as join39, resolve as resolve35 } from "node:path";
42324
+ import { basename as basename11, dirname as dirname24, join as join40, resolve as resolve35 } from "node:path";
42218
42325
  function readJson3(path2) {
42219
42326
  try {
42220
42327
  const parsed = JSON.parse(readFileSync46(path2, "utf8"));
@@ -42225,9 +42332,9 @@ function readJson3(path2) {
42225
42332
  }
42226
42333
  function pushInputsFromContent(dir) {
42227
42334
  const root = resolve35(dir);
42228
- if (!existsSync42(join39(root, "himalaya.content.json"))) return { initialized: false };
42229
- const content = readJson3(join39(root, "himalaya.content.json"));
42230
- const provisioning = readJson3(join39(root, "provisioning.json"));
42335
+ if (!existsSync42(join40(root, "himalaya.content.json"))) return { initialized: false };
42336
+ const content = readJson3(join40(root, "himalaya.content.json"));
42337
+ const provisioning = readJson3(join40(root, "provisioning.json"));
42231
42338
  const native = provisioning.native ?? {};
42232
42339
  return {
42233
42340
  initialized: true,
@@ -42235,7 +42342,7 @@ function pushInputsFromContent(dir) {
42235
42342
  // autoClaimSlug's docblock describes as the project-declared slug. Without the fallback a
42236
42343
  // package with no `name` sent a body missing `app` and earned `400 invalid_app_id` with both
42237
42344
  // private keys already on the wire.
42238
- app: text3(content.name) ?? basename10(root),
42345
+ app: text3(content.name) ?? basename11(root),
42239
42346
  ...text3(provisioning.siteId) ? { site: text3(provisioning.siteId) } : {},
42240
42347
  ...text3(native.iosBundleId) ? { bundleId: text3(native.iosBundleId) } : {},
42241
42348
  ...text3(native.androidApplicationId) ? { androidApplicationId: text3(native.androidApplicationId) } : {}
@@ -42356,14 +42463,14 @@ function buildPushSetupBody(i, keys) {
42356
42463
  };
42357
42464
  }
42358
42465
  function readPushOnboarding(dir) {
42359
- const path2 = join39(resolve35(dir), PUSH_ONBOARDING_PATH);
42466
+ const path2 = join40(resolve35(dir), PUSH_ONBOARDING_PATH);
42360
42467
  if (!existsSync42(path2)) return { version: 1 };
42361
42468
  const parsed = readJson3(path2);
42362
42469
  return { version: 1, ...parsed };
42363
42470
  }
42364
42471
  function writeFile(dir, file) {
42365
- const path2 = join39(resolve35(dir), PUSH_ONBOARDING_PATH);
42366
- mkdirSync19(dirname23(path2), { recursive: true, mode: 448 });
42472
+ const path2 = join40(resolve35(dir), PUSH_ONBOARDING_PATH);
42473
+ mkdirSync19(dirname24(path2), { recursive: true, mode: 448 });
42367
42474
  writeFileSync15(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
42368
42475
  try {
42369
42476
  chmodSync2(path2, 384);
@@ -42391,7 +42498,7 @@ function recordPushDeferral(dir, d) {
42391
42498
  return push;
42392
42499
  }
42393
42500
  function clearPushDeferral(dir) {
42394
- const path2 = join39(resolve35(dir), PUSH_ONBOARDING_PATH);
42501
+ const path2 = join40(resolve35(dir), PUSH_ONBOARDING_PATH);
42395
42502
  if (!existsSync42(path2)) return;
42396
42503
  const { push: _dropped, ...rest } = readPushOnboarding(dir);
42397
42504
  writeFile(dir, { ...rest, version: 1 });
@@ -43164,7 +43271,7 @@ __export(template_trim_exports, {
43164
43271
  runTemplateTrim: () => runTemplateTrim
43165
43272
  });
43166
43273
  import { cpSync, existsSync as existsSync43, mkdirSync as mkdirSync20, readdirSync as readdirSync23, readFileSync as readFileSync47, renameSync as renameSync5, rmSync as rmSync8, statSync as statSync10, writeFileSync as writeFileSync16 } from "node:fs";
43167
- import { dirname as dirname24, join as join40 } from "node:path";
43274
+ import { dirname as dirname25, join as join41 } from "node:path";
43168
43275
  function routeMatcher(pattern) {
43169
43276
  const detail = /^\^([A-Za-z0-9_]+)\(\?:\[_\/\]\(\.\+\)\)\?\$$/.exec(pattern);
43170
43277
  if (detail) {
@@ -43858,20 +43965,20 @@ function homeModulesPass(app, kept, edited) {
43858
43965
  return { text: patched.src, dropped: patched.droppedModules };
43859
43966
  }
43860
43967
  function listWorkers(dir) {
43861
- const root = join40(dir, "tier5-src");
43968
+ const root = join41(dir, "tier5-src");
43862
43969
  if (!existsSync43(root)) return { dirs: [], files: {} };
43863
- const dirs = readdirSync23(root).filter((n) => statSync10(join40(root, n)).isDirectory()).sort();
43970
+ const dirs = readdirSync23(root).filter((n) => statSync10(join41(root, n)).isDirectory()).sort();
43864
43971
  const files = {};
43865
43972
  const walk2 = (abs, rel) => {
43866
43973
  for (const name of readdirSync23(abs)) {
43867
43974
  if (name === "node_modules") continue;
43868
- const p = join40(abs, name);
43975
+ const p = join41(abs, name);
43869
43976
  const r = `${rel}/${name}`;
43870
43977
  if (statSync10(p).isDirectory()) walk2(p, r);
43871
43978
  else if (/\.(?:[cm]?[jt]sx?|json)$/.test(name)) files[r] = readFileSync47(p, "utf8");
43872
43979
  }
43873
43980
  };
43874
- for (const d of dirs) walk2(join40(root, d), `tier5-src/${d}`);
43981
+ for (const d of dirs) walk2(join41(root, d), `tier5-src/${d}`);
43875
43982
  return { dirs, files };
43876
43983
  }
43877
43984
  function csv(v) {
@@ -43894,8 +44001,8 @@ async function runTemplateTrim(req, deps) {
43894
44001
  links = req.links;
43895
44002
  }
43896
44003
  const dir = req.dir;
43897
- const devPath = join40(dir, "dev/index.ts");
43898
- const configPath = join40(dir, "config.ts");
44004
+ const devPath = join41(dir, "dev/index.ts");
44005
+ const configPath = join41(dir, "config.ts");
43899
44006
  if (!existsSync43(devPath) || !existsSync43(configPath)) {
43900
44007
  return refuse3(new TrimRefusal(`${dir} has no dev/index.ts + config.ts \u2014 point --content at an app scaffolded with \`himi init --template\``));
43901
44008
  }
@@ -43913,23 +44020,23 @@ async function runTemplateTrim(req, deps) {
43913
44020
  throw e;
43914
44021
  }
43915
44022
  if (req.dryRun) return { code: 0, result: { ok: true, dryRun: true, ...plan.report, validate: null } };
43916
- const hadHimi = existsSync43(join40(dir, ".himi"));
43917
- const backupRel = join40(".himi", "trim-backup", (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-"));
43918
- const backup = join40(dir, backupRel);
44023
+ const hadHimi = existsSync43(join41(dir, ".himi"));
44024
+ const backupRel = join41(".himi", "trim-backup", (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-"));
44025
+ const backup = join41(dir, backupRel);
43919
44026
  const originals = [[devPath, "dev/index.ts"], [configPath, "config.ts"]];
43920
44027
  const moved = [];
43921
44028
  const restore = () => {
43922
44029
  for (const [path2, rel] of originals) {
43923
- const original = readFileSync47(join40(backup, rel));
44030
+ const original = readFileSync47(join41(backup, rel));
43924
44031
  if (!existsSync43(path2) || !readFileSync47(path2).equals(original)) writeFileSync16(path2, original);
43925
44032
  }
43926
- for (const name of [...moved].reverse()) renameSync5(join40(backup, "tier5-src", name), join40(dir, "tier5-src", name));
44033
+ for (const name of [...moved].reverse()) renameSync5(join41(backup, "tier5-src", name), join41(dir, "tier5-src", name));
43927
44034
  moved.length = 0;
43928
44035
  };
43929
44036
  const apply = () => {
43930
44037
  const moveDir = deps.moveDir ?? renameSync5;
43931
44038
  for (const name of plan.removedWorkers) {
43932
- moveDir(join40(dir, "tier5-src", name), join40(backup, "tier5-src", name));
44039
+ moveDir(join41(dir, "tier5-src", name), join41(backup, "tier5-src", name));
43933
44040
  moved.push(name);
43934
44041
  }
43935
44042
  if (plan.dev !== dev) writeFileSync16(devPath, plan.dev);
@@ -43937,8 +44044,8 @@ async function runTemplateTrim(req, deps) {
43937
44044
  };
43938
44045
  const dropBackup = () => {
43939
44046
  rmSync8(backup, { recursive: true, force: true });
43940
- for (const d of [dirname24(backup), join40(dir, ".himi")]) {
43941
- if (d === join40(dir, ".himi") && hadHimi) break;
44047
+ for (const d of [dirname25(backup), join41(dir, ".himi")]) {
44048
+ if (d === join41(dir, ".himi") && hadHimi) break;
43942
44049
  try {
43943
44050
  if (!readdirSync23(d).length) rmSync8(d, { recursive: true });
43944
44051
  } catch {
@@ -43964,9 +44071,9 @@ async function runTemplateTrim(req, deps) {
43964
44071
  return { code: 1, result: { ok: false, error: `${error} (${message}); every file was restored`, rolledBack: true, ...base(validate4) } };
43965
44072
  };
43966
44073
  try {
43967
- mkdirSync20(join40(backup, "dev"), { recursive: true });
43968
- for (const [path2, rel] of originals) cpSync(path2, join40(backup, rel));
43969
- if (plan.removedWorkers.length) mkdirSync20(join40(backup, "tier5-src"), { recursive: true });
44074
+ mkdirSync20(join41(backup, "dev"), { recursive: true });
44075
+ for (const [path2, rel] of originals) cpSync(path2, join41(backup, rel));
44076
+ if (plan.removedWorkers.length) mkdirSync20(join41(backup, "tier5-src"), { recursive: true });
43970
44077
  } catch (e) {
43971
44078
  dropBackup();
43972
44079
  return { code: 1, result: { ok: false, error: `could not back up the app before trimming it (${e.message}); nothing was changed`, rolledBack: true, ...base() } };
@@ -44748,7 +44855,7 @@ __export(pack_exports, {
44748
44855
  import { createHash as createHash21 } from "node:crypto";
44749
44856
  import { deflateRawSync, inflateRawSync } from "node:zlib";
44750
44857
  import { existsSync as existsSync44, mkdirSync as mkdirSync21, readFileSync as readFileSync48, readdirSync as readdirSync24, rmSync as rmSync9, statSync as statSync11, writeFileSync as writeFileSync17 } from "node:fs";
44751
- import { dirname as dirname25, join as join41, resolve as resolve37 } from "node:path";
44858
+ import { dirname as dirname26, join as join42, resolve as resolve37 } from "node:path";
44752
44859
  function writeZip(entries) {
44753
44860
  const sorted2 = entries.slice().sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
44754
44861
  const total = sorted2.reduce((n, e) => n + e.bytes.length, 0);
@@ -44845,10 +44952,10 @@ function readIf(path2) {
44845
44952
  return existsSync44(path2) && statSync11(path2).isFile() ? readFileSync48(path2) : null;
44846
44953
  }
44847
44954
  function listDir(dir) {
44848
- return existsSync44(dir) ? readdirSync24(dir).filter((f) => statSync11(join41(dir, f)).isFile()) : [];
44955
+ return existsSync44(dir) ? readdirSync24(dir).filter((f) => statSync11(join42(dir, f)).isFile()) : [];
44849
44956
  }
44850
44957
  function gatherReleaseEntries(appDir2) {
44851
- const manifestPath = join41(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
44958
+ const manifestPath = join42(appDir2, HIMI_PACKAGE_MANIFEST_PATH);
44852
44959
  const manifestBytes = readIf(manifestPath);
44853
44960
  if (!manifestBytes) throw new Error(`no ${HIMI_PACKAGE_MANIFEST_PATH} in ${appDir2} \u2014 build a release there first`);
44854
44961
  const manifest = JSON.parse(manifestBytes.toString("utf8"));
@@ -44872,7 +44979,7 @@ function gatherReleaseEntries(appDir2) {
44872
44979
  }
44873
44980
  const missing = [];
44874
44981
  for (const rel of wanted) {
44875
- const bytes2 = readIf(join41(appDir2, rel));
44982
+ const bytes2 = readIf(join42(appDir2, rel));
44876
44983
  if (bytes2) entries.push({ path: rel, bytes: bytes2 });
44877
44984
  else missing.push(rel);
44878
44985
  }
@@ -44883,12 +44990,12 @@ function gatherReleaseEntries(appDir2) {
44883
44990
  );
44884
44991
  }
44885
44992
  for (const name of SINGLETONS) {
44886
- const bytes2 = readIf(join41(appDir2, name));
44993
+ const bytes2 = readIf(join42(appDir2, name));
44887
44994
  if (bytes2) entries.push({ path: name, bytes: bytes2 });
44888
44995
  }
44889
44996
  const skipped = [];
44890
44997
  for (const sub of ["screens", "bundles", "assets", "widgets"]) {
44891
- for (const f of listDir(join41(appDir2, sub))) {
44998
+ for (const f of listDir(join42(appDir2, sub))) {
44892
44999
  if (!wanted.has(`${sub}/${f}`)) skipped.push(`${sub}/${f}`);
44893
45000
  }
44894
45001
  }
@@ -44921,18 +45028,18 @@ function buildEntries(appDir2, app, opts) {
44921
45028
  return { all, header, manifest, skipped };
44922
45029
  }
44923
45030
  function packRelease(releaseRoot, app, out, opts = {}) {
44924
- const appDir2 = join41(resolve37(releaseRoot), app);
45031
+ const appDir2 = join42(resolve37(releaseRoot), app);
44925
45032
  const { all, header, skipped } = buildEntries(appDir2, app, opts);
44926
45033
  const buf = writeZip(all);
44927
45034
  const isDir2 = existsSync44(out) && statSync11(out).isDirectory();
44928
- const outFile = isDir2 ? join41(resolve37(out), packageFileName(app, header.releaseId)) : resolve37(out);
44929
- mkdirSync21(dirname25(outFile), { recursive: true });
45035
+ const outFile = isDir2 ? join42(resolve37(out), packageFileName(app, header.releaseId)) : resolve37(out);
45036
+ mkdirSync21(dirname26(outFile), { recursive: true });
44930
45037
  writeFileSync17(outFile, buf);
44931
45038
  return { app, releaseId: header.releaseId, header, out: outFile, bytes: buf.length, entryCount: all.length, skipped };
44932
45039
  }
44933
45040
  function resolvePackageDirDest(outDir, app, releaseId) {
44934
45041
  const packagedApp = (dir) => {
44935
- const bytes2 = readIf(join41(dir, HIMI_PACKAGE_HEADER_PATH));
45042
+ const bytes2 = readIf(join42(dir, HIMI_PACKAGE_HEADER_PATH));
44936
45043
  if (!bytes2) return void 0;
44937
45044
  try {
44938
45045
  return JSON.parse(bytes2.toString("utf8")).app;
@@ -44949,7 +45056,7 @@ function resolvePackageDirDest(outDir, app, releaseId) {
44949
45056
  throw new Error(`refusing to write a package tree over ${outDir} \u2014 it is a file, not a directory`);
44950
45057
  }
44951
45058
  if (replaceable(outDir)) return outDir;
44952
- const child = join41(outDir, packageDirName(app, releaseId));
45059
+ const child = join42(outDir, packageDirName(app, releaseId));
44953
45060
  if (!replaceable(child)) {
44954
45061
  throw new Error(
44955
45062
  `refusing to replace ${child}: it is not empty and is not a ${app} package (no ${HIMI_PACKAGE_HEADER_PATH}). Pass --out to a new or empty directory.`
@@ -44963,14 +45070,14 @@ function packReleaseToDir(releaseRoot, app, outDir, opts = {}) {
44963
45070
  "a package carrying the app's source has no --format dir form: readers that predate the source entry drop it before hashing a directory and refuse the package as tampered. Pack it as a .himi archive."
44964
45071
  );
44965
45072
  }
44966
- const appDir2 = join41(resolve37(releaseRoot), app);
45073
+ const appDir2 = join42(resolve37(releaseRoot), app);
44967
45074
  const { all, header, skipped } = buildEntries(appDir2, app, opts);
44968
45075
  const dest = resolvePackageDirDest(resolve37(outDir), app, header.releaseId);
44969
45076
  rmSync9(dest, { recursive: true, force: true });
44970
45077
  let bytes2 = 0;
44971
45078
  for (const entry of all) {
44972
- const target = join41(dest, entry.path);
44973
- mkdirSync21(dirname25(target), { recursive: true });
45079
+ const target = join42(dest, entry.path);
45080
+ mkdirSync21(dirname26(target), { recursive: true });
44974
45081
  writeFileSync17(target, entry.bytes);
44975
45082
  bytes2 += entry.bytes.length;
44976
45083
  }
@@ -44998,10 +45105,10 @@ function openPackageDir(dir) {
44998
45105
  const root = resolve37(dir);
44999
45106
  const entries = /* @__PURE__ */ new Map();
45000
45107
  const walk2 = (rel) => {
45001
- const abs = rel ? join41(root, rel) : root;
45108
+ const abs = rel ? join42(root, rel) : root;
45002
45109
  for (const name of readdirSync24(abs)) {
45003
45110
  const childRel = rel ? `${rel}/${name}` : name;
45004
- const childAbs = join41(abs, name);
45111
+ const childAbs = join42(abs, name);
45005
45112
  if (statSync11(childAbs).isDirectory()) walk2(childRel);
45006
45113
  else if (isSafeEntryName(childRel)) entries.set(childRel, readFileSync48(childAbs));
45007
45114
  }
@@ -45048,11 +45155,11 @@ function unpackTo(buf, dest, appFallback) {
45048
45155
  if (!app) throw new Error("package declares no app id (no himi-package.json and no manifest.app)");
45049
45156
  if (!isSafeAppId(app)) throw new Error(`package declares an unsafe app id ${JSON.stringify(app)} \u2014 refusing to unpack it`);
45050
45157
  const root = resolve37(dest);
45051
- const appDir2 = join41(root, app);
45158
+ const appDir2 = join42(root, app);
45052
45159
  rmSync9(appDir2, { recursive: true, force: true });
45053
45160
  for (const [rel, bytes2] of entries) {
45054
- const target = join41(appDir2, rel);
45055
- mkdirSync21(dirname25(target), { recursive: true });
45161
+ const target = join42(appDir2, rel);
45162
+ mkdirSync21(dirname26(target), { recursive: true });
45056
45163
  writeFileSync17(target, bytes2);
45057
45164
  }
45058
45165
  return { root, appDir: appDir2, app };
@@ -45088,19 +45195,19 @@ __export(app_source_exports, {
45088
45195
  zipAppSource: () => zipAppSource
45089
45196
  });
45090
45197
  import { readdirSync as readdirSync25, lstatSync as lstatSync8, readFileSync as readFileSync49, mkdirSync as mkdirSync22, writeFileSync as writeFileSync18, existsSync as existsSync45, rmSync as rmSync10, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3 } from "node:fs";
45091
- import { join as join42, resolve as resolve38, sep as sep10 } from "node:path";
45198
+ import { join as join43, resolve as resolve38, sep as sep10 } from "node:path";
45092
45199
  import { deflateRawSync as deflateRawSync2 } from "node:zlib";
45093
45200
  function walkSourceTree(dir, file, skip) {
45094
45201
  const walk2 = (relDir) => {
45095
- for (const name of readdirSync25(join42(dir, relDir))) {
45096
- const rel = relDir ? join42(relDir, name) : name;
45097
- const st = lstatSync8(join42(dir, rel));
45202
+ for (const name of readdirSync25(join43(dir, relDir))) {
45203
+ const rel = relDir ? join43(relDir, name) : name;
45204
+ const st = lstatSync8(join43(dir, rel));
45098
45205
  if (st.isSymbolicLink()) {
45099
45206
  skip(rel);
45100
45207
  continue;
45101
45208
  }
45102
45209
  if (st.isDirectory()) {
45103
- if (isDeniedSourceDir(name, relDir) || existsSync45(join42(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
45210
+ if (isDeniedSourceDir(name, relDir) || existsSync45(join43(dir, rel, PACKAGE_DIR_MARKER))) skip(rel);
45104
45211
  else walk2(rel);
45105
45212
  continue;
45106
45213
  }
@@ -45118,7 +45225,7 @@ function collectAppSource(dir) {
45118
45225
  const skipped = [];
45119
45226
  walkSourceTree(
45120
45227
  dir,
45121
- (archivePath, hostRel) => entries.push({ path: archivePath, bytes: readFileSync49(join42(dir, hostRel)) }),
45228
+ (archivePath, hostRel) => entries.push({ path: archivePath, bytes: readFileSync49(join43(dir, hostRel)) }),
45122
45229
  (hostRel) => skipped.push(hostRel)
45123
45230
  );
45124
45231
  entries.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
@@ -45172,13 +45279,13 @@ function writeAppSource(entries, destDir) {
45172
45279
  const segments = entry.path.split("/");
45173
45280
  let dir = root;
45174
45281
  for (const segment of segments.slice(0, -1)) {
45175
- dir = join42(dir, segment);
45282
+ dir = join43(dir, segment);
45176
45283
  const kind = pathKind(dir);
45177
45284
  if (kind?.isSymbolicLink()) unlinkSync3(dir);
45178
45285
  else if (kind) continue;
45179
45286
  mkdirSync22(dir);
45180
45287
  }
45181
- const target = join42(root, ...segments);
45288
+ const target = join43(root, ...segments);
45182
45289
  if (pathKind(target)?.isSymbolicLink()) unlinkSync3(target);
45183
45290
  writeFileSync18(target, entry.bytes);
45184
45291
  written.push(entry.path);
@@ -45213,7 +45320,7 @@ function writeConflicts(entries, destDir) {
45213
45320
  let dir = root;
45214
45321
  let stop = false;
45215
45322
  for (const [i, segment] of segments.slice(0, -1).entries()) {
45216
- dir = join42(dir, segment);
45323
+ dir = join43(dir, segment);
45217
45324
  const kind2 = pathKind(dir);
45218
45325
  if (!kind2 || kind2.isSymbolicLink()) {
45219
45326
  stop = true;
@@ -45225,7 +45332,7 @@ function writeConflicts(entries, destDir) {
45225
45332
  break;
45226
45333
  }
45227
45334
  if (stop) continue;
45228
- const kind = pathKind(join42(root, ...segments));
45335
+ const kind = pathKind(join43(root, ...segments));
45229
45336
  if (kind && !kind.isSymbolicLink() && kind.isDirectory()) {
45230
45337
  say(entry.path, "is a directory here, but the release has a file at that path");
45231
45338
  }
@@ -45235,7 +45342,7 @@ function writeConflicts(entries, destDir) {
45235
45342
  function removeStaleSource(entries, destDir) {
45236
45343
  const root = resolve38(destDir);
45237
45344
  const removed = staleSourcePaths(entries, root);
45238
- for (const rel of removed) rmSync10(join42(root, ...rel.split("/")), { force: true });
45345
+ for (const rel of removed) rmSync10(join43(root, ...rel.split("/")), { force: true });
45239
45346
  const needed = /* @__PURE__ */ new Set();
45240
45347
  for (const entry of entries) {
45241
45348
  if (isDeniedSourcePath(entry.path)) continue;
@@ -45247,10 +45354,10 @@ function removeStaleSource(entries, destDir) {
45247
45354
  }
45248
45355
  function pruneEmptyDirs(root, rel, needed, removed) {
45249
45356
  let empty = true;
45250
- for (const name of readdirSync25(rel ? join42(root, rel) : root)) {
45251
- const childRel = rel ? join42(rel, name) : name;
45357
+ for (const name of readdirSync25(rel ? join43(root, rel) : root)) {
45358
+ const childRel = rel ? join43(rel, name) : name;
45252
45359
  const posix4 = childRel.split(sep10).join("/");
45253
- const kind = lstatSync8(join42(root, childRel));
45360
+ const kind = lstatSync8(join43(root, childRel));
45254
45361
  if (kind.isSymbolicLink() || !kind.isDirectory() || isDeniedSourceDir(name, rel)) {
45255
45362
  empty = false;
45256
45363
  continue;
@@ -45260,7 +45367,7 @@ function pruneEmptyDirs(root, rel, needed, removed) {
45260
45367
  empty = false;
45261
45368
  continue;
45262
45369
  }
45263
- rmdirSync2(join42(root, childRel));
45370
+ rmdirSync2(join43(root, childRel));
45264
45371
  removed.push(`${posix4}/`);
45265
45372
  }
45266
45373
  return empty;
@@ -45316,7 +45423,7 @@ __export(eject_exports, {
45316
45423
  ejectModule: () => ejectModule
45317
45424
  });
45318
45425
  import { existsSync as existsSync46, mkdirSync as mkdirSync23, readFileSync as readFileSync50, writeFileSync as writeFileSync19 } from "node:fs";
45319
- import { dirname as dirname26, join as join43, relative as relative7, resolve as resolve39, sep as sep11 } from "node:path";
45426
+ import { dirname as dirname27, join as join44, relative as relative8, resolve as resolve39, sep as sep11 } from "node:path";
45320
45427
  function locate(repoRootOrCwd, mod) {
45321
45428
  const inRepo = resolve39(repoRootOrCwd, `stdlib/flows/${mod}/src/index.ts`);
45322
45429
  if (existsSync46(inRepo)) return { path: inRepo, form: "source" };
@@ -45345,8 +45452,8 @@ function ejectModule(opts) {
45345
45452
  };
45346
45453
  }
45347
45454
  const ext = found.form === "source" ? "ts" : "mjs";
45348
- const target = join43(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
45349
- mkdirSync23(dirname26(target), { recursive: true });
45455
+ const target = join44(contentDir2, "tier5-src", "_ejected", `${mod}.${ext}`);
45456
+ mkdirSync23(dirname27(target), { recursive: true });
45350
45457
  const banner = `// EJECTED from @wix/himalaya/${mod}. This app owns this file now.
45351
45458
  //
45352
45459
  // Central fixes to @wix/himalaya/${mod} NO LONGER REACH THIS APP \u2014 including any
@@ -45369,7 +45476,7 @@ function ejectModule(opts) {
45369
45476
  if (!existsSync46(f)) continue;
45370
45477
  const before = readFileSync50(f, "utf8");
45371
45478
  let after = before;
45372
- let rel = relative7(dirname26(f), target).split(sep11).join("/").replace(/\.tsx?$/, ".js");
45479
+ let rel = relative8(dirname27(f), target).split(sep11).join("/").replace(/\.tsx?$/, ".js");
45373
45480
  if (!rel.startsWith(".")) rel = `./${rel}`;
45374
45481
  for (const spec of specifiersFor(mod)) {
45375
45482
  const q = spec.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -45401,7 +45508,7 @@ var init_eject = __esm({
45401
45508
 
45402
45509
  // src/wix-writes.ts
45403
45510
  import { existsSync as existsSync47, readFileSync as readFileSync51 } from "node:fs";
45404
- import { join as join44 } from "node:path";
45511
+ import { join as join45 } from "node:path";
45405
45512
  function isProvenRead(method, path2) {
45406
45513
  if (/[#\x00-\x1F\x7F]/.test(path2)) return false;
45407
45514
  const verb = method.toUpperCase();
@@ -45482,7 +45589,7 @@ function parseDataAccess(text5, from) {
45482
45589
  }
45483
45590
  function readDataAccess(dir) {
45484
45591
  for (const name of ["SPEC.md", "MOBILE-UX.md"]) {
45485
- const p = join44(dir, name);
45592
+ const p = join45(dir, name);
45486
45593
  if (!existsSync47(p)) continue;
45487
45594
  let text5;
45488
45595
  try {
@@ -45594,7 +45701,7 @@ __export(test_exports, {
45594
45701
  writeRecordedMocks: () => writeRecordedMocks
45595
45702
  });
45596
45703
  import { existsSync as existsSync48, mkdirSync as mkdirSync24, readFileSync as readFileSync52, writeFileSync as writeFileSync20 } from "node:fs";
45597
- import { join as join45, resolve as resolve40 } from "node:path";
45704
+ import { join as join46, resolve as resolve40 } from "node:path";
45598
45705
  function readTestConfig(dir) {
45599
45706
  const p = resolve40(dir, TEST_CONFIG_FILE);
45600
45707
  if (!existsSync48(p)) return {};
@@ -45774,8 +45881,8 @@ function writeRecordedMocks(opts) {
45774
45881
  mkdir: (p) => mkdirSync24(p, { recursive: true }),
45775
45882
  write: (p, s) => writeFileSync20(p, s)
45776
45883
  };
45777
- fs.mkdir(join45(opts.dir, "dev"));
45778
- fs.write(join45(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
45884
+ fs.mkdir(join46(opts.dir, "dev"));
45885
+ fs.write(join46(opts.dir, "dev", "net-mocks.json"), JSON.stringify(opts.mocks, null, 2) + "\n");
45779
45886
  return { ok: true, rules, to: "dev/net-mocks.json" };
45780
45887
  }
45781
45888
  function scopeDescriptors(descriptors, requestedIds, invalidScreens) {
@@ -46258,9 +46365,9 @@ __export(mobile_ux_lint_exports, {
46258
46365
  mobileUxIssues: () => mobileUxIssues
46259
46366
  });
46260
46367
  import { existsSync as existsSync49, readFileSync as readFileSync53 } from "node:fs";
46261
- import { join as join46 } from "node:path";
46368
+ import { join as join47 } from "node:path";
46262
46369
  function mobileUxIssues(dir, strict) {
46263
- const file = join46(dir, "MOBILE-UX.md");
46370
+ const file = join47(dir, "MOBILE-UX.md");
46264
46371
  if (!existsSync49(file)) return [];
46265
46372
  let text5;
46266
46373
  try {
@@ -47940,7 +48047,7 @@ __export(functions_exports, {
47940
48047
  runRemoteFunctionOperation: () => runRemoteFunctionOperation
47941
48048
  });
47942
48049
  import { readFileSync as readFileSync54, existsSync as existsSync50 } from "node:fs";
47943
- import { join as join47, resolve as resolve41 } from "node:path";
48050
+ import { join as join48, resolve as resolve41 } from "node:path";
47944
48051
  function resolveFunctionsTarget(input) {
47945
48052
  const explicitUrl = input.functionsUrl?.trim();
47946
48053
  if (explicitUrl) return { mode: "remote", baseUrl: explicitUrl };
@@ -47959,7 +48066,7 @@ async function loadFunctionsApp(dir) {
47959
48066
  }
47960
48067
  const sources = {};
47961
48068
  for (const definition of config.functions.functions) {
47962
- const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join47(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync50);
48069
+ const source = [".ts", ".js", ".mts", ".mjs"].map((extension) => join48(loaded.dir, "functions", `${definition.name}${extension}`)).find(existsSync50);
47963
48070
  if (!source) throw new Error(`missing source for function ${definition.name}; expected functions/${definition.name}.ts`);
47964
48071
  sources[definition.name] = readFileSync54(source, "utf8");
47965
48072
  }
@@ -48114,9 +48221,9 @@ __export(studio_reel_exports, {
48114
48221
  });
48115
48222
  import { createHash as createHash24 } from "node:crypto";
48116
48223
  import { lstatSync as lstatSync9, readFileSync as readFileSync55 } from "node:fs";
48117
- import { basename as basename11, join as join48 } from "node:path";
48224
+ import { basename as basename12, join as join49 } from "node:path";
48118
48225
  function loadMemory2(dir) {
48119
- const m = readJson4(join48(dir, ".himi", "studio", "memory.json"));
48226
+ const m = readJson4(join49(dir, ".himi", "studio", "memory.json"));
48120
48227
  if (!isObj2(m) || m.version !== 1 || !isObj2(m.shots) || !Array.isArray(m.timeline)) return null;
48121
48228
  const shots = [];
48122
48229
  for (const [id, s] of Object.entries(m.shots)) {
@@ -48153,8 +48260,8 @@ function planReel(dir) {
48153
48260
  const memory = loadMemory2(dir);
48154
48261
  const { entries } = readProgress(dir);
48155
48262
  const summary = summarizeProgress(entries);
48156
- const manifest = readJson4(join48(dir, "himalaya.content.json"));
48157
- const tokens = readJson4(join48(dir, "tokens.json"));
48263
+ const manifest = readJson4(join49(dir, "himalaya.content.json"));
48264
+ const tokens = readJson4(join49(dir, "tokens.json"));
48158
48265
  const accentToken = tokens?.colors?.accentPrimary;
48159
48266
  const accentRaw = typeof accentToken === "string" ? accentToken : accentToken?.light;
48160
48267
  const accent = typeof accentRaw === "string" && ACCENT.test(accentRaw) ? accentRaw : DEFAULT_ACCENT;
@@ -48169,13 +48276,13 @@ function planReel(dir) {
48169
48276
  ts: e.ts,
48170
48277
  message: e.message,
48171
48278
  step: str(e.step),
48172
- files: (Array.isArray(e.images) ? e.images : []).map((i) => isObj2(i) && typeof i.file === "string" ? basename11(i.file) : "").filter((f) => HISTORY_NAME.test(f))
48279
+ files: (Array.isArray(e.images) ? e.images : []).map((i) => isObj2(i) && typeof i.file === "string" ? basename12(i.file) : "").filter((f) => HISTORY_NAME.test(f))
48173
48280
  }));
48174
48281
  const times = [summary.startedAt, ...timeline.map((t) => t.ts), memory?.createdAt].filter((x) => !!x).sort();
48175
48282
  const startedAt = times[0] ?? null;
48176
48283
  const endedAt = [summary.lastAt, ...timeline.map((t) => t.ts)].filter((x) => !!x).sort().pop() ?? null;
48177
48284
  return {
48178
- app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename11(dir),
48285
+ app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename12(dir),
48179
48286
  accent,
48180
48287
  startedAt,
48181
48288
  endedAt,
@@ -48196,7 +48303,7 @@ function inlineImages(dir, plan, budget = REEL_BUDGET_BYTES) {
48196
48303
  const verified = (f) => {
48197
48304
  if (!HISTORY_NAME.test(f)) return null;
48198
48305
  try {
48199
- const path2 = join48(dir, HISTORY_DIR, f);
48306
+ const path2 = join49(dir, HISTORY_DIR, f);
48200
48307
  const st = lstatSync9(path2);
48201
48308
  if (!st.isFile() || st.nlink !== 1) return null;
48202
48309
  const bytes2 = readFileSync55(path2);
@@ -48366,7 +48473,7 @@ __export(native_decode_exports, {
48366
48473
  import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
48367
48474
  import { existsSync as existsSync51, mkdtempSync as mkdtempSync2, readFileSync as readFileSync56, rmSync as rmSync11, writeFileSync as writeFileSync21 } from "node:fs";
48368
48475
  import { tmpdir as tmpdir3 } from "node:os";
48369
- import { join as join49 } from "node:path";
48476
+ import { join as join50 } from "node:path";
48370
48477
  import { fileURLToPath as fileURLToPath20 } from "node:url";
48371
48478
  function nativeDecodePackageDir() {
48372
48479
  return fileURLToPath20(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
@@ -48376,8 +48483,8 @@ function nativeDecodeAndroidHarnessDir() {
48376
48483
  }
48377
48484
  function nativeOracleShipped() {
48378
48485
  return {
48379
- ios: existsSync51(join49(nativeDecodePackageDir(), "Package.swift")),
48380
- android: existsSync51(join49(nativeDecodeAndroidHarnessDir(), "gradlew"))
48486
+ ios: existsSync51(join50(nativeDecodePackageDir(), "Package.swift")),
48487
+ android: existsSync51(join50(nativeDecodeAndroidHarnessDir(), "gradlew"))
48381
48488
  };
48382
48489
  }
48383
48490
  function detectNativeDecode(options = {}) {
@@ -48388,7 +48495,7 @@ function detectNativeDecode(options = {}) {
48388
48495
  return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
48389
48496
  }
48390
48497
  if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
48391
- const packageAvailable = options.packageAvailable ?? existsSync51(join49(packageDir, "Package.swift"));
48498
+ const packageAvailable = options.packageAvailable ?? existsSync51(join50(packageDir, "Package.swift"));
48392
48499
  if (!packageAvailable) {
48393
48500
  return {
48394
48501
  platform: "ios",
@@ -48400,7 +48507,7 @@ function detectNativeDecode(options = {}) {
48400
48507
  }
48401
48508
  function localPropertiesSdk(harnessDir) {
48402
48509
  try {
48403
- const match = readFileSync56(join49(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
48510
+ const match = readFileSync56(join50(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
48404
48511
  return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
48405
48512
  } catch {
48406
48513
  return null;
@@ -48408,7 +48515,7 @@ function localPropertiesSdk(harnessDir) {
48408
48515
  }
48409
48516
  function detectAndroidNativeDecode(options = {}) {
48410
48517
  const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
48411
- const gradlew = join49(harnessDir, "gradlew");
48518
+ const gradlew = join50(harnessDir, "gradlew");
48412
48519
  const gradlewAvailable = options.gradlewAvailable ?? existsSync51(gradlew);
48413
48520
  if (!gradlewAvailable) {
48414
48521
  return {
@@ -48491,14 +48598,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
48491
48598
  return verdicts;
48492
48599
  }
48493
48600
  function runNativeDecode(options) {
48494
- const descriptorDir = mkdtempSync2(join49(tmpdir3(), "himi-native-decode-"));
48601
+ const descriptorDir = mkdtempSync2(join50(tmpdir3(), "himi-native-decode-"));
48495
48602
  const startedAt = Date.now();
48496
48603
  try {
48497
48604
  for (const descriptor of options.descriptors) {
48498
48605
  if (typeof descriptor.descriptorJson !== "string") {
48499
48606
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
48500
48607
  }
48501
- writeFileSync21(join49(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48608
+ writeFileSync21(join50(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48502
48609
  }
48503
48610
  options.progress?.("building cached Swift oracle");
48504
48611
  execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
@@ -48510,7 +48617,7 @@ function runNativeDecode(options) {
48510
48617
  encoding: "utf8"
48511
48618
  }).trim();
48512
48619
  options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
48513
- const stdout = execFileSync5(join49(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
48620
+ const stdout = execFileSync5(join50(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
48514
48621
  stdio: ["ignore", "pipe", "pipe"],
48515
48622
  encoding: "utf8"
48516
48623
  });
@@ -48528,15 +48635,15 @@ function runNativeDecode(options) {
48528
48635
  }
48529
48636
  }
48530
48637
  function runAndroidNativeDecode(options) {
48531
- const descriptorDir = mkdtempSync2(join49(tmpdir3(), "himi-native-decode-android-"));
48532
- const outputPath = join49(descriptorDir, "verdicts.ndjson");
48638
+ const descriptorDir = mkdtempSync2(join50(tmpdir3(), "himi-native-decode-android-"));
48639
+ const outputPath = join50(descriptorDir, "verdicts.ndjson");
48533
48640
  const startedAt = Date.now();
48534
48641
  try {
48535
48642
  for (const descriptor of options.descriptors) {
48536
48643
  if (typeof descriptor.descriptorJson !== "string") {
48537
48644
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
48538
48645
  }
48539
- writeFileSync21(join49(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48646
+ writeFileSync21(join50(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
48540
48647
  }
48541
48648
  options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
48542
48649
  execFileSync5(options.gradlew, [
@@ -48622,12 +48729,12 @@ __export(browser_authoring_exports, {
48622
48729
  import { createServer as createServer3 } from "node:http";
48623
48730
  import { createHash as createHash25, randomBytes as randomBytes4 } from "node:crypto";
48624
48731
  import { existsSync as existsSync52, readdirSync as readdirSync26, readFileSync as readFileSync57, realpathSync as realpathSync6, statSync as statSync12 } from "node:fs";
48625
- import { join as join50, posix as posix2, relative as relative8, sep as sep12 } from "node:path";
48732
+ import { join as join51, posix as posix2, relative as relative9, sep as sep12 } from "node:path";
48626
48733
  function humanMs(ms) {
48627
48734
  return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
48628
48735
  }
48629
48736
  function collectWorkerSources(tier5SrcDir, bundleName) {
48630
- const root = join50(tier5SrcDir, bundleName);
48737
+ const root = join51(tier5SrcDir, bundleName);
48631
48738
  const files = {};
48632
48739
  const visitedDirs = /* @__PURE__ */ new Set();
48633
48740
  const walk2 = (abs, rel) => {
@@ -48635,7 +48742,7 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
48635
48742
  if (visitedDirs.has(real)) return;
48636
48743
  visitedDirs.add(real);
48637
48744
  for (const name of readdirSync26(abs).sort()) {
48638
- const childAbs = join50(abs, name);
48745
+ const childAbs = join51(abs, name);
48639
48746
  const childRel = posix2.join(rel, name);
48640
48747
  if (statSync12(childAbs).isDirectory()) {
48641
48748
  walk2(childAbs, childRel);
@@ -48661,18 +48768,18 @@ function collectRelativeSiblings(files, tier5SrcDir) {
48661
48768
  const spec = m[1];
48662
48769
  const virtual = posix2.normalize(posix2.join(dir, spec));
48663
48770
  if (!virtual.startsWith("/tier5-src/")) continue;
48664
- const onDisk = join50(tier5SrcDir, virtual.slice("/tier5-src/".length));
48771
+ const onDisk = join51(tier5SrcDir, virtual.slice("/tier5-src/".length));
48665
48772
  const candidates = [
48666
48773
  onDisk,
48667
48774
  `${onDisk}.ts`,
48668
48775
  `${onDisk}.js`,
48669
48776
  onDisk.replace(/\.js$/, ".ts"),
48670
- join50(onDisk, "index.ts"),
48671
- join50(onDisk, "index.js")
48777
+ join51(onDisk, "index.ts"),
48778
+ join51(onDisk, "index.js")
48672
48779
  ];
48673
48780
  for (const abs of candidates) {
48674
48781
  if (!existsSync52(abs) || statSync12(abs).isDirectory()) continue;
48675
- const key2 = `/tier5-src/${relative8(tier5SrcDir, abs).split(sep12).join(posix2.sep)}`;
48782
+ const key2 = `/tier5-src/${relative9(tier5SrcDir, abs).split(sep12).join(posix2.sep)}`;
48676
48783
  if (key2 in files) break;
48677
48784
  files[key2] = readFileSync57(abs, "utf8");
48678
48785
  queue.push(key2);
@@ -48882,7 +48989,7 @@ __export(coverage_exports, {
48882
48989
  trendAndStore: () => trendAndStore
48883
48990
  });
48884
48991
  import { existsSync as existsSync53, mkdirSync as mkdirSync25, readFileSync as readFileSync58, writeFileSync as writeFileSync22 } from "node:fs";
48885
- import { dirname as dirname27, join as join51 } from "node:path";
48992
+ import { dirname as dirname28, join as join52 } from "node:path";
48886
48993
  function suppressedNativeKeys(oracle) {
48887
48994
  return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
48888
48995
  }
@@ -49062,7 +49169,7 @@ function assembleLedger(r, options = {}) {
49062
49169
  return out;
49063
49170
  }
49064
49171
  function trendAndStore(dir, entries, suppressed) {
49065
- const p = join51(dir, LEDGER_FILE);
49172
+ const p = join52(dir, LEDGER_FILE);
49066
49173
  let previous = null;
49067
49174
  try {
49068
49175
  if (existsSync53(p)) {
@@ -49074,7 +49181,7 @@ function trendAndStore(dir, entries, suppressed) {
49074
49181
  const current = entries.map((e) => e.key);
49075
49182
  const stored = [.../* @__PURE__ */ new Set([...current, ...(previous ?? []).filter((key2) => (suppressed ?? []).includes(key2))])];
49076
49183
  try {
49077
- mkdirSync25(dirname27(p), { recursive: true });
49184
+ mkdirSync25(dirname28(p), { recursive: true });
49078
49185
  writeFileSync22(p, JSON.stringify({ keys: stored, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
49079
49186
  } catch {
49080
49187
  return null;
@@ -49105,7 +49212,7 @@ function formatLedger(entries, trend) {
49105
49212
  return out.join("\n");
49106
49213
  }
49107
49214
  function diffAndStoreObservations(dir, current) {
49108
- const p = join51(dir, OBS_FILE);
49215
+ const p = join52(dir, OBS_FILE);
49109
49216
  let previous = null;
49110
49217
  try {
49111
49218
  if (existsSync53(p)) {
@@ -49119,7 +49226,7 @@ function diffAndStoreObservations(dir, current) {
49119
49226
  } catch {
49120
49227
  }
49121
49228
  try {
49122
- mkdirSync25(dirname27(p), { recursive: true });
49229
+ mkdirSync25(dirname28(p), { recursive: true });
49123
49230
  writeFileSync22(p, JSON.stringify({ screens: current, ts: (/* @__PURE__ */ new Date()).toISOString() }, null, 2));
49124
49231
  } catch {
49125
49232
  return null;
@@ -49158,8 +49265,8 @@ var LEDGER_FILE, OBS_FILE;
49158
49265
  var init_coverage = __esm({
49159
49266
  "src/coverage.ts"() {
49160
49267
  init_native_decode();
49161
- LEDGER_FILE = join51(".himi", "test-ledger.json");
49162
- OBS_FILE = join51(".himi", "test-observations.json");
49268
+ LEDGER_FILE = join52(".himi", "test-ledger.json");
49269
+ OBS_FILE = join52(".himi", "test-observations.json");
49163
49270
  }
49164
49271
  });
49165
49272
 
@@ -49171,7 +49278,7 @@ __export(design_kits_exports, {
49171
49278
  listKits: () => listKits2
49172
49279
  });
49173
49280
  import { existsSync as existsSync54, readFileSync as readFileSync59, readdirSync as readdirSync27 } from "node:fs";
49174
- import { join as join52, basename as basename12 } from "node:path";
49281
+ import { join as join53, basename as basename13 } from "node:path";
49175
49282
  import { fileURLToPath as fileURLToPath21 } from "node:url";
49176
49283
  function kitsDir() {
49177
49284
  return KIT_DIR_CANDIDATES.find((p) => existsSync54(p));
@@ -49179,7 +49286,7 @@ function kitsDir() {
49179
49286
  function listKits2() {
49180
49287
  const dir = kitsDir();
49181
49288
  if (!dir) return [];
49182
- return readdirSync27(dir).filter((f) => f.endsWith(".json")).map((f) => basename12(f, ".json")).sort();
49289
+ return readdirSync27(dir).filter((f) => f.endsWith(".json")).map((f) => basename13(f, ".json")).sort();
49183
49290
  }
49184
49291
  function kitReport(name) {
49185
49292
  const dir = kitsDir();
@@ -49198,7 +49305,7 @@ In a published @wix/himalaya-cli this is a packaging bug \u2014 the kits should
49198
49305
  if (!kits.includes(name)) {
49199
49306
  return { ok: false, kit: name, kits, problems: [`no design kit named "${name}". Available: ${kits.join(", ")}`] };
49200
49307
  }
49201
- const raw = readFileSync59(join52(dir, `${name}.json`), "utf8");
49308
+ const raw = readFileSync59(join53(dir, `${name}.json`), "utf8");
49202
49309
  let parsed;
49203
49310
  try {
49204
49311
  parsed = JSON.parse(raw);
@@ -49222,9 +49329,9 @@ var init_design_kits = __esm({
49222
49329
  "src/design-kits.ts"() {
49223
49330
  KIT_DIR_CANDIDATES = [
49224
49331
  // in-repo: tools/himi-cli/src/design-kits.ts → <repo>/stdlib/design-kits/
49225
- join52(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
49332
+ join53(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
49226
49333
  // published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/design-kits/
49227
- join52(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
49334
+ join53(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
49228
49335
  ];
49229
49336
  }
49230
49337
  });
@@ -49239,7 +49346,7 @@ __export(assets_exports, {
49239
49346
  verifyReport: () => verifyReport
49240
49347
  });
49241
49348
  import { readFileSync as readFileSync60 } from "node:fs";
49242
- import { basename as basename13 } from "node:path";
49349
+ import { basename as basename14 } from "node:path";
49243
49350
  function declaredAssets(dir) {
49244
49351
  return collectAssets(dir).map((a) => {
49245
49352
  const bytes2 = readFileSync60(a.path);
@@ -49320,7 +49427,7 @@ function verifyReport(dir, app, manifest) {
49320
49427
  }
49321
49428
  function addAssetPayload(manifest, filePath, opts) {
49322
49429
  const bytes2 = readFileSync60(filePath);
49323
- const name = opts.name ?? basename13(filePath);
49430
+ const name = opts.name ?? basename14(filePath);
49324
49431
  const sha2565 = assetSha256(bytes2);
49325
49432
  const record2 = {
49326
49433
  sha256: sha2565,
@@ -50994,7 +51101,7 @@ __export(run_exports, {
50994
51101
  });
50995
51102
  import { cpSync as cpSync2, existsSync as existsSync55, mkdirSync as mkdirSync26, mkdtempSync as mkdtempSync3, readFileSync as readFileSync61, rmSync as rmSync12, statSync as statSync13 } from "node:fs";
50996
51103
  import { tmpdir as tmpdir4 } from "node:os";
50997
- import { dirname as dirname28, join as join53 } from "node:path";
51104
+ import { dirname as dirname29, join as join54 } from "node:path";
50998
51105
  import { fileURLToPath as fileURLToPath22 } from "node:url";
50999
51106
  function makePackageRunHandler(opts) {
51000
51107
  const store = new FileReleaseStore(opts.releaseRoot);
@@ -51023,7 +51130,7 @@ async function fetchBytes(url) {
51023
51130
  async function resolvePackage(source, workDir) {
51024
51131
  const isUrl2 = /^https?:\/\//i.test(source);
51025
51132
  if (!isUrl2 && existsSync55(source) && statSync13(source).isDirectory()) {
51026
- const appDirManifest = join53(source, "release-manifest.json");
51133
+ const appDirManifest = join54(source, "release-manifest.json");
51027
51134
  if (existsSync55(appDirManifest)) {
51028
51135
  const opened2 = openPackageDir(source);
51029
51136
  if (!opened2.validation.ok) {
@@ -51033,9 +51140,9 @@ async function resolvePackage(source, workDir) {
51033
51140
  const app2 = opened2.header?.app ?? opened2.manifest?.app;
51034
51141
  if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
51035
51142
  if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
51036
- const root2 = workDir ?? mkdtempSync3(join53(tmpdir4(), "himi-run-"));
51037
- const target = join53(root2, app2);
51038
- if (join53(source) !== target) {
51143
+ const root2 = workDir ?? mkdtempSync3(join54(tmpdir4(), "himi-run-"));
51144
+ const target = join54(root2, app2);
51145
+ if (join54(source) !== target) {
51039
51146
  mkdirSync26(root2, { recursive: true });
51040
51147
  rmSync12(target, { recursive: true, force: true });
51041
51148
  cpSync2(source, target, { recursive: true });
@@ -51053,7 +51160,7 @@ async function resolvePackage(source, workDir) {
51053
51160
  throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
51054
51161
  }
51055
51162
  const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync61(source);
51056
- const root = workDir ?? mkdtempSync3(join53(tmpdir4(), "himi-run-"));
51163
+ const root = workDir ?? mkdtempSync3(join54(tmpdir4(), "himi-run-"));
51057
51164
  const { app, appDir: appDir2 } = unpackTo(bytes2, root);
51058
51165
  const opened = openPackageDir(appDir2);
51059
51166
  if (!opened.validation.ok) {
@@ -51074,11 +51181,11 @@ async function resolvePackage(source, workDir) {
51074
51181
  async function loadPreviewAssets() {
51075
51182
  try {
51076
51183
  const mod = await Promise.resolve().then(() => (init_preview_assets_generated(), preview_assets_generated_exports));
51077
- const here = dirname28(fileURLToPath22(import.meta.url));
51184
+ const here = dirname29(fileURLToPath22(import.meta.url));
51078
51185
  const candidates = [
51079
- join53(here, "preview-assets.generated.bin"),
51186
+ join54(here, "preview-assets.generated.bin"),
51080
51187
  // published: copied next to the bundled CLI
51081
- join53(here, "../../../packages/serve/src/preview-assets.generated.bin")
51188
+ join54(here, "../../../packages/serve/src/preview-assets.generated.bin")
51082
51189
  // in-repo checkout
51083
51190
  ];
51084
51191
  for (const path2 of candidates) {
@@ -51182,7 +51289,7 @@ __export(run_watch_exports, {
51182
51289
  });
51183
51290
  import { closeSync as closeSync2, constants, existsSync as existsSync56, fstatSync, lstatSync as lstatSync10, statSync as statSync14, mkdirSync as mkdirSync27, openSync as openSync2, readFileSync as readFileSync62, realpathSync as realpathSync7, renameSync as renameSync6, rmSync as rmSync13, writeFileSync as writeFileSync23, watch as fsWatch } from "node:fs";
51184
51291
  import { randomUUID as randomUUID3 } from "node:crypto";
51185
- import { extname as extname4, join as join54, resolve as resolve42, sep as sep13 } from "node:path";
51292
+ import { extname as extname4, join as join55, resolve as resolve42, sep as sep13 } from "node:path";
51186
51293
  function diffReleases(prev, next) {
51187
51294
  const bundles = Object.keys(next.bundles).filter((b) => prev.bundles[b]?.sha256 !== next.bundles[b].sha256).sort();
51188
51295
  const changedBundles = new Set(bundles);
@@ -51223,7 +51330,7 @@ function watchContent(dir, onChange, opts = {}) {
51223
51330
  let timer = null;
51224
51331
  const pending = /* @__PURE__ */ new Set();
51225
51332
  const watcher2 = watch2(dir, { recursive: true }, (_event, file) => {
51226
- if (!file || ignoredChange(file, (rel) => isDir(join54(dir, rel)))) return;
51333
+ if (!file || ignoredChange(file, (rel) => isDir(join55(dir, rel)))) return;
51227
51334
  pending.add(file);
51228
51335
  if (timer) clearTimeout(timer);
51229
51336
  timer = setTimeout(() => {
@@ -51244,7 +51351,7 @@ function watchedContentDir(source) {
51244
51351
  if (!source || /^https?:\/\//i.test(source)) return null;
51245
51352
  const dir = resolve42(source);
51246
51353
  try {
51247
- return statSync14(dir).isDirectory() && existsSync56(join54(dir, "himalaya.content.json")) ? dir : null;
51354
+ return statSync14(dir).isDirectory() && existsSync56(join55(dir, "himalaya.content.json")) ? dir : null;
51248
51355
  } catch {
51249
51356
  return null;
51250
51357
  }
@@ -51301,7 +51408,7 @@ function serialize(task) {
51301
51408
  });
51302
51409
  }
51303
51410
  function himiDir(dir) {
51304
- const root = join54(dir, ".himi");
51411
+ const root = join55(dir, ".himi");
51305
51412
  try {
51306
51413
  return lstatSync10(root).isDirectory() ? root : null;
51307
51414
  } catch (e) {
@@ -51313,11 +51420,11 @@ function himiDir(dir) {
51313
51420
  function writeRunRecord(dir, record2) {
51314
51421
  const root = himiDir(dir);
51315
51422
  if (!root) return false;
51316
- const tmp = join54(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
51423
+ const tmp = join55(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
51317
51424
  try {
51318
51425
  writeFileSync23(tmp, `${JSON.stringify(record2, null, 2)}
51319
51426
  `, { flag: "wx" });
51320
- renameSync6(tmp, join54(root, "run.json"));
51427
+ renameSync6(tmp, join55(root, "run.json"));
51321
51428
  } catch (e) {
51322
51429
  rmSync13(tmp, { force: true });
51323
51430
  throw e;
@@ -51325,7 +51432,7 @@ function writeRunRecord(dir, record2) {
51325
51432
  return true;
51326
51433
  }
51327
51434
  function removeRunRecord(dir, owner) {
51328
- const root = join54(dir, ".himi");
51435
+ const root = join55(dir, ".himi");
51329
51436
  try {
51330
51437
  if (!lstatSync10(root).isDirectory()) return;
51331
51438
  } catch {
@@ -51340,16 +51447,16 @@ function removeRunRecord(dir, owner) {
51340
51447
  }
51341
51448
  if (typeof pid === "number" && pid !== owner) return;
51342
51449
  }
51343
- rmSync13(join54(root, "run.json"), { force: true });
51450
+ rmSync13(join55(root, "run.json"), { force: true });
51344
51451
  }
51345
51452
  function boardFile(dir, pathname) {
51346
51453
  let rel = null;
51347
- if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join54("studio", "index.html");
51348
- else if (pathname === "/__himi/studio/state.js") rel = join54("studio", "state.js");
51349
- else if (pathname === "/__himi/studio/timeline.js") rel = join54("studio", "timeline.js");
51454
+ if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join55("studio", "index.html");
51455
+ else if (pathname === "/__himi/studio/state.js") rel = join55("studio", "state.js");
51456
+ else if (pathname === "/__himi/studio/timeline.js") rel = join55("studio", "timeline.js");
51350
51457
  else {
51351
51458
  const m = /^\/__himi\/history\/([0-9a-f]{64}\.(png|jpg|gif|webp))$/.exec(pathname);
51352
- if (m) rel = join54("history", m[1]);
51459
+ if (m) rel = join55("history", m[1]);
51353
51460
  }
51354
51461
  if (!rel) return null;
51355
51462
  const bytes2 = readConfined(resolve42(dir, ".himi"), rel);
@@ -51365,7 +51472,7 @@ function readConfined(root, rel) {
51365
51472
  const parts = rel.split(sep13);
51366
51473
  let at = root;
51367
51474
  for (let i = 0; i < parts.length; i++) {
51368
- at = join54(at, parts[i]);
51475
+ at = join55(at, parts[i]);
51369
51476
  const st = lstatSync10(at);
51370
51477
  if (st.isSymbolicLink() || !(i === parts.length - 1 ? st.isFile() : st.isDirectory())) return null;
51371
51478
  }
@@ -51428,7 +51535,7 @@ __export(run_browser_exports, {
51428
51535
  import { createServer as createServer5 } from "node:http";
51429
51536
  import { existsSync as existsSync57, readFileSync as readFileSync63 } from "node:fs";
51430
51537
  import { spawnSync as spawnSync3 } from "node:child_process";
51431
- import { dirname as dirname29, resolve as resolve43 } from "node:path";
51538
+ import { dirname as dirname30, resolve as resolve43 } from "node:path";
51432
51539
  import { fileURLToPath as fileURLToPath23 } from "node:url";
51433
51540
  function stagedDir() {
51434
51541
  return process.env.HIMI_BROWSER_PLANE_OUT ? resolve43(process.env.HIMI_BROWSER_PLANE_OUT) : resolve43(REPO, "packages", "serve", "dist", "browser-plane");
@@ -51570,7 +51677,7 @@ var init_run_browser = __esm({
51570
51677
  init_open_url();
51571
51678
  init_file_store();
51572
51679
  init_wix_client_id();
51573
- HERE = dirname29(fileURLToPath23(import.meta.url));
51680
+ HERE = dirname30(fileURLToPath23(import.meta.url));
51574
51681
  REPO = resolve43(HERE, "..", "..", "..");
51575
51682
  SERVED = /* @__PURE__ */ new Set(["host.html", "sw.js", "package-reader.js"]);
51576
51683
  }
@@ -51991,9 +52098,9 @@ __export(preflight_exports, {
51991
52098
  requireEnv: () => requireEnv
51992
52099
  });
51993
52100
  import { existsSync as existsSync58, readFileSync as readFileSync64 } from "node:fs";
51994
- import { isAbsolute as isAbsolute3, relative as relative9, resolve as resolve44 } from "node:path";
52101
+ import { isAbsolute as isAbsolute3, relative as relative10, resolve as resolve44 } from "node:path";
51995
52102
  function isInsideRepo(p) {
51996
- const rel = relative9(REPO_ROOT3, resolve44(p));
52103
+ const rel = relative10(REPO_ROOT3, resolve44(p));
51997
52104
  return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
51998
52105
  }
51999
52106
  function assertCredentialOutsideRepo(label2, p) {
@@ -52071,17 +52178,17 @@ __export(credential_profile_exports, {
52071
52178
  });
52072
52179
  import { existsSync as existsSync59, readFileSync as readFileSync65 } from "node:fs";
52073
52180
  import { homedir as homedir5 } from "node:os";
52074
- import { join as join55 } from "node:path";
52181
+ import { join as join56 } from "node:path";
52075
52182
  function credentialsDir(home = homedir5()) {
52076
- return join55(home, ".himalaya", "store-credentials");
52183
+ return join56(home, ".himalaya", "store-credentials");
52077
52184
  }
52078
52185
  function profilePath(name, home = homedir5()) {
52079
52186
  if (!PROFILE_NAME.test(name)) {
52080
52187
  throw new Error(
52081
- `credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join55(credentialsDir(home), "<name>.json")}; it is never a path.`
52188
+ `credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join56(credentialsDir(home), "<name>.json")}; it is never a path.`
52082
52189
  );
52083
52190
  }
52084
- return join55(credentialsDir(home), `${name}.json`);
52191
+ return join56(credentialsDir(home), `${name}.json`);
52085
52192
  }
52086
52193
  function parseProfile(text5, label2) {
52087
52194
  let doc;
@@ -52195,7 +52302,7 @@ __export(preflight_app_exports, {
52195
52302
  });
52196
52303
  import { readFileSync as readFileSync66, existsSync as existsSync60, readdirSync as readdirSync28, statSync as statSync15 } from "node:fs";
52197
52304
  import { createHash as createHash26 } from "node:crypto";
52198
- import { join as join56 } from "node:path";
52305
+ import { join as join57 } from "node:path";
52199
52306
  function analyze(projectYml, storeConfig, icon, account) {
52200
52307
  const f = [];
52201
52308
  const has = (re, s) => re.test(s);
@@ -52265,7 +52372,7 @@ async function preflightApp(app, opts = {}) {
52265
52372
  const findings = analyze(
52266
52373
  projectYml,
52267
52374
  storeConfig,
52268
- await appIconState(join56(appDir(app), "ios")),
52375
+ await appIconState(join57(appDir(app), "ios")),
52269
52376
  profileAccount(app, storeConfig, opts)
52270
52377
  );
52271
52378
  findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
@@ -52294,16 +52401,16 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
52294
52401
  return f;
52295
52402
  }
52296
52403
  function appLevelMetadataFiles(app, locale = "en-US") {
52297
- const root = join56(storeDir(app), "metadata");
52404
+ const root = join57(storeDir(app), "metadata");
52298
52405
  const out = /* @__PURE__ */ new Set();
52299
52406
  if (existsSync60(root)) {
52300
52407
  for (const n of readdirSync28(root)) if (n.endsWith(".txt")) out.add(n);
52301
52408
  }
52302
- if (existsSync60(join56(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
52409
+ if (existsSync60(join57(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
52303
52410
  return out;
52304
52411
  }
52305
52412
  function reviewInfoFiles(app) {
52306
- const dir = join56(storeDir(app), "review_information");
52413
+ const dir = join57(storeDir(app), "review_information");
52307
52414
  if (!existsSync60(dir)) return /* @__PURE__ */ new Set();
52308
52415
  return new Set(readdirSync28(dir).filter((n) => n.endsWith(".txt")));
52309
52416
  }
@@ -52414,10 +52521,10 @@ function analyzePlayListing(assets) {
52414
52521
  return f;
52415
52522
  }
52416
52523
  function playListingAssets(app, locale = "en-US") {
52417
- const dir = join56(storeDir(app), "play", locale, "images");
52524
+ const dir = join57(storeDir(app), "play", locale, "images");
52418
52525
  const read = (names) => {
52419
52526
  for (const name of names) {
52420
- const p = join56(dir, name);
52527
+ const p = join57(dir, name);
52421
52528
  try {
52422
52529
  if (statSync15(p).isFile()) return { name, bytes: readFileSync66(p) };
52423
52530
  } catch {
@@ -52450,26 +52557,26 @@ function analyzeListing(metaFiles, shots) {
52450
52557
  return f;
52451
52558
  }
52452
52559
  function metadataFilesPresent(app, locale = "en-US") {
52453
- const dir = join56(storeDir(app), "metadata", locale);
52560
+ const dir = join57(storeDir(app), "metadata", locale);
52454
52561
  if (!existsSync60(dir)) return /* @__PURE__ */ new Set();
52455
52562
  return new Set(readdirSync28(dir).filter((n) => n.endsWith(".txt")));
52456
52563
  }
52457
52564
  function listScreenshots(app, locale = "en-US") {
52458
52565
  const out = [];
52459
- const flat = join56(storeDir(app), "screenshots", locale);
52566
+ const flat = join57(storeDir(app), "screenshots", locale);
52460
52567
  if (existsSync60(flat)) {
52461
52568
  for (const png of readdirSync28(flat).filter((n) => n.endsWith(".png"))) {
52462
- const sz = pngSize(readFileSync66(join56(flat, png)));
52569
+ const sz = pngSize(readFileSync66(join57(flat, png)));
52463
52570
  if (sz) out.push({ name: png, w: sz.w, h: sz.h });
52464
52571
  }
52465
52572
  }
52466
- const legacy = join56(storeDir(app), "metadata", locale, "screenshots");
52573
+ const legacy = join57(storeDir(app), "metadata", locale, "screenshots");
52467
52574
  if (existsSync60(legacy)) {
52468
52575
  for (const deviceDir of readdirSync28(legacy)) {
52469
- const d = join56(legacy, deviceDir);
52576
+ const d = join57(legacy, deviceDir);
52470
52577
  if (!statSync15(d).isDirectory()) continue;
52471
52578
  for (const png of readdirSync28(d).filter((n) => n.endsWith(".png"))) {
52472
- const sz = pngSize(readFileSync66(join56(d, png)));
52579
+ const sz = pngSize(readFileSync66(join57(d, png)));
52473
52580
  if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
52474
52581
  }
52475
52582
  }
@@ -52477,10 +52584,10 @@ function listScreenshots(app, locale = "en-US") {
52477
52584
  return out;
52478
52585
  }
52479
52586
  function placeholderHashes2() {
52480
- const templateIos = join56(appDir("_template"), "ios");
52587
+ const templateIos = join57(appDir("_template"), "ios");
52481
52588
  if (!existsSync60(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
52482
52589
  for (const target of readdirSync28(templateIos)) {
52483
- const p = join56(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
52590
+ const p = join57(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
52484
52591
  try {
52485
52592
  if (!statSync15(p).isFile()) continue;
52486
52593
  return [LEGACY_PLACEHOLDER_SHA2562, createHash26("sha256").update(readFileSync66(p)).digest("hex")];
@@ -52516,7 +52623,7 @@ async function pixelIssues(bytes2) {
52516
52623
  async function appIconState(iosDir) {
52517
52624
  if (!existsSync60(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
52518
52625
  for (const target of readdirSync28(iosDir)) {
52519
- const p = join56(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
52626
+ const p = join57(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
52520
52627
  try {
52521
52628
  if (!statSync15(p).isFile()) continue;
52522
52629
  const bytes2 = readFileSync66(p);
@@ -52802,7 +52909,7 @@ var init_asc_status = __esm({
52802
52909
  // ../../core/functions-secrets/src/vault.ts
52803
52910
  import { createCipheriv, createDecipheriv, randomBytes as randomBytes5 } from "node:crypto";
52804
52911
  import { mkdir, readFile as readFile2, rename, writeFile as writeFile2 } from "node:fs/promises";
52805
- import { dirname as dirname30 } from "node:path";
52912
+ import { dirname as dirname31 } from "node:path";
52806
52913
  function createJsonSecretStore(filePath) {
52807
52914
  const read = async () => {
52808
52915
  try {
@@ -52815,7 +52922,7 @@ function createJsonSecretStore(filePath) {
52815
52922
  }
52816
52923
  };
52817
52924
  const write2 = async (records) => {
52818
- await mkdir(dirname30(filePath), { recursive: true });
52925
+ await mkdir(dirname31(filePath), { recursive: true });
52819
52926
  const temporary = `${filePath}.${process.pid}.tmp`;
52820
52927
  await writeFile2(temporary, `${JSON.stringify(records, null, 2)}
52821
52928
  `, { mode: 384 });
@@ -53011,9 +53118,9 @@ __export(notify_exports, {
53011
53118
  });
53012
53119
  import { chmodSync as chmodSync3, mkdirSync as mkdirSync28, readFileSync as readFileSync71, writeFileSync as writeFileSync25 } from "node:fs";
53013
53120
  import { homedir as homedir6 } from "node:os";
53014
- import { dirname as dirname31, join as join57 } from "node:path";
53121
+ import { dirname as dirname32, join as join58 } from "node:path";
53015
53122
  function defaultSessionsPath() {
53016
- return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join57(homedir6(), ".himalaya", "admin-sessions.json");
53123
+ return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join58(homedir6(), ".himalaya", "admin-sessions.json");
53017
53124
  }
53018
53125
  function loadSessionsFile(path2 = defaultSessionsPath()) {
53019
53126
  try {
@@ -53025,10 +53132,10 @@ function loadSessionsFile(path2 = defaultSessionsPath()) {
53025
53132
  function saveAdminSession(adminUrl, session, path2 = defaultSessionsPath()) {
53026
53133
  const file = loadSessionsFile(path2);
53027
53134
  file.sessions = { ...file.sessions, [adminUrl]: session };
53028
- mkdirSync28(dirname31(path2), { recursive: true, mode: 448 });
53135
+ mkdirSync28(dirname32(path2), { recursive: true, mode: 448 });
53029
53136
  writeFileSync25(path2, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
53030
53137
  try {
53031
- chmodSync3(dirname31(path2), 448);
53138
+ chmodSync3(dirname32(path2), 448);
53032
53139
  chmodSync3(path2, 384);
53033
53140
  } catch {
53034
53141
  }
@@ -56957,7 +57064,7 @@ var init_brand_font = __esm({
56957
57064
 
56958
57065
  // src/site-analyze/write-artifacts.ts
56959
57066
  import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync26 } from "node:fs";
56960
- import { join as join58 } from "node:path";
57067
+ import { join as join59 } from "node:path";
56961
57068
  function attachVeloSources(book, sources, put) {
56962
57069
  const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
56963
57070
  for (const f of book.velo.files) {
@@ -57112,12 +57219,12 @@ async function downloadMedia(book, fetchImpl, put) {
57112
57219
  }
57113
57220
  async function writeBusinessBook(result, opts) {
57114
57221
  const out = opts.outDir;
57115
- mkdirSync29(join58(out, "evidence/pages"), { recursive: true });
57116
- mkdirSync29(join58(out, "media/catalog"), { recursive: true });
57222
+ mkdirSync29(join59(out, "evidence/pages"), { recursive: true });
57223
+ mkdirSync29(join59(out, "media/catalog"), { recursive: true });
57117
57224
  const files = [];
57118
57225
  const put = (rel, body) => {
57119
- const p = join58(out, rel);
57120
- mkdirSync29(join58(p, ".."), { recursive: true });
57226
+ const p = join59(out, rel);
57227
+ mkdirSync29(join59(p, ".."), { recursive: true });
57121
57228
  writeFileSync26(p, body);
57122
57229
  files.push(rel);
57123
57230
  };
@@ -57212,7 +57319,7 @@ var init_customer_build = __esm({
57212
57319
 
57213
57320
  // src/site-analyze/apply.ts
57214
57321
  import { existsSync as existsSync61, readFileSync as readFileSync72, writeFileSync as writeFileSync27, copyFileSync as copyFileSync3, mkdirSync as mkdirSync30, realpathSync as realpathSync8, statSync as statSync16 } from "node:fs";
57215
- import { dirname as dirname32, isAbsolute as isAbsolute4, join as join59, resolve as resolve45, sep as sep14 } from "node:path";
57322
+ import { dirname as dirname33, isAbsolute as isAbsolute4, join as join60, resolve as resolve45, sep as sep14 } from "node:path";
57216
57323
  import { spawnSync as spawnSync4 } from "node:child_process";
57217
57324
  function unpairedRedirectNote(overlay) {
57218
57325
  if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
@@ -57227,8 +57334,8 @@ function committedShellProvisioning(path2) {
57227
57334
  function findRepoRoot(cwd) {
57228
57335
  let dir = cwd;
57229
57336
  for (let i = 0; i < 8; i++) {
57230
- if (SHELL_NAMES2.some((name) => existsSync61(join59(dir, shellAppDir(name), "package.json")))) return dir;
57231
- const next = dirname32(dir);
57337
+ if (SHELL_NAMES2.some((name) => existsSync61(join60(dir, shellAppDir(name), "package.json")))) return dir;
57338
+ const next = dirname33(dir);
57232
57339
  if (next === dir) break;
57233
57340
  dir = next;
57234
57341
  }
@@ -57296,7 +57403,7 @@ function mergeCustomerOwned(committed, overlay) {
57296
57403
  }
57297
57404
  function buildMergedContract(options) {
57298
57405
  const { appDir: appDir2, packageDir, overlay } = options;
57299
- const committedPath = join59(appDir2, "provisioning.json");
57406
+ const committedPath = join60(appDir2, "provisioning.json");
57300
57407
  if (!existsSync61(committedPath)) {
57301
57408
  throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
57302
57409
  }
@@ -57312,7 +57419,7 @@ function buildMergedContract(options) {
57312
57419
  };
57313
57420
  const stage = (fromRel, toRel) => {
57314
57421
  const from = contained(packageDir, fromRel);
57315
- const to = contained(join59(appDir2, STAGED), toRel.slice(STAGED.length + 1));
57422
+ const to = contained(join60(appDir2, STAGED), toRel.slice(STAGED.length + 1));
57316
57423
  if (!from || !to || !existsSync61(from)) return void 0;
57317
57424
  let real;
57318
57425
  let realRoot;
@@ -57325,7 +57432,7 @@ function buildMergedContract(options) {
57325
57432
  if (!real.startsWith(realRoot + sep14)) return void 0;
57326
57433
  try {
57327
57434
  if (!statSync16(real).isFile()) return void 0;
57328
- mkdirSync30(dirname32(to), { recursive: true });
57435
+ mkdirSync30(dirname33(to), { recursive: true });
57329
57436
  copyFileSync3(real, to);
57330
57437
  } catch {
57331
57438
  return void 0;
@@ -57335,7 +57442,7 @@ function buildMergedContract(options) {
57335
57442
  };
57336
57443
  const icon = stage("media/icon.png", `${STAGED}/icon.png`);
57337
57444
  if (icon) branding.appIconPath = icon;
57338
- const facesPath = join59(packageDir, "media/fonts/faces.json");
57445
+ const facesPath = join60(packageDir, "media/fonts/faces.json");
57339
57446
  if (existsSync61(facesPath)) {
57340
57447
  let faces = [];
57341
57448
  try {
@@ -57360,10 +57467,10 @@ function buildMergedContract(options) {
57360
57467
  merged.branding = branding;
57361
57468
  const body = `${JSON.stringify(merged, null, 2)}
57362
57469
  `;
57363
- const path2 = join59(packageDir, "provisioning.contract.json");
57470
+ const path2 = join60(packageDir, "provisioning.contract.json");
57364
57471
  writeFileSync27(path2, body);
57365
- const localPath = join59(appDir2, LOCAL_CONTRACT_REL);
57366
- mkdirSync30(dirname32(localPath), { recursive: true });
57472
+ const localPath = join60(appDir2, LOCAL_CONTRACT_REL);
57473
+ mkdirSync30(dirname33(localPath), { recursive: true });
57367
57474
  writeFileSync27(localPath, body);
57368
57475
  staged.push(localPath);
57369
57476
  return { path: path2, staged };
@@ -57397,7 +57504,7 @@ function catalogTypography(overlay, template) {
57397
57504
  function staticFaqFor(overlay, overlayPath) {
57398
57505
  const own3 = overlay.faq;
57399
57506
  if (own3 !== void 0) return deriveStaticFaq(own3);
57400
- const bookPath = join59(dirname32(resolve45(overlayPath)), "book.json");
57507
+ const bookPath = join60(dirname33(resolve45(overlayPath)), "book.json");
57401
57508
  if (!existsSync61(bookPath)) return void 0;
57402
57509
  try {
57403
57510
  const book = JSON.parse(readFileSync72(bookPath, "utf8"));
@@ -57427,8 +57534,8 @@ async function applyOverlays(input) {
57427
57534
  `shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
57428
57535
  );
57429
57536
  }
57430
- const appDir2 = join59(repoRoot2, shellAppDir(shell));
57431
- const packageDir = dirname32(resolve45(input.overlayPath));
57537
+ const appDir2 = join60(repoRoot2, shellAppDir(shell));
57538
+ const packageDir = dirname33(resolve45(input.overlayPath));
57432
57539
  const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
57433
57540
  wrote.push(...staged);
57434
57541
  const r = spawnSync4("npm", ["run", "prepare:customer", "--", "--contract", contract], {
@@ -57449,7 +57556,7 @@ async function applyOverlays(input) {
57449
57556
  note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
57450
57557
  };
57451
57558
  }
57452
- const pkgProv = join59(cwd, "provisioning.json");
57559
+ const pkgProv = join60(cwd, "provisioning.json");
57453
57560
  assertNotCommitted(pkgProv, input.forbiddenProvisioning);
57454
57561
  let packageFaq = faq;
57455
57562
  if (existsSync61(pkgProv)) {
@@ -57462,7 +57569,7 @@ async function applyOverlays(input) {
57462
57569
  writeFileSync27(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
57463
57570
  wrote.push(pkgProv);
57464
57571
  }
57465
- const pkgTokens = join59(cwd, "tokens.json");
57572
+ const pkgTokens = join60(cwd, "tokens.json");
57466
57573
  if (existsSync61(pkgTokens) && (tokens.colors || tokens.typography)) {
57467
57574
  const cur = JSON.parse(readFileSync72(pkgTokens, "utf8"));
57468
57575
  let tokensIn = tokens;
@@ -57489,7 +57596,7 @@ async function applyOverlays(input) {
57489
57596
  wrote.push(pkgTokens);
57490
57597
  }
57491
57598
  const homeAction = homeRefreshActionId(shell);
57492
- const homeSrc = join59(cwd, "dev/index.ts");
57599
+ const homeSrc = join60(cwd, "dev/index.ts");
57493
57600
  if (homeAction && existsSync61(homeSrc)) {
57494
57601
  const prev = readFileSync72(homeSrc, "utf8");
57495
57602
  const patched = patchBrandParams(prev, overlay, homeAction);
@@ -57523,7 +57630,7 @@ async function applyOverlays(input) {
57523
57630
  }
57524
57631
  }
57525
57632
  if (!input.iconPath || !existsSync61(input.iconPath)) {
57526
- const book = input.iconPath ? dirname32(dirname32(resolve45(input.iconPath))) : void 0;
57633
+ const book = input.iconPath ? dirname33(dirname33(resolve45(input.iconPath))) : void 0;
57527
57634
  notes.push(
57528
57635
  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"
57529
57636
  );
@@ -62899,7 +63006,7 @@ import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync75, mkdirSync
62899
63006
  import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
62900
63007
  import { createHash as createHash27, randomUUID as randomUUID5 } from "node:crypto";
62901
63008
  import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
62902
- import { join as join60, resolve as resolve47, relative as relative10, basename as basename14, dirname as dirname33 } from "node:path";
63009
+ import { join as join61, resolve as resolve47, relative as relative11, basename as basename15, dirname as dirname34 } from "node:path";
62903
63010
  import { fileURLToPath as fileURLToPath24 } from "node:url";
62904
63011
 
62905
63012
  // ../serve-cli/src/client.ts
@@ -66020,7 +66127,7 @@ var str6 = (v) => typeof v === "string" ? v : void 0;
66020
66127
  var num2 = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
66021
66128
  function embeddedTemplateCatalog() {
66022
66129
  return availableTemplates().map((name) => {
66023
- const path2 = join60(templateSourceDir(name), TEMPLATE_META_FILE);
66130
+ const path2 = join61(templateSourceDir(name), TEMPLATE_META_FILE);
66024
66131
  const meta = JSON.parse(readFileSync75(path2, "utf8"));
66025
66132
  if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
66026
66133
  throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
@@ -66824,9 +66931,9 @@ function packageVersion(path2) {
66824
66931
  function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
66825
66932
  let dir = resolve47(fromDir);
66826
66933
  for (; ; ) {
66827
- const version2 = packageVersion(join60(dir, "node_modules", "@wix", "himalaya", "package.json"));
66934
+ const version2 = packageVersion(join61(dir, "node_modules", "@wix", "himalaya", "package.json"));
66828
66935
  if (version2) return { version: version2, source: "local" };
66829
- const parent = dirname33(dir);
66936
+ const parent = dirname34(dir);
66830
66937
  if (parent === dir) break;
66831
66938
  dir = parent;
66832
66939
  }
@@ -66834,7 +66941,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
66834
66941
  if (bundled) return { version: bundled, source: "bundled" };
66835
66942
  try {
66836
66943
  const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
66837
- const version2 = root ? packageVersion(join60(root, "@wix", "himalaya", "package.json")) : void 0;
66944
+ const version2 = root ? packageVersion(join61(root, "@wix", "himalaya", "package.json")) : void 0;
66838
66945
  return version2 ? { version: version2, source: "global" } : {};
66839
66946
  } catch {
66840
66947
  return {};
@@ -66881,7 +66988,7 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
66881
66988
  var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
66882
66989
  var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
66883
66990
  function updateCachePath(env = process.env) {
66884
- return env.HIMI_UPDATE_CACHE_FILE ?? join60(homedir7(), ".himalaya", "update-check.json");
66991
+ return env.HIMI_UPDATE_CACHE_FILE ?? join61(homedir7(), ".himalaya", "update-check.json");
66885
66992
  }
66886
66993
  function readUpdateCache(path2) {
66887
66994
  try {
@@ -66893,7 +67000,7 @@ function readUpdateCache(path2) {
66893
67000
  }
66894
67001
  function writeUpdateCache(path2, cache) {
66895
67002
  try {
66896
- mkdirSync31(dirname33(path2), { recursive: true, mode: 448 });
67003
+ mkdirSync31(dirname34(path2), { recursive: true, mode: 448 });
66897
67004
  writeFileSync29(path2, JSON.stringify(cache, null, 2) + "\n", { mode: 384 });
66898
67005
  } catch {
66899
67006
  }
@@ -66953,11 +67060,11 @@ function createUpdateRunner(spawn7 = spawnSync5) {
66953
67060
  },
66954
67061
  installedVersion: () => {
66955
67062
  const root = globalNodeModulesRoot();
66956
- return root ? packageVersion(join60(root, "@wix", "himalaya-cli", "package.json")) : void 0;
67063
+ return root ? packageVersion(join61(root, "@wix", "himalaya-cli", "package.json")) : void 0;
66957
67064
  },
66958
67065
  reexec: (argv) => {
66959
67066
  const root = globalNodeModulesRoot();
66960
- const entry = root ? join60(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
67067
+ const entry = root ? join61(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
66961
67068
  if (!entry || !existsSync63(entry)) return void 0;
66962
67069
  const result = spawnSync5(process.execPath, [entry, ...argv], {
66963
67070
  // inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
@@ -67049,7 +67156,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
67049
67156
  };
67050
67157
  const release = () => removeIfMine(lockPath);
67051
67158
  try {
67052
- mkdirSync31(dirname33(lockPath), { recursive: true, mode: 448 });
67159
+ mkdirSync31(dirname34(lockPath), { recursive: true, mode: 448 });
67053
67160
  } catch {
67054
67161
  return () => {
67055
67162
  };
@@ -67612,7 +67719,7 @@ function executableOnPath(name, env = process.env) {
67612
67719
  const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
67613
67720
  for (const dir of entries) {
67614
67721
  for (const suffix of suffixes) {
67615
- const candidate = join60(dir, `${name}${suffix}`);
67722
+ const candidate = join61(dir, `${name}${suffix}`);
67616
67723
  try {
67617
67724
  if (!statSync17(candidate).isFile()) continue;
67618
67725
  if (process.platform !== "win32") accessSync(candidate, constants2.X_OK);
@@ -67735,13 +67842,13 @@ async function nativeConfigAdvisories(app, configSource) {
67735
67842
  }
67736
67843
  function readConfigSource(dir) {
67737
67844
  try {
67738
- return readFileSync75(join60(dir, "config.ts"), "utf8");
67845
+ return readFileSync75(join61(dir, "config.ts"), "utf8");
67739
67846
  } catch {
67740
67847
  return null;
67741
67848
  }
67742
67849
  }
67743
67850
  function writePngFile(path2, base64) {
67744
- mkdirSync31(dirname33(path2), { recursive: true });
67851
+ mkdirSync31(dirname34(path2), { recursive: true });
67745
67852
  writeFileSync29(path2, Buffer.from(base64, "base64"));
67746
67853
  return path2;
67747
67854
  }
@@ -67771,7 +67878,7 @@ function keptPlan(kept) {
67771
67878
  }
67772
67879
  async function initFromRemoteTemplate(name, parentDir, template, c) {
67773
67880
  const dir = resolve47(parentDir, name);
67774
- if (existsSync63(join60(dir, "himalaya.content.json"))) {
67881
+ if (existsSync63(join61(dir, "himalaya.content.json"))) {
67775
67882
  throw new Error(`content package already exists at ${dir}`);
67776
67883
  }
67777
67884
  const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
@@ -67829,8 +67936,8 @@ function restoreDestinationIssue(dest, force) {
67829
67936
  function isHimalayaMonorepoCheckout(start) {
67830
67937
  let dir = resolve47(start);
67831
67938
  for (; ; ) {
67832
- if (existsSync63(join60(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync63(join60(dir, "core", "serve", "src", "server.ts"))) return true;
67833
- const parent = dirname33(dir);
67939
+ if (existsSync63(join61(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync63(join61(dir, "core", "serve", "src", "server.ts"))) return true;
67940
+ const parent = dirname34(dir);
67834
67941
  if (parent === dir) return false;
67835
67942
  dir = parent;
67836
67943
  }
@@ -67867,7 +67974,7 @@ function shellShaDivergenceWarnings(jobs) {
67867
67974
  }
67868
67975
  async function templatePublishName(sourceDir) {
67869
67976
  const id = await appId(sourceDir);
67870
- return IDENTITY_SENTINELS.some((s) => id.includes(s)) ? basename14(sourceDir) : id;
67977
+ return IDENTITY_SENTINELS.some((s) => id.includes(s)) ? basename15(sourceDir) : id;
67871
67978
  }
67872
67979
  function templateNameError(name, from) {
67873
67980
  if (name.startsWith(TEMPLATE_APP_PREFIX)) {
@@ -67890,7 +67997,7 @@ function materializeForPreview(appDir2, slug, displayName) {
67890
67997
  Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
67891
67998
  );
67892
67999
  const repoRoot2 = resolve47(fileURLToPath24(new URL("../../..", import.meta.url)));
67893
- const root = join60(repoRoot2, "node_modules", ".cache", "himi-template-preview");
68000
+ const root = join61(repoRoot2, "node_modules", ".cache", "himi-template-preview");
67894
68001
  const stillRunning = (pid) => {
67895
68002
  try {
67896
68003
  process.kill(pid, 0);
@@ -67904,12 +68011,12 @@ function materializeForPreview(appDir2, slug, displayName) {
67904
68011
  if (!entry.isDirectory()) continue;
67905
68012
  const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
67906
68013
  if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
67907
- rmSync14(join60(root, entry.name), { recursive: true, force: true });
68014
+ rmSync14(join61(root, entry.name), { recursive: true, force: true });
67908
68015
  }
67909
68016
  }
67910
68017
  } catch {
67911
68018
  }
67912
- const dest = join60(root, `${slug}-${process.pid}`);
68019
+ const dest = join61(root, `${slug}-${process.pid}`);
67913
68020
  rmSync14(dest, { recursive: true, force: true });
67914
68021
  mkdirSync31(dest, { recursive: true });
67915
68022
  try {
@@ -67923,16 +68030,16 @@ function materializeForPreview(appDir2, slug, displayName) {
67923
68030
  async function appId(dir) {
67924
68031
  try {
67925
68032
  const { readFileSync: readFileSync76 } = await import("node:fs");
67926
- const m = JSON.parse(readFileSync76(join60(dir, "himalaya.content.json"), "utf8"));
68033
+ const m = JSON.parse(readFileSync76(join61(dir, "himalaya.content.json"), "utf8"));
67927
68034
  if (m.name) return m.name;
67928
68035
  } catch {
67929
68036
  }
67930
- return basename14(dir);
68037
+ return basename15(dir);
67931
68038
  }
67932
68039
  async function contentVisibility(dir) {
67933
68040
  try {
67934
68041
  const { readFileSync: readFileSync76 } = await import("node:fs");
67935
- const m = JSON.parse(readFileSync76(join60(dir, "himalaya.content.json"), "utf8"));
68042
+ const m = JSON.parse(readFileSync76(join61(dir, "himalaya.content.json"), "utf8"));
67936
68043
  if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
67937
68044
  } catch {
67938
68045
  }
@@ -68156,7 +68263,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
68156
68263
  ...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/" } : {},
68157
68264
  // In a git repo the refresh moves the diff identity an earlier `himi test` attested (that
68158
68265
  // hash is shared with the repo gates and deliberately exempts nothing but its own metadata).
68159
- ...existsSync63(join60(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" } : {},
68266
+ ...existsSync63(join61(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" } : {},
68160
68267
  ...res.skipped.length ? { skipped: res.skipped } : {},
68161
68268
  portalUrl: idx.portalUrl
68162
68269
  });
@@ -68179,7 +68286,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
68179
68286
  try {
68180
68287
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
68181
68288
  const bres = await buildContentForValidation2(dir, { resolution });
68182
- out = mkdtempSync4(join60(tmpdir5(), "himi-ux-record-"));
68289
+ out = mkdtempSync4(join61(tmpdir5(), "himi-ux-record-"));
68183
68290
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
68184
68291
  const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
68185
68292
  const releaseId = outcome.manifest.releaseId;
@@ -68357,7 +68464,7 @@ async function producedWidgetFamilies(dir) {
68357
68464
  let js;
68358
68465
  for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
68359
68466
  try {
68360
- js = readFileSync75(join60(outDir, candidate), "utf8");
68467
+ js = readFileSync75(join61(outDir, candidate), "utf8");
68361
68468
  break;
68362
68469
  } catch {
68363
68470
  }
@@ -68388,7 +68495,7 @@ async function producedWidgetFamilies(dir) {
68388
68495
  }
68389
68496
  return { families, source: "dist/bundles" };
68390
68497
  }
68391
- var boardOpen = (dir) => existsSync63(join60(dir, ".himi", "studio", "index.html"));
68498
+ var boardOpen = (dir) => existsSync63(join61(dir, ".himi", "studio", "index.html"));
68392
68499
  var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
68393
68500
  async function leaveForBoard(dir, record2, value) {
68394
68501
  if (!boardOpen(dir)) return;
@@ -68668,7 +68775,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
68668
68775
  const owed = openApprovals2(readApprovals2(dir).events).length;
68669
68776
  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`);
68670
68777
  }
68671
- const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f) => existsSync63(join60(parentDir, f)));
68778
+ const planInParent = ["SPEC.md", "MOBILE-UX.md"].filter((f) => existsSync63(join61(parentDir, f)));
68672
68779
  if (planInParent.length) {
68673
68780
  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}`);
68674
68781
  }
@@ -68795,7 +68902,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
68795
68902
  const sourceDir = resolve47(str6(flags["source-dir"]) ?? appDir2);
68796
68903
  let meta;
68797
68904
  try {
68798
- meta = JSON.parse(readFileSync75(join60(sourceDir, TEMPLATE_META_FILE), "utf8"));
68905
+ meta = JSON.parse(readFileSync75(join61(sourceDir, TEMPLATE_META_FILE), "utf8"));
68799
68906
  } catch {
68800
68907
  io.error(JSON.stringify({ error: `no ${TEMPLATE_META_FILE} in ${sourceDir} \u2014 a template must declare { title, description, tags } to be published`, hint: `add ${TEMPLATE_META_FILE} next to himalaya.content.json (or pass --source-dir <dir>)` }));
68801
68908
  return 2;
@@ -68805,7 +68912,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
68805
68912
  return 2;
68806
68913
  }
68807
68914
  try {
68808
- const appearance = extractTemplateAppearance(JSON.parse(readFileSync75(join60(sourceDir, "tokens.json"), "utf8")));
68915
+ const appearance = extractTemplateAppearance(JSON.parse(readFileSync75(join61(sourceDir, "tokens.json"), "utf8")));
68809
68916
  meta = { ...appearance, ...meta };
68810
68917
  } catch {
68811
68918
  }
@@ -68827,7 +68934,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
68827
68934
  const force = flags.force === true;
68828
68935
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
68829
68936
  const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
68830
- const out = mkdtempSync4(join60(tmpdir5(), "himi-template-"));
68937
+ const out = mkdtempSync4(join61(tmpdir5(), "himi-template-"));
68831
68938
  publishScratch.push(out);
68832
68939
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
68833
68940
  const outcome = await buildReleaseFromContent2(buildDir, out, {
@@ -69123,7 +69230,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69123
69230
  const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
69124
69231
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
69125
69232
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
69126
- const out = mkdtempSync4(join60(tmpdir5(), "himi-validate-"));
69233
+ const out = mkdtempSync4(join61(tmpdir5(), "himi-validate-"));
69127
69234
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
69128
69235
  const outcome = await buildReleaseFromContent2(dir, out, {
69129
69236
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -69286,15 +69393,15 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69286
69393
  case "studio": {
69287
69394
  const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
69288
69395
  const dir = contentDir(flags);
69289
- if (!existsSync63(join60(dir, "himalaya.content.json"))) {
69396
+ if (!existsSync63(join61(dir, "himalaya.content.json"))) {
69290
69397
  io.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/" }));
69291
69398
  return 2;
69292
69399
  }
69293
69400
  if (pos[1] === "reel") {
69294
69401
  const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
69295
- const out = resolve47(str6(flags.out) ?? join60(dir, ".himi", "making-of.html"));
69402
+ const out = resolve47(str6(flags.out) ?? join61(dir, ".himi", "making-of.html"));
69296
69403
  const { html, plan } = buildReel2(dir);
69297
- mkdirSync31(dirname33(out), { recursive: true });
69404
+ mkdirSync31(dirname34(out), { recursive: true });
69298
69405
  writeFileSync29(out, html);
69299
69406
  const { pathToFileURL: pathToFileURL9 } = await import("node:url");
69300
69407
  const url2 = pathToFileURL9(out).href;
@@ -69359,7 +69466,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69359
69466
  } = await Promise.resolve().then(() => (init_progress(), progress_exports));
69360
69467
  const dir = contentDir(flags);
69361
69468
  const journal = journalPath2(dir);
69362
- const isContentPackage = existsSync63(join60(dir, "himalaya.content.json"));
69469
+ const isContentPackage = existsSync63(join61(dir, "himalaya.content.json"));
69363
69470
  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" };
69364
69471
  const message = pos.slice(1).join(" ").trim();
69365
69472
  const approvalFlags = ["approve", "done", "drop"].filter((f) => flags[f] !== void 0);
@@ -69495,7 +69602,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69495
69602
  case "test": {
69496
69603
  const dir = contentDir(flags);
69497
69604
  const structuredOutput = flags.json === true || io.isTTY !== true;
69498
- if (existsSync63(join60(dir, "functions"))) {
69605
+ if (existsSync63(join61(dir, "functions"))) {
69499
69606
  const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
69500
69607
  const loaded = await loadFunctionsApp2(dir);
69501
69608
  const results = [];
@@ -69582,7 +69689,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69582
69689
  }
69583
69690
  }
69584
69691
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
69585
- const out = mkdtempSync4(join60(tmpdir5(), "himi-test-"));
69692
+ const out = mkdtempSync4(join61(tmpdir5(), "himi-test-"));
69586
69693
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
69587
69694
  const outcome = await buildReleaseFromContent2(dir, out, {
69588
69695
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -69627,7 +69734,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69627
69734
  io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
69628
69735
  return 2;
69629
69736
  }
69630
- const sources = collectWorkerSources2(join60(dir, "tier5-src"), screen.bundleName);
69737
+ const sources = collectWorkerSources2(join61(dir, "tier5-src"), screen.bundleName);
69631
69738
  if (!sources) {
69632
69739
  io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
69633
69740
  return 2;
@@ -69788,7 +69895,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69788
69895
  const sp = await runShotsPass2({
69789
69896
  descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
69790
69897
  tokens: outcome.tokens,
69791
- outDir: join60(dir, ".himi", "shots"),
69898
+ outDir: join61(dir, ".himi", "shots"),
69792
69899
  width: 390,
69793
69900
  layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
69794
69901
  ...budgetMs ? { budgetMs } : {},
@@ -69826,7 +69933,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69826
69933
  releaseId: result.releaseId,
69827
69934
  releasePayload: release,
69828
69935
  descriptors: attestedDescriptors,
69829
- screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join60(dir, ".himi", "shots", name)])),
69936
+ screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join61(dir, ".himi", "shots", name)])),
69830
69937
  coverage: {
69831
69938
  screens: crawledScreens.size,
69832
69939
  actionsDispatched: result.actions.exercised,
@@ -69980,7 +70087,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69980
70087
  }
69981
70088
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
69982
70089
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
69983
- const out = mkdtempSync4(join60(tmpdir5(), "himi-render-"));
70090
+ const out = mkdtempSync4(join61(tmpdir5(), "himi-render-"));
69984
70091
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
69985
70092
  const outcome = await buildReleaseFromContent2(dir, out, {
69986
70093
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -69994,7 +70101,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
69994
70101
  const diagnostics = (outcome.lint ?? []).find((s) => s.screenId === screenId)?.issues ?? [];
69995
70102
  let pngFile;
69996
70103
  let attestationPngFile;
69997
- const shotPath = join60(dir, ".himi", "shots", `${screenId}.png`);
70104
+ const shotPath = join61(dir, ".himi", "shots", `${screenId}.png`);
69998
70105
  const pngTarget = typeof flags.png === "string" ? str6(flags.png) : flags.png === true ? shotPath : void 0;
69999
70106
  if (pngTarget && r.pngBase64) {
70000
70107
  pngFile = writePngFile(pngTarget, r.pngBase64);
@@ -70343,7 +70450,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
70343
70450
  io.error(JSON.stringify({ error: `${dest} already exists and is not empty`, hint: "pass --force to write into it anyway (merging, and naming what it keeps), --replace to restore exactly what was archived, or --out/--name to land somewhere else" }));
70344
70451
  return 1;
70345
70452
  }
70346
- if (replace && occupied && !existsSync63(join60(dest, "himalaya.content.json"))) {
70453
+ if (replace && occupied && !existsSync63(join61(dest, "himalaya.content.json"))) {
70347
70454
  io.error(JSON.stringify({
70348
70455
  error: `${dest} is not a content package \u2014 refusing to --replace it`,
70349
70456
  hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
@@ -70484,7 +70591,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
70484
70591
  const force = flags.force === true;
70485
70592
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
70486
70593
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
70487
- const out = mkdtempSync4(join60(tmpdir5(), "himi-push-"));
70594
+ const out = mkdtempSync4(join61(tmpdir5(), "himi-push-"));
70488
70595
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
70489
70596
  const outcome = await buildReleaseFromContent2(dir, out, {
70490
70597
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -70510,7 +70617,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
70510
70617
  const manifest = outcome.manifest;
70511
70618
  const payload = await loadReleaseFromDir(declared, out);
70512
70619
  const { shellQuote: shellQuote2 } = await Promise.resolve().then(() => (init_shell_quote(), shell_quote_exports));
70513
- const contentRel = relative10(process.cwd(), dir) || ".";
70620
+ const contentRel = relative11(process.cwd(), dir) || ".";
70514
70621
  const contentArg = shellQuote2(contentRel);
70515
70622
  if (onlyRaw !== void 0) {
70516
70623
  const onlyDraft = flags.draft === true;
@@ -71005,7 +71112,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71005
71112
  }
71006
71113
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
71007
71114
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
71008
- const built = mkdtempSync4(join60(tmpdir5(), "himi-pack-"));
71115
+ const built = mkdtempSync4(join61(tmpdir5(), "himi-pack-"));
71009
71116
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
71010
71117
  const outcome = await buildReleaseFromContent2(dir, built, {
71011
71118
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -71264,11 +71371,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71264
71371
  const app = await appId(dir2);
71265
71372
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
71266
71373
  const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
71267
- temp = mkdtempSync4(join60(tmpdir5(), "himi-run-build-"));
71374
+ temp = mkdtempSync4(join61(tmpdir5(), "himi-run-build-"));
71268
71375
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
71269
71376
  const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
71270
71377
  servedMissing = initial.missingBundles;
71271
- source = join60(temp, app);
71378
+ source = join61(temp, app);
71272
71379
  }
71273
71380
  const chromeArg = str6(flags.chrome) ?? "preview";
71274
71381
  if (chromeArg !== "preview" && chromeArg !== "app") {
@@ -71304,7 +71411,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71304
71411
  if (!recordKit) return;
71305
71412
  startedAt = (/* @__PURE__ */ new Date()).toISOString();
71306
71413
  const failure = record2(served2, { ok: true, at: startedAt });
71307
- if (!recorded) io.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${join60(dir, ".himi")} is not a real directory`}, so the build board will not frame this preview.` }));
71414
+ if (!recorded) io.error(JSON.stringify({ run: "run_record_skipped", message: `${failure ?? `${join61(dir, ".himi")} is not a real directory`}, so the build board will not frame this preview.` }));
71308
71415
  await refreshBoard();
71309
71416
  };
71310
71417
  const retract = async () => {
@@ -71335,7 +71442,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71335
71442
  }
71336
71443
  const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
71337
71444
  const bus = watchKit ? new watchKit.ReloadBus() : void 0;
71338
- if (watch2) served = mkdtempSync4(join60(tmpdir5(), "himi-run-served-"));
71445
+ if (watch2) served = mkdtempSync4(join61(tmpdir5(), "himi-run-served-"));
71339
71446
  const running = await runPackage2(source, {
71340
71447
  port,
71341
71448
  chrome: chromeArg,
@@ -71356,8 +71463,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71356
71463
  await announce(running);
71357
71464
  if (watchKit && bus) {
71358
71465
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
71359
- const live2 = join60(running.releaseRoot, running.app);
71360
- const manifestOf = (tree) => JSON.parse(readFileSync75(join60(tree, "release-manifest.json"), "utf8"));
71466
+ const live2 = join61(running.releaseRoot, running.app);
71467
+ const manifestOf = (tree) => JSON.parse(readFileSync75(join61(tree, "release-manifest.json"), "utf8"));
71361
71468
  let current = manifestOf(live2);
71362
71469
  const failed2 = async (message) => {
71363
71470
  if (stopping) return;
@@ -71368,7 +71475,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71368
71475
  };
71369
71476
  rebuild = watchKit.serialize(async () => {
71370
71477
  const t0 = Date.now();
71371
- const next = mkdtempSync4(join60(tmpdir5(), "himi-run-build-"));
71478
+ const next = mkdtempSync4(join61(tmpdir5(), "himi-run-build-"));
71372
71479
  try {
71373
71480
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
71374
71481
  if (bres.compileErrors.length) {
@@ -71385,14 +71492,14 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
71385
71492
  return;
71386
71493
  }
71387
71494
  if (stopping) return;
71388
- const fresh = manifestOf(join60(next, running.app));
71495
+ const fresh = manifestOf(join61(next, running.app));
71389
71496
  const diff = watchKit.diffReleases(current, fresh);
71390
71497
  const retired = `${live2}.retired-${Date.now()}`;
71391
71498
  renameSync7(live2, retired);
71392
71499
  try {
71393
- renameSync7(join60(next, running.app), live2);
71500
+ renameSync7(join61(next, running.app), live2);
71394
71501
  } catch {
71395
- cpSync3(join60(next, running.app), live2, { recursive: true });
71502
+ cpSync3(join61(next, running.app), live2, { recursive: true });
71396
71503
  }
71397
71504
  rmSync14(retired, { recursive: true, force: true });
71398
71505
  current = fresh;
@@ -72709,7 +72816,7 @@ ${label2}`);
72709
72816
  const platform = str6(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
72710
72817
  {
72711
72818
  const distDir = contentDir(flags);
72712
- if (existsSync63(join60(distDir, "himalaya.content.json"))) {
72819
+ if (existsSync63(join61(distDir, "himalaya.content.json"))) {
72713
72820
  const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
72714
72821
  const errors = issues.filter((i) => i.severity === "error");
72715
72822
  for (const i of issues.filter((i2) => i2.severity === "warning")) {