nodality 1.1.15 → 1.2.1

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 (201) hide show
  1. package/bin/mcp-server.mjs +28 -2
  2. package/bin/nodality.js +61 -0
  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 +60 -1
  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 +60 -1
  31. package/dist/designer.esm.js +1 -1
  32. package/dist/designer.esm.js.LICENSE.txt +60 -1
  33. package/dist/element-mapper.cjs.js +1 -1
  34. package/dist/element-mapper.cjs.js.LICENSE.txt +1 -1
  35. package/dist/element-mapper.esm.js +1 -1
  36. package/dist/element-mapper.esm.js.LICENSE.txt +1 -1
  37. package/dist/finalresult.esm.js +1 -1
  38. package/dist/finalresult.esm.js.LICENSE.txt +60 -1
  39. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  40. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  41. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  42. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  43. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  44. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  45. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  46. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  47. package/dist/free.cjs.js.LICENSE.txt +1 -1
  48. package/dist/free.esm.js.LICENSE.txt +1 -1
  49. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  50. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  51. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  52. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  53. package/dist/image.cjs.js.LICENSE.txt +1 -1
  54. package/dist/image.esm.js.LICENSE.txt +1 -1
  55. package/dist/index.cjs.js +1 -1
  56. package/dist/index.cjs.js.LICENSE.txt +60 -1
  57. package/dist/index.d.ts +1 -1
  58. package/dist/index.esm.js +1 -1
  59. package/dist/index.esm.js.LICENSE.txt +60 -1
  60. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  61. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  62. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  63. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  64. package/dist/link.cjs.js.LICENSE.txt +1 -1
  65. package/dist/link.esm.js.LICENSE.txt +1 -1
  66. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  67. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  68. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  69. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  70. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  71. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  72. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  73. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  74. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  75. package/dist/picker.esm.js.LICENSE.txt +1 -1
  76. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  77. package/dist/progress.esm.js.LICENSE.txt +1 -1
  78. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  79. package/dist/radio.esm.js.LICENSE.txt +1 -1
  80. package/dist/range.cjs.js.LICENSE.txt +1 -1
  81. package/dist/range.esm.js.LICENSE.txt +1 -1
  82. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  83. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  84. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  85. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  86. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  87. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  88. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  89. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  90. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  91. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  92. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  93. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  94. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  95. package/dist/stack.esm.js.LICENSE.txt +1 -1
  96. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  97. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  98. package/dist/table.cjs.js.LICENSE.txt +1 -1
  99. package/dist/table.esm.js.LICENSE.txt +1 -1
  100. package/dist/text-field.cjs.js +1 -1
  101. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  102. package/dist/text-field.esm.js +1 -1
  103. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  104. package/dist/text.cjs.js.LICENSE.txt +1 -1
  105. package/dist/text.esm.js.LICENSE.txt +1 -1
  106. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  107. package/dist/theme.esm.js.LICENSE.txt +1 -1
  108. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  109. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  110. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  111. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  112. package/dist/video.cjs.js.LICENSE.txt +1 -1
  113. package/dist/video.esm.js.LICENSE.txt +1 -1
  114. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  115. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  116. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  117. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  118. package/layout/animator.js +1 -1
  119. package/layout/audio.js +1 -1
  120. package/layout/audionew.js +1 -1
  121. package/layout/base.js +1 -1
  122. package/layout/beta-desktop-bar.js +1 -1
  123. package/layout/beta-mobile-bar.js +1 -1
  124. package/layout/button.js +1 -1
  125. package/layout/center.js +1 -1
  126. package/layout/checkbox.js +1 -1
  127. package/layout/circle.js +1 -1
  128. package/layout/code.js +1 -1
  129. package/layout/container.js +1 -1
  130. package/layout/dropdown-2025.js +1 -1
  131. package/layout/flex-card.js +1 -1
  132. package/layout/flex-grid.js +1 -1
  133. package/layout/flex-row.js +1 -1
  134. package/layout/form-components/custom.js +1 -1
  135. package/layout/form-components/data-list.js +1 -1
  136. package/layout/form-components/floating-input.js +1 -1
  137. package/layout/form-components/form-all.js +1 -1
  138. package/layout/form-components/form.js +6 -1
  139. package/layout/form-components/image-picker.js +1 -1
  140. package/layout/form-components/picker.js +1 -1
  141. package/layout/form-components/radio.js +1 -1
  142. package/layout/form-components/radiogroup.js +1 -1
  143. package/layout/form-components/range.js +1 -1
  144. package/layout/free.js +1 -1
  145. package/layout/grid-switcher.js +1 -1
  146. package/layout/grid.js +1 -1
  147. package/layout/horizontal-scroller.js +1 -1
  148. package/layout/image.js +1 -1
  149. package/layout/index.js +1 -1
  150. package/layout/link.js +1 -1
  151. package/layout/list.js +1 -1
  152. package/layout/meta-adder.js +1 -1
  153. package/layout/modal-2025.js +1 -1
  154. package/layout/morph.js +1 -1
  155. package/layout/multiswitcher.js +1 -1
  156. package/layout/nav-bar.js +1 -1
  157. package/layout/nav-factor/custom-div.js +1 -1
  158. package/layout/new-nav-bar.js +1 -1
  159. package/layout/polygon.js +1 -1
  160. package/layout/prerender-site.js +1 -1
  161. package/layout/prerender.js +1 -1
  162. package/layout/progress.js +1 -1
  163. package/layout/row.js +1 -1
  164. package/layout/scroll-video.js +1 -1
  165. package/layout/side-bar.js +1 -1
  166. package/layout/side-nav-bar.js +1 -1
  167. package/layout/simple-bar.js +1 -1
  168. package/layout/slider-2025.js +1 -1
  169. package/layout/spacer.js +1 -1
  170. package/layout/stack.js +1 -1
  171. package/layout/svg.js +1 -1
  172. package/layout/switcher.js +1 -1
  173. package/layout/table.js +1 -1
  174. package/layout/text-field.js +13 -1
  175. package/layout/text.js +1 -1
  176. package/layout/ulist.js +1 -1
  177. package/layout/video.js +1 -1
  178. package/layout/wrap.js +1 -1
  179. package/layout/zoom-card.js +1 -1
  180. package/lib/agent-surface.js +347 -0
  181. package/lib/card-getter.js +1 -1
  182. package/lib/codegen.js +1 -1
  183. package/lib/data.js +1 -1
  184. package/lib/designer.js +22 -1
  185. package/lib/element-mapper.js +2 -1
  186. package/lib/keyframe-animation.js +1 -1
  187. package/lib/link-getter.js +1 -1
  188. package/lib/morph-node.js +15 -2
  189. package/lib/raster-inspect.js +1 -1
  190. package/lib/raster-ops.js +1 -1
  191. package/lib/raster-presets.js +1 -1
  192. package/lib/scroll-video.js +1 -1
  193. package/lib/seo.js +1 -1
  194. package/lib/stacker.js +1 -1
  195. package/lib/suggest.js +1 -1
  196. package/lib/theme.js +1 -1
  197. package/lib/transform-anim.js +1 -1
  198. package/lib/transition.js +1 -1
  199. package/lib/validate-nodes.js +79 -2
  200. package/lib/webmcp-adapter.js +339 -0
  201. package/package.json +1 -1
