Ship log

Changelog

Every release, what changed, and why. See the full history on GitHub Releases.

v0.3.24Sep 3, 2026

Changelog

Features

  • b5a046ddcd171d2609b20d005d2f811de27db381 feat(build): add Windows support and refactor signal handling

Other

  • b5bd067acc96accd0a9d807915c2cebaa24e5e2d refactor: rename module and update references to theboringfloor
v0.3.23Sep 3, 2026

Changelog

Features

  • 930107f30af735f09038b4e4cf6bf6909e776b39 feat(app): lease current backend at send and idle recap
  • a963fecf6231b730e00645373ebcd6e60dea9bb8 feat(brand): add CLI, display, env, and dotdir names
  • e5ee1f07f9e447711cd8139c161646e345e5a4b3 feat(config): enhance theme directory migration and update tests
  • 16aec843027a27af1ebebad5fdf34d2985b72a6a feat(config): implement home directory migration from ~/.theboringoffice to ~/.theboringfloor
  • bceb96038eec2d7b5ab999417f87620705fb0273 feat(config): store state in ~/.theboringfloor
  • 043db0cecd761b6ec2c704c6b3ca1878f7c16a56 feat(install): ship theboringfloor binary with tbo shims
  • fb3143f604292ef9af57b3535422fa9b506896a8 feat(website): 302 /install.sh and /install.ps1 to GitHub main

Other

  • 0569b751225d811d8c1fda367c3a6602d544f54f Refactor Hero component in website
  • 19fdc2ce3e878872ff8f74d33f4b75c0713f31d4 docs(website): rename product to theboringfloor
  • 6d2310176a3f030c0527e75bca7e40f824502d4c docs: rebrand product copy to theboringfloor
  • f013230b616691ca721c5368517b44885d39742d refactor: rename wire prefix and copy to theboringfloor
v0.3.22Sep 2, 2026theboringoffice v0.3.22 — built-in browser first

Agents now get an explicit built-in-browser-first rule on both backends.

  • Use the office browser for every URL, including localhost and external pages.
  • open-browser shows a page, browser-screenshot captures it for the member, and browser-snapshot reads text/links for the agent.
  • browser-action remains mutating and permission-gated.
  • Agents must not launch Chrome, Chromium, Playwright, Puppeteer, terminal-browser, or another browser process unless the member explicitly asks for an external browser or the built-in path fails and the failure is explained.
  • The policy lives in both the first-turn runtime prompt and the canonical oikonomos charter, so it survives context compaction/reload.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.21...v0.3.22

v0.3.21Sep 2, 2026theboringoffice v0.3.21 — context recovery

The office can now give its boss recent chat context when compaction or a long session makes it lose the thread.

  • Context recovery tool: agents on both backends can emit ⟦recent-messages⟧ (default 20) or ⟦recent-messages: N⟧ (1..50). The marker is hidden, and the office sends a bounded synthetic transcript containing recent user, boss, and tool-output rows. Newest context is preserved; recovery-control noise cannot recursively reappear.
  • Post-bypass sends proven: successful ON/OFF/rapid transitions route ordinary text and attachments exactly once to the fresh backend. An unavailable generation now shows send failed: active backend unavailable instead of silently claiming success. OpenCode and real Claude candidate handoff tests both return replies after old-generation cleanup.
  • Changelog refresh: every static build fetches a fresh release list; the canonical changelog includes v0.3.20.
  • Interaction polish: right-panel tabs are clickable and terminal mouse/focus/capture behavior is hardened.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.20...v0.3.21

v0.3.20Sep 2, 2026theboringoffice v0.3.20 — bypass works on both backends

Bypass permissions now works end-to-end on both backends.

  • Reliable lifecycle: /bypass builds and starts the replacement before switching. The current backend remains usable during restart, the indicator reflects the active mode, failures retain the old backend, rapid toggles coalesce, stale results are ignored, and discarded candidates are stopped asynchronously.
  • OpenCode: bypass is a process-scoped OPENCODE_CONFIG_CONTENT override on the office-owned child. OFF strips inherited overrides. Project config, parent environment, and brain.json remain untouched. The serve reaper is the sole Wait owner.
  • Claude: --dangerously-skip-permissions propagates through initial Start, death respawn, NewOffice, SwapPrimary, and ReconnectMCP. CLI rejection is actionable.
  • Real provider proof: OpenCode created a file under bypass with zero permission events. Claude ON executed Write with zero EvPermission/can_use_tool; the OFF control prompted and completed after allow-once.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.19...v0.3.20

v0.3.19Sep 2, 2026

Changelog

Other

  • 770629878725a6abf1b978d15f1cf8bc66c11a8a wave 103: fix typing animation hang after boss turn ends without text — tool-call-only turns (boss dispatches sub-agents with no plan text) left the boss-N typing placeholder Pending:true forever because maybeBossCompleted swallowed the completion and nothing else cleared it. OpenCode backend now emits a clearing EvChatBoss on session.idle for the primary (guarded against false mid-turn idles by checking textSess); Claude backend emits the same on the result event that pops the FIFO. The reducer's branch (c) learned to strip stale placeholders without appending an empty bubble when the clearing event arrives, making it a no-op on normal turns where streaming already stripped the placeholder.
v0.3.18Sep 2, 2026

Fixes

  • Pasted images now survive for the assistant to read — the Claude backend wrote [attached file: "path"] text references to temp files that were cleaned up before the assistant could read them. Paste attachments are now persisted to a stable directory so the path reference remains valid after the send pipeline's cleanup pass.

  • Bypass permission mode no longer gets stuck on "restarting" — when a backend build result arrived with a stale transition ID, the bypass latch (bypassRestarting) was never cleared, permanently wedging future /bypass toggles. Both stale-transition guards now properly release the latch.

v0.3.17Sep 2, 2026theboringoffice v0.3.17 — attachment routing after swaps

Fixes Markdown/code attachments after backend switches and bypass respawns.

  • Ordinary Enter now resolves the current backend when the send command executes. /backend and /bypass can no longer leave chat pointing at a stopped backend.
  • Backend generations transition accepting → draining → retired: new sends switch immediately, preaccepted sends may finish, and old teardown happens asynchronously without freezing the UI.
  • Claude stdin write failures return real errors instead of false success, so queued attachments remain retryable.
  • End-to-end app-to-wire tests cover OpenCode immediate sends, queued/reset retries, and replaced native Claude. Markdown and Go files are always quoted absolute path references; zero text media parts are emitted.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.16...v0.3.17

v0.3.16Sep 1, 2026theboringoffice v0.3.16 — attachments, themes, Windows

Three rough edges closed in one release.

  • Attachments no longer break Claude providers. OpenCode uploads only content-validated images and PDFs. Text, source, archives, and other files become safe absolute path references that the agent reads with its file tools. Spoofed media MIME falls back to a path reference. Native Claude now implements attachment sending instead of silently dropping files.
  • Themes are coherent again. The sidebar wrapper and PanelBox own one continuous per-theme background; ordinary chat, tool, output, roster, board, and picker text inherits it instead of drawing black/white rectangles. Active selections, diff tints, and terminal ANSI backgrounds remain semantic. Theme identity now invalidates the frame cache, including automatic light/dark switches.
  • Windows installer support. A PowerShell installer and Windows getting-started documentation are included.

