nodality 1.2.5 → 1.2.7

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 (278) hide show
  1. package/API.md +8 -4
  2. package/README.md +15 -1
  3. package/bin/install-skill.mjs +160 -0
  4. package/bin/nodality.js +12 -0
  5. package/dist/animator.cjs.js +1 -1
  6. package/dist/animator.cjs.js.LICENSE.txt +1 -1
  7. package/dist/animator.esm.js +1 -1
  8. package/dist/animator.esm.js.LICENSE.txt +1 -1
  9. package/dist/audionew.cjs.js +1 -1
  10. package/dist/audionew.cjs.js.LICENSE.txt +1 -1
  11. package/dist/audionew.esm.js +1 -1
  12. package/dist/audionew.esm.js.LICENSE.txt +1 -1
  13. package/dist/base.cjs.js +1 -1
  14. package/dist/base.cjs.js.LICENSE.txt +1 -1
  15. package/dist/base.esm.js +1 -1
  16. package/dist/base.esm.js.LICENSE.txt +1 -1
  17. package/dist/beta-desktop-bar.cjs.js +1 -1
  18. package/dist/beta-desktop-bar.cjs.js.LICENSE.txt +1 -1
  19. package/dist/beta-desktop-bar.esm.js +1 -1
  20. package/dist/beta-desktop-bar.esm.js.LICENSE.txt +1 -1
  21. package/dist/beta-mobile-bar.cjs.js +1 -1
  22. package/dist/beta-mobile-bar.cjs.js.LICENSE.txt +1 -1
  23. package/dist/beta-mobile-bar.esm.js +1 -1
  24. package/dist/beta-mobile-bar.esm.js.LICENSE.txt +1 -1
  25. package/dist/bundle.umd.js +1 -1
  26. package/dist/bundle.umd.js.LICENSE.txt +1 -1
  27. package/dist/button.cjs.js +1 -1
  28. package/dist/button.cjs.js.LICENSE.txt +1 -1
  29. package/dist/button.esm.js +1 -1
  30. package/dist/button.esm.js.LICENSE.txt +1 -1
  31. package/dist/card-getter.cjs.js.LICENSE.txt +1 -1
  32. package/dist/card-getter.esm.js.LICENSE.txt +1 -1
  33. package/dist/center.cjs.js +1 -1
  34. package/dist/center.cjs.js.LICENSE.txt +1 -1
  35. package/dist/center.esm.js +1 -1
  36. package/dist/center.esm.js.LICENSE.txt +1 -1
  37. package/dist/checkbox.cjs.js +1 -1
  38. package/dist/checkbox.cjs.js.LICENSE.txt +1 -1
  39. package/dist/checkbox.esm.js +1 -1
  40. package/dist/checkbox.esm.js.LICENSE.txt +1 -1
  41. package/dist/code.cjs.js +1 -1
  42. package/dist/code.cjs.js.LICENSE.txt +1 -1
  43. package/dist/code.esm.js +1 -1
  44. package/dist/code.esm.js.LICENSE.txt +1 -1
  45. package/dist/container.cjs.js +1 -1
  46. package/dist/container.cjs.js.LICENSE.txt +1 -1
  47. package/dist/container.esm.js +1 -1
  48. package/dist/container.esm.js.LICENSE.txt +1 -1
  49. package/dist/data-list.cjs.js.LICENSE.txt +1 -1
  50. package/dist/data-list.esm.js.LICENSE.txt +1 -1
  51. package/dist/designer.cjs.js +1 -1
  52. package/dist/designer.cjs.js.LICENSE.txt +1 -1
  53. package/dist/designer.esm.js +1 -1
  54. package/dist/designer.esm.js.LICENSE.txt +1 -1
  55. package/dist/element-mapper.cjs.js +1 -1
  56. package/dist/element-mapper.cjs.js.LICENSE.txt +1 -1
  57. package/dist/element-mapper.esm.js +1 -1
  58. package/dist/element-mapper.esm.js.LICENSE.txt +1 -1
  59. package/dist/finalresult.esm.js +1 -1
  60. package/dist/finalresult.esm.js.LICENSE.txt +1 -1
  61. package/dist/flex-card.cjs.js +1 -1
  62. package/dist/flex-card.cjs.js.LICENSE.txt +1 -1
  63. package/dist/flex-card.esm.js +1 -1
  64. package/dist/flex-card.esm.js.LICENSE.txt +1 -1
  65. package/dist/flex-grid.cjs.js +1 -1
  66. package/dist/flex-grid.cjs.js.LICENSE.txt +1 -1
  67. package/dist/flex-grid.esm.js +1 -1
  68. package/dist/flex-grid.esm.js.LICENSE.txt +1 -1
  69. package/dist/flex-row.cjs.js +1 -1
  70. package/dist/flex-row.cjs.js.LICENSE.txt +1 -1
  71. package/dist/flex-row.esm.js +1 -1
  72. package/dist/flex-row.esm.js.LICENSE.txt +1 -1
  73. package/dist/floating-input.cjs.js +1 -1
  74. package/dist/floating-input.cjs.js.LICENSE.txt +1 -1
  75. package/dist/floating-input.esm.js +1 -1
  76. package/dist/floating-input.esm.js.LICENSE.txt +1 -1
  77. package/dist/free.cjs.js +1 -1
  78. package/dist/free.cjs.js.LICENSE.txt +1 -1
  79. package/dist/free.esm.js +1 -1
  80. package/dist/free.esm.js.LICENSE.txt +1 -1
  81. package/dist/horizontal-scroller.cjs.js.LICENSE.txt +1 -1
  82. package/dist/horizontal-scroller.esm.js.LICENSE.txt +1 -1
  83. package/dist/image-picker.cjs.js +1 -1
  84. package/dist/image-picker.cjs.js.LICENSE.txt +1 -1
  85. package/dist/image-picker.esm.js +1 -1
  86. package/dist/image-picker.esm.js.LICENSE.txt +1 -1
  87. package/dist/image.cjs.js +1 -1
  88. package/dist/image.cjs.js.LICENSE.txt +1 -1
  89. package/dist/image.esm.js +1 -1
  90. package/dist/image.esm.js.LICENSE.txt +1 -1
  91. package/dist/index.cjs.js +1 -1
  92. package/dist/index.cjs.js.LICENSE.txt +1 -1
  93. package/dist/index.d.ts +1 -1
  94. package/dist/index.esm.js +1 -1
  95. package/dist/index.esm.js.LICENSE.txt +1 -1
  96. package/dist/keyframe-animation.cjs.js.LICENSE.txt +1 -1
  97. package/dist/keyframe-animation.esm.js.LICENSE.txt +1 -1
  98. package/dist/link-getter.cjs.js +1 -1
  99. package/dist/link-getter.cjs.js.LICENSE.txt +1 -1
  100. package/dist/link-getter.esm.js +1 -1
  101. package/dist/link-getter.esm.js.LICENSE.txt +1 -1
  102. package/dist/link.cjs.js +1 -1
  103. package/dist/link.cjs.js.LICENSE.txt +1 -1
  104. package/dist/link.esm.js +1 -1
  105. package/dist/link.esm.js.LICENSE.txt +1 -1
  106. package/dist/meta-adder.cjs.js +1 -1
  107. package/dist/meta-adder.cjs.js.LICENSE.txt +1 -1
  108. package/dist/meta-adder.esm.js +1 -1
  109. package/dist/meta-adder.esm.js.LICENSE.txt +1 -1
  110. package/dist/modal-2025.cjs.js +1 -1
  111. package/dist/modal-2025.cjs.js.LICENSE.txt +1 -1
  112. package/dist/modal-2025.esm.js +1 -1
  113. package/dist/modal-2025.esm.js.LICENSE.txt +1 -1
  114. package/dist/multiswitcher.cjs.js +1 -1
  115. package/dist/multiswitcher.cjs.js.LICENSE.txt +1 -1
  116. package/dist/multiswitcher.esm.js +1 -1
  117. package/dist/multiswitcher.esm.js.LICENSE.txt +1 -1
  118. package/dist/new-nav-bar.cjs.js +1 -1
  119. package/dist/new-nav-bar.cjs.js.LICENSE.txt +1 -1
  120. package/dist/new-nav-bar.esm.js +1 -1
  121. package/dist/new-nav-bar.esm.js.LICENSE.txt +1 -1
  122. package/dist/picker.cjs.js +1 -1
  123. package/dist/picker.cjs.js.LICENSE.txt +1 -1
  124. package/dist/picker.esm.js +1 -1
  125. package/dist/picker.esm.js.LICENSE.txt +1 -1
  126. package/dist/progress.cjs.js +1 -1
  127. package/dist/progress.cjs.js.LICENSE.txt +1 -1
  128. package/dist/progress.esm.js +1 -1
  129. package/dist/progress.esm.js.LICENSE.txt +1 -1
  130. package/dist/radio.cjs.js.LICENSE.txt +1 -1
  131. package/dist/radio.esm.js.LICENSE.txt +1 -1
  132. package/dist/range.cjs.js.LICENSE.txt +1 -1
  133. package/dist/range.esm.js.LICENSE.txt +1 -1
  134. package/dist/scroll-video.cjs.js.LICENSE.txt +1 -1
  135. package/dist/scroll-video.esm.js.LICENSE.txt +1 -1
  136. package/dist/side-bar.cjs.js +1 -1
  137. package/dist/side-bar.cjs.js.LICENSE.txt +1 -1
  138. package/dist/side-bar.esm.js +1 -1
  139. package/dist/side-bar.esm.js.LICENSE.txt +1 -1
  140. package/dist/side-nav-bar.cjs.js +1 -1
  141. package/dist/side-nav-bar.cjs.js.LICENSE.txt +1 -1
  142. package/dist/side-nav-bar.esm.js +1 -1
  143. package/dist/side-nav-bar.esm.js.LICENSE.txt +1 -1
  144. package/dist/simple-bar.cjs.js +1 -1
  145. package/dist/simple-bar.cjs.js.LICENSE.txt +1 -1
  146. package/dist/simple-bar.esm.js +1 -1
  147. package/dist/simple-bar.esm.js.LICENSE.txt +1 -1
  148. package/dist/slider-2025.cjs.js +1 -1
  149. package/dist/slider-2025.cjs.js.LICENSE.txt +1 -1
  150. package/dist/slider-2025.esm.js +1 -1
  151. package/dist/slider-2025.esm.js.LICENSE.txt +1 -1
  152. package/dist/spacer.cjs.js +1 -1
  153. package/dist/spacer.cjs.js.LICENSE.txt +1 -1
  154. package/dist/spacer.esm.js +1 -1
  155. package/dist/spacer.esm.js.LICENSE.txt +1 -1
  156. package/dist/stack.cjs.js +1 -1
  157. package/dist/stack.cjs.js.LICENSE.txt +1 -1
  158. package/dist/stack.esm.js +1 -1
  159. package/dist/stack.esm.js.LICENSE.txt +1 -1
  160. package/dist/stacker.cjs.js.LICENSE.txt +1 -1
  161. package/dist/stacker.esm.js.LICENSE.txt +1 -1
  162. package/dist/table.cjs.js +1 -1
  163. package/dist/table.cjs.js.LICENSE.txt +1 -1
  164. package/dist/table.esm.js +1 -1
  165. package/dist/table.esm.js.LICENSE.txt +1 -1
  166. package/dist/text-field.cjs.js +1 -1
  167. package/dist/text-field.cjs.js.LICENSE.txt +1 -1
  168. package/dist/text-field.esm.js +1 -1
  169. package/dist/text-field.esm.js.LICENSE.txt +1 -1
  170. package/dist/text.cjs.js +1 -1
  171. package/dist/text.cjs.js.LICENSE.txt +1 -1
  172. package/dist/text.esm.js +1 -1
  173. package/dist/text.esm.js.LICENSE.txt +1 -1
  174. package/dist/theme.cjs.js.LICENSE.txt +1 -1
  175. package/dist/theme.esm.js.LICENSE.txt +1 -1
  176. package/dist/transform-anim.cjs.js.LICENSE.txt +1 -1
  177. package/dist/transform-anim.esm.js.LICENSE.txt +1 -1
  178. package/dist/ulist.cjs.js +1 -1
  179. package/dist/ulist.cjs.js.LICENSE.txt +1 -1
  180. package/dist/ulist.esm.js +1 -1
  181. package/dist/ulist.esm.js.LICENSE.txt +1 -1
  182. package/dist/video.cjs.js +1 -1
  183. package/dist/video.cjs.js.LICENSE.txt +1 -1
  184. package/dist/video.esm.js +1 -1
  185. package/dist/video.esm.js.LICENSE.txt +1 -1
  186. package/dist/wrap.cjs.js +1 -1
  187. package/dist/wrap.cjs.js.LICENSE.txt +1 -1
  188. package/dist/wrap.esm.js +1 -1
  189. package/dist/wrap.esm.js.LICENSE.txt +1 -1
  190. package/dist/zoom-card.cjs.js +1 -1
  191. package/dist/zoom-card.cjs.js.LICENSE.txt +1 -1
  192. package/dist/zoom-card.esm.js +1 -1
  193. package/dist/zoom-card.esm.js.LICENSE.txt +1 -1
  194. package/layout/animator.js +13 -2
  195. package/layout/audio.js +1 -1
  196. package/layout/audionew.js +1 -1
  197. package/layout/base.js +1 -1
  198. package/layout/beta-desktop-bar.js +1 -1
  199. package/layout/beta-mobile-bar.js +1 -1
  200. package/layout/button.js +1 -1
  201. package/layout/center.js +1 -1
  202. package/layout/checkbox.js +1 -1
  203. package/layout/circle.js +1 -1
  204. package/layout/code.js +1 -1
  205. package/layout/container.js +1 -1
  206. package/layout/dropdown-2025.js +1 -1
  207. package/layout/flex-card.js +1 -1
  208. package/layout/flex-grid.js +1 -1
  209. package/layout/flex-row.js +1 -1
  210. package/layout/form-components/custom.js +1 -1
  211. package/layout/form-components/data-list.js +1 -1
  212. package/layout/form-components/floating-input.js +1 -1
  213. package/layout/form-components/form-all.js +1 -1
  214. package/layout/form-components/form.js +1 -1
  215. package/layout/form-components/image-picker.js +1 -1
  216. package/layout/form-components/picker.js +1 -1
  217. package/layout/form-components/radio.js +1 -1
  218. package/layout/form-components/radiogroup.js +1 -1
  219. package/layout/form-components/range.js +1 -1
  220. package/layout/free.js +1 -1
  221. package/layout/grid-switcher.js +1 -1
  222. package/layout/grid.js +1 -1
  223. package/layout/horizontal-scroller.js +1 -1
  224. package/layout/image.js +1 -1
  225. package/layout/index.js +1 -1
  226. package/layout/link.js +1 -1
  227. package/layout/list.js +1 -1
  228. package/layout/meta-adder.js +1 -1
  229. package/layout/modal-2025.js +1 -1
  230. package/layout/morph.js +1 -1
  231. package/layout/multiswitcher.js +1 -1
  232. package/layout/nav-bar.js +1 -1
  233. package/layout/nav-factor/custom-div.js +1 -1
  234. package/layout/new-nav-bar.js +1 -1
  235. package/layout/polygon.js +1 -1
  236. package/layout/prerender-site.js +1 -1
  237. package/layout/prerender.js +1 -1
  238. package/layout/progress.js +1 -1
  239. package/layout/row.js +1 -1
  240. package/layout/scroll-video.js +1 -1
  241. package/layout/side-bar.js +1 -1
  242. package/layout/side-nav-bar.js +1 -1
  243. package/layout/simple-bar.js +1 -1
  244. package/layout/slider-2025.js +1 -1
  245. package/layout/spacer.js +1 -1
  246. package/layout/stack.js +1 -1
  247. package/layout/svg.js +1 -1
  248. package/layout/switcher.js +1 -1
  249. package/layout/table.js +1 -1
  250. package/layout/text-field.js +1 -1
  251. package/layout/text.js +1 -1
  252. package/layout/ulist.js +1 -1
  253. package/layout/video.js +1 -1
  254. package/layout/wrap.js +1 -1
  255. package/layout/zoom-card.js +1 -1
  256. package/lib/agent-surface.js +1 -1
  257. package/lib/card-getter.js +1 -1
  258. package/lib/codegen.js +1 -1
  259. package/lib/data.js +1 -1
  260. package/lib/designer.js +6 -2
  261. package/lib/element-mapper.js +5 -5
  262. package/lib/keyframe-animation.js +1 -1
  263. package/lib/link-getter.js +1 -1
  264. package/lib/morph-node.js +1 -1
  265. package/lib/raster-inspect.js +1 -1
  266. package/lib/raster-ops.js +1 -1
  267. package/lib/raster-presets.js +1 -1
  268. package/lib/scroll-video.js +1 -1
  269. package/lib/seo.js +1 -1
  270. package/lib/stacker.js +1 -1
  271. package/lib/suggest.js +1 -1
  272. package/lib/theme.js +1 -1
  273. package/lib/transform-anim.js +1 -1
  274. package/lib/transition.js +1 -1
  275. package/lib/validate-nodes.js +107 -2
  276. package/lib/webmcp-adapter.js +1 -1
  277. package/package.json +3 -2
  278. package/skills/nodality/SKILL.md +203 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/spacer.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/stack.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/svg.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/table.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/text.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/ulist.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/video.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/layout/wrap.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/codegen.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/data.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/designer.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1309,7 +1309,11 @@ new Slider(texts, null, { tintColor: "#e74c3c", inactiveColor: "#ccc" })
