@wix/himalaya-cli 0.1015.0 → 0.1016.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.
Files changed (89) hide show
  1. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/dev-server/src/builder.d.ts +67 -1
  2. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/state/src/index.d.ts +45 -3
  3. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/define-app.d.ts +18 -0
  4. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/ts/src/schema.d.ts +7 -0
  5. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/genie-chat/src/index.d.ts +51 -0
  6. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/core.mjs +21 -0
  7. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/sdui.mjs +79 -6
  8. package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-genie-chat.mjs +23 -0
  9. package/dist/cli.mjs +1225 -645
  10. package/dist/preview-assets.generated.bin +0 -0
  11. package/guides/component-reference.json +1 -1
  12. package/guides/component-reference.md +25 -9
  13. package/guides/designing-himi-screens.md +6 -4
  14. package/guides/headless-loop.md +1 -0
  15. package/guides/sdk-reference.json +47 -5
  16. package/guides/tier-5-add-a-screen.md +40 -13
  17. package/guides/wix-api-usage.md +9 -0
  18. package/package.json +2 -2
  19. package/templates/beauty-salon/dev/index.ts +252 -7
  20. package/templates/beauty-salon/tier5-src/himi-booking-bookings/index.ts +5 -2
  21. package/templates/beauty-salon-owner/config.ts +1 -1
  22. package/templates/beauty-salon-owner/dev/index.ts +419 -2
  23. package/templates/beauty-salon-owner/tier5-src/_shared/aria-chat.ts +226 -9
  24. package/templates/beauty-salon-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  25. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  26. package/templates/branded-lite/dev/index.ts +487 -14
  27. package/templates/branded-lite/tier5-src/himi-booking-bookings/index.ts +5 -2
  28. package/templates/community-club/dev/index.ts +196 -13
  29. package/templates/community-club-owner/config.ts +1 -1
  30. package/templates/community-club-owner/dev/index.ts +402 -2
  31. package/templates/community-club-owner/tier5-src/_shared/aria-chat.ts +226 -9
  32. package/templates/community-club-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  33. package/templates/community-club-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  34. package/templates/events-meetups/dev/index.ts +196 -13
  35. package/templates/events-meetups-owner/config.ts +1 -1
  36. package/templates/events-meetups-owner/dev/index.ts +348 -2
  37. package/templates/events-meetups-owner/tier5-src/_shared/aria-chat.ts +226 -9
  38. package/templates/events-meetups-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  39. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  40. package/templates/gym-fitness/dev/index.ts +324 -12
  41. package/templates/gym-fitness/tier5-src/himi-booking-bookings/index.ts +5 -2
  42. package/templates/gym-fitness-owner/config.ts +1 -1
  43. package/templates/gym-fitness-owner/dev/index.ts +440 -2
  44. package/templates/gym-fitness-owner/tier5-src/_shared/aria-chat.ts +226 -9
  45. package/templates/gym-fitness-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  46. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  47. package/templates/himi-chat/dev/index.ts +2 -2
  48. package/templates/nonprofit-cause/dev/index.ts +212 -13
  49. package/templates/nonprofit-cause-owner/config.ts +1 -1
  50. package/templates/nonprofit-cause-owner/dev/index.ts +386 -2
  51. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-chat.ts +226 -9
  52. package/templates/nonprofit-cause-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  53. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  54. package/templates/owner-lite/config.ts +1 -1
  55. package/templates/owner-lite/dev/index.ts +446 -2
  56. package/templates/owner-lite/tier5-src/_shared/aria-chat.ts +226 -9
  57. package/templates/owner-lite/tier5-src/_shared/aria-client-tools.ts +234 -0
  58. package/templates/owner-lite/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  59. package/templates/podcast-creator/dev/index.ts +206 -13
  60. package/templates/podcast-creator-owner/config.ts +1 -1
  61. package/templates/podcast-creator-owner/dev/index.ts +402 -2
  62. package/templates/podcast-creator-owner/tier5-src/_shared/aria-chat.ts +226 -9
  63. package/templates/podcast-creator-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  64. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  65. package/templates/portfolio-creative/dev/index.ts +249 -11
  66. package/templates/portfolio-creative-owner/config.ts +1 -1
  67. package/templates/portfolio-creative-owner/dev/index.ts +419 -2
  68. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-chat.ts +226 -9
  69. package/templates/portfolio-creative-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  70. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  71. package/templates/restaurant/dev/index.ts +219 -11
  72. package/templates/restaurant-owner/config.ts +1 -1
  73. package/templates/restaurant-owner/dev/index.ts +440 -2
  74. package/templates/restaurant-owner/tier5-src/_shared/aria-chat.ts +226 -9
  75. package/templates/restaurant-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  76. package/templates/restaurant-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  77. package/templates/retail-store/dev/index.ts +159 -6
  78. package/templates/retail-store-owner/config.ts +1 -1
  79. package/templates/retail-store-owner/dev/index.ts +381 -2
  80. package/templates/retail-store-owner/tier5-src/_shared/aria-chat.ts +226 -9
  81. package/templates/retail-store-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  82. package/templates/retail-store-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
  83. package/templates/yoga-studio/dev/index.ts +284 -12
  84. package/templates/yoga-studio/tier5-src/himi-booking-bookings/index.ts +5 -2
  85. package/templates/yoga-studio-owner/config.ts +1 -1
  86. package/templates/yoga-studio-owner/dev/index.ts +386 -2
  87. package/templates/yoga-studio-owner/tier5-src/_shared/aria-chat.ts +226 -9
  88. package/templates/yoga-studio-owner/tier5-src/_shared/aria-client-tools.ts +234 -0
  89. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-aria/index.ts +40 -0
package/dist/cli.mjs CHANGED
@@ -5345,6 +5345,7 @@ function walk(node, registry, path2, out) {
5345
5345
  var SYSTEM_FONT_FAMILY;
5346
5346
  var init_tokens = __esm({
5347
5347
  "../../core/ts/src/tokens.ts"() {
5348
+ "use strict";
5348
5349
  SYSTEM_FONT_FAMILY = "$system";
5349
5350
  }
5350
5351
  });
@@ -6516,6 +6517,260 @@ var init_l10n_strings = __esm({
6516
6517
  }
6517
6518
  });
6518
6519
 
6520
+ // ../../core/dev-server/src/a11y-contract.ts
6521
+ function isDynamicValue(v) {
6522
+ return typeof v === "string" && (v.startsWith("$service:") || v.startsWith("$item") || v.startsWith("$flag") || v.startsWith("$state") || v.startsWith("$t:"));
6523
+ }
6524
+ function isActionEnvelope(v) {
6525
+ return !!v && typeof v === "object" && !Array.isArray(v) && typeof v.actionId === "string";
6526
+ }
6527
+ function own(bag, key2) {
6528
+ return Object.prototype.hasOwnProperty.call(bag, key2) ? bag[key2] : void 0;
6529
+ }
6530
+ function atExposureOf(node) {
6531
+ const mods = node.modifiers;
6532
+ if (!mods || typeof mods !== "object" || Array.isArray(mods)) return "exposed";
6533
+ const m = mods;
6534
+ if (m.accessibilityHidden === true) return "hidden";
6535
+ if (m.accessibilityRole === "decorative" && !isInteractive(node)) return "decorative";
6536
+ return "exposed";
6537
+ }
6538
+ function isInteractive(node) {
6539
+ const raw = node.modifiers;
6540
+ const mods = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
6541
+ return TAP_MODIFIER_KEYS.some(
6542
+ (k) => !!mods[k] && typeof mods[k] === "object" || !!node[k] && typeof node[k] === "object"
6543
+ );
6544
+ }
6545
+ function ownName(n) {
6546
+ for (const k of ACCESSIBLE_NAME_KEYS) {
6547
+ const v = own(n, k);
6548
+ if (typeof v === "string" && v.trim() !== "" || isDynamicValue(v)) return true;
6549
+ }
6550
+ for (const k of CONTENT_ARM_KEYS) {
6551
+ const v = own(n, k);
6552
+ if (v !== void 0 && v !== null) return true;
6553
+ }
6554
+ return false;
6555
+ }
6556
+ function isWireWrapper(n) {
6557
+ return componentTypeOf(n) !== null && typeof n.body?.type === "string";
6558
+ }
6559
+ function nameIn(node, at) {
6560
+ if (!node || typeof node !== "object") return false;
6561
+ if (Array.isArray(node)) return node.some((v) => nameIn(v, at));
6562
+ if (isActionEnvelope(node)) return false;
6563
+ const n = node;
6564
+ let readOwnKeys = true;
6565
+ if (at === "descendant") {
6566
+ const exposure = atExposureOf(n);
6567
+ if (exposure === "hidden") return false;
6568
+ if (exposure === "decorative") readOwnKeys = false;
6569
+ } else if (at === "decorativeOwn") {
6570
+ if (componentTypeOf(n) !== null) return nameIn(n, "descendant");
6571
+ readOwnKeys = false;
6572
+ }
6573
+ if (readOwnKeys) {
6574
+ if (ownName(n)) return true;
6575
+ return Object.values(n).some((v) => nameIn(v, "descendant"));
6576
+ }
6577
+ const wrapper = isWireWrapper(n);
6578
+ return Object.entries(n).some(([k, v]) => {
6579
+ if (k === "body" && wrapper && v && typeof v === "object" && !Array.isArray(v)) {
6580
+ return Object.values(v).some((w) => nameIn(w, "decorativeOwn"));
6581
+ }
6582
+ return nameIn(v, "decorativeOwn");
6583
+ });
6584
+ }
6585
+ function hasAccessibleName(node) {
6586
+ return nameIn(node, "self");
6587
+ }
6588
+ function componentTypeOf(node) {
6589
+ const body = node.body;
6590
+ if (body && typeof body === "object" && !Array.isArray(body) && typeof body.type === "string" && typeof body.package === "string") {
6591
+ return body.type;
6592
+ }
6593
+ if (typeof node.type === "string" && typeof node.package === "string") return node.type;
6594
+ return null;
6595
+ }
6596
+ function accessibleNameGaps(descriptor, options = {}) {
6597
+ const out = [];
6598
+ const interactiveOnly = options.interactiveOnly === true;
6599
+ const walk2 = (node, path2, key2, suppressed = false) => {
6600
+ if (!node || typeof node !== "object") return;
6601
+ if (Array.isArray(node)) {
6602
+ node.forEach((v, i) => walk2(v, `${path2}[${i}]`, key2, suppressed));
6603
+ return;
6604
+ }
6605
+ const n = node;
6606
+ if (key2 === "args" || key2 === "input" && path2 === "input") return;
6607
+ const rawMods = n.modifiers;
6608
+ const hasMods = !!rawMods && typeof rawMods === "object" && !Array.isArray(rawMods);
6609
+ const exposure = atExposureOf(n);
6610
+ if (exposure === "hidden") return;
6611
+ const viaBody = componentTypeOf(n) !== null && typeof n.body?.type === "string";
6612
+ const bodyMods = viaBody ? n.body.modifiers : void 0;
6613
+ const deferToBody = viaBody && !hasMods && !!bodyMods && typeof bodyMods === "object" && !Array.isArray(bodyMods);
6614
+ if (key2 !== "modifiers" && !suppressed && !deferToBody) {
6615
+ if (exposure !== "decorative") {
6616
+ const tappable = isInteractive(n);
6617
+ const type = componentTypeOf(n);
6618
+ const row = type ? own(A11Y_CONTRACT, type) : void 0;
6619
+ const contractual = !interactiveOnly && row?.name === "required";
6620
+ if ((tappable || contractual) && !hasAccessibleName(n)) {
6621
+ out.push({
6622
+ at: path2 || "root",
6623
+ type: type ?? (n.icon ? "icon" : "node"),
6624
+ reason: tappable ? "interactive" : "contract",
6625
+ // §3.4: interactivity promotes the container to a BUTTON whatever its row says.
6626
+ role: tappable ? "button" : row?.role ?? "unspecified"
6627
+ });
6628
+ }
6629
+ }
6630
+ }
6631
+ for (const [k, v] of Object.entries(n)) {
6632
+ walk2(v, path2 ? `${path2}.${k}` : k, k, k === "body" && viaBody && !deferToBody);
6633
+ }
6634
+ };
6635
+ walk2(descriptor, "", "");
6636
+ return out;
6637
+ }
6638
+ var A11Y_CONTRACT, ACCESSIBLE_NAME_KEYS, CONTENT_ARM_KEYS, TAP_MODIFIER_KEYS;
6639
+ var init_a11y_contract = __esm({
6640
+ "../../core/dev-server/src/a11y-contract.ts"() {
6641
+ A11Y_CONTRACT = {
6642
+ // ---- Layout / structural containers -------------------------------------------------
6643
+ // Transparent by default: not AT stops, they expose their children directly. They become a
6644
+ // named GROUP only when they carry `accessibilityLabel` — or when an `onTap` promotes them
6645
+ // (§3.4), which is what the `conditional` arm catches.
6646
+ VStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
6647
+ HStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
6648
+ ZStack: { role: "unspecified", name: "conditional", state: [], decorative: false },
6649
+ Grid: { role: "unspecified", name: "conditional", state: [], decorative: false },
6650
+ LazyList: { role: "list", name: "conditional", state: ["item position", "item count"], decorative: false },
6651
+ Card: { role: "group", name: "conditional", state: [], decorative: false },
6652
+ Divider: { role: "decorative", name: "none", state: [], decorative: true },
6653
+ Spacer: { role: "decorative", name: "none", state: [], decorative: true },
6654
+ SplitView: { role: "unspecified", name: "conditional", state: [], decorative: false },
6655
+ Section: { role: "group", name: "conditional", state: [], decorative: false },
6656
+ LabeledContent: { role: "group", name: "required", state: ["value = the content"], decorative: false },
6657
+ // ---- Text and inline content --------------------------------------------------------
6658
+ // Named by themselves: the copy IS the name, so `required` here reads "this node must carry
6659
+ // some copy", which is also what makes an empty Text a finding rather than a silent stop.
6660
+ Text: { role: "text", name: "required", state: [], decorative: false },
6661
+ RichText: { role: "text", name: "required", state: [], decorative: false },
6662
+ Label: { role: "text", name: "required", state: [], decorative: false },
6663
+ Marquee: { role: "text", name: "required", state: [], decorative: false },
6664
+ Badge: { role: "status", name: "required", state: ["count/value"], decorative: false },
6665
+ Tag: { role: "text", name: "required", state: ["selected (if in a group)"], decorative: false },
6666
+ // ---- Images and media ---------------------------------------------------------------
6667
+ Image: { role: "image", name: "conditional", state: [], decorative: false },
6668
+ // `contentDescription` present ⇒ IMAGE; absent ⇒ DECORATIVE. That is exactly why this pass
6669
+ // can exist: before #2893 there was no way for an author to SAY "decorative", so a validator
6670
+ // could not tell a chevron from an unlabelled icon button and any rule would have been noise.
6671
+ Icon: { role: "decorative", name: "conditional", state: [], decorative: true },
6672
+ Avatar: { role: "image", name: "required", state: [], decorative: false },
6673
+ AvatarStrip: { role: "group", name: "required", state: ["count"], decorative: false },
6674
+ Video: { role: "group", name: "required", state: ["playing/paused", "position"], decorative: false },
6675
+ MediaPlayer: { role: "group", name: "required", state: ["playing/paused", "position"], decorative: false },
6676
+ Lottie: { role: "decorative", name: "conditional", state: [], decorative: true },
6677
+ Rive: { role: "decorative", name: "conditional", state: [], decorative: true },
6678
+ PdfView: { role: "group", name: "required", state: ["page N of M"], decorative: false },
6679
+ VoiceNote: { role: "group", name: "required", state: ["playing", "duration/position"], decorative: false },
6680
+ Map: { role: "image", name: "required", state: [], decorative: false },
6681
+ WebView: { role: "group", name: "required", state: [], decorative: false },
6682
+ // ---- Interactive controls -----------------------------------------------------------
6683
+ Button: { role: "button", name: "required", state: ["disabled"], decorative: false },
6684
+ Fab: { role: "button", name: "required", state: ["disabled"], decorative: false },
6685
+ TextField: { role: "textfield", name: "required", state: ["value", "error", "required"], decorative: false },
6686
+ SearchField: { role: "search", name: "required", state: ["value"], decorative: false },
6687
+ Toggle: { role: "toggle", name: "required", state: ["on/off"], decorative: false },
6688
+ Stepper: { role: "adjustable", name: "required", state: ["value", "increment/decrement"], decorative: false },
6689
+ Slider: { role: "adjustable", name: "required", state: ["value (+ min/max/pct)"], decorative: false },
6690
+ SelectionControl: { role: "checkbox", name: "required", state: ["checked", "group membership"], decorative: false },
6691
+ Picker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
6692
+ DatePicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
6693
+ WheelPicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
6694
+ ColorPicker: { role: "combobox", name: "required", state: ["current selection", "expanded"], decorative: false },
6695
+ OtpInput: { role: "textfield", name: "required", state: ["value", "per-cell position"], decorative: false },
6696
+ ChipsInput: { role: "textfield", name: "required", state: ["value", "each chip removable"], decorative: false },
6697
+ Chip: { role: "button", name: "required", state: ["selected", "disabled"], decorative: false },
6698
+ FilterChips: { role: "group", name: "required", state: ["each chip selected"], decorative: false },
6699
+ SegmentedControl: { role: "tablist", name: "required", state: ["each segment selected"], decorative: false },
6700
+ Tabs: { role: "tablist", name: "required", state: ["selected tab", "index/count"], decorative: false },
6701
+ Menu: { role: "menu", name: "required", state: ["each item enabled/checked"], decorative: false },
6702
+ Rating: { role: "adjustable", name: "required", state: ['value "N of M"'], decorative: false },
6703
+ ListItem: { role: "listitem", name: "required", state: ["selected", "disabled", "position"], decorative: false },
6704
+ // ---- Navigation and progress structures ---------------------------------------------
6705
+ DisclosureGroup: { role: "button", name: "required", state: ["expanded/collapsed"], decorative: false },
6706
+ CollapsingHeader: { role: "heading", name: "required", state: ["expanded/collapsed"], decorative: false },
6707
+ Carousel: { role: "list", name: "required", state: ["item N of M"], decorative: false },
6708
+ Pager: { role: "list", name: "required", state: ["item N of M"], decorative: false },
6709
+ PageControl: { role: "adjustable", name: "required", state: ["page N of M"], decorative: false },
6710
+ StepIndicator: { role: "group", name: "required", state: ["step N of M", "current"], decorative: false },
6711
+ // ---- Status, feedback, and overlays -------------------------------------------------
6712
+ ProgressBar: { role: "progressbar", name: "conditional", state: ["value/pct or indeterminate"], decorative: false },
6713
+ ActivityIndicator: { role: "status", name: "conditional", state: ["busy"], decorative: false },
6714
+ Gauge: { role: "progressbar", name: "required", state: ["value + unit"], decorative: false },
6715
+ Skeleton: { role: "decorative", name: "none", state: [], decorative: true },
6716
+ Banner: { role: "status", name: "required", state: ["dismissible"], decorative: false },
6717
+ Snackbar: { role: "status", name: "required", state: [], decorative: false },
6718
+ AlertDialog: { role: "alert", name: "required", state: ["modal"], decorative: false },
6719
+ Tooltip: { role: "unspecified", name: "required", state: [], decorative: false },
6720
+ EmptyState: { role: "group", name: "required", state: [], decorative: false },
6721
+ StatefulSection: { role: "group", name: "conditional", state: ["loading/empty/error/loaded"], decorative: false },
6722
+ FieldError: { role: "alert", name: "required", state: ["associated field"], decorative: false },
6723
+ BottomSheet: { role: "dialog", name: "required", state: ["modal", "expanded"], decorative: false },
6724
+ Popover: { role: "dialog", name: "required", state: ["modal", "expanded"], decorative: false },
6725
+ Form: { role: "group", name: "conditional", state: ["field grouping", "errors"], decorative: false },
6726
+ FormField: { role: "group", name: "conditional", state: ["field grouping", "errors"], decorative: false },
6727
+ // ---- Data, visualization, and temporal ----------------------------------------------
6728
+ Chart: { role: "image", name: "required", state: ["a spoken data summary"], decorative: false },
6729
+ DonutChart: { role: "image", name: "required", state: ["a spoken data summary"], decorative: false },
6730
+ Legend: { role: "list", name: "required", state: ["each series name + value"], decorative: false },
6731
+ DataTable: { role: "group", name: "required", state: ["row/col headers", "cell position"], decorative: false },
6732
+ Table: { role: "group", name: "required", state: ["row/col headers", "cell position"], decorative: false },
6733
+ MonthCalendar: { role: "grid", name: "required", state: ["selected date", "today", "range"], decorative: false },
6734
+ TimeGrid: { role: "grid", name: "required", state: ["slot time", "availability", "selected"], decorative: false },
6735
+ Agenda: { role: "list", name: "required", state: ["each entry time + title"], decorative: false },
6736
+ Timeline: { role: "list", name: "required", state: ["each event position + label"], decorative: false },
6737
+ // ---- Fragment / worker composition --------------------------------------------------
6738
+ // Pass-through: the subtree they render is subject to the same contract, so scoring the
6739
+ // carrier as well would double-report its children.
6740
+ FragmentSlot: { role: "unspecified", name: "none", state: ["announcement on case change"], decorative: false },
6741
+ WorkerSubtree: { role: "unspecified", name: "none", state: [], decorative: false }
6742
+ };
6743
+ ACCESSIBLE_NAME_KEYS = [
6744
+ "accessibilityLabel",
6745
+ "contentDescription",
6746
+ "text",
6747
+ "title",
6748
+ "label",
6749
+ "placeholder",
6750
+ "message",
6751
+ "subtitle",
6752
+ "overline",
6753
+ "caption",
6754
+ "initials",
6755
+ "emptyText",
6756
+ "actionLabel",
6757
+ "confirmLabel",
6758
+ "cancelLabel",
6759
+ "helpText",
6760
+ "errorMessage",
6761
+ "centerTitle",
6762
+ "centerSubtitle",
6763
+ // The one `…Path` TWIN of a name prop in the whole vocabulary. Binding copy to worker state
6764
+ // is authoring it, not omitting it — `textPath: "$service:cart.title"` speaks on device.
6765
+ // (Checked: `textPath` is the only `<nameKey>Path` prop `KNOWN_PROPS` declares. The other
6766
+ // ~40 `…Path` props bind items, colours, dates and values, none of which is a name.)
6767
+ "textPath"
6768
+ ];
6769
+ CONTENT_ARM_KEYS = ["template", "timeRef"];
6770
+ TAP_MODIFIER_KEYS = ["onTap", "onLongPress", "onDoubleTap"];
6771
+ }
6772
+ });
6773
+
6519
6774
  // ../../stdlib/wix-sdk/media/src/index.ts