@@ -209,13 +209,39 @@ const IMPL = {
209
209
  },
210
210
  });
211
211
 
212
- const bytes = (await readFile(out)).length;
212
+ const html = await readFile(out, "utf8");
213
+ const bytes = Buffer.byteLength(html);
214
+
215
+ // The surface this pair would give an OPERATING agent, reported to
216
+ // the GENERATING one. The two loops meet here: a model writing the
217
+ // page can see the tools a model using the page will be handed, and
218
+ // can tell before shipping that a form it meant to expose derived
219
+ // nothing. Lifted out of the rendered page rather than derived a
220
+ // second time, so what is reported is what the build emitted.
221
+ let surface;
222
+ const at = html.indexOf('id="nodality-agent-manifest"');
223
+ if (at >= 0) {
224
+ const s = html.indexOf(">", at);
225
+ const e = html.indexOf("</script>", s);
226
+ if (s >= 0 && e > s) {
227
+ try {
228
+ const m = JSON.parse(html.slice(s + 1, e));
229
+ surface = {
230
+ tools: m.tools.map((x) => ({ name: x.name, description: x.description })),
231
+ views: m.views || null,
232
+ };
233
+ } catch { /* a malformed declaration is simply not reported */ }
234
+ }
235
+ }
236
+
213
237
  return ok({
214
238
  path: out, bytes,
239
+ ...(surface ? { surface } : {}),
215
240
  // Said plainly, because an agent cannot see the result and would
216
241
  // otherwise report a shader that never ran as working.
217
242
  note: "Prerendered DOM only. Raster effects and morph transitions " +
218
- "need a GPU and run when this file is opened in a browser.",
243
+ "need a GPU and run when this file is opened in a browser." +
244
+ (surface ? " `surface` is what an agent operating this page would be offered." : ""),
219
245
  });
