> your AI agent picks dependencies from memory; give it dated facts — try starlog.dev ↗ vet your agent's deps ↗ vibe-coding is fine. vibe-importing isn’t. — try starlog.dev ↗ vibe-importing isn’t fine ↗ your agent has never seen your private packages — try starlog.dev ↗ facts for private packages ↗ a linter for the dependencies your AI agent picks — try starlog.dev ↗ a linter for agent deps ↗

Back to Articles

Mindwalk: Watching Your Coding Agent Wander Through a 3D Map of Your Codebase

[ View on GitHub ]

Mindwalk: Watching Your Coding Agent Wander Through a 3D Map of Your Codebase

Hook

Your coding agent just made 73 file edits to complete a two-line bug fix. The logs say everything worked. The 3D replay shows it got lost in your utils folder for 40 minutes.

Context

Coding agents are no longer experimental toys—they're shipping features, refactoring legacy code, and burning through API credits in production environments. But when a session goes sideways, you're left squinting at JSONL logs wondering why the agent opened database.ts seventeen times or edited then reverted the same function four times in a row. Traditional observability tools treat code files as opaque strings in a key-value store, measuring token counts and latency but missing the spatial dimension: where did the agent go, how did it navigate your repository's structure, and why did it take that path instead of the obvious one?

Mindwalk reframes agent session logs as navigation traces through a spatial representation of your codebase. Instead of scrolling through thousands of log lines, you watch a replay where file interactions appear as glowing markers on a 3D city map—your repository structure becomes the game board, and the agent's actions become a visible trail. The tool emerged from a specific pain point: debugging why Claude Code sessions were inefficient required reconstructing mental models from flat logs. Mindwalk makes those patterns visible by exploiting a key insight—if you generate the same 3D layout for identical repository structures, you can compare agent behavior across sessions by overlaying their spatial footprints.

Technical Insight

Mindwalk's architecture splits into three deliberately isolated stages, each producing cacheable artifacts that can be analyzed independently. The adapter layer normalizes vendor-specific JSONL formats into a unified trace model. The citymap generator produces deterministic 3D layouts from repository trees. The server combines these artifacts and serves a React/Three.js frontend that handles replay and visualization.

The adapter subsystem is where vendor lock-in happens, but also where the interesting correlation logic lives. Claude Code and Codex both emit JSONL logs, but their event schemas differ—Claude might represent a file edit as {"type": "apply_diff", "path": "src/main.go"} while Codex uses {"action": "modify", "file": "src/main.go"}. The adapters parse these into a normalized trace event model that includes subagent correlation. When agents spawn subagents (Claude Code's "subtasks" or Codex's "delegated tasks"), the adapter reconstructs the hierarchical graph so you can switch lenses during replay—watch the entire session, or zoom into just what a specific subagent touched. Here's a simplified example of what the normalized trace structure looks like:

// internal/adapter/trace.go
type TraceEvent struct {
    Timestamp   time.Time
    AgentID     string  // "root" or subagent identifier
    ParentID    string  // correlates subagent to parent
    Action      ActionType
    Path        string  // file path relative to repo root
    Intensity   float64 // visit frequency or edit magnitude
}

type ActionType int
const (
    ActionSeen ActionType = iota  // file opened/previewed
    ActionRead                     // content fully read
    ActionEdited                   // content modified
    ActionDeleted                  // file removed
)

The citymap generator takes a repository tree and produces a 3D layout using consistent hashing—identical trees always produce identical spatial coordinates. This is critical for cross-session comparison. The implementation offers multiple layout algorithms (radial tree, treemap, force-directed graph), but all must satisfy the determinism constraint. For a typical repository, the generator assigns each directory a spatial region and distributes files within that region based on filename hashes. The output is a JSON mesh defining coordinates for each file:

{
  "nodes": [
    {"path": "src/main.go", "x": 12.4, "y": 0, "z": -8.1},
    {"path": "src/util/hash.go", "x": 15.2, "y": 0, "z": -3.7}
  ],
  "edges": [
    {"from": "src", "to": "src/main.go"}
  ]
}

