@nanisoft/prism-llms 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +88 -0
  2. package/THIRD-PARTY-NOTICES.md +48 -0
  3. package/dist/data.json +3996 -387
  4. package/dist/demo-graph.d.ts +21 -12
  5. package/dist/demo-graph.js +37 -21
  6. package/dist/extractor.d.ts +24 -17
  7. package/dist/extractor.js +269 -153
  8. package/dist/index.d.ts +12 -7
  9. package/dist/index.js +9 -7
  10. package/dist/llms-full.txt +7968 -2013
  11. package/dist/llms.txt +97 -93
  12. package/dist/markdown.d.ts +69 -23
  13. package/dist/markdown.js +131 -72
  14. package/dist/md/blocks/app-shell-01.md +135 -0
  15. package/dist/md/blocks/auth-form-01.md +135 -0
  16. package/dist/md/blocks/cta-01.md +88 -0
  17. package/dist/md/blocks/data-table-01.md +196 -0
  18. package/dist/md/blocks/feature-grid-01.md +92 -0
  19. package/dist/md/blocks/hero-01.md +90 -0
  20. package/dist/md/blocks/instrument-panel-01.md +109 -0
  21. package/dist/md/blocks/logo-strip-01.md +97 -0
  22. package/dist/md/blocks/note-grid-01.md +102 -0
  23. package/dist/md/blocks/page-header-01.md +97 -0
  24. package/dist/md/blocks/pricing-01.md +91 -0
  25. package/dist/md/blocks/process-rail-01.md +106 -0
  26. package/dist/md/blocks/product-grid-01.md +113 -0
  27. package/dist/md/blocks/settings-panel-01.md +148 -0
  28. package/dist/md/blocks/site-footer.md +103 -11
  29. package/dist/md/blocks/site-header.md +111 -11
  30. package/dist/md/blocks/stack-grid-01.md +108 -0
  31. package/dist/md/blocks/stats-01.md +89 -0
  32. package/dist/md/blocks/status-ledger-01.md +121 -0
  33. package/dist/md/changelogs/prism-llms.md +206 -0
  34. package/dist/md/changelogs/prism-mcp-server.md +88 -0
  35. package/dist/md/changelogs/prism-tokens.md +126 -0
  36. package/dist/md/changelogs/prism-ui.md +429 -0
  37. package/dist/md/components/accordion.md +108 -0
  38. package/dist/md/components/alert.md +90 -7
  39. package/dist/md/components/avatar.md +89 -7
  40. package/dist/md/components/badge.md +74 -7
  41. package/dist/md/components/breadcrumb.md +84 -7
  42. package/dist/md/components/button.md +90 -7
  43. package/dist/md/components/card.md +90 -7
  44. package/dist/md/components/checkbox.md +101 -7
  45. package/dist/md/components/cta-link.md +98 -0
  46. package/dist/md/components/diagram.md +124 -0
  47. package/dist/md/components/dialog.md +128 -0
  48. package/dist/md/components/dropdown-menu.md +125 -0
  49. package/dist/md/components/fact-list.md +85 -0
  50. package/dist/md/components/field.md +116 -0
  51. package/dist/md/components/input.md +86 -7
  52. package/dist/md/components/kbd.md +77 -0
  53. package/dist/md/components/pagination.md +95 -7
  54. package/dist/md/components/popover.md +95 -7
  55. package/dist/md/components/product-mark.md +123 -0
  56. package/dist/md/components/product-switcher.md +88 -0
  57. package/dist/md/components/progress.md +88 -7
  58. package/dist/md/components/prose.md +91 -0
  59. package/dist/md/components/radio-group.md +111 -0
  60. package/dist/md/components/section.md +91 -0
  61. package/dist/md/components/select.md +143 -7
  62. package/dist/md/components/separator.md +77 -0
  63. package/dist/md/components/skeleton.md +71 -7
  64. package/dist/md/components/slider.md +90 -7
  65. package/dist/md/components/switch.md +104 -7
  66. package/dist/md/components/table.md +104 -7
  67. package/dist/md/components/tabs.md +105 -7
  68. package/dist/md/components/textarea.md +101 -0
  69. package/dist/md/components/tooltip.md +95 -7
  70. package/dist/md/components/typography.md +82 -7
  71. package/dist/md/content/about-content.md +36 -0
  72. package/dist/md/content/audience.md +43 -0
  73. package/dist/md/content/glossary.md +69 -0
  74. package/dist/md/content/product-vocabulary.md +53 -0
  75. package/dist/md/content/voice.md +52 -0
  76. package/dist/md/content/writing-mechanics.md +58 -0
  77. package/dist/md/foundation/colors.md +10 -0
  78. package/dist/md/foundation/iconography.md +14 -0
  79. package/dist/md/foundation/motion.md +10 -0
  80. package/dist/md/foundation/radii.md +9 -0
  81. package/dist/md/foundation/shadows.md +9 -0
  82. package/dist/md/foundation/spacings.md +8 -0
  83. package/dist/md/foundation/typography.md +9 -0
  84. package/dist/md/foundation/variables.md +9 -0
  85. package/dist/md/overview/architecture.md +76 -0
  86. package/dist/md/overview/brand.md +41 -0
  87. package/dist/md/overview/composition.md +77 -0
  88. package/dist/md/overview/quickstart.md +97 -0
  89. package/dist/md/overview/theming.md +89 -0
  90. package/dist/md/overview/using-llms.md +83 -0
  91. package/dist/md/pages/auth-page.md +149 -0
  92. package/dist/md/pages/blog-post-page.md +136 -0
  93. package/dist/md/pages/dashboard-page.md +241 -0
  94. package/dist/md/pages/marketing-page.md +199 -0
  95. package/dist/md/pages/not-found-page.md +105 -0
  96. package/dist/md/pages/settings-page.md +206 -0
  97. package/dist/prism-skill.md +50 -0
  98. package/dist/store.d.ts +203 -0
  99. package/dist/store.js +317 -0
  100. package/package.json +29 -26
  101. package/dist/demo-graph.d.ts.map +0 -1
  102. package/dist/demo-graph.js.map +0 -1
  103. package/dist/extractor.d.ts.map +0 -1
  104. package/dist/extractor.js.map +0 -1
  105. package/dist/index.d.ts.map +0 -1
  106. package/dist/index.js.map +0 -1
  107. package/dist/markdown.d.ts.map +0 -1
  108. package/dist/markdown.js.map +0 -1
  109. package/dist/md/blocks/component-demo.md +0 -19
  110. package/dist/md/blocks/page-header.md +0 -19
  111. package/dist/md/components/affix.md +0 -14
  112. package/dist/md/components/anchor.md +0 -14
  113. package/dist/md/components/auto-complete.md +0 -14
  114. package/dist/md/components/back-top.md +0 -14
  115. package/dist/md/components/border-beam.md +0 -14
  116. package/dist/md/components/calendar.md +0 -14
  117. package/dist/md/components/carousel.md +0 -14
  118. package/dist/md/components/cascader.md +0 -14
  119. package/dist/md/components/col.md +0 -14
  120. package/dist/md/components/collapse.md +0 -14
  121. package/dist/md/components/color-picker.md +0 -14
  122. package/dist/md/components/date-picker.md +0 -14
  123. package/dist/md/components/descriptions.md +0 -14
  124. package/dist/md/components/display-title.md +0 -20
  125. package/dist/md/components/divider.md +0 -14
  126. package/dist/md/components/drawer.md +0 -14
  127. package/dist/md/components/dropdown.md +0 -14
  128. package/dist/md/components/empty.md +0 -14
  129. package/dist/md/components/flex.md +0 -14
  130. package/dist/md/components/float-button.md +0 -14
  131. package/dist/md/components/form.md +0 -14
  132. package/dist/md/components/grid.md +0 -14
  133. package/dist/md/components/image.md +0 -14
  134. package/dist/md/components/input-number.md +0 -14
  135. package/dist/md/components/layout.md +0 -14
  136. package/dist/md/components/list.md +0 -14
  137. package/dist/md/components/listy.md +0 -14
  138. package/dist/md/components/masonry.md +0 -14
  139. package/dist/md/components/mentions.md +0 -14
  140. package/dist/md/components/menu.md +0 -14
  141. package/dist/md/components/modal.md +0 -14
  142. package/dist/md/components/popconfirm.md +0 -14
  143. package/dist/md/components/qrcode.md +0 -14
  144. package/dist/md/components/radio.md +0 -14
  145. package/dist/md/components/rate.md +0 -14
  146. package/dist/md/components/result.md +0 -14
  147. package/dist/md/components/row.md +0 -14
  148. package/dist/md/components/segmented.md +0 -14
  149. package/dist/md/components/space.md +0 -14
  150. package/dist/md/components/spin.md +0 -14
  151. package/dist/md/components/splitter.md +0 -14
  152. package/dist/md/components/statistic.md +0 -14
  153. package/dist/md/components/steps.md +0 -14
  154. package/dist/md/components/tag.md +0 -14
  155. package/dist/md/components/time-picker.md +0 -14
  156. package/dist/md/components/timeline.md +0 -14
  157. package/dist/md/components/tour.md +0 -14
  158. package/dist/md/components/transfer.md +0 -14
  159. package/dist/md/components/tree-select.md +0 -14
  160. package/dist/md/components/tree.md +0 -14
  161. package/dist/md/components/upload.md +0 -14
  162. package/dist/md/components/watermark.md +0 -14
  163. package/dist/md/docs/brand.md +0 -41
  164. package/dist/md/pages/blog-layout.md +0 -19
  165. package/dist/md/pages/docs-shell.md +0 -23
  166. package/dist/md/theme/blue-dark.md +0 -127
  167. package/dist/md/theme/blue-light.md +0 -129
  168. package/dist/md/theme/green-dark.md +0 -127
  169. package/dist/md/theme/green-light.md +0 -129
  170. package/dist/md/theme/lavender-dark.md +0 -127
  171. package/dist/md/theme/lavender-light.md +0 -129
  172. package/dist/md/theme/peach-dark.md +0 -127
  173. package/dist/md/theme/peach-light.md +0 -129
  174. package/dist/md/theme/rose-dark.md +0 -127
  175. package/dist/md/theme/rose-light.md +0 -129
