@vscode/component-explorer-cli 0.1.1-2 → 0.1.1-20

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.
Files changed (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/SECURITY.md +14 -0
  4. package/dist/WorktreePool.d.ts +22 -0
  5. package/dist/WorktreePool.d.ts.map +1 -0
  6. package/dist/WorktreePool.js +58 -0
  7. package/dist/WorktreePool.js.map +1 -0
  8. package/dist/WorktreePool.test.d.ts +2 -0
  9. package/dist/WorktreePool.test.d.ts.map +1 -0
  10. package/dist/_virtual/_build-info.js +4 -0
  11. package/dist/_virtual/_build-info.js.map +1 -0
  12. package/dist/browserPage.d.ts +5 -0
  13. package/dist/browserPage.d.ts.map +1 -1
  14. package/dist/browserPage.js +28 -2
  15. package/dist/browserPage.js.map +1 -1
  16. package/dist/commands/acceptCommand.d.ts +2 -1
  17. package/dist/commands/acceptCommand.d.ts.map +1 -1
  18. package/dist/commands/acceptCommand.js +15 -8
  19. package/dist/commands/acceptCommand.js.map +1 -1
  20. package/dist/commands/checkStabilityCommand.d.ts +12 -0
  21. package/dist/commands/checkStabilityCommand.d.ts.map +1 -0
  22. package/dist/commands/checkStabilityCommand.js +84 -0
  23. package/dist/commands/checkStabilityCommand.js.map +1 -0
  24. package/dist/commands/compareCommand.d.ts +5 -1
  25. package/dist/commands/compareCommand.d.ts.map +1 -1
  26. package/dist/commands/compareCommand.js +56 -71
  27. package/dist/commands/compareCommand.js.map +1 -1
  28. package/dist/commands/mcpCommand.d.ts +4 -1
  29. package/dist/commands/mcpCommand.d.ts.map +1 -1
  30. package/dist/commands/mcpCommand.js +51 -8
  31. package/dist/commands/mcpCommand.js.map +1 -1
  32. package/dist/commands/screenshotCommand.d.ts +9 -2
  33. package/dist/commands/screenshotCommand.d.ts.map +1 -1
  34. package/dist/commands/screenshotCommand.js +73 -15
  35. package/dist/commands/screenshotCommand.js.map +1 -1
  36. package/dist/commands/serveCommand.d.ts +6 -1
  37. package/dist/commands/serveCommand.d.ts.map +1 -1
  38. package/dist/commands/serveCommand.js +104 -23
  39. package/dist/commands/serveCommand.js.map +1 -1
  40. package/dist/commands/watchCommand.d.ts +3 -2
  41. package/dist/commands/watchCommand.d.ts.map +1 -1
  42. package/dist/commands/watchCommand.js +28 -80
  43. package/dist/commands/watchCommand.js.map +1 -1
  44. package/dist/comparison.d.ts +70 -0
  45. package/dist/comparison.d.ts.map +1 -0
  46. package/dist/comparison.js +264 -0
  47. package/dist/comparison.js.map +1 -0
  48. package/dist/component-explorer-config.schema.json +222 -0
  49. package/dist/componentExplorer.d.ts +40 -2
  50. package/dist/componentExplorer.d.ts.map +1 -1
  51. package/dist/componentExplorer.js +118 -24
  52. package/dist/componentExplorer.js.map +1 -1
  53. package/dist/daemon/DaemonContext.d.ts +4 -0
  54. package/dist/daemon/DaemonContext.d.ts.map +1 -0
  55. package/dist/daemon/DaemonService.d.ts +146 -21
  56. package/dist/daemon/DaemonService.d.ts.map +1 -1
  57. package/dist/daemon/DaemonService.js +620 -123
  58. package/dist/daemon/DaemonService.js.map +1 -1
  59. package/dist/daemon/dynamicSessions.test.d.ts +2 -0
  60. package/dist/daemon/dynamicSessions.test.d.ts.map +1 -0
  61. package/dist/daemon/lifecycle.d.ts +8 -3
  62. package/dist/daemon/lifecycle.d.ts.map +1 -1
  63. package/dist/daemon/lifecycle.js +27 -10
  64. package/dist/daemon/lifecycle.js.map +1 -1
  65. package/dist/daemon/pipeClient.d.ts +6 -1
  66. package/dist/daemon/pipeClient.d.ts.map +1 -1
  67. package/dist/daemon/pipeClient.js +101 -8
  68. package/dist/daemon/pipeClient.js.map +1 -1
  69. package/dist/daemon/pipeServer.d.ts +2 -1
  70. package/dist/daemon/pipeServer.d.ts.map +1 -1
  71. package/dist/daemon/pipeServer.js +56 -6
  72. package/dist/daemon/pipeServer.js.map +1 -1
  73. package/dist/daemon/types.d.ts +12 -0
  74. package/dist/daemon/types.d.ts.map +1 -0
  75. package/dist/daemon/version.d.ts +10 -0
  76. package/dist/daemon/version.d.ts.map +1 -0
  77. package/dist/daemon/version.js +17 -0
  78. package/dist/daemon/version.js.map +1 -0
  79. package/dist/dependencyInstaller.d.ts +2 -2
  80. package/dist/dependencyInstaller.d.ts.map +1 -1
  81. package/dist/dependencyInstaller.js +1 -1
  82. package/dist/dependencyInstaller.js.map +1 -1
  83. package/dist/external/vscode-observables/observables/dist/disposables.js +24 -1
  84. package/dist/external/vscode-observables/observables/dist/disposables.js.map +1 -1
  85. package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js +1 -4
  86. package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js.map +1 -1
  87. package/dist/external/vscode-observables/observables/dist/observableInternal/index.js +2 -5
  88. package/dist/external/vscode-observables/observables/dist/observableInternal/index.js.map +1 -1
  89. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js +30 -6
  90. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js.map +1 -1
  91. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js +1 -1
  92. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js.map +1 -1
  93. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js +12 -1
  94. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js.map +1 -1
  95. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js +55 -0
  96. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js.map +1 -0
  97. package/dist/formatValue.d.ts +2 -0
  98. package/dist/formatValue.d.ts.map +1 -0
  99. package/dist/formatValue.js +96 -0
  100. package/dist/formatValue.js.map +1 -0
  101. package/dist/formatValue.test.d.ts +2 -0
  102. package/dist/formatValue.test.d.ts.map +1 -0
  103. package/dist/git/gitIndexResolver.d.ts +25 -0
  104. package/dist/git/gitIndexResolver.d.ts.map +1 -0
  105. package/dist/git/gitIndexResolver.js +91 -0
  106. package/dist/git/gitIndexResolver.js.map +1 -0
  107. package/dist/git/gitIndexResolver.test.d.ts +2 -0
  108. package/dist/git/gitIndexResolver.test.d.ts.map +1 -0
  109. package/dist/git/gitService.d.ts +2 -0
  110. package/dist/git/gitService.d.ts.map +1 -1
  111. package/dist/git/gitService.js +6 -0
  112. package/dist/git/gitService.js.map +1 -1
  113. package/dist/git/gitUtils.js +1 -1
  114. package/dist/git/gitUtils.js.map +1 -1
  115. package/dist/git/gitWorktreeManager.d.ts +6 -0
  116. package/dist/git/gitWorktreeManager.d.ts.map +1 -1
  117. package/dist/git/gitWorktreeManager.js +42 -13
  118. package/dist/git/gitWorktreeManager.js.map +1 -1
  119. package/dist/git/gitWorktreeManager.test.d.ts +2 -0
  120. package/dist/git/gitWorktreeManager.test.d.ts.map +1 -0
  121. package/dist/git/testUtils.d.ts +13 -0
  122. package/dist/git/testUtils.d.ts.map +1 -0
  123. package/dist/httpServer.d.ts +6 -1
  124. package/dist/httpServer.d.ts.map +1 -1
  125. package/dist/httpServer.js +30 -10
  126. package/dist/httpServer.js.map +1 -1
  127. package/dist/index.js +11 -2
  128. package/dist/index.js.map +1 -1
  129. package/dist/logger.d.ts +1 -0
  130. package/dist/logger.d.ts.map +1 -1
  131. package/dist/logger.js +7 -1
  132. package/dist/logger.js.map +1 -1
  133. package/dist/mcp/McpServer.d.ts +47 -4
  134. package/dist/mcp/McpServer.d.ts.map +1 -1
  135. package/dist/mcp/McpServer.js +913 -155
  136. package/dist/mcp/McpServer.js.map +1 -1
  137. package/dist/mcp/TaskManager.d.ts +28 -0
  138. package/dist/mcp/TaskManager.d.ts.map +1 -0
  139. package/dist/mcp/TaskManager.js +54 -0
  140. package/dist/mcp/TaskManager.js.map +1 -0
  141. package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js +137 -0
  142. package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js.map +1 -0
  143. package/dist/packages/simple-api/dist/chunk-SGBCNXYH.js +24 -0
  144. package/dist/packages/simple-api/dist/chunk-SGBCNXYH.js.map +1 -0
  145. package/dist/packages/simple-api/dist/chunk-TAEFVNPN.js +27 -0
  146. package/dist/packages/simple-api/dist/chunk-TAEFVNPN.js.map +1 -0
  147. package/dist/packages/simple-api/dist/express.js +104 -0
  148. package/dist/packages/simple-api/dist/express.js.map +1 -0
  149. package/dist/resolveProject.d.ts +21 -0
  150. package/dist/resolveProject.d.ts.map +1 -0
  151. package/dist/resolveProject.js +39 -0
  152. package/dist/resolveProject.js.map +1 -0
  153. package/dist/utils.d.ts +31 -0
  154. package/dist/utils.d.ts.map +1 -0
  155. package/dist/utils.js +49 -0
  156. package/dist/utils.js.map +1 -0
  157. package/dist/watchConfig.d.ts +52 -9
  158. package/dist/watchConfig.d.ts.map +1 -1
  159. package/dist/watchConfig.js +67 -62
  160. package/dist/watchConfig.js.map +1 -1
  161. package/package.json +31 -8
  162. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js +0 -72
  163. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js.map +0 -1
  164. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js +0 -447
  165. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js.map +0 -1
  166. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js +0 -64
  167. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js.map +0 -1
  168. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js +0 -52
  169. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js.map +0 -1
@@ -1,89 +1,74 @@
1
1
  import { Command, Option } from 'clipanion';
2
- import { ConsoleLogger, verbosityToLogLevel } from '../logger.js';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import { compareScreenshotsOnDisk, printComparisonToConsole, writeComparisonReport } from '../comparison.js';
5
+ import { ConsoleLogger, verbosityToLogLevel, logBuildInfo } from '../logger.js';
3
6
  import { FileSystemStorage } from '../storage.js';
7
+ import { resolveProject } from '../resolveProject.js';
8
+ import { listPngFiles, matchGlob } from '../utils.js';
4
9
 
5
10
  class CompareCommand extends Command {
6
- static paths = [['compare']];
11
+ static paths = [['screenshot:compare']];
7
12
  static usage = Command.Usage({
8
- description: 'Compare current screenshots against baseline',
13
+ description: 'Compare screenshot directories (file-level only)',
9
14
  examples: [
10
- ['Compare default directories', '$0 compare'],
15
+ ['Compare default directories', '$0 screenshot:compare'],
16
+ ['Compare with custom paths', '$0 screenshot:compare --baseline ./golden --current ./actual'],
17
+ ['Generate report folder', '$0 screenshot:compare --report ./report'],
11
18
  ],
12
19
  });
13
20
  verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
14
- root = Option.String('--root', process.cwd(), { description: 'Project root directory' });
21
+ filter = Option.String('--filter', { required: false, description: 'Filter fixtures by glob pattern' });
22
+ project = Option.String('-p,--project', process.cwd(), { description: 'Project: a directory, vite config file, or component-explorer.json' });
23
+ baseline = Option.String('--baseline', '.screenshots/baseline', { description: 'Baseline screenshots directory' });
24
+ current = Option.String('--current', '.screenshots/current', { description: 'Current screenshots directory' });
25
+ report = Option.String('--report', { required: false, description: 'Output report folder (contains report.json, report.md, and changed screenshots)' });
15
26
  async execute() {
16
- new ConsoleLogger('compare', this.context.stdout, verbosityToLogLevel(this.verbose));
17
- const storage = new FileSystemStorage(`${this.root}/.screenshots`);
18
- const baselineFiles = await storage.list('baseline');
19
- const currentFiles = await storage.list('current');
20
- const baselineSet = new Set(baselineFiles.map(f => f.replace('baseline/', '')));
21
- const currentSet = new Set(currentFiles.map(f => f.replace('current/', '')));
22
- const added = [];
23
- const removed = [];
24
- const changed = [];
25
- const unchanged = [];
26
- for (const file of currentSet) {
27
- if (!baselineSet.has(file)) {
28
- added.push(file);
29
- }
30
- else {
31
- const baselineData = await storage.read(`baseline/${file}`);
32
- const currentData = await storage.read(`current/${file}`);
33
- if (buffersEqual(baselineData, currentData)) {
34
- unchanged.push(file);
35
- }
36
- else {
37
- changed.push(file);
38
- }
39
- }
27
+ const resolved = await resolveProject(this.project);
28
+ const projectDir = resolved.projectDir;
29
+ const _logger = new ConsoleLogger('compare', this.context.stdout, verbosityToLogLevel(this.verbose));
30
+ logBuildInfo(_logger);
31
+ const baselineDir = path.isAbsolute(this.baseline) ? this.baseline : path.join(projectDir, this.baseline);
32
+ const currentDir = path.isAbsolute(this.current) ? this.current : path.join(projectDir, this.current);
33
+ const baselineStorage = new FileSystemStorage(baselineDir);
34
+ const currentStorage = new FileSystemStorage(currentDir);
35
+ // List all PNG files
36
+ let baselineFiles = await listPngFiles(baselineDir);
37
+ let currentFiles = await listPngFiles(currentDir);
38
+ // Apply filter if specified
39
+ if (this.filter) {
40
+ const filterFn = (file) => matchGlob(file.replace(/\.png$/, ''), this.filter);
41
+ baselineFiles = baselineFiles.filter(filterFn);
42
+ currentFiles = currentFiles.filter(filterFn);
40
43
  }
41
- for (const file of baselineSet) {
42
- if (!currentSet.has(file)) {
43
- removed.push(file);
44
- }
44
+ const currentMetadata = await readFixturesJson(currentDir);
45
+ const baselineMetadata = await readFixturesJson(baselineDir);
46
+ const result = await compareScreenshotsOnDisk({ list: async () => currentFiles, read: (id) => currentStorage.read(id), exists: (id) => currentStorage.exists(id) }, { list: async () => baselineFiles, read: (id) => baselineStorage.read(id), exists: (id) => baselineStorage.exists(id) }, currentFiles, baselineFiles, { currentMetadata, baselineMetadata });
47
+ printComparisonToConsole(result, this.context.stdout);
48
+ if (this.report) {
49
+ const reportDir = path.isAbsolute(this.report) ? this.report : path.join(process.cwd(), this.report);
50
+ await writeComparisonReport({
51
+ reportDir,
52
+ result,
53
+ baselinePath: this.baseline,
54
+ currentPath: this.current,
55
+ getBaselineData: (id) => baselineStorage.read(`${id}.png`),
56
+ getCurrentData: (id) => currentStorage.read(`${id}.png`),
57
+ });
58
+ this.context.stdout.write(`\nReport written to: ${this.report}/\n`);
45
59
  }
46
- if (added.length > 0) {
47
- this.context.stdout.write(`Added (${added.length}):\n`);
48
- for (const f of added) {
49
- this.context.stdout.write(` + ${f}\n`);
50
- }
51
- }
52
- if (removed.length > 0) {
53
- this.context.stdout.write(`Removed (${removed.length}):\n`);
54
- for (const f of removed) {
55
- this.context.stdout.write(` - ${f}\n`);
56
- }
57
- }
58
- if (changed.length > 0) {
59
- this.context.stdout.write(`Changed (${changed.length}):\n`);
60
- for (const f of changed) {
61
- this.context.stdout.write(` ~ ${f}\n`);
62
- }
63
- }
64
- if (unchanged.length > 0) {
65
- this.context.stdout.write(`Unchanged (${unchanged.length}):\n`);
66
- for (const f of unchanged) {
67
- this.context.stdout.write(` = ${f}\n`);
68
- }
69
- }
70
- const hasDiffs = added.length > 0 || removed.length > 0 || changed.length > 0;
71
- if (hasDiffs) {
72
- this.context.stdout.write('\nDifferences found.\n');
73
- return 1;
74
- }
75
- this.context.stdout.write('\nNo differences.\n');
76
- return 0;
60
+ const hasDiffs = result.added.length > 0 || result.removed.length > 0 || result.changed.length > 0;
61
+ return hasDiffs ? 1 : 0;
77
62
  }
78
63
  }
79
- function buffersEqual(a, b) {
80
- if (a.length !== b.length)
81
- return false;
82
- for (let i = 0; i < a.length; i++) {
83
- if (a[i] !== b[i])
84
- return false;
64
+ async function readFixturesJson(dir) {
65
+ try {
66
+ const data = await fs.readFile(path.join(dir, 'fixtures.json'), 'utf-8');
67
+ return JSON.parse(data);
68
+ }
69
+ catch {
70
+ return undefined;
85
71
  }
86
- return true;
87
72
  }
88
73
 
89
74
  export { CompareCommand };
@@ -1 +1 @@
1
- {"version":3,"file":"compareCommand.js","sources":["../../src/commands/compareCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compareCommand.js","sources":["../../src/commands/compareCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -2,7 +2,10 @@ import { Command } from 'clipanion';
2
2
  export declare class McpCommand extends Command {
3
3
  static paths: string[][];
4
4
  static usage: import("clipanion").Usage;
5
- readonly config: string;
5
+ readonly project: string;
6
+ readonly noAutostart: boolean;
7
+ readonly noAutostartHint: string | undefined;
8
+ readonly callTimeout: string | undefined;
6
9
  execute(): Promise<void>;
7
10
  }
8
11
  //# sourceMappingURL=mcpCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcpCommand.d.ts","sourceRoot":"","sources":["../../src/commands/mcpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,qBAAa,UAAW,SAAQ,OAAO;IACtC,OAAgB,KAAK,aAAa;IAElC,OAAgB,KAAK,4BAKlB;IAEH,QAAQ,CAAC,MAAM,SAA8F;IAEvG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ9B"}
1
+ {"version":3,"file":"mcpCommand.d.ts","sourceRoot":"","sources":["../../src/commands/mcpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAO5C,qBAAa,UAAW,SAAQ,OAAO;IACtC,OAAgB,KAAK,aAAa;IAElC,OAAgB,KAAK,4BAMlB;IAEH,QAAQ,CAAC,OAAO,SAA2I;IAC3J,QAAQ,CAAC,WAAW,UAAoH;IACxI,QAAQ,CAAC,eAAe,qBAAyI;IACjK,QAAQ,CAAC,WAAW,qBAAyG;IAEvH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA4C9B"}
@@ -1,22 +1,65 @@
1
1
  import { Command, Option } from 'clipanion';
2
- import { ensureDaemon } from '../daemon/lifecycle.js';
3
- import { ComponentExplorerMcpServer } from '../mcp/McpServer.js';
2
+ import '../external/vscode-observables/observables/dist/observableInternal/index.js';
3
+ import { observableValue } from '../external/vscode-observables/observables/dist/observableInternal/observables/observableValue.js';
4
+ import '../external/vscode-observables/observables/dist/observableInternal/debugLocation.js';
5
+ import '../external/vscode-observables/observables/dist/observableInternal/observables/derived.js';
6
+ import '../external/vscode-observables/observables/dist/observableInternal/utils/utils.js';
7
+ import '../external/vscode-observables/observables/dist/observableInternal/observables/observableFromEvent.js';
8
+ import { ensureDaemon, tryConnect } from '../daemon/lifecycle.js';
9
+ import { daemonPipeName } from '../daemon/pipeName.js';
10
+ import { DaemonConnection, ComponentExplorerMcpServer } from '../mcp/McpServer.js';
11
+ import { resolveProject } from '../resolveProject.js';
4
12
 
5
13
  class McpCommand extends Command {
6
14
  static paths = [['mcp']];
7
15
  static usage = Command.Usage({
8
16
  description: 'Start an MCP server over stdio. Auto-starts a daemon if not already running.',
9
17
  examples: [
10
- ['Start MCP server', '$0 mcp -c config.json'],
18
+ ['Start MCP server', '$0 mcp --project config.json'],
19
+ ['Require existing daemon', '$0 mcp --project config.json --no-daemon-autostart'],
11
20
  ],
12
21
  });
13
- config = Option.String('-c,--config', { required: true, description: 'Path to watch config JSON' });
22
+ project = Option.String('-p,--project,-c', { required: true, description: 'Project: a directory, vite config file, or component-explorer.json' });
23
+ noAutostart = Option.Boolean('--no-daemon-autostart', false, { description: 'Do not auto-start daemon; poll for it instead' });
24
+ noAutostartHint = Option.String('--no-daemon-hint', { description: 'Hint message shown when daemon is not running (used with --no-daemon-autostart)' });
25
+ callTimeout = Option.String('--call-timeout', { description: 'Timeout in seconds for daemon calls (default: 15)' });
14
26
  async execute() {
15
- // Ensure daemon is running (auto-starts in background if needed)
16
- const daemon = await ensureDaemon(this.config);
27
+ const resolved = await resolveProject(this.project);
28
+ if (resolved.kind !== 'explorerConfig') {
29
+ this.context.stderr.write('Error: mcp requires a component-explorer.json config file.\n');
30
+ return;
31
+ }
32
+ const daemonObservable = observableValue('daemon', undefined);
33
+ const mcpClientName = `mcp12-${new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, '')}`;
34
+ let pollFn;
35
+ if (this.noAutostart) {
36
+ const pipeName = daemonPipeName(resolved.configPath);
37
+ pollFn = async () => {
38
+ const client = await tryConnect(pipeName, { clientName: mcpClientName });
39
+ if (client) {
40
+ if (!daemonObservable.get()) {
41
+ daemonObservable.set(new DaemonConnection(client), undefined);
42
+ }
43
+ }
44
+ else {
45
+ daemonObservable.set(undefined, undefined);
46
+ }
47
+ };
48
+ await pollFn();
49
+ setInterval(pollFn, 5000);
50
+ }
51
+ else {
52
+ const daemon = await ensureDaemon(resolved.configPath, { clientName: mcpClientName });
53
+ daemonObservable.set(new DaemonConnection(daemon), undefined);
54
+ }
17
55
  // Create and connect the MCP server over stdio
18
- const mcpServer = new ComponentExplorerMcpServer(daemon);
19
- await mcpServer.connect();
56
+ await ComponentExplorerMcpServer.create(daemonObservable, {
57
+ pollFn,
58
+ noAutostartHint: this.noAutostartHint,
59
+ callTimeoutMs: this.callTimeout ? Number(this.callTimeout) * 1000 : undefined,
60
+ });
61
+ // Keep the process alive until the MCP connection closes
62
+ await new Promise(() => { });
20
63
  }
21
64
  }
22
65
 
@@ -1 +1 @@
1
- {"version":3,"file":"mcpCommand.js","sources":["../../src/commands/mcpCommand.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAIM,MAAO,UAAW,SAAQ,OAAO,CAAA;IACtC,OAAgB,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AAEjC,IAAA,OAAgB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AACrC,QAAA,WAAW,EAAE,8EAA8E;AAC3F,QAAA,QAAQ,EAAE;YACT,CAAC,kBAAkB,EAAE,uBAAuB,CAAC;AAC7C,SAAA;AACD,KAAA,CAAC;AAEO,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,2BAA2B,EAAE,CAAC;AAE5G,IAAA,MAAM,OAAO,GAAA;;QAEZ,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;;AAG9C,QAAA,MAAM,SAAS,GAAG,IAAI,0BAA0B,CAAC,MAAM,CAAC;AACxD,QAAA,MAAM,SAAS,CAAC,OAAO,EAAE;IAC1B;;;;;"}
1
+ {"version":3,"file":"mcpCommand.js","sources":["../../src/commands/mcpCommand.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;;;AAOM,MAAO,UAAW,SAAQ,OAAO,CAAA;IACtC,OAAgB,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;AAEjC,IAAA,OAAgB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AACrC,QAAA,WAAW,EAAE,8EAA8E;AAC3F,QAAA,QAAQ,EAAE;YACT,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;YACpD,CAAC,yBAAyB,EAAE,oDAAoD,CAAC;AACjF,SAAA;AACD,KAAA,CAAC;AAEO,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,oEAAoE,EAAE,CAAC;AACjJ,IAAA,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC;AAC9H,IAAA,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,WAAW,EAAE,iFAAiF,EAAE,CAAC;AACvJ,IAAA,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC;AAE5H,IAAA,MAAM,OAAO,GAAA;QACZ,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;AACnD,QAAA,IAAI,QAAQ,CAAC,IAAI,KAAK,gBAAgB,EAAE;YACvC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8DAA8D,CAAC;YACzF;QACD;QAEA,MAAM,gBAAgB,GAAG,eAAe,CACvC,QAAQ,EACR,SAAS,CACT;QAED,MAAM,aAAa,GAAG,CAAA,MAAA,EAAS,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA,CAAE;AAErG,QAAA,IAAI,MAAyC;AAC7C,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE;YACrB,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC;YACpD,MAAM,GAAG,YAAW;AACnB,gBAAA,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;gBACxE,IAAI,MAAM,EAAE;AACX,oBAAA,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,EAAE;wBAC5B,gBAAgB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;oBAC9D;gBACD;qBAAO;AACN,oBAAA,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC;gBAC3C;AACD,YAAA,CAAC;YACD,MAAM,MAAM,EAAE;AACd,YAAA,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC;QAC1B;aAAO;AACN,YAAA,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;YACrF,gBAAgB,CAAC,GAAG,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;QAC9D;;QAGe,MAAM,0BAA0B,CAAC,MAAM,CAAC,gBAAgB,EAAE;YACxE,MAAM;YACN,eAAe,EAAE,IAAI,CAAC,eAAe;AACrC,YAAA,aAAa,EAAE,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,GAAG,SAAS;AAC7E,SAAA;;QAGD,MAAM,IAAI,OAAO,CAAO,MAAK,EAAE,CAAC,CAAC;IAClC;;;;;"}
@@ -5,7 +5,14 @@ export declare class ScreenshotCommand extends Command {
5
5
  readonly verbose: number;
6
6
  readonly filter: string | undefined;
7
7
  readonly accept: boolean;
8
- readonly root: string;
9
- execute(): Promise<void>;
8
+ readonly project: string;
9
+ readonly target: string | undefined;
10
+ readonly compare: boolean;
11
+ readonly compareTarget: string | undefined;
12
+ readonly report: string | undefined;
13
+ readonly headed: boolean;
14
+ readonly timeout: string;
15
+ execute(): Promise<number>;
16
+ private _runComparison;
10
17
  }
11
18
  //# sourceMappingURL=screenshotCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenshotCommand.d.ts","sourceRoot":"","sources":["../../src/commands/screenshotCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAQ5C,qBAAa,iBAAkB,SAAQ,OAAO;IAC7C,OAAgB,KAAK,aAAoB;IAEzC,OAAgB,KAAK,4BAOlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,MAAM,UAAuG;IACtH,QAAQ,CAAC,IAAI,SAAqF;IAE5F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC9B"}
1
+ {"version":3,"file":"screenshotCommand.d.ts","sourceRoot":"","sources":["../../src/commands/screenshotCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAW5C,qBAAa,iBAAkB,SAAQ,OAAO;IAC7C,OAAgB,KAAK,aAAoB;IAEzC,OAAgB,KAAK,4BAOlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,MAAM,UAAiI;IAChJ,QAAQ,CAAC,OAAO,SAAuI;IACvJ,QAAQ,CAAC,MAAM,qBAAsK;IACrL,QAAQ,CAAC,OAAO,UAA8F;IAC9G,QAAQ,CAAC,aAAa,qBAA+K;IACrM,QAAQ,CAAC,MAAM,qBAA4G;IAC3H,QAAQ,CAAC,MAAM,UAAwG;IACvH,QAAQ,CAAC,OAAO,SAA+G;IAEzH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;YAwElB,cAAc;CA+B5B"}
@@ -1,10 +1,13 @@
1
1
  import { Command, Option } from 'clipanion';
2
+ import * as path from 'node:path';
2
3
  import { PlaywrightBrowserPageFactory } from '../browserPage.js';
4
+ import { compareScreenshotsInMemory, printComparisonToConsole, writeComparisonReport } from '../comparison.js';
3
5
  import { BrowserComponentExplorer } from '../componentExplorer.js';
4
6
  import { DefaultComponentExplorerHttpServerFactory } from '../httpServer.js';
5
- import { ConsoleLogger, verbosityToLogLevel } from '../logger.js';
7
+ import { ConsoleLogger, verbosityToLogLevel, logBuildInfo } from '../logger.js';
8
+ import { resolveProject, resolvedProjectToViteProjectRef } from '../resolveProject.js';
6
9
  import { FileSystemStorage } from '../storage.js';
7
- import { ViteProjectRef } from '../viteProjectRef.js';
10
+ import { matchGlob, writeFile } from '../utils.js';
8
11
 
9
12
  class ScreenshotCommand extends Command {
10
13
  static paths = [['screenshot']];
@@ -18,19 +21,42 @@ class ScreenshotCommand extends Command {
18
21
  });
19
22
  verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
20
23
  filter = Option.String('--filter', { required: false, description: 'Filter fixtures by glob pattern' });
21
- accept = Option.Boolean('--accept', false, { description: 'Write directly to baseline instead of current' });
22
- root = Option.String('--root', process.cwd(), { description: 'Project root directory' });
24
+ accept = Option.Boolean('--accept', false, { description: 'Write to baseline instead of current (mutually exclusive with --target)' });
25
+ project = Option.String('-p,--project', process.cwd(), { description: 'Project: a directory, vite config file, or component-explorer.json' });
26
+ target = Option.String('--target', { required: false, description: 'Screenshot output directory (default: .screenshots/current, or .screenshots/baseline with --accept)' });
27
+ compare = Option.Boolean('--compare', false, { description: 'Compare screenshots after capturing' });
28
+ compareTarget = Option.String('--compare-target', { required: false, description: 'Directory to compare against (default: .screenshots/baseline, or .screenshots/current with --accept)' });
29
+ report = Option.String('--report', { required: false, description: 'Output report folder (requires --compare)' });
30
+ headed = Option.Boolean('--headed', false, { description: 'Show the browser window (useful for debugging)' });
31
+ timeout = Option.String('--timeout', '30000', { description: 'Navigation timeout in milliseconds (default: 30000)' });
23
32
  async execute() {
33
+ // Validate mutually exclusive options
34
+ if (this.accept && this.target) {
35
+ this.context.stderr.write('Error: --accept and --target are mutually exclusive.\n');
36
+ return 1;
37
+ }
24
38
  const logger = new ConsoleLogger('screenshot', this.context.stdout, verbosityToLogLevel(this.verbose));
25
- const outputDir = this.accept ? 'baseline' : 'current';
26
- const storage = new FileSystemStorage(`${this.root}/.screenshots`);
39
+ logBuildInfo(logger);
40
+ const resolved = await resolveProject(this.project);
41
+ const projectDir = resolved.projectDir;
42
+ const viteProject = resolvedProjectToViteProjectRef(resolved);
43
+ // Determine target directory
44
+ const defaultTarget = this.accept ? '.screenshots/baseline' : '.screenshots/current';
45
+ const targetDir = this.target ?? defaultTarget;
46
+ const targetPath = path.isAbsolute(targetDir) ? targetDir : path.join(projectDir, targetDir);
47
+ // Determine compare target directory
48
+ const defaultCompareTarget = this.accept ? '.screenshots/current' : '.screenshots/baseline';
49
+ const compareTargetDir = this.compareTarget ?? defaultCompareTarget;
50
+ const compareTargetPath = path.isAbsolute(compareTargetDir) ? compareTargetDir : path.join(projectDir, compareTargetDir);
51
+ const storage = new FileSystemStorage(targetPath);
27
52
  const serverFactory = new DefaultComponentExplorerHttpServerFactory();
28
- const browserFactory = new PlaywrightBrowserPageFactory();
53
+ const browserFactory = new PlaywrightBrowserPageFactory(this.headed, Number(this.timeout), logger);
54
+ const screenshots = new Map();
29
55
  let server;
30
56
  let explorer;
31
57
  try {
32
58
  this.context.stdout.write('Starting Vite dev server...\n');
33
- server = await serverFactory.createViteServer(ViteProjectRef.fromSourceRootDir(this.root), { logger });
59
+ server = await serverFactory.createViteServer(viteProject, { logger });
34
60
  this.context.stdout.write(`Server running at ${server.url}\n`);
35
61
  explorer = new BrowserComponentExplorer(browserFactory, server, logger);
36
62
  const fixtures = await explorer.listFixtures();
@@ -39,23 +65,55 @@ class ScreenshotCommand extends Command {
39
65
  : fixtures;
40
66
  this.context.stdout.write(`Found ${filtered.length} fixture(s)\n`);
41
67
  for (const fixture of filtered) {
42
- const png = await explorer.screenshotFixture(fixture.fixtureId);
43
- const filePath = `${outputDir}/${fixture.fixtureId}.png`;
44
- await storage.write(filePath, png);
68
+ const result = await explorer.screenshotFixture(fixture.fixtureId);
69
+ await storage.write(`${fixture.fixtureId}.png`, result.image);
70
+ screenshots.set(fixture.fixtureId, { data: result.image, background: fixture.background, labels: fixture.labels });
45
71
  this.context.stdout.write(` ✓ ${fixture.fixtureId}\n`);
46
72
  }
47
- this.context.stdout.write(`\nScreenshots saved to .screenshots/${outputDir}/\n`);
73
+ await writeFixturesJson(targetPath, filtered);
74
+ this.context.stdout.write(`\nScreenshots saved to ${targetDir}/\n`);
48
75
  }
49
76
  finally {
50
77
  await explorer?.dispose();
51
78
  await browserFactory.dispose();
52
79
  await server?.dispose();
53
80
  }
81
+ // Compare if requested
82
+ if (this.compare) {
83
+ this.context.stdout.write(`\nComparing against ${compareTargetDir}...\n`);
84
+ return this._runComparison(screenshots, targetPath, compareTargetPath, projectDir);
85
+ }
86
+ return 0;
87
+ }
88
+ async _runComparison(screenshots, targetPath, compareTargetPath, projectDir) {
89
+ const compareStorage = new FileSystemStorage(compareTargetPath);
90
+ const result = await compareScreenshotsInMemory(screenshots, {
91
+ list: async () => [],
92
+ read: (id) => compareStorage.read(id),
93
+ exists: (id) => compareStorage.exists(id),
94
+ });
95
+ printComparisonToConsole(result, this.context.stdout);
96
+ if (this.report) {
97
+ const reportDir = path.isAbsolute(this.report) ? this.report : path.join(projectDir, this.report);
98
+ await writeComparisonReport({
99
+ reportDir,
100
+ result,
101
+ baselinePath: compareTargetPath,
102
+ currentPath: targetPath,
103
+ getBaselineData: (id) => compareStorage.read(`${id}.png`),
104
+ getCurrentData: async (id) => screenshots.get(id).data,
105
+ });
106
+ this.context.stdout.write(`\nReport written to: ${this.report}/\n`);
107
+ }
108
+ return (result.added.length > 0 || result.changed.length > 0) ? 1 : 0;
54
109
  }
55
110
  }
56
- function matchGlob(fixtureId, pattern) {
57
- const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
58
- return regex.test(fixtureId);
111
+ async function writeFixturesJson(targetDir, fixtures) {
112
+ const metadata = {};
113
+ for (const f of fixtures) {
114
+ metadata[f.fixtureId] = { background: f.background, labels: f.labels };
115
+ }
116
+ await writeFile(path.join(targetDir, 'fixtures.json'), Buffer.from(JSON.stringify(metadata, null, 2)));
59
117
  }
60
118
 
61
119
  export { ScreenshotCommand };
@@ -1 +1 @@
1
- {"version":3,"file":"screenshotCommand.js","sources":["../../src/commands/screenshotCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screenshotCommand.js","sources":["../../src/commands/screenshotCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -3,14 +3,19 @@ export declare class ServeCommand extends Command {
3
3
  static paths: string[][];
4
4
  static usage: import("clipanion").Usage;
5
5
  readonly verbose: number;
6
- readonly config: string;
6
+ readonly project: string;
7
7
  readonly background: boolean;
8
8
  readonly attach: boolean;
9
9
  readonly kill: boolean;
10
+ readonly killIfRunning: boolean;
11
+ readonly redirectionPort: string | undefined;
12
+ readonly redirectionHost: string | undefined;
10
13
  execute(): Promise<void>;
14
+ private _killExistingAndWait;
11
15
  private _ensureBackground;
12
16
  private _attach;
13
17
  private _printEvent;
14
18
  private _startDaemon;
19
+ private _startRedirectionServer;
15
20
  }
16
21
  //# sourceMappingURL=serveCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serveCommand.d.ts","sourceRoot":"","sources":["../../src/commands/serveCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAW5C,qBAAa,YAAa,SAAQ,OAAO;IACxC,OAAgB,KAAK,aAAe;IAEpC,OAAgB,KAAK,4BAgBlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,MAAM,SAA8F;IAC7G,QAAQ,CAAC,UAAU,UAAoG;IACvH,QAAQ,CAAC,MAAM,UAAsG;IACrH,QAAQ,CAAC,IAAI,UAAkF;IAEzF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA+ChB,iBAAiB;YAsBjB,OAAO;IAgBrB,OAAO,CAAC,WAAW;YAeL,YAAY;CA+B1B"}
1
+ {"version":3,"file":"serveCommand.d.ts","sourceRoot":"","sources":["../../src/commands/serveCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAe5C,qBAAa,YAAa,SAAQ,OAAO;IACxC,OAAgB,KAAK,aAAe;IAEpC,OAAgB,KAAK,4BAkBlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,OAAO,SAA2I;IAC3J,QAAQ,CAAC,UAAU,UAAoG;IACvH,QAAQ,CAAC,MAAM,UAAsG;IACrH,QAAQ,CAAC,IAAI,UAAkF;IAC/F,QAAQ,CAAC,aAAa,UAAqH;IAC3I,QAAQ,CAAC,eAAe,qBAA8H;IACtJ,QAAQ,CAAC,eAAe,qBAAsH;IAExI,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YA2DhB,oBAAoB;YAkBpB,iBAAiB;YA0BjB,OAAO;IAgBrB,OAAO,CAAC,WAAW;YAeL,YAAY;IAgD1B,OAAO,CAAC,uBAAuB;CAyB/B"}