@colixsystems/widget-sdk 0.276.0 → 0.277.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.
@@ -1,8 +1,16 @@
1
- // CommonJS twin of lucideIconName.js for the backend (the page service +
2
- // any other Node consumer require this). Keep the two in sync — same
3
- // algorithm, same behaviour. See lucideIconName.js for the rationale.
1
+ // GENERATED from lucideIconName.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change lucideIconName.js, then run `npm run generate:cjs` in packages/widget-sdk.
4
3
  "use strict";
5
4
 
5
+ // Normalize a human-typed Lucide icon name to the PascalCase form Lucide
6
+ // exports its components under. The lucide.dev gallery shows kebab-case
7
+ // (`arrow-right`) and its copy button hands you kebab-case, but
8
+ // `lucide-react` / `lucide-react-native` key their components in PascalCase
9
+ // (`ArrowRight`). This bridges the two so any of kebab / snake / spaced /
10
+ // camel / PascalCase resolves: `arrow-right`, `arrow_right`, `arrow right`,
11
+ // `arrowRight`, and `ArrowRight` all become `ArrowRight`; `building-2` becomes
12
+ // `Building2`. Non-strings and blanks return "" so callers fall back to a
13
+ // placeholder. Already-PascalCase names pass through unchanged.
6
14
  function normalizeLucideIconName(name) {
7
15
  if (typeof name !== "string") return "";
8
16
  const trimmed = name.trim();
@@ -13,5 +21,6 @@ function normalizeLucideIconName(name) {
13
21
  .map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
14
22
  .join("");
15
23
  }
16
-
17
- module.exports = { normalizeLucideIconName };
24
+ module.exports = {
25
+ normalizeLucideIconName,
26
+ };
package/dist/manifest.cjs CHANGED
@@ -1,11 +1,12 @@
1
- // CommonJS mirror of manifest.js. Lets backend services (CJS) call
2
- // `validateManifest(...)` without a dynamic-import detour. The two files
3
- // share their constants by mutual import via createRequire — manifest.js
4
- // re-exports the same functions defined here so there is exactly one
5
- // implementation.
1
+ // GENERATED from manifest.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change manifest.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
6
4
 
7
5
  const { CONTRACT } = require("./contract.cjs");
8
6
 
7
+ // Structural validation of a widget manifest, shared by the CLI, hosts and backend.
8
+
9
+
9
10
  const PAYLOAD_VALUE_TYPES = CONTRACT.payloadValueTypes;
10
11
 
11
12
  // sc-4505 — a payload / input field map: { <field>: { type, label? } }. This is
@@ -120,16 +121,7 @@ function validateManifestTranslations(translations, manifestId, errors) {
120
121
  }
121
122
  }
122
123
 
