A tool-agnostic, real-time dotfiles manager for AI coding agents. Point it at any project on disk and it inventories every harness artifact — context files, skills, MCP servers, hooks, subagents — grouped by which agent reads them (Claude Code, Cursor, Codex CLI, Pi, Windsurf, Copilot, Continue, Cline, Aider, Gemini CLI, Roo). Click any entry to inspect or edit it in place; saves write back to disk and the UI re-renders live.
Optionally emits a derived .harness/manifest.toml that coding agents can read as a token-efficient table-of-contents — bundled skills teach Claude Code / Cursor / Codex / Pi to consult that manifest and propose changes through the visualizer rather than editing harness files blindly.
Modern AI coding setups sprawl across a dozen folders: .claude/, .cursor/, .codex/, .windsurf/, ~/.claude/, .github/copilot-instructions.md, project-local rule files, MCP configs, hooks, subagents. After a few months of adding skills and rules you lose track of what's loaded when, which file outranks which, and whether two agents are getting contradictory instructions.
The visualizer answers, in one screen: what is my agent actually reading?
Prerequisites: Node.js 24+ (the repo pins it via .nvmrc).
git clone https://github.com/<your-fork>/harness-visualizer
cd harness-visualizer
npm install
npm run dev:safe # checks ports 3001/5173 first, prompts before killing squatters| Command | What it does |
|---|---|
npm run dev |
Plain start. Backend exits with EADDRINUSE if 3001 is taken; Vite silently picks a different port if 5173 is taken (this breaks the frontend → backend socket connection, so prefer dev:safe). |
npm run dev:safe |
Checks both ports first. If anything is squatting, prints what it is and asks before killing. Then npm run dev. |
npm run dev:force |
Same as dev:safe but no prompt — kill anything in the way. |
npm run stop |
Kill any leftover dev processes (anything on 3001/5173 + leaked concurrently / tsx watch backend / vite frontend processes). |
The frontend opens at http://localhost:5173; the backend binds to http://127.0.0.1:3001. By default the visualizer scans the directory npm run dev was launched from. Click 📁 Configure in the header to point it elsewhere, or set HARNESS_VISUALIZER_ROOT=/path/to/project before starting.
- Run
npm run dev:safefrom inside this repo. The visualizer scans its own directory and shows you what this project's harness looks like —.claude/plugins, skills, hooks, settings, and so on. - Click the Agents tab (default). Each detected agent gets a collapsible panel showing how it loads context, where its config files live, and which skills / MCPs / hooks / subagents it pulls in.
- Open the Inspector by clicking any artifact. The right rail shows a typed view; toggle Edit to open the markdown editor in place. Save (⌘S / Ctrl+S) and the file watcher re-renders the graph live.
- Point it at another project: click 📁 Configure, browse to one of your repos, and watch the Agents view repopulate. Or run
HARNESS_VISUALIZER_ROOT=/path/to/repo npm run dev:safe.
Five canonical harness layers, scoped global / project / local:
- context —
CLAUDE.md,AGENTS.md,AGENTS.override.md,GEMINI.md,SYSTEM.md,APPEND_SYSTEM.md,.cursor/rules/*.{md,mdc},.windsurf/rules/*.md,.github/copilot-instructions.md,.github/instructions/*.instructions.md,.continue/rules/*.md,.clinerules/*,.aider.conf.yml,.roo/rules/*.md - skill —
.claude/skills/<name>/SKILL.md,.pi/agent/skills/<name>/SKILL.md,.pi/skills/<name>/SKILL.md,.agents/skills/<name>/SKILL.md - mcp —
.mcp.json,.cursor/mcp.json,.gemini/settings.json,.continue/config.yaml,.claude/settings.json(also a hook) - hook —
.claude/settings.json,.claude/settings.local.json - subagent —
.claude/agents/*.md
A single file matching multiple layer globs produces multiple entries (e.g., .claude/settings.json surfaces as both a hook and an mcp entry, with distinct ids).
User overrides live at <watchRoot>/.harness-visualizer/patterns.json. v1-shape overrides are auto-migrated to v2 in-memory on load.
| Tab | Purpose |
|---|---|
| Agents (default) | Per-agent collapsible panels. Each shows context-loading pattern, config files per scope, capabilities (skills/MCPs/hooks/subagents), and an [Effective ▸] drill-down. |
| Issues | Aggregated status flags + scanner diagnostics. IntelliJ Inspections-style: severity-grouped, click-to-open the entry. |
| Table | Power-user flat inventory. Sortable on Tool / Layer / Scope / Path / Activation / Tokens. |
Right-rail Inspector opens on entry click — read-first, with an Edit toggle that swaps in md-editor-v3. Two tabs: Details (typed view) and Raw (JSON).
| Key | Action |
|---|---|
a |
Agents tab |
i |
Issues tab |
t |
Table tab |
/ |
Open Configure (directory picker) |
g |
Open Patterns editor |
? |
Toggle keyboard-shortcut help |
Esc |
Close drill-down, then inspector |
⌘S / Ctrl+S |
Save (in Markdown / Pattern editors) |
Shortcuts are suppressed when focus is on an <input>, <textarea>, or contenteditable element.
The visualizer ships portable skills — install one into your agent of choice and that agent can interface with the running visualizer:
curl http://127.0.0.1:3001/api/harness/skill?tool=claude-code
# returns { filename, installPath, content }Tier A targets: claude-code, cursor, codex, pi. The skill body teaches the agent to:
- Read
.harness/manifest.toml(orGET /api/harness/state) for the current state. - Propose changes via
POST /api/harness/proposerather than writing harness files directly. - Let the user review proposals in the browser.
The backend reads and writes files on your machine, so the threat model matters:
- HTTP server bound to
127.0.0.1only — never0.0.0.0. No network access. - Socket.IO CORS pinned to localhost origins.
- All filesystem paths validated via
realpath+ a TOCTOU-safesafeOpenprimitive (O_NOFOLLOW+ inode-compare). - File IO restricted to project + local watch roots for writes. Reads also allow the global scope (HOME) — bounded by explicit pattern map globs, no
**/prefix on global entries. - Six-extension allowlist (
.md,.markdown,.json,.yml,.yaml,.txt) + 1 MB cap. - Atomic writes via sibling-tmp +
fsync+rename.
Full threat-model addendum at specs/scope-aware-scanning/security.md.
- Frontend: Vue 3.5 + Vite 8 + Pinia 3 + Tailwind v4 +
@vueuse/core+md-editor-v3 - Backend: Express 5 + Socket.IO 4.8 +
chokidarv5 +fast-glob+gray-matter+ zod 4 +smol-toml+js-tiktoken - Shared: zod schemas + TypeScript types in
@harness-visualizer/shared - Tests: Vitest 4 across all three workspaces (~590 tests)
For the architectural source of truth and project conventions, see AGENTS.md. For the phase-by-phase build plan, see ROADMAP.md (v1) and ROADMAP_V2.md (v2).
The repo is an npm workspaces monorepo with three packages: frontend, backend, shared.
npm run typecheck # 3 workspaces (frontend / backend / shared)
npm run lint # eslint . --max-warnings=0
npm run test # vitest run — all projectsWorking in this codebase with an AI agent? Read AGENTS.md first — it's the single source of truth for conventions, stack rules, security non-negotiables, and the spec workflow. Tool-specific configs (CLAUDE.md, .cursor/rules/, etc.) point back to it by design.
All 17 build phases complete (0–16). The v2 milestone shipped the per-agent UI, scope-aware multi-root scanning, the derived TOML manifest, status detection, the agent-facing skill package, and demo polish. See ROADMAP.md and ROADMAP_V2.md for the per-phase breakdown.
TBD — see issue tracker. The dependency footprint is permissive (MIT / Apache-2.0 / ISC).