What's New
This page tracks the user-visible changes in recent Thrum releases — highlights, breaking changes, and anything that needs attention when you upgrade. The full machine-readable history lives in CHANGELOG.md.
v0.10.5 — 2026-05-21
v0.10.5 shipped
2026-05-21 after an eight-RC soak — the backstory (what it's actually like to
run a release with a team of agents) is in the blog post
28 Agents and a Release on the Side.
One thing to know before you upgrade: the BREAKING thrum send change. The
bare form thrum send "msg" now requires either --to @<agent> for a directed
send or --broadcast for explicit team fanout — the old silent-broadcast
default was a footgun (one accidental bare send fanned out to a 90-plus-agent
team mid-cycle). --to @everyone still works as the legacy keyword. Adding
--to or --broadcast to your scripts and aliases is the only migration step.
Backstop and hygiene. The headline change is operational: a daemon-side backstop
nudger re-emits delivery notifications for stale-unread messages on its own
schedule, replacing the per-agent thrum-inbox-poll.sh cron that previously had
to be installed and maintained per worktree. Around that: long-running agent
worktrees stop drifting from the embedded daemon-managed script templates
(runtime-init now overwrites them while preserving user-customized configs),
thrum prime leaves a visible scrollback anchor so you can confirm at a glance
that context loaded, the project-setup skill works in redirected worktrees
again, and a handful of inbox-race fixes land alongside two small new CLI flags
(thrum inbox --from @agent, thrum worktree teardown --delete-branch).
Plus a headless worktree.Create / worktree.Destroy Go API moving into
internal/worktree — no user-visible CLI change, but it's the substrate the
v0.11 agent epics build on for ephemeral-worktree flows. The URL migration to
thrum.team from leonletto.github.io/thrum also wraps up in this release
(Phase 6.3 — old URLs redirect cleanly).
Beyond the backstop work, v0.10.5 tightens how Thrum sits alongside the tools
around it. thrum init now merges its hooks into an existing
.claude/settings.json instead of skipping the file outright, so it coexists
cleanly with third-party hooks — most importantly the one bd setup claude
installs. Beads integration itself moves to that bd setup claude path (or
thrum's own auto-install when Beads is enabled and on your PATH); the
standalone Beads plugin is no longer recommended.
There's also a round of operator-facing reliability fixes: thrum monitor stop
no longer hangs or leaves orphaned child processes, the thrum monitor
subcommands accept the human-readable monitor name instead of only the ID, and
the diagnostic commands warn consistently when you've run them from the wrong
worktree. On the coordination side, two v0.11 coordinator-discipline skills were
backported — context-monitoring (a restart ladder that catches an agent before
it hits a context blow-up) and review-gates for the brainstorm pipeline.
Upgrade Notes
thrum sendmigration (BREAKING). Update scripts and aliases that use the barethrum send "msg"— add--to @<name>for a directed send or--broadcastfor team fanout.--to @everyonestill works as the legacy keyword.- Beads users: if you're on the standalone Beads plugin, switch to the CLI +
hook path — uninstall the plugin,
brew install beads, runbd setup claude, restart Claude Code. Thrum-managed projects handle this for you. - Otherwise, no action needed. The daemon backstop nudger is on by default;
if you installed the old
thrum-inbox-poll.shcron you can remove it (it's now a no-op).
Full change list: CHANGELOG v0.10.5. See the Beta Channel page for install commands.
v0.10.4 — 2026-05-17 (Quick Footgun Release)
v0.10.4 shipped
2026-05-17 after a compressed 4-hour soak. rc.1 was unsalvageable — its
remediation text advertised an internal --repo escape hatch to agent-facing
output, undoing the guard's intent. rc.2 corrected the text and promoted clean.
Standard thrum functionality is unchanged. v0.10.4 only fixes confusing messages agents get when they cd into the wrong worktree by accident. Normal same-worktree day-to-day use is unaffected. This is UX and safety hardening, not a regression fix. Full backstory: Shooting Yourself in Both Feet.
The bug was a known footgun in the original identity-guard work (thrum-7b84.6): when an agent's CLI command ran from a worktree that didn't match its pane-bound identity, mutating commands could silently send under the wrong identity. v0.10.4 splits CLI commands into three behaviour classes:
- Class A — mutating commands (send, reply, message read, inbox markRead, context save, etc.): fail closed with a clear error message naming both the expected worktree and the actual cwd. Nothing leaves under the wrong identity.
- Class B — diagnostic commands (team, status, daemon, whoami, version): keep working but emit a one-line banner before the output: "you're in another worktree — running against your registered agent at …". Lets cross-repo housekeeping scripts (updating thrum + restarting daemons across N repos) still succeed without spurious failures.
- Class C — purely informational reads (inbox listing without markRead, list helpers): same banner as Class B, no other change.
The remediation: cd back to the agent's own worktree, or run thrum prime to
re-claim the identity if the pane binding has drifted.
See the Beta Channel page for install commands.
v0.10.3
v0.10.3 shipped
2026-05-16 after a 5-day, 11-RC soak cycle. Each rc.N closed exactly one bug the
previous candidate surfaced under real use — none of them dramatic on their own,
every one the kind of thing that turns into "thrum is flaky" if it ships
uncaught. The full story is in the blog post
The Release That Wouldn't Land.
This release is largely about the runtime experience: codex gains the same first-class plugin treatment claude has had, fresh and restarted tmux panes no longer sit idle when an agent misses its prime banner, and the first-launch trust dialogs both codex and claude show are now recognized as a distinct class so Thrum's startup keystrokes don't accidentally answer them. A bundle of quieter fixes around env scoping, self-echo, and preamble framing rounds it out.
Added
Codex plugin first-class support.
codex-plugin/plugins/thrum/now ships the same hook surface the Claude plugin has: SessionStart auto-prime, PreToolUse safety block, and a Stop hook that flags unread inbox messages. Fourteen role-discipline skills sync over fromclaude-plugin. Installation is a one-command bootstrap that also handles a third-party cache-staging gap in codex 0.130.0, so you can install and start using it in the same step:bash <(curl -fsSL https://raw.githubusercontent.com/leonletto/thrum/thrum-dev/codex-plugin/plugins/thrum/scripts/install-plugin.sh)Tmux silence watchdog after launch and restart. When
thrum tmux launchorthrum tmux restartreturns, the daemon watches the agent's pane for silence and sends a contextual nudge if the agent hasn't engaged within the configured threshold. Closes the long-standing gap where fresh codex agents (and large-context restarts in claude) would sit idle at a welcome banner or post-restart screen because they'd missed the prime instruction. Configurable via the newrestart.silence_watchdog_secondskey (default 30s; negative disables; see Configuration). Internally this also replaces the previous hardcoded 10-second pre-inject sleep with a pane-stability readiness probe.Trust-gate detection for codex and claude first-launch dialogs. Thrum recognizes the trust prompt both runtimes show on first launch in a new directory as a distinct class. When a trust gate is up, keystroke injection paths (identity banner, prime nudge, watchdog nudge) are skipped so the user can answer the prompt without interference from Thrum. Normal permission-prompt handling and supervisor notify are unchanged — see Trust-Gate Detection.
Per-session env scoping at session create.
tmux.CreateSessionWithEnvpassesTHRUM_NAME/AGENT_ID/ROLE/MODULE/HOME/INTENTper-session, so distinct tmux sessions on a shared server present distinct identities to their initial shells. Subsequent split-window and new-window panes inherit correctly.Anti-rush discipline in coordinator and orchestrator preambles. Five operational rules codify patterns the project has hit before — skipping review gates on small diffs, bucketing findings as "follow-ups" without justification, shipping a fix labeled X when the actual cause is something else, declaring DONE without verifying the user-visible bug is gone, and taking the cheapest path on autopilot.
Changed
thrum initlowercases the default agent name. The wizard previously derived names likecoord_316Redesignfrom a capitalized repo directory and then rejected its own suggestion at the validator (a-z,0-9,_only). The default is now always validator-compatible.Pre-launch readiness is gated on pane stability, not a fixed sleep. The post-launch / post-restart inject path polls the tmux pane every second and proceeds once two consecutive captures are byte-identical (TUI rendered, runtime at input-ready), with a 60s ceiling. Replaces the brittle
Sleep(10s) + retrypattern that drove an earlier trust-prompt regression.Role preambles now say skills MUST be invoked, not auto-loaded. The "Available skills (situational)" section in seven role preambles previously implied skills fire automatically when the runtime matches trigger phrases. Skills do not auto-load — agents must invoke them explicitly via the
Skilltool. Wording is now directive rather than descriptive.Enhanced role preambles regain the in-tmux listener-suppression carveout. Twelve enhanced preambles (
deployer / documenter / monitor / planner / tester / reviewer×strict / autonomous) had restated the "spawn a listener on session start" instruction without preserving the tmux carveout from the base preamble, causing tmux-managed agents to spawn a redundant background listener that burned context for zero delivery benefit. Carveout restored; a regression test now fails any preamble that issues the spawn directive without the SKIP-when-in-tmux qualifier.thrum worktree createpropagates SessionStart hook scripts into the new worktree'sscripts/directory.scripts/thrum-startup.shandscripts/thrum-check-inbox.share gitignored, sogit worktree adddoesn't carry them across; without the per-worktree copy, the Claude Code SessionStart hook fired against a missing script and the agent never quickstarted in worktree-created subdirs. Copy is idempotent on size+mtime.codexruntime preset is markedHasSessionStartHook: true(parity withclaudeandcursor). The codex SessionStart hook shipped earlier but the preset wasn't updated, soHandleLaunch/HandleRestartwere routing codex through the non-hook branch (typing/thrum:primeinto the TUI) instead of emitting the identity banner once the runtime rendered./thrum:restartskill rewritten around prose continuations. The skill dropped from ~134 lines to ~50 by replacing the JSON-snapshot Resume Plan template +thrum tmux snapshot save+ append flow with a direct write of an in-context-composed prose continuation to.thrum/restart/<agent_id>.md. Auto-prime pickup is unchanged; coordinator-notify and the non-tmux operator fallback are preserved. Field-tested across 7 v0.11 substrate agent restart cycles — continuations averaged ~200 lines with high signal density. Synced across the codex, opencode, cursor, and claude runtime plugins.
Fixed
Self-echo phantom nudge. Outbound
thrum sendfrom agent A to agent B was producing a phantomNew message from @<A>reminder in A's own pane on every send. Root cause:CLAUDE_PROJECT_DIRleaks through a shared tmux server's default-environment, so Claude Code in B's pane was resolving the${CLAUDE_PROJECT_DIR}/scripts/thrum-check-inbox.shhook against A's worktree. Fix scrubsCLAUDE_PROJECT_DIRat the existingcleanTmuxEnvchokepoint, alongside theTHRUM_*andTMUX/TMUX_PANEscrubs. Scope is narrow to the single variable with documented leak evidence;CLAUDE_API_KEYand otherCLAUDE_*vars are explicitly preserved by a regression test.Defense-in-depth self-echo guards. Independent of the env-leak fix, both the daemon spool dispatcher and the inbox-check hook now drop any spool entry whose
frommatches the receiving agent ID — so a future regression upstream cannot reach the user-visible self-echo nudge.project-philosophyskill respectsAskUserQuestion's 4-option limit. Step 5 of the skill prompted with option lists that could exceed the tool's hard cap of 4, failing withInvalid tool parameters. The skill now uses sequential questions (category?→specific item within category?) when the natural option count exceeds four. Synced across all four runtime plugin copies.thrum init --forceno longer silently disables messaging. A hard-coded assignment in the runtime-selection step was overwritingsingle_agent_modetotrueon every init run, which disables the inbox listener and stop-hook checks. Agents appeared healthy inthrum teambut inbound messages never arrived and replies silently dropped. Affected users upgrading via the commonthrum init --forcerefresh path; fresh installs were unaffected. If you hit this on an earlier release, open the project's.thrum/config.jsonand flipsingle_agent_modeback tofalse.Watchdog now recognizes Claude Code 2.1.141's
·thinking-spinner glyph. Claude 2.1.141 introduced a·prefix on some thinking-spinner states alongside the existing✻glyph. The watchdog'sclaudeSpinnerRegexonly matched✻, so panes showing the new spinner were classified as silent — over-triggering nudges into still-thinking agents. The regex now covers both glyph forms; a regression test pins five observed· <verb>…variants against the live Claude TUI.
Upgrade Notes
- One new config key.
restart.silence_watchdog_seconds(default 30s, negative disables) — only relevant if you want to tune the post-launch / post-restart nudge cadence. - Codex users: the one-command installer above is the easiest path. The
legacy
~/.codex/skills/extra-roots loader is gone as of codex 0.130.0; if you previously installed there, see the migration note in Codex Plugin. - No CLI flag removals or behavior reversals since v0.10.2.
v0.10.2 — 2026-05-04
Hotfix release closing two related foot-guns from the v0.10.x identity work: the
SessionStart hook (scripts/thrum-startup.sh) breaking on every
already-registered worktree, and a tmux env-hijack class that caused new panes
to resolve identity to the daemon-starter's agent. Plus a long-standing
thrum purge regression where message JSONL files weren't actually shrinking.
Fixed
thrum quickstartno longer rejects idempotent same-name re-register. Thequickstart_self_renameguard was firing on every call where the caller already owned an identity, even when the requested--namematched the existing one. This brokescripts/thrum-startup.sh— the SessionStart hook on every claude session — at step 3 (thrum quickstart);set -eaborted before steps 4 (inbox check), 5 (announce), and 6 (cron install) ran.thrum tmux startagainst an existing worktree hit the same guard and aborted before claude launched. Same-name re-register is now allowed without--force(it's an idempotent no-op); a real rename (different--name) still requires--force.tmux.create-spawned panes no longer inheritTHRUM_*env from the daemon. When the daemon was started from a primed shell, every tmux pane it spawned inherited the daemon'sTHRUM_AGENT_ID,THRUM_HOME, etc. — causing the new pane'sthrum whoamito resolve to the daemon-starter's identity instead of the pane's intended agent. Two-layer fix: scrubTHRUM_*from the daemon's tmux exec env, AND pass per-session-e KEY=overrides so even long-running tmux servers (which cache the environ from server-start time) produce clean panes.thrum purge --confirmnow actually shrinks JSONL message files. The filter was passing the wrong field name ("created_at"vs the on-disk"timestamp") when iterating message JSONLs, so every record was kept and on-disk files grew unboundedly. Verified live:--before 30dagainst a 335MB sync dir filtered 13 message files in 7.7s.Misleading
unauthenticated_rpcdeny message now points atthrum primeas the cache-warming recovery (wascd into a registered agent worktree and retry, which was the wrong fix when the caller already WAS in a registered worktree but the daemon's binding cache hadn't warmed after a restart).
Internal
- Release-test harness coord-whoami probe now retries 3× 30s instead of a single 60s wait — recovers from missed-keystroke races on saturated multi-agent dev boxes.
- Unit-test hardening:
internal/cliandinternal/configtest packages now haveTestMainenv-isolation guards so tests don't silently inheritTHRUM_*pollution from the operator's primed shell.
Upgrade Notes
- No CLI flag changes; no config changes. Drop-in upgrade from v0.10.1.
- After upgrade:
make install(or download the new binary), thenthrum daemon restartso the running daemon picks up the new binary. Also refresh the Claude Code plugin (/plugin update thrum, or remove + add the marketplace) — v0.10.2 ships an updatedinject-prime-context.shthat improves the SessionStart context delivery banner.
v0.10.1 — 2026-05-03
Two related identity-resolver fixes shipped together. v0.10.0 is marked prerelease; upgrade to v0.10.1.
Fixed
thrum quickstartfrom a.thrum/redirect-using worktree no longer writes the agent identity into the parent repo. WhenTHRUM_HOMEwas set (which the wizard's daemon-inline path effectively does for spawned panes),quickstartwas hijacking the identity-write target to$THRUM_HOME/.thrum/identities/and recording the parent path as the agent'sworktree. Subsequent identity-resolution from any peer worktree could then cross-claim, with symptoms likethrum whoamireturning the wrong agent andunauthenticated_rpcguard denying writes.Boot-time identity reconcile so write RPCs from any registered worktree succeed after a daemon restart, without re-running
thrum quickstart. Previously, the peercred resolver matched caller CWDs againstsession_refs JOIN sessions WHERE ended_at IS NULL— that view is durable in SQLite but loses rows on shutdown / cleanup / long quiescence, so disk truth (identity files) and resolver truth (DB rows) drifted apart.thrum send,thrum tmux start, and other write RPCs would fail withanonymous caller cannot invoke Xfrom a worktree where an identity file clearly existed; onlythrum quickstart --forcere-populated the rows (thrum primedid not). The fix walks.thrum/identities/*.jsonat daemon boot and inserts the missing(sessions, session_refs)pairs viasafedbin a per-identity transaction. Local-only by design — direct SQL, no JSONL events, no cross-machine sync — becausesession_refsis intentionally local-only state. The same pass restores in-memory tmux pane-nudge bindings for any identity whosetmux_sessionis still alive. Closes thrum-soj8 + thrum-6kk6.
How to verify after upgrade
# Existing redirect-using worktrees: re-quickstart from inside the
# worktree to refresh the identity file with the corrected location
# and worktree value.
cd <child-worktree>
thrum quickstart --name <name> --role <role> --module <module> --force
thrum whoami # should report the child worktree, not THRUM_HOME
v0.10.0 prerelease note
The v0.10.0 release page on GitHub is marked prerelease and the Homebrew tap was reverted to v0.9.2 during the fix window. v0.10.1 promotes back to "latest" with the regression closed.
v0.10.0 — 2026-05-03
The v0.10.0 work centers on thrum init. The first-run experience used to be a
silent scaffold and a list of follow-up commands; now it walks you through
identity, worktrees root, role templates, and daemon start in one interactive
flow. Existing CI scripts keep working unchanged via the --non-interactive
flag (or any non-TTY stdin).
New
thrum initinteractive wizard. On a TTY,thrum initprompts for agent name / role / module, worktrees-root path, role-template choice (enhanced / default / skip), and starts the daemon — all in one flow. Press enter through every prompt to accept the recommended defaults.- Pre-fill any prompt with a flag. The wizard reads
--name,--role,--module,--worktrees-root,--roles=enhanced|default|skip, and--no-daemonso you can script it end-to-end in fixtures. --forcere-init pre-seeds prompts from existing values. Runningthrum init --forceon a previously-initialized repo loads identity and worktrees-root from the current.thrum/so pressing enter through the prompts is a no-op refresh.- Transactional rollback on failure or SIGINT. If any wizard step errors
after
.gitignore/.git/info/excludewere touched, the wizard restores them byte-for-byte. Ctrl-C during prompts cleans up cleanly. implementer-worktree-write-onlyrole template. The wizard's "enhanced" choice ships a stricter implementer preamble that pins writes to the agent's own worktree and forbids drive-by edits to the main repo.- tmux gate. If
tmuxis not onPATHwhen the wizard reaches the daemon-start step, init exits early with an OS-appropriate install hint (brew install tmux/apt install tmux).
Changed
- Default worktrees base path migrated.
worktrees.base_pathnow defaults to~/.thrum/worktrees/<project>(was~/.workspaces/<project>). Repos with an explicitWorktrees.BasePathin.thrum/config.jsonare unaffected. If you relied on the implicit fallback and want existing worktrees to keep resolving, runthrum config set worktrees.base_path "$HOME/.workspaces/<project>"before the next worktree create. The wizard's worktrees-root prompt also accepts the legacy path.
Fixed
scripts/thrum-check-inbox.shexcluded alongsidethrum-startup.sh. Init now adds the inbox-check helper to.gitignore(and.git/info/excludein stealth mode), preventing it from leaking into tracked changes.
Migration
- If you scripted
thrum initin CI: add--non-interactive(or rely on non-TTY stdin) — both keep the legacy silent path. The wizard never fires under those conditions. - If your worktrees lived under
~/.workspaces/<project>and you want them to stay there: pin the path withthrum config set worktrees.base_path "$HOME/.workspaces/<project>"before the nextthrum worktree create.
v0.9.2 — 2026-04-29
The v0.9.2 work was mostly polish on agents and preambles — the parts of Thrum agents wake up with. If you've been wishing role discipline survived restarts better, or that Claude Code sessions actually loaded the briefing they're supposed to, this is the release.
New
role_configpersists in.thrum/config.json. When you run/thrum:configure-roles, your answers (autonomy + scope per role) save under a new top-levelrole_configkey. The skill prefills from saved answers on re-run so you only re-confirm what you want to change. See Role Templates and Configuration → Role Config.thrum roles refresh— re-renders.thrum/role_templates/<role>.mdfrom saved answers + the shipped templates embedded in the binary. Run this after upgrading Thrum without re-doing the interactive prompts.thrum primesurfaces drift hints. Three codes:roles.config.migration(rendered templates exist, norole_configblock),roles.config.schema-bump(shipped schema newer than saved),roles.config.body-diff(shipped template body changed). Precedence is top to bottom; only one fires per repo.- User overlay composed into the rendered preamble.
.thrum/context/<agent>.mdis auto-created empty bythrum quickstart. Anything you write into it gets appended afterDefaultPreamblewith a---separator. Per-agent tweaks ride on top of the role discipline without forking the template. - Pane-side identity banner. Sessions launched via
thrum tmux createand restarted viathrum tmux restartnow display an Agent / Role / Worktree / Branch banner directly in the tmux pane, plus aMUST READline pointing at the auto-loaded briefing. The banner only fires on runtimes that ship the SessionStart hook (Claude Code and Cursor today). See Claude Code Plugin → Pane-side identity banner. - SessionStart hook injects
thrum primeoutput. The Claude Code and Cursor plugins' SessionStart hook now runsthrum primeand emits the full briefing inline as the hook'sadditionalContext. Restart-snapshot framing is hoisted to the top with a🛑 ACTION REQUIREDdirective so it doesn't get read-and-rationalized-away. - Role-skills layer. Ten new description-triggered skills deepen role
discipline situationally without bloating the always-loaded preamble. Three
for coordinator (
dispatching-work,running-review-cycles,managing-state-and-lifecycle), four for implementer (receiving-dispatch,tdd-and-quality,status-and-handoff,receiving-review-feedback), three for researcher (investigating,answering-queries,maintaining-memory).
Fixed
- tmux pty leak (thrum-x6e8.5).
tmux-execmigrated fromrespawn-paneto a persistent-session pool. The previous approach leaked pseudo-terminals on every respawn, eventually exhausting the per-process fd limit on long-running daemons. thrum tmux statusandthrum tmux connectleaked sessions across daemons (thrum-zuz5). Pass 2 ofHandleStatuswas filtering on@thrum-managed=1, which every Thrum daemon stamps — so sessions from unrelated worktrees and projects leaked into the picker.HandleCreatenow also stamps@thrum-thrum-dir=<this daemon's thrum_dir>and pass 2 filters on it. Migration: sessions created before v0.9.2 won't appear in pass-2 output until you recreate them viathrum tmux create.runPreambleInitfallback ignored.thrum/redirect(thrum-5hhx). Worktree setups using the redirect indirection silently lost their custom preamble path. Fallback now follows the redirect.- Worktree preambles rendered relative strategy paths (thrum-rm4x,
thrum-z9zl). Generated preambles referenced
strategies/<file>relative to the rendering CWD, breaking when read from a different directory. Paths are now absolute against the project root. thrum context preamble --initoverwrote customized templates (thrum-pk2o).--initskipped.thrum/role_templates/<role>.mdand went straight to the generic default. It now consultsRenderRoleTemplatefirst and only falls back when no rendered template exists.- Peercred unknown-vs-anonymous (thrum-ndtw, backported from v0.9.1). v0.9.0
wrapped introspection failures (
tspeer.Get,gopsutil.Cwd) withErrAnonymous, which rejected mutating RPCs from registered Bash subprocesses on macOS. Steps 1+2 now return raw errors and fall through to legacy client-asserted identity. Provably-anonymous paths (steps 3+5) still wrap.
v0.9.1 — 2026-04-24
thrum setup claude-md --apply— the documented-but-unimplemented command from issue #8 now works. Barethrum setup claude-mdprints the template;--applycreatesCLAUDE.md(or appends to existing);--apply --forcereplaces idempotently. Block markers:<!-- BEGIN THRUM -->/<!-- END THRUM -->.- Peercred resolver error taxonomy (thrum-ndtw). Same fix described under v0.9.2 above; landed first in v0.9.1.
v0.9.0 — 2026-04-23
What's New
- Permission-prompt detection — the daemon detects when a tmux-managed agent hits a blocking permission prompt and routes an actionable nudge to configured supervisors. Approve or deny from the CLI, web UI, or Telegram. See Permission Prompt Detection.
- Identity guards — cross-worktree CWD enforcement hard-errors on CWD drift instead of silently misattributing actions to the wrong agent. See Troubleshooting: Identity.
- CLI hints (Phase B) — contextual guidance printed before and after destructive or multi-step commands. See CLI Hints.
- Drift reconciliation — peers self-heal address drift automatically without re-pairing. See Peers.
thrum tmux quickstart— alias forthrum tmux create. Same command, clearer name.thrum tmux createnow requires--name,--role,--module(or--no-agent) and runs quickstart inside the new pane automatically.thrum worktree setup— alias forthrum worktree create. Both commands now accept optional quickstart flags (--name,--role,--module,--intent,--runtime). Provide all three required flags and it creates a real tmux session, runs quickstart inside it, and prints the next-stepthrum tmux launch <name>command. The agent identity is registered, but the runtime is not started untiltmux launchruns — a clean two-step pattern with no manualthrum quickstart.- Single identity per worktree — quickstart cleans up old identity files after writing the new one. You can't end up with a stale identity causing auto-select errors.
thrum tmux launchhard-errors on missing identity — launch needs an agent identity to determine the runtime. Sessions created with--no-agent(or worktrees with no identity file) cannot be launched until you register an agent first.- Next-step guard messages —
agent register,worktree create(no agent),purge --confirm,daemon stop,tmux restart, andtmux launchnow print explicit hints about what to do next (or what just broke). - Monitor Jobs v1 —
thrum monitor start/list/show/stop/logs/restart. Attach a monitor to any long-running process and it emits matches as synthetic Thrum messages. Leading-edge debounce (default 60s, min 30s), auto-persist, local-socket-only.
Breaking Changes
If you're upgrading from v0.8.x, read this section before starting the daemon.
- Forged
caller_agent_idrejected — pre-v0.9.0 callers could pass anycaller_agent_idand it was accepted at face value. Now cross-checked against kernel-verified PID resolution. Mismatches get "identity mismatch" and are dropped. - WebSocket non-localhost origin → HTTP 403 — pre-v0.9.0,
CheckOriginreturnedtruefor all origins. Browser pages on non-loopback origins can no longer upgrade to WebSocket. message.deleteby non-author rejected — only the original author can soft-delete their own messages.message.deleteByAgentrequires caller == target — agents can only bulk-delete their own messages.message.deleteByScopeis daemon-internal only — no longer callable from any external client (CLI, browser, or unix socket).- Legacy daemon_id auto-rotated — first v0.9.0 daemon start rotates
pre-existing hostname-derived daemon IDs to ULID format. Existing peer pairs
must be re-paired:
thrum peer remove <name>thenthrum peer add --type tailscale <name>on each peer. - Downgrade blocked by migration guard — running a v0.8.x binary against a
database migrated to schema v24 fails with a clear error. Recovery: stop
daemon → restore
thrum.db.pre-migration-v<N>-bak→ run the older binary. ~/.thrum/runtimes.jsonreplaces the old platform config path — silently dropped on upgrade; custom runtimes disappear. Move the file manually: Linux:~/.config/thrum/runtimes.json→~/.thrum/runtimes.json; macOS:~/Library/Application Support/thrum/runtimes.json→~/.thrum/runtimes.json.peer add --typeandpeer join --typeare now mandatory — the previously implicittailscaledefault is gone. Add--type tailscaleto any existing scripts that omit it.alert-silencehook no longer triggers permission-prompt detection — daemon-side poller replaces it (~20s detection latency). Existingalert-silenceconfig in.tmux.confis inert for this purpose.- Identity guards hard-error on CWD drift — running thrum from the wrong CWD
fails with
identity guard "cross_worktree" fired: pid_mismatchinstead of silently misattributing. UseTHRUM_HOMEto pin repo path. See Troubleshooting: Identity. thrum daemon startandthrum initrefuse non-git directories — pass--forcefor non-anchored use.thrum quickstartrefuses self-rename / name collision — without--force. Previously a silent overwrite.- Telegram fresh-DM
yresolves a pending nudge instead of routing to--target— if the sender has a pending permission nudge, a barey/n/yes/no/allow/denyDM resolves that nudge rather than delivering to the configured target agent.
v0.7.x
- Orchestrator role — a dedicated coordinator agent that reads your plan, claims tasks, spawns implementers, and stops at every review gate without touching the merge button; see Orchestrator Role
- Multi-runtime support — Claude Code, Codex, OpenCode, etc. all work; Thrum picks the right tmux launch command for each; see Multi-Runtime
- Peer mesh — agents on different machines join one team over Tailscale or local network with no extra servers; see Peers
- Single-agent mode — Thrum's context management and session tracking work without any messaging layer; it's now the default for new installs; see Single-Agent Mode
- Daemon-managed tmux sessions — the daemon owns the session lifecycle, delivers messages the moment they arrive, and runs zero background listeners in the agent process; see Tmux Sessions
- Command queue dispatch — coordinators submit commands to agent panes via
thrum tmux queue, with completion tracking,@systemnotifications, and restart recovery; see Tmux Sessions — Queue Dispatch - Worktree management —
thrum worktree create/teardown/list(alias:thrum worktree setup) handles git worktree setup with automatic Thrum and Beads redirect wiring - Daemon logging — structured slog output with lumberjack rotation; view
with
thrum daemon logs; configurable viadaemon.log_level
Older Releases
For releases before v0.7.0, and for the full machine-readable history, see CHANGELOG.md.