@wix/himalaya-cli 0.1130.0 → 0.1131.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -24749,6 +24749,7 @@ function shouldRevealError(args) {
24749
24749
  var EMAIL_RE, URL_HOST_RE, INTEGER_RE, NUMBER_RE;
24750
24750
  var init_validation = __esm({
24751
24751
  "../../core/ts/src/validation.ts"() {
24752
+ "use strict";
24752
24753
  EMAIL_RE = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;
24753
24754
  URL_HOST_RE = /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(:[0-9]+)?$/;
24754
24755
  INTEGER_RE = /^[+-]?[0-9]+$/;
@@ -29149,6 +29150,7 @@ function validateWorkerSubtree(raw, slotId, policy, actionCatalog) {
29149
29150
  var WORKER_SUBTREE_CEILINGS, ID_PART, ACTION_ID;
29150
29151
  var init_worker_subtree = __esm({
29151
29152
  "../../core/ts/src/worker-subtree.ts"() {
29153
+ "use strict";
29152
29154
  init_worker_subtree_safe_types_generated();
29153
29155
  WORKER_SUBTREE_CEILINGS = Object.freeze({
29154
29156
  maxEncodedBytes: 65536,
@@ -43143,7 +43145,7 @@ async function crawlScreenInner(opts) {
43143
43145
  severity: "error",
43144
43146
  ...source ? { source } : {},
43145
43147
  message: `${e.service}: ${e.message}`,
43146
- hint: isTransportReject(e.message) ? `the worker let the transport rejection escape instead of handling it \u2014 catch it and set an error state, or crawl with a net fixture (--net)` : /Cannot read properties of|is not a function|undefined is not/.test(e.message) ? `a TypeError on a property read is usually a WRONG REFERENCE, not a failed fetch \u2014 check the receiver first (classic: \`svc.actions.<x>(\u2026)\` \u2014 actions are DIRECT methods on the handle, \`.actions\` is undefined on device; or indexing into a possibly-empty list). Wrapping a wrong reference in try/catch silences the crash but leaves the control dead.` : `an uncaught throw here leaves the screen on whatever state it had \u2014 wrap the failing call and set an error state`
43148
+ hint: isTransportReject(e.message) ? `the worker let the transport rejection escape instead of handling it \u2014 catch it and set an error state, or crawl with a net fixture (--net)` : e.argless && /Cannot destructure/.test(e.message) ? `the crawl dispatched this action with NO payload \u2014 it only types a value it can read off the app (docs/himi-test.md \u2192 Typed form journeys), so a field hook it cannot aim arrives with no argument. A device always sends the control's payload key, but a reducer should still tolerate a bare call: default the payload parameter (\`(s, { value } = {}) => \u2026\`), or add a himi-test.json journey that types a real value.` : /Cannot read properties of|is not a function|undefined is not/.test(e.message) ? `a TypeError on a property read is usually a WRONG REFERENCE, not a failed fetch \u2014 check the receiver first (classic: \`svc.actions.<x>(\u2026)\` \u2014 actions are DIRECT methods on the handle, \`.actions\` is undefined on device; or indexing into a possibly-empty list). Wrapping a wrong reference in try/catch silences the crash but leaves the control dead.` : `an uncaught throw here leaves the screen on whatever state it had \u2014 wrap the failing call and set an error state`
43147
43149
  });
43148
43150
  }
43149
43151
  for (const [svc, s] of Object.entries(state)) {
@@ -43357,7 +43359,7 @@ async function crawlScreenInner(opts) {
43357
43359
  try {
43358
43360
  await handle.dispatch(parsed.action, ...workerArgs(dispatched));
43359
43361
  } catch (e) {
43360
- errors.push({ service: parsed.service, message: `${parsed.action}: ${errText(e)}`, ...e.stack ? { stack: e.stack } : {} });
43362
+ errors.push({ service: parsed.service, message: `${parsed.action}: ${errText(e)}`, ...e.stack ? { stack: e.stack } : {}, argless: workerArgs(dispatched).length === 0 });
43361
43363
  }
43362
43364
  exercised += 1;
43363
43365
  const { state, defects } = snapshot(w);
@@ -73095,6 +73097,35 @@ Transport: same targets/tokens as himi-serve \u2014 --target <local|prod|bo>, --
73095
73097
  --telemetry-url, --control-token/--telemetry-token, or HIMI_* env.
73096
73098
  Guides: ${DEVELOPER_PORTAL_URL}`;
73097
73099
  var ONLY_USAGE = "himi push --only <selector>[,<selector>\u2026] (--draft|--live) [--from-release <id>] [--accept-regressions] [--accept-partial]";
73100
+ var LOGIN_HELP = `himi login \u2014 get a scoped serve-control token and store it in
73101
+ ~/.himalaya/serve-targets.json, so push / promote / preview need no pasted token.
73102
+
73103
+ himi login [--browser | --wix | --dpx] [--target <t>] [--no-open]
73104
+
73105
+ MODES \u2014 pick by who is at the keyboard
73106
+ --browser YOUR OWN Wix account, in a browser. No VPN, no BO. The DEFAULT when the target
73107
+ has no BO issuer, which is the \`wix\` target \u2014 and \`wix\` is the default target
73108
+ off-repo, so a bare \`himi login\` there is this mode. --no-open prints the URL
73109
+ instead of opening it (a headless shell).
73110
+ --wix HEADLESS. Uses the machine's EXISTING Wix CLI credential (\`wix login\`, or
73111
+ \`wix login --api-key\` in a pod) \u2014 the mode a CI job or an agent container can
73112
+ satisfy. It does not create a credential; log the Wix CLI in first.
73113
+ --dpx Wix EMPLOYEE. Reads the BO session at ~/.dpx/session/token (dpx 2.x:
73114
+ \`dpx auth login\` then \`dpx auth token > ~/.dpx/session/token\`). Internal
73115
+ targets only (--target bo); VPN-gated.
73116
+
73117
+ TARGET
73118
+ --target <t> which serve plane the token is for. Resolved like every other command:
73119
+ --target, then HIMI_SERVE_TARGET, then serve-targets.json \`default\`, then
73120
+ \`wix\` off-repo. Log in to the SAME target you push to \u2014 a token is stored
73121
+ per target, and a push to another one will not find it.
73122
+
73123
+ CHECK IT
73124
+ himi doctor which login modes would work on this machine, before you try one
73125
+ himi whoami what the stored token is scoped to
73126
+
73127
+ OTHER
73128
+ --issue-url <url>, --owner-issue-url <url> override the issuer (advanced / tests)`;
73098
73129
  var PATCH_HELP = `himi patch \u2014 change ONE item of a published app, from a raw file, on a machine
73099
73130
  that does not have the content package.
73100
73131
 
@@ -74985,7 +75016,7 @@ async function runCommand(argv, io, deps) {
74985
75016
  io.log(flags.json ? JSON.stringify({ himi: v }, null, 2) : `himi v${v}`);
74986
75017
  return 0;
74987
75018
  }
74988
- const VERB_HELP = /* @__PURE__ */ new Set(["patch"]);
75019
+ const VERB_HELP = /* @__PURE__ */ new Set(["patch", "login"]);
74989
75020
  if (!command || command === "help" || flags.help === true && !VERB_HELP.has(command)) {
74990
75021
  const footer = `
74991
75022
 
@@ -79681,6 +79712,10 @@ ${label2}`);
79681
79712
  return allOk ? 0 : 1;
79682
79713
  }
79683
79714
  case "login": {
79715
+ if (flags.help === true) {
79716
+ io.log(LOGIN_HELP);
79717
+ return 0;
79718
+ }
79684
79719
  const target = targetName();
79685
79720
  const prevControlToken = loadTargetsFile().targets?.[target]?.controlToken;
79686
79721
  let issue2;
@@ -10,7 +10,7 @@
10
10
  // examples/counter-t5.descriptor.json (its logicBundle.integrity is the SRI of the
11
11
  // built bundle). Authoritative bundle-authoring doc: docs/tier-5-add-a-screen.md.
12
12
 
13
- import { defineService } from "@himalaya/state";
13
+ import { defineService } from "@wix/himalaya/state";
14
14
 
15
15
  interface CounterState {
16
16
  value: number;
@@ -183,8 +183,10 @@ cells inside a `Card([VStack(spacing: 0)])`.
183
183
  > horizontal rail) where its own virtualized scroll is what you want.
184
184
 
185
185
  **Text** — `Text` for a single styled string (`maxLines` to truncate); `RichText` for inline mixed
186
- marks (bold/italic/link within one paragraph); `Label` for an icon+text pair; `Marquee` only for
187
- genuinely scrolling text. *Reach for `RichText`, not concatenated `Text`, when marks vary mid-line.*
186
+ marks (bold/italic/link within one paragraph); `RichContent` for a Wix Ricos document with blocks,
187
+ media, lists, or tables; `Label` for an icon+text pair; `Marquee` only for genuinely scrolling text.
188
+ *Reach for `RichText`, not concatenated `Text`, when marks vary mid-line; use `RichContent` for
189
+ long-form Ricos content rather than flattening it into text rows.*
188
190
 
189
191
  **Inputs & forms** — field controls: `TextField` (with `keyboard`/`autoCapitalization`/`secure`),
190
192
  `SearchField`, `Toggle`, `Stepper`, `Slider`, `SelectionControl` (checkbox/radio),
@@ -279,7 +281,7 @@ Concrete patterns lifted from real usage:
279
281
  - **Cell list** — `card([ vstack({ spacing: 0, alignment: "leading", children: [ …ListItem cells… ] }) ])`. `spacing: 0` because the cells own their own dividers/padding.
280
282
  - **Overlay** — `zstack({ alignment: "center", children: [ backdropImage(cornerRadius 12), withModifiers(label, { padding, background: { token: "accentPrimary" }, cornerRadius: 10 }) ] })`.
281
283
  - **Responsive** — `grid({ columns: 1, columnsMedium: 2, spacing: 12 })` for 1-up on phone / 2-up on tablet; `splitView({ primary, detail, primaryMaxWidth: 280 })` for master/detail that stacks on a phone; set `contentMaxWidth` in tokens so wide surfaces keep a readable column instead of running edge-to-edge.
282
- - **Centered separator, not a flanked divider** — the classic "—— or ——" needs each `divider()` to take equal remaining width, and the HStack row-share only kicks in for controls with an intrinsic fill (a bare `divider()` inside an HStack collapses to a tick). Use a **centered caption** instead: `hstack({ children: [spacer(), text("or continue with", "caption", { color: "textSecondary" }), spacer()] })`, optionally over a single full-width `divider()`.
284
+ - **Centered separator, not a flanked divider** — the classic "—— or ——" needs each `divider()` to take equal remaining width, and the HStack row-share only kicks in for controls with an intrinsic fill. **Never put a bare `divider()` inside an HStack**: it is a horizontal rule on every surface, and on web and Android it claims the row's full width and squeezes its siblings (a stat row's `12` wraps to `1`/`2`); only iOS draws a thin vertical line. For a stats row, separate the columns with `spacer()`s or spacing instead. Use a **centered caption** instead: `hstack({ children: [spacer(), text("or continue with", "caption", { color: "textSecondary" }), spacer()] })`, optionally over a single full-width `divider()`.
283
285
 
284
286
  > **Intrinsic-fill controls grab the row.** `Button` and `TextField` have an intrinsic FILL, so the next four idioms are about NOT letting that surprise you (they were the papercuts every off-repo app hit):
285
287
 
@@ -10,8 +10,8 @@
10
10
  // Because this worker rides the Wix transport (globalThis.himalaya.wixApi), the
11
11
  // descriptor's logicBundle.declaredCapabilities MUST include "wix_api" (RFC 0043 D4).
12
12
 
13
- import { defineService } from "@himalaya/state";
14
- import { productPrice, queryStoreProducts, type StoreProduct } from "@himalaya/wix-stores";
13
+ import { defineService } from "@wix/himalaya/state";
14
+ import { productPrice, queryStoreProducts, type StoreProduct } from "@wix/himalaya/wix-stores";
15
15
 
16
16
  // FLAT strings only — the row template binds `$item.name`, never `$item.priceData.…`.
17
17
  // All shaping happens here in normalize(), not at the binding site.
@@ -11,8 +11,8 @@
11
11
  // The write rides the Wix transport → the descriptor's logicBundle MUST declare
12
12
  // "wix_api" (RFC 0043 D4).
13
13
 
14
- import { defineService } from "@himalaya/state";
15
- import { createDraftPost, type WixDraftPostWrite, type WixRichContent } from "@himalaya/wix-blog";
14
+ import { defineService } from "@wix/himalaya/state";
15
+ import { createDraftPost, type WixDraftPostWrite, type WixRichContent } from "@wix/himalaya/wix-blog";
16
16
 
17
17
  interface PostFormState {
18
18
  // Prefill values — what the fields SHOW (edit mode / echo after save). The
@@ -73,6 +73,14 @@ the payload contract names. A `Slider`, `Stepper`, `Toggle` or `DatePicker` has
73
73
  those still dispatch with the descriptor's default (often empty) value, and the gap ledger says so
74
74
  per screen.
75
75
 
76
+ **An argless dispatch carries no payload at all.** When the descriptor's own `params`/`args` are
77
+ empty and the crawl has nothing to type, it calls the reducer with **no argument** — the same
78
+ calling convention the host uses for an empty payload. A device always sends the control's payload
79
+ key (`value` for a field's `onChange`), but a reducer written `(s, { value }) => …` throws
80
+ `Cannot destructure property 'value' of 'undefined'` under the crawl. That `worker-threw` is a real
81
+ catch, not a crawl bug, and its hint says so: default the parameter (`(s, { value } = {}) => …`,
82
+ or read `p?.value`), or add a journey below that types a real value.
83
+
76
84
  For a flow where the real proof is **typed value → submit → visible completion** — several fields,
77
85
  in order, ending in a rendered result — add a short screen-local journey to `himi-test.json`:
78
86
 
@@ -9,7 +9,7 @@
9
9
  // hosts expose globalThis.himalaya.storage, web falls back to localStorage,
10
10
  // and a missing/failing store just means the card shows again next launch.
11
11
 
12
- import { defineService } from "@himalaya/state";
12
+ import { defineService } from "@wix/himalaya/state";
13
13
 
14
14
  const ONBOARDING_KEY = "myapp.onboarded";
15
15
 
@@ -9,8 +9,8 @@
9
9
  // Builds on the dynamic-list recipe (worker owns the array, four-state display
10
10
  // strings) — see examples/dynamic-list.* for that base. Declares "wix_api".
11
11
 
12
- import { defineService } from "@himalaya/state";
13
- import { queryPosts, type WixPost } from "@himalaya/wix-blog";
12
+ import { defineService } from "@wix/himalaya/state";
13
+ import { queryPosts, type WixPost } from "@wix/himalaya/wix-blog";
14
14
 
15
15
  interface PostRow {
16
16
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/himalaya-cli",
3
- "version": "0.1130.0",
3
+ "version": "0.1131.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": [
@@ -67,5 +67,5 @@
67
67
  "artifactId": "himalaya-cli"
68
68
  }
69
69
  },
70
- "falconPackageHash": "8340fceb4deeef12cc58c6969904b2b33ae4c90a5923c20cef72d267"
70
+ "falconPackageHash": "4920f7f92ed5d3cccc334bbc8ff870b7299ebb01377a75b9829788cd"
71
71
  }