Independent review caught and fixed a MIME-spoof bypass and missing-file transcript-count mismatch before release.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.15...v0.3.16

v0.3.15Sep 1, 2026

Changelog

Other

  • a0da7fb33ad07bc23451512f68b1ce7e79e692cc wave 99: panel elements inherit PanelBg — every styled span inside the sidebar panel now carries the PanelBg background instead of defaulting to the terminal bg. New OnPanel/OnPanelBold helpers + 8 Panel* style variants (PanelDim, PanelHeader, PanelAccent, PanelErr, PanelOK, PanelInfo, PanelTool, PanelWarn) in chrome/styles.go mirror the OnBar pattern; all 14 panel files updated to use them. No more visible background holes between PanelBox fill and element text.
v0.3.14Sep 1, 2026

Changelog

Other

  • c890841e4750f26363c1466d2b4ea91dbcd0c0cb add changelog page to website — fetches GitHub releases at build time, renders all versions with markdown bodies. Nav link added (desktop + mobile).
  • 57e7619809be500033b5fc65a82bb462de1bed47 wave 98: panel background tint — new PanelBg theme color gives the sidebar panel a subtle offset from the terminal background. All 5 themes (noir, paper, mono, dracula, solarized) carry the tint; PanelBox border + fill use it, model.go sidebar container too.
v0.3.13Sep 1, 2026

Changelog

Other

  • a5cd7934364b10af4b6bbc9b26978f5ba46c0076 wave 97: /done no longer freezes + ESC exits /btw — two fixes: (1) /done called SwapPrimary synchronously on the UI goroutine (30s teardown+spawn parked the input); now rides a tea.Cmd via new doneOfficeMsg, same async pattern as /btw's btwOfficeMsg — transient "returning from btw…" notice while in flight. (2) ESC key exits /btw mode: new handler in handleKey (after thread-focus and model-picker, before tab switches) calls shared exitBtw() when btwSaved is non-nil. Status bar, notices, and command palette all updated to show "esc or /done to return".
v0.3.12Sep 1, 2026

Changelog

Other

  • b1fa4860e10ae0f45f57fa36802230b56391eee7 wave 96: /btw async + stream-path subagent hire — two fixes: (1) /btw no longer hangs the UI — NewOffice() (30s teardownProc drain) now rides a tea.Cmd with btwOfficeMsg carrying the result back; snapshot restore on failure, trailing-text send on success, transient "starting btw session…" notice while in flight. (2) claude backend subthread registration: stream-path content_block_start for Agent/Task tools now early-hires via claudeIssueEmployee (new isSubagentTool helper) so ownerFor resolves before the snapshot arrives — previously subagent tool calls between stream start and snapshot fell through to the "taskgast" ghost fallback. Snapshot path enriches stream-hired tasks with description when it lands (fixed dead-code check: compared against default "untitled brief" title, not empty string). snapshotIn set on enrichment path so claudeToolFold freezes correctly
v0.3.11Aug 31, 2026theboringoffice v0.3.11 — click a tool call, see its output

Every tool row in the transcript now answers the obvious question: what did it return?

Click any tool call (any kind — bash, read, write, grep, everything) and it expands with the tool's captured output: wrapped, capped at 12 rows with a tail note, 8000 bytes tail-kept so the error at the end is never cut. Running tools and output-less calls show an honest no output as such. Done events update an expanded row in place; worker-thread tool calls expand too; both backends feed it (claude tool_result, opencode state.output — schema verified against a live serve).

Also in this window: the sibling wave 95 shipped /btw side-sessions and a claude backend hardening pack (v0.3.10).

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.10...v0.3.11

v0.3.10Aug 31, 2026

Changelog

Other

  • 274caa708cf7251f4f6805361a06ecd4a9367bc5 wave 95: /btw subchat + claude backend fixes — /btw opens a side session (saves chat/tasks/mails + mints fresh backend session; /done restores via new SwapPrimary seam); claude backend: detect "Agent" tool name (newer CLI renamed "Task"), emit EvFire on subagent completion (employees no longer accumulate), fix double-spawn race in Send (CAS on died under lock), fix signal-to-recycled-PID in ReconnectMCP (Process.Signal instead of raw syscall.Kill), handle control_cancel_request (stale permission prompts cleared), fix snapshotIn ordering (set after hold creation), emit EvTool done for Task/Agent tools
v0.3.9Aug 30, 2026theboringoffice v0.3.9 — byte-exact charter freshness

One-line policy, shipped: on claude-only offices the seeded .opencode/oikonomos.md now refreshes to the embedded charter whenever it drifts (absent, stale after an upgrade, or hand-edited) — the same office-owned discipline the opencode pass has always had. Fresh files cost zero writes and zero boot notes. Members edit CLAUDE.md, never the payload.

Live-verified on the real CLI: the boss recites all five developer return-contract sections (DONE/FILES/VERIFY/PROOF/ISSUES) from the real charter through the office's own spawn path.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.8...v0.3.9

v0.3.8Aug 30, 2026theboringoffice v0.3.8 — the charter reaches claude

Fixes the 'claudecode work is mediocre while opencode flies' gap.

Root cause: the office injected its oikonomos manager protocol only into opencode's config file. Claude Code reads project memory (CLAUDE.md) — which the office never wrote, so claude bosses worked unprimed: no decomposition discipline, no permission etiquette, no proof-of-work contract.

Now claudecode boots get the same charter: the office writes CLAUDE.md (created with an import of the bundled oikonomos charter when absent; an idempotent marked block appended below your content when you already keep one — your bytes are never touched). Live-verified against the real CLI: a marker planted in the charter comes back verbatim from the boss through the office's own spawn path.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.7...v0.3.8

v0.3.7Aug 30, 2026theboringoffice v0.3.7 — warm paper light theme

Website-only wave: the light theme trades sterile white for a warm off-white paper tone across the page, hero/CTA bands, and chrome — cards and popovers stay white so the layering still reads. Dark mode untouched. Verified on a real headless-Chrome capture of the built site.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.6...v0.3.7

v0.3.6Aug 30, 2026theboringoffice v0.3.6 — theme-consistent sections

Website-only wave: the light theme, finished.

  • Every section matches — light mode no longer has dark islands: the hero plasma band, the workflow CTA band, and every terminal-screenshot frame follow the theme (dark mode is byte-identical to before).
  • Terminal shots invert — in light mode the dark terminal screenshots flip to light via invert(1) hue-rotate(180deg), chosen on side-by-side captures over plain invert (your blue accent stays blue instead of clashing orange). Applied to docs shots, home shots, the demo video frame, and the hero plasma canvas.
  • Footer CTA buttons no longer render black-on-black in light mode.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.5...v0.3.6

v0.3.5Aug 30, 2026theboringoffice v0.3.5 — light-first site + AGENTS.md field guide

