Skip to content

Releases: cjairm/devgeta

v1.40.2

Choose a tag to compare

@github-actions github-actions released this 29 Sep 21:58

fix(opencode): stop the notify plugin from crashing OpenCode at startup

After v1.40.1, OpenCode failed to start. Its log showed
"plugin config hook failed ... evaluating 'N.config'". After upgrading, run
dg configure opencode --force to replace the broken deployed plugin.

  • Stop exporting exitFallbackSync from the notify.js plugin. OpenCode's
    plugin loader calls every exported function in a plugin file as a plugin and
    reads .config on what it returns. This helper returns nothing, so the read
    threw and OpenCode could not start. Its tests now go through Notify's
    existing sync-exec parameter, which also covers the real exit-listener
    wiring.
  • Make the plugin loader-safety test await each export's result and fail when
    it is undefined or null. The old test only checked that each export was a
    function and did not throw, so it could not catch this crash.

Full Changelog: v1.40.1...v1.40.2

v1.40.1

Choose a tag to compare

@github-actions github-actions released this 29 Sep 17:14

fix(ws): list agents that worktree layouts start, even while their shell wrapper shows

Some running agents were missing from the AGENTS section of dg ws, even though
their Claude Code process was alive and the pane was marked as an agent.

  • A coder started as <coder>; exec <shell> (how worktree layouts launch them)
    shows the wrapper shell as its current command for its whole life. The agent
    check read that as "the coder exited, only a prompt is left" and hid the pane.
    tmux's own fields cannot tell that wrapper from a real leftover prompt, so the
    scan now asks whether the pane's process still has a child. A child means the
    coder is running and the pane is listed; none means it stays hidden.
  • The extra check is one ps call per scan, and only when a pane in that state
    exists. ADR-0055 records the change and why it bends ADR-0024.

Full Changelog: v1.40.0...v1.40.1

v1.40.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 14:25

feat(ws): list a repo's plain windows as their own rows, and close one with d d

In dg ws, a repo with extra tmux windows (say a node window and a zsh
window next to its worktree) showed a single row named after the session,
usually the same name as the repo. Enter on it reached only the first of those
windows. The rest could not be seen or picked. Each plain window now gets its
own row under the repo, named by the window.

  • One row per plain window, before the repo's worktree rows. The session name
    is no longer shown, because the repo header already says where you are.
  • Enter switches to that exact window. Rows are keyed by tmux's window id, not
    the window's name: tmux auto-names every shell zsh, and a name lookup could
    land in the wrong window.
  • d d on a window row closes that window only. Its session and the other
    windows in it stay.
  • n on a window row (or a pane row under it) offers that repo first in the
    picker, as it already did from a worktree row.
  • The dashboard opens with the cursor on the window you came from.

Behavior changes: the repo-session row is gone. $ (rename session) no longer
works from a repo's rows. Use tmux's own keys, or $ on a standalone session
row. d d from a repo's row used to close all of that session's plain windows.
It now closes only the window under the cursor.

Full Changelog: v1.39.0...v1.40.0

v1.39.0

Choose a tag to compare

@github-actions github-actions released this 29 Sep 00:10

feat(ws): close agents with dd, scroll with the wheel, and fix ctrl+h/j/k/l in the dashboard

In dg ws, ctrl+h/j/k/l never reached the dashboard: tmux moved panes
instead, so you couldn't jump between the spaces and agents sections (only
ctrl+shift worked, by accident). This release fixes that, fills in the parts of
the agents-section design that were missing, and stops dg configure from
deploying an older build's configs.

  • Fix the tmux pass-through for the dashboard. The check for devgeta ws sat in
    a second if-shell nested inside the Vim check, and tmux strips escapes once
    more in a nested command, so its pattern reached grep broken and never
    matched. Both checks now share one if-shell "$is_vim || $is_dgws".
  • d d on an agent row closes that agent's pane only, with the same two-press
    confirm as every other d. Other panes in the window (an editor next to the
    coder) stay open; it never deletes a worktree or kills a session itself.
  • The mouse wheel scrolls whatever is under the pointer: over a section it moves
    that section's cursor and stops at its ends, over the diff it scrolls three
    lines a notch.
  • While filtering, the text each row matched on is highlighted in both sections.
  • dg configure no longer deploys stale configs from a local build. The
    unpacked config folder was named by version and commit only, which every
    build of one commit with uncommitted changes shares, so a later build reused
    an earlier build's hooks and templates. The name now includes a fingerprint
    of the embedded configs, so any change unpacks fresh.

