nodality 1.2.10 → 1.2.11

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.
Files changed (202) hide show
  1. package/bin/mcp-server.mjs +86 -0
  2. package/bin/schema-cli.mjs +55 -11
  3. package/dist/animator.cjs.js.LICENSE.txt +1 -1
  4. package/dist/animator.esm.js.LICENSE.txt +1 -1
  5. package/dist/audionew.cjs.js.LICENSE.txt +1 -1
  6. package/dist/audionew.esm.js.LICENSE.txt +1 -1
  7. package/dist/base.cjs.js.LICENSE.txt +1 -1
  8. package/dist/base.esm.js.LICENSE.txt +1 -1
  9. package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
  10. package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
  11. package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
  12. package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
  13. package/dist/bundle.umd.js +1 -1
  14. package/dist/bundle.umd.js.LICENSE.txt +1 -28
  15. package/dist/button.cjs.js.LICENSE.txt +1 -1
  16. package/dist/button.esm.js.LICENSE.txt +1 -1
  17. package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
  18. package/dist/card-getter.esm.js.LICENSE.txt +1 -1
  19. package/dist/center.cjs.js.LICENSE.txt +1 -1
  20. package/dist/center.esm.js.LICENSE.txt +1 -1
  21. package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
  22. package/dist/checkbox.esm.js.LICENSE.txt +1 -1
  23. package/dist/code.cjs.js.LICENSE.txt +1 -1
  24. package/dist/code.esm.js.LICENSE.txt +1 -1
  25. package/dist/container.cjs.js.LICENSE.txt +1 -1
  26. package/dist/container.esm.js.LICENSE.txt +1 -1
  27. package/dist/data-list.cjs.js.LICENSE.txt +1 -1
  28. package/dist/data-list.esm.js.LICENSE.txt +1 -1
  29. package/dist/designer.cjs.js +1 -1
  30. package/dist/designer.cjs.js.LICENSE.txt +1 -28
  31. package/dist/designer.esm.js +1 -1
  32. package/dist/designer.esm.js.LICENSE.txt +1 -28
  33. package/dist/element-mapper.cjs.js.LICENSE.txt +1 -1
  34. package/dist/element-mapper.esm.js.LICENSE.txt +1 -1
  35. package/dist/finalresult.esm.js +1 -1
  36. package/dist/finalresult.esm.js.LICENSE.txt +1 -28
  37. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  38. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  39. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  40. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  41. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  42. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  43. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  44. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  45. package/dist/free.cjs.js.LICENSE.txt +1 -1
  46. package/dist/free.esm.js.LICENSE.txt +1 -1
  47. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  48. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  49. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  50. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  51. package/dist/image.cjs.js.LICENSE.txt +1 -1
  52. package/dist/image.esm.js.LICENSE.txt +1 -1
  53. package/dist/index.cjs.js +1 -1
  54. package/dist/index.cjs.js.LICENSE.txt +1 -28
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.esm.js +1 -1
  57. package/dist/index.esm.js.LICENSE.txt +1 -28
  58. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  59. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  60. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  61. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  62. package/dist/link.cjs.js.LICENSE.txt +1 -1
  63. package/dist/link.esm.js.LICENSE.txt +1 -1
  64. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  65. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  66. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  67. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  68. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  69. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  70. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  71. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  72. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  73. package/dist/picker.esm.js.LICENSE.txt +1 -1
  74. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  75. package/dist/progress.esm.js.LICENSE.txt +1 -1
  76. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  77. package/dist/radio.esm.js.LICENSE.txt +1 -1
  78. package/dist/range.cjs.js.LICENSE.txt +1 -1
  79. package/dist/range.esm.js.LICENSE.txt +1 -1
  80. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  81. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  82. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  83. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  84. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  85. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  86. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  87. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  88. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  89. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  90. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  91. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  92. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  93. package/dist/stack.esm.js.LICENSE.txt +1 -1
  94. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  95. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  96. package/dist/table.cjs.js.LICENSE.txt +1 -1
  97. package/dist/table.esm.js.LICENSE.txt +1 -1
  98. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  99. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  100. package/dist/text.cjs.js.LICENSE.txt +1 -1
  101. package/dist/text.esm.js.LICENSE.txt +1 -1
  102. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  103. package/dist/theme.esm.js.LICENSE.txt +1 -1
  104. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  105. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  106. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  107. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  108. package/dist/video.cjs.js.LICENSE.txt +1 -1
  109. package/dist/video.esm.js.LICENSE.txt +1 -1
  110. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  111. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  112. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  113. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  114. package/layout/animator.js +1 -1
  115. package/layout/audio.js +1 -1
  116. package/layout/audionew.js +1 -1
  117. package/layout/base.js +1 -1
  118. package/layout/beta-desktop-bar.js +1 -1
  119. package/layout/beta-mobile-bar.js +1 -1
  120. package/layout/button.js +1 -1
  121. package/layout/center.js +1 -1
  122. package/layout/checkbox.js +1 -1
  123. package/layout/circle.js +1 -1
  124. package/layout/code.js +1 -1
  125. package/layout/container.js +1 -1
  126. package/layout/dropdown-2025.js +1 -1
  127. package/layout/flex-card.js +1 -1
  128. package/layout/flex-grid.js +1 -1
  129. package/layout/flex-row.js +1 -1
  130. package/layout/form-components/custom.js +1 -1
  131. package/layout/form-components/data-list.js +1 -1
  132. package/layout/form-components/floating-input.js +1 -1
  133. package/layout/form-components/form-all.js +1 -1
  134. package/layout/form-components/form.js +1 -1
  135. package/layout/form-components/image-picker.js +1 -1
  136. package/layout/form-components/picker.js +1 -1
  137. package/layout/form-components/radio.js +1 -1
  138. package/layout/form-components/radiogroup.js +1 -1
  139. package/layout/form-components/range.js +1 -1
  140. package/layout/free.js +1 -1
  141. package/layout/grid-switcher.js +1 -1
  142. package/layout/grid.js +1 -1
  143. package/layout/horizontal-scroller.js +1 -1
  144. package/layout/image.js +1 -1
  145. package/layout/index.js +1 -1
  146. package/layout/link.js +1 -1
  147. package/layout/list.js +1 -1
  148. package/layout/meta-adder.js +1 -1
  149. package/layout/modal-2025.js +1 -1
  150. package/layout/morph.js +1 -1
  151. package/layout/multiswitcher.js +1 -1
  152. package/layout/nav-bar.js +1 -1
  153. package/layout/nav-factor/custom-div.js +1 -1
  154. package/layout/new-nav-bar.js +1 -1
  155. package/layout/polygon.js +1 -1
  156. package/layout/prerender-site.js +1 -1
  157. package/layout/prerender.js +1 -1
  158. package/layout/progress.js +1 -1
  159. package/layout/row.js +1 -1
  160. package/layout/scroll-video.js +1 -1
  161. package/layout/side-bar.js +1 -1
  162. package/layout/side-nav-bar.js +1 -1
  163. package/layout/simple-bar.js +1 -1
  164. package/layout/slider-2025.js +1 -1
  165. package/layout/spacer.js +1 -1
  166. package/layout/stack.js +1 -1
  167. package/layout/svg.js +1 -1
  168. package/layout/switcher.js +1 -1
  169. package/layout/table.js +1 -1
  170. package/layout/text-field.js +1 -1
  171. package/layout/text.js +1 -1
  172. package/layout/ulist.js +1 -1
  173. package/layout/video.js +1 -1
  174. package/layout/wrap.js +1 -1
  175. package/layout/zoom-card.js +1 -1
  176. package/lib/agent-surface.js +1 -1
  177. package/lib/card-getter.js +1 -1
  178. package/lib/codegen.js +1 -1
  179. package/lib/data.js +1 -1
  180. package/lib/designer.js +1 -1
  181. package/lib/element-mapper.js +1 -1
  182. package/lib/element-params.generated.js +1 -1
  183. package/lib/keyframe-animation.js +1 -1
  184. package/lib/link-getter.js +1 -1
  185. package/lib/morph-node.js +1 -1
  186. package/lib/parse-html.js +14 -2
  187. package/lib/raster-inspect.js +1 -1
  188. package/lib/raster-ops.js +1 -1
  189. package/lib/raster-presets.js +1 -1
  190. package/lib/scroll-video.js +1 -1
  191. package/lib/seo.js +1 -1
  192. package/lib/stacker.js +1 -1
  193. package/lib/suggest.js +1 -1
  194. package/lib/theme.js +1 -1
  195. package/lib/transform-anim.js +1 -1
  196. package/lib/transition.js +1 -1
  197. package/lib/validate-nodes.js +40 -1
  198. package/lib/webmcp-adapter.js +1 -1
  199. package/package.json +4 -2
  200. package/schema.json +7953 -0
  201. package/scripts/generate-schema.mjs +251 -0
  202. package/skills/nodality/SKILL.md +71 -1
