| Type: | Package |
| Title: | Code Analysis and Project Context for R |
| Version: | 0.2.0 |
| Description: | Parses R source files into AST symbol indices, traces function callers across projects, discovers project dependency graphs, generates project briefings, and provides package introspection tools. Designed for AI coding agents that need structured code understanding. |
| License: | Apache License (≥ 2) |
| URL: | https://github.com/cornball-ai/saber |
| BugReports: | https://github.com/cornball-ai/saber/issues |
| Suggests: | tinytest |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.2 |
| NeedsCompilation: | no |
| Packaged: | 2026-03-25 08:09:53 UTC; troy |
| Author: | Troy Hernandez |
| Maintainer: | Troy Hernandez <troy@cornball.ai> |
| Repository: | CRAN |
| Date/Publication: | 2026-03-30 08:50:02 UTC |
Blast radius analysis
Description
Find all callers of a function across projects. Find callers of a function across projects
Given a function name and project, finds all internal callers within that project and all callers in downstream projects (projects whose DESCRIPTION lists this one in Depends, Imports, or LinkingTo).
Usage
blast_radius(fn, project = NULL, scan_dir = path.expand("~"),
cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols"),
exclude = default_exclude())
Arguments
fn |
Character. Function name to search for. |
project |
Character. Project name (or path to project directory). |
scan_dir |
Directory to scan for downstream projects. |
cache_dir |
Directory for symbol cache files. |
exclude |
Character vector of directory basenames to skip when scanning for downstream projects. |
Value
A data.frame with columns: caller, project, file, line.
Examples
# Create a minimal project
d <- file.path(tempdir(), "blastpkg")
dir.create(file.path(d, "R"), recursive = TRUE, showWarnings = FALSE)
writeLines("helper <- function(x) x + 1", file.path(d, "R", "helper.R"))
writeLines("main <- function(x) helper(x * 2)", file.path(d, "R", "main.R"))
# Find all callers of helper()
blast_radius("helper", project = d, scan_dir = tempdir(),
cache_dir = tempdir())
Project briefings
Description
Generate project context for AI coding agents. Generate a project briefing
Produces a concise markdown briefing combining DESCRIPTION metadata,
downstream dependents, Claude Code memory, and recent git commits.
Written to ~/.cache/R/saber/briefs/ so both the agent and user
see the same context.
Usage
briefing(project = NULL, scan_dir = path.expand("~"),
memory_base = file.path(path.expand("~"), ".claude", "projects"),
briefs_dir = file.path(tools::R_user_dir("saber", "cache"), "briefs"),
max_memory_lines = 30L)
Arguments
project |
Project name. If NULL, inferred from the current working directory basename. |
scan_dir |
Directory to scan for project directories. |
memory_base |
Base directory for Claude Code project memory files. |
briefs_dir |
Directory to write briefing markdown files. |
max_memory_lines |
Maximum lines to include from the memory file. |
Value
The briefing text (character string), returned invisibly. Also
written to briefs_dir/{project}.md.
Examples
d <- file.path(tempdir(), "briefpkg")
dir.create(file.path(d, "R"), recursive = TRUE, showWarnings = FALSE)
writeLines(c("Package: briefpkg", "Title: Demo", "Version: 0.1.0"),
file.path(d, "DESCRIPTION"))
briefing("briefpkg", scan_dir = tempdir(),
briefs_dir = file.path(tempdir(), "briefs"))
Default directories to exclude when scanning for projects
Description
Returns a character vector of directory basenames that are skipped
when scanning for downstream projects. Override by passing a custom
exclude vector to blast_radius.
Usage
default_exclude()
Value
Character vector of directory basenames.
Examples
default_exclude()
Find projects that depend on a given package
Description
Scans DESCRIPTION files in project directories under scan_dir
for Depends, Imports, or LinkingTo fields that reference package.
Usage
find_downstream(package, scan_dir = path.expand("~"),
exclude = default_exclude())
Arguments
package |
Character. Package name to search for. |
scan_dir |
Directory to scan for project directories. |
exclude |
Character vector of directory basenames to skip. |
Value
Character vector of project names that depend on package.
Examples
d <- file.path(tempdir(), "dsdir")
dir.create(d, showWarnings = FALSE)
pkg <- file.path(d, "child")
dir.create(pkg, showWarnings = FALSE)
writeLines(c("Package: child", "Version: 0.1.0", "Imports: parent"),
file.path(pkg, "DESCRIPTION"))
find_downstream("parent", scan_dir = d)
Package introspection
Description
Query installed R packages for exports, internals, and help. List exported functions of a package
Returns a data.frame of exported functions with their argument signatures.
Usage
pkg_exports(package, pattern = NULL)
Arguments
package |
Character. Package name. |
pattern |
Optional regex to filter function names. |
Value
A data.frame with columns: name, args.
Examples
pkg_exports("tools")
pkg_exports("tools", pattern = "^Rd")
Get help for a package topic as markdown
Description
Extracts help documentation and converts it to clean markdown.
Usage
pkg_help(topic, package, format = c("md", "hugo"))
Arguments
topic |
Character. The help topic name. |
package |
Character. Package name. |
format |
Character. Output format: |
Value
Character string of markdown help text.
Examples
cat(pkg_help("md5sum", "tools"))
List internal (non-exported) functions of a package
Description
Returns functions defined in a package namespace but not exported.
Usage
pkg_internals(package, pattern = NULL)
Arguments
package |
Character. Package name. |
pattern |
Optional regex to filter function names. |
Value
A data.frame with columns: name, args.
Examples
pkg_internals("tools", pattern = "^check")
Project discovery
Description
Discover R package projects and their dependency relationships. Discover R package projects
Scans a directory for subdirectories containing a DESCRIPTION file and returns their metadata.
Usage
projects(scan_dir = path.expand("~"), exclude = default_exclude())
Arguments
scan_dir |
Directory to scan for project directories. |
exclude |
Character vector of directory basenames to skip. |
Value
A data.frame with columns: package, title, version, path, depends, imports.
Examples
d <- file.path(tempdir(), "scandir")
dir.create(d, showWarnings = FALSE)
pkg <- file.path(d, "mypkg")
dir.create(pkg, showWarnings = FALSE)
writeLines(c("Package: mypkg", "Title: Demo", "Version: 0.1.0"),
file.path(pkg, "DESCRIPTION"))
projects(scan_dir = d)
AST symbol index
Description
Parse R source files to extract function definitions and calls.
Usage
symbols(project_dir,
cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols"))
Arguments
project_dir |
Path to the project directory. |
cache_dir |
Directory for symbol cache files. |
Value
A list with components:
- defs
data.frame(name, file, line, exported)
- calls
data.frame(caller, callee, file, line)
Examples
# Create a minimal project with R source files
d <- file.path(tempdir(), "demopkg")
dir.create(file.path(d, "R"), recursive = TRUE, showWarnings = FALSE)
writeLines("add <- function(x, y) x + y", file.path(d, "R", "add.R"))
writeLines("double <- function(x) add(x, x)", file.path(d, "R", "double.R"))
idx <- symbols(d, cache_dir = tempdir())
idx$defs # function definitions
idx$calls # call relationships (double calls add)