cargo-brief 0.3.1

Visibility-aware Rust API extractor — pseudo-Rust output for AI agent consumption
Documentation

cargo-brief

Visibility-aware Rust API extractor — pseudo-Rust output for AI agent consumption.

Why?

AI coding agents need to understand crate APIs without reading full source files. HTML docs waste tokens on navigation chrome, and cargo doc --json is too verbose. cargo-brief outputs concise pseudo-Rust that fits in a context window:

  • Function bodies replaced with ;
  • Only items visible from the caller's perspective
  • Doc comments preserved verbatim
  • Compact module hierarchy

Installation

cargo install cargo-brief

Requires the nightly toolchain (for rustdoc --output-format json):

rustup toolchain install nightly

Usage

cargo brief <target> [module_path] [OPTIONS]

The first argument is flexible — it can be a crate name, self, a crate::module path, or even a file path:

Syntax Resolves to
my-crate Named crate (hyphen/underscore normalized)
self Current package (detected from cwd)
self::module Current package, specific module
crate::module Named crate + module in one arg
src/foo.rs File path → auto-converted to module path
unknown_name If not a workspace package → treated as self module

Examples

# Show the full API of a crate in your workspace
cargo brief my-crate --recursive

# Inspect the current package
cargo brief self --recursive

# Show a specific module (multiple syntaxes)
cargo brief my-crate utils::helpers
cargo brief self::utils
cargo brief src/utils.rs

# Show only what's visible from an external crate
cargo brief my-crate --at-package other-crate

# Limit recursion depth
cargo brief my-crate --depth 2

# Exclude certain item kinds
cargo brief my-crate --no-macros --no-traits

# Search for items by name (fuzzy / imprecise search)
cargo brief my-crate --search spawn
cargo brief --crates hecs --search "World spawn"
cargo brief self --search "config timeout"

Options

Flag Description
<target> Target to inspect: crate name, self, crate::module, or file path
[module_path] Module path within the crate (e.g., my_mod::submod or src/my_mod.rs)
--at-package <pkg> Caller's package name (for visibility resolution)
--at-mod <path> Caller's module path (determines what is visible)
--depth <n> How many submodule levels to recurse into (default: 1)
--recursive Recurse into all submodules (no depth limit)
--all Show all item kinds including blanket/auto-trait impls
--no-structs Exclude structs
--no-enums Exclude enums
--no-traits Exclude traits
--no-functions Exclude free functions
--no-aliases Exclude type aliases
--no-constants Exclude constants and statics
--no-unions Exclude unions
--no-macros Exclude macros
--search <pattern> Search leaf items by name (case-insensitive, multi-word AND)
--toolchain <name> Nightly toolchain name (default: nightly)
--manifest-path <path> Path to Cargo.toml

Search Mode

--search finds leaf items whose full path contains the given pattern (case-insensitive). Multiple words are AND-matched — all must appear somewhere in the path.

cargo brief --crates hecs --search component
// crate hecs — search: "component" (11 results)

/// A collection of component types
struct query::ComponentSet;

enum world::ComponentError;

field world::ArchetypeInfo::component_count: u32;

variant world::WorldError::ComponentNotFound;
variant world::WorldError::ComponentAlreadyBorrowed;

/// Insert a component into an entity
fn world::World::insert_component<T: Component>(&mut self, entity: Entity, component: T) -> Result<()>;
fn world::World::remove_component<T: Component>(&mut self, entity: Entity) -> Result<T>;
fn world::World::get_component<T: Component>(&self, entity: Entity) -> Result<ComponentRef<'_, T>>;

type world::ComponentId = u32;
const world::MAX_COMPONENTS: usize = ..;
macro component_bundle!;

Leaf items included in search: functions, methods, struct fields, enum variants, constants, statics, type aliases, macros, associated types/consts. Container types (struct, enum, trait, union) appear when their name matches directly.

Output Format

// crate my_crate
mod utils {
    /// Computes the hash of the input.
    pub fn hash(input: &[u8]) -> u64;

    pub struct Config {
        pub timeout: Duration,
        pub retries: u32,
        // ... private fields
    }

    impl Config {
        pub fn new() -> Self;
        pub fn with_timeout(self, timeout: Duration) -> Self;
    }

    pub trait Processor: Send + Sync {
        type Output;
        fn process(&self, input: &[u8]) -> Self::Output;
    }
}

AI Agent Setup

Claude Code

Add a note to your project's CLAUDE.md so the AI knows to use cargo-brief when exploring crate APIs:

## Exploring Crate APIs

Use `cargo brief` to inspect crate interfaces instead of reading source files directly:

# Current package API
cargo brief self --recursive

# Specific module (by name or file path)
cargo brief self::some_module --recursive
cargo brief src/some_module.rs --recursive

# Named crate in workspace
cargo brief <crate> --recursive

# Multi-workspace: specify manifest path
cargo brief <crate> --manifest-path path/to/Cargo.toml --recursive

# External visibility only (what other crates can see)
cargo brief <crate> --at-package consumer-crate --recursive

# Search for items by name (imprecise / fuzzy)
cargo brief <crate> --search "spawn entity"
cargo brief --crates serde --search "deserialize"

Generic LLM Agent

Pipe the output directly into your agent's context:

# Current package API
cargo brief self --recursive | your-agent-tool

# Specific module
cargo brief self::network::http --recursive | your-agent-tool

Or use it as a tool call that returns the output as a string to the agent.

License

MPL-2.0