dox-describe
SkillFiles & storageLets your agent fill empty Purpose cells in a directory's AGENTS.md tree with one-line file summaries.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the dox-describe skill
About this capability
Fill the empty Purpose cells of a directory `AGENTS.md` tree with one-line LLM summaries (one subagent per file, plan-then-confirm, cap 50 rows/run). Use for a path-only `kb dox init` tree, or when asked to "describe the tree", "fill AGENTS.md purposes", or "populate the kb corpus".
What this skill tells your AI
The instructions your AI receives, as published by blackbelttechnology/pi-agent-dashboard in packages/kb-extension/.pi/skills/dox-describe/SKILL.md and read by ahel’s review.
Turn a path-only directory AGENTS.md tree into a searchable kb corpus. A fresh
kb dox init tree carries rows shaped | `file.ts` | | — the Purpose cell is
empty, so the agents retrieval lane (the one file-lookup queries depend on)
finds nothing. This skill fills those cells with one-line, caveman-style
purposes, one subagent per AGENTS.md.
Read-only first: the CLI enumerates empty rows; the LLM only ever writes a
Purpose cell. The parent never edits an AGENTS.md itself, and a subagent edits
only the single file it was assigned.
Step 1 — enumerate the empty rows
kb dox describe --list --json
Parse { groups: [{ agentsPath, subjects: string[] }], total }. Each group is
one AGENTS.md; each subject is a path whose Purpose cell is empty. Nothing to
do when total === 0 — say so and stop.
Step 2 — present the plan and confirm
Show the user, then WAIT (ask_user, confirm) for approval before any write:
- number of
AGENTS.mdfiles (groups) and number of rows (total); - a rough cost estimate (≈ rows × one short file read, plus one subagent per group; state it is a rough bound, not a promise);
- the per-run cap: 50 rows. Rows beyond the cap are DEFERRED to a re-run (the walk is empty-cells-only, so a re-run is resumable by construction);
- any row whose subject file is missing or unreadable (report, do not assign).
Never start fan-out without an explicit yes.
Step 3 — fan out ONE subagent per AGENTS.md
Cap concurrency at 2 in flight (the extension schedules a debounced reindex
on every markdown write, and every subagent contends on the single SQLite index;
≤2 keeps SQLITE_BUSY recoverable — the parent's final reindex is
authoritative). Skip groups whose rows are entirely past the cap.
Spawn with an inline Agent label (write-capable, parent defaults). Do NOT use
Explore — it is read-only and cannot fill cells.
Each subagent's task must include:
- the absolute
AGENTS.mdpath and its assigned subjects (cap 50 total across all groups for this run); - must read every file it describes — never guess from the filename;
- the row rules:
- ONE line per row, exactly the schema
| `file` | purpose |; - purpose ≤ 200 chars, caveman style: short declarative fragments, drop articles/copulas, subject → verb → object;
- name key exports / contracts / params verbatim (
symbolName, paths, env vars); concrete tokens over prose; - CONDENSE, never promote to a
<File>.AGENTS.mdsidecar — sidecar splitting is the parent's/scripts/split-large-agents.mjsjob; - edit ONLY its own
AGENTS.md; do not touch any other file; - write the purpose into the EXISTING row (same line, same path cell) — do not add, delete, or reorder rows;
- a subject file that cannot be read (missing, binary, 0-byte) → leave its Purpose cell EMPTY and report it back; never invent a purpose.
- ONE line per row, exactly the schema
Step 4 — verify, report, reindex
kb dox lint— must be clean. On a finding, hand it back to the subagent that owns thatAGENTS.mdto repair or revert its OWN file (the parent never edits a tree file). Re-run lint after the repair.- One final reindex so the new purposes are searchable:
(The extension's debounced reindex is best-effort under contention; this explicit pass is authoritative.)kb index - Report to the user: rows filled, rows deferred (cap), unreadable rows left
empty, and — when deferred > 0 — "run
dox-describeagain to fill the rest".
Re-running is idempotent: --list returns only rows still empty, so a second
run writes nothing when everything is filled.
Headless escape hatch
For very large trees (well past the 50-row cap), the plan-then-confirm loop is
boring to babysit. You may instead drive workers with parallel headless pi
processes (pi -p "<task>"), one per AGENTS.md, then run steps 4.1–4.3
yourself. This is an escape hatch, not the default: it skips the interactive
confirm, so the CALLER owns the cap and the kb dox lint gate.
Pitfalls
- Do NOT let a subagent "improve" neighbouring cells or reformat the table — the
parent's
--listwalk andkb dox lintboth depend on the exact row shape. - Do NOT fan out more than 2 at once — concurrent reindex writes can hit
SQLITE_BUSY. - A wrong-but-non-empty purpose is NOT revisited in v1 (no correctness oracle);
a
--stalerefresh mode is a follow-up. Read the file before describing it. - Never write a Purpose for a file you could not open — an empty cell is honest, a guessed one is rot.
Signals
- GitHub stars
- 292
- Forks
- 44
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
dox-describe- Source
- github.com/blackbelttechnology/pi-agent-dashboard