zeitzeuge 0.3.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -0
  3. package/dist/analysis/agent.d.ts +19 -0
  4. package/dist/analysis/agent.d.ts.map +1 -0
  5. package/dist/analysis/parser.d.ts +3 -0
  6. package/dist/analysis/parser.d.ts.map +1 -0
  7. package/dist/analysis/prompts.d.ts +2 -0
  8. package/dist/analysis/prompts.d.ts.map +1 -0
  9. package/dist/browser/capture.d.ts +14 -0
  10. package/dist/browser/capture.d.ts.map +1 -0
  11. package/dist/browser/launch.d.ts +6 -0
  12. package/dist/browser/launch.d.ts.map +1 -0
  13. package/dist/browser/runtime-trace.d.ts +52 -0
  14. package/dist/browser/runtime-trace.d.ts.map +1 -0
  15. package/dist/browser/trace.d.ts +8 -0
  16. package/dist/browser/trace.d.ts.map +1 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +1695 -0
  20. package/dist/models/init.d.ts +3 -0
  21. package/dist/models/init.d.ts.map +1 -0
  22. package/dist/output/report.d.ts +38 -0
  23. package/dist/output/report.d.ts.map +1 -0
  24. package/dist/output/terminal.d.ts +31 -0
  25. package/dist/output/terminal.d.ts.map +1 -0
  26. package/dist/sandbox/workspace.d.ts +33 -0
  27. package/dist/sandbox/workspace.d.ts.map +1 -0
  28. package/dist/schema.d.ts +64 -0
  29. package/dist/schema.d.ts.map +1 -0
  30. package/dist/types.d.ts +245 -0
  31. package/dist/types.d.ts.map +1 -0
  32. package/dist/vitest/classify.d.ts +19 -0
  33. package/dist/vitest/classify.d.ts.map +1 -0
  34. package/dist/vitest/heap-profile-parser.d.ts +12 -0
  35. package/dist/vitest/heap-profile-parser.d.ts.map +1 -0
  36. package/dist/vitest/index.d.ts +17 -0
  37. package/dist/vitest/index.d.ts.map +1 -0
  38. package/dist/vitest/index.js +1616 -0
  39. package/dist/vitest/plugin.d.ts +17 -0
  40. package/dist/vitest/plugin.d.ts.map +1 -0
  41. package/dist/vitest/profile-parser.d.ts +13 -0
  42. package/dist/vitest/profile-parser.d.ts.map +1 -0
  43. package/dist/vitest/prompts.d.ts +10 -0
  44. package/dist/vitest/prompts.d.ts.map +1 -0
  45. package/dist/vitest/reporter.d.ts +79 -0
  46. package/dist/vitest/reporter.d.ts.map +1 -0
  47. package/dist/vitest/types.d.ts +231 -0
  48. package/dist/vitest/types.d.ts.map +1 -0
  49. package/dist/vitest/workspace.d.ts +25 -0
  50. package/dist/vitest/workspace.d.ts.map +1 -0
  51. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) Christian Bromann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ <p align="center">
