Add development plan with 13 milestone specifications
- docs/plan.md: Master roadmap with phases and priorities - docs/milestones/01-13: Detailed specs for each feature - Updated CLAUDE.md with plan references and build commands Milestones cover: - Phase 1: Temporal versioning, auto-capture, context injection, codebase indexing - Phase 2: Daily journal, content ingestion, graph visualization, import/export - Phase 3: Multi-graph, smart retrieval, TUI dashboard, browser extension, shell completions
This commit is contained in:
271
docs/milestones/07-graph-visualization.md
Normal file
271
docs/milestones/07-graph-visualization.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# Milestone 7: Graph Visualization
|
||||
|
||||
## Overview
|
||||
|
||||
Export the knowledge graph as interactive HTML visualizations, SVG images, and Mermaid diagrams. See and understand your knowledge structure.
|
||||
|
||||
## Motivation
|
||||
|
||||
- Visual understanding of knowledge structure
|
||||
- Identify orphaned or disconnected nodes
|
||||
- Documentation and sharing
|
||||
- Obsidian-style graph view is beloved
|
||||
|
||||
## Features
|
||||
|
||||
### 7.1 Interactive HTML Export
|
||||
|
||||
```bash
|
||||
# Export full graph as interactive HTML
|
||||
cortex export --format html --output graph.html
|
||||
|
||||
# Export subgraph from a root node
|
||||
cortex export abc123 --format html --output component-graph.html
|
||||
|
||||
# Export with filters
|
||||
cortex export --kind component --format html
|
||||
```
|
||||
|
||||
### 7.2 SVG/PNG Export
|
||||
|
||||
```bash
|
||||
# Static SVG export
|
||||
cortex export --format svg --output graph.svg
|
||||
|
||||
# PNG with custom dimensions
|
||||
cortex export --format png --width 1920 --height 1080
|
||||
|
||||
# Export specific depth from root
|
||||
cortex export abc123 --format svg --depth 3
|
||||
```
|
||||
|
||||
### 7.3 Mermaid Diagram Export
|
||||
|
||||
```bash
|
||||
# Export as Mermaid syntax
|
||||
cortex export --format mermaid
|
||||
|
||||
# Output:
|
||||
# ```mermaid
|
||||
# graph TD
|
||||
# A[Component: Auth] --> B[Component: UserService]
|
||||
# A --> C[Decision: Use JWT]
|
||||
# ```
|
||||
```
|
||||
|
||||
### 7.4 Live Server
|
||||
|
||||
```bash
|
||||
# Start live visualization server
|
||||
cortex viz
|
||||
|
||||
# Opens browser with interactive graph
|
||||
# Auto-refreshes on database changes
|
||||
```
|
||||
|
||||
### 7.5 Customization
|
||||
|
||||
```bash
|
||||
# Custom color scheme
|
||||
cortex export --format html --theme dark
|
||||
|
||||
# Filter by tags
|
||||
cortex export --format html --tags auth,security
|
||||
|
||||
# Layout options
|
||||
cortex export --format html --layout force|tree|radial
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
### HTML Exporter (D3.js)
|
||||
|
||||
```typescript
|
||||
// src/core/export/html.ts
|
||||
export async function exportHtml(options: ExportOptions): Promise<string> {
|
||||
const { nodes, edges } = await getGraphData(options);
|
||||
|
||||
const graphData = {
|
||||
nodes: nodes.map(n => ({
|
||||
id: n.id,
|
||||
label: n.title,
|
||||
kind: n.kind,
|
||||
tags: n.tags,
|
||||
group: kindToGroup(n.kind),
|
||||
})),
|
||||
links: edges.map(e => ({
|
||||
source: e.fromId,
|
||||
target: e.toId,
|
||||
type: e.type,
|
||||
})),
|
||||
};
|
||||
|
||||
return generateHtmlTemplate(graphData, options.theme);
|
||||
}
|
||||
|
||||
function generateHtmlTemplate(data: GraphData, theme: string): string {
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Cortex Knowledge Graph</title>
|
||||
<script src="https://d3js.org/d3.v7.min.js"></script>
|
||||
<style>${getStyles(theme)}</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="graph"></div>
|
||||
<div id="sidebar"></div>
|
||||
<script>
|
||||
const data = ${JSON.stringify(data)};
|
||||
${getD3Script()}
|
||||
</script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
```
|
||||
|
||||
### D3 Force Graph
|
||||
|
||||
```typescript
|
||||
const D3_SCRIPT = `
|
||||
const width = window.innerWidth;
|
||||
const height = window.innerHeight;
|
||||
|
||||
const svg = d3.select("#graph")
|
||||
.append("svg")
|
||||
.attr("width", width)
|
||||
.attr("height", height);
|
||||
|
||||
const simulation = d3.forceSimulation(data.nodes)
|
||||
.force("link", d3.forceLink(data.links).id(d => d.id).distance(100))
|
||||
.force("charge", d3.forceManyBody().strength(-300))
|
||||
.force("center", d3.forceCenter(width / 2, height / 2));
|
||||
|
||||
// ... link and node rendering
|
||||
// ... drag behavior
|
||||
// ... zoom behavior
|
||||
// ... click to show details
|
||||
`;
|
||||
```
|
||||
|
||||
### Mermaid Exporter
|
||||
|
||||
```typescript
|
||||
// src/core/export/mermaid.ts
|
||||
export async function exportMermaid(options: ExportOptions): Promise<string> {
|
||||
const { nodes, edges } = await getGraphData(options);
|
||||
|
||||
const lines = ['graph TD'];
|
||||
|
||||
// Define nodes
|
||||
for (const node of nodes) {
|
||||
const shape = kindToShape(node.kind);
|
||||
lines.push(` ${shortId(node.id)}${shape.open}"${escape(node.title)}"${shape.close}`);
|
||||
}
|
||||
|
||||
// Define edges
|
||||
for (const edge of edges) {
|
||||
const arrow = typeToArrow(edge.type);
|
||||
lines.push(` ${shortId(edge.fromId)} ${arrow} ${shortId(edge.toId)}`);
|
||||
}
|
||||
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function kindToShape(kind: string): { open: string; close: string } {
|
||||
switch (kind) {
|
||||
case 'component': return { open: '[', close: ']' };
|
||||
case 'decision': return { open: '{', close: '}' };
|
||||
case 'task': return { open: '([', close: '])' };
|
||||
default: return { open: '(', close: ')' };
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Live Visualization Server
|
||||
|
||||
```typescript
|
||||
// src/server/viz.ts
|
||||
export function startVizServer(port: number): void {
|
||||
const app = express();
|
||||
|
||||
app.get('/', async (req, res) => {
|
||||
const html = await exportHtml({ theme: 'dark', layout: 'force' });
|
||||
res.send(html);
|
||||
});
|
||||
|
||||
app.get('/api/graph', async (req, res) => {
|
||||
const data = await getGraphData({});
|
||||
res.json(data);
|
||||
});
|
||||
|
||||
// WebSocket for live updates
|
||||
const wss = new WebSocketServer({ server });
|
||||
watchDatabase((change) => {
|
||||
wss.clients.forEach(client => {
|
||||
client.send(JSON.stringify({ type: 'update', data: change }));
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(port);
|
||||
open(`http://localhost:${port}`);
|
||||
}
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
| Command | Description |
|
||||
|---------|-------------|
|
||||
| `cortex export --format html` | Export interactive HTML |
|
||||
| `cortex export --format svg` | Export static SVG |
|
||||
| `cortex export --format png` | Export PNG image |
|
||||
| `cortex export --format mermaid` | Export Mermaid syntax |
|
||||
| `cortex export <id> --depth <n>` | Export subgraph |
|
||||
| `cortex viz` | Start live visualization server |
|
||||
| `cortex viz --port <n>` | Custom port |
|
||||
|
||||
## MCP Tools
|
||||
|
||||
```typescript
|
||||
memory_export // Export graph in specified format
|
||||
memory_visualize // Get visualization URL
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
- [ ] HTML export renders correctly in browsers
|
||||
- [ ] SVG export produces valid SVG
|
||||
- [ ] Mermaid syntax is valid
|
||||
- [ ] Subgraph export respects depth
|
||||
- [ ] Live server updates on changes
|
||||
- [ ] Large graphs (1000+ nodes) perform well
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Interactive HTML with zoom, pan, search
|
||||
- [ ] Click node to see details
|
||||
- [ ] Color-coded by node kind
|
||||
- [ ] Edge types visually distinct
|
||||
- [ ] Mermaid compatible with GitHub/docs
|
||||
- [ ] Live server auto-refreshes
|
||||
|
||||
## Estimated Effort
|
||||
|
||||
- HTML + D3 template: 6 hours
|
||||
- SVG export: 3 hours
|
||||
- Mermaid export: 2 hours
|
||||
- Live server: 4 hours
|
||||
- Theming: 2 hours
|
||||
- Testing: 3 hours
|
||||
- **Total: ~20 hours**
|
||||
|
||||
## Dependencies
|
||||
|
||||
- D3.js (bundled in HTML output)
|
||||
- Optional: Puppeteer for PNG export
|
||||
|
||||
## References
|
||||
|
||||
- [D3.js Force Graph](https://observablehq.com/@d3/force-directed-graph)
|
||||
- [Mermaid.js](https://mermaid.js.org/)
|
||||
- [Obsidian Graph View](https://help.obsidian.md/Plugins/Graph+view)
|
||||
Reference in New Issue
Block a user