lum1104/understand-anything/understand
- community
- ext:[{"type":"config","description":"Configuration overrides"}]
Checking that the SKILL.md file is still in the repository.
Analyze a codebase to produce an interactive knowledge graph for understanding architecture, components, and relationships
Install
npx vskill@latest install lum1104/understand-anything/understandSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
/understand
Analyze the current codebase and produce a knowledge-graph.json file in the project's data directory (.ua/, or the legacy .understand-anything/ when it already exists). This file powers the interactive dashboard for exploring the project's architecture.
Options
$ARGUMENTSmay contain:--full— Force a full rebuild, ignoring any existing graph--auto-update— Enable automatic graph updates on commit (writesautoUpdate: trueto$UA_DIR/config.json)--no-auto-update— Disable automatic graph updates (writesautoUpdate: falseto$UA_DIR/config.json)--review— Run full LLM graph-reviewer instead of inline deterministic validation--language <lang>— Generate all textual content (summaries, descriptions, tags, titles, languageNotes, languageLesson) in the specified language. Accepts ISO 639-1 codes (zh,ja,ko,en,es,fr,de, etc.) or friendly names (chinese,japanese,korean,english,spanish, etc.). Locale variants supported:zh-TW,zh-HK, etc. Defaults toen(English). Stores preference in$UA_DIR/config.jsonfor consistency across incremental updates.--exclude <patterns>— Comma-separated glob patterns for additional files/directories to exclude from analysis (e.g.,--exclude "tests/*,docs/*"). These patterns take highest priority over built-in defaults and.understandignorerules. Supports gitignore syntax including!negation.- A directory path (e.g.
/path/to/repoor../other-project) — Analyze the given directory instead of the current working directory
Progress Reporting
Throughout execution, report progress to the user at each phase transition and during batch processing. This keeps users informed on large codebases where analysis can take a long time.
- Phase transitions: At the start of each phase, print a status line:
> [Phase N/7] <phase name>... > > Example: [Phase 2/7] Analyzing files (12 batches)...
- Batch progress: During Phase 2, report each batch with its index and total:
> Analyzing batch X/N (files: foo.ts, bar.ts, ...) (list up to 3 filenames, then ... if more)
- Phase completion: When a phase finishes, briefly confirm:
> Phase N complete. <one-line summary of result> > > Example: Phase 1 complete. Found 247 files across 3 languages.
Phase 0 — Pre-flight
Determine whether to run a full analysis or incremental update.
- Resolve `PROJECT_ROOT`:
- Parse
$ARGUMENTSfor a non-flag token (any argument that does not start with--). If found, treat it as the target directory path. - If the path is relative, resolve it against the current working directory.
- Verify the resolved path exists and is a directory (run
test -d <path>). If it does not exist or is not a directory, report an error to the user and STOP. - Set
PROJECT_ROOTto the resolved absolute path. - If no directory path argument is found, set
PROJECT_ROOTto the current working directory. - Worktree redirect. If
PROJECT_ROOTis inside a git worktree (not the main checkout), redirect output to the main repository root. Worktrees managed by Claude Code are ephemeral — the data directory (.ua/, or legacy.understand-anything/) written there is destroyed when the session ends, taking the knowledge graph with it (issue #133). Detect a worktree by comparinggit rev-parse --git-diragainstgit rev-parse --git-common-dir; in a normal checkout or submodule they resolve to the same path, in a worktree they differ and the parent of--git-common-diris the main repo root.
``bash COMMON_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-common-dir 2>/dev/null) GIT_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-dir 2>/dev/null) if [ -n "$COMMON_DIR" ] && [ -n "$GIT_DIR" ]; then COMMON_ABS=$(cd "$PROJECT_ROOT" && cd "$COMMON_DIR" 2>/dev/null && pwd -P) GIT_ABS=$(cd "$PROJECT_ROOT" && cd "$GIT_DIR" 2>/dev/null && pwd -P) if [ -n "$COMMON_ABS" ] && [ "$COMMON_ABS" != "$GIT_ABS" ]; then MAIN_ROOT=$(dirname "$COMMON_ABS") if [ -d "$MAIN_ROOT" ] && [ "${UNDERSTAND_NO_WORKTREE_REDIRECT:-0}" != "1" ]; then echo "[understand] Detected git worktree at $PROJECT_ROOT" echo "[understand] Redirecting output to main repo root: $MAIN_ROOT" echo "[understand] (Set UNDERSTAND_NO_WORKTREE_REDIRECT=1 to keep PROJECT_ROOT as the worktree.)" PROJECT_ROOT="$MAIN_ROOT" fi fi fi ``
Set UNDERSTAND_NO_WORKTREE_REDIRECT=1 if you intentionally want a per-worktree graph (rare — most users want the redirect). 1.5. Ensure the plugin is built. Later phases invoke Node scripts that import @understand-anything/core. On a fresh install packages/core/dist/ does not exist yet — build once.
Important: do not assume the plugin root is simply two directories above the skill path string. In many installations ~/.agents/skills/understand is a symlink into the real plugin checkout. Prefer runtime-provided plugin roots first (for Claude), then fall back to universal symlinks, skill symlink resolution, and common clone-based install paths.
Resolve the plugin root like this:
```bash SKILL_REAL=$(realpath ~/.agents/skills/understand 2>/dev/null || readlink -f ~/.agents/skills/understand 2>/dev/null || echo "") SELF_RELATIVE=$([ -n "$SKILL_REAL" ] && cd "$SKILL_REAL/../.." 2>/dev/null && pwd || echo "") COPILOT_SKILL_REAL=$(realpath ~/.copilot/skills/understand 2>/dev/null || readlink -f ~/.copilot/skills/understand 2>/dev/null || echo "") COPILOT_SELF_RELATIVE=$([ -n "$COPILOT_SKILL_REAL" ] && cd "$COPILOT_SKILL_REAL/../.." 2>/dev/null && pwd || echo "")
PLUGIN_ROOT="" for candidate in \ "${CLAUDE_PLUGIN_ROOT}" \ "$HOME/.understand-anything-plugin" \ "$SELF_RELATIVE" \ "$COPILOT_SELF_RELATIVE" \ "$HOME/.codex/understand-anything/understand-anything-plugin" \ "$HOME/.opencode/understand-anything/understand-anything-plugin" \ "$HOME/.pi/understand-anything/understand-anything-plugin" \ "$HOME/understand-anything/understand-anything-plugin"; do if [ -n "$candidate" ] && [ -f "$candidate/package.json" ] && [ -f "$candidate/pnpm-workspace.yaml" ]; then PLUGIN_ROOT="$candidate" break fi done
if [ -z "$PLUGIN_ROOT" ]; then echo "Error: Cannot find the understand-anything plugin root." echo "Checked:" echo " - ${CLAUDE_PLUGIN_ROOT:-<unset CLAUDE_PLUGIN_ROOT>}" echo " - $HOME/.understand-anything-plugin" echo " - ${SELF_RELATIVE:-<unresolved path derived from ~/.agents/skills/understand>}" echo " - ${COPILOT_SELF_RELATIVE:-<unresolved path derived from ~/.copilot/skills/understand>}" echo " - $HOME/.codex/understand-anything/understand-anything-plugin" echo " - $HOME/.opencode/understand-anything/understand-anything-plugin" echo " - $HOME/.pi/understand-anything/understand-anything-plugin" echo " - $HOME/understand-anything/understand-anything-plugin" echo "Make sure the plugin is installed correctly." exit 1 fi
if [ ! -f "$PLUGIN_ROOT/packages/core/dist/index.js" ]; then cd "$PLUGIN_ROOT" && (pnpm install --frozen-lockfile 2>/dev/null || pnpm install) && pnpm --filter @understand-anything/core build fi ```
If pnpm is missing, report to the user: "Install Node.js ≥ 22 and pnpm ≥ 10, then re-run /understand."
1.7. Resolve the data directory `$UA_DIR`. All Understand-Anything artifacts live in the project's data directory. Resolve it once, now that $PROJECT_ROOT is known, and reuse $UA_DIR for every read and write in later phases: ``bash UA_DIR="$PROJECT_ROOT/$([ -d "$PROJECT_ROOT/.understand-anything" ] && echo .understand-anything || echo .ua)" ` This keeps the legacy .understand-anything/ directory when it already exists (existing projects keep working with no migration) and uses the new .ua/ otherwise. Because each phase may run in a fresh shell, treat $UA_DIR — like $PROJECT_ROOT` — as a value you carry forward and substitute; re-resolve it with the line above if a later command block needs it in a new shell.
- Get the current git commit hash:
``bash git rev-parse HEAD ``
- Create the intermediate and temp output directories:
``bash mkdir -p "$UA_DIR/intermediate" mkdir -p "$UA_DIR/tmp" ` 3.1. **Purge stale trash dirs.** Phase 7 cleanup mvs scratch dirs into .trash-<timestamp>/ rather than rm -rfing them directly (see issue #301), so that destructive-action gates on hardened hosts don't trip on just-created paths. Reclaim the space here once the trash is older than 7 days — by this point any freshness-window check has long since stopped caring about those dirs: `bash find "$UA_DIR/" -maxdepth 1 -type d -name '.trash-*' -mtime +7 -exec rm -rf {} + 2>/dev/null || true `` 3.5. Auto-update configuration:
- If
--auto-updateis in$ARGUMENTS: write{"autoUpdate": true}to$UA_DIR/config.json - If
--no-auto-updateis in$ARGUMENTS: write{"autoUpdate": false}to$UA_DIR/config.json - These flags only set the config — analysis proceeds normally regardless.
3.6. Language configuration:
- Parse
$ARGUMENTSfor--language <lang>flag. If found, extract the language code. - Language code normalization: Map friendly names to ISO codes:
chinese→zh,japanese→ja,korean→ko,english→en,spanish→es,french→fr,german→de,portuguese→pt,russian→ru,vietnamese→vi,arabic→ar, etc.- Locale variants:
zh-TW,zh-HK,zh-CN,pt-BR, etc. are preserved as-is. - If
--languageis NOT specified: - Stored preference wins. If
$UA_DIR/config.jsonhas anoutputLanguagefield, set$OUTPUT_LANGUAGEto it and skip the rest. - Otherwise detect (first run only). Infer the predominant language of the user's conversation as an ISO 639-1 code (
$DETECTED_LANG). If it isenor cannot be confidently determined, set$OUTPUT_LANGUAGE=enand proceed silently — no prompt (English users see no change). - If `$DETECTED_LANG` ≠ `en`, confirm once before analyzing: tell the user you detected
<language>and ask whether to generate all content in it; they press Enter/"yes" to accept, or type another language code/name to override (normalize via the friendly-name map above). If running non-interactively (no reply possible), skip the wait, use$DETECTED_LANG, and print a one-line notice instead of blocking. - Persist the resolved
$OUTPUT_LANGUAGE(includingen) intoconfig.jsonso it never re-prompts for this project. - If
--languageIS specified: - Update
$UA_DIR/config.jsonwith the new language: merge{"outputLanguage": "<lang>"}into existing config. - Store as
$OUTPUT_LANGUAGEfor use throughout all phases. - Language directive template: Store as
$LANGUAGE_DIRECTIVE:
``markdown > **Language directive**: Generate all textual content (summaries, descriptions, tags, titles, languageNotes, languageLesson) in **{language}**. Maintain technical accuracy while using natural, native-level phrasing in the target language. Keep technical terms in English when no standard translation exists (e.g., "middleware", "hook", "barrel"). ``
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingunderstand-anything-plugin/skills/understand/SKILL.md
Popularity
- Repository stars
- 75,097
- Repository forks
- 6,251
- 7-day trend score
- 56
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 12 Oct 2026, 15 days ago.
Extension points
configConfiguration overrides
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/lum1104/understand-anything/understand)