package/dist/extractor.js CHANGED
@@ -1,42 +1,70 @@
1
1
  /**
2
- * The one props extractor (tickets 12/16): reads prism-ui's built `.d.ts`
3
- * surface — TSDoc preserved — and returns the Prism-added props. Homed here
4
- * and exported (`@nanisoft/prism-llms/extractor`) for the site's API tables;
5
- * one extractor, two consumers. Runs after `^build`, so it reads declarations,
6
- * never TS source.
2
+ * The one props extractor.
7
3
  *
8
- * Deliberately compiler-API-free: TypeScript 7 (this repo's compiler) no
9
- * longer ships the JS compiler API, and ADR-0003 already accepts cosmetic
10
- * fidelity risk on gnarly unions. This is a small structural scanner for the
11
- * declaration shape prism-ui emits — `export interface XProps [extends Y]`
12
- * with JSDoc-carried descriptions. Pass-through re-exports never match, and
13
- * that absence IS the Extends seam (ADR-0004): no extracted props means the
14
- * item is "antd X, unchanged".
15
- */
16
- /**
17
- * Extract every exported `*Props` interface from a `.d.ts` source, in source
18
- * order. Returns an empty array for re-export-only files (pass-throughs).
4
+ * It reads `@nanisoft/prism-ui`'s emitted declarations, never its TypeScript
5
+ * source, and it is deliberately compiler-API-free: a small structural scanner
6
+ * for the declaration shapes this repository emits. Ticket 12 section 2 fixes
7
+ * the seam at the emitted `.d.ts`, so a compiler bump cannot break the corpus.
8
+ *
9
+ * The shapes it understands:
10
+ * - a named props type (`export type XProps = { ... }` or
11
+ * `export interface XProps extends Y { ... }`), referenced by a function;
12
+ * - an inline props object on the function parameter;
13
+ * - `ComponentProps<'tag'>`, recorded as an inherited base rather than
14
+ * expanded, so a native-backed component reports its element;
15
+ * - `VariantProps<typeof recipe>`, expanded from the emitted `cva` declaration
16
+ * into the recipe's `variant` and `size` rows.
17
+ *
18
+ * One extractor, two renderers: the corpus's `## Props` definition list and the
19
+ * site's API reference table. There is no second extraction.
19
20
  */
