@hybridlabor-api/bdb-synapse 1.1.1 → 1.2.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 (38) hide show
  1. package/internal/judge/cli.go +27 -1
  2. package/internal/server/analyze.go +1 -1
  3. package/internal/server/static/assets/{index-ndrpq0ER.js → index-Dxzi7dw9.js} +3 -3
  4. package/internal/server/static/assets/logo.svg +56 -0
  5. package/internal/server/static/assets/synapse-app-logo.svg +69 -0
  6. package/internal/server/static/assets/synapse-sidebar-logo.svg +64 -0
  7. package/internal/server/static/favicon.svg +50 -0
  8. package/internal/server/static/index.html +2 -5
  9. package/package.json +1 -1
  10. package/web/index.html +1 -4
  11. package/web/public/assets/logo.svg +56 -0
  12. package/web/public/assets/synapse-app-logo.svg +69 -0
  13. package/web/public/assets/synapse-sidebar-logo.svg +64 -0
  14. package/web/public/favicon.svg +50 -0
  15. package/web/src/ui/LogoMark.tsx +8 -30
  16. package/web/src/ui/ReportPanel.tsx +11 -1
  17. package/web/src/ui/SessionRail.tsx +7 -6
  18. package/bin/synapse +0 -0
  19. package/bin/synapse-darwin-arm64 +0 -0
  20. package/bin/synapse-linux-amd64 +0 -0
  21. package/bin/synapse.exe +0 -0
  22. package/web/dist/assets/fraunces-latin-ext-standard-italic-CGbN9UgK.woff2 +0 -0
  23. package/web/dist/assets/fraunces-latin-ext-standard-normal-CJcjJNj7.woff2 +0 -0
  24. package/web/dist/assets/fraunces-latin-standard-italic-lSdLDfvT.woff2 +0 -0
  25. package/web/dist/assets/fraunces-latin-standard-normal-DihXLNYH.woff2 +0 -0
  26. package/web/dist/assets/fraunces-vietnamese-standard-italic-DxWqP7Ku.woff2 +0 -0
  27. package/web/dist/assets/fraunces-vietnamese-standard-normal-Czevyj-6.woff2 +0 -0
  28. package/web/dist/assets/index-BNoY_BiB.css +0 -1
  29. package/web/dist/assets/index-ndrpq0ER.js +0 -3
  30. package/web/dist/assets/index-ndrpq0ER.js.map +0 -1
  31. package/web/dist/assets/react-gcHzaSmV.js +0 -10
  32. package/web/dist/assets/react-gcHzaSmV.js.map +0 -1
  33. package/web/dist/assets/schibsted-grotesk-latin-ext-wght-normal-hsMS0n0O.woff2 +0 -0
  34. package/web/dist/assets/schibsted-grotesk-latin-wght-normal-Bb8VGrTG.woff2 +0 -0
  35. package/web/dist/assets/three-DnGjZfD1.js +0 -4012
  36. package/web/dist/assets/three-DnGjZfD1.js.map +0 -1
  37. package/web/dist/index.html +0 -26
  38. package/web/tsconfig.tsbuildinfo +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-ndrpq0ER.js","sources":["../../node_modules/lucide-react/dist/esm/shared/src/utils.js","../../node_modules/lucide-react/dist/esm/defaultAttributes.js","../../node_modules/lucide-react/dist/esm/Icon.js","../../node_modules/lucide-react/dist/esm/createLucideIcon.js","../../node_modules/lucide-react/dist/esm/icons/bot.js","../../node_modules/lucide-react/dist/esm/icons/circle.js","../../node_modules/lucide-react/dist/esm/icons/crosshair.js","../../node_modules/lucide-react/dist/esm/icons/ellipsis.js","../../node_modules/lucide-react/dist/esm/icons/eye-off.js","../../node_modules/lucide-react/dist/esm/icons/eye.js","../../node_modules/lucide-react/dist/esm/icons/folder-open.js","../../node_modules/lucide-react/dist/esm/icons/info.js","../../node_modules/lucide-react/dist/esm/icons/loader.js","../../node_modules/lucide-react/dist/esm/icons/mountain.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-close.js","../../node_modules/lucide-react/dist/esm/icons/panel-left-open.js","../../node_modules/lucide-react/dist/esm/icons/pause.js","../../node_modules/lucide-react/dist/esm/icons/play.js","../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js","../../node_modules/lucide-react/dist/esm/icons/rotate-ccw.js","../../node_modules/lucide-react/dist/esm/icons/search.js","../../node_modules/lucide-react/dist/esm/icons/sparkles.js","../../node_modules/lucide-react/dist/esm/icons/step-back.js","../../node_modules/lucide-react/dist/esm/icons/step-forward.js","../../node_modules/lucide-react/dist/esm/icons/tree-pine.js","../../node_modules/lucide-react/dist/esm/icons/triangle-alert.js","../../node_modules/lucide-react/dist/esm/icons/users.js","../../node_modules/lucide-react/dist/esm/icons/video.js","../../node_modules/lucide-react/dist/esm/icons/x.js","../../src/api/client.ts","../../src/ui/Dock.tsx","../../src/ui/AgentsPanel.tsx","../../src/ui/ReportPanel.tsx","../../src/ui/ViewPanel.tsx","../../src/playback/reducer.ts","../../src/playback/recorder.ts","../../src/types.ts","../../src/scene/textures.ts","../../src/scene/dirLabels.ts","../../src/scene/sceneUtils.ts","../../src/scene/trail.ts","../../src/scene/CityScene.tsx","../../src/scene/treeLayout.ts","../../src/scene/TreeScene.tsx","../../src/state/filters.ts","../../node_modules/zustand/esm/vanilla.mjs","../../node_modules/zustand/esm/react.mjs","../../src/state/store.ts","../../src/ui/Hud.tsx","../../src/ui/Inspector.tsx","../../src/ui/LogoMark.tsx","../../src/ui/shortcuts.ts","../../src/ui/SessionRail.tsx","../../src/ui/Timeline.tsx","../../src/App.tsx","../../src/main.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 8V4H8\", key: \"hb8ula\" }],\n [\"rect\", { width: \"16\", height: \"12\", x: \"4\", y: \"8\", rx: \"2\", key: \"enze0r\" }],\n [\"path\", { d: \"M2 14h2\", key: \"vft8re\" }],\n [\"path\", { d: \"M20 14h2\", key: \"4cs60a\" }],\n [\"path\", { d: \"M15 13v2\", key: \"1xurst\" }],\n [\"path\", { d: \"M9 13v2\", key: \"rq6x2g\" }]\n];\nconst Bot = createLucideIcon(\"bot\", __iconNode);\n\nexport { __iconNode, Bot as default };\n//# sourceMappingURL=bot.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }]];\nconst Circle = createLucideIcon(\"circle\", __iconNode);\n\nexport { __iconNode, Circle as default };\n//# sourceMappingURL=circle.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"line\", { x1: \"22\", x2: \"18\", y1: \"12\", y2: \"12\", key: \"l9bcsi\" }],\n [\"line\", { x1: \"6\", x2: \"2\", y1: \"12\", y2: \"12\", key: \"13hhkx\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"6\", y2: \"2\", key: \"10w3f3\" }],\n [\"line\", { x1: \"12\", x2: \"12\", y1: \"22\", y2: \"18\", key: \"15g9kq\" }]\n];\nconst Crosshair = createLucideIcon(\"crosshair\", __iconNode);\n\nexport { __iconNode, Crosshair as default };\n//# sourceMappingURL=crosshair.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"1\", key: \"41hilf\" }],\n [\"circle\", { cx: \"19\", cy: \"12\", r: \"1\", key: \"1wjl8i\" }],\n [\"circle\", { cx: \"5\", cy: \"12\", r: \"1\", key: \"1pcz8c\" }]\n];\nconst Ellipsis = createLucideIcon(\"ellipsis\", __iconNode);\n\nexport { __iconNode, Ellipsis as default };\n//# sourceMappingURL=ellipsis.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\",\n key: \"ct8e1f\"\n }\n ],\n [\"path\", { d: \"M14.084 14.158a3 3 0 0 1-4.242-4.242\", key: \"151rxh\" }],\n [\n \"path\",\n {\n d: \"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\",\n key: \"13bj9a\"\n }\n ],\n [\"path\", { d: \"m2 2 20 20\", key: \"1ooewy\" }]\n];\nconst EyeOff = createLucideIcon(\"eye-off\", __iconNode);\n\nexport { __iconNode, EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\",\n key: \"1nclc0\"\n }\n ],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n];\nconst Eye = createLucideIcon(\"eye\", __iconNode);\n\nexport { __iconNode, Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\",\n key: \"usdka0\"\n }\n ]\n];\nconst FolderOpen = createLucideIcon(\"folder-open\", __iconNode);\n\nexport { __iconNode, FolderOpen as default };\n//# sourceMappingURL=folder-open.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"10\", key: \"1mglay\" }],\n [\"path\", { d: \"M12 16v-4\", key: \"1dtifu\" }],\n [\"path\", { d: \"M12 8h.01\", key: \"e9boi3\" }]\n];\nconst Info = createLucideIcon(\"info\", __iconNode);\n\nexport { __iconNode, Info as default };\n//# sourceMappingURL=info.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 2v4\", key: \"3427ic\" }],\n [\"path\", { d: \"m16.2 7.8 2.9-2.9\", key: \"r700ao\" }],\n [\"path\", { d: \"M18 12h4\", key: \"wj9ykh\" }],\n [\"path\", { d: \"m16.2 16.2 2.9 2.9\", key: \"1bxg5t\" }],\n [\"path\", { d: \"M12 18v4\", key: \"jadmvz\" }],\n [\"path\", { d: \"m4.9 19.1 2.9-2.9\", key: \"bwix9q\" }],\n [\"path\", { d: \"M2 12h4\", key: \"j09sii\" }],\n [\"path\", { d: \"m4.9 4.9 2.9 2.9\", key: \"giyufr\" }]\n];\nconst Loader = createLucideIcon(\"loader\", __iconNode);\n\nexport { __iconNode, Loader as default };\n//# sourceMappingURL=loader.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [[\"path\", { d: \"m8 3 4 8 5-5 5 15H2L8 3z\", key: \"otkl63\" }]];\nconst Mountain = createLucideIcon(\"mountain\", __iconNode);\n\nexport { __iconNode, Mountain as default };\n//# sourceMappingURL=mountain.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m16 15-3-3 3-3\", key: \"14y99z\" }]\n];\nconst PanelLeftClose = createLucideIcon(\"panel-left-close\", __iconNode);\n\nexport { __iconNode, PanelLeftClose as default };\n//# sourceMappingURL=panel-left-close.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"3\", rx: \"2\", key: \"afitv7\" }],\n [\"path\", { d: \"M9 3v18\", key: \"fh3hqa\" }],\n [\"path\", { d: \"m14 9 3 3-3 3\", key: \"8010ee\" }]\n];\nconst PanelLeftOpen = createLucideIcon(\"panel-left-open\", __iconNode);\n\nexport { __iconNode, PanelLeftOpen as default };\n//# sourceMappingURL=panel-left-open.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"rect\", { x: \"14\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"kaeet6\" }],\n [\"rect\", { x: \"5\", y: \"3\", width: \"5\", height: \"18\", rx: \"1\", key: \"1wsw3u\" }]\n];\nconst Pause = createLucideIcon(\"pause\", __iconNode);\n\nexport { __iconNode, Pause as default };\n//# sourceMappingURL=pause.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\",\n key: \"10ikf1\"\n }\n ]\n];\nconst Play = createLucideIcon(\"play\", __iconNode);\n\nexport { __iconNode, Play as default };\n//# sourceMappingURL=play.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8\", key: \"v9h5vc\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }],\n [\"path\", { d: \"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16\", key: \"3uifl3\" }],\n [\"path\", { d: \"M8 16H3v5\", key: \"1cv678\" }]\n];\nconst RefreshCw = createLucideIcon(\"refresh-cw\", __iconNode);\n\nexport { __iconNode, RefreshCw as default };\n//# sourceMappingURL=refresh-cw.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\", key: \"1357e3\" }],\n [\"path\", { d: \"M3 3v5h5\", key: \"1xhq8a\" }]\n];\nconst RotateCcw = createLucideIcon(\"rotate-ccw\", __iconNode);\n\nexport { __iconNode, RotateCcw as default };\n//# sourceMappingURL=rotate-ccw.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z\",\n key: \"1s2grr\"\n }\n ],\n [\"path\", { d: \"M20 2v4\", key: \"1rf3ol\" }],\n [\"path\", { d: \"M22 4h-4\", key: \"gwowj6\" }],\n [\"circle\", { cx: \"4\", cy: \"20\", r: \"2\", key: \"6kqj1y\" }]\n];\nconst Sparkles = createLucideIcon(\"sparkles\", __iconNode);\n\nexport { __iconNode, Sparkles as default };\n//# sourceMappingURL=sparkles.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M13.971 4.285A2 2 0 0 1 17 6v12a2 2 0 0 1-3.029 1.715l-9.997-5.998a2 2 0 0 1-.003-3.432z\",\n key: \"19qhus\"\n }\n ],\n [\"path\", { d: \"M21 20V4\", key: \"cb8qj8\" }]\n];\nconst StepBack = createLucideIcon(\"step-back\", __iconNode);\n\nexport { __iconNode, StepBack as default };\n//# sourceMappingURL=step-back.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M10.029 4.285A2 2 0 0 0 7 6v12a2 2 0 0 0 3.029 1.715l9.997-5.998a2 2 0 0 0 .003-3.432z\",\n key: \"1ystz2\"\n }\n ],\n [\"path\", { d: \"M3 4v16\", key: \"1ph11n\" }]\n];\nconst StepForward = createLucideIcon(\"step-forward\", __iconNode);\n\nexport { __iconNode, StepForward as default };\n//# sourceMappingURL=step-forward.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m17 14 3 3.3a1 1 0 0 1-.7 1.7H4.7a1 1 0 0 1-.7-1.7L7 14h-.3a1 1 0 0 1-.7-1.7L9 9h-.2A1 1 0 0 1 8 7.3L12 3l4 4.3a1 1 0 0 1-.8 1.7H15l3 3.3a1 1 0 0 1-.7 1.7H17Z\",\n key: \"cpyugq\"\n }\n ],\n [\"path\", { d: \"M12 22v-3\", key: \"kmzjlo\" }]\n];\nconst TreePine = createLucideIcon(\"tree-pine\", __iconNode);\n\nexport { __iconNode, TreePine as default };\n//# sourceMappingURL=tree-pine.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\",\n key: \"wmoenq\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n];\nconst TriangleAlert = createLucideIcon(\"triangle-alert\", __iconNode);\n\nexport { __iconNode, TriangleAlert as default };\n//# sourceMappingURL=triangle-alert.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2\", key: \"1yyitq\" }],\n [\"path\", { d: \"M16 3.128a4 4 0 0 1 0 7.744\", key: \"16gr8j\" }],\n [\"path\", { d: \"M22 21v-2a4 4 0 0 0-3-3.87\", key: \"kshegd\" }],\n [\"circle\", { cx: \"9\", cy: \"7\", r: \"4\", key: \"nufk8\" }]\n];\nconst Users = createLucideIcon(\"users\", __iconNode);\n\nexport { __iconNode, Users as default };\n//# sourceMappingURL=users.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\",\n key: \"ftymec\"\n }\n ],\n [\"rect\", { x: \"2\", y: \"6\", width: \"14\", height: \"12\", rx: \"2\", key: \"158x01\" }]\n];\nconst Video = createLucideIcon(\"video\", __iconNode);\n\nexport { __iconNode, Video as default };\n//# sourceMappingURL=video.js.map\n","/**\n * @license lucide-react v0.561.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"M18 6 6 18\", key: \"1bl5f8\" }],\n [\"path\", { d: \"m6 6 12 12\", key: \"d8bk6v\" }]\n];\nconst X = createLucideIcon(\"x\", __iconNode);\n\nexport { __iconNode, X as default };\n//# sourceMappingURL=x.js.map\n","import type { AgentGraph, CityMap, JudgeChoice, ReportStatus, SessionMeta, Trace } from \"../types\";\n\nasync function getJSON<T>(url: string): Promise<T> {\n const res = await fetch(url);\n if (!res.ok) {\n const detail = (await res.text()).trim();\n throw new Error(detail || `${res.status} ${res.statusText}`);\n }\n return res.json() as Promise<T>;\n}\n\n// raw fetch failures read like stack noise in the toast; translate the two\n// failure shapes (server gone vs. server said no) into something actionable\nexport function describeError(err: unknown, doing: string): string {\n if (err instanceof TypeError) {\n return `Can't reach the Synapse server while ${doing} — is it still running?`;\n }\n const detail = (err instanceof Error ? err.message : String(err)).trim();\n return detail ? `Couldn't finish ${doing}: ${detail}` : `Couldn't finish ${doing}`;\n}\n\nexport function listSessions(fresh = false): Promise<SessionMeta[]> {\n return getJSON<SessionMeta[]>(fresh ? \"/api/sessions?fresh=1\" : \"/api/sessions\");\n}\n\nexport function getTrace(key: string): Promise<Trace> {\n return getJSON<Trace>(`/api/sessions/${encodeURIComponent(key)}/trace`);\n}\n\nexport function getCityMap(key: string): Promise<CityMap> {\n return getJSON<CityMap>(`/api/sessions/${encodeURIComponent(key)}/citymap`);\n}\n\nexport function getSessionSnapshot(key: string): Promise<{ trace: Trace; city: CityMap }> {\n return getJSON<{ trace: Trace; city: CityMap }>(`/api/sessions/${encodeURIComponent(key)}/snapshot`);\n}\n\nexport function getSessionAgents(rootKey: string): Promise<AgentGraph> {\n return getJSON<AgentGraph>(`/api/sessions/${encodeURIComponent(rootKey)}/agents`);\n}\n\nexport function getAgentTrace(rootKey: string, agentID: string): Promise<Trace> {\n return getJSON<Trace>(\n `/api/sessions/${encodeURIComponent(rootKey)}/agents/${encodeURIComponent(agentID)}/trace`\n );\n}\n\nexport function getSessionReport(key: string): Promise<ReportStatus> {\n return getJSON<ReportStatus>(`/api/sessions/${encodeURIComponent(key)}/report`);\n}\n\n// kicks off a judge run on the server; progress is observed by polling\n// getSessionReport until state leaves \"running\". The choice picks judge CLI\n// and model; omitted fields fall back to the server's defaults.\nexport async function startSessionAnalyze(key: string, choice?: JudgeChoice): Promise<ReportStatus> {\n const res = await fetch(`/api/sessions/${encodeURIComponent(key)}/analyze`, {\n method: \"POST\",\n headers: choice ? { \"Content-Type\": \"application/json\" } : undefined,\n body: choice ? JSON.stringify(choice) : undefined\n });\n if (!res.ok) {\n const detail = (await res.text()).trim();\n throw new Error(detail || `${res.status} ${res.statusText}`);\n }\n return res.json() as Promise<ReportStatus>;\n}\n\n// backs the static full-repo map view: the citymap for a repo, with no session\n// or trace attached. Without a repo path the server falls back to its\n// configured RepoRoot (the `mindwalk map <repo>` case).\nexport function getRepoMap(repo?: string): Promise<CityMap> {\n const url = repo ? `/api/repomap?repo=${encodeURIComponent(repo)}` : \"/api/repomap\";\n return getJSON<CityMap>(url);\n}\n","import type { LucideIcon } from \"lucide-react\";\nimport { useEffect, useRef, type ReactNode } from \"react\";\n\nexport type PanelPresentation = \"sheet\" | \"pop\";\nexport type PanelSection = \"scene\" | \"session\";\nexport type PanelBadge = \"running\" | \"done\" | \"stale\" | \"failed\";\n\n/**\n * One dock panel, declared as data. Extending the dock — a layers toggle, a\n * compare view, a metrics board — means registering one descriptor here;\n * the strip, grouping, badges, and open/close behavior come for free.\n */\nexport interface PanelDescriptor {\n id: string;\n icon: LucideIcon;\n hint: string;\n /** scene = how the stage renders; session = depth content about the trace */\n section: PanelSection;\n /** sheet = full-height paper, one at a time; pop = compact card anchored\n * to the strip, coexists with an open sheet */\n presentation: PanelPresentation;\n badge?: PanelBadge | null;\n render: () => ReactNode;\n}\n\ninterface DockProps {\n panels: PanelDescriptor[];\n openSheet: string | null;\n openPop: string | null;\n onToggle: (panel: PanelDescriptor) => void;\n onClosePop: () => void;\n}\n\nexport function Dock({ panels, openSheet, openPop, onToggle, onClosePop }: DockProps) {\n const popRef = useRef<HTMLDivElement | null>(null);\n const stripRef = useRef<HTMLDivElement | null>(null);\n const sheet = panels.find((panel) => panel.id === openSheet && panel.presentation === \"sheet\");\n const pop = panels.find((panel) => panel.id === openPop && panel.presentation === \"pop\");\n const sections: PanelSection[] = [\"scene\", \"session\"];\n const grouped = sections\n .map((section) => ({ section, items: panels.filter((panel) => panel.section === section) }))\n .filter((group) => group.items.length > 0);\n\n // pops are transient: click-away or Escape dismisses, like any menu; the\n // strip is exempt so the toggle button doesn't dismiss-then-reopen\n useEffect(() => {\n if (!pop) return;\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (popRef.current?.contains(target) || stripRef.current?.contains(target)) return;\n onClosePop();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onClosePop();\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [pop, onClosePop]);\n\n return (\n <div className=\"dock\">\n {/* anchored left of the whole dock: beside the sheet when one is open,\n beside the strip otherwise — never covering either */}\n {pop ? (\n <div className=\"dock-pop\" ref={popRef}>\n {pop.render()}\n </div>\n ) : null}\n {sheet ? <aside className=\"dock-panel\">{sheet.render()}</aside> : null}\n <div className=\"dock-side\" ref={stripRef}>\n {/* toggle buttons, not tabs: panels open as pops or sheets with no\n tabpanel relationship, so aria-pressed is the honest semantic */}\n <div className=\"dock-strip\" role=\"group\" aria-label=\"Stage panels\">\n {grouped.map((group, index) => (\n <div key={group.section} className=\"dock-strip-group\">\n {index > 0 ? <div className=\"dock-strip-divider\" aria-hidden /> : null}\n {group.items.map((panel) => {\n const active = panel.id === openSheet || panel.id === openPop;\n const Icon = panel.icon;\n return (\n <button\n key={panel.id}\n aria-pressed={active}\n className={active ? \"active\" : \"\"}\n onClick={() => onToggle(panel)}\n data-hint={panel.hint}\n aria-label={panel.hint}\n >\n <Icon size={15} />\n {panel.badge ? <span className={`dock-dot dock-dot-${panel.badge}`} /> : null}\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n </div>\n );\n}\n","import { AlertTriangle, Bot, Circle, Info, Loader, RefreshCw, X } from \"lucide-react\";\nimport { Fragment, useEffect, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { AgentGraph, AgentNode } from \"../types\";\n\ninterface AgentsPanelProps {\n graph?: AgentGraph;\n current: string | null;\n loading: boolean;\n loadingAgentID?: string;\n locked?: boolean;\n error?: string;\n retryAgentID?: string | null;\n onSelect: (agentID: string | null) => void;\n onRetry: () => void;\n onClose: () => void;\n}\n\ntype AgentDetailState = {\n agentID: string;\n mode: \"preview\" | \"pinned\";\n anchor: HTMLElement;\n} | null;\n\ninterface PopoverPosition {\n left: number;\n top: number;\n width: number;\n maxHeight: number;\n}\n\nexport function AgentsPanel({\n graph,\n current,\n loading,\n loadingAgentID,\n locked = false,\n error,\n retryAgentID,\n onSelect,\n onRetry,\n onClose\n}: AgentsPanelProps) {\n const children = graph?.agents.filter((agent) => agent.kind !== \"main\") ?? [];\n const main = graph?.agents.find((agent) => agent.kind === \"main\");\n const graphError = error && retryAgentID === null ? error : undefined;\n const [detail, setDetail] = useState<AgentDetailState>(null);\n const detailAgent = graph?.agents.find((agent) => agent.id === detail?.agentID);\n\n useEffect(() => {\n if (detail && graph && !detailAgent) setDetail(null);\n }, [detail, detailAgent, graph]);\n\n const closePanel = () => {\n setDetail(null);\n onClose();\n };\n\n return (\n <div className=\"dock-body agents-panel\" aria-label=\"Agent lenses\">\n <div className=\"inspector-head\">\n <div>\n <div className=\"inspector-path\">Agents</div>\n <div className=\"agents-head-note\">Choose one trace at a time</div>\n </div>\n <button className=\"icon-btn\" onClick={closePanel} title=\"Close\" aria-label=\"Close agents\">\n <X size={15} />\n </button>\n </div>\n\n {graphError ? (\n <AgentError error={graphError} locked={locked} onRetry={onRetry} />\n ) : null}\n\n <div className=\"agent-list\" aria-busy={loading || loadingAgentID !== undefined}>\n <button\n className={\n current === null ? \"agent-row agent-row-select active\" : \"agent-row agent-row-select\"\n }\n aria-pressed={current === null}\n disabled={locked}\n onClick={() => onSelect(null)}\n >\n <span className=\"agent-row-icon\" aria-hidden>\n <Circle size={12} />\n </span>\n <span className=\"agent-row-copy\">\n <span className=\"agent-row-primary\">\n <span className=\"agent-row-title\">\n Main\n {current === null ? <span className=\"agent-current\">current</span> : null}\n </span>\n <span className=\"agent-row-count\">{eventCount(main?.traceEventCount ?? 0)}</span>\n </span>\n <span className=\"agent-row-secondary\">Root trace</span>\n </span>\n </button>\n\n {children.map((agent) => {\n const rowError = error && retryAgentID === agent.id ? error : undefined;\n return (\n <Fragment key={agent.id}>\n <AgentRow\n agent={agent}\n current={current === agent.id}\n loading={loadingAgentID === agent.id}\n locked={locked}\n onSelect={onSelect}\n detailMode={detail?.agentID === agent.id ? detail.mode : undefined}\n onPreview={(anchor) =>\n setDetail((currentDetail) =>\n currentDetail?.mode === \"pinned\"\n ? currentDetail\n : { agentID: agent.id, mode: \"preview\", anchor }\n )\n }\n onPreviewEnd={(agentID) =>\n setDetail((currentDetail) =>\n currentDetail?.agentID === agentID && currentDetail.mode === \"preview\"\n ? null\n : currentDetail\n )\n }\n onToggleDetails={(anchor) =>\n setDetail((currentDetail) =>\n currentDetail?.agentID === agent.id && currentDetail.mode === \"pinned\"\n ? null\n : { agentID: agent.id, mode: \"pinned\", anchor }\n )\n }\n />\n {rowError ? (\n <AgentError error={rowError} locked={locked} onRetry={onRetry} rowLocal />\n ) : null}\n </Fragment>\n );\n })}\n\n {graph && children.length === 0 ? <p className=\"agents-empty\">No child agents found.</p> : null}\n {!graph && loading ? (\n <p className=\"agents-state\" aria-live=\"polite\">\n <Loader size={13} className=\"spin\" aria-hidden />\n Loading agents…\n </p>\n ) : null}\n </div>\n\n {detail && detailAgent ? (\n <AgentDetailPopover agent={detailAgent} state={detail} onClose={() => setDetail(null)} />\n ) : null}\n </div>\n );\n}\n\nfunction AgentError({\n error,\n locked,\n onRetry,\n rowLocal = false\n}: {\n error: string;\n locked: boolean;\n onRetry: () => void;\n rowLocal?: boolean;\n}) {\n return (\n <div className={rowLocal ? \"agents-error row-local\" : \"agents-error\"} role=\"alert\">\n <span>\n <AlertTriangle size={14} aria-hidden />\n {error}\n </span>\n <button className=\"agents-retry\" onClick={onRetry} disabled={locked}>\n <RefreshCw size={13} aria-hidden />\n Retry\n </button>\n </div>\n );\n}\n\nfunction AgentRow({\n agent,\n current,\n loading,\n locked,\n onSelect,\n detailMode,\n onPreview,\n onPreviewEnd,\n onToggleDetails\n}: {\n agent: AgentNode;\n current: boolean;\n loading: boolean;\n locked: boolean;\n onSelect: (agentID: string | null) => void;\n detailMode?: \"preview\" | \"pinned\";\n onPreview: (anchor: HTMLElement) => void;\n onPreviewEnd: (agentID: string) => void;\n onToggleDetails: (anchor: HTMLElement) => void;\n}) {\n const available = agent.traceAvailability === \"available\";\n const status = agentStatus(agent, loading);\n const secondary = [agent.role, agent.instructionPreview].filter(Boolean).join(\" · \");\n const disabled = !available || locked;\n\n return (\n <div\n className={[\"agent-row\", current ? \"active\" : \"\", disabled ? \"disabled\" : \"\"]\n .filter(Boolean)\n .join(\" \")}\n onMouseEnter={(event) => onPreview(event.currentTarget)}\n onMouseLeave={() => onPreviewEnd(agent.id)}\n onFocus={(event) => onPreview(event.currentTarget)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null)) {\n onPreviewEnd(agent.id);\n }\n }}\n >\n <button\n className=\"agent-row-select\"\n style={{ paddingLeft: `${12 + Math.min(agent.depth, 4) * 14}px` }}\n aria-pressed={current}\n disabled={disabled}\n onClick={() => onSelect(agent.id)}\n aria-label={`${agent.label}, ${status}`}\n >\n <span className=\"agent-row-icon\" aria-hidden>\n {loading ? <Loader size={13} className=\"spin\" /> : <Bot size={13} />}\n </span>\n <span className=\"agent-row-copy\">\n <span className=\"agent-row-primary\">\n <span className=\"agent-row-title\">\n {agent.label}\n {current ? <span className=\"agent-current\">current</span> : null}\n </span>\n <span className={`agent-row-count agent-status-${agent.traceAvailability}`}>\n {status}\n </span>\n </span>\n <span className=\"agent-row-secondary\">{secondary || \"No launch details\"}</span>\n </span>\n </button>\n <button\n className=\"agent-row-detail-trigger\"\n aria-label={`${detailMode === \"pinned\" ? \"Unpin\" : \"Pin\"} details for ${agent.label}`}\n aria-pressed={detailMode === \"pinned\"}\n onClick={(event) => {\n event.stopPropagation();\n onToggleDetails(event.currentTarget.closest(\".agent-row\") as HTMLElement);\n }}\n >\n <Info size={12} aria-hidden />\n </button>\n </div>\n );\n}\n\nfunction AgentDetailPopover({\n agent,\n state,\n onClose\n}: {\n agent: AgentNode;\n state: NonNullable<AgentDetailState>;\n onClose: () => void;\n}) {\n const margin = 12;\n const popoverRef = useRef<HTMLDivElement>(null);\n const [position, setPosition] = useState<PopoverPosition>({\n left: margin,\n top: margin,\n width: Math.min(520, window.innerWidth - margin * 2),\n maxHeight: window.innerHeight - margin * 2\n });\n\n useLayoutEffect(() => {\n const updatePosition = () => {\n const gap = 12;\n const width = Math.min(520, window.innerWidth - margin * 2);\n const anchorRect = state.anchor.getBoundingClientRect();\n const leftCandidate = anchorRect.left - width - gap;\n const rightCandidate = anchorRect.right + gap;\n const left =\n leftCandidate >= margin\n ? leftCandidate\n : rightCandidate + width <= window.innerWidth - margin\n ? rightCandidate\n : Math.min(\n Math.max(anchorRect.left, margin),\n window.innerWidth - width - margin\n );\n const maxHeight = window.innerHeight - margin * 2;\n const measuredHeight = Math.min(popoverRef.current?.offsetHeight ?? maxHeight, maxHeight);\n const top = Math.min(\n Math.max(anchorRect.top, margin),\n window.innerHeight - measuredHeight - margin\n );\n setPosition({ left, top, width, maxHeight });\n };\n\n const animatedPanel = state.anchor.closest(\".dock-panel\");\n updatePosition();\n window.addEventListener(\"resize\", updatePosition);\n window.addEventListener(\"scroll\", updatePosition, true);\n animatedPanel?.addEventListener(\"animationend\", updatePosition);\n return () => {\n window.removeEventListener(\"resize\", updatePosition);\n window.removeEventListener(\"scroll\", updatePosition, true);\n animatedPanel?.removeEventListener(\"animationend\", updatePosition);\n };\n }, [state.anchor]);\n\n useEffect(() => {\n if (state.mode !== \"pinned\") return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") onClose();\n };\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (popoverRef.current?.contains(target) || state.anchor.contains(target)) return;\n onClose();\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n };\n }, [onClose, state.anchor, state.mode]);\n\n return createPortal(\n <div\n ref={popoverRef}\n className={`agent-detail-popover ${state.mode}`}\n role={state.mode === \"preview\" ? \"tooltip\" : \"dialog\"}\n aria-label={`${agent.label} details`}\n style={position}\n >\n <div className=\"agent-detail-head\">\n <span>\n <strong>{agent.label}</strong>\n {agent.role ? <span>{agent.role}</span> : null}\n </span>\n {state.mode === \"pinned\" ? (\n <button className=\"agent-detail-close\" onClick={onClose} aria-label=\"Close details\">\n <X size={14} aria-hidden />\n </button>\n ) : null}\n </div>\n {agent.instructionPreview ? (\n <div className=\"agent-detail-instruction\">{agent.instructionPreview}</div>\n ) : null}\n <div className=\"agent-detail-meta\">{agentDetail(agent)}</div>\n </div>,\n document.body\n );\n}\n\nfunction agentStatus(agent: AgentNode, loading: boolean): string {\n if (loading) return \"Loading trace…\";\n if (agent.traceAvailability === \"missing\") return \"Trace missing\";\n if (agent.status === \"failed\") return \"Launch failed · no trace\";\n if (agent.traceAvailability === \"unavailable\") return \"Trace unavailable\";\n return eventCount(agent.traceEventCount);\n}\n\nfunction eventCount(count: number): string {\n return `${count} event${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction agentDetail(agent: AgentNode): string {\n return `Launch: ${agent.status} · Trace: ${agent.traceAvailability} · Correlation: ${agent.linkQuality} via ${agent.linkMethod}`;\n}\n","import { useCallback, useState, type ReactNode } from \"react\";\nimport { AlertTriangle, RefreshCw, Sparkles, X } from \"lucide-react\";\nimport type {\n JudgeChoice,\n ReportDimension,\n ReportFinding,\n ReportStatus,\n Rubric,\n RubricCriterion,\n RubricTask,\n Severity,\n Verdict\n} from \"../types\";\n\ninterface ReportPanelProps {\n status?: ReportStatus;\n analyzing: boolean;\n locked: boolean;\n onAnalyze: (choice: JudgeChoice) => void;\n onClose: () => void;\n /** jump the playhead to an evidence seq and focus its file in the scene */\n onJumpTo: (seq: number) => void;\n}\n\nconst DIMENSION_WORDS: Record<string, { title: string; hint: string }> = {\n exploration: { title: \"Exploration\", hint: \"Did the agent build enough understanding before editing?\" },\n scope: { title: \"Scope\", hint: \"Does the footprint match what the task needed?\" },\n wandering: { title: \"Wandering\", hint: \"Purposeful path, or circles and dead ends?\" },\n verification: { title: \"Verification\", hint: \"Were edits verified, and errors followed up?\" }\n};\n\n/** the mainstream models each judge CLI can be pinned to; \"\" keeps its default */\nconst JUDGE_MODELS: Record<string, { value: string; label: string }[]> = {\n claude: [\n { value: \"\", label: \"default model\" },\n { value: \"sonnet\", label: \"sonnet\" },\n { value: \"opus\", label: \"opus\" },\n { value: \"fable\", label: \"fable\" }\n ],\n codex: [\n { value: \"\", label: \"default model\" },\n { value: \"gpt-5.6-sol\", label: \"gpt-5.6 sol\" },\n { value: \"gpt-5.6-terra\", label: \"gpt-5.6 terra\" }\n ]\n};\n\nconst JUDGE_CHOICE_KEY = \"mindwalk:judge-choice\";\n\nfunction loadStoredChoice(): JudgeChoice {\n try {\n const raw = localStorage.getItem(JUDGE_CHOICE_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as Partial<JudgeChoice>;\n return {\n cli: typeof parsed.cli === \"string\" ? parsed.cli : \"\",\n model: typeof parsed.model === \"string\" ? parsed.model : \"\"\n };\n }\n } catch {\n // corrupt storage reads as \"no preference\"\n }\n return { cli: \"\", model: \"\" };\n}\n\n/** clamp a stored choice to what is actually installed and offered */\nfunction resolveChoice(choice: JudgeChoice, clis: string[]): JudgeChoice {\n const cli = clis.includes(choice.cli) ? choice.cli : (clis[0] ?? \"\");\n const models = JUDGE_MODELS[cli] ?? [];\n const model = models.some((m) => m.value === choice.model) ? choice.model : \"\";\n return { cli, model };\n}\n\n// dock panel content: the session evaluation. The Dock owns positioning;\n// this owns only its own markup.\nexport function ReportPanel({ status, analyzing, locked, onAnalyze, onClose, onJumpTo }: ReportPanelProps) {\n // the judge choice persists across sessions and reloads; the picker shows\n // wherever a run can start (empty, failed, stale)\n const [storedChoice, setStoredChoice] = useState<JudgeChoice>(loadStoredChoice);\n const clis = status?.judgeClis ?? (status?.judgeCli ? [status.judgeCli] : []);\n const choice = resolveChoice(storedChoice, clis);\n const changeChoice = useCallback((next: JudgeChoice) => {\n setStoredChoice(next);\n try {\n localStorage.setItem(JUDGE_CHOICE_KEY, JSON.stringify(next));\n } catch {\n // storage full or unavailable — the selection still applies this session\n }\n }, []);\n const analyze = useCallback(() => onAnalyze(choice), [onAnalyze, choice]);\n\n return (\n <div className=\"dock-body\" aria-label=\"Session evaluation\">\n <div className=\"inspector-head\">\n <div>\n <div className=\"inspector-path\">Evaluation</div>\n {status?.report ? (\n <div className=\"report-meta\">\n judged by {status.report.judge.cli}\n {status.report.judge.model ? ` · ${status.report.judge.model}` : \"\"} ·{\" \"}\n {day(status.report.judge.generatedAt)}\n </div>\n ) : null}\n </div>\n <button className=\"icon-btn\" onClick={onClose} title=\"Close\" aria-label=\"Close evaluation\">\n <X size={15} />\n </button>\n </div>\n <PanelBody\n status={status}\n analyzing={analyzing}\n locked={locked}\n analyze={analyze}\n onJumpTo={onJumpTo}\n picker={clis.length > 0 ? <JudgePicker clis={clis} choice={choice} onChange={changeChoice} /> : null}\n />\n </div>\n );\n}\n\nfunction JudgePicker({\n clis,\n choice,\n onChange\n}: {\n clis: string[];\n choice: JudgeChoice;\n onChange: (choice: JudgeChoice) => void;\n}) {\n const models = JUDGE_MODELS[choice.cli] ?? [{ value: \"\", label: \"default model\" }];\n return (\n <div className=\"report-picker\">\n <select\n value={choice.cli}\n onChange={(e) => onChange({ cli: e.target.value, model: \"\" })}\n aria-label=\"Judge agent\"\n title=\"Which agent CLI judges this session\"\n >\n {clis.map((cli) => (\n <option key={cli} value={cli}>\n {cli}\n </option>\n ))}\n </select>\n <select\n value={choice.model}\n onChange={(e) => onChange({ ...choice, model: e.target.value })}\n aria-label=\"Judge model\"\n title=\"Which model the judge runs on\"\n >\n {models.map((model) => (\n <option key={model.value} value={model.value}>\n {model.label}\n </option>\n ))}\n </select>\n </div>\n );\n}\n\nfunction PanelBody({\n status,\n analyzing,\n locked,\n analyze,\n onJumpTo,\n picker\n}: {\n status?: ReportStatus;\n analyzing: boolean;\n locked: boolean;\n analyze: () => void;\n onJumpTo: (seq: number) => void;\n picker: ReactNode;\n}) {\n if (!status) {\n return <p className=\"report-note\">Checking for an existing report…</p>;\n }\n if (status.state === \"running\" || analyzing) {\n return (\n <div className=\"report-note\">\n <p className=\"report-running\">Judging the trajectory…</p>\n <p>\n The judge first drafts task-specific criteria from your request, then scores the session against\n them plus four process dimensions. Usually a minute or two; you can keep exploring meanwhile.\n </p>\n </div>\n );\n }\n if (status.state === \"failed\") {\n return (\n <div className=\"report-note\">\n <p className=\"report-error\">\n <AlertTriangle size={13} /> Evaluation failed\n </p>\n <p className=\"report-error-detail\">{status.error}</p>\n {picker}\n <button className=\"report-run\" onClick={analyze}>\n <RefreshCw size={13} />\n Retry\n </button>\n </div>\n );\n }\n if (status.state === \"none\" || !status.report) {\n if (!status.judgeAvailable) {\n return (\n <p className=\"report-note\">\n Evaluation needs a local agent CLI as judge. Install <code>claude</code> or <code>codex</code> and\n make it available on PATH.\n </p>\n );\n }\n return (\n <div className=\"report-note\">\n <p>\n Ask an agent to evaluate this session: how it explored, whether the footprint matched the task,\n where it wandered, and how it verified its work. Every finding links back to the timeline.\n </p>\n {picker}\n <button className=\"report-run\" onClick={analyze}>\n <Sparkles size={13} />\n Evaluate session\n </button>\n <p className=\"report-cost\">\n Runs the selected CLI under your own account and sends it a summary of this session — task wording,\n file paths, event digests — for the model to read. About a minute.\n </p>\n </div>\n );\n }\n\n const report = status.report;\n return (\n <div className=\"report-body\">\n <div className=\"report-controls\">\n {status.stale ? (\n <p className=\"report-stale-note\">\n Based on {report.session.eventCount} events — the session has grown since.\n </p>\n ) : null}\n <div className=\"report-stale-actions\">\n {picker}\n <button\n className=\"report-rerun\"\n onClick={analyze}\n title={status.stale ? \"Re-evaluate with the current trace\" : \"Run a fresh evaluation of this session\"}\n >\n <RefreshCw size={12} />\n Re-evaluate\n </button>\n </div>\n </div>\n {/* the lede: one line of what was asked, then the judge's overview —\n the report reads summary-first, details after */}\n <p className=\"report-task\">{report.taskSummary}</p>\n <p className=\"report-narrative\">{report.narrative}</p>\n <RubricSection rubric={report.rubric} locked={locked} onJumpTo={onJumpTo} />\n <p className=\"report-chapter\">Process</p>\n {report.dimensions.map((dimension) => (\n <Dimension key={dimension.name} dimension={dimension} locked={locked} onJumpTo={onJumpTo} />\n ))}\n {report.notableMoments?.length ? (\n <section className=\"report-section\">\n <p className=\"eyebrow\">Moments</p>\n {report.notableMoments.map((moment) => (\n <button\n key={moment.seq}\n className=\"report-moment\"\n onClick={() => onJumpTo(moment.seq)}\n disabled={locked}\n title={`Jump to step ${moment.seq + 1}`}\n >\n <strong>#{moment.seq + 1}</strong>\n <span>{moment.note}</span>\n </button>\n ))}\n </section>\n ) : null}\n </div>\n );\n}\n\n// the task-accounting layer: rubric criteria grouped by task, between the\n// task summary and the four process dimensions. Absent or unavailable\n// rubrics collapse to a single quiet line — the fixed layer never waits.\nfunction RubricSection({\n rubric,\n locked,\n onJumpTo\n}: {\n rubric?: Rubric;\n locked: boolean;\n onJumpTo: (seq: number) => void;\n}) {\n if (!rubric) {\n return <p className=\"report-rubric-note\">This report has no task rubric — re-evaluate to add one.</p>;\n }\n if (rubric.status !== \"scored\" || !rubric.tasks?.length) {\n const text =\n rubric.reason === \"generation-failed\"\n ? \"Task rubric unavailable this run — showing process dimensions only.\"\n : rubric.reason === \"no-events\"\n ? \"No tool events to evidence a rubric.\"\n : \"Not enough task text to build a rubric from.\";\n return <p className=\"report-rubric-note\">{text}</p>;\n }\n const tasks = rubric.tasks;\n const criteria = tasks.flatMap((task) => task.criteria);\n const thin = criteria.filter((criterion) => criterion.coverage && criterion.coverage !== \"sufficient\");\n const showHint = criteria.length > 0 && thin.length / criteria.length > 0.4;\n const multi = tasks.length > 1;\n return (\n <div className=\"report-rubric\">\n <p className=\"report-chapter\">Tasks</p>\n {showHint ? (\n <p className=\"report-rubric-hint\">\n {thin.length} of {criteria.length} criteria had thin evidence — the log may not show enough to\n judge them.\n </p>\n ) : null}\n {tasks.map((task, i) => (\n // anchor seqs are validated disjoint across tasks, so the first one is\n // a unique stable key; titles are LLM-authored and may collide\n <RubricTaskBlock\n key={task.anchorSeqs?.[0] ?? `task-${i}`}\n task={task}\n multi={multi}\n locked={locked}\n onJumpTo={onJumpTo}\n />\n ))}\n {rubric.note ? (\n <div className=\"report-rubric-footnote\">\n <p className=\"eyebrow\">Rubric note</p>\n <p>{rubric.note}</p>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction RubricTaskBlock({\n task,\n multi,\n locked,\n onJumpTo\n}: {\n task: RubricTask;\n multi: boolean;\n locked: boolean;\n onJumpTo: (seq: number) => void;\n}) {\n const startSeq = task.anchorSeqs?.[0];\n return (\n <section className=\"report-rubric-task\">\n {multi ? (\n // single-task sessions skip the header: the criteria read like a\n // fifth..nth dimension and the layout stays close to what it was\n <button\n className=\"rubric-task-head\"\n onClick={() => {\n if (startSeq !== undefined) onJumpTo(startSeq);\n }}\n disabled={locked || startSeq === undefined}\n title={startSeq !== undefined ? `Jump to this task's start (step ${startSeq + 1})` : undefined}\n >\n {/* no state dot here: each criterion below carries its own verdict\n chip, and severity dots stay the panel's only dot vocabulary */}\n <span className=\"rubric-task-title\">\n {task.title}\n {task.type ? <span className=\"rubric-task-type\">{task.type}</span> : null}\n </span>\n </button>\n ) : null}\n {task.criteria.map((criterion) => (\n <Criterion key={criterion.id} criterion={criterion} locked={locked} onJumpTo={onJumpTo} />\n ))}\n </section>\n );\n}\n\n// a criterion renders exactly like a dimension — same head, chip, and\n// finding buttons — plus a muted coverage badge when evidence ran thin\nfunction Criterion({\n criterion,\n locked,\n onJumpTo\n}: {\n criterion: RubricCriterion;\n locked: boolean;\n onJumpTo: (seq: number) => void;\n}) {\n const hint = [\n criterion.why,\n criterion.good ? `good: ${criterion.good}` : \"\",\n criterion.bad ? `bad: ${criterion.bad}` : \"\"\n ]\n .filter(Boolean)\n .join(\"\\n\");\n return (\n <section className=\"report-dimension report-criterion\">\n <div className=\"report-dimension-head\">\n <span className=\"report-criterion-name\" title={hint || undefined}>\n {criterion.title}\n </span>\n <span className=\"report-criterion-badges\">\n {criterion.coverage === \"partial\" ? <span className=\"coverage-badge\">partial evidence</span> : null}\n <span\n className={`verdict verdict-${criterion.verdict}`}\n title={\n criterion.coverage === \"none\"\n ? \"The log cannot evidence this criterion either way\"\n : undefined\n }\n >\n {verdictWord(criterion.verdict)}\n </span>\n </span>\n </div>\n {criterion.findings.map((finding) => (\n <FindingButton key={`${finding.severity}|${finding.evidenceSeqs?.join(\",\")}|${finding.claim}`} finding={finding} locked={locked} onJumpTo={onJumpTo} />\n ))}\n </section>\n );\n}\n\nfunction FindingButton({\n finding,\n locked,\n onJumpTo\n}: {\n finding: ReportFinding;\n locked: boolean;\n onJumpTo: (seq: number) => void;\n}) {\n return (\n <button\n className=\"report-finding\"\n onClick={() => {\n const seq = finding.evidenceSeqs?.[0];\n if (seq !== undefined) onJumpTo(seq);\n }}\n disabled={locked || !finding.evidenceSeqs?.length}\n title={\n finding.evidenceSeqs?.length\n ? `Jump to step ${finding.evidenceSeqs[0] + 1} — evidence: ${finding.evidenceSeqs.map((seq) => `#${seq + 1}`).join(\" \")}`\n : undefined\n }\n >\n <span className={`severity-dot ${severityClass(finding.severity)}`} />\n <span className=\"report-claim\">{finding.claim}</span>\n </button>\n );\n}\n\nfunction Dimension({\n dimension,\n locked,\n onJumpTo\n}: {\n dimension: ReportDimension;\n locked: boolean;\n onJumpTo: (seq: number) => void;\n}) {\n const words = DIMENSION_WORDS[dimension.name] ?? { title: dimension.name, hint: \"\" };\n return (\n <section className=\"report-dimension\">\n <div className=\"report-dimension-head\" data-hint={words.hint}>\n <span className=\"report-dimension-name\">{words.title}</span>\n <span className={`verdict verdict-${dimension.verdict}`}>{verdictWord(dimension.verdict)}</span>\n </div>\n {dimension.findings.map((finding) => (\n <FindingButton key={`${finding.severity}|${finding.evidenceSeqs?.join(\",\")}|${finding.claim}`} finding={finding} locked={locked} onJumpTo={onJumpTo} />\n ))}\n </section>\n );\n}\n\nfunction verdictWord(verdict: Verdict): string {\n return verdict === \"insufficient-data\" ? \"no signal\" : verdict;\n}\n\nfunction severityClass(severity: Severity): string {\n return `sev-${severity}`;\n}\n\nfunction day(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n return d.toISOString().slice(0, 10);\n}\n","import { Mountain, TreePine } from \"lucide-react\";\nimport type { SceneView } from \"../state/store\";\n\ninterface ViewPanelProps {\n view: SceneView;\n onViewChange: (view: SceneView) => void;\n /** the legend line for the active view (\"glow ∝ revisits\", …) */\n note: string;\n /** during video export the scene canvas must not be swapped */\n locked?: boolean;\n}\n\n// pop content for the dock's scene section: how the stage renders. Future\n// layer toggles (line-level lights, trail length, floor contrast) join this\n// panel instead of growing the strip.\nexport function ViewPanel({ view, onViewChange, note, locked = false }: ViewPanelProps) {\n return (\n // toggle buttons rather than a radiogroup: the full radio pattern would\n // demand roving tabindex + arrow-key navigation these buttons don't have\n <div className=\"view-pop\" role=\"group\" aria-label=\"Scene view\">\n <button\n aria-pressed={view === \"tree\"}\n className={view === \"tree\" ? \"view-row active\" : \"view-row\"}\n onClick={() => onViewChange(\"tree\")}\n disabled={locked}\n >\n <TreePine size={14} />\n <span>Tree</span>\n </button>\n <button\n aria-pressed={view === \"terrain\"}\n className={view === \"terrain\" ? \"view-row active\" : \"view-row\"}\n onClick={() => onViewChange(\"terrain\")}\n disabled={locked}\n >\n <Mountain size={14} />\n <span>Terrain</span>\n </button>\n <p className=\"view-note\">\n {note}\n <span className=\"view-key\">V</span>\n </p>\n </div>\n );\n}\n","import type { CityMap, Target, Touch, Trace, TraceEvent } from \"../types\";\n\nexport const touchRank: Record<Touch, number> = {\n hit: 1,\n read: 2,\n edit: 3\n};\n\nexport interface FilePlayback {\n touchByFile: Map<number, Touch>;\n touchByPath: Map<string, Touch>;\n visitsByFile: Map<number, number>;\n historyByPath: Map<string, TraceEvent[]>;\n recentTargets: Target[];\n}\n\nconst RECENT_WINDOW = 12;\n\n// Incremental playback state. Stepping the playhead forward applies only the\n// events it crossed; scrubbing backward replays from the start once. Snapshots\n// share the engine's live collections — consumers must treat them as read-only\n// and re-read whenever the snapshot identity changes (one fresh wrapper per\n// snapshotAt call).\nexport class PlaybackEngine {\n private readonly events: TraceEvent[];\n private readonly idByPath = new Map<string, number>();\n private cursor = -1;\n private readonly touchByFile = new Map<number, Touch>();\n private readonly touchByPath = new Map<string, Touch>();\n private readonly visitsByFile = new Map<number, number>();\n private readonly historyByPath = new Map<string, TraceEvent[]>();\n private readonly recentTargets: Target[] = [];\n\n constructor(trace: Trace | undefined, city: CityMap | undefined) {\n this.events = trace?.events ?? [];\n for (const file of city?.files ?? []) {\n this.idByPath.set(file.path, file.id);\n }\n }\n\n snapshotAt(seq: number): FilePlayback {\n const lastSeq = Math.min(seq, this.events.length - 1);\n if (lastSeq < this.cursor) this.reset();\n for (let i = this.cursor + 1; i <= lastSeq; i++) {\n this.apply(this.events[i]);\n }\n this.cursor = Math.max(this.cursor, lastSeq);\n return {\n touchByFile: this.touchByFile,\n touchByPath: this.touchByPath,\n visitsByFile: this.visitsByFile,\n historyByPath: this.historyByPath,\n recentTargets: this.recentTargets\n };\n }\n\n private reset() {\n this.cursor = -1;\n this.touchByFile.clear();\n this.touchByPath.clear();\n this.visitsByFile.clear();\n this.historyByPath.clear();\n this.recentTargets.length = 0;\n }\n\n private apply(event: TraceEvent) {\n for (const target of event.targets) {\n const prev = this.touchByPath.get(target.path);\n if (!prev || touchRank[target.touch] > touchRank[prev]) {\n this.touchByPath.set(target.path, target.touch);\n }\n const fileId = target.fileId ?? this.idByPath.get(target.path);\n if (fileId !== undefined) {\n const prevFile = this.touchByFile.get(fileId);\n if (!prevFile || touchRank[target.touch] > touchRank[prevFile]) {\n this.touchByFile.set(fileId, target.touch);\n }\n this.visitsByFile.set(fileId, (this.visitsByFile.get(fileId) ?? 0) + 1);\n }\n const history = this.historyByPath.get(target.path);\n if (history) history.push(event);\n else this.historyByPath.set(target.path, [event]);\n }\n if (event.targets.length > 0) {\n // the trail follows the strongest signal: skip weak (heuristic) targets\n const primary = event.targets.find((target) => !target.weak) ?? event.targets[0];\n this.recentTargets.push({ ...primary, fileId: primary.fileId ?? this.idByPath.get(primary.path) });\n if (this.recentTargets.length > RECENT_WINDOW) this.recentTargets.shift();\n }\n }\n}\n","// Client-side video export: capture the live WebGL canvas with MediaRecorder\n// while driving the playhead from the first event to the last, then hand back a\n// webm Blob. No server, no extra dependency — captureStream + MediaRecorder are\n// native browser APIs.\n\nexport interface RecordOptions {\n canvas: HTMLCanvasElement;\n total: number; // number of playback events (trace.events.length)\n setSeq: (seq: number) => void; // drives the store's currentSeq\n fps?: number; // capture frame rate\n durationMs?: number; // wall-clock length of the exported run\n onProgress?: (fraction: number) => void; // 0..1\n signal?: AbortSignal; // cancel an in-flight recording\n}\n\nexport interface RecordResult {\n blob: Blob;\n extension: string; // matches the recorded container (webm / mp4 / …)\n}\n\n// Map a MediaRecorder mimeType to a sensible file extension. Falls back to the\n// container subtype when it's an unknown-but-plausible type.\nfunction extensionForMime(mimeType: string): string {\n const base = mimeType.split(\";\")[0].trim().toLowerCase(); // strip codecs\n const subtype = base.split(\"/\")[1] ?? \"\";\n if (subtype.includes(\"webm\")) return \"webm\";\n if (subtype.includes(\"mp4\")) return \"mp4\";\n if (subtype.includes(\"x-matroska\") || subtype.includes(\"matroska\")) return \"mkv\";\n if (subtype.includes(\"ogg\")) return \"ogv\";\n return subtype || \"webm\";\n}\n\nconst DEFAULT_FPS = 30;\n// Long sessions would otherwise produce minutes of video; cap the run and let\n// the playhead cover more events per frame. Short sessions play close to\n// real-ish time via the per-event floor.\nconst MAX_DURATION_MS = 30_000;\nconst PER_EVENT_MS = 120;\n\nfunction pickMimeType(): string | undefined {\n const candidates = [\"video/webm;codecs=vp9\", \"video/webm;codecs=vp8\", \"video/webm\"];\n for (const type of candidates) {\n if (typeof MediaRecorder !== \"undefined\" && MediaRecorder.isTypeSupported(type)) return type;\n }\n return undefined;\n}\n\nexport function recordingSupported(): boolean {\n return (\n typeof MediaRecorder !== \"undefined\" &&\n typeof HTMLCanvasElement !== \"undefined\" &&\n typeof HTMLCanvasElement.prototype.captureStream === \"function\"\n );\n}\n\n// Records the playback and resolves with the recorded blob and a file extension\n// that matches the actual container. Rejects if the browser can't record or the\n// run is aborted.\nexport function recordPlayback(opts: RecordOptions): Promise<RecordResult> {\n const { canvas, total, setSeq, onProgress, signal } = opts;\n const fps = opts.fps ?? DEFAULT_FPS;\n\n if (!recordingSupported()) {\n return Promise.reject(new Error(\"This browser can't record the canvas (MediaRecorder unavailable).\"));\n }\n if (total <= 0) {\n return Promise.reject(new Error(\"Nothing to record — load a session first.\"));\n }\n\n const durationMs = opts.durationMs ?? Math.min(MAX_DURATION_MS, Math.max(1000, total * PER_EVENT_MS));\n const mimeType = pickMimeType();\n const stream = canvas.captureStream(fps);\n const recorder = mimeType ? new MediaRecorder(stream, { mimeType }) : new MediaRecorder(stream);\n const chunks: BlobPart[] = [];\n\n return new Promise<RecordResult>((resolve, reject) => {\n let rafId = 0;\n let startTs = 0;\n let settled = false;\n\n const cleanup = () => {\n if (rafId) cancelAnimationFrame(rafId);\n stream.getTracks().forEach((track) => track.stop());\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n const finish = () => {\n if (settled) return;\n settled = true;\n cleanup();\n // the browser may have chosen a container different from what we\n // requested; trust recorder.mimeType so the blob type and file extension\n // match what was actually recorded\n const actualType = recorder.mimeType || mimeType || \"video/webm\";\n resolve({ blob: new Blob(chunks, { type: actualType }), extension: extensionForMime(actualType) });\n };\n\n const fail = (err: Error) => {\n if (settled) return;\n settled = true;\n cleanup();\n try {\n if (recorder.state !== \"inactive\") recorder.stop();\n } catch {\n // recorder already torn down\n }\n reject(err);\n };\n\n const onAbort = () => fail(new Error(\"Recording cancelled.\"));\n\n recorder.ondataavailable = (e) => {\n if (e.data && e.data.size > 0) chunks.push(e.data);\n };\n recorder.onerror = () => fail(new Error(\"Recording failed.\"));\n recorder.onstop = finish;\n\n if (signal) {\n if (signal.aborted) {\n fail(new Error(\"Recording cancelled.\"));\n return;\n }\n signal.addEventListener(\"abort\", onAbort);\n }\n\n const tick = (ts: number) => {\n if (settled) return;\n if (!startTs) startTs = ts;\n const fraction = Math.min(1, (ts - startTs) / durationMs);\n const seq = Math.min(total - 1, Math.floor(fraction * (total - 1)));\n setSeq(seq);\n onProgress?.(fraction);\n if (fraction >= 1) {\n // let the final frame paint before closing the recorder\n rafId = requestAnimationFrame(() => {\n if (recorder.state !== \"inactive\") recorder.stop();\n });\n return;\n }\n rafId = requestAnimationFrame(tick);\n };\n\n setSeq(0);\n recorder.start();\n rafId = requestAnimationFrame(tick);\n });\n}\n\n// Triggers a browser download of the recorded Blob.\nexport function downloadBlob(blob: Blob, filename: string): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n // revoke on the next tick so the download has a chance to start\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n}\n","export type Action = \"search\" | \"read\" | \"edit\" | \"exec\" | \"verify\" | \"other\";\nexport type Touch = \"hit\" | \"read\" | \"edit\";\n\n/** the words the HUD legend uses for each touch state — every surface that\n * names a touch must speak this vocabulary, not the wire values */\nexport function touchWord(touch?: Touch): string {\n switch (touch) {\n case \"hit\":\n return \"seen\";\n case \"read\":\n return \"read\";\n case \"edit\":\n return \"edited\";\n default:\n return \"unvisited\";\n }\n}\n\nexport interface SessionMeta {\n key: string;\n id: string;\n harness: string;\n title?: string;\n path: string;\n cwd?: string;\n model?: string;\n gitBranch?: string;\n startedAt?: string;\n endedAt?: string;\n eventCount: number;\n /** user-turn count; with eventCount, the badge's cheap staleness signal */\n userTurns?: number;\n /** evaluation state for the rail badge; absent when never evaluated */\n reportState?: \"running\" | \"done\" | \"stale\" | \"failed\";\n}\n\nexport type AgentKind = \"main\" | \"subagent\";\nexport type AgentStatus = \"main\" | \"launched\" | \"failed\" | \"unknown\";\nexport type TraceAvailability = \"available\" | \"missing\" | \"unavailable\";\nexport type AgentLinkQuality = \"exact\" | \"derived\" | \"unavailable\";\nexport type AgentLinkMethod =\n | \"root\"\n | \"codex-agent-id\"\n | \"codex-parent-thread-id\"\n | \"claude-tool-use-id\"\n | \"claude-subagents-directory\"\n | \"unavailable\";\n\nexport interface AgentGraph {\n version: number;\n rootSessionKey: string;\n agents: AgentNode[];\n}\n\nexport interface AgentNode {\n id: string;\n parentId?: string;\n depth: number;\n kind: AgentKind;\n label: string;\n role?: string;\n instructionPreview?: string;\n launchSeq?: number;\n launchCallId?: string;\n status: AgentStatus;\n traceAvailability: TraceAvailability;\n traceSessionKey?: string;\n traceEventCount: number;\n linkQuality: AgentLinkQuality;\n linkMethod: AgentLinkMethod;\n}\n\nexport interface Rect {\n x: number;\n z: number;\n w: number;\n d: number;\n}\n\nexport interface CityMap {\n version: number;\n repo: {\n root: string;\n commit?: string;\n dirty: boolean;\n generatedAt: string;\n /** the tree holds more files than the map shows — a scan budget cut in */\n truncated?: boolean;\n };\n files: CityFile[];\n dirs: CityDir[];\n layout: {\n algorithm: string;\n weight: string;\n };\n}\n\nexport interface CityFile {\n id: number;\n path: string;\n dir: string;\n lines: number;\n bytes: number;\n lang?: string;\n rect: Rect;\n ghost: boolean;\n}\n\nexport interface CityDir {\n path: string;\n depth: number;\n rect: Rect;\n fileCount: number;\n lines: number;\n}\n\nexport interface Trace {\n version: number;\n session: {\n id: string;\n harness: string;\n model?: string;\n title?: string;\n cwd?: string;\n commit?: string;\n startedAt?: string;\n endedAt?: string;\n eventCount: number;\n path?: string;\n };\n events: TraceEvent[];\n marks: Mark[];\n stats: Stats;\n}\n\nexport interface TraceEvent {\n seq: number;\n ts?: string;\n tool: string;\n action: Action;\n targets: Target[];\n outside?: OutsideTouch[];\n resultBytes: number;\n isError: boolean;\n outcomeKnown?: boolean;\n summary: string;\n}\n\nexport interface Target {\n path: string;\n fileId?: number;\n touch: Touch;\n lines?: [number, number][];\n weak?: boolean;\n}\n\nexport interface OutsideTouch {\n scope: \"home\" | \"tmp\" | \"other\";\n path: string;\n}\n\nexport interface Mark {\n seq: number;\n type: \"compaction\" | \"user-message\" | \"subagent\";\n note?: string;\n}\n\nexport interface Stats {\n filesInRepo: number;\n fovea: number;\n parafovea: number;\n edited: number;\n eventsBeforeFirstEdit: number;\n regressionRate: number;\n errorRate: number;\n actions: ActionCounts;\n errors: ActionCounts;\n maxEditsPerFile: number;\n /** files edited in three or more events */\n churnFiles: number;\n userTurns: number;\n compactions: number;\n subagents: number;\n resultBytes: number;\n /** edit events after the last verify event; every edit event when the session never verified */\n editsAfterLastVerify: number;\n observability: Observability;\n}\n\n/**\n * Grades each derived metric's source signal: \"exact\" when the harness\n * records it structurally, \"estimated\" when inferred from command or output\n * text, \"unavailable\" when the log carries no usable signal.\n */\nexport interface Observability {\n reads: MetricObservability;\n errors: MetricObservability;\n}\n\nexport type MetricObservability = \"exact\" | \"estimated\" | \"unavailable\";\n\n/** LLM-assisted evaluation of one session; verdicts are server-derived\n * from finding severities, never decided by the judge itself */\nexport interface Report {\n version: number;\n session: {\n id: string;\n harness: string;\n model?: string;\n /** event count the report was generated from — the staleness signal */\n eventCount: number;\n };\n judge: {\n cli: string;\n /** the LLM that actually judged, as reported by the CLI itself */\n model?: string;\n promptVersion: number;\n /** set only when the report carries a scored rubric */\n rubricPromptVersion?: number;\n generatedAt: string;\n };\n taskSummary: string;\n dimensions: ReportDimension[];\n /** task-accounting layer; absent on --no-rubric and pre-rubric reports */\n rubric?: Rubric;\n notableMoments?: ReportMoment[];\n narrative: string;\n}\n\nexport type RubricStatus = \"scored\" | \"unavailable\";\nexport type RubricReason = \"generation-failed\" | \"no-task-text\" | \"weak-task-text\" | \"no-events\";\n/** what the log let the scorer judge; none forces insufficient-data */\nexport type Coverage = \"sufficient\" | \"partial\" | \"none\";\n\n/** session-specific criteria generated before scoring, grouped by the\n * independent tasks the judge enumerated from the user messages */\nexport interface Rubric {\n status: RubricStatus;\n reason?: RubricReason;\n source?: \"full\" | \"task\";\n taskDigest?: string;\n tasks?: RubricTask[];\n /** what the scorer felt the rubric did not let it express */\n note?: string;\n}\n\nexport interface RubricTask {\n title: string;\n type?: string;\n anchorUserMessages: number[];\n /** mark seqs the anchors resolve to — the task's start on the timeline */\n anchorSeqs?: number[];\n criteria: RubricCriterion[];\n}\n\nexport interface RubricCriterion {\n id: string;\n title: string;\n why?: string;\n good?: string;\n bad?: string;\n coverage?: Coverage;\n verdict: Verdict;\n findings: ReportFinding[];\n}\n\nexport type Verdict = \"good\" | \"warning\" | \"problem\" | \"insufficient-data\";\nexport type Severity = \"info\" | \"warning\" | \"problem\";\nexport type DimensionName = \"exploration\" | \"scope\" | \"wandering\" | \"verification\";\n\nexport interface ReportDimension {\n name: DimensionName;\n verdict: Verdict;\n findings: ReportFinding[];\n}\n\nexport interface ReportFinding {\n claim: string;\n severity: Severity;\n evidenceSeqs?: number[];\n}\n\nexport interface ReportMoment {\n seq: number;\n note: string;\n}\n\nexport interface ReportStatus {\n state: \"none\" | \"running\" | \"done\" | \"failed\";\n /** done, but generated from fewer events than the trace now has */\n stale: boolean;\n report?: Report;\n error?: string;\n judgeAvailable: boolean;\n /** default judge (first available) */\n judgeCli?: string;\n /** every installed judge CLI, preference order first */\n judgeClis?: string[];\n}\n\n/** the panel's judge selection, sent with the analyze request */\nexport interface JudgeChoice {\n cli: string;\n /** empty string keeps the CLI's default model */\n model: string;\n}\n\nexport interface ActionCounts {\n search: number;\n read: number;\n edit: number;\n exec: number;\n verify: number;\n other: number;\n}\n","import * as THREE from \"three\";\n\nlet fireflyMap: THREE.Texture | null = null;\nexport function fireflyTexture(): THREE.Texture {\n if (fireflyMap) return fireflyMap;\n const size = 64;\n const canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n const ctx = canvas.getContext(\"2d\")!;\n const g = ctx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2);\n g.addColorStop(0, \"rgba(255,255,255,1)\");\n g.addColorStop(0.25, \"rgba(255,210,160,0.55)\");\n g.addColorStop(1, \"rgba(255,158,94,0)\");\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, size, size);\n fireflyMap = new THREE.CanvasTexture(canvas);\n fireflyMap.userData.shared = true; // module cache: disposeGroup must not free it\n return fireflyMap;\n}\n\nlet haloMap: THREE.Texture | null = null;\nexport function haloTexture(): THREE.Texture {\n if (haloMap) return haloMap;\n const size = 128;\n const canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n const ctx = canvas.getContext(\"2d\")!;\n const g = ctx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2);\n g.addColorStop(0, \"rgba(255,255,255,0.9)\");\n g.addColorStop(0.4, \"rgba(255,255,255,0.28)\");\n g.addColorStop(1, \"rgba(255,255,255,0)\");\n ctx.fillStyle = g;\n ctx.fillRect(0, 0, size, size);\n haloMap = new THREE.CanvasTexture(canvas);\n haloMap.userData.shared = true; // module cache: disposeGroup must not free it\n return haloMap;\n}\n\nexport function labelTexture(text: string): { texture: THREE.Texture; aspect: number } {\n const font = '500 30px \"Schibsted Grotesk Variable\", \"PingFang SC\", sans-serif';\n const measure = document.createElement(\"canvas\").getContext(\"2d\")!;\n measure.font = font;\n const width = Math.ceil(measure.measureText(text).width) + 24;\n const height = 44;\n const canvas = document.createElement(\"canvas\");\n canvas.width = width * 2;\n canvas.height = height * 2;\n const ctx = canvas.getContext(\"2d\")!;\n ctx.scale(2, 2);\n ctx.font = font;\n ctx.textBaseline = \"middle\";\n ctx.textAlign = \"center\";\n ctx.fillStyle = \"rgba(197, 205, 222, 0.95)\";\n ctx.fillText(text, width / 2, height / 2 + 1);\n const texture = new THREE.CanvasTexture(canvas);\n texture.anisotropy = 4;\n return { texture, aspect: width / height };\n}\n","import * as THREE from \"three\";\nimport { labelTexture } from \"./textures\";\n\n// Map-style LOD for directory names, shared by both scenes: a label shows\n// while its subtree spans enough screen pixels — zoom out and only the big\n// forks stay named, push in and deeper directories surface where you're\n// looking. Two colliding labels drop whichever names fewer files.\n\nexport interface DirLabelEntry {\n name: string;\n x: number;\n z: number;\n /** world-space reach of the directory's subtree, drives the LOD cutoff */\n radius: number;\n fileCount: number;\n depth: number;\n}\n\ninterface DirLabel {\n sprite: THREE.Sprite;\n entry: DirLabelEntry;\n aspect: number;\n target: number;\n}\n\nconst LABEL_MIN_SUBTREE_PX = 60;\nconst LABEL_BUDGET = 120;\n\nexport class DirLabelSet {\n private readonly labels: DirLabel[] = [];\n private readonly y: number;\n private dirty = true;\n private readonly lastCamPos = new THREE.Vector3(Infinity, Infinity, Infinity);\n private readonly lastCamQuat = new THREE.Quaternion(0, 0, 0, 0);\n private lastViewW = 0;\n private lastViewH = 0;\n private readonly point = new THREE.Vector3();\n\n // sprites start invisible and fade in once the first projection pass runs;\n // alwaysOnTop labels (terrain) skip the depth test so mountains never bury\n // the district names\n constructor(entries: DirLabelEntry[], group: THREE.Group, y: number, alwaysOnTop = false) {\n this.y = y;\n const budget = [...entries].sort((a, b) => b.fileCount - a.fileCount).slice(0, LABEL_BUDGET);\n for (const entry of budget) {\n const { texture, aspect } = labelTexture(entry.name);\n const sprite = new THREE.Sprite(\n new THREE.SpriteMaterial({\n map: texture,\n transparent: true,\n opacity: 0,\n depthWrite: false,\n depthTest: !alwaysOnTop,\n toneMapped: false,\n fog: false\n })\n );\n if (alwaysOnTop) sprite.renderOrder = 20;\n sprite.visible = false;\n sprite.position.set(entry.x, y, entry.z);\n sprite.raycast = () => undefined;\n group.add(sprite);\n this.labels.push({ sprite, entry, aspect, target: 0 });\n }\n }\n\n markDirty() {\n this.dirty = true;\n }\n\n // reprojects subtrees whenever the camera or viewport moves, picks the\n // labels whose subtree is prominent on screen, drops collision losers\n updateTargets(camera: THREE.PerspectiveCamera, viewW: number, viewH: number) {\n if (this.labels.length === 0 || viewW === 0 || viewH === 0) return;\n const moved =\n this.dirty ||\n !camera.position.equals(this.lastCamPos) ||\n !camera.quaternion.equals(this.lastCamQuat) ||\n viewW !== this.lastViewW ||\n viewH !== this.lastViewH;\n if (!moved) return;\n this.dirty = false;\n this.lastCamPos.copy(camera.position);\n this.lastCamQuat.copy(camera.quaternion);\n this.lastViewW = viewW;\n this.lastViewH = viewH;\n\n const tanV = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2);\n const maxDim = Math.max(viewW, viewH);\n interface Candidate {\n label: DirLabel;\n sx: number;\n sy: number;\n pw: number;\n ph: number;\n }\n const candidates: Candidate[] = [];\n for (const label of this.labels) {\n this.point.set(label.entry.x, this.y, label.entry.z);\n const dist = this.point.distanceTo(camera.position);\n const pxPerWorld = viewH / (2 * dist * tanV);\n const subtreePx = label.entry.radius * pxPerWorld;\n this.point.project(camera);\n const sx = ((this.point.x + 1) / 2) * viewW;\n const sy = ((1 - this.point.y) / 2) * viewH;\n const onScreen = this.point.z < 1 && sx > -60 && sx < viewW + 60 && sy > -40 && sy < viewH + 40;\n // too small to matter, or so large we're inside it — either way the\n // name would float over unrelated geometry\n if (!onScreen || subtreePx < LABEL_MIN_SUBTREE_PX || subtreePx > maxDim * 1.6) {\n label.target = 0;\n continue;\n }\n // constant screen-size type, like map labels\n const ph = label.entry.depth <= 1 ? 15 : 13;\n const worldH = ph / pxPerWorld;\n label.sprite.scale.set(worldH * label.aspect, worldH, 1);\n candidates.push({ label, sx, sy, pw: ph * label.aspect, ph });\n }\n candidates.sort((a, b) => b.label.entry.fileCount - a.label.entry.fileCount);\n const kept: Candidate[] = [];\n for (const candidate of candidates) {\n const clash = kept.some(\n (other) =>\n Math.abs(other.sx - candidate.sx) < (other.pw + candidate.pw) / 2 + 14 &&\n Math.abs(other.sy - candidate.sy) < (other.ph + candidate.ph) / 2 + 10\n );\n candidate.label.target = clash ? 0 : 1;\n if (!clash) kept.push(candidate);\n }\n }\n\n // labels ease toward their LOD targets each frame\n ease(reduced: boolean) {\n for (const label of this.labels) {\n const material = label.sprite.material as THREE.SpriteMaterial;\n const diff = label.target - material.opacity;\n if (Math.abs(diff) > 0.02) {\n material.opacity = reduced ? label.target : material.opacity + diff * 0.16;\n } else if (material.opacity !== label.target) {\n material.opacity = label.target;\n }\n label.sprite.visible = material.opacity > 0.02;\n }\n }\n}\n","import * as THREE from \"three\";\nimport type { Touch } from \"../types\";\n\n// Shared scene vocabulary. The touch colors are the meaning the HUD legend\n// promises; both scenes must draw them identically. Ambient colors (ground,\n// unvisited, ghost) stay per-scene tuning.\nexport const SKY = new THREE.Color(\"#12151c\");\nexport const EMBER = new THREE.Color(\"#ff9e5e\");\n\nexport const touchColors: Record<Touch | \"selected\", THREE.Color> = {\n hit: new THREE.Color(\"#8fb45f\"),\n // chromatic enough to read as blue on lit terrain columns — a paler tint\n // washed out to white and stopped matching the HUD legend\n read: new THREE.Color(\"#a5c8f1\"),\n edit: new THREE.Color(\"#f0ad5a\"),\n selected: new THREE.Color(\"#f6ead2\")\n};\n\n// Distance along `dir` that fits every point inside the camera frustum.\n// Returns null while the viewport has no usable aspect (hidden pane, tab in\n// the background, mid-layout) — fitting then would park the camera at NaN\n// forever; callers must retry once a real resize lands.\nexport function fitDistance(\n camera: THREE.PerspectiveCamera,\n dir: THREE.Vector3,\n points: Iterable<THREE.Vector3>\n): number | null {\n if (!Number.isFinite(camera.aspect) || camera.aspect <= 0) return null;\n const forward = dir.clone().negate();\n const right = new THREE.Vector3().crossVectors(forward, new THREE.Vector3(0, 1, 0)).normalize();\n const up = new THREE.Vector3().crossVectors(right, forward);\n const tanV = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2);\n const tanH = tanV * camera.aspect;\n let distance = 0;\n for (const point of points) {\n const depth = point.dot(forward);\n distance = Math.max(\n distance,\n Math.abs(point.dot(right)) / tanH - depth,\n Math.abs(point.dot(up)) / tanV - depth\n );\n }\n return distance;\n}\n\n// Pan the camera (position + orbit target together, so the view direction\n// holds) until `world` projects inside the viewport's safe area. The right\n// margin reserves room for the inspector panel, which would otherwise sit\n// exactly on top of the leaf the user just selected.\nexport function ensureVisible(\n camera: THREE.PerspectiveCamera,\n controls: { target: THREE.Vector3; update: () => void },\n world: THREE.Vector3,\n viewW: number,\n viewH: number,\n reservedRight: number\n) {\n if (viewW === 0 || viewH === 0) return;\n const forward = camera.getWorldDirection(new THREE.Vector3());\n const depth = world.clone().sub(camera.position).dot(forward);\n if (depth <= 0) return; // behind the camera: panning math breaks down\n const projected = world.clone().project(camera);\n const sx = ((projected.x + 1) / 2) * viewW;\n const sy = ((1 - projected.y) / 2) * viewH;\n const safeL = 48;\n const safeR = Math.max(safeL + 60, viewW - reservedRight - 48);\n const safeT = 120;\n const safeB = viewH - 100;\n const targetX = Math.min(Math.max(sx, safeL), safeR);\n const targetY = Math.min(Math.max(sy, safeT), safeB);\n if (targetX === sx && targetY === sy) return;\n const tanV = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2);\n const tanH = tanV * camera.aspect;\n const right = new THREE.Vector3().crossVectors(forward, new THREE.Vector3(0, 1, 0)).normalize();\n const up = new THREE.Vector3().crossVectors(right, forward);\n // moving the camera right shifts the point left on screen, and vice versa\n const pan = right\n .multiplyScalar(((sx - targetX) * 2 * depth * tanH) / viewW)\n .addScaledVector(up, ((targetY - sy) * 2 * depth * tanV) / viewH);\n camera.position.add(pan);\n controls.target.add(pan);\n controls.update();\n}\n\n// One-line hover readout, driven imperatively from the scenes' pointermove\n// handlers so hovering never re-renders the React tree.\nexport class SceneTip {\n private readonly el: HTMLDivElement;\n private readonly pathEl: HTMLSpanElement;\n private readonly metaEl: HTMLSpanElement;\n\n constructor(private readonly host: HTMLElement) {\n this.el = document.createElement(\"div\");\n this.el.className = \"scene-tip\";\n this.pathEl = document.createElement(\"span\");\n this.metaEl = document.createElement(\"span\");\n this.metaEl.className = \"dim\";\n this.el.append(this.pathEl, this.metaEl);\n host.appendChild(this.el);\n }\n\n show(path: string, meta: string, clientX: number, clientY: number) {\n this.pathEl.textContent = path;\n this.metaEl.textContent = ` · ${meta}`;\n this.el.style.display = \"block\";\n const bounds = this.host.getBoundingClientRect();\n const x = clientX - bounds.left;\n const y = clientY - bounds.top;\n const left = Math.min(x + 14, Math.max(0, bounds.width - this.el.offsetWidth - 8));\n const top = Math.min(y + 16, Math.max(0, bounds.height - this.el.offsetHeight - 8));\n this.el.style.left = `${left}px`;\n this.el.style.top = `${top}px`;\n }\n\n hide() {\n this.el.style.display = \"none\";\n }\n\n dispose() {\n this.el.remove();\n }\n}\n\nexport const prefersReducedMotion = () =>\n typeof window !== \"undefined\" && window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n\nexport function disposeGroup(group: THREE.Group) {\n group.traverse((obj) => {\n if (obj instanceof THREE.Mesh || obj instanceof THREE.Line || obj instanceof THREE.Sprite) {\n obj.geometry?.dispose();\n const mat = obj.material as THREE.Material | THREE.Material[];\n if (Array.isArray(mat)) mat.forEach(disposeMaterial);\n else if (mat) disposeMaterial(mat);\n }\n });\n}\n\nfunction disposeMaterial(mat: THREE.Material) {\n // Material.dispose() does not free assigned textures; module-cached\n // textures (fireflyTexture/haloTexture) are marked shared and must survive.\n const map = (mat as THREE.Material & { map?: THREE.Texture | null }).map;\n if (map && !map.userData.shared) map.dispose();\n mat.dispose();\n}\n","import * as THREE from \"three\";\nimport { EMBER } from \"./sceneUtils\";\n\nconst SAMPLES = 14;\nconst MAX_ARCS = 11; // playback keeps 12 recent targets → at most 11 arcs\n\n// Fixed-capacity trail: the arc soup changes every playback tick, so the\n// geometry and material are allocated once and only the attribute contents\n// (plus the draw range) are rewritten in place.\nexport class TrailRenderer {\n readonly object: THREE.LineSegments;\n private readonly positions: THREE.BufferAttribute;\n private readonly colors: THREE.BufferAttribute;\n private readonly lift: number;\n private readonly arcPoints = Array.from({ length: SAMPLES + 1 }, () => new THREE.Vector3());\n private readonly mid = new THREE.Vector3();\n private readonly curve = new THREE.QuadraticBezierCurve3();\n private readonly color = new THREE.Color();\n\n constructor(lift: number) {\n this.lift = lift;\n const vertexCount = MAX_ARCS * SAMPLES * 2;\n const geometry = new THREE.BufferGeometry();\n this.positions = new THREE.BufferAttribute(new Float32Array(vertexCount * 3), 3);\n this.positions.setUsage(THREE.DynamicDrawUsage);\n this.colors = new THREE.BufferAttribute(new Float32Array(vertexCount * 3), 3);\n this.colors.setUsage(THREE.DynamicDrawUsage);\n geometry.setAttribute(\"position\", this.positions);\n geometry.setAttribute(\"color\", this.colors);\n geometry.setDrawRange(0, 0);\n const material = new THREE.LineBasicMaterial({\n vertexColors: true,\n transparent: true,\n blending: THREE.AdditiveBlending,\n depthWrite: false,\n fog: false\n });\n this.object = new THREE.LineSegments(geometry, material);\n this.object.frustumCulled = false;\n }\n\n // points are the recent fixations, oldest first, y already at arc height\n update(points: THREE.Vector3[]) {\n const arcs = Math.min(Math.max(points.length - 1, 0), MAX_ARCS);\n if (arcs === 0) {\n this.object.geometry.setDrawRange(0, 0);\n return;\n }\n const start = points.length - 1 - arcs;\n let v = 0;\n for (let i = 1; i <= arcs; i++) {\n const a = points[start + i - 1];\n const b = points[start + i];\n this.mid.copy(a).lerp(b, 0.5);\n this.mid.y = Math.max(a.y, b.y) + a.distanceTo(b) * 0.22 + this.lift;\n this.curve.v0.copy(a);\n this.curve.v1.copy(this.mid);\n this.curve.v2.copy(b);\n for (let s = 0; s <= SAMPLES; s++) {\n this.curve.getPoint(s / SAMPLES, this.arcPoints[s]);\n }\n const recency = i / arcs;\n this.color.copy(EMBER).multiplyScalar(0.05 + 0.95 * recency * recency);\n for (let s = 0; s < SAMPLES; s++) {\n const pa = this.arcPoints[s];\n const pb = this.arcPoints[s + 1];\n this.positions.setXYZ(v, pa.x, pa.y, pa.z);\n this.colors.setXYZ(v, this.color.r, this.color.g, this.color.b);\n v++;\n this.positions.setXYZ(v, pb.x, pb.y, pb.z);\n this.colors.setXYZ(v, this.color.r, this.color.g, this.color.b);\n v++;\n }\n }\n this.object.geometry.setDrawRange(0, v);\n this.positions.needsUpdate = true;\n this.colors.needsUpdate = true;\n }\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport * as THREE from \"three\";\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\nimport { touchWord, type CityFile, type CityMap, type Touch } from \"../types\";\nimport type { FilePlayback } from \"../playback/reducer\";\nimport { DirLabelSet } from \"./dirLabels\";\nimport {\n disposeGroup,\n EMBER,\n ensureVisible,\n fitDistance,\n prefersReducedMotion,\n SceneTip,\n SKY,\n touchColors\n} from \"./sceneUtils\";\nimport { fireflyTexture } from \"./textures\";\nimport { TrailRenderer } from \"./trail\";\n\ninterface CitySceneProps {\n city?: CityMap;\n playback: FilePlayback;\n selectedPath?: string;\n onSelect: (path?: string) => void;\n onCanvasReady?: (canvas: HTMLCanvasElement | null) => void;\n // static map mode: with no session to drive attention height, raise terrain\n // columns by file size (lines of code) instead of leaving the plain flat\n locHeights?: boolean;\n}\n\n// Attention terrain: the map is a flat dark plain (fog of war); height is\n// earned by attention — touch depth × revisits — so mountains grow where the\n// walker lingered. Light is data: only touched terrain gets bright color.\nconst colors: Record<Touch | \"unvisited\" | \"ghost\" | \"selected\", THREE.Color> = {\n unvisited: new THREE.Color(\"#5b6372\"),\n ghost: new THREE.Color(\"#404551\"),\n ...touchColors\n};\n\nconst TILE_H = 0.14;\nconst LABEL_Y = 2.4;\n// the inspector docks on the right; selection pans the camera clear of it\nconst INSPECTOR_RESERVED_PX = 348;\n\nfunction attentionHeight(touch: Touch, visits: number): number {\n const base = touch === \"edit\" ? 7.2 : touch === \"read\" ? 4.2 : 1.6;\n return base * (1 + 0.35 * Math.log2(Math.max(visits, 1)));\n}\n\n// static map height: normalized lines of code, log-scaled so a few huge files\n// don't flatten everything else. maxLog is log2(largest file's lines).\nconst LOC_MIN_H = 0.3;\nconst LOC_MAX_H = 16;\n// gamma > 1 exaggerates the top end: small files stay low, big files spike, so\n// the skyline reads as a city (towers vs shacks) instead of a uniform plateau\nconst LOC_HEIGHT_GAMMA = 2.2;\n// normalized 0..1 position of a file by lines of code (log-scaled)\nfunction locFraction(lines: number, maxLog: number): number {\n if (maxLog <= 0) return 0;\n return Math.min(1, Math.log2(Math.max(lines, 1)) / maxLog);\n}\nfunction locHeight(t: number): number {\n return LOC_MIN_H + Math.pow(t, LOC_HEIGHT_GAMMA) * (LOC_MAX_H - LOC_MIN_H);\n}\n\n// LOC tier ramp: small files stay grey, then warm up through orange and purple\n// to red for the largest files. Stops are interpolated so the terrain reads as\n// a continuous gradient rather than hard bands.\nconst LOC_RAMP: { at: number; color: THREE.Color }[] = [\n { at: 0.0, color: new THREE.Color(\"#5b6372\") }, // grey (matches unvisited)\n { at: 0.35, color: new THREE.Color(\"#e0894f\") }, // orange\n { at: 0.7, color: new THREE.Color(\"#9a6bd8\") }, // purple\n { at: 1.0, color: new THREE.Color(\"#e0524f\") } // red\n];\nfunction locColor(t: number): THREE.Color {\n for (let i = 1; i < LOC_RAMP.length; i++) {\n if (t <= LOC_RAMP[i].at) {\n const lo = LOC_RAMP[i - 1];\n const hi = LOC_RAMP[i];\n const span = hi.at - lo.at;\n const k = span > 0 ? (t - lo.at) / span : 0;\n return lo.color.clone().lerp(hi.color, k);\n }\n }\n return LOC_RAMP[LOC_RAMP.length - 1].color.clone();\n}\n\ninterface TerrainSlot {\n fileId: number;\n target: number;\n color: THREE.Color;\n}\n\nexport function CityScene({ city, playback, selectedPath, onSelect, onCanvasReady, locHeights }: CitySceneProps) {\n const hostRef = useRef<HTMLDivElement | null>(null);\n const tileMeshRef = useRef<THREE.InstancedMesh | null>(null);\n const terrainMeshRef = useRef<THREE.InstancedMesh | null>(null);\n const filesRef = useRef<CityFile[]>([]);\n const slotsRef = useRef<TerrainSlot[]>([]);\n const heightsRef = useRef<Map<number, number>>(new Map());\n const rendererRef = useRef<THREE.WebGLRenderer | null>(null);\n const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);\n const controlsRef = useRef<OrbitControls | null>(null);\n const sceneRef = useRef<THREE.Scene | null>(null);\n const cityGroupRef = useRef<THREE.Group | null>(null);\n const trailRef = useRef<TrailRenderer | null>(null);\n const fireflyRef = useRef<THREE.Sprite | null>(null);\n const labelSetRef = useRef<DirLabelSet | null>(null);\n const frameRef = useRef<number | null>(null);\n const reducedRef = useRef(false);\n const boundsRef = useRef({ cx: 0, cz: 0, size: 120 });\n // handlers live in the mount effect; they read playback through this ref\n const playbackRef = useRef(playback);\n playbackRef.current = playback;\n // camera fit deferred while the viewport reports no size (hidden pane,\n // background tab); resize retries it instead of leaving the camera at NaN\n const fitPendingRef = useRef<(() => boolean) | null>(null);\n\n const bounds = useMemo(() => {\n if (!city || city.files.length === 0) return { cx: 0, cz: 0, size: 120, halfW: 60, halfD: 60 };\n let minX = Infinity;\n let maxX = -Infinity;\n let minZ = Infinity;\n let maxZ = -Infinity;\n for (const file of city.files) {\n minX = Math.min(minX, file.rect.x);\n maxX = Math.max(maxX, file.rect.x + file.rect.w);\n minZ = Math.min(minZ, file.rect.z);\n maxZ = Math.max(maxZ, file.rect.z + file.rect.d);\n }\n return {\n cx: (minX + maxX) / 2,\n cz: (minZ + maxZ) / 2,\n size: Math.max(maxX - minX, maxZ - minZ, 60),\n halfW: (maxX - minX) / 2,\n halfD: (maxZ - minZ) / 2\n };\n }, [city]);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const reduced = prefersReducedMotion();\n reducedRef.current = reduced;\n\n const scene = new THREE.Scene();\n scene.background = SKY;\n sceneRef.current = scene;\n\n const camera = new THREE.PerspectiveCamera(38, host.clientWidth / host.clientHeight || 1, 0.1, 2400);\n camera.position.set(70, 130, 100);\n cameraRef.current = camera;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n renderer.setSize(host.clientWidth, host.clientHeight);\n rendererRef.current = renderer;\n host.appendChild(renderer.domElement);\n onCanvasReady?.(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = !reduced;\n controls.dampingFactor = 0.08;\n controls.maxPolarAngle = Math.PI * 0.44;\n // the god view drifts slowly around the terrain until the user takes over\n controls.autoRotate = !reduced;\n controls.autoRotateSpeed = -0.5;\n const tip = new SceneTip(host);\n controls.addEventListener(\"start\", () => {\n controls.autoRotate = false;\n tip.hide();\n });\n controlsRef.current = controls;\n\n const sky = new THREE.HemisphereLight(\"#66779b\", \"#161922\", 1.7);\n scene.add(sky);\n const moon = new THREE.DirectionalLight(\"#b6c5de\", 1.1);\n moon.position.set(-60, 120, -40);\n scene.add(moon);\n\n const raycaster = new THREE.Raycaster();\n const pointer = new THREE.Vector2();\n const pickFile = (event: PointerEvent): CityFile | undefined => {\n if (!cameraRef.current || !rendererRef.current) return undefined;\n const rect = rendererRef.current.domElement.getBoundingClientRect();\n pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n raycaster.setFromCamera(pointer, cameraRef.current);\n const targets = [terrainMeshRef.current, tileMeshRef.current].filter(Boolean) as THREE.Object3D[];\n const hit = raycaster.intersectObjects(targets, false)[0];\n if (!hit || hit.instanceId === undefined) return undefined;\n if (hit.object === terrainMeshRef.current) {\n const slot = slotsRef.current[hit.instanceId];\n return slot ? filesRef.current[slot.fileId] : undefined;\n }\n return filesRef.current[hit.instanceId];\n };\n\n let downAt: { x: number; y: number } | null = null;\n const onPointerDown = (event: PointerEvent) => {\n downAt = { x: event.clientX, y: event.clientY };\n };\n const onPointerUp = (event: PointerEvent) => {\n if (!downAt) return;\n const moved = Math.hypot(event.clientX - downAt.x, event.clientY - downAt.y);\n downAt = null;\n if (moved > 5) return;\n onSelect(pickFile(event)?.path);\n };\n // hover: cursor + one-line readout, throttled to one raycast per frame\n let hoverRaf = 0;\n const onPointerMove = (event: PointerEvent) => {\n if (downAt) {\n tip.hide();\n return;\n }\n if (hoverRaf) return;\n hoverRaf = requestAnimationFrame(() => {\n hoverRaf = 0;\n const file = pickFile(event);\n renderer.domElement.style.cursor = file ? \"pointer\" : \"\";\n if (!file) {\n tip.hide();\n return;\n }\n const snapshot = playbackRef.current;\n const touch = snapshot.touchByPath.get(file.path);\n const visits = snapshot.visitsByFile.get(file.id) ?? 0;\n const meta = touch\n ? `${touchWord(touch)} · ${visits} visit${visits === 1 ? \"\" : \"s\"}`\n : touchWord(undefined);\n tip.show(file.path, file.ghost ? `${meta} · ghost` : meta, event.clientX, event.clientY);\n });\n };\n const onPointerLeave = () => {\n tip.hide();\n renderer.domElement.style.cursor = \"\";\n };\n renderer.domElement.addEventListener(\"pointerdown\", onPointerDown);\n renderer.domElement.addEventListener(\"pointerup\", onPointerUp);\n renderer.domElement.addEventListener(\"pointermove\", onPointerMove);\n renderer.domElement.addEventListener(\"pointerleave\", onPointerLeave);\n\n const resize = () => {\n if (!hostRef.current) return;\n const w = hostRef.current.clientWidth;\n const h = hostRef.current.clientHeight;\n if (w === 0 || h === 0) return;\n renderer.setSize(w, h);\n camera.aspect = w / h;\n camera.updateProjectionMatrix();\n if (fitPendingRef.current?.()) fitPendingRef.current = null;\n };\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n const clock = new THREE.Clock();\n const matrix = new THREE.Matrix4();\n const quaternion = new THREE.Quaternion();\n const render = () => {\n controls.update();\n labelSetRef.current?.updateTargets(camera, renderer.domElement.clientWidth, renderer.domElement.clientHeight);\n labelSetRef.current?.ease(reducedRef.current);\n\n // grow / shrink terrain columns toward their attention targets\n const terrain = terrainMeshRef.current;\n const slots = slotsRef.current;\n const heights = heightsRef.current;\n if (terrain && slots.length > 0) {\n let moving = false;\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const file = filesRef.current[slot.fileId];\n if (!file) continue;\n let cur = heights.get(slot.fileId) ?? 0;\n const diff = slot.target - cur;\n if (Math.abs(diff) > 0.015) {\n cur = reducedRef.current ? slot.target : cur + diff * 0.13;\n heights.set(slot.fileId, cur);\n moving = true;\n } else if (cur !== slot.target) {\n heights.set(slot.fileId, slot.target);\n cur = slot.target;\n moving = true;\n }\n const sx = Math.max(file.rect.w, 0.45) + 0.04;\n const sz = Math.max(file.rect.d, 0.45) + 0.04;\n matrix.compose(\n new THREE.Vector3(\n file.rect.x + file.rect.w / 2 - boundsRef.current.cx,\n Math.max(cur, 0.02) / 2 + TILE_H,\n file.rect.z + file.rect.d / 2 - boundsRef.current.cz\n ),\n quaternion,\n new THREE.Vector3(sx, Math.max(cur, 0.02), sz)\n );\n terrain.setMatrixAt(i, matrix);\n }\n if (moving) terrain.instanceMatrix.needsUpdate = true;\n }\n\n const firefly = fireflyRef.current;\n if (firefly?.visible) {\n const t = clock.getElapsedTime();\n const base = firefly.userData.baseScale as number;\n const pulse = reducedRef.current ? 1 : 1 + 0.1 * Math.sin(t * 2.4);\n firefly.scale.setScalar(base * pulse);\n }\n renderer.render(scene, camera);\n frameRef.current = requestAnimationFrame(render);\n };\n render();\n\n return () => {\n if (frameRef.current) cancelAnimationFrame(frameRef.current);\n if (hoverRaf) cancelAnimationFrame(hoverRaf);\n renderer.domElement.removeEventListener(\"pointerdown\", onPointerDown);\n renderer.domElement.removeEventListener(\"pointerup\", onPointerUp);\n renderer.domElement.removeEventListener(\"pointermove\", onPointerMove);\n renderer.domElement.removeEventListener(\"pointerleave\", onPointerLeave);\n tip.dispose();\n observer.disconnect();\n controls.dispose();\n renderer.dispose();\n host.removeChild(renderer.domElement);\n scene.clear();\n onCanvasReady?.(null);\n };\n }, [onSelect, onCanvasReady]);\n\n // build the plain: ground, grid, district plates, flat file tiles\n useEffect(() => {\n const scene = sceneRef.current;\n if (!scene) return;\n filesRef.current = city?.files ?? [];\n slotsRef.current = [];\n heightsRef.current = new Map();\n boundsRef.current = bounds;\n if (!city || city.files.length === 0) return;\n\n const group = new THREE.Group();\n const size = bounds.size;\n\n scene.fog = new THREE.Fog(SKY, size * 2.1, size * 4.2);\n\n const ground = new THREE.Mesh(\n new THREE.PlaneGeometry(size * 6, size * 6),\n new THREE.MeshStandardMaterial({ color: \"#14171e\", roughness: 1 })\n );\n ground.rotation.x = -Math.PI / 2;\n ground.position.y = -0.32;\n group.add(ground);\n\n const grid = new THREE.GridHelper(size * 2.8, 46, \"#20242e\", \"#1a1e27\");\n (grid.material as THREE.Material).transparent = true;\n (grid.material as THREE.Material).opacity = 0.5;\n grid.position.y = -0.3;\n group.add(grid);\n\n const plateDirs = city.dirs.filter((dir) => dir.depth <= 3 && dir.rect.w > 0 && dir.rect.d > 0);\n if (plateDirs.length > 0) {\n const plateGeo = new THREE.BoxGeometry(1, 1, 1);\n const plateMat = new THREE.MeshStandardMaterial({ roughness: 0.95, metalness: 0 });\n const plates = new THREE.InstancedMesh(plateGeo, plateMat, plateDirs.length);\n const matrix = new THREE.Matrix4();\n const shade = new THREE.Color();\n plateDirs.forEach((dir, i) => {\n const top = -0.2 + Math.min(dir.depth, 3) * 0.06;\n const height = top + 0.3;\n matrix.compose(\n new THREE.Vector3(\n dir.rect.x + dir.rect.w / 2 - bounds.cx,\n top - height / 2,\n dir.rect.z + dir.rect.d / 2 - bounds.cz\n ),\n new THREE.Quaternion(),\n new THREE.Vector3(dir.rect.w, height, dir.rect.d)\n );\n plates.setMatrixAt(i, matrix);\n shade.set(\"#1a1f29\").lerp(new THREE.Color(\"#252b37\"), Math.min(dir.depth, 3) / 3);\n plates.setColorAt(i, shade);\n });\n plates.instanceMatrix.needsUpdate = true;\n if (plates.instanceColor) plates.instanceColor.needsUpdate = true;\n group.add(plates);\n }\n\n // flat tiles: every file exists on the map, dark until visited\n const tileGeo = new THREE.BoxGeometry(1, 1, 1);\n const tileMat = new THREE.MeshStandardMaterial({ roughness: 0.85, metalness: 0 });\n const tiles = new THREE.InstancedMesh(tileGeo, tileMat, city.files.length);\n const matrix = new THREE.Matrix4();\n for (const file of city.files) {\n const sx = Math.max(file.rect.w, 0.45);\n const sz = Math.max(file.rect.d, 0.45);\n const x = file.rect.x + file.rect.w / 2 - bounds.cx;\n const z = file.rect.z + file.rect.d / 2 - bounds.cz;\n matrix.compose(new THREE.Vector3(x, TILE_H / 2, z), new THREE.Quaternion(), new THREE.Vector3(sx, TILE_H, sz));\n tiles.setMatrixAt(file.id, matrix);\n tiles.setColorAt(file.id, baseColor(file));\n }\n tiles.instanceMatrix.needsUpdate = true;\n if (tiles.instanceColor) tiles.instanceColor.needsUpdate = true;\n tileMeshRef.current = tiles;\n group.add(tiles);\n\n // attention terrain: unlit columns that grow out of the plain\n const terrain = new THREE.InstancedMesh(\n attentionColumnGeometry(),\n new THREE.MeshBasicMaterial({ toneMapped: false, vertexColors: true }),\n city.files.length\n );\n terrain.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(city.files.length * 3), 3);\n terrain.count = 0;\n terrain.frustumCulled = false;\n terrainMeshRef.current = terrain;\n group.add(terrain);\n\n // district labels above the plain; drawn over the columns so a mountain\n // range never buries the name of the district behind it\n labelSetRef.current = new DirLabelSet(\n city.dirs\n .filter((dir) => dir.depth >= 1 && dir.fileCount > 0 && dir.rect.w > 0 && dir.rect.d > 0)\n .map((dir) => ({\n name: dirBasename(dir.path),\n x: dir.rect.x + dir.rect.w / 2 - bounds.cx,\n z: dir.rect.z + dir.rect.d / 2 - bounds.cz,\n radius: Math.hypot(dir.rect.w, dir.rect.d) / 2,\n fileCount: dir.fileCount,\n depth: dir.depth\n })),\n group,\n LABEL_Y,\n true\n );\n\n const firefly = new THREE.Sprite(\n new THREE.SpriteMaterial({\n map: fireflyTexture(),\n color: EMBER,\n blending: THREE.AdditiveBlending,\n depthWrite: false,\n transparent: true\n })\n );\n firefly.userData.baseScale = Math.max(size * 0.028, 2.2);\n firefly.visible = false;\n fireflyRef.current = firefly;\n group.add(firefly);\n\n const trail = new TrailRenderer(1.4);\n trailRef.current = trail;\n group.add(trail.object);\n\n cityGroupRef.current = group;\n scene.add(group);\n\n // keep the canonical viewing direction, but pull back exactly far\n // enough that the whole plain fits the viewport's frustum — the fixed\n // size multiplier ignores the aspect ratio and overflows short windows\n const fitView = (): boolean => {\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n if (!camera || !controls) return true;\n const dir = new THREE.Vector3(0.46, 1.08, 0.72).normalize();\n const corners: THREE.Vector3[] = [];\n for (const sx of [-1, 1]) {\n for (const sz of [-1, 1]) {\n corners.push(new THREE.Vector3(sx * bounds.halfW, 0, sz * bounds.halfD));\n }\n }\n const fitted = fitDistance(camera, dir, corners);\n if (fitted === null) return false;\n // breathing room so map edges clear the HUD overlays; floor keeps\n // near-empty maps from parking the camera on the ground\n const distance = Math.max(fitted * 1.12, size * 0.6);\n camera.position.copy(dir).multiplyScalar(distance);\n controls.target.set(0, 0, 0);\n controls.minDistance = size * 0.18;\n controls.maxDistance = Math.max(size * 2.6, distance * 1.2);\n controls.update();\n return true;\n };\n fitPendingRef.current = fitView() ? null : fitView;\n\n return () => {\n fitPendingRef.current = null;\n disposeGroup(group);\n scene.remove(group);\n cityGroupRef.current = null;\n tileMeshRef.current = null;\n terrainMeshRef.current = null;\n trailRef.current = null;\n fireflyRef.current = null;\n labelSetRef.current = null;\n };\n }, [city, bounds]);\n\n // playback → terrain targets and colors\n useEffect(() => {\n const terrain = terrainMeshRef.current;\n const tiles = tileMeshRef.current;\n if (!terrain || !tiles || !city) return;\n\n const heights = heightsRef.current;\n const slots: TerrainSlot[] = [];\n const present = new Set<number>();\n // static map mode: no session drives attention, so raise every column by\n // its lines of code instead of leaving the terrain flat\n const maxLog = locHeights\n ? Math.log2(Math.max(1, city.files.reduce((m, f) => Math.max(m, f.lines), 1)))\n : 0;\n for (const file of city.files) {\n const touch = playback.touchByFile.get(file.id);\n const selected = file.path === selectedPath;\n tiles.setColorAt(file.id, selected ? colors.selected : baseColor(file));\n if (touch) {\n const visits = playback.visitsByFile.get(file.id) ?? 1;\n let color = colors[touch];\n if (file.ghost) color = color.clone().lerp(colors.ghost, 0.45);\n if (selected) color = colors.selected;\n slots.push({ fileId: file.id, target: attentionHeight(touch, visits), color });\n present.add(file.id);\n } else if (locHeights) {\n const t = locFraction(file.lines, maxLog);\n let color = locColor(t);\n if (file.ghost) color = color.lerp(colors.ghost, 0.45);\n if (selected) color = colors.selected;\n slots.push({ fileId: file.id, target: locHeight(t), color });\n present.add(file.id);\n }\n }\n // let columns that just went dark shrink back into the plain\n for (const [fileId, cur] of heights) {\n if (cur > 0.04 && !present.has(fileId)) {\n slots.push({ fileId, target: 0, color: colors.unvisited });\n } else if (cur <= 0.04 && !present.has(fileId)) {\n heights.delete(fileId);\n }\n }\n\n slots.forEach((slot, i) => terrain.setColorAt(i, slot.color));\n terrain.count = slots.length;\n if (terrain.instanceColor) terrain.instanceColor.needsUpdate = true;\n if (tiles.instanceColor) tiles.instanceColor.needsUpdate = true;\n slotsRef.current = slots;\n }, [city, playback, selectedPath, locHeights]);\n\n // the inspector opens over the right edge; pan the selected tile clear of it\n useEffect(() => {\n if (!city || !selectedPath) return;\n const file = city.files.find((f) => f.path === selectedPath);\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n const canvas = rendererRef.current?.domElement;\n if (!file || !camera || !controls || !canvas) return;\n controls.autoRotate = false;\n const top = heightsRef.current.get(file.id) ?? TILE_H;\n const world = centerFor(file, bounds);\n world.y = top;\n ensureVisible(camera, controls, world, canvas.clientWidth, canvas.clientHeight, INSPECTOR_RESERVED_PX);\n }, [city, bounds, selectedPath]);\n\n // trail: ballistic arcs between recent fixations + the firefly at the head\n useEffect(() => {\n const trail = trailRef.current;\n if (!trail || !city) return;\n\n // playback resolves fileId with the same path key the citymap uses, so a\n // target still missing one has no tile to land on\n const targetFiles = playback.recentTargets\n .map((target) => (target.fileId !== undefined ? city.files[target.fileId] : undefined))\n .filter((file): file is CityFile => Boolean(file));\n\n const peakFor = (file: CityFile): number => {\n const touch = playback.touchByFile.get(file.id);\n const visits = playback.visitsByFile.get(file.id) ?? 1;\n return touch ? attentionHeight(touch, visits) : TILE_H;\n };\n\n const firefly = fireflyRef.current;\n if (firefly) {\n const head = targetFiles[targetFiles.length - 1];\n if (head) {\n const p = centerFor(head, bounds);\n firefly.position.set(p.x, peakFor(head) + 1.6, p.z);\n firefly.visible = true;\n } else {\n firefly.visible = false;\n }\n }\n\n trail.update(\n targetFiles.map((file) => {\n const p = centerFor(file, bounds);\n p.y = peakFor(file) + 0.4;\n return p;\n })\n );\n }, [city, playback, bounds]);\n\n return <div className=\"city-scene\" ref={hostRef} aria-label=\"Attention terrain\" />;\n}\n\n// Columns must read as phosphorescence, not paint: glow pools at the crest and\n// falls off into the plain. Vertex shade multiplies the per-instance touch\n// color; the top face sits under the side rims so edges catch the most light.\nfunction attentionColumnGeometry(): THREE.BoxGeometry {\n const geo = new THREE.BoxGeometry(1, 1, 1);\n const pos = geo.getAttribute(\"position\");\n const normal = geo.getAttribute(\"normal\");\n const shade = new Float32Array(pos.count * 3);\n for (let i = 0; i < pos.count; i++) {\n const t = pos.getY(i) + 0.5;\n const glow = normal.getY(i) === 1 ? 0.82 : 0.34 + 0.66 * t * t;\n shade.fill(glow, i * 3, i * 3 + 3);\n }\n geo.setAttribute(\"color\", new THREE.BufferAttribute(shade, 3));\n return geo;\n}\n\nfunction baseColor(file: CityFile): THREE.Color {\n if (file.ghost) return colors.ghost;\n let h = 2166136261;\n for (let i = 0; i < file.path.length; i++) {\n h = Math.imul(h ^ file.path.charCodeAt(i), 16777619);\n }\n const jitter = ((h >>> 0) % 1000) / 1000 - 0.5;\n return colors.unvisited.clone().offsetHSL(0, 0, jitter * 0.05);\n}\n\nfunction centerFor(file: CityFile, bounds: { cx: number; cz: number }): THREE.Vector3 {\n return new THREE.Vector3(file.rect.x + file.rect.w / 2 - bounds.cx, 0, file.rect.z + file.rect.d / 2 - bounds.cz);\n}\n\nfunction dirBasename(path: string): string {\n return path.slice(path.lastIndexOf(\"/\") + 1) || path;\n}\n","import type { CityFile } from \"../types\";\n\n// Deterministic radial tree: root at the origin, directories as branch\n// forks, files as leaf slots. Every leaf gets an equal angular share in\n// path-sorted order, so the same commit always grows the same tree.\n\nexport interface TreeDir {\n path: string;\n name: string;\n x: number;\n z: number;\n depth: number;\n fileCount: number;\n // how far the subtree's leaves reach from the fork, in layout units —\n // the scene projects this to screen pixels to decide when the directory\n // is prominent enough to deserve its label\n radius: number;\n}\n\nexport interface TreeEdge {\n childPath?: string;\n childFileId?: number;\n points: { x: number; z: number }[];\n}\n\nexport interface TreeLayout {\n radius: number;\n leaf: Map<number, { x: number; z: number }>;\n dirs: TreeDir[];\n edges: TreeEdge[];\n}\n\ninterface Node {\n name: string;\n path: string;\n depth: number;\n children: Map<string, Node>;\n files: CityFile[];\n leafCount: number;\n angle: number;\n}\n\nexport function computeTreeLayout(files: CityFile[]): TreeLayout {\n const root: Node = { name: \"\", path: \"\", depth: 0, children: new Map(), files: [], leafCount: 0, angle: 0 };\n const sorted = [...files].sort((a, b) => (a.path < b.path ? -1 : 1));\n for (const file of sorted) {\n const parts = file.path.split(\"/\").filter(Boolean);\n let node = root;\n for (const part of parts.slice(0, -1)) {\n let next = node.children.get(part);\n if (!next) {\n next = {\n name: part,\n path: node.path ? `${node.path}/${part}` : part,\n depth: node.depth + 1,\n children: new Map(),\n files: [],\n leafCount: 0,\n angle: 0\n };\n node.children.set(part, next);\n }\n node = next;\n }\n node.files.push(file);\n }\n\n let maxDepth = 1;\n const countLeaves = (node: Node): number => {\n node.leafCount = node.files.length;\n if (node.files.length > 0) maxDepth = Math.max(maxDepth, node.depth + 1);\n for (const child of node.children.values()) {\n node.leafCount += countLeaves(child);\n }\n return node.leafCount;\n };\n countLeaves(root);\n\n const total = Math.max(root.leafCount, 1);\n const radius = Math.max(55, Math.sqrt(total) * 4);\n const step = radius / Math.max(maxDepth, 1);\n const slotAngle = (Math.PI * 2) / total;\n\n const layout: TreeLayout = { radius, leaf: new Map(), dirs: [], edges: [] };\n const polar = (r: number, angle: number) => ({ x: r * Math.cos(angle), z: r * Math.sin(angle) });\n\n const sampleEdge = (r1: number, a1: number, r2: number, a2: number): { x: number; z: number }[] => {\n // straight spokes out of the root, eased sweeps between rings\n const from = r1 < 1e-6 ? a2 : a1;\n let delta = a2 - from;\n while (delta > Math.PI) delta -= Math.PI * 2;\n while (delta < -Math.PI) delta += Math.PI * 2;\n const points: { x: number; z: number }[] = [];\n const SEGMENTS = 8;\n for (let s = 0; s <= SEGMENTS; s++) {\n const t = s / SEGMENTS;\n const ease = t * t * (3 - 2 * t);\n points.push(polar(r1 + (r2 - r1) * t, from + delta * ease));\n }\n return points;\n };\n\n let cursor = 0;\n const place = (node: Node) => {\n node.angle = (cursor + node.leafCount / 2) * slotAngle;\n const dirs = [...node.children.values()].sort((a, b) => (a.name < b.name ? -1 : 1));\n const files = [...node.files].sort((a, b) => (a.path < b.path ? -1 : 1));\n for (const child of dirs) {\n place(child);\n }\n for (const file of files) {\n const angle = (cursor + 0.5) * slotAngle;\n cursor += 1;\n const pos = polar((node.depth + 1) * step, angle);\n layout.leaf.set(file.id, pos);\n layout.edges.push({\n childFileId: file.id,\n points: sampleEdge(node.depth * step, node.angle, (node.depth + 1) * step, angle)\n });\n }\n if (node.path !== \"\") {\n const pos = polar(node.depth * step, node.angle);\n layout.dirs.push({\n path: node.path,\n name: node.name,\n x: pos.x,\n z: pos.z,\n depth: node.depth,\n fileCount: node.leafCount,\n radius: 0\n });\n }\n };\n place(root);\n\n // parent→dir edges need final angles, so wire them after placement\n const nodeByPath = new Map<string, Node>();\n const collect = (node: Node) => {\n nodeByPath.set(node.path, node);\n for (const child of node.children.values()) collect(child);\n };\n collect(root);\n for (const dir of layout.dirs) {\n const node = nodeByPath.get(dir.path)!;\n const parentPath = dir.path.includes(\"/\") ? dir.path.slice(0, dir.path.lastIndexOf(\"/\")) : \"\";\n const parent = nodeByPath.get(parentPath)!;\n layout.edges.push({\n childPath: dir.path,\n points: sampleEdge(parent.depth * step, parent.angle, node.depth * step, node.angle)\n });\n }\n\n // subtree reach: every leaf stretches the radius of each ancestor dir\n const dirByPath = new Map(layout.dirs.map((dir) => [dir.path, dir]));\n for (const file of files) {\n const pos = layout.leaf.get(file.id);\n if (!pos) continue;\n const parts = file.path.split(\"/\").filter(Boolean);\n let path = \"\";\n for (let i = 0; i < parts.length - 1; i++) {\n path = path ? `${path}/${parts[i]}` : parts[i];\n const dir = dirByPath.get(path);\n if (!dir) continue;\n dir.radius = Math.max(dir.radius, Math.hypot(pos.x - dir.x, pos.z - dir.z));\n }\n }\n\n return layout;\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport * as THREE from \"three\";\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\nimport { touchWord, type CityFile, type CityMap, type Touch } from \"../types\";\nimport type { FilePlayback } from \"../playback/reducer\";\nimport { DirLabelSet } from \"./dirLabels\";\nimport {\n disposeGroup,\n ensureVisible,\n fitDistance,\n prefersReducedMotion,\n SceneTip,\n SKY,\n touchColors\n} from \"./sceneUtils\";\nimport { computeTreeLayout, type TreeLayout } from \"./treeLayout\";\nimport { fireflyTexture, haloTexture } from \"./textures\";\nimport { TrailRenderer } from \"./trail\";\n\ninterface TreeSceneProps {\n city?: CityMap;\n playback: FilePlayback;\n selectedPath?: string;\n onSelect: (path?: string) => void;\n onCanvasReady?: (canvas: HTMLCanvasElement | null) => void;\n}\n\n// Firefly tree: the repo is a radial tree — directories fork, files are\n// leaves. The walker is a firefly that lights leaves as it lands; attention\n// depth shows as the pool of light it leaves behind on the ground.\n//\n// One variable, one channel: leaf color says WHAT happened (touch state),\n// halo radius says HOW MUCH (visits), branch brightness says WHERE the\n// light is, and the selection is a shape (ring + beam), never a recolor.\nconst colors: Record<Touch | \"unvisited\" | \"ghost\" | \"selected\", THREE.Color> = {\n unvisited: new THREE.Color(\"#5a6375\"),\n ghost: new THREE.Color(\"#4d5464\"),\n ...touchColors\n};\nconst EDGE_BASE = new THREE.Color(\"#3c424f\");\n// branches leading to visited leaves brighten, but stay neutral: the branch\n// guides the eye, the leaf carries the classification\nconst EDGE_LIT = new THREE.Color(\"#7d8496\");\n// white-hot walker: keeps the firefly apart from edit-amber leaves\nconst FIREFLY_HOT = new THREE.Color(\"#ffeeda\");\nconst LEAF_Y = 0.7;\n\n// halo radius encodes revisits only — touch type already lives in the leaf\n// color, and doubling it up here made the radius unreadable\nfunction haloRadius(visits: number): number {\n return Math.min(1.8 * (1 + 0.45 * Math.log2(Math.max(visits, 1))), 4.8);\n}\n\ninterface HaloSlot {\n fileId: number;\n target: number;\n color: THREE.Color;\n}\n\nconst LABEL_Y = 1.8;\n// the inspector docks on the right; selection pans the camera clear of it\nconst INSPECTOR_RESERVED_PX = 348;\n\nexport function TreeScene({ city, playback, selectedPath, onSelect, onCanvasReady }: TreeSceneProps) {\n const hostRef = useRef<HTMLDivElement | null>(null);\n const leafMeshRef = useRef<THREE.InstancedMesh | null>(null);\n const ghostMeshRef = useRef<THREE.InstancedMesh | null>(null);\n const ghostIndexRef = useRef<Map<number, number>>(new Map());\n const selectionRef = useRef<{ ring: THREE.Mesh; beam: THREE.Mesh } | null>(null);\n const haloMeshRef = useRef<THREE.InstancedMesh | null>(null);\n const edgesRef = useRef<THREE.LineSegments | null>(null);\n const edgeMetaRef = useRef<{ childPath?: string; childFileId?: number; vertexCount: number }[]>([]);\n const filesRef = useRef<CityFile[]>([]);\n const layoutRef = useRef<TreeLayout | null>(null);\n const slotsRef = useRef<HaloSlot[]>([]);\n const radiiRef = useRef<Map<number, number>>(new Map());\n const rendererRef = useRef<THREE.WebGLRenderer | null>(null);\n const cameraRef = useRef<THREE.PerspectiveCamera | null>(null);\n const controlsRef = useRef<OrbitControls | null>(null);\n const sceneRef = useRef<THREE.Scene | null>(null);\n const groupRef = useRef<THREE.Group | null>(null);\n const trailRef = useRef<TrailRenderer | null>(null);\n const fireflyRef = useRef<THREE.Sprite | null>(null);\n const labelSetRef = useRef<DirLabelSet | null>(null);\n const frameRef = useRef<number | null>(null);\n const reducedRef = useRef(false);\n // handlers live in the mount effect; they read playback through this ref\n const playbackRef = useRef(playback);\n playbackRef.current = playback;\n // camera fit deferred while the viewport reports no size (hidden pane,\n // background tab); resize retries it instead of leaving the camera at NaN\n const fitPendingRef = useRef<(() => boolean) | null>(null);\n\n const layout = useMemo(() => (city && city.files.length > 0 ? computeTreeLayout(city.files) : null), [city]);\n\n useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n const reduced = prefersReducedMotion();\n reducedRef.current = reduced;\n\n const scene = new THREE.Scene();\n scene.background = SKY;\n sceneRef.current = scene;\n\n const camera = new THREE.PerspectiveCamera(38, host.clientWidth / host.clientHeight || 1, 0.1, 2400);\n camera.position.set(60, 110, 90);\n cameraRef.current = camera;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));\n renderer.setSize(host.clientWidth, host.clientHeight);\n rendererRef.current = renderer;\n host.appendChild(renderer.domElement);\n onCanvasReady?.(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = !reduced;\n controls.dampingFactor = 0.08;\n controls.maxPolarAngle = Math.PI * 0.44;\n controls.autoRotate = !reduced;\n controls.autoRotateSpeed = -0.5;\n const tip = new SceneTip(host);\n controls.addEventListener(\"start\", () => {\n controls.autoRotate = false;\n tip.hide();\n });\n controlsRef.current = controls;\n\n const sky = new THREE.HemisphereLight(\"#66779b\", \"#161922\", 1.7);\n scene.add(sky);\n const moon = new THREE.DirectionalLight(\"#b6c5de\", 1.1);\n moon.position.set(-60, 120, -40);\n scene.add(moon);\n\n // screen-space nearest-leaf picking: tiny orbs are hostile raycast\n // targets, so pick whatever leaf lands closest to the pointer\n const PICK_RADIUS = 18;\n const projected = new THREE.Vector3();\n const pickFile = (event: PointerEvent): CityFile | undefined => {\n const treeLayout = layoutRef.current;\n if (!treeLayout || !cameraRef.current || !rendererRef.current) return undefined;\n const rect = rendererRef.current.domElement.getBoundingClientRect();\n const px = event.clientX - rect.left;\n const py = event.clientY - rect.top;\n let best: CityFile | undefined;\n let bestD2 = PICK_RADIUS * PICK_RADIUS;\n for (const file of filesRef.current) {\n const pos = treeLayout.leaf.get(file.id);\n if (!pos) continue;\n projected.set(pos.x, LEAF_Y, pos.z).project(cameraRef.current);\n if (projected.z > 1) continue;\n const sx = ((projected.x + 1) / 2) * rect.width;\n const sy = ((1 - projected.y) / 2) * rect.height;\n const d2 = (sx - px) * (sx - px) + (sy - py) * (sy - py);\n if (d2 < bestD2) {\n bestD2 = d2;\n best = file;\n }\n }\n return best;\n };\n\n let downAt: { x: number; y: number } | null = null;\n const onPointerDown = (event: PointerEvent) => {\n downAt = { x: event.clientX, y: event.clientY };\n };\n const onPointerUp = (event: PointerEvent) => {\n if (!downAt) return;\n const moved = Math.hypot(event.clientX - downAt.x, event.clientY - downAt.y);\n downAt = null;\n if (moved > 5) return;\n onSelect(pickFile(event)?.path);\n };\n // hover: cursor + one-line readout, throttled to one pick per frame\n let hoverRaf = 0;\n const onPointerMove = (event: PointerEvent) => {\n if (downAt) {\n tip.hide();\n return;\n }\n if (hoverRaf) return;\n hoverRaf = requestAnimationFrame(() => {\n hoverRaf = 0;\n const file = pickFile(event);\n renderer.domElement.style.cursor = file ? \"pointer\" : \"\";\n if (!file) {\n tip.hide();\n return;\n }\n const snapshot = playbackRef.current;\n const touch = snapshot.touchByPath.get(file.path);\n const visits = snapshot.visitsByFile.get(file.id) ?? 0;\n const meta = touch\n ? `${touchWord(touch)} · ${visits} visit${visits === 1 ? \"\" : \"s\"}`\n : touchWord(undefined);\n tip.show(file.path, file.ghost ? `${meta} · ghost` : meta, event.clientX, event.clientY);\n });\n };\n const onPointerLeave = () => {\n tip.hide();\n renderer.domElement.style.cursor = \"\";\n };\n renderer.domElement.addEventListener(\"pointerdown\", onPointerDown);\n renderer.domElement.addEventListener(\"pointerup\", onPointerUp);\n renderer.domElement.addEventListener(\"pointermove\", onPointerMove);\n renderer.domElement.addEventListener(\"pointerleave\", onPointerLeave);\n\n const resize = () => {\n if (!hostRef.current) return;\n const w = hostRef.current.clientWidth;\n const h = hostRef.current.clientHeight;\n if (w === 0 || h === 0) return;\n renderer.setSize(w, h);\n camera.aspect = w / h;\n camera.updateProjectionMatrix();\n if (fitPendingRef.current?.()) fitPendingRef.current = null;\n };\n const observer = new ResizeObserver(resize);\n observer.observe(host);\n\n const clock = new THREE.Clock();\n const matrix = new THREE.Matrix4();\n const quaternion = new THREE.Quaternion().setFromEuler(new THREE.Euler(-Math.PI / 2, 0, 0));\n const render = () => {\n controls.update();\n labelSetRef.current?.updateTargets(camera, renderer.domElement.clientWidth, renderer.domElement.clientHeight);\n labelSetRef.current?.ease(reducedRef.current);\n\n // pools of light grow toward their attention radius\n const halos = haloMeshRef.current;\n const slots = slotsRef.current;\n const radii = radiiRef.current;\n const treeLayout = layoutRef.current;\n if (halos && treeLayout && slots.length > 0) {\n let moving = false;\n for (let i = 0; i < slots.length; i++) {\n const slot = slots[i];\n const pos = treeLayout.leaf.get(slot.fileId);\n if (!pos) continue;\n let cur = radii.get(slot.fileId) ?? 0;\n const diff = slot.target - cur;\n if (Math.abs(diff) > 0.015) {\n cur = reducedRef.current ? slot.target : cur + diff * 0.12;\n radii.set(slot.fileId, cur);\n moving = true;\n } else if (cur !== slot.target) {\n radii.set(slot.fileId, slot.target);\n cur = slot.target;\n moving = true;\n }\n matrix.compose(\n new THREE.Vector3(pos.x, 0.06, pos.z),\n quaternion,\n new THREE.Vector3(Math.max(cur, 0.01) * 2, Math.max(cur, 0.01) * 2, 1)\n );\n halos.setMatrixAt(i, matrix);\n }\n if (moving) halos.instanceMatrix.needsUpdate = true;\n }\n\n const firefly = fireflyRef.current;\n if (firefly?.visible) {\n const t = clock.getElapsedTime();\n const base = firefly.userData.baseScale as number;\n const pulse = reducedRef.current ? 1 : 1 + 0.1 * Math.sin(t * 2.4);\n firefly.scale.setScalar(base * pulse);\n }\n renderer.render(scene, camera);\n frameRef.current = requestAnimationFrame(render);\n };\n render();\n\n return () => {\n if (frameRef.current) cancelAnimationFrame(frameRef.current);\n if (hoverRaf) cancelAnimationFrame(hoverRaf);\n renderer.domElement.removeEventListener(\"pointerdown\", onPointerDown);\n renderer.domElement.removeEventListener(\"pointerup\", onPointerUp);\n renderer.domElement.removeEventListener(\"pointermove\", onPointerMove);\n renderer.domElement.removeEventListener(\"pointerleave\", onPointerLeave);\n tip.dispose();\n observer.disconnect();\n controls.dispose();\n renderer.dispose();\n host.removeChild(renderer.domElement);\n scene.clear();\n onCanvasReady?.(null);\n };\n }, [onSelect, onCanvasReady]);\n\n // grow the skeleton: ground, edges, leaves, labels\n useEffect(() => {\n const scene = sceneRef.current;\n if (!scene) return;\n filesRef.current = city?.files ?? [];\n layoutRef.current = layout;\n slotsRef.current = [];\n radiiRef.current = new Map();\n if (!city || !layout) return;\n\n const group = new THREE.Group();\n const size = layout.radius * 2.3;\n\n scene.fog = new THREE.Fog(SKY, size * 2.1, size * 4.2);\n\n const ground = new THREE.Mesh(\n new THREE.PlaneGeometry(size * 6, size * 6),\n new THREE.MeshStandardMaterial({ color: \"#14171e\", roughness: 1 })\n );\n ground.rotation.x = -Math.PI / 2;\n ground.position.y = -0.25;\n group.add(ground);\n\n const grid = new THREE.GridHelper(size * 2.4, 40, \"#1d222c\", \"#181c25\");\n (grid.material as THREE.Material).transparent = true;\n (grid.material as THREE.Material).opacity = 0.4;\n grid.position.y = -0.24;\n group.add(grid);\n\n // branch skeleton, one segment soup with per-vertex colors\n const positions: number[] = [];\n const edgeMeta: { childPath?: string; childFileId?: number; vertexCount: number }[] = [];\n for (const edge of layout.edges) {\n let count = 0;\n for (let i = 0; i < edge.points.length - 1; i++) {\n positions.push(edge.points[i].x, 0.12, edge.points[i].z);\n positions.push(edge.points[i + 1].x, 0.12, edge.points[i + 1].z);\n count += 2;\n }\n edgeMeta.push({ childPath: edge.childPath, childFileId: edge.childFileId, vertexCount: count });\n }\n const edgeGeo = new THREE.BufferGeometry();\n edgeGeo.setAttribute(\"position\", new THREE.Float32BufferAttribute(positions, 3));\n const edgeColors = new Float32Array(positions.length);\n edgeGeo.setAttribute(\"color\", new THREE.BufferAttribute(edgeColors, 3));\n const edges = new THREE.LineSegments(\n edgeGeo,\n new THREE.LineBasicMaterial({ vertexColors: true, transparent: true, opacity: 0.9 })\n );\n edgesRef.current = edges;\n edgeMetaRef.current = edgeMeta;\n group.add(edges);\n\n // leaves: one orb per file, sized by sqrt(lines) — solid for files on\n // disk, wireframe for ghosts (touched in the session, gone from the\n // repo): shape separates them where a third grey never could.\n // state colors must not fade with distance, so leaf-like materials\n // opt out of the fog; only the ground plane keeps the depth cue\n const leafGeo = new THREE.SphereGeometry(0.5, 10, 8);\n const leafMat = new THREE.MeshBasicMaterial({ toneMapped: false, fog: false });\n const leaves = new THREE.InstancedMesh(leafGeo, leafMat, city.files.length);\n leaves.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(city.files.length * 3), 3);\n const ghostFiles = city.files.filter((file) => file.ghost);\n const ghostIndex = new Map<number, number>();\n ghostFiles.forEach((file, i) => ghostIndex.set(file.id, i));\n ghostIndexRef.current = ghostIndex;\n const matrix = new THREE.Matrix4();\n const hidden = new THREE.Matrix4().makeScale(0, 0, 0);\n for (const file of city.files) {\n const pos = layout.leaf.get(file.id);\n if (!pos) continue;\n if (file.ghost) {\n leaves.setMatrixAt(file.id, hidden);\n continue;\n }\n const scale = Math.min(0.24 + Math.sqrt(Math.max(file.lines, 1)) * 0.045, 1.05);\n matrix.compose(new THREE.Vector3(pos.x, LEAF_Y, pos.z), new THREE.Quaternion(), new THREE.Vector3(scale, scale, scale));\n leaves.setMatrixAt(file.id, matrix);\n leaves.setColorAt(file.id, colors.unvisited);\n }\n leaves.instanceMatrix.needsUpdate = true;\n if (leaves.instanceColor) leaves.instanceColor.needsUpdate = true;\n leafMeshRef.current = leaves;\n group.add(leaves);\n\n let ghosts: THREE.InstancedMesh | null = null;\n if (ghostFiles.length > 0) {\n ghosts = new THREE.InstancedMesh(\n new THREE.SphereGeometry(0.55, 8, 5),\n new THREE.MeshBasicMaterial({ wireframe: true, transparent: true, opacity: 0.85, toneMapped: false, fog: false }),\n ghostFiles.length\n );\n ghosts.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(ghostFiles.length * 3), 3);\n for (const file of ghostFiles) {\n const pos = layout.leaf.get(file.id);\n const i = ghostIndex.get(file.id)!;\n if (!pos) {\n ghosts.setMatrixAt(i, hidden);\n continue;\n }\n const scale = Math.min(0.24 + Math.sqrt(Math.max(file.lines, 1)) * 0.045, 1.05) * 0.8;\n matrix.compose(new THREE.Vector3(pos.x, LEAF_Y, pos.z), new THREE.Quaternion(), new THREE.Vector3(scale, scale, scale));\n ghosts.setMatrixAt(i, matrix);\n ghosts.setColorAt(i, colors.ghost);\n }\n ghosts.instanceMatrix.needsUpdate = true;\n if (ghosts.instanceColor) ghosts.instanceColor.needsUpdate = true;\n ghosts.raycast = () => undefined;\n group.add(ghosts);\n }\n ghostMeshRef.current = ghosts;\n\n // pools of light under visited leaves — normal blending with a fixed\n // alpha: additive stacking burned dense directories into one white\n // blob and erased the per-file radius\n const halos = new THREE.InstancedMesh(\n new THREE.PlaneGeometry(1, 1),\n new THREE.MeshBasicMaterial({\n map: haloTexture(),\n transparent: true,\n opacity: 0.55,\n depthWrite: false,\n toneMapped: false,\n fog: false\n }),\n city.files.length\n );\n halos.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(city.files.length * 3), 3);\n halos.count = 0;\n halos.frustumCulled = false;\n halos.raycast = () => undefined;\n haloMeshRef.current = halos;\n group.add(halos);\n\n // directory labels: screen-space LOD in the render loop decides which\n // of the biggest subtrees show their name\n labelSetRef.current = new DirLabelSet(layout.dirs, group, LABEL_Y);\n\n const firefly = new THREE.Sprite(\n new THREE.SpriteMaterial({\n map: fireflyTexture(),\n color: FIREFLY_HOT,\n blending: THREE.AdditiveBlending,\n depthWrite: false,\n transparent: true,\n fog: false\n })\n );\n firefly.userData.baseScale = Math.max(size * 0.026, 2.2);\n firefly.visible = false;\n fireflyRef.current = firefly;\n group.add(firefly);\n\n // selection is a shape, not a recolor: the ring + beam mark the leaf\n // while its touch color stays intact\n const selectionMat = new THREE.MeshBasicMaterial({\n color: colors.selected,\n transparent: true,\n opacity: 0.9,\n side: THREE.DoubleSide,\n depthWrite: false,\n toneMapped: false,\n fog: false\n });\n const ring = new THREE.Mesh(new THREE.RingGeometry(1.2, 1.5, 48), selectionMat);\n ring.rotation.x = -Math.PI / 2;\n ring.visible = false;\n ring.raycast = () => undefined;\n group.add(ring);\n const beam = new THREE.Mesh(\n new THREE.CylinderGeometry(0.05, 0.05, 6, 6, 1, true),\n new THREE.MeshBasicMaterial({\n color: colors.selected,\n transparent: true,\n opacity: 0.32,\n blending: THREE.AdditiveBlending,\n depthWrite: false,\n toneMapped: false,\n fog: false\n })\n );\n beam.visible = false;\n beam.raycast = () => undefined;\n group.add(beam);\n selectionRef.current = { ring, beam };\n\n const trail = new TrailRenderer(1.6);\n trailRef.current = trail;\n group.add(trail.object);\n\n groupRef.current = group;\n scene.add(group);\n\n // keep the canonical viewing direction, but pull back exactly far\n // enough that every leaf fits the viewport's frustum — nominal radius\n // ignores the aspect ratio and overflows short windows\n const fitView = (): boolean => {\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n if (!camera || !controls) return true;\n const dir = new THREE.Vector3(0.3, 0.66, 0.47).normalize();\n const points = [...layout.leaf.values()].map((pos) => new THREE.Vector3(pos.x, LEAF_Y, pos.z));\n const fitted = fitDistance(camera, dir, points);\n if (fitted === null) return false;\n // breathing room so edge leaves clear the HUD overlays\n const distance = fitted * 1.12;\n camera.position.copy(dir).multiplyScalar(distance);\n controls.target.set(0, 0, 0);\n controls.minDistance = size * 0.15;\n controls.maxDistance = Math.max(size * 2.4, distance * 1.2);\n controls.update();\n return true;\n };\n fitPendingRef.current = fitView() ? null : fitView;\n\n return () => {\n fitPendingRef.current = null;\n disposeGroup(group);\n scene.remove(group);\n groupRef.current = null;\n leafMeshRef.current = null;\n ghostMeshRef.current = null;\n ghostIndexRef.current = new Map();\n selectionRef.current = null;\n haloMeshRef.current = null;\n edgesRef.current = null;\n trailRef.current = null;\n fireflyRef.current = null;\n labelSetRef.current = null;\n };\n }, [city, layout]);\n\n // playback → leaf colors, halo targets, branch tinting\n useEffect(() => {\n const leaves = leafMeshRef.current;\n const ghosts = ghostMeshRef.current;\n const ghostIndex = ghostIndexRef.current;\n const halos = haloMeshRef.current;\n const edges = edgesRef.current;\n if (!leaves || !halos || !edges || !city || !layout) return;\n\n const radii = radiiRef.current;\n const slots: HaloSlot[] = [];\n const present = new Set<number>();\n // directories on a path to a touched file — branches brighten as a\n // single neutral tone, classification stays on the leaves\n const litDirs = new Set<string>();\n for (const file of city.files) {\n const touch = playback.touchByFile.get(file.id);\n let leafColor = file.ghost ? colors.ghost : colors.unvisited;\n if (touch) {\n leafColor = colors[touch];\n const visits = playback.visitsByFile.get(file.id) ?? 1;\n slots.push({ fileId: file.id, target: haloRadius(visits), color: colors[touch] });\n present.add(file.id);\n const parts = file.path.split(\"/\");\n let path = \"\";\n for (let i = 0; i < parts.length - 1; i++) {\n path = path ? `${path}/${parts[i]}` : parts[i];\n litDirs.add(path);\n }\n }\n if (file.ghost) {\n const i = ghostIndex.get(file.id);\n if (ghosts && i !== undefined) ghosts.setColorAt(i, leafColor);\n } else {\n leaves.setColorAt(file.id, leafColor);\n }\n }\n for (const [fileId, cur] of radii) {\n if (cur > 0.04 && !present.has(fileId)) {\n slots.push({ fileId, target: 0, color: colors.unvisited });\n } else if (cur <= 0.04 && !present.has(fileId)) {\n radii.delete(fileId);\n }\n }\n slots.forEach((slot, i) => halos.setColorAt(i, slot.color));\n halos.count = slots.length;\n if (halos.instanceColor) halos.instanceColor.needsUpdate = true;\n if (leaves.instanceColor) leaves.instanceColor.needsUpdate = true;\n if (ghosts?.instanceColor) ghosts.instanceColor.needsUpdate = true;\n slotsRef.current = slots;\n\n // brighten branches that lead to light\n const colorAttr = edges.geometry.getAttribute(\"color\") as THREE.BufferAttribute;\n let vertex = 0;\n for (const meta of edgeMetaRef.current) {\n let lit = false;\n if (meta.childFileId !== undefined) {\n lit = playback.touchByFile.has(meta.childFileId);\n } else if (meta.childPath) {\n lit = litDirs.has(meta.childPath);\n }\n const tinted = lit ? EDGE_LIT : EDGE_BASE;\n for (let v = 0; v < meta.vertexCount; v++) {\n colorAttr.setXYZ(vertex++, tinted.r, tinted.g, tinted.b);\n }\n }\n colorAttr.needsUpdate = true;\n }, [city, layout, playback]);\n\n // selection marker follows the selected leaf\n useEffect(() => {\n const selection = selectionRef.current;\n if (!selection || !city || !layout) return;\n const file = selectedPath ? city.files.find((f) => f.path === selectedPath) : undefined;\n const pos = file ? layout.leaf.get(file.id) : undefined;\n if (pos) {\n selection.ring.position.set(pos.x, 0.1, pos.z);\n selection.beam.position.set(pos.x, 3, pos.z);\n selection.ring.visible = true;\n selection.beam.visible = true;\n // the inspector opens over the right edge; pan the leaf clear of it\n const camera = cameraRef.current;\n const controls = controlsRef.current;\n const canvas = rendererRef.current?.domElement;\n if (camera && controls && canvas) {\n controls.autoRotate = false;\n ensureVisible(\n camera,\n controls,\n new THREE.Vector3(pos.x, LEAF_Y, pos.z),\n canvas.clientWidth,\n canvas.clientHeight,\n INSPECTOR_RESERVED_PX\n );\n }\n } else {\n selection.ring.visible = false;\n selection.beam.visible = false;\n }\n }, [city, layout, selectedPath]);\n\n // trail arcs + firefly\n useEffect(() => {\n const trail = trailRef.current;\n if (!trail || !city || !layout) return;\n\n // playback resolves fileId with the same path key the citymap uses, so a\n // target still missing one has no leaf to land on\n const targetFiles = playback.recentTargets\n .map((target) => (target.fileId !== undefined ? city.files[target.fileId] : undefined))\n .filter((file): file is CityFile => Boolean(file && layout.leaf.get(file.id)));\n\n const firefly = fireflyRef.current;\n if (firefly) {\n const head = targetFiles[targetFiles.length - 1];\n if (head) {\n const pos = layout.leaf.get(head.id)!;\n firefly.position.set(pos.x, LEAF_Y + 1.7, pos.z);\n firefly.visible = true;\n } else {\n firefly.visible = false;\n }\n }\n\n trail.update(\n targetFiles.map((file) => {\n const pos = layout.leaf.get(file.id)!;\n return new THREE.Vector3(pos.x, LEAF_Y + 0.3, pos.z);\n })\n );\n }, [city, layout, playback]);\n\n return <div className=\"city-scene\" ref={hostRef} aria-label=\"Firefly tree\" />;\n}\n","import type { SessionMeta } from \"../types\";\n\nexport interface SessionFilters {\n hideEmpty: boolean;\n harness?: string;\n}\n\nconst STORAGE_KEY = \"mindwalk.sessionFilters\";\n\n// activeKey keeps an explicitly opened session visible even when it has no\n// calls; the harness filter is deliberate user intent, so it still applies\nexport function sessionVisible(session: SessionMeta, filters: SessionFilters, activeKey?: string): boolean {\n if (filters.harness && session.harness !== filters.harness) return false;\n if (filters.hideEmpty && session.eventCount === 0 && session.key !== activeKey) return false;\n return true;\n}\n\nexport function loadFilters(): SessionFilters {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as Partial<SessionFilters>;\n return {\n hideEmpty: parsed.hideEmpty !== false,\n harness: typeof parsed.harness === \"string\" ? parsed.harness : undefined\n };\n }\n } catch {\n // corrupted storage: fall through to defaults\n }\n return { hideEmpty: true };\n}\n\nexport function saveFilters(filters: SessionFilters): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(filters));\n } catch {\n // storage unavailable: filters reset on next load\n }\n}\n","const createStoreImpl = (createState) => {\n let state;\n const listeners = /* @__PURE__ */ new Set();\n const setState = (partial, replace) => {\n const nextState = typeof partial === \"function\" ? partial(state) : partial;\n if (!Object.is(nextState, state)) {\n const previousState = state;\n state = (replace != null ? replace : typeof nextState !== \"object\" || nextState === null) ? nextState : Object.assign({}, state, nextState);\n listeners.forEach((listener) => listener(state, previousState));\n }\n };\n const getState = () => state;\n const getInitialState = () => initialState;\n const subscribe = (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n };\n const api = { setState, getState, getInitialState, subscribe };\n const initialState = state = createState(setState, getState, api);\n return api;\n};\nconst createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);\n\nexport { createStore };\n","import React from 'react';\nimport { createStore } from 'zustand/vanilla';\n\nconst identity = (arg) => arg;\nfunction useStore(api, selector = identity) {\n const slice = React.useSyncExternalStore(\n api.subscribe,\n React.useCallback(() => selector(api.getState()), [api, selector]),\n React.useCallback(() => selector(api.getInitialState()), [api, selector])\n );\n React.useDebugValue(slice);\n return slice;\n}\nconst createImpl = (createState) => {\n const api = createStore(createState);\n const useBoundStore = (selector) => useStore(api, selector);\n Object.assign(useBoundStore, api);\n return useBoundStore;\n};\nconst create = ((createState) => createState ? createImpl(createState) : createImpl);\n\nexport { create, useStore };\n","import { create } from \"zustand\";\nimport type { CityMap, SessionMeta, Trace } from \"../types\";\nimport { loadFilters, saveFilters } from \"./filters\";\n\nexport type SceneView = \"tree\" | \"terrain\";\n\ninterface AppState {\n sessions: SessionMeta[];\n activeSessionKey?: string;\n trace?: Trace;\n city?: CityMap;\n currentSeq: number;\n selectedPath?: string;\n view: SceneView;\n loading: boolean;\n error?: string;\n hideEmpty: boolean;\n harnessFilter?: string;\n railCollapsed: boolean;\n mapOnly: boolean;\n setView: (view: SceneView) => void;\n setSessions: (sessions: SessionMeta[]) => void;\n setActiveSession: (key?: string) => void;\n setData: (trace: Trace, city: CityMap) => void;\n setCityOnly: (city: CityMap) => void;\n setCurrentSeq: (seq: number) => void;\n setSelectedPath: (path?: string) => void;\n setLoading: (loading: boolean) => void;\n setError: (error?: string) => void;\n setHideEmpty: (hideEmpty: boolean) => void;\n setHarnessFilter: (harness?: string) => void;\n setRailCollapsed: (collapsed: boolean) => void;\n}\n\nconst initialFilters = loadFilters();\n\nconst RAIL_COLLAPSED_KEY = \"mindwalk.railCollapsed\";\n\nfunction loadRailCollapsed(): boolean {\n try {\n return localStorage.getItem(RAIL_COLLAPSED_KEY) === \"1\";\n } catch {\n return false;\n }\n}\n\nexport const useAppStore = create<AppState>((set, get) => ({\n sessions: [],\n currentSeq: 0,\n view: \"terrain\",\n loading: false,\n hideEmpty: initialFilters.hideEmpty,\n harnessFilter: initialFilters.harness,\n railCollapsed: loadRailCollapsed(),\n mapOnly: false,\n setView: (view) => set({ view }),\n setSessions: (sessions) => set({ sessions }),\n setActiveSession: (activeSessionKey) =>\n set({ activeSessionKey, trace: undefined, city: undefined, currentSeq: 0, selectedPath: undefined }),\n setData: (trace, city) => set({ trace, city, currentSeq: Math.max(0, trace.events.length - 1) }),\n // static full-repo map: render the city with no session/trace attached\n setCityOnly: (city) => set({ city, trace: undefined, currentSeq: 0, selectedPath: undefined, mapOnly: true }),\n setCurrentSeq: (currentSeq) => set({ currentSeq }),\n setSelectedPath: (selectedPath) => set({ selectedPath }),\n setLoading: (loading) => set({ loading }),\n setError: (error) => set({ error }),\n setHideEmpty: (hideEmpty) => {\n set({ hideEmpty });\n saveFilters({ hideEmpty, harness: get().harnessFilter });\n },\n setHarnessFilter: (harnessFilter) => {\n set({ harnessFilter });\n saveFilters({ hideEmpty: get().hideEmpty, harness: harnessFilter });\n },\n setRailCollapsed: (railCollapsed) => {\n set({ railCollapsed });\n try {\n localStorage.setItem(RAIL_COLLAPSED_KEY, railCollapsed ? \"1\" : \"0\");\n } catch {\n // storage unavailable: preference resets on next load\n }\n }\n}));\n","import { memo, useEffect, useRef, useState } from \"react\";\nimport type { ActionCounts, CityMap, MetricObservability, Trace } from \"../types\";\n\nexport interface ChurnEntry {\n path: string;\n edits: number;\n}\n\ninterface HudProps {\n trace?: Trace;\n city?: CityMap;\n agentLabel?: string;\n // live counts at the playhead, passed as primitives so memo stays effective\n editedNow: number;\n readNow: number;\n seenNow: number;\n churn: ChurnEntry[];\n onSelectFile: (path: string) => void;\n onOpenAgents?: () => void;\n locked?: boolean;\n}\n\nconst CHURN_PANEL_ROWS = 8;\n\n// memo: the app re-renders every playback tick; the HUD only changes when the\n// session, the view toggle, or the touch counts under the playhead change\nexport const Hud = memo(function Hud({\n trace,\n city,\n agentLabel,\n editedNow,\n readNow,\n seenNow,\n churn,\n onSelectFile,\n onOpenAgents,\n locked = false\n}: HudProps) {\n const stats = trace?.stats;\n const readFinal = stats ? stats.fovea - stats.edited : 0;\n const unvisitedNow = stats ? Math.max(0, stats.filesInRepo - editedNow - readNow - seenNow) : 0;\n const unvisitedFinal = stats ? Math.max(0, stats.filesInRepo - stats.fovea - stats.parafovea) : 0;\n const ghostCount = city ? city.files.reduce((n, file) => n + (file.ghost ? 1 : 0), 0) : 0;\n const errorCount = stats ? countActions(stats.errors) : 0;\n const showReview = stats ? errorCount > 0 || stats.churnFiles > 0 || stats.actions.edit > 0 : false;\n\n const [churnOpen, setChurnOpen] = useState(false);\n const churnPanelRef = useRef<HTMLDivElement | null>(null);\n const churnToggleRef = useRef<HTMLButtonElement | null>(null);\n\n // a new session invalidates the open list; close instead of showing stale rows\n useEffect(() => setChurnOpen(false), [trace]);\n\n useEffect(() => {\n if (!churnOpen) return;\n const onPointerDown = (event: PointerEvent) => {\n const target = event.target as Node;\n if (churnPanelRef.current?.contains(target) || churnToggleRef.current?.contains(target)) return;\n setChurnOpen(false);\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setChurnOpen(false);\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [churnOpen]);\n\n return (\n <div className=\"hud\" aria-hidden={!city}>\n <div className=\"hud-left\">\n <div className=\"hud-title-line\">\n <div className=\"hud-repo\">{city ? basename(city.repo.root) : \"\"}</div>\n {trace && agentLabel ? (\n <button\n className=\"hud-lens\"\n onClick={onOpenAgents}\n disabled={!onOpenAgents || locked}\n aria-label={`Open Agent lenses, current ${agentLabel}`}\n >\n <span>Lens</span>\n {agentLabel}\n </button>\n ) : null}\n </div>\n {city ? (\n <div className=\"hud-commit\">\n <span>{city.repo.commit || \"worktree\"}</span>\n {city.repo.dirty ? <span className=\"dirty\">● dirty</span> : null}\n {trace?.session.model ? <span>{trace.session.model}</span> : null}\n {stats ? (\n <span data-hint=\"Files in the repository map — the denominator of the coverage spectrum below\">\n {stats.filesInRepo} files\n </span>\n ) : null}\n {city.repo.truncated ? (\n <span data-hint=\"The tree holds more files than the map shows — scanning stopped at the budget\">\n partial map\n </span>\n ) : null}\n </div>\n ) : null}\n {stats ? (\n <>\n {/* the spectrum doubles as scene legend and live tally: each entry is\n a touch state, counted at the playhead → across the whole walk */}\n <div className=\"spectrum\">\n <SpectrumStat\n kind=\"edit\"\n label=\"edited\"\n now={editedNow}\n final={stats.edited}\n hint=\"Files the agent changed\"\n />\n <SpectrumStat\n kind=\"read\"\n label=\"read\"\n now={readNow}\n final={readFinal}\n hint=\"Files the agent opened and read, but never changed\"\n />\n <SpectrumStat\n kind=\"hit\"\n label=\"seen\"\n now={seenNow}\n final={stats.parafovea}\n hint=\"Files that only appeared in search results, never opened\"\n />\n <SpectrumStat\n kind=\"unvisited\"\n label=\"unvisited\"\n now={unvisitedNow}\n final={unvisitedFinal}\n hint=\"Files in the map the agent never touched\"\n />\n {ghostCount > 0 ? (\n <SpectrumStat\n kind=\"ghost\"\n label=\"ghost\"\n now={ghostCount}\n final={ghostCount}\n hint=\"Files the session touched that are gone from the repository — drawn hollow in the scene\"\n />\n ) : null}\n </div>\n {/* session scale: quiet background numbers, final totals only —\n unlike the playhead-live spectrum above */}\n <div className=\"hud-quiet\">\n <span data-hint={`Tool calls — ${mixHint(stats.actions)}`}>\n {countActions(stats.actions)} calls\n </span>\n <span data-hint=\"User messages — each one starts a turn of agent work\">\n {stats.userTurns} turns\n </span>\n {stats.subagents > 0 ? (\n <button\n className=\"hud-agent-link\"\n data-hint=\"Subagent launches (Task/Agent) — open Agent lenses\"\n onClick={onOpenAgents}\n disabled={!onOpenAgents || locked}\n aria-label={`Open ${stats.subagents} subagent${stats.subagents === 1 ? \"\" : \"s\"} in Agent lenses`}\n >\n {stats.subagents} subagent{stats.subagents === 1 ? \"\" : \"s\"}\n </button>\n ) : null}\n {stats.compactions > 0 ? (\n <span data-hint=\"Context compactions — the conversation was summarized to free memory\">\n {stats.compactions} compaction{stats.compactions === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n <span data-hint=\"Tool output the agent consumed over the session\">\n {fmtBytes(stats.resultBytes)} output\n </span>\n <span data-hint={rereadHint(stats.observability.reads)}>\n {stats.observability.reads === \"unavailable\"\n ? \"re-reads n/a\"\n : `re-reads ${approx(stats.observability.reads)}${pct(stats.regressionRate)}`}\n </span>\n </div>\n {/* review: only signals worth a second look — absent when clean */}\n {showReview ? (\n <div className=\"hud-review\">\n <span className=\"review-label\">review</span>\n {errorCount > 0 ? (\n <span\n className=\"warn\"\n data-hint={`${mixHint(stats.errors)} — press X to jump to the next one${errorCaveat(stats.observability.errors)}`}\n >\n {approx(stats.observability.errors)}\n {errorCount} error{errorCount === 1 ? \"\" : \"s\"}\n </span>\n ) : null}\n {stats.churnFiles > 0 ? (\n <button\n ref={churnToggleRef}\n className={churnOpen ? \"warn churn-toggle open\" : \"warn churn-toggle\"}\n aria-expanded={churnOpen}\n onClick={() => setChurnOpen((open) => !open)}\n data-hint={`Files edited in three or more separate events — the most-edited file changed ${stats.maxEditsPerFile} times. Click to list them.`}\n >\n {stats.churnFiles} file{stats.churnFiles === 1 ? \"\" : \"s\"} edited 3+ times\n </button>\n ) : null}\n {stats.actions.edit > 0 ? (\n stats.actions.verify === 0 ? (\n <span\n className=\"warn\"\n data-hint=\"The session edited files but no build or test commands were recognized (go test, make test, npm run build, …)\"\n >\n never verified\n </span>\n ) : stats.editsAfterLastVerify > 0 ? (\n <span\n className=\"warn\"\n data-hint={`Edit events after the session's last build or test run — ${verifyRuns(stats.actions.verify)} total; pass/fail is not tracked`}\n >\n {stats.editsAfterLastVerify} edit{stats.editsAfterLastVerify === 1 ? \"\" : \"s\"} after\n last verify\n </span>\n ) : (\n <span\n className=\"ok\"\n data-hint={`The last edit was followed by a build or test run — ${verifyRuns(stats.actions.verify)} total; pass/fail is not tracked`}\n >\n verified after final edit\n </span>\n )\n ) : null}\n </div>\n ) : null}\n {churnOpen ? (\n <div className=\"churn-panel\" ref={churnPanelRef}>\n {churn.slice(0, CHURN_PANEL_ROWS).map((entry) => (\n <button\n key={entry.path}\n className=\"churn-row\"\n onClick={() => {\n onSelectFile(entry.path);\n setChurnOpen(false);\n }}\n >\n <span className=\"churn-path\">{entry.path}</span>\n <span className=\"churn-count\">\n {entry.edits} edit{entry.edits === 1 ? \"\" : \"s\"}\n </span>\n </button>\n ))}\n {churn.length > CHURN_PANEL_ROWS ? (\n <p className=\"churn-more\">…and {churn.length - CHURN_PANEL_ROWS} more</p>\n ) : null}\n </div>\n ) : null}\n </>\n ) : null}\n </div>\n </div>\n );\n});\n\nfunction SpectrumStat({\n kind,\n label,\n now,\n final,\n hint\n}: {\n kind: \"edit\" | \"read\" | \"hit\" | \"unvisited\" | \"ghost\";\n label: string;\n now: number;\n final: number;\n hint: string;\n}) {\n return (\n <div className=\"spectrum-stat\" data-hint={hint}>\n <span className={`legend-dot ${kind}`} />\n <span className=\"spectrum-label\">{label}</span>\n <strong>{now === final ? final : `${now} → ${final}`}</strong>\n </div>\n );\n}\n\nfunction pct(rate: number): string {\n return `${Math.round(rate * 100)}%`;\n}\n\nfunction approx(observability: MetricObservability): string {\n return observability === \"estimated\" ? \"~\" : \"\";\n}\n\nfunction verifyRuns(count: number): string {\n return `${count} verify run${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction rereadHint(observability: MetricObservability): string {\n switch (observability) {\n case \"unavailable\":\n return \"No file reads observed — this session reads files through commands Synapse could not recognize\";\n case \"estimated\":\n return \"Reads that re-read a file unchanged since its last read — inferred from shell commands, so the rate is approximate\";\n default:\n return \"Reads that re-read a file unchanged since its last read\";\n }\n}\n\nfunction errorCaveat(observability: MetricObservability): string {\n return observability === \"estimated\"\n ? \" — inferred from command output; failures inside scripted calls may be missed\"\n : \"\";\n}\n\nconst ACTION_ORDER = [\"search\", \"read\", \"edit\", \"exec\", \"verify\", \"other\"] as const;\n\nfunction countActions(counts: ActionCounts): number {\n return ACTION_ORDER.reduce((sum, key) => sum + counts[key], 0);\n}\n\nfunction mixHint(counts: ActionCounts): string {\n const parts = ACTION_ORDER.filter((key) => counts[key] > 0).map((key) => `${counts[key]} ${key}`);\n return parts.length ? parts.join(\" · \") : \"none\";\n}\n\nfunction fmtBytes(bytes: number): string {\n const kb = bytes / 1024;\n if (kb < 1) return `${bytes} B`;\n if (kb < 1000) return `${Math.round(kb)} KB`;\n return `${(kb / 1024).toFixed(1)} MB`;\n}\n\nfunction basename(path: string): string {\n const clean = path.replace(/\\/+$/, \"\");\n return clean.slice(clean.lastIndexOf(\"/\") + 1);\n}\n","import { AlertTriangle, X } from \"lucide-react\";\nimport { touchWord, type CityFile, type Touch, type TraceEvent } from \"../types\";\n\ninterface InspectorProps {\n /** absent when nothing is selected yet — renders the teaching empty state */\n file?: CityFile;\n touch?: Touch;\n history: TraceEvent[];\n onClose: () => void;\n onJumpTo: (seq: number) => void;\n locked?: boolean;\n}\n\n// dock panel content: the selected file's identity, touch state, and visit\n// history. The Dock owns positioning; this owns only its own markup.\nexport function Inspector({\n file,\n touch,\n history,\n onClose,\n onJumpTo,\n locked = false\n}: InspectorProps) {\n if (!file) {\n return (\n <div className=\"dock-body\" aria-label=\"File inspector\">\n <div className=\"inspector-head\">\n <div className=\"inspector-path\">Inspect</div>\n <button className=\"icon-btn\" onClick={onClose} title=\"Close\" aria-label=\"Close inspector\">\n <X size={15} />\n </button>\n </div>\n <p className=\"dock-note\">Click a building in the scene to inspect a file — its touch state, size, and every visit the agent paid it.</p>\n </div>\n );\n }\n const slash = file.path.lastIndexOf(\"/\");\n const dir = slash >= 0 ? file.path.slice(0, slash + 1) : \"\";\n const name = slash >= 0 ? file.path.slice(slash + 1) : file.path;\n\n return (\n <div className=\"dock-body\" aria-label={`File ${file.path}`}>\n <div className=\"inspector-head\">\n <div>\n <div className=\"inspector-path\">\n <span className=\"dir\">{dir}</span>\n {name}\n </div>\n {file.ghost ? <span className=\"ghost-badge\">ghost — not in this tree</span> : null}\n </div>\n <button className=\"icon-btn\" onClick={onClose} title=\"Close\" aria-label=\"Close inspector\">\n <X size={15} />\n </button>\n </div>\n <dl className=\"inspector-facts\">\n <div>\n <dt>Touch</dt>\n <dd className={touch ? `touch-${touch}` : undefined}>{touchWord(touch)}</dd>\n </div>\n <div>\n <dt>Lang</dt>\n <dd>{file.lang || \"text\"}</dd>\n </div>\n <div>\n <dt>Lines</dt>\n <dd>{file.lines.toLocaleString()}</dd>\n </div>\n <div>\n <dt>Bytes</dt>\n <dd>{file.bytes.toLocaleString()}</dd>\n </div>\n </dl>\n <section className=\"inspector-history\">\n <p className=\"eyebrow\">Visits · {history.length}</p>\n <div className=\"history-list\">\n {history\n .slice(-14)\n .reverse()\n .map((event) => (\n <button\n key={event.seq}\n className=\"history-row\"\n onClick={() => onJumpTo(event.seq)}\n disabled={locked}\n title={`Jump to step ${event.seq + 1} — ${event.summary}`}\n >\n <span className={`action-dot ${event.action}`} />\n <strong>#{event.seq + 1}</strong>\n <span>{event.tool}</span>\n <span className=\"history-time\">{event.ts ? clock(event.ts) : \"\"}</span>\n {event.isError ? <AlertTriangle className=\"history-err\" size={13} /> : <span />}\n </button>\n ))}\n {history.length === 0 ? (\n <p className=\"muted\">Not visited yet at this point of the walk. Scrub the timeline forward.</p>\n ) : null}\n </div>\n </section>\n </div>\n );\n}\n\nfunction clock(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n return [d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, \"0\")).join(\":\");\n}\n","// The mark tells the product's story in one tile: a repository waiting in the\n// dark, and an agent's walk lighting it up — footsteps of warm firefly light,\n// touched nodes glowing by state (search moss, read moon, edit amber).\n// Colors are literal so the mark stays identical to the favicon and README asset.\nexport function LogoMark({ size = 22 }: { size?: number }) {\n return (\n <svg viewBox=\"0 0 64 64\" width={size} height={size} aria-hidden focusable=\"false\">\n <defs>\n <radialGradient id=\"logo-halo\">\n <stop offset=\"0%\" stopColor=\"#f1aa57\" stopOpacity=\"0.55\" />\n <stop offset=\"100%\" stopColor=\"#f1aa57\" stopOpacity=\"0\" />\n </radialGradient>\n </defs>\n <rect width=\"64\" height=\"64\" rx=\"14\" fill=\"#0f141b\" />\n <circle cx=\"20\" cy=\"15\" r=\"1.6\" fill=\"#3b4047\" />\n <circle cx=\"11\" cy=\"27\" r=\"1.4\" fill=\"#3b4047\" />\n <circle cx=\"51\" cy=\"40\" r=\"1.6\" fill=\"#3b4047\" />\n <circle cx=\"34\" cy=\"53\" r=\"1.4\" fill=\"#3b4047\" />\n <g fill=\"#f1aa57\">\n <circle cx=\"18.6\" cy=\"47.9\" r=\"1.15\" opacity=\"0.35\" />\n <circle cx=\"22.7\" cy=\"45.2\" r=\"1.25\" opacity=\"0.42\" />\n <circle cx=\"25.9\" cy=\"42\" r=\"1.35\" opacity=\"0.49\" />\n <circle cx=\"28.2\" cy=\"38.1\" r=\"1.45\" opacity=\"0.56\" />\n <circle cx=\"30.9\" cy=\"29.3\" r=\"1.55\" opacity=\"0.64\" />\n <circle cx=\"33\" cy=\"25.4\" r=\"1.65\" opacity=\"0.72\" />\n <circle cx=\"36\" cy=\"22.1\" r=\"1.75\" opacity=\"0.8\" />\n <circle cx=\"38\" cy=\"20.4\" r=\"1.85\" opacity=\"0.88\" />\n </g>\n <circle cx=\"13\" cy=\"50\" r=\"4.5\" fill=\"#9fc67b\" opacity=\"0.16\" />\n <circle cx=\"13\" cy=\"50\" r=\"2.4\" fill=\"#9fc67b\" />\n <circle cx=\"29.5\" cy=\"34\" r=\"5\" fill=\"#b6daf1\" opacity=\"0.16\" />\n <circle cx=\"29.5\" cy=\"34\" r=\"2.7\" fill=\"#b6daf1\" />\n <circle cx=\"44\" cy=\"17.5\" r=\"9.5\" fill=\"url(#logo-halo)\" />\n <circle cx=\"44\" cy=\"17.5\" r=\"3.4\" fill=\"#f1aa57\" />\n <circle cx=\"44\" cy=\"17.5\" r=\"1.7\" fill=\"#ffe0b0\" />\n </svg>\n );\n}\n","// ⌘B on macOS, Ctrl+B elsewhere — the toggle lives in App's keydown handler\nconst isMac = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\n\nexport const toggleRailShortcut = isMac ? \"⌘B\" : \"Ctrl+B\";\n","import { Eye, EyeOff, FolderOpen, PanelLeftClose, RefreshCw, Search } from \"lucide-react\";\nimport { memo, useEffect, useMemo, useRef, useState } from \"react\";\nimport { sessionVisible } from \"../state/filters\";\nimport { LogoMark } from \"./LogoMark\";\nimport { toggleRailShortcut } from \"./shortcuts\";\nimport type { SessionMeta } from \"../types\";\n\ninterface SessionRailProps {\n sessions: SessionMeta[];\n activeKey?: string;\n loading: boolean;\n hideEmpty: boolean;\n harnessFilter?: string;\n collapsed: boolean;\n onSelect: (key: string) => void;\n onRefresh: () => void;\n onHideEmptyChange: (hide: boolean) => void;\n onHarnessFilterChange: (harness?: string) => void;\n onCollapse: () => void;\n // opens the static full-repo map for a repo path in a new tab\n onOpenMap: (repo: string) => void;\n // the active session's repo, offered as the popover's one-click choice\n activeRepo?: string;\n // while a video export records, session switching is locked so it can't swap\n // the canvas or playhead out from under the recorder\n locked?: boolean;\n // the panel's authoritative (digest-based) status for the active session;\n // undefined = unknown (keep the list's approximate badge), null = no report\n activeReportState?: \"running\" | \"done\" | \"stale\" | \"failed\" | null;\n}\n\n// memo: the app re-renders every playback tick; the rail's props only change\n// on scans, session switches, and filter changes\nexport const SessionRail = memo(function SessionRail({\n sessions,\n activeKey,\n loading,\n hideEmpty,\n harnessFilter,\n collapsed,\n onSelect,\n onRefresh,\n onHideEmptyChange,\n onHarnessFilterChange,\n onCollapse,\n onOpenMap,\n activeRepo,\n locked = false,\n activeReportState\n}: SessionRailProps) {\n const [query, setQuery] = useState(\"\");\n const [repoPath, setRepoPath] = useState(\"\");\n const [mapOpen, setMapOpen] = useState(false);\n const mapPopRef = useRef<HTMLDivElement | null>(null);\n\n useEffect(() => {\n if (!mapOpen) return;\n const onPointerDown = (event: PointerEvent) => {\n if (mapPopRef.current?.contains(event.target as Node)) return;\n setMapOpen(false);\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") setMapOpen(false);\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [mapOpen]);\n const harnesses = useMemo(() => [...new Set(sessions.map((s) => s.harness))].sort(), [sessions]);\n const emptyCount = useMemo(() => sessions.filter((s) => s.eventCount === 0).length, [sessions]);\n // a persisted filter can name a harness with no sessions this scan; treating\n // it as \"all\" avoids an empty list with no visible chip to clear it\n const effectiveHarness = harnessFilter && harnesses.includes(harnessFilter) ? harnessFilter : undefined;\n const shown = useMemo(() => {\n const q = query.trim().toLowerCase();\n return sessions.filter((session) => {\n if (!sessionVisible(session, { hideEmpty, harness: effectiveHarness }, activeKey)) return false;\n if (!q) return true;\n return `${session.title ?? \"\"} ${session.id} ${session.gitBranch ?? \"\"} ${session.harness}`\n .toLowerCase()\n .includes(q);\n });\n }, [sessions, query, hideEmpty, effectiveHarness, activeKey]);\n\n return (\n <aside className={collapsed ? \"session-rail collapsed\" : \"session-rail\"}>\n <div className=\"rail-head\">\n <h1 className=\"wordmark\">\n <LogoMark />\n <span>\n Synapse<span className=\"spark\">.</span>\n </span>\n </h1>\n <div className=\"rail-head-actions\">\n <div className=\"rail-map\" ref={mapPopRef}>\n <button\n className=\"icon-btn\"\n onClick={() => setMapOpen((open) => !open)}\n aria-expanded={mapOpen}\n title=\"Open a repository map\"\n aria-label=\"Open a repository map\"\n >\n <FolderOpen size={15} />\n </button>\n {mapOpen ? (\n <div className=\"rail-map-pop\">\n {activeRepo ? (\n <button\n className=\"rail-map-primary\"\n onClick={() => {\n onOpenMap(activeRepo);\n setMapOpen(false);\n }}\n title={`Open the map of ${activeRepo}`}\n >\n <FolderOpen size={14} aria-hidden />\n <span className=\"rail-map-primary-text\">\n <span className=\"rail-map-primary-name\">{repoBasename(activeRepo)}</span>\n {/* the leading LRM pins the path's neutral \"/\" runs to\n LTR order inside the RTL ellipsis-at-start trick */}\n <span className=\"rail-map-primary-path\">{\"\\u200E\" + activeRepo}</span>\n </span>\n </button>\n ) : null}\n {activeRepo ? (\n <div className=\"rail-map-divider\" aria-hidden>\n <span>or open any repository</span>\n </div>\n ) : (\n <p className=\"rail-map-label\">Open a repository map</p>\n )}\n <form\n className=\"rail-map-form\"\n onSubmit={(e) => {\n e.preventDefault();\n const path = repoPath.trim();\n if (path) {\n onOpenMap(path);\n setMapOpen(false);\n }\n }}\n >\n <input\n type=\"text\"\n className=\"rail-map-input\"\n placeholder=\"/path/to/repo\"\n value={repoPath}\n onChange={(e) => setRepoPath(e.currentTarget.value)}\n spellCheck={false}\n />\n <button type=\"submit\" className=\"rail-map-go\" disabled={repoPath.trim() === \"\"}>\n Open\n </button>\n </form>\n </div>\n ) : null}\n </div>\n <button\n className=\"icon-btn\"\n onClick={onRefresh}\n disabled={locked}\n title=\"Rescan sessions\"\n aria-label=\"Rescan sessions\"\n >\n <RefreshCw size={15} />\n </button>\n <button\n className=\"icon-btn\"\n onClick={onCollapse}\n title={`Hide sidebar (${toggleRailShortcut})`}\n aria-label=\"Hide session sidebar\"\n >\n <PanelLeftClose size={15} />\n </button>\n </div>\n </div>\n <div className=\"rail-controls\">\n <label className=\"rail-filter\">\n <Search size={14} aria-hidden />\n <input\n type=\"search\"\n placeholder=\"Filter sessions\"\n value={query}\n onChange={(e) => setQuery(e.currentTarget.value)}\n aria-label=\"Filter sessions\"\n />\n </label>\n {harnesses.length > 1 || emptyCount > 0 ? (\n <div className=\"rail-chips\" role=\"group\" aria-label=\"Session filters\">\n {harnesses.length > 1 ? (\n <>\n <button\n className={effectiveHarness === undefined ? \"chip active\" : \"chip\"}\n onClick={() => onHarnessFilterChange(undefined)}\n >\n all\n </button>\n {harnesses.map((harness) => (\n <button\n key={harness}\n className={effectiveHarness === harness ? \"chip active\" : \"chip\"}\n onClick={() => onHarnessFilterChange(harness)}\n >\n {harnessLabel(harness)}\n </button>\n ))}\n </>\n ) : null}\n {emptyCount > 0 ? (\n <button\n className={hideEmpty ? \"eye-toggle\" : \"eye-toggle showing\"}\n onClick={() => onHideEmptyChange(!hideEmpty)}\n aria-pressed={!hideEmpty}\n title={\n hideEmpty ? `Show ${emptyCount} empty sessions` : `Hide ${emptyCount} empty sessions`\n }\n aria-label={\n hideEmpty ? `Show ${emptyCount} empty sessions` : `Hide ${emptyCount} empty sessions`\n }\n >\n {hideEmpty ? <EyeOff size={13} aria-hidden /> : <Eye size={13} aria-hidden />}\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n <div className=\"session-list\" aria-busy={loading}>\n {shown.map((session) => (\n <button\n key={session.key}\n className={session.key === activeKey ? \"session-row active\" : \"session-row\"}\n onClick={() => onSelect(session.key)}\n disabled={locked}\n >\n <span className=\"session-title\">{session.title || session.id}</span>\n <span className=\"session-meta\">\n <span className=\"session-meta-text\">\n {harnessLabel(session.harness)} · {session.eventCount}{\" \"}\n {session.eventCount === 1 ? \"call\" : \"calls\"}\n {session.gitBranch ? ` · ${session.gitBranch}` : \"\"}\n {session.endedAt ? ` · ${shortDate(session.endedAt)}` : \"\"}\n </span>\n {(() => {\n // the panel's digest-based status outranks the list's cheap\n // event-count grading for the active session\n const evalState =\n session.key === activeKey && activeReportState !== undefined\n ? activeReportState\n : session.reportState;\n return evalState ? (\n <span\n className={`rail-eval rail-eval-${evalState}`}\n title={evalHint(evalState)}\n aria-label={evalHint(evalState)}\n >\n {evalState === \"running\" ? \"evaluating\" : \"\"}\n </span>\n ) : null;\n })()}\n </span>\n </button>\n ))}\n {shown.length === 0 ? (\n <p className=\"muted\" style={{ padding: \"10px 8px\" }}>\n {loading && sessions.length === 0 ? \"Scanning sessions…\" : \"No matching sessions.\"}\n </p>\n ) : null}\n </div>\n <div className=\"rail-foot\">\n {shown.length === sessions.length\n ? `${sessions.length} session${sessions.length === 1 ? \"\" : \"s\"}`\n : `${shown.length} of ${sessions.length} sessions`}\n </div>\n </aside>\n );\n});\n\nfunction repoBasename(path: string): string {\n const clean = path.replace(/\\/+$/, \"\");\n return clean.slice(clean.lastIndexOf(\"/\") + 1) || clean;\n}\n\nfunction evalHint(state: \"running\" | \"done\" | \"stale\" | \"failed\"): string {\n switch (state) {\n case \"running\":\n return \"Evaluation in progress\";\n case \"done\":\n return \"Evaluation ready\";\n case \"stale\":\n return \"Evaluation ready, but the session has grown since\";\n case \"failed\":\n return \"Last evaluation failed\";\n }\n}\n\nfunction harnessLabel(harness: string): string {\n switch (harness) {\n case \"claude-code\":\n return \"claude\";\n default:\n return harness;\n }\n}\n\nfunction shortDate(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n const now = new Date();\n const sameYear = d.getFullYear() === now.getFullYear();\n const md = `${String(d.getMonth() + 1).padStart(2, \"0\")}-${String(d.getDate()).padStart(2, \"0\")}`;\n const hm = `${String(d.getHours()).padStart(2, \"0\")}:${String(d.getMinutes()).padStart(2, \"0\")}`;\n return sameYear ? `${md} ${hm}` : `${d.getFullYear()}-${md}`;\n}\n","import { Ellipsis, Loader, Pause, Play, RotateCcw, StepBack, StepForward, Video } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Action, Mark, Trace, TraceEvent } from \"../types\";\n\ninterface TimelineProps {\n trace?: Trace;\n currentSeq: number;\n onChange: (seq: number) => void;\n onSubagentMark?: (seq: number) => void;\n onExport?: () => void;\n exporting?: boolean;\n}\n\nconst BUCKETS = 160;\nconst BASE_TICK_MS = 340;\nconst SPEEDS = [1, 4, 16] as const;\ntype Speed = (typeof SPEEDS)[number];\n\ninterface Bucket {\n count: number;\n dominant: Action;\n}\n\n// marks that land on the same strip pixel collapse into one glyph; the title\n// carries the count so dense sessions stay legible\ninterface MarkGroup {\n type: Mark[\"type\"];\n seq: number;\n pos: number;\n count: number;\n note?: string;\n}\n\nconst MARK_SLOTS = 220;\n\nconst MARK_LABEL: Record<Mark[\"type\"], string> = {\n compaction: \"context compaction\",\n \"user-message\": \"user message\",\n subagent: \"subagent\"\n};\n\nconst STRIP_ACTIONS: Action[] = [\"search\", \"read\", \"edit\", \"verify\", \"exec\"];\n\nexport function Timeline({\n trace,\n currentSeq,\n onChange,\n onSubagentMark,\n onExport,\n exporting = false\n}: TimelineProps) {\n const [playing, setPlaying] = useState(false);\n const [speed, setSpeed] = useState<Speed>(1);\n const [menuOpen, setMenuOpen] = useState(false);\n const menuRef = useRef<HTMLDivElement>(null);\n const total = trace?.events.length ?? 0;\n const max = Math.max(0, total - 1);\n const seq = Math.min(currentSeq, max);\n const event = trace?.events[seq];\n\n useEffect(() => {\n setPlaying(false);\n }, [trace]);\n\n // while a video export is recording, the recorder owns the playhead — force\n // playback off so the Timeline timer can't fight it for currentSeq\n useEffect(() => {\n if (exporting) setPlaying(false);\n }, [exporting]);\n\n // the timer and shortcuts read position via refs so ticking doesn't tear them down\n const seqRef = useRef(seq);\n const maxRef = useRef(max);\n const playingRef = useRef(playing);\n seqRef.current = seq;\n maxRef.current = max;\n playingRef.current = playing;\n\n useEffect(() => {\n if (!playing || total === 0 || exporting) return;\n // higher speeds keep the render rate bounded by advancing several events per tick\n const interval = Math.max(85, BASE_TICK_MS / speed);\n const step = Math.max(1, Math.round((speed * interval) / BASE_TICK_MS));\n const timer = window.setInterval(() => {\n if (seqRef.current >= maxRef.current) {\n setPlaying(false);\n return;\n }\n onChange(Math.min(seqRef.current + step, maxRef.current));\n }, interval);\n return () => window.clearInterval(timer);\n }, [playing, speed, total, onChange, exporting]);\n\n const togglePlay = useCallback(() => {\n if (!playingRef.current && seqRef.current >= maxRef.current) onChange(0);\n setPlaying((v) => !v);\n }, [onChange]);\n\n const cycleSpeed = useCallback(() => {\n setSpeed((s) => SPEEDS[(SPEEDS.indexOf(s) + 1) % SPEEDS.length]);\n }, []);\n\n const step = useCallback(\n (delta: number) => {\n onChange(Math.min(maxRef.current, Math.max(0, seqRef.current + delta)));\n },\n [onChange]\n );\n\n const jumpEvent = useCallback(\n (dir: 1 | -1, pred: (e: TraceEvent) => boolean) => {\n if (!trace) return;\n for (let i = seqRef.current + dir; i >= 0 && i < trace.events.length; i += dir) {\n if (pred(trace.events[i])) {\n onChange(i);\n return;\n }\n }\n },\n [trace, onChange]\n );\n\n const markSeqs = useMemo(() => {\n const clamped = (trace?.marks ?? []).map((mark) => Math.min(mark.seq, Math.max(0, (trace?.events.length ?? 1) - 1)));\n return [...new Set(clamped)].sort((a, b) => a - b);\n }, [trace]);\n\n const jumpMark = useCallback(\n (dir: 1 | -1) => {\n const cur = seqRef.current;\n const next = dir === 1 ? markSeqs.find((s) => s > cur) : [...markSeqs].reverse().find((s) => s < cur);\n if (next !== undefined) onChange(next);\n },\n [markSeqs, onChange]\n );\n\n // playback shortcuts; scene and rail keep their own (⌘B lives in App).\n // suspended while exporting so a keypress can't move the recorded playhead.\n useEffect(() => {\n if (!trace || exporting) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.metaKey || e.ctrlKey || e.altKey) return;\n const target = e.target as HTMLElement | null;\n if (target?.closest(\"input, textarea, select, button, [contenteditable]\")) return;\n switch (e.key) {\n case \" \":\n e.preventDefault();\n togglePlay();\n return;\n case \"ArrowLeft\":\n e.preventDefault();\n step(e.shiftKey ? -10 : -1);\n return;\n case \"ArrowRight\":\n e.preventDefault();\n step(e.shiftKey ? 10 : 1);\n return;\n case \"Home\":\n e.preventDefault();\n onChange(0);\n return;\n case \"End\":\n e.preventDefault();\n onChange(maxRef.current);\n return;\n }\n switch (e.key.toLowerCase()) {\n case \"s\":\n cycleSpeed();\n return;\n case \"e\":\n jumpEvent(e.shiftKey ? -1 : 1, (ev) => ev.action === \"edit\");\n return;\n case \"x\":\n jumpEvent(e.shiftKey ? -1 : 1, (ev) => ev.isError);\n return;\n case \"m\":\n jumpMark(e.shiftKey ? -1 : 1);\n return;\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [trace, exporting, togglePlay, step, onChange, cycleSpeed, jumpEvent, jumpMark]);\n\n // transport + scrubber are inert with no trace, or while an export owns the playhead\n const locked = total === 0 || exporting;\n\n useEffect(() => {\n if (locked) setMenuOpen(false);\n }, [locked]);\n\n useEffect(() => {\n if (!menuOpen) return;\n const onDown = (e: PointerEvent) => {\n if (!menuRef.current?.contains(e.target as Node)) setMenuOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") setMenuOpen(false);\n };\n window.addEventListener(\"pointerdown\", onDown);\n window.addEventListener(\"keydown\", onKey);\n return () => {\n window.removeEventListener(\"pointerdown\", onDown);\n window.removeEventListener(\"keydown\", onKey);\n };\n }, [menuOpen]);\n\n const buckets = useMemo<Bucket[]>(() => {\n if (!trace || total === 0) return [];\n const n = Math.min(BUCKETS, total);\n const out: Bucket[] = [];\n for (let b = 0; b < n; b++) {\n const from = Math.floor((b * total) / n);\n const to = Math.floor(((b + 1) * total) / n);\n const byAction = new Map<Action, number>();\n for (let i = from; i < to; i++) {\n const action = trace.events[i].action;\n byAction.set(action, (byAction.get(action) ?? 0) + 1);\n }\n let dominant: Action = \"other\";\n let best = -1;\n // edits are rare but load-bearing: let them win the bucket color on ties\n const priority: Action[] = [\"edit\", \"verify\", \"read\", \"search\", \"exec\", \"other\"];\n for (const action of priority) {\n const count = byAction.get(action) ?? 0;\n if (count > best) {\n best = count;\n dominant = action;\n }\n }\n out.push({ count: to - from, dominant });\n }\n return out;\n }, [trace, total]);\n\n const peak = useMemo(() => buckets.reduce((acc, b) => Math.max(acc, b.count), 1), [buckets]);\n\n const markGroups = useMemo<MarkGroup[]>(() => {\n if (!trace) return [];\n const groups = new Map<string, MarkGroup>();\n for (const mark of trace.marks) {\n // tail marks can carry seq == events.length; clamp keeps them on the strip\n const seqC = Math.min(mark.seq, max);\n const pos = max > 0 ? seqC / max : 0;\n const key = `${mark.type}:${Math.round(pos * MARK_SLOTS)}`;\n const group = groups.get(key);\n if (group) {\n group.count++;\n group.seq = Math.min(group.seq, seqC);\n } else {\n groups.set(key, { type: mark.type, seq: seqC, pos, count: 1, note: mark.note });\n }\n }\n return [...groups.values()];\n }, [trace, max]);\n\n return (\n <footer className=\"deck\">\n <div className=\"deck-main\">\n <div className=\"strip\">\n <div className=\"strip-marks\">\n {markGroups.map((group, i) => (\n <button\n type=\"button\"\n key={`${group.type}-${group.seq}-${i}`}\n className={`strip-mark ${group.type}`}\n style={{ left: `${group.pos * 100}%` }}\n disabled={locked}\n title={`${group.note || MARK_LABEL[group.type]}${group.count > 1 ? ` ×${group.count}` : \"\"}`}\n aria-label={`Jump to ${group.note || MARK_LABEL[group.type]} at event ${group.seq + 1}${group.count > 1 ? `, ${group.count} marks` : \"\"}`}\n onClick={() =>\n group.type === \"subagent\" && onSubagentMark\n ? onSubagentMark(group.seq)\n : onChange(group.seq)\n }\n />\n ))}\n </div>\n <div className=\"strip-bars\" aria-hidden>\n {buckets.map((bucket, i) => (\n <span\n key={i}\n className={`strip-bar ${bucket.dominant}`}\n style={{ height: `${18 + (bucket.count / peak) * 82}%` }}\n />\n ))}\n </div>\n {total > 0 ? (\n <div className=\"strip-playhead\" style={{ left: `${(seq / Math.max(max, 1)) * 100}%` }} aria-hidden />\n ) : null}\n <input\n className=\"strip-input\"\n type=\"range\"\n min={0}\n max={max}\n value={seq}\n disabled={locked}\n onChange={(e) => onChange(Number(e.currentTarget.value))}\n aria-label=\"Playback position\"\n aria-valuetext={event ? `event ${event.seq}: ${event.tool}` : \"empty\"}\n />\n </div>\n\n <div className=\"deck-pos\">\n {/* reserve the widest count for this session (\"599 / 599\") so the\n ticking digits never resize the strip beside them */}\n <span className=\"deck-pos-count\" style={{ minWidth: `${String(Math.max(total, 1)).length * 2 + 3}ch` }}>\n {total > 0 ? `${seq + 1} / ${total}` : \"0 / 0\"}\n </span>\n <span className=\"deck-pos-clock\">{event?.ts ? clock(event.ts) : \"—\"}</span>\n </div>\n\n <div className=\"transport\">\n <button\n className=\"icon-btn\"\n onClick={() => step(-1)}\n disabled={locked}\n title=\"Step back (←)\"\n aria-label=\"Step back one event\"\n >\n <StepBack size={15} />\n </button>\n <button\n className=\"play-btn\"\n onClick={togglePlay}\n disabled={locked}\n title={playing ? \"Pause (Space)\" : \"Play (Space)\"}\n aria-label={playing ? \"Pause playback\" : \"Play playback\"}\n >\n {playing ? <Pause size={16} /> : <Play size={16} className=\"play-glyph\" />}\n </button>\n <button\n className=\"icon-btn\"\n onClick={() => step(1)}\n disabled={locked}\n title=\"Step forward (→)\"\n aria-label=\"Step forward one event\"\n >\n <StepForward size={15} />\n </button>\n <div className=\"transport-more\" ref={menuRef}>\n {/* the trigger doubles as status: recording spinner while an export\n runs, the engaged speed when it isn't 1× */}\n <button\n className={`icon-btn${exporting ? \" recording\" : \"\"}${menuOpen ? \" open\" : \"\"}`}\n onClick={() => setMenuOpen((v) => !v)}\n disabled={locked}\n aria-haspopup=\"true\"\n aria-expanded={menuOpen}\n title=\"More controls\"\n aria-label=\"More playback controls\"\n >\n {exporting ? (\n <Loader size={15} className=\"spin\" />\n ) : speed !== 1 ? (\n <span className=\"more-speed\">{speed}×</span>\n ) : (\n <Ellipsis size={15} />\n )}\n </button>\n {menuOpen ? (\n <div className=\"transport-pop\">\n <div className=\"pop-speed\">\n <span className=\"pop-speed-label\">Speed</span>\n <div className=\"pop-speed-chips\" title=\"Cycle with S\">\n {SPEEDS.map((s) => (\n <button\n key={s}\n className={s === speed ? \"pop-chip engaged\" : \"pop-chip\"}\n onClick={() => setSpeed(s)}\n aria-pressed={s === speed}\n >\n {s}×\n </button>\n ))}\n </div>\n </div>\n <button\n className=\"pop-item\"\n onClick={() => {\n onChange(0);\n setMenuOpen(false);\n }}\n >\n <RotateCcw size={14} />\n <span>Restart</span>\n <kbd>Home</kbd>\n </button>\n {onExport ? (\n <button\n className=\"pop-item\"\n onClick={() => {\n setMenuOpen(false);\n onExport();\n }}\n >\n <Video size={14} />\n <span>Export video</span>\n </button>\n ) : null}\n </div>\n ) : null}\n </div>\n </div>\n </div>\n\n <div className=\"deck-foot\">\n <div className=\"readout-now\">\n {event ? (\n <>\n <span className={`action-dot ${event.action}`} />\n <span className=\"readout-tool\">{event.tool}</span>\n {event.isError ? <span className=\"err\">error</span> : null}\n <span className=\"readout-summary\" title={event.summary}>\n {event.summary}\n </span>\n </>\n ) : (\n <span className=\"readout-summary\">\n {trace ? \"No recorded activity for this agent.\" : \"Select a session to start the walk.\"}\n </span>\n )}\n </div>\n <div className=\"deck-legend\" aria-hidden>\n <span className=\"legend-group\">\n {STRIP_ACTIONS.map((action) => (\n <span key={action} className=\"legend-item\">\n <span className={`action-dot ${action}`} />\n {action}\n </span>\n ))}\n </span>\n <span className=\"legend-group\">\n <span className=\"legend-item\">\n <span className=\"legend-glyph compaction\" />\n compaction\n </span>\n <span className=\"legend-item\">\n <span className=\"legend-glyph subagent\" />\n subagent\n </span>\n <span className=\"legend-item\">\n <span className=\"legend-glyph user-message\" />\n user turn\n </span>\n </span>\n </div>\n </div>\n </footer>\n );\n}\n\nfunction clock(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n return [d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, \"0\")).join(\":\");\n}\n","import { PanelLeftOpen } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n describeError,\n getAgentTrace,\n getRepoMap,\n getSessionAgents,\n getSessionReport,\n getSessionSnapshot,\n listSessions,\n startSessionAnalyze\n} from \"./api/client\";\nimport { Crosshair, Sparkles, Mountain, TreePine, Users } from \"lucide-react\";\nimport type { AgentGraph, CityMap, JudgeChoice, ReportStatus, Trace } from \"./types\";\nimport { Dock, type PanelDescriptor } from \"./ui/Dock\";\nimport { AgentsPanel } from \"./ui/AgentsPanel\";\nimport { ReportPanel } from \"./ui/ReportPanel\";\nimport { ViewPanel } from \"./ui/ViewPanel\";\nimport { PlaybackEngine } from \"./playback/reducer\";\nimport { downloadBlob, recordingSupported, recordPlayback } from \"./playback/recorder\";\nimport { CityScene } from \"./scene/CityScene\";\nimport { TreeScene } from \"./scene/TreeScene\";\nimport { sessionVisible } from \"./state/filters\";\nimport { useAppStore } from \"./state/store\";\nimport { Hud } from \"./ui/Hud\";\nimport { Inspector } from \"./ui/Inspector\";\nimport { SessionRail } from \"./ui/SessionRail\";\nimport { toggleRailShortcut } from \"./ui/shortcuts\";\nimport { Timeline } from \"./ui/Timeline\";\nimport \"./styles.css\";\n\nfunction evaluateHint(badge: \"running\" | \"done\" | \"stale\" | \"failed\" | null): string {\n switch (badge) {\n case \"running\":\n return \"The judge is reading the trace — about a minute\";\n case \"done\":\n return \"Evaluation ready\";\n case \"stale\":\n return \"Evaluation ready, but the session has grown since\";\n case \"failed\":\n return \"The last evaluation failed — open to retry\";\n default:\n return \"Evaluate this session with your local agent CLI\";\n }\n}\n\nconst MAIN_ACTOR_KEY = \"__main__\";\n\nexport default function App() {\n const {\n sessions,\n activeSessionKey,\n trace,\n city,\n currentSeq,\n selectedPath,\n view,\n loading,\n error,\n hideEmpty,\n harnessFilter,\n railCollapsed,\n mapOnly,\n setView,\n setSessions,\n setActiveSession,\n setData,\n setCityOnly,\n setCurrentSeq,\n setSelectedPath,\n setLoading,\n setError,\n setHideEmpty,\n setHarnessFilter,\n setRailCollapsed\n } = useAppStore();\n const urlSessionConsumed = useRef(false);\n const scanGeneration = useRef(0);\n const loadGeneration = useRef(0);\n const lensGeneration = useRef(0);\n const agentGraphRequest = useRef(0);\n const agentTraceRequest = useRef(0);\n const manualRefreshInFlight = useRef(false);\n const pendingLoads = useRef(0);\n const activeSessionKeyRef = useRef(activeSessionKey);\n activeSessionKeyRef.current = activeSessionKey;\n const canvasRef = useRef<HTMLCanvasElement | null>(null);\n const [exporting, setExporting] = useState(false);\n const [openSheet, setOpenSheet] = useState<string | null>(null);\n const [openPop, setOpenPop] = useState<string | null>(null);\n const [reportStatus, setReportStatus] = useState<ReportStatus | undefined>();\n const [agentGraph, setAgentGraph] = useState<AgentGraph | undefined>();\n const [activeAgentID, setActiveAgentID] = useState<string | null>(null);\n const [agentGraphLoading, setAgentGraphLoading] = useState(false);\n const [loadingAgentID, setLoadingAgentID] = useState<string | undefined>();\n const [agentPanelError, setAgentPanelError] = useState<string | undefined>();\n const [agentRetryID, setAgentRetryID] = useState<string | null | undefined>();\n const activeAgentIDRef = useRef<string | null>(null);\n const pendingAgentIDRef = useRef<string | undefined>(undefined);\n const rootTraceRef = useRef<Trace | undefined>(undefined);\n const rootCityRef = useRef<CityMap | undefined>(undefined);\n const actorTraceCache = useRef(new Map<string, Trace>());\n const actorPlayheads = useRef(new Map<string, number>());\n const exportingRef = useRef(false);\n exportingRef.current = exporting;\n\n // scenes hand up their live <canvas> so the video exporter can capture it;\n // stable identity keeps the scene mount effect from remounting on every render\n const handleCanvasReady = useCallback((canvas: HTMLCanvasElement | null) => {\n canvasRef.current = canvas;\n }, []);\n\n const beginLoading = useCallback(() => {\n pendingLoads.current++;\n setLoading(true);\n }, [setLoading]);\n\n const endLoading = useCallback(() => {\n pendingLoads.current = Math.max(0, pendingLoads.current - 1);\n if (pendingLoads.current === 0) setLoading(false);\n }, [setLoading]);\n\n const resetLens = useCallback(() => {\n const generation = ++lensGeneration.current;\n agentGraphRequest.current++;\n agentTraceRequest.current++;\n activeAgentIDRef.current = null;\n pendingAgentIDRef.current = undefined;\n rootTraceRef.current = undefined;\n rootCityRef.current = undefined;\n actorTraceCache.current.clear();\n actorPlayheads.current.clear();\n setAgentGraph(undefined);\n setActiveAgentID(null);\n setAgentGraphLoading(false);\n setLoadingAgentID(undefined);\n setAgentPanelError(undefined);\n setAgentRetryID(undefined);\n return generation;\n }, []);\n\n const loadAgentGraph = useCallback(async (key: string, generation = lensGeneration.current) => {\n const request = ++agentGraphRequest.current;\n setAgentGraphLoading(true);\n setAgentPanelError(undefined);\n setAgentRetryID(undefined);\n try {\n const graph = await getSessionAgents(key);\n if (\n generation !== lensGeneration.current ||\n request !== agentGraphRequest.current ||\n activeSessionKeyRef.current !== key\n ) {\n return;\n }\n setAgentGraph(graph);\n } catch (err) {\n if (\n generation === lensGeneration.current &&\n request === agentGraphRequest.current &&\n activeSessionKeyRef.current === key\n ) {\n setAgentPanelError(describeError(err, \"loading agents\"));\n setAgentRetryID(null);\n }\n } finally {\n if (\n generation === lensGeneration.current &&\n request === agentGraphRequest.current &&\n activeSessionKeyRef.current === key\n ) {\n setAgentGraphLoading(false);\n }\n }\n }, []);\n\n const loadSession = useCallback(async (key: string) => {\n const generation = ++loadGeneration.current;\n const currentLensGeneration = lensGeneration.current;\n beginLoading();\n setError(undefined);\n try {\n const { trace: nextTrace, city: nextCity } = await getSessionSnapshot(key);\n if (\n generation !== loadGeneration.current ||\n currentLensGeneration !== lensGeneration.current ||\n activeSessionKeyRef.current !== key\n ) {\n return;\n }\n rootTraceRef.current = nextTrace;\n rootCityRef.current = nextCity;\n actorTraceCache.current.set(MAIN_ACTOR_KEY, nextTrace);\n const activeChildID = activeAgentIDRef.current;\n if (activeChildID === null) {\n setData(nextTrace, nextCity);\n const remembered = actorPlayheads.current.get(MAIN_ACTOR_KEY);\n if (remembered !== undefined) {\n setCurrentSeq(Math.min(remembered, Math.max(0, nextTrace.events.length - 1)));\n }\n setSelectedPath(undefined);\n } else {\n const childTrace = actorTraceCache.current.get(activeChildID);\n if (childTrace) {\n const seq = useAppStore.getState().currentSeq;\n setData(childTrace, nextCity);\n setCurrentSeq(Math.min(seq, Math.max(0, childTrace.events.length - 1)));\n }\n }\n } catch (err) {\n if (generation === loadGeneration.current && activeSessionKeyRef.current === key) {\n setError(describeError(err, \"loading the session\"));\n }\n } finally {\n endLoading();\n }\n }, [beginLoading, endLoading, setCurrentSeq, setData, setError, setSelectedPath]);\n\n const invalidateActorTracesForRescan = useCallback(() => {\n const activeActorID = activeAgentIDRef.current;\n actorPlayheads.current.set(\n activeActorID ?? MAIN_ACTOR_KEY,\n useAppStore.getState().currentSeq\n );\n agentTraceRequest.current++;\n pendingAgentIDRef.current = undefined;\n actorTraceCache.current.clear();\n activeAgentIDRef.current = null;\n setActiveAgentID(null);\n setLoadingAgentID(undefined);\n setAgentPanelError(undefined);\n setAgentRetryID(undefined);\n\n const rootTrace = rootTraceRef.current;\n const rootCity = rootCityRef.current;\n if (rootTrace && rootCity) {\n setData(rootTrace, rootCity);\n const remembered = actorPlayheads.current.get(MAIN_ACTOR_KEY);\n if (remembered !== undefined) {\n setCurrentSeq(Math.min(remembered, Math.max(0, rootTrace.events.length - 1)));\n }\n setSelectedPath(undefined);\n }\n }, [setCurrentSeq, setData, setSelectedPath]);\n\n const scan = useCallback(async (fresh: boolean) => {\n const generation = ++scanGeneration.current;\n beginLoading();\n setError(undefined);\n try {\n const data = await listSessions(fresh);\n if (generation !== scanGeneration.current) return;\n setSessions(data);\n let preferred: string | undefined;\n if (!urlSessionConsumed.current) {\n urlSessionConsumed.current = true;\n const selector = new URL(window.location.href).searchParams.get(\"session\") ?? undefined;\n const exact = selector ? data.find((session) => session.key === selector) : undefined;\n const legacyMatches = selector && !exact ? data.filter((session) => session.id === selector) : [];\n const fromUrl = exact?.key ?? (legacyMatches.length === 1 ? legacyMatches[0].key : undefined);\n if (fromUrl) {\n preferred = fromUrl;\n } else if (legacyMatches.length > 1) {\n console.warn(`session id \"${selector}\" is ambiguous; falling back to the latest session`);\n } else if (selector) {\n console.warn(`session \"${selector}\" not found; falling back to the latest session`);\n }\n }\n // a session can disappear between scans; fall back instead of pinning a dead key\n const currentActiveKey = activeSessionKeyRef.current;\n const stillListed =\n currentActiveKey !== undefined && data.some((session) => session.key === currentActiveKey);\n // prefer a session the rail will actually show; if the filters hide\n // everything, the newest session still beats a blank stage\n const fallback = (\n data.find((session) => sessionVisible(session, { hideEmpty, harness: harnessFilter })) ?? data[0]\n )?.key;\n const next = preferred ?? (stillListed ? currentActiveKey : fallback);\n if (next !== currentActiveKey) {\n const lens = resetLens();\n activeSessionKeyRef.current = next;\n if (!next) loadGeneration.current++;\n setActiveSession(next);\n if (next) void loadAgentGraph(next, lens);\n } else if (fresh && next) {\n invalidateActorTracesForRescan();\n void loadAgentGraph(next);\n }\n if (next) await loadSession(next);\n } catch (err) {\n if (generation === scanGeneration.current) {\n setError(describeError(err, \"scanning sessions\"));\n }\n } finally {\n endLoading();\n }\n }, [beginLoading, endLoading, harnessFilter, hideEmpty, invalidateActorTracesForRescan, loadAgentGraph, loadSession, resetLens, setActiveSession, setError, setSessions]);\n\n const loadRepoMap = useCallback(async (repo?: string) => {\n beginLoading();\n setError(undefined);\n try {\n const city = await getRepoMap(repo);\n setCityOnly(city);\n } catch (err) {\n setError(describeError(err, \"loading the repository map\"));\n } finally {\n endLoading();\n }\n }, [beginLoading, endLoading, setCityOnly, setError]);\n\n // open the static map for a repo in a new tab so the running session stays put\n const openMap = useCallback((repo?: string) => {\n const url = repo ? `/?map=1&repo=${encodeURIComponent(repo)}` : \"/?map=1\";\n window.open(url, \"_blank\", \"noopener\");\n }, []);\n\n const selectSession = useCallback((key: string) => {\n if (activeSessionKeyRef.current === key) return;\n const lens = resetLens();\n activeSessionKeyRef.current = key;\n setActiveSession(key);\n void loadAgentGraph(key, lens);\n void loadSession(key);\n }, [loadAgentGraph, loadSession, resetLens, setActiveSession]);\n\n const saveActivePlayhead = useCallback(() => {\n const key = activeAgentIDRef.current ?? MAIN_ACTOR_KEY;\n actorPlayheads.current.set(key, useAppStore.getState().currentSeq);\n }, []);\n\n const showCachedActor = useCallback((agentID: string | null, nextTrace: Trace, nextCity: CityMap) => {\n saveActivePlayhead();\n activeAgentIDRef.current = agentID;\n setActiveAgentID(agentID);\n setData(nextTrace, nextCity);\n const remembered = actorPlayheads.current.get(agentID ?? MAIN_ACTOR_KEY);\n if (remembered !== undefined) {\n setCurrentSeq(Math.min(remembered, Math.max(0, nextTrace.events.length - 1)));\n }\n setSelectedPath(undefined);\n }, [saveActivePlayhead, setCurrentSeq, setData, setSelectedPath]);\n\n const selectAgent = useCallback(async (agentID: string | null) => {\n if (exportingRef.current) return;\n const rootKey = activeSessionKeyRef.current;\n const nextCity = rootCityRef.current;\n if (!rootKey || !nextCity) return;\n\n const request = ++agentTraceRequest.current;\n pendingAgentIDRef.current = undefined;\n setLoadingAgentID(undefined);\n setAgentPanelError(undefined);\n setAgentRetryID(undefined);\n\n if (activeAgentIDRef.current === agentID) return;\n\n const cachedTrace =\n agentID === null ? rootTraceRef.current : actorTraceCache.current.get(agentID);\n if (cachedTrace) {\n showCachedActor(agentID, cachedTrace, nextCity);\n return;\n }\n if (agentID === null) return;\n\n const node = agentGraph?.agents.find((agent) => agent.id === agentID);\n if (!node || node.traceAvailability !== \"available\") return;\n\n const generation = lensGeneration.current;\n pendingAgentIDRef.current = agentID;\n setLoadingAgentID(agentID);\n try {\n const nextTrace = await getAgentTrace(rootKey, agentID);\n if (\n generation !== lensGeneration.current ||\n request !== agentTraceRequest.current ||\n pendingAgentIDRef.current !== agentID ||\n activeSessionKeyRef.current !== rootKey ||\n exportingRef.current\n ) {\n return;\n }\n actorTraceCache.current.set(agentID, nextTrace);\n showCachedActor(agentID, nextTrace, rootCityRef.current ?? nextCity);\n } catch (err) {\n if (\n generation === lensGeneration.current &&\n request === agentTraceRequest.current &&\n pendingAgentIDRef.current === agentID &&\n activeSessionKeyRef.current === rootKey\n ) {\n setAgentPanelError(describeError(err, `loading the ${node.label} trace`));\n setAgentRetryID(agentID);\n }\n } finally {\n if (\n generation === lensGeneration.current &&\n request === agentTraceRequest.current &&\n pendingAgentIDRef.current === agentID &&\n activeSessionKeyRef.current === rootKey\n ) {\n pendingAgentIDRef.current = undefined;\n setLoadingAgentID(undefined);\n }\n }\n }, [agentGraph, showCachedActor]);\n\n const retryAgents = useCallback(() => {\n const key = activeSessionKeyRef.current;\n if (exportingRef.current || !key || agentRetryID === undefined) return;\n if (agentRetryID === null) void loadAgentGraph(key);\n else void selectAgent(agentRetryID);\n }, [agentRetryID, loadAgentGraph, selectAgent]);\n\n const exportVideo = useCallback(async () => {\n const canvas = canvasRef.current;\n const total = trace?.events.length ?? 0;\n if (!canvas || total === 0 || exportingRef.current) return;\n // the recorder owns the playhead for the duration of the export; setting\n // exporting=true locks the transport, scrubber, session rail, and view\n // toggle (see the `exporting` prop threaded into Timeline/SessionRail/Hud)\n // so nothing else moves the playhead or swaps the canvas mid-recording\n const exportSessionKey = activeSessionKeyRef.current;\n const exportActorID = activeAgentIDRef.current;\n const resumeSeq = useAppStore.getState().currentSeq;\n agentTraceRequest.current++;\n pendingAgentIDRef.current = undefined;\n setLoadingAgentID(undefined);\n exportingRef.current = true;\n setExporting(true);\n setError(undefined);\n try {\n const { blob, extension } = await recordPlayback({\n canvas,\n total,\n setSeq: setCurrentSeq\n });\n const name = trace?.session.id || exportSessionKey || \"session\";\n downloadBlob(blob, `mindwalk-${name}.${extension}`);\n } catch (err) {\n setError(describeError(err, \"exporting the video\"));\n } finally {\n // only restore the playhead if we're still on the same session and actor —\n // a guard in case a switch slipped through; normally the UI lock prevents it\n if (\n activeSessionKeyRef.current === exportSessionKey &&\n activeAgentIDRef.current === exportActorID\n ) {\n setCurrentSeq(resumeSeq);\n }\n exportingRef.current = false;\n setExporting(false);\n }\n }, [trace, exporting, setCurrentSeq, setError]);\n\n // stable callbacks keep SessionRail's memo effective across playback ticks\n const collapseRail = useCallback(() => setRailCollapsed(true), [setRailCollapsed]);\n const expandRail = useCallback(() => setRailCollapsed(false), [setRailCollapsed]);\n\n // --- session evaluation: fetched on session switch, polled while the judge\n // runs; the judge itself only ever starts from the explicit button press\n const refreshReport = useCallback(async (key: string) => {\n try {\n const status = await getSessionReport(key);\n if (activeSessionKeyRef.current === key) setReportStatus(status);\n } catch {\n // not worth a toast: the status stays undefined, the panel keeps its\n // \"checking\" state, and the unknown-status retry effect below tries\n // again until the server answers\n }\n }, []);\n\n useEffect(() => {\n setOpenSheet(null);\n setOpenPop(null);\n setReportStatus(undefined);\n if (activeSessionKey && !mapOnly) void refreshReport(activeSessionKey);\n }, [activeSessionKey, mapOnly, refreshReport]);\n\n // refreshes the rail's evaluation badges without disturbing selection —\n // scan() owns selection fallback, this only swaps the list data\n const refreshSessionList = useCallback(async () => {\n try {\n setSessions(await listSessions());\n } catch {\n // badge refresh is best-effort; the next scan will catch up\n }\n }, [setSessions]);\n\n // manual rescan: the active key usually survives it, so the report status\n // must be refetched explicitly — it may have gone stale or finished while\n // we weren't polling\n const refresh = useCallback(() => {\n if (exportingRef.current || manualRefreshInFlight.current) return;\n manualRefreshInFlight.current = true;\n const key = activeSessionKeyRef.current;\n if (key && !mapOnly) void refreshReport(key);\n void scan(true).finally(() => {\n manualRefreshInFlight.current = false;\n });\n }, [scan, refreshReport, mapOnly]);\n\n useEffect(() => {\n if (reportStatus?.state !== \"running\" || !activeSessionKey) return;\n const timer = setInterval(() => {\n void refreshReport(activeSessionKey);\n void refreshSessionList();\n }, 2500);\n return () => {\n clearInterval(timer);\n // one more list pass so the rail badge leaves \"evaluating\" promptly\n void refreshSessionList();\n };\n }, [reportStatus?.state, activeSessionKey, refreshReport, refreshSessionList]);\n\n // while the report status is unknown (first request failed or still on its\n // way), keep asking — otherwise a single dropped request would pin the\n // panel to \"checking\" until a session switch or reload\n useEffect(() => {\n if (reportStatus !== undefined || !activeSessionKey || mapOnly) return;\n const timer = setInterval(() => void refreshReport(activeSessionKey), 5000);\n return () => clearInterval(timer);\n }, [reportStatus === undefined, activeSessionKey, mapOnly, refreshReport]);\n\n // a judge can be running for a session other than the active one; keep the\n // rail badges honest by polling the list until every run finishes (the\n // running-state effect above already polls while the active session runs)\n const anyEvaluating = useMemo(() => sessions.some((s) => s.reportState === \"running\"), [sessions]);\n useEffect(() => {\n if (!anyEvaluating || reportStatus?.state === \"running\") return;\n const timer = setInterval(() => void refreshSessionList(), 5000);\n return () => clearInterval(timer);\n }, [anyEvaluating, reportStatus?.state, refreshSessionList]);\n\n const analyzeSession = useCallback(async (choice: JudgeChoice) => {\n const key = activeSessionKeyRef.current;\n if (!key) return;\n try {\n const status = await startSessionAnalyze(key, choice);\n if (activeSessionKeyRef.current === key) setReportStatus(status);\n void refreshSessionList();\n } catch (err) {\n setError(describeError(err, \"starting the evaluation\"));\n }\n }, [setError, refreshSessionList]);\n\n // selecting a file in the scene opens the inspect sheet; deselecting keeps\n // whatever panel the user had open\n const selectFile = useCallback(\n (path: string | undefined) => {\n setSelectedPath(path);\n if (path) setOpenSheet(\"inspect\");\n },\n [setSelectedPath]\n );\n\n const closeSheet = useCallback(() => setOpenSheet(null), []);\n const closePop = useCallback(() => setOpenPop(null), []);\n const openAgents = useCallback(() => {\n if (!exportingRef.current) setOpenSheet(\"agents\");\n }, []);\n\n // sheets are exclusive (one full-height paper at a time); pops toggle\n // independently so a view tweak never steals the open report\n const togglePanel = useCallback((panel: PanelDescriptor) => {\n if (panel.presentation === \"sheet\") {\n setOpenSheet((current) => (current === panel.id ? null : panel.id));\n } else {\n setOpenPop((current) => (current === panel.id ? null : panel.id));\n }\n }, []);\n\n // a finding jump moves the playhead and focuses the evidence's file so the\n // claim is visible in the scene, not just in the panel — without stealing\n // the dock away from the evaluation tab\n const jumpToEvidence = useCallback(\n (seq: number) => {\n if (exportingRef.current) return;\n const rootTrace = rootTraceRef.current;\n const rootCity = rootCityRef.current;\n if (!rootTrace || !rootCity) return;\n agentTraceRequest.current++;\n pendingAgentIDRef.current = undefined;\n setLoadingAgentID(undefined);\n if (activeAgentIDRef.current !== null) {\n saveActivePlayhead();\n activeAgentIDRef.current = null;\n setActiveAgentID(null);\n setData(rootTrace, rootCity);\n }\n setCurrentSeq(seq);\n actorPlayheads.current.set(MAIN_ACTOR_KEY, seq);\n const event = rootTrace.events[seq];\n const path = event?.targets.find((target) => target.path)?.path;\n setSelectedPath(path);\n },\n [saveActivePlayhead, setCurrentSeq, setData, setSelectedPath]\n );\n\n const openAgentsAtMark = useCallback((seq: number) => {\n setCurrentSeq(seq);\n setOpenSheet(\"agents\");\n }, [setCurrentSeq]);\n\n const jumpToHistory = useCallback((seq: number) => {\n if (exportingRef.current) return;\n setCurrentSeq(seq);\n }, [setCurrentSeq]);\n\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() !== \"b\" || !(e.metaKey || e.ctrlKey) || e.altKey || e.shiftKey) return;\n e.preventDefault();\n const store = useAppStore.getState();\n store.setRailCollapsed(!store.railCollapsed);\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, []);\n\n // V cycles the scene view without opening the view pop; locked during\n // export because switching scenes would swap the recorded canvas\n useEffect(() => {\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() !== \"v\" || e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) return;\n const target = e.target as HTMLElement | null;\n if (target && (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\" || target.isContentEditable)) return;\n if (exportingRef.current) return;\n const store = useAppStore.getState();\n store.setView(store.view === \"tree\" ? \"terrain\" : \"tree\");\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, []);\n\n useEffect(() => {\n const params = new URL(window.location.href).searchParams;\n if (params.get(\"map\") === \"1\") {\n void loadRepoMap(params.get(\"repo\") ?? undefined);\n } else {\n void scan(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const reportBadge = useMemo(() => {\n if (reportStatus?.state === \"running\") return \"running\" as const;\n if (reportStatus?.state === \"failed\") return \"failed\" as const;\n if (reportStatus?.state === \"done\") return reportStatus.stale ? (\"stale\" as const) : (\"done\" as const);\n return null;\n }, [reportStatus]);\n\n const agentLabel = useMemo(() => {\n if (activeAgentID === null) return \"Main\";\n return agentGraph?.agents.find((agent) => agent.id === activeAgentID)?.label ?? \"Subagent\";\n }, [activeAgentID, agentGraph]);\n\n const viewNote =\n view === \"tree\"\n ? trace\n ? \"glow ∝ revisits\"\n : \"static map\"\n : trace\n ? \"height ∝ depth × revisits\"\n : \"height ∝ lines\";\n\n const engine = useMemo(() => new PlaybackEngine(trace, city), [trace, city]);\n const playback = useMemo(() => engine.snapshotAt(currentSeq), [engine, currentSeq]);\n // live tallies for the HUD spectrum; touchByPath mirrors the backend stats scope\n const touchCounts = useMemo(() => {\n let edited = 0;\n let read = 0;\n let seen = 0;\n for (const touch of playback.touchByPath.values()) {\n if (touch === \"edit\") edited++;\n else if (touch === \"read\") read++;\n else seen++;\n }\n return { edited, read, seen };\n }, [playback]);\n const selectedFile = useMemo(\n () => (selectedPath ? city?.files.find((file) => file.path === selectedPath) : undefined),\n [city, selectedPath]\n );\n // mirrors the backend churn definition (stats.churnFiles): per path, the\n // number of events that carried an edit touch; churn means three or more\n const churn = useMemo(() => {\n const counts = new Map<string, number>();\n for (const event of trace?.events ?? []) {\n for (const target of event.targets) {\n if (target.touch === \"edit\" && target.path) {\n counts.set(target.path, (counts.get(target.path) ?? 0) + 1);\n }\n }\n }\n return [...counts.entries()]\n .filter(([, edits]) => edits >= 3)\n .map(([path, edits]) => ({ path, edits }))\n .sort((a, b) => b.edits - a.edits || (a.path < b.path ? -1 : 1));\n }, [trace]);\n\n return (\n <main className={mapOnly ? \"app-frame rail-collapsed\" : railCollapsed ? \"app-frame rail-collapsed\" : \"app-frame\"}>\n {mapOnly ? null : (\n <SessionRail\n sessions={sessions}\n activeKey={activeSessionKey}\n loading={loading}\n hideEmpty={hideEmpty}\n harnessFilter={harnessFilter}\n collapsed={railCollapsed}\n onSelect={selectSession}\n onRefresh={refresh}\n onHideEmptyChange={setHideEmpty}\n onHarnessFilterChange={setHarnessFilter}\n onCollapse={collapseRail}\n onOpenMap={openMap}\n activeRepo={trace?.session.cwd}\n locked={exporting}\n activeReportState={reportStatus === undefined ? undefined : reportBadge}\n />\n )}\n <section className=\"stage\">\n <div className=\"viewport\">\n {!mapOnly && railCollapsed ? (\n <button\n className=\"rail-expand\"\n onClick={expandRail}\n title={`Show sidebar (${toggleRailShortcut})`}\n aria-label=\"Show session sidebar\"\n >\n <PanelLeftOpen size={15} />\n </button>\n ) : null}\n {view === \"tree\" ? (\n <TreeScene\n city={city}\n playback={playback}\n selectedPath={selectedPath}\n onSelect={selectFile}\n onCanvasReady={handleCanvasReady}\n />\n ) : (\n <CityScene\n city={city}\n playback={playback}\n selectedPath={selectedPath}\n onSelect={selectFile}\n onCanvasReady={handleCanvasReady}\n locHeights={mapOnly}\n />\n )}\n <Hud\n trace={trace}\n city={city}\n agentLabel={agentLabel}\n editedNow={touchCounts.edited}\n readNow={touchCounts.read}\n seenNow={touchCounts.seen}\n churn={churn}\n onSelectFile={selectFile}\n onOpenAgents={!mapOnly && trace ? openAgents : undefined}\n locked={exporting}\n />\n {city ? (\n <Dock\n panels={[\n {\n id: \"view\",\n icon: view === \"tree\" ? TreePine : Mountain,\n hint: `Scene view: ${view} — click to change, or press V`,\n section: \"scene\",\n presentation: \"pop\",\n render: () => (\n <ViewPanel view={view} onViewChange={setView} note={viewNote} locked={exporting} />\n )\n },\n {\n id: \"inspect\",\n icon: Crosshair,\n hint: \"Inspect the selected file\",\n section: \"session\",\n presentation: \"sheet\",\n render: () => (\n <Inspector\n file={selectedFile}\n touch={selectedFile ? playback.touchByPath.get(selectedFile.path) : undefined}\n history={selectedFile ? (playback.historyByPath.get(selectedFile.path) ?? []) : []}\n onClose={closeSheet}\n onJumpTo={jumpToHistory}\n locked={exporting}\n />\n )\n },\n ...(!mapOnly && trace\n ? [\n {\n id: \"agents\",\n icon: Users,\n hint: `Agent lenses — current: ${agentLabel}`,\n section: \"session\",\n presentation: \"sheet\",\n render: () => (\n <AgentsPanel\n graph={agentGraph}\n current={activeAgentID}\n loading={agentGraphLoading}\n loadingAgentID={loadingAgentID}\n locked={exporting}\n error={agentPanelError}\n retryAgentID={agentRetryID}\n onSelect={(agentID) => void selectAgent(agentID)}\n onRetry={retryAgents}\n onClose={closeSheet}\n />\n )\n } satisfies PanelDescriptor\n ]\n : []),\n ...(!mapOnly && trace\n ? [\n {\n id: \"evaluate\",\n icon: Sparkles,\n hint: evaluateHint(reportBadge),\n section: \"session\",\n presentation: \"sheet\",\n badge: reportBadge,\n render: () => (\n <ReportPanel\n status={reportStatus}\n analyzing={reportStatus?.state === \"running\"}\n locked={exporting}\n onAnalyze={(choice) => void analyzeSession(choice)}\n onClose={closeSheet}\n onJumpTo={jumpToEvidence}\n />\n )\n } satisfies PanelDescriptor\n ]\n : [])\n ]}\n openSheet={openSheet}\n openPop={openPop}\n onToggle={togglePanel}\n onClosePop={closePop}\n />\n ) : null}\n {!mapOnly && !loading && sessions.length === 0 ? (\n <div className=\"empty-stage\">\n <div className=\"card\">\n <h2>No sessions found</h2>\n <p>\n Synapse scans <code>~/.claude/projects</code>, <code>~/.codex/sessions</code>,{\" \"}\n <code>~/.pi/agent/sessions</code>, and <code>~/.gemini/antigravity-cli/brain</code> for agent traces. Run a session there, then refresh.\n </p>\n </div>\n </div>\n ) : null}\n {loading ? (\n <div className=\"toast\">{mapOnly ? \"Building the map…\" : sessions.length === 0 ? \"Scanning sessions…\" : \"Reading trace…\"}</div>\n ) : null}\n {error ? <div className=\"toast error\">{error}</div> : null}\n </div>\n <Timeline\n trace={trace}\n currentSeq={currentSeq}\n onChange={setCurrentSeq}\n onExport={recordingSupported() ? exportVideo : undefined}\n exporting={exporting}\n onSubagentMark={openAgentsAtMark}\n />\n </section>\n </main>\n );\n}\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport \"@fontsource-variable/fraunces/standard.css\";\nimport \"@fontsource-variable/fraunces/standard-italic.css\";\nimport \"@fontsource-variable/schibsted-grotesk\";\nimport App from \"./App\";\n\ncreateRoot(document.getElementById(\"root\")!).render(\n <StrictMode>\n <App />\n </StrictMode>\n);\n"],"names":["toKebabCase","string","toCamelCase","match","p1","p2","toPascalCase","camelCase","mergeClasses","classes","className","index","array","hasA11yProp","props","prop","defaultAttributes","Icon","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","children","iconNode","rest","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","__iconNode","Bot","Circle","Crosshair","Ellipsis","EyeOff","Eye","FolderOpen","Info","Loader","Mountain","PanelLeftClose","PanelLeftOpen","Pause","Play","RefreshCw","RotateCcw","Search","Sparkles","StepBack","StepForward","TreePine","TriangleAlert","Users","Video","X","getJSON","url","res","detail","describeError","err","doing","listSessions","fresh","getSessionSnapshot","key","getSessionAgents","rootKey","getAgentTrace","agentID","getSessionReport","startSessionAnalyze","choice","getRepoMap","repo","Dock","panels","openSheet","openPop","onToggle","onClosePop","popRef","useRef","stripRef","sheet","panel","pop","grouped","section","group","useEffect","onPointerDown","event","target","onKeyDown","jsxs","jsx","active","AgentsPanel","graph","current","loading","loadingAgentID","locked","error","retryAgentID","onSelect","onRetry","onClose","agent","main","graphError","setDetail","useState","detailAgent","closePanel","AgentError","rowError","Fragment","AgentRow","anchor","currentDetail","AgentDetailPopover","rowLocal","AlertTriangle","detailMode","onPreview","onPreviewEnd","onToggleDetails","available","status","agentStatus","secondary","disabled","state","popoverRef","position","setPosition","useLayoutEffect","updatePosition","width","anchorRect","leftCandidate","rightCandidate","left","maxHeight","measuredHeight","top","animatedPanel","handleKeyDown","handlePointerDown","createPortal","agentDetail","eventCount","count","DIMENSION_WORDS","JUDGE_MODELS","JUDGE_CHOICE_KEY","loadStoredChoice","raw","parsed","resolveChoice","clis","cli","model","m","ReportPanel","analyzing","onAnalyze","onJumpTo","storedChoice","setStoredChoice","changeChoice","useCallback","next","analyze","day","PanelBody","JudgePicker","onChange","models","e","picker","report","RubricSection","dimension","Dimension","moment","rubric","text","tasks","criteria","task","thin","criterion","showHint","multi","i","RubricTaskBlock","startSeq","Criterion","hint","verdictWord","finding","FindingButton","seq","severityClass","words","verdict","severity","iso","d","ViewPanel","view","onViewChange","note","touchRank","RECENT_WINDOW","PlaybackEngine","trace","city","file","lastSeq","prev","fileId","prevFile","history","primary","extensionForMime","mimeType","subtype","DEFAULT_FPS","MAX_DURATION_MS","PER_EVENT_MS","pickMimeType","candidates","type","recordingSupported","recordPlayback","opts","canvas","total","setSeq","onProgress","signal","fps","durationMs","stream","recorder","chunks","resolve","reject","rafId","startTs","settled","cleanup","track","onAbort","finish","actualType","fail","tick","ts","fraction","downloadBlob","blob","filename","touchWord","touch","fireflyMap","fireflyTexture","ctx","g","THREE.CanvasTexture","haloMap","haloTexture","labelTexture","font","measure","height","texture","LABEL_MIN_SUBTREE_PX","LABEL_BUDGET","DirLabelSet","THREE.Vector3","THREE.Quaternion","entries","y","alwaysOnTop","budget","a","b","entry","aspect","sprite","THREE.Sprite","THREE.SpriteMaterial","camera","viewW","viewH","tanV","THREE.MathUtils","maxDim","label","dist","pxPerWorld","subtreePx","sx","sy","ph","worldH","kept","candidate","clash","other","reduced","material","diff","SKY","THREE.Color","EMBER","touchColors","fitDistance","dir","points","forward","right","up","tanH","distance","point","depth","ensureVisible","controls","world","reservedRight","projected","safeL","safeR","safeT","safeB","targetX","targetY","pan","SceneTip","host","path","meta","clientX","clientY","bounds","x","prefersReducedMotion","disposeGroup","obj","THREE.Mesh","THREE.Line","mat","disposeMaterial","map","SAMPLES","MAX_ARCS","TrailRenderer","THREE.QuadraticBezierCurve3","lift","vertexCount","geometry","THREE.BufferGeometry","THREE.BufferAttribute","THREE.DynamicDrawUsage","THREE.LineBasicMaterial","THREE.AdditiveBlending","THREE.LineSegments","arcs","start","v","s","recency","pa","pb","colors","TILE_H","LABEL_Y","INSPECTOR_RESERVED_PX","attentionHeight","visits","LOC_MIN_H","LOC_MAX_H","LOC_HEIGHT_GAMMA","locFraction","lines","maxLog","locHeight","t","LOC_RAMP","locColor","lo","hi","span","k","CityScene","playback","selectedPath","onCanvasReady","locHeights","hostRef","tileMeshRef","terrainMeshRef","filesRef","slotsRef","heightsRef","rendererRef","cameraRef","controlsRef","sceneRef","cityGroupRef","trailRef","fireflyRef","labelSetRef","frameRef","reducedRef","boundsRef","playbackRef","fitPendingRef","useMemo","minX","maxX","minZ","maxZ","scene","THREE.Scene","THREE.PerspectiveCamera","renderer","THREE.WebGLRenderer","OrbitControls","tip","sky","THREE.HemisphereLight","moon","THREE.DirectionalLight","raycaster","THREE.Raycaster","pointer","THREE.Vector2","pickFile","rect","targets","hit","slot","downAt","onPointerUp","moved","hoverRaf","onPointerMove","snapshot","onPointerLeave","resize","w","h","observer","clock","THREE.Clock","matrix","THREE.Matrix4","quaternion","render","terrain","slots","heights","moving","cur","sz","firefly","base","pulse","THREE.Group","THREE.Fog","ground","THREE.PlaneGeometry","THREE.MeshStandardMaterial","grid","THREE.GridHelper","plateDirs","plateGeo","THREE.BoxGeometry","plateMat","plates","THREE.InstancedMesh","shade","tileGeo","tileMat","tiles","z","baseColor","attentionColumnGeometry","THREE.MeshBasicMaterial","THREE.InstancedBufferAttribute","dirBasename","trail","fitView","corners","fitted","present","f","selected","centerFor","targetFiles","peakFor","head","p","geo","pos","normal","glow","jitter","computeTreeLayout","files","root","sorted","parts","node","part","maxDepth","countLeaves","child","radius","step","slotAngle","layout","polar","r","angle","sampleEdge","r1","a1","r2","a2","from","delta","SEGMENTS","ease","cursor","place","dirs","nodeByPath","collect","parentPath","parent","dirByPath","EDGE_BASE","EDGE_LIT","FIREFLY_HOT","LEAF_Y","haloRadius","TreeScene","leafMeshRef","ghostMeshRef","ghostIndexRef","selectionRef","haloMeshRef","edgesRef","edgeMetaRef","layoutRef","radiiRef","groupRef","PICK_RADIUS","treeLayout","px","py","best","bestD2","d2","THREE.Euler","halos","radii","positions","edgeMeta","edge","edgeGeo","THREE.Float32BufferAttribute","edgeColors","edges","leafGeo","THREE.SphereGeometry","leafMat","leaves","ghostFiles","ghostIndex","hidden","scale","ghosts","selectionMat","THREE.DoubleSide","ring","THREE.RingGeometry","beam","THREE.CylinderGeometry","litDirs","leafColor","colorAttr","vertex","lit","tinted","selection","STORAGE_KEY","sessionVisible","session","filters","activeKey","loadFilters","saveFilters","createStoreImpl","createState","listeners","setState","partial","replace","nextState","previousState","listener","getState","api","initialState","createStore","identity","arg","useStore","selector","slice","React","createImpl","useBoundStore","create","initialFilters","RAIL_COLLAPSED_KEY","loadRailCollapsed","useAppStore","set","get","sessions","activeSessionKey","currentSeq","hideEmpty","harnessFilter","railCollapsed","CHURN_PANEL_ROWS","Hud","memo","agentLabel","editedNow","readNow","seenNow","churn","onSelectFile","onOpenAgents","stats","readFinal","unvisitedNow","unvisitedFinal","ghostCount","n","errorCount","countActions","showReview","churnOpen","setChurnOpen","churnPanelRef","churnToggleRef","basename","SpectrumStat","mixHint","fmtBytes","rereadHint","approx","pct","errorCaveat","open","verifyRuns","kind","now","final","rate","observability","ACTION_ORDER","counts","sum","bytes","kb","clean","Inspector","slash","name","LogoMark","isMac","toggleRailShortcut","SessionRail","collapsed","onRefresh","onHideEmptyChange","onHarnessFilterChange","onCollapse","onOpenMap","activeRepo","activeReportState","query","setQuery","repoPath","setRepoPath","mapOpen","setMapOpen","mapPopRef","harnesses","emptyCount","effectiveHarness","shown","q","repoBasename","harness","harnessLabel","shortDate","evalState","evalHint","sameYear","md","hm","BUCKETS","BASE_TICK_MS","SPEEDS","MARK_SLOTS","MARK_LABEL","STRIP_ACTIONS","Timeline","onSubagentMark","onExport","exporting","playing","setPlaying","speed","setSpeed","menuOpen","setMenuOpen","menuRef","max","seqRef","maxRef","playingRef","interval","timer","togglePlay","cycleSpeed","jumpEvent","pred","markSeqs","clamped","mark","jumpMark","ev","onDown","onKey","buckets","out","to","byAction","action","dominant","priority","peak","acc","markGroups","groups","seqC","bucket","evaluateHint","badge","MAIN_ACTOR_KEY","App","mapOnly","setView","setSessions","setActiveSession","setData","setCityOnly","setCurrentSeq","setSelectedPath","setLoading","setError","setHideEmpty","setHarnessFilter","setRailCollapsed","urlSessionConsumed","scanGeneration","loadGeneration","lensGeneration","agentGraphRequest","agentTraceRequest","manualRefreshInFlight","pendingLoads","activeSessionKeyRef","canvasRef","setExporting","setOpenSheet","setOpenPop","reportStatus","setReportStatus","agentGraph","setAgentGraph","activeAgentID","setActiveAgentID","agentGraphLoading","setAgentGraphLoading","setLoadingAgentID","agentPanelError","setAgentPanelError","agentRetryID","setAgentRetryID","activeAgentIDRef","pendingAgentIDRef","rootTraceRef","rootCityRef","actorTraceCache","actorPlayheads","exportingRef","handleCanvasReady","beginLoading","endLoading","resetLens","generation","loadAgentGraph","request","loadSession","currentLensGeneration","nextTrace","nextCity","activeChildID","remembered","childTrace","invalidateActorTracesForRescan","activeActorID","rootTrace","rootCity","scan","data","preferred","exact","legacyMatches","fromUrl","currentActiveKey","stillListed","fallback","lens","loadRepoMap","openMap","selectSession","saveActivePlayhead","showCachedActor","selectAgent","cachedTrace","retryAgents","exportVideo","exportSessionKey","exportActorID","resumeSeq","extension","collapseRail","expandRail","refreshReport","refreshSessionList","refresh","anyEvaluating","analyzeSession","selectFile","closeSheet","closePop","openAgents","togglePanel","jumpToEvidence","openAgentsAtMark","jumpToHistory","store","params","reportBadge","viewNote","engine","touchCounts","edited","read","seen","selectedFile","edits","createRoot","StrictMode"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,45,46]}