Introduction

Defuse (pronounced “def-use”) is a simple utility for querying SCIP indexes. It gives you fast, deterministic answers about symbol relationships, call graphs, and change history in your codebase. It’s built on top of the SCIP indexers from Sourcegraph and gitoxide.

$ defuse resolve validate

lib/auth.ts::validate(token: Token) → string
lib/schema.ts::validate(input: FormData) → ValidationResult

SCIP indexers compile your source code into a portable symbol graph, and Defuse reads that graph and exposes it through a consistent CLI interface with fully qualified symbol names, structured JSON output, and no running language server required.

At Claybird (YC F25), we’ve found that coding agents like Claude Code and Codex perform significantly better when given access to a precise symbol graph rather than relying on text search and file reading alone.

Your codebase has two functions named validate. Claude Code uses ripgrep, which returns both, but Defuse doesn’t.

$ defuse symbols callers lib/auth.ts::validate

triggers/login.ts:14     const session = validate(token)
triggers/refresh.ts:8    const session = validate(token)
$ defuse impact lib/auth.ts::validate

lib/auth.ts::validate
├── triggers/login.ts::handleLogin
│   └── routes/auth.ts::POST /login
└── triggers/refresh.ts::handleRefresh
    └── routes/auth.ts::POST /refresh

lib/schema.ts::validate is not in this tree. It’s a different function.

Before touching a symbol you’ve never seen, defuse context gives you the full picture in one command.

$ defuse context lib/auth.ts::validate

Definition
  lib/auth.ts:3     export function validate(token: Token): string

Callers
  triggers/login.ts:14     const session = validate(token)
  triggers/refresh.ts:8    const session = validate(token)

Callees
  lib/jwt.ts::verify
  lib/cache.ts::lookup

Recent history
  abc123f  2 days ago   tighten token expiry check         Alice
  f9e01b2  11 days ago  add cache lookup before jwt parse  Alice
  3c8a77d  3 weeks ago  initial implementation             Bob

Installation

cargo install defuse

Getting started

Index your codebase. Defuse detects the languages in your repository and runs the appropriate SCIP indexers automatically.

cd your-project
defuse index

You’re ready to query.

# Resolve a name to its fully qualified symbol
defuse resolve "authenticate"
 
# Find where a symbol is defined
defuse symbols def src/auth/service.ts::AuthService::authenticate
 
# Find every reference to a symbol
defuse symbols refs src/auth/service.ts::AuthService::authenticate
 
# Find all callers of a function
defuse symbols callers src/auth/service.ts::AuthService::authenticate
 
# Understand the blast radius before a refactor
defuse impact src/auth/service.ts::AuthService::authenticate
 
# 360° view of a symbol before editing
defuse context src/auth/service.ts::AuthService::authenticate
 
# Git blame at a specific line
defuse blame src/auth/service.ts:42
 
# Full history of changes to a symbol
defuse history src/auth/service.ts::AuthService::authenticate
 
# What symbols changed in a commit
defuse diff --commit abc123f

All commands support --json for structured output.

Using with Claude Code

Add the following to your project’s CLAUDE.md:

CLAUDE.md
### Code navigation
 
ALWAYS use defuse before reading or editing any file you haven't seen yet.
NEVER use grep or glob to find symbol definitions, trace references, or analyze dependencies.
 
Key commands:
 
defuse resolve <n>               # resolve an ambiguous name to a fully qualified symbol
defuse symbols refs <symbol>        # find all references to a symbol
defuse symbols callers <symbol>     # find all callers of a function
defuse context <symbol>             # 360° view of a symbol before editing
defuse impact <symbol>              # understand blast radius before refactoring
defuse diff --commit <hash>         # what symbols changed in a given commit

Defuse always accepts fully qualified symbol names of the form file::Type::method. Use defuse resolve first when you have a short name and need to disambiguate.

CLI reference

defuse resolve <n>               # resolve a name to fully qualified symbol(s)

defuse symbols def <symbol>         # find the definition of a symbol
defuse symbols refs <symbol>        # find all references to a symbol
defuse symbols callers <symbol>     # find all callers of a function
defuse symbols callees <symbol>     # find all functions called by a symbol
defuse symbols impls <symbol>       # find all implementations of an interface or trait

defuse blame <file>:<line>          # git blame at a specific line
defuse history <symbol>             # full change history for a symbol
defuse diff --commit <hash>         # symbols changed in a commit

defuse context <symbol>             # definition, refs, callers, callees, and recent history
defuse impact <symbol>              # transitive blast radius of changing a symbol

defuse index                        # index the current repository
defuse reindex                      # incremental reindex
defuse reindex --watch              # reindex on file changes

How it works

defuse index detects the languages present in your repository and runs the appropriate SCIP indexer for each — scip-typescript for TypeScript and JavaScript, scip-go for Go, scip-rust for Rust, and so on. The resulting index is a portable, language-agnostic symbol graph stored in your project root.

All symbol queries read directly from this file. Git operations use gitoxide. No server, no daemon, no network access.

The index is safe to commit or ignore depending on your preference. defuse reindex --watch keeps it current during active development.

Supported languages

LanguageIndexer
TypeScript / JavaScriptscip-typescript
Goscip-go
Rustscip-rust
Pythonscip-python
Javascip-java
C / C++scip-clang

License

MIT