@superdesign/cli 0.1.4 → 0.1.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Super Design
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -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.4";
15
+ export declare const CLI_VERSION = "0.1.6";
16
16
  /** Config directory name */
17
17
  export declare const CONFIG_DIR_NAME = ".superdesign";
18
18
  /** Config file name */
@@ -31,3 +31,6 @@ export declare const EXIT_CODES: {
31
31
  export declare const SKILLS_DIR = ".claude/skills/superdesign";
32
32
  /** SKILL.md file name */
33
33
  export declare const SKILL_FILE_NAME = "SKILL.md";
34
+ /** PostHog analytics configuration */
35
+ export declare const POSTHOG_KEY: string;
36
+ export declare const POSTHOG_HOST: string;
package/dist/index.cjs CHANGED
@@ -91,8 +91,6 @@ var __webpack_exports__ = {};
91
91
  const external_url_namespaceObject = require("url");
92
92
  const external_path_namespaceObject = require("path");
93
93
  const external_commander_namespaceObject = require("commander");
94
- const external_fs_namespaceObject = require("fs");
95
- const external_os_namespaceObject = require("os");
96
94
  const CONFIG_DIR_NAME = '.superdesign';
97
95
  const CONFIG_FILE_NAME = 'config.json';
98
96
  const EXIT_CODES = {
@@ -106,6 +104,11 @@ var __webpack_exports__ = {};
106
104
  };
107
105
  const SKILLS_DIR = '.claude/skills/superdesign';
108
106
  const SKILL_FILE_NAME = 'SKILL.md';
107
+ const POSTHOG_KEY = process.env.POSTHOG_KEY || 'phc_oUcDklFBX3wy8eksSyEC0pataKCgSadur1sio5hBHg4';
108
+ const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com';
109
+ const external_fs_namespaceObject = require("fs");
110
+ const external_os_namespaceObject = require("os");
111
+ var external_os_default = /*#__PURE__*/ __webpack_require__.n(external_os_namespaceObject);
109
112
  function getConfigDir() {
110
113
  return external_path_namespaceObject.join(external_os_namespaceObject.homedir(), CONFIG_DIR_NAME);
111
114
  }
@@ -313,7 +316,7 @@ var __webpack_exports__ = {};
313
316
  try {
314
317
  startSpinner('Creating auth session...');
315
318
  const session = await createSession({
316
- cliVersion: "0.1.4",
319
+ cliVersion: "0.1.6",
317
320
  os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
318
321
  hostname: external_os_namespaceObject.hostname()
319
322
  });
@@ -512,269 +515,35 @@ var __webpack_exports__ = {};
512
515
  return `---
513
516
  name: superdesign
514
517
  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
518
+ metadata:
519
+ author: superdesign
520
+ version: "0.0.1"
515
521
  ---
516
522
 
517
- SuperDesign helps you (1) find design inspirations/styles and (2) optionally generate/iterate design drafts on an infinite canvas.
518
-
519
- Each SuperDesign canvas run creates a new node and returns a \`previewUrl\`.
523
+ SuperDesign helps you (1) find design inspirations/styles and (2) generate/iterate design drafts on an infinite canvas.
520
524
 
521
525
  ---
522
526
 
523
- ## Core scenarios (what this skill handles)
527
+ # Core scenarios (what this skill handles)
524
528
 
525
529
  1. **Help me design X** (feature/page/flow)
526
530
  2. **Set design system**
527
531
  3. **Help me improve design of X**
528
532
 
529
- ---
530
-
531
- ## Tooling overview
532
-
533
- ### A) Inspiration & Style Tools (generic, always available)
534
- Use these to discover style direction, references, and brand context:
535
-
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
- \`\`\`
542
-
543
- - **Get full prompt details**
544
- \`\`\`bash
545
- superdesign get-prompts --slugs "<slug1,slug2,...>" --json
546
- \`\`\`
547
-
548
- - **Extract brand guide from a URL**
549
- \`\`\`bash
550
- superdesign extract-brand-guide --url https://example.com --json
551
- \`\`\`
552
-
553
- ### B) Canvas Design Tools (specialised, optional)
554
-
555
- Use these when you want to explore multiple directions and show previews:
556
-
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
562
-
563
- > Pixel-perfect HTML playground is ONLY required for Canvas workflows.
564
-
565
- ---
566
-
567
- ## Always-on rules
568
-
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.
575
-
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.
584
-
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\`
592
-
593
- ### Example: Adding a "Book Demo" section to home page
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:
611
- \`\`\`bash
612
- --prompt "Add a Book Demo section between the hero and projects sections. Requirements: minimal card style, horizontal layout..."
613
- \`\`\`
614
-
615
- ---
616
-
617
- # 1) Design System Setup
618
-
619
- ### Step 0 — Ask user (one question)
620
-
621
- "Do you want to **create a new design system** or **extract from the current codebase**?"
622
-
623
- ### A) Extract from codebase
624
-
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
633
-
634
- ### B) Create a new design system (to improve current UI)
635
-
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)
644
-
645
- ---
646
-
647
- # 2) Designing X (feature/page/flow)
648
-
649
- ## A) If user wants references / direction only (no canvas)
650
-
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
696
-
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)
716
-
717
- \`\`\`bash
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 \\
723
- --json
533
+ # How it works
534
+ Fetch fresh guidelines below:
724
535
  \`\`\`
725
-
726
- ---
727
-
728
- # Advanced usage
729
-
730
- ### Plan + generate a full user journey
731
-
732
- Plan:
733
- \`\`\`bash
734
- superdesign plan-flow-pages \\
735
- --draft-id <draftId> \\
736
- --source-node-id <nodeId> \\
737
- --context "<flow context>" \\
738
- --json
536
+ https://raw.githubusercontent.com/superdesigndev/superdesign-skill/main/skills/superdesign/SUPERDESIGN.md
739
537
  \`\`\`
740
538
 
741
- Execute:
742
- \`\`\`bash
743
- superdesign execute-flow-pages \\
744
- --draft-id <draftId> \\
745
- --source-node-id <nodeId> \\
746
- --pages '[{"title":"Signup","prompt":"..."},{"title":"Payment","prompt":"..."}]' \\
747
- --json
748
- \`\`\`
539
+ Action accordingly based on instruction in the guidelines
749
540
 
750
- ### Get HTML reference from a draft
541
+ # Superdesign CLI
751
542
 
752
- \`\`\`bash
753
- superdesign get-design --draft-id <draftId> --output ./design.html
754
543
  \`\`\`
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
766
-
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
544
+ npm install -g @superdesign/cli@latest
545
+ superdesign init
546
+ superdesign --help
778
547
  \`\`\`
779
548
  `;
780
549
  }
@@ -866,102 +635,6 @@ superdesign get-design --draft-id <id> --json
866
635
  const response = await client.post(`/external/projects/${projectId}/drafts/add`, data);
867
636
  return response.data;
868
637
  }
