snatching amp's walkthrough for my own purposes mwhahaha traverse.dunkirk.sh/diagram/6121f05c-a5ef-4ecf-8ffc-02534c5e767c

feat: use elk and escaoe stuff and update prompt

dunkirk.sh 2ee276ff 480204f4

verified
+35 -43
+22 -32
src/index.ts
··· 59 59 }); 60 60 61 61 const nodeMetadataSchema = z.object({ 62 - title: z.string().describe("Display name for the node"), 63 - description: z 64 - .string() 65 - .describe("Detailed markdown explanation of this component"), 62 + title: z.string(), 63 + description: z.string(), 66 64 links: z 67 - .array( 68 - z.object({ 69 - label: z.string().describe("Display text, e.g. src/auth.ts"), 70 - url: z.string().describe("File path or URL"), 71 - }), 72 - ) 73 - .optional() 74 - .describe("Related files or documentation"), 75 - codeSnippet: z.string().optional().describe("Optional code example"), 76 - threadID: z 77 - .string() 78 - .optional() 79 - .describe("Optional link to deeper exploration thread"), 65 + .array(z.object({ label: z.string(), url: z.string() })) 66 + .optional(), 67 + codeSnippet: z.string().optional(), 80 68 }); 81 69 82 70 server.registerTool("walkthrough_diagram", { 83 71 title: "Walkthrough Diagram", 84 - description: 85 - "Render an interactive Mermaid diagram where users can click nodes to see detailed information about each component. Use plain text labels in Mermaid code, no HTML tags or custom styling.", 72 + description: `Render an interactive Mermaid diagram where users can click nodes to see details. 73 + 74 + BEFORE calling this tool, deeply explore the codebase: 75 + 1. Use search/read tools to find key files, entry points, and architecture patterns 76 + 2. Trace execution paths and data flow between components 77 + 3. Read source files — don't guess from filenames 78 + 79 + Then build the diagram: 80 + - Use \`flowchart TB\` with plain text labels, no HTML or custom styling 81 + - 5-12 nodes at the right abstraction level (not too granular, not too high-level) 82 + - Node keys must match Mermaid node IDs exactly 83 + - Descriptions: 2-3 paragraphs of markdown per node. Write for someone who has never seen this codebase — explain what the component does, how it works, and why it matters. Use \`code spans\` for identifiers and markdown headers to organize longer explanations 84 + - Links: include file:line references from your exploration 85 + - Code snippets: key excerpts (under 15 lines) showing the most important or representative code`, 86 86 inputSchema: z.object({ 87 - code: z 88 - .string() 89 - .describe( 90 - "Mermaid diagram code. Use plain text labels, no HTML tags. No custom styling/colors.", 91 - ), 92 - summary: z 93 - .string() 94 - .describe("One-sentence summary of what the diagram illustrates"), 95 - nodes: z 96 - .record(z.string(), nodeMetadataSchema) 97 - .describe( 98 - "Metadata for clickable nodes, keyed by node ID from mermaid code", 99 - ), 87 + code: z.string(), 88 + summary: z.string(), 89 + nodes: z.record(z.string(), nodeMetadataSchema), 100 90 }), 101 91 }, async ({ code, summary, nodes }) => { 102 92 const id = String(++diagramCounter);
+13 -10
src/template.ts
··· 1 1 import type { WalkthroughDiagram } from "./types.ts"; 2 2 3 3 export function generateViewerHTML(diagram: WalkthroughDiagram): string { 4 - const diagramJSON = JSON.stringify(diagram); 4 + const diagramJSON = JSON.stringify(diagram).replace(/<\//g, "<\\/"); 5 5 6 6 return `<!DOCTYPE html> 7 7 <html lang="en"> ··· 258 258 .diagram-section .node { cursor: pointer; } 259 259 260 260 .diagram-section .node:hover :is(rect, circle, ellipse, polygon, path) { 261 - filter: brightness(1.12) !important; 261 + fill: var(--code-bg) !important; 262 + stroke-width: 2px !important; 262 263 } 263 264 264 265 .diagram-section .node.selected :is(rect, circle, ellipse, polygon, path) { 265 - filter: brightness(1.2) !important; 266 - stroke: var(--text-muted) !important; 267 - stroke-width: 1.5px !important; 266 + fill: var(--code-bg) !important; 267 + stroke-width: 2.5px !important; 268 268 } 269 269 270 270 /* Edge hover */ 271 271 .diagram-section .node:hover ~ .edgePath path, 272 272 .diagram-section .edgePath:hover path { 273 - stroke-width: 3px; 274 - filter: brightness(1.2); 273 + stroke-width: 2.5px; 275 274 } 276 275 277 276 /* Highlight pulse animation */ ··· 279 278 animation: node-highlight-pulse 0.5s ease-in-out 3; 280 279 } 281 280 @keyframes node-highlight-pulse { 282 - 0%, 100% { filter: brightness(1); } 283 - 50% { filter: brightness(1.3) drop-shadow(0 0 8px var(--text)); } 281 + 0%, 100% { stroke-width: 1px; } 282 + 50% { stroke-width: 3px; } 284 283 } 285 284 286 285 /* ERD: don't apply hover/selected effects to individual row cells */ ··· 425 424 426 425 <script type="module"> 427 426 import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs"; 427 + import elkLayouts from "https://cdn.jsdelivr.net/npm/@mermaid-js/layout-elk@0/dist/mermaid-layout-elk.esm.min.mjs"; 428 + 429 + mermaid.registerLayoutLoaders(elkLayouts); 428 430 429 431 const DIAGRAM_DATA = ${diagramJSON}; 430 432 ··· 440 442 await mermaid.initialize({ 441 443 startOnLoad: true, 442 444 theme: "base", 443 - flowchart: { useMaxWidth: false, htmlLabels: true, curve: "monotoneY", nodeSpacing: 50, rankSpacing: 50 }, 445 + layout: "elk", 446 + flowchart: { useMaxWidth: false, htmlLabels: true, nodeSpacing: 24, rankSpacing: 40 }, 444 447 securityLevel: "loose", 445 448 }); 446 449
-1
src/types.ts
··· 8 8 description: string; 9 9 links?: NodeLink[]; 10 10 codeSnippet?: string; 11 - threadID?: string; 12 11 } 13 12 14 13 export interface WalkthroughDiagram {