# Skill Surface: /understand, /understand-chat, /understand-diff & Hooks

> Eight skills are exposed: /understand (full graph build), /understand-dashboard (opens dashboard), /understand-chat (Q&A against the graph using context-builder.ts), /understand-diff (change analysis via diff-analyzer.ts), /understand-explain (node explanation via explain-builder.ts), /understand-onboard (onboarding guide via onboard-builder.ts), /understand-domain, and /understand-knowledge. The @understand-anything/skill package exports typed builders consumed by the chat/diff/explain/onboard skills. Hooks (hooks.json) fire PostToolUse on git commit to trigger auto-update and a PreToolUse hook to auto-update before /understand-chat responses. Agent models are all set to inherit for cross-platform compatibility.

- Repository: Lum1104/Understand-Anything
- GitHub: https://github.com/Lum1104/Understand-Anything
- Human wiki: https://grok-wiki.com/public/wiki/lum1104-understand-anything-3b923df96896
- Complete Markdown: https://grok-wiki.com/public/wiki/lum1104-understand-anything-3b923df96896/llms-full.txt

## Source Files

- `understand-anything-plugin/src/index.ts`
- `understand-anything-plugin/src/context-builder.ts`
- `understand-anything-plugin/src/diff-analyzer.ts`
- `understand-anything-plugin/src/explain-builder.ts`
- `understand-anything-plugin/src/onboard-builder.ts`
- `understand-anything-plugin/hooks/hooks.json`
- `understand-anything-plugin/skills/understand-chat/SKILL.md`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:

- [understand-anything-plugin/src/index.ts](understand-anything-plugin/src/index.ts)
- [understand-anything-plugin/src/context-builder.ts](understand-anything-plugin/src/context-builder.ts)
- [understand-anything-plugin/src/diff-analyzer.ts](understand-anything-plugin/src/diff-analyzer.ts)
- [understand-anything-plugin/src/explain-builder.ts](understand-anything-plugin/src/explain-builder.ts)
- [understand-anything-plugin/src/onboard-builder.ts](understand-anything-plugin/src/onboard-builder.ts)
- [understand-anything-plugin/hooks/hooks.json](understand-anything-plugin/hooks/hooks.json)
- [understand-anything-plugin/hooks/auto-update-prompt.md](understand-anything-plugin/hooks/auto-update-prompt.md)
- [understand-anything-plugin/skills/understand/SKILL.md](understand-anything-plugin/skills/understand/SKILL.md)
- [understand-anything-plugin/skills/understand-chat/SKILL.md](understand-anything-plugin/skills/understand-chat/SKILL.md)
- [understand-anything-plugin/skills/understand-diff/SKILL.md](understand-anything-plugin/skills/understand-diff/SKILL.md)
- [understand-anything-plugin/skills/understand-explain/SKILL.md](understand-anything-plugin/skills/understand-explain/SKILL.md)
- [understand-anything-plugin/skills/understand-onboard/SKILL.md](understand-anything-plugin/skills/understand-onboard/SKILL.md)
- [understand-anything-plugin/skills/understand-dashboard/SKILL.md](understand-anything-plugin/skills/understand-dashboard/SKILL.md)
- [understand-anything-plugin/skills/understand-domain/SKILL.md](understand-anything-plugin/skills/understand-domain/SKILL.md)
- [understand-anything-plugin/skills/understand-knowledge/SKILL.md](understand-anything-plugin/skills/understand-knowledge/SKILL.md)
</details>

# Skill Surface: /understand, /understand-chat, /understand-diff & Hooks

The `@understand-anything/skill` package exposes eight slash commands (skills) that cover the full lifecycle of working with a codebase knowledge graph: building the graph, querying it conversationally, analyzing diffs, explaining individual components, generating onboarding guides, visualizing a business domain model, and indexing an LLM wiki. Each skill is a SKILL.md prompt file consumed directly by the AI runtime; the four chat/diff/explain/onboard skills additionally delegate heavy graph-query logic to typed TypeScript builder functions exported from `src/index.ts`, keeping the prompt logic thin and the computation testable.

