@redsift/ds-mcp-server 12.3.1-muiv6-alpha.2

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 (258) hide show
  1. package/README.md +203 -0
  2. package/consumer-instructions/.cursorrules +80 -0
  3. package/consumer-instructions/.windsurfrules +80 -0
  4. package/consumer-instructions/CLAUDE.md +87 -0
  5. package/consumer-instructions/redsift-design-system.instructions.md +87 -0
  6. package/data/demos/patterns/crossfiltered-datagrid-page/example.tsx +750 -0
  7. package/data/demos/patterns/crossfiltered-datagrid-page/with-empty-state.tsx +111 -0
  8. package/data/demos/patterns/crossfiltered-datagrid-page/with-error.tsx +122 -0
  9. package/data/demos/patterns/crossfiltered-datagrid-page/with-loading.tsx +88 -0
  10. package/data/demos/patterns/datagrid-page/example.tsx +521 -0
  11. package/data/demos/patterns/datagrid-page/with-empty-state.tsx +80 -0
  12. package/data/demos/patterns/datagrid-page/with-error.tsx +96 -0
  13. package/data/demos/patterns/datagrid-page/with-loading.tsx +57 -0
  14. package/data/demos/patterns/drilldown-datagrid-page/example.tsx +715 -0
  15. package/data/demos/patterns/drilldown-datagrid-page/with-empty-state.tsx +113 -0
  16. package/data/demos/patterns/drilldown-datagrid-page/with-error.tsx +125 -0
  17. package/data/demos/patterns/drilldown-datagrid-page/with-loading.tsx +90 -0
  18. package/data/demos/patterns/server-datagrid-page/example.tsx +757 -0
  19. package/data/demos/patterns/server-datagrid-page/with-empty-state.tsx +107 -0
  20. package/data/demos/patterns/server-datagrid-page/with-error.tsx +107 -0
  21. package/data/demos/patterns/server-datagrid-page/with-loading.tsx +63 -0
  22. package/data/docs/components/charts/Arc.json +179 -0
  23. package/data/docs/components/charts/Arcs.json +104 -0
  24. package/data/docs/components/charts/Axis.json +269 -0
  25. package/data/docs/components/charts/Bar.json +236 -0
  26. package/data/docs/components/charts/BarChart.json +852 -0
  27. package/data/docs/components/charts/BarChartBars.json +18 -0
  28. package/data/docs/components/charts/BarChartGroupedTooltip.json +9 -0
  29. package/data/docs/components/charts/BarChartOverlay.json +34 -0
  30. package/data/docs/components/charts/BarChartSection.json +94 -0
  31. package/data/docs/components/charts/BaseBarChart.json +852 -0
  32. package/data/docs/components/charts/ChartContainerTitle.json +574 -0
  33. package/data/docs/components/charts/DataPoint.json +160 -0
  34. package/data/docs/components/charts/Dot.json +191 -0
  35. package/data/docs/components/charts/EmptyBarChart.json +852 -0
  36. package/data/docs/components/charts/EmptyLineChart.json +753 -0
  37. package/data/docs/components/charts/EmptyPieChart.json +826 -0
  38. package/data/docs/components/charts/EmptyScatterPlot.json +802 -0
  39. package/data/docs/components/charts/Legend.json +510 -0
  40. package/data/docs/components/charts/LegendItem.json +128 -0
  41. package/data/docs/components/charts/Line.json +69 -0
  42. package/data/docs/components/charts/LineChart.json +753 -0
  43. package/data/docs/components/charts/LoadingBarChart.json +852 -0
  44. package/data/docs/components/charts/LoadingLineChart.json +753 -0
  45. package/data/docs/components/charts/LoadingPieChart.json +826 -0
  46. package/data/docs/components/charts/LoadingScatterPlot.json +802 -0
  47. package/data/docs/components/charts/PieChart.json +826 -0
  48. package/data/docs/components/charts/RenderedLineChart.json +753 -0
  49. package/data/docs/components/charts/RenderedLinearBarChart.json +823 -0
  50. package/data/docs/components/charts/RenderedOrdinalBarChart.json +852 -0
  51. package/data/docs/components/charts/RenderedPieChart.json +826 -0
  52. package/data/docs/components/charts/RenderedScatterPlot.json +802 -0
  53. package/data/docs/components/charts/ScatterPlot.json +802 -0
  54. package/data/docs/components/charts/getAxisType.json +9 -0
  55. package/data/docs/components/charts/getComponentPosition.json +9 -0
  56. package/data/docs/components/dashboard/ChartEmptyState.json +42 -0
  57. package/data/docs/components/dashboard/Dashboard.json +26 -0
  58. package/data/docs/components/dashboard/DataCard.json +300 -0
  59. package/data/docs/components/dashboard/DataCardBody.json +431 -0
  60. package/data/docs/components/dashboard/DataCardHeader.json +304 -0
  61. package/data/docs/components/dashboard/DataCardListbox.json +529 -0
  62. package/data/docs/components/dashboard/DataRow.json +539 -0
  63. package/data/docs/components/dashboard/DrilldownItem.json +342 -0
  64. package/data/docs/components/dashboard/FilterableBarChart.json +83 -0
  65. package/data/docs/components/dashboard/FilterableDataGrid.json +83 -0
  66. package/data/docs/components/dashboard/FilterablePieChart.json +83 -0
  67. package/data/docs/components/dashboard/FilterableScatterPlot.json +83 -0
  68. package/data/docs/components/dashboard/PdfDocument.json +58 -0
  69. package/data/docs/components/dashboard/PdfExportButton.json +458 -0
  70. package/data/docs/components/dashboard/TimeSeriesBarChart.json +172 -0
  71. package/data/docs/components/dashboard/WithFilters.json +83 -0
  72. package/data/docs/components/design-system/ActiveDescendantListbox.json +521 -0
  73. package/data/docs/components/design-system/Alert.json +349 -0
  74. package/data/docs/components/design-system/AppBar.json +64 -0
  75. package/data/docs/components/design-system/AppContainer.json +67 -0
  76. package/data/docs/components/design-system/AppContent.json +566 -0
  77. package/data/docs/components/design-system/AppSidePanel.json +87 -0
  78. package/data/docs/components/design-system/Badge.json +293 -0
  79. package/data/docs/components/design-system/BaseBreadcrumbs.json +298 -0
  80. package/data/docs/components/design-system/BaseGrid.json +543 -0
  81. package/data/docs/components/design-system/BaseSkeleton.json +338 -0
  82. package/data/docs/components/design-system/BreadcrumbItem.json +231 -0
  83. package/data/docs/components/design-system/Breadcrumbs.json +298 -0
  84. package/data/docs/components/design-system/Button.json +402 -0
  85. package/data/docs/components/design-system/ButtonGroup.json +415 -0
  86. package/data/docs/components/design-system/ButtonLink.json +568 -0
  87. package/data/docs/components/design-system/Card.json +328 -0
  88. package/data/docs/components/design-system/CardActions.json +431 -0
  89. package/data/docs/components/design-system/CardBody.json +431 -0
  90. package/data/docs/components/design-system/CardHeader.json +428 -0
  91. package/data/docs/components/design-system/Checkbox.json +426 -0
  92. package/data/docs/components/design-system/CheckboxGroup.json +382 -0
  93. package/data/docs/components/design-system/ConditionalWrapper.json +40 -0
  94. package/data/docs/components/design-system/DetailedCard.json +401 -0
  95. package/data/docs/components/design-system/DetailedCardCollapsibleSectionItems.json +29 -0
  96. package/data/docs/components/design-system/DetailedCardHeader.json +37 -0
  97. package/data/docs/components/design-system/DetailedCardSection.json +90 -0
  98. package/data/docs/components/design-system/DetailedCardSectionItem.json +109 -0
  99. package/data/docs/components/design-system/Flexbox.json +523 -0
  100. package/data/docs/components/design-system/FocusWithinGroup.json +9 -0
  101. package/data/docs/components/design-system/Grid.json +543 -0
  102. package/data/docs/components/design-system/GridItem.json +388 -0
  103. package/data/docs/components/design-system/Heading.json +390 -0
  104. package/data/docs/components/design-system/Icon.json +325 -0
  105. package/data/docs/components/design-system/IconButton.json +371 -0
  106. package/data/docs/components/design-system/IconButtonLink.json +588 -0
  107. package/data/docs/components/design-system/Item.json +554 -0
  108. package/data/docs/components/design-system/Link.json +552 -0
  109. package/data/docs/components/design-system/LinkButton.json +397 -0
  110. package/data/docs/components/design-system/Listbox.json +529 -0
  111. package/data/docs/components/design-system/Number.json +773 -0
  112. package/data/docs/components/design-system/NumberField.json +594 -0
  113. package/data/docs/components/design-system/Pill.json +378 -0
  114. package/data/docs/components/design-system/ProgressBar.json +121 -0
  115. package/data/docs/components/design-system/RadarSvgLinearGradient.json +9 -0
  116. package/data/docs/components/design-system/Radio.json +415 -0
  117. package/data/docs/components/design-system/RadioGroup.json +382 -0
  118. package/data/docs/components/design-system/RenderedListboxItem.json +18 -0
  119. package/data/docs/components/design-system/RovingTabindexListbox.json +521 -0
  120. package/data/docs/components/design-system/Shield.json +360 -0
  121. package/data/docs/components/design-system/SideNavigationMenu.json +144 -0
  122. package/data/docs/components/design-system/SideNavigationMenuBar.json +89 -0
  123. package/data/docs/components/design-system/SideNavigationMenuItem.json +319 -0
  124. package/data/docs/components/design-system/Skeleton.json +338 -0
  125. package/data/docs/components/design-system/SkeletonCircle.json +338 -0
  126. package/data/docs/components/design-system/SkeletonText.json +371 -0
  127. package/data/docs/components/design-system/Spinner.json +291 -0
  128. package/data/docs/components/design-system/Switch.json +415 -0
  129. package/data/docs/components/design-system/SwitchGroup.json +382 -0
  130. package/data/docs/components/design-system/Text.json +418 -0
  131. package/data/docs/components/design-system/TextArea.json +501 -0
  132. package/data/docs/components/design-system/TextField.json +539 -0
  133. package/data/docs/components/design-system/sizeToDimension.json +9 -0
  134. package/data/docs/components/pickers/BaseCombobox.json +320 -0
  135. package/data/docs/components/pickers/BaseComboboxContent.json +453 -0
  136. package/data/docs/components/pickers/BaseMenuButton.json +240 -0
  137. package/data/docs/components/pickers/BaseMenuButtonContent.json +442 -0
  138. package/data/docs/components/pickers/BaseSelect.json +258 -0
  139. package/data/docs/components/pickers/Combobox.json +320 -0
  140. package/data/docs/components/pickers/ComboboxContent.json +453 -0
  141. package/data/docs/components/pickers/ComboboxContentFooter.json +431 -0
  142. package/data/docs/components/pickers/ComboboxContentHeader.json +431 -0
  143. package/data/docs/components/pickers/ComboboxContentListbox.json +541 -0
  144. package/data/docs/components/pickers/ComboboxTrigger.json +336 -0
  145. package/data/docs/components/pickers/Item.json +554 -0
  146. package/data/docs/components/pickers/MenuButton.json +240 -0
  147. package/data/docs/components/pickers/MenuButtonContent.json +442 -0
  148. package/data/docs/components/pickers/MenuButtonContentFooter.json +431 -0
  149. package/data/docs/components/pickers/MenuButtonContentHeader.json +431 -0
  150. package/data/docs/components/pickers/MenuButtonContentMenu.json +523 -0
  151. package/data/docs/components/pickers/MenuButtonTrigger.json +287 -0
  152. package/data/docs/components/pickers/Select.json +258 -0
  153. package/data/docs/components/pickers/SelectContent.json +442 -0
  154. package/data/docs/components/pickers/SelectTrigger.json +298 -0
  155. package/data/docs/components/popovers/BaseDialog.json +114 -0
  156. package/data/docs/components/popovers/BaseDialogContent.json +21 -0
  157. package/data/docs/components/popovers/BasePopover.json +171 -0
  158. package/data/docs/components/popovers/BaseToggletip.json +184 -0
  159. package/data/docs/components/popovers/BaseTooltip.json +121 -0
  160. package/data/docs/components/popovers/Button.json +402 -0
  161. package/data/docs/components/popovers/ButtonLink.json +568 -0
  162. package/data/docs/components/popovers/Dialog.json +114 -0
  163. package/data/docs/components/popovers/DialogContent.json +21 -0
  164. package/data/docs/components/popovers/DialogContentActions.json +442 -0
  165. package/data/docs/components/popovers/DialogContentBody.json +442 -0
  166. package/data/docs/components/popovers/DialogContentHeader.json +76 -0
  167. package/data/docs/components/popovers/DialogTrigger.json +276 -0
  168. package/data/docs/components/popovers/IconButton.json +371 -0
  169. package/data/docs/components/popovers/IconButtonLink.json +588 -0
  170. package/data/docs/components/popovers/Link.json +552 -0
  171. package/data/docs/components/popovers/LinkButton.json +397 -0
  172. package/data/docs/components/popovers/Popover.json +171 -0
  173. package/data/docs/components/popovers/PopoverContent.json +442 -0
  174. package/data/docs/components/popovers/PopoverTrigger.json +276 -0
  175. package/data/docs/components/popovers/Toast.json +145 -0
  176. package/data/docs/components/popovers/ToastContainer.json +122 -0
  177. package/data/docs/components/popovers/Toggletip.json +184 -0
  178. package/data/docs/components/popovers/ToggletipContent.json +402 -0
  179. package/data/docs/components/popovers/ToggletipTrigger.json +276 -0
  180. package/data/docs/components/popovers/Tooltip.json +121 -0
  181. package/data/docs/components/popovers/TooltipContent.json +402 -0
  182. package/data/docs/components/popovers/TooltipTrigger.json +276 -0
  183. package/data/docs/components/products/Dialog.json +106 -0
  184. package/data/docs/components/products/MenuButton.json +232 -0
  185. package/data/docs/components/products/PulsedRadarImage.json +9 -0
  186. package/data/docs/components/products/RadarButton.json +402 -0
  187. package/data/docs/components/products/RadarItem.json +554 -0
  188. package/data/docs/components/table/ControlledPagination.json +9 -0
  189. package/data/docs/components/table/DataGrid.json +93 -0
  190. package/data/docs/components/table/GridToolbarFilterSemanticField.json +69 -0
  191. package/data/docs/components/table/ServerSideControlledPagination.json +9 -0
  192. package/data/docs/components/table/StatefulDataGrid.json +117 -0
  193. package/data/docs/components/table/TextCell.json +118 -0
  194. package/data/docs/components/table/Toolbar.json +145 -0
  195. package/data/docs/components/table/ToolbarWrapper.json +9 -0
  196. package/data/docs/components-index.json +1206 -0
  197. package/data/docs/components.json +55694 -0
  198. package/data/docs/llms-full.txt +8012 -0
  199. package/data/docs/llms.txt +234 -0
  200. package/data/docs/patterns-catalog.md +359 -0
  201. package/data/docs/patterns.json +712 -0
  202. package/data/metadata.json +4 -0
  203. package/data/patterns/crossfiltered-datagrid-page.mdx +386 -0
  204. package/data/patterns/datagrid-page.mdx +214 -0
  205. package/data/patterns/drilldown-datagrid-page.mdx +291 -0
  206. package/data/patterns/server-datagrid-page.mdx +301 -0
  207. package/data/tokens/properties/components/dark-components.json +1108 -0
  208. package/data/tokens/properties/components/light-components.json +1108 -0
  209. package/data/tokens/properties/core/border-radius.json +3 -0
  210. package/data/tokens/properties/core/color.json +280 -0
  211. package/data/tokens/properties/core/layout.json +14 -0
  212. package/data/tokens/properties/core/typography.json +199 -0
  213. package/data/tokens/redsift-design-tokens.css +1391 -0
  214. package/dist/data-store.d.ts +47 -0
  215. package/dist/data-store.d.ts.map +1 -0
  216. package/dist/data-store.js +152 -0
  217. package/dist/data-store.js.map +1 -0
  218. package/dist/index.d.ts +16 -0
  219. package/dist/index.d.ts.map +1 -0
  220. package/dist/index.js +50 -0
  221. package/dist/index.js.map +1 -0
  222. package/dist/init.d.ts +14 -0
  223. package/dist/init.d.ts.map +1 -0
  224. package/dist/init.js +137 -0
  225. package/dist/init.js.map +1 -0
  226. package/dist/paths.d.ts +30 -0
  227. package/dist/paths.d.ts.map +1 -0
  228. package/dist/paths.js +53 -0
  229. package/dist/paths.js.map +1 -0
  230. package/dist/pattern-store.d.ts +41 -0
  231. package/dist/pattern-store.d.ts.map +1 -0
  232. package/dist/pattern-store.js +177 -0
  233. package/dist/pattern-store.js.map +1 -0
  234. package/dist/prompts.d.ts +14 -0
  235. package/dist/prompts.d.ts.map +1 -0
  236. package/dist/prompts.js +762 -0
  237. package/dist/prompts.js.map +1 -0
  238. package/dist/resources.d.ts +14 -0
  239. package/dist/resources.d.ts.map +1 -0
  240. package/dist/resources.js +482 -0
  241. package/dist/resources.js.map +1 -0
  242. package/dist/scaffold.d.ts +31 -0
  243. package/dist/scaffold.d.ts.map +1 -0
  244. package/dist/scaffold.js +239 -0
  245. package/dist/scaffold.js.map +1 -0
  246. package/dist/token-store.d.ts +70 -0
  247. package/dist/token-store.d.ts.map +1 -0
  248. package/dist/token-store.js +196 -0
  249. package/dist/token-store.js.map +1 -0
  250. package/dist/tools.d.ts +15 -0
  251. package/dist/tools.d.ts.map +1 -0
  252. package/dist/tools.js +491 -0
  253. package/dist/tools.js.map +1 -0
  254. package/dist/types.d.ts +108 -0
  255. package/dist/types.d.ts.map +1 -0
  256. package/dist/types.js +17 -0
  257. package/dist/types.js.map +1 -0
  258. package/package.json +39 -0
