@buoy-design/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.
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +5 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands/__tests__/ci.test.d.ts +2 -0
- package/dist/commands/__tests__/ci.test.d.ts.map +1 -0
- package/dist/commands/__tests__/ci.test.js +33 -0
- package/dist/commands/__tests__/ci.test.js.map +1 -0
- package/dist/commands/bootstrap.d.ts +3 -0
- package/dist/commands/bootstrap.d.ts.map +1 -0
- package/dist/commands/bootstrap.js +458 -0
- package/dist/commands/bootstrap.js.map +1 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +314 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/ci.d.ts +24 -0
- package/dist/commands/ci.d.ts.map +1 -0
- package/dist/commands/ci.js +273 -0
- package/dist/commands/ci.js.map +1 -0
- package/dist/commands/ci.logic.d.ts +20 -0
- package/dist/commands/ci.logic.d.ts.map +1 -0
- package/dist/commands/ci.logic.js +28 -0
- package/dist/commands/ci.logic.js.map +1 -0
- package/dist/commands/drift.d.ts +3 -0
- package/dist/commands/drift.d.ts.map +1 -0
- package/dist/commands/drift.js +178 -0
- package/dist/commands/drift.js.map +1 -0
- package/dist/commands/index.d.ts +9 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +9 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +490 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/plugins.d.ts +3 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +72 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +266 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +205 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +67 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +1040 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +116 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/detect/frameworks.d.ts +18 -0
- package/dist/detect/frameworks.d.ts.map +1 -0
- package/dist/detect/frameworks.js +168 -0
- package/dist/detect/frameworks.js.map +1 -0
- package/dist/detect/index.d.ts +3 -0
- package/dist/detect/index.d.ts.map +1 -0
- package/dist/detect/index.js +3 -0
- package/dist/detect/index.js.map +1 -0
- package/dist/detect/project-detector.d.ts +61 -0
- package/dist/detect/project-detector.d.ts.map +1 -0
- package/dist/detect/project-detector.js +849 -0
- package/dist/detect/project-detector.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/output/formatters.d.ts +21 -0
- package/dist/output/formatters.d.ts.map +1 -0
- package/dist/output/formatters.js +421 -0
- package/dist/output/formatters.js.map +1 -0
- package/dist/output/index.d.ts +3 -0
- package/dist/output/index.d.ts.map +1 -0
- package/dist/output/index.js +3 -0
- package/dist/output/index.js.map +1 -0
- package/dist/output/reporters.d.ts +23 -0
- package/dist/output/reporters.d.ts.map +1 -0
- package/dist/output/reporters.js +147 -0
- package/dist/output/reporters.js.map +1 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +3 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/loader.d.ts +11 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +77 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/registry.d.ts +15 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +32 -0
- package/dist/plugins/registry.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { writeFileSync, existsSync, readFileSync, mkdirSync } from 'fs';
|
|
3
|
+
import { resolve, relative } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { spinner, success, error, info, header, newline } from '../output/reporters.js';
|
|
7
|
+
import { ProjectDetector } from '../detect/project-detector.js';
|
|
8
|
+
const STYLE_PRESETS = {
|
|
9
|
+
minimal: {
|
|
10
|
+
name: 'Minimal & Clean',
|
|
11
|
+
description: 'Subtle colors, generous whitespace, thin borders',
|
|
12
|
+
colors: { primary: '#0f172a', secondary: '#64748b', accent: '#3b82f6', neutral: '#f8fafc' },
|
|
13
|
+
borderRadius: '0.375rem',
|
|
14
|
+
spacing: 'spacious',
|
|
15
|
+
},
|
|
16
|
+
bold: {
|
|
17
|
+
name: 'Bold & Vibrant',
|
|
18
|
+
description: 'Strong colors, high contrast, prominent elements',
|
|
19
|
+
colors: { primary: '#7c3aed', secondary: '#ec4899', accent: '#f59e0b', neutral: '#1e1b4b' },
|
|
20
|
+
borderRadius: '0.75rem',
|
|
21
|
+
spacing: 'comfortable',
|
|
22
|
+
},
|
|
23
|
+
soft: {
|
|
24
|
+
name: 'Soft & Friendly',
|
|
25
|
+
description: 'Pastel tones, rounded corners, warm feel',
|
|
26
|
+
colors: { primary: '#6366f1', secondary: '#a78bfa', accent: '#f472b6', neutral: '#faf5ff' },
|
|
27
|
+
borderRadius: '1rem',
|
|
28
|
+
spacing: 'comfortable',
|
|
29
|
+
},
|
|
30
|
+
corporate: {
|
|
31
|
+
name: 'Corporate & Professional',
|
|
32
|
+
description: 'Conservative palette, structured layout, trust signals',
|
|
33
|
+
colors: { primary: '#1e40af', secondary: '#475569', accent: '#059669', neutral: '#f1f5f9' },
|
|
34
|
+
borderRadius: '0.25rem',
|
|
35
|
+
spacing: 'compact',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
const BUOY_CONFIG_DIR = resolve(homedir(), '.buoy');
|
|
39
|
+
const BUOY_CONFIG_FILE = resolve(BUOY_CONFIG_DIR, 'config.json');
|
|
40
|
+
function loadGlobalConfig() {
|
|
41
|
+
try {
|
|
42
|
+
if (existsSync(BUOY_CONFIG_FILE)) {
|
|
43
|
+
return JSON.parse(readFileSync(BUOY_CONFIG_FILE, 'utf-8'));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Ignore errors, return empty config
|
|
48
|
+
}
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
function saveGlobalConfig(config) {
|
|
52
|
+
if (!existsSync(BUOY_CONFIG_DIR)) {
|
|
53
|
+
mkdirSync(BUOY_CONFIG_DIR, { recursive: true });
|
|
54
|
+
}
|
|
55
|
+
writeFileSync(BUOY_CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
56
|
+
}
|
|
57
|
+
function getAnthropicApiKey() {
|
|
58
|
+
// Check environment variable first
|
|
59
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
60
|
+
return process.env.ANTHROPIC_API_KEY;
|
|
61
|
+
}
|
|
62
|
+
// Check global config
|
|
63
|
+
const config = loadGlobalConfig();
|
|
64
|
+
return config.anthropicApiKey || null;
|
|
65
|
+
}
|
|
66
|
+
export function createBuildCommand() {
|
|
67
|
+
const cmd = new Command('build')
|
|
68
|
+
.description('Generate a design system with AI (requires Anthropic API key)')
|
|
69
|
+
.option('--style <style>', 'Style preset: minimal, bold, soft, corporate')
|
|
70
|
+
.option('--primary-color <color>', 'Primary brand color (hex)')
|
|
71
|
+
.option('--framework <framework>', 'Target framework: react, vue, svelte, vanilla')
|
|
72
|
+
.option('--output <path>', 'Output directory', '.')
|
|
73
|
+
.option('--extend <file>', 'Extend existing token file')
|
|
74
|
+
.option('--set-key <key>', 'Set your Anthropic API key')
|
|
75
|
+
.action(async (options) => {
|
|
76
|
+
// Handle setting API key
|
|
77
|
+
if (options.setKey) {
|
|
78
|
+
const config = loadGlobalConfig();
|
|
79
|
+
config.anthropicApiKey = options.setKey;
|
|
80
|
+
saveGlobalConfig(config);
|
|
81
|
+
success('Anthropic API key saved to ~/.buoy/config.json');
|
|
82
|
+
info('You can now run: buoy build');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Check for API key
|
|
86
|
+
const apiKey = getAnthropicApiKey();
|
|
87
|
+
if (!apiKey) {
|
|
88
|
+
error('Anthropic API key not found');
|
|
89
|
+
console.log('');
|
|
90
|
+
info('Set your API key with one of these methods:');
|
|
91
|
+
console.log('');
|
|
92
|
+
console.log(chalk.cyan(' Option 1: ') + 'Environment variable');
|
|
93
|
+
console.log(chalk.dim(' export ANTHROPIC_API_KEY=sk-ant-...'));
|
|
94
|
+
console.log('');
|
|
95
|
+
console.log(chalk.cyan(' Option 2: ') + 'Save to Buoy config');
|
|
96
|
+
console.log(chalk.dim(' buoy build --set-key sk-ant-...'));
|
|
97
|
+
console.log('');
|
|
98
|
+
info('Get your API key at: https://console.anthropic.com/');
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const spin = spinner('Analyzing project...');
|
|
102
|
+
try {
|
|
103
|
+
const cwd = process.cwd();
|
|
104
|
+
// Detect project info
|
|
105
|
+
const detector = new ProjectDetector(cwd);
|
|
106
|
+
const projectInfo = await detector.detect();
|
|
107
|
+
// Determine framework
|
|
108
|
+
let framework = options.framework;
|
|
109
|
+
if (!framework && projectInfo.frameworks.length > 0) {
|
|
110
|
+
const f = projectInfo.frameworks[0];
|
|
111
|
+
framework = f.name;
|
|
112
|
+
spin.stop();
|
|
113
|
+
info(`Detected framework: ${chalk.cyan(f.name)}`);
|
|
114
|
+
spin.start();
|
|
115
|
+
}
|
|
116
|
+
framework = framework || 'vanilla';
|
|
117
|
+
// Determine style
|
|
118
|
+
const style = options.style || 'minimal';
|
|
119
|
+
const preset = STYLE_PRESETS[style] || STYLE_PRESETS.minimal;
|
|
120
|
+
spin.text = 'Generating design system with Claude...';
|
|
121
|
+
// Call Claude API
|
|
122
|
+
const designSystem = await generateDesignSystem(apiKey, {
|
|
123
|
+
framework,
|
|
124
|
+
style: preset,
|
|
125
|
+
primaryColor: options.primaryColor,
|
|
126
|
+
projectName: projectInfo.name,
|
|
127
|
+
existingTokens: options.extend ? loadExistingTokens(options.extend) : undefined,
|
|
128
|
+
});
|
|
129
|
+
spin.stop();
|
|
130
|
+
// Write output files
|
|
131
|
+
const outputDir = resolve(cwd, options.output);
|
|
132
|
+
header('Generated Design System');
|
|
133
|
+
newline();
|
|
134
|
+
// Write tokens.json
|
|
135
|
+
const tokensPath = resolve(outputDir, 'tokens.json');
|
|
136
|
+
writeFileSync(tokensPath, JSON.stringify(designSystem.tokens, null, 2));
|
|
137
|
+
success(`Created ${relative(cwd, tokensPath)}`);
|
|
138
|
+
// Write CSS variables
|
|
139
|
+
const cssPath = resolve(outputDir, 'tokens.css');
|
|
140
|
+
writeFileSync(cssPath, designSystem.css);
|
|
141
|
+
success(`Created ${relative(cwd, cssPath)}`);
|
|
142
|
+
// Write Tailwind config if applicable
|
|
143
|
+
if (framework === 'react' || framework === 'nextjs' || framework === 'vue' || framework === 'svelte') {
|
|
144
|
+
const tailwindPath = resolve(outputDir, 'tailwind.tokens.js');
|
|
145
|
+
writeFileSync(tailwindPath, designSystem.tailwind);
|
|
146
|
+
success(`Created ${relative(cwd, tailwindPath)}`);
|
|
147
|
+
}
|
|
148
|
+
newline();
|
|
149
|
+
info('Next steps:');
|
|
150
|
+
info(' 1. Review the generated tokens');
|
|
151
|
+
info(' 2. Import tokens.css in your app');
|
|
152
|
+
info(' 3. Run ' + chalk.cyan('buoy status') + ' to check alignment');
|
|
153
|
+
newline();
|
|
154
|
+
console.log(chalk.dim('💡 Tip: Run buoy build again to regenerate with different options'));
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
spin.stop();
|
|
158
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
159
|
+
error(`Build failed: ${message}`);
|
|
160
|
+
if (message.includes('401') || message.includes('authentication')) {
|
|
161
|
+
info('Your API key may be invalid. Check it at https://console.anthropic.com/');
|
|
162
|
+
}
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return cmd;
|
|
167
|
+
}
|
|
168
|
+
function loadExistingTokens(filePath) {
|
|
169
|
+
try {
|
|
170
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
171
|
+
return JSON.parse(content);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async function generateDesignSystem(apiKey, options) {
|
|
178
|
+
const prompt = buildPrompt(options);
|
|
179
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
180
|
+
method: 'POST',
|
|
181
|
+
headers: {
|
|
182
|
+
'Content-Type': 'application/json',
|
|
183
|
+
'x-api-key': apiKey,
|
|
184
|
+
'anthropic-version': '2023-06-01',
|
|
185
|
+
},
|
|
186
|
+
body: JSON.stringify({
|
|
187
|
+
model: 'claude-sonnet-4-20250514',
|
|
188
|
+
max_tokens: 4096,
|
|
189
|
+
messages: [
|
|
190
|
+
{
|
|
191
|
+
role: 'user',
|
|
192
|
+
content: prompt,
|
|
193
|
+
},
|
|
194
|
+
],
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
if (!response.ok) {
|
|
198
|
+
const errorBody = await response.text();
|
|
199
|
+
throw new Error(`Anthropic API error: ${response.status} - ${errorBody}`);
|
|
200
|
+
}
|
|
201
|
+
const data = await response.json();
|
|
202
|
+
const textContent = data.content.find(c => c.type === 'text');
|
|
203
|
+
if (!textContent?.text) {
|
|
204
|
+
throw new Error('No response from Claude');
|
|
205
|
+
}
|
|
206
|
+
// Parse the response to extract JSON blocks
|
|
207
|
+
return parseClaudeResponse(textContent.text);
|
|
208
|
+
}
|
|
209
|
+
function buildPrompt(options) {
|
|
210
|
+
const primaryColor = options.primaryColor || options.style.colors.primary;
|
|
211
|
+
return `You are a design system expert. Generate a complete design token system for a ${options.framework} project called "${options.projectName}".
|
|
212
|
+
|
|
213
|
+
Style: ${options.style.name}
|
|
214
|
+
Description: ${options.style.description}
|
|
215
|
+
Primary Color: ${primaryColor}
|
|
216
|
+
|
|
217
|
+
${options.existingTokens ? `Extend these existing tokens:\n${JSON.stringify(options.existingTokens, null, 2)}\n` : ''}
|
|
218
|
+
|
|
219
|
+
Generate a comprehensive design token system with:
|
|
220
|
+
1. Color palette (primary, secondary, accent, neutral, semantic colors like success/error/warning)
|
|
221
|
+
2. Typography scale (font sizes, line heights, font weights)
|
|
222
|
+
3. Spacing scale (consistent increments)
|
|
223
|
+
4. Border radii
|
|
224
|
+
5. Shadows
|
|
225
|
+
6. Breakpoints
|
|
226
|
+
|
|
227
|
+
Respond with exactly three code blocks:
|
|
228
|
+
|
|
229
|
+
\`\`\`json
|
|
230
|
+
{
|
|
231
|
+
"colors": { ... },
|
|
232
|
+
"typography": { ... },
|
|
233
|
+
"spacing": { ... },
|
|
234
|
+
"radii": { ... },
|
|
235
|
+
"shadows": { ... },
|
|
236
|
+
"breakpoints": { ... }
|
|
237
|
+
}
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
\`\`\`css
|
|
241
|
+
:root {
|
|
242
|
+
/* CSS variables here */
|
|
243
|
+
}
|
|
244
|
+
\`\`\`
|
|
245
|
+
|
|
246
|
+
\`\`\`javascript
|
|
247
|
+
// Tailwind theme extension
|
|
248
|
+
module.exports = {
|
|
249
|
+
theme: {
|
|
250
|
+
extend: { ... }
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
\`\`\`
|
|
254
|
+
|
|
255
|
+
Be thorough and include semantic color tokens for UI states. Use the primary color to derive a harmonious palette.`;
|
|
256
|
+
}
|
|
257
|
+
function parseClaudeResponse(response) {
|
|
258
|
+
// Extract JSON block
|
|
259
|
+
const jsonMatch = response.match(/```json\s*([\s\S]*?)```/);
|
|
260
|
+
const cssMatch = response.match(/```css\s*([\s\S]*?)```/);
|
|
261
|
+
const jsMatch = response.match(/```javascript\s*([\s\S]*?)```/) || response.match(/```js\s*([\s\S]*?)```/);
|
|
262
|
+
let tokens = {};
|
|
263
|
+
let css = '';
|
|
264
|
+
let tailwind = '';
|
|
265
|
+
if (jsonMatch?.[1]) {
|
|
266
|
+
try {
|
|
267
|
+
tokens = JSON.parse(jsonMatch[1].trim());
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Use empty tokens if parsing fails
|
|
271
|
+
tokens = { error: 'Failed to parse generated tokens' };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (cssMatch?.[1]) {
|
|
275
|
+
css = cssMatch[1].trim();
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
css = generateFallbackCss(tokens);
|
|
279
|
+
}
|
|
280
|
+
if (jsMatch?.[1]) {
|
|
281
|
+
tailwind = jsMatch[1].trim();
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
tailwind = generateFallbackTailwind(tokens);
|
|
285
|
+
}
|
|
286
|
+
return { tokens, css, tailwind };
|
|
287
|
+
}
|
|
288
|
+
function generateFallbackCss(tokens) {
|
|
289
|
+
const lines = ['/* Generated by buoy build */', ':root {'];
|
|
290
|
+
const flattenObject = (obj, prefix = '') => {
|
|
291
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
292
|
+
const varName = prefix ? `${prefix}-${key}` : key;
|
|
293
|
+
if (typeof value === 'object' && value !== null) {
|
|
294
|
+
flattenObject(value, varName);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
lines.push(` --${varName}: ${value};`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
flattenObject(tokens);
|
|
302
|
+
lines.push('}');
|
|
303
|
+
return lines.join('\n');
|
|
304
|
+
}
|
|
305
|
+
function generateFallbackTailwind(tokens) {
|
|
306
|
+
return `// Generated by buoy build
|
|
307
|
+
/** @type {import('tailwindcss').Config} */
|
|
308
|
+
module.exports = {
|
|
309
|
+
theme: {
|
|
310
|
+
extend: ${JSON.stringify(tokens, null, 4).replace(/\n/g, '\n ')}
|
|
311
|
+
}
|
|
312
|
+
};`;
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import type { Severity } from '@buoy-design/core';
|
|
3
|
+
export interface CIOutput {
|
|
4
|
+
version: string;
|
|
5
|
+
timestamp: string;
|
|
6
|
+
summary: {
|
|
7
|
+
total: number;
|
|
8
|
+
critical: number;
|
|
9
|
+
warning: number;
|
|
10
|
+
info: number;
|
|
11
|
+
};
|
|
12
|
+
topIssues: Array<{
|
|
13
|
+
type: string;
|
|
14
|
+
severity: Severity;
|
|
15
|
+
component: string;
|
|
16
|
+
message: string;
|
|
17
|
+
file?: string;
|
|
18
|
+
line?: number;
|
|
19
|
+
suggestion?: string;
|
|
20
|
+
}>;
|
|
21
|
+
exitCode: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function createCICommand(): Command;
|
|
24
|
+
//# sourceMappingURL=ci.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci.d.ts","sourceRoot":"","sources":["../../src/commands/ci.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,SAAS,EAAE,KAAK,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,QAAQ,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+DD,wBAAgB,eAAe,IAAI,OAAO,CAiLzC"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// apps/cli/src/commands/ci.ts
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { loadConfig, getConfigPath } from '../config/loader.js';
|
|
4
|
+
import { loadDiscoveredPlugins, registry } from '../plugins/index.js';
|
|
5
|
+
import { setJsonMode } from '../output/reporters.js';
|
|
6
|
+
const SEVERITY_ORDER = {
|
|
7
|
+
info: 0,
|
|
8
|
+
warning: 1,
|
|
9
|
+
critical: 2,
|
|
10
|
+
};
|
|
11
|
+
function validateGitHubOptions(options) {
|
|
12
|
+
const token = options.githubToken || process.env.GITHUB_TOKEN;
|
|
13
|
+
const repo = options.githubRepo || process.env.GITHUB_REPOSITORY;
|
|
14
|
+
const prInput = options.githubPr || process.env.GITHUB_PR_NUMBER;
|
|
15
|
+
// Validate token: must be non-empty if provided
|
|
16
|
+
if (token !== undefined && token.trim() === '') {
|
|
17
|
+
throw new Error('Invalid GitHub token: must be non-empty if provided.');
|
|
18
|
+
}
|
|
19
|
+
// Validate repo format: must be "owner/repo" with non-empty parts
|
|
20
|
+
if (repo !== undefined) {
|
|
21
|
+
const repoPattern = /^[^/]+\/[^/]+$/;
|
|
22
|
+
if (!repoPattern.test(repo)) {
|
|
23
|
+
throw new Error(`Invalid GitHub repo format: '${repo}'. Must be in 'owner/repo' format (e.g., 'facebook/react').`);
|
|
24
|
+
}
|
|
25
|
+
const [owner, repoName] = repo.split('/');
|
|
26
|
+
if (!owner || owner.trim() === '' || !repoName || repoName.trim() === '') {
|
|
27
|
+
throw new Error(`Invalid GitHub repo format: '${repo}'. Both owner and repo parts must be non-empty.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Validate PR number: must be a positive integer
|
|
31
|
+
let pr;
|
|
32
|
+
if (prInput !== undefined) {
|
|
33
|
+
const parsed = parseInt(prInput, 10);
|
|
34
|
+
if (isNaN(parsed) || parsed <= 0 || !Number.isInteger(parsed) || String(parsed) !== prInput.trim()) {
|
|
35
|
+
throw new Error(`Invalid PR number: '${prInput}'. Must be a positive integer.`);
|
|
36
|
+
}
|
|
37
|
+
pr = parsed;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
token: token?.trim(),
|
|
41
|
+
repo: repo?.trim(),
|
|
42
|
+
pr,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export function createCICommand() {
|
|
46
|
+
const cmd = new Command('ci')
|
|
47
|
+
.description('Run drift detection for CI environments')
|
|
48
|
+
.option('--fail-on <severity>', 'Exit 1 if drift at this severity or higher: critical, warning, info, none', 'critical')
|
|
49
|
+
.option('--format <format>', 'Output format: json, summary', 'json')
|
|
50
|
+
.option('--quiet', 'Suppress non-essential output')
|
|
51
|
+
.option('--top <n>', 'Number of top issues to include', '10')
|
|
52
|
+
.option('--github-token <token>', 'GitHub token for PR comments (or use GITHUB_TOKEN env)')
|
|
53
|
+
.option('--github-repo <repo>', 'GitHub repo in owner/repo format (or use GITHUB_REPOSITORY env)')
|
|
54
|
+
.option('--github-pr <number>', 'PR number to comment on (or use GITHUB_PR_NUMBER env)')
|
|
55
|
+
.action(async (options) => {
|
|
56
|
+
// Set JSON mode to ensure any reporter output goes to stderr
|
|
57
|
+
if (options.format === 'json') {
|
|
58
|
+
setJsonMode(true);
|
|
59
|
+
}
|
|
60
|
+
const log = options.quiet ? () => { } : console.error.bind(console);
|
|
61
|
+
try {
|
|
62
|
+
// Validate GitHub options early, before any scanning
|
|
63
|
+
const github = validateGitHubOptions(options);
|
|
64
|
+
// Check for config
|
|
65
|
+
if (!getConfigPath()) {
|
|
66
|
+
const output = {
|
|
67
|
+
version: '0.0.1',
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
summary: { total: 0, critical: 0, warning: 0, info: 0 },
|
|
70
|
+
topIssues: [],
|
|
71
|
+
exitCode: 0,
|
|
72
|
+
};
|
|
73
|
+
console.log(JSON.stringify(output, null, 2));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
log('Loading configuration...');
|
|
77
|
+
const { config } = await loadConfig();
|
|
78
|
+
log('Loading plugins...');
|
|
79
|
+
await loadDiscoveredPlugins({ projectRoot: process.cwd() });
|
|
80
|
+
log('Scanning for drift...');
|
|
81
|
+
// Import analysis modules
|
|
82
|
+
const { ReactComponentScanner } = await import('@buoy-design/scanners/git');
|
|
83
|
+
const { SemanticDiffEngine } = await import('@buoy-design/core/analysis');
|
|
84
|
+
// Scan components
|
|
85
|
+
const components = [];
|
|
86
|
+
// Determine which sources to scan from config
|
|
87
|
+
const sourcesToScan = [];
|
|
88
|
+
if (config.sources.react?.enabled)
|
|
89
|
+
sourcesToScan.push('react');
|
|
90
|
+
if (config.sources.vue?.enabled)
|
|
91
|
+
sourcesToScan.push('vue');
|
|
92
|
+
if (config.sources.svelte?.enabled)
|
|
93
|
+
sourcesToScan.push('svelte');
|
|
94
|
+
if (config.sources.angular?.enabled)
|
|
95
|
+
sourcesToScan.push('angular');
|
|
96
|
+
// Scan each source
|
|
97
|
+
for (const source of sourcesToScan) {
|
|
98
|
+
const plugin = registry.getByDetection(source);
|
|
99
|
+
if (plugin && plugin.scan) {
|
|
100
|
+
// Use plugin
|
|
101
|
+
const sourceConfig = config.sources[source];
|
|
102
|
+
const result = await plugin.scan({
|
|
103
|
+
projectRoot: process.cwd(),
|
|
104
|
+
config: sourceConfig || {},
|
|
105
|
+
include: sourceConfig?.include,
|
|
106
|
+
exclude: sourceConfig?.exclude,
|
|
107
|
+
});
|
|
108
|
+
components.push(...result.components);
|
|
109
|
+
if (result.errors && result.errors.length > 0) {
|
|
110
|
+
for (const err of result.errors) {
|
|
111
|
+
log(`[${source}] ${err.file || ''}: ${err.message}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// Fall back to bundled scanner
|
|
117
|
+
if (source === 'react' && config.sources.react) {
|
|
118
|
+
const scanner = new ReactComponentScanner({
|
|
119
|
+
projectRoot: process.cwd(),
|
|
120
|
+
include: config.sources.react.include,
|
|
121
|
+
exclude: config.sources.react.exclude,
|
|
122
|
+
designSystemPackage: config.sources.react.designSystemPackage,
|
|
123
|
+
});
|
|
124
|
+
const result = await scanner.scan();
|
|
125
|
+
components.push(...result.items);
|
|
126
|
+
}
|
|
127
|
+
// Add other framework fallbacks as needed
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Run semantic diff
|
|
131
|
+
const engine = new SemanticDiffEngine();
|
|
132
|
+
const diffResult = engine.analyzeComponents(components, {
|
|
133
|
+
checkDeprecated: true,
|
|
134
|
+
checkNaming: true,
|
|
135
|
+
checkDocumentation: true,
|
|
136
|
+
});
|
|
137
|
+
let drifts = diffResult.drifts;
|
|
138
|
+
// Apply ignore rules
|
|
139
|
+
for (const ignoreRule of config.drift.ignore) {
|
|
140
|
+
drifts = drifts.filter(d => {
|
|
141
|
+
if (d.type !== ignoreRule.type)
|
|
142
|
+
return true;
|
|
143
|
+
if (!ignoreRule.pattern)
|
|
144
|
+
return false;
|
|
145
|
+
const regex = new RegExp(ignoreRule.pattern);
|
|
146
|
+
return !regex.test(d.source.entityName);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
// Build output
|
|
150
|
+
const output = buildCIOutput(drifts, options);
|
|
151
|
+
// Post to GitHub if configured (using pre-validated values)
|
|
152
|
+
if (github.token && github.repo && github.pr) {
|
|
153
|
+
try {
|
|
154
|
+
const githubPlugin = registry.get('@buoy-design/plugin-github');
|
|
155
|
+
if (githubPlugin && githubPlugin.report) {
|
|
156
|
+
log('Posting to GitHub PR...');
|
|
157
|
+
const driftResult = {
|
|
158
|
+
signals: drifts.map(d => ({
|
|
159
|
+
type: d.type,
|
|
160
|
+
severity: d.severity,
|
|
161
|
+
message: d.message,
|
|
162
|
+
component: d.source.entityName,
|
|
163
|
+
file: d.source.location?.split(':')[0],
|
|
164
|
+
line: d.source.location?.includes(':')
|
|
165
|
+
? parseInt(d.source.location.split(':')[1] || '0', 10)
|
|
166
|
+
: undefined,
|
|
167
|
+
suggestion: d.details.suggestions?.[0],
|
|
168
|
+
})),
|
|
169
|
+
summary: {
|
|
170
|
+
total: drifts.length,
|
|
171
|
+
critical: drifts.filter(d => d.severity === 'critical').length,
|
|
172
|
+
warning: drifts.filter(d => d.severity === 'warning').length,
|
|
173
|
+
info: drifts.filter(d => d.severity === 'info').length,
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
await githubPlugin.report(driftResult, {
|
|
177
|
+
ci: true,
|
|
178
|
+
format: 'markdown',
|
|
179
|
+
github: {
|
|
180
|
+
token: github.token,
|
|
181
|
+
repo: github.repo,
|
|
182
|
+
pr: github.pr,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
log('Posted PR comment');
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
log('GitHub plugin not installed, skipping PR comment');
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
193
|
+
log(`Failed to post GitHub comment: ${msg}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (options.format === 'json') {
|
|
197
|
+
console.log(JSON.stringify(output, null, 2));
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
printSummary(output);
|
|
201
|
+
}
|
|
202
|
+
process.exit(output.exitCode);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
206
|
+
console.error(JSON.stringify({ error: message }, null, 2));
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
return cmd;
|
|
211
|
+
}
|
|
212
|
+
function buildCIOutput(drifts, options) {
|
|
213
|
+
const summary = {
|
|
214
|
+
total: drifts.length,
|
|
215
|
+
critical: drifts.filter(d => d.severity === 'critical').length,
|
|
216
|
+
warning: drifts.filter(d => d.severity === 'warning').length,
|
|
217
|
+
info: drifts.filter(d => d.severity === 'info').length,
|
|
218
|
+
};
|
|
219
|
+
// Sort by severity (critical first)
|
|
220
|
+
const sorted = [...drifts].sort((a, b) => SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity]);
|
|
221
|
+
const topN = parseInt(options.top, 10) || 10;
|
|
222
|
+
const topIssues = sorted.slice(0, topN).map(d => {
|
|
223
|
+
const locationParts = d.source.location?.split(':');
|
|
224
|
+
return {
|
|
225
|
+
type: d.type,
|
|
226
|
+
severity: d.severity,
|
|
227
|
+
component: d.source.entityName,
|
|
228
|
+
message: d.message,
|
|
229
|
+
file: locationParts?.[0],
|
|
230
|
+
line: locationParts?.[1] ? parseInt(locationParts[1], 10) : undefined,
|
|
231
|
+
suggestion: d.details.suggestions?.[0],
|
|
232
|
+
};
|
|
233
|
+
});
|
|
234
|
+
// Determine exit code
|
|
235
|
+
let exitCode = 0;
|
|
236
|
+
const failOn = options.failOn;
|
|
237
|
+
if (failOn !== 'none') {
|
|
238
|
+
const threshold = SEVERITY_ORDER[failOn] ?? SEVERITY_ORDER.critical;
|
|
239
|
+
const hasFailure = drifts.some(d => SEVERITY_ORDER[d.severity] >= threshold);
|
|
240
|
+
exitCode = hasFailure ? 1 : 0;
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
version: '0.0.1',
|
|
244
|
+
timestamp: new Date().toISOString(),
|
|
245
|
+
summary,
|
|
246
|
+
topIssues,
|
|
247
|
+
exitCode,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function printSummary(output) {
|
|
251
|
+
const icon = output.exitCode === 0 ? '✓' : '✗';
|
|
252
|
+
const status = output.exitCode === 0 ? 'PASS' : 'FAIL';
|
|
253
|
+
console.log(`${icon} Buoy Drift Check: ${status}`);
|
|
254
|
+
console.log('');
|
|
255
|
+
console.log(` Total: ${output.summary.total}`);
|
|
256
|
+
console.log(` Critical: ${output.summary.critical}`);
|
|
257
|
+
console.log(` Warning: ${output.summary.warning}`);
|
|
258
|
+
console.log(` Info: ${output.summary.info}`);
|
|
259
|
+
if (output.topIssues.length > 0) {
|
|
260
|
+
console.log('');
|
|
261
|
+
console.log('Top issues:');
|
|
262
|
+
for (const issue of output.topIssues.slice(0, 5)) {
|
|
263
|
+
const sev = issue.severity === 'critical' ? '!' :
|
|
264
|
+
issue.severity === 'warning' ? '~' : 'i';
|
|
265
|
+
const loc = issue.file ? ` (${issue.file}${issue.line ? `:${issue.line}` : ''})` : '';
|
|
266
|
+
console.log(` [${sev}] ${issue.component}: ${issue.message}${loc}`);
|
|
267
|
+
}
|
|
268
|
+
if (output.topIssues.length > 5) {
|
|
269
|
+
console.log(` ... and ${output.topIssues.length - 5} more`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
//# sourceMappingURL=ci.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ci.js","sourceRoot":"","sources":["../../src/commands/ci.ts"],"names":[],"mappings":"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"}
|