@cosmicstack/mercury-agent 1.1.9 → 1.1.12
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.
- package/README.md +101 -1
- package/README.zh-CN.md +265 -140
- package/dist/index.js +4473 -1842
- package/dist/index.js.map +1 -1
- package/dist/web/ui/assets/{Chat-DCFkzIwn.js → Chat-DXSn2dY8.js} +2 -2
- package/dist/web/ui/assets/{Chat-DCFkzIwn.js.map → Chat-DXSn2dY8.js.map} +1 -1
- package/dist/web/ui/assets/{Dashboard-B81ollv8.js → Dashboard-1rlAqQ-Y.js} +2 -2
- package/dist/web/ui/assets/{Dashboard-B81ollv8.js.map → Dashboard-1rlAqQ-Y.js.map} +1 -1
- package/dist/web/ui/assets/{Goals-D0cR8yIP.js → Goals-CgSUAXLH.js} +2 -2
- package/dist/web/ui/assets/{Goals-D0cR8yIP.js.map → Goals-CgSUAXLH.js.map} +1 -1
- package/dist/web/ui/assets/{Graph-C3eHp3_J.js → Graph-DnlOWkay.js} +2 -2
- package/dist/web/ui/assets/{Graph-C3eHp3_J.js.map → Graph-DnlOWkay.js.map} +1 -1
- package/dist/web/ui/assets/{Kanban-DrkTRyni.js → Kanban-DRlNiNRF.js} +2 -2
- package/dist/web/ui/assets/{Kanban-DrkTRyni.js.map → Kanban-DRlNiNRF.js.map} +1 -1
- package/dist/web/ui/assets/{Login-GRQ-LjgN.js → Login-BP5524pC.js} +2 -2
- package/dist/web/ui/assets/{Login-GRQ-LjgN.js.map → Login-BP5524pC.js.map} +1 -1
- package/dist/web/ui/assets/{MarkdownRenderer-Dvh1jwyj.js → MarkdownRenderer-B9KGVD0X.js} +2 -2
- package/dist/web/ui/assets/{MarkdownRenderer-Dvh1jwyj.js.map → MarkdownRenderer-B9KGVD0X.js.map} +1 -1
- package/dist/web/ui/assets/{Memory-dAZsKmWz.js → Memory-BOQEY0H8.js} +2 -2
- package/dist/web/ui/assets/{Memory-dAZsKmWz.js.map → Memory-BOQEY0H8.js.map} +1 -1
- package/dist/web/ui/assets/{Permissions-DCiyUUfI.js → Permissions-jbFH-toa.js} +2 -2
- package/dist/web/ui/assets/{Permissions-DCiyUUfI.js.map → Permissions-jbFH-toa.js.map} +1 -1
- package/dist/web/ui/assets/{PersonDetail-iZgApJog.js → PersonDetail-Ca8B9io8.js} +2 -2
- package/dist/web/ui/assets/{PersonDetail-iZgApJog.js.map → PersonDetail-Ca8B9io8.js.map} +1 -1
- package/dist/web/ui/assets/{Persons-Bs_HhYjC.js → Persons-epdmUeBM.js} +2 -2
- package/dist/web/ui/assets/{Persons-Bs_HhYjC.js.map → Persons-epdmUeBM.js.map} +1 -1
- package/dist/web/ui/assets/{Providers-CL6wMWni.js → Providers-Bm8sZNZo.js} +2 -2
- package/dist/web/ui/assets/{Providers-CL6wMWni.js.map → Providers-Bm8sZNZo.js.map} +1 -1
- package/dist/web/ui/assets/{Schedules-BQwE1hP5.js → Schedules-BZKhm9R7.js} +2 -2
- package/dist/web/ui/assets/{Schedules-BQwE1hP5.js.map → Schedules-BZKhm9R7.js.map} +1 -1
- package/dist/web/ui/assets/{Settings-26SF-okR.js → Settings-Hii-5oku.js} +2 -2
- package/dist/web/ui/assets/{Settings-26SF-okR.js.map → Settings-Hii-5oku.js.map} +1 -1
- package/dist/web/ui/assets/Skills-BHJp2CgD.js +17 -0
- package/dist/web/ui/assets/Skills-BHJp2CgD.js.map +1 -0
- package/dist/web/ui/assets/{Tasks-DbwRozzx.js → Tasks-D36pqkro.js} +2 -2
- package/dist/web/ui/assets/{Tasks-DbwRozzx.js.map → Tasks-D36pqkro.js.map} +1 -1
- package/dist/web/ui/assets/{Usage-i_q6Ri4s.js → Usage-CmjaYrsT.js} +2 -2
- package/dist/web/ui/assets/{Usage-i_q6Ri4s.js.map → Usage-CmjaYrsT.js.map} +1 -1
- package/dist/web/ui/assets/{Workspace-ZR5syf-9.js → Workspace-BYLf-wTJ.js} +2 -2
- package/dist/web/ui/assets/{Workspace-ZR5syf-9.js.map → Workspace-BYLf-wTJ.js.map} +1 -1
- package/dist/web/ui/assets/{activity-CIP1IzSg.js → activity-MOTqH8zM.js} +2 -2
- package/dist/web/ui/assets/{activity-CIP1IzSg.js.map → activity-MOTqH8zM.js.map} +1 -1
- package/dist/web/ui/assets/{alert-dialog-CW-j2nG4.js → alert-dialog-MbYSbZx5.js} +2 -2
- package/dist/web/ui/assets/{alert-dialog-CW-j2nG4.js.map → alert-dialog-MbYSbZx5.js.map} +1 -1
- package/dist/web/ui/assets/{arrow-left-D2YO-iMS.js → arrow-left-CtqQsBC6.js} +2 -2
- package/dist/web/ui/assets/{arrow-left-D2YO-iMS.js.map → arrow-left-CtqQsBC6.js.map} +1 -1
- package/dist/web/ui/assets/{avatar-BLsf3GhK.js → avatar-BIYaY7pR.js} +2 -2
- package/dist/web/ui/assets/{avatar-BLsf3GhK.js.map → avatar-BIYaY7pR.js.map} +1 -1
- package/dist/web/ui/assets/{badge-DfDJNUtd.js → badge-CUJiWF1y.js} +2 -2
- package/dist/web/ui/assets/{badge-DfDJNUtd.js.map → badge-CUJiWF1y.js.map} +1 -1
- package/dist/web/ui/assets/{button-TaFPR-zy.js → button-CNasMlFE.js} +2 -2
- package/dist/web/ui/assets/{button-TaFPR-zy.js.map → button-CNasMlFE.js.map} +1 -1
- package/dist/web/ui/assets/{card-DAYo4Zl5.js → card-BdsEOP7t.js} +2 -2
- package/dist/web/ui/assets/{card-DAYo4Zl5.js.map → card-BdsEOP7t.js.map} +1 -1
- package/dist/web/ui/assets/{chevron-down-CQi0yuay.js → chevron-down-CB9J_vvZ.js} +2 -2
- package/dist/web/ui/assets/{chevron-down-CQi0yuay.js.map → chevron-down-CB9J_vvZ.js.map} +1 -1
- package/dist/web/ui/assets/{circle-check-DweDcOkA.js → circle-check-DvGSe1uZ.js} +2 -2
- package/dist/web/ui/assets/{circle-check-DweDcOkA.js.map → circle-check-DvGSe1uZ.js.map} +1 -1
- package/dist/web/ui/assets/{circle-x-BmL20etA.js → circle-x-CyaGJ_BM.js} +2 -2
- package/dist/web/ui/assets/{circle-x-BmL20etA.js.map → circle-x-CyaGJ_BM.js.map} +1 -1
- package/dist/web/ui/assets/{dialog-DovgkMhT.js → dialog-Bd1rELXb.js} +2 -2
- package/dist/web/ui/assets/{dialog-DovgkMhT.js.map → dialog-Bd1rELXb.js.map} +1 -1
- package/dist/web/ui/assets/{download-_QBatDio.js → download-C8RvlFqO.js} +2 -2
- package/dist/web/ui/assets/{download-_QBatDio.js.map → download-C8RvlFqO.js.map} +1 -1
- package/dist/web/ui/assets/{eye-Wpgtfmgw.js → eye-BJ0NucMz.js} +2 -2
- package/dist/web/ui/assets/{eye-Wpgtfmgw.js.map → eye-BJ0NucMz.js.map} +1 -1
- package/dist/web/ui/assets/{file-text-2EGFNyc1.js → file-text-BWWBuD_N.js} +2 -2
- package/dist/web/ui/assets/{file-text-2EGFNyc1.js.map → file-text-BWWBuD_N.js.map} +1 -1
- package/dist/web/ui/assets/{folder-open-C-OiZn9P.js → folder-open-BwjemFy7.js} +2 -2
- package/dist/web/ui/assets/{folder-open-C-OiZn9P.js.map → folder-open-BwjemFy7.js.map} +1 -1
- package/dist/web/ui/assets/{git-branch-BT9gCKgG.js → git-branch-D9JVASpC.js} +2 -2
- package/dist/web/ui/assets/{git-branch-BT9gCKgG.js.map → git-branch-D9JVASpC.js.map} +1 -1
- package/dist/web/ui/assets/{index-BhxU0YlT.js → index-C3YiF4qv.js} +6 -6
- package/dist/web/ui/assets/index-C3YiF4qv.js.map +1 -0
- package/dist/web/ui/assets/{index-CUT6Fr2C.js → index-CaqLZNof.js} +2 -2
- package/dist/web/ui/assets/{index-CUT6Fr2C.js.map → index-CaqLZNof.js.map} +1 -1
- package/dist/web/ui/assets/index-CuhiuVab.css +1 -0
- package/dist/web/ui/assets/{input-L1uz5xAQ.js → input-CH3dmo9r.js} +2 -2
- package/dist/web/ui/assets/{input-L1uz5xAQ.js.map → input-CH3dmo9r.js.map} +1 -1
- package/dist/web/ui/assets/{loader-circle-BTFgt3hG.js → loader-circle-DbYKk0_Q.js} +2 -2
- package/dist/web/ui/assets/{loader-circle-BTFgt3hG.js.map → loader-circle-DbYKk0_Q.js.map} +1 -1
- package/dist/web/ui/assets/{pencil-uxK07iYy.js → pencil-gNDEMhav.js} +2 -2
- package/dist/web/ui/assets/{pencil-uxK07iYy.js.map → pencil-gNDEMhav.js.map} +1 -1
- package/dist/web/ui/assets/{plus-DcWFYr4m.js → plus-7rbHkByr.js} +2 -2
- package/dist/web/ui/assets/{plus-DcWFYr4m.js.map → plus-7rbHkByr.js.map} +1 -1
- package/dist/web/ui/assets/{power-DVIqVIMj.js → power-BS7gCDWs.js} +2 -2
- package/dist/web/ui/assets/{power-DVIqVIMj.js.map → power-BS7gCDWs.js.map} +1 -1
- package/dist/web/ui/assets/{progress-DMwOdxli.js → progress-ZzhsBV2v.js} +2 -2
- package/dist/web/ui/assets/{progress-DMwOdxli.js.map → progress-ZzhsBV2v.js.map} +1 -1
- package/dist/web/ui/assets/{search-D1OOxb1X.js → search-BZsbhO0B.js} +2 -2
- package/dist/web/ui/assets/{search-D1OOxb1X.js.map → search-BZsbhO0B.js.map} +1 -1
- package/dist/web/ui/assets/{select-Dnx_bUgy.js → select-vRSgBrHz.js} +2 -2
- package/dist/web/ui/assets/{select-Dnx_bUgy.js.map → select-vRSgBrHz.js.map} +1 -1
- package/dist/web/ui/assets/{send-D4uxqmyH.js → send-BkyTIUtJ.js} +2 -2
- package/dist/web/ui/assets/{send-D4uxqmyH.js.map → send-BkyTIUtJ.js.map} +1 -1
- package/dist/web/ui/assets/{sparkles-DLSJA4xU.js → sparkles-DcP24GEL.js} +2 -2
- package/dist/web/ui/assets/{sparkles-DLSJA4xU.js.map → sparkles-DcP24GEL.js.map} +1 -1
- package/dist/web/ui/assets/{switch-CvDDbCUA.js → switch-LRN9wWy2.js} +2 -2
- package/dist/web/ui/assets/{switch-CvDDbCUA.js.map → switch-LRN9wWy2.js.map} +1 -1
- package/dist/web/ui/assets/{terminal-DI3J3W_z.js → terminal-CWG62zdD.js} +2 -2
- package/dist/web/ui/assets/{terminal-DI3J3W_z.js.map → terminal-CWG62zdD.js.map} +1 -1
- package/dist/web/ui/assets/{textarea-CXLsr8tf.js → textarea-CXh3tmJ1.js} +2 -2
- package/dist/web/ui/assets/{textarea-CXLsr8tf.js.map → textarea-CXh3tmJ1.js.map} +1 -1
- package/dist/web/ui/assets/{zap-C-0oH5gt.js → zap-BEfqVtvZ.js} +2 -2
- package/dist/web/ui/assets/{zap-C-0oH5gt.js.map → zap-BEfqVtvZ.js.map} +1 -1
- package/dist/web/ui/index.html +2 -2
- package/package.json +9 -4
- package/dist/web/ui/assets/Skills-DANyYK_d.js +0 -7
- package/dist/web/ui/assets/Skills-DANyYK_d.js.map +0 -1
- package/dist/web/ui/assets/index-BhxU0YlT.js.map +0 -1
- package/dist/web/ui/assets/index-DOw1nKre.css +0 -1
- package/dist/web/ui/sw.js.map +0 -1
- package/dist/web/ui/workbox-0bb07689.js +0 -3
- package/dist/web/ui/workbox-0bb07689.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Graph-C3eHp3_J.js","sources":["../../node_modules/lucide-react/dist/esm/icons/network.js","../../src/pages/brain/Graph.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.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: \"16\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"4q2zg0\" }],\n [\"rect\", { x: \"2\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"8cvhb9\" }],\n [\"rect\", { x: \"9\", y: \"2\", width: \"6\", height: \"6\", rx: \"1\", key: \"1egb70\" }],\n [\"path\", { d: \"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3\", key: \"1jsf9p\" }],\n [\"path\", { d: \"M12 12V8\", key: \"2874zd\" }]\n];\nconst Network = createLucideIcon(\"network\", __iconNode);\n\nexport { __iconNode, Network as default };\n//# sourceMappingURL=network.js.map\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport { Network, Search, Loader2 } from \"lucide-react\";\nimport api, { type GraphNode, type GraphEdge, type Memory } from \"@/lib/api\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"@/components/ui/dialog\";\n\n// ── Node type color map ──\nconst TYPE_COLORS: Record<string, string> = {\n fact: \"#3b82f6\",\n preference: \"#a78bfa\",\n experience: \"#22c55e\",\n goal: \"#f59e0b\",\n project: \"#00d4ff\",\n person: \"#ec4899\",\n skill: \"#6366f1\",\n belief: \"#f97316\",\n observation: \"#14b8a6\",\n default: \"#6b7280\",\n};\n\nfunction getTypeColor(type: string): string {\n return TYPE_COLORS[type] || TYPE_COLORS.default;\n}\n\n// ── Internal layout types ──\ninterface NodePos {\n x: number;\n y: number;\n}\n\ninterface NodeVelocity {\n seed: number;\n freq: number;\n amp: number;\n}\n\ninterface TooltipInfo {\n x: number;\n y: number;\n node: GraphNode;\n connections: number;\n}\n\nfunction isDarkMode(): boolean {\n return (\n document.documentElement.classList.contains(\"dark\") ||\n document.documentElement.getAttribute(\"data-theme\") !== \"light\"\n );\n}\n\nexport function GraphPage() {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const [loading, setLoading] = useState(true);\n const [nodes, setNodes] = useState<GraphNode[]>([]);\n const [edges, setEdges] = useState<GraphEdge[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [tooltip, setTooltip] = useState<TooltipInfo | null>(null);\n\n // Detail dialog state — opens on single-click of a node.\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailNode, setDetailNode] = useState<GraphNode | null>(null);\n const [detailMemory, setDetailMemory] = useState<Memory | null>(null);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailError, setDetailError] = useState<string | null>(null);\n\n // Mutable refs for canvas state (avoid re-renders during animation)\n const stateRef = useRef({\n nodes: [] as GraphNode[],\n edges: [] as GraphEdge[],\n positions: new Map<string, NodePos>(),\n anchors: new Map<string, NodePos>(),\n velocities: new Map<string, NodeVelocity>(),\n pan: { x: 0, y: 0 },\n zoom: 1,\n dragging: false,\n dragNode: null as GraphNode | null,\n hoveredNode: null as GraphNode | null,\n selectedNode: null as GraphNode | null,\n lastMouse: { x: 0, y: 0 },\n // Press tracking — used to distinguish a click from a drag.\n pressNode: null as GraphNode | null,\n pressX: 0,\n pressY: 0,\n pressT: 0,\n moved: false,\n searchQuery: \"\",\n animFrame: 0,\n dpr: 1,\n });\n\n // Keep searchQuery in sync with ref\n useEffect(() => {\n stateRef.current.searchQuery = searchQuery;\n }, [searchQuery]);\n\n // ── Connection count helper ──\n const connectionCount = useCallback((nodeId: string, edgeList: GraphEdge[]) => {\n let count = 0;\n for (const e of edgeList) {\n if (e.source === nodeId || e.target === nodeId) count++;\n }\n return count;\n }, []);\n\n // ── Init positions in a circle ──\n const initPositions = useCallback(\n (nodeList: GraphNode[], canvasW: number, canvasH: number) => {\n const s = stateRef.current;\n const cx = canvasW / 2;\n const cy = canvasH / 2;\n s.positions.clear();\n s.anchors.clear();\n s.velocities.clear();\n\n nodeList.forEach((node, i) => {\n const angle = (i / nodeList.length) * Math.PI * 2;\n const r = 150 + Math.random() * 100;\n const x = cx + r * Math.cos(angle);\n const y = cy + r * Math.sin(angle);\n s.positions.set(node.id, { x, y });\n s.anchors.set(node.id, { x, y });\n s.velocities.set(node.id, {\n seed: Math.random(),\n freq: 0.00009 + Math.random() * 0.00007,\n amp: 0.25 + Math.random() * 0.25,\n });\n });\n },\n []\n );\n\n // ── Force-directed layout (80 iterations) ──\n const runLayout = useCallback(\n (nodeList: GraphNode[], edgeList: GraphEdge[], w: number, h: number) => {\n const s = stateRef.current;\n const iters = 80;\n\n for (let iter = 0; iter < iters; iter++) {\n const area = w * h;\n const k = Math.sqrt(area / Math.max(1, nodeList.length));\n const repForce = k * k;\n const attForce = 0.01;\n const forces = new Map<string, { fx: number; fy: number }>();\n nodeList.forEach((n) => forces.set(n.id, { fx: 0, fy: 0 }));\n\n // Repulsion (Coulomb)\n for (let i = 0; i < nodeList.length; i++) {\n for (let j = i + 1; j < nodeList.length; j++) {\n const pi = s.positions.get(nodeList[i].id);\n const pj = s.positions.get(nodeList[j].id);\n if (!pi || !pj) continue;\n const dx = pi.x - pj.x;\n const dy = pi.y - pj.y;\n const dist = Math.max(Math.sqrt(dx * dx + dy * dy), 1);\n const f = repForce / (dist * dist);\n const fx = (dx / dist) * f;\n const fy = (dy / dist) * f;\n forces.get(nodeList[i].id)!.fx += fx;\n forces.get(nodeList[i].id)!.fy += fy;\n forces.get(nodeList[j].id)!.fx -= fx;\n forces.get(nodeList[j].id)!.fy -= fy;\n }\n }\n\n // Attraction (Hooke) along edges\n edgeList.forEach((e) => {\n const ps = s.positions.get(e.source);\n const pt = s.positions.get(e.target);\n if (!ps || !pt) return;\n const dx = pt.x - ps.x;\n const dy = pt.y - ps.y;\n const fs = forces.get(e.source);\n const ft = forces.get(e.target);\n if (fs) {\n fs.fx += dx * attForce;\n fs.fy += dy * attForce;\n }\n if (ft) {\n ft.fx -= dx * attForce;\n ft.fy -= dy * attForce;\n }\n });\n\n // Center gravity\n const cx = w / 2;\n const cy = h / 2;\n const gravity = 0.001;\n nodeList.forEach((n) => {\n const p = s.positions.get(n.id);\n const f = forces.get(n.id);\n if (!p || !f) return;\n f.fx += (cx - p.x) * gravity;\n f.fy += (cy - p.y) * gravity;\n });\n\n // Apply with damping\n const damp = 0.1;\n nodeList.forEach((n) => {\n const f = forces.get(n.id);\n const p = s.positions.get(n.id);\n if (!f || !p) return;\n p.x += f.fx * damp;\n p.y += f.fy * damp;\n });\n }\n\n // Sync anchors\n nodeList.forEach((n) => {\n const p = s.positions.get(n.id);\n const a = s.anchors.get(n.id);\n if (p && a) {\n a.x = p.x;\n a.y = p.y;\n }\n });\n },\n []\n );\n\n // ── Resize canvas with DPR ──\n const resizeCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n const container = containerRef.current;\n if (!canvas || !container) return;\n\n const dpr = window.devicePixelRatio || 1;\n stateRef.current.dpr = dpr;\n const w = container.clientWidth;\n const h = container.clientHeight;\n canvas.width = w * dpr;\n canvas.height = h * dpr;\n canvas.style.width = `${w}px`;\n canvas.style.height = `${h}px`;\n }, []);\n\n // ── Screen → graph coordinate transform ──\n const screenToGraph = useCallback(\n (sx: number, sy: number): { x: number; y: number } => {\n const s = stateRef.current;\n const dpr = s.dpr;\n return {\n x: (sx * dpr - s.pan.x) / s.zoom,\n y: (sy * dpr - s.pan.y) / s.zoom,\n };\n },\n []\n );\n\n // ── Hit test ──\n const findNodeAt = useCallback(\n (gx: number, gy: number): GraphNode | null => {\n const s = stateRef.current;\n for (let i = s.nodes.length - 1; i >= 0; i--) {\n const n = s.nodes[i];\n const p = s.positions.get(n.id);\n if (!p) continue;\n const r = (n.size || 8) * 1.5;\n const dx = gx - p.x;\n const dy = gy - p.y;\n if (dx * dx + dy * dy < r * r) return n;\n }\n return null;\n },\n []\n );\n\n // ── Draw ──\n const draw = useCallback((ts: number) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n const s = stateRef.current;\n const dpr = s.dpr;\n const w = canvas.width;\n const h = canvas.height;\n const dark = isDarkMode();\n\n ctx.clearRect(0, 0, w, h);\n\n // Background\n ctx.fillStyle = dark ? \"#0a0e14\" : \"#ffffff\";\n ctx.fillRect(0, 0, w, h);\n\n ctx.save();\n ctx.translate(s.pan.x, s.pan.y);\n ctx.scale(s.zoom, s.zoom);\n\n // Focus neighborhood\n const focus = s.hoveredNode || s.selectedNode;\n const neighbors = new Set<string>();\n const activeEdgeIdx = new Set<number>();\n if (focus) {\n s.edges.forEach((e, i) => {\n if (e.source === focus.id) {\n neighbors.add(e.target);\n activeEdgeIdx.add(i);\n }\n if (e.target === focus.id) {\n neighbors.add(e.source);\n activeEdgeIdx.add(i);\n }\n });\n neighbors.add(focus.id);\n }\n\n // ── Edges ──\n s.edges.forEach((e, i) => {\n const ps = s.positions.get(e.source);\n const pt = s.positions.get(e.target);\n if (!ps || !pt) return;\n\n const active = activeEdgeIdx.has(i);\n if (active) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.7)\"\n : \"rgba(0,136,170,0.6)\";\n ctx.lineWidth = (2 * dpr) / s.zoom;\n } else if (focus) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.06)\"\n : \"rgba(0,136,170,0.05)\";\n ctx.lineWidth = (0.6 * dpr) / s.zoom;\n } else {\n const pulse = (Math.sin(ts * 0.00022 + i * 1.3) + 1) * 0.5;\n const alpha = (dark ? 0.16 : 0.13) + pulse * 0.06;\n ctx.strokeStyle = dark\n ? `rgba(0,212,255,${alpha.toFixed(3)})`\n : `rgba(0,136,170,${alpha.toFixed(3)})`;\n ctx.lineWidth = ((0.7 + pulse * 0.3) * dpr) / s.zoom;\n }\n\n ctx.beginPath();\n ctx.moveTo(ps.x, ps.y);\n ctx.lineTo(pt.x, pt.y);\n ctx.stroke();\n });\n\n // ── Nodes ──\n const searchQ = s.searchQuery.toLowerCase();\n\n s.nodes.forEach((n) => {\n const p = s.positions.get(n.id);\n if (!p) return;\n\n const isHovered = s.hoveredNode?.id === n.id;\n const isSelected = s.selectedNode?.id === n.id;\n const isNeighbor = neighbors.has(n.id);\n\n const v = s.velocities.get(n.id);\n const breathe =\n 1 + Math.sin(ts * 0.00035 + (v?.seed ?? 0) * 11.7) * 0.01;\n const baseR = (n.size || 8) * dpr;\n const r = baseR * (isHovered || isSelected ? 1.4 : breathe);\n\n // Alpha based on search / focus\n let alpha = 1;\n if (searchQ) {\n const hay = (n.fullLabel || n.label).toLowerCase();\n alpha = hay.includes(searchQ) ? 1 : 0.12;\n } else if (focus) {\n alpha = isHovered || isSelected || isNeighbor ? 1 : 0.18;\n }\n ctx.globalAlpha = alpha;\n\n // Glow\n if (isHovered || isSelected) {\n ctx.beginPath();\n ctx.arc(p.x, p.y, r + (5 * dpr) / s.zoom, 0, Math.PI * 2);\n ctx.fillStyle = dark\n ? \"rgba(0,212,255,0.14)\"\n : \"rgba(0,136,170,0.12)\";\n ctx.fill();\n }\n\n // Node circle\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.fillStyle = getTypeColor(n.type);\n ctx.fill();\n\n // Stroke\n if (isHovered || isSelected) {\n ctx.strokeStyle = dark ? \"#f0f0f0\" : \"#1a1a1a\";\n ctx.lineWidth = (2 * dpr) / s.zoom;\n ctx.stroke();\n } else if (isNeighbor && focus) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.65)\"\n : \"rgba(0,136,170,0.55)\";\n ctx.lineWidth = (1.8 * dpr) / s.zoom;\n ctx.stroke();\n }\n\n // Label — only for hovered / selected node. Keep it short (truncated `label`)\n // since the full text is shown in the tooltip / detail dialog instead.\n // This keeps the canvas clean and readable.\n if (isHovered || isSelected) {\n const fontSize = Math.max(10 * dpr, (11 * dpr) / s.zoom);\n ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n\n // Background pill for legibility\n const text = n.label;\n const metrics = ctx.measureText(text);\n const padX = 6 * dpr;\n const padY = 3 * dpr;\n const bx = p.x - metrics.width / 2 - padX;\n const by = p.y + r + 4 * dpr;\n const bw = metrics.width + padX * 2;\n const bh = fontSize + padY * 2;\n ctx.fillStyle = dark ? \"rgba(10,14,20,0.92)\" : \"rgba(255,255,255,0.95)\";\n ctx.beginPath();\n ctx.roundRect?.(bx, by, bw, bh, 4 * dpr);\n ctx.fill();\n\n ctx.fillStyle = dark\n ? `rgba(240,240,240,${alpha})`\n : `rgba(20,20,20,${alpha})`;\n ctx.fillText(text, p.x, by + padY);\n }\n\n ctx.globalAlpha = 1;\n });\n\n ctx.restore();\n }, []);\n\n // ── Motion update (breathing drift) ──\n const updateMotion = useCallback((ts: number) => {\n const s = stateRef.current;\n s.nodes.forEach((n) => {\n if (s.dragNode?.id === n.id) return;\n const p = s.positions.get(n.id);\n const a = s.anchors.get(n.id);\n const v = s.velocities.get(n.id);\n if (!p || !a || !v) return;\n p.x = a.x + Math.sin(ts * v.freq + v.seed * 11.1) * v.amp;\n p.y = a.y + Math.cos(ts * v.freq * 0.87 + v.seed * 17.3) * v.amp;\n });\n }, []);\n\n // ── Open detail dialog for a node (fetches full memory record) ──\n const openNodeDetail = useCallback(async (node: GraphNode) => {\n setDetailNode(node);\n setDetailMemory(null);\n setDetailError(null);\n setDetailOpen(true);\n setDetailLoading(true);\n stateRef.current.selectedNode = node;\n try {\n const mem = await api.brain.memory.get(node.id);\n setDetailMemory(mem);\n } catch (err) {\n // Not every node has a backing memory record (graph may include\n // person / goal aggregates) — fall back gracefully to node-only info.\n setDetailError(\n err instanceof Error ? err.message : \"Failed to load details\"\n );\n } finally {\n setDetailLoading(false);\n }\n }, []);\n\n // ── Mouse handlers ──\n const onMouseDown = useCallback(\n (e: MouseEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const sx = e.clientX - rect.left;\n const sy = e.clientY - rect.top;\n const gp = screenToGraph(sx, sy);\n const node = findNodeAt(gp.x, gp.y);\n const s = stateRef.current;\n\n s.pressNode = node;\n s.pressX = e.clientX;\n s.pressY = e.clientY;\n s.pressT = performance.now();\n s.moved = false;\n\n if (node) {\n s.dragNode = node;\n } else {\n s.dragging = true;\n }\n s.lastMouse = { x: e.clientX, y: e.clientY };\n },\n [screenToGraph, findNodeAt]\n );\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const sx = e.clientX - rect.left;\n const sy = e.clientY - rect.top;\n const s = stateRef.current;\n\n // Track whether the mouse has moved meaningfully since press.\n // 4px threshold lets micro-jitter still count as a click.\n if (s.pressT && !s.moved) {\n const ddx = e.clientX - s.pressX;\n const ddy = e.clientY - s.pressY;\n if (ddx * ddx + ddy * ddy > 16) s.moved = true;\n }\n\n if (s.dragNode) {\n const gp = screenToGraph(sx, sy);\n const p = s.positions.get(s.dragNode.id);\n const a = s.anchors.get(s.dragNode.id);\n if (p) {\n p.x = gp.x;\n p.y = gp.y;\n }\n if (a) {\n a.x = gp.x;\n a.y = gp.y;\n }\n } else if (s.dragging) {\n const dpr = s.dpr;\n s.pan.x += (e.clientX - s.lastMouse.x) * dpr;\n s.pan.y += (e.clientY - s.lastMouse.y) * dpr;\n } else {\n const gp = screenToGraph(sx, sy);\n const node = findNodeAt(gp.x, gp.y);\n if (node !== s.hoveredNode) {\n s.hoveredNode = node;\n if (node) {\n setTooltip({\n x: e.clientX - rect.left + 14,\n y: e.clientY - rect.top + 14,\n node,\n connections: connectionCount(node.id, s.edges),\n });\n } else {\n setTooltip(null);\n }\n } else if (node && tooltip) {\n setTooltip((prev) =>\n prev\n ? {\n ...prev,\n x: e.clientX - rect.left + 14,\n y: e.clientY - rect.top + 14,\n }\n : null\n );\n }\n }\n s.lastMouse = { x: e.clientX, y: e.clientY };\n },\n [screenToGraph, findNodeAt, connectionCount, tooltip]\n );\n\n const onMouseUp = useCallback(() => {\n const s = stateRef.current;\n const wasClick =\n !s.moved &&\n s.pressNode !== null &&\n performance.now() - s.pressT < 500;\n const clickedNode = s.pressNode;\n\n s.dragNode = null;\n s.dragging = false;\n s.pressNode = null;\n s.pressT = 0;\n s.moved = false;\n\n if (wasClick && clickedNode) {\n openNodeDetail(clickedNode);\n }\n }, [openNodeDetail]);\n\n const onWheel = useCallback(\n (e: WheelEvent) => {\n e.preventDefault();\n const s = stateRef.current;\n const delta = e.deltaY > 0 ? 0.92 : 1.08;\n const newZoom = Math.min(3.0, Math.max(0.3, s.zoom * delta));\n const scaleFactor = newZoom / s.zoom;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const mx = (e.clientX - rect.left) * s.dpr;\n const my = (e.clientY - rect.top) * s.dpr;\n\n s.pan.x = mx - (mx - s.pan.x) * scaleFactor;\n s.pan.y = my - (my - s.pan.y) * scaleFactor;\n s.zoom = newZoom;\n },\n []\n );\n\n // ── Main effect: fetch, layout, animate ──\n useEffect(() => {\n let cancelled = false;\n\n async function init() {\n setLoading(true);\n try {\n const data = await api.brain.graph();\n if (cancelled) return;\n const n = data.nodes || [];\n const e = data.edges || [];\n setNodes(n);\n setEdges(e);\n\n const s = stateRef.current;\n s.nodes = n;\n s.edges = e;\n\n resizeCanvas();\n const canvas = canvasRef.current;\n const cw = canvas ? canvas.width : 800;\n const ch = canvas ? canvas.height : 600;\n\n initPositions(n, cw, ch);\n runLayout(n, e, cw, ch);\n } catch (err) {\n console.error(\"Failed to load graph data:\", err);\n }\n if (!cancelled) setLoading(false);\n }\n\n init();\n return () => {\n cancelled = true;\n };\n }, [initPositions, runLayout, resizeCanvas]);\n\n // ── Animation loop + event listeners ──\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas || loading) return;\n\n resizeCanvas();\n\n // Animation loop\n let running = true;\n const loop = (ts: number) => {\n if (!running) return;\n updateMotion(ts);\n draw(ts);\n stateRef.current.animFrame = requestAnimationFrame(loop);\n };\n stateRef.current.animFrame = requestAnimationFrame(loop);\n\n // Event listeners\n canvas.addEventListener(\"mousedown\", onMouseDown);\n canvas.addEventListener(\"mousemove\", onMouseMove);\n canvas.addEventListener(\"mouseup\", onMouseUp);\n canvas.addEventListener(\"mouseleave\", onMouseUp);\n canvas.addEventListener(\"wheel\", onWheel, { passive: false });\n\n const handleResize = () => {\n resizeCanvas();\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n running = false;\n cancelAnimationFrame(stateRef.current.animFrame);\n canvas.removeEventListener(\"mousedown\", onMouseDown);\n canvas.removeEventListener(\"mousemove\", onMouseMove);\n canvas.removeEventListener(\"mouseup\", onMouseUp);\n canvas.removeEventListener(\"mouseleave\", onMouseUp);\n canvas.removeEventListener(\"wheel\", onWheel);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [\n loading,\n resizeCanvas,\n updateMotion,\n draw,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n onWheel,\n ]);\n\n // ── Legend entries ──\n const legendEntries = nodes.length\n ? [...new Set(nodes.map((n) => n.type))].sort()\n : [];\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border/50 bg-background/80 px-6 py-4 backdrop-blur-sm\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-[#00d4ff]/10\">\n <Network className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <h1 className=\"text-xl font-semibold tracking-tight text-foreground\">\n Knowledge Graph\n </h1>\n <p className=\"text-xs text-muted-foreground\">\n Visualize connections in Mercury's memory\n </p>\n </div>\n </div>\n </div>\n\n {/* Canvas area */}\n <div\n ref={containerRef}\n className=\"relative flex-1\"\n style={{ minHeight: 500 }}\n >\n {loading && (\n <div className=\"absolute inset-0 z-20 flex items-center justify-center bg-background/60 backdrop-blur-sm\">\n <div className=\"flex flex-col items-center gap-3\">\n <Loader2 className=\"h-8 w-8 animate-spin text-[#00d4ff]\" />\n <span className=\"text-sm text-muted-foreground\">\n Loading knowledge graph...\n </span>\n </div>\n </div>\n )}\n\n {!loading && nodes.length === 0 && (\n <div className=\"absolute inset-0 z-20 flex items-center justify-center\">\n <div className=\"flex flex-col items-center gap-3 text-center\">\n <Network className=\"h-12 w-12 text-muted-foreground/40\" />\n <p className=\"text-sm text-muted-foreground\">\n No knowledge graph data available yet\n </p>\n </div>\n </div>\n )}\n\n <canvas\n ref={canvasRef}\n className={`absolute inset-0 h-full w-full ${tooltip ? \"cursor-pointer\" : \"cursor-grab\"}`}\n />\n\n {/* Search overlay */}\n <div className=\"absolute right-4 top-4 z-10\">\n <div className=\"flex items-center gap-2 rounded-lg border border-border/60 bg-background/90 px-3 py-1.5 shadow-lg backdrop-blur-sm\">\n <Search className=\"h-4 w-4 text-muted-foreground\" />\n <input\n type=\"text\"\n placeholder=\"Search nodes...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-48 border-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground/60\"\n />\n </div>\n </div>\n\n {/* Legend overlay */}\n {legendEntries.length > 0 && (\n <div className=\"absolute bottom-4 left-4 z-10 rounded-lg border border-border/60 bg-background/90 px-3 py-2.5 shadow-lg backdrop-blur-sm\">\n <p className=\"mb-1.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n Node Types\n </p>\n <div className=\"flex flex-col gap-1\">\n {legendEntries.map((type) => (\n <div key={type} className=\"flex items-center gap-2\">\n <span\n className=\"inline-block h-2.5 w-2.5 rounded-full\"\n style={{ backgroundColor: getTypeColor(type) }}\n />\n <span className=\"text-[11px] capitalize text-foreground/80\">\n {type}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Tooltip */}\n {tooltip && (\n <div\n className=\"pointer-events-none absolute z-30 rounded-lg border border-border/60 bg-popover/95 px-3 py-2 shadow-xl backdrop-blur-sm\"\n style={{\n left: tooltip.x,\n top: tooltip.y,\n maxWidth: 320,\n // Flip horizontally near the right edge of the container so the\n // tooltip never gets clipped or pushes off-screen.\n transform:\n containerRef.current &&\n tooltip.x + 340 > containerRef.current.clientWidth\n ? \"translateX(calc(-100% - 28px))\"\n : undefined,\n }}\n >\n <p className=\"break-words text-sm font-medium leading-snug text-foreground\">\n {tooltip.node.fullLabel || tooltip.node.label}\n </p>\n <div className=\"mt-1 flex items-center gap-2\">\n <span\n className=\"inline-block h-2 w-2 rounded-full\"\n style={{ backgroundColor: getTypeColor(tooltip.node.type) }}\n />\n <span className=\"text-xs capitalize text-muted-foreground\">\n {tooltip.node.type}\n </span>\n <span className=\"text-xs text-muted-foreground/60\">·</span>\n <span className=\"text-xs text-muted-foreground\">\n {tooltip.connections} connection\n {tooltip.connections !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n <p className=\"mt-1.5 text-[10px] uppercase tracking-wider text-muted-foreground/70\">\n Click for details\n </p>\n </div>\n )}\n </div>\n\n {/* Node detail dialog */}\n <NodeDetailDialog\n open={detailOpen}\n onOpenChange={(v) => {\n setDetailOpen(v);\n if (!v) {\n stateRef.current.selectedNode = null;\n }\n }}\n node={detailNode}\n memory={detailMemory}\n loading={detailLoading}\n error={detailError}\n connections={\n detailNode ? connectionCount(detailNode.id, edges) : 0\n }\n />\n </div>\n );\n}\n\n// ── Detail dialog ──\ninterface NodeDetailDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n node: GraphNode | null;\n memory: Memory | null;\n loading: boolean;\n error: string | null;\n connections: number;\n}\n\nfunction formatTs(ts: string | number | undefined): string {\n if (!ts) return \"—\";\n const d = typeof ts === \"number\" ? new Date(ts) : new Date(ts);\n if (Number.isNaN(d.getTime())) return String(ts);\n return d.toLocaleString();\n}\n\nfunction NodeDetailDialog({\n open,\n onOpenChange,\n node,\n memory,\n loading,\n error,\n connections,\n}: NodeDetailDialogProps) {\n if (!node) return null;\n const color = getTypeColor(node.type);\n const fullLabel = node.fullLabel || node.label;\n const summary = memory?.summary || fullLabel;\n const detail = memory?.detail;\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <div className=\"flex items-center gap-2\">\n <span\n className=\"inline-block h-3 w-3 rounded-full\"\n style={{ backgroundColor: color }}\n />\n <span className=\"text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {node.type}\n </span>\n </div>\n <DialogTitle className=\"mt-1 break-words text-lg leading-snug\">\n {summary}\n </DialogTitle>\n </DialogHeader>\n\n {loading && (\n <div className=\"flex items-center gap-2 py-4 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Loading details…\n </div>\n )}\n\n {!loading && memory && (\n <div className=\"space-y-4\">\n {detail && (\n <div>\n <p className=\"mb-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n Detail\n </p>\n <p className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90\">\n {detail}\n </p>\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-3 text-xs sm:grid-cols-3\">\n {memory.scope && (\n <DetailField label=\"Scope\" value={memory.scope} />\n )}\n {typeof memory.importance === \"number\" && (\n <DetailField\n label=\"Importance\"\n value={memory.importance.toFixed(2)}\n />\n )}\n {typeof memory.confidence === \"number\" && (\n <DetailField\n label=\"Confidence\"\n value={memory.confidence.toFixed(2)}\n />\n )}\n {typeof memory.evidenceCount === \"number\" && (\n <DetailField\n label=\"Evidence\"\n value={String(memory.evidenceCount)}\n />\n )}\n <DetailField label=\"Connections\" value={String(connections)} />\n {memory.evidenceKind && (\n <DetailField label=\"Source\" value={memory.evidenceKind} />\n )}\n <DetailField label=\"Created\" value={formatTs(memory.createdAt)} />\n {memory.updatedAt && (\n <DetailField label=\"Updated\" value={formatTs(memory.updatedAt)} />\n )}\n {memory.lastSeenAt && (\n <DetailField\n label=\"Last seen\"\n value={formatTs(memory.lastSeenAt)}\n />\n )}\n </div>\n\n <div className=\"border-t border-border/40 pt-2\">\n <p className=\"font-mono text-[10px] text-muted-foreground/70\">\n {memory.id}\n </p>\n </div>\n </div>\n )}\n\n {!loading && !memory && (\n <div className=\"space-y-3\">\n <p className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90\">\n {fullLabel}\n </p>\n <div className=\"grid grid-cols-2 gap-3 text-xs\">\n <DetailField label=\"Type\" value={node.type} />\n <DetailField label=\"Connections\" value={String(connections)} />\n {typeof node.importance === \"number\" && (\n <DetailField\n label=\"Importance\"\n value={node.importance.toFixed(2)}\n />\n )}\n {typeof node.confidence === \"number\" && (\n <DetailField\n label=\"Confidence\"\n value={node.confidence.toFixed(2)}\n />\n )}\n </div>\n {error && (\n <p className=\"text-xs text-muted-foreground/70\">\n Could not load full record: {error}\n </p>\n )}\n <p className=\"font-mono text-[10px] text-muted-foreground/70\">\n {node.id}\n </p>\n </div>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction DetailField({ label, value }: { label: string; value: string }) {\n return (\n <div>\n <p className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {label}\n </p>\n <p className=\"mt-0.5 break-words text-foreground/90\">{value}</p>\n </div>\n );\n}\n"],"names":["__iconNode","Network","createLucideIcon","TYPE_COLORS","getTypeColor","type","isDarkMode","GraphPage","canvasRef","useRef","containerRef","loading","setLoading","useState","nodes","setNodes","edges","setEdges","searchQuery","setSearchQuery","tooltip","setTooltip","detailOpen","setDetailOpen","detailNode","setDetailNode","detailMemory","setDetailMemory","detailLoading","setDetailLoading","detailError","setDetailError","stateRef","useEffect","connectionCount","useCallback","nodeId","edgeList","count","e","initPositions","nodeList","canvasW","canvasH","s","cx","cy","node","i","angle","r","x","y","runLayout","w","h","iters","iter","area","k","repForce","attForce","forces","n","j","pi","pj","dx","dy","dist","f","fx","fy","ps","pt","fs","ft","gravity","p","damp","a","resizeCanvas","canvas","container","dpr","screenToGraph","sx","sy","findNodeAt","gx","gy","draw","ts","ctx","dark","focus","neighbors","activeEdgeIdx","pulse","alpha","searchQ","isHovered","_a","isSelected","_b","isNeighbor","v","breathe","fontSize","text","metrics","padX","padY","bx","by","bw","bh","_c","updateMotion","openNodeDetail","mem","api","err","onMouseDown","rect","gp","onMouseMove","ddx","ddy","prev","onMouseUp","wasClick","clickedNode","onWheel","delta","newZoom","scaleFactor","mx","my","cancelled","init","data","cw","ch","running","loop","handleResize","legendEntries","jsxs","jsx","Loader2","Search","NodeDetailDialog","formatTs","d","open","onOpenChange","memory","error","connections","color","fullLabel","summary","detail","Dialog","DialogContent","DialogHeader","DialogTitle","DetailField","label","value"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"Graph-DnlOWkay.js","sources":["../../node_modules/lucide-react/dist/esm/icons/network.js","../../src/pages/brain/Graph.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.511.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: \"16\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"4q2zg0\" }],\n [\"rect\", { x: \"2\", y: \"16\", width: \"6\", height: \"6\", rx: \"1\", key: \"8cvhb9\" }],\n [\"rect\", { x: \"9\", y: \"2\", width: \"6\", height: \"6\", rx: \"1\", key: \"1egb70\" }],\n [\"path\", { d: \"M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3\", key: \"1jsf9p\" }],\n [\"path\", { d: \"M12 12V8\", key: \"2874zd\" }]\n];\nconst Network = createLucideIcon(\"network\", __iconNode);\n\nexport { __iconNode, Network as default };\n//# sourceMappingURL=network.js.map\n","import { useEffect, useRef, useState, useCallback } from \"react\";\nimport { Network, Search, Loader2 } from \"lucide-react\";\nimport api, { type GraphNode, type GraphEdge, type Memory } from \"@/lib/api\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"@/components/ui/dialog\";\n\n// ── Node type color map ──\nconst TYPE_COLORS: Record<string, string> = {\n fact: \"#3b82f6\",\n preference: \"#a78bfa\",\n experience: \"#22c55e\",\n goal: \"#f59e0b\",\n project: \"#00d4ff\",\n person: \"#ec4899\",\n skill: \"#6366f1\",\n belief: \"#f97316\",\n observation: \"#14b8a6\",\n default: \"#6b7280\",\n};\n\nfunction getTypeColor(type: string): string {\n return TYPE_COLORS[type] || TYPE_COLORS.default;\n}\n\n// ── Internal layout types ──\ninterface NodePos {\n x: number;\n y: number;\n}\n\ninterface NodeVelocity {\n seed: number;\n freq: number;\n amp: number;\n}\n\ninterface TooltipInfo {\n x: number;\n y: number;\n node: GraphNode;\n connections: number;\n}\n\nfunction isDarkMode(): boolean {\n return (\n document.documentElement.classList.contains(\"dark\") ||\n document.documentElement.getAttribute(\"data-theme\") !== \"light\"\n );\n}\n\nexport function GraphPage() {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n const [loading, setLoading] = useState(true);\n const [nodes, setNodes] = useState<GraphNode[]>([]);\n const [edges, setEdges] = useState<GraphEdge[]>([]);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [tooltip, setTooltip] = useState<TooltipInfo | null>(null);\n\n // Detail dialog state — opens on single-click of a node.\n const [detailOpen, setDetailOpen] = useState(false);\n const [detailNode, setDetailNode] = useState<GraphNode | null>(null);\n const [detailMemory, setDetailMemory] = useState<Memory | null>(null);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailError, setDetailError] = useState<string | null>(null);\n\n // Mutable refs for canvas state (avoid re-renders during animation)\n const stateRef = useRef({\n nodes: [] as GraphNode[],\n edges: [] as GraphEdge[],\n positions: new Map<string, NodePos>(),\n anchors: new Map<string, NodePos>(),\n velocities: new Map<string, NodeVelocity>(),\n pan: { x: 0, y: 0 },\n zoom: 1,\n dragging: false,\n dragNode: null as GraphNode | null,\n hoveredNode: null as GraphNode | null,\n selectedNode: null as GraphNode | null,\n lastMouse: { x: 0, y: 0 },\n // Press tracking — used to distinguish a click from a drag.\n pressNode: null as GraphNode | null,\n pressX: 0,\n pressY: 0,\n pressT: 0,\n moved: false,\n searchQuery: \"\",\n animFrame: 0,\n dpr: 1,\n });\n\n // Keep searchQuery in sync with ref\n useEffect(() => {\n stateRef.current.searchQuery = searchQuery;\n }, [searchQuery]);\n\n // ── Connection count helper ──\n const connectionCount = useCallback((nodeId: string, edgeList: GraphEdge[]) => {\n let count = 0;\n for (const e of edgeList) {\n if (e.source === nodeId || e.target === nodeId) count++;\n }\n return count;\n }, []);\n\n // ── Init positions in a circle ──\n const initPositions = useCallback(\n (nodeList: GraphNode[], canvasW: number, canvasH: number) => {\n const s = stateRef.current;\n const cx = canvasW / 2;\n const cy = canvasH / 2;\n s.positions.clear();\n s.anchors.clear();\n s.velocities.clear();\n\n nodeList.forEach((node, i) => {\n const angle = (i / nodeList.length) * Math.PI * 2;\n const r = 150 + Math.random() * 100;\n const x = cx + r * Math.cos(angle);\n const y = cy + r * Math.sin(angle);\n s.positions.set(node.id, { x, y });\n s.anchors.set(node.id, { x, y });\n s.velocities.set(node.id, {\n seed: Math.random(),\n freq: 0.00009 + Math.random() * 0.00007,\n amp: 0.25 + Math.random() * 0.25,\n });\n });\n },\n []\n );\n\n // ── Force-directed layout (80 iterations) ──\n const runLayout = useCallback(\n (nodeList: GraphNode[], edgeList: GraphEdge[], w: number, h: number) => {\n const s = stateRef.current;\n const iters = 80;\n\n for (let iter = 0; iter < iters; iter++) {\n const area = w * h;\n const k = Math.sqrt(area / Math.max(1, nodeList.length));\n const repForce = k * k;\n const attForce = 0.01;\n const forces = new Map<string, { fx: number; fy: number }>();\n nodeList.forEach((n) => forces.set(n.id, { fx: 0, fy: 0 }));\n\n // Repulsion (Coulomb)\n for (let i = 0; i < nodeList.length; i++) {\n for (let j = i + 1; j < nodeList.length; j++) {\n const pi = s.positions.get(nodeList[i].id);\n const pj = s.positions.get(nodeList[j].id);\n if (!pi || !pj) continue;\n const dx = pi.x - pj.x;\n const dy = pi.y - pj.y;\n const dist = Math.max(Math.sqrt(dx * dx + dy * dy), 1);\n const f = repForce / (dist * dist);\n const fx = (dx / dist) * f;\n const fy = (dy / dist) * f;\n forces.get(nodeList[i].id)!.fx += fx;\n forces.get(nodeList[i].id)!.fy += fy;\n forces.get(nodeList[j].id)!.fx -= fx;\n forces.get(nodeList[j].id)!.fy -= fy;\n }\n }\n\n // Attraction (Hooke) along edges\n edgeList.forEach((e) => {\n const ps = s.positions.get(e.source);\n const pt = s.positions.get(e.target);\n if (!ps || !pt) return;\n const dx = pt.x - ps.x;\n const dy = pt.y - ps.y;\n const fs = forces.get(e.source);\n const ft = forces.get(e.target);\n if (fs) {\n fs.fx += dx * attForce;\n fs.fy += dy * attForce;\n }\n if (ft) {\n ft.fx -= dx * attForce;\n ft.fy -= dy * attForce;\n }\n });\n\n // Center gravity\n const cx = w / 2;\n const cy = h / 2;\n const gravity = 0.001;\n nodeList.forEach((n) => {\n const p = s.positions.get(n.id);\n const f = forces.get(n.id);\n if (!p || !f) return;\n f.fx += (cx - p.x) * gravity;\n f.fy += (cy - p.y) * gravity;\n });\n\n // Apply with damping\n const damp = 0.1;\n nodeList.forEach((n) => {\n const f = forces.get(n.id);\n const p = s.positions.get(n.id);\n if (!f || !p) return;\n p.x += f.fx * damp;\n p.y += f.fy * damp;\n });\n }\n\n // Sync anchors\n nodeList.forEach((n) => {\n const p = s.positions.get(n.id);\n const a = s.anchors.get(n.id);\n if (p && a) {\n a.x = p.x;\n a.y = p.y;\n }\n });\n },\n []\n );\n\n // ── Resize canvas with DPR ──\n const resizeCanvas = useCallback(() => {\n const canvas = canvasRef.current;\n const container = containerRef.current;\n if (!canvas || !container) return;\n\n const dpr = window.devicePixelRatio || 1;\n stateRef.current.dpr = dpr;\n const w = container.clientWidth;\n const h = container.clientHeight;\n canvas.width = w * dpr;\n canvas.height = h * dpr;\n canvas.style.width = `${w}px`;\n canvas.style.height = `${h}px`;\n }, []);\n\n // ── Screen → graph coordinate transform ──\n const screenToGraph = useCallback(\n (sx: number, sy: number): { x: number; y: number } => {\n const s = stateRef.current;\n const dpr = s.dpr;\n return {\n x: (sx * dpr - s.pan.x) / s.zoom,\n y: (sy * dpr - s.pan.y) / s.zoom,\n };\n },\n []\n );\n\n // ── Hit test ──\n const findNodeAt = useCallback(\n (gx: number, gy: number): GraphNode | null => {\n const s = stateRef.current;\n for (let i = s.nodes.length - 1; i >= 0; i--) {\n const n = s.nodes[i];\n const p = s.positions.get(n.id);\n if (!p) continue;\n const r = (n.size || 8) * 1.5;\n const dx = gx - p.x;\n const dy = gy - p.y;\n if (dx * dx + dy * dy < r * r) return n;\n }\n return null;\n },\n []\n );\n\n // ── Draw ──\n const draw = useCallback((ts: number) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) return;\n\n const s = stateRef.current;\n const dpr = s.dpr;\n const w = canvas.width;\n const h = canvas.height;\n const dark = isDarkMode();\n\n ctx.clearRect(0, 0, w, h);\n\n // Background\n ctx.fillStyle = dark ? \"#0a0e14\" : \"#ffffff\";\n ctx.fillRect(0, 0, w, h);\n\n ctx.save();\n ctx.translate(s.pan.x, s.pan.y);\n ctx.scale(s.zoom, s.zoom);\n\n // Focus neighborhood\n const focus = s.hoveredNode || s.selectedNode;\n const neighbors = new Set<string>();\n const activeEdgeIdx = new Set<number>();\n if (focus) {\n s.edges.forEach((e, i) => {\n if (e.source === focus.id) {\n neighbors.add(e.target);\n activeEdgeIdx.add(i);\n }\n if (e.target === focus.id) {\n neighbors.add(e.source);\n activeEdgeIdx.add(i);\n }\n });\n neighbors.add(focus.id);\n }\n\n // ── Edges ──\n s.edges.forEach((e, i) => {\n const ps = s.positions.get(e.source);\n const pt = s.positions.get(e.target);\n if (!ps || !pt) return;\n\n const active = activeEdgeIdx.has(i);\n if (active) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.7)\"\n : \"rgba(0,136,170,0.6)\";\n ctx.lineWidth = (2 * dpr) / s.zoom;\n } else if (focus) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.06)\"\n : \"rgba(0,136,170,0.05)\";\n ctx.lineWidth = (0.6 * dpr) / s.zoom;\n } else {\n const pulse = (Math.sin(ts * 0.00022 + i * 1.3) + 1) * 0.5;\n const alpha = (dark ? 0.16 : 0.13) + pulse * 0.06;\n ctx.strokeStyle = dark\n ? `rgba(0,212,255,${alpha.toFixed(3)})`\n : `rgba(0,136,170,${alpha.toFixed(3)})`;\n ctx.lineWidth = ((0.7 + pulse * 0.3) * dpr) / s.zoom;\n }\n\n ctx.beginPath();\n ctx.moveTo(ps.x, ps.y);\n ctx.lineTo(pt.x, pt.y);\n ctx.stroke();\n });\n\n // ── Nodes ──\n const searchQ = s.searchQuery.toLowerCase();\n\n s.nodes.forEach((n) => {\n const p = s.positions.get(n.id);\n if (!p) return;\n\n const isHovered = s.hoveredNode?.id === n.id;\n const isSelected = s.selectedNode?.id === n.id;\n const isNeighbor = neighbors.has(n.id);\n\n const v = s.velocities.get(n.id);\n const breathe =\n 1 + Math.sin(ts * 0.00035 + (v?.seed ?? 0) * 11.7) * 0.01;\n const baseR = (n.size || 8) * dpr;\n const r = baseR * (isHovered || isSelected ? 1.4 : breathe);\n\n // Alpha based on search / focus\n let alpha = 1;\n if (searchQ) {\n const hay = (n.fullLabel || n.label).toLowerCase();\n alpha = hay.includes(searchQ) ? 1 : 0.12;\n } else if (focus) {\n alpha = isHovered || isSelected || isNeighbor ? 1 : 0.18;\n }\n ctx.globalAlpha = alpha;\n\n // Glow\n if (isHovered || isSelected) {\n ctx.beginPath();\n ctx.arc(p.x, p.y, r + (5 * dpr) / s.zoom, 0, Math.PI * 2);\n ctx.fillStyle = dark\n ? \"rgba(0,212,255,0.14)\"\n : \"rgba(0,136,170,0.12)\";\n ctx.fill();\n }\n\n // Node circle\n ctx.beginPath();\n ctx.arc(p.x, p.y, r, 0, Math.PI * 2);\n ctx.fillStyle = getTypeColor(n.type);\n ctx.fill();\n\n // Stroke\n if (isHovered || isSelected) {\n ctx.strokeStyle = dark ? \"#f0f0f0\" : \"#1a1a1a\";\n ctx.lineWidth = (2 * dpr) / s.zoom;\n ctx.stroke();\n } else if (isNeighbor && focus) {\n ctx.strokeStyle = dark\n ? \"rgba(0,212,255,0.65)\"\n : \"rgba(0,136,170,0.55)\";\n ctx.lineWidth = (1.8 * dpr) / s.zoom;\n ctx.stroke();\n }\n\n // Label — only for hovered / selected node. Keep it short (truncated `label`)\n // since the full text is shown in the tooltip / detail dialog instead.\n // This keeps the canvas clean and readable.\n if (isHovered || isSelected) {\n const fontSize = Math.max(10 * dpr, (11 * dpr) / s.zoom);\n ctx.font = `${fontSize}px -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"top\";\n\n // Background pill for legibility\n const text = n.label;\n const metrics = ctx.measureText(text);\n const padX = 6 * dpr;\n const padY = 3 * dpr;\n const bx = p.x - metrics.width / 2 - padX;\n const by = p.y + r + 4 * dpr;\n const bw = metrics.width + padX * 2;\n const bh = fontSize + padY * 2;\n ctx.fillStyle = dark ? \"rgba(10,14,20,0.92)\" : \"rgba(255,255,255,0.95)\";\n ctx.beginPath();\n ctx.roundRect?.(bx, by, bw, bh, 4 * dpr);\n ctx.fill();\n\n ctx.fillStyle = dark\n ? `rgba(240,240,240,${alpha})`\n : `rgba(20,20,20,${alpha})`;\n ctx.fillText(text, p.x, by + padY);\n }\n\n ctx.globalAlpha = 1;\n });\n\n ctx.restore();\n }, []);\n\n // ── Motion update (breathing drift) ──\n const updateMotion = useCallback((ts: number) => {\n const s = stateRef.current;\n s.nodes.forEach((n) => {\n if (s.dragNode?.id === n.id) return;\n const p = s.positions.get(n.id);\n const a = s.anchors.get(n.id);\n const v = s.velocities.get(n.id);\n if (!p || !a || !v) return;\n p.x = a.x + Math.sin(ts * v.freq + v.seed * 11.1) * v.amp;\n p.y = a.y + Math.cos(ts * v.freq * 0.87 + v.seed * 17.3) * v.amp;\n });\n }, []);\n\n // ── Open detail dialog for a node (fetches full memory record) ──\n const openNodeDetail = useCallback(async (node: GraphNode) => {\n setDetailNode(node);\n setDetailMemory(null);\n setDetailError(null);\n setDetailOpen(true);\n setDetailLoading(true);\n stateRef.current.selectedNode = node;\n try {\n const mem = await api.brain.memory.get(node.id);\n setDetailMemory(mem);\n } catch (err) {\n // Not every node has a backing memory record (graph may include\n // person / goal aggregates) — fall back gracefully to node-only info.\n setDetailError(\n err instanceof Error ? err.message : \"Failed to load details\"\n );\n } finally {\n setDetailLoading(false);\n }\n }, []);\n\n // ── Mouse handlers ──\n const onMouseDown = useCallback(\n (e: MouseEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const sx = e.clientX - rect.left;\n const sy = e.clientY - rect.top;\n const gp = screenToGraph(sx, sy);\n const node = findNodeAt(gp.x, gp.y);\n const s = stateRef.current;\n\n s.pressNode = node;\n s.pressX = e.clientX;\n s.pressY = e.clientY;\n s.pressT = performance.now();\n s.moved = false;\n\n if (node) {\n s.dragNode = node;\n } else {\n s.dragging = true;\n }\n s.lastMouse = { x: e.clientX, y: e.clientY };\n },\n [screenToGraph, findNodeAt]\n );\n\n const onMouseMove = useCallback(\n (e: MouseEvent) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const sx = e.clientX - rect.left;\n const sy = e.clientY - rect.top;\n const s = stateRef.current;\n\n // Track whether the mouse has moved meaningfully since press.\n // 4px threshold lets micro-jitter still count as a click.\n if (s.pressT && !s.moved) {\n const ddx = e.clientX - s.pressX;\n const ddy = e.clientY - s.pressY;\n if (ddx * ddx + ddy * ddy > 16) s.moved = true;\n }\n\n if (s.dragNode) {\n const gp = screenToGraph(sx, sy);\n const p = s.positions.get(s.dragNode.id);\n const a = s.anchors.get(s.dragNode.id);\n if (p) {\n p.x = gp.x;\n p.y = gp.y;\n }\n if (a) {\n a.x = gp.x;\n a.y = gp.y;\n }\n } else if (s.dragging) {\n const dpr = s.dpr;\n s.pan.x += (e.clientX - s.lastMouse.x) * dpr;\n s.pan.y += (e.clientY - s.lastMouse.y) * dpr;\n } else {\n const gp = screenToGraph(sx, sy);\n const node = findNodeAt(gp.x, gp.y);\n if (node !== s.hoveredNode) {\n s.hoveredNode = node;\n if (node) {\n setTooltip({\n x: e.clientX - rect.left + 14,\n y: e.clientY - rect.top + 14,\n node,\n connections: connectionCount(node.id, s.edges),\n });\n } else {\n setTooltip(null);\n }\n } else if (node && tooltip) {\n setTooltip((prev) =>\n prev\n ? {\n ...prev,\n x: e.clientX - rect.left + 14,\n y: e.clientY - rect.top + 14,\n }\n : null\n );\n }\n }\n s.lastMouse = { x: e.clientX, y: e.clientY };\n },\n [screenToGraph, findNodeAt, connectionCount, tooltip]\n );\n\n const onMouseUp = useCallback(() => {\n const s = stateRef.current;\n const wasClick =\n !s.moved &&\n s.pressNode !== null &&\n performance.now() - s.pressT < 500;\n const clickedNode = s.pressNode;\n\n s.dragNode = null;\n s.dragging = false;\n s.pressNode = null;\n s.pressT = 0;\n s.moved = false;\n\n if (wasClick && clickedNode) {\n openNodeDetail(clickedNode);\n }\n }, [openNodeDetail]);\n\n const onWheel = useCallback(\n (e: WheelEvent) => {\n e.preventDefault();\n const s = stateRef.current;\n const delta = e.deltaY > 0 ? 0.92 : 1.08;\n const newZoom = Math.min(3.0, Math.max(0.3, s.zoom * delta));\n const scaleFactor = newZoom / s.zoom;\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const mx = (e.clientX - rect.left) * s.dpr;\n const my = (e.clientY - rect.top) * s.dpr;\n\n s.pan.x = mx - (mx - s.pan.x) * scaleFactor;\n s.pan.y = my - (my - s.pan.y) * scaleFactor;\n s.zoom = newZoom;\n },\n []\n );\n\n // ── Main effect: fetch, layout, animate ──\n useEffect(() => {\n let cancelled = false;\n\n async function init() {\n setLoading(true);\n try {\n const data = await api.brain.graph();\n if (cancelled) return;\n const n = data.nodes || [];\n const e = data.edges || [];\n setNodes(n);\n setEdges(e);\n\n const s = stateRef.current;\n s.nodes = n;\n s.edges = e;\n\n resizeCanvas();\n const canvas = canvasRef.current;\n const cw = canvas ? canvas.width : 800;\n const ch = canvas ? canvas.height : 600;\n\n initPositions(n, cw, ch);\n runLayout(n, e, cw, ch);\n } catch (err) {\n console.error(\"Failed to load graph data:\", err);\n }\n if (!cancelled) setLoading(false);\n }\n\n init();\n return () => {\n cancelled = true;\n };\n }, [initPositions, runLayout, resizeCanvas]);\n\n // ── Animation loop + event listeners ──\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas || loading) return;\n\n resizeCanvas();\n\n // Animation loop\n let running = true;\n const loop = (ts: number) => {\n if (!running) return;\n updateMotion(ts);\n draw(ts);\n stateRef.current.animFrame = requestAnimationFrame(loop);\n };\n stateRef.current.animFrame = requestAnimationFrame(loop);\n\n // Event listeners\n canvas.addEventListener(\"mousedown\", onMouseDown);\n canvas.addEventListener(\"mousemove\", onMouseMove);\n canvas.addEventListener(\"mouseup\", onMouseUp);\n canvas.addEventListener(\"mouseleave\", onMouseUp);\n canvas.addEventListener(\"wheel\", onWheel, { passive: false });\n\n const handleResize = () => {\n resizeCanvas();\n };\n window.addEventListener(\"resize\", handleResize);\n\n return () => {\n running = false;\n cancelAnimationFrame(stateRef.current.animFrame);\n canvas.removeEventListener(\"mousedown\", onMouseDown);\n canvas.removeEventListener(\"mousemove\", onMouseMove);\n canvas.removeEventListener(\"mouseup\", onMouseUp);\n canvas.removeEventListener(\"mouseleave\", onMouseUp);\n canvas.removeEventListener(\"wheel\", onWheel);\n window.removeEventListener(\"resize\", handleResize);\n };\n }, [\n loading,\n resizeCanvas,\n updateMotion,\n draw,\n onMouseDown,\n onMouseMove,\n onMouseUp,\n onWheel,\n ]);\n\n // ── Legend entries ──\n const legendEntries = nodes.length\n ? [...new Set(nodes.map((n) => n.type))].sort()\n : [];\n\n return (\n <div className=\"flex h-full flex-col\">\n {/* Header */}\n <div className=\"flex items-center justify-between border-b border-border/50 bg-background/80 px-6 py-4 backdrop-blur-sm\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-[#00d4ff]/10\">\n <Network className=\"h-5 w-5 text-[#00d4ff]\" />\n </div>\n <div>\n <h1 className=\"text-xl font-semibold tracking-tight text-foreground\">\n Knowledge Graph\n </h1>\n <p className=\"text-xs text-muted-foreground\">\n Visualize connections in Mercury's memory\n </p>\n </div>\n </div>\n </div>\n\n {/* Canvas area */}\n <div\n ref={containerRef}\n className=\"relative flex-1\"\n style={{ minHeight: 500 }}\n >\n {loading && (\n <div className=\"absolute inset-0 z-20 flex items-center justify-center bg-background/60 backdrop-blur-sm\">\n <div className=\"flex flex-col items-center gap-3\">\n <Loader2 className=\"h-8 w-8 animate-spin text-[#00d4ff]\" />\n <span className=\"text-sm text-muted-foreground\">\n Loading knowledge graph...\n </span>\n </div>\n </div>\n )}\n\n {!loading && nodes.length === 0 && (\n <div className=\"absolute inset-0 z-20 flex items-center justify-center\">\n <div className=\"flex flex-col items-center gap-3 text-center\">\n <Network className=\"h-12 w-12 text-muted-foreground/40\" />\n <p className=\"text-sm text-muted-foreground\">\n No knowledge graph data available yet\n </p>\n </div>\n </div>\n )}\n\n <canvas\n ref={canvasRef}\n className={`absolute inset-0 h-full w-full ${tooltip ? \"cursor-pointer\" : \"cursor-grab\"}`}\n />\n\n {/* Search overlay */}\n <div className=\"absolute right-4 top-4 z-10\">\n <div className=\"flex items-center gap-2 rounded-lg border border-border/60 bg-background/90 px-3 py-1.5 shadow-lg backdrop-blur-sm\">\n <Search className=\"h-4 w-4 text-muted-foreground\" />\n <input\n type=\"text\"\n placeholder=\"Search nodes...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-48 border-none bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground/60\"\n />\n </div>\n </div>\n\n {/* Legend overlay */}\n {legendEntries.length > 0 && (\n <div className=\"absolute bottom-4 left-4 z-10 rounded-lg border border-border/60 bg-background/90 px-3 py-2.5 shadow-lg backdrop-blur-sm\">\n <p className=\"mb-1.5 text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n Node Types\n </p>\n <div className=\"flex flex-col gap-1\">\n {legendEntries.map((type) => (\n <div key={type} className=\"flex items-center gap-2\">\n <span\n className=\"inline-block h-2.5 w-2.5 rounded-full\"\n style={{ backgroundColor: getTypeColor(type) }}\n />\n <span className=\"text-[11px] capitalize text-foreground/80\">\n {type}\n </span>\n </div>\n ))}\n </div>\n </div>\n )}\n\n {/* Tooltip */}\n {tooltip && (\n <div\n className=\"pointer-events-none absolute z-30 rounded-lg border border-border/60 bg-popover/95 px-3 py-2 shadow-xl backdrop-blur-sm\"\n style={{\n left: tooltip.x,\n top: tooltip.y,\n maxWidth: 320,\n // Flip horizontally near the right edge of the container so the\n // tooltip never gets clipped or pushes off-screen.\n transform:\n containerRef.current &&\n tooltip.x + 340 > containerRef.current.clientWidth\n ? \"translateX(calc(-100% - 28px))\"\n : undefined,\n }}\n >\n <p className=\"break-words text-sm font-medium leading-snug text-foreground\">\n {tooltip.node.fullLabel || tooltip.node.label}\n </p>\n <div className=\"mt-1 flex items-center gap-2\">\n <span\n className=\"inline-block h-2 w-2 rounded-full\"\n style={{ backgroundColor: getTypeColor(tooltip.node.type) }}\n />\n <span className=\"text-xs capitalize text-muted-foreground\">\n {tooltip.node.type}\n </span>\n <span className=\"text-xs text-muted-foreground/60\">·</span>\n <span className=\"text-xs text-muted-foreground\">\n {tooltip.connections} connection\n {tooltip.connections !== 1 ? \"s\" : \"\"}\n </span>\n </div>\n <p className=\"mt-1.5 text-[10px] uppercase tracking-wider text-muted-foreground/70\">\n Click for details\n </p>\n </div>\n )}\n </div>\n\n {/* Node detail dialog */}\n <NodeDetailDialog\n open={detailOpen}\n onOpenChange={(v) => {\n setDetailOpen(v);\n if (!v) {\n stateRef.current.selectedNode = null;\n }\n }}\n node={detailNode}\n memory={detailMemory}\n loading={detailLoading}\n error={detailError}\n connections={\n detailNode ? connectionCount(detailNode.id, edges) : 0\n }\n />\n </div>\n );\n}\n\n// ── Detail dialog ──\ninterface NodeDetailDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n node: GraphNode | null;\n memory: Memory | null;\n loading: boolean;\n error: string | null;\n connections: number;\n}\n\nfunction formatTs(ts: string | number | undefined): string {\n if (!ts) return \"—\";\n const d = typeof ts === \"number\" ? new Date(ts) : new Date(ts);\n if (Number.isNaN(d.getTime())) return String(ts);\n return d.toLocaleString();\n}\n\nfunction NodeDetailDialog({\n open,\n onOpenChange,\n node,\n memory,\n loading,\n error,\n connections,\n}: NodeDetailDialogProps) {\n if (!node) return null;\n const color = getTypeColor(node.type);\n const fullLabel = node.fullLabel || node.label;\n const summary = memory?.summary || fullLabel;\n const detail = memory?.detail;\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <div className=\"flex items-center gap-2\">\n <span\n className=\"inline-block h-3 w-3 rounded-full\"\n style={{ backgroundColor: color }}\n />\n <span className=\"text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {node.type}\n </span>\n </div>\n <DialogTitle className=\"mt-1 break-words text-lg leading-snug\">\n {summary}\n </DialogTitle>\n </DialogHeader>\n\n {loading && (\n <div className=\"flex items-center gap-2 py-4 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Loading details…\n </div>\n )}\n\n {!loading && memory && (\n <div className=\"space-y-4\">\n {detail && (\n <div>\n <p className=\"mb-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n Detail\n </p>\n <p className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90\">\n {detail}\n </p>\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-3 text-xs sm:grid-cols-3\">\n {memory.scope && (\n <DetailField label=\"Scope\" value={memory.scope} />\n )}\n {typeof memory.importance === \"number\" && (\n <DetailField\n label=\"Importance\"\n value={memory.importance.toFixed(2)}\n />\n )}\n {typeof memory.confidence === \"number\" && (\n <DetailField\n label=\"Confidence\"\n value={memory.confidence.toFixed(2)}\n />\n )}\n {typeof memory.evidenceCount === \"number\" && (\n <DetailField\n label=\"Evidence\"\n value={String(memory.evidenceCount)}\n />\n )}\n <DetailField label=\"Connections\" value={String(connections)} />\n {memory.evidenceKind && (\n <DetailField label=\"Source\" value={memory.evidenceKind} />\n )}\n <DetailField label=\"Created\" value={formatTs(memory.createdAt)} />\n {memory.updatedAt && (\n <DetailField label=\"Updated\" value={formatTs(memory.updatedAt)} />\n )}\n {memory.lastSeenAt && (\n <DetailField\n label=\"Last seen\"\n value={formatTs(memory.lastSeenAt)}\n />\n )}\n </div>\n\n <div className=\"border-t border-border/40 pt-2\">\n <p className=\"font-mono text-[10px] text-muted-foreground/70\">\n {memory.id}\n </p>\n </div>\n </div>\n )}\n\n {!loading && !memory && (\n <div className=\"space-y-3\">\n <p className=\"whitespace-pre-wrap break-words text-sm leading-relaxed text-foreground/90\">\n {fullLabel}\n </p>\n <div className=\"grid grid-cols-2 gap-3 text-xs\">\n <DetailField label=\"Type\" value={node.type} />\n <DetailField label=\"Connections\" value={String(connections)} />\n {typeof node.importance === \"number\" && (\n <DetailField\n label=\"Importance\"\n value={node.importance.toFixed(2)}\n />\n )}\n {typeof node.confidence === \"number\" && (\n <DetailField\n label=\"Confidence\"\n value={node.confidence.toFixed(2)}\n />\n )}\n </div>\n {error && (\n <p className=\"text-xs text-muted-foreground/70\">\n Could not load full record: {error}\n </p>\n )}\n <p className=\"font-mono text-[10px] text-muted-foreground/70\">\n {node.id}\n </p>\n </div>\n )}\n </DialogContent>\n </Dialog>\n );\n}\n\nfunction DetailField({ label, value }: { label: string; value: string }) {\n return (\n <div>\n <p className=\"text-[10px] font-medium uppercase tracking-wider text-muted-foreground\">\n {label}\n </p>\n <p className=\"mt-0.5 break-words text-foreground/90\">{value}</p>\n </div>\n );\n}\n"],"names":["__iconNode","Network","createLucideIcon","TYPE_COLORS","getTypeColor","type","isDarkMode","GraphPage","canvasRef","useRef","containerRef","loading","setLoading","useState","nodes","setNodes","edges","setEdges","searchQuery","setSearchQuery","tooltip","setTooltip","detailOpen","setDetailOpen","detailNode","setDetailNode","detailMemory","setDetailMemory","detailLoading","setDetailLoading","detailError","setDetailError","stateRef","useEffect","connectionCount","useCallback","nodeId","edgeList","count","e","initPositions","nodeList","canvasW","canvasH","s","cx","cy","node","i","angle","r","x","y","runLayout","w","h","iters","iter","area","k","repForce","attForce","forces","n","j","pi","pj","dx","dy","dist","f","fx","fy","ps","pt","fs","ft","gravity","p","damp","a","resizeCanvas","canvas","container","dpr","screenToGraph","sx","sy","findNodeAt","gx","gy","draw","ts","ctx","dark","focus","neighbors","activeEdgeIdx","pulse","alpha","searchQ","isHovered","_a","isSelected","_b","isNeighbor","v","breathe","fontSize","text","metrics","padX","padY","bx","by","bw","bh","_c","updateMotion","openNodeDetail","mem","api","err","onMouseDown","rect","gp","onMouseMove","ddx","ddy","prev","onMouseUp","wasClick","clickedNode","onWheel","delta","newZoom","scaleFactor","mx","my","cancelled","init","data","cw","ch","running","loop","handleResize","legendEntries","jsxs","jsx","Loader2","Search","NodeDetailDialog","formatTs","d","open","onOpenChange","memory","error","connections","color","fullLabel","summary","detail","Dialog","DialogContent","DialogHeader","DialogTitle","DetailField","label","value"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as e,m as Ke,A as Ve}from"./vendor-motion-Dwx3-JO5.js";import{r,j as Ps,e as Ls}from"./vendor-react-C7pctHW3.js";import{u as Es,a as es,D as Bs,c as Us,b as Ms,K as Rs,P as zs,S as cs,v as xs,d as Fs,C as Os}from"./vendor-dnd-DRBSMxXo.js";import{C as ss,c as ts,a as _s,b as Hs}from"./card-
|
|
1
|
+
import{j as e,m as Ke,A as Ve}from"./vendor-motion-Dwx3-JO5.js";import{r,j as Ps,e as Ls}from"./vendor-react-C7pctHW3.js";import{u as Es,a as es,D as Bs,c as Us,b as Ms,K as Rs,P as zs,S as cs,v as xs,d as Fs,C as Os}from"./vendor-dnd-DRBSMxXo.js";import{C as ss,c as ts,a as _s,b as Hs}from"./card-BdsEOP7t.js";import{B as j}from"./button-CNasMlFE.js";import{B as z}from"./badge-CUJiWF1y.js";import{I as ke}from"./input-CH3dmo9r.js";import{T as re}from"./textarea-CXh3tmJ1.js";import{D as be,a as ve,b as ye,c as we,d as We,e as Ge,f as Ze}from"./dialog-Bd1rELXb.js";import{A as Ce,h as Se,a as De,b as Ae,c as Te,d as Pe,e as Le,f as Ee,g as Be,T as Ue}from"./alert-dialog-MbYSbZx5.js";import{S as Fe,a as Oe,b as _e,c as He,d as q}from"./select-vRSgBrHz.js";import{j as qs,k as $s,l as ms,m as Is,n as us,D as hs,O as ps}from"./vendor-radix-3UdfCgs_.js";import{c as Ks}from"./index-CaqLZNof.js";import{e as I,X as qe,c as D,a as b,b as S,P as Je,t as $,h as ne,S as Vs,g as fs,M as Ws}from"./index-C3YiF4qv.js";import{C as Gs,a as Zs,b as Js}from"./collapsible-BU_K9n8f.js";import{A as as}from"./arrow-left-CtqQsBC6.js";import{P as gs}from"./pencil-gNDEMhav.js";import{P as js}from"./plus-7rbHkByr.js";import{L as ee}from"./loader-circle-DbYKk0_Q.js";import{S as Xs}from"./sparkles-DcP24GEL.js";import{Z as ns}from"./zap-BEfqVtvZ.js";import{G as ie}from"./git-branch-D9JVASpC.js";import{C as Ys}from"./circle-check-DvGSe1uZ.js";import{P as Qs,a as et}from"./power-BS7gCDWs.js";import{C as st}from"./chevron-down-CB9J_vvZ.js";import{S as Ns}from"./send-BkyTIUtJ.js";import{F as ze}from"./file-text-BWWBuD_N.js";import{E as tt}from"./eye-BJ0NucMz.js";import{D as at}from"./download-C8RvlFqO.js";import"./vendor-syntax-xZUI6Op9.js";/**
|
|
2
2
|
* @license lucide-react v0.511.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -42,4 +42,4 @@ import{j as e,m as Ke,A as Ve}from"./vendor-motion-Dwx3-JO5.js";import{r,j as Ps
|
|
|
42
42
|
`),t=[];let h=!1,m=[];for(let u=0;u<l.length;u++){const i=l[u];if(i.startsWith("```")){h?(t.push(e.jsx("pre",{className:"rounded-md bg-muted p-3 text-[11px] font-mono overflow-x-auto my-2",children:e.jsx("code",{children:m.join(`
|
|
43
43
|
`)})},u)),m=[],h=!1):(h=!0,i.slice(3).trim());continue}if(h){m.push(i);continue}i.startsWith("# ")?t.push(e.jsx("h1",{className:"text-lg font-bold mt-3 mb-1",children:K(i.slice(2))},u)):i.startsWith("## ")?t.push(e.jsx("h2",{className:"text-base font-semibold mt-2 mb-1",children:K(i.slice(3))},u)):i.startsWith("### ")?t.push(e.jsx("h3",{className:"text-sm font-semibold mt-2 mb-0.5",children:K(i.slice(4))},u)):i.startsWith("- ")||i.startsWith("* ")?t.push(e.jsx("li",{className:"ml-4 list-disc text-foreground/80",children:K(i.slice(2))},u)):/^\d+\.\s/.test(i)?t.push(e.jsx("li",{className:"ml-4 list-decimal text-foreground/80",children:K(i.replace(/^\d+\.\s/,""))},u)):i.startsWith("> ")?t.push(e.jsx("blockquote",{className:"border-l-2 border-[#00d4ff]/40 pl-3 text-muted-foreground italic my-1",children:K(i.slice(2))},u)):i.trim()===""?t.push(e.jsx("div",{className:"h-2"},u)):t.push(e.jsx("p",{className:"text-foreground/80 my-0.5",children:K(i)},u))}return h&&m.length>0&&t.push(e.jsx("pre",{className:"rounded-md bg-muted p-3 text-[11px] font-mono overflow-x-auto my-2",children:e.jsx("code",{children:m.join(`
|
|
44
44
|
`)})},"unclosed")),e.jsx(e.Fragment,{children:t})}function K(s){const l=[];let t=s,h=0;for(;t.length>0;){const m=t.match(/^(.*?)`([^`]+)`/);if(m){m[1]&&l.push(e.jsx("span",{children:m[1]},h++)),l.push(e.jsx("code",{className:"bg-muted px-1 py-0.5 rounded text-[10px] font-mono text-[#00d4ff]",children:m[2]},h++)),t=t.slice(m[0].length);continue}const u=t.match(/^(.*?)\*\*([^*]+)\*\*/);if(u){u[1]&&l.push(e.jsx("span",{children:u[1]},h++)),l.push(e.jsx("strong",{children:u[2]},h++)),t=t.slice(u[0].length);continue}l.push(e.jsx("span",{children:t},h++));break}return e.jsx(e.Fragment,{children:l})}export{la as KanbanPage};
|
|
45
|
-
//# sourceMappingURL=Kanban-
|
|
45
|
+
//# sourceMappingURL=Kanban-DRlNiNRF.js.map
|