A `hooks.json` file wires two lifecycle hooks into the AI runtime so that the knowledge graph stays current without user intervention: a `PostToolUse` hook fires whenever a `git commit/merge/cherry-pick/rebase` is detected and triggers an incremental auto-update, and a `SessionStart` hook compares the stored git commit hash against `HEAD` and triggers the same update if they diverge. All agent models referenced across every skill are set to `inherit`, making the entire skill surface portable across Claude Code, Cursor, opencode, and any other compatible runtime.

---

## Skill Inventory

| Skill | Trigger | What it does | Backed by |
|---|---|---|---|
| `/understand` | User-invoked | Full or incremental graph build | 7-phase pipeline with subagents |
| `/understand-dashboard` | Auto after `/understand` | Starts Vite dev server with tokenized URL | `packages/dashboard/` |
| `/understand-chat` | User-invoked | Q&A against the graph | `context-builder.ts` |
| `/understand-diff` | User-invoked | Change/PR impact analysis | `diff-analyzer.ts` |
| `/understand-explain` | User-invoked | Deep-dive on a file or function | `explain-builder.ts` |
| `/understand-onboard` | User-invoked | Markdown onboarding guide | `onboard-builder.ts` |
| `/understand-domain` | User-invoked | Business domain flow graph | `domain-analyzer` agent |
| `/understand-knowledge` | User-invoked | Karpathy LLM wiki graph | `article-analyzer` agent |

---

## `/understand` — Graph Build Pipeline

`/understand` is the root skill. It produces `.understand-anything/knowledge-graph.json` and then automatically triggers `/understand-dashboard`.

### Options

| Flag | Effect |
|---|---|
| `--full` | Force complete rebuild, ignoring existing graph |
| `--auto-update` | Write `autoUpdate: true` to `config.json` (enables hook-driven incremental updates) |
| `--no-auto-update` | Write `autoUpdate: false` to `config.json` |
| `--review` | Use the LLM `graph-reviewer` agent instead of inline deterministic validation |
| `--language <lang>` | Output summaries/tags in a specific language (ISO 639-1 or friendly name); persisted to `config.json` |
| `<path>` | Analyze a different directory; git worktrees are redirected to the main repo root |

### Seven-Phase Pipeline

```text
Phase 0    Pre-flight: resolve PROJECT_ROOT, detect worktree, build core if needed,
           check auto-update config, merge subdomain graphs
Phase 0.5  .understandignore setup (user-confirmed)
Phase 1    SCAN — project-scanner agent: file tree, language/framework detection,
           importMap, fileCategory per file
Phase 2    ANALYZE — up to 5 concurrent file-analyzer subagents (batches of 25 files);
           merge-batch-graphs.py normalizes IDs and linkes tested_by edges
Phase 3    ASSEMBLE REVIEW — assemble-reviewer agent validates cross-batch consistency
Phase 4    ARCHITECTURE — architecture-analyzer agent; language/framework context injected
Phase 5    TOUR — tour-builder agent; README and entry point injected as context
Phase 6    REVIEW — inline deterministic Node.js validator (or LLM graph-reviewer with --review)
Phase 7    SAVE — write knowledge-graph.json, build fingerprints baseline, write meta.json,
           clean intermediate files, auto-launch dashboard
```

The decision logic in Phase 0 determines whether to run a full analysis, incremental update, or review-only:

- **No existing graph** → full analysis (all phases)
- **Existing graph + same commit hash** → ask user (rebuild / review / nothing)
- **Existing graph + changed files** → incremental: only re-analyze changed files, then re-run architecture/tour
- **`--full`** → always full analysis

Sources: [understand-anything-plugin/skills/understand/SKILL.md:143-153]()

### Knowledge Graph Schema

The output JSON has a fixed schema validated in Phase 6. Key shapes:

| Section | Contents |
|---|---|
| `project` | name, description, languages, frameworks, analyzedAt, gitCommitHash |
| `nodes[]` | id, type (13 types), name, filePath, summary, tags, complexity, languageNotes? |
| `edges[]` | source, target, type (26 types), direction, weight |
| `layers[]` | id, name, description, nodeIds[] |
| `tour[]` | order, title, description, nodeIds[], languageLesson? |

