From 6400f560d2442a0cfec2bb387c88227c2d9df252 Mon Sep 17 00:00:00 2001 From: TroyHernandez Date: Sun, 17 May 2026 10:27:41 -0500 Subject: [PATCH 1/3] Expose cache_dir on fn_graph() to keep checks out of ~/.cache fn_graph() called symbols(project_dir) without a cache_dir, so its example and the matching tinytest wrote to the user's persistent cache (~/.cache/R/saber/symbols/.rds). That triggered CRAN's 'checking for new files in some other directories' NOTE on packages that exercise fn_graph during R CMD check, and on saber itself when the example runs. Add cache_dir as an exposed parameter mirroring blast_radius() and symbols(), forward it to symbols(), and update the example + test to pass tempdir(). The default is unchanged for callers that omit it, so existing usage keeps working. --- R/fn_graph.R | 11 ++++++++--- inst/tinytest/test_fn_graph.R | 2 +- man/fn_graph.Rd | 10 ++++++++-- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/R/fn_graph.R b/R/fn_graph.R index ac458cb..76c7a0b 100644 --- a/R/fn_graph.R +++ b/R/fn_graph.R @@ -11,6 +11,9 @@ #' @param project_dir Path to the project directory (an R package root). #' @param include_external If \code{TRUE}, also include nodes for #' functions called from other packages. Default \code{FALSE}. +#' @param cache_dir Directory for the underlying \code{\link{symbols}} +#' cache. Pass \code{tempdir()} (or any non-default path) when running +#' examples / tests to avoid writing to the user's persistent cache. #' @param ... Passed through to \code{\link{graph_svg}} (e.g., #' \code{width}, \code{height}, \code{iterations}, \code{seed}). #' @return Character vector of SVG lines. Write with \code{writeLines()}. @@ -22,11 +25,13 @@ #' 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")) -#' svg <- fn_graph(d) +#' svg <- fn_graph(d, cache_dir = tempdir()) #' writeLines(svg, tempfile(fileext = ".svg")) #' @export -fn_graph <- function(project_dir, include_external = FALSE, ...) { - idx <- symbols(project_dir) +fn_graph <- function(project_dir, include_external = FALSE, + cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols"), + ...) { + idx <- symbols(project_dir, cache_dir = cache_dir) defs <- idx$defs calls <- idx$calls diff --git a/inst/tinytest/test_fn_graph.R b/inst/tinytest/test_fn_graph.R index 73e84ef..027f2b6 100644 --- a/inst/tinytest/test_fn_graph.R +++ b/inst/tinytest/test_fn_graph.R @@ -8,7 +8,7 @@ writeLines(c("Package: demo", "Version: 0.1.0"), file.path(d, "DESCRIPTION")) 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")) -svg <- fn_graph(d) +svg <- fn_graph(d, cache_dir = tempdir()) expect_true(is.character(svg)) expect_true(any(grepl("^ Date: Sun, 17 May 2026 10:43:02 -0500 Subject: [PATCH 2/3] fn_graph: move cache_dir after ... so positional graph_svg args still work Inserting cache_dir between include_external and ... broke existing positional callers: fn_graph(d, FALSE, 900) used to forward 900 into graph_svg(...) but would now bind it to cache_dir and fail in symbols(). Putting cache_dir after ... makes it name-only, which matches base R convention (paste's sep/collapse, c's recursive, etc.) and preserves positional forwarding for graph_svg. --- R/fn_graph.R | 10 +++++----- man/fn_graph.Rd | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/fn_graph.R b/R/fn_graph.R index 76c7a0b..a879163 100644 --- a/R/fn_graph.R +++ b/R/fn_graph.R @@ -11,11 +11,12 @@ #' @param project_dir Path to the project directory (an R package root). #' @param include_external If \code{TRUE}, also include nodes for #' functions called from other packages. Default \code{FALSE}. +#' @param ... Passed through to \code{\link{graph_svg}} (e.g., +#' \code{width}, \code{height}, \code{iterations}, \code{seed}). #' @param cache_dir Directory for the underlying \code{\link{symbols}} #' cache. Pass \code{tempdir()} (or any non-default path) when running #' examples / tests to avoid writing to the user's persistent cache. -#' @param ... Passed through to \code{\link{graph_svg}} (e.g., -#' \code{width}, \code{height}, \code{iterations}, \code{seed}). +#' Name-only argument — must be passed by name. #' @return Character vector of SVG lines. Write with \code{writeLines()}. #' @examples #' d <- file.path(tempdir(), "fngdemo") @@ -28,9 +29,8 @@ #' svg <- fn_graph(d, cache_dir = tempdir()) #' writeLines(svg, tempfile(fileext = ".svg")) #' @export -fn_graph <- function(project_dir, include_external = FALSE, - cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols"), - ...) { +fn_graph <- function(project_dir, include_external = FALSE, ..., + cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols")) { idx <- symbols(project_dir, cache_dir = cache_dir) defs <- idx$defs calls <- idx$calls diff --git a/man/fn_graph.Rd b/man/fn_graph.Rd index 78621c0..babf2a4 100644 --- a/man/fn_graph.Rd +++ b/man/fn_graph.Rd @@ -3,9 +3,8 @@ \alias{fn_graph} \title{Code intelligence: function call graph} \usage{ -fn_graph(project_dir, include_external = FALSE, - cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols"), - ...) +fn_graph(project_dir, include_external = FALSE, ..., + cache_dir = file.path(tools::R_user_dir("saber", "cache"), "symbols")) } \arguments{ \item{project_dir}{Path to the project directory (an R package root).} @@ -13,12 +12,13 @@ fn_graph(project_dir, include_external = FALSE, \item{include_external}{If \code{TRUE}, also include nodes for functions called from other packages. Default \code{FALSE}.} -\item{cache_dir}{Directory for the underlying \code{\link{symbols}} -cache. Pass \code{tempdir()} (or any non-default path) when running -examples / tests to avoid writing to the user's persistent cache.} - \item{...}{Passed through to \code{\link{graph_svg}} (e.g., \code{width}, \code{height}, \code{iterations}, \code{seed}).} + +\item{cache_dir}{Directory for the underlying \code{\link{symbols}} +cache. Pass \code{tempdir()} (or any non-default path) when running +examples / tests to avoid writing to the user's persistent cache. +Name-only argument — must be passed by name.} } \value{ Character vector of SVG lines. Write with \code{writeLines()}. From c5c150f3dece65937950d5a47dd49490e7e5cc5c Mon Sep 17 00:00:00 2001 From: TroyHernandez Date: Sun, 17 May 2026 10:43:09 -0500 Subject: [PATCH 3/3] Bump version to 0.7.1.1 --- DESCRIPTION | 2 +- NEWS.md | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a747650..e107478 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: saber Type: Package Title: Context Engineering for Large Language Model Agents -Version: 0.7.1 +Version: 0.7.1.1 Authors@R: c( person("Troy", "Hernandez", role = c("aut", "cre"), email = "troy@cornball.ai", diff --git a/NEWS.md b/NEWS.md index 06f0aae..0564b2d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# saber 0.7.1.1 + +## Changes + +- `fn_graph()` now accepts `cache_dir`, mirroring `blast_radius()` and + `symbols()`. The default is unchanged. The example and tinytest pass + `tempdir()` so R CMD check no longer leaves files under + `tools::R_user_dir("saber", "cache")`. + # saber 0.7.1 ## Changes