5.7 KiB
Understand Anything
Project Overview
An open-source tool combining LLM intelligence + static analysis to produce interactive dashboards for understanding codebases.
Prerequisites
- Node.js >= 22 (developed on v24)
- pnpm >= 10 (pinned via
packageManagerfield in rootpackage.json)
Architecture
- Monorepo with pnpm workspaces
- understand-anything-plugin/ — Claude Code plugin containing all source code:
- packages/core — Shared analysis engine (types, persistence, tree-sitter, search, schema, tours, plugins)
- packages/dashboard — React + TypeScript web dashboard (React Flow, Zustand, TailwindCSS v4)
- src/ — Skill TypeScript source for
/understand-chat,/understand-diff,/understand-explain,/understand-onboard - skills/ — Skill definitions (
/understand,/understand-dashboard, etc.) - agents/ — Agent definitions (project-scanner, file-analyzer, architecture-analyzer, tour-builder, graph-reviewer)
Dashboard
- Dark luxury theme: deep blacks (#0a0a0a), gold/amber accents (#d4a574), DM Serif Display typography
- Graph-first layout: 75% graph + 360px right sidebar
- No ChatPanel or Monaco Editor
- Sidebar tabs:
Info(ProjectOverview default → NodeInfo when node selected → LearnPanel in Learn persona, composing) andFiles(FileExplorer tree built from the structural graph) - Code viewer: prism-react-renderer source viewer that slides up from the bottom on file node click; an expand button promotes it into a full-screen modal. Source content is fetched from the dev server's
/file-content.jsonendpoint, gated by access token + a graph-derived path allowlist - Schema validation on graph load with error banner
Agent Pipeline
- Agents write intermediate results to
.understand-anything/intermediate/on disk (not returned to context) - Agent model field is omitted from frontmatter so each platform falls back to its configured default —
inheritwas a Claude Code-only keyword that opencode (and similar tools) treated as a literal model id and rejected withProviderModelNotFoundError(see #167) /understandauto-triggers/understand-dashboardafter completion- Intermediate files cleaned up after graph assembly
Key Commands
pnpm install— Install all dependenciespnpm --filter @understand-anything/core build— Build the core packagepnpm --filter @understand-anything/core test— Run core testspnpm --filter @understand-anything/skill build— Build the plugin packagepnpm test— Run all tests (skill tests live at repo-roottests/skill/, picked up by rootvitest.config.ts)pnpm --filter @understand-anything/dashboard build— Build the dashboardpnpm dev:dashboard— Start dashboard dev serverpnpm lint— Run ESLint across the project
Conventions
- TypeScript strict mode everywhere
- Vitest for testing
- ESM modules (
"type": "module") - Knowledge graph JSON lives in
.understand-anything/directory of analyzed projects - Core uses subpath exports (
./search,./types,./schema) to avoid pulling Node.js modules into browser
Gotchas
- tree-sitter: Uses
web-tree-sitter(WASM) instead of nativetree-sitter— native bindings fail on darwin/arm64 + Node 24 - Dashboard imports: Dashboard must only import from core's browser-safe subpath exports (
./search,./types,./schema), never the main entry point which pulls in Node.js modules
Scripts
scripts/generate-large-graph.mjs— Generates a fake knowledge graph for performance testing (e.g. large-graph layout). Writes to.understand-anything/knowledge-graph.json. Usage:node scripts/generate-large-graph.mjs [nodeCount](default: 3000 nodes). Not part of the production pipeline.
Versioning
When pushing to remote, bump the version in all five of these files (keep them in sync):
understand-anything-plugin/package.json→"version"fieldunderstand-anything-plugin/.claude-plugin/plugin.json→"version"field.claude-plugin/plugin.json→"version"field.cursor-plugin/plugin.json→"version"field.copilot-plugin/plugin.json→"version"field
Note: .claude-plugin/marketplace.json does not carry a version — the plugins[] entry only supports name and source, and adding other fields causes marketplace schema validation failures.
Testing Local Plugin Changes
Claude Code caches installed plugins at ~/.claude/plugins/cache/understand-anything/understand-anything/<version>/. Symlinks don't work because Claude's Search/Glob tools can't follow them. To test local changes:
-
Build the packages:
pnpm --filter @understand-anything/core build pnpm --filter @understand-anything/skill build -
Find the installed version (must match what the marketplace currently serves):
ls ~/.claude/plugins/cache/understand-anything/understand-anything/ -
Copy your local plugin into the cache, replacing
<VERSION>with the version from step 2:rm -rf ~/.claude/plugins/cache/understand-anything/understand-anything/<VERSION> cp -R ./understand-anything-plugin ~/.claude/plugins/cache/understand-anything/understand-anything/<VERSION> -
Start a fresh Claude Code session (existing sessions cache the old prompts in context).
-
Run
/understand --fullin the target project to verify.
Re-sync after further changes:
pnpm --filter @understand-anything/core build && \
cp -R ./understand-anything-plugin/* ~/.claude/plugins/cache/understand-anything/understand-anything/<VERSION>/
To revert to upstream: Uninstall and reinstall the plugin from the marketplace — it repopulates the cache from the upstream repo.