real-prototypes-skill 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/.claude/skills/agent-browser-skill/SKILL.md +252 -0
- package/.claude/skills/real-prototypes-skill/.gitignore +188 -0
- package/.claude/skills/real-prototypes-skill/ACCESSIBILITY.md +668 -0
- package/.claude/skills/real-prototypes-skill/INSTALL.md +259 -0
- package/.claude/skills/real-prototypes-skill/LICENSE +21 -0
- package/.claude/skills/real-prototypes-skill/PUBLISH.md +310 -0
- package/.claude/skills/real-prototypes-skill/QUICKSTART.md +240 -0
- package/.claude/skills/real-prototypes-skill/README.md +442 -0
- package/.claude/skills/real-prototypes-skill/SKILL.md +375 -0
- package/.claude/skills/real-prototypes-skill/capture/capture-engine.js +1153 -0
- package/.claude/skills/real-prototypes-skill/capture/config.schema.json +170 -0
- package/.claude/skills/real-prototypes-skill/cli.js +596 -0
- package/.claude/skills/real-prototypes-skill/docs/TROUBLESHOOTING.md +278 -0
- package/.claude/skills/real-prototypes-skill/docs/schemas/capture-config.md +167 -0
- package/.claude/skills/real-prototypes-skill/docs/schemas/design-tokens.md +183 -0
- package/.claude/skills/real-prototypes-skill/docs/schemas/manifest.md +169 -0
- package/.claude/skills/real-prototypes-skill/examples/CLAUDE.md.example +73 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/CLAUDE.md +136 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/FEATURES.md +222 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/README.md +82 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/references/design-tokens.json +87 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/references/screenshots/homepage-viewport.png +0 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/references/screenshots/prototype-chatbot-final.png +0 -0
- package/.claude/skills/real-prototypes-skill/examples/amazon-chatbot/references/screenshots/prototype-fullpage-v2.png +0 -0
- package/.claude/skills/real-prototypes-skill/references/accessibility-fixes.md +298 -0
- package/.claude/skills/real-prototypes-skill/references/accessibility-report.json +253 -0
- package/.claude/skills/real-prototypes-skill/scripts/CAPTURE-ENHANCEMENTS.md +344 -0
- package/.claude/skills/real-prototypes-skill/scripts/IMPLEMENTATION-SUMMARY.md +517 -0
- package/.claude/skills/real-prototypes-skill/scripts/QUICK-START.md +229 -0
- package/.claude/skills/real-prototypes-skill/scripts/QUICKSTART-layout-analysis.md +148 -0
- package/.claude/skills/real-prototypes-skill/scripts/README-analyze-layout.md +407 -0
- package/.claude/skills/real-prototypes-skill/scripts/analyze-layout.js +880 -0
- package/.claude/skills/real-prototypes-skill/scripts/capture-platform.js +203 -0
- package/.claude/skills/real-prototypes-skill/scripts/comprehensive-capture.js +597 -0
- package/.claude/skills/real-prototypes-skill/scripts/create-manifest.js +338 -0
- package/.claude/skills/real-prototypes-skill/scripts/enterprise-pipeline.js +428 -0
- package/.claude/skills/real-prototypes-skill/scripts/extract-tokens.js +468 -0
- package/.claude/skills/real-prototypes-skill/scripts/full-site-capture.js +738 -0
- package/.claude/skills/real-prototypes-skill/scripts/generate-tailwind-config.js +296 -0
- package/.claude/skills/real-prototypes-skill/scripts/integrate-accessibility.sh +161 -0
- package/.claude/skills/real-prototypes-skill/scripts/manifest-schema.json +302 -0
- package/.claude/skills/real-prototypes-skill/scripts/setup-prototype.sh +167 -0
- package/.claude/skills/real-prototypes-skill/scripts/test-analyze-layout.js +338 -0
- package/.claude/skills/real-prototypes-skill/scripts/test-validation.js +307 -0
- package/.claude/skills/real-prototypes-skill/scripts/validate-accessibility.js +598 -0
- package/.claude/skills/real-prototypes-skill/scripts/validate-manifest.js +499 -0
- package/.claude/skills/real-prototypes-skill/scripts/validate-output.js +361 -0
- package/.claude/skills/real-prototypes-skill/scripts/validate-prerequisites.js +319 -0
- package/.claude/skills/real-prototypes-skill/scripts/verify-layout-analysis.sh +77 -0
- package/.claude/skills/real-prototypes-skill/templates/dashboard-widget.tsx.template +91 -0
- package/.claude/skills/real-prototypes-skill/templates/data-table.tsx.template +193 -0
- package/.claude/skills/real-prototypes-skill/templates/form-section.tsx.template +250 -0
- package/.claude/skills/real-prototypes-skill/templates/modal-dialog.tsx.template +239 -0
- package/.claude/skills/real-prototypes-skill/templates/nav-item.tsx.template +265 -0
- package/.claude/skills/real-prototypes-skill/validation/validation-engine.js +559 -0
- package/.env.example +74 -0
- package/LICENSE +21 -0
- package/README.md +444 -0
- package/bin/cli.js +319 -0
- package/package.json +59 -0
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Platform Prototype CLI
|
|
5
|
+
*
|
|
6
|
+
* Enterprise-grade tool for capturing web platforms and generating prototypes.
|
|
7
|
+
*
|
|
8
|
+
* Commands:
|
|
9
|
+
* capture - Capture a web platform (screenshots, HTML, design tokens)
|
|
10
|
+
* validate - Validate capture or prototype
|
|
11
|
+
* generate - Generate prototype from capture
|
|
12
|
+
* pipeline - Run full capture-validate-generate pipeline
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
|
|
19
|
+
const SKILL_DIR = __dirname;
|
|
20
|
+
const PROJECTS_DIR = path.resolve(SKILL_DIR, '../../../projects');
|
|
21
|
+
const VERSION = '1.1.0';
|
|
22
|
+
|
|
23
|
+
function log(message, type = 'info') {
|
|
24
|
+
const styles = {
|
|
25
|
+
info: '\x1b[36m→\x1b[0m',
|
|
26
|
+
success: '\x1b[32m✓\x1b[0m',
|
|
27
|
+
warning: '\x1b[33m⚠\x1b[0m',
|
|
28
|
+
error: '\x1b[31m✗\x1b[0m',
|
|
29
|
+
title: '\x1b[1m\x1b[35m'
|
|
30
|
+
};
|
|
31
|
+
console.log(`${styles[type] || ''} ${message}${type === 'title' ? '\x1b[0m' : ''}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function showBanner() {
|
|
35
|
+
console.log(`
|
|
36
|
+
\x1b[35m╔═══════════════════════════════════════════════════════════╗
|
|
37
|
+
║ ║
|
|
38
|
+
║ \x1b[1mPlatform Prototype\x1b[0m\x1b[35m ║
|
|
39
|
+
║ Capture any platform. Generate pixel-perfect prototypes.║
|
|
40
|
+
║ ║
|
|
41
|
+
║ Version: ${VERSION} ║
|
|
42
|
+
║ ║
|
|
43
|
+
╚═══════════════════════════════════════════════════════════╝\x1b[0m
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function showHelp() {
|
|
48
|
+
showBanner();
|
|
49
|
+
console.log(`
|
|
50
|
+
\x1b[1mUSAGE\x1b[0m
|
|
51
|
+
real-prototypes-skill <command> [options]
|
|
52
|
+
|
|
53
|
+
\x1b[1mCOMMANDS\x1b[0m
|
|
54
|
+
new Create a new project
|
|
55
|
+
capture Capture a web platform
|
|
56
|
+
validate Validate capture or prototype
|
|
57
|
+
generate Generate prototype from capture
|
|
58
|
+
pipeline Run full capture → validate → generate pipeline
|
|
59
|
+
init Initialize a new capture configuration
|
|
60
|
+
list List all projects
|
|
61
|
+
|
|
62
|
+
\x1b[1mPROJECT OPTIONS\x1b[0m
|
|
63
|
+
--project Project name (required for capture/validate/generate/pipeline)
|
|
64
|
+
|
|
65
|
+
\x1b[1mCAPTURE OPTIONS\x1b[0m
|
|
66
|
+
--url Platform URL (required)
|
|
67
|
+
--email Login email
|
|
68
|
+
--password Login password
|
|
69
|
+
--output Output directory (default: ./references)
|
|
70
|
+
--config Path to config file
|
|
71
|
+
--mode Capture mode: auto, manual, hybrid (default: auto)
|
|
72
|
+
|
|
73
|
+
\x1b[1mVALIDATE OPTIONS\x1b[0m
|
|
74
|
+
--phase Validation phase: pre-capture, post-capture, pre-gen, post-gen, all
|
|
75
|
+
--refs References directory (default: ./references)
|
|
76
|
+
--proto Prototype directory (default: ./prototype)
|
|
77
|
+
|
|
78
|
+
\x1b[1mGENERATE OPTIONS\x1b[0m
|
|
79
|
+
--refs References directory (default: ./references)
|
|
80
|
+
--output Output directory (default: ./prototype)
|
|
81
|
+
--feature Feature to add (can be used multiple times)
|
|
82
|
+
|
|
83
|
+
\x1b[1mEXAMPLES\x1b[0m
|
|
84
|
+
# Create a new project
|
|
85
|
+
real-prototypes-skill new --project my-app
|
|
86
|
+
|
|
87
|
+
# Capture a platform
|
|
88
|
+
real-prototypes-skill capture --project my-app --url https://app.example.com --email user@test.com --password secret
|
|
89
|
+
|
|
90
|
+
# Validate capture
|
|
91
|
+
real-prototypes-skill validate --project my-app --phase post-capture
|
|
92
|
+
|
|
93
|
+
# Generate prototype
|
|
94
|
+
real-prototypes-skill generate --project my-app
|
|
95
|
+
|
|
96
|
+
# Run full pipeline
|
|
97
|
+
real-prototypes-skill pipeline --project my-app --url https://app.example.com --email user@test.com --password secret
|
|
98
|
+
|
|
99
|
+
# List all projects
|
|
100
|
+
real-prototypes-skill list
|
|
101
|
+
|
|
102
|
+
\x1b[1mENVIRONMENT VARIABLES\x1b[0m
|
|
103
|
+
PLATFORM_EMAIL Login email (alternative to --email)
|
|
104
|
+
PLATFORM_PASSWORD Login password (alternative to --password)
|
|
105
|
+
`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function parseArgs(args) {
|
|
109
|
+
const options = {
|
|
110
|
+
command: args[0],
|
|
111
|
+
project: null,
|
|
112
|
+
url: null,
|
|
113
|
+
email: process.env.PLATFORM_EMAIL,
|
|
114
|
+
password: process.env.PLATFORM_PASSWORD,
|
|
115
|
+
output: null,
|
|
116
|
+
config: null,
|
|
117
|
+
mode: 'auto',
|
|
118
|
+
phase: 'all',
|
|
119
|
+
refs: null,
|
|
120
|
+
proto: null,
|
|
121
|
+
features: []
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
for (let i = 1; i < args.length; i++) {
|
|
125
|
+
switch (args[i]) {
|
|
126
|
+
case '--project':
|
|
127
|
+
options.project = args[++i];
|
|
128
|
+
break;
|
|
129
|
+
case '--url':
|
|
130
|
+
options.url = args[++i];
|
|
131
|
+
break;
|
|
132
|
+
case '--email':
|
|
133
|
+
options.email = args[++i];
|
|
134
|
+
break;
|
|
135
|
+
case '--password':
|
|
136
|
+
options.password = args[++i];
|
|
137
|
+
break;
|
|
138
|
+
case '--output':
|
|
139
|
+
options.output = args[++i];
|
|
140
|
+
break;
|
|
141
|
+
case '--config':
|
|
142
|
+
options.config = args[++i];
|
|
143
|
+
break;
|
|
144
|
+
case '--mode':
|
|
145
|
+
options.mode = args[++i];
|
|
146
|
+
break;
|
|
147
|
+
case '--phase':
|
|
148
|
+
options.phase = args[++i];
|
|
149
|
+
break;
|
|
150
|
+
case '--refs':
|
|
151
|
+
options.refs = args[++i];
|
|
152
|
+
break;
|
|
153
|
+
case '--proto':
|
|
154
|
+
options.proto = args[++i];
|
|
155
|
+
break;
|
|
156
|
+
case '--feature':
|
|
157
|
+
options.features.push(args[++i]);
|
|
158
|
+
break;
|
|
159
|
+
case '--help':
|
|
160
|
+
case '-h':
|
|
161
|
+
showHelp();
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Set project-based paths if project is specified
|
|
167
|
+
if (options.project) {
|
|
168
|
+
const projectDir = path.join(PROJECTS_DIR, options.project);
|
|
169
|
+
options.refs = options.refs || path.join(projectDir, 'references');
|
|
170
|
+
options.proto = options.proto || path.join(projectDir, 'prototype');
|
|
171
|
+
} else {
|
|
172
|
+
options.refs = options.refs || './references';
|
|
173
|
+
options.proto = options.proto || './prototype';
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return options;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function requireProject(options, command) {
|
|
180
|
+
if (!options.project) {
|
|
181
|
+
log(`--project is required for ${command} command`, 'error');
|
|
182
|
+
log('Example: real-prototypes-skill ' + command + ' --project my-app', 'info');
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function getProjectDir(projectName) {
|
|
188
|
+
return path.join(PROJECTS_DIR, projectName);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function runNew(options) {
|
|
192
|
+
showBanner();
|
|
193
|
+
|
|
194
|
+
if (!options.project) {
|
|
195
|
+
log('--project is required for new command', 'error');
|
|
196
|
+
log('Example: real-prototypes-skill new --project my-app', 'info');
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const projectDir = getProjectDir(options.project);
|
|
201
|
+
const refsDir = path.join(projectDir, 'references');
|
|
202
|
+
const protoDir = path.join(projectDir, 'prototype');
|
|
203
|
+
|
|
204
|
+
if (fs.existsSync(projectDir)) {
|
|
205
|
+
log(`Project "${options.project}" already exists at ${projectDir}`, 'error');
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
log(`Creating project: ${options.project}`, 'title');
|
|
210
|
+
|
|
211
|
+
// Create directories
|
|
212
|
+
fs.mkdirSync(refsDir, { recursive: true });
|
|
213
|
+
fs.mkdirSync(path.join(refsDir, 'screenshots'), { recursive: true });
|
|
214
|
+
fs.mkdirSync(path.join(refsDir, 'html'), { recursive: true });
|
|
215
|
+
fs.mkdirSync(protoDir, { recursive: true });
|
|
216
|
+
|
|
217
|
+
// Create project config
|
|
218
|
+
const projectConfig = {
|
|
219
|
+
name: options.project,
|
|
220
|
+
created: new Date().toISOString(),
|
|
221
|
+
platform: {
|
|
222
|
+
name: '',
|
|
223
|
+
baseUrl: ''
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
fs.writeFileSync(path.join(projectDir, 'project.json'), JSON.stringify(projectConfig, null, 2));
|
|
227
|
+
|
|
228
|
+
log(`Project created: ${projectDir}`, 'success');
|
|
229
|
+
console.log(`
|
|
230
|
+
\x1b[1mProject Structure:\x1b[0m
|
|
231
|
+
${projectDir}/
|
|
232
|
+
├── project.json # Project configuration
|
|
233
|
+
├── references/ # Captured platform assets
|
|
234
|
+
│ ├── screenshots/
|
|
235
|
+
│ └── html/
|
|
236
|
+
└── prototype/ # Generated prototype
|
|
237
|
+
|
|
238
|
+
\x1b[1mNext Steps:\x1b[0m
|
|
239
|
+
1. Capture a platform:
|
|
240
|
+
real-prototypes-skill capture --project ${options.project} --url https://your-platform.com
|
|
241
|
+
|
|
242
|
+
2. Or run the full pipeline:
|
|
243
|
+
real-prototypes-skill pipeline --project ${options.project} --url https://your-platform.com
|
|
244
|
+
`);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function runList() {
|
|
248
|
+
showBanner();
|
|
249
|
+
log('Projects:', 'title');
|
|
250
|
+
|
|
251
|
+
if (!fs.existsSync(PROJECTS_DIR)) {
|
|
252
|
+
log('No projects found. Create one with: real-prototypes-skill new --project <name>', 'info');
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const projects = fs.readdirSync(PROJECTS_DIR, { withFileTypes: true })
|
|
257
|
+
.filter(dirent => dirent.isDirectory())
|
|
258
|
+
.map(dirent => {
|
|
259
|
+
const projectDir = path.join(PROJECTS_DIR, dirent.name);
|
|
260
|
+
const configPath = path.join(projectDir, 'project.json');
|
|
261
|
+
const manifestPath = path.join(projectDir, 'references', 'manifest.json');
|
|
262
|
+
|
|
263
|
+
let config = { name: dirent.name };
|
|
264
|
+
let manifest = null;
|
|
265
|
+
|
|
266
|
+
if (fs.existsSync(configPath)) {
|
|
267
|
+
try { config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); } catch {}
|
|
268
|
+
}
|
|
269
|
+
if (fs.existsSync(manifestPath)) {
|
|
270
|
+
try { manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')); } catch {}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
name: dirent.name,
|
|
275
|
+
platform: config.platform?.baseUrl || 'Not configured',
|
|
276
|
+
pages: manifest?.pages?.length || 0,
|
|
277
|
+
created: config.created || 'Unknown'
|
|
278
|
+
};
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
if (projects.length === 0) {
|
|
282
|
+
log('No projects found. Create one with: real-prototypes-skill new --project <name>', 'info');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
console.log('');
|
|
287
|
+
console.log(' \x1b[1mName\x1b[0m \x1b[1mPlatform\x1b[0m \x1b[1mPages\x1b[0m');
|
|
288
|
+
console.log(' ' + '-'.repeat(70));
|
|
289
|
+
|
|
290
|
+
projects.forEach(p => {
|
|
291
|
+
const name = p.name.padEnd(20);
|
|
292
|
+
const platform = (p.platform || '').substring(0, 27).padEnd(27);
|
|
293
|
+
const pages = String(p.pages).padStart(5);
|
|
294
|
+
console.log(` ${name} ${platform} ${pages}`);
|
|
295
|
+
});
|
|
296
|
+
console.log('');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
async function runCapture(options) {
|
|
300
|
+
requireProject(options, 'capture');
|
|
301
|
+
log(`Starting platform capture for project: ${options.project}`, 'title');
|
|
302
|
+
|
|
303
|
+
// Build config
|
|
304
|
+
const config = options.config
|
|
305
|
+
? JSON.parse(fs.readFileSync(options.config, 'utf-8'))
|
|
306
|
+
: {
|
|
307
|
+
platform: {
|
|
308
|
+
name: options.url ? new URL(options.url).hostname : 'unknown',
|
|
309
|
+
baseUrl: options.url
|
|
310
|
+
},
|
|
311
|
+
auth: {
|
|
312
|
+
type: options.email ? 'form' : 'none',
|
|
313
|
+
loginUrl: '/login',
|
|
314
|
+
credentials: {
|
|
315
|
+
email: options.email,
|
|
316
|
+
password: options.password
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
capture: {
|
|
320
|
+
mode: options.mode,
|
|
321
|
+
maxPages: 100,
|
|
322
|
+
maxDepth: 5,
|
|
323
|
+
viewports: [
|
|
324
|
+
{ name: 'desktop', width: 1920, height: 1080 }
|
|
325
|
+
],
|
|
326
|
+
interactions: {
|
|
327
|
+
clickButtons: true,
|
|
328
|
+
clickDropdowns: true,
|
|
329
|
+
clickTabs: true,
|
|
330
|
+
clickTableRows: true
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
output: {
|
|
334
|
+
directory: options.output || options.refs,
|
|
335
|
+
screenshots: true,
|
|
336
|
+
html: true,
|
|
337
|
+
designTokens: true
|
|
338
|
+
},
|
|
339
|
+
validation: {
|
|
340
|
+
minPages: 5,
|
|
341
|
+
minColors: 10,
|
|
342
|
+
requireDetailPages: true
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
if (!config.platform.baseUrl) {
|
|
347
|
+
log('Missing --url parameter', 'error');
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Write temp config
|
|
352
|
+
const configPath = path.join(SKILL_DIR, '.temp-config.json');
|
|
353
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
354
|
+
|
|
355
|
+
// Run capture engine
|
|
356
|
+
try {
|
|
357
|
+
const enginePath = path.join(SKILL_DIR, 'capture', 'capture-engine.js');
|
|
358
|
+
execSync(`node "${enginePath}" --config "${configPath}"`, { stdio: 'inherit' });
|
|
359
|
+
log('Capture completed successfully!', 'success');
|
|
360
|
+
return true;
|
|
361
|
+
} catch (error) {
|
|
362
|
+
log('Capture failed', 'error');
|
|
363
|
+
return false;
|
|
364
|
+
} finally {
|
|
365
|
+
if (fs.existsSync(configPath)) {
|
|
366
|
+
fs.unlinkSync(configPath);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async function runValidate(options) {
|
|
372
|
+
requireProject(options, 'validate');
|
|
373
|
+
log(`Running ${options.phase} validation for project: ${options.project}`, 'title');
|
|
374
|
+
|
|
375
|
+
const validatorPath = path.join(SKILL_DIR, 'validation', 'validation-engine.js');
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
execSync(`node "${validatorPath}" ${options.phase} "${options.refs}" "${options.proto}"`, {
|
|
379
|
+
stdio: 'inherit'
|
|
380
|
+
});
|
|
381
|
+
return true;
|
|
382
|
+
} catch (error) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function runGenerate(options) {
|
|
388
|
+
requireProject(options, 'generate');
|
|
389
|
+
log(`Generating prototype for project: ${options.project}`, 'title');
|
|
390
|
+
|
|
391
|
+
// This would integrate with your prototype generation logic
|
|
392
|
+
// For now, we'll provide guidance
|
|
393
|
+
|
|
394
|
+
const manifestPath = path.join(options.refs, 'manifest.json');
|
|
395
|
+
const tokensPath = path.join(options.refs, 'design-tokens.json');
|
|
396
|
+
|
|
397
|
+
if (!fs.existsSync(manifestPath)) {
|
|
398
|
+
log('manifest.json not found - run capture first', 'error');
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (!fs.existsSync(tokensPath)) {
|
|
403
|
+
log('design-tokens.json not found - run capture first', 'error');
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
408
|
+
const tokens = JSON.parse(fs.readFileSync(tokensPath, 'utf-8'));
|
|
409
|
+
|
|
410
|
+
console.log(`
|
|
411
|
+
\x1b[1mCapture Summary:\x1b[0m
|
|
412
|
+
Platform: ${manifest.platform.name}
|
|
413
|
+
Pages: ${manifest.pages.length}
|
|
414
|
+
Colors: ${tokens.totalColorsFound}
|
|
415
|
+
Primary Color: ${tokens.colors?.primary || 'Not identified'}
|
|
416
|
+
|
|
417
|
+
\x1b[1mGeneration Instructions:\x1b[0m
|
|
418
|
+
1. Use ONLY colors from design-tokens.json
|
|
419
|
+
2. Match layout from screenshots exactly
|
|
420
|
+
3. Use inline styles for colors (Tailwind custom colors may not work)
|
|
421
|
+
4. Validate with: real-prototypes-skill validate --phase post-gen
|
|
422
|
+
|
|
423
|
+
\x1b[1mRequired Colors:\x1b[0m
|
|
424
|
+
Primary: ${tokens.colors?.primary || 'N/A'}
|
|
425
|
+
Text: ${tokens.colors?.text?.primary || 'N/A'}
|
|
426
|
+
Background: ${tokens.colors?.background?.white || 'N/A'}
|
|
427
|
+
Border: ${tokens.colors?.border?.default || 'N/A'}
|
|
428
|
+
|
|
429
|
+
\x1b[1mFeatures to add:\x1b[0m
|
|
430
|
+
${options.features.length > 0 ? options.features.map(f => ` - ${f}`).join('\n') : ' (none specified)'}
|
|
431
|
+
`);
|
|
432
|
+
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
async function runPipeline(options) {
|
|
437
|
+
requireProject(options, 'pipeline');
|
|
438
|
+
showBanner();
|
|
439
|
+
log(`Running full pipeline for project: ${options.project}`, 'title');
|
|
440
|
+
|
|
441
|
+
console.log(`
|
|
442
|
+
\x1b[1mPipeline Steps:\x1b[0m
|
|
443
|
+
1. Pre-capture validation
|
|
444
|
+
2. Platform capture
|
|
445
|
+
3. Post-capture validation
|
|
446
|
+
4. Pre-generation validation
|
|
447
|
+
5. Prototype generation
|
|
448
|
+
6. Post-generation validation
|
|
449
|
+
`);
|
|
450
|
+
|
|
451
|
+
// Step 1: Pre-capture validation
|
|
452
|
+
log('Step 1: Pre-capture validation', 'info');
|
|
453
|
+
// Simplified - would normally run validator
|
|
454
|
+
|
|
455
|
+
// Step 2: Capture
|
|
456
|
+
log('Step 2: Platform capture', 'info');
|
|
457
|
+
const captureSuccess = await runCapture(options);
|
|
458
|
+
if (!captureSuccess) {
|
|
459
|
+
log('Pipeline failed at capture step', 'error');
|
|
460
|
+
process.exit(1);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Step 3: Post-capture validation
|
|
464
|
+
log('Step 3: Post-capture validation', 'info');
|
|
465
|
+
options.phase = 'post-capture';
|
|
466
|
+
const postCaptureValid = await runValidate(options);
|
|
467
|
+
if (!postCaptureValid) {
|
|
468
|
+
log('Pipeline failed at post-capture validation', 'error');
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Step 4: Pre-generation validation
|
|
473
|
+
log('Step 4: Pre-generation validation', 'info');
|
|
474
|
+
options.phase = 'pre-generation';
|
|
475
|
+
const preGenValid = await runValidate(options);
|
|
476
|
+
if (!preGenValid) {
|
|
477
|
+
log('Pipeline failed at pre-generation validation', 'error');
|
|
478
|
+
process.exit(1);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Step 5: Generate
|
|
482
|
+
log('Step 5: Prototype generation', 'info');
|
|
483
|
+
await runGenerate(options);
|
|
484
|
+
|
|
485
|
+
log('Pipeline completed!', 'success');
|
|
486
|
+
console.log(`
|
|
487
|
+
\x1b[1mNext Steps:\x1b[0m
|
|
488
|
+
1. Review screenshots in ${options.refs}/screenshots/
|
|
489
|
+
2. Check design-tokens.json for color palette
|
|
490
|
+
3. Generate prototype using the captured references
|
|
491
|
+
4. Run: real-prototypes-skill validate --phase post-gen
|
|
492
|
+
`);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function runInit(options) {
|
|
496
|
+
showBanner();
|
|
497
|
+
log('Initializing capture configuration...', 'title');
|
|
498
|
+
|
|
499
|
+
const configTemplate = {
|
|
500
|
+
platform: {
|
|
501
|
+
name: 'My Platform',
|
|
502
|
+
baseUrl: 'https://app.example.com'
|
|
503
|
+
},
|
|
504
|
+
auth: {
|
|
505
|
+
type: 'form',
|
|
506
|
+
loginUrl: '/login',
|
|
507
|
+
credentials: {
|
|
508
|
+
emailField: 'email',
|
|
509
|
+
passwordField: 'password',
|
|
510
|
+
submitButton: 'Sign in'
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
capture: {
|
|
514
|
+
mode: 'auto',
|
|
515
|
+
maxPages: 100,
|
|
516
|
+
maxDepth: 5,
|
|
517
|
+
viewports: [
|
|
518
|
+
{ name: 'desktop', width: 1920, height: 1080 },
|
|
519
|
+
{ name: 'tablet', width: 768, height: 1024 },
|
|
520
|
+
{ name: 'mobile', width: 375, height: 812 }
|
|
521
|
+
],
|
|
522
|
+
interactions: {
|
|
523
|
+
clickButtons: true,
|
|
524
|
+
clickDropdowns: true,
|
|
525
|
+
clickTabs: true,
|
|
526
|
+
clickTableRows: true,
|
|
527
|
+
clickModals: true,
|
|
528
|
+
hoverElements: true
|
|
529
|
+
},
|
|
530
|
+
exclude: ['/logout', '/signout', '/delete', '/remove']
|
|
531
|
+
},
|
|
532
|
+
output: {
|
|
533
|
+
directory: './references',
|
|
534
|
+
screenshots: true,
|
|
535
|
+
html: true,
|
|
536
|
+
designTokens: true
|
|
537
|
+
},
|
|
538
|
+
validation: {
|
|
539
|
+
minPages: 5,
|
|
540
|
+
minColors: 10,
|
|
541
|
+
requireDetailPages: true,
|
|
542
|
+
requireAllTabs: true
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
const outputPath = options.output || './capture-config.json';
|
|
547
|
+
fs.writeFileSync(outputPath, JSON.stringify(configTemplate, null, 2));
|
|
548
|
+
|
|
549
|
+
log(`Configuration created: ${outputPath}`, 'success');
|
|
550
|
+
console.log(`
|
|
551
|
+
\x1b[1mNext Steps:\x1b[0m
|
|
552
|
+
1. Edit ${outputPath} with your platform details
|
|
553
|
+
2. Set environment variables:
|
|
554
|
+
export PLATFORM_EMAIL=your@email.com
|
|
555
|
+
export PLATFORM_PASSWORD=yourpassword
|
|
556
|
+
3. Run: real-prototypes-skill capture --config ${outputPath}
|
|
557
|
+
`);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Main
|
|
561
|
+
const args = process.argv.slice(2);
|
|
562
|
+
const options = parseArgs(args);
|
|
563
|
+
|
|
564
|
+
switch (options.command) {
|
|
565
|
+
case 'new':
|
|
566
|
+
runNew(options);
|
|
567
|
+
break;
|
|
568
|
+
case 'list':
|
|
569
|
+
runList();
|
|
570
|
+
break;
|
|
571
|
+
case 'capture':
|
|
572
|
+
runCapture(options);
|
|
573
|
+
break;
|
|
574
|
+
case 'validate':
|
|
575
|
+
runValidate(options);
|
|
576
|
+
break;
|
|
577
|
+
case 'generate':
|
|
578
|
+
runGenerate(options);
|
|
579
|
+
break;
|
|
580
|
+
case 'pipeline':
|
|
581
|
+
runPipeline(options);
|
|
582
|
+
break;
|
|
583
|
+
case 'init':
|
|
584
|
+
runInit(options);
|
|
585
|
+
break;
|
|
586
|
+
case 'help':
|
|
587
|
+
case '--help':
|
|
588
|
+
case '-h':
|
|
589
|
+
case undefined:
|
|
590
|
+
showHelp();
|
|
591
|
+
break;
|
|
592
|
+
default:
|
|
593
|
+
log(`Unknown command: ${options.command}`, 'error');
|
|
594
|
+
log('Run "real-prototypes-skill --help" for usage', 'info');
|
|
595
|
+
process.exit(1);
|
|
596
|
+
}
|