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
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)
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):
## 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
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
{"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.