220
246
  },
221
247
  };
package/bin/nodality.js CHANGED
@@ -596,6 +596,67 @@ async function runPrerender(rawArgs) {
596
596
  }
597
597
 
598
598
  await prerenderSite(config);
599
+ writeAgentManifest(config);
600
+ }
601
+
602
+ /**
603
+ * Lift the agent surface out of the prerendered pages into one file.
604
+ *
605
+ * Nothing derives anything here. The declaration was written into each
606
+ * document by the SAME code that registers the tools at runtime, so by
607
+ * the time prerendering has finished it is already serialised inside the
608
+ * static HTML — this only gathers it up, so that a consumer which wants
609
+ * capability without parsing pages has one URL to fetch. That is the
610
+ * half of the agent story that needs no browser support, no origin
611
+ * trial and no standard: a crawler, an indexer, or an agent deciding
612
+ * whether the site is worth visiting reads it without executing
613
+ * anything.
614
+ *
615
+ * Byte-stability matters and is asserted in the suite: the file ships
616
+ * from a build, so it inherits the determinism the whole model rests on
617
+ * — pages are visited in sorted order and nothing here is timestamped.
618
+ */
619
+ function writeAgentManifest(config) {
620
+ const uploadDir = path.resolve(config.uploadDir || "upload");
621
+ const MANIFEST_ID = "nodality-agent-manifest";
622
+ const pages = {};
623
+
624
+ const scan = (dir, prefix = "") => {
625
+ let entries;
626
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
627
+ for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {
628
+ const abs = path.join(dir, e.name);
629
+ if (e.isDirectory()) {
630
+ if (["node_modules", "dist", "lib", "layout", "assets", "p"].includes(e.name)) continue;
631
+ scan(abs, prefix + e.name + "/");
632
+ continue;
633
+ }
634
+ if (!e.name.endsWith(".html")) continue;
635
+ const html = fs.readFileSync(abs, "utf8");
636
+ // Located by id rather than parsed: the file is emitted by us, and
637
+ // a dependency-free substring read cannot be broken by whatever a
638
+ // page happens to contain elsewhere.
639
+ const open = html.indexOf(`id="${MANIFEST_ID}"`);
640
+ if (open < 0) continue;
641
+ const start = html.indexOf(">", open);
642
+ const end = html.indexOf("</script>", start);
643
+ if (start < 0 || end < 0) continue;
644
+ try {
645
+ pages[prefix + e.name] = JSON.parse(html.slice(start + 1, end));
646
+ } catch { /* a page that did not finish rendering is simply absent */ }
647
+ }
648
+ };
649
+ scan(uploadDir);
650
+
651
+ const out = path.join(uploadDir, "agent-manifest.json");
652
+ if (!Object.keys(pages).length) {
653
+ // No page declared a surface: remove a stale file rather than leave
654
+ // one claiming capabilities the site no longer offers.
655
+ if (fs.existsSync(out)) fs.unlinkSync(out);
656
+ return;
657
+ }
658
+ fs.writeFileSync(out, JSON.stringify({ origin: config.origin || null, pages }, null, 2) + "\n");
659
+ console.log(`✅ Agent manifest — ${Object.keys(pages).length} page(s) → agent-manifest.json`);
599
660
  }
600
661
 
601
662
  // ─── compile subcommand ────────────────────────────────────────
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.1.14
2
+ * nodality v1.2.0
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */