Releases: hongnoul/gwae
Release list
v1.0.1
v1.0.1
A maintenance release about staying out of the way: an idle session no longer
warms the laptop, and quitting gwae now really does take its processes with it,
whichever way you quit.
Fixed
-
Quitting gwae leaves nothing running. The force-quit overlay promises
running commands are terminated immediately, and that is the one moment a
user trusts a multiplexer. It was only true for jobs that stayed in the
pane's process group:nohup thing &, asetsiddaemon, or anything a
pane's shell put in its own group via job control all survived and kept
running with no window left to find them in. Teardown now walks the real
process tree (collected before the root is signalled, since a dead root's
children are reparented to init and become unfindable) and kills the group,
the root, and every descendant deepest-first. -
Being killed tears down the panes too, not just quitting.
kill gwae,
closing the host terminal window (SIGHUP), a panic, or a failure during
startup all bypassed teardown entirely and leaked the same detached work.
Every exit path now funnels into one reaper: signal handlers for
HUP/TERM/INT/QUIT, a panic hook, a drop guard over the TUI, and a final
sweep on the normal path. The signal path does only async-signal-safe work
and hands the process-table walk to a thread parked since startup, waiting
on it with a 2s bound, because a mux that refuses to die when told to is
worse than one that leaks. gwae still dies of the signal it was sent, so
supervisors reading128+signosee the truth, and the terminal is handed
back usable (alternate screen left, cursor shown) instead of stranding you
in a black rectangle. -
An idle session no longer burns ~3.5% of a core. With nothing on screen
changing, the render loop still polled the terminal size 500x a second; on
macOS each of those opens and closes/dev/tty, which was ~75% of gwae's
entire CPU time. The size check is now a 250ms backstop (the event path
still handles every resize the host reports, instantly), and the input poll
relaxes to 30ms after 750ms of quiet, snapping back on the first keystroke
or byte of pane output. Measured on an idle 200x50 session: 3.4% -> 0.9%. -
macOS: keystrokes dropped until you click, after switching Spaces. kitty
in native fullscreen owns its own Space; returning to it leaves the window
AXMainbut never key, so GLFW believes nothing is focused and discards
every keystroke. kitty 0.48.2 carries the upstream fix for the windowed case
but it is guarded on!focusedWindowIdand does not cover native
fullscreen.docs/MACOS-FOCUS.mddocuments both remedies and ships
gwae-focus-fix, an NSWorkspace observer that re-focuses the window.
Changed
- The E2E harness no longer hangs on an animating screen.
press()drained
"until output goes quiet", which never happens once the onboarding banner
animates, andscreen()could capture a half-written frame. Draining is now
bounded andscreen()returns a frame known to have been written end to
end, so the suite reports a result instead of having to be killed by hand.
Commits
- fix(windows): reap's registry helpers were dead code off unix
- style: rustfmt the preview_e2e screen selector
- tests: preview_e2e read a truncated screen when the flow does not animate
- release: v1.0.1
- Kill every pane's processes however gwae exits, not just on quit
- tests: stop preview_e2e hanging forever on an animating flow
- fix: quitting left detached pane jobs running forever
- perf: stop the idle mux burning ~3.5% of a core (hot laptop)
- docs: fix macOS keystrokes dropped until click after Space switch
- tests: dismiss the startup HUD in the in-pane splash e2e
- roadmap: plan alt+y yank (pane/turn, text or image) with context default
- astrophile: snapshot
- Update demo use case description in README
- astrophile: snapshot #4 (AUR live)
- packaging: sync AUR PKGBUILD with published gwae-bin (per-arch sources)
- dist: AUR gwae-bin 1.0.0 published, checklist Phase 1 complete
- astrophile: snapshot
- geo: llms.txt install section lists Homebrew tap and crates.io
- astrophile: snapshot #3
- dist: crates.io live (4 crates at 1.0.0), niri thread posted, cargo install from registry
- packaging: version fields on path deps for crates.io publish
- astrophile: snapshot #2
- dist: Homebrew tap live (hongnoul/tap/gwae); niri thread draft; checklist blockers
- packaging: crates.io keywords/categories for gwae and gwae-layout
- Update README.md
- Update README.md
- Revise project description in README.md
- Fix typo in README description
- Rephrase project description in README.md
- growth: real launch copy in drafts (show-hn, reddit, awesome-lists, checklist)
- growth: astrophile protocol infra
- geo: add llms.txt and examples/ (audit 33/33)
- Update README to improve clarity of demo speed note
- Update demo use case description in README
- Update README.md
- Update README.md
- Update README.md
- docs: link btm and OneTriangle in README
- Revise README for clarity and platform details
- Revise demo use case wording in README
- Revise demo video description in README
- docs: render demo inline as centered GIF, link mp4 for full quality
- docs: merge launch narrative, benchmarks, and stack into README; add logo and demo video
- packaging: update checksums for the re-cut gwae-named v1.0.0 assets
Full changelog: v1.0.0...v1.0.1
v1.0.0
v1.0.0
First stable release. gwae ships as one static binary for macOS, Linux,
and Windows with the scrolling strip grid, quantized viewport, OSC 133 agent
dashboard, smart-jump, guided onboarding, Kitty graphics passthrough, theme
presets, and live-PTY E2E coverage. MIT licensed.
Added
-
⌥+↑/⌥+↓read back through a pane's scrollback. With the wheel no
longer claimed by gwae (see Removed), the keyboard is the only route into
a pane's history, so it needed one:⌥+↑/⌥+↓move three rows a notch, and
⌥+Shift+↑/↓or⌥+PageUp/PageDownmove about a screenful. Typing snaps the
pane back to live, and a full-screen app on the alternate screen (vim,
less) has no scrollback of ours to move, so it gets the arrow keys it
expects instead. Covered bytests/scrollback_e2e.rs, which drives the real
binary and reconstructs the painted screen. -
Onboarding offers to install
btm. The last question of the guided setup
offers bottom, the system monitor
that makes a good permanent neighbour to an agent pane, defaulting to yes. On
macOS a yes installs Homebrew first when it is missing: that is gwae's
implementation detail, so it happens silently rather than becoming a second
question about a package manager the user may never have heard of. The offer
is skipped entirely whenbtmis already installed (a question whose only
honest answer is "already done" teaches people that setup asks things it
already knows), andGWAE_NO_INSTALL=1turns it off for unattended runs.
The summary reports what actually happened on the machine, not what was
answered: "yes" and "installed" are different claims. -
gwae tunereports input latency across all three layers. A keystroke
crosses macOS, your terminal, and gwae — and gwae twice, since what
you see is the program's echo making the return trip. Tuning only gwae's
own knob therefore fixes a third of the problem.tuneprobes all three and
says which are slower than they need to be, with the exact command for each.
It writes only gwae's own config; macOS globals and your terminal's
config are printed for you to apply, never edited silently. First-run
onboarding offers the same thing once, right after you pick an agent, and
stays silent when there is nothing to fix.doctorcarries a summary line,
anddocs/LATENCY.mdexplains the reasoning (including why removing
gwae's wait entirely would make typing worse, not better). -
The first pane opens on your agent, not a bare shell. gwae exists to
drive agent harnesses, but every launch dropped you at a shell prompt to
type the harness name yourself. Pane 1.1 now runs the same agent gateway
⌥+;uses, so startup has exactly two outcomes: your configured agent is
already running, or you get the selector and pick one (which is then saved,
making every later launch the first case).gwae run <cmd>still wins,
since that is you being specific. -
Detection is no longer limited to an allowlist. The picker only knew a
fixed list of harnesses, so anything newer than the release — or a personal
wrapper script — was invisible. It now merges three sources:agentsfrom
your config, the names it can label, and a scan ofPATHfor agent-shaped
commands. You can also just type a command at the prompt. The scan skips
system directories, without which a stock macOSPATHoffersssh-agent,
KernelEventAgent,b64encodeand the disk toolgptabove the real
entries. -
⌥+;now works before you have picked an agent. It randefault_agent
blind, so on a machine without that harness installed the pane's child died
the instant it spawned and left a blank box with no explanation — the same
thing that happens if you typo the command. The key now opens an agent
gateway (gwae agent) in the pane: whendefault_agentresolves it
execs it immediately and paints nothing, and otherwise it lists the
harnesses actually found on yourPATH(jcode,claude,codex,
gemini,opencode,crush,aider,cursor-agent,amp,goose),
runs the one you choose, and saves it asdefault_agentso the next;is
instant. Choosing nothing, or having nothing installed, opens a plain
$SHELLwith a note saying why. Because the gatewayexecs, the pane's
process is the harness: same pid, same PTY, and its own window title still
reaches the host.gwae doctorreports the same resolution, and
gwae agent --printshows it without prompting or running anything. -
⌥+<number>reaches columns past 9.⌥+1..9jumped on the keystroke,
which capped addressable columns at nine: there is no⌥+10key, so a wide
strip could only be reached by walking⌥+l. Holding⌥is already a mode
(it reveals the HUD/minimap), so digits typed while it is down now accumulate
into one number and commit when the modifier is released —⌥+12
focuses column 12. A pending number is echoed along the bottom row so a
half-typed address is never mistaken for a dropped keystroke. Terminals that
do not report a bare⌥release (no Kitty keyboard protocol) commit on a
500ms idle instead, and any other chord commits immediately, so single-digit
jumps feel exactly as they did.
Changed
-
Onboarding is one question per screen, driven with the arrow keys. The
guided setup was a single long transcript of numbered lists that scrolled
past as you answered, and every question needed a number followed by Enter.
It now clears to one question at a time:↑↓orj/kmoves the highlight,
→/l/⏎goes to the next question,←/h/⌫goes back to the
previous one with your earlier answer still selected, and a digit picks an
option outright without an Enter. The flow ends on a summary screen listing
every setting as it now stands and the file it landed in — itself a step you
can back out of, so an answer you regret on the way out is fixable without
re-running setup. -
Latency tuning is applied silently, before the first question. It used to
be a prompt at the end of onboarding, which asked users to adjudicate a
number they cannot evaluate.input_poll_mshas exactly one right answer, so
gwae now sets it in its own config file before setup draws anything, and
the summary screen reports only what is left for the user to do (kitty and
macOS settings, which gwae will never edit for them). -
The inset skeleton frames now ship off. Framing every column and insetting
its content by a cell is a strong look, and it was both the default and a
setup question. Panes are now full-bleed out of the box, with focus shown as
an accent background tint;skeleton = truebrings the frames back for
anyone who wants them, and setup no longer asks. Placeholder boxes are no
longer coupled to the frames, so an empty grid still shows where panes go
(and still advertises the keybindings via[cowsay]) either way. -
default_agentnow defaults to unset rather than"jcode". Defaulting
to one vendor's harness meant every user who had not installed that tool
hit the dead-pane path above on their first⌥+;. Unset is now a normal
state that the gateway resolves interactively, so first run works no matter
which agent you use. An explicitdefault_agentkeeps behaving exactly as
before. -
Key hints now name the platform's own modifier. The cowsay hints and the
cheat-sheet HUD hard-coded macOS vocabulary (⌥,↵,⇧), which is
meaningless on Linux/Windows where the same key isAltand the glyphs may
not even exist in the terminal font. Both surfaces resolve key names through
a newkeysmodule, so they readAlt+g/Enteroff macOS and can never
disagree with each other.
Removed
- Mouse wheel scrollback, and the
mouse/scroll_lineskeys. gwae
captured the wheel to scroll the pane under the cursor, which meant it also
had to translate the wheel into arrow keys for alt-screen pagers, and it put
two knobs in the config (and two questions in setup) for behavior most users
never asked to change. The wheel now goes to a child that requested mouse
reporting, verbatim in its own coordinates, and nowhere else. Mouse capture
itself stays on, since click-to-focus and drag-to-copy depend on it. Old
configs keep loading: the keys are simply no longer read. Scrollback moves
with the new⌥+↑/↓binding below.
Fixed
- Hints no longer teach bindings that do not exist. The default cowsay list
advertisedcfor "new pane" (never implemented) and told users to "press ;"
with no modifier at all, which just types a semicolon into the focused pane;
the HUD listed the same phantomcand labelledqas "quit" when it kills
a pane (⇧qquits). The hint list is rewritten from the real key table and
covered by tests that fail if a hint names a dead binding.
Added
- Empty grid cells now document themselves with a cowsay hint: an empty
placeholder box showed only its big block-fontstrip.cellidentifier, which
says where you are but not what to do about it. Each empty box now draws a
small cow under the identifier speaking a keybinding hint (Alt-Enter opens a column here,Press ; to spawn an agent, ...), so a fresh workspace teaches
its own bindings. The art is generated in-process (nocowsay(1)dependency)
and wrapped to the box width. Which box says what is chosen by hashing the
cell's position, never randomly, so a box always says the same thing and idle
gwae still paints zero cells per frame. The identifier always wins: boxes
too narrow (under 23 cells) or too short for both degrade to the label alone
rather than a clipped cow. Configure via[cowsay]enabled/messages;
both are picked up by live config reload. - Kitty graphics passthrough: images now render inside panes: vt100 (the
hosted emulator) sil...