@calibrate-ds/cli 0.1.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 (201) hide show
  1. package/dist/__tests__/component-slug.test.d.ts +2 -0
  2. package/dist/__tests__/component-slug.test.d.ts.map +1 -0
  3. package/dist/__tests__/component-slug.test.js +54 -0
  4. package/dist/__tests__/component-slug.test.js.map +1 -0
  5. package/dist/__tests__/lock-changes.test.d.ts +2 -0
  6. package/dist/__tests__/lock-changes.test.d.ts.map +1 -0
  7. package/dist/__tests__/lock-changes.test.js +81 -0
  8. package/dist/__tests__/lock-changes.test.js.map +1 -0
  9. package/dist/__tests__/permissions.test.d.ts +2 -0
  10. package/dist/__tests__/permissions.test.d.ts.map +1 -0
  11. package/dist/__tests__/permissions.test.js +67 -0
  12. package/dist/__tests__/permissions.test.js.map +1 -0
  13. package/dist/__tests__/stamp-in-lock.test.d.ts +2 -0
  14. package/dist/__tests__/stamp-in-lock.test.d.ts.map +1 -0
  15. package/dist/__tests__/stamp-in-lock.test.js +102 -0
  16. package/dist/__tests__/stamp-in-lock.test.js.map +1 -0
  17. package/dist/__tests__/status-logic.test.d.ts +2 -0
  18. package/dist/__tests__/status-logic.test.d.ts.map +1 -0
  19. package/dist/__tests__/status-logic.test.js +74 -0
  20. package/dist/__tests__/status-logic.test.js.map +1 -0
  21. package/dist/__tests__/team-roster.test.d.ts +2 -0
  22. package/dist/__tests__/team-roster.test.d.ts.map +1 -0
  23. package/dist/__tests__/team-roster.test.js +97 -0
  24. package/dist/__tests__/team-roster.test.js.map +1 -0
  25. package/dist/ai/claude-provider.d.ts +13 -0
  26. package/dist/ai/claude-provider.d.ts.map +1 -0
  27. package/dist/ai/claude-provider.js +335 -0
  28. package/dist/ai/claude-provider.js.map +1 -0
  29. package/dist/ai/enhance-doc.d.ts +24 -0
  30. package/dist/ai/enhance-doc.d.ts.map +1 -0
  31. package/dist/ai/enhance-doc.js +272 -0
  32. package/dist/ai/enhance-doc.js.map +1 -0
  33. package/dist/ai/openai-provider.d.ts +13 -0
  34. package/dist/ai/openai-provider.d.ts.map +1 -0
  35. package/dist/ai/openai-provider.js +345 -0
  36. package/dist/ai/openai-provider.js.map +1 -0
  37. package/dist/ai/prompt-utils.d.ts +23 -0
  38. package/dist/ai/prompt-utils.d.ts.map +1 -0
  39. package/dist/ai/prompt-utils.js +67 -0
  40. package/dist/ai/prompt-utils.js.map +1 -0
  41. package/dist/commands/ai.d.ts +8 -0
  42. package/dist/commands/ai.d.ts.map +1 -0
  43. package/dist/commands/ai.js +576 -0
  44. package/dist/commands/ai.js.map +1 -0
  45. package/dist/commands/apply.d.ts +4 -0
  46. package/dist/commands/apply.d.ts.map +1 -0
  47. package/dist/commands/apply.js +98 -0
  48. package/dist/commands/apply.js.map +1 -0
  49. package/dist/commands/assign.d.ts +5 -0
  50. package/dist/commands/assign.d.ts.map +1 -0
  51. package/dist/commands/assign.js +180 -0
  52. package/dist/commands/assign.js.map +1 -0
  53. package/dist/commands/ci.d.ts +4 -0
  54. package/dist/commands/ci.d.ts.map +1 -0
  55. package/dist/commands/ci.js +84 -0
  56. package/dist/commands/ci.js.map +1 -0
  57. package/dist/commands/context.d.ts +19 -0
  58. package/dist/commands/context.d.ts.map +1 -0
  59. package/dist/commands/context.js +297 -0
  60. package/dist/commands/context.js.map +1 -0
  61. package/dist/commands/diff.d.ts +2 -0
  62. package/dist/commands/diff.d.ts.map +1 -0
  63. package/dist/commands/diff.js +119 -0
  64. package/dist/commands/diff.js.map +1 -0
  65. package/dist/commands/doctor.d.ts +5 -0
  66. package/dist/commands/doctor.d.ts.map +1 -0
  67. package/dist/commands/doctor.js +348 -0
  68. package/dist/commands/doctor.js.map +1 -0
  69. package/dist/commands/document-system.d.ts +5 -0
  70. package/dist/commands/document-system.d.ts.map +1 -0
  71. package/dist/commands/document-system.js +84 -0
  72. package/dist/commands/document-system.js.map +1 -0
  73. package/dist/commands/document.d.ts +6 -0
  74. package/dist/commands/document.d.ts.map +1 -0
  75. package/dist/commands/document.js +276 -0
  76. package/dist/commands/document.js.map +1 -0
  77. package/dist/commands/export.d.ts +11 -0
  78. package/dist/commands/export.d.ts.map +1 -0
  79. package/dist/commands/export.js +74 -0
  80. package/dist/commands/export.js.map +1 -0
  81. package/dist/commands/generate-components.d.ts +4 -0
  82. package/dist/commands/generate-components.d.ts.map +1 -0
  83. package/dist/commands/generate-components.js +62 -0
  84. package/dist/commands/generate-components.js.map +1 -0
  85. package/dist/commands/generate-composites.d.ts +2 -0
  86. package/dist/commands/generate-composites.d.ts.map +1 -0
  87. package/dist/commands/generate-composites.js +31 -0
  88. package/dist/commands/generate-composites.js.map +1 -0
  89. package/dist/commands/generate-tokens.d.ts +2 -0
  90. package/dist/commands/generate-tokens.d.ts.map +1 -0
  91. package/dist/commands/generate-tokens.js +48 -0
  92. package/dist/commands/generate-tokens.js.map +1 -0
  93. package/dist/commands/help-topics.d.ts +2 -0
  94. package/dist/commands/help-topics.d.ts.map +1 -0
  95. package/dist/commands/help-topics.js +324 -0
  96. package/dist/commands/help-topics.js.map +1 -0
  97. package/dist/commands/implement.d.ts +5 -0
  98. package/dist/commands/implement.d.ts.map +1 -0
  99. package/dist/commands/implement.js +595 -0
  100. package/dist/commands/implement.js.map +1 -0
  101. package/dist/commands/import-tokens.d.ts +2 -0
  102. package/dist/commands/import-tokens.d.ts.map +1 -0
  103. package/dist/commands/import-tokens.js +42 -0
  104. package/dist/commands/import-tokens.js.map +1 -0
  105. package/dist/commands/init.d.ts +6 -0
  106. package/dist/commands/init.d.ts.map +1 -0
  107. package/dist/commands/init.js +410 -0
  108. package/dist/commands/init.js.map +1 -0
  109. package/dist/commands/inspect-component.d.ts +2 -0
  110. package/dist/commands/inspect-component.d.ts.map +1 -0
  111. package/dist/commands/inspect-component.js +146 -0
  112. package/dist/commands/inspect-component.js.map +1 -0
  113. package/dist/commands/log.d.ts +4 -0
  114. package/dist/commands/log.d.ts.map +1 -0
  115. package/dist/commands/log.js +109 -0
  116. package/dist/commands/log.js.map +1 -0
  117. package/dist/commands/onboarding.d.ts +9 -0
  118. package/dist/commands/onboarding.d.ts.map +1 -0
  119. package/dist/commands/onboarding.js +63 -0
  120. package/dist/commands/onboarding.js.map +1 -0
  121. package/dist/commands/plan.d.ts +3 -0
  122. package/dist/commands/plan.d.ts.map +1 -0
  123. package/dist/commands/plan.js +108 -0
  124. package/dist/commands/plan.js.map +1 -0
  125. package/dist/commands/prompt.d.ts +5 -0
  126. package/dist/commands/prompt.d.ts.map +1 -0
  127. package/dist/commands/prompt.js +77 -0
  128. package/dist/commands/prompt.js.map +1 -0
  129. package/dist/commands/prune.d.ts +2 -0
  130. package/dist/commands/prune.d.ts.map +1 -0
  131. package/dist/commands/prune.js +95 -0
  132. package/dist/commands/prune.js.map +1 -0
  133. package/dist/commands/remove.d.ts +2 -0
  134. package/dist/commands/remove.d.ts.map +1 -0
  135. package/dist/commands/remove.js +76 -0
  136. package/dist/commands/remove.js.map +1 -0
  137. package/dist/commands/scaffold.d.ts +2 -0
  138. package/dist/commands/scaffold.d.ts.map +1 -0
  139. package/dist/commands/scaffold.js +47 -0
  140. package/dist/commands/scaffold.js.map +1 -0
  141. package/dist/commands/scan.d.ts +2 -0
  142. package/dist/commands/scan.d.ts.map +1 -0
  143. package/dist/commands/scan.js +91 -0
  144. package/dist/commands/scan.js.map +1 -0
  145. package/dist/commands/stamp.d.ts +11 -0
  146. package/dist/commands/stamp.d.ts.map +1 -0
  147. package/dist/commands/stamp.js +147 -0
  148. package/dist/commands/stamp.js.map +1 -0
  149. package/dist/commands/status.d.ts +7 -0
  150. package/dist/commands/status.d.ts.map +1 -0
  151. package/dist/commands/status.js +219 -0
  152. package/dist/commands/status.js.map +1 -0
  153. package/dist/commands/team.d.ts +7 -0
  154. package/dist/commands/team.d.ts.map +1 -0
  155. package/dist/commands/team.js +173 -0
  156. package/dist/commands/team.js.map +1 -0
  157. package/dist/index.d.ts +3 -0
  158. package/dist/index.d.ts.map +1 -0
  159. package/dist/index.js +303 -0
  160. package/dist/index.js.map +1 -0
  161. package/dist/onboarding/content.d.ts +39 -0
  162. package/dist/onboarding/content.d.ts.map +1 -0
  163. package/dist/onboarding/content.js +82 -0
  164. package/dist/onboarding/content.js.map +1 -0
  165. package/dist/utils/component-slug.d.ts +10 -0
  166. package/dist/utils/component-slug.d.ts.map +1 -0
  167. package/dist/utils/component-slug.js +13 -0
  168. package/dist/utils/component-slug.js.map +1 -0
  169. package/dist/utils/framework-registry.d.ts +41 -0
  170. package/dist/utils/framework-registry.d.ts.map +1 -0
  171. package/dist/utils/framework-registry.js +82 -0
  172. package/dist/utils/framework-registry.js.map +1 -0
  173. package/dist/utils/gitignore.d.ts +4 -0
  174. package/dist/utils/gitignore.d.ts.map +1 -0
  175. package/dist/utils/gitignore.js +67 -0
  176. package/dist/utils/gitignore.js.map +1 -0
  177. package/dist/utils/lock-changes.d.ts +14 -0
  178. package/dist/utils/lock-changes.d.ts.map +1 -0
  179. package/dist/utils/lock-changes.js +26 -0
  180. package/dist/utils/lock-changes.js.map +1 -0
  181. package/dist/utils/logger.d.ts +9 -0
  182. package/dist/utils/logger.d.ts.map +1 -0
  183. package/dist/utils/logger.js +32 -0
  184. package/dist/utils/logger.js.map +1 -0
  185. package/dist/utils/permissions.d.ts +17 -0
  186. package/dist/utils/permissions.d.ts.map +1 -0
  187. package/dist/utils/permissions.js +37 -0
  188. package/dist/utils/permissions.js.map +1 -0
  189. package/dist/utils/status-logic.d.ts +16 -0
  190. package/dist/utils/status-logic.d.ts.map +1 -0
  191. package/dist/utils/status-logic.js +32 -0
  192. package/dist/utils/status-logic.js.map +1 -0
  193. package/dist/utils/storybook-setup.d.ts +5 -0
  194. package/dist/utils/storybook-setup.d.ts.map +1 -0
  195. package/dist/utils/storybook-setup.js +104 -0
  196. package/dist/utils/storybook-setup.js.map +1 -0
  197. package/dist/utils/team-roster.d.ts +35 -0
  198. package/dist/utils/team-roster.d.ts.map +1 -0
  199. package/dist/utils/team-roster.js +99 -0
  200. package/dist/utils/team-roster.js.map +1 -0
  201. package/package.json +44 -0
