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.
Files changed (91) hide show
  1. package/.claude/settings.local.json +26 -0
  2. package/.claude/skills/uisnap/README.md +48 -0
  3. package/.claude/skills/uisnap/REFERENCE.md +1261 -0
  4. package/.claude/skills/uisnap/SETUP.md +75 -0
  5. package/.claude/skills/uisnap/SKILL.md +130 -0
  6. package/.claude/skills/uisnap/snapshot-capture-and-analysis.md +452 -0
  7. package/.claude/skills/uisnap/trace-capture-and-analysis.md +472 -0
  8. package/CHANGELOG.md +96 -0
  9. package/LICENSE +21 -0
  10. package/README.md +394 -0
  11. package/SKILL-INSTALLATION.md +103 -0
  12. package/dist/analyze-console.d.ts +3 -0
  13. package/dist/analyze-console.d.ts.map +1 -0
  14. package/dist/analyze-console.js +153 -0
  15. package/dist/analyze-console.js.map +1 -0
  16. package/dist/analyze-network.d.ts +3 -0
  17. package/dist/analyze-network.d.ts.map +1 -0
  18. package/dist/analyze-network.js +156 -0
  19. package/dist/analyze-network.js.map +1 -0
  20. package/dist/chrome-trace-analyze.d.ts +3 -0
  21. package/dist/chrome-trace-analyze.d.ts.map +1 -0
  22. package/dist/chrome-trace-analyze.js +119 -0
  23. package/dist/chrome-trace-analyze.js.map +1 -0
  24. package/dist/chrome-trace-import.d.ts +3 -0
  25. package/dist/chrome-trace-import.d.ts.map +1 -0
  26. package/dist/chrome-trace-import.js +90 -0
  27. package/dist/chrome-trace-import.js.map +1 -0
  28. package/dist/commands/snapshot.d.ts +4 -0
  29. package/dist/commands/snapshot.d.ts.map +1 -0
  30. package/dist/commands/snapshot.js +154 -0
  31. package/dist/commands/snapshot.js.map +1 -0
  32. package/dist/diagnose.d.ts +3 -0
  33. package/dist/diagnose.d.ts.map +1 -0
  34. package/dist/diagnose.js +244 -0
  35. package/dist/diagnose.js.map +1 -0
  36. package/dist/index.d.ts +4 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +26 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/pw.d.ts +3 -0
  41. package/dist/pw.d.ts.map +1 -0
  42. package/dist/pw.js +289 -0
  43. package/dist/pw.js.map +1 -0
  44. package/dist/query-a11y.d.ts +3 -0
  45. package/dist/query-a11y.d.ts.map +1 -0
  46. package/dist/query-a11y.js +208 -0
  47. package/dist/query-a11y.js.map +1 -0
  48. package/dist/trace-import.d.ts +3 -0
  49. package/dist/trace-import.d.ts.map +1 -0
  50. package/dist/trace-import.js +93 -0
  51. package/dist/trace-import.js.map +1 -0
  52. package/dist/types.d.ts +70 -0
  53. package/dist/types.d.ts.map +1 -0
  54. package/dist/types.js +3 -0
  55. package/dist/types.js.map +1 -0
  56. package/dist/utils/chromeTraceAnalyze.d.ts +40 -0
  57. package/dist/utils/chromeTraceAnalyze.d.ts.map +1 -0
  58. package/dist/utils/chromeTraceAnalyze.js +113 -0
  59. package/dist/utils/chromeTraceAnalyze.js.map +1 -0
  60. package/dist/utils/chromeTraceHelpers.d.ts +4 -0
  61. package/dist/utils/chromeTraceHelpers.d.ts.map +1 -0
  62. package/dist/utils/chromeTraceHelpers.js +68 -0
  63. package/dist/utils/chromeTraceHelpers.js.map +1 -0
  64. package/dist/utils/chromeTraceImport.d.ts +14 -0
  65. package/dist/utils/chromeTraceImport.d.ts.map +1 -0
  66. package/dist/utils/chromeTraceImport.js +77 -0
  67. package/dist/utils/chromeTraceImport.js.map +1 -0
  68. package/dist/utils/helpers.d.ts +3 -0
  69. package/dist/utils/helpers.d.ts.map +1 -0
  70. package/dist/utils/helpers.js +88 -0
  71. package/dist/utils/helpers.js.map +1 -0
  72. package/dist/utils/projectRoot.d.ts +2 -0
  73. package/dist/utils/projectRoot.d.ts.map +1 -0
  74. package/dist/utils/projectRoot.js +56 -0
  75. package/dist/utils/projectRoot.js.map +1 -0
  76. package/dist/utils/traceHelpers.d.ts +4 -0
  77. package/dist/utils/traceHelpers.d.ts.map +1 -0
  78. package/dist/utils/traceHelpers.js +67 -0
  79. package/dist/utils/traceHelpers.js.map +1 -0
  80. package/dist/utils/traceImport.d.ts +20 -0
  81. package/dist/utils/traceImport.d.ts.map +1 -0
  82. package/dist/utils/traceImport.js +124 -0
  83. package/dist/utils/traceImport.js.map +1 -0
  84. package/dist/utils/webVitals.d.ts +9 -0
  85. package/dist/utils/webVitals.d.ts.map +1 -0
  86. package/dist/utils/webVitals.js +54 -0
  87. package/dist/utils/webVitals.js.map +1 -0
  88. package/examples/login-flow.js +37 -0
  89. package/examples/scroll-perf-trace.js +43 -0
  90. package/examples/simple-capture.js +28 -0
  91. 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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=analyze-console.d.ts.map
@@ -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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=analyze-network.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-network.d.ts","sourceRoot":"","sources":["../src/analyze-network.ts"],"names":[],"mappings":""}