@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.
@@ -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.1.12";
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.1.12",
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.1.12",
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.1.12");
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
- program.addCommand(createLoginCommand());
1366
- program.addCommand(createLogoutCommand());
1367
- program.addCommand(createInitCommand());
1368
- program.addCommand(createCreateProjectCommand());
1369
- program.addCommand(createIterateDesignDraftCommand());
1370
- program.addCommand(createPlanFlowPagesCommand(), {
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
- program.addCommand(createExecuteFlowPagesCommand());
1374
- program.addCommand(createExtractBrandGuideCommand());
1375
- program.addCommand(createSearchPromptsCommand());
1376
- program.addCommand(createGetPromptsCommand());
1377
- program.addCommand(createFetchDesignNodesCommand());
1378
- program.addCommand(createGetDesignCommand());
1379
- program.addCommand(createCreateDesignDraftCommand());
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
- await program.parseAsync(process.argv);
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.1.12",
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.1.12",
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.1.12");
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
- program.addCommand(createLoginCommand());
1274
- program.addCommand(createLogoutCommand());
1275
- program.addCommand(createInitCommand());
1276
- program.addCommand(createCreateProjectCommand());
1277
- program.addCommand(createIterateDesignDraftCommand());
1278
- program.addCommand(createPlanFlowPagesCommand(), {
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
- program.addCommand(createExecuteFlowPagesCommand());
1282
- program.addCommand(createExtractBrandGuideCommand());
1283
- program.addCommand(createSearchPromptsCommand());
1284
- program.addCommand(createGetPromptsCommand());
1285
- program.addCommand(createFetchDesignNodesCommand());
1286
- program.addCommand(createGetDesignCommand());
1287
- program.addCommand(createCreateDesignDraftCommand());
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
- await program.parseAsync(process.argv);
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.1.12",
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
+ }