@caelo-cms/shared 0.10.22 → 0.10.24

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 (249) hide show
  1. package/dist/ai-tools.d.ts +289 -273
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +342 -323
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/auth-forms.d.ts.map +1 -1
  6. package/dist/auth-forms.js +4 -1
  7. package/dist/auth-forms.js.map +1 -1
  8. package/dist/base-css.d.ts +35 -0
  9. package/dist/base-css.d.ts.map +1 -0
  10. package/dist/base-css.js +40 -0
  11. package/dist/base-css.js.map +1 -0
  12. package/dist/build-page.d.ts +330 -0
  13. package/dist/build-page.d.ts.map +1 -0
  14. package/dist/build-page.js +282 -0
  15. package/dist/build-page.js.map +1 -0
  16. package/dist/content.d.ts +322 -9
  17. package/dist/content.d.ts.map +1 -1
  18. package/dist/content.js +354 -11
  19. package/dist/content.js.map +1 -1
  20. package/dist/css-gradient-scan.d.ts +14 -0
  21. package/dist/css-gradient-scan.d.ts.map +1 -0
  22. package/dist/css-gradient-scan.js +81 -0
  23. package/dist/css-gradient-scan.js.map +1 -0
  24. package/dist/css-var-scan.d.ts +56 -0
  25. package/dist/css-var-scan.d.ts.map +1 -0
  26. package/dist/css-var-scan.js +97 -0
  27. package/dist/css-var-scan.js.map +1 -0
  28. package/dist/design-draft-shell.d.ts +21 -0
  29. package/dist/design-draft-shell.d.ts.map +1 -0
  30. package/dist/design-draft-shell.js +81 -0
  31. package/dist/design-draft-shell.js.map +1 -0
  32. package/dist/design-manifest.d.ts +36 -0
  33. package/dist/design-manifest.d.ts.map +1 -0
  34. package/dist/design-manifest.js +90 -0
  35. package/dist/design-manifest.js.map +1 -0
  36. package/dist/fonts.d.ts +89 -0
  37. package/dist/fonts.d.ts.map +1 -0
  38. package/dist/fonts.js +241 -0
  39. package/dist/fonts.js.map +1 -0
  40. package/dist/genesis-inventory.d.ts +32 -0
  41. package/dist/genesis-inventory.d.ts.map +1 -0
  42. package/dist/genesis-inventory.js +186 -0
  43. package/dist/genesis-inventory.js.map +1 -0
  44. package/dist/genesis.d.ts +102 -0
  45. package/dist/genesis.d.ts.map +1 -0
  46. package/dist/genesis.js +145 -0
  47. package/dist/genesis.js.map +1 -0
  48. package/dist/i18n.d.ts +29 -36
  49. package/dist/i18n.d.ts.map +1 -1
  50. package/dist/i18n.js +53 -128
  51. package/dist/i18n.js.map +1 -1
  52. package/dist/index.d.ts +28 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +28 -1
  55. package/dist/index.js.map +1 -1
  56. package/dist/interactions.d.ts +23 -0
  57. package/dist/interactions.d.ts.map +1 -0
  58. package/dist/interactions.js +44 -0
  59. package/dist/interactions.js.map +1 -0
  60. package/dist/media.d.ts +101 -16
  61. package/dist/media.d.ts.map +1 -1
  62. package/dist/media.js +126 -15
  63. package/dist/media.js.map +1 -1
  64. package/dist/page-log.d.ts +94 -0
  65. package/dist/page-log.d.ts.map +1 -0
  66. package/dist/page-log.js +111 -0
  67. package/dist/page-log.js.map +1 -0
  68. package/dist/preview-compose.d.ts +85 -12
  69. package/dist/preview-compose.d.ts.map +1 -1
  70. package/dist/preview-compose.js +157 -67
  71. package/dist/preview-compose.js.map +1 -1
  72. package/dist/proposal-status.d.ts +40 -0
  73. package/dist/proposal-status.d.ts.map +1 -0
  74. package/dist/proposal-status.js +34 -0
  75. package/dist/proposal-status.js.map +1 -0
  76. package/dist/responsive-images.d.ts +64 -0
  77. package/dist/responsive-images.d.ts.map +1 -0
  78. package/dist/responsive-images.js +98 -0
  79. package/dist/responsive-images.js.map +1 -0
  80. package/dist/safe-keys.d.ts +9 -0
  81. package/dist/safe-keys.d.ts.map +1 -0
  82. package/dist/safe-keys.js +20 -0
  83. package/dist/safe-keys.js.map +1 -0
  84. package/dist/seo.d.ts +11 -16
  85. package/dist/seo.d.ts.map +1 -1
  86. package/dist/seo.js +7 -23
  87. package/dist/seo.js.map +1 -1
  88. package/dist/skills.d.ts +14 -68
  89. package/dist/skills.d.ts.map +1 -1
  90. package/dist/skills.js +19 -113
  91. package/dist/skills.js.map +1 -1
  92. package/dist/strip-cdata.d.ts +7 -0
  93. package/dist/strip-cdata.d.ts.map +1 -0
  94. package/dist/strip-cdata.js +48 -0
  95. package/dist/strip-cdata.js.map +1 -0
  96. package/dist/structured-sets.d.ts +6 -52
  97. package/dist/structured-sets.d.ts.map +1 -1
  98. package/dist/structured-sets.js +6 -68
  99. package/dist/structured-sets.js.map +1 -1
  100. package/dist/subagents.d.ts +105 -3
  101. package/dist/subagents.d.ts.map +1 -1
  102. package/dist/subagents.js +224 -41
  103. package/dist/subagents.js.map +1 -1
  104. package/dist/template-engine.d.ts +85 -0
  105. package/dist/template-engine.d.ts.map +1 -0
  106. package/dist/template-engine.js +403 -0
  107. package/dist/template-engine.js.map +1 -0
  108. package/dist/theme-importers/auto-detect.d.ts +26 -0
  109. package/dist/theme-importers/auto-detect.d.ts.map +1 -0
  110. package/dist/theme-importers/auto-detect.js +42 -0
  111. package/dist/theme-importers/auto-detect.js.map +1 -0
  112. package/dist/theme-importers/css-comments.d.ts +12 -0
  113. package/dist/theme-importers/css-comments.d.ts.map +1 -0
  114. package/dist/theme-importers/css-comments.js +15 -0
  115. package/dist/theme-importers/css-comments.js.map +1 -0
  116. package/dist/theme-importers/dtcg.d.ts +46 -0
  117. package/dist/theme-importers/dtcg.d.ts.map +1 -0
  118. package/dist/theme-importers/dtcg.js +111 -0
  119. package/dist/theme-importers/dtcg.js.map +1 -0
  120. package/dist/theme-importers/loose.d.ts +3 -0
  121. package/dist/theme-importers/loose.d.ts.map +1 -0
  122. package/dist/theme-importers/loose.js +76 -0
  123. package/dist/theme-importers/loose.js.map +1 -0
  124. package/dist/theme-importers/shadcn.d.ts +24 -0
  125. package/dist/theme-importers/shadcn.d.ts.map +1 -0
  126. package/dist/theme-importers/shadcn.js +135 -0
  127. package/dist/theme-importers/shadcn.js.map +1 -0
  128. package/dist/theme-importers/style-dictionary.d.ts +17 -0
  129. package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
  130. package/dist/theme-importers/style-dictionary.js +125 -0
  131. package/dist/theme-importers/style-dictionary.js.map +1 -0
  132. package/dist/theme-importers/tailwind.d.ts +3 -0
  133. package/dist/theme-importers/tailwind.d.ts.map +1 -0
  134. package/dist/theme-importers/tailwind.js +218 -0
  135. package/dist/theme-importers/tailwind.js.map +1 -0
  136. package/dist/theme-literal-binding.d.ts +37 -0
  137. package/dist/theme-literal-binding.d.ts.map +1 -0
  138. package/dist/theme-literal-binding.js +138 -0
  139. package/dist/theme-literal-binding.js.map +1 -0
  140. package/dist/theme-normalize.d.ts +31 -0
  141. package/dist/theme-normalize.d.ts.map +1 -0
  142. package/dist/theme-normalize.js +587 -0
  143. package/dist/theme-normalize.js.map +1 -0
  144. package/dist/theme-ramp.d.ts +55 -0
  145. package/dist/theme-ramp.d.ts.map +1 -0
  146. package/dist/theme-ramp.js +149 -0
  147. package/dist/theme-ramp.js.map +1 -0
  148. package/dist/theme-render.d.ts +105 -0
  149. package/dist/theme-render.d.ts.map +1 -0
  150. package/dist/theme-render.js +441 -0
  151. package/dist/theme-render.js.map +1 -0
  152. package/dist/themes-errors.d.ts +109 -0
  153. package/dist/themes-errors.d.ts.map +1 -0
  154. package/dist/themes-errors.js +170 -0
  155. package/dist/themes-errors.js.map +1 -0
  156. package/dist/themes.d.ts +343 -0
  157. package/dist/themes.d.ts.map +1 -0
  158. package/dist/themes.js +697 -0
  159. package/dist/themes.js.map +1 -0
  160. package/dist/version.d.ts +7 -4
  161. package/dist/version.d.ts.map +1 -1
  162. package/dist/version.js +6 -3
  163. package/dist/version.js.map +1 -1
  164. package/package.json +10 -2
  165. package/src/__tests__/redos-hardening.test.ts +160 -0
  166. package/src/ai-tools-add-module-modes.test.ts +106 -0
  167. package/src/ai-tools-position.test.ts +134 -0
  168. package/src/ai-tools.test.ts +81 -0
  169. package/src/ai-tools.ts +1105 -0
  170. package/src/auth-forms.ts +36 -0
  171. package/src/base-css.ts +42 -0
  172. package/src/build-page.test.ts +228 -0
  173. package/src/build-page.ts +319 -0
  174. package/src/cap-failures.ts +67 -0
  175. package/src/content.test.ts +170 -0
  176. package/src/content.ts +620 -0
  177. package/src/context.ts +43 -0
  178. package/src/css-gradient-scan.ts +88 -0
  179. package/src/css-var-scan.test.ts +96 -0
  180. package/src/css-var-scan.ts +144 -0
  181. package/src/derive-module-type.test.ts +80 -0
  182. package/src/design-draft-shell.test.ts +85 -0
  183. package/src/design-draft-shell.ts +109 -0
  184. package/src/design-manifest.ts +93 -0
  185. package/src/fonts.test.ts +157 -0
  186. package/src/fonts.ts +296 -0
  187. package/src/genesis-inventory.test.ts +86 -0
  188. package/src/genesis-inventory.ts +215 -0
  189. package/src/genesis-sanitize.test.ts +35 -0
  190. package/src/genesis.ts +158 -0
  191. package/src/i18n.test.ts +58 -0
  192. package/src/i18n.ts +91 -0
  193. package/src/index.test.ts +10 -0
  194. package/src/index.ts +59 -0
  195. package/src/interactions.ts +48 -0
  196. package/src/logger.ts +147 -0
  197. package/src/media.test.ts +160 -0
  198. package/src/media.ts +355 -0
  199. package/src/page-log.test.ts +163 -0
  200. package/src/page-log.ts +124 -0
  201. package/src/preview-compose.test.ts +637 -0
  202. package/src/preview-compose.ts +656 -0
  203. package/src/preview-scanner.test.ts +96 -0
  204. package/src/preview-scanner.ts +214 -0
  205. package/src/proposal-status.test.ts +69 -0
  206. package/src/proposal-status.ts +40 -0
  207. package/src/responsive-images.test.ts +104 -0
  208. package/src/responsive-images.ts +151 -0
  209. package/src/result.ts +29 -0
  210. package/src/safe-keys.ts +21 -0
  211. package/src/seo.test.ts +194 -0
  212. package/src/seo.ts +233 -0
  213. package/src/skills.ts +48 -0
  214. package/src/snapshots.test.ts +80 -0
  215. package/src/snapshots.ts +81 -0
  216. package/src/strip-cdata.test.ts +41 -0
  217. package/src/strip-cdata.ts +50 -0
  218. package/src/structured-sets.ts +114 -0
  219. package/src/subagents.test.ts +262 -0
  220. package/src/subagents.ts +432 -0
  221. package/src/template-engine.test.ts +379 -0
  222. package/src/template-engine.ts +520 -0
  223. package/src/theme-gradient.test.ts +92 -0
  224. package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
  225. package/src/theme-importers/auto-detect.ts +84 -0
  226. package/src/theme-importers/css-comments.ts +15 -0
  227. package/src/theme-importers/dtcg.ts +106 -0
  228. package/src/theme-importers/loose.ts +76 -0
  229. package/src/theme-importers/shadcn.ts +133 -0
  230. package/src/theme-importers/style-dictionary.ts +125 -0
  231. package/src/theme-importers/tailwind.ts +217 -0
  232. package/src/theme-literal-binding.test.ts +71 -0
  233. package/src/theme-literal-binding.ts +159 -0
  234. package/src/theme-motion.test.ts +115 -0
  235. package/src/theme-normalize-envelope.test.ts +43 -0
  236. package/src/theme-normalize-gradient.test.ts +135 -0
  237. package/src/theme-normalize.ts +661 -0
  238. package/src/theme-ramp.ts +187 -0
  239. package/src/theme-render-sanitize.test.ts +45 -0
  240. package/src/theme-render.test.ts +119 -0
  241. package/src/theme-render.ts +487 -0
  242. package/src/theme-shadow.test.ts +56 -0
  243. package/src/themes-errors.ts +199 -0
  244. package/src/themes.ts +842 -0
  245. package/src/version.ts +66 -0
  246. package/dist/translation.d.ts +0 -127
  247. package/dist/translation.d.ts.map +0 -1
  248. package/dist/translation.js +0 -208
  249. package/dist/translation.js.map +0 -1
