Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4e1eacb
Add git tools for basic repository operations
gadenbuie Oct 15, 2025
2b1d9f5
Refactor git tests to use local_temp_git_repo() helper
gadenbuie Oct 15, 2025
4f05d72
Refactor(tests): Rename helper function argument
gadenbuie Oct 15, 2025
18837b6
tests: Check gert not installed errors
gadenbuie Oct 15, 2025
55ea253
tests: Remove " works"
gadenbuie Oct 15, 2025
7522935
Add snapshot tests for git tool outputs
gadenbuie Oct 15, 2025
d4bae00
Add scrub_git_details() to stabilize git test snapshots
gadenbuie Oct 15, 2025
dd1eeb6
tests: Add test for integrated workflow
gadenbuie Oct 15, 2025
eb6a85c
feat: Rework outputs from git tools, add `md_kv_table()` helper
gadenbuie Oct 15, 2025
dc8323d
docs(btw_tools): link to tool functions from table
gadenbuie Oct 15, 2025
ffcdcb4
chore(AGENTS): Add check functions
gadenbuie Oct 15, 2025
4139ec2
refactor: Use HTML from shiny
gadenbuie Oct 15, 2025
1edce56
tests: Use `main` as default branch in temp git repos
gadenbuie Oct 15, 2025
93bdd6f
Revert "refactor: Use HTML from shiny"
gadenbuie Oct 15, 2025
a1913d1
chore: Use local version of HTML()
gadenbuie Oct 15, 2025
5f5d2fd
tests: Really force `main` over `master`
gadenbuie Oct 15, 2025
bfeb855
git: clarify git-diff behavior and fix empty-diff detection
gadenbuie Oct 16, 2025
ed76502
ui: add tool-group toggle and centralized group icons
gadenbuie Oct 16, 2025
45583ee
refactor(git-status): Rename `staged` to `include`
gadenbuie Oct 16, 2025
c8fabd4
refactor: to_title_case
gadenbuie Oct 16, 2025
cd0d06f
docs(btw_tools): break tools into groups
gadenbuie Oct 16, 2025
e8a0771
chore: Add `git` tool group to btw.md template
gadenbuie Oct 16, 2025
24af306
chore: write out tools as long list (easier to toggle with comments)
gadenbuie Oct 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,34 @@ Edit files in `inst/prompts/`. These are assembled in `btw_client()` based on co
- **Tool functions return `tool_result()` objects** with value and optional display metadata
- **All tool wrappers accept `_intent` parameter** (added automatically by `wrap_with_intent()`)
- **Snapshot tests for tool outputs** to catch formatting changes
- **Use `check_*()` functions** from rlang for argument validation
- **Use `check_*()` functions** argument validation, described below

### Type Check Functions

#### Scalars
- `check_bool()` - Validates single TRUE/FALSE value
- `check_string()` - Validates single string (allows empty by default)
- `check_name()` - Validates non-empty string for use as name
- `check_number_decimal()` - Validates single numeric value (allows decimals)
- `check_number_whole()` - Validates single integer value
- `check_symbol()` - Validates R symbol/name object
- `check_arg()` - Validates argument name (symbol)
- `check_call()` - Validates defused call object
- `check_environment()` - Validates environment object
- `check_function()` - Validates function (any type)
- `check_closure()` - Validates R function (not primitive/builtin)
- `check_formula()` - Validates formula object

#### Vectors
- `check_character()` - Validates character vector
- `check_logical()` - Validates logical vector
- `check_data_frame()` - Validates data frame

#### Common Parameters
- All functions support `allow_null` parameter
- Most scalars support `allow_na`
- Number checkers support `min`/`max` bounds and `allow_infinite`
- All use `arg`/`call` for error context

## Important Notes

Expand Down
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Collate:
'tool-environment.R'
'tool-files-code-search.R'
'tool-files.R'
'tool-git.R'
'tool-rstudioapi.R'
'tool-search-packages.R'
'tool-session-package-installed.R'
Expand Down
7 changes: 7 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ export(btw_tool_files_code_search)
export(btw_tool_files_list_files)
export(btw_tool_files_read_text_file)
export(btw_tool_files_write_text_file)
export(btw_tool_git_branch_checkout)
export(btw_tool_git_branch_create)
export(btw_tool_git_branch_list)
export(btw_tool_git_commit)
export(btw_tool_git_diff)
export(btw_tool_git_log)
export(btw_tool_git_status)
export(btw_tool_ide_read_current_editor)
export(btw_tool_search_package_info)
export(btw_tool_search_packages)
Expand Down
48 changes: 35 additions & 13 deletions R/btw_client_app.R
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,29 @@ btw_app_from_client <- function(client, messages = list(), ...) {
}
})

lapply(tool_groups, function(group) {
shiny::observeEvent(input[[paste0("tools_toggle_", group)]], {
current <- input[[paste0("tools_", group)]]
all_tools <- btw_tools_df()
group_tools <- all_tools[all_tools$group == group, ][["name"]]
if (length(current) == length(group_tools)) {
# All selected, so deselect all
shiny::updateCheckboxGroupInput(
session = session,
inputId = paste0("tools_", group),
selected = ""
)
} else {
# Not all selected, so select all
shiny::updateCheckboxGroupInput(
session = session,
inputId = paste0("tools_", group),
selected = group_tools
)
}
})
})

shiny::observe({
if (!length(selected_tools())) {
client$set_tools(list())
Expand Down Expand Up @@ -256,34 +279,33 @@ app_tool_group_choice_input <- function(
initial_tool_names <- group_tools_df$name
}

label_icon <- switch(
group,
"docs" = tool_icon("dictionary"),
"env" = tool_icon("source-environment"),
"files" = tool_icon("folder-open"),
"ide" = tool_icon("code-blocks"),
"search" = tool_icon("search"),
"session" = tool_icon("screen-search-desktop"),
"web" = tool_icon("globe-book"),
tool_icon("construction")
)
label_icon <- tool_group_icon(group, "construction")

label_text <- switch(
group,
"docs" = shiny::span(label_icon, "Documentation"),
"env" = shiny::span(label_icon, "Environment"),
"files" = shiny::span(label_icon, "Files"),
"git" = shiny::span(label_icon, "Git"),
"ide" = shiny::span(label_icon, "IDE"),
"search" = shiny::span(label_icon, "Search"),
"session" = shiny::span(label_icon, "Session Info"),
"web" = shiny::span(label_icon, "Web Tools"),
"other" = shiny::span(label_icon, "Other Tools"),
paste0(toupper(substring(group, 1, 1)), substring(group, 2))
to_title_case(group)
)

shiny::checkboxGroupInput(
inputId = paste0("tools_", group),
label = shiny::h3(label_text, class = "h6 mb-0"),
label = shiny::h3(
class = "h6 mb-0",
shiny::actionLink(
paste0("tools_toggle_", group),
label_text,
class = "link-body-emphasis",
style = "text-decoration: none;"
)
),
choiceNames = choice_names,
choiceValues = group_tools_df$name,
selected = intersect(group_tools_df$name, initial_tool_names),
Expand Down
2 changes: 1 addition & 1 deletion R/edit_btw_md.R
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
#' ````
#' ---
#' client: claude/claude-4-5-sonnet-latest
#' tools: [docs, env, files, ide, search, session, web]
#' tools: [docs, env, files, git, ide, search, session, web]
#' ---
#'
#' Follow these important style rules when writing R code:
Expand Down
Loading