Agent skill

R CLI App

by posit-dev in posit-dev/skills

Build command-line apps in R using the Rapp package. An agent skill from posit-dev/skills.

MITAuto-check passedFrontend & Design

Install R CLI App

skills CLI
$ npx skills add posit-dev/skills --skill r-cli-app -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install posit-dev/skills r-cli-app --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/posit-dev/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/r-lib/r-cli-app .claude/skills/r-cli-app && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
r-cli-app
GitHub stars
529
Token cost
~2.9k tokens
SKILL.md length
783 words
Files
9 (incl. references)
Skills in repo
17
Repo updated
First seen
Licence
MIT

At a glance

Build command-line apps in R using the Rapp package. An agent skill from posit-dev/skills.

  • Works in 3 steps: The same script works identically via… → You write normal R code — Rapp infers… → Default values in your R code become the…
  • Creating a CLI tool in R
  • SKILL.md covers Core Concept: Scripts Are the…, Pattern Recognition: R → CLI…, Script Structure and Named Options, plus 11 more sections
  • Runs R scripts from its folder

What it does

R CLI App is an agent skill from posit-dev/skills. Build command-line apps in R using the Rapp package. Use when creating a CLI tool in R, adding argument parsing to an R script, turning an R script into a command-line app, shipping CLIs in an R package, or using Rapp (the alternative Rscript front-end). Also use for shebang scripts, exec/ directory in R packages, or subcommand-based R tools.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 13 other files, including reference files (for example `.evals/convert-script/eval.md`, `.evals/convert-script/prompt.md` and `.evals/simple-cli/eval.md`).

It sits in Frontend & Design. The repository describes itself as: A collection of Claude Skills from Posit. The licence is MIT.

When your agent uses it

  • Creating a CLI tool in R
  • Adding argument parsing to an R script
  • Turning an R script into a command-line app
  • Shipping CLIs in an R package

Example prompts

  • “/r-cli-app”

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. The same script works identically via source() and as a CLI tool.
  2. You write normal R code — Rapp infers the CLI from what you write.
  3. Default values in your R code become the CLI defaults.

What it can do on your machine

Read from SKILL.md and the folder at commit 0300946. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships script files (R), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

R CLI App loads about 2.9k tokens when it runs, and up to ~4.3k if it reads all its reference files. Until then it costs about 89 tokens; SKILL.md has 783 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~89
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from posit-dev/skills at commit 0300946, republished under its MIT licence (© posit-dev). 783 words, ~2,859 tokens.