Node ID conventions: `file:<path>`, `function:<path>:<name>`, `class:<path>:<name>`, `config:<path>`, `document:<path>`, `service:<path>`, etc.

Sources: [understand-anything-plugin/skills/understand/SKILL.md:751-789]()

---

## The `@understand-anything/skill` Package

The TypeScript source under `understand-anything-plugin/src/` exports four typed builder functions consumed by the chat, diff, explain, and onboard skill prompts. This separates testable computation from prompt text.

```typescript
// understand-anything-plugin/src/index.ts
export { buildChatContext, formatContextForPrompt, type ChatContext } from "./context-builder.js";
export { buildChatPrompt } from "./understand-chat.js";
export { buildDiffContext, formatDiffAnalysis, type DiffContext } from "./diff-analyzer.js";
export { buildExplainContext, formatExplainPrompt, type ExplainContext } from "./explain-builder.js";
export { buildOnboardingGuide } from "./onboard-builder.js";
```

Sources: [understand-anything-plugin/src/index.ts:1-17]()

---

## `/understand-chat` — Graph Q&A

`/understand-chat [query]` answers freeform questions about the codebase by searching the knowledge graph rather than reading source files directly.

### How the Skill Prompt Works

1. Verify `.understand-anything/knowledge-graph.json` exists (fail fast if not)
2. Grep the graph for the user's query keywords in `"name"`, `"summary"`, and `"tags"` fields — avoiding loading the full JSON into context
3. For each matched node ID, grep edges to build the 1-hop subgraph
4. Grep `"layers"` to find which architectural layers the matched nodes belong to
5. Answer using only the relevant subgraph, referencing specific files, functions, and relationships

Sources: [understand-anything-plugin/skills/understand-chat/SKILL.md:25-54]()

### `context-builder.ts` — The Backing Library

The `buildChatContext` function is the programmatic equivalent of the skill's grep-based approach. It uses `SearchEngine` from `@understand-anything/core` to search nodes, then expands one hop via edges, and collects all layers that contain any expanded node:

```typescript
// understand-anything-plugin/src/context-builder.ts:25-79
export function buildChatContext(graph, query, maxNodes): ChatContext {
  const engine = new SearchEngine(graph.nodes);
  const searchResults = engine.search(query, { limit: maxNodes ?? 15 });

  // 1-hop expansion via edges
  const expandedIds = new Set(matchedIds);
  for (const edge of graph.edges) {
    if (matchedIds.has(edge.source)) expandedIds.add(edge.target);
    if (matchedIds.has(edge.target)) expandedIds.add(edge.source);
  }

  // Collect edges where both endpoints are in the expanded set
  // Collect layers containing any expanded node
  return { projectName, projectDescription, relevantNodes, relevantEdges, relevantLayers, query };
}
```

`formatContextForPrompt` then serializes the `ChatContext` into markdown sections (Project header, Relevant Layers, Code Components, Relationships) suitable for LLM consumption.

Sources: [understand-anything-plugin/src/context-builder.ts:25-147]()

---

## `/understand-diff` — Change Impact Analysis

`/understand-diff` maps git diffs onto the knowledge graph to identify changed components, downstream blast radius, affected architectural layers, and risk level.

### Skill Prompt Workflow

1. Get changed files: `git diff --name-only` (uncommitted) or `git diff main...HEAD --name-only` (branch)
2. Grep the graph for nodes whose `filePath` matches each changed file
3. Grep edges for 1-hop neighbors (upstream callers and downstream dependencies)
4. Identify affected layers
5. Produce a structured report: Changed Components, Affected Components, Affected Layers, Risk Assessment
6. Write `.understand-anything/diff-overlay.json` so the dashboard can highlight changed/affected nodes visually

Sources: [understand-anything-plugin/skills/understand-diff/SKILL.md:29-70]()

### `diff-analyzer.ts` — The Backing Library

`buildDiffContext` maps file paths to graph nodes (also pulling in `contains`-edge children of matched file nodes), finds 1-hop affected neighbors, and computes a `DiffContext`:

