@wix/himalaya-cli 0.1007.0 → 0.1008.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.
Binary file
@@ -126,9 +126,10 @@
126
126
  "category": "Core",
127
127
  "propsType": "ButtonProps",
128
128
  "bindings": [
129
+ "disabledPath",
129
130
  "title"
130
131
  ],
131
- "propsSource": "export interface ButtonProps {\n /** Button label — binding-aware (\"$item.\"/\"$service:\") on web, iOS and Android. */\n title: string;\n action: Action;\n style?: string;\n /** Literal only, NOT bindable: a `\"$service:…\"` string here fails `validate`, and there is no\n * `disabledPath`. To disable from worker state, author two buttons — the live one and a\n * `disabled: true` copy — and swap them with complementary `modifiers.hiddenPath` flags\n * (e.g. `canSubmit` / `cannotSubmit`); also guard the action so a stray tap is a no-op. */\n disabled?: boolean;\n /** Capability enrichments. */\n leadingIcon?: IconRef;\n trailingIcon?: IconRef;\n loading?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n fullWidth?: boolean;\n iconOnly?: boolean;\n /** #1049 — corner radius; reshapes the button (overrides the forced pill). */\n cornerRadius?: number;\n /** #1049 — minimum height (pt/dp/px). */\n minHeight?: number;\n}"
132
+ "propsSource": "export interface ButtonProps {\n /** Button label — binding-aware (\"$item.\"/\"$service:\") on web, iOS and Android. */\n title: string;\n action: Action;\n style?: string;\n /** LITERAL disabled state. A `\"$service:…\"` string here fails `validate` (the wire type is\n * bool) — bind `disabledPath` instead. */\n disabled?: boolean;\n /** #3117 — `$service:`/`$item.` binding → a live bool that disables the button while true\n * (e.g. a submit while a request is in flight). Binding-aware. OR'd with `disabled`,\n * `loading` and an enclosing Form's validity: a bound `false` never re-enables a button one\n * of those disabled, and an unresolved binding leaves the literal in charge. */\n disabledPath?: string;\n /** Capability enrichments. */\n leadingIcon?: IconRef;\n trailingIcon?: IconRef;\n loading?: boolean;\n size?: \"sm\" | \"md\" | \"lg\";\n fullWidth?: boolean;\n iconOnly?: boolean;\n /** #1049 — corner radius; reshapes the button (overrides the forced pill). */\n cornerRadius?: number;\n /** #1049 — minimum height (pt/dp/px). */\n minHeight?: number;\n}"
132
133
  },
