$npx -y skills add Egonex-AI/Understand-Anything --skill understand-domainExtract business domain knowledge from a codebase and generate an interactive domain flow graph. Works standalone (lightweight scan) or derives from an existing /understand knowledge graph.
| 1 | # /understand-domain |
| 2 | |
| 3 | Extracts business domain knowledge — domains, business flows, and process steps — from a codebase and produces an interactive horizontal flow graph in the dashboard. |
| 4 | |
| 5 | ## How It Works |
| 6 | |
| 7 | - If a knowledge graph already exists (`.ua/knowledge-graph.json`, or the legacy `.understand-anything/knowledge-graph.json` when that directory is present), derives domain knowledge from it (cheap, no file scanning) |
| 8 | - If no knowledge graph exists, performs a lightweight scan: file tree + entry point detection + sampled files |
| 9 | - Use `--full` flag to force a fresh scan even if a knowledge graph exists |
| 10 | |
| 11 | ## Instructions |
| 12 | |
| 13 | ### Phase 0: Resolve `PROJECT_ROOT` |
| 14 | |
| 15 | Set `PROJECT_ROOT` to the current working directory. |
| 16 | |
| 17 | **Worktree redirect.** If `PROJECT_ROOT` is 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 domain graph with it (issue #133). Detect a worktree by comparing `git rev-parse --git-dir` against `git 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-dir` is the main repo root. |
| 18 | |
| 19 | ```bash |
| 20 | COMMON_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-common-dir 2>/dev/null) |
| 21 | GIT_DIR=$(git -C "$PROJECT_ROOT" rev-parse --git-dir 2>/dev/null) |
| 22 | if [ -n "$COMMON_DIR" ] && [ -n "$GIT_DIR" ]; then |
| 23 | COMMON_ABS=$(cd "$PROJECT_ROOT" && cd "$COMMON_DIR" 2>/dev/null && pwd -P) |
| 24 | GIT_ABS=$(cd "$PROJECT_ROOT" && cd "$GIT_DIR" 2>/dev/null && pwd -P) |
| 25 | if [ -n "$COMMON_ABS" ] && [ "$COMMON_ABS" != "$GIT_ABS" ]; then |
| 26 | MAIN_ROOT=$(dirname "$COMMON_ABS") |
| 27 | if [ -d "$MAIN_ROOT" ] && [ "${UNDERSTAND_NO_WORKTREE_REDIRECT:-0}" != "1" ]; then |
| 28 | echo "[understand-domain] Detected git worktree at $PROJECT_ROOT" |
| 29 | echo "[understand-domain] Redirecting output to main repo root: $MAIN_ROOT" |
| 30 | echo "[understand-domain] (Set UNDERSTAND_NO_WORKTREE_REDIRECT=1 to keep PROJECT_ROOT as the worktree.)" |
| 31 | PROJECT_ROOT="$MAIN_ROOT" |
| 32 | fi |
| 33 | fi |
| 34 | fi |
| 35 | ``` |
| 36 | |
| 37 | Use `$PROJECT_ROOT` (not the bare CWD) for every reference to "the current project" / `<project-root>` in subsequent phases. |
| 38 | |
| 39 | **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: |
| 40 | ```bash |
| 41 | UA_DIR="$PROJECT_ROOT/$([ -d "$PROJECT_ROOT/.understand-anything" ] && echo .understand-anything || echo .ua)" |
| 42 | ``` |
| 43 | 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, carry `$UA_DIR` forward like `$PROJECT_ROOT`, re-resolving it with the line above if a later command block needs it. |
| 44 | |
| 45 | **Important:** do **not** assume the plugin root is simply two directories above the skill path string. In many installations `~/.agents/skills/understand-domain` 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. |
| 46 | |
| 47 | Resolve the plugin root like this: |
| 48 | |
| 49 | ```bash |
| 50 | SKILL_REAL=$(realpath ~/.agents/skills/understand-domain 2>/dev/null || readlink -f ~/.agents/skills/understand-domain 2>/dev/null || echo "") |
| 51 | SELF_RELATIVE=$([ -n "$SKILL_REAL" ] && cd "$SKILL_REAL/../.." 2>/dev/null && pwd || echo "") |
| 52 | COPILOT_SKILL_REAL=$(realpath ~/.copilot/skills/understand-domain 2>/dev/null || readlink -f ~/.copilot/skills/understand-domain 2>/dev/null || echo "") |
| 53 | COPILOT_SELF_RELATIVE=$([ -n "$COPILOT_SKILL_REAL" ] && cd "$COPILOT_SKILL_REAL/../.." 2>/dev/null && pwd || echo "") |
| 54 | |
| 55 | PLUGIN_ROOT="" |
| 56 | for candidate in \ |
| 57 | "${CLAUDE_PLUGIN_ROOT}" \ |
| 58 | "$HOME/.understand-anything-plugin" \ |
| 59 | "$SELF_RELATIVE" \ |
| 60 | "$COPILOT_SELF_RELATIVE" \ |
| 61 | "$HOME/.codex/understand-anything/understand-anything-plugin" \ |
| 62 | "$HOME/.opencode/understand-anything/understand-anything-plugin" \ |
| 63 | "$HOME/.pi/understand-anything/understand-anything-plugin" \ |
| 64 | "$HOME/understand-anything/understand-anything-plugin"; do |
| 65 | if [ -n "$candidate" ] && [ -f "$candidate/package.json" ] && [ -f "$candidate/pnpm-workspace.yaml" ]; then |
| 66 | PLUGIN_ROOT="$candidate" |
| 67 | break |
| 68 | fi |
| 69 | done |
| 70 | |
| 71 | if [ -z "$PLUGIN_ROOT" ]; then |
| 72 | echo "Error: Cannot find the understand-anything plugin root." |
| 73 | echo "Checked:" |
| 74 | echo " - ${CLAUDE_PLUGIN_ROOT:-<unset CLAUDE_PLUGIN_ROOT>}" |
| 75 | echo " - $HOME/.understand-anything-plugin" |
| 76 | echo " - ${SELF_RELATIVE:-<unresolved path |