@superdesign/cli 0.1.5 → 0.1.7
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/README.md +264 -0
- package/dist/config/constants.d.ts +4 -1
- package/dist/index.cjs +135 -298
- package/dist/index.js +133 -297
- package/dist/utils/analytics.d.ts +24 -0
- package/dist/utils/job-runner.d.ts +2 -1
- package/package.json +3 -2
package/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
SuperDesign helps you (1) find design inspirations/styles and (2) generate/iterate design drafts on an infinite canvas.
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Core scenarios (what this skill handles)
|
|
6
|
+
|
|
7
|
+
1. **Help me design X** (feature/page/flow)
|
|
8
|
+
2. **Set design system**
|
|
9
|
+
3. **Help me improve design of X**
|
|
10
|
+
|
|
11
|
+
# Quickstart
|
|
12
|
+
|
|
13
|
+
Install CLI
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
npm install -g @superdesign/cli@latest
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Install skills for any coding agent
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
npx skills add superdesigndev/superdesign-skill
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Prompt in any agent
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
/superdesign help me design X
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
--
|
|
32
|
+
|
|
33
|
+
## Tooling overview
|
|
34
|
+
|
|
35
|
+
### A) Inspiration & Style Tools (generic, always available)
|
|
36
|
+
|
|
37
|
+
Use these to discover style direction, references, and brand context:
|
|
38
|
+
|
|
39
|
+
- **Search prompt library** (style/components/pages)
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
superdesign search-prompts --keyword "<keyword>" --json
|
|
43
|
+
superdesign search-prompts --tags "style" --json
|
|
44
|
+
superdesign search-prompts --tags "style" --keyword "<style keyword>" --json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- **Get full prompt details**
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
superdesign get-prompts --slugs "<slug1,slug2,...>" --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **Extract brand guide from a URL**
|
|
54
|
+
```bash
|
|
55
|
+
superdesign extract-brand-guide --url https://example.com --json
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### B) Canvas Design Tools
|
|
59
|
+
|
|
60
|
+
Use design agent to generate high quality design drafts:
|
|
61
|
+
|
|
62
|
+
- Create project (supports prompt / prompt file / HTML)
|
|
63
|
+
- Create design draft
|
|
64
|
+
- Iterate design draft (replace / branch)
|
|
65
|
+
- Plan flow pages → execute flow pages
|
|
66
|
+
- Fetch specific design draft
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Overall SOP for designing features on top of existing app:
|
|
71
|
+
|
|
72
|
+
1. Investigate existing UI, workflow
|
|
73
|
+
2. Setup design system file if not exist yet
|
|
74
|
+
3. Requirements gathering: use askQuestion tool to clarify requirements with users (Optionally use Inspiration tool to find inspiration when needed)
|
|
75
|
+
4. Ask user whether ready to design in superdesign OR implement UI directly
|
|
76
|
+
5. If yes to superdesign
|
|
77
|
+
5.1 Create/update a pixel perfect html replica of current UI of page that we will design on top of in `.superdesign/replica_html_template/<name>.html` (html should only contain & reflect how UI look now, the actual design should be handled by superdesign agent)
|
|
78
|
+
5.2 Create project with this replica html + design system guide
|
|
79
|
+
5.3 Start desigining by iterating & branching design draft based on designDraft ID returned from project
|
|
80
|
+
|
|
81
|
+
## Always-on rules
|
|
82
|
+
|
|
83
|
+
- Design system should live at: `.superdesign/design-system.md`
|
|
84
|
+
- If `.superdesign/design-system.md` is missing, run **Design System Setup** first.
|
|
85
|
+
- Use `askQuestion` to ask high-signal questions (constraints, taste, tradeoffs).
|
|
86
|
+
- Always use `--json` for machine parsing.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## replica_html_template rules (Canvas only)
|
|
91
|
+
|
|
92
|
+
The purpose of replica html template is creating a lightweight version of existing UI so design agent can iterate on top of it (Since superdesign doesn't have access to your codebase directly, this is important context)
|
|
93
|
+
|
|
94
|
+
Overall process for designing features on top of existing app:
|
|
95
|
+
|
|
96
|
+
1. Identify & understand existing UI of page related
|
|
97
|
+
2. Create/update a pixel perfect replica html in `.superdesign/replica_html_template/<name>.html` (Only replicate how UI look now, do NOT design)
|
|
98
|
+
|
|
99
|
+
- If design task is redesign profile page, then replicate current profile page UI pixel perfectly
|
|
100
|
+
- If design task is add new button to side panel, identify which page side panel is using, then replicate that page UI pixel perfectly
|
|
101
|
+
|
|
102
|
+
**replica_html_template = BEFORE state (what exists now).** It provides context for SuperDesign agent.
|
|
103
|
+
Actual design will be done via superdesign agent, by passing the prompt
|
|
104
|
+
|
|
105
|
+
The replica_html_template must contain **ONLY UI that currently exists in the codebase**.
|
|
106
|
+
|
|
107
|
+
- **DO NOT** design or improve anything in the replica_html_template
|
|
108
|
+
- **DO NOT** add placeholder sections like `<!-- NEW FEATURE - DESIGN THIS -->`
|
|
109
|
+
- **DO** create pixel-perfect replica of current UI state
|
|
110
|
+
- Save to: `.superdesign/replica_html_template/<name>.html`
|
|
111
|
+
|
|
112
|
+
### Naming & Reuse
|
|
113
|
+
|
|
114
|
+
**Naming convention**
|
|
115
|
+
Name replica_html_template for reusability: Use the page route (e.g., `home.html`, `settings-profile.html`, `dashboard.html`)
|
|
116
|
+
This makes it easy to identify if a page_template already exists.
|
|
117
|
+
|
|
118
|
+
**Before creating a replica_html_template:**
|
|
119
|
+
|
|
120
|
+
1. Check if `.superdesign/replica_html_template/` already contains a matching file
|
|
121
|
+
2. If exists: reuse it or update to reflect the latest existing UI
|
|
122
|
+
3. If not exists: create the neww file
|
|
123
|
+
|
|
124
|
+
### Example: Adding a "Book Demo" section to home page
|
|
125
|
+
|
|
126
|
+
**BAD approach:**
|
|
127
|
+
|
|
128
|
+
```html
|
|
129
|
+
<!-- replica_html_template includes a sketched Book Demo section -->
|
|
130
|
+
<section class="book-demo">
|
|
131
|
+
<!-- DESIGN THIS - Add CTA here -->
|
|
132
|
+
<h3>Book a Demo</h3>
|
|
133
|
+
<button>Schedule</button>
|
|
134
|
+
</section>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**GOOD approach:**
|
|
138
|
+
|
|
139
|
+
```html
|
|
140
|
+
<!-- replica_html_template is pure replica of existing home page (hero + projects) -->
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Then in the iterate command:
|
|
144
|
+
1/ create project passing this replica html
|
|
145
|
+
2/ create design draft based on design draft id
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
# 1) Design System Setup
|
|
150
|
+
|
|
151
|
+
### Step 0 — Ask user (one question)
|
|
152
|
+
|
|
153
|
+
"Do you want to **create a new design system** or **extract from the current codebase**?"
|
|
154
|
+
|
|
155
|
+
### A) Extract from codebase
|
|
156
|
+
|
|
157
|
+
1. Investigate codebase:
|
|
158
|
+
- Product context: what is being built, target users, core value proposition, key user journeys and page structure
|
|
159
|
+
- design tokens, typography, colors, spacing, radius, shadows
|
|
160
|
+
- motion/animation patterns
|
|
161
|
+
- example components usage + implementation patterns
|
|
162
|
+
2. Write standalone design system to:
|
|
163
|
+
- `.superdesign/design-system.md`
|
|
164
|
+
- Must be implementable without the codebase
|
|
165
|
+
|
|
166
|
+
### B) Create a new design system (to improve current UI)
|
|
167
|
+
|
|
168
|
+
1. Investigate codebase to understand:
|
|
169
|
+
- Product context: what is being built, target users, core value proposition, key user journeys and page structure
|
|
170
|
+
- needed pages/components
|
|
171
|
+
2. Gather inspirations (generic tools):
|
|
172
|
+
- `superdesign search-prompts --tags "style" --json`
|
|
173
|
+
- `superdesign get-prompts --slugs ... --json`
|
|
174
|
+
- optional: `superdesign extract-brand-guide --url ... --json`
|
|
175
|
+
3. Interview user (`askQuestion`) to choose direction
|
|
176
|
+
4. Write:
|
|
177
|
+
- `.superdesign/design-system.md` (product context + UX flows + visual design, adapted to references)
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
# 2) Designing X (feature/page/flow)
|
|
182
|
+
|
|
183
|
+
### Example workflow - Add feature to existing page
|
|
184
|
+
|
|
185
|
+
1. Investigate existing design and Ask targeted questions (`askQuestion`) about requirements + taste
|
|
186
|
+
2. After clarifying, Ask user whether ready to design in superdesign OR implement UI directly
|
|
187
|
+
3. If design in superdesign
|
|
188
|
+
3.1 Ensure `.superdesign/design-system.md` exists (setup if missing)
|
|
189
|
+
3.2 Identify page most relevant, and build a pixel-perfect replica in replica_html_template:
|
|
190
|
+
- `.superdesign/replica_html_template/<page>-<feature>.html`
|
|
191
|
+
3.3 Create project with replica_html_template (returns `draftId`):
|
|
192
|
+
```bash
|
|
193
|
+
superdesign create-project \
|
|
194
|
+
--title "<feature>" \
|
|
195
|
+
--html-file .superdesign/replica_html_template/<file>.html \
|
|
196
|
+
--set-project-prompt-file .superdesign/design-system.md \
|
|
197
|
+
--json
|
|
198
|
+
```
|
|
199
|
+
→ Note: `draftId` in response is the baseline draft
|
|
200
|
+
3.4 Branch designs from baseline (use `draftId` from step 3.3)
|
|
201
|
+
```bash
|
|
202
|
+
superdesign iterate-design-draft \
|
|
203
|
+
--draft-id <draftId> \
|
|
204
|
+
-p "Dark theme with neon accents" \
|
|
205
|
+
-p "Minimal with more whitespace" \
|
|
206
|
+
-p "Bold gradients and shadows" \
|
|
207
|
+
--mode branch \
|
|
208
|
+
--json
|
|
209
|
+
```
|
|
210
|
+
3.5 Share design title & preview URL → collect feedback → iterate
|
|
211
|
+
|
|
212
|
+
### Advanced usage
|
|
213
|
+
|
|
214
|
+
#### Design multiple page OR a full user journey
|
|
215
|
+
|
|
216
|
+
Execute:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
superdesign execute-flow-pages \
|
|
220
|
+
--draft-id <draftId> \
|
|
221
|
+
--source-node-id <nodeId> \
|
|
222
|
+
--pages '[{"title":"Signup","prompt":"..."},{"title":"Payment","prompt":"..."}]' \
|
|
223
|
+
--json
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### Get HTML reference from a draft
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
superdesign get-design --draft-id <draftId> --output ./design.html
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Quick reference (key commands)
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Inspirations
|
|
238
|
+
superdesign search-prompts --keyword "<keyword>" --json
|
|
239
|
+
superdesign search-prompts --tags "style" --json
|
|
240
|
+
superdesign get-prompts --slugs "<slug1,slug2>" --json
|
|
241
|
+
superdesign extract-brand-guide --url https://example.com --json
|
|
242
|
+
|
|
243
|
+
# Canvas - Create project
|
|
244
|
+
# Options: -s/--set-project-prompt (inline), --set-project-prompt-file (from file)
|
|
245
|
+
superdesign create-project --title "X" --set-project-prompt "..." --json
|
|
246
|
+
superdesign create-project --title "X" --set-project-prompt-file .superdesign/design-system.md --json
|
|
247
|
+
superdesign create-project --title "X" --html-file ./index.html --set-project-prompt-file .superdesign/design-system.md --json
|
|
248
|
+
|
|
249
|
+
# Iterate: replace mode (single variation, updates in place)
|
|
250
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode replace --json
|
|
251
|
+
|
|
252
|
+
# Iterate: Explore multiple versions & variations (each prompt = one variation, prompt should be just directional, do not specify color, style, let superdesign design expert fill in details, you just give direction)
|
|
253
|
+
superdesign iterate-design-draft --draft-id <id> -p "dark theme" -p "minimal" -p "bold" --mode branch --json
|
|
254
|
+
|
|
255
|
+
# Iterate: Auto explore (only give exploration direction, and let Superdesign fill in details, e.g. explore different styles; Default do not use this)
|
|
256
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json
|
|
257
|
+
|
|
258
|
+
# Fetch & get designs
|
|
259
|
+
superdesign fetch-design-nodes --project-id <id> --json
|
|
260
|
+
superdesign get-design --draft-id <id> --json
|
|
261
|
+
|
|
262
|
+
# Create new design from scracth without any reference - ONLY use this for creating brand new design, default NEVER use this
|
|
263
|
+
superdesign create-design-draft --project-id <id> --title "X" -p "..." --json
|
|
264
|
+
```
|
|
@@ -12,7 +12,10 @@ 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.
|
|
15
|
+
export declare const CLI_VERSION = "0.1.7";
|
|
16
|
+
/** PostHog analytics configuration */
|
|
17
|
+
export declare const POSTHOG_KEY: string;
|
|
18
|
+
export declare const POSTHOG_HOST: string;
|
|
16
19
|
/** Config directory name */
|
|
17
20
|
export declare const CONFIG_DIR_NAME = ".superdesign";
|
|
18
21
|
/** Config file name */
|
package/dist/index.cjs
CHANGED
|
@@ -91,8 +91,8 @@ 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
|
|
95
|
-
const
|
|
94
|
+
const POSTHOG_KEY = process.env.POSTHOG_KEY || 'phc_oUcDklFBX3wy8eksSyEC0pataKCgSadur1sio5hBHg4';
|
|
95
|
+
const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com';
|
|
96
96
|
const CONFIG_DIR_NAME = '.superdesign';
|
|
97
97
|
const CONFIG_FILE_NAME = 'config.json';
|
|
98
98
|
const EXIT_CODES = {
|
|
@@ -106,6 +106,9 @@ var __webpack_exports__ = {};
|
|
|
106
106
|
};
|
|
107
107
|
const SKILLS_DIR = '.claude/skills/superdesign';
|
|
108
108
|
const SKILL_FILE_NAME = 'SKILL.md';
|
|
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.
|
|
319
|
+
cliVersion: "0.1.7",
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 login
|
|
546
|
+
superdesign --help
|
|
778
547
|
\`\`\`
|
|
779
548
|
`;
|
|
780
549
|
}
|
|
@@ -882,56 +651,45 @@ superdesign get-design --draft-id <id> --json
|
|
|
882
651
|
}
|
|
883
652
|
async function runJob(config) {
|
|
884
653
|
const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
894
|
-
}
|
|
895
|
-
});
|
|
896
|
-
if (pollResult.timedOut) {
|
|
897
|
-
failSpinner(timeoutLabel);
|
|
898
|
-
output_error('Job timed out. The operation may still be processing in the background.');
|
|
899
|
-
if (isJsonMode()) output({
|
|
900
|
-
error: 'timeout',
|
|
901
|
-
jobId: job.jobId
|
|
902
|
-
});
|
|
903
|
-
process.exit(EXIT_CODES.TIMEOUT);
|
|
904
|
-
}
|
|
905
|
-
if (!pollResult.success || !pollResult.data) {
|
|
906
|
-
failSpinner(failureLabel);
|
|
907
|
-
output_error(pollResult.error || 'Failed to get job status');
|
|
908
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
909
|
-
}
|
|
910
|
-
const jobResult = pollResult.data;
|
|
911
|
-
if (isJobFailed(jobResult)) {
|
|
912
|
-
failSpinner(failureLabel);
|
|
913
|
-
output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
|
|
914
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
915
|
-
}
|
|
916
|
-
if (!isJobCompleted(jobResult)) {
|
|
917
|
-
failSpinner('Unexpected job status');
|
|
918
|
-
output_error('Job ended in unexpected state');
|
|
919
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
654
|
+
startSpinner(startLabel);
|
|
655
|
+
const job = await startJob();
|
|
656
|
+
updateSpinner(pollingLabel);
|
|
657
|
+
const pollResult = await poll(()=>getJobStatus(job.jobId), isJobDone, {
|
|
658
|
+
intervalMs: 2000,
|
|
659
|
+
timeoutMs,
|
|
660
|
+
onPoll: (attempt)=>{
|
|
661
|
+
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
920
662
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
663
|
+
});
|
|
664
|
+
if (pollResult.timedOut) {
|
|
665
|
+
failSpinner(timeoutLabel);
|
|
666
|
+
if (isJsonMode()) output({
|
|
667
|
+
error: 'timeout',
|
|
668
|
+
jobId: job.jobId
|
|
669
|
+
});
|
|
670
|
+
else output_error('Job timed out. The operation may still be processing in the background.');
|
|
671
|
+
throw new ApiClientError('Job timed out', 'timeout');
|
|
672
|
+
}
|
|
673
|
+
if (!pollResult.success || !pollResult.data) {
|
|
926
674
|
failSpinner(failureLabel);
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
675
|
+
const errMsg = pollResult.error || 'Failed to get job status';
|
|
676
|
+
if (!isJsonMode()) output_error(errMsg);
|
|
677
|
+
throw new ApiClientError(errMsg, 'api_error');
|
|
678
|
+
}
|
|
679
|
+
const jobResult = pollResult.data;
|
|
680
|
+
if (isJobFailed(jobResult)) {
|
|
681
|
+
failSpinner(failureLabel);
|
|
682
|
+
if (!isJsonMode()) output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
|
|
683
|
+
throw new ApiClientError(jobResult.error.message, jobResult.error.code);
|
|
934
684
|
}
|
|
685
|
+
if (!isJobCompleted(jobResult)) {
|
|
686
|
+
failSpinner('Unexpected job status');
|
|
687
|
+
if (!isJsonMode()) output_error('Job ended in unexpected state');
|
|
688
|
+
throw new ApiClientError('Job ended in unexpected state', 'unexpected_status');
|
|
689
|
+
}
|
|
690
|
+
succeedSpinner(successLabel);
|
|
691
|
+
if (isJsonMode()) output(transformResult(jobResult));
|
|
692
|
+
else displayResult(jobResult);
|
|
935
693
|
}
|
|
936
694
|
function job_runner_requireAuth(isAuthenticated) {
|
|
937
695
|
if (!isAuthenticated()) {
|
|
@@ -1509,6 +1267,72 @@ superdesign get-design --draft-id <id> --json
|
|
|
1509
1267
|
});
|
|
1510
1268
|
return command;
|
|
1511
1269
|
}
|
|
1270
|
+
const external_posthog_node_namespaceObject = require("posthog-node");
|
|
1271
|
+
let posthogClient = null;
|
|
1272
|
+
function getPostHog() {
|
|
1273
|
+
if (!posthogClient && POSTHOG_KEY) posthogClient = new external_posthog_node_namespaceObject.PostHog(POSTHOG_KEY, {
|
|
1274
|
+
host: POSTHOG_HOST
|
|
1275
|
+
});
|
|
1276
|
+
return posthogClient;
|
|
1277
|
+
}
|
|
1278
|
+
const SENSITIVE_KEYS = [
|
|
1279
|
+
'token',
|
|
1280
|
+
'key',
|
|
1281
|
+
'secret',
|
|
1282
|
+
'password',
|
|
1283
|
+
'apikey',
|
|
1284
|
+
'auth',
|
|
1285
|
+
'authorization',
|
|
1286
|
+
'credential'
|
|
1287
|
+
];
|
|
1288
|
+
function sanitizeOptions(options) {
|
|
1289
|
+
const sanitized = {};
|
|
1290
|
+
for (const [key, value] of Object.entries(options)){
|
|
1291
|
+
if ('function' == typeof value || key.startsWith('_')) continue;
|
|
1292
|
+
const lowerKey = key.toLowerCase();
|
|
1293
|
+
if (!SENSITIVE_KEYS.some((sensitive)=>lowerKey.includes(sensitive))) {
|
|
1294
|
+
if ('string' != typeof value || !(value.length > 100)) sanitized[key] = value;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
return sanitized;
|
|
1298
|
+
}
|
|
1299
|
+
async function trackCommand(opts) {
|
|
1300
|
+
const { teamId } = loadConfig();
|
|
1301
|
+
const metadata = {
|
|
1302
|
+
command: opts.command,
|
|
1303
|
+
success: opts.success,
|
|
1304
|
+
durationMs: opts.durationMs,
|
|
1305
|
+
errorCode: opts.errorCode,
|
|
1306
|
+
options: opts.options,
|
|
1307
|
+
cliVersion: "0.1.7",
|
|
1308
|
+
os: `${external_os_default().platform()} ${external_os_default().release()}`
|
|
1309
|
+
};
|
|
1310
|
+
const posthog = getPostHog();
|
|
1311
|
+
if (posthog) {
|
|
1312
|
+
const distinctId = teamId || `anon_${external_os_default().hostname()}`;
|
|
1313
|
+
posthog.capture({
|
|
1314
|
+
distinctId,
|
|
1315
|
+
event: 'cli_command',
|
|
1316
|
+
properties: {
|
|
1317
|
+
team_id: teamId,
|
|
1318
|
+
...metadata
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
if (manager_isAuthenticated() && teamId) try {
|
|
1323
|
+
const client = getApiClient();
|
|
1324
|
+
await client.post('/external/track', {
|
|
1325
|
+
activityType: 'cli_command',
|
|
1326
|
+
metadata
|
|
1327
|
+
});
|
|
1328
|
+
} catch {}
|
|
1329
|
+
}
|
|
1330
|
+
async function shutdownAnalytics() {
|
|
1331
|
+
if (posthogClient) {
|
|
1332
|
+
await posthogClient.shutdown();
|
|
1333
|
+
posthogClient = null;
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1512
1336
|
const src_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
|
|
1513
1337
|
const src_dirname = (0, external_path_namespaceObject.dirname)(src_filename);
|
|
1514
1338
|
(0, external_dotenv_namespaceObject.config)({
|
|
@@ -1517,7 +1341,20 @@ superdesign get-design --draft-id <id> --json
|
|
|
1517
1341
|
(0, external_dotenv_namespaceObject.config)();
|
|
1518
1342
|
function createProgram() {
|
|
1519
1343
|
const program = new external_commander_namespaceObject.Command();
|
|
1520
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.
|
|
1344
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.7");
|
|
1345
|
+
let startTime = 0;
|
|
1346
|
+
program.hook('preAction', ()=>{
|
|
1347
|
+
startTime = Date.now();
|
|
1348
|
+
});
|
|
1349
|
+
program.hook('postAction', async (_thisCommand, actionCommand)=>{
|
|
1350
|
+
await trackCommand({
|
|
1351
|
+
command: actionCommand.name(),
|
|
1352
|
+
success: true,
|
|
1353
|
+
durationMs: Date.now() - startTime,
|
|
1354
|
+
options: sanitizeOptions(actionCommand.opts())
|
|
1355
|
+
});
|
|
1356
|
+
await shutdownAnalytics();
|
|
1357
|
+
});
|
|
1521
1358
|
program.addCommand(createLoginCommand());
|
|
1522
1359
|
program.addCommand(createLogoutCommand());
|
|
1523
1360
|
program.addCommand(createInitCommand());
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,13 @@ import { fileURLToPath } from "url";
|
|
|
3
3
|
import { dirname, join, resolve as external_path_resolve } from "path";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
6
|
-
import { homedir, hostname, platform, release } from "os";
|
|
6
|
+
import os, { homedir, hostname, platform, release } from "os";
|
|
7
7
|
import axios from "axios";
|
|
8
8
|
import ora from "ora";
|
|
9
9
|
import { writeFile } from "fs/promises";
|
|
10
|
+
import { PostHog } from "posthog-node";
|
|
11
|
+
const POSTHOG_KEY = process.env.POSTHOG_KEY || 'phc_oUcDklFBX3wy8eksSyEC0pataKCgSadur1sio5hBHg4';
|
|
12
|
+
const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com';
|
|
10
13
|
const CONFIG_DIR_NAME = '.superdesign';
|
|
11
14
|
const CONFIG_FILE_NAME = 'config.json';
|
|
12
15
|
const EXIT_CODES = {
|
|
@@ -223,7 +226,7 @@ async function runAuthFlow(options = {}) {
|
|
|
223
226
|
try {
|
|
224
227
|
startSpinner('Creating auth session...');
|
|
225
228
|
const session = await createSession({
|
|
226
|
-
cliVersion: "0.1.
|
|
229
|
+
cliVersion: "0.1.7",
|
|
227
230
|
os: `${platform()} ${release()}`,
|
|
228
231
|
hostname: hostname()
|
|
229
232
|
});
|
|
@@ -422,269 +425,35 @@ function getSkillTemplate() {
|
|
|
422
425
|
return `---
|
|
423
426
|
name: superdesign
|
|
424
427
|
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
|
|
428
|
+
metadata:
|
|
429
|
+
author: superdesign
|
|
430
|
+
version: "0.0.1"
|
|
425
431
|
---
|
|
426
432
|
|
|
427
|
-
SuperDesign helps you (1) find design inspirations/styles and (2)
|
|
428
|
-
|
|
429
|
-
Each SuperDesign canvas run creates a new node and returns a \`previewUrl\`.
|
|
433
|
+
SuperDesign helps you (1) find design inspirations/styles and (2) generate/iterate design drafts on an infinite canvas.
|
|
430
434
|
|
|
431
435
|
---
|
|
432
436
|
|
|
433
|
-
|
|
437
|
+
# Core scenarios (what this skill handles)
|
|
434
438
|
|
|
435
439
|
1. **Help me design X** (feature/page/flow)
|
|
436
440
|
2. **Set design system**
|
|
437
441
|
3. **Help me improve design of X**
|
|
438
442
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
## Tooling overview
|
|
442
|
-
|
|
443
|
-
### A) Inspiration & Style Tools (generic, always available)
|
|
444
|
-
Use these to discover style direction, references, and brand context:
|
|
445
|
-
|
|
446
|
-
- **Search prompt library** (style/components/pages)
|
|
447
|
-
\`\`\`bash
|
|
448
|
-
superdesign search-prompts --keyword "<keyword>" --json
|
|
449
|
-
superdesign search-prompts --tags "style" --json
|
|
450
|
-
superdesign search-prompts --tags "style" --keyword "<style keyword>" --json
|
|
451
|
-
\`\`\`
|
|
452
|
-
|
|
453
|
-
- **Get full prompt details**
|
|
454
|
-
\`\`\`bash
|
|
455
|
-
superdesign get-prompts --slugs "<slug1,slug2,...>" --json
|
|
456
|
-
\`\`\`
|
|
457
|
-
|
|
458
|
-
- **Extract brand guide from a URL**
|
|
459
|
-
\`\`\`bash
|
|
460
|
-
superdesign extract-brand-guide --url https://example.com --json
|
|
461
|
-
\`\`\`
|
|
462
|
-
|
|
463
|
-
### B) Canvas Design Tools (specialised, optional)
|
|
464
|
-
|
|
465
|
-
Use these when you want to explore multiple directions and show previews:
|
|
466
|
-
|
|
467
|
-
- Create project (supports prompt / prompt file / HTML)
|
|
468
|
-
- Create design draft
|
|
469
|
-
- Iterate design draft (replace / branch)
|
|
470
|
-
- Plan flow pages → execute flow pages
|
|
471
|
-
- Fetch nodes, export HTML
|
|
472
|
-
|
|
473
|
-
> Pixel-perfect HTML playground is ONLY required for Canvas workflows.
|
|
474
|
-
|
|
475
|
-
---
|
|
476
|
-
|
|
477
|
-
## Always-on rules
|
|
478
|
-
|
|
479
|
-
- Design system should live at: \`.superdesign/design-system.md\`
|
|
480
|
-
- If \`.superdesign/design-system.md\` is missing, run **Design System Setup** first.
|
|
481
|
-
- Use \`askQuestion\` to ask high-signal questions (constraints, taste, tradeoffs).
|
|
482
|
-
- For Canvas workflows: build a simplified/pixel-perfect prototype HTML in:
|
|
483
|
-
- \`.superdesign/playgrounds/<name>.html\`
|
|
484
|
-
- Always use \`--json\` for machine parsing.
|
|
485
|
-
|
|
486
|
-
---
|
|
487
|
-
|
|
488
|
-
## Playground rules (Canvas only)
|
|
489
|
-
|
|
490
|
-
**Playground = BEFORE state (what exists now).** It provides context for SuperDesign agent.
|
|
491
|
-
**Prompt = DESIRED CHANGE (what to add/modify).**
|
|
492
|
-
|
|
493
|
-
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.
|
|
494
|
-
|
|
495
|
-
- **DO NOT** design or improve anything in the playground
|
|
496
|
-
- **DO NOT** add placeholder sections like \`<!-- NEW FEATURE - DESIGN THIS -->\`
|
|
497
|
-
- **DO** create pixel-perfect replica of current UI state
|
|
498
|
-
- Valid formats:
|
|
499
|
-
- **Component-only**: isolated component with enough markup to show core UX/states
|
|
500
|
-
- **Full page**: replica of page where component operates (shows surrounding context)
|
|
501
|
-
- Save to: \`.superdesign/playgrounds/<name>.html\`
|
|
502
|
-
|
|
503
|
-
### Example: Adding a "Book Demo" section to home page
|
|
504
|
-
|
|
505
|
-
**BAD approach:**
|
|
506
|
-
\`\`\`html
|
|
507
|
-
<!-- playground includes a sketched Book Demo section -->
|
|
508
|
-
<section class="book-demo">
|
|
509
|
-
<!-- DESIGN THIS - Add CTA here -->
|
|
510
|
-
<h3>Book a Demo</h3>
|
|
511
|
-
<button>Schedule</button>
|
|
512
|
-
</section>
|
|
513
|
-
\`\`\`
|
|
514
|
-
|
|
515
|
-
**GOOD approach:**
|
|
516
|
-
\`\`\`html
|
|
517
|
-
<!-- playground is pure replica of existing home page (hero + projects) -->
|
|
518
|
-
<!-- NO book demo section in HTML -->
|
|
443
|
+
# How it works
|
|
444
|
+
Fetch fresh guidelines below:
|
|
519
445
|
\`\`\`
|
|
520
|
-
|
|
521
|
-
\`\`\`bash
|
|
522
|
-
--prompt "Add a Book Demo section between the hero and projects sections. Requirements: minimal card style, horizontal layout..."
|
|
523
|
-
\`\`\`
|
|
524
|
-
|
|
525
|
-
---
|
|
526
|
-
|
|
527
|
-
# 1) Design System Setup
|
|
528
|
-
|
|
529
|
-
### Step 0 — Ask user (one question)
|
|
530
|
-
|
|
531
|
-
"Do you want to **create a new design system** or **extract from the current codebase**?"
|
|
532
|
-
|
|
533
|
-
### A) Extract from codebase
|
|
534
|
-
|
|
535
|
-
1. Investigate codebase:
|
|
536
|
-
- design tokens, typography, colors, spacing, radius, shadows
|
|
537
|
-
- motion/animation patterns
|
|
538
|
-
- example components usage + implementation patterns
|
|
539
|
-
- core product functions + key pages
|
|
540
|
-
2. Write standalone design system to:
|
|
541
|
-
- \`.superdesign/design-system.md\`
|
|
542
|
-
- Must be implementable without the codebase
|
|
543
|
-
|
|
544
|
-
### B) Create a new design system (to improve current UI)
|
|
545
|
-
|
|
546
|
-
1. Investigate codebase to understand product + needed pages/components
|
|
547
|
-
2. Gather inspirations (generic tools):
|
|
548
|
-
- \`superdesign search-prompts --tags "style" --json\`
|
|
549
|
-
- \`superdesign get-prompts --slugs ... --json\`
|
|
550
|
-
- optional: \`superdesign extract-brand-guide --url ... --json\`
|
|
551
|
-
3. Interview user (\`askQuestion\`) to choose direction
|
|
552
|
-
4. Write:
|
|
553
|
-
- \`.superdesign/design-system.md\` (adapted to product + references)
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
# 2) Designing X (feature/page/flow)
|
|
558
|
-
|
|
559
|
-
## A) If user wants references / direction only (no canvas)
|
|
560
|
-
|
|
561
|
-
1. Ensure \`.superdesign/design-system.md\` exists (setup if missing)
|
|
562
|
-
2. Use inspiration tools to collect references:
|
|
563
|
-
- search prompts (style + component/page)
|
|
564
|
-
- get prompts (full details)
|
|
565
|
-
- extract brand guide if relevant
|
|
566
|
-
3. Provide a concrete design spec:
|
|
567
|
-
- layout + hierarchy
|
|
568
|
-
- component set + states
|
|
569
|
-
- token guidance (typography/color/spacing/radius/motion)
|
|
570
|
-
- interaction notes + edge cases
|
|
571
|
-
|
|
572
|
-
## B) If user wants visual exploration (canvas optional)
|
|
573
|
-
|
|
574
|
-
Use canvas when direction is uncertain or multiple options are needed.
|
|
575
|
-
|
|
576
|
-
### Canvas workflow — Add feature to existing page
|
|
577
|
-
|
|
578
|
-
1. Ensure \`.superdesign/design-system.md\` exists (setup if missing)
|
|
579
|
-
2. Build prototype HTML playground (simplified + pixel-perfect enough):
|
|
580
|
-
- \`.superdesign/playgrounds/<page>-<feature>.html\`
|
|
581
|
-
3. Ask targeted questions (\`askQuestion\`) about requirements + taste
|
|
582
|
-
4. Create project with playground HTML (returns \`draftId\`):
|
|
583
|
-
\`\`\`bash
|
|
584
|
-
superdesign create-project \\
|
|
585
|
-
--title "<feature>" \\
|
|
586
|
-
--html-file .superdesign/playgrounds/<file>.html \\
|
|
587
|
-
--prompt-file .superdesign/design-system.md \\
|
|
588
|
-
--json
|
|
589
|
-
\`\`\`
|
|
590
|
-
→ Note: \`draftId\` in response is the baseline draft
|
|
591
|
-
5. Branch designs from baseline (use \`draftId\` from step 4):
|
|
592
|
-
\`\`\`bash
|
|
593
|
-
superdesign iterate-design-draft \\
|
|
594
|
-
--draft-id <draftId> \\
|
|
595
|
-
--prompt "<design requirements>" \\
|
|
596
|
-
--mode branch \\
|
|
597
|
-
--count 3 \\
|
|
598
|
-
--json
|
|
599
|
-
\`\`\`
|
|
600
|
-
6. Share \`previewUrl\` → collect feedback → iterate
|
|
601
|
-
|
|
602
|
-
### Canvas workflow — Add new page
|
|
603
|
-
|
|
604
|
-
Same as above, but playground should include shared UI shell:
|
|
605
|
-
- nav, layout container, spacing rhythm, shared components
|
|
606
|
-
|
|
607
|
-
### Canvas workflow — Improve current UI
|
|
608
|
-
|
|
609
|
-
1. Investigate product + current UI states
|
|
610
|
-
2. Ensure design system exists
|
|
611
|
-
3. Propose improvement options:
|
|
612
|
-
- big restructure
|
|
613
|
-
- style uplift
|
|
614
|
-
- low-hanging polish
|
|
615
|
-
4. Pick one → build playground → create project (prompt-file design system) → branch drafts
|
|
616
|
-
5. Share \`previewUrl\` → iterate
|
|
617
|
-
|
|
618
|
-
### When to use create-design-draft
|
|
619
|
-
|
|
620
|
-
Only use \`create-design-draft\` when creating from scratch (no HTML baseline).
|
|
621
|
-
|
|
622
|
-
**Required in prompt:**
|
|
623
|
-
- Full page structure (header, sidebar, main content areas)
|
|
624
|
-
- Component environment/surroundings
|
|
625
|
-
- Layout context (what's above/below/beside)
|
|
626
|
-
|
|
627
|
-
\`\`\`bash
|
|
628
|
-
superdesign create-design-draft \\
|
|
629
|
-
--project-id <id> \\
|
|
630
|
-
--title "Feature X" \\
|
|
631
|
-
--prompt "Page has: fixed header 64px, left sidebar 240px, main content area. Design a settings panel in the main content area with..." \\
|
|
632
|
-
--device desktop \\
|
|
633
|
-
--json
|
|
634
|
-
\`\`\`
|
|
635
|
-
|
|
636
|
-
---
|
|
637
|
-
|
|
638
|
-
# Advanced usage
|
|
639
|
-
|
|
640
|
-
### Plan + generate a full user journey
|
|
641
|
-
|
|
642
|
-
Plan:
|
|
643
|
-
\`\`\`bash
|
|
644
|
-
superdesign plan-flow-pages \\
|
|
645
|
-
--draft-id <draftId> \\
|
|
646
|
-
--source-node-id <nodeId> \\
|
|
647
|
-
--context "<flow context>" \\
|
|
648
|
-
--json
|
|
446
|
+
https://raw.githubusercontent.com/superdesigndev/superdesign-skill/main/skills/superdesign/SUPERDESIGN.md
|
|
649
447
|
\`\`\`
|
|
650
448
|
|
|
651
|
-
|
|
652
|
-
\`\`\`bash
|
|
653
|
-
superdesign execute-flow-pages \\
|
|
654
|
-
--draft-id <draftId> \\
|
|
655
|
-
--source-node-id <nodeId> \\
|
|
656
|
-
--pages '[{"title":"Signup","prompt":"..."},{"title":"Payment","prompt":"..."}]' \\
|
|
657
|
-
--json
|
|
658
|
-
\`\`\`
|
|
449
|
+
Action accordingly based on instruction in the guidelines
|
|
659
450
|
|
|
660
|
-
|
|
451
|
+
# Superdesign CLI
|
|
661
452
|
|
|
662
|
-
\`\`\`bash
|
|
663
|
-
superdesign get-design --draft-id <draftId> --output ./design.html
|
|
664
453
|
\`\`\`
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
## Quick reference (key commands)
|
|
669
|
-
|
|
670
|
-
\`\`\`bash
|
|
671
|
-
# Inspirations
|
|
672
|
-
superdesign search-prompts --keyword "<keyword>" --json
|
|
673
|
-
superdesign search-prompts --tags "style" --json
|
|
674
|
-
superdesign get-prompts --slugs "<slug1,slug2>" --json
|
|
675
|
-
superdesign extract-brand-guide --url https://example.com --json
|
|
676
|
-
|
|
677
|
-
# Canvas
|
|
678
|
-
superdesign create-project --title "X" --prompt "..." --json
|
|
679
|
-
superdesign create-project --title "X" --prompt-file .superdesign/design-system.md --json
|
|
680
|
-
superdesign create-project --title "X" --html-file ./index.html --prompt-file .superdesign/design-system.md --json
|
|
681
|
-
|
|
682
|
-
superdesign create-design-draft --project-id <id> --title "X" --prompt "..." --device desktop --json
|
|
683
|
-
superdesign iterate-design-draft --draft-id <id> --prompt "..." --mode replace --json
|
|
684
|
-
superdesign iterate-design-draft --draft-id <id> --prompt "..." --mode branch --count 3 --json
|
|
685
|
-
|
|
686
|
-
superdesign fetch-design-nodes --project-id <id> --json
|
|
687
|
-
superdesign get-design --draft-id <id> --json
|
|
454
|
+
npm install -g @superdesign/cli@latest
|
|
455
|
+
superdesign login
|
|
456
|
+
superdesign --help
|
|
688
457
|
\`\`\`
|
|
689
458
|
`;
|
|
690
459
|
}
|
|
@@ -792,56 +561,45 @@ function isJobFailed(response) {
|
|
|
792
561
|
}
|
|
793
562
|
async function runJob(config) {
|
|
794
563
|
const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
804
|
-
}
|
|
805
|
-
});
|
|
806
|
-
if (pollResult.timedOut) {
|
|
807
|
-
failSpinner(timeoutLabel);
|
|
808
|
-
output_error('Job timed out. The operation may still be processing in the background.');
|
|
809
|
-
if (isJsonMode()) output({
|
|
810
|
-
error: 'timeout',
|
|
811
|
-
jobId: job.jobId
|
|
812
|
-
});
|
|
813
|
-
process.exit(EXIT_CODES.TIMEOUT);
|
|
814
|
-
}
|
|
815
|
-
if (!pollResult.success || !pollResult.data) {
|
|
816
|
-
failSpinner(failureLabel);
|
|
817
|
-
output_error(pollResult.error || 'Failed to get job status');
|
|
818
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
819
|
-
}
|
|
820
|
-
const jobResult = pollResult.data;
|
|
821
|
-
if (isJobFailed(jobResult)) {
|
|
822
|
-
failSpinner(failureLabel);
|
|
823
|
-
output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
|
|
824
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
564
|
+
startSpinner(startLabel);
|
|
565
|
+
const job = await startJob();
|
|
566
|
+
updateSpinner(pollingLabel);
|
|
567
|
+
const pollResult = await poll(()=>getJobStatus(job.jobId), isJobDone, {
|
|
568
|
+
intervalMs: 2000,
|
|
569
|
+
timeoutMs,
|
|
570
|
+
onPoll: (attempt)=>{
|
|
571
|
+
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
825
572
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
else
|
|
834
|
-
|
|
835
|
-
}
|
|
573
|
+
});
|
|
574
|
+
if (pollResult.timedOut) {
|
|
575
|
+
failSpinner(timeoutLabel);
|
|
576
|
+
if (isJsonMode()) output({
|
|
577
|
+
error: 'timeout',
|
|
578
|
+
jobId: job.jobId
|
|
579
|
+
});
|
|
580
|
+
else output_error('Job timed out. The operation may still be processing in the background.');
|
|
581
|
+
throw new ApiClientError('Job timed out', 'timeout');
|
|
582
|
+
}
|
|
583
|
+
if (!pollResult.success || !pollResult.data) {
|
|
836
584
|
failSpinner(failureLabel);
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
585
|
+
const errMsg = pollResult.error || 'Failed to get job status';
|
|
586
|
+
if (!isJsonMode()) output_error(errMsg);
|
|
587
|
+
throw new ApiClientError(errMsg, 'api_error');
|
|
588
|
+
}
|
|
589
|
+
const jobResult = pollResult.data;
|
|
590
|
+
if (isJobFailed(jobResult)) {
|
|
591
|
+
failSpinner(failureLabel);
|
|
592
|
+
if (!isJsonMode()) output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
|
|
593
|
+
throw new ApiClientError(jobResult.error.message, jobResult.error.code);
|
|
594
|
+
}
|
|
595
|
+
if (!isJobCompleted(jobResult)) {
|
|
596
|
+
failSpinner('Unexpected job status');
|
|
597
|
+
if (!isJsonMode()) output_error('Job ended in unexpected state');
|
|
598
|
+
throw new ApiClientError('Job ended in unexpected state', 'unexpected_status');
|
|
844
599
|
}
|
|
600
|
+
succeedSpinner(successLabel);
|
|
601
|
+
if (isJsonMode()) output(transformResult(jobResult));
|
|
602
|
+
else displayResult(jobResult);
|
|
845
603
|
}
|
|
846
604
|
function job_runner_requireAuth(isAuthenticated) {
|
|
847
605
|
if (!isAuthenticated()) {
|
|
@@ -1418,6 +1176,71 @@ function createGetDesignCommand() {
|
|
|
1418
1176
|
});
|
|
1419
1177
|
return command;
|
|
1420
1178
|
}
|
|
1179
|
+
let posthogClient = null;
|
|
1180
|
+
function getPostHog() {
|
|
1181
|
+
if (!posthogClient && POSTHOG_KEY) posthogClient = new PostHog(POSTHOG_KEY, {
|
|
1182
|
+
host: POSTHOG_HOST
|
|
1183
|
+
});
|
|
1184
|
+
return posthogClient;
|
|
1185
|
+
}
|
|
1186
|
+
const SENSITIVE_KEYS = [
|
|
1187
|
+
'token',
|
|
1188
|
+
'key',
|
|
1189
|
+
'secret',
|
|
1190
|
+
'password',
|
|
1191
|
+
'apikey',
|
|
1192
|
+
'auth',
|
|
1193
|
+
'authorization',
|
|
1194
|
+
'credential'
|
|
1195
|
+
];
|
|
1196
|
+
function sanitizeOptions(options) {
|
|
1197
|
+
const sanitized = {};
|
|
1198
|
+
for (const [key, value] of Object.entries(options)){
|
|
1199
|
+
if ('function' == typeof value || key.startsWith('_')) continue;
|
|
1200
|
+
const lowerKey = key.toLowerCase();
|
|
1201
|
+
if (!SENSITIVE_KEYS.some((sensitive)=>lowerKey.includes(sensitive))) {
|
|
1202
|
+
if ('string' != typeof value || !(value.length > 100)) sanitized[key] = value;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
return sanitized;
|
|
1206
|
+
}
|
|
1207
|
+
async function trackCommand(opts) {
|
|
1208
|
+
const { teamId } = loadConfig();
|
|
1209
|
+
const metadata = {
|
|
1210
|
+
command: opts.command,
|
|
1211
|
+
success: opts.success,
|
|
1212
|
+
durationMs: opts.durationMs,
|
|
1213
|
+
errorCode: opts.errorCode,
|
|
1214
|
+
options: opts.options,
|
|
1215
|
+
cliVersion: "0.1.7",
|
|
1216
|
+
os: `${os.platform()} ${os.release()}`
|
|
1217
|
+
};
|
|
1218
|
+
const posthog = getPostHog();
|
|
1219
|
+
if (posthog) {
|
|
1220
|
+
const distinctId = teamId || `anon_${os.hostname()}`;
|
|
1221
|
+
posthog.capture({
|
|
1222
|
+
distinctId,
|
|
1223
|
+
event: 'cli_command',
|
|
1224
|
+
properties: {
|
|
1225
|
+
team_id: teamId,
|
|
1226
|
+
...metadata
|
|
1227
|
+
}
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
if (manager_isAuthenticated() && teamId) try {
|
|
1231
|
+
const client = getApiClient();
|
|
1232
|
+
await client.post('/external/track', {
|
|
1233
|
+
activityType: 'cli_command',
|
|
1234
|
+
metadata
|
|
1235
|
+
});
|
|
1236
|
+
} catch {}
|
|
1237
|
+
}
|
|
1238
|
+
async function shutdownAnalytics() {
|
|
1239
|
+
if (posthogClient) {
|
|
1240
|
+
await posthogClient.shutdown();
|
|
1241
|
+
posthogClient = null;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1421
1244
|
const src_filename = fileURLToPath(import.meta.url);
|
|
1422
1245
|
const src_dirname = dirname(src_filename);
|
|
1423
1246
|
external_dotenv_config({
|
|
@@ -1426,7 +1249,20 @@ external_dotenv_config({
|
|
|
1426
1249
|
external_dotenv_config();
|
|
1427
1250
|
function createProgram() {
|
|
1428
1251
|
const program = new Command();
|
|
1429
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.
|
|
1252
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.7");
|
|
1253
|
+
let startTime = 0;
|
|
1254
|
+
program.hook('preAction', ()=>{
|
|
1255
|
+
startTime = Date.now();
|
|
1256
|
+
});
|
|
1257
|
+
program.hook('postAction', async (_thisCommand, actionCommand)=>{
|
|
1258
|
+
await trackCommand({
|
|
1259
|
+
command: actionCommand.name(),
|
|
1260
|
+
success: true,
|
|
1261
|
+
durationMs: Date.now() - startTime,
|
|
1262
|
+
options: sanitizeOptions(actionCommand.opts())
|
|
1263
|
+
});
|
|
1264
|
+
await shutdownAnalytics();
|
|
1265
|
+
});
|
|
1430
1266
|
program.addCommand(createLoginCommand());
|
|
1431
1267
|
program.addCommand(createLogoutCommand());
|
|
1432
1268
|
program.addCommand(createInitCommand());
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Analytics - Dual tracking with PostHog (real-time) and Backend (long-term storage)
|
|
3
|
+
*/
|
|
4
|
+
export interface TrackCommandOptions {
|
|
5
|
+
command: string;
|
|
6
|
+
success: boolean;
|
|
7
|
+
durationMs: number;
|
|
8
|
+
errorCode?: string;
|
|
9
|
+
options?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Sanitize command options by removing sensitive values, functions, and internal properties
|
|
13
|
+
*/
|
|
14
|
+
export declare function sanitizeOptions(options: Record<string, unknown>): Record<string, unknown>;
|
|
15
|
+
/**
|
|
16
|
+
* Track a CLI command execution
|
|
17
|
+
* Sends to both PostHog (real-time dashboards) and backend (long-term storage)
|
|
18
|
+
*/
|
|
19
|
+
export declare function trackCommand(opts: TrackCommandOptions): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Shutdown analytics and flush any pending events
|
|
22
|
+
* Should be called before CLI exits
|
|
23
|
+
*/
|
|
24
|
+
export declare function shutdownAnalytics(): Promise<void>;
|
|
@@ -33,8 +33,9 @@ export interface JobRunnerResult<TResult> {
|
|
|
33
33
|
/**
|
|
34
34
|
* Run a job with polling and standard error handling
|
|
35
35
|
* Handles spinner updates, timeout, failure states, and output formatting
|
|
36
|
+
* Returns normally on success, throws on failure (to allow postAction hooks to run)
|
|
36
37
|
*/
|
|
37
|
-
export declare function runJob<TResult>(config: JobRunnerConfig<TResult>): Promise<
|
|
38
|
+
export declare function runJob<TResult>(config: JobRunnerConfig<TResult>): Promise<void>;
|
|
38
39
|
/**
|
|
39
40
|
* Check authentication and exit with appropriate error if not authenticated
|
|
40
41
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superdesign/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "CLI for SuperDesign Platform - agent skills for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"commander": "^11.1.0",
|
|
30
30
|
"dotenv": "^16.3.0",
|
|
31
31
|
"open": "^10.0.0",
|
|
32
|
-
"ora": "^8.0.0"
|
|
32
|
+
"ora": "^8.0.0",
|
|
33
|
+
"posthog-node": "^5.24.1"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@rslib/core": "0.15.1",
|