No Go changes in this release — website and content only.

  • The website goes light-first — a full light/dark/system theme: light by default, the old dark design pixel-preserved as the dark variant, an anti-FOUC script so the first paint is always the right theme, and a sun/moon toggle in the header (persisted, instant, follows your OS in system mode). Verified with a CDP-driven real Chrome session.
  • New blog: AGENTS.md best practices — 'the agent reads it before your code': a 3,500-word field guide to project-level agent instruction files (AGENTS.md, CLAUDE.md, and the neighbor formats), with a comparison table of the landscape, verified sources, and an honest 'when this is the wrong move' section.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.4...v0.3.5

v0.3.4Aug 30, 2026theboringoffice v0.3.4 — bypass permissions mode

The deliberate escape hatch, supported by both backends.

/bypass toggles a session-scoped bypass-permissions mode. Enabling asks for an explicit confirm first — agents will run tools and browser actions WITHOUT asking, this office session only — disabling is instant. While on: a loud amber ⚠ BYPASS segment rides every tab's topbar; claude respawns with --dangerously-skip-permissions (your session context resumes); opencode's config merges a permission allow-all (your explicit deny rules still win); any stray ask is auto-approved with a dim log row; and the office's own browser-action prompt is covered too. Nothing is written to disk — every boot starts with bypass OFF.

Live-verified against the real claude CLI: a bypass run completed a Write-tool turn with zero permission asks on the wire.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.3...v0.3.4

v0.3.3Aug 28, 2026theboringoffice v0.3.3 — docs catch-up + picker polish

No behavior cliffs here — just everything made legible and consistent.

  • Docs fully catch up — the website's browser-tab page covers the e/O keys, shot mode, and the agent's full tool belt; keys-and-slash gains the browser key table, paste behaviors, picker search, and shift+enter/ctrl+j; install flags documented. The README gains a compact Keys section (office + browser gestures, paste chip, picker search).
  • Picker search harmonized — the /session picker rises to the house contract: accent-highlighted match spans, esc clears the filter before it closes, and pastes land in the filter. The @ attach picker highlights your matches (its query stays in the draft, by design).

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.2...v0.3.3

v0.3.2Aug 28, 2026theboringoffice v0.3.2 — the UX wave

Small-surface quality-of-life, all end-to-end.

  • Paste works everywhere — one deliberate paste router sends your paste to the thing that's focused: the question dialog's answer block (batched, multi-line), the embedded terminal's shell (bracketed-paste wrapped), the model picker's filter, or the chat. Nothing ever eats a paste silently again.
  • Chat paste grows up — big pastes (>20 lines or >2000 chars) collapse to a one-line chip ("pasted 31 lines · 433 chars"); one backspace deletes the chip; the full text still reaches the agent. Small pastes insert literally, and shift+enter / ctrl+j give you newlines.
  • /model picker search — type to narrow (N/M badge, filter row, no-matches state, esc clears then closes). /session and the @ attach picker already had it.
  • Browser tabe edits the URL inline in the location bar (enter opens, esc cancels); O opens the current page in your OS browser.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.1...v0.3.2

v0.3.1Aug 28, 2026theboringoffice v0.3.1 — zero follow-ups

Every open follow-up from the browser pivot, closed end-to-end.

  • Pixel-exact screenshots — the office now asks your terminal its real cell pixel size (CSI 16t) and sizes the headless viewport exactly: an 80x43 pane renders 1280x1376, retina-crisp. Fallback stays graceful on non-answering terminals.
  • Shared renders — a 30s LRU + singleflight cache inside the engine means the agent tool and the tab display never render the same page twice; concurrent requests share one Chrome run.
  • Browser actions — the agent can click, fill inputs, and eval JavaScript on pages (both backends). Every action asks your permission first through the office's existing modal (approve-once), and the result comes back to the agent as a follow-up message. Verified live on real Chrome.
  • Chat image previews finally paint in production — a wave-64 bug (the TUI renderer eats in-band image escapes) is fixed by routing previews through the frame splice; they scroll with the transcript and delete when scrolled off.
  • Bandwidth — the image splice now only emits on changes (plus terminal-erase repairs), collapsing the re-emit stream.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.3.0...v0.3.1

v0.3.0Aug 28, 2026theboringoffice v0.3.0 — the browser pivot

The browser tab stops fighting the terminal and starts showing you pages.

What's new

  • Headless screenshots are the browser display — every open (yours or the agent's) renders the page in headless Chrome (pure-Go CDP, uses your installed Chrome/Chromium/Edge) and shows the PNG inside the tab on kitty/ghostty; everywhere else you get the text lane plus the saved PNG path. Static, crisp, always works — no live compositor fighting over your terminal.
  • Agent tools (opencode + Claude Code) — the boss can now take a screenshot of a page for you (browser: shot of <url> → <path> rows) and read pages itself (snapshots come back to it as follow-up messages it can quote from).
  • The embedded zenbu lane is opt-in — retained for the kitty/ghostty+terminal-browser crowd behind THEBORINGOFFICE_ZENBU_LANE=1; the installer's terminal-browser stage is now --with-terminal-browser.

Reality checks

  • chrome missing → the pane tells you how to fix it (THEBORINGOFFICE_CHROME); refusal/timeout rows are exact.
  • Verified on a live drive: /open on the real app produced 46 stable-id PNG frames in the real TTY stream, and the decoded frame is the fully rendered page.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.30...v0.3.0

v0.2.30Aug 28, 2026theboringoffice v0.2.30 — freeze keeps the chain

Fixes the base64-text leak members saw when re-opening the browser tab on v0.2.29.

Root cause: the keep-alive freeze SIGSTOPs the child mid-chunk constantly; resetting the splitter dropped the chain's head, so the thawed tail (pure base64, no escape opener) painted as text. Freeze now parks consumption only — the pending chain is preserved and the thawed tail completes it into a valid frame. Proven across 40 forced mid-chain freezes with zero base64 on grid or scrollback, and mutation-tested by restoring the old behavior (which reproduces the exact rows from the member's screenshot).

Also adds cmd/kittyprobe: a tiny diagnostic that asks your terminal which kitty frame shapes it accepts (the terminal answers in its own words) — built for the ongoing empty-pane investigation.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.29...v0.2.30

v0.2.29Aug 28, 2026theboringoffice v0.2.29 — the page never leaves

The embedded browser now survives tab flips.

Before: leaving the browser tab (ctrl+b / q / esc) killed the embedded terminal-browser session — returning meant an Electron cold boot and a full reload.

Now: leaving the tab FREEZES the child (SIGSTOP, zero CPU) and hides the image; returning thaws the same process and repaints the retained frame in ~10ms. Verified on a live drive: same pid across flips, 4 seconds of frozen silence, instant repaint, and the image still deletes before alt-screen exit at quit. Quit/close/open-new-URL semantics unchanged.

Also in this release: attribution default-on core (config + app layer) from a parallel wave.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.28...v0.2.29

v0.2.28Aug 28, 2026theboringoffice v0.2.28 — the embedded browser holds still

Fixes the three defects members hit in v0.2.27's premium browser lane, all verified on a live Ghostty drive:

  • No more flicker — the office re-ided every frame by content hash, forcing a delete+re-emit cycle at ~2fps (flash, empty, flash). Image ids are now stable per child frame id, so the terminal replaces atomically in place: 55/56 consecutive frames on a live drive with zero interleaved deletes.
  • No more wrong size — frames now carry the pane's exact cell box (c=/r=), so the page scales INTO the pane instead of painting at native pixels.
  • No more base64 text — partial kitty transmissions on session churn (tab flips, respawns) are discarded instead of painting ~30 rows of base64; a racy interleaved-sequence case the real child produces is handled too.

