| name | visualize-system |
| description | Live system visualization using D2 diagrams. Analyzes codebase architecture, generates a D2 diagram, and starts a live-updating browser view. Designed to be re-invoked repeatedly (manually or via /loop) to keep the visualization current as the agent works. Use when user says "visualize system", "visualize", "show me the architecture", "system diagram", "live diagram", or "map this codebase". |
Visualize System
Generate and maintain a live D2 diagram of the system you're working in. A live "situation map" that stays current as code changes.
When to Use This Skill
- User says "visualize system", "visualize", "system diagram", "map this"
- User wants to see architecture while working
- Combined with
/loop for continuous updates during a work session
Instructions
Phase 1: Initial Setup (first invocation only)
Check if D2 is installed:
which d2 || echo "NOT_INSTALLED"
If not installed, tell the user to run brew install d2.
Check if a situation map already exists:
ls .visualize-system.d2 2>/dev/null
If no existing map, proceed to Phase 2. If one exists, skip to Phase 3 (Update).
Phase 2: Generate Initial Map
Analyze the codebase to understand its architecture. Focus on:
- Project structure — directories, entry points, key modules
- Dependencies between modules — imports, API calls, database access
- External services — databases, APIs, queues, caches
- Data flow — how requests/data move through the system
Use Glob, Grep, and Read to understand the system. Prioritize:
- Entry points (main, index, app, server files)
- Route/controller definitions
- Service/module boundaries
- Database models/schemas
- Config files for external services
Then generate .visualize-system.d2 in the project root. Follow these D2 conventions:
D2 Style Guide
# Use containers to group related components
backend: Backend {
api: API Routes
auth: Auth Service
db: Database Layer
}
frontend: Frontend {
pages: Pages
components: Components
state: State Management
}
# Show relationships with labels
frontend.pages -> backend.api: REST calls
backend.auth -> backend.db: queries
# Use shapes for external services
postgres: PostgreSQL {
shape: cylinder
}
redis: Redis Cache {
shape: cylinder
}
# Use colors sparingly for emphasis
# Red for areas currently being modified
backend.auth.style.fill: "#ffcccc"
Diagram principles:
- Show the RIGHT level of abstraction — not every file, not just "frontend/backend"
- Group by architectural boundary, not directory structure
- Label edges with what flows between components (data, events, queries)
- Highlight the area currently being worked on with a subtle fill color
- Use
direction: right for wide systems, default (top-down) for deep systems
- Keep it to ONE page — if it's too complex, zoom into the relevant subsystem
After generating the file, automatically start the watch server (do NOT tell the user to run it manually):
d2 --watch .visualize-system.d2 .visualize-system.svg &
Run this via the Bash tool with run_in_background: true. This opens the browser with a live-updating SVG that refreshes whenever the .d2 file changes.
Phase 3: Update Existing Map
The .d2 file is NOT what you're monitoring — the D2 watch server handles browser refresh automatically when the file changes. Your job is to detect codebase changes and update the .d2 file to reflect them, which triggers the browser to reload the visualization.
When re-invoked (the map already exists):
- Check what changed in the codebase — look at source code changes since the diagram was last updated:
git diff --name-only 2>/dev/null | grep -v '.visualize-system'
git log --oneline -5 --name-only 2>/dev/null
-
Assess if the diagram needs updating — a meaningful change is:
- New module, service, or component added
- New dependency/relationship between modules
- Module renamed, moved, or deleted
- New external service integration
- Significant change to data flow
NOT meaningful (skip update):
- Bug fixes within a single module
- Style/formatting changes
- Test additions that don't reveal new architecture
- Documentation changes
- Minor refactors within existing boundaries
-
If meaningful: Read the current .visualize-system.d2, apply targeted edits using the Edit tool. Don't regenerate from scratch — preserve the user's mental model by making incremental changes. The D2 watch server will detect the file change and auto-refresh the browser.
-
If not meaningful: Report "No architectural changes detected — map is current." and stop.
-
Update highlights: Move the highlight color to whatever area is currently being worked on. Remove highlights from areas that are no longer active.
How it works with /loop
When combined with /loop (e.g. /loop 5m /visualize-system), this creates a live dashboard:
- You make code changes normally
- Every N minutes, this skill re-invokes and checks what source files changed
- If architecture changed, it edits
.visualize-system.d2
- D2's
--watch detects the file edit and re-renders the SVG
- The browser auto-refreshes to show the updated diagram
The flow is: codebase changes → skill detects → edits .d2 file → D2 watch renders → browser refreshes
Parameters
The user can optionally specify focus:
/visualize-system — full system overview
/visualize-system auth — zoom into auth subsystem
/visualize-system frontend — zoom into frontend
When a focus area is specified, generate a more detailed diagram of just that subsystem instead of the full overview.
Notes
- The
.visualize-system.d2 file should be gitignored (it's a working artifact)
- D2's
--watch mode handles browser refresh — you only need to edit the .d2 file
- Works best with
/loop 5m /visualize-system for continuous monitoring
- If the project has a CLAUDE.md with architecture notes, use those as a starting point
- Keep diagrams simple — they should be glanceable, not comprehensive documentation