Behavior changes: plain ctrl+h/j/k/l now move within the dashboard and hand
off to the next tmux pane at its edges. d in the agents section now arms a
close instead of doing nothing.

Migration: after upgrading, run dg configure tmux --force to load the fixed
bindings (it reloads tmux when run inside it).

Full Changelog: v1.38.1...v1.39.0

v1.38.1

Choose a tag to compare

@github-actions github-actions released this 28 Sep 23:29

fix(ws): list coders that worktree layouts start, not just ones typed into a shell

A coder started by a worktree layout was missing from the dashboard's AGENTS
section, so a worktree running two agents showed only one. Layouts launch the
coder as zsh -c '<coder>', which makes tmux report the pane's program as
zsh for the coder's whole life, and the "pane is back to a plain shell" check
treated it as a coder that had exited.

  • The shell check now applies only to a pane that falls back to a shell when its
    program exits: one started as tmux's default shell, the shell by name or
    $SHELL, or a command that ends by exec'ing a shell (<coder>; exec zsh,
    tmux-resurrect's restored panes). Any other pane closes when its command
    exits, so a shell there is only the wrapper around a running coder.
  • The dashboard's 3-second tmux scan reads each pane's start command for this,
    still in its one existing tmux call.

Full Changelog: v1.38.0...v1.38.1

v1.38.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 23:22

feat(ws): list every AI agent in its own dashboard section, with its state and coder

Finding the agent that needed you in dg ws meant reading dot colors across the
whole tree, including windows that only ran Neovim or a shell. The dashboard now
has two sections: SPACES (repos, worktrees and sessions, with no status markers)
and AGENTS, one flat list of every Claude Code and OpenCode pane, most urgent
first, each with a state word and the coder's name.

  • Agents are sorted blocked > error > done > working > idle. "Done" is new: the
    agent finished and you haven't looked yet; it becomes "idle" once you have.
    enter jumps straight to the agent's pane, and the right pane shows that
    agent's worktree diff.
  • Each coder now says what it is: the Claude hooks and the OpenCode plugin
    write a @dg_agent_kind pane option on start and with every state write,
    and remove it on exit (ADR-0055). A pane that is back to a plain shell is
    never listed.
  • a folds agents and w folds spaces, in any order. A folded section becomes
    a one-line bar at the bottom of the column (the agents bar keeps a count per
    state), and the last open section can't fold. +/- or dragging the AGENTS
    header moves the split; a section that needs less space gives the rest to the
    other. Folds and split are saved with the rest of the view state.
  • / searches only the open sections; in agents it matches location, coder
    name and state word, so /blocked and /opencode work. Headers show
    "1 of 4" while filtering.
  • The dashboard takes its pane-move keys from tmux (list-keys), so your
    ctrl+h/j/k/l move between sections and the diff pane, and hand off to the
    next tmux pane at an edge (ADR-0057). The shipped tmux config passes those
    keys through to devgeta ws.
  • Repos with no open window start folded; unfolding one is remembered.

Fixes

  • A working agent no longer shows as idle. Picking it in dg ws wiped its
    busy state, and answering a permission prompt left nothing to set busy
    again. Looking at a pane now only clears states that ask for you
    (done/blocked/error), and both coders mark themselves busy again when a tool
    finishes (Claude PostToolUse, OpenCode tool.execute.after).
  • The cursor can no longer move invisibly inside a folded section, and reopening
    the dashboard with spaces folded lands on the agent in the window you came
    from.
  • A selected idle agent row, and the folded bars, no longer render as an empty
    gray bar: dim text on the selection background was the same color as the
    background.
  • The OpenCode plugin's tests could write @dg_agent_kind opencode onto the
    real tmux pane they ran in; they now never see the real pane.