21
+ function toProp(row) {
22
+ return {
23
+ name: row.name,
24
+ typeText: row.type.replace(/\s+/g, ' ').trim(),
25
+ required: row.required,
26
+ ...(row.description ? { description: row.description } : {}),
27
+ ...(row.default && row.default !== '-' ? { defaultValue: row.default } : {}),
28
+ };
29
+ }
30
+ /** Extract every exported `*Props` interface from a declaration, in source order. */
20
31
  export function extractProps(source) {
21
32
  const results = [];
22
- const interfacePattern = /export\s+interface\s+(\w+)(?:\s+extends\s+([\w.]+))?\s*\{/g;
33
+ const pattern = /export\s+interface\s+(\w+)(?:\s+extends\s+([^{}]+?))?\s*\{/g;
23
34
  let match;
24
- while ((match = interfacePattern.exec(source)) !== null) {
35
+ while ((match = pattern.exec(source)) !== null) {
25
36
  if (!(match[1] ?? '').endsWith('Props'))
26
- continue; // supporting types (DocsNavEntry, BlogFrontmatter) are not props
27
- const openBrace = interfacePattern.lastIndex - 1;
37
+ continue;
38
+ const openBrace = pattern.lastIndex - 1;
28
39
  const body = readBalancedBody(source, openBrace);
29
40
  if (body === undefined)
30
- continue; // unbalanced — skip rather than guess
41
+ continue;
31
42
  results.push({
32
43
  typeName: match[1] ?? '',
33
- extendsType: match[2],
34
- props: parseProps(body),
44
+ ...(match[2] ? { extendsType: match[2].trim() } : {}),
45
+ props: parseMembers(body).map(toProp),
35
46
  });
36
47
  }
37
48
  return results;
38
49
  }
39
- /** The `{…}` body of the declaration whose brace sits at `openBrace`, or undefined when unbalanced. */
50
+ /**
51
+ * Extract the props of the named exports from one declaration file's text.
52
+ * Exports with no declaration are reported with an empty prop list.
53
+ */
54
+ export function extractExports(source, exportNames) {
55
+ return exportNames.map((name) => {
56
+ const params = findFunctionParams(source, name);
57
+ if (params === null)
58
+ return { typeName: name, props: [] };
59
+ const { props, inherited } = resolveAnnotation(annotationOf(params), source);
60
+ return {
61
+ typeName: name,
62
+ ...(inherited.length > 0 ? { extendsType: inherited.join(' & ') } : {}),
63
+ props,
64
+ };
65
+ });
66
+ }
67
+ /** The `{...}` body of the declaration whose brace sits at `openBrace`. */
40
68
  function readBalancedBody(source, openBrace) {
41
69
  let depth = 0;
42
70
  let i = openBrace;
@@ -86,158 +114,246 @@ function skipString(source, start, quote) {
86
114
  }
87
115
  return -1;
88
116
  }
89
- /** Parse property signatures out of an interface body. Non-signature members (methods, indexers) are skipped. */
90
- function parseProps(body) {
91
- const props = [];
92
- let i = 0;
93
- let pendingDocs;
94
- while (i < body.length) {
95
- const trivia = skipTrivia(body, i);
96
- i = trivia.next;
97
- pendingDocs = trivia.jsDoc ?? pendingDocs;
98
- if (i >= body.length)
99
- break;
100
- const nameMatch = /^([\w$]+)(\?)?\s*:/.exec(body.slice(i));
101
- if (!nameMatch) {
102
- // Not a property signature (call/construct/index signature, stray token) —
103
- // skip to the next statement boundary at depth 0.
104
- const boundary = nextTopLevelBoundary(body, i);
105
- if (boundary === -1)
106
- break;
107
- pendingDocs = undefined;
108
- i = boundary;
109
- continue;
110
- }
111
- const typeStart = i + nameMatch[0].length;
112
- const typeEnd = nextTopLevelBoundary(body, typeStart);
113
- const rawType = typeEnd === -1 ? body.slice(typeStart) : body.slice(typeStart, typeEnd);
114
- props.push({
115
- name: nameMatch[1] ?? '',
116
- typeText: normalizeType(rawType),
117
- description: pendingDocs?.description,
118
- defaultValue: pendingDocs?.defaultValue,
119
- required: !nameMatch[2],
120
- });
121
- pendingDocs = undefined;
122
- if (typeEnd === -1)
123
- break;
124
- i = typeEnd + 1;
125
- }
126
- return props;
127
- }
128
117
  /**
129
- * Advance past whitespace/comments. `/**` comments are captured as JSDoc
130
- * (description + `@defaultValue`), merged across consecutive blocks.
118
+ * Every object body a named type's declaration holds, in source order.
119
+ *
120
+ * A union is published whole or not at all. The single-body form this replaces
121
+ * took the FIRST match and the first balanced body, so it published one body and
122
+ * dropped every other by declaration order. For an emitted declaration shaped
123
+ * `Common & ({ A } | { B })` it published neither arm at all, only the shared
124
+ * part, so the API table described a type the declaration does not describe: the
125
+ * `bare` arm of a union was invisible to every reader and every agent. A
126
+ * type-level truth the extractor drops becomes a documentation-level lie, so the
127
+ * scan walks every balanced body inside the declaration's own extent instead.
128
+ *
129
+ * The depth and angle tracking is load-bearing rather than defensive. A member
130
+ * semicolon sits at depth 1, so a scan that stopped on the first `;` would end
131
+ * the declaration at `variant?: 'icon';` and never reach the second arm, which
132
+ * is the defect this function exists to remove. Angle brackets are tracked
133
+ * because a generic argument can carry its own braces.
131
134
  */
132
- function skipTrivia(source, start) {
133
- let i = start;
134
- let jsDoc;
135
- while (i < source.length) {
136
- const ch = source[i] ?? '';
137
- if (/\s/.test(ch)) {
138
- i += 1;
139
- continue;
140
- }
141
- if (ch === '/' && source[i + 1] === '*' && source[i + 2] === '*') {
142
- const close = source.indexOf('*/', i + 3);
143
- if (close === -1)
144
- return { next: source.length };
145
- // Consecutive JSDoc blocks merge — a description and a @defaultValue may
146
- // live in separate blocks (tsc emits one, hand-written d.ts may not).
147
- const parsed = readJsDoc(source.slice(i + 3, close));
148
- if (parsed) {
149
- jsDoc = {
150
- description: jsDoc?.description ?? parsed.description,
151
- defaultValue: jsDoc?.defaultValue ?? parsed.defaultValue,
152
- };
153
- }
154
- i = close + 2;
135
+ function findTypeBodies(source, name) {
136
+ const pattern = new RegExp(`(?:export\\s+)?(?:type|interface)\\s+${name}\\b`);
137
+ const match = pattern.exec(source);
138
+ if (!match)
139
+ return [];
140
+ const bodies = [];
141
+ let depth = 0;
142
+ let angle = 0;
143
+ let quote = null;
144
+ let i = match.index + match[0].length;
145
+ for (; i < source.length; i += 1) {
146
+ const ch = source[i];
147
+ if (quote !== null) {
148
+ if (ch === quote && source[i - 1] !== '\\')
149
+ quote = null;
155
150
  continue;
156
151
  }
157
- if (ch === '/' && source[i + 1] === '*') {
158
- const close = source.indexOf('*/', i + 2);
159
- if (close === -1)
160
- return { next: source.length };
161
- i = close + 2;
152
+ if (ch === '"' || ch === "'" || ch === '`') {
153
+ quote = ch;
162
154
  continue;
163
155
  }
164
- if (ch === '/' && source[i + 1] === '/') {
165
- const close = source.indexOf('\n', i);
166
- if (close === -1)
167
- return { next: source.length };
168
- i = close;
156
+ if (ch === '{') {
157
+ const body = readBalancedBody(source, i);
158
+ if (body === undefined)
159
+ return bodies;
160
+ bodies.push(body);
161
+ depth += 1;
169
162
  continue;
170
163
  }
171
- return { next: i, jsDoc };
164
+ if (ch === '}')
165
+ depth -= 1;
166
+ else if (ch === '(')
167
+ depth += 1;
168
+ else if (ch === ')')
169
+ depth -= 1;
170
+ else if (ch === '<')
171
+ angle += 1;
172
+ else if (ch === '>')
173
+ angle = Math.max(0, angle - 1);
174
+ // The declaration ends at the first terminator that closes nothing it
175
+ // opened, so the next declaration's braces cannot be collected as arms.
176
+ else if ((ch === ';' || ch === '\n') && depth <= 0 && angle === 0)
177
+ return bodies;
172
178
  }
173
- return { next: i, jsDoc };
179
+ return bodies;
174
180
  }
175
- function readJsDoc(text) {
176
- const lines = text
177
- .split('\n')
178
- .map((line) => line.replace(/^\s*\*/, '').trim());
179
- const description = [];
180
- let defaultValue;
181
- for (const line of lines) {
182
- if (!line) {
183
- if (description.length > 0)
184
- description.push('');
185
- continue;
186
- }
187
- const tag = /^@(\w+)\s*(.*)$/.exec(line);
188
- if (tag) {
189
- if (tag[1] === 'defaultValue')
190
- defaultValue = tag[2] || undefined;
191
- continue; // other tags (@example, @internal, …) stay out of the docs
192
- }
193
- description.push(line);
181
+ function findFunctionParams(source, name) {
182
+ const pattern = new RegExp(`declare\\s+function\\s+${name}\\s*\\(`);
183
+ const match = pattern.exec(source);
184
+ if (!match)
185
+ return null;
186
+ const start = match.index + match[0].length;
187
+ let depth = 1;
188
+ let quote = null;
189
+ let i = start;
190
+ for (; i < source.length; i += 1) {
191
+ const ch = source[i];
192
+ if (quote) {
193
+ if (ch === quote && source[i - 1] !== '\\')
194
+ quote = null;
195
+ continue;
196
+ }
197
+ if (ch === '"' || ch === "'" || ch === '`')
198
+ quote = ch;
199
+ else if (ch === '(')
200
+ depth += 1;
201
+ else if (ch === ')') {
202
+ depth -= 1;
203
+ if (depth === 0)
204
+ break;
205
+ }
194
206
  }
195
- const joined = description.join(' ').trim();
196
- if (!joined && !defaultValue)
197
- return undefined;
198
- return { description: joined || undefined, defaultValue };
207
+ return source.slice(start, i);
199
208
  }
200
- /** Index of the next `;` or `,` at bracket depth 0 (starting at `from`), or -1. */
201
- function nextTopLevelBoundary(source, from) {
209
+ function annotationOf(params) {
202
210
  let depth = 0;
203
- let i = from;
204
- while (i < source.length) {
205
- const ch = source[i];
206
- if (ch === '/' && source[i + 1] === '*') {
207
- const close = source.indexOf('*/', i + 2);
208
- if (close === -1)
209
- return -1;
210
- i = close + 2;
211
+ let angle = 0;
212
+ let quote = null;
213
+ for (let i = 0; i < params.length; i += 1) {
214
+ const ch = params[i];
215
+ if (quote) {
216
+ if (ch === quote && params[i - 1] !== '\\')
217
+ quote = null;
211
218
  continue;
212
219
  }
213
- if (ch === '/' && source[i + 1] === '/') {
214
- const close = source.indexOf('\n', i);
215
- if (close === -1)
216
- return -1;
217
- i = close;
220
+ if (ch === '"' || ch === "'" || ch === '`')
221
+ quote = ch;
222
+ else if (ch === '(' || ch === '{' || ch === '[')
223
+ depth += 1;
224
+ else if (ch === ')' || ch === '}' || ch === ']')
225
+ depth -= 1;
226
+ else if (ch === '<')
227
+ angle += 1;
228
+ else if (ch === '>')
229
+ angle = Math.max(0, angle - 1);
230
+ else if (ch === ':' && depth === 0 && angle === 0)
231
+ return params.slice(i + 1).trim();
232
+ }
233
+ return null;
234
+ }
235
+ function variantRows(source, recipeName) {
236
+ const pattern = new RegExp(`declare const ${recipeName}\\s*:\\s*\\(props\\?:\\s*\\(\\{([\\s\\S]*?)\\}\\s*&`);
237
+ const match = pattern.exec(source);
238
+ return match ? parseMembers(match[1] ?? '') : [];
239
+ }
240
+ function resolveAnnotation(annotation, source) {
241
+ if (!annotation)
242
+ return { props: [], inherited: [] };
243
+ const named = /^[A-Za-z_$][\w$]*$/.test(annotation) ? findTypeBodies(source, annotation) : [];
244
+ if (named.length > 0) {
245
+ // Every arm, in declaration order, so a union reaches the table whole
246
+ // rather than as whichever arm happened to be written first.
247
+ return { props: named.flatMap((body) => parseMembers(body)).map(toProp), inherited: [] };
248
+ }
249
+ if (annotation.startsWith('{')) {
250
+ const body = readBalancedBody(annotation, 0);
251
+ if (body !== undefined)
252
+ return { props: parseMembers(body).map(toProp), inherited: [] };
253
+ }
254
+ const props = [];
255
+ const inherited = [];
256
+ const recipe = /VariantProps<typeof (\w+)>/.exec(annotation);
257
+ if (recipe)
258
+ props.push(...variantRows(source, recipe[1] ?? '').map(toProp));
259
+ const componentProps = /ComponentProps<'([^']+)'>/.exec(annotation);
260
+ if (componentProps)
261
+ inherited.push(`React.ComponentProps<'${componentProps[1]}'>`);
262
+ if (props.length === 0 && inherited.length === 0) {
263
+ inherited.push(annotation.replace(/\s+/g, ' ').slice(0, 200));
264
+ }
265
+ return { props, inherited };
266
+ }
267
+ function splitTopLevel(body) {
268
+ const parts = [];
269
+ let depth = 0;
270
+ let angle = 0;
271
+ let quote = null;
272
+ let current = '';
273
+ for (let i = 0; i < body.length; i += 1) {
274
+ const ch = body[i];
275
+ if (!quote && ch === '/' && body[i + 1] === '*') {
276
+ const end = body.indexOf('*/', i + 2);
277
+ const stop = end < 0 ? body.length : end + 2;
278
+ current += body.slice(i, stop);
279
+ i = stop - 1;
280
+ continue;
281
+ }
282
+ if (!quote && ch === '/' && body[i + 1] === '/') {
283
+ const end = body.indexOf('\n', i + 2);
284
+ const stop = end < 0 ? body.length : end;
285
+ current += body.slice(i, stop);
286
+ i = stop - 1;
287
+ continue;
288
+ }
289
+ if (quote) {
290
+ current += ch;
291
+ if (ch === quote && body[i - 1] !== '\\')
292
+ quote = null;
218
293
  continue;
219
294
  }
220
295
  if (ch === '"' || ch === "'" || ch === '`') {
221
- i = skipString(source, i, ch);
222
- if (i === -1)
223
- return -1;
296
+ quote = ch;
297
+ current += ch;
224
298
  continue;
225
299
  }
226
- if (ch === '(' || ch === '[' || ch === '{' || ch === '<')
300
+ if (ch === '(' || ch === '{' || ch === '[')
227
301
  depth += 1;
228
- if (ch === ')' || ch === ']' || ch === '}' || ch === '>')
302
+ else if (ch === ')' || ch === '}' || ch === ']')
229
303
  depth -= 1;
230
- if (depth === 0 && (ch === ';' || ch === ','))
231
- return i;
232
- i += 1;
304
+ else if (ch === '<')
305
+ angle += 1;
306
+ else if (ch === '>')
307
+ angle = Math.max(0, angle - 1);
308
+ if (ch === ';' && depth <= 0 && angle === 0) {
309
+ parts.push(current);
310
+ current = '';
311
+ continue;
312
+ }
313
+ current += ch;
233
314
  }
234
- return -1;
315
+ if (current.trim())
316
+ parts.push(current);
317
+ return parts;
235
318
  }
236
- /** Collapse comments and newlines to single spaces — readable, verbatim type text. */
237
- function normalizeType(raw) {
238
- return raw
239
- .replace(/\/\*[\s\S]*?\*\//g, ' ')
240
- .replace(/\s+/g, ' ')
319
+ function parseJsdoc(text) {
320
+ const match = /\/\*\*([\s\S]*?)\*\//.exec(text);
321
+ if (!match)
322
+ return { description: '', defaultValue: '' };
323
+ let content = match[1] ?? '';
324
+ let defaultValue = '';
325
+ const tag = /@defaultValue\s+([^\s*]+)/.exec(content);
326
+ if (tag) {
327
+ defaultValue = tag[1] ?? '';
328
+ content = content.replace(tag[0], ' ');
329
+ }
330
+ const description = content
331
+ .split('\n')
332
+ .map((line) => line.replace(/^\s*\*?\s?/, '').trim())
333
+ .filter((line) => line && !line.startsWith('@'))
334
+ .join(' ')
241
335
  .trim();
336
+ return { description, defaultValue };
337
+ }
338
+ function parseMembers(body) {
339
+ const rows = [];
340
+ for (const part of splitTopLevel(body)) {
341
+ const trimmed = part.trim();
342
+ if (!trimmed)
343
+ continue;
344
+ const comment = /\/\*\*([\s\S]*?)\*\//.exec(trimmed);
345
+ const rest = comment ? trimmed.slice(comment.index + comment[0].length) : trimmed;
346
+ const { description, defaultValue } = parseJsdoc(trimmed);
347
+ const member = /^([A-Za-z_$][\w$]*)\s*(\?)?\s*:\s*([\s\S]+)$/.exec(rest.trim());
348
+ if (!member)
349
+ continue;
350
+ rows.push({
351
+ name: member[1] ?? '',
352
+ type: (member[3] ?? '').replace(/;\s*$/, '').trim(),
353
+ required: !member[2],
354
+ default: defaultValue || '-',
355
+ description,
356
+ });
357
+ }
358
+ return rows;
242
359
  }
243
- //# sourceMappingURL=extractor.js.map
package/dist/index.d.ts CHANGED
@@ -1,10 +1,15 @@
1
1
  /**
2
- * prism-llms public surface. The root stays compiler-free (the extractor sits
3
- * behind `./extractor`); what ships here is the Markdown lane every consumer
4
- * of the corpus shares — the site's stub/API tooling imports these helpers so
5
- * it renders exactly what the generator emits.
2
+ * prism-llms public surface.
3
+ *
4
+ * The store contract is exported from the root; the extractor sits behind the
5
+ * `./extractor` subpath and is shared with the site's API reference table. The
6
+ * Markdown lane and the demo contract ship so a consumer renders exactly what
7
+ * the generator emits.
6
8
  */
7
- export { parseMdx, fence, renderComponentDemos, stripMdxMechanics, renderTable, renderPropsSection, type DocMeta, type ParsedMdx, } from './markdown.js';
9
+ export { parsePrismDocsStore, STORE_CATEGORIES, STORE_KINDS, STORE_MODES, STORE_PACKS, STORE_SCALE_GROUPS, STORE_SECTIONS, STORE_SECTION_TITLES, STORE_STATUSES, } from './store.js';
10
+ export type { Mode, PackId, PrismChangelog, PrismChangelogRelease, PrismDocsExample, PrismDocsPage, PrismDocsStore, PrismDocsStoreEntry, PrismScaleGroup, PrismScaleToken, PrismSemanticToken, PrismThemeTokens, PrismTokensProjection, StoreKind, StoreSection, StoreStatus, TokenGroup, } from './store.js';
11
+ export { assembleDoc, demoTitle, fence, parseMdx, parsePropLine, renderCompositionSection, renderCrossReferences, renderDemoSection, renderPropLine, renderPropsBody, renderPropsSection, stripMdxMechanics, stripSection, } from './markdown.js';
12
+ export type { CompositionField, CrossReference, DocMeta, ParsedMdx, ParsedPropLine, } from './markdown.js';
8
13
  export type { ExtractedInterface, ExtractedProp } from './extractor.js';
9
- export { scanPrismImports, validateDemoSource, type DemoViolation } from './demo-graph.js';
10
- //# sourceMappingURL=index.d.ts.map
14
+ export { scanPrismImports, scanPrismImportsWithSource, validateDemoSource, } from './demo-graph.js';
15
+ export type { DemoViolation, PrismImport } from './demo-graph.js';
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  /**
2
- * prism-llms public surface. The root stays compiler-free (the extractor sits
3
- * behind `./extractor`); what ships here is the Markdown lane every consumer
4
- * of the corpus shares — the site's stub/API tooling imports these helpers so
5
- * it renders exactly what the generator emits.
2
+ * prism-llms public surface.
3
+ *
4
+ * The store contract is exported from the root; the extractor sits behind the
5
+ * `./extractor` subpath and is shared with the site's API reference table. The
6
+ * Markdown lane and the demo contract ship so a consumer renders exactly what
7
+ * the generator emits.
6
8
  */
7
- export { parseMdx, fence, renderComponentDemos, stripMdxMechanics, renderTable, renderPropsSection, } from './markdown.js';
8
- export { scanPrismImports, validateDemoSource } from './demo-graph.js';
9
- //# sourceMappingURL=index.js.map
9
+ export { parsePrismDocsStore, STORE_CATEGORIES, STORE_KINDS, STORE_MODES, STORE_PACKS, STORE_SCALE_GROUPS, STORE_SECTIONS, STORE_SECTION_TITLES, STORE_STATUSES, } from './store.js';
10
+ export { assembleDoc, demoTitle, fence, parseMdx, parsePropLine, renderCompositionSection, renderCrossReferences, renderDemoSection, renderPropLine, renderPropsBody, renderPropsSection, stripMdxMechanics, stripSection, } from './markdown.js';
11
+ export { scanPrismImports, scanPrismImportsWithSource, validateDemoSource, } from './demo-graph.js';