@@ -0,0 +1,13 @@
1
+ import type { ImplementationProvider, ComponentImplementationResult, ComponentPromptPackage } from "@calibrate-ds/shared-types";
2
+ export declare class OpenAIProvider implements ImplementationProvider {
3
+ name: string;
4
+ private client;
5
+ private model;
6
+ constructor(apiKey: string, model?: string);
7
+ implementComponent(params: {
8
+ componentName: string;
9
+ framework: string | null;
10
+ promptPackage: ComponentPromptPackage;
11
+ }): Promise<ComponentImplementationResult>;
12
+ }
13
+ //# sourceMappingURL=openai-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../src/ai/openai-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,sBAAsB,EAAiB,MAAM,4BAA4B,CAAC;AA+S/I,qBAAa,cAAe,YAAW,sBAAsB;IACzD,IAAI,SAAY;IAChB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,MAAM,EAAE,MAAM,EAAE,KAAK,SAAW;IAKtC,kBAAkB,CAAC,MAAM,EAAE;QAC7B,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,aAAa,EAAE,sBAAsB,CAAC;KACzC,GAAG,OAAO,CAAC,6BAA6B,CAAC;CAgD7C"}
@@ -0,0 +1,345 @@
1
+ import OpenAI from "openai";
2
+ import { calcMaxTokens, buildUserMessage, formatTokenUsage } from "./prompt-utils.js";
3
+ const SYSTEM_PROMPT = `You are a design system component implementation assistant working inside PTB (Calibrate).
4
+
5
+ You receive a structured design context document describing a component extracted directly from Figma. Your job is to implement the component files that bring this design to life in code.
6
+
7
+ The examples below use React/JSX syntax. If the context specifies a different framework, apply the same principles using that framework's equivalent patterns.
8
+
9
+ ## Rules
10
+
11
+ 1. Call the write_file function for EVERY file you generate. Do not output prose or fenced code blocks — function calls only.
12
+ 2. You MUST generate ALL FOUR of these files, no exceptions:
13
+ - <ComponentName>.<ext> — the component implementation
14
+ - <ComponentName>.types.ts — TypeScript prop types
15
+ - <ComponentName>.module.css — CSS module styles (generate an empty file if the component truly has no styles)
16
+ - index.ts — barrel export (always required, even if it is a single re-export line)
17
+ Before writing the last file, verify:
18
+ - [ ] The component file imports the Props type: \`import type { ComponentNameProps } from './ComponentName.types';\`
19
+ - [ ] Every \`[Class: X]\` annotation in the render structure is applied as a plain utility string (never a CSS module key)
20
+ - [ ] No \`display: none\` in CSS for elements already handled by a JS conditional in the template
21
+ - [ ] No fixed \`height: Npx\` on any element that wraps text content
22
+ - [ ] Dependency props match the \`Accepted props\` list in the context — no invented prop names, defaults match \`/* default: X */\` annotations
23
+ - [ ] Conditional rendering wraps ONLY the node at the specified path, not all instances of that component type
24
+ - [ ] Every prop in the Props Interface Skeleton is destructured in the function signature — no props silently dropped
25
+ 3. Implement ONLY what the design context specifies:
26
+ - Variant axes → prop union types (these are PROPS, not useState)
27
+ - Token bindings → CSS custom properties (use the resolved variable names from the context)
28
+ - State contract → conditional class logic driven by a prop or controlled state
29
+ - Interaction contract → event handler stubs
30
+ - Layout → flex/grid CSS matching direction, gap, padding from context
31
+ - Size → CSS classes, never inline style={{ width, height }}
32
+ 4. Do NOT invent business logic, API calls, or application state.
33
+ 5. Do NOT add features absent from the design context.
34
+ 6. Follow the framework and naming conventions specified in the prompt.
35
+ 7. Never reference hardcoded colour values — always use the CSS custom properties from the token bindings.
36
+
37
+ ## Anti-patterns — never do these
38
+
39
+ **1. Variant axes are props, not state:**
40
+ \`\`\`tsx
41
+ // WRONG — variant axes from the design context are never local state
42
+ const [variant, setVariant] = useState<'primary' | 'secondary'>('primary');
43
+ // RIGHT — receive as a prop with the Figma default as the default value
44
+ function Component({ variant = 'primary' }: ComponentProps) { ... }
45
+ \`\`\`
46
+
47
+ **2. CSS modules must be imported as an object, not as a side-effect:**
48
+ \`\`\`tsx
49
+ // WRONG — side-effect import; className string has no scoping
50
+ import './Component.module.css';
51
+ className="root"
52
+ // RIGHT — named import gives you the scoped class map
53
+ import styles from './Component.module.css';
54
+ className={styles.root}
55
+ \`\`\`
56
+
57
+ **3. Import every component you render — never use an undeclared identifier:**
58
+ \`\`\`tsx
59
+ // WRONG — renders <SubComponent /> without importing it; runtime error
60
+ // RIGHT
61
+ import { SubComponent } from '../sub-component/index.js';
62
+ \`\`\`
63
+
64
+ **4. Never inline pixel dimensions from the context — put them in CSS:**
65
+ \`\`\`tsx
66
+ // WRONG — inline styles bypass the CSS module and are hard to override
67
+ <div style={{ width: 320, height: 48 }}>
68
+ // RIGHT — dimensions belong in the CSS module
69
+ .root { width: 320px; height: 48px; }
70
+ \`\`\`
71
+
72
+ **5. Never pass a Figma metadata object as a prop:**
73
+ \`\`\`tsx
74
+ // WRONG — slot values in the context are design descriptions, not runtime values
75
+ <Component iconSlot={{ kind: 'unknown', componentId: '123:456' }} />
76
+ // RIGHT — render the actual resolved component in JSX
77
+ <IconComponent />
78
+ \`\`\`
79
+
80
+ **6. Pass sub-component dependencies as named slot props, not as children:**
81
+ \`\`\`tsx
82
+ // WRONG — passing as children only works if the component explicitly renders {children}
83
+ <ParentComponent><IconComponent /></ParentComponent>
84
+ // RIGHT — use the named slot prop defined in the Slot Contract
85
+ <ParentComponent icon={<IconComponent />} />
86
+ \`\`\`
87
+
88
+ **7. Never use heading tags (h1–h6) for non-heading content:**
89
+ \`\`\`tsx
90
+ // WRONG — labels, captions, and timestamps are not document headings
91
+ <h1>{label}</h1>
92
+ // RIGHT — use the semantically appropriate inline or block element
93
+ <span className={styles.label}>{label}</span>
94
+ <time className={styles.timestamp}>{timestamp}</time>
95
+ \`\`\`
96
+
97
+ **8. All props that have a Figma default must have a default value in code:**
98
+ \`\`\`tsx
99
+ // WRONG — prop with no default silently breaks the component when omitted
100
+ function Component({ label, value }: ComponentProps) { ... }
101
+ // RIGHT — mirror the Figma default so the component renders correctly in isolation
102
+ function Component({ label = 'Default label', value = '' }: ComponentProps) { ... }
103
+ \`\`\`
104
+
105
+ **9. Never use local state for anything driven by the design context:**
106
+ \`\`\`tsx
107
+ // WRONG — design-system variant axes are never local state
108
+ const [variant, setVariant] = useState('primary');
109
+ // WRONG — inventing a boolean flag for a slot that should be a ReactNode
110
+ function Component({ showIcon = false }: ComponentProps) { ... }
111
+ // RIGHT — receive variant axes and slot props directly; derive everything from props
112
+ function Component({ variant = 'primary', icon }: ComponentProps) { ... }
113
+ \`\`\`
114
+ Slot props (icons, sub-components) are ALWAYS \`ReactNode\` — never \`boolean\`.
115
+
116
+ **10. Never set a fixed height on a text or content container:**
117
+ \`\`\`css
118
+ /* WRONG — clips content when text reflows on the web */
119
+ .content { height: 80px; }
120
+ /* RIGHT — let the container grow with its content */
121
+ .content { min-height: 1.5em; } /* or omit height entirely */
122
+ \`\`\`
123
+ Figma fixes containers to their current content height. On the web, text reflows freely.
124
+ Use \`min-height\` or no height for any element that wraps text. Only apply a fixed \`height\`
125
+ to elements with a truly fixed visual footprint (icons, avatars, dividers, separators).
126
+
127
+ **11. A slot prop IS the element to render — never use its presence to select a hardcoded fallback:**
128
+ \`\`\`tsx
129
+ // WRONG — prop holds a ReactNode; treating it as a boolean selects a hardcoded component
130
+ const rendered = icon ? <DefaultIcon /> : null;
131
+ // RIGHT — render whatever was passed in
132
+ {icon}
133
+ // RIGHT — use the design default only as a fallback when nothing is passed
134
+ {icon ?? <DefaultIcon />}
135
+ \`\`\`
136
+ A slot prop named \`icon?: React.ReactNode\` is the element itself. The named component in the
137
+ context is the design tool's placeholder — use it as the \`??\` fallback, not the primary render.
138
+
139
+ **12. Never concatenate className with template literals — use a filtered join:**
140
+ \`\`\`tsx
141
+ // WRONG — produces "root undefined" when the optional className prop is not passed
142
+ className={\`\${styles.root} \${className}\`}
143
+ // RIGHT — filter removes falsy values before joining
144
+ className={[styles.root, className].filter(Boolean).join(' ')}
145
+ \`\`\`
146
+
147
+ **13. Never build dynamic class names from variant values — use data attributes:**
148
+ \`\`\`tsx
149
+ // WRONG — generates class names like "size-sm-status-active" that don't exist in the CSS module
150
+ const cls = \`size-\${size}-status-\${status}\`;
151
+ <div className={styles[cls]}>
152
+ // RIGHT — the CSS skeleton uses [data-*] attribute selectors; wire props to data attributes
153
+ <div
154
+ className={styles.root}
155
+ data-size={size}
156
+ data-status={status}
157
+ >
158
+ \`\`\`
159
+ The CSS skeleton already has \`.root[data-size="sm"] { ... }\` — connect props via \`data-*\`, never via dynamic class names.
160
+
161
+ **14. Always import the component's Props type from its .types file:**
162
+ \`\`\`tsx
163
+ // WRONG — type identifier is used but not imported → TypeScript error
164
+ const MyComponent: React.FC<MyComponentProps> = ...
165
+ // RIGHT
166
+ import type { MyComponentProps } from './MyComponent.types';
167
+ const MyComponent: React.FC<MyComponentProps> = ...
168
+ \`\`\`
169
+ Every component has a \`<ComponentName>.types.ts\` file. Always import the Props type from it.
170
+
171
+ **15. A CSS module key lookup must contain exactly one key — never two class names in one string:**
172
+ \`\`\`tsx
173
+ // WRONG — looks up a single key with a space in it; always resolves to undefined
174
+ className={styles['element-name utility-class']}
175
+ // RIGHT — look up the module key, then join utility classes separately as plain strings
176
+ className={[styles['element-name'], 'utility-class'].filter(Boolean).join(' ')}
177
+ \`\`\`
178
+ \`styles[key]\` is a single object property lookup. A space-separated string is one key, not two classes.
179
+
180
+ **16. CSS module keys containing a hyphen MUST use bracket notation — dot notation is a syntax error:**
181
+ \`\`\`tsx
182
+ // WRONG — "list-item" parses as "styles.list" minus "item" — JavaScript subtraction syntax error
183
+ className={styles.list-item}
184
+ // RIGHT — any key that is not a valid JS identifier requires bracket notation
185
+ className={styles['list-item']}
186
+ \`\`\`
187
+ Any CSS module key with a \`-\`, digit start, or reserved word must use \`styles['key']\`.
188
+
189
+ **17. A ReactNode slot prop is already an element — render it directly, never invoke it as a component:**
190
+ \`\`\`tsx
191
+ // WRONG — variable name in lowercase JSX is treated as a DOM element tag, not a component
192
+ {icon && <icon />}
193
+ // WRONG — the variable holds a ReactNode, not a constructor; calling it as a component is an error
194
+ {icon && <Icon />}
195
+ // RIGHT — a ReactNode renders as-is; undefined or null renders nothing
196
+ {icon}
197
+ \`\`\`
198
+ If the slot is optional, \`{prop}\` is the complete render expression — no boolean guard, no JSX invocation.
199
+ Never invent a paired \`showX: boolean\` alongside \`x: ReactNode\`. The presence or absence of the node IS the visibility control.
200
+
201
+ **18. Render structure \`[Class: X]\` tags are global utility classes — apply them as plain strings alongside the module class:**
202
+ \`\`\`tsx
203
+ // Context render structure: "Label node [Class: type-body-sm]"
204
+ // WRONG — drops the typography utility class entirely
205
+ <span className={styles['label']}>{text}</span>
206
+ // WRONG — tries to look up the utility class as a module key; always undefined
207
+ <span className={styles['label type-body-sm']}>{text}</span>
208
+ // RIGHT — module class handles component-specific styles; utility class handles typography
209
+ <span className={[styles['label'], 'type-body-sm'].filter(Boolean).join(' ')}>{text}</span>
210
+ \`\`\`
211
+ \`[Class: X]\` in the render structure is a global utility class (e.g. from \`typography.css\`). It is NOT a CSS module key. Always apply it as a plain string entry in the class array.
212
+
213
+ **19. Nodes marked \`visible: false\` in a variant diff must be conditionally removed from the DOM:**
214
+ \`\`\`tsx
215
+ // Context variant diff: "sidebar node — visible: true → false in state=collapsed"
216
+ // WRONG — CSS display:none hides visually but the node is still in the DOM and still runs
217
+ <div className={styles.layout}>
218
+ <Sidebar />
219
+ </div>
220
+ // RIGHT — use a JS conditional so the node does not render at all in that state
221
+ <div className={styles.layout}>
222
+ {status !== 'collapsed' && <Sidebar />}
223
+ </div>
224
+ \`\`\`
225
+ When the variant diff shows \`visible: true → false\` for a node in a given state, use \`&&\` or a ternary to remove it entirely — do not rely only on CSS.
226
+
227
+ **20. When one of several instances of the same dependency is conditionally hidden, wrap ONLY that instance:**
228
+ \`\`\`tsx
229
+ // Context: two SubComponent instances — one always visible, one hidden in state=secondary
230
+ // WRONG — wraps both; nothing renders in 'secondary' state
231
+ {variant !== 'secondary' && <SubComponent type="icon" />}
232
+ {variant !== 'secondary' && <SubComponent label="Open" />}
233
+ // RIGHT — the Conditional Rendering Guide names the hidden SLOT (e.g. "cta");
234
+ // cross-reference the Slot Render Guide to find which specific instance it maps to
235
+ <SubComponent type="icon" /> {/* always rendered */}
236
+ {variant !== 'secondary' && <SubComponent label="Open" />} {/* 'cta' slot — hidden in secondary */}
237
+ \`\`\`
238
+ The Conditional Rendering Guide names SLOTS (e.g. \`/* hide slot: cta */\`), not component types.
239
+ Look up that slot in the Slot Render Guide to identify exactly which instance to wrap.
240
+ All other instances of the same component that are NOT named remain always-rendered.
241
+
242
+ **21. Always use named exports — never default exports:**
243
+ \`\`\`tsx
244
+ // WRONG — default exports break named imports used by every consumer of this component
245
+ export default function Component({ ... }: ComponentProps) { ... }
246
+ export default Component;
247
+
248
+ // RIGHT — named export so every import can use { Component }
249
+ export function Component({ ... }: ComponentProps) { ... }
250
+ // OR
251
+ export const Component: React.FC<ComponentProps> = ({ ... }) => { ... };
252
+ \`\`\`
253
+ The \`index.ts\` barrel must also re-export named:
254
+ \`\`\`ts
255
+ // WRONG
256
+ export { default } from './Component.js';
257
+ // RIGHT
258
+ export { Component } from './Component.js';
259
+ \`\`\`
260
+
261
+ **22. \`data-state\` only exists on the root container — child overrides must use descendant selectors:**
262
+ \`\`\`css
263
+ /* WRONG — data-state is not on .sidebar; this selector never matches */
264
+ .sidebar[data-state="collapsed"] { width: 0; }
265
+
266
+ /* RIGHT — data-state lives on .container; use descendant selector */
267
+ .container[data-state="collapsed"] .sidebar { width: 0; }
268
+ \`\`\`
269
+ Every state/variant attribute is set on the root element only. Any CSS overrides for child elements
270
+ in a given state must be written as \`.container[data-X="Y"] .child\`, never \`.child[data-X="Y"]\`.
271
+ The CSS skeleton already shows the correct descendant-selector form — follow it exactly.`;
272
+ const WRITE_FILE_TOOL = {
273
+ type: "function",
274
+ function: {
275
+ name: "write_file",
276
+ description: "Write a generated implementation file for the component. Call this once per file.",
277
+ parameters: {
278
+ type: "object",
279
+ properties: {
280
+ path: {
281
+ type: "string",
282
+ description: "File path relative to the component folder, e.g. Button.tsx or Button.module.css"
283
+ },
284
+ content: {
285
+ type: "string",
286
+ description: "Full file content — no PTB_METADATA header needed, PTB adds that automatically"
287
+ }
288
+ },
289
+ required: ["path", "content"]
290
+ }
291
+ }
292
+ };
293
+ // GPT-5.x and o-series reasoning models use max_completion_tokens instead of max_tokens.
294
+ function tokenLimitParam(model, value) {
295
+ return /^(gpt-5|o1|o3|o4)/.test(model)
296
+ ? { max_completion_tokens: value }
297
+ : { max_tokens: value };
298
+ }
299
+ export class OpenAIProvider {
300
+ name = "OpenAI";
301
+ client;
302
+ model;
303
+ constructor(apiKey, model = "gpt-4o") {
304
+ this.client = new OpenAI({ apiKey });
305
+ this.model = model;
306
+ }
307
+ async implementComponent(params) {
308
+ const { componentName, framework, promptPackage } = params;
309
+ const response = await this.client.chat.completions.create({
310
+ model: this.model,
311
+ ...tokenLimitParam(this.model, calcMaxTokens(promptPackage)),
312
+ tools: [WRITE_FILE_TOOL],
313
+ tool_choice: "auto",
314
+ messages: [
315
+ { role: "system", content: SYSTEM_PROMPT },
316
+ { role: "user", content: buildUserMessage(promptPackage, componentName, framework) }
317
+ ]
318
+ });
319
+ const usage = response.usage;
320
+ if (usage) {
321
+ console.log(formatTokenUsage(usage.prompt_tokens, usage.completion_tokens, usage.prompt_tokens_details?.cached_tokens ?? 0));
322
+ }
323
+ const files = [];
324
+ const toolCalls = response.choices[0]?.message?.tool_calls ?? [];
325
+ for (const call of toolCalls) {
326
+ if (call.type === "function" && call.function.name === "write_file") {
327
+ try {
328
+ const input = JSON.parse(call.function.arguments);
329
+ if (input.path && input.content !== undefined) {
330
+ files.push({ path: input.path, content: input.content });
331
+ }
332
+ }
333
+ catch {
334
+ // malformed tool call — skip
335
+ }
336
+ }
337
+ }
338
+ if (files.length === 0) {
339
+ throw new Error(`OpenAI returned no files for "${componentName}". ` +
340
+ `Finish reason: ${response.choices[0]?.finish_reason}. Check your API key and model access.`);
341
+ }
342
+ return { files };
343
+ }
344
+ }
345
+ //# sourceMappingURL=openai-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../src/ai/openai-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ComponentPromptPackage } from "@calibrate-ds/shared-types";
2
+ /**
3
+ * Calculates an appropriate max_tokens ceiling based on component complexity.
4
+ * Avoids reserving 8096 for components that only need ~2000 output tokens.
5
+ *
6
+ * Base 2048 covers 4 files at ~500 tokens each.
7
+ * Each structural feature adds headroom for the extra code it requires.
8
+ */
9
+ export declare function calcMaxTokens(pkg: ComponentPromptPackage): number;
10
+ /**
11
+ * Builds a compact user message from the prompt package.
12
+ *
13
+ * Two passes of trimming:
14
+ * 1. Strip "Structure Summary" — human-readable recap already covered by data sections below it.
15
+ * 2. Trim "Variant Differences" — for components with many variants this section dominates
16
+ * input tokens (can be 8k+ for 40+ variant combos). The AI doesn't need every structural
17
+ * diff to generate correct code — variant axes + token bindings are sufficient.
18
+ * We keep the first MAX_VARIANT_EXAMPLES as reference and replace the rest with a summary.
19
+ */
20
+ export declare function buildUserMessage(pkg: ComponentPromptPackage, componentName: string, framework: string | null): string;
21
+ /** Formats token usage for display after a generation call. */
22
+ export declare function formatTokenUsage(input: number, output: number, cached?: number): string;
23
+ //# sourceMappingURL=prompt-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-utils.d.ts","sourceRoot":"","sources":["../../src/ai/prompt-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEzE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,sBAAsB,GAAG,MAAM,CAajE;AAID;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC5B,GAAG,EAAE,sBAAsB,EAC3B,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAAG,IAAI,GACzB,MAAM,CA4BR;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAMvF"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Calculates an appropriate max_tokens ceiling based on component complexity.
3
+ * Avoids reserving 8096 for components that only need ~2000 output tokens.
4
+ *
5
+ * Base 2048 covers 4 files at ~500 tokens each.
6
+ * Each structural feature adds headroom for the extra code it requires.
7
+ */
8
+ export function calcMaxTokens(pkg) {
9
+ const s = pkg.structureSummary;
10
+ let max = 2048;
11
+ if (s?.hasVariants)
12
+ max += 512;
13
+ if (s?.hasStateContract)
14
+ max += 768;
15
+ if (s?.hasInteractionContract)
16
+ max += 512;
17
+ if (s?.hasPrototypeInteractionContract)
18
+ max += 512;
19
+ if (s?.hasTokenBindings)
20
+ max += 512;
21
+ if (s?.hasDependencies)
22
+ max += (s.dependencyCount ?? 1) * 256;
23
+ // Cap at 6144 — enough for complex components without over-reserving
24
+ return Math.min(max, 6144);
25
+ }
26
+ const MAX_VARIANT_EXAMPLES = 3;
27
+ /**
28
+ * Builds a compact user message from the prompt package.
29
+ *
30
+ * Two passes of trimming:
31
+ * 1. Strip "Structure Summary" — human-readable recap already covered by data sections below it.
32
+ * 2. Trim "Variant Differences" — for components with many variants this section dominates
33
+ * input tokens (can be 8k+ for 40+ variant combos). The AI doesn't need every structural
34
+ * diff to generate correct code — variant axes + token bindings are sufficient.
35
+ * We keep the first MAX_VARIANT_EXAMPLES as reference and replace the rest with a summary.
36
+ */
37
+ export function buildUserMessage(pkg, componentName, framework) {
38
+ // Pass 1: strip redundant Structure Summary section
39
+ let text = pkg.promptText.replace(/\n## Structure Summary\n(?:- .+\n)*/, "\n");
40
+ // Pass 2: trim Variant Differences to MAX_VARIANT_EXAMPLES + summary
41
+ text = text.replace(/(\n## Variant Differences\n)([\s\S]*?)(?=\n## [A-Z]|\n---|\s*$)/, (_match, header, body) => {
42
+ // Each variant block starts with "### Variant:"
43
+ const blocks = body.split(/(?=### Variant:)/).filter((b) => b.trim());
44
+ if (blocks.length <= MAX_VARIANT_EXAMPLES)
45
+ return header + body;
46
+ const kept = blocks.slice(0, MAX_VARIANT_EXAMPLES).join("");
47
+ const omitted = blocks.length - MAX_VARIANT_EXAMPLES;
48
+ const note = `\n> ${omitted} more variant combinations omitted. Implement all ${blocks.length} combinations using the Variant Axes and Token Bindings defined above.\n`;
49
+ return header + kept + note;
50
+ });
51
+ return [
52
+ `Implement component: **${componentName}**`,
53
+ `Framework: ${framework || "react"}`,
54
+ ``,
55
+ text.trimStart()
56
+ ].join("\n");
57
+ }
58
+ /** Formats token usage for display after a generation call. */
59
+ export function formatTokenUsage(input, output, cached) {
60
+ const dim = "\x1b[2m";
61
+ const reset = "\x1b[0m";
62
+ const parts = [`${input.toLocaleString()} in`, `${output.toLocaleString()} out`];
63
+ if (cached && cached > 0)
64
+ parts.push(`${cached.toLocaleString()} cached`);
65
+ return `${dim} ↳ tokens: ${parts.join(" | ")}${reset}`;
66
+ }
67
+ //# sourceMappingURL=prompt-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-utils.js","sourceRoot":"","sources":["../../src/ai/prompt-utils.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,GAA2B;IACrD,MAAM,CAAC,GAAG,GAAG,CAAC,gBAAgB,CAAC;IAC/B,IAAI,GAAG,GAAG,IAAI,CAAC;IAEf,IAAI,CAAC,EAAE,WAAW;QAAuB,GAAG,IAAI,GAAG,CAAC;IACpD,IAAI,CAAC,EAAE,gBAAgB;QAAkB,GAAG,IAAI,GAAG,CAAC;IACpD,IAAI,CAAC,EAAE,sBAAsB;QAAY,GAAG,IAAI,GAAG,CAAC;IACpD,IAAI,CAAC,EAAE,+BAA+B;QAAG,GAAG,IAAI,GAAG,CAAC;IACpD,IAAI,CAAC,EAAE,gBAAgB;QAAkB,GAAG,IAAI,GAAG,CAAC;IACpD,IAAI,CAAC,EAAE,eAAe;QAAmB,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;IAE/E,qEAAqE;IACrE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAC5B,GAA2B,EAC3B,aAAqB,EACrB,SAAwB;IAExB,oDAAoD;IACpD,IAAI,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,CAC7B,qCAAqC,EACrC,IAAI,CACP,CAAC;IAEF,qEAAqE;IACrE,IAAI,GAAG,IAAI,CAAC,OAAO,CACf,iEAAiE,EACjE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QACrB,gDAAgD;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,MAAM,IAAI,oBAAoB;YAAE,OAAO,MAAM,GAAG,IAAI,CAAC;QAEhE,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,oBAAoB,CAAC;QACrD,MAAM,IAAI,GAAG,OAAO,OAAO,qDAAqD,MAAM,CAAC,MAAM,0EAA0E,CAAC;QACxK,OAAO,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAChC,CAAC,CACJ,CAAC;IAEF,OAAO;QACH,0BAA0B,aAAa,IAAI;QAC3C,cAAc,SAAS,IAAI,OAAO,EAAE;QACpC,EAAE;QACF,IAAI,CAAC,SAAS,EAAE;KACnB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,MAAc,EAAE,MAAe;IAC3E,MAAM,GAAG,GAAI,SAAS,CAAC;IACvB,MAAM,KAAK,GAAG,SAAS,CAAC;IACxB,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,cAAc,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IACjF,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC1E,OAAO,GAAG,GAAG,eAAe,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function aiStatusCommand(): Promise<void>;
2
+ export declare function aiListCommand(): Promise<void>;
3
+ export declare function aiProvidersCommand(): Promise<void>;
4
+ export declare function aiUseCommand(provider: string): Promise<void>;
5
+ export declare function aiRemoveCommand(provider: string): Promise<void>;
6
+ export declare function aiModelCommand(modelId?: string): Promise<void>;
7
+ export declare function aiSetupCommand(): Promise<void>;
8
+ //# sourceMappingURL=ai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAyWA,wBAAsB,eAAe,kBA2GpC;AAID,wBAAsB,aAAa,kBA8BlC;AAID,wBAAsB,kBAAkB,kBAEvC;AAID,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,iBAyBlD;AAID,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,iBAyBrD;AAID,wBAAsB,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,iBA4EpD;AAID,wBAAsB,cAAc,kBAGnC"}