Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
747dec2
chore(ledger): config TUI decisions
NovusEdge Oct 7, 2026
20e335c
chore(ledger): config TUI revised after spec review
NovusEdge Oct 7, 2026
ff18fce
chore(ledger): detached terminal launch probe
NovusEdge Oct 7, 2026
d6dbf65
feat(installer): the config TUI's run directory protocol
NovusEdge Oct 7, 2026
82500c5
feat(installer): config TUI rows and keys
NovusEdge Oct 7, 2026
e265f55
feat(host): stat and a run timeout; the test kit lists folders
NovusEdge Oct 7, 2026
50988c0
feat(installer): the config TUI's screen
NovusEdge Oct 7, 2026
a8cb476
feat(installer): glowup-installer config
NovusEdge Oct 7, 2026
e7c6321
feat(remote): the config TUI's command allowlist and line reader
NovusEdge Oct 7, 2026
68972a2
feat(launch): pick a terminal, detach it, fetch the installer binary
NovusEdge Oct 7, 2026
0e776ee
feat(remote): runs, undo points and the state snapshot
NovusEdge Oct 7, 2026
1aabdc4
fix(installer): config TUI review fixes
NovusEdge Oct 7, 2026
561914d
Merge branch 'feat/config-tui-go' into feat/config-tui
NovusEdge Oct 7, 2026
b7abd45
feat(config): /glowup config opens the config TUI in a terminal
NovusEdge Oct 7, 2026
b601695
docs: the config TUI
NovusEdge Oct 7, 2026
0dddb3e
fix(config): launch and run-folder review fixes
NovusEdge Oct 7, 2026
29ff3cf
chore(ledger): config TUI default terminal and Windows decisions
NovusEdge Oct 7, 2026
445e80c
fix(config): a closed TUI no longer blocks the next /glowup config
NovusEdge Oct 8, 2026
af5901b
feat(config): /glowup config on native Windows
NovusEdge Oct 8, 2026
b01ff0d
feat(tui): PreviewAt draws the preview at any width, and ClawdColumnI…
NovusEdge Oct 8, 2026
009d8aa
feat(config): restyle the config TUI after stoat and the site
NovusEdge Oct 8, 2026
9cdfc6e
fix(config): Esc undoes motion, the poll drains a quit TUI's last lin…
NovusEdge Oct 8, 2026
8cdcd91
fix(config): closing the window frees the run, the bubble tail follow…
NovusEdge Oct 8, 2026
0a9dca7
docs(config): README, terminal list and CHANGELOG match the code
NovusEdge Oct 8, 2026
845a6d7
chore(ledger): config TUI live-check claim and the open Windows launc…
NovusEdge Oct 8, 2026
5741f9a
test(config): find the plugin root from the test file, not a home path
NovusEdge Oct 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .docket/ledger.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,15 @@
{"schema":3,"kind":"decision","id":"d89","text":"A refresh that finds new counts for a file touches it again.","state":"adopted","ts":"2026-10-07T13:17:02+00:00","author":"claude-code","session":"","branch":"feat/pane-and-hints","scope":["hooks/changes.ts","hooks/model.ts"],"rationale":"The brief makes at the sort key for Changes and Diff, and a git-only edit has to reorder; max keeps an edit that landed while git ran","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"choice":"refreshCounts stamps the refresh time when counts change; mergeCounts keeps the later of the two times","alternatives":["Keep the first-seen time for refreshed files"],"decided_by":""}
{"schema":3,"kind":"decision","id":"d90","text":"The Diff tab reads hunks only while it is the visible tab.","state":"adopted","ts":"2026-10-07T13:17:02+00:00","author":"claude-code","session":"","branch":"feat/pane-and-hints","scope":["hooks/diff.ts","hooks/register.tsx","hooks/pane.tsx"],"rationale":"git diff is the costly call, and the render hook can only read published state","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"choice":"Hunks live in the published pane view as a plain record, are read on the refresh queue while the tab shows and on switching to it, and untracked files are read with head -c 64 KB","alternatives":["Read the diff on every refresh","Keep hunks in module state outside the view"],"decided_by":""}
{"schema":3,"kind":"decision","id":"d91","text":"In the glowup pane, a person's scroll move of at least the engine's bodyRows pages by the open tab's window; wheel ticks and plugin scrolls move their own distance","state":"adopted","ts":"2026-10-07T13:19:24+00:00","author":"claude-code","session":"","branch":"feat/pane-and-hints","scope":["hooks/register.tsx","hooks/pane.tsx"],"rationale":"The engine sizes page keys by bodyRows and Home/End by contentRows; the pane fills its body so the two are equal and indistinguishable, and paging by bodyRows skipped rows because the tab window is shorter","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"Claude Code tells the scroll keys apart in UiScrollInput","cost_if_wrong":"Home and End page instead of jumping to an end","pinned":false,"choice":"ui.scroll hook: origin person and |by| >= bodyRows → sign(by) × the tab window height from the last render; otherwise by as given, clamped to the tab's last offset","alternatives":["Treat |by| >= contentRows as Home/End and jump to an end"],"decided_by":""}
{"schema":3,"kind":"decision","id":"d92","text":"/glowup config opens a Charm TUI in a new terminal window, with changes applied live to the running session","state":"adopted","ts":"2026-10-07T20:50:20+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/configpane.tsx","hooks/register.tsx","installer/"],"rationale":"The pane's Buttons and Inputs depend on Claude Code's pane focus and the owner found it unusable; the installer already carries the Charm stack, preview and Clawd","supports":[],"depends_on":[],"answers":[],"supersedes":["d65"],"evidence":[],"revisit":"","cost_if_wrong":"Release archives and install docs change; removing the pane later leaves desktop Code tab users with the printed command","pinned":false,"supersede_reason":"revise","choice":"glowup-installer config subcommand (Bubble Tea v2, lipgloss), launched detached in a terminal picked from the environment; the old pane moves to /glowup config pane for 0.12 and is then removed","alternatives":["Keep improving the in-Claude config pane","A separate Go binary for config only"],"decided_by":"owner"}
{"schema":3,"kind":"decision","id":"d93","text":"The config TUI and the mod talk through command lines and a state snapshot in $CLAUDE_CONFIG_DIR/glowup/remote/","state":"adopted","ts":"2026-10-07T20:50:20+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/remote.ts","installer/internal/"],"rationale":"All validation stays in TypeScript and a new setting is wired once; the engine store format belongs to Claude Code and is read only at session start","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"choice":"The TUI appends absolute /glowup command strings to commands.jsonl; each session runs them through runConfig and writes state-<session>.json with state, option lists and the last note","alternatives":["A desired-state JSON the mod diffs and applies","The TUI writes the engine store file directly"],"decided_by":"owner"}
{"schema":3,"kind":"decision","id":"d94","text":"Esc in the config TUI undoes through a per-run snapshot each session keeps in memory","state":"adopted","ts":"2026-10-07T20:50:20+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/remote.ts"],"rationale":"A pack command cannot rebuild a custom mix or a theme override","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"choice":"A session saves mix, pet, bubbles, motion, setup and fields the first time it sees a run; an undo line restores them through the Ctl setters and the store","alternatives":["The TUI replays commands for the values it saw at start"],"decided_by":"owner"}
{"schema":3,"kind":"question","id":"q13","text":"Can the mod's host.run open a terminal window (konsole -e, tmux new-window) from inside Claude Code's engine?","state":"open","ts":"2026-10-07T20:50:20+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts"],"rationale":"","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false}
{"schema":3,"kind":"decision","id":"d95","text":"In a terminal, /glowup config opens a Charm TUI in a new window bound to the session that ran it; the desktop Code tab keeps the pane","state":"adopted","ts":"2026-10-07T21:03:58+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts","hooks/register.tsx","hooks/configpane.tsx","installer/"],"rationale":"process.run reads output until exit and kills at 30 s; process.spawn kills its child when the module unloads; process is CLI-only, so the desktop has no way to open a window","supports":[],"depends_on":[],"answers":[],"supersedes":["d92"],"evidence":[],"revisit":"","cost_if_wrong":"Release archives and install docs change","pinned":false,"supersede_reason":"revise","choice":"glowup-installer config --run <dir>, launched detached through sh -c 'setsid -f' from process.run; the pane stays for sessions without a terminal surface and as /glowup config pane","alternatives":["Remove the pane one release later","process.spawn for the TUI"],"decided_by":"owner"}
{"schema":3,"kind":"decision","id":"d96","text":"Each config TUI run has its own directory, and only the session that created it applies its commands","state":"adopted","ts":"2026-10-07T21:03:58+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/remote.ts","installer/internal/"],"rationale":"Commands build on each session's in-memory state, so several sessions applying one line store different results; one writer keeps the store consistent, and per-run directories remove run ordering and takeover handling","supports":[],"depends_on":[],"answers":[],"supersedes":["d93"],"evidence":[],"revisit":"","cost_if_wrong":"Other open sessions see changes only at their next start","pinned":false,"supersede_reason":"revise","choice":"$CLAUDE_CONFIG_DIR/glowup/remote/<run>/ holds owner, undo.json, open (mtime heartbeat), commands.jsonl and state.json; a 250 ms poll in the owning session only; commands limited to an allowlist","alternatives":["One shared channel every session applies"],"decided_by":"claude"}
{"schema":3,"kind":"decision","id":"d97","text":"Config TUI undo restores the raw store keys saved at run start and reloads settings","state":"adopted","ts":"2026-10-07T21:03:58+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/remote.ts","hooks/register.tsx"],"rationale":"In-memory values would pin defaults (a migrated mix, fallback fields, an absent setup) into the store; a file survives a hot reload","supports":[],"depends_on":[],"answers":[],"supersedes":["d94"],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"supersede_reason":"revise","choice":"undo.json holds mix, pet, bubbles, reducedMotion, setup and statusline as stored (null when absent); undo writes them back, deletes absent keys, and calls loadSettings factored out of session.start","alternatives":["Restore in-memory values through the Ctl setters"],"decided_by":"claude"}
{"schema":3,"kind":"claim","id":"c14","text":"From a mod, process.run of sh -c 'setsid -f konsole -e …' returns in under 1 s and the window survives a module hot reload","state":"accepted","ts":"2026-10-07T21:54:56+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts"],"rationale":"","supports":[],"depends_on":[],"answers":["q13"],"supersedes":[],"evidence":[{"ref":"live probe 2026-10-08, 505 ms"}],"revisit":"","cost_if_wrong":"","pinned":false}
{"schema":3,"kind":"decision","id":"d98","text":"When /glowup config cannot use tmux or a terminal named in $TERMINAL or detected by its variable, it opens the person's default terminal","state":"adopted","ts":"2026-10-07T21:55:50+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts","hooks/register.tsx"],"rationale":"The owner asked for default-terminal launch beyond Konsole; xdg-terminal-exec and x-terminal-emulator are the standard default-terminal entry points, and $TERMINAL is an explicit choice so it beats detection","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false,"choice":"Linux: tmux, then $TERMINAL (any; unknown ones get -e), then the detected current terminal, then xdg-terminal-exec, then x-terminal-emulator, then the printed command. macOS: tmux, Ghostty/Terminal/iTerm by TERM_PROGRAM, else Terminal.app","alternatives":["Only the detected current terminal, else print the command","Read desktop settings (kdeglobals TerminalApplication, gsettings default-applications.terminal)"],"decided_by":"owner"}
{"schema":3,"kind":"decision","id":"d99","text":"/glowup config opens the config TUI on native Windows","state":"adopted","ts":"2026-10-07T22:38:36+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts","hooks/register.tsx"],"rationale":"The owner asked for cross-OS support; start honours the Windows 11 default-terminal setting, which covers Windows Terminal without a separate branch","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"Unit-tested only; a wrong Windows step fails at first use on Windows and falls back to the printed command","pinned":false,"choice":"Detect Windows by OS=Windows_NT, fetch the windows_amd64 zip with curl.exe/tar.exe and PowerShell for folders and the checksum, launch with cmd.exe /c start so Windows 11 uses the default terminal app","alternatives":["Windows prints the command to run by hand","Launch wt.exe when WT_SESSION is set"],"decided_by":"owner"}
{"schema":3,"kind":"question","id":"q14","text":"Does cmd.exe /c start leave the config TUI holding process.run's pipes on Windows, so /glowup config waits 30 s and prints the fallback while the window is open?","state":"open","ts":"2026-10-08T10:46:42+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts"],"rationale":"","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[],"revisit":"","cost_if_wrong":"","pinned":false}
{"schema":3,"kind":"claim","id":"c15","text":"The config TUI's Linux launch works live: tmux window, Konsole, $TERMINAL=xterm, hot reload, /clear mid-run, q and Esc","state":"accepted","ts":"2026-10-08T10:46:43+00:00","author":"claude-code","session":"","branch":"feat/config-tui","scope":["hooks/launch.ts","hooks/register.tsx"],"rationale":"macOS and Windows launches are unit-tested only","supports":[],"depends_on":[],"answers":[],"supersedes":[],"evidence":[{"ref":"Task 11 live check 2026-10-08, task-11-report.md"}],"revisit":"","cost_if_wrong":"","pinned":false}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `/glowup config` opens a settings screen in its own terminal window, and changes show in the session as you make them. Esc undoes everything since it opened. It has been run live on Linux; the macOS and Windows launches are new and have not had a live run yet.

