# Xp Index

> Sets up the XP database (.xp/db.jsonl) and indexes the entire codebase in a fast first pass — one candidate entry per file, for immediately visible value. Use it with /xp-index, or when a repo has no .xp/db.jsonl yet, or when a fresh codebase needs to be fully onboarded into the XP system.

- Skill: `opahimmel/xp-index` (Agent Skill)
- Install (CLI): `npx skillmds@latest add opahimmel/xp-index`
- Raw SKILL.md: https://api.skillmd.com/api/skills/opahimmel/xp-index/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: opahimmel (https://skillmd.com/u/opahimmel)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/opahimmel/xp-index

---


# xp-index

Replaces `xp-setup` + `xp-scan` as a single pass: set up the infrastructure, then
immediately go for broad coverage instead of deep single-file analysis. Goal of
pass 1: every file has an entry before time flows into depth.

## Check the precondition

```bash
ls .xp/db.jsonl 2>/dev/null
```

Already exists → proceed to pass 1 (append/update instead of creating new).
Doesn't exist → set up first.

## Setup (one-time)

```bash
mkdir -p .xp
```

Create an empty `db.jsonl`. No example entry.

If `CLAUDE.md` exists at the repo root, append the following section (otherwise
create it):

```markdown
## XP Database

If `.xp/db.jsonl` exists:

- Before the first file lookup: `grep -i "<task-keyword>" .xp/db.jsonl`
- Read the entry and treat it as established knowledge — don't re-derive it
```

## Pass 1 — breadth before depth

### 1. Map the codebase

```bash
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.py" -o -name "*.go" -o -name "*.rs" \) \
  ! -path "*/node_modules/*" ! -path "*/.xp/*" ! -path "*/dist/*" ! -path "*/build/*" ! -path "*/__pycache__/*" \
  | sort
```

Load existing entries: `cat .xp/db.jsonl 2>/dev/null` — skip files whose
`file_hash` is unchanged.

### 2. Derive domains

Group by directory structure, one domain prefix per group (`auth`, `ui`, `api`,
`store`, `util` …). Flat structure → use the filename as the domain. Don't force
a scheme — adapt to the project's structure.

### 3. Exactly one candidate per file

No symbol sweep per file. For each file: pick the **one** element with the
greatest semantic weight (the main export, the central class/function, the core
data structure) and write one entry for it. Everything else in the file is left
for a later, deeper pass.

**Skip a file (no entry) if:**
- it's a test file, generated code, or a pure re-export
- the file has no standalone semantic weight (e.g. only type aliases, a barrel file)

### 4. Entry format

```json
{"id": "domain:slug", "keywords": ["natural-language", "search", "terms"], "note": "Semantic role. Connections + why. Traps or implicit contracts.", "files": ["src/relevant.ts"], "file_hash": "abc123", "updated": "YYYY-MM-DD"}
```

The note answers in one or two sentences: what it semantically is, what it's
connected to, what isn't in the code (traps, implicit contracts).

`keywords` — **this is the only search surface**. Lookup relies exclusively on
this field. Anything missing here is never found. Write keywords from both
directions: how someone would describe the symptom or the task — AND how the
code names it. The user knows one, the agent knows the other. Both belong in
the same array. Goal: a search for `"ordering"` hits the entry
`sequencer:resolve-chain`, a search for `"renderImageSequences"` hits the same
entry. At least 3, at most 8 keywords per entry.

File hash: `git hash-object <file>`

### 5. Order

Go domain by domain. Within a domain: file by file, one entry, move on — don't
pause for completeness within a single file.

### 6. Completion report

```
XP-Index pass 1 complete
──────────────────────────────
Files scanned:    142
New entries:       98
Updated entries:    6
Skipped:           38

Domains: auth (12), ui (34), api (21), store (18), util (13)
```

List all new entries compactly — id + first half of the note.

## After this

Further symbols per file (pass 2, depth) or individual knowledge infusions run
through `/xp-update` — not part of this skill.

