Install
$ agentstack add skill-alxxpersonal-forge-charm-gum ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
charm-gum
gum is a CLI for glamorous shell scripts. All interaction writes to stdout; capture with $(). All commands render to stderr so stdout stays clean for piping.
Quick Start
brew install gum # macOS/Linux
go install github.com/charmbracelet/gum@latest
NAME=$(gum input --placeholder "your name")
gum confirm "Continue?" && echo "hello $NAME"
Every flag has an env var equivalent: --placeholder = GUM_INPUT_PLACEHOLDER. Export env vars to set defaults project-wide.
Command Reference
input - single-line prompt
gum input [flags]
# key flags:
# --placeholder "text" hint text
# --value "text" pre-filled value
# --password mask input
# --header "text" label above input
# --width N fixed width (0 = terminal width)
# --char-limit N max chars (default 400, 0 = unlimited)
# --timeout 30s auto-submit after duration
NAME=$(gum input --placeholder "full name" --header "Enter your name")
PASS=$(gum input --password --placeholder "password")
write - multi-line textarea
gum write [flags]
# key flags:
# --placeholder "text"
# --header "text"
# --width N, --height N
# --show-line-numbers
# --show-cursor-line
# --max-lines N
# ctrl+d to submit, ctrl+c to cancel
BODY=$(gum write --placeholder "PR description..." --header "Description" --width 80)
choose - pick from a list
gum choose [options...] [flags]
# pipe options or pass as args
# key flags:
# --limit N max selectable (default 1)
# --no-limit unlimited selection
# --header "text"
# --height N visible rows (default 10)
# --cursor "> " cursor prefix
# --selected "val" pre-selected item
# --ordered preserve selection order
# --timeout 30s
TYPE=$(gum choose "fix" "feat" "docs" "chore" "refactor")
PKGS=$(brew list | gum choose --no-limit --header "Remove packages")
filter - fuzzy search a list
gum filter [options...] [flags]
# reads from stdin or args; fuzzy match by default
# key flags:
# --limit N
# --no-limit
# --placeholder "text"
# --header "text"
# --height N
# --value "text" initial filter query
# --no-fuzzy prefix match only
# --no-strict return query if no match
# --reverse render from bottom
SESSION=$(tmux list-sessions -F '#S' | gum filter --placeholder "pick session...")
BRANCH=$(git branch | cut -c 3- | gum filter --placeholder "checkout...")
confirm - yes/no prompt
gum confirm [prompt] [flags]
# exits 0 = yes, 1 = no; use with && / ||
# key flags:
# --affirmative "Yes" confirm button label
# --negative "No" cancel button label
# --default which is pre-selected (true = yes)
# --timeout 30s
# --show-output echo chosen action to stdout
gum confirm "Delete branch?" && git branch -D "$BRANCH"
gum confirm "Overwrite?" --affirmative "Overwrite" --negative "Skip" || exit 0
spin - spinner while command runs
gum spin [flags] --
# key flags:
# --title "text" message shown next to spinner
# --spinner dot type: line,dot,minidot,jump,pulse,points,globe,moon,monkey,meter,hamburger
# --show-output stream stdout/stderr live
# --show-error show output only on failure
# --timeout 60s
gum spin --title "Installing deps..." -- npm install
OUTPUT=$(gum spin --show-output --title "Fetching..." -- curl -s https://api.example.com/data)
style - styled text output
gum style [flags] "text" ["text2" ...]
# multiple strings are rendered as separate lines in one block
# key flags:
# --foreground "#hex"|"256color"
# --background "#hex"|"256color"
# --border none|hidden|normal|rounded|thick|double
# --border-foreground
# --align left|center|right
# --width N, --height N
# --margin "T R B L" (css shorthand)
# --padding "T R B L"
# --bold, --italic, --underline, --strikethrough, --faint
gum style --foreground 212 --border rounded --padding "1 2" "Done!"
format - render markdown, code, templates, emoji
gum format [flags] [text...]
# key flags:
# -t markdown|template|code|emoji (default: markdown)
# -l python language hint for code type
# --theme pink glamour theme for markdown
echo "# Hello\n- item 1\n- item 2" | gum format
cat script.sh | gum format -t code -l bash
echo '{{ Bold "OK" }} {{ Color "99" "0" " gum " }}' | gum format -t template
echo "I :heart: gum :candy:" | gum format -t emoji
join - compose styled blocks side by side or stacked
gum join [flags] "block1" "block2"
# flags:
# --vertical stack top to bottom (default is horizontal)
# --align left|center|right
# always quote gum style output to preserve newlines
A=$(gum style --border rounded --padding "0 2" "left")
B=$(gum style --border rounded --padding "0 2" "right")
gum join "$A" "$B"
file - file picker from tree
gum file [path] # defaults to current dir
# flags: --cursor, --height, --show-hidden
$EDITOR "$(gum file $HOME)"
pager - scrollable viewer
gum pager _` format. Set in shell profile for persistent defaults:
```bash
export GUM_CHOOSE_CURSOR_FOREGROUND="#FF79C6"
export GUM_INPUT_PLACEHOLDER="..."
export GUM_SPIN_SPINNER="dot"
Common Mistakes
- capturing output: gum writes the prompt to stderr, result to stdout.
VAL=$(gum input)works correctly. - spin command separator:
--is required before the command:gum spin --title "..." -- npm install. Without it gum parses your command as its own flags. - confirm exit code:
gum confirmreturns 0 for yes, 1 for no. Use&&/||notif [ $? -eq 0 ]- both work but&&is idiomatic. - join with newlines: always quote
$(gum style ...)in join args or newlines collapse:gum join "$A" "$B"notgum join $A $B. - filter with no match: by default
--strictis on - filter returns nothing if no match. Use--no-strictto return the query string instead. - choose vs filter:
choose= static list, cursor navigation.filter= fuzzy search while typing. Use filter for long lists. - multi-select output: each selection on its own line. Iterate with
while IFS= read -r item; do ... done <<< "$SELECTION".
Checklist
- [ ] capture interactive output with
$(), not redirect - [ ] add
-- commandseparator forgum spin - [ ] handle empty selection (
[ -z "$VAR" ] && exit 0) - [ ] use
--no-limitfor multi-select, iterate output line by line - [ ] use
--default=falseon destructive confirms - [ ] quote
$(gum style ...)when passing togum join - [ ] set
--timeoutfor unattended or CI-adjacent scripts - [ ] test ctrl+c behavior - gum exits non-zero, handle with
set -eor explicit checks
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: alxxpersonal
- Source: alxxpersonal/forge
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.