Files
codegraph/run-interactive-test.md
T
Colby McHenry 7fe64b32be feat(eval): add agent-eval harness and /audit + /publish Claude skills
Replaces the old interactive publish.js script with two Claude skills and
a full agent-evaluation harness:

- `.claude/skills/audit/` — `/audit` skill drives `scripts/agent-eval/audit.sh`
  to benchmark retrieval quality (with vs. without codegraph) on a chosen
  real-world repo from the new `corpus.json` (17 repos across 14 languages).
- `.claude/skills/publish/` — `/publish` skill orchestrates the full release
  workflow (preflight → changelog → confirmation gate → bump/build → npm
  publish → GitHub release), replacing `publish.js`.
- `scripts/agent-eval/` — headless (`run-agent.sh`, `run-all.sh`) and
  interactive tmux (`itrun.sh`) harnesses with stream-json parsers
  (`parse-run.mjs`, `parse-session.mjs`) that report tool calls, token
  usage, and a VERDICT line summarising codegraph_explore vs. Read/Grep counts.
- `run-interactive-test.md` — documents the two harnesses, idle-detection
  approach, and what "good" agent behavior looks like after explore-first
  guidance.
2026-05-20 09:39:17 -05:00

132 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Running the agent-behavior test (how agents actually use codegraph)
This explains how to measure **how a Claude Code agent uses the codegraph MCP
tools** on a real repo — which tools it calls (does it lead with
`codegraph_explore`?), how many follow-up `Read`/`Grep`s it does, and the token
cost. Use it when changing tool guidance (`server-instructions.ts`,
`instructions-template.ts`, tool descriptions) or retrieval, to verify the
change actually shifts agent behavior.
Scripts live in `scripts/agent-eval/`.
## Why two harnesses (read this first)
| | Interactive (`itrun.sh`) | Headless (`run-agent.sh`) |
|---|---|---|
| Drives | the real TUI via tmux | `claude -p` print mode |
| Subagent it picks | **Explore** (matches real UX) | general-purpose (diverges) |
| Metrics | tool breakdown (from session logs) + `Done(…)` token summary | exact per-tool calls + tokens/cost (stream-json) |
| Cost | Claude Max subscription | API $ (`total_cost_usd`) |
**Headless `claude -p` does NOT reproduce what users see** — it silently picks
the general-purpose subagent, while interactive sessions delegate to the
read-first **Explore** subagent. So for "what does my session actually do," use
the interactive harness. For a clean per-tool/token breakdown in one shot, use
headless (and ask for the Explore subagent in the prompt if you want that path).
## Prerequisites
- **tmux 3.0+**
- A logged-in `claude` CLI (Claude Max or API).
- codegraph configured as an MCP server (`claude mcp list` shows `codegraph`).
The interactive harness uses your global config, so it runs whatever
`codegraph` resolves to — point that at your dev build (`npm link` / the
symlinked global) to test local changes.
- A target repo, cloned and indexed:
```bash
git clone --depth 1 https://github.com/square/okhttp /tmp/corpus/okhttp
cd /tmp/corpus/okhttp && codegraph init -i
```
Good scale spread for a sweep: Alamofire (~100 files), Excalidraw (~600),
OkHttp (~640), VS Code (~10k).
## Interactive test (the faithful one)
```bash
scripts/agent-eval/itrun.sh <repo-path> <label> "<question>"
```
Example:
```bash
scripts/agent-eval/itrun.sh /tmp/corpus/vscode vscode \
"How does the extension host communicate with the main process?"
```
It opens `claude` in a tmux session, types the question, waits for the agent to
finish, then prints:
- the `Done (N tool uses · Xk tokens · Ym)` subagent summary (from the pane),
- the `Context Xk/1.0M` main-session size,
- a **tool breakdown** parsed from the session logs (main + subagents), ending
in a `VERDICT: codegraph_explore used Nx | Read N | Grep/Bash N` line.
### Startup robustness (so unattended runs don't silently no-op)
Two things bite an unattended driver before the prompt even runs:
- **The `` glyph is drawn ~6s before the input accepts keystrokes.** Waiting
for `` is necessary but not sufficient. The harness sends the prompt, then
**verifies a chunk of it actually landed in the input box**, retrying until it
does — so it can't type into a not-yet-live input and submit nothing.
- **First time claude opens a repo it shows "Is this a project you trust?"**
(which also contains ``). The harness detects that dialog and presses Enter
to accept it before typing.
If the prompt never lands or work never starts, the harness now **fails loudly**
(non-zero exit) instead of capturing an empty pane and reporting a bogus run.
### How completion is detected (the tricky part)
Claude's TUI redraws in place, so you can't just wait for output to stop. The
harness polls `tmux capture-pane` and treats the pane as **busy** when it shows
the spinner's elapsed-time-in-parens — `(8s · …)` / `(1m 3s · …)`, matched by
`\(([0-9]+m )?[0-9]+s ·`. That's the *universal* working signal: it shows during
the pre-stream **thinking** phase (`(8s · thinking with max effort)`, which has
no token arrow yet) *and* during streaming. The `↓ N`/`↑ N` token arrow,
`esc to interrupt`, and `Initializing…` are OR'd in as belt-and-braces (some TUI
versions show one but not the others). It declares **idle** when the `` prompt
is present and not busy for 10 consecutive polls (~5s, long enough to ride out
mid-conversation thinking gaps that briefly drop the spinner). (Technique
adapted from devpit's `WaitForIdle`.)
### Where the breakdown comes from
`parse-session.mjs` reads the newest session log under
`~/.claude/projects/<escaped-cwd>/<session>.jsonl` and its subagent transcripts
under `<session>/subagents/*.jsonl`. The **subagent** file is where the real
tool calls are — the main log only shows the `Agent` delegation. You can run it
standalone:
```bash
node scripts/agent-eval/parse-session.mjs /tmp/corpus/vscode
```
## Headless test (clean tokens, forceable Explore path)
```bash
scripts/agent-eval/run-agent.sh <repo-path> <label> "<question>"
```
Writes stream-json and prints the tool sequence + exact tokens/cost. To
reproduce the Explore-subagent path headlessly, ask for it:
`"Use an Explore subagent to investigate, then answer: …"`.
## Running a sweep
Single runs vary a lot (the VS Code question has ranged 2637 tool uses /
88105k tokens across runs). For a real signal, run N≥3 and take the median:
```bash
for i in 1 2 3; do
scripts/agent-eval/itrun.sh /tmp/corpus/vscode "vscode-$i" "<question>"
done
```
## What "good" looks like
After the explore-first guidance (PR #191), an understanding question should
show the agent **leading with `codegraph_explore`** and using `search`/`node`
to fill gaps — not a wall of `Read`/`Grep`. Example faithful run:
`VERDICT: codegraph_explore used 3x | Read 8 | Grep/Bash 1`. If `explore` is 0
and `Read`/`Grep` dominate, the guidance regressed.
## Output artifacts
Transcripts and logs go to `$AGENT_EVAL_OUT` (default `/tmp/agent-eval/`):
`itrun-<label>.txt` (pane capture), `run-<label>.jsonl` (headless stream-json).