--- title: Roadmap description: What ships today in the v1.9.0 licensing line: a dual MIT OR Apache-2.0 license, the notices of the libraries compiled into the binary, and an em dash sweep through everything gwm prints. Earlier lines follow. --- # Roadmap The full roadmap (with grouped categories and per-item issue links) lives in [`ROADMAP.md`](https://github.com/kbrdn1/gwm-cli/blob/main/ROADMAP.md) at the repo root. The issue tracker is the source of truth for scope details, acceptance criteria, and alternatives considered. ## current state: v1.9.0 stable The current **stable** line is **v1.9.0** (`Cargo.toml` `version = "1.9.0"`, tagged 2026-08-16), the licensing line: gwm is **dual-licensed MIT OR Apache-2.0** ([#573](https://github.com/kbrdn1/gwm-cli/issues/573)). Nothing is taken away, MIT stays in full under `LICENSE-MIT`; `LICENSE-APACHE` joins it for §3, an express patent grant from every contributor that MIT has no clause for at all, and it is the pair rustc, cargo, clap, serde, ratatui and git2 already ship. You pick either one and never have to say which. The libraries statically compiled into the binary now ship their notices too ([#577](https://github.com/kbrdn1/gwm-cli/issues/577)): libgit2 is GPLv2 with a linking exception conditional on that notice travelling with the distribution, and zlib's terms say its notice may not be removed. The rest of the line is the text gwm prints: 165 em dashes across 161 string literals, plus 49 in `gwm --help` ([#567](https://github.com/kbrdn1/gwm-cli/issues/567)); the Settings panel sizing to its active tab rather than to a flat 60% of the frame ([#569](https://github.com/kbrdn1/gwm-cli/issues/569)); and one spelling for a worktree path everywhere it is printed in full ([#568](https://github.com/kbrdn1/gwm-cli/issues/568)). See [`changelogs/1.9.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.9.0.md). **v1.8.0** (tagged 2026-08-13) was the density line: the TUI became **compact by default** ([#545](https://github.com/kbrdn1/gwm-cli/issues/545)), panes and sidebar sections dropping their box rules for a filled one-line header, two rows and two columns back each, with modal titles moved into the top rule ([#549](https://github.com/kbrdn1/gwm-cli/issues/549)), the Status block folded onto a single row ([#547](https://github.com/kbrdn1/gwm-cli/issues/547)) and `[tui] layout = "bordered"` as the opt-out. Every bounded overlay resolved its width through one policy instead of four ([#550](https://github.com/kbrdn1/gwm-cli/issues/550)), two of which used to get *narrower* as the terminal widened, and four truncators moved from counting characters to counting terminal cells ([#554](https://github.com/kbrdn1/gwm-cli/issues/554) / [#560](https://github.com/kbrdn1/gwm-cli/issues/560) / [#562](https://github.com/kbrdn1/gwm-cli/issues/562) / [#563](https://github.com/kbrdn1/gwm-cli/issues/563)). A default layout is outside the SemVer promise on purpose: the policy leaves any visual detail of the interface free to change in a minor. **v1.7.1** (tagged 2026-08-12) was a documentation patch with the binary unchanged: the agent session pane got its own page, five text-only pages got a capture, and a guard now fails the build on a broken image link instead of letting the docs deploy fail. **v1.7.0** (tagged 2026-08-12) is the largest feature line since 1.0: per-worktree notes, the rich PR/Issue view with its inline review comments, container execution on `exec` profiles, multi-row selection with a batch delete, and the Symfony preset. It closes the four capability gaps the comparative read of the field turned up, so the [comparison page](/comparison) now reports parity where it reported a deficit. See [`changelogs/1.7.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.7.0.md). The previous line, **v1.6.1** (tagged 2026-08-04), closed the gaps left by the v1.6.0 security fix. **That fix affects every version up to and including 1.5.0**: see [`changelogs/1.6.1.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.6.1.md), [`changelogs/1.6.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.6.0.md) and the sections below. The **machine-readable contracts frozen at 1.0.0 are unchanged**: the CLI subcommands / flags / exit codes, the `--format=json` schemas, the daemon JSON-RPC protocol, and the `.gwm.toml` section set will not break without a major bump (see [Stability & compatibility](/development/stability)). The project MSRV is **1.95**. Since the 1.0.0 milestone (tagged 2026-06-26): three 1.0.x patches hardened the stable line, **v1.1.0** shipped the first outside-report-driven pair ([#363](https://github.com/kbrdn1/gwm-cli/issues/363): persisted sidebar layout + OSC52 clipboard fallback over SSH) with **v1.1.1** fixing global config resolution on macOS, **v1.2.0** shipped the distribution train ([#383](https://github.com/kbrdn1/gwm-cli/issues/383): Scoop, `.deb` / `.rpm`, AUR, aqua, winget automation), **v1.3.0** made gwm agent-aware, **v1.4.0** finished the help overlay and the TUI-polish trio, **v1.5.0** made gwm multi-forge, and **v1.6.0** fixes a command injection through branch names in lifecycle hooks while landing the naming-flexibility line: the section below. Per-version notes live under [`changelogs/`](https://github.com/kbrdn1/gwm-cli/tree/main/changelogs). ## v1.6.1: bidi follow-up and self-maintaining documentation The v1.6.1 line closes what the 1.6.0 neutralisation missed and puts the documentation on rails. Consolidated notes: [`changelogs/1.6.1.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.6.1.md). Key items: - **The bidi controls the sanitisers missed** ([#502](https://github.com/kbrdn1/gwm-cli/issues/502)): the 1.6.0 rule rests on `char::is_control`, which covers C0, DEL and C1. It does not cover the twelve characters carrying the `Bidi_Control` property, which are `Cf` and not `Cc`: they reorder how a terminal renders the text around them without ever being a control byte. The site that matters is the pre-trust bootstrap summary, whose whole job is to let someone decide whether to authorise a shell command out of a repo they have not vetted; a summary that can be made to misrepresent that command is worse than no summary. An `[aliases]` expansion is refused rather than neutralised, because it becomes argv before clap parses it. - **Branch names reaching the TUI table** ([#506](https://github.com/kbrdn1/gwm-cli/issues/506)): the sinks the CLI goes through are not on the TUI's path, and what protected it so far was incidental. Measured on ratatui 0.30, every render path drops the zero-width control bytes, but `List` and `Table` keep the `Bidi_Control` characters, and git's ref rules refuse the ASCII controls but not the Unicode format ones. The neutralisation goes in the width-clipping funnel every constrained cell already passes through, so a column added later inherits it. - **The documentation publishes itself** ([#423](https://github.com/kbrdn1/gwm-cli/issues/423)): the tree under `docs/` is served at ****. A merge into `main` touching `docs/`, `changelogs/` or `Cargo.toml` triggers a resync and a redeploy without anyone asking. The in-repo tree stays the source of truth, the site is generated from it and never edited on the other side. - **herdr integration page** ([#511](https://github.com/kbrdn1/gwm-cli/issues/511)): `herdr-plugin-gwm` drives gwm from inside the herdr multiplexer, documented in English and French. The plugin never creates a worktree of its own: gwm creates, herdr adopts, which is what keeps a single source of truth. - **Test hardening around the same class of mistake**: a rule about the `$HOME` guard that was stated in a doc comment rather than checked is now derived by construction ([#507](https://github.com/kbrdn1/gwm-cli/issues/507)), and two harness races never reachable from the product are closed ([#500](https://github.com/kbrdn1/gwm-cli/issues/500)). ## v1.6.0: security fix and naming flexibility The v1.6.0 line closes a command injection and drops the ` ` requirement. Consolidated notes: [`changelogs/1.6.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.6.0.md). Key items: - **Security: a branch name could inject a command into a lifecycle hook** ([GHSA-fffq-vg6f-gxqm](https://github.com/kbrdn1/gwm-cli/security/advisories/GHSA-fffq-vg6f-gxqm), high, CWE-78 / CWE-88): hook placeholders were substituted into the step's `run` string and handed to `sh -c`, and git permits `;`, `|`, `&`, `$`, backticks and redirections in a ref name. A branch pushed by somebody else, a fork PR branch is enough, could therefore run arbitrary commands as anyone who had trusted their own repo's hooks, with no trust prompt anywhere in the path: the gate asks about the repo's hooks and never covered the branch name flowing into them. **Every version up to and including 1.5.0 is affected and there is no backport.** Values are now shell-escaped on expansion; `env` values stay unescaped because they never see a shell. - **Free-form worktree names** ([#416](https://github.com/kbrdn1/gwm-cli/issues/416)): `gwm create --name spike-redis` names a worktree freely instead of composing the ` ` triple. The name becomes the branch verbatim, so `branch_pattern` / `path_pattern` do not apply, and the features that read a branch name back (issue auto-linking, gitmoji) stay inactive on it; `gwm link` remains available. - **The TUI forms follow the repo's own patterns** ([#418](https://github.com/kbrdn1/gwm-cli/issues/418)): create and rename present the fields the configured patterns actually ask for, in the order those patterns write them, rather than the canonical triple. A repo whose convention is `{type}/{desc}` is no longer shown an Issue field it would discard. Both forms move between the structured and free-form shapes with the same verb, in both directions. - **Hook context as environment variables**: `GWM_BRANCH`, `GWM_PATH`, `GWM_TYPE`, `GWM_ISSUE`, `GWM_DESC`, `GWM_USER`, `GWM_OWNER`, `GWM_REPO` alongside the `{placeholder}` syntax. A hook that reads `"$GWM_BRANCH"` never has to think about quoting, because a shell does not re-parse metacharacters coming out of a variable. - **The declared MSRV is 1.95, and CI holds it** ([#491](https://github.com/kbrdn1/gwm-cli/issues/491)): `Cargo.toml` had claimed 1.86 for a whole release line while the locked graph needed more, silently, because `rusqlite`'s bundled `libsqlite3-sys` declares no floor of its own and no manifest read finds it. A job now installs the declared floor and both resolves and compiles the committed lockfile against it, on all three runners. - **Hardening found while verifying the above**: `.gwm.toml` values no longer reach the terminal with their control bytes intact ([#473](https://github.com/kbrdn1/gwm-cli/issues/473)), placeholder expansion is single pass so an expansion is a value rather than more template ([#494](https://github.com/kbrdn1/gwm-cli/issues/494)), a failed `gwm create` no longer leaves the branch it created behind ([#487](https://github.com/kbrdn1/gwm-cli/issues/487)), and a free-form name is validated against Windows path rules on every platform ([#475](https://github.com/kbrdn1/gwm-cli/issues/475)). ## v1.5.0: multi-forge (GitLab) The v1.5.0 line puts a `Forge` trait behind the network layer and ships a second backend for it. Consolidated notes: [`changelogs/1.5.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.5.0.md). Key additions: - **A `Forge` trait and a GitLab (`glab`) backend** ([#419](https://github.com/kbrdn1/gwm-cli/issues/419)): issue and pull/merge request lookups go through an abstraction with two implementations, `gh` and `glab`. Worktrees, bootstrap, branch naming and the `branch..gwm-*` link storage are unchanged and forge-neutral, so nothing about a repo becomes forge-specific on disk. Full page: [GitLab (multi-forge)](/integrations/gitlab). - **Explicit forge selection** ([#419](https://github.com/kbrdn1/gwm-cli/issues/419)): a new `forge = "github" | "gitlab"` key in `.gwm.toml`. Omitted, the forge is inferred from the `origin` host, but only on the vendors' own domains (`github.com`, `ghe.com`, `gitlab.com`): a self-hosted instance lives on an arbitrary domain, so the explicit key is how you name the backend, and it always wins over inference. - **Authorising a self-hosted host is a separate decision** ([#419](https://github.com/kbrdn1/gwm-cli/issues/419)): a host gwm does not recognise is **not** assumed to be GitHub, because guessing would send an authenticated call, and whatever token the environment carries, to whatever host a cloned repo's `origin` named. Authorisation comes from a new `[forge_hosts]` table read from **your own** global config, or from approving the repo's `.gwm.toml` in the TOFU trust ledger. New `gwm trust add` approves a repo without running anything, since the existing prompt only fires when there is a bootstrap surface to execute. - **GitLab specifics absorbed at the parse boundary** ([#419](https://github.com/kbrdn1/gwm-cli/issues/419)): `iid` as the user-visible number, nested subgroup paths, the `/-/` URL infix, date-only milestone due dates, project labels separated from inherited group labels, and a pipeline-to-CI-state map in which an unrecognised status is reported as `unknown` and never aggregates to a green CI. `$GWM_GLAB` overrides the binary, mirroring `$GWM_GH`. - **The trust ledger keys on the repo again, not on its host** ([#463](https://github.com/kbrdn1/gwm-cli/issues/463)): the new forge gate built its half of the `(origin, sha256)` key from scheme + host only, which shared one approval across every repo on that host whose `.gwm.toml` hashed identically. All four call sites now go through one helper. ## v1.4.0: help overlay completeness + TUI polish The v1.4.0 line closes the [#436](https://github.com/kbrdn1/gwm-cli/issues/436) / [#437](https://github.com/kbrdn1/gwm-cli/issues/437) / [#438](https://github.com/kbrdn1/gwm-cli/issues/438) TUI-polish trio and completes the `?` help overlay. Consolidated notes: [`changelogs/1.4.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.4.0.md). Key additions: - **Complete help overlay** ([#453](https://github.com/kbrdn1/gwm-cli/issues/453)): the `?` overlay documents every key context: one section per modal overlay, each verb resolved live against `[tui.keys.modal.]` so rebinds show through, with a per-section completeness guard extending the #334 one to every modal verb. The statusline which-key was re-audited (`exec` / `agents` joined the worktrees footer), and the review loop hardened a **reserved-typing contract** across every input sub-mode: keys a text input legitimately consumes cannot be bound to modal verbs (rejected at config time), and an unbound modified Backspace still erases. - **CI checks overlay** ([#436](https://github.com/kbrdn1/gwm-cli/issues/436)): `C` (or `c` while the status pane holds focus) lists every check of the linked PR's `statusCheckRollup`: state icon per row, owning workflow + run duration in a muted detail column, `j` / `k` selection, `Enter` opens the check's details URL, `/` filters, `f` re-fetches in place; verbs rebindable under `[tui.keys.modal.ci_checks]`. - **Working Tree scroll** ([#437](https://github.com/kbrdn1/gwm-cli/issues/437)): with the status pane focused, `J` / `K` (rebindable `wt_scroll_down` / `wt_scroll_up`) scroll the file tree independently, clamped to the granted viewport; the offset resets on worktree navigation and the commits ↔ stashes toggle. - **Responsive sidebar heights** ([#438](https://github.com/kbrdn1/gwm-cli/issues/438)): the Agents / Working Tree / Recent Commits sections share the column through a pure layout solver: natural heights while everything fits, guaranteed floors on short terminals (7 lines for Working Tree, 5 for Recent Commits), proportional split of the remainder, the non-scrollable Agents pane never clipped, and a scrollbar on an overflowing Working Tree. - **Housekeeping**: a project logo (dark / light SVG pair heading the README), `persist-credentials: false` on every read-only workflow checkout ([#433](https://github.com/kbrdn1/gwm-cli/issues/433)), and the red-on-every-release `winget-publish` job removed in favour of the manual `komac` recipe ([#448](https://github.com/kbrdn1/gwm-cli/issues/448)). ## v1.3.0: agent sessions + the Windows daemon The v1.3.0 line makes gwm aware of the AI-agent sessions working in its worktrees, and finishes the daemon's platform story. Consolidated notes: [`changelogs/1.3.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.3.0.md). Key additions: - **Agent session pane** ([#408](https://github.com/kbrdn1/gwm-cli/issues/408)): gwm detects AI-agent coding sessions (Claude Code, Codex, opencode, Mistral Vibe) per worktree by reading each tool's on-disk session artefacts (`std::fs` only, no process scanning, identical behaviour on Linux / macOS / Windows). Surfaced as an **AGENT** column in the worktree table, an `Agent:` summary line plus a pinned-sessions pane in the sidebar, an interactive detail overlay on `a` (select / pin / unpin, rebindable under `[tui.keys.modal.detail]`), an additive experimental-tier `agents` field on the JSON / daemon rows (`SCHEMA_VERSION` stays 1), and an active-agent segment in `gwm statusline`. - **`gwm agents` + manual pinning** ([#408](https://github.com/kbrdn1/gwm-cli/issues/408)): the same detection as a CLI surface: `gwm agents` lists sessions per worktree (human or `--format=json`), the plain `gwm list` table gains the AGENT column, and `gwm agents attach ` / `detach` pin a session when the recorded directory is not enough. Sessions carry a human-readable name when their artefacts have one. - **Windows named pipe transport for the daemon** ([#439](https://github.com/kbrdn1/gwm-cli/issues/439)): `gwm daemon` and `gwm statusline` now work on Windows: the daemon binds an owner-only named pipe under `\\.\pipe\` with the same JSON-RPC surface, DoS guards and graceful degradation as the unix socket, and the statusline client rides it. The docs' Unix-only caveats are lifted. - **Process-level liveness for Claude Code sessions** ([#441](https://github.com/kbrdn1/gwm-cli/issues/441)): on Unix, a Claude Code session whose recorded PID is gone drops to idle immediately instead of riding the 5-minute activity window. - **Hardening + fixes** ([#429](https://github.com/kbrdn1/gwm-cli/issues/429) / [#430](https://github.com/kbrdn1/gwm-cli/issues/430) / [#440](https://github.com/kbrdn1/gwm-cli/issues/440) / [#445](https://github.com/kbrdn1/gwm-cli/issues/445)): release-workflow checkouts only persist credentials when they push, the silently-failing AUR publish job is gone, `gwm clean --yes` tolerates ENOTEMPTY races from concurrent watchers, and the agent overlay's attach prompt keeps a fixed frame while typing. ## v1.0.0: the 1.0 commitment The post-`rc.4` stable delta completes the 1.0 commitment: frozen, versioned machine contracts plus the additive features that freeze anticipated. Consolidated notes: [`changelogs/1.0.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/1.0.0.md). Key additions: - **Frozen, versioned machine contracts** ([#317](https://github.com/kbrdn1/gwm-cli/issues/317)): `tests/contract_tests.rs` pins `SCHEMA_VERSION = 1`, the daemon `schema_version`, and the four machine surfaces (`--format=json` on `list` / `doctor` / `path`, plus `status --json`) against baselines; the per-field tiers live in [`docs/schema/README.md`](https://github.com/kbrdn1/gwm-cli/blob/main/docs/schema/README.md). - **Published stability & compatibility policy** ([#318](https://github.com/kbrdn1/gwm-cli/issues/318)): what's covered by SemVer versus free to change in a minor / patch, EN + FR ([Stability & compatibility](/development/stability)). - **Frozen `exec` / `clean` surface** ([#319](https://github.com/kbrdn1/gwm-cli/issues/319)): the `gwm exec` / `gwm clean` flag surface is locked for the 1.0 line (all non-frozen extensions deferred as additive), pinned by a `contract_tests` canary. - **Named `[exec]` / `[clean]` profiles + bounded `--jobs`** ([#324](https://github.com/kbrdn1/gwm-cli/issues/324)): reusable command / reclaim profiles selected with `--profile`, plus opt-in bounded parallelism (`--jobs`) for the fan-out. - **`--workspace` fan-out for `gwm exec` / `gwm clean`** ([#326](https://github.com/kbrdn1/gwm-cli/issues/326)): run the fleet chores across every repo one level below a workspace root, not just the current repo's worktrees. - **TUI exec / clean overlays** ([#325](https://github.com/kbrdn1/gwm-cli/issues/325)): `x` runs an `[exec]` profile and `X` a `[clean]` profile from inside the TUI, with a live output overlay. - **Help-overlay + overlay polish** ([#334](https://github.com/kbrdn1/gwm-cli/issues/334)): the `?` help overlay now documents every action (pinned by a completeness test), plus assorted overlay refinements. ### preceding TUI cycle: v0.9.0 The v0.9.0 line built on the v0.8.0 configurability cycle and added the TUI train: - **Full theme-role coverage** ([#170](https://github.com/kbrdn1/gwm-cli/issues/170) / [#210](https://github.com/kbrdn1/gwm-cli/issues/210) / [#211](https://github.com/kbrdn1/gwm-cli/issues/211) / [#214](https://github.com/kbrdn1/gwm-cli/issues/214)): the resolved `[theme]` is threaded through every TUI render site, with dedicated `name`, `path`, `staged`, `modified`, and `untracked` roles. Defaults are preserved and pinned by `tests/tui_theme_audit_tests.rs`. - **`git2` 0.21 source migration** ([#169](https://github.com/kbrdn1/gwm-cli/issues/169)): the breaking accessor API change from the deferred v0.8.0 bump is now handled in source, pruning the old `url` transitive tree. - **TUI statusbar, layout, and modal polish** ([#217](https://github.com/kbrdn1/gwm-cli/issues/217) / [#220](https://github.com/kbrdn1/gwm-cli/issues/220) / [#222](https://github.com/kbrdn1/gwm-cli/issues/222) / [#224](https://github.com/kbrdn1/gwm-cli/issues/224)): contextual statusbar, animated GitHub-fetch spinner, direct pane-focus keys (`1` / `2`), stacked-by-default sidebar, wider overlays, and refined create/link/delete/Issue-PR modals. - **Async-task spine** ([#231](https://github.com/kbrdn1/gwm-cli/issues/231) / [#255](https://github.com/kbrdn1/gwm-cli/issues/255) / [#258](https://github.com/kbrdn1/gwm-cli/issues/258) / [#256](https://github.com/kbrdn1/gwm-cli/issues/256)): worktree refresh, GitHub fetch, `sync` (`S`), and bootstrap (`b`) now run off-thread with coalescing, late-result drop, and statusbar progress instead of freezing the event loop. - **Pane-key family `1` / `2` / `3` / `4`** ([#226](https://github.com/kbrdn1/gwm-cli/issues/226) / [#232](https://github.com/kbrdn1/gwm-cli/issues/232)): direct focus for Worktrees / Status, a Command Logs overlay, and a Configuration panel showing the resolved config with repo / user / default source attribution. - **Docs key (`.`)** ([#233](https://github.com/kbrdn1/gwm-cli/issues/233)): open the documentation from inside the TUI; rebindable as `open_docs`. The full v0.9.0 release notes live at [`changelogs/0.9.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/0.9.0.md). The MSRV was raised to **1.86** in the v0.10.0 line by the PTY overlay's `portable-pty` / `tui-term` dependencies (`tui-term` declares `rust-version = "1.86.0"`); the current floor is stated at the top of this page. ## v0.10.0: Settings editability + TUI enrichment The first theme of v0.10.0 (originally cut as `v0.10.0-rc.1`, 2026-06-10) is **Settings editability + TUI enrichment**. RC notes: [`changelogs/pre-releases/0.10.0-rc.1.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/pre-releases/0.10.0-rc.1.md). Key additions: - **Editable Settings panel** ([#279](https://github.com/kbrdn1/gwm-cli/issues/279)): category tabs (Theme / Worktree / TUI / All), per-project ↔ global layer selector (`L`), live-persist into TOML with on-the-fly apply; herdr-style scrollbar on all scrollable modals. - **Working Tree colour-coded counts** ([#287](https://github.com/kbrdn1/gwm-cli/issues/287)): nerdfont created / modified / deleted footer counts + matching row recolouring; Status pane `Diff +ins -del` vs base (three-dot semantics). - **Issue/PR enrichment** ([#283](https://github.com/kbrdn1/gwm-cli/issues/283) / [#285](https://github.com/kbrdn1/gwm-cli/issues/285)): `●/●` pastilles in the worktree table, nerdfont state-chip badges, cached GitHub state that survives restarts, initial startup refresh, periodic `[tui].auto_refresh_secs` auto-refresh. - **Async loaders** ([#257](https://github.com/kbrdn1/gwm-cli/issues/257) / [#276](https://github.com/kbrdn1/gwm-cli/issues/276) / [#267](https://github.com/kbrdn1/gwm-cli/issues/267)): reusable `LoaderWidget`, async create-worktree and quit-wait on the spine (delete, create, and quit no longer block the render loop). ## v0.10.0: overlays, workspace, JSON API, and the GitHub inbound half The second theme of v0.10.0 (the post-rc.1 trains, `rc.2` / `rc.3`) is the larger feature batch: embedded overlays, multi-repo workspace mode, the JSON API + daemon and its first consumers, config presets, fleet chores, and the TOFU trust ledger. Per-RC deltas live under [`changelogs/pre-releases/`](https://github.com/kbrdn1/gwm-cli/tree/main/changelogs/pre-releases). Key additions: - **Embedded PTY overlays** ([#35](https://github.com/kbrdn1/gwm-cli/issues/35)): `l` / `L` open lazygit, `r` / `R` open the configured review tool, and `o` / `O` open a native `$SHELL` session inside the TUI (no alternate-screen swap; `Esc` closes), powered by `portable-pty` + `tui-term`. This is what raised the project MSRV to **1.86**. - **TUI keymap redesign** ([#290](https://github.com/kbrdn1/gwm-cli/issues/290)): unified list-view bindings (`p` / `P` pull / push, `c` edit-worktree, `e` exit-to-worktree, `y` / `w` yank, `t` mux pane, `h` / `H` macros) plus user-defined `[tui.macro1]` / `[tui.macro2]`. Pre-#290 slugs still load via backward-compat aliases. - **Rebindable contextual modal keys** ([#219](https://github.com/kbrdn1/gwm-cli/issues/219) / [#294](https://github.com/kbrdn1/gwm-cli/issues/294)): every modal verb is remappable under nested `[tui.keys.modal.]` tables, and the Settings panel gains a **Keys** tab to edit every binding live (keystroke capture + validated write-back). - **Multi-repo workspace mode** ([#36](https://github.com/kbrdn1/gwm-cli/issues/36)): `gwm --workspace ~/Projects` (and bare-`gwm` auto-detect) opens the TUI across every git repo one level below a root with a REPO column; `gwm list --workspace` prints the merged table; `gwm create --repo ` picks the target. - **Config presets** ([#37](https://github.com/kbrdn1/gwm-cli/issues/37)): `gwm init --preset ` seeds an opinionated `.gwm.toml` for `laravel` / `node` / `nuxt` / `rust` / `go` / `python-uv` / `generic`; `--list-presets` enumerates them, `--show` prints the resolved TOML without writing. - **JSON API + daemon** ([#38](https://github.com/kbrdn1/gwm-cli/issues/38)): `--format=json` on `gwm list` / `doctor` / `path` (stable schemas under `docs/schema/`), and `gwm daemon`, a JSON-RPC 2.0 server over a unix socket with `list` / `doctor` / `path` methods plus a `subscribe` push stream, for editor / statusbar integration. - **Status sidebar** ([#299](https://github.com/kbrdn1/gwm-cli/issues/299) / [#300](https://github.com/kbrdn1/gwm-cli/issues/300)): the Issue/PR section surfaces the linked PR's overall CI state (passing / failing / running, derived from the already-fetched rollup), and the Working Tree pane renders `git status` as a git-coloured nerd-font file-explorer tree. - **Inbound GitHub: `gwm review `** ([#308](https://github.com/kbrdn1/gwm-cli/issues/308)): materialise an existing GitHub PR (cross-fork aware) into an isolated worktree by fetching `refs/pull//head` and creating a `review/pr--…` branch, so you can check out a teammate's PR to review / test / fix it. Safe-by-default: bootstrap and lifecycle hooks are **off** unless you pass `--bootstrap` (the PR's code is untrusted input); `--name` overrides the local branch name. This closes the inbound half of the worktree⇄GitHub loop and turns the CI indicator (#299) into a complete review workflow. - **First daemon consumer: `gwm statusline`** ([#309](https://github.com/kbrdn1/gwm-cli/issues/309)): a dependency-free one-line worktree summary for shell prompts (tmux / starship / zsh), the first real client of `gwm daemon` (#38). Prints once by default; `--watch` rides the `subscribe` push stream and reprints on every change; `--socket` overrides the socket path. Degrades to a blank line when no daemon is running. - **Fleet chores across worktrees** ([#313](https://github.com/kbrdn1/gwm-cli/issues/313)): `gwm exec [...] -- ` runs a command in each worktree sequentially (every non-main worktree by default, or the slugs listed before `--`; everything after `--` is forwarded verbatim), prints a per-worktree `✓ / ✗` rollup, and exits non-zero if any failed. `gwm clean [...] [--yes]` reports, and with `--yes` reclaims, heavy build artifacts (`target/`, `node_modules/`, `dist/`, `build/`); `--yes` only deletes directories git treats as ignored, so a tracked `dist/` or `build/` is skipped. - **TOFU trust ledger on `.gwm.toml`** ([#95](https://github.com/kbrdn1/gwm-cli/issues/95)): the first `gwm create` / `gwm bootstrap` against a repo prints the bootstrap surface and prompts before running it; an approval is recorded in `$XDG_CONFIG_HOME/gwm/trust.toml` keyed on `(origin URL, sha256 of .gwm.toml)`, and any byte change re-prompts. For non-interactive environments, the global `--allow-bootstrap` flag (or `GWM_ALLOW_BOOTSTRAP=1`) bypasses the prompt and `--deny-bootstrap` refuses bootstrap outright. Inspect and manage the ledger with `gwm trust list` / `gwm trust revoke ` / `gwm trust show`. ## previous stable cycle: v0.8.0 For reference, **v0.8.0** promoted the large configurability and personalisation cycle: - **Release hardening, Windows CI, CLI aliases, and Gitmoji tooling** (`v0.8.0-rc.1`, [#146](https://github.com/kbrdn1/gwm-cli/issues/146) / [#147](https://github.com/kbrdn1/gwm-cli/issues/147) / [#112](https://github.com/kbrdn1/gwm-cli/issues/112) / [#85](https://github.com/kbrdn1/gwm-cli/issues/85) / [#86](https://github.com/kbrdn1/gwm-cli/issues/86)): reliable release publishing, `[Unreleased]` duplicate guard, `windows-latest` in the test matrix, `[aliases]`, `gwm commit-prefix`, `gwm types --gitmoji`, and an opt-in `commit-msg` hook. - **Safety daily** (`v0.8.0-rc.2`, [#29](https://github.com/kbrdn1/gwm-cli/issues/29) / [#31](https://github.com/kbrdn1/gwm-cli/issues/31)): `--dry-run` on `gwm remove` / `gwm prune`, plus `gwm undo` / `gwm history` backed by `$XDG_DATA_HOME/gwm/history.toml`. - **Config CLI, lifecycle hooks, GitHub templates, and TUI personalisation** (`v0.8.0-rc.3`, [#88](https://github.com/kbrdn1/gwm-cli/issues/88) / [#89](https://github.com/kbrdn1/gwm-cli/issues/89) / [#83](https://github.com/kbrdn1/gwm-cli/issues/83) / [#84](https://github.com/kbrdn1/gwm-cli/issues/84) / [#87](https://github.com/kbrdn1/gwm-cli/issues/87) / [#32](https://github.com/kbrdn1/gwm-cli/issues/32) / [#33](https://github.com/kbrdn1/gwm-cli/issues/33) / [#34](https://github.com/kbrdn1/gwm-cli/issues/34)): `gwm config`, `[hooks.*]`, `gwm new`, `gwm pr`, remappable `[tui.keys]`, the `:` command palette, role-based `[theme]` presets, and sidebar stashes mode. - **Quick wins** (`v0.8.0-rc.4`, [#24](https://github.com/kbrdn1/gwm-cli/issues/24) / [#27](https://github.com/kbrdn1/gwm-cli/issues/27)): `gwm sync [] [--merge]` and `cargo-binstall` support. - **Global config and chrome polish** (`v0.8.0-rc.5`, [#190](https://github.com/kbrdn1/gwm-cli/issues/190) / [#188](https://github.com/kbrdn1/gwm-cli/issues/188) / [#185](https://github.com/kbrdn1/gwm-cli/issues/185) / [#187](https://github.com/kbrdn1/gwm-cli/issues/187) / [#180](https://github.com/kbrdn1/gwm-cli/issues/180) / [#179](https://github.com/kbrdn1/gwm-cli/issues/179) / [#181](https://github.com/kbrdn1/gwm-cli/issues/181) / [#175](https://github.com/kbrdn1/gwm-cli/issues/175)): user-level `~/.config/gwm/config.toml`, responsive sidebar, `claude-dark`, modal polish, single-line statusline, working-tree colourisation, ephemeral PR auto-detection, and `{repo_path}` / `{repo_parent}` placeholders. The full v0.8.0 notes live at [`changelogs/0.8.0.md`](https://github.com/kbrdn1/gwm-cli/blob/main/changelogs/0.8.0.md). ## what's next The lot below shipped in the **v1.7.0** cut (2026-08-12), in the order the root [`ROADMAP.md`](https://github.com/kbrdn1/gwm-cli/blob/main/ROADMAP.md) lists it. The order is not by size: each step sits where it is cheapest to land, which usually means ahead of the thing that would otherwise have to be reopened to accommodate it. - **Bulk selection** ([#484](https://github.com/kbrdn1/gwm-cli/issues/484) ✅, merged into `dev`, awaiting the cut): `Space` marks a row and `d` deletes the marked set behind one confirm, with `gwm remove a b c` as the non-interactive half. It went first because it changes what "the current row" means, and the two features behind it both open on the current row. Only `d` reads the mark set, by design: every other verb keeps acting on the cursor row, and the pane footer carries the count so a live selection is never invisible. `cycle_sidebar_layout` moved off `Space` onto `z` to make room. - **Symfony preset** ([#392](https://github.com/kbrdn1/gwm-cli/issues/392) ✅): a seventh `gwm init --preset`, merged and waiting for the cut. Modelled on the Laravel one but not a copy of it: Symfony commits `.env` and gitignores `.env.local`, the reverse of Laravel, so the preset copies the local override and seeds its guard from the committed `.env`. It was queued here as the one item sequenced against nothing, which held for the merge order but not for its reach: every stack preset puts its commands in `[hooks.*]`, and two `gwm doctor` checks read `[[bootstrap.command]]` only, so the preset arrived with a clean report about a file the doctor had barely read. Fixed alongside it. - **Rich PR / Issue view** ([#420](https://github.com/kbrdn1/gwm-cli/issues/420) ✅): metadata, checks, reviews and comments in the TUI. It was deliberately queued behind multi-forge so it is born speaking to both forges rather than being rewritten later. `I` opens it on the description, the metadata, the CI rollup, the reviews and the conversation, at no extra request: the fields ride along in the call gwm already made for the rollup. The comments anchored to a diff hunk followed in [#528](https://github.com/kbrdn1/gwm-cli/issues/528): GraphQL-only, so they landed as a second transport rather than a wider field list, on a request the view fires for itself so `gwm status` does not pay for it. - **Per-worktree notes** ([#515](https://github.com/kbrdn1/gwm-cli/issues/515) ✅): gwm knows the branch, the linked issue, the diff and the agent session, but nothing of where you were. A note attached to a worktree, editable from the TUI, closes the gap between holding eight worktrees and remembering what each one was for. `N` opens it in an editable modal rather than suspending the TUI for `$EDITOR`, since a note is usually three lines written between two thoughts; `Ctrl+e` inside still hands the file to the editor and reloads what it wrote. Storage is a plain markdown file under `.git/gwm/notes/` in the main checkout, which survives `gwm remove` and needs no sweeper, since "the branch is gone" is a question git answers in one call. - **Container execution** ([#421](https://github.com/kbrdn1/gwm-cli/issues/421) ✅): a `[container]` block on an `exec` profile. It left the deferred pile because the comparison page now sits behind it, and container execution is a column in that table. The cost is not the wrapper but the mount: a linked worktree's `.git` is a file holding an absolute host path, so mounting the worktree alone yields a container in which git does not answer, which is a bug the reference implementation ships. gwm mirrors host paths and mounts the main checkout's gitdir alongside. Three fields rather than the reference's nine (`image`, `runtime`, `extra_args`), because `-w` / `-e` / `-v` are already `docker run` flags; no `interactive`, since a TTY per container means nothing across a fan-out; and profile-only, because the inline `gwm exec -- ` is the frozen 1.0 surface. - **Comparison page** ([#422](https://github.com/kbrdn1/gwm-cli/issues/422) ✅): gwm against gwq and lazyworktree, shipped at [Comparison](/comparison) in English and French. The issue's premise did not survive the re-read it asked for: it listed agent sessions, container execution, GitLab and per-worktree metadata as lazyworktree's lead, and gwm now has all four, so the page reports parity there instead of a gap. Re-measured on 2026-08-12, the star spread narrowed from 30 / 270 / 456 to 126 / 281 / 461, and neither competitor carries a git binding in its `go.mod`, which turns the vendored-libgit2 difference into something checkable rather than claimed. What stays ahead is named: lazyworktree's rich worktree metadata, its per-worktree `.wt` hooks, and seven more months of use. - **Docs in German, Spanish and Japanese** ([#522](https://github.com/kbrdn1/gwm-cli/issues/522)): five locales instead of two, last in the lot and after the comparison page. The audience data does not ask for it, so it is a forward bet, and each language carries a different one: German is the largest non-English bloc already reading the project, Spanish buys reach that does not exist yet, and Japanese is the one with a competitive argument, since the incumbent gwm is positioned against is Japanese-authored. Roughly 155,000 words, which is worth naming before it is scheduled. Three launch prerequisites are tracked alongside the lot rather than inside it: re-recording the demo GIF ([#523](https://github.com/kbrdn1/gwm-cli/issues/523)), the 26 documentation pages out of 41 that carry no image ([#524](https://github.com/kbrdn1/gwm-cli/issues/524)), and the directory and search-index submissions ([#525](https://github.com/kbrdn1/gwm-cli/issues/525)). The naming-flexibility line ([#415](https://github.com/kbrdn1/gwm-cli/issues/415) through [#418](https://github.com/kbrdn1/gwm-cli/issues/418), plus [#475](https://github.com/kbrdn1/gwm-cli/issues/475) and [#479](https://github.com/kbrdn1/gwm-cli/issues/479) to [#482](https://github.com/kbrdn1/gwm-cli/issues/482)) shipped in v1.6.0 and is closed. Publishing the documentation ([#423](https://github.com/kbrdn1/gwm-cli/issues/423)) shipped in v1.6.1. For fresh work, start from the issue tracker: - [Open issues: `enhancement`](https://github.com/kbrdn1/gwm-cli/issues?q=is%3Aopen+label%3Aenhancement) - [Open issues: `good first issue`](https://github.com/kbrdn1/gwm-cli/issues?q=is%3Aopen+label%3A%22good+first+issue%22) - [Open issues: `roadmap`](https://github.com/kbrdn1/gwm-cli/issues?q=is%3Aopen+label%3Aroadmap) ## how to contribute 1. Pick an issue or open a new one with `--label enhancement` / `--label bug` describing the scope. 2. `gwm create ` to spin up an isolated worktree (the issue auto-links itself; see [GitHub linking](/integrations/github-linking#auto-detection)). 3. Follow the conventions in [`CONTRIBUTING.md`](https://github.com/kbrdn1/gwm-cli/blob/main/CONTRIBUTING.md). See [Contributing](/development/contributing) for the docs-site version. 4. Open a PR targeting `dev`. Stable releases ship via a `dev → main` merge PR following the convention `🔀 chore(release): merge dev → main for vX.Y.Z`.