869
- function createCreateProjectCommand() {
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)=>{
871
- if (options.json) setJsonMode(true);
872
- try {
873
- if (!manager_isAuthenticated()) {
874
- output_error('Not authenticated. Run `superdesign login` first.');
875
- process.exit(EXIT_CODES.AUTH_REQUIRED);
876
- }
877
- if (options.device && ![
878
- 'mobile',
879
- 'tablet',
880
- 'desktop'
881
- ].includes(options.device)) {
882
- output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
883
- process.exit(EXIT_CODES.VALIDATION_ERROR);
884
- }
885
- let htmlContent;
886
- if (options.htmlFile) {
887
- if (!external_fs_namespaceObject.existsSync(options.htmlFile)) {
888
- output_error(`HTML file not found: ${options.htmlFile}`);
889
- process.exit(EXIT_CODES.VALIDATION_ERROR);
890
- }
891
- htmlContent = external_fs_namespaceObject.readFileSync(options.htmlFile, 'utf-8');
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;
901
- startSpinner('Creating project...');
902
- const project = await createProject({
903
- title: options.title,
904
- html: htmlContent,
905
- prompt: promptContent,
906
- deviceMode: options.device
907
- });
908
- succeedSpinner('Project created successfully!');
909
- if (options.open) {
910
- const urlWithLive = `${project.projectUrl}?live=1`;
911
- await openBrowser(urlWithLive);
912
- }
913
- if (isJsonMode()) output({
914
- projectId: project.projectId,
915
- title: project.title,
916
- projectUrl: project.projectUrl,
917
- shareToken: project.shareToken,
918
- ...project.draftId && {
919
- draftId: project.draftId,
920
- previewUrl: project.previewUrl
921
- }
922
- });
923
- else {
924
- success(`Project "${project.title}" created!`);
925
- info(`\nProject ID: ${project.projectId}`);
926
- info(`Project URL: ${project.projectUrl}`);
927
- if (project.draftId) {
928
- info(`\nDraft ID: ${project.draftId}`);
929
- info(`Preview URL: ${project.previewUrl}`);
930
- }
931
- }
932
- } catch (err) {
933
- failSpinner('Failed to create project');
934
- if (err instanceof ApiClientError) {
935
- output_error(`API Error: ${err.message}`);
936
- process.exit(EXIT_CODES.API_ERROR);
937
- }
938
- const message = err instanceof Error ? err.message : 'Unknown error';
939
- output_error(message);
940
- process.exit(EXIT_CODES.GENERAL_ERROR);
941
- }
942
- });
943
- return command;
944
- }
945
- async function createDraft(projectId, data) {
946
- const client = getApiClient();
947
- const response = await client.post(`/external/projects/${projectId}/drafts/create`, data);
948
- return response.data;
949
- }
950
- async function iterateDraft(draftId, data) {
951
- const client = getApiClient();
952
- const response = await client.post(`/external/drafts/${draftId}/iterate`, data);
953
- return response.data;
954
- }
955
- async function planFlowPages(draftId, data) {
956
- const client = getApiClient();
957
- const response = await client.post(`/external/drafts/${draftId}/flow/plan`, data);
958
- return response.data;
959
- }
960
- async function executeFlowPages(draftId, data) {
961
- const client = getApiClient();
962
- const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
963
- return response.data;
964
- }
965
638
  async function getJobStatus(jobId) {
966
639
  const client = getApiClient();
967
640
  const response = await client.get(`/external/jobs/${jobId}`);
@@ -1051,18 +724,98 @@ superdesign get-design --draft-id <id> --json
1051
724
  else output_error(`${failureMessage}: ${message}`);
1052
725
  process.exit(EXIT_CODES.GENERAL_ERROR);
1053
726
  }
