@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.
- package/LICENSE +21 -0
- package/README.md +177 -0
- package/SECURITY.md +14 -0
- package/dist/WorktreePool.d.ts +22 -0
- package/dist/WorktreePool.d.ts.map +1 -0
- package/dist/WorktreePool.js +58 -0
- package/dist/WorktreePool.js.map +1 -0
- package/dist/WorktreePool.test.d.ts +2 -0
- package/dist/WorktreePool.test.d.ts.map +1 -0
- package/dist/_virtual/_build-info.js +4 -0
- package/dist/_virtual/_build-info.js.map +1 -0
- package/dist/browserPage.d.ts +5 -0
- package/dist/browserPage.d.ts.map +1 -1
- package/dist/browserPage.js +28 -2
- package/dist/browserPage.js.map +1 -1
- package/dist/commands/acceptCommand.d.ts +2 -1
- package/dist/commands/acceptCommand.d.ts.map +1 -1
- package/dist/commands/acceptCommand.js +15 -8
- package/dist/commands/acceptCommand.js.map +1 -1
- package/dist/commands/checkStabilityCommand.d.ts +12 -0
- package/dist/commands/checkStabilityCommand.d.ts.map +1 -0
- package/dist/commands/checkStabilityCommand.js +84 -0
- package/dist/commands/checkStabilityCommand.js.map +1 -0
- package/dist/commands/compareCommand.d.ts +5 -1
- package/dist/commands/compareCommand.d.ts.map +1 -1
- package/dist/commands/compareCommand.js +56 -71
- package/dist/commands/compareCommand.js.map +1 -1
- package/dist/commands/mcpCommand.d.ts +4 -1
- package/dist/commands/mcpCommand.d.ts.map +1 -1
- package/dist/commands/mcpCommand.js +51 -8
- package/dist/commands/mcpCommand.js.map +1 -1
- package/dist/commands/screenshotCommand.d.ts +9 -2
- package/dist/commands/screenshotCommand.d.ts.map +1 -1
- package/dist/commands/screenshotCommand.js +73 -15
- package/dist/commands/screenshotCommand.js.map +1 -1
- package/dist/commands/serveCommand.d.ts +6 -1
- package/dist/commands/serveCommand.d.ts.map +1 -1
- package/dist/commands/serveCommand.js +104 -23
- package/dist/commands/serveCommand.js.map +1 -1
- package/dist/commands/watchCommand.d.ts +3 -2
- package/dist/commands/watchCommand.d.ts.map +1 -1
- package/dist/commands/watchCommand.js +28 -80
- package/dist/commands/watchCommand.js.map +1 -1
- package/dist/comparison.d.ts +70 -0
- package/dist/comparison.d.ts.map +1 -0
- package/dist/comparison.js +264 -0
- package/dist/comparison.js.map +1 -0
- package/dist/component-explorer-config.schema.json +222 -0
- package/dist/componentExplorer.d.ts +40 -2
- package/dist/componentExplorer.d.ts.map +1 -1
- package/dist/componentExplorer.js +118 -24
- package/dist/componentExplorer.js.map +1 -1
- package/dist/daemon/DaemonContext.d.ts +4 -0
- package/dist/daemon/DaemonContext.d.ts.map +1 -0
- package/dist/daemon/DaemonService.d.ts +146 -21
- package/dist/daemon/DaemonService.d.ts.map +1 -1
- package/dist/daemon/DaemonService.js +620 -123
- package/dist/daemon/DaemonService.js.map +1 -1
- package/dist/daemon/dynamicSessions.test.d.ts +2 -0
- package/dist/daemon/dynamicSessions.test.d.ts.map +1 -0
- package/dist/daemon/lifecycle.d.ts +8 -3
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +27 -10
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/pipeClient.d.ts +6 -1
- package/dist/daemon/pipeClient.d.ts.map +1 -1
- package/dist/daemon/pipeClient.js +101 -8
- package/dist/daemon/pipeClient.js.map +1 -1
- package/dist/daemon/pipeServer.d.ts +2 -1
- package/dist/daemon/pipeServer.d.ts.map +1 -1
- package/dist/daemon/pipeServer.js +56 -6
- package/dist/daemon/pipeServer.js.map +1 -1
- package/dist/daemon/types.d.ts +12 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/version.d.ts +10 -0
- package/dist/daemon/version.d.ts.map +1 -0
- package/dist/daemon/version.js +17 -0
- package/dist/daemon/version.js.map +1 -0
- package/dist/dependencyInstaller.d.ts +2 -2
- package/dist/dependencyInstaller.d.ts.map +1 -1
- package/dist/dependencyInstaller.js +1 -1
- package/dist/dependencyInstaller.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/disposables.js +24 -1
- package/dist/external/vscode-observables/observables/dist/disposables.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js +1 -4
- package/dist/external/vscode-observables/observables/dist/observableInternal/commonFacade/deps.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/index.js +2 -5
- package/dist/external/vscode-observables/observables/dist/observableInternal/index.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js +30 -6
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/consoleObservableLogger.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/baseObservable.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js +12 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/observables/derived.js.map +1 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js +55 -0
- package/dist/external/vscode-observables/observables/dist/observableInternal/utils/utilsCancellation.js.map +1 -0
- package/dist/formatValue.d.ts +2 -0
- package/dist/formatValue.d.ts.map +1 -0
- package/dist/formatValue.js +96 -0
- package/dist/formatValue.js.map +1 -0
- package/dist/formatValue.test.d.ts +2 -0
- package/dist/formatValue.test.d.ts.map +1 -0
- package/dist/git/gitIndexResolver.d.ts +25 -0
- package/dist/git/gitIndexResolver.d.ts.map +1 -0
- package/dist/git/gitIndexResolver.js +91 -0
- package/dist/git/gitIndexResolver.js.map +1 -0
- package/dist/git/gitIndexResolver.test.d.ts +2 -0
- package/dist/git/gitIndexResolver.test.d.ts.map +1 -0
- package/dist/git/gitService.d.ts +2 -0
- package/dist/git/gitService.d.ts.map +1 -1
- package/dist/git/gitService.js +6 -0
- package/dist/git/gitService.js.map +1 -1
- package/dist/git/gitUtils.js +1 -1
- package/dist/git/gitUtils.js.map +1 -1
- package/dist/git/gitWorktreeManager.d.ts +6 -0
- package/dist/git/gitWorktreeManager.d.ts.map +1 -1
- package/dist/git/gitWorktreeManager.js +42 -13
- package/dist/git/gitWorktreeManager.js.map +1 -1
- package/dist/git/gitWorktreeManager.test.d.ts +2 -0
- package/dist/git/gitWorktreeManager.test.d.ts.map +1 -0
- package/dist/git/testUtils.d.ts +13 -0
- package/dist/git/testUtils.d.ts.map +1 -0
- package/dist/httpServer.d.ts +6 -1
- package/dist/httpServer.d.ts.map +1 -1
- package/dist/httpServer.js +30 -10
- package/dist/httpServer.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +7 -1
- package/dist/logger.js.map +1 -1
- package/dist/mcp/McpServer.d.ts +47 -4
- package/dist/mcp/McpServer.d.ts.map +1 -1
- package/dist/mcp/McpServer.js +913 -155
- package/dist/mcp/McpServer.js.map +1 -1
- package/dist/mcp/TaskManager.d.ts +28 -0
- package/dist/mcp/TaskManager.d.ts.map +1 -0
- package/dist/mcp/TaskManager.js +54 -0
- package/dist/mcp/TaskManager.js.map +1 -0
- package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js +137 -0
- package/dist/packages/simple-api/dist/chunk-3R7GHWBM.js.map +1 -0
- package/dist/packages/simple-api/dist/chunk-SGBCNXYH.js +24 -0
- package/dist/packages/simple-api/dist/chunk-SGBCNXYH.js.map +1 -0
- package/dist/packages/simple-api/dist/chunk-TAEFVNPN.js +27 -0
- package/dist/packages/simple-api/dist/chunk-TAEFVNPN.js.map +1 -0
- package/dist/packages/simple-api/dist/express.js +104 -0
- package/dist/packages/simple-api/dist/express.js.map +1 -0
- package/dist/resolveProject.d.ts +21 -0
- package/dist/resolveProject.d.ts.map +1 -0
- package/dist/resolveProject.js +39 -0
- package/dist/resolveProject.js.map +1 -0
- package/dist/utils.d.ts +31 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +49 -0
- package/dist/utils.js.map +1 -0
- package/dist/watchConfig.d.ts +52 -9
- package/dist/watchConfig.d.ts.map +1 -1
- package/dist/watchConfig.js +67 -62
- package/dist/watchConfig.js.map +1 -1
- package/package.json +31 -8
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js +0 -72
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/debuggerRpc.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js +0 -447
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/devToolsLogger.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js +0 -64
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/rpc.js.map +0 -1
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js +0 -52
- package/dist/external/vscode-observables/observables/dist/observableInternal/logging/debugger/utils.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Microsoft Corporation.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE
|
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.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!-- BEGIN MICROSOFT SECURITY.MD V1.0.0 BLOCK -->
|
|
2
|
+
|
|
3
|
+
## Security
|
|
4
|
+
|
|
5
|
+
Microsoft takes the security of our software products and services seriously, which
|
|
6
|
+
includes all source code repositories in our GitHub organizations.
|
|
7
|
+
|
|
8
|
+
**Please do not report security vulnerabilities through public GitHub issues.**
|
|
9
|
+
|
|
10
|
+
For security reporting information, locations, contact information, and policies,
|
|
11
|
+
please review the latest guidance for Microsoft repositories at
|
|
12
|
+
[https://aka.ms/SECURITY.md](https://aka.ms/SECURITY.md).
|
|
13
|
+
|
|
14
|
+
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class WorktreeSlot {
|
|
2
|
+
readonly index: number;
|
|
3
|
+
readonly worktreePath: string;
|
|
4
|
+
private _assignedSession;
|
|
5
|
+
constructor(index: number, worktreePath: string);
|
|
6
|
+
get assignedSession(): string | undefined;
|
|
7
|
+
get isFree(): boolean;
|
|
8
|
+
assign(sessionName: string): void;
|
|
9
|
+
release(): void;
|
|
10
|
+
configDir(configDirRelToGitRoot: string): string;
|
|
11
|
+
}
|
|
12
|
+
export declare class WorktreePool {
|
|
13
|
+
readonly maxSlots: number;
|
|
14
|
+
private readonly _slots;
|
|
15
|
+
constructor(maxSlots: number, worktreeRoot: string);
|
|
16
|
+
allocate(sessionName: string): WorktreeSlot;
|
|
17
|
+
release(sessionName: string): void;
|
|
18
|
+
getSlot(sessionName: string): WorktreeSlot | undefined;
|
|
19
|
+
get freeSlotCount(): number;
|
|
20
|
+
get slots(): readonly WorktreeSlot[];
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=WorktreePool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreePool.d.ts","sourceRoot":"","sources":["../src/WorktreePool.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IAIvB,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM;IAJ9B,OAAO,CAAC,gBAAgB,CAAqB;gBAGnC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM;IAG9B,IAAI,eAAe,IAAI,MAAM,GAAG,SAAS,CAAkC;IAC3E,IAAI,MAAM,IAAI,OAAO,CAAgD;IAErE,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IACjC,OAAO,IAAI,IAAI;IAEf,SAAS,CAAC,qBAAqB,EAAE,MAAM,GAAG,MAAM;CAGhD;AAED,qBAAa,YAAY;IAIvB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAH1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAGvC,QAAQ,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM;IAOrB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY;IAiB3C,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAOlC,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAItD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,KAAK,IAAI,SAAS,YAAY,EAAE,CAEnC;CACD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
|
|
3
|
+
class WorktreeSlot {
|
|
4
|
+
index;
|
|
5
|
+
worktreePath;
|
|
6
|
+
_assignedSession;
|
|
7
|
+
constructor(index, worktreePath) {
|
|
8
|
+
this.index = index;
|
|
9
|
+
this.worktreePath = worktreePath;
|
|
10
|
+
}
|
|
11
|
+
get assignedSession() { return this._assignedSession; }
|
|
12
|
+
get isFree() { return this._assignedSession === undefined; }
|
|
13
|
+
assign(sessionName) { this._assignedSession = sessionName; }
|
|
14
|
+
release() { this._assignedSession = undefined; }
|
|
15
|
+
configDir(configDirRelToGitRoot) {
|
|
16
|
+
return path.resolve(this.worktreePath, configDirRelToGitRoot);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
class WorktreePool {
|
|
20
|
+
maxSlots;
|
|
21
|
+
_slots;
|
|
22
|
+
constructor(maxSlots, worktreeRoot) {
|
|
23
|
+
this.maxSlots = maxSlots;
|
|
24
|
+
this._slots = Array.from({ length: maxSlots }, (_, i) => new WorktreeSlot(i + 1, path.resolve(worktreeRoot, `component-explorer-${i + 1}`)));
|
|
25
|
+
}
|
|
26
|
+
allocate(sessionName) {
|
|
27
|
+
const existing = this._slots.find(s => s.assignedSession === sessionName);
|
|
28
|
+
if (existing) {
|
|
29
|
+
throw new Error(`Session "${sessionName}" already has a worktree slot allocated`);
|
|
30
|
+
}
|
|
31
|
+
const free = this._slots.find(s => s.isFree);
|
|
32
|
+
if (!free) {
|
|
33
|
+
const assigned = this._slots.map(s => ` slot ${s.index}: ${s.assignedSession}`).join('\n');
|
|
34
|
+
throw new Error(`No free worktree slots (max ${this.maxSlots}). ` +
|
|
35
|
+
`Close a session first.\nCurrently assigned:\n${assigned}`);
|
|
36
|
+
}
|
|
37
|
+
free.assign(sessionName);
|
|
38
|
+
return free;
|
|
39
|
+
}
|
|
40
|
+
release(sessionName) {
|
|
41
|
+
const slot = this._slots.find(s => s.assignedSession === sessionName);
|
|
42
|
+
if (slot) {
|
|
43
|
+
slot.release();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
getSlot(sessionName) {
|
|
47
|
+
return this._slots.find(s => s.assignedSession === sessionName);
|
|
48
|
+
}
|
|
49
|
+
get freeSlotCount() {
|
|
50
|
+
return this._slots.filter(s => s.isFree).length;
|
|
51
|
+
}
|
|
52
|
+
get slots() {
|
|
53
|
+
return this._slots;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { WorktreePool, WorktreeSlot };
|
|
58
|
+
//# sourceMappingURL=WorktreePool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreePool.js","sources":["../src/WorktreePool.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorktreePool.test.d.ts","sourceRoot":"","sources":["../src/WorktreePool.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_build-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
package/dist/browserPage.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ILogger } from './logger.js';
|
|
1
2
|
export interface BrowserPageFactory {
|
|
2
3
|
openPage(url: string): Promise<BrowserPage>;
|
|
3
4
|
dispose(): Promise<void>;
|
|
@@ -8,7 +9,11 @@ export interface BrowserPage {
|
|
|
8
9
|
dispose(): Promise<void>;
|
|
9
10
|
}
|
|
10
11
|
export declare class PlaywrightBrowserPageFactory implements BrowserPageFactory {
|
|
12
|
+
readonly headed: boolean;
|
|
13
|
+
readonly timeoutMs: number;
|
|
11
14
|
private _browser;
|
|
15
|
+
private readonly _logger;
|
|
16
|
+
constructor(headed?: boolean, timeoutMs?: number, logger?: ILogger);
|
|
12
17
|
openPage(url: string): Promise<BrowserPage>;
|
|
13
18
|
dispose(): Promise<void>;
|
|
14
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserPage.d.ts","sourceRoot":"","sources":["../src/browserPage.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC3B,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,UAAU,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,qBAAa,4BAA6B,YAAW,kBAAkB;
|
|
1
|
+
{"version":3,"file":"browserPage.d.ts","sourceRoot":"","sources":["../src/browserPage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,aAAa,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC3B,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,UAAU,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3D,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,qBAAa,4BAA6B,YAAW,kBAAkB;IAI1D,QAAQ,CAAC,MAAM,EAAE,OAAO;IAAU,QAAQ,CAAC,SAAS,EAAE,MAAM;IAHxE,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEb,MAAM,GAAE,OAAe,EAAW,SAAS,GAAE,MAAe,EAAE,MAAM,CAAC,EAAE,OAAO;IAI7F,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA0B3C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI9B"}
|
package/dist/browserPage.js
CHANGED
|
@@ -1,12 +1,38 @@
|
|
|
1
|
+
import { nullLogger } from './logger.js';
|
|
2
|
+
|
|
1
3
|
class PlaywrightBrowserPageFactory {
|
|
4
|
+
headed;
|
|
5
|
+
timeoutMs;
|
|
2
6
|
_browser;
|
|
7
|
+
_logger;
|
|
8
|
+
constructor(headed = false, timeoutMs = 30_000, logger) {
|
|
9
|
+
this.headed = headed;
|
|
10
|
+
this.timeoutMs = timeoutMs;
|
|
11
|
+
this._logger = logger ?? nullLogger;
|
|
12
|
+
}
|
|
3
13
|
async openPage(url) {
|
|
4
14
|
if (!this._browser) {
|
|
5
15
|
const { chromium } = await import('playwright');
|
|
6
|
-
this._browser = await chromium.launch();
|
|
16
|
+
this._browser = await chromium.launch({ headless: !this.headed });
|
|
7
17
|
}
|
|
8
18
|
const page = await this._browser.newPage();
|
|
9
|
-
|
|
19
|
+
page.on('console', (msg) => {
|
|
20
|
+
const type = msg.type();
|
|
21
|
+
const text = msg.text();
|
|
22
|
+
if (type === 'error') {
|
|
23
|
+
this._logger.debug(`[browser] error: ${text}`);
|
|
24
|
+
}
|
|
25
|
+
else if (type === 'warning') {
|
|
26
|
+
this._logger.debug(`[browser] warn: ${text}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this._logger.trace(`[browser] ${type}: ${text}`);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
page.on('pageerror', (err) => {
|
|
33
|
+
this._logger.debug(`[browser] uncaught error: ${err.message}`);
|
|
34
|
+
});
|
|
35
|
+
await page.goto(url, { waitUntil: 'networkidle', timeout: this.timeoutMs });
|
|
10
36
|
return new PlaywrightBrowserPage(page);
|
|
11
37
|
}
|
|
12
38
|
async dispose() {
|
package/dist/browserPage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browserPage.js","sources":["../src/browserPage.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browserPage.js","sources":["../src/browserPage.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,8 @@ export declare class AcceptCommand extends Command {
|
|
|
4
4
|
static usage: import("clipanion").Usage;
|
|
5
5
|
readonly verbose: number;
|
|
6
6
|
readonly filter: string | undefined;
|
|
7
|
-
readonly
|
|
7
|
+
readonly project: string;
|
|
8
|
+
readonly screenshotDir: string;
|
|
8
9
|
execute(): Promise<void>;
|
|
9
10
|
}
|
|
10
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;
|
|
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;CA+B9B"}
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import { Command, Option } from 'clipanion';
|
|
2
|
-
import
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { ConsoleLogger, verbosityToLogLevel, logBuildInfo } from '../logger.js';
|
|
3
4
|
import { FileSystemStorage } from '../storage.js';
|
|
5
|
+
import { resolveProject } from '../resolveProject.js';
|
|
4
6
|
|
|
5
7
|
class AcceptCommand extends Command {
|
|
6
|
-
static paths = [['accept']];
|
|
8
|
+
static paths = [['screenshot:accept']];
|
|
7
9
|
static usage = Command.Usage({
|
|
8
|
-
description: 'Promote current screenshots
|
|
10
|
+
description: 'Promote current screenshots to baseline (file-level only)',
|
|
9
11
|
examples: [
|
|
10
|
-
['Accept all', '$0 accept'],
|
|
11
|
-
['Accept specific fixtures', '$0 accept --filter "Button/*"'],
|
|
12
|
+
['Accept all', '$0 screenshot:accept'],
|
|
13
|
+
['Accept specific fixtures', '$0 screenshot:accept --filter "Button/*"'],
|
|
12
14
|
],
|
|
13
15
|
});
|
|
14
16
|
verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
|
|
15
17
|
filter = Option.String('--filter', { required: false, description: 'Filter fixtures by glob pattern' });
|
|
16
|
-
|
|
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' });
|
|
17
20
|
async execute() {
|
|
18
|
-
|
|
19
|
-
const
|
|
21
|
+
const resolved = await resolveProject(this.project);
|
|
22
|
+
const projectDir = resolved.projectDir;
|
|
23
|
+
const _logger = new ConsoleLogger('accept', this.context.stdout, verbosityToLogLevel(this.verbose));
|
|
24
|
+
logBuildInfo(_logger);
|
|
25
|
+
const screenshotPath = path.isAbsolute(this.screenshotDir) ? this.screenshotDir : path.join(projectDir, this.screenshotDir);
|
|
26
|
+
const storage = new FileSystemStorage(screenshotPath);
|
|
20
27
|
let currentFiles = await storage.list('current');
|
|
21
28
|
if (this.filter) {
|
|
22
29
|
const regex = new RegExp('^current/' + this.filter.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acceptCommand.js","sources":["../../src/commands/acceptCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"acceptCommand.js","sources":["../../src/commands/acceptCommand.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Command } from 'clipanion';
|
|
2
|
+
export declare class CheckStabilityCommand extends Command {
|
|
3
|
+
static paths: string[][];
|
|
4
|
+
static usage: import("clipanion").Usage;
|
|
5
|
+
readonly verbose: number;
|
|
6
|
+
readonly project: string;
|
|
7
|
+
readonly labelPattern: string | undefined;
|
|
8
|
+
readonly headed: boolean;
|
|
9
|
+
readonly timeout: string;
|
|
10
|
+
execute(): Promise<number>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=checkStabilityCommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkStabilityCommand.d.ts","sourceRoot":"","sources":["../../src/commands/checkStabilityCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAQ5C,qBAAa,qBAAsB,SAAQ,OAAO;IACjD,OAAgB,KAAK,aAAyB;IAE9C,OAAgB,KAAK,4BAMlB;IAEH,QAAQ,CAAC,OAAO,SAAsG;IACtH,QAAQ,CAAC,OAAO,SAAuI;IACvJ,QAAQ,CAAC,YAAY,qBAA+I;IACpK,QAAQ,CAAC,MAAM,UAAwG;IACvH,QAAQ,CAAC,OAAO,SAA+G;IAEzH,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;CAwEhC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Command, Option } from 'clipanion';
|
|
2
|
+
import { PlaywrightBrowserPageFactory } from '../browserPage.js';
|
|
3
|
+
import { BrowserComponentExplorer } from '../componentExplorer.js';
|
|
4
|
+
import { DefaultComponentExplorerHttpServerFactory } from '../httpServer.js';
|
|
5
|
+
import { ConsoleLogger, verbosityToLogLevel, logBuildInfo } from '../logger.js';
|
|
6
|
+
import { resolveProject, resolvedProjectToViteProjectRef } from '../resolveProject.js';
|
|
7
|
+
import { contentHash } from '../screenshotCache.js';
|
|
8
|
+
|
|
9
|
+
class CheckStabilityCommand extends Command {
|
|
10
|
+
static paths = [['check-stability']];
|
|
11
|
+
static usage = Command.Usage({
|
|
12
|
+
description: 'Check rendering stability of fixtures (outputs JSON)',
|
|
13
|
+
examples: [
|
|
14
|
+
['Check all fixtures', '$0 check-stability'],
|
|
15
|
+
['Filter by label', '$0 check-stability --label-pattern "theme:dark"'],
|
|
16
|
+
],
|
|
17
|
+
});
|
|
18
|
+
verbose = Option.Counter('-v,--verbose', 0, { description: 'Increase log verbosity (-v debug, -vv trace)' });
|
|
19
|
+
project = Option.String('-p,--project', process.cwd(), { description: 'Project: a directory, vite config file, or component-explorer.json' });
|
|
20
|
+
labelPattern = Option.String('--label-pattern', { required: false, description: 'RegExp to filter fixtures by label (matched against inherited labels)' });
|
|
21
|
+
headed = Option.Boolean('--headed', false, { description: 'Show the browser window (useful for debugging)' });
|
|
22
|
+
timeout = Option.String('--timeout', '30000', { description: 'Navigation timeout in milliseconds (default: 30000)' });
|
|
23
|
+
async execute() {
|
|
24
|
+
const logger = new ConsoleLogger('check-stability', this.context.stderr, verbosityToLogLevel(this.verbose));
|
|
25
|
+
logBuildInfo(logger);
|
|
26
|
+
let labelRegex;
|
|
27
|
+
if (this.labelPattern) {
|
|
28
|
+
try {
|
|
29
|
+
labelRegex = new RegExp(this.labelPattern);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
this.context.stderr.write(`Error: Invalid label pattern: ${this.labelPattern}\n`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const resolved = await resolveProject(this.project);
|
|
37
|
+
const viteProject = resolvedProjectToViteProjectRef(resolved);
|
|
38
|
+
const serverFactory = new DefaultComponentExplorerHttpServerFactory();
|
|
39
|
+
const browserFactory = new PlaywrightBrowserPageFactory(this.headed, Number(this.timeout));
|
|
40
|
+
let server;
|
|
41
|
+
let explorer;
|
|
42
|
+
try {
|
|
43
|
+
this.context.stderr.write('Starting Vite dev server...\n');
|
|
44
|
+
server = await serverFactory.createViteServer(viteProject, { logger });
|
|
45
|
+
this.context.stderr.write(`Server running at ${server.url}\n`);
|
|
46
|
+
explorer = new BrowserComponentExplorer(browserFactory, server, logger);
|
|
47
|
+
const allFixtures = await explorer.listFixtures();
|
|
48
|
+
const fixtures = labelRegex
|
|
49
|
+
? allFixtures.filter(f => f.labels.some(l => labelRegex.test(l)))
|
|
50
|
+
: allFixtures;
|
|
51
|
+
this.context.stderr.write(`Found ${fixtures.length} fixture(s)${labelRegex ? ` (filtered from ${allFixtures.length})` : ''}\n`);
|
|
52
|
+
const results = [];
|
|
53
|
+
for (let i = 0; i < fixtures.length; i++) {
|
|
54
|
+
const fixture = fixtures[i];
|
|
55
|
+
this.context.stderr.write(`[${i + 1}/${fixtures.length}] Checking ${fixture.fixtureId}...`);
|
|
56
|
+
const result = await explorer.screenshotFixtureStabilityCheck(fixture.fixtureId);
|
|
57
|
+
const hashes = result.screenshots.map(s => contentHash(s.image));
|
|
58
|
+
const isStable = hashes[0] === hashes[1] && hashes[1] === hashes[2];
|
|
59
|
+
results.push({
|
|
60
|
+
fixtureId: fixture.fixtureId,
|
|
61
|
+
isStable,
|
|
62
|
+
screenshots: result.screenshots.map((s, j) => ({ hash: hashes[j], delayMs: s.delayMs })),
|
|
63
|
+
});
|
|
64
|
+
this.context.stderr.write(` ${isStable ? 'stable' : 'UNSTABLE'}\n`);
|
|
65
|
+
}
|
|
66
|
+
const stable = results.filter(r => r.isStable).length;
|
|
67
|
+
const unstable = results.length - stable;
|
|
68
|
+
const output = {
|
|
69
|
+
fixtures: results,
|
|
70
|
+
summary: { total: results.length, stable, unstable },
|
|
71
|
+
};
|
|
72
|
+
this.context.stdout.write(JSON.stringify(output, null, 2) + '\n');
|
|
73
|
+
return unstable > 0 ? 1 : 0;
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
await explorer?.dispose();
|
|
77
|
+
await browserFactory.dispose();
|
|
78
|
+
await server?.dispose();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export { CheckStabilityCommand };
|
|
84
|
+
//# sourceMappingURL=checkStabilityCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkStabilityCommand.js","sources":["../../src/commands/checkStabilityCommand.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;AAQM,MAAO,qBAAsB,SAAQ,OAAO,CAAA;IACjD,OAAgB,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAE7C,IAAA,OAAgB,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;AACrC,QAAA,WAAW,EAAE,sDAAsD;AACnE,QAAA,QAAQ,EAAE;YACT,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;YAC5C,CAAC,iBAAiB,EAAE,iDAAiD,CAAC;AACtE,SAAA;AACD,KAAA,CAAC;AAEO,IAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE,CAAC;AAC5G,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,EAAE,oEAAoE,EAAE,CAAC;AAC7I,IAAA,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,uEAAuE,EAAE,CAAC;AAC1J,IAAA,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,gDAAgD,EAAE,CAAC;AAC7G,IAAA,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;AAE9H,IAAA,MAAM,OAAO,GAAA;QACZ,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3G,YAAY,CAAC,MAAM,CAAC;AAEpB,QAAA,IAAI,UAA8B;AAClC,QAAA,IAAI,IAAI,CAAC,YAAY,EAAE;AACtB,YAAA,IAAI;gBACH,UAAU,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;YAC3C;AAAE,YAAA,MAAM;AACP,gBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,8BAAA,EAAiC,IAAI,CAAC,YAAY,CAAA,EAAA,CAAI,CAAC;AACjF,gBAAA,OAAO,CAAC;YACT;QACD;QAEA,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;AACnD,QAAA,MAAM,WAAW,GAAG,+BAA+B,CAAC,QAAQ,CAAC;AAE7D,QAAA,MAAM,aAAa,GAAG,IAAI,yCAAyC,EAAE;AACrE,QAAA,MAAM,cAAc,GAAG,IAAI,4BAA4B,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE1F,QAAA,IAAI,MAAM;AACV,QAAA,IAAI,QAAQ;AACZ,QAAA,IAAI;YACH,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC;AAC1D,YAAA,MAAM,GAAG,MAAM,aAAa,CAAC,gBAAgB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC;AACtE,YAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,kBAAA,EAAqB,MAAM,CAAC,GAAG,CAAA,EAAA,CAAI,CAAC;YAE9D,QAAQ,GAAG,IAAI,wBAAwB,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC;AACvE,YAAA,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE;YAEjD,MAAM,QAAQ,GAAG;kBACd,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;kBAC9D,WAAW;YAEd,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,MAAA,EAAS,QAAQ,CAAC,MAAM,CAAA,WAAA,EAAc,UAAU,GAAG,CAAA,gBAAA,EAAmB,WAAW,CAAC,MAAM,CAAA,CAAA,CAAG,GAAG,EAAE,CAAA,EAAA,CAAI,CAAC;YAE/H,MAAM,OAAO,GAAiG,EAAE;AAEhH,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACzC,gBAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,QAAQ,CAAC,MAAM,CAAA,WAAA,EAAc,OAAO,CAAC,SAAS,CAAA,GAAA,CAAK,CAAC;gBAE3F,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,+BAA+B,CAAC,OAAO,CAAC,SAAS,CAAC;AAChF,gBAAA,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;gBAEnE,OAAO,CAAC,IAAI,CAAC;oBACZ,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,QAAQ;AACR,oBAAA,WAAW,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AACxF,iBAAA,CAAC;AAEF,gBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,CAAA,EAAI,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAA,EAAA,CAAI,CAAC;YACpE;AAEA,YAAA,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM;AACrD,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,MAAM;AAExC,YAAA,MAAM,MAAM,GAAG;AACd,gBAAA,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE;aACpD;YAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;YAEjE,OAAO,QAAQ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAC5B;gBAAU;AACT,YAAA,MAAM,QAAQ,EAAE,OAAO,EAAE;AACzB,YAAA,MAAM,cAAc,CAAC,OAAO,EAAE;AAC9B,YAAA,MAAM,MAAM,EAAE,OAAO,EAAE;QACxB;IACD;;;;;"}
|
|
@@ -3,7 +3,11 @@ export declare class CompareCommand extends Command {
|
|
|
3
3
|
static paths: string[][];
|
|
4
4
|
static usage: import("clipanion").Usage;
|
|
5
5
|
readonly verbose: number;
|
|
6
|
-
readonly
|
|
6
|
+
readonly filter: string | undefined;
|
|
7
|
+
readonly project: string;
|
|
8
|
+
readonly baseline: string;
|
|
9
|
+
readonly current: string;
|
|
10
|
+
readonly report: string | undefined;
|
|
7
11
|
execute(): Promise<number>;
|
|
8
12
|
}
|
|
9
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;
|
|
1
|
+
{"version":3,"file":"compareCommand.d.ts","sourceRoot":"","sources":["../../src/commands/compareCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAS5C,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;CAoDhC"}
|