@@ -135,6 +135,54 @@ const TOOLS = [
135
135
  required: ["nodes"],
136
136
  },
137
137
  },
138
+ {
139
+ name: "get_schema",
140
+ description:
141
+ "One element type's parameters, on demand. This is the other half of " +
142
+ "list_ops: that returns the vocabulary of N, this returns the " +
143
+ "vocabulary of E. Call it for the type you are about to write rather " +
144
+ "than carrying every type's parameters in context \u2014 that is the " +
145
+ "difference between paying for a schema once and paying for it in " +
146
+ "every request. Each entry names the mapper, the components it builds " +
147
+ "and every parameter recovered from the source those components " +
148
+ "actually read, so it cannot describe a parameter the library does " +
149
+ "not have. Omit `type` for the whole schema. Composites carry content " +
150
+ "in a slot \u2014 `items` for cards, nav, sideNav, table and ulist; " +
151
+ "`children` for row, form and wrap \u2014 and declaring it in the " +
152
+ "other one renders the placeholders instead.",
153
+ inputSchema: {
154
+ type: "object",
155
+ properties: {
156
+ type: {
157
+ type: "string",
158
+ description: "An element type, e.g. \"cards\". Omit for the whole schema.",
159
+ },
160
+ },
161
+ },
162
+ },
163
+ {
164
+ name: "parse_html",
165
+ description:
166
+ "Read a rendered page back into an E array, so a page can be EDITED " +
167
+ "rather than only generated: parse it, change the one thing, render " +
168
+ "again. Two tiers, and the report says which one you got. A page " +
169
+ "rendered with `{annotate: true}` carries its own descriptors and " +
170
+ "comes back exactly \u2014 every type, every option, nothing " +
171
+ "inferred. Without that, only what the tag settles is recovered: " +
172
+ "headings, paragraphs, links, images and lists. Thirteen composite " +
173
+ "types render as a bare <div> with nothing to tell them apart, so " +
174
+ "those are reported unrecovered rather than guessed \u2014 a wrong " +
175
+ "guess would silently become a different page. The recovered spec is " +
176
+ "validated before it is returned, because a descriptor read out of a " +
177
+ "document is untrusted input.",
178
+ inputSchema: {
179
+ type: "object",
180
+ properties: {
181
+ html: { type: "string", description: "The rendered HTML to read back." },
182
+ },
183
+ required: ["html"],
184
+ },
185
+ },
138
186
  {
139
187
  name: "preview",
140
188
  description:
@@ -180,6 +228,44 @@ const IMPL = {
180
228
  validate_nodes: async ({ nodes, elements }) =>
181
229
  ok(validateNodes(nodes, elements)),
182
230
 
231
+ // Served from the shipped schema.json rather than regenerated: the
232
+ // generator is a build-time script and this server answers in-process. The
233
+ // drift test keeps the committed copy honest, so reading it is not a second
234
+ // source of truth, it is the same one at rest.
235
+ get_schema: async ({ type } = {}) => {
236
+ const [{ readFile }, { fileURLToPath }, { dirname, join }] = await Promise.all([
237
+ import("node:fs/promises"), import("node:url"), import("node:path"),
238
+ ]);
239
+ const here = dirname(fileURLToPath(import.meta.url));
240
+ const schema = JSON.parse(await readFile(join(here, "..", "schema.json"), "utf8"));
241
+ const types = schema.types || {};
242
+ if (!type) return ok(schema);
243
+ if (!types[type]) {
244
+ // Same report shape as everything else, so an agent parses one thing.
245
+ return ok({
246
+ ok: false,
247
+ errors: [{
248
+ code: "UNKNOWN_ELEMENT_TYPE", path: "type", got: type,
249
+ suggestions: Object.keys(types)
250
+ .filter((t) => t.slice(0, 2) === String(type).slice(0, 2)).slice(0, 3),
251
+ valid: Object.keys(types),
252
+ }],
253
+ });
254
+ }
255
+ return ok({ type, ...types[type] });
256
+ },
257
+
258
+ parse_html: async ({ html }) => {
259
+ // Same arrangement as `preview`: a DOM is a build-time concern, so jsdom
260
+ // is not bundled and its absence arrives as MISSING_PEER_DEPENDENCY from
261
+ // the handler below rather than as a stack trace.
262
+ const [{ JSDOM }, { parseReport }] = await Promise.all([
263
+ import("jsdom"), import("../lib/parse-html.js"),
264
+ ]);
265
+ const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>");
266
+ return ok(parseReport(String(html ?? ""), dom.window.document));
267
+ },
268
+
183
269
  preview: async ({ elements, nodes, output }) => {
184
270
  const N = nodes || [];
185
271
  const report = validateNodes(N, elements);
@@ -5,24 +5,68 @@
5
5
  // that can fetch one type's parameters pays for that type once, instead of
6
6
  // carrying every type's vocabulary in every request.
7
7
  //
8
- // The schema is regenerated from source on each call rather than read from
9
- // the committed schema.json, so what an agent is told can never be staler
10
- // than the library it is talking to. `--check` compares the two and is what
11
- // CI runs.
8
+ // TWO SOURCES, in order, because the first one is not always there.
9
+ //
10
+ // In a checkout the generator runs and the schema is rebuilt from source, so
11
+ // what an agent is told cannot be staler than the library it is talking to.
12
+ // In an INSTALLED package it is read from the shipped schema.json instead.
13
+ //
14
+ // That second path is not belt-and-braces, it is a bug fix. `schema.json` and
15
+ // `scripts/` were both outside package.json's `files`, so neither reached the
16
+ // tarball, and `npx nodality schema` failed with MODULE_NOT_FOUND for every
17
+ // consumer while working perfectly in the dev tree — property 2 shipped as
18
+ // nothing at all. Both are packaged now, and `packaging/smoke.mjs` runs this
19
+ // subcommand against the packed tarball so the surface cannot regress
20
+ // invisibly again.
12
21
  import { spawn } from "node:child_process";
13
22
  import { fileURLToPath } from "node:url";
23
+ import { existsSync, readFileSync } from "node:fs";
14
24
  import path from "node:path";
15
25
 
16
26
  export async function runSchema(args) {
17
27
  const here = path.dirname(fileURLToPath(import.meta.url));
18
28
  const gen = path.join(here, "..", "scripts", "generate-schema.mjs");
29
+ const committed = path.join(here, "..", "schema.json");
19
30
  const type = args.find((a) => !a.startsWith("--"));
20
- const passthrough = args.includes("--check")
21
- ? ["--check"]
22
- : type ? ["--type", type] : ["--stdout"];
23
31
 
24
- await new Promise((resolve) => {
25
- const p = spawn(process.execPath, [gen, ...passthrough], { stdio: "inherit" });
26
- p.on("exit", (code) => { process.exitCode = code ?? 0; resolve(); });
27
- });
32
+ if (existsSync(gen)) {
33
+ const passthrough = args.includes("--check")
34
+ ? ["--check"]
35
+ : type ? ["--type", type] : ["--stdout"];
36
+ await new Promise((resolve) => {
37
+ const p = spawn(process.execPath, [gen, ...passthrough], { stdio: "inherit" });
38
+ p.on("exit", (code) => { process.exitCode = code ?? 0; resolve(); });
39
+ });
40
+ return;
41
+ }
42
+
43
+ if (!existsSync(committed)) {
44
+ console.error("[nodality] no schema available: neither scripts/generate-schema.mjs");
45
+ console.error(" nor schema.json is present in this installation.");
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+
50
+ // `--check` asks whether the committed copy matches what the source would
51
+ // produce. Without the generator that question cannot be answered, and
52
+ // answering "yes" from the file being checked would be circular.
53
+ if (args.includes("--check")) {
54
+ console.error("[nodality] --check needs scripts/generate-schema.mjs, which is not");
55
+ console.error(" present in an installed package. Run it from a checkout.");
56
+ process.exitCode = 1;
57
+ return;
58
+ }
59
+
60
+ const schema = JSON.parse(readFileSync(committed, "utf8"));
61
+ if (type) {
62
+ const entry = schema.types?.[type];
63
+ if (!entry) {
64
+ console.error(`unknown type "${type}"`);
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ console.log(JSON.stringify({ type, ...entry }, null, 2));
69
+ return;
70
+ }
71
+ process.stdout.write(JSON.stringify(schema, null, 2) + "\n");
28
72
  }
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.9
2
+ * nodality v1.2.10
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */