Skip to content

willmarple/harness-visualizer

Repository files navigation

Harness Visualizer

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.

Why this exists

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?

Quickstart

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.

Your first 60 seconds

  1. Run npm run dev:safe from 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.
  2. 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.
  3. 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.
  4. 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.

What gets discovered

Five canonical harness layers, scoped global / project / local:

  • contextCLAUDE.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.

Top-level UI

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).

Keyboard shortcuts

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 agent-facing skill

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:

  1. Read .harness/manifest.toml (or GET /api/harness/state) for the current state.
  2. Propose changes via POST /api/harness/propose rather than writing harness files directly.
  3. Let the user review proposals in the browser.

Security model

The backend reads and writes files on your machine, so the threat model matters:

  • HTTP server bound to 127.0.0.1 only — never 0.0.0.0. No network access.
  • Socket.IO CORS pinned to localhost origins.
  • All filesystem paths validated via realpath + a TOCTOU-safe safeOpen primitive (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.

Stack

  • Frontend: Vue 3.5 + Vite 8 + Pinia 3 + Tailwind v4 + @vueuse/core + md-editor-v3
  • Backend: Express 5 + Socket.IO 4.8 + chokidar v5 + 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).

Developing

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 projects

Working 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.

Roadmap snapshot

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.

License

TBD — see issue tracker. The dependency footprint is permissive (MIT / Apache-2.0 / ISC).

About

App to help visualize agent harness artifacts

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors