Skip to content
Back to skills

charmed-gum

BSecurity

Write interactive shell scripts with the gum CLI (Charm, charmbracelet): choose, filter, confirm, input, write, file, spin, table, pager, style, join, format, and log, with their flags, exit codes, environment variable defaults, and Bash examples. Use when a Bash or shell script needs a prompt, menu, picker, fuzzy finder, yes or no question, text input, spinner, CSV table, pager, styled output with borders and terminal colors, rendered Markdown, or log lines, without writing Go. Not for Go pr...

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 12, 2026
ai-agentsgoshellbashtestinggit

Works with

  • cursor
  • terminal
  • cli

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URLin references/commands.md

Pro scans all 4 files and shows the line behind each finding

Scanned October 12, 2026

npx -y skills add tpscloud/charmedimsure --skill charmed-gum --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of charmed-gum?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for charmed-gum
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/tpscloud-charmed-gum/badge)](https://www.skillsdirectory.com/skills/tpscloud-charmed-gum)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: charmed-gum
description: "Write interactive shell scripts with the gum CLI (Charm, charmbracelet): choose, filter, confirm, input, write, file, spin, table, pager, style, join, format, and log, with their flags, exit codes, environment variable defaults, and Bash examples. Use when a Bash or shell script needs a prompt, menu, picker, fuzzy finder, yes or no question, text input, spinner, CSV table, pager, styled output with borders and terminal colors, rendered Markdown, or log lines, without writing Go. Not for Go programs (charmed-huh, charmed-bubbletea)."
license: "MIT"
---

# gum

Add prompts, pickers, spinners, tables, and styled output to Bash scripts
with the gum CLI, with exact flags, keys, and exit codes so scripts handle
cancellation correctly.

Written from gum 2.0.2 (its source, `gum --help`, and each subcommand's help),
the baseline for this skill; run `gum --version` first (2.x prints
`gum version 2.0.2`) and confirm a flag with `gum <cmd> --help` on the
installed version before relying on it.

If the request names a subcommand, go straight to it. Full flags and keys for
every subcommand are in [references/commands.md](references/commands.md).

## Workflow

1. Check the installed version with `gum --version`, or guard the script with
   `gum version-check '>=2.0.0' || exit 1`, which exits 1 outside the range.
2. Pick the command: `choose` for a short list, `filter` past a couple dozen
   items, `confirm` for yes/no, `input` or `write` for text, `file` for a
   path, `spin` around a slow command, `style`, `join`, `format`, `table`,
   `pager`, or `log` for output.
3. Capture the result with `$(...)` and chain `|| exit 1` so an abort stops
   the script; then check for an empty result where the command allows one.
4. Run `bash -n script.sh` to catch syntax errors before running it.
5. Run the script in a terminal and exercise the edges: Ctrl+c, Esc, a
   declined confirm, and an empty selection. If a prompt does not show or a
   value is wrong, check the rules in [How gum behaves](#how-gum-behaves)
   and the command's section in [references/commands.md](references/commands.md).

## How gum behaves

- Prompts draw on stderr; the result goes to stdout. Capture with `$(...)`
  and the UI still shows.
- Ctrl+c aborts with exit status 130, and Esc aborts with a nonzero status in
  every prompt except `table` (in `filter`, the first Esc only leaves the
  search box). The exit status is the reliable signal: some commands can
  still print a preselected value on abort, so test `$?` (or chain
  `|| exit 1`) before using the captured variable. `gum table` is the
  exception: Esc or q exits 0 with an empty line, so check the captured row
  as well.
- Many flags expose environment defaults such as `GUM_CHOOSE_CURSOR` and
  `GUM_INPUT_PLACEHOLDER`; check the subcommand help for the exact names.
  Selection flags such as `choose --limit` and `--no-limit` have no env
  binding. `gum style` uses bare names (`FOREGROUND`, `BORDER`, `PADDING`).
- Style flags share a shape: `--<part>.foreground`, `--<part>.background`,
  and often `--padding "0 1"`. Colors are ANSI indexes or hex.
- `style`, `join`, `format`, and `table --print` write through a color
  profile writer: when stdout is not a terminal (a pipe, a file, or `$(...)`)
  the ANSI styling is stripped and the borders and layout stay.
  `CLICOLOR_FORCE=1` keeps the colors and `NO_COLOR=1` removes them.
- `--timeout 30s` ends an interactive command after the duration. `confirm`
  then returns its default; the other prompts print "timed out" and exit 124.
- Options arrive as arguments or one per line on stdin. Output is one
  selection per line; change with `--output-delimiter`.

## Prompts

```sh
# pick one, or several (x or tab toggles, a selects all)
format=$(gum choose --header "Format" JSON YAML TOML) || exit 1
tasks=$(printf '%s\n' "List files" "Show size" | \
  gum choose --no-limit --selected='*' --ordered --header "Tasks") || exit 1
[[ -n $tasks ]] || exit 0   # --no-limit allows confirming an empty selection

# fuzzy search over a long list
file=$(find . -type f -name '*.md' | gum filter --placeholder "Which Markdown file?") || exit 1

# text
name=$(gum input --placeholder "project name" --header "Name") || exit 1
msg=$(gum write --header "Commit message" --placeholder "what changed?" --char-limit 500) || exit 1

# a directory (needs at least one subdirectory to choose from)
dir=$(gum file . --directory --file=false --all) || exit 1

# yes or no
if gum confirm "List files in the current directory?"; then
  ls -la .
fi
```

`confirm` exits 0 for the affirmative and 1 for the negative or Esc. Ctrl+c
returns a nonzero status. An `if` branch runs only on success. In `write`,
Enter submits and Ctrl+J inserts a newline.

## spin

```sh
gum spin --spinner dot --show-output --title "Listing files" -- find . -type f
gum spin --show-output --title "Measuring directory" -- du -sh .
```

The command's exit status is gum's exit status. `--show-output` streams both
stdout and stderr. With `--show-output` alone, a failing command's output is
discarded; add `--show-error` to print it. These flags apply only when stdout
is a terminal. When stdout is a pipe, a file, or `$(...)`, gum hands it to the
command directly, so its stdout is captured with or without `--show-output`,
even when it fails. `--timeout` makes gum stop waiting and exit 124, but the
command keeps running; wrap it in `timeout(1)` when it must stop.

## Output commands

```sh
gum style --foreground 212 --border double --padding "1 3" "Project tasks"
gum join --horizontal --align top "$left" "$right"
gum format < README.md
gum table --print --border rounded --file status.csv
gum pager < CHANGELOG.md
gum log --structured --level info "task completed" task "List files"
```

Read [references/commands.md](references/commands.md) for the style flags and
env defaults, `join` layouts, `format` types (code, template, emoji) and
themes, interactive `table` row selection, `pager` search, and `log` levels,
formatters, and time layouts.

## Putting it together

```sh
#!/usr/bin/env bash
set -euo pipefail

gum style --border rounded --padding "0 2" --foreground 212 "Project tasks"

tasks=$(gum choose --no-limit --selected='*' --ordered --header "Tasks" \
  "List files" "Show size") || exit 1
[[ -n $tasks ]] || { gum log --level warn "No tasks selected"; exit 0; }
dir=$(gum file . --directory --file=false --all) || exit 1

gum confirm "Run the selected tasks in $dir?" || exit 1

while IFS= read -r task; do
  case "$task" in
    "List files") gum spin --show-output --show-error --title "$task" -- ls -la "$dir" ;;
    "Show size") gum spin --show-output --show-error --title "$task" -- du -sh "$dir" ;;
    *) printf 'Unknown task: %s\n' "$task" >&2; exit 1 ;;
  esac
  gum log --structured --level info "task completed" task "$task" directory "$dir"
done <<<"$tasks"
```

The examples use Bash syntax. The complete recipe was exercised with gum
2.0.2, including cancellation, a declined confirm, and an empty selection. It
uses `set -euo pipefail` and a here string. For fish, adapt the assignments,
loops, and error handling to fish syntax. A complete fish recipe is not
included; fish and Zsh versions have not been tested.

## Mistakes that cost time

- Testing `[ -n "$choice" ]` but not the exit status. An aborted prompt can
  still print a preselected value in some commands; check `$?`.
- Redirecting stderr to a file while a prompt runs. The UI vanishes, and in
  2.0.2 `gum input` without `--width` panics and exits 124 with "timed out".
- Passing options with spaces as one argument to `choose`. Quote each option,
  or feed them on stdin one per line.
- Forgetting `--no-limit` and then wondering why only one item comes back.
- Telling users to press space in `gum choose` or Ctrl+Space in `gum filter`.
  Use x or tab in `choose` and tab in `filter`.
- Using `gum spin` for a command that needs the TTY (an editor, a login
  prompt). spin captures the command's output; run those directly.

## Older versions

- Install: package managers ship 2.0.2 (`brew install gum`,
  `nix-env -iA nixpkgs.gum`), and `go install charm.land/gum/v2@latest`
  builds the current release. The old path `github.com/charmbracelet/gum`
  stops at 0.17.0.
- `gum --version` on 0.17.0 printed the version with a leading `v`; 2.x
  prints it without one (`gum version 2.0.2`).
- Flags, defaults, and env names match 0.17.0. The move to Bubble Tea v2
  changed some keys and output handling:
  - Space and Ctrl+Space toggled in `choose` in 0.17.0 and do nothing in 2.x.
  - Ctrl+Space toggled in `filter` in 0.17.0; 2.x uses tab.
  - In 0.17.0, `format` kept its colors when piped; 2.x strips them like
    `style` and `join`.

Files in this skill

  • LICENSES/MIT.txt1.1 KB
  • NOTICE.md733 B
  • SKILL.md8.5 KB
  • references/commands.md7.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.