```typescript
// understand-anything-plugin/src/diff-analyzer.ts:22-88
export function buildDiffContext(graph, changedFiles): DiffContext {
  // Map files → node IDs; track unmappedFiles for newly created/deleted files
  // Expand via "contains" edges (e.g., a file node → its function nodes)
  // Find 1-hop affected nodes and the impacted edges
  // Identify affected layers from union of changed + affected node IDs
  return { changedFiles, changedNodes, affectedNodes, impactedEdges, affectedLayers, unmappedFiles };
}
```

`formatDiffAnalysis` produces a risk-scored markdown report. The risk assessment heuristics are:

| Signal | Risk indicator |
|---|---|
| Any `changedNodes` with `complexity === "complex"` | High complexity flag |
| `affectedLayers.length > 1` | Cross-layer impact flag |
| `affectedNodes.length > 5` | Wide blast radius flag |
| `unmappedFiles.length > 0` | New/untracked files flag |
| None of the above | Low risk |

Sources: [understand-anything-plugin/src/diff-analyzer.ts:160-194]()

---

## `/understand-explain` — Deep Component Explanation

`/understand-explain [file-path]` produces a thorough explanation of a single file or function by combining graph context with source file reading.

### Path Format Support

Both `src/auth.ts` (file) and `src/auth.ts:login` (file:function) are accepted. The skill prompt reads the actual source file in step 6, while steps 2-5 use only graph grep operations.

### `explain-builder.ts` — The Backing Library

`buildExplainContext` resolves `path:function` notation, falls back to file path matching, then collects child nodes (via `contains` edges), connected neighbors (1-hop, excluding children), all relevant edges, and the containing layer:

```typescript
// understand-anything-plugin/src/explain-builder.ts:22-103
export function buildExplainContext(graph, path): ExplainContext {
  // Parse "src/auth.ts:login" → filePath + funcName
  // targetNode → childNodes (contains edges) → connectedNodes (1-hop)
  // relevantEdges: all edges touching target or children
  // layer: first layer containing the target node ID
}
```

`formatExplainPrompt` serializes the result as a structured "Deep Dive" prompt with sections for Architectural Layer, Internal Components, Connected Components, Relationships, and Language Notes. When the target node is not found, it returns a diagnostic message explaining possible causes (not analyzed, renamed, or deleted).

Sources: [understand-anything-plugin/src/explain-builder.ts:22-196]()

---

## `/understand-onboard` — Onboarding Guide Generation

`/understand-onboard` synthesizes the knowledge graph into a standalone markdown document suitable for new team members.

### `onboard-builder.ts` — The Backing Library

`buildOnboardingGuide` reads the full graph and renders seven sections in order:

| Section | Source data |
|---|---|
| Project overview table | `graph.project` (languages, frameworks, node/edge counts, analyzedAt) |
| Architecture layers | `graph.layers` + node names from `graph.nodes` |
| Key Concepts | `graph.nodes` filtered to `type === "concept"` |
| Getting Started (Guided Tour) | `graph.tour` steps with ordered walkthrough and optional `languageLesson` |
| File Map | All `type === "file"` nodes with filePath, summary, complexity |
| Complexity Hotspots | `graph.nodes` filtered to `complexity === "complex"` |
| Footer | Version attribution |

```typescript
// understand-anything-plugin/src/onboard-builder.ts:7-124
export function buildOnboardingGuide(graph: KnowledgeGraph): string {
  // Project header table
  // Architecture section per layer (with member names resolved from nodes)
  // Key Concepts (concept-type nodes only)
  // Getting Started (tour steps, with languageLesson support)
  // File Map table
  // Complexity Hotspots list
  // Attribution footer referencing graph.version
}
```

The skill prompt (steps 8-10) instructs the AI to output clean markdown and offer to save it as `docs/ONBOARDING.md`.

Sources: [understand-anything-plugin/src/onboard-builder.ts:7-124](), [understand-anything-plugin/skills/understand-onboard/SKILL.md:43-54]()

---

## `/understand-dashboard` — Dashboard Launcher

`/understand-dashboard [project-path]` starts the Vite dev server for the React dashboard. It resolves `PLUGIN_ROOT` through a priority-ordered candidate list (`CLAUDE_PLUGIN_ROOT` → `~/.understand-anything-plugin` → self-relative symlink resolution → common clone paths), builds the core package if `dist/` is missing, then starts:

```bash
cd <dashboard-dir> && GRAPH_DIR=<project-dir> npx vite --host 127.0.0.1
```

The server prints a tokenized URL (`?token=<TOKEN>`) that must be passed to the user verbatim — the token gates access to the `/file-content.json` endpoint and is required to load graph data.

`/understand` automatically calls `/understand-dashboard` at the end of Phase 7 if graph validation passed.

Sources: [understand-anything-plugin/skills/understand-dashboard/SKILL.md:80-99]()

---

## `/understand-domain` — Business Domain Graph

`/understand-domain [--full]` extracts business domains, flows, and process steps — separate from the structural code graph.

- **Without `--full`**: if `knowledge-graph.json` exists, derives domain knowledge directly from it (no file scanning, cheap)
- **With `--full`** or no existing graph: runs a lightweight scan via `extract-domain-context.py`, which emits file tree, entry points (HTTP routes, CLI commands, event handlers, cron jobs), and file signatures — then dispatches a `domain-analyzer` agent

Output goes to `.understand-anything/domain-graph.json`. The dashboard detects this file and switches to the horizontal domain flow layout. The graph uses `kind: "knowledge"` to signal force-directed layout.

Sources: [understand-anything-plugin/skills/understand-domain/SKILL.md:89-141]()

---

## `/understand-knowledge` — Karpathy LLM Wiki Graph

`/understand-knowledge [wiki-directory]` targets a Karpathy-pattern LLM wiki (raw sources + wiki markdown with `[[wikilink]]` syntax + schema file + `index.md` + `log.md`).

The pipeline:
1. **DETECT**: `parse-knowledge-base.py` runs deterministic extraction: article nodes, source nodes, topic nodes, `related` edges from wikilinks, `categorized_under` edges from `index.md` section headings → `scan-manifest.json`
2. **ANALYZE**: `article-analyzer` subagents (batches of 10-15, up to 3 concurrent) extract implicit relationships not captured by wikilinks
3. **MERGE**: `merge-knowledge-graph.py` deduplicates entities, normalizes node/edge types, builds layers from `index.md` categories, builds tour from section ordering
4. **SAVE**: validates, writes `knowledge-graph.json`, auto-triggers `/understand-dashboard`

The `--full` flag is not applicable; a fresh run always re-parses.

Sources: [understand-anything-plugin/skills/understand-knowledge/SKILL.md:29-127]()

---

## Hooks: Automatic Graph Maintenance

Two hooks in `hooks.json` keep the knowledge graph current without user intervention.

### Hook Configuration

```json
// understand-anything-plugin/hooks/hooks.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "printf '%s' \"$TOOL_INPUT\" | grep -qE 'git\\s+(commit|merge|cherry-pick|rebase)' && [ -f .understand-anything/config.json ] && grep -q '\"autoUpdate\".*true' .understand-anything/config.json && [ -f .understand-anything/knowledge-graph.json ] && echo \"...\""
      }]
    }],
    "SessionStart": [{
      "hooks": [{
        "type": "command",
        "command": "... compare stored gitCommitHash with git rev-parse HEAD ..."
      }]
    }]
  }
}
```

Sources: [understand-anything-plugin/hooks/hooks.json:1-25]()

### Hook Behavior Table

| Hook | Trigger | Condition | Action |
|---|---|---|---|
| `PostToolUse` (Bash matcher) | Any Bash tool call containing `git commit/merge/cherry-pick/rebase` | `autoUpdate: true` in `config.json` AND `knowledge-graph.json` exists | Instructs AI to read `auto-update-prompt.md` and execute incremental update |
| `SessionStart` | Session begin | `autoUpdate: true` AND stored `gitCommitHash` ≠ `git rev-parse HEAD` | Same — triggers incremental update if graph is stale |

Both hooks are **guard-checked**: if `autoUpdate` is not `true` or no graph file exists, the hook outputs nothing (via `|| true`) and is a no-op.

### Auto-Update Pipeline (hooks/auto-update-prompt.md)

The hook-triggered update follows a four-phase, token-minimizing pipeline:

```text
Phase 0  Pre-flight — verify graph + meta exist; get git commit diff
         Apply .understandignore exclusions to the changed-file list
Phase 1  Structural Fingerprint Check (zero LLM tokens)
         Classify each changed file as NONE / COSMETIC / STRUCTURAL
         Decision: SKIP | PARTIAL_UPDATE | ARCHITECTURE_UPDATE | FULL_UPDATE
Phase 2  Targeted Re-Analysis (LLM tokens only for STRUCTURAL files)
         Dispatch file-analyzer subagents only for structurally changed files
         Merge new nodes/edges into existing graph (remove stale, add fresh)
Phase 3  Conditional architecture/tour update + save
         LOAD-PATCH-SAVE fingerprints (never overwrite — issue #152 guard)
         Clean intermediate files; report summary
```

The fingerprint check in Phase 1 classifies changes without LLM calls using regex extraction (functions, classes, imports, exports). Only Phase 2 spends LLM tokens, and only when structural signatures actually changed.

A critical correctness invariant: the fingerprint update in Phase 3 must **load all existing entries, patch only the re-analyzed files, and save the full dict back**. Overwriting with only the fresh batch causes every other file to appear as a new structural change on the next commit, escalating to `FULL_UPDATE` permanently (tracked as issue #152).

Sources: [understand-anything-plugin/hooks/auto-update-prompt.md:1-10](), [understand-anything-plugin/hooks/auto-update-prompt.md:94-149](), [understand-anything-plugin/hooks/auto-update-prompt.md:243-290]()

---

## Cross-Cutting Design Decisions

### Agent Model Inheritance

All agent definitions across every skill use `model: inherit`. This means the model used is whatever the host AI runtime (Claude Code, Cursor, opencode, etc.) is configured to use, with no hardcoded provider or model name anywhere in the skill surface. This makes the entire plugin BYOC/BYOK-friendly.

### Plugin Root Resolution

Every skill that needs to invoke scripts or agent definitions resolves `PLUGIN_ROOT` through the same priority list:

```text
1. $CLAUDE_PLUGIN_ROOT   (runtime-injected, highest priority)
2. ~/.understand-anything-plugin  (universal symlink)
3. Two levels up from ~/.agents/skills/<skill-name>  (self-relative)
4. Two levels up from ~/.copilot/skills/<skill-name>  (Copilot personal skills)
5. ~/.codex/.../understand-anything-plugin  (common clone paths)
6. ~/.opencode/.../  (opencode clone path)
7. ~/.pi/.../  (pi clone path)
8. ~/understand-anything/...  (home directory clone)
```

Failure to resolve any candidate causes an explicit error with all checked paths listed — no silent fallback.

### Graph-First, File-Second Query Pattern

The chat, diff, and explain skills follow a consistent strategy: **grep the graph first, read source files last (or not at all)**. This keeps most queries within a small subgraph context window rather than loading large source files. The `SearchEngine` (from `@understand-anything/core`) and grep-based approaches both implement the same 1-hop expansion logic: match by name/summary/tags, then expand via edges to neighbors.

### Worktree Redirect

`/understand` and `/understand-domain` both detect git worktrees by comparing `git rev-parse --git-dir` against `git rev-parse --git-common-dir`. When inside a worktree, output is redirected to the main repo root — worktree paths are ephemeral and would lose the graph when the session ends (tracked as issue #133). Set `UNDERSTAND_NO_WORKTREE_REDIRECT=1` to opt out.

Sources: [understand-anything-plugin/skills/understand/SKILL.md:33-53](), [understand-anything-plugin/skills/understand-domain/SKILL.md:22-43]()

---

## Summary

The eight skills form a layered system: `/understand` builds the graph that all other skills consume, `/understand-dashboard` visualizes it, and the query skills (`/understand-chat`, `/understand-diff`, `/understand-explain`, `/understand-onboard`) extract actionable knowledge from the graph without re-reading source files. Two domain-specific skills (`/understand-domain`, `/understand-knowledge`) extend the graph model to business flows and LLM wikis respectively. The hooks system closes the loop by keeping the graph synchronized with every commit automatically, spending zero LLM tokens on cosmetic-only changes and targeting only structurally changed files when real changes occur. Sources: [understand-anything-plugin/hooks/auto-update-prompt.md:4-6]()
