Steve Golton
90d · built 2026-07-24
90-day totals
- Commits
- 134
- Grow
- 17.9
- Maintenance
- 11.1
- Fixes
- 2.0
- Total ETV
- 31
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 26 %
- By Growth share
- Top 26 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+320.0 %
vs 15 prior
↑+37.6 pp
recent vs prior
↓-18.2 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 2.4ETVui: Simplify DataGrid schema models (#6710) Currently the schema is a record of tables keyed by name, like this: ```js { slice: { id: {}, ts: {}, dur: {}, track: {ref: 'track', ...}, // Ref to the foreign table }, track: { id: {}, name: {} }, parent: {ref: 'slice', ...}, // Recursive reference } ``` This works but is messy: - Can reference non-existent tables - must check for undefined everywhere. - The vast majority of schemas in practice are flat (single table) which means we have to nest every single schema inside a dummy table name when its totally redundant. - Field paths don't specify a 'root' table name so we must pass the 'root' (default) table name around as a string everywhere. ## The fix This patch replaces this nominal structure with a structured definition which solves all of these problems: E.g. ```js const sliceSchema = { id: {}, ts: {}, dur: {}, table: { schema: { // <-- Nested table schema id: {}, name: {} }, }, parent: { get schema() { // <-- recursive references can exist - you just have to use a getter. return sliceSchema; } }, } ``` Notes: - The recursive via getter trick is borrowed from [zod](https://zod.dev/api?id=recursive-objects#recursive-objects). - The sqlSchema (the separate schema passed to the SQLDataSource has been restructured in a similar way. - This is a big change due to the number of DataGrid call-sites, but it's mainly mechanical. Should be a no-op. Key changes: - SchemaRef.ref (string) → SchemaRef.schema (ColumnSchema), with get schema() for self-referential tables - SQLTableSchema.table → SQLTableSchema.tableOrSubquery, always wrapped in parens in generated SQL - DataGridAttrs.schema is now ColumnSchema (was SchemaRegistry), rootSchema removed - SQLDataSource config extends SQLTableSchema directly (was sqlSchema + rootSchemaName) - Add getQuery() to SQLDataSource and sub-engines for SQL inspectiongithub.com-google-perfetto · c4002e38 · 2026-07-16
- 2.2ETVui: Memscope - Live dashboard page (#5785) This patch adds a new `dev.perfetto.Memscope` UI plugin: a live memory dashboard that connects to an Android (ADB / WDP) or Linux (websocket) target, starts a lightweight trace, and renders periodically refreshed snapshots across four tabs (Processes, System, File Cache, Pressure & Swap). NOTE: In order to keep the PRs as small as possible, this is just the first part of the memscope plugin which only features the dashboard - no profiling mode is implemented yet. ## Key bits - Live tracing session (sessions/live_session.ts): low-overhead monitoring config (process_stats, sys_stats, ftrace). Polls snapshots on an interval, parsing and extracting key counter information. - Connection view (views/connection.ts): Landing page when no session is currently running. Allows the user to select a device protocol, and, if relevant, presents a device list to allow device selection. - Dashboard view: (views/dashboard.ts): Shows up when the user connects to a device and starts recording a live tracing session. Displays a toolbar showing the status of the live session and buttons to control the session, and the four tabs with a tab switcher (SegmentedButton). - Tabs: - Processes tab (views/tabs/processes.ts): Shows a few header cards showing high level system memory usage, a chart showing the sum of all processes grouped by category (arbitrary list defined in process_categories.ts), and a table of all processes with various stats spread across various columns. - System tab (views/tabs/system.ts): Shows various system level memory stats across billboards and a chart. - Page cache tab (views/tabs/page_cache.ts): Show page cache stats including usage and activity charts. - Pressure, swap and LMK tab (views/tabs/pressure_swap.ts): Displays swap usage, memory pressure and LMK events. - Process categorization (process_categories.ts): maps Android process names → high-level categories (Framework, HAL, System UI, …). Colors are assigned positionally from the chart palette so adding categories doesn't require picking hex. ## Usage / testing: - Enable the dev.perfetto.Memscope plugin & restart the page. - Click the memscope sidebar entry. - Connect to your Android/Linux device of choice. - Verify stats look correct. Press pause and play again to ensure the snapshots stop updating when paused. - Switching tabs should stop the periodic updates (and period redraws). - Stop & Open Trace produces a working trace in the main UI. - Verify category chips and OOM-bucket chips read well in both light and dark themesgithub.com-google-perfetto · a0a484ac · 2026-05-12
- 1.5ETVui: Add LLM core gateway plugin + chrome API provider + test chat page (#6509) This patch adds the following plugins: - **dev.perfetto.Llm**: A common entry point for which other plugins can access language model functionality, and protocol provider plugins can register their protocols against. - **dev.perfetto.LlmProtocolChromePrompt**: A language model provider exposing the Chrome Prompt API (on-device gemini nano model) as an LLM provider. This plugin also registers gemini-nano as a *static* provider & model, which will appear as an ever present option not available to user configuration (this is the same way that extension servers will register hard coded configurations). In the future we may disable this entire plugin, but for now it makes sense to keep it enabled and present for testing. - **dev.perfetto.LlmTestChat**: A very simple test chatbot style page used for testing the API. No tools, just allows chatting with the model for the sake of testing. RFC: https://github.com/google/perfetto/discussions/6241 Note - the LLM core registries are kept as plugins for now rather than merge into the UI core. This is to keep things cleaner while we're still working out the kinks in the protocol, and will be subsumed into the core at some point in the future. Testing: - In chrome, enable the prompt API `chrome://flags/#prompt-api-for-gemini-nano` if not enabled by default. - Enable the dev.perfetto.LlmTestChat plugin - Under `Support` in the sidebar, click the LLM test chat page <img width="303" height="236" alt="image" src="https://github.com/user-attachments/assets/037e3408-1e16-4b18-bf45-875990b4dbd2" />github.com-google-perfetto · e68c84d0 · 2026-07-03
- 1.4ETVui: Fix fuzzy search matching by replacing MiniSearch with fuzzysort (#6852) Fix odd fuzzy search behavior where search terms like 'gpucompute' did not match 'GpuCompute'. Replace MiniSearch with fuzzysort, which is built for omniboxes, and adds some better support for other things such as multi key seraching. Summary of changes: - Switch MiniSearch for fuzzysort (0 deps, bundle size reduced by 35K). - Modify the interface to allow multiple key lookup functions to be passed which is now handled natively by fuzzysort. - Add fuzzy demo page in the widgets page (#!/widgets/fuzzy-search) - Sprinkly readonly on arrays liberally where appropriate. Update FuzzyFinder to support single and multi-key lookups, allowing Omnibox command search to filter across both command names and sources with per-field match highlights. Add a Fuzzy Search demo to WidgetsPage.github.com-google-perfetto · d08db71b · 2026-07-23
- 1.3ETVui: Extract reusable components and utils out of memscope (#6435) Widgets: - Panel - Hero - Page - Billboard - ProgressBar - ColorChip - Callout (special memscope themed version) Utils: - Byte formatters (bytes_formate.ts) - Switch to using IEC units (e.g. MiB, GiB, etc) for memory Tweak styling: - In light mode make the panels white and the background gray (invert). - Add staggered fade-in animation.github.com-google-perfetto · d9c6f174 · 2026-06-30
- 1.2ETVui: Add Intelletto assistant plugin (#6512) Adds dev.perfetto.Intelletto, the conversational assistant that sits in the sidebar and uses the LLM gateway plugin. It owns the agent loop (multi-step tool use with lazy tool loading), the trace-scoped chat session and context registry, the core query/schema tools, and the sidebar chat panel. The agent drives the gateway directly: it picks the first configured model advertising the 'agentic' role and streams a turn via gateway.createStream(). The chat panel header shows that active model. RFC: https://github.com/google/perfetto/discussions/6240 Note: Plugin is not enabled while in development - so for testing, enable `dev.perfetto.Intelletto` and open the sidebar. Tools: 1. run_query — run PerfettoSQL, return rows as JSON 2. get_schema — list tables/views or a table's columns 3. get_selection — read the current UI selection 4. show_query — open a query in the Query page (mutating) 5. navigate — switch to a route, e.g. /viewer (mutating) 6. list_tools / more_tools — lazy-loading meta-tools (off by default) Context injections: 1. page — current page route 2. viewport — visible time range (start/end ns) 3. selection — current selection, if anygithub.com-google-perfetto · 1c27245e · 2026-07-04
- 1.0ETVui: Add custom SVG-based line chart component (#5783) Adds LineChartSvg - a Mithril+SVG drop-in replacement for the ECharts backed LineChart. Adds features such as series hover & tooltip emphasis, and handles updates much more cleanly without losing state compared to the echarts approach. Also, add to the widget demo page, and add features to CursorTooltip (popup position and offset).github.com-google-perfetto · f10c701f · 2026-05-11
- 0.8ETVui: Add memory over time chart + mini memory breakdown flamegraph (#6445) Add smaps based memory composition over time chart to the summary tab of the memscope landing page. This shows smaps composition over time broken down into various categories, and also doubles as a snapshot selector. <img width="1086" height="580" alt="image" src="https://github.com/user-attachments/assets/394dfc14-aa50-4fd0-9841-6d7f61b546c1" />github.com-google-perfetto · d2efecaf · 2026-07-01
- 0.7ETVui: Memscope - Profiling support (#5786) This patch adds profiling support to the memscope dashboard. - Addition of a new profile 'action' button along side each debuggable process in the process table. - Profile session (sessions/profile_session.ts): Starts a new Java + native heap tracing session with an opinionated configuration recording into ring buffers. - Profiling page (views/profile_page.ts): Displays the current status of the profiling session as well as some process stats taken from the live session data pertinent to the process being profiled. Features a cancel and stop & open button which stops and opens the trace in perfetto, switching back to the main timeline. <img width="2046" height="720" alt="image" src="https://github.com/user-attachments/assets/4cc648fb-bba3-4bc6-9e35-61a88f0b9511" /> <img width="1032" height="708" alt="image" src="https://github.com/user-attachments/assets/079030dc-e5c5-48da-ab08-98b54e94d623" />github.com-google-perfetto · 83e042ce · 2026-05-19
- 0.7ETVui: Add java memory breakdown sections to memscope (#6451) Add java sections to the memory overview page. - Java memory breakdown - Bitmaps breakdown Also pull out ratio and share bar into dedicated components.github.com-google-perfetto · 86dd58a3 · 2026-07-01
- 0.6ETVui: Datagrid: Escape dots in field names (#6721) Add splitPath/escapePath so column names containing literal dots work correctly. Rename toAlias() to quoteIdentifier(). Field names passed to datagrid (field paths) are dot separated (e.g. parent.id, or track.name) when used to reference nested tables as defined by the schema. The trouble is sometimes we provide these field names from unescaped raw values from the user, which can themselves contain dots. This patch establishes an escaping format where we dots are treated as path delimiters but double dots are escaped. E.g. - `foo.bar` -> `['foo', 'bar']` - `foo..bar` -> `['foo.bar']` - `foo...bar` -> `['foo.', 'bar']`github.com-google-perfetto · fb2aa5a1 · 2026-07-16
- 0.6ETVui: Refactor sidebar (#5606) Refactored sidebar by extracting a number of components into their own classes, and also moved the timeline menu item out into the timeline plugin. This patch is a pure refactor - no functional changes.github.com-google-perfetto · 74b90423 · 2026-04-29
- 0.6ETVui: Add SVG based histogram chart component (#5802) This patch introduces a new SVG based histogram implementation (not using echarts), similar to the newly introduced SVG based line chart component, which (compared to the echart impl): - Is stable in screenshot tests. - Looks better (no sub-pixel gaps between bars). - Gives us a lot more control to do simple yet custom things like highlighting the background of a bar, which echarts makes it difficult to do. - Fits with the UI's theme and and existing widgets much more closely. This patch contains the following changes: - New chart implementation `HistogramSVG`. - Refactor out some common reusable chart logic into common modules shared with `LineChartSvg`. - Refactor `LineChartSVG` a little to use the new common code and remove a previous hack based on keying. - Use the new svg based histogram in the slice distribution panels.github.com-google-perfetto · 99a4e9c6 · 2026-05-11
- 0.6ETVui: chore: Bump deps to patch security issues (#6160) This patch fixes the following security issues: 1. markdown-it - https://github.com/google/perfetto/security/dependabot/312 2. protobufjs - https://github.com/google/perfetto/security/dependabot/308 Note: These are not a major concern for us as this code for the most part runs client side, but worth keeping on top of this issues. ## List of packages updated | Package | Previous Version | New Version | Type | | :--- | :--- | :--- | :--- | | `typescript` | `5.5.2` | `5.9.3` | devDependencies | | `eslint` | `^9.6.0` | `^9.39.4` | devDependencies | | `@typescript-eslint/eslint-plugin` | `^7.14.1` | `^8.60.1` | devDependencies | | `@typescript-eslint/parser` | `^7.14.1` | `^8.60.1` | devDependencies | | `protobufjs` | `^7.5.6` | `^7.6.2` | dependencies | | `protobufjs-cli` | `1.2.1` | `^1.3.2` | devDependencies | | `markdown-it` | `^13.0.0` | `^14.2.0` | dependencies | | `@types/markdown-it` | `^13.0.0` | `^14.1.2` | devDependencies | | `@types/node` | `^20.14.9` | `^20.19.41` | dependencies | | `@types/w3c-web-usb` | `^1.0.10` | `^1.0.14` | dependencies | ## Updating markdown-it Updating this package kicked off a cascade of issues. - markdown-it@14 requires a newer typescript version than what we currently are using (5.5.2). For the sake of completeness this patch bumps typescript to 5.9.3 which is the latest version within the 5 major revision (moving to 6.X is another problem). - Typescript 5.7 introduced a breaking change in TypedArrays and friends (such as DataView), making these generic over the type of ArrayBuffer they use - ArrayBuffer or SharedArrayBuffer. [TS Release Notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-7.html#typedarrays-are-now-generic-over-arraybufferlike). IIUC, this is to support ES2024 changes to the API of ArrayBuffer. - A lot of libraries have been very slow to update their types to be more specific about what type of array they output, simply leaving it has Uint8Array or similar, or to allow ArrayBufferLike as inputs. - This caused a cascade of type issues through the codebase which needed to be fixed. Mostly mechanical aside from one sticking point: - protobuf.Write.finish() returns a Uint8Array, the storage type is left purposely undefined. In reality it's always going to be an ArrayBuffer type unless patched but the types have not been tweaked to address this. - This causes type issues as we try to write this into a Blob as a BlobPart which the types specify as having a requirement on ArrayBuffer (not shared). This is bogus, all environments would accept a SharedArrayBuffer anyway. - Tangentially related - a Uint8Array cannot be implicity cast to an ArrayBuffer any more - meaning the special cast in AppImpl is no longer required. - Argument of type 'Uint8Array<ArrayBuffer>' is not assignable to parameter of type 'ArrayBuffer'. - Also what's changed is that calling map.keys().next().value now returns T | undefined, but before it returned T. See [TS release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-6.html#strict-builtin-iterator-checks-and---strictbuiltiniteratorreturn).github.com-google-perfetto · adc57d9e · 2026-06-08
- 0.6ETVui: Add ability to pivot on arg values (#4976) This patch allows users to add group by argument values in the slice selection aggregation view. In order to get this working, we needed to provide much more configurability from the aggregators so this patch also reconfigures the output of the aggregators to be closer to that of the datagrid, giving them more control. All aggregators needed to be updated accordingly to fit the new interface. The only aggregator which has actually changed is the slice selection aggregator, which adds `arg_set_id` to the underlying table, and adds a new parameterised `Args` column. Testing: - Make an area selection over one or more slice tracks - Wait for the table to load - Click the triple dot dropdown in one of the group header cells -> click `Add group by` - Select an argument (or fuzzy search) to add the column <img width="959" height="378" alt="image" src="https://github.com/user-attachments/assets/fb8252a0-5695-4dcb-824b-acc203322940" /> <img width="781" height="146" alt="image" src="https://github.com/user-attachments/assets/18fe506c-7a89-49cb-a7a4-f9b53c94d17f" />github.com-google-perfetto · 7b9a30e2 · 2026-07-14
- 0.6ETVui: Add trace summary billboards to the memory overview page (#6440) Add tab strip and trace summary billboards to the memory overview page - summary section. Trace summary billboards: - Process uptime - Process OOM score - Peak RSS (Anon + swap - from counters) - Rss spike (RSS high watermark - max RSS seen - from counters) - Memory delta (smaps) - Memory rate (spams) - GC/Java churn (placeholders - not implemented yet) Also added a smaps page tab that's currently stubbed out. <img width="1405" height="310" alt="image" src="https://github.com/user-attachments/assets/454702c0-1b37-4219-b905-8b1ee67c7aaf" />github.com-google-perfetto · 8b1b64d0 · 2026-06-30
- 0.5ETVui: Add intelletto tools for building DE graphs (#6520) Inject the following tools and context injections to allow the agent to build, read and modify DE graphs. Note 1: For now, these tools are defined in the Intelletto plugin. Keeping all tool calls in this plugin doesn't scale, and plugins in general should register their own tools with the intelletto plugin to expose more functionality to the assistant (or use commands when we adapt them for model use), but this introduces a dependency that transitively enables the intelletto plugin when depended on by an default enabled plugin. I want to avoid default enabling the intelletto plugin while in development, thus we flip the dependency for the DE tools - for now. Note 2: The tools expect the model to build the DE JSON directly, so we teach it how to understand the JSON schema in the tool descriptions. Once we have Perfetto SQL Next we can transition to this. Tools: | Tool | Mutating | What it does | |------|----------|--------------| | `get_graph` | no | Returns the active Data Explorer graph as JSON (or `"<empty>"`). For the model to read what the user is exploring. | | `set_graph` | yes | Replaces the graph with supplied JSON and navigates to the Data Explorer. Structural pre-check → apply → returns per-node runtime errors so the model can iterate. Its description embeds the whole `GRAPH_FORMAT` catalog. | | `check_graph` | no | Runs the *current* graph against the trace, reports per-node errors, changes nothing. | | `validate_graph` | no | Dry-runs a *candidate* graph JSON (structural + runtime) without applying it. | Context injections: | Id | Kind | What it injects | |----|------|-----------------| | `dev.perfetto.DataExplorer#selected_node` | context | The node the user has selected in the query builder: `nodeId`, `type`, `title`, serialized `state`, and output `columns`. Lets the model resolve "this node" / "the selected step" and edit the right one. |github.com-google-perfetto · cdd6cacd · 2026-07-06
- 0.5ETVui: Add openai compatible LLM protocol (#6523) Add openai compatible LLM protocol plugin, which supports a wide range of model provider backends: - OpenAI - Local (llama.cpp, vLLM, etc...) - Openrouter - etc... Also added CSP exception to http://localhost:8080 for use with llama-server.github.com-google-perfetto · 9c4ed467 · 2026-07-06
- 0.5ETVuI: Add two new charts: ProportionBar and Flamegraph (#6429) This patch adds two new DOM based charts: ### ProportionBar A bar showing how a given metric is split across varioius categories (E.g. memory). Features an optional legend (reused from the bar chart). Similar to a pie chart. <img width="588" height="91" alt="image" src="https://github.com/user-attachments/assets/2128c314-86ad-4abf-8a60-aabce2675c87" /> ### FlamegraphChart A simpler version of the flamegraph, and a hover tooltip - to be used in overview pages. In the future we may merge this with its bigger brother flamegraph.ts or at least tweak the styling to make it more visually consistent. <img width="587" height="205" alt="image" src="https://github.com/user-attachments/assets/87bd01eb-2a64-4b36-bccd-822c054d9442" />github.com-google-perfetto · 7cd2217c · 2026-06-30
- 0.5ETVui: Add new side panel extension point (#5960) Gives plugins a place to surface their own UI alongside the main page. Plugins can register tabs against a new SidePanelManager (exposed on both App and Trace) and call showTab() open them; tabs registered via Trace are automatically torn down with the trace. The panel itself lives to the right of the page content in a resizable split, with a tab strip across registered tabs so multiple plugins can coexist without fighting over the space. Also add com.example.SidePanel example plugin which demonstrates using this panel extension point. <img width="1106" height="682" alt="image" src="https://github.com/user-attachments/assets/99a5d40b-684e-4f73-8528-7dc1c0d60306" />github.com-google-perfetto · ff8d6b24 · 2026-05-22