Behavior changes: space rows no longer show agent status dots; agent state is
shown only in the AGENTS section. Selected idle agent rows show their text at
full brightness. Claude Code runs one extra hook after every tool call (one
tmux call when the agent is already busy).

Migration: after upgrading, run dg configure claude --force,
dg configure opencode --force and dg configure tmux --force, then restart
running coders so they load the new hooks. If you build devgeta from source
with uncommitted changes, run dg configure devgeta --force first: builds from
the same commit share one extracted config folder, so a later build can deploy
an earlier build's hooks.

Full Changelog: v1.37.0...v1.38.0

v1.37.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 22:15

feat(ws): open the dashboard on its last worktree list, with the cursor already on your row

dg ws used to open empty and show "(loading...)" until every repo's
git worktree list and the diffstat sweep finished, then move the cursor from
the top to your session's row. It now opens with the rows from last time and
the cursor already in place, while the same loads run in the background and
replace them.

  • Save the last successful worktree list (repo, name, path, branch) and its
    diffstats to $XDG_CACHE_HOME/devgeta/ws-snapshot.json after every fresh git
    load, and draw it on the first frame. Nothing from tmux is saved; sessions,
    panes and agent states always come from the live scan. A missing, corrupt or
    old-format file is ignored (ADR-0054).
  • Run one tmux scan before the first frame when a saved list exists, so the
    cursor opens on the row for the session you are in instead of jumping there.
    The cursor itself is still not saved (ADR-0050 holds). If your row is not in
    the saved list, the real git load places the cursor, as before.
  • The 3-second tmux refresh and 30-second git refresh are unchanged. Each fresh
    git load replaces what is on screen and rewrites the saved file.

Behavior changes: a worktree removed outside the dashboard still shows when
dg ws opens, until the first git load lands (usually under a second), then
disappears.

Full Changelog: v1.36.0...v1.37.0

v1.36.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 21:51

feat(ws): redraw the dashboard, give each repo its session rows, and make delete safe

dg ws is cleaner to read, remembers how you left it, shows each repo's tmux
sessions as rows you can switch to, rename and close, and can no longer delete
a worktree's unsaved work by accident.

Dashboard look

  • A flatter layout: repo headers are just the bold name, worktree rows drop
    the branch glyph and tree connectors, and standalone sessions sit under a
    dim "sessions" header.
  • Every worktree row shows its changes as a green/red +A −R on the right,
    computed on the 30-second refresh (ADR-0051).
  • The selected row gets a soft background and a yellow ▌ edge instead of a
    solid block, and keeps its own glyph and diffstat colors.
  • The hint bar is down to five keys; everything else is under ?.

Sessions

  • Each repo's tmux sessions are rows under the repo, showing the session's
    name (ADR-0052). A session holding nothing but worktree windows gets no row,
    since each of those windows already has its own.
  • enter on a session row switches to its plain window. This used to fail
    with "can't find pane" when the window's name had a dot, such as the
    "2.1.282" that Claude Code's version puts in a window title.
  • $ renames a session. New worktree windows follow the renamed session
    instead of starting a second one under the old name.
  • d d on a repo's session row closes only that session's plain windows; the
    repo's worktree windows and the session stay. On a standalone session it
    kills the session, as before.
  • h folds the repo group from a session row too.

Opening and reopening

  • Folds and the left-pane width are saved across reopens (ADR-0050).
  • The dashboard opens on the row you came from: the worktree row from a
    worktree window, the session row from a plain window. Pressing j/k while
    it is still loading is no longer undone a moment later.

Deleting a worktree never loses work unless forced (ADR-0053)

