@unoverse-platform/studio 0.1.71 → 0.1.73

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unoverse-platform/studio",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "type": "module",
5
5
  "description": "Unoverse Studio: the local authoring app. Reads your own rx/ folder, no backend.",
6
6
  "scripts": {
@@ -111,6 +111,49 @@ export interface UnoverseNode {
111
111
  * exclusive, instead of a `visibleWhen` repeated on every branch. Each branch is a
112
112
  * normal subtree (commonly a `{ "$include": "step-x" }`, expanded at load). */
113
113
  cases?: Record<string, UnoverseNode>;
114
+
115
+ // ── Declared 2026-08-23 ────────────────────────────────────────────────────────
116
+ // These were all in live use across shipped definitions, and the renderer handled
117
+ // them, but this interface never declared them. Definitions arrive as YAML and are
118
+ // parsed as unknown, so they never met `UnoverseNode` and nothing objected — the
119
+ // interface quietly fell behind what ships. Found by the per-primitive contract work
120
+ // (UNOVERSE_CONFORMANCE §2a); the guard is `packages/base/tests/primitive-contract-drift.test.ts`,
121
+ // which now fails if this list and `vocabulary.mjs` disagree again.
122
+
123
+ /** Ref: the atom to compose. Authoring-time only — the server expands every `Ref`
124
+ * before serving, so a rendered tree never contains one. */
125
+ ref?: string;
126
+ /** Ref: literals written INTO the atom. A bind whose field is a `with` key becomes a
127
+ * hardcoded attribute, and a truthy key satisfies a matching `visibleWhen` guard. */
128
+ with?: Record<string, unknown>;
129
+ /** Each: the LEGACY spelling of `template`, still read. New definitions write `template`. */
130
+ app?: UnoverseNode;
131
+ /** Button: a literal label, when the content is not composed from `children` and not
132
+ * bound via `bind.label`. */
133
+ label?: string;
134
+ /** STATE-OWNED SIZING: this panel's own width, and therefore its contribution to the
135
+ * app's total. A named size from the org's `styles/semantic/app-sizes`, a raw CSS
136
+ * width, or `flex` to take the remaining host space. One declaration per panel. */
137
+ appWidth?: string;
138
+ /** Box: text-selection behaviour for the subtree. */
139
+ selection?: string;
140
+ /** Markdown: render links in the surrounding text colour rather than the link colour,
141
+ * for a block that is already inside a coloured surface. */
142
+ inheritLinkColor?: boolean;
143
+ /** Input: cap the number of characters accepted. */
144
+ maxLength?: number;
145
+ /** Input: render a multi-line field rather than a single line. */
146
+ multiline?: boolean;
147
+ /** Input: visible rows when `multiline` is set. */
148
+ rows?: number;
149
+ /** Input: the on-screen keyboard hint handed to the platform (`numeric`, `tel`, …).
150
+ * Distinct from `inputType`, which says what the field IS. */
151
+ inputMode?: string;
152
+ /** Input: the autofill hint handed to the platform (`one-time-code`, `email`, …). */
153
+ autoComplete?: string;
154
+ /** Input: move to the next field as soon as this one is full — the OTP behaviour,
155
+ * which is only meaningful alongside `maxLength`. */
156
+ advanceOnFill?: boolean;
114
157
  }
115
158
 
116
159
  export interface UnoverseDefinition {
@@ -43,8 +43,8 @@ states:
43
43
  - **Top-level order IS the priority ladder**, base first. The app can be in ONE
44
44
  state at a time: it walks the list top-down and enters the first of its states that
45
45
  ANY hosted component currently matches. The ladder is DERIVED from the tree; never
46
- author `stateOrder` (that field survives only as the legacy form for apps
47
- without a tree).
46
+ author `stateOrder`. It is now a LINT ERROR beside a tree (`file.mjs`), after two
47
+ client components ran on one for months because nothing enforced the rule.
48
48
  - **Nesting IS containment, enforced by compilation.** A declared base substate
49
49
  (`welcome`) is stripped from every non-base arrangement; no hand-written guard ever
50
50
  polices it. The substate's file keeps its own condition (`visibleWhen: isEmpty`).
@@ -76,8 +76,9 @@ design/<project>/apps/<name>/
76
76
  products.yaml # state "products" → core + cards rail
77
77
  detail.yaml # state "detail" → core + full record page
78
78
  components/ # app-local partials (core, header, composer-bar, turns…)
79
- states/ # base substates' drawings (welcome): included plainly by the
80
- # chrome, own condition inside, containment compiled from the tree
79
+ # NO states/ folder: every drawing lives in layouts/. A substate's
80
+ # drawing is axis-prefixed (step-register, callState-idle) and named
81
+ # by its `layout:` key, so layouts/ reads at a glance.
81
82
  ```
82
83
 
83
84
  Each layout = a complete arrangement: `$include: components/core` + that state's