@superdesign/cli 0.1.0 → 0.1.2

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 CHANGED
@@ -53,32 +53,37 @@ var __webpack_exports__ = {};
53
53
  (()=>{
54
54
  __webpack_require__.r(__webpack_exports__);
55
55
  __webpack_require__.d(__webpack_exports__, {
56
+ getApiUrl: ()=>getApiUrl,
57
+ fetchDesignNodes: ()=>fetchDesignNodes,
58
+ createPublicApiClient: ()=>createPublicApiClient,
59
+ claimSession: ()=>claimSession,
60
+ isAuthenticated: ()=>manager_isAuthenticated,
61
+ addDraft: ()=>addDraft,
62
+ isJobFailed: ()=>isJobFailed,
63
+ createProgram: ()=>createProgram,
64
+ getDesignHtml: ()=>getDesignHtml,
65
+ ApiClientError: ()=>ApiClientError,
56
66
  run: ()=>run,
67
+ extractBrandGuide: ()=>extractBrandGuide,
57
68
  createDraft: ()=>createDraft,
58
- getApiUrl: ()=>getApiUrl,
59
69
  iterateDraft: ()=>iterateDraft,
60
70
  clearConfig: ()=>clearConfig,
61
71
  isJobDone: ()=>isJobDone,
62
72
  createProject: ()=>createProject,
63
73
  executeFlowPages: ()=>executeFlowPages,
64
74
  loadConfig: ()=>loadConfig,
65
- createPublicApiClient: ()=>createPublicApiClient,
66
75
  planFlowPages: ()=>planFlowPages,
67
- claimSession: ()=>claimSession,
68
- isAuthenticated: ()=>manager_isAuthenticated,
69
- addDraft: ()=>addDraft,
76
+ getPrompts: ()=>getPrompts,
70
77
  saveConfig: ()=>saveConfig,
78
+ updateConfig: ()=>updateConfig,
71
79
  createSession: ()=>createSession,
72
- isJobFailed: ()=>isJobFailed,
73
- getConfigPath: ()=>getConfigPath,
74
80
  pollSession: ()=>pollSession,
75
- updateConfig: ()=>updateConfig,
76
- createProgram: ()=>createProgram,
81
+ getConfigPath: ()=>getConfigPath,
77
82
  getApiClient: ()=>getApiClient,
78
83
  getJobStatus: ()=>getJobStatus,
79
84
  getConfigDir: ()=>getConfigDir,
80
85
  isJobCompleted: ()=>isJobCompleted,
81
- ApiClientError: ()=>ApiClientError,
86
+ searchPrompts: ()=>searchPrompts,
82
87
  getApiKey: ()=>getApiKey,
83
88
  createApiClient: ()=>createApiClient
84
89
  });
@@ -308,7 +313,7 @@ var __webpack_exports__ = {};
308
313
  try {
309
314
  startSpinner('Creating auth session...');
310
315
  const session = await createSession({
311
- cliVersion: "0.1.0",
316
+ cliVersion: "0.1.2",
312
317
  os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
313
318
  hostname: external_os_namespaceObject.hostname()
314
319
  });
@@ -509,241 +514,282 @@ name: superdesign
509
514
  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
515
  ---
511
516
 
512
- # SuperDesign Integration
513
- This skill provides integration with the SuperDesign platform for AI-powered design generation.
517
+ SuperDesign helps you (1) find design inspirations/styles and (2) optionally generate/iterate design drafts on an infinite canvas.
514
518
 
515
- ## Available Commands
519
+ Each SuperDesign canvas run creates a new node and returns a \`previewUrl\`.
516
520
 
517
- ### Create Project
521
+ ---
518
522
 
519
- Create a new new project, can pass optional HTML as initial starting point for design iteration:
523
+ ## Core scenarios (what this skill handles)
520
524
 
521
- \`\`\`bash
522
- # Basic project
523
- superdesign create-project --title "My Project" --json
525
+ 1. **Help me design X** (feature/page/flow)
526
+ 2. **Set design system**
527
+ 3. **Help me improve design of X**
524
528
 
525
- # Project with initial HTML
526
- superdesign create-project --title "My Project" --html "<html>...</html>" --json
529
+ ---
527
530
 
528
- # Project with HTML from file
529
- superdesign create-project --title "My Project" --html-file ./index.html --json
530
- \`\`\`
531
+ ## Tooling overview
531
532
 
532
- **Output (JSON):**
533
- \`\`\`json
534
- {
535
- "projectId": "uuid",
536
- "title": "My Project",
537
- "projectUrl": "https://app.superdesign.ai/...",
538
- "shareToken": "token"
539
- }
540
- \`\`\`
533
+ ### A) Inspiration & Style Tools (generic, always available)
534
+ Use these to discover style direction, references, and brand context:
541
535
 
542
- ### Create Design Draft
536
+ - **Search prompt library** (style/components/pages)
537
+ \`\`\`bash
538
+ superdesign search-prompts --keyword "<keyword>" --json
539
+ superdesign search-prompts --tags "style" --json
540
+ superdesign search-prompts --tags "style" --keyword "<style keyword>" --json
541
+ \`\`\`
543
542
 
544
- Generate a design draft using AI designer:
543
+ - **Get full prompt details**
544
+ \`\`\`bash
545
+ superdesign get-prompts --slugs "<slug1,slug2,...>" --json
546
+ \`\`\`
545
547
 
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
- \`\`\`
548
+ - **Extract brand guide from a URL**
549
+ \`\`\`bash
550
+ superdesign extract-brand-guide --url https://example.com --json
551
+ \`\`\`
554
552
 
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)
553
+ ### B) Canvas Design Tools (specialised, optional)
560
554
 
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
- \`\`\`
555
+ Use these when you want to explore multiple directions and show previews:
573
556
 
574
- ### Iterate Design Draft
557
+ - Create project (supports prompt / prompt file / HTML)
558
+ - Create design draft
559
+ - Iterate design draft (replace / branch)
560
+ - Plan flow pages → execute flow pages
561
+ - Fetch nodes, export HTML
575
562
 
576
- Create variations or improvements of an existing draft:
563
+ > Pixel-perfect HTML playground is ONLY required for Canvas workflows.
577
564
 
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
565
+ ---
585
566
 
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
- \`\`\`
567
+ ## Always-on rules
594
568
 
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)
569
+ - Design system should live at: \`.superdesign/design-system.md\`
570
+ - If \`.superdesign/design-system.md\` is missing, run **Design System Setup** first.
571
+ - Use \`askQuestion\` to ask high-signal questions (constraints, taste, tradeoffs).
572
+ - For Canvas workflows: build a simplified/pixel-perfect prototype HTML in:
573
+ - \`.superdesign/playgrounds/<name>.html\`
574
+ - Always use \`--json\` for machine parsing.
600
575
 
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
- \`\`\`
576
+ ---
577
+
578
+ ## Playground rules (Canvas only)
579
+
580
+ **Playground = BEFORE state (what exists now).** It provides context for SuperDesign agent.
581
+ **Prompt = DESIRED CHANGE (what to add/modify).**
582
+
583
+ The playground HTML must contain **ONLY UI that currently exists in the codebase**. For NEW features/sections, describe them entirely in the \`--prompt\` flag — do NOT add wireframes, placeholders, or sketches to the playground HTML.
617
584
 
618
- ### Plan Flow Pages
585
+ - **DO NOT** design or improve anything in the playground
586
+ - **DO NOT** add placeholder sections like \`<!-- NEW FEATURE - DESIGN THIS -->\`
587
+ - **DO** create pixel-perfect replica of current UI state
588
+ - Valid formats:
589
+ - **Component-only**: isolated component with enough markup to show core UX/states
590
+ - **Full page**: replica of page where component operates (shows surrounding context)
591
+ - Save to: \`.superdesign/playgrounds/<name>.html\`
619
592
 
620
- Get AI suggestions for related pages in a user flow:
593
+ ### Example: Adding a "Book Demo" section to home page
621
594
 
595
+ **BAD approach:**
596
+ \`\`\`html
597
+ <!-- playground includes a sketched Book Demo section -->
598
+ <section class="book-demo">
599
+ <!-- DESIGN THIS - Add CTA here -->
600
+ <h3>Book a Demo</h3>
601
+ <button>Schedule</button>
602
+ </section>
603
+ \`\`\`
604
+
605
+ **GOOD approach:**
606
+ \`\`\`html
607
+ <!-- playground is pure replica of existing home page (hero + projects) -->
608
+ <!-- NO book demo section in HTML -->
609
+ \`\`\`
610
+ Then in the iterate command:
622
611
  \`\`\`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
612
+ --prompt "Add a Book Demo section between the hero and projects sections. Requirements: minimal card style, horizontal layout..."
628
613
  \`\`\`
629
614
 
630
- **Options:**
631
- - \`--draft-id\` (required): Source draft
632
- - \`--source-node-id\` (required): Starting node in flow
633
- - \`--context\`: Additional context for planning
615
+ ---
634
616
 
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
- \`\`\`
617
+ # 1) Design System Setup
651
618
 
652
- ### Execute Flow Pages
619
+ ### Step 0 — Ask user (one question)
653
620
 
654
- Generate the planned flow pages:
621
+ "Do you want to **create a new design system** or **extract from the current codebase**?"
655
622
 
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
- \`\`\`
623
+ ### A) Extract from codebase
663
624
 
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
625
+ 1. Investigate codebase:
626
+ - design tokens, typography, colors, spacing, radius, shadows
627
+ - motion/animation patterns
628
+ - example components usage + implementation patterns
629
+ - core product functions + key pages
630
+ 2. Write standalone design system to:
631
+ - \`.superdesign/design-system.md\`
632
+ - Must be implementable without the codebase
669
633
 
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
- \`\`\`
634
+ ### B) Create a new design system (to improve current UI)
687
635
 
688
- ## Workflow Examples
636
+ 1. Investigate codebase to understand product + needed pages/components
637
+ 2. Gather inspirations (generic tools):
638
+ - \`superdesign search-prompts --tags "style" --json\`
639
+ - \`superdesign get-prompts --slugs ... --json\`
640
+ - optional: \`superdesign extract-brand-guide --url ... --json\`
641
+ 3. Interview user (\`askQuestion\`) to choose direction
642
+ 4. Write:
643
+ - \`.superdesign/design-system.md\` (adapted to product + references)
689
644
 
690
- ### Create a new design from scratch
645
+ ---
691
646
 
692
- \`\`\`bash
693
- # 1. Create project
694
- PROJECT=$(superdesign create-project --title "Landing Page" --json)
695
- PROJECT_ID=$(echo $PROJECT | jq -r '.projectId')
647
+ # 2) Designing X (feature/page/flow)
696
648
 
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)
649
+ ## A) If user wants references / direction only (no canvas)
703
650
 
704
- echo "Preview: $(echo $DRAFT | jq -r '.previewUrl')"
705
- \`\`\`
651
+ 1. Ensure \`.superdesign/design-system.md\` exists (setup if missing)
652
+ 2. Use inspiration tools to collect references:
653
+ - search prompts (style + component/page)
654
+ - get prompts (full details)
655
+ - extract brand guide if relevant
656
+ 3. Provide a concrete design spec:
657
+ - layout + hierarchy
658
+ - component set + states
659
+ - token guidance (typography/color/spacing/radius/motion)
660
+ - interaction notes + edge cases
661
+
662
+ ## B) If user wants visual exploration (canvas optional)
663
+
664
+ Use canvas when direction is uncertain or multiple options are needed.
665
+
666
+ ### Canvas workflow — Add feature to existing page
667
+
668
+ 1. Ensure \`.superdesign/design-system.md\` exists (setup if missing)
669
+ 2. Build prototype HTML playground (simplified + pixel-perfect enough):
670
+ - \`.superdesign/playgrounds/<page>-<feature>.html\`
671
+ 3. Ask targeted questions (\`askQuestion\`) about requirements + taste
672
+ 4. Create project with playground HTML (returns \`draftId\`):
673
+ \`\`\`bash
674
+ superdesign create-project \\
675
+ --title "<feature>" \\
676
+ --html-file .superdesign/playgrounds/<file>.html \\
677
+ --prompt-file .superdesign/design-system.md \\
678
+ --json
679
+ \`\`\`
680
+ → Note: \`draftId\` in response is the baseline draft
681
+ 5. Branch designs from baseline (use \`draftId\` from step 4):
682
+ \`\`\`bash
683
+ superdesign iterate-design-draft \\
684
+ --draft-id <draftId> \\
685
+ --prompt "<design requirements>" \\
686
+ --mode branch \\
687
+ --count 3 \\
688
+ --json
689
+ \`\`\`
690
+ 6. Share \`previewUrl\` → collect feedback → iterate
691
+
692
+ ### Canvas workflow — Add new page
693
+
694
+ Same as above, but playground should include shared UI shell:
695
+ - nav, layout container, spacing rhythm, shared components
706
696
 
707
- ### Iterate on existing design
697
+ ### Canvas workflow Improve current UI
698
+
699
+ 1. Investigate product + current UI states
700
+ 2. Ensure design system exists
701
+ 3. Propose improvement options:
702
+ - big restructure
703
+ - style uplift
704
+ - low-hanging polish
705
+ 4. Pick one → build playground → create project (prompt-file design system) → branch drafts
706
+ 5. Share \`previewUrl\` → iterate
707
+
708
+ ### When to use create-design-draft
709
+
710
+ Only use \`create-design-draft\` when creating from scratch (no HTML baseline).
711
+
712
+ **Required in prompt:**
713
+ - Full page structure (header, sidebar, main content areas)
714
+ - Component environment/surroundings
715
+ - Layout context (what's above/below/beside)
708
716
 
709
717
  \`\`\`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 \\
718
+ superdesign create-design-draft \\
719
+ --project-id <id> \\
720
+ --title "Feature X" \\
721
+ --prompt "Page has: fixed header 64px, left sidebar 240px, main content area. Design a settings panel in the main content area with..." \\
722
+ --device desktop \\
716
723
  --json
717
724
  \`\`\`
718
725
 
719
- ### Build a complete user flow
726
+ ---
720
727
 
728
+ # Advanced usage
729
+
730
+ ### Plan + generate a full user journey
731
+
732
+ Plan:
721
733
  \`\`\`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)
734
+ superdesign plan-flow-pages \\
735
+ --draft-id <draftId> \\
736
+ --source-node-id <nodeId> \\
737
+ --context "<flow context>" \\
738
+ --json
739
+ \`\`\`
728
740
 
729
- # 2. Execute the plan
730
- PAGES=$(echo $PLAN | jq -c '.pages')
741
+ Execute:
742
+ \`\`\`bash
731
743
  superdesign execute-flow-pages \\
732
- --draft-id <draft-id> \\
733
- --source-node-id <node-id> \\
734
- --pages "$PAGES" \\
744
+ --draft-id <draftId> \\
745
+ --source-node-id <nodeId> \\
746
+ --pages '[{"title":"Signup","prompt":"..."},{"title":"Payment","prompt":"..."}]' \\
735
747
  --json
736
748
  \`\`\`
737
749
 
750
+ ### Get HTML reference from a draft
738
751
 
739
- ## Tips
752
+ \`\`\`bash
753
+ superdesign get-design --draft-id <draftId> --output ./design.html
754
+ \`\`\`
755
+
756
+ ---
757
+
758
+ ## Quick reference (key commands)
759
+
760
+ \`\`\`bash
761
+ # Inspirations
762
+ superdesign search-prompts --keyword "<keyword>" --json
763
+ superdesign search-prompts --tags "style" --json
764
+ superdesign get-prompts --slugs "<slug1,slug2>" --json
765
+ superdesign extract-brand-guide --url https://example.com --json
740
766
 
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
767
+ # Canvas
768
+ superdesign create-project --title "X" --prompt "..." --json
769
+ superdesign create-project --title "X" --prompt-file .superdesign/design-system.md --json
770
+ superdesign create-project --title "X" --html-file ./index.html --prompt-file .superdesign/design-system.md --json
771
+
772
+ superdesign create-design-draft --project-id <id> --title "X" --prompt "..." --device desktop --json
773
+ superdesign iterate-design-draft --draft-id <id> --prompt "..." --mode replace --json
774
+ superdesign iterate-design-draft --draft-id <id> --prompt "..." --mode branch --count 3 --json
775
+
776
+ superdesign fetch-design-nodes --project-id <id> --json
777
+ superdesign get-design --draft-id <id> --json
778
+ \`\`\`
745
779
  `;
746
780
  }
781
+ function ensureGitignoreEntry(gitignorePath, entry) {
782
+ if (external_fs_namespaceObject.existsSync(gitignorePath)) {
783
+ const content = external_fs_namespaceObject.readFileSync(gitignorePath, 'utf-8');
784
+ const hasEntry = content.split('\n').some((line)=>line.trim() === entry);
785
+ if (hasEntry) return false;
786
+ const prefix = content.endsWith('\n') ? '' : '\n';
787
+ external_fs_namespaceObject.appendFileSync(gitignorePath, `${prefix}${entry}\n`, 'utf-8');
788
+ return true;
789
+ }
790
+ external_fs_namespaceObject.writeFileSync(gitignorePath, `${entry}\n`, 'utf-8');
791
+ return true;
792
+ }
747
793
  function createInitCommand() {
748
794
  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
795
  if (options.json) setJsonMode(true);
@@ -780,14 +826,19 @@ superdesign execute-flow-pages \\
780
826
  });
781
827
  const skillContent = getSkillTemplate();
782
828
  external_fs_namespaceObject.writeFileSync(skillFilePath, skillContent, 'utf-8');
829
+ const gitignorePath = external_path_namespaceObject.join(cwd, '.gitignore');
830
+ const gitignoreEntry = '.superdesign';
831
+ const gitignoreUpdated = ensureGitignoreEntry(gitignorePath, gitignoreEntry);
783
832
  if (isJsonMode()) output({
784
833
  success: true,
785
834
  path: skillFilePath,
835
+ gitignoreUpdated,
786
836
  message: 'Skill files installed successfully'
787
837
  });
788
838
  else {
789
839
  success('Skill files installed successfully!');
790
840
  info(`\nSkill file created at: ${skillFilePath}`);
841
+ if (gitignoreUpdated) info(".gitignore updated to exclude .superdesign directory");
791
842
  info('\nClaude Code will now have access to SuperDesign commands.');
792
843
  info('Available commands:');
793
844
  info(' - superdesign create-project');
@@ -795,6 +846,7 @@ superdesign execute-flow-pages \\
795
846
  info(' - superdesign iterate-design-draft');
796
847
  info(' - superdesign plan-flow-pages');
797
848
  info(' - superdesign execute-flow-pages');
849
+ info(' - superdesign extract-brand-guide');
798
850
  }
799
851
  } catch (err) {
800
852
  const message = err instanceof Error ? err.message : 'Unknown error';
@@ -815,7 +867,7 @@ superdesign execute-flow-pages \\
815
867
  return response.data;
816
868
  }