2
+ <img src=".github/assets/zeitzeuge.png" alt="ZeitZeuge mascot: a detective stopwatch with a magnifying glass witnessing slowdowns" width="220" />
3
+ </p>
4
+
5
+ # zeitzeuge
6
+
7
+ AI-powered performance analysis for frontend page loads and Vitest test suites. Captures V8 heap snapshots, performance traces, Chrome runtime traces, and CPU profiles — stores everything in a virtual filesystem and hands it to a Deep Agent that investigates bottlenecks and provides code-level fixes.
8
+
9
+ > _"Zeuge" = witness — the tool "witnesses" slowdowns in your page loads and test runs._
10
+
11
+ ## Quick start
12
+
13
+ ### Page-load analysis
14
+
15
+ ```bash
16
+ # Set your API key
17
+ export OPENAI_API_KEY=sk-... # or ANTHROPIC_API_KEY
18
+
19
+ # Analyze any URL
20
+ npx zeitzeuge http://localhost:3000
21
+ ```
22
+
23
+ ### Vitest integration
24
+
25
+ Add the plugin to your `vitest.config.ts` to profile your test suite and get AI-powered analysis of your **application code** performance:
26
+
27
+ ```ts
28
+ import { defineConfig } from 'vitest/config';
29
+ import { zeitzeuge } from 'zeitzeuge/vitest';
30
+
31
+ export default defineConfig({
32
+ plugins: [zeitzeuge()],
33
+ });
34
+ ```
35
+
36
+ Run your tests as usual — zeitzeuge instruments the run with V8 CPU profiling, collects the profiles, and runs a Deep Agent analysis after tests complete:
37
+
38
+ ```bash
39
+ vitest run
40
+ ```
41
+
42
+ A Markdown report is written to `zeitzeuge-report.md` with findings and suggested fixes.
43
+
44
+ ## How it works
45
+
46
+ ### Page-load mode (`npx zeitzeuge <url>`)
47
+
48
+ 1. **Launches Chrome** via WebdriverIO with DevTools Protocol access
49
+ 2. **Captures everything in one page load:**
50
+ - V8 heap snapshot (memory analysis)
51
+ - Performance trace (network waterfall, long tasks, paint timing)
52
+ - **Chrome runtime trace** via the [Tracing domain](https://chromedevtools.github.io/devtools-protocol/tot/Tracing/) — every function call, event dispatch, layout, paint, and GC event on the main thread
53
+ - All network assets (scripts, CSS, HTML source code)
54
+ 3. **Builds a VFS workspace** using `@langchain/node-vfs` — an in-memory virtual filesystem containing:
55
+ - `/heap/summary.json` — parsed heap snapshot data
56
+ - `/trace/summary.json` — page load timing & metrics
57
+ - `/trace/runtime/blocking-functions.json` — functions blocking the main thread > 50ms
58
+ - `/trace/runtime/event-listeners.json` — event listener add/remove imbalances
59
+ - `/trace/runtime/frame-breakdown.json` — time breakdown: scripting vs layout vs paint vs GC
60
+ - `/scripts/`, `/styles/`, `/html/` — actual source files
61
+ 4. **Deep Agent explores** — a LangChain Deep Agent (`deepagents`) autonomously browses the workspace, reads actual source code, greps for patterns, and correlates heap data with trace data and runtime analysis
62
+ 5. **Reports findings** — memory leaks, frame-blocking functions, listener leaks, render-blocking scripts, GC pressure — with code-level fixes
63
+
64
+ ### Vitest mode (`zeitzeuge/vitest` plugin)
65
+
66
+ 1. **Instruments Vitest** — injects `--cpu-prof` into worker process args, forces `pool: 'forks'` for reliable profiling, disables file parallelism for clean per-file profiles
67
+ 2. **Captures V8 CPU profiles** for each test file during the test run
68
+ 3. **Classifies hot functions** — every profiled function is categorized as `application`, `dependency`, `test`, or `framework` based on its file path relative to your project root
69
+ 4. **Builds a VFS workspace** containing:
70
+ - `/hot-functions/application.json` — hotspots in **your** code (primary focus)
71
+ - `/hot-functions/dependencies.json` — hotspots in third-party code
72
+ - `/scripts/application.json` — per-file CPU time for your source files
73
+ - `/scripts/dependencies.json` — per-file CPU time for dependencies
74
+ - `/profiles/*.json` — full CPU profile summaries with call trees
75
+ - `/timing/overview.json` — per-test timing data
76
+ - `/src/`, `/tests/` — actual source files referenced by hot functions
77
+ 5. **Deep Agent analyzes your application code** — focuses on bottlenecks in the code you wrote, not test infrastructure overhead. Reports dependency issues when your code makes expensive calls into libraries.
78
+
79
+ ## What it finds
80
+
81
+ ### Page-load findings
82
+
83
+ **Memory issues:**
84
+
85
+ - Memory leaks (unbounded caches, growing arrays/maps)
86
+ - Detached DOM nodes still referenced in JavaScript
87
+ - Large retained objects and closure leaks
88
+
89
+ **Page-load issues:**
90
+
91
+ - Render-blocking scripts (`<script>` without `async`/`defer`)
92
+ - Render-blocking stylesheets
93
+ - Long main-thread tasks (> 50ms)
94
+ - Oversized bundles and unused code
95
+ - Sequential waterfall bottlenecks
96
+
97
+ **Runtime issues:**
98
+
99
+ - **Frame-blocking functions** — exact function name, script URL, line number, and call stack for any function blocking the main thread > 50ms
100
+ - **Event listener leaks** — `addEventListener` calls without matching `removeEventListener`, growing listener counts
101
+ - **GC pressure** — frequent or long garbage collection pauses indicating memory churn
102
+ - **Layout thrashing** — forced synchronous layouts from reading layout properties after DOM mutations
103
+
104
+ ### Vitest analysis
105
+
106
+ **Application code bottlenecks:**
107
+
108
+ - Hot functions with high self time in your source code
109
+ - Expensive algorithms (O(n^2) loops, redundant computation, unnecessary sorting)
110
+ - Object allocation hotspots driving GC pressure
111
+ - Synchronous blocking in hot paths (file I/O, crypto, JSON serialization)
112
+
113
+ **Dependency bottlenecks:**
114
+
115
+ - Third-party libraries consuming disproportionate CPU
116
+ - Unnecessary calls to expensive dependency APIs in hot paths
117
+ - Suggestions for alternative libraries or configuration changes
118
+
119
+ **GC pressure:**
120
+
121
+ - Functions creating many short-lived objects in tight loops
122
+ - Large allocations that could be pooled or reused
123
+
124
+ ## Vitest plugin options
125
+
126
+ ```ts
127
+ zeitzeuge({
128
+ // Enable/disable the plugin (default: true)
129
+ enabled: true,
130
+
131
+ // Path for the Markdown report (default: 'zeitzeuge-report.md')
132
+ output: 'zeitzeuge-report.md',
133
+
134
+ // Directory for temporary .cpuprofile files (default: '.zeitzeuge-profiles')
135
+ profileDir: '.zeitzeuge-profiles',
136
+
137
+ // Also write V8 heap profiles (.heapprofile) for workers (default: false)
138
+ // Uses: --heap-prof + --heap-prof-dir=<profileDir>
139
+ heapProf: false,
140
+
141
+ // Run Deep Agent analysis after tests finish (default: true)
142
+ analyzeOnFinish: true,
143
+
144
+ // Project root for classifying application vs dependency code (default: process.cwd())
145
+ projectRoot: process.cwd(),
146
+
147
+ // Enable debug logging (default: false)
148
+ verbose: false,
149
+ });
150
+ ```
151
+
152
+ ### Heap profiling (`heapProf`) — when to enable it
153
+
154
+ `heapProf` captures **allocation sampling** (written as `.heapprofile` files) and can help you find:
155
+
156
+ - Allocation hotspots (functions / modules allocating lots of bytes)
157
+ - High GC pressure caused by excessive short-lived objects
158
+
159
+ It defaults to **`false`** because it can be a net negative for everyday runs:
160
+
161
+ - **Overhead**: allocation sampling adds runtime overhead and can skew timings/CPU profiles
162
+ - **Artifact size / IO**: `.heapprofile` files can be large, increasing IO and CI flakiness
163
+ - **Noise**: test runners allocate a lot in setup/framework code; heap data can be less actionable unless you’re specifically chasing allocations/GC
164
+
165
+ Recommendation: keep it off by default and enable it when you suspect **allocation/GC issues** or when CPU hotspots alone aren’t explaining slow tests.
166
+
167
+ ## CLI options
168
+
169
+ ```text
170
+ zeitzeuge <url> [options]
171
+
172
+ Options:
173
+ --verbose, -v Enable verbose/debug logging [boolean] [default: false]
174
+ --headless Run Chrome in headless mode [boolean] [default: true]
175
+ --timeout Page load timeout in milliseconds [number] [default: 30000]
176
+ --help, -h Show help [boolean]
177
+ --version Show version number [boolean]
178
+ ```
179
+
180
+ ## Environment variables
181
+
182
+ | Variable | Description |
183
+ | ------------------- | --------------------------------------------------------------- |
184
+ | `OPENAI_API_KEY` | OpenAI API key (preferred) |
185
+ | `ANTHROPIC_API_KEY` | Anthropic API key (fallback) |
186
+ | `ZEITZEUGE_MODEL` | Override model name (e.g. `gpt-4o`, `claude-sonnet-4-20250514`) |
187
+
188
+ ## Development
189
+
190
+ ```bash
191
+ # Install dependencies
192
+ bun install
193
+
194
+ # Run in development
195
+ bun run dev -- http://localhost:3000
196
+
197
+ # Run tests
198
+ bun test
199
+
200
+ # Build for distribution
201
+ bun run build
202
+ ```
203
+
204
+ ## Tech stack
205
+
206
+ - **Runtime:** [Bun](https://bun.sh) (works across JS runtimes)
207
+ - **Browser automation:** [WebdriverIO](https://webdriver.io) + Chrome DevTools Protocol
208
+ - **Runtime tracing:** [CDP Tracing domain](https://chromedevtools.github.io/devtools-protocol/tot/Tracing/) for function-level main-thread analysis
209
+ - **V8 CPU profiling:** `--cpu-prof` for per-function timing in test suites
210
+ - **AI analysis:** [Deep Agents](https://docs.langchain.com/oss/javascript/deepagents/overview) + [LangChain](https://langchain.com)
211
+ - **Virtual filesystem:** [@langchain/node-vfs](https://docs.langchain.com/oss/javascript/integrations/providers/node-vfs) — in-memory VFS sandbox
212
+ - **LLM providers:** OpenAI, Anthropic (auto-detected from environment)
@@ -0,0 +1,19 @@
1
+ import { type BackendProtocol } from 'deepagents';
2
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
3
+ import type { Finding } from '../types.js';
4
+ /**
5
+ * Analyze performance data using a Deep Agent that explores
6
+ * the workspace containing heap + trace data + source files.
7
+ */
8
+ export declare function analyze(model: BaseChatModel, backend: BackendProtocol): Promise<Finding[]>;
9
+ /**
10
+ * Analyze Vitest test performance data using a Deep Agent that explores
11
+ * the workspace containing CPU profiles + test timing + source files.
12
+ */
13
+ export declare function analyzeTestPerformance(model: BaseChatModel, backend: BackendProtocol): Promise<Finding[]>;
14
+ /**
15
+ * Format bytes into a human-readable string.
16
+ * Kept for backwards compatibility with existing imports.
17
+ */
18
+ export declare function formatBytes(bytes: number): string;
19
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/analysis/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAKjF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;GAGG;AACH,wBAAsB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkChG;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,OAAO,EAAE,CAAC,CA8BpB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD"}
@@ -0,0 +1,3 @@
1
+ import type { RawSnapshot, HeapSummary } from '../types.js';
2
+ export declare function parseSnapshot(rawSnapshot: RawSnapshot): HeapSummary;
3
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/analysis/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EAMZ,MAAM,aAAa,CAAC;AA6BrB,wBAAgB,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,CAyVnE"}
@@ -0,0 +1,2 @@
1
+ export declare const SYSTEM_PROMPT = "You are an expert web performance engineer. You have access to a virtual filesystem workspace containing captured data from a real page load: heap snapshot, network trace, and Chrome runtime trace.\n\n## Workspace structure\n\n- /heap/summary.json \u2014 Parsed V8 heap snapshot: largest objects, type stats, constructor stats, detached DOM nodes, closure stats\n- /trace/summary.json \u2014 Page load metrics: timing, long tasks, render-blocking resources, resource breakdown\n- /trace/network-waterfall.json \u2014 Every network request with timing, size, priority, render-blocking status\n- /trace/asset-manifest.json \u2014 Index of all assets with paths to stored files\n- /trace/runtime/summary.json \u2014 Runtime trace overview: frame breakdown (scripting/layout/paint/GC), blocking function count, listener imbalances, GC stats\n- /trace/runtime/blocking-functions.json \u2014 Functions that blocked the main thread > 50ms, with script URL, line number, call stack, and duration\n- /trace/runtime/event-listeners.json \u2014 Event listener add/remove counts per event type, with source locations\n- /trace/runtime/frame-breakdown.json \u2014 Time spent in scripting vs layout vs paint vs GC\n- /trace/runtime/raw-events.json \u2014 Full Chrome trace events (large file \u2014 read to investigate specific function calls, layouts, GC, and event dispatches)\n- /scripts/*.js \u2014 Actual JavaScript source files captured during page load\n- /styles/*.css \u2014 Actual CSS source files\n- /html/document.html \u2014 The HTML document\n\n## Your workflow\n\n1. Read /heap/summary.json, /trace/summary.json, AND /trace/runtime/summary.json first for the big picture\n2. Identify the highest-impact issues from all datasets\n3. For each issue, dive into the relevant source files to understand the root cause\n4. Provide specific, code-level fixes\n\n## What to look for\n\n### Memory issues (from heap data)\n- Memory leaks: unbounded arrays, maps, caches that grow without bound\n- Detached DOM nodes: DOM elements removed from the document but still referenced\n- Large retained objects: single objects or trees retaining disproportionate memory\n- Closure leaks: closures capturing variables they no longer need\n\n### Page-load issues (from trace + source code)\n- Render-blocking scripts: <script> in <head> without async/defer \u2014 read the script to judge if it must be synchronous\n- Render-blocking CSS: large stylesheets blocking first paint\n- Long tasks (> 50ms): identify the function/module causing the block by reading the source\n- Large bundles: scripts > 100KB \u2014 search for unused imports or code that could be lazy-loaded\n- Sequential waterfalls: resources chained sequentially that could load in parallel\n\n### Runtime issues (from Chrome trace)\n- Frame-blocking functions: read /trace/runtime/blocking-functions.json first, then inspect the actual script source at the reported line number to understand what the function does and how to optimize it\n- Event listener leaks: check /trace/runtime/event-listeners.json for event types where addCount >> removeCount, then grep the scripts for those addEventListener calls\n- GC pressure: high GC pause counts or duration suggest excessive short-lived object creation \u2014 look for hot loops creating objects\n- Layout thrashing: forced synchronous layouts caused by reading layout properties (offsetHeight, getBoundingClientRect) after DOM writes\n\n## Output guidelines\n\n- Report 3\u20137 findings, ordered by impact (mix of memory, page-load, and runtime if all have issues)\n- Be specific \u2014 name actual files, functions, object constructors, and retention paths\n- Provide concrete code fixes, not generic advice\n- If heap, trace, and runtime all look healthy, say so \u2014 don't manufacture issues";
2
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/analysis/prompts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,ytHAkDwD,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Browser } from 'webdriverio';
2
+ import type { CaptureResult, CaptureOptions } from '../types.js';
3
+ /**
4
+ * Capture both a heap snapshot and a performance trace from a single page load.
5
+ *
6
+ * Flow:
7
+ * 1. Set up network interception + performance tracing BEFORE navigation
8
+ * 2. Navigate to URL and wait for load
9
+ * 3. Wait for settle period (2s) to catch late-firing long tasks
10
+ * 4. Stop tracing and collect network data
11
+ * 5. Take heap snapshot (after page is loaded + settled)
12
+ */
13
+ export declare function capturePage(browser: Browser, url: string, options?: CaptureOptions): Promise<CaptureResult>;
14
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/browser/capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGjE;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAwDxB"}
@@ -0,0 +1,6 @@
1
+ import { type Browser } from 'webdriverio';
2
+ import type { LaunchOptions } from '../types.js';
3
+ export type { Browser } from 'webdriverio';
4
+ export declare function launchBrowser(options?: LaunchOptions): Promise<Browser>;
5
+ export declare function closeBrowser(browser: Browser): Promise<void>;
6
+ //# sourceMappingURL=launch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/browser/launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAsB,aAAa,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAmBjF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMlE"}
@@ -0,0 +1,52 @@
1
+ import type { TraceEvent, BlockingFunction, EventListenerInfo, FrameBreakdown, GCEvent, RuntimeTraceSummary } from '../types.js';
2
+ /**
3
+ * Parse raw Chrome trace events into a structured RuntimeTraceSummary.
4
+ *
5
+ * @param traceEvents - Array of Chrome trace events from Tracing.dataCollected
6
+ * @param navigationStartTs - Navigation start timestamp in microseconds (from trace)
7
+ */
8
+ export declare function parseRuntimeTrace(traceEvents: TraceEvent[], navigationStartTs: number): RuntimeTraceSummary;
9
+ /**
10
+ * Identify the main renderer thread (CrRendererMain).
11
+ *
12
+ * Strategy:
13
+ * 1. Look for __metadata thread_name event with args.name === "CrRendererMain"
14
+ * 2. Fallback: thread with the most FunctionCall events
15
+ * 3. Return 0 if no events
16
+ */
17
+ export declare function findMainThread(events: TraceEvent[]): number;
18
+ /**
19
+ * Extract function calls that block the main thread (> 50ms).
20
+ *
21
+ * Looks for "FunctionCall" and "EvaluateScript" events with phase "X" (complete)
22
+ * and duration > 50ms. Extracts function name, script URL, line number, and call stack.
23
+ */
24
+ export declare function extractBlockingFunctions(mainEvents: TraceEvent[], navigationStartTs: number): BlockingFunction[];
25
+ /**
26
+ * Extract event listener dispatch patterns.
27
+ *
28
+ * Groups EventDispatch events by event type and counts dispatches.
29
+ * Also collects source location information.
30
+ */
31
+ export declare function extractEventListenerInfo(mainEvents: TraceEvent[]): EventListenerInfo[];
32
+ /**
33
+ * Build a frame time breakdown from main-thread events.
34
+ *
35
+ * Categorises all events with duration into: scripting, layout, painting, gc, other.
36
+ * All values are in milliseconds.
37
+ */
38
+ export declare function buildFrameBreakdown(mainEvents: TraceEvent[]): FrameBreakdown;
39
+ /**
40
+ * Extract GC events (MajorGC, MinorGC) with timing and heap size data.
41
+ */
42
+ export declare function extractGCEvents(mainEvents: TraceEvent[], navigationStartTs: number): GCEvent[];
43
+ /**
44
+ * Find frequently dispatched events (> 10 dispatches of the same type).
45
+ * High-frequency dispatches without throttle/debounce indicate potential issues.
46
+ */
47
+ export declare function findFrequentEvents(mainEvents: TraceEvent[]): Array<{
48
+ eventType: string;
49
+ count: number;
50
+ totalDuration: number;
51
+ }>;
52
+ //# sourceMappingURL=runtime-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-trace.d.ts","sourceRoot":"","sources":["../../src/browser/runtime-trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,OAAO,EACP,mBAAmB,EACpB,MAAM,aAAa,CAAC;AA4BrB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,UAAU,EAAE,EACzB,iBAAiB,EAAE,MAAM,GACxB,mBAAmB,CAkCrB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAwB3D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,UAAU,EAAE,EACxB,iBAAiB,EAAE,MAAM,GACxB,gBAAgB,EAAE,CA6CpB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,iBAAiB,EAAE,CAkDtF;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,cAAc,CAmC5E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,EAAE,CAkB9F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EAAE,GACvB,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CA4BpE"}
@@ -0,0 +1,8 @@
1
+ import type { TraceHandle, CaptureOptions } from '../types.js';
2
+ /**
3
+ * Start tracing page load on a CDP session.
4
+ * Call this BEFORE navigation so it captures everything from the start.
5
+ * Returns a TraceHandle — call `stop()` after the page has loaded and settled.
6
+ */
7
+ export declare function tracePageLoad(cdpSession: any, _options?: CaptureOptions): Promise<TraceHandle>;
8
+ //# sourceMappingURL=trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/browser/trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMV,WAAW,EACX,cAAc,EAEf,MAAM,aAAa,CAAC;AA8BrB;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,GAAG,EACf,QAAQ,GAAE,cAAmB,GAC5B,OAAO,CAAC,WAAW,CAAC,CA4NtB"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}