@superdesign/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/superdesign.js +11 -0
- package/dist/api/auth.d.ts +36 -0
- package/dist/api/client.d.ts +28 -0
- package/dist/api/drafts.d.ts +46 -0
- package/dist/api/jobs.d.ts +73 -0
- package/dist/api/projects.d.ts +33 -0
- package/dist/commands/create-design-draft.d.ts +5 -0
- package/dist/commands/create-project.d.ts +5 -0
- package/dist/commands/execute-flow-pages.d.ts +5 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/iterate-design-draft.d.ts +5 -0
- package/dist/commands/login.d.ts +5 -0
- package/dist/commands/logout.d.ts +5 -0
- package/dist/commands/plan-flow-pages.d.ts +5 -0
- package/dist/config/constants.d.ts +33 -0
- package/dist/config/manager.d.ts +45 -0
- package/dist/index.cjs +1254 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1107 -0
- package/dist/skills/superdesign.d.ts +4 -0
- package/dist/utils/ascii-animation.d.ts +17 -0
- package/dist/utils/auth-flow.d.ts +22 -0
- package/dist/utils/job-runner.d.ts +41 -0
- package/dist/utils/open-browser.d.ts +7 -0
- package/dist/utils/output.d.ts +39 -0
- package/dist/utils/poll.d.ts +29 -0
- package/dist/utils/spinner.d.ts +29 -0
- package/package.json +55 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
|
|
3
|
+
return 'undefined' == typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
|
|
4
|
+
}();
|
|
5
|
+
var __webpack_modules__ = {
|
|
6
|
+
open: function(module) {
|
|
7
|
+
module.exports = import("open").then(function(module) {
|
|
8
|
+
return module;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var __webpack_module_cache__ = {};
|
|
13
|
+
function __webpack_require__(moduleId) {
|
|
14
|
+
var cachedModule = __webpack_module_cache__[moduleId];
|
|
15
|
+
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
16
|
+
var module = __webpack_module_cache__[moduleId] = {
|
|
17
|
+
exports: {}
|
|
18
|
+
};
|
|
19
|
+
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
20
|
+
return module.exports;
|
|
21
|
+
}
|
|
22
|
+
(()=>{
|
|
23
|
+
__webpack_require__.n = (module)=>{
|
|
24
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
25
|
+
__webpack_require__.d(getter, {
|
|
26
|
+
a: getter
|
|
27
|
+
});
|
|
28
|
+
return getter;
|
|
29
|
+
};
|
|
30
|
+
})();
|
|
31
|
+
(()=>{
|
|
32
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
33
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
get: definition[key]
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
(()=>{
|
|
40
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
41
|
+
})();
|
|
42
|
+
(()=>{
|
|
43
|
+
__webpack_require__.r = (exports1)=>{
|
|
44
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
45
|
+
value: 'Module'
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
48
|
+
value: true
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
var __webpack_exports__ = {};
|
|
53
|
+
(()=>{
|
|
54
|
+
__webpack_require__.r(__webpack_exports__);
|
|
55
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
56
|
+
run: ()=>run,
|
|
57
|
+
createDraft: ()=>createDraft,
|
|
58
|
+
getApiUrl: ()=>getApiUrl,
|
|
59
|
+
iterateDraft: ()=>iterateDraft,
|
|
60
|
+
clearConfig: ()=>clearConfig,
|
|
61
|
+
isJobDone: ()=>isJobDone,
|
|
62
|
+
createProject: ()=>createProject,
|
|
63
|
+
executeFlowPages: ()=>executeFlowPages,
|
|
64
|
+
loadConfig: ()=>loadConfig,
|
|
65
|
+
createPublicApiClient: ()=>createPublicApiClient,
|
|
66
|
+
planFlowPages: ()=>planFlowPages,
|
|
67
|
+
claimSession: ()=>claimSession,
|
|
68
|
+
isAuthenticated: ()=>manager_isAuthenticated,
|
|
69
|
+
addDraft: ()=>addDraft,
|
|
70
|
+
saveConfig: ()=>saveConfig,
|
|
71
|
+
createSession: ()=>createSession,
|
|
72
|
+
isJobFailed: ()=>isJobFailed,
|
|
73
|
+
getConfigPath: ()=>getConfigPath,
|
|
74
|
+
pollSession: ()=>pollSession,
|
|
75
|
+
updateConfig: ()=>updateConfig,
|
|
76
|
+
createProgram: ()=>createProgram,
|
|
77
|
+
getApiClient: ()=>getApiClient,
|
|
78
|
+
getJobStatus: ()=>getJobStatus,
|
|
79
|
+
getConfigDir: ()=>getConfigDir,
|
|
80
|
+
isJobCompleted: ()=>isJobCompleted,
|
|
81
|
+
ApiClientError: ()=>ApiClientError,
|
|
82
|
+
getApiKey: ()=>getApiKey,
|
|
83
|
+
createApiClient: ()=>createApiClient
|
|
84
|
+
});
|
|
85
|
+
const external_dotenv_namespaceObject = require("dotenv");
|
|
86
|
+
const external_url_namespaceObject = require("url");
|
|
87
|
+
const external_path_namespaceObject = require("path");
|
|
88
|
+
const external_commander_namespaceObject = require("commander");
|
|
89
|
+
const external_fs_namespaceObject = require("fs");
|
|
90
|
+
const external_os_namespaceObject = require("os");
|
|
91
|
+
const CONFIG_DIR_NAME = '.superdesign';
|
|
92
|
+
const CONFIG_FILE_NAME = 'config.json';
|
|
93
|
+
const EXIT_CODES = {
|
|
94
|
+
SUCCESS: 0,
|
|
95
|
+
GENERAL_ERROR: 1,
|
|
96
|
+
AUTH_REQUIRED: 2,
|
|
97
|
+
AUTH_FAILED: 3,
|
|
98
|
+
API_ERROR: 4,
|
|
99
|
+
VALIDATION_ERROR: 5,
|
|
100
|
+
TIMEOUT: 6
|
|
101
|
+
};
|
|
102
|
+
const SKILLS_DIR = '.claude/skills/superdesign';
|
|
103
|
+
const SKILL_FILE_NAME = 'SKILL.md';
|
|
104
|
+
function getConfigDir() {
|
|
105
|
+
return external_path_namespaceObject.join(external_os_namespaceObject.homedir(), CONFIG_DIR_NAME);
|
|
106
|
+
}
|
|
107
|
+
function getConfigPath() {
|
|
108
|
+
return external_path_namespaceObject.join(getConfigDir(), CONFIG_FILE_NAME);
|
|
109
|
+
}
|
|
110
|
+
function ensureConfigDir() {
|
|
111
|
+
const configDir = getConfigDir();
|
|
112
|
+
if (!external_fs_namespaceObject.existsSync(configDir)) external_fs_namespaceObject.mkdirSync(configDir, {
|
|
113
|
+
recursive: true,
|
|
114
|
+
mode: 448
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function loadConfig() {
|
|
118
|
+
const configPath = getConfigPath();
|
|
119
|
+
if (!external_fs_namespaceObject.existsSync(configPath)) return {};
|
|
120
|
+
try {
|
|
121
|
+
const content = external_fs_namespaceObject.readFileSync(configPath, 'utf-8');
|
|
122
|
+
return JSON.parse(content);
|
|
123
|
+
} catch {
|
|
124
|
+
return {};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function saveConfig(config) {
|
|
128
|
+
ensureConfigDir();
|
|
129
|
+
const configPath = getConfigPath();
|
|
130
|
+
external_fs_namespaceObject.writeFileSync(configPath, JSON.stringify(config, null, 2), {
|
|
131
|
+
encoding: 'utf-8',
|
|
132
|
+
mode: 384
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function updateConfig(updates) {
|
|
136
|
+
const current = loadConfig();
|
|
137
|
+
const updated = {
|
|
138
|
+
...current,
|
|
139
|
+
...updates
|
|
140
|
+
};
|
|
141
|
+
saveConfig(updated);
|
|
142
|
+
return updated;
|
|
143
|
+
}
|
|
144
|
+
function clearConfig() {
|
|
145
|
+
const configPath = getConfigPath();
|
|
146
|
+
if (external_fs_namespaceObject.existsSync(configPath)) external_fs_namespaceObject.unlinkSync(configPath);
|
|
147
|
+
}
|
|
148
|
+
function manager_isAuthenticated() {
|
|
149
|
+
const config = loadConfig();
|
|
150
|
+
return !!config.apiKey;
|
|
151
|
+
}
|
|
152
|
+
function getApiKey() {
|
|
153
|
+
const config = loadConfig();
|
|
154
|
+
if (!config.apiKey) throw new Error('Not authenticated. Run `superdesign login` first.');
|
|
155
|
+
return config.apiKey;
|
|
156
|
+
}
|
|
157
|
+
function getApiUrl() {
|
|
158
|
+
const config = loadConfig();
|
|
159
|
+
return config.apiUrl || process.env.SUPERDESIGN_API_URL || 'https://api.superdesign.dev/v1';
|
|
160
|
+
}
|
|
161
|
+
const external_axios_namespaceObject = require("axios");
|
|
162
|
+
var external_axios_default = /*#__PURE__*/ __webpack_require__.n(external_axios_namespaceObject);
|
|
163
|
+
class ApiClientError extends Error {
|
|
164
|
+
constructor(message, code, status, details){
|
|
165
|
+
super(message), this.code = code, this.status = status, this.details = details;
|
|
166
|
+
this.name = 'ApiClientError';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function createApiClient(requireAuth = true) {
|
|
170
|
+
const baseURL = getApiUrl();
|
|
171
|
+
const client = external_axios_default().create({
|
|
172
|
+
baseURL,
|
|
173
|
+
timeout: 30000,
|
|
174
|
+
headers: {
|
|
175
|
+
'Content-Type': 'application/json'
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
if (requireAuth) client.interceptors.request.use((config)=>{
|
|
179
|
+
if (!manager_isAuthenticated()) throw new ApiClientError('Not authenticated. Run `superdesign login` first.', 'auth_required', 401);
|
|
180
|
+
const apiKey = getApiKey();
|
|
181
|
+
config.headers.Authorization = `Bearer ${apiKey}`;
|
|
182
|
+
return config;
|
|
183
|
+
});
|
|
184
|
+
client.interceptors.response.use((response)=>response, (error)=>{
|
|
185
|
+
if (error.response) {
|
|
186
|
+
const { status, data } = error.response;
|
|
187
|
+
const apiError = data?.error;
|
|
188
|
+
throw new ApiClientError(apiError?.message || error.message, apiError?.code || 'api_error', status, apiError?.details);
|
|
189
|
+
}
|
|
190
|
+
if ('ECONNREFUSED' === error.code) throw new ApiClientError('Could not connect to SuperDesign API', 'connection_error');
|
|
191
|
+
if ('ETIMEDOUT' === error.code) throw new ApiClientError('Request timed out', 'timeout');
|
|
192
|
+
throw new ApiClientError(error.message || 'Unknown error', 'unknown_error');
|
|
193
|
+
});
|
|
194
|
+
return client;
|
|
195
|
+
}
|
|
196
|
+
function createPublicApiClient() {
|
|
197
|
+
return createApiClient(false);
|
|
198
|
+
}
|
|
199
|
+
function getApiClient() {
|
|
200
|
+
return createApiClient(true);
|
|
201
|
+
}
|
|
202
|
+
async function createSession(data) {
|
|
203
|
+
const client = createPublicApiClient();
|
|
204
|
+
const response = await client.post('/cli-auth/sessions', data);
|
|
205
|
+
return response.data;
|
|
206
|
+
}
|
|
207
|
+
async function pollSession(pollToken) {
|
|
208
|
+
const client = createPublicApiClient();
|
|
209
|
+
const response = await client.get('/cli-auth/sessions/poll', {
|
|
210
|
+
params: {
|
|
211
|
+
token: pollToken
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
return response.data;
|
|
215
|
+
}
|
|
216
|
+
async function claimSession(pollToken) {
|
|
217
|
+
const client = createPublicApiClient();
|
|
218
|
+
const response = await client.post('/cli-auth/sessions/claim', {
|
|
219
|
+
pollToken
|
|
220
|
+
});
|
|
221
|
+
return response.data;
|
|
222
|
+
}
|
|
223
|
+
async function openBrowser(url) {
|
|
224
|
+
const open = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "open"));
|
|
225
|
+
await open.default(url);
|
|
226
|
+
}
|
|
227
|
+
async function poll(fn, isDone, options = {}) {
|
|
228
|
+
const intervalMs = options.intervalMs ?? 2000;
|
|
229
|
+
const timeoutMs = options.timeoutMs ?? 300000;
|
|
230
|
+
const startTime = Date.now();
|
|
231
|
+
let attempt = 0;
|
|
232
|
+
while(Date.now() - startTime < timeoutMs){
|
|
233
|
+
attempt++;
|
|
234
|
+
if (options.onPoll) options.onPoll(attempt);
|
|
235
|
+
try {
|
|
236
|
+
const result = await fn();
|
|
237
|
+
if (isDone(result)) return {
|
|
238
|
+
success: true,
|
|
239
|
+
data: result
|
|
240
|
+
};
|
|
241
|
+
} catch (err) {
|
|
242
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
243
|
+
return {
|
|
244
|
+
success: false,
|
|
245
|
+
error: message
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
await sleep(intervalMs);
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
success: false,
|
|
252
|
+
timedOut: true,
|
|
253
|
+
error: 'Polling timed out'
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function sleep(ms) {
|
|
257
|
+
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
258
|
+
}
|
|
259
|
+
const external_ora_namespaceObject = require("ora");
|
|
260
|
+
var external_ora_default = /*#__PURE__*/ __webpack_require__.n(external_ora_namespaceObject);
|
|
261
|
+
let jsonMode = false;
|
|
262
|
+
function setJsonMode(enabled) {
|
|
263
|
+
jsonMode = enabled;
|
|
264
|
+
}
|
|
265
|
+
function isJsonMode() {
|
|
266
|
+
return jsonMode;
|
|
267
|
+
}
|
|
268
|
+
function output(data) {
|
|
269
|
+
if (jsonMode) console.log(JSON.stringify(data, null, 2));
|
|
270
|
+
else if ('string' == typeof data) console.log(data);
|
|
271
|
+
else console.log(JSON.stringify(data, null, 2));
|
|
272
|
+
}
|
|
273
|
+
function success(message) {
|
|
274
|
+
if (!jsonMode) console.log(`✓ ${message}`);
|
|
275
|
+
}
|
|
276
|
+
function output_error(message) {
|
|
277
|
+
if (jsonMode) console.error(JSON.stringify({
|
|
278
|
+
error: message
|
|
279
|
+
}));
|
|
280
|
+
else console.error(`✗ ${message}`);
|
|
281
|
+
}
|
|
282
|
+
function info(message) {
|
|
283
|
+
if (!jsonMode) console.log(message);
|
|
284
|
+
}
|
|
285
|
+
let currentSpinner = null;
|
|
286
|
+
function startSpinner(text) {
|
|
287
|
+
if (isJsonMode()) return null;
|
|
288
|
+
currentSpinner = external_ora_default()(text).start();
|
|
289
|
+
return currentSpinner;
|
|
290
|
+
}
|
|
291
|
+
function updateSpinner(text) {
|
|
292
|
+
if (currentSpinner) currentSpinner.text = text;
|
|
293
|
+
}
|
|
294
|
+
function succeedSpinner(text) {
|
|
295
|
+
if (currentSpinner) {
|
|
296
|
+
currentSpinner.succeed(text);
|
|
297
|
+
currentSpinner = null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function failSpinner(text) {
|
|
301
|
+
if (currentSpinner) {
|
|
302
|
+
currentSpinner.fail(text);
|
|
303
|
+
currentSpinner = null;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function runAuthFlow(options = {}) {
|
|
307
|
+
const { openBrowser: shouldOpenBrowser = true, showSuccessMessage = true } = options;
|
|
308
|
+
try {
|
|
309
|
+
startSpinner('Creating auth session...');
|
|
310
|
+
const session = await createSession({
|
|
311
|
+
cliVersion: "0.1.0",
|
|
312
|
+
os: `${external_os_namespaceObject.platform()} ${external_os_namespaceObject.release()}`,
|
|
313
|
+
hostname: external_os_namespaceObject.hostname()
|
|
314
|
+
});
|
|
315
|
+
updateSpinner('Waiting for browser authorization...');
|
|
316
|
+
if (shouldOpenBrowser) try {
|
|
317
|
+
await openBrowser(session.authUrl);
|
|
318
|
+
info(`\nOpened browser to: ${session.authUrl}`);
|
|
319
|
+
} catch {
|
|
320
|
+
info(`\nPlease open this URL in your browser:\n${session.authUrl}`);
|
|
321
|
+
}
|
|
322
|
+
else info(`\nPlease open this URL in your browser:\n${session.authUrl}`);
|
|
323
|
+
info(`\nSession code: ${session.sessionCode}`);
|
|
324
|
+
info('Waiting for authorization...\n');
|
|
325
|
+
const pollResult = await poll(()=>pollSession(session.pollToken), (response)=>'pending' !== response.status, {
|
|
326
|
+
intervalMs: 2000,
|
|
327
|
+
timeoutMs: 600000,
|
|
328
|
+
onPoll: (attempt)=>{
|
|
329
|
+
if (attempt % 10 === 0) updateSpinner(`Waiting for authorization... (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
if (pollResult.timedOut) {
|
|
333
|
+
failSpinner('Authorization timed out');
|
|
334
|
+
return {
|
|
335
|
+
success: false,
|
|
336
|
+
error: 'Session expired. Please try again.'
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
if (!pollResult.success || !pollResult.data) {
|
|
340
|
+
failSpinner('Authorization failed');
|
|
341
|
+
return {
|
|
342
|
+
success: false,
|
|
343
|
+
error: pollResult.error || 'Failed to get authorization status'
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
const authResponse = pollResult.data;
|
|
347
|
+
if ('expired' === authResponse.status) {
|
|
348
|
+
failSpinner('Session expired');
|
|
349
|
+
return {
|
|
350
|
+
success: false,
|
|
351
|
+
error: 'Session expired. Please try again.'
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
if ('approved' !== authResponse.status || !authResponse.apiKey) {
|
|
355
|
+
failSpinner('Authorization denied');
|
|
356
|
+
return {
|
|
357
|
+
success: false,
|
|
358
|
+
error: 'Authorization was denied or failed.'
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
await claimSession(session.pollToken);
|
|
362
|
+
updateConfig({
|
|
363
|
+
apiKey: authResponse.apiKey,
|
|
364
|
+
teamId: authResponse.teamId,
|
|
365
|
+
teamName: authResponse.teamName
|
|
366
|
+
});
|
|
367
|
+
succeedSpinner('Authenticated successfully!');
|
|
368
|
+
if (showSuccessMessage) success(`Logged in to team: ${authResponse.teamName}`);
|
|
369
|
+
return {
|
|
370
|
+
success: true,
|
|
371
|
+
teamId: authResponse.teamId,
|
|
372
|
+
teamName: authResponse.teamName,
|
|
373
|
+
apiKey: authResponse.apiKey
|
|
374
|
+
};
|
|
375
|
+
} catch (err) {
|
|
376
|
+
failSpinner('Login failed');
|
|
377
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
378
|
+
output_error(message);
|
|
379
|
+
return {
|
|
380
|
+
success: false,
|
|
381
|
+
error: message
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const LOGO = `
|
|
386
|
+
███████╗██╗ ██╗██████╗ ███████╗██████╗ ██████╗ ███████╗███████╗██╗ ██████╗ ███╗ ██╗
|
|
387
|
+
██╔════╝██║ ██║██╔══██╗██╔════╝██╔══██╗██╔══██╗██╔════╝██╔════╝██║██╔════╝ ████╗ ██║
|
|
388
|
+
███████╗██║ ██║██████╔╝█████╗ ██████╔╝██║ ██║█████╗ ███████╗██║██║ ███╗██╔██╗ ██║
|
|
389
|
+
╚════██║██║ ██║██╔═══╝ ██╔══╝ ██╔══██╗██║ ██║██╔══╝ ╚════██║██║██║ ██║██║╚██╗██║
|
|
390
|
+
███████║╚██████╔╝██║ ███████╗██║ ██║██████╔╝███████╗███████║██║╚██████╔╝██║ ╚████║
|
|
391
|
+
╚══════╝ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝
|
|
392
|
+
`.trim();
|
|
393
|
+
const TAGLINE = 'AI designer for coding agents';
|
|
394
|
+
const SCRAMBLE_CHARS = '░▒▓█▄▀│┤┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌';
|
|
395
|
+
function ascii_animation_sleep(ms) {
|
|
396
|
+
return new Promise((resolve)=>setTimeout(resolve, ms));
|
|
397
|
+
}
|
|
398
|
+
function getRandomChar() {
|
|
399
|
+
return SCRAMBLE_CHARS[Math.floor(Math.random() * SCRAMBLE_CHARS.length)];
|
|
400
|
+
}
|
|
401
|
+
function shouldSkipAnimation() {
|
|
402
|
+
if (process.env.CI) return true;
|
|
403
|
+
if (!process.stdout.isTTY) return true;
|
|
404
|
+
if (process.env.NO_COLOR) return true;
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
function clearFrame(lineCount) {
|
|
408
|
+
for(let i = 0; i < lineCount; i++){
|
|
409
|
+
process.stdout.write('\x1B[1A');
|
|
410
|
+
process.stdout.write('\x1B[2K');
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async function animateLogo() {
|
|
414
|
+
if (shouldSkipAnimation()) {
|
|
415
|
+
console.log(LOGO);
|
|
416
|
+
console.log(TAGLINE);
|
|
417
|
+
console.log();
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const lines = LOGO.split('\n');
|
|
421
|
+
const frames = 20;
|
|
422
|
+
const frameDelay = 60;
|
|
423
|
+
const scrambledLines = lines.map((line)=>line.split('').map((char)=>' ' === char ? ' ' : getRandomChar()).join(''));
|
|
424
|
+
console.log(scrambledLines.join('\n'));
|
|
425
|
+
for(let frame = 1; frame <= frames; frame++){
|
|
426
|
+
await ascii_animation_sleep(frameDelay);
|
|
427
|
+
clearFrame(lines.length);
|
|
428
|
+
const revealRatio = frame / frames;
|
|
429
|
+
const easedRatio = 1 - Math.pow(1 - revealRatio, 3);
|
|
430
|
+
const renderedLines = lines.map((line)=>line.split('').map((char, i)=>{
|
|
431
|
+
if (' ' === char) return ' ';
|
|
432
|
+
const positionFactor = i / line.length;
|
|
433
|
+
const threshold = 1.2 * easedRatio - 0.3 * positionFactor;
|
|
434
|
+
if (Math.random() < threshold) return char;
|
|
435
|
+
return getRandomChar();
|
|
436
|
+
}).join(''));
|
|
437
|
+
console.log(renderedLines.join('\n'));
|
|
438
|
+
}
|
|
439
|
+
clearFrame(lines.length);
|
|
440
|
+
console.log(LOGO);
|
|
441
|
+
await ascii_animation_sleep(100);
|
|
442
|
+
console.log(TAGLINE);
|
|
443
|
+
console.log();
|
|
444
|
+
}
|
|
445
|
+
function createLoginCommand() {
|
|
446
|
+
const command = new external_commander_namespaceObject.Command('login').description('Authenticate with SuperDesign platform').option('--json', 'Output in JSON format').option('--no-browser', 'Do not open browser automatically').action(async (options)=>{
|
|
447
|
+
if (options.json) setJsonMode(true);
|
|
448
|
+
if (!isJsonMode()) await animateLogo();
|
|
449
|
+
const currentConfig = loadConfig();
|
|
450
|
+
if (currentConfig.apiKey) {
|
|
451
|
+
info(`Already authenticated as team: ${currentConfig.teamName || 'Unknown'}`);
|
|
452
|
+
info('Run `superdesign login` again to re-authenticate.');
|
|
453
|
+
}
|
|
454
|
+
const result = await runAuthFlow({
|
|
455
|
+
openBrowser: false !== options.noBrowser,
|
|
456
|
+
showSuccessMessage: !isJsonMode()
|
|
457
|
+
});
|
|
458
|
+
if (!result.success) {
|
|
459
|
+
output_error(result.error || 'Authentication failed');
|
|
460
|
+
process.exit(EXIT_CODES.AUTH_FAILED);
|
|
461
|
+
}
|
|
462
|
+
if (isJsonMode()) output({
|
|
463
|
+
success: true,
|
|
464
|
+
teamId: result.teamId,
|
|
465
|
+
teamName: result.teamName
|
|
466
|
+
});
|
|
467
|
+
else {
|
|
468
|
+
info('\nYou can now use SuperDesign CLI commands.');
|
|
469
|
+
info('Run `superdesign init` to install Claude Code skills.');
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
return command;
|
|
473
|
+
}
|
|
474
|
+
function createLogoutCommand() {
|
|
475
|
+
const command = new external_commander_namespaceObject.Command('logout').description('Log out and clear stored credentials').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
476
|
+
if (options.json) setJsonMode(true);
|
|
477
|
+
try {
|
|
478
|
+
if (!manager_isAuthenticated()) {
|
|
479
|
+
if (isJsonMode()) output({
|
|
480
|
+
success: true,
|
|
481
|
+
message: 'Not logged in'
|
|
482
|
+
});
|
|
483
|
+
else info('Not logged in.');
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const config = loadConfig();
|
|
487
|
+
const teamName = config.teamName;
|
|
488
|
+
clearConfig();
|
|
489
|
+
if (isJsonMode()) output({
|
|
490
|
+
success: true,
|
|
491
|
+
message: 'Logged out successfully',
|
|
492
|
+
teamName
|
|
493
|
+
});
|
|
494
|
+
else {
|
|
495
|
+
success('Logged out successfully!');
|
|
496
|
+
if (teamName) info(`Disconnected from team: ${teamName}`);
|
|
497
|
+
info('\nRun `superdesign login` or `superdesign init` to authenticate again.');
|
|
498
|
+
}
|
|
499
|
+
} catch (err) {
|
|
500
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
501
|
+
output_error(`Failed to logout: ${message}`);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
return command;
|
|
505
|
+
}
|
|
506
|
+
function getSkillTemplate() {
|
|
507
|
+
return `---
|
|
508
|
+
name: superdesign
|
|
509
|
+
description: Superdesign is a design agent, where it specialised in frontend UI/UX design; Use this skill before you implement any UI that require some design thinking
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
# SuperDesign Integration
|
|
513
|
+
This skill provides integration with the SuperDesign platform for AI-powered design generation.
|
|
514
|
+
|
|
515
|
+
## Available Commands
|
|
516
|
+
|
|
517
|
+
### Create Project
|
|
518
|
+
|
|
519
|
+
Create a new new project, can pass optional HTML as initial starting point for design iteration:
|
|
520
|
+
|
|
521
|
+
\`\`\`bash
|
|
522
|
+
# Basic project
|
|
523
|
+
superdesign create-project --title "My Project" --json
|
|
524
|
+
|
|
525
|
+
# Project with initial HTML
|
|
526
|
+
superdesign create-project --title "My Project" --html "<html>...</html>" --json
|
|
527
|
+
|
|
528
|
+
# Project with HTML from file
|
|
529
|
+
superdesign create-project --title "My Project" --html-file ./index.html --json
|
|
530
|
+
\`\`\`
|
|
531
|
+
|
|
532
|
+
**Output (JSON):**
|
|
533
|
+
\`\`\`json
|
|
534
|
+
{
|
|
535
|
+
"projectId": "uuid",
|
|
536
|
+
"title": "My Project",
|
|
537
|
+
"projectUrl": "https://app.superdesign.ai/...",
|
|
538
|
+
"shareToken": "token"
|
|
539
|
+
}
|
|
540
|
+
\`\`\`
|
|
541
|
+
|
|
542
|
+
### Create Design Draft
|
|
543
|
+
|
|
544
|
+
Generate a design draft using AI designer:
|
|
545
|
+
|
|
546
|
+
\`\`\`bash
|
|
547
|
+
superdesign create-design-draft \\
|
|
548
|
+
--project-id <project-id> \\
|
|
549
|
+
--title "Hero Section" \\
|
|
550
|
+
--prompt "Create a modern hero section with gradient background" \\
|
|
551
|
+
--device desktop \\
|
|
552
|
+
--json
|
|
553
|
+
\`\`\`
|
|
554
|
+
|
|
555
|
+
**Options:**
|
|
556
|
+
- \`--project-id\` (required): Project to add draft to
|
|
557
|
+
- \`--title\` (required): Draft title
|
|
558
|
+
- \`--prompt\` (required): AI generation prompt
|
|
559
|
+
- \`--device\`: Device mode (mobile, tablet, desktop)
|
|
560
|
+
|
|
561
|
+
**Output (JSON):**
|
|
562
|
+
\`\`\`json
|
|
563
|
+
{
|
|
564
|
+
"draftId": "uuid",
|
|
565
|
+
"nodeId": "uuid",
|
|
566
|
+
"title": "Hero Section",
|
|
567
|
+
"projectUrl": "https://app.superdesign.ai/...",
|
|
568
|
+
"nodeUrl": "https://app.superdesign.ai/...?node=...",
|
|
569
|
+
"previewUrl": "https://preview.superdesign.ai/...",
|
|
570
|
+
"creditsConsumed": 1
|
|
571
|
+
}
|
|
572
|
+
\`\`\`
|
|
573
|
+
|
|
574
|
+
### Iterate Design Draft
|
|
575
|
+
|
|
576
|
+
Create variations or improvements of an existing draft:
|
|
577
|
+
|
|
578
|
+
\`\`\`bash
|
|
579
|
+
# Replace mode - updates the existing draft
|
|
580
|
+
superdesign iterate-design-draft \\
|
|
581
|
+
--draft-id <draft-id> \\
|
|
582
|
+
--prompt "Make the colors more vibrant" \\
|
|
583
|
+
--mode replace \\
|
|
584
|
+
--json
|
|
585
|
+
|
|
586
|
+
# Branch mode - creates new variations
|
|
587
|
+
superdesign iterate-design-draft \\
|
|
588
|
+
--draft-id <draft-id> \\
|
|
589
|
+
--prompt "Try different color schemes" \\
|
|
590
|
+
--mode branch \\
|
|
591
|
+
--count 3 \\
|
|
592
|
+
--json
|
|
593
|
+
\`\`\`
|
|
594
|
+
|
|
595
|
+
**Options:**
|
|
596
|
+
- \`--draft-id\` (required): Draft to iterate on
|
|
597
|
+
- \`--prompt\` (required): Iteration instructions
|
|
598
|
+
- \`--mode\` (required): "replace" or "branch"
|
|
599
|
+
- \`--count\`: Number of variations (1-4, branch mode only)
|
|
600
|
+
|
|
601
|
+
**Output (JSON):**
|
|
602
|
+
\`\`\`json
|
|
603
|
+
{
|
|
604
|
+
"drafts": [
|
|
605
|
+
{
|
|
606
|
+
"draftId": "uuid",
|
|
607
|
+
"nodeId": "uuid",
|
|
608
|
+
"title": "Variation 1",
|
|
609
|
+
"nodeUrl": "https://...",
|
|
610
|
+
"previewUrl": "https://..."
|
|
611
|
+
}
|
|
612
|
+
],
|
|
613
|
+
"projectUrl": "https://...",
|
|
614
|
+
"creditsConsumed": 3
|
|
615
|
+
}
|
|
616
|
+
\`\`\`
|
|
617
|
+
|
|
618
|
+
### Plan Flow Pages
|
|
619
|
+
|
|
620
|
+
Get AI suggestions for related pages in a user flow:
|
|
621
|
+
|
|
622
|
+
\`\`\`bash
|
|
623
|
+
superdesign plan-flow-pages \\
|
|
624
|
+
--draft-id <draft-id> \\
|
|
625
|
+
--source-node-id <node-id> \\
|
|
626
|
+
--context "E-commerce checkout flow" \\
|
|
627
|
+
--json
|
|
628
|
+
\`\`\`
|
|
629
|
+
|
|
630
|
+
**Options:**
|
|
631
|
+
- \`--draft-id\` (required): Source draft
|
|
632
|
+
- \`--source-node-id\` (required): Starting node in flow
|
|
633
|
+
- \`--context\`: Additional context for planning
|
|
634
|
+
|
|
635
|
+
**Output (JSON):**
|
|
636
|
+
\`\`\`json
|
|
637
|
+
{
|
|
638
|
+
"pages": [
|
|
639
|
+
{
|
|
640
|
+
"title": "Cart Review",
|
|
641
|
+
"prompt": "Create a cart review page showing..."
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
"title": "Payment",
|
|
645
|
+
"prompt": "Create a payment form with..."
|
|
646
|
+
}
|
|
647
|
+
],
|
|
648
|
+
"creditsConsumed": 1
|
|
649
|
+
}
|
|
650
|
+
\`\`\`
|
|
651
|
+
|
|
652
|
+
### Execute Flow Pages
|
|
653
|
+
|
|
654
|
+
Generate the planned flow pages:
|
|
655
|
+
|
|
656
|
+
\`\`\`bash
|
|
657
|
+
superdesign execute-flow-pages \\
|
|
658
|
+
--draft-id <draft-id> \\
|
|
659
|
+
--source-node-id <node-id> \\
|
|
660
|
+
--pages '[{"title":"Cart","prompt":"Create cart page"},{"title":"Payment","prompt":"Create payment form"}]' \\
|
|
661
|
+
--json
|
|
662
|
+
\`\`\`
|
|
663
|
+
|
|
664
|
+
**Options:**
|
|
665
|
+
- \`--draft-id\` (required): Source draft
|
|
666
|
+
- \`--source-node-id\` (required): Starting node
|
|
667
|
+
- \`--pages\` (required): JSON array of pages to generate
|
|
668
|
+
- \`--context\`: Additional context
|
|
669
|
+
|
|
670
|
+
**Output (JSON):**
|
|
671
|
+
\`\`\`json
|
|
672
|
+
{
|
|
673
|
+
"drafts": [
|
|
674
|
+
{
|
|
675
|
+
"index": 0,
|
|
676
|
+
"draftId": "uuid",
|
|
677
|
+
"nodeId": "uuid",
|
|
678
|
+
"title": "Cart",
|
|
679
|
+
"nodeUrl": "https://...",
|
|
680
|
+
"previewUrl": "https://..."
|
|
681
|
+
}
|
|
682
|
+
],
|
|
683
|
+
"projectUrl": "https://...",
|
|
684
|
+
"creditsConsumed": 2
|
|
685
|
+
}
|
|
686
|
+
\`\`\`
|
|
687
|
+
|
|
688
|
+
## Workflow Examples
|
|
689
|
+
|
|
690
|
+
### Create a new design from scratch
|
|
691
|
+
|
|
692
|
+
\`\`\`bash
|
|
693
|
+
# 1. Create project
|
|
694
|
+
PROJECT=$(superdesign create-project --title "Landing Page" --json)
|
|
695
|
+
PROJECT_ID=$(echo $PROJECT | jq -r '.projectId')
|
|
696
|
+
|
|
697
|
+
# 2. Generate initial design
|
|
698
|
+
DRAFT=$(superdesign create-design-draft \\
|
|
699
|
+
--project-id $PROJECT_ID \\
|
|
700
|
+
--title "Hero" \\
|
|
701
|
+
--prompt "Modern SaaS landing page hero with gradient, CTA button" \\
|
|
702
|
+
--json)
|
|
703
|
+
|
|
704
|
+
echo "Preview: $(echo $DRAFT | jq -r '.previewUrl')"
|
|
705
|
+
\`\`\`
|
|
706
|
+
|
|
707
|
+
### Iterate on existing design
|
|
708
|
+
|
|
709
|
+
\`\`\`bash
|
|
710
|
+
# Create variations
|
|
711
|
+
superdesign iterate-design-draft \\
|
|
712
|
+
--draft-id <draft-id> \\
|
|
713
|
+
--prompt "Try a dark theme version" \\
|
|
714
|
+
--mode branch \\
|
|
715
|
+
--count 2 \\
|
|
716
|
+
--json
|
|
717
|
+
\`\`\`
|
|
718
|
+
|
|
719
|
+
### Build a complete user flow
|
|
720
|
+
|
|
721
|
+
\`\`\`bash
|
|
722
|
+
# 1. Plan the flow
|
|
723
|
+
PLAN=$(superdesign plan-flow-pages \\
|
|
724
|
+
--draft-id <draft-id> \\
|
|
725
|
+
--source-node-id <node-id> \\
|
|
726
|
+
--context "User onboarding flow" \\
|
|
727
|
+
--json)
|
|
728
|
+
|
|
729
|
+
# 2. Execute the plan
|
|
730
|
+
PAGES=$(echo $PLAN | jq -c '.pages')
|
|
731
|
+
superdesign execute-flow-pages \\
|
|
732
|
+
--draft-id <draft-id> \\
|
|
733
|
+
--source-node-id <node-id> \\
|
|
734
|
+
--pages "$PAGES" \\
|
|
735
|
+
--json
|
|
736
|
+
\`\`\`
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
## Tips
|
|
740
|
+
|
|
741
|
+
- Always use \`--json\` flag when parsing output programmatically
|
|
742
|
+
- Store project and draft IDs for subsequent operations
|
|
743
|
+
- Use \`plan-flow-pages\` before \`execute-flow-pages\` for best results
|
|
744
|
+
- The \`previewUrl\` can be used to view designs without authentication
|
|
745
|
+
`;
|
|
746
|
+
}
|
|
747
|
+
function createInitCommand() {
|
|
748
|
+
const command = new external_commander_namespaceObject.Command('init').description('Install SuperDesign skill files for Claude Code (auto-login if needed)').option('--json', 'Output in JSON format').option('--force', 'Overwrite existing skill files').action(async (options)=>{
|
|
749
|
+
if (options.json) setJsonMode(true);
|
|
750
|
+
if (!isJsonMode()) await animateLogo();
|
|
751
|
+
try {
|
|
752
|
+
if (!manager_isAuthenticated()) {
|
|
753
|
+
info('Not authenticated. Starting login flow...\n');
|
|
754
|
+
const authResult = await runAuthFlow({
|
|
755
|
+
showSuccessMessage: true
|
|
756
|
+
});
|
|
757
|
+
if (!authResult.success) {
|
|
758
|
+
output_error(authResult.error || 'Authentication failed');
|
|
759
|
+
process.exit(EXIT_CODES.AUTH_FAILED);
|
|
760
|
+
}
|
|
761
|
+
info('');
|
|
762
|
+
}
|
|
763
|
+
const cwd = process.cwd();
|
|
764
|
+
const skillsPath = external_path_namespaceObject.join(cwd, SKILLS_DIR);
|
|
765
|
+
const skillFilePath = external_path_namespaceObject.join(skillsPath, SKILL_FILE_NAME);
|
|
766
|
+
if (external_fs_namespaceObject.existsSync(skillFilePath) && !options.force) {
|
|
767
|
+
if (isJsonMode()) output({
|
|
768
|
+
success: false,
|
|
769
|
+
error: 'Skill file already exists. Use --force to overwrite.',
|
|
770
|
+
path: skillFilePath
|
|
771
|
+
});
|
|
772
|
+
else {
|
|
773
|
+
info(`Skill file already exists at: ${skillFilePath}`);
|
|
774
|
+
info('Use --force to overwrite.');
|
|
775
|
+
}
|
|
776
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
777
|
+
}
|
|
778
|
+
external_fs_namespaceObject.mkdirSync(skillsPath, {
|
|
779
|
+
recursive: true
|
|
780
|
+
});
|
|
781
|
+
const skillContent = getSkillTemplate();
|
|
782
|
+
external_fs_namespaceObject.writeFileSync(skillFilePath, skillContent, 'utf-8');
|
|
783
|
+
if (isJsonMode()) output({
|
|
784
|
+
success: true,
|
|
785
|
+
path: skillFilePath,
|
|
786
|
+
message: 'Skill files installed successfully'
|
|
787
|
+
});
|
|
788
|
+
else {
|
|
789
|
+
success('Skill files installed successfully!');
|
|
790
|
+
info(`\nSkill file created at: ${skillFilePath}`);
|
|
791
|
+
info('\nClaude Code will now have access to SuperDesign commands.');
|
|
792
|
+
info('Available commands:');
|
|
793
|
+
info(' - superdesign create-project');
|
|
794
|
+
info(' - superdesign create-design-draft');
|
|
795
|
+
info(' - superdesign iterate-design-draft');
|
|
796
|
+
info(' - superdesign plan-flow-pages');
|
|
797
|
+
info(' - superdesign execute-flow-pages');
|
|
798
|
+
}
|
|
799
|
+
} catch (err) {
|
|
800
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
801
|
+
output_error(`Failed to initialize: ${message}`);
|
|
802
|
+
process.exit(EXIT_CODES.GENERAL_ERROR);
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
return command;
|
|
806
|
+
}
|
|
807
|
+
async function createProject(data) {
|
|
808
|
+
const client = getApiClient();
|
|
809
|
+
const response = await client.post('/external/projects', data);
|
|
810
|
+
return response.data;
|
|
811
|
+
}
|
|
812
|
+
async function addDraft(projectId, data) {
|
|
813
|
+
const client = getApiClient();
|
|
814
|
+
const response = await client.post(`/external/projects/${projectId}/drafts/add`, data);
|
|
815
|
+
return response.data;
|
|
816
|
+
}
|
|
817
|
+
function createCreateProjectCommand() {
|
|
818
|
+
const command = new external_commander_namespaceObject.Command('create-project').description('Create a new SuperDesign project').requiredOption('--title <title>', 'Project title').option('--html <html>', 'Initial HTML content for first draft').option('--html-file <path>', 'Path to HTML file for first draft').option('--device <mode>', 'Device mode for draft (mobile, tablet, desktop)', 'desktop').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
819
|
+
if (options.json) setJsonMode(true);
|
|
820
|
+
try {
|
|
821
|
+
if (!manager_isAuthenticated()) {
|
|
822
|
+
output_error('Not authenticated. Run `superdesign login` first.');
|
|
823
|
+
process.exit(EXIT_CODES.AUTH_REQUIRED);
|
|
824
|
+
}
|
|
825
|
+
if (options.device && ![
|
|
826
|
+
'mobile',
|
|
827
|
+
'tablet',
|
|
828
|
+
'desktop'
|
|
829
|
+
].includes(options.device)) {
|
|
830
|
+
output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
|
|
831
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
832
|
+
}
|
|
833
|
+
let htmlContent;
|
|
834
|
+
if (options.htmlFile) {
|
|
835
|
+
if (!external_fs_namespaceObject.existsSync(options.htmlFile)) {
|
|
836
|
+
output_error(`HTML file not found: ${options.htmlFile}`);
|
|
837
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
838
|
+
}
|
|
839
|
+
htmlContent = external_fs_namespaceObject.readFileSync(options.htmlFile, 'utf-8');
|
|
840
|
+
} else if (options.html) htmlContent = options.html;
|
|
841
|
+
startSpinner('Creating project...');
|
|
842
|
+
const project = await createProject({
|
|
843
|
+
title: options.title
|
|
844
|
+
});
|
|
845
|
+
let draftResult = null;
|
|
846
|
+
if (htmlContent) draftResult = await addDraft(project.projectId, {
|
|
847
|
+
title: 'Initial Draft',
|
|
848
|
+
html: htmlContent,
|
|
849
|
+
deviceMode: options.device
|
|
850
|
+
});
|
|
851
|
+
succeedSpinner('Project created successfully!');
|
|
852
|
+
const result = {
|
|
853
|
+
projectId: project.projectId,
|
|
854
|
+
title: project.title,
|
|
855
|
+
projectUrl: project.projectUrl,
|
|
856
|
+
shareToken: project.shareToken,
|
|
857
|
+
...draftResult && {
|
|
858
|
+
draft: {
|
|
859
|
+
draftId: draftResult.draftId,
|
|
860
|
+
nodeId: draftResult.nodeId,
|
|
861
|
+
nodeUrl: draftResult.nodeUrl,
|
|
862
|
+
previewUrl: draftResult.previewUrl
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
};
|
|
866
|
+
if (isJsonMode()) output(result);
|
|
867
|
+
else {
|
|
868
|
+
success(`Project "${project.title}" created!`);
|
|
869
|
+
info(`\nProject ID: ${project.projectId}`);
|
|
870
|
+
info(`Project URL: ${project.projectUrl}`);
|
|
871
|
+
if (draftResult) {
|
|
872
|
+
info(`\nDraft ID: ${draftResult.draftId}`);
|
|
873
|
+
info(`Draft URL: ${draftResult.nodeUrl}`);
|
|
874
|
+
info(`Preview URL: ${draftResult.previewUrl}`);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
} catch (err) {
|
|
878
|
+
failSpinner('Failed to create project');
|
|
879
|
+
if (err instanceof ApiClientError) {
|
|
880
|
+
output_error(`API Error: ${err.message}`);
|
|
881
|
+
process.exit(EXIT_CODES.API_ERROR);
|
|
882
|
+
}
|
|
883
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
884
|
+
output_error(message);
|
|
885
|
+
process.exit(EXIT_CODES.GENERAL_ERROR);
|
|
886
|
+
}
|
|
887
|
+
});
|
|
888
|
+
return command;
|
|
889
|
+
}
|
|
890
|
+
async function createDraft(projectId, data) {
|
|
891
|
+
const client = getApiClient();
|
|
892
|
+
const response = await client.post(`/external/projects/${projectId}/drafts/create`, data);
|
|
893
|
+
return response.data;
|
|
894
|
+
}
|
|
895
|
+
async function iterateDraft(draftId, data) {
|
|
896
|
+
const client = getApiClient();
|
|
897
|
+
const response = await client.post(`/external/drafts/${draftId}/iterate`, data);
|
|
898
|
+
return response.data;
|
|
899
|
+
}
|
|
900
|
+
async function planFlowPages(draftId, data) {
|
|
901
|
+
const client = getApiClient();
|
|
902
|
+
const response = await client.post(`/external/drafts/${draftId}/flow/plan`, data);
|
|
903
|
+
return response.data;
|
|
904
|
+
}
|
|
905
|
+
async function executeFlowPages(draftId, data) {
|
|
906
|
+
const client = getApiClient();
|
|
907
|
+
const response = await client.post(`/external/drafts/${draftId}/flow/execute`, data);
|
|
908
|
+
return response.data;
|
|
909
|
+
}
|
|
910
|
+
async function getJobStatus(jobId) {
|
|
911
|
+
const client = getApiClient();
|
|
912
|
+
const response = await client.get(`/external/jobs/${jobId}`);
|
|
913
|
+
return response.data;
|
|
914
|
+
}
|
|
915
|
+
function isJobDone(response) {
|
|
916
|
+
return 'completed' === response.status || 'failed' === response.status;
|
|
917
|
+
}
|
|
918
|
+
function isJobCompleted(response) {
|
|
919
|
+
return 'completed' === response.status;
|
|
920
|
+
}
|
|
921
|
+
function isJobFailed(response) {
|
|
922
|
+
return 'failed' === response.status;
|
|
923
|
+
}
|
|
924
|
+
async function runJob(config) {
|
|
925
|
+
const { startLabel, pollingLabel, successLabel, timeoutLabel, failureLabel, timeoutMs = 300000, startJob, transformResult, displayResult } = config;
|
|
926
|
+
try {
|
|
927
|
+
startSpinner(startLabel);
|
|
928
|
+
const job = await startJob();
|
|
929
|
+
updateSpinner(pollingLabel);
|
|
930
|
+
const pollResult = await poll(()=>getJobStatus(job.jobId), isJobDone, {
|
|
931
|
+
intervalMs: 2000,
|
|
932
|
+
timeoutMs,
|
|
933
|
+
onPoll: (attempt)=>{
|
|
934
|
+
if (attempt % 5 === 0) updateSpinner(`${pollingLabel} (${Math.floor(2000 * attempt / 1000)}s)`);
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
if (pollResult.timedOut) {
|
|
938
|
+
failSpinner(timeoutLabel);
|
|
939
|
+
output_error('Job timed out. The operation may still be processing in the background.');
|
|
940
|
+
if (isJsonMode()) output({
|
|
941
|
+
error: 'timeout',
|
|
942
|
+
jobId: job.jobId
|
|
943
|
+
});
|
|
944
|
+
process.exit(EXIT_CODES.TIMEOUT);
|
|
945
|
+
}
|
|
946
|
+
if (!pollResult.success || !pollResult.data) {
|
|
947
|
+
failSpinner(failureLabel);
|
|
948
|
+
output_error(pollResult.error || 'Failed to get job status');
|
|
949
|
+
process.exit(EXIT_CODES.API_ERROR);
|
|
950
|
+
}
|
|
951
|
+
const jobResult = pollResult.data;
|
|
952
|
+
if (isJobFailed(jobResult)) {
|
|
953
|
+
failSpinner(failureLabel);
|
|
954
|
+
output_error(`${jobResult.error.code}: ${jobResult.error.message}`);
|
|
955
|
+
process.exit(EXIT_CODES.API_ERROR);
|
|
956
|
+
}
|
|
957
|
+
if (!isJobCompleted(jobResult)) {
|
|
958
|
+
failSpinner('Unexpected job status');
|
|
959
|
+
output_error('Job ended in unexpected state');
|
|
960
|
+
process.exit(EXIT_CODES.API_ERROR);
|
|
961
|
+
}
|
|
962
|
+
succeedSpinner(successLabel);
|
|
963
|
+
if (isJsonMode()) output(transformResult(jobResult));
|
|
964
|
+
else displayResult(jobResult);
|
|
965
|
+
process.exit(EXIT_CODES.SUCCESS);
|
|
966
|
+
} catch (err) {
|
|
967
|
+
failSpinner(failureLabel);
|
|
968
|
+
if (err instanceof ApiClientError) {
|
|
969
|
+
output_error(`API Error: ${err.message}`);
|
|
970
|
+
process.exit(EXIT_CODES.API_ERROR);
|
|
971
|
+
}
|
|
972
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
973
|
+
output_error(message);
|
|
974
|
+
process.exit(EXIT_CODES.GENERAL_ERROR);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
function job_runner_requireAuth(isAuthenticated) {
|
|
978
|
+
if (!isAuthenticated()) {
|
|
979
|
+
output_error('Not authenticated. Run `superdesign login` first.');
|
|
980
|
+
process.exit(EXIT_CODES.AUTH_REQUIRED);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
function createCreateDesignDraftCommand() {
|
|
984
|
+
const command = new external_commander_namespaceObject.Command('create-design-draft').description('Create a design draft using AI generation').requiredOption('--project-id <id>', 'Project ID').requiredOption('--title <title>', 'Draft title').requiredOption('--prompt <prompt>', 'Design prompt for AI generation').option('--device <mode>', 'Device mode (mobile, tablet, desktop)', 'desktop').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
985
|
+
if (options.json) setJsonMode(true);
|
|
986
|
+
job_runner_requireAuth(manager_isAuthenticated);
|
|
987
|
+
if (options.device && ![
|
|
988
|
+
'mobile',
|
|
989
|
+
'tablet',
|
|
990
|
+
'desktop'
|
|
991
|
+
].includes(options.device)) {
|
|
992
|
+
output_error('Invalid device mode. Must be: mobile, tablet, or desktop');
|
|
993
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
994
|
+
}
|
|
995
|
+
await runJob({
|
|
996
|
+
startLabel: 'Creating design draft...',
|
|
997
|
+
pollingLabel: 'Generating design with AI...',
|
|
998
|
+
successLabel: 'Design draft created!',
|
|
999
|
+
timeoutLabel: 'Generation timed out',
|
|
1000
|
+
failureLabel: 'Failed to create draft',
|
|
1001
|
+
startJob: ()=>createDraft(options.projectId, {
|
|
1002
|
+
title: options.title,
|
|
1003
|
+
prompt: options.prompt,
|
|
1004
|
+
deviceMode: options.device
|
|
1005
|
+
}),
|
|
1006
|
+
transformResult: (job)=>({
|
|
1007
|
+
draftId: job.result.draftId,
|
|
1008
|
+
nodeId: job.result.nodeId,
|
|
1009
|
+
title: job.result.title,
|
|
1010
|
+
projectUrl: job.result.projectUrl,
|
|
1011
|
+
nodeUrl: job.result.nodeUrl,
|
|
1012
|
+
previewUrl: job.result.previewUrl,
|
|
1013
|
+
creditsConsumed: job.creditsConsumed
|
|
1014
|
+
}),
|
|
1015
|
+
displayResult: (job)=>{
|
|
1016
|
+
success(`Draft "${job.result.title}" created!`);
|
|
1017
|
+
info(`\nDraft ID: ${job.result.draftId}`);
|
|
1018
|
+
info(`Node URL: ${job.result.nodeUrl}`);
|
|
1019
|
+
info(`Preview URL: ${job.result.previewUrl}`);
|
|
1020
|
+
info(`Credits consumed: ${job.creditsConsumed}`);
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
});
|
|
1024
|
+
return command;
|
|
1025
|
+
}
|
|
1026
|
+
function createIterateDesignDraftCommand() {
|
|
1027
|
+
const command = new external_commander_namespaceObject.Command('iterate-design-draft').description('Iterate on an existing draft using AI').requiredOption('--draft-id <id>', 'Draft ID to iterate on').requiredOption('--prompt <prompt>', 'Iteration prompt').requiredOption('--mode <mode>', 'Iteration mode (replace or branch)').option('--count <count>', 'Number of variations to generate (1-4)', '1').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
1028
|
+
if (options.json) setJsonMode(true);
|
|
1029
|
+
job_runner_requireAuth(manager_isAuthenticated);
|
|
1030
|
+
if (![
|
|
1031
|
+
'replace',
|
|
1032
|
+
'branch'
|
|
1033
|
+
].includes(options.mode)) {
|
|
1034
|
+
output_error('Invalid mode. Must be: replace or branch');
|
|
1035
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
1036
|
+
}
|
|
1037
|
+
const count = parseInt(options.count || '1', 10);
|
|
1038
|
+
if (isNaN(count) || count < 1 || count > 4) {
|
|
1039
|
+
output_error('Invalid count. Must be between 1 and 4');
|
|
1040
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
1041
|
+
}
|
|
1042
|
+
await runJob({
|
|
1043
|
+
startLabel: 'Starting iteration...',
|
|
1044
|
+
pollingLabel: 'Iterating design with AI...',
|
|
1045
|
+
successLabel: 'Iteration complete!',
|
|
1046
|
+
timeoutLabel: 'Iteration timed out',
|
|
1047
|
+
failureLabel: 'Failed to iterate draft',
|
|
1048
|
+
startJob: ()=>iterateDraft(options.draftId, {
|
|
1049
|
+
prompt: options.prompt,
|
|
1050
|
+
mode: options.mode,
|
|
1051
|
+
count: count
|
|
1052
|
+
}),
|
|
1053
|
+
transformResult: (job)=>({
|
|
1054
|
+
drafts: job.result.drafts,
|
|
1055
|
+
projectUrl: job.result.projectUrl,
|
|
1056
|
+
creditsConsumed: job.creditsConsumed
|
|
1057
|
+
}),
|
|
1058
|
+
displayResult: (job)=>{
|
|
1059
|
+
success(`Created ${job.result.drafts.length} draft variation(s)!`);
|
|
1060
|
+
info(`\nProject URL: ${job.result.projectUrl}`);
|
|
1061
|
+
info(`Credits consumed: ${job.creditsConsumed}`);
|
|
1062
|
+
info('\nDrafts:');
|
|
1063
|
+
job.result.drafts.forEach((draft, i)=>{
|
|
1064
|
+
info(` ${i + 1}. ${draft.title}`);
|
|
1065
|
+
info(` Draft ID: ${draft.draftId}`);
|
|
1066
|
+
info(` Preview: ${draft.previewUrl}`);
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
return command;
|
|
1072
|
+
}
|
|
1073
|
+
function createPlanFlowPagesCommand() {
|
|
1074
|
+
const command = new external_commander_namespaceObject.Command('plan-flow-pages').description('Plan flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--source-node-id <id>', 'Source node ID in the flow').option('--context <context>', 'Additional context for flow planning').option('--json', 'Output in JSON format').action(async (options)=>{
|
|
1075
|
+
if (options.json) setJsonMode(true);
|
|
1076
|
+
job_runner_requireAuth(manager_isAuthenticated);
|
|
1077
|
+
await runJob({
|
|
1078
|
+
startLabel: 'Planning flow pages...',
|
|
1079
|
+
pollingLabel: 'AI is analyzing and planning pages...',
|
|
1080
|
+
successLabel: 'Flow pages planned!',
|
|
1081
|
+
timeoutLabel: 'Planning timed out',
|
|
1082
|
+
failureLabel: 'Failed to plan flow pages',
|
|
1083
|
+
startJob: ()=>planFlowPages(options.draftId, {
|
|
1084
|
+
sourceNodeId: options.sourceNodeId,
|
|
1085
|
+
flowContext: options.context
|
|
1086
|
+
}),
|
|
1087
|
+
transformResult: (job)=>({
|
|
1088
|
+
pages: job.result.pages,
|
|
1089
|
+
creditsConsumed: job.creditsConsumed
|
|
1090
|
+
}),
|
|
1091
|
+
displayResult: (job)=>{
|
|
1092
|
+
success(`Planned ${job.result.pages.length} flow page(s)!`);
|
|
1093
|
+
info(`Credits consumed: ${job.creditsConsumed}`);
|
|
1094
|
+
info('\nSuggested pages:');
|
|
1095
|
+
job.result.pages.forEach((page, i)=>{
|
|
1096
|
+
info(`\n ${i + 1}. ${page.title}`);
|
|
1097
|
+
const promptPreview = page.prompt.length > 100 ? `${page.prompt.substring(0, 100)}...` : page.prompt;
|
|
1098
|
+
info(` Prompt: ${promptPreview}`);
|
|
1099
|
+
});
|
|
1100
|
+
info('\nUse `superdesign execute-flow-pages` to generate these pages.');
|
|
1101
|
+
}
|
|
1102
|
+
});
|
|
1103
|
+
});
|
|
1104
|
+
return command;
|
|
1105
|
+
}
|
|
1106
|
+
function parsePages(pagesJson) {
|
|
1107
|
+
const parsed = JSON.parse(pagesJson);
|
|
1108
|
+
if (!Array.isArray(parsed)) throw new Error('Pages must be an array');
|
|
1109
|
+
for (const page of parsed){
|
|
1110
|
+
if (!page.title || 'string' != typeof page.title) throw new Error('Each page must have a title string');
|
|
1111
|
+
if (!page.prompt || 'string' != typeof page.prompt) throw new Error('Each page must have a prompt string');
|
|
1112
|
+
}
|
|
1113
|
+
return parsed;
|
|
1114
|
+
}
|
|
1115
|
+
function createExecuteFlowPagesCommand() {
|
|
1116
|
+
const command = new external_commander_namespaceObject.Command('execute-flow-pages').description('Generate flow pages using AI').requiredOption('--draft-id <id>', 'Source draft ID').requiredOption('--source-node-id <id>', 'Source node ID in the flow').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)=>{
|
|
1117
|
+
if (options.json) setJsonMode(true);
|
|
1118
|
+
job_runner_requireAuth(manager_isAuthenticated);
|
|
1119
|
+
let pages;
|
|
1120
|
+
try {
|
|
1121
|
+
pages = parsePages(options.pages);
|
|
1122
|
+
} catch (parseErr) {
|
|
1123
|
+
const msg = parseErr instanceof Error ? parseErr.message : 'Invalid JSON';
|
|
1124
|
+
output_error(`Invalid pages JSON: ${msg}`);
|
|
1125
|
+
output_error('Expected format: [{"title": "Page 1", "prompt": "Create a..."}]');
|
|
1126
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
1127
|
+
}
|
|
1128
|
+
if (0 === pages.length) {
|
|
1129
|
+
output_error('At least one page is required');
|
|
1130
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
1131
|
+
}
|
|
1132
|
+
if (pages.length > 10) {
|
|
1133
|
+
output_error('Maximum 10 pages allowed');
|
|
1134
|
+
process.exit(EXIT_CODES.VALIDATION_ERROR);
|
|
1135
|
+
}
|
|
1136
|
+
const timeoutMs = Math.max(300000, 2 * pages.length * 60000);
|
|
1137
|
+
await runJob({
|
|
1138
|
+
startLabel: `Generating ${pages.length} flow page(s)...`,
|
|
1139
|
+
pollingLabel: `AI is generating ${pages.length} page(s)...`,
|
|
1140
|
+
successLabel: 'Flow pages generated!',
|
|
1141
|
+
timeoutLabel: 'Generation timed out',
|
|
1142
|
+
failureLabel: 'Failed to execute flow pages',
|
|
1143
|
+
timeoutMs,
|
|
1144
|
+
startJob: ()=>executeFlowPages(options.draftId, {
|
|
1145
|
+
sourceNodeId: options.sourceNodeId,
|
|
1146
|
+
flowContext: options.context,
|
|
1147
|
+
pages
|
|
1148
|
+
}),
|
|
1149
|
+
transformResult: (job)=>({
|
|
1150
|
+
drafts: job.result.drafts,
|
|
1151
|
+
projectUrl: job.result.projectUrl,
|
|
1152
|
+
creditsConsumed: job.creditsConsumed
|
|
1153
|
+
}),
|
|
1154
|
+
displayResult: (job)=>{
|
|
1155
|
+
success(`Generated ${job.result.drafts.length} flow page(s)!`);
|
|
1156
|
+
info(`\nProject URL: ${job.result.projectUrl}`);
|
|
1157
|
+
info(`Credits consumed: ${job.creditsConsumed}`);
|
|
1158
|
+
info('\nGenerated pages:');
|
|
1159
|
+
job.result.drafts.forEach((draft)=>{
|
|
1160
|
+
info(`\n ${draft.index + 1}. ${draft.title}`);
|
|
1161
|
+
info(` Draft ID: ${draft.draftId}`);
|
|
1162
|
+
info(` Node URL: ${draft.nodeUrl}`);
|
|
1163
|
+
info(` Preview: ${draft.previewUrl}`);
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
});
|
|
1168
|
+
return command;
|
|
1169
|
+
}
|
|
1170
|
+
const src_filename = (0, external_url_namespaceObject.fileURLToPath)(__rslib_import_meta_url__);
|
|
1171
|
+
const src_dirname = (0, external_path_namespaceObject.dirname)(src_filename);
|
|
1172
|
+
(0, external_dotenv_namespaceObject.config)({
|
|
1173
|
+
path: (0, external_path_namespaceObject.resolve)(src_dirname, '../.env')
|
|
1174
|
+
});
|
|
1175
|
+
(0, external_dotenv_namespaceObject.config)();
|
|
1176
|
+
function createProgram() {
|
|
1177
|
+
const program = new external_commander_namespaceObject.Command();
|
|
1178
|
+
program.name('superdesign').description('SuperDesign CLI - AI product designer for coding agents').version("0.1.0");
|
|
1179
|
+
program.addCommand(createLoginCommand());
|
|
1180
|
+
program.addCommand(createLogoutCommand());
|
|
1181
|
+
program.addCommand(createInitCommand());
|
|
1182
|
+
program.addCommand(createCreateProjectCommand());
|
|
1183
|
+
program.addCommand(createCreateDesignDraftCommand());
|
|
1184
|
+
program.addCommand(createIterateDesignDraftCommand());
|
|
1185
|
+
program.addCommand(createPlanFlowPagesCommand());
|
|
1186
|
+
program.addCommand(createExecuteFlowPagesCommand());
|
|
1187
|
+
return program;
|
|
1188
|
+
}
|
|
1189
|
+
async function run() {
|
|
1190
|
+
const program = createProgram();
|
|
1191
|
+
await program.parseAsync(process.argv);
|
|
1192
|
+
}
|
|
1193
|
+
})();
|
|
1194
|
+
exports.ApiClientError = __webpack_exports__.ApiClientError;
|
|
1195
|
+
exports.addDraft = __webpack_exports__.addDraft;
|
|
1196
|
+
exports.claimSession = __webpack_exports__.claimSession;
|
|
1197
|
+
exports.clearConfig = __webpack_exports__.clearConfig;
|
|
1198
|
+
exports.createApiClient = __webpack_exports__.createApiClient;
|
|
1199
|
+
exports.createDraft = __webpack_exports__.createDraft;
|
|
1200
|
+
exports.createProgram = __webpack_exports__.createProgram;
|
|
1201
|
+
exports.createProject = __webpack_exports__.createProject;
|
|
1202
|
+
exports.createPublicApiClient = __webpack_exports__.createPublicApiClient;
|
|
1203
|
+
exports.createSession = __webpack_exports__.createSession;
|
|
1204
|
+
exports.executeFlowPages = __webpack_exports__.executeFlowPages;
|
|
1205
|
+
exports.getApiClient = __webpack_exports__.getApiClient;
|
|
1206
|
+
exports.getApiKey = __webpack_exports__.getApiKey;
|
|
1207
|
+
exports.getApiUrl = __webpack_exports__.getApiUrl;
|
|
1208
|
+
exports.getConfigDir = __webpack_exports__.getConfigDir;
|
|
1209
|
+
exports.getConfigPath = __webpack_exports__.getConfigPath;
|
|
1210
|
+
exports.getJobStatus = __webpack_exports__.getJobStatus;
|
|
1211
|
+
exports.isAuthenticated = __webpack_exports__.isAuthenticated;
|
|
1212
|
+
exports.isJobCompleted = __webpack_exports__.isJobCompleted;
|
|
1213
|
+
exports.isJobDone = __webpack_exports__.isJobDone;
|
|
1214
|
+
exports.isJobFailed = __webpack_exports__.isJobFailed;
|
|
1215
|
+
exports.iterateDraft = __webpack_exports__.iterateDraft;
|
|
1216
|
+
exports.loadConfig = __webpack_exports__.loadConfig;
|
|
1217
|
+
exports.planFlowPages = __webpack_exports__.planFlowPages;
|
|
1218
|
+
exports.pollSession = __webpack_exports__.pollSession;
|
|
1219
|
+
exports.run = __webpack_exports__.run;
|
|
1220
|
+
exports.saveConfig = __webpack_exports__.saveConfig;
|
|
1221
|
+
exports.updateConfig = __webpack_exports__.updateConfig;
|
|
1222
|
+
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
1223
|
+
"ApiClientError",
|
|
1224
|
+
"addDraft",
|
|
1225
|
+
"claimSession",
|
|
1226
|
+
"clearConfig",
|
|
1227
|
+
"createApiClient",
|
|
1228
|
+
"createDraft",
|
|
1229
|
+
"createProgram",
|
|
1230
|
+
"createProject",
|
|
1231
|
+
"createPublicApiClient",
|
|
1232
|
+
"createSession",
|
|
1233
|
+
"executeFlowPages",
|
|
1234
|
+
"getApiClient",
|
|
1235
|
+
"getApiKey",
|
|
1236
|
+
"getApiUrl",
|
|
1237
|
+
"getConfigDir",
|
|
1238
|
+
"getConfigPath",
|
|
1239
|
+
"getJobStatus",
|
|
1240
|
+
"isAuthenticated",
|
|
1241
|
+
"isJobCompleted",
|
|
1242
|
+
"isJobDone",
|
|
1243
|
+
"isJobFailed",
|
|
1244
|
+
"iterateDraft",
|
|
1245
|
+
"loadConfig",
|
|
1246
|
+
"planFlowPages",
|
|
1247
|
+
"pollSession",
|
|
1248
|
+
"run",
|
|
1249
|
+
"saveConfig",
|
|
1250
|
+
"updateConfig"
|
|
1251
|
+
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
1252
|
+
Object.defineProperty(exports, '__esModule', {
|
|
1253
|
+
value: true
|
|
1254
|
+
});
|