ALWAYS A WORK IN PROGRESS / CHANGELOG

A little better.
Every shift.

Every release, every improvement, and the details behind them. Follow the office as it grows.

THEBORINGFLOOR / MAKE ROOM FOR POSSIBILITY
  1. 78v0.12.0

    v0.12.0

    Changelog

    Features

    • 69b213ad4b9b139f8b941a36087c4cdcd59e66f3 feat: recover an interrupted codex turn from its rollout store
  2. 77v0.11.0

    v0.11.0

    Changelog

    Features

    • 052f1550fba0a854a1a2fd1ec934483027a4a039 feat: background a busy claude or codex floor instead of refusing
  3. 76v0.10.0

    v0.10.0

    Changelog

    Features

    • 33941f329bbd7bf9815d1f72acf45ea2025b75a1 feat: hand off busy floors to a background office on switch
  4. 75v0.9.0

    v0.9.0

    Changelog

    Features

    • ef3dda90ad60d337db45e0240e234d9d93172aba feat(website): redesign site with cobalt visuals and interactive office
    • 568053bb445826121f0cc377e99a99e14bdaf305 feat(website): showcase themes and add quiet office ambience
    • 1f765ed7aa94ae381f6b3db2f913699bcc65b53e feat: select native models per backend and sub-agent

    Fixes

    • e2b584f62dff4082221c98220fb91e8c5b2708c3 fix(website): calm the mobile hero, swap demo video, drop invert
  5. 74v0.8.0

    v0.8.0 — Cockpit control plane and custom themes

    The terminal office becomes a cockpit, with a much larger theme library and a way to make it your own.

    Cockpit control plane

    • Tactical floor grid, numbered consoles, command input rail, and navigator shortcuts.
    • Live operations instruments show task completion, active dispatches, and agent states from the office's actual data.
    • Instruments adapt to terminal size and collapse when space is tight.
    • Every palette uses the same cockpit layout. Cockpit is the dark default; Paper remains the light default, and existing explicit choices stay pinned.

    Fourteen palettes and VS Code imports

    Added Cockpit, Tokyo Night, Catppuccin Mocha, Catppuccin Latte, Nord, Gruvbox, One Dark, Rosé Pine, and GitHub Light alongside Noir, Paper, Mono, Dracula, and Solarized.

    Type /theme to preview palettes with the arrow keys, Enter to save, or Escape to cancel. /themes lists built-in and imported palettes.

    /theme import "/path/to/My Theme.json"
    /theme export ~/my-floor-theme.json
    /theme reload
    

    Or import at startup:

    theboringfloor --import-theme ./my-theme.jsonc
    

    Export any palette, edit its name/colors/tokenColors, and import it to customize the office. Imports are stored as custom-<name> in ~/.config/theboringfloor/themes/ (or under $XDG_CONFIG_HOME). Reimport the same name to update it immediately, or edit its saved JSON and reload. Exports refuse to overwrite existing files.

    The importer supports JSON/JSONC comments, trailing commas, local relative includes, alpha hex colors, and common TextMate syntax scopes for diff code. Editor, status-bar, border, button, terminal ANSI, and diff colors map to the cockpit, with defaults for missing slots. VS Code-specific components, semantic-token rules, complex language selectors, .tmTheme references, and extension packages do not transfer; import the extension's JSON theme file.

    Fixes and validation

    • Theme content changes invalidate frame, floor, panel, and diff caches, including same-name imports.
    • Floor clicks account for the cockpit's actual position and do not select hidden agents through the instruments.
    • Full Go test suite passed, including layout checks from 40 to 220 columns and import/persistence/reload/error cases.
    • Native PTY smoke tests passed for all 14 built-in palettes and a CLI-imported theme; dark/light imported palettes were also visually reviewed.

    This release also includes the updated printed-document website design.

  6. 73v0.7.0

    v0.7.0 — Attention inbox and connected ticket handoffs

    The office now makes decisions easier to find and tickets easier to follow from handoff to review.

    • Android attention inbox: see floors waiting for plan review, blocked tickets, and tickets ready for review. Open the relevant plan or ticket directly, or switch to All floors to follow ongoing work.
    • Explicit office status: distinguish planning, working, ready, offline, permission requests, and questions. Deferred desktop requests remain visible, and pending plans stay discoverable even when their pane is hidden.
    • Connected tickets: prepare a prompt with acceptance criteria, link the active conversation, and return to it from Android or the desktop board (o). Preparing a handoff stages the prompt for review and leaves ticket status unchanged.
    • Delivery review: record result summaries and verification notes beside acceptance checklists. These are team-authored records, not automatically attested checks.
    • Safer edits: versioned ticket saves reject stale updates. Desktop and Android editors preserve drafts when saving fails.
    • Faster, recoverable mobile startup: startup reads local settings without waiting for the gateway. New connection settings take effect immediately. Failed inbox refreshes retain the last view with a warning; requests are bounded to four concurrent floors and polling stops while the app is backgrounded.
    • Website: new Android feature section with actual Flutter screenshots and updated workspace documentation.

    Update the office and gateway to v0.7.0+ for the new execution metadata and ticket handoffs. Permissions and assistant questions still require the desktop office. The inbox refreshes while the app is open; this release does not add background execution or push notifications.

    Validation: full Go suite, targeted ticket-conflict regression checks, 133 Flutter tests, Flutter static analysis, light/dark phone-size widget renders, production website build and browser checks, and a signed Android release build. Physical-device/emulator validation was not available.

    Android: signed APK · SHA-256 checksum. Published package version: 0.7.0 (81). Signature verified against the existing release certificate.

  7. 72v0.6.0

    v0.6.0 — Android floors and clean conversations

    Android now brings project floors to your phone, with conversations, teams, a ticket board, project files, and plan review in one workspace.

    • Start or resume conversations with Claude Code, OpenCode, or Codex, and assign them to a team.
    • Create teams and edit tickets with status, priority, ownership, descriptions, and checklists.
    • Browse the project tree, preview source with line numbers, and stage a question about a file in chat.
    • Review, edit, and approve plans from Android. New plans open automatically in live chat, and approval checks the exact draft you reviewed.
    • Read clean conversations: the Android app hides tools, reasoning, worker activity, notices, and intermediate prose while preserving user messages and completed assistant replies. Code blocks inside real replies remain visible, and raw session history stays intact.
    • Pick up desktop-started work through idle chat polling, with history cleared correctly when the active backend or session changes.

    Update both floor and floorgate to v0.6.0 or newer for the workspace features. Transcript filtering happens in the Android app and also supports older transcript payloads. Older servers without explicit phase metadata use the last completed primary reply in each user turn.

    The release includes desktop CLI bundles and a signed Android APK. Android version names now follow release tags, with increasing build numbers for future updates.

    Validation: 127 Flutter tests, Flutter static analysis, Go tests, phone-size widget screenshots, and a signed release APK build. No physical Android device or emulator validation was performed.

  8. 71v0.5.1

    v0.5.1 — Solid terminal backgrounds

    Fixes terminal background colors and transparency leaking through the office, transcript, composer, and other views.

    • Paint every app cell with the selected theme's solid background, including blank rows, startup, dialogs, plans, and resized layouts.
    • Restore app foreground/background colors after nested text-style resets while preserving explicit highlights, diffs, and links.
    • Give Noir a fixed RGB palette so terminal themes cannot recolor the app's bars, accents, or office furniture.
    • Cache the fully painted frame to keep redraws inexpensive.

    Validation: full Go test suite, rendered-cell checks across desktop/mobile layouts and theme switches, and 16 Noir/Paper fixture renders against a contrasting magenta terminal background with zero fallback-background pixels inside the UI.

  9. 70v0.5.0

    v0.5.0 — Project floors, Codex, and planning before implementation

    A floor for every project

    • Three panes: project floors on the far left, the office in the middle, and transcript and tools on the right.
    • Persistent project teams and tickets with priorities, ownership, checklists, and five workflow stages.
    • A project file tree with source previews and conversation attachments.
    • Separate conversation histories, titles, teams, and backend selection. Choose OpenCode, Claude Code, or the new Codex backend.
    • Transcript search and improved wrapping, plus metadata-based history listing and bounded local archives.

    Planning before implementation

    Clearly substantial requests enter plan mode before dispatch. The boss also receives instructions to plan major features and migrations before implementing them. Floor MCP plan tools open the plan pane automatically, even from focused or expanded views.

    Attachments retain planning intent. New drafts reset approval confirmation, stale drafts cannot be reused for a new request without review, and a late approval cannot hide a newer draft. Codex uses a read-only sandbox for planning; Claude Code planning remains instruction-based with its existing permissions.

    Simpler setup and updated docs

    The external terminal-browser package has been removed. Built-in text navigation and headless screenshots remain available, and external links use the system browser.

    The website now includes an interactive workspace tour, current application screenshots, and guides for floors, teams, tickets, files, history, and planning.

    Verification

    Go tests and targeted race checks, website production build with TypeScript checks, terminal smoke testing, and desktop/mobile browser checks passed. All 664 checked internal website links and assets resolved.

  10. 69v0.4.5

    v0.4.5

    Changelog

    Other

    • f52ef31f64afab55c5fc1c8e00a4d93f10263d74 wave 116: the phone stops guessing who is working
  11. 68v0.4.4

    v0.4.4

    Changelog

    Other

    • 4707ea8f6725672c99b942ebb3bfc75aca33c974 wave 115: the pocket office learns to keep up
  12. 67v0.4.3

    v0.4.3

    Changelog

    Other

    • 53258b3ab024789bf7224f5658658463616b0a9a wave 114: the chat streams again, behind glass
  13. 66v0.4.2

    v0.4.2

    Changelog

    Other

    • 17c73c6fd8855cda88a1f1f49558c1a0260b9e24 wave 113: the app gets its face
  14. 65v0.4.1

    v0.4.1

    Changelog

    Other

    • af63eef6a3ffca12a89aa8fc88958f4db1c59721 wave 112: the office recovers, and the phone becomes a real client
  15. 64v0.4.0

    v0.4.0

    Changelog

    Other

    • 313689f86428f3a6b166d3c1f4ff890ae031218d wave 111: the office in your pocket

    Android app

    theboringfloor-0.4.0.apk — 50,930,146 bytes, Android only.

    Self-signed. Verify before installing:

    SHA-256 (apk)  4978e35975d11a61bfa8c984ff66cacd775443fa4973a7c710cfe4d086cd29c0
    Signing cert SHA-256  3d:0c:9f:22:46:46:59:cc:aa:c8:f2:a2:8d:7c:91:ed:7e:53:57:0a:d8:4d:d7:e3:8c:aa:19:ea:59:1e:b3:cb
    

    Setup: https://theboringfloor.com/docs/control-plane

  16. 63v0.3.31

    v0.3.31

    Changelog

    Other

    • 478d784351dc9fe382ee2289214362b2f4751d45 site: declare image/png for the generated Open Graph images
    • 4d798fb1a5ca2e5e6ff03dcb2c1c1b2c171ed78f wave 110: hidden side sessions and per-sub-agent models
  17. 62v0.3.30

    theboringfloor v0.3.30 — agents can see the MCP servers they actually have

    An agent asked to use an MCP tool, found no listing of its own servers, and concluded thefloor_mcp was unavailable to it. The server was registered and connected the whole time. Two separate defects made that misreading possible.

    Our own server was invisible to opencode agents

    The MCP prompt attachment is rendered during backend start. mcpinstall.Ensure registers thefloor_mcp from an independent goroutine. There was no ordering edge between them, so on the boot that first registered the server, the attachment was rendered from a config read taken before the write — and thefloor_mcp was missing from the list agents actually read.

    Registration is now sequenced ahead of the charter pass. The regression test covers servers split across opencode.json and opencode.jsonc simultaneously, which is the real-world shape.

    Claude Code sessions got no MCP listing at all

    charter_claude.go had zero MCP awareness. A Claude-backed agent had no way to know which servers existed, so it guessed.

    It now enumerates Claude Code's own configuration — user scope (CLAUDE_CONFIG_DIR or ~/.claude.json), the matching projects entry, and project .mcp.json — honours disabledMcpServers, and writes an attachment imported from CLAUDE.md:

    # Available MCP servers
    
    This Claude Code session has the MCP servers below configured.
    Use only the listed server names when selecting an MCP tool.
    
    - `thefloor_mcp` (stdio) — configured in user config
    

    One file per host

    The Claude attachment lives at .claude/mcp-servers.md, not .opencode/mcp-servers.md. Two hosts rendering different content into one path would overwrite each other on every backend swap, each thrashing the other's skip-when-unchanged check. Each host now owns its own directory, and a regression test pins that the Claude pass leaves the opencode-owned file byte-identical.

    Privacy is unchanged

    Both attachments list names, transport types, and provenance only — never commands, argv, URLs, headers, or environment values. A real Claude config carries an absolute binary path and an env object; neither may reach a prompt.

    Full Changelog: https://github.com/theboringhumane/theboringfloor/compare/v0.3.29...v0.3.30

  18. 61v0.3.29

    theboringfloor v0.3.29 — theboringfloor is the only name

    The old name is gone. theboringfloor is the only name in the codebase, the release pipeline, the installers, and the docs.

    Release assets are renamed

    Archives are now theboringfloor_<version>_<os>_<arch>.tar.gz (.zip on Windows), instead of theboringoffice_*.

    If you have an old copy of install.sh cached, re-fetch it:

    curl -fsSL https://boringfloor.com/install.sh | sh
    

    Your environment variables still work

    Canonical names are now THEFLOOR_* — THEFLOOR_HOME, THEFLOOR_BACKEND, THEFLOOR_THEME, THEFLOOR_NO_CONTROL, and 25 more.

    The legacy THEBORINGOFFICE_* spellings are still read, silently. If you have them in a shell profile, CI job, or script, nothing changes for you and nothing warns at you. The canonical name wins when both are set.

    Every env-name constant was converted and every read of it routed through the new accessor. Converting the constant alone would have quietly broken anyone still exporting the old spelling.

    Your sessions are safe

    Reads consult both same-product layouts, canonical first:

    1. ~/.theboringfloor/projects/<dirhash>/session.json
    2. ~/.theboringfloor/sessions/<dirhash>/session.json

    Writes still land only on projects/. A corrupt canonical file now returns not-found rather than falling through and resurrecting a stale snapshot.

    What was actually removed

    • GRAFEIO_* env vars and ~/.grafeio state — code, tests, docs, gitignore.
    • The ~/.theboringoffice/ read fallback.
    • The theboringoffice command alias. It is no longer created, and uninstall removes one left by an older install. The tbo shim is unchanged.

    Uninstall still works on older installs

    --version output is now theboringfloor v…, but the uninstaller's ownership probe accepts both spellings, so binaries installed from v0.3.28 and earlier remain removable.

    Corrected documentation

    Two pages were promising behaviour that no longer exists: getting-started claimed ~/.grafeio and GRAFEIO_* still worked, and the backends page documented a THEBORINGFLOOR_BACKEND variable that never existed. Both fixed.

    Housekeeping

    Dropped a 29 MB compiled uishot binary that had been tracked at the repo root.

    Full Changelog: https://github.com/theboringhumane/theboringfloor/compare/v0.3.28...v0.3.29

  19. 60v0.3.28

    theboringfloor v0.3.28 — thefloor_mcp: the office speaks MCP

    The office now speaks MCP. A companion binary, thefloor_mcp, ships inside the same archive and registers itself with OpenCode (and with Claude Code when its CLI is present) on first boot.

    Six tools

    ToolArgsNeeds a running office?
    plan_present{text}yes
    plan_update{text}yes
    plan_get_approved{}no — live, else on-disk
    transcript_read{limit?}no — live, else on-disk
    transcript_search{query, limit?}no — on-disk, current project only
    office_status{}no

    Presenting a plan is still presentation only. It never executes work — you review, edit, and press ctrl+x twice. The existing plan markers keep working.

    How it reaches the office

    The office now runs a control API bound to 127.0.0.1 on an ephemeral port, protected by a bearer token, and publishes ~/.theboringfloor/projects/<dirhash>/control.json at mode 0600. HTTP handlers never touch the UI — they emit events onto the Bubble Tea loop and wait for a reply computed on that goroutine.

    Honest limits

    • The on-disk transcript is capped at 200 messages per project, so transcript_search searches the recent tail, not full history.
    • Search is scoped to the current project and cannot read another project's transcript.
    • Write tools have no offline fallback: with no office running they return an error rather than pretending to succeed.
    • The token file is readable by processes running as you. That is the same trust boundary as your SSH keys and your editor's IPC socket, and is strictly stronger than the unauthenticated backend server already listening on loopback.

    Hardening

    Discovery records carry a boot id and are validated by executable name rather than pid alone; the client verifies health returns the expected directory before sending anything else, bounding a port squatter to a single request; stale records are pruned automatically. Automatic config registration preserves large integers byte-exact, writes through symlinked configs instead of replacing them, never touches opencode.jsonc, and routes Claude through its own CLI.

    Uninstall is now ownership-aware: a SHA-256 manifest first, with a bounded --version probe so existing installations still uninstall cleanly.

    Opt-outs: THEBORINGOFFICE_NO_CONTROL=1, THEBORINGOFFICE_NO_MCP_INSTALL=1.

    Full Changelog: https://github.com/theboringhumane/theboringfloor/compare/v0.3.27...v0.3.28

  20. 59v0.3.27

    v0.3.27 — vibrant_babbage

    🏢 vibrant_babbage

    "Click it and it comes back to life."

    ✨ What's New

    • 📌 BTW Pin Row — hidden sessions now resume with a single click on the pin bubble. No more hunting through the transcript to find where you left off.
    • 🧪 btw_hide_test.go — new test coverage for the hidden-session flow.
    • ⚙️ theboringfloor settings bootstrap — .theboringfloor/settings.json ships with the repo.

    🔧 Fixes

    • 🔄 Bypass mode restart — old backend keeps accepting connections during restart so nothing drops on the floor.

    📦 Changelog

    CommitDescription
    b582b68📌 feat: btw-pin row hit-map for hidden-session resume on click
    7e649de🔄 fix: bypass mode keeps old backend accepting during restart

    🤖 Built with care by the boring office.

  21. 58v0.3.26

    🚀 v0.3.26 — Bypass Persistence & Windows Terminal Support

    ✨ What's New

    🔒 Bypass Mode Persistence

    • Project-local settings — bypass mode now saves to .theboringfloor/settings.json in your project root, so it survives restarts
    • Clean backend restart — drain → stop → rebuild lifecycle eliminates the race window that caused message drops
    • No more error sounds — sends during backend transition show a soft "restarting" notice instead of playing the error sound

    🪟 Windows Terminal Support

    • Native ConPTY — terminal now works on Windows via CreatePseudoConsole (no more spawn C:\windows\system32\cmd.exe: unsupported errors!)
    • Platform-split PTY — Unix keeps creack/pty, Windows gets proper ConPTY with full resize, process lifecycle, and pipe I/O
    • Retry spam fix — terminal no longer retries endlessly when the initial spawn fails

    📦 Downloads

    PlatformArchitecture
    🍎 macOSApple Silicon (arm64)theboringoffice_0.3.26_darwin_arm64.tar.gz
    🍎 macOSIntel (amd64)theboringoffice_0.3.26_darwin_amd64.tar.gz
    🐧 Linuxx86_64 (amd64)theboringoffice_0.3.26_linux_amd64.tar.gz
    🐧 LinuxARM (arm64)theboringoffice_0.3.26_linux_arm64.tar.gz
    🪟 Windowsx86_64 (amd64)theboringoffice_0.3.26_windows_amd64.zip
    🪟 WindowsARM (arm64)theboringoffice_0.3.26_windows_arm64.zip

    🔧 Technical Details

    <details> <summary>Files changed (9 files, +698 / -202)</summary>
    • cmd/theboringoffice/main.go — boot-time bypass restore from project settings
    • internal/app/model.go — WithBypassPermissions option, drain-based restart, transition-aware error handling
    • internal/app/terminal.go — one-shot retry guard for terminal spawn
    • internal/app/bypass_test.go — 24 tests covering persistence, boot restore, transition behavior
    • internal/term/term.go — platform-neutral ptyResult contract, removed direct creack/pty dependency
    • internal/term/pty_unix.go 🆕 — Unix PTY via creack/pty (build-tagged !windows)
    • internal/term/pty_windows.go 🆕 — Windows ConPTY via x/sys/windows
    • internal/config/project_settings.go 🆕 — atomic read/write for .theboringfloor/settings.json
    • internal/config/project_settings_test.go 🆕 — 9 tests for project settings infrastructure
    </details>

    Full Changelog: https://github.com/theboringhumane/theboringfloor/compare/v0.3.25...v0.3.26

  22. 57v0.3.25

    theboringfloor v0.3.25 — agent plan tools

    Agents can now work with the office's existing plan pane directly.

    • Present a plan: plan-present fills the plan pane as a draft for member review.
    • Update a plan: plan-update replaces the current draft without changing the last approved plan.
    • Read the approved plan: plan-get-approved sends the latest member-approved plan back to the agent, or an explicit no-plan response.
    • Presenting/updating never executes work. The member still reviews/edits and presses ctrl+x twice to approve.
    • Approved plans persist separately from drafts, capped rune-safely at 20,000 runes.
    • Approval captures one immutable snapshot: the exact capped plan sent to build is the exact plan recorded as approved.
    • Strict block parsing and fuzz coverage prevent nested/overlapping plan markers from panicking.

    Also includes PowerShell installer checksum hardening and tests.

    Full Changelog: https://github.com/theboringhumane/theboringfloor/compare/v0.3.24...v0.3.25

  23. 56v0.3.24

    v0.3.24

    Changelog

    Features

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

    Other

    • b5bd067acc96accd0a9d807915c2cebaa24e5e2d refactor: rename module and update references to theboringfloor
  24. 55v0.3.23

    v0.3.23

    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
  25. 54v0.3.22

    theboringoffice 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

  26. 53v0.3.21

    theboringoffice 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

  27. 52v0.3.20

    theboringoffice 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

  28. 51v0.3.19

    v0.3.19

    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.
  29. 50v0.3.18

    v0.3.18

    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.

  30. 49v0.3.17

    theboringoffice 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

  31. 48v0.3.16

    theboringoffice 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

  32. 47v0.3.15

    v0.3.15

    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.
  33. 46v0.3.14

    v0.3.14

    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.
  34. 45v0.3.13

    v0.3.13

    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".
  35. 44v0.3.12

    v0.3.12

    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
  36. 43v0.3.11

    theboringoffice 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

  37. 42v0.3.10

    v0.3.10

    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
  38. 41v0.3.9

    theboringoffice 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

  39. 40v0.3.8

    theboringoffice 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

  40. 39v0.3.7

    theboringoffice 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

  41. 38v0.3.6

    theboringoffice 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

  42. 37v0.3.5

    theboringoffice 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

  43. 36v0.3.4

    theboringoffice 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

  44. 35v0.3.3

    theboringoffice 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

  45. 34v0.3.2

    theboringoffice 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 tab — e 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

  46. 33v0.3.1

    theboringoffice 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

  47. 32v0.3.0

    theboringoffice 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

  48. 31v0.2.30

    theboringoffice 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

  49. 30v0.2.29

    theboringoffice 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

  50. 29v0.2.28

    theboringoffice 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

  51. 28v0.2.27

    theboringoffice 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

  52. 27v0.2.26

    theboringoffice 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

  53. 26v0.2.25

    theboringoffice 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

  54. 25v0.2.24

    theboringoffice 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

  55. 24v0.2.23

    v0.2.23

    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
  56. 23v0.2.22

    theboringoffice 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 proofs — cmd/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

  57. 22v0.2.21

    theboringoffice 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

  58. 21v0.2.20

    theboringoffice 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 layer — ui.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

  59. 20v0.2.19

    theboringoffice 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 layer — ui.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

  60. 19v0.2.17

    v0.2.17

    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+
  61. 18v0.2.16

    theboringoffice 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

  62. 17v0.2.15

    theboringoffice 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 & status — memory: 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

  63. 16v0.2.14

    theboringoffice 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 gate — presentBossPlan 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 reality — uisot --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

  64. 15v0.2.13

    theboringoffice 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 view — ThreadRowAt, 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

  65. 14v0.2.12

    theboringoffice 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

  66. 13v0.2.11

    theboringoffice 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

  67. 12v0.2.10

    theboringoffice 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 view — ctrl+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

  68. 11v0.2.9

    theboringoffice 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+space — ctrl+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

  69. 10v0.2.8

    theboringoffice 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

  70. 09v0.2.7

    theboringoffice 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

  71. 08v0.2.6

    theboringoffice 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

  72. 07v0.2.5

    theboringoffice 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

  73. 06v0.2.4

    theboringoffice 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 mode — ctrl+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 focus — ctrl+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

  74. 05v0.2.3

    theboringoffice 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 modes — ctrl+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 key — ctrl+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

  75. 04v0.2.2

    theboringoffice 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

  76. 03v0.2.1

    v0.2.1

  77. 02v0.2.0

    theboringoffice 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 floor — theboringcto 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

  78. 01v0.1.0

    v0.1.0

    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