@superdesign/cli 0.1.12 → 0.2.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/api/drafts.d.ts +7 -0
- package/dist/config/constants.d.ts +1 -1
- package/dist/index.cjs +118 -24
- package/dist/index.js +119 -25
- package/dist/utils/context-files.d.ts +9 -0
- package/package.json +2 -2
package/dist/api/drafts.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Drafts API endpoints
|
|
3
3
|
*/
|
|
4
|
+
export interface ContextFile {
|
|
5
|
+
filename: string;
|
|
6
|
+
content: string;
|
|
7
|
+
}
|
|
4
8
|
export interface CreateDraftRequest {
|
|
5
9
|
title: string;
|
|
6
10
|
prompt: string;
|
|
7
11
|
deviceMode?: 'mobile' | 'tablet' | 'desktop';
|
|
12
|
+
contextFiles?: ContextFile[];
|
|
8
13
|
}
|
|
9
14
|
export interface IterateDraftRequest {
|
|
10
15
|
prompts?: string[];
|
|
11
16
|
prompt?: string;
|
|
12
17
|
count?: 1 | 2 | 3 | 4;
|
|
13
18
|
mode: 'replace' | 'branch';
|
|
19
|
+
contextFiles?: ContextFile[];
|
|
14
20
|
}
|
|
15
21
|
export interface PlanFlowRequest {
|
|
16
22
|
flowContext?: string;
|
|
@@ -22,6 +28,7 @@ export interface FlowPage {
|
|
|
22
28
|
export interface ExecuteFlowRequest {
|
|
23
29
|
flowContext?: string;
|
|
24
30
|
pages: FlowPage[];
|
|
31
|
+
contextFiles?: ContextFile[];
|
|
25
32
|
}
|
|
26
33
|
export interface JobCreatedResponse {
|
|
27
34
|
jobId: string;
|
|
@@ -12,7 +12,7 @@ export declare const POLL_TIMEOUT_MS: number;
|
|
|
12
12
|
export declare const AUTH_POLL_INTERVAL_MS = 2000;
|
|
13
13
|
export declare const AUTH_POLL_TIMEOUT_MS: number;
|
|
14
14
|
/** CLI version - should match package.json */
|
|
15
|
-
export declare const CLI_VERSION = "0.
|
|
15
|
+
export declare const CLI_VERSION = "0.2.0";
|
|
16
16
|
/** PostHog analytics configuration */
|
|
17
17
|
export declare const POSTHOG_KEY: string;
|
|
18
18
|
export declare const POSTHOG_HOST: string;
|
package/dist/index.cjs
CHANGED
|
@@ -316,7 +316,7 @@ var __webpack_exports__ = {};
|
|
|
316
316
|
try {
|
|
317
317
|
startSpinner('Creating auth session...');
|
|
318
318
|
const session = await createSession({
|
|
319
|
-
cliVersion: "0.
|
|
319
|
+
cliVersion: "0.2.0",
|
|
320
320
|
os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
|
|
321
321
|
hostname: external_os_namespaceObject.hostname()
|
|
322
322
|
});
|
|
@@ -799,11 +799,30 @@ superdesign --help
|
|
|
799
799
|
const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
|
|
800
800
|
return response.data;
|
|
801
801
|
}
|
|
802
|
+
function readContextFiles(filePaths) {
|
|
803
|
+
const cwd = process.cwd();
|
|
804
|
+
return filePaths.map((filePath)=>{
|
|
805
|
+
const absolutePath = (0, external_path_namespaceObject.resolve)(cwd, filePath);
|
|
806
|
+
try {
|
|
807
|
+
const content = (0, external_fs_namespaceObject.readFileSync)(absolutePath, 'utf-8');
|
|
808
|
+
const filename = (0, external_path_namespaceObject.relative)(cwd, absolutePath);
|
|
809
|
+
return {
|
|
810
|
+
filename,
|
|
811
|
+
content
|
|
812
|
+
};
|
|
813
|
+
} catch (err) {
|
|
814
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
815
|
+
output_error(`Failed to read context file "${filePath}": ${msg}`);
|
|
816
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
817
|
+
}
|
|
818
|
+
});
|
|
819
|
+
}
|
|
802
820
|
function createCreateDesignDraftCommand() {
|
|
803
|
-
const command = new external_commander_namespaceObject.Command('create-design-draft').description('Create a design draft from scratch without any reference, Default dont use this, use iterate-design-draft instead').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('-p, --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)=>{
|
|
821
|
+
const command = new external_commander_namespaceObject.Command('create-design-draft').description('Create a design draft from scratch without any reference, Default dont use this, use iterate-design-draft instead').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('-p, --prompt <prompt>', 'Design prompt for AI generation').option('--device <mode>', 'Device mode (mobile, tablet, desktop)', 'desktop').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
804
822
|
if (options.json) setJsonMode(true);
|
|
805
823
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
806
824
|
validateDeviceMode(options.device);
|
|
825
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
807
826
|
await runJob({
|
|
808
827
|
startLabel: 'Creating design draft...',
|
|
809
828
|
pollingLabel: 'Generating design with AI...',
|
|
@@ -813,7 +832,8 @@ superdesign --help
|
|
|
813
832
|
startJob: ()=>createDraft(options.projectId, {
|
|
814
833
|
title: options.title,
|
|
815
834
|
prompt: options.prompt,
|
|
816
|
-
deviceMode: options.device
|
|
835
|
+
deviceMode: options.device,
|
|
836
|
+
contextFiles
|
|
817
837
|
}),
|
|
818
838
|
transformResult: (job)=>({
|
|
819
839
|
draftId: job.result.draftId,
|
|
@@ -885,17 +905,20 @@ Usage Examples:
|
|
|
885
905
|
superdesign iterate-design-draft --draft-id <id> -p "dark theme" -p "minimal" -p "bold" --mode branch --json
|
|
886
906
|
|
|
887
907
|
# Iterate: Auto explore (only give exploration direction, and let Superdesign fill in details, e.g. explore different styles; Default do NOT use auto explore mode)
|
|
888
|
-
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json`).requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('-p, --prompt <prompt...>', 'Iteration prompt(s). Use multiple -p for specific prompts per variation.').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations (1-4). Only used when single prompt provided.').option('--json', 'Output in JSON format').addOption(new external_commander_namespaceObject.Option('--project-id <id>').hideHelp()).action(async (options)=>{
|
|
908
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json`).requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('-p, --prompt <prompt...>', 'Iteration prompt(s). Use multiple -p for specific prompts per variation.').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations (1-4). Only used when single prompt provided.').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').addOption(new external_commander_namespaceObject.Option('--project-id <id>').hideHelp()).action(async (options)=>{
|
|
889
909
|
if (options.json) setJsonMode(true);
|
|
890
910
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
891
911
|
const { prompts, count, mode } = validateOptions(options);
|
|
912
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
892
913
|
const requestData = prompts.length > 1 ? {
|
|
893
914
|
prompts,
|
|
894
|
-
mode
|
|
915
|
+
mode,
|
|
916
|
+
contextFiles
|
|
895
917
|
} : {
|
|
896
918
|
prompt: prompts[0],
|
|
897
919
|
count: count,
|
|
898
|
-
mode
|
|
920
|
+
mode,
|
|
921
|
+
contextFiles
|
|
899
922
|
};
|
|
900
923
|
await runJob({
|
|
901
924
|
startLabel: 'Starting iteration...',
|
|
@@ -966,7 +989,7 @@ Usage Examples:
|
|
|
966
989
|
return parsed;
|
|
967
990
|
}
|
|
968
991
|
function createExecuteFlowPagesCommand() {
|
|
969
|
-
const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').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)=>{
|
|
992
|
+
const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--pages <json>', 'JSON array of pages to generate [{title, prompt}]').option('--context <context>', 'Additional context for flow generation').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
970
993
|
if (options.json) setJsonMode(true);
|
|
971
994
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
972
995
|
let pages;
|
|
@@ -986,6 +1009,7 @@ Usage Examples:
|
|
|
986
1009
|
output_error('Maximum 10 pages allowed');
|
|
987
1010
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
988
1011
|
}
|
|
1012
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
989
1013
|
const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
|
|
990
1014
|
await runJob({
|
|
991
1015
|
startLabel: `Generating ${pages.length} flow page(s)...`,
|
|
@@ -996,7 +1020,8 @@ Usage Examples:
|
|
|
996
1020
|
timeoutMs,
|
|
997
1021
|
startJob: ()=>executeFlowPages(options.draftId, {
|
|
998
1022
|
flowContext: options.context,
|
|
999
|
-
pages
|
|
1023
|
+
pages,
|
|
1024
|
+
contextFiles
|
|
1000
1025
|
}),
|
|
1001
1026
|
transformResult: (job)=>({
|
|
1002
1027
|
drafts: job.result.drafts,
|
|
@@ -1311,7 +1336,7 @@ Usage Examples:
|
|
|
1311
1336
|
durationMs: opts.durationMs,
|
|
1312
1337
|
errorCode: opts.errorCode,
|
|
1313
1338
|
options: opts.options,
|
|
1314
|
-
cliVersion: "0.
|
|
1339
|
+
cliVersion: "0.2.0",
|
|
1315
1340
|
os: `${external_os_default().platform()} ${external_os_default().release()}`
|
|
1316
1341
|
};
|
|
1317
1342
|
const posthog = getPostHog();
|
|
@@ -1346,9 +1371,46 @@ Usage Examples:
|
|
|
1346
1371
|
path: (0, external_path_namespaceObject.resolve)(src_dirname, '../.env')
|
|
1347
1372
|
});
|
|
1348
1373
|
(0, external_dotenv_namespaceObject.config)();
|
|
1374
|
+
function getFailedCommandUsage(program) {
|
|
1375
|
+
const failedCommand = findFailedCommand(program);
|
|
1376
|
+
if (!failedCommand) return {
|
|
1377
|
+
message: 'Run with --help for usage information'
|
|
1378
|
+
};
|
|
1379
|
+
return {
|
|
1380
|
+
command: failedCommand.name(),
|
|
1381
|
+
description: failedCommand.description(),
|
|
1382
|
+
requiredOptions: failedCommand.options.filter((opt)=>opt.mandatory).map((opt)=>({
|
|
1383
|
+
flags: opt.flags,
|
|
1384
|
+
description: opt.description
|
|
1385
|
+
})),
|
|
1386
|
+
allOptions: failedCommand.options.map((opt)=>({
|
|
1387
|
+
flags: opt.flags,
|
|
1388
|
+
description: opt.description,
|
|
1389
|
+
required: opt.mandatory
|
|
1390
|
+
}))
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
function getFailedCommandHelp(program) {
|
|
1394
|
+
const failedCommand = findFailedCommand(program);
|
|
1395
|
+
if (!failedCommand) return '\nRun with --help for usage information\n';
|
|
1396
|
+
return '\n' + failedCommand.helpInformation();
|
|
1397
|
+
}
|
|
1398
|
+
function findFailedCommand(program) {
|
|
1399
|
+
const args = process.argv;
|
|
1400
|
+
const commandName = args[2];
|
|
1401
|
+
if (!commandName || commandName.startsWith('-')) return program;
|
|
1402
|
+
const subcommand = program.commands.find((cmd)=>cmd.name() === commandName);
|
|
1403
|
+
return subcommand || program;
|
|
1404
|
+
}
|
|
1349
1405
|
function createProgram() {
|
|
1350
1406
|
const program = new external_commander_namespaceObject.Command();
|
|
1351
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.
|
|
1407
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.2.0");
|
|
1408
|
+
program.configureOutput({
|
|
1409
|
+
writeErr: (str)=>{
|
|
1410
|
+
if (!process.argv.includes('--json')) process.stderr.write(str);
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1413
|
+
program.exitOverride();
|
|
1352
1414
|
let startTime = 0;
|
|
1353
1415
|
program.hook('preAction', ()=>{
|
|
1354
1416
|
startTime = Date.now();
|
|
@@ -1362,26 +1424,58 @@ Usage Examples:
|
|
|
1362
1424
|
});
|
|
1363
1425
|
await shutdownAnalytics();
|
|
1364
1426
|
});
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1427
|
+
const addCommandWithOverride = (cmd, opts)=>{
|
|
1428
|
+
cmd.exitOverride();
|
|
1429
|
+
cmd.configureOutput({
|
|
1430
|
+
writeErr: (str)=>{
|
|
1431
|
+
if (!process.argv.includes('--json')) process.stderr.write(str);
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
program.addCommand(cmd, opts);
|
|
1435
|
+
};
|
|
1436
|
+
addCommandWithOverride(createLoginCommand());
|
|
1437
|
+
addCommandWithOverride(createLogoutCommand());
|
|
1438
|
+
addCommandWithOverride(createInitCommand());
|
|
1439
|
+
addCommandWithOverride(createCreateProjectCommand());
|
|
1440
|
+
addCommandWithOverride(createIterateDesignDraftCommand());
|
|
1441
|
+
addCommandWithOverride(createPlanFlowPagesCommand(), {
|
|
1371
1442
|
hidden: true
|
|
1372
1443
|
});
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1444
|
+
addCommandWithOverride(createExecuteFlowPagesCommand());
|
|
1445
|
+
addCommandWithOverride(createExtractBrandGuideCommand());
|
|
1446
|
+
addCommandWithOverride(createSearchPromptsCommand());
|
|
1447
|
+
addCommandWithOverride(createGetPromptsCommand());
|
|
1448
|
+
addCommandWithOverride(createFetchDesignNodesCommand());
|
|
1449
|
+
addCommandWithOverride(createGetDesignCommand());
|
|
1450
|
+
addCommandWithOverride(createCreateDesignDraftCommand());
|
|
1380
1451
|
return program;
|
|
1381
1452
|
}
|
|
1382
1453
|
async function run() {
|
|
1383
1454
|
const program = createProgram();
|
|
1384
|
-
|
|
1455
|
+
try {
|
|
1456
|
+
await program.parseAsync(process.argv);
|
|
1457
|
+
} catch (err) {
|
|
1458
|
+
if (err && 'object' == typeof err && 'code' in err) {
|
|
1459
|
+
const commanderError = err;
|
|
1460
|
+
if ('commander.helpDisplayed' === commanderError.code || 'commander.version' === commanderError.code) process.exit(0);
|
|
1461
|
+
if ('commander.missingMandatoryOptionValue' === commanderError.code) {
|
|
1462
|
+
const hasJsonFlag = process.argv.includes('--json');
|
|
1463
|
+
if (hasJsonFlag) {
|
|
1464
|
+
const errorOutput = {
|
|
1465
|
+
error: commanderError.message,
|
|
1466
|
+
usage: getFailedCommandUsage(program)
|
|
1467
|
+
};
|
|
1468
|
+
process.stderr.write(JSON.stringify(errorOutput, null, 2) + '\n');
|
|
1469
|
+
} else {
|
|
1470
|
+
process.stderr.write('\n');
|
|
1471
|
+
const helpInfo = getFailedCommandHelp(program);
|
|
1472
|
+
if (helpInfo) process.stderr.write(helpInfo);
|
|
1473
|
+
}
|
|
1474
|
+
process.exit(1);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
throw err;
|
|
1478
|
+
}
|
|
1385
1479
|
}
|
|
1386
1480
|
})();
|
|
1387
1481
|
exports.ApiClientError = __webpack_exports__.ApiClientError;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { config as external_dotenv_config } from "dotenv";
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
|
-
import { dirname, join, resolve as external_path_resolve } from "path";
|
|
3
|
+
import { dirname, join, relative, resolve as external_path_resolve } from "path";
|
|
4
4
|
import { Command, Option } from "commander";
|
|
5
5
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
6
6
|
import os, { homedir, hostname, platform, release } from "os";
|
|
@@ -226,7 +226,7 @@ async function runAuthFlow(options = {}) {
|
|
|
226
226
|
try {
|
|
227
227
|
startSpinner('Creating auth session...');
|
|
228
228
|
const session = await createSession({
|
|
229
|
-
cliVersion: "0.
|
|
229
|
+
cliVersion: "0.2.0",
|
|
230
230
|
os: `${platform()} ${release()}`,
|
|
231
231
|
hostname: hostname()
|
|
232
232
|
});
|
|
@@ -709,11 +709,30 @@ async function executeFlowPages(draftId, data) {
|
|
|
709
709
|
const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
|
|
710
710
|
return response.data;
|
|
711
711
|
}
|
|
712
|
+
function readContextFiles(filePaths) {
|
|
713
|
+
const cwd = process.cwd();
|
|
714
|
+
return filePaths.map((filePath)=>{
|
|
715
|
+
const absolutePath = external_path_resolve(cwd, filePath);
|
|
716
|
+
try {
|
|
717
|
+
const content = readFileSync(absolutePath, 'utf-8');
|
|
718
|
+
const filename = relative(cwd, absolutePath);
|
|
719
|
+
return {
|
|
720
|
+
filename,
|
|
721
|
+
content
|
|
722
|
+
};
|
|
723
|
+
} catch (err) {
|
|
724
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
725
|
+
output_error(`Failed to read context file "${filePath}": ${msg}`);
|
|
726
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
727
|
+
}
|
|
728
|
+
});
|
|
729
|
+
}
|
|
712
730
|
function createCreateDesignDraftCommand() {
|
|
713
|
-
const command = new Command('create-design-draft').description('Create a design draft from scratch without any reference, Default dont use this, use iterate-design-draft instead').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('-p, --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)=>{
|
|
731
|
+
const command = new Command('create-design-draft').description('Create a design draft from scratch without any reference, Default dont use this, use iterate-design-draft instead').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('-p, --prompt <prompt>', 'Design prompt for AI generation').option('--device <mode>', 'Device mode (mobile, tablet, desktop)', 'desktop').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
714
732
|
if (options.json) setJsonMode(true);
|
|
715
733
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
716
734
|
validateDeviceMode(options.device);
|
|
735
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
717
736
|
await runJob({
|
|
718
737
|
startLabel: 'Creating design draft...',
|
|
719
738
|
pollingLabel: 'Generating design with AI...',
|
|
@@ -723,7 +742,8 @@ function createCreateDesignDraftCommand() {
|
|
|
723
742
|
startJob: ()=>createDraft(options.projectId, {
|
|
724
743
|
title: options.title,
|
|
725
744
|
prompt: options.prompt,
|
|
726
|
-
deviceMode: options.device
|
|
745
|
+
deviceMode: options.device,
|
|
746
|
+
contextFiles
|
|
727
747
|
}),
|
|
728
748
|
transformResult: (job)=>({
|
|
729
749
|
draftId: job.result.draftId,
|
|
@@ -795,17 +815,20 @@ Usage Examples:
|
|
|
795
815
|
superdesign iterate-design-draft --draft-id <id> -p "dark theme" -p "minimal" -p "bold" --mode branch --json
|
|
796
816
|
|
|
797
817
|
# Iterate: Auto explore (only give exploration direction, and let Superdesign fill in details, e.g. explore different styles; Default do NOT use auto explore mode)
|
|
798
|
-
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json`).requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('-p, --prompt <prompt...>', 'Iteration prompt(s). Use multiple -p for specific prompts per variation.').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations (1-4). Only used when single prompt provided.').option('--json', 'Output in JSON format').addOption(new Option('--project-id <id>').hideHelp()).action(async (options)=>{
|
|
818
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json`).requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('-p, --prompt <prompt...>', 'Iteration prompt(s). Use multiple -p for specific prompts per variation.').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations (1-4). Only used when single prompt provided.').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').addOption(new Option('--project-id <id>').hideHelp()).action(async (options)=>{
|
|
799
819
|
if (options.json) setJsonMode(true);
|
|
800
820
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
801
821
|
const { prompts, count, mode } = validateOptions(options);
|
|
822
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
802
823
|
const requestData = prompts.length > 1 ? {
|
|
803
824
|
prompts,
|
|
804
|
-
mode
|
|
825
|
+
mode,
|
|
826
|
+
contextFiles
|
|
805
827
|
} : {
|
|
806
828
|
prompt: prompts[0],
|
|
807
829
|
count: count,
|
|
808
|
-
mode
|
|
830
|
+
mode,
|
|
831
|
+
contextFiles
|
|
809
832
|
};
|
|
810
833
|
await runJob({
|
|
811
834
|
startLabel: 'Starting iteration...',
|
|
@@ -876,7 +899,7 @@ function parsePages(pagesJson) {
|
|
|
876
899
|
return parsed;
|
|
877
900
|
}
|
|
878
901
|
function createExecuteFlowPagesCommand() {
|
|
879
|
-
const command = new Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').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)=>{
|
|
902
|
+
const command = new Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--pages <json>', 'JSON array of pages to generate [{title, prompt}]').option('--context <context>', 'Additional context for flow generation').option('--context-file <paths...>', 'UI source files to include as context for AI generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
880
903
|
if (options.json) setJsonMode(true);
|
|
881
904
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
882
905
|
let pages;
|
|
@@ -896,6 +919,7 @@ function createExecuteFlowPagesCommand() {
|
|
|
896
919
|
output_error('Maximum 10 pages allowed');
|
|
897
920
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
898
921
|
}
|
|
922
|
+
const contextFiles = options.contextFile ? readContextFiles(options.contextFile) : void 0;
|
|
899
923
|
const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
|
|
900
924
|
await runJob({
|
|
901
925
|
startLabel: `Generating ${pages.length} flow page(s)...`,
|
|
@@ -906,7 +930,8 @@ function createExecuteFlowPagesCommand() {
|
|
|
906
930
|
timeoutMs,
|
|
907
931
|
startJob: ()=>executeFlowPages(options.draftId, {
|
|
908
932
|
flowContext: options.context,
|
|
909
|
-
pages
|
|
933
|
+
pages,
|
|
934
|
+
contextFiles
|
|
910
935
|
}),
|
|
911
936
|
transformResult: (job)=>({
|
|
912
937
|
drafts: job.result.drafts,
|
|
@@ -1219,7 +1244,7 @@ async function trackCommand(opts) {
|
|
|
1219
1244
|
durationMs: opts.durationMs,
|
|
1220
1245
|
errorCode: opts.errorCode,
|
|
1221
1246
|
options: opts.options,
|
|
1222
|
-
cliVersion: "0.
|
|
1247
|
+
cliVersion: "0.2.0",
|
|
1223
1248
|
os: `${os.platform()} ${os.release()}`
|
|
1224
1249
|
};
|
|
1225
1250
|
const posthog = getPostHog();
|
|
@@ -1254,9 +1279,46 @@ external_dotenv_config({
|
|
|
1254
1279
|
path: external_path_resolve(src_dirname, '../.env')
|
|
1255
1280
|
});
|
|
1256
1281
|
external_dotenv_config();
|
|
1282
|
+
function getFailedCommandUsage(program) {
|
|
1283
|
+
const failedCommand = findFailedCommand(program);
|
|
1284
|
+
if (!failedCommand) return {
|
|
1285
|
+
message: 'Run with --help for usage information'
|
|
1286
|
+
};
|
|
1287
|
+
return {
|
|
1288
|
+
command: failedCommand.name(),
|
|
1289
|
+
description: failedCommand.description(),
|
|
1290
|
+
requiredOptions: failedCommand.options.filter((opt)=>opt.mandatory).map((opt)=>({
|
|
1291
|
+
flags: opt.flags,
|
|
1292
|
+
description: opt.description
|
|
1293
|
+
})),
|
|
1294
|
+
allOptions: failedCommand.options.map((opt)=>({
|
|
1295
|
+
flags: opt.flags,
|
|
1296
|
+
description: opt.description,
|
|
1297
|
+
required: opt.mandatory
|
|
1298
|
+
}))
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
function getFailedCommandHelp(program) {
|
|
1302
|
+
const failedCommand = findFailedCommand(program);
|
|
1303
|
+
if (!failedCommand) return '\nRun with --help for usage information\n';
|
|
1304
|
+
return '\n' + failedCommand.helpInformation();
|
|
1305
|
+
}
|
|
1306
|
+
function findFailedCommand(program) {
|
|
1307
|
+
const args = process.argv;
|
|
1308
|
+
const commandName = args[2];
|
|
1309
|
+
if (!commandName || commandName.startsWith('-')) return program;
|
|
1310
|
+
const subcommand = program.commands.find((cmd)=>cmd.name() === commandName);
|
|
1311
|
+
return subcommand || program;
|
|
1312
|
+
}
|
|
1257
1313
|
function createProgram() {
|
|
1258
1314
|
const program = new Command();
|
|
1259
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.
|
|
1315
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.2.0");
|
|
1316
|
+
program.configureOutput({
|
|
1317
|
+
writeErr: (str)=>{
|
|
1318
|
+
if (!process.argv.includes('--json')) process.stderr.write(str);
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
program.exitOverride();
|
|
1260
1322
|
let startTime = 0;
|
|
1261
1323
|
program.hook('preAction', ()=>{
|
|
1262
1324
|
startTime = Date.now();
|
|
@@ -1270,25 +1332,57 @@ function createProgram() {
|
|
|
1270
1332
|
});
|
|
1271
1333
|
await shutdownAnalytics();
|
|
1272
1334
|
});
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1335
|
+
const addCommandWithOverride = (cmd, opts)=>{
|
|
1336
|
+
cmd.exitOverride();
|
|
1337
|
+
cmd.configureOutput({
|
|
1338
|
+
writeErr: (str)=>{
|
|
1339
|
+
if (!process.argv.includes('--json')) process.stderr.write(str);
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
1342
|
+
program.addCommand(cmd, opts);
|
|
1343
|
+
};
|
|
1344
|
+
addCommandWithOverride(createLoginCommand());
|
|
1345
|
+
addCommandWithOverride(createLogoutCommand());
|
|
1346
|
+
addCommandWithOverride(createInitCommand());
|
|
1347
|
+
addCommandWithOverride(createCreateProjectCommand());
|
|
1348
|
+
addCommandWithOverride(createIterateDesignDraftCommand());
|
|
1349
|
+
addCommandWithOverride(createPlanFlowPagesCommand(), {
|
|
1279
1350
|
hidden: true
|
|
1280
1351
|
});
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1352
|
+
addCommandWithOverride(createExecuteFlowPagesCommand());
|
|
1353
|
+
addCommandWithOverride(createExtractBrandGuideCommand());
|
|
1354
|
+
addCommandWithOverride(createSearchPromptsCommand());
|
|
1355
|
+
addCommandWithOverride(createGetPromptsCommand());
|
|
1356
|
+
addCommandWithOverride(createFetchDesignNodesCommand());
|
|
1357
|
+
addCommandWithOverride(createGetDesignCommand());
|
|
1358
|
+
addCommandWithOverride(createCreateDesignDraftCommand());
|
|
1288
1359
|
return program;
|
|
1289
1360
|
}
|
|
1290
1361
|
async function run() {
|
|
1291
1362
|
const program = createProgram();
|
|
1292
|
-
|
|
1363
|
+
try {
|
|
1364
|
+
await program.parseAsync(process.argv);
|
|
1365
|
+
} catch (err) {
|
|
1366
|
+
if (err && 'object' == typeof err && 'code' in err) {
|
|
1367
|
+
const commanderError = err;
|
|
1368
|
+
if ('commander.helpDisplayed' === commanderError.code || 'commander.version' === commanderError.code) process.exit(0);
|
|
1369
|
+
if ('commander.missingMandatoryOptionValue' === commanderError.code) {
|
|
1370
|
+
const hasJsonFlag = process.argv.includes('--json');
|
|
1371
|
+
if (hasJsonFlag) {
|
|
1372
|
+
const errorOutput = {
|
|
1373
|
+
error: commanderError.message,
|
|
1374
|
+
usage: getFailedCommandUsage(program)
|
|
1375
|
+
};
|
|
1376
|
+
process.stderr.write(JSON.stringify(errorOutput, null, 2) + '\n');
|
|
1377
|
+
} else {
|
|
1378
|
+
process.stderr.write('\n');
|
|
1379
|
+
const helpInfo = getFailedCommandHelp(program);
|
|
1380
|
+
if (helpInfo) process.stderr.write(helpInfo);
|
|
1381
|
+
}
|
|
1382
|
+
process.exit(1);
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
throw err;
|
|
1386
|
+
}
|
|
1293
1387
|
}
|
|
1294
1388
|
export { ApiClientError, addDraft, claimSession, clearConfig, createApiClient, createDraft, createProgram, createProject, createPublicApiClient, createSession, executeFlowPages, extractBrandGuide, fetchDesignNodes, getApiClient, getApiKey, getApiUrl, getConfigDir, getConfigPath, getDesignHtml, getJobStatus, getPrompts, manager_isAuthenticated as isAuthenticated, isJobCompleted, isJobDone, isJobFailed, iterateDraft, loadConfig, planFlowPages, pollSession, run, saveConfig, searchPrompts, updateConfig };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for reading context files from disk
|
|
3
|
+
*/
|
|
4
|
+
import type { ContextFile } from '../api/drafts';
|
|
5
|
+
/**
|
|
6
|
+
* Read context files from disk and return as ContextFile array.
|
|
7
|
+
* Exits the process if any file cannot be read.
|
|
8
|
+
*/
|
|
9
|
+
export declare function readContextFiles(filePaths: string[]): ContextFile[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdesign/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI for SuperDesign Platform - agent skills for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -53,4 +53,4 @@
|
|
|
53
53
|
"directory": "packages/cli"
|
|
54
54
|
},
|
|
55
55
|
"license": "MIT"
|
|
56
|
-
}
|
|
56
|
+
}
|