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 @@
1
+ {"version":3,"file":"chromeTraceHelpers.js","sourceRoot":"","sources":["../../src/utils/chromeTraceHelpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,4CAIC;AASD,4DAsCC;AA5DD,uCAAyB;AAEzB,2DAAkF;AAO3E,KAAK,UAAU,gBAAgB,CAAC,GAAe;IACpD,MAAM,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE;QAC9B,UAAU,EAAE,yHAAyH;KACtI,CAAC,CAAC;AACL,CAAC;AASM,KAAK,UAAU,wBAAwB,CAC5C,GAAe,EACf,SAAiB;IAGjB,MAAM,WAAW,GAAU,EAAE,CAAC;IAC9B,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5C,GAAG,CAAC,EAAE,CAAC,uBAAuB,EAAE,CAAC,MAAW,EAAE,EAAE;YAC9C,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACrC,OAAO,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAGH,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAG9B,MAAM,aAAa,CAAC;IAGpB,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,2BAA2B,SAAS,EAAE,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,wBAAwB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAG1D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAGnD,MAAM,MAAM,GAAG,MAAM,IAAA,oCAAgB,EAAC,SAAS,CAAC,CAAC;IACjD,MAAM,IAAA,6CAAyB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhD,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,cAAc,iBAAiB,CAAC,CAAC;IAEpD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface ChromeTraceEvent {
2
+ pid: number;
3
+ tid: number;
4
+ ts: number;
5
+ ph: string;
6
+ cat: string;
7
+ name: string;
8
+ dur?: number;
9
+ args?: any;
10
+ s?: string;
11
+ }
12
+ export declare function parseChromeTrace(traceFilePath: string): Promise<ChromeTraceEvent[]>;
13
+ export declare function createChromeTraceDatabase(dbPath: string, events: ChromeTraceEvent[]): Promise<void>;
14
+ //# sourceMappingURL=chromeTraceImport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeTraceImport.d.ts","sourceRoot":"","sources":["../../src/utils/chromeTraceImport.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAQD,wBAAsB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAIzF;AAQD,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,gBAAgB,EAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CA+Cf"}
@@ -0,0 +1,77 @@
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.parseChromeTrace = parseChromeTrace;
37
+ exports.createChromeTraceDatabase = createChromeTraceDatabase;
38
+ const fs = __importStar(require("fs"));
39
+ const duckdb_async_1 = require("duckdb-async");
40
+ async function parseChromeTrace(traceFilePath) {
41
+ const content = fs.readFileSync(traceFilePath, 'utf8');
42
+ const events = JSON.parse(content);
43
+ return events;
44
+ }
45
+ async function createChromeTraceDatabase(dbPath, events) {
46
+ const db = await duckdb_async_1.Database.create(dbPath);
47
+ try {
48
+ await db.exec(`
49
+ CREATE TABLE tasks (
50
+ name VARCHAR,
51
+ cat VARCHAR,
52
+ ts_ms DOUBLE,
53
+ dur_ms DOUBLE,
54
+ pid INTEGER,
55
+ tid INTEGER,
56
+ args JSON
57
+ )
58
+ `);
59
+ await db.exec(`
60
+ CREATE INDEX idx_tasks_dur ON tasks(dur_ms DESC);
61
+ CREATE INDEX idx_tasks_name ON tasks(name);
62
+ CREATE INDEX idx_tasks_ts ON tasks(ts_ms);
63
+ `);
64
+ const completeEvents = events.filter(e => e.ph === 'X' && e.dur !== undefined);
65
+ const stmt = await db.prepare(`
66
+ INSERT INTO tasks VALUES (?, ?, ?, ?, ?, ?, ?)
67
+ `);
68
+ for (const event of completeEvents) {
69
+ await stmt.run(event.name, event.cat, event.ts / 1000, (event.dur || 0) / 1000, event.pid, event.tid, event.args ? JSON.stringify(event.args) : null);
70
+ }
71
+ await stmt.finalize();
72
+ }
73
+ finally {
74
+ await db.close();
75
+ }
76
+ }
77
+ //# sourceMappingURL=chromeTraceImport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromeTraceImport.js","sourceRoot":"","sources":["../../src/utils/chromeTraceImport.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,4CAIC;AAQD,8DAkDC;AAvFD,uCAAyB;AACzB,+CAAwC;AAwBjC,KAAK,UAAU,gBAAgB,CAAC,aAAqB;IAC1D,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;IACzD,OAAO,MAAM,CAAC;AAChB,CAAC;AAQM,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EACd,MAA0B;IAE1B,MAAM,EAAE,GAAG,MAAM,uBAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC;QAEH,MAAM,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;KAUb,CAAC,CAAC;QAGH,MAAM,EAAE,CAAC,IAAI,CAAC;;;;KAIb,CAAC,CAAC;QAGH,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;QAE/E,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC;;KAE7B,CAAC,CAAC;QAEH,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,GAAG,CACZ,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,EAAE,GAAG,IAAI,EACf,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,EACvB,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,GAAG,EACT,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAC/C,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ScriptUtils } from '../types';
2
+ export declare function createUtils(baseOutputDir: string): ScriptUtils;
3
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAQvC,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAwE9D"}
@@ -0,0 +1,88 @@
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.createUtils = createUtils;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const traceHelpers_1 = require("./traceHelpers");
40
+ const chromeTraceHelpers_1 = require("./chromeTraceHelpers");
41
+ function createUtils(baseOutputDir) {
42
+ let stepCounter = 0;
43
+ return {
44
+ baseOutputDir,
45
+ writeJson: (filepath, data) => {
46
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
47
+ fs.writeFileSync(filepath, JSON.stringify(data, null, 2));
48
+ },
49
+ writeJsonl: (filepath, items) => {
50
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
51
+ fs.writeFileSync(filepath, items.map(i => JSON.stringify(i)).join('\n'));
52
+ },
53
+ appendJsonl: (filepath, item) => {
54
+ const dir = path.dirname(filepath);
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ fs.appendFileSync(filepath, JSON.stringify(item) + '\n');
57
+ },
58
+ captureStep: async (page, stepName, action) => {
59
+ if (action) {
60
+ await action();
61
+ }
62
+ stepCounter++;
63
+ const stepDir = path.join(baseOutputDir, `step-${stepCounter}-${stepName}`);
64
+ fs.mkdirSync(stepDir, { recursive: true });
65
+ const a11ySnapshot = await page.locator('body').ariaSnapshot();
66
+ fs.writeFileSync(path.join(stepDir, 'a11y.yaml'), a11ySnapshot);
67
+ const metadata = await page.evaluate(() => {
68
+ const title = document.title;
69
+ const url = window.location.href;
70
+ return {
71
+ title,
72
+ url,
73
+ timestamp: new Date().toISOString(),
74
+ };
75
+ });
76
+ fs.writeFileSync(path.join(stepDir, 'metadata.json'), JSON.stringify(metadata, null, 2));
77
+ console.log(` ✓ Step ${stepCounter}: ${stepName} (${metadata.url})`);
78
+ },
79
+ tracePath: (name) => {
80
+ return path.join(baseOutputDir, `${name}.trace.zip`);
81
+ },
82
+ startTrace: traceHelpers_1.startTrace,
83
+ stopTraceAndImport: traceHelpers_1.stopTraceAndImport,
84
+ startChromeTrace: chromeTraceHelpers_1.startChromeTrace,
85
+ stopChromeTraceAndImport: chromeTraceHelpers_1.stopChromeTraceAndImport,
86
+ };
87
+ }
88
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getUserProjectDir(): string;
2
+ //# sourceMappingURL=projectRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectRoot.d.ts","sourceRoot":"","sources":["../../src/utils/projectRoot.ts"],"names":[],"mappings":"AAOA,wBAAgB,iBAAiB,IAAI,MAAM,CAuB1C"}
@@ -0,0 +1,56 @@
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.getUserProjectDir = getUserProjectDir;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ function getUserProjectDir() {
40
+ let dir = process.cwd();
41
+ while (dir !== path.dirname(dir)) {
42
+ if (fs.existsSync(path.join(dir, '.git'))) {
43
+ return dir;
44
+ }
45
+ dir = path.dirname(dir);
46
+ }
47
+ dir = process.cwd();
48
+ while (dir !== path.dirname(dir)) {
49
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
50
+ return dir;
51
+ }
52
+ dir = path.dirname(dir);
53
+ }
54
+ return process.cwd();
55
+ }
56
+ //# sourceMappingURL=projectRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectRoot.js","sourceRoot":"","sources":["../../src/utils/projectRoot.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,8CAuBC;AA9BD,uCAAyB;AACzB,2CAA6B;AAM7B,SAAgB,iBAAiB;IAI/B,IAAI,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACxB,OAAO,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;YAC1C,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAGD,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACpB,OAAO,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAGD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;AACvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { BrowserContext } from 'playwright';
2
+ export declare function startTrace(context: BrowserContext): Promise<void>;
3
+ export declare function stopTraceAndImport(context: BrowserContext, tracePath: string): Promise<string>;
4
+ //# sourceMappingURL=traceHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceHelpers.d.ts","sourceRoot":"","sources":["../../src/utils/traceHelpers.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQ5C,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAKvE;AASD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CA+BjB"}
@@ -0,0 +1,67 @@
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.startTrace = startTrace;
37
+ exports.stopTraceAndImport = stopTraceAndImport;
38
+ const fs = __importStar(require("fs"));
39
+ const os = __importStar(require("os"));
40
+ const path = __importStar(require("path"));
41
+ const traceImport_1 = require("./traceImport");
42
+ async function startTrace(context) {
43
+ await context.tracing.start({
44
+ screenshots: true,
45
+ snapshots: true,
46
+ });
47
+ }
48
+ async function stopTraceAndImport(context, tracePath) {
49
+ await context.tracing.stop({ path: tracePath });
50
+ const dbPath = tracePath.replace(/\.trace\.zip$/, '.db').replace(/\.zip$/, '.db');
51
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'pw-trace-'));
52
+ try {
53
+ const extractedDir = await (0, traceImport_1.extractTrace)(tracePath, tempDir);
54
+ const traceFile = path.join(extractedDir, 'trace.trace');
55
+ const actions = await (0, traceImport_1.parseTraceActions)(traceFile);
56
+ await (0, traceImport_1.createTraceDatabase)(dbPath, { actions });
57
+ console.log(` → Trace database created: ${dbPath}`);
58
+ console.log(` → ${actions.length} actions imported`);
59
+ }
60
+ finally {
61
+ if (fs.existsSync(tempDir)) {
62
+ fs.rmSync(tempDir, { recursive: true, force: true });
63
+ }
64
+ }
65
+ return dbPath;
66
+ }
67
+ //# sourceMappingURL=traceHelpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceHelpers.js","sourceRoot":"","sources":["../../src/utils/traceHelpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,gCAKC;AASD,gDAkCC;AA3DD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAE7B,+CAAqF;AAO9E,KAAK,UAAU,UAAU,CAAC,OAAuB;IACtD,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1B,WAAW,EAAE,IAAI;QACjB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;AACL,CAAC;AASM,KAAK,UAAU,kBAAkB,CACtC,OAAuB,EACvB,SAAiB;IAGjB,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAGhD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAGlF,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;IAEpE,IAAI,CAAC;QAEH,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAG5D,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,IAAA,+BAAiB,EAAC,SAAS,CAAC,CAAC;QAGnD,MAAM,IAAA,iCAAmB,EAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAE/C,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,OAAO,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC;IACxD,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;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface TraceAction {
2
+ call_id: string;
3
+ class: string;
4
+ method: string;
5
+ start_time_ms: number;
6
+ end_time_ms: number;
7
+ duration_ms: number;
8
+ params?: any;
9
+ result?: any;
10
+ error?: string;
11
+ before_snapshot?: string;
12
+ after_snapshot?: string;
13
+ }
14
+ export declare function extractTrace(zipPath: string, outputDir: string): Promise<string>;
15
+ export declare function parseTraceActions(traceFilePath: string): Promise<TraceAction[]>;
16
+ export interface TraceData {
17
+ actions: TraceAction[];
18
+ }
19
+ export declare function createTraceDatabase(dbPath: string, data: TraceData): Promise<void>;
20
+ //# sourceMappingURL=traceImport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceImport.d.ts","sourceRoot":"","sources":["../../src/utils/traceImport.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AASD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAWtF;AAQD,wBAAsB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA8CrF;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAQD,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDxF"}
@@ -0,0 +1,124 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.extractTrace = extractTrace;
40
+ exports.parseTraceActions = parseTraceActions;
41
+ exports.createTraceDatabase = createTraceDatabase;
42
+ const fs = __importStar(require("fs"));
43
+ const adm_zip_1 = __importDefault(require("adm-zip"));
44
+ const duckdb_async_1 = require("duckdb-async");
45
+ async function extractTrace(zipPath, outputDir) {
46
+ if (!fs.existsSync(zipPath)) {
47
+ throw new Error(`Trace file not found: ${zipPath}`);
48
+ }
49
+ const zip = new adm_zip_1.default(zipPath);
50
+ zip.extractAllTo(outputDir, true);
51
+ return outputDir;
52
+ }
53
+ async function parseTraceActions(traceFilePath) {
54
+ const content = fs.readFileSync(traceFilePath, 'utf8');
55
+ const lines = content.split('\n').filter(line => line.trim());
56
+ const events = lines.map(line => JSON.parse(line));
57
+ const beforeEvents = new Map();
58
+ const afterEvents = new Map();
59
+ for (const event of events) {
60
+ if (event.type === 'before') {
61
+ beforeEvents.set(event.callId, event);
62
+ }
63
+ else if (event.type === 'after') {
64
+ afterEvents.set(event.callId, event);
65
+ }
66
+ }
67
+ const actions = [];
68
+ for (const [callId, before] of beforeEvents.entries()) {
69
+ const after = afterEvents.get(callId);
70
+ if (after) {
71
+ actions.push({
72
+ call_id: callId,
73
+ class: before.class,
74
+ method: before.method,
75
+ start_time_ms: before.startTime,
76
+ end_time_ms: after.endTime,
77
+ duration_ms: after.endTime - before.startTime,
78
+ params: before.params,
79
+ result: after.result,
80
+ error: after.error,
81
+ before_snapshot: before.beforeSnapshot,
82
+ after_snapshot: after.afterSnapshot,
83
+ });
84
+ }
85
+ }
86
+ actions.sort((a, b) => a.start_time_ms - b.start_time_ms);
87
+ return actions;
88
+ }
89
+ async function createTraceDatabase(dbPath, data) {
90
+ const db = await duckdb_async_1.Database.create(dbPath);
91
+ try {
92
+ await db.exec(`
93
+ CREATE TABLE actions (
94
+ call_id VARCHAR PRIMARY KEY,
95
+ class VARCHAR,
96
+ method VARCHAR,
97
+ start_time_ms DOUBLE,
98
+ end_time_ms DOUBLE,
99
+ duration_ms DOUBLE,
100
+ params JSON,
101
+ result JSON,
102
+ error VARCHAR,
103
+ before_snapshot VARCHAR,
104
+ after_snapshot VARCHAR
105
+ )
106
+ `);
107
+ await db.exec(`
108
+ CREATE INDEX idx_actions_duration ON actions(duration_ms DESC);
109
+ CREATE INDEX idx_actions_start_time ON actions(start_time_ms);
110
+ CREATE INDEX idx_actions_class_method ON actions(class, method);
111
+ `);
112
+ const stmt = await db.prepare(`
113
+ INSERT INTO actions VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
114
+ `);
115
+ for (const action of data.actions) {
116
+ await stmt.run(action.call_id, action.class, action.method, action.start_time_ms, action.end_time_ms, action.duration_ms, action.params ? JSON.stringify(action.params) : null, action.result ? JSON.stringify(action.result) : null, action.error || null, action.before_snapshot || null, action.after_snapshot || null);
117
+ }
118
+ await stmt.finalize();
119
+ }
120
+ finally {
121
+ await db.close();
122
+ }
123
+ }
124
+ //# sourceMappingURL=traceImport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceImport.js","sourceRoot":"","sources":["../../src/utils/traceImport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Page } from 'playwright';
2
+ export interface WebVitals {
3
+ fcp: number;
4
+ lcp: number;
5
+ tti: number;
6
+ cls: number;
7
+ }
8
+ export declare function captureWebVitals(page: Page): Promise<WebVitals>;
9
+ //# sourceMappingURL=webVitals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webVitals.d.ts","sourceRoot":"","sources":["../../src/utils/webVitals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAgErE"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.captureWebVitals = captureWebVitals;
4
+ async function captureWebVitals(page) {
5
+ const vitals = await page.evaluate(() => {
6
+ return new Promise((resolve) => {
7
+ const result = {};
8
+ const paintEntries = performance.getEntriesByType('paint');
9
+ const fcpEntry = paintEntries.find((entry) => entry.name === 'first-contentful-paint');
10
+ result.fcp = fcpEntry ? Math.round(fcpEntry.startTime) : 0;
11
+ let lcpValue = 0;
12
+ const lcpObserver = new PerformanceObserver((entryList) => {
13
+ const entries = entryList.getEntries();
14
+ const lastEntry = entries[entries.length - 1];
15
+ if (lastEntry && lastEntry.renderTime) {
16
+ lcpValue = Math.round(lastEntry.renderTime);
17
+ }
18
+ else if (lastEntry && lastEntry.loadTime) {
19
+ lcpValue = Math.round(lastEntry.loadTime);
20
+ }
21
+ });
22
+ try {
23
+ lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
24
+ }
25
+ catch (e) {
26
+ }
27
+ let clsValue = 0;
28
+ const clsObserver = new PerformanceObserver((entryList) => {
29
+ for (const entry of entryList.getEntries()) {
30
+ if (!entry.hadRecentInput) {
31
+ clsValue += entry.value;
32
+ }
33
+ }
34
+ });
35
+ try {
36
+ clsObserver.observe({ type: 'layout-shift', buffered: true });
37
+ }
38
+ catch (e) {
39
+ }
40
+ const navigationTiming = performance.getEntriesByType('navigation')[0];
41
+ const loadComplete = navigationTiming ? navigationTiming.loadEventEnd : 0;
42
+ result.tti = Math.round(loadComplete);
43
+ setTimeout(() => {
44
+ result.lcp = lcpValue || Math.round(loadComplete);
45
+ result.cls = Math.round(clsValue * 1000) / 1000;
46
+ lcpObserver.disconnect();
47
+ clsObserver.disconnect();
48
+ resolve(result);
49
+ }, 100);
50
+ });
51
+ });
52
+ return vitals;
53
+ }
54
+ //# sourceMappingURL=webVitals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webVitals.js","sourceRoot":"","sources":["../../src/utils/webVitals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ // Example: Multi-step login flow with automatic capture
2
+ //
3
+ // Usage: pw-debug exec examples/login-flow.js https://example.com
4
+ //
5
+ // Available in script context:
6
+ // - page, context, browser (Playwright instances)
7
+ // - args (command-line arguments after URL)
8
+ // - fs, path (Node.js modules)
9
+ // - utils.captureStep(page, stepName, action) - Capture step with auto-numbering
10
+ // - utils.writeJson, utils.writeJsonl, utils.appendJsonl
11
+
12
+ // Step 1: Navigate to login page
13
+ await utils.captureStep(page, 'goto-login', async () => {
14
+ await page.goto('https://example.com/login');
15
+ });
16
+
17
+ // Step 2: Fill email field
18
+ await utils.captureStep(page, 'fill-email', async () => {
19
+ await page.getByLabel('Email').fill('test@example.com');
20
+ });
21
+
22
+ // Step 3: Fill password field
23
+ await utils.captureStep(page, 'fill-password', async () => {
24
+ await page.getByLabel('Password').fill('password123');
25
+ });
26
+
27
+ // Step 4: Click submit button
28
+ await utils.captureStep(page, 'click-submit', async () => {
29
+ await page.getByRole('button', { name: 'Submit' }).click();
30
+ });
31
+
32
+ // Step 5: Wait for dashboard to load
33
+ await utils.captureStep(page, 'dashboard-loaded', async () => {
34
+ await page.waitForURL('**/dashboard');
35
+ });
36
+
37
+ console.log('\n✓ Login flow completed successfully!');