cli
# ClaudeWave Editor Description The cli skill provides R functions for creating formatted command-line output with semantic markup. It includes functions for displaying styled messages, progress indicators, alerts, and lists, along with inline markup syntax for formatting code, file paths, package names, and variables. Use this skill when building R packages that need polished terminal output with contextual formatting and proper pluralization handling.
git clone --depth 1 https://github.com/posit-dev/skills /tmp/cli && cp -r /tmp/cli/r-lib/cli ~/.claude/skills/cliSKILL.md
# CLI for R Packages
## When to Use What
task: Display error with context and formatting
use: `cli_abort()` with inline markup and bullet lists
task: Show warning with formatting
use: `cli_warn()` with inline markup
task: Display informative message
use: `cli_inform()` with inline markup
task: Show progress for counted operations
use: `cli_progress_bar()` with total count
task: Show simple progress steps
use: `cli_progress_step()` with status messages
task: Format code or function names
use: `{.code ...}` or `{.fn package::function}`
task: Format file paths
use: `{.file path/to/file}`
task: Format package names
use: `{.pkg packagename}`
task: Format variable names
use: `{.var variable_name}`
task: Format values
use: `{.val value}`
task: Handle singular/plural text
use: `{?s}` or `{?y/ies}` with pluralization
task: Create headers
use: `cli_h1()`, `cli_h2()`, `cli_h3()`
task: Create alerts
use: `cli_alert_success()`, `cli_alert_danger()`, `cli_alert_warning()`, `cli_alert_info()`
task: Create lists
use: `cli_ul()`, `cli_ol()`, `cli_dl()` with `cli_li()`
## Inline Markup Essentials
Use inline markup with `{.class content}` syntax to format text:
```r
# Basic formatting
cli_text("Function {.fn mean} calculates averages")
cli_text("Install package {.pkg dplyr}")
cli_text("See file {.file ~/.Rprofile}")
cli_text("{.var x} must be numeric, not {.obj_type_of {x}}")
cli_text("Got value {.val {x}}")
# Code formatting
cli_text("Use {.code sum(x, na.rm = TRUE)}")
# Paths and arguments
cli_text("Reading from {.path /data/file.csv}")
cli_text("Set {.arg na.rm} to TRUE")
# Types and classes
cli_text("Object is {.cls data.frame}")
# Emphasis
cli_text("This is {.emph important}")
cli_text("This is {.strong critical}")
# Fields
cli_text("The {.field name} field is required")
```
### Vector Collapsing
Vectors are automatically collapsed with commas and "and":
```r
pkgs <- c("dplyr", "tidyr", "ggplot2")
cli_text("Installing packages: {.pkg {pkgs}}")
#> Installing packages: dplyr, tidyr, and ggplot2
files <- c("data.csv", "script.R")
cli_text("Found {length(files)} file{?s}: {.file {files}}")
#> Found 2 files: data.csv and script.R
```
### Escaping Braces
Use double braces `{{` and `}}` to escape literal braces:
```r
cli_text("Use {{variable}} syntax in glue")
#> Use {variable} syntax in glue
```
**For complete markup reference**: See [references/inline-markup.md](references/inline-markup.md) for all 50+ inline classes, edge cases, nesting rules, and advanced patterns.
## Pluralization Basics
Use `{?}` for pluralization with three patterns:
### Single Alternative
```r
nfile <- 1
cli_text("Found {nfile} file{?s}")
#> Found 1 file
nfile <- 3
cli_text("Found {nfile} file{?s}")
#> Found 3 files
```
### Two Alternatives
```r
ndir <- 1
cli_text("Found {ndir} director{?y/ies}")
#> Found 1 directory
ndir <- 5
cli_text("Found {ndir} director{?y/ies}")
#> Found 5 directories
```
### Three Alternatives (zero/one/many)
```r
nfile <- 0
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 0 files: no files
nfile <- 1
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 1 file: the file
nfile <- 3
cli_text("Found {nfile} file{?s}: {?no/the/the} file{?s}")
#> Found 3 files: the files
```
### Helpers: qty() and no()
Use `no()` to display "no" instead of zero:
```r
nfile <- 0
cli_text("Found {no(nfile)} file{?s}")
#> Found no files
```
Use `qty()` to set quantity explicitly:
```r
nupd <- 3
ntotal <- 10
cli_text("{nupd}/{ntotal} {qty(nupd)} file{?s} {?needs/need} updates")
#> 3/10 files need updates
```
**For advanced pluralization**: See [references/inline-markup.md](references/inline-markup.md) for edge cases and complex patterns.
## CLI Conditions: Core Patterns
Use cli conditions instead of base R for better formatting:
### cli_abort() - Formatted Errors
```r
# Before (base R)
stop("File not found: ", path)
# After (cli)
cli_abort("File {.file {path}} not found")
# With bullets for context
check_file <- function(path) {
if (!file.exists(path)) {
cli_abort(c(
"File not found",
"x" = "Cannot read {.file {path}}",
"i" = "Check that the file exists"
))
}
}
```
### cli_warn() - Formatted Warnings
```r
# Before (base R)
warning("Column ", col, " has missing values")
# After (cli)
cli_warn("Column {.field {col}} has missing values")
# With context
cli_warn(c(
"Data quality issues detected",
"!" = "Column {.field {col}} has {n_missing} missing value{?s}",
"i" = "Consider using {.fn tidyr::drop_na}"
))
```
### cli_inform() - Formatted Messages
```r
# Before (base R)
message("Processing ", n, " files")
# After (cli)
cli_inform("Processing {n} file{?s}")
# With structure
cli_inform(c(
"v" = "Successfully loaded {.pkg dplyr}",
"i" = "Version {packageVersion('dplyr')}"
))
```
### Bullet Types
- `"x"` - Error/problem (red X)
- `"!"` - Warning (yellow !)
- `"i"` - Information (blue i)
- `"v"` - Success (green checkmark)
- `"*"` - Bullet point
- `">"` - Arrow/pointer
**For advanced error design**: See [references/conditions.md](references/conditions.md) for error design principles, rlang integration, testing strategies, and real-world patterns.
## Basic Progress Indicators
### Simple Progress Steps
```r
process_data <- function() {
cli_progress_step("Loading data")
data <- load_data()
cli_progress_step("Cleaning data")
clean <- clean_data(data)
cli_progress_step("Analyzing data")
analyze(clean)
}
```
### Basic Progress Bar
```r
process_files <- function(files) {
cli_progress_bar("Processing files", total = length(files))
for (file in files) {
process_file(file)
cli_progress_update()
}
}
```
### Auto-Cleanup
Progress bars auto-close when the function exits:
```r
process <- function() {
cli_progress_bar("Working", total = 100)
for (i in 1:100) {
Sys.sleep(0.01)
cli_progress_update()
}
# No need to call cli_progress_done() - auto-closes
}
```
**For advan>
Create and use brand.yml files for consistent branding across Shiny apps and Quarto documents. Covers: (1) Creating new _brand.yml files, (2) Applying to Shiny (R and Python), (3) Using in Quarto, (4) Modifying existing files, and (5) Troubleshooting. Includes complete specifications and integration guides.
Write ggsql queries — a grammar of graphics for SQL. Use when the user wants to create, modify, or understand a ggsql visualization query.
Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes. Activate when the user says "create pr", "make a pr", "open pull request", "submit pr", "pr for these changes", or wants to get their current work into a reviewable PR. Assumes the project uses git, is hosted on GitHub, and has GitHub Actions CI with automated checks (lint, build, tests, etc.). Does NOT merge - stops when CI passes and provides the PR link.
Address PR review feedback by systematically working through every unresolved PR review thread on the current branch's PR - analyze each comment, make the requested code changes (with tests where useful), commit, and optionally reply and resolve.
Bulk resolve unresolved PR review threads on the current branch’s PR — typically after threads have been addressed manually or via /pr-threads-address
>
Guide for drafting issue closure and decline responses as an open-source package maintainer. Use when helping compose a reply that says \"no\" to a feature request, closes an issue as won't-fix, redirects a user to a different package, explains why a design choice is intentional, or otherwise declines or closes a community contribution. Also use when the maintainer needs to explain a deprecation, point out a user misunderstanding, or communicate an effort/scope tradeoff to a contributor.