@vscode/component-explorer-cli 0.1.1-0 → 0.1.1-10

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 (167) hide show
  1. package/README.md +177 -0
  2. package/dist/browserPage.js +4 -2
  3. package/dist/browserPage.js.map +1 -1
  4. package/dist/commands/acceptCommand.d.ts +3 -1
  5. package/dist/commands/acceptCommand.d.ts.map +1 -1
  6. package/dist/commands/acceptCommand.js +20 -8
  7. package/dist/commands/acceptCommand.js.map +1 -1
  8. package/dist/commands/compareCommand.d.ts +6 -1
  9. package/dist/commands/compareCommand.d.ts.map +1 -1
  10. package/dist/commands/compareCommand.js +51 -73
  11. package/dist/commands/compareCommand.js.map +1 -1
  12. package/dist/commands/mcpCommand.d.ts +10 -0
  13. package/dist/commands/mcpCommand.d.ts.map +1 -0
  14. package/dist/commands/mcpCommand.js +58 -0
  15. package/dist/commands/mcpCommand.js.map +1 -0
  16. package/dist/commands/screenshotCommand.d.ts +8 -2
  17. package/dist/commands/screenshotCommand.d.ts.map +1 -1
  18. package/dist/commands/screenshotCommand.js +70 -17
  19. package/dist/commands/screenshotCommand.js.map +1 -1
  20. package/dist/commands/serveCommand.d.ts +19 -0
  21. package/dist/commands/serveCommand.d.ts.map +1 -0
  22. package/dist/commands/serveCommand.js +194 -0
  23. package/dist/commands/serveCommand.js.map +1 -0
  24. package/dist/commands/watchCommand.d.ts +2 -2
  25. package/dist/commands/watchCommand.d.ts.map +1 -1
  26. package/dist/commands/watchCommand.js +39 -26
  27. package/dist/commands/watchCommand.js.map +1 -1
  28. package/dist/comparison.d.ts +60 -0
  29. package/dist/comparison.d.ts.map +1 -0
  30. package/dist/comparison.js +250 -0
  31. package/dist/comparison.js.map +1 -0
  32. package/dist/component-explorer-config.schema.json +183 -0
  33. package/dist/componentExplorer.d.ts +44 -2
  34. package/dist/componentExplorer.d.ts.map +1 -1
  35. package/dist/componentExplorer.js +103 -18
  36. package/dist/componentExplorer.js.map +1 -1
  37. package/dist/daemon/DaemonContext.d.ts +4 -0
  38. package/dist/daemon/DaemonContext.d.ts.map +1 -0
  39. package/dist/daemon/DaemonService.d.ts +188 -0
  40. package/dist/daemon/DaemonService.d.ts.map +1 -0
  41. package/dist/daemon/DaemonService.js +610 -0
  42. package/dist/daemon/DaemonService.js.map +1 -0
  43. package/dist/daemon/approvalStore.d.ts +51 -0
  44. package/dist/daemon/approvalStore.d.ts.map +1 -0
  45. package/dist/daemon/approvalStore.js +58 -0
  46. package/dist/daemon/approvalStore.js.map +1 -0
  47. package/dist/daemon/lifecycle.d.ts +13 -0
  48. package/dist/daemon/lifecycle.d.ts.map +1 -0
  49. package/dist/daemon/lifecycle.js +68 -0
  50. package/dist/daemon/lifecycle.js.map +1 -0
  51. package/dist/daemon/pipeClient.d.ts +9 -0
  52. package/dist/daemon/pipeClient.d.ts.map +1 -0
  53. package/dist/daemon/pipeClient.js +111 -0
  54. package/dist/daemon/pipeClient.js.map +1 -0
  55. package/dist/daemon/pipeName.d.ts +2 -0
  56. package/dist/daemon/pipeName.d.ts.map +1 -0
  57. package/dist/daemon/pipeName.js +14 -0
  58. package/dist/daemon/pipeName.js.map +1 -0
  59. package/dist/daemon/pipeServer.d.ts +4 -0
  60. package/dist/daemon/pipeServer.d.ts.map +1 -0
  61. package/dist/daemon/pipeServer.js +25 -0
  62. package/dist/daemon/pipeServer.js.map +1 -0
  63. package/dist/daemon/types.d.ts +12 -0
  64. package/dist/daemon/types.d.ts.map +1 -0
  65. package/dist/dependencyInstaller.js +8 -5
  66. package/dist/dependencyInstaller.js.map +1 -1
  67. package/dist/explorerSession.d.ts +5 -3
  68. package/dist/explorerSession.d.ts.map +1 -1
  69. package/dist/explorerSession.js +11 -5
  70. package/dist/explorerSession.js.map +1 -1
  71. package/dist/external/vscode-observables/observables/dist/disposables.js +66 -0
  72. package/dist/external/vscode-observables/observables/dist/disposables.js.map +1 -0
  73. package/dist/external/vscode-observables/observables/dist/observableInternal/base.js +22 -0
  74. package/dist/external/vscode-observables/observables/dist/observableInternal/base.js.map +1 -0
  75. package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js +37 -0
  76. package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js.map +1 -0
  77. package/dist/external/vscode-observables/observables/dist/observableInternal/debugLocation.js +77 -0
  78. package/dist/external/vscode-observables/observables/dist/observableInternal/debugLocation.js.map +1 -0
  79. package/dist/external/vscode-observables/observables/dist/observableInternal/debugName.js +114 -0
  80. package/dist/external/vscode-observables/observables/dist/observableInternal/debugName.js.map +1 -0
  81. package/dist/external/vscode-observables/observables/dist/observableInternal/index.js +22 -0
  82. package/dist/external/vscode-observables/observables/dist/observableInternal/index.js.map +1 -0
  83. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js +356 -0
  84. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js.map +1 -0
  85. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugGetDependencyGraph.js +79 -0
  86. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugGetDependencyGraph.js.map +1 -0
  87. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/logging.js +100 -0
  88. package/dist/external/vscode-observables/observables/dist/observableInternal/logging/logging.js.map +1 -0
  89. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js +143 -0
  90. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js.map +1 -0
  91. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js +28 -0
  92. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js.map +1 -0
  93. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derivedImpl.js +362 -0
  94. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derivedImpl.js.map +1 -0
  95. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/observableFromEvent.js +123 -0
  96. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/observableFromEvent.js.map +1 -0
  97. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/observableValue.js +81 -0
  98. package/dist/external/vscode-observables/observables/dist/observableInternal/observables/observableValue.js.map +1 -0
  99. package/dist/external/vscode-observables/observables/dist/observableInternal/reactions/autorun.js +23 -0
  100. package/dist/external/vscode-observables/observables/dist/observableInternal/reactions/autorun.js.map +1 -0
  101. package/dist/external/vscode-observables/observables/dist/observableInternal/reactions/autorunImpl.js +226 -0
  102. package/dist/external/vscode-observables/observables/dist/observableInternal/reactions/autorunImpl.js.map +1 -0
  103. package/dist/external/vscode-observables/observables/dist/observableInternal/transaction.js +87 -0
  104. package/dist/external/vscode-observables/observables/dist/observableInternal/transaction.js.map +1 -0
  105. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utils.js +68 -0
  106. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utils.js.map +1 -0
  107. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js +55 -0
  108. package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js.map +1 -0
  109. package/dist/formatValue.d.ts +2 -0
  110. package/dist/formatValue.d.ts.map +1 -0
  111. package/dist/formatValue.js +96 -0
  112. package/dist/formatValue.js.map +1 -0
  113. package/dist/formatValue.test.d.ts +2 -0
  114. package/dist/formatValue.test.d.ts.map +1 -0
  115. package/dist/git/gitCommitId.js +4 -2
  116. package/dist/git/gitCommitId.js.map +1 -1
  117. package/dist/git/gitCommitResolver.js +11 -3
  118. package/dist/git/gitCommitResolver.js.map +1 -1
  119. package/dist/git/gitService.js +5 -2
  120. package/dist/git/gitService.js.map +1 -1
  121. package/dist/git/gitUtils.js +10 -7
  122. package/dist/git/gitUtils.js.map +1 -1
  123. package/dist/git/gitWorktreeManager.js +5 -2
  124. package/dist/git/gitWorktreeManager.js.map +1 -1
  125. package/dist/httpServer.d.ts +9 -7
  126. package/dist/httpServer.d.ts.map +1 -1
  127. package/dist/httpServer.js +75 -11
  128. package/dist/httpServer.js.map +1 -1
  129. package/dist/index.js +6 -1
  130. package/dist/index.js.map +1 -1
  131. package/dist/logger.d.ts +17 -1
  132. package/dist/logger.d.ts.map +1 -1
  133. package/dist/logger.js +43 -6
  134. package/dist/logger.js.map +1 -1
  135. package/dist/mcp/McpServer.d.ts +58 -0
  136. package/dist/mcp/McpServer.d.ts.map +1 -0
  137. package/dist/mcp/McpServer.js +820 -0
  138. package/dist/mcp/McpServer.js.map +1 -0
  139. package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js +137 -0
  140. package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js.map +1 -0
  141. package/dist/packages/simple-api/dist/chunk-Q24JOMNK.js +27 -0
  142. package/dist/packages/simple-api/dist/chunk-Q24JOMNK.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/express.js +104 -0
  146. package/dist/packages/simple-api/dist/express.js.map +1 -0
  147. package/dist/resolveProject.d.ts +21 -0
  148. package/dist/resolveProject.d.ts.map +1 -0
  149. package/dist/resolveProject.js +39 -0
  150. package/dist/resolveProject.js.map +1 -0
  151. package/dist/screenshotCache.js +7 -4
  152. package/dist/screenshotCache.js.map +1 -1
  153. package/dist/sourceTreeId.js +4 -2
  154. package/dist/sourceTreeId.js.map +1 -1
  155. package/dist/storage.js +5 -2
  156. package/dist/storage.js.map +1 -1
  157. package/dist/utils.d.ts +24 -0
  158. package/dist/utils.d.ts.map +1 -0
  159. package/dist/utils.js +50 -0
  160. package/dist/utils.js.map +1 -0
  161. package/dist/viteProjectRef.js +5 -2
  162. package/dist/viteProjectRef.js.map +1 -1
  163. package/dist/watchConfig.d.ts +41 -0
  164. package/dist/watchConfig.d.ts.map +1 -1
  165. package/dist/watchConfig.js +48 -23
  166. package/dist/watchConfig.js.map +1 -1
  167. package/package.json +19 -6
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # @vscode/component-explorer-cli
2
+
3
+ Command-line tool for capturing, comparing, and managing component fixture screenshots.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @vscode/component-explorer-cli
9
+ ```
10
+
11
+ The binary is available as `component-explorer`.
12
+
13
+ ## Commands
14
+
15
+ ### `screenshot`
16
+
17
+ Capture screenshots of all fixtures using a headless browser.
18
+
19
+ ```bash
20
+ component-explorer screenshot [options]
21
+ ```
22
+
23
+ | Option | Description |
24
+ |---|---|
25
+ | `-p, --project <path>` | Project: a directory, vite config file, or component-explorer.json (default: cwd) |
26
+ | `--filter <pattern>` | Filter fixtures by glob pattern |
27
+ | `--accept` | Write to baseline instead of current (mutually exclusive with `--target`) |
28
+ | `--target <dir>` | Screenshot output directory (default: `.screenshots/current`, or `.screenshots/baseline` with `--accept`) |
29
+ | `--compare` | Compare screenshots after capturing |
30
+ | `--compare-target <dir>` | Directory to compare against (default: `.screenshots/baseline`, or `.screenshots/current` with `--accept`) |
31
+ | `--report <dir>` | Output report folder with report.json, report.md, and changed screenshots (requires `--compare`) |
32
+ | `-v, --verbose` | Increase log verbosity (`-v` debug, `-vv` trace) |
33
+
34
+ ```bash
35
+ # Capture all fixtures
36
+ component-explorer screenshot
37
+
38
+ # Capture and accept as baseline
39
+ component-explorer screenshot --accept
40
+
41
+ # Capture, then compare against baseline
42
+ component-explorer screenshot --compare
43
+
44
+ # Filter by glob
45
+ component-explorer screenshot --filter "Button/*"
46
+ ```
47
+
48
+ ### `screenshot:compare`
49
+
50
+ Compare two screenshot directories (file-level hash comparison).
51
+
52
+ ```bash
53
+ component-explorer screenshot:compare [options]
54
+ ```
55
+
56
+ | Option | Description |
57
+ |---|---|
58
+ | `-p, --project <path>` | Project directory (default: cwd) |
59
+ | `--baseline <dir>` | Baseline screenshots directory (default: `.screenshots/baseline`) |
60
+ | `--current <dir>` | Current screenshots directory (default: `.screenshots/current`) |
61
+ | `--filter <pattern>` | Filter fixtures by glob pattern |
62
+ | `--report <dir>` | Output report folder (contains report.json, report.md, and changed screenshots) |
63
+ | `-v, --verbose` | Increase log verbosity |
64
+
65
+ Exits with code 1 if differences are found, 0 otherwise.
66
+
67
+ ```bash
68
+ # Compare default directories
69
+ component-explorer screenshot:compare
70
+
71
+ # Compare with custom paths
72
+ component-explorer screenshot:compare --baseline ./golden --current ./actual
73
+
74
+ # Generate report folder
75
+ component-explorer screenshot:compare --report ./report
76
+ ```
77
+
78
+ ### `screenshot:accept`
79
+
80
+ Promote current screenshots to baseline by copying them from `.screenshots/current` to `.screenshots/baseline`.
81
+
82
+ ```bash
83
+ component-explorer screenshot:accept [options]
84
+ ```
85
+
86
+ | Option | Description |
87
+ |---|---|
88
+ | `-p, --project <path>` | Project directory (default: cwd) |
89
+ | `--filter <pattern>` | Filter fixtures by glob pattern |
90
+ | `--screenshot-dir <dir>` | Screenshots directory (default: `.screenshots`) |
91
+ | `-v, --verbose` | Increase log verbosity |
92
+
93
+ ```bash
94
+ # Accept all current screenshots as baseline
95
+ component-explorer screenshot:accept
96
+
97
+ # Accept specific fixtures
98
+ component-explorer screenshot:accept --filter "Button/*"
99
+ ```
100
+
101
+ ### `watch`
102
+
103
+ Watch for source changes and automatically re-capture/compare screenshots. Supports both simple mode (single project) and config mode (multiple sessions with git worktrees).
104
+
105
+ ```bash
106
+ component-explorer watch [options]
107
+ ```
108
+
109
+ | Option | Description |
110
+ |---|---|
111
+ | `-p, --project <path>` | Project: a directory, vite config file, or component-explorer.json (default: cwd) |
112
+ | `-v, --verbose` | Increase log verbosity |
113
+
114
+ In simple mode, starts a Vite dev server and re-captures screenshots on every HMR update. In config mode (when given a `component-explorer.json`), manages multiple sessions including git worktree-based baselines.
115
+
116
+ ```bash
117
+ # Watch all fixtures
118
+ component-explorer watch
119
+
120
+ # Watch with config
121
+ component-explorer watch -p component-explorer.json
122
+ ```
123
+
124
+ ### `serve`
125
+
126
+ Start or attach to a Component Explorer daemon process. The daemon manages Vite servers and browser sessions in the background.
127
+
128
+ ```bash
129
+ component-explorer serve -p <config> [options]
130
+ ```
131
+
132
+ | Option | Description |
133
+ |---|---|
134
+ | `-p, --project, -c <path>` | **(required)** Path to a component-explorer.json config file |
135
+ | `--background` | Spawn as a detached background process |
136
+ | `--attach` | Attach to a running daemon and stream events |
137
+ | `--kill` | Shut down a running daemon |
138
+ | `-v, --verbose` | Increase log verbosity |
139
+
140
+ Without flags, starts a foreground daemon. Combine `--background` and `--attach` to ensure a daemon is running and then stream its events.
141
+
142
+ ```bash
143
+ # Start in foreground
144
+ component-explorer serve -p config.json
145
+
146
+ # Start in background
147
+ component-explorer serve -p config.json --background
148
+
149
+ # Attach to running daemon
150
+ component-explorer serve -p config.json --attach
151
+
152
+ # Ensure daemon + attach
153
+ component-explorer serve -p config.json --background --attach
154
+
155
+ # Kill running daemon
156
+ component-explorer serve -p config.json --kill
157
+ ```
158
+
159
+ ### `mcp`
160
+
161
+ Start a [Model Context Protocol](https://modelcontextprotocol.io/) server over stdio. Auto-starts a daemon if one is not already running.
162
+
163
+ ```bash
164
+ component-explorer mcp -p <config>
165
+ ```
166
+
167
+ | Option | Description |
168
+ |---|---|
169
+ | `-p, --project, -c <path>` | **(required)** Path to a component-explorer.json config file |
170
+
171
+ ```bash
172
+ component-explorer mcp --project config.json
173
+ ```
174
+
175
+ ## Global Options
176
+
177
+ All commands support `-v` / `--verbose` for increased log output. Use `-vv` for trace-level logging.
@@ -1,4 +1,4 @@
1
- export class PlaywrightBrowserPageFactory {
1
+ class PlaywrightBrowserPageFactory {
2
2
  _browser;
3
3
  async openPage(url) {
4
4
  if (!this._browser) {
@@ -36,4 +36,6 @@ class PlaywrightBrowserPage {
36
36
  await this._page.close();
37
37
  }
38
38
  }
39
- //# sourceMappingURL=browserPage.js.map
39
+
40
+ export { PlaywrightBrowserPageFactory };
41
+ //# sourceMappingURL=browserPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browserPage.js","sourceRoot":"","sources":["../src/browserPage.ts"],"names":[],"mappings":"AAWA,MAAM,OAAO,4BAA4B;IAChC,QAAQ,CAA2C;IAE3D,KAAK,CAAC,QAAQ,CAAC,GAAW;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QACzC,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC3C,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;QACnD,OAAO,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC3B,CAAC;CACD;AAED,MAAM,qBAAqB;IACG;IAA7B,YAA6B,KAAgC;QAAhC,UAAK,GAAL,KAAK,CAA2B;IAAG,CAAC;IAEjE,KAAK,CAAC,UAAU,CAAI,UAAkB;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAe,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,iBAAyB;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,4CAA4C,iBAAiB,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,0FAA0F;QAC1F,MAAM,MAAM,GAAG,MAAO,OAA8E,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjI,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,OAAO;QACZ,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACD"}
1
+ {"version":3,"file":"browserPage.js","sources":["../src/browserPage.ts"],"sourcesContent":[null],"names":[],"mappings":"MAWa,4BAA4B,CAAA;AAChC,IAAA,QAAQ;IAEhB,MAAM,QAAQ,CAAC,GAAW,EAAA;AACzB,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;YACnB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,OAAO,YAAY,CAAC;YAC/C,IAAI,CAAC,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE;QACxC;QACA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE;AAC1C,QAAA,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AAClD,QAAA,OAAO,IAAI,qBAAqB,CAAC,IAAI,CAAC;IACvC;AAEA,IAAA,MAAM,OAAO,GAAA;AACZ,QAAA,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE;AAC5B,QAAA,IAAI,CAAC,QAAQ,GAAG,SAAS;IAC1B;AACA;AAED,MAAM,qBAAqB,CAAA;AACG,IAAA,KAAA;AAA7B,IAAA,WAAA,CAA6B,KAAgC,EAAA;QAAhC,IAAA,CAAA,KAAK,GAAL,KAAK;IAA8B;IAEhE,MAAM,UAAU,CAAI,UAAkB,EAAA;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAe;IACrD;IAEA,MAAM,UAAU,CAAC,iBAAyB,EAAA;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC;AACjE,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,EAAE;QAClC,IAAI,CAAC,OAAO,EAAE;AACb,YAAA,MAAM,IAAI,KAAK,CAAC,4CAA4C,iBAAiB,CAAA,CAAE,CAAC;QACjF;;AAEA,QAAA,MAAM,MAAM,GAAG,MAAO,OAA8E,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAChI,QAAA,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC;IAC9B;AAEA,IAAA,MAAM,OAAO,GAAA;AACZ,QAAA,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;IACzB;AACA;;;;"}
@@ -2,8 +2,10 @@ import { Command } from 'clipanion';
2
2
  export declare class AcceptCommand extends Command {
3
3
  static paths: string[][];
4
4
  static usage: import("clipanion").Usage;
5
+ readonly verbose: number;
5
6
  readonly filter: string | undefined;
6
- readonly root: string;
7
+ readonly project: string;
8
+ readonly screenshotDir: string;
7
9
  execute(): Promise<void>;
8
10
  }
9
11
  //# sourceMappingURL=acceptCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"acceptCommand.d.ts","sourceRoot":"","sources":["../../src/commands/acceptCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAG5C,qBAAa,aAAc,SAAQ,OAAO;IACzC,OAAgB,KAAK,aAAgB;IAErC,OAAgB,KAAK,4BAMlB;IAEH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,IAAI,SAAqF;IAE5F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA0B9B"}
1
+ {"version":3,"file":"acceptCommand.d.ts","sourceRoot":"","sources":["../../src/commands/acceptCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAM5C,qBAAa,aAAc,SAAQ,OAAO;IACzC,OAAgB,KAAK,aAA2B;IAEhD,OAAgB,KAAK,4BAMlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,OAAO,SAAuI;IACvJ,QAAQ,CAAC,aAAa,SAA+F;IAE/G,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B9B"}
@@ -1,18 +1,28 @@
1
1
  import { Command, Option } from 'clipanion';
2
+ import * as path from 'node:path';
3
+ import { ConsoleLogger, verbosityToLogLevel } from '../logger.js';
2
4
  import { FileSystemStorage } from '../storage.js';
3
- export class AcceptCommand extends Command {
4
- static paths = [['accept']];
5
+ import { resolveProject } from '../resolveProject.js';
6
+
7
+ class AcceptCommand extends Command {
8
+ static paths = [['screenshot:accept']];
5
9
  static usage = Command.Usage({
6
- description: 'Promote current screenshots as baseline',
10
+ description: 'Promote current screenshots to baseline (file-level only)',
7
11
  examples: [
8
- ['Accept all', '$0 accept'],
9
- ['Accept specific fixtures', '$0 accept --filter "Button/*"'],
12
+ ['Accept all', '$0 screenshot:accept'],
13
+ ['Accept specific fixtures', '$0 screenshot:accept --filter "Button/*"'],
10
14
  ],
11
15
  });
16
+ verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
12
17
  filter = Option.String('--filter', { required: false, description: 'Filter fixtures by glob pattern' });
13
- root = Option.String('--root', process.cwd(), { description: 'Project root directory' });
18
+ project = Option.String('-p,--project', process.cwd(), { description: 'Project: a directory, vite config file, or component-explorer.json' });
19
+ screenshotDir = Option.String('--screenshot-dir', '.screenshots', { description: 'Screenshots directory' });
14
20
  async execute() {
15
- const storage = new FileSystemStorage(`${this.root}/.screenshots`);
21
+ const resolved = await resolveProject(this.project);
22
+ const projectDir = resolved.projectDir;
23
+ new ConsoleLogger('accept', this.context.stdout, verbosityToLogLevel(this.verbose));
24
+ const screenshotPath = path.isAbsolute(this.screenshotDir) ? this.screenshotDir : path.join(projectDir, this.screenshotDir);
25
+ const storage = new FileSystemStorage(screenshotPath);
16
26
  let currentFiles = await storage.list('current');
17
27
  if (this.filter) {
18
28
  const regex = new RegExp('^current/' + this.filter.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
@@ -31,4 +41,6 @@ export class AcceptCommand extends Command {
31
41
  this.context.stdout.write(`\nAccepted ${currentFiles.length} screenshot(s) as baseline.\n`);
32
42
  }
33
43
  }
34
- //# sourceMappingURL=acceptCommand.js.map
44
+
45
+ export { AcceptCommand };
46
+ //# sourceMappingURL=acceptCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"acceptCommand.js","sourceRoot":"","sources":["../../src/commands/acceptCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,OAAO,aAAc,SAAQ,OAAO;IACzC,MAAM,CAAU,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAErC,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACrC,WAAW,EAAE,yCAAyC;QACtD,QAAQ,EAAE;YACT,CAAC,YAAY,EAAE,WAAW,CAAC;YAC3B,CAAC,0BAA0B,EAAE,+BAA+B,CAAC;SAC7D;KACD,CAAC,CAAC;IAEM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC,CAAC;IACxG,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAElG,KAAK,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,eAAe,CAAC,CAAC;QAEnE,IAAI,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEjD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,KAAK,GAAG,IAAI,MAAM,CACvB,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,GAAG,CACxE,CAAC;YACF,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACjE,OAAO;QACR,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,OAAO,CAAC,KAAK,CAAC,YAAY,YAAY,EAAE,EAAE,IAAI,CAAC,CAAC;YACtD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,YAAY,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,YAAY,CAAC,MAAM,+BAA+B,CAAC,CAAC;IAC7F,CAAC"}
1
+ {"version":3,"file":"acceptCommand.js","sources":["../../src/commands/acceptCommand.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;AAMM,MAAO,aAAc,SAAQ,OAAO,CAAA;IACzC,OAAgB,KAAK,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC;AAE/C,IAAA,OAAgB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AACrC,QAAA,WAAW,EAAE,2DAA2D;AACxE,QAAA,QAAQ,EAAE;YACT,CAAC,YAAY,EAAE,sBAAsB,CAAC;YACtC,CAAC,0BAA0B,EAAE,0CAA0C,CAAC;AACxE,SAAA;AACD,KAAA,CAAC;AAEO,IAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;AAC5G,IAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,iCAAiC,EAAE,CAAC;AACvG,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,oEAAoE,EAAE,CAAC;AAC7I,IAAA,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,cAAc,EAAE,EAAE,WAAW,EAAE,uBAAuB,EAAE,CAAC;AAEpH,IAAA,MAAM,OAAO,GAAA;QACZ,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;AACnD,QAAA,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU;QACtB,IAAI,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC;AAClG,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC;AAC3H,QAAA,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,cAAc,CAAC;QAErD,IAAI,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;AAEhD,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;YAChB,MAAM,KAAK,GAAG,IAAI,MAAM,CACvB,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,GAAG,CACxE;AACD,YAAA,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvD;AAEA,QAAA,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE;YAC9B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC;YAChE;QACD;AAEA,QAAA,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACrC,MAAM,OAAO,CAAC,KAAK,CAAC,CAAA,SAAA,EAAY,YAAY,CAAA,CAAE,EAAE,IAAI,CAAC;YACrD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,IAAA,EAAO,YAAY,CAAA,EAAA,CAAI,CAAC;QACnD;AAEA,QAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,WAAA,EAAc,YAAY,CAAC,MAAM,CAAA,6BAAA,CAA+B,CAAC;IAC5F;;;;;"}
@@ -2,7 +2,12 @@ import { Command } from 'clipanion';
2
2
  export declare class CompareCommand extends Command {
3
3
  static paths: string[][];
4
4
  static usage: import("clipanion").Usage;
5
- readonly root: string;
5
+ readonly verbose: number;
6
+ readonly filter: string | undefined;
7
+ readonly project: string;
8
+ readonly baseline: string;
9
+ readonly current: string;
10
+ readonly report: string | undefined;
6
11
  execute(): Promise<number>;
7
12
  }
8
13
  //# sourceMappingURL=compareCommand.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compareCommand.d.ts","sourceRoot":"","sources":["../../src/commands/compareCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAG5C,qBAAa,cAAe,SAAQ,OAAO;IAC1C,OAAgB,KAAK,aAAiB;IAEtC,OAAgB,KAAK,4BAKlB;IAEH,QAAQ,CAAC,IAAI,SAAqF;IAE5F,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAgEhC"}
1
+ {"version":3,"file":"compareCommand.d.ts","sourceRoot":"","sources":["../../src/commands/compareCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAQ5C,qBAAa,cAAe,SAAQ,OAAO;IAC1C,OAAgB,KAAK,aAA4B;IAEjD,OAAgB,KAAK,4BAOlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,OAAO,SAAuI;IACvJ,QAAQ,CAAC,QAAQ,SAA2G;IAC5H,QAAQ,CAAC,OAAO,SAAwG;IACxH,QAAQ,CAAC,MAAM,qBAAkJ;IAE3J,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CA+ChC"}
@@ -1,84 +1,62 @@
1
1
  import { Command, Option } from 'clipanion';
2
+ import * as path from 'node:path';
3
+ import { compareScreenshotsOnDisk, printComparisonToConsole, writeComparisonReport } from '../comparison.js';
4
+ import { ConsoleLogger, verbosityToLogLevel } from '../logger.js';
2
5
  import { FileSystemStorage } from '../storage.js';
3
- export class CompareCommand extends Command {
4
- static paths = [['compare']];
6
+ import { resolveProject } from '../resolveProject.js';
7
+ import { listPngFiles, matchGlob } from '../utils.js';
8
+
9
+ class CompareCommand extends Command {
10
+ static paths = [['screenshot:compare']];
5
11
  static usage = Command.Usage({
6
- description: 'Compare current screenshots against baseline',
12
+ description: 'Compare screenshot directories (file-level only)',
7
13
  examples: [
8
- ['Compare default directories', '$0 compare'],
14
+ ['Compare default directories', '$0 screenshot:compare'],
15
+ ['Compare with custom paths', '$0 screenshot:compare --baseline ./golden --current ./actual'],
16
+ ['Generate report folder', '$0 screenshot:compare --report ./report'],
9
17
  ],
10
18
  });
11
- root = Option.String('--root', process.cwd(), { description: 'Project root directory' });
19
+ verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
20
+ filter = Option.String('--filter', { required: false, description: 'Filter fixtures by glob pattern' });
21
+ project = Option.String('-p,--project', process.cwd(), { description: 'Project: a directory, vite config file, or component-explorer.json' });
22
+ baseline = Option.String('--baseline', '.screenshots/baseline', { description: 'Baseline screenshots directory' });
23
+ current = Option.String('--current', '.screenshots/current', { description: 'Current screenshots directory' });
24
+ report = Option.String('--report', { required: false, description: 'Output report folder (contains report.json, report.md, and changed screenshots)' });
12
25
  async execute() {
13
- const storage = new FileSystemStorage(`${this.root}/.screenshots`);
14
- const baselineFiles = await storage.list('baseline');
15
- const currentFiles = await storage.list('current');
16
- const baselineSet = new Set(baselineFiles.map(f => f.replace('baseline/', '')));
17
- const currentSet = new Set(currentFiles.map(f => f.replace('current/', '')));
18
- const added = [];
19
- const removed = [];
20
- const changed = [];
21
- const unchanged = [];
22
- for (const file of currentSet) {
23
- if (!baselineSet.has(file)) {
24
- added.push(file);
25
- }
26
- else {
27
- const baselineData = await storage.read(`baseline/${file}`);
28
- const currentData = await storage.read(`current/${file}`);
29
- if (buffersEqual(baselineData, currentData)) {
30
- unchanged.push(file);
31
- }
32
- else {
33
- changed.push(file);
34
- }
35
- }
26
+ const resolved = await resolveProject(this.project);
27
+ const projectDir = resolved.projectDir;
28
+ new ConsoleLogger('compare', this.context.stdout, verbosityToLogLevel(this.verbose));
29
+ const baselineDir = path.isAbsolute(this.baseline) ? this.baseline : path.join(projectDir, this.baseline);
30
+ const currentDir = path.isAbsolute(this.current) ? this.current : path.join(projectDir, this.current);
31
+ const baselineStorage = new FileSystemStorage(baselineDir);
32
+ const currentStorage = new FileSystemStorage(currentDir);
33
+ // List all PNG files
34
+ let baselineFiles = await listPngFiles(baselineDir);
35
+ let currentFiles = await listPngFiles(currentDir);
36
+ // Apply filter if specified
37
+ if (this.filter) {
38
+ const filterFn = (file) => matchGlob(file.replace(/\.png$/, ''), this.filter);
39
+ baselineFiles = baselineFiles.filter(filterFn);
40
+ currentFiles = currentFiles.filter(filterFn);
36
41
  }
37
- for (const file of baselineSet) {
38
- if (!currentSet.has(file)) {
39
- removed.push(file);
40
- }
42
+ 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);
43
+ printComparisonToConsole(result, this.context.stdout);
44
+ if (this.report) {
45
+ const reportDir = path.isAbsolute(this.report) ? this.report : path.join(process.cwd(), this.report);
46
+ await writeComparisonReport({
47
+ reportDir,
48
+ result,
49
+ baselinePath: this.baseline,
50
+ currentPath: this.current,
51
+ getBaselineData: (id) => baselineStorage.read(`${id}.png`),
52
+ getCurrentData: (id) => currentStorage.read(`${id}.png`),
53
+ });
54
+ this.context.stdout.write(`\nReport written to: ${this.report}/\n`);
41
55
  }
42
- if (added.length > 0) {
43
- this.context.stdout.write(`Added (${added.length}):\n`);
44
- for (const f of added) {
45
- this.context.stdout.write(` + ${f}\n`);
46
- }
47
- }
48
- if (removed.length > 0) {
49
- this.context.stdout.write(`Removed (${removed.length}):\n`);
50
- for (const f of removed) {
51
- this.context.stdout.write(` - ${f}\n`);
52
- }
53
- }
54
- if (changed.length > 0) {
55
- this.context.stdout.write(`Changed (${changed.length}):\n`);
56
- for (const f of changed) {
57
- this.context.stdout.write(` ~ ${f}\n`);
58
- }
59
- }
60
- if (unchanged.length > 0) {
61
- this.context.stdout.write(`Unchanged (${unchanged.length}):\n`);
62
- for (const f of unchanged) {
63
- this.context.stdout.write(` = ${f}\n`);
64
- }
65
- }
66
- const hasDiffs = added.length > 0 || removed.length > 0 || changed.length > 0;
67
- if (hasDiffs) {
68
- this.context.stdout.write('\nDifferences found.\n');
69
- return 1;
70
- }
71
- this.context.stdout.write('\nNo differences.\n');
72
- return 0;
73
- }
74
- }
75
- function buffersEqual(a, b) {
76
- if (a.length !== b.length)
77
- return false;
78
- for (let i = 0; i < a.length; i++) {
79
- if (a[i] !== b[i])
80
- return false;
56
+ const hasDiffs = result.added.length > 0 || result.removed.length > 0 || result.changed.length > 0;
57
+ return hasDiffs ? 1 : 0;
81
58
  }
82
- return true;
83
59
  }
84
- //# sourceMappingURL=compareCommand.js.map
60
+
61
+ export { CompareCommand };
62
+ //# sourceMappingURL=compareCommand.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compareCommand.js","sourceRoot":"","sources":["../../src/commands/compareCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,OAAO,cAAe,SAAQ,OAAO;IAC1C,MAAM,CAAU,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEtC,MAAM,CAAU,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QACrC,WAAW,EAAE,8CAA8C;QAC3D,QAAQ,EAAE;YACT,CAAC,6BAA6B,EAAE,YAAY,CAAC;SAC7C;KACD,CAAC,CAAC;IAEM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAElG,KAAK,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,IAAI,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,eAAe,CAAC,CAAC;QAEnE,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEnD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAChF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAE7E,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAa,EAAE,CAAC;QAE/B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACP,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;gBAC5D,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;gBAC1D,IAAI,YAAY,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC7C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACP,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC;QACF,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACF,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,KAAK,CAAC,MAAM,MAAM,CAAC,CAAC;YACxD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;QACpE,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,MAAM,MAAM,CAAC,CAAC;YAC5D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;QACtE,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,MAAM,MAAM,CAAC,CAAC;YAC5D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;QACtE,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,SAAS,CAAC,MAAM,MAAM,CAAC,CAAC;YAChE,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC;QACxE,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAE9E,IAAI,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACV,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACjD,OAAO,CAAC,CAAC;IACV,CAAC;;AAGF,SAAS,YAAY,CAAC,CAAa,EAAE,CAAa;IACjD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"compareCommand.js","sources":["../../src/commands/compareCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Command } from 'clipanion';
2
+ export declare class McpCommand extends Command {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ readonly project: string;
6
+ readonly noAutostart: boolean;
7
+ readonly noAutostartHint: string | undefined;
8
+ execute(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=mcpCommand.d.ts.map
@@ -0,0 +1 @@
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;IAE3J,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAqC9B"}
@@ -0,0 +1,58 @@
1
+ import { Command, Option } from 'clipanion';
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';
12
+
13
+ class McpCommand extends Command {
14
+ static paths = [['mcp']];
15
+ static usage = Command.Usage({
16
+ description: 'Start an MCP server over stdio. Auto-starts a daemon if not already running.',
17
+ examples: [
18
+ ['Start MCP server', '$0 mcp --project config.json'],
19
+ ['Require existing daemon', '$0 mcp --project config.json --no-daemon-autostart'],
20
+ ],
21
+ });
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
+ async execute() {
26
+ const resolved = await resolveProject(this.project);
27
+ if (resolved.kind !== 'explorerConfig') {
28
+ this.context.stderr.write('Error: mcp requires a component-explorer.json config file.\n');
29
+ return;
30
+ }
31
+ const daemonObservable = observableValue('daemon', undefined);
32
+ const mcpClientName = `mcp-${new Date().toISOString().replace(/[-:]/g, '').replace(/\.\d+Z$/, '')}`;
33
+ let pollFn;
34
+ if (this.noAutostart) {
35
+ const pipeName = daemonPipeName(resolved.configPath);
36
+ pollFn = async () => {
37
+ const client = await tryConnect(pipeName, { clientName: mcpClientName });
38
+ daemonObservable.set(client ? new DaemonConnection(client) : undefined, undefined);
39
+ };
40
+ await pollFn();
41
+ setInterval(pollFn, 5000);
42
+ }
43
+ else {
44
+ const daemon = await ensureDaemon(resolved.configPath, { clientName: mcpClientName });
45
+ daemonObservable.set(new DaemonConnection(daemon), undefined);
46
+ }
47
+ // Create and connect the MCP server over stdio
48
+ await ComponentExplorerMcpServer.create(daemonObservable, {
49
+ pollFn,
50
+ noAutostartHint: this.noAutostartHint,
51
+ });
52
+ // Keep the process alive until the MCP connection closes
53
+ await new Promise(() => { });
54
+ }
55
+ }
56
+
57
+ export { McpCommand };
58
+ //# sourceMappingURL=mcpCommand.js.map
@@ -0,0 +1 @@
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;AAEhK,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,IAAA,EAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA,CAAE;AAEnG,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;AACxE,gBAAA,gBAAgB,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,SAAS,EAAE,SAAS,CAAC;AACnF,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,SAAA;;QAGD,MAAM,IAAI,OAAO,CAAO,MAAK,EAAE,CAAC,CAAC;IAClC;;;;;"}
@@ -2,9 +2,15 @@ import { Command } from 'clipanion';
2
2
  export declare class ScreenshotCommand extends Command {
3
3
  static paths: string[][];
4
4
  static usage: import("clipanion").Usage;
5
+ readonly verbose: number;
5
6
  readonly filter: string | undefined;
6
7
  readonly accept: boolean;
7
- readonly root: string;
8
- 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
+ execute(): Promise<number>;
14
+ private _runComparison;
9
15
  }
10
16
  //# 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;AAO5C,qBAAa,iBAAkB,SAAQ,OAAO;IAC7C,OAAgB,KAAK,aAAoB;IAEzC,OAAgB,KAAK,4BAOlB;IAEH,QAAQ,CAAC,MAAM,qBAAkG;IACjH,QAAQ,CAAC,MAAM,UAAuG;IACtH,QAAQ,CAAC,IAAI,SAAqF;IAE5F,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAqC9B"}
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;IAErH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;YAqElB,cAAc;CA+B5B"}