@wix/himalaya-cli 0.837.0 → 0.839.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.
@@ -84,8 +84,9 @@ An adopted `wixId` declaration is **optional for reads**. A worker may call
84
84
  read even when `config.ts` has no `cms` block; declaring it records the expected
85
85
  schema for humans and `himi validate`, but does not grant or enable that read.
86
86
 
87
- `himi cms query` labels every collection on the site `owned`, `adopted`, or
88
- `foreign`, so the blast radius is visible before you run anything.
87
+ `himi cms query --all` labels every collection on the site `owned`, `adopted`, or
88
+ `foreign`, so the blast radius is visible before you run anything. (Without `--all`
89
+ it reads only the ids you declare — see [below](#himi-cms-query--read-only).)
89
90
 
90
91
  ### `site analyze --apply` adopts, it never claims
91
92
 
@@ -275,7 +276,8 @@ boots as — an unauthenticated visitor — rather than as one it has no way to
275
276
  export WIX_SITE_ID=<msid> # or pass --site <msid> to every command
276
277
 
277
278
  himi validate # offline: prefix, field types, displayField, seed keys, permissions
278
- himi cms query # READ-ONLY: what exists, who owns it, where it drifts
279
+ himi cms query --all # READ-ONLY: what the SITE has, including collections you never declared
280
+ himi cms query # READ-ONLY: just your declared ids — what exists, who owns it, where it drifts
279
281
  himi cms create # provision the owned collections (idempotent)
280
282
  himi cms seed # fill the EMPTY owned collections from `seed:`
281
283
  himi push --draft # ship the content package; does NOT touch the site
@@ -287,13 +289,67 @@ publishing a release is exactly the surprise this design avoids.
287
289
 
288
290
  ### `himi cms query` — read-only
289
291
 
290
- Every collection on the site, labeled `owned` / `adopted` / `foreign`, with item
291
- counts for the declared ones and a `drift` list: declared-but-missing collections,
292
- missing fields, undeclared extra fields, and type mismatches. Run it first, and run
293
- it after `create` to confirm.
292
+ **By default it reads only the ids you declared.** One targeted `GET` per declared
293
+ collection, and the report says so with `siteScanned: false`. You get item counts and
294
+ a `drift` list: declared-but-missing collections, missing fields, undeclared extra
295
+ fields, and type mismatches. Run it first, and run it after `create` to confirm.
294
296
 
295
- Item counts are fetched only for *declared* collections — a site inventory doesn't
296
- fan out a query per foreign collection.
297
+ The default never lists the site, so it cannot show you a collection you did not
298
+ declare — **including one this app owns**. A leftover `himi_<app>_*` from a renamed
299
+ declaration is labeled `owned` when the scan finds it, but only `--all` looks.
300
+
301
+ The default stays off the site-wide list on purpose: that list is ~1MB and 46–60s on
302
+ a real site (194 collections on one test site) and its socket gets reset mid-transfer,
303
+ while the per-id reads it actually needs are ~3KB each.
304
+
305
+ #### `--all` — scan the site and discover what to adopt
306
+
307
+ `himi cms query --all --site <msid>` additionally lists the whole site and describes
308
+ every **foreign** collection — one this app neither owns nor declares:
309
+
310
+ ```json
311
+ {
312
+ "siteScanned": true,
313
+ "foreign": {
314
+ "count": 31,
315
+ "collections": [
316
+ { "id": "QaRecipes", "displayName": "Recipes", "readRole": "ANYONE", "itemCount": null,
317
+ "fields": [ { "key": "title", "type": "TEXT" }, { "key": "cookMinutes", "type": "NUMBER" } ] }
318
+ ],
319
+ "truncated": 6
320
+ }
321
+ }
322
+ ```
323
+
324
+ That is enough to write the adopted declaration without a second call: `wixId` is the
325
+ `id`, and the `fields` carry the keys **and** the types a declaration must mirror (Wix
326
+ cannot retype a field in place, so a wrong type is a refusal, not a warning). A field
327
+ with no `type` is one the site did not report a type for — read that collection directly
328
+ before declaring it, rather than guessing; the scan will not invent one for you.
329
+
330
+ - **It works with no `cms` block at all.** Discovering what to declare is precisely the
331
+ case where nothing is declared yet, so `--all` is the one flag for which a missing
332
+ `cms` block is *not* "nothing to do".
333
+ - **Foreign collections are never item-counted** (`itemCount: null`). A row count is one
334
+ query each, and fanning that across a whole site is the cost this scan must not pay.
335
+ Declare or adopt the collection and the count arrives with the next `himi cms query`.
336
+ - **Only the first 25 are described.** `foreign.count` is how many the scan listed and
337
+ `foreign.truncated` says how many of those went undescribed, so a short list is never
338
+ mistaken for a short site. For the full per-collection picture — field types,
339
+ read/write roles and sample rows — use
340
+ [`himi site analyze --site <msid>`](wix-business-context.md).
341
+ - **`foreign.count` is not a site census.** `GET /data/v2/collections` is paged and this
342
+ scan reads one page. When Wix reports a total larger than that page,
343
+ `unlistedCollections` says how many the listing left out; when Wix reports no total,
344
+ neither field can tell you, so treat `foreign.count` as "foreign collections in what we
345
+ listed" and use `site analyze` if you need certainty about a very large site.
346
+
347
+ **The scan is owner-scoped, and there is no tokenless alternative.** It needs
348
+ `--site <msid>` (or `WIX_SITE_ID`) and owner auth via `wix token`, because enumerating
349
+ collections is `GET /data/v2/collections`, which requires the *Manage Data
350
+ Collections* scope. A visitor/anonymous token can read the **items** of an
351
+ `ANYONE`-read collection whose id you already have, but it can never list collections —
352
+ so no CLI work can make the tokenless path discover them.
297
353
 
298
354
  ### `himi cms create` — additive and idempotent
299
355
 
@@ -109,6 +109,7 @@ Only **unambiguous** defects, so a green run stays worth trusting:
109
109
  | `unresolved-wix-media` | error | A media-typed prop holding a raw Wix media handle/id the renderer cannot load. |
110
110
  | `binding-unresolved` | error / warning | A `$service:` binding aimed at state the worker never defines. It is an error when the missing value can leave visible UI blank. A direct prop with sibling `collapseWhenEmpty: true` is an advisory warning instead: the renderer deliberately removes that zero-size optional chrome, while the warning keeps the omitted contract auditable. |
111
111
  | `nav-param-dropped` | error | A bound `himi.open` param that resolves to nothing, so the target opens without it and error-cards. |
112
+ | `nav-target-missing` | **warning** | A `himi.open` whose target is neither a baked screen, nor one of the app's declared `linkableScreens`, nor an instance of one (`course_detail_c1` under the base `course_detail`) — the tap opens nothing. Only judged when the caller supplies the app's exact linkable set; an absent set means no opinion, never a guess. A target still carrying an **unresolved** `$` token is dropped before it becomes an edge and is never judged — but one that RESOLVED to a concrete id is judged, which is the point: `$item.detailScreenId` resolving to `course_detail_c1` against the first row is exactly the case the instance rule exists for. |
112
113
  | `poll-action-missing` | error | A `_poll` directive every host will silently ignore — an action the bundle never declares, a malformed `action`, a missing `id`, or a non-positive `intervalMs`. Each ends the same way: a screen that never refreshes, with nothing saying why. Nothing in the descriptor names the polled action, so no static check can see it. (A merely too-small interval is legal — the host clamps it.) |
113
114
  | `no-request-issued` | **warning** | A worker that uses the Wix transport but never fetches — "the screen loaded with sample data." A warning: a conditional or tap-triggered fetch is legitimate. |
114
115
  | `native-decode-failed` | error | Under `--native`, the real Swift/Kotlin decoder rejected the baked descriptor bytes (one bad enum blanks the whole screen on device). |
@@ -120,8 +121,25 @@ Only **unambiguous** defects, so a green run stays worth trusting:
120
121
  | `typed-value-ignored` | **warning** | The crawl typed the value a control really carries — the payload key every renderer injects for that control — and the dispatch changed **nothing**: no state, no navigation, no request. The value is read off the app itself (an id from the control's own options, or a word from the worker's seeded state) and is always one the control is *not* already showing, so a reducer that ignores it cannot work on device. A warning because the input is the crawl's: a reducer that legitimately no-ops on a value is possible, and `himi-test.json` `skip[]` takes the invariant. |
121
122
 
122
123
  **Deliberately never reported:** an empty collection · an `error` state (often the correct
123
- answer to empty input) · a `null` optional · whether a nav target *exists* (approximating
124
- the router's real screen set flagged working deep links as dead on 15 of 37 corpus apps).
124
+ answer to empty input) · a `null` optional.
125
+
126
+ **Nav-target existence was on that list and came off it — read why before trusting it.**
127
+ Judging a target against an *approximation* of the router's screen set flagged working deep
128
+ links as dead on 15 of 37 apps, which retired the check. The exact set is the app-config's
129
+ `linkableScreens`, and a reader bug meant it arrived empty for a long time — so that verdict
130
+ was really measured against the **baked screen ids alone**, which is the approximation, not
131
+ against the exact set it was supposed to use.
132
+
133
+ Re-measured with the exact set, the check needed one more rule before it was silent: a linkable
134
+ entry declares a **base** (`course_detail`, with `paramKeys`) while a row navigates to a
135
+ worker-computed **instance** (`course_detail_c1`), and plain set membership reported two working
136
+ deep links as dead. With base-covers-its-instances it is silent everywhere it was measured —
137
+ **19 of 19 apps, no false positives.**
138
+
139
+ It ships at `warning`, with one real catch behind it: an app that declared four of its five
140
+ templated detail routes in `linkableScreens` and omitted the fifth, so a deep link to that
141
+ screen could not resolve while the in-app tap still worked. That is what distinguishes it from
142
+ a check that merely never fires.
125
143
 
126
144
  > **A false failure is worse than no tool.** It teaches an author to stop reading the
127
145
  > output, and then the real findings go unread too. When in doubt, the crawl stays quiet.
@@ -115,13 +115,20 @@ Only **unambiguous** defects, so a green run stays worth trusting:
115
115
  | every `$service:` binding names state the worker actually defines | a binding aimed at nothing (service, or its first path segment — a deeper miss on an empty list is legitimately data-dependent and is **not** reported) |
116
116
  | no nav param silently dropped | a bound `himi.open` param that resolves to nothing is **dropped** ([actionParams.ts](../core/web-renderer/src/actionParams.ts)), so the target opens without it and error-cards |
117
117
  | a worker that uses the Wix transport actually issued a request | "the fetch never left and the screen loaded with sample data" — a **warning**, since a conditional or tap-triggered fetch is legitimate |
118
+ | a nav target actually resolves | a `himi.open` at a screen that is neither baked, nor declared in `linkableScreens`, nor an instance of a declared base — a **warning**, and only when the app's exact linkable set is available |
118
119
 
119
120
  Deliberately **not** reported: an empty collection, an `error` state (often the correct answer
120
- to empty input), a `null` optional field, and whether a nav target screen exists (the router's
121
- real set is the union of baked screens, config-declared templated bases, and nav overrides —
122
- approximating it flagged working deep links as dead on 15 of 37 corpus apps). When in doubt the
123
- crawl stays quiet: one false failure teaches an author to stop reading the output, and then the
124
- real findings go unread too.
121
+ to empty input), and a `null` optional field. When in doubt the crawl stays quiet: one false
122
+ failure teaches an author to stop reading the output, and then the real findings go unread too.
123
+
124
+ Nav-target existence was on that list until recently. The router's real set is the union of baked
125
+ screens, config-declared templated bases **and their instances**, and nav overrides —
126
+ approximating it flagged working deep links as dead on 15 of 37 apps. That verdict was measured
127
+ against baked ids alone, because a reader bug left the exact set (`linkableScreens`) empty. With
128
+ the exact set, plus the rule that a declared base covers its instances, it measured silent on
129
+ all 19 apps it was run against — **no false positives, and one real catch**: a templated detail
130
+ route an app never declared linkable, so deep links to it could not resolve. See
131
+ [himi-test.md](himi-test.md) for the full history.
125
132
 
126
133
  ### It runs the worker the way the DEVICE does
127
134
 
@@ -184,7 +184,9 @@ images stay as `static.wixstatic.com` URLs in descriptors — do not vendor
184
184
 
185
185
  ### 4. CMS, verticals, forms, pages
186
186
 
187
- - **CMS the site already has** — `himi cms query`, then **adopt** with `wixId` in
187
+ - **CMS the site already has** — `himi cms query --all --site <msid>` (owner-scoped;
188
+ it is the only door that reveals a collection id you do not already know), then
189
+ **adopt** with `wixId` in
188
190
  `config.ts` (`himi docs cms-collections`). Read-only. Never seed or alter a
189
191
  collection you did not create. Create `himi_<appSlug>_*` only for storage the
190
192
  site does not have.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.837.0",
3
+ "version": "0.839.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": [
@@ -63,5 +63,5 @@
63
63
  "artifactId": "himalaya-cli"
64
64
  }
65
65
  },
66
- "falconPackageHash": "358928473c090a4ddfc84e0818462623d39870fc81acde3e9b21a28f"
66
+ "falconPackageHash": "5de4fef57d6c6e87d57791a1f1af4e7bd241ef8902a4fbb3292442a0"
67
67
  }