···190190 )
191191192192 usethis::use_air()
193193- c(
194194- "{",
195195- ' "recommendations": [',
196196- ' "Posit.air-vscode",',
197197- ' "etiennebacher.jarl-vscode"',
198198- " ]",
199199- "}"
200200- ) |>
201201- write_to_path(fs::path(".vscode", "extensions.json"))
202202- c(
203203- "[lint]",
204204- "extend-select = [\"TESTTHAT\"]"
205205- ) |>
206206- write_to_path(fs::path("tests", "jarl.toml")) # TODO: need to make GHA jarl runs respect this
193193+ copy_template_file("extensions.json", fs::path(".vscode", "extensions.json"))
194194+ copy_template_file("jarl.toml", fs::path("tests", "jarl.toml")) # TODO: need to make GHA jarl runs respect this
207195}
208196209197#' Configure Dependabot Defaults
···214202#' @keywords internal
215203#' @noRd
216204setup_dependabot <- function() {
217217- c(
218218- "version: 2",
219219- "updates:",
220220- " - package-ecosystem: \"github-actions\"",
221221- " directory: \"/\"",
222222- " schedule:",
223223- " interval: \"weekly\""
224224- ) |> # TODO: move file to inst?
225225- write_to_path(fs::path(".github", "dependabot.yml"))
205205+ copy_template_file("dependabot.yml", fs::path(".github", "dependabot.yml"))
226206}
227207228208#' Configure AGENTS Defaults
229209#'
230230-#' Placeholder for AGENTS file setup.
210210+#' Copies an opinionated, concise AGENTS.md for R package development.
231211#'
232212#' @return Invisibly returns `NULL`.
233213#' @keywords internal
234214#' @noRd
235215setup_agents <- function() {
236236- # See https://simonwillison.net/guides/agentic-engineering-patterns/
237237- c(
238238- "# General",
239239- "Read DESCRIPTION, README",
240240- "Red/green TDD via usethis::use_test()",
241241- "",
242242- "# Personality",
243243- "Literal, direct, concise, high-signal, non-empathic. No hedging, both-sidesing, closing summaries, or offers. Only ask questions if functionally blocked.",
244244- "",
245245- "# R Dev Rules",
246246- "No manual edits to .Rd or NAMESPACE.",
247247- "Use devtools::document(), test(), check().",
248248- "Prefer Base R, existing dep closure. Request permission for new deps which make code better.",
249249- "Add deps via usethis::use_import_from(), use_package()",
250250- "air format ., jarl check . --fix --allow-dirty, all tests, and R CMD check pass before you claim to be done."
251251- ) |>
252252- write_to_path(fs::path("AGENTS.md"))
216216+ copy_template_file("AGENTS.md", "AGENTS.md")
253217}
254254-255218256219#' Choose and Apply a License
257220#'
+17
R/utils.R
···1313 writeLines(text, filepath)
1414}
15151616+#' Copy a Template File
1717+#'
1818+#' Copies a file from `inst/templates` into the target location.
1919+#'
2020+#' @param template_file Template file name inside `inst/templates`.
2121+#' @param destination Destination file path.
2222+#'
2323+#' @return Invisibly returns `NULL`.
2424+#' @keywords internal
2525+#' @noRd
2626+copy_template_file <- function(template_file, destination) {
2727+ fs::dir_create(fs::path_dir(destination))
2828+ fs::path_package("bootstrapper", "templates", template_file) |>
2929+ fs::file_copy(destination, overwrite = TRUE)
3030+ invisible(NULL)
3131+}
3232+1633#' Find and Replace in a File
1734#'
1835#' Replaces matching text in a single file.
+13
inst/templates/AGENTS.md
···11+# General
22+Read DESCRIPTION, README
33+Red/green TDD via usethis::use_test()
44+55+# Personality
66+Literal, direct, concise, high-signal, non-empathic. No hedging, both-sidesing, closing summaries, or offers. Only ask questions if functionally blocked.
77+88+# R Dev Rules
99+No manual edits to .Rd or NAMESPACE.
1010+Use devtools::document(), test(), check().
1111+Prefer Base R, existing dep closure. Request permission for new deps which make code better.
1212+Add deps via usethis::use_import_from(), use_package()
1313+air format ., jarl check . --fix --allow-dirty, all tests, and R CMD check pass before you claim to be done.