### Changed

- The in-Claude config pane is now `/glowup config pane`, and still what `/glowup config` opens in the desktop Code tab.

## [0.11.0] - 2026-10-07

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ If a session loads both an installed copy and a clone, the clone wins and the in

## Using it

`/glowup` on its own lists the handful of commands most people need, and `/glowup config` opens a pane where you pick a pack, spinner and pet, type exact colors, and set up the band, tabs and status line. Everything else, including installing shared packs and themes, overriding single colors and exporting to Konsole, is in [Commands](docs/commands.md).
`/glowup` on its own lists the handful of commands most people need, and `/glowup config` opens a settings screen in a new terminal window where you pick a pack, spinner and pet, type exact colors, and set up the band, tabs and status line. Everything else, including installing shared packs and themes, overriding single colors and exporting to Konsole, is in [Commands](docs/commands.md).

glowup's settings also appear in Claude Code's `/plugin` menu. A change there and a `/glowup` command set the same saved choice, so whichever you made last is the one in effect. Changes made in `/plugin` apply at the next session start or after `/reload-plugins`.

Expand Down
21 changes: 18 additions & 3 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: Every /glowup subcommand, what it prints, and when it fails.
```text title="claude code"
glowup

/glowup config open the config pane: pack, colors, layout
/glowup config open the config TUI in a new terminal window
/glowup pack <name> switch look: arcade classic cozy crt
/glowup pet clawd|robot|off pick a pet, or none
/glowup pane open or close the side pane
Expand Down Expand Up @@ -133,15 +133,30 @@ Your layout and behavior settings. They are yours alone: installing someone's pa

## config

`/glowup config` opens a pane with a row for each choice, a preview of the look under them, and Done, Copy studio link and Reset at the bottom. Up and down move between rows.
`/glowup config` opens glowup's settings screen in a new terminal window. On Windows that is a new window in your default terminal app; WSL behaves as Linux. Changes apply to the session you ran it in as you make them. `q` keeps them, and Esc puts back what you had when the screen opened. In the desktop Code tab, where there is no terminal to open, `/glowup config` opens the pane described below instead, and `/glowup config pane` opens that pane anywhere.

The window opens in the first of these that applies:

1. Inside tmux, a new tmux window.
2. The terminal named by `$TERMINAL`, if you set it. Setting `$TERMINAL` is how you pick the terminal. glowup knows the argument conventions of konsole, kitty, ghostty, wezterm, gnome-terminal, foot, alacritty, xfce4-terminal, mate-terminal and terminator, and runs any other terminal as `<terminal> -e <command>`.
3. The terminal you are in, when glowup recognizes it: Konsole, kitty, Ghostty, WezTerm or GNOME Terminal.
4. Your system's default terminal: `xdg-terminal-exec`, then `x-terminal-emulator`.

On macOS the first rule applies too, tmux first. Otherwise it is Ghostty, iTerm, kitty or WezTerm, matching the terminal you are in, and Terminal.app for anything else. Without a display, as over SSH, nothing can open; glowup prints the command to run in a terminal instead, and it prints the same command if the window fails to start.

glowup runs the `glowup-installer` for the installed version. It looks first at the path in `GLOWUP_BIN`, then at `installer/glowup-installer` in a clone, and otherwise downloads the release's copy; see [Install](install.md#the-config-tui-binary). While the screen is open, `/glowup config` in that session says so instead of opening a second one.

### The config pane

The pane has a row for each choice, a preview of the look under them, and Done, Copy studio link and Reset at the bottom. Up and down move between rows.

The rows are Pack, Spinner, one for each color role, Band, Tabs, Meter, Pet, Sleeps, Bubbles, Bubble, Moods, Motion and Status. A row shown as ‹ value › cycles to its next value when you press Enter and applies it at once. The other rows are fields you type into and submit with Enter. A field you have not edited does nothing on Enter.

A color field takes a hex such as `#8ecbff` or `8ecbff`, and an empty one clears that role's override. Band, Tabs, Moods and Status take a list separated by commas or spaces, and the order you type is the order glowup draws them. An empty Band or Moods field means none, an empty Status field means the default fields, and Tabs needs at least one. The pane says what it did, or why it refused, on the line under the buttons.

