@reshotdev/screenshot 0.0.1-beta.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/LICENSE +190 -0
- package/README.md +388 -0
- package/package.json +64 -0
- package/src/commands/auth.js +259 -0
- package/src/commands/chrome.js +140 -0
- package/src/commands/ci-run.js +123 -0
- package/src/commands/ci-setup.js +288 -0
- package/src/commands/drifts.js +423 -0
- package/src/commands/import-tests.js +309 -0
- package/src/commands/ingest.js +458 -0
- package/src/commands/init.js +633 -0
- package/src/commands/publish.js +1721 -0
- package/src/commands/pull.js +303 -0
- package/src/commands/record.js +94 -0
- package/src/commands/run.js +476 -0
- package/src/commands/setup-wizard.js +740 -0
- package/src/commands/setup.js +137 -0
- package/src/commands/status.js +275 -0
- package/src/commands/sync.js +621 -0
- package/src/commands/ui.js +248 -0
- package/src/commands/validate-docs.js +529 -0
- package/src/index.js +462 -0
- package/src/lib/api-client.js +815 -0
- package/src/lib/capture-engine.js +1623 -0
- package/src/lib/capture-script-runner.js +3120 -0
- package/src/lib/ci-detect.js +137 -0
- package/src/lib/config.js +1240 -0
- package/src/lib/diff-engine.js +642 -0
- package/src/lib/hash.js +74 -0
- package/src/lib/image-crop.js +396 -0
- package/src/lib/matrix.js +89 -0
- package/src/lib/output-path-template.js +318 -0
- package/src/lib/playwright-runner.js +252 -0
- package/src/lib/polished-clip.js +553 -0
- package/src/lib/privacy-engine.js +408 -0
- package/src/lib/progress-tracker.js +142 -0
- package/src/lib/record-browser-injection.js +654 -0
- package/src/lib/record-cdp.js +612 -0
- package/src/lib/record-clip.js +343 -0
- package/src/lib/record-config.js +623 -0
- package/src/lib/record-screenshot.js +360 -0
- package/src/lib/record-terminal.js +123 -0
- package/src/lib/recorder-service.js +781 -0
- package/src/lib/secrets.js +51 -0
- package/src/lib/selector-strategies.js +859 -0
- package/src/lib/standalone-mode.js +400 -0
- package/src/lib/storage-providers.js +569 -0
- package/src/lib/style-engine.js +684 -0
- package/src/lib/ui-api.js +4677 -0
- package/src/lib/ui-assets.js +373 -0
- package/src/lib/ui-executor.js +587 -0
- package/src/lib/variant-injector.js +591 -0
- package/src/lib/viewport-presets.js +454 -0
- package/src/lib/worker-pool.js +118 -0
- package/web/cropper/index.html +436 -0
- package/web/manager/dist/assets/index--ZgioErz.js +507 -0
- package/web/manager/dist/assets/index-n468W0Wr.css +1 -0
- package/web/manager/dist/index.html +27 -0
- package/web/subtitle-editor/index.html +295 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// index.js - Reshot CLI entry point
|
|
4
|
+
// Consolidated command structure for ease of use while maintaining power features
|
|
5
|
+
|
|
6
|
+
require("dotenv").config({
|
|
7
|
+
path: require("path").join(__dirname, "..", ".env"),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const { Command } = require("commander");
|
|
11
|
+
const chalk = require("chalk");
|
|
12
|
+
const pkg = require("../package.json");
|
|
13
|
+
|
|
14
|
+
const program = new Command();
|
|
15
|
+
|
|
16
|
+
program
|
|
17
|
+
.name("reshot")
|
|
18
|
+
.description("Visual documentation that stays in sync")
|
|
19
|
+
.version(pkg.version);
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// CORE COMMANDS (Primary workflow)
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
// Setup: Interactive wizard for initial configuration
|
|
26
|
+
program
|
|
27
|
+
.command("setup")
|
|
28
|
+
.description("Interactive setup wizard (auth, config, features)")
|
|
29
|
+
.option("--offline", "Skip authentication (local-only mode)")
|
|
30
|
+
.option("--force", "Force re-initialization even if already set up")
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
try {
|
|
33
|
+
const setupWizard = require("./commands/setup-wizard");
|
|
34
|
+
await setupWizard(options);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error(chalk.red("Error:"), error.message);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Sync: Upload traces and documentation to platform
|
|
42
|
+
program
|
|
43
|
+
.command("sync")
|
|
44
|
+
.description("Upload Playwright traces and documentation to Reshot")
|
|
45
|
+
.option("--trace-dir <path>", "Path to test-results directory")
|
|
46
|
+
.option("--traces", "Sync traces only")
|
|
47
|
+
.option("--docs", "Sync documentation only")
|
|
48
|
+
.option("--dry-run", "Preview what would be synced")
|
|
49
|
+
.option("-v, --verbose", "Show detailed output")
|
|
50
|
+
.action(async (options) => {
|
|
51
|
+
try {
|
|
52
|
+
const syncCommand = require("./commands/sync");
|
|
53
|
+
await syncCommand({
|
|
54
|
+
traceDir: options.traceDir,
|
|
55
|
+
traces: options.traces,
|
|
56
|
+
docs: options.docs,
|
|
57
|
+
dryRun: options.dryRun,
|
|
58
|
+
verbose: options.verbose,
|
|
59
|
+
});
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error(chalk.red("Error:"), error.message);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Status: View project status, sync jobs, and drift summary
|
|
67
|
+
program
|
|
68
|
+
.command("status")
|
|
69
|
+
.description("View project status, sync history, and drift summary")
|
|
70
|
+
.option("--jobs", "Show only sync job history")
|
|
71
|
+
.option("--drifts", "Show only drift queue")
|
|
72
|
+
.option("--config", "Show only configuration")
|
|
73
|
+
.option("--limit <n>", "Limit number of items shown", parseInt)
|
|
74
|
+
.option("--json", "Output as JSON")
|
|
75
|
+
.action(async (options) => {
|
|
76
|
+
try {
|
|
77
|
+
const statusCommand = require("./commands/status");
|
|
78
|
+
await statusCommand(options);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(chalk.red("Error:"), error.message);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Studio: Launch visual management UI
|
|
86
|
+
program
|
|
87
|
+
.command("studio")
|
|
88
|
+
.description("Launch Reshot Studio (visual management UI)")
|
|
89
|
+
.option("--port <port>", "Port for web UI", "4300")
|
|
90
|
+
.option("--host <host>", "Host for web UI", "127.0.0.1")
|
|
91
|
+
.option("--no-open", "Do not automatically open browser")
|
|
92
|
+
.action(async (options) => {
|
|
93
|
+
try {
|
|
94
|
+
const uiCommand = require("./commands/ui");
|
|
95
|
+
await uiCommand(options);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error(chalk.red("Error:"), error.message);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Validate: Check configuration and documentation bindings
|
|
103
|
+
program
|
|
104
|
+
.command("validate")
|
|
105
|
+
.description("Validate configuration and documentation bindings")
|
|
106
|
+
.option("--strict", "Fail on warnings (zombie links, unbound files)")
|
|
107
|
+
.option("--fix", "Attempt to auto-fix issues where possible")
|
|
108
|
+
.option("-v, --verbose", "Show detailed validation output")
|
|
109
|
+
.action(async (options) => {
|
|
110
|
+
try {
|
|
111
|
+
const validateCommand = require("./commands/validate-docs");
|
|
112
|
+
if (typeof validateCommand.validateDocSync === "function") {
|
|
113
|
+
await validateCommand.validateDocSync(options);
|
|
114
|
+
} else {
|
|
115
|
+
await validateCommand.validateDocs(options);
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
console.error(chalk.red("Error:"), error.message);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ============================================================================
|
|
124
|
+
// VISUAL CAPTURE COMMANDS
|
|
125
|
+
// ============================================================================
|
|
126
|
+
|
|
127
|
+
// Run: Execute scenarios from config (automated visual capture)
|
|
128
|
+
program
|
|
129
|
+
.command("run")
|
|
130
|
+
.description("Execute visual capture scenarios from config")
|
|
131
|
+
.option("-s, --scenarios <keys>", "Comma-separated list of scenario keys")
|
|
132
|
+
.option("--no-headless", "Run browser in visible mode")
|
|
133
|
+
.option("--variant <json>", "Override variant configuration as JSON")
|
|
134
|
+
.option("--all-variants", "Run all configured variant combinations")
|
|
135
|
+
.option("--no-variants", "Skip variant expansion")
|
|
136
|
+
.option(
|
|
137
|
+
"-f, --format <format>",
|
|
138
|
+
"Output format: step-by-step-images | summary-video",
|
|
139
|
+
)
|
|
140
|
+
.option(
|
|
141
|
+
"-c, --concurrency <n>",
|
|
142
|
+
"Number of parallel browser workers",
|
|
143
|
+
parseInt,
|
|
144
|
+
)
|
|
145
|
+
.option("--diff", "Enable baseline comparison")
|
|
146
|
+
.option("--no-diff", "Disable baseline comparison")
|
|
147
|
+
.option("--no-privacy", "Disable privacy masking")
|
|
148
|
+
.option("--no-style", "Disable style processing")
|
|
149
|
+
.option("--cloud", "Compare against cloud baselines")
|
|
150
|
+
.option("--debug", "Enable verbose debug logging")
|
|
151
|
+
.action(async (options) => {
|
|
152
|
+
if (options.debug) {
|
|
153
|
+
process.env.RESHOT_DEBUG = "1";
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const runCommand = require("./commands/run");
|
|
157
|
+
const scenarioKeys = options.scenarios
|
|
158
|
+
? options.scenarios.split(",").map((s) => s.trim())
|
|
159
|
+
: null;
|
|
160
|
+
await runCommand({
|
|
161
|
+
scenarioKeys,
|
|
162
|
+
headless: options.headless,
|
|
163
|
+
variant: options.variant,
|
|
164
|
+
allVariants: options.allVariants,
|
|
165
|
+
noVariants: options.variants === false,
|
|
166
|
+
noPrivacy: options.privacy === false,
|
|
167
|
+
noStyle: options.style === false,
|
|
168
|
+
format: options.format,
|
|
169
|
+
diff: options.diff,
|
|
170
|
+
cloud: options.cloud,
|
|
171
|
+
concurrency: options.concurrency,
|
|
172
|
+
});
|
|
173
|
+
} catch (error) {
|
|
174
|
+
console.error(chalk.red("Error:"), error.message);
|
|
175
|
+
if (options.debug && error.stack) {
|
|
176
|
+
console.error(chalk.gray(error.stack));
|
|
177
|
+
}
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// Record: Interactive visual recording from live browser
|
|
183
|
+
program
|
|
184
|
+
.command("record [title]")
|
|
185
|
+
.description("Interactively record visuals from a live browser session")
|
|
186
|
+
.option("--browser", "Launch Chrome with remote debugging before recording")
|
|
187
|
+
.option("-p, --port <port>", "Chrome debugging port (default: 9222)")
|
|
188
|
+
.option("--url <url>", "URL to open when launching browser")
|
|
189
|
+
.option("--debug", "Enable verbose debug logging")
|
|
190
|
+
.action(async (title, options) => {
|
|
191
|
+
if (options.debug) {
|
|
192
|
+
process.env.RESHOT_DEBUG = "1";
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
// If --browser flag, launch Chrome first
|
|
196
|
+
if (options.browser) {
|
|
197
|
+
const chromeCommand = require("./commands/chrome");
|
|
198
|
+
await chromeCommand({
|
|
199
|
+
port: options.port || "9222",
|
|
200
|
+
url: options.url || "about:blank",
|
|
201
|
+
});
|
|
202
|
+
// Give Chrome time to start
|
|
203
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const recordCommand = require("./commands/record");
|
|
207
|
+
await recordCommand(title);
|
|
208
|
+
} catch (error) {
|
|
209
|
+
console.error(chalk.red("Error:"), error.message);
|
|
210
|
+
if (options.debug && error.stack) {
|
|
211
|
+
console.error(chalk.gray(error.stack));
|
|
212
|
+
}
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// Import tests: Import existing Playwright tests into Reshot
|
|
218
|
+
program
|
|
219
|
+
.command("import-tests")
|
|
220
|
+
.description("Import existing Playwright tests and create journey mappings")
|
|
221
|
+
.option("--dry-run", "Preview mappings without saving")
|
|
222
|
+
.option("--no-interactive", "Run without prompts")
|
|
223
|
+
.action(async (options) => {
|
|
224
|
+
try {
|
|
225
|
+
const importTestsCommand = require("./commands/import-tests");
|
|
226
|
+
await importTestsCommand({
|
|
227
|
+
dryRun: options.dryRun,
|
|
228
|
+
interactive: options.interactive,
|
|
229
|
+
});
|
|
230
|
+
} catch (error) {
|
|
231
|
+
console.error(chalk.red("Error:"), error.message);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// PUBLISHING & INTEGRATION COMMANDS
|
|
238
|
+
// ============================================================================
|
|
239
|
+
|
|
240
|
+
// Publish: Upload generated assets to platform with versioning
|
|
241
|
+
program
|
|
242
|
+
.command("publish")
|
|
243
|
+
.description("Publish visual assets to Reshot platform")
|
|
244
|
+
.option("--tag <tag>", "Version tag (e.g., v1.2, release-2024-01)")
|
|
245
|
+
.option("-m, --message <message>", "Commit message for this publish")
|
|
246
|
+
.option("--video <path>", "Explicit video file to upload with this publish")
|
|
247
|
+
.option("--dry-run", "Preview without uploading")
|
|
248
|
+
.option("-f, --force", "Skip confirmation prompts")
|
|
249
|
+
.option("--output-json", "Write structured result to .reshot/output/publish-result.json")
|
|
250
|
+
.action(async (options) => {
|
|
251
|
+
try {
|
|
252
|
+
const publishCommand = require("./commands/publish");
|
|
253
|
+
await publishCommand({
|
|
254
|
+
...options,
|
|
255
|
+
outputJson: options.outputJson,
|
|
256
|
+
});
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error(chalk.red("Error:"), error.message);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Pull: Generate asset map for build pipelines
|
|
264
|
+
program
|
|
265
|
+
.command("pull")
|
|
266
|
+
.description("Pull asset map for your build pipeline")
|
|
267
|
+
.option("-f, --format <format>", "Output format: json, ts, csv", "json")
|
|
268
|
+
.option("-o, --output <path>", "Output file path")
|
|
269
|
+
.option("--full", "Include full metadata in TypeScript output")
|
|
270
|
+
.option("--status <status>", "Filter: approved, pending, all", "approved")
|
|
271
|
+
.action(async (options) => {
|
|
272
|
+
try {
|
|
273
|
+
const pullCommand = require("./commands/pull");
|
|
274
|
+
await pullCommand({
|
|
275
|
+
format: options.format,
|
|
276
|
+
output: options.output,
|
|
277
|
+
full: options.full,
|
|
278
|
+
status: options.status,
|
|
279
|
+
});
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.error(chalk.red("Error:"), error.message);
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// CI: CI/CD integration commands
|
|
287
|
+
const ciCommand = program
|
|
288
|
+
.command("ci")
|
|
289
|
+
.description("CI/CD integration commands");
|
|
290
|
+
|
|
291
|
+
ciCommand
|
|
292
|
+
.command("setup")
|
|
293
|
+
.description("Interactive CI/CD setup wizard (GitHub Actions, etc.)")
|
|
294
|
+
.action(async () => {
|
|
295
|
+
try {
|
|
296
|
+
const ciSetup = require("./commands/ci-setup");
|
|
297
|
+
await ciSetup();
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.error(chalk.red("Error:"), error.message);
|
|
300
|
+
process.exit(1);
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
ciCommand
|
|
305
|
+
.command("run")
|
|
306
|
+
.description("Run capture + publish in one step (CI-optimized)")
|
|
307
|
+
.option("-c, --config <path>", "Path to docsync.config.json")
|
|
308
|
+
.option("--tag <tag>", "Version tag for publish")
|
|
309
|
+
.option("-m, --message <message>", "Commit message for publish")
|
|
310
|
+
.option("--dry-run", "Preview without uploading")
|
|
311
|
+
.option("--no-publish", "Run capture only, skip publish")
|
|
312
|
+
.action(async (options) => {
|
|
313
|
+
try {
|
|
314
|
+
const ciRun = require("./commands/ci-run");
|
|
315
|
+
await ciRun(options);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error(chalk.red("Error:"), error.message);
|
|
318
|
+
process.exit(1);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// ============================================================================
|
|
323
|
+
// DRIFT MANAGEMENT COMMANDS
|
|
324
|
+
// ============================================================================
|
|
325
|
+
|
|
326
|
+
// Drifts: View and manage documentation drifts
|
|
327
|
+
program
|
|
328
|
+
.command("drifts [action] [id]")
|
|
329
|
+
.description("View and manage documentation drifts")
|
|
330
|
+
.addHelpText(
|
|
331
|
+
"after",
|
|
332
|
+
`
|
|
333
|
+
Actions:
|
|
334
|
+
list List all drifts (default)
|
|
335
|
+
show <id> Show drift details
|
|
336
|
+
approve <id> Approve a drift
|
|
337
|
+
reject <id> Reject a drift
|
|
338
|
+
ignore <id> Mark drift as ignored
|
|
339
|
+
sync <id> Mark as manually synced (external_host)
|
|
340
|
+
approve-all Approve all pending drifts
|
|
341
|
+
reject-all Reject all pending drifts
|
|
342
|
+
validate Validate journey bindings
|
|
343
|
+
`,
|
|
344
|
+
)
|
|
345
|
+
.option("--status <status>", "Filter: PENDING, APPROVED, REJECTED, IGNORED")
|
|
346
|
+
.option("--journey <key>", "Filter by journey key")
|
|
347
|
+
.option("-v, --verbose", "Show detailed information")
|
|
348
|
+
.action(async (action, id, options) => {
|
|
349
|
+
try {
|
|
350
|
+
const driftsCommand = require("./commands/drifts");
|
|
351
|
+
// Map action/id to the expected subcommand/args format
|
|
352
|
+
const subcommand = action || "list";
|
|
353
|
+
const args = id ? [id] : [];
|
|
354
|
+
await driftsCommand(subcommand, args, options);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
console.error(chalk.red("Error:"), error.message);
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// ============================================================================
|
|
362
|
+
// UTILITY COMMANDS (Hidden from main help, but available)
|
|
363
|
+
// ============================================================================
|
|
364
|
+
|
|
365
|
+
// Auth: Standalone authentication (for re-auth scenarios)
|
|
366
|
+
program
|
|
367
|
+
.command("auth", { hidden: true })
|
|
368
|
+
.description("Authenticate with Reshot Cloud")
|
|
369
|
+
.action(async () => {
|
|
370
|
+
try {
|
|
371
|
+
const authCommand = require("./commands/auth");
|
|
372
|
+
await authCommand();
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error(chalk.red("Error:"), error.message);
|
|
375
|
+
process.exit(1);
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Init: Standalone initialization (for manual config)
|
|
380
|
+
program
|
|
381
|
+
.command("init", { hidden: true })
|
|
382
|
+
.description("Initialize Reshot configuration")
|
|
383
|
+
.action(async () => {
|
|
384
|
+
try {
|
|
385
|
+
const initCommand = require("./commands/init");
|
|
386
|
+
await initCommand();
|
|
387
|
+
} catch (error) {
|
|
388
|
+
console.error(chalk.red("Error:"), error.message);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
// Chrome: Launch Chrome with debugging (absorbed into record --browser)
|
|
394
|
+
program
|
|
395
|
+
.command("chrome", { hidden: true })
|
|
396
|
+
.description("Launch Chrome with remote debugging")
|
|
397
|
+
.option("-p, --port <port>", "Remote debugging port", "9222")
|
|
398
|
+
.option("--url <url>", "URL to open after launch", "about:blank")
|
|
399
|
+
.action(async (options) => {
|
|
400
|
+
try {
|
|
401
|
+
const chromeCommand = require("./commands/chrome");
|
|
402
|
+
await chromeCommand(options);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error(chalk.red("Error:"), error.message);
|
|
405
|
+
process.exit(1);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
// Ingest: Alias for sync (backward compatibility)
|
|
410
|
+
program
|
|
411
|
+
.command("ingest", { hidden: true })
|
|
412
|
+
.description("Upload traces and docs (alias for sync)")
|
|
413
|
+
.option("--trace-dir <path>", "Path to test-results directory")
|
|
414
|
+
.option("--dry-run", "Preview what would be synced")
|
|
415
|
+
.action(async (options) => {
|
|
416
|
+
console.log(
|
|
417
|
+
chalk.yellow("Note: 'ingest' is now 'sync'. Running sync...\n"),
|
|
418
|
+
);
|
|
419
|
+
try {
|
|
420
|
+
const syncCommand = require("./commands/sync");
|
|
421
|
+
await syncCommand({
|
|
422
|
+
traceDir: options.traceDir,
|
|
423
|
+
dryRun: options.dryRun,
|
|
424
|
+
});
|
|
425
|
+
} catch (error) {
|
|
426
|
+
console.error(chalk.red("Error:"), error.message);
|
|
427
|
+
process.exit(1);
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
// UI: Alias for studio (backward compatibility)
|
|
432
|
+
program
|
|
433
|
+
.command("ui", { hidden: true })
|
|
434
|
+
.description("Launch Reshot Studio (alias for studio)")
|
|
435
|
+
.option("--port <port>", "Port for web UI", "4300")
|
|
436
|
+
.option("--host <host>", "Host for web UI", "127.0.0.1")
|
|
437
|
+
.option("--no-open", "Do not automatically open browser")
|
|
438
|
+
.action(async (options) => {
|
|
439
|
+
try {
|
|
440
|
+
const uiCommand = require("./commands/ui");
|
|
441
|
+
await uiCommand(options);
|
|
442
|
+
} catch (error) {
|
|
443
|
+
console.error(chalk.red("Error:"), error.message);
|
|
444
|
+
process.exit(1);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
// Init-docs: Alias hidden (merged into setup wizard)
|
|
449
|
+
program
|
|
450
|
+
.command("init-docs", { hidden: true })
|
|
451
|
+
.description("Initialize documentation sync (use setup instead)")
|
|
452
|
+
.action(async () => {
|
|
453
|
+
try {
|
|
454
|
+
const initDocsCommand = require("./commands/init-docs");
|
|
455
|
+
await initDocsCommand();
|
|
456
|
+
} catch (error) {
|
|
457
|
+
console.error(chalk.red("Error:"), error.message);
|
|
458
|
+
process.exit(1);
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
program.parse(process.argv);
|