rtk reach — proposed feature for rtk-ai/rtk
A complement to rtk discover that answers a different question:
Of the LLM input tokens Claude Code is actually consuming, what fraction is even reachable by RTK in the first place?
rtk discover already tells you which Bash commands RTK can compress. But
it only sees Bash. Claude Code's built-in Read, Grep, and Glob tools
go around the Bash hook entirely — and on real workloads they often produce
the largest share of tool-result tokens. Without a view that includes them,
it's hard to set realistic expectations for how much RTK can actually save
per session.
This repo contains a Python prototype that produces that view today, plus a proposal for landing it as a Rust subcommand inside RTK.
For every Claude Code session JSONL under ~/.claude/projects/, the script:
- Walks
assistantevents to map eachtool_use_idto its tool name and (for Bash) the original command string. - Walks
userevents to find eachtool_result, looks up the matching tool name, and attributes the result's text size to it. - For Bash specifically, splits results into:
- rtk-wrapped — command went through
rtk(hook fired, or Claude typedrtk …directly). - rtk-coverable — RTK has a wrapper for this command but the call didn't use it (would have, with the hook installed).
- other — RTK doesn't (yet) wrap this command.
- rtk-wrapped — command went through
- Aggregates per session and across all scanned sessions.
Token counts use the standard chars / 4 estimate; we also surface exact
billed-input numbers from the assistant usage blocks for sanity checking.
Headline
────────────────────────────────────────────────────────────────
Bash share of tool results: 30.2%
RTK active on Bash output: 7.2%
RTK reachable on Bash output: 50.1%
RTK reachable on ALL tool results: 15.1%
The last line is the one that's hard to get from existing RTK commands: the ceiling on what RTK can save you for this workload.
See sample-output.txt for a full run.
Key insight from the sample: 42% of tool-result content was Read (which
bypasses RTK's Bash hook), so the RTK ceiling for that workflow was ~15%
— meaningful, but a long way from the README's headline 80%.
# Default: current project, last 7 days, text output
python3 rtk_reach.py
# All projects, last 30 days
python3 rtk_reach.py --all --since 30
# JSON for piping into dashboards
python3 rtk_reach.py --all --json | jq '.headline'
# Just one project (substring match against file path)
python3 rtk_reach.py --all --project finance-chatRequires Python ≥ 3.9. No external dependencies.
Three reasons:
- Closes the loop between RTK's existing analytics.
rtk gainshows what RTK saved.rtk discoverfinds Bash misses.rtk sessiontracks Bash adoption per session.rtk reachwould show what fraction of total context RTK has any shot at touching — a number every user wants to know before deciding whether RTK is worth installing for their workflow. - Sets honest expectations. The README's "60–90%" headline assumes a pure-Bash workflow. For typical Claude Code use, where Read/Grep dominate, the real ceiling is much lower — and users discover this only after install. Surfacing it up front is good UX.
- Cheap to ship. RTK already parses Claude session JSONL in
src/discover/provider.rs. The only change needed is to drop the Bash-only pre-filter and track per-tool aggregates. Seerust-integration-sketch.mdfor the rough shape.
- Sidechain (subagent) tool calls are inline in the same JSONL with
isSidechain: true. The prototype currently counts them with the main chain. A future flag could break them out. tool_result.contentimages are not measured (we only sum text). This understates reality slightly when Claude reads screenshots, but those don't go through RTK anyway.- Token estimate is
chars / 4. The billed-input numbers from the assistantusageblock are reported alongside as a cross-check. They won't match exactly because the billed numbers include system prompt, prior assistant messages, and cached prefix re-reads. RTK_COVERED_COMMANDSis hand-maintained against RTK's wrapper list. The Rust port should reusediscover::registry::classify_commandfor authoritative classification.
| File | Purpose |
|---|---|
rtk_reach.py |
The runnable Python prototype |
sample-output.txt |
Real output from a 6-session, 7-day scan |
rust-integration-sketch.md |
How a Rust port would integrate with discover/provider.rs |
ISSUE.md |
Issue body to file at github.com/rtk-ai/rtk/issues/new |
Same as RTK (Apache-2.0 / MIT dual). Contributions welcome.