@reshotdev/screenshot 0.0.1-beta.4 → 0.0.1-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // index.js - Reshot CLI entry point
4
- // Consolidated command structure for ease of use while maintaining power features
5
4
 
6
5
  require("dotenv").config({
7
6
  path: require("path").join(__dirname, "..", ".env"),
@@ -15,7 +14,7 @@ const program = new Command();
15
14
 
16
15
  program
17
16
  .name("reshot")
18
- .description("Visual documentation that stays in sync")
17
+ .description("Visual capture, publishing, and governance for your UI")
19
18
  .version(pkg.version);
20
19
 
21
20
  // ============================================================================
@@ -25,7 +24,7 @@ program
25
24
  // Setup: Interactive wizard for initial configuration
26
25
  program
27
26
  .command("setup")
28
- .description("Interactive setup wizard (auth, config, features)")
27
+ .description("Interactive setup wizard (auth, config)")
29
28
  .option("--offline", "Skip authentication (local-only mode)")
30
29
  .option("--force", "Force re-initialization even if already set up")
31
30
  .action(async (options) => {
@@ -38,13 +37,11 @@ program
38
37
  }
39
38
  });
40
39
 
41
- // Sync: Upload traces and documentation to platform
40
+ // Sync: Upload Playwright traces to platform
42
41
  program
43
42
  .command("sync")
44
- .description("Upload Playwright traces and documentation to Reshot")
43
+ .description("Upload Playwright traces to Reshot")
45
44
  .option("--trace-dir <path>", "Path to test-results directory")
46
- .option("--traces", "Sync traces only")
47
- .option("--docs", "Sync documentation only")
48
45
  .option("--dry-run", "Preview what would be synced")
49
46
  .option("-v, --verbose", "Show detailed output")
50
47
  .action(async (options) => {
@@ -52,8 +49,6 @@ program
52
49
  const syncCommand = require("./commands/sync");
53
50
  await syncCommand({
54
51
  traceDir: options.traceDir,
55
- traces: options.traces,
56
- docs: options.docs,
57
52
  dryRun: options.dryRun,
58
53
  verbose: options.verbose,
59
54
  });
@@ -63,7 +58,7 @@ program
63
58
  }
64
59
  });
65
60
 
66
- // Status: View project status, sync jobs, and drift summary
61
+ // Status: View project status and drift summary
67
62
  program
68
63
  .command("status")
69
64
  .description("View project status, sync history, and drift summary")
@@ -99,27 +94,6 @@ program
99
94
  }
100
95
  });
101
96
 
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
97
  // ============================================================================
124
98
  // VISUAL CAPTURE COMMANDS
125
99
  // ============================================================================
@@ -247,12 +221,14 @@ program
247
221
  .option("--dry-run", "Preview without uploading")
248
222
  .option("-f, --force", "Skip confirmation prompts")
249
223
  .option("--output-json", "Write structured result to .reshot/output/publish-result.json")