817
869
  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)=>{
870
+ 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('--prompt <prompt>', 'System prompt for the AI agent').option('--prompt-file <path>', 'Path to markdown file containing system prompt').option('--device <mode>', 'Device mode for draft (mobile, tablet, desktop)', 'desktop').option('--json', 'Output in JSON format').option('--no-open', 'Do not open project in browser after creation').action(async (options)=>{
819
871
  if (options.json) setJsonMode(true);
820
872
  try {
821
873
  if (!manager_isAuthenticated()) {
@@ -838,40 +890,43 @@ superdesign execute-flow-pages \\
838
890
  }
839
891
  htmlContent = external_fs_namespaceObject.readFileSync(options.htmlFile, 'utf-8');
840
892
  } else if (options.html) htmlContent = options.html;
893
+ let promptContent;
894
+ if (options.promptFile) {
895
+ if (!external_fs_namespaceObject.existsSync(options.promptFile)) {
896
+ output_error(`Prompt file not found: ${options.promptFile}`);
897
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
898
+ }
899
+ promptContent = external_fs_namespaceObject.readFileSync(options.promptFile, 'utf-8');
900
+ } else if (options.prompt) promptContent = options.prompt;
841
901
  startSpinner('Creating project...');
842
902
  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',
903
+ title: options.title,
848
904
  html: htmlContent,
905
+ prompt: promptContent,
849
906
  deviceMode: options.device
850
907
  });
851
908
  succeedSpinner('Project created successfully!');
852
- const result = {
909
+ if (options.open) {
910
+ const urlWithLive = `${project.projectUrl}?live=1`;
911
+ await openBrowser(urlWithLive);
912
+ }
913
+ if (isJsonMode()) output({
853
914
  projectId: project.projectId,
854
915
  title: project.title,
855
916
  projectUrl: project.projectUrl,
856
917
  shareToken: project.shareToken,
857
- ...draftResult && {
858
- draft: {
859
- draftId: draftResult.draftId,
860
- nodeId: draftResult.nodeId,
861
- nodeUrl: draftResult.nodeUrl,
862
- previewUrl: draftResult.previewUrl
863
- }
918
+ ...project.draftId && {
919
+ draftId: project.draftId,
920
+ previewUrl: project.previewUrl
864
921
  }
865
- };
866
- if (isJsonMode()) output(result);
922
+ });
867
923
  else {
868
924
  success(`Project "${project.title}" created!`);
869
925
  info(`\nProject ID: ${project.projectId}`);
870
926
  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}`);
927
+ if (project.draftId) {
928
+ info(`\nDraft ID: ${project.draftId}`);
929
+ info(`Preview URL: ${project.previewUrl}`);
875
930
  }
876
931
  }
877
932
  } catch (err) {
@@ -980,6 +1035,22 @@ superdesign execute-flow-pages \\
980
1035
  process.exit(EXIT_CODES.AUTH_REQUIRED);
981
1036
  }
982
1037
  }
1038
+ function handleApiError(err, failureMessage) {
1039
+ if (err instanceof ApiClientError) {
1040
+ if (isJsonMode()) output({
1041
+ error: err.message,
1042
+ code: err.code
1043
+ });
1044
+ else output_error(`API Error: ${err.message}`);
1045
+ process.exit(EXIT_CODES.API_ERROR);
1046
+ }
1047
+ const message = err instanceof Error ? err.message : 'Unknown error';
1048
+ if (isJsonMode()) output({
1049
+ error: message
1050
+ });
1051
+ else output_error(`${failureMessage}: ${message}`);
1052
+ process.exit(EXIT_CODES.GENERAL_ERROR);
1053
+ }
983
1054
  function createCreateDesignDraftCommand() {
984
1055
  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
1056
  if (options.json) setJsonMode(true);
@@ -1167,6 +1238,261 @@ superdesign execute-flow-pages \\
1167
1238
  });
1168
1239
  return command;
1169
1240
  }
1241
+ async function extractBrandGuide(url) {
1242
+ const client = getApiClient();
1243
+ const response = await client.post('/external/brand/extract', {
1244
+ url
1245
+ });
1246
+ return response.data;
1247
+ }
1248
+ function extractDomain(url) {
1249
+ try {
1250
+ const parsed = new URL(url);
1251
+ return parsed.hostname.replace(/^www\./, '');
1252
+ } catch {
1253
+ return url.replace(/[^a-zA-Z0-9.-]/g, '_');
1254
+ }
1255
+ }
1256
+ async function downloadFile(url, outputPath) {
1257
+ try {
1258
+ const response = await fetch(url);
1259
+ if (!response.ok) return false;
1260
+ const buffer = Buffer.from(await response.arrayBuffer());
1261
+ external_fs_namespaceObject.writeFileSync(outputPath, buffer);
1262
+ return true;
1263
+ } catch {
1264
+ return false;
1265
+ }
1266
+ }
1267
+ function createExtractBrandGuideCommand() {
1268
+ const command = new external_commander_namespaceObject.Command('extract-brand-guide').description('Extract brand guidelines from a website URL').requiredOption('--url <url>', 'Website URL to extract brand guide from').option('--output-dir <path>', 'Output directory (default: .superdesign/brand_styles/<domain>)').option('--json', 'Output in JSON format').action(async (options)=>{
1269
+ if (options.json) setJsonMode(true);
1270
+ job_runner_requireAuth(manager_isAuthenticated);
1271
+ const spinner = isJsonMode() ? null : external_ora_default()('Extracting brand guide...').start();
1272
+ try {
1273
+ const result = await extractBrandGuide(options.url);
1274
+ if (!result.success) {
1275
+ if (spinner) spinner.fail('Failed to extract brand guide');
1276
+ if (isJsonMode()) output({
1277
+ success: false,
1278
+ error: result.error || 'Failed to extract brand guide'
1279
+ });
1280
+ else output_error(result.error || 'Failed to extract brand guide');
1281
+ process.exit(EXIT_CODES.API_ERROR);
1282
+ }
1283
+ if (spinner) spinner.succeed('Brand guide extracted successfully');
1284
+ const domain = extractDomain(options.url);
1285
+ const cwd = process.cwd();
1286
+ const outputDir = options.outputDir || external_path_namespaceObject.join(cwd, '.superdesign', 'brand_styles', domain);
1287
+ external_fs_namespaceObject.mkdirSync(outputDir, {
1288
+ recursive: true
1289
+ });
1290
+ const jsonPath = external_path_namespaceObject.join(outputDir, 'brand-guide.json');
1291
+ external_fs_namespaceObject.writeFileSync(jsonPath, JSON.stringify(result, null, 2), 'utf-8');
1292
+ let screenshotSaved = false;
1293
+ if (result.data?.screenshot?.url) {
1294
+ const screenshotPath = external_path_namespaceObject.join(outputDir, 'screenshot.png');
1295
+ const downloadSpinner = isJsonMode() ? null : external_ora_default()('Downloading screenshot...').start();
1296
+ screenshotSaved = await downloadFile(result.data.screenshot.url, screenshotPath);
1297
+ if (downloadSpinner) if (screenshotSaved) downloadSpinner.succeed('Screenshot downloaded');
1298
+ else downloadSpinner.warn('Could not download screenshot');
1299
+ }
1300
+ if (isJsonMode()) output({
1301
+ success: true,
1302
+ outputDir,
1303
+ files: {
1304
+ brandGuide: jsonPath,
1305
+ screenshot: screenshotSaved ? external_path_namespaceObject.join(outputDir, 'screenshot.png') : null
1306
+ },
1307
+ data: result.data
1308
+ });
1309
+ else {
1310
+ success('Brand guide saved!');
1311
+ if (screenshotSaved) info(`\nScreenshot: ${external_path_namespaceObject.join(outputDir, 'screenshot.png')}`);
1312
+ info(`Extracted brand style JSON: ${jsonPath}`);
1313
+ }
1314
+ } catch (err) {
1315
+ if (spinner) spinner.fail('Failed to extract brand guide');
1316
+ const message = err instanceof Error ? err.message : 'Unknown error';
1317
+ if (isJsonMode()) output({
1318
+ success: false,
1319
+ error: message
1320
+ });
1321
+ else output_error(`Failed to extract brand guide: ${message}`);
1322
+ process.exit(EXIT_CODES.API_ERROR);
1323
+ }
1324
+ });
1325
+ return command;
1326
+ }
1327
+ async function searchPrompts(data) {
1328
+ const client = getApiClient();
1329
+ const response = await client.post('/external/prompts/search', data);
1330
+ return response.data;
1331
+ }
1332
+ async function getPrompts(data) {
1333
+ const client = getApiClient();
1334
+ const response = await client.post('/external/prompts/get', data);
1335
+ return response.data;
1336
+ }
1337
+ function createSearchPromptsCommand() {
1338
+ const command = new external_commander_namespaceObject.Command('search-prompts').description('Search public prompts in the library').option('--keyword <text>', "Search keyword (searches title and description)").option('--tags <tags>', 'Comma-separated tags to filter by').option('--limit <n>', 'Maximum number of results (default: 20, max: 100)').option('--offset <n>', 'Number of results to skip (for pagination)').option('--json', 'Output in JSON format').action(async (options)=>{
1339
+ if (options.json) setJsonMode(true);
1340
+ job_runner_requireAuth(manager_isAuthenticated);
1341
+ const spinner = isJsonMode() ? null : external_ora_default()('Searching prompts...').start();
1342
+ try {
1343
+ const tags = options.tags ? options.tags.split(',').map((t)=>t.trim()) : void 0;
1344
+ const limit = options.limit ? parseInt(options.limit, 10) : 20;
1345
+ const offset = options.offset ? parseInt(options.offset, 10) : 0;
1346
+ const result = await searchPrompts({
1347
+ keyword: options.keyword,
1348
+ tags,
1349
+ limit,
1350
+ offset
1351
+ });
1352
+ if (spinner) spinner.succeed(`Found ${result.prompts.length} prompts (total: ${result.total})`);
1353
+ if (isJsonMode()) output(result);
1354
+ else if (0 === result.prompts.length) info('\nNo prompts found matching your criteria.');
1355
+ else {
1356
+ success(`\nFound ${result.prompts.length} prompts:\n`);
1357
+ result.prompts.forEach((prompt, index)=>{
1358
+ const tagsStr = prompt.tags.length > 0 ? ` [${prompt.tags.join(', ')}]` : '';
1359
+ console.log(`${index + 1}. "${prompt.title}"${tagsStr}`);
1360
+ if (prompt.description) {
1361
+ const desc = prompt.description.length > 100 ? prompt.description.substring(0, 97) + '...' : prompt.description;
1362
+ console.log(` ${desc}`);
1363
+ }
1364
+ console.log(` Views: ${prompt.viewCount} | Remixes: ${prompt.remixCount}`);
1365
+ if (prompt.previewUrl) console.log(` Preview: ${prompt.previewUrl}`);
1366
+ console.log(` Slug: ${prompt.slug}`);
1367
+ console.log('');
1368
+ });
1369
+ if (result.total > result.prompts.length) info(`Showing ${result.prompts.length} of ${result.total} results. Use --offset to paginate.`);
1370
+ }
1371
+ } catch (err) {
1372
+ if (spinner) spinner.fail('Failed to search prompts');
1373
+ handleApiError(err, 'Failed to search prompts');
1374
+ }
1375
+ });
1376
+ return command;
1377
+ }
1378
+ function createGetPromptsCommand() {
1379
+ const command = new external_commander_namespaceObject.Command('get-prompts').description('Get prompts by their slugs').requiredOption('--slugs <slugs>', 'Comma-separated list of prompt slugs').option('--json', 'Output in JSON format').action(async (options)=>{
1380
+ if (options.json) setJsonMode(true);
1381
+ job_runner_requireAuth(manager_isAuthenticated);
1382
+ const slugs = options.slugs.split(',').map((s)=>s.trim());
1383
+ if (0 === slugs.length) {
1384
+ output_error('At least one slug is required');
1385
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1386
+ }
1387
+ if (slugs.length > 20) {
1388
+ output_error('Maximum 20 slugs allowed per request');
1389
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
1390
+ }
1391
+ const spinner = isJsonMode() ? null : external_ora_default()(`Fetching ${slugs.length} prompt(s)...`).start();
1392
+ try {
1393
+ const result = await getPrompts({
1394
+ slugs
1395
+ });
1396
+ if (spinner) spinner.succeed(`Retrieved ${result.prompts.length} of ${slugs.length} prompts`);
1397
+ if (isJsonMode()) output(result);
1398
+ else if (0 === result.prompts.length) info('\nNo prompts found for the provided slugs.');
1399
+ else {
1400
+ result.prompts.forEach((prompt, index)=>{
1401
+ if (index > 0) console.log('\n' + '='.repeat(60) + '\n');
1402
+ success(`Prompt: "${prompt.title}"`);
1403
+ info(`Slug: ${prompt.slug}`);
1404
+ if (prompt.tags.length > 0) info(`Tags: ${prompt.tags.join(', ')}`);
1405
+ if (prompt.description) console.log(`\nDescription: ${prompt.description}`);
1406
+ console.log('\n---');
1407
+ console.log(prompt.prompt);
1408
+ console.log('---\n');
1409
+ console.log(`Views: ${prompt.viewCount} | Remixes: ${prompt.remixCount}`);
1410
+ if (prompt.previewUrl) info(`Preview: ${prompt.previewUrl}`);
1411
+ if (prompt.images && prompt.images.length > 0) info(`Images: ${prompt.images.length} attached`);
1412
+ });
1413
+ const foundSlugs = result.prompts.map((p)=>p.slug);
1414
+ const missingSlugs = slugs.filter((s)=>!foundSlugs.includes(s));
1415
+ if (missingSlugs.length > 0) {
1416
+ console.log('');
1417
+ info(`Note: ${missingSlugs.length} slug(s) not found: ${missingSlugs.join(', ')}`);
1418
+ }
1419
+ }
1420
+ } catch (err) {
1421
+ if (spinner) spinner.fail('Failed to get prompts');
1422
+ handleApiError(err, 'Failed to get prompts');
1423
+ }
1424
+ });
1425
+ return command;
1426
+ }
1427
+ async function fetchDesignNodes(projectId) {
1428
+ const client = getApiClient();
1429
+ const response = await client.get(`/external/projects/${projectId}/design-nodes`);
1430
+ return response.data;
1431
+ }
1432
+ async function getDesignHtml(draftId) {
1433
+ const client = getApiClient();
1434
+ const response = await client.get(`/external/drafts/${draftId}/html`);
1435
+ return response.data;
1436
+ }
1437
+ function displayNode(node, index) {
1438
+ console.log(`${index + 1}. "${node.title}" (depth: ${node.iterationDepth})`);
1439
+ info(node.parentDraftId ? ` Parent: ${node.parentDraftId}` : ' Root draft');
1440
+ if (node.description) console.log(` ${node.description}`);
1441
+ info(` Preview: ${node.previewUrl}`);
1442
+ if (node.screenshot) info(` Screenshot: ${node.screenshot.url}`);
1443
+ console.log(` Created: ${node.createdAt}\n`);
1444
+ }
1445
+ function createFetchDesignNodesCommand() {
1446
+ const command = new external_commander_namespaceObject.Command('fetch-design-nodes').description('Get all design draft nodes for a project').requiredOption('--project-id <projectId>', 'Project ID to fetch nodes from').option('--json', 'Output in JSON format').action(async (options)=>{
1447
+ if (options.json) setJsonMode(true);
1448
+ job_runner_requireAuth(manager_isAuthenticated);
1449
+ const spinner = isJsonMode() ? null : external_ora_default()('Fetching design nodes...').start();
1450
+ try {
1451
+ const result = await fetchDesignNodes(options.projectId);
1452
+ if (spinner) spinner.succeed(`Found ${result.nodes.length} design node(s)`);
1453
+ if (isJsonMode()) return void output(result);
1454
+ if (0 === result.nodes.length) return void info('\nNo design nodes found in this project.');
1455
+ console.log(`\nFound ${result.nodes.length} design node(s):\n`);
1456
+ result.nodes.forEach(displayNode);
1457
+ } catch (err) {
1458
+ if (spinner) spinner.fail('Failed to fetch design nodes');
1459
+ handleApiError(err, 'Failed to fetch design nodes');
1460
+ }
1461
+ });
1462
+ return command;
1463
+ }
1464
+ const promises_namespaceObject = require("fs/promises");
1465
+ async function writeHtmlToFile(result, outputPath) {
1466
+ const resolvedPath = (0, external_path_namespaceObject.resolve)(process.cwd(), outputPath);
1467
+ await (0, promises_namespaceObject.writeFile)(resolvedPath, result.htmlContent, 'utf-8');
1468
+ if (isJsonMode()) output({
1469
+ ...result,
1470
+ savedTo: resolvedPath
1471
+ });
1472
+ else {
1473
+ success(`HTML written to: ${resolvedPath}`);
1474
+ info(`Title: ${result.title}`);
1475
+ info(`Draft ID: ${result.draftId}`);
1476
+ }
1477
+ }
1478
+ function createGetDesignCommand() {
1479
+ const command = new external_commander_namespaceObject.Command('get-design').description('Get HTML content for a specific draft').requiredOption('--draft-id <draftId>', 'Draft ID to fetch').option('--json', 'Output in JSON format').option('--output <path>', 'Write HTML to file instead of stdout').action(async (options)=>{
1480
+ if (options.json) setJsonMode(true);
1481
+ job_runner_requireAuth(manager_isAuthenticated);
1482
+ const spinner = isJsonMode() ? null : external_ora_default()('Fetching design HTML...').start();
1483
+ try {
1484
+ const result = await getDesignHtml(options.draftId);
1485
+ if (spinner) spinner.succeed(`Retrieved design: "${result.title}"`);
1486
+ if (options.output) return void await writeHtmlToFile(result, options.output);
1487
+ if (isJsonMode()) return void output(result);
1488
+ console.log(result.htmlContent);
1489
+ } catch (err) {
1490
+ if (spinner) spinner.fail('Failed to get design HTML');
1491
+ handleApiError(err, 'Failed to get design HTML');
1492
+ }
1493
+ });
1494
+ return command;
1495
+ }
1170
1496
  const src_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
1171
1497
  const src_dirname = (0, external_path_namespaceObject.dirname)(src_filename);
1172
1498
  (0, external_dotenv_namespaceObject.config)({
@@ -1175,7 +1501,7 @@ superdesign execute-flow-pages \\
1175
1501
  (0, external_dotenv_namespaceObject.config)();
1176
1502
  function createProgram() {
1177
1503
  const program = new external_commander_namespaceObject.Command();
1178
- program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.0");
1504
+ program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.2");
1179
1505
  program.addCommand(createLoginCommand());
1180
1506
  program.addCommand(createLogoutCommand());
1181
1507
  program.addCommand(createInitCommand());
@@ -1184,6 +1510,11 @@ superdesign execute-flow-pages \\
1184
1510
  program.addCommand(createIterateDesignDraftCommand());
1185
1511
  program.addCommand(createPlanFlowPagesCommand());
1186
1512
  program.addCommand(createExecuteFlowPagesCommand());
1513
+ program.addCommand(createExtractBrandGuideCommand());
1514
+ program.addCommand(createSearchPromptsCommand());
1515
+ program.addCommand(createGetPromptsCommand());
1516
+ program.addCommand(createFetchDesignNodesCommand());
1517
+ program.addCommand(createGetDesignCommand());
1187
1518
  return program;
1188
1519
  }
1189
1520
  async function run() {
@@ -1202,12 +1533,16 @@ exports.createProject = __webpack_exports__.createProject;
1202
1533
  exports.createPublicApiClient = __webpack_exports__.createPublicApiClient;
1203
1534
  exports.createSession = __webpack_exports__.createSession;
1204
1535
  exports.executeFlowPages = __webpack_exports__.executeFlowPages;
1536
+ exports.extractBrandGuide = __webpack_exports__.extractBrandGuide;
1537
+ exports.fetchDesignNodes = __webpack_exports__.fetchDesignNodes;
1205
1538
  exports.getApiClient = __webpack_exports__.getApiClient;
1206
1539
  exports.getApiKey = __webpack_exports__.getApiKey;
1207
1540
  exports.getApiUrl = __webpack_exports__.getApiUrl;
1208
1541
  exports.getConfigDir = __webpack_exports__.getConfigDir;
1209
1542
  exports.getConfigPath = __webpack_exports__.getConfigPath;
1543
+ exports.getDesignHtml = __webpack_exports__.getDesignHtml;
1210
1544
  exports.getJobStatus = __webpack_exports__.getJobStatus;
1545
+ exports.getPrompts = __webpack_exports__.getPrompts;
1211
1546
  exports.isAuthenticated = __webpack_exports__.isAuthenticated;
1212
1547
  exports.isJobCompleted = __webpack_exports__.isJobCompleted;
1213
1548
  exports.isJobDone = __webpack_exports__.isJobDone;
@@ -1218,6 +1553,7 @@ exports.planFlowPages = __webpack_exports__.planFlowPages;
1218
1553
  exports.pollSession = __webpack_exports__.pollSession;
1219
1554
  exports.run = __webpack_exports__.run;
1220
1555
  exports.saveConfig = __webpack_exports__.saveConfig;
1556
+ exports.searchPrompts = __webpack_exports__.searchPrompts;
1221
1557
  exports.updateConfig = __webpack_exports__.updateConfig;
1222
1558
  for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1223
1559
  "ApiClientError",
@@ -1231,12 +1567,16 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1231
1567
  "createPublicApiClient",
1232
1568
  "createSession",
1233
1569
  "executeFlowPages",
1570
+ "extractBrandGuide",
1571
+ "fetchDesignNodes",
1234
1572
  "getApiClient",
1235
1573
  "getApiKey",
1236
1574
  "getApiUrl",
1237
1575
  "getConfigDir",
1238
1576
  "getConfigPath",
1577
+ "getDesignHtml",
1239
1578
  "getJobStatus",
1579
+ "getPrompts",
1240
1580
  "isAuthenticated",
1241
1581
  "isJobCompleted",
1242
1582
  "isJobDone",
@@ -1247,6 +1587,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
1247
1587
  "pollSession",
1248
1588
  "run",
1249
1589
  "saveConfig",
1590
+ "searchPrompts",
1250
1591
  "updateConfig"
1251
1592
  ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
1252
1593
  Object.defineProperty(exports, '__esModule', {