@superdesign/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/index.cjs ADDED
@@ -0,0 +1,1254 @@
1
+ "use strict";
2
+ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
+ return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
+ }();
5
+ var __webpack_modules__ = {
6
+ open: function(module) {
7
+ module.exports = import("open").then(function(module) {
8
+ return module;
9
+ });
10
+ }
11
+ };
12
+ var __webpack_module_cache__ = {};
13
+ function __webpack_require__(moduleId) {
14
+ var cachedModule = __webpack_module_cache__[moduleId];
15
+ if (void 0 !== cachedModule) return cachedModule.exports;
16
+ var module = __webpack_module_cache__[moduleId] = {
17
+ exports: {}
18
+ };
19
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
20
+ return module.exports;
21
+ }
22
+ (()=>{
23
+ __webpack_require__.n = (module)=>{
24
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
25
+ __webpack_require__.d(getter, {
26
+ a: getter
27
+ });
28
+ return getter;
29
+ };
30
+ })();
31
+ (()=>{
32
+ __webpack_require__.d = (exports1, definition)=>{
33
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
34
+ enumerable: true,
35
+ get: definition[key]
36
+ });
37
+ };
38
+ })();
39
+ (()=>{
40
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
41
+ })();
42
+ (()=>{
43
+ __webpack_require__.r = (exports1)=>{
44
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
45
+ value: 'Module'
46
+ });
47
+ Object.defineProperty(exports1, '__esModule', {
48
+ value: true
49
+ });
50
+ };
51
+ })();
52
+ var __webpack_exports__ = {};
53
+ (()=>{
54
+ __webpack_require__.r(__webpack_exports__);
55
+ __webpack_require__.d(__webpack_exports__, {
56
+ run: ()=>run,
57
+ createDraft: ()=>createDraft,
58
+ getApiUrl: ()=>getApiUrl,
59
+ iterateDraft: ()=>iterateDraft,
60
+ clearConfig: ()=>clearConfig,
61
+ isJobDone: ()=>isJobDone,
62
+ createProject: ()=>createProject,
63
+ executeFlowPages: ()=>executeFlowPages,
64
+ loadConfig: ()=>loadConfig,
65
+ createPublicApiClient: ()=>createPublicApiClient,
66
+ planFlowPages: ()=>planFlowPages,
67
+ claimSession: ()=>claimSession,
68
+ isAuthenticated: ()=>manager_isAuthenticated,
69
+ addDraft: ()=>addDraft,
70
+ saveConfig: ()=>saveConfig,
71
+ createSession: ()=>createSession,
72
+ isJobFailed: ()=>isJobFailed,
73
+ getConfigPath: ()=>getConfigPath,
74
+ pollSession: ()=>pollSession,
75
+ updateConfig: ()=>updateConfig,
76
+ createProgram: ()=>createProgram,
77
+ getApiClient: ()=>getApiClient,
78
+ getJobStatus: ()=>getJobStatus,
79
+ getConfigDir: ()=>getConfigDir,
80
+ isJobCompleted: ()=>isJobCompleted,
81
+ ApiClientError: ()=>ApiClientError,
82
+ getApiKey: ()=>getApiKey,
83
+ createApiClient: ()=>createApiClient
84
+ });
85
+ const external_dotenv_namespaceObject = require("dotenv");
86
+ const external_url_namespaceObject = require("url");
87
+ const external_path_namespaceObject = require("path");
88
+ const external_commander_namespaceObject = require("commander");
89
+ const external_fs_namespaceObject = require("fs");
90
+ const external_os_namespaceObject = require("os");
91
+ const CONFIG_DIR_NAME = '.superdesign';
92
+ const CONFIG_FILE_NAME = 'config.json';
93
+ const EXIT_CODES = {
94
+ SUCCESS: 0,
95
+ GENERAL_ERROR: 1,
96
+ AUTH_REQUIRED: 2,
97
+ AUTH_FAILED: 3,
98
+ API_ERROR: 4,
99
+ VALIDATION_ERROR: 5,
100
+ TIMEOUT: 6
101
+ };
102
+ const SKILLS_DIR = '.claude/skills/superdesign';
103
+ const SKILL_FILE_NAME = 'SKILL.md';
104
+ function getConfigDir() {
105
+ return external_path_namespaceObject.join(external_os_namespaceObject.homedir(), CONFIG_DIR_NAME);
106
+ }
107
+ function getConfigPath() {
108
+ return external_path_namespaceObject.join(getConfigDir(), CONFIG_FILE_NAME);
109
+ }
110
+ function ensureConfigDir() {
111
+ const configDir = getConfigDir();
112
+ if (!external_fs_namespaceObject.existsSync(configDir)) external_fs_namespaceObject.mkdirSync(configDir, {
113
+ recursive: true,
114
+ mode: 448
115
+ });
116
+ }
117
+ function loadConfig() {
118
+ const configPath = getConfigPath();
119
+ if (!external_fs_namespaceObject.existsSync(configPath)) return {};
120
+ try {
121
+ const content = external_fs_namespaceObject.readFileSync(configPath, 'utf-8');
122
+ return JSON.parse(content);
123
+ } catch {
124
+ return {};
125
+ }
126
+ }
127
+ function saveConfig(config) {
128
+ ensureConfigDir();
129
+ const configPath = getConfigPath();
130
+ external_fs_namespaceObject.writeFileSync(configPath, JSON.stringify(config, null, 2), {
131
+ encoding: 'utf-8',
132
+ mode: 384
133
+ });
134
+ }
135
+ function updateConfig(updates) {
136
+ const current = loadConfig();
137
+ const updated = {
138
+ ...current,
139
+ ...updates
140
+ };
141
+ saveConfig(updated);
142
+ return updated;
143
+ }
144
+ function clearConfig() {
145
+ const configPath = getConfigPath();
146
+ if (external_fs_namespaceObject.existsSync(configPath)) external_fs_namespaceObject.unlinkSync(configPath);
147
+ }
148
+ function manager_isAuthenticated() {
149
+ const config = loadConfig();
150
+ return !!config.apiKey;
151
+ }
152
+ function getApiKey() {
153
+ const config = loadConfig();
154
+ if (!config.apiKey) throw new Error('Not authenticated. Run `superdesign login` first.');
155
+ return config.apiKey;
156
+ }
157
+ function getApiUrl() {
158
+ const config = loadConfig();
159
+ return config.apiUrl || process.env.SUPERDESIGN_API_URL || 'https://api.superdesign.dev/v1';
160
+ }
161
+ const external_axios_namespaceObject = require("axios");
162
+ var external_axios_default = /*#__PURE__*/ __webpack_require__.n(external_axios_namespaceObject);
163
+ class ApiClientError extends Error {
164
+ constructor(message, code, status, details){
165
+ super(message), this.code = code, this.status = status, this.details = details;
166
+ this.name = 'ApiClientError';
167
+ }
168
+ }
169
+ function createApiClient(requireAuth = true) {
170
+ const baseURL = getApiUrl();
171
+ const client = external_axios_default().create({
172
+ baseURL,
173
+ timeout: 30000,
174
+ headers: {
175
+ 'Content-Type': 'application/json'
176
+ }
177
+ });
178
+ if (requireAuth) client.interceptors.request.use((config)=>{
179
+ if (!manager_isAuthenticated()) throw new ApiClientError('Not authenticated. Run `superdesign login` first.', 'auth_required', 401);
180
+ const apiKey = getApiKey();
181
+ config.headers.Authorization = `Bearer ${apiKey}`;
182
+ return config;
183
+ });
184
+ client.interceptors.response.use((response)=>response, (error)=>{
185
+ if (error.response) {
186
+ const { status, data } = error.response;
187
+ const apiError = data?.error;
188
+ throw new ApiClientError(apiError?.message || error.message, apiError?.code || 'api_error', status, apiError?.details);
189
+ }
190
+ if ('ECONNREFUSED' === error.code) throw new ApiClientError('Could not connect to SuperDesign API', 'connection_error');
191
+ if ('ETIMEDOUT' === error.code) throw new ApiClientError('Request timed out', 'timeout');
192
+ throw new ApiClientError(error.message || 'Unknown error', 'unknown_error');
193
+ });
194
+ return client;
195
+ }
196
+ function createPublicApiClient() {
197
+ return createApiClient(false);
198
+ }
199
+ function getApiClient() {
200
+ return createApiClient(true);
201
+ }
202
+ async function createSession(data) {
203
+ const client = createPublicApiClient();
204
+ const response = await client.post('/cli-auth/sessions', data);
205
+ return response.data;
206
+ }
207
+ async function pollSession(pollToken) {
208
+ const client = createPublicApiClient();
209
+ const response = await client.get('/cli-auth/sessions/poll', {
210
+ params: {
211
+ token: pollToken
212
+ }
213
+ });
214
+ return response.data;
215
+ }
216
+ async function claimSession(pollToken) {
217
+ const client = createPublicApiClient();
218
+ const response = await client.post('/cli-auth/sessions/claim', {
219
+ pollToken
220
+ });
221
+ return response.data;
222
+ }
223
+ async function openBrowser(url) {
224
+ const open = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "open"));
225
+ await open.default(url);
226
+ }
227
+ async function poll(fn, isDone, options = {}) {
228
+ const intervalMs = options.intervalMs ?? 2000;
229
+ const timeoutMs = options.timeoutMs ?? 300000;
230
+ const startTime = Date.now();
231
+ let attempt = 0;
232
+ while(Date.now() - startTime < timeoutMs){
233
+ attempt++;
234
+ if (options.onPoll) options.onPoll(attempt);
235
+ try {
236
+ const result = await fn();
237
+ if (isDone(result)) return {
238
+ success: true,
239
+ data: result
240
+ };
241
+ } catch (err) {
242
+ const message = err instanceof Error ? err.message : 'Unknown error';
243
+ return {
244
+ success: false,
245
+ error: message
246
+ };
247
+ }
248
+ await sleep(intervalMs);
249
+ }
250
+ return {
251
+ success: false,
252
+ timedOut: true,
253
+ error: 'Polling timed out'
254
+ };
255
+ }
256
+ function sleep(ms) {
257
+ return new Promise((resolve)=>setTimeout(resolve, ms));
258
+ }
259
+ const external_ora_namespaceObject = require("ora");
260
+ var external_ora_default = /*#__PURE__*/ __webpack_require__.n(external_ora_namespaceObject);
261
+ let jsonMode = false;
262
+ function setJsonMode(enabled) {
263
+ jsonMode = enabled;
264
+ }
265
+ function isJsonMode() {
266
+ return jsonMode;
267
+ }
268
+ function output(data) {
269
+ if (jsonMode) console.log(JSON.stringify(data, null, 2));
270
+ else if ('string' == typeof data) console.log(data);
271
+ else console.log(JSON.stringify(data, null, 2));
272
+ }
273
+ function success(message) {
274
+ if (!jsonMode) console.log(`✓ ${message}`);
275
+ }
276
+ function output_error(message) {
277
+ if (jsonMode) console.error(JSON.stringify({
278
+ error: message
279
+ }));
280
+ else console.error(`✗ ${message}`);
281
+ }
282
+ function info(message) {
283
+ if (!jsonMode) console.log(message);
284
+ }
285
+ let currentSpinner = null;
286
+ function startSpinner(text) {
287
+ if (isJsonMode()) return null;
288
+ currentSpinner = external_ora_default()(text).start();
289
+ return currentSpinner;
290
+ }
291
+ function updateSpinner(text) {
292
+ if (currentSpinner) currentSpinner.text = text;
293
+ }
294
+ function succeedSpinner(text) {
295
+ if (currentSpinner) {
296
+ currentSpinner.succeed(text);
297
+ currentSpinner = null;
298
+ }
299
+ }
300
+ function failSpinner(text) {
301
+ if (currentSpinner) {
302
+ currentSpinner.fail(text);
303
+ currentSpinner = null;
304
+ }
305
+ }
306
+ async function runAuthFlow(options = {}) {
307
+ const { openBrowser: shouldOpenBrowser = true, showSuccessMessage = true } = options;
308
+ try {
309
+ startSpinner('Creating auth session...');
310
+ const session = await createSession({
311
+ cliVersion: "0.1.0",
312
+ os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
313
+ hostname: external_os_namespaceObject.hostname()
314
+ });
315
+ updateSpinner('Waiting for browser authorization...');
316
+ if (shouldOpenBrowser) try {
317
+ await openBrowser(session.authUrl);
318
+ info(`\nOpened browser to: ${session.authUrl}`);
319
+ } catch {
320
+ info(`\nPlease open this URL in your browser:\n${session.authUrl}`);
321
+ }
322
+ else info(`\nPlease open this URL in your browser:\n${session.authUrl}`);
323
+ info(`\nSession code: ${session.sessionCode}`);
324
+ info('Waiting for authorization...\n');
325
+ const pollResult = await poll(()=>pollSession(session.pollToken), (response)=>'pending' !== response.status, {
326
+ intervalMs: 2000,
327
+ timeoutMs: 600000,
328
+ onPoll: (attempt)=>{
329
+ if (attempt % 10 === 0) updateSpinner(`Waiting for authorization... (${Math.floor(2000 * attempt / 1000)}s)`);
330
+ }
331
+ });
332
+ if (pollResult.timedOut) {
333
+ failSpinner('Authorization timed out');
334
+ return {
335
+ success: false,
336
+ error: 'Session expired. Please try again.'
337
+ };
338
+ }
339
+ if (!pollResult.success || !pollResult.data) {
340
+ failSpinner('Authorization failed');
341
+ return {
342
+ success: false,
343
+ error: pollResult.error || 'Failed to get authorization status'
344
+ };
345
+ }
346
+ const authResponse = pollResult.data;
347
+ if ('expired' === authResponse.status) {
348
+ failSpinner('Session expired');
349
+ return {
350
+ success: false,
351
+ error: 'Session expired. Please try again.'
352
+ };
353
+ }
354
+ if ('approved' !== authResponse.status || !authResponse.apiKey) {
355
+ failSpinner('Authorization denied');
356
+ return {
357
+ success: false,
358
+ error: 'Authorization was denied or failed.'
359
+ };
360
+ }
361
+ await claimSession(session.pollToken);
362
+ updateConfig({
363
+ apiKey: authResponse.apiKey,
364
+ teamId: authResponse.teamId,
365
+ teamName: authResponse.teamName
366
+ });
367
+ succeedSpinner('Authenticated successfully!');
368
+ if (showSuccessMessage) success(`Logged in to team: ${authResponse.teamName}`);
369
+ return {
370
+ success: true,
371
+ teamId: authResponse.teamId,
372
+ teamName: authResponse.teamName,
373
+ apiKey: authResponse.apiKey
374
+ };
375
+ } catch (err) {
376
+ failSpinner('Login failed');
377
+ const message = err instanceof Error ? err.message : 'Unknown error';
378
+ output_error(message);
379
+ return {
380
+ success: false,
381
+ error: message
382
+ };
383
+ }
384
+ }
385
+ const LOGO = `
386
+ ███████╗██╗ ██╗██████╗ ███████╗██████╗ ██████╗ ███████╗███████╗██╗ ██████╗ ███╗ ██╗
387
+ ██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔════╝██╔════╝██║██╔════╝ ████╗ ██║
388
+ ███████╗██║ ██║██████╔╝█████╗ ██████╔╝██║ ██║█████╗ ███████╗██║██║ ███╗██╔██╗ ██║
389
+ ╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║ ██║██╔══╝ ╚════██║██║██║ ██║██║╚██╗██║
390
+ ███████║╚██████╔╝██║ ███████╗██║ ██║██████╔╝███████╗███████║██║╚██████╔╝██║ ╚████║
391
+ ╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝
392
+ `.trim();
393
+ const TAGLINE = 'AI designer for coding agents';
394
+ const SCRAMBLE_CHARS = '░▒▓█▄▀│┤┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌';
395
+ function ascii_animation_sleep(ms) {
396
+ return new Promise((resolve)=>setTimeout(resolve, ms));
397
+ }
398
+ function getRandomChar() {
399
+ return SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)];
400
+ }
401
+ function shouldSkipAnimation() {
402
+ if (process.env.CI) return true;
403
+ if (!process.stdout.isTTY) return true;
404
+ if (process.env.NO_COLOR) return true;
405
+ return false;
406
+ }
407
+ function clearFrame(lineCount) {
408
+ for(let i = 0; i < lineCount; i++){
409
+ process.stdout.write('\x1B[1A');
410
+ process.stdout.write('\x1B[2K');
411
+ }
412
+ }
413
+ async function animateLogo() {
414
+ if (shouldSkipAnimation()) {
415
+ console.log(LOGO);
416
+ console.log(TAGLINE);
417
+ console.log();
418
+ return;
419
+ }
420
+ const lines = LOGO.split('\n');
421
+ const frames = 20;
422
+ const frameDelay = 60;
423
+ const scrambledLines = lines.map((line)=>line.split('').map((char)=>' ' === char ? ' ' : getRandomChar()).join(''));
424
+ console.log(scrambledLines.join('\n'));
425
+ for(let frame = 1; frame <= frames; frame++){
426
+ await ascii_animation_sleep(frameDelay);
427
+ clearFrame(lines.length);
428
+ const revealRatio = frame / frames;
429
+ const easedRatio = 1 - Math.pow(1 - revealRatio, 3);
430
+ const renderedLines = lines.map((line)=>line.split('').map((char, i)=>{
431
+ if (' ' === char) return ' ';
432
+ const positionFactor = i / line.length;
433
+ const threshold = 1.2 * easedRatio - 0.3 * positionFactor;
434
+ if (Math.random() < threshold) return char;
435
+ return getRandomChar();
436
+ }).join(''));
437
+ console.log(renderedLines.join('\n'));
438
+ }
439
+ clearFrame(lines.length);
440
+ console.log(LOGO);
441
+ await ascii_animation_sleep(100);
442
+ console.log(TAGLINE);
443
+ console.log();
444
+ }
445
+ function createLoginCommand() {
446
+ const command = new external_commander_namespaceObject.Command('login').description('Authenticate with SuperDesign platform').option('--json', 'Output in JSON format').option('--no-browser', 'Do not open browser automatically').action(async (options)=>{
447
+ if (options.json) setJsonMode(true);
448
+ if (!isJsonMode()) await animateLogo();
449
+ const currentConfig = loadConfig();
450
+ if (currentConfig.apiKey) {
451
+ info(`Already authenticated as team: ${currentConfig.teamName || 'Unknown'}`);
452
+ info('Run `superdesign login` again to re-authenticate.');
453
+ }
454
+ const result = await runAuthFlow({
455
+ openBrowser: false !== options.noBrowser,
456
+ showSuccessMessage: !isJsonMode()
457
+ });
458
+ if (!result.success) {
459
+ output_error(result.error || 'Authentication failed');
460
+ process.exit(EXIT_CODES.AUTH_FAILED);
461
+ }
462
+ if (isJsonMode()) output({
463
+ success: true,
464
+ teamId: result.teamId,
465
+ teamName: result.teamName
466
+ });
467
+ else {
468
+ info('\nYou can now use SuperDesign CLI commands.');
469
+ info('Run `superdesign init` to install Claude Code skills.');
470
+ }
471
+ });
472
+ return command;
473
+ }
474
+ function createLogoutCommand() {
475
+ const command = new external_commander_namespaceObject.Command('logout').description('Log out and clear stored credentials').option('--json', 'Output in JSON format').action(async (options)=>{
476
+ if (options.json) setJsonMode(true);
477
+ try {
478
+ if (!manager_isAuthenticated()) {
479
+ if (isJsonMode()) output({
480
+ success: true,
481
+ message: 'Not logged in'
482
+ });
483
+ else info('Not logged in.');
484
+ return;
485
+ }
486
+ const config = loadConfig();
487
+ const teamName = config.teamName;
488
+ clearConfig();
489
+ if (isJsonMode()) output({
490
+ success: true,
491
+ message: 'Logged out successfully',
492
+ teamName
493
+ });
494
+ else {
495
+ success('Logged out successfully!');
496
+ if (teamName) info(`Disconnected from team: ${teamName}`);
497
+ info('\nRun `superdesign login` or `superdesign init` to authenticate again.');
498
+ }
499
+ } catch (err) {
500
+ const message = err instanceof Error ? err.message : 'Unknown error';
501
+ output_error(`Failed to logout: ${message}`);
502
+ }
503
+ });
504
+ return command;
505
+ }
506
+ function getSkillTemplate() {
507
+ return `---
508
+ name: superdesign
509
+ description: Superdesign is a design agent, where it specialised in frontend UI/UX design; Use this skill before you implement any UI that require some design thinking
510
+ ---
511
+
512
+ # SuperDesign Integration
513
+ This skill provides integration with the SuperDesign platform for AI-powered design generation.
514
+
515
+ ## Available Commands
516
+
517
+ ### Create Project
518
+
519
+ Create a new new project, can pass optional HTML as initial starting point for design iteration:
520
+
521
+ \`\`\`bash
522
+ # Basic project
523
+ superdesign create-project --title "My Project" --json
524
+
525
+ # Project with initial HTML
526
+ superdesign create-project --title "My Project" --html "<html>...</html>" --json
527
+
528
+ # Project with HTML from file
529
+ superdesign create-project --title "My Project" --html-file ./index.html --json
530
+ \`\`\`
531
+
532
+ **Output (JSON):**
533
+ \`\`\`json
534
+ {
535
+ "projectId": "uuid",
536
+ "title": "My Project",
537
+ "projectUrl": "https://app.superdesign.ai/...",
538
+ "shareToken": "token"
539
+ }
540
+ \`\`\`
541
+
542
+ ### Create Design Draft
543
+
544
+ Generate a design draft using AI designer:
545
+
546
+ \`\`\`bash
547
+ superdesign create-design-draft \\
548
+ --project-id <project-id> \\
549
+ --title "Hero Section" \\
550
+ --prompt "Create a modern hero section with gradient background" \\
551
+ --device desktop \\
552
+ --json
553
+ \`\`\`
554
+
555
+ **Options:**
556
+ - \`--project-id\` (required): Project to add draft to
557
+ - \`--title\` (required): Draft title
558
+ - \`--prompt\` (required): AI generation prompt
559
+ - \`--device\`: Device mode (mobile, tablet, desktop)
560
+
561
+ **Output (JSON):**
562
+ \`\`\`json
563
+ {
564
+ "draftId": "uuid",
565
+ "nodeId": "uuid",
566
+ "title": "Hero Section",
567
+ "projectUrl": "https://app.superdesign.ai/...",
568
+ "nodeUrl": "https://app.superdesign.ai/...?node=...",
569
+ "previewUrl": "https://preview.superdesign.ai/...",
570
+ "creditsConsumed": 1
571
+ }
572
+ \`\`\`
573
+
574
+ ### Iterate Design Draft
575
+
576
+ Create variations or improvements of an existing draft:
577
+
578
+ \`\`\`bash
579
+ # Replace mode - updates the existing draft
580
+ superdesign iterate-design-draft \\
581
+ --draft-id <draft-id> \\
582
+ --prompt "Make the colors more vibrant" \\
583
+ --mode replace \\
584
+ --json
585
+
586
+ # Branch mode - creates new variations
587
+ superdesign iterate-design-draft \\
588
+ --draft-id <draft-id> \\
589
+ --prompt "Try different color schemes" \\
590
+ --mode branch \\
591
+ --count 3 \\
592
+ --json
593
+ \`\`\`
594
+
595
+ **Options:**
596
+ - \`--draft-id\` (required): Draft to iterate on
597
+ - \`--prompt\` (required): Iteration instructions
598
+ - \`--mode\` (required): "replace" or "branch"
599
+ - \`--count\`: Number of variations (1-4, branch mode only)
600
+
601
+ **Output (JSON):**
602
+ \`\`\`json
603
+ {
604
+ "drafts": [
605
+ {
606
+ "draftId": "uuid",
607
+ "nodeId": "uuid",
608
+ "title": "Variation 1",
609
+ "nodeUrl": "https://...",
610
+ "previewUrl": "https://..."
611
+ }
612
+ ],
613
+ "projectUrl": "https://...",
614
+ "creditsConsumed": 3
615
+ }
616
+ \`\`\`
617
+
618
+ ### Plan Flow Pages
619
+
620
+ Get AI suggestions for related pages in a user flow:
621
+
622
+ \`\`\`bash
623
+ superdesign plan-flow-pages \\
624
+ --draft-id <draft-id> \\
625
+ --source-node-id <node-id> \\
626
+ --context "E-commerce checkout flow" \\
627
+ --json
628
+ \`\`\`
629
+
630
+ **Options:**
631
+ - \`--draft-id\` (required): Source draft
632
+ - \`--source-node-id\` (required): Starting node in flow
633
+ - \`--context\`: Additional context for planning
634
+
635
+ **Output (JSON):**
636
+ \`\`\`json
637
+ {
638
+ "pages": [
639
+ {
640
+ "title": "Cart Review",
641
+ "prompt": "Create a cart review page showing..."
642
+ },
643
+ {
644
+ "title": "Payment",
645
+ "prompt": "Create a payment form with..."
646
+ }
647
+ ],
648
+ "creditsConsumed": 1
649
+ }
650
+ \`\`\`
651
+
652
+ ### Execute Flow Pages
653
+
654
+ Generate the planned flow pages:
655
+
656
+ \`\`\`bash
657
+ superdesign execute-flow-pages \\
658
+ --draft-id <draft-id> \\
659
+ --source-node-id <node-id> \\
660
+ --pages '[{"title":"Cart","prompt":"Create cart page"},{"title":"Payment","prompt":"Create payment form"}]' \\
661
+ --json
662
+ \`\`\`
663
+
664
+ **Options:**
665
+ - \`--draft-id\` (required): Source draft
666
+ - \`--source-node-id\` (required): Starting node
667
+ - \`--pages\` (required): JSON array of pages to generate
668
+ - \`--context\`: Additional context
669
+
670
+ **Output (JSON):**
671
+ \`\`\`json
672
+ {
673
+ "drafts": [
674
+ {
675
+ "index": 0,
676
+ "draftId": "uuid",
677
+ "nodeId": "uuid",
678
+ "title": "Cart",
679
+ "nodeUrl": "https://...",
680
+ "previewUrl": "https://..."
681
+ }
682
+ ],
683
+ "projectUrl": "https://...",
684
+ "creditsConsumed": 2
685
+ }
686
+ \`\`\`
687
+
688
+ ## Workflow Examples
689
+
690
+ ### Create a new design from scratch
691
+
692
+ \`\`\`bash
693
+ # 1. Create project
694
+ PROJECT=$(superdesign create-project --title "Landing Page" --json)
695
+ PROJECT_ID=$(echo $PROJECT | jq -r '.projectId')
696
+
697
+ # 2. Generate initial design
698
+ DRAFT=$(superdesign create-design-draft \\
699
+ --project-id $PROJECT_ID \\
700
+ --title "Hero" \\
701
+ --prompt "Modern SaaS landing page hero with gradient, CTA button" \\
702
+ --json)
703
+
704
+ echo "Preview: $(echo $DRAFT | jq -r '.previewUrl')"
705
+ \`\`\`
706
+
707
+ ### Iterate on existing design
708
+
709
+ \`\`\`bash
710
+ # Create variations
711
+ superdesign iterate-design-draft \\
712
+ --draft-id <draft-id> \\
713
+ --prompt "Try a dark theme version" \\
714
+ --mode branch \\
715
+ --count 2 \\
716
+ --json
717
+ \`\`\`
718
+
719
+ ### Build a complete user flow
720
+
721
+ \`\`\`bash
722
+ # 1. Plan the flow
723
+ PLAN=$(superdesign plan-flow-pages \\
724
+ --draft-id <draft-id> \\
725
+ --source-node-id <node-id> \\
726
+ --context "User onboarding flow" \\
727
+ --json)
728
+
729
+ # 2. Execute the plan
730
+ PAGES=$(echo $PLAN | jq -c '.pages')
731
+ superdesign execute-flow-pages \\
732
+ --draft-id <draft-id> \\
733
+ --source-node-id <node-id> \\
734
+ --pages "$PAGES" \\
735
+ --json
736
+ \`\`\`
737
+
738
+
739
+ ## Tips
740
+
741
+ - Always use \`--json\` flag when parsing output programmatically
742
+ - Store project and draft IDs for subsequent operations
743
+ - Use \`plan-flow-pages\` before \`execute-flow-pages\` for best results
744
+ - The \`previewUrl\` can be used to view designs without authentication
745
+ `;
746
+ }
747
+ function createInitCommand() {
748
+ const command = new external_commander_namespaceObject.Command('init').description('Install SuperDesign skill files for Claude Code (auto-login if needed)').option('--json', 'Output in JSON format').option('--force', 'Overwrite existing skill files').action(async (options)=>{
749
+ if (options.json) setJsonMode(true);
750
+ if (!isJsonMode()) await animateLogo();
751
+ try {
752
+ if (!manager_isAuthenticated()) {
753
+ info('Not authenticated. Starting login flow...\n');
754
+ const authResult = await runAuthFlow({
755
+ showSuccessMessage: true
756
+ });
757
+ if (!authResult.success) {
758
+ output_error(authResult.error || 'Authentication failed');
759
+ process.exit(EXIT_CODES.AUTH_FAILED);
760
+ }
761
+ info('');
762
+ }
763
+ const cwd = process.cwd();
764
+ const skillsPath = external_path_namespaceObject.join(cwd, SKILLS_DIR);
765
+ const skillFilePath = external_path_namespaceObject.join(skillsPath, SKILL_FILE_NAME);
766
+ if (external_fs_namespaceObject.existsSync(skillFilePath) && !options.force) {
767
+ if (isJsonMode()) output({
768
+ success: false,
769
+ error: 'Skill file already exists. Use --force to overwrite.',
770
+ path: skillFilePath
771
+ });
772
+ else {
773
+ info(`Skill file already exists at: ${skillFilePath}`);
774
+ info('Use --force to overwrite.');
775
+ }
776
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
777
+ }
778
+ external_fs_namespaceObject.mkdirSync(skillsPath, {
779
+ recursive: true
780
+ });
781
+ const skillContent = getSkillTemplate();
782
+ external_fs_namespaceObject.writeFileSync(skillFilePath, skillContent, 'utf-8');
783
+ if (isJsonMode()) output({
784
+ success: true,
785
+ path: skillFilePath,
786
+ message: 'Skill files installed successfully'
787
+ });
788
+ else {
789
+ success('Skill files installed successfully!');
790
+ info(`\nSkill file created at: ${skillFilePath}`);
791
+ info('\nClaude Code will now have access to SuperDesign commands.');
792
+ info('Available commands:');
793
+ info(' - superdesign create-project');
794
+ info(' - superdesign create-design-draft');
795
+ info(' - superdesign iterate-design-draft');
796
+ info(' - superdesign plan-flow-pages');
797
+ info(' - superdesign execute-flow-pages');
798
+ }
799
+ } catch (err) {
800
+ const message = err instanceof Error ? err.message : 'Unknown error';
801
+ output_error(`Failed to initialize: ${message}`);
802
+ process.exit(EXIT_CODES.GENERAL_ERROR);
803
+ }
804
+ });
805
+ return command;
806
+ }
807
+ async function createProject(data) {
808
+ const client = getApiClient();
809
+ const response = await client.post('/external/projects', data);
810
+ return response.data;
811
+ }
812
+ async function addDraft(projectId, data) {
813
+ const client = getApiClient();
814
+ const response = await client.post(`/external/projects/${projectId}/drafts/add`, data);
815
+ return response.data;
816
+ }
817
+ function createCreateProjectCommand() {
818
+ const command = new external_commander_namespaceObject.Command('create-project').description('Create a new SuperDesign project').requiredOption('--title <title>', 'Project title').option('--html <html>', 'Initial HTML content for first draft').option('--html-file <path>', 'Path to HTML file for first draft').option('--device <mode>', 'Device mode for draft (mobile, tablet, desktop)', 'desktop').option('--json', 'Output in JSON format').action(async (options)=>{
819
+ if (options.json) setJsonMode(true);
820
+ try {
821
+ if (!manager_isAuthenticated()) {
822
+ output_error('Not authenticated. Run `superdesign login` first.');
823
+ process.exit(EXIT_CODES.AUTH_REQUIRED);
824
+ }
825
+ if (options.device && ![
826
+ 'mobile',
827
+ 'tablet',
828
+ 'desktop'
829
+ ].includes(options.device)) {
830
+ output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
831
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
832
+ }
833
+ let htmlContent;
834
+ if (options.htmlFile) {
835
+ if (!external_fs_namespaceObject.existsSync(options.htmlFile)) {
836
+ output_error(`HTML file not found: ${options.htmlFile}`);
837
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
838
+ }
839
+ htmlContent = external_fs_namespaceObject.readFileSync(options.htmlFile, 'utf-8');
840
+ } else if (options.html) htmlContent = options.html;
841
+ startSpinner('Creating project...');
842
+ const project = await createProject({
843
+ title: options.title
844
+ });
845
+ let draftResult = null;
846
+ if (htmlContent) draftResult = await addDraft(project.projectId, {
847
+ title: 'Initial Draft',
848
+ html: htmlContent,
849
+ deviceMode: options.device
850
+ });
851
+ succeedSpinner('Project created successfully!');
852
+ const result = {
853
+ projectId: project.projectId,
854
+ title: project.title,
855
+ projectUrl: project.projectUrl,
856
+ shareToken: project.shareToken,
857
+ ...draftResult && {
858
+ draft: {
859
+ draftId: draftResult.draftId,
860
+ nodeId: draftResult.nodeId,
861
+ nodeUrl: draftResult.nodeUrl,
862
+ previewUrl: draftResult.previewUrl
863
+ }
864
+ }
865
+ };
866
+ if (isJsonMode()) output(result);
867
+ else {
868
+ success(`Project "${project.title}" created!`);
869
+ info(`\nProject ID: ${project.projectId}`);
870
+ info(`Project URL: ${project.projectUrl}`);
871
+ if (draftResult) {
872
+ info(`\nDraft ID: ${draftResult.draftId}`);
873
+ info(`Draft URL: ${draftResult.nodeUrl}`);
874
+ info(`Preview URL: ${draftResult.previewUrl}`);
875
+ }
876
+ }
877
+ } catch (err) {
878
+ failSpinner('Failed to create project');
879
+ if (err instanceof ApiClientError) {
880
+ output_error(`API Error: ${err.message}`);
881
+ process.exit(EXIT_CODES.API_ERROR);
882
+ }
883
+ const message = err instanceof Error ? err.message : 'Unknown error';
884
+ output_error(message);
885
+ process.exit(EXIT_CODES.GENERAL_ERROR);
886
+ }
887
+ });
888
+ return command;
889
+ }
890
+ async function createDraft(projectId, data) {
891
+ const client = getApiClient();
892
+ const response = await client.post(`/external/projects/${projectId}/drafts/create`, data);
893
+ return response.data;
894
+ }
895
+ async function iterateDraft(draftId, data) {
896
+ const client = getApiClient();
897
+ const response = await client.post(`/external/drafts/${draftId}/iterate`, data);
898
+ return response.data;
899
+ }
900
+ async function planFlowPages(draftId, data) {
901
+ const client = getApiClient();
902
+ const response = await client.post(`/external/drafts/${draftId}/flow/plan`, data);
903
+ return response.data;
904
+ }
905
+ async function executeFlowPages(draftId, data) {
906
+ const client = getApiClient();
907
+ const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
908
+ return response.data;
909
+ }
910
+ async function getJobStatus(jobId) {
911
+ const client = getApiClient();
912
+ const response = await client.get(`/external/jobs/${jobId}`);
913
+ return response.data;
914
+ }
915
+ function isJobDone(response) {
916
+ return 'completed' === response.status || 'failed' === response.status;
917
+ }
918
+ function isJobCompleted(response) {
919
+ return 'completed' === response.status;
920
+ }
921
+ function isJobFailed(response) {
922
+ return 'failed' === response.status;
923
+ }
924
+ async function runJob(config) {
925
+ const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
926
+ try {
927
+ startSpinner(startLabel);
928
+ const job = await startJob();
929
+ updateSpinner(pollingLabel);
930
+ const pollResult = await poll(()=>getJobStatus(job.jobId), isJobDone, {
931
+ intervalMs: 2000,
932
+ timeoutMs,
933
+ onPoll: (attempt)=>{
934
+ if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
935
+ }
936
+ });
937
+ if (pollResult.timedOut) {
938
+ failSpinner(timeoutLabel);
939
+ output_error('Job timed out. The operation may still be processing in the background.');
940
+ if (isJsonMode()) output({
941
+ error: 'timeout',
942
+ jobId: job.jobId
943
+ });
944
+ process.exit(EXIT_CODES.TIMEOUT);
945
+ }
946
+ if (!pollResult.success || !pollResult.data) {
947
+ failSpinner(failureLabel);
948
+ output_error(pollResult.error || 'Failed to get job status');
949
+ process.exit(EXIT_CODES.API_ERROR);
950
+ }
951
+ const jobResult = pollResult.data;
952
+ if (isJobFailed(jobResult)) {
953
+ failSpinner(failureLabel);
954
+ output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
955
+ process.exit(EXIT_CODES.API_ERROR);
956
+ }
957
+ if (!isJobCompleted(jobResult)) {
958
+ failSpinner('Unexpected job status');
959
+ output_error('Job ended in unexpected state');
960
+ process.exit(EXIT_CODES.API_ERROR);
961
+ }
962
+ succeedSpinner(successLabel);
963
+ if (isJsonMode()) output(transformResult(jobResult));
964
+ else displayResult(jobResult);
965
+ process.exit(EXIT_CODES.SUCCESS);
966
+ } catch (err) {
967
+ failSpinner(failureLabel);
968
+ if (err instanceof ApiClientError) {
969
+ output_error(`API Error: ${err.message}`);
970
+ process.exit(EXIT_CODES.API_ERROR);
971
+ }
972
+ const message = err instanceof Error ? err.message : 'Unknown error';
973
+ output_error(message);
974
+ process.exit(EXIT_CODES.GENERAL_ERROR);
975
+ }
976
+ }
977
+ function job_runner_requireAuth(isAuthenticated) {
978
+ if (!isAuthenticated()) {
979
+ output_error('Not authenticated. Run `superdesign login` first.');
980
+ process.exit(EXIT_CODES.AUTH_REQUIRED);
981
+ }
982
+ }
983
+ function createCreateDesignDraftCommand() {
984
+ const command = new external_commander_namespaceObject.Command('create-design-draft').description('Create a design draft using AI generation').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('--prompt <prompt>', 'Design prompt for AI generation').option('--device <mode>', 'Device mode (mobile, tablet, desktop)', 'desktop').option('--json', 'Output in JSON format').action(async (options)=>{
985
+ if (options.json) setJsonMode(true);
986
+ job_runner_requireAuth(manager_isAuthenticated);
987
+ if (options.device && ![
988
+ 'mobile',
989
+ 'tablet',
990
+ 'desktop'
991
+ ].includes(options.device)) {
992
+ output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
993
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
994
+ }
995
+ await runJob({
996
+ startLabel: 'Creating design draft...',
997
+ pollingLabel: 'Generating design with AI...',
998
+ successLabel: 'Design draft created!',
999
+ timeoutLabel: 'Generation timed out',
1000
+ failureLabel: 'Failed to create draft',
1001
+ startJob: ()=>createDraft(options.projectId, {
1002
+ title: options.title,
1003
+ prompt: options.prompt,
1004
+ deviceMode: options.device
1005
+ }),
1006
+ transformResult: (job)=>({
1007
+ draftId: job.result.draftId,
1008
+ nodeId: job.result.nodeId,
1009
+ title: job.result.title,
1010
+ projectUrl: job.result.projectUrl,
1011
+ nodeUrl: job.result.nodeUrl,
1012
+ previewUrl: job.result.previewUrl,
1013
+ creditsConsumed: job.creditsConsumed
1014
+ }),
1015
+ displayResult: (job)=>{
1016
+ success(`Draft "${job.result.title}" created!`);
1017
+ info(`\nDraft ID: ${job.result.draftId}`);
1018
+ info(`Node URL: ${job.result.nodeUrl}`);
1019
+ info(`Preview URL: ${job.result.previewUrl}`);
1020
+ info(`Credits consumed: ${job.creditsConsumed}`);
1021
+ }
1022
+ });
1023
+ });
1024
+ return command;
1025
+ }
1026
+ function createIterateDesignDraftCommand() {
1027
+ const command = new external_commander_namespaceObject.Command('iterate-design-draft').description('Iterate on an existing draft using AI').requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('--prompt <prompt>', 'Iteration prompt').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations to generate (1-4)', '1').option('--json', 'Output in JSON format').action(async (options)=>{
1028
+ if (options.json) setJsonMode(true);
1029
+ job_runner_requireAuth(manager_isAuthenticated);
1030
+ if (![
1031
+ 'replace',
1032
+ 'branch'
1033
+ ].includes(options.mode)) {
1034
+ output_error('Invalid mode. Must be: replace or branch');
1035
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1036
+ }
1037
+ const count = parseInt(options.count || '1', 10);
1038
+ if (isNaN(count) || count < 1 || count > 4) {
1039
+ output_error('Invalid count. Must be between 1 and 4');
1040
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1041
+ }
1042
+ await runJob({
1043
+ startLabel: 'Starting iteration...',
1044
+ pollingLabel: 'Iterating design with AI...',
1045
+ successLabel: 'Iteration complete!',
1046
+ timeoutLabel: 'Iteration timed out',
1047
+ failureLabel: 'Failed to iterate draft',
1048
+ startJob: ()=>iterateDraft(options.draftId, {
1049
+ prompt: options.prompt,
1050
+ mode: options.mode,
1051
+ count: count
1052
+ }),
1053
+ transformResult: (job)=>({
1054
+ drafts: job.result.drafts,
1055
+ projectUrl: job.result.projectUrl,
1056
+ creditsConsumed: job.creditsConsumed
1057
+ }),
1058
+ displayResult: (job)=>{
1059
+ success(`Created ${job.result.drafts.length} draft variation(s)!`);
1060
+ info(`\nProject URL: ${job.result.projectUrl}`);
1061
+ info(`Credits consumed: ${job.creditsConsumed}`);
1062
+ info('\nDrafts:');
1063
+ job.result.drafts.forEach((draft, i)=>{
1064
+ info(` ${i + 1}. ${draft.title}`);
1065
+ info(` Draft ID: ${draft.draftId}`);
1066
+ info(` Preview: ${draft.previewUrl}`);
1067
+ });
1068
+ }
1069
+ });
1070
+ });
1071
+ return command;
1072
+ }
1073
+ function createPlanFlowPagesCommand() {
1074
+ const command = new external_commander_namespaceObject.Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--source-node-id <id>', 'Source node ID in the flow').option('--context <context>', 'Additional context for flow planning').option('--json', 'Output in JSON format').action(async (options)=>{
1075
+ if (options.json) setJsonMode(true);
1076
+ job_runner_requireAuth(manager_isAuthenticated);
1077
+ await runJob({
1078
+ startLabel: 'Planning flow pages...',
1079
+ pollingLabel: 'AI is analyzing and planning pages...',
1080
+ successLabel: 'Flow pages planned!',
1081
+ timeoutLabel: 'Planning timed out',
1082
+ failureLabel: 'Failed to plan flow pages',
1083
+ startJob: ()=>planFlowPages(options.draftId, {
1084
+ sourceNodeId: options.sourceNodeId,
1085
+ flowContext: options.context
1086
+ }),
1087
+ transformResult: (job)=>({
1088
+ pages: job.result.pages,
1089
+ creditsConsumed: job.creditsConsumed
1090
+ }),
1091
+ displayResult: (job)=>{
1092
+ success(`Planned ${job.result.pages.length} flow page(s)!`);
1093
+ info(`Credits consumed: ${job.creditsConsumed}`);
1094
+ info('\nSuggested pages:');
1095
+ job.result.pages.forEach((page, i)=>{
1096
+ info(`\n ${i + 1}. ${page.title}`);
1097
+ const promptPreview = page.prompt.length > 100 ? `${page.prompt.substring(0, 100)}...` : page.prompt;
1098
+ info(` Prompt: ${promptPreview}`);
1099
+ });
1100
+ info('\nUse `superdesign execute-flow-pages` to generate these pages.');
1101
+ }
1102
+ });
1103
+ });
1104
+ return command;
1105
+ }
1106
+ function parsePages(pagesJson) {
1107
+ const parsed = JSON.parse(pagesJson);
1108
+ if (!Array.isArray(parsed)) throw new Error('Pages must be an array');
1109
+ for (const page of parsed){
1110
+ if (!page.title || 'string' != typeof page.title) throw new Error('Each page must have a title string');
1111
+ if (!page.prompt || 'string' != typeof page.prompt) throw new Error('Each page must have a prompt string');
1112
+ }
1113
+ return parsed;
1114
+ }
1115
+ function createExecuteFlowPagesCommand() {
1116
+ const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--source-node-id <id>', 'Source node ID in the flow').requiredOption('--pages <json>', 'JSON array of pages to generate [{title, prompt}]').option('--context <context>', 'Additional context for flow generation').option('--json', 'Output in JSON format').action(async (options)=>{
1117
+ if (options.json) setJsonMode(true);
1118
+ job_runner_requireAuth(manager_isAuthenticated);
1119
+ let pages;
1120
+ try {
1121
+ pages = parsePages(options.pages);
1122
+ } catch (parseErr) {
1123
+ const msg = parseErr instanceof Error ? parseErr.message : 'Invalid JSON';
1124
+ output_error(`Invalid pages JSON: ${msg}`);
1125
+ output_error('Expected format: [{"title": "Page 1", "prompt": "Create a..."}]');
1126
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1127
+ }
1128
+ if (0 === pages.length) {
1129
+ output_error('At least one page is required');
1130
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1131
+ }
1132
+ if (pages.length > 10) {
1133
+ output_error('Maximum 10 pages allowed');
1134
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1135
+ }
1136
+ const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
1137
+ await runJob({
1138
+ startLabel: `Generating ${pages.length} flow page(s)...`,
1139
+ pollingLabel: `AI is generating ${pages.length} page(s)...`,
1140
+ successLabel: 'Flow pages generated!',
1141
+ timeoutLabel: 'Generation timed out',
1142
+ failureLabel: 'Failed to execute flow pages',
1143
+ timeoutMs,
1144
+ startJob: ()=>executeFlowPages(options.draftId, {
1145
+ sourceNodeId: options.sourceNodeId,
1146
+ flowContext: options.context,
1147
+ pages
1148
+ }),
1149
+ transformResult: (job)=>({
1150
+ drafts: job.result.drafts,
1151
+ projectUrl: job.result.projectUrl,
1152
+ creditsConsumed: job.creditsConsumed
1153
+ }),
1154
+ displayResult: (job)=>{
1155
+ success(`Generated ${job.result.drafts.length} flow page(s)!`);
1156
+ info(`\nProject URL: ${job.result.projectUrl}`);
1157
+ info(`Credits consumed: ${job.creditsConsumed}`);
1158
+ info('\nGenerated pages:');
1159
+ job.result.drafts.forEach((draft)=>{
1160
+ info(`\n ${draft.index + 1}. ${draft.title}`);
1161
+ info(` Draft ID: ${draft.draftId}`);
1162
+ info(` Node URL: ${draft.nodeUrl}`);
1163
+ info(` Preview: ${draft.previewUrl}`);
1164
+ });
1165
+ }
1166
+ });
1167
+ });
1168
+ return command;
1169
+ }
1170
+ const src_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
1171
+ const src_dirname = (0, external_path_namespaceObject.dirname)(src_filename);
1172
+ (0, external_dotenv_namespaceObject.config)({
1173
+ path: (0, external_path_namespaceObject.resolve)(src_dirname, '../.env')
1174
+ });
1175
+ (0, external_dotenv_namespaceObject.config)();
1176
+ function createProgram() {
1177
+ const program = new external_commander_namespaceObject.Command();
1178
+ program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.0");
1179
+ program.addCommand(createLoginCommand());
1180
+ program.addCommand(createLogoutCommand());
1181
+ program.addCommand(createInitCommand());
1182
+ program.addCommand(createCreateProjectCommand());
1183
+ program.addCommand(createCreateDesignDraftCommand());
1184
+ program.addCommand(createIterateDesignDraftCommand());
1185
+ program.addCommand(createPlanFlowPagesCommand());
1186
+ program.addCommand(createExecuteFlowPagesCommand());
1187
+ return program;
1188
+ }
1189
+ async function run() {
1190
+ const program = createProgram();
1191
+ await program.parseAsync(process.argv);
1192
+ }
1193
+ })();
1194
+ exports.ApiClientError = __webpack_exports__.ApiClientError;
1195
+ exports.addDraft = __webpack_exports__.addDraft;
1196
+ exports.claimSession = __webpack_exports__.claimSession;
1197
+ exports.clearConfig = __webpack_exports__.clearConfig;
1198
+ exports.createApiClient = __webpack_exports__.createApiClient;
1199
+ exports.createDraft = __webpack_exports__.createDraft;
1200
+ exports.createProgram = __webpack_exports__.createProgram;
1201
+ exports.createProject = __webpack_exports__.createProject;
1202
+ exports.createPublicApiClient = __webpack_exports__.createPublicApiClient;
1203
+ exports.createSession = __webpack_exports__.createSession;
1204
+ exports.executeFlowPages = __webpack_exports__.executeFlowPages;
1205
+ exports.getApiClient = __webpack_exports__.getApiClient;
1206
+ exports.getApiKey = __webpack_exports__.getApiKey;
1207
+ exports.getApiUrl = __webpack_exports__.getApiUrl;
1208
+ exports.getConfigDir = __webpack_exports__.getConfigDir;
1209
+ exports.getConfigPath = __webpack_exports__.getConfigPath;
1210
+ exports.getJobStatus = __webpack_exports__.getJobStatus;
1211
+ exports.isAuthenticated = __webpack_exports__.isAuthenticated;
1212
+ exports.isJobCompleted = __webpack_exports__.isJobCompleted;
1213
+ exports.isJobDone = __webpack_exports__.isJobDone;
1214
+ exports.isJobFailed = __webpack_exports__.isJobFailed;
1215
+ exports.iterateDraft = __webpack_exports__.iterateDraft;
1216
+ exports.loadConfig = __webpack_exports__.loadConfig;
1217
+ exports.planFlowPages = __webpack_exports__.planFlowPages;
1218
+ exports.pollSession = __webpack_exports__.pollSession;
1219
+ exports.run = __webpack_exports__.run;
1220
+ exports.saveConfig = __webpack_exports__.saveConfig;
1221
+ exports.updateConfig = __webpack_exports__.updateConfig;
1222
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1223
+ "ApiClientError",
1224
+ "addDraft",
1225
+ "claimSession",
1226
+ "clearConfig",
1227
+ "createApiClient",
1228
+ "createDraft",
1229
+ "createProgram",
1230
+ "createProject",
1231
+ "createPublicApiClient",
1232
+ "createSession",
1233
+ "executeFlowPages",
1234
+ "getApiClient",
1235
+ "getApiKey",
1236
+ "getApiUrl",
1237
+ "getConfigDir",
1238
+ "getConfigPath",
1239
+ "getJobStatus",
1240
+ "isAuthenticated",
1241
+ "isJobCompleted",
1242
+ "isJobDone",
1243
+ "isJobFailed",
1244
+ "iterateDraft",
1245
+ "loadConfig",
1246
+ "planFlowPages",
1247
+ "pollSession",
1248
+ "run",
1249
+ "saveConfig",
1250
+ "updateConfig"
1251
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
1252
+ Object.defineProperty(exports, '__esModule', {
1253
+ value: true
1254
+ });