)]}'
{
  "commit": "a70a5700efe199c015b30b5ae6698ca62a2bb624",
  "tree": "21d354d6957b4dbdb4ca599faf85ad32b98e9a47",
  "parents": [
    "a086df3e983f572e6e5d93e1ec84479ea5d3f2fa"
  ],
  "author": {
    "name": "fiveapplesonthetable",
    "email": "fiveapplesonthetable@gmail.com",
    "time": "Thu Apr 30 22:27:22 2026 +0100"
  },
  "committer": {
    "name": "Zimuzo Ezeozue",
    "email": "zezeozue@google.com",
    "time": "Thu Apr 30 22:27:22 2026 +0100"
  },
  "message": "ui: HDE: bidirectional Object↔Flamegraph navigation\n\nObject view: surface the flamegraph as a per-path action. Each of the\ntwo retention-path sections — \"Shortest Path from GC Root\" and\n\"Dominator Tree Path\" — gets a \"View in Flamegraph\" button next to its\ntitle. The button on the shortest-path section opens the flamegraph\nwith the \"Object Size\" metric pivoted at the object\u0027s BFS-tree node;\nthe dominator-path button opens \"Dominated Object Size\" pivoted at the\nobject\u0027s dominator-tree node. The user already chose the path type\nimplicitly by being in that section, so each button maps to the metric\nwhose tree the path_hash was resolved against — no metric selector to\nreach for.\n\nPlumbing:\n  * `Section` widget gains an optional `actions: m.Children` rendered\n    to the right of the title; clicks on the actions area are isolated\n    from the toggle so an action click doesn\u0027t collapse the section.\n  * `HeapDumpExplorerSession.openFlamegraphPivotedAt(pathHash, label,\n    isDominator)` (arrow property, passed by reference into Mithril\n    attrs) directly seeds the session\u0027s flamegraph panel state with\n    the right metric and a PIVOT view, then navigates to the flamegraph\n    tab. No \"pending\" state, no consume callback, no one-shot latch.\n  * The button handler in `object_view` queries the object\u0027s\n    path_hash_stable from the corresponding stdlib table, then calls\n    `openFlamegraphPivotedAt` (passed in as an attr).\n\nPIVOT match: path_hash_stable moves from the aggregatable to the\nunaggregatable property set on every metric (and is CAST to TEXT in\nSQL — the stdlib emits INT64, but the flamegraph reads unaggregatable\ncolumns as STR_NULL). That puts it in `matchingColumns` so the PIVOT\nregex can target a specific node by its hash.\n\nChip text: the PIVOT view\u0027s `displayLabel` reads \"\u003cClass\u003e (this\ninstance)\". The \"(this instance)\" suffix tells the user this filter\nis path-specific, not class-based — typing a plain class name would\nproduce a different (class-wide) PIVOT.\n\nTogether with the previous commit\u0027s \"Show objects from this class\"\nnode action — which carries path_hash_stable into the flamegraph-\nobjects tab — this lets a user round-trip between an individual\nobject and either of its paths in the flamegraph (and vice versa)\nwithout leaving the Heap Dump Explorer. Both sides are keyed by the\nactive dump\u0027s (upid, ts).\n\nIncludes Playwright e2e coverage in\nui/src/test/heap_dump_explorer_flamegraph.test.ts: each button drives\nthe correct metric and a PIVOT chip; re-clicking the same button\nre-applies the pivot (regression coverage).\n\nChange-Id: Ibb72dbcfa29e859318fbfa41653efa79104e8371\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "bc9fd7628cca5d26f45b4f55f7da0f691003f961",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/components.ts",
      "new_id": "4e8c4d4e46486f056c2ecbcd8f1bf76b770e163b",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/components.ts"
    },
    {
      "type": "modify",
      "old_id": "b40a94279daf254d3fa8e5978e1211a74e682f48",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts",
      "new_id": "d7ea96c2d665ca99978214af6759863d544fb7fc",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts"
    },
    {
      "type": "modify",
      "old_id": "a2a43679d6a653224892e8e9775652b54ae5d3e1",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/session.ts",
      "new_id": "430204484864aa3fa1bf1debdc61e17c7033f315",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/session.ts"
    },
    {
      "type": "modify",
      "old_id": "4ba2cf83c80b7b1e1d8eb8283b3160db68c75146",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/styles.scss",
      "new_id": "220f1fe172befc64837a057c587331c7cea41808",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/styles.scss"
    },
    {
      "type": "modify",
      "old_id": "6bb49484c8d1cf1c924f2188ff406071b67870e1",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/flamegraph_view.ts",
      "new_id": "a8e0d5fead0752052bedef72710be69fe4a3720b",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/flamegraph_view.ts"
    },
    {
      "type": "modify",
      "old_id": "71a18db27688fad1d9483a284ff31bb2f058926e",
      "old_mode": 33188,
      "old_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/object_view.ts",
      "new_id": "71025331801c6b9bddb9ce8e10c51283a4e3ed7c",
      "new_mode": 33188,
      "new_path": "ui/src/plugins/com.android.HeapDumpExplorer/views/object_view.ts"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "9ff9bf298182f174874858a6b1244ed624160c34",
      "new_mode": 33188,
      "new_path": "ui/src/test/heap_dump_explorer_flamegraph.test.ts"
    }
  ]
}