123
- // REQ-MKT-ACTION (sc-4879): a widget no longer declares server-side actions.
124
- //
125
- // `manifest.actions` was how an automation shipped before Actions existed as
126
- // their own marketplace deliverable — a widget was two products in one package,
127
- // a component that renders and a script that never renders at all. It is now
128
- // REFUSED rather than ignored: an author who declares it believes the
129
- // automation will ship, and silence would publish that misunderstanding.
130
- //
131
- // The replacement is a marketplace Action (`@colixsystems/action-sdk`), which
132
- // the workspace installs and configures on its own.
124
+ // REQ-MKT-ACTION (sc-4879): refused, not ignored — the author expects it to ship.
133
125
  function validateManifestActions(_actions, errors) {
134
126
  errors.push(
135
127
  "manifest.actions is no longer supported — ship the automation as a " +
package/dist/manifest.js CHANGED
@@ -1,10 +1,6 @@
1
- // CommonJS mirror of manifest.js. Lets backend services (CJS) call
2
- // `validateManifest(...)` without a dynamic-import detour. The two files
3
- // share their constants by mutual import via createRequire — manifest.js
4
- // re-exports the same functions defined here so there is exactly one
5
- // implementation.
1
+ // Structural validation of a widget manifest, shared by the CLI, hosts and backend.
6
2
 
7
- import { CONTRACT, normaliseActionTriggerTypes } from "./contract.js";
3
+ import { CONTRACT } from "./contract.js";
8
4
 
9
5
  const PAYLOAD_VALUE_TYPES = CONTRACT.payloadValueTypes;
10
6
 
@@ -39,20 +35,6 @@ const VALID_CATEGORIES = new Set([
39
35
  ]);
40
36
  const VALID_PLATFORMS = new Set(["web", "native"]);
41
37
 
42
- // REQ-WIDGET-ACTION — structural validation for manifest-declared server
43
- // actions. Mirrors the backend action.service caps; the runner re-validates
44
- // the cron expression (node-cron) and binds the tenant-local API key + table
45
- // at enable time, so we only check shape + size here (cross-env: no Buffer).
46
- const VALID_ACTION_TRIGGERS = new Set([
47
- "schedule",
48
- "record_created",
49
- "record_updated",
50
- "record_deleted",
51
- ]);
52
- const ACTION_SCRIPT_MAX_BYTES = 200 * 1024;
53
- const ACTION_TIMEOUT_MIN_MS = 100;
54
- const ACTION_TIMEOUT_MAX_MS = 5 * 60 * 1000;
55
-
56
38
  // REQ-L10N-WIDGET — caps + patterns for manifest-declared translations.
57
39
  // The relative key pattern is deliberately tighter than the dictionary's
58
40
  // own KEY_RE: once the host namespaces it (`widget.<id>.<key>`) the result
@@ -134,54 +116,13 @@ function validateManifestTranslations(translations, manifestId, errors) {
134
116
  }
135
117
  }
136
118
 
137
- function validateManifestActions(actions, errors) {
138
- if (!Array.isArray(actions)) {
139
- errors.push("manifest.actions must be an array (omit it or use [] for none)");
140
- return;
141
- }
142
- const seenKeys = new Set();
143
- for (const a of actions) {
144
- if (a === null || typeof a !== "object") {
145
- errors.push("manifest.actions entries must be objects");
146
- break;
147
- }
148
- if (!isNonEmptyString(a.key)) {
149
- errors.push("manifest.actions[].key must be a non-empty string");
150
- } else if (seenKeys.has(a.key)) {
151
- errors.push(`manifest.actions[].key "${a.key}" is duplicated`);
152
- } else {
153
- seenKeys.add(a.key);
154
- }
155
- pushIf(errors, isNonEmptyString(a.name), "manifest.actions[].name must be a non-empty string");
156
- const triggerTypes = normaliseActionTriggerTypes(a);
157
- if (triggerTypes === null) {
158
- errors.push(
159
- `manifest.actions[].triggerTypes must be a non-empty array of unique values from ${[...VALID_ACTION_TRIGGERS].join(", ")}`,
160
- );
161
- } else if (triggerTypes.includes("schedule")) {
162
- pushIf(
163
- errors,
164
- isNonEmptyString(a.scheduleCron),
165
- "manifest.actions[].scheduleCron is required when triggerTypes contains 'schedule'",
166
- );
167
- }
168
- if (!isNonEmptyString(a.scriptSource)) {
169
- errors.push("manifest.actions[].scriptSource must be a non-empty string");
170
- } else if (utf8ByteLength(a.scriptSource) > ACTION_SCRIPT_MAX_BYTES) {
171
- errors.push("manifest.actions[].scriptSource exceeds 200 KiB");
172
- }
173
- if (a.timeoutMs !== undefined) {
174
- const t = Number(a.timeoutMs);
175
- if (!Number.isFinite(t) || t < ACTION_TIMEOUT_MIN_MS || t > ACTION_TIMEOUT_MAX_MS) {
176
- errors.push("manifest.actions[].timeoutMs must be between 100 and 300000");
177
- }
178
- }
179
- if (a.triggerTableId !== undefined || a.apiKeyId !== undefined) {
180
- errors.push(
181
- "manifest.actions[] must not include triggerTableId or apiKeyId — those are tenant-local and bound after install",
182
- );
183
- }
184
- }
119
+ // REQ-MKT-ACTION (sc-4879): refused, not ignored — the author expects it to ship.
120
+ function validateManifestActions(_actions, errors) {
121
+ errors.push(
122
+ "manifest.actions is no longer supported — ship the automation as a " +
123
+ "marketplace Action (@colixsystems/action-sdk) instead of declaring it " +
124
+ "on a widget",
125
+ );
185
126
  }
186
127
 
187
128
  function canonicalCategory(c) {
@@ -361,7 +302,7 @@ function validateManifest(m) {
361
302
  }
362
303
  }
363
304
 
364
- // `actions` is optional (additive in SDK 1.8.0) — only validate when present.
305
+ // Present at all is now an error (sc-4879) — see validateManifestActions.
365
306
  if (manifest.actions !== undefined) {
366
307
  validateManifestActions(manifest.actions, errors);
367
308
  }
@@ -1,11 +1,8 @@
1
- // CommonJS mirror of navigation.js — the CJS compiler and the Mason build runner
2
- // resolve a `theme_config.navigation` block with the SAME rules the web host
3
- // applies, so an app's menu type cannot mean one thing on web and another in the
4
- // exported Expo app.
5
- //
6
- // The BODY below is copied VERBATIM from navigation.js; only the module syntax
7
- // differs. navigation-parity.test.js pins both facts — identical bodies AND
8
- // identical behaviour over a shared case table — so drift fails CI.
1
+ // GENERATED from navigation.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change navigation.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
4
+
5
+ const { CONTRACT, isHexColor, contrastRatio, mixHex, readableTextColor } = require("./contract.cjs");
9
6
 
10
7
  // REQ-NAV-STRUCTURE — the host side of an app's navigation SHAPE and the
11
8
  // tokens its footer strip is painted with.
@@ -25,7 +22,6 @@
25
22
  // the SAME literal, so what a planner may persist and what a host draws cannot
26
23
  // diverge.
27
24
 
28
- const { CONTRACT, isHexColor, contrastRatio, mixHex, readableTextColor } = require("./contract.cjs");
29
25
 
30
26
  // Absent or unknown resolves here, so every app authored before menu types
31
27
  // existed renders and compiles byte-identically.
@@ -895,5 +891,29 @@ function borderWidthOr(...values) {
895
891
  }
896
892
  return BORDER_WIDTH_MIN;
897
893
  }
898
-
899
- module.exports = { normaliseNavigation, menuItemCap, resolveFooterTokens, FOOTER_SIZES, clampFooterSize, FOOTER_HOME_LINE_CLEARANCE_PX, resolveSidebarTokens, resolveTopStripeLayout, resolveTopBarTokens, topStripeShowKey, TOP_STRIPE_ALWAYS_SHOWN_SLOTS, TOP_STRIPE_SLOTS, MIN_TOP_STRIPE_HEIGHT_PX, MAX_TOP_STRIPE_HEIGHT_PX, MIN_TOP_STRIPE_PADDING_X_PX, MAX_TOP_STRIPE_PADDING_X_PX, MAX_TOP_STRIPE_OFFSET_Y_PX, DEFAULT_TOP_STRIPE_HEIGHT_PX, DEFAULT_TOP_STRIPE_PADDING_X_PX, resolveSidebarUnfold, resolveLocalNavModel, drawsLocalNavAnywhere, isDarkSurface, resolveAppLogo };
894
+ module.exports = {
895
+ normaliseNavigation,
896
+ menuItemCap,
897
+ resolveFooterTokens,
898
+ FOOTER_SIZES,
899
+ clampFooterSize,
900
+ FOOTER_HOME_LINE_CLEARANCE_PX,
901
+ resolveSidebarTokens,
902
+ TOP_STRIPE_SLOTS,
903
+ TOP_STRIPE_ALWAYS_SHOWN_SLOTS,
904
+ MIN_TOP_STRIPE_HEIGHT_PX,
905
+ MAX_TOP_STRIPE_HEIGHT_PX,
906
+ MIN_TOP_STRIPE_PADDING_X_PX,
907
+ MAX_TOP_STRIPE_PADDING_X_PX,
908
+ MAX_TOP_STRIPE_OFFSET_Y_PX,
909
+ DEFAULT_TOP_STRIPE_HEIGHT_PX,
910
+ DEFAULT_TOP_STRIPE_PADDING_X_PX,
911
+ topStripeShowKey,
912
+ resolveTopStripeLayout,
913
+ isDarkSurface,
914
+ resolveAppLogo,
915
+ resolveTopBarTokens,
916
+ resolveSidebarUnfold,
917
+ resolveLocalNavModel,
918
+ drawsLocalNavAnywhere,
919
+ };
@@ -0,0 +1,169 @@
1
+ // GENERATED from source-mask.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change source-mask.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
4
+
5
+ // sc-6086: the shared source masker, extracted verbatim from linter.js so the
6
+ // linter, the packer's import scanner, and the dev-server guard all agree on
7
+ // what is code and what is a comment or string literal (CLAUDE.md §3).
8
+ //
9
+ // Length-preserving: every blanked character becomes a space and newlines are
10
+ // kept, so an index into the mask is the SAME index in the original source.
11
+ // That is what lets a caller match against the mask and splice the original.
12
+
13
+ // Replace the *content* of comments and string / template literals with
14
+ // spaces so the banned-identifier scan only ever sees executable code. A
15
+ // banned host-escape identifier (`window`, `document`, `eval`, `process`, …)
16
+ // is only dangerous as a real identifier reference — never as prose in a
17
+ // `//` comment or as character data inside a string — so matching the bare
18
+ // word there is a false positive that blocks an otherwise-clean widget (a
19
+ // comment that reads "the hour window the grid renders" must not trip
20
+ // `no-window`).
21
+ //
22
+ // Newlines are preserved verbatim so reported line numbers still line up
23
+ // with the original source. Template-literal `${ … }` expression holes are
24
+ // left intact: real code lives there and must still be scanned (`${window}`
25
+ // is a genuine escape). Backslash escapes inside strings/templates are
26
+ // consumed so an escaped quote (`"\""`) doesn't end the literal early.
27
+ function stripNonCode(
28
+ source,
29
+ { keepStrings = false, keepTemplates = keepStrings } = {},
30
+ ) {
31
+ let out = "";
32
+ const n = source.length;
33
+ let mode = "code"; // code | line | block | sq | dq | tmpl
34
+ // Brace depth, plus a stack of the depths at which an enclosing template
35
+ // literal resumes — lets a `${ … }` hole (which may itself contain `{}`,
36
+ // strings, or nested templates) be told apart from the literal text.
37
+ let braceDepth = 0;
38
+ const tmplStack = [];
39
+ const keep = (ch) => {
40
+ out += ch;
41
+ };
42
+ const blank = (ch) => {
43
+ out += ch === "\n" || ch === "\r" ? ch : " ";
44
+ };
45
+ // String / template CONTENT: blanked for the banned-identifier scan
46
+ // (prose must not trip `no-window`), kept for the host-API-URL scan,
47
+ // whose whole job is to find a URL literal.
48
+ const str = keepStrings ? keep : blank;
49
+ // An import specifier is always a quoted string, never a template literal —
50
+ // so the import scanner keeps quoted content and blanks templates, which is
51
+ // what stops an `import … from "./x"` line inside a backtick block from
52
+ // reading as a real statement.
53
+ const tmplStr = keepTemplates ? keep : blank;
54
+ let i = 0;
55
+ while (i < n) {
56
+ const ch = source[i];
57
+ const nx = source[i + 1];
58
+ if (mode === "code") {
59
+ if (ch === "/" && nx === "/") {
60
+ mode = "line";
61
+ blank(ch);
62
+ blank(nx);
63
+ i += 2;
64
+ } else if (ch === "/" && nx === "*") {
65
+ mode = "block";
66
+ blank(ch);
67
+ blank(nx);
68
+ i += 2;
69
+ } else if (ch === "'") {
70
+ mode = "sq";
71
+ str(ch);
72
+ i += 1;
73
+ } else if (ch === '"') {
74
+ mode = "dq";
75
+ str(ch);
76
+ i += 1;
77
+ } else if (ch === "`") {
78
+ mode = "tmpl";
79
+ tmplStr(ch);
80
+ i += 1;
81
+ } else if (ch === "{") {
82
+ braceDepth += 1;
83
+ keep(ch);
84
+ i += 1;
85
+ } else if (ch === "}") {
86
+ braceDepth -= 1;
87
+ if (
88
+ tmplStack.length > 0 &&
89
+ tmplStack[tmplStack.length - 1] === braceDepth
90
+ ) {
91
+ tmplStack.pop();
92
+ mode = "tmpl";
93
+ str(ch);
94
+ } else {
95
+ keep(ch);
96
+ }
97
+ i += 1;
98
+ } else {
99
+ keep(ch);
100
+ i += 1;
101
+ }
102
+ } else if (mode === "line") {
103
+ if (ch === "\n") {
104
+ mode = "code";
105
+ keep(ch);
106
+ } else {
107
+ blank(ch);
108
+ }
109
+ i += 1;
110
+ } else if (mode === "block") {
111
+ if (ch === "*" && nx === "/") {
112
+ mode = "code";
113
+ blank(ch);
114
+ blank(nx);
115
+ i += 2;
116
+ } else {
117
+ blank(ch);
118
+ i += 1;
119
+ }
120
+ } else if (mode === "sq" || mode === "dq") {
121
+ const quote = mode === "sq" ? "'" : '"';
122
+ if (ch === "\\") {
123
+ str(ch);
124
+ if (i + 1 < n) str(nx);
125
+ i += 2;
126
+ } else if (ch === quote) {
127
+ mode = "code";
128
+ str(ch);
129
+ i += 1;
130
+ } else if (ch === "\n") {
131
+ // A bare newline terminates an unterminated string in JS; bail back
132
+ // to code so malformed input can't blank the rest of the file.
133
+ mode = "code";
134
+ keep(ch);
135
+ i += 1;
136
+ } else {
137
+ str(ch);
138
+ i += 1;
139
+ }
140
+ } else {
141
+ // mode === "tmpl"
142
+ if (ch === "\\") {
143
+ tmplStr(ch);
144
+ if (i + 1 < n) tmplStr(nx);
145
+ i += 2;
146
+ } else if (ch === "`") {
147
+ mode = "code";
148
+ tmplStr(ch);
149
+ i += 1;
150
+ } else if (ch === "$" && nx === "{") {
151
+ // Enter an expression hole. Remember the brace depth the template
152
+ // resumes at, then count the `{` so its matching `}` is recognised.
153
+ tmplStack.push(braceDepth);
154
+ braceDepth += 1;
155
+ mode = "code";
156
+ keep(ch);
157
+ keep(nx);
158
+ i += 2;
159
+ } else {
160
+ tmplStr(ch);
161
+ i += 1;
162
+ }
163
+ }
164
+ }
165
+ return out;
166
+ }
167
+ module.exports = {
168
+ stripNonCode,
169
+ };
@@ -1,9 +1,12 @@
1
- // CommonJS mirror of theme-appearance.js, for the backend's theme coercion and
2
- // the compiler. The BODY is copied VERBATIM; theme-appearance-parity.test.js
3
- // pins identical bodies and identical behaviour.
1
+ // GENERATED from theme-appearance.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change theme-appearance.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
4
4
 
5
5
  const { isHexColor, APPEARANCE_PREFERENCES } = require("./contract.cjs");
6
6
 
7
+ // APPEARANCE_PREFERENCES: what an app opens on and a user may choose.
8
+
9
+
7
10
  // REQ-THEME-APPEARANCE (sc-12335) — the ONE implementation of an app's light and
8
11
  // dark palettes, and of which one is showing. Host surface, not author API.
9
12
 
@@ -181,10 +184,9 @@ function themeInBothModes(theme, mode, twin) {
181
184
  if (mode !== "dark") return withDarkPalette(base, twinPalette);
182
185
  return withDarkPalette(overlayPalette(base, twinPalette), recolourablePalette(base));
183
186
  }
184
-
185
187
  module.exports = {
186
- APPEARANCE_MODES,
187
188
  APPEARANCE_PREFERENCES,
189
+ APPEARANCE_MODES,
188
190
  themePaletteOf,
189
191
  normaliseAppearance,
190
192
  resolveAppearancePreference,
@@ -1,6 +1,6 @@
1
+ // APPEARANCE_PREFERENCES: what an app opens on and a user may choose.
1
2
  import { isHexColor, APPEARANCE_PREFERENCES } from "./contract.js";
2
3
 
3
- // What an app opens on and a user may choose; one list, in the contract.
4
4
  export { APPEARANCE_PREFERENCES };
5
5
 
6
6
  // REQ-THEME-APPEARANCE (sc-12335) — the ONE implementation of an app's light and
@@ -1,10 +1,6 @@
1
- // CommonJS mirror of theme-background.js — the compiler (Expo export) and the
2
- // Mason build runner are CJS and must resolve an app background and a login
3
- // design against the SAME rules the web hosts apply, or the two renders diverge.
4
- //
5
- // The BODY below is copied VERBATIM from theme-background.js; only the module
6
- // syntax differs. theme-background-parity.test.js pins both facts — identical
7
- // bodies AND identical behaviour over a shared case table — so drift fails CI.
1
+ // GENERATED from theme-background.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change theme-background.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
8
4
 
9
5
  // REQ-THEME-08 / REQ-PLR-05-CUSTOM — the ONE implementation of the app's
10
6
  // background gradient and of the sign-in screen's design, shared by both hosts.
@@ -169,7 +165,6 @@ function resolveLoginTextVisibility(login) {
169
165
  subheading: own.hideSubheading !== true,
170
166
  };
171
167
  }
172
-
173
168
  module.exports = {
174
169
  LOGIN_TEXT_MAX_LENGTH,
175
170
  normaliseThemeGradient,
@@ -1,10 +1,8 @@
1
- // CommonJS mirror of theme-components.js — the Mason build runner (CJS)
2
- // validates a `set_theme` components blob against the SAME vocabulary the hosts
3
- // apply, so what a planner may persist and what a widget renders cannot diverge.
4
- //
5
- // The BODY below is copied VERBATIM from theme-components.js; only the module
6
- // syntax differs. theme-components-parity.test.js pins both facts — identical
7
- // bodies AND identical behaviour over a shared case table — so drift fails CI.
1
+ // GENERATED from theme-components.js by scripts/generate-cjs.js — DO NOT EDIT.
2
+ // Change theme-components.js, then run `npm run generate:cjs` in packages/widget-sdk.
3
+ "use strict";
4
+
5
+ const { CONTRACT, normaliseComponentGradient } = require("./contract.cjs");
8
6
 
9
7
  // REQ-THEME-15 (sc-1497) — the host side of per-component style tokens.
10
8
  //
@@ -23,7 +21,6 @@
23
21
  // widget reads. The Mason build runner validates `set_theme` against the SAME
24
22
  // literal, so what a planner may emit and what a host applies cannot diverge.
25
23
 
26
- const { CONTRACT, normaliseComponentGradient } = require("./contract.cjs");
27
24
 
28
25
  // 3-, 6- and 8-digit hex, matching what the build runner persists — the host
29
26
  // must never drop a colour the runner already accepted.
@@ -402,5 +399,11 @@ function applyThemeComponentStyle(manifestId, theme, props, styleSchema) {
402
399
  const authored = isPlainObject(base.style) ? base.style : null;
403
400
  return { ...base, style: { ...themed, ...authored } };
404
401
  }
405
-
406
- module.exports = { normaliseThemeComponents, normaliseWidgetStyleFields, normaliseWidgetStyles, applyThemeComponentStyle, styleValueBytes, MAX_STYLE_STRING_LENGTH };
402
+ module.exports = {
403
+ normaliseThemeComponents,
404
+ MAX_STYLE_STRING_LENGTH,
405
+ styleValueBytes,
406
+ normaliseWidgetStyleFields,
407
+ normaliseWidgetStyles,
408
+ applyThemeComponentStyle,
409
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.276.0",
3
+ "version": "0.277.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "homepage": "https://github.com/Colix-AB/AppStudio",
6
6
  "type": "module",
@@ -61,7 +61,7 @@
61
61
  ],
62
62
  "scripts": {
63
63
  "build": "node scripts/build.js",
64
- "generate:contract": "node scripts/contract-cjs.js",
64
+ "generate:cjs": "node scripts/generate-cjs.js",
65
65
  "test": "node --test \"src/__tests__/*.test.js\""
66
66
  },
67
67
  "engines": {
package/src/contract.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // The widget SDK contract: the ONE source the linter, the AI agents, the
2
2
  // compiler and both hosts read. `contract.cjs` is GENERATED from `contract.js`
3
- // (`npm run generate:contract`) for CommonJS consumers — never edit it by hand;
4
- // contract-cjs-generated.test.js fails when it is stale.
3
+ // (`npm run generate:cjs`) for CommonJS consumers — never edit it by hand;
4
+ // cjs-generated.test.js fails when it is stale.
5
5
 
6
6
  // REQ-AI-AGENT-DESIGN (sc-3696): the ONE cross-platform elevation vocabulary.
7
7
  // `shadow*` applies on iOS + react-native-web, `elevation` drives Android.