The page now renders, scales, and stays. kitty/ghostty + terminal-browser on PATH.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.27...v0.2.28

v0.2.27Aug 27, 2026theboringoffice v0.2.27 — the page you see is the page

The premium browser lane now actually paints.

What was wrong: terminal-browser streams pages as kitty graphics escapes (chunked RGBA frames). Two bugs compounded: the lane's text grid consumed the stream (base64 garbage / blank body), and even correctly-captured image escapes could not reach your terminal — the office's TUI renderer silently drops zero-width APC sequences inside the view string.

The fix: the lane splits the child's PTY stream — kitty escapes go to a bounded image store, text chrome keeps rendering in the grid — and a frame-output splice (tea.WithOutput wrapper) re-emits the live images at the pane's exact cell origin after every renderer flush, with proper deletes on suspend/close/quit. Format-agnostic, verified against the real terminal-browser v0.6.0 wire on a live PTY capture, and production-verified end-to-end: the office's TTY stream now carries the real page frames (0 ESC_G before, 35 after).

kitty/ghostty + terminal-browser on PATH = the browser tab shows the real rendered page, CSS and images included. Everything else (text lane, fallback, floor flip) unchanged.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.26...v0.2.27

v0.2.26Aug 27, 2026theboringoffice v0.2.26 — the browser names its lane

Small release answering one member question forever: why does the browser look like text?

  • The pane tells you its lane — a dim row under the bar now says exactly why you're seeing text: terminal-browser not on PATH (with the install pointer), terminal not kitty-capable, or a kill-switch set. Premium lane shows no hint. Resolved once at pane creation, zero per-frame probing.
  • The installer offers terminal-browser — a new optional stage downloads the zenbu bundle (darwin/linux, arm64 + x64), installs it intact into ~/.local/share/terminal-browser with an exec shim on PATH, verifies --version, and can never abort the install. --skip-terminal-browser to opt out; --uninstall removes bundle + shim.

kitty/ghostty + this release = the browser tab embeds the real browser automatically.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.25...v0.2.26

v0.2.25Aug 27, 2026theboringoffice v0.2.25 — claude wire hardening

Robustness release on top of v0.2.24's browser wave.

  • Permission events carry the session id again — the real claude 2.1.247 can_use_tool envelope omits session_id (live-captured); the mapper now falls back to the pinned primary session instead of emitting an empty field.
  • 2.1.247 wire-shape pins — fixtures for the newly observed frame subtypes (system/status, informational, thinking_tokens, signature_delta, pre-init control_response ack) lock in the deliberate safe-ignore contract, binary-faithful to the CLI's own emitters.
  • Bedrock id shapes pinned — msg_bdrk_/toolu_bdrk_ flow through the mapping prefix-agnostic.
  • Abort-ladder test de-flaked — stub deadlines 2-4s raised to 8s; green under full-suite parallel load.

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.24...v0.2.25

v0.2.24Aug 27, 2026theboringoffice v0.2.24 — the browser grows up

The terminal office where LLM agents work as coworkers. v0.2.24 grows the browser up and hardens the installer.

Features & fixes

  • Browser lives on the left pane (wave 78) — the left pane is now a two-tab slot: floor (the office, default) and browser, flipped with ctrl+b. The right strip is back to seven tabs. /open <url>, the chat o key, history ring, link cursor — all unchanged, now in the left slot.
  • Agents can open pages themselves — on either backend (opencode or Claude Code) the boss can ask the office to open a URL; the slot flips to the browser and a dim browser: opening <url> (asked by the boss) notice marks who sent you there. Refused opens post the reason.
  • The premium lane is LIVE — on kitty/ghostty with the terminal-browser binary on PATH, the browser tab embeds the real browser (CSS, images, full rendering) at the slot's exact pixel size. Text lane stays the universal default everywhere else; early/non-zero exit falls back to text with the URL kept. Leaving the slot suspends the session, returning resumes it.
  • URL policy relaxed sensibly — localhost always (either scheme), https:// opens any host by default; only plain http:// beyond localhost needs THEBORINGOFFICE_BROWSER_ALLOW_HTTP=1.
  • Claude backend verified LIVE — new opt-in integration tests (THEBORINGOFFICE_LIVE_CLAUDE=1) prove against the real claude CLI: one bubble per message (no doubling), permission ask → answer → tool ran, thinking tokens rendered. Plus regression pins for all three.
  • Installer fix (member-reported) — the agentmemory step no longer 404s (correct scoped package @agentmemory/agentmemory) and can never abort the install again: any npm/init failure degrades to printed manual steps and the installer completes.

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.23...v0.2.24

v0.2.23Aug 27, 2026

Changelog

Other

  • a597274a5dd15fc9f0cc0d471f624c9576464283 wave 74: claude backend end-to-end — permission modal + 28 dialog kinds + thinking/transcript rendering
  • fcd0efba967b00fe778ac2589bdf9a8dd9fa3a63 wave 75: agent browser-open tool + browser tab on the left pane (app/state/panels)
  • 38305118f155faf20b5c361d1b3551f420287684 wave 76: docs — browser-tab page + README dialog-kinds/browser copy
  • 56f1941bdb6caf05de5028ef1edbf6e8da363ad4 wave 77: office ledger — recorded dispatches for waves 74-76
v0.2.22Aug 27, 2026theboringoffice v0.2.22 — the office gets a browser

The terminal office where LLM agents work as coworkers. v0.2.22 ships the browser tab end-to-end.

Features & fixes

  • Browser tab (wave 73) — a new tab after git: a text-mode HTML viewer right in the left panel. Headings, bold text, link-index navigation, back/forward history ring, slash command to open a URL, esc to go back. Works on every terminal, no extra tooling needed.
  • Zenbu premium lane — on kitty-capable terminals with zenbu installed, the browser tab upgrades to a real embedded browser PTY (spawned with exact pixel size, group-kill + reap on exit). If the lane exits early (under 300ms) it falls back to the text lane with a dim note — you never lose the page.
  • Deterministic proofscmd/uishot --browser and --browser --lane kitty render the tab against a fixture for docs/screenshots.
  • Also in this release: Claude backend works (no init wait, floor seats instantly, ~/.claude config default — v0.2.21), gitx/attribution for majdoor-authored child-process env (opt-in), plus everything since v0.2.20: transcript images, open-in-browser hotkey, board sync, wedge-out-of-transcript, gitignore attach picker, plan-editor selection engine, memory wave, docs site.

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.21...v0.2.22

v0.2.21Aug 27, 2026theboringoffice v0.2.21 — Claude works, attribution works, everything works

The terminal office where LLM agents work as coworkers. v0.2.21 fixes the Claude backend end-to-end and ships the attribution layer the tag kept missing.