@@ -0,0 +1,762 @@
1
+ /**
2
+ * MCP Prompts for the Red Sift Design System.
3
+ *
4
+ * Provides reusable prompt templates that guide AI assistants through
5
+ * common workflows like creating components, adding props, and building forms.
6
+ */
7
+ import { z } from 'zod';
8
+ import { PACKAGES } from './types.js';
9
+ /**
10
+ * Register all MCP prompts on the server.
11
+ */
12
+ export function registerPrompts(server, store, patternStore) {
13
+ // ─── create-component ────────────────────────────────────────────────
14
+ server.registerPrompt('create-component', {
15
+ description: 'Step-by-step guide to create a new component following design system conventions.',
16
+ argsSchema: {
17
+ name: z.string().describe('Component name in PascalCase (e.g. "StatusCard")'),
18
+ package: z.enum(PACKAGES).optional().describe('Target package (default: "design-system")'),
19
+ element: z.string().optional().describe('HTML element to extend (default: "div"). E.g. "button", "input", "a"'),
20
+ description: z.string().optional().describe('Brief description of the component'),
21
+ },
22
+ }, async ({ name, package: pkg, element, description }) => {
23
+ const targetPkg = pkg || 'design-system';
24
+ const htmlElement = element || 'div';
25
+ const desc = description || `The ${name} component.`;
26
+ const kebabName = toKebabCase(name);
27
+ return {
28
+ messages: [
29
+ {
30
+ role: 'user',
31
+ content: {
32
+ type: 'text',
33
+ text: `Create a new component **${name}** in the \`@redsift/${targetPkg}\` package.
34
+
35
+ ## Requirements
36
+
37
+ - **Component name:** ${name}
38
+ - **Package:** @redsift/${targetPkg}
39
+ - **Directory:** packages/${targetPkg}/src/components/${kebabName}/
40
+ - **HTML element:** <${htmlElement}>
41
+ - **Description:** ${desc}
42
+
43
+ ## Steps
44
+
45
+ 1. **Generate scaffold** — Use the \`generate_component_scaffold\` tool with name="${name}", package="${targetPkg}", element="${htmlElement}", description="${desc}".
46
+ 2. **Create the directory** — \`packages/${targetPkg}/src/components/${kebabName}/\`
47
+ 3. **Write all 6 files** from the scaffold output:
48
+ - \`${name}.tsx\` — Main component
49
+ - \`types.ts\` — Props interface
50
+ - \`styles.ts\` — Styled component
51
+ - \`index.ts\` — Re-exports
52
+ - \`${name}.test.tsx\` — Tests
53
+ - \`${name}.stories.tsx\` — Storybook stories
54
+ 4. **Export the component** — Add \`export * from './components/${kebabName}';\` to \`packages/${targetPkg}/index.ts\`
55
+ 5. **Verify** — Run \`yarn check-types:${targetPkg}\` to confirm no type errors.
56
+
57
+ ## Conventions Checklist
58
+
59
+ - [ ] Uses \`Comp\` type and \`forwardRef\`
60
+ - [ ] Static \`.className = 'redsift-${kebabName}'\`
61
+ - [ ] Static \`.displayName = '${name}'\`
62
+ - [ ] Uses \`classNames()\` for className concatenation
63
+ - [ ] Props extend \`ComponentProps<'${htmlElement}'>\` and \`StylingProps\`
64
+ - [ ] Styled component uses transient props (\`$\` prefix)
65
+ - [ ] Tests cover: snapshot, default render, className forwarding, ref forwarding
66
+ - [ ] JSDoc comment above export with \`@example\` block`,
67
+ },
68
+ },
69
+ ],
70
+ };
71
+ });
72
+ // ─── add-prop ────────────────────────────────────────────────────────
73
+ server.registerPrompt('add-prop', {
74
+ description: 'Guide to add a new prop to an existing component, updating all related files.',
75
+ argsSchema: {
76
+ component: z.string().describe('Existing component name in PascalCase (e.g. "Button")'),
77
+ propName: z.string().describe('New prop name in camelCase (e.g. "isLoading")'),
78
+ propType: z.string().describe('TypeScript type (e.g. "boolean", "string", "\'sm\' | \'md\' | \'lg\'")'),
79
+ required: z.string().optional().describe('Whether the prop is required ("true" or "false", default: "false")'),
80
+ defaultValue: z.string().optional().describe('Default value for the prop'),
81
+ description: z.string().optional().describe('JSDoc description for the prop'),
82
+ },
83
+ }, async ({ component, propName, propType, required, defaultValue, description }) => {
84
+ const isRequired = required === 'true';
85
+ const desc = description || `The ${propName} prop.`;
86
+ const comp = store.getComponent(component);
87
+ const packageName = comp ? comp.package.replace('@redsift/', '') : 'design-system';
88
+ const kebabName = toKebabCase(component);
89
+ const needsTransient = shouldBeTransient(propName);
90
+ return {
91
+ messages: [
92
+ {
93
+ role: 'user',
94
+ content: {
95
+ type: 'text',
96
+ text: `Add a new prop **${propName}** to the **${component}** component in \`@redsift/${packageName}\`.
97
+
98
+ ## Prop Details
99
+
100
+ - **Name:** ${propName}
101
+ - **Type:** ${propType}
102
+ - **Required:** ${isRequired ? 'Yes' : 'No'}
103
+ ${defaultValue ? `- **Default:** ${defaultValue}` : ''}
104
+ - **Description:** ${desc}
105
+
106
+ ## Files to Update
107
+
108
+ ### 1. \`packages/${packageName}/src/components/${kebabName}/types.ts\`
109
+
110
+ Add to \`${component}Props\`:
111
+ \`\`\`ts
112
+ /**
113
+ * ${desc}${defaultValue ? `\n * @default ${defaultValue}` : ''}
114
+ */
115
+ ${propName}${isRequired ? '' : '?'}: ${propType};
116
+ \`\`\`
117
+
118
+ ${needsTransient
119
+ ? `Add to \`Styled${component}Props\`:
120
+ \`\`\`ts
121
+ $${propName}?: ${component}Props['${propName}'];
122
+ \`\`\``
123
+ : ''}
124
+
125
+ ### 2. \`packages/${packageName}/src/components/${kebabName}/${component}.tsx\`
126
+
127
+ - Destructure \`${propName}\` from props${defaultValue ? ` with default: \`${propName} = ${defaultValue}\`` : ''}
128
+ ${needsTransient
129
+ ? `- Pass \`$${propName}={${propName}}\` to the styled component`
130
+ : `- Use \`${propName}\` in the render logic`}
131
+
132
+ ### 3. \`packages/${packageName}/src/components/${kebabName}/styles.ts\`
133
+
134
+ ${needsTransient
135
+ ? `Use the transient prop in styles:
136
+ \`\`\`ts
137
+ \${({ $${propName} }) => $${propName} ? css\\\`/* styles */\\\` : ''}
138
+ \`\`\``
139
+ : 'Add any relevant styles.'}
140
+
141
+ ### 4. \`packages/${packageName}/src/components/${kebabName}/${component}.stories.tsx\`
142
+
143
+ Add story variants demonstrating the new prop:
144
+ \`\`\`tsx
145
+ export const With${capitalize(propName)}: Story = {
146
+ args: {
147
+ ${propName}: ${getExampleValue(propType, defaultValue)},
148
+ },
149
+ };
150
+ \`\`\`
151
+
152
+ ### 5. \`packages/${packageName}/src/components/${kebabName}/${component}.test.tsx\`
153
+
154
+ Add test for the new prop:
155
+ \`\`\`tsx
156
+ it('should handle ${propName} prop', () => {
157
+ const { container } = render(<${component} ${propName}={${getExampleValue(propType, defaultValue)}} />);
158
+ // Assert expected behavior
159
+ });
160
+ \`\`\`
161
+
162
+ ### 6. Update snapshots
163
+
164
+ \`\`\`bash
165
+ yarn test:unit:${packageName} -u
166
+ \`\`\`
167
+
168
+ ## Verification
169
+
170
+ \`\`\`bash
171
+ yarn check-types:${packageName}
172
+ yarn lint:${packageName}
173
+ yarn test:unit:${packageName}
174
+ \`\`\``,
175
+ },
176
+ },
177
+ ],
178
+ };
179
+ });
180
+ // ─── build-form ──────────────────────────────────────────────────────
181
+ server.registerPrompt('build-form', {
182
+ description: 'Generate a form composition using design system form components.',
183
+ argsSchema: {
184
+ fields: z
185
+ .string()
186
+ .describe('Comma-separated list of field definitions. Format: "name:type" where type is text|email|password|number|select|checkbox|radio|textarea. Example: "email:email,password:password,name:text,role:select"'),
187
+ submitLabel: z.string().optional().describe('Submit button label (default: "Submit")'),
188
+ layout: z.string().optional().describe('Form layout: "vertical" (default) or "horizontal"'),
189
+ },
190
+ }, async ({ fields, submitLabel, layout }) => {
191
+ const submit = submitLabel || 'Submit';
192
+ const formLayout = layout || 'vertical';
193
+ const parsedFields = fields.split(',').map((f) => {
194
+ const [name, type] = f.trim().split(':');
195
+ return { name: name.trim(), type: (type || 'text').trim() };
196
+ });
197
+ const imports = new Set(['Button']);
198
+ const fieldComponents = [];
199
+ for (const field of parsedFields) {
200
+ const label = capitalize(field.name.replace(/([A-Z])/g, ' $1').trim());
201
+ switch (field.type) {
202
+ case 'text':
203
+ case 'email':
204
+ case 'password':
205
+ case 'number':
206
+ imports.add('TextField');
207
+ fieldComponents.push(` <TextField\n label="${label}"\n name="${field.name}"\n type="${field.type}"${field.type === 'email' ? '\n autoComplete="email"' : ''}${field.type === 'password' ? '\n autoComplete="current-password"' : ''}\n />`);
208
+ break;
209
+ case 'textarea':
210
+ imports.add('TextArea');
211
+ fieldComponents.push(` <TextArea\n label="${label}"\n name="${field.name}"\n rows={4}\n />`);
212
+ break;
213
+ case 'select':
214
+ imports.add('Select');
215
+ imports.add('Option');
216
+ fieldComponents.push(` <Select label="${label}" name="${field.name}">\n <Option value="option1">Option 1</Option>\n <Option value="option2">Option 2</Option>\n </Select>`);
217
+ break;
218
+ case 'checkbox':
219
+ imports.add('Checkbox');
220
+ fieldComponents.push(` <Checkbox label="${label}" name="${field.name}" />`);
221
+ break;
222
+ case 'radio':
223
+ imports.add('RadioGroup');
224
+ imports.add('Radio');
225
+ fieldComponents.push(` <RadioGroup label="${label}" name="${field.name}">\n <Radio value="option1" label="Option 1" />\n <Radio value="option2" label="Option 2" />\n </RadioGroup>`);
226
+ break;
227
+ default:
228
+ imports.add('TextField');
229
+ fieldComponents.push(` <TextField label="${label}" name="${field.name}" type="text" />`);
230
+ }
231
+ }
232
+ const importList = Array.from(imports).sort().join(', ');
233
+ return {
234
+ messages: [
235
+ {
236
+ role: 'user',
237
+ content: {
238
+ type: 'text',
239
+ text: `Build a form with the following fields using Red Sift Design System components.
240
+
241
+ ## Form Specification
242
+
243
+ - **Layout:** ${formLayout}
244
+ - **Fields:** ${parsedFields.map((f) => `${f.name} (${f.type})`).join(', ')}
245
+ - **Submit:** "${submit}"
246
+
247
+ ## Generated Code
248
+
249
+ \`\`\`tsx
250
+ import React, { FormEvent } from 'react';
251
+ import { ${importList} } from '@redsift/design-system';
252
+
253
+ interface FormData {
254
+ ${parsedFields.map((f) => ` ${f.name}: ${f.type === 'checkbox' ? 'boolean' : 'string'};`).join('\n')}
255
+ }
256
+
257
+ function MyForm() {
258
+ const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
259
+ e.preventDefault();
260
+ const formData = new FormData(e.currentTarget);
261
+ // Process form data
262
+ };
263
+
264
+ return (
265
+ <form onSubmit={handleSubmit}${formLayout === 'horizontal'
266
+ ? ' style={{ display: "flex", gap: "16px", alignItems: "flex-end", flexWrap: "wrap" }}'
267
+ : ''}>
268
+ ${fieldComponents.join('\n\n')}
269
+
270
+ <Button type="submit">${submit}</Button>
271
+ </form>
272
+ );
273
+ }
274
+ \`\`\`
275
+
276
+ ## Notes
277
+
278
+ - All form components are from \`@redsift/design-system\`
279
+ - Add validation as needed using the \`error\` and \`helperText\` props on \`TextField\`
280
+ - For Select fields, replace placeholder options with real data
281
+ - Use \`useSearchParams\` or a form library for state management if needed`,
282
+ },
283
+ },
284
+ ],
285
+ };
286
+ });
287
+ // ─── pr-description ──────────────────────────────────────────────────
288
+ server.registerPrompt('pr-description', {
289
+ description: 'Generate a pull request description following the repository PR template.',
290
+ argsSchema: {
291
+ title: z.string().describe('PR title'),
292
+ changes: z.string().describe('Description of the changes made'),
293
+ issueNumber: z.string().optional().describe('Related GitHub issue number'),
294
+ packages: z
295
+ .string()
296
+ .optional()
297
+ .describe('Comma-separated list of affected packages (e.g. "design-system, popovers")'),
298
+ },
299
+ }, async ({ title, changes, issueNumber, packages: pkgs }) => {
300
+ const affectedPkgs = pkgs
301
+ ? pkgs
302
+ .split(',')
303
+ .map((p) => p.trim())
304
+ .filter(Boolean)
305
+ : [];
306
+ return {
307
+ messages: [
308
+ {
309
+ role: 'user',
310
+ content: {
311
+ type: 'text',
312
+ text: `Generate a pull request description for the following changes.
313
+
314
+ ## PR Details
315
+
316
+ - **Title:** ${title}
317
+ - **Changes:** ${changes}
318
+ ${issueNumber ? `- **Issue:** #${issueNumber}` : '- **Issue:** (none specified)'}
319
+ ${affectedPkgs.length > 0 ? `- **Affected packages:** ${affectedPkgs.map((p) => `@redsift/${p}`).join(', ')}` : ''}
320
+
321
+ ## PR Template
322
+
323
+ Fill in this template:
324
+
325
+ \`\`\`markdown
326
+ ## Summary
327
+
328
+ <!-- Brief description of the change -->
329
+
330
+ ${issueNumber ? `Closes #${issueNumber}` : '<!-- Link to related issue -->'}
331
+
332
+ ## Changes
333
+
334
+ ${changes}
335
+
336
+ ## Checklist
337
+
338
+ - [${issueNumber ? 'x' : ' '}] Linked to a GitHub issue
339
+ - [ ] Added/updated unit tests
340
+ - [ ] Added/updated Storybook stories
341
+ - [ ] Verified accessibility (keyboard navigation, screen reader)
342
+ - [ ] Updated snapshots (\`yarn test:unit:<package> -u\`)
343
+ - [ ] Updated CHANGELOG.md under \`[Unreleased]\`
344
+ - [ ] Ran \`yarn check-types:<package>\` with no errors
345
+ - [ ] Ran \`yarn lint:<package>\` with no errors
346
+ - [ ] Tested in Storybook locally
347
+
348
+ ## How to Test
349
+
350
+ 1. Check out this branch
351
+ 2. Run \`yarn install\`
352
+ 3. Run \`yarn start:storybook\`
353
+ 4. Navigate to the affected component(s)
354
+ 5. Verify the changes work as expected
355
+
356
+ ## Screenshots
357
+
358
+ <!-- Add screenshots if visual changes -->
359
+ \`\`\`
360
+
361
+ Also generate a changelog entry for CHANGELOG.md under \`[Unreleased]\`:
362
+
363
+ ${affectedPkgs.map((p) => `- \`@redsift/${p}\`: ${changes}`).join('\n') || `- ${changes}`}`,
364
+ },
365
+ },
366
+ ],
367
+ };
368
+ });
369
+ // ─── implement-ui ────────────────────────────────────────────────────
370
+ server.registerPrompt('implement-ui', {
371
+ description: 'Generate a complete UI implementation using proven design system composition patterns. Searches for matching patterns and provides detailed component usage guidance.',
372
+ argsSchema: {
373
+ description: z
374
+ .string()
375
+ .describe('Describe the UI you want to build (e.g. "a data table with search and export", "a settings page with toggles")'),
376
+ target: z
377
+ .string()
378
+ .optional()
379
+ .describe('Target framework or context (e.g. "React", "Next.js"). Defaults to React.'),
380
+ },
381
+ }, async ({ description, target }) => {
382
+ const framework = target || 'React';
383
+ // Search for relevant patterns
384
+ const patterns = patternStore.searchPatterns(description, 5);
385
+ let patternSection;
386
+ if (patterns.length === 0) {
387
+ patternSection = `No exact pattern matches found for "${description}". Use the \`search_patterns\` tool with broader terms, or compose from individual components using \`search_components\`.`;
388
+ }
389
+ else {
390
+ const patternBlocks = patterns.map((p) => {
391
+ const components = p.components.join(', ');
392
+ const packages = p.packages.join(', ');
393
+ return `### ${p.name}
394
+ - **Description:** ${p.description}
395
+ - **Components:** ${components}
396
+ - **Packages:** ${packages}
397
+ - **Layout:** ${p.layout}
398
+ - **Tags:** ${p.tags.join(', ')}
399
+ - **Documentation:** https://design-system.redsift.io/patterns/${p.slug}
400
+ - **Full demo source:** Fetch the resource \`design-system://patterns/${p.slug}\` to get complete working code`;
401
+ });
402
+ patternSection = patternBlocks.join('\n\n');
403
+ }
404
+ return {
405
+ messages: [
406
+ {
407
+ role: 'user',
408
+ content: {
409
+ type: 'text',
410
+ text: `Implement a ${framework} UI for the following requirement:
411
+
412
+ > ${description}
413
+
414
+ ## Matching Composition Patterns
415
+
416
+ ${patternSection}
417
+
418
+ ## Implementation Instructions
419
+
420
+ 1. **Fetch the full pattern spec** for each matched pattern above by reading the resource \`design-system://patterns/{slug}\`. This gives you:
421
+ - **When to Use** — decision criteria to confirm pattern fit
422
+ - **Anatomy** — visual structure (which component goes in which slot)
423
+ - **Features** — required vs optional features table
424
+ - **State Management** — every \`useState\`/\`useRef\` hook with TypeScript types and initial values
425
+ - **Data Contract** — TypeScript type definitions for rows and fetch functions
426
+ - **Implementation Checklist** — ordered step-by-step build guide
427
+ - **Complete demo source code** — a full working reference implementation
428
+ - **Variant demos** — loading, empty, and error state implementations
429
+ - **Keyboard & Accessibility** — a11y requirements
430
+
431
+ 2. **Follow the Implementation Checklist** step-by-step. It references the other spec sections by name (e.g. "Define your row type per Data Contract").
432
+
433
+ 3. **Adapt the Data Contract** — Replace the example \`Row\` type with your actual domain types. Keep the same field structure (id, status fields, date fields, tag arrays) where applicable.
434
+
435
+ 4. **Use the State Management section** as your hook scaffold — copy the hooks and adapt types to your data model.
436
+
437
+ 5. **Include variant handling** — Implement loading, empty, and error states as shown in the variant demos. These are critical for production quality.
438
+
439
+ 6. **Import components** from the listed packages (e.g. \`import { Button, Flexbox, Heading } from '@redsift/design-system';\`).
440
+
441
+ 7. **Look up individual component props** using the \`get_component_props\` tool if you need the full API for any component.
442
+
443
+ ## Code Quality Requirements
444
+
445
+ - Use TypeScript with proper types (no \`any\`)
446
+ - Use \`forwardRef\` for components that wrap DOM elements
447
+ - Use \`styled-components\` with transient props (\`$\` prefix) for styling
448
+ - Follow the component naming and file structure conventions of the design system
449
+ - Implement loading, empty, and error states (not just the happy path)
450
+
451
+ ## Output
452
+
453
+ Provide a complete, working ${framework} implementation with:
454
+ - All necessary imports
455
+ - TypeScript interfaces for props and data types
456
+ - Component implementation with all state hooks
457
+ - Loading, empty, and error state handling
458
+ - Brief usage example`,
459
+ },
460
+ },
461
+ ],
462
+ };
463
+ });
464
+ // ─── create-pattern ──────────────────────────────────────────────────
465
+ server.registerPrompt('create-pattern', {
466
+ description: 'Step-by-step guide to create a new pattern page for the design system website.',
467
+ argsSchema: {
468
+ name: z.string().describe('Pattern name in Title Case (e.g. "Dashboard Card")'),
469
+ description: z.string().describe('Brief description of what the pattern is and when to use it'),
470
+ components: z
471
+ .string()
472
+ .describe('Comma-separated list of components used. Format: "ComponentName:/category/slug" (e.g. "Button:/forms/button,Flexbox:/layout/flexbox")'),
473
+ relatedPatterns: z
474
+ .string()
475
+ .optional()
476
+ .describe('Comma-separated list of related patterns. Format: "Pattern Name:slug" (e.g. "Table Toolbar:table-toolbar,Data Table Page:data-table-page")'),
477
+ variants: z
478
+ .string()
479
+ .optional()
480
+ .describe('Comma-separated list of variant demo names beyond the default "example" (e.g. "with-loading,with-empty-state")'),
481
+ },
482
+ }, async ({ name, description, components, relatedPatterns, variants }) => {
483
+ const slug = toKebabCase(name.replace(/\s+/g, ''));
484
+ const parsedComponents = components.split(',').map((c) => {
485
+ const [compName, href] = c.trim().split(':');
486
+ return { name: compName.trim(), href: href?.trim() || '' };
487
+ });
488
+ const parsedRelated = relatedPatterns
489
+ ? relatedPatterns.split(',').map((r) => {
490
+ const [rName, rSlug] = r.trim().split(':');
491
+ return { name: rName.trim(), slug: rSlug?.trim() || toKebabCase(rName.trim().replace(/\s+/g, '')) };
492
+ })
493
+ : [];
494
+ const parsedVariants = variants
495
+ ? variants
496
+ .split(',')
497
+ .map((v) => v.trim())
498
+ .filter(Boolean)
499
+ : [];
500
+ const componentLines = parsedComponents
501
+ .map((c) => `- <Link href="${c.href}" as={RouterLink}>${c.name}</Link> — TODO: describe role`)
502
+ .join('\n');
503
+ const relatedLines = parsedRelated.length > 0
504
+ ? parsedRelated
505
+ .map((r) => `- <Link href="/patterns/${r.slug}" as={RouterLink}>${r.name}</Link> — TODO: describe relationship`)
506
+ .join('\n')
507
+ : '- <!-- Add related patterns -->';
508
+ const variantSections = parsedVariants
509
+ .map((v) => {
510
+ const title = v
511
+ .replace(/-/g, ' ')
512
+ .replace(/\b\w/g, (c) => c.toUpperCase())
513
+ .replace(/^With /, 'With ');
514
+ return `## ${title}
515
+
516
+ TODO: Describe this variant.
517
+
518
+ <DemoBlock withThemeSwitcher path="patterns/${slug}/${v}" />`;
519
+ })
520
+ .join('\n\n');
521
+ const mdxContent = `import { Link } from '@redsift/design-system';
522
+ import { DemoBlock } from '../../components/DemoBlock';
523
+ import { CodeBlock } from '../../components/CodeBlock';
524
+ import { RouterLink } from '../../components/RouterLink';
525
+
526
+ ## Introduction
527
+
528
+ ${description}
529
+
530
+ ### Components
531
+
532
+ {/* prettier-ignore */}
533
+ ${componentLines}
534
+
535
+ ## Example
536
+
537
+ TODO: Describe the default example.
538
+
539
+ <DemoBlock withThemeSwitcher path="patterns/${slug}/example" />
540
+
541
+ ${variantSections ? variantSections + '\n\n' : ''}## Related Patterns
542
+
543
+ {/* prettier-ignore */}
544
+ ${relatedLines}`;
545
+ const patternsJsonEntry = JSON.stringify({
546
+ name,
547
+ slug,
548
+ description,
549
+ components: parsedComponents.map((c) => c.name),
550
+ packages: ['@redsift/design-system'],
551
+ layout: 'TODO: describe component layout',
552
+ tags: ['TODO'],
553
+ }, null, 2);
554
+ return {
555
+ messages: [
556
+ {
557
+ role: 'user',
558
+ content: {
559
+ type: 'text',
560
+ text: `Create a new pattern page **${name}** for the design system website.
561
+
562
+ ## Pattern Details
563
+
564
+ - **Name:** ${name}
565
+ - **Slug:** ${slug}
566
+ - **Description:** ${description}
567
+ - **Components:** ${parsedComponents.map((c) => c.name).join(', ')}
568
+ ${parsedRelated.length > 0 ? `- **Related patterns:** ${parsedRelated.map((r) => r.name).join(', ')}` : ''}
569
+ ${parsedVariants.length > 0 ? `- **Variants:** ${parsedVariants.join(', ')}` : ''}
570
+
571
+ ## Steps
572
+
573
+ ### 1. Create the MDX page
574
+
575
+ **File:** \`apps/website/pages/patterns/${slug}.mdx\`
576
+
577
+ \`\`\`mdx
578
+ ${mdxContent}
579
+ \`\`\`
580
+
581
+ ### 2. Create demo files
582
+
583
+ **Directory:** \`apps/website/demo/patterns/${slug}/\`
584
+
585
+ Create at minimum:
586
+ - \`example.tsx\` — default demo
587
+ ${parsedVariants.map((v) => `- \`${v}.tsx\` — ${v.replace(/-/g, ' ')} variant`).join('\n')}
588
+
589
+ Each demo file should export a default React component demonstrating the pattern.
590
+
591
+ ### 3. Register in patterns.json
592
+
593
+ **File:** \`docs/patterns.json\`
594
+
595
+ Add this entry to the array:
596
+
597
+ \`\`\`json
598
+ ${patternsJsonEntry}
599
+ \`\`\`
600
+
601
+ ### 4. Update CHANGELOG.md
602
+
603
+ Add under \`[Unreleased]\`:
604
+ - \`website\`: Add ${name} pattern page
605
+
606
+ ## Critical Conventions
607
+
608
+ - **\`{/* prettier-ignore */}\`** is REQUIRED before every list that contains \`<Link>\` tags (both Components and Related Patterns lists). Without it, Prettier reformats the single-line tags into multi-line JSX which breaks the MDX parser.
609
+ - **Keep all \`<Link>\` tags on a single line** within list items — never split across multiple lines.
610
+ - If a component has sub-components (e.g. Card.Header), list them on the same line: \`<Link ...>Card</Link>, Card.Header, Card.Body — description\`
611
+ - Demo paths in \`<DemoBlock>\` must match the file structure under \`apps/website/demo/\`.
612
+
613
+ ## Verification
614
+
615
+ 1. Run \`yarn dev:website\` and navigate to \`/patterns/${slug}\`
616
+ 2. Verify the page renders without MDX parser errors
617
+ 3. Save the file and verify Prettier does not break the Link lists
618
+ 4. Confirm all demo blocks render correctly`,
619
+ },
620
+ },
621
+ ],
622
+ };
623
+ });
624
+ // ─── add-demo ────────────────────────────────────────────────────────
625
+ server.registerPrompt('add-demo', {
626
+ description: 'Generate a demo file for a component or pattern on the documentation website.',
627
+ argsSchema: {
628
+ component: z
629
+ .string()
630
+ .describe('Component name in PascalCase (e.g. "Button") or pattern slug (e.g. "data-table-page")'),
631
+ demoName: z.string().describe('Demo file name without extension (e.g. "example", "with-loading", "variants")'),
632
+ description: z.string().optional().describe('What this demo should demonstrate'),
633
+ isPattern: z
634
+ .string()
635
+ .optional()
636
+ .describe('"true" if this is a pattern demo, "false" for component demo (default: "false")'),
637
+ },
638
+ }, async ({ component, demoName, description, isPattern }) => {
639
+ const isPatternDemo = isPattern === 'true';
640
+ const slug = isPatternDemo ? component : toKebabCase(component);
641
+ const demoDir = isPatternDemo ? `patterns/${slug}` : slug;
642
+ const demoPath = `apps/website/demo/${demoDir}/${demoName}.tsx`;
643
+ const desc = description || `Demonstrates the ${demoName.replace(/-/g, ' ')} state/variant.`;
644
+ // Look up component info for imports
645
+ const comp = isPatternDemo ? null : store.getComponent(component);
646
+ const packageName = comp ? comp.package : '@redsift/design-system';
647
+ return {
648
+ messages: [
649
+ {
650
+ role: 'user',
651
+ content: {
652
+ type: 'text',
653
+ text: `Create a demo file for **${component}** — **${demoName}**.
654
+
655
+ ## Demo Details
656
+
657
+ - **Component:** ${component}
658
+ - **Demo name:** ${demoName}
659
+ - **File:** \`${demoPath}\`
660
+ - **Description:** ${desc}
661
+ - **Package:** ${packageName}
662
+
663
+ ## Template
664
+
665
+ \`\`\`tsx
666
+ import React from 'react';
667
+ import { ${isPatternDemo ? '/* components */' : component} } from '${packageName}';
668
+
669
+ export default () => (
670
+ // TODO: implement the ${demoName.replace(/-/g, ' ')} demo
671
+ <${isPatternDemo ? 'div' : component}>Example</${isPatternDemo ? 'div' : component}>
672
+ );
673
+ \`\`\`
674
+
675
+ ## Conventions
676
+
677
+ 1. **Default export** — every demo MUST use a default export (arrow function or named function)
678
+ 2. **Self-contained** — demos should not share utilities or state with other demo files
679
+ 3. **Import from packages** — use \`import { X } from '${packageName}'\`, not source paths
680
+ 4. **Clean code** — the source is shown in the "Show Code" panel, keep it readable
681
+ 5. **No data fetching** — use hardcoded mock data
682
+ 6. **Layout** — wrap multiple items in \`<Flexbox>\` with appropriate gap and direction
683
+ 7. **Props from DemoBlock** — the demo receives \`isScreenSmall: boolean\` and \`theme: Theme\` as props (use if needed)
684
+
685
+ ## MDX Reference
686
+
687
+ After creating the demo file, reference it in the MDX page:
688
+
689
+ \`\`\`mdx
690
+ <DemoBlock withThemeSwitcher path="${demoDir}/${demoName}" />
691
+ \`\`\`
692
+
693
+ ## Verification
694
+
695
+ 1. Run \`yarn dev:website\`
696
+ 2. Navigate to the component/pattern page
697
+ 3. Confirm the demo renders (not a stuck spinner)
698
+ 4. Toggle the code viewer and verify the source looks clean`,
699
+ },
700
+ },
701
+ ],
702
+ };
703
+ });
704
+ }
705
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
706
+ function toKebabCase(str) {
707
+ return str
708
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
709
+ .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
710
+ .toLowerCase();
711
+ }
712
+ function capitalize(str) {
713
+ return str.charAt(0).toUpperCase() + str.slice(1);
714
+ }
715
+ /**
716
+ * Determine if a prop should use a transient ($-prefixed) styled prop.
717
+ * Visual/styling props need transient props; event handlers and refs don't.
718
+ */
719
+ function shouldBeTransient(propName) {
720
+ // Event handlers, refs, and children don't need transient props
721
+ if (propName.startsWith('on') || propName === 'ref' || propName === 'children') {
722
+ return false;
723
+ }
724
+ // Common visual props
725
+ const visualProps = [
726
+ 'variant',
727
+ 'size',
728
+ 'color',
729
+ 'disabled',
730
+ 'isDisabled',
731
+ 'isLoading',
732
+ 'isActive',
733
+ 'isOpen',
734
+ 'isSelected',
735
+ 'fullWidth',
736
+ 'align',
737
+ 'direction',
738
+ 'orientation',
739
+ 'placement',
740
+ 'appearance',
741
+ ];
742
+ if (visualProps.includes(propName))
743
+ return true;
744
+ // Default to transient for non-standard HTML attributes
745
+ return propName.startsWith('is') || propName.startsWith('has');
746
+ }
747
+ function getExampleValue(type, defaultValue) {
748
+ if (defaultValue)
749
+ return defaultValue;
750
+ if (type === 'boolean')
751
+ return 'true';
752
+ if (type === 'string')
753
+ return '"example"';
754
+ if (type === 'number')
755
+ return '42';
756
+ if (type.includes('|')) {
757
+ const first = type.split('|')[0].trim().replace(/['"]/g, '');
758
+ return `"${first}"`;
759
+ }
760
+ return 'undefined';
761
+ }
762
+ //# sourceMappingURL=prompts.js.map