1054
- function createCreateDesignDraftCommand() {
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)=>{
727
+ const VALID_DEVICES = [
728
+ 'mobile',
729
+ 'tablet',
730
+ 'desktop'
731
+ ];
732
+ function validateDeviceMode(device) {
733
+ if (device && !VALID_DEVICES.includes(device)) {
734
+ output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
735
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
736
+ }
737
+ }
738
+ function readFileContent(filePath, inlineContent, fileType) {
739
+ if (filePath) {
740
+ if (!(0, external_fs_namespaceObject.existsSync)(filePath)) {
741
+ output_error(`${fileType} file not found: ${filePath}`);
742
+ process.exit(EXIT_CODES.VALIDATION_ERROR);
743
+ }
744
+ return (0, external_fs_namespaceObject.readFileSync)(filePath, 'utf-8');
745
+ }
746
+ return inlineContent;
747
+ }
748
+ function createCreateProjectCommand() {
749
+ 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('-s, --set-project-prompt <prompt>', 'System prompt for the AI agent').option('--set-project-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)=>{
1056
750
  if (options.json) setJsonMode(true);
1057
751
  job_runner_requireAuth(manager_isAuthenticated);
1058
- if (options.device && ![
1059
- 'mobile',
1060
- 'tablet',
1061
- 'desktop'
1062
- ].includes(options.device)) {
1063
- output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
1064
- process.exit(EXIT_CODES.VALIDATION_ERROR);
752
+ validateDeviceMode(options.device);
753
+ const htmlContent = readFileContent(options.htmlFile, options.html, 'HTML');
754
+ const promptContent = readFileContent(options.setProjectPromptFile, options.setProjectPrompt, 'Prompt');
755
+ startSpinner('Creating project...');
756
+ try {
757
+ const project = await createProject({
758
+ title: options.title,
759
+ html: htmlContent,
760
+ prompt: promptContent,
761
+ deviceMode: options.device
762
+ });
763
+ succeedSpinner('Project created successfully!');
764
+ if (options.open) {
765
+ const urlWithLive = `${project.projectUrl}?live=1`;
766
+ await openBrowser(urlWithLive);
767
+ }
768
+ if (isJsonMode()) output({
769
+ projectId: project.projectId,
770
+ title: project.title,
771
+ projectUrl: project.projectUrl,
772
+ shareToken: project.shareToken,
773
+ ...project.draftId && {
774
+ draftId: project.draftId,
775
+ previewUrl: project.previewUrl
776
+ }
777
+ });
778
+ else {
779
+ success(`Project "${project.title}" created!`);
780
+ info(`\nProject ID: ${project.projectId}`);
781
+ info(`Project URL: ${project.projectUrl}`);
782
+ if (project.draftId) {
783
+ info(`\nDraft ID: ${project.draftId}`);
784
+ info(`Preview URL: ${project.previewUrl}`);
785
+ }
786
+ }
787
+ } catch (err) {
788
+ failSpinner('Failed to create project');
789
+ handleApiError(err, 'Failed to create project');
1065
790
  }
791
+ });
792
+ return command;
793
+ }
794
+ async function createDraft(projectId, data) {
795
+ const client = getApiClient();
796
+ const response = await client.post(`/external/projects/${projectId}/drafts/create`, data);
797
+ return response.data;
798
+ }
799
+ async function iterateDraft(draftId, data) {
800
+ const client = getApiClient();
801
+ const response = await client.post(`/external/drafts/${draftId}/iterate`, data);
802
+ return response.data;
803
+ }
804
+ async function planFlowPages(draftId, data) {
805
+ const client = getApiClient();
806
+ const response = await client.post(`/external/drafts/${draftId}/flow/plan`, data);
807
+ return response.data;
808
+ }
809
+ async function executeFlowPages(draftId, data) {
810
+ const client = getApiClient();
811
+ const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
812
+ return response.data;
813
+ }
814
+ function createCreateDesignDraftCommand() {
815
+ 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('-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)=>{
816
+ if (options.json) setJsonMode(true);
817
+ job_runner_requireAuth(manager_isAuthenticated);
818
+ validateDeviceMode(options.device);
1066
819
  await runJob({
1067
820
  startLabel: 'Creating design draft...',
1068
821
  pollingLabel: 'Generating design with AI...',
@@ -1525,15 +1278,104 @@ superdesign get-design --draft-id <id> --json
1525
1278
  });
1526
1279
  return command;
1527
1280
  }
1281
+ const external_posthog_node_namespaceObject = require("posthog-node");
1282
+ let posthogClient = null;
1283
+ function getPostHog() {
1284
+ if (!posthogClient && POSTHOG_KEY) posthogClient = new external_posthog_node_namespaceObject.PostHog(POSTHOG_KEY, {
1285
+ host: POSTHOG_HOST
1286
+ });
1287
+ return posthogClient;
1288
+ }
1289
+ function sanitizeOptions(options) {
1290
+ const sensitiveKeys = [
1291
+ 'token',
1292
+ 'key',
1293
+ 'secret',
1294
+ 'password',
1295
+ 'apiKey',
1296
+ 'api_key',
1297
+ 'apikey',
1298
+ 'auth',
1299
+ 'authorization',
1300
+ 'credential'
1301
+ ];
1302
+ const sanitized = {};
1303
+ for (const [key, value] of Object.entries(options)){
1304
+ const lowerKey = key.toLowerCase();
1305
+ if (!sensitiveKeys.some((sensitive)=>lowerKey.includes(sensitive))) {
1306
+ if ('string' != typeof value || !(value.length > 100)) sanitized[key] = value;
1307
+ }
1308
+ }
1309
+ return sanitized;
1310
+ }
1311
+ async function trackCommand(opts) {
1312
+ const config = loadConfig();
1313
+ const teamId = config.teamId;
1314
+ const metadata = {
1315
+ command: opts.command,
1316
+ success: opts.success,
1317
+ durationMs: opts.durationMs,
1318
+ errorCode: opts.errorCode,
1319
+ options: opts.options ? sanitizeOptions(opts.options) : void 0,
1320
+ cliVersion: "0.1.6",
1321
+ os: `${external_os_default().platform()} ${external_os_default().release()}`
1322
+ };
1323
+ const posthog = getPostHog();
1324
+ if (posthog) {
1325
+ const distinctId = teamId || `anon_${external_os_default().hostname()}`;
1326
+ posthog.capture({
1327
+ distinctId,
1328
+ event: 'cli_command',
1329
+ properties: {
1330
+ team_id: teamId,
1331
+ ...metadata
1332
+ }
1333
+ });
1334
+ }
1335
+ if (manager_isAuthenticated() && teamId) try {
1336
+ const client = getApiClient();
1337
+ await client.post('/external/track', {
1338
+ activityType: 'cli_command',
1339
+ metadata
1340
+ });
1341
+ } catch {}
1342
+ }
1343
+ async function shutdownAnalytics() {
1344
+ if (posthogClient) {
1345
+ await posthogClient.shutdown();
1346
+ posthogClient = null;
1347
+ }
1348
+ }
1528
1349
  const src_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
1529
1350
  const src_dirname = (0, external_path_namespaceObject.dirname)(src_filename);
1530
1351
  (0, external_dotenv_namespaceObject.config)({
1531
1352
  path: (0, external_path_namespaceObject.resolve)(src_dirname, '../.env')
1532
1353
  });
1533
1354
  (0, external_dotenv_namespaceObject.config)();
1355
+ let commandStartTime = 0;
1356
+ let currentCommand = '';
1357
+ function sanitizeCommandOptions(opts) {
1358
+ const sanitized = {};
1359
+ for (const [key, value] of Object.entries(opts))if (!('function' == typeof value || key.startsWith('_'))) sanitized[key] = value;
1360
+ return sanitized;
1361
+ }
1534
1362
  function createProgram() {
1535
1363
  const program = new external_commander_namespaceObject.Command();
1536
- program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.4");
1364
+ program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.6");
1365
+ program.hook('preAction', ()=>{
1366
+ commandStartTime = Date.now();
1367
+ currentCommand = process.argv[2] || 'unknown';
1368
+ });
1369
+ program.hook('postAction', async (_thisCommand, actionCommand)=>{
1370
+ const durationMs = Date.now() - commandStartTime;
1371
+ await trackCommand({
1372
+ command: currentCommand,
1373
+ success: true,
1374
+ durationMs,
1375
+ options: sanitizeCommandOptions(actionCommand.opts())
1376
+ });
1377
+ await shutdownAnalytics();
1378
+ });
1537
1379
  program.addCommand(createLoginCommand());
1538
1380
  program.addCommand(createLogoutCommand());
1539
1381
  program.addCommand(createInitCommand());