@@ -0,0 +1,441 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * v0.11.0 — DTCG-aligned theme renderer (#45 Phase 3).
4
+ *
5
+ * Walks a `ThemeDocument` (DTCG tokens jsonb) and emits CSS custom
6
+ * properties under the Tailwind 4 namespace convention so module CSS
7
+ * can `var(--color-primary)` / `var(--spacing-lg)` etc. without
8
+ * mental-translation from DTCG paths.
9
+ *
10
+ * Namespace mapping (matches Tailwind 4's `@theme { … }` directive):
11
+ *
12
+ * color.X → --color-X
13
+ * typography.X → --font-X (fontFamily) + --text-X (fontSize)
14
+ * + --font-weight-X + --leading-X + --tracking-X
15
+ * spacing.X → --spacing-X
16
+ * radius.X → --radius-X
17
+ * shadow.X → --shadow-X (expanded to `<x> <y> <blur> [spread] <color> [inset]`)
18
+ * breakpoint.X → --breakpoint-X
19
+ * duration.X → --duration-X
20
+ * ease.X → --ease-X (cubic-bezier expansion)
21
+ *
22
+ * Color tokens carrying `{ light, dark }` emit the light value inside
23
+ * `:root { … }` AND the dark value inside `:root.dark { … }` so a
24
+ * single declaration drives both surfaces.
25
+ *
26
+ * DTCG aliases (`"{group.token}"`) are resolved before emission.
27
+ * Cyclic aliases produce a structured error rather than infinite-
28
+ * looping. Pure function — no IO, dependency-free, testable in unit
29
+ * isolation.
30
+ */
31
+ import { flattenTokens } from "./themes.js";
32
+ /** Renderer-level error for cyclic / unresolved aliases. */
33
+ export class ThemeRenderError extends Error {
34
+ kind;
35
+ path;
36
+ constructor(kind, path, message) {
37
+ super(message);
38
+ this.name = "ThemeRenderError";
39
+ this.kind = kind;
40
+ this.path = path;
41
+ }
42
+ }
43
+ /**
44
+ * Emit the `:root { … }` (+ optional `:root.dark { … }`) CSS for the
45
+ * supplied tokens document. Returns the bare CSS body — caller wraps
46
+ * it in `<style data-source="theme">…</style>` and injects it ahead of
47
+ * module CSS in the document head.
48
+ *
49
+ * Pass `options.selector` (v0.11.1) to scope the rule blocks under a
50
+ * custom selector instead of `:root`. The admin live preview uses
51
+ * `.theme-preview` so the operator's edits don't leak onto the admin
52
+ * UI. Public + chat paths omit the option and get the default.
53
+ */
54
+ export function renderThemeCss(tokens, options = {}) {
55
+ const selector = options.selector ?? ":root";
56
+ const flat = flattenTokens(tokens);
57
+ const resolveCache = new Map();
58
+ const lightLines = [];
59
+ const darkLines = [];
60
+ for (const { path, token } of flat) {
61
+ const category = path.split(".")[0] ?? "";
62
+ const value = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
63
+ emitTokenLines(category, path, value, lightLines, darkLines);
64
+ }
65
+ const lightBlock = `${selector}{${lightLines.join("")}}`;
66
+ if (darkLines.length === 0)
67
+ return lightBlock;
68
+ return `${lightBlock}${selector}.dark{${darkLines.join("")}}`;
69
+ }
70
+ // ────────────────────────────────────────────────────────────────────
71
+ // v0.11.1 (issue #76) — `get_theme as` format helpers
72
+ // ────────────────────────────────────────────────────────────────────
73
+ /**
74
+ * Named export of the `:root { … }` CSS-vars form. Alias for
75
+ * `renderThemeCss(tokens)` — exists so the AI tool's `as: "css-vars"`
76
+ * dispatch table reads symmetrically with the other format names.
77
+ */
78
+ export function formatThemeAsCssVars(tokens) {
79
+ return renderThemeCss(tokens);
80
+ }
81
+ /**
82
+ * v0.11.4 (issue #76 follow-up) — return JUST the CSS variable names
83
+ * the renderer would emit for this token document. The AI uses this in
84
+ * the system-prompt `## Theme` block so it knows exactly which
85
+ * `var(--…)` names exist before authoring module CSS.
86
+ *
87
+ * Without this surface the AI guesses var names (e.g. `--color-text`,
88
+ * `--color-surface`) that look reasonable but don't exist in the
89
+ * shadcn-style theme — its CSS then falls through to hardcoded
90
+ * fallbacks and the page renders monochrome regardless of token values.
91
+ *
92
+ * Returns a sorted, de-duplicated array. Emits the same names as the
93
+ * `renderThemeCss` light branch (the dark variant uses the same names
94
+ * with different values, so listing them once is correct).
95
+ */
96
+ export function listThemeCssVarNames(tokens) {
97
+ const flat = flattenTokens(tokens);
98
+ if (flat.length === 0)
99
+ return [];
100
+ const resolveCache = new Map();
101
+ const lines = [];
102
+ for (const { path, token } of flat) {
103
+ const category = path.split(".")[0] ?? "";
104
+ const value = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
105
+ emitTokenLines(category, path, value, lines, []);
106
+ }
107
+ // Each `lines` entry is `--name:value;`. Strip the value to get the name.
108
+ const names = new Set();
109
+ for (const line of lines) {
110
+ const colon = line.indexOf(":");
111
+ if (colon <= 0)
112
+ continue;
113
+ const name = line.slice(0, colon).trim();
114
+ if (name.startsWith("--"))
115
+ names.add(name);
116
+ }
117
+ return [...names].sort();
118
+ }
119
+ /**
120
+ * Emit a Tailwind 4 `@theme inline { … }` block. The body re-uses the
121
+ * same per-category emission as `renderThemeCss` so the variable names
122
+ * match what `app.css` exposes — feeding this output into the Tailwind
123
+ * importer round-trips to the same DTCG document.
124
+ */
125
+ export function formatThemeAsTailwind(tokens) {
126
+ const flat = flattenTokens(tokens);
127
+ const resolveCache = new Map();
128
+ const lightLines = [];
129
+ const darkLines = [];
130
+ for (const { path, token } of flat) {
131
+ const category = path.split(".")[0] ?? "";
132
+ const value = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
133
+ emitTokenLines(category, path, value, lightLines, darkLines);
134
+ }
135
+ // Tailwind 4 `@theme` doesn't have a built-in dark variant; emit the
136
+ // light values in the `@theme inline` block and append a `.dark { … }`
137
+ // override block at module top-level (matches Caelo's app.css setup).
138
+ const themeBody = lightLines.join("");
139
+ if (darkLines.length === 0)
140
+ return `@theme inline {${themeBody}}`;
141
+ return `@theme inline {${themeBody}}\n.dark{${darkLines.join("")}}`;
142
+ }
143
+ /**
144
+ * Emit a terse one-line summary of the tokens document — primary color
145
+ * shorthand, body font, default radius, and category counts. Used by
146
+ * the system-prompt `## Theme` block so the AI sees the theme's feel
147
+ * without spending tokens on the full DTCG document.
148
+ *
149
+ * Format: `primary=<hex|oklch>, body=<fontFamily-first-name>, radius=<value>, <category counts>`.
150
+ * Falls back to category counts only when the canonical paths aren't
151
+ * populated (e.g. an empty or unusual theme).
152
+ */
153
+ export function formatThemeSummary(tokens) {
154
+ const flat = flattenTokens(tokens);
155
+ if (flat.length === 0)
156
+ return "no tokens";
157
+ const resolveCache = new Map();
158
+ let primary;
159
+ let body;
160
+ let radiusDefault;
161
+ const counts = new Map();
162
+ for (const { path, token } of flat) {
163
+ const category = path.split(".")[0] ?? "(uncategorised)";
164
+ counts.set(category, (counts.get(category) ?? 0) + 1);
165
+ if (path === "color.primary" ||
166
+ path === "color.primary.500" ||
167
+ path === "color.primary.DEFAULT") {
168
+ const v = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
169
+ const flatVal = pickColorVariant(v);
170
+ if (typeof flatVal === "string" && primary === undefined)
171
+ primary = flatVal;
172
+ }
173
+ if (path === "typography.body") {
174
+ const v = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
175
+ if (v && typeof v === "object" && "fontFamily" in v) {
176
+ const ff = v.fontFamily;
177
+ if (typeof ff === "string")
178
+ body = ff
179
+ .split(",")[0]
180
+ ?.trim()
181
+ .replace(/^['"]|['"]$/g, "");
182
+ }
183
+ }
184
+ if (path === "radius.md") {
185
+ const v = resolveTokenValue(token, tokens, resolveCache, new Set([path]));
186
+ if (typeof v === "string")
187
+ radiusDefault = v;
188
+ }
189
+ }
190
+ const parts = [];
191
+ if (primary)
192
+ parts.push(`primary=${primary}`);
193
+ if (body)
194
+ parts.push(`body=${body}`);
195
+ if (radiusDefault)
196
+ parts.push(`radius=${radiusDefault}`);
197
+ const categoryParts = [];
198
+ for (const [k, n] of counts)
199
+ categoryParts.push(`${n} ${k}`);
200
+ if (categoryParts.length > 0)
201
+ parts.push(categoryParts.join("/"));
202
+ return parts.join(", ");
203
+ }
204
+ function pickColorVariant(value) {
205
+ if (value && typeof value === "object" && "light" in value) {
206
+ return value.light;
207
+ }
208
+ return value;
209
+ }
210
+ // ────────────────────────────────────────────────────────────────────
211
+ // Alias resolution
212
+ // ────────────────────────────────────────────────────────────────────
213
+ const ALIAS_REGEX = /^\{([a-zA-Z0-9_.-]+)\}$/;
214
+ function resolveTokenValue(token, doc, cache, seen) {
215
+ return resolveValue(token.$value, doc, cache, seen);
216
+ }
217
+ function resolveValue(raw, doc, cache, seen) {
218
+ if (typeof raw === "string") {
219
+ const m = ALIAS_REGEX.exec(raw);
220
+ if (!m)
221
+ return raw;
222
+ const targetPath = m[1];
223
+ if (!targetPath)
224
+ return raw;
225
+ if (seen.has(targetPath)) {
226
+ throw new ThemeRenderError("cyclic-alias", targetPath, `cyclic DTCG alias detected at '${targetPath}' (chain: ${[...seen].join(" → ")} → ${targetPath})`);
227
+ }
228
+ if (cache.has(targetPath))
229
+ return cache.get(targetPath);
230
+ const target = lookupPath(doc, targetPath);
231
+ if (!target) {
232
+ throw new ThemeRenderError("missing-alias", targetPath, `DTCG alias '{${targetPath}}' points at a path that doesn't exist in this theme`);
233
+ }
234
+ const resolved = resolveValue(target.$value, doc, cache, new Set([...seen, targetPath]));
235
+ cache.set(targetPath, resolved);
236
+ return resolved;
237
+ }
238
+ // Composite ({ light, dark } color, typography sub-fields, shadow sub-fields).
239
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
240
+ const obj = raw;
241
+ const out = {};
242
+ for (const [k, v] of Object.entries(obj)) {
243
+ out[k] = resolveValue(v, doc, cache, seen);
244
+ }
245
+ return out;
246
+ }
247
+ return raw;
248
+ }
249
+ function lookupPath(doc, path) {
250
+ const parts = path.split(".");
251
+ let cur = doc;
252
+ for (const p of parts) {
253
+ if (cur === null || typeof cur !== "object")
254
+ return null;
255
+ cur = cur[p];
256
+ if (cur === undefined)
257
+ return null;
258
+ }
259
+ if (cur && typeof cur === "object" && "$value" in cur)
260
+ return cur;
261
+ return null;
262
+ }
263
+ // ────────────────────────────────────────────────────────────────────
264
+ // Per-category CSS emission
265
+ // ────────────────────────────────────────────────────────────────────
266
+ function emitTokenLines(category, path, value, lightLines, darkLines) {
267
+ // Strip the category prefix to get the rest of the path. e.g.
268
+ // `color.brand.primary` → `brand-primary` becomes `--color-brand-primary`.
269
+ //
270
+ // v0.11.1 (issue #76) — Tailwind/shadcn convention: a leaf at
271
+ // `<group>.DEFAULT` (e.g. the OKLCh ramp's `color.primary.DEFAULT`
272
+ // alias generated by deriveOklchPrimaryRamp) emits `--<category>-<group>`
273
+ // (NOT `--<category>-<group>-DEFAULT`) so module HTML using
274
+ // `var(--color-primary)` resolves to the brand color. Without this,
275
+ // the ramp's group emits `--color-primary-50` … `--color-primary-900`
276
+ // + `--color-primary-DEFAULT` but no bare `--color-primary` — and
277
+ // consumers fall back to the cascade. This special-case applies to
278
+ // every category (color/spacing/radius/etc.) so any future
279
+ // DTCG-group-with-DEFAULT-alias works the same way.
280
+ const restRaw = path.slice(category.length + 1);
281
+ const rest = restRaw.endsWith(".DEFAULT")
282
+ ? restRaw.slice(0, -".DEFAULT".length).replace(/\./g, "-")
283
+ : restRaw.replace(/\./g, "-");
284
+ const baseName = `--${category === "ease" ? "ease" : category}-${rest}`;
285
+ switch (category) {
286
+ case "color":
287
+ emitColor(baseName, value, lightLines, darkLines);
288
+ break;
289
+ case "typography":
290
+ emitTypography(rest, value, lightLines);
291
+ break;
292
+ case "spacing":
293
+ case "radius":
294
+ case "breakpoint":
295
+ emitSimple(baseName, value, lightLines);
296
+ break;
297
+ case "shadow":
298
+ emitShadow(baseName, value, lightLines);
299
+ break;
300
+ case "duration":
301
+ emitSimple(baseName, value, lightLines);
302
+ break;
303
+ case "ease":
304
+ emitEase(baseName, value, lightLines);
305
+ break;
306
+ case "gradient":
307
+ // issue #153 — first-class since v0.13: CSS gradient string →
308
+ // `--gradient-<name>` (value scrubbed by sanitizeCssTokenValue
309
+ // like every emitted token).
310
+ emitSimple(baseName, value, lightLines);
311
+ break;
312
+ default:
313
+ // Unknown category — emit as `--<category>-<rest>: <value>` so
314
+ // forward-compat tokens still appear in CSS rather than silently
315
+ // disappearing.
316
+ emitSimple(baseName, value, lightLines);
317
+ }
318
+ }
319
+ function emitColor(baseName, value, lightLines, darkLines) {
320
+ if (value && typeof value === "object" && "light" in value && "dark" in value) {
321
+ const both = value;
322
+ lightLines.push(`${baseName}:${asString(both.light)};`);
323
+ darkLines.push(`${baseName}:${asString(both.dark)};`);
324
+ return;
325
+ }
326
+ lightLines.push(`${baseName}:${asString(value)};`);
327
+ }
328
+ function emitTypography(rest, value, out) {
329
+ if (typeof value !== "object" || value === null) {
330
+ // Alias resolved to a scalar; emit on --font-<rest>.
331
+ out.push(`--font-${rest}:${asString(value)};`);
332
+ return;
333
+ }
334
+ const v = value;
335
+ if (v.fontFamily !== undefined)
336
+ out.push(`--font-${rest}:${asString(v.fontFamily)};`);
337
+ if (v.fontSize !== undefined)
338
+ out.push(`--text-${rest}:${asString(v.fontSize)};`);
339
+ if (v.fontWeight !== undefined)
340
+ out.push(`--font-weight-${rest}:${asString(v.fontWeight)};`);
341
+ if (v.lineHeight !== undefined)
342
+ out.push(`--leading-${rest}:${asString(v.lineHeight)};`);
343
+ if (v.letterSpacing !== undefined)
344
+ out.push(`--tracking-${rest}:${asString(v.letterSpacing)};`);
345
+ }
346
+ function emitShadow(baseName, value, out) {
347
+ // Literal CSS box-shadow string (the tolerant `shadowValueString` form).
348
+ // Emit verbatim — the DTCG object form is expanded below.
349
+ if (typeof value === "string") {
350
+ const s = value.trim();
351
+ if (s.length > 0)
352
+ out.push(`${baseName}:${s};`);
353
+ return;
354
+ }
355
+ if (Array.isArray(value)) {
356
+ // Layered shadow — join with comma so CSS receives multi-layer.
357
+ const layers = value
358
+ .map((layer) => shadowLayerToCss(layer))
359
+ .filter((s) => s !== null);
360
+ if (layers.length > 0)
361
+ out.push(`${baseName}:${layers.join(",")};`);
362
+ return;
363
+ }
364
+ const single = shadowLayerToCss(value);
365
+ if (single !== null)
366
+ out.push(`${baseName}:${single};`);
367
+ }
368
+ function shadowLayerToCss(layer) {
369
+ if (!layer || typeof layer !== "object")
370
+ return null;
371
+ const v = layer;
372
+ const x = asString(v.offsetX ?? "0");
373
+ const y = asString(v.offsetY ?? "0");
374
+ const blur = asString(v.blur ?? "0");
375
+ const spread = v.spread !== undefined ? ` ${asString(v.spread)}` : "";
376
+ const color = asString(v.color ?? "currentColor");
377
+ const inset = v.inset === true ? " inset" : "";
378
+ return `${x} ${y} ${blur}${spread} ${color}${inset}`;
379
+ }
380
+ function emitEase(baseName, value, out) {
381
+ if (Array.isArray(value) && value.length === 4) {
382
+ out.push(`${baseName}:cubic-bezier(${value.map((n) => asString(n)).join(", ")});`);
383
+ return;
384
+ }
385
+ out.push(`${baseName}:${asString(value)};`);
386
+ }
387
+ function emitSimple(baseName, value, out) {
388
+ out.push(`${baseName}:${asString(value)};`);
389
+ }
390
+ function asString(value) {
391
+ if (value === null || value === undefined)
392
+ return "";
393
+ if (typeof value === "string")
394
+ return sanitizeCssTokenValue(value);
395
+ if (typeof value === "number" || typeof value === "boolean")
396
+ return String(value);
397
+ return sanitizeCssTokenValue(JSON.stringify(value));
398
+ }
399
+ /**
400
+ * v0.11.0 fix (#45 review thread on theme-render.ts:207 — HIGH XSS) —
401
+ * scrub HTML-context escape sequences from a string that's about to
402
+ * be injected into a `<style>` block.
403
+ *
404
+ * CSS values are otherwise unrestricted in character set (font-family
405
+ * names legitimately contain quotes, commas, parens, hyphens), so we
406
+ * don't HTML-encode broadly — that would break perfectly-valid
407
+ * `font-family: "Segoe UI", sans-serif` declarations. Instead, scrub
408
+ * the two sequences that let an attacker break out of the surrounding
409
+ * `<style>…</style>` context:
410
+ *
411
+ * - `</style` (case-insensitive) — premature end-tag would close
412
+ * the style block and let everything after it parse as HTML
413
+ * (`fontFamily: "Inter</style><script>alert(1)</script>"`).
414
+ * - `<!--` / `-->` — CDO/CDC tokens; some HTML parsers treat them
415
+ * specially inside `<style>` and they're never valid in a real
416
+ * CSS value anyway.
417
+ *
418
+ * The themeColorToken / themeDimensionToken Zod regexes already
419
+ * constrain those token types to character sets that exclude `<`, so
420
+ * this scrub is the load-bearing defence for the free-form fields
421
+ * (`typography.X.fontFamily`, `$description` if it ever lands in CSS).
422
+ */
423
+ function sanitizeCssTokenValue(value) {
424
+ // Run to a fixed point: removing one sequence can re-create another
425
+ // (e.g. `<!--</style>-->` → `</style` only appears after the comment
426
+ // tokens go), which a single pass would leave behind (CodeQL
427
+ // js/incomplete-multi-character-sanitization). `--!>` is the HTML5
428
+ // alternative comment-close and must be scrubbed alongside `-->`
429
+ // (CodeQL js/bad-tag-filter).
430
+ let out = value;
431
+ let prev;
432
+ do {
433
+ prev = out;
434
+ out = out
435
+ .replace(/<\/style/gi, "")
436
+ .replace(/<!--/g, "")
437
+ .replace(/--!?>/g, "");
438
+ } while (out !== prev);
439
+ return out;
440
+ }
441
+ //# sourceMappingURL=theme-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-render.js","sourceRoot":"","sources":["../src/theme-render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Typed errors emitted by the theme primitive (#45, v0.11.0).
3
+ *
4
+ * Per CLAUDE.md §11 ("Failure surfaces are AI-actionable") every error
5
+ * includes the next step the AI should try inside `.message`. The ops
6
+ * layer wraps these as `err({kind:"HandlerError", message})`; the AI
7
+ * tool layer returns them in `content`. Inline classes (vs ad-hoc
8
+ * strings) so callers can `instanceof` to surface structured fields
9
+ * (suggestions, supported formats) to the UI / system-prompt later.
10
+ */
11
+ /**
12
+ * Loose token name could not be normalized to a canonical DTCG path.
13
+ * Carries the closest-match suggestions so the AI's next attempt has
14
+ * a concrete target.
15
+ */
16
+ export declare class UnknownTokenName extends Error {
17
+ readonly input: string;
18
+ readonly suggestions: readonly string[];
19
+ constructor(input: string, suggestions: readonly string[]);
20
+ }
21
+ /**
22
+ * Value supplied for a color token isn't in a supported CSS color
23
+ * format. The message names every format we accept so the AI's retry
24
+ * lands.
25
+ */
26
+ export declare class InvalidColorValue extends Error {
27
+ readonly input: string;
28
+ readonly supportedFormats: readonly string[];
29
+ constructor(input: string);
30
+ }
31
+ /**
32
+ * v0.11.0 (#45 opt §2) — `themes.import_dtcg` was handed a JSON body
33
+ * whose shape doesn't look like DTCG (no `$value` anywhere in the
34
+ * tree). v0.11.1 (issue #76) — auto-detect chain uses this as a
35
+ * "fall through to next importer" signal; only surfaces verbatim when
36
+ * the caller explicitly picked the DTCG importer.
37
+ */
38
+ export declare class NotDtcgShape extends Error {
39
+ constructor(message?: string);
40
+ }
41
+ /**
42
+ * v0.11.1 (issue #76) — Style Dictionary importer rejected input.
43
+ * Used as a fall-through signal by the auto-detect chain.
44
+ */
45
+ export declare class NotStyleDictionaryShape extends Error {
46
+ constructor(message?: string);
47
+ }
48
+ /**
49
+ * v0.11.1 (issue #76) — Tailwind 4 `@theme { … }` importer rejected
50
+ * input. Either no `@theme` block found, or the body contained a
51
+ * construct the line-by-line parser can't handle (calc(), nested
52
+ * at-rules). Auto-detect chain catches it and falls through.
53
+ */
54
+ export declare class NotTailwindShape extends Error {
55
+ constructor(message?: string);
56
+ }
57
+ /**
58
+ * v0.11.1 (issue #76) — Tailwind 4 importer hit a construct it can't
59
+ * parse (e.g. `calc(…)` values, nested at-rules). Surfaced verbatim
60
+ * by the auto-detect chain since the input WAS Tailwind-shaped — the
61
+ * caller should simplify or pre-resolve.
62
+ */
63
+ export declare class TailwindImportError extends Error {
64
+ readonly construct: string;
65
+ constructor(construct: string, line: string);
66
+ }
67
+ /**
68
+ * v0.11.1 (issue #76) — shadcn `:root { … }` importer rejected input
69
+ * (no `:root` selector found, or values were wrapped in `{value: …}`
70
+ * style-dictionary shape). Auto-detect chain falls through.
71
+ */
72
+ export declare class NotShadcnShape extends Error {
73
+ constructor(message?: string);
74
+ }
75
+ /**
76
+ * v0.11.1 (issue #76) — loose JSON-object importer rejected input
77
+ * (not a JSON object, or contains `$value` / `value` leaves that
78
+ * belong to a different format). Auto-detect chain falls through.
79
+ */
80
+ export declare class NotLooseShape extends Error {
81
+ constructor(message?: string);
82
+ }
83
+ /**
84
+ * v0.11.1 (issue #76) — auto-detect chain ran every importer and none
85
+ * accepted the input. Carries per-format rejection reasons so the AI's
86
+ * next turn can fix the input or fall back to `set_theme_tokens`.
87
+ */
88
+ export declare class NoImporterMatched extends Error {
89
+ readonly attempts: ReadonlyArray<{
90
+ format: string;
91
+ reason: string;
92
+ }>;
93
+ constructor(attempts: ReadonlyArray<{
94
+ format: string;
95
+ reason: string;
96
+ }>);
97
+ }
98
+ /**
99
+ * Loose-name input resolved to a canonical path but the value's
100
+ * inferred category doesn't match the category for that path
101
+ * (e.g. caller put a `0.5rem` value at `color.primary`).
102
+ */
103
+ export declare class TokenCategoryMismatch extends Error {
104
+ readonly canonicalPath: string;
105
+ readonly expected: string;
106
+ readonly got: string;
107
+ constructor(canonicalPath: string, expected: string, got: string);
108
+ }
109
+ //# sourceMappingURL=themes-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themes-errors.d.ts","sourceRoot":"","sources":["../src/themes-errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;gBAC5B,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE;CAU1D;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAO1C;gBACU,KAAK,EAAE,MAAM;CAY1B;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,CAAC,EAAE,MAAM;CAS7B;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,CAAC,EAAE,MAAM;CAS7B;AAED;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,CAAC,EAAE,MAAM;CAQ7B;AAED;;;;;GAKG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBACf,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAQ5C;AAED;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,CAAC,EAAE,MAAM;CAQ7B;AAED;;;;GAIG;AACH,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,CAAC,EAAE,MAAM;CAM7B;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBACzD,QAAQ,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CASxE;AAED;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBACT,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CASjE"}