@reshotdev/screenshot 0.0.1-beta.4 ā 0.0.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +9 -2
- package/src/commands/auth.js +1 -3
- package/src/commands/ci-setup.js +2 -2
- package/src/commands/drifts.js +5 -70
- package/src/commands/import-tests.js +13 -13
- package/src/commands/ingest.js +10 -10
- package/src/commands/init.js +16 -277
- package/src/commands/publish.js +3 -204
- package/src/commands/pull.js +2 -2
- package/src/commands/setup-wizard.js +123 -523
- package/src/commands/setup.js +7 -7
- package/src/commands/status.js +26 -43
- package/src/commands/sync.js +28 -236
- package/src/commands/ui.js +1 -1
- package/src/index.js +9 -90
- package/src/lib/api-client.js +8 -8
- package/src/lib/capture-engine.js +3 -3
- package/src/lib/config.js +8 -72
- package/src/lib/record-config.js +1 -1
- package/src/lib/standalone-mode.js +1 -1
- package/src/lib/storage-providers.js +4 -4
- package/src/lib/ui-api.js +3 -3
- package/web/manager/dist/assets/{index--ZgioErz.js ā index-8H7P9ANi.js} +1 -1
- package/web/manager/dist/index.html +1 -1
- package/src/commands/validate-docs.js +0 -529
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ reshot studio
|
|
|
30
30
|
|
|
31
31
|
## Configuration
|
|
32
32
|
|
|
33
|
-
Create `
|
|
33
|
+
Create `reshot.config.json` in your project root:
|
|
34
34
|
|
|
35
35
|
```json
|
|
36
36
|
{
|
|
@@ -221,7 +221,7 @@ During recording:
|
|
|
221
221
|
- Press **C** to start/stop a video clip
|
|
222
222
|
- Press **Q** to quit and save
|
|
223
223
|
|
|
224
|
-
The recorded scenario is appended to `
|
|
224
|
+
The recorded scenario is appended to `reshot.config.json` automatically.
|
|
225
225
|
|
|
226
226
|
## Authentication
|
|
227
227
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reshotdev/screenshot",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.6",
|
|
4
4
|
"description": "CI/CD screenshot and video capture CLI",
|
|
5
5
|
"author": "Reshot <hello@reshot.dev>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,7 +13,14 @@
|
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
|
15
15
|
},
|
|
16
|
-
"keywords": [
|
|
16
|
+
"keywords": [
|
|
17
|
+
"screenshots",
|
|
18
|
+
"ci-cd",
|
|
19
|
+
"documentation",
|
|
20
|
+
"visual-testing",
|
|
21
|
+
"automation",
|
|
22
|
+
"playwright"
|
|
23
|
+
],
|
|
17
24
|
"bin": {
|
|
18
25
|
"reshot": "./src/index.js"
|
|
19
26
|
},
|
package/src/commands/auth.js
CHANGED
|
@@ -145,9 +145,7 @@ async function verifyApiKey(apiBaseUrl, apiKey) {
|
|
|
145
145
|
async function authCommand() {
|
|
146
146
|
const apiBaseUrl = getApiBaseUrl();
|
|
147
147
|
const explicitPortEnv =
|
|
148
|
-
process.env.RESHOT_CLI_CALLBACK_PORT ||
|
|
149
|
-
process.env.DOCSYNC_CLI_CALLBACK_PORT ||
|
|
150
|
-
"";
|
|
148
|
+
process.env.RESHOT_CLI_CALLBACK_PORT || "";
|
|
151
149
|
const basePort = parseInt(explicitPortEnv || `${DEFAULT_CALLBACK_PORT}`, 10);
|
|
152
150
|
const hasExplicitPort = Boolean(explicitPortEnv);
|
|
153
151
|
|
package/src/commands/ci-setup.js
CHANGED
|
@@ -37,7 +37,7 @@ jobs:
|
|
|
37
37
|
- name: Install ffmpeg
|
|
38
38
|
run: sudo apt-get update && sudo apt-get install -y ffmpeg
|
|
39
39
|
|
|
40
|
-
# Generate visual assets from
|
|
40
|
+
# Generate visual assets from reshot.config.json blueprint
|
|
41
41
|
# Only runs if features.visuals is enabled for the project
|
|
42
42
|
- name: Run Reshot scenarios
|
|
43
43
|
env:
|
|
@@ -205,7 +205,7 @@ async function ciSetupCommand() {
|
|
|
205
205
|
|
|
206
206
|
switch (provider) {
|
|
207
207
|
case 'github':
|
|
208
|
-
workflowPath = path.join(process.cwd(), '.github', 'workflows', '
|
|
208
|
+
workflowPath = path.join(process.cwd(), '.github', 'workflows', 'reshot.yml');
|
|
209
209
|
workflowContent = GITHUB_ACTIONS_WORKFLOW(secretNames);
|
|
210
210
|
break;
|
|
211
211
|
|
package/src/commands/drifts.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - reshot drifts sync <id> Mark as manually synced (external_host)
|
|
13
13
|
* - reshot drifts approve-all Approve all pending drifts
|
|
14
14
|
* - reshot drifts reject-all Reject all pending drifts
|
|
15
|
-
* - reshot drifts
|
|
15
|
+
* - reshot drifts approve-all Approve all pending drifts
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
const chalk = require("chalk");
|
|
@@ -273,76 +273,16 @@ async function batchDriftAction(apiKey, projectId, action, options = {}) {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
/**
|
|
277
|
-
* Validate journey bindings against visual inventory
|
|
278
|
-
*/
|
|
279
|
-
async function validateBindings(apiKey, projectId, options = {}) {
|
|
280
|
-
console.log(chalk.blue("\nš Validating Journey Bindings\n"));
|
|
281
|
-
|
|
282
|
-
try {
|
|
283
|
-
// Fetch visual keys from server
|
|
284
|
-
const visualKeys = await apiClient.getVisualKeys(projectId, apiKey);
|
|
285
|
-
console.log(chalk.green(` ā Fetched ${visualKeys.size} visual keys from project`));
|
|
286
|
-
|
|
287
|
-
// Read docsync config
|
|
288
|
-
const docSyncConfig = config.readDocSyncConfig();
|
|
289
|
-
const docConfig = docSyncConfig.documentation;
|
|
290
|
-
|
|
291
|
-
if (!docConfig || !docConfig.root) {
|
|
292
|
-
console.log(chalk.yellow(" ā No documentation.root configured"));
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// Use the validate-docs module for full validation
|
|
297
|
-
const validateDocs = require("./validate-docs");
|
|
298
|
-
const result = await validateDocs.validateDocSync({
|
|
299
|
-
strict: options.strict,
|
|
300
|
-
verbose: options.verbose,
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
// Additional server-side validation: check if any journey keys in the project
|
|
304
|
-
// are not bound to any documentation
|
|
305
|
-
const mappings = docConfig.mappings || {};
|
|
306
|
-
const boundKeys = new Set(Object.values(mappings));
|
|
307
|
-
|
|
308
|
-
const orphanedVisuals = [];
|
|
309
|
-
for (const key of visualKeys) {
|
|
310
|
-
if (!boundKeys.has(key)) {
|
|
311
|
-
orphanedVisuals.push(key);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (orphanedVisuals.length > 0) {
|
|
316
|
-
console.log(chalk.yellow(`\n ā ${orphanedVisuals.length} visual(s) not bound to documentation:`));
|
|
317
|
-
if (options.verbose) {
|
|
318
|
-
orphanedVisuals.slice(0, 10).forEach((key) => {
|
|
319
|
-
console.log(chalk.gray(` - ${key}`));
|
|
320
|
-
});
|
|
321
|
-
if (orphanedVisuals.length > 10) {
|
|
322
|
-
console.log(chalk.gray(` ... and ${orphanedVisuals.length - 10} more`));
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (!result.valid) {
|
|
328
|
-
process.exit(1);
|
|
329
|
-
}
|
|
330
|
-
} catch (error) {
|
|
331
|
-
console.error(chalk.red("Error:"), error.message);
|
|
332
|
-
process.exit(1);
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
276
|
/**
|
|
337
277
|
* Main drifts command handler
|
|
338
278
|
*/
|
|
339
279
|
async function driftsCommand(subcommand, args = [], options = {}) {
|
|
340
280
|
// Read configuration
|
|
341
|
-
let
|
|
281
|
+
let reshotConfig;
|
|
342
282
|
try {
|
|
343
|
-
|
|
283
|
+
reshotConfig = config.readConfigLenient();
|
|
344
284
|
} catch (error) {
|
|
345
|
-
console.error(chalk.red("Error:"), "
|
|
285
|
+
console.error(chalk.red("Error:"), "reshot.config.json not found. Run `reshot init` first.");
|
|
346
286
|
process.exit(1);
|
|
347
287
|
}
|
|
348
288
|
|
|
@@ -352,7 +292,7 @@ async function driftsCommand(subcommand, args = [], options = {}) {
|
|
|
352
292
|
const projectId =
|
|
353
293
|
process.env.RESHOT_PROJECT_ID ||
|
|
354
294
|
settings?.projectId ||
|
|
355
|
-
|
|
295
|
+
reshotConfig._metadata?.projectId;
|
|
356
296
|
|
|
357
297
|
if (!apiKey) {
|
|
358
298
|
console.error(chalk.red("Error:"), "API key not found. Set RESHOT_API_KEY or run `reshot auth`.");
|
|
@@ -398,10 +338,6 @@ async function driftsCommand(subcommand, args = [], options = {}) {
|
|
|
398
338
|
await batchDriftAction(apiKey, projectId, "reject", options);
|
|
399
339
|
break;
|
|
400
340
|
|
|
401
|
-
case "validate":
|
|
402
|
-
await validateBindings(apiKey, projectId, options);
|
|
403
|
-
break;
|
|
404
|
-
|
|
405
341
|
default:
|
|
406
342
|
console.error(chalk.red("Error:"), `Unknown subcommand: ${subcommand}`);
|
|
407
343
|
console.log(chalk.gray("\nAvailable subcommands:"));
|
|
@@ -413,7 +349,6 @@ async function driftsCommand(subcommand, args = [], options = {}) {
|
|
|
413
349
|
console.log(chalk.white(" sync ") + chalk.gray("Mark as manually synced"));
|
|
414
350
|
console.log(chalk.white(" approve-all ") + chalk.gray("Approve all pending drifts"));
|
|
415
351
|
console.log(chalk.white(" reject-all ") + chalk.gray("Reject all pending drifts"));
|
|
416
|
-
console.log(chalk.white(" validate ") + chalk.gray("Validate journey bindings"));
|
|
417
352
|
process.exit(1);
|
|
418
353
|
}
|
|
419
354
|
|
|
@@ -250,7 +250,7 @@ async function importTestsCommand(options = {}) {
|
|
|
250
250
|
{
|
|
251
251
|
type: "confirm",
|
|
252
252
|
name: "confirm",
|
|
253
|
-
message: "Save these mappings to
|
|
253
|
+
message: "Save these mappings to reshot.config.json?",
|
|
254
254
|
default: true,
|
|
255
255
|
},
|
|
256
256
|
]);
|
|
@@ -261,36 +261,36 @@ async function importTestsCommand(options = {}) {
|
|
|
261
261
|
}
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
-
// Update
|
|
265
|
-
let
|
|
264
|
+
// Update reshot.config.json
|
|
265
|
+
let reshotConfig;
|
|
266
266
|
try {
|
|
267
|
-
// Try to read existing config (use
|
|
268
|
-
|
|
267
|
+
// Try to read existing config (use readConfigLenient which is less strict)
|
|
268
|
+
reshotConfig = config.readConfigLenient();
|
|
269
269
|
} catch {
|
|
270
270
|
// Create new config with minimal required fields
|
|
271
|
-
|
|
272
|
-
$schema: "https://reshot.dev/schemas/
|
|
271
|
+
reshotConfig = {
|
|
272
|
+
$schema: "https://reshot.dev/schemas/reshot-config.json",
|
|
273
273
|
version: "2.0",
|
|
274
274
|
scenarios: [],
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
// Add visuals section with trace mappings
|
|
279
|
-
|
|
280
|
-
...
|
|
279
|
+
reshotConfig.visuals = {
|
|
280
|
+
...reshotConfig.visuals,
|
|
281
281
|
traceDir: pwConfig.outputDir,
|
|
282
282
|
journeyMappings,
|
|
283
283
|
};
|
|
284
284
|
|
|
285
285
|
// Ensure scenarios array exists for config.readConfig() compatibility
|
|
286
|
-
if (!
|
|
287
|
-
|
|
286
|
+
if (!reshotConfig.scenarios) {
|
|
287
|
+
reshotConfig.scenarios = [];
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
config.writeConfig(
|
|
290
|
+
config.writeConfig(reshotConfig);
|
|
291
291
|
|
|
292
292
|
console.log(
|
|
293
|
-
chalk.green("\nā Updated
|
|
293
|
+
chalk.green("\nā Updated reshot.config.json with journey mappings"),
|
|
294
294
|
);
|
|
295
295
|
console.log(chalk.gray("\nNext steps:"));
|
|
296
296
|
console.log(
|
package/src/commands/ingest.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// ingest.js - Upload traces and documentation for
|
|
2
|
-
// Implements the "Smart Handoff" protocol from the
|
|
1
|
+
// ingest.js - Upload traces and documentation for Reshot processing
|
|
2
|
+
// Implements the "Smart Handoff" protocol from the Reshot specification
|
|
3
3
|
|
|
4
4
|
const chalk = require("chalk");
|
|
5
5
|
const crypto = require("crypto");
|
|
@@ -51,7 +51,7 @@ function parseFrontmatter(content) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* Discover documentation files based on
|
|
54
|
+
* Discover documentation files based on reshot.config.json
|
|
55
55
|
*/
|
|
56
56
|
async function discoverDocumentation(docConfig, projectRoot) {
|
|
57
57
|
const files = [];
|
|
@@ -267,14 +267,14 @@ async function commitIngestion(apiKey, projectId, uploadResults, git, cliVersion
|
|
|
267
267
|
* Main ingest command
|
|
268
268
|
*/
|
|
269
269
|
async function ingestCommand(options = {}) {
|
|
270
|
-
console.log(chalk.blue('\nš„ Reshot
|
|
270
|
+
console.log(chalk.blue('\nš„ Reshot Reshot Ingest\n'));
|
|
271
271
|
|
|
272
272
|
// Read configuration
|
|
273
|
-
let
|
|
273
|
+
let reshotConfig;
|
|
274
274
|
try {
|
|
275
|
-
|
|
275
|
+
reshotConfig = config.readConfigLenient();
|
|
276
276
|
} catch (error) {
|
|
277
|
-
console.error(chalk.red('Error:'), '
|
|
277
|
+
console.error(chalk.red('Error:'), 'reshot.config.json not found. Run `reshot init` first.');
|
|
278
278
|
process.exit(1);
|
|
279
279
|
}
|
|
280
280
|
|
|
@@ -283,7 +283,7 @@ async function ingestCommand(options = {}) {
|
|
|
283
283
|
const apiKey = process.env.RESHOT_API_KEY || settings?.apiKey;
|
|
284
284
|
const projectId = process.env.RESHOT_PROJECT_ID ||
|
|
285
285
|
settings?.projectId ||
|
|
286
|
-
|
|
286
|
+
reshotConfig._metadata?.projectId;
|
|
287
287
|
|
|
288
288
|
if (!apiKey) {
|
|
289
289
|
console.error(chalk.red('Error:'), 'API key not found. Set RESHOT_API_KEY or run `reshot auth`.');
|
|
@@ -296,9 +296,9 @@ async function ingestCommand(options = {}) {
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
// Validate documentation configuration
|
|
299
|
-
const docConfig =
|
|
299
|
+
const docConfig = reshotConfig.documentation;
|
|
300
300
|
if (!docConfig) {
|
|
301
|
-
console.error(chalk.red('Error:'), 'No "documentation" block found in
|
|
301
|
+
console.error(chalk.red('Error:'), 'No "documentation" block found in reshot.config.json');
|
|
302
302
|
process.exit(1);
|
|
303
303
|
}
|
|
304
304
|
|
package/src/commands/init.js
CHANGED
|
@@ -14,123 +14,10 @@ const {
|
|
|
14
14
|
getConfigDefaults,
|
|
15
15
|
} = require("../lib/standalone-mode");
|
|
16
16
|
|
|
17
|
-
/**
|
|
18
|
-
* Auto-detect documentation directories
|
|
19
|
-
*/
|
|
20
|
-
function detectDocumentationRoot() {
|
|
21
|
-
const commonPaths = [
|
|
22
|
-
"docs",
|
|
23
|
-
"documentation",
|
|
24
|
-
"content",
|
|
25
|
-
"doc",
|
|
26
|
-
"guides",
|
|
27
|
-
".vitepress/content",
|
|
28
|
-
".docusaurus/docs",
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
for (const dir of commonPaths) {
|
|
32
|
-
const fullPath = path.join(process.cwd(), dir);
|
|
33
|
-
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
|
|
34
|
-
// Check if it has markdown files
|
|
35
|
-
const files = fs.readdirSync(fullPath);
|
|
36
|
-
if (files.some((f) => f.endsWith(".md") || f.endsWith(".mdx"))) {
|
|
37
|
-
return dir;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Generate documentation block configuration
|
|
47
|
-
*/
|
|
48
|
-
function generateDocumentationConfig(root = "./docs", strategy = "git_pr") {
|
|
49
|
-
return {
|
|
50
|
-
root,
|
|
51
|
-
include: ["**/*.md", "**/*.mdx"],
|
|
52
|
-
exclude: ["**/_*.mdx", "**/node_modules/**", "**/.next/**"],
|
|
53
|
-
strategy,
|
|
54
|
-
assetFormat: "markdown",
|
|
55
|
-
mappings: {},
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Scaffold a basic documentation structure
|
|
61
|
-
*/
|
|
62
|
-
async function scaffoldDocumentation() {
|
|
63
|
-
const docsDir = path.join(process.cwd(), "docs");
|
|
64
|
-
|
|
65
|
-
// Create docs directory
|
|
66
|
-
fs.ensureDirSync(docsDir);
|
|
67
|
-
|
|
68
|
-
// Create README
|
|
69
|
-
const readmeContent = `# Documentation
|
|
70
|
-
|
|
71
|
-
This directory contains documentation for your project.
|
|
72
|
-
|
|
73
|
-
## Getting Started
|
|
74
|
-
|
|
75
|
-
Documentation files are automatically synced with your codebase using Reshot DocSync.
|
|
76
|
-
|
|
77
|
-
### Linking Docs to Visuals
|
|
78
|
-
|
|
79
|
-
Add frontmatter to your markdown files to link them to visual journeys:
|
|
80
|
-
|
|
81
|
-
\`\`\`markdown
|
|
82
|
-
---
|
|
83
|
-
title: "Feature Name"
|
|
84
|
-
reshot_journey: "feature/workflow-name"
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
# Feature Documentation
|
|
88
|
-
|
|
89
|
-
Your content here...
|
|
90
|
-
\`\`\`
|
|
91
|
-
|
|
92
|
-
## Commands
|
|
93
|
-
|
|
94
|
-
- \`reshot validate\` - Validate documentation configuration
|
|
95
|
-
- \`reshot ingest\` - Upload traces and documentation
|
|
96
|
-
- \`reshot drifts\` - View and manage documentation drifts
|
|
97
|
-
|
|
98
|
-
For more information, visit: https://docs.reshot.dev
|
|
99
|
-
`;
|
|
100
|
-
|
|
101
|
-
fs.writeFileSync(path.join(docsDir, "README.md"), readmeContent);
|
|
102
|
-
|
|
103
|
-
// Create example doc
|
|
104
|
-
const exampleContent = `---
|
|
105
|
-
title: "Getting Started"
|
|
106
|
-
reshot_journey: "onboarding/first-steps"
|
|
107
|
-
description: "Quick start guide for new users"
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
# Getting Started
|
|
111
|
-
|
|
112
|
-
Welcome! This is an example documentation file.
|
|
113
|
-
|
|
114
|
-
## Steps
|
|
115
|
-
|
|
116
|
-
1. **Step 1**: Description of first step
|
|
117
|
-
2. **Step 2**: Description of second step
|
|
118
|
-
3. **Step 3**: Description of third step
|
|
119
|
-
|
|
120
|
-
## Next Steps
|
|
121
|
-
|
|
122
|
-
Continue to the next guide...
|
|
123
|
-
`;
|
|
124
|
-
|
|
125
|
-
fs.writeFileSync(path.join(docsDir, "getting-started.md"), exampleContent);
|
|
126
|
-
|
|
127
|
-
return "docs";
|
|
128
|
-
}
|
|
129
|
-
|
|
130
17
|
async function initCommand() {
|
|
131
18
|
console.log(chalk.cyan("š Initializing Reshot...\n"));
|
|
132
19
|
|
|
133
|
-
// Check if we already have a
|
|
20
|
+
// Check if we already have a reshot.config.json with BYOS storage config
|
|
134
21
|
let existingConfig = null;
|
|
135
22
|
let isBYOSMode = false;
|
|
136
23
|
|
|
@@ -272,7 +159,7 @@ async function initCommand() {
|
|
|
272
159
|
|
|
273
160
|
// Create a basic BYOS config with sane defaults
|
|
274
161
|
const byosConfig = {
|
|
275
|
-
$schema: "https://reshot.dev/schemas/
|
|
162
|
+
$schema: "https://reshot.dev/schemas/reshot-config.json",
|
|
276
163
|
version: "2.0",
|
|
277
164
|
baseUrl: "http://localhost:3000",
|
|
278
165
|
assetDir: ".reshot/output",
|
|
@@ -359,7 +246,7 @@ async function initCommand() {
|
|
|
359
246
|
|
|
360
247
|
console.log(
|
|
361
248
|
chalk.green(
|
|
362
|
-
"\nā Created
|
|
249
|
+
"\nā Created reshot.config.json with BYOS storage configuration"
|
|
363
250
|
)
|
|
364
251
|
);
|
|
365
252
|
console.log(chalk.cyan("\nNext steps:"));
|
|
@@ -396,13 +283,13 @@ async function initCommand() {
|
|
|
396
283
|
name: "overwrite",
|
|
397
284
|
default: false,
|
|
398
285
|
message:
|
|
399
|
-
"
|
|
286
|
+
"reshot.config.json already exists. Overwrite it with the latest blueprint?",
|
|
400
287
|
},
|
|
401
288
|
]);
|
|
402
289
|
overwrite = answer.overwrite;
|
|
403
290
|
|
|
404
291
|
if (!overwrite) {
|
|
405
|
-
console.log(chalk.yellow("ā Existing
|
|
292
|
+
console.log(chalk.yellow("ā Existing reshot.config.json preserved."));
|
|
406
293
|
return;
|
|
407
294
|
}
|
|
408
295
|
}
|
|
@@ -412,132 +299,8 @@ async function initCommand() {
|
|
|
412
299
|
overwrite,
|
|
413
300
|
});
|
|
414
301
|
|
|
415
|
-
// Auto-detect and configure documentation
|
|
416
|
-
console.log(chalk.cyan("\nš Configuring documentation sync..."));
|
|
417
|
-
|
|
418
|
-
let docsRoot = detectDocumentationRoot();
|
|
419
|
-
let shouldScaffold = false;
|
|
420
|
-
|
|
421
|
-
if (!docsRoot) {
|
|
422
|
-
console.log(chalk.yellow(" No documentation directory detected."));
|
|
423
|
-
|
|
424
|
-
const { action } = await inquirer.prompt([
|
|
425
|
-
{
|
|
426
|
-
type: "list",
|
|
427
|
-
name: "action",
|
|
428
|
-
message: "Would you like to:",
|
|
429
|
-
choices: [
|
|
430
|
-
{
|
|
431
|
-
name: "Create a new docs/ directory with examples",
|
|
432
|
-
value: "scaffold",
|
|
433
|
-
},
|
|
434
|
-
{ name: "Specify an existing directory", value: "specify" },
|
|
435
|
-
{ name: "Skip documentation setup (add later)", value: "skip" },
|
|
436
|
-
],
|
|
437
|
-
},
|
|
438
|
-
]);
|
|
439
|
-
|
|
440
|
-
if (action === "scaffold") {
|
|
441
|
-
console.log(chalk.cyan(" Creating docs/ directory..."));
|
|
442
|
-
docsRoot = await scaffoldDocumentation();
|
|
443
|
-
shouldScaffold = true;
|
|
444
|
-
console.log(chalk.green(" ā Created docs/ with example files"));
|
|
445
|
-
} else if (action === "specify") {
|
|
446
|
-
const { customPath } = await inquirer.prompt([
|
|
447
|
-
{
|
|
448
|
-
type: "input",
|
|
449
|
-
name: "customPath",
|
|
450
|
-
message: "Documentation directory path:",
|
|
451
|
-
default: "./docs",
|
|
452
|
-
validate: (input) => {
|
|
453
|
-
const fullPath = path.join(process.cwd(), input);
|
|
454
|
-
if (!fs.existsSync(fullPath)) {
|
|
455
|
-
return `Directory ${input} does not exist. Create it first or choose scaffold option.`;
|
|
456
|
-
}
|
|
457
|
-
return true;
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
]);
|
|
461
|
-
docsRoot = customPath;
|
|
462
|
-
}
|
|
463
|
-
} else {
|
|
464
|
-
console.log(chalk.green(` ā Detected documentation at: ${docsRoot}`));
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
// Add documentation block to config
|
|
468
|
-
if (docsRoot) {
|
|
469
|
-
// Detect if this is a GitHub repo for strategy recommendation
|
|
470
|
-
const isGitRepo = fs.existsSync(path.join(process.cwd(), ".git"));
|
|
471
|
-
const hasGitHubRemote =
|
|
472
|
-
isGitRepo &&
|
|
473
|
-
(() => {
|
|
474
|
-
try {
|
|
475
|
-
const { execSync } = require("child_process");
|
|
476
|
-
const remote = execSync("git remote get-url origin", {
|
|
477
|
-
encoding: "utf-8",
|
|
478
|
-
});
|
|
479
|
-
return remote.includes("github.com");
|
|
480
|
-
} catch {
|
|
481
|
-
return false;
|
|
482
|
-
}
|
|
483
|
-
})();
|
|
484
|
-
|
|
485
|
-
let strategy = "git_pr";
|
|
486
|
-
|
|
487
|
-
if (hasGitHubRemote) {
|
|
488
|
-
console.log(chalk.cyan(" ā Detected GitHub repository"));
|
|
489
|
-
const { useGitPR } = await inquirer.prompt([
|
|
490
|
-
{
|
|
491
|
-
type: "confirm",
|
|
492
|
-
name: "useGitPR",
|
|
493
|
-
message:
|
|
494
|
-
"Automatically create Pull Requests for documentation updates?",
|
|
495
|
-
default: true,
|
|
496
|
-
},
|
|
497
|
-
]);
|
|
498
|
-
strategy = useGitPR ? "git_pr" : "external_host";
|
|
499
|
-
} else {
|
|
500
|
-
const { strategyChoice } = await inquirer.prompt([
|
|
501
|
-
{
|
|
502
|
-
type: "list",
|
|
503
|
-
name: "strategyChoice",
|
|
504
|
-
message: "How should documentation updates be delivered?",
|
|
505
|
-
choices: [
|
|
506
|
-
{
|
|
507
|
-
name: "Git Pull Requests (recommended for GitHub/GitLab repos)",
|
|
508
|
-
value: "git_pr",
|
|
509
|
-
},
|
|
510
|
-
{
|
|
511
|
-
name: "Notifications only (for external CMS like ReadMe, GitBook)",
|
|
512
|
-
value: "external_host",
|
|
513
|
-
},
|
|
514
|
-
],
|
|
515
|
-
},
|
|
516
|
-
]);
|
|
517
|
-
strategy = strategyChoice;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
blueprint.documentation = generateDocumentationConfig(
|
|
521
|
-
docsRoot,
|
|
522
|
-
strategy
|
|
523
|
-
);
|
|
524
|
-
|
|
525
|
-
// Save updated config
|
|
526
|
-
config.writeConfig(blueprint);
|
|
527
|
-
|
|
528
|
-
console.log(chalk.green(" ā Documentation sync configured"));
|
|
529
|
-
console.log(chalk.gray(` Root: ${docsRoot}`));
|
|
530
|
-
console.log(chalk.gray(` Strategy: ${strategy}`));
|
|
531
|
-
|
|
532
|
-
if (shouldScaffold) {
|
|
533
|
-
console.log(chalk.cyan("\n š Example files created:"));
|
|
534
|
-
console.log(chalk.gray(" - docs/README.md"));
|
|
535
|
-
console.log(chalk.gray(" - docs/getting-started.md"));
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
302
|
if (blueprint._metadata?.projectName) {
|
|
540
|
-
console.log(chalk.green("ā Pulled
|
|
303
|
+
console.log(chalk.green("ā Pulled reshot.config.json from Reshot"));
|
|
541
304
|
} else {
|
|
542
305
|
console.log(
|
|
543
306
|
chalk.yellow(
|
|
@@ -545,7 +308,7 @@ async function initCommand() {
|
|
|
545
308
|
)
|
|
546
309
|
);
|
|
547
310
|
}
|
|
548
|
-
console.log(chalk.green("ā Saved
|
|
311
|
+
console.log(chalk.green("ā Saved reshot.config.json"));
|
|
549
312
|
|
|
550
313
|
const updatedSettings = config.readSettings();
|
|
551
314
|
console.log("");
|
|
@@ -559,7 +322,7 @@ async function initCommand() {
|
|
|
559
322
|
console.log("\nNext steps:");
|
|
560
323
|
console.log(
|
|
561
324
|
` 1. Review ${chalk.bold(
|
|
562
|
-
"
|
|
325
|
+
"reshot.config.json"
|
|
563
326
|
)} and commit it to your repo.`
|
|
564
327
|
);
|
|
565
328
|
console.log(
|
|
@@ -568,38 +331,14 @@ async function initCommand() {
|
|
|
568
331
|
)}`
|
|
569
332
|
);
|
|
570
333
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
)
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
);
|
|
580
|
-
console.log(
|
|
581
|
-
` 3. Run ${chalk.bold(
|
|
582
|
-
"reshot validate"
|
|
583
|
-
)} to check your documentation setup.`
|
|
584
|
-
);
|
|
585
|
-
console.log(
|
|
586
|
-
` 4. Run Playwright tests to generate traces, then ${chalk.bold(
|
|
587
|
-
"reshot ingest"
|
|
588
|
-
)}`
|
|
589
|
-
);
|
|
590
|
-
console.log(
|
|
591
|
-
` 5. Push your branch - Reshot will detect drift and create PRs.`
|
|
592
|
-
);
|
|
593
|
-
} else {
|
|
594
|
-
console.log(
|
|
595
|
-
` 2. Run ${chalk.bold(
|
|
596
|
-
'reshot record "My Visual"'
|
|
597
|
-
)} to capture your first flow.`
|
|
598
|
-
);
|
|
599
|
-
console.log(
|
|
600
|
-
` 3. Push your branch and open a PR. Reshot will post visual changes as a PR comment.`
|
|
601
|
-
);
|
|
602
|
-
}
|
|
334
|
+
console.log(
|
|
335
|
+
` 2. Run ${chalk.bold(
|
|
336
|
+
'reshot record "My Visual"'
|
|
337
|
+
)} to capture your first flow.`
|
|
338
|
+
);
|
|
339
|
+
console.log(
|
|
340
|
+
` 3. Push your branch and open a PR. Reshot will post visual changes as a PR comment.`
|
|
341
|
+
);
|
|
603
342
|
console.log("");
|
|
604
343
|
} catch (error) {
|
|
605
344
|
console.error(chalk.red("Failed to initialize:"), error.message);
|