Features & fixes

  • Claude backend never times out on init (wave 71) — Start seats the floor immediately and returns nil; system/init becomes async metadata pinned when it lands (the input-gated init bug, proven locally). primaryID becomes empty-tolerant with PrimaryOverride override-wins semantics; CLAUDE_CONFIG_DIR defaults to ~/.claude so existing logins carry over; sandboxing stays available only via explicit THEBORINGOFFICE_CLAUDE_CONFIG
  • gitx/attribution (wave 72)WithMajdoorAuthorEnv + MajdoorEnvMerge for spawned child processes; opt-in via THEBORINGOFFICE_MajdoorFlag; every spawned backend/terminal child now gets majdoor-authored git identity without touching the harness
  • Full chain shipped: transcript images (62), open-in-browser hotkey (65+66), zenbu terminal-browser lane (70), board sync (53), wedge-out-of-transcript (55), gitignore attach picker (66), terminal capture re-key (44), plan-editor selection (63), memory wave (52), docs site (67-69), Claude Code backend (56-59)

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.20...v0.2.21

v0.2.20Aug 26, 2026theboringoffice v0.2.20 — sight, sound, and the open road

The terminal office where LLM agents work as coworkers. v0.2.20 teaches your office to see — boss turns render inline images — and opens the road to the web from inside the transcript.

Features

  • Inline image previews (wave 62) — every completed boss turn with file parts renders a 🖼 <name> · <WxH> · <mime> chip + box-averaged raster preview of the first 64×20 cells with 24-bit 38;2/48;2 half-blocks (works on every terminal). Payload caps: 8 MiB, decoded dims ≤10k, ≤4 images per turn, pending bubbles never show previews, remote URLs never fetched
  • Terminal protocol detection layerui.images = "auto" | "ascii" | "off" + /images cycler: path auto → kitty placeholder lines (ESC_G a=T,t=d,f=100,i=<hash8>,q=2 on kitty && Ghostty) → iTerm2 OSC 1337 (inline=1;width=<cols>:height=<rows>;base64,…) → ASCII half-block fallback; strict kitty→iterm→ascii fallback with native-error recovery
  • o open-in-browser (wave 65) — press on any bubble carrying verified targets (schemed URLs, on-disk local paths verified by os.Stat, boss media): · o (open) beacon marks it; o floats an OPEN IN BROWSER picker or dismisses one-off direct; exec.LookPath(open|xdg-open) with activity logging → opened: <name>; the claim holds only while transcript is focused and the selection mark is live, and only outside modals — it never steals keystrokes from free typing
  • zenbu terminal-browser lane (wave 70) — on kitty-capable terminals (kitty, Ghostty, WezTerm), open targets in-terminal via terminal-browser binary when installed, cascading cleanly to system-open on non-zero exit or host mismatch; THEBORINGOFFICE_TERMINAL_BROWSER_OFF=1 kills the lane without touching anything else (no config changes, no API surface)
  • Neighbourhood chain in the box — the full waves leading here: Claude Code backend (56-59), memory wave (52), board sync (53), wedge-out-of-transcript (55), terminal capture re-key (44), gitignore attach (66), docs site (67-69)

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.19...v0.2.20

v0.2.19Aug 26, 2026theboringoffice v0.2.19 — images, selection, and Claude in the office

The terminal office where LLM agents work as coworkers. v0.2.19 opens the eyes and the edit hand of your transcript — and ships Claude Code as a first-class brain alongside opencode.

