mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-12 09:47:20 +08:00
Distilled from #789 (safe features only). Adds backend dead-code classification (status + in_calls in the layout JSON), a GET /api/repo-info endpoint for GitHub deep-links, and the frontend dead-code filters, node code preview, and deep-links. The render-cap revert was dropped (kept 2000 for DEFAULT_MAX_NODES/HARD_MAX_NODES and GRAPH_RENDER_NODE_LIMIT); the sidebar regex-search refactor was omitted. Security fixes over the original: repo-info strips credentials from any returned remote_url; the legitimate https blob-URL construction is allow-listed so the static gate passes; libgit2 is not re-initialized/shutdown per request (reuses the process-wide init from cbm_alloc_init); deep-link path segments are URL-encoded. Co-authored-by: Andy Zehady <azehady@ciroos.ai> Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
57 lines
2.0 KiB
TypeScript
57 lines
2.0 KiB
TypeScript
import { Html } from "@react-three/drei";
|
|
import type { GraphNode } from "../lib/types";
|
|
import { colorForLabel, colorForStatus } from "../lib/colors";
|
|
|
|
interface NodeTooltipProps {
|
|
node: GraphNode;
|
|
}
|
|
|
|
function lineRange(node: GraphNode): string | null {
|
|
if (!node.start_line) return null;
|
|
if (node.end_line && node.end_line !== node.start_line)
|
|
return `L${node.start_line}-${node.end_line}`;
|
|
return `L${node.start_line}`;
|
|
}
|
|
|
|
export function NodeTooltip({ node }: NodeTooltipProps) {
|
|
return (
|
|
<Html
|
|
position={[node.x, node.y + node.size * 0.7, node.z]}
|
|
center
|
|
style={{ pointerEvents: "none" }}
|
|
>
|
|
<div className="bg-[#1a1a2e]/95 backdrop-blur border border-white/10 rounded-lg px-3 py-2 text-xs whitespace-nowrap shadow-xl max-w-[350px]">
|
|
<div className="flex items-center gap-1.5 mb-1">
|
|
<span
|
|
className="w-2 h-2 rounded-full shrink-0"
|
|
style={{ backgroundColor: colorForLabel(node.label) }}
|
|
/>
|
|
<span className="text-white font-medium truncate">{node.name}</span>
|
|
<span className="text-white/30 ml-1 shrink-0">{node.label}</span>
|
|
</div>
|
|
{node.file_path && (
|
|
<p className="text-white/30 font-mono truncate">
|
|
{node.file_path}
|
|
{lineRange(node) && <span className="text-white/40"> · {lineRange(node)}</span>}
|
|
</p>
|
|
)}
|
|
{node.status && node.status !== "structural" && (
|
|
<div className="flex items-center gap-1.5 mt-1">
|
|
<span
|
|
className="w-1.5 h-1.5 rounded-full shrink-0"
|
|
style={{ backgroundColor: colorForStatus(node.status) }}
|
|
/>
|
|
<span className="text-white/45">{node.status}</span>
|
|
{node.in_calls !== undefined && (
|
|
<span className="text-white/25">
|
|
· {node.in_calls} caller{node.in_calls === 1 ? "" : "s"}
|
|
</span>
|
|
)}
|
|
</div>
|
|
)}
|
|
<p className="text-white/20 mt-1 text-[10px]">click for code →</p>
|
|
</div>
|
|
</Html>
|
|
);
|
|
}
|