Last updated: 2026-03-25
Code analysis and project context for R.
saber (“to know” in Spanish, pronounced sah-BEHR) parses R source into structured symbol indices, traces function callers across projects, discovers dependency graphs, generates project briefings, and cracks open installed packages for introspection. Built for AI coding agents that need to understand R code without guessing.
Install
1remotes::install_github("cornball-ai/saber")
What it does
9 exported functions.
| Function | What it does |
|---|---|
symbols() | Parse R source files into function defs and calls via getParseData() |
blast_radius() | Find every caller of a function, across projects |
find_downstream() | Find all projects that depend on a given package |
projects() | Discover R package projects and their metadata |
briefing() | Generate a project context briefing (metadata, dependents, memory, git log) |
pkg_exports() | List exported functions with argument signatures |
pkg_internals() | List internal (non-exported) functions |
pkg_help() | Pull help documentation as markdown |
default_exclude() | Default directories to skip when scanning |
Examples
Index all function definitions and calls in a project:
1syms <- saber::symbols("~/myproject")
2syms$defs # data.frame: name, file, line, exported
3syms$calls # data.frame: caller, callee, file, line
Find who calls a function (and where the damage lands if you change it):
1saber::blast_radius("my_function", project = "~/myproject")
2#> caller project file line
3#> do_thing myproject main.R 42
4#> run_batch downstream pipeline.R 17
Discover projects and their dependencies:
1saber::projects()
2#> package title version path depends imports
3#> saber Code Analysis for R 0.2.0 /home/troy/saber ...
4
5saber::find_downstream("jsonlite")
6#> [1] "chatterbox" "cornfab" "diffuseR" "llamaR" "llm.api"
7#> [6] "safetensors" "stt.api" "torch" "tts.api" "tuber" "whisper"
Generate a project briefing for an AI agent:
1saber::briefing("saber")
2#> # Briefing: saber
3#> _Generated 2026-03-25 00:30_
4#>
5#> ## Package
6#> - **Name**: saber
7#> - **Title**: Code Analysis and Project Context for R
8#> - **Version**: 0.2.0
9#>
10#> ## Recent commits
11#> - 7983478 Add r-ci GitHub Actions workflow
12#> - ...
Inspect any installed package:
1saber::pkg_exports("saber")
2saber::pkg_help("symbols", "saber")
How it works
symbols() runs getParseData() on every R/*.R file in a project, extracts function definitions and call sites, and caches the results as RDS in the user cache directory. Cache invalidates on file content changes (MD5).
blast_radius() builds on top of symbols(). It finds internal callers, then scans ~/ for any project whose DESCRIPTION declares a dependency on the target package. Traces the call graph across all of them.
projects() scans for directories containing DESCRIPTION files and reads their metadata. find_downstream() does the same scan but filters to projects that depend on a specific package.
briefing() assembles project context from DESCRIPTION metadata, downstream dependents, Claude Code memory files, and recent git commits. It returns a printable saber_briefing character object and writes the same markdown to the user cache directory so both the agent and user see the same context.
Claude Code hook
saber ships a SessionStart hook that injects a project briefing into Claude Code’s context at the start of every session. Find the hook script’s path:
1system.file("scripts", "session-start.R", package = "saber")
Then add it to your Claude Code settings (~/.claude/settings.json):
1{
2 "hooks": {
3 "SessionStart": [
4 {
5 "hooks": [
6 {
7 "type": "command",
8 "command": "Rscript /path/to/session-start.R",
9 "timeout": 15
10 }
11 ]
12 }
13 ]
14 }
15}
Every new session starts with the project’s metadata, downstream dependents, Claude Code memory, and recent git commits already in context.
License
Apache-2.0
Reference
See Function Reference for complete API documentation.
Functions
saber Reference
Function reference for saber