6520
6775
  function wixMediaId(reference) {
6521
6776
  return WIX_IMAGE.exec(reference)?.[1] ?? (reference.includes("/") || reference.includes(":") ? "" : reference);
@@ -7428,7 +7683,7 @@ function serviceFieldDeclared(state, path2) {
7428
7683
  function ellipsis(value, max) {
7429
7684
  return value.length <= max ? value : `${value.slice(0, max)}\u2026`;
7430
7685
  }
7431
- function own(table, key2) {
7686
+ function own2(table, key2) {
7432
7687
  return Object.prototype.hasOwnProperty.call(table, key2) ? table[key2] : void 0;
7433
7688
  }
7434
7689
  function isOpaqueAuthorJson(key2, value, atRoot) {
@@ -7473,7 +7728,7 @@ function nativeRequiredFindings(descriptor) {
7473
7728
  value.forEach((v, i) => checkNested(v, of, `${path2}[${i}]`, from));
7474
7729
  return;
7475
7730
  }
7476
- const rule = own(NATIVE_NESTED_CLASSES, cls);
7731
+ const rule = own2(NATIVE_NESTED_CLASSES, cls);
7477
7732
  if (!rule) return;
7478
7733
  if (Array.isArray(value) || !value || typeof value !== "object") {
7479
7734
  reportKind(cls, value, path2, from);
@@ -7481,17 +7736,17 @@ function nativeRequiredFindings(descriptor) {
7481
7736
  }
7482
7737
  const bag = value;
7483
7738
  for (const name of rule.required) {
7484
- if (own(bag, name) !== void 0 && bag[name] !== null) continue;
7739
+ if (own2(bag, name) !== void 0 && bag[name] !== null) continue;
7485
7740
  out.push({
7486
7741
  path: `${path2}.${name}`,
7487
7742
  message: `${cls}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${cls}', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine (reached from ${from})`
7488
7743
  });
7489
7744
  }
7490
7745
  for (const [name, sub] of Object.entries(rule.nested)) {
7491
- const inner = own(bag, name);
7746
+ const inner = own2(bag, name);
7492
7747
  if (inner !== void 0 && inner !== null) checkNested(inner, sub, `${path2}.${name}`, from);
7493
7748
  }
7494
- if (cls === "Action") checkActionParams(own(bag, "params"), `${path2}.params`, from);
7749
+ if (cls === "Action") checkActionParams(own2(bag, "params"), `${path2}.params`, from);
7495
7750
  };
7496
7751
  const checkActionParams = (params, path2, from) => {
7497
7752
  if (params === void 0 || params === null) return;
@@ -7524,22 +7779,22 @@ function nativeRequiredFindings(descriptor) {
7524
7779
  const props = body.props;
7525
7780
  const bag = props && typeof props === "object" && !Array.isArray(props) ? props : {};
7526
7781
  const base = at ? `${at}.body.props` : "body.props";
7527
- for (const name of own(NATIVE_REQUIRED_PROPS, type) ?? []) {
7528
- if (own(bag, name) !== void 0 && bag[name] !== null) continue;
7782
+ for (const name of own2(NATIVE_REQUIRED_PROPS, type) ?? []) {
7783
+ if (own2(bag, name) !== void 0 && bag[name] !== null) continue;
7529
7784
  const hint = type === "Button" && name === "title" && bag.iconOnly === true ? " \u2014 `iconOnly` HIDES the label, it does not make it optional; keep a title (it is also the accessibility label)" : "";
7530
7785
  out.push({
7531
7786
  path: `${base}.${name}`,
7532
7787
  message: `${type}.${name} is REQUIRED by the native decoder but is missing \u2014 native decode rejects it ("Field '${name}' is required for type with serial name 'io.himalaya.core.${type}Props', but it was missing") and drops the WHOLE screen from the seed, while web renders it fine${hint}`
7533
7788
  });
7534
7789
  }
7535
- for (const [prop, cls] of Object.entries(own(NATIVE_NESTED_PROPS, type) ?? {})) {
7536
- const value = own(bag, prop);
7790
+ for (const [prop, cls] of Object.entries(own2(NATIVE_NESTED_PROPS, type) ?? {})) {
7791
+ const value = own2(bag, prop);
7537
7792
  if (value === void 0 || value === null) continue;
7538
7793
  checkNested(value, cls, `${base}.${prop}`, `${type}.${prop}`);
7539
7794
  }
7540
7795
  }
7541
7796
  if (body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string") {
7542
- const modifiers = own(record2, "modifiers");
7797
+ const modifiers = own2(record2, "modifiers");
7543
7798
  if (modifiers !== void 0 && modifiers !== null) {
7544
7799
  checkNested(modifiers, NATIVE_MODIFIERS_CLASS, at ? `${at}.modifiers` : "modifiers", "modifiers");
7545
7800
  }
@@ -7553,7 +7808,7 @@ function nativeRequiredFindings(descriptor) {
7553
7808
  if (descriptor && typeof descriptor === "object" && !Array.isArray(descriptor)) {
7554
7809
  const root = descriptor;
7555
7810
  for (const [field, cls] of Object.entries(NATIVE_DESCRIPTOR_NESTED)) {
7556
- const value = own(root, field);
7811
+ const value = own2(root, field);
7557
7812
  if (value === void 0 || value === null) continue;
7558
7813
  checkNested(value, cls, field, `${NATIVE_DESCRIPTOR_CLASS}.${field}`);
7559
7814
  }
@@ -7583,14 +7838,14 @@ function componentPropFindings(descriptor) {
7583
7838
  const body = record2.body;
7584
7839
  if (typeof body?.package === "string" && CORE_PACKAGES.has(body.package) && typeof body.type === "string") {
7585
7840
  const type = body.type;
7586
- const declared = own(KNOWN_PROPS, type);
7841
+ const declared = own2(KNOWN_PROPS, type);
7587
7842
  const props = body.props;
7588
7843
  if (declared && props && typeof props === "object" && !Array.isArray(props)) {
7589
7844
  const bag = props;
7590
7845
  const base = at ? `${at}.body.props` : "body.props";
7591
7846
  for (const name of Object.keys(bag)) {
7592
7847
  const path2 = `${base}.${name}`;
7593
- const kind = own(declared, name);
7848
+ const kind = own2(declared, name);
7594
7849
  if (kind === void 0) {
7595
7850
  if (LEGACY_UNSCORED_KEYS.has(`${type}.${name}`)) continue;
7596
7851
  const hint = MODIFIER_KEYS.has(name) ? ` \u2014 \`${name}\` is a MODIFIER, not a prop: move it out of \`props\` and into the node's \`modifiers\` bag (\`{ id, body, modifiers: { ${name}: \u2026 } }\`)` : "";
@@ -7606,7 +7861,7 @@ function componentPropFindings(descriptor) {
7606
7861
  if (kind === "any") continue;
7607
7862
  if (typeof value === "string" && BINDING_SIGIL_RE.test(value)) {
7608
7863
  if (kind === "string") continue;
7609
- const twin = own(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
7864
+ const twin = own2(declared, `${name}Path`) !== void 0 ? `${name}Path` : void 0;
7610
7865
  const inArray = IN_ARRAY_BINDING_PROPS.has(`${type}.${name}`) && value.startsWith(SERVICE_SIGIL);
7611
7866
  out.push({
7612
7867
  path: path2,
@@ -7629,10 +7884,10 @@ function componentPropFindings(descriptor) {
7629
7884
  });
7630
7885
  continue;
7631
7886
  }
7632
- if (own(NATIVE_PROP_ENUMS, name) !== void 0) continue;
7887
+ if (own2(NATIVE_PROP_ENUMS, name) !== void 0) continue;
7633
7888
  const actual = wireKind(value);
7634
7889
  if (actual === kind) {
7635
- if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own(INTEGER_PROPS, type)?.includes(name)) {
7890
+ if (kind === "number" && typeof value === "number" && !Number.isInteger(value) && own2(INTEGER_PROPS, type)?.includes(name)) {
7636
7891
  out.push({
7637
7892
  path: path2,
7638
7893
  kind: "decode",
@@ -7650,13 +7905,13 @@ function componentPropFindings(descriptor) {
7650
7905
  }
7651
7906
  }
7652
7907
  if (body && typeof body === "object" && typeof body.type === "string" && typeof body.package === "string") {
7653
- const modifiers = own(record2, "modifiers");
7908
+ const modifiers = own2(record2, "modifiers");
7654
7909
  if (modifiers && typeof modifiers === "object" && !Array.isArray(modifiers)) {
7655
7910
  const schemaOwnsUnknownKeys = SCHEMA_SCORED_NODES.has(at);
7656
7911
  const bag = modifiers;
7657
7912
  for (const key2 of Object.keys(bag)) {
7658
7913
  if (MODIFIER_KEYS.has(key2)) {
7659
- const spec = own(MODIFIER_KINDS, key2);
7914
+ const spec = own2(MODIFIER_KINDS, key2);
7660
7915
  const value = bag[key2];
7661
7916
  if (!spec || value === void 0 || value === null) continue;
7662
7917
  const where = at ? `${at}.modifiers.${key2}` : `modifiers.${key2}`;
@@ -8252,7 +8507,7 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8252
8507
  if (isOpaqueAuthorJson(k, val, at === "")) continue;
8253
8508
  if (k === "params" && typeof node.actionId === "string") continue;
8254
8509
  const here = at ? `${at}.${k}` : k;
8255
- const allowed2 = own(NATIVE_PROP_ENUMS, k);
8510
+ const allowed2 = own2(NATIVE_PROP_ENUMS, k);
8256
8511
  if (typeof val === "string" && enums.has(k) && DYNAMIC_PLACEHOLDER.test(val)) {
8257
8512
  issues.push({
8258
8513
  severity: "error",
@@ -8493,6 +8748,30 @@ function validateScreenDescriptor(screenId, descriptor, opts = {}) {
8493
8748
  });
8494
8749
  }
8495
8750
  }
8751
+ const a11yMode = opts.a11y?.enforce ?? "error";
8752
+ if (a11yMode !== "off") {
8753
+ const severity = a11yMode === "warn" && !strict ? "warning" : "error";
8754
+ const gaps = accessibleNameGaps(descriptor);
8755
+ const CAP4 = 20;
8756
+ for (const gap of gaps.slice(0, CAP4)) {
8757
+ const row = Object.prototype.hasOwnProperty.call(A11Y_CONTRACT, gap.type) ? A11Y_CONTRACT[gap.type] : void 0;
8758
+ const why = gap.reason === "interactive" ? `it carries an \`onTap\`/\`onLongPress\`/\`onDoubleTap\`, which promotes ANY node to a control that owes a name (RFC 0058 \xA73.4)` : `RFC 0058 \xA73.3 requires a name for \`${gap.type}\` (announced as \`${gap.role}\`)`;
8759
+ const fix = gap.reason === "contract" ? `Give it \`modifiers.accessibilityLabel\`, or copy on a descendant \u2014 or, if it really is presentational, say so with \`modifiers.accessibilityRole: "decorative"\` (node-local) or \`modifiers.accessibilityHidden: true\` (whole subtree).` : `Give it \`modifiers.accessibilityLabel\`, or put readable copy on a descendant. An icon-only control names itself with \`Icon.contentDescription\`. \`decorative\` does not silence a control${row?.decorative ? ` \u2014 a tappable \`${gap.type}\` is one` : ""}.`;
8760
+ issues.push({
8761
+ severity,
8762
+ pass: "a11y",
8763
+ path: gap.at,
8764
+ message: `${gap.type} renders no accessible name anywhere in its subtree, and ${why}. A screen reader announces this node as an unnamed \`${gap.role}\`. ${fix}`
8765
+ });
8766
+ }
8767
+ if (gaps.length > CAP4) {
8768
+ issues.push({
8769
+ severity,
8770
+ pass: "a11y",
8771
+ message: `+${gaps.length - CAP4} more node(s) on this screen render no accessible name (${gaps.length} in total). Fix the ${CAP4} above and re-run to see the rest.`
8772
+ });
8773
+ }
8774
+ }
8496
8775
  return {
8497
8776
  screenId,
8498
8777
  ok: !issues.some((i) => i.severity === "error"),
@@ -8507,6 +8786,7 @@ var init_validate_descriptor_core = __esm({
8507
8786
  init_validator();
8508
8787
  init_validator();
8509
8788
  init_l10n_strings();
8789
+ init_a11y_contract();
8510
8790
  init_bindings();
8511
8791
  init_media_value();
8512
8792
  init_frame_limits();
@@ -8957,6 +9237,7 @@ var init_validate_descriptor_core = __esm({
8957
9237
  interactive: "boolean",
8958
9238
  max: "number",
8959
9239
  onChange: "any",
9240
+ size: "string",
8960
9241
  value: "number",
8961
9242
  valuePath: "string"
8962
9243
  },
@@ -12729,8 +13010,8 @@ var init_tokens2 = __esm({
12729
13010
  // ../font-bake/web-fallback.ts
12730
13011
  function webRenderedFallback(family) {
12731
13012
  const stack = fontStack(family);
12732
- const own2 = `"${family}", `;
12733
- const tail = stack.startsWith(own2) ? stack.slice(own2.length) : stack;
13013
+ const own3 = `"${family}", `;
13014
+ const tail = stack.startsWith(own3) ? stack.slice(own3.length) : stack;
12734
13015
  return tail.split(",")[0].trim().replace(/^"(.*)"$/, "$1");
12735
13016
  }
12736
13017
  var init_web_fallback = __esm({
@@ -14076,7 +14357,7 @@ function parseIconConfig(configTs) {
14076
14357
  const block = /^ {2}icon\s*[:=]\s*\{([^}]*)\}/m.exec(src);
14077
14358
  if (!block) return {};
14078
14359
  const body = block[1];
14079
- const str6 = (k) => new RegExp(`\\b${k}\\s*:\\s*["']([^"']+)["']`).exec(body)?.[1];
14360
+ const str7 = (k) => new RegExp(`\\b${k}\\s*:\\s*["']([^"']+)["']`).exec(body)?.[1];
14080
14361
  const num3 = (k) => {
14081
14362
  const m = new RegExp(`\\b${k}\\s*:\\s*(-?(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?)\\s*(?=[,}\\n]|$)`).exec(body);
14082
14363
  if (!m) return void 0;
@@ -14087,10 +14368,10 @@ function parseIconConfig(configTs) {
14087
14368
  return n;
14088
14369
  };
14089
14370
  const out = {};
14090
- const source = str6("source");
14091
- const glyph = str6("glyph");
14092
- const accentColor = str6("accentColor");
14093
- const backgroundColor = str6("backgroundColor");
14371
+ const source = str7("source");
14372
+ const glyph = str7("glyph");
14373
+ const accentColor = str7("accentColor");
14374
+ const backgroundColor = str7("backgroundColor");
14094
14375
  const glyphScale = num3("glyphScale");
14095
14376
  for (const [key2, parsed] of [
14096
14377
  ["source", source],
@@ -18732,13 +19013,13 @@ function parsePaddingShorthand(v) {
18732
19013
  }
18733
19014
  function addIntrinsicPadding(style, modPad) {
18734
19015
  if (!style) return void 0;
18735
- const own2 = parsePaddingShorthand(style.padding);
18736
- if (!own2) return void 0;
19016
+ const own3 = parsePaddingShorthand(style.padding);
19017
+ if (!own3) return void 0;
18737
19018
  const sides = [
18738
- ["paddingTop", own2.top],
18739
- ["paddingBottom", own2.bottom],
18740
- ["paddingLeft", own2.left],
18741
- ["paddingRight", own2.right]
19019
+ ["paddingTop", own3.top],
19020
+ ["paddingBottom", own3.bottom],
19021
+ ["paddingLeft", own3.left],
19022
+ ["paddingRight", own3.right]
18742
19023
  ];
18743
19024
  let out;
18744
19025
  for (const [key2, ownPx] of sides) {
@@ -24025,10 +24306,10 @@ function calSnap(minuteOfDay, step) {
24025
24306
  return Math.min(Math.max(Math.round(minuteOfDay / s) * s, 0), 24 * 60);
24026
24307
  }
24027
24308
  function calMoveEvent(startMinute, endMinute, deltaMinutes, step) {
24028
- const duration = Math.max(1, endMinute - startMinute);
24029
- const maxStart = Math.max(0, 24 * 60 - duration);
24309
+ const duration2 = Math.max(1, endMinute - startMinute);
24310
+ const maxStart = Math.max(0, 24 * 60 - duration2);
24030
24311
  const start = Math.min(Math.max(calSnap(startMinute + deltaMinutes, step), 0), maxStart);
24031
- return { startMinute: start, endMinute: start + duration };
24312
+ return { startMinute: start, endMinute: start + duration2 };
24032
24313
  }
24033
24314
  function calResizeEvent(startMinute, endMinute, deltaMinutes, step) {
24034
24315
  const s = Math.max(1, step);
@@ -24178,7 +24459,7 @@ function calKeyActivate(enabled, activate) {
24178
24459
  function applyA11ySemantics(node, ctx, extra) {
24179
24460
  const m = node?.modifiers;
24180
24461
  if (!m) return void 0;
24181
- const str6 = (v) => {
24462
+ const str7 = (v) => {
24182
24463
  if (v == null) return void 0;
24183
24464
  const r = resolveScalarStatic(v, ctx);
24184
24465
  const s = r == null ? "" : String(r).trim();
@@ -24189,7 +24470,7 @@ function applyA11ySemantics(node, ctx, extra) {
24189
24470
  extra.inert = "";
24190
24471
  return void 0;
24191
24472
  }
24192
- const role = str6(m.accessibilityRole ?? m.accessibility_role);
24473
+ const role = str7(m.accessibilityRole ?? m.accessibility_role);
24193
24474
  const headingLevel = m.headingLevel ?? m.heading_level;
24194
24475
  const tappable = Boolean((m.onTap ?? m.on_tap ?? m.onDoubleTap ?? m.on_double_tap) && ctx.onAction);
24195
24476
  if (role === "decorative" && !tappable) {
@@ -24204,8 +24485,8 @@ function applyA11ySemantics(node, ctx, extra) {
24204
24485
  if (typeof headingLevel === "number" && headingLevel >= 1 && headingLevel <= 6) {
24205
24486
  extra["aria-level"] = String(headingLevel);
24206
24487
  }
24207
- const hint = str6(m.accessibilityHint ?? m.accessibility_hint);
24208
- const value = str6(m.accessibilityValue ?? m.accessibility_value);
24488
+ const hint = str7(m.accessibilityHint ?? m.accessibility_hint);
24489
+ const value = str7(m.accessibilityValue ?? m.accessibility_value);
24209
24490
  if (value) extra["aria-valuetext"] = value;
24210
24491
  const traits = m.accessibilityTraits ?? m.accessibility_traits;
24211
24492
  if (Array.isArray(traits)) {
@@ -25079,7 +25360,7 @@ function renderInner(node, ctx) {
25079
25360
  }
25080
25361
  }
25081
25362
  }
25082
- var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
25363
+ var useIsomorphicLayoutEffect, ResponsiveGrid, SPLIT_EXPANDED_MIN_WIDTH, SPLIT_COLUMN_GAP, ResponsiveSplitView, ABSOLUTE_URL_RE, appearKeyframesInjected, pressStylesInjected, FOCUS_RING_CSS, focusStylesInjected, HLIST_CHILD_CSS, hListStylesInjected, listAnimateRuntimeInstalled, transitionKeyframesInjected, countUpRuntimeInjected, MEASURE_PREFIX, measureRuntimeInjected, revealRuntimeInjected, vectorAnimStylesInjected, scrollProgressRuntimeInjected, confettiRuntimeInjected, lottieRuntimeInjected, riveRuntimeInjected, gradientKeyframesInjected, parallaxRuntimeInjected, spinKeyframesInjected, marqueeKeyframesInjected, alignItems, zJustifyItems, hAlignItems, bodyFont, kids, rowKids, staggeredKids, asTextL10n, asBoundText, useBoundString, InterpolatedTextView, txt, selectFragmentCase, fragmentValueHash, fragmentSlotContent, FragmentSlotNode, WorkerSubtreeNode, resolveItemDeep2, resolveSwipeActions, resolveModBindings, resolvedComponentId, directServiceBindings, ReactiveDirectScalars, HiddenGate, KEYBOARD_INPUT_MODES, AUTOCAPITALIZE_VALUES, ENTER_KEY_HINTS, AUTOGROW_CEILING, EditableField, MenuNode, LoadMoreSentinel, FieldErrorNode, FormView, MediaSlotProvider, MEDIA_ITEM_BINDABLE, MediaPlayerView, VideoNode, PdfViewNode, WebViewNode, InteractivePicker, InteractiveDatePicker, InteractiveSearchField, InteractiveStepper, SYNTHETIC_TAP_ROLE, INFERRED_DECORATIVE, ICON_GLYPH, INTERACTIVE_ROLES, ALWAYS_INTERACTIVE_COMPONENT_TYPES, controlNode, ToggleNode, SliderNode, SelectionControlNode, TabsNode, SegmentedControlNode, DisclosureGroupNode, GridNode, SplitViewNode, TextNode, ImageNode, AvatarNode, IconNode, ButtonNode, OtpInputNode, ProgressBarNode, ActivityIndicatorNode, BottomSheetNode, ChipsInputNode, ChipNode, TableNode, GaugeRing, GaugeNode, RATING_METRICS, ratingMetrics, RatingNode, AvatarStripNode, CHART_STROKE_CYCLE, chartStrokeAt, chartBarCenter, ChartNode, donutSliceOpacity, DonutChartNode, LegendMarker, LegendNode, cellAlign, DataTableNode, voiceNoteState, voiceNoteDelivery, VOICE_NOTE_DEFAULT_BARS, clampBarCount, VoiceNoteNode, TimelineNode, WheelPickerNode, ColorPickerNode, FilterChipsNode, TILE_PX, MAX_MERCATOR_LAT, DEFAULT_TILE_MAX_ZOOM, CIRCLE_SEGMENTS, METRES_PER_DEG_LAT, MARKER_HIT_RADIUS, SHAPE_HIT_RADIUS, MapNode, CollapsingHeaderNode, UnsupportedOnSurface, CALENDAR_DATE_ONLY_RE, CAL_DEFAULT_MAX_DOTS, CAL_AGENDA_INITIAL_DAYS, CAL_AGENDA_PAGE_DAYS, CAL_DEFAULT_SNAP_MINUTES, CAL_UNASSIGNED_LANE_ID, MonthCalendarNode, TimeGridNode, AgendaNode, ARIA_ROLE, A11yHintDescription, WebRenderer;
25083
25364
  var init_renderNode = __esm({
25084
25365
  "../../core/web-renderer/src/renderNode.tsx"() {
25085
25366
  "use strict";
@@ -25808,7 +26089,7 @@ var init_renderNode = __esm({
25808
26089
  }, [resolvedItems.length, startIndex, queueReady, seatKey]);
25809
26090
  const [status, setStatus] = React5.useState("idle");
25810
26091
  const [position, setPosition] = React5.useState(initialStartPosition);
25811
- const [duration, setDuration] = React5.useState(0);
26092
+ const [duration2, setDuration] = React5.useState(0);
25812
26093
  const [buffered, setBuffered] = React5.useState(0);
25813
26094
  const [rate, setRateState] = React5.useState(1);
25814
26095
  const [fullscreen, setFullscreen] = React5.useState(false);
@@ -25851,9 +26132,9 @@ var init_renderNode = __esm({
25851
26132
  artist: String(item?.artist ?? ""),
25852
26133
  artworkUrl: String(item?.artworkUrl ?? props.posterUrl ?? ""),
25853
26134
  positionSeconds: position,
25854
- durationSeconds: duration || Number(item?.durationSeconds ?? 0),
26135
+ durationSeconds: duration2 || Number(item?.durationSeconds ?? 0),
25855
26136
  bufferedSeconds: buffered,
25856
- progress: duration > 0 ? Math.max(0, Math.min(1, position / duration)) : 0,
26137
+ progress: duration2 > 0 ? Math.max(0, Math.min(1, position / duration2)) : 0,
25857
26138
  muted: mediaRef.current?.muted ?? props.muted === true,
25858
26139
  rate,
25859
26140
  fullscreen,
@@ -25881,7 +26162,7 @@ var init_renderNode = __esm({
25881
26162
  status,
25882
26163
  index,
25883
26164
  positionSeconds: position,
25884
- durationSeconds: duration || Number(item?.durationSeconds ?? 0),
26165
+ durationSeconds: duration2 || Number(item?.durationSeconds ?? 0),
25885
26166
  bufferedSeconds: buffered,
25886
26167
  rate,
25887
26168
  muted: mediaRef.current?.muted ?? props.muted === true,
@@ -25891,7 +26172,7 @@ var init_renderNode = __esm({
25891
26172
  error
25892
26173
  };
25893
26174
  ctx.onAction({ ...action, args: { ...action.args ?? {}, ...snapshot2, ...extra }, params: { ...action.params ?? {}, sessionId, index: String(index), ...Object.fromEntries(Object.entries(extra).map(([k, v]) => [k, String(v)])) } });
25894
- }, [ctx.onAction, sessionId, status, index, position, duration, item, buffered, rate, props.muted, fullscreen, error]);
26175
+ }, [ctx.onAction, sessionId, status, index, position, duration2, item, buffered, rate, props.muted, fullscreen, error]);
25895
26176
  React5.useEffect(() => {
25896
26177
  if (!isUnsupportedProvider || status === "error") return;
25897
26178
  setStatus("error");
@@ -26115,8 +26396,8 @@ var init_renderNode = __esm({
26115
26396
  /* @__PURE__ */ jsx6("button", { "aria-label": status === "playing" ? "Pause" : "Play", onClick: () => status === "playing" ? pause() : void play(), style: { width: 38, height: 38, borderRadius: "50%", color: background, background: foreground, border: 0, fontSize: 18 }, children: status === "playing" ? "\u275A\u275A" : "\u25B6" }),
26116
26397
  /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 }, children: [
26117
26398
  /* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(position) }),
26118
- /* @__PURE__ */ jsx6("input", { "aria-label": "Media position", type: "range", min: 0, max: Math.max(duration, 1), step: 0.1, value: Math.min(position, Math.max(duration, 1)), onChange: (event) => seek(Number(event.currentTarget.value)), style: { width: "100%", accentColor: accent } }),
26119
- /* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(duration) })
26399
+ /* @__PURE__ */ jsx6("input", { "aria-label": "Media position", type: "range", min: 0, max: Math.max(duration2, 1), step: 0.1, value: Math.min(position, Math.max(duration2, 1)), onChange: (event) => seek(Number(event.currentTarget.value)), style: { width: "100%", accentColor: accent } }),
26400
+ /* @__PURE__ */ jsx6("span", { style: { fontSize: 11, whiteSpace: "nowrap" }, children: time(duration2) })
26120
26401
  ] }),
26121
26402
  items.length > 1 && /* @__PURE__ */ jsx6("button", { "aria-label": "Next", onClick: () => select(index + 1), style: { color: "inherit", background: "transparent", border: 0, fontSize: 18 }, children: "\u25B6\u25B6" }),
26122
26403
  props.fullscreen !== "disabled" && /* @__PURE__ */ jsx6("button", { "aria-label": "Fullscreen", onClick: () => void toggleFullscreen(), style: { color: "inherit", background: "transparent", border: 0, fontSize: 18 }, children: "\u26F6" })
@@ -27003,20 +27284,26 @@ var init_renderNode = __esm({
27003
27284
  /* @__PURE__ */ jsx6("div", { style: { position: "absolute", inset: 0, display: "grid", placeItems: "center", fontFamily: fontStack(capF.family), fontSize: capF.remSize, fontWeight: capF.weight, color: C("textPrimary", "#13171e") }, children: txt(props.label, ctx) || `${Math.round(pct * 100)}%` })
27004
27285
  ] }) });
27005
27286
  });
27287
+ RATING_METRICS = {
27288
+ sm: { cell: 16, glyph: 14, gap: 2 },
27289
+ md: { cell: 22, glyph: 20, gap: 3 }
27290
+ };
27291
+ ratingMetrics = (size) => size === "sm" ? RATING_METRICS.sm : RATING_METRICS.md;
27006
27292
  RatingNode = withExtras("RatingNode", ({ props, ctx, wrap }) => {
27007
27293
  const C = ctx.color;
27008
27294
  const bound = useResolvedScalar(props.valuePath, ctx);
27009
27295
  const raw = props.valuePath != null ? bound : props.value;
27010
27296
  const val = typeof raw === "number" ? raw : 0;
27011
27297
  const max = props.max ?? 5;
27298
+ const m = ratingMetrics(props.size);
27012
27299
  const col = C(props.color ?? "warning", "#E89F00");
27013
27300
  const invalidIcon = props.icon != null && typeof props.icon !== "string";
27014
27301
  const base = invalidIcon ? ICON_FALLBACK : (typeof props.icon === "string" && props.icon ? props.icon : "star").replace(/_fill$/, "");
27015
27302
  const filledCount = Math.round(val);
27016
27303
  const onClickStar = (i) => ctx.onAction && props.interactive && props.onChange ? () => ctx.onAction({ ...props.onChange, params: { ...props.onChange?.params ?? {}, value: String(i + 1) } }) : void 0;
27017
- return /* @__PURE__ */ jsx6("span", { style: { display: "inline-flex", alignItems: "center", gap: 3, ...wrap }, children: Array.from({ length: max }).map((_, i) => {
27304
+ return /* @__PURE__ */ jsx6("span", { style: { display: "inline-flex", alignItems: "center", gap: m.gap, ...wrap }, children: Array.from({ length: max }).map((_, i) => {
27018
27305
  const filled = i < filledCount;
27019
- return /* @__PURE__ */ jsx6("span", { onClick: onClickStar(i), style: { display: "inline-grid", placeItems: "center", width: 22, height: 22, cursor: props.interactive ? "pointer" : "default", opacity: filled ? 1 : 0.28 }, children: iconSvg(filled ? `${base}_fill` : base, { size: 20, color: col }) }, i);
27306
+ return /* @__PURE__ */ jsx6("span", { onClick: onClickStar(i), style: { display: "inline-grid", placeItems: "center", width: m.cell, height: m.cell, cursor: props.interactive ? "pointer" : "default", opacity: filled ? 1 : 0.28 }, children: iconSvg(filled ? `${base}_fill` : base, { size: m.glyph, color: col }) }, i);
27020
27307
  }) });
27021
27308
  });
27022
27309
  AvatarStripNode = withExtras("AvatarStripNode", ({ props, ctx, wrap }) => {
@@ -28449,10 +28736,10 @@ var init_renderNode = __esm({
28449
28736
  };
28450
28737
  A11yHintDescription = ({ hint, idBase, children, ...forwarded }) => {
28451
28738
  const descId = `${idBase ?? "hm"}__hint${React5.useId()}`;
28452
- const own2 = children.props;
28739
+ const own3 = children.props;
28453
28740
  const next = { ...forwarded };
28454
- if (forwarded.style) next.style = { ...own2.style ?? {}, ...forwarded.style };
28455
- next["aria-describedby"] = [own2["aria-describedby"], descId].filter(Boolean).join(" ");
28741
+ if (forwarded.style) next.style = { ...own3.style ?? {}, ...forwarded.style };
28742
+ next["aria-describedby"] = [own3["aria-describedby"], descId].filter(Boolean).join(" ");
28456
28743
  return /* @__PURE__ */ jsxs3(Fragment3, { children: [
28457
28744
  React5.cloneElement(children, next),
28458
28745
  /* @__PURE__ */ jsx6("span", { id: descId, hidden: true, "data-hm-a11y-hint": "", children: hint })
@@ -31480,7 +31767,9 @@ async function runScreenDiagnostics(state, screenId, descriptor) {
31480
31767
  nativeActions,
31481
31768
  appWorkerActions,
31482
31769
  strict: false,
31483
- workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? [])
31770
+ workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
31771
+ // Same a11y rung the build lint applies (RFC 0058 §5) — diagnostics must not disagree.
31772
+ a11y: state.app?.module.config.a11y
31484
31773
  });
31485
31774
  const telemetry = state.telemetryEvents.filter((e) => e.screenId === screenId && (/^worker_/.test(e.type) || e.type === "bundle_load_revoked")).slice(-20);
31486
31775
  const lastError = [...telemetry].reverse().find((e) => /crash|revoked|error|fail/i.test(e.type)) ?? null;
@@ -32136,8 +32425,8 @@ function startBundleSourceWatcher(state) {
32136
32425
  }
32137
32426
  function applyTopBarDefault(descriptor, config) {
32138
32427
  const fallback = config?.navigation?.topBarDefault;
32139
- const own2 = descriptor?.topBar;
32140
- if (!fallback || own2) return descriptor;
32428
+ const own3 = descriptor?.topBar;
32429
+ if (!fallback || own3) return descriptor;
32141
32430
  return { ...descriptor, topBar: fallback };
32142
32431
  }
32143
32432
  function syncNetMocksWithApp(state) {
@@ -32405,7 +32694,7 @@ async function handleWebWix(req, res, state) {
32405
32694
  const session = webWixSession(req, res, state);
32406
32695
  const auth = resolveWebWixAuth(state.app);
32407
32696
  const path2 = new URL(req.url ?? "", "http://localhost").pathname;
32408
- const readJson4 = async () => {
32697
+ const readJson5 = async () => {
32409
32698
  const chunks = [];
32410
32699
  for await (const c of req) chunks.push(c);
32411
32700
  const t = Buffer.concat(chunks).toString("utf8");
@@ -32422,7 +32711,7 @@ async function handleWebWix(req, res, state) {
32422
32711
  res.end(JSON.stringify(obj3));
32423
32712
  };
32424
32713
  if (path2 === "/v1/__webwix/login" && req.method === "POST") {
32425
- const b = await readJson4();
32714
+ const b = await readJson5();
32426
32715
  try {
32427
32716
  const { memberToken, visitorToken } = await memberDirectLogin(
32428
32717
  auth.clientId,
@@ -32439,7 +32728,7 @@ async function handleWebWix(req, res, state) {
32439
32728
  }
32440
32729
  }
32441
32730
  if (path2 === "/v1/__webwix/call" && req.method === "POST") {
32442
- const b = await readJson4();
32731
+ const b = await readJson5();
32443
32732
  if (b.ownerMsid !== void 0 || b.checkOwnerSession === true) {
32444
32733
  const msid = String(b.ownerMsid ?? "");
32445
32734
  if (!isSafeMsid(msid)) return reply(400, { error: "webwix_owner_bad_msid" });
@@ -32555,7 +32844,7 @@ async function handleWebWix(req, res, state) {
32555
32844
  });
32556
32845
  }
32557
32846
  if (path2 === "/v1/__webwix/register" && req.method === "POST") {
32558
- const b = await readJson4();
32847
+ const b = await readJson5();
32559
32848
  try {
32560
32849
  const { memberToken, visitorToken } = await memberDirectRegister(
32561
32850
  auth.clientId,
@@ -33105,7 +33394,8 @@ async function handleAdminPlayground(req, res, state) {
33105
33394
  nativeActions,
33106
33395
  appWorkerActions,
33107
33396
  strict,
33108
- workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? [])
33397
+ workerSubtreeScreens: new Set(state.app?.module.config.workerSubtreeScreens ?? []),
33398
+ a11y: state.app?.module.config.a11y
33109
33399
  });
33110
33400
  return sendJson(res, report2.ok ? 200 : 422, report2);
33111
33401
  }
@@ -37532,7 +37822,10 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37532
37822
  appWorkerActions,
37533
37823
  strict: collect2.strict,
37534
37824
  workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? []),
37535
- l10n: l10nLintOptions(preloaded.module.config.locale, preloaded.dir)
37825
+ l10n: l10nLintOptions(preloaded.module.config.locale, preloaded.dir),
37826
+ // RFC 0058 §5 — the app's own rung of the a11y ladder. Omitted ⇒ the validator's
37827
+ // default, "error"; an in-repo app with ratcheted debt declares "warn".
37828
+ a11y: preloaded.module.config.a11y
37536
37829
  });
37537
37830
  lint.push({ screenId, ok: report2.ok, issues: report2.issues });
37538
37831
  }
@@ -37560,7 +37853,8 @@ async function buildFromLoaded(preloaded, dest, opts = {}) {
37560
37853
  nativeActions,
37561
37854
  appWorkerActions,
37562
37855
  strict: collect2.strict,
37563
- workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? [])
37856
+ workerSubtreeScreens: new Set(preloaded.module.config.workerSubtreeScreens ?? []),
37857
+ a11y: preloaded.module.config.a11y
37564
37858
  });
37565
37859
  lint.push({ screenId: wantedRender, ok: report2.ok, issues: report2.issues });
37566
37860
  }
@@ -38095,6 +38389,7 @@ __export(progress_exports, {
38095
38389
  appleScriptString: () => appleScriptString,
38096
38390
  archiveBytes: () => archiveBytes,
38097
38391
  archiveImage: () => archiveImage,
38392
+ imageExtension: () => imageExtension,
38098
38393
  journalPath: () => journalPath,
38099
38394
  notifyDesktop: () => notifyDesktop,
38100
38395
  parseStep: () => parseStep,
@@ -38335,6 +38630,7 @@ __export(studio_exports, {
38335
38630
  STUDIO_PAGE: () => STUDIO_PAGE,
38336
38631
  VALIDATE_RECORD: () => VALIDATE_RECORD,
38337
38632
  buildView: () => buildView,
38633
+ escapeHtml: () => escapeHtml,
38338
38634
  observeShots: () => observeShots,
38339
38635
  openStudio: () => openStudio,
38340
38636
  refreshStudio: () => refreshStudio,
@@ -40659,8 +40955,8 @@ function rewriteNav(nav, removed, homeId) {
40659
40955
  return p;
40660
40956
  };
40661
40957
  const tabFor = (screenId) => {
40662
- const own2 = remainingRoots.find((t) => t.screenId === screenId);
40663
- return typeof own2?.id === "string" ? own2.id : void 0;
40958
+ const own3 = remainingRoots.find((t) => t.screenId === screenId);
40959
+ return typeof own3?.id === "string" ? own3.id : void 0;
40664
40960
  };
40665
40961
  const homeTab = tabFor(homeId) ?? (typeof remainingRoots[0]?.id === "string" ? remainingRoots[0].id : "");
40666
40962
  const finalTab = /* @__PURE__ */ new Map();
@@ -40795,8 +41091,8 @@ function planTrim(src, keepIds, links) {
40795
41091
  if (!linksOf(r).some((l) => removedTarget(l.to))) continue;
40796
41092
  const block = structuredClone(r.block);
40797
41093
  const isDead = (entry) => {
40798
- const own2 = tapTarget(entry);
40799
- const to = own2 && removedTarget(own2) ? own2 : rowTemplateTarget(entry, removedTarget);
41094
+ const own3 = tapTarget(entry);
41095
+ const to = own3 && removedTarget(own3) ? own3 : rowTemplateTarget(entry, removedTarget);
40800
41096
  if (!to) return false;
40801
41097
  dropped.push({ screen: r.label, node: entryLabel(entry), to });
40802
41098
  return true;
@@ -44922,6 +45218,254 @@ var init_functions = __esm({
44922
45218
  }
44923
45219
  });
44924
45220
 
45221
+ // src/studio-reel.ts
45222
+ var studio_reel_exports = {};
45223
+ __export(studio_reel_exports, {
45224
+ REEL_BUDGET_BYTES: () => REEL_BUDGET_BYTES,
45225
+ buildReel: () => buildReel,
45226
+ inlineImages: () => inlineImages,
45227
+ planReel: () => planReel,
45228
+ renderReel: () => renderReel,
45229
+ thin: () => thin,
45230
+ utcDay: () => utcDay
45231
+ });
45232
+ import { createHash as createHash24 } from "node:crypto";
45233
+ import { lstatSync as lstatSync7, readFileSync as readFileSync52 } from "node:fs";
45234
+ import { basename as basename11, join as join45 } from "node:path";
45235
+ function loadMemory2(dir) {
45236
+ const m = readJson4(join45(dir, ".himi", "studio", "memory.json"));
45237
+ if (!isObj(m) || m.version !== 1 || !isObj(m.shots) || !Array.isArray(m.timeline)) return null;
45238
+ const shots = [];
45239
+ for (const [id, s] of Object.entries(m.shots)) {
45240
+ if (!isObj(s)) continue;
45241
+ const file = historyName(s.sha, s.ext);
45242
+ const firstSeen = str(s.firstSeen);
45243
+ if (!file || !firstSeen) continue;
45244
+ const versions = typeof s.versions === "number" && Number.isSafeInteger(s.versions) && s.versions > 0 ? s.versions : 1;
45245
+ shots.push({ id, file, firstSeen, versions, present: s.present === true });
45246
+ }
45247
+ const timeline = [];
45248
+ for (const t of m.timeline) {
45249
+ if (!isObj(t)) continue;
45250
+ const file = historyName(t.sha, t.ext);
45251
+ const ts2 = str(t.ts);
45252
+ const id = str(t.id);
45253
+ if (file && ts2 && id) timeline.push({ ts: ts2, id, file });
45254
+ }
45255
+ return { createdAt: str(m.createdAt), shots, timeline };
45256
+ }
45257
+ function captionAt(entries, ts2) {
45258
+ let best = null;
45259
+ for (const e of entries) if (e.ts <= ts2) best = e;
45260
+ return best ? best.message : null;
45261
+ }
45262
+ function thin(items, max) {
45263
+ if (items.length <= max) return items;
45264
+ if (max < 2) return items.slice(-1);
45265
+ const out = [];
45266
+ for (let i = 0; i < max; i++) out.push(items[Math.round(i * (items.length - 1) / (max - 1))]);
45267
+ return out;
45268
+ }
45269
+ function planReel(dir) {
45270
+ const memory = loadMemory2(dir);
45271
+ const { entries } = readProgress(dir);
45272
+ const summary = summarizeProgress(entries);
45273
+ const manifest = readJson4(join45(dir, "himalaya.content.json"));
45274
+ const tokens = readJson4(join45(dir, "tokens.json"));
45275
+ const accentToken = tokens?.colors?.accentPrimary;
45276
+ const accentRaw = typeof accentToken === "string" ? accentToken : accentToken?.light;
45277
+ const accent = typeof accentRaw === "string" && ACCENT.test(accentRaw) ? accentRaw : DEFAULT_ACCENT;
45278
+ const shots = memory?.shots ?? [];
45279
+ const present = shots.filter((s) => s.present).sort((a, b) => a.firstSeen.localeCompare(b.firstSeen) || a.id.localeCompare(b.id));
45280
+ const home = present.find((s) => /(^|_)home($|_)/i.test(s.id)) ?? present.find((s) => /home/i.test(s.id));
45281
+ const focusId = home?.id ?? present[0]?.id ?? null;
45282
+ const timeline = memory && focusId ? memory.timeline.filter((t) => t.id === focusId) : [];
45283
+ const frames = thin(timeline, MAX_FLIP_FRAMES).map((t) => ({ ts: t.ts, file: t.file, caption: captionAt(entries, t.ts) }));
45284
+ const finals = present.map((s) => ({ id: s.id, file: s.file }));
45285
+ const postcards = entries.map((e) => ({
45286
+ ts: e.ts,
45287
+ message: e.message,
45288
+ step: str(e.step),
45289
+ files: (Array.isArray(e.images) ? e.images : []).map((i) => isObj(i) && typeof i.file === "string" ? basename11(i.file) : "").filter((f) => HISTORY_NAME.test(f))
45290
+ }));
45291
+ const times = [summary.startedAt, ...timeline.map((t) => t.ts), memory?.createdAt].filter((x) => !!x).sort();
45292
+ const startedAt = times[0] ?? null;
45293
+ const endedAt = [summary.lastAt, ...timeline.map((t) => t.ts)].filter((x) => !!x).sort().pop() ?? null;
45294
+ return {
45295
+ app: typeof manifest?.name === "string" && manifest.name ? manifest.name : basename11(dir),
45296
+ accent,
45297
+ startedAt,
45298
+ endedAt,
45299
+ focusId,
45300
+ frames,
45301
+ finals,
45302
+ postcards,
45303
+ stats: {
45304
+ screens: finals.length,
45305
+ versions: shots.reduce((n, s) => n + s.versions, 0),
45306
+ postcards: entries.length,
45307
+ elapsedMs: startedAt && endedAt ? Date.parse(endedAt) - Date.parse(startedAt) : null
45308
+ },
45309
+ dropped: 0
45310
+ };
45311
+ }
45312
+ function inlineImages(dir, plan, budget = REEL_BUDGET_BYTES) {
45313
+ const verified = (f) => {
45314
+ if (!HISTORY_NAME.test(f)) return null;
45315
+ try {
45316
+ const path2 = join45(dir, HISTORY_DIR, f);
45317
+ const st = lstatSync7(path2);
45318
+ if (!st.isFile() || st.nlink !== 1) return null;
45319
+ const bytes2 = readFileSync52(path2);
45320
+ return createHash24("sha256").update(bytes2).digest("hex") === f.slice(0, 64) && imageExtension(bytes2) === f.slice(65) ? bytes2 : null;
45321
+ } catch {
45322
+ return null;
45323
+ }
45324
+ };
45325
+ const sizes = /* @__PURE__ */ new Map();
45326
+ const sizeOf = (f) => {
45327
+ if (!sizes.has(f)) sizes.set(f, verified(f)?.length ?? null);
45328
+ return sizes.get(f);
45329
+ };
45330
+ const total = (p) => {
45331
+ const blank = /* @__PURE__ */ new Map();
45332
+ let bytes2 = 0;
45333
+ for (const f of cited(p)) {
45334
+ const n = sizeOf(f);
45335
+ if (n === null) continue;
45336
+ blank.set(f, "");
45337
+ bytes2 += `data:${mimeOf(f)};base64,`.length + 4 * Math.ceil(n / 3);
45338
+ }
45339
+ return bytes2 + Buffer.byteLength(renderReel(p, blank));
45340
+ };
45341
+ let current = { ...plan };
45342
+ let dropped = 0;
45343
+ const over = () => total(current) > budget;
45344
+ while (over() && current.frames.length > 2) {
45345
+ const next = thin(current.frames, Math.max(2, Math.floor(current.frames.length * 0.7)));
45346
+ dropped += current.frames.length - next.length;
45347
+ current = { ...current, frames: next };
45348
+ }
45349
+ for (let i = 0; i < current.postcards.length && over(); i++) {
45350
+ if (!current.postcards[i].files.length) continue;
45351
+ dropped += current.postcards[i].files.length;
45352
+ current = { ...current, postcards: current.postcards.map((c, j) => j === i ? { ...c, files: [] } : c) };
45353
+ }
45354
+ const order = current.finals.map((f, j) => ({ f, j })).filter(({ f }) => f.file).sort((a, b) => Number(a.f.id === current.focusId) - Number(b.f.id === current.focusId) || b.j - a.j);
45355
+ for (const { j } of order) {
45356
+ if (!over()) break;
45357
+ dropped++;
45358
+ current = { ...current, finals: current.finals.map((f, k) => k === j ? { ...f, file: null } : f) };
45359
+ }
45360
+ if (over() && current.frames.length > 1) {
45361
+ dropped += current.frames.length - 1;
45362
+ current = { ...current, frames: current.frames.slice(-1) };
45363
+ }
45364
+ const images = /* @__PURE__ */ new Map();
45365
+ for (const f of new Set(cited(current))) {
45366
+ if (sizeOf(f) === null) continue;
45367
+ const bytes2 = verified(f);
45368
+ if (!bytes2 || bytes2.length !== sizeOf(f)) continue;
45369
+ images.set(f, `data:${mimeOf(f)};base64,${bytes2.toString("base64")}`);
45370
+ }
45371
+ return { plan: { ...current, dropped }, images };
45372
+ }
45373
+ function duration(ms) {
45374
+ if (ms === null || !Number.isFinite(ms) || ms < 0) return "\u2014";
45375
+ const m = Math.round(ms / 6e4);
45376
+ return m < 60 ? `${m} min` : `${Math.floor(m / 60)} h ${m % 60} min`;
45377
+ }
45378
+ function utcDay(ts2) {
45379
+ const d = new Date(ts2);
45380
+ return Number.isNaN(d.getTime()) ? "" : `${d.toUTCString().slice(0, 16)} (UTC)`;
45381
+ }
45382
+ function sinceStart(start, ts2) {
45383
+ if (!start) return "";
45384
+ const s = Math.max(0, Math.round((Date.parse(ts2) - Date.parse(start)) / 1e3));
45385
+ const h = Math.floor(s / 3600);
45386
+ const m = Math.floor(s % 3600 / 60);
45387
+ const sec = String(s % 60).padStart(2, "0");
45388
+ return h ? `${h}:${String(m).padStart(2, "0")}:${sec}` : `${m}:${sec}`;
45389
+ }
45390
+ function renderReel(plan, images) {
45391
+ const img = (f, alt, cls = "") => f && images.has(f) ? `<img class="${cls}" src="${images.get(f)}" alt="${escapeHtml(alt)}">` : "";
45392
+ const count = (n) => escapeHtml(String(Number.isSafeInteger(n) && n >= 0 ? n : 0));
45393
+ const accent = ACCENT.test(plan.accent) ? plan.accent : DEFAULT_ACCENT;
45394
+ const clock = (ts2) => sinceStart(plan.startedAt, ts2);
45395
+ const frames = plan.frames.filter((f) => images.has(f.file));
45396
+ const flip = frames.length ? `<section class="flip"><div class="phone">${frames.map((f, i) => `<img class="fr${i === 0 ? " on" : ""}" src="${images.get(f.file)}" alt="${escapeHtml(plan.focusId ?? "")} at ${clock(f.ts)}">`).join("")}</div>
45397
+ <div class="flipcap"><div class="t" id="ft">${frames[0] ? clock(frames[0].ts) : ""}</div><div id="fc">${escapeHtml(frames[0]?.caption ?? "")}</div><div class="bar"><div id="fb"></div></div></div></section>` : `<p class="muted">No screen versions were recorded \u2014 open the build board with <code>himi studio</code> before building to capture them.</p>`;
45398
+ const data = JSON.stringify(frames.map((f) => ({ t: clock(f.ts), c: f.caption ?? "" }))).replace(/</g, "\\u003c");
45399
+ return `<!doctype html>
45400
+ <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
45401
+ <title>${escapeHtml(plan.app)} \xB7 the making of</title>
45402
+ <style>
45403
+ :root{--bg:#f6f5f2;--card:#fff;--ink:#1c1c1a;--muted:#6b6a64;--line:#e6e3dc;--accent:${accent}}
45404
+ @media (prefers-color-scheme:dark){:root{--bg:#121211;--card:#1c1c1a;--ink:#ecebe6;--muted:#a3a19a;--line:#2c2b28}}
45405
+ *{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
45406
+ .wrap{max-width:980px;margin:0 auto;padding:32px 20px 64px}h1{font-size:30px;margin:0 0 4px}h2{font-size:14px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin:40px 0 14px}
45407
+ .muted{color:var(--muted)}.stats{display:flex;gap:28px;flex-wrap:wrap;margin:18px 0 8px}.stats b{display:block;font-size:24px}
45408
+ .flip{display:flex;gap:28px;align-items:center;flex-wrap:wrap}.phone{position:relative;width:280px;aspect-ratio:390/844;border:10px solid #111;border-radius:38px;overflow:hidden;background:#fff;flex:none}
45409
+ .phone img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top;opacity:0;transition:opacity .35s}.phone img.on{opacity:1}
45410
+ .flipcap{flex:1;min-width:220px}.flipcap .t{font-size:40px;font-weight:700;font-variant-numeric:tabular-nums;color:var(--accent)}.bar{height:4px;background:var(--line);border-radius:2px;margin-top:16px}.bar div{height:4px;background:var(--accent);border-radius:2px;width:0}
45411
+ .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:18px}.grid figure{margin:0;text-align:center}.grid img{width:100%;aspect-ratio:390/844;object-fit:cover;object-position:top;border:6px solid #111;border-radius:22px;background:#fff}
45412
+ figcaption{font-size:12px;color:var(--muted);margin-top:6px;word-break:break-all}
45413
+ .log{list-style:none;padding:0;margin:0}.log li{display:flex;gap:14px;padding:12px 0;border-top:1px solid var(--line)}.log .t{min-width:52px;color:var(--muted);font-variant-numeric:tabular-nums}.log .s{font-size:12px;color:var(--muted);text-transform:capitalize}
45414
+ .log .imgs{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap}.log .imgs img{height:120px;border-radius:10px;border:1px solid var(--line)}
45415
+ footer{margin-top:48px;font-size:12px;color:var(--muted)}
45416
+ </style></head><body><div class="wrap">
45417
+ <h1>${escapeHtml(plan.app)}</h1><div class="muted">The making of \u2014 every version of the app as it was built${plan.startedAt ? `, ${escapeHtml(utcDay(plan.startedAt))}` : ""}</div>
45418
+ <div class="stats"><div><b>${duration(plan.stats.elapsedMs)}</b><span class="muted">from first picture to last</span></div><div><b>${count(plan.stats.screens)}</b><span class="muted">screens</span></div><div><b>${count(plan.stats.versions)}</b><span class="muted">versions rendered</span></div><div><b>${count(plan.stats.postcards)}</b><span class="muted">postcards</span></div></div>
45419
+ <h2>${escapeHtml(plan.focusId ?? "The app")}, version by version</h2>
45420
+ ${flip}
45421
+ <h2>Where it ended up</h2>
45422
+ <div class="grid">${plan.finals.map((f) => `<figure>${img(f.file, f.id)}<figcaption>${escapeHtml(f.id)}</figcaption></figure>`).join("")}</div>
45423
+ <h2>Postcards</h2>
45424
+ <ul class="log">${plan.postcards.map((c) => `<li><div class="t">${clock(c.ts)}</div><div><div>${escapeHtml(c.message)}</div>${c.step ? `<div class="s">step ${JOURNEY_STEPS.indexOf(c.step) + 1} \xB7 ${escapeHtml(c.step)}</div>` : ""}${c.files.length ? `<div class="imgs">${c.files.map((f) => img(f, c.message)).join("")}</div>` : ""}</div></li>`).join("") || `<li class="muted">No postcards were journaled.</li>`}</ul>
45425
+ <footer>Built with himi.${plan.dropped ? ` ${count(plan.dropped)} pictures were left out to keep this file small.` : ""}</footer>
45426
+ </div>
45427
+ <script>
45428
+ (function(){var F=${data};var imgs=document.querySelectorAll(".phone img");if(imgs.length<2)return;var i=0;
45429
+ function show(n){imgs[i].classList.remove("on");i=n;imgs[i].classList.add("on");document.getElementById("ft").textContent=F[i].t;document.getElementById("fc").textContent=F[i].c;document.getElementById("fb").style.width=(100*i/(imgs.length-1))+"%"}
45430
+ function tick(){show(i+1<imgs.length?i+1:0);setTimeout(tick,i+1<imgs.length?900:2500)}setTimeout(tick,1200);})();
45431
+ </script>
45432
+ </body></html>
45433
+ `;
45434
+ }
45435
+ function buildReel(dir, budget = REEL_BUDGET_BYTES) {
45436
+ const { plan, images } = inlineImages(dir, planReel(dir), budget);
45437
+ return { html: renderReel(plan, images), plan };
45438
+ }
45439
+ var REEL_BUDGET_BYTES, MAX_FLIP_FRAMES, DEFAULT_ACCENT, ACCENT, HISTORY_NAME, MIME2, mimeOf, readJson4, isObj, str, historyName, cited;
45440
+ var init_studio_reel = __esm({
45441
+ "src/studio-reel.ts"() {
45442
+ init_progress();
45443
+ init_studio();
45444
+ REEL_BUDGET_BYTES = 12 * 1024 * 1024;
45445
+ MAX_FLIP_FRAMES = 40;
45446
+ DEFAULT_ACCENT = "#3b6fd8";
45447
+ ACCENT = /^#[0-9a-f]{3,8}$/i;
45448
+ HISTORY_NAME = /^[0-9a-f]{64}\.(png|jpg|gif|webp)$/;
45449
+ MIME2 = { png: "image/png", jpg: "image/jpeg", gif: "image/gif", webp: "image/webp" };
45450
+ mimeOf = (file) => MIME2[file.slice(65)] ?? "image/png";
45451
+ readJson4 = (file) => {
45452
+ try {
45453
+ return JSON.parse(readFileSync52(file, "utf8"));
45454
+ } catch {
45455
+ return null;
45456
+ }
45457
+ };
45458
+ isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
45459
+ str = (v) => typeof v === "string" && v ? v : null;
45460
+ historyName = (sha, ext) => typeof sha === "string" && typeof ext === "string" && HISTORY_NAME.test(`${sha}.${ext}`) ? `${sha}.${ext}` : null;
45461
+ cited = (p) => [
45462
+ ...p.frames.map((f) => f.file),
45463
+ ...p.finals.flatMap((f) => f.file ? [f.file] : []),
45464
+ ...p.postcards.flatMap((c) => c.files)
45465
+ ];
45466
+ }
45467
+ });
45468
+
44925
45469
  // src/native-decode.ts
44926
45470
  var native_decode_exports = {};
44927
45471
  __export(native_decode_exports, {
@@ -44937,9 +45481,9 @@ __export(native_decode_exports, {
44937
45481
  runNativeDecode: () => runNativeDecode
44938
45482
  });
44939
45483
  import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
44940
- import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync52, rmSync as rmSync10, writeFileSync as writeFileSync20 } from "node:fs";
45484
+ import { existsSync as existsSync48, mkdtempSync as mkdtempSync2, readFileSync as readFileSync53, rmSync as rmSync10, writeFileSync as writeFileSync20 } from "node:fs";
44941
45485
  import { tmpdir as tmpdir3 } from "node:os";
44942
- import { join as join45 } from "node:path";
45486
+ import { join as join46 } from "node:path";
44943
45487
  import { fileURLToPath as fileURLToPath20 } from "node:url";
44944
45488
  function nativeDecodePackageDir() {
44945
45489
  return fileURLToPath20(new URL("../../../core/runtime/ios/HimalayaCore/", import.meta.url));
@@ -44949,8 +45493,8 @@ function nativeDecodeAndroidHarnessDir() {
44949
45493
  }
44950
45494
  function nativeOracleShipped() {
44951
45495
  return {
44952
- ios: existsSync48(join45(nativeDecodePackageDir(), "Package.swift")),
44953
- android: existsSync48(join45(nativeDecodeAndroidHarnessDir(), "gradlew"))
45496
+ ios: existsSync48(join46(nativeDecodePackageDir(), "Package.swift")),
45497
+ android: existsSync48(join46(nativeDecodeAndroidHarnessDir(), "gradlew"))
44954
45498
  };
44955
45499
  }
44956
45500
  function detectNativeDecode(options = {}) {
@@ -44961,7 +45505,7 @@ function detectNativeDecode(options = {}) {
44961
45505
  return { platform: "ios", available: false, reason: `the iOS decoder oracle requires macOS (darwin); this host is ${hostPlatform}` };
44962
45506
  }
44963
45507
  if (!swiftAvailable) return { platform: "ios", available: false, reason: "swift is not on PATH" };
44964
- const packageAvailable = options.packageAvailable ?? existsSync48(join45(packageDir, "Package.swift"));
45508
+ const packageAvailable = options.packageAvailable ?? existsSync48(join46(packageDir, "Package.swift"));
44965
45509
  if (!packageAvailable) {
44966
45510
  return {
44967
45511
  platform: "ios",
@@ -44973,7 +45517,7 @@ function detectNativeDecode(options = {}) {
44973
45517
  }
44974
45518
  function localPropertiesSdk(harnessDir) {
44975
45519
  try {
44976
- const match = readFileSync52(join45(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
45520
+ const match = readFileSync53(join46(harnessDir, "local.properties"), "utf8").match(/^sdk\.dir\s*=\s*(.+)$/m);
44977
45521
  return match?.[1]?.trim().replace(/\\([ :\\])/g, "$1") ?? null;
44978
45522
  } catch {
44979
45523
  return null;
@@ -44981,7 +45525,7 @@ function localPropertiesSdk(harnessDir) {
44981
45525
  }
44982
45526
  function detectAndroidNativeDecode(options = {}) {
44983
45527
  const harnessDir = options.harnessDir ?? nativeDecodeAndroidHarnessDir();
44984
- const gradlew = join45(harnessDir, "gradlew");
45528
+ const gradlew = join46(harnessDir, "gradlew");
44985
45529
  const gradlewAvailable = options.gradlewAvailable ?? existsSync48(gradlew);
44986
45530
  if (!gradlewAvailable) {
44987
45531
  return {
@@ -45064,14 +45608,14 @@ function parseNativeDecodeOutput(stdout, expectedScreenIds, platform = "ios") {
45064
45608
  return verdicts;
45065
45609
  }
45066
45610
  function runNativeDecode(options) {
45067
- const descriptorDir = mkdtempSync2(join45(tmpdir3(), "himi-native-decode-"));
45611
+ const descriptorDir = mkdtempSync2(join46(tmpdir3(), "himi-native-decode-"));
45068
45612
  const startedAt = Date.now();
45069
45613
  try {
45070
45614
  for (const descriptor of options.descriptors) {
45071
45615
  if (typeof descriptor.descriptorJson !== "string") {
45072
45616
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
45073
45617
  }
45074
- writeFileSync20(join45(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
45618
+ writeFileSync20(join46(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
45075
45619
  }
45076
45620
  options.progress?.("building cached Swift oracle");
45077
45621
  execFileSync5("swift", ["build", "--package-path", options.packageDir, "--product", "himi-decode-oracle"], {
@@ -45083,7 +45627,7 @@ function runNativeDecode(options) {
45083
45627
  encoding: "utf8"
45084
45628
  }).trim();
45085
45629
  options.progress?.(`running real Swift decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
45086
- const stdout = execFileSync5(join45(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
45630
+ const stdout = execFileSync5(join46(binPath, "himi-decode-oracle"), ["--dir", descriptorDir], {
45087
45631
  stdio: ["ignore", "pipe", "pipe"],
45088
45632
  encoding: "utf8"
45089
45633
  });
@@ -45101,15 +45645,15 @@ function runNativeDecode(options) {
45101
45645
  }
45102
45646
  }
45103
45647
  function runAndroidNativeDecode(options) {
45104
- const descriptorDir = mkdtempSync2(join45(tmpdir3(), "himi-native-decode-android-"));
45105
- const outputPath = join45(descriptorDir, "verdicts.ndjson");
45648
+ const descriptorDir = mkdtempSync2(join46(tmpdir3(), "himi-native-decode-android-"));
45649
+ const outputPath = join46(descriptorDir, "verdicts.ndjson");
45106
45650
  const startedAt = Date.now();
45107
45651
  try {
45108
45652
  for (const descriptor of options.descriptors) {
45109
45653
  if (typeof descriptor.descriptorJson !== "string") {
45110
45654
  throw new Error(`native decode cannot judge ${descriptor.screenId}: the release builder did not return its exact baked JSON bytes`);
45111
45655
  }
45112
- writeFileSync20(join45(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
45656
+ writeFileSync20(join46(descriptorDir, `${encodeURIComponent(descriptor.screenId)}.json`), descriptor.descriptorJson);
45113
45657
  }
45114
45658
  options.progress?.(`running real Kotlin decoder over ${options.descriptors.length} screen${options.descriptors.length === 1 ? "" : "s"}`);
45115
45659
  execFileSync5(options.gradlew, [
@@ -45124,7 +45668,7 @@ function runAndroidNativeDecode(options) {
45124
45668
  stdio: ["ignore", "ignore", "pipe"],
45125
45669
  encoding: "utf8"
45126
45670
  });
45127
- const stdout = readFileSync52(outputPath, "utf8");
45671
+ const stdout = readFileSync53(outputPath, "utf8");
45128
45672
  return {
45129
45673
  platform: "android",
45130
45674
  verdicts: parseNativeDecodeOutput(stdout, options.descriptors.map((descriptor) => descriptor.screenId), "android"),
@@ -45193,14 +45737,14 @@ __export(browser_authoring_exports, {
45193
45737
  sdkSubpathReader: () => sdkSubpathReader
45194
45738
  });
45195
45739
  import { createServer as createServer3 } from "node:http";
45196
- import { createHash as createHash24, randomBytes as randomBytes4 } from "node:crypto";
45197
- import { existsSync as existsSync49, readdirSync as readdirSync24, readFileSync as readFileSync53, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
45198
- import { join as join46, posix, relative as relative8, sep as sep12 } from "node:path";
45740
+ import { createHash as createHash25, randomBytes as randomBytes4 } from "node:crypto";
45741
+ import { existsSync as existsSync49, readdirSync as readdirSync24, readFileSync as readFileSync54, realpathSync as realpathSync5, statSync as statSync12 } from "node:fs";
45742
+ import { join as join47, posix, relative as relative8, sep as sep12 } from "node:path";
45199
45743
  function humanMs(ms) {
45200
45744
  return ms < 1e3 ? `${ms}ms` : `${Math.round(ms / 1e3)}s`;
45201
45745
  }
45202
45746
  function collectWorkerSources(tier5SrcDir, bundleName) {
45203
- const root = join46(tier5SrcDir, bundleName);
45747
+ const root = join47(tier5SrcDir, bundleName);
45204
45748
  const files = {};
45205
45749
  const visitedDirs = /* @__PURE__ */ new Set();
45206
45750
  const walk2 = (abs, rel) => {
@@ -45208,12 +45752,12 @@ function collectWorkerSources(tier5SrcDir, bundleName) {
45208
45752
  if (visitedDirs.has(real)) return;
45209
45753
  visitedDirs.add(real);
45210
45754
  for (const name of readdirSync24(abs).sort()) {
45211
- const childAbs = join46(abs, name);
45755
+ const childAbs = join47(abs, name);
45212
45756
  const childRel = posix.join(rel, name);
45213
45757
  if (statSync12(childAbs).isDirectory()) {
45214
45758
  walk2(childAbs, childRel);
45215
45759
  } else if (/\.(ts|tsx|js|mjs|json)$/.test(name)) {
45216
- files[childRel] = readFileSync53(childAbs, "utf8");
45760
+ files[childRel] = readFileSync54(childAbs, "utf8");
45217
45761
  }
45218
45762
  }
45219
45763
  };
@@ -45234,20 +45778,20 @@ function collectRelativeSiblings(files, tier5SrcDir) {
45234
45778
  const spec = m[1];
45235
45779
  const virtual = posix.normalize(posix.join(dir, spec));
45236
45780
  if (!virtual.startsWith("/tier5-src/")) continue;
45237
- const onDisk = join46(tier5SrcDir, virtual.slice("/tier5-src/".length));
45781
+ const onDisk = join47(tier5SrcDir, virtual.slice("/tier5-src/".length));
45238
45782
  const candidates = [
45239
45783
  onDisk,
45240
45784
  `${onDisk}.ts`,
45241
45785
  `${onDisk}.js`,
45242
45786
  onDisk.replace(/\.js$/, ".ts"),
45243
- join46(onDisk, "index.ts"),
45244
- join46(onDisk, "index.js")
45787
+ join47(onDisk, "index.ts"),
45788
+ join47(onDisk, "index.js")
45245
45789
  ];
45246
45790
  for (const abs of candidates) {
45247
45791
  if (!existsSync49(abs) || statSync12(abs).isDirectory()) continue;
45248
45792
  const key2 = `/tier5-src/${relative8(tier5SrcDir, abs).split(sep12).join(posix.sep)}`;
45249
45793
  if (key2 in files) break;
45250
- files[key2] = readFileSync53(abs, "utf8");
45794
+ files[key2] = readFileSync54(abs, "utf8");
45251
45795
  queue.push(key2);
45252
45796
  break;
45253
45797
  }
@@ -45282,7 +45826,7 @@ function collectSdkModules(files, resolveSubpath) {
45282
45826
  function sdkSubpathReader(resolve48) {
45283
45827
  return (sub) => {
45284
45828
  try {
45285
- return readFileSync53(resolve48(`@wix/himalaya/${sub}`), "utf8");
45829
+ return readFileSync54(resolve48(`@wix/himalaya/${sub}`), "utf8");
45286
45830
  } catch {
45287
45831
  return null;
45288
45832
  }
@@ -45292,7 +45836,7 @@ function encodeJob(job) {
45292
45836
  return Buffer.from(JSON.stringify(job), "utf8").toString("base64");
45293
45837
  }
45294
45838
  function mintToken2(payload, nonce = randomBytes4(16).toString("hex")) {
45295
- const digest2 = createHash24("sha256").update(payload, "utf8").digest("base64url");
45839
+ const digest2 = createHash25("sha256").update(payload, "utf8").digest("base64url");
45296
45840
  return `${nonce}.${digest2}`;
45297
45841
  }
45298
45842
  function defaultOpenBrowser2(url) {
@@ -45454,8 +45998,8 @@ __export(coverage_exports, {
45454
45998
  suppressedNativeKeys: () => suppressedNativeKeys,
45455
45999
  trendAndStore: () => trendAndStore
45456
46000
  });
45457
- import { existsSync as existsSync50, mkdirSync as mkdirSync24, readFileSync as readFileSync54, writeFileSync as writeFileSync21 } from "node:fs";
45458
- import { dirname as dirname26, join as join47 } from "node:path";
46001
+ import { existsSync as existsSync50, mkdirSync as mkdirSync24, readFileSync as readFileSync55, writeFileSync as writeFileSync21 } from "node:fs";
46002
+ import { dirname as dirname26, join as join48 } from "node:path";
45459
46003
  function suppressedNativeKeys(oracle) {
45460
46004
  return [...oracle.ios ? [] : ["native-decode|ios"], ...oracle.android ? [] : ["native-decode|android"]];
45461
46005
  }
@@ -45516,15 +46060,15 @@ function assembleLedger(r, options = {}) {
45516
46060
  remedy: SOURCEMAP_REMEDY[c.sourcemap]
45517
46061
  });
45518
46062
  }
45519
- const own2 = (c.uncoveredFunctions ?? []).filter((f) => f.source?.startsWith("tier5-src/") || f.source?.startsWith("core/dev-server/tier5-bundles-src/"));
45520
- if (!own2.length) continue;
45521
- const named = own2.slice(0, 6).map((f) => `${f.name} (${f.source})`).join(", ");
45522
- const more = own2.length > 6 ? ` +${own2.length - 6} more` : "";
46063
+ const own3 = (c.uncoveredFunctions ?? []).filter((f) => f.source?.startsWith("tier5-src/") || f.source?.startsWith("core/dev-server/tier5-bundles-src/"));
46064
+ if (!own3.length) continue;
46065
+ const named = own3.slice(0, 6).map((f) => `${f.name} (${f.source})`).join(", ");
46066
+ const more = own3.length > 6 ? ` +${own3.length - 6} more` : "";
45523
46067
  out.push({
45524
46068
  key: `code-uncovered|${c.screen}`,
45525
46069
  kind: "code-uncovered",
45526
46070
  screen: c.screen,
45527
- gap: `${own2.length} worker function${own2.length === 1 ? "" : "s"} never executed on any axis: ${named}${more}`,
46071
+ gap: `${own3.length} worker function${own3.length === 1 ? "" : "s"} never executed on any axis: ${named}${more}`,
45528
46072
  remedy: "usually an error/edge branch \u2014 give the crawl data that reaches it (a net-mocks rule, cms seed rows, or a nav edge with the right input), or verify the path on a preview"
45529
46073
  });
45530
46074
  }
@@ -45625,11 +46169,11 @@ function assembleLedger(r, options = {}) {
45625
46169
  return out;
45626
46170
  }
45627
46171
  function trendAndStore(dir, entries, suppressed) {
45628
- const p = join47(dir, LEDGER_FILE);
46172
+ const p = join48(dir, LEDGER_FILE);
45629
46173
  let previous = null;
45630
46174
  try {
45631
46175
  if (existsSync50(p)) {
45632
- const parsed = JSON.parse(readFileSync54(p, "utf8"));
46176
+ const parsed = JSON.parse(readFileSync55(p, "utf8"));
45633
46177
  if (Array.isArray(parsed.keys)) previous = parsed.keys.filter((k) => typeof k === "string");
45634
46178
  }
45635
46179
  } catch {
@@ -45668,11 +46212,11 @@ function formatLedger(entries, trend) {
45668
46212
  return out.join("\n");
45669
46213
  }
45670
46214
  function diffAndStoreObservations(dir, current) {
45671
- const p = join47(dir, OBS_FILE);
46215
+ const p = join48(dir, OBS_FILE);
45672
46216
  let previous = null;
45673
46217
  try {
45674
46218
  if (existsSync50(p)) {
45675
- const parsed = JSON.parse(readFileSync54(p, "utf8"));
46219
+ const parsed = JSON.parse(readFileSync55(p, "utf8"));
45676
46220
  if (parsed.screens && typeof parsed.screens === "object" && !Array.isArray(parsed.screens) && Object.values(parsed.screens).every(
45677
46221
  (v) => Array.isArray(v) && v.every((l) => typeof l === "string")
45678
46222
  )) {
@@ -45721,8 +46265,8 @@ var LEDGER_FILE, OBS_FILE;
45721
46265
  var init_coverage = __esm({
45722
46266
  "src/coverage.ts"() {
45723
46267
  init_native_decode();
45724
- LEDGER_FILE = join47(".himi", "test-ledger.json");
45725
- OBS_FILE = join47(".himi", "test-observations.json");
46268
+ LEDGER_FILE = join48(".himi", "test-ledger.json");
46269
+ OBS_FILE = join48(".himi", "test-observations.json");
45726
46270
  }
45727
46271
  });
45728
46272
 
@@ -45733,8 +46277,8 @@ __export(design_kits_exports, {
45733
46277
  kitsDir: () => kitsDir,
45734
46278
  listKits: () => listKits2
45735
46279
  });
45736
- import { existsSync as existsSync51, readFileSync as readFileSync55, readdirSync as readdirSync25 } from "node:fs";
45737
- import { join as join48, basename as basename11 } from "node:path";
46280
+ import { existsSync as existsSync51, readFileSync as readFileSync56, readdirSync as readdirSync25 } from "node:fs";
46281
+ import { join as join49, basename as basename12 } from "node:path";
45738
46282
  import { fileURLToPath as fileURLToPath21 } from "node:url";
45739
46283
  function kitsDir() {
45740
46284
  return KIT_DIR_CANDIDATES.find((p) => existsSync51(p));
@@ -45742,7 +46286,7 @@ function kitsDir() {
45742
46286
  function listKits2() {
45743
46287
  const dir = kitsDir();
45744
46288
  if (!dir) return [];
45745
- return readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) => basename11(f, ".json")).sort();
46289
+ return readdirSync25(dir).filter((f) => f.endsWith(".json")).map((f) => basename12(f, ".json")).sort();
45746
46290
  }
45747
46291
  function kitReport(name) {
45748
46292
  const dir = kitsDir();
@@ -45761,7 +46305,7 @@ In a published @wix/himalaya-cli this is a packaging bug \u2014 the kits should
45761
46305
  if (!kits.includes(name)) {
45762
46306
  return { ok: false, kit: name, kits, problems: [`no design kit named "${name}". Available: ${kits.join(", ")}`] };
45763
46307
  }
45764
- const raw = readFileSync55(join48(dir, `${name}.json`), "utf8");
46308
+ const raw = readFileSync56(join49(dir, `${name}.json`), "utf8");
45765
46309
  let parsed;
45766
46310
  try {
45767
46311
  parsed = JSON.parse(raw);
@@ -45785,9 +46329,9 @@ var init_design_kits = __esm({
45785
46329
  "src/design-kits.ts"() {
45786
46330
  KIT_DIR_CANDIDATES = [
45787
46331
  // in-repo: tools/himi-cli/src/design-kits.ts → <repo>/stdlib/design-kits/
45788
- join48(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
46332
+ join49(fileURLToPath21(new URL("../../..", import.meta.url)), "stdlib", "design-kits"),
45789
46333
  // published CLI: <pkg>/dist/cli.mjs → <pkg>/stdlib/design-kits/
45790
- join48(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
46334
+ join49(fileURLToPath21(new URL("..", import.meta.url)), "stdlib", "design-kits")
45791
46335
  ];
45792
46336
  }
45793
46337
  });
@@ -45801,11 +46345,11 @@ __export(assets_exports, {
45801
46345
  removeAssetPayload: () => removeAssetPayload,
45802
46346
  verifyReport: () => verifyReport
45803
46347
  });
45804
- import { readFileSync as readFileSync56 } from "node:fs";
45805
- import { basename as basename12 } from "node:path";
46348
+ import { readFileSync as readFileSync57 } from "node:fs";
46349
+ import { basename as basename13 } from "node:path";
45806
46350
  function declaredAssets(dir) {
45807
46351
  return collectAssets(dir).map((a) => {
45808
- const bytes2 = readFileSync56(a.path);
46352
+ const bytes2 = readFileSync57(a.path);
45809
46353
  return {
45810
46354
  name: a.name,
45811
46355
  sha256: assetSha256(bytes2),
@@ -45882,8 +46426,8 @@ function verifyReport(dir, app, manifest) {
45882
46426
  };
45883
46427
  }
45884
46428
  function addAssetPayload(manifest, filePath, opts) {
45885
- const bytes2 = readFileSync56(filePath);
45886
- const name = opts.name ?? basename12(filePath);
46429
+ const bytes2 = readFileSync57(filePath);
46430
+ const name = opts.name ?? basename13(filePath);
45887
46431
  const sha2565 = assetSha256(bytes2);
45888
46432
  const record2 = {
45889
46433
  sha256: sha2565,
@@ -46767,12 +47311,13 @@ ${releaseId}`;
46767
47311
  const bytes2 = await store.getSource(app, m.sourceHash);
46768
47312
  if (!bytes2) return json3(404, { error: "template_source_not_found", app });
46769
47313
  const etag = `"${m.sourceHash}"`;
47314
+ const cache = { "cache-control": pin ? PINNED_CACHE_CONTROL : DOC_CACHE_CONTROL, ...pin ? { vary: "x-himalaya-release" } : {} };
46770
47315
  if (request.headers.get("if-none-match") === etag) {
46771
- return new Response(null, { status: 304, headers: { etag, "cache-control": DOC_CACHE_CONTROL } });
47316
+ return new Response(null, { status: 304, headers: { etag, ...cache } });
46772
47317
  }
46773
47318
  return new Response(bytes2, {
46774
47319
  status: 200,
46775
- headers: { "content-type": JSON_CT, etag, "cache-control": DOC_CACHE_CONTROL, "x-himalaya-app": app }
47320
+ headers: { "content-type": JSON_CT, etag, ...cache, "x-himalaya-app": app }
46776
47321
  });
46777
47322
  }
46778
47323
  if (path2 === "/v1/authoring-docs" || /^\/v1\/authoring-docs\/(spec|mobile-ux)$/.test(path2)) {
@@ -47449,19 +47994,19 @@ var init_preview_assets_generated = __esm({
47449
47994
  "../../packages/serve/src/preview-assets.generated.ts"() {
47450
47995
  init_preview_assets_format();
47451
47996
  PREVIEW_ASSET_MANIFEST = [
47452
- { key: "assets/index-TpXF5JLO.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1013412, sha256: "e6d1da59c13ca586b7834f4d08ca9e136b7fea8be9355d952d757fc66fc779a5" },
47453
- { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1013420, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
47454
- { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1104344, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
47455
- { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1195328, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
47456
- { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1286308, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
47457
- { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1377180, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
47458
- { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1468160, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
47459
- { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1576796, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
47460
- { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1685880, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
47461
- { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1794928, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
47462
- { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1902628, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
47463
- { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1990736, length: 4448, sha256: "5f0ee56640a5dfc73d3b2b78526aa1f7966de1bec39fe746e0d9ba39d57d829e" },
47464
- { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1995184, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
47997
+ { key: "assets/index-DH7r6zgZ.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1016081, sha256: "da605bbde6f416c275340836d0b6d327478e5d067c24905a46274d18c1b00b98" },
47998
+ { key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1016089, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
47999
+ { key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1107013, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
48000
+ { key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1197997, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
48001
+ { key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1288977, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
48002
+ { key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 1379849, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
48003
+ { key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 1470829, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
48004
+ { key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 1579465, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
48005
+ { key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 1688549, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
48006
+ { key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 1797597, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
48007
+ { key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 1905297, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
48008
+ { key: "index.html", contentType: "text/html; charset=utf-8", offset: 1993405, length: 4448, sha256: "ce170a0a2ee86aac30f70b5468e744898c697fb5f46c685ebc5d83b4402b22db" },
48009
+ { key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 1997853, length: 17209, sha256: "dffc9718e2faa63ae2cc919e0a842f585ed565aaaa7c53778e90379442c731b6" }
47465
48010
  ];
47466
48011
  }
47467
48012
  });
@@ -47477,9 +48022,9 @@ __export(run_exports, {
47477
48022
  runPackage: () => runPackage,
47478
48023
  withoutProdServe: () => withoutProdServe
47479
48024
  });
47480
- import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync57, rmSync as rmSync11, statSync as statSync13 } from "node:fs";
48025
+ import { cpSync as cpSync2, existsSync as existsSync52, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync3, readFileSync as readFileSync58, rmSync as rmSync11, statSync as statSync13 } from "node:fs";
47481
48026
  import { tmpdir as tmpdir4 } from "node:os";
47482
- import { dirname as dirname27, join as join49 } from "node:path";
48027
+ import { dirname as dirname27, join as join50 } from "node:path";
47483
48028
  import { fileURLToPath as fileURLToPath22 } from "node:url";
47484
48029
  function makePackageRunHandler(opts) {
47485
48030
  return makeRunHandler({
@@ -47499,7 +48044,7 @@ async function fetchBytes(url) {
47499
48044
  async function resolvePackage(source, workDir) {
47500
48045
  const isUrl2 = /^https?:\/\//i.test(source);
47501
48046
  if (!isUrl2 && existsSync52(source) && statSync13(source).isDirectory()) {
47502
- const appDirManifest = join49(source, "release-manifest.json");
48047
+ const appDirManifest = join50(source, "release-manifest.json");
47503
48048
  if (existsSync52(appDirManifest)) {
47504
48049
  const opened2 = openPackageDir(source);
47505
48050
  if (!opened2.validation.ok) {
@@ -47509,9 +48054,9 @@ async function resolvePackage(source, workDir) {
47509
48054
  const app2 = opened2.header?.app ?? opened2.manifest?.app;
47510
48055
  if (!app2) throw new Error(`${source} has no app id (no himi-package.json and no manifest.app)`);
47511
48056
  if (!isSafeAppId(app2)) throw new Error(`${source} declares an unsafe app id ${JSON.stringify(app2)} \u2014 refusing to open it`);
47512
- const root2 = workDir ?? mkdtempSync3(join49(tmpdir4(), "himi-run-"));
47513
- const target = join49(root2, app2);
47514
- if (join49(source) !== target) {
48057
+ const root2 = workDir ?? mkdtempSync3(join50(tmpdir4(), "himi-run-"));
48058
+ const target = join50(root2, app2);
48059
+ if (join50(source) !== target) {
47515
48060
  mkdirSync25(root2, { recursive: true });
47516
48061
  rmSync11(target, { recursive: true, force: true });
47517
48062
  cpSync2(source, target, { recursive: true });
@@ -47528,8 +48073,8 @@ async function resolvePackage(source, workDir) {
47528
48073
  }
47529
48074
  throw new Error(`${source} is a directory but has no release-manifest.json \u2014 is it a package?`);
47530
48075
  }
47531
- const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync57(source);
47532
- const root = workDir ?? mkdtempSync3(join49(tmpdir4(), "himi-run-"));
48076
+ const bytes2 = isUrl2 ? await fetchBytes(source) : readFileSync58(source);
48077
+ const root = workDir ?? mkdtempSync3(join50(tmpdir4(), "himi-run-"));
47533
48078
  const { app, appDir: appDir2 } = unpackTo(bytes2, root);
47534
48079
  const opened = openPackageDir(appDir2);
47535
48080
  if (!opened.validation.ok) {
@@ -47552,14 +48097,14 @@ async function loadPreviewAssets() {
47552
48097
  const mod = await Promise.resolve().then(() => (init_preview_assets_generated(), preview_assets_generated_exports));
47553
48098
  const here = dirname27(fileURLToPath22(import.meta.url));
47554
48099
  const candidates = [
47555
- join49(here, "preview-assets.generated.bin"),
48100
+ join50(here, "preview-assets.generated.bin"),
47556
48101
  // published: copied next to the bundled CLI
47557
- join49(here, "../../../packages/serve/src/preview-assets.generated.bin")
48102
+ join50(here, "../../../packages/serve/src/preview-assets.generated.bin")
47558
48103
  // in-repo checkout
47559
48104
  ];
47560
48105
  for (const path2 of candidates) {
47561
48106
  if (!existsSync52(path2)) continue;
47562
- const blob = readFileSync57(path2);
48107
+ const blob = readFileSync58(path2);
47563
48108
  return mod.assemblePreviewAssetsFromBlob(new Uint8Array(blob.buffer, blob.byteOffset, blob.byteLength));
47564
48109
  }
47565
48110
  return /* @__PURE__ */ new Map();
@@ -47654,9 +48199,9 @@ __export(run_watch_exports, {
47654
48199
  watchedContentDir: () => watchedContentDir,
47655
48200
  writeRunRecord: () => writeRunRecord
47656
48201
  });
47657
- import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync7, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync58, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as rmSync12, writeFileSync as writeFileSync22, watch as fsWatch } from "node:fs";
48202
+ import { closeSync as closeSync2, constants, existsSync as existsSync53, fstatSync, lstatSync as lstatSync8, statSync as statSync14, mkdirSync as mkdirSync26, openSync as openSync2, readFileSync as readFileSync59, realpathSync as realpathSync6, renameSync as renameSync5, rmSync as rmSync12, writeFileSync as writeFileSync22, watch as fsWatch } from "node:fs";
47658
48203
  import { randomUUID as randomUUID3 } from "node:crypto";
47659
- import { extname as extname4, join as join50, resolve as resolve42, sep as sep13 } from "node:path";
48204
+ import { extname as extname4, join as join51, resolve as resolve42, sep as sep13 } from "node:path";
47660
48205
  function diffReleases(prev, next) {
47661
48206
  const bundles = Object.keys(next.bundles).filter((b) => prev.bundles[b]?.sha256 !== next.bundles[b].sha256).sort();
47662
48207
  const changedBundles = new Set(bundles);
@@ -47696,7 +48241,7 @@ function watchContent(dir, onChange, opts = {}) {
47696
48241
  let timer = null;
47697
48242
  const pending = /* @__PURE__ */ new Set();
47698
48243
  const watcher = watch2(dir, { recursive: true }, (_event, file) => {
47699
- if (!file || ignoredChange(file, (rel) => isDir(join50(dir, rel)))) return;
48244
+ if (!file || ignoredChange(file, (rel) => isDir(join51(dir, rel)))) return;
47700
48245
  pending.add(file);
47701
48246
  if (timer) clearTimeout(timer);
47702
48247
  timer = setTimeout(() => {
@@ -47717,7 +48262,7 @@ function watchedContentDir(source) {
47717
48262
  if (!source || /^https?:\/\//i.test(source)) return null;
47718
48263
  const dir = resolve42(source);
47719
48264
  try {
47720
- return statSync14(dir).isDirectory() && existsSync53(join50(dir, "himalaya.content.json")) ? dir : null;
48265
+ return statSync14(dir).isDirectory() && existsSync53(join51(dir, "himalaya.content.json")) ? dir : null;
47721
48266
  } catch {
47722
48267
  return null;
47723
48268
  }
@@ -47774,23 +48319,23 @@ function serialize(task) {
47774
48319
  });
47775
48320
  }
47776
48321
  function himiDir(dir) {
47777
- const root = join50(dir, ".himi");
48322
+ const root = join51(dir, ".himi");
47778
48323
  try {
47779
- return lstatSync7(root).isDirectory() ? root : null;
48324
+ return lstatSync8(root).isDirectory() ? root : null;
47780
48325
  } catch (e) {
47781
48326
  if (e.code !== "ENOENT") return null;
47782
48327
  mkdirSync26(root, { recursive: true });
47783
- return lstatSync7(root).isDirectory() ? root : null;
48328
+ return lstatSync8(root).isDirectory() ? root : null;
47784
48329
  }
47785
48330
  }
47786
48331
  function writeRunRecord(dir, record2) {
47787
48332
  const root = himiDir(dir);
47788
48333
  if (!root) return false;
47789
- const tmp = join50(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
48334
+ const tmp = join51(root, `.run.json.${process.pid}.${randomUUID3()}.tmp`);
47790
48335
  try {
47791
48336
  writeFileSync22(tmp, `${JSON.stringify(record2, null, 2)}
47792
48337
  `, { flag: "wx" });
47793
- renameSync5(tmp, join50(root, "run.json"));
48338
+ renameSync5(tmp, join51(root, "run.json"));
47794
48339
  } catch (e) {
47795
48340
  rmSync12(tmp, { force: true });
47796
48341
  throw e;
@@ -47798,21 +48343,21 @@ function writeRunRecord(dir, record2) {
47798
48343
  return true;
47799
48344
  }
47800
48345
  function removeRunRecord(dir) {
47801
- const root = join50(dir, ".himi");
48346
+ const root = join51(dir, ".himi");
47802
48347
  try {
47803
- if (!lstatSync7(root).isDirectory()) return;
48348
+ if (!lstatSync8(root).isDirectory()) return;
47804
48349
  } catch {
47805
48350
  return;
47806
48351
  }
47807
- rmSync12(join50(root, "run.json"), { force: true });
48352
+ rmSync12(join51(root, "run.json"), { force: true });
47808
48353
  }
47809
48354
  function boardFile(dir, pathname) {
47810
48355
  let rel = null;
47811
- if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join50("studio", "index.html");
47812
- else if (pathname === "/__himi/studio/state.js") rel = join50("studio", "state.js");
48356
+ if (pathname === "/__himi/studio/" || pathname === "/__himi/studio/index.html") rel = join51("studio", "index.html");
48357
+ else if (pathname === "/__himi/studio/state.js") rel = join51("studio", "state.js");
47813
48358
  else {
47814
48359
  const m = /^\/__himi\/history\/([0-9a-f]{64}\.(png|jpg|gif|webp))$/.exec(pathname);
47815
- if (m) rel = join50("history", m[1]);
48360
+ if (m) rel = join51("history", m[1]);
47816
48361
  }
47817
48362
  if (!rel) return null;
47818
48363
  const bytes2 = readConfined(resolve42(dir, ".himi"), rel);
@@ -47824,12 +48369,12 @@ function boardFile(dir, pathname) {
47824
48369
  }
47825
48370
  function readConfined(root, rel) {
47826
48371
  try {
47827
- if (!lstatSync7(root).isDirectory()) return null;
48372
+ if (!lstatSync8(root).isDirectory()) return null;
47828
48373
  const parts = rel.split(sep13);
47829
48374
  let at = root;
47830
48375
  for (let i = 0; i < parts.length; i++) {
47831
- at = join50(at, parts[i]);
47832
- const st = lstatSync7(at);
48376
+ at = join51(at, parts[i]);
48377
+ const st = lstatSync8(at);
47833
48378
  if (st.isSymbolicLink() || !(i === parts.length - 1 ? st.isFile() : st.isDirectory())) return null;
47834
48379
  }
47835
48380
  const canonicalRoot = realpathSync6(root);
@@ -47837,7 +48382,7 @@ function readConfined(root, rel) {
47837
48382
  const fd = openSync2(at, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
47838
48383
  try {
47839
48384
  if (!fstatSync(fd).isFile()) return null;
47840
- return readFileSync58(fd);
48385
+ return readFileSync59(fd);
47841
48386
  } finally {
47842
48387
  closeSync2(fd);
47843
48388
  }
@@ -47888,7 +48433,7 @@ __export(run_browser_exports, {
47888
48433
  runInBrowser: () => runInBrowser
47889
48434
  });
47890
48435
  import { createServer as createServer5 } from "node:http";
47891
- import { existsSync as existsSync54, readFileSync as readFileSync59 } from "node:fs";
48436
+ import { existsSync as existsSync54, readFileSync as readFileSync60 } from "node:fs";
47892
48437
  import { spawnSync as spawnSync3 } from "node:child_process";
47893
48438
  import { dirname as dirname28, resolve as resolve43 } from "node:path";
47894
48439
  import { fileURLToPath as fileURLToPath23 } from "node:url";
@@ -47996,7 +48541,7 @@ async function runInBrowser(releaseRoot, app, header, opts = {}) {
47996
48541
  }
47997
48542
  let bytes2;
47998
48543
  try {
47999
- bytes2 = readFileSync59(resolve43(stagedDir(), name));
48544
+ bytes2 = readFileSync60(resolve43(stagedDir(), name));
48000
48545
  } catch (e) {
48001
48546
  res.writeHead(503, { "content-type": "application/json" });
48002
48547
  res.end(JSON.stringify({ error: "browser_plane_unstaged", file: name, detail: String(e) }));
@@ -48109,13 +48654,13 @@ async function runWixMobileRelease(pos, flags, io, deps) {
48109
48654
  };
48110
48655
  if (invokedAs !== "testflight" && !(invokedAs === "store" && pos[1] === "upload")) return fail2("Wix Mobile Release only supports `himi testflight <app>` or `himi store upload <app>`");
48111
48656
  if (app !== "himi-player") return fail2("Wix Mobile Release is reserved for the Wix-owned Himi Player binary", { app });
48112
- if (str(flags.artifact)) return fail2("--artifact is not accepted for Himi Player; pass --release so deployed serve can validate the Job Service IPA and call MRE with its service identity");
48657
+ if (str2(flags.artifact)) return fail2("--artifact is not accepted for Himi Player; pass --release so deployed serve can validate the Job Service IPA and call MRE with its service identity");
48113
48658
  if (on(flags["no-wait"])) return fail2("--no-wait is not supported for Himi Player TestFlight releases; wait for MRE processing to complete");
48114
- const release = str(flags.release);
48115
- const version2 = str(flags.version);
48659
+ const release = str2(flags.release);
48660
+ const version2 = str2(flags.version);
48116
48661
  if (!release) return fail2("--release is required for a Himi Player TestFlight release");
48117
48662
  if (!version2 || !/^\d+(?:\.\d+){0,2}$/.test(version2)) return fail2("--version needs the Player marketing version (for example 1.0.0)");
48118
- if (str(flags.track) && str(flags.track) !== "testflight" && str(flags.track) !== "internal") return fail2("Wix Mobile Release only supports TestFlight upload; public App Store release remains a separate human step");
48663
+ if (str2(flags.track) && str2(flags.track) !== "testflight" && str2(flags.track) !== "internal") return fail2("Wix Mobile Release only supports TestFlight upload; public App Store release remains a separate human step");
48119
48664
  const plan = {
48120
48665
  ok: true,
48121
48666
  dryRun: on(flags["dry-run"]),
@@ -48148,10 +48693,10 @@ async function runWixMobileRelease(pos, flags, io, deps) {
48148
48693
  return fail2(`could not complete the Himi Player TestFlight Job Service release: ${error.message}`);
48149
48694
  }
48150
48695
  }
48151
- var str, on;
48696
+ var str2, on;
48152
48697
  var init_wix_mobile_release = __esm({
48153
48698
  "src/wix-mobile-release.ts"() {
48154
- str = (value) => typeof value === "string" ? value : void 0;
48699
+ str2 = (value) => typeof value === "string" ? value : void 0;
48155
48700
  on = (value) => value === true || value === "true";
48156
48701
  }
48157
48702
  });
@@ -48231,7 +48776,7 @@ async function runStore(pos, flags, io, deps) {
48231
48776
  if (sub === "status") {
48232
48777
  let creds2;
48233
48778
  try {
48234
- creds2 = deps.resolveCredentials({ app, cfg, profileFlag: str2(flags.profile) });
48779
+ creds2 = deps.resolveCredentials({ app, cfg, profileFlag: str3(flags.profile) });
48235
48780
  } catch (e) {
48236
48781
  return fail2(e.message);
48237
48782
  }
@@ -48251,7 +48796,7 @@ async function runStore(pos, flags, io, deps) {
48251
48796
  }
48252
48797
  let findings;
48253
48798
  try {
48254
- findings = await deps.preflightApp(app, { profileFlag: str2(flags.profile) });
48799
+ findings = await deps.preflightApp(app, { profileFlag: str3(flags.profile) });
48255
48800
  } catch (e) {
48256
48801
  return fail2(e.message);
48257
48802
  }
@@ -48266,7 +48811,7 @@ async function runStore(pos, flags, io, deps) {
48266
48811
  }
48267
48812
  return errors.length === 0 ? 0 : 1;
48268
48813
  }
48269
- const explicitTrack = str2(flags.track);
48814
+ const explicitTrack = str3(flags.track);
48270
48815
  const configTrack = cfg.review?.defaultTrackIos;
48271
48816
  const track = explicitTrack ?? (invokedAs === "testflight" ? "testflight" : configTrack ?? "testflight");
48272
48817
  if (track === "appstore") {
@@ -48281,7 +48826,7 @@ async function runStore(pos, flags, io, deps) {
48281
48826
  let creds;
48282
48827
  let version2;
48283
48828
  try {
48284
- creds = deps.resolveCredentials({ app, cfg, profileFlag: str2(flags.profile) });
48829
+ creds = deps.resolveCredentials({ app, cfg, profileFlag: str3(flags.profile) });
48285
48830
  version2 = deps.readVersion(app);
48286
48831
  } catch (e) {
48287
48832
  return fail2(e.message);
@@ -48434,10 +48979,10 @@ function credsToEnv(c) {
48434
48979
  HIMALAYA_APPLE_TEAM_ID: c.team
48435
48980
  };
48436
48981
  }
48437
- var str2, on2, UPLOAD_STEPS, BUILD_STEPS, TRACKS, PROCESSING_POLL_MS, PROCESSING_TIMEOUT_MS;
48982
+ var str3, on2, UPLOAD_STEPS, BUILD_STEPS, TRACKS, PROCESSING_POLL_MS, PROCESSING_TIMEOUT_MS;
48438
48983
  var init_store3 = __esm({
48439
48984
  "src/store.ts"() {
48440
- str2 = (v) => typeof v === "string" ? v : void 0;
48985
+ str3 = (v) => typeof v === "string" ? v : void 0;
48441
48986
  on2 = (v) => v === true || v === "true";
48442
48987
  UPLOAD_STEPS = ["signing", "build", "validate", "upload"];
48443
48988
  BUILD_STEPS = /* @__PURE__ */ new Set(["signing", "build"]);
@@ -48456,7 +49001,7 @@ __export(preflight_exports, {
48456
49001
  parseStoreConfig: () => parseStoreConfig,
48457
49002
  requireEnv: () => requireEnv
48458
49003
  });
48459
- import { existsSync as existsSync55, readFileSync as readFileSync60 } from "node:fs";
49004
+ import { existsSync as existsSync55, readFileSync as readFileSync61 } from "node:fs";
48460
49005
  import { isAbsolute as isAbsolute3, relative as relative9, resolve as resolve44 } from "node:path";
48461
49006
  function isInsideRepo(p) {
48462
49007
  const rel = relative9(REPO_ROOT3, resolve44(p));
@@ -48516,7 +49061,7 @@ function loadStoreConfig(app) {
48516
49061
  if (!existsSync55(p)) {
48517
49062
  throw new Error(`No store config at ${p}. Create apps/${app}/store/store.config.yaml first (see /setup-store-signing).`);
48518
49063
  }
48519
- return parseStoreConfig(readFileSync60(p, "utf8"));
49064
+ return parseStoreConfig(readFileSync61(p, "utf8"));
48520
49065
  }
48521
49066
  var init_preflight = __esm({
48522
49067
  "../store-release/preflight.ts"() {
@@ -48535,19 +49080,19 @@ __export(credential_profile_exports, {
48535
49080
  profilePath: () => profilePath,
48536
49081
  resolveStoreCredentials: () => resolveStoreCredentials
48537
49082
  });
48538
- import { existsSync as existsSync56, readFileSync as readFileSync61 } from "node:fs";
49083
+ import { existsSync as existsSync56, readFileSync as readFileSync62 } from "node:fs";
48539
49084
  import { homedir as homedir5 } from "node:os";
48540
- import { join as join51 } from "node:path";
49085
+ import { join as join52 } from "node:path";
48541
49086
  function credentialsDir(home = homedir5()) {
48542
- return join51(home, ".himalaya", "store-credentials");
49087
+ return join52(home, ".himalaya", "store-credentials");
48543
49088
  }
48544
49089
  function profilePath(name, home = homedir5()) {
48545
49090
  if (!PROFILE_NAME.test(name)) {
48546
49091
  throw new Error(
48547
- `credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join51(credentialsDir(home), "<name>.json")}; it is never a path.`
49092
+ `credential profile ${JSON.stringify(name)} is not a profile name \u2014 use letters, digits, ".", "_" or "-" starting with a letter or digit. It names ${join52(credentialsDir(home), "<name>.json")}; it is never a path.`
48548
49093
  );
48549
49094
  }
48550
- return join51(credentialsDir(home), `${name}.json`);
49095
+ return join52(credentialsDir(home), `${name}.json`);
48551
49096
  }
48552
49097
  function parseProfile(text5, label2) {
48553
49098
  let doc;
@@ -48578,7 +49123,7 @@ function resolveStoreCredentials(opts) {
48578
49123
  const { app, cfg } = opts;
48579
49124
  const env = opts.env ?? process.env;
48580
49125
  const home = opts.home ?? homedir5();
48581
- const read = opts.readProfile ?? ((p) => readFileSync61(p, "utf8"));
49126
+ const read = opts.readProfile ?? ((p) => readFileSync62(p, "utf8"));
48582
49127
  const exists = opts.profileExists ?? existsSync56;
48583
49128
  const ios = cfg.ios ?? {};
48584
49129
  const flagName = opts.profileFlag?.trim();
@@ -48659,9 +49204,9 @@ __export(preflight_app_exports, {
48659
49204
  preflightApp: () => preflightApp,
48660
49205
  profileAccount: () => profileAccount
48661
49206
  });
48662
- import { readFileSync as readFileSync62, existsSync as existsSync57, readdirSync as readdirSync26, statSync as statSync15 } from "node:fs";
48663
- import { createHash as createHash25 } from "node:crypto";
48664
- import { join as join52 } from "node:path";
49207
+ import { readFileSync as readFileSync63, existsSync as existsSync57, readdirSync as readdirSync26, statSync as statSync15 } from "node:fs";
49208
+ import { createHash as createHash26 } from "node:crypto";
49209
+ import { join as join53 } from "node:path";
48665
49210
  function analyze(projectYml, storeConfig, icon, account) {
48666
49211
  const f = [];
48667
49212
  const has = (re, s) => re.test(s);
@@ -48725,13 +49270,13 @@ function profileAccount(app, storeConfig, opts = {}) {
48725
49270
  }
48726
49271
  }
48727
49272
  async function preflightApp(app, opts = {}) {
48728
- const projectYml = existsSync57(iosProjectYml(app)) ? readFileSync62(iosProjectYml(app), "utf8") : "";
48729
- const storeConfig = existsSync57(storeConfigPath(app)) ? readFileSync62(storeConfigPath(app), "utf8") : "";
49273
+ const projectYml = existsSync57(iosProjectYml(app)) ? readFileSync63(iosProjectYml(app), "utf8") : "";
49274
+ const storeConfig = existsSync57(storeConfigPath(app)) ? readFileSync63(storeConfigPath(app), "utf8") : "";
48730
49275
  if (!storeConfig) return [{ level: "error", message: `no apps/${app}/store/store.config.yaml \u2014 run /setup-store-signing first.` }];
48731
49276
  const findings = analyze(
48732
49277
  projectYml,
48733
49278
  storeConfig,
48734
- await appIconState(join52(appDir(app), "ios")),
49279
+ await appIconState(join53(appDir(app), "ios")),
48735
49280
  profileAccount(app, storeConfig, opts)
48736
49281
  );
48737
49282
  findings.push(...analyzeListing(metadataFilesPresent(app), listScreenshots(app)));
@@ -48760,16 +49305,16 @@ function analyzeSubmissionRecord(appLevel, review, opts) {
48760
49305
  return f;
48761
49306
  }
48762
49307
  function appLevelMetadataFiles(app, locale = "en-US") {
48763
- const root = join52(storeDir(app), "metadata");
49308
+ const root = join53(storeDir(app), "metadata");
48764
49309
  const out = /* @__PURE__ */ new Set();
48765
49310
  if (existsSync57(root)) {
48766
49311
  for (const n of readdirSync26(root)) if (n.endsWith(".txt")) out.add(n);
48767
49312
  }
48768
- if (existsSync57(join52(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
49313
+ if (existsSync57(join53(root, locale, "privacy_url.txt"))) out.add("privacy_url.txt");
48769
49314
  return out;
48770
49315
  }
48771
49316
  function reviewInfoFiles(app) {
48772
- const dir = join52(storeDir(app), "review_information");
49317
+ const dir = join53(storeDir(app), "review_information");
48773
49318
  if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
48774
49319
  return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
48775
49320
  }
@@ -48880,12 +49425,12 @@ function analyzePlayListing(assets) {
48880
49425
  return f;
48881
49426
  }
48882
49427
  function playListingAssets(app, locale = "en-US") {
48883
- const dir = join52(storeDir(app), "play", locale, "images");
49428
+ const dir = join53(storeDir(app), "play", locale, "images");
48884
49429
  const read = (names) => {
48885
49430
  for (const name of names) {
48886
- const p = join52(dir, name);
49431
+ const p = join53(dir, name);
48887
49432
  try {
48888
- if (statSync15(p).isFile()) return { name, bytes: readFileSync62(p) };
49433
+ if (statSync15(p).isFile()) return { name, bytes: readFileSync63(p) };
48889
49434
  } catch {
48890
49435
  }
48891
49436
  }
@@ -48916,26 +49461,26 @@ function analyzeListing(metaFiles, shots) {
48916
49461
  return f;
48917
49462
  }
48918
49463
  function metadataFilesPresent(app, locale = "en-US") {
48919
- const dir = join52(storeDir(app), "metadata", locale);
49464
+ const dir = join53(storeDir(app), "metadata", locale);
48920
49465
  if (!existsSync57(dir)) return /* @__PURE__ */ new Set();
48921
49466
  return new Set(readdirSync26(dir).filter((n) => n.endsWith(".txt")));
48922
49467
  }
48923
49468
  function listScreenshots(app, locale = "en-US") {
48924
49469
  const out = [];
48925
- const flat = join52(storeDir(app), "screenshots", locale);
49470
+ const flat = join53(storeDir(app), "screenshots", locale);
48926
49471
  if (existsSync57(flat)) {
48927
49472
  for (const png of readdirSync26(flat).filter((n) => n.endsWith(".png"))) {
48928
- const sz = pngSize(readFileSync62(join52(flat, png)));
49473
+ const sz = pngSize(readFileSync63(join53(flat, png)));
48929
49474
  if (sz) out.push({ name: png, w: sz.w, h: sz.h });
48930
49475
  }
48931
49476
  }
48932
- const legacy = join52(storeDir(app), "metadata", locale, "screenshots");
49477
+ const legacy = join53(storeDir(app), "metadata", locale, "screenshots");
48933
49478
  if (existsSync57(legacy)) {
48934
49479
  for (const deviceDir of readdirSync26(legacy)) {
48935
- const d = join52(legacy, deviceDir);
49480
+ const d = join53(legacy, deviceDir);
48936
49481
  if (!statSync15(d).isDirectory()) continue;
48937
49482
  for (const png of readdirSync26(d).filter((n) => n.endsWith(".png"))) {
48938
- const sz = pngSize(readFileSync62(join52(d, png)));
49483
+ const sz = pngSize(readFileSync63(join53(d, png)));
48939
49484
  if (sz) out.push({ name: `${deviceDir}/${png}`, w: sz.w, h: sz.h });
48940
49485
  }
48941
49486
  }
@@ -48943,13 +49488,13 @@ function listScreenshots(app, locale = "en-US") {
48943
49488
  return out;
48944
49489
  }
48945
49490
  function placeholderHashes2() {
48946
- const templateIos = join52(appDir("_template"), "ios");
49491
+ const templateIos = join53(appDir("_template"), "ios");
48947
49492
  if (!existsSync57(templateIos)) return [LEGACY_PLACEHOLDER_SHA2562];
48948
49493
  for (const target of readdirSync26(templateIos)) {
48949
- const p = join52(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
49494
+ const p = join53(templateIos, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
48950
49495
  try {
48951
49496
  if (!statSync15(p).isFile()) continue;
48952
- return [LEGACY_PLACEHOLDER_SHA2562, createHash25("sha256").update(readFileSync62(p)).digest("hex")];
49497
+ return [LEGACY_PLACEHOLDER_SHA2562, createHash26("sha256").update(readFileSync63(p)).digest("hex")];
48953
49498
  } catch {
48954
49499
  }
48955
49500
  }
@@ -48982,11 +49527,11 @@ async function pixelIssues(bytes2) {
48982
49527
  async function appIconState(iosDir) {
48983
49528
  if (!existsSync57(iosDir)) return { exists: false, isPlaceholder: false, storeIssues: [] };
48984
49529
  for (const target of readdirSync26(iosDir)) {
48985
- const p = join52(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
49530
+ const p = join53(iosDir, target, "Assets.xcassets", "AppIcon.appiconset", "icon_1024.png");
48986
49531
  try {
48987
49532
  if (!statSync15(p).isFile()) continue;
48988
- const bytes2 = readFileSync62(p);
48989
- const hash = createHash25("sha256").update(bytes2).digest("hex");
49533
+ const bytes2 = readFileSync63(p);
49534
+ const hash = createHash26("sha256").update(bytes2).digest("hex");
48990
49535
  const pixels = await pixelIssues(bytes2);
48991
49536
  return {
48992
49537
  exists: true,
@@ -49057,7 +49602,7 @@ __export(version_exports, {
49057
49602
  setAndroidVersion: () => setAndroidVersion,
49058
49603
  setIosVersion: () => setIosVersion
49059
49604
  });
49060
- import { readFileSync as readFileSync63, writeFileSync as writeFileSync23 } from "node:fs";
49605
+ import { readFileSync as readFileSync64, writeFileSync as writeFileSync23 } from "node:fs";
49061
49606
  function readIosVersion(projectYml) {
49062
49607
  const marketing = matchScalar(projectYml, "CFBundleShortVersionString");
49063
49608
  const build2 = matchScalar(projectYml, "CFBundleVersion");
@@ -49115,8 +49660,8 @@ function setAndroidVersion(gradle, v) {
49115
49660
  function bumpVersion(app, opts) {
49116
49661
  const iosPath = iosProjectYml(app);
49117
49662
  const gradlePath = androidGradle(app);
49118
- const iosYml = readFileSync63(iosPath, "utf8");
49119
- const gradle = readFileSync63(gradlePath, "utf8");
49663
+ const iosYml = readFileSync64(iosPath, "utf8");
49664
+ const gradle = readFileSync64(gradlePath, "utf8");
49120
49665
  const current = readIosVersion(iosYml);
49121
49666
  const next = {
49122
49667
  marketing: opts.marketing ?? current.marketing,
@@ -49133,7 +49678,7 @@ var init_version = __esm({
49133
49678
  });
49134
49679
 
49135
49680
  // ../store-release/register-bundle.ts
49136
- import { readFileSync as readFileSync64 } from "node:fs";
49681
+ import { readFileSync as readFileSync65 } from "node:fs";
49137
49682
  import { createPrivateKey as createPrivateKey2, sign } from "node:crypto";
49138
49683
  function b64url2(b) {
49139
49684
  return Buffer.from(b).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
@@ -49151,7 +49696,7 @@ function bundleIdBody(identifier, name, platform = "IOS") {
49151
49696
  async function registerBundleId(opts) {
49152
49697
  const env = requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
49153
49698
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
49154
- const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync64(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
49699
+ const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync65(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
49155
49700
  const res = await fetch(`${ASC_API}/v1/bundleIds`, {
49156
49701
  method: "POST",
49157
49702
  headers: { Authorization: `Bearer ${jwt}`, "Content-Type": "application/json" },
@@ -49205,7 +49750,7 @@ __export(asc_status_exports, {
49205
49750
  ascStatus: () => ascStatus,
49206
49751
  buildVerdict: () => buildVerdict
49207
49752
  });
49208
- import { readFileSync as readFileSync65 } from "node:fs";
49753
+ import { readFileSync as readFileSync66 } from "node:fs";
49209
49754
  function buildVerdict(builds) {
49210
49755
  if (!builds.length) {
49211
49756
  return "NO builds registered \u2014 if you uploaded recently and it's been >15 min, the binary was REJECTED IN PROCESSING (reason is email-only; run validate-binary.ts / scan-purpose-strings.ts to reproduce it).";
@@ -49219,7 +49764,7 @@ function buildVerdict(builds) {
49219
49764
  function client(creds) {
49220
49765
  const env = creds ?? requireEnv(["ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH"]);
49221
49766
  assertCredentialOutsideRepo("ASC_KEY_PATH", env.ASC_KEY_PATH);
49222
- const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync65(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
49767
+ const jwt = ascJwt(env.ASC_KEY_ID, env.ASC_ISSUER_ID, readFileSync66(env.ASC_KEY_PATH, "utf8"), Math.floor(Date.now() / 1e3));
49223
49768
  return async (path2) => {
49224
49769
  const r = await fetch(`${ASC}${path2}`, { headers: { Authorization: `Bearer ${jwt}` } });
49225
49770
  return { status: r.status, json: await r.json().catch(() => ({})) };
@@ -49379,7 +49924,7 @@ __export(secrets_exports, {
49379
49924
  runRemoteSecretsCommand: () => runRemoteSecretsCommand,
49380
49925
  runSecretsCommand: () => runSecretsCommand
49381
49926
  });
49382
- import { readFileSync as readFileSync66 } from "node:fs";
49927
+ import { readFileSync as readFileSync67 } from "node:fs";
49383
49928
  function environment(value) {
49384
49929
  if (value === "preview" || value === "production") return value;
49385
49930
  throw new Error("--environment must be preview or production");
@@ -49410,7 +49955,7 @@ async function runSecretsCommand(operation, flags, io, options = {}) {
49410
49955
  io.log(JSON.stringify(await vault.list({ app, environment: env })));
49411
49956
  return 0;
49412
49957
  }
49413
- const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
49958
+ const value = options.readValue ? options.readValue() : readFileSync67(0, "utf8").replace(/\r?\n$/, "");
49414
49959
  if (operation === "set") await vault.set({ app, environment: env, name, value });
49415
49960
  else if (operation === "rotate") await vault.rotate({ app, environment: env, name, value });
49416
49961
  else throw new Error(`unknown secrets operation ${operation}`);
@@ -49439,7 +49984,7 @@ async function runRemoteSecretsCommand(operation, flags, io, options) {
49439
49984
  }
49440
49985
  let body;
49441
49986
  if (operation !== "list") {
49442
- const value = options.readValue ? options.readValue() : readFileSync66(0, "utf8").replace(/\r?\n$/, "");
49987
+ const value = options.readValue ? options.readValue() : readFileSync67(0, "utf8").replace(/\r?\n$/, "");
49443
49988
  body = JSON.stringify({ value });
49444
49989
  }
49445
49990
  const response = await (options.fetchImpl ?? fetch)(url, { method: operation === "list" ? "GET" : operation === "set" ? "PUT" : "POST", headers: headers2, body });
@@ -49475,15 +50020,15 @@ __export(notify_exports, {
49475
50020
  runNotify: () => runNotify,
49476
50021
  saveAdminSession: () => saveAdminSession
49477
50022
  });
49478
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as readFileSync67, writeFileSync as writeFileSync24 } from "node:fs";
50023
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync27, readFileSync as readFileSync68, writeFileSync as writeFileSync24 } from "node:fs";
49479
50024
  import { homedir as homedir6 } from "node:os";
49480
- import { dirname as dirname30, join as join53 } from "node:path";
50025
+ import { dirname as dirname30, join as join54 } from "node:path";
49481
50026
  function defaultSessionsPath() {
49482
- return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join53(homedir6(), ".himalaya", "admin-sessions.json");
50027
+ return process.env.HIMI_ADMIN_SESSIONS_FILE ?? join54(homedir6(), ".himalaya", "admin-sessions.json");
49483
50028
  }
49484
50029
  function loadSessionsFile(path2 = defaultSessionsPath()) {
49485
50030
  try {
49486
- return JSON.parse(readFileSync67(path2, "utf8"));
50031
+ return JSON.parse(readFileSync68(path2, "utf8"));
49487
50032
  } catch {
49488
50033
  return {};
49489
50034
  }
@@ -49532,7 +50077,7 @@ function parseDataFlag(raw) {
49532
50077
  }
49533
50078
  async function runNotify(pos, flags, io, deps = {}) {
49534
50079
  const doFetch = deps.fetchImpl ?? fetch;
49535
- const str6 = (v) => typeof v === "string" ? v : void 0;
50080
+ const str7 = (v) => typeof v === "string" ? v : void 0;
49536
50081
  const json5 = flags.json === true;
49537
50082
  const print = (v) => io.log(JSON.stringify(v, null, 2));
49538
50083
  const sub = pos[1];
@@ -49547,8 +50092,8 @@ async function runNotify(pos, flags, io, deps = {}) {
49547
50092
  return 2;
49548
50093
  }
49549
50094
  const { adminUrl, session } = resolveAuth({
49550
- adminUrl: str6(flags["admin-url"]),
49551
- adminSession: str6(flags["admin-session"]),
50095
+ adminUrl: str7(flags["admin-url"]),
50096
+ adminSession: str7(flags["admin-session"]),
49552
50097
  ...deps.env ? { env: deps.env } : {},
49553
50098
  ...deps.file ? { file: deps.file } : {}
49554
50099
  });
@@ -49599,14 +50144,14 @@ async function runNotify(pos, flags, io, deps = {}) {
49599
50144
  }
49600
50145
  return report2.ok ? 0 : 1;
49601
50146
  }
49602
- const app = str6(flags.app);
50147
+ const app = str7(flags.app);
49603
50148
  if (!app) {
49604
50149
  io.error(JSON.stringify({ error: "--app is required", usage: USAGE2 }));
49605
50150
  return 2;
49606
50151
  }
49607
50152
  if (sub === "tokens") {
49608
50153
  const query = new URLSearchParams();
49609
- const platform = str6(flags.platform);
50154
+ const platform = str7(flags.platform);
49610
50155
  if (platform) query.set("platform", platform);
49611
50156
  if (flags["include-disabled"] === true) query.set("includeDisabled", "1");
49612
50157
  const url = `${adminUrl}/v1/admin/push-tokens/${encodeURIComponent(app)}${query.size ? `?${query}` : ""}`;
@@ -49650,8 +50195,8 @@ async function runNotify(pos, flags, io, deps = {}) {
49650
50195
  }
49651
50196
  return 0;
49652
50197
  }
49653
- const token = str6(flags.token);
49654
- const device = str6(flags.device);
50198
+ const token = str7(flags.token);
50199
+ const device = str7(flags.device);
49655
50200
  const all = flags.all === true;
49656
50201
  const targets = [token && "--token", device && "--device", all && "--all"].filter(Boolean);
49657
50202
  if (targets.length === 0) {
@@ -49668,20 +50213,20 @@ async function runNotify(pos, flags, io, deps = {}) {
49668
50213
  return 2;
49669
50214
  }
49670
50215
  const silent = flags.silent === true;
49671
- const title = str6(flags.title);
50216
+ const title = str7(flags.title);
49672
50217
  if (!silent && !title) {
49673
50218
  io.error(JSON.stringify({ error: "--title is required for a visible notification (use --silent for a background push)", usage: USAGE2 }));
49674
50219
  return 2;
49675
50220
  }
49676
- const badgeRaw = str6(flags.badge);
50221
+ const badgeRaw = str7(flags.badge);
49677
50222
  const payload = {
49678
50223
  ...title ? { title } : {},
49679
- ...str6(flags.body) ? { body: str6(flags.body) } : {},
49680
- ...str6(flags.link) ? { link: str6(flags.link) } : {},
49681
- ...str6(flags.category) ? { category: str6(flags.category) } : {},
49682
- ...str6(flags.channel) ? { channelId: str6(flags.channel) } : {},
49683
- ...str6(flags.platform) ? { platform: str6(flags.platform) } : {},
49684
- ...str6(flags["bundle-id"]) ? { bundleId: str6(flags["bundle-id"]) } : {},
50224
+ ...str7(flags.body) ? { body: str7(flags.body) } : {},
50225
+ ...str7(flags.link) ? { link: str7(flags.link) } : {},
50226
+ ...str7(flags.category) ? { category: str7(flags.category) } : {},
50227
+ ...str7(flags.channel) ? { channelId: str7(flags.channel) } : {},
50228
+ ...str7(flags.platform) ? { platform: str7(flags.platform) } : {},
50229
+ ...str7(flags["bundle-id"]) ? { bundleId: str7(flags["bundle-id"]) } : {},
49685
50230
  ...badgeRaw !== void 0 && Number.isFinite(Number(badgeRaw)) ? { badge: Number(badgeRaw) } : {},
49686
50231
  ...silent ? { pushType: "background" } : {},
49687
50232
  ...flags["dry-run"] === true ? { dryRun: true } : {},
@@ -49946,7 +50491,7 @@ var init_copy_clean = __esm({
49946
50491
  function genericDescription(it) {
49947
50492
  for (const field of DESCRIPTION_FIELDS) {
49948
50493
  const raw = it[field];
49949
- const text5 = typeof raw === "string" ? raw : str3(raw?.text);
50494
+ const text5 = typeof raw === "string" ? raw : str4(raw?.text);
49950
50495
  if (!text5) continue;
49951
50496
  const plain2 = text5.replace(/<[^>]*>/g, " ").replace(/&nbsp;/g, " ");
49952
50497
  if (plain2.trim()) return plain2;
@@ -49994,18 +50539,18 @@ function planPrice(p) {
49994
50539
  const price = pricing?.price ?? p.price;
49995
50540
  if (typeof price === "string" && price.trim()) return price.trim();
49996
50541
  if (price && typeof price === "object") {
49997
- return str3(price.formatted) || str3(price.value) || void 0;
50542
+ return str4(price.formatted) || str4(price.value) || void 0;
49998
50543
  }
49999
- return str3(p.formattedPrice) || str3(pricing?.formattedPrice) || void 0;
50544
+ return str4(p.formattedPrice) || str4(pricing?.formattedPrice) || void 0;
50000
50545
  }
50001
50546
  function planDetail(p) {
50002
50547
  const pricing = p.pricing && typeof p.pricing === "object" ? p.pricing : void 0;
50003
50548
  const sub = pricing?.subscription && typeof pricing.subscription === "object" ? pricing.subscription : void 0;
50004
50549
  const cycleDur = sub?.cycleDuration && typeof sub.cycleDuration === "object" ? sub.cycleDuration : void 0;
50005
50550
  const count = cycleDur?.count;
50006
- const unit = str3(cycleDur?.unit ?? cycleDur?.period).toLowerCase();
50007
- const cycle = typeof count === "number" && unit ? `${count} ${unit}` : str3(sub?.cycle ?? pricing?.cycle ?? p.period ?? p.billingPeriod);
50008
- const perks = asArr(p.perks ?? p.benefits).map((x) => str3(x) || str3(x.name)).filter(Boolean);
50551
+ const unit = str4(cycleDur?.unit ?? cycleDur?.period).toLowerCase();
50552
+ const cycle = typeof count === "number" && unit ? `${count} ${unit}` : str4(sub?.cycle ?? pricing?.cycle ?? p.period ?? p.billingPeriod);
50553
+ const perks = asArr(p.perks ?? p.benefits).map((x) => str4(x) || str4(x.name)).filter(Boolean);
50009
50554
  const bits = [cycle, perks.slice(0, 4).join("; ")].filter(Boolean);
50010
50555
  return bits.length ? bits.join(" \xB7 ") : void 0;
50011
50556
  }
@@ -50017,7 +50562,7 @@ function formLabels(x, depth = 0, out = []) {
50017
50562
  }
50018
50563
  if (typeof x !== "object") return out;
50019
50564
  const o = x;
50020
- const label2 = str3(o.label ?? o.displayName ?? o.fieldTitle ?? o.title);
50565
+ const label2 = str4(o.label ?? o.displayName ?? o.fieldTitle ?? o.title);
50021
50566
  if (label2 && !UUID_RE.test(label2) && label2.length < 80 && !out.includes(label2)) out.push(label2);
50022
50567
  for (const k of ["fields", "formFields", "form", "schema", "properties"]) {
50023
50568
  if (o[k] != null) formLabels(o[k], depth + 1, out);
@@ -50060,10 +50605,10 @@ function side(call, def) {
50060
50605
  }
50061
50606
  function toItems(def, raw) {
50062
50607
  return raw.slice(0, 12).map((it, i) => ({
50063
- id: str3((def.idOf ? def.idOf(it) : it.id) ?? `row-${i}`),
50608
+ id: str4((def.idOf ? def.idOf(it) : it.id) ?? `row-${i}`),
50064
50609
  title: def.titleOf(it) || "(untitled)",
50065
50610
  imageUrl: def.imageOf?.(it),
50066
- price: def.priceOf?.(it) || str3(it.price?.formatted) || str3(it.formattedPrice) || void 0,
50611
+ price: def.priceOf?.(it) || str4(it.price?.formatted) || str4(it.formattedPrice) || void 0,
50067
50612
  detail: def.detailOf?.(it),
50068
50613
  description: copyOrDrop(def.descriptionOf ? def.descriptionOf(it) : genericDescription(it), 240) || void 0
50069
50614
  }));
@@ -50088,7 +50633,7 @@ async function readBookingsCategories(call) {
50088
50633
  const { data } = await probeCall(call, "POST", "/bookings/v2/categories/query", {
50089
50634
  query: { paging: { limit: 100 } }
50090
50635
  });
50091
- return asArr(data?.categories).map((c) => ({ id: str3(c.id), name: str3(c.name ?? c.title) }));
50636
+ return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.name ?? c.title) }));
50092
50637
  }
50093
50638
  async function readRedirects(call) {
50094
50639
  if (!call) return 0;
@@ -50101,27 +50646,27 @@ async function readStoreCategories(call) {
50101
50646
  query: { cursorPaging: { limit: 100 } },
50102
50647
  treeReference: { appNamespace: "@wix/stores" }
50103
50648
  });
50104
- return asArr(data?.categories).map((c) => ({ id: str3(c.id), name: str3(c.name), count: typeof c.numberOfProducts === "number" ? c.numberOfProducts : void 0 }));
50649
+ return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.name), count: typeof c.numberOfProducts === "number" ? c.numberOfProducts : void 0 }));
50105
50650
  }
50106
50651
  async function readBlogCategories(call) {
50107
50652
  if (!call) return [];
50108
50653
  const { data } = await probeCall(call, "POST", "/blog/v3/categories/query", {
50109
50654
  query: { paging: { limit: 100 } }
50110
50655
  });
50111
- return asArr(data?.categories).map((c) => ({ id: str3(c.id), name: str3(c.label ?? c.name) }));
50656
+ return asArr(data?.categories).map((c) => ({ id: str4(c.id), name: str4(c.label ?? c.name) }));
50112
50657
  }
50113
50658
  async function readMediaLibrary(call) {
50114
50659
  if (!call) return [];
50115
50660
  const { data } = await probeCall(call, "GET", "/site-media/v1/files?paging.limit=50");
50116
50661
  return asArr(data?.files).slice(0, 50).map((f) => ({
50117
- id: str3(f.id ?? f.fileId),
50118
- url: str3(f.url) || (str3(f.id) ? `https://static.wixstatic.com/media/${str3(f.id)}` : ""),
50119
- filename: str3(f.displayName ?? f.fileName ?? f.name) || void 0
50662
+ id: str4(f.id ?? f.fileId),
50663
+ url: str4(f.url) || (str4(f.id) ? `https://static.wixstatic.com/media/${str4(f.id)}` : ""),
50664
+ filename: str4(f.displayName ?? f.fileName ?? f.name) || void 0
50120
50665
  })).filter((f) => f.id && f.url);
50121
50666
  }
50122
50667
  function sampleTitle(data) {
50123
50668
  for (const k of ["title", "name", "headline", "slug", "label", "displayName"]) {
50124
- const v = str3(data[k]).trim();
50669
+ const v = str4(data[k]).trim();
50125
50670
  if (v && !v.includes("@") && v.length < 120) return v;
50126
50671
  }
50127
50672
  for (const [k, v] of Object.entries(data)) {
@@ -50145,13 +50690,13 @@ async function readCms(call, opts = {}) {
50145
50690
  const unread = Math.max(0, (total ?? all.length) - cols.length);
50146
50691
  const out = [];
50147
50692
  for (const c of cols) {
50148
- const id = str3(c.id);
50693
+ const id = str4(c.id);
50149
50694
  if (!id) continue;
50150
50695
  const fieldsRaw = asArr(c.fields ?? c.displayFields);
50151
50696
  const fields = fieldsRaw.map((f) => ({
50152
- key: str3(f.key ?? f.id),
50153
- displayName: str3(f.displayName) || void 0,
50154
- type: str3(f.type) || void 0,
50697
+ key: str4(f.key ?? f.id),
50698
+ displayName: str4(f.displayName) || void 0,
50699
+ type: str4(f.type) || void 0,
50155
50700
  ...f.systemField === true ? { systemField: true } : {},
50156
50701
  ...f.encrypted === true ? { encrypted: true } : {}
50157
50702
  })).filter((f) => f.key);
@@ -50164,17 +50709,17 @@ async function readCms(call, opts = {}) {
50164
50709
  const samples = items.slice(0, 5).map((row, i) => {
50165
50710
  const dataObj = row.data && typeof row.data === "object" ? row.data : row;
50166
50711
  const title = sampleTitle(dataObj);
50167
- return { id: str3(row.id ?? dataObj._id) || `row-${i}`, ...title ? { title } : {} };
50712
+ return { id: str4(row.id ?? dataObj._id) || `row-${i}`, ...title ? { title } : {} };
50168
50713
  });
50169
50714
  out.push({
50170
50715
  id,
50171
- displayName: str3(c.displayName ?? c.name) || void 0,
50716
+ displayName: str4(c.displayName ?? c.name) || void 0,
50172
50717
  // A Wix APP's collection (Stores, Bookings, …) — the generic CMS screen must not
50173
50718
  // advertise it, because its vertical already does, properly.
50174
- ...str3(c.ownerAppId) ? { ownerAppId: str3(c.ownerAppId) } : {},
50175
- ...str3(c.displayField) ? { displayField: str3(c.displayField) } : {},
50176
- readRole: str3(perms?.read) || str3(c.permissions) || void 0,
50177
- writeRole: str3(perms?.insert ?? perms?.update) || void 0,
50719
+ ...str4(c.ownerAppId) ? { ownerAppId: str4(c.ownerAppId) } : {},
50720
+ ...str4(c.displayField) ? { displayField: str4(c.displayField) } : {},
50721
+ readRole: str4(perms?.read) || str4(c.permissions) || void 0,
50722
+ writeRole: str4(perms?.insert ?? perms?.update) || void 0,
50178
50723
  fields,
50179
50724
  sampleCount: items.length,
50180
50725
  ...samples.length ? { samples } : {}
@@ -50198,8 +50743,8 @@ async function readInstalledApps(call) {
50198
50743
  if (!data) continue;
50199
50744
  const raw = asArr(data.apps ?? data.siteApps ?? data.items);
50200
50745
  const apps = raw.map((a) => ({
50201
- id: str3(a.id ?? a.appId ?? a.appDefId),
50202
- name: str3(a.name ?? a.appName ?? a.title) || void 0
50746
+ id: str4(a.id ?? a.appId ?? a.appDefId),
50747
+ name: str4(a.name ?? a.appName ?? a.title) || void 0
50203
50748
  })).filter((a) => a.id);
50204
50749
  if (apps.length) return apps.slice(0, 40);
50205
50750
  }
@@ -50218,7 +50763,7 @@ async function readMemberRoles(call) {
50218
50763
  }
50219
50764
  if (!data) continue;
50220
50765
  const raw = asArr(data.roles ?? data.items);
50221
- const names = raw.map((r) => str3(r.title ?? r.name ?? r.id)).filter((n) => n && !n.includes("@"));
50766
+ const names = raw.map((r) => str4(r.title ?? r.name ?? r.id)).filter((n) => n && !n.includes("@"));
50222
50767
  if (names.length) return { names: names.slice(0, 24), status: "ok" };
50223
50768
  sawEmptyPayload = true;
50224
50769
  }
@@ -50226,13 +50771,13 @@ async function readMemberRoles(call) {
50226
50771
  if (sawAuthError) return { names: [], status: "error" };
50227
50772
  return { names: [], status: "empty" };
50228
50773
  }
50229
- var asArr, str3, DESCRIPTION_FIELDS, UUID_RE, CORE_PROBES, OPTIONAL_PROBES, ALL, CMS_LIST_LIMIT;
50774
+ var asArr, str4, DESCRIPTION_FIELDS, UUID_RE, CORE_PROBES, OPTIONAL_PROBES, ALL, CMS_LIST_LIMIT;
50230
50775
  var init_probes = __esm({
50231
50776
  "src/site-analyze/probes.ts"() {
50232
50777
  init_rest();
50233
50778
  init_copy_clean();
50234
50779
  asArr = (x) => Array.isArray(x) ? x : [];
50235
- str3 = (x) => typeof x === "string" ? x : "";
50780
+ str4 = (x) => typeof x === "string" ? x : "";
50236
50781
  DESCRIPTION_FIELDS = ["plainDescription", "description", "shortDescription", "excerpt", "tagLine", "subtitle"];
50237
50782
  UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
50238
50783
  CORE_PROBES = [
@@ -50242,9 +50787,9 @@ var init_probes = __esm({
50242
50787
  path: "/stores/v3/products/query",
50243
50788
  body: { query: { cursorPaging: { limit: 50 } } },
50244
50789
  itemsOf: (d) => asArr(d.products),
50245
- titleOf: (p) => str3(p.name),
50790
+ titleOf: (p) => str4(p.name),
50246
50791
  imageOf: productImage,
50247
- priceOf: (p) => str3(p.price?.formatted) || str3(p.priceData?.formatted?.price) || str3(p.formattedPrice) || (typeof p.price === "number" ? String(p.price) : void 0),
50792
+ priceOf: (p) => str4(p.price?.formatted) || str4(p.priceData?.formatted?.price) || str4(p.formattedPrice) || (typeof p.price === "number" ? String(p.price) : void 0),
50248
50793
  fallbacks: [
50249
50794
  {
50250
50795
  method: "POST",
@@ -50266,7 +50811,7 @@ var init_probes = __esm({
50266
50811
  path: "/bookings/v2/services/query",
50267
50812
  body: { query: { paging: { limit: 50 } } },
50268
50813
  itemsOf: (d) => asArr(d.services),
50269
- titleOf: (s) => str3(s.name),
50814
+ titleOf: (s) => str4(s.name),
50270
50815
  imageOf: serviceImage
50271
50816
  },
50272
50817
  {
@@ -50275,8 +50820,8 @@ var init_probes = __esm({
50275
50820
  path: "/events/v3/events/query",
50276
50821
  body: { query: { paging: { limit: 50 } } },
50277
50822
  itemsOf: (d) => asArr(d.events),
50278
- titleOf: (e) => str3(e.title ?? e.name),
50279
- imageOf: (e) => str3(e.mainImage) || str3(e.mainImage?.url) || void 0
50823
+ titleOf: (e) => str4(e.title ?? e.name),
50824
+ imageOf: (e) => str4(e.mainImage) || str4(e.mainImage?.url) || void 0
50280
50825
  },
50281
50826
  {
50282
50827
  vertical: "blog",
@@ -50284,7 +50829,7 @@ var init_probes = __esm({
50284
50829
  path: "/blog/v3/posts/query",
50285
50830
  body: { query: { paging: { limit: 50 } } },
50286
50831
  itemsOf: (d) => asArr(d.posts),
50287
- titleOf: (p) => str3(p.title),
50832
+ titleOf: (p) => str4(p.title),
50288
50833
  imageOf: blogCover
50289
50834
  },
50290
50835
  {
@@ -50293,7 +50838,7 @@ var init_probes = __esm({
50293
50838
  path: "/social-groups-proxy/groups/v2/groups/query",
50294
50839
  body: { query: { paging: { limit: 50 } } },
50295
50840
  itemsOf: (d) => asArr(d.groups),
50296
- titleOf: (g) => str3(g.title ?? g.name),
50841
+ titleOf: (g) => str4(g.title ?? g.name),
50297
50842
  imageOf: (g) => deepImageUrl(g.coverImage) || deepImageUrl(g.image)
50298
50843
  },
50299
50844
  {
@@ -50302,7 +50847,7 @@ var init_probes = __esm({
50302
50847
  path: "/online-programs/v3/programs/query",
50303
50848
  body: { query: { cursorPaging: { limit: 50 } } },
50304
50849
  itemsOf: (d) => asArr(d.programs),
50305
- titleOf: (p) => str3(p.title ?? p.name),
50850
+ titleOf: (p) => str4(p.title ?? p.name),
50306
50851
  imageOf: (p) => deepImageUrl(p.image) || deepImageUrl(p.coverImage) || deepImageUrl(p.media)
50307
50852
  },
50308
50853
  {
@@ -50310,21 +50855,21 @@ var init_probes = __esm({
50310
50855
  method: "GET",
50311
50856
  path: "/restaurants/menus/v1/menus",
50312
50857
  itemsOf: (d) => asArr(d.menus),
50313
- titleOf: (m) => str3(m.name)
50858
+ titleOf: (m) => str4(m.name)
50314
50859
  }
50315
50860
  ];
50316
50861
  OPTIONAL_PROBES = [
50317
- { vertical: "plans", method: "GET", path: "/pricing-plans/v2/plans", itemsOf: (d) => asArr(d.plans), titleOf: (p) => str3(p.name), imageOf: (p) => deepImageUrl(p.image) || deepImageUrl(p.media), priceOf: planPrice, detailOf: planDetail },
50318
- { vertical: "reviews", method: "POST", path: "/reviews/v1/reviews/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.reviews), titleOf: (r) => str3(r.content ?? r.title) },
50319
- { vertical: "loyalty", method: "GET", path: "/loyalty-programs/v1/program", itemsOf: (d) => d.loyaltyProgram ? [d.loyaltyProgram] : [], titleOf: (p) => str3(p.name) || "Loyalty" },
50320
- { vertical: "forum", method: "POST", path: "/forum/v1/posts/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.posts), titleOf: (p) => str3(p.title) },
50321
- { vertical: "donations", method: "POST", path: "/donation-campaigns/v2/donation-campaigns/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.donationCampaigns), titleOf: (c) => str3(c.name) },
50322
- { vertical: "giftCards", method: "POST", path: "/gift-cards/v1/gift-cards/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.giftCards), titleOf: (g) => str3(g.name) },
50323
- { vertical: "reservations", method: "GET", path: "/table-reservations/reservation-locations/v1/reservation-locations", itemsOf: (d) => asArr(d.reservationLocations ?? d.reservations), titleOf: (l) => str3(l.name) },
50324
- { vertical: "badges", method: "POST", path: "/badges/v4/badges/query", body: { query: { cursorPaging: { limit: 50 } } }, itemsOf: (d) => asArr(d.badges), titleOf: (b) => str3(b.title ?? b.name) },
50325
- { vertical: "coupons", method: "POST", path: "/stores/v2/coupons/query", body: { query: { paging: { limit: 30 } } }, itemsOf: (d) => asArr(d.coupons), titleOf: (c) => str3(c.name) },
50326
- { vertical: "forms", method: "POST", path: "/form-schema-service/v4/forms/query", body: { query: { paging: { limit: 30 } }, namespace: "wix.form_app.form" }, itemsOf: (d) => asArr(d.forms), titleOf: (f) => str3(f.name), detailOf: formDetail },
50327
- { vertical: "portfolio", method: "GET", path: "/portfolio/v1/projects", itemsOf: (d) => asArr(d.projects), titleOf: (p) => str3(p.title ?? p.name), imageOf: (p) => deepImageUrl(p.coverImage) || deepImageUrl(p.image) },
50862
+ { vertical: "plans", method: "GET", path: "/pricing-plans/v2/plans", itemsOf: (d) => asArr(d.plans), titleOf: (p) => str4(p.name), imageOf: (p) => deepImageUrl(p.image) || deepImageUrl(p.media), priceOf: planPrice, detailOf: planDetail },
50863
+ { vertical: "reviews", method: "POST", path: "/reviews/v1/reviews/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.reviews), titleOf: (r) => str4(r.content ?? r.title) },
50864
+ { vertical: "loyalty", method: "GET", path: "/loyalty-programs/v1/program", itemsOf: (d) => d.loyaltyProgram ? [d.loyaltyProgram] : [], titleOf: (p) => str4(p.name) || "Loyalty" },
50865
+ { vertical: "forum", method: "POST", path: "/forum/v1/posts/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.posts), titleOf: (p) => str4(p.title) },
50866
+ { vertical: "donations", method: "POST", path: "/donation-campaigns/v2/donation-campaigns/query", body: { query: { cursorPaging: { limit: 20 } } }, itemsOf: (d) => asArr(d.donationCampaigns), titleOf: (c) => str4(c.name) },
50867
+ { vertical: "giftCards", method: "POST", path: "/gift-cards/v1/gift-cards/query", body: { query: { paging: { limit: 10 } } }, itemsOf: (d) => asArr(d.giftCards), titleOf: (g) => str4(g.name) },
50868
+ { vertical: "reservations", method: "GET", path: "/table-reservations/reservation-locations/v1/reservation-locations", itemsOf: (d) => asArr(d.reservationLocations ?? d.reservations), titleOf: (l) => str4(l.name) },
50869
+ { vertical: "badges", method: "POST", path: "/badges/v4/badges/query", body: { query: { cursorPaging: { limit: 50 } } }, itemsOf: (d) => asArr(d.badges), titleOf: (b) => str4(b.title ?? b.name) },
50870
+ { vertical: "coupons", method: "POST", path: "/stores/v2/coupons/query", body: { query: { paging: { limit: 30 } } }, itemsOf: (d) => asArr(d.coupons), titleOf: (c) => str4(c.name) },
50871
+ { vertical: "forms", method: "POST", path: "/form-schema-service/v4/forms/query", body: { query: { paging: { limit: 30 } }, namespace: "wix.form_app.form" }, itemsOf: (d) => asArr(d.forms), titleOf: (f) => str4(f.name), detailOf: formDetail },
50872
+ { vertical: "portfolio", method: "GET", path: "/portfolio/v1/projects", itemsOf: (d) => asArr(d.projects), titleOf: (p) => str4(p.title ?? p.name), imageOf: (p) => deepImageUrl(p.coverImage) || deepImageUrl(p.image) },
50328
50873
  {
50329
50874
  vertical: "members",
50330
50875
  method: "POST",
@@ -51428,7 +51973,7 @@ function veloArtifactRelPath(veloPath) {
51428
51973
  if (!parts.length || parts.some((s) => s === "..")) return void 0;
51429
51974
  return `${VELO_DIR}/${parts.join("/")}`;
51430
51975
  }
51431
- function str4(x) {
51976
+ function str5(x) {
51432
51977
  return typeof x === "string" ? x : "";
51433
51978
  }
51434
51979
  function asArr2(x) {
@@ -51446,9 +51991,9 @@ function filesFromOwnerPayload(data, redact = redactSecrets) {
51446
51991
  for (const item of raw) {
51447
51992
  if (!item || typeof item !== "object") continue;
51448
51993
  const f = item;
51449
- const path2 = str4(f.path || f.relativePath || f.fileName || f.name);
51994
+ const path2 = str5(f.path || f.relativePath || f.fileName || f.name);
51450
51995
  if (!path2 || isSecretVeloPath(path2)) continue;
51451
- const content = str4(f.content ?? f.source ?? f.code ?? f.body);
51996
+ const content = str5(f.content ?? f.source ?? f.code ?? f.body);
51452
51997
  const bytes2 = typeof f.bytes === "number" ? f.bytes : typeof f.size === "number" ? f.size : content.length;
51453
51998
  const redacted = content ? redact(content) : "";
51454
51999
  const forDisk = redacted.length > VELO_FILE_CAP ? redacted.slice(0, VELO_FILE_CAP) + "\n/* \u2026truncated */" : redacted;
@@ -53041,7 +53586,7 @@ var init_brand_font = __esm({
53041
53586
 
53042
53587
  // src/site-analyze/write-artifacts.ts
53043
53588
  import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync25 } from "node:fs";
53044
- import { join as join54 } from "node:path";
53589
+ import { join as join55 } from "node:path";
53045
53590
  function attachVeloSources(book, sources, put) {
53046
53591
  const byPath = new Map((sources ?? []).map((s) => [s.path, s.text]));
53047
53592
  for (const f of book.velo.files) {
@@ -53196,12 +53741,12 @@ async function downloadMedia(book, fetchImpl, put) {
53196
53741
  }
53197
53742
  async function writeBusinessBook(result, opts) {
53198
53743
  const out = opts.outDir;
53199
- mkdirSync28(join54(out, "evidence/pages"), { recursive: true });
53200
- mkdirSync28(join54(out, "media/catalog"), { recursive: true });
53744
+ mkdirSync28(join55(out, "evidence/pages"), { recursive: true });
53745
+ mkdirSync28(join55(out, "media/catalog"), { recursive: true });
53201
53746
  const files = [];
53202
53747
  const put = (rel, body) => {
53203
- const p = join54(out, rel);
53204
- mkdirSync28(join54(p, ".."), { recursive: true });
53748
+ const p = join55(out, rel);
53749
+ mkdirSync28(join55(p, ".."), { recursive: true });
53205
53750
  writeFileSync25(p, body);
53206
53751
  files.push(rel);
53207
53752
  };
@@ -53295,8 +53840,8 @@ var init_customer_build = __esm({
53295
53840
  });
53296
53841
 
53297
53842
  // src/site-analyze/apply.ts
53298
- import { existsSync as existsSync58, readFileSync as readFileSync68, writeFileSync as writeFileSync26, copyFileSync as copyFileSync3, mkdirSync as mkdirSync29, realpathSync as realpathSync7, statSync as statSync16 } from "node:fs";
53299
- import { dirname as dirname31, isAbsolute as isAbsolute4, join as join55, resolve as resolve45, sep as sep14 } from "node:path";
53843
+ import { existsSync as existsSync58, readFileSync as readFileSync69, writeFileSync as writeFileSync26, copyFileSync as copyFileSync3, mkdirSync as mkdirSync29, realpathSync as realpathSync7, statSync as statSync16 } from "node:fs";
53844
+ import { dirname as dirname31, isAbsolute as isAbsolute4, join as join56, resolve as resolve45, sep as sep14 } from "node:path";
53300
53845
  import { spawnSync as spawnSync4 } from "node:child_process";
53301
53846
  function unpairedRedirectNote(overlay) {
53302
53847
  if (!overlay.wix?.clientId || overlay.wix.redirectUri) return void 0;
@@ -53311,7 +53856,7 @@ function committedShellProvisioning(path2) {
53311
53856
  function findRepoRoot(cwd) {
53312
53857
  let dir = cwd;
53313
53858
  for (let i = 0; i < 8; i++) {
53314
- if (SHELL_NAMES2.some((name) => existsSync58(join55(dir, shellAppDir(name), "package.json")))) return dir;
53859
+ if (SHELL_NAMES2.some((name) => existsSync58(join56(dir, shellAppDir(name), "package.json")))) return dir;
53315
53860
  const next = dirname31(dir);
53316
53861
  if (next === dir) break;
53317
53862
  dir = next;
@@ -53379,11 +53924,11 @@ function mergeCustomerOwned(committed, overlay) {
53379
53924
  }
53380
53925
  function buildMergedContract(options) {
53381
53926
  const { appDir: appDir2, packageDir, overlay } = options;
53382
- const committedPath = join55(appDir2, "provisioning.json");
53927
+ const committedPath = join56(appDir2, "provisioning.json");
53383
53928
  if (!existsSync58(committedPath)) {
53384
53929
  throw new Error(`shell has no committed provisioning.json at ${committedPath} to build a contract from`);
53385
53930
  }
53386
- const committed = JSON.parse(readFileSync68(committedPath, "utf8"));
53931
+ const committed = JSON.parse(readFileSync69(committedPath, "utf8"));
53387
53932
  const merged = mergeCustomerOwned(committed, overlay);
53388
53933
  const overlayFontFamily = (overlay.branding ?? {}).fontFamily;
53389
53934
  const branding = merged.branding ?? {};
@@ -53395,7 +53940,7 @@ function buildMergedContract(options) {
53395
53940
  };
53396
53941
  const stage = (fromRel, toRel) => {
53397
53942
  const from = contained(packageDir, fromRel);
53398
- const to = contained(join55(appDir2, STAGED), toRel.slice(STAGED.length + 1));
53943
+ const to = contained(join56(appDir2, STAGED), toRel.slice(STAGED.length + 1));
53399
53944
  if (!from || !to || !existsSync58(from)) return void 0;
53400
53945
  let real;
53401
53946
  let realRoot;
@@ -53418,11 +53963,11 @@ function buildMergedContract(options) {
53418
53963
  };
53419
53964
  const icon = stage("media/icon.png", `${STAGED}/icon.png`);
53420
53965
  if (icon) branding.appIconPath = icon;
53421
- const facesPath = join55(packageDir, "media/fonts/faces.json");
53966
+ const facesPath = join56(packageDir, "media/fonts/faces.json");
53422
53967
  if (existsSync58(facesPath)) {
53423
53968
  let faces = [];
53424
53969
  try {
53425
- const parsed = JSON.parse(readFileSync68(facesPath, "utf8"));
53970
+ const parsed = JSON.parse(readFileSync69(facesPath, "utf8"));
53426
53971
  faces = Array.isArray(parsed) ? parsed : [];
53427
53972
  } catch {
53428
53973
  faces = [];
@@ -53443,9 +53988,9 @@ function buildMergedContract(options) {
53443
53988
  merged.branding = branding;
53444
53989
  const body = `${JSON.stringify(merged, null, 2)}
53445
53990
  `;
53446
- const path2 = join55(packageDir, "provisioning.contract.json");
53991
+ const path2 = join56(packageDir, "provisioning.contract.json");
53447
53992
  writeFileSync26(path2, body);
53448
- const localPath = join55(appDir2, LOCAL_CONTRACT_REL);
53993
+ const localPath = join56(appDir2, LOCAL_CONTRACT_REL);
53449
53994
  mkdirSync29(dirname31(localPath), { recursive: true });
53450
53995
  writeFileSync26(localPath, body);
53451
53996
  staged.push(localPath);
@@ -53455,8 +54000,8 @@ async function applyOverlays(input) {
53455
54000
  const cwd = resolve45(input.cwd);
53456
54001
  const shell = input.shell ?? DEFAULT_BRANDABLE_SHELL;
53457
54002
  assertKnownShell(shell);
53458
- const overlay = JSON.parse(readFileSync68(input.overlayPath, "utf8"));
53459
- const tokens = JSON.parse(readFileSync68(input.tokensPath, "utf8"));
54003
+ const overlay = JSON.parse(readFileSync69(input.overlayPath, "utf8"));
54004
+ const tokens = JSON.parse(readFileSync69(input.tokensPath, "utf8"));
53460
54005
  const wrote = [];
53461
54006
  const notes = [];
53462
54007
  const repoRoot2 = findRepoRoot(cwd);
@@ -53466,7 +54011,7 @@ async function applyOverlays(input) {
53466
54011
  `shell "${shell}" cannot bake a customer brand \u2014 it ships no prepare:customer script`
53467
54012
  );
53468
54013
  }
53469
- const appDir2 = join55(repoRoot2, shellAppDir(shell));
54014
+ const appDir2 = join56(repoRoot2, shellAppDir(shell));
53470
54015
  const packageDir = dirname31(resolve45(input.overlayPath));
53471
54016
  const { path: contract, staged } = buildMergedContract({ appDir: appDir2, packageDir, overlay });
53472
54017
  wrote.push(...staged);
@@ -53488,10 +54033,10 @@ async function applyOverlays(input) {
53488
54033
  note: `prepare:customer --contract with a merged contract (committed provisioning.json untouched)${unpairedInRepo ? ` \xB7 ${unpairedInRepo}` : ""}`
53489
54034
  };
53490
54035
  }
53491
- const pkgProv = join55(cwd, "provisioning.json");
54036
+ const pkgProv = join56(cwd, "provisioning.json");
53492
54037
  assertNotCommitted(pkgProv, input.forbiddenProvisioning);
53493
54038
  if (existsSync58(pkgProv)) {
53494
- const cur = JSON.parse(readFileSync68(pkgProv, "utf8"));
54039
+ const cur = JSON.parse(readFileSync69(pkgProv, "utf8"));
53495
54040
  const merged = deepMerge4(cur, overlay);
53496
54041
  writeFileSync26(pkgProv, JSON.stringify(merged, null, 2) + "\n");
53497
54042
  wrote.push(pkgProv);
@@ -53499,9 +54044,9 @@ async function applyOverlays(input) {
53499
54044
  writeFileSync26(pkgProv, JSON.stringify(overlay, null, 2) + "\n");
53500
54045
  wrote.push(pkgProv);
53501
54046
  }
53502
- const pkgTokens = join55(cwd, "tokens.json");
54047
+ const pkgTokens = join56(cwd, "tokens.json");
53503
54048
  if (existsSync58(pkgTokens) && (tokens.colors || tokens.typography)) {
53504
- const cur = JSON.parse(readFileSync68(pkgTokens, "utf8"));
54049
+ const cur = JSON.parse(readFileSync69(pkgTokens, "utf8"));
53505
54050
  const merged = deepMerge4(cur, tokens);
53506
54051
  const mergedColors = merged.colors;
53507
54052
  if (mergedColors && typeof mergedColors === "object" && !Array.isArray(mergedColors)) {
@@ -53520,9 +54065,9 @@ async function applyOverlays(input) {
53520
54065
  wrote.push(pkgTokens);
53521
54066
  }
53522
54067
  const homeAction = homeRefreshActionId(shell);
53523
- const homeSrc = join55(cwd, "dev/index.ts");
54068
+ const homeSrc = join56(cwd, "dev/index.ts");
53524
54069
  if (homeAction && existsSync58(homeSrc)) {
53525
- const prev = readFileSync68(homeSrc, "utf8");
54070
+ const prev = readFileSync69(homeSrc, "utf8");
53526
54071
  const patched = patchBrandParams(prev, overlay, homeAction);
53527
54072
  let next = patched.src;
53528
54073
  if (!patched.foreign && overlay.installedVerticals?.length) {
@@ -54558,20 +55103,20 @@ function canonicalDomain(domainName) {
54558
55103
  if (domainName == null) {
54559
55104
  return void 0;
54560
55105
  }
54561
- let str6 = domainName.trim().replace(/^\./, "");
54562
- if (IP_V6_REGEX_OBJECT.test(str6)) {
54563
- if (!str6.startsWith("[")) {
54564
- str6 = "[" + str6;
55106
+ let str7 = domainName.trim().replace(/^\./, "");
55107
+ if (IP_V6_REGEX_OBJECT.test(str7)) {
55108
+ if (!str7.startsWith("[")) {
55109
+ str7 = "[" + str7;
54565
55110
  }
54566
- if (!str6.endsWith("]")) {
54567
- str6 = str6 + "]";
55111
+ if (!str7.endsWith("]")) {
55112
+ str7 = str7 + "]";
54568
55113
  }
54569
- return domainToASCII(str6).slice(1, -1);
55114
+ return domainToASCII(str7).slice(1, -1);
54570
55115
  }
54571
- if (/[^\u0001-\u007f]/.test(str6)) {
54572
- return domainToASCII(str6);
55116
+ if (/[^\u0001-\u007f]/.test(str7)) {
55117
+ return domainToASCII(str7);
54573
55118
  }
54574
- return str6.toLowerCase();
55119
+ return str7.toLowerCase();
54575
55120
  }
54576
55121
  function formatDate(date) {
54577
55122
  return date.toUTCString();
@@ -54665,16 +55210,16 @@ function parseDate(cookieDate) {
54665
55210
  }
54666
55211
  return date;
54667
55212
  }
54668
- function trimTerminator(str6) {
54669
- if (isEmptyString(str6)) return str6;
55213
+ function trimTerminator(str7) {
55214
+ if (isEmptyString(str7)) return str7;
54670
55215
  for (let t = 0; t < TERMINATORS.length; t++) {
54671
55216
  const terminator = TERMINATORS[t];
54672
- const terminatorIdx = terminator ? str6.indexOf(terminator) : -1;
55217
+ const terminatorIdx = terminator ? str7.indexOf(terminator) : -1;
54673
55218
  if (terminatorIdx !== -1) {
54674
- str6 = str6.slice(0, terminatorIdx);
55219
+ str7 = str7.slice(0, terminatorIdx);
54675
55220
  }
54676
55221
  }
54677
- return str6;
55222
+ return str7;
54678
55223
  }
54679
55224
  function parseCookiePair(cookiePair, looseMode) {
54680
55225
  cookiePair = trimTerminator(cookiePair);
@@ -54705,13 +55250,13 @@ function parseCookiePair(cookiePair, looseMode) {
54705
55250
  c.value = cookieValue;
54706
55251
  return c;
54707
55252
  }
54708
- function parse(str6, options) {
54709
- if (isEmptyString(str6) || !isString(str6)) {
55253
+ function parse(str7, options) {
55254
+ if (isEmptyString(str7) || !isString(str7)) {
54710
55255
  return void 0;
54711
55256
  }
54712
- str6 = str6.trim();
54713
- const firstSemi = str6.indexOf(";");
54714
- const cookiePair = firstSemi === -1 ? str6 : str6.slice(0, firstSemi);
55257
+ str7 = str7.trim();
55258
+ const firstSemi = str7.indexOf(";");
55259
+ const cookiePair = firstSemi === -1 ? str7 : str7.slice(0, firstSemi);
54715
55260
  const c = parseCookiePair(cookiePair, options?.loose ?? false);
54716
55261
  if (!c) {
54717
55262
  return void 0;
@@ -54719,7 +55264,7 @@ function parse(str6, options) {
54719
55264
  if (firstSemi === -1) {
54720
55265
  return c;
54721
55266
  }
54722
- const unparsed = str6.slice(firstSemi + 1).trim();
55267
+ const unparsed = str7.slice(firstSemi + 1).trim();
54723
55268
  if (unparsed.length === 0) {
54724
55269
  return c;
54725
55270
  }
@@ -54800,19 +55345,19 @@ function parse(str6, options) {
54800
55345
  }
54801
55346
  return c;
54802
55347
  }
54803
- function fromJSON(str6) {
54804
- if (!str6 || isEmptyString(str6)) {
55348
+ function fromJSON(str7) {
55349
+ if (!str7 || isEmptyString(str7)) {
54805
55350
  return void 0;
54806
55351
  }
54807
55352
  let obj3;
54808
- if (typeof str6 === "string") {
55353
+ if (typeof str7 === "string") {
54809
55354
  try {
54810
- obj3 = JSON.parse(str6);
55355
+ obj3 = JSON.parse(str7);
54811
55356
  } catch {
54812
55357
  return void 0;
54813
55358
  }
54814
55359
  } else {
54815
- obj3 = str6;
55360
+ obj3 = str7;
54816
55361
  }
54817
55362
  const c = new Cookie();
54818
55363
  Cookie.serializableProperties.forEach((prop) => {
@@ -55530,42 +56075,42 @@ var init_dist = __esm({
55530
56075
  * @public
55531
56076
  */
55532
56077
  toString() {
55533
- let str6 = this.cookieString();
56078
+ let str7 = this.cookieString();
55534
56079
  if (this.expires != "Infinity") {
55535
56080
  if (this.expires instanceof Date) {
55536
- str6 += `; Expires=${formatDate(this.expires)}`;
56081
+ str7 += `; Expires=${formatDate(this.expires)}`;
55537
56082
  }
55538
56083
  }
55539
56084
  if (this.maxAge != null && this.maxAge != Infinity) {
55540
- str6 += `; Max-Age=${String(this.maxAge)}`;
56085
+ str7 += `; Max-Age=${String(this.maxAge)}`;
55541
56086
  }
55542
56087
  if (this.domain && !this.hostOnly) {
55543
- str6 += `; Domain=${this.domain}`;
56088
+ str7 += `; Domain=${this.domain}`;
55544
56089
  }
55545
56090
  if (this.path) {
55546
- str6 += `; Path=${this.path}`;
56091
+ str7 += `; Path=${this.path}`;
55547
56092
  }
55548
56093
  if (this.secure) {
55549
- str6 += "; Secure";
56094
+ str7 += "; Secure";
55550
56095
  }
55551
56096
  if (this.httpOnly) {
55552
- str6 += "; HttpOnly";
56097
+ str7 += "; HttpOnly";
55553
56098
  }
55554
56099
  if (this.sameSite && this.sameSite !== "none") {
55555
56100
  if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.lax.toLowerCase()) {
55556
- str6 += `; SameSite=${_Cookie2.sameSiteCanonical.lax}`;
56101
+ str7 += `; SameSite=${_Cookie2.sameSiteCanonical.lax}`;
55557
56102
  } else if (this.sameSite.toLowerCase() === _Cookie2.sameSiteCanonical.strict.toLowerCase()) {
55558
- str6 += `; SameSite=${_Cookie2.sameSiteCanonical.strict}`;
56103
+ str7 += `; SameSite=${_Cookie2.sameSiteCanonical.strict}`;
55559
56104
  } else {
55560
- str6 += `; SameSite=${this.sameSite}`;
56105
+ str7 += `; SameSite=${this.sameSite}`;
55561
56106
  }
55562
56107
  }
55563
56108
  if (this.extensions) {
55564
56109
  this.extensions.forEach((ext) => {
55565
- str6 += `; ${ext}`;
56110
+ str7 += `; ${ext}`;
55566
56111
  });
55567
56112
  }
55568
- return str6;
56113
+ return str7;
55569
56114
  }
55570
56115
  /**
55571
56116
  * Computes the TTL relative to now (milliseconds).
@@ -55688,8 +56233,8 @@ var init_dist = __esm({
55688
56233
  * @param str - The `Set-Cookie` header or a Cookie string to parse.
55689
56234
  * @param options - Configures `strict` or `loose` mode for cookie parsing
55690
56235
  */
55691
- static parse(str6, options) {
55692
- return parse(str6, options);
56236
+ static parse(str7, options) {
56237
+ return parse(str7, options);
55693
56238
  }
55694
56239
  /**
55695
56240
  * Does the reverse of {@link Cookie.toJSON}.
@@ -55716,8 +56261,8 @@ var init_dist = __esm({
55716
56261
  *
55717
56262
  * @param str - An unparsed JSON string or a value that has already been parsed as JSON
55718
56263
  */
55719
- static fromJSON(str6) {
55720
- return fromJSON(str6);
56264
+ static fromJSON(str7) {
56265
+ return fromJSON(str7);
55721
56266
  }
55722
56267
  };
55723
56268
  _Cookie.cookiesCreated = 0;
@@ -57706,7 +58251,7 @@ __export(cli_exports, {
57706
58251
  runSiteAnalyze: () => runSiteAnalyze,
57707
58252
  runSiteFunctionCli: () => runSiteFunctionCli
57708
58253
  });
57709
- import { readFileSync as readFileSync69 } from "node:fs";
58254
+ import { readFileSync as readFileSync70 } from "node:fs";
57710
58255
  import { resolve as resolve46 } from "node:path";
57711
58256
  function assetFetchFor(_opts) {
57712
58257
  return pinnedFetch2;
@@ -57793,7 +58338,7 @@ async function runSiteFunctionCli(opts) {
57793
58338
  let source;
57794
58339
  if (opts.sourcePath) {
57795
58340
  const p = resolve46(opts.cwd ?? process.cwd(), opts.sourcePath);
57796
- source = readFileSync69(p, "utf8");
58341
+ source = readFileSync70(p, "utf8");
57797
58342
  }
57798
58343
  let body;
57799
58344
  if (opts.bodyRaw != null) {
@@ -58050,7 +58595,7 @@ __export(site_create_exports, {
58050
58595
  runSiteList: () => runSiteList,
58051
58596
  writeProvisioningBinding: () => writeProvisioningBinding
58052
58597
  });
58053
- import { existsSync as existsSync59, readFileSync as readFileSync70, writeFileSync as writeFileSync27 } from "node:fs";
58598
+ import { existsSync as existsSync59, readFileSync as readFileSync71, writeFileSync as writeFileSync27 } from "node:fs";
58054
58599
  import { resolve as resolvePath2 } from "node:path";
58055
58600
  function oauthClientName(projectName) {
58056
58601
  return `${projectName} client`;
@@ -58199,7 +58744,7 @@ async function runSiteCreate(opts) {
58199
58744
  if (!wantOauthApp) return { ...base, nextSteps: nextSteps(metaSiteId) };
58200
58745
  return { ...base, clientId, redirectUri, nextSteps: nextSteps(metaSiteId, clientId) };
58201
58746
  }
58202
- function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync: readFileSync70, writeFileSync: writeFileSync27 }) {
58747
+ function writeProvisioningBinding(target, binding2, fs = { existsSync: existsSync59, readFileSync: readFileSync71, writeFileSync: writeFileSync27 }) {
58203
58748
  const msid = binding2.siteId;
58204
58749
  const path2 = resolvePath2(target);
58205
58750
  const committed = committedShellProvisioning(path2);
@@ -58872,11 +59417,11 @@ var init_context = __esm({
58872
59417
  });
58873
59418
 
58874
59419
  // src/cli.ts
58875
- import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync71, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as rmSync13, readdirSync as readdirSync27, statSync as statSync17, lstatSync as lstatSync8, accessSync, constants as constants2, renameSync as renameSync6, cpSync as cpSync3 } from "node:fs";
59420
+ import { mkdtempSync as mkdtempSync4, readFileSync as readFileSync72, mkdirSync as mkdirSync30, writeFileSync as writeFileSync28, existsSync as existsSync60, rmSync as rmSync13, readdirSync as readdirSync27, statSync as statSync17, lstatSync as lstatSync9, accessSync, constants as constants2, renameSync as renameSync6, cpSync as cpSync3 } from "node:fs";
58876
59421
  import { execFile, execFileSync as execFileSync7, spawnSync as spawnSync5, spawn as spawn6 } from "node:child_process";
58877
- import { createHash as createHash26, randomUUID as randomUUID5 } from "node:crypto";
59422
+ import { createHash as createHash27, randomUUID as randomUUID5 } from "node:crypto";
58878
59423
  import { tmpdir as tmpdir5, homedir as homedir7, hostname } from "node:os";
58879
- import { join as join56, resolve as resolve47, relative as relative10, basename as basename13, dirname as dirname32 } from "node:path";
59424
+ import { join as join57, resolve as resolve47, relative as relative10, basename as basename14, dirname as dirname32 } from "node:path";
58880
59425
  import { fileURLToPath as fileURLToPath24 } from "node:url";
58881
59426
 
58882
59427
  // ../serve-cli/src/client.ts
@@ -62148,12 +62693,12 @@ function parseFlags(argv) {
62148
62693
  return { _, flags };
62149
62694
  }
62150
62695
  var caveatLead = (ni) => ni.severity === "category" ? "WARNING \u2014 not implemented" : "NOTE \u2014 implemented, but these props are inert";
62151
- var str5 = (v) => typeof v === "string" ? v : void 0;
62696
+ var str6 = (v) => typeof v === "string" ? v : void 0;
62152
62697
  var num2 = (v) => typeof v === "string" && v !== "" && Number.isFinite(Number(v)) ? Number(v) : void 0;
62153
62698
  function embeddedTemplateCatalog() {
62154
62699
  return availableTemplates().map((name) => {
62155
- const path2 = join56(templateSourceDir(name), TEMPLATE_META_FILE);
62156
- const meta = JSON.parse(readFileSync71(path2, "utf8"));
62700
+ const path2 = join57(templateSourceDir(name), TEMPLATE_META_FILE);
62701
+ const meta = JSON.parse(readFileSync72(path2, "utf8"));
62157
62702
  if (!meta || typeof meta.title !== "string" || typeof meta.description !== "string" || !Array.isArray(meta.tags)) {
62158
62703
  throw new Error(`${path2} must be { title: string, description: string, tags: string[], category?: string }`);
62159
62704
  }
@@ -62215,6 +62760,10 @@ var USAGE = `himi \u2014 the Himalaya authoring CLI (remote dev loop)
62215
62760
  app is built \u2014 screens as they render, the journey step and the
62216
62761
  latest postcard, validate/test/UX/draft checks, site vs app.
62217
62762
  Updates itself; once open, other commands keep it current.
62763
+ himi studio reel [--out <file>] [--no-open]
62764
+ the making-of: one self-contained HTML file of the app taking
62765
+ shape \u2014 a flipbook of the home screen, the final screens, the
62766
+ postcards. Default .himi/making-of.html.
62218
62767
  himi progress ["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]
62219
62768
  journal a postcard for the owner (.himi/progress.jsonl): what
62220
62769
  changed, which journey step, and the image that shows it (copied
@@ -62766,7 +63315,7 @@ var COMMANDS = [
62766
63315
  { name: "test", summary: "DERIVED behavioral crawl \u2014 no test files to write. Boots each screen's real worker, replays its onAppear, then dispatches every action site the descriptor already declares (each from a fresh boot) and checks a narrow set of unambiguous invariants: no uncaught throw, never stuck on `loading`, no `$service:` token or NaN/undefined/[object Object] reaching visible text, no binding aimed at state the worker never defines, no nav param silently dropped, no dead nav target. Catches what validate/render cannot \u2014 a WRONG REDUCER passes both with ok:true. Runs the worker in a DEVICE-PARITY sandbox (no setTimeout/setInterval, as on JSC/WebView) so a bundle that would die on device fails here. Crawls on HERMETIC DATA by default \u2014 zero network: the app's own dev/net-mocks.json first (--net <file> overrides), then the config's CMS `seed:` rows, then a canned fixture of frozen real vertical responses shipped with the CLI (exercises code paths, not API-contract truth) \u2014 so the success/mapping path runs, not just the failure UI. Two boot-only HOSTILE passes (every list empty; every request 500) then check the failure/empty day \u2014 corpus-proven, so their findings are errors. NAV EDGES are followed too: every himi.open site ($item params resolved against row 0 of its list, $service against worker state) and worker _nav directive is harvested, and each baked target is booted WITH the params the source sends \u2014 detail screens finally run their content arm; edge findings are errors tagged edge:<source>. --native runs both real native decoders over the exact baked JSON bytes; --native ios or --native android selects one. It is explicit, runs only from a Himalaya SOURCE CHECKOUT (the decoder oracles are that tree's own HimalayaCore Swift package and Gradle harness, which a published install does not ship), and needs the selected local toolchain. From a source checkout, default runs name missing native verdicts in the coverage ledger; elsewhere the ledger stays silent about them rather than offering a remedy you cannot run. --offline strips all data layers (the old reject-all axis); --no-hostile skips the hostile passes. --record (EXPLICIT, never automatic) refreshes dev/net-mocks.json from live reads first: it boots each screen (load + root onAppear ONLY \u2014 nothing the app's own launch would not fire; the tap/action crawl never sees the live transport, and only proven reads \u2014 GET, or read-shaped POST (/query, /search, /list*, \u2026) \u2014 ever reach the wire), freezes the round-trips, then crawls hermetically on the fresh fixture; record against a QA site, not production. Nodes it cannot judge headless are named, never silently passed. Exit 1 on any error. The CLI carries the authoring runtime off-repo; no per-app SDK install is required. --browser runs the whole loop (build \u2192 extract \u2192 validate \u2192 render \u2192 test) in YOUR browser instead of here, so the source never reaches a pod: it opens one screen's worker + descriptor in a tab, blocks on a loopback callback, and prints the report it posts back. One screen per tab \u2014 name it. --no-open prints the URL rather than launching a browser (SSH); --timeout <ms> bounds the wait, which matters because the page has no execution deadline of its own and an infinite loop in the worker hangs the tab.", required: "[<screenId>\u2026] [--content <dir>] [--net <file>] [--budget <ms>] [--deep [n]] [--record] [--native [ios|android]] [--no-shots] [--offline] [--no-hostile] [--all-screens] [--browser] [--no-open] [--timeout <ms>] [--json]" },
62767
63316
  { name: "ux", summary: "audit or record mobile UX evidence. `audit` checks the public-safe contract, seeded blank acceptance rows, placeholder source copy, app-specific mocks, and iOS/Android audit records. It warns while existing templates migrate; `--strict` promotes missing evidence. `record` stores checks performed on an installed iOS/Android build: `--checks` is required for passed|failed and empty for unavailable, which drove nothing and needs a `--reason` instead. `record` also STAMPS the release it audited (it resolves the id from a build, the same one a push would publish), because an unforced `himi push` of a release with screens refuses when no drive is recorded for THAT release, or when the one that is recorded says `failed` \u2014 the artifact stopped being advice nobody reads (#2955). `unavailable` still satisfies it; only `failed` refuses.", required: "audit [--content <dir>] [--strict] [--json] | record --content <dir> --platform ios|android --status passed|failed|unavailable [--checks back,keyboard,...] [--reason <text>]" },
62768
63317
  { name: "progress", summary: 'the build JOURNAL an agent keeps for the owner while it works. `himi progress "<what changed>" --step <1-8|name> --image <png>` appends one postcard to .himi/progress.jsonl \u2014 the step is one of the customer journey\'s eight (discover, classify, plan, implement, brand, validate, review, download) \u2014 and COPIES each image, content-addressed, into .himi/history/, because .himi/shots/ is overwritten by every render and cleared by every full `himi test`, so a path into it would later show a different picture than the one the owner was sent. --image repeats. --notify also raises a best-effort desktop notification for an owner who stepped away. A bare `himi progress` prints the journal with the current step and elapsed time \u2014 also how an agent recovers its place after its context was compacted. Local only: nothing is sent anywhere.', required: '["<message>" [--step <1-8|name>] [--image <png>]\u2026 [--notify]] [--content <dir>]' },
62769
- { name: "studio", summary: "open the BUILD BOARD \u2014 one local page the owner can leave open while an agent builds their app, which fills itself in: every screen as it renders (NEW/CHANGED badges, and each earlier version kept for a filmstrip), the journey stepper and the latest postcard from `himi progress`, the validate/test/UX/draft checks as they run, the site next to the app's home screen with its palette, and the navigation the test crawl followed. Writes .himi/studio/index.html and opens it; the page re-reads its state every two seconds, so nothing needs to be served. OPT-IN BY EXISTENCE: until this command has run, no other command touches .himi/studio/ \u2014 after it, render/test/validate/push/icon/site/ux/progress each refresh the board as they finish (best-effort; never fails a command). Every image is a content-addressed copy in .himi/history/, never a live path into .himi/shots/. Local only, no secrets: it never reads a preview token, handover code or control token. --no-open prints the path instead (SSH, CI).", required: "[--content <dir>] [--no-open]" },
63318
+ { name: "studio", summary: "open the BUILD BOARD \u2014 one local page the owner can leave open while an agent builds their app, which fills itself in: every screen as it renders (NEW/CHANGED badges, and each earlier version kept for a filmstrip), the journey stepper and the latest postcard from `himi progress`, the validate/test/UX/draft checks as they run, the site next to the app's home screen with its palette, and the navigation the test crawl followed. Writes .himi/studio/index.html and opens it; the page re-reads its state every two seconds, so nothing needs to be served. OPT-IN BY EXISTENCE: until this command has run, no other command touches .himi/studio/ \u2014 after it, render/test/validate/push/icon/site/ux/progress each refresh the board as they finish (best-effort; never fails a command). Every image is a content-addressed copy in .himi/history/, never a live path into .himi/shots/. Local only, no secrets: it never reads a preview token, handover code or control token. --no-open prints the path instead (SSH, CI). `himi studio reel` writes the MAKING-OF: one self-contained HTML file (every image inlined, nothing fetched) with a flipbook of the home screen version by version, captioned by the postcard in effect at the time, the final screens, and every postcard \u2014 sized to stay attachable, thinning frames first. Defaults to .himi/making-of.html (never archived by push); --out to put it elsewhere.", required: "[--content <dir>] [--no-open] | reel [--out <file>] [--no-open]" },
62770
63319
  { name: "render", summary: "headless-render a screen with the web renderer: render-tree + diagnostics, optional --png <file>, --scheme dark, --tree. Local by default (content dir). Pass --remote --app --release to hit GET /v1/preview/\u2026/render on the serve plane after a push. Boots the worker so $service bindings resolve; --static raw bindings; --live real Wix fetches; --state injects worker state; --input supplies pre-boot navigation params; --width/--device for PNG viewport; --rtl for dir=rtl + $env:isRTL.", required: "<screenId> [--content <dir>] [--scheme dark] [--png <file>] [--tree] [--static] [--live] [--state <json|file>] [--input <json|file>] [--width <px> | --device <name>] [--rtl] [--remote --app --release]" },
62771
63320
  { name: "cms", summary: "inspect, provision, and seed the app's CMS (Wix Data) collections, declared as a `cms` block in config.ts. `query` is READ-ONLY \u2014 by default it fetches ONLY the physical ids `config.ts` declares (item counts + schema drift) and reports `siteScanned: false`; it never lists the site, so an UNDECLARED `himi_<app>_` collection this app owns is not reached without `--all`. `--all` SCANS the site \u2014 every collection it lists is labeled `owned`/`adopted`/`foreign`, and it describes every foreign one \u2014 id, non-system field keys + types, and the site's read role \u2014 so an app with no `cms` block at all can DISCOVER a collection to adopt (`--all` is the one case where a missing `cms` block is not 'nothing to do'). Foreign collections are described up to a cap and are never item-counted (`itemCount: null`), because a row count is one query each; `foreign.count` is how many the scan LISTED \u2014 it follows the list endpoint's pages, and `listingIncomplete: true` says when the walk stopped short of the end, with `unlistedCollections` counting what it left out when Wix gave a paging total \u2014 and `foreign.truncated` says how many of those went undescribed, each still NAMED in `foreign.others` (id + displayName), so a collection the site already has is never hidden behind the cap. The scan is OWNER-scoped \u2014 it needs --site <msid> (or WIX_SITE_ID) plus owner auth via `wix token`; a visitor token can read a public collection's ITEMS but can never enumerate collections, so there is no tokenless discovery path. `create` reconciles declared collections additively and idempotently, and REFUSES any id outside the app's `himi_<app>_` namespace, so it is safe against a production site. It reports declared-vs-site `permissionDrift` but never writes permissions unless asked with --apply-permissions, so a field reconcile can't silently revert access control changed in the dashboard. `seed` inserts the git-tracked `seed:` rows into EMPTY owned collections (--force to add to a non-empty one; --ai writes placeholder rows plus a refinement prompt for you to review). Adopted collections (declared by `wixId`) are read-only and never created, updated, or seeded. Site from --site <msid> or WIX_SITE_ID; owner auth via `wix token`.", required: "query|create|seed [--site <msid>] [--content <dir>] [--all] [--dry-run] [--force] [--allow-destructive] [--apply-permissions] [--only <id>] [--ai] [--count <n>]" },
62772
63321
  { name: "data", summary: "read-only plan or explicitly provision/seed declared KV and Wix Data resources. Preview and production are separate scopes. KV administration uses the operator data plane from --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN; draft push never calls it.", required: "plan|create|seed [--site <msid>] [--environment preview|production] [--content <dir>] [--data-url <url>] [--dry-run] [--force]" },
@@ -62815,7 +63364,7 @@ var COMMANDS = [
62815
63364
  ];
62816
63365
  function cliVersion() {
62817
63366
  try {
62818
- return JSON.parse(readFileSync71(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
63367
+ return JSON.parse(readFileSync72(new URL("../package.json", import.meta.url), "utf8")).version ?? "unknown";
62819
63368
  } catch {
62820
63369
  return "unknown";
62821
63370
  }
@@ -62933,7 +63482,7 @@ function ageInDays(publishedAt, now = Date.now()) {
62933
63482
  }
62934
63483
  function packageVersion(path2) {
62935
63484
  try {
62936
- const version2 = JSON.parse(readFileSync71(path2, "utf8")).version;
63485
+ const version2 = JSON.parse(readFileSync72(path2, "utf8")).version;
62937
63486
  return typeof version2 === "string" && version2 ? version2 : void 0;
62938
63487
  } catch {
62939
63488
  return void 0;
@@ -62942,7 +63491,7 @@ function packageVersion(path2) {
62942
63491
  function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("./authoring-runtime/node_modules/@wix/himalaya/package.json", import.meta.url)) {
62943
63492
  let dir = resolve47(fromDir);
62944
63493
  for (; ; ) {
62945
- const version2 = packageVersion(join56(dir, "node_modules", "@wix", "himalaya", "package.json"));
63494
+ const version2 = packageVersion(join57(dir, "node_modules", "@wix", "himalaya", "package.json"));
62946
63495
  if (version2) return { version: version2, source: "local" };
62947
63496
  const parent = dirname32(dir);
62948
63497
  if (parent === dir) break;
@@ -62952,7 +63501,7 @@ function resolvedSdkVersion(fromDir = process.cwd(), bundledManifest = new URL("
62952
63501
  if (bundled) return { version: bundled, source: "bundled" };
62953
63502
  try {
62954
63503
  const root = execFileSync7("npm", ["root", "-g"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
62955
- const version2 = root ? packageVersion(join56(root, "@wix", "himalaya", "package.json")) : void 0;
63504
+ const version2 = root ? packageVersion(join57(root, "@wix", "himalaya", "package.json")) : void 0;
62956
63505
  return version2 ? { version: version2, source: "global" } : {};
62957
63506
  } catch {
62958
63507
  return {};
@@ -62999,11 +63548,11 @@ var UPDATE_RETRY_AFTER_FAILURE_MS = 60 * 60 * 1e3;
62999
63548
  var UPDATE_SNOOZE_MS = 24 * 60 * 60 * 1e3;
63000
63549
  var UPDATE_REEXEC_ENV = "HIMI_UPDATED_ONCE";
63001
63550
  function updateCachePath(env = process.env) {
63002
- return env.HIMI_UPDATE_CACHE_FILE ?? join56(homedir7(), ".himalaya", "update-check.json");
63551
+ return env.HIMI_UPDATE_CACHE_FILE ?? join57(homedir7(), ".himalaya", "update-check.json");
63003
63552
  }
63004
63553
  function readUpdateCache(path2) {
63005
63554
  try {
63006
- const parsed = JSON.parse(readFileSync71(path2, "utf8"));
63555
+ const parsed = JSON.parse(readFileSync72(path2, "utf8"));
63007
63556
  return parsed && typeof parsed === "object" ? parsed : {};
63008
63557
  } catch {
63009
63558
  return {};
@@ -63071,11 +63620,11 @@ function createUpdateRunner(spawn7 = spawnSync5) {
63071
63620
  },
63072
63621
  installedVersion: () => {
63073
63622
  const root = globalNodeModulesRoot();
63074
- return root ? packageVersion(join56(root, "@wix", "himalaya-cli", "package.json")) : void 0;
63623
+ return root ? packageVersion(join57(root, "@wix", "himalaya-cli", "package.json")) : void 0;
63075
63624
  },
63076
63625
  reexec: (argv) => {
63077
63626
  const root = globalNodeModulesRoot();
63078
- const entry = root ? join56(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
63627
+ const entry = root ? join57(root, "@wix", "himalaya-cli", "dist", "cli.mjs") : void 0;
63079
63628
  if (!entry || !existsSync60(entry)) return void 0;
63080
63629
  const result = spawnSync5(process.execPath, [entry, ...argv], {
63081
63630
  // inherit keeps PIPED STDIN working — commands that read stdin must survive a re-exec.
@@ -63123,7 +63672,7 @@ function staleUpdateLockFile(cachePath, now) {
63123
63672
  for (const path2 of [`${cachePath}.lock.break`, `${cachePath}.lock`]) {
63124
63673
  let content;
63125
63674
  try {
63126
- content = readFileSync71(path2, "utf8");
63675
+ content = readFileSync72(path2, "utf8");
63127
63676
  } catch {
63128
63677
  continue;
63129
63678
  }
@@ -63146,7 +63695,7 @@ function acquireUpdateLock(cachePath, now, hooks = {}) {
63146
63695
  const mine = lockStamp(now);
63147
63696
  const readLock = (path2) => {
63148
63697
  try {
63149
- return readFileSync71(path2, "utf8");
63698
+ return readFileSync72(path2, "utf8");
63150
63699
  } catch {
63151
63700
  return void 0;
63152
63701
  }
@@ -63684,7 +64233,7 @@ function executableOnPath(name, env = process.env) {
63684
64233
  const suffixes = process.platform === "win32" ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
63685
64234
  for (const dir of entries) {
63686
64235
  for (const suffix of suffixes) {
63687
- const candidate = join56(dir, `${name}${suffix}`);
64236
+ const candidate = join57(dir, `${name}${suffix}`);
63688
64237
  try {
63689
64238
  if (!statSync17(candidate).isFile()) continue;
63690
64239
  if (process.platform !== "win32") accessSync(candidate, constants2.X_OK);
@@ -63793,7 +64342,7 @@ async function nativeConfigAdvisories(app, configSource) {
63793
64342
  const { iosProjectYml: iosProjectYml2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
63794
64343
  const { androidOptedIn: androidOptedIn3, LABEL_IOS_SPLASH: LABEL_IOS_SPLASH2 } = await Promise.resolve().then(() => (init_splash(), splash_exports));
63795
64344
  const iosYmlPath = iosProjectYml2(app);
63796
- const iosYml = existsSync60(iosYmlPath) ? readFileSync71(iosYmlPath, "utf8") : "";
64345
+ const iosYml = existsSync60(iosYmlPath) ? readFileSync72(iosYmlPath, "utf8") : "";
63797
64346
  let optedIn = iosYml.includes(LABEL_IOS_SPLASH2);
63798
64347
  if (!optedIn) {
63799
64348
  const { androidManifestPath: androidManifestPath3 } = await Promise.resolve().then(() => (init_gen_native_config(), gen_native_config_exports));
@@ -63807,7 +64356,7 @@ async function nativeConfigAdvisories(app, configSource) {
63807
64356
  }
63808
64357
  function readConfigSource(dir) {
63809
64358
  try {
63810
- return readFileSync71(join56(dir, "config.ts"), "utf8");
64359
+ return readFileSync72(join57(dir, "config.ts"), "utf8");
63811
64360
  } catch {
63812
64361
  return null;
63813
64362
  }
@@ -63819,7 +64368,7 @@ function writePngFile(path2, base64) {
63819
64368
  }
63820
64369
  async function initFromRemoteTemplate(name, parentDir, template, c) {
63821
64370
  const dir = resolve47(parentDir, name);
63822
- if (existsSync60(join56(dir, "himalaya.content.json"))) {
64371
+ if (existsSync60(join57(dir, "himalaya.content.json"))) {
63823
64372
  throw new Error(`content package already exists at ${dir}`);
63824
64373
  }
63825
64374
  const r = await c.fetchTemplateSource(TEMPLATE_APP_PREFIX + template);
@@ -63831,7 +64380,7 @@ async function initFromRemoteTemplate(name, parentDir, template, c) {
63831
64380
  return finishScaffold(materializeSource(archive.files, name, dir), template);
63832
64381
  }
63833
64382
  function contentDir(flags) {
63834
- return resolve47(str5(flags.content) ?? process.cwd());
64383
+ return resolve47(str6(flags.content) ?? process.cwd());
63835
64384
  }
63836
64385
  function renameRestoredSource(restored, declaredApp, renamed) {
63837
64386
  const text5 = {};
@@ -63849,7 +64398,7 @@ function renameRestoredSource(restored, declaredApp, renamed) {
63849
64398
  function symlinkDestinationIssue(dest) {
63850
64399
  let kind;
63851
64400
  try {
63852
- kind = lstatSync8(dest);
64401
+ kind = lstatSync9(dest);
63853
64402
  } catch {
63854
64403
  return null;
63855
64404
  }
@@ -63877,7 +64426,7 @@ function restoreDestinationIssue(dest, force) {
63877
64426
  function isHimalayaMonorepoCheckout(start) {
63878
64427
  let dir = resolve47(start);
63879
64428
  for (; ; ) {
63880
- if (existsSync60(join56(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync60(join56(dir, "core", "serve", "src", "server.ts"))) return true;
64429
+ if (existsSync60(join57(dir, "tools", "himi-cli", "src", "cli.ts")) && existsSync60(join57(dir, "core", "serve", "src", "server.ts"))) return true;
63881
64430
  const parent = dirname32(dir);
63882
64431
  if (parent === dir) return false;
63883
64432
  dir = parent;
@@ -63920,7 +64469,7 @@ function materializeForPreview(appDir2, slug, displayName) {
63920
64469
  Object.entries(files).map(([rel, body]) => [rel, rel === "himalaya.content.json" ? substituteIdentity(body, slug) : body])
63921
64470
  );
63922
64471
  const repoRoot2 = resolve47(fileURLToPath24(new URL("../../..", import.meta.url)));
63923
- const root = join56(repoRoot2, "node_modules", ".cache", "himi-template-preview");
64472
+ const root = join57(repoRoot2, "node_modules", ".cache", "himi-template-preview");
63924
64473
  const stillRunning = (pid) => {
63925
64474
  try {
63926
64475
  process.kill(pid, 0);
@@ -63934,12 +64483,12 @@ function materializeForPreview(appDir2, slug, displayName) {
63934
64483
  if (!entry.isDirectory()) continue;
63935
64484
  const pid = Number(entry.name.startsWith(`${slug}-`) ? entry.name.slice(slug.length + 1) : NaN);
63936
64485
  if (Number.isInteger(pid) && pid > 0 && pid !== process.pid && !stillRunning(pid)) {
63937
- rmSync13(join56(root, entry.name), { recursive: true, force: true });
64486
+ rmSync13(join57(root, entry.name), { recursive: true, force: true });
63938
64487
  }
63939
64488
  }
63940
64489
  } catch {
63941
64490
  }
63942
- const dest = join56(root, `${slug}-${process.pid}`);
64491
+ const dest = join57(root, `${slug}-${process.pid}`);
63943
64492
  rmSync13(dest, { recursive: true, force: true });
63944
64493
  mkdirSync30(dest, { recursive: true });
63945
64494
  materializeSource(forBuild, displayName, dest, slug);
@@ -63947,17 +64496,17 @@ function materializeForPreview(appDir2, slug, displayName) {
63947
64496
  }
63948
64497
  async function appId(dir) {
63949
64498
  try {
63950
- const { readFileSync: readFileSync72 } = await import("node:fs");
63951
- const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
64499
+ const { readFileSync: readFileSync73 } = await import("node:fs");
64500
+ const m = JSON.parse(readFileSync73(join57(dir, "himalaya.content.json"), "utf8"));
63952
64501
  if (m.name) return m.name;
63953
64502
  } catch {
63954
64503
  }
63955
- return basename13(dir);
64504
+ return basename14(dir);
63956
64505
  }
63957
64506
  async function contentVisibility(dir) {
63958
64507
  try {
63959
- const { readFileSync: readFileSync72 } = await import("node:fs");
63960
- const m = JSON.parse(readFileSync72(join56(dir, "himalaya.content.json"), "utf8"));
64508
+ const { readFileSync: readFileSync73 } = await import("node:fs");
64509
+ const m = JSON.parse(readFileSync73(join57(dir, "himalaya.content.json"), "utf8"));
63961
64510
  if (m.visibility === "public" || m.visibility === "unlisted") return m.visibility;
63962
64511
  } catch {
63963
64512
  }
@@ -63965,7 +64514,7 @@ async function contentVisibility(dir) {
63965
64514
  }
63966
64515
  function visibilityFlag(flags, io) {
63967
64516
  if (flags.visibility === void 0) return {};
63968
- const v = str5(flags.visibility);
64517
+ const v = str6(flags.visibility);
63969
64518
  if (v !== "public" && v !== "unlisted") {
63970
64519
  io.error(JSON.stringify({ error: `--visibility must be public or unlisted (got "${v ?? ""}")` }));
63971
64520
  return null;
@@ -64159,7 +64708,7 @@ Seed your coding agent with \`himi agent-init\`. Guides: ${idx.portalUrl}`);
64159
64708
  return 0;
64160
64709
  }
64161
64710
  case "agent-init": {
64162
- const dir = resolve47(str5(flags.dir) ?? process.cwd());
64711
+ const dir = resolve47(str6(flags.dir) ?? process.cwd());
64163
64712
  const res = writeAgentContext(dir);
64164
64713
  print({ ok: true, dir: res.dir, files: res.files, portalUrl: idx.portalUrl });
64165
64714
  return 0;
@@ -64181,7 +64730,7 @@ async function recordedReleaseForContentQuietly(dir, resolution, onDrift) {
64181
64730
  try {
64182
64731
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
64183
64732
  const bres = await buildContentForValidation2(dir, { resolution });
64184
- out = mkdtempSync4(join56(tmpdir5(), "himi-ux-record-"));
64733
+ out = mkdtempSync4(join57(tmpdir5(), "himi-ux-record-"));
64185
64734
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
64186
64735
  const outcome = await buildReleaseFromContent2(dir, out, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {}, collect: { lint: true } });
64187
64736
  const releaseId = outcome.manifest.releaseId;
@@ -64359,7 +64908,7 @@ async function producedWidgetFamilies(dir) {
64359
64908
  let js;
64360
64909
  for (const candidate of [`${name}.bundle.js`, `${name}.js`, name]) {
64361
64910
  try {
64362
- js = readFileSync71(join56(outDir, candidate), "utf8");
64911
+ js = readFileSync72(join57(outDir, candidate), "utf8");
64363
64912
  break;
64364
64913
  } catch {
64365
64914
  }
@@ -64390,7 +64939,7 @@ async function producedWidgetFamilies(dir) {
64390
64939
  }
64391
64940
  return { families, source: "dist/bundles" };
64392
64941
  }
64393
- var boardOpen = (dir) => existsSync60(join56(dir, ".himi", "studio", "index.html"));
64942
+ var boardOpen = (dir) => existsSync60(join57(dir, ".himi", "studio", "index.html"));
64394
64943
  var BOARD_REFRESHERS = /* @__PURE__ */ new Set(["render", "test", "validate", "build", "push", "icon", "site", "ux", "progress"]);
64395
64944
  async function leaveForBoard(dir, record2, value) {
64396
64945
  if (!boardOpen(dir)) return;
@@ -64445,20 +64994,20 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64445
64994
  if (update) updateNotice = update;
64446
64995
  }
64447
64996
  const contextualDefaultTarget = defaultTargetForCommand(command, contentDir(flags));
64448
- const targetName = () => resolveTargetName({ target: str5(flags.target), defaultTarget: contextualDefaultTarget });
64997
+ const targetName = () => resolveTargetName({ target: str6(flags.target), defaultTarget: contextualDefaultTarget });
64449
64998
  const client2 = () => new ServeCliClient(
64450
64999
  resolveTarget({
64451
- target: str5(flags.target),
65000
+ target: str6(flags.target),
64452
65001
  defaultTarget: contextualDefaultTarget,
64453
- serveUrl: str5(flags["serve-url"]),
64454
- telemetryUrl: str5(flags["telemetry-url"]),
64455
- controlUrl: str5(flags["control-url"]),
64456
- telemetryToken: str5(flags["telemetry-token"]),
64457
- controlToken: str5(flags["control-token"])
65002
+ serveUrl: str6(flags["serve-url"]),
65003
+ telemetryUrl: str6(flags["telemetry-url"]),
65004
+ controlUrl: str6(flags["control-url"]),
65005
+ telemetryToken: str6(flags["telemetry-token"]),
65006
+ controlToken: str6(flags["control-token"])
64458
65007
  })
64459
65008
  );
64460
- const serveBase = () => resolveTarget({ target: str5(flags.target), defaultTarget: contextualDefaultTarget, serveUrl: str5(flags["serve-url"]) }).serve;
64461
- const controlBase = () => resolveTarget({ target: str5(flags.target), defaultTarget: contextualDefaultTarget, controlUrl: str5(flags["control-url"]) }).control ?? "";
65009
+ const serveBase = () => resolveTarget({ target: str6(flags.target), defaultTarget: contextualDefaultTarget, serveUrl: str6(flags["serve-url"]) }).serve;
65010
+ const controlBase = () => resolveTarget({ target: str6(flags.target), defaultTarget: contextualDefaultTarget, controlUrl: str6(flags["control-url"]) }).control ?? "";
64462
65011
  const foreignPlaneRefusal = async () => {
64463
65012
  const base = serveBase();
64464
65013
  if (!isLoopbackBase(base)) return null;
@@ -64656,8 +65205,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64656
65205
  io.error(JSON.stringify({ ok: false, error: flagError }));
64657
65206
  return 2;
64658
65207
  }
64659
- const template = str5(flags.template);
64660
- const parentDir = resolve47(str5(flags.dir) ?? process.cwd());
65208
+ const template = str6(flags.template);
65209
+ const parentDir = resolve47(str6(flags.dir) ?? process.cwd());
64661
65210
  if (template && flags.remote === true) {
64662
65211
  try {
64663
65212
  const res2 = await initFromRemoteTemplate(name, parentDir, template, client2());
@@ -64774,11 +65323,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64774
65323
  return outcome.code;
64775
65324
  }
64776
65325
  if (sub === "publish") {
64777
- const appDir2 = resolve47(str5(flags.dir) ?? process.cwd());
64778
- const sourceDir = resolve47(str5(flags["source-dir"]) ?? appDir2);
65326
+ const appDir2 = resolve47(str6(flags.dir) ?? process.cwd());
65327
+ const sourceDir = resolve47(str6(flags["source-dir"]) ?? appDir2);
64779
65328
  let meta;
64780
65329
  try {
64781
- meta = JSON.parse(readFileSync71(join56(sourceDir, TEMPLATE_META_FILE), "utf8"));
65330
+ meta = JSON.parse(readFileSync72(join57(sourceDir, TEMPLATE_META_FILE), "utf8"));
64782
65331
  } catch {
64783
65332
  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>)` }));
64784
65333
  return 2;
@@ -64788,11 +65337,11 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64788
65337
  return 2;
64789
65338
  }
64790
65339
  try {
64791
- const appearance = extractTemplateAppearance(JSON.parse(readFileSync71(join56(sourceDir, "tokens.json"), "utf8")));
65340
+ const appearance = extractTemplateAppearance(JSON.parse(readFileSync72(join57(sourceDir, "tokens.json"), "utf8")));
64792
65341
  meta = { ...appearance, ...meta };
64793
65342
  } catch {
64794
65343
  }
64795
- const name = str5(flags.name) ?? await appId(sourceDir);
65344
+ const name = str6(flags.name) ?? await appId(sourceDir);
64796
65345
  const templateAppId = TEMPLATE_APP_PREFIX + name;
64797
65346
  const buildDir = materializeForPreview(appDir2, name, meta.title);
64798
65347
  const app = await appId(buildDir);
@@ -64800,7 +65349,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64800
65349
  const force = flags.force === true;
64801
65350
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
64802
65351
  const bres = await buildContentForValidation2(buildDir, { resolution: resolutionFlag(flags) });
64803
- const out = mkdtempSync4(join56(tmpdir5(), "himi-template-"));
65352
+ const out = mkdtempSync4(join57(tmpdir5(), "himi-template-"));
64804
65353
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
64805
65354
  const outcome = await buildReleaseFromContent2(buildDir, out, {
64806
65355
  ...hasWorkers ? { tier5Dir: bundleOutDir2(buildDir) } : {},
@@ -64849,13 +65398,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64849
65398
  }));
64850
65399
  return 1;
64851
65400
  }
64852
- const iconPath = str5(flags.icon) ? resolve47(str5(flags.icon)) : templateIconPath(name);
65401
+ const iconPath = str6(flags.icon) ? resolve47(str6(flags.icon)) : templateIconPath(name);
64853
65402
  let iconHash;
64854
65403
  if (iconPath) {
64855
65404
  try {
64856
- const bytes2 = readFileSync71(iconPath);
65405
+ const bytes2 = readFileSync72(iconPath);
64857
65406
  payload.icon = bytes2.toString("base64");
64858
- iconHash = createHash26("sha256").update(bytes2).digest("hex");
65407
+ iconHash = createHash27("sha256").update(bytes2).digest("hex");
64859
65408
  } catch {
64860
65409
  }
64861
65410
  }
@@ -64904,8 +65453,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
64904
65453
  const tplVis = visibilityFlag(flags, io);
64905
65454
  if (!tplVis) return 2;
64906
65455
  const publishMeta = {
64907
- ...str5(flags.label) ? { label: str5(flags.label) } : {},
64908
- ...str5(flags.notes) ? { notes: str5(flags.notes) } : {},
65456
+ ...str6(flags.label) ? { label: str6(flags.label) } : {},
65457
+ ...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
64909
65458
  ...tplVis.value ? { visibility: tplVis.value } : {}
64910
65459
  };
64911
65460
  let sendPayload = payload;
@@ -65005,7 +65554,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65005
65554
  return 1;
65006
65555
  }
65007
65556
  const releaseId = r.json?.releaseId ?? payload.manifest.releaseId;
65008
- const targetFlag = str5(flags.target) ? ` --target ${str5(flags.target)}` : "";
65557
+ const targetFlag = str6(flags.target) ? ` --target ${str6(flags.target)}` : "";
65009
65558
  print({
65010
65559
  ok: true,
65011
65560
  template: name,
@@ -65086,7 +65635,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65086
65635
  const { navIssues: navIssues2 } = await Promise.resolve().then(() => (init_nav_lint(), nav_lint_exports));
65087
65636
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
65088
65637
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
65089
- const out = mkdtempSync4(join56(tmpdir5(), "himi-validate-"));
65638
+ const out = mkdtempSync4(join57(tmpdir5(), "himi-validate-"));
65090
65639
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
65091
65640
  const outcome = await buildReleaseFromContent2(dir, out, {
65092
65641
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -65124,12 +65673,12 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65124
65673
  }
65125
65674
  case "functions": {
65126
65675
  const { buildLocalFunctions: buildLocalFunctions2, describeFunction: describeFunction2, invokeLocalFunction: invokeLocalFunction2, invokeRemoteFunction: invokeRemoteFunction2, listFunctions: listFunctions2, loadFunctionsApp: loadFunctionsApp2, openApiForFunctions: openApiForFunctions2, resolveFunctionsTarget: resolveFunctionsTarget2, runRemoteFunctionOperation: runRemoteFunctionOperation2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
65127
- const remoteTarget = str5(flags.target);
65676
+ const remoteTarget = str6(flags.target);
65128
65677
  const boCookie = () => {
65129
65678
  const path2 = dpxSessionTokenPath();
65130
65679
  let raw;
65131
65680
  try {
65132
- raw = readFileSync71(path2, "utf8");
65681
+ raw = readFileSync72(path2, "utf8");
65133
65682
  } catch {
65134
65683
  throw new Error(`no DPX BO session at ${path2}; run dpx auth login, write dpx auth token to that path, then himi login --dpx --target bo`);
65135
65684
  }
@@ -65147,14 +65696,14 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65147
65696
  io.error(JSON.stringify({ error: `functions ${sub} needs ${allowed2.join(" | ")}` }));
65148
65697
  return 2;
65149
65698
  }
65150
- const app = str5(flags.app);
65699
+ const app = str6(flags.app);
65151
65700
  const id = pos[3];
65152
65701
  if (!app || !["list", "dlq"].includes(action) && !id) {
65153
65702
  io.error(JSON.stringify({ error: `functions ${sub} ${action} needs --app${["list", "dlq"].includes(action) ? "" : " and an id/name"}` }));
65154
65703
  return 2;
65155
65704
  }
65156
- const target2 = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str5(flags["functions-url"]), releaseId: str5(flags.release), requireRemote: true });
65157
- const result = await runRemoteFunctionOperation2({ baseUrl: target2.mode === "remote" ? target2.baseUrl : "", app, environment: str5(flags.environment) === "preview" ? "preview" : "production", resource: sub === "jobs" ? "jobs" : "schedules", action, id, releaseId: str5(flags.release), boCookie: boCookie(), previewToken: str5(flags["preview-token"]) });
65705
+ const target2 = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str6(flags["functions-url"]), releaseId: str6(flags.release), requireRemote: true });
65706
+ const result = await runRemoteFunctionOperation2({ baseUrl: target2.mode === "remote" ? target2.baseUrl : "", app, environment: str6(flags.environment) === "preview" ? "preview" : "production", resource: sub === "jobs" ? "jobs" : "schedules", action, id, releaseId: str6(flags.release), boCookie: boCookie(), previewToken: str6(flags["preview-token"]) });
65158
65707
  print({ ...result.body, ok: result.ok, status: result.status });
65159
65708
  return result.ok ? 0 : 1;
65160
65709
  }
@@ -65190,7 +65739,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65190
65739
  }
65191
65740
  let input = { name: "Himi", value: "echo", ok: true };
65192
65741
  if (flags.body !== void 0) {
65193
- const raw = str5(flags.body);
65742
+ const raw = str6(flags.body);
65194
65743
  if (!raw) {
65195
65744
  io.error(JSON.stringify({ error: "--body must be non-empty JSON" }));
65196
65745
  return 2;
@@ -65204,7 +65753,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65204
65753
  }
65205
65754
  let params = {};
65206
65755
  if (flags.params !== void 0) {
65207
- const raw = str5(flags.params);
65756
+ const raw = str6(flags.params);
65208
65757
  try {
65209
65758
  const parsed = JSON.parse(raw ?? "");
65210
65759
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || Object.values(parsed).some((value) => typeof value !== "string")) throw new Error("must be a JSON object of string values");
@@ -65214,16 +65763,16 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65214
65763
  return 2;
65215
65764
  }
65216
65765
  }
65217
- const remoteRelease = str5(flags.release);
65218
- const target = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str5(flags["functions-url"]), releaseId: remoteRelease });
65766
+ const remoteRelease = str6(flags.release);
65767
+ const target = resolveFunctionsTarget2({ target: remoteTarget, functionsUrl: str6(flags["functions-url"]), releaseId: remoteRelease });
65219
65768
  if (target.mode === "remote") {
65220
65769
  const definition = loaded.definitions.find((item) => item.name === name);
65221
65770
  if (!definition) {
65222
65771
  io.error(JSON.stringify({ error: `unknown function "${name}"` }));
65223
65772
  return 1;
65224
65773
  }
65225
- const app = str5(flags.app) ?? loaded.app;
65226
- const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken: str5(flags["preview-token"]), boCookie: boCookie() });
65774
+ const app = str6(flags.app) ?? loaded.app;
65775
+ const invoked2 = await invokeRemoteFunction2({ baseUrl: target.baseUrl, app, definition, body: input, params, releaseId: remoteRelease, previewToken: str6(flags["preview-token"]), boCookie: boCookie() });
65227
65776
  const response = invoked2.response;
65228
65777
  const text6 = await response.text();
65229
65778
  let body2;
@@ -65249,10 +65798,41 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65249
65798
  case "studio": {
65250
65799
  const { openStudio: openStudio2 } = await Promise.resolve().then(() => (init_studio(), studio_exports));
65251
65800
  const dir = contentDir(flags);
65252
- if (!existsSync60(join56(dir, "himalaya.content.json"))) {
65801
+ if (!existsSync60(join57(dir, "himalaya.content.json"))) {
65253
65802
  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/" }));
65254
65803
  return 2;
65255
65804
  }
65805
+ if (pos[1] === "reel") {
65806
+ const { buildReel: buildReel2 } = await Promise.resolve().then(() => (init_studio_reel(), studio_reel_exports));
65807
+ const out = resolve47(str6(flags.out) ?? join57(dir, ".himi", "making-of.html"));
65808
+ const { html, plan } = buildReel2(dir);
65809
+ mkdirSync30(dirname32(out), { recursive: true });
65810
+ writeFileSync28(out, html);
65811
+ const { pathToFileURL: pathToFileURL9 } = await import("node:url");
65812
+ const url2 = pathToFileURL9(out).href;
65813
+ const open2 = flags["no-open"] !== true;
65814
+ if (open2) {
65815
+ const { openUrl: openUrl2 } = await Promise.resolve().then(() => (init_open_url(), open_url_exports));
65816
+ openUrl2(url2);
65817
+ }
65818
+ print({
65819
+ ok: true,
65820
+ file: out,
65821
+ url: url2,
65822
+ opened: open2,
65823
+ bytes: Buffer.byteLength(html),
65824
+ frames: plan.frames.length,
65825
+ screens: plan.stats.screens,
65826
+ postcards: plan.stats.postcards,
65827
+ ...plan.dropped ? { dropped: plan.dropped, note: "pictures were left out to keep the file attachable" } : {},
65828
+ ...plan.frames.length === 0 ? { hint: "no screen versions were recorded \u2014 run `himi studio` before building so the board keeps them" } : {}
65829
+ });
65830
+ return 0;
65831
+ }
65832
+ if (pos[1] !== void 0) {
65833
+ io.error(JSON.stringify({ ok: false, error: "unknown_subcommand", got: pos[1], expected: "himi studio [reel]" }));
65834
+ return 2;
65835
+ }
65256
65836
  const { page, url, view } = openStudio2(dir);
65257
65837
  const open = flags["no-open"] !== true;
65258
65838
  if (open) {
@@ -65274,7 +65854,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65274
65854
  const { appendProgress: appendProgress2, readProgress: readProgress2, summarizeProgress: summarizeProgress2, parseStep: parseStep2, notifyDesktop: notifyDesktop2, appLabel: appLabel2, journalPath: journalPath2, ProgressError: ProgressError2, JOURNEY_STEPS: JOURNEY_STEPS2 } = await Promise.resolve().then(() => (init_progress(), progress_exports));
65275
65855
  const dir = contentDir(flags);
65276
65856
  const journal = journalPath2(dir);
65277
- const hint = existsSync60(join56(dir, "himalaya.content.json")) ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
65857
+ const hint = existsSync60(join57(dir, "himalaya.content.json")) ? {} : { hint: "no himalaya.content.json here \u2014 run from the app directory (or pass --content <dir>) so the build board finds this journal" };
65278
65858
  const message = pos.slice(1).join(" ").trim();
65279
65859
  if (!message) {
65280
65860
  if (flags.step !== void 0 || flags.image !== void 0 || flags.notify === true) {
@@ -65325,9 +65905,9 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65325
65905
  io.error(JSON.stringify({ error: "ux needs audit | record" }));
65326
65906
  return 2;
65327
65907
  }
65328
- const platform = str5(flags.platform);
65329
- const status = str5(flags.status);
65330
- const checks = str5(flags.checks)?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
65908
+ const platform = str6(flags.platform);
65909
+ const status = str6(flags.status);
65910
+ const checks = str6(flags.checks)?.split(",").map((item) => item.trim()).filter(Boolean) ?? [];
65331
65911
  if (!isNativePlatform(platform)) {
65332
65912
  io.error(JSON.stringify({ error: `ux record needs --platform ${NATIVE_PLATFORMS.join("|")}` }));
65333
65913
  return 2;
@@ -65341,7 +65921,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65341
65921
  drifting = workers;
65342
65922
  });
65343
65923
  try {
65344
- const evidence = recordNativeAudit(dir, platform, status, checks, str5(flags.reason), uxRelease ?? void 0);
65924
+ const evidence = recordNativeAudit(dir, platform, status, checks, str6(flags.reason), uxRelease ?? void 0);
65345
65925
  print({
65346
65926
  ok: true,
65347
65927
  content: dir,
@@ -65366,7 +65946,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65366
65946
  case "test": {
65367
65947
  const dir = contentDir(flags);
65368
65948
  const structuredOutput = flags.json === true || io.isTTY !== true;
65369
- if (existsSync60(join56(dir, "functions"))) {
65949
+ if (existsSync60(join57(dir, "functions"))) {
65370
65950
  const { invokeLocalFunction: invokeLocalFunction2, loadFunctionsApp: loadFunctionsApp2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
65371
65951
  const loaded = await loadFunctionsApp2(dir);
65372
65952
  const results = [];
@@ -65391,21 +65971,21 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65391
65971
  }
65392
65972
  let budgetMs;
65393
65973
  if (flags.budget !== void 0) {
65394
- budgetMs = Number(str5(flags.budget));
65974
+ budgetMs = Number(str6(flags.budget));
65395
65975
  if (!Number.isFinite(budgetMs) || budgetMs <= 0) {
65396
- io.error(JSON.stringify({ error: `--budget must be a positive number of ms (got "${str5(flags.budget) ?? ""}")` }));
65976
+ io.error(JSON.stringify({ error: `--budget must be a positive number of ms (got "${str6(flags.budget) ?? ""}")` }));
65397
65977
  return 2;
65398
65978
  }
65399
65979
  }
65400
65980
  let deep;
65401
65981
  if (flags.deep !== void 0) {
65402
- deep = flags.deep === true ? 3 : Number(str5(flags.deep));
65982
+ deep = flags.deep === true ? 3 : Number(str6(flags.deep));
65403
65983
  if (!Number.isFinite(deep) || deep < 2 || deep > 6) {
65404
65984
  io.error(JSON.stringify({ error: `--deep takes a chain depth between 2 and 6 (got "${String(flags.deep)}") \u2014 bare --deep means 3` }));
65405
65985
  return 2;
65406
65986
  }
65407
65987
  }
65408
- const netPath = str5(flags.net);
65988
+ const netPath = str6(flags.net);
65409
65989
  if (flags.net !== void 0 && !netPath) {
65410
65990
  io.error(JSON.stringify({ error: "--net was given but empty \u2014 pass a path to a net-mocks JSON file" }));
65411
65991
  return 2;
@@ -65436,7 +66016,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65436
66016
  const { detectAndroidNativeDecode: detectAndroidNativeDecode2, detectNativeDecode: detectNativeDecode2, nativeDecodePlatforms: nativeDecodePlatforms2 } = await Promise.resolve().then(() => (init_native_decode(), native_decode_exports));
65437
66017
  let platforms;
65438
66018
  try {
65439
- platforms = nativeDecodePlatforms2(flags.native === true ? true : str5(flags.native));
66019
+ platforms = nativeDecodePlatforms2(flags.native === true ? true : str6(flags.native));
65440
66020
  } catch (error) {
65441
66021
  io.error(JSON.stringify({ error: error.message }));
65442
66022
  return 2;
@@ -65453,7 +66033,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65453
66033
  }
65454
66034
  }
65455
66035
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
65456
- const out = mkdtempSync4(join56(tmpdir5(), "himi-test-"));
66036
+ const out = mkdtempSync4(join57(tmpdir5(), "himi-test-"));
65457
66037
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
65458
66038
  const outcome = await buildReleaseFromContent2(dir, out, {
65459
66039
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -65478,9 +66058,9 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65478
66058
  }
65479
66059
  let browserTimeoutMs;
65480
66060
  if (flags.timeout !== void 0) {
65481
- browserTimeoutMs = Number(str5(flags.timeout));
66061
+ browserTimeoutMs = Number(str6(flags.timeout));
65482
66062
  if (!Number.isFinite(browserTimeoutMs) || browserTimeoutMs <= 0) {
65483
- io.error(JSON.stringify({ error: `--timeout must be a positive number of ms (got "${str5(flags.timeout) ?? ""}")` }));
66063
+ io.error(JSON.stringify({ error: `--timeout must be a positive number of ms (got "${str6(flags.timeout) ?? ""}")` }));
65484
66064
  return 2;
65485
66065
  }
65486
66066
  }
@@ -65498,7 +66078,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65498
66078
  io.error(JSON.stringify({ error: `screen "${screen.screenId}" has no Tier-5 worker, so there is nothing for the browser loop to build` }));
65499
66079
  return 2;
65500
66080
  }
65501
- const sources = collectWorkerSources2(join56(dir, "tier5-src"), screen.bundleName);
66081
+ const sources = collectWorkerSources2(join57(dir, "tier5-src"), screen.bundleName);
65502
66082
  if (!sources) {
65503
66083
  io.error(JSON.stringify({ error: `no worker source found at tier5-src/${screen.bundleName} \u2014 the browser loop compiles SOURCE, not the built bundle` }));
65504
66084
  return 2;
@@ -65659,7 +66239,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65659
66239
  const sp = await runShotsPass2({
65660
66240
  descriptors: scopeDescriptors2(outcome.descriptors ?? [], pos.slice(1), invalidScreens),
65661
66241
  tokens: outcome.tokens,
65662
- outDir: join56(dir, ".himi", "shots"),
66242
+ outDir: join57(dir, ".himi", "shots"),
65663
66243
  width: 390,
65664
66244
  layers: { rules: shotRules, ...cmsSeed ? { cmsSeed } : {}, ...canned ? { canned: canned.byKey } : {} },
65665
66245
  ...budgetMs ? { budgetMs } : {},
@@ -65697,7 +66277,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65697
66277
  releaseId: result.releaseId,
65698
66278
  releasePayload: release,
65699
66279
  descriptors: attestedDescriptors,
65700
- screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join56(dir, ".himi", "shots", name)])),
66280
+ screenshots: Object.fromEntries(writtenShots.filter((name) => crawledScreens.has(name.replace(/\.png$/, ""))).map((name) => [name.replace(/\.png$/, ""), join57(dir, ".himi", "shots", name)])),
65701
66281
  coverage: {
65702
66282
  screens: crawledScreens.size,
65703
66283
  actionsDispatched: result.actions.exercised,
@@ -65731,15 +66311,15 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65731
66311
  io.error(JSON.stringify({ error: "render --remote cannot --dump-state: the serve plane has no worker runtime. Render locally to inspect state." }));
65732
66312
  return 2;
65733
66313
  }
65734
- const app2 = str5(flags.app);
65735
- const release2 = str5(flags.release);
66314
+ const app2 = str6(flags.app);
66315
+ const release2 = str6(flags.release);
65736
66316
  if (!app2 || !release2) {
65737
66317
  io.error(JSON.stringify({ error: "render --remote needs --app and --release" }));
65738
66318
  return 2;
65739
66319
  }
65740
- const scheme2 = str5(flags.scheme) === "dark" ? "dark" : "light";
66320
+ const scheme2 = str6(flags.scheme) === "dark" ? "dark" : "light";
65741
66321
  const wantPng2 = flags.png === true || typeof flags.png === "string";
65742
- const widthRaw = str5(flags.width);
66322
+ const widthRaw = str6(flags.width);
65743
66323
  const width = widthRaw ? Number(widthRaw) : void 0;
65744
66324
  let r2;
65745
66325
  try {
@@ -65770,7 +66350,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65770
66350
  }
65771
66351
  const dir = contentDir(flags);
65772
66352
  const app = await appId(dir);
65773
- const scheme = str5(flags.scheme) === "dark" ? "dark" : "light";
66353
+ const scheme = str6(flags.scheme) === "dark" ? "dark" : "light";
65774
66354
  const wantPng = flags.png === true || typeof flags.png === "string";
65775
66355
  const hydrate = flags.static !== true;
65776
66356
  const live2 = flags.live === true;
@@ -65781,13 +66361,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65781
66361
  }
65782
66362
  let injectedState;
65783
66363
  if (flags.state !== void 0) {
65784
- const stateArg = str5(flags.state);
66364
+ const stateArg = str6(flags.state);
65785
66365
  if (!stateArg || !stateArg.trim()) {
65786
66366
  io.error(JSON.stringify({ error: "--state was given but empty \u2014 pass inline JSON `{\u2026}` or a path to a .json file" }));
65787
66367
  return 2;
65788
66368
  }
65789
66369
  try {
65790
- const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync71(stateArg.replace(/^@/, ""), "utf8");
66370
+ const raw = stateArg.trim().startsWith("{") ? stateArg : readFileSync72(stateArg.replace(/^@/, ""), "utf8");
65791
66371
  injectedState = JSON.parse(raw);
65792
66372
  } catch (e) {
65793
66373
  io.error(JSON.stringify({ error: `--state must be inline JSON or a path to a .json file \u2014 ${e.message}` }));
@@ -65796,13 +66376,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65796
66376
  }
65797
66377
  let injectedInput;
65798
66378
  if (flags.input !== void 0) {
65799
- const inputArg = str5(flags.input);
66379
+ const inputArg = str6(flags.input);
65800
66380
  if (!inputArg || !inputArg.trim()) {
65801
66381
  io.error(JSON.stringify({ error: "--input was given but empty \u2014 pass inline JSON `{\u2026}` or a path to a .json file" }));
65802
66382
  return 2;
65803
66383
  }
65804
66384
  try {
65805
- const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync71(inputArg.replace(/^@/, ""), "utf8");
66385
+ const raw = inputArg.trim().startsWith("{") ? inputArg : readFileSync72(inputArg.replace(/^@/, ""), "utf8");
65806
66386
  const parsed = JSON.parse(raw);
65807
66387
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("must be a JSON object");
65808
66388
  injectedInput = parsed;
@@ -65812,7 +66392,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65812
66392
  }
65813
66393
  }
65814
66394
  const DEVICE_WIDTHS = renderDeviceWidths();
65815
- const deviceName = str5(flags.device);
66395
+ const deviceName = str6(flags.device);
65816
66396
  let renderWidth;
65817
66397
  if (deviceName) {
65818
66398
  renderWidth = DEVICE_WIDTHS[deviceName.toLowerCase()];
@@ -65837,7 +66417,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65837
66417
  } else if (typeof flags.width === "string" && flags.width) {
65838
66418
  renderWidth = Math.round(Number(flags.width));
65839
66419
  if (!Number.isFinite(renderWidth) || renderWidth <= 0) {
65840
- io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${str5(flags.width)}")` }));
66420
+ io.error(JSON.stringify({ error: `--width must be a positive number of pixels (got "${str6(flags.width)}")` }));
65841
66421
  return 2;
65842
66422
  }
65843
66423
  }
@@ -65845,13 +66425,13 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65845
66425
  if (typeof flags["load-budget"] === "string" && flags["load-budget"]) {
65846
66426
  loadBudgetMs = Number(flags["load-budget"]);
65847
66427
  if (!Number.isFinite(loadBudgetMs) || loadBudgetMs <= 0) {
65848
- io.error(JSON.stringify({ error: `--load-budget must be a positive number of ms (got "${str5(flags["load-budget"])}")` }));
66428
+ io.error(JSON.stringify({ error: `--load-budget must be a positive number of ms (got "${str6(flags["load-budget"])}")` }));
65849
66429
  return 2;
65850
66430
  }
65851
66431
  }
65852
66432
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
65853
66433
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
65854
- const out = mkdtempSync4(join56(tmpdir5(), "himi-render-"));
66434
+ const out = mkdtempSync4(join57(tmpdir5(), "himi-render-"));
65855
66435
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
65856
66436
  const outcome = await buildReleaseFromContent2(dir, out, {
65857
66437
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -65865,8 +66445,8 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
65865
66445
  const diagnostics = (outcome.lint ?? []).find((s) => s.screenId === screenId)?.issues ?? [];
65866
66446
  let pngFile;
65867
66447
  let attestationPngFile;
65868
- const shotPath = join56(dir, ".himi", "shots", `${screenId}.png`);
65869
- const pngTarget = typeof flags.png === "string" ? str5(flags.png) : flags.png === true ? shotPath : void 0;
66448
+ const shotPath = join57(dir, ".himi", "shots", `${screenId}.png`);
66449
+ const pngTarget = typeof flags.png === "string" ? str6(flags.png) : flags.png === true ? shotPath : void 0;
65870
66450
  if (pngTarget && r.pngBase64) {
65871
66451
  pngFile = writePngFile(pngTarget, r.pngBase64);
65872
66452
  attestationPngFile = resolve47(pngTarget) === resolve47(shotPath) ? pngFile : writePngFile(shotPath, r.pngBase64);
@@ -66047,7 +66627,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
66047
66627
  return report2(res.status, { wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
66048
66628
  }
66049
66629
  if (sub === "from-site") {
66050
- const book = str5(flags.book) ?? ".himi/business-book";
66630
+ const book = str6(flags.book) ?? ".himi/business-book";
66051
66631
  const logo = siteBookIcon2(book);
66052
66632
  if (!logo) {
66053
66633
  const absence = siteLogoAbsence2(book);
@@ -66062,7 +66642,7 @@ himi v${cliVersion()} \u2014 run \`himi --version\`. If authoring commands fail
66062
66642
  return report2(res.status, { from: logo, wrote: res.wrote, normalized: res.normalized, playListingIcon: res.playDerived });
66063
66643
  }
66064
66644
  if (sub === "generate") {
66065
- const res = await generateIcon2(dir, { glyph: str5(flags.glyph), background: str5(flags.accent), derivePlay: true });
66645
+ const res = await generateIcon2(dir, { glyph: str6(flags.glyph), background: str6(flags.accent), derivePlay: true });
66066
66646
  return report2(res.status, { wrote: res.wrote });
66067
66647
  }
66068
66648
  if (sub === "glyphs") {
@@ -66094,8 +66674,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66094
66674
  return report2.ok ? 0 : 1;
66095
66675
  }
66096
66676
  if (sub === "verify") {
66097
- const app = str5(flags.app) ?? await appId(dir);
66098
- const found = await fetchReleaseManifest(client2, app, str5(flags.release));
66677
+ const app = str6(flags.app) ?? await appId(dir);
66678
+ const found = await fetchReleaseManifest(client2, app, str6(flags.release));
66099
66679
  if ("error" in found) {
66100
66680
  io.error(JSON.stringify(found));
66101
66681
  return 1;
@@ -66105,9 +66685,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66105
66685
  return report2.ok ? 0 : 1;
66106
66686
  }
66107
66687
  if (sub === "add" || sub === "rm") {
66108
- const app = str5(flags.app) ?? await appId(dir);
66688
+ const app = str6(flags.app) ?? await appId(dir);
66109
66689
  const { contentReleaseId: contentReleaseId2 } = await Promise.resolve().then(() => (init_build3(), build_exports2));
66110
- const found = await fetchReleaseManifest(client2, app, str5(flags.release));
66690
+ const found = await fetchReleaseManifest(client2, app, str6(flags.release));
66111
66691
  if ("error" in found) {
66112
66692
  io.error(JSON.stringify(found));
66113
66693
  return 1;
@@ -66123,7 +66703,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66123
66703
  io.error(JSON.stringify({ error: "assets add needs a file: himi assets add <file> [--name <logical/name>]" }));
66124
66704
  return 2;
66125
66705
  }
66126
- const { payload, record: record2, name: name2 } = addAssetPayload2(manifest, file, { name: str5(flags.name), mintReleaseId: contentReleaseId2 });
66706
+ const { payload, record: record2, name: name2 } = addAssetPayload2(manifest, file, { name: str6(flags.name), mintReleaseId: contentReleaseId2 });
66127
66707
  const r2 = await client2().publishRelease(payload, {}, flags.live !== true);
66128
66708
  if (!r2.ok) {
66129
66709
  print({ ok: false, status: r2.status, body: r2.json ?? r2.text });
@@ -66192,8 +66772,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66192
66772
  io.error(JSON.stringify({ error: "pull needs an <app>", usage: "himi pull <app> [--release <id>] [--out <dir>] [--name <new>]" }));
66193
66773
  return 2;
66194
66774
  }
66195
- const renamed = str5(flags.name);
66196
- const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? wanted);
66775
+ const renamed = str6(flags.name);
66776
+ const dest = resolve47(str6(flags.out) ?? process.cwd(), renamed ?? wanted);
66197
66777
  const replace = flags.replace === true;
66198
66778
  const force = replace || flags.force === true;
66199
66779
  const linked = symlinkDestinationIssue(dest);
@@ -66214,7 +66794,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66214
66794
  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" }));
66215
66795
  return 1;
66216
66796
  }
66217
- if (replace && occupied && !existsSync60(join56(dest, "himalaya.content.json"))) {
66797
+ if (replace && occupied && !existsSync60(join57(dest, "himalaya.content.json"))) {
66218
66798
  io.error(JSON.stringify({
66219
66799
  error: `${dest} is not a content package \u2014 refusing to --replace it`,
66220
66800
  hint: "--replace only clears a directory that holds himalaya.content.json. Check --out/--name, or pass --force to merge into it instead."
@@ -66222,7 +66802,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66222
66802
  return 1;
66223
66803
  }
66224
66804
  }
66225
- const pulled = await client2().ownerSource(wanted, str5(flags.release));
66805
+ const pulled = await client2().ownerSource(wanted, str6(flags.release));
66226
66806
  if (!pulled.ok) {
66227
66807
  io.error(JSON.stringify({ ok: false, app: wanted, status: pulled.status, ...pulled.json ?? {} }));
66228
66808
  return 1;
@@ -66295,7 +66875,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66295
66875
  const declared = await appId(dir);
66296
66876
  let onlyRaw;
66297
66877
  if (flags.only !== void 0) {
66298
- onlyRaw = str5(flags.only);
66878
+ onlyRaw = str6(flags.only);
66299
66879
  if (!onlyRaw) {
66300
66880
  io.error(JSON.stringify({ error: "--only needs a selector", usage: ONLY_USAGE }));
66301
66881
  return 2;
@@ -66317,7 +66897,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66317
66897
  return 2;
66318
66898
  }
66319
66899
  }
66320
- if (flags["from-release"] !== void 0 && !str5(flags["from-release"])) {
66900
+ if (flags["from-release"] !== void 0 && !str6(flags["from-release"])) {
66321
66901
  io.error(JSON.stringify({ ok: false, error: "from_release_needs_a_value", message: "--from-release takes a release id to branch from. Omit the flag entirely to patch the live release.", usage: ONLY_USAGE }));
66322
66902
  return 2;
66323
66903
  }
@@ -66327,7 +66907,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66327
66907
  let ownerIssue;
66328
66908
  let pushToken;
66329
66909
  try {
66330
- const t = resolveTarget({ target: pushTarget, controlToken: str5(flags["control-token"]) });
66910
+ const t = resolveTarget({ target: pushTarget, controlToken: str6(flags["control-token"]) });
66331
66911
  ownerIssue = t.ownerIssue;
66332
66912
  pushToken = t.controlToken;
66333
66913
  } catch {
@@ -66353,7 +66933,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66353
66933
  const force = flags.force === true;
66354
66934
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
66355
66935
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
66356
- const out = mkdtempSync4(join56(tmpdir5(), "himi-push-"));
66936
+ const out = mkdtempSync4(join57(tmpdir5(), "himi-push-"));
66357
66937
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
66358
66938
  const outcome = await buildReleaseFromContent2(dir, out, {
66359
66939
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -66392,7 +66972,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66392
66972
  io.error(JSON.stringify(parsed.error, null, 2));
66393
66973
  return 2;
66394
66974
  }
66395
- const fromRelease = str5(flags["from-release"]);
66975
+ const fromRelease = str6(flags["from-release"]);
66396
66976
  const baseForPlan = await fetchReleaseManifest(client2, app, fromRelease);
66397
66977
  if ("error" in baseForPlan) {
66398
66978
  io.error(JSON.stringify(baseForPlan));
@@ -66441,7 +67021,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66441
67021
  let localSourceHash;
66442
67022
  try {
66443
67023
  const { collectAppSource: collectAppSource2, zipAppSource: zipAppSource2 } = await Promise.resolve().then(() => (init_app_source(), app_source_exports));
66444
- localSourceHash = createHash26("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
67024
+ localSourceHash = createHash27("sha256").update(zipAppSource2(collectAppSource2(dir).entries).toString("base64")).digest("hex");
66445
67025
  } catch {
66446
67026
  }
66447
67027
  return runReleasePatch({
@@ -66460,8 +67040,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66460
67040
  acceptPartial: flags["accept-partial"] === true,
66461
67041
  force,
66462
67042
  meta: {
66463
- ...str5(flags.label) ? { label: str5(flags.label) } : {},
66464
- ...str5(flags.notes) ? { notes: str5(flags.notes) } : {},
67043
+ ...str6(flags.label) ? { label: str6(flags.label) } : {},
67044
+ ...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
66465
67045
  ...hasErrors ? { forcedPastErrors: true } : {}
66466
67046
  },
66467
67047
  ...localSourceHash ? { localSourceHash } : {},
@@ -66581,8 +67161,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66581
67161
  if (!visArg) return 2;
66582
67162
  const visibility = visArg.value ?? await contentVisibility(dir);
66583
67163
  const meta = {
66584
- ...str5(flags.label) ? { label: str5(flags.label) } : {},
66585
- ...str5(flags.notes) ? { notes: str5(flags.notes) } : {},
67164
+ ...str6(flags.label) ? { label: str6(flags.label) } : {},
67165
+ ...str6(flags.notes) ? { notes: str6(flags.notes) } : {},
66586
67166
  ...visibility ? { visibility } : {},
66587
67167
  ...attestation ? { attestation } : {},
66588
67168
  ...forcedPastErrors ? { forcedPastErrors: true } : {}
@@ -66614,7 +67194,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66614
67194
  let adoptedSlug;
66615
67195
  if (flags["no-claim"] !== true) {
66616
67196
  if (ownerIssue && pushToken && !tokenCoversApp(pushToken, app)) {
66617
- const claim = await autoClaimSlug({ ownerIssue, controlToken: pushToken, app, accountId: str5(flags["account-id"]) });
67197
+ const claim = await autoClaimSlug({ ownerIssue, controlToken: pushToken, app, accountId: str6(flags["account-id"]) });
66618
67198
  if (claim.fatal) {
66619
67199
  io.error(JSON.stringify({
66620
67200
  ok: false,
@@ -66791,7 +67371,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66791
67371
  // goes. `push` hands it to a serve plane, `pack` hands it to a FILE, so an app can
66792
67372
  // be emailed, dropped on a static host, or opened from Files with no serve at all.
66793
67373
  case "pack": {
66794
- const format = str5(flags.format) ?? "zip";
67374
+ const format = str6(flags.format) ?? "zip";
66795
67375
  if (format !== "zip" && format !== "dir") {
66796
67376
  io.error(JSON.stringify({ error: `unknown --format ${JSON.stringify(format)}`, formats: ["zip", "dir"] }));
66797
67377
  return 2;
@@ -66806,13 +67386,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66806
67386
  return 2;
66807
67387
  }
66808
67388
  const { packRelease: packRelease2, packReleaseToDir: packReleaseToDir2 } = await Promise.resolve().then(() => (init_pack(), pack_exports));
66809
- const displayName = str5(flags.name);
67389
+ const displayName = str6(flags.name);
66810
67390
  const launchMode = flags.snapshot === true ? "snapshot" : "live";
66811
67391
  const packOpts = { createdBy: `himi-cli ${cliVersion()}`, launchMode, ...displayName ? { displayName } : {} };
66812
67392
  const writePack = (root, appName, out, source) => format === "dir" ? packReleaseToDir2(root, appName, out, packOpts) : packRelease2(root, appName, out, { ...packOpts, ...source ? { source } : {} });
66813
- const releaseDir = str5(flags["release-dir"]);
67393
+ const releaseDir = str6(flags["release-dir"]);
66814
67394
  if (releaseDir) {
66815
- const only = str5(flags.app);
67395
+ const only = str6(flags.app);
66816
67396
  if (!only) {
66817
67397
  io.error(JSON.stringify({ error: "--release-dir needs --app (a release store holds many apps)" }));
66818
67398
  return 2;
@@ -66825,7 +67405,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66825
67405
  return 2;
66826
67406
  }
66827
67407
  try {
66828
- const res = writePack(resolve47(releaseDir), only, resolve47(str5(flags.out) ?? process.cwd()));
67408
+ const res = writePack(resolve47(releaseDir), only, resolve47(str6(flags.out) ?? process.cwd()));
66829
67409
  print({
66830
67410
  ok: true,
66831
67411
  app: res.app,
@@ -66874,7 +67454,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66874
67454
  }
66875
67455
  const { buildContentForValidation: buildContentForValidation2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
66876
67456
  const bres = await buildContentForValidation2(dir, { resolution: resolutionFlag(flags) });
66877
- const built = mkdtempSync4(join56(tmpdir5(), "himi-pack-"));
67457
+ const built = mkdtempSync4(join57(tmpdir5(), "himi-pack-"));
66878
67458
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
66879
67459
  const outcome = await buildReleaseFromContent2(dir, built, {
66880
67460
  ...hasWorkers ? { tier5Dir: bundleOutDir2(dir) } : {},
@@ -66896,7 +67476,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66896
67476
  return 1;
66897
67477
  }
66898
67478
  try {
66899
- const res = writePack(built, app, resolve47(str5(flags.out) ?? dir), sourceArchive);
67479
+ const res = writePack(built, app, resolve47(str6(flags.out) ?? dir), sourceArchive);
66900
67480
  print({
66901
67481
  ok: true,
66902
67482
  app: res.app,
@@ -66964,7 +67544,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66964
67544
  io.error(JSON.stringify({ ok: false, error: "app_source_not_in_package", detail: `${HIMI_PACKAGE_SOURCE_PATH2} is absent despite the header declaring it` }));
66965
67545
  return 1;
66966
67546
  }
66967
- const renamed = str5(flags.name);
67547
+ const renamed = str6(flags.name);
66968
67548
  const idsToCheck = renamed ? [["--name", renamed]] : [["package", opened.header.app]];
66969
67549
  for (const [what, value] of idsToCheck) {
66970
67550
  if (!isSafeAppId2(value)) {
@@ -66977,7 +67557,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
66977
67557
  return 1;
66978
67558
  }
66979
67559
  }
66980
- const dest = resolve47(str5(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
67560
+ const dest = resolve47(str6(flags.out) ?? process.cwd(), renamed ?? opened.header.app);
66981
67561
  const issue2 = restoreDestinationIssue(dest, flags.force === true);
66982
67562
  if (issue2) {
66983
67563
  io.error(JSON.stringify(issue2));
@@ -67041,7 +67621,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67041
67621
  case "share": {
67042
67622
  const sub = pos[1];
67043
67623
  if (sub === "revoke") {
67044
- const app = str5(flags.app);
67624
+ const app = str6(flags.app);
67045
67625
  const shareId = pos[2];
67046
67626
  if (!app || !shareId) {
67047
67627
  io.error(JSON.stringify({ error: "himi share revoke needs --app <app> <shareId>" }));
@@ -67055,7 +67635,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67055
67635
  print({ ok: true, ...result.json });
67056
67636
  return 0;
67057
67637
  }
67058
- const file = str5(flags.file);
67638
+ const file = str6(flags.file);
67059
67639
  if (!file) {
67060
67640
  io.error(JSON.stringify({ error: "himi share needs --file <package.himi>; create it with `himi pack --out <file>`" }));
67061
67641
  return 2;
@@ -67077,13 +67657,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67077
67657
  }));
67078
67658
  return 1;
67079
67659
  }
67080
- const archive = readFileSync71(resolve47(file));
67660
+ const archive = readFileSync72(resolve47(file));
67081
67661
  const result = await client2().createPackageShare({
67082
67662
  app: opened.header.app,
67083
67663
  releaseId: opened.header.releaseId,
67084
67664
  launchMode: opened.header.launchMode ?? "snapshot",
67085
67665
  archiveBase64: archive.toString("base64"),
67086
- ...str5(flags["expires-at"]) ? { expiresAt: str5(flags["expires-at"]) } : {}
67666
+ ...str6(flags["expires-at"]) ? { expiresAt: str6(flags["expires-at"]) } : {}
67087
67667
  });
67088
67668
  if (!result.ok) {
67089
67669
  print({ ok: false, status: result.status, body: result.json ?? result.text });
@@ -67116,7 +67696,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67116
67696
  flags.content = watchedDir;
67117
67697
  source = void 0;
67118
67698
  }
67119
- const conflict = watchFlagConflict2({ source, browser: flags.browser === true, spa: str5(flags.spa) });
67699
+ const conflict = watchFlagConflict2({ source, browser: flags.browser === true, spa: str6(flags.spa) });
67120
67700
  if (conflict) {
67121
67701
  io.error(JSON.stringify({ ok: false, ...conflict }));
67122
67702
  return 2;
@@ -67130,22 +67710,22 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67130
67710
  const app = await appId(dir2);
67131
67711
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
67132
67712
  const bres = await buildContentBundles2(dir2, { resolution: resolutionFlag(flags) });
67133
- temp = mkdtempSync4(join56(tmpdir5(), "himi-run-build-"));
67713
+ temp = mkdtempSync4(join57(tmpdir5(), "himi-run-build-"));
67134
67714
  const hasWorkers = bres.built.length > 0 || bres.compileErrors.length > 0;
67135
67715
  const initial = await buildReleaseFromContent2(dir2, temp, { ...hasWorkers ? { tier5Dir: bundleOutDir2(dir2) } : {} });
67136
67716
  servedMissing = initial.missingBundles;
67137
- source = join56(temp, app);
67717
+ source = join57(temp, app);
67138
67718
  }
67139
- const chromeArg = str5(flags.chrome) ?? "preview";
67719
+ const chromeArg = str6(flags.chrome) ?? "preview";
67140
67720
  if (chromeArg !== "preview" && chromeArg !== "app") {
67141
67721
  io.error(JSON.stringify({ error: `unknown --chrome ${JSON.stringify(chromeArg)}`, values: ["preview", "app"] }));
67142
67722
  return 2;
67143
67723
  }
67144
67724
  let port;
67145
67725
  if (flags.port !== void 0) {
67146
- port = Number(str5(flags.port));
67726
+ port = Number(str6(flags.port));
67147
67727
  if (!Number.isInteger(port) || port < 0 || port > 65535) {
67148
- io.error(JSON.stringify({ error: `--port needs a number 0-65535, got ${JSON.stringify(str5(flags.port) ?? "")}` }));
67728
+ io.error(JSON.stringify({ error: `--port needs a number 0-65535, got ${JSON.stringify(str6(flags.port) ?? "")}` }));
67149
67729
  return 2;
67150
67730
  }
67151
67731
  }
@@ -67171,13 +67751,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67171
67751
  const dir = contentDir(flags);
67172
67752
  const watchKit = watch2 ? await Promise.resolve().then(() => (init_run_watch(), run_watch_exports)) : null;
67173
67753
  const bus = watchKit ? new watchKit.ReloadBus() : void 0;
67174
- if (watch2) served = mkdtempSync4(join56(tmpdir5(), "himi-run-served-"));
67754
+ if (watch2) served = mkdtempSync4(join57(tmpdir5(), "himi-run-served-"));
67175
67755
  const running = await runPackage2(source, {
67176
67756
  port,
67177
67757
  chrome: chromeArg,
67178
- screen: str5(flags.screen),
67179
- surface: str5(flags.surface),
67180
- spa: str5(flags.spa),
67758
+ screen: str6(flags.screen),
67759
+ surface: str6(flags.surface),
67760
+ spa: str6(flags.spa),
67181
67761
  open: flags["no-open"] !== true,
67182
67762
  ...watchKit && served && bus ? { workDir: served, screenEvents: bus, extraRoutes: (request) => watchKit.boardFile(dir, new URL(request.url).pathname) } : {}
67183
67763
  });
@@ -67197,11 +67777,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67197
67777
  if (watchKit.writeRunRecord(dir, { url: running.url, port: running.port, pid: process.pid, startedAt, build: build2 })) recorded = true;
67198
67778
  };
67199
67779
  record2({ ok: true, at: startedAt });
67200
- if (!recorded) io.error(JSON.stringify({ watch: "run_record_skipped", message: `${join56(dir, ".himi")} is not a real directory, so the build board will not frame this preview.` }));
67780
+ if (!recorded) io.error(JSON.stringify({ watch: "run_record_skipped", message: `${join57(dir, ".himi")} is not a real directory, so the build board will not frame this preview.` }));
67201
67781
  await refreshBoard();
67202
67782
  const { buildContentBundles: buildContentBundles2, buildReleaseFromContent: buildReleaseFromContent2, bundleOutDir: bundleOutDir2 } = await loadAuthoring();
67203
- const live2 = join56(running.releaseRoot, running.app);
67204
- const manifestOf = (tree) => JSON.parse(readFileSync71(join56(tree, "release-manifest.json"), "utf8"));
67783
+ const live2 = join57(running.releaseRoot, running.app);
67784
+ const manifestOf = (tree) => JSON.parse(readFileSync72(join57(tree, "release-manifest.json"), "utf8"));
67205
67785
  let current = manifestOf(live2);
67206
67786
  const failed2 = async (message) => {
67207
67787
  if (stopping) return;
@@ -67212,7 +67792,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67212
67792
  };
67213
67793
  rebuild = watchKit.serialize(async () => {
67214
67794
  const t0 = Date.now();
67215
- const next = mkdtempSync4(join56(tmpdir5(), "himi-run-build-"));
67795
+ const next = mkdtempSync4(join57(tmpdir5(), "himi-run-build-"));
67216
67796
  try {
67217
67797
  const bres = await buildContentBundles2(dir, { resolution: resolutionFlag(flags) });
67218
67798
  if (bres.compileErrors.length) {
@@ -67229,14 +67809,14 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67229
67809
  return;
67230
67810
  }
67231
67811
  if (stopping) return;
67232
- const fresh = manifestOf(join56(next, running.app));
67812
+ const fresh = manifestOf(join57(next, running.app));
67233
67813
  const diff = watchKit.diffReleases(current, fresh);
67234
67814
  const retired = `${live2}.retired-${Date.now()}`;
67235
67815
  renameSync6(live2, retired);
67236
67816
  try {
67237
- renameSync6(join56(next, running.app), live2);
67817
+ renameSync6(join57(next, running.app), live2);
67238
67818
  } catch {
67239
- cpSync3(join56(next, running.app), live2, { recursive: true });
67819
+ cpSync3(join57(next, running.app), live2, { recursive: true });
67240
67820
  }
67241
67821
  rmSync13(retired, { recursive: true, force: true });
67242
67822
  current = fresh;
@@ -67298,15 +67878,15 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67298
67878
  }
67299
67879
  }
67300
67880
  case "preview": {
67301
- const app = str5(flags.app);
67302
- const release = str5(flags.release);
67881
+ const app = str6(flags.app);
67882
+ const release = str6(flags.release);
67303
67883
  if (!app || !release) {
67304
67884
  io.error(JSON.stringify({ error: "preview needs --app and --release" }));
67305
67885
  return 2;
67306
67886
  }
67307
67887
  const base = serveBase();
67308
- const screen = str5(flags.screen);
67309
- const surface = str5(flags.surface);
67888
+ const screen = str6(flags.screen);
67889
+ const surface = str6(flags.surface);
67310
67890
  if (surface && !surfaceById(surface)) {
67311
67891
  io.error(JSON.stringify({
67312
67892
  error: `unknown --surface "${surface}"`,
@@ -67314,22 +67894,22 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67314
67894
  }));
67315
67895
  return 2;
67316
67896
  }
67317
- let previewToken = str5(flags["preview-token"]);
67897
+ let previewToken = str6(flags["preview-token"]);
67318
67898
  let previewTokenExpiresAt;
67319
67899
  let previewHandover;
67320
67900
  let mintedHere = false;
67321
67901
  let mintFailure;
67322
67902
  if (!previewToken) {
67323
67903
  const target = resolveTarget({
67324
- target: str5(flags.target),
67904
+ target: str6(flags.target),
67325
67905
  // Same default as `client()` (#2483.1) — without it this resolved a DIFFERENT target
67326
67906
  // than the request that follows, so off-repo the mint was attempted against `local`.
67327
67907
  defaultTarget: contextualDefaultTarget,
67328
- serveUrl: str5(flags["serve-url"]),
67329
- telemetryUrl: str5(flags["telemetry-url"]),
67330
- controlUrl: str5(flags["control-url"]),
67331
- telemetryToken: str5(flags["telemetry-token"]),
67332
- controlToken: str5(flags["control-token"])
67908
+ serveUrl: str6(flags["serve-url"]),
67909
+ telemetryUrl: str6(flags["telemetry-url"]),
67910
+ controlUrl: str6(flags["control-url"]),
67911
+ telemetryToken: str6(flags["telemetry-token"]),
67912
+ controlToken: str6(flags["control-token"])
67333
67913
  });
67334
67914
  if (!target.controlToken) {
67335
67915
  mintFailure = `this target has no stored control credential, so none was requested \u2014 run \`himi login --target ${targetName()}\`, or pass --control-token`;
@@ -67390,8 +67970,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67390
67970
  case "surfaces": {
67391
67971
  const dir = contentDir(flags);
67392
67972
  const platforms = readLocalPlatforms(dir);
67393
- const app = str5(flags.app);
67394
- const release = str5(flags.release);
67973
+ const app = str6(flags.app);
67974
+ const release = str6(flags.release);
67395
67975
  const base = serveBase();
67396
67976
  const withLinks = !!(app && release && base);
67397
67977
  const produced = flags["measure-widgets"] === true ? await producedWidgetFamilies(dir) : { families: void 0, source: "not-measured" };
@@ -67443,16 +68023,16 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67443
68023
  return 0;
67444
68024
  }
67445
68025
  case "context": {
67446
- const app = str5(flags.app);
67447
- const release = str5(flags.release);
68026
+ const app = str6(flags.app);
68027
+ const release = str6(flags.release);
67448
68028
  if (!app || !release) {
67449
68029
  io.error(JSON.stringify({ error: "context needs --app and --release" }));
67450
68030
  return 2;
67451
68031
  }
67452
- const include = str5(flags.include);
68032
+ const include = str6(flags.include);
67453
68033
  let r;
67454
68034
  try {
67455
- r = await client2().previewContext(app, release, { screen: str5(flags.screen), include });
68035
+ r = await client2().previewContext(app, release, { screen: str6(flags.screen), include });
67456
68036
  } catch (e) {
67457
68037
  io.error(JSON.stringify({
67458
68038
  error: `cannot reach serve for context: ${e.message}. Pass --target bo.`,
@@ -67467,8 +68047,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67467
68047
  }
67468
68048
  case "app-docs": {
67469
68049
  const subcommand = pos[1] ?? "list";
67470
- const app = str5(flags.app);
67471
- const release = str5(flags.release) ?? str5(flags.releaseId);
68050
+ const app = str6(flags.app);
68051
+ const release = str6(flags.release) ?? str6(flags.releaseId);
67472
68052
  if (!app) {
67473
68053
  io.error(JSON.stringify({ error: "app-docs needs --app" }));
67474
68054
  return 2;
@@ -67496,15 +68076,15 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67496
68076
  return 0;
67497
68077
  }
67498
68078
  case "telemetry": {
67499
- const app = str5(flags.app);
67500
- const release = str5(flags.release) ?? str5(flags.releaseId);
68079
+ const app = str6(flags.app);
68080
+ const release = str6(flags.release) ?? str6(flags.releaseId);
67501
68081
  if (!app || !release) {
67502
68082
  io.error(JSON.stringify({ error: "telemetry needs --app and --release" }));
67503
68083
  return 2;
67504
68084
  }
67505
68085
  const c = client2();
67506
68086
  const target = targetName();
67507
- const level = str5(flags.level);
68087
+ const level = str6(flags.level);
67508
68088
  const byLevel = (ls) => level ? ls.filter((l) => l.level === level) : ls;
67509
68089
  const includeEvents = flags["no-events"] !== true;
67510
68090
  const includeLogs = flags["no-logs"] !== true;
@@ -67519,8 +68099,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67519
68099
  if (includeEvents) {
67520
68100
  const r = await c.telemetryEvents(app, {
67521
68101
  releaseId: release,
67522
- screenId: str5(flags.screen) ?? str5(flags.screenId),
67523
- event: str5(flags.type) ?? str5(flags.event),
68102
+ screenId: str6(flags.screen) ?? str6(flags.screenId),
68103
+ event: str6(flags.type) ?? str6(flags.event),
67524
68104
  since: eventSince,
67525
68105
  limit: num2(flags.limit),
67526
68106
  crashesOnly: flags["crashes-only"] === true || flags.crashesOnly === true
@@ -67533,7 +68113,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67533
68113
  if (includeLogs) {
67534
68114
  const r = await c.telemetryLogs(app, {
67535
68115
  releaseId: release,
67536
- screenId: str5(flags.screen) ?? str5(flags.screenId),
68116
+ screenId: str6(flags.screen) ?? str6(flags.screenId),
67537
68117
  since: logSince,
67538
68118
  limit: num2(flags.limit)
67539
68119
  });
@@ -67555,7 +68135,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67555
68135
  }
67556
68136
  const eventCount = out.events?.length ?? 0;
67557
68137
  const logCount = out.logs?.length ?? 0;
67558
- const narrowed = !!(level || str5(flags.screen) || str5(flags.screenId) || str5(flags.type) || str5(flags.event) || flags["crashes-only"] === true || flags.crashesOnly === true || num2(flags.limit) !== void 0 || eventSince !== void 0 || logSince !== void 0);
68138
+ const narrowed = !!(level || str6(flags.screen) || str6(flags.screenId) || str6(flags.type) || str6(flags.event) || flags["crashes-only"] === true || flags.crashesOnly === true || num2(flags.limit) !== void 0 || eventSince !== void 0 || logSince !== void 0);
67559
68139
  const wholeChannels = includeEvents && includeLogs && !narrowed;
67560
68140
  if (wholeChannels && eventCount === 0 && logCount === 0 && !includeSummary && !includeCrashes) {
67561
68141
  out.note = "no events and no worker console output on this release \u2014 open the web preview or Himi Player link for it, then retry or use --follow";
@@ -67599,8 +68179,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67599
68179
  }
67600
68180
  }
67601
68181
  case "screens": {
67602
- const app = str5(flags.app);
67603
- const release = str5(flags.release);
68182
+ const app = str6(flags.app);
68183
+ const release = str6(flags.release);
67604
68184
  if (!app || !release) {
67605
68185
  io.error(JSON.stringify({ error: "screens needs --app and --release" }));
67606
68186
  return 2;
@@ -67621,8 +68201,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67621
68201
  }
67622
68202
  case "diagnose": {
67623
68203
  const screenId = pos[1];
67624
- const app = str5(flags.app);
67625
- const release = str5(flags.release);
68204
+ const app = str6(flags.app);
68205
+ const release = str6(flags.release);
67626
68206
  if (!screenId || !app || !release) {
67627
68207
  io.error(JSON.stringify({ error: "diagnose needs <screenId> --app --release" }));
67628
68208
  return 2;
@@ -67647,8 +68227,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67647
68227
  return body.ok === false ? 1 : 0;
67648
68228
  }
67649
68229
  case "deeplinks": {
67650
- const app = str5(flags.app);
67651
- const release = str5(flags.release);
68230
+ const app = str6(flags.app);
68231
+ const release = str6(flags.release);
67652
68232
  if (!app || !release) {
67653
68233
  io.error(JSON.stringify({ error: "deeplinks needs --app and --release" }));
67654
68234
  return 2;
@@ -67668,13 +68248,13 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67668
68248
  return 0;
67669
68249
  }
67670
68250
  case "logs": {
67671
- const app = str5(flags.app);
68251
+ const app = str6(flags.app);
67672
68252
  if (!app) {
67673
68253
  io.error(JSON.stringify({ error: "logs needs --app" }));
67674
68254
  return 2;
67675
68255
  }
67676
- const release = str5(flags.release);
67677
- const level = str5(flags.level);
68256
+ const release = str6(flags.release);
68257
+ const level = str6(flags.level);
67678
68258
  const byLevel = (ls) => level ? ls.filter((l) => l.level === level) : ls;
67679
68259
  const num3 = (v) => typeof v === "string" && v ? Number(v) : void 0;
67680
68260
  const c = client2();
@@ -67683,7 +68263,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67683
68263
  try {
67684
68264
  r = await c.telemetryLogs(app, {
67685
68265
  releaseId: release,
67686
- screenId: str5(flags.screen) ?? str5(flags.screenId),
68266
+ screenId: str6(flags.screen) ?? str6(flags.screenId),
67687
68267
  since: num3(flags.since),
67688
68268
  limit: num3(flags.limit)
67689
68269
  });
@@ -67701,7 +68281,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67701
68281
  }
67702
68282
  const rawLogs = r.json?.logs ?? [];
67703
68283
  const logs = byLevel(rawLogs);
67704
- const narrowed = !!(level || str5(flags.screen) || str5(flags.screenId) || num3(flags.since) !== void 0 || num3(flags.limit) !== void 0);
68284
+ const narrowed = !!(level || str6(flags.screen) || str6(flags.screenId) || num3(flags.since) !== void 0 || num3(flags.limit) !== void 0);
67705
68285
  const scope = release ? "this release" : "this app";
67706
68286
  const note = logs.length > 0 ? void 0 : narrowed ? `no worker \`console.*\` lines matched this query${level && rawLogs.length ? ` (${rawLogs.length} line(s) were hidden by --level ${level})` : ""}. Drop --level/--screen/--since/--limit to see the whole console channel for ${scope}; the telemetry EVENT stream is a separate channel, read with \`himi telemetry\`.` : `no worker \`console.*\` output on ${scope}. This is the console channel \u2014 distinct from the telemetry EVENT stream, which \`himi telemetry --app <app> --release <id>\` reads: ${scope} can carry many events and no console lines \u2014 commonly because the worker never logged any, though an empty channel can also mean the lines aged out or never made it through ingestion. Boot-time \`console.log\` is visible via \`himi validate\` / \`himi render\`.`;
67707
68287
  print({ ok: true, logs, ...note ? { note } : {} });
@@ -67711,7 +68291,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67711
68291
  const deadline = num3(flags.for) !== void 0 ? Date.now() + num3(flags.for) : Infinity;
67712
68292
  let since = num3(flags.since) ?? 0;
67713
68293
  for (; ; ) {
67714
- const r = await c.telemetryLogs(app, { releaseId: release, screenId: str5(flags.screen) ?? str5(flags.screenId), since });
68294
+ const r = await c.telemetryLogs(app, { releaseId: release, screenId: str6(flags.screen) ?? str6(flags.screenId), since });
67715
68295
  if (r.ok) {
67716
68296
  const logs = r.json?.logs ?? [];
67717
68297
  for (const l of byLevel(logs)) io.log(JSON.stringify(l));
@@ -67722,8 +68302,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67722
68302
  }
67723
68303
  }
67724
68304
  case "promote": {
67725
- const app = str5(flags.app);
67726
- const release = str5(flags.release);
68305
+ const app = str6(flags.app);
68306
+ const release = str6(flags.release);
67727
68307
  if (!app || !release) {
67728
68308
  io.error(JSON.stringify({ error: "promote needs --app and --release" }));
67729
68309
  return 2;
@@ -67731,7 +68311,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67731
68311
  const target = targetName();
67732
68312
  const force = flags.force === true;
67733
68313
  const ringGiven = flags.ring !== void 0;
67734
- const ring = str5(flags.ring);
68314
+ const ring = str6(flags.ring);
67735
68315
  if (ringGiven && !ring) {
67736
68316
  io.error(JSON.stringify({ error: "--ring needs a ring name, e.g. --ring ga" }));
67737
68317
  return 2;
@@ -67829,8 +68409,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67829
68409
  }));
67830
68410
  return 2;
67831
68411
  }
67832
- const app = str5(flags.app) ?? await appId(contentDir(flags));
67833
- const file = str5(flags.file);
68412
+ const app = str6(flags.app) ?? await appId(contentDir(flags));
68413
+ const file = str6(flags.file);
67834
68414
  if (!file) {
67835
68415
  io.error(JSON.stringify({ error: `patch ${kind} needs --file`, usage: PATCH_USAGE }));
67836
68416
  return 2;
@@ -67841,7 +68421,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67841
68421
  }
67842
68422
  const draft = patchBlastRadius(PATCH_USAGE);
67843
68423
  if (draft === null) return 2;
67844
- const notes = str5(flags.notes);
68424
+ const notes = str6(flags.notes);
67845
68425
  if (!draft && (kind === "screen" || kind === "app-config") && !notes) {
67846
68426
  io.error(JSON.stringify({
67847
68427
  ok: false,
@@ -67852,11 +68432,11 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67852
68432
  }));
67853
68433
  return 2;
67854
68434
  }
67855
- if (flags["from-release"] !== void 0 && !str5(flags["from-release"])) {
68435
+ if (flags["from-release"] !== void 0 && !str6(flags["from-release"])) {
67856
68436
  io.error(JSON.stringify({ ok: false, error: "from_release_needs_a_value", message: "--from-release takes a release id to branch from. Omit the flag entirely to patch the live release.", usage: PATCH_USAGE }));
67857
68437
  return 2;
67858
68438
  }
67859
- const fromRelease = str5(flags["from-release"]);
68439
+ const fromRelease = str6(flags["from-release"]);
67860
68440
  const baseOrRefuse = (manifest) => {
67861
68441
  if (manifest) return true;
67862
68442
  io.error(JSON.stringify({
@@ -67874,7 +68454,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67874
68454
  const patchGitSha = defaultGitOps2(contentDir(flags)).shortSha() ?? "dev";
67875
68455
  const meta = {
67876
68456
  gitSha: patchGitSha,
67877
- ...str5(flags.label) ? { label: str5(flags.label) } : {},
68457
+ ...str6(flags.label) ? { label: str6(flags.label) } : {},
67878
68458
  ...notes ? { notes } : {}
67879
68459
  };
67880
68460
  const common = {
@@ -67891,7 +68471,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67891
68471
  lintNote: "`himi patch` sends a raw file. Nothing here built or linted your app \u2014 `himi push --only <selector>` is the same edit with the full lint gate in front of it."
67892
68472
  };
67893
68473
  if (kind === "tokens" || kind === "app-config") {
67894
- const body = readFileSync71(file, "utf8");
68474
+ const body = readFileSync72(file, "utf8");
67895
68475
  const patch2 = kind === "tokens" ? { tokens: body } : { appConfig: body };
67896
68476
  return runReleasePatch({
67897
68477
  ...common,
@@ -67906,7 +68486,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67906
68486
  io.error(JSON.stringify({ error: "patch screen needs a <screenId>", usage: PATCH_USAGE }));
67907
68487
  return 2;
67908
68488
  }
67909
- const descriptor = readFileSync71(file, "utf8");
68489
+ const descriptor = readFileSync72(file, "utf8");
67910
68490
  try {
67911
68491
  JSON.parse(descriptor);
67912
68492
  } catch (e) {
@@ -67935,7 +68515,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67935
68515
  io.error(JSON.stringify({ ok: false, error: "bundle_flag_needs_a_value", message: "--bundle takes a bundle sha256, or the literal `none` to unbind the screen.", usage: PATCH_USAGE }));
67936
68516
  return 2;
67937
68517
  }
67938
- const bundleFlag = str5(flags.bundle);
68518
+ const bundleFlag = str6(flags.bundle);
67939
68519
  const bundle = bundleFlag === "none" ? null : bundleFlag;
67940
68520
  if (!baseOrRefuse(baseFound.manifest)) return 1;
67941
68521
  return runReleasePatch({
@@ -67946,9 +68526,9 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
67946
68526
  extra: { kind, screen: id, file: { path: file, bytes: Buffer.byteLength(descriptor, "utf8") } }
67947
68527
  });
67948
68528
  }
67949
- const bytes2 = readFileSync71(file);
67950
- const sha = createHash26("sha256").update(bytes2).digest("hex");
67951
- const forScreens = (str5(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
68529
+ const bytes2 = readFileSync72(file);
68530
+ const sha = createHash27("sha256").update(bytes2).digest("hex");
68531
+ const forScreens = (str6(flags["for-screen"]) ?? "").split(",").map((s) => s.trim()).filter(Boolean);
67952
68532
  if (flags["no-rebind"] !== void 0 && flags["no-rebind"] !== true) {
67953
68533
  io.error(JSON.stringify({ ok: false, error: "no_rebind_takes_no_value", message: "--no-rebind is a switch and takes no value; pass it bare.", usage: PATCH_USAGE }));
67954
68534
  return 2;
@@ -68037,7 +68617,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
68037
68617
  // READ of the device-facing door, and what that read says is what gets printed.
68038
68618
  case "flags": {
68039
68619
  const sub = pos[1];
68040
- const app = str5(flags.app) ?? await appId(contentDir(flags));
68620
+ const app = str6(flags.app) ?? await appId(contentDir(flags));
68041
68621
  const usage = "usage: himi flags list | set <key> --definition <json|@file> | ramp <key> [--percent 0-100] [--enabled true|false] | rm <key>";
68042
68622
  if (sub !== "list" && sub !== "set" && sub !== "ramp" && sub !== "rm") {
68043
68623
  io.error(JSON.stringify({ error: `unknown flags subcommand: ${sub ?? "(none)"}`, hint: usage }));
@@ -68083,14 +68663,14 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
68083
68663
  return 2;
68084
68664
  }
68085
68665
  if (sub === "set") {
68086
- const arg = str5(flags.definition);
68666
+ const arg = str6(flags.definition);
68087
68667
  if (!arg) {
68088
68668
  io.error(JSON.stringify({ error: "flags set needs --definition <json|@file>", hint: usage }));
68089
68669
  return 2;
68090
68670
  }
68091
68671
  let def;
68092
68672
  try {
68093
- const parsed = JSON.parse(arg.startsWith("@") ? readFileSync71(arg.slice(1), "utf8") : arg);
68673
+ const parsed = JSON.parse(arg.startsWith("@") ? readFileSync72(arg.slice(1), "utf8") : arg);
68094
68674
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
68095
68675
  io.error(JSON.stringify({ error: "invalid_definition", problems: [`--definition must be a JSON object, got ${Array.isArray(parsed) ? "an array" : parsed === null ? "null" : typeof parsed}`] }));
68096
68676
  return 2;
@@ -68135,7 +68715,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
68135
68715
  return 2;
68136
68716
  }
68137
68717
  const enabledGiven = flags.enabled !== void 0;
68138
- const enabledRaw = flags.enabled === true ? "true" : str5(flags.enabled);
68718
+ const enabledRaw = flags.enabled === true ? "true" : str6(flags.enabled);
68139
68719
  if (enabledGiven && enabledRaw !== "true" && enabledRaw !== "false") {
68140
68720
  io.error(JSON.stringify({ error: `--enabled must be true or false, got ${String(flags.enabled)}` }));
68141
68721
  return 2;
@@ -68213,7 +68793,7 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
68213
68793
  io.error(JSON.stringify({ error: `visibility takes public|unlisted (got "${value}")` }));
68214
68794
  return 2;
68215
68795
  }
68216
- const app = str5(flags.app) ?? await appId(contentDir(flags));
68796
+ const app = str6(flags.app) ?? await appId(contentDir(flags));
68217
68797
  let r;
68218
68798
  try {
68219
68799
  r = value === void 0 ? await client2().appSettings(app) : await client2().setVisibility(app, value);
@@ -68235,8 +68815,8 @@ default (no --glyph): ${DEFAULT_GLYPH2} \u2014 a mark that claims nothing, so th
68235
68815
  // a minBinaryVersion floor bump.
68236
68816
  case "store":
68237
68817
  case "testflight": {
68238
- if (str5(flags.provider) === "wix-mobile-release") {
68239
- const playerTarget = wixPlayerTestflightTarget(str5(flags.target));
68818
+ if (str6(flags.provider) === "wix-mobile-release") {
68819
+ const playerTarget = wixPlayerTestflightTarget(str6(flags.target));
68240
68820
  if (!playerTarget) {
68241
68821
  io.error(JSON.stringify({ error: "Wix Mobile Release requires deployed --target bo or --target prod; local/custom targets cannot hold the Himi service identity" }));
68242
68822
  return 2;
@@ -68470,8 +69050,8 @@ ${label2}`);
68470
69050
  io.error(JSON.stringify({ error: "dist watch needs a <jobId>" }));
68471
69051
  return 2;
68472
69052
  }
68473
- const intervalMs2 = Number(str5(flags.interval)) || 2e4;
68474
- const deadline2 = Date.now() + (Number(str5(flags.timeout)) || 45 * 6e4);
69053
+ const intervalMs2 = Number(str6(flags.interval)) || 2e4;
69054
+ const deadline2 = Date.now() + (Number(str6(flags.timeout)) || 45 * 6e4);
68475
69055
  let announced = false;
68476
69056
  for (; ; ) {
68477
69057
  let s;
@@ -68513,14 +69093,14 @@ ${label2}`);
68513
69093
  }
68514
69094
  }
68515
69095
  if (sub === "list") {
68516
- const app2 = str5(flags.app) ?? await appId(contentDir(flags));
69096
+ const app2 = str6(flags.app) ?? await appId(contentDir(flags));
68517
69097
  if (!app2) {
68518
69098
  io.error(JSON.stringify({ error: "dist list needs --app" }));
68519
69099
  return 2;
68520
69100
  }
68521
69101
  let r2;
68522
69102
  try {
68523
- r2 = await c.distList(app2, Number(str5(flags.limit)) || void 0);
69103
+ r2 = await c.distList(app2, Number(str6(flags.limit)) || void 0);
68524
69104
  } catch (e) {
68525
69105
  return distUnreachable(e);
68526
69106
  }
@@ -68546,15 +69126,15 @@ ${label2}`);
68546
69126
  io.error(JSON.stringify({ error: `unknown dist subcommand "${sub}" \u2014 use status | watch | list | cancel, or no subcommand to start a build` }));
68547
69127
  return 2;
68548
69128
  }
68549
- const app = str5(flags.app) ?? await appId(contentDir(flags));
69129
+ const app = str6(flags.app) ?? await appId(contentDir(flags));
68550
69130
  if (!app) {
68551
69131
  io.error(JSON.stringify({ error: "dist needs --app (or a content dir whose himalaya.content.json names one)" }));
68552
69132
  return 2;
68553
69133
  }
68554
- const platform = str5(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
69134
+ const platform = str6(flags.platform)?.split(",").map((p) => p.trim()).filter(Boolean);
68555
69135
  {
68556
69136
  const distDir = contentDir(flags);
68557
- if (existsSync60(join56(distDir, "himalaya.content.json"))) {
69137
+ if (existsSync60(join57(distDir, "himalaya.content.json"))) {
68558
69138
  const issues = await iconIssues(distDir, flags.strict === true, { requireDeclared: true, requireVerified: true });
68559
69139
  const errors = issues.filter((i) => i.severity === "error");
68560
69140
  for (const i of issues.filter((i2) => i2.severity === "warning")) {
@@ -68572,31 +69152,31 @@ ${label2}`);
68572
69152
  }
68573
69153
  }
68574
69154
  const { captchaContentInput: captchaContentInput2 } = await Promise.resolve().then(() => (init_captcha2(), captcha_exports));
68575
- const captchaSiteId = str5(flags.site) ?? captchaContentInput2(contentDir(flags)).siteId;
69155
+ const captchaSiteId = str6(flags.site) ?? captchaContentInput2(contentDir(flags)).siteId;
68576
69156
  let r;
68577
69157
  try {
68578
69158
  r = await c.distCreate({
68579
69159
  app,
68580
69160
  ...platform?.length ? { platform } : {},
68581
- ...str5(flags.release) ? { release: str5(flags.release) } : {},
69161
+ ...str6(flags.release) ? { release: str6(flags.release) } : {},
68582
69162
  ...flags["allow-draft"] === true ? { allowDraft: true } : {},
68583
69163
  ...captchaSiteId ? { captchaSiteId } : {},
68584
- ...str5(flags.shell) ? { shell: str5(flags.shell) } : {},
69164
+ ...str6(flags.shell) ? { shell: str6(flags.shell) } : {},
68585
69165
  // INTERIM, iOS only: sign under an internal enterprise id the Mac pool already holds a
68586
69166
  // profile for, because no profile covers a himi shell's own id yet. The serve plane
68587
69167
  // refuses anything outside its allow-list (internal `ent.*` only — never a store id).
68588
69168
  // flags["borrow-ios-id"], NOT flags.borrowIosId — parseFlags does no kebab→camel
68589
69169
  // conversion (see line ~58), so the camel form reads undefined and the flag would be a
68590
69170
  // silent no-op. Every other multi-word flag here uses the bracket form for the same reason.
68591
- ...str5(flags["borrow-ios-id"]) ? { borrowIosBundleId: str5(flags["borrow-ios-id"]) } : {},
68592
- ...str5(flags.destination) ? { destination: str5(flags.destination) } : {},
68593
- ...str5(flags.signing) ? { signing: str5(flags.signing) } : {},
69171
+ ...str6(flags["borrow-ios-id"]) ? { borrowIosBundleId: str6(flags["borrow-ios-id"]) } : {},
69172
+ ...str6(flags.destination) ? { destination: str6(flags.destination) } : {},
69173
+ ...str6(flags.signing) ? { signing: str6(flags.signing) } : {},
68594
69174
  // WHICH KEYSTORE signs the APK. A separate axis from --signing (that one is the Apple
68595
69175
  // account), so a `--platform ios,android` build can say "Wix-managed on iOS, the QA
68596
69176
  // keystore on Android" — the normal combination — with one command.
68597
69177
  // flags["android-signing"], NOT flags.androidSigning: parseFlags does no kebab→camel
68598
69178
  // conversion, so the camel form reads undefined and the flag is a silent no-op.
68599
- ...str5(flags["android-signing"]) ? { androidSigning: str5(flags["android-signing"]) } : {}
69179
+ ...str6(flags["android-signing"]) ? { androidSigning: str6(flags["android-signing"]) } : {}
68600
69180
  });
68601
69181
  } catch (e) {
68602
69182
  return distUnreachable(e);
@@ -68611,14 +69191,14 @@ ${label2}`);
68611
69191
  if (noWait) {
68612
69192
  print({ status: r.status, ...r.json ?? {} });
68613
69193
  if (!flags.json) {
68614
- const t = str5(flags.target);
69194
+ const t = str6(flags.target);
68615
69195
  const targetArg = t ? ` --target ${t}` : "";
68616
69196
  for (const j of jobs) io.log(` ${j.platform} ${j.jobId} \u2192 himi dist status ${j.jobId}${targetArg}`);
68617
69197
  }
68618
69198
  return 0;
68619
69199
  }
68620
- const intervalMs = Number(str5(flags.interval)) || 2e4;
68621
- const timeoutMs = Number(str5(flags.timeout)) || 45 * 6e4;
69200
+ const intervalMs = Number(str6(flags.interval)) || 2e4;
69201
+ const timeoutMs = Number(str6(flags.timeout)) || 45 * 6e4;
68622
69202
  const deadline = Date.now() + timeoutMs;
68623
69203
  const pending = new Map(jobs.map((j) => [String(j.jobId), String(j.platform)]));
68624
69204
  const done = [];
@@ -68660,7 +69240,7 @@ ${label2}`);
68660
69240
  let issue2;
68661
69241
  let ownerIssue;
68662
69242
  try {
68663
- const t = resolveTarget({ target, issueUrl: str5(flags["issue-url"]), ownerIssueUrl: str5(flags["owner-issue-url"]) });
69243
+ const t = resolveTarget({ target, issueUrl: str6(flags["issue-url"]), ownerIssueUrl: str6(flags["owner-issue-url"]) });
68664
69244
  issue2 = t.issue;
68665
69245
  ownerIssue = t.ownerIssue;
68666
69246
  } catch (e) {
@@ -68823,7 +69403,7 @@ ${label2}`);
68823
69403
  const dpxPath = dpxSessionTokenPath();
68824
69404
  let dpx;
68825
69405
  try {
68826
- dpx = readFileSync71(dpxPath, "utf8").trim();
69406
+ dpx = readFileSync72(dpxPath, "utf8").trim();
68827
69407
  } catch {
68828
69408
  io.error(JSON.stringify({ error: `no dpx session at ${dpxPath} \u2014 run \`dpx auth login\` then \`dpx auth token > ${dpxPath}\` (dpx 2.x keeps its own state in ~/.dpx/auth.json and does NOT write the legacy session file), or omit --dpx` }));
68829
69409
  return 1;
@@ -68859,7 +69439,7 @@ ${label2}`);
68859
69439
  const target = targetName();
68860
69440
  let ownerIssue;
68861
69441
  try {
68862
- ownerIssue = resolveTarget({ target, ownerIssueUrl: str5(flags["owner-issue-url"]) }).ownerIssue;
69442
+ ownerIssue = resolveTarget({ target, ownerIssueUrl: str6(flags["owner-issue-url"]) }).ownerIssue;
68863
69443
  } catch (e) {
68864
69444
  io.error(JSON.stringify({ error: e.message }));
68865
69445
  return 2;
@@ -68875,10 +69455,10 @@ ${label2}`);
68875
69455
  }
68876
69456
  const base = ownerIssue.replace(/\/$/, "");
68877
69457
  const sub = pos[1];
68878
- const cookie = str5(flags.cookie) ?? process.env.HIMI_WIX_COOKIE;
69458
+ const cookie = str6(flags.cookie) ?? process.env.HIMI_WIX_COOKIE;
68879
69459
  let ownerToken;
68880
69460
  try {
68881
- ownerToken = resolveTarget({ target, controlToken: str5(flags["control-token"]) }).controlToken;
69461
+ ownerToken = resolveTarget({ target, controlToken: str6(flags["control-token"]) }).controlToken;
68882
69462
  } catch {
68883
69463
  }
68884
69464
  if (!cookie && !ownerToken) {
@@ -68898,9 +69478,9 @@ ${label2}`);
68898
69478
  return 2;
68899
69479
  }
68900
69480
  const body = { slug };
68901
- const dn = str5(flags["display-name"]);
69481
+ const dn = str6(flags["display-name"]);
68902
69482
  if (dn) body.displayName = dn;
68903
- const acct = str5(flags["account-id"]);
69483
+ const acct = str6(flags["account-id"]);
68904
69484
  if (acct) body.accountId = acct;
68905
69485
  const r2 = await fetch(`${base}/v1/owner/apps/claim`, { method: "POST", redirect: "error", headers: { ...headers2, "content-type": "application/json" }, body: JSON.stringify(body) });
68906
69486
  const j2 = await r2.json().catch(() => ({}));
@@ -69020,8 +69600,8 @@ ${label2}`);
69020
69600
  try {
69021
69601
  const t = resolveTarget({
69022
69602
  target,
69023
- controlUrl: str5(flags["control-url"]),
69024
- controlToken: str5(flags["control-token"])
69603
+ controlUrl: str6(flags["control-url"]),
69604
+ controlToken: str6(flags["control-token"])
69025
69605
  });
69026
69606
  if (t.controlToken && t.control) {
69027
69607
  const revokeRefusal = credentialHostRefusal(t.control);
@@ -69099,8 +69679,8 @@ ${label2}`);
69099
69679
  }
69100
69680
  case "doctor": {
69101
69681
  const target = targetName();
69102
- const timeoutMs = Number(str5(flags.timeout)) > 0 ? Number(str5(flags.timeout)) : DOCTOR_TIMEOUT_MS;
69103
- const dataUrl = str5(flags["data-url"]) ?? process.env.HIMI_DATA_URL ?? PUBLIC_WIX_API_BASE;
69682
+ const timeoutMs = Number(str6(flags.timeout)) > 0 ? Number(str6(flags.timeout)) : DOCTOR_TIMEOUT_MS;
69683
+ const dataUrl = str6(flags["data-url"]) ?? process.env.HIMI_DATA_URL ?? PUBLIC_WIX_API_BASE;
69104
69684
  let resolved2;
69105
69685
  let serveUrl = "";
69106
69686
  let targetError;
@@ -69110,9 +69690,9 @@ ${label2}`);
69110
69690
  // Passing `str(flags.target)` re-ran resolution without `defaultTarget`, so off-repo
69111
69691
  // doctor labelled its report `wix` while probing the `local` URLs.
69112
69692
  target,
69113
- serveUrl: str5(flags["serve-url"]),
69114
- controlUrl: str5(flags["control-url"]),
69115
- controlToken: str5(flags["control-token"])
69693
+ serveUrl: str6(flags["serve-url"]),
69694
+ controlUrl: str6(flags["control-url"]),
69695
+ controlToken: str6(flags["control-token"])
69116
69696
  });
69117
69697
  serveUrl = resolved2.serve;
69118
69698
  } catch (e) {
@@ -69216,7 +69796,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69216
69796
  const { BO_FUNCTIONS_BASE_URL: BO_FUNCTIONS_BASE_URL2, resolveFunctionsTarget: resolveFunctionsTarget2 } = await Promise.resolve().then(() => (init_functions(), functions_exports));
69217
69797
  let secretTarget;
69218
69798
  try {
69219
- secretTarget = resolveFunctionsTarget2({ target: str5(flags.target), functionsUrl: str5(flags["functions-url"]), releaseId: str5(flags.release) });
69799
+ secretTarget = resolveFunctionsTarget2({ target: str6(flags.target), functionsUrl: str6(flags["functions-url"]), releaseId: str6(flags.release) });
69220
69800
  } catch (error) {
69221
69801
  io.error(JSON.stringify({ error: error.message }));
69222
69802
  return 1;
@@ -69225,7 +69805,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69225
69805
  const path2 = dpxSessionTokenPath();
69226
69806
  let raw;
69227
69807
  try {
69228
- raw = readFileSync71(path2, "utf8");
69808
+ raw = readFileSync72(path2, "utf8");
69229
69809
  } catch {
69230
69810
  io.error(JSON.stringify({ error: `no DPX BO session at ${path2}` }));
69231
69811
  return 1;
@@ -69269,20 +69849,20 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69269
69849
  let site;
69270
69850
  let call;
69271
69851
  try {
69272
- site = resolveSiteId(str5(flags.site));
69852
+ site = resolveSiteId(str6(flags.site));
69273
69853
  call = ownerTransport(site);
69274
69854
  } catch (error) {
69275
69855
  io.error(JSON.stringify({ error: error.message }));
69276
69856
  return 2;
69277
69857
  }
69278
- const environment2 = str5(flags.environment) ?? "preview";
69858
+ const environment2 = str6(flags.environment) ?? "preview";
69279
69859
  if (environment2 !== "preview" && environment2 !== "production") {
69280
69860
  io.error(JSON.stringify({ error: "--environment must be preview or production" }));
69281
69861
  return 2;
69282
69862
  }
69283
69863
  let kv;
69284
69864
  if (data.kv?.length) {
69285
- const baseUrl = str5(flags["data-url"]) ?? process.env.HIMI_DATA_ADMIN_URL;
69865
+ const baseUrl = str6(flags["data-url"]) ?? process.env.HIMI_DATA_ADMIN_URL;
69286
69866
  const token = process.env.HIMI_DATA_ADMIN_TOKEN;
69287
69867
  if (!baseUrl || !token) {
69288
69868
  io.error(JSON.stringify({ error: "KV declarations require --data-url/HIMI_DATA_ADMIN_URL and HIMI_DATA_ADMIN_TOKEN for the operator data plane", app, site, environment: environment2 }));
@@ -69354,7 +69934,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69354
69934
  return 1;
69355
69935
  }
69356
69936
  if (sub === "seed" && flags.ai === true) {
69357
- const res = await writeSeedRows({ app, cms, dir, count: Number(str5(flags.count)) || 8 });
69937
+ const res = await writeSeedRows({ app, cms, dir, count: Number(str6(flags.count)) || 8 });
69358
69938
  print(res);
69359
69939
  return res.ok ? 0 : 1;
69360
69940
  }
@@ -69371,7 +69951,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69371
69951
  let call;
69372
69952
  let site;
69373
69953
  try {
69374
- site = resolveSiteId(str5(flags.site));
69954
+ site = resolveSiteId(str6(flags.site));
69375
69955
  call = ownerTransport(site);
69376
69956
  } catch (e) {
69377
69957
  io.error(JSON.stringify({ error: e.message }));
@@ -69380,7 +69960,7 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69380
69960
  const common = { app, cms, call };
69381
69961
  let report2;
69382
69962
  try {
69383
- report2 = sub === "query" ? await queryCms({ ...common, all: flags.all === true }) : sub === "create" ? await createCms({ ...common, dryRun: flags["dry-run"] === true, allowDestructive: flags["allow-destructive"] === true, applyPermissions: flags["apply-permissions"] === true }) : await seedCms({ ...common, dir, dryRun: flags["dry-run"] === true, force: flags.force === true, only: str5(flags.only) });
69963
+ report2 = sub === "query" ? await queryCms({ ...common, all: flags.all === true }) : sub === "create" ? await createCms({ ...common, dryRun: flags["dry-run"] === true, allowDestructive: flags["allow-destructive"] === true, applyPermissions: flags["apply-permissions"] === true }) : await seedCms({ ...common, dir, dryRun: flags["dry-run"] === true, force: flags.force === true, only: str6(flags.only) });
69384
69964
  } catch (e) {
69385
69965
  const partial = e.partial;
69386
69966
  io.error(JSON.stringify({
@@ -69403,17 +69983,17 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69403
69983
  const r = await runSiteFunctionCli2({
69404
69984
  op: pos[2],
69405
69985
  name: pos[3],
69406
- siteFlag: str5(flags.site),
69407
- siteUrl: str5(flags.url) ?? str5(flags["site-url"]) ?? process.env.WIX_SITE_URL,
69408
- clientId: str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID,
69409
- method: str5(flags.method),
69410
- sourcePath: str5(flags.source),
69411
- bodyRaw: str5(flags.body),
69986
+ siteFlag: str6(flags.site),
69987
+ siteUrl: str6(flags.url) ?? str6(flags["site-url"]) ?? process.env.WIX_SITE_URL,
69988
+ clientId: str6(flags["client-id"]) ?? process.env.WIX_CLIENT_ID,
69989
+ method: str6(flags.method),
69990
+ sourcePath: str6(flags.source),
69991
+ bodyRaw: str6(flags.body),
69412
69992
  publish: flags.publish === true,
69413
69993
  invoke: flags.invoke === true,
69414
69994
  dryRun: flags["dry-run"] === true,
69415
69995
  visitor: flags.visitor === true,
69416
- cwd: str5(flags.content) ?? process.cwd()
69996
+ cwd: str6(flags.content) ?? process.cwd()
69417
69997
  });
69418
69998
  print(r);
69419
69999
  return r.ok ? 0 : 1;
@@ -69435,17 +70015,17 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69435
70015
  }
69436
70016
  try {
69437
70017
  const r = op === "list" ? await runSiteClientList2({
69438
- siteFlag: str5(flags.site),
69439
- redirectUri: str5(flags["redirect-uri"])
70018
+ siteFlag: str6(flags.site),
70019
+ redirectUri: str6(flags["redirect-uri"])
69440
70020
  }) : await runSiteClientEnsure2({
69441
- siteFlag: str5(flags.site),
69442
- name: str5(flags.name),
69443
- redirectUri: str5(flags["redirect-uri"]),
70021
+ siteFlag: str6(flags.site),
70022
+ name: str6(flags.name),
70023
+ redirectUri: str6(flags["redirect-uri"]),
69444
70024
  new: flags.new === true,
69445
70025
  yes: flags.yes === true,
69446
70026
  // Bare `--write-provisioning` is the default path; with a value it is that path.
69447
- writeProvisioning: flags["write-provisioning"] === true ? true : str5(flags["write-provisioning"]),
69448
- siteUrl: str5(flags["site-url"]) ?? str5(flags.url)
70027
+ writeProvisioning: flags["write-provisioning"] === true ? true : str6(flags["write-provisioning"]),
70028
+ siteUrl: str6(flags["site-url"]) ?? str6(flags.url)
69449
70029
  });
69450
70030
  print(r);
69451
70031
  return r.ok ? 0 : 1;
@@ -69468,15 +70048,15 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69468
70048
  try {
69469
70049
  const r = sub === "list" ? await runSiteList2() : await runSiteCreate2({
69470
70050
  name: pos[2],
69471
- type: str5(flags.type),
69472
- templateId: str5(flags.template),
69473
- verticals: str5(flags.verticals),
69474
- folderId: str5(flags.folder),
69475
- redirectUri: str5(flags["redirect-uri"]),
70051
+ type: str6(flags.type),
70052
+ templateId: str6(flags.template),
70053
+ verticals: str6(flags.verticals),
70054
+ folderId: str6(flags.folder),
70055
+ redirectUri: str6(flags["redirect-uri"]),
69476
70056
  noOauthApp: flags["no-oauth-app"] === true,
69477
70057
  // Bare `--write-provisioning` is the default path; with a value it is that path.
69478
- writeProvisioning: flags["write-provisioning"] === true ? true : str5(flags["write-provisioning"]),
69479
- siteUrl: str5(flags["site-url"]),
70058
+ writeProvisioning: flags["write-provisioning"] === true ? true : str6(flags["write-provisioning"]),
70059
+ siteUrl: str6(flags["site-url"]),
69480
70060
  yes: flags.yes === true,
69481
70061
  // The argv as typed, so the dry run echoes back a command that actually
69482
70062
  // recreates THIS plan. Reconstructing it from the fields above would
@@ -69495,14 +70075,14 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69495
70075
  io.error(JSON.stringify({ error: sub ? `unknown site subcommand "${sub}"` : "site needs a subcommand", usage: `himi site create <name> [--type wix|headless|branded-app|vibe] --yes | himi site list | himi site client ensure|list --site <msid> | himi site analyze --client-id <id> --url <https://\u2026> [--site <msid>] [--out <dir>] [--apply [--shell <id>]] | himi site function list|get|put|publish|invoke \u2026` }));
69496
70076
  return 2;
69497
70077
  }
69498
- const clientId = str5(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
69499
- const siteUrl = str5(flags.url) ?? str5(flags["site-url"]);
70078
+ const clientId = str6(flags["client-id"]) ?? process.env.WIX_CLIENT_ID;
70079
+ const siteUrl = str6(flags.url) ?? str6(flags["site-url"]);
69500
70080
  if (flags["read-only"] === true) {
69501
70081
  if (flags.apply || flags.out || flags.shell || flags["redirect-uri"]) {
69502
70082
  io.error(JSON.stringify({ error: "--read-only returns API context only; it cannot be combined with --apply, --out, --shell, or --redirect-uri" }));
69503
70083
  return 2;
69504
70084
  }
69505
- const siteId = str5(flags.site) ?? process.env.WIX_SITE_ID;
70085
+ const siteId = str6(flags.site) ?? process.env.WIX_SITE_ID;
69506
70086
  if (!clientId && !siteId && !process.env.WIX_TEST_TOKEN?.trim()) {
69507
70087
  io.error(JSON.stringify({ error: "--read-only needs --site, --client-id, or a site-scoped WIX_TEST_TOKEN" }));
69508
70088
  return 2;
@@ -69544,16 +70124,16 @@ ${report2.ok ? "OK \u2014 data + serve plane reachable." : typeof report2.hint =
69544
70124
  const r = await runSiteAnalyze2({
69545
70125
  clientId,
69546
70126
  siteUrl,
69547
- siteFlag: str5(flags.site),
69548
- outDir: str5(flags.out),
70127
+ siteFlag: str6(flags.site),
70128
+ outDir: str6(flags.out),
69549
70129
  apply: flags.apply === true,
69550
- shell: str5(flags.shell),
70130
+ shell: str6(flags.shell),
69551
70131
  // A redirect already REGISTERED on --client-id, recorded into the applied binding.
69552
70132
  // Analyze cannot discover it (GET-only; the registered list lives behind
69553
70133
  // `oauth-app/v1`), and the shell refuses to reuse its own default once a customer
69554
70134
  // client is in play — so it is passed in by whoever registered it.
69555
- redirectUri: str5(flags["redirect-uri"]),
69556
- cwd: str5(flags.content) ?? process.cwd()
70135
+ redirectUri: str6(flags["redirect-uri"]),
70136
+ cwd: str6(flags.content) ?? process.cwd()
69557
70137
  });
69558
70138
  print({ ok: true, ...r });
69559
70139
  return 0;