133
134
  {
134
135
  "name": "TextField",
@@ -40,7 +40,7 @@ See also **[Modifiers](#modifiers)** (the `modifiers` block) and **[Actions](#ac
40
40
  | `Text` | Core | `text` |
41
41
  | `Image` | Core | `url`, `initials`, `contentDescription` |
42
42
  | `Icon` | Core | — |
43
- | `Button` | Core | `title` |
43
+ | `Button` | Core | `disabledPath`, `title` |
44
44
  | `TextField` | Core | `valuePath`, `focusPath`, `errorPath` |
45
45
  | `Toggle` | Core | `valuePath` |
46
46
  | `Stepper` | Core | `valuePath` |
@@ -486,11 +486,14 @@ export interface ButtonProps {
486
486
  title: string;
487
487
  action: Action;
488
488
  style?: string;
489
- /** Literal only, NOT bindable: a `"$service:…"` string here fails `validate`, and there is no
490
- * `disabledPath`. To disable from worker state, author two buttons — the live one and a
491
- * `disabled: true` copy — and swap them with complementary `modifiers.hiddenPath` flags
492
- * (e.g. `canSubmit` / `cannotSubmit`); also guard the action so a stray tap is a no-op. */
489
+ /** LITERAL disabled state. A `"$service:…"` string here fails `validate` (the wire type is
490
+ * bool) — bind `disabledPath` instead. */
493
491
  disabled?: boolean;
492
+ /** #3117 — `$service:`/`$item.` binding → a live bool that disables the button while true
493
+ * (e.g. a submit while a request is in flight). Binding-aware. OR'd with `disabled`,
494
+ * `loading` and an enclosing Form's validity: a bound `false` never re-enables a button one
495
+ * of those disabled, and an unresolved binding leaves the literal in charge. */
496
+ disabledPath?: string;
494
497
  /** Capability enrichments. */
495
498
  leadingIcon?: IconRef;
496
499
  trailingIcon?: IconRef;
@@ -158,6 +158,11 @@ shape (heading swap, `savedScreenId`, back-navigation).
158
158
  defensively (`String(v ?? "")`, `v === true`).
159
159
  - **Disable double-submit UX-side is not needed** — actions serialize per worker;
160
160
  but DO return a `saving` status if the write is slow so the UI can reflect it.
161
+ To grey the submit out meanwhile, keep a boolean beside it (e.g. `busy: true`
162
+ while the write runs) and bind the submit button's `disabledPath:
163
+ "$service:<svc>.busy"` — `disabledPath` wants a bool, not the `status` string.
164
+ It only ever ADDS a reason to be disabled: a bound `false` never re-enables a
165
+ submit the form's own validation is holding.
161
166
  - **`himi render` shows the initial (empty) form** — prefill bindings resolve to
162
167
  initial state; a real submit needs the pushed preview or a device drive.
163
168
 
@@ -14,6 +14,22 @@ areas, always in the same order, so you can skim for the one you care about.
14
14
 
15
15
  ---
16
16
 
17
+ ## 2026-09-24
18
+
19
+ ### Getting started & the CLI
20
+
21
+ - **`himi template trim --keep <ids>` cuts a scaffolded template down to the screens you want,
22
+ then proves it still validates.** A starter template ships every screen in one generated
23
+ `dev/index.ts` — about 1.8 MB for `gym-fitness` and 4.5 MB for `branded-lite` — so trimming by
24
+ hand meant deleting blocks from that file and then hunting down every navigation row and worker
25
+ that still pointed at them. The command removes the other screens, their `linkableScreens`,
26
+ tab, drawer and deep-link entries, and the `tier5-src/` workers no kept screen uses, then runs
27
+ `himi validate --strict` and puts every file back if it fails. A kept screen that links to a
28
+ removed one is refused unless you pass `--links follow` (keep those too) or `--links drop`
29
+ (remove the taps), and `--dry-run` prints the plan without writing. `himi docs trim-a-template`
30
+ no longer tells you `validate --strict` catches a tab pointing at a deleted screen: it does not,
31
+ and `himi test` is what reports it. (#3149)
32
+
17
33
  ## 2026-09-18
18
34
 
19
35
  ### Logic, data & SDKs
@@ -85,7 +85,9 @@ back to the offline copy — so it never hard-fails. Then run the normal loop
85
85
  **`branded-lite` is a full reference, not a small starter.** After `himi init --template
86
86
  branded-lite`, trim it or mine it rather than deleting `tier5-src/` + `dev/` and starting from
87
87
  blank. **Trim** when most of the approved `SPEC.md` is screens the template already has: delete
88
- the rest. **Mine** when few of its screens match: keep the `tier5-src/_shared/` helpers and the
88
+ the rest with `himi template trim --keep <screen ids> --links drop`, which removes the other
89
+ screens, their navigation rows and the workers nothing else uses, and rolls back unless
90
+ `himi validate --strict` still passes (`--dry-run` shows the plan first). **Mine** when few of its screens match: keep the `tier5-src/_shared/` helpers and the
89
91
  Wix worker chains, and write your own screens in `dev/index.ts` — the file holds every screen
90
92
  as a raw descriptor (megabytes for the full templates), so replacing it is often faster than
91
93
  editing it. Both paths, and how `dev/index.ts`, `tier5-src/`, and `navigation.linkableScreens`
@@ -13,7 +13,10 @@ away the live Wix wiring the template exists to give you. Vertical overlays reth
13
13
  copy/tokens; they do not shrink the screen count. There are two ways to keep that wiring:
14
14
 
15
15
  - **Trim it** when the approved `SPEC.md` is mostly screens the template already has: keep
16
- those, **delete what the plan does not need** ([How to trim](#how-to-trim)).
16
+ those, **delete what the plan does not need**. `himi template trim --keep <ids>` does the whole
17
+ cut for you and proves it with `himi validate --strict`
18
+ ([Trim with one command](#trim-with-one-command)); the manual steps are
19
+ [below](#how-to-trim-by-hand) for when it refuses.
17
20
  - **Mine it** when the app's screens are its own and few template screens match — the
18
21
  realistic case for a multi-megabyte file of nested descriptors. Keep the worker layer,
19
22
  replace the screens ([Or mine it](#or-mine-it-keep-the-wix-plumbing-write-your-own-screens)).
@@ -32,10 +35,71 @@ A screen is not one file. After `himi init`, these three must agree:
32
35
  | `dev/index.ts` `SCREENS` map | The descriptors, as raw objects. After `himi init` the file is **yours** ("this file is yours now") — edit it, cut it down, or replace it. |
33
36
  | `config.ts` `navigation.linkableScreens` | Deep-link / tab targets. `himalaya://screen/<id>` resolves **only** if the id is listed here. Tab roots also appear under `navigation.tabBar.items`. |
34
37
 
35
- `himi validate --strict` fails if a tab/linkable id has no descriptor, or a descriptor
36
- has no worker when it declares `logicBundle`.
37
-
38
- ## How to trim
38
+ `himi validate --strict` fails when a descriptor declares a `logicBundle` whose worker is gone.
39
+ It does **not** check navigation against the screens: a `tabBar` item or `linkableScreens` id
40
+ with no descriptor passes `validate --strict` cleanly — only `himi test` reports it, as
41
+ `nav-target-missing`. So a hand trim that forgets `config.ts` ships a tab that opens nothing,
42
+ with a green validate. `himi template trim` checks this itself.
43
+
44
+ ## Trim with one command
45
+
46
+ ```sh
47
+ himi template trim --keep himi_shop,himi_product,himi_cart,himi_account --dry-run # the plan, nothing written
48
+ himi template trim --keep himi_shop,himi_product,himi_cart,himi_account --links drop # do it
49
+ ```
50
+
51
+ Run it in (or point `--content` at) the app `himi init --template` scaffolded — not the
52
+ template itself, which it refuses. `--keep` takes `SCREENS` ids and templated route ids (the
53
+ part before the brackets: `himi_product` for `himi_product[_{id}]`). The home screen is always
54
+ kept, and so is any screen the navigation pins — a drawer or sidebar body
55
+ (`contentScreenId`, which is how the owner templates draw their menu) or a drawer header's or
56
+ footer's target; both are listed under `implicit`. It prints one JSON report and:
57
+
58
+ - **deletes** every other `SCREENS` and `TEMPLATED` entry whole, so the blocks you keep stay
59
+ byte for byte as they were;
60
+ - **prunes navigation**: `linkableScreens` (a kept screen whose parent was removed is
61
+ re-parented to its nearest kept ancestor, and moved to a remaining tab when its tab went),
62
+ `tabBar`, `drawer` and `sidebar` items (a section header left with no rows goes too), deep
63
+ links, top-bar actions, surface destinations, and exact ids in `workerSubtreeScreens`;
64
+ - **removes** each `tier5-src/<worker>/` no kept screen still uses. Workers are shared between
65
+ screens, so a worker stays as long as one kept screen points at it; `tier5-src/_shared/`
66
+ always stays;
67
+ - **proves it**: runs `himi validate --strict`, and checks the rewritten navigation for any id it
68
+ removed. If either fails, every file and worker directory is put back exactly as it was and
69
+ the command exits `1`; `--force` keeps the trimmed tree anyway. While it runs, the originals
70
+ sit in `.himi/trim-backup/`, which is deleted once the trim validates (and kept under
71
+ `--force`). A failure while *writing* the trim (a worker directory it cannot move, say) is
72
+ always put back, `--force` or not — `--force` keeps a finished trim, never a half-done one.
73
+
74
+ **Links between screens.** A kept screen that opens a removed one (a `himi.open` whose
75
+ `screenId` is a literal) would be a dead tap, so by default the trim is **refused** — and the
76
+ refusal lists both ways out:
77
+
78
+ - `--links follow` keeps every screen the kept ones link to, as well (`addedByLinks` says which
79
+ link pulled each one in). On a branded home this grows quickly: the account screen alone links
80
+ to a dozen others.
81
+ - `--links drop` removes the taps instead: the buttons, rows, cards, menu rows and top-bar
82
+ actions that open a removed screen, a list whose every row would open one, and a home
83
+ section that holds nothing else (its row leaves the home's modules too). Home modules for a
84
+ vertical whose screens you removed (a bookings "Up next" once the booking screens are gone)
85
+ are dropped as well. `droppedLinks` names every node it took.
86
+
87
+ A screen id that is computed at runtime — `$item.detailScreenId`, or a worker building
88
+ `"himi_product_" + id` — cannot be judged from the descriptors. The trim searches the kept
89
+ workers' code for ids of removed screens instead and lists them under `warnings.workerRefs`
90
+ (`tier5-src/himi-store-shop/index.ts:83 → himi_product`): add those ids to `--keep` if the tap
91
+ should keep working.
92
+
93
+ It **refuses** (exit `2`, nothing written) when `--keep` is missing or names an id the app does
94
+ not serve (the report lists the ones it does), when the app's `dev/index.ts` or `config.ts` is
95
+ no longer in the shape `himi init` writes (a block, the `navigation` object or
96
+ `workerSubtreeScreens` that is not plain JSON), when kept screens link to removed ones and no `--links` was given, when no tab would be
97
+ left, and when dropping links would leave a kept screen empty or cannot reach a link. Then trim
98
+ by hand, below.
99
+
100
+ Afterwards: `himi render <each kept screen>`, then `himi test`.
101
+
102
+ ## How to trim by hand
39
103
 
40
104
  1. **Inventory against `SPEC.md`.** List the screen ids you will keep (home + the
41
105
  verticals in the approved plan + account/profile if the app signs in). Everything
@@ -48,14 +112,14 @@ has no worker when it declares `logicBundle`.
48
112
  serve). Leave the file's import of `config` and the default export intact.
49
113
  4. **Remove navigation.** In `config.ts`, drop those ids from `linkableScreens`. If you
50
114
  drop a tab root, also remove its `tabBar.items` entry (keep at least one tab).
51
- 5. **Prove it.** `himi validate --strict` then `himi render <kept-home-id>`. A leftover
52
- `linkableScreens` id with no `SCREENS` key, or a `SCREENS` key whose worker dir is
53
- gone, is the usual miss.
115
+ 5. **Prove it.** `himi validate --strict`, `himi render <kept-home-id>`, then `himi test`. A
116
+ `SCREENS` key whose worker dir is gone fails validate; a leftover `linkableScreens` or tab id
117
+ with no `SCREENS` key does not — `himi test` is what reports it (`nav-target-missing`).
54
118
 
55
- Worked example — keep Home + Shop + Account from branded-lite:
119
+ Worked example — keep Home + Shop + Account from branded-lite (what the command above does):
56
120
 
57
- - Keep `tier5-src/himi-branded-lite-home/`, `himi-branded-lite-shop/` (and the store
58
- workers it calls), `himi-store-account/` / `himi-branded-lite-account/`.
121
+ - Keep `tier5-src/himi-branded-lite-home/`, `himi-store-shop/` (and the store workers it
122
+ calls, such as `himi-store-product/` for the product page), and `himi-store-account/`.
59
123
  - Delete bookings/events/blog/forum/CMS/spaces worker dirs you are not shipping.
60
124
  - `SCREENS` keeps `himi_branded_home`, `himi_shop`, `himi_product`, `himi_cart`,
61
125
  `himi_account`, … and drops `himi_services`, `himi_events`, …
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1007.0",
3
+ "version": "0.1008.0",
4
4
  "type": "module",
5
5
  "description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
6
6
  "keywords": [
@@ -65,5 +65,5 @@
65
65
  "artifactId": "himalaya-cli"
66
66
  }
67
67
  },
68
- "falconPackageHash": "65e6a5e768e3d17f2b360d6fc1601cc92b0fff459a87b02b588c643a"
68
+ "falconPackageHash": "6e55785cc22d09405bcfbeb88665d72ea523bdea1bd2bcc60ea1a435"
69
69
  }