1309
1309
  code.style.width = 300;
1310
1310
  code.style.height = 300; // both work
1311
1311
  code.setAttribute("id", "elements");
1312
- code.value = this.code.join("");
1312
+ // ";\n\n", not "": each entry is a complete expression, and joining
1313
+ // them with nothing produced "})new Text(" — a syntax error, so the
1314
+ // generated code could not be pasted anywhere once a page had more
1315
+ // than one element.
1316
+ code.value = this.code.join(";\n\n");
1313
1317
  this.target = "#elements";
1314
1318
 
1315
1319
  let pre = document.createElement("pre");
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1618,10 +1618,10 @@ const blast = this.filtero("blast", el.id, obj.customOptions);
1618
1618
  .items([
1619
1619
  new Image(item.img).set({isFull: true, url: item.img}),
1620
1620
  // #f97316 rather than the CSS keyword orange (rgb 255,165,0), a legacy
1621
- // value that reads yellow beside modern palettes. No backticks here:
1622
- // this block lives inside a template literal and is evaluated as
1623
- // source, so module scope is not visible either.
1624
- new Text(item.title).set({ size: "S5", color: "#f97316" }),
1621
+ // value that reads yellow beside modern palettes. No backticks here:
1622
+ // this block lives inside a template literal and is evaluated as
1623
+ // source, so module scope is not visible either.
1624
+ new Text(item.title).set({ size: "S5", color: "#f97316" }),
1625
1625
  new Link("Link").set({
1626
1626
  text: item.title,
1627
1627
  url: item.link,
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/morph-node.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/raster-ops.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/seo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/stacker.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/suggest.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/theme.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/transition.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -59,6 +59,59 @@ const EDGE_FIELDS = [
59
59
  */
60
60
  const AGENT_SURFACE_FIELDS = ["op", "name", "forms", "exclude"];
61
61
 
62
+ /**
63
+ * Design ops that may be written as a BARE STRING, `{ op: "gradient" }`,
64
+ * and are expanded against a table of defaults by `Des.add`. This list is
65
+ * that table's key set (`ops` in designer.js) and must track it: a string
66
+ * outside it is never expanded, so it reaches the renderer as a node
67
+ * nothing matches and does nothing at all.
68
+ *
69
+ * None of these collide with a raster op name, which is what makes the
70
+ * two string families separable at all.
71
+ */
72
+ const BARE_DESIGN_OPS = [
73
+ "blast", "gradient", "shadow", "filter", "animation", "transform", "span",
74
+ ];
75
+
76
+ /**
77
+ * Design ops written in object form, `{ op: { name: "gradient", … } }`.
78
+ *
79
+ * Assembled from the dispatch sites rather than from the documentation,
80
+ * because the two disagree: the reference calls one of these "LinkStyle"
81
+ * while the runtime matches `"link-style"`. Deliberately generous — a
82
+ * name missing from this list produces a false UNKNOWN_DESIGN_OP on a
83
+ * node that works, and `preview` refuses to render an invalid pair, so
84
+ * over-reporting costs more than under-reporting.
85
+ */
86
+ const DESIGN_OP_NAMES = [
87
+ "animation", "background", "blast", "card-style", "filter", "gradient",
88
+ "layout", "link-style", "margin", "navStyle", "shadow", "slayout",
89
+ "span", "transform",
90
+ ];
91
+
92
+ /**
93
+ * Every top-level key a design node reads.
94
+ *
95
+ * Both forms read `op`, `target`, `range`, and — from the loop that runs
96
+ * over every node, not just the expanded ones — `style` and `duration`.
97
+ * Anything else on the object form is ignored in silence, which is
98
+ * precisely how the README's `colors: [...]` survived.
99
+ *
100
+ * The bare-string form reads four more, because its expansion lifts them
101
+ * INTO the op it substitutes: that is how
102
+ * `{ op: "gradient", gradient: "linear-gradient(…)" }` customises the
103
+ * default, and it is documented, so the two forms cannot share one list.
104
+ *
105
+ * Assembled by reading every `customOptions[i].x` and `protoOptions[i].x`
106
+ * in designer.js, then swept against the e2e fixtures — which is how
107
+ * `style` and `duration` were caught. Guessing this list produces false
108
+ * positives on working pages, and `preview` refuses an invalid pair.
109
+ */
110
+ const DESIGN_FIELDS = ["op", "target", "range", "style", "duration"];
111
+ const BARE_DESIGN_FIELDS = [
112
+ ...DESIGN_FIELDS, "filter", "gradient", "color", "width",
113
+ ];
114
+
62
115
  /** Node families, told apart exactly the way the runtime tells them apart. */
63
116
  const familyOf = (node) => {
64
117
  if (!node || typeof node !== "object") return "invalid";
@@ -66,6 +119,12 @@ const familyOf = (node) => {
66
119
  if (typeof op === "string") {
67
120
  if (op === "morph") return "morph";
68
121
  if (op === "agent-surface") return "agent-surface";
122
+ // Checked BEFORE falling through to raster. A bare-string design
123
+ // op is not a raster op, and reporting it as an unknown one was a
124
+ // false positive on documented usage: `{ op: "gradient" }` is on
125
+ // the gradient page, renders the default gradient, and validated
126
+ // as UNKNOWN_OP suggesting a raster op that would not do it.
127
+ if (BARE_DESIGN_OPS.includes(op)) return "design";
69
128
  return "raster";
70
129
  }
71
130
  if (op && typeof op === "object" && typeof op.name === "string") return "design";
@@ -174,7 +233,53 @@ export function validateNodes(nodes, elements) {
174
233
 
175
234
  checkTargets(node.target, `${path}.target`);
176
235
 
177
- if (family === "design") return; // design nodes carry their own vocabulary
236
+ if (family === "design") {
237
+ // Was `return` — "design nodes carry their own vocabulary", which
238
+ // was true and yet left the whole family unchecked. The cost was
239
+ // paid in the reference: a design option written in the wrong
240
+ // place is not a no-op with a warning, it is a no-op in silence,
241
+ // and the gradient one made the target INVISIBLE. Checked here at
242
+ // the two levels the runtime actually reads.
243
+ const bare = typeof node.op === "string";
244
+ const name = bare ? node.op : node.op.name;
245
+
246
+ if (!bare && !DESIGN_OP_NAMES.includes(name)) {
247
+ push("UNKNOWN_DESIGN_OP", `${path}.op.name`, name,
248
+ suggest(name, DESIGN_OP_NAMES), DESIGN_OP_NAMES);
249
+ }
250
+
251
+ // Top-level keys. The object form reads three; the bare-string
252
+ // form reads four more because its expansion lifts them into the
253
+ // op it substitutes.
254
+ const allowed = bare ? BARE_DESIGN_FIELDS : DESIGN_FIELDS;
255
+ for (const key in node) {
256
+ if (allowed.includes(key)) continue;
257
+ // A near miss of a real top-level field is a typo and gets
258
+ // the usual suggestion. Anything else, on the object form,
259
+ // is almost always an option written one level too high —
260
+ // design options live INSIDE `op` — so say where it goes
261
+ // rather than only listing what may sit out here. That is
262
+ // the whole of the README's `colors` mistake.
263
+ const near = suggest(key, allowed);
264
+ const hint = near.length || bare ? near : [`op.${key}`];
265
+ push("UNKNOWN_PARAM", `${path}.${key}`, key, hint, allowed);
266
+ }
267
+
268
+ // A gradient with nothing to paint. `op.gradient` is the CSS
269
+ // string and `op.direction: "radial"` substitutes a built-in
270
+ // one; with neither, the node names an effect that cannot
271
+ // happen. It renders as nothing since 1.2.7 and rendered as an
272
+ // invisible element before that, so it is worth a report either
273
+ // way. The bare-string form is exempt: its whole purpose is to
274
+ // take the default.
275
+ if (!bare && name === "gradient" &&
276
+ node.op.gradient === undefined && node.op.direction === undefined) {
277
+ push("MISSING_FIELD", `${path}.op.gradient`, undefined, [],
278
+ ["a CSS gradient, e.g. \"linear-gradient(#1d6fe0, #7fd1ff)\"",
279
+ "or direction: \"radial\" to take the built-in one"]);
280
+ }
281
+ return;
282
+ }
178
283
 
179
284
  if (family === "agent-surface") {
180
285
  // The ids this node names must exist, for the usual reason:
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.2.5
2
+ * nodality v1.2.7
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodality",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "A lightweight library for declarative UI elements.",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -13,7 +13,8 @@
13
13
  "dist/",
14
14
  "bin/",
15
15
  "API.md",
16
- "examples/"
16
+ "examples/",
17
+ "skills/"
17
18
  ],
18
19
  "exports": {
19
20
  ".": {