Because coordinates are deterministic, you can load two different sessions on the same citymap and immediately spot divergent navigation patterns. If Session A shows heavy activity in the top-left quadrant (your API handlers) while Session B circles the bottom-right (database models), you've found a scoping problem before reading a single log line.

The touch-state model encodes agent interactions as visual properties. Each file transitions through states: unvisited (gray wireframe), seen (faint blue glow), read (bright blue), edited (yellow to orange gradient based on edit frequency). Deleted files persist as red wireframe ghosts, preserving the forensic trail. The intensity parameter drives glow brightness—a file opened once gets a faint highlight, a file churned fifteen times pulses like a beacon. This exploits preattentive visual processing: your brain spots the hot zones before you consciously parse the scene.

The evaluation judge runs as a subprocess executing local CLI tools (claude or codex) in a deliberately neutered environment—no tool access, no MCP servers, no settings persistence. It receives only a task summary and a digest of trace events, then outputs a structured assessment. This design keeps sensitive session data local until you explicitly trigger analysis, and ensures reproducible evaluations by eliminating non-deterministic tool interactions. The judge doesn't get the raw logs or repo content, just the spatial digest:

# What the judge subprocess receives
echo '{
  "task": "Add user authentication",
  "files_touched": 23,
  "files_edited": 8,
  "revisit_rate": 0.34,
  "primary_clusters": ["src/auth", "src/api", "tests"]
}' | claude --mode judge

The frontend handles video export entirely client-side using WebM encoding via the MediaRecorder API. You scrub through the replay, configure camera angles, then click "Export"—the browser renders and encodes locally. No server-side rendering dependencies, no uploading session data to generate videos. This aligns with Mindwalk's zero-telemetry design: everything stays on your machine unless you choose to share exported artifacts.

Gotcha

Mindwalk's adapter architecture creates hard vendor lock-in. It currently supports Claude Code and Codex JSONL formats, period. If you're running Cursor, Cody, GitHub Copilot Workspace, or Aider, you're writing a custom adapter from scratch. Worse, the normalized trace model assumes discrete file-level events—streaming agents that send delta updates or agents that operate on AST nodes rather than files will require rethinking the entire event schema. The project provides no plugin system or adapter SDK, so extending support means forking and maintaining your own build.

The deterministic citymap sounds great until you hit a repository it can't handle gracefully. Monorepos with deeply nested module structures (think src/services/user/api/v2/handlers/auth/session/middleware.go) produce cramped vertical towers where files overlap visually. Flat repositories with thousands of sibling files (common in data science projects with one Python script per experiment) generate sprawling horizontal planes where spatial relationships become meaningless. The layout algorithms are fixed—you can't tune them for your repo's characteristics, and there's no automatic detection to choose the best algorithm based on tree shape. You'll waste time experimenting with layouts that all look wrong because your repository's structure doesn't fit the assumptions.

File-level granularity loses critical information. When an agent edits the same 500-line file six times, making surgical changes to different functions, Mindwalk shows one increasingly bright yellow node. You don't see that the first three edits touched authentication logic while the last three mangled error handling in a completely different section. No diff visualization, no line-level heatmaps, no way to distinguish productive iteration from destructive churn within a single file. For debugging sessions where agents repeatedly "fix" the same code block, you'll still need to grep the raw logs.

Verdict

Use if: You're debugging why coding agents explore inefficiently, need to explain session costs to stakeholders who don't read logs, or you're tuning prompts/context strategies and want visual confirmation that scope changes actually changed behavior. It's particularly valuable when comparing agent performance across sessions on the same codebase—the deterministic layouts make patterns obvious. Skip if: You're running agents at production scale (this is a local diagnostic tool, not monitoring infrastructure), you need real-time observation during sessions (replay-only by design), your agents aren't Claude Code or Codex (adapter lock-in is painful), or your repository structure is pathological (deep nesting or extreme flatness breaks spatial layouts). Also skip if you need diff-level granularity—Mindwalk shows where agents went, not precisely what they changed. For teams doing serious agent development on Claude/Codex with normal repository structures, Mindwalk is the spatial debugger you didn't know you needed. For everyone else, the adapter tax makes it a curiosity.