uisnap 0.1.0
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/.claude/settings.local.json +26 -0
- package/.claude/skills/uisnap/README.md +48 -0
- package/.claude/skills/uisnap/REFERENCE.md +1261 -0
- package/.claude/skills/uisnap/SETUP.md +75 -0
- package/.claude/skills/uisnap/SKILL.md +130 -0
- package/.claude/skills/uisnap/snapshot-capture-and-analysis.md +452 -0
- package/.claude/skills/uisnap/trace-capture-and-analysis.md +472 -0
- package/CHANGELOG.md +96 -0
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/SKILL-INSTALLATION.md +103 -0
- package/dist/analyze-console.d.ts +3 -0
- package/dist/analyze-console.d.ts.map +1 -0
- package/dist/analyze-console.js +153 -0
- package/dist/analyze-console.js.map +1 -0
- package/dist/analyze-network.d.ts +3 -0
- package/dist/analyze-network.d.ts.map +1 -0
- package/dist/analyze-network.js +156 -0
- package/dist/analyze-network.js.map +1 -0
- package/dist/chrome-trace-analyze.d.ts +3 -0
- package/dist/chrome-trace-analyze.d.ts.map +1 -0
- package/dist/chrome-trace-analyze.js +119 -0
- package/dist/chrome-trace-analyze.js.map +1 -0
- package/dist/chrome-trace-import.d.ts +3 -0
- package/dist/chrome-trace-import.d.ts.map +1 -0
- package/dist/chrome-trace-import.js +90 -0
- package/dist/chrome-trace-import.js.map +1 -0
- package/dist/commands/snapshot.d.ts +4 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +154 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/diagnose.d.ts +3 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +244 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/pw.d.ts +3 -0
- package/dist/pw.d.ts.map +1 -0
- package/dist/pw.js +289 -0
- package/dist/pw.js.map +1 -0
- package/dist/query-a11y.d.ts +3 -0
- package/dist/query-a11y.d.ts.map +1 -0
- package/dist/query-a11y.js +208 -0
- package/dist/query-a11y.js.map +1 -0
- package/dist/trace-import.d.ts +3 -0
- package/dist/trace-import.d.ts.map +1 -0
- package/dist/trace-import.js +93 -0
- package/dist/trace-import.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/chromeTraceAnalyze.d.ts +40 -0
- package/dist/utils/chromeTraceAnalyze.d.ts.map +1 -0
- package/dist/utils/chromeTraceAnalyze.js +113 -0
- package/dist/utils/chromeTraceAnalyze.js.map +1 -0
- package/dist/utils/chromeTraceHelpers.d.ts +4 -0
- package/dist/utils/chromeTraceHelpers.d.ts.map +1 -0
- package/dist/utils/chromeTraceHelpers.js +68 -0
- package/dist/utils/chromeTraceHelpers.js.map +1 -0
- package/dist/utils/chromeTraceImport.d.ts +14 -0
- package/dist/utils/chromeTraceImport.d.ts.map +1 -0
- package/dist/utils/chromeTraceImport.js +77 -0
- package/dist/utils/chromeTraceImport.js.map +1 -0
- package/dist/utils/helpers.d.ts +3 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +88 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/projectRoot.d.ts +2 -0
- package/dist/utils/projectRoot.d.ts.map +1 -0
- package/dist/utils/projectRoot.js +56 -0
- package/dist/utils/projectRoot.js.map +1 -0
- package/dist/utils/traceHelpers.d.ts +4 -0
- package/dist/utils/traceHelpers.d.ts.map +1 -0
- package/dist/utils/traceHelpers.js +67 -0
- package/dist/utils/traceHelpers.js.map +1 -0
- package/dist/utils/traceImport.d.ts +20 -0
- package/dist/utils/traceImport.d.ts.map +1 -0
- package/dist/utils/traceImport.js +124 -0
- package/dist/utils/traceImport.js.map +1 -0
- package/dist/utils/webVitals.d.ts +9 -0
- package/dist/utils/webVitals.d.ts.map +1 -0
- package/dist/utils/webVitals.js +54 -0
- package/dist/utils/webVitals.js.map +1 -0
- package/examples/login-flow.js +37 -0
- package/examples/scroll-perf-trace.js +43 -0
- package/examples/simple-capture.js +28 -0
- package/package.json +74 -0
package/README.md
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# uisnap
|
|
2
|
+
|
|
3
|
+
UI snapshot debugging for frontend development. Capture browser state to disk once, query efficiently many times.
|
|
4
|
+
|
|
5
|
+
## Philosophy
|
|
6
|
+
|
|
7
|
+
**Capture once, query many** - Expensive browser operations write to disk once. Cheap local queries analyze data repeatedly without re-running the browser. Achieves ~17x token reduction vs. traditional debugging approaches.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g uisnap
|
|
13
|
+
npx playwright install chromium
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Installing the Claude Code Skill
|
|
17
|
+
|
|
18
|
+
To teach Claude Code when and how to use this toolkit:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# For team sharing (recommended):
|
|
22
|
+
mkdir -p .claude/skills
|
|
23
|
+
cp -r node_modules/uisnap/.claude/skills/uisnap .claude/skills/
|
|
24
|
+
git add .claude/skills/
|
|
25
|
+
|
|
26
|
+
# For personal use only:
|
|
27
|
+
mkdir -p ~/.claude/skills
|
|
28
|
+
cp -r node_modules/uisnap/.claude/skills/uisnap ~/.claude/skills/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
See [SKILL-INSTALLATION.md](./SKILL-INSTALLATION.md) for details.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Capture page state (auto-generates timestamped directory)
|
|
37
|
+
uisnap snapshot https://example.com
|
|
38
|
+
|
|
39
|
+
# Analyze the latest snapshot using the "latest" symlink
|
|
40
|
+
uisnap-analyze-console snapshots/example.com/latest/console.jsonl
|
|
41
|
+
uisnap-analyze-network snapshots/example.com/latest/network.jsonl
|
|
42
|
+
uisnap-query-a11y snapshots/example.com/latest/a11y.yaml --links
|
|
43
|
+
|
|
44
|
+
# Or specify explicit path for baselines/comparisons
|
|
45
|
+
uisnap snapshot https://example.com snapshots/baseline/
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
### Capture Commands
|
|
51
|
+
|
|
52
|
+
**Snapshot** - Capture full page state:
|
|
53
|
+
```bash
|
|
54
|
+
uisnap snapshot <url> [output-dir]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
If `output-dir` is omitted, auto-generates: `snapshots/{hostname}/{timestamp}/`
|
|
58
|
+
|
|
59
|
+
**Chrome Performance Trace** - Capture browser performance metrics:
|
|
60
|
+
```bash
|
|
61
|
+
uisnap exec chrome-perf-trace.js <url> [output-dir]
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Captures Chrome DevTools performance trace with automatic DuckDB import. Analyzes paint, layout, JavaScript execution, and other browser internals.
|
|
65
|
+
|
|
66
|
+
**Auto-generated structure:**
|
|
67
|
+
```
|
|
68
|
+
snapshots/
|
|
69
|
+
├── example.com/
|
|
70
|
+
│ ├── 2025-12-25-143052/
|
|
71
|
+
│ ├── 2025-12-25-144315/
|
|
72
|
+
│ └── latest -> 2025-12-25-144315/ (symlink to most recent)
|
|
73
|
+
└── myapp.com/
|
|
74
|
+
└── ...
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Each snapshot captures:
|
|
78
|
+
- `a11y.yaml` - ARIA accessibility snapshot
|
|
79
|
+
- `console.jsonl` - Console messages (one JSON per line)
|
|
80
|
+
- `network.jsonl` - Network requests (one JSON per line)
|
|
81
|
+
- `metadata.json` - Page metadata (title, URL, viewport, timestamp)
|
|
82
|
+
|
|
83
|
+
**Exec** - Execute custom scripts for multi-step flows or custom data extraction:
|
|
84
|
+
```bash
|
|
85
|
+
uisnap exec <script.js> <url> [output-dir]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If `output-dir` is omitted, auto-generates: `snapshots/{hostname}/{script-name}-{timestamp}/`
|
|
89
|
+
|
|
90
|
+
Scripts have access to:
|
|
91
|
+
- `page, context, browser` - Playwright instances
|
|
92
|
+
- `utils.captureStep(page, name, action)` - Auto-capture steps with numbering
|
|
93
|
+
- `utils.writeJson, writeJsonl, appendJsonl` - Data writing helpers
|
|
94
|
+
- `fs, path` - Node.js modules
|
|
95
|
+
- `args` - Remaining command-line arguments
|
|
96
|
+
|
|
97
|
+
### Analysis Commands
|
|
98
|
+
|
|
99
|
+
**Analyze Console**:
|
|
100
|
+
```bash
|
|
101
|
+
uisnap-analyze-console <console.jsonl>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Provides:
|
|
105
|
+
- Message counts by type (error, warning, log)
|
|
106
|
+
- Grouped errors with counts and locations
|
|
107
|
+
- Grouped warnings with counts and locations
|
|
108
|
+
|
|
109
|
+
**Analyze Network**:
|
|
110
|
+
```bash
|
|
111
|
+
uisnap-analyze-network <network.jsonl>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Provides:
|
|
115
|
+
- Request counts by resource type, method, status
|
|
116
|
+
- Failed requests (4xx, 5xx)
|
|
117
|
+
- Slow requests (>1s)
|
|
118
|
+
- Requests by domain
|
|
119
|
+
|
|
120
|
+
**Query A11y**:
|
|
121
|
+
```bash
|
|
122
|
+
uisnap-query-a11y <a11y.yaml> <query>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Queries:
|
|
126
|
+
- `--buttons` - List all buttons
|
|
127
|
+
- `--links` - List all links
|
|
128
|
+
- `--headings` - List all headings
|
|
129
|
+
- `--inputs` - List all input fields
|
|
130
|
+
- `--interactive` - List all interactive elements
|
|
131
|
+
- `--images` - List all images
|
|
132
|
+
- `<text>` - Search by text content
|
|
133
|
+
|
|
134
|
+
**Analyze Chrome Trace**:
|
|
135
|
+
```bash
|
|
136
|
+
uisnap-chrome-trace-analyze <trace.db> [options]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Options:
|
|
140
|
+
- `--long-tasks` - Show tasks over threshold (default: 50ms)
|
|
141
|
+
- `--js-time` - Show JavaScript execution time breakdown
|
|
142
|
+
- `--layout-paint` - Show layout and paint performance
|
|
143
|
+
- `--threshold=N` - Set threshold in ms (default: 50)
|
|
144
|
+
- `--full` - Show all details
|
|
145
|
+
|
|
146
|
+
Progressive disclosure: Default shows summary with hints for next steps.
|
|
147
|
+
|
|
148
|
+
**Import Chrome Trace** (manual import if needed):
|
|
149
|
+
```bash
|
|
150
|
+
uisnap-chrome-trace-import <trace.json> <output.db>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Imports Chrome DevTools trace JSON into queryable DuckDB database. Usually not needed since chrome-perf-trace.js auto-imports.
|
|
154
|
+
|
|
155
|
+
## Example Workflow
|
|
156
|
+
|
|
157
|
+
### Basic Debugging
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# 1. Capture page state (creates timestamped snapshot)
|
|
161
|
+
uisnap snapshot https://myapp.com
|
|
162
|
+
|
|
163
|
+
# 2. Check for errors (use "latest" for convenience)
|
|
164
|
+
uisnap-analyze-console snapshots/myapp.com/latest/console.jsonl
|
|
165
|
+
|
|
166
|
+
# 3. Check network failures
|
|
167
|
+
uisnap-analyze-network snapshots/myapp.com/latest/network.jsonl
|
|
168
|
+
|
|
169
|
+
# 4. Find the submit button
|
|
170
|
+
uisnap-query-a11y snapshots/myapp.com/latest/a11y.yaml "Submit"
|
|
171
|
+
|
|
172
|
+
# 5. Make fixes, capture again - never overwrites!
|
|
173
|
+
uisnap snapshot https://myapp.com
|
|
174
|
+
|
|
175
|
+
# 6. Analyze latest results
|
|
176
|
+
uisnap-analyze-console snapshots/myapp.com/latest/console.jsonl
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Iterative Debugging
|
|
180
|
+
|
|
181
|
+
The auto-timestamped structure is perfect for iterative debugging:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# First attempt
|
|
185
|
+
uisnap snapshot https://myapp.com
|
|
186
|
+
# Creates: snapshots/myapp.com/2025-12-25-143052/
|
|
187
|
+
|
|
188
|
+
# Make code changes...
|
|
189
|
+
|
|
190
|
+
# Second attempt
|
|
191
|
+
uisnap snapshot https://myapp.com
|
|
192
|
+
# Creates: snapshots/myapp.com/2025-12-25-144315/
|
|
193
|
+
|
|
194
|
+
# "latest" always points to most recent
|
|
195
|
+
uisnap-query-a11y snapshots/myapp.com/latest/a11y.yaml --buttons
|
|
196
|
+
|
|
197
|
+
# View history
|
|
198
|
+
ls snapshots/myapp.com/
|
|
199
|
+
# 2025-12-25-143052/
|
|
200
|
+
# 2025-12-25-144315/
|
|
201
|
+
# latest -> 2025-12-25-144315/
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Regression Testing
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Before deployment (use explicit path for baseline)
|
|
208
|
+
uisnap snapshot https://myapp.com snapshots/baseline/
|
|
209
|
+
|
|
210
|
+
# After deployment (auto-generated)
|
|
211
|
+
uisnap snapshot https://myapp.com
|
|
212
|
+
|
|
213
|
+
# Compare baseline vs latest (TODO: implement compare command)
|
|
214
|
+
# compare snapshots/baseline/ snapshots/myapp.com/latest/
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Performance Analysis
|
|
218
|
+
|
|
219
|
+
**Initial page load:**
|
|
220
|
+
```bash
|
|
221
|
+
# Snapshot captures everything including Chrome trace
|
|
222
|
+
uisnap snapshot https://myapp.com
|
|
223
|
+
uisnap-diagnose snapshots/myapp.com/latest/ --performance
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Continuous tracing (scroll, animations, interactions):**
|
|
227
|
+
```bash
|
|
228
|
+
# Use the scroll-perf example or write your own
|
|
229
|
+
uisnap exec examples/scroll-perf-trace.js https://myapp.com
|
|
230
|
+
|
|
231
|
+
# 2. Start with summary
|
|
232
|
+
uisnap-chrome-trace-analyze snapshots/myapp.com/latest/chrome-trace.db
|
|
233
|
+
# Shows: Total tasks, duration, hints for next steps
|
|
234
|
+
|
|
235
|
+
# 3. Identify long blocking tasks
|
|
236
|
+
uisnap-chrome-trace-analyze snapshots/myapp.com/latest/chrome-trace.db --long-tasks
|
|
237
|
+
# Shows: Tasks over 50ms with timestamps
|
|
238
|
+
|
|
239
|
+
# 4. Analyze JavaScript execution
|
|
240
|
+
uisnap-chrome-trace-analyze snapshots/myapp.com/latest/chrome-trace.db --js-time
|
|
241
|
+
# Shows: JS execution breakdown by type (total, avg, max)
|
|
242
|
+
|
|
243
|
+
# 5. Check layout/paint performance
|
|
244
|
+
uisnap-chrome-trace-analyze snapshots/myapp.com/latest/chrome-trace.db --layout-paint
|
|
245
|
+
# Shows: Layout and paint operation counts and timings
|
|
246
|
+
|
|
247
|
+
# 6. See everything at once
|
|
248
|
+
uisnap-chrome-trace-analyze snapshots/myapp.com/latest/chrome-trace.db --full
|
|
249
|
+
|
|
250
|
+
# 7. Custom queries with DuckDB (advanced)
|
|
251
|
+
duckdb snapshots/myapp.com/latest/chrome-trace.db
|
|
252
|
+
> SELECT name, dur_ms FROM tasks WHERE name LIKE '%Paint%' ORDER BY dur_ms DESC LIMIT 10;
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Custom Scripts
|
|
256
|
+
|
|
257
|
+
### Multi-Step Flows
|
|
258
|
+
|
|
259
|
+
Use `utils.captureStep()` for multi-step interactions with automatic capture:
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
// login-flow.js
|
|
263
|
+
// Usage: uisnap exec login-flow.js https://myapp.com
|
|
264
|
+
|
|
265
|
+
// Step 1: Navigate
|
|
266
|
+
await utils.captureStep(page, 'goto-login', async () => {
|
|
267
|
+
await page.goto('https://myapp.com/login');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Step 2: Fill email (using Playwright's role-based selectors)
|
|
271
|
+
await utils.captureStep(page, 'fill-email', async () => {
|
|
272
|
+
await page.getByLabel('Email').fill('test@example.com');
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Step 3: Submit
|
|
276
|
+
await utils.captureStep(page, 'click-submit', async () => {
|
|
277
|
+
await page.getByRole('button', { name: 'Submit' }).click();
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Creates:
|
|
282
|
+
```
|
|
283
|
+
snapshots/myapp.com/login-flow-2025-12-25-143052/
|
|
284
|
+
├── step-1-goto-login/
|
|
285
|
+
│ ├── a11y.yaml
|
|
286
|
+
│ └── metadata.json
|
|
287
|
+
├── step-2-fill-email/
|
|
288
|
+
│ └── ...
|
|
289
|
+
└── step-3-click-submit/
|
|
290
|
+
└── ...
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Simple Data Extraction
|
|
294
|
+
|
|
295
|
+
For custom data extraction without step capture:
|
|
296
|
+
|
|
297
|
+
```javascript
|
|
298
|
+
// extract-data.js
|
|
299
|
+
await page.goto('https://example.com');
|
|
300
|
+
|
|
301
|
+
const data = await page.evaluate(() => {
|
|
302
|
+
return {
|
|
303
|
+
links: Array.from(document.links).map(l => l.href),
|
|
304
|
+
headings: Array.from(document.querySelectorAll('h1')).map(h => h.textContent),
|
|
305
|
+
};
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
utils.writeJson('data.json', data);
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Output Formats
|
|
312
|
+
|
|
313
|
+
### ARIA Snapshot (YAML)
|
|
314
|
+
|
|
315
|
+
```yaml
|
|
316
|
+
- heading "Example Domain" [level=1]
|
|
317
|
+
- paragraph: This domain is for use in examples.
|
|
318
|
+
- link "Learn more":
|
|
319
|
+
- /url: https://iana.org/domains/example
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Console Logs (JSONL)
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
{"timestamp":"2025-12-25T10:30:00.000Z","type":"error","text":"Failed to load","location":{"url":"https://example.com/app.js","lineNumber":42}}
|
|
326
|
+
{"timestamp":"2025-12-25T10:30:01.000Z","type":"log","text":"User clicked submit","location":{"url":"https://example.com/app.js","lineNumber":100}}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Network Requests (JSONL)
|
|
330
|
+
|
|
331
|
+
```json
|
|
332
|
+
{"url":"https://api.example.com/users","status":200,"statusText":"OK","method":"GET","resourceType":"fetch","timing":{"startTime":1234.5,"responseEnd":1456.7}}
|
|
333
|
+
{"url":"https://api.example.com/submit","status":500,"statusText":"Internal Server Error","method":"POST","resourceType":"fetch"}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## Token Efficiency
|
|
337
|
+
|
|
338
|
+
Traditional approach:
|
|
339
|
+
- Full DOM: ~15,000 tokens
|
|
340
|
+
- Console logs: ~8,000 tokens
|
|
341
|
+
- Screenshots: ~10,000 tokens
|
|
342
|
+
- **Total: ~40,000 tokens**
|
|
343
|
+
|
|
344
|
+
This toolkit:
|
|
345
|
+
- Capture to disk: ~2,000 tokens (one-time)
|
|
346
|
+
- Analyze summaries: ~100 tokens
|
|
347
|
+
- Query results: ~200 tokens
|
|
348
|
+
- **Total: ~2,350 tokens (~17x reduction)**
|
|
349
|
+
|
|
350
|
+
Chrome performance traces:
|
|
351
|
+
- Raw 36MB trace JSON: ~9,000,000 tokens
|
|
352
|
+
- DuckDB import: ~100 tokens (one-time)
|
|
353
|
+
- Canned query results: ~100-500 tokens
|
|
354
|
+
- **Total: ~600 tokens (~18,000x reduction)**
|
|
355
|
+
|
|
356
|
+
## Development
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
# Clone and install
|
|
360
|
+
git clone https://github.com/tonyhschu/uisnap
|
|
361
|
+
cd uisnap
|
|
362
|
+
npm install
|
|
363
|
+
|
|
364
|
+
# Build
|
|
365
|
+
npm run build
|
|
366
|
+
|
|
367
|
+
# Test locally
|
|
368
|
+
node dist/pw.js snapshot https://example.com test-output/
|
|
369
|
+
|
|
370
|
+
# Deploy skill to local Claude Code
|
|
371
|
+
./deploy-skill.sh
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Local Deployment Script
|
|
375
|
+
|
|
376
|
+
The `deploy-skill.sh` script copies the skill to `~/.claude/skills/` making it available to all Claude Code instances on your machine:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
./deploy-skill.sh
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
This removes any existing version and installs the latest skill instructions.
|
|
383
|
+
|
|
384
|
+
## License
|
|
385
|
+
|
|
386
|
+
MIT
|
|
387
|
+
|
|
388
|
+
## Contributing
|
|
389
|
+
|
|
390
|
+
See [.claude/skills/uisnap/SKILL.md](./.claude/skills/uisnap/SKILL.md) for guidance on working with this codebase in Claude Code.
|
|
391
|
+
|
|
392
|
+
For detailed reference:
|
|
393
|
+
- Snapshot debugging: [snapshot-capture-and-analysis.md](./.claude/skills/uisnap/snapshot-capture-and-analysis.md)
|
|
394
|
+
- Performance debugging: [trace-capture-and-analysis.md](./.claude/skills/uisnap/trace-capture-and-analysis.md)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Installing the uisnap Skill
|
|
2
|
+
|
|
3
|
+
This toolkit comes with a Claude Code Skill that teaches Claude when and how to use it.
|
|
4
|
+
|
|
5
|
+
## Quick Install
|
|
6
|
+
|
|
7
|
+
### 1. Install the Toolkit Globally
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g uisnap
|
|
11
|
+
npx playwright install chromium
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. Install the Skill
|
|
15
|
+
|
|
16
|
+
**For team sharing (recommended):**
|
|
17
|
+
|
|
18
|
+
In your project root:
|
|
19
|
+
```bash
|
|
20
|
+
mkdir -p .claude/skills
|
|
21
|
+
cp -r node_modules/uisnap/.claude/skills/uisnap .claude/skills/
|
|
22
|
+
git add .claude/skills/uisnap/
|
|
23
|
+
git commit -m "Add uisnap skill"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**For personal use only:**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
mkdir -p ~/.claude/skills
|
|
30
|
+
cp -r node_modules/uisnap/.claude/skills/uisnap ~/.claude/skills/
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 3. Verify
|
|
34
|
+
|
|
35
|
+
Ask Claude: "Can you help me debug console errors on example.com?"
|
|
36
|
+
|
|
37
|
+
Claude should automatically activate the uisnap skill and use the toolkit.
|
|
38
|
+
|
|
39
|
+
## Manual Skill Installation
|
|
40
|
+
|
|
41
|
+
If you're developing the toolkit locally:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# In this repository
|
|
45
|
+
mkdir -p ~/.claude/skills/uisnap
|
|
46
|
+
cp .claude/skills/uisnap/SKILL.md ~/.claude/skills/uisnap/
|
|
47
|
+
cp .claude/skills/uisnap/SETUP.md ~/.claude/skills/uisnap/
|
|
48
|
+
cp .claude/skills/uisnap/REFERENCE.md ~/.claude/skills/uisnap/
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Testing the Skill
|
|
52
|
+
|
|
53
|
+
Try these prompts to verify the skill activates:
|
|
54
|
+
|
|
55
|
+
- "Debug console errors on https://myapp.com"
|
|
56
|
+
- "Help me test the login flow on https://myapp.com"
|
|
57
|
+
- "Why is the submit button not working?"
|
|
58
|
+
- "Check network requests on https://myapp.com"
|
|
59
|
+
- "Analyze the accessibility tree on this page"
|
|
60
|
+
|
|
61
|
+
## Skill Location
|
|
62
|
+
|
|
63
|
+
After installation, the skill files are at:
|
|
64
|
+
|
|
65
|
+
**Project skill:**
|
|
66
|
+
```
|
|
67
|
+
your-project/
|
|
68
|
+
└── .claude/
|
|
69
|
+
└── skills/
|
|
70
|
+
└── uisnap/
|
|
71
|
+
├── SKILL.md (main skill file)
|
|
72
|
+
├── SETUP.md (installation guide)
|
|
73
|
+
└── REFERENCE.md (detailed spec)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Personal skill:**
|
|
77
|
+
```
|
|
78
|
+
~/.claude/skills/uisnap/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Updating the Skill
|
|
82
|
+
|
|
83
|
+
When the toolkit updates:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Reinstall globally
|
|
87
|
+
npm install -g uisnap@latest
|
|
88
|
+
|
|
89
|
+
# Update skill files
|
|
90
|
+
cp -r node_modules/uisnap/.claude/skills/uisnap .claude/skills/
|
|
91
|
+
# or for personal: ~/.claude/skills/
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Uninstalling
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Remove toolkit
|
|
98
|
+
npm uninstall -g uisnap
|
|
99
|
+
|
|
100
|
+
# Remove skill
|
|
101
|
+
rm -rf .claude/skills/uisnap
|
|
102
|
+
# or: rm -rf ~/.claude/skills/uisnap
|
|
103
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-console.d.ts","sourceRoot":"","sources":["../src/analyze-console.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
function main() {
|
|
39
|
+
const args = process.argv.slice(2);
|
|
40
|
+
const logFile = args.find(arg => !arg.startsWith('--'));
|
|
41
|
+
const showErrors = args.includes('--errors') || args.includes('--full');
|
|
42
|
+
const showWarnings = args.includes('--warnings') || args.includes('--full');
|
|
43
|
+
const showOther = args.includes('--full');
|
|
44
|
+
if (!logFile || args.includes('--help')) {
|
|
45
|
+
console.error('Usage: analyze-console <console.jsonl> [options]');
|
|
46
|
+
console.error('\nOptions:');
|
|
47
|
+
console.error(' --errors Show error details');
|
|
48
|
+
console.error(' --warnings Show warning details');
|
|
49
|
+
console.error(' --full Show all details (errors + warnings + other)');
|
|
50
|
+
console.error('\nDefault: Shows only summary counts');
|
|
51
|
+
process.exit(args.includes('--help') ? 0 : 1);
|
|
52
|
+
}
|
|
53
|
+
if (!fs.existsSync(logFile)) {
|
|
54
|
+
console.error(`Error: File not found: ${logFile}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
const logs = fs.readFileSync(logFile, 'utf8')
|
|
58
|
+
.split('\n')
|
|
59
|
+
.filter(line => line.trim())
|
|
60
|
+
.map(line => JSON.parse(line));
|
|
61
|
+
if (logs.length === 0) {
|
|
62
|
+
console.log('No console messages found.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const counts = {};
|
|
66
|
+
logs.forEach(log => {
|
|
67
|
+
counts[log.type] = (counts[log.type] || 0) + 1;
|
|
68
|
+
});
|
|
69
|
+
console.log('=== Console Summary ===');
|
|
70
|
+
console.log(`Total messages: ${logs.length}`);
|
|
71
|
+
Object.entries(counts)
|
|
72
|
+
.sort((a, b) => b[1] - a[1])
|
|
73
|
+
.forEach(([type, count]) => {
|
|
74
|
+
console.log(` ${type}: ${count}`);
|
|
75
|
+
});
|
|
76
|
+
if (!showErrors && !showWarnings && !showOther) {
|
|
77
|
+
const hasErrors = counts['error'] > 0;
|
|
78
|
+
const hasWarnings = counts['warning'] > 0;
|
|
79
|
+
const hasOther = Object.keys(counts).some(t => t !== 'error' && t !== 'warning' && t !== 'log' && t !== 'debug');
|
|
80
|
+
if (hasErrors || hasWarnings || hasOther) {
|
|
81
|
+
console.log('\nFor details, use:');
|
|
82
|
+
if (hasErrors)
|
|
83
|
+
console.log(' --errors Show error messages and locations');
|
|
84
|
+
if (hasWarnings)
|
|
85
|
+
console.log(' --warnings Show warning messages');
|
|
86
|
+
if (hasOther)
|
|
87
|
+
console.log(' --full Show all details (errors + warnings + other)');
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (showErrors) {
|
|
92
|
+
const errors = logs.filter(l => l.type === 'error');
|
|
93
|
+
if (errors.length > 0) {
|
|
94
|
+
console.log('\n=== Errors ===');
|
|
95
|
+
const errorGroups = groupByText(errors);
|
|
96
|
+
errorGroups.forEach((group, i) => {
|
|
97
|
+
console.log(`${i + 1}. [${group.count}x] ${group.text}`);
|
|
98
|
+
if (group.locations.length > 0 && group.locations[0]) {
|
|
99
|
+
console.log(` Location: ${group.locations[0].url}:${group.locations[0].lineNumber || '?'}`);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (showWarnings) {
|
|
105
|
+
const warnings = logs.filter(l => l.type === 'warning');
|
|
106
|
+
if (warnings.length > 0) {
|
|
107
|
+
console.log('\n=== Warnings ===');
|
|
108
|
+
const warningGroups = groupByText(warnings);
|
|
109
|
+
warningGroups.forEach((group, i) => {
|
|
110
|
+
console.log(`${i + 1}. [${group.count}x] ${group.text}`);
|
|
111
|
+
if (group.locations.length > 0 && group.locations[0]) {
|
|
112
|
+
console.log(` Location: ${group.locations[0].url}:${group.locations[0].lineNumber || '?'}`);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (showOther) {
|
|
118
|
+
const otherTypes = Object.keys(counts).filter(t => t !== 'error' && t !== 'warning' && t !== 'log');
|
|
119
|
+
if (otherTypes.length > 0) {
|
|
120
|
+
console.log('\n=== Other Message Types ===');
|
|
121
|
+
otherTypes.forEach(type => {
|
|
122
|
+
const messages = logs.filter(l => l.type === type);
|
|
123
|
+
console.log(`\n${type} (${messages.length}):`);
|
|
124
|
+
messages.slice(0, 5).forEach(msg => {
|
|
125
|
+
console.log(` - ${msg.text}`);
|
|
126
|
+
});
|
|
127
|
+
if (messages.length > 5) {
|
|
128
|
+
console.log(` ... and ${messages.length - 5} more`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function groupByText(logs) {
|
|
135
|
+
const groups = new Map();
|
|
136
|
+
logs.forEach(log => {
|
|
137
|
+
const existing = groups.get(log.text) || [];
|
|
138
|
+
existing.push(log);
|
|
139
|
+
groups.set(log.text, existing);
|
|
140
|
+
});
|
|
141
|
+
return Array.from(groups.entries())
|
|
142
|
+
.map(([text, entries]) => ({
|
|
143
|
+
text,
|
|
144
|
+
count: entries.length,
|
|
145
|
+
locations: entries
|
|
146
|
+
.filter(e => e.location)
|
|
147
|
+
.map(e => e.location)
|
|
148
|
+
.filter((loc, idx, arr) => arr.findIndex(l => l.url === loc.url && l.lineNumber === loc.lineNumber) === idx),
|
|
149
|
+
}))
|
|
150
|
+
.sort((a, b) => b.count - a.count);
|
|
151
|
+
}
|
|
152
|
+
main();
|
|
153
|
+
//# sourceMappingURL=analyze-console.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-console.js","sourceRoot":"","sources":["../src/analyze-console.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-network.d.ts","sourceRoot":"","sources":["../src/analyze-network.ts"],"names":[],"mappings":""}
|