Done, or Esc, closes the pane. Copy studio link puts a link to the studio on the clipboard, and the pane says so when the copy fails, as on a surface with no clipboard. Reset asks first, then clears your color overrides and your setup.

Each row has the same effect as the matching command (`pack`, `spinner`, `color`, `setup`, `pet`, `bubbles`, `motion`, `statusline fields`). Mixing layers from different packs and saving a pack are only available as commands. In a `-p` run, `/glowup config` prints the command list instead of opening the pane.
Each row has the same effect as the matching command (`pack`, `spinner`, `color`, `setup`, `pet`, `bubbles`, `motion`, `statusline fields`). Mixing layers from different packs and saving a pack are only available as commands. In a `-p` run, `/glowup config` prints the command list instead of opening the screen or the pane.

## Settings and the store

Expand Down
4 changes: 4 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ curl -fsSL https://glowup.khimani.dev/install.sh | sh -s -- --yes --pack crt

Set `GLOWUP_VERSION=v0.3.0` to use that release's installer instead of the latest.

### The config TUI binary

The first time you run `/glowup config`, glowup downloads the `glowup-installer` that matches the installed glowup version to `~/.local/share/glowup/bin/<version>/` (under `$XDG_DATA_HOME` if you set it; on Windows the file is `glowup-installer.exe` in `%XDG_DATA_HOME%\glowup\bin\<version>\` or `%USERPROFILE%\.local\share\glowup\bin\<version>\`) and checks it against the release's `checksums.txt`. Later runs reuse that copy. Set `GLOWUP_BIN` to the path of a `glowup-installer` to use that one instead of downloading. A clone with `installer/glowup-installer` built (`just installer-build`) uses it without the variable.

### Terminals

The installer has been tested in Konsole, kitty, ghostty, alacritty and xterm. It uses 24-bit color when the terminal advertises it, falls back to 256 colors under `TERM=xterm`, and respects `NO_COLOR`.
Expand Down
Loading
Loading