Skip to content
gwmgwmgwmv1.10.0

v0.8.0

Stable promotion of the full 0.8.0 release train. This consolidates every pre-release delta from rc.1, rc.2, rc.3, rc.4, and rc.5 into the stable notes. The headline of this cycle is configurability + personalisation: CLI aliases and a Gitmoji mapping, a config CLI and lifecycle hooks, GitHub issue / PR templates, a full TUI personalisation axis (remappable keymap with chords, command palette, role-based themes, sidebar stashes mode), a user-level global config layer, and a responsive / polished TUI chrome - plus the safety-daily tranche (--dry-run, gwm undo / gwm history), the gwm sync and cargo-binstall quick wins, and the v0.7.0 release-pipeline post-mortem fixes.

Install with cargo install gwm --version 0.8.0, cargo binstall gwm, or from the release archives. MSRV is 1.82.

No .gwm.toml migration is required. Legacy [[bootstrap.command]] entries are auto-aliased to [[hooks.post_create]], so existing configs keep working unchanged. The new user-level global config (~/.config/gwm/config.toml) is purely additive - with no global file, loading is identical to a repo-only 0.7.0 setup.

The git2 0.20 → 0.21 bump (#157) is intentionally deferred out of 0.8.0: it is a breaking accessor-API migration (several Option-returning accessors now return Result, Oid::zero deprecated) tracked as a dedicated source migration in #169. The Dependabot PR stays open until that lands.

  • 📝 Refresh the docs/ tree to the full v0.8.0 surface and add a French i18n mirror under docs/fr/ (#199 / #200). Documents every v0.7.0 → v0.8.0 addition that was still missing or only listed as planned: gwm commit-prefix, gwm hooks install commit-msg, gwm undo / gwm history, gwm theme list/show, gwm tui keys, gwm types --gitmoji, and --dry-run on gwm remove / gwm prune; the role-based [theme] presets, the remappable [tui.keys] keymap with chord support, the : command palette, the sidebar stashes mode, and the rc.5 TUI chrome polish; the [theme] / [tui.keys] schema, the user-level global config (~/.config/gwm/config.toml), and the {repo_path} / {repo_parent} placeholders; the 8th gwm doctor keymap check, cargo binstall packaging, and the PR auto-detection provenance. Adds three pages (tui/themes, tui/keymap-and-palette, configuration/global-config), fixes typos / capitalisation / cross-links throughout, and ships a complete French translation (33 pages, English remains canonical).

Historical delta: [0.8.0-rc.1] - 2026-05-23

Section titled “Historical delta: [0.8.0-rc.1] - 2026-05-23”

Delta against v0.7.0 stable. Merged PRs: #148, #149, #150, #151, #152.

First RC of the 0.8.0 series. Bundles the first tranche of the configurability axis - CLI aliases and a Gitmoji mapping - plus the v0.7.0-stable post-mortem fixes on the release / pre-release CI pipeline and the addition of windows-latest to the test matrix.

  • CLI aliases ([aliases] in .gwm.toml + user-level fallback) (#86 / #151). git config ships with [alias]; gwm now mirrors the shape. Declare an alias under [aliases] in .gwm.toml (repo-level, follows the repo across machines) or in ~/.config/gwm/aliases.toml (user-level fallback). gwm <alias> is expanded to argv tokens BEFORE clap parses, so wip = "create feat 0 wip" makes gwm wip behave as gwm create feat 0 wip. Resolution order: built-in subcommands always win (gwm list can never be shadowed), then repo, then user. Shell pipelines (&&, ||, |, ;, backticks) in alias values are refused at load time - use a shell alias for shell semantics. New gwm aliases list subcommand prints the resolved chain grouped by source, with shadowed user entries flagged inline. Tolerant of non-UTF-8 argv (uses std::env::args_os() + Cli::parse_from).
  • Gitmoji mapping + gwm commit-prefix + opt-in commit-msg hook (#85 / #152). The repo’s Gitmoji + Conventional Commits convention is now first-class. Three new surfaces:
    • gwm commit-prefix [--branch <name>] [--unicode] prints the canonical commit prefix (e.g. :sparkles: feat(#41): or ✨ feat(#41):) - handy for shell prompts, AI assistants, and scripted commit composition. Reads .gwm.toml even when --branch is supplied.
    • gwm types --gitmoji extends the existing branch-type list with two more columns (unicode emoji + :shortcode:).
    • gwm hooks install commit-msg [--force] installs an opt-in .git/hooks/commit-msg that auto-prepends the resolved prefix when the user’s commit message doesn’t already start with one. Non-destructive by default (refuses to overwrite a pre-existing hook without --force). Honors core.hooksPath, resolves linked-worktree .git files via Repository::discover, and degrades gracefully if gwm is not in $PATH at commit time.
  • New [gitmoji] block in .gwm.toml lets teams override individual shortcodes without redeclaring the whole table (the ten built-in defaults are baked into the binary). Custom branch types are supported - migration = ":truck:" round-trips through gwm types --gitmoji.
  • Under --unicode, gwm commit-prefix and the unicode column of gwm types --gitmoji normalise known :shortcode: overrides (e.g. feat = ":rocket:" → 🚀 feat(#1): instead of :rocket: feat(#1):). The known-shortcode set extends to the most commonly-swapped Gitmoji entries (:rocket:, :fire:, :lock:, :art:, :lipstick:, :hammer:, :bookmark:, :truck:, :rotating_light:, …). Unknown shortcodes fall through verbatim - no panic, no substitution. (#85)
  • Pre-release publishing now fails before upload when root [Unreleased] repeats bullets or issue references already shipped in the immediately previous RC notes. (#147 / #149)
  • Stable GitHub Releases now publish through the GitHub CLI with the workflow token and clobberable asset uploads, avoiding the softprops/action-gh-release bad-credentials failure seen on v0.7.0. (#146 / #148)
  • 👷 windows-latest added to the test matrix (#112 / #150). The main cargo test job now runs on ubuntu-latest, macos-latest, and windows-latest. Companion portability fixes ship in the same PR train (config path escaping, unix-only test gating, portable shell-script execution, drive-prefix rejection on Windows).
  • ✅ E2E coverage for gwm aliases list (built-in / repo / user precedence, shadowing rejection, shell-pipeline refusal, non-UTF-8 argv tolerance) - 21 new unit tests in tests/aliases_tests.rs + 9 in tests/cli_binary.rs.
  • ✅ E2E coverage for gwm commit-prefix (shortcode + unicode + --branch + override) and gwm hooks install commit-msg (fresh install, refuse overwrite without --force, linked worktree, core.hooksPath) - 9 tests in tests/gitmoji_tests.rs, 7 in tests/hooks_tests.rs, 9 in tests/cli_binary.rs.

Historical delta: [0.8.0-rc.2] - 2026-05-23

Section titled “Historical delta: [0.8.0-rc.2] - 2026-05-23”

Delta against v0.8.0-rc.1. Merged PRs: #153, #154, #155.

Second RC of the 0.8.0 series. Ships the Safety daily tranche - preview before you destroy, then gwm undo if you destroy anyway - plus the codified v0.7.0 retrospective in CLAUDE.md and a sibling AGENTS.md mirror.

  • --dry-run flag on gwm remove and gwm prune (#31 / #154). Preview destructive operations before running them.
    • gwm prune --dry-run walks the worktree list, prints every prunable entry (name + path + reason), and exits 0 without touching the admin files. Empty case reports 0 worktree(s) to prune so scripted callers get a stable signal. Output is sorted by name for deterministic stdout diffing.
    • gwm remove <pattern> --dry-run resolves the fuzzy pattern, prints the would-remove plan (name + path + branch, with (would be deleted) next to the branch when --delete-branch is also passed), and exits 0. An ambiguous pattern fires the same non-zero candidate-list error as the destructive form - --dry-run only suppresses destruction, not resolution failures.
    • Detached HEAD worktree edge case: combining --dry-run --delete-branch on a worktree with no resolvable branch now prints branch: - (no branch to delete) instead of the misleading (would be deleted) rider, mirroring worktree::remove’s actual behaviour (it only drops a branch when one is resolvable).
    • Column widths in the prune plan are computed in Unicode characters (.chars().count()), not bytes, so non-ASCII worktree names or paths stay aligned in a fixed-width terminal.
    • worktree::prune now consumes worktree::prunable_worktrees (the same scanner that backs --dry-run), so the preview and the destructive pass can never drift on what “prunable” means.
    • No breaking change: existing call sites without --dry-run keep the destructive default.
  • gwm undo + gwm history + operation journal (#29 / #155). Recover from a misfired gwm remove without git reflog archaeology.
    • Operation journal: every destructive op (gwm remove, with or without --delete-branch) appends an entry to $XDG_DATA_HOME/gwm/history.toml (override via $GWM_HISTORY_FILE; macOS fallback under Application Support, Windows under %LOCALAPPDATA%). Each entry captures the timestamp, worktree name, branch name, branch OID at deletion time, on-disk path, the --delete-branch flag, and the canonicalised repo_root so per-repo separation works across symlink chains.
    • Rotation cap: 100 entries max across the whole journal; oldest-by-timestamp dropped on overflow.
    • gwm undo [--bootstrap]: pops the most recent op for the current repo, recreates refs/heads/<branch> at the saved OID via Repository::reference, re-adds the worktree at the saved path with reuse_branch: true. The --bootstrap flag opts into re-running the per-worktree bootstrap (off by default to keep undo cheap). The journal entry is consumed only after a successful resurrection - a mid-flight failure keeps the recovery anchor intact. Detached-HEAD entries are refused with an explicit error rather than silently doing nothing.
    • gwm history [--limit N] [--all]: lists the recent ops newest-first. Default --limit is 20. By default filters to the current repo’s canonicalised workdir; --all surfaces every entry across every repo for forensic / multi-repo grep. Empty result prints no operations recorded as a stable scripted signal. --limit 0 keeps the count line distinct from an empty journal so scripts can tell “I asked for nothing” from “there is nothing”.
    • gwm remove --dry-run does NOT write to the journal - previewing a destruction must never allow “undoing” something that never happened.
    • Journal IO failures are logged to stderr but never block the destructive op: failing a remove because we couldn’t write ~/.local/share/gwm/history.toml (disk full, read-only FS, sandboxed CI runner) would be more surprising than losing recoverability.
  • Codify v0.7.0 retrospective rules + AGENTS.md mirror (#153). Seven recurring patterns from the v0.7.0 post-mortems land in CLAUDE.md: stack depth (max 2-3 PRs), encapsulation-nit batching after a stack merges, parallel-agent ownership rule (only when file ownership is disjoint), follow-up issues beating scope creep, MSRV verification against the whole codebase, root CHANGELOG hygiene against rc duplicates, and the release-workflow credentials proof. AGENTS.md is added as a sibling mirror so the same house rules apply whether Claude Code or Codex is driving. ROADMAP.md Current state bumps to v0.7.0, and .gitignore picks up .claude/ and .serena/.
  • ✅ 7 new unit tests in tests/cli_format_tests.rs pinning the format_remove_plan / format_prune_plan helpers extracted in the Copilot follow-up on #154 (detached-HEAD safety, unicode column alignment).
  • ✅ 9 new E2E tests in tests/cli_binary.rs and 4 in tests/worktree_integration.rs covering --dry-run for both remove and prune (#154).
  • ✅ 10 new E2E tests in tests/cli_binary.rs and 8 new unit tests in tests/history_tests.rs covering the journal IO contract, gwm history, gwm undo, the remove journal hook, and detached-HEAD refusal (#155).
  • 840 tests total across the cargo test matrix (ubuntu-latest, macos-latest, windows-latest) wired in ci.yml. Each merge into dev is gated on the matrix turning green; pre-release artifacts are built from the same commit by pre-release.yml.

Historical delta: [0.8.0-rc.3] - 2026-05-29

Section titled “Historical delta: [0.8.0-rc.3] - 2026-05-29”

Delta against v0.8.0-rc.2. Merged PRs: #161, #162, #163, #164, #165, #166, #167, #168, #158, #159, #160.

Third RC of the 0.8.0 series and the largest. Lands the remaining configurability tranches (config CLI, lifecycle hooks, GitHub issue / PR templates) and the full TUI personalisation axis (remappable keymap with chord support, command palette, role-based themes, sidebar stashes mode), plus three dependency bumps. The git2 0.21 bump is deferred - it is a breaking accessor-API migration tracked in #169.

  • gwm config get/set/unset/list/validate/path/edit (#89 / #161). Git-config-style CLI over .gwm.toml. get/set/unset operate on dotted keys, list dumps the resolved config, validate re-runs the load-time checks and reports the first error, path prints the resolved config file location, edit opens it in $EDITOR. Writes go through toml_edit so existing comments, ordering, and formatting survive a set.
  • Lifecycle hooks under [hooks.*] (#88 / #162). Declarative pre_create / post_create / pre_bootstrap / post_bootstrap / pre_remove / post_remove phases, each a list of commands with placeholder expansion, a per-step on_fail = abort|warn|ignore, and a global --skip-hooks escape hatch. Legacy [[bootstrap.command]] entries are aliased to [[hooks.post_create]] so existing configs keep working (soft-breaking, no action required).
  • [issue_template] defaults + gwm new <type> <desc> (#83 / #163). Create a GitHub issue from per-branch-type issue-form templates and immediately spin up the linked worktree in one command.
  • [pr_template] defaults + gwm pr [--draft] [--base <ref>] [--render] (#84 / #164). Render per-branch-type PR bodies with {commits} / {files_changed} placeholders and shell out to gh pr create. --render prints the body without opening a PR; --base overrides the resolved trunk (with a common-trunk fallback). Body-supplied content wins over the template default.
  • [tui.keys] configurable keymap with chord support (#87 / #165). Rebind every TUI list-view action (down, up, top, bottom, quit, …) with crossterm-grammar keys, including multi-key chords like g g. Overrides are validated at load time (unknown actions, parse errors, chord conflicts, and prefix collisions are hard errors). Adds gwm tui keys to print the resolved keymap with per-row source, a gwm doctor check for an unbound quit, and a keymap-driven help overlay (?) so the documentation always matches the resolved bindings.
  • Sidebar stashes mode (#34 / #166). Toggle with s (rebindable as toggle_sidebar_mode in [tui.keys]). Cycles the Details panel between commits (git log --oneline + git status --short, the pre-existing behaviour) and stashes (git stash list). The panel title shows the active mode; the bottom hint switches to Enter: copy stash@{N} to status in stashes mode. Cache is keyed by (worktree-path, mode) so toggling re-shells the right git command without leaking stale content between modes.
  • Command palette overlay (#32 / #167). Opened by : (rebindable as command_palette in [tui.keys]). Type to fuzzy-filter the registered actions (:create, :bootstrap, :yank, …); Enter fires, Tab/Down/Up cycles the highlight, Esc cancels. The palette and the keystroke dispatcher share the same Action dispatcher under the hood, so the two surfaces can never drift on which verbs are addressable or how they behave.
  • [theme] role-based colours (#33 / #168). New [theme] block in .gwm.toml for role-based colours (focus, accent, branch, clean, dirty, main, locked, prunable, muted, selection_bg). Built-in presets ship for catppuccin, gruvbox, tokyo-night; per-role overrides win over presets. Values accept named (cyan), indexed (220), or hex (#89b4fa). Validation runs at load (unknown preset, unknown role, bad colour value all reject). Adds gwm theme list to print preset names and gwm theme show <name> to dump a preset as a copy-pasteable, round-trippable [theme] block. The TUI threads the resolved theme through App.theme; a full colour audit of every draw_* site is tracked as a follow-up (#170).
  • ⬆️ Bump serde_json 1.0.149 → 1.0.150 (#158).
  • ⬆️ Bump sha2 0.10 → 0.11 (#159). Verified MSRV-clean against the 1.82 floor (cargo clippy --all-targets -- -W clippy::incompatible_msrv).
  • ⬆️ Bump criterion 0.5 → 0.8 (#160). The benches migrate off the deprecated criterion::black_box to std::hint::black_box so cargo clippy --all-targets -- -D warnings stays green under the bump.
  • git2 0.20 → 0.21 (#157) is a breaking accessor-API migration (several Option-returning accessors now return Result, Oid::zero deprecated) and does not build as-is. Tracked as a dedicated source migration in #169; the Dependabot PR stays open until that lands.
  • TDD throughout: each feature shipped with its companion unit / E2E / state-machine tests (config CLI in tests/, lifecycle hooks in tests/bootstrap_tests.rs, issue / PR templates in tests/cli_binary.rs, keymap / palette / stashes / theme in tests/tui_app_tests.rs and config tests).
  • 973 tests total green locally and on the ubuntu-latest / macos-latest / windows-latest matrix.

Historical delta: [0.8.0-rc.4] - 2026-05-29

Section titled “Historical delta: [0.8.0-rc.4] - 2026-05-29”

Delta against v0.8.0-rc.3. Merged PRs: #172, #173.

Fourth RC of the 0.8.0 series. A short delta: the two remaining Quick wins that landed after rc.3 - gwm sync (#24) and cargo-binstall support (#27). Cut as a dedicated RC rather than folded into the stable so the “stable == last soaked RC” discipline holds. The git2 0.21 bump stays deferred to #169 (Dependabot #157 left open).

  • gwm sync [<pattern>] [--merge] (#24 / #172). Fetch a worktree’s upstream and rebase its branch onto it - or merge with --merge. Resolves the target worktree by fuzzy pattern (defaults to the CWD worktree). Refuses a dirty working tree and a branch with no upstream; a conflicting rebase/merge is aborted so the worktree stays usable, with an actionable error. Read-side inspection uses libgit2; the fetch/rebase/merge steps shell out to git so the user’s configured credentials are honoured.
  • cargo-binstall support (#27 / #173). [package.metadata.binstall] in Cargo.toml lets cargo binstall gwm pull the prebuilt archive (gwm-v{version}-{target}.tar.gz, .zip on Windows) straight from the GitHub Release - no Rust toolchain or libgit2 compile at install time. Pinned against artefact-naming drift by tests/binstall_metadata_tests.rs.
  • TDD throughout: gwm sync shipped with format_sync_report contract tests in tests/cli_format_tests.rs plus E2E coverage; cargo-binstall metadata pinned by tests/binstall_metadata_tests.rs against artefact-naming drift.
  • 989 tests total green locally and on the ubuntu-latest / macos-latest / windows-latest matrix.

Historical delta: [0.8.0-rc.5] - 2026-06-01

Section titled “Historical delta: [0.8.0-rc.5] - 2026-06-01”

Delta against v0.8.0-rc.4. Merged PRs: #176, #178, #182, #183, #184, #186, #189, #191, #192, #195, #197.

The largest RC of the 0.8.0 series - the personalisation + polish wave on top of rc.4’s quick wins: a user-level global config layer, a responsive TUI sidebar, the claude-dark preset and a reworked header, a full modal polish pass, a single-line statusline, working-tree colourisation, PR auto-detection, and {repo_path} / {repo_parent} config placeholders - plus a test-hermeticity fix so cargo test no longer reads the contributor’s real global config. The git2 0.21 bump stays deferred to #169 (Dependabot #157 left open).

  • User-level global config at ~/.config/gwm/config.toml (XDG: $XDG_CONFIG_HOME/gwm/config.toml), merged underneath each repo’s .gwm.toml. Set a preference once - e.g. [theme] preset = "…" - and it applies to every repo. The merge is a deep TOML overlay: the repo wins on conflicting scalars, tables ([theme], [worktree], [tui], …) merge key-by-key, and arrays ([[labels]], [[bootstrap.copy]], …) are replaced wholesale by the repo when present. Validation runs on the merged result. With no global file, loading is identical to before (repo-only, then the built-in default). Set GWM_NO_GLOBAL_CONFIG=1 to force strictly repo-only loading (used by CI for deterministic runs). (#190)
  • Responsive TUI sidebar - layout orientation and position. On a narrow terminal (< 120 cols) the details sidebar no longer disappears: instead of hiding, it now stacks under the worktree table (table on top, sidebar below). A new V key cycles the layout auto → side-by-side → stacked → auto (auto is the width-driven default; the other two pin the orientation regardless of width). The sidebar can also sit on the left of the table: a new [tui] sidebar_position = "left" | "right" knob (default right, preserving prior behaviour) sets the default side, and H toggles it live. The left/right preference applies to the side-by-side layout; the stacked layout always keeps the sidebar at the bottom. (#188)
  • Ephemeral PR auto-detection for a branch’s pull request. When no PR is explicitly linked (gwm link --pr), gwm now resolves the branch’s PR from GitHub (gh pr list --head <branch> --state all) and surfaces it marked detected - never written to git config, so it stays fresh and an explicit link always wins. Wired into gwm status (always, one worktree), the TUI sidebar (on the F refresh, marked “ (detected)“), and a new opt-in gwm list --detect-pr flag that adds a PR column (one gh call per worktree; plain gwm list stays network-free). New LinkSource::Detected provenance alongside branch-name / explicit. (#181)
  • {repo_path} and {repo_parent} placeholders for .gwm.toml paths/patterns. {repo_path} expands to the main repo’s absolute working directory and {repo_parent} to its parent, so a base can be expressed relative to the repo on disk - e.g. base = "{repo_parent}/worktrees" puts worktrees in a sibling worktrees/ dir, matching an editor’s ../worktrees convention (Zed’s git.worktree_directory) without a per-project editor config. Purely additive; existing {home}/{repo} bases are unchanged. (#175)
  • claude-dark built-in theme preset, a port of the Claude dark palette (orange accent #D4825D / #C15F3C, green/yellow/purple/red semantics). Discoverable via gwm theme list and gwm theme show claude-dark (also resolves under the alias claude). (#185)
  • Colourisation of the Working Tree sidebar block in the TUI, with three distinct status colours so modified and created files stay visually apart: the staged (X) status column renders cyan, a worktree modification (Y) yellow, and untracked ?? entries green. Each file name takes its dominant status colour (green when untracked, yellow when modified, cyan when staged-only). The displayed text is unchanged - only colour is added - so each entry still shows the exact git status --short codes. (#179)
  • TUI modal polish - every overlay (confirm delete, help, new worktree, bootstrap report, open, link, command palette) now shares one frame: a rounded border with a bold themed title, colours pulled from the resolved [theme] instead of hard-coded values, and a box sized to its content rather than a fixed percentage of the screen (the confirm and create modals no longer dwarf their few lines). The confirm overlay gained selectable [ Confirm ] / [ Cancel ] buttons (navigate with ← / → / Tab, Enter activates the focused one), with focus defaulting to Cancel so a stray Enter cancels rather than deletes; the classic y / n / Esc shortcuts are unchanged. A long worktree path is tilde-compressed and middle-ellipsized to one line. An animated spinner sits beside the safety-countdown progress bar as a live loader. The help overlay renders each key chord as its own coloured badge (the statusline chip style) with themed section headers. (#187)
  • TUI statusline is now a single line. Key hints render as reverse-video badge chips (the key painted with the theme accent, followed by a short label) and the status message (action log) is pinned flush-right with absolute priority - when the terminal is too narrow, the hint list is truncated with an … marker while the log stays visible. Previously the footer occupied two rows and wrapped, which could push the log off-screen. No keybindings changed. (#180)
  • TUI header is now a single borderless row with a clear visual hierarchy instead of a boxed, flat cyan string. The version renders as a reverse-video badge chip (matching the #180 footer chips), the repo name is bold, and the working directory is tilde-compressed and dimmed as secondary context. The picker flag is now its own reverse-video chip. The layout is width-driven: under width pressure the path is truncated/dropped first, the repo name next, and the version chip survives last. Dropping the border reclaims two rows for the worktree table. gwm --version parity is preserved (version still sourced from CARGO_PKG_VERSION). (#185)
  • Test hermeticity - config-dependent tests no longer read the contributor’s real ~/.config/gwm/config.toml. After #190 added the global-config layer, aliases::load and App::new_at merged the runner’s actual global config, so cargo test failed on any machine whose global config diverged from the built-in defaults (e.g. a [theme] preset unknown to the checked-out build). Added injectable seams aliases::load_layered(repo, global, user) and App::new_at_layered(start, global) mirroring Config::load_layered (#190); the leaking tests now inject None for a fully repo-only, deterministic resolution. Runtime behaviour of aliases::load / App::new_at is unchanged - they still read the real global config. The remaining call sites across the suite (config_tests.rs, bootstrap_tests.rs, doctor_tests.rs, tui_app_tests.rs, tui_chord_tests.rs, tui_state_palette_tests.rs) were swept onto the same seams - plus a new App::new_picker_at_layered - so cargo test is now green without GWM_NO_GLOBAL_CONFIG=1 regardless of the contributor’s global config. (#194 / #196)
  • The focused panel border (worktree list ↔ sidebar, toggled with Tab) now paints with the theme focus role instead of a hardcoded Color::Cyan, so the active “tab” honours the configured palette (e.g. the claude-dark preset’s orange) rather than always rendering cyan. The default theme is unchanged (focus is still Cyan), so default-theme users see no difference. (#185)
  • TDD throughout; the full suite is green locally (without GWM_NO_GLOBAL_CONFIG=1 after the #194 / #196 hermeticity sweep) and on the ubuntu-latest / macos-latest / windows-latest matrix.