Skip to content

Releases: m4ttstack/mattstack

v2.15.0

Choose a tag to compare

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

mattstack.app can now be set up for one person with no team, rt can move a repo's stored state to a new name ahead of the repo's rename to mattstack, and every chat session gets a hidden identity behind its handle.

Just me setup (RT-328)

  • a Just me card on the Team screen installs mattstack.app for one person: no team repo, no access rows, and team-only apps such as board stay off (#523, #520)
  • Settings > Apps lists every app with a toggle and a "Needs a team" caption on a solo install; rt apps list, rt apps enable and rt apps disable are the same switches from the CLI (#523, #520)
  • Settings > Team on a solo install offers Create a team and Join a team, which re-enter setup at the Team step and turn team apps back on (#523)
  • rt team status reports mode: "solo" when no team clone exists (#520)
  • deck reads requiresTeam from each app's manifest and can idle any app: a disabled app leaves the launcher and its launch agent is uninstalled until it is re-enabled (#517)

Repo rename groundwork

  • rt repos reidentify <old> <new> moves every store rt keys by repo identity (the repo index, worktree registry and data dir, tracking, the events cursor, state.db tables, herds, editor prefs and repos.<id> settings sections) from one remote identity to another. Each store reports moved, already, none or refused; a refusal in one store never stops the others; --dry-run shows the counts first (#524)
  • the daemon runs the same move on its own when a tracked repo's remote now derives a new GitHub identity and GitHub confirms the old name redirects to it (#524)
  • the shared checkout resolves ~/Documents/GitHub/mattstack first and falls back to ~/Documents/GitHub/repo-tools, so a machine keeps working before and after the folder moves (#524)

Chat

  • every session gets a hidden identity id behind its display name, so a recycled name never inherits another agent's rooms, DMs, unread or history; existing handles keep their rows (#521)
  • rt chat sign-in --as <name or id> continues an identity and --name <name> starts a fresh one; the agent name pool grows to 1,000 (#521)

Settings

  • eleven per-repo keys (rt.roles, rt.worktrees, rt.hooks, rt.sync and others) refuse a global value instead of applying it to every repo; rt settings check reports a stray one (#518)
  • the VS Code extension now reads repo sections for the open repo, and console's effective-inputs panel reads the run's own repo (#518)

Glance and gitq

  • the group dashboard rides one shared cable instead of a watcher per MR, a late MR joins the group's push, and a single MR dashboard follows the cable's connection state (#519)
  • GitHubEventsPoller commits its tick state only after a full tick (#519)
  • gitq undo moves refs by compare-and-swap, never by checkout, checks for holding worktrees first, and resumes a partial undo (#519)

Also

  • MCP git tools accept a hand-made git worktree of a registered repo, such as <checkout>/.worktrees/<name>, and still refuse its subdirectories (#522)
  • the VS Code extension bundle is load-checked in the release (#519)
  • glitter's hovered tab button has symmetric padding (#514)
  • @mattstack/glance-react is private; it no longer publishes to npm (#516)
  • the marketplace catalog ships the current mattstack plugin (RT-338 wave 1, 0.26.1) and fast-browser plugin

Full Changelog: v2.14.0...v2.15.0

v2.14.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 15:05

One repo now builds the whole suite: the apps, glance and gitq were folded into rt with their history, so mattstack.app ships board, console, chat, boxscore, deck and gitq from the tagged commit. Agents reach rt through MCP tools instead of Bash for MRs, runs, worktrees, herds and chat, with credentials redacted from every result.

Monorepo

  • m4ttstack/apps, m4ttstack/glance and m4ttstack/gitq live in this repo as apps/*, packages/* and apps/gitq, imported as merge commits with full history; the old repos are read-only from here on (#489, #499, #502)
  • rt-client, settings-kit and tui-kit are private workspace packages built by the root install; nothing publishes them anymore
  • the release builds every bundled app from the tagged commit (scripts/build-apps.ts), so an app change merged to main is in the next release by construction; only fast-browser stays a pinned download
  • @mattstack/glance, @mattstack/glance-react and @mattstack/gitq still publish to npm on demand from their directories; gitq's release tags gitq-v<version> and refuses a workspace dependency whose version is not on npm
  • rt release app <name> cuts a patch release for one bundled app when the diff stays inside that app, the notes and the website (#464, #469)

MCP tools (RT-326)

  • MR tools cover reads and writes on GitLab: mr_view, mr_list, mr_threads, mr_pipeline, mr_job_trace, mr_for_branch, mr_create, mr_update, mr_upload, mr_comment, mr_comment_inline, mr_reply_thread, mr_resolve_thread, mr_approve, mr_ready, mr_rebase, mr_retry, mr_map and mr_merge, so board posting no longer waits on the Bash classifier (#472, #478, #485, #491)
  • run_* tools start, stage, snapshot and answer decision runs (#488); worktree_provision, worktree_dispose and worktree_stop_holders plus the herd_* tools drive worktrees and herds, and rt_verb exposes a wider curated verb set (#497)
  • guarded git tools git_push, git_pull, git_rebase and branch_sync; a push whose upstream targets main, master or the remote default is refused (#492)
  • chat_* tools mirror every rt chat verb, and a daemon-signed-in session gets a chat session file so its tools answer with its own handle (#501, #504)
  • every tool result passes through credential redaction, so a token in an avatar URL or remote never reaches a transcript; enrich also strips userinfo from https remotes (#500, #482)
  • the daemon auto-accepts Claude Code's relocation prompt for announced attended panes (#490)
  • the mattstack skills for chat, worktrees and herdr-inject run on these tools instead of Bash; rt skills lists a pack's MCP tools, check --strict lints them with derived rules and a pack script scan, and an advisory audit flags Bash where a tool exists (#493, #505, #507, #513)
  • base Claude permissions drop the glab and rt runs rules and add the Monitor waits; the gate rule stays (#487)

Settings

  • every key has a schema, writes are validated, rt settings check verifies the real stores, and a schema lock guards breaking changes between releases (#474)
  • versioned store names with migrations and drift detection, so a key can change shape without stranding an older app (#484)
  • rt.mcp.uploadRoots widens where mr_upload may read from (#479)
  • test runs refuse to write the account's real stores (#468)

Glitter

  • opens any repo without registering it (#509)
  • the mouse wheel scrolls the view, not the selection (#510)
  • a diff line taller than the pane scrolls row by row, and a file-to-symlink typechange parses both diff blocks (#459, #454)
  • the master row hides its glyph when there are no changes, and the sidebar's tab pad and gap rows collapse

Herd

  • worker trees are pre-trusted for every account, and rendered briefs drop author-note blocks (#511, #512)
  • herd ask option labels are capped at 60 characters so a gate never waits on an overlong form (#495)
  • panes keep a real title: rt agent no longer passes --name, and pane rename drops the -- herdr keeps in the label (#471)
  • a gate can supply its own notification headline and summary (#465)

Tray

  • Discard New Build keeps the build cached instead of wasting it (#483)
  • each badged gate counts once in the dock, and badge fetches use their own connection per app host (#467, #466)
  • review changes opens in its own window, and rows stay busy until the list refresh lands (#458)

Worktrees and MRs

  • one containment rule for triage and dispose checks every tip, and the panel stops polling when closed (#470)
  • dispose accepts a HEAD already in main over a stale origin/<branch> (#460)
  • an unsynced MR's discussions are stored instead of throwing (#486)

Docs

  • rt.cool, install, onboarding and teams follow the mattstack.app setup flow and state current behaviour only (#461)
  • skills tell sessions to run /reload-plugins after a sync or init instead of restarting (#496)

CI

  • the unit suite runs as three balanced shards and a PR runs only its changed tests plus the guard tests; a go job runs beside static with runner-measured timings; superseded PR runs are cancelled (#475, #480, #457)
  • test hygiene: a test that leaves process.exitCode set fails on its own, HOME stays valid across files, daemon-logger and shutdown tests are order-independent, and leftover Go module caches are swept (#473, #462, #463, #453)
  • the dev app stage always reconciles the copied deps against deps.lock (#455)

Board 0.1.8

  • approved means GitLab says approved (#160)
  • a respond gate's row counts its threads and the status word clamps; an answered gate leaves the decision queue right away (#162)
  • notifications link to the MR's row and read in plain words (#163)
  • badges report the gate ids they count, so a run gate is never double-counted against console, and a gate settled during a relay gap stops counting (#164)
  • board and deck share one decision-gate helper, and deck's own row shows its service (#165)
  • doctor's retry and rebase go through rt's MR tools instead of glab ci retry (#167)

Console 0.1.4

  • JSON editors for every settings row and explain layer, a per-repo view with a repo picker, and a Needs fixing flow for diverged or unregistered keys, now working across repos with diverged scalars handled (#169, #494, #498)
  • the installed-caches chip says to run /reload-plugins in running sessions instead of restarting them (#496)
  • the gate-count endpoint returns the counted gate ids so the tray can dedupe against board (#164)

Deck 1.1.2

  • removing a route-only row clears its routes, and board shows remove failures (#161)

gitq

  • the bundled CLI moves from the 0.2.1 binary to the tree: cascades record and use a per-node fork point, continue keeps the resumed branch's store update and records the fork point against the final target, preflight warns when a child's fork point is unrecoverable, and the rebase engine refuses a doomed sweep instead of conflicting through it
  • transient watchman cookies no longer count as a dirty tree
  • gitq abort falls back to the leased slot when no pause file survives and only aborts a rebase that is in progress there; the board's action endpoint refuses a non-local Origin, a non-JSON body and an untracked stack (#502)
  • repos.json keys are forwarded unchanged as identities, matching rt-client's identity-keyed lookups

Boxscore and chat ship unchanged apart from boxscore's settings page taking its composite editors from the schema (#169).

Full Changelog: v2.13.1...v2.14.0

v2.13.1

Choose a tag to compare

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

A follow-up to 2.13.0: Sparkle updates install on the first click, and deck's Add app registers an app from its manifest.

Updates

  • "Install and Relaunch" now installs on the first click even with the mattstack window open. The window-close quit interception used to cancel Sparkle's quit, so the app only closed its window and the install waited for another click; Sparkle's own installer is now let through while an install is running (RT-296, #451). Updating to 2.13.1 from 2.13.0 or earlier still goes through the old app's code, so if the window only closes, click Install and Relaunch again.

Deck 1.1.1

  • Add app asks for the app's directory and registers it from its mattstack.deck.json, the same as deck register --dir (port, start command, env, action commands, name and icon); a directory without a manifest falls back to name, command and working directory (RT-297, #452)
  • Add app never changes an app that is already registered: it reports "already registered" instead of relinking or restarting it
  • the route-only "I run this myself" option is gone from Add app
  • a relative or missing directory is refused before anything registers, deck register --dir resolves a relative path, and typing in the form no longer jumps focus back to the Name field

Glitter

  • the diff pane tints added and removed rows, highlights whole files so multi-line comments and markdown headings color correctly, and soft-wraps long lines (#443)

Full Changelog: v2.13.0...v2.13.1

v2.13.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 12:10

The prod-readiness release. Opening mattstack.app on a Mac that had been running mattstack-dev now serves every bundled app on the first launch, a daemon launchd refuses to start heals itself, boxscore ships in the bundle, the window waits for deck instead of showing a 502, and setup stops registering apps one by one.

Bundled apps

  • deck 1.1.0 serves exactly the apps the bundle ships: on every start its sweep creates, adopts or fixes the rows for board, chat, console and boxscore, creates each app's data directory, and stops serving (without deleting) anything else, so switching between mattstack and mattstack-dev never destroys the other flavor's registrations (RT-280, RT-281, RT-284, #448)
  • the gitq CLI still ships and stays on your PATH; the gitq web app is no longer served by mattstack.app (RT-281, #448)
  • boxscore 0.1.0 is bundled for the first time (RT-282, #448)
  • board, chat 0.1.3 and console 0.1.3 carry their name and icon inside the bundle, so tabs are labelled on a clean install (#445, #448)
  • board 0.1.7 shows a "Board isn't set up yet" page until your team's board settings exist, instead of restarting in a loop, and switches to the real board on its own once they do (#450)
  • rt-tray/deps.lock rows can declare serve: { port, args }; a row with it is a bundled app, a row without it is a tool (#442)

Tray

  • the window holds its splash until deck answers and the app list has loaded, up to 90 seconds, then shows "Can't reach deck" with the reason and a Retry button (RT-283, #446)
  • a tab whose app answers a server error shows the failure overlay with a working Retry instead of a blank 502 page (RT-283, #446)
  • a daemon or deck that launchd refuses to start ("alive but not serving", exit 78) is healed once at launch with a clean unregister and register (RT-279, #449)
  • re-registering a launch agent waits for launchd to drop the old job before registering again, and the app records an agent as set up only after it answers (RT-279, #449)
  • a version change no longer force-restarts agents registered on the same launch, which removes the ~30 second gap before deck answered; served apps restart once, after deck is up (RT-283, #449)

Setup and uninstall

  • rt setup no longer registers board, chat, console or gitq itself; deck's sweep does it on both flavors (RT-281, RT-284, #444)
  • rt uninstall rejects arguments it does not recognise instead of running a full uninstall, and removes mattstack's apps from deck in one call (#444)

Developer tooling

  • the clean-room VM check now fails unless deck serves exactly the bundle's apps, each healthy with its icon, and checks every .mattstack route (RT-284, #447)
  • the dev app's build cache drops builds whose worktree is gone (#437)
  • rt release update-machine accepts a daemon running a later main that contains the release (#438)
  • the repo purity gate judges only commit messages a push would publish, with tests for the new range (#439, #441)
  • @mattstack/glance 0.27.0 (#440)
  • glitter's guarded branch header reads "checked out in another worktree" with a padlock glyph

Full Changelog: v2.12.0...v2.13.0

v2.12.0

Choose a tag to compare

@github-actions github-actions released this 25 Sep 02:30

The worktree triage and updater release. A new tray panel handles the worktrees left behind after a merge, connecting a forge links you straight to a token with the right scopes, and the app's updater moves to Sparkle 2.10.0.

Tray and setup

  • Worktrees… panel: every worktree left behind after its merge request merged, why it is stuck, whether its work is safe elsewhere, and one guarded action per row (dispose, keep, push the branch, review the diff, stop holders, or remove to the 14-day trash); the menu item carries a count and a daily summary notification opens the panel (#429)
  • rt worktree triage [--repo] [--json] prints the same rows in the terminal (#429)
  • dispose now accepts a branch that was rebased into its merged MR (RT-271, #429)
  • the Connect sheet links to the forge's new-token page with rt's scopes pre-checked; GitLab owners are now asked for api, and a stored token missing a scope reads invalid and names it (RT-276, #433)

Updates

  • Sparkle 2.10.0: fixes temp-file leaks when a delta update fails and re-applies filesystem compression after delta updates on macOS 27; tested both ways in the VM, from 2.11.0's Sparkle 2.9.6 and from the new updater itself (#434)

Developer tooling

  • the dev app caches builds per worktree, so switching back to a tree you already built is instant (#435)
  • rt cd's background branch-cache refresh runs in its own session, so a pane reads idle 10 to 15 seconds sooner after rt cd (#436)
  • rt release update-machine reads deck list's real table through the serving bundle's own deck, and fails closed when deck lists no managed apps (RT-274, #430)
  • the release workflow caches its dependency downloads, so an upstream outage no longer fails a release that has built before (#432)
  • the VM walkthrough dismisses Setup Assistant after boot, and its update leg accepts the v-prefixed version CI stamps into rt (#428, #434)

Documentation

  • a Glitter guide on rt.cool covering the board, the checkbox staging model, stash, history, menus, and every key (#431)
  • the tray guide covers the Worktrees panel, and the install page lists the token scopes each forge and role needs

Full Changelog: v2.11.0...v2.12.0

v2.11.0

Choose a tag to compare

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

the onboarding and agent-tools release. A new teammate reaches Install without a terminal, picks a writing style, and gets a checklist that re-checks in about 3 seconds. Agents get a curated MCP door into rt, and rt glitter grows into a GitHub Desktop style git client.

Setup and onboarding

  • onboarding UI pass over every wizard screen: team cards, checklist rows, install progress that scrolls to the running step, Done, and the connect sheet (#377)
  • writing style: a skills.writingStyle setting, rt skills writing-style show | list | use | new, and a setup row that Finish requires and that cannot be skipped, with a picker of the mattstack plugin's presets (#387)
  • Install now installs and enables the superpowers plugin; existing installs pick it up from the plugins row's one-click install (#373)
  • rt team join points a joiner's board at the team's switchboard, and a joiner reaches Install without a terminal when the team declares one (#373, #393)
  • rt home remote set <url> gives the home repo a remote from setup; the inviter is notified when an invitee replies; the Slack connect error names the real cause (#417)
  • Install seeds Claude Code's permissions.defaultMode: auto when a config dir has none, so Enterprise and Console-key sessions stop prompting for routine git (#396)
  • the baseline Claude permissions allow rt runs and rt gate, so pipeline skills stop prompting in unattended panes (#395)
  • checklist refresh drops from about 14s to about 3s: the Fast Browser rows ask fast-browser doctor for only the four checks they read (#407)
  • a Chrome Web Store install of the Fast Browser extension now reads ready, and a failing extension row shows doctor's own fix (#407)
  • Settings > Fast Browser joins a checklist load already running instead of starting a second one (#406)
  • the team screen's restore card is hidden until rt restore exists (#414)

Agents, gates and MCP

  • rt_verb: a new MCP tool in the mattstack plugin that runs a curated set of agent-safe rt verbs (#378)
  • security: compiled rt no longer loads a bunfig.toml preload or a .env from the caller's working directory (#378)
  • the AskUserQuestion hook asks the daemon via rt gate fork-check, so a pane's own run gate can be asked as a form (#391)
  • unattended panes accept Claude Code's worktree relocation prompt in its current drawing instead of stalling (#394)
  • injecting into a Claude pane sets aside anything already typed and restores it afterwards (#408)
  • gate notifications: a click opens the surface first (#362), pane-started work returns to its pane (#366), and pane-bound clicks no longer flash the shell window (#369)
  • herd escalations collapse into one summary per herd that focuses the shepherd (#388)
  • rt herd spawn and rt agent start default --account to the caller's cswap account (#367)
  • rt skills init scaffolds a team's first skills pack, and rt skills bind writes the pack's own fragment (#401)

Git client (rt glitter)

  • a GitHub Desktop style board: changes, commit, branches, worktrees and the action segment, built to the design boards (#346, #353, #354)
  • History tab (#383), stash with GitHub Desktop's own markers (#399), right-click and ctrl-k context menu (#389)
  • live status for the current worktree and animated spinners (#400), hover on every interactive region (#360)
  • create branches and provision worktrees from the foldouts, and list worktrees git knows about beyond rt's registry (#357, #365, #368)
  • publish a repository with no remote through gh (#420)
  • polish and follow-ups (#363, #405), plus a whole-binary pty test gate (#356, #392)

Worktrees

  • on-deck worktrees build by cloning a golden donor's installed artifacts instead of a cold install, on replenish and on provision (#359, #364, #370, #371)
  • merged worktrees stranded by herds and orphans are disposed (#410)
  • missing GitHub tokens and untracked repos no longer silently disable PR state and merge cleanup; rt falls back to the gh session (#382)
  • the rt cd picker groups worktrees by recency and hides disposable trees

Daemon and project sync

  • daemon restarts are pid-verified end to end instead of reporting success early (#361)
  • project sync failures are reported to the board (#374), merged and closed MRs come from the index (#375), and rt.ignoredMrs keeps deploy-branch MRs out of sync (#381)

mattstack.app and the dev app

  • tab and dock badges for decisions waiting on you (#398)
  • dev mode is retired: whoever launches a process sets its flavor, and the app you opened last is the active one (#418); launch agents re-register when their shipped plist changes (#419)
  • a hand-installed deck agent is retired on flavor handoff and cleared before the prod deck helper registers (#380, #384)
  • the board's scrollbar gutter no longer renders as a black strip (#355)
  • the dev app runs deck from a linked checkout (#402) and can rebuild and restart itself from the tray (#411, #403, #404, #421)
  • the tray asks flock to focus a pane when flock is running
  • rt run's queued launches open a seeded runner board (#390), and the runner board claims the mouse (#412)

Bundled apps

  • board 0.1.5: every gate opens the two-column gate sheet, structured review gates with a full-screen decision queue, edit a drafted reply before it posts, merge refusal reasons, the freshness banner names rt's sync failure, and BOARD-48, BOARD-47 and SKILLS-76 fixes (#427)
  • console 0.1.2: one grouped, filterable settings page with explain as a modal, the member-joined notification toggle, and unset notification toggles read on, matching what the daemon sends (#426, #427)
  • chat 0.1.2: the Radix colour system and one type ladder (#427)
  • deck 1.0.7 (was 1.0.5): the bundle helper owns deck, deploy restarts a source-run deck in the dev app, and app badges reach the shell (#385, #413)
  • fast-browser 0.1.5 (was 0.1.3): doctor --checks, and Web Store installs pass extension-installed (#407)
  • every app artifact is now signed with the Developer ID certificate under a stable identifier, so TCC grants survive updates (#347)

Plugins and tools

  • plugin catalog: mattstack 0.20.0 (pack authoring, writing-style presets, Hold at Gate 2 posts nothing) and fast-browser at 0.1.5 (#425)
  • bundled tools: age 1.3.2, gh 2.101.0, glab 1.119.0, node 24.21.0, cloudflared 2026.9.3 (#425); Sparkle stays at 2.9.6 for its own release
  • release and VM scripts' existence guards no longer invert under pipefail (#425)
  • @mattstack/rt-client 0.31.1 and @mattstack/settings-kit 0.3.0 (#374, #376, #379, #422, #424, #426)

Release tooling

  • rt release preflight, rt release verify and rt release update-machine turn the release checklist's mechanical steps into verbs (#350, #351, #352)
  • rt-tray/vm/run/gatekeeper-check.sh: a clean-room Gatekeeper assessment for any signed app (#358)

Full Changelog: v2.10.2...v2.11.0

v2.10.2

Choose a tag to compare

@github-actions github-actions released this 18 Sep 21:07

the fresh-pins release. Deck learns to update itself, and every plugin a fresh install receives is finally current.

Bundled apps

  • deck 1.0.5: deck update now resolves releases from the apps monorepo by tag prefix, so a small deck fix can ship to a machine in minutes without a full mattstack release; it had silently pointed at the retired standalone repo. Plus a dev-mode badge alignment fix (#341)

Plugin marketplace

  • refreshed the catalog's plugin pins: the mattstack skills plugin was 263 commits stale and the fast-browser plugin 30, so fresh installs were getting a months-old plugin layer (#342)

Release process

  • the release skill now audits every vendored layer (bundled apps, plugin catalog, standalone apps, tool pins, the Chrome extension) instead of only the app rows, and gains a pin-only fast path for serve-only apps (#340, #343)

Full Changelog: v2.10.1...v2.10.2

v2.10.1

Choose a tag to compare

@github-actions github-actions released this 18 Sep 19:18

the one-invite release. Joining a team now takes exactly one invite: the code your inviter sends is the whole thing, board peering included.

Team invites

  • the invite carries board peering: rt team invite registers the invitee's board on the switchboard and seals the board token into the encrypted invite pointer, and the join stores it where the board already reads it. The hand-delivered second board invite is gone (#339)
  • only the team's declared switchboard is trusted: an invite can never point the join (or the admin token) anywhere else, and every peering failure degrades to a completed join that names the board-panel re-invite as the repair (#339)
  • removing a member revokes every age key recorded for them across both roster keys, and roster reads prefer mattstack.roster everywhere, matching the apps (#339)

Gates and daemon

  • a dead pane's gate-push retry delivers doorbell-only, never injecting Escape into a live session (#328)
  • background fetches abort their child process instead of leaving it running, and the fetch gate's 60s race aborts with it (#337)
  • BUSY-deferred deletes in the project-MRs store are retried instead of lost (#336)

Toolchain

  • the bundled and CI-pinned bun moves to 1.4.2 (#334)

Full Changelog: v2.10.0...v2.10.1

v2.10.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 16:32

the polish release. Everything v2.9.0 shipped, plus the app-layer refresh it should have carried: every bundled mattstack app now ships current, including the board half of the gate seam. The mac app window grows find in page, a proper settings window, and a calmer startup.

The mac app

  • find in page: cmd-F searches the mattstack window (#311)
  • the settings window is a native tabbed window (General, Permissions, Fast Browser, Team, Uninstall) with the active pane named in the titlebar; the SwiftUI tab pill that collapsed into an overflow chevron on macOS 26 is gone (#312, #319)
  • Dev mode is a switch with a confirmation instead of a wordy button; the handoff still quits this flavor and launches the other (#312)
  • startup shows a fixed-life splash with a loading indicator and retries the icon fetch; the post-settle hold dropped from 1.0s to 0.3s (#318, #315)

Bundled apps, refreshed

  • board 0.1.4: the board side of the gate seam ships (gates converge on daemon gate:ask, GateForm renders option descriptions and question context) plus peer-board asks over the switchboard (#324)
  • chat 0.1.1, console 0.1.1, deck 1.0.4: current app-layer builds; the bundle no longer pins the September 7 fold-in era
  • deck logs its own serve output to ~/.mattstack/deck/logs/agent.log, so a boot failure finally leaves evidence, and a failed port bind now names the process holding the port before exiting for launchd's retry (deck-v1.0.4)
  • fast-browser 0.1.3: reads Claude plugin state via claude plugin list --json (the old text parser broke on the new synced-plugins section) and knows the current extension id (#313)

Gates and daemon

  • gate:ask reports why the form cap forced a wait instead of silently queueing (#317)
  • the daemon auto-accepts EnterWorktree's permission-root relocation prompt for registry-verified trees (#316)
  • the executor reconciler expires long-gone executors from the roster (#322)
  • a done herd job with a live follow-up round no longer draws the watchdog's close nag (#320)

Setup

  • fastbrowser.setup skips honestly on a host-less machine again: the skip now survives fast-browser's requested-host-absent wording (#308)
  • the bundle build prunes *.iconset resource dirs from helpers, so a helper shipping icon sources cannot fail the codesign seal (#314)

Proving it

  • the VM walkthrough unlocks the tester keychain before the assert phase, so the state-backup assertions run as a real user session would (#310)
  • the release process itself learned from 2.9.0: publish verification includes the draft flip and the public latest pointer, and a pin-freshness step keeps the bundled apps from shipping stale silently (#321, #323)

Full Changelog: v2.9.0...v2.10.0

v2.9.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 20:12
4de34c5

the agent-coordination release. rt grows a daemon gate facility that lets any surface ask a question and any surface answer it, a full herd orchestration layer for running fleets of Claude workers, an MCP server that exposes the estate's verbs as typed tools, and the finished Go picker that retires fzf outright. Underneath: encrypted off-machine state backup, a background pane server, mac app lifecycle fixes, a headless git core library, and a VM harness that now proves team joins, updates, and the whole kitchen sink on clean guests.

Upgrading from 2.8.0: v2.8.0 does not install on a fresh Mac. Required checklist rows could never clear: a probe budget too short for the tool it measured, a backup row alarming inside the daemon's own push-delay window, a forge row demanding a confirmation the Accounts row had already handled, and a switchboard row demanding a credential no input could satisfy. Two of these hard-blocked Install. This release fixes all four and the fresh-Mac install path.

Gates

  • a daemon gate registry (gates.db): rt gate open|answer|wait|list|park|close|subscribe, CAS answers, same-kind supersede, TTL escalation, retention sweeps
  • gates carry labeled options, context, origin, and an owner; owner-scoped subscriptions route herd questions to the shepherd and keep them out of human notifications
  • gate:ask owns the ceremony server-side: subject resolved from the caller's session (run, then agent record), one shared presentation rule (form iff an injectable pane, a nudge target, and every question at or under 4 options), context capped, supersede inherited from gate:open
  • answer-shape validation is canonical in rt-client (gate-answers, gate-presentation); the daemon and every UI consume the same module
  • strict option membership at the answer verb closes the silent-inversion class; a surface is never notified of the answer it recorded itself
  • remotely answered form gates get doorbell-then-Escape injection, with pane refs resolved live by session and worktree rather than a stale paneId
  • the gate-fork PreToolUse hook denies improvised AskUserQuestion forks in subject-stamped panes; herd spawns stamp the subject, and the app bundle ships the hook script
  • notification bridge: settings-driven rules with subjectPrefix filters, pane-focus click routing, and a {question} template
  • rt gate ask: a CLI verb that opens a gate with the full gate:ask ceremony from the terminal (#276)
  • canonical option shape (value + label) normalized at the registry; gate:ask passes meta and origin through (#279)
  • options carry descriptions and per-question context (#299)
  • a recommended flag on options; label normalization leaves path-like and id-like labels untouched, and a suffix guard prevents double-appending the recommended marker (#281)
  • answered-gate pushes are consumed when the nudged session reads the answer (gate:wait / herd:answer); missed answers are re-sent by a periodic sweep with bounded attempts (#280)
  • gate:ask resolves a stale-run subject by walking a ladder (run, then agent record), carries origin.worktree, and refuses bare-context human-owned gates that would produce an unanswerable question (milestone and pane-attention kinds exempt) (#295)
  • gate-fork hook allows the worktree's own open run-gate, so a worker's own pipeline questions are not denied (#290)

Herding

  • rt herd start|spawn|status|gates|ask|milestone|answer|report|close|wrap-up|resume|list: one verb spawns the worktree, pane, brief, chat sign-in, and trust accept; the daemon records job state as a side effect of every verb
  • worker questions ride the gate registry and push to the shepherd; reports and lifecycle land in the herd's chat room; a fresh session recovers everything with rt herd resume
  • hidden mode runs workers on a shared background herdr server with claims; rt herd attend brings one pane in front of the human
  • rt herd brief assembles job briefs mechanically from the shepherd skill's template and strategy bodies, with leftover-marker detection
  • idle-stall notices, dead-pane nudge retries, respawn into the same tree with the stored brief, and disposal guarded by running-run checks
  • rt accounts lists credential health; a daemon sweep probes github/gitlab token expiry and notifies on transitions
  • a daemon-driven watchdog detects wedged workers (no progress, no open gate, no activity) and pokes them by injecting a line into the worker's pane over the herdr socket (#301)
  • watchdog follow-up wave: trust unification across spawn and resume, 12-item sweep of lifecycle edge cases (#304)
  • watchdog open-gate exemption (a worker waiting on a gate is not wedged), and mid-run trust accept off by default so workers do not auto-accept trust dialogs the shepherd has not seen (#305)
  • spawn folder-trust robustness: the spawned pane's folder-trust dialog is accepted after launch; dead worker sessions detected by session liveness, not pane existence (#296)

MCP

  • rt mcp serve: a stdio MCP server (server name mattstack) exposing gates, chat, herd, and MR threads as typed tools over the daemon: gate_answer, gate_list, chat_post, chat_dm, chat_ack, chat_claim, chat_release, mr_reply_thread, herd_gates, herd_ask, herd_answer, herd_report
  • chat identity resolves from the caller's Claude session id; the server is lazy-loaded so rt startup stays flat
  • wave-2 tools: gate_ask, mr_comment_inline, mr_map, and cursor-based gate_list for paginated queries (#277)
  • heal-pair repo lookup resolves a repo by name against the repos index; the MCP layer replaces daemon error codes with remediation prose so callers get actionable messages (#297)
  • the chat skill trims onto the MCP chat tools so agents using the MCP server get chat without the CLI (#278)

MR plumbing

  • mr:comment-inline: positioned DiffNote comments with diff_refs fetched server-side, the created note's type verified from the creation response, and one delete-and-repost repair on silent degrade (glance 0.25.0)
  • rt mr map: your open MRs joined to the local worktrees holding their branches by exact branch equality
  • stale-claim sweeps honor open MRs and measured activity; worktree auto-dispose reads GitHub PR state too

The picker

  • the fzf cutover completes: every picker is the one-shot Go rt-ui pick verb, fzf's matcher kept only as a pinned ranking library; fzf.ts and the fzf-driving e2e suites are deleted
  • multi-select with marks and a selected panel, an action registry driving the keybar and ctrl-k menu, modal overlays, right-click menus, held-modifier chrome, match highlighting, grouped rows, in-place detail expansion
  • cd, commit, run, navigation, skills, worktree, and arg-collector pickers all migrate; breadcrumbs and a shared aborted line on every cancel path
  • navigation rebuilt on the events model (descend-in-place, sort modal, watcher); run picker gets grouped script rows and a tab queue

Background panes

  • a persistent bg service with a claims store: rt agent --bg launches on the background server, rt bg ensure|status|release|stop manage it, and stop is claim-gated so nothing owned dies silently
  • rt pane send: inject a line into any pane, self targets the caller, and --then queues a continuation the daemon types after the target's turn ends
  • runner's herdr mode acquires the bg server through the daemon with a board claim; focus attends via pane:focus

The mac app

  • the tray app stays a Dock app for the whole run; the Dock icon is never hidden while the process is alive (#287)
  • a Window menu so cmd-W closes the window instead of doing nothing (#286)
  • a quit with no window on screen is a real quit, not a silent background linger (#283)
  • the app catalog is warmed at launch so a browser handoff arriving before the window has opened does not blow the caller's timeout and fall back to the browser (#282)
  • TrayState and its writers pinned to the main actor, fixing an off-main-thread SwiftUI publish during the 10s status polling that aborted the app (#292)
  • terminal focus raise for daemon-hosted panes: when a pane needs attention, the terminal window comes forward (#238)

Teams

  • invites deliver as one join link (code, deep link, and page url share an extractor); the app accepts a paste and preflights the joiner's forge auth
  • invite mints a forge grant; members can be pull-only, and every team write path (publish, members, secrets, snapshot push) refuses honestly on a pull-only clone
  • a team-clone snapshot engine pulls, converges the Claude plugin pack cache against what the team serves, and never resolves conflicts silently
  • gh and glab run from the app bundle; clone, publish, and invite carry the token rt holds instead of hoping the shell has one

State backup

  • encrypted, compressed, off-machine backup of suite state: VACUUM or tar, zstd, age to multiple recipients, Git LFS in the home repo; restore decrypts, integrity-checks, and places with holder-process guards
  • age, zstd, and git-lfs ship in the bundle and resolve from it first; a daemon sweep runs the cycle every 4 hours

Setup and the app

  • finish-gated checklist rows with waive/unwaive; the Fast Browser extension gates Finish unless waived, and Done exposes the manual steps Install cannot take
  • a privileged proxy helper installs with pinned payloads, root-owned staging, CA trust it owns and can untrust, and complete rollback
  • Install seeds a baseline Claude Code permissions allow list, writes a Linear MCP entry when a key exists, and distinguishes unowned PATH precedence from missing
  • four checklist rows that cried wolf are fixed; credential expiry shows on the checklist
  • team setup asks where your repos should live instead of assuming a folder (#265)
  • editor opening via OS handoff for non-web schemes (vscode://, cursor://) and a suite-wide default editor setting (#294)
  • the sdm probe trusts the status table rather than matching an email substring (#302)
  • the baseline allow list includes the mattstack MCP server under ...
Read more