How We Dogfood Travsr on the Travsr Repo
We index our own Rust workspace with Travsr and use it every day to answer questions like "what calls this function?" Here's what that workflow looks like.
At Travsr, we eat our own cooking. The entire Travsr-com/travsr Rust workspace is indexed by Travsr and we use it continuously during development. This post walks through what that actually looks like in practice.
The setup
After every commit to the main repo, the git post-commit hook triggers travsr hook-run. The graph, stored in SQLite, updates incrementally on the changed files. Claude Desktop has Travsr wired as an MCP source via the local stdio transport:
{
"mcpServers": {
"travsr": {
"command": "travsr",
"args": ["mcp", "--stdio"]
}
}
}
No server to start. No API key. Just a running daemon.
Real queries we run every day
Before touching a crate: get_blast_radius("crates/travsr-retrieval/src/bfs.rs"): tells us which downstream crates will be affected by changes to the BFS module. This short-circuits a lot of “I wonder if this change breaks anything” speculation.
When reviewing a PR: get_callers("RetrievalEngine::query"): returns every call site of that method across the whole workspace. Reviewers can see exactly where the interface is used before approving a signature change.
When adding a new MCP tool: get_dependencies("crates/travsr-mcp/src/tools/get_context.rs", transitive: true): the full transitive import graph tells us exactly what the new tool depends on.
What we’ve caught with it
- A circular dependency introduced between
travsr-retrievalandtravsr-storeduring a refactor: caught byget_dependenciesbefore it hit CI. - A dead call path in the PCST implementation that no longer had any callers after a module rename:
get_callersreturned an empty list, flagging the code for removal. - A missing integration test:
get_blast_radiuson a core type showed 6 downstream consumers with no corresponding test coverage.
The honest part
As of v0.5.1, the graph is complete for TypeScript and Rust with full semantic edges. Python semantic enrichment via pyright is live and ships with the daemon; it runs best-effort and falls back to the structural graph if pyright isn’t on your PATH. Go has full Tree-sitter structural coverage (imports, definitions, function signatures); the gopls semantic pass for call and reference edges is deferred to Phase 4.
Some queries (particularly get_execution_path for deeply nested call chains) can return false negatives until PCST is fully tuned on larger graphs.
We use it anyway. Even a structural BFS graph without full semantic edges is more useful than guessing from chunks.
Interested in trying it yourself? npm install -g @travsr.com/travsr && travsr init from your repo root gets you indexed in about 30 seconds on a mid-sized codebase.