# TerminalWidget — full documentation
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Index of links: https://terminalwidget.app/llms.txt
This file concatenates the Markdown exports listed in llms.txt for one-pass ingestion. Individual pages remain available at the Source URLs below.
---
## Docs: TerminalWidget CLI
Source: https://terminalwidget.app/cli.md
# TerminalWidget CLI
> Command-line and URL scheme documentation for TerminalWidget.
Source: https://terminalwidget.app/cli
Use the TerminalWidget command-line tool to update widgets from scripts, shell commands, and automation.
**Add a widget first.** Updates only appear on widgets you place yourself (Desktop or Home Screen) after you set **Edit Widget → Target name** to match `--target`. See [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
If you prefer Script Editor or AppleScript-based automation, see [AppleScript Documentation](https://terminalwidget.app/applescript.md).
**Looking for ready-made CLI recipes?** The [Widgets](https://terminalwidget.app/widgets.md#text-widgets) page has screenshot-matched examples for every mode — text, progress, charts, tables, and especially [launcher button JSON](https://terminalwidget.app/widgets.md#launcher-buttons-buttons-in-json). Scroll past the image gallery to the command sections below.
## Usage
```text
terminal-widget [--target NAME] [--clear|--clear-buttons] [--text "STRING"|--text -] [--no-wrap] [--ansi-mode auto|on|off] [--strip-colors] [--icon "SF_SYMBOL"] [--font "FONT NAME"] [--font-size POINTS] [--fit-text] [--fg COLOR] [--text-color COLOR] [--caption-color COLOR] [--title TEXT] [--title-alignment left|center|right] [--title-color COLOR] [--bg COLOR] [--alpha A] [--progress N[,N...] --progress-format MODE --progress-layout LAYOUT --gradient-from COLOR --gradient-to COLOR --gradient-width N] [--chart "N N ..." --chart-format MODE --chart-height N[%] --neo-characters SET --base-zero|--base N --bar-radius N --chart-bar-style solid|glass] [--table PATH|-] [--no-header] [--grid MODE] [--table-layout auto|equal|fill] [--table-align left,center,right] [--center-table] [--caption] [--caption-text TEXT] [--caption-left TEXT] [--caption-right TEXT] [--annotate] [--label-y] [--timestamp] [--image PATH_OR_URL|--background-image PATH_OR_URL] [--filter FILTER[:VALUE][,FILTER[:VALUE]...]] [--padding N|fill|--fullsize] [--theme|--mode system|light|dark] [--notify] [--no-notify] [--notify-once] [--json PATH|-] [--action-kind KIND --action-value VALUE|--clear-action]
```
```text
terminal-widget completions [--shell fish|bash|zsh|all] [--name CMD ...] [--install] [--stdout]
```
## Install CLI Command
If `TerminalWidget.app` is installed in `/Applications`, symlink `terminal-widget` into your user bin (no `sudo` required):
```bash
mkdir -p "$HOME/bin"
ln -sf /Applications/TerminalWidget.app/Contents/MacOS/TerminalWidget "$HOME/bin/terminal-widget"
```
You can create this symlink anywhere in your `$PATH` (for example `~/.local/bin`, `/opt/homebrew/bin`, or `/usr/local/bin`).
If you prefer a shell function instead of a symlink, add one of these snippets:
```bash
# Bash (~/.bashrc or ~/.bash_profile)/Zsh (~/.zshrc)
terminal-widget() {
/Applications/TerminalWidget.app/Contents/MacOS/TerminalWidget "$@"
}
```
```fish
# Fish (~/.config/fish/functions/terminal-widget.fish)
function terminal-widget
/Applications/TerminalWidget.app/Contents/MacOS/TerminalWidget $argv
end
```
## Shell Completions
Generate Fish, Bash, and Zsh completion scripts so you can tab-complete all `terminal-widget` flags and options.
- Generated scripts register the basename of the invoked binary (`$0`) plus its casing counterpart, so `TerminalWidget` and `terminal-widget` both tab-complete. That covers shell functions and aliases, which keep the real binary name in `argv[0]`.
- `--name CMD` adds another token to register and is repeatable. The first `--name` value also names the generated files.
- Without `--install` or `--stdout`, writes scripts into `./completions/` in the current directory: `NAME.fish`, `NAME.bash`, and `_NAME` (Zsh).
- `--install` auto-detects the current shell (or pass `--shell`) and writes to that shell's user completion directory. Does not edit shell rc files.
- `--stdout` prints one shell's script to stdout; requires a single `--shell` (`fish`, `bash`, or `zsh`, not `all`).
When invoked through the sandboxed app binary, `--install` cannot write to your shell configuration directory. Use `--stdout` and redirect it from your shell instead:
```bash
terminal-widget completions --shell fish --stdout > ~/.config/fish/completions/terminal-widget.fish
```
```bash
# Write scripts into ./completions for the current binary name
terminal-widget completions
# Install for the current shell (auto-detect)
terminal-widget completions --install
# Force shell + register an extra command name (repeatable)
terminal-widget completions --shell fish --name tw --install
```
```fish
terminal-widget completions --install
# then open a new Fish session (or source ~/.config/fish/completions/terminal-widget.fish)
```
Install paths by shell:
- **Fish:** `~/.config/fish/completions/NAME.fish`
- **Zsh:** `~/.zsh/completions/_NAME`
- **Bash:** `~/.local/share/bash-completion/completions/NAME` (extensionless)
Zsh users may need `~/.zsh/completions` on `fpath` before `compinit` (for example `fpath=(~/.zsh/completions $fpath)` in `~/.zshrc`). The CLI does not modify rc files for you.
Run `terminal-widget completions --help` for all subcommand flags.
## Diagnostics
Inspect recent failures and warnings without digging through Console.app. On each device, the host app and widget extension append to one bounded event log in that device’s App Group container. The log is **device-local**: your Mac does not show iPhone events, and your phone does not show Mac CLI or menu-bar app events.
**Mac:** read the log with the `log` subcommand, **Info/Debug → Recent events** in the menu bar app, or a **`twdiags`** widget.
**iPhone and iPad:** add a widget whose **Target name** is `twdiags`. There is no Info/Debug panel and no `terminal-widget log` on device — the widget is the viewer.
### Diagnostics widget (`twdiags`)
Name any widget’s **Target name** `twdiags` (case-insensitive) and it shows recent diagnostic events from **that device** as its text. No special payload is written for that target: the timeline provider substitutes the log into the target’s existing styling, so normal flags still apply for colors, fonts, and background.
**Setup**
1. Add a Terminal Widget on the Desktop or Home Screen.
2. Open **Edit Widget** and set **Target name** to `twdiags`.
3. On Mac, optionally style it from the CLI:
```bash
terminal-widget --target twdiags --bg 111111 --fg 00ff88 --font Menlo --font-size 9
```
On iPhone and iPad, style the widget with Shortcuts, the URL scheme, or a Mac update that syncs styling via iCloud — the log text always comes from the local device.
The widget shows the newest matching events (default: warn and error, up to 12 lines). On iOS, appending an event does not itself refresh the widget; the display updates when WidgetKit rebuilds the timeline, including after updates that request a widget reload.
**What you will see**
Each line is one event: timestamp, level, optional target, and message.
On **Mac**, typical codes include failed launcher commands (`action.command_exit`), missing apps (`action.app_not_found`), image failures (`image.*`), save/sync problems (`save.failed`, `cloud.*`), and reload/timeline pairing (`reload.requested`, `timeline.built`).
On **iOS**, events come from Shortcuts and URL-scheme updates, CloudKit pull/push/subscribe failures, button/tap action failures, image fetch/copy/render misses, save failures, and the same reload/timeline pairing (`reload.requested`, `timeline.built`). The pairing events are `info` level, so the default `warn` threshold hides them until `TerminalWidgetDiagnosticsLevel` is set to `info`.
**Notes**
- A widget that already used the target name `twdiags` for something else will be taken over by the diagnostics view.
- The diagnostics widget does not log its own timeline builds, so it will not flood itself with `timeline.built` noise.
- Content such as charts, progress, and images on a `twdiags` target is cleared when the log is rendered; only text styling fields are kept.
- Each device keeps its own log file; iCloud widget sync does not mirror diagnostics history across Mac and iPhone.
### `terminal-widget log` (Mac only)
```bash
terminal-widget log [--level error|warn|info] [--target NAME] [--limit N] [--follow] [--json] [--clear]
```
- `--level LEVEL` Minimum severity to show: `error`, `warn`, or `info` (default `info`).
- `--target NAME` Only events for this widget target.
- `--limit N` Newest N matching events.
- `--follow` Stream new matching events until interrupted.
- `--json` Emit one JSON object per line instead of the human-readable one-line format.
- `--clear` Wipe the entire log. Cannot be combined with `--target`, `--level`, `--limit`, or `--follow`.
Examples:
```bash
# Recent events (info and above)
terminal-widget log
# Warnings and errors for one target
terminal-widget log --level warn --target cpu --limit 20
# Watch live while tapping a broken launcher button
terminal-widget log --follow --level warn
```
### Preferences
Two App Group preferences control what the `twdiags` widget shows (the `log` command has its own `--level` / `--limit` flags):
- `TerminalWidgetDiagnosticsLevel` — minimum level for `twdiags` (`error`, `warn`, or `info`; default `warn`)
- `TerminalWidgetDiagnosticsLineCount` — how many lines `twdiags` renders (clamped to 1…100; default 12)
On Mac, you can set them from a shell:
```bash
defaults write group.brettterpstra.TerminalWidget TerminalWidgetDiagnosticsLevel -string info
defaults write group.brettterpstra.TerminalWidget TerminalWidgetDiagnosticsLineCount -int 20
```
The `defaults write` example is Mac-only. iPhone and iPad have no diagnostics settings UI; the same App Group keys are honored if set, and otherwise use `warn` and 12 lines. At the default `warn` level, `reload.requested` and `timeline.built` are recorded but hidden from `twdiags`; set the level to `info` to display them.
### Info/Debug (Mac only)
Open the menu bar app → **Info/Debug**. The panel lists **Recent events** with severity colors, and **Copy cloud diagnostics** includes that history on the clipboard. iPhone and iPad do not have this panel; use a `twdiags` widget on the Home Screen instead.
### Privacy
The log can include file paths, command text, and captured stderr. Those lines appear on the `twdiags` widget (Mac and iOS) and in Info/Debug on Mac. On Mac, clear the log with `terminal-widget log --clear` when you do not want that history kept.
## Options
- `--target NAME` Widget to update (matches Edit Widget "Target name"). If omitted, uses the last target written (`.lastTarget`), else the first registered widget name (`widget1`, `widget2`, ...), else `widget1`. The reserved name `twdiags` (case-insensitive) turns the widget into a [diagnostics log view](#diagnostics-widget-twdiags) instead of normal content.
- `--clear` Delete this target's payload file, per-target images, and App Group mirror entry; when iCloud sync is enabled, also deletes that target's cloud record. Other targets and the instance registry are untouched. Does not seed a demo payload. Incompatible with content/update flags (including `--clear-buttons`).
- `--clear-buttons` Remove launcher buttons from this target; keep all other content. Requires an existing payload. Incompatible with `--clear` and with content flags that set buttons in the same invocation.
- `--text STRING` Text line (shown above the progress bar when both are set). Supports CommonMark-style markdown links `[label](url)` on macOS and iOS widgets (tappable; see Notes).
- `--command COMMAND` Run a shell command and use its stdout as the widget text. If both `--text` and `--command` are set, `--command` wins. Prefer piping from your own shell (`… \| terminal-widget --text -`) when you need your full PATH, aliases, and functions.
- `--no-wrap` Truncate long lines with an ellipsis instead of soft-wrapping; explicit line breaks are preserved (each line truncates independently)
- `--ansi-mode MODE` ANSI rendering for text (`auto` default, `on`, or `off`)
- `--strip-colors` Strip ANSI escape sequences from text before display
- `--icon SF_SYMBOL` SF Symbol name; shown before text, or before the progress bar, or alone centered if nothing else is set
- `--font "FONT NAME"` Installed system font name used for text rendering (omitting `--font` resets to default)
- `--font-size POINTS` Base text size in points (`> 0`). Also acts as a minimum floor when full-width text fitting is enabled.
- `--fit-text` Scale text to fit widget width and height for text-only and text+icon layouts. Uses the same 10pt inset as `--padding fill` and vertically centers the scaled block, without enabling image fill mode.
- `--foreground COLOR` Text/icon color (alias: `--fg`). Accepts `RRGGBB`, `#RRGGBB`, `rgb(r,g,b)`, or `rgba(r,g,b,a)`. Comma-separated values use the **first** for text and icons and the **full list** as per-series colors for grouped sparkline/bar charts (up to four series).
- `--text-color COLOR` Color for the main `--text` line and default table cell styling; omit to use `--foreground`/theme.
- `--caption-color COLOR` Color for chart/progress captions (`[min/max]`, `[n%]`), `--caption-text`, `--caption-left` / `--caption-right` footer text, and the optional `--timestamp` line; omit to use `--foreground`/theme.
- `--title-color COLOR` Color for `--title`; omit to use `--foreground`/theme.
- `--background COLOR` Widget background color (alias: `--bg`). Accepts `RRGGBB`, `#RRGGBB`, `rgb(r,g,b)`, or `rgba(r,g,b,a)`.
- `--bg-gradient-from COLOR` Background gradient start color. Accepts the same formats as `--bg`.
- `--bg-gradient-to COLOR` Background gradient end color. Accepts the same formats as `--bg`. Legacy alias: `--bg-gradent-to`.
- `--bg-gradient-start DIR` Background gradient start direction (`n`, `s`, `e`, `w`, `nw`, `ne`, `sw`, `se`). End point is automatically the opposite direction. Also accepts aliases `top`, `right`, `bottom`, `left`, `topleft`, `topright`, `bottomleft`, `bottomright`.
- `--alpha A` Override alpha channel for `--foreground`/`--background`/`--text-color`/`--caption-color`/`--title-color` this update (`0.0...1.0`).
- `--progress N[,N...]` One `0-100` percentage, or comma-separated percentages for `quad4`; omit to hide progress on this update.
- `--progress-format bar|matrix|dots|stack|circle|watch|quadrant|quad4|gradient|gradient-horizontal|gradient-vertical` Progress style (default `bar`; `quad-4` aliases to `quad4`; `gradient` aliases to `gradient-horizontal`).
- `--progress-layout LAYOUT` Quadrant groups for `quad4`. Use comma-separated quadrants or clockwise ranges such as `1,2,3,4`, `1-2,3-4`, or `1-4`. Defaults to `1,2,3,4` and is rejected for other progress formats.
- `--gradient-from COLOR` Gradient start color for gradient progress formats. Uses the same color formats as `--fg` and `--bg`.
- `--gradient-to COLOR` Gradient end color for gradient progress formats. Uses the same color formats as `--fg` and `--bg`.
- `--gradient-width N` Gradient thickness in points (`1-2048`): width for vertical gradients, height for horizontal gradients.
- `--chart VALUES` Chart series values separated by spaces or commas. For **grouped sparkline/bar** columns, use slash-separated series (for example `0 1 5 2/1 2 5 3` draws two side-by-side sub-bars per column, up to four series). Use `low-high` pairs for `rangebar`. For **pie**, use `label:value[:color]` tokens (for example `CPU:45 Memory:30 Disk:25`). JSON input (via `--json` or structured refresh) may use a nested numeric array (for example `[[0,1,5],[1,2,5]]`), named series objects (for example `[{"name":"CPU","values":[1,2,3]}]`), or a `slices` array for pie. Omit to clear. Max 128 points per series (keeps the newest when over the cap).
- `--append VALUES` Append chart columns or text lines to the existing target. Chart append uses the same syntax as `--chart` (including slash-grouped columns and rangebar `low-high` pairs) and must match the existing chart shape. Text append joins with a newline. Preserves settings not overridden by this update. Incompatible with `--chart`, `--text`/`--command`, `--table`, and `--image`.
- `--limit N` Keep the last `N` chart columns or text lines in storage. Persists on the target until changed. `0` clears the soft limit (charts still hard-capped at 128 newest points). Works with `--chart`, `--text`, and `--append`, or alone to re-truncate existing data.
- `--base-zero` Force chart y-axis scaling to start at `0` (alias for `--base 0`).
- `--base N` Force chart y-axis scaling to start at numeric baseline `N` instead of the series minimum.
- `--chart-height N[%]` Override chart height. Use a positive point value (for example `50`) or percent of available chart area (for example `80%`). Default behavior is `100%`.
- `--chart-format MODE` Chart style (default: `sparkline`):
- `sparkline` (aliases: `spark`, `bar`): bar sparkline scaled min..max
- `graph` (alias: `line`): connected line with point markers
- `waveform` (alias: `wave`): centered mirrored bars interpolated between values
- `area`: line graph with area fill under the curve
- `lollipop`: stems from baseline with dots at values
- `strip` (alias: `dot`): dot/strip plot with no connecting line
- `radial`: circular/radial connected plot
- `delta`: positive/negative bars showing change between adjacent points
- `threshold`: line graph with threshold guide line
- `smooth`: smoothed curve interpolation
- `sine`: half-sine interpolation between points
- `peak`: line graph with peak point emphasized
- `matrix`: heatmap matrix values mapped to foreground alpha
- `rangebar`: contiguous range bars from `low-high` pairs such as `1-3,2-3,1-4`
- `series` (aliases: `lines`, `multiline`): overlapping line charts with shared Y scaling; use slash-separated groups like grouped sparklines (`1 2 3/4 5 6`). Legend labels default to `Series 1`, `Series 2`, … unless you pass `--chart-series-labels` or JSON `series: [{name, values}, …]`.
- `pie`: pie chart from `label:value[:color]` tokens (for example `CPU:45 Memory:30 Disk:25`) or JSON `slices` array
- `--chart-key auto|inline|left|bottom|external|none` Legend placement for `series` and `pie` charts (default `auto`). For **pie** on **medium** and **extra large** widgets, `auto`/`inline`/`left` show a side legend to the **left** of the pie (scaled to fill that column). For **series**, `auto`/`bottom` show the legend under the chart. `external` hides the legend on the main widget (pair with `--key-target`). A prior `--chart-key external` is **not** preserved when you update chart data without `--chart-key` — omit the flag (or use `auto`/`inline`) to show the legend again.
- `--chart-series-labels LIST` Comma-separated legend labels for `series` charts. Order matches slash-separated groups in `--chart` (for example `CPU,Memory,Disk` for three series). Also accepted in JSON as `chartSeriesLabels` (string or array) or per-series `name`/`label` on objects in a `series` array.
- `--key-target NAME` Write legend rows to a second widget target (for example `cpu-key`). Use `auto` to expand to `{current-target}-key`. Requires chart data that produces a legend (`series` or `pie`). Often used with `--chart-key external`. The key widget's **Edit Widget → Target name** must match exactly. External key widgets inherit `--fg`, `--bg`, gradient, and padding from the main chart update; legend text scales to fill the key widget like `--fit-text`.
- `--neo-characters katakana|ascii|binary` Character set for `neo` chart format (default `katakana`).
- `--bar-radius N` Corner radius percentage for bar-shaped charts (`0-100`, default `0`). Applies when chart format resolves to `sparkline`/`bar` or `rangebar`.
- `--chart-bar-style solid|glass` Optional **bar/cell/ring/slice** appearance. `glass` adds a gradient “liquid glass” look to vertical bars, matrix cells, pie slices, and **circle** progress rings. Valid with `--chart` and formats `sparkline` (or `bar`), `waveform`, `rangebar`, `matrix`, `pie`, or `delta`, or with `--progress` and `--progress-format circle` (no chart data required for circle glass). Grouped slash syntax requires `sparkline`/`spark`/`bar` format. Default is solid / omitted.
- `--table PATH|-` Render tabular data from `.csv`, `.tsv`, or `.json` file path, or `-` to read from stdin
- `--no-header` Disable table header styling
- `--grid MODE` Table separators/striping mode:
- `none` no grid lines (header divider still renders when header is enabled)
- `row` (alias: `horizontal`) horizontal lines only
- `column` (alias: `vertical`) vertical lines only
- `both` horizontal + vertical lines
- `zebra` alternating row and column striping
- `zebra-row` alternating row striping only
- `zebra-column` alternating column striping only
- `--table-layout MODE` Table column sizing mode:
- `auto` content-measured widths (default). Extra space stays after the last column instead of stretching every cell. Use `--center-table` to split that leftover space on both sides.
- `fill` content-measured widths stretched proportionally to fill the widget (the previous `auto` behavior).
- `equal` uniform column widths based on available table width
- `--table-align LIST` Per-column table text alignment: comma-separated `left`, `center`, or `right` (aliases `l`/`c`/`r`, `leading`/`trailing`, `centre`). Too few values repeat the last for remaining columns; extra values are ignored. Default is all `left`. A fresh `--table` without `--table-align` writes that default (it does not keep a previous alignment).
- `--center-table` With `--table-layout auto`, center the content-sized table horizontally in the widget instead of leaving leftover space after the last column. Horizontal rules span the table, not the full widget. Ignored for `equal` and `fill`. A fresh `--table` without `--center-table` writes the default (left-aligned table block).
- `--zebra-opacity VALUE` Zebra opacity scale for `zebra` grid modes:
- Decimal values (`0.0...1.0`) are interpreted directly
- Integer values (`0...100`) are interpreted as percentages
- Default: `0.75`
- `--no-grid` Alias for `--grid none`
- `--title TEXT` Optional single-line title at the top of chart, text, image, or progress widgets (inside padding; reduces main content height). GitHub `:emoji:` shortcodes expand like `--text`. Line breaks collapse to spaces; max 200 characters.
- `--title-alignment MODE` Horizontal alignment for `--title`: `left`, `center` (default), or `right`.
- `--caption` Show centered `[min/max]` caption below the active chart (or `[n%]` for bar progress when not using `--caption-text`); pairs with chart or progress updates
- `--caption-text TEXT` Custom footer text below widget content (replaces auto `[min/max]` or `[n%]`; implies `--caption`, so you do not need both). Works on any widget type with content (text, image, chart, progress, etc.). GitHub `:emoji:` shortcodes expand like `--text`. Line breaks are collapsed to spaces; max 200 characters.
- `--caption-left TEXT` Bottom-left label on the chart/progress footer (single line; line breaks are collapsed to spaces). Requires `--chart` (or a legacy chart flag) or `--progress`. Independent of `--caption`; layout scales and truncates so left, optional center (`--caption` or `--caption-text`), and right share one row.
- `--caption-right TEXT` Bottom-right label on the chart/progress footer (same rules as `--caption-left`).
- `--annotate` Show small value labels above chart points/bars (chart-only).
- `--label-y` Draw a left y-axis with five tick labels (high … low) for numeric charts (`sparkline`, `graph`, `waveform`, `matrix`, `rangebar`, and related chart families)
- `--timestamp` Show a short local “last updated” time at the bottom on any widget type when no chart/progress footer already shows it; pairs with `--caption` / `--caption-text` on charts and progress (time is taken from the update, not from WidgetKit refresh)
- `--image IMAGE_PATH` Absolute/relative image path or an `http(s)` image URL
- `~` is accepted and expanded to your home directory.
- On Mac, local paths outside the app sandbox need an **Image folder** grant in Terminal Widget (Info/Debug → Add image folder…), or a one-time file chooser when the app can prompt. Full Disk Access does not grant arbitrary paths to the sandboxed app. If neither applies, copy the image into `~/Library/Group Containers/group.brettterpstra.TerminalWidget/` and pass an absolute path.
- SVG tip: WidgetKit’s SVG parser is not full WebKit. Convert `` / `` to outlined paths before display, or labels that look fine in Safari may be missing in the widget. Inkscape CLI: `inkscape in.svg --export-text-to-path --export-plain-svg --export-filename=out.svg` (see [SVG diagrams](https://terminalwidget.app/widgets.md#svg-diagrams)).
- `--background-image IMAGE_PATH` Use an absolute/relative image path or `http(s)` URL as a full-bleed background behind text, icons, progress, charts, or tables. It cannot be combined with `--image`. Padding insets the foreground only; the photo always fills the widget. Use `--filter alpha:0-100` to fade the backdrop so `--bg` shows through.
- `--filter FILTER[:VALUE][,FILTER[:VALUE]...]` Apply one or more filters to `--image` or `--background-image`:
- `grayscale` (aliases: `gray`, `mono`)
- `sepia[:0-100]` (default intensity `100`)
- `negative` (aliases: `invert`, `inverted`)
- `pixelate[:1-200]` (alias: `pixellate`, default scale `8`)
- `blur[:0-100]` (default radius `8`)
- `alpha[:0-100]` image opacity percent (`0` transparent, `100` opaque). `alpha=VALUE` is also accepted.
- Chain filters by repeating `--filter` and/or using comma-separated lists. Filters are applied in order.
- `--image` cannot be combined with chart data (`--chart` or legacy chart flags); `--background-image` can (including with `--table`).
- `--full-width` Alias for `--padding fill` (kept for compatibility)
- `--padding N|fill` Widget content padding in points (`0-64`), or `fill` for orientation-aware image fill/crop mode
- `--fullsize` Shortcut for `--padding 0` (edge-to-edge content)
- `--theme MODE` `system`, `light`, or `dark`
- `--mode MODE` Alias for `--theme` (`system`, `light`, or `dark`)
- `--notify` Persist **notify-on-change** for this widget target: when display content changes on this Mac or device, TerminalWidget posts a **local** Notification Center alert (setting is stored in the widget payload and syncs via iCloud so each device can notify itself after it applies updates). Also applies to the current update. On iOS and iPadOS, notification permission must be enabled for TerminalWidget in Settings.
- `--no-notify` Turn off persisted notify-on-change for this target.
- `--notify-once` Post a local notification only if this update changes display content; does **not** change the persisted notify setting.
- `--json SOURCE` Load widget fields from structured JSON. Use `-` for stdin, a file path, or an `http(s)` URL. Any explicit CLI flags override keys from the JSON document. Image keys are `image` or `backgroundImage` (`background-image`); they are mutually exclusive. Table keys include `tableAlign` (string or array) and `tableCenter` / `center-table` (boolean; auto layout only).
- `--action-kind KIND` Persist a widget tap/click action for this target. Values: `open-url`, `open-app`, `run-shortcut`, `run-command`, `refresh` (re-fetch `--action-value` on tap). Alias: `--tap-action`.
- `--action-value VALUE` Value for `--action-kind`: a URL (including the refresh endpoint for `refresh`), macOS bundle identifier, Shortcut name, or shell command. Alias: `--tap-action-value`.
- `--clear-action` Remove the persisted widget tap/click action for this target.
- `--auto-update KIND` Enable Mac host auto-update for this target: `shortcut` or `image-url` (`off` / `false` clears). Pair with `--auto-update-value` and optionally `--auto-update-interval`.
- `--auto-update-value VALUE` Shortcut name or `http(s)` image URL for `--auto-update`.
- `--auto-update-interval SECS` Seconds between auto-updates (minimum `60`).
- `--clear-auto-update` Remove the persisted auto-update recipe for this target. Deleting a Desktop/Home Screen widget does **not** clear auto-update; the Mac menu-bar app keeps firing while it is open (and iCloud can restore the recipe after reinstall). Use this flag, Shortcuts **Clear Auto-Update**, or Info/Debug → Auto-update.
- `--background` When used **without** a color value, do not launch TerminalWidget or open its refresh URL (quiet update). Prefer `--background-mode` when you also pass `--bg` / `--background COLOR` in the same command.
- `--background-mode` Unambiguous alias for bare `--background` (skip LaunchServices handoff).
- `--strict-local-open` Fail if local `open` handoff fails (URL scheme / app launch diagnostics). Useful when debugging tap actions and Continuity handoff.
- `--verbose` Print debug/status output and manual test URL
- `--help` Show this help
## Notes
- **Piping:** Run commands in your normal shell, then pipe stdout into the widget with `--text -`. That keeps your PATH, aliases, and shell functions available, and avoids sandbox limits that apply when the bundled `terminal-widget` binary runs subprocesses on your behalf.
- `--text -` reads text from stdin.
- `--no-wrap` truncates each line with tail ellipsis instead of soft-wrapping; newline-separated lines stay separate.
- `--ansi-mode auto` parses ANSI only when escape codes are present; `--ansi-mode on` always parses; `--ansi-mode off` leaves text untouched.
- `--strip-colors` removes ANSI control sequences (useful when command output includes terminal color codes but you want plain text).
- `--chart -` reads chart values from stdin.
- `--append -` reads append values from stdin.
- `--table -` reads table data from stdin.
- `--json -` reads a full structured widget document from stdin; explicit CLI options override JSON fields.
- Legacy stdin modes are still accepted: `--sparkline -`, `--graph -`, `--waveform -`, and `--matrix -`.
- If neither `--text -` nor `--chart -` nor `--json -` is used, piped stdin defaults to text when `--text` is omitted.
- Omitting `--text` (and not piping stdin as text) clears the widget text line (for example: `terminal-widget --progress 50` only updates the bar).
- Icon-only: pass `--icon` with no `--text`, `--image`, `--progress`, or chart flags to show a centered symbol. A `--background-image` may still be present.
- Omit `--foreground`/`--background`/`--text-color`/`--caption-color`/`--title-color` on a later update to reset those colors to theme defaults.
- `--text`, `--icon`, `--title`, and `--caption-text` accept GitHub-style `:shortcode:` emoji aliases (for example `:rocket:` → 🚀), same as table cell strings in `--table` input.
- `--padding fill` enables image fill mode: portrait images fill width/crop height, landscape images fill height/crop width.
- Without `--image`, `--padding fill`/`--full-width` enables full-width text scaling (with a built-in inset) for text-only and text+icon layouts.
- `--fit-text` enables the same text fitting behavior for text-only and text+icon layouts, but without changing image fill behavior. Scaling uses a 10pt inset (same as `--padding fill`) and centers the fitted block. Fit-text scaling is skipped when `--text` contains any markdown links so link hit targets stay correct.
- Markdown links in `--text` (and append/JSON `text`) and in `--table` cell strings (CSV/TSV/JSON, including headers) use `[label](url)`. Labels may include spaces; URLs need a scheme (`https://…`, `mailto:…`, etc.). Relative/schemeless URLs and unbalanced markup stay literal. Tapping a link opens that URL; taps on non-link areas still use `--action-kind` / the whole-widget action. Links are not parsed in `--title` or `--caption-text`. Quote CSV cells when the URL contains commas.
- JSON may include a `buttons` array (max 12) of launcher buttons. Each button uses `{ "label", "color", "action-type", "action-value" }` and may include an optional `icon` (an SF Symbol name or `:emoji:` shortcode), plus optional border fields (`border`, `border-color`, `border-width` 0-12, `border-radius` 0-48). Buttons render in a footer grid under any content (or alone). When any button has an icon, every button reserves a left gutter so icons and labels line up. `action-type` matches `--action-kind` values. Layout: optional root `button-columns` / `buttonColumns` is `"smart"`|`"auto"`|`1`|`2`|`3` (small widgets stay 1 column; omit to leave previous mode). Root border defaults: `button-border` (e.g. `"2px #0f0aff"`), `button-border-color`, `button-border-width`, `button-border-radius`; per-button border fields override. Borderless when no border color/width is set; color alone implies width 1; omitted radius defaults to 8. On iOS, `open-app` and `run-command` are shown muted and do not run. Clear the footer with `"buttons": []` (merges onto the previous payload and keeps text, charts, images, and other fields), `--clear-buttons`, or `--json '{"buttons":[]}'`; omit `buttons` to leave previous buttons. See [Widgets](https://terminalwidget.app/widgets.md#launcher-buttons-buttons-in-json) for the full field reference.
- `--filter` requires `--image` or `--background-image`. Use `--filter alpha:40` to fade a background image behind foreground content.
- `--progress-format` requires at least one `--progress` value. `--progress-layout` additionally requires `--progress-format quad4`.
- Grouped slash chart literals (`0 1 2/3 4 5`) require `--chart-format sparkline`, `spark`, `bar`, or `series`/`lines`/`multiline`.
- `--chart-bar-style glass` with circle progress requires `--progress-format circle` (chart values optional).
- `--gradient-from`, `--gradient-to`, and `--gradient-width` require `--progress`.
- `--padding` and `--fullsize` persist in payload until changed again for that target.
- If only one of `--bg-gradient-from`/`--bg-gradient-to` is set, the other side falls back to `--bg` for that update (or the current theme default when `--bg` is omitted).
- Widget actions persist in payload until changed or cleared. iOS can open URLs and run Shortcuts by URL scheme; macOS also supports launching apps by bundle identifier and running shell commands through TerminalWidget.
- Widget taps with no configured `--action-kind` / action do nothing (Terminal Widget does not open).
- Local image paths for `--image` follow the same Mac **Image folder** grants and file-chooser fallback described above. AppleScript and Shortcuts image updates use the same rules.
- Updates the App Group JSON + prefs, then posts widget refresh notifications from CLI mode (without launching a new app instance).
## Examples
Script and Shortcut recipes that update TerminalWidget live are published in the [Recipes](https://terminalwidget.app/recipes) index, including launchd scheduling notes and copy-paste scripts.
- [Browse recipes](https://terminalwidget.app/recipes)
- [Submit your own recipe](https://terminalwidget.app/recipes/submit)
## GitHub emoji shortcodes
These fields expand `:name:` aliases to emoji (for example `:rocket:` → 🚀, `:+1:` → 👍):
- `--text` and piped/command stdin used as text
- `--icon`
- `--title` and `--caption-text`
- Table cells in `--table` CSV/TSV/JSON input
`:emoji:` does not apply to `--caption-left`, `--caption-right`, or chart numeric literals.
Full list of GitHub-style shortcodes: [Emoji cheat sheet](https://github.com/ikatyang/emoji-cheat-sheet) (same aliases GitHub documents for Markdown).
## Command Examples
For screenshot-ready CLI examples (text, progress, charts, tables, button JSON), see [Widgets Gallery and Modes](https://terminalwidget.app/widgets.md#text-widgets) — especially [launcher buttons](https://terminalwidget.app/widgets.md#launcher-buttons-buttons-in-json) and [emoji + tables](https://terminalwidget.app/widgets.md#emoji--tables).
```bash
terminal-widget --target widget1 --text "Deploy complete" --icon "checkmark.circle.fill" --fg "#22c55e"
terminal-widget --target widget1 --text "Status: [Docs](https://terminalwidget.app) · [Support](https://terminalwidget.app/support)"
terminal-widget --target widget1 --text "A very long status message that should stay on one line and truncate with an ellipsis" --no-wrap
echo -e "Hello\nWorld" | figlet -f "Bloody" | terminal-widget --target widget1 --text - --font menlo --no-wrap --fit-text --bg-gradient-from ea39f3 --bg-gradient-to 9d3b7f --bg-gradient-start nw --text-color d9e3e6
pmset -g batt | head -1 | terminal-widget --target widget2 --text -
terminal-widget --target widget3 --image "https://picsum.photos/800/400" --fullsize
terminal-widget --target widget3 --image "https://picsum.photos/800/400" --filter sepia:35
terminal-widget --target widget3 --image "https://picsum.photos/800/400" --filter grayscale --filter blur:8
terminal-widget --target widget3 --image "https://picsum.photos/800/400" --filter "sepia:20,blur:10"
terminal-widget --target widget1 --background-image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" --filter alpha:40 --bg 0f172a --fg "#f8fafc" --title "Today" --text "Austin 84" --caption-text "Clear" --icon sun.max.fill
terminal-widget --target widget1 --background-image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" --filter alpha:35 --bg 0f172a --fg "#7dd3fc" --chart "4 8 15 16 23 42" --text "Throughput"
terminal-widget --target widget1 --progress 67 --text "Rendering"
terminal-widget --target widget1 --progress 67 --progress-format gradient-horizontal --gradient-from "#22d3ee" --gradient-to "#9333ea" --gradient-width 18 --text "Deploying"
terminal-widget --target widget1 --text "Sleep score" --progress 85 --progress-format quadrant --fg "#7dd3fc" --caption --bg "#0f172a"
terminal-widget --target widget1 --progress 92,74,55,38 --progress-format quad4 --progress-layout 1,2,3,4 --chart-series-labels "Build,Test,Ship,Docs" --chart-key inline --caption --caption-text "Sprint goals" --fg "#38bdf8,#4ade80,#fbbf24,#f87171" --bg "#0f172a" --caption-color "#94a3b8"
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline --limit 20
terminal-widget --target widget1 --append "90 91" --limit 20
terminal-widget --target widget1 --append "3/4"
terminal-widget --target widget1 --append "2-5 3-6"
terminal-widget --target widget1 --text "line 1" --limit 50
terminal-widget --target widget1 --append "line 2"
terminal-widget --target widget1 --limit 10
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline --chart-height 55%
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline --bar-radius 45
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline --base-zero
terminal-widget --target widget1 --chart "0 1 5 2/1 2 5 3" --chart-format bar --fg "#cc0000,#00cc00,#0000cc" --annotate
terminal-widget --target widget1 --chart "1 2 3 4/5 6 7 8/9 10 11 12" --chart-format series --chart-series-labels "CPU,Memory,Disk" --fg "#f87171,#4ade80,#60a5fa" --bg "#0f172a"
terminal-widget --target widget1 --chart-format series --chart '{"series":[{"name":"CPU","values":[1,4,9,3]},{"name":"Memory","values":[2,5,8,4]},{"name":"Disk","values":[6,7,5,2]}]}' --fg "#f87171,#4ade80,#60a5fa" --bg "#0f172a"
terminal-widget --target widget1 --chart "CPU:45:#f87171 Memory:30:#4ade80 Disk:25:#60a5fa" --chart-format pie --chart-key inline --bg "#0f172a" --fg "#e2e8f0"
terminal-widget --target cpu --chart "CPU:45 Memory:30 Disk:25" --chart-format pie --chart-key external --key-target cpu-key --bg "#0f172a" --fg "#e2e8f0"
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sparkline --chart-bar-style glass --bar-radius 35
terminal-widget --target widget1 --progress 72 --progress-format circle --chart-bar-style glass --fg "#4a9eff" --caption
terminal-widget --chart "6-8,1-8,1-6,2-4,1-6" --chart-format rangebar --chart-bar-style glass --bar-radius 40 --target widget1 --bg "ffffff" --fg "ca4fae" --text "TerminalWidget" --text-color "#5ac5fa"
terminal-widget --target widget1 --chart "5 12 8 21 34 55 89" --chart-format sine --caption
terminal-widget --target widget1 --chart "0 2 8 3 5 1 0 9" --chart-format matrix
terminal-widget --target widget1 --chart "3 6 2 8 5 9 4" --chart-format neo --neo-characters ascii --annotate
terminal-widget --chart "5-6,1-6,1-5,1.5-4,1-5" --chart-format rangebar --target widget1 --bg "ffffff" --fg "ca4fae"
terminal-widget --target widget1 --clear
terminal-widget --target widget1 --clear-buttons
terminal-widget --target widget1 --json '{"buttons":[]}'
terminal-widget --target widget1 --icon :x: --bg "#ff5f5f"
terminal-widget --target widget1 --text "Deploy :rocket: :+1:" --icon :smiley:
terminal-widget --target widget1 --text "Build queue" --title ":chart_with_upwards_trend: Throughput" --title-alignment center --title-color "#a78bfa" --caption-text "Updated :clock3:" --timestamp --bg "#0f172a" --fg "#94a3b8"
terminal-widget --target widget1 --chart "5 12 8 21 13 34" --chart-format graph --title "Weekly trend" --caption-text ":white_check_mark: On track" --caption-color "#94a3b8" --fg "#e2e8f0" --bg "#0f172a"
terminal-widget --target widget1 --table /Users/ttscoff/Desktop/Code/terminal-widget/status.csv
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --table-layout auto --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --zebra-opacity 0.4 --table-layout auto --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --zebra-opacity 60 --table-layout auto --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid both --table-layout equal --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --table-layout fill --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --table-align left,right,center --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --table-layout auto --center-table --mode dark
terminal-widget --target widget1 --table ~/status/status.csv --grid none --mode dark
echo "Build complete" | terminal-widget --target widget1
cal | terminal-widget --target cal --text -
figlet -f doom "$(users | head -n 1)" | terminal-widget --target username --text -
ls -G /Applications | head -n 12 | terminal-widget --target ansi --text - --ansi-mode auto
printf '\033[30;47m black/white \033[0m \033[97;44m white/blue \033[0m\n' | terminal-widget --target ansi-bg --text - --ansi-mode on
git status --short | terminal-widget --target plain --text - --strip-colors
terminal-widget --target widget1 --chart - --chart-format radial < values.txt
cat /Users/ttscoff/Desktop/Code/terminal-widget/status.csv | terminal-widget --target widget1 --table -
```
## Chart Gallery
Use the same data with different `--chart-format` values to compare styles quickly:
```bash
# Base sample data
DATA="1 4 9 3 8 2 7 5 10 6"
terminal-widget --target widget1 --chart "$DATA" --chart-format sparkline
terminal-widget --target widget1 --chart "$DATA" --chart-format sparkline --chart-height 55%
terminal-widget --target widget1 --chart "$DATA" --chart-format sparkline --bar-radius 45
terminal-widget --target widget1 --chart "$DATA" --chart-format graph
terminal-widget --target widget1 --chart "$DATA" --chart-format waveform
terminal-widget --target widget1 --chart "$DATA" --chart-format area
terminal-widget --target widget1 --chart "$DATA" --chart-format lollipop
terminal-widget --target widget1 --chart "$DATA" --chart-format strip
terminal-widget --target widget1 --chart "$DATA" --chart-format radial
terminal-widget --target widget1 --chart "$DATA" --chart-format delta
terminal-widget --target widget1 --chart "$DATA" --chart-format threshold
terminal-widget --target widget1 --chart "$DATA" --chart-format smooth
terminal-widget --target widget1 --chart "$DATA" --chart-format sine
terminal-widget --target widget1 --chart "$DATA" --chart-format peak
terminal-widget --target widget1 --chart "$DATA" --chart-format matrix
terminal-widget --chart "5-6,1-6,1-5,1.5-4,1-5" --chart-format rangebar --target widget1 --bg "ffffff" --fg "ca4fae"
terminal-widget --chart "6-8,1-8,1-6,2-4,1-6" --chart-format rangebar --chart-bar-style glass --bar-radius 40 --target widget1 --bg "ffffff" --fg "ca4fae" --text "TerminalWidget" --text-color "#5ac5fa"
```
Add `--caption` to any chart command to show `[min/max]` below the chart.
History-style range labels on a chart footer (with centered `[min/max]`):
```bash
terminal-widget --target widget1 --chart "5 8 6 12 9 15 11" --chart-format graph --caption \
--caption-left "5/4/26 08:00" --caption-right "5/5/26 15:00" --caption-color "#94a3b8"
```
## URL Scheme Examples
For complete URL parameter documentation, behavior notes, and more ready-to-paste examples, see [URL Scheme Documentation](https://terminalwidget.app/url-scheme.md).
```text
terminalwidget://update?target=widget1&text=Backup%20Complete&icon=externaldrive.fill
terminalwidget://update?target=widget2&progress=42&text=Syncing
terminalwidget://update?target=widget3&image=https%3A%2F%2Fpicsum.photos%2F640%2F360&padding=0
terminalwidget://update?target=widget1&chart=4,8,15,16,23,42&chartFormat=peak&caption=1
terminalwidget://update?target=widget1&chart=5,8,6,12&chartFormat=graph&caption=1&captionLeft=Start&captionRight=Now
terminalwidget://update?target=widget2&theme=dark&fg=%23ffffff&bg=%23111417
```
---
## Docs: Widget Types, Modes, and Examples
Source: https://terminalwidget.app/widgets.md
# Widget Types, Modes, and Examples
> A complete guide to TerminalWidget text, progress, and chart modes with sample commands and screenshot capture workflow.
Source: https://terminalwidget.app/widgets
**TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.**
Use this page as a visual checklist for every widget style. Each section includes sample commands you can run as-is, plus screenshot slots for macOS, iOS/iPadOS, and watchOS.
**Widgets are not automatic.** Place a TerminalWidget on the Desktop or Home Screen yourself, then set **Edit Widget → Target name** so sample commands (and any automation) can reach it. Setup steps: [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
**Diagnostics widget (`twdiags`):** on Mac, iPhone, and iPad, set the Target name to `twdiags` to show recent failures and warnings from that device (device-local log — Mac events do not appear on iPhone and vice versa). On Mac you can also use the CLI `log` subcommand or Info/Debug; on iOS the widget is the viewer. Full details: [CLI → Diagnostics](https://terminalwidget.app/cli.md#diagnostics).
> Click a screenshot to zoom and you'll see the command that generated it beneath it.
## macOS Widget Gallery
Example output for each widget style:
- [{:loading=eager fetchpriority=high width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-basic@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-nowrap@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/ansi-text-bg@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/terminal-output@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/terminal-output-figlet@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-icon@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-markdown-links@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-markdown-include@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/buttons-launcher@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/buttons-border@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-caption-colors@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/bg-gradient@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/icon-text-fill@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/icon-only@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-bar@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-matrix@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-dots@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-stack@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-gradient-horizontal@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-gradient-vertical@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-circle@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-watch@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-quadrant@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/progress-quad4@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-grouped@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-series@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-pie@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-sparkline@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-append-limit@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-height@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-base-zero@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/base-zero@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-sparkline-radius@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-sparkline-glass@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-graph@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-waveform@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-area@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-lollipop@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-strip@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-radial@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-delta@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-threshold@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-smooth@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-sine@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-peak@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-neo@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-matrix@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-rangebar@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-rangebar-glass@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-annotate@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-annotate-bars@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-label-y@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-timestamp@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/chart-caption-sides@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-title-caption@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/text-title-align-left@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/foreground-background@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/light-mode@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/image-full-width@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/image-filter-sepia@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/image-filter-grayscale@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/image-filter-chain@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/background-image-text@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/background-image-chart@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/background-image-table@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/fullsize-area@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/icon-inline@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/emoji-icon-bg@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-grid-zebra@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-grid-both@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-grid-none@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-cell-links@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-align@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/table-layout-fill@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/macos/center-table@2x.jpg){.widget-shot.js-lightbox}
{.widget-shot-grid}
- [{:loading=lazy width=400 height=258}](https://terminalwidget.app/assets/video/widgets.mp4){.widget-shot.widget-shot-video.js-lightbox data-lightbox-type=video data-video-poster="/assets/images/home/widgets-700.jpg" data-video-webm="/assets/video/widgets.webm" data-lightbox-caption="macOS widgets demo"}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/video/progress-bars.mp4){.widget-shot.widget-shot-video.js-lightbox data-lightbox-type=video data-video-poster="/assets/images/progress-bars.jpg" data-lightbox-caption="Progress Bars Demo"}
{.widget-shot-grid}
## iOS/iPadOS/watchOS
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-trio@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-markdown-links@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-markdown-include@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/buttons-launcher@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/buttons-border@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-nowrap@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/terminal-output@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-trio@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-caption-colors@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/bg-gradient@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-stack@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-gradient@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-circle-watch@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-quadrant@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/progress-quad4@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-grouped@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-series@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-pie@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-core@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-append-limit@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-height@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-base-zero@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-caption-sides@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-title-caption@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/text-title-align-left@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/base-zero@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-sparkline-radius@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-sparkline-glass@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-sparkline-glass-2@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-styles-a@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-styles-b@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-styles-c@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-neo@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-matrix-annotate@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-annotate-bars@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-rangebar@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/chart-rangebar-glass@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/ansi-text-trio@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/mode-showcase@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/image-showcase@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/background-image-text@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/background-image-chart@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/background-image-table@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/icon-inline-mix@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/fullsize-contrast@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/fg-bg-variants@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/icon-only-trio@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/lock-screen-trio@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/table-grid-modes@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/table-cell-links@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/table-align@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/table-layout-fill@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=400 height=400}](https://terminalwidget.app/assets/images/shots/iphone/center-table@2x.jpg){.widget-shot.js-lightbox}
{.widget-shot-grid}
## watchOS
Screenshots coming soon.
## Text Widgets
Text mode is active when you provide `--text` or `--command` without chart/progress-only output.
### Basic Text
```bash
terminal-widget --target widget1 --text "Build complete"
```
### Text + Icon
```bash
terminal-widget --target widget1 --text "API healthy" --icon "checkmark.seal.fill"
```
### Markdown links in text
`--text` accepts CommonMark-style `[label](url)` links. On macOS and iOS, link labels render as tappable buttons; taps outside links still use the widget's `--action-kind` action. URLs need a scheme (`https://…`, `mailto:…`, etc.). `--fit-text` scaling is skipped when any link is present.
```bash
terminal-widget --target widget1 --text "Status: [Docs](https://terminalwidget.app) · [Support](https://terminalwidget.app/support)" --fg "#EAF6FF" --bg "#1F2A44"
terminal-widget --target widget1 --text "[Open dashboard](https://example.com/status)"
terminal-widget --target widget1 --text "Include [Markdown links](https://brettterpstra.com) in widgets" --fg "#EAF6FF" --bg "#1F2A44"
```
### Launcher buttons (`buttons` in JSON)
JSON updates (`--json`) can include a `buttons` array that renders a tappable footer grid under any widget content (text, chart, progress, image, table), or alone as a buttons-only layout. Max **12** buttons. Set launcher buttons from CLI `--json` (file, `-` stdin, inline `{...}`, or URL); Shortcuts/AppleScript do not expose per-button fields in v1, but any update that sends structured JSON can include `buttons`.
### Button fields
Each entry needs a label and an action:
| Field | Required | Notes |
| --- | --- | --- |
| `label` | yes | Button title |
| `icon` | no | SF Symbol name or `:emoji:` shortcode; left of label. If any button has an icon, all buttons reserve a left gutter so icons/labels line up |
| `action-type` | yes | Same values as `--action-kind`: `open-url`, `open-app`, `run-shortcut`, `run-command`, `refresh` (aliases: `actionType`, `actionKind`) |
| `action-value` | yes | URL, macOS bundle ID, Shortcut name, shell command, or refresh endpoint (aliases: `actionValue`) |
| `color` | no | Fill / accent color for the button |
| `border` | no | Shorthand stroke, e.g. `"2px #0f0aff"` or `"#ffffff 1.5"` (see borders below) |
| `border-color` | no | Stroke color (aliases: `borderColor`) |
| `border-width` | no | Stroke width in points, `0`–`12` (aliases: `borderWidth`) |
| `border-radius` | no | Corner radius in points, `0`–`48` (aliases: `borderRadius`); omit for default **8** |
### Button layout (`button-columns`)
- **Small** widgets always use one column.
- **Medium / large** default to smart layout: **3** columns when the button count is divisible by 3, otherwise **2**. Incomplete final rows are padded so widths stay equal. A single button stays one column.
- Root `button-columns` / `buttonColumns`: `"smart"` or `"auto"` restores smart layout; `1`, `2`, or `3` forces that many columns (capped by button count).
- Omit `button-columns` to leave the previous column mode. Clear the footer with `"buttons": []` (merges onto the previous payload and keeps text, charts, and other content), `--clear-buttons`, or `--json '{"buttons":[]}'`. Omit the `buttons` key to leave the previous button list.
### Button border styling
Buttons are **borderless** by default. Borders come from widget-level defaults and optional per-button overrides.
**Root defaults** (apply to every button unless overridden):
- `button-border` / `buttonBorder` — shorthand width + color, e.g. `"2px #0f0aff"`
- `button-border-color` / `buttonBorderColor`
- `button-border-width` / `buttonBorderWidth` (`0`–`12`)
- `button-border-radius` / `buttonBorderRadius` (`0`–`48`)
**Per-button overrides:** `border`, `border-color`, `border-width`, `border-radius` win over the matching root default.
**Shorthand rules:** tokens may be `WIDTH`, `WIDTHpx`, and/or a color (`#rrggbb`, named colors, etc.), in either order. Optional `solid` / `none` tokens are ignored. Empty string clears width + color from that shorthand. Explicit `border-color` / `border-width` (or root equivalents) after a shorthand override those parts.
**Effective stroke:** if a border color is set and width is omitted, width defaults to **1**. If neither color nor width is set, width is **0** (no stroke). Corner radius defaults to **8** when omitted.
Root border keys persist like other payload fields: send them without `buttons` to restyle the current grid; omit them to keep previous defaults.
### Button platform notes
On **iOS**, `open-app` and `run-command` buttons render muted and do not run (macOS supports all action types). When any launcher buttons are present, the whole-widget tap URL is omitted on macOS so the footer controls stay interactive.
```bash
terminal-widget --target widget1 --json - <<'EOF'
{
"text": "Status board",
"button-columns": 2,
"button-border": "2px #0f0aff",
"button-border-radius": 10,
"buttons": [
{"label": "Docs", "icon": "doc.text", "color": "#5ac5fa", "border": "1px #ffffff", "border-radius": 10, "action-type": "open-url", "action-value": "https://terminalwidget.app"},
{"label": "Marked", "color": "#22c55e", "action-type": "open-app", "action-value": "com.brettterpstra.marked2"},
{"label": "Refresh", "action-type": "refresh", "action-value": "https://example.com/widget.json"}
]
}
EOF
```
### Title and custom caption (`--title`, `--title-color`, `--caption-text`)
`--title` renders a small caption-style line at the top (inside padding). `--caption-text` sets custom footer text below the main content and implies `--caption` (no `[min/max]` or `[n%]` auto text). Both accept GitHub `:emoji:` shortcodes like `--text`.
```bash
terminal-widget --target widget1 --text "Build queue" --title ":chart_with_upwards_trend: Throughput" --title-color "#a78bfa" --caption-text "Updated :clock3:" --timestamp --bg "#0f172a" --fg "#94a3b8"
terminal-widget --target widget1 --chart "5 12 8 21 13 34" --chart-format graph --title "Weekly trend" --caption-text ":white_check_mark: On track" --caption-color "#94a3b8" --fg "#e2e8f0" --bg "#0f172a"
terminal-widget --target widget1 --text "Deploy log" --title "Left-aligned title" --title-alignment left --fg "#e2e8f0" --bg "#0f172a"
```
`--title-alignment` accepts `left`, `center` (default when `--title` is set), or `right`.
### Text vs caption colors (`--text-color`, `--caption-color`)
Use `--foreground` for icons, charts, and progress visuals. Optionally set `--text-color` so the main `--text` line (and table defaults) differ from `--foreground`, and `--caption-color` for `[min/max]`, `[n%]`, `--caption-text`, and `--timestamp` lines.
```bash
terminal-widget --target widget1 --text "Queues" --foreground "#64748b" --text-color "#2dd4bf" --progress 55 --caption --timestamp --caption-color "#fbbf24" --bg "#0f172a"
```
### Single-Line Truncation (`--no-wrap`)
```bash
terminal-widget --target widget1 --text "This is a very long line that truncates instead of wrapping in the widget" --no-wrap
```
### Terminal Output (`terminal-output`)
```bash
cal -A 1 | terminal-widget --target widget1 --text - --font menlo --bg "333333" --fg "#e1c245" --no-wrap
```
### Icon-Only Widget
When no `--text`, `--progress`, `--chart`, `--image`, or `--command` is present, the icon is centered and scaled.
```bash
terminal-widget --target widget1 --icon "terminal.fill"
```
### ANSI Text (`--ansi-mode`, `--strip-colors`)
Use ANSI escape sequences for foreground/background color blocks in text mode, or strip them when you want plain text.
```bash
printf '\033[30;47m black on white \033[0m \033[97;44m white on blue \033[0m' | terminal-widget --target widget1 --text - --ansi-mode on
printf '\033[31mred text\033[0m' | terminal-widget --target widget1 --text - --strip-colors
```
## Progress Widgets
Progress mode uses `--progress 0..100`. Add `--progress-format` to choose a visual style.
### `bar` (default)
```bash
terminal-widget --target widget1 --text "Syncing assets" --progress 42 --progress-format bar
```
### `matrix`
```bash
terminal-widget --target widget1 --text "Compile queue" --progress 74 --progress-format matrix --caption
```
### `dots`
```bash
terminal-widget --target widget1 --text "Packaging release" --progress 92 --progress-format dots --caption
```
### `stack`
```bash
terminal-widget --target widget1 --text "Layer sync" --progress 68 --progress-format stack --caption
```
### `gradient` / `gradient-horizontal`
`gradient` is an alias for `gradient-horizontal`.
```bash
terminal-widget --target widget1 --text "Transfer queue" --progress 52 --progress-format gradient --gradient-from "#4fd1ff" --caption
```
### `gradient-vertical`
Use `--gradient-width` to render a narrower vertical progress bar.
```bash
terminal-widget --target widget1 --text "Build queue" --progress 63 --progress-format gradient-vertical --gradient-from "rgba(126,240,168,0.95)" --gradient-width 32 --caption
```
### `circle`
```bash
terminal-widget --target widget1 --text "Build Progress" --progress 72 --progress-format circle --fg "#7ee081" --caption --bg "#2a1f44"
```
macOS gallery slot **progress-circle** matches the command above (`capture-macos-widgets.sh --only progress-circle`).
### `watch` (clock-style arc)
```bash
terminal-widget --target widget1 --text "Build time" --progress 58 --progress-format watch --fg "#a78bfa" --caption --bg "#1e293b"
```
macOS gallery slot **progress-watch** matches the command above (`capture-macos-widgets.sh --only progress-watch`).
### `quadrant`
Four-quadrant ring (counter-clockwise from 12). Segment thickness grows with progress; completed adjacent quadrants merge.
```bash
terminal-widget --target widget1 --text "Sleep score" --progress 85 --progress-format quadrant --fg "#7dd3fc" --caption --bg "#0f172a"
```
macOS gallery slot **progress-quadrant** matches the command above (`capture-macos-widgets.sh --only progress-quadrant`).
### `quad4` (multi-goal quadrants)
Pass up to four comma-separated percentages. `--progress-layout` assigns each value to a quadrant or clockwise quadrant range; omitted values are padded with zero.
```bash
terminal-widget --target widget1 \
--progress 92,74,55,38 \
--progress-format quad4 \
--progress-layout 1,2,3,4 \
--chart-series-labels "Build,Test,Ship,Docs" \
--chart-key inline \
--caption \
--caption-text "Sprint goals" \
--fg "#38bdf8,#4ade80,#fbbf24,#f87171" \
--bg "#0f172a" \
--caption-color "#94a3b8"
```
`quad-4` is accepted as an input alias. macOS gallery slot **progress-quad4** matches the command above (`capture-macos-widgets.sh --only progress-quad4`). On macOS captures, widget2 pushes its legend to widget4 with `--chart-key external --key-target widget4`.
## Chart Widgets
Chart mode uses `--chart "N N ..."` with `--chart-format`. `rangebar` uses `low-high` pairs instead of single numeric values.
### Grouped sparkline/bar (`/` series)
Use slash-separated segments for side-by-side sub-bars per column (up to four series). Pair with comma-separated `--foreground` for per-series colors.
```bash
terminal-widget --target widget1 --chart "0 1 5 2/1 2 5 3/2 3 4 1" --chart-format bar --bar-radius 20 --fg "#ee9b00,#e9d8a6,#94d2bd" --annotate --bg "#001219"
```
macOS gallery slot **chart-grouped** matches the command above (`capture-macos-widgets.sh --only chart-grouped`). iOS interactive scene **chart-grouped** uses the same slash syntax on all three widget targets.
### Multi-series line chart (`series`)
Overlapping line charts with a bottom legend (default for `series`). Reuse slash-separated groups (same syntax as grouped sparklines). Label each line with `--chart-series-labels` or JSON `series: [{name, values}, …]`:
```bash
terminal-widget --target widget1 --chart "1 4 9 3/2 5 8 4/6 7 5 2" --chart-format series --chart-series-labels "CPU,Memory,Disk" --fg "#f87171,#4ade80,#60a5fa" --bg "#0f172a"
```
Gallery slot **chart-series** (`capture-macos-widgets.sh --only chart-series`).
### Pie chart (`pie`)
Categorical slices with percentages in the legend. CLI literal: `label:value[:color]` tokens; JSON `slices` arrays also work via structured input.
**Inline legend** (medium and extra-large widgets): side key to the left of the pie, scaled to fill the left column:
```bash
terminal-widget --target widget1 --chart "CPU:45:#f87171 Memory:30:#4ade80 Disk:25:#60a5fa" --chart-format pie --chart-key inline --fg "#e2e8f0" --bg "#0f172a"
terminal-widget --target widget1 --chart "CPU:45:#f87171 Memory:30:#4ade80 Disk:25:#60a5fa" --chart-format pie --chart-bar-style glass --chart-key inline --fg "#e2e8f0" --bg "#0f172a"
```
On smaller or square layouts, use `--chart-key bottom` for a legend under the chart, or pair the chart with a dedicated key widget:
```bash
terminal-widget --target cpu --chart "CPU:45 Memory:30 Disk:25" --chart-format pie --chart-key external --key-target cpu-key --bg "#0f172a" --fg "#e2e8f0"
```
Set the key widget's **Target name** to `cpu-key` (must match `--key-target`). The key widget inherits foreground, background, gradient, and padding from the chart update. Legend rows scale to fill the key widget.
Gallery slot **chart-pie** (`capture-macos-widgets.sh --only chart-pie`) demonstrates inline keys on medium/extra-large widgets and an external key on a second target.
### Chart legends (`--chart-key`, `--key-target`)
| Placement | Behavior |
| --- | --- |
| `auto` | Pie on medium/extra-large: inline side legend. Series: bottom legend. |
| `inline` / `left` | Side legend (pie on landscape sizes). |
| `bottom` | Legend under the chart. |
| `external` | No legend on the main widget; write rows to `--key-target`. |
| `none` | Hide the legend entirely. |
External key widgets are legend-only targets. They receive the same colors and padding as the chart widget that produced the legend.
### Starter Example
```bash
terminal-widget --target widget1 --chart "1 4 9 3 8 2 7 5 10 6" --chart-format sparkline
```
### Append and limit (`--append`, `--limit`)
Use `--append` to add chart columns (same syntax as `--chart`, including slash-grouped series and rangebar `low-high` pairs) or text lines without replacing the rest of the widget. Use `--limit N` for a rolling window of the newest N columns/lines (`0` clears the soft limit; charts still hard-cap at 128 newest points).
```bash
terminal-widget --target widget1 --chart "1 4 9 3 8 2 7 5" --chart-format sparkline --limit 8 --bar-radius 20 --chart-bar-style glass --fg "#ffffff" --bg "#9b1e86"
terminal-widget --target widget1 --append "10 6" --limit 8
```
macOS gallery slot **chart-append-limit** matches the sequence above.
### Bar radius (`--bar-radius`)
Use `--bar-radius 0..100` to round sparkline bar corners, or **range bar** column corners in `rangebar` mode.
```bash
terminal-widget --target widget1 --chart "1 4 9 3 8 2 7 5 10 6" --chart-format sparkline --bar-radius 45
terminal-widget --target widget1 --chart "1-3,2-4,1-5" --chart-format rangebar --bar-radius 40
```
### Chart bar style (`--chart-bar-style`)
Use `--chart-bar-style glass` with bar-like formats (**sparkline**, **waveform**, **rangebar**, **matrix**, **pie**, **delta**) for a gradient “liquid glass” bar/cell/slice treatment (default is solid). The same flag applies to **circle** progress rings (`--progress-format circle`) without chart data.
```bash
terminal-widget --target widget1 --chart "1 4 9 3 8 2 7 5 10 6" --chart-format sparkline --chart-bar-style glass --bar-radius 35
terminal-widget --target widget1 --progress 72 --progress-format circle --chart-bar-style glass --fg "#4a9eff" --caption
terminal-widget --chart "6-8,1-8,1-6,2-4,1-6" --chart-format rangebar --chart-bar-style glass --bar-radius 40 --target widget1 --bg "ffffff" --fg "ca4fae" --text "TerminalWidget" --text-color "#5ac5fa"
```
macOS gallery slot **chart-rangebar-glass** matches the range bar example above (run `capture-macos-widgets.sh --only chart-rangebar-glass` after placing widgets).
### All Chart Modes
```bash
DATA="1 4 9 3 8 2 7 5 10 6"
terminal-widget --target widget1 --chart "$DATA" --chart-format sparkline
terminal-widget --target widget1 --chart "$DATA" --chart-format graph
terminal-widget --target widget1 --chart "$DATA" --chart-format waveform
terminal-widget --target widget1 --chart "$DATA" --chart-format area
terminal-widget --target widget1 --chart "$DATA" --chart-format lollipop
terminal-widget --target widget1 --chart "$DATA" --chart-format strip
terminal-widget --target widget1 --chart "$DATA" --chart-format radial
terminal-widget --target widget1 --chart "$DATA" --chart-format delta
terminal-widget --target widget1 --chart "$DATA" --chart-format threshold
terminal-widget --target widget1 --chart "$DATA" --chart-format smooth
terminal-widget --target widget1 --chart "$DATA" --chart-format sine
terminal-widget --target widget1 --chart "$DATA" --chart-format peak
terminal-widget --target widget1 --chart "$DATA" --chart-format matrix
terminal-widget --chart "5-6,1-6,1-5,1.5-4,1-5" --chart-format rangebar --target widget1 --bg "ffffff" --fg "ca4fae"
```
### Range Bar
`rangebar` draws each bar as one contiguous inclusive range. The y axis starts at `0` and scales to the highest range endpoint plus one.
```bash
terminal-widget --chart "5-6,1-6,1-5,1.5-4,1-5" --chart-format rangebar --target widget1 --bg "ffffff" --fg "ca4fae"
```
### Chart Annotation (`--annotate`)
`--annotate` overlays point/bar labels for `sparkline`, `graph`, `waveform`, and `rangebar` chart families.
```bash
terminal-widget --target widget1 --chart "5 12 8 21 13 34" --chart-format graph --annotate
terminal-widget --target widget1 --chart "5 12 8 21 13 34" --chart-format sparkline --annotate
```
Gallery captures for bar-style annotations use slug **chart-annotate-bars** (`capture-macos-widgets.sh` / `capture-ios-widgets-interactive.sh --only chart-annotate-bars`).
### Y axis labels (`--label-y`) and update time (`--timestamp`)
`--label-y` adds a left axis with five labels spanning the chart’s value range (and `0…max+1` for `rangebar`). `--timestamp` shows a short local “last updated” line at the bottom on any widget type when no chart/progress footer already shows it; on charts/progress it can be combined with `--caption`, `--caption-text`, or used alone. Both apply to the same update that sets the payload (not the WidgetKit refresh schedule).
```bash
terminal-widget --target widget1 --chart "1 4 9 3 8 2 7 5 10 6" --chart-format sparkline --label-y --caption
terminal-widget --target widget1 --chart "5 12 8 21 13 34" --chart-format graph --caption --timestamp
terminal-widget --target widget1 --text "Syncing" --progress 42 --caption --timestamp
```
## Styling and Layout Flags
## Emoji + Tables
TerminalWidget expands GitHub-style `:shortcode:` aliases (same set as GitHub-flavored Markdown) in **`--text`**, **`--icon`**, **`--title`**, and **`--caption-text`**, plus table cell strings from **`--table`**. Examples: `:rocket:` → 🚀, `:white_check_mark:` → ✅, `:clock3:` → 🕒.
```bash
terminal-widget --target widget1 --text "Deploy :rocket:" --icon :smiley:
terminal-widget --target widget1 --title ":chart_with_upwards_trend: Weekly" --caption-text "Updated :clock3:"
```
Use these exact commands when capturing screenshot slots:
### Emoji Icon + Background (`emoji-icon-bg`)
```bash
terminal-widget --target widget1 --icon :x: --bg "#ff5f5f"
```
### Table with Zebra Grid (`table-grid-zebra`)
```bash
terminal-widget --target widget1 --table ~/status/status.csv --grid zebra --zebra-opacity 60 --mode dark
```
### Table with Row + Column Grid (`table-grid-both`)
```bash
terminal-widget --target widget1 --table ~/status/status.csv --grid both --mode dark
```
### Table with Header Rule Only (`table-grid-none`)
```bash
terminal-widget --target widget1 --table ~/status/status.csv --grid none --mode dark
```
### Table cell markdown links (`table-cell-links`)
Table cells accept the same `[label](url)` syntax as `--text`. Linked labels render as tappable buttons; other cell text stays plain.
```bash
cat scripts/fixtures/capture-table-links.csv | terminal-widget --target widget1 --table - --grid zebra --mode dark --table-layout equal
```
### Table column alignment (`table-align`)
Per-column text alignment for header and body (`left`, `center`, or `right`). Remaining columns repeat the last value. Independent of `--table-layout`.
```bash
cat scripts/fixtures/capture-table-sample.csv | terminal-widget --target widget1 --table - --grid zebra --mode dark --table-layout equal --table-align left,center,right
```
### Table fill layout (`table-layout-fill`)
Content-measured columns stretched proportionally to fill the widget width (the previous `--table-layout auto` behavior).
```bash
cat scripts/fixtures/capture-table-sample.csv | terminal-widget --target widget1 --table - --grid zebra --mode dark --table-layout fill
```
### Center auto table (`center-table`)
With `--table-layout auto`, leftover width is split on both sides instead of sitting after the last column. Ignored for `equal` and `fill`. Horizontal rules span the table, not the full widget.
```bash
cat scripts/fixtures/capture-table-sample.csv | terminal-widget --target widget1 --table - --grid zebra --mode dark --table-layout auto --center-table
```
### Background image table (`background-image-table`)
Live planet positions with a night-sky `--background-image`. Requires python3 and astropy.
```bash
python3 scripts/planets.py --all
python3 scripts/planets.py --target widget1 --background 1
python3 scripts/planets.py --target 2
```
### Optional STDIN Variant
```bash
cat ~/status/status.csv | terminal-widget --target widget1 --table -
```
### Foreground / Background (`--foreground`, `--background`, aliases `--fg`, `--bg`)
These set text/icon/chart/progress foreground and widget background colors for this payload.
```bash
terminal-widget --target widget1 --text "Night mode test" --icon "moon.stars.fill" --fg "#dbeafe" --bg "#0b1220"
```
### Full-size (`--fullsize`, alias for `--padding 0`)
Useful for edge-to-edge charts/images and dense visual widgets.
```bash
terminal-widget --target widget1 --chart "2 6 4 9 7 3 8 5" --chart-format area --fullsize
```
### Image + Full Width (`--image` + `--full-width`)
Use a remote image source and fill mode for edge-to-edge image rendering.
```bash
terminal-widget --target widget1 --image "https://picsum.photos/400/400" --full-width
```
### SVG diagrams
WidgetKit’s SVG renderer is not full WebKit. SVGs that use `` or `` often look correct in Safari, Sketch, and similar apps, but labels can be missing or wrong in the widget. **Convert text to outlines/paths** before passing the file to `--image` — then display is clean.
Easiest conversion is usually the Inkscape CLI:
```bash
inkscape treeBoxes.svg --export-text-to-path --export-plain-svg --export-filename=usingPaths.svg
```
Then point TerminalWidget at the outlined file:
```bash
terminal-widget --target widget1 --image ./usingPaths.svg
```
### Image Filters (`--filter`)
Apply built-in filters to images. You can pass one filter, repeat `--filter`, or provide a comma-separated filter chain.
```bash
terminal-widget --target widget1 --image "https://picsum.photos/640/640" --filter sepia:35
terminal-widget --target widget1 --image "https://picsum.photos/640/640" --filter grayscale
terminal-widget --target widget1 --image "https://picsum.photos/640/640" --filter "sepia:25,blur:8"
```
### Background image
`--background-image` places an image full-bleed behind text, icons, progress, charts, or tables. It is mutually exclusive with the content `--image` option. Use `--filter alpha:0-100` to fade the backdrop so `--bg` shows through. Padding insets the foreground only; the photo always fills the widget. Watch complications do not draw the backdrop.
```bash
terminal-widget --target widget1 --background-image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" --filter alpha:40 --bg 0f172a --fg "#f8fafc" --title "Today" --text "Austin 84" --caption-text "Clear" --icon sun.max.fill
terminal-widget --target widget1 --background-image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" --filter alpha:35 --bg 0f172a --fg "#7dd3fc" --chart "4 8 15 16 23 42" --text "Throughput"
python3 scripts/planets.py --target widget1 --background 1
```
macOS gallery slots **background-image-text**, **background-image-chart**, and **background-image-table** match those commands (`capture-macos-widgets.sh --only background-image-text,background-image-chart,background-image-table`). The iOS interactive script uses the same slugs. Override the photo for the text/chart slots with `TW_BACKGROUND_IMAGE_URL`. The table slot runs `scripts/planets.py` (python3 + astropy). macOS updates widget1–4 (extra large through small; the small widget uses a compact sky+icon instead of a table). Lightbox captions still show the widget1 command. iOS uses `--all` to push widget1–3 with skies 1–3 (sailboat, nebula, starburst).
### Icon Behavior (`--icon`)
`--icon` is inline with text/progress/chart, or centered if icon-only mode is active.
```bash
terminal-widget --target widget1 --text "CPU 62%" --icon "cpu.fill" --chart "58 61 66 62 64 62" --chart-format strip
```
---
## Docs: TerminalWidget Shortcuts
Source: https://terminalwidget.app/shortcuts.md
# TerminalWidget Shortcuts
> Build TerminalWidget automations in Shortcuts with practical examples.
Source: https://terminalwidget.app/shortcuts
Use TerminalWidget's App Intents in Shortcuts.app for native automation that does not require shell commands or manual URL encoding.
**Add a widget first.** Shortcuts only update widgets you place yourself (Desktop or Home Screen) after you set **Edit Widget → Target name** to match the action's **Target** field. See [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
{:loading=lazy width=1074 height=684 style="max-width:100%;height:auto;"}
## Available Shortcuts Actions
TerminalWidget exposes intent actions for common update types:
- **Render Widget**: full payload action (text, icon, progress, chart, image or background image, colors, theme, layout)
- **Render Text**: quick text/icon update
- **Render Chart**: chart update with format options
- **Render Progress**: progress update with style options
- **Render Image**: image update with optional filters/layout controls
- **Render Table**: table render from CSV/TSV/JSON data source
These map to the same validation/rendering pipeline used by CLI, AppleScript, and URL scheme updates. **Text** fields may include CommonMark-style `[label](url)` links; the widget renders them as tappable buttons (same rules as CLI `--text`). Launcher button grids (including `button-columns` layout and `button-border` / per-button border styling) are set via structured JSON `buttons` through CLI `--json` (or any JSON payload path), not individual Shortcut fields in v1. See [Widgets](https://terminalwidget.app/widgets.md#launcher-buttons-buttons-in-json) for the button and border field reference.
On **Render Widget** (Update TerminalWidget), optional **Background Image** places a full-bleed image behind text, icons, progress, charts, or tables. It is mutually exclusive with the content **Image** field, and **Filter** `alpha:0-100` can fade it. The same field is available on Render Text, Render Chart, Render Progress, and Render Image. Combine **Table** and **Background Image** on Render Widget; the dedicated Render Table action does not include a background-image field. Optional **Title**, **Title Alignment** (`Left`, `Center`, `Right`; default **Center** when **Title** is set), **Title Color**, and **Caption Text** accept GitHub `:emoji:` shortcodes (for example `:rocket:`, `:white_check_mark:`), same as **Text** and **Icon**. **Caption Text** implies **Caption** and replaces auto `[min/max]` or `[n%]` text. Optional **Label Y** adds a left y-axis to numeric charts, and **Timestamp** shows the last CLI/URL update time at the bottom (with or without **Caption** / **Caption Text**). **Chart** accepts space-separated numbers, **slash-separated grouped sparkline/bar or multi-series line groups** (for example `0 1 5 2/1 2 5 3`, up to four series), rangebar `low-high` pairs, pie `label:value[:color]` tokens (for example `CPU:45 Memory:30 Disk:25`), or JSON (flat, nested numeric, named `series`, or pie `slices`). Use **Chart Format** `sparkline`/`bar` for grouped slash input, **Series Lines** for overlapping line charts with a bottom legend, or **Pie** for categorical slices. Optional **Append** adds chart columns (same syntax as Chart) or text lines to the existing target without replacing other settings; optional **Limit** keeps the last N chart columns or text lines (persisted; `0` clears the soft limit). Append cannot be combined with Chart or Text in the same action. Comma-separated **Foreground** colors use the first value for text/icons and the rest for series or slice colors. **Chart Bar Style** `Glass` applies to sparkline/bar, waveform, range bar, matrix, and delta charts, and to **circle** progress rings when **Progress Format** is `Circle` (chart data not required for circle glass). Optional **Chart Key** controls legend placement (`Auto`, `Inline`/`Left`, `Bottom`, `External`, `None`). **Chart Series Labels** sets comma-separated series names. **Key Target** writes the legend to a second widget (pair with **Chart Key** `External`; the key widget inherits colors from the chart update). **Render Text**, **Render Chart**, **Render Progress**, and **Render Image** expose the same title, alignment, title color, caption text, and timestamp fields where they apply. **Render Chart** and **Render Progress** also expose chart and bar-style fields where applicable (progress can use **Caption** for `[n%]` and **Timestamp** for the update time). Optional **Notify on change** persists in the widget payload (syncs via iCloud); **Notify once** fires a local notification only when this action changes display content and does not change the saved setting. Grant notification permission when prompted.
On **Render Widget**, optional action fields can assign what happens when the widget is tapped or clicked:
- **Action Kind**: `open-url`, `open-app`, `run-shortcut`, or `run-command`
- **Action Value**: the URL, macOS bundle identifier, Shortcut name, or shell command
- **Clear Action**: removes the saved tap/click action for the target
Actions are saved with the target payload and sync through iCloud. On macOS, all four action kinds are supported. On iOS, URL and Shortcut actions are supported; synced macOS-only app and shell actions fall back to the normal widget open/update behavior.
### Auto-update (Run Every)
On **Render Widget** / **Update TerminalWidget**, optional **Run Every**, **Run Every Unit**, and **Shortcut Name** store a Mac-only auto-update recipe on that target. While the Terminal Widget menu-bar app is open (or set to Open at Login), it re-triggers that Shortcut on the interval.
- Removing the Desktop widget does **not** clear the recipe.
- Later updates that omit **Run Every** leave the existing recipe in place.
- To stop it: turn on **Clear Auto-Update** in an Update TerminalWidget action, run `terminal-widget --target YOUR_TARGET --clear-auto-update`, or use **Info/Debug → Auto-update** in the menu bar app.
- If iCloud sync is on, also clear (or delete the cloud record) so a reinstall does not restore the recipe.
## Build Your First Shortcut
1. Open **Shortcuts.app** and create a new shortcut.
2. Add the **Render Widget** action from TerminalWidget.
3. Set **Target** (for example `widget1`).
4. Fill any fields you want to update (`Text`, `Icon`, `Progress`, etc.).
5. Run the shortcut and confirm the widget refreshes.
## Passing Data Into Actions
Shortcuts variables can drive any field in the action.
### From Input Prompt
1. Add **Ask for Input** (`Prompt`: `Widget text`).
2. Add **Render Text**.
3. Set `Target` to `widget1`.
4. Set `Text` to **Provided Input**.
### From Dictionary/Data
1. Build a **Dictionary** with keys like `target`, `text`, `progress`.
2. Add **Get Dictionary Value** actions.
3. Feed each result into **Render Widget** parameters.
### From Web/API Data
1. Add **Get Contents of URL**.
2. Parse JSON fields (for example status or numeric metrics).
3. Convert/format values if needed.
4. Pass results into **Render Widget**, **Render Chart**, or **Render Progress**.
## Pattern Examples
### Daily Status Widget
- Trigger: **Time of Day** automation
- Actions:
1. `Get Contents of URL` (status endpoint)
2. `Get Dictionary Value` (`message`, `progress`)
3. `Render Widget` (`target: widget1`, text from `message`, progress from `progress`)
### Build Result Widget
- Trigger: run from Share Sheet, Finder Quick Action, or manual run
- Actions:
1. `Run Script over SSH` or `Get File` metadata
2. conditional branch (`If`)
3. `Render Text` with `icon` set to success/failure symbol
### Chart Snapshot Widget
- Trigger: schedule every 15 minutes
- Actions:
1. fetch metrics
2. build list of numbers
3. join numbers as chart input
4. `Render Chart` with chosen `chart format` and optional caption. Use `rangebar` with values like `1-3 2-3 1-4` for range bars.
### Grouped Sparkline Widget
- Trigger: manual or scheduled
- Actions:
1. `Render Chart` with `Chart` set to `0 1 5 2/1 2 5 3`, `Chart Format` `Bar` or `Sparkline`, optional `Foreground` `#cc0000,#00cc00,#0000cc`, optional `Annotation` and `Chart Bar Style` `Glass`.
### Multi-Series Line Chart Widget
- Trigger: manual or scheduled
- Actions:
1. `Render Chart` with `Chart` set to `1 4 9 3/2 5 8 4/6 7 5 2`, `Chart Format` `Series Lines`, `Chart Series Labels` `CPU,Memory,Disk`, optional `Foreground` `#f87171,#4ade80,#60a5fa`.
### Pie Chart Widget
- Trigger: manual or scheduled
- Actions:
1. `Render Chart` with `Chart` set to pie literals such as `CPU:45 Memory:30 Disk:25`, `Chart Format` `Pie`, `Chart Key` `Inline`, optional comma-separated `Foreground` for slice colors.
2. For a dedicated key widget: set `Chart Key` to `External`, `Key Target` to `cpu-key` (must match **Edit Widget → Target name** on the key widget).
### Circle Progress with Glass Ring
- Actions:
1. `Render Progress` with `Progress` `72`, `Progress Format` `Circle`, `Chart Bar Style` `Glass`, optional `Caption`.
### Launcher Widget
- Trigger: manual run from Shortcuts
- Actions:
1. Add `Render Widget`
2. Set `Target` to `widget1`
3. Set `Text` and `Icon` for the visible widget state
4. Set `Action Kind` to `open-url`
5. Set `Action Value` to the destination URL
Use `run-shortcut` with a Shortcut name to make the widget run another Shortcut when tapped. Use `open-app` with a macOS bundle identifier or `run-command` with a shell command for macOS-only launcher widgets.
## Data Formatting Notes
- **Progress** expects `0...100`.
- **Chart** values should be numeric and in display order. For **grouped sparkline/bar** columns, separate series with `/` (for example `10 20 30/12 18 25`); use **Chart Format** sparkline or bar. For **multi-series line** charts, use **Chart Format** Series Lines with the same slash syntax. For **pie** charts, use **Chart Format** Pie with `label:value[:color]` tokens (for example `CPU:45 Memory:30 Disk:25`). Up to four series and 128 points per series for line/sparkline modes.
- **Chart Bar Style** `Glass` works with sparkline/bar, waveform, range bar, matrix, delta charts, and with **Progress Format** `Circle` (no chart field needed for circle glass).
- **Foreground** comma-separated lists: first color for text/icons, remaining colors for grouped chart series or pie slice colors.
- **Chart Key**, **Chart Series Labels**, and **Key Target** on **Update TerminalWidget** and **Show TerminalWidget Chart** control legend placement, series names, and external key widgets (same behavior as CLI `--chart-key`, `--chart-series-labels`, and `--key-target`).
- **Colors** accept hex/rgb/rgba style values.
- **Table** input should point to readable CSV/TSV/JSON content.
- **Table Layout** is `Auto` (content-sized; leftover space after the last column), `Fill` (stretch measured columns to widget width), or `Equal`.
- **Table Align** is a comma-separated list of `left`, `center`, or `right` (one value per column; remaining columns repeat the last value).
- **Center Table** centers an auto-sized table horizontally. It only applies to auto layout and is ignored for equal and fill.
- **Image** and **Background Image** can be local files or remote URLs, but cannot both be set in one action. Background images are always full-bleed and can accompany text, progress, charts, and tables.
- **Action Kind** accepts `open-url`, `open-app`, `run-shortcut`, or `run-command`.
- **Action Value** must match the kind: URL for `open-url`, bundle identifier for `open-app`, Shortcut name for `run-shortcut`, or shell command for `run-command`.
If optional fields are omitted, those values are left unchanged (or reset by intent defaults where applicable).
## Mixing with URL Scheme and CLI
You can combine integrations in one workflow:
- Use Shortcuts for user input and scheduling.
- Use URL scheme links for quick launcher-style actions.
- Use CLI in shell-centric workflows (build scripts, cron, CI agents).
Related docs:
- [Recipes](https://terminalwidget.app/recipes)
- [URL Scheme Documentation](https://terminalwidget.app/url-scheme.md)
- [CLI Documentation](https://terminalwidget.app/cli.md)
- [AppleScript Documentation](https://terminalwidget.app/applescript.md)
## iOS Shortcuts
All Shortcut actions are also available on iOS.
On iPhone and iPad, open TerminalWidget once after install and **allow notifications** when prompted (that is what adds TerminalWidget under **Settings > Notifications**). The app relies on push notifications to pull iCloud widget updates in the background; without permission, Home Screen widgets may not refresh until you open the app. The same permission is required for notify-on-change alerts.
- [{:loading=lazy width=512 height=512}](https://terminalwidget.app/assets/images/tw-shortcuts-actions-512@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=512 height=512}](https://terminalwidget.app/assets/images/tw-shortcuts-show-chart-512@2x.jpg){.widget-shot.js-lightbox}
- [{:loading=lazy width=512 height=512}](https://terminalwidget.app/assets/images/tw-shortcuts-result-512@2x.jpg){.widget-shot.js-lightbox}
{.widget-shot-grid.shortcuts-shot-grid}
---
## Docs: TerminalWidget AppleScript
Source: https://terminalwidget.app/applescript.md
# TerminalWidget AppleScript
> AppleScript command reference and examples for TerminalWidget.
Source: https://terminalwidget.app/applescript
Use TerminalWidget's AppleScript dictionary to update widgets from
Script Editor, AppleScript apps, and automation tools.
**Add a widget first.** AppleScript only updates widgets you place yourself (Desktop or Home Screen) after you set **Edit Widget → Target name** to match the `target` parameter. See [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
## Usage
```applescript
tell application "TerminalWidget"
render widget target "widget1" text "Hello from AppleScript" icon "terminal.fill"
end tell
```
## Commands
- `render widget` Full update command with named parameters (text, icon,
chart, progress, image, background image, table, theme, colors, layout, and formatting
options)
- `render text` Convenience command for text updates
- `render chart` Convenience command for chart updates
- `render progress` Convenience command for progress updates
- `render image` Convenience command for image updates
- `render background image` Convenience command for full-bleed background image updates
- `render table` Convenience command for table updates
## Examples
```applescript
tell application "TerminalWidget"
render widget target "widget1" text "Deploy done" icon "checkmark.circle.fill" ¬
notify true
render chart target "widget1" chart "1 2 3 4 5" chart format "smooth" ¬
annotation true caption true timestamp true
render chart target "widget1" chart "0 1 5 2/1 2 5 3" chart format "bar" ¬
foreground "#cc0000,#00cc00,#0000cc" annotation true
render chart target "widget1" chart "1 4 9 3/2 5 8 4/6 7 5 2" chart format "series" ¬
chart series labels "CPU,Memory,Disk" foreground "#f87171,#4ade80,#60a5fa" background "#0f172a"
render chart target "widget1" chart "CPU:45 Memory:30 Disk:25" chart format "pie" ¬
foreground "#f87171,#4ade80,#60a5fa" background "#0f172a"
render widget target "cpu" chart "CPU:45 Memory:30 Disk:25" chart format "pie" ¬
chart key "external" key target "cpu-key" background "#0f172a" foreground "#e2e8f0"
render chart target "widget1" chart "1-3 2-3 1-4" chart format "rangebar"
render widget target "widget1" append data "6 7" limit 20
render progress target "widget1" progress 72 ¬
progress format "circle" chart bar style "glass" caption true
render progress target "widget1" progress 72 ¬
progress format "gradient-horizontal" ¬
gradient from "#38bdf8" gradient to "#0ea5e9" gradient width 24 ¬
caption true timestamp true
render text target "widget1" text "Build passed" icon "checkmark.circle.fill"
render image (POSIX file "/tmp/status.png") target "widget1" ¬
filter "sepia:65,blur:8" full width true
render image "/tmp/status.png" target "widget1" padding "12"
render widget image (POSIX file "/tmp/status.png") target "widget1"
render background image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" ¬
target "widget1" filter "alpha:40"
render widget target "widget1" background image "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?auto=format&fit=crop&w=1600&q=80" ¬
filter "alpha:35" chart "4 8 15 16 23 42" text "Throughput"
end tell
```
## Dictionary
Explore the dictionary in Script Editor with **File->Open Dictionary** (⇧⌘O). Select TerminalWidget from the dictionary selection window.
`render widget` _v_ : Apply a full widget update using CLI-style options.
- `[target text]` : Widget target identifier.
- `[text text]` : Widget text content.
- `[icon text]` : SF Symbol or emoji icon.
- `[theme text]` : Theme: system, light, or dark.
- `[font text]` : Font family name.
- `[font size real]` : Font size in points.
- `[foreground text]` : Foreground color. Comma-separated values use the first for text/icons and the full list for grouped sparkline series colors.
- `[background text]` : Background color value.
- `[alpha real]` : Global alpha from 0 to 1.
- `[padding text]` : Padding value or fill.
- `[chart text]` : Chart data: space-separated numbers, slash-separated grouped sparkline/bar or multi-series line groups (for example `0 1 5 2/1 2 5 3`, up to four series), rangebar `low-high` pairs, pie `label:value[:color]` tokens (for example `CPU:45 Memory:30 Disk:25`), or JSON (flat array, nested numeric series, named `series` objects, or pie `slices`).
- `[append data text]` : Append chart columns (same syntax as chart) or text lines to the existing widget. Named `append data` because `append` is reserved in AppleScript. Incompatible with replacing `chart`/`text` in the same command.
- `[limit integer]` : Keep the last N chart columns or text lines (persisted). `0` clears the soft limit.
- `[chart format text]` : Chart format name (`sparkline`, `graph`, `series`/`lines`/`multiline`, `pie`, `matrix`, `rangebar`, etc.).
- `[chart key text]` : Legend placement for `series` and `pie`: `auto`, `inline`/`left`, `bottom`, `external`, or `none`. Pie on medium/extra-large widgets uses a side legend for `auto`/`inline`/`left`.
- `[chart series labels text]` : Comma-separated legend labels for `series` charts (order matches slash-separated groups).
- `[key target text]` : Second widget target for an external legend (for example `cpu-key`). Use with `chart key` `external`. The key widget inherits foreground, background, gradient, and padding from the chart update.
- `[bar radius integer]` : Sparkline bar or range bar corner radius percentage (`0`–`100`).
- `[chart bar style text]` : `solid` (default) or `glass` for sparkline/bar, waveform, rangebar, matrix, pie, delta charts, and circle progress rings.
- `[annotation boolean]` / `[annotate boolean]` : Enable chart annotation.
- `[title text]` : Optional title at the top of chart, text, image, or progress widgets (`:emoji:` shortcodes expand).
- `[title alignment text]` : Title alignment: `left`, `center` (default when title is set), or `right`.
- `[title color text]` : Title color (hex/rgb/rgba); defaults to foreground.
- `[caption text text]` : Custom footer below content (implies caption; replaces auto min/max or percent). `:emoji:` shortcodes expand (for example `:white_check_mark:` → ✅).
- `[caption boolean]` : Show `[min/max]` or `[n%]` caption when applicable.
- `[label y boolean]` : Show y-axis labels on numeric charts.
- `[timestamp boolean]` : Show last update time at the bottom (any widget type when no footer already shows it).
- `[progress integer]` : Progress percentage `0`–`100`.
- `[progress format text]` : Progress style (`bar`, `matrix`, `dots`, `stack`, `circle`, `watch`, `quadrant`, `gradient-horizontal`, `gradient-vertical`).
- `[gradient from text]` : Gradient start color.
- `[gradient to text]` : Gradient end color.
- `[gradient width integer]` : Gradient width in pixels.
- `[image text]` : Path or URL to image.
- `[background image text]` : Path or URL to a full-bleed background image. It can accompany text, progress, charts, or tables, but not `image`.
- `[filter text]` : Image filter specification.
- `[table text]` : Table content payload.
- `[header boolean]` : Show table header row.
- `[grid text]` : Table grid style.
- `[table layout text]` : Table layout mode (`auto`, `equal`, or `fill`).
- `[table align text]` : Per-column table text alignment (comma-separated `left`, `center`, or `right`; remaining columns repeat the last value).
- `[center table boolean]` : Center an auto-sized table horizontally. Ignored for `equal` and `fill` layouts.
- `[zebra opacity real]` : Zebra striping opacity from 0 to 1.
- `[status coloring boolean]` : Enable semantic table status coloring.
- `[notify boolean]` : Persist notify-on-change for this target (local notification when display content changes).
- `[notify once boolean]` : Notify only for this command when display content changes (does not change persisted setting).
- `[action kind text]` : Widget tap/click action kind: `open-url`, `open-app`, `run-shortcut`, or `run-command`.
- `[action value text]` : URL, bundle identifier, Shortcut name, or shell command for the action.
- `[clear action boolean]` : Remove the persisted widget tap/click action.
`render text` _v_ : Convenience wrapper for text updates.
- `[target text]` : Widget target identifier.
- `[text text]` : Widget text content.
- `[icon text]` : SF Symbol or emoji icon.
- `[theme text]` : Theme: system, light, or dark.
- `[title text]` : Optional title at the top (`:emoji:` shortcodes expand).
- `[title alignment text]` : Title alignment: `left`, `center`, or `right`.
- `[title color text]` : Title color (hex/rgb/rgba); defaults to foreground.
- `[caption text text]` : Custom footer below content (`:emoji:` shortcodes expand).
- `[timestamp boolean]` : Show last update time at the bottom.
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
`render chart` _v_ : Convenience wrapper for chart updates.
- `[target text]` : Widget target identifier.
- `[chart text]` : Chart data (slash-separated series for grouped sparkline/bar or multi-series lines, pie `label:value` tokens, or JSON).
- `[chart format text]` : Chart format name, such as `sparkline`, `graph`, `series`, `pie`, `matrix`, or `rangebar`.
- `[chart key text]` : Legend placement for `series` and `pie` (`auto`, `inline`/`left`, `bottom`, `external`, `none`).
- `[chart series labels text]` : Comma-separated legend labels for `series` charts.
- `[key target text]` : External legend widget target (pair with `chart key` `external`).
- `[bar radius integer]` : Sparkline bar or range bar corner radius percentage (`0`–`100`).
- `[chart bar style text]` : `solid` or `glass` for compatible bar chart modes.
- `[annotation boolean]` / `[annotate boolean]` : Enable chart annotation.
- `[title text]` : Optional title at the top (`:emoji:` shortcodes expand).
- `[title alignment text]` : Title alignment: `left`, `center`, or `right`.
- `[title color text]` : Title color (hex/rgb/rgba); defaults to foreground.
- `[caption text text]` : Custom footer text (`:emoji:` shortcodes expand).
- `[caption boolean]` : Show `[min/max]` caption below the chart.
- `[label y boolean]` : Show y-axis labels on numeric charts.
- `[timestamp boolean]` : Show last update time below the caption (with or without caption).
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
`render progress` _v_ : Convenience wrapper for progress updates.
- `[target text]` : Widget target identifier.
- `[progress integer]` : Progress percentage from 0 to 100.
- `[title text]` : Optional title at the top (`:emoji:` shortcodes expand).
- `[title alignment text]` : Title alignment: `left`, `center`, or `right`.
- `[title color text]` : Title color (hex/rgb/rgba); defaults to foreground.
- `[caption text text]` : Custom footer text (`:emoji:` shortcodes expand).
- `[caption boolean]` : Show `[n%]` with bar/matrix/etc. progress styles when applicable.
- `[timestamp boolean]` : Show last update time in the caption area.
- `[progress format text]` : Progress style (`bar`, `matrix`, `dots`, `stack`, `circle`, `watch`, `quadrant`, `gradient-horizontal`, `gradient-vertical`).
- `[chart bar style text]` : `glass` for a glossy circle ring when `progress format` is `circle` (aliases: `chart bar style`, `chart-bar-style`).
- `[gradient from text]` : Gradient start color.
- `[gradient to text]` : Gradient end color.
- `[gradient width integer]` : Gradient width in pixels.
- `[foreground text]` : Foreground color (ring color for circle progress).
- `[background text]` : Background color value.
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
`render image` _v_ : Convenience wrapper for image updates.
- `[target text]` : Widget target identifier.
- `[image text]` : Path or URL to image.
- `[filter text]` : Image filter specification.
- `[title text]` : Optional title at the top (`:emoji:` shortcodes expand).
- `[title alignment text]` : Title alignment: `left`, `center`, or `right`.
- `[title color text]` : Title color (hex/rgb/rgba); defaults to foreground.
- `[caption text text]` : Custom footer text (`:emoji:` shortcodes expand).
- `[timestamp boolean]` : Show last update time at the bottom.
- `[full width boolean]` : Enable full-width content layout.
- `[padding text]` : Padding value or fill.
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
`render background image` _v_ : Convenience wrapper for full-bleed background image updates.
- `[background image text]` : Path or URL to the background image.
- `[target text]` : Widget target identifier.
- `[filter text]` : Image filter specification; use `alpha:0-100` to fade the background.
- `[title text]` : Optional title at the top.
- `[title alignment text]` : Title alignment: `left`, `center`, or `right`.
- `[title color text]` : Title color (hex/rgb/rgba).
- `[caption text text]` : Optional footer text.
- `[timestamp boolean]` : Show the last update time.
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
`render table` _v_ : Convenience wrapper for table updates.
- `[target text]` : Widget target identifier.
- `[table text]` : Table content payload.
- `[header boolean]` : Show table header row.
- `[grid text]` : Table grid style.
- `[table layout text]` : Table layout mode (`auto`, `equal`, or `fill`).
- `[table align text]` : Per-column table text alignment (comma-separated `left`, `center`, or `right`; remaining columns repeat the last value).
- `[center table boolean]` : Center an auto-sized table horizontally. Ignored for `equal` and `fill` layouts.
- `[notify boolean]` : Persist notify-on-change for this target.
- `[notify once boolean]` : One-shot notify for this command only.
## Notes
- Grouped sparkline/bar charts use slash-separated segments in `chart` (for example `0 1 5 2/1 2 5 3`) with `chart format` `sparkline`, `spark`, or `bar`. Pair with comma-separated `foreground` for per-series colors.
- Multi-series line charts use `chart format` `series` (aliases `lines`, `multiline`) with the same slash syntax. Set `chart series labels` for custom legend names.
- Pie charts use `chart format` `pie` with `label:value[:color]` tokens in `chart`. Use `chart key` `inline`/`left` for a side legend on medium/extra-large widgets, or `chart key` `external` with `key target` for a dedicated legend widget.
- External key widgets inherit `foreground`, `background`, and padding from the chart update and scale legend text to fill the widget.
- `chart bar style` `glass` on `render progress` with `progress format` `circle` draws a glossy ring without chart data.
- AppleScript updates use the same request/validation pipeline as CLI and Shortcuts.
- `render image` accepts either a direct value
(`render image "/tmp/file.png"`) or a `POSIX file` value.
- `render background image` accepts a path, URL, or `POSIX file` value the same way.
- `annotation true` and `annotate true` are treated as the same option.
- If Script Editor does not recognize commands after an app update,
relaunch TerminalWidget and reopen Script Editor.
---
## Docs: TerminalWidget URL Scheme
Source: https://terminalwidget.app/url-scheme.md
# TerminalWidget URL Scheme
> URL scheme reference and examples for automating TerminalWidget updates.
Source: https://terminalwidget.app/url-scheme
Use the `terminalwidget://` URL scheme to trigger widget updates from Shortcuts, LaunchBar, Alfred, Raycast, browser bookmarks, and any app that can open URLs.
**Add a widget first.** URL updates only appear on widgets you place yourself (Desktop or Home Screen) after you set **Edit Widget → Target name** to match `target=`. See [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
## Base Format
```text
terminalwidget://update?target=widget1&text=Hello%20World
```
- Scheme: `terminalwidget://`
- Action path: `update`
- Parameters: URL query items (`key=value`)
Values should be URL-encoded (` ` => `%20`, `#` => `%23`, `&` => `%26`).
Widget taps use a separate dispatch endpoint:
```text
terminalwidget://action?target=widget1
```
You usually do not need to open that URL yourself. Set `actionKind` and `actionValue` on the `update` endpoint, and the widget extension will use the action endpoint when the saved action is supported on the current platform.
## How It Works
1. macOS receives the URL and launches (or wakes) TerminalWidget.
2. The URL is parsed into the same payload used by the CLI and AppleScript layers.
3. The target widget state is written to shared preferences/App Group storage.
4. Widget refresh notifications are posted.
If a parameter is invalid, that field is ignored while valid fields still apply.
## Common Parameters
- `target`: widget target name (`widget1`, `widget2`, or custom target)
- `text`: text line (may include CommonMark-style `[label](url)` links; see note below)
- `icon`: SF Symbol name or GitHub `:emoji:` shortcode (for example `:rocket:`)
- `progress`: integer `0-100`
- `chart`: chart data (`4,8,15,16,23,42` or `4 8 15 16 23 42`; grouped sparkline/bar uses slash-separated series such as `0 1 5 2/1 2 5 3`; `rangebar` uses `1-3,2-3,1-4`; `series` uses the same slash syntax; `pie` uses `CPU:45 Memory:30 Disk:25` or `label:value[:color]` tokens)
- `append`: append chart columns (same syntax as `chart`) or text lines to the existing target; incompatible with `chart`/`text` in the same URL
- `limit`: keep the last N chart columns or text lines (persisted); `0` clears the soft limit
- `chartFormat`: `sparkline`, `graph`, `series`/`lines`/`multiline`, `pie`, `area`, `matrix`, `rangebar`, etc. Grouped slash `chart` values require `sparkline`/`spark`/`bar`. Multi-series lines use `series`; pie slices use `pie`.
- `chartKey` (or `chart-key`): legend placement for `series` and `pie`: `auto`, `inline`/`left`, `bottom`, `external`, or `none`. Pie on medium/extra-large widgets shows a side legend for `auto`/`inline`/`left`.
- `chartSeriesLabels` (or `chart-series-labels`): comma-separated legend labels for `series` charts (order matches slash-separated groups).
- `keyTarget` (or `key-target`): second widget target for an external legend (for example `cpu-key`). Pair with `chartKey=external`. The key widget inherits `fg`, `bg`, gradient, and padding from the chart update.
- `chartBarStyle` (or `chart-bar-style`): set to `glass` for bar-style chart modes and for `progressFormat=circle` rings; omit the parameter to **keep** the target’s existing chart bar style (omission does not turn glass off). Include `chartBarStyle` / `chart-bar-style` with a non-`glass` value (or `solid`) to return to the default solid bars.
- `fg`: comma-separated foreground colors use the first for text/icons and the full list for grouped sparkline series colors.
- `title` (or `widgetTitle` / `widget-title`): optional top title (chart, text, image, progress); GitHub `:emoji:` shortcodes expand
- `titleAlignment` (or `title-alignment` / `widgetTitleAlignment`): `left`, `center`, or `right` (default `center` when `title` is set)
- `captionText` (or `caption-text`): custom footer text (implies `caption=1`; replaces auto min/max or percent captions); `:emoji:` shortcodes expand
- `caption`: `1`/`true` to show chart min/max caption (or progress percent caption when used with progress)
- `labelY`: `1`/`true` to show the five-tick y-axis for numeric charts
- `timestamp` (or `chartTimestamp` / `chart-timestamp`): `1`/`true` to show the last update time at the bottom (any widget type when no footer already shows it)
- `image`: local file path or image URL
- `backgroundImage` (or `background-image`): local file path or image URL rendered full-bleed behind text, icons, progress, charts, or tables; mutually exclusive with `image`
- `filter`: filter chain (`sepia:35,blur:8`)
- `padding`: numeric value, `fill`, or `0`
- `theme`: `system`, `light`, or `dark`
- `fg`: foreground color (`#RRGGBB`, `rgb(...)`, `rgba(...)`)
- `textColor` (or `text-color`): main widget text / table default cell color; omit to match foreground
- `captionColor` (or `caption-color`): captions, custom caption text, and timestamp text; omit to match foreground
- `titleColor` (or `title-color`): title text color; omit to match foreground
- `bg`: background color
- `alpha`: `0.0...1.0` (applies to foreground, background, text color, caption color, and title color when those are set)
- `table`: `.csv`, `.tsv`, or `.json` path
- `grid`: `none`, `row`, `column`, `both`, `zebra`, `zebra-row`, `zebra-column`
- `tableLayout`: `auto` (content-sized; leftover space after the last column), `equal`, or `fill`. Pair `auto` with `tableCenter=1` to center the hugged table instead.
- `tableAlign`: comma-separated `left`, `center`, or `right` (aliases `l`/`c`/`r`, `leading`/`trailing`). Too few values repeat the last column; extras are ignored. Also stored on the `tablePayload` JSON envelope as `tableAlign`. Empty `tableAlign=` clears to the default (all left).
- `tableCenter` (aliases `table-center`, `centerTable`, `center-table`): `1`/`true` to center an auto-sized table horizontally; `0`/`false` or empty `tableCenter=` clears. Ignored for `equal` and `fill`. Also stored on the `tablePayload` JSON envelope as `tableCenter`.
- `zebraOpacity`: decimal `0.0...1.0` or percent-style `0...100`
- `notify`: `1`/`true` / `0`/`false` — persist notify-on-change in the payload (each device notifies locally after it applies a changed display state)
- `notifyOnce`: `1`/`true` — one-shot notify for this URL only if display content changes (does not persist)
- `actionKind`: widget tap/click action kind: `open-url`, `open-app`, `run-shortcut`, or `run-command`
- `actionValue`: value for `actionKind`: URL, macOS bundle identifier, Shortcut name, or shell command
- `clearAction`: `1`/`true` — remove the saved widget tap/click action
Widget body `text` may include CommonMark-style `[label](url)` links. The widget renders them as tappable buttons; non-link taps still use `actionKind` / `actionValue`.
Launcher button grids (`buttons`, borders, `button-columns`) are not available as URL query parameters. Set them with CLI `--json` (or another structured JSON update). See [Widgets](https://terminalwidget.app/widgets.md#launcher-buttons-buttons-in-json).
Action support is platform-specific. macOS supports all four action kinds. iOS supports URL and Shortcut actions; synced macOS-only app and shell actions fall back to the normal widget open/update behavior.
## Example URLs
### Text + Icon
```text
terminalwidget://update?target=widget1&text=Build%20Complete&icon=checkmark.circle.fill
terminalwidget://update?target=widget2&text=Deploy%20%F0%9F%9A%80&icon=%3Arocket%3A
```
### Progress
```text
terminalwidget://update?target=widget1&text=Syncing&progress=42
terminalwidget://update?target=widget1&text=Transfer%20Queue&progress=63&progressFormat=gradient-vertical&gradientFrom=%234fd1ff&gradientWidth=32&caption=1
```
### Charts
```text
terminalwidget://update?target=widget3&chart=4,8,15,16,23,42&chartFormat=peak
terminalwidget://update?target=widget3&chart=5,12,8,21,13,34&chartFormat=graph&annotate=1&caption=true
terminalwidget://update?target=widget3&chart=1,4,9,3&chartFormat=sparkline&labelY=1×tamp=1
terminalwidget://update?target=widget1&progress=50&caption=1×tamp=1
terminalwidget://update?target=widget1&text=Build%20queue&title=%F0%9F%93%88%20Throughput&captionText=Updated%20%E2%8F%B0×tamp=1
terminalwidget://update?target=widget3&chart=1,4,9,3,8,2,7,5&chartFormat=matrix&padding=0
terminalwidget://update?target=widget3&chart=1-3,2-3,1-4&chartFormat=rangebar
terminalwidget://update?target=widget1&chart=1%204%209%203/2%205%208%204/6%207%205%202&chartFormat=series&chartSeriesLabels=CPU,Memory,Disk&fg=%23f87171,%234ade80,%2360a5fa&bg=%230f172a
terminalwidget://update?target=widget1&chart=CPU:45%20Memory:30%20Disk:25&chartFormat=pie&fg=%23f87171,%234ade80,%2360a5fa&bg=%230f172a
terminalwidget://update?target=cpu&chart=CPU:45%20Memory:30%20Disk:25&chartFormat=pie&chartKey=external&keyTarget=cpu-key&bg=%230f172a&fg=%23e2e8f0
terminalwidget://update?target=widget3&chart=1,4,9,3,8,2,7,5&chartFormat=sparkline&limit=20
terminalwidget://update?target=widget3&append=10,12&limit=20
```
### Images + Filters
```text
terminalwidget://update?target=widget2&image=https%3A%2F%2Fpicsum.photos%2F640%2F360&padding=fill
terminalwidget://update?target=widget2&image=https%3A%2F%2Fpicsum.photos%2F640%2F640&filter=sepia%3A25%2Cblur%3A8
terminalwidget://update?target=widget2&image=%2FUsers%2Fyou%2FPictures%2Fstatus.png&padding=12
terminalwidget://update?target=widget1&backgroundImage=https%3A%2F%2Fimages.unsplash.com%2Fphoto-1506905925346-21bda4d32df4%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1600%26q%3D80&filter=alpha%3A40&text=Austin%2084
```
### Tables
```text
terminalwidget://update?target=widget1&table=%2FUsers%2Fyou%2Fstatus.csv&grid=zebra&tableLayout=auto&zebraOpacity=60
terminalwidget://update?target=widget1&table=%2FUsers%2Fyou%2Fstatus.tsv&grid=both&tableLayout=equal
terminalwidget://update?target=widget1&table=%2FUsers%2Fyou%2Fstatus.csv&grid=zebra&tableLayout=fill
terminalwidget://update?target=widget1&tablePayload=...&tableAlign=left,right,center
terminalwidget://update?target=widget1&tablePayload=...&tableLayout=auto&tableCenter=1
terminalwidget://update?target=widget1&table=%2FUsers%2Fyou%2Fstatus.json&grid=none
```
### Colors + Theme
```text
terminalwidget://update?target=widget2&theme=dark&fg=%23ffffff&bg=%23111417
terminalwidget://update?target=widget2&text=Light%20Mode%20Test&icon=sun.horizon&theme=light
terminalwidget://update?target=widget2&text=Alpha%20Override&fg=%23ffcc00&bg=%230f172a&alpha=0.85
```
### Combined Payloads
```text
terminalwidget://update?target=widget1&text=CPU%2062%25&icon=cpu.fill&chart=58,61,66,62,64,62&chartFormat=strip
terminalwidget://update?target=widget1&text=Night%20Audit&icon=moon.stars.fill&progress=91&theme=dark&fg=%23dbeafe&bg=%230b1220
```
### Notify on change
```text
terminalwidget://update?target=widget1&text=Service%20OK¬ify=1
terminalwidget://update?target=widget1&text=Deploy%20done¬ifyOnce=1
```
### Widget tap actions
```text
terminalwidget://update?target=widget1&text=Open%20dashboard&icon=arrow.up.right.square&actionKind=open-url&actionValue=https%3A%2F%2Fexample.com%2Fdashboard
terminalwidget://update?target=widget1&text=Run%20Backup&icon=externaldrive.fill&actionKind=run-shortcut&actionValue=Start%20Backup
terminalwidget://update?target=widget1&text=Open%20Transmission&icon=arrow.up.right.square&actionKind=open-app&actionValue=org.m0k.transmission
terminalwidget://update?target=widget1&text=Run%20script&icon=terminal&actionKind=run-command&actionValue=say%20Done
terminalwidget://update?target=widget1&clearAction=1
```
Opening the dispatch endpoint runs the action currently saved for the target:
```text
terminalwidget://action?target=widget1
```
## Building URLs in Scripts
When generating URLs from scripts, always URL-encode dynamic values:
```bash
TARGET="widget1"
TEXT="$(python3 -c 'import urllib.parse; print(urllib.parse.quote("Build complete #42"))')"
open "terminalwidget://update?target=${TARGET}&text=${TEXT}&icon=checkmark.circle.fill"
```
## Shortcuts Tip
In Shortcuts, use **URL Encode** on text values before building the URL string, then call **Open URLs**.
For native Shortcuts actions (which avoid manual URL encoding), see [Shortcuts Documentation](https://terminalwidget.app/shortcuts.md).
---
## Docs: TerminalWidget Integrations
Source: https://terminalwidget.app/integrations.md
# TerminalWidget Integrations
> Choose the best integration path for automating TerminalWidget updates.
Source: https://terminalwidget.app/integrations
**TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.**
Pick the integration that matches your automation stack. Each option links to detailed documentation and examples.
**Required before any update works:** TerminalWidget does not create desktop or Home Screen widgets for you. You must **manually add** a TerminalWidget widget, then set its **Target name** (widget ID). CLI, Shortcuts, AppleScript, and URL updates only reach widgets that share that ID. Follow [Getting Started](#getting-started) below before troubleshooting "nothing changed."
## Getting Started
Before CLI, Shortcuts, AppleScript, or URL scheme updates will show up, add a TerminalWidget widget and give it a **Target name** (widget ID). Every integration updates widgets by that ID.
### 1. Add a widget
**macOS**
1. Right-click the desktop (or open Notification Center / widgets gallery, depending on your macOS version).
2. Choose **Edit Widgets**, then find **TerminalWidget**.
3. Add a Small, Medium, or Large widget to the desktop.
4. Open the TerminalWidget menu bar app at least once after install.
If Desktop widgets look washed out when you are not in Show Desktop mode, open **System Settings → Desktop & Dock → Widgets** and set **Dim widgets on desktop** to **Never**.
**iPhone / iPad**
1. Touch and hold the Home Screen, then tap **Edit** → **Add Widget**.
2. Select **TerminalWidget** and add a size you want.
3. Open the TerminalWidget app at least once after install so iCloud sync can register the device (needed for Mac ↔ iPhone ↔ Watch sync).
### 2. Set the Target name
1. On the widget, open **Edit Widget** (right-click / long-press → Edit Widget).
2. Set **Target name** to an ID you will use in automation — for example `widget1`, `sales`, or `backup`.
3. Leave other options as defaults for now.
Use the same Target name in your scripts and Shortcuts (`--target`, **Target**, URL `target=`, and so on). Different widgets can share one ID (they show the same content) or use unique IDs for separate dashboards.
### 3. Send a test update
After the Target name is set, send a quick update from any integration — for example:
```bash
terminal-widget --target widget1 --text "Hello from TerminalWidget" --icon "checkmark.seal.fill"
```
If the widget does not change, confirm the Target name matches exactly (case-sensitive) and that TerminalWidget is installed and has been opened once on that device.
### 4. Sync with iCloud (optional)
Cross-device sync (Mac, iPhone, Apple Watch) uses iCloud and is **on by default**.
If you only use one device and do not want CloudKit:
- **Mac:** open the menu bar app → **Info/Debug** and turn off **Sync with iCloud**.
- **iPhone / iPad:** open TerminalWidget → **Info/Debug** and turn off the same toggle.
Local CLI, Shortcuts, and URL updates keep working on that device. Mac ↔ iPhone ↔ Watch sync stops until you turn the toggle back on. The preference is per device.
---
---
## Product: Put Terminal Output on Your Desktop
Source: https://terminalwidget.app/index.md
# Put Terminal Output on Your Desktop
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/
## Features
- **Real-time data at a glance**: Output text from [terminal commands](https://terminalwidget.app/cli.md) or generate charts, progress bars, and tables from data. Instant updates on macOS; rapid sync on iOS via iCloud.
- **Powerful CLI & automation**: [Full CLI](https://terminalwidget.app/cli.md) included, plus [Shortcuts](https://terminalwidget.app/shortcuts.md), [AppleScript](https://terminalwidget.app/applescript.md), and a [URL scheme](https://terminalwidget.app/url-scheme.md) for automation on Mac and iOS.
- **Multiple widget targets**: Target widgets individually from scripts and automations. Sync the same targets across Macs, iPhones, and iPads when iCloud is enabled.
- **Rich visual payloads**: Progress bars, charts, sparklines, matrix displays, tables, and local or remote images—including edge-to-edge layouts.
- **Full customization**: Control colors, fonts, icons, titles, and captions on every update.
- **Native & lightweight**: Mac App Store app with WidgetKit widgets and a small CLI—no Electron shell or always-on web server.
## Example command
```bash
terminal-widget --target widget1 --text "Build complete" --icon "checkmark.seal.fill" --progress 100 --fg "#22c55e"
```
## macOS
- Output any text, image, or chart data to fully [customizable widgets](https://terminalwidget.app/widgets.md)
- Use [shell scripts](https://terminalwidget.app/recipes) or [AppleScript](https://terminalwidget.app/applescript.md) output on macOS
- Interact via [Shortcuts](https://terminalwidget.app/shortcuts.md) or [URL scheme](https://terminalwidget.app/url-scheme.md) on macOS and iOS
- Assign actions to widgets to execute on tap/click
## Platforms
- Widgets sync across your Apple devices when iCloud is enabled.
- iOS and iPadOS widgets support the same [rich text, progress bar, and sparkline payloads](https://terminalwidget.app/widgets.md).
- Use the [URL scheme](https://terminalwidget.app/url-scheme.md) or [Shortcuts actions](https://terminalwidget.app/shortcuts.md) to update widgets from iPhone and iPad.
- Existing [CLI scripts](https://terminalwidget.app/cli.md) continue to work the same for Mac workflows.
## How it compares
| | TerminalWidget | Typical alternatives |
| --- | --- | --- |
| Footprint | Native Mac App Store app with WidgetKit widgets and a small CLI — no Electron shell or always-on web server. | Custom Electron/web dashboards or a self-hosted monitoring stack. |
| How you update | CLI, Shortcuts, AppleScript, or URL scheme targeting named widgets. | Agents, scrapers, or hand-built UI refresh loops. |
| Mac + iPhone + iPad | Same widget targets sync over iCloud when enabled. | Separate tools per platform, or your own sync relay. |
| What you can show | Text, progress, charts/sparklines, tables, and local or remote images. | Whatever you build into a custom dashboard — usually more setup. |
| Pricing | $19.99 one-time universal App Store purchase. | SaaS seats, infrastructure cost, or ongoing DIY maintenance. |
## FAQ
### How do I update a widget from a script or remote job?
First add a TerminalWidget widget to the Desktop or Home Screen and set Edit Widget → Target name. Then use the included terminal-widget CLI with flags like --target, --text, --progress, --chart, --icon, and --fg, or push the same fields via Shortcuts, AppleScript, or the URL scheme. On Mac, updates apply immediately. On iPhone and iPad, content syncs through iCloud after TerminalWidget has been opened once and notification permission has been allowed (the prompt on first open) so background pulls can wake the app. Full setup: https://terminalwidget.app/integrations#getting-started
### Why doesn’t my CLI or Shortcut update show on the widget?
TerminalWidget never auto-places widgets. You must add one yourself, then set its Target name to match --target, the Shortcuts Target field, or URL target=. Names are case-sensitive. Step-by-step guide: https://terminalwidget.app/integrations#getting-started
### Can tapping a widget run an action?
Yes. You can assign a tap/click action per widget target — open a URL, open a Mac app, run a Shortcut, run a shell command (macOS), or refresh from a URL. Actions sync with the widget payload over iCloud. On iOS, URL and Shortcut actions are supported; Mac-only app and shell actions fall back to normal open/update behavior.
### What can widgets display?
Plain or formatted text, progress (0–100), sparklines and other chart styles, matrix-style integer displays, tables (CSV/TSV/JSON), and local or remote images including edge-to-edge layouts. Colors, fonts, icons, titles, and captions are configurable per update.
### Do I need internet or iCloud for sync?
Local Mac updates work without the network. Cross-device sync uses iCloud, so each Mac, iPhone, and iPad should be signed into the same Apple ID with iCloud enabled for TerminalWidget. iOS and iPadOS also need notification permission so widgets can refresh in the background when another device updates a target.
### Why do my Mac desktop widgets look dimmed?
macOS can dim Desktop widgets when you are not in Show Desktop mode. To keep them fully visible, open System Settings → Desktop & Dock → Widgets and set Dim widgets on desktop to Never.
### Why does my SVG look wrong in the widget (missing text)?
WidgetKit’s SVG renderer is not full WebKit. Diagrams that use text or tspan elements often render correctly in Safari or Sketch but drop or mishandle labels in widgets. Convert text to outlines/paths before passing the SVG to --image — then labels display cleanly. Easiest with Inkscape CLI: inkscape in.svg --export-text-to-path --export-plain-svg --export-filename=out.svg (details on the Widgets page).
**TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.**
Send output from the CLI, Shortcuts, AppleScript, or a URL scheme. Available as a universal App Store app for **$19.99**.
---
## Product: Press Kit
Source: https://terminalwidget.app/press.md
# Press Kit
> Press kit for TerminalWidget.
Source: https://terminalwidget.app/press
### Downloads
- [Mac App Store](https://apps.apple.com/us/app/terminalwidget/id6764288419)
- [Press pack (ZIP)](https://terminalwidget.app/press/terminalwidget-press.zip) — press release and images
- [Launch video (MP4)](https://terminalwidget.app/press/terminalwidget-launch.mp4) — promo clip for embedding and coverage
### Promo video
### Product
**TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.**
|----:|:-----|
**Product** | TerminalWidget
**Website** | https://terminalwidget.app/
**Recipes** | https://terminalwidget.app/recipes/
**Availability** | Mac App Store (initial release)
**Price** | $19.99 USD, one-time purchase (Mac and iOS)
---
## Product: Join the TestFlight
Source: https://terminalwidget.app/testflight.md
# Join the TestFlight
> Join the TerminalWidget public TestFlight beta on iOS.
Source: https://terminalwidget.app/testflight
Join the public TestFlight beta to try it out and help debug!
---
## Product: Sign up for updates on TerminalWidget
Source: https://terminalwidget.app/newsletter.md
# Sign up for updates on TerminalWidget
> Subscribe for TerminalWidget updates and relevant offers.
Source: https://terminalwidget.app/newsletter
Get TerminalWidget updates and recipes—shell scripts, shortcuts, and other tips for building dashboards—plus relevant offers. Your email will only be used for this newsletter and will never be sold.
---
## Product: Downloads
Source: https://terminalwidget.app/downloads.md
# Downloads
> Downloadable files for TerminalWidget.
Source: https://terminalwidget.app/downloads
- [TW-Dash.zip](https://terminalwidget.app/assets/downloads/TW-Dash.zip) — Dash docset
---
## Compare: Compare TerminalWidget
Source: https://terminalwidget.app/compare.md
# Compare TerminalWidget
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare
Last reviewed: 2026-08-08
## Comparisons
- [TerminalWidget vs xbar](https://terminalwidget.app/compare/terminalwidget-vs-xbar.md): Side-by-side comparison of TerminalWidget and xbar for Mac script output and status displays.
- [TerminalWidget vs SwiftBar](https://terminalwidget.app/compare/terminalwidget-vs-swiftbar.md): Side-by-side comparison of TerminalWidget and SwiftBar for Mac script output and status displays.
- [TerminalWidget vs Übersicht](https://terminalwidget.app/compare/terminalwidget-vs-ubersicht.md): Side-by-side comparison of TerminalWidget and Übersicht for Mac desktop widgets and script output.
- [TerminalWidget vs GeekTool](https://terminalwidget.app/compare/terminalwidget-vs-geektool.md): Side-by-side comparison of TerminalWidget and GeekTool for Mac desktop script output and status displays.
- [Best Mac scriptable widget tools](https://terminalwidget.app/compare/best-mac-scriptable-widgets.md): Roundup of Mac tools that show script and automation output on the desktop or menu bar: TerminalWidget, xbar, SwiftBar, Übersicht, and GeekTool.
---
## Compare: Best Mac scriptable widget tools
Source: https://terminalwidget.app/compare/best-mac-scriptable-widgets.md
# Best Mac scriptable widget tools
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare/best-mac-scriptable-widgets
Last reviewed: 2026-08-08
| Tool | Surface | How you update | Mac / iPhone | Price | Best when… |
| --- | --- | --- | --- | --- | --- |
| TerminalWidget | Desktop / Home Screen widgets (WidgetKit) | CLI, Shortcuts, AppleScript, URL scheme | Mac, iPhone, iPad | $19.99 one-time (Mac App Store, universal) | You want named WidgetKit targets, charts/progress/images, and Mac + iPhone sync |
| xbar | Menu bar | Executable plugins / scripts on a refresh schedule | Mac | Free / open source | You want glanceable status in the menu bar and community plugins |
| SwiftBar | Menu bar | Executable plugins / scripts on a refresh schedule | Mac | Free / open source | You want an xbar-style plugin workflow with a modern SwiftBar host |
| Übersicht | Desktop (HTML/JS widgets) | Widget refresh commands / custom JS widgets | Mac | Free / open source | You want full HTML/CSS layout control on the desktop |
| GeekTool | Desktop geeklets (shell / file / image / web) | Shell commands or scripts on a refresh timer | Mac | Free (direct download) | You want free, script-driven text or images drawn directly on the desktop |
---
## Compare: TerminalWidget vs xbar
Source: https://terminalwidget.app/compare/terminalwidget-vs-xbar.md
# TerminalWidget vs xbar
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare/terminalwidget-vs-xbar
Last reviewed: 2026-08-08
xbar: Free open-source macOS app that shows script output in the menu bar (BitBar successor), with a large plugin ecosystem.
| Feature | TerminalWidget | xbar |
| --- | --- | --- |
| Price | $19.99 one-time (App Store) | Free / open source |
| Desktop widgets (WidgetKit) | Yes | No |
| Menu bar plugins | No | Yes (core focus) |
| iPhone / iPad widgets | Yes (iCloud sync) | No |
| Update via CLI / shell | Yes (terminal-widget CLI) | Yes (plugin scripts) |
| Shortcuts / URL scheme | Yes | No (script-driven) |
| iCloud sync across devices | Yes (optional) | No |
| Charts / progress / images | Built-in modes | Text / menu (custom if you draw it) |
| App Store distribution | Yes | No (direct / Homebrew) |
| Custom HTML/CSS UI | No | Limited (menu) |
| Plugin / community ecosystem | Recipes + docs samples | Large plugin browser |
## Choose TerminalWidget if…
- You want WidgetKit widgets on the Mac desktop and iPhone/iPad Home Screen
- You update from CLI, Shortcuts, AppleScript, or a URL scheme
- You need progress bars, charts, tables, or images—not only plain text
- You want the same target to sync over iCloud
## Choose xbar if…
- You primarily want menu bar output, not Desktop widgets
- You want a free open-source tool with hundreds of community plugins
- You are fine staying on Mac only (no iPhone widget sync)
---
## Compare: TerminalWidget vs SwiftBar
Source: https://terminalwidget.app/compare/terminalwidget-vs-swiftbar.md
# TerminalWidget vs SwiftBar
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare/terminalwidget-vs-swiftbar
Last reviewed: 2026-08-08
SwiftBar: Free macOS menu bar app compatible with BitBar/xbar-style plugins, with a SwiftUI-based host and plugin browser.
| Feature | TerminalWidget | SwiftBar |
| --- | --- | --- |
| Price | $19.99 one-time (App Store) | Free / open source |
| Desktop widgets (WidgetKit) | Yes | No |
| Menu bar plugins | No | Yes (core focus) |
| iPhone / iPad widgets | Yes (iCloud sync) | No |
| Update via CLI / shell | Yes (terminal-widget CLI) | Yes (plugin scripts) |
| Shortcuts / URL scheme | Yes | No (script-driven) |
| iCloud sync across devices | Yes (optional) | No |
| Charts / progress / images | Built-in modes | Text / menu (custom if you draw it) |
| App Store distribution | Yes | No (direct / Homebrew) |
| Custom HTML/CSS UI | No | Limited (menu) |
| Plugin / community ecosystem | Recipes + docs samples | BitBar/xbar-compatible plugins |
## Choose TerminalWidget if…
- You want WidgetKit widgets on the Mac desktop and iPhone/iPad Home Screen
- You update from CLI, Shortcuts, AppleScript, or a URL scheme
- You need progress bars, charts, tables, or images—not only plain text
- You want the same target to sync over iCloud
## Choose SwiftBar if…
- You want BitBar/xbar-compatible menu bar plugins
- You prefer SwiftBar's host app and plugin management
- You do not need WidgetKit desktop or iPhone widgets
---
## Compare: TerminalWidget vs Übersicht
Source: https://terminalwidget.app/compare/terminalwidget-vs-ubersicht.md
# TerminalWidget vs Übersicht
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare/terminalwidget-vs-ubersicht
Last reviewed: 2026-08-08
Übersicht: macOS desktop widget layer where each widget is a small HTML/JS/CoffeeScript program drawn on the desktop.
| Feature | TerminalWidget | Übersicht |
| --- | --- | --- |
| Price | $19.99 one-time (App Store) | Free / open source |
| Desktop widgets (WidgetKit) | Yes | No (custom HTML desktop layer) |
| Menu bar plugins | No | No |
| iPhone / iPad widgets | Yes (iCloud sync) | No |
| Update via CLI / shell | Yes (terminal-widget CLI) | Yes (widget commands / scripts) |
| Shortcuts / URL scheme | Yes | Limited / custom |
| iCloud sync across devices | Yes (optional) | No |
| Charts / progress / images | Built-in modes | Via custom HTML/JS |
| App Store distribution | Yes | No (direct download) |
| Custom HTML/CSS UI | No | Yes (core focus) |
| Plugin / community ecosystem | Recipes + docs samples | Community widgets / examples |
## Choose TerminalWidget if…
- You want WidgetKit widgets on the Mac desktop and iPhone/iPad Home Screen
- You update from CLI, Shortcuts, AppleScript, or a URL scheme
- You need progress bars, charts, tables, or images—not only plain text
- You want the same target to sync over iCloud
## Choose Übersicht if…
- You want custom HTML/CSS/JS layouts on the desktop
- You are comfortable maintaining small web-like widgets
- You do not need App Store WidgetKit or iPhone Home Screen widgets
---
## Compare: TerminalWidget vs GeekTool
Source: https://terminalwidget.app/compare/terminalwidget-vs-geektool.md
# TerminalWidget vs GeekTool
> TerminalWidget is a Mac, iPhone, and iPad app that shows text, progress bars, charts, and images in widgets, used by developers and power users to monitor scripts and automations at a glance.
Source: https://terminalwidget.app/compare/terminalwidget-vs-geektool
Last reviewed: 2026-08-08
GeekTool: Classic free macOS app that places shell, file, image, or web geeklets on the desktop and refreshes them on a timer.
| Feature | TerminalWidget | GeekTool |
| --- | --- | --- |
| Price | $19.99 one-time (App Store) | Free (direct download) |
| Desktop widgets (WidgetKit) | Yes | No (desktop geeklets, not WidgetKit) |
| Menu bar plugins | No | No |
| iPhone / iPad widgets | Yes (iCloud sync) | No |
| Update via CLI / shell | Yes (terminal-widget CLI) | Yes (shell geeklets on a timer) |
| Shortcuts / URL scheme | Yes | No (script-driven) |
| iCloud sync across devices | Yes (optional) | No |
| Charts / progress / images | Built-in modes | Text, images, or web geeklets (DIY) |
| App Store distribution | Yes | No (direct download) |
| Custom HTML/CSS UI | No | Yes (web geeklet) |
| Plugin / community ecosystem | Recipes + docs samples | Shared geeklets / community scripts |
## Choose TerminalWidget if…
- You want WidgetKit widgets on the Mac desktop and iPhone/iPad Home Screen
- You update from CLI, Shortcuts, AppleScript, or a URL scheme
- You need progress bars, charts, tables, or images—not only plain text
- You want the same target to sync over iCloud
## Choose GeekTool if…
- You want free desktop geeklets driven by shell scripts on a timer
- You are comfortable configuring Geeklets and do not need WidgetKit
- You only need Mac desktop display (no iPhone widgets or App Store sync)
---
## Optional: Changelog
Source: https://terminalwidget.app/changelog.md
# Changelog
> Release history for Terminal Widget (macOS, iOS, Apple Watch).
Source: https://terminalwidget.app/changelog
### 2.1.8
2026-09-04 03:20
#### CHANGED
- **Widget gallery** description mentions Home Screen and Lock Screen sizes
- **Lock Screen widgets** support rectangular and circular sizes on iPhone using the same target as the Home Screen widget
- **Lock Screen rectangular** shows text-first content (icon plus stripped text, optional progress), then progress, image, or a mini chart when text is absent
- **Lock Screen circular** shows a progress ring when percent is set, otherwise the SF Symbol icon or a letter fallback
- **Lock screen images** load once and fall back to the empty state if decode fails
- **Lock screen text** strips ANSI from widget titles as well as body text
### 2.1.6
2026-08-26 07:08
#### NEW
- **`terminal-widget log`** subcommand reads the bounded diagnostic event log from the App Group (`--level`, `--target`, `--limit`, `--follow`, `--json`, `--clear`).
- **`twdiags` widgets** on Mac and iOS render the device-local event log as text while keeping that target's styling; each device shows its own events only (no cross-device mirroring).
- **Info/Debug recent events** on Mac lists the last fifty diagnostic events and includes them when copying cloud diagnostics.
- **Diagnostic event log** records silent failures from the host app, CLI, and widget extension into one local JSONL store in the App Group.
- **Button command outcomes** capture nonzero exits, stderr, slow runs, and signal kills for widget `run-command` actions instead of failing quietly.
- **Missing widget images** are recorded when a payload claims an image the renderer cannot load on Mac and iOS.
- **Image fetch, copy, write, and App Group fallback** failures are recorded instead of failing quietly.
- **Save, iCloud pull/push/retry/subscribe, payload decode, and table clamp** failures are recorded in the diagnostic log on Mac and iOS.
- **Autoupdate shortcut and image refresh** failures are recorded in the diagnostic log.
- **Chart data truncation and open handoff failures** from the CLI are recorded in the diagnostic log.
- **Widget button actions** with an unknown kind, invalid URL, or missing app bundle are recorded instead of failing silently on Mac and iOS.
- **Widget reload requests and timeline builds** are paired in the log so stalled refreshes are easier to spot on Mac and iOS.
#### IMPROVED
- **Fish and bash completions** key off the first positional subcommand so flag values that look like subcommand names no longer steal completions (including `log` subcommand flags).
- **Noisy diagnostic codes** can be throttled per target so repeated reload, sync, and timeline events do not flood the log.
- **`terminal-widget log --follow`** flushes stdout so piped output appears promptly while tailing the log.
#### FIXED
- **Hiding the menu bar icon** no longer quits the app, so Control Center or a menu bar manager can park the item and bring it back instead of leaving no process to restore.
- **Quit TerminalWidget**, logout, and shutdown still exit normally after an intentional quit.
- **Shortcuts and URL-scheme updates on iOS** that fail validation or cannot save the payload now record the failure instead of failing quietly.
- **Failing button commands slower than the timeout** now record their exit instead of stopping at a "still running" warning that implied success.
- **Commands killed by a signal** are recorded as failures rather than being treated as a clean exit.
- **`terminal-widget log --json`** no longer prints prose on stdout when the log is empty, so piping to `jq` works instead of failing on the first line.
- **`terminal-widget log --clear`** is refused alongside `--target`, `--level`, `--limit`, or `--follow` instead of accepting filters and then deleting every target's events anyway.
### 2.1.5
2026-08-20 09:11
#### CHANGED
- **Idle widget taps** remain inert when no --action-kind is set (placeholder Hello World does not clear on click).
#### NEW
- **Pie charts** with `--chart-format pie` and `label:value[:color]` tokens (space- or comma-separated), optional per-slice colors, JSON `slices` arrays, inline side legend on medium/extra-large widgets, and percentage labels in the legend.
- **Multi-series line charts** with `--chart-format series` (slash-separated groups), shared Y scaling, and optional `--chart-series-labels` for legend names.
- **`--chart-key`** legend placement (`auto`, `inline`/`left`, `bottom`, `external`, `none`) for pie and series charts on macOS and iOS widgets.
- **`--key-target`** to write legend rows to a second widget (for example `cpu-key`), including legend-only key widgets that inherit colors from the main chart and scale text to fill the widget.
- **`--chart-bar-style glass`** support for pie slices (liquid glass wedge fills).
- **Quad4 multi-goal progress** with comma-separated `--progress` values, `--progress-format quad4` (`quad-4` alias), and optional `--progress-layout` grouping across CLI, URL, AppleScript, Shortcuts, and JSON.
#### IMPROVED
- **Matrix charts** keep up to 2048 cells (was 128, same as sparklines) and shrink cell size to fit the widget so extra-large heatmaps can show a dense series.
- **Series line colors** now match legend swatches instead of using a single foreground color for every line.
- **External key widgets** inherit foreground, background, gradient, and padding from the main chart update.
- **`--fit-text` for tables** grows cell fonts until width or height binds, persists on table updates, and vertically centers with `--center-table` (auto layout).
- **Table fit-text width safety** so grown cells stop before truncating, instead of overshooting into ellipses.
- **`--font` on tables** uses the same installed font for cells and column measurement as `--text` (macOS and iOS).
#### FIXED
- **Figlet and other `--no-wrap` ASCII blocks** no longer clip the first lines in WidgetKit. Multiline terminal art is rasterized to an image, scaled with the same 10pt inset as `--padding fill`, and centered when `--fit-text` is on.
- **Comma-separated pie literals** such as `Work:40,Play:25,Sleep:35` now parse correctly (commas inside `rgb(...)` colors are preserved).
- **iOS pie/series widget updates** by adding pie, series, and legend fields to the host app payload and URL handler so Shortcuts and URL updates persist and reload widgets.
- **External key widget updates** from CLI and URL scheme now write legend payloads to the `--key-target` widget instead of leaving it on the placeholder.
- **Whole-widget taps** on Mac and iPhone/iPad use App Intents (same path as launcher buttons) so configured actions keep working when custom-scheme widgetURL delivery fails.
### 2.1.4
2026-08-19 14:29
#### NEW
- **Quad4 multi-goal progress** accepts comma-separated `--progress` percentages with `--progress-format quad4` (`quad-4` alias) and optional `--progress-layout` quadrant grouping across CLI, URL, AppleScript, Shortcuts, and JSON automation.
#### IMPROVED
- **`--font` on tables** uses the same installed font for table cells as for `--text` (including `--fit-text` column measurement), on macOS and iOS.
#### FIXED
- **Whole-widget taps** on Mac and iPhone/iPad use App Intents (same path as launcher buttons) so configured actions keep working when custom-scheme `widgetURL` delivery fails.
#### CHANGED
- **Idle widget taps** remain inert when no `--action-kind` is set (placeholder Hello World does not clear on click).
### 2.1.3
2026-08-18 09:40
#### IMPROVED
- **Matrix charts** keep up to 2048 cells (was 128, same as sparklines) and shrink cell size to fit the widget so extra-large heatmaps can show a dense series.
#### FIXED
- **Figlet and other `--no-wrap` ASCII blocks** no longer clip the first lines in WidgetKit. Multiline terminal art is rasterized to an image, scaled with the same 10pt inset as `--padding fill`, and centered when `--fit-text` is on.
### 2.1.2
2026-08-18 09:40
#### CHANGED
- **Auto table columns** hug their measured text instead of stretching leftover width into every cell. Extra space stays after the last column; use `--table-layout equal` for uniform columns that fill the widget.
- **Center table** (`--center-table`) centers a content-sized table horizontally in the widget instead of leaving leftover space after the last column. Applies only to `--table-layout auto` and is ignored for equal and fill. Horizontal rules span the table, not the full widget. Also on AppleScript (`center table`), Shortcuts (Center Table on Update Widget and Show Table), JSON (`tableCenter` / `center-table`), and the URL scheme (`tableCenter=1`). A fresh `--table` without `--center-table` writes the default (left-aligned block).
- **Per-column table alignment** with `--table-align` (`left`/`center`/`right`, plus `l`/`c`/`r`, `leading`/`trailing`, and `centre`). Too few values repeat the last column; extras are ignored. Default is all left. Also on AppleScript (`table align`), Shortcuts (Table Align on Update Widget and Show Table), JSON (`tableAlign` string or array), and the URL scheme (`tableAlign=`). A fresh `--table` without `--table-align` writes the default instead of keeping a previous alignment.
- **Table layout fill** (`--table-layout fill`) measures columns from content then stretches them proportionally to the widget width (the previous auto behavior). Also on AppleScript (`table layout`), Shortcuts (Table Layout on Update Widget and Show Table), JSON, and the URL scheme (`tableLayout=fill`).
### 2.1.0
2026-08-16 10:19
#### CHANGED
- **Background image** for all chart types
- **Image detection and URL handling** ignore blank stored values and accept lowercase backgroundimage URLs.
- **JSON background images** now import with the background role without storing raw URLs as relative paths.
- **Deferred image imports** preserve whether the image is foreground content or a background.
- **Image role conflicts** are rejected across CLI flags and structured JSON.
- **Table row and type sizing** keeps dense Medium tables from overflowing with uneven rows, and sizes Large table type from the width needed to show the cells instead of growing the font to fill leftover height (which truncated columns).
- **Fill table layout** is no longer rewritten to auto on macOS and iOS widgets, so columns actually stretch instead of hugging.
#### NEW
- **Background image** for all chart types
- **Quadrant progress widgets** render segmented arcs for the quadrant progress format.
- **Mobile quadrant progress widgets** mirror the Mac segmented arc layout, captions, and footer behavior.
- **Quadrant progress automation** accepts quadrant through AppleScript and Shortcuts update requests.
- **Widget auto-update** recipe design for Shortcut re-run and image URL re-fetch on Mac host timers with optional Open at Login.
- **Auto-update recipes** persist per widget for Shortcut re-run or http(s) image refresh on Mac host timers.
- **Open at Login** toggle keeps the menu bar app (and timers) running across reboots without helpers.
- **Shortcuts Run Every** fields configure shortcut auto-update from Update TerminalWidget.
- **Markdown link labels** can include nested square brackets (for example [Item [nested]](https://example.com))
- **Quadrant progress captions** use the same centered layout and footer behavior as circle progress.
- **CLI progress formats** parse, document, complete, and emit quadrant payloads.
- **Oversized gaps** no longer drop partial segments; applyGaps
- **gapRadians NaN** cap asin argument at 1 so gap stays finite.
- **Quadrant progress arc direction** on Mac now sweeps CCW from 12
- **Quadrant progress arcs** now use clockwise: true so segments draw the short CCW path from 12 toward 9 instead of the long way through 3 and 6.
- **Quadrant URL updates** preserve the quadrant progress format on Mac and mobile.
- **Quadrant segment gaps** remain visible around round stroke caps at typical widget sizes.
- **Quadrant progress** grows stroke thickness on a full ring instead of shortening the active quadrant arc
## 2.0.10
#### IMPROVED
- **Markdown link labels** can include nested square brackets (for example [Item [nested]](https://example.com))
## 2.0.9
#### IMPROVED
- **ANSI colors** apply to text next to markdown links (for example a colored flag prefix before a tappable [label](url))
## 2.0.7
#### CHANGED
- **Tap URL helpers** return nil for nil or unconfigured actions on Mac and iOS
- **Image URL imports** now use authorized image folders before asking you to choose a file.
- **Synced transparent images** materialize as PNG (opaque photos still use JPEG) so widget backgrounds show through after sync.
#### NEW
- **Table cells** (CSV/TSV/JSON, including headers) support CommonMark `[label](url)` inline links on Mac and iPhone/iPad, same rules and tap behavior as `--text` links.
- **Image folder bookmarks** persist allowed image directories in the App Group as security-scoped bookmarks
- **Folder path helper** checks whether a file path lies under a granted folder prefix
- **Image folder management** lets Mac users grant and remove folders for local image automation.
- **Idle taps** Widget taps with no action do nothing; app does not open
- **Image folders** CLI docs for Mac folder grants, chooser fallback, FDA note
- **AppleScript image paths** Same folder grant rules as CLI
- **Image folders** (Info/Debug on Mac) let you grant one or more folders so CLI, AppleScript, and Shortcuts can load local images without a permission prompt for every file.
#### IMPROVED
- **GUI startup** avoids duplicate activation verification.
- **In-app help** explains the permission prompt and what to do if TerminalWidget is missing from Settings > Notifications.
- **AppleScript image updates** now offer the image chooser when a supplied image URL cannot be read.
- **Local image imports** try granted folders first, then fall back to a file chooser when the app can prompt (including AppleScript/Shortcuts), instead of failing silently.
#### FIXED
- **Mac open-url and markdown link taps** now open in the system default browser (including Choosy or Zen) instead of always preferring Safari.
- **Idle widget taps** no longer open the app when no tap action is configured
- **Image folder list** stays current when CLI sync triggers reloadFromDiskAndRefreshWidgets
- **Image-folder imports** continue to later granted folders when an earlier access attempt does not copy the file.
- **Widget taps with no action** do nothing on Mac and iPhone/iPad instead of opening Terminal Widget.
- **iCloud image sync** keeps transparency for PNG/alpha sources instead of flattening them to white JPEG on Mac and iPhone/iPad.
- **Stale white JPEG sync blobs** refresh when the on-disk source image still has alpha.
## 2.0.6
#### NEW
- **Direct licensing** adds Paddle purchase, activation, and seven-day trial handling.
- **License gates** block expired Direct CLI access and present the GUI licensing flow.
- **License menu** adds purchase, activation, and trial status controls to Direct builds.
- **TerminalWidget Direct app target** builds a Developer ID variant with bundle ID com.brettterpstra.TerminalWidget.direct, the DIRECT compile flag, and Paddle 4.5.1 plus Sparkle 2.9.5 linked and embedded.
- **WidgetExtension Direct** widget extension uses bundle ID com.brettterpstra.TerminalWidget.direct.Widget and is embedded only in the Direct app.
- **TerminalWidget Direct scheme** is shared for build, run, and archive.
- **--help, -h, --version, and completions** run without a license check at all
- **Trial not started** is a distinct state, so a fresh install is offered the trial instead of being told the trial ended
#### IMPROVED
- **GUI startup** avoids duplicate activation verification.
- **In-app help** explains the permission prompt and what to do if TerminalWidget is missing from Settings > Notifications.
#### FIXED
- **AppleScript append/limit** now use dictionary terms `append data` and `limit` on `render widget`, fixing parse errors from the reserved word `append` and missing sdef parameters.
- **CLI licensing** waits for Paddle verification and denies access when verification times out or fails.
- **Mac App Store app** no longer copies Info-Direct.plist into its Resources bundle.
- **Sparkle updates** now work in the sandboxed Direct build via the -spks/-spki mach-lookup exception and SUEnableInstallerLauncherService
- **iCloud sync** in Direct builds targets the Production CloudKit container explicitly, in both the app and widget entitlements
- **terminal-widget** no longer contacts Paddle on every command: a successful verification is cached for 24 hours and unlicensed copies rely on local trial state
- **Offline use** keeps a verified license working for 24 hours instead of failing on the first network hiccup
- **Revoked licenses** now destroy the local activation instead of lingering until the next launch
- **TerminalWidget Direct** now refuses to run with a usable menu bar when licensing cannot initialize; it offers Retry or Quit
- **Install Command Line Tool** finds the executable in Direct builds, where the product is named "TerminalWidget Direct" rather than "TerminalWidget"
- **terminal-widget** wakes and launches the app it was installed from, so a Direct install no longer signals the App Store build
- **Desktop widget updates** no longer stall until Edit Widget when the instance registry balloons from ephemeral WidgetKit Intent UUIDs; pathological registries are compacted instead of preserving every target-matching id.
- **Instance registry growth** from Intent gallery churn is capped at 8 placement ids per target name so the shared registry cannot climb back into multi-megabyte territory.
- **iPhone/iPad notification settings** now appear under Settings > Notifications after first open because the app requests authorization on launch instead of only when a notify-on-change alert fires.
### 2.0.5
#### CHANGED
- **--fit-text** scaling is skipped when any markdown link is present so link hit targets stay reliable.
- **iOS launcher buttons** mute `open-app` and `run-command` (unsupported) while `open-url`, `run-shortcut`, and `refresh` still work.
#### NEW
- **Markdown links** in widget text use CommonMark `[label](url)` syntax and render as tappable buttons on macOS and iOS.
- **Link taps** open the linked URL while non-link areas keep the existing widget tap/--action-kind behavior.
- **Launcher buttons** via JSON `buttons` (label, color, action-type, action-value; max 12) render as a tappable footer grid under any widget content on macOS and iOS.
- **button-columns** accepts `smart`/`auto` or `1`/`2`/`3` to force the footer grid; omit keeps the previous setting, and `"buttons": []` clears buttons.
- **Smart button layout** on medium/large uses 3 columns when the count is divisible by 3, otherwise 2, pads incomplete rows for uniform widths, and keeps small widgets single-column.
- **Button borders** support per-button `border` / `border-color` / `border-width` (0-12) / `border-radius` (0-48) plus root defaults via `button-border`, `button-border-color`, `button-border-width`, and `button-border-radius`.
- **Border shorthand** accepts values like `2px #0f0aff` (either order); color alone implies width 1, and omitted radius defaults to 8.
- **Button tap intents** ship for macOS and iOS so launcher actions run from the widget (host intents handle refresh/run-command).
#### IMPROVED
- **Buttons-only widgets** vertically center the button grid when there is no other content.
- **Edit Widget** shows only Target name and hides the internal Instance ID field.
#### FIXED
- **--json overlays** now persist text, colors, theme, and related fields instead of dropping them when only JSON supplied those values.
- **Inline --json '{...}'** is accepted as JSON instead of being treated as a missing file path.
- **URL and app opens** from widget buttons and markdown links stay on the Mac instead of Continuity-handing off to iPhone.
- **Edit Widget target names** (including `widget1`) are always honored instead of being remapped onto `widgetN` via the instance registry.
- **Instance registry repair** no longer wipes mappings just because many named CLI targets exist.
- **Mac widget gallery** shows "Terminal Widget" again so Desktop widgets are easier to find beside Continuity copies.
- **Invalid launcher icons** ASCII names that are not valid SF Symbols now leave the reserved gutter empty.
- **Widget taps without a configured action** on macOS now open the non-mutating action URL instead of update?target=, which was rebuilding an empty payload and blanking the widget.
- **Target-only update URLs** are ignored on macOS and iOS so stale widget timelines cannot wipe existing content.
### 2.0.3
2026-08-02 05:17
#### CHANGED
- **Chart hard max** keeps the newest 128 points instead of the oldest when series overflow.
#### NEW
- **--append** adds chart columns (same syntax as --chart, including slash-grouped series and rangebar low-high pairs) or text lines to an existing widget while preserving unrelated settings.
- **--limit N** keeps the newest N chart columns or text lines in storage, persists on the target, works with chart/text/append or alone, and uses 0 to clear the soft limit.
- **Append and limit** are available from CLI, AppleScript, Shortcuts, URL scheme, and structured JSON with shape checks for incompatible chart data.
## 2.0.2
#### CHANGED
- Allow user to disable iCloud entirely
## 2.0.1
#### IMPROVED
- The TerminalWidget iOS app adds an Updating widgets section that explains Shortcuts and the URL scheme on iPhone and iPad, notes that the Mac app and CLI are the most efficient way to control widgets, and links to terminalwidget.app/integrations.
- The iOS app help screen notes that notification permission is required so push can wake the app for iCloud sync when another device updates a widget.
## 1.2.1
#### NEW
- `--title` adds an optional single-line title at the top of chart, text, image, and progress widgets (inside padding, with main content height reduced accordingly); supported via URL `title`, Shortcuts, and AppleScript.
- `--title-color` sets the title color separately from `--foreground` (falls back to foreground/theme when omitted); URL key `titleColor`, Shortcuts, and AppleScript.
- `--timestamp` works on any widget type (text, image, table, etc.), not only charts and progress; the update time appears at the bottom when no chart/progress caption row already shows it.
- `--caption-text` sets custom footer text below widget content (replaces auto `[min/max]` or `[n%]` captions); implies `--caption` so both flags are not required. Supported via URL `captionText`, Shortcuts, AppleScript, and structured JSON.
- GitHub `:emoji:` shortcodes in `--title` and `--caption-text` expand the same way as `--text` and `--icon`.
- `--title-alignment` (`left`, `center`, `right`) controls horizontal alignment of the widget title (defaults to `center` when `--title` is set); supported via URL `titleAlignment`, Shortcuts, AppleScript, and structured JSON.
## 1.2.0
#### CHANGED
- Preserve and round-trip neo chart character settings in widget payloads so neo rendering stays consistent across updates and devices.
- Combining chart data with images is rejected from the CLI and automation (Shortcuts Update Widget and related flows); AppleScript dictionary notes that images omit chart data; terminalwidget URLs resolve chart-vs-image conflicts by dropping the conflicting side.
- Existing Shortcuts that used the free-text Action Kind field on Update Terminal Widget may need that parameter re-selected after upgrading.
- URL scheme handling accepts `fitText` and `fit-text` query keys as aliases for text full width alongside `textFullWidth` / `text-full-width`.
#### NEW
- Grouped sparkline/bar charts accept slash-separated value sets in `--chart` (for example `0 1 5 2/1 2 5 3`) with side-by-side sub-bars per column, shared Y scaling, default series opacity stepping, and comma-separated `--foreground` colors (first color for text/icons, full list for series). The same slash literal works in Shortcuts and AppleScript `chart` parameters; JSON chart input may use a nested numeric array (for example `[[0,1,5],[1,2,5]]`) which normalizes to the slash form for URLs and storage.
- Circle progress format supports `--chart-bar-style glass` for a gradient glass ring (CLI, URL, Shortcuts, and AppleScript via existing chart bar style).
- Add --base N and --base-zero so chart scaling can start from a fixed baseline instead of the series minimum.
- Add a neo chart format with selectable katakana, ascii, or binary characters across CLI, URL updates, AppleScript, and Shortcuts on macOS and iOS.
- Add --chart-height N[%] to CLI updates so chart widgets can be constrained by points or percent while keeping 100% as the default behavior.
- Add chart height support to URL updates, AppleScript commands/dictionary, and Shortcuts intents on macOS and iOS so automation can set chart size consistently.
- Add --bg-gradient-from, --bg-gradient-to, and --bg-gradient-start so widgets can render directional background gradients directly from the CLI.
- Add background gradient parameters to URL updates, AppleScript, and Shortcuts (macOS and iOS) so automation workflows can set gradient colors and direction consistently.
- Optional alpha in image filter specs; CLI expands tilde in local image paths and can hand off permission-restricted image files to the running app for import instead of failing silently; Show Chart shortcut intent exposes optional image path and filter when there is no chart.
- Shortcuts widget tap action kind is a fixed picker (Open URL, Open App, Run Shortcut, Run Shell Command) instead of typing raw strings; optional tap action kind, value, and clear action are available on Show Terminal Widget Text, Chart, Progress, Image, and Table intents on macOS and iOS, not only Update Terminal Widget.
- CLI `--fit-text` enables fitting text in text-only and text+icon layouts without enabling fill/full-width image behavior; AppleScript recognizes fit text / fit-text / fit-text as aliases for full-width-style fitting flags where mapped.
- Apple Watch app lists iCloud-synced widget targets, opens a square preview with back navigation and remembers the last viewed target across launches, merges quick text edits into existing CloudKit JSON without stripping chart or table fields, and handles terminalwidgetwatch:// deep links from the complication.
- Watch complication (accessory rectangular): CloudKit timelines with simplified chart or synced image preview, clear widget container background, one App Intent recommendation per known target (cached from the CloudKit index), no SF Symbol overlay, and plain text display with ANSI escape stripping.
- Structured JSON refresh overlay and shared chart literal parsing through macOS and iOS automation, the bundled CLI, Shortcuts, and AppleScript update flows.
- CLI and automation support for chart baseline (--base / --base-zero), neo chart character sets, chart height in points or percent, background gradient colors and direction, and fit-text for text layouts.
#### IMPROVED
- Show mirrored y-axis labels for waveform charts so symmetric top/bottom halves read consistently with --label-y.
- Support chart baseline values in AppleScript and Shortcuts chart updates for parity with CLI behavior.
- Update chart rendering for neo mode with direction-aware y-axis labels and full-height layout behavior to better fit widget families.
- Apply chart height constraints in macOS and iOS widget rendering so sparkline, graph, waveform, matrix, and rangebar charts respect explicit height overrides.
- Keep gradient rendering stable across partial updates by preserving gradient output when only one stop or direction is provided in a later update.
- IOS widget payloads decode background gradients and chart options (baseline, height, neo characters) from shared storage; CloudKit-driven payload merges accept newer widget revisions when sync metadata is stale.
- Bundled and app CLI default output stays quiet: stderr hints for empty `--command`, deferred `--image` import, App Group image fallback, and image copy diagnostics print only when `--verbose` is passed.
- MacOS and iOS widgets: text fitting uses a lower minimum scale, height-aware scaling with multiline no-wrap, and line caps that cooperate with text full width for ANSI and plain multiline content.
- Shortcuts widget tap action kind is a fixed picker across Update and Show intents; chart and image updates reject conflicting payloads with clearer behavior; default CLI output stays quieter with optional --verbose diagnostics for image and command edge cases.
- MacOS and iOS widgets honor chart height and baseline, preserve partial background gradients, improve waveform y-axis labeling, tighten text fitting for multiline ANSI, and fix full-width layouts for images and gradient progress bars.
#### FIXED
- Fall back to embedded base64 image data when App Group image copies fail, so --image updates can still succeed in restricted environments.
- Reject invalid chart height values and enforce that chart height can only be set when chart content is present, with clear validation errors.
- Fill missing background gradient stop colors from --bg (or theme defaults) so one-sided gradient updates do not collapse to solid backgrounds.
- MacOS and iOS widgets lay out gradient progress and fill-mode images across the full widget without leaving empty chart space above images; sparkline bar charts honor the payload chart baseline.
- Waveform charts honor optional chart baseline (`chartBase`) when normalizing bar heights on macOS and iOS widget extensions.
- Widget and CLI validation for chart height, base64 image fallback when App Group file copies fail, waveform scaling with chartBase, and several gradient or fill layout edge cases on macOS and iOS extensions.
## 1.1.5
#### NEW
- Add --base N and --base-zero so chart scaling can start from a fixed baseline instead of the series minimum.
- Add neo chart mode: a full-height cascading character-rain chart style for numeric series values.
- Add --neo-characters (katakana|ascii|binary) to control the character set used by neo charts.
#### IMPROVED
- Show mirrored y-axis labels for waveform charts so symmetric top/bottom halves read consistently with --label-y.
- Support chart baseline values in AppleScript and Shortcuts chart updates for parity with CLI behavior.
- Wire neo chart and --neo-characters through URL automation, AppleScript, and Shortcuts (macOS + iOS).
## 1.1.4
#### CHANGED
- Menu bar extra icon asset switched to MenuBarAppIconVector.pdf (Contents.json updated).
- Xcode icon catalog (terminalwidget3.icon/icon.json layer scale and translation tweaks; PNG sources refreshed).
#### IMPROVED
- The iOS app help screen notes that you can assign a widget tap action via Shortcuts, the URL scheme, or the TerminalWidget CLI on Mac.
- CloudKit pulls coalesce behind a single in-flight guard, a lightweight throttle for routine callers, forced pulls for startup, pushes, explicit URL sync requests, plus one queued follow-up when callers stack during an active fetch.
#### FIXED
- Tapping an iOS widget when no tap action is configured no longer wipes widget content because the tap URL always uses the non-mutating scheme host instead of falling through to update parsing.
- Medium and large iOS text widgets with an icon keep the icon and text grouped and centered together instead of pinning the icon on the left while only the text centers.
## 1.1.3
#### CHANGED
- Keep `--background COLOR` as the widget background color option while treating bare `--background` as background update mode.
- Update the TerminalWidget app icon artwork used by the macOS, iOS, and watchOS app targets.
- Refreshed the terminalwidget3 app icon asset.
- Bundled/hosted CLI: default zebra opacity documentation and parsing match 0.24; clearer stdin behavior when combining tables with implicit piped text and explicit --text.
#### NEW
- Improved dropdown menu on macOS and app screen on iOS
- Add bare `--background` and `--background-mode` CLI options for prompt hooks that update widgets without launching TerminalWidget or opening the refresh URL.
- Optional notify-on-change on widget payloads (synced); local Notification Center alerts when display content changes after CLI, URL, Shortcuts, AppleScript, or CloudKit pull on macOS and iOS.
- CLI and standalone CLI package: --notify, --no-notify, and --notify-once after widget updates when content changed.
- AppleScript and Shortcuts (macOS and mobile): persistent notify, notify-once, and sdef parameters for render widget and convenience commands.
- Widgets can store a tap/click action per target and route configured taps through Terminal Widget while preserving the existing update/open behavior when no action is set.
- MacOS widget actions can open URLs, run Shortcuts, launch apps by bundle identifier, or run shell commands through Terminal Widget.
- IOS widget actions can open URLs and run Shortcuts; synced macOS-only app and shell actions fall back to the normal widget open/update behavior instead of no-op taps.
- CLI and standalone CLI package: --action-kind, --action-value, --tap-action, --tap-action-value, and --clear-action configure or remove persisted widget actions.
- AppleScript and Shortcuts on macOS and iOS can configure or clear widget actions through the same update pipeline.
- Adds a rangebar chart format for macOS and iOS widgets, drawing each data item as a contiguous low-high bar from values like "1-3,2-3,1-4".
- CLI, URL automation, AppleScript, and Shortcuts can create rangebar charts and preserve range data in widget payloads.
- Optional glass-style bar and heatmap fills for supported chart types (sparkline, waveform, matrix, rangebar, delta), exposed via --chart-bar-style, URL chartBarStyle, AppleScript, Shortcuts, and the AppleScript dictionary on macOS and iOS.
- Separate colors for main widget text vs chart/progress captions and timestamps (--text-color, --caption-color, matching URL keys and automation).
- Optional last-update time shown below captions when timestamp is enabled, driven by a stored update time on each successful widget apply.
#### IMPROVED
- Rangebar charts expand to fill available vertical space on medium and large widgets while still supporting captions, annotation, icons, and Y-axis labels.
- The documentation site can show a docked table of contents on long pages, including the CLI page.
- URL and CLI alpha now also scales opacity for text and caption colors when those colors are set.
- Chart glass fills use a stronger vertical gradient and outer rim so glass reads clearly versus solid fills on small widgets.
- Glass bars add an inset inner stroke (translucent white toward top-leading, soft dark toward bottom-trailing) a few points inside the pill for a reflective glazed edge like glossy UI references.
- Default table zebra striping is lighter (CLI and widgets default to 0.24 unless --zebra-opacity overrides).
- Vertical gradient progress moves the "[n%]" caption below the bar when the bar is too narrow so it does not wrap one character per line.
- Sync-debug-app.sh caps pluginkit, mdfind, and lsregister work during --deep-refresh so stale LaunchServices cleanup cannot hang indefinitely.
- IOS widget payload model carries tableGridMode, tableLayout, and tableZebraOpacity like the desktop payload.
- Menu bar extra icon uses the vector MenuBarAppIcon asset at a slightly larger template frame.
#### FIXED
- Cold TerminalWidget launches from the CLI now use `open -g` so updates do not steal focus from Terminal or hide visor-style terminals.
- Terminal-widget and non-app CLI no longer crash with --notify (UserNotifications when running inside a .app bundle; AppleScript display notification fallback when main bundle is not available).
- Bar glass style is preserved when follow-up URLs update the chart but omit chartBarStyle, so configured glass no longer briefly appears then reverts to solid.
- Range bar glass mode draws with Canvas plus the same liquid-glass helper as the waveform chart so WidgetKit snapshots show gradients and bezel instead of flattening layered SwiftUI fills to a flat color.
- Range bar (and other charts combined with title text) no longer take the text-only layout branch, so range bars and glass styling render under the headline like on macOS.
- ANSI-colored text in widgets no longer has the widget tint forced over escape-sequence colors, and reset segments use the normal text color again.
- ANSI background colors (SGR 40-47 / 100-107) render reliably on iOS widgets by compositing segments with SwiftUI backgrounds where AttributedString background colors are ignored.
## 1.1.2
#### NEW
- Improved dropdown menu on macOS and app screen on iOS
## 1.1.1
#### FIXED
- Allow `--text -` with no piped input to clear widget text instead of failing with a stdin error.
## 1.0.0
#### CHANGED
- Replace the repo-root `terminal-widget` bash/Python script with a small launcher that runs the embedded app binary, a local SwiftPM build, or respects `TERMINAL_WIDGET_CLI`.
- Sparkline rendering and icon/sparkline layout are more consistent in desktop widgets.
- Sparkline visuals no longer draw the rounded background or outline, showing bars only.
- Removed the bottom-right widget target indicator from the widget UI.
- Removed experimental polling options after unreliable update behavior in real use.
- CLI status output is now quiet by default and only prints detailed update/debug information when `--verbose` is set.
- Updated macOS and iOS widget rendering to support full-width image mode while keeping default image fit behavior when the flag is omitted.
- Changed image fill semantics from --full-width to --padding fill for clearer, mode-based image layout control.
- Updated macOS and iOS widget rendering to use the new image fill mode flag while preserving default fit behavior when fill is not enabled.
- CLI validation now enforces chart context for --caption so the flag is only used with --sparkline or --matrix.
- Expanded chart format parsing to accept waveform/wave while preserving existing sparkline, graph, and matrix aliases.
- Split smooth and sine behavior so smooth keeps curve smoothing while sine uses half-sine interpolation between points.
- Removed in-app privileged install buttons and moved system-path install flow to Terminal-driven sudo execution.
- Matrix progress now uses a 9-column layout for more consistent completion behavior.
- Refine matrix/dots progress and chart layout alignment so captions and grids render more consistently across widget families.
- Progress updates now preserve gradient settings in payload and URL updates, with defaults that fall back to foreground color when explicit gradient colors are omitted.
- Added `--grid` modes (`none`, `row`/`horizontal`, `column`/`vertical`, `both`, `zebra`, `zebra-row`, `zebra-column`) and made header separators always render under header rows.
- Gradient progress bars now always render with rounded corners in both macOS and mobile widget extensions.
- Updated CLI usage and validation so filter and table formatting options are explicitly documented and normalized.
- Full-width text rendering now adapts alignment per payload content on both macOS and iOS widgets while preserving centered layout for regular text.
- AppleScript automation commands now use parser-safe `render ...` verbs (`render widget`, `render text`, `render chart`, `render progress`, `render image`, `render table`) so scripts compile reliably.
- AppleScript `render image` convenience command now supports `full width` and `padding` options for layout control parity with broader widget updates.
- AppleScript `render progress` convenience command now accepts `foreground` and `background` color parameters for colorized progress updates.
- Shortcuts convenience actions for text, progress, image, and table now expose padding, full width, and fullsize controls in the action UI.
- Automation text updates now expand GitHub-style `:emoji:` shortcodes (for example `:rocket:`) consistently outside the standalone CLI path.
- CLI execution now routes through the main TerminalWidget app binary, including updated launcher path guidance for /Applications and ~/Applications installs.
- CLI text, icon, and table content now support GitHub-style :emoji: shortcodes such as :rocket: and :+1:.
- Refresh macOS, menu bar, and iOS app icon assets.
#### NEW
- Ship a Swift `terminal-widget` Mach-O binary built via SwiftPM and embedded in the app bundle so users do not need Python or other scripting runtimes for the helper.
- Widget progress bar (0-100) and min-max bar sparkline from payload; CLI --progress and --sparkline/--spark (comma or space separated values, up to 128 points).
- Terminalwidget://update URLs accept progress= and sparkline= query parameters alongside existing fields.
- --image now accepts remote http(s) URLs in addition to local file paths so API-generated images can be displayed directly.
- Added --padding N and --fullsize flags to control widget content inset, including edge-to-edge image layouts.
- Added --font "FONT NAME" to set widget text to an installed system font for a target.
- Added --mode as an alias for --theme so dark/light/system overrides can be set with either flag.
- Added --padding N and --fullsize controls for per-widget content inset, including edge-to-edge image layouts.
- --image accepts remote http(s) URLs as well as local file paths for API-generated images.
- Added --foreground/--fg and --background/--bg with support for RRGGBB, #RRGGBB, rgb(...), and rgba(...) color formats.
- Added --alpha to override foreground/background transparency per update.
- Added --font "FONT NAME" support for text rendering with installed system fonts.
- Added --poll MINUTES to refresh a target automatically while the app is running, with support for command or image poll sources.
- Added polling stop controls via --poll 0/false/off and --clear for per-target disable.
- Added --clear to reset widget content and styling fields for a target in one command.
- Added a matrix heatmap chart mode that can render numeric series in the widget alongside existing icon and image layouts.
- Added iPhone and iPad app/widget support with shared target-based widget updates.
- Added mobile App Intent configuration so iOS/iPadOS widgets can pick and render synced targets.
- Added --full-width for --image to fill widget width and crop vertically like Photos-style widgets.
- Added --caption mode for sparkline and matrix updates to show a centered [min/max] label below the chart.
- Added waveform chart support for serial numeric data with centered mirrored bars and interpolation between values for a denser visual style.
- Added chart formats for area, lollipop, strip/dot, radial, delta, threshold, smooth, sine, and peak to visualize serial numeric data in multiple styles.
- Added a Run in Terminal action next to Copy sudo command to open Terminal and prefill the install command automatically.
- Added --progress-format bar|matrix so progress can render as a 10x4 matrix with fractional lower-row opacity and foreground color styling.
- Added a centered [NN%] caption for matrix progress when --caption is used.
- Added a watchOS companion app and watch complication so you can browse targets and push quick text updates from Apple Watch.
- --caption now works with standard progress bars and shows a right-aligned [NN%] label inline with the bar.
- Add --font-size and full-width text scaling for text-only and text+icon layouts when using --padding fill/--full-width, while keeping --image fill behavior unchanged.
- Add dots as a supported --progress-format across CLI, macOS widgets, and iOS widgets.
- Add watch complication target selection backed by CloudKit target discovery, with target-aware payload rendering in inline/circular/rectangular families.
- Added a stack progress format that renders 10 full-width horizontal bars and fills bottom-up using 10 opacity levels per bar.
- Added gradient progress modes: gradient (alias), gradient-horizontal, and gradient-vertical for macOS and iOS widgets.
- Added --gradient-from, --gradient-to, and --gradient-width so gradient colors and bar thickness can be controlled from the CLI.
- Added `--table` support for CSV, TSV, and JSON sources from files or stdin with automatic format detection.
- Added a dedicated table renderer in macOS widgets with header support, status coloring, and content-measured column sizing.
- Added GitHub emoji shortcode expansion for `--icon`, `--text`, and table cell values so shortcodes like `:x:` render as emoji.
- Added built-in image filters for widgets (`grayscale`, `sepia`, `negative`, `pixelate`, `blur`) via `--filter`.
- Added table layout and zebra tuning controls with `--table-layout auto|equal` and `--zebra-opacity`.
- Added a "CLI docs" action to the menu bar app menu that opens https://terminalwidget.app/cli.
- Added a matching "CLI docs" action to the setup/install window so help is available during onboarding.
- Add iOS Shortcuts actions for updating widgets with text, charts, progress, images, and tables.
- Add GitHub emoji shortcode expansion for automated text updates.
- Add automation support for no-wrap text, ANSI rendering modes, stripping ANSI colors, and sparkline bar radius.
#### IMPROVED
- Widget refresh behavior with a shorter timeline fallback, tighter staggered `WidgetCenter` retries, and applying custom-scheme URLs on the main thread immediately when already there.
- Load payload from App Group JSON with an optional UserDefaults mirror and pick the newest revision; mirror defaults when reloading from disk from the host app.
- Expose a stable App Group container path for the unsandboxed CLI so it writes the same JSON the app and widget read.
- CLI output: manual test URL includes progress and sparkline when set; prints sparkline value count or cleared when --sparkline is used.
- CLI and widget payload rules for icon-only vs text, progress, sparkline, and image updates (omit flags to clear bars and sparkline where documented).
- Widget refresh behavior is more reliable with real timeline timestamps and automatic compaction of oversized instance registry data.
- Custom font selection now resolves common family/display/PostScript names more reliably instead of silently falling back.
- Fullsize image mode now reaches true edge-to-edge by disabling WidgetKit content margins and using low-radius corners for flush images.
- Poll settings are persisted and restored per target while the app remains active, without requiring external services.
- Appearance controls remain available and stable, including font and color customization support.
- Added `--matrix` support in the CLI so matrix values can be sent directly to the widget payload.
- Added stdin dash-input support for `--text`, `--sparkline`, and `--matrix`, plus piped-stdin fallback to text when no explicit stdin flag is used.
- Expanded iCloud payload sync between macOS and iOS with source-device tracking, pull/push diagnostics, and retry queue behavior.
- Kept --full-width as a compatibility alias so existing scripts continue to work while migrating to --padding fill.
- Fill mode is now orientation-aware: portrait images fill width and crop height, while landscape and panorama images fill height and crop width.
- Chart captions are now rendered consistently on both macOS and iOS widgets with compact numeric formatting for integer and decimal series.
- Chart payload parsing and rendering now stay in sync across macOS and iOS targets, including caption behavior for all chart modes.
- Icon-only widgets now scale symbols to fill available vertical space inside the current padding on macOS and iOS.
- Added --annotate labels for sparkline, graph, and waveform chart formats.
- IOS widget updates now refresh more reliably after payload writes and preserve current rendering state.
- Matrix progress now scales to fill available widget space so squares grow in wider widget layouts.
- Improve watch cloud diagnostics with clearer iCloud/capability error messages and add an in-app watch payload preview section.
- Dots progress now keeps previously filled dots in place between updates so increasing progress adds dots and decreasing progress removes dots without reshuffling.
- IOS widget timeline loading now prefers newer cloud payload revisions and persists refreshed payload data for more reliable cross-device updates.
- Gradient progress now supports caption overlays with automatic contrast-aware text color for better readability.
- Added iOS URL sync support for base64 `tablePayload` updates, including clamping and table/chart mode coordination.
- Updated icon rendering on macOS and iOS to gracefully handle both SF Symbols and literal emoji text.
- Gradient progress now places its midpoint at 20% of the remaining range from the progress start, making the active color more readable.
- Filter chaining now works in order with repeated `--filter` flags and comma-separated lists like `--filter "sepia:20,blur:10"`.
- Multiline widget text now automatically left-aligns when lines start with spaces or tabs, so ASCII art and preformatted terminal output keep their intended shape instead of being centered.
- AppleScript image path handling now normalizes alias-style and URL-style inputs and uses a copy fallback path so valid images render consistently in widgets.
- Shortcuts action discovery is more reliable by using a non-empty app display name and refreshing app shortcut parameters on app launch.
- CLI payload writes now prefer the real App Group container when available, improving update reliability from the app-bundled executable.
- Bring AppleScript, Shortcuts, and CLI update options closer to parity across text, chart, progress, image, and table widgets.
- Render ANSI foreground/background color sequences in widget text while allowing callers to force ANSI on, off, or stripped.
- Improve sparkline widgets with configurable bar corner radius.
- Declare the macOS app's App Store category as Productivity.
#### FIXED
- Stop the desktop widget from updating tens of seconds or minutes after the menu bar already showed new text by posting a Darwin notification after payload writes and reloading timelines from the widget extension process (avoids WidgetKit throttling `WidgetCenter` reloads from the LSUIElement host).
- Handle `terminalwidget:///update?sync=1` by reloading from disk so URL-based refresh does not merge stale in-memory state over fresh CLI writes.
- Prevent a crash when the "Set up terminal-widget" / Install CLI tool window opens by disabling NSHostingView-driven window min/max sync, using a fixed content width, and setting explicit window content size limits so AppKit's constraint update cycle no longer throws during display.
- Install to system PATH from the app now triggers the admin password dialog instead of failing immediately with a permissions error.
- Widget instances keep stable target names instead of drifting into high widget numbers, so --target updates the expected widget again.
- Renaming a widget target now updates the stock demo command text to the new --target value.
- Widgets recover cleanly after payload files are deleted by recreating missing payload JSON and avoiding stale mirrored fallback content.
- Progress-only widgets are vertically centered instead of sticking to the top.
- Text-only and text-plus-progress layouts now remain vertically centered consistently with other widget content combinations.
- Running terminal-widget now fully replaces widget content with only the flags provided, so stale images/icons no longer persist when omitted.
- Text-only, progress-only, and mixed text/progress layouts are consistently vertically centered.
- Fullsize image rendering now reaches widget edges by disabling WidgetKit content margins, while preserving low-radius corners for flush images.
- CLI updates now replace prior content state, clearing stale fields such as image/icon/padding/font when omitted from a command.
- Custom fonts now resolve more reliably from common installed font names (family/display/PostScript matches) instead of silently falling back.
- Text-only, progress-only, and mixed text/progress combinations stay vertically centered.
- CLI updates now fully replace prior widget content, clearing stale image/icon/padding/font/color state when those flags are omitted.
- CLI now validates poll usage so --poll requires either --command or --image as the refresh source.
- Widget update flow remains immediate and reliable without background polling side effects.
- Added argument validation errors for conflicting chart modes and conflicting stdin dash usage to prevent ambiguous command behavior.
- Local --image updates now sync across devices by embedding a scaled image payload that each device decodes into local widget image storage.
- Restored reliable Xcode scheme behavior by adding shared schemes so the app and widget extension can be rebuilt and run consistently.
- Updated CLI install AppleScript success handling to avoid false warning behavior with newer NSAppleScript APIs.
- Commands now write a fresh payload each time so unspecified fields are cleared and old chart/text/image content never leaks into later updates.
- Improved Terminal launch reliability by explicitly opening/activating Terminal and retrying command injection during startup.
- --full-width now implies zero padding so image fill mode behaves as edge-to-edge by default.
- Explicit widget target names are now preserved more reliably instead of being remapped to stale widgetN slots.
- Matrix progress now fills the active 10s column correctly for 1-9 remainder values instead of spilling into the next column.
- Matrix progress now pre-fills prior lower-row columns consistently so values like 57% render with the expected solid and partial blocks.
- Matrix progress now renders 100% as fully completed, with lower rows darkening to match the top-row fill color.
- Watch app and complication bundle IDs now align with the iOS companion app prefix requirements so watch simulator installs succeed.
- Progress format parsing and payload handling now accept stack consistently across CLI and URL-driven updates on macOS and iOS.
- Full-width text scaling now keeps a built-in 10pt inset so text does not render edge-to-edge when using padding fill mode.
- Gradient bars now render with a 6px corner radius when constrained by --gradient-width, while full-bleed gradients stay square.
- Prevented filtered images from going blank by hardening widget-side Core Image rendering for large inputs.
- AppleScript scripting metadata now registers correctly so TerminalWidget appears as a usable dictionary in Script Editor instead of reporting a corrupted dictionary.
- AppleScript `render image` now accepts direct file arguments (including `POSIX file`) and named image/path values more reliably instead of failing or silently dropping the image update.
- Shortcuts `Update TerminalWidget` now accepts icon-only updates instead of requiring text, chart, progress, image, or table content.
- Embedded CLI signing now uses the app's code-sign identity with hardened runtime so notarization checks pass for nested binaries.
- Running terminal-widget with no flags now exits with clear guidance instead of unintentionally launching duplicate app instances when TerminalWidget is already running.
- Fix iOS widget updates so the app and widget extension apply fresh CloudKit payloads instead of letting stale local files block newer remote content.
- Fix iOS CloudKit push handling so sync can run before SwiftUI views appear.
- Fix macOS CLI update handoff so command-line writes notify the app through SIGUSR1 and the URL scheme, with permission warnings suppressed.
- Allow `--text -` to accept empty or whitespace-only piped input so the widget text can be cleared while preserving specified options such as background color.
# TerminalWidget
## 1.0
#### CHANGED
- Replace the repo-root `terminal-widget` bash/Python script with a small launcher that runs the embedded app binary, a local SwiftPM build, or respects `TERMINAL_WIDGET_CLI`.
- Sparkline rendering and icon/sparkline layout are more consistent in desktop widgets.
- Sparkline visuals no longer draw the rounded background or outline, showing bars only.
- Removed the bottom-right widget target indicator from the widget UI.
- Removed experimental polling options after unreliable update behavior in real use.
- CLI status output is now quiet by default and only prints detailed update/debug information when `--verbose` is set.
- Updated macOS and iOS widget rendering to support full-width image mode while keeping default image fit behavior when the flag is omitted.
- Changed image fill semantics from --full-width to --padding fill for clearer, mode-based image layout control.
- Updated macOS and iOS widget rendering to use the new image fill mode flag while preserving default fit behavior when fill is not enabled.
- CLI validation now enforces chart context for --caption so the flag is only used with --sparkline or --matrix.
- Expanded chart format parsing to accept waveform/wave while preserving existing sparkline, graph, and matrix aliases.
- Split smooth and sine behavior so smooth keeps curve smoothing while sine uses half-sine interpolation between points.
- Removed in-app privileged install buttons and moved system-path install flow to Terminal-driven sudo execution.
#### NEW
- Ship a Swift `terminal-widget` Mach-O binary built via SwiftPM and embedded in the app bundle so users do not need Python or other scripting runtimes for the helper.
- Added first-party AppleScript automation (`render widget` and convenience `render ...` commands) with full update-parameter coverage and `annotation true` support parity with CLI behavior.
- Added Shortcuts App Intent automation actions (`Update TerminalWidget` plus convenience actions) with parity mapping for annotation/caption/label toggles.
- Widget progress bar (0-100) and min-max bar sparkline from payload; CLI --progress and --sparkline/--spark (comma or space separated values, up to 128 points).
- Terminalwidget://update URLs accept progress= and sparkline= query parameters alongside existing fields.
- --image now accepts remote http(s) URLs in addition to local file paths so API-generated images can be displayed directly.
- Added --padding N and --fullsize flags to control widget content inset, including edge-to-edge image layouts.
- Added --font "FONT NAME" to set widget text to an installed system font for a target.
- Added --mode as an alias for --theme so dark/light/system overrides can be set with either flag.
- Added --padding N and --fullsize controls for per-widget content inset, including edge-to-edge image layouts.
- --image accepts remote http(s) URLs as well as local file paths for API-generated images.
- Added --foreground/--fg and --background/--bg with support for RRGGBB, #RRGGBB, rgb(...), and rgba(...) color formats.
- Added --alpha to override foreground/background transparency per update.
- Added --font "FONT NAME" support for text rendering with installed system fonts.
- Added --poll MINUTES to refresh a target automatically while the app is running, with support for command or image poll sources.
- Added polling stop controls via --poll 0/false/off and --clear for per-target disable.
- Added --clear to reset widget content and styling fields for a target in one command.
- Added a matrix heatmap chart mode that can render numeric series in the widget alongside existing icon and image layouts.
- Added iPhone and iPad app/widget support with shared target-based widget updates.
- Added mobile App Intent configuration so iOS/iPadOS widgets can pick and render synced targets.
- Added --full-width for --image to fill widget width and crop vertically like Photos-style widgets.
- Added --caption mode for sparkline and matrix updates to show a centered [min/max] label below the chart.
- Added waveform chart support for serial numeric data with centered mirrored bars and interpolation between values for a denser visual style.
- Added chart formats for area, lollipop, strip/dot, radial, delta, threshold, smooth, sine, and peak to visualize serial numeric data in multiple styles.
- Added a Run in Terminal action next to Copy sudo command to open Terminal and prefill the install command automatically.
#### IMPROVED
- Updated README automation docs with AppleScript and Shortcuts examples, including `annotation true` usage and parity guidance between automation and CLI surfaces.
- Widget refresh behavior with a shorter timeline fallback, tighter staggered `WidgetCenter` retries, and applying custom-scheme URLs on the main thread immediately when already there.
- Load payload from App Group JSON with an optional UserDefaults mirror and pick the newest revision; mirror defaults when reloading from disk from the host app.
- Expose a stable App Group container path for the unsandboxed CLI so it writes the same JSON the app and widget read.
- CLI output: manual test URL includes progress and sparkline when set; prints sparkline value count or cleared when --sparkline is used.
- CLI and widget payload rules for icon-only vs text, progress, sparkline, and image updates (omit flags to clear bars and sparkline where documented).
- Widget refresh behavior is more reliable with real timeline timestamps and automatic compaction of oversized instance registry data.
- Custom font selection now resolves common family/display/PostScript names more reliably instead of silently falling back.
- Fullsize image mode now reaches true edge-to-edge by disabling WidgetKit content margins and using low-radius corners for flush images.
- Poll settings are persisted and restored per target while the app remains active, without requiring external services.
- Appearance controls remain available and stable, including font and color customization support.
- Added `--matrix` support in the CLI so matrix values can be sent directly to the widget payload.
- Added stdin dash-input support for `--text`, `--sparkline`, and `--matrix`, plus piped-stdin fallback to text when no explicit stdin flag is used.
- Expanded iCloud payload sync between macOS and iOS with source-device tracking, pull/push diagnostics, and retry queue behavior.
- Kept --full-width as a compatibility alias so existing scripts continue to work while migrating to --padding fill.
- Fill mode is now orientation-aware: portrait images fill width and crop height, while landscape and panorama images fill height and crop width.
- Chart captions are now rendered consistently on both macOS and iOS widgets with compact numeric formatting for integer and decimal series.
- Chart payload parsing and rendering now stay in sync across macOS and iOS targets, including caption behavior for all chart modes.
- Icon-only widgets now scale symbols to fill available vertical space inside the current padding on macOS and iOS.
#### FIXED
- Stop the desktop widget from updating tens of seconds or minutes after the menu bar already showed new text by posting a Darwin notification after payload writes and reloading timelines from the widget extension process (avoids WidgetKit throttling `WidgetCenter` reloads from the LSUIElement host).
- Handle `terminalwidget:///update?sync=1` by reloading from disk so URL-based refresh does not merge stale in-memory state over fresh CLI writes.
- Prevent a crash when the "Set up terminal-widget" / Install CLI tool window opens by disabling NSHostingView-driven window min/max sync, using a fixed content width, and setting explicit window content size limits so AppKit's constraint update cycle no longer throws during display.
- Install to system PATH from the app now triggers the admin password dialog instead of failing immediately with a permissions error.
- Widget instances keep stable target names instead of drifting into high widget numbers, so --target updates the expected widget again.
- Renaming a widget target now updates the stock demo command text to the new --target value.
- Widgets recover cleanly after payload files are deleted by recreating missing payload JSON and avoiding stale mirrored fallback content.
- Progress-only widgets are vertically centered instead of sticking to the top.
- Text-only and text-plus-progress layouts now remain vertically centered consistently with other widget content combinations.
- Running terminal-widget now fully replaces widget content with only the flags provided, so stale images/icons no longer persist when omitted.
- Text-only, progress-only, and mixed text/progress layouts are consistently vertically centered.
- Fullsize image rendering now reaches widget edges by disabling WidgetKit content margins, while preserving low-radius corners for flush images.
- CLI updates now replace prior content state, clearing stale fields such as image/icon/padding/font when omitted from a command.
- Custom fonts now resolve more reliably from common installed font names (family/display/PostScript matches) instead of silently falling back.
- Text-only, progress-only, and mixed text/progress combinations stay vertically centered.
- CLI updates now fully replace prior widget content, clearing stale image/icon/padding/font/color state when those flags are omitted.
- CLI now validates poll usage so --poll requires either --command or --image as the refresh source.
- Widget update flow remains immediate and reliable without background polling side effects.
- Added argument validation errors for conflicting chart modes and conflicting stdin dash usage to prevent ambiguous command behavior.
- Local --image updates now sync across devices by embedding a scaled image payload that each device decodes into local widget image storage.
- Restored reliable Xcode scheme behavior by adding shared schemes so the app and widget extension can be rebuilt and run consistently.
- Updated CLI install AppleScript success handling to avoid false warning behavior with newer NSAppleScript APIs.
- Commands now write a fresh payload each time so unspecified fields are cleared and old chart/text/image content never leaks into later updates.
- Improved Terminal launch reliability by explicitly opening/activating Terminal and retrying command injection during startup.
- --full-width now implies zero padding so image fill mode behaves as edge-to-edge by default.
---
## Optional: Support
Source: https://terminalwidget.app/support.md
# Support
> Support options for TerminalWidget.
Source: https://terminalwidget.app/support
Need help with TerminalWidget?
**Post an issue on GitHub** — the preferred way to request support. Issues are public, so others with the same question can find answers, and they help us track bugs and feature requests.
[Open a GitHub issue](https://github.com/ttscoff/terminalwidget/issues)
Prefer email? Contact Brett directly at [tw@brettterpstra.com](mailto:tw@brettterpstra.com?subject=Terminal%20Widget%20Support%20Request).
## iOS and iPadOS setup
After installing TerminalWidget on iPhone or iPad:
1. Open the TerminalWidget app at least once. Allow notifications when prompted — iOS only lists TerminalWidget under **Settings > Notifications** after that prompt. The app uses push to wake for iCloud pulls when another device updates a widget; without permission, widgets may not refresh until you open the app manually.
2. **Manually add** a TerminalWidget widget to the Home Screen, then set **Edit Widget → Target name** to match the widget ID you update from your Mac, Shortcuts, or URL scheme. Full steps: [Integrations → Getting Started](https://terminalwidget.app/integrations.md#getting-started).
3. If you need to change notification settings later, open **Settings > Notifications > TerminalWidget** (or **Settings > Apps > TerminalWidget**). If the app is missing from that list, open TerminalWidget once more and accept the permission prompt.
4. Confirm you are signed into iCloud on the device with the same Apple ID used on your Mac.
Single-device use without iCloud: on Mac, open the menu bar app → Info/Debug and turn off **Sync with iCloud**. On iPhone, open TerminalWidget → Info/Debug and turn off the same toggle. Local CLI, Shortcuts, and URL updates keep working; Mac ↔ iPhone ↔ Watch sync stops until you turn it back on.
If widgets still look stale, open TerminalWidget, tap the menu, choose **Refresh**, then open **Info/Debug** and check **Last pull** under Cloud sync. A successful pull updates that timestamp.
## Diagnosing silent failures
When a launcher button, image, or update fails without an on-widget error:
**Mac**
1. Open the menu bar app → **Info/Debug** and scroll to **Recent events**.
2. Or run `terminal-widget log --level warn` from a terminal.
3. Or add a widget whose **Target name** is `twdiags` to watch the same history on the Desktop.
**iPhone and iPad**
1. Add a TerminalWidget to the Home Screen and set **Edit Widget → Target name** to `twdiags`.
2. Trigger the failing update again (Shortcut, URL scheme, button tap, etc.) and wait for the widget to refresh.
3. Read the event lines on the widget. There is no Info/Debug panel and no `terminal-widget log` on device.
The diagnostics log is **device-local**: a `twdiags` widget on your phone shows iOS events only (Shortcuts/URL updates, CloudKit, button actions, images, reload/timeline pairing). Mac CLI and menu-bar events appear only on Mac.
Full details: [CLI → Diagnostics](https://terminalwidget.app/cli.md#diagnostics).
Notify-on-change alerts (from `--notify`, URL `notify=1`, or Shortcuts) also require notification permission on iOS and iPadOS.
---
## Optional: Privacy Policy
Source: https://terminalwidget.app/privacy.md
# Privacy Policy
> Privacy policy for TerminalWidget.
Source: https://terminalwidget.app/privacy
TerminalWidget does not collect, transmit, or store any personal information.
The app does not use analytics, tracking pixels, ad networks, third-party telemetry, or remote data collection services. Any data shown in widgets is generated from your own commands, scripts, and sources on your device.
---
## Optional: End User License Agreement (EULA)
Source: https://terminalwidget.app/legal.md
# End User License Agreement (EULA)
> Legal terms for TerminalWidget.
Source: https://terminalwidget.app/legal
This End User License Agreement ("Agreement") is between you and the developer of TerminalWidget ("Licensor") and governs your use of the TerminalWidget application ("App").
By installing or using the App, you agree to this Agreement.
1. **License Grant**
Licensor grants you a personal, non-exclusive, non-transferable, revocable license to use the App on Apple-branded devices you own or control, subject to the App Store Terms of Service.
2. **Restrictions**
You may not copy, modify, distribute, sell, lease, sublicense, reverse engineer, decompile, or disassemble the App except as allowed by applicable law.
3. **Ownership**
The App, including all intellectual property rights, remains the property of Licensor.
4. **No Warranty**
The App is provided "as is" and "as available" without warranties of any kind, express or implied, including merchantability, fitness for a particular purpose, and non-infringement.
5. **Limitation of Liability**
To the maximum extent permitted by law, Licensor is not liable for any indirect, incidental, special, consequential, or punitive damages, or any loss of data, profits, or business arising from your use of the App.
6. **Termination**
This Agreement is effective until terminated. Your rights terminate automatically if you fail to comply with this Agreement.
7. **Governing Law**
This Agreement is governed by applicable laws in Licensor's jurisdiction, excluding conflict of law principles.
8. **Contact**
For legal questions, contact: [tw@brettterpstra.com](mailto:tw@brettterpstra.com)
---
## Optional: Assets
Source: https://terminalwidget.app/assets.md
# Assets
> Public asset downloads for TerminalWidget.
Source: https://terminalwidget.app/assets
- [Downloads](https://terminalwidget.app/assets/downloads/)