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
@@ -0,0 +1,208 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const fs = __importStar(require("fs"));
41
+ const yaml_1 = __importDefault(require("yaml"));
42
+ function main() {
43
+ const snapshotFile = process.argv[2];
44
+ const query = process.argv[3];
45
+ if (!snapshotFile || !query) {
46
+ console.error('Usage: query-a11y <a11y.yaml> <query>');
47
+ console.error('\nQueries:');
48
+ console.error(' --buttons List all buttons');
49
+ console.error(' --links List all links');
50
+ console.error(' --headings List all headings');
51
+ console.error(' --inputs List all input fields');
52
+ console.error(' --interactive List all interactive elements');
53
+ console.error(' --images List all images');
54
+ console.error(' <text> Search by text content');
55
+ process.exit(1);
56
+ }
57
+ if (!fs.existsSync(snapshotFile)) {
58
+ console.error(`Error: File not found: ${snapshotFile}`);
59
+ process.exit(1);
60
+ }
61
+ const yamlContent = fs.readFileSync(snapshotFile, 'utf8');
62
+ const ariaTree = parseAriaYaml(yamlContent);
63
+ let matcher;
64
+ let description;
65
+ switch (query) {
66
+ case '--buttons':
67
+ matcher = n => n.role === 'button';
68
+ description = 'buttons';
69
+ break;
70
+ case '--links':
71
+ matcher = n => n.role === 'link';
72
+ description = 'links';
73
+ break;
74
+ case '--headings':
75
+ matcher = n => n.role === 'heading';
76
+ description = 'headings';
77
+ break;
78
+ case '--inputs':
79
+ matcher = n => ['textbox', 'searchbox', 'combobox'].includes(n.role || '');
80
+ description = 'input fields';
81
+ break;
82
+ case '--interactive':
83
+ matcher = n => ['button', 'link', 'textbox', 'checkbox', 'radio', 'searchbox', 'combobox'].includes(n.role || '');
84
+ description = 'interactive elements';
85
+ break;
86
+ case '--images':
87
+ matcher = n => n.role === 'img';
88
+ description = 'images';
89
+ break;
90
+ default:
91
+ matcher = n => Boolean(n.name && n.name.toLowerCase().includes(query.toLowerCase()));
92
+ description = `elements matching "${query}"`;
93
+ }
94
+ const results = traverse(ariaTree, matcher);
95
+ if (results.length === 0) {
96
+ console.log(`No ${description} found.`);
97
+ return;
98
+ }
99
+ console.log(`Found ${results.length} ${description}:\n`);
100
+ results.forEach((node, i) => {
101
+ const attrs = [];
102
+ if (node.role)
103
+ attrs.push(`role="${node.role}"`);
104
+ if (node.name)
105
+ attrs.push(`name="${node.name}"`);
106
+ if (node.level)
107
+ attrs.push(`level=${node.level}`);
108
+ if (node.disabled)
109
+ attrs.push('disabled');
110
+ if (node.checked !== undefined)
111
+ attrs.push(`checked=${node.checked}`);
112
+ if (node.url)
113
+ attrs.push(`url="${node.url}"`);
114
+ console.log(`${i + 1}. ${attrs.join(' ')}`);
115
+ });
116
+ }
117
+ function parseAriaYaml(yamlContent) {
118
+ const parsed = yaml_1.default.parse(yamlContent);
119
+ if (!Array.isArray(parsed)) {
120
+ return [];
121
+ }
122
+ return parsed.map(item => parseAriaNode(item)).filter((n) => n !== null);
123
+ }
124
+ function parseAriaNode(item) {
125
+ if (typeof item === 'string') {
126
+ return parseAriaString(item);
127
+ }
128
+ if (typeof item !== 'object' || item === null) {
129
+ return null;
130
+ }
131
+ const node = {};
132
+ for (const [key, value] of Object.entries(item)) {
133
+ if (key === '/url') {
134
+ node.url = value;
135
+ continue;
136
+ }
137
+ const parsedKey = parseAriaString(key);
138
+ if (parsedKey) {
139
+ Object.assign(node, parsedKey);
140
+ }
141
+ else {
142
+ node.role = key;
143
+ }
144
+ if (Array.isArray(value)) {
145
+ node.children = value.map(child => parseAriaNode(child)).filter((n) => n !== null);
146
+ const urlChild = value.find(v => typeof v === 'object' && v !== null && '/url' in v);
147
+ if (urlChild) {
148
+ node.url = urlChild['/url'];
149
+ node.children = node.children?.filter(c => !c.url || c.role);
150
+ }
151
+ }
152
+ else if (typeof value === 'string') {
153
+ if (!node.name) {
154
+ node.name = value;
155
+ }
156
+ }
157
+ }
158
+ return Object.keys(node).length > 0 ? node : null;
159
+ }
160
+ function parseAriaString(str) {
161
+ const withQuotes = str.match(/^(\w+)\s+"([^"]+)"(?:\s*\[([^\]]+)\])?$/);
162
+ if (withQuotes) {
163
+ const [, role, name, attrs] = withQuotes;
164
+ const node = { role, name };
165
+ if (attrs) {
166
+ const levelMatch = attrs.match(/level=(\d+)/);
167
+ if (levelMatch) {
168
+ node.level = parseInt(levelMatch[1]);
169
+ }
170
+ if (attrs.includes('disabled'))
171
+ node.disabled = true;
172
+ if (attrs.includes('checked=true'))
173
+ node.checked = true;
174
+ if (attrs.includes('checked=false'))
175
+ node.checked = false;
176
+ }
177
+ return node;
178
+ }
179
+ const withAttrs = str.match(/^(\w+)(?:\s*\[([^\]]+)\])?$/);
180
+ if (withAttrs) {
181
+ const [, role, attrs] = withAttrs;
182
+ const node = { role };
183
+ if (attrs) {
184
+ const levelMatch = attrs.match(/level=(\d+)/);
185
+ if (levelMatch) {
186
+ node.level = parseInt(levelMatch[1]);
187
+ }
188
+ if (attrs.includes('disabled'))
189
+ node.disabled = true;
190
+ }
191
+ return node;
192
+ }
193
+ return null;
194
+ }
195
+ function traverse(nodes, matcher, results = []) {
196
+ const nodeArray = Array.isArray(nodes) ? nodes : [nodes];
197
+ for (const node of nodeArray) {
198
+ if (matcher(node)) {
199
+ results.push(node);
200
+ }
201
+ if (node.children && node.children.length > 0) {
202
+ traverse(node.children, matcher, results);
203
+ }
204
+ }
205
+ return results;
206
+ }
207
+ main();
208
+ //# sourceMappingURL=query-a11y.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-a11y.js","sourceRoot":"","sources":["../src/query-a11y.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=trace-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-import.d.ts","sourceRoot":"","sources":["../src/trace-import.ts"],"names":[],"mappings":""}
@@ -0,0 +1,93 @@
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
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const traceImport_1 = require("./utils/traceImport");
41
+ async function main() {
42
+ const args = process.argv.slice(2);
43
+ if (args.length === 0 || args.includes('--help')) {
44
+ console.error('Usage: trace-import <trace.zip> [output.db]');
45
+ console.error('');
46
+ console.error('Imports a Playwright trace.zip file into a DuckDB database for efficient querying.');
47
+ console.error('');
48
+ console.error('Arguments:');
49
+ console.error(' trace.zip Path to Playwright trace.zip file');
50
+ console.error(' output.db Output database path (default: trace.db in same directory)');
51
+ console.error('');
52
+ console.error('Example:');
53
+ console.error(' trace-import snapshots/localhost/latest/flow.trace.zip');
54
+ console.error(' trace-import flow.trace.zip flow.db');
55
+ process.exit(args.includes('--help') ? 0 : 1);
56
+ }
57
+ const zipPath = args[0];
58
+ const dbPath = args[1] || zipPath.replace(/\.trace\.zip$/, '.db').replace(/\.zip$/, '.db');
59
+ if (!fs.existsSync(zipPath)) {
60
+ console.error(`Error: Trace file not found: ${zipPath}`);
61
+ process.exit(1);
62
+ }
63
+ console.log(`Importing trace: ${zipPath}`);
64
+ console.log(`Output database: ${dbPath}`);
65
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pw-trace-'));
66
+ try {
67
+ console.log(' → Extracting trace.zip...');
68
+ const extractedDir = await (0, traceImport_1.extractTrace)(zipPath, tempDir);
69
+ console.log(' → Parsing actions...');
70
+ const traceFile = path.join(extractedDir, 'trace.trace');
71
+ const actions = await (0, traceImport_1.parseTraceActions)(traceFile);
72
+ console.log(` → Found ${actions.length} actions`);
73
+ console.log(' → Creating DuckDB database...');
74
+ await (0, traceImport_1.createTraceDatabase)(dbPath, { actions });
75
+ console.log('');
76
+ console.log(`✓ Database created: ${dbPath}`);
77
+ console.log('');
78
+ console.log('Query examples:');
79
+ console.log(` duckdb ${dbPath} -json "SELECT class, method, duration_ms FROM actions WHERE duration_ms > 100 ORDER BY duration_ms DESC"`);
80
+ console.log(` duckdb ${dbPath} "SELECT COUNT(*) FROM actions"`);
81
+ }
82
+ catch (error) {
83
+ console.error('Error during import:', error);
84
+ process.exit(1);
85
+ }
86
+ finally {
87
+ if (fs.existsSync(tempDir)) {
88
+ fs.rmSync(tempDir, { recursive: true, force: true });
89
+ }
90
+ }
91
+ }
92
+ main();
93
+ //# sourceMappingURL=trace-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-import.js","sourceRoot":"","sources":["../src/trace-import.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AACzB,qDAA2F;AAO3F,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACpG,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QAC1F,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE3F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,EAAE,CAAC,CAAC;IAG1C,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAEpE,IAAI,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAG1D,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,IAAA,+BAAiB,EAAC,SAAS,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;QAGnD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,MAAM,IAAA,iCAAmB,EAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAE/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,2GAA2G,CAAC,CAAC;QAC3I,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,iCAAiC,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QAET,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { Page, BrowserContext, Browser } from 'playwright';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ export type CommandHandler = (page: Page, context: BrowserContext, browser: Browser, args: string[]) => Promise<void>;
5
+ export interface BuiltinCommands {
6
+ [command: string]: CommandHandler;
7
+ }
8
+ export interface ScriptUtils {
9
+ baseOutputDir: string;
10
+ writeJson: (filepath: string, data: unknown) => void;
11
+ writeJsonl: (filepath: string, items: unknown[]) => void;
12
+ appendJsonl: (filepath: string, item: unknown) => void;
13
+ captureStep: (page: Page, stepName: string, action?: () => Promise<void>) => Promise<void>;
14
+ tracePath: (name: string) => string;
15
+ startTrace: (context: any) => Promise<void>;
16
+ stopTraceAndImport: (context: any, tracePath: string) => Promise<string>;
17
+ startChromeTrace: (cdp: any) => Promise<void>;
18
+ stopChromeTraceAndImport: (cdp: any, tracePath: string) => Promise<string>;
19
+ }
20
+ export interface ScriptEnvironment {
21
+ page: Page;
22
+ context: BrowserContext;
23
+ browser: Browser;
24
+ args: string[];
25
+ fs: typeof fs;
26
+ path: typeof path;
27
+ utils: ScriptUtils;
28
+ }
29
+ export interface ConsoleLogEntry {
30
+ timestamp: string;
31
+ type: string;
32
+ text: string;
33
+ location?: {
34
+ url: string;
35
+ lineNumber?: number;
36
+ columnNumber?: number;
37
+ };
38
+ }
39
+ export interface NetworkLogEntry {
40
+ url: string;
41
+ status: number;
42
+ statusText: string;
43
+ method: string;
44
+ resourceType: string;
45
+ timing?: {
46
+ startTime: number;
47
+ responseEnd: number;
48
+ };
49
+ }
50
+ export interface PageMetadata {
51
+ title: string;
52
+ url: string;
53
+ viewport: {
54
+ width: number;
55
+ height: number;
56
+ };
57
+ timestamp: string;
58
+ }
59
+ export interface ScenarioStep {
60
+ action: 'goto' | 'click' | 'fill' | 'wait';
61
+ url?: string;
62
+ selector?: string;
63
+ value?: string;
64
+ duration?: number;
65
+ wait?: number;
66
+ }
67
+ export interface Scenario {
68
+ steps: ScenarioStep[];
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ export interface TraceSummary {
2
+ totalTasks: number;
3
+ totalDuration: number;
4
+ longTasksCount: number;
5
+ }
6
+ export interface LongTask {
7
+ name: string;
8
+ duration: number;
9
+ timestamp: number;
10
+ }
11
+ export interface JsStats {
12
+ name: string;
13
+ count: number;
14
+ total: number;
15
+ avg: number;
16
+ max: number;
17
+ }
18
+ export interface LayoutPaintStats {
19
+ name: string;
20
+ count: number;
21
+ total: number;
22
+ avg: number;
23
+ }
24
+ export interface AnalysisResults {
25
+ summary: TraceSummary;
26
+ longTasks?: LongTask[];
27
+ jsStats?: JsStats[];
28
+ layoutPaintStats?: LayoutPaintStats[];
29
+ }
30
+ export declare function getTraceSummary(dbPath: string, threshold?: number): Promise<TraceSummary>;
31
+ export declare function getLongTasks(dbPath: string, threshold?: number, limit?: number): Promise<LongTask[]>;
32
+ export declare function getJsStats(dbPath: string): Promise<JsStats[]>;
33
+ export declare function getLayoutPaintStats(dbPath: string, limit?: number): Promise<LayoutPaintStats[]>;
34
+ export declare function analyzeChromeTrace(dbPath: string, options?: {
35
+ showLongTasks?: boolean;
36
+ showJsTime?: boolean;
37
+ showLayoutPaint?: boolean;
38
+ threshold?: number;
39
+ }): Promise<AnalysisResults>;
40
+ //# sourceMappingURL=chromeTraceAnalyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeTraceAnalyze.d.ts","sourceRoot":"","sources":["../../src/utils/chromeTraceAnalyze.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,gBAAgB,EAAE,CAAC;CACvC;AAKD,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAgBnG;AAKD,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAoBlH;AAKD,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA2BnE;AAKD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA0BzG;AAKD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,eAAe,CAAC,CAmB1B"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTraceSummary = getTraceSummary;
4
+ exports.getLongTasks = getLongTasks;
5
+ exports.getJsStats = getJsStats;
6
+ exports.getLayoutPaintStats = getLayoutPaintStats;
7
+ exports.analyzeChromeTrace = analyzeChromeTrace;
8
+ const duckdb_async_1 = require("duckdb-async");
9
+ async function getTraceSummary(dbPath, threshold = 50) {
10
+ const db = await duckdb_async_1.Database.create(dbPath, { access_mode: 'READ_ONLY' });
11
+ try {
12
+ const totalTasks = await db.all('SELECT COUNT(*) as count FROM tasks');
13
+ const totalDuration = await db.all('SELECT ROUND(SUM(dur_ms), 2) as total FROM tasks');
14
+ const longTasks = await db.all(`SELECT COUNT(*) as count FROM tasks WHERE dur_ms > ${threshold}`);
15
+ return {
16
+ totalTasks: Number(totalTasks[0].count),
17
+ totalDuration: Number(totalDuration[0].total || 0),
18
+ longTasksCount: Number(longTasks[0].count),
19
+ };
20
+ }
21
+ finally {
22
+ await db.close();
23
+ }
24
+ }
25
+ async function getLongTasks(dbPath, threshold = 50, limit = 20) {
26
+ const db = await duckdb_async_1.Database.create(dbPath, { access_mode: 'READ_ONLY' });
27
+ try {
28
+ const tasks = await db.all(`
29
+ SELECT name, ROUND(dur_ms, 2) as dur_ms, ROUND(ts_ms, 2) as ts_ms
30
+ FROM tasks
31
+ WHERE dur_ms > ${threshold}
32
+ ORDER BY dur_ms DESC
33
+ LIMIT ${limit}
34
+ `);
35
+ return tasks.map((task) => ({
36
+ name: task.name,
37
+ duration: Number(task.dur_ms),
38
+ timestamp: Number(task.ts_ms),
39
+ }));
40
+ }
41
+ finally {
42
+ await db.close();
43
+ }
44
+ }
45
+ async function getJsStats(dbPath) {
46
+ const db = await duckdb_async_1.Database.create(dbPath, { access_mode: 'READ_ONLY' });
47
+ try {
48
+ const stats = await db.all(`
49
+ SELECT
50
+ name,
51
+ COUNT(*) as count,
52
+ ROUND(SUM(dur_ms), 2) as total_ms,
53
+ ROUND(AVG(dur_ms), 2) as avg_ms,
54
+ ROUND(MAX(dur_ms), 2) as max_ms
55
+ FROM tasks
56
+ WHERE name LIKE '%Script%' OR name LIKE '%Function%'
57
+ GROUP BY name
58
+ ORDER BY total_ms DESC
59
+ `);
60
+ return stats.map((stat) => ({
61
+ name: stat.name,
62
+ count: Number(stat.count),
63
+ total: Number(stat.total_ms),
64
+ avg: Number(stat.avg_ms),
65
+ max: Number(stat.max_ms),
66
+ }));
67
+ }
68
+ finally {
69
+ await db.close();
70
+ }
71
+ }
72
+ async function getLayoutPaintStats(dbPath, limit = 10) {
73
+ const db = await duckdb_async_1.Database.create(dbPath, { access_mode: 'READ_ONLY' });
74
+ try {
75
+ const stats = await db.all(`
76
+ SELECT
77
+ name,
78
+ COUNT(*) as count,
79
+ ROUND(SUM(dur_ms), 2) as total_ms,
80
+ ROUND(AVG(dur_ms), 2) as avg_ms
81
+ FROM tasks
82
+ WHERE name LIKE '%Layout%' OR name LIKE '%Paint%' OR name LIKE '%Style%'
83
+ GROUP BY name
84
+ ORDER BY total_ms DESC
85
+ LIMIT ${limit}
86
+ `);
87
+ return stats.map((stat) => ({
88
+ name: stat.name,
89
+ count: Number(stat.count),
90
+ total: Number(stat.total_ms),
91
+ avg: Number(stat.avg_ms),
92
+ }));
93
+ }
94
+ finally {
95
+ await db.close();
96
+ }
97
+ }
98
+ async function analyzeChromeTrace(dbPath, options = {}) {
99
+ const threshold = options.threshold || 50;
100
+ const summary = await getTraceSummary(dbPath, threshold);
101
+ const results = { summary };
102
+ if (options.showLongTasks && summary.longTasksCount > 0) {
103
+ results.longTasks = await getLongTasks(dbPath, threshold);
104
+ }
105
+ if (options.showJsTime) {
106
+ results.jsStats = await getJsStats(dbPath);
107
+ }
108
+ if (options.showLayoutPaint) {
109
+ results.layoutPaintStats = await getLayoutPaintStats(dbPath);
110
+ }
111
+ return results;
112
+ }
113
+ //# sourceMappingURL=chromeTraceAnalyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeTraceAnalyze.js","sourceRoot":"","sources":["../../src/utils/chromeTraceAnalyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { CDPSession } from 'playwright';
2
+ export declare function startChromeTrace(cdp: CDPSession): Promise<void>;
3
+ export declare function stopChromeTraceAndImport(cdp: CDPSession, tracePath: string): Promise<string>;
4
+ //# sourceMappingURL=chromeTraceHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeTraceHelpers.d.ts","sourceRoot":"","sources":["../../src/utils/chromeTraceHelpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQxC,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIrE;AASD,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAmCjB"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.startChromeTrace = startChromeTrace;
37
+ exports.stopChromeTraceAndImport = stopChromeTraceAndImport;
38
+ const fs = __importStar(require("fs"));
39
+ const chromeTraceImport_1 = require("./chromeTraceImport");
40
+ async function startChromeTrace(cdp) {
41
+ await cdp.send('Tracing.start', {
42
+ categories: 'devtools.timeline,v8.execute,disabled-by-default-devtools.timeline,disabled-by-default-devtools.timeline.frame,toplevel',
43
+ });
44
+ }
45
+ async function stopChromeTraceAndImport(cdp, tracePath) {
46
+ const traceEvents = [];
47
+ const traceComplete = new Promise((resolve) => {
48
+ cdp.on('Tracing.dataCollected', (params) => {
49
+ traceEvents.push(...params.value);
50
+ });
51
+ cdp.on('Tracing.tracingComplete', () => {
52
+ resolve(undefined);
53
+ });
54
+ });
55
+ await cdp.send('Tracing.end');
56
+ await traceComplete;
57
+ fs.writeFileSync(tracePath, JSON.stringify(traceEvents, null, 2));
58
+ console.log(` → Chrome trace saved: ${tracePath}`);
59
+ console.log(` → Events captured: ${traceEvents.length}`);
60
+ const dbPath = tracePath.replace(/\.json$/, '.db');
61
+ const events = await (0, chromeTraceImport_1.parseChromeTrace)(tracePath);
62
+ await (0, chromeTraceImport_1.createChromeTraceDatabase)(dbPath, events);
63
+ const completeEvents = events.filter(e => e.ph === 'X').length;
64
+ console.log(` → Database created: ${dbPath}`);
65
+ console.log(` → ${completeEvents} tasks imported`);
66
+ return dbPath;
67
+ }
68
+ //# sourceMappingURL=chromeTraceHelpers.js.map