A dashboard d d could delete a worktree with uncommitted changes: the
dashboard always removed with force, and every removal ran git branch -D.

  • d d and D D refuse when the worktree has uncommitted changes (untracked
    files included) or commits that no remote branch and no local default
    branch contain, and say what is at risk. F F is the one forced delete, and
    its confirmation names what will be lost.
  • dg wt remove without --force gets the same check.
  • A removal deletes the branch git reports for the worktree. It used to pass
    the flattened folder name, so a branch like feat/login was never deleted
    (git looked for feat-login), or the wrong branch could be.

Fixes

  • The cursor no longer jumps to another row when the list refreshes, a filter
    changes, or a fold happens.
  • Folding one worktree no longer folds another whose tmux window name happens
    to collide.
  • z no longer needs two presses after folding repos by hand.
  • The diff pane no longer shows the previous row's diff, or its scroll
    position, after moving to a new row. Long diffs are cut at a line boundary.

Behavior changes: dg wt remove without --force now refuses a worktree
whose branch has unpushed commits, where it used to delete the branch
silently. In dg ws, d d and D D refuse in the same cases, and F F is
the new forced delete.

Full Changelog: v1.35.3...v1.36.0

v1.35.3

Choose a tag to compare

@github-actions github-actions released this 23 Sep 00:24

fix(ws): stop listing every repo's own session twice on the dashboard's first frames

Opening dg ws showed each repo's tmux session as a standalone session row
next to the repo row it belongs to, then silently dropped the duplicates a
second or two later. A regression in v1.35.2.

The dashboard starts its git enumeration and its tmux scan together, and the
scan wins — it is two calls to a running server, while the enumeration spawns a
git process per repo. v1.35.2 taught the session rows to ask whether a window's
worktree still exists, but the answer they asked was an empty worktree list
that simply had not loaded yet, and an empty list reads as "no worktree backs
anything."

  • Tell "no worktrees exist" apart from "no worktree list yet". They were the
    same empty map, which is what made a loading dashboard look like a dashboard
    with nothing in it. Until the first list lands the session rows fall back to
    the window-name prefix, which can hide an orphan for one tick but can never
    double-list a repo's session.
  • Classify a session scan against the worktree list that exists when the scan
    LANDS, not one copied when the scan was ordered. The copy was taken as the
    dashboard launched, so it was empty no matter what loaded afterwards. This is
    the rule the worktree rows already followed.
  • Re-run the classification the moment the first worktree list arrives, so a
    session whose worktree window is orphaned shows up with it rather than up to
    three seconds later.

Behavior changes: none beyond removing the duplicate rows. Sessions holding a
worktree window whose worktree is gone still appear as standalone sessions,
which is what v1.35.2 added.

Full Changelog: v1.35.2...v1.35.3

v1.35.2

Choose a tag to compare

@github-actions github-actions released this 22 Sep 22:58

fix(ws): stop hiding a tmux session whose worktree window outlived its worktree

A tmux session disappeared from dg ws and had no way back. Removing a
worktree by hand — a bare git worktree remove, or an agent doing it from
inside that worktree's own window — never runs devgeta's window-kill step, so
the wt- window survives with its name intact. The dashboard hid the entire
session on the strength of that name, even though git no longer listed the
worktree. The session was still there in tmux ls, but nothing devgeta ships
could see it, list it, switch to it or clean it up.

  • Decide whether a window is worktree-backed by asking whether its worktree
    still exists, instead of matching the wt- name prefix. The prefix only
    ever proved devgeta created the window, never that anything still backs it,
    so the one case it had to get right was the one it got wrong.
  • A session whose only worktree window is orphaned is listed as a standalone
    session again, with the usual switch and kill actions on it.
  • In a session that still holds a live worktree window, an orphaned one
    alongside it now counts as a plain window, so the repo header can reach it.
    Previously no row could.

Behavior changes: sessions that were hidden because they held a stale wt-
window now appear in dg ws as standalone sessions. If you have one of these
today, it shows up as soon as you upgrade; the dead window inside it is yours
to kill from the dashboard.

Full Changelog: v1.35.1...v1.35.2