224
+ .option("--auto-approve", "Automatically approve published visuals (skip review queue)")
250
225
  .action(async (options) => {
251
226
  try {
252
227
  const publishCommand = require("./commands/publish");
253
228
  await publishCommand({
254
229
  ...options,
255
230
  outputJson: options.outputJson,
231
+ autoApprove: options.autoApprove,
256
232
  });
257
233
  } catch (error) {
258
234
  console.error(chalk.red("Error:"), error.message);
@@ -304,7 +280,7 @@ ciCommand
304
280
  ciCommand
305
281
  .command("run")
306
282
  .description("Run capture + publish in one step (CI-optimized)")
307
- .option("-c, --config <path>", "Path to docsync.config.json")
283
+ .option("-c, --config <path>", "Path to reshot.config.json")
308
284
  .option("--tag <tag>", "Version tag for publish")
309
285
  .option("-m, --message <message>", "Commit message for publish")
310
286
  .option("--dry-run", "Preview without uploading")
@@ -323,10 +299,10 @@ ciCommand
323
299
  // DRIFT MANAGEMENT COMMANDS
324
300
  // ============================================================================
325
301
 
326
- // Drifts: View and manage documentation drifts
302
+ // Drifts: View and manage visual drifts
327
303
  program
328
304
  .command("drifts [action] [id]")
329
- .description("View and manage documentation drifts")
305
+ .description("View and manage visual drifts")
330
306
  .addHelpText(
331
307
  "after",
332
308
  `
@@ -339,7 +315,6 @@ Actions:
339
315
  sync <id> Mark as manually synced (external_host)
340
316
  approve-all Approve all pending drifts
341
317
  reject-all Reject all pending drifts
342
- validate Validate journey bindings
343
318
  `,
344
319
  )
345
320
  .option("--status <status>", "Filter: PENDING, APPROVED, REJECTED, IGNORED")
@@ -348,7 +323,6 @@ Actions:
348
323
  .action(async (action, id, options) => {
349
324
  try {
350
325
  const driftsCommand = require("./commands/drifts");
351
- // Map action/id to the expected subcommand/args format
352
326
  const subcommand = action || "list";
353
327
  const args = id ? [id] : [];
354
328
  await driftsCommand(subcommand, args, options);
@@ -364,7 +338,7 @@ Actions:
364
338
 
365
339
  // Auth: Standalone authentication (for re-auth scenarios)
366
340
  program
367
- .command("auth", { hidden: true })
341
+ .command("auth")
368
342
  .description("Authenticate with Reshot Cloud")
369
343
  .action(async () => {
370
344
  try {
@@ -406,57 +380,4 @@ program
406
380
  }
407
381
  });
408
382
 
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
383
  program.parse(process.argv);
@@ -3,15 +3,35 @@ const axios = require("axios");
3
3
  const FormData = require("form-data");
4
4
  const fs = require("fs");
5
5
 
6
- const baseUrl =
7
- process.env.RESHOT_API_BASE_URL ||
8
- process.env.DOCSYNC_API_BASE_URL ||
9
- "http://localhost:3000/api";
6
+ const PRODUCTION_API_URL = "https://reshot.dev/api";
10
7
 
11
8
  function getApiBaseUrl() {
12
- return baseUrl;
9
+ // 1. Explicit env var override (for CI or local dev)
10
+ if (process.env.RESHOT_API_BASE_URL) {
11
+ return process.env.RESHOT_API_BASE_URL;
12
+ }
13
+
14
+ // 2. Read from settings.json (set during auth/setup)
15
+ try {
16
+ const path = require("path");
17
+ const settingsPath = path.join(process.cwd(), ".reshot", "settings.json");
18
+ if (fs.existsSync(settingsPath)) {
19
+ const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
20
+ if (settings.platformUrl) {
21
+ return settings.platformUrl.replace(/\/+$/, "") + "/api";
22
+ }
23
+ }
24
+ } catch {
25
+ // Settings don't exist yet (first auth) — fall through to default
26
+ }
27
+
28
+ // 3. Default to production
29
+ return PRODUCTION_API_URL;
13
30
  }
14
31
 
32
+ // Resolved once at module load — all API calls use this
33
+ const baseUrl = getApiBaseUrl();
34
+
15
35
  /**
16
36
  * Sleep helper for retry delays
17
37
  */
@@ -586,6 +606,30 @@ async function publishTransactional(apiKey, payload) {
586
606
  return response.data;
587
607
  }
588
608
 
609
+ /**
610
+ * Batch publish metadata for multiple scenarios in one request
611
+ * @param {string} apiKey - API key for authentication
612
+ * @param {Object} payload - { commits: Array<{ metadata, assets }> }
613
+ * @returns {Promise<Object>}
614
+ */
615
+ async function publishBatch(apiKey, payload) {
616
+ if (!apiKey) {
617
+ throw new Error("API key is required to publish");
618
+ }
619
+
620
+ const response = await axios.post(`${baseUrl}/v1/publish/batch`, payload, {
621
+ headers: {
622
+ "Content-Type": "application/json",
623
+ Authorization: `Bearer ${apiKey}`,
624
+ },
625
+ timeout: 60000,
626
+ maxBodyLength: Infinity,
627
+ maxContentLength: Infinity,
628
+ });
629
+
630
+ return response.data;
631
+ }
632
+
589
633
  /**
590
634
  * Check which hashes already exist in storage (for deduplication)
591
635
  * @param {string} apiKey - API key for authentication
@@ -648,7 +692,7 @@ async function getBaselines(projectId, apiKey) {
648
692
  */
649
693
  async function exportVisuals(projectId, options = {}) {
650
694
  const { format = "json", status = "approved" } = options;
651
- const settings = require("./config").loadSettings();
695
+ const settings = require("./config").readSettings();
652
696
  const apiKey = settings?.apiKey;
653
697
 
654
698
  if (!apiKey) {
@@ -688,7 +732,7 @@ async function post(endpoint, data, options = {}) {
688
732
  }
689
733
 
690
734
  /**
691
- * DocSync: Initialize ingestion job with manifest
735
+ * Initialize ingestion job with manifest
692
736
  */
693
737
  async function initIngest(apiKey, projectId, manifest) {
694
738
  return withRetry(async () => {
@@ -705,7 +749,7 @@ async function initIngest(apiKey, projectId, manifest) {
705
749
  }
706
750
 
707
751
  /**
708
- * DocSync: Commit ingestion job after uploads complete
752
+ * Commit ingestion job after uploads complete
709
753
  */
710
754
  async function commitIngest(apiKey, projectId, uploadResults, git, cli) {
711
755
  return withRetry(async () => {
@@ -722,7 +766,7 @@ async function commitIngest(apiKey, projectId, uploadResults, git, cli) {
722
766
  }
723
767
 
724
768
  /**
725
- * DocSync: Get drift records for a project
769
+ * Get drift records for a project
726
770
  */
727
771
  async function getDrifts(apiKey, projectId, options = {}) {
728
772
  return withRetry(async () => {
@@ -742,7 +786,7 @@ async function getDrifts(apiKey, projectId, options = {}) {
742
786
  }
743
787
 
744
788
  /**
745
- * DocSync: Get sync jobs for a project
789
+ * Get sync jobs for a project
746
790
  */
747
791
  async function getSyncJobs(apiKey, projectId, options = {}) {
748
792
  return withRetry(async () => {
@@ -762,7 +806,7 @@ async function getSyncJobs(apiKey, projectId, options = {}) {
762
806
  }
763
807
 
764
808
  /**
765
- * DocSync: Perform action on a drift record
809
+ * Perform action on a drift record
766
810
  */
767
811
  async function driftAction(apiKey, projectId, driftId, action, options = {}) {
768
812
  return withRetry(async () => {
@@ -800,12 +844,13 @@ module.exports = {
800
844
  signAssets,
801
845
  uploadToPresignedUrl,
802
846
  publishTransactional,
847
+ publishBatch,
803
848
  checkExistingHashes,
804
849
  // Diffing support
805
850
  getBaselines,
806
851
  // Export support
807
852
  exportVisuals,
808
- // DocSync
853
+ // Reshot
809
854
  post,
810
855
  initIngest,
811
856
  commitIngest,
@@ -412,11 +412,11 @@ class CaptureEngine {
412
412
  projectId = settings.urlVariables?.PROJECT_ID;
413
413
  // 2. Check settings projectId
414
414
  if (!projectId) projectId = settings.projectId;
415
- // 3. Check docsync.config.json urlVariables
415
+ // 3. Check reshot.config.json urlVariables
416
416
  if (!projectId) {
417
417
  try {
418
- const docsyncConfig = config.readConfig() || {};
419
- projectId = docsyncConfig.urlVariables?.PROJECT_ID;
418
+ const reshotConfig = config.readConfig() || {};
419
+ projectId = reshotConfig.urlVariables?.PROJECT_ID;
420
420
  } catch (_e) {
421
421
  // Config may not exist
422
422
  }
@@ -1133,11 +1133,25 @@ async function runScenarioWithStepByStepCapture(scenario, options = {}) {
1133
1133
  `Page error detected: ${errMsg}. The page rendered an error UI instead of expected content.`
1134
1134
  );
1135
1135
  } else if (retryResult.status === "timeout") {
1136
+ const currentUrl = engine.page.url();
1136
1137
  console.log(
1137
1138
  chalk.yellow(
1138
- ` ⚠ Ready selector not found after ${retryResult.attempts} attempt(s), proceeding with current state`
1139
+ ` ⚠ Ready selector not found after ${retryResult.attempts} attempt(s): ${readySelector}`
1140
+ )
1141
+ );
1142
+ console.log(
1143
+ chalk.gray(` URL: ${currentUrl}`)
1144
+ );
1145
+ console.log(
1146
+ chalk.gray(
1147
+ ` Hint: The page loaded but this selector does not exist. Check your readySelector in reshot.config.json.`
1139
1148
  )
1140
1149
  );
1150
+ throw new Error(
1151
+ `Scenario readySelector "${readySelector}" not found after ${retryResult.attempts} attempt(s). ` +
1152
+ `The page loaded at ${currentUrl} but the selector does not exist. ` +
1153
+ `Update readySelector in reshot.config.json or remove it to skip this check.`
1154
+ );
1141
1155
  } else if (retryResult.attempts > 1) {
1142
1156
  console.log(
1143
1157
  chalk.green(
@@ -2185,8 +2199,16 @@ async function runScenarioWithVideoCapture(scenario, options = {}) {
2185
2199
  });
2186
2200
  } catch (e) {
2187
2201
  if (!isOptional) {
2202
+ const currentUrl = page.url();
2203
+ console.warn(
2204
+ chalk.yellow(` ⚠ Element not found: ${params.target}`)
2205
+ );
2206
+ console.warn(chalk.gray(` URL: ${currentUrl}`));
2207
+ console.warn(chalk.gray(` Timeout: ${waitTimeout}ms`));
2188
2208
  console.warn(
2189
- chalk.yellow(` ⚠ Wait for ${params.target} timed out`)
2209
+ chalk.gray(
2210
+ ` Hint: Verify the selector exists on the page. Run 'reshot record' to inspect.`
2211
+ )
2190
2212
  );
2191
2213
  }
2192
2214
  }
package/src/lib/config.js CHANGED
@@ -64,7 +64,7 @@ function createAuthErrorResponse(message) {
64
64
  code: "AUTH_REQUIRED",
65
65
  };
66
66
  }
67
- const CONFIG_PATH = path.join(process.cwd(), "docsync.config.json");
67
+ const CONFIG_PATH = path.join(process.cwd(), "reshot.config.json");
68
68
  const WORKSPACE_PATH = path.join(process.cwd(), SETTINGS_DIR, "workspace.json");
69
69
 
70
70
  /**
@@ -470,84 +470,22 @@ function readConfig() {
470
470
  }
471
471
  }
472
472
 
473
- // Validate optional docs block
474
- if (config.docs !== undefined) {
475
- if (
476
- typeof config.docs !== "object" ||
477
- config.docs === null ||
478
- Array.isArray(config.docs)
479
- ) {
480
- throw new Error("docs must be an object");
481
- }
482
- if (
483
- config.docs.root !== undefined &&
484
- typeof config.docs.root !== "string"
485
- ) {
486
- throw new Error("docs.root must be a string");
487
- }
488
- if (
489
- config.docs.include !== undefined &&
490
- !Array.isArray(config.docs.include)
491
- ) {
492
- throw new Error("docs.include must be an array of strings");
493
- }
494
- if (
495
- config.docs.exclude !== undefined &&
496
- !Array.isArray(config.docs.exclude)
497
- ) {
498
- throw new Error("docs.exclude must be an array of strings");
499
- }
500
- }
501
-
502
473
  return config;
503
474
  }
504
475
 
505
476
  /**
506
- * Read docsync.config.json with DocSync-specific configuration
507
- * Returns the full config including the documentation block for ingestion
508
- * @returns {Object} DocSync configuration
477
+ * Read reshot.config.json without requiring scenarios array
478
+ * Used by sync and other commands that don't need scenario validation
479
+ * @returns {Object} Configuration
509
480
  */
510
- function readDocSyncConfig() {
481
+ function readConfigLenient() {
511
482
  if (!fs.existsSync(CONFIG_PATH)) {
512
483
  throw new Error(
513
484
  `Config file not found at ${CONFIG_PATH}. Run \`reshot init\` to create one.`
514
485
  );
515
486
  }
516
487
 
517
- const config = fs.readJSONSync(CONFIG_PATH);
518
-
519
- // Validate documentation block if present
520
- if (config.documentation) {
521
- const doc = config.documentation;
522
-
523
- // Validate required fields
524
- if (!doc.strategy) {
525
- throw new Error('documentation.strategy is required (git_pr or external_host)');
526
- }
527
-
528
- if (!['git_pr', 'external_host'].includes(doc.strategy)) {
529
- throw new Error('documentation.strategy must be "git_pr" or "external_host"');
530
- }
531
-
532
- // Validate optional fields
533
- if (doc.assetFormat && !['cdn_link', 'markdown'].includes(doc.assetFormat)) {
534
- throw new Error('documentation.assetFormat must be "cdn_link" or "markdown"');
535
- }
536
-
537
- if (doc.include && !Array.isArray(doc.include)) {
538
- throw new Error('documentation.include must be an array of glob patterns');
539
- }
540
-
541
- if (doc.exclude && !Array.isArray(doc.exclude)) {
542
- throw new Error('documentation.exclude must be an array of glob patterns');
543
- }
544
-
545
- if (doc.mappings && typeof doc.mappings !== 'object') {
546
- throw new Error('documentation.mappings must be an object');
547
- }
548
- }
549
-
550
- return config;
488
+ return fs.readJSONSync(CONFIG_PATH);
551
489
  }
552
490
 
553
491
  /**
@@ -851,8 +789,6 @@ async function initializeProject(projectId, apiKey, options = {}) {
851
789
  contextCount: 1,
852
790
  features: {
853
791
  visuals: true,
854
- docs: false,
855
- changelog: true,
856
792
  },
857
793
  },
858
794
  };
@@ -1230,8 +1166,8 @@ module.exports = {
1230
1166
  // Mode & validation
1231
1167
  getModeInfo,
1232
1168
  validateConfig,
1233
- // DocSync configuration
1234
- readDocSyncConfig,
1169
+ // Lenient config read (no scenario validation)
1170
+ readConfigLenient,
1235
1171
  // Paths
1236
1172
  SETTINGS_PATH,
1237
1173
  SETTINGS_DIR,
@@ -600,7 +600,7 @@ async function finalizeScenarioAndWriteConfig(
600
600
 
601
601
  console.log(
602
602
  chalk.green(
603
- "\n✔ docsync.config.json has been updated. Please review and commit the changes to your repository.\n"
603
+ "\n✔ reshot.config.json has been updated. Please review and commit the changes to your repository.\n"
604
604
  )
605
605
  );
606
606
  console.log(chalk.gray(`Scenario: ${result.scenarioName}`));
@@ -103,7 +103,7 @@ const DEFAULT_STANDALONE_SETTINGS = {
103
103
  };
104
104
 
105
105
  const SETTINGS_DIR = ".reshot";
106
- const CONFIG_PATH = "docsync.config.json";
106
+ const CONFIG_PATH = "reshot.config.json";
107
107
  const SETTINGS_PATH = path.join(SETTINGS_DIR, "settings.json");
108
108
 
109
109
  /**
@@ -114,7 +114,7 @@ ${chalk.cyan('AWS S3 Setup:')}
114
114
  ${chalk.gray('export AWS_SECRET_ACCESS_KEY="your-secret-access-key"')}
115
115
  ${chalk.gray('export AWS_REGION="us-east-1" # optional, defaults to us-east-1')}
116
116
 
117
- 3. ${chalk.yellow('Update docsync.config.json:')}
117
+ 3. ${chalk.yellow('Update reshot.config.json:')}
118
118
  ${chalk.gray(JSON.stringify({
119
119
  storage: {
120
120
  type: 's3',
@@ -143,7 +143,7 @@ ${chalk.cyan('Cloudflare R2 Setup:')}
143
143
  ${chalk.gray('export R2_ACCESS_KEY_ID="your-r2-access-key"')}
144
144
  ${chalk.gray('export R2_SECRET_ACCESS_KEY="your-r2-secret-key"')}
145
145
 
146
- 3. ${chalk.yellow('Update docsync.config.json:')}
146
+ 3. ${chalk.yellow('Update reshot.config.json:')}
147
147
  ${chalk.gray(JSON.stringify({
148
148
  storage: {
149
149
  type: 'r2',
@@ -165,7 +165,7 @@ ${chalk.cyan('Local Storage Setup:')}
165
165
 
166
166
  For local testing or self-hosted scenarios:
167
167
 
168
- 1. ${chalk.yellow('Update docsync.config.json:')}
168
+ 1. ${chalk.yellow('Update reshot.config.json:')}
169
169
  ${chalk.gray(JSON.stringify({
170
170
  storage: {
171
171
  type: 'local',
@@ -536,7 +536,7 @@ function createStorageProvider(config) {
536
536
 
537
537
  /**
538
538
  * Determine storage mode from config
539
- * @param {object} docSyncConfig - The docsync.config.json content
539
+ * @param {object} docSyncConfig - The reshot.config.json content
540
540
  * @returns {'platform'|'byos'}
541
541
  */
542
542
  function getStorageMode(docSyncConfig) {
package/src/lib/ui-api.js CHANGED
@@ -43,17 +43,16 @@ const {
43
43
  * @returns {string} Platform URL
44
44
  */
45
45
  function getPlatformUrl(settings) {
46
- // Priority: settings.platformUrl > env var > localhost default
46
+ // Priority: settings.platformUrl > env var > production default
47
47
  if (settings?.platformUrl) {
48
48
  return settings.platformUrl;
49
49
  }
50
- const envUrl =
51
- process.env.RESHOT_API_BASE_URL || process.env.DOCSYNC_API_BASE_URL;
50
+ const envUrl = process.env.RESHOT_API_BASE_URL;
52
51
  if (envUrl) {
53
52
  // Remove /api suffix if present to get platform URL
54
53
  return envUrl.replace(/\/api\/?$/, "");
55
54
  }
56
- return "http://localhost:3000";
55
+ return "https://reshot.dev";
57
56
  }
58
57
 
59
58
  /**
@@ -431,7 +430,7 @@ function attachApiRoutes(app, context) {
431
430
 
432
431
  /**
433
432
  * PUT /api/privacy
434
- * Update privacy configuration in docsync.config.json
433
+ * Update privacy configuration in reshot.config.json
435
434
  */
436
435
  app.put("/api/privacy", async (req, res, next) => {
437
436
  try {
@@ -472,7 +471,7 @@ function attachApiRoutes(app, context) {
472
471
 
473
472
  /**
474
473
  * PUT /api/style
475
- * Update style configuration in docsync.config.json
474
+ * Update style configuration in reshot.config.json
476
475
  */
477
476
  app.put("/api/style", async (req, res, next) => {
478
477
  try {
@@ -2852,7 +2851,7 @@ function attachApiRoutes(app, context) {
2852
2851
  const apiBaseUrl = getApiBaseUrl();
2853
2852
  // Derive platformUrl from apiBaseUrl (remove /api suffix)
2854
2853
  const platformUrl =
2855
- apiBaseUrl.replace(/\/api\/?$/, "") || "http://localhost:3000";
2854
+ apiBaseUrl.replace(/\/api\/?$/, "") || "https://reshot.dev";
2856
2855
 
2857
2856
  config.writeSettings({
2858
2857
  projectId: project.id,