@superdesign/cli 0.1.6 → 0.1.8
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 +263 -0
- package/dist/config/constants.d.ts +4 -4
- package/dist/index.cjs +67 -86
- package/dist/index.js +67 -86
- package/dist/utils/analytics.d.ts +2 -3
- package/dist/utils/job-runner.d.ts +2 -1
- package/package.json +8 -8
- package/LICENSE +0 -21
package/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
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
|
+
--pages '[{"title":"Signup","prompt":"..."},{"title":"Payment","prompt":"..."}]' \
|
|
222
|
+
--json
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Get HTML reference from a draft
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
superdesign get-design --draft-id <draftId> --output ./design.html
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Quick reference (key commands)
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Inspirations
|
|
237
|
+
superdesign search-prompts --keyword "<keyword>" --json
|
|
238
|
+
superdesign search-prompts --tags "style" --json
|
|
239
|
+
superdesign get-prompts --slugs "<slug1,slug2>" --json
|
|
240
|
+
superdesign extract-brand-guide --url https://example.com --json
|
|
241
|
+
|
|
242
|
+
# Canvas - Create project
|
|
243
|
+
# Options: -s/--set-project-prompt (inline), --set-project-prompt-file (from file)
|
|
244
|
+
superdesign create-project --title "X" --set-project-prompt "..." --json
|
|
245
|
+
superdesign create-project --title "X" --set-project-prompt-file .superdesign/design-system.md --json
|
|
246
|
+
superdesign create-project --title "X" --html-file ./index.html --set-project-prompt-file .superdesign/design-system.md --json
|
|
247
|
+
|
|
248
|
+
# Iterate: replace mode (single variation, updates in place)
|
|
249
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode replace --json
|
|
250
|
+
|
|
251
|
+
# 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)
|
|
252
|
+
superdesign iterate-design-draft --draft-id <id> -p "dark theme" -p "minimal" -p "bold" --mode branch --json
|
|
253
|
+
|
|
254
|
+
# Iterate: Auto explore (only give exploration direction, and let Superdesign fill in details, e.g. explore different styles; Default do not use this)
|
|
255
|
+
superdesign iterate-design-draft --draft-id <id> -p "..." --mode branch --count 3 --json
|
|
256
|
+
|
|
257
|
+
# Fetch & get designs
|
|
258
|
+
superdesign fetch-design-nodes --project-id <id> --json
|
|
259
|
+
superdesign get-design --draft-id <id> --json
|
|
260
|
+
|
|
261
|
+
# Create new design from scracth without any reference - ONLY use this for creating brand new design, default NEVER use this
|
|
262
|
+
superdesign create-design-draft --project-id <id> --title "X" -p "..." --json
|
|
263
|
+
```
|
|
@@ -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.8";
|
|
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 */
|
|
@@ -31,6 +34,3 @@ export declare const EXIT_CODES: {
|
|
|
31
34
|
export declare const SKILLS_DIR = ".claude/skills/superdesign";
|
|
32
35
|
/** SKILL.md file name */
|
|
33
36
|
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,6 +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 POSTHOG_KEY = process.env.POSTHOG_KEY || 'phc_oUcDklFBX3wy8eksSyEC0pataKCgSadur1sio5hBHg4';
|
|
95
|
+
const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com';
|
|
94
96
|
const CONFIG_DIR_NAME = '.superdesign';
|
|
95
97
|
const CONFIG_FILE_NAME = 'config.json';
|
|
96
98
|
const EXIT_CODES = {
|
|
@@ -104,8 +106,6 @@ var __webpack_exports__ = {};
|
|
|
104
106
|
};
|
|
105
107
|
const SKILLS_DIR = '.claude/skills/superdesign';
|
|
106
108
|
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
109
|
const external_fs_namespaceObject = require("fs");
|
|
110
110
|
const external_os_namespaceObject = require("os");
|
|
111
111
|
var external_os_default = /*#__PURE__*/ __webpack_require__.n(external_os_namespaceObject);
|
|
@@ -316,7 +316,7 @@ var __webpack_exports__ = {};
|
|
|
316
316
|
try {
|
|
317
317
|
startSpinner('Creating auth session...');
|
|
318
318
|
const session = await createSession({
|
|
319
|
-
cliVersion: "0.1.
|
|
319
|
+
cliVersion: "0.1.8",
|
|
320
320
|
os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
|
|
321
321
|
hostname: external_os_namespaceObject.hostname()
|
|
322
322
|
});
|
|
@@ -542,7 +542,7 @@ Action accordingly based on instruction in the guidelines
|
|
|
542
542
|
|
|
543
543
|
\`\`\`
|
|
544
544
|
npm install -g @superdesign/cli@latest
|
|
545
|
-
superdesign
|
|
545
|
+
superdesign login
|
|
546
546
|
superdesign --help
|
|
547
547
|
\`\`\`
|
|
548
548
|
`;
|
|
@@ -651,56 +651,45 @@ superdesign --help
|
|
|
651
651
|
}
|
|
652
652
|
async function runJob(config) {
|
|
653
653
|
const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
663
|
-
}
|
|
664
|
-
});
|
|
665
|
-
if (pollResult.timedOut) {
|
|
666
|
-
failSpinner(timeoutLabel);
|
|
667
|
-
output_error('Job timed out. The operation may still be processing in the background.');
|
|
668
|
-
if (isJsonMode()) output({
|
|
669
|
-
error: 'timeout',
|
|
670
|
-
jobId: job.jobId
|
|
671
|
-
});
|
|
672
|
-
process.exit(EXIT_CODES.TIMEOUT);
|
|
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)`);
|
|
673
662
|
}
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (!isJobCompleted(jobResult)) {
|
|
686
|
-
failSpinner('Unexpected job status');
|
|
687
|
-
output_error('Job ended in unexpected state');
|
|
688
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
689
|
-
}
|
|
690
|
-
succeedSpinner(successLabel);
|
|
691
|
-
if (isJsonMode()) output(transformResult(jobResult));
|
|
692
|
-
else displayResult(jobResult);
|
|
693
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
694
|
-
} catch (err) {
|
|
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) {
|
|
695
674
|
failSpinner(failureLabel);
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
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);
|
|
703
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);
|
|
704
693
|
}
|
|
705
694
|
function job_runner_requireAuth(isAuthenticated) {
|
|
706
695
|
if (!isAuthenticated()) {
|
|
@@ -927,9 +916,10 @@ superdesign --help
|
|
|
927
916
|
return command;
|
|
928
917
|
}
|
|
929
918
|
function createPlanFlowPagesCommand() {
|
|
930
|
-
const command = new external_commander_namespaceObject.Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').
|
|
919
|
+
const command = new external_commander_namespaceObject.Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').option('--context <context>', 'Additional context for flow planning').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
931
920
|
if (options.json) setJsonMode(true);
|
|
932
921
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
922
|
+
const sourceNodeId = `draft-variant-${options.draftId}`;
|
|
933
923
|
await runJob({
|
|
934
924
|
startLabel: 'Planning flow pages...',
|
|
935
925
|
pollingLabel: 'AI is analyzing and planning pages...',
|
|
@@ -937,7 +927,7 @@ superdesign --help
|
|
|
937
927
|
timeoutLabel: 'Planning timed out',
|
|
938
928
|
failureLabel: 'Failed to plan flow pages',
|
|
939
929
|
startJob: ()=>planFlowPages(options.draftId, {
|
|
940
|
-
sourceNodeId
|
|
930
|
+
sourceNodeId,
|
|
941
931
|
flowContext: options.context
|
|
942
932
|
}),
|
|
943
933
|
transformResult: (job)=>({
|
|
@@ -969,7 +959,7 @@ superdesign --help
|
|
|
969
959
|
return parsed;
|
|
970
960
|
}
|
|
971
961
|
function createExecuteFlowPagesCommand() {
|
|
972
|
-
const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--
|
|
962
|
+
const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--pages <json>', 'JSON array of pages to generate [{title, prompt}]').option('--context <context>', 'Additional context for flow generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
973
963
|
if (options.json) setJsonMode(true);
|
|
974
964
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
975
965
|
let pages;
|
|
@@ -989,6 +979,7 @@ superdesign --help
|
|
|
989
979
|
output_error('Maximum 10 pages allowed');
|
|
990
980
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
991
981
|
}
|
|
982
|
+
const sourceNodeId = `draft-variant-${options.draftId}`;
|
|
992
983
|
const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
|
|
993
984
|
await runJob({
|
|
994
985
|
startLabel: `Generating ${pages.length} flow page(s)...`,
|
|
@@ -998,7 +989,7 @@ superdesign --help
|
|
|
998
989
|
failureLabel: 'Failed to execute flow pages',
|
|
999
990
|
timeoutMs,
|
|
1000
991
|
startJob: ()=>executeFlowPages(options.draftId, {
|
|
1001
|
-
sourceNodeId
|
|
992
|
+
sourceNodeId,
|
|
1002
993
|
flowContext: options.context,
|
|
1003
994
|
pages
|
|
1004
995
|
}),
|
|
@@ -1286,38 +1277,36 @@ superdesign --help
|
|
|
1286
1277
|
});
|
|
1287
1278
|
return posthogClient;
|
|
1288
1279
|
}
|
|
1280
|
+
const SENSITIVE_KEYS = [
|
|
1281
|
+
'token',
|
|
1282
|
+
'key',
|
|
1283
|
+
'secret',
|
|
1284
|
+
'password',
|
|
1285
|
+
'apikey',
|
|
1286
|
+
'auth',
|
|
1287
|
+
'authorization',
|
|
1288
|
+
'credential'
|
|
1289
|
+
];
|
|
1289
1290
|
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
1291
|
const sanitized = {};
|
|
1303
1292
|
for (const [key, value] of Object.entries(options)){
|
|
1293
|
+
if ('function' == typeof value || key.startsWith('_')) continue;
|
|
1304
1294
|
const lowerKey = key.toLowerCase();
|
|
1305
|
-
if (!
|
|
1295
|
+
if (!SENSITIVE_KEYS.some((sensitive)=>lowerKey.includes(sensitive))) {
|
|
1306
1296
|
if ('string' != typeof value || !(value.length > 100)) sanitized[key] = value;
|
|
1307
1297
|
}
|
|
1308
1298
|
}
|
|
1309
1299
|
return sanitized;
|
|
1310
1300
|
}
|
|
1311
1301
|
async function trackCommand(opts) {
|
|
1312
|
-
const
|
|
1313
|
-
const teamId = config.teamId;
|
|
1302
|
+
const { teamId } = loadConfig();
|
|
1314
1303
|
const metadata = {
|
|
1315
1304
|
command: opts.command,
|
|
1316
1305
|
success: opts.success,
|
|
1317
1306
|
durationMs: opts.durationMs,
|
|
1318
1307
|
errorCode: opts.errorCode,
|
|
1319
|
-
options: opts.options
|
|
1320
|
-
cliVersion: "0.1.
|
|
1308
|
+
options: opts.options,
|
|
1309
|
+
cliVersion: "0.1.8",
|
|
1321
1310
|
os: `${external_os_default().platform()} ${external_os_default().release()}`
|
|
1322
1311
|
};
|
|
1323
1312
|
const posthog = getPostHog();
|
|
@@ -1352,27 +1341,19 @@ superdesign --help
|
|
|
1352
1341
|
path: (0, external_path_namespaceObject.resolve)(src_dirname, '../.env')
|
|
1353
1342
|
});
|
|
1354
1343
|
(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
|
-
}
|
|
1362
1344
|
function createProgram() {
|
|
1363
1345
|
const program = new external_commander_namespaceObject.Command();
|
|
1364
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.
|
|
1346
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.8");
|
|
1347
|
+
let startTime = 0;
|
|
1365
1348
|
program.hook('preAction', ()=>{
|
|
1366
|
-
|
|
1367
|
-
currentCommand = process.argv[2] || 'unknown';
|
|
1349
|
+
startTime = Date.now();
|
|
1368
1350
|
});
|
|
1369
1351
|
program.hook('postAction', async (_thisCommand, actionCommand)=>{
|
|
1370
|
-
const durationMs = Date.now() - commandStartTime;
|
|
1371
1352
|
await trackCommand({
|
|
1372
|
-
command:
|
|
1353
|
+
command: actionCommand.name(),
|
|
1373
1354
|
success: true,
|
|
1374
|
-
durationMs,
|
|
1375
|
-
options:
|
|
1355
|
+
durationMs: Date.now() - startTime,
|
|
1356
|
+
options: sanitizeOptions(actionCommand.opts())
|
|
1376
1357
|
});
|
|
1377
1358
|
await shutdownAnalytics();
|
|
1378
1359
|
});
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,8 @@ import axios from "axios";
|
|
|
8
8
|
import ora from "ora";
|
|
9
9
|
import { writeFile } from "fs/promises";
|
|
10
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';
|
|
11
13
|
const CONFIG_DIR_NAME = '.superdesign';
|
|
12
14
|
const CONFIG_FILE_NAME = 'config.json';
|
|
13
15
|
const EXIT_CODES = {
|
|
@@ -21,8 +23,6 @@ const EXIT_CODES = {
|
|
|
21
23
|
};
|
|
22
24
|
const SKILLS_DIR = '.claude/skills/superdesign';
|
|
23
25
|
const SKILL_FILE_NAME = 'SKILL.md';
|
|
24
|
-
const POSTHOG_KEY = process.env.POSTHOG_KEY || 'phc_oUcDklFBX3wy8eksSyEC0pataKCgSadur1sio5hBHg4';
|
|
25
|
-
const POSTHOG_HOST = process.env.POSTHOG_HOST || 'https://eu.i.posthog.com';
|
|
26
26
|
function getConfigDir() {
|
|
27
27
|
return join(homedir(), CONFIG_DIR_NAME);
|
|
28
28
|
}
|
|
@@ -226,7 +226,7 @@ async function runAuthFlow(options = {}) {
|
|
|
226
226
|
try {
|
|
227
227
|
startSpinner('Creating auth session...');
|
|
228
228
|
const session = await createSession({
|
|
229
|
-
cliVersion: "0.1.
|
|
229
|
+
cliVersion: "0.1.8",
|
|
230
230
|
os: `${platform()} ${release()}`,
|
|
231
231
|
hostname: hostname()
|
|
232
232
|
});
|
|
@@ -452,7 +452,7 @@ Action accordingly based on instruction in the guidelines
|
|
|
452
452
|
|
|
453
453
|
\`\`\`
|
|
454
454
|
npm install -g @superdesign/cli@latest
|
|
455
|
-
superdesign
|
|
455
|
+
superdesign login
|
|
456
456
|
superdesign --help
|
|
457
457
|
\`\`\`
|
|
458
458
|
`;
|
|
@@ -561,56 +561,45 @@ function isJobFailed(response) {
|
|
|
561
561
|
}
|
|
562
562
|
async function runJob(config) {
|
|
563
563
|
const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
573
|
-
}
|
|
574
|
-
});
|
|
575
|
-
if (pollResult.timedOut) {
|
|
576
|
-
failSpinner(timeoutLabel);
|
|
577
|
-
output_error('Job timed out. The operation may still be processing in the background.');
|
|
578
|
-
if (isJsonMode()) output({
|
|
579
|
-
error: 'timeout',
|
|
580
|
-
jobId: job.jobId
|
|
581
|
-
});
|
|
582
|
-
process.exit(EXIT_CODES.TIMEOUT);
|
|
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)`);
|
|
583
572
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
if (!isJobCompleted(jobResult)) {
|
|
596
|
-
failSpinner('Unexpected job status');
|
|
597
|
-
output_error('Job ended in unexpected state');
|
|
598
|
-
process.exit(EXIT_CODES.API_ERROR);
|
|
599
|
-
}
|
|
600
|
-
succeedSpinner(successLabel);
|
|
601
|
-
if (isJsonMode()) output(transformResult(jobResult));
|
|
602
|
-
else displayResult(jobResult);
|
|
603
|
-
process.exit(EXIT_CODES.SUCCESS);
|
|
604
|
-
} catch (err) {
|
|
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) {
|
|
605
584
|
failSpinner(failureLabel);
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
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);
|
|
613
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');
|
|
599
|
+
}
|
|
600
|
+
succeedSpinner(successLabel);
|
|
601
|
+
if (isJsonMode()) output(transformResult(jobResult));
|
|
602
|
+
else displayResult(jobResult);
|
|
614
603
|
}
|
|
615
604
|
function job_runner_requireAuth(isAuthenticated) {
|
|
616
605
|
if (!isAuthenticated()) {
|
|
@@ -837,9 +826,10 @@ function createIterateDesignDraftCommand() {
|
|
|
837
826
|
return command;
|
|
838
827
|
}
|
|
839
828
|
function createPlanFlowPagesCommand() {
|
|
840
|
-
const command = new Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').
|
|
829
|
+
const command = new Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').option('--context <context>', 'Additional context for flow planning').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
841
830
|
if (options.json) setJsonMode(true);
|
|
842
831
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
832
|
+
const sourceNodeId = `draft-variant-${options.draftId}`;
|
|
843
833
|
await runJob({
|
|
844
834
|
startLabel: 'Planning flow pages...',
|
|
845
835
|
pollingLabel: 'AI is analyzing and planning pages...',
|
|
@@ -847,7 +837,7 @@ function createPlanFlowPagesCommand() {
|
|
|
847
837
|
timeoutLabel: 'Planning timed out',
|
|
848
838
|
failureLabel: 'Failed to plan flow pages',
|
|
849
839
|
startJob: ()=>planFlowPages(options.draftId, {
|
|
850
|
-
sourceNodeId
|
|
840
|
+
sourceNodeId,
|
|
851
841
|
flowContext: options.context
|
|
852
842
|
}),
|
|
853
843
|
transformResult: (job)=>({
|
|
@@ -879,7 +869,7 @@ function parsePages(pagesJson) {
|
|
|
879
869
|
return parsed;
|
|
880
870
|
}
|
|
881
871
|
function createExecuteFlowPagesCommand() {
|
|
882
|
-
const command = new Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--
|
|
872
|
+
const command = new Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--pages <json>', 'JSON array of pages to generate [{title, prompt}]').option('--context <context>', 'Additional context for flow generation').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
883
873
|
if (options.json) setJsonMode(true);
|
|
884
874
|
job_runner_requireAuth(manager_isAuthenticated);
|
|
885
875
|
let pages;
|
|
@@ -899,6 +889,7 @@ function createExecuteFlowPagesCommand() {
|
|
|
899
889
|
output_error('Maximum 10 pages allowed');
|
|
900
890
|
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
901
891
|
}
|
|
892
|
+
const sourceNodeId = `draft-variant-${options.draftId}`;
|
|
902
893
|
const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
|
|
903
894
|
await runJob({
|
|
904
895
|
startLabel: `Generating ${pages.length} flow page(s)...`,
|
|
@@ -908,7 +899,7 @@ function createExecuteFlowPagesCommand() {
|
|
|
908
899
|
failureLabel: 'Failed to execute flow pages',
|
|
909
900
|
timeoutMs,
|
|
910
901
|
startJob: ()=>executeFlowPages(options.draftId, {
|
|
911
|
-
sourceNodeId
|
|
902
|
+
sourceNodeId,
|
|
912
903
|
flowContext: options.context,
|
|
913
904
|
pages
|
|
914
905
|
}),
|
|
@@ -1194,38 +1185,36 @@ function getPostHog() {
|
|
|
1194
1185
|
});
|
|
1195
1186
|
return posthogClient;
|
|
1196
1187
|
}
|
|
1188
|
+
const SENSITIVE_KEYS = [
|
|
1189
|
+
'token',
|
|
1190
|
+
'key',
|
|
1191
|
+
'secret',
|
|
1192
|
+
'password',
|
|
1193
|
+
'apikey',
|
|
1194
|
+
'auth',
|
|
1195
|
+
'authorization',
|
|
1196
|
+
'credential'
|
|
1197
|
+
];
|
|
1197
1198
|
function sanitizeOptions(options) {
|
|
1198
|
-
const sensitiveKeys = [
|
|
1199
|
-
'token',
|
|
1200
|
-
'key',
|
|
1201
|
-
'secret',
|
|
1202
|
-
'password',
|
|
1203
|
-
'apiKey',
|
|
1204
|
-
'api_key',
|
|
1205
|
-
'apikey',
|
|
1206
|
-
'auth',
|
|
1207
|
-
'authorization',
|
|
1208
|
-
'credential'
|
|
1209
|
-
];
|
|
1210
1199
|
const sanitized = {};
|
|
1211
1200
|
for (const [key, value] of Object.entries(options)){
|
|
1201
|
+
if ('function' == typeof value || key.startsWith('_')) continue;
|
|
1212
1202
|
const lowerKey = key.toLowerCase();
|
|
1213
|
-
if (!
|
|
1203
|
+
if (!SENSITIVE_KEYS.some((sensitive)=>lowerKey.includes(sensitive))) {
|
|
1214
1204
|
if ('string' != typeof value || !(value.length > 100)) sanitized[key] = value;
|
|
1215
1205
|
}
|
|
1216
1206
|
}
|
|
1217
1207
|
return sanitized;
|
|
1218
1208
|
}
|
|
1219
1209
|
async function trackCommand(opts) {
|
|
1220
|
-
const
|
|
1221
|
-
const teamId = config.teamId;
|
|
1210
|
+
const { teamId } = loadConfig();
|
|
1222
1211
|
const metadata = {
|
|
1223
1212
|
command: opts.command,
|
|
1224
1213
|
success: opts.success,
|
|
1225
1214
|
durationMs: opts.durationMs,
|
|
1226
1215
|
errorCode: opts.errorCode,
|
|
1227
|
-
options: opts.options
|
|
1228
|
-
cliVersion: "0.1.
|
|
1216
|
+
options: opts.options,
|
|
1217
|
+
cliVersion: "0.1.8",
|
|
1229
1218
|
os: `${os.platform()} ${os.release()}`
|
|
1230
1219
|
};
|
|
1231
1220
|
const posthog = getPostHog();
|
|
@@ -1260,27 +1249,19 @@ external_dotenv_config({
|
|
|
1260
1249
|
path: external_path_resolve(src_dirname, '../.env')
|
|
1261
1250
|
});
|
|
1262
1251
|
external_dotenv_config();
|
|
1263
|
-
let commandStartTime = 0;
|
|
1264
|
-
let currentCommand = '';
|
|
1265
|
-
function sanitizeCommandOptions(opts) {
|
|
1266
|
-
const sanitized = {};
|
|
1267
|
-
for (const [key, value] of Object.entries(opts))if (!('function' == typeof value || key.startsWith('_'))) sanitized[key] = value;
|
|
1268
|
-
return sanitized;
|
|
1269
|
-
}
|
|
1270
1252
|
function createProgram() {
|
|
1271
1253
|
const program = new Command();
|
|
1272
|
-
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.
|
|
1254
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.8");
|
|
1255
|
+
let startTime = 0;
|
|
1273
1256
|
program.hook('preAction', ()=>{
|
|
1274
|
-
|
|
1275
|
-
currentCommand = process.argv[2] || 'unknown';
|
|
1257
|
+
startTime = Date.now();
|
|
1276
1258
|
});
|
|
1277
1259
|
program.hook('postAction', async (_thisCommand, actionCommand)=>{
|
|
1278
|
-
const durationMs = Date.now() - commandStartTime;
|
|
1279
1260
|
await trackCommand({
|
|
1280
|
-
command:
|
|
1261
|
+
command: actionCommand.name(),
|
|
1281
1262
|
success: true,
|
|
1282
|
-
durationMs,
|
|
1283
|
-
options:
|
|
1263
|
+
durationMs: Date.now() - startTime,
|
|
1264
|
+
options: sanitizeOptions(actionCommand.opts())
|
|
1284
1265
|
});
|
|
1285
1266
|
await shutdownAnalytics();
|
|
1286
1267
|
});
|
|
@@ -9,9 +9,9 @@ export interface TrackCommandOptions {
|
|
|
9
9
|
options?: Record<string, unknown>;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Sanitize command options
|
|
12
|
+
* Sanitize command options by removing sensitive values, functions, and internal properties
|
|
13
13
|
*/
|
|
14
|
-
declare function sanitizeOptions(options: Record<string, unknown>): Record<string, unknown>;
|
|
14
|
+
export declare function sanitizeOptions(options: Record<string, unknown>): Record<string, unknown>;
|
|
15
15
|
/**
|
|
16
16
|
* Track a CLI command execution
|
|
17
17
|
* Sends to both PostHog (real-time dashboards) and backend (long-term storage)
|
|
@@ -22,4 +22,3 @@ export declare function trackCommand(opts: TrackCommandOptions): Promise<void>;
|
|
|
22
22
|
* Should be called before CLI exits
|
|
23
23
|
*/
|
|
24
24
|
export declare function shutdownAnalytics(): Promise<void>;
|
|
25
|
-
export { sanitizeOptions };
|
|
@@ -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.8",
|
|
4
4
|
"description": "CLI for SuperDesign Platform - agent skills for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -20,13 +20,17 @@
|
|
|
20
20
|
"dist",
|
|
21
21
|
"bin"
|
|
22
22
|
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "rslib build && chmod +x bin/superdesign.js",
|
|
25
|
+
"dev": "rslib build --watch"
|
|
26
|
+
},
|
|
23
27
|
"dependencies": {
|
|
24
28
|
"axios": "^1.6.0",
|
|
25
29
|
"commander": "^11.1.0",
|
|
26
30
|
"dotenv": "^16.3.0",
|
|
27
31
|
"open": "^10.0.0",
|
|
28
32
|
"ora": "^8.0.0",
|
|
29
|
-
"posthog-node": "^
|
|
33
|
+
"posthog-node": "^5.24.1"
|
|
30
34
|
},
|
|
31
35
|
"devDependencies": {
|
|
32
36
|
"@rslib/core": "0.15.1",
|
|
@@ -48,9 +52,5 @@
|
|
|
48
52
|
"url": "https://github.com/superdesigndev/superdesign-platform.git",
|
|
49
53
|
"directory": "packages/cli"
|
|
50
54
|
},
|
|
51
|
-
"license": "MIT"
|
|
52
|
-
|
|
53
|
-
"build": "rslib build && chmod +x bin/superdesign.js",
|
|
54
|
-
"dev": "rslib build --watch"
|
|
55
|
-
}
|
|
56
|
-
}
|
|
55
|
+
"license": "MIT"
|
|
56
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
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.
|