Features

  • Inline image previews in transcripts (v1) — boss turns carrying a file part render inline: a 🖼 paste-diagram.png · 8×8 · image/png chip plus half-block truecolor raster rows ( glyphs with 24-bit 38;2/48;2 cell pairs — works everywhere). Box-averaged downsample capped at 64×20, payload cap 8 MiB, decoded dims ≤10k, ≤4 images per turn, remote URLs never fetched, pending bubbles never show images
  • Terminal protocol detection layerui.images = "auto" | "ascii" | "off" with a live /images cycler: kitty placeholders (kitty/ghostty), iTerm2 OSC 1337 (iterm2/wezterm/vscode-optin), ASCII raster fallback everywhere else; TMUX, Apple Terminal, and dumb terminals fold to chips
  • Complete plan-editor selection engine — shift-motion marking (rune and visual-row), ctrl+a select-all (textarea's own LineStart rebound to home), esc collapse, mouse drag across wrapped rows, rune-exact cut/copy through the clipboard seam with pbcopy verdict routing and the Copied N chars toast, paste-over-selection routed so it can never land in the chat draft, an SGR-7 highlight unfurled per wrapped segment, blur clears the mark, and a live footer while a mark is armed
  • Claude Code as a second backend (waves 56–59) — stdio claude CLI sibling backend behind backend.NewClaude: stream-json framing, system/init/user+assistant/stream_event/result/api_retry/control_response mapping, per-turn usage deltas, interrupt→SIGINT→SIGTERM ladder, resume spawn, byte-deterministic --claudestub and --claude uishot, /backend slash with drain-first switches, install-select --backend opencode|claudecode, per-backend session pins, topbar backend awareness, and CI-proof classes (stopDrainTimeout/stopKillGrace/sendTermMouse)
  • Board sync + memory wave (52)reconcileBoardDone, /memory [filter] slash, project ledger in .opencode/office-ledger.md + agentmemory mirror, boot splash lane status, and the wedge watchdog that one-notices per turn without ever landing in the live chat transcript
  • Terminal capture re-key (44) — one key toggles shell capture both ways (ctrl+space)
  • gitignore-aware attach picker (66) — the @ picker no longer lists .venv, node_modules, .pytest_cache, __pycache__, dist/build/target/, or .git/*
  • Full docs site (67–69) — nine handwritten pages at theboringoffice.pages.dev/docs with golden docs/shots/*.png frames posed in browser-chrome figures

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.17...v0.2.19

v0.2.17Aug 26, 2026

Changelog

Other

  • 8ba2f3a194645d9f47b71bd29d6f0b83227b392d wave 54: office sounds library on the website — /sounds page lists the 7 synthesized chimes with duration + waveform + meaning per card; cmd/soundexport deterministically emits the WAVs into website/public/sounds/ (byte-identical to what the office plays); site nav+footer links, sitemap entry, play/pause cards, metadata+canonical+
v0.2.16Aug 26, 2026theboringoffice v0.2.16 — the board stays in sync

The terminal office where LLM agents work as coworkers. v0.2.16 finishes the board's completion loop: no more DOING rows stranded after the work is done.

Features

  • reconcileBoardDone — a completion hook fired at both completion sites (maybeChildReturned + queue done): it sweeps office-owned DOING rows and flips them deterministically:
    • exact-ID rows: untouched (existing flow owns them)
    • same-owner rows: the OLDEST in-progress row of that agent flips
    • normalized title-prefix ≥8 runes (lowercase + whitespace-transported), worker-gated rows also flip
    • cross-worker ambiguity, non-completion kinds, and agentmemory-mirrored rows are silent no-ops — never a false flip, never a race
  • One dim [office] board sync: flipped N rows to done note per flipped batch — the member sees the sync happen.
  • uisot --boardsync deterministic proof: 3 staged doings → return(tekton-1) closes its exact row and the sweep flips skopos-1's oldest → return(tekton-2) flips nothing (worker-collision). Byte-identical across two runs.

Also inside (the ledger wave)

  • Project-wise dispatch ledger (<dir>/.opencode/office-ledger.md) + charter step 4 indoctrination (the boss consults the ledger before re-dispatching) + /memory [filter] member slash + boot-time memory-lane status

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.15...v0.2.16

v0.2.15Aug 26, 2026theboringoffice v0.2.15 — the office remembers

The terminal office where LLM agents work as coworkers. v0.2.15 gives the office project memory so the boss never says "I have no session history" again.

Features

  • Project-wise dispatch ledger — every completed dispatch writes a record (title, worker, verdict, summary, files, verify digest, proof line, timestamp) into <dir>/.opencode/office-ledger.md: newest-first, capped at 50, deduped by ledger ID, byte-stable, and included in the instructions the serve reads
  • agentmemory mirror — the same record goes to agentmemory as an office_dispatch_done observation when the lane is up; file-only degrade when it's not, never blocking the office
  • Charter step 4 — every served project learns to consult the ledger BEFORE re-dispatching ("check it, and agentmemory if equipped, so already-completed work is not repeated")
  • Boot splash & statusmemory: ledger armed (agentmemory OK) or memory: file-only (agentmemory :3111 refused) so silent degrade never happens again
  • /memory [filter] slash — newest-first rows per dispatch: date, title, worker, verdict ✓/✗, files, verify digest; live-only fallback when <dir>/.opencode/office-ledger.md hasn't seeded yet
  • Activity lines[memory] recorded: <title> → ledger rides every completed dispatch alongside its return: mail

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.14...v0.2.15

v0.2.14Aug 25, 2026theboringoffice v0.2.14 — plans that look like plans

The terminal office where LLM agents work as coworkers. v0.2.14 stops the plan pane from swallowing your boss's status chatter.

Fixes

  • Plan-pane shape gatepresentBossPlan now presents left only when the reply looks like a plan: a markdown structural signal (heading, bullets, numbered steps, code fences, or a bold section label) plus ≥3 lines and ≥160 non-whitespace characters. Boss narration stays in chat where it belongs
  • Plan-present behavior preserved: a proper plan arriving after chatter still opens; if a plan already lives in the pane and the boss keeps chatting, the pane keeps the real plan
  • Teaching note for the empty-pane vacuum: "boss is chatting; when it writes a plan it lands on the left", fired once per session
  • Persistence gate — the same shape test guards what can survive in session.json
  • Scripted realityuisot --planshot now demonstrates the exact trajectory: boss replies with two chatter lines → pane STAYS hidden, then one # Goal/# Steps plan → pane opens (byte-deterministic twice)

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.13...v0.2.14

v0.2.13Aug 25, 2026theboringoffice v0.2.13 — one click to the thread

The terminal office where LLM agents work as coworkers. v0.2.13 opens the door on every thread row.

Features

  • Click any thread row into the focus viewThreadRowAt, a new read-only hit-test over the thread hit-map: collapsed threads resolve their header and sneak rows, expanded threads resolve their header and closing rows; internal tool rows never resolve, and floating cards (question, permission, picker) always keep precedence
  • Wedge notices are boot-scoped now — the red "boss turn wedged" line renders with a boot-warn mark, is stripped from session.json, and never accumulates stale copies across boots
  • MCP servers listing per project — every directory the backend serves gets .opencode/mcp-servers.md, so the boss and her developers see exactly which servers their project has
  • Typed-slash flake determinism — the /power saver leg of uisot --power all is driven synchronously through the real slash pick→commit path (no more popover-prefill-residue concatenation); README documents the long-memory narrative

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.12...v0.2.13

v0.2.12Aug 25, 2026theboringoffice v0.2.12 — scroll back in time

The terminal office where LLM agents work as coworkers. v0.2.12 teaches a long memory to the transcript.

Features

  • Older-history pagination — scroll to the top of the transcript and the office walks one page further back: one async page-walk per landing (10s deadline), byte-stable anchor prepends, drained-top latches silently, three-strike failure backoff without banners, hydrate/live-echo dedupe so nothing renders twice, and question/permission floats politely suppress the gesture
  • Demo parity — the scripted tour walks its canned 500-row history end to end

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.11...v0.2.12

v0.2.11Aug 25, 2026theboringoffice v0.2.11 — lighter on the machine

The terminal office where LLM agents work as coworkers. v0.2.11 makes the office measurably kind to your machine.

Performance (measured on this build)

  • Transcript virtualization — every timeline item renders through a per-block cache (fingerprint-invalidated, LRU); only touched blocks re-render, historical boss bubbles never see glamour twice. The windowed viewport projects only the scroll region — no more whole-transcript walks per frame
  • Measured: chat test hot path 4.07s → 3.06s wall (−25%), renderer work ∝ what changed, not what exists
  • Reducer hot path — tail-first replace scans (stream deltas hot at O(1)), appendChat capacity reuse, the git rev-parse probe moved off the Frame path (stale-now, refresh-async)
  • Measured: stream-delta probe −28% wall
  • Idle diet — the 83ms spinner chain gates on real liveness (zero forced frame renders per second when quiet), ambient chatter via allocation-free RNG, parked offices skip sprite churn, panels fingerprint-skip redundant renders
  • Measured: total wall −23.5%, sampled CPU −61%, math/rand fully out of the tick profile

Fixes

  • Older-history pagination groundwork (500-row demo history, live paged fetch)

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.10...v0.2.11

v0.2.10Aug 24, 2026theboringoffice v0.2.10 — threads in focus

The terminal office where LLM agents work as coworkers. v0.2.10 gives your threads a room of their own.

Features

  • Thread focus viewctrl+f opens the current worker thread fullscreen: its complete transcript (tool calls, per-call diffs, thinking) in a nested panel. esc or ctrl+f bounces back with state byte-identical; boss questions and permission asks still outrank and dismount it immediately
  • Per-tool-call inline diffs — every Edit/Write/Create call inside a thread now shows its own diff: [tool] Edit x ✓ · +8 −3 on the row, ↳ diff · path beneath it, click to open the full line-numbered patch (created files render as new-file pseudo-diffs)
  • Boss bubbles finally aligned — glamour's leading blank frame row is stripped: the prefix now rides its first body line instead of an empty label row
  • Wedge watchdog, gentler — one notice per turn, not one per quiet stretch; the hint vanishes the moment traffic resumes

Also inside

  • MCP prompt attachment (<dir>/.opencode/mcp-servers.md): every project your backend serves learns which MCP servers the boss and her developers may use — discovered from the very config chain the serve reads

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.9...v0.2.10

v0.2.9Aug 24, 2026theboringoffice v0.2.9 — ctrl+space, the key that wasn't tab

The terminal office where LLM agents work as coworkers. v0.2.9 fixes a keybinding that physically collided.

Fixes

  • Capture toggle re-keyed to ctrl+spacectrl+i and tab emit the identical byte (0x09) in every terminal, so pressing tab to leave the terminal tab was read as "dive into capture" and jailed you again. ctrl+space (0x00) is one toggle key that flips shell capture both ways: press to dive in, press again to step back out. ctrl+o remains as a release alias.
  • Released terminal tab now behaves like every other tab: tab/shift+tab cycle, 1..7 jump, ctrl+q arms, letters never leak into the PTY or the chat.

The deep cut (v0.2.2..v0.2.8): mouse selection with verified copy, transcript breathing room, plan/build modes, notifications, the stuck-busy watchdog, the Git tab — all inside.

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.8...v0.2.9

v0.2.8Aug 24, 2026theboringoffice v0.2.8 — calm transcript, opt-in shell

The terminal office where LLM agents work as coworkers. v0.2.8 fixes two of the most visible UX papercuts.

Features & fixes

  • Terminal tab: opt-in capture — the terminal tab no longer jails you: released by default (tab/1–7/ctrl+q work everywhere), ctrl+i dives into the shell (full grab semantics), ctrl+o releases, capture auto-drops when you leave the tab, no memory on re-enter
  • Transcript anchoring — think/tool rows keep first-seen timestamps (nothing swims past its boss bubble); subagent thread groups segment per work epoch so recycled desk names can no longer weld unrelated tasks together (each segment keeps its own title); thread keys anchor on the earliest positive timestamp
  • Restore banners stopped duplicating — boot notices are process-local now (never persisted; already-polluted session files self-clean)
  • Wedge watchdog refinement — send-side staging placeholders no longer masquerade as boss activity (completion event semantics)

Also inside

architecture docs updated · explicit-pin resume notice self-cleans · charter fan-out manual sharpened · the website gained agent-ops posts and AI-crawler SEO from the parallel sessions

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.7...v0.2.8

v0.2.7Aug 24, 2026theboringoffice v0.2.7 — the Git tab

The terminal office where LLM agents work as coworkers. v0.2.7 puts your repo's state on the floor.

Features

  • The Git tab — a seventh panel showing live repo status: header summary (modified / added / untracked / deleted + line counts), a scrollable file list with status glyphs (M, A, ??, D, R, * = staged), and enter/mouse to drill into the diff — powered by internal/gitx (read-only, 2s-timeout, no-color)
  • Terminal grab semantics — while the terminal tab is active the keys belong to your shell (tab completion, shift+tab, numbers included); the only app-kept keys are ctrl+o (release back to chat) and ctrl+q (double-press quit)

Also in v0.2.x (waves 36–41)

Conversation-first plan mode · plan-mode hardening (double-press approve, flip-on-acceptance) · stuck-busy watchdog + always-working /stop · OS notifications ("the tap on your shoulder") · atomic installer · darwin pbcopy selection hardening

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.6...v0.2.7

v0.2.6Aug 24, 2026theboringoffice v0.2.6 — the tap on your shoulder

The terminal office where LLM agents work as coworkers. v0.2.6 brings you back when it matters — and never recovers wrongly.

Features

  • OS desktop notifications — when your terminal is unfocused and the office is blocked on your decision, one coalesced banner names the employee and tool (permission needed — tekton-1 needs write); when the boss's turn completes, one the boss is done — <gist> ping. A burst of asks is always ONE ping. Zero deps (osascript / notify-send)
  • Focus-aware silence — DECSET 1004 focus reporting: while you watch, the office says nothing at all
  • Controls/notify on|off (persists), ui.notifications in brain.json, THEBORINGOFFICE_NO_NOTIFY=1

Stuck-busy recovery

  • 120s wall-clock wedge watchdog — a red transcript row + hint swap when a boss turn goes silent; never auto-kills
  • /stop always works — even when the serve is dead (unwinds locally, queue intact)
  • SSE re-attach reconciles lost completions; serve-death detection with respawn-on-next-send; session re-anchor clears stale pending bubbles

Also in

  • Installer now installs via atomic rename (no more macOS "Code Signature Invalid" kills)
  • darwin selection copy = real pbcopy with toast gated on its verdict (OSC52 fallback for ssh)
  • --stop uishot proof refreshed to the question-hold roadblock contract
  • internal/gitx — read-only git status/diff backend for the upcoming Git panel

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.5...v0.2.6

v0.2.5Aug 24, 2026theboringoffice v0.2.5 — plans that can't silently flip

The terminal office where LLM agents work as coworkers. v0.2.5 hardens plan mode against every silent flip found in the field.

Fixes (plan/build trust)

  • Approve is now a double-press — first ctrl+x arms with a toast, second inside 1.5s fires. Muscle-memory cuts can no longer nuke plan mode
  • Restored plans aren't approvable untouched — a plan restored from your last session must be opened and edited first
  • Mode flips only on send acceptance — a backend error keeps you in plan with a red approve failed — still in plan row (previously flipped first, asked later)
  • Mid-turn exits are explicit — leaving plan mode while a plan-tagged reply is in flight now posts boss reply landed in chat (plan mode was off when it completed) so a reply never vanishes into the pane's absence
  • Degrade visibility — a serve that rejects the agent field now shows [plan·degraded] in the status bar, a one-time red warning on plan entry, and the rejection itself is a transcript row (was: a single silent statusline flash)
  • Failed sends always land in the transcript as red rows

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.4...v0.2.5

v0.2.4Aug 24, 2026theboringoffice v0.2.4 — conversation-first plans

The terminal office where LLM agents work as coworkers. v0.2.4 makes plan mode conversation-first.

Features

  • Conversation-first plan modectrl+p flips mode only (chat keeps focus, floor stays floor); the boss's finished reply opens the markdown plan pane in the floor slot passively — you keep typing
  • Your edits are safe — once you touch the plan pane, a fresh boss reply never clobbers it; anti-clobber latch with a dim boss replied — your edited plan kept note (test-pinned)
  • Approve from either focusctrl+x on the chat input or in the pane sends the plan to the build agent and flips back; untouched/empty plans refused politely
  • pane opens empty-but-manual-scratch: click it and the starter template (mermaid block) arms

Website

"Plan, then build" section copy + README synced to the new behavior.

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.3...v0.2.4

v0.2.3Aug 24, 2026theboringoffice v0.2.3 — plan, then build

The terminal office where LLM agents work as coworkers. v0.2.3 adds plan/build modes with a real plan editor, plus website polish.

Features

  • Plan/build modesctrl+p toggles a full-pane markdown plan editor in the floor slot: starter template with a captioned mermaid diagram block, glamour-read-only view when unfocused, memoized renders. Plan-mode boss sends ride opencode's native read-only plan agent (agent:"plan" on prompt_async, degrade-open latch for older serves)
  • Approve with one keyctrl+x sends your edited plan to the boss as agent=build and flips the mode home; an untouched template is refused politely. The plan buffer survives reboots (session.json)
  • [plan] status badge + plan-aware hint bars
  • Topbar reads the release stamp — never shows a stale version again (wave 33)
  • Deterministic proofs — new uisot --planshot scenario; stale --layout proof refreshed to the current geometry

Website

Vision/homepage in the human voice (living office manifesto) · under-the-hood (Go binary, power governor, battery-kind) + built-in-public sections · SEO pack (OG/Twitter/sitemap/robots via Cloudflare Pages) · Plan-then-build section with a plan-mode screenshot · mobile staircase fix · MIT license

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.2...v0.2.3

v0.2.2Aug 24, 2026theboringoffice v0.2.2 — a transcript you can touch

The terminal office where LLM agents work as coworkers. v0.2.2 makes the chat transcript interactive, sharpens session lifecycle, and rewrites the website's vision page.

Features

  • Mouse text selection over the transcript — drag-select highlights live (SGR reverse, re-arms across styled chunks); release copies via OSC52 with a transient "Copied N chars" status toast; a motionless press still behaves exactly like a plain click (threads/folds/perm cards); esc clears first
  • Long user messages fold — >3 rendered lines collapse to 3 rows + "click to expand / ... collapse" toggle
  • Whole-bubble thread clicking — expanded threads now register their closing-summary rows (collapsed cards were already fully clickable)
  • Transcript inset — +2 columns of breathing room on both sides of the chat panel
  • Session lifecycle polish (wave 30): /session accept = clean quit + relaunch as -s <pin>; ctrl+q double-press with armed toast; normal exits print session <id> — resume: theboringoffice -s <id>
  • Website: vision page rewritten as the living-office manifesto

Fixes

  • Selection highlight re-arm across lipgloss \x1b[m resets (SGR-empty-param resets previously killed the highlight mid-span)
  • Fatal exit path now stops the opencode serve child (orphan-serve leak)

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.2.1...v0.2.2

v0.2.0Aug 22, 2026theboringoffice v0.2.0 — sessions, models & a visible CTO

Terminal office for opencode — agents as coworkers on an ASCII floor. v0.2.0 ships seven feature waves over v0.1.0.

Features

  • Eager CTO on the live floortheboringcto is seated in his exec suite from boot (demo parity), swaps for the real architecture-brief child on dispatch, re-seats after the batch drains
  • Chat transcript breathing room — one blank row between every timeline item; loop-owned separation, tidy bubbles/cards/diffs
  • Resume a specific past session at boot-s|--session <id> (env THEBORINGOFFICE_SESSION); beats session.json's restore, skips the freshness gate, degrades open on an unknown id
  • /session picker — live resume with a root-session card: type to narrow, wrapped arrows, enter re-anchors, boss-busy refusal, current no-op, esc cancels; pin persists immediately
  • /model list picker — bare /model opens the server's real models (GET /provider): arrows, enter switches the boss model live (persists to brain.json), esc cancels; /model provider/id free-form unchanged
  • Prompt-cache token display — statusbar shows cache NNk once cache reads flow (headline tok and $ untouched)
  • Marketing screenshot pipeline — deterministic cmd/uishot scenarios (--at, --modelshot) + freeze renders at 5086×2896 under website/public/shots/

Fixes

  • Thread click hit-map top-edge off-by-two (first-item thread groups)
  • ListModels rides a file-local ctx-aware GET (no cross-helper collision)

Install / upgrade

curl -fsSL https://raw.githubusercontent.com/theboringhumane/theboringoffice/main/install.sh | bash

Full Changelog: https://github.com/theboringhumane/theboringoffice/compare/v0.1.0...v0.2.0

v0.1.0Aug 22, 2026

Changelog

Features

  • d0126ab190079ac906a761b4a5cbf0a575fb86fb feat(chat): prompt attachments — image paste (ctrl+v) + @ file popover

Fixes

  • 726f05b098b5b349cdf2afd5fbf178dd64e46e07 fix: question-tool deadlock — interactive answer modal + real API answer path
  • 408620a11edb1063e15cdf2e6e9affe17619bb4d fix: stale boss reply on reused sessions (messageID-pinned completion)

Other

  • b14367026f38543b263d5da5b6c98e0c56c1072d Grafeio (γραφείο) v0.1.0 — the terminal office
  • aeb48755a91d387858cafdb7c1893d3d2c3b94a3 Grafeio v2 — Go + Bubble Tea rebuild: tabbed right panel, glamour chat
  • 92091a0805ba2ff1e1992921542e029b7dfbdb66 readme: fullscreen layout + real screenshot gallery
  • 8f0ba5c6d0fb6862789e611466452b6b8df8fb81 ui(chat): subagent threads inline in chat timeline, sorted by time
  • bcb163582509c416ebdc5f6d7884a0cef09f83a9 ui: default sidebar 80 cols, /wide ceiling 100
  • 0337ec1ce50c7acf1b82abefb36093d6dad766ac ui: widen default sidebar 44->68 cols, raise /wide ceiling 60->80
  • e1391e475614aa51401c655007b28bc859b9fbc5 wave 10: vt-grade terminal + chat threads + caret fix + freed boss
  • 123cdb01e9d8d5977ef13bc863ac198e9e296b4b wave 11: session memory, slash popover, agent thoughts, clickable office
  • c093b620b4b4225fe6a0177f0bd81337f729c45d wave 12: bundled manager charter (oikonomos inside grafeio)
  • 84a55ecaeb3aaa27775cf737114489d86b6d0373 wave 13: /stop command, free-send while busy, SSE anti-spam
  • 794c8ba141e66736584554accc75532e77b8ac53 wave 14: office concierge — instant answers while the boss works
  • 7e93d953e5f2fbe52361a054d5b6f84766e93c7c wave 15: full transcript retention, boxed thread cards with carets, team-working loader, cost tag, esc/up back-nav
  • f193aedfa8f50e97917547aa525750d8752ee151 wave 2 — opencode-style fullscreen chrome + pixel-office ASCII floorplan
  • 35309df8445fd2cfd7e5c3b9ae294ef5eb58003b wave 2: thinking/tool visibility, themes, slash commands, dup fix, node-legacy removed
  • 2fc2bde04d47cbd33aad8338308b79bda0dd099f wave 3 — full color: floor + chrome
  • 16cb7ad732dba241d06826b56ce9cb08c7bd32b2 wave 3: permissions end-to-end, question tool, message queue, file diffs
  • 1be39a4d23f41fb3b1ad168d78250930672a22e3 wave 4+5 — screenshot pipeline + art polish + blink fix
  • 8eb7832ab488cc2428ef02f1adbd88f50ecffe2e wave 4: opencode-style colorful diffs
  • fad20cff37b72db8099ad06e804a34a21f54094f wave 5: streaming thinking transcripts
  • ccb2def46dac535ce4dd770b8888fe798e7527a0 wave 6: live-typing boss bubble
  • 0c7bd01f0a48e219a783870e76b2b139abbac0ca wave 7: queue as intelligent backlog — batch dispatch, board rows, respawn
  • 78eed1b08dca1808cc990076225b1af3cccf2520 wave 8: brain.json config + power governor (battery-aware office)
  • ab662acbe43af6202b331795ada9a0f587779f40 wave 8b: office social life + synth sound engine (wired)
  • 259a151d4ddb46ad348bc1f1b57e1b53d747bb34 wave 9: embedded OS terminal tab + configurable/layout modes
  • 8872e0ad02dbcd86e9eb3cf7993dce084d5008ee waves 16-21: theboringoffice — full rename, CTO reviewer (theboringcto), offline mode w/ auto-resume, mobile vertical layout, auto light/dark themes, boss/cto model config, topbar project+branch, goreleaser release pipeline + curl installer, mail boot-panic fix