Download SKILL.mdSave it as .claude/skills/r-cli-app/SKILL.md (or your agent's skills folder). This skill also uses 8 other files; get the full folder from GitHub.
name
r-cli-app
description
Build command-line apps in R using the Rapp package. Use when creating a CLI tool in R, adding argument parsing to an R script, turning an R script into a command-line app, shipping CLIs in an R package, or using Rapp (the alternative Rscript front-end). Also use for shebang scripts, exec/ directory in R packages, or subcommand-based R tools.
metadata.author
Garrick Aden-Buie (@gadenbuie)
metadata.version
1.1
license
MIT

Building CLI Apps with Rapp

Rapp (v0.3.0) is an R package that provides a drop-in replacement for Rscript that automatically parses command-line arguments into R values. It turns simple R scripts into polished CLI apps with argument parsing, help text, and subcommand support — with zero boilerplate.

R ≥ 4.1.0 | CRAN: install.packages("Rapp") | GitHub: r-lib/Rapp

After installing, put the Rapp launcher on PATH:

r
Rapp::install_pkg_cli_apps("Rapp")

This places the Rapp executable in ~/.local/bin (macOS/Linux) or %LOCALAPPDATA%\Programs\R\Rapp\bin (Windows).


Core Concept: Scripts Are the Spec

Rapp scans top-level expressions of an R script and converts specific patterns into CLI constructs. This means:

  1. The same script works identically via source() and as a CLI tool.
  2. You write normal R code — Rapp infers the CLI from what you write.
  3. Default values in your R code become the CLI defaults.

Only top-level assignments are recognized. Assignments inside functions, loops, or conditionals are not parsed as CLI arguments.


Pattern Recognition: R → CLI Mapping

This table is the heart of Rapp — each R pattern automatically maps to a CLI surface:

R Top-Level ExpressionCLI SurfaceNotes
foo <- "text"--foo <value>String option
foo <- 1L--foo <int>Integer option
foo <- 3.14--foo <float>Float option
foo <- TRUE / FALSE--foo / --no-fooBoolean toggle
foo <- NA_integer_--foo <int>Optional integer (NA = not set)
foo <- NA_character_--foo <str>Optional string (NA = not set)
foo <- NULLpositional argRequired by default
foo... <- NULLvariadic positionalZero or more values
foo <- c()repeatable --fooMultiple values as strings
foo <- list()repeatable --fooMultiple values parsed as YAML/JSON
switch("", cmd1={}, cmd2={})subcommandsapp cmd1, app cmd2
switch(cmd <- "", ...)subcommandsSame; captures command name in cmd
Type behavior
  • Non-string scalars are parsed as YAML/JSON at the CLI and coerced to the R type of the default. n <- 5L means --n 10 gives integer 10L.
  • NA defaults signal optional arguments. Test with !is.na(myvar).
  • Snake case variable names map to kebab-case: n_flips → --n-flips.
  • Positional args always arrive as character strings — convert manually.

Script Structure

Shebang line
r
#!/usr/bin/env Rapp

Makes the script directly executable on macOS/Linux after chmod +x. On Windows, call Rapp myscript.R explicitly.

Front matter metadata

Hash-pipe comments (#|) before any code set script-level metadata:

r
#!/usr/bin/env Rapp
#| name: my-app
#| title: My App
#| description: |
#|   A short description of what this app does.
#|   Can span multiple lines using YAML block scalar `|`.

The name: field sets the app name in help output (defaults to filename).

Per-argument annotations

Place #| comments immediately before the assignment they annotate:

r
#| description: Number of coin flips
#| short: 'n'
flips <- 1L

Available annotation fields:

FieldPurpose
description:Help text shown in --help
title:Display title (for subcommands and front matter)
short:Single-letter alias, e.g. 'n' → -n
required:true/false — for positional args only
val_type:Override type: string, integer, float, bool, any
arg_type:Override CLI type: option, switch, positional
action:For repeatable options: replace or append

Add #| short: for frequently-used options — users expect single-letter shortcuts for common flags like verbose (-v), output (-o), or count (-n).


Named Options

Scalar literal assignments become named options:

r
name <- "world"          # --name <value>    (string, default "world")
count <- 1L              # --count <int>     (integer, default 1)
threshold <- 0.5         # --threshold <flt> (float, default 0.5)
seed <- NA_integer_      # --seed <int>      (optional, NA if omitted)
output <- NA_character_  # --output <str>    (optional, NA if omitted)

For optional arguments, test whether the user supplied them:

r
seed <- NA_integer_
if (!is.na(seed)) set.seed(seed)
Show full SKILL.md (318 more words)Show less

Boolean Switches

TRUE/FALSE assignments become toggles:

r
verbose <- FALSE   # --verbose or --no-verbose
wrap <- TRUE       # --wrap (default) or --no-wrap

Values yes/true/1 set TRUE; no/false/0 set FALSE.

Repeatable Options

r
pattern <- c()     # --pattern '*.csv' --pattern 'sales-*'  → character vector
threshold <- list() # --threshold 5 --threshold '[10,20]'   → list of parsed values

Positional Arguments

Assign NULL for positional args (required by default):

r
#| description: The input file to process.
input_file <- NULL

Make optional with #| required: false. Test with is.null(myvar).

Variadic positional args

Use ... suffix to collect multiple positional values:

r
pkgs... <- c()
# install-pkgs dplyr ggplot2 tidyr → pkgs... = c("dplyr", "ggplot2", "tidyr")

Subcommands

Use switch() with a string first argument to declare subcommands. Options before the switch() are global; options inside branches are local to that subcommand.

r
switch(
  command <- "",

  #| title: Display the todos
  list = {
    #| description: Max entries to display (-1 for all).
    limit <- 30L
    # ... list implementation
  },

  #| title: Add a new todo
  add = {
    #| description: Task description to add.
    task <- NULL
    # ... add implementation
  },

  #| title: Mark a task as completed
  done = {
    #| description: Index of the task to complete.
    index <- 1L
    # ... done implementation
  }
)

Help is scoped: myapp --help lists commands; myapp list --help shows list-specific options plus globals. Subcommands can nest by placing another switch() inside a branch.


Built-in Help

Every Rapp automatically gets --help (human-readable) and --help-yaml (machine-readable). These work with subcommands too.


Development and Testing

Interactive Development

Use Rapp::run() to test scripts from an R session:

r
Rapp::run("path/to/myapp.R", c("--help"))
Rapp::run("path/to/myapp.R", c("--name", "Alice", "--count", "5"))

It returns the evaluation environment (invisibly) for inspection, and supports browser() for interactive debugging.

Testing CLI Apps in Packages

Use Rapp::run() with testthat snapshot testing. Test computed values by accessing the returned environment, and test output with expect_snapshot().

See references/advanced.md for detailed testing patterns, including:

  • Accessing computed values via the evaluation environment
  • Snapshot testing for help output and formatted text
  • Testing file side effects and state changes

Complete Example: Coin Flipper

r
#!/usr/bin/env Rapp
#| name: flip-coin
#| description: |
#|   Flip a coin.

#| description: Number of coin flips
#| short: 'n'
flips <- 1L

sep <- " "
wrap <- TRUE

seed <- NA_integer_
if (!is.na(seed)) {
  set.seed(seed)
}

cat(sample(c("heads", "tails"), flips, TRUE), sep = sep, fill = wrap)
sh
flip-coin            # heads
flip-coin -n 3       # heads tails heads
flip-coin --seed 42 -n 5
flip-coin --help

Generated help:

Usage: flip-coin [OPTIONS]

Flip a coin.

Options:
  -n, --flips <FLIPS>  Number of coin flips [default: 1] [type: integer]
      --sep <SEP>      [default: " "] [type: string]
      --wrap / --no-wrap  [default: true]
      --seed <SEED>    [default: NA] [type: integer]

Complete Example: Todo Manager (Subcommands)

r
#!/usr/bin/env Rapp
#| name: todo
#| description: Manage a simple todo list.

#| description: Path to the todo list file.
#| short: s
store <- ".todo.yml"

switch(
  command <- "",

  list = {
    #| description: Max entries to display (-1 for all).
    limit <- 30L

    tasks <- if (file.exists(store)) yaml::read_yaml(store) else list()
    if (!length(tasks)) {
      cat("No tasks yet.\n")
    } else {
      if (limit >= 0L) tasks <- head(tasks, limit)
      writeLines(sprintf("%2d. %s\n", seq_along(tasks), tasks))
    }
  },

  add = {
    #| description: Task description to add.
    task <- NULL

    tasks <- if (file.exists(store)) yaml::read_yaml(store) else list()
    tasks[[length(tasks) + 1L]] <- task
    yaml::write_yaml(tasks, store)
    cat("Added:", task, "\n")
  },

  done = {
    #| description: Index of the task to complete.
    #| short: i
    index <- 1L

    tasks <- if (file.exists(store)) yaml::read_yaml(store) else list()
    task <- tasks[[as.integer(index)]]
    tasks[[as.integer(index)]] <- NULL
    yaml::write_yaml(tasks, store)
    cat("Completed:", task, "\n")
  }
)
sh
todo add "Write quarterly report"
todo list
todo list --limit 5
todo done 1
todo --store /tmp/work.yml list

Shipping CLIs in an R Package

Place CLI scripts in exec/ and add Rapp to Imports in DESCRIPTION:

mypkg/
├── DESCRIPTION
├── R/
├── exec/
│   ├── myapp       # script with #!/usr/bin/env Rapp shebang
│   └── myapp2
└── man/

Users install the CLI launchers after installing the package:

r
Rapp::install_pkg_cli_apps("mypkg")

Expose a convenience installer so users don't need to know about Rapp:

r
#' Install mypkg CLI apps
#' @export
install_mypkg_cli <- function(destdir = NULL) {
  Rapp::install_pkg_cli_apps(package = "mypkg", destdir = destdir)
}

By default, launchers set --default-packages=base,<pkg>, so only base and the package are auto-loaded. Use library() for other dependencies.


Quick Reference: Common Patterns

NA vs NULL for optional arguments
  • NA (NA_integer_, NA_character_) → optional named option. Test: !is.na(x).
  • NULL + #| required: false → optional positional arg. Test: !is.null(x).
stdin/stdout
r
input_file <- NA_character_
con <- if (is.na(input_file)) file("stdin") else file(input_file, "r")
lines <- readLines(con)
writeLines(lines, stdout())
Exit codes and stderr
r
message("Error: something went wrong")   # writes to stderr
cat("Error:", msg, "\n", file = stderr()) # also stderr
quit(status = 1)                          # non-zero exit
Error handling
r
tryCatch({
  result <- do_work()
}, error = function(e) {
  cat("Error:", conditionMessage(e), "\n", file = stderr())
  quit(status = 1)
})

Additional Reference

For less common topics — launcher customization (#| launcher: front matter), detailed Rapp::install_pkg_cli_apps() API options, and more complete examples (deduplication filter, variadic install-pkg, interactive fallback) — read references/advanced.md.

© posit-dev, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 8 other files (references) in r-lib/r-cli-app of posit-dev/skills.

  • SKILL.md
  • .evals/convert-script/eval.md
  • .evals/convert-script/input-script.R
  • .evals/convert-script/prompt.md
  • .evals/simple-cli/eval.md
  • .evals/simple-cli/prompt.md
  • .evals/subcommand-tool/eval.md
  • .evals/subcommand-tool/prompt.md
  • references/advanced.md

Open the folder on GitHubat commit 0300946

Compare with similar skills

R CLI App next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

R CLI App compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
R CLI App this skillposit-dev/skills529—~2.9kAutomated safety check: PassMIT
Web Artifacts Builderanthropics/skills180k40 repos~769Automated safety check: PassApache-2.0
React Doctormakeplane/plane60k12 repos~657Automated safety check: PassAGPL-3.0
React Composition Patternsvercel-labs/openreview1.7k58 repos~721Automated safety check: PassMIT
Impeccablebestofjs/bestofjs3.1k27 repos~2.6kAutomated safety check: PassMIT
Figma Design System Builderwarpdotdev/warp65k2 repos~4.4kAutomated safety check: PassAGPL-3.0

Similar skills

  • Web Artifacts Builder

    anthropics/skills

    Official

    Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.

    180k GitHub starsUsed in 40 repos~769 tokens
    Frontend & DesignAuto-check passed
  • React Doctor

    makeplane/plane

    Scans React code for lint, accessibility, bundle size and architecture issues, reports a health score and checks that changes do not lower it.

    60k GitHub starsUsed in 12 repos~657 tokens
    Frontend & DesignAuto-check passed
  • React Composition Patterns

    vercel-labs/openreview

    Official

    Rules for structuring React components with composition instead of boolean props, covering compound components, lifted state, variants and React 19 changes.

    1.7k GitHub starsUsed in 58 repos~721 tokens
    Frontend & DesignAuto-check passed
  • Impeccable

    bestofjs/bestofjs

    A skill your agent uses when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a…

    3.1k GitHub starsUsed in 27 repos~2.6k tokens
    Frontend & DesignAuto-check passed
  • Builds or updates a design system in Figma from a codebase in ordered phases: discovery, variables and tokens, components, theming and documentation, with checkpoints.

    65k GitHub starsUsed in 2 repos~4.4k tokens
    Frontend & DesignAuto-check passed
  • Tailwindcss Development

    anonaddy/anonaddy

    Always invoke when the user's message includes 'tailwind' in any form.

    4.9k GitHub starsUsed in 10 repos~865 tokens
    Frontend & DesignAuto-check passed

More from posit-dev/skills

All 17 skills in this repo
  • R Lifecycle

    posit-dev/skills

    Guidance for managing R package lifecycle according to tidyverse principles using the lifecycle package.

    529 GitHub stars~1.5k tokensUpdated today
    Auto-check passed
  • PR Create

    posit-dev/skills

    Creates a pull request from current changes, monitors GitHub CI, and debugs any failures until CI passes.

    529 GitHub stars~4.3k tokensUpdated today
    Auto-check: warnings
  • Shiny Bslib

    posit-dev/skills

    Build modern Shiny dashboards and applications using bslib (Bootstrap 5).

    529 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Shiny Bslib Theming

    posit-dev/skills

    Advanced theming for Shiny apps using bslib and Bootstrap 5.

    529 GitHub stars~3.6k tokensUpdated today
    Auto-check passed
  • Critical Code Reviewer

    posit-dev/skills

    Rigorously review code or pull requests for correctness, security, accessibility, maintainability, tests, and edge cases.

    529 GitHub stars~3.9k tokensUpdated today
    Auto-check passed
  • Deploy To Connect

    posit-dev/skills

    Deploy or publish Python and R content to a Posit Connect server using rsconnect-python or the R rsconnect package.

    529 GitHub stars~5k tokensUpdated today
    Auto-check: notes

Questions about R CLI App

What does R CLI App do?

Build command-line apps in R using the Rapp package. An agent skill from posit-dev/skills. R CLI App is an agent skill from posit-dev/skills. Build command-line apps in R using the Rapp package.

When should I use R CLI App?

R CLI App fits situations like: creating a CLI tool in R; adding argument parsing to an R script; turning an R script into a command-line app; shipping CLIs in an R package.

How do I install R CLI App in Claude Code?

Run `npx skills add posit-dev/skills --skill r-cli-app -a claude-code`. Or copy the skill folder (r-lib/r-cli-app in posit-dev/skills) into .claude/skills/r-cli-app in your project. Claude Code loads it when a task matches its description.

How do I install R CLI App in Codex?

Run `npx skills add posit-dev/skills --skill r-cli-app -a codex`. Or copy the skill folder (r-lib/r-cli-app in posit-dev/skills) into .agents/skills/r-cli-app in your project. Codex loads it when a task matches its description.

Can I use R CLI App in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add posit-dev/skills --skill r-cli-app -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/r-cli-app, .gemini/skills/r-cli-app, .github/skills/r-cli-app and .opencode/skills/r-cli-app in your project.

What does R CLI App need to run?

Going by SKILL.md and its folder, R CLI App needs R for the scripts in its folder.

Does R CLI App access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is R CLI App safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does R CLI App use?

R CLI App is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does R CLI App use?

About 2.9k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.4k tokens, read only when the agent opens those files.

What are the alternatives to R CLI App?

Skills that share tags, products or a category with R CLI App: Web Artifacts Builder (anthropics/skills, 180k stars), React Doctor (makeplane/plane, 60k stars), React Composition Patterns (vercel-labs/openreview, 1.7k stars) and Impeccable (bestofjs/bestofjs, 3.1k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains R CLI App?

posit-dev (a GitHub organization) maintains it in posit-dev/skills, which has 529 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on October 6, 2026.

Source: posit-dev/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.