Skip to content

sugarcraft/candy-shell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

63 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

candy-shell

CandyShell

CI codecov Packagist Version License PHP

demo

composer require sugarcraft/candy-shell

PHP port of charmbracelet/gum β€” a composer-installable CLI of SugarCraft TUI primitives, useful for shell scripts.

# Apply styling.
candyshell style --foreground "#ff5f87" --bold "Hello, candy!"

# Pick one item.
choice=$(candyshell choose Pizza Burger Salad)

# Read a single line.
name=$(candyshell input --placeholder "Your name?")

# Confirm a destructive action.
candyshell confirm "Really delete $file?" && rm "$file"

Subcommands

All 13 gum subcommands ship. Run candyshell <cmd> --help for the full flag list per command.

Command Role
choose Pick one or many items from a list.
confirm Yes/no prompt β€” exit 0 on confirm, 1 on cancel.
file Interactive file picker.
filter Fuzzy filter over stdin lines (single- or multi-select).
format Render Markdown / code / template / emoji to the terminal.
input Read a single line; supports --password masking.
join Concatenate two styled fragments side-by-side or stacked.
log Levelled / structured log output (text Β· json Β· logfmt).
pager Scrollable viewer for long input.
spin Run an external command behind a spinner.
style Apply Sprinkles styling to argv (or stdin).
table Render a CSV / TSV table.
write Multi-line text editor.

Flag reference (selected highlights)

The audit lists upstream-gum flags that are not yet wired in CandyShell. The shipped surface today covers the 80 % case for shell scripts; see AUDIT_2026_05_06.md for the full delta. Common flags across commands:

  • --limit N / --no-limit / --ordered / --selected="a,b" β€” multi-select on choose and filter.
  • --header "Email:" / --prompt "> " / --value "$LAST" / --char-limit N / --width N / --max-lines N / --show-line-numbers on input / write.
  • --affirmative "Yes" / --negative "No" / --default=yes|no / --show-output on confirm.
  • --show-output / --show-error plus 12 spinner styles (dot Β· line Β· pulse Β· globe Β· points Β· monkey Β· moon Β· meter Β· mini-dot Β· hamburger Β· ellipsis Β· jump) on spin.
  • --min-level info / --prefix / --time RFC3339 / --file out.log / --formatter text|json|logfmt / --structured on log.
  • --border / --border-foreground "#ff0" / --height N / --trim on style.

Environment

CandyShell respects standard CLI colour conventions:

  • NO_COLOR=1 disables every SGR escape β€” output is plain ASCII.
  • CLICOLOR=0 disables colour when stdout is not a TTY (otherwise defaults to colour).
  • CLICOLOR_FORCE=1 keeps colour even when stdout is piped or redirected.
  • FORCE_COLOR=1|2|3 forces a specific tier (16 / 256 / TrueColor).

Exit codes

  • 0 β€” normal completion. For confirm, this means the user picked the affirmative answer.
  • 1 β€” confirm declined; or non-zero exit forwarded from the external command run by spin.
  • 130 β€” interrupted (Ctrl-C / SIGINT). Matches POSIX shell convention.

Porting from gum

Most gum X invocations work as candyshell X verbatim. Known behavioural differences (also see AUDIT_2026_05_06.md):

  • format accepts -t/--type (markdown, code, template, emoji) alongside --theme. Template support is the lightweight {{VAR}} expansion β€” Go template-function helpers are not implemented.
  • --style flags using the gum dotted form (--header.foreground, --cursor.foreground, …) are not yet wired across every command.
  • --timeout, --show-help, --strip-ansi, and the --cursor-mode flags now accept their gum-equivalent values on every command. Where a flag is meaningless to a non-interactive command (format, join, log, style, table) it is still accepted for parity but treated as a no-op.
  • confirm --default=yes|no is the form to use; the older --default-yes alias is preserved.

Theming and customization

Almost every interactive subcommand accepts a --style flag in <element>.<property>=<value> form. Repeat the flag to layer properties or target multiple elements:

candyshell choose --style "cursor.foreground=212" \
                  --style "selected.bold=true" \
                  --style "header.foreground=99" \
                  --header "Pick a colour" red green blue

Available properties on every element: foreground, background, bold, italic, underline, strikethrough, faint, blink, reverse. Element names are documented inline in each subcommand's --help output (choose exposes cursor, header, selected, unselected; confirm exposes prompt, selected, unselected; input/write expose prompt, placeholder, cursor, header, lineNumber).

Colour values accept the same surface as CandySprinkles: hex (#ff8800), ANSI 0–15 (9 for bright red), 8-bit (212), and named CSS colours (coral, slategray).

Themes for format ride on CandyShine: pass --theme dracula, --theme tokyo-night, --theme dark, --theme light, --theme pink, --theme ascii, or --theme notty to swap renderer presets without authoring a Style yourself. --type code --language=go reuses the markdown pipeline for syntax-only rendering, while --type emoji expands the built-in :smile: shortcode set (unknown shortcodes pass through verbatim).

The same Style rules apply to the style subcommand, which is the canonical way to compose lipgloss-style boxes from a script:

candyshell style --foreground=212 --bold --border rounded \
                 --padding "1 4" --margin "0 2" "Welcome aboard"

Test

cd candy-shell && composer install && vendor/bin/phpunit

Demos

choose

choose

Confirm

confirm

file

file

filter

filter

format

format

Input

input

join

join

log

log

pager

pager

spin

spin

Style

style

Table

table

write

write

About

🐚 PHP port of 🍬 gum β€” 13 CLI primitives: choose, confirm, file, filter, format, input, join, log, pager, spin, style, table, write.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages