Ctrl K
ComunidadGuías…

CHANGELOG.md

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Changelog

All notable changes to Caprock. Format: [Keep a Changelog](https://keepachangelog.com/).
Versions map to the roadmap phases in `.ai/09-execution-plan.md`: **v0.1.0** = Observe,
**v0.2.0** = Control, **v0.3.0** = Orchestrate. **v0.4.x**/**v0.5.0** are post-Orchestrate
polish (plan-limit windows, orchestrator-lifecycle fixes, Homebrew formula, first-run UX).

## [Unreleased]

Changes waiting for the next release are one file each in `changes/unreleased/`,
assembled into a version section here by `scripts/changelog.py` when a release is
cut; `scripts/changelog.py preview` prints that section now. The format is in
`changes/README.md`.

## [0.175.0] - 2026-11-07

### Added

- **machines:** a prompt on another of your computers can be approved or
  denied from the app's notification, as one on this computer can (macOS and
  Linux); the answer goes to that computer through the link, and a prompt
  answered there first takes the notification away.
- **machines:** the Cost screen has **This Mac / All computers**: with
  another computer linked, *All computers* shows each computer's spend,
  priced with its own table, and the total of those that answered. A
  computer that did not answer is named as not counted, never as $0.
- **machines:** a linked computer's access is now bound to that computer's
  own key, with nothing to do: a copy of it taken off that computer works
  from nowhere else.
- **docs:** `docs/machines.md` says what the hosted relay
  measured, how and when to run your own relay, and how to measure a link
  between two computers.
- **storage:** The status strip at the bottom of the window shows how far
  compression has got (*Compressing · 40% · 224.6MB saved*), and once it has
  caught up and packing the file would free a meaningful amount, offers *Pack
  database · ~85 s*. A click opens the details: how long it takes and what it
  frees, both estimated from this database, that sessions keep running and new
  events wait, and **Pack now**. Every event that arrives during the pack is
  recorded when it ends. The pack shows a progress bar measured from what
  SQLite has written. `GET /v1/storage/pack` reports the job and the pack,
  `POST` starts one, and `GET /v1/storage`'s `compression` gains the job's
  progress.

### Fixed

- **storage:** Compress tool output now works on a computer whose agents never
  stop. It waited for 30 minutes with nothing recorded, which agents running
  around the clock never leave, so with the setting on all night it compressed
  nothing. Its steps — and the base64 compaction's, and incremental vacuum's,
  which give free space back to the disk — now run whenever writes pause for
  5 seconds, give way to any write that arrives, and rest nine times as long
  as each step took, so they use at most a tenth of one core.

## [0.174.1] - 2026-11-07

### Added

- **machines:** `GET /v1/machines` says what each linked computer's channel
  has cost the relay (`traffic`: messages and bytes each way since the daemon
  started or paired it), and `bench/peer.mjs --idle N` measures a window left
  open — so the hosted relay's free-plan headroom is read, not guessed.

### Fixed

- **ui:** the Agent panel's header shows the session's portrait again: the
  face you picked for it (a duck, a crown, a pumpkin…) or its own, large,
  where 0.174.0 drew only the agent's mark. A click on it still picks the
  face, and the mark is a small badge on its corner, so Claude and Codex
  still tell apart. The header is symmetric: the portrait is as tall as the
  figures beside it, so both columns start and end on the same lines; the
  subagents' faces sit centred beside the portrait in at most two rows (past
  eight, seven and a *+N*); and when the state and the permission mode wrap
  under a long name they stand at the left, not over the figures. The
  *1 working · peak 4* line now floats under the faces on hover instead of
  holding empty room under them.
- **machines:** after the other computer's owner pressed Allow, the sidebar,
  Now and New agent kept saying "waiting for Allow" until Settings → Computers
  was opened, and the next look came a minute later. A computer that lets this
  one in — a socket opens, a request is answered — is now asked again by
  itself, one that waits for Allow is looked at again after 5 s, 10 s, 20 s…,
  and the same clears "removed" when that computer knows this one again. In
  the two-daemon smoke the laptop learned of the Allow about 3 s after it.
- **machines:** a prompt said on another computer while its sessions were
  being read could miss the one list for up to 10 s: the read from just before
  it was kept as fresh. Such a read is now answered but not kept.
- **machines:** after another computer's Caprock restarted, this one kept
  asking it for frames past its new count, got a reset on every reconnect, and
  lost the prompts said there while the link was down; it now resumes from
  where that computer stands. A computer that lets the watch in and hangs up at
  once is waited out (2 s doubling to 60 s) instead of re-dialled every 2 s.

## [0.174.0] - 2026-11-06

### Added

- **plugin:** Caprock is a Claude Code plugin. `claude plugin marketplace add
  dspv/caprock`, then `claude plugin install caprock@caprock`, adds the
  read-only `caprock mcp` server for every project. Its launcher finds
  `caprock` even when the desktop app put none on your `PATH`, and when
  Caprock is not installed it says so, with the install link, instead of a
  bare "failed". It downloads and sends nothing.
- **ui:** the file tab reads more kinds of file. Markdown and HTML get
  *Rendered* / *Source* / *Split*, Split showing the source and the page side
  by side, their scrolling kept together for Markdown; the choice is
  remembered. An HTML page is drawn in a sandboxed frame that runs no script
  and loads nothing from the network, its own stylesheets and pictures read
  from the project. CSV and TSV files show as a table, pictures (SVG too) as
  themselves, and code and config files are syntax-highlighted by a part of
  the app loaded only when such a file is opened; a file over 256 KB stays
  plain.

### Changed

- **ui:** the Agent panel's header puts the pictures at the left and the
  figures at the right. The agent's mark is a large tile (still the button
  that picks the session's face), and beside it the subagents' faces in a
  grid of four columns: the working in colour, the recently finished grey,
  a *+N* tile past eight. The small mark on the name row is gone in this
  look, so the agent is drawn once. Burn, tokens and cost stand
  right-aligned, under the pictures in a narrow panel. Hovering the grid
  shows *1 working · peak 4*, which opens the last hour's chart, and the
  three dots that switch looks. This *Matrix* look is the default and
  replaces *Crew*; a viewer who had picked the crew gets the matrix.
  *Faces as chips* and *Strip* stay.

### Fixed

- **ui:** the Agent panel (⌘I) no longer says $0.00 for a session on a
  model Caprock has no price for, such as Kimi or DeepSeek after a limit
  moved the session there. Its cost figures read — with the model named on
  hover; a session with some turns priced shows the priced sum with a +
  (*$1.84+*) and says on hover how many turns are not in it.
- **daemon:** "Return after the reset" survives a restart. A session that
  Caprock moved to another provider or sign-in at a usage limit still goes
  back once the limit resets, even when Caprock restarted in between; a
  return more than an hour overdue at the restart is dropped.

## [0.173.0] - 2026-11-06

### Added

- **sidebar:** on a large database with *Compress tool output* off, the
  sidebar's bottom block says so in one quiet line — for example *Database 2.5GB ·
  compressing frees about 1.0GB*, both figures from your own database, the
  saving an estimate from a sample of your tool calls. It shows only when the
  estimate is at least 300 MB. A click opens the switch in Settings → Storage,
  lit, and turns nothing on; × hides it for 30 days. Folded, it is a database
  icon with a dot. It goes as soon as compression is on.
- **storage:** *Compress tool output*, under Status → Storage, stores tool
  calls and their results older than a day zstd-compressed, a few hundred
  rows at a time while Caprock is idle — never at start and never while
  anything is being recorded. Prompts and replies stay as they are, so search
  is unchanged. Off until you turn it on; the panel says how much smaller
  your own database would be (an estimate from 2,000 of your tool calls), and
  once it runs, how much it is. On a copy of a 2.5 GB database it saved
  818 MiB of tool output, and the file went to 1.5 GB after the one VACUUM
  that follows, which runs only when the disk has room for it. Turned off, the
  same job restores the rows. An older Caprock refuses to open the database
  after this upgrade (with a one-line message, changing nothing). Proposed
  and measured by [@SergeAx](https://github.com/SergeAx) in #672.
- **ios:** scanning the computer's pairing code with the iPhone's own Camera
  app now opens Caprock for iPhone and pairs it, instead of opening Safari
  and asking you to scan again inside the app. Only the pairing link opens
  the app; every other `m.caprock.dev` address still opens in Safari, and
  without the app the link opens the phone's page as before. The link is
  read on the phone; nothing new is sent anywhere. Needs the next App Store
  build of the app.
- **phone:** m.caprock.dev in Safari on an iPhone shows Apple's banner,
  *Caprock · Open in the App Store*, so someone who scanned the pairing code
  with the camera learns that Caprock for iPhone exists. Only the phone's page
  carries it; other browsers, the app itself and a home-screen copy never
  show it.
- **ui:** Settings → Use on your phone offers Caprock for iPhone in a clear
  row, *iPhone? Caprock for iPhone adds notifications, voice and photos.*
  **Get it on the App Store** shows a QR the iPhone's camera opens the App
  Store with; before, a small grey link opened the listing on the computer,
  where it installs nothing on the phone.

### Changed

- **cockpit:** the Context meter says what a compaction is doing. While one
  runs — started from Caprock, typed in the terminal or Claude Code's own —
  stripes move over the bar and the line reads *Compacting · 0:16 · usually
  ~1 min*, the time since it began and this machine's median (no "usually"
  until five compactions were timed; Claude Code reports no progress, so
  there is no percent). The moment it ends the meter shows the size it
  left, *2% full · was 332k*, the old fill shrinking away once. The empty
  track is tinted where the bar turns amber (60%) and red (85%), and the
  quarter marks read the same over the fill and the track.
- **ui:** Settings on a computer is large and easy to read, the way the phone's
  is: section titles 19px, every option's name 15.5px with its explanation
  under it, every on/off a switch, fields and buttons at least 34–36px tall,
  and a step up for all the small print in every section. Nothing moved and no
  setting changed; the phone layout is as it was.
- **ui:** the Agent panel's subagents take far less room. By default the
  subagent chips under the figures are now the subagents' faces — in colour
  and pulsing while one works, grey once it finished — with *1 working · peak
  4* beside them, which opens the last hour's chart under the row; there is
  no framed block. A *Strip* look draws one line instead: the working faces
  big, the finished small and grey, and the hour as a small sparkline that
  shows the peak on hover and opens the full chart on a click. The *Crew*
  look stays, with less padding and a shorter chart. The *Chart of faces* and
  *Numbers* looks are gone; a viewer who had picked one gets the new default.
  With no subagents in the session, nothing is drawn.

### Fixed

- **ios:** dictation in the iPhone app waits up to two seconds for the final
  words after you stop it, instead of dropping the recogniser at once (the
  speech plugin 8.4.6, on Capacitor 8.6.0).
- **cockpit:** the Context meter drops to the size a compaction left as soon as `/compact` finishes, instead of showing the size before it until the model answers again.
- **ui:** attaching on a phone offers two clear choices. The Attach button
  (the phone's New chat and Save, a chat, and a session's chat on the Full
  dashboard) opens a menu with **Photos**, the photo library or the camera,
  and **Files**, which opens the Files browser straight away; before, one
  picker left both to iOS's own sheet. With a mouse it opens the file dialog
  as before. A HEIC photo is now always sent as JPEG, so one picked from
  Files is no longer refused. The iOS app names why it opens the photo
  library, from its next App Store build.

## [0.172.0] - 2026-11-06

### Added

- **ui:** Settings → *Use on your phone* has one line under **Connect a
  phone**, *iPhone: get Caprock on the App Store*, linking to Caprock for
  iPhone, now on the App Store; it opens in the default browser and sends
  nothing. *How it works* names the app as a way to keep Caprock on an
  iPhone, and the iOS README, `docs/app.md` and `.ai/` no longer call the
  app ready for review.
- **telegram:** a Morning summary — one Telegram message each morning from
  your bot: how many of the new mail conversations Caprock Mail's sorting
  marked important, with the sender and subject of the newest five; the
  sessions that finished overnight per project, with those that stopped at a
  usage limit or exited with an error; and the sessions and tasks waiting
  for you. Buttons open mail, Home and History on your phone when it can
  reach this computer. Off until turned on in Settings → Telegram, at 08:00
  unless you pick another time; a computer asleep then sends it on waking,
  until noon, and never twice in a day. Settings says what it sends, and
  *Send a test summary now* shows it at once. Free (ADR-092).
- **chats:** on a phone, New chat asks who works — Claude on your
  subscription, another Claude sign-in, DeepSeek or Kimi on your key (only
  while it is set), Codex — and where: a chat of its own, a recent folder or
  any other folder under home. The chat then works in that folder, opens as
  a chat and is listed in Chats, with a line saying what it sees and that
  only its model's provider gets what it reads. On a desktop New chat still
  starts at once, and *In a folder…* opens the same steps. Folders can be
  labelled Work or Personal from the Where step; the tags show on the Chats
  list, which filters by them (ADR-091).

### Changed

- **ui:** the app's sidebar is calmer and says what is open and in which
  phase. New agent sits in its own band at the top, with Chat, Project and a
  ⋯ menu (New shell, Search, History, Share your week) in one row under it;
  the keys are the ones they always had. A new **Open** section lists exactly
  your open tabs in tab order, each with its project, its ⌘ key and a coloured
  phase: working, needs you, idle, done or failed. Projects are folded to one
  line with a short summary ("1 needs you", "2 running", "3 idle") and unfold
  to their sessions as before. Recently closed folds to one line. The Today
  card became one thin line above Dashboard — spend, running, what waits and
  the fuller plan window — with a × to hide it; Settings or the ⋯ menu brings
  it back. The Projects | Tabs switch left the heading, since Open lists the
  tabs; Settings → Appearance keeps the choice of what sits under Open.

## [0.171.0] - 2026-11-03

### Added

- **agents:** when a Claude Code session Caprock started hits its plan's usage
  limit, it can be continued elsewhere: on DeepSeek or Kimi as the same
  conversation, on another Claude Code sign-in as the same conversation (its
  transcript copied there, never moved), or on Codex with a summary of the
  work. `POST /v1/sessions/{id}/continue-on`; sessions carry `limit_hit`
  with the reset time; Settings can move a session automatically and bring
  it back after the reset (ADR-090).
- **terminal:** at the limit, one quiet line under the session's terminal
  says which window and when it reopens ("5-hour limit · back at 18:40"),
  with a small chip for each place it can go on — another Claude sign-in,
  DeepSeek or Kimi when their keys are set, Codex — and Wait. A click moves
  it; the tab follows the new session, and a note says where it went, with
  Undo.
- **settings:** *When a limit is reached*: Ask me, Continue automatically on
  an ordered list of targets, or Wait for the reset, and Back on Claude after
  the reset.
- **subscriptions:** Claude Code on Kimi, on your own Kimi platform key, kept
  in the keychain like the DeepSeek key, with Moonshot's published settings
  for Claude Code; its key field sits under DeepSeek's.

### Changed

- **plan:** Claude's plans carry Anthropic's new names: Max 5× is now **Max**
  ($100) and Max 20× is now **Ultra** ($200), as renamed at the end of
  October 2026 (claude.com/pricing, read 2026-11-03). The plan picker offers
  Pro, Max and Ultra, and a plan Caprock's picker stored under an old name
  reads back under the new one, so the header chip that said *Max 20× ·
  $200.00/mo* now says *Ultra · $200.00/mo*. A plan name you typed yourself
  is left as you wrote it. A verified Ultra account has no five-hour limit,
  so the Plan limits card shows its week alone, and a five-hour reading left
  from before the move is no longer shown as a stale window forever.

### Fixed

- **session:** a session on a model with no published price (Claude Code on
  Kimi, `kimi-k3`) no longer reads "Cost $0.00". The Cost tile, the session
  header and the Now card show "—" and "price unknown", or the priced sum
  with "+ N unpriced turns" when only some turns could be priced, and the
  cumulative cost panel counts priced turns only. The session API carries
  `stats.unpriced_turns`.

## [0.170.1] - 2026-11-02

### Fixed

- **app:** the macOS `.dmg` opens on its branded window again (in fact for the
  first time from a release): the background picture, the app and the
  Applications folder side by side, the 660×400 window. Tauri's bundler lays
  that window out with a Finder script it skips on CI, so every `.dmg`
  release.yml built since 0.97.0 opened as a plain white folder. The image is
  now made with dmgbuild, which writes the window's settings directly, and the
  release and CI checks fail without them.

## [0.170.0] - 2026-11-02

### Changed

- **ui:** the all-time strip on Now is a row of tiles like Cost's Totals — a
  label over each figure, one even row — instead of a running line that
  wrapped *sessions a day* onto a second line; on a phone the Quick chat and
  New session buttons go under it.
- **ui:** the Agent panel's empty subagent frame says *no subagents · 1h* on
  one line instead of wrapping *no subagents in the last hour*.
- **app:** the macOS installer window is graphite with Caprock's characters
  round the arrow — *Your agents are waiting*, *Drag Caprock onto
  Applications* — instead of the plain paper ground.

## [0.169.0] - 2026-10-31

### Added

- **ui:** At a glance has the share button the other figure panels have:
  picture without the Charts/Numbers switch or fold toggles, and Copy as
  text with the Numbers view's tables. So do All time on Home, Last 30 days
  and Compactions on Cost, Hermes Agent on Cost, Compactions on Week, and
  Lifetime, Daily cost, Top projects (names hidden by default) and Model
  mix on Lifetime.

### Changed

- **ui:** the Agent panel's session chip says *uptime 8d* instead of
  *started 8d ago*, so it stays on the model and context line; the start
  time is in its tooltip.
- **ui:** the subagent frame in the Agent panel is drawn with the Caprock
  characters instead of a thin step line. By default the last hour is a
  chart of faces: twelve five-minute columns, each a stack of faces as tall
  as the most subagents at once, with the peak and the time it was reached
  (*peak 5 at 09:42*); past six at once one face stands for several. Two
  more looks sit behind three small dots in the frame's corner: *Crew*, one
  face per working subagent with the finished faded, and *Numbers*, the
  crowd large with *N working now*. The faces follow the one picked for
  Claude in Settings, and the choice of look is remembered.
- **app:** the "Caprock vX is available" card on Now updates in place in the
  desktop app — **Update to vX — Restart**, a progress bar while it
  downloads, then the restart — the same one click as the status strip,
  instead of a Download link to the release page. A browser and installs
  that cannot update themselves still get the command or the release page.

### Fixed

- **ui:** a share button can no longer leave the sheet stuck on "Drawing…"
  with every button off. A press on a card whose figures are still being
  counted waits at most six seconds, saying *Counting this month…*, then
  sends the card as shown (its corner still names the reading); the picture
  embeds only the fonts the page already loaded, from the browser's cache,
  instead of fetching eight font files from a daemon busy counting the
  month; and drawing has a 30-second limit, after which the buttons come
  back with *Could not draw the card — try again.* Panel pictures get the
  same limit.

## [0.168.0] - 2026-10-31

### Added

- **compact:** every compaction is now a stat: what it cost and what it has
  saved since, both estimated from the pricing table and marked ≈. The Agent
  panel's Context shows the latest one on one line (*32h ago · 442k → 19k ·
  cost ≈ $0.09*) with a small curve of the saving since and *saved ≈* at its
  end; the ⓘ beside *~15% stays* says what /compact does and how each figure
  is estimated. Cost and Week gain a Compactions panel: the count, cost,
  saved and net for the period. Every compaction already recorded is filled
  in once on the first start, its summary's length read back from the
  transcript. New `GET /v1/stats/compactions`; `GET
  /v1/sessions/{id}/compaction` gains `estimate` (migration 0077).

### Fixed

- **pricing:** Claude Sonnet 5.5 cache reads are priced at $0.10 per million
  tokens from 7 October 2026, as Anthropic charges (0.05x the input price);
  the table had kept $0.20. Turns from that day are repriced once, openly,
  and the session and daily totals move by the difference. GPT-6.1 Terra
  gets its own row, so its Codex turns are priced instead of counted as
  unpriced. Table version 2026-10-31.1.

## [0.167.0] - 2026-10-30

### Added

- **ui:** the Agent panel header shows the session's reasoning effort beside
  its model, *Opus 5.5 · high*, as Claude Code's own hooks report it. The
  daemon now keeps the newest known level per session (low, medium, high,
  xhigh, max; migration 0076) and returns it as `effort`; a session whose
  hooks never named one shows the model alone.

### Fixed

- **ui:** a shared panel's picture is the title and the content alone: fold
  chevrons, More/Less and Hide toggles, Settings links, a row's ways in,
  tooltips and hover-only buttons are left out. With Hide project names on,
  names no longer slip through in part: a folder's last segment, a GitHub
  slug's owner and repository and a name in another letter case are hidden
  too, and an activity line such as "editing caprock/internal/api/x.go"
  reads "editing path 1", its file names and branches replaced.

## [0.166.0] - 2026-10-29

### Added

- **ui:** Files: → expands a folder in place, its contents right below it
  one level in, as Finder's list view does; → again steps onto its first
  file, ← folds it or steps back to the folder holding the row. A triangle
  on each folder row does the same with the mouse; Enter still goes into
  the folder. Nested rows show git marks, size and date, are tinted in
  compare mode, stay under *What the agent changed*, and can be marked,
  viewed, edited, copied, moved and sent to the Trash.

### Changed

- **ui:** the top of the Agent panel (⌘I) takes about half the height it
  did and cuts nothing. One row carries the agent's own mark (a click on it
  still picks the session's face), the session's name once, the project only
  when it differs, the branch, the state and the permission mode. Burn rate
  stays big with tokens and spend on one line under it, beside a new chart of
  how many subagents worked each minute of the last hour, with how many work
  now, their types and the hour's peak; with none, the chart says so. The
  model, the context fill and the start are small chips under them.
- **api:** `GET /v1/sessions/{id}/subagents?hour=1` adds the last hour's
  subagent count a minute (`hour: {start, step_ms, counts, peak}`).
- **ui:** a folded **Plan limits** panel is no longer an empty row. Its header
  keeps one thin bar per window the panel shows — Claude's 5 hours and week,
  and Codex's when it reports them — each with its short name, the percentage
  and the reset time, coloured as the gauges are (amber from 60%, red above
  85%, grey when the reading is stale). As the row narrows the reset times go
  first, then the names; the bars and percentages stay, on one line.

## [0.165.1] - 2026-10-29

### Fixed

- **app:** the window no longer flips to "the daemon stopped" and back to the
  dashboard on a brief hiccup. A running daemon is kept through 5 s of failed
  checks (20 s when it is only slow), and a slow `/v1/status` no longer counts
  at all; a real stop (its `runtime.json` gone, or its process exited) is
  still seen at once. When the app does count the daemon as gone, `app.log`
  says why.

## [0.165.0] - 2026-10-28

### Added

- **ui:** Files, a two-panel file manager in the spirit of Norton Commander
  that knows about your agents (⇧⌘X, Ctrl+Shift+X on Windows and Linux; ⌘K
  → Open Files; Files in a project's menu). Your checkout on the left, an
  agent's worktree on the right: Compare tints what differs and what is on
  one side only, What <agent> changed filters to that worktree's changes,
  View shows the file or its diff with + and − counts. Copy, move or rename,
  new folder and delete (F5–F8, or ⌥5–⌥8 on a Mac), each confirmed by name;
  delete only ever moves to the Trash. Reaches only the project's folder and
  its worktrees, and is read-only from a phone or another computer. A
  Norton look paints it blue with cyan frames and the F-key bar.
- **ui:** every figures panel can be shared — Live pulse, Repos, CI/CD, Plan
  limits, Most expensive, Releases, Plan value and the Cost panels get a share
  icon in their header: Copy image, Save PNG, Copy as text (Markdown) and Post
  to X, Threads or LinkedIn through the share card's own sheet. *Hide project
  names*, on by default and remembered, turns projects, sessions, branches,
  folders, pull request titles and logins into "project 1", "session 1"… in
  the picture and the text alike. Drawn on your machine; only the X, Threads
  and LinkedIn buttons upload the picture, to caprock.dev, as for the share
  card.

### Changed

- **ci:** the Windows Go leg, the slowest job in a CI run, is split into
  three jobs that run side by side (lint and smoke, the slowest package's
  tests, the rest of the tests), and a pull request that touches only the
  changelog, its fragments or `.ai/` docs — a release pull request — skips the
  build and test jobs while the docs checks still run.
- **ui:** the agent cockpit's header names the agent in a small muted label
  and puts the session's configuration where the big name was: the model
  and how full its context is (*Opus 5.5 · 62% ctx*). Under it, the
  subagents working now are counted by type (*3 subagents · 2 Explore,
  1 general-purpose*), and a type opens the first of its kind in the
  Subagents section. A figure the daemon does not report is left out.
- **ui:** the tab in front is framed in the accent on every side, the
  Dashboard tab in front a step heavier, and behind it keeps an accent
  outline, so it is the one tab the eye finds. The Pipeline and Mail tabs are
  quiet beside it now, drawn like a session tab until brought forward. The
  Pipeline tab closes from behind too (its × on hover), and with ⌘W
  (Ctrl+Shift+W) while it is in front; it stays closed until ⌘P opens it
  again.

### Fixed

- **ios:** the iPhone app's upload to App Store Connect is no longer refused
  over export compliance. The build no longer claims an approved compliance
  code it does not have; App Store Connect asks the encryption questions on
  the build instead.
- **ui:** the Repos panel's last column (Release) no longer runs past the
  panel's right edge in a mid-width window: a letter-spaced heading wider than
  its column no longer widens the column, and the table drops to its narrower
  layout a little earlier.

## [0.164.1] - 2026-10-28

### Changed

- **ui:** the app window uses less memory with terminal tabs left in the
  background. A tab out of sight for five minutes now gives its terminal's
  GPU context back, and every closed or replaced terminal gives its context
  back at once instead of when the page next cleans up. Measured in the app
  with eight terminal tabs, a long chat and the Dashboard open, after 25
  minutes: the window's graphics memory went from 125 to 80 MB and the whole
  app from 478 to 432 MB. Coming back to a tab looks as it did: the terminal
  is drawn in the frame it appears in.

## [0.164.0] - 2026-10-28

### Added

- **ios:** Caprock for iPhone, version 1.0, ready for the App Store, in
  `ios-app/`: the phone remote in a Capacitor shell, bundled rather than
  loaded from `m.caprock.dev`. Pair by scanning the computer's code with the
  app's own camera, or paste the link; dictate in any language the iPhone
  recognises on its own, with nothing sent anywhere and a line when a language
  is not on the device; lock the app behind Face ID; the pairing kept in the
  Keychain; **Try it without a Mac** on bundled sample data that connects to
  nothing; the app's own Settings (paired computer, voice language, Face ID,
  unpair). Nothing in the app is for sale. A manual workflow
  (`ios-release.yml`) archives, signs and uploads a build to App Store
  Connect; the listing texts are in `ios-app/store/`. No push notifications
  in 1.0; they follow in 1.1 (ADR-083).
- **machines:** start an agent on another computer from this one. New agent
  gains a Machine field when you have linked a computer: pick it, and the
  folders, agents and models are read from that computer, the agent runs
  there, and its tab opens here. A computer that cannot take a start is
  listed with why (offline, waiting for Allow, removed there), and a refusal
  is said in words, a folder missing there included.
- **machines:** one list across your computers. Sessions on the other
  computers that need you sort first in the sidebar, Now shows them under
  *On other computers*, and the app tells you when one needs you, naming the
  computer. A computer that goes away is shown as offline with when it last
  answered, not with the sessions it had. The daemon reads each computer once
  for every window (`GET /v1/machines/sessions`) and listens to it for
  prompts only while a window is open.
- **machines:** a guide for trying it on two computers,
  `docs/machines.md`, and an end-to-end test with two real
  daemons and a local relay in the smoke suite.

## [0.163.1] - 2026-10-28

### Fixed

- **app:** a daemon that answers slowly on a loaded computer no longer flips
  the window to "The Caprock daemon stopped". A daemon that takes the connection
  and answers late is kept for 20 seconds; no connection at all, or silence
  past that, shows it as stopped.

## [0.163.0] - 2026-10-27

### Added

- **browser:** *Open on my phone* in phone mode. A local dev server's page
  (Vite, Next, webpack on localhost) opens on a real phone on the same Wi-Fi:
  a QR code, scanned with the phone's camera. Caprock shares that one server
  through a proxy on this computer's Wi-Fi address and a random port, behind a
  link only the QR carries; live reload works. Sharing stops on *Stop
  sharing*, after 30 minutes unused, after 8 hours, or when Caprock quits
  (ADR-087).

### Changed

- **ui:** folded, the CI section says "#220 merged" (or "closed") for a pull
  request that is done, instead of a tally of its old checks.

### Fixed

- **queue:** a message waiting in a session's queue is no longer lost when
  the session ends. When the process ends, the waiting messages are kept for
  7 days, shown under the conversation as *Not sent: the session ended*,
  each with **Send to a new session** (the same agent in the same folder,
  continuing the conversation when it can; the message then goes in through
  that session's queue), **Copy** and **Delete**, and **Send all** for
  several, in order, one per turn. A `/clear` no longer empties the queue:
  it moves to the new session and carries on delivering there. Migration
  0075 (ADR-053, amendment of 2026-10-27).
- **ui:** a pull request with failed checks no longer says "ready to merge".
  GitHub calls it clean when no check is required, and Caprock repeated that
  beside the red checks; it now says "mergeable, checks failed", or "checks
  running" while they run.
- **ui:** the window holds much less memory over a long day. The Live pulse
  kept every tool's whole answer (command output, files read in full, an
  edit's original file) for up to 4,000 events a track; it now keeps what the
  bars read. An open chat following a busy agent no longer grows for as long
  as it stays open: past 240 messages it keeps the newest 120 and pages the
  rest back in when scrolled to. A session's timeline left open keeps 1,000
  live events instead of 5,000. The agent cockpit keeps a result's outcome,
  not its output, and clipped text no longer keeps the full original alive.

## [0.162.0] - 2026-10-27

### Added

- **share:** X, Threads and LinkedIn now put the card you chose in the post
  itself. Pressing one uploads that exact picture — the picture alone — to
  caprock.dev and opens the post with its link, whose preview is the card, so
  there is nothing to paste. The buttons' tooltips and the box after posting
  say so, and the box can take the picture down again (Remove the shared
  picture); Settings → Privacy lists every shared picture with Remove. The
  social site may keep the preview it already fetched. Share…, Copy image,
  Save image and My Telegram never upload. If the upload fails, the sheet
  falls back to the clipboard and the ⌘V steps, and says why in one line
  (ADR-086).
- **phone:** Share your week on the phone home draws the Week card and opens
  the phone's own share menu with the picture attached — on an iPhone, pick
  Threads or X. Nothing is uploaded on the phone.

### Fixed

- **store:** an upgrade that found no disk for the safety copy of the
  database used to say so only in the log. It is now recorded, and
  `/v1/status` (`upgrade_copy_skipped`), `caprock status`, Now and Status say
  that no copy was made, how much disk was free and needed, and that older
  Caprock versions cannot open the upgraded database.
- **ui:** while older history moves in after the 0073 upgrade, History,
  Memory's search and session pages say so in one quiet line, "Older history
  is still loading — N% moved", gone once the move ends.

## [0.161.0] - 2026-10-27

### Added

- **cockpit:** **Compact context**, free. In the Context section, one click
  types Claude Code's own `/compact` into a session Caprock started — at once
  at its prompt, otherwise when its turn ends — and the session carries on
  in place with a summary; `/clear` is never typed. The collapsed Context
  line shows a small icon from 60% full; both are hidden under 100k tokens.
  Before the press it says what usually stays and where that comes from:
  your own compactions once five are measured, until then one machine's
  measurement (70 automatic compactions, 2026-09-29 to 2026-10-25, a median
  15% kept). After it, the measured before and after, *Compacted: 41.4k →
  10.1k tokens* — at once where Claude Code writes the size after on its
  compaction boundary, else with the next reply. A session another terminal holds is never typed into: it
  shows the command to type there and Continue here. Compaction boundaries
  are now read from transcripts, including the ones already on disk, once,
  in the background (`GET /v1/sessions/{id}/compaction`,
  `POST /v1/agents/{id}/compact`).

### Changed

- **store:** an event names its session by an integer key instead of
  repeating the session's 36-character id in its row and in most indexes. A
  1 GB database came out 128 MiB smaller after a VACUUM (measured
  2026-10-19). The upgrade no longer rewrites the events table before the
  dashboard answers: the first start takes seconds, and the older events
  move into the new table in the background, newest first, 1 min 52 s for
  603,141 of them on a 1.2 GB database (measured 2026-10-23). Until they
  are in, the Now screen and `caprock status` say so, older history is
  incomplete, the other agents' importers wait, and removing a session asks
  to try again later. A query on `caprock.db` joins `sessions` for a
  session's id (`docs/schema.md`). No earlier release opens the upgraded
  database, so the upgrade first keeps a copy of it as `caprock.pre-0073.db`
  in the data directory for 30 days: to go back, stop Caprock, put the copy
  in place of `caprock.db`, remove `caprock.db-wal` and `caprock.db-shm`,
  and install the older release. `caprock up` and the desktop app wait for
  the copy and say the database is upgrading.

## [0.160.0] - 2026-10-26

### Changed

- **ui:** the share sheet writes the post from your figures — "My agents
  shipped 48 PRs this week.", the other counts and which agents did the work —
  in place of one line with no number; the dollars stay on the card. After X,
  Threads or LinkedIn opens, a box lists the steps: the card is on your
  clipboard, the post is open, and pressing ⌘V in the post adds the card.

## [0.159.1] - 2026-10-25

### Fixed

- **share:** X, Threads and LinkedIn get the card you chose, dark or paper: the
  post no longer carries a caprock.dev link, which made them show the site's
  dark preview instead, and a large line says to press ⌘V (Ctrl+V) in the post
  to add the card from the clipboard.

## [0.159.0] - 2026-10-25

### Added

- **cost:** every cost at API list price now also says what the work was of
  your subscription, on a muted line under it: plan dollars and the share of
  the weekly limit (*$50 at API · ≈$1.65 of plan · ≈2.3% of a week*). On the
  Cost screen, the session card, a session's page, the Pipeline's rows, its
  Releases and both Most expensive lists. Each sign-in is priced by its own
  plan over the last 30 days and calibrated on its own last full week; hover
  for how, and why use outside Caprock makes the figures run a little high.
  Nothing is shown on a metered plan, with no plan stated, or before a
  weekly window has been seen.
- **share:** share from wherever you work: a small share icon on the
  sidebar's Today card, File → Share Your Figures… in the macOS app, and the
  share toast now shows over session tabs too.
- **share:** your week, every week: when a week closes (Sunday 18:00, or the
  first time you open Caprock in the two days after) and it merged at least
  one PR, one quiet toast offers the card in its own figures ("Your week is
  done. 33× your plan this week · 48 PRs merged") and opens the sheet on this
  week. Once per week, whichever way you answer.
- **share:** Threads joins X and LinkedIn as a place to post the card.

### Changed

- **resources:** one **Free up memory** button, in Caprock resources and in
  the memory popover alike, replaces *Clean up* and *End N idle agents*. It
  opens a list in two groups — leftovers and idle agents — each line with
  its own checkbox and size, the total following the ticks, and says first
  what happens: conversations are kept, and anything an idle agent started
  in the background stops with it.
- **resources:** it is stricter about what is safe. A test copy of Caprock
  is offered only once the agent that started it is gone; one whose agent
  still runs is kept, with the reason on its row. An idle agent is offered
  only after 15 minutes idle, with nothing but its own helpers running under
  it, and never the tab in front; the rest it leaves running are listed with
  why, and the daemon checks each again at the click.
- **share:** the share card tells the truth. Pull requests come from GitHub's
  record where Caprock holds one (the lists the Pipeline reads), not only from
  the `gh pr merge` commands agents ran — a batch or script merge counts now.
  Sessions started at `/` or in your home folder (scheduled scripts) are left
  out of every figure, and the card says "hand-run sessions". The cost per
  merged PR is the Pipeline's own per-PR figure, averaged, so the two never
  disagree.
- **share:** the card's pull request count is GitHub's whole period. When the
  lists Caprock kept do not reach back to the period's start, the missing
  older pull requests are read from GitHub once, in the background, and kept;
  the next card counts them (it read 48 merged where GitHub said 59 before).
- **share:** one card, two formats. Landscape and portrait lead with the same
  two big figures — your plan's multiple (or the dollars) and merged PRs —
  instead of a Figures card and a Story card that said different things.
- **share:** a calmer sheet: Share…, Copy and Save in one row; My Telegram, X,
  Threads and LinkedIn in another; the post text behind *Edit post text*; one line on
  what leaves the machine. *Send to someone in Telegram* is gone — Copy image
  does that.

### Fixed

- **ui:** a row's ⋯ menu on Chats, Now and the home is no longer cut off by
  the list's rounded box on a wide window: it is drawn above everything, under
  the ⋯, and opens upwards when the window has no room below (#816).
- **terminal:** a tab whose agent **Free up memory** ended shows its
  conversation with Continue here at once, instead of *Can't connect · next
  try in 10 s* over a process Caprock itself ended.
- **resources:** Caprock resources no longer offers to stop Caprock Mail. The
  separate Mail app was taken for a Caprock command left behind because its
  process name starts with `caprock`; an app in its own bundle is never listed
  now, only the `caprock` binary itself.
- **store:** a pull request a script opened or merged now gets the agent cost
  of the session that ran the script. Before, only a `gh pr` command the
  session typed itself counted, so on the PRs & CI board three releases made
  by a release script showed "–". Now GitHub's own opening and merge times are
  matched to the one session in the repository that had a Bash call running at
  that moment. With no such session, or more than one, the pull request stays
  unattributed. Nothing is stored, and every session is still charged once.
- **share:** the week card's footer keeps *caprock.dev · What's yours?* on one
  line in the 1200 × 630 picture; its note reads *PRs: GitHub + agents*.
- **share:** a pull request merged after `cd ~/dev/<repo>` from another
  repository's session is no longer counted twice on the share card.

## [0.158.0] - 2026-10-24

### Added

- **brain:** Second Brain no longer reads every session. A session a
  scheduled job starts can say so (`POST /v1/agents {"automation": true}`)
  and is never read or handed memories; Settings → Second Brain → *Never
  read these folders* skips every session in a folder (recorded as skipped,
  with the folder) and keeps those projects out of the graph, search and
  what a new session is handed unless you open that project. Nothing
  already kept is deleted. The instructions also tell the model to skip
  what is true only of one run (what the agent did or saved this time, a
  dropped connection) and keep what still holds for the product or the
  codebase.
- **ui:** the Lifetime screen says, under its daily chart, that Claude Code
  deletes conversations older than its `cleanupPeriodDays` (30 days unless
  set), so the history before Caprock's first day was gone before Caprock saw
  it, and offers **Keep them from now on**: it writes `cleanupPeriodDays:
  36500` into `~/.claude/settings.json`, that key only and every other byte of
  the file kept, backed up first, and refuses a file that is not valid JSON.
  Shown only while the period is unset or 90 days or fewer; nothing leaves
  the machine (`GET`/`POST /v1/claude/retention`).

### Changed

- **docs:** the README opens the way caprock.dev now does: every coding agent
  you run, wherever it runs, who is waiting on you, who is stuck and how close
  the limit is, then each pull request to release with what it cost. Its first
  sections follow the site's order: pull requests, sessions waiting on you,
  terminals, cost and limits.

### Fixed

- **brain:** the sidebar card's line at the daily limit reads *Limit reached ·
  1546* instead of being cut mid-word on a 14-inch screen.
- **brain:** Second Brain no longer reads sessions started at the disk root or
  in the home folder itself, where launchd and cron run scheduled `claude -p`
  jobs. They are recorded as skipped with the reason, drop out of the
  sessions waiting at once and stop using the daily token limit; folders
  under the home are read as before, and nothing already kept is deleted.
  Settings → Second Brain says so under *Never read these folders*.
- **agents:** a session whose program exits a moment after it starts now
  says why. Its tab shows *Claude Code exited at once (code 1)* with the last
  lines it printed, the program that ran, and **Try again** and **Close**,
  instead of *Connecting to the session… Can't connect · next try in 5 s*
  over a process that was already gone. The same lines, the command and the
  binary's version go to service.log at WARN, and `GET /v1/agents/{id}/exit`
  serves them (kept in the new `session_exits` table).
- **agents:** *Continue here* on a Claude Code session that moved to another
  folder with `cd` starts in the folder its conversation began in. Started in
  the moved-to folder, `claude --resume` printed "No conversation found" and
  exited at once.
- **pipeline:** a pull request closed without a merge is no longer drawn in
  flight as *PR open*: a session's record of it made the row even though
  GitHub listed it closed. A row whose only title is its number now reads
  *#796*, not *#796 #796*.
- **pipeline:** one cost per pull request. The in-flight row, the list's
  *Agent cost* and the *Agents · 14 days* figure now read the same recorded
  spend (the in-flight row used to add up the whole sessions on it), and a
  pull request closed without a merge in the window counts toward the 14
  days: what agents spent on it was spent.
- **pipeline:** with no pull request merged in 14 days, *Speed* says *–*
  and why instead of *0.0/day*; with no agent cost recorded on any pull
  request, *Agents* says *–* and why instead of $0.00.

## [0.157.0] - 2026-10-24

### Added

- **brain:** Second Brain no longer reads every session. A session a
  scheduled job starts can say so (`POST /v1/agents {"automation": true}`)
  and is never read or handed memories; Settings → Second Brain → *Never
  read these folders* skips every session in a folder (recorded as skipped,
  with the folder) and keeps those projects out of the graph, search and
  what a new session is handed unless you open that project. Nothing
  already kept is deleted. The instructions also tell the model to skip
  what is true only of one run (what the agent did or saved this time, a
  dropped connection) and keep what still holds for the product or the
  codebase.
- **ui:** the Lifetime screen says, under its daily chart, that Claude Code
  deletes conversations older than its `cleanupPeriodDays` (30 days unless
  set), so the history before Caprock's first day was gone before Caprock saw
  it, and offers **Keep them from now on**: it writes `cleanupPeriodDays:
  36500` into `~/.claude/settings.json`, that key only and every other byte of
  the file kept, backed up first, and refuses a file that is not valid JSON.
  Shown only while the period is unset or 90 days or fewer; nothing leaves
  the machine (`GET`/`POST /v1/claude/retention`).

### Fixed

- **agents:** a session whose program exits a moment after it starts now
  says why. Its tab shows *Claude Code exited at once (code 1)* with the last
  lines it printed, the program that ran, and **Try again** and **Close**,
  instead of *Connecting to the session… Can't connect · next try in 5 s*
  over a process that was already gone. The same lines, the command and the
  binary's version go to service.log at WARN, and `GET /v1/agents/{id}/exit`
  serves them (kept in the new `session_exits` table).
- **agents:** *Continue here* on a Claude Code session that moved to another
  folder with `cd` starts in the folder its conversation began in. Started in
  the moved-to folder, `claude --resume` printed "No conversation found" and
  exited at once.

## [0.156.0] - 2026-10-24

### Changed

- **app:** the status strip holds service things only: the session in
  front's model, context, next-call price and cost, and today's spend, left
  it — the session's cockpit and the sidebar's Today strip carry them. What
  the session's processes use (CPU and memory) stays.

### Fixed

- **app:** on a narrower screen the status strip's *Update to vX — Restart*
  button and *Downloading vX* wrapped onto two lines; they stay on one, and
  a paid plan reads *Premium* there, with the plan and its end date in its
  tooltip.

## [0.155.0] - 2026-10-23

### Added

- **ui:** the phone attaches any file Caprock keeps, not only photos: a
  Markdown note, a PDF, a spreadsheet or a source file, from Choose File on
  an iPhone, in a session's chat, the Home field and the Save sheet. A
  document shows as a chip with its name and goes into the session by its
  path, as a file dropped on the desktop does; one Caprock does not keep, or
  one over 10 MB, is refused with the reason in a line under the field.
- **ui:** the phone Home's *Full dashboard* is a row like the others, with
  what is there under it (*New session, all projects and sessions,
  settings*), instead of a faint line.

## [0.154.2] - 2026-10-23

### Fixed

- **app:** a Page tab opened on an address nobody answers no longer flashes
  a white rectangle before *Nothing answers at …*: a new page stays hidden
  until it has something to show.
- **app:** shrinking the window with a phone preview open no longer draws
  the page past the window's bottom edge while the tab catches up.
- **app:** a phone page drawn smaller than its true size reads the device's
  size exactly: an iPhone 16 reads 393×681, where it had read 392 wide side
  by side and up to three pixels short in height when scaled.

## [0.154.1] - 2026-10-23

### Fixed

- **release:** a stray `ui/node_modules` link committed in 0.154.0 stopped
  that release from building; it is removed, and `.gitignore` now ignores
  `node_modules` whether it is a folder or a link. 0.154.0 was tagged but
  never published, so this release carries everything listed for it.

## [0.154.0] - 2026-10-23

### Changed

- **ui/brain:** Second Brain's *Last 14 days* now looks like the Dashboard:
  a row of big figures (tokens over the 14 days, the API-price cost, today
  against the daily limit, reads), the tokens per day in the Dashboard's
  chart style with its ruler, still stacked by project with the limit line
  and the over-limit mark, and a clear top five projects with each one's
  share and a bar in its chart colour. The rest fold into one *and N more*
  line that opens the full table of every project.

### Fixed

- **pipeline:** with no predicted version, the release plan said *Next release
  Next release · 1 merged*; the line under the heading no longer repeats it.
- **brain:** a long memory title in the graph panel's *Newest* list is cut
  with an ellipsis instead of running past the panel's edge.
- **ui:** the cockpit's CI block, folded, no longer shows an old copy of a
  pull request's checks as running. Its one line was drawn from what was
  kept when the block was last unfolded and never read again, so it could
  say "#801 · 4 running · 11h" of a pull request merged hours before, next
  to the time of a different answer. The session's pull requests are now
  read folded too, the line waits for that read and the time beside it is
  that read's; a kept copy not read again yet no longer has a growing
  elapsed time.
- **telegram:** a module that answers a button press at once keeps its edit.
  The press is written to the module's store before its `✓ <label>` mark is
  put under the message, so a module quick enough to replace the text and
  buttons in that moment could see the late mark put an old button back over
  its new message. The mark now goes only under the buttons that were
  pressed, and a module's edit and a press's mark no longer interleave.
- **app:** a Page tab in Phone mode never draws past the tab any more. A
  device whose page area did not fit kept its true size, and the page's
  window drew over the status bar, past the app's window and over the Dock;
  it is now drawn smaller to fit (*drawn at 74%*) and the page zoomed out to
  match, so it still lays out at the device's width. The bar's DPR reads
  *2*, not *2.200000047683716*.
- **app:** a page where nothing answers says so instead of a blank white
  page: *Nothing answers at 127.0.0.1:22776* (or *No address found for* a
  host) with Retry, in a normal tab and inside the phone alike.

## [0.153.0] - 2026-10-23

### Added

- **pipeline:** Most expensive now has a Month · All time switch, the month by
  default and remembered on this device, and reaches past the newest 50 pull
  requests GitHub lists: every pull request Caprock knows of in the repository
  (the ones agents opened or merged, and every one GitHub ever listed to this
  machine, now kept locally) and every release the checkout's version tags
  mark, each release costing what the pull requests it shipped cost. All from
  this machine; nothing more is asked of GitHub.

### Changed

- **brain:** Second Brain's *Last 14 days* shows where the tokens went. Each
  day's bar is stacked by project: the three that spent the most each get a
  colour, everything else is one grey *Other*, and hovering a segment names
  the project, the day and its tokens. A day over the limit keeps its
  colours and gets a warn dot above it. The table puts the same colour
  before each project's name and a thin bar after its tokens, sized against
  the project that spent the most. `GET /v1/brain/spend` now splits each
  day by project (`days[].projects`).

### Fixed

- **brain:** a session opened in `/` (a background `claude` run there is
  labelled `/`) no longer stalls Second Brain. Its project could not be
  stored, so every read of it failed whole, was never recorded, and the same
  chunk was asked again every few seconds: 3,363 times in 13 hours on one
  machine, its tokens counted toward neither the retry wait nor the daily
  limit. Such a session is now read in no project; an answer that cannot be
  stored is recorded as a failed read with its tokens and waits out the retry;
  and one memory that cannot be stored is left out while the rest of the read
  is kept, a memory sent with no title taking one from its summary.
- **brain:** the Second Brain strip says a read that did not finish in plain
  words — *The last read didn't finish (Claude's answer could not be saved).
  Caprock tries that session again by itself in 15–60 min and goes on with
  the others.* — with the raw error only in its tooltip, and so do Settings'
  *Last problem* line and the *Just read* list (*given up after 4 tries*
  instead of *too short* for a session given up on).

## [0.152.1] - 2026-10-23

### Fixed

- **brain:** a session opened in `/` (a background `claude` run there is
  labelled `/`) no longer stalls Second Brain. Its project could not be
  stored, so every read of it failed whole, was never recorded, and the same
  chunk was asked again every few seconds: 3,363 times in 13 hours on one
  machine, its tokens counted toward neither the retry wait nor the daily
  limit. Such a session is now read in no project; an answer that cannot be
  stored is recorded as a failed read with its tokens and waits out the retry;
  and one memory that cannot be stored is left out while the rest of the read
  is kept, a memory sent with no title taking one from its summary.
- **brain:** the Second Brain strip says a read that did not finish in plain
  words — *The last read didn't finish (Claude's answer could not be saved).
  Caprock tries that session again by itself in 15–60 min and goes on with
  the others.* — with the raw error only in its tooltip, and so do Settings'
  *Last problem* line and the *Just read* list (*given up after 4 tries*
  instead of *too short* for a session given up on).

## [0.152.0] - 2026-10-23

### Added

- **pipeline:** A Most expensive panel under Releases on the Pipeline page: the five pull requests (open, or merged in the last 14 days) and the five releases (of the newest read) with the highest recorded agent cost at API list price, side by side, stacked on a phone. A pull request opens its detail beside the list, a release opens on GitHub; one with no recorded session is left out, and each list says the span it covers.

### Changed

- **status bar:** the memory item reads "This Mac" instead of "Mac".

### Fixed

- **mail:** Show OAuth failures and expiry in the add-account screen, keep in-progress callbacks pending, and reconnect OAuth accounts from Settings without removing their mail. Explain when browser sign-in is unavailable in a build.
- **mail:** Keep connection timeouts concise without guessing their cause, offer retry and provider help, and keep known server settings folded after a failed account check.
- **mail:** Explain iCloud app-specific passwords step by step and replace raw authentication failures with an actionable error and folded details.
- **ui:** dragging a session row in the sidebar now shows it moving: the row
  follows the pointer, raised over the others, and they slide apart by its
  height to show where it will land. Released over the list it lands there;
  released off the list, or on Escape, it slides back and nothing moves.
  Before, the row only dimmed and you could not see where it was going. A
  dragged row or tab now makes way for a neighbour once it is halfway over
  it, rather than all the way.
- **ui:** dragging a tab in the top strip now shows it moving: the tab
  follows the pointer, raised over the others, and they slide apart to show
  where it will land. Released over the strip it lands there; released off
  the strip, or on Escape, it slides back and nothing moves. Before, the tab
  only dimmed and you could not see where it was going.

## [0.151.0] - 2026-10-22

### Changed

- **store:** the Tools screen's drill-down no longer reads tool payloads: each
  call's group, each result's failure and each Agent result's subagent are
  stored beside the event when it is written (migration 0070). On a 2 GB
  database the Bash drill-down over 30 days went from 4.1 s to 0.8 s. Calls
  stored before the upgrade are filled in the background, newest first, and
  read as before until they are, so the upgrade starts as fast as ever and
  no screen changes meanwhile. The first step towards compressing tool
  payloads (#672).

## [0.150.0] - 2026-10-22

### Added

- **app:** Phone preview in one click. When a terminal prints a local dev
  server's address (Vite, Next, webpack, `localhost`, `127.0.0.1`,
  `0.0.0.0`, `[::1]`, `*.localhost`), *Preview on phone* appears after it;
  a click opens the page beside that terminal, split, already in Phone mode
  on the device used last with Touch on, with no setting to turn on first.
  ⌘K → *Preview on phone…* lists the servers your terminals printed, then
  *Preview a URL on phone…* for any other address.
- **app:** Phones side by side. *Side by side* on the phone bar shows the
  page on an iPhone SE, an iPhone 16 and a Pixel 9 at once, each at its real
  width (375, 393, 412) and drawn smaller together to fit the pane. Reload
  and your dev server's hot reload reach all three, each scrolls on its own,
  and a phone whose page is wider than its screen gets a red *cut off*. A
  pane too narrow scrolls the row sideways; a phone's name goes back to that
  one phone. Off by default and remembered; the two extra phones exist only
  while it is on.

### Changed

- **app:** the update card folds into the status strip. A chevron in its
  corner, or Esc while focus is in it, hides the card, and the download goes
  on as a short item in the strip: *↓ 0.149.0 · 22%* with a thin bar, then
  *0.149.0 ready · Restart*, or the failure in the warning colour. A click on
  the item brings the card back (on the error, after a failure); the card
  never comes back by itself, and the fold holds for that version only.
- **ui:** under the Week card, the subagent hint is now three big figures —
  what the week's subagents cost, about what the same tokens cost on Haiku,
  and the possible saving — with one button, *Start new agents with Haiku
  subagents*, that makes Haiku the default New agent starts subagents on in
  every project that has not chosen otherwise. The fine print below the card
  is a row of small chips, each with its full sentence on hover.

### Fixed

- **pricing:** a gateway's free model — an id ending in `-free` (OpenCode
  Zen, such as `deepseek-v4.1-flash-free`) or `:free` (OpenRouter) — is priced
  at $0 instead of showing as an unknown model to report. Turns already stored
  unpriced are priced on the next start. Pricing table `2026-10-22.1`. Closes
  #787.
- **now:** the "sessions were still running when Caprock last stopped" banner
  no longer offers Continue on `claude -p` and Agent SDK runs. Those answer one
  prompt and exit, so a stop that caught one cut nothing off; Caprock now reads
  how the session was started from its transcript and leaves them out,
  including from a banner already showing.
- **loop:** a browser or computer-use tool taking the same screenshot,
  scrolling, waiting, pressing a key or navigating again is no longer flagged
  as a loop. That is how those tools work. A repeated click, typed text, edit
  or command still raises the alert.
- **memory:** the memory popover no longer lists an app bigger than the
  group it sits in (colima at 8.2 GB under *Other apps and the system* at
  7.6 GB). The used figure is RAM, while an app's size counts its compressed
  and swapped-out memory too, as Activity Monitor does; an idle virtual
  machine's guest is mostly in swap. The group now takes what its apps hold
  when that is more, an app running a virtual machine is marked *· virtual
  machine*, the card says when the sizes add up past what is in use, and the
  stacked bar never runs past the used share.
- **report:** the Weekly report panel no longer shows an old "Last send failed"
  under a fresh "sent — check Telegram". It reads the outcome again after
  *Send one now*, and a new bot token or chat forgets the last failure, which
  was about the bot that is no longer configured.

### Security

- **brain:** Second Brain no longer keeps credentials or payment details.
  Before a memory's title, summary or keywords are saved — by the automatic
  extraction, by hand, by the re-tag or from an Obsidian note — API keys and
  tokens (`sk-…`, GitHub, Slack, AWS, Google, Stripe, Telegram bot tokens,
  JWTs, bearer values, PEM private keys), card numbers (Luhn-checked),
  IBANs (checksum-checked), labelled passwords, secrets and bank account or
  routing numbers become a placeholder such as `[redacted: card number]`.
  The prose sent to the model to be read is filtered the same way, and the
  extraction's instructions say never to record such values. Memories kept
  before this are scrubbed once on start; the log says how many, by kind.
  `caprock mcp` uses the same filter, so its placeholders now name the kind
  too. The Second Brain settings say so in one line.

## [0.149.0] - 2026-10-22

### Added

- **ui:** the status bar shows the machine's memory: *Mac 9.1/16 GB* with a
  small green bar, amber with what the agents hold when the system warns or
  85% is in use, and red *Memory low* when the pressure is critical or swap
  keeps growing. A click shows who holds it — agents, Caprock, other apps —
  each agent with its state, the apps using the most, and one button that
  ends the idle agents Caprock started (their conversations are kept;
  Continue picks them up). Agents started elsewhere are listed, never
  touched. Read from the OS's own figures on macOS, Linux and Windows, only
  while a window is open; a paired phone sees the totals, not other apps'
  names. An agent whose one process passes 3 GB (or a fifth of the
  machine), or grows for hours, is flagged in the popover and its
  inspector with **Restart it fresh**: the process ends and the same
  conversation continues in a new one. Memory is each process's physical
  footprint on macOS, compressed pages included, as Activity Monitor shows.
  New `GET /v1/system/memory`, `POST /v1/system/memory/end-idle` and
  `POST /v1/system/memory/restart`.

### Changed

- **inspector:** every tab's Spend now opens on that agent's own session —
  its burn and spend — instead of one period shared by every tab, which made
  a Caprock-wide *today* show the same chart and dollars in every tab.
  *Today*, *7d* and *30d* across all sessions are still in the period picker,
  and a pick stays in the tab it was made in. Folded, a chip says whose
  figures they are: *session*, or *today · all*.

### Fixed

- **app:** a terminal tab left out of sight for ten minutes keeps the last
  1,000 lines of its scrollback instead of 10,000, and has the full 10,000
  again when shown. Every tab ever opened used to hold its whole scrollback:
  ten full tabs held 103 MB of the window's memory, 24 MB once trimmed
  (measured 2026-10-22). The tab in front and anything shown in the last ten
  minutes are unchanged, and nothing is redrawn on the way back.
- **daemon:** cached dashboard answers for a past day or range are dropped
  once they are too old to show (they were kept for as long as the daemon
  ran); a session Caprock started that crashes or is killed no longer leaves
  its last tool inputs in memory; and the daemon sets a soft 256 MiB ceiling
  on Go's own memory (unless `GOMEMLIMIT` is set). A heavy synthetic load
  stayed under 90 MB of it (measured 2026-10-22); near it the daemon collects
  harder and returns memory to the system instead of growing.
- **app:** dragging a file from iCloud Drive onto the window no longer
  closes the app. macOS hands over such a file in a way the window's drag
  code did not expect, and the app quit on the spot (0.141.0 to 0.147.0).
  Every file is now passed on as it is, whatever its name or where it lives.
  If the app ever stops on an error again, the reason is written to
  `app.log` in Caprock's data folder.
- **app:** the app no longer stops at "Caprock could not start: another
  Caprock daemon is already running" when its background service is still
  starting, which happened at login on a busy Mac. It waits for that daemon
  and connects to it. If the service does not answer, the app restarts it.
  Try again does the same.
- **app:** dropping a file on the window no longer touches the disk on the
  thread that draws the app. A file from Finder is handed to the terminal as
  it is; a screenshot thumbnail or another temporary file is copied on a
  background thread first. On a Mac short of memory and swapping, that copy
  could freeze the window for seconds.
- **hooks:** the hook shim in Caprock's data folder is brought up to date every
  time Caprock starts. The desktop app never replaced it, so a shim an earlier
  Homebrew install had put there could keep running, months old, under a
  current Caprock. With no separate shim to copy, the app puts its own
  `caprock` there, which works as the shim.
- **hooks:** Caprock's own hook and status line commands in
  `~/.claude/settings.json` are repointed at this install when they run a
  `caprock` that is gone or is another copy (an uninstalled Homebrew one, for
  example). A status line or hook of your own is never touched, and the file
  is backed up first.
- **terminal:** a terminal tab whose session's process is gone no longer
  spins on "Reconnecting…" for good. After the background service restarted,
  tabs for sessions that died with it were refused by the daemon on every try,
  and a browser is never told why. Now, after three refused tries, the tab
  asks the daemon and says what is wrong and what to do ("Can't connect" with
  the reason); a session the daemon still does not hold about 20 s later is
  ended, and the app shows its conversation with Continue here. A tab restored
  for a running session whose terminal Caprock lost opens that way at once,
  and a session the daemon holds is served even when no new agent could be
  started.

## [0.148.0] - 2026-10-22

### Added

- **brain:** Second Brain now goes back and reads what it skipped. Before
  this release, a read of a long session kept only its newest part, and the
  older part was never read. Caprock now finds those skipped parts on its
  own and reads them oldest first. It does this only while automatic
  reading is on, only when no new session is waiting, and within the same
  daily token limit. The Second Brain status shows how far it has got and
  estimates how many days the rest will take.
- **brain:** Second Brain finds what was decided and knows which decisions
  still stand. Search matches whole words (*PR* no longer finds *project*
  and *prompt*: 136 memories instead of 1,097 on the owner's database),
  any word may match, rarer words and title or keyword hits rank first,
  and *PR*, *pull request*, *cost*, *price*, *spend*, *decision* and *rule*
  find each other. Each new memory gets five to eight English keywords,
  whatever language its title is in, so an English query finds a memory
  written in another language (older memories get theirs from the
  re-tag). A read
  is shown the project's current decisions and recent memories with their
  ids: it no longer repeats one, can link to one, and can say a new
  decision supersedes an older one. A superseded memory is ranked last,
  dimmed and struck through in the graph, and says what replaced it; its
  *Undo* makes it current again. A new session's handoff now leads with
  the project's current decisions (up to 15), carries one memory per
  session, and goes even when no recent passage does. `caprock mcp` gains
  `current_decisions`, and `search_memories` returns up to 30 ranked
  candidates with keywords and a short summary for the agent to judge.
- **brain:** Second Brain gives English keywords to the memories that have
  none, the ones kept before keywords existed and the ones typed by hand,
  so an English search finds a memory titled in another language. It runs
  on its own while automatic reading is on and no session waits to be
  read, 40 memories a call, within the same daily token limit; its tokens
  show in the spend like a read's, in a row of their own (*Keywords for
  older memories*), and the strip's second line says *Adding keywords to
  older memories: X / Y* while no catch-up is running.
- **brain:** Second Brain says what it spends. A strip on top of the screen
  reads *Today 84k of 300k tokens* over a thin bar against the daily limit,
  with a chip for its share of every Claude token Caprock recorded in the
  same 24 hours; while a backfill catches up, a second line says *X / Y
  reads, about N days left*. A click opens the last 14 days: tokens per day
  against the limit, and reads, tokens and memories per project. Read from
  the new `GET /v1/brain/spend?days=` (open to paired devices); the status
  gains a generic `catch_up` field.
- **mcp:** one-click Connect for `caprock mcp`. Second Brain opens with *Let
  your agents ask Second Brain* and a button per installed agent; a click runs
  `claude mcp add -s user caprock -- <path> mcp` or `codex mcp add …` on this
  machine, *Update path* fixes a registration that points at an old caprock,
  and *Disconnect* removes it. Settings shows the same status above the copy
  commands. Only on a click, never from a paired phone, and nothing leaves the
  computer (`GET /v1/mcp/agents`, `POST /v1/mcp/agents/{agent}/connect|disconnect`).
- **modules:** a private module can say what waits on you in it, with `PUT
  /v1/x/<id>/attention` (a count and up to eight items, each a short label and a
  `#route` inside the module). Its sidebar row shows a small *2 waiting*; a
  click unfolds the items, and an item opens the module right there. The row and
  Second Brain above it fold as an accordion. At 0 the row is unchanged, and a
  report stops showing a day after the module last sent one.
- **modules:** a module can edit a Telegram message it sent — new text, new buttons, or none (`PATCH /v1/x/<id>/telegram/<message_id>`) — so a batch of approved drafts shows which cards are done, can thread a new message under one of its own with `reply_to_message_id`, and can pin one message at a time with `pin` (silently, replacing only its own previous pin). Presses on edited buttons land in the module's store like the first ones; any message the module did not send is a 404.
- **tabs:** an empty new shell shows one dim line under its prompt, "Run
  claude, codex or any command · ⌘W closes this tab" (Ctrl+Shift+W on
  Windows and Linux). It is drawn over the terminal, never typed into the
  shell, goes at the first key you type, and never shows in a tab that
  already has output. The tab strip's + now says "New terminal ⌘T" on hover
  (Ctrl+Shift+T on Windows and Linux).

### Fixed

- **mcp:** `memory_topics` with a project now counts that project's memories
  and lists that project alone, instead of the totals for every project
  beside one project's topics. `session_summary` says how many files a long
  session touched beyond the 40 it lists (*+N more*), counted from the whole
  session rather than the daemon's first 100.
- **brain:** the screens no longer promise every agent what only Claude Code
  gets. Any agent's sessions add memories, but only a Claude Code session is
  handed them at start; the tagline, the agents line (*Claude Code and Codex
  add to it; Claude Code sessions start with it.*) and the third step of
  *How it works* now say so. *Links* on the Brain screen counts links from
  one memory to another only, not each memory's link to its topic or
  project.
- **brain:** Second Brain reads a long session whole. A read still sends at
  most 24,000 characters, but a session with more is now read in chunks,
  oldest first, each read going on where the last one stopped; before, a
  read kept only the newest part and the older part was never read. A wake
  still makes at most four calls, so a read costs what it did. The
  extraction is also told to keep a decision or standing rule you state
  ("from now on", "rule:") as a decision, and a stretch of mostly your own
  prompts is read rather than skipped for want of the agent's prose.
  Machine-made "user" turns (task notifications, reminders, slash-command
  echoes, messages from other sessions) are no longer read as your words,
  and a prompt is sent up to 2,000 characters instead of 600.
- **brain:** A short exchange at the end of a session that is still open is
  no longer marked read and lost. Second Brain waits and reads it together
  with what the session says next. When the session has ended, the short
  tail is marked read, so nothing waits forever.
- **brain:** a session that ran in a folder under the system's temp directory
  no longer files its memories under a throwaway project named after that
  folder (an archive extracted to `ops-seo-site-m143z5ko` made one per run).
  A checkout there with a remote is named after the remote's repository;
  anything else keeps its memories with their topics and no project.
- **docs:** the guides match the app again. Closing a tab ends an idle agent
  (its conversation kept) and asks about a working one; the sidebar has no
  worktree rows or ±N; the phone says *No internet on this phone* and counts
  down to its next try; desktop notifications have the one switch *When a
  session needs you*; a paired phone starts any agent it lists, not just
  three; Gemini is read through its telemetry file; and an ended Hermes
  session is carried on in your own terminal, not in a Caprock tab.
- **app:** dropping a file on the window no longer touches the disk on the
  thread that draws the app. A file from Finder is handed to the terminal as
  it is; a screenshot thumbnail or another temporary file is copied on a
  background thread first. On a Mac short of memory and swapping, that copy
  could freeze the window for seconds.
- **hermes:** an ended Hermes session can be continued in a Caprock tab
  again (`hermes chat --resume <id>`), as Codex and OpenCode ones are; it was
  refused with "Caprock continues Claude Code, Codex and OpenCode sessions."
  It is offered once the session has ended, while its folder and Hermes's
  `state.db` exist and `hermes` is installed.
- **ui:** the shortcut list no longer says ⌘W leaves the session running: it
  closes the tab or pane, an idle agent ends with its conversation kept, and
  a working one asks Keep it running or Stop it.
- **phone:** Continue on the phone home now lists the sessions open as tabs
  on your computer, in the tab strip's order and under the same names, and a
  row no longer jumps around as sessions start and stop working: its status
  changes in place. Sessions running in the background without a tab stay
  under *All sessions*. When the computer's app has not reported its tabs,
  the live sessions are listed oldest first, in an order activity never
  changes. The app now reports its tabs in strip order, and the daemon
  answers `GET /v1/tabs` (a paired phone may read it).
- **now:** **What happened** is back on Now, after a merge on 2026-10-14
  dropped it an hour after it shipped and brought back the old feed of one
  line per command. It shows the moments of your sessions again: files edited
  (grouped by folder), tests and builds with their result, commits, pushes,
  pull requests, subagents by their task, turn ends, approvals and failed
  commands, with reads as a quiet `+N`. *All commands* brings the full feed
  back; the panel folds and every row is the same height; the end of a turn
  no longer reads as "session ended".

## [0.147.0] - 2026-10-22

### Added

- **modules:** a private module can message its owner. `POST
  /v1/x/<id>/telegram` sends to the owner's own paired chat through the
  existing Caprock bot, its first line naming the module, with optional
  buttons or a reply field; a press or a reply is written back into the
  module's store (`telegram/<message_id>-<n>`) and never reaches a session.
  `POST /v1/x/<id>/notify` shows a desktop notification from the Caprock app,
  titled with the module's name, that opens the module when clicked.

### Fixed

- **ui:** a folded inspector section no longer runs past the panel's edge.
  The Changes row read *511 files +35244 −7781 Review and co*, cut mid-word;
  now each row's summary shortens to fit: the counts compacted (*+35.3k
  −7.8k*), *Review* for *Review and commit*, then fewer parts, and nothing
  rather than half a word. The same holds for Subagents and Processes.
- **ui:** the Subagents cost says *total*: *1 finished $2,549.54* was every
  subagent's cost over the whole session beside the count of those that
  finished in the last half hour, and read as one subagent's.
- **mail:** *Import everything* no longer hides Apple Mail when macOS keeps
  Caprock out of its account list. iCloud, Google and Exchange accounts in
  Apple Mail were silently missing because the list sits behind Full Disk
  Access, which macOS never asks for. The screen now says *Caprock can't read
  Apple Mail's account list*, with *Open Full Disk Access* (opens that list in
  System Settings and shows Caprock's program in Finder) and *Add iCloud with
  an app password instead*. Adding iCloud now walks through getting an
  app-specific password in three short steps, with a button that opens
  account.apple.com and one field for the code. An iCloud account found in
  Apple Mail is marked *Needs an app password*.
- **telegram:** saving a new bot token, or pairing a new chat, no longer
  leaves the old *Last alert failed* under Settings → Telegram until a test
  is sent. The old outcome is forgotten at once and the line reads *Saved.
  Send a test alert to check it reaches you.* With no alert switched on, the
  section now says the bot is idle: nothing is sent and its messages are not
  read.

## [0.146.0] - 2026-10-22

### Added

- **docs:** what `/clear` and a fork do in Caprock: the conversation stays one
  card linked to its earlier parts, while Claude itself starts with an empty
  context and gets no handoff note.

### Changed

- **brain:** memories moving: when a read keeps memories, one silver thread
  for the whole read drifts from that session's row (else its tab, its
  project's row or its agent's face) into the sidebar's Second Brain, which
  ripples and shows *+N*; when a new session is handed memories, a thread
  goes the other way into its tab with *N memories handed*. At most one a
  minute each way, with counts merged, never while you type, nothing in a
  hidden window; with reduced motion only the count shows. The setting is
  now *Show memories moving* (same switch, one for both directions). The
  card's agent faces now show only agents whose sessions were read in the
  last 24 hours, each with how many, and the one being read glows; the orb's background sparks
  no longer look like memories arriving. The live `brain` frames gain a
  read's start and end (`phase`, `run`, `agent`, `added`) and a `handoff`
  frame, and `GET /v1/brain/status` gains `auto.agents_24h`.
- **attention:** a session whose turn ended is now either **Needs you** or
  **Done**. Needs you is a permission prompt, a question, a plan to approve
  (ExitPlanMode, which now says so), a turn that stopped on an error (a
  StopFailure such as a rate limit, which used to read "working", then
  "idle"), or a last message that asks you something (a guess, marked with a
  dashed GUESS chip). Done is a turn whose last message asks nothing: it stays
  listed, quieter, and is never counted in the badge, the tray head or the
  phone's amber card. Home, the sidebar, the tray popover and menu (Done in
  its own submenu) and the phone home all show it; *needs me?* and *not
  needed* move a guess until the session's next turn.
- **notifications:** a turn that ends on a question is *Needs your answer*
  instead of *Finished*, and a Done turn raises no OS notification. Telegram
  still sends *Finished* for Done turns, unless the new *Also when it asked
  nothing (Done)* switch is turned off.

### Fixed

- **ui:** the session's state under its portrait says *Background* on one line
  while background subagents work, instead of wrapping *Background agents*
  over two lines in a narrow inspector; the full *Background agents working ·
  N* stays on hover and is what a screen reader announces.
- **api:** a shell tab's inspector shows its folder's uncommitted changes, instead of asking for a session that does not exist and logging a 404 on every refresh.
- **tabs:** after `/clear` in an agent tab, the tab carries on with the
  conversation instead of freezing on the part before it. The terminal stays
  attached, the chat shows the earlier part above a *Context cleared — Claude
  no longer remembers the part above* line with the new part under it, typing
  works, and the session page no longer says the session has ended while it
  runs. A fork never takes the original's tab. A Caprock restart finds the
  newest part of a cleared session again.

## [0.145.0] - 2026-10-21

### Added

- **app:** Phone mode for a browser tab (beta, with the in-app browser on):
  *Phone* on the tab's toolbar, or ⌥⌘R (Ctrl+Alt+Shift+D on Windows and
  Linux), shows the page at iPhone 16, iPhone SE (3rd gen), Pixel 9, Galaxy
  S24 or a custom size inside a simple device frame. The page itself is
  resized to the phone's page area, so media queries and `innerHeight` read
  the phone's numbers, and it gets the phone browser's user agent. Rotate,
  browser bars shown or scrolled away, and *Touch*, which turns the mouse
  into a finger (drag to scroll with momentum, swipe, pull a sheet). Page
  heights marked *est.* are estimates of the bars; the **?** lists per
  system what is real, approximate or not emulated.

### Changed

- **ui:** The phone home is shorter and says more at a glance. *New chat* is a
  filled button in the Chats row. Continue, Releases and Saved fold from their
  headers (Continue open, the other two folded at first), and a folded section
  keeps one line: how many sessions wait, work and sit idle; the repository and
  its next release, with a pull request whose CI failed said first in red; how
  many notes were saved and the newest. The phone remembers the folds. A new
  *Limits* line shows the 5-hour window with its reset and the weekly one,
  amber from 80% and red from 95% (Codex's when Claude Code has none), and
  opens Cost at its plan limits. A live Continue row says its context used and
  its subagents at work.
- **api:** `GET /v1/stats/limits` answers the plan windows alone
  (`rate_limits`, `codex_rate_limits`), as the summary carries them, so the
  phone reads two percentages without the whole summary. A paired device may
  read it.

### Fixed

- **ui:** links in a chat can be tapped, on the phone too. A bare
  `https://…` address in an agent's reply was plain text; now every http(s)
  address in a reply, a prompt, the Answers tab and the last-word popover is
  a link that opens in a new tab (in the desktop app, your browser), with a
  sentence's trailing punctuation left out and a long address wrapping
  instead of widening the screen. Other schemes stay text.
- **remote:** a phone that loses its network no longer offers *Pair again*.
  It says *No internet on this phone* at once, large and full width, with
  the next try's countdown, and reconnects by itself when the network is
  back, keeping the last screen dimmed underneath. A relay that cannot be
  reached and a computer that is not answering each get their own words;
  *Pair again* shows only when the computer removed the phone or its keys
  changed.
- **api:** Claude Code's footer no longer loses characters after you switch
  tabs or apps or reconnect: no more status line of lone digits or mode line
  with its words gone. The repaint that redraws a reattached terminal now waits
  for the session to draw at the narrower size before restoring its width. A
  busy Claude Code used to get both size changes as one and redraw nothing. A
  terminal that falls behind mid-session is now repainted too.

## [0.144.0] - 2026-10-21

### Added

- **modules:** a private module opens on a paired phone the owner made a
  controller, over Wi-Fi or from anywhere: listed in the phone's menu and the
  header, drawn in the app's theme, with its own files and document store.
  It runs in a sandboxed frame that reaches only that module's files and
  store; a phone that only views sees no module, and the admin key and
  installing a module stay on the computer.

## [0.143.0] - 2026-10-21

### Added

- **agents:** `POST /v1/agents` takes `end_when_done: true` for a new Claude
  Code or Codex session started with a prompt: once its turn finishes (Claude
  Code's Stop hook, Codex's `task_complete`) with no permission prompt,
  question, queued message or working subagent left, Caprock ends it the way
  End does. A script that starts a one-job session every half hour no longer
  leaves an idle TUI behind each time — Codex's never exits by itself, and 27
  of them had piled up in a day on one machine. Off unless asked for; never
  applied to a session started without it or not started by Caprock.
- **agents:** a chat or agent Caprock started that has no tab is ended once it
  has sat idle for 12 hours — nothing typed, drawn or recorded, and no
  permission prompt, question, queued message or working subagent waiting —
  so idle sessions no longer pile up in memory. Settings → New sessions →
  *End idle chats after*: 2 h, 12 h, 24 h or Never. The conversation stays
  listed and says *Ended after 12 h idle — continue*; opening it (or replying
  to it in Telegram) continues it from where it stopped. Never applied to a
  session with a tab, a shell, the orchestrator's workers, or a session
  Caprock did not start. Idle time is measured from the session's own
  activity, so a daemon restart does not reset it.

### Changed

- **ci:** the release's desktop app builds start from compiled Rust
  dependencies instead of from scratch. A new master-only CI job keeps a
  Rust cache of the macOS universal build (both architectures). CI's Linux
  app build moves to ubuntu-22.04, the image the release builds the AppImage
  on, so the two share one cache. The release jobs only read master's caches
  and no longer write Go caches that no later tag could read. A stale or
  missing cache costs build time only: signing, notarization and the
  updater signatures are unchanged.

## [0.142.0] - 2026-10-21

### Changed

- **app:** the macOS app is now signed with Caprock's Apple Developer ID and
  notarized by Apple, the `.app` and the `.dmg` stapled, so it opens without
  "Open Anyway" and the Homebrew cask no longer clears the quarantine flag.
  macOS keys privacy answers to the app's signature, and this signer is new
  to it: on the first launch of the first release signed this way Caprock
  asks once more for the microphone and for each folder it was allowed, and
  updates keep the answers from then on. Answers given to `claude` or
  `codex`, notifications and keychain passwords are not affected. While the Apple secrets are missing a release
  falls back to the self-signed certificate, as before.

### Removed

- **phone:** the phone chat's walkie-talkie bar is gone (owner, 2026-10-21:
  unused and in the way): the speaker switch, the + sheet, hold-to-talk, and
  the latest answer's AI;DR, Read aloud, Continue and Stop. The phone chat
  has the regular field again: Keys, Photo, the dictation language, the
  microphone and Send. New chat stays on the phone home; Report a bug is in
  ⌘K on a computer.

### Fixed

- **store:** Caprock no longer opens a database that a newer Caprock has
  migrated. Going back to an older version used to open it anyway and could
  lose data without a word; now the daemon stops before writing anything and
  says, in one line, the database's schema number, the highest this version
  knows, and to install the newer Caprock. `caprock up`, the desktop app's
  "Caprock could not start" screen and `caprock doctor` show that line, and
  the database file is left exactly as it was.

## [0.141.0] - 2026-10-21

### Added

- **sidebar:** *Recently closed* lists the last five tabs you closed, newest
  first, each with a quiet age (*2 min*, *1 h*), above *Running, no tab* in
  the Tabs list and after the projects in the Projects list. A click brings
  the conversation back in a tab: its own tab while the agent still runs,
  continued with `--resume` once it ended. **⇧⌘T** reopens the newest, as in
  a browser (Ctrl+Alt+Shift+T on Windows and Linux). *Show all in History*
  opens History; the list is kept across restarts.
- **sidebar:** *Running, no tab* keeps the sessions you started yourself,
  titled and active in the last day. Sessions in a temporary folder, ones
  another tool started with a scripted brief, untitled ones and ones idle for
  a day fold into one *Background · N* row at the bottom, opened on a click
  and remembered.

### Changed

- **modules:** a private module's key is ⇧⌘1–⇧⌘9 on a Mac (it was ⌥⌘1–⌥⌘9),
  so the first module opens with ⇧⌘1. Windows and Linux keep
  Ctrl+Alt+Shift+1–9. macOS keeps ⇧⌘3, ⇧⌘4 and ⇧⌘5 for screenshots, so on a
  Mac the third to fifth module's row shows no key and says why in its
  tooltip; the key still works where those screenshot shortcuts are off.
- **app:** the theme picker moved from ⇧⌘T to ⌥⌘P (Ctrl+Alt+Shift+P on
  Windows and Linux), so ⇧⌘T can reopen the last closed tab.
- **app:** an agent tab's Chat | Terminal pills are one quiet icon at the
  right of the tab strip. It shows the other view — a chat bubble over the
  terminal, a terminal glyph over the chat — named *Show as chat* / *Show as
  terminal*, and one click flips it. Each session keeps its own view, and the
  terminal stays running under the chat as before.

### Removed

- **app:** the session deck under the agent's terminal (⌘B, the *Deck*
  button, *Pipeline bar: On/Off* in the palette). What it showed is in the
  inspector and on the Pipeline page: a session's own pull request in the
  inspector's CI block now offers the one action it needs — *Resolve
  conflict*, *Update branch*, *Fix CI* or *Re-run* — asking once in the row,
  with its agent cost and who is on it, and *Log in Pipeline →* opens the
  Pipeline on that pull request with its failed job's log and *Investigate*.
  The Pipeline page gains a *Default branch* panel: each workflow's newest
  run there, a failed job's log with *Investigate*, and what GitHub billed
  for Actions this month. The deck's Branches view is gone. ⌘B is free.

### Fixed

- **daemon:** the dashboard reads far less of the database while agents work.
  The Work board keeps each live session's newest events and task list until
  the session writes something, the plan-limit pace is counted again only
  when a new sample arrives, the status screen's Memory line stops at the
  first passage it needs instead of parsing a fortnight of replies (it often
  ran out of time and showed nothing), and a week of spend per subscription
  is summed once a minute instead of on every request. On a copy of a 1.85 GB
  database with the Now screen open, the database reads the daemon asked for
  fell from 2,050 MB to 1,231 MB in three minutes.
  The Work board also keeps each session's spend today until it changes, and
  task lists are read from their own index (migration 0066) instead of a walk
  through every event of the session.
- **ui:** the phone no longer scrolls sideways. On an iPhone, tapping a field
  smaller than 16px (the phone home's Repository and Project pickers, most
  Settings fields, Cost's cap) zoomed the page in and left it panning
  sideways; every field is 16px on a phone or touch screen now. A chat file's
  Markdown viewer no longer grows to the width of its longest link or path,
  and a wide table in a reply scrolls in its own frame instead of breaking
  every cell into two-letter lines. A new e2e test walks every phone screen,
  sheet and menu at 360, 390 and 430 px in a phone profile and fails on any
  sideways scroll, anything cut off at the edge or any field under 16px.
- **smoke:** the end-to-end smoke tests start their daemons with the file
  secret store, so running them on a Mac never writes a test token into the
  real login keychain; the Telegram smoke had replaced a developer's real bot
  token there.

## [0.140.2] - 2026-10-20

### Fixed

- **app:** after an in-app update on macOS, Caprock opens again with its
  window in front. The updated app was started as a child of the old one,
  which macOS never brought forward, so it waited behind other windows until
  a click on its Dock icon; it is now launched the way the Dock launches it.
- **app:** a terminal no longer keeps stale rows after its GPU context is
  lost (a sleep, a GPU reset, or WebKit letting a background tab's context
  go): it switches to its plain renderer in that frame instead of drawing on
  a dead canvas for three seconds, or for good when no loss was reported, and
  gets a fresh context shortly after. A lost context is also looked for when
  you come back to the tab or the window. The key hint over Claude Code's
  input box goes when the window loses focus instead of staying over the
  quick replies.
- **app:** reopening a terminal or coming back to it after its connection
  was let go no longer leaves a stale line on its bottom row. Caprock makes
  the program in it redraw by changing the size for a moment; it used to
  take one row away, and Claude Code then cleared one row too few. It now
  takes one column away, which makes it clear the whole screen.
- **app:** a window that goes white comes back by itself instead of staying
  blank until the app is quit. When macOS ends the WebView's content process
  (under memory pressure, or a crash), the app reloads that window, waiting
  longer each time it repeats. A page the app asked for that never finished
  loading is loaded again while the daemon answers. A page that loaded but
  drew nothing (a file of it missing while the daemon restarted) shows
  *Reconnecting to Caprock…* with Reload and reloads once the daemon
  answers. Each of these, and the crash screen, writes one line to the app's
  own log on your Mac (`app.log` in Caprock's data folder), so a report can
  say why; nothing is sent anywhere.

## [0.140.1] - 2026-10-20

### Changed

- **deps:** routine dependency updates: purego 0.11.2, klauspost/compress
  1.20.3, golang.org/x/text 0.43.0 and x/sync 0.24.0; React 19.3.1, Vitest
  5.0.5, jsdom 30.1.3 and Playwright 1.64.1 for the dashboard's tests; the
  goreleaser action 7.3.0 for release builds.

## [0.140.0] - 2026-10-20

### Added

- **app:** an agent tab shows its session as a **Chat** or as its
  **Terminal**, from a switch in the tab strip. Quick chats open on Chat and
  project sessions on Terminal; the choice is remembered for each session.
  The chat reads like one: your messages as bubbles, the agent's replies as
  text, each tool call as one plain line (*Searched the web: …*), and a
  question that only the terminal can answer links to **Open in Terminal**.
  Switching never restarts the session or types into it, and the hidden
  terminal does not draw.

### Changed

- **perf(api):** with the dashboard open and agents working, the daemon no
  longer counts the whole history again on every 10-second poll. A history
  that reaches before today (7 days, 30 days, all time) is kept for a minute
  however fast it was to count; today's keeps its 3-second refresh. A quick
  count was quick only because the page cache answered it, and on a machine
  short of memory every count went to disk: one user's daemon read 8.8 GB in
  an hour. On a preview stand with a 103 MB database and the Now screen open,
  database reads fell from 193 MB to 71 MB per 3 minutes (2026-10-20). The
  lifetime and weekly figures can now be up to about two minutes behind.
- **ui:** Settings → Computers says what to do. Connected computers come
  first — this one, the ones it reaches and the ones that reach it, each with
  **Disconnect** — then *What is this computer?* (**The main one** or
  **Connects to another**) and three numbered steps for that side that tick
  as they are done: access from anywhere, the other computer's choice, and
  the link to paste with how long it lasts and **Copy**. What the relay is,
  where access from anywhere is switched on and what it sends sit behind the
  (i) beside *Add a computer*. Pairing and what it sends are unchanged.
- **ui:** the pull request progress bars end at merged. A merged pull request's
  bar is now completely filled on Work, the Pipeline, the release plan, the
  phone's Releases and the right panel's CI block, instead of leaving a grey
  *released* block that read as unfinished or closed. Whether it shipped is a
  quiet word after the bar: *in v0.140.0* once released, a muted *not
  released* while a repository that cuts releases waits for the next one. A
  pull request closed without a merge still reads *Closed*.

### Fixed

- **ui:** Lifetime's Daily cost chart draws every calendar day through
  today, a day without work as an empty bar, instead of closing the gap
  and putting a quiet week next to a busy day. Its 30d, 90d and 180d now
  cover the same days as the range buttons, in local time.
- **ui:** quick chats no longer pile up in the sidebar with no tab. Closing
  tabs in bulk — a project's *Close tabs*, its ×, *Hide*, *Remove from list* —
  ends the quick chats in them as ⌘W does (one question for a chat still
  answering). A quick chat with no tab is listed under *Running, no tab* only
  while it works or asks for something, or for 10 minutes after its last
  answer; it stays on the Chats screen and in the palette. Its row now says
  what the chat is about, when it started and its model, instead of only
  *Quick chat · <model>*, so two chats can be told apart.
- **ui:** on Windows and Linux, hovering a sidebar row (Dashboard, Mail,
  Settings, New agent and the rest) or a folded footer icon shows one hint,
  its tooltip with the key in it, instead of a key chip at once and the
  tooltip a second later. The chips still show under keyboard focus and all
  together while Ctrl is held; macOS is unchanged.

## [0.139.0] - 2026-10-19

### Changed

- **ui:** the right panel's *Release* section reads at its own width: each
  pull request's title takes the full row and wraps to two lines instead of
  being cut beside a progress bar, with one muted line under it in plain
  words (*CI 1/3*, *CI failed*, *ready*, *merged · not released*) and its
  age. Blocked pull requests come first, marked *!*; a branch a batch pull
  request already carries shows as that pull request's *+N branches*; the
  branches without a pull request fold away by default, one line each with
  their age; the heading is the version and the last release.

## [0.138.0] - 2026-10-19

### Added

- **agents:** New agent (desktop, and the phone's start sheet) asks which
  model Claude Code's subagents run on: the session's own (default), Haiku,
  Sonnet or Opus. It sets `CLAUDE_CODE_SUBAGENT_MODEL` for the session, is
  remembered per project, and shows on the session as *subagents: Haiku*. The
  Week screen adds a note when subagents ran on a pricier model than Haiku and
  the difference is a dollar or more: what they cost, and about what the same
  tokens would cost on Haiku (an estimate at list prices).

### Changed

- **perf:** a hidden window no longer receives terminal output: after 2 s
  out of sight each terminal lets its socket go and, when shown, resumes from
  its last byte, so nothing is lost. A flooding terminal is written at most
  every 33 ms instead of on every chunk. The status strip's footprint and the
  shell list arrive as live-socket frames instead of a 10 s poll each.
  Measured in Chromium against a test daemon, 60 s each (2026-10-19,
  `docs/app-window-footprint-2026-10-19.md`): terminal frames to a hidden page
  1,218 → 0 and its CPU 1.85% → 0.62%; three tabs with one at 20 lines a
  second 28.4% → 17.9% browser CPU and 7.3 s → 4.3 s main-thread work; idle
  Home 28 → 17 requests a minute.
- **ui:** right after a check, the version panel's button is Check again;
  What's new is a link on the "Checked" line.

### Fixed

- **brain:** keeping a memory while a backfill imports many transcripts no
  longer fails with `SQLITE_BUSY`. Each import batch left the database free
  for a while after it committed, but a batch already waiting was handed the
  lock at once, so the gap never opened; it now waits the gap out. A write
  that still finds the database busy is answered `503` with words, and the
  dashboard tries a drop again rather than showing a bare error.
- **terminal:** a shell terminal's holder stops on `SIGTERM` within about a
  second. It passed `SIGTERM` to the shell, which ignores it, and then waited
  for good; it now hangs the shell up first (as closing a terminal window
  does, which also ends the shell's jobs), and kills what is still running
  750 ms later.
- **release:** the right panel's *Branches pushed, no PR yet* no longer lists
  branches that already shipped. A branch squashed into a batch pull request
  was still listed once master edited the same files or the release consumed
  its changelog fragment; it is now found by its commit subjects in the
  squash's message, or by its changes still standing in master's history. A
  branch already inside another open pull request's branch (a batch) is left
  out too. Each branch reads in two lines at 360px — its commit subject, then
  the branch, its commits and age with ↗ — five at a time behind *Show all
  N*, and a branch with no commit in a week waits behind *+N older*. Pull
  request titles in the right panel take two lines instead of being cut.
- **ui:** in a short window a sheet uses most of its height, and New agent's
  First message scrolls into view when focused instead of sitting under the
  footer.

## [0.137.0] - 2026-10-19

### Added

- **telegram:** forward messages to your paired bot — text, photos, links,
  files, voice notes, one or several at once — and it asks once *Where to?*:
  a running session Caprock started (waiting, working, then recent), a new
  chat, or Cancel. Everything goes to the agent as one message, your own
  words first, each item quoted with who wrote it; photos and files are
  saved where pasted files go and named by path, a voice note is saved and
  marked not transcribed. A busy session gets it when its turn ends, and the
  bot says when it went. In Caprock it shows with a small *from Telegram*.
  *Reply here* (off by default, remembered) sends that turn's answer back.
  Premium, with two-way chat on (ADR-081).

### Fixed

- **app:** on Windows the tab keys read "Ctrl@0" and "Ctrl@1": the chip
  used the ⇧ glyph, which no font Windows draws it with carries. Off macOS
  every key now reads as the chord you press, Ctrl+Shift+1. The long
  Windows and Linux key hints no longer crowd or cut the sidebar's labels
  ("Settings", the theme's name, "Quick chat") or fill the header: a row
  shows its key while the pointer is on it, and holding Ctrl shows every
  key at once. macOS is unchanged.

## [0.136.0] - 2026-10-19

### Changed

- **ui:** the line under the next release now says where it stands in one row: what is merged, the open pull request and its CI, agents working and branches ready, and the last release. Each part jumps to its list.
- **perf(api):** the all-time history behind the Now screen and History is no
  longer counted again on every poll while agents work. It is refreshed at
  most once per 20 times what counting it took (never past 2 minutes), and
  its totals reuse the summary's scans instead of making them twice. Today's
  figures keep their 3-second refresh. Measured 2026-10-18 on an M1 Pro under
  a synthetic working load (four Claude and two Codex sessions writing, hooks,
  two dashboard pages): on an 890,000-event history the daemon went from 40%
  of one core to 11% and the history refresh's allocation from 2,839 MB to
  182 MB per 150 s; on a 181,000-event history the refresh's own CPU fell 40%
  and the daemon's total stayed within noise.
- **perf(api):** the sessions list no longer re-reads every listed session's
  recent events on every request. Each session's reads are kept until its
  events change: an insert raises its newest event id, and new database
  triggers count updates and deletes (migration 0063). Narration, stats, live
  subagents and the clock are still worked out on every request. Measured
  2026-10-18 on an M1 Pro under a synthetic working load (181,000-event
  history, four Claude and two Codex sessions writing, hooks, two dashboard
  pages): the list's allocation per request fell from 0.85–0.87 MB to
  0.35–0.36 MB and its CPU per request from 1.8–3.2 ms to 0.8–1.1 ms. The
  daemon went from 13–15% of one core to 11–12%. The cache holds about 9 MB
  for at most 256 sessions.
- **perf(rollup):** importing history writes many events per transaction
  instead of one. The Claude transcript reader and the Codex importer commit
  up to 512 events or 50 ms at a time, with a transcript's read position saved
  in the same transaction, so a failed batch is read again and nothing is lost
  or counted twice. Live hook events keep their own transaction and are let in
  as soon as they wait. Every recorded event also stopped starting four or five
  short-lived goroutines inside the database layer. Measured 2026-10-18 on an
  M1 Pro, importing a synthetic 178,000-event history: 149–150 s and 152–160 s
  of CPU before, 101 s and 83–84 s after; the daemon under a working load went
  from 12.8% of one core to 11.6–11.9%.
- **web app:** The phone Home is back to what 0.134.0 showed: the Projects list added in 0.135.0 now appears only at tablet width and wider, so long-unused projects no longer fill the phone screen. The chat field is no longer docked at the bottom: it lives in a Chats section, folded by default, with the newest chats and All chats.
- **web app:** The folded Chats row on the phone Home has a **+ New chat** button at its right: one tap opens the chat field with the cursor in it.
- **ui:** Send just sends, on the phone and on the Mac. A message sent while
  the agent works was already held and typed in by itself when the turn ended,
  but it was drawn as a dashed "Queued" bubble with three equal buttons (Edit,
  Cancel, Send now), which read as a choice you still had to make. It is now an
  ordinary outgoing bubble with one muted line, "Sends when Claude finishes";
  Send now, Edit and Cancel are small text links. The box says "Message will
  send when the agent is free".

### Fixed

- **chat:** a reply now shows the moment it is written. Claude Code writes a
  reply's thinking first and its words on a later line of the same message;
  the daemon merged those words into the stored turn without telling the live
  feed, so a chat showed the turn's cost and no answer until it was opened
  again. Measured on a preview daemon: never within 30 s before, 108 ms now.
  The merge is now an `event_update` frame, and the chat replaces the reply in
  place.
- **chat:** a chat says when its agent is at work: *Claude is thinking…* with
  a clock from your message, the call it runs (*Running npm test*, *Reading
  main.go*), or *Waiting for your permission* with the Yes / No card under
  the conversation, on the desktop, in the app's chat tab and on the phone.
  A quick chat runs in the default permission mode, so a web fetch or a
  command could stall it on a prompt the chat never showed.
- **chat:** what you send shows at once as your bubble, *Sending…* then
  *Sent ✓*, until the session's own record of it arrives; one the daemon
  refused reads *Not sent* with Retry. Before, nothing showed until the
  transcript caught up, so a message to a busy session looked lost.
- **chat:** text you pasted shows as a quiet *Pasted · N lines* block, folded
  past six lines, instead of Claude Code's raw `<pasted_content>` tags; a
  `<system-reminder>` inside a prompt is left out.
- **codex:** a reply no longer shows its text twice when the import was interrupted between saving the turn and saving its words; the import is retried on the next tick, and turns already doubled are corrected the next time their session file is read in full.
- **ui:** AI;DR on a phone reached through access from anywhere no longer
  answers 403. The relay drops the browser's Origin and fetch metadata, and
  the tap sent no Content-Type to stand in for them; it now sends an empty
  JSON body. A 403 on AI;DR says in words that Caprock refused it.
- **web app:** Keep the phone Home and the permission card inside the screen: a long path, tool name or "always" answer in a waiting prompt no longer widens the page, so cards keep their right margin and the header spans the full width.
- **ui:** a dictated message is never silently lost on the phone. When the
  speech service ends by itself mid-recording (Chrome on Android does after a
  pause), Caprock listens again and keeps every word; interim words with no
  final are sent rather than wiped; a later, emptier result never erases
  what is in the field; Send while listening waits for the last words. A
  pointer cancel keeps recording instead of dropping it, and sliding off the
  mic sends nothing but leaves the words in the field. A message the daemon
  does not take becomes a draft with Retry, a message on its way when the
  tab is discarded comes back as a draft, and the field's text survives a
  discarded tab.
- **ui:** the dictation language can be changed from the phone's + sheet,
  which was the only way on a chat's screen (it was stuck on the phone's own
  language there), and the recording line names the language it listens in.
  Speech recognition still hears one language per recording: the browser's
  API cannot detect a second one, and Caprock has no transcription of its own.

## [0.135.0] - 2026-10-18

### Added

- **mcp:** let your coding agents ask Caprock what earlier sessions learned.
  `caprock mcp` is a free, read-only MCP server on stdio: eleven tools for
  Second Brain, handoff, session history and prose, costs, CI and loop alerts.
  Settings → Use Caprock from your agents (MCP) has the commands for Claude
  Code and Codex, including the full binary path for desktop-only installs.
  Answers enter your agent's conversation and reach its model; credential-shaped
  text is redacted. No tool starts, stops or types into sessions or changes settings.
- **brain:** import an Obsidian vault into Second Brain. Markdown notes,
  links, aliases and tags join the graph, with their vault and source files
  marked; the original files stay unchanged. Saved vaults refresh every ten
  minutes while Caprock runs, and can be refreshed or removed from the import
  sheet. Letting agents use the notes is a separate switch per vault, off by
  default, covering memory handoffs, MCP reads and model topic lists.
- **Mail:** clean Spam into Trash and permanently clean Trash by message age or local spam score, with a count and confirmation scoped to the selected account or all accounts.

### Changed

- **Resources:** Larger text, shorter explanations and clearer memory and disk figures make the Caprock doctor easier to read.
- **Second Brain:** give the graph more room with a collapsible details panel,
  clearer connections, a more open layout, zoom buttons and controls for node
  size, link visibility and label density.
- **agents:** Restore Codex's original glyph and terminal character; show ChatGPT imports with OpenAI's Blossom instead of a generic chat bubble.
- **perf(api):** the all-time history behind the Now screen and History is no
  longer counted again on every poll while agents work. It is refreshed at
  most once per 20 times what counting it took (never past 2 minutes), and
  its totals reuse the summary's scans instead of making them twice. Today's
  figures keep their 3-second refresh. Measured 2026-10-18 on an M1 Pro under
  a synthetic working load (four Claude and two Codex sessions writing, hooks,
  two dashboard pages): on an 890,000-event history the daemon went from 40%
  of one core to 11% and the history refresh's allocation from 2,839 MB to
  182 MB per 150 s; on a 181,000-event history the refresh's own CPU fell 40%
  and the daemon's total stayed within noise.
- **perf(api):** the sessions list no longer re-reads every listed session's
  recent events on every request. Each session's reads are kept until its
  events change: an insert raises its newest event id, and new database
  triggers count updates and deletes (migration 0063). Narration, stats, live
  subagents and the clock are still worked out on every request. Measured
  2026-10-18 on an M1 Pro under a synthetic working load (181,000-event
  history, four Claude and two Codex sessions writing, hooks, two dashboard
  pages): the list's allocation per request fell from 0.85–0.87 MB to
  0.35–0.36 MB and its CPU per request from 1.8–3.2 ms to 0.8–1.1 ms. The
  daemon went from 13–15% of one core to 11–12%. The cache holds about 9 MB
  for at most 256 sessions.
- **pipeline:** the Flow row is three cards instead of ten equal tiles: Now
  (All clear, or the most urgent count with the other two beside it, each
  still a filter of the list), Speed (throughput, with CI, opened to merged
  and merged to released as one line) and Agents (the cost, the cost per
  agent-hour and the team now, which still opens the team chart). A
  sparkline is drawn only where there is history, and what is missing is
  said once under the row. The cards stack on a narrow window.
- **ui:** the release plan in the session's right panel reads in plain words.
  Sections say what they hold, with a one-line hint ("Branches pushed, no PR
  yet", "Will go into the next batch PR"); a branch row says "3 commits ·
  pushed 2h ago" with its branch name under the subject and a "branch" chip
  instead of a lone bar; a subagent row reads "Agent: <task>" with "working
  12m".

### Fixed

- **web app:** Show projects and their sessions near the top of Home on phones and tablets, including saved projects with no sessions.
- **navigation:** Keep the open session address intact when a tablet switches to the phone layout.
- **chat:** a photo attached in the chat — the phone's Photo above all — no
  longer puts its full saved path in the field. It shows as an *Image 1*,
  *Image 2* chip with a thumbnail and an × over the field, and your words stay
  your own. On Send each photo is pasted into the session first, as the
  desktop terminal pastes a dropped image, so Claude Code shows `[Image #1]`,
  then the words follow; before, the path went in as text inside the message.
  A message held while offline keeps its photos.

## [0.134.0] - 2026-10-18

### Changed

- **termbuf:** terminal output no longer allocates as it scrolls through the
  256 KiB scrollback ring, in the daemon and in the pty-host alike: the ring
  is one fixed array written in a circle, and the wake-up channel is made only
  when a terminal is waiting. Measured 2026-10-18 on an M1 Pro under load
  (`BenchmarkRingWrite`, full ring, nobody waiting): a 1 KiB write went from
  5153 B and 1 allocation to none, a 16 KiB write from 77,938 B and 1
  allocation to none.
- **codex:** a live Codex session's transcript is read from where the last
  poll stopped, and only what the new lines added is offered to the database,
  instead of parsing the whole file and offering every record again on each
  append. Measured 2026-10-18 on a synthetic 16,384-record transcript (Apple
  M1 Pro under load): one poll after a one-record append went from about
  201 MB allocated and 1.2 million allocations to about 150 KB and 300.
  A restart, a rewritten file and a compressed rollout are still read in full
  once.
- **docs:** document the resource-usage audit, synthetic allocation measurements and prioritized optimization proposals.

### Fixed

- **ingest:** a Claude Code transcript record longer than the 16 MiB line limit
  is now skipped while it is read, in fragments, instead of being read whole
  first: one read of a 32 MiB record allocated 67 MB before and 17 MB after,
  and the same 17 MB for a 64 MiB one. A complete record over the limit is
  skipped too (before, only an unfinished one was), counted once as a
  malformed line, and the line after it is read. Skipping an unfinished one no
  longer leaves the offset inside it, which made the next read start the whole
  transcript over.

## [0.133.0] - 2026-10-18

### Added

- **app:** the status strip carries *Premium*, the header's way to buy, which
  a terminal in front hides; and, while a plan window is 70% spent, *pause
  before the limit*, which opens Premium on the plan-window stop. Neither
  shows to someone who has Premium.
- **modules:** each private module's sidebar row shows a key, ⌥⌘1 to ⌥⌘9
  (Ctrl+Alt+Shift+1–9 on Windows and Linux), that opens it from anywhere in
  the app. The keys exist only while a module is installed.
- **machines:** your other computers in the app (ADR-067). The sidebar lists
  each linked computer and the sessions running there, tagged by its name,
  and opens one with its Session view and terminal as on that computer's own
  screen, through this Caprock. Settings → Computers adds one by the link it
  shows, renames, forgets and checks them, says when one is offline, waiting
  for Allow, removed there or refused, lists the steps for the other computer
  (install, `caprock remote on`, `caprock pair --computer`), and shows a link
  for another computer to reach this one. With none linked, one quiet
  *+ Add a machine* row in the sidebar.
- **resources:** `GET /v1/resources` reports the machine as a whole —
  cores, one-minute load (not on Windows), total and available memory.
- **bench:** `bench/peer.mjs` measures keystroke-to-echo through a linked
  computer against the same session typed into locally.
- **mail:** removing an account signed in with Google now also revokes
  Caprock's access at Google, not only the token on this machine; for a
  Microsoft account, which offers apps no way to do that, the confirmation
  says where to remove the access. `docs/mail-oauth.md` gains the owner's
  setup checklist and a step-by-step test on a real Gmail and Outlook account,
  and the Go tests walk a whole account's life against a fake provider and
  fake mail servers: sign in, sync, read, send after the access token
  expired, remove.
- **projects:** put several repositories in one project without a folder
  around them. In New project, *Put several repositories in one project*
  turns the folder list into checkboxes: tick repositories in one folder or
  several, *2 selected · Continue*, name it, done. Nothing is made on disk:
  the first one ticked is the project's home repository, where agents start,
  and they reach the others. A project's menu has *Add a repository…* for
  later, New agent asks which repository to start in, each session in the
  sidebar names its repository, and the CI/CD section lists every
  repository of the project.
- **doctor:** the orphan list now covers Codex CLIs whose session ended or
  whose parent exited, and terminals still running from an older Caprock
  install (a Homebrew `caprock pty-host` left from before a move to the app),
  shown but never ticked in Clean up. Each process shows its CPU and its
  command line, cut short with tokens and passwords hidden. The status bar
  says *3 orphans* and the doctor *Orphans: 3 · 410 MB*; `caprock doctor`
  prints the same.
- **release:** the right panel's Release section now shows what heads into
  the next release beyond merged pull requests: pushed branches with no pull
  request yet (ahead of the default branch, from the last 14 days, titled by
  their last commit, with their commits ahead and age; ones whose work is
  already on the default branch by content, as after a squash or batch
  merge, are left out) and the session's working subagents (*working ·
  12m*). The rows stand in sections with counts: *In this release*, *Pull
  requests*, *Ready* (branches) and *In progress* (agents).
- **ui:** Settings has a search field at the top of its menu (above the
  sections on a narrow window). Typing filters the sections live by title and
  by every label, hint and button inside them, understands common words
  (*token* finds Telegram, *dark* Appearance, *phone* Use on your phone,
  *shortcut* Global shortcut) and marks the matches; Enter or a click jumps to
  the matching control and lights it. Esc clears; ⌘F (Ctrl+Shift+F, or
  Ctrl+F, on Windows and Linux) puts the cursor in it while Settings is in
  front.

### Changed

- **app:** closing a working agent's tab asks in one short line, and the two
  choices carry a few words each; *Keep it running* is drawn filled as the
  recommended one, *Stop it* outlined.
- **ui:** Codex is shown by OpenAI's own mark, the Blossom, everywhere it
  appears — sidebar rows, tabs, Projects, the pulse, Now cards, the tray, At a
  glance, Second Brain, the Week and share cards. Where the other agents have
  characters, Codex is the Blossom on a plain white tile instead of the drawn
  terminal box. Per OpenAI's brand guidelines it is used unchanged, in black
  or white only, with no face or other additions.
- **ui:** the ⇧⌘-click link chooser (Ctrl+Shift+click off macOS) now offers
  two choices: *Default browser*, named by the browser it is, and *Caprock
  browser*, always in the desktop app. Picking *Caprock browser* while the
  in-app browser is off turns it on, and a toast says where to turn it off.
  *Copy link* follows. Other browsers wait behind a quiet *Other browser…*,
  which lists real web browsers only: apps that merely handle web links,
  such as a chat app, a terminal or a bank's secure-browser wrapper, are
  no longer offered. The hover hint now reads *⇧⌘-click to choose where it
  opens*.
- **doctor:** stopping a listed process sends SIGTERM and then reports
  whether it is still running, instead of following up with SIGKILL on its
  own. A process that ignores the request gets **Force stop** in the panel,
  or `caprock doctor --stop <pid> --force`, as a second, separate choice.
- **settings:** Settings → Use on your phone is rebuilt plain. It opens with
  one sentence that says whether a phone is connected — *iPhone · Safari is
  connected and can control sessions · seen 2 min ago*, or *No phone
  connected yet.* — with the one fix beside it when something is in the way.
  One button, **Connect a phone**, shows the QR with one line (*Scan with
  your phone's camera. Works once, 4:43 left.*). The four-step checklist is
  gone; how it works, the home-screen link, the way back to the page and the
  off switch are folded under **How it works**. Each device is one row: its
  name, *Can control* or *View only*, when it was last seen, **Allow
  control** or **Take control away**, and **Remove**. Devices not seen for
  30 days fold into *N old devices* with **Remove all**, confirmed once. The
  phone's own pages now point to *Connect a phone* and *Allow control*.
- **app:** the quick replies under a terminal say what they are: *Reply to
  the agent:* leads the row, and each one's hover names the message it sends.
- **ui:** setting up or changing the Telegram bot is one card with three
  numbered steps that tick as they are done — copy the token in @BotFather,
  paste it here (a **Paste** button reads the clipboard), send your bot the
  code with **Open @yourbot**. Connected, it is one line, *Connected to @bot ·
  alerts to <chat>*, with real **Change bot**, **Pair again** and
  **Disconnect** buttons; where the token is kept moved behind the **i**. A
  refused token brings the same card back in red.

### Fixed

- **terminal:** The wheel scrolls Codex again. A terminal opened, reloaded or
  reconnected after Codex's startup had scrolled out of the daemon's 256 KB
  output buffer came back on the normal screen with the mouse off, so the
  wheel never reached Codex. The replay now restores the alternate screen and
  mouse reporting along with the other modes the session set.
- **pipeline:** in a repository that cuts no releases (none published and no
  version tag in 180 days, such as a site deployed on every merge), merged is
  now the last step: the CI block's and the Pipeline's bars end at merged and
  fill, and the release plan says *No releases here: work ships when it
  merges* instead of listing every merge as waiting for a release that never
  comes. Where releases are cut, the empty released step says what it means
  and what a merge waits for (*the next release (v0.133.0)*, *in v0.132.0*);
  where it cannot be read, the step is drawn as not known.
- **subscriptions:** a session started on an added Claude Code or Codex
  subscription now runs on that subscription's own sign-in even when your
  shell exports `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`,
  `CODEX_API_KEY` or another credential the agent would otherwise use
  first. Settings → Subscriptions names any such variable it sets aside,
  and sessions on your own sign-in keep them. Removing a subscription now
  names the macOS Keychain item its sign-in is kept in and offers **Sign out
  first**, which types the agent's own sign-out into a shell tab for you to
  run. Caprock still never touches the Keychain.
- **ui:** the Settings menu draws an icon for *Closing a tab*, gives
  Telegram's chat its own icon beside the bot's, and shows a tooltip only on
  a title it cuts, so it no longer covers the row above.
- **ui:** when Telegram refuses the bot's token (*Unauthorized*), Settings →
  Telegram says so in a large box with the two steps to fix it — copy the
  token from @BotFather, paste it under Change bot — and opens the bot fields.

## [0.132.0] - 2026-10-17

### Added

- **ui:** an agent's "update available" notice in a terminal gets a small bar
  near the bottom of that terminal — *Codex 0.162.0 available · Copy command ·
  Open a terminal · ×*. Copy puts the printed command on the clipboard, joined
  back across wrapped lines and without the "Run … to update." words; Open a
  terminal opens a plain shell tab in the session's folder and types nothing
  into it; × hides it for that agent and version. Caprock never runs the
  command. Codex's banner and Claude Code's update notices are recognised.
- **now:** At a glance shows which way each share is moving. Every legend
  row, Numbers table row and agent carries a small marker, the change in its
  share between the last 7 days and the 7 before (`↑ 9`, `↓ 4`, `·` under a
  point), and its hover says both shares in words. When a model's share of
  spend moved five points or more, one sentence under Where the money went
  says so. Measured shares only, no projection; `GET /v1/glance` gained
  `trend`.

### Fixed

- **queue:** a message Caprock types into a session it started is sent, not
  left sitting in the prompt. *Tell the agent* on a loop alert could leave
  its text typed into a Codex session's composer, unsent, because the agent
  read the Enter as part of the fast run of text before it. The text now
  goes as a bracketed paste wherever the session turned paste on (Claude
  Code and Codex both do), the Enter follows on its own after a pause that
  grows with the message, and 1.5 s later Caprock reads the screen and
  presses Enter once more if the prompt still holds the text — never into a
  menu, and not once the turn has started. The same path serves the chat
  field, the phone, a delivery at the end of a turn, Send now and Telegram
  replies. The loop card now says *Sent to the agent* or *Will send when it
  finishes this turn*; Dismiss never sends.

## [0.131.0] - 2026-10-17

### Added

- **modules:** a slot for private modules (ADR-076). A signed admin key
  pasted into Settings → License names the modules this machine may run;
  `caprock module install <dir>` copies one in from a local folder; each
  installed module gets a sidebar screen in the app's theme and a small JSON
  document store. Without a key nothing of it is shown.

## [0.130.0] - 2026-10-17

### Added

- **brain:** the Second Brain graph card unfolds into the graph: the dialog
  opens out of the card's rectangle with the card's picture growing into
  it, and folds back into the card on close (a full-screen sheet on a
  phone; a cut under reduced motion). The graph is coloured by project with
  the projects and the busiest topics named, *Find in the graph* and a
  project picker pick nodes out without laying it out again, and a panel
  beside it says what the hovered or opened node holds — a project's or a
  topic's memory count, its latest memories, the sessions they came from
  and *Open* — else the whole graph's counts, its projects and its newest
  memories.
- **brain:** thoughts arriving: a memory just kept flies as a spark from
  its session's sidebar row or tab into the sidebar's Second Brain card,
  which pulses, and lands in its project's cluster when the graph is drawn.
  Throttled, never under reduced motion, and off with Settings → Second
  Brain, *Animate thoughts arriving*. The live `brain` frame of an added
  memory now carries its `session` and `project`.
- **app:** the link chooser (⇧⌘-click a terminal link) lists *Open in
  Caprock* after the browsers while the in-app browser (beta) is on.
- **app:** the in-app browser is back as a beta, off until you turn it on
  (Settings → In-app browser). *New browser tab* (File menu, ⌘K, the +
  menu) opens a tab after your agents with the cursor in its address box;
  plain words search DuckDuckGo, or the engine you pick. A page stays
  exactly where it was while you work elsewhere, a link that opens a new
  window opens another tab, ⌥← ⌥→ (Ctrl+PageUp/PageDown on Windows and
  Linux) step between tabs, and when an agent starts waiting on you a strip
  names it and a playing video pauses. ⌘-click still opens your default
  browser. Each page now runs in a window of its own rather than inside
  Caprock's window, which is what crashed the app on macOS 27 and lost
  drops in 0.124.0; a page is never closed while it is busy.
- **ui:** the highlight where you type can be switched off, or made stronger.
  Settings → Terminal → *Highlight where you type* covers both the faint band
  on Claude Code's input box and the chat field's accent tint, with *Subtle*
  or *Stronger*. ⌥⌘G (Ctrl+Alt+Shift+G on Windows and Linux) flips it in
  every open terminal at once and remembers it; ⌘K has *Toggle input
  highlight*, and pointing at the input box shows the key on its top edge.
- **ui:** a release plan row opens its session in one click, as a *Waiting
  for you* row does: an agent's row (in the next release or not in one yet)
  is itself the button, and a pull request's row with an agent on it gets a
  small *Open session* button after its title. In the app it opens the
  session's tab, in a browser its terminal or timeline, and on the phone an
  agent's row opens its chat.

### Changed

- **ui:** the release plan says itself in plain words: *Nothing new since
  v0.129.0, released 9m ago* or *3 changes waiting for the next release ·
  last release v0.129.0, 9m ago*, with the usual gap on hover only; idle
  agents sit under *Not in a release yet · agents waiting for you, idle 30+
  min*; an agent's row with no pull request says *no PR yet*, and every bar
  segment names the steps in order on hover.

### Fixed

- **ui:** the session panel's Changes section stays inside the panel: a long
  file path no longer pushes the counts, the bar and Review and commit past
  its right edge.
- **ui:** the "New" tag on the active top tab (Second Brain) is readable: on
  the accent fill it takes the label's own ink on a chip instead of faint grey.

## [0.129.0] - 2026-10-17

### Added

- **chats:** import your Claude.ai and ChatGPT conversations into Chats. Ask
  the service for your data (Claude.ai: Settings → Privacy → Export data;
  ChatGPT: Settings → Data controls → Export data), then choose the .zip it
  emails you under *Import from Claude.ai or ChatGPT…* on the Chats screen.
  Each conversation becomes a read-only chat marked with its service,
  searchable, archivable and deletable, and readable from a paired phone.
  The file is read on your computer and nothing is sent anywhere. Importing
  a newer export adds only what is new, and a chat you deleted stays
  deleted. Neither service offers a way for another program to read your
  history, so this is an import from the export, not a live sync (ADR-074).
- **app:** choose the browser a terminal link opens in. ⌘-click (Ctrl+click
  on Windows and Linux) still opens the default browser; ⇧⌘-click
  (Ctrl+Shift+click) opens a small chooser at the pointer with the browsers
  installed on this machine, the default first, and *Copy link*. Arrows move,
  Enter picks, Esc closes. The link's hover hint names both clicks, and both
  are in the shortcuts list. The daemon finds the browsers from what the OS
  says handles web links (LaunchServices on macOS, the registry on Windows,
  desktop entries on Linux) and answers only this machine
  (`GET /v1/browsers`, `POST /v1/browsers/open`).
- **ui:** each repository in the CI/CD section has its own *Hide* button beside
  *active 10d ago*, with an *Undo* in its place for ten seconds, and the
  section's last line says *N hidden · Show* to list them and bring them back,
  one at a time or all at once. The ⋯ menu that held the only Hide is gone.
- **ui:** a row of the Repos section opens under itself (its chevron, or
  *More* for every row): the branch checked out, the newest CI run with its
  result, open and merged pull requests, red runs, the release, the lines of 7
  days, the folder, and git's own error in full when it could not be read.

### Changed

- **app:** closing the tab of an agent that is still working asks with two
  equal buttons, each with a line saying what it does: **Keep it running**
  (only the tab closes; in focus, so ⌘W then Enter still keeps it) and
  **Stop it** (it stops now; continue it later from History or the
  sidebar). Stopping was a quiet link under one button before. Escape
  still cancels.

### Fixed

- **projects:** the Repos section no longer says "git could not be read" for a
  busy repository. Its one `git log --all --shortstat` over 14 days took 12 s
  on a checkout with 961 refs and 1,048 recent commits (measured 2026-10-17),
  past the 5 s git timeout, and the failure was kept for 10 minutes. Commits are
  now listed without diffs, which stays fast, and each commit's lines are
  counted once, kept, and diffed in batches under their own budget; when it
  runs out the row keeps its commits, marks the lines `…` and goes on counting
  a minute later.

## [0.128.1] - 2026-10-17

### Fixed

- **release:** 0.128.0 was tagged but never published: a phone Releases test
  read the "read N ago" line before the stats answer had drawn it, and failed
  the release run. The test now waits for the line; 0.128.1 carries 0.128.0.

## [0.128.0] - 2026-10-17

### Added

- **api:** AI;DR: `POST /v1/events/{id}/tldr` squeezes one agent answer into
  at most two short sentences, in the answer's own language, by a separate
  call to your own `claude` (Second Brain's headless runner, Haiku, no
  session written), only when you tap it. Never typed into the session. The
  result is kept, so a second tap makes no call; an answer under 280
  characters is its own TL;DR. A paired controller phone may use it
  (ADR-072).
- **ui:** Halloween pumpkins for Claude's portrait: eight of them (a
  jack-o'-lantern, a witch, a vampire, a ghost, a black cat, a mummy, a
  monster and a lantern) on a new *Pumpkins* tab of the face menu, and
  *A pumpkin per session* in Settings → Appearance. Nobody's current face
  changes.
  Through October the quiet *try a duck?* line beside an idle portrait
  says *try a pumpkin?* instead and opens the pumpkins.
- **support:** Report a bug, from the phone bar's + menu and ⌘K *Report a
  bug…*: type or dictate what happened, attach up to three screenshots (made
  small on the device), add an email if you want a reply, and press Send to
  support. It goes privately to Caprock support at caprock.dev, never to
  GitHub, and only on that click; the sheet lists exactly what is sent — your
  text, the screenshots, the email if given, the Caprock version and the OS
  (ADR-073).

### Changed

- **phone:** the chat's bottom bar is one row: a speaker switch that reads
  new answers aloud (on by default, remembered per device), a + menu with
  Photo, New chat and Report a bug, a one-line field that Enter sends, and a
  round hold-to-talk microphone — hold to speak and release to send, tap to
  start and tap again to send, slide off to cancel. The latest answer carries
  AI;DR (a two-line summary from your machine), Read aloud, Continue and
  Stop. Esc, Tab, the arrows, Enter, Ctrl+C and the dictation language moved
  to the session's ··· menu. The desktop chat is unchanged.

## [0.127.0] - 2026-10-16

### Added

- **ui:** Halloween pumpkins for Claude's portrait: eight of them (a
  jack-o'-lantern, a witch, a vampire, a ghost, a black cat, a mummy, a
  monster and a lantern) on a new *Pumpkins* tab of the face menu, and
  *A pumpkin per session* in Settings → Appearance. Nobody's current face
  changes.
  Through October the quiet *try a duck?* line beside an idle portrait
  says *try a pumpkin?* instead and opens the pumpkins.
- **ui:** the Pipeline's *Next release* panel says where the release itself
  is: the next version's bump and why (*minor · a feature since …*,
  *patch · fixes only*), then its stages as the pull request rows' pills —
  merged → release PR → CI → tag → builds → published → site — the current
  one filled, done ones ticked, and any stage Caprock cannot read (the
  site's deploy) left neutral with a *?* rather than guessed. A tag already
  pushed and still building shows above as *releasing*, its builds counted
  as files on the release against the release before it. Under the rows,
  one line for the last release: when, how many files, and a link.
- **github:** the releases the board lists carry their uploaded file count
  (`assets`), from the same request.

### Changed

- **phone:** a session or chat can be ended from wherever the phone lists it,
  not only from inside it (owner: trial chats could not be ended). Each live
  row Caprock started — the home's Chats and Continue, All sessions, the Chats
  screen — has *End session…* in its ⋯ (a swipe left opens it too), one
  confirm, then the polite stop that keeps the conversation; the row then
  reads *ended*, and an ended chat stays in Chats to be continued. A chat's
  own ⋯ has *End this chat…* first. Where End is not offered the row and the
  session's sheet say why in one line: a session started in your own terminal
  is never stopped by Caprock, and a phone that can only watch is told where
  to allow control (Settings → Use on your phone → Let it control sessions).

### Fixed

- **ui:** the version panel can check again right after a check. When you are
  on the latest version and the last check is recent, the "Checked 4m ago"
  line carries a *Check again* link beside the What's new button.

## [0.126.0] - 2026-10-16

### Added

- **chats:** Chats are their own kind of session. Start one in one tap on the
  phone home, the new Chats screen, or ⌥⌘N in the app, on the model you used
  last (a compact model chip changes it). Chats are listed apart from your
  projects, newest first, with search, rename, archive and delete, and a count;
  a chat reads as a conversation, never a terminal, and can be continued after
  it ends. The files a chat writes open in a viewer — Markdown rendered, HTML
  sandboxed with no scripts, PDF in the browser's viewer, images — and can be
  downloaded, on a phone too. A paired phone that may control can now start,
  continue, archive and delete chats. *Quick chat with…* keeps the model
  chooser (ADR-071).

### Changed

- **app:** ⌘W closes the tab in front, not the window. The macOS menu's
  Close Window held ⌘W, so the key hid the whole window; File → Close Tab
  holds it now and closes the tab as its × does, asking first about a
  running agent or shell. With the Dashboard in front it does nothing;
  Window → Close Window (no key), the red button, ⌘H and ⌘M still put the
  window away, and in the Mail window ⌘W still closes it. Windows and Linux
  keep Ctrl+Shift+W, since Ctrl+W is the shell's delete-word.
- **app:** the Premium dialog's *Also in Premium* chips are bigger, so the row is seen at first glance.
- **app:** the version panel says *You're on the latest version* in a sentence and shows one button — what's new right after a check, Check now otherwise.
- **app:** a *Waiting for you* row on Home is one big way back into that
  session: a click anywhere on it, Enter, or its amber *Open terminal →* opens
  the session's tab in the desktop app (opening one if needed), or its
  terminal in a browser. *what did it ask?* still opens the answer in place,
  and the row now names the session after the project, so two waiting rows in
  one project say which is which.

## [0.125.0] - 2026-10-16

### Added

- **docs:** `docs/install-agent.md` says what the install does, where it lives and how to remove it; the agent install prompt is now five lines, runs the same script as the site, and leaves Claude Code's settings to the app.
- **ci:** `make e2e` drives the app's golden paths in Playwright's own
  headless shell against a sandboxed daemon (temp home and data directory, a
  free port, the fake `claude`): the workspace loads with no console errors,
  sessions open as tabs with a sidebar row in Tree and Flat, typing, paste and
  a native file drop reach the terminal, and the palette, Settings, Second
  Brain, Pipeline and the share dialog open. `make pr-check` runs it when
  `ui/` or `internal/api/` changed, and CI runs it on Ubuntu. The app's own
  tests now check that a drop is heard as both the window's and the
  webview's event, through one handler (the 0.123.0 bug).
- **mail:** AI sorts the inbox. With AI on, Mail labels your newest 200
  conversations, then new mail as it arrives, as Important, Updates,
  Newsletters or Spam, with a one-line summary in place of the snippet and
  a *Reply* mark on mail that waits on your answer. Filters along the top
  of the inbox — `1` All (everything but spam), `2` Important, `3` Updates,
  `4` Newsletters, `5` Spam with its count. Nothing moves on the server by
  itself: `!` sends a conversation to Junk, `n` says it is not spam, and
  Mail remembers that for the sender too. While it works the list says
  *Sorting 37 conversations…*; with AI off one line offers *Let AI sort
  your inbox — Turn on* and says where the text goes. Sorting uses the
  provider you picked in Mail's settings, a batch of conversations per
  call, in the background. The sample inbox shows the labels without any
  AI call.
- **mail:** Who does the AI work is named wherever it acts — under the
  inbox filters, under every summary and on the composer's AI bar — with
  *change* opening Settings at the AI section, and the reader shows a
  conversation's stored one-liner at once. A new *Language* setting
  (same as the email, English, Russian, Spanish, German) sets what
  summaries are written in; a drafted reply keeps the language of the mail
  it answers.
- **mail:** junk stays out of the Inbox, even when your mail provider
  leaves it there (owner request, translated: "there's a lot of spam in my
  inbox — every mail client filters this"). Caprock's own filter runs on the
  machine, with no AI and nothing sent anywhere, and is on from the start. It
  reads what the receiving server wrote into each message — SPF, DKIM and
  DMARC results and the server's own spam verdict — plus a few cheap checks
  (a brand name on an unrelated domain, replies sent to a free mail address,
  URL shorteners, image-only mail), and a small learning classifier taught by
  your Spam folder and by every *Spam* (`!`) and *Not spam* (`n`, new) you
  press. Anyone you have written to, or said *Not spam* for, is never junk.
  Hidden mail is listed under *Caprock thinks these are junk* in Spam
  (`g !`), whose count the sidebar shows, and the reader says why; nothing is
  moved or deleted on the server unless you press Spam yourself.
- **mail:** with AI sorting on, Spam is one list and one count whoever
  found it: the inbox's Spam filter (`5`) and the Spam folder view show the
  junk filter's catch first, then the AI's, each with a single *Spam* label,
  and `n` clears both at once — the filter learns, the AI's label is taken
  back, and the sender is never spam again. Mail the filter caught is never
  sent to the AI.
- **mail:** Mail from the keyboard, with the key on every action. Each
  button shows its key as a small chip — `e` archive, `#` delete, `v` move
  (a numbered folder list), `s` star, `u` unread, `i` summarise, `r`/`a`/`f`
  reply, reply all, forward, `c` compose — the folders show `g i`, `g u`,
  `g s` and the rest, `/` search, `,` settings, `g r` check mail, and `?`
  lists every shortcut. `t` opens the theme list: `j`/`k` show each palette
  at once, Enter keeps it, Esc goes back, a digit picks — Sunlight outside,
  Dark Pastel at night. *Summarise* is there even with AI off: the first
  press says which provider would answer and where the mail goes, and
  *Turn on and summarise* switches it on. In the composer ⌘↩ sends and ⌘J
  drafts the reply with AI.

### Changed

- **app:** feedback is one box: type what's wrong, drop or paste a
  screenshot anywhere on it, and press Send (⌘↩, Ctrl+Enter off macOS). The
  first line becomes the issue's title. Bug / Idea / Question, the
  diagnostics, *Choose image…* and *Capture window* are under *Details*;
  nothing else is required. What you typed is kept until it is sent, so Esc
  loses nothing. Send still opens a prefilled GitHub issue in your browser
  for you to submit; Caprock sends nothing itself.
- **pipeline:** The *Next release* plan uses its width. Its bar grows with
  the panel, one taller segment per step (agent, PR, CI, merged, released),
  each named on hover, and the step under way breathes softly. Beside the
  stage word, as the width allows, each row says what it waits for now
  (*CI on Windows · 6m*, *needs a rebase*, *fix: go (windows-latest)*,
  *a release*), the agent cost recorded on it at API list price (*—* where
  no session was), a dot per OS its checks ran on, how long its CI took
  against the usual (*14m +27%*, *6m / ~11m* while running), and how long
  ago it was opened. In a narrow panel these columns drop first, and the plan never
  scrolls sideways. On the phone each row also says what it waits for.
- **brain:** Second Brain leads with what it is for. One status line on top
  (*Up to date · 278 memories · 137 new today · 91 topics · $0.15 in 24 h*,
  or the stage and N of M over the progress bar while it builds) replaces
  the three step blocks and six tiles, with the rest under *Details*. The
  middle is **What your next session gets** — pick a repository and see the
  up-to-five memories a new session there is handed, in order, and whether
  one opening now would get them — then **Recent memories** with search, a
  project and a span. The graph is a small card on the side; a click opens
  it in a near-full-screen dialog to zoom, pan and explore (Esc, × or the
  backdrop close it). The *Graph* | *List* switch is gone. New read-only
  `GET /v1/brain/handoff?project=` names the memories with the same pick
  the handoff makes.
- **app:** every dashboard page says where you are and how to get back. Off
  Home the header reads *caprock / Pipeline* (the browser tab too:
  *Pipeline · caprock*), one item is highlighted — Settings included — and a
  *← Home* button returns to Home in the same tab. In the app the Pipeline and
  Mail tabs carry *← Dashboard*, which brings the Dashboard tab back. Links
  that leave Caprock are marked ↗ and say *Opens in a new tab* (or *Opens in
  your browser* in the app); links that stay inside use → instead. The
  version dialog's link to turn release checks on now opens Settings rather
  than falling through to Home.
- **app:** Mail opens in a window of its own, not as a tab inside Caprock's
  window with the sidebar beside it. In the desktop app the sidebar's *Mail*,
  ⇧⌘M and the palette's *Open Mail* launch or bring forward the Caprock Mail
  preview when it is installed (macOS, in Applications); without it they open
  a second Caprock window, *Caprock Mail*, with Mail alone, brought to the
  front when it is already open. In a browser the Mail tab stays, under a
  banner, *Mail works best in its own window*, whose button — or ⇧⌘M on the
  Mail tab — opens Mail alone in a browser window.
- **app:** the Premium dialog shows the whole plan, not only the feature you
  clicked. Its header counts the plan and states the yearly price ("Premium ·
  8 features · $30 a year"), and under the feature one row of chips names the
  other seven; a chip shows that feature in place, and the ones added in the
  last 30 days are marked New.

### Fixed

- **app:** the right panel's CI block lists only what is in flight: open pull
  requests, and the ones merged since the latest release. Released and
  closed ones are gone, so a repository that publishes no releases (a site
  that pushes straight to master) no longer fills the block with every merge.
  With nothing in flight it says so in one line, with the last release and how
  long ago it was, over the three newest merges. Ring and By OS are never
  blank: without the session deck's own PR they draw the newest pull request
  in flight, read its checks themselves, and say "Nothing in flight" when
  nothing is.
- **ui:** a freshly opened window no longer logs a 404 for
  `/v1/projects/dir:…/cleanup`: the finished-copies line waits for the
  daemon's own project list instead of asking about a project the window
  derived while that list was loading. Found by `make e2e`.
- **app:** a new release shows within minutes. The release check is due
  every 15 minutes (it was hourly, so a release could sit unannounced for
  most of an hour), and when you come back to the window Caprock checks
  again if the last check is ten minutes old. Never more than one check per
  ten minutes unless you ask; still one conditional request to GitHub, and
  only while Settings → Updates allows it.
- **app:** the answer to a check is at the bottom right, beside the
  version, where you look for it: *Checking for updates…*, *Caprock is up
  to date* for a few seconds, *Couldn't check for updates* with **Retry**,
  or **Update to vX — Restart** as an amber pill. The banner at the top
  centre is gone from the app.

## [0.124.1] - 2026-10-16

### Changed

- **brain:** the wheel scrolls the page past the Second Brain graph instead of
  zooming it. Click the graph (or press Enter on it) to zoom and move it; an
  accent ring shows it is in hand, and Escape, a click outside or the mouse
  leaving lets it go. A click on a dot still opens it, and Fit works either way.

### Removed

- **app:** the Page tab is gone for now: with it the app crashed on macOS 27 and drops went missing. ⌘-click opens a link in your browser again (ADR-070, withdrawn).

### Fixed

- **phone:** quick replies under a session's chat take the page's own surface
  in a light theme (Light, Light Cold, Book and the rest) instead of drawing as
  dark pills; under an agent's terminal in the app they still sit on the
  terminal's ground.
- **app:** a file dropped beside a terminal — on the tab strip, a margin, the composer — goes to the terminal you used last instead of vanishing, and a drop with nowhere to go says so.

## [0.124.0] - 2026-10-16

### Changed

- **app:** the sidebar's Today card has three states, kept per viewer: the
  full card, one line (`$33.79 · 11 running · 5h 6% · 7d 74%`, plus what
  waits when anything does) by its chevron, or hidden by the × that shows on
  hover. Right-click offers Full card, One line and Hide; Settings →
  Appearance → *Today card in the sidebar* brings it back. Its Share button
  is gone: sharing stays in ⌘K and on Pipeline.

### Fixed

- **app:** every tab in the strip has a row in the sidebar, in Projects and
  in Tabs view. A project or session hidden by hand and then opened again
  (from More…, a link or a restored workspace) had a ⌘N tab and no row; it
  is now listed while its tab is open, and goes back behind More… when the
  last tab closes. Hiding a project from its menu also closes its tabs.
- **ci:** a computer that removed this one is said so at once: a second check
  of a machine, asked while one is in flight, waits for its answer instead of
  returning the state from before it, so the proxy answers 403 "revoked" right
  after a revoke rather than passing the other computer's 401 on (the
  two-daemon smoke test's Windows failure). In New project from a template, a
  card clicked before the sheet had settled is the one chosen; the first card
  is chosen by default without an effect that could overwrite the click.
  `make pr-check` runs the whole UI suite when `ui/` changed, not only the
  changed test files.

## [0.123.1] - 2026-10-16

### Fixed

- **app:** a file dragged onto a terminal (a screenshot's thumbnail, a Finder file) types its path again; 0.123.0 heard no drop at all.

## [0.123.0] - 2026-10-16

### Added

- **app:** a Page tab — open a web page inside Caprock, apart from your
  agents. ⌘-click (Ctrl-click on Windows and Linux) a web link in an agent's
  terminal or chat, pick *Open a page…* in ⌘K or the + menu, or type an
  address such as `localhost:5173` into ⌘K. The page gets its own tab after
  every agent's, with a globe, back, forward, reload, an address field, copy
  and *Open in browser*; it takes no ⌘1–⌘9 and no sidebar row. In the
  desktop app it is the system's own web view with no access to Caprock and
  no cookies shared with it, loaded only when you ask, and freed after five
  minutes behind other tabs; in a browser, only a page on this machine opens
  in a tab and any other goes to the browser.

### Fixed

- **remote:** revoking a device closes its terminal opened through the relay
  at once, with "this device was removed". A keystroke arriving as the socket
  closed used to drop the stream without telling the other computer, and its
  terminal stayed open. After one failed write the stream now drops what is
  typed next at once instead of writing it into the closing socket.
- **daemon:** stopping the daemon waits for its background work (history
  backfills, pruning, Second Brain's loop, the projects list and any clone
  still running) before the database closes, instead of leaving it to read a
  closed database; a clone in progress is stopped rather than left writing.
- **ci:** `make pr-check`, the step before a pull request: the changed Go
  packages with `-race`, their changed tests three times, a Windows vet and
  test build, and the changed dashboard tests. Four flaky tests were fixed at
  the root.

## [0.122.0] - 2026-10-16

### Added

- **pipeline:** what an hour of agent work costs, and how big the agent
  team is. Two new figures end the Flow row for the picked repository.
  **Cost / agent-hour** is the last 24 hours' spend per active agent-hour,
  at API list price (an estimate). An agent-hour is the burn rate's own
  rule: one session's clock hour with five or more priced calls. The
  figure carries a 15-day line, *▲ 35% vs 14-day avg*, and tokens per hour
  and in all. **Agent team** shows the main sessions and subagents at work
  in the last ten minutes and today's peak. Its line counts distinct agents
  a day, captioned with the 14-day average and peak, with each day split
  by agent kind on hover. Pressed, it opens a 31-day stacked bar chart,
  like a contributors graph. Both are read from this machine's events by
  the new `GET /v1/pipeline/agents`. With too little history they say
  *not enough history*.
- **pipeline:** share the figures. A Share pill in the Pipeline's head draws
  the eight Flow figures, each with its 14-day line, as a 2x card in the
  screen's theme, with the dates and caprock.dev. Save it, copy it, post it
  to X or LinkedIn with words you can edit (the card goes on the clipboard
  to paste in), or send it to Telegram: To me through your own paired bot
  (`POST /v1/telegram/photo`, only on that click), or to someone else
  through Telegram's share link. The card and the words are anonymous by
  default ("a GitHub repo", aggregates only, no titles, branches, authors
  or paths); Show repo name is an opt-in for that one share and is never
  remembered. The dashboard's share sheet gained the same Post and
  Telegram actions.
- **machines:** one of your computers can work on another's sessions
  (ADR-067). On the computer to be reached, `caprock pair --computer`
  prints a link (turning access from anywhere on if it is off); on the
  other, `caprock machines add '<link>'` pairs with it through that
  computer's own relay, end to end encrypted. Nothing is let in until the
  first computer's owner allows it by name: a card on its screen, the
  prompt in the terminal that printed the link, or `caprock machines allow
  <name>` over SSH. An allowed computer can start agents in any folder, open
  shells and run tasks there, but never change that computer's settings,
  pairing, updates or the doctor's stop. `caprock machines revoke <name>`
  or Remove ends it at once, open terminals included, and `caprock machines
  forget <name>` on the other side drops it from both. On Linux both
  `caprock service install` and `caprock pair --computer` say when
  `loginctl enable-linger` is needed to stay reachable with nobody logged
  in.
- **phone:** the phone home shows your releases: per repository, the next
  version and a row per piece of work with its ten-block progress bar and
  stage word, the release plan the Pipeline and Work → Release draw. A row
  opens its pull request on GitHub; a chip switches repository. It reads on
  opening, on release news, on *Refresh* and on a pull at the top of the
  home-screen app — never on a timer. A paired phone may now read
  `GET /v1/sessions/{id}/ci/stats` (read-only), which the bars come from.
- **phone:** end the session you are in from its bar: a red *End* on a
  session Caprock started, one confirm sheet (*The conversation is saved
  and can be continued.*), then the polite stop: Claude Code is asked to
  exit and write its transcript out, and is killed only if it is still
  running a few seconds later, so the session can be resumed. Sessions started outside Caprock, and phones that may only
  read, see no End.
- **phone:** the session's bar stays at the top while Timeline, Changes or
  Answers scroll, over the notch, so the way back is always one tap away.
- **brain:** see Second Brain build. A header strip on its screen says the
  state (*Building · reading session 12 of 48* over a progress bar, *Up to
  date · last built 14:02*, *Paused*, *Stopped*, *Waiting* for today's
  limit), which step a read is at (find sessions, Claude extracts, link into
  the graph) with the session being read, what it gives (how many new
  sessions were handed its memories) and counted figures: memories, new
  today, topics, links, tokens and cost at API list price in the last 24
  hours. The folded sidebar card reads *Building · 12 of 48* over a thin
  bar while it builds. `GET /v1/brain/status` carries `stage`, the read's
  `phase` and these counts; migration 0058 records the memories each new
  session is handed.
- **hermes:** Caprock sees Hermes Agent. Its sessions, prompts, replies, tool
  calls, tokens and cost are read from Hermes's own database, read-only, and
  shown beside every other agent, with a `hermes` filter and Hermes's own
  glyph. Cost is Hermes's figure, never re-priced, and the Cost screen says
  which part the provider reported and which is Hermes's estimate. Cron jobs
  and gateway chats (Telegram, Slack…) are shown apart as background runs, by
  source. Delegated subagents sit inside the session that delegated them,
  counted once. **New agent → Hermes** starts `hermes chat` in a terminal tab
  and links it to its Hermes record; with no model set, `hermes model` is
  offered as your own step. See `docs/hermes.md`.
- **app:** Markdown reads comfortably in a file tab, and goes to another agent
  in one click. The document sits at a reading measure with a larger heading
  scale; code blocks have a Copy button, wide tables scroll on their own,
  task lists show real check boxes, headings take anchors that in-page links
  jump to, and a relative picture is read from the project through the
  daemon (one on the web stays its alt text, so nothing is fetched from
  outside the machine). Contents sit beside a long document on a wide window
  and in a dropdown on a narrow one, with a thin reading-progress line. The
  tab's header has a quiet toolbar: *Copy path*, *Copy for an agent*
  (`@/absolute/path`, which Claude Code, Codex and the others read as a file
  reference), *Copy Markdown*, *Download*, and *Send to a session*, which
  types that reference into a running agent Caprock started without sending
  it, then brings that agent forward for you to add your words. A `.md` path
  an agent prints in its chat or terminal now opens the file in a tab
  (⌘-click in the terminal, Ctrl+click elsewhere), and *Open file…* lists
  Markdown files first. Every "link" is a path on this machine; nothing is
  uploaded.

### Changed

- **ci:** a pull request no longer carries the built dashboard
  (`internal/api/dist`). Every two PRs that touched `ui/` used to conflict
  there, because the bundle's file names are content hashes; now a PR that
  changes it fails CI's *no dist in the PR* check (and `make check`) with
  the command that drops it (`make dist-reset`), and a new `dist` workflow
  rebuilds and commits it on `master` after each merge that touches `ui/`.
  `go install …@latest` still embeds the tag's dashboard: release `verify`
  and `make release-ready` check that the tagged commit's copy is its own
  `ui/` built, so a release is tagged after that rebuild lands (ADR-068).
- **brain:** the Second Brain graph looks like a knowledge graph: one round
  disc of small dots that fills the panel, with topics and projects as little
  bursts of their memories. Dots are in the text colour (dark in a light
  theme) with a faint tint for topics, edges are hairlines, and the one accent
  marks the node you hover or open. No names at rest: the hubs' names fade in
  as you zoom, then every memory's, and hovering names a node and its
  neighbours while the rest fades. It settles before it is shown and then
  stays still (no frames at rest); drag a dot and its neighbours follow,
  scroll or pinch to zoom, and *Fit* brings the whole disc back. The
  sidebar's turning brain uses the same small dots and hairlines.
- **pipeline:** the *In flight*, *Needs a fix* and *Ready* counts open the
  pull requests behind them. Hovering or focusing one lists up to five with
  why each is there (*CI red*, *Conflict*, *Changes requested*), and *Needs
  a fix* says how many the page saw fixed in the last 24 hours. A click
  filters the list to them across the whole repository, even from *This
  session*, with a *Needs a fix · 4 ×* chip to clear it, and scrolls to
  the list. A red pull request's CI pill names the failed checks on hover.
- **app:** "Caprock on this computer" (the popover behind *caprock 1.6 GB ·
  1.8 GB* in the status bar) says what is wrong in one line — *All good —
  Caprock uses 1.6 GB*, or *Caprock is using more than it should* with one
  **Clean up (frees ~X MB)**. Below it, one row per kind of problem in plain
  words, each with a line of why, its size and a small Stop: *Test copies of
  Caprock* (left by agent work in temporary folders and worktrees, not your
  app), *Leftover helpers* (servers finished agent sessions left running),
  *Disk reads* (normal or more than usual). Pids, paths and the long
  explanations moved under each row's *Details*; the memory and disk
  breakdown is behind *What the 1.6 GB is spent on*. Every stop shows the
  list first, one checkbox per process with the safe ones ticked, and stops
  nothing until you click *Stop*. The *Advanced* checkbox is gone.

### Fixed

- **remote:** turning access from anywhere on in the first moments after
  Caprock started could leave it connected but reporting itself off, so the
  pairing link came back empty until the next restart. The settings are now
  read once, under the same lock as the switch.
- **remote:** a request cancelled by the phone or another computer is no
  longer ended as if its answer were complete, so a cut-short answer is
  never read as whole.
- **app:** only the tab you are in looks selected (a user could not tell
  where she was: the tabs waiting on her wore the same accent bar along
  their top as the tab in front, so four tabs looked selected). The tab in
  front alone has the 3px accent edge, the panel's fill and a bold title,
  and room for about 16 characters of it — it read *ca…*; there its
  project's name gives way first. A tab waiting on you shows an amber dot
  before its title, pulsing slowly; one looping or failed a red dot. Never
  a bar.
- **app:** closing an agent's tab is one decision at most, and always says
  the conversation is saved. An idle agent Caprock started ends with its
  tab, no question, and a toast says *Closed. The conversation is saved —
  reopen it from History or the sidebar.* One still working or waiting gets
  one sentence, **Close tab** (it keeps working in the background) and a
  quiet *Stop it instead*; no checkbox. Settings → Closing a tab still
  makes it always keep or always stop. Ending now asks the agent to stop
  (SIGTERM, then a kill after 5 seconds) instead of killing it at once, so
  Claude Code writes its transcript out and the session can be continued
  with --resume; the agent-signal endpoint takes `end` for this.
- **tests:** the template sheet test reads the plan once the parent folder has loaded, so it no longer fails on a slow runner.
- **ui:** Live Pulse puts the hour's cost in one right-aligned column: every
  row's chart, money and agents tracks are fixed widths, so `$28.98` and
  `$0.03` no longer sit at different places depending on the model name
  beside them.
- **ui:** Telegram is always a choice on both share sheets (Share your
  figures and the Pipeline's), in a row right under
  Share… / Copy / Save. **Send to my Telegram** sends the card through your
  own bot to your own chat (or reads **Set up Telegram** until one is
  connected); **Send to someone in Telegram** copies the card and opens
  Telegram's chat picker — the Telegram app itself in the desktop app when
  it is installed, else t.me — saying "Image copied — paste it in the chat".

## [0.121.0] - 2026-10-15

### Added

- **brain:** Second Brain says where it is kept — in its Settings and under
  *Details* in How it works: the real path of `caprock.db` as the daemon
  resolved it (with *Copy path*), the tables `brain_nodes`, `brain_edges`
  and `brain_runs`, and that the session text goes to Anthropic through
  your own Claude to be read while nothing goes to Caprock.
  `GET /v1/brain/status` carries the path as `db_path`.
- **remote:** the groundwork for reaching your other computers through the
  relay (ADR-067). A Caprock daemon can now be a client of another
  machine's daemon over the same end-to-end encrypted channel a phone uses,
  pair with it by its link and keep the token in `machines.json` (0600),
  opening the channel only while something needs it. Nothing to see yet:
  the routes, the target's computer pairing and the app follow.

### Changed

- **app:** the sidebar's session rows are bigger and easy to read (a user
  could not read them, nor tell which tab she was in). Rows are 38px with
  the title at 14px; each says its state as a dot and a word — green and
  breathing while it works, amber while it waits, faint when idle — and a
  tab's key is the footer's readable chip. The flat list no longer draws
  the project's name on each row; the tooltip and screen readers still say
  it. Only the tab in front looks selected now (an accent tint, a 3px
  accent edge and a bold title): a row waiting on you is marked by its
  amber dot and word, no longer by a fill and edge of its own, and the
  project in front lost its edge. The Today card folds to one line by its
  chevron and can be hidden from its right-click menu; Settings →
  Appearance shows it again, and while it is hidden the list's heading
  counts what waits on you.
- **app:** the sidebar's Second Brain card is quiet by default: folded to one
  muted row, *Second Brain · Idle · 140 memories* or *Indexing 3 sessions…*,
  whose small glyph pulses slowly only while a read runs. It lifts a pixel on
  hover, a click opens Second Brain, and the chevron unfolds a calmer orb
  (smaller, slower, fainter, fewer sparks). A fold you saved is kept. The
  card now sits under the list and above the footer instead of at the end
  of the list's scroll, so its status line is never cut off by the footer;
  when room is short the orb shrinks (and in a window under 640px tall is
  not drawn). The orb's sparks also follow the sessions working now.
- **app:** the right panel's CI pull-request bars say what their stages are:
  one faint line, *open · CI · merged · released*, over the bars' columns,
  and each segment's tooltip names its step and state (done, running,
  failed, waiting) with the landing-queue label on the step a PR is on. The
  rows are as tall as before.

### Fixed

- **app:** on macOS the first click on a Caprock window that is not in front
  reaches the page: a tab's × in the title-bar strip closes the tab at once
  instead of the first click only bringing the window forward. Dragging the
  window by its title bar works as before.
- **loop:** a subagent's edits no longer raise a loop alert on its parent. A
  subagent's tool calls arrive under the parent's session id, and the
  detector counted them in the parent's window: a parent and two subagents
  making the same edit, three each, read as nine repeats of one call. Each
  thread now counts its own — the main thread, and every subagent apart — and
  a subagent that really repeats itself still raises the alert on the session
  it works for. A hook fired inside a subagent with no `agent_id` is told
  apart by its transcript path (`…/subagents/agent-<id>.jsonl`). The Week
  card's longest loop counts the same way.

## [0.120.0] - 2026-10-15

### Added

- **brain:** the Second Brain banner and *How it works* show the agents you
  actually use — up to five of Claude Code, Codex, Gemini CLI, OpenCode and
  DeepSeek, from your last 30 days, drawn as Caprock's own characters (Claude
  in the face you picked, duck included) — around the brain, each line
  carrying a pulse into it: *One memory for all your agents*, with a line
  naming them (*Claude Code, Codex and Gemini CLI remember together.*).
  With no usage yet it is Claude Code alone. Both now say *Free* in a quiet
  accent pill, and the dialog adds *Free — runs on your own Claude, on this
  computer.* The pulses hold still with reduced motion.
- **app:** a release plan with progress bars — on the Pipeline, in the
  right panel and on Work. The next version your changelog entries call
  for (a feature makes a minor release, fixes a patch; hover it for how it
  was counted), then a ten-block bar per pull request merged since the last
  tag, open, or agent still at work, with its step in a word — a
  landing-queue label such as *landing: queued* when it has one, the CI
  step red when a check failed — and drafts and idle agents under *Later*.
  It is a *Next release* panel under the Pipeline's figures, a *Release*
  section in the right panel and a third view on Work beside List and
  Kanban. The right panel's sections now move by a small grip at their top
  left: drag it, press ⌥⇧↑ ⌥⇧↓ on it (Ctrl+Shift+↑ ↓ on Windows and
  Linux), or click it for Move up, Move down, Move to top and Reset order;
  the order is kept for you.
- **app:** the release check runs hourly instead of every six hours, and
  within five minutes of the computer waking; it is the same conditional
  request to GitHub, and nothing new is sent. Settings has its own
  **Updates** section: the switch, when Caprock last checked, and **Check
  now**. In the desktop app it adds a choice for a new version: **Ask me**
  (the card, as before) or **Update automatically**, which downloads the
  update in the background and restarts into it only when no agent is
  working or waiting on a permission prompt, you have left the app alone
  for two minutes, and nothing typed is waiting to be sent — with ten
  seconds' notice and **Not now**, and *Updated to vX · What's new*
  afterwards. Sessions and tabs come back as after any update. The update
  card also offers **Always update automatically**.
- **app:** a check for updates you ask for always answers. Nothing newer:
  a banner says *You're up to date — Caprock X is the latest · checked just
  now*, with **Close**, and goes after 8 seconds unless the pointer is on
  it. A failed check shows the error with **Retry**. The hourly background
  check stays silent when there is nothing new.
- **brain:** Second Brain starts in one click and you can watch it being built.
  The empty screen is one picture, *Give your agents a memory*, *Free* and
  *Start building*, with one line on what it does (your own Claude reads your
  last 30 days on this computer, up to the daily limit, nothing goes to
  Caprock) and the rest under *Details*. The click turns it on and reads the
  past month. While it builds, the screen shows the session it is reading,
  *12 of 41 sessions* with a bar, memories found counting up, today's tokens,
  where it all comes from per project, and the last reads, with *Pause* and
  the one fix for a problem (*Check again*, *Raise to 1M a day*). A build now
  reads session after session instead of four every five minutes.
- **brain:** the living brain: a slowly turning cloud of your memories with
  your agents at its rim and sparks flying into it while it reads, in the
  sidebar card and on the screen. At rest it added about 0.6% of the page's
  main thread (measured in a headless browser, 2026-10-15), and nothing while
  out of view.
- **app:** the status bar's *agent cpu … ram …* opens a popover on hover,
  focus or click: CPU and memory over the last 15 minutes or hour for the
  agent in front, all sessions and Caprock itself, each with its figure now,
  peak and average, and the sessions using the most right now, a click on one
  bringing its tab forward. The daemon keeps the samples it already takes in
  a fixed one-hour ring (`GET /v1/resources/history`): 157 KB for ten
  sessions, no new sampling.
- **app:** quick replies: under the terminal of every agent Caprock started,
  and above the chat's field, a row of small buttons sends *Continue*,
  *Shorter*, *Explain*, *Run tests* or *Commit* in one click, the way the
  composer sends. Edit the list in Settings → Terminal → *Quick replies*.
  Sessions started in another terminal never get the row.

### Changed

- **changelog:** a pull request no longer edits `CHANGELOG.md`. It adds one
  file, `changes/unreleased/<slug>.md`, holding its entry under a `kind:`
  line, and the release writes them all into the new version's section with
  `scripts/changelog.py assemble`; `scripts/changelog.py preview` shows that
  section before then, and `make docs-check` rejects a malformed file. With
  many pull requests in flight, editing one shared section made git conflict
  and, three times on 2026-10-15, put entries silently into releases that
  had already shipped. The Work page's next-release list reads these files
  too, from any repository that keeps them.
- **brain:** the sidebar's Second Brain card is one click target into the
  screen, folds to one row that says what it is doing (*Extracting from
  acme-api*, *Indexing 3 sessions*, *Idle*, *Paused*) with the count, and its
  *Start building* opens the screen instead of a wall of consent text.
- **brain:** the graph reads at a glance: memories cluster around their
  project, a dot's size is its links and its colour its kind, only projects
  and the busiest topics are named, and hovering a node lights its
  neighbourhood and dims the rest. Settings on the screen are one gear with
  three choices; *How it works* says its details in three short lines.
- **ui:** the *Take Caprock with you* strip has two buttons instead of five:
  *Set up* opens a small list of Phone and Telegram, each with its state, its
  own action and *Not needed*, and *Later* hides the strip for three days. The
  × folds it to a *0 of 2* chip in the status bar that opens it again.
- **ui:** a GitHub read that fails on the network or with a 5xx now says
  *Couldn't reach GitHub. Showing data from 6 min ago.* with *Retry*, the raw
  error and the exact time in the tooltip, and then what GitHub's status page
  reports: an outage with a link to it, or *all systems operational — likely
  your connection*. *Watch GitHub Status* in that line, off by default, shows
  a dot in the status bar while GitHub reports an incident. The daemon reads
  githubstatus.com only while GitHub is connected, with nothing about you.
- **store:** four indexes that later ones had replaced are dropped, giving
  back 125 MiB of a 1041 MiB database of 519,000 events, with every query
  as fast as before. The space returns as the database's idle vacuum runs.

### Fixed

- **app:** terminals reconnect on their own after the network drops. A
  terminal whose connection was lost retried on a single timer, and the
  only thing watching it stopped with the socket: when the browser refused
  to start a new socket once (as a network stack being swapped under it
  can), or the timer was lost, the tab said *Reconnecting…* for good and
  nothing typed reached the session until the tab was closed (user report:
  every tab stuck after a Wi-Fi drop). A terminal between sockets is now
  checked every second and always has a retry on its way and on time; a
  pause for its own backlog resumes after 15 s even if the terminal never
  reports catching up; and the window getting focus checks the connection
  at once. The badge says the attempt and the next try, and after 3
  failed tries or 10 s down offers **Reconnect now**, which reconnects the
  same session — no new process. The dashboard's live connection got the
  same watchdog and button.
- **brain:** search finds any language's letters in any case, several
  words, and small typos. Second Brain's search matched one phrase, and
  ignored case for Latin letters only, so a memory in Greek or with
  accents was missed when typed in another case. Now every word has to
  match, in any order, in a title, summary, project or linked topic, with
  case and accents ignored in every script; when little matches exactly, a
  word a typo or an ending away counts too, said as *including close
  matches*. Results come best first — title above summary above a close
  match — and the List view marks the matched words. The search box says
  what it searches.
- **app:** the terminal in front no longer turns to garbage after a long
  day of tabs. xterm's WebGL renderer shares one glyph atlas among every
  terminal, merges its pages when it fills, and after the second merge
  kept drawing from the old page's texture (the new merged page carried
  the same per-page version number as the old one): letters clipped and
  overlapped over the whole screen until font size + then −. Every
  terminal now re-sends its atlas to the GPU and redraws when a merge
  happens, and the window back in front after half a minute away does the
  same for the tab shown.
- **app:** the sidebar footer is a band of its own under the list, on a solid
  fill with a hairline on top, so the edge between the list and the tools reads
  at a glance in every palette; the list scrolls above it and its last line
  (Second Brain's *Local · your own Claude · free*) is whole when scrolled to
  the end. Folded, a key above an icon is part of that icon's button: a click
  on ⌘D, ⌘P, ⇧⌘M and the rest does what the icon does, with its tooltip.
- **pipeline:** the repository picker lists only git repositories on GitHub.
  A folder outside git (a copy in Downloads, a quick chat's folder, the paste
  folder), a repository with no remote and one on another host are no longer
  offered, so picking an entry never ends on "This folder is not a git
  repository with a remote". Two clones of one GitHub repository are one
  entry, and two entries that would read the same word show owner/name, else
  their parent folder. The *N more…* list follows the same rules, and Home's
  Pipeline card picks from the same list. New read: `GET /v1/repos/remotes`.
- **ui:** the theme picker is walked with the arrow keys, each palette shown as the focus lands on it; Enter or Space keeps it.
- **agents:** text copied from an agent (its `pbcopy`) keeps non-Latin letters: every process Caprock starts gets a UTF-8 locale when it has none, not only agent tabs, and the daemon sets one on itself at start.
- **ui:** the UI tests that turned PRs red at random pass every time. The
  chat test's live store dialled a socket nobody answered and flipped the
  link to *reconnecting* mid-test; the cockpit tests compared times drawn
  from the clock with fixtures stamped when the file loaded; the app
  workspace tests handed the dashboard a summary without `savings`, so the
  Now screen crashed whenever it drew one; and the first test to open the
  lazily loaded dashboard paid for transforming it inside its own 5 s, then
  asked for its links before they had drawn. Tests only; nothing in the
  product changed.

## [0.119.0] - 2026-10-15

### Added

- **mail:** the AI assistant works with the subscriptions you already have.
  *Summarise* and *Draft reply* can go through your own logged-in Claude
  Code, Codex or Gemini CLI (run headless, with no tools, hooks or session
  file), through an API key for Anthropic, OpenAI, OpenRouter or DeepSeek
  (kept in your keychain, never shown again), or through a local model
  server as before. *Automatic*, the default, uses the first of claude,
  codex, gemini and a local server this computer has, so with Claude Code
  installed turning AI on is the only step. Settings show which provider
  answers and where the mail text goes; it is sent only when you click an
  AI action, and the thread reaches the model fenced as data it must not
  follow.
- **app:** New project from a template — the dialog. *From a template…* in
  New project's footer or ⌘K: pick a saved template or look one up
  (`owner/name`, its link, or a folder), name the project, paste or drop
  the brief, and the box under it says what *Create* will run and send
  (the name and visibility, to GitHub, through your own `gh`; nothing
  without it). Progress shows in the footer; Esc hides it and the agent
  still starts in its own tab when the project is ready. A failed clone
  offers *Try the clone again* and *Open on GitHub*. Settings → Project
  templates edits and removes them. In the app a dropped `.md` or `.txt`
  becomes the brief (`read_dropped_text`, only from the latest drop).
- **projects:** start a project from a template — the daemon side. Add your own template (a GitHub template repository,
  a folder, or both) with where its brief goes and the agent's first
  prompt; Caprock reads its `TEMPLATE.md` to fill those in. Making a
  project from it runs your own `gh` on your click (`gh repo create
  --template`, then `gh repo clone`), or copies the folder's last commit
  into a new repository when you pick the local copy, then writes your
  brief and commits it — never pushed. A failure takes away only the
  folder Caprock made and never deletes a repository on GitHub; Retry
  picks up where it stopped (ADR-065).
- **pipeline:** every figure on the Pipeline page — and the five on Home —
  shows its last 14 days as a small line, with today set against them
  underneath: *usual*, *above usual +38%*, *below usual −30%*. In flight,
  throughput, the CI median, opened → merged, merged → released and the
  agent cost each get one; green where today is the better side (a shorter
  CI run or merge, more merges), amber the worse, muted for the open count
  and the cost. Running totals compare today so far with earlier days at
  the same hour; a day with nothing to measure is a gap, not a zero; with
  fewer than three earlier days of data it says *not enough history*.
  Hover a day for its value, or the word for what it is compared with.
  Counted from what the Pipeline already reads: no new GitHub request.

### Changed

- **app:** the Pipeline has its own tab again, pinned with the system tabs
  right after the Dashboard tab and before Mail, drawn like them: its glyph
  and ⌘P (Ctrl⇧P on Windows and Linux), its × while it is in front. ⌘P,
  *Pipeline* at the foot of the sidebar and *Open Pipeline* in the palette
  bring it to the front, and again go back to where you were; ⇧⌘B still
  works and ⌘B stays the Pipeline bar. It stays in the Dashboard too:
  *Pipeline* in its menu and *Open Pipeline →* on Home take you to that
  tab, so the page is drawn once and, behind other tabs, reads nothing. The
  tab is kept across restarts.

### Fixed

- **phone:** Settings → Use on your phone tells you how to get back to a
  phone you already paired. Each paired phone says *Already paired — just
  open m.caprock.dev on that phone*, and **Open on the phone again** shows
  a QR code of that address (the address only: no code and no key, so it
  pairs nothing) and the Add to Home Screen tip. With a Telegram bot set up,
  **Send the link to my phone** sends the address to your Telegram chat
  through your own bot, and says so before you press it.

## [0.118.0] - 2026-10-15

### Added

- **app:** a live session's row on Home takes you into the running session.
  Click anywhere on the row (or Enter on it) and the session's tab comes to
  the front, as its ⌘N does, or opens if it has none; *Go to session ↗* with
  the tab's key shows on hover, and *details* still opens the session page.
  A session started in your own terminal says *in your terminal* and offers
  *Continue in Caprock*: a new process on a copy of the conversation, in a
  new tab, leaving the one in your terminal untouched. An idle session
  Caprock started gets a small **× End**, which asks first only when
  messages wait in its queue; a working session and one your terminal
  started never do. In a browser the row keeps its *open* link.
- **work:** the Work page — every piece of work on the machine on its way to
  a release, one row per branch at its furthest stage, grouped Next release,
  In review, In work, Planned and Released, or as Kanban columns. Each row
  has a bar along agent → PR → CI → merged → released filled to its stage
  (red when CI failed or it conflicts), who works on it (the agent and
  model, started by Caprock or your terminal), elapsed time and agent cost
  at list price. Estimates appear only with a measured basis: a turn's
  rough range, CI against its median, merge to release against the median
  lag, and the gap since the last tag against the usual gap. Rows that
  need you come first; agents idle for over 30 minutes fold into one line.
  It is second in the Dashboard's menu (⇧⌘W; Ctrl+Alt+Shift+W on Windows
  and Linux, and again back to where you were), and Home shows its headline
  and first rows above the Live pulse with *Open Work →*. A session row
  brings that session's tab to the front; a pull request's title opens it
  in the Pipeline with its detail open.
- **work:** The Work board's daemon answer, `GET /v1/work` (ADR-064): every
  live session on the machine — started by Caprock or by hand — with its
  state, its running turn's rough range (Claude Code only, never while it
  waits on you), its own task list, what it cost today and the pull
  requests it recorded; the task runner's tasks and the queued messages;
  and each repository's `[Unreleased]` CHANGELOG entries, newest tags and
  commits past the last one, read from local git as of your last fetch.
  Nothing is written, nothing is polled, GitHub is not asked and git never
  fetches. The screen comes next.
- **pipeline:** The PRs & CI board's flow strip carries how often the
  repository ships: the median gap between its releases already read
  (`release_gap_median_ms`, with three gaps or more), never a date for the
  next one.
- **app:** a Sunlight theme for working in bright light. It is black text
  on pure white with no faint greys: every text colour, the faintest
  included, is 7:1 or more against its background, measured on every
  surface. Text is one weight heavier, borders and hairlines are dark
  enough to see in glare, and the sidebar is opaque. The status colours
  and the accent are saturated and stay apart. Its terminal keeps all 16
  ANSI colours at 5.3:1 or more on white (the normal eight 7:1), the
  yellow and cyan that usually wash out included. Pick it under Light in
  the theme picker or Settings → Appearance.

### Changed

- **app:** where you type is easier to find, quietly. The Chat view's field
  carries a hint of the accent at rest — a faint tint and a hairline edge,
  a little stronger with the focus — on every theme and terminal palette.
  In a Claude Code terminal, the rows of its input box (between the two
  rules, at the `❯` prompt) sit on a faint band of the terminal's own
  background, lifted a step: it follows the box as it grows or moves, leaves
  any cell Claude Code coloured alone, reads only the bottom rows of the
  screen, and draws nothing for other agents, shells, dialogs and menus.
- **app:** keys named after what they open. ⌘D opens the Dashboard (⌘0
  still does), ⌘P the Pipeline (⇧⌘B still works), ⇧⌘T the theme picker,
  and ⇧⌘W Work; ⌘F stays Find and ⌘T New shell. On Windows and Linux they
  are Ctrl+Shift+D, Ctrl+Shift+P, Ctrl+Alt+Shift+T and Ctrl+Alt+Shift+W —
  never Ctrl+D, which stays the shell's end of input. The sidebar's footer
  shows *Dashboard ⌘D*, *Pipeline ⌘P* and the theme's ⇧⌘T, folded or not,
  and the palette, the shortcuts list and the tooltips say the new keys.
- **dashboard:** The Pipeline is a page of the Dashboard now, beside *Week*
  in its menu, instead of a tab of its own: ⌘P and *Pipeline* in the
  sidebar open the Dashboard tab there (Ctrl+Shift+P on Windows and
  Linux), and again go back to where you were. It shows one repository —
  the agent in front's, else the one you looked at last — with buttons
  beside its title to switch. It is drawn as the Dashboard is: its figures
  are the Dashboard's tiles, larger and readable, each explained in a card
  under it on hover rather than a tooltip over the number; every pull
  request's whole title; and its four steps tell done (ticked), current
  (filled, ✗ when red, a turning ring while CI runs) and still ahead
  (outlined) apart by shape as well as colour. A pull request's detail
  opens beside the list. Home's CI/CD section shows the Pipeline's first
  five figures at its top — in flight, needing a fix, ready, throughput,
  CI median — with *Open Pipeline →*. A Pipeline tab saved by an earlier
  version opens as the page.
- **ui:** Get premium in the header is a quiet tinted button, not a bright
  block: the same height, radius and type as Feedback and Settings beside
  it, a faint premium tint with a hairline border and premium-coloured text,
  the price a step fainter, a little stronger on hover. Its text reads at
  4.5:1 or more in every palette.

- **brain:** Second Brain looks like what it is: a brain made of a graph.
  Nodes and links in the side view of a brain, in the memory kinds'
  colours, softly pulsing, with a new node dropping in now and then and
  linking up (still with reduced motion; CSS only, nothing runs in the
  background). *How it works* is big and short — *Your agents' memory*,
  one line on what it does, three one-line steps, *Over time: your
  personal Jarvis*, one line on privacy and one button; the defaults
  (Haiku, 300k tokens a day, up to five memories) moved into a folded
  *Details*. The empty sidebar banner leads with the same brain, *Give
  your agents a memory*, *Start building* and *How it works*.

### Fixed

- **picker:** an arrow key pressed in the folder picker the moment a
  folder's entries appear is no longer lost; the selection used to be
  cleared just after it was made.
- **app:** the theme picker opens whole, above everything. From the
  sidebar's footer its palettes were cut off at the sidebar's edge and the
  terminal drew over them; it now opens over the whole window, kept inside
  it on every edge at any sidebar width and with the footer folded, and
  scrolls in a window shorter than itself. Opening it puts the focus on the
  palette in use; Esc, or tabbing past the last palette, closes it and gives
  the focus back to the button.
- **app:** the sidebar footer's shortcuts are readable. Folded, the keys
  above the icons were small faint 10px chips; now every key in the footer
  is the New agent chip's size, folded or not. Where one has no room —
  beside a row's words, or over a folded icon — it is left out whole
  rather than drawn smaller, and the key stays in the tooltip: a row
  measures itself and brings the chip back when it widens. Off macOS the
  folded keys still show on hover, now at full size.
- **mail:** the Caprock Mail preview app reloads onto Caprock's new page
  after Caprock updates (it used to keep showing the page from before the
  update when the port stayed the same), and a click on its Dock icon
  brings the window back.

## [0.117.5] - 2026-10-15

### Added

- **brain:** Second Brain's status says when the reader wakes next
  (`next_wake`), so a screen can tell you when the first memories may come
  instead of leaving you at 0. Turning building on still wakes the reader
  at once, and a double click or a second yes never starts a second read
  beside the first.
- **mail:** Mail on its own. `<daemon>/?mail=1` is the inbox and nothing
  else of Caprock — no sidebar, no tabs — titled *Caprock Mail*.
  `app/mail-mac` builds a Mac preview app around it: Caprock's icon with an
  envelope in place of the dot, one window on the running Caprock, so the
  accounts and mail are the same as in the Mail tab. It waits for Caprock
  when it isn't running and follows it to a new port.

### Changed

- **brain:** the sidebar's Second Brain block is a small banner while it is
  empty, instead of a bare 0 and two faint lines: a faint graph breathing
  (still with reduced motion), *Remembers what your agents learn — so the
  next one starts smarter.*, **Start building** and *How it works*, and
  *Local · your own Claude · free*. **Start building** asks in place —
  your own `claude` and its model, on this computer, the daily token
  limit, where the prose goes, and that Settings turns it off — and only
  **Turn on** switches it on and starts on your last 30 days of sessions,
  within that limit; without Claude Code it says so and offers no
  button. Once on and still empty it says what it is doing: *Reading your
  recent sessions…*, or how many sessions are waiting, and the last
  problem if there was one. The same line replaces *your personal Jarvis*
  under the Second Brain screen's title.
- **brain:** Second Brain's *How it works* now explains it in ten
  seconds. *Remembers what your agents learn — so the next one starts
  smarter*: it keeps the decisions, findings, ideas and open questions
  your sessions arrive at and hands the relevant ones to the next agent
  you start — over time, your personal Jarvis, an assistant that knows
  your projects. Three steps say how (a session ends → your own `claude`
  reads it on this computer, Haiku and 300k tokens a day by default →
  up to five memories go into the next session's handoff), and one line
  says that nothing leaves the computer except that call and where to
  turn it off.

### Fixed

- **app:** typing a name in New project's folder field now searches the
  folder it is in. `~/dev/cap` used to empty the list; now it lists the
  folders of `~/dev` holding *cap* — the ones starting with it first, the
  letters marked — and every key narrows it at once. The first match is
  highlighted: ↑↓ move, Enter picks it, Tab completes to it and goes
  inside. No match says *No folder starting with 'cap' in ~/dev*. Works
  with `~`, backslashes and drive letters on Windows.
- **windows:** Caprock no longer flashes console windows that steal the
  keyboard focus. The daemon ran without a console, so every git, gh or
  `claude -p` it started opened a window of its own for a fraction of a
  second, every few seconds, and typing in other windows came out ragged
  (user report on Windows 10). Every child now starts with a hidden
  console, and a test keeps it that way.

- **mail:** adding an account can no longer sit on *Checking…* forever. A
  server that goes quiet while Mail connects or signs in — IMAP had no limit
  and SMTP waited five minutes per command — now ends the check within 30
  seconds with what happened: which server stopped answering, and that
  another mail app open on the same account can count against the server's
  connection limit. A synced mailbox still waits in IDLE as long as it
  needs; the limit is lifted once signed in.

## [0.117.4] - 2026-10-15

### Changed

- **alerts:** a loop alert is now one sentence and three actions. It
  says what happened — *caprock ran the same command 5 times in 3
  minutes (python3 …/p2e.py)*, the whole command on hover — with the
  costs quiet underneath. **Tell the agent** shows a message marked
  *[Caprock]* and signed as sent by Caprock's loop alert, which you can
  edit, then puts it in that session's queue so the agent reads it when
  its turn ends; it is offered only on sessions Caprock started, and a
  session you started yourself gets **Open session** instead. **Dismiss**
  has a menu with *Don't warn about this command again in this session*
  and the one remaining cap link, *Set a spending cap…*. The same card is
  on Now, in the agent cockpit and on the session page.
- **brain:** it is called *Second Brain* everywhere it is named — the
  sidebar block (*SECOND BRAIN*), the dashboard's screen row, the screen's
  title, ⌘K (*Second Brain*, *Add to Second Brain…*) and *Drop into Second
  Brain* — with a brain outline as its mark (it was a drop falling into a
  bowl, which did not read as a brain) beside the name, and one faint line under it in
  the sidebar and on the screen: *All your agents build your personal Jarvis
  over time.*
- **app:** the chat button in the tab strip says what it is: a speech
  bubble and the word **Chat**, as Deck has its word, lit while the chat is
  shown. Its tooltip says what the chat is: this session as messages —
  your prompts, the agent's replies, one line per tool call — and a field
  that types into it, while the terminal keeps running.

### Fixed

- **app:** terminals no longer show rows of wrong letters ("ι ɤr ·r")
  after another tab redraws its glyphs. All terminals share one set of
  drawn glyphs; when one tab rebuilt it (back after five minutes, after the
  Mac woke, on a display change) the others kept pointing at places in it
  that now held other letters, until their rows were drawn again — for a
  couple of seconds after closing a tab or leaving the chat, or for good in
  a tab that printed nothing. Every terminal now redraws from the new set
  at once, and a tab coming back into view sends its glyphs to the GPU
  again. Under the chat (and under Changes or a comparison) the terminal is
  put away as a tab behind another is: what the agent prints meanwhile is
  drawn at once when you come back.
- **app:** a terminal no longer opens with its letters spread far apart
  after the app restarts (an update): a letter cell measured before the
  terminal's font settled was kept until you changed the font size. A cell
  no monospace font could have is now measured again on its own, when the
  fonts are in, when the window comes back and when the tab is shown.

## [0.117.3] - 2026-10-14

### Added

- **pipeline:** ⇧⌘B (Ctrl+Alt+Shift+B on Windows and Linux) opens the
  Pipeline in a tab, or brings it to the front; pressed again there, it goes
  back to the tab you were on. *Open Pipeline* is in ⌘K too.
- **cockpit:** the CI block's *PRs* view shows the repository's pull
  requests as thin progress bars toward a release — Open → CI → Merged →
  Released, CI in its check colour — with each one's number, title and time
  on its step. It scrolls; *Expand* makes it taller and is remembered;
  *Pipeline ↗* opens the page.

### Changed

- **brain:** Second Brain is free, all of it. There is no cap on the
  memories you drop in by hand (it was twenty without a licence), and the
  automatic build from finished sessions works for everyone who says yes —
  it runs on your own `claude`. The Brain screen asks everyone once; the
  sidebar's Brain block starts unfolded, with no lock, and *How it works*
  explains it and opens the Brain screen. A Premium licence bought for
  Second Brain stays exactly as it was, with every other Premium feature.
  `GET /v1/brain/status` no longer carries `licensed`, `free_max` or
  `free_left`, and no Second Brain route answers `402`.
- **pipeline:** *PRs & CI* is now **Pipeline**, everywhere: the tab, the
  sidebar footer, the palette, the deck. Tabs you had open come back under
  the new name. The page is one list of pull requests instead of a board
  and a list: each row its number, its whole title, its labels, and the
  steps Open → CI → Merged → Released as pills, the one it is on
  highlighted, then its agent cost. In flight first, then merged, then
  released (ten, then *Show more*). Click a row for its detail over the
  page; × or Esc closes it. The red-runs and Actions-minutes figures went
  with the old list.
- **app:** the sidebar footer's button is *Pipeline*: a click opens the page
  or goes back from it. Showing or hiding the bar under the agent is now on
  the bar itself (*Pipeline* and ×), ⌘B, and *Pipeline bar: On/Off* in ⌘K.

## [0.117.2] - 2026-10-14

### Added

- **mail:** **Import everything.** Mail lists the mail accounts it can
  read on the computer — Thunderbird, and Apple Mail including the Google,
  iCloud and Exchange accounts in System Settings › Internet Accounts —
  each address once, under the app it came from and when that profile was
  last used (accounts from a profile unused for 90 days start unticked). An
  app it cannot read is not shown. Tick them and press *Import*: accounts with a saved
  Thunderbird password connect by themselves, then each other account asks
  for its one sign-in in turn (Google or Microsoft in the browser, an
  app-specific password for iCloud, otherwise the password), with a
  progress list of connected, waiting and failed accounts, *Retry*, *Skip
  for now* and *Come back*. A build without Google or Microsoft sign-in says so and asks for
  an app password instead of showing a button that cannot work.
- **release:** Mail's Google and Microsoft client IDs are compiled into
  releases from the `CAPROCK_MAIL_GOOGLE_CLIENT_ID`,
  `CAPROCK_MAIL_GOOGLE_CLIENT_SECRET` and `CAPROCK_MAIL_MICROSOFT_CLIENT_ID`
  GitHub secrets, the desktop app's daemon included; unset, a release still
  builds.
- **now:** each figure in *Today* has a small line of your last 14 days and
  one word against your own median: *usual*, *above usual +38%*, *below
  usual −20%*. Running totals (cost, sessions, turns) are compared by the
  same time of day, so a morning no longer reads low against whole days;
  *Burn now* is set against your typical 10-minute window while working.
  Cache hit gets the line only. Hover says what it is compared with; under
  five days of history it says *not enough history*. It follows the agent
  filter. New endpoint `GET /v1/stats/trends`.

- **brain:** Second Brain builds itself, once you say yes. When a
  session has been quiet for ten minutes, your own `claude` (Haiku, no
  tools, no transcript, none of your hooks) picks out what it decided and
  found, and each memory links back to the passage it came from. A daily
  token limit (100k, 300k or 1M), short sessions skipped, failures retried
  later; *Build from my last 30 days* shows an estimate first. Settings →
  Second Brain shows what it used and read. A new session's handoff now
  carries up to five of the repository's memories.
- **app:** Caprock may also ask about a feature it is considering — running
  Hugging Face models on your computer, and one of watching short ads to
  earn money or YouTube while agents work. At most one strip a day; each
  question is two clicks and an optional email. Nothing leaves the computer
  until you press **Send**, which sends those answers to caprock.dev and
  nothing else; *Not interested* and × send nothing, and an answered strip
  never returns.
- **brain:** Second Brain drawn. The Brain screen opens on a graph of your
  memories and their topics and projects — drag, zoom, click a dot to open
  it, *List* for rows — smooth with thousands of memories. The app's
  sidebar has a Brain block below the projects: the newest thirty as a small
  graph where each new memory drops in, and the three newest titles. The
  strip that offered Second Brain ahead of its arrival no longer shows.

### Fixed

- **prs:** the PRs & CI board follows merges and releases instead of
  freezing. With a dozen open pull requests whose checks were running, the
  daemon read each one's state one after another, ran past its deadline on
  every refresh, and the board kept showing its afternoon answer for hours —
  merged pull requests still under *CI running*, new releases missing —
  behind a bare *updating…*. The open pull requests are now read four at a
  time within a budget, the board's answer always comes back (a card whose
  checks could not be read again in time is drawn faint), and releases are
  read every 2 minutes instead of 10. The header always says how current
  the data is: *Updated just now*, *Saved 5 h ago · refreshing…* while a
  kept copy is read again, or *Couldn't refresh: <why> · showing data from
  15:02 · Retry*; the CI/CD section on Now says the same. A refresh that
  keeps failing is no longer retried on every poll.
- **ui:** selected text stays readable in every theme. In a terminal,
  Claude Code's own selection (fullscreen mode) painted its highlight in the
  palette's blue, which in a dark palette is light, under light text — in
  Dark Pastel 1.6:1, nearly invisible. Every terminal palette now keeps text
  at 4.5:1 or more against whatever is behind it, as the light ones already
  did. Selected text on the page sits on a lighter wash of the accent (20%,
  was 35%), written out per palette: body text 8:1 or more, muted text
  4.3:1 or more.

- **phone:** a paired phone stays paired. A dropped connection, a computer
  or relay restarting, a phone asleep or offline, a computer still on an
  older Caprock, or a QR opened twice no longer send the phone back to
  *Settings → Use on your phone*. Three causes: a phone hanging up in the
  middle of an answer took the computer off the relay for every phone; the
  relay could hand the next phone a stray message meant for the one before,
  which the page read as "not your computer"; and the page believed a
  single bad answer. Now the page asks to pair again only when the computer
  has turned the phone away on two separate connections, or refused it
  three times in a row, and it still checks once a minute and comes back by
  itself if that was wrong. Needs the new page at m.caprock.dev and the
  relay redeployed; the computer's half comes with the next release.
- **status:** an agent you set going no longer reads *waiting for you*
  for seconds after. Answering a permission prompt — a key in the
  terminal, the card's buttons, the phone, Telegram — shows it working at
  once (*approved — running …*), instead of when the allowed command
  finished; answering No shows it waiting for you. Enter at its prompt
  shows *starting on your message* straight away, and goes back if
  nothing was sent. Every screen (sidebar, tabs, cockpit, tray, phone)
  now updates a session's status as soon as it changes rather than up to
  two seconds later, and a Codex or Gemini session you type into is read
  at once instead of on its next poll. Measured with a test agent: a
  prompt to *working* about 1 s → under 10 ms; an approved 15 s command
  16 s → under 10 ms.

## [0.117.1] - 2026-10-14

### Added

- **now:** the tokens beside each pull request's cost in the CI/CD
  section (*9.4M tok · $2.12*); the hover splits input, output, cache read
  and cache write.

- **brain:** Second Brain. Keep the answers worth keeping as memories — an
  idea, a decision, a finding, an open question — each linked to its
  project, its topics and the moment in the session it came from. **Drop
  into brain** sits under every answer on Memory, in a session's Answers
  and in the chat view; ⇧⌘H (Ctrl+Shift+H on Windows and Linux) or ⌘K →
  *Add to brain…* takes a line of your own. *Brain* in the screen row
  searches them by words, project and time, and opens one to edit, pin,
  link to a topic or delete. Twenty memories are free; Premium keeps every
  one. Kept in Caprock's database on this machine.

### Fixed

- **app (macOS):** macOS no longer asks for the microphone (and for
  Desktop, Documents or Downloads) again after every Caprock update. The app
  and its daemon are now signed with one Caprock certificate that stays the
  same across releases, instead of an ad-hoc signature macOS saw as a new
  program each time. The first update to this release asks one last time;
  later updates keep your answers. Opening the app the first time is
  unchanged: it is still not signed with an Apple Developer ID.
### Changed

- **phone:** a session's header is one 44px bar: back, the title, a dot for
  its state, and **Chat | Terminal** with **···** for the other views. The
  project, permission mode, model, controls and details are a tap on the
  title away. In the chat the bar is drawn over the conversation and slides
  away while you scroll down, back on scroll up or a tap at the top, so the
  text never jumps. On the relay page at 390×844 the conversation began
  178px down the screen (the computer bar and three header rows); now 44px,
  and 0 while the bar is away (owner, 2026-10-14, translated: "I want the
  header to take minimum space because I need to read this chat").
- **phone:** the relay page's computer bar ("DimaS-MBP ▾") is gone while the
  connection is fine and one computer is paired. It comes back while
  connecting or offline, and with several computers paired it shows outside
  a session; inside one, the switch is in the title's sheet.
- **chat:** the message field glows softly in the accent while it has the
  focus, a little more once there is text in it; on the phone and the
  desktop alike.
- **now:** *Live activity* is now **What happened**: the moments of your
  sessions instead of every command. Files edited (grouped by folder), tests
  and checks with their result (*passed*, *failed (exit 2)*, or *no result
  recorded* when there is none), builds, commits with their message, pushes,
  pull requests opened or merged, subagents by their task, a turn ending with
  the first line of the reply, a session waiting for approval, and a command
  that failed. Reads, searches and the like are a quiet `+N` on the moment
  they led up to. On one day of real use that is 1,974 rows where the old
  feed had 11,493. *All commands* brings the old feed back; the panel folds
  like the others and remembers it; every row is the same height.
- **app:** the sidebar's bottom block reads more clearly. *Dashboard ⌘0*
  has a row of its own again; under it, one row in two halves: **PRs &
  CI** named with its mode (*CI Off*, *CI Bar*, *CI Page*; ⇧⌘B in its
  tooltip) and the **theme** with its name. On Windows and Linux the two
  take a row each, and PRs & CI shows its key, Ctrl+Alt+Shift+B.
- **app:** folded, the bottom block's icons are a size bigger, and on a
  Mac each one has its key drawn small above it (⇧⌘F, ⇧⌘M, ⌘0, ⌘,
  ⇧⌘B). On Windows and Linux the keys are too long for that and show
  above the icon you point at.

### Fixed

- **phone:** dictation listened only for the browser's language, so Russian
  speech came out as English words. A chip beside the microphone (**EN**,
  **RU**…) says the language and changes it: a tap moves through the
  browser's languages, then opens a list of common ones (English, Russian,
  Ukrainian, German, French, Spanish, Portuguese, Italian, Polish, Turkish,
  Japanese, Chinese, Korean, Arabic, Hebrew). Remembered per viewer; shown
  prominently once when the browser names more than one language.

- **now:** the activity feed no longer says "session ended" at the end of
  every turn and every subagent's stop; it says *finished its turn* or
  *subagent stopped*, and "session ended" only when one did.

- **phone:** a phone can type the moment it pairs. A newly paired phone
  could only look until a second click on the computer — impossible once
  you have left the house. Settings → Use on your phone now has **This
  phone can type and start agents** beside **Show a code**, ticked by
  default and remembered on the computer; the code carries it, so the phone
  pairs ready to work. Untick it for a phone that should only look. The
  panel lists the steps one line each and, while the code is up and after,
  ticks off what is done and what is left: access from anywhere, the phone
  paired (by name), whether it can type (with **Let it control sessions**
  right there if not) and whether the app is installed on it. The phone
  opens on a short **Ready** card — connected to which computer, whether it
  can type and, if not, exactly where on the computer to fix it, the
  install button, and **Open sessions**. m.caprock.dev needs a redeploy
  for the phone's half.

- **now:** the CI/CD section lists only repositories with a session in the
  last 14 days, most recent first. Older ones, and any you hide from a
  block's new ⋯ menu (*Hide from CI/CD*), fold into one quiet line —
  *3 older repositories · 1 hidden — show* — and are not read from GitHub
  until you show them; hidden ones come back with *Show again*.
- **now:** GitHub no longer runs out of time on the CI/CD section: the
  repositories are read three at a time, each with its own 12 seconds,
  instead of one after another under a single deadline that left every
  later one *context deadline exceeded*. A slow GitHub is one grey line —
  *GitHub didn't answer in time — retrying* — once for the section when
  every repository says the same, and the names show at once while the
  figures load.
- **now:** a session that drove many pull requests is no longer charged
  whole to the one whose branch it ended on. It is split between the pull
  requests it worked on, and such a row says *shared*; the release pull
  request #601 read as $1,884.29, the whole orchestrating session, and now
  reads $2.12 (measured on the owner's database). This also corrects the
  PRs & CI Board's agent cost.
- **app:** on Windows and Linux the *Settings* row's words no longer run
  under *phone, Telegram*, and *Send feedback*'s key is no longer cut
  off at the sidebar's edge.

### Changed

- **app:** the dashboard keeps its place. Switch to a terminal tab and back,
  or from Home to Cost and back, and each screen is where you left it:
  scrolled to the same spot, with the Live pulse rows, panels and folds you
  opened still open. A screen out of sight asks the daemon nothing.
- **app:** ⌘0 (Ctrl+Shift+0 on Windows and Linux) brings the dashboard back
  where you left it; pressed again, it goes to Home at its top. The
  sidebar's *Dashboard* row does the same, and *Home* in the dashboard's
  bar scrolls Home to its top.
- **ui:** the main dashboard screen is called **Home** (it was *Now*), in
  the bar, the palette and the back links. `#/home` opens it; old `#/now`
  links still work.

## [0.117.0] - 2026-10-14

### Added

- **app:** closing the tab of an agent Caprock started now asks: **Close
  tab** (in focus, so ⌘W then Enter works as before and the agent keeps
  running) or **Close and end the agent**, which stops it (asking once
  more if it is still answering; the conversation is kept). Tick *Don't
  ask again* to keep your answer; Settings → *Closing a tab* changes it
  back. An agent you started in your own terminal is never ended from
  Caprock: its tab just closes.
- **app:** in the Tabs list, sessions running with no tab sit under a
  quiet *Running, no tab* line, so an agent whose tab you closed no
  longer looks like an open chat.
- **app:** a Mail button with its own key. *Mail ⇧⌘M* in the sidebar's
  bottom block (Ctrl+Shift+M on Windows and Linux) opens Mail in a tab of its
  own beside the Dashboard tab; pressed again it brings it to the front. With
  no account yet it opens straight on a sample inbox, with a line on top and
  *Add account* (Google, Microsoft, iCloud, Other, import); adding your
  account leaves the sample. Also in the palette as *Open Mail*.
- **app:** Send feedback opens with ⇧⌘F (Ctrl+Alt+Shift+F on Windows and
  Linux) from anywhere in the app, and its row in the sidebar shows the key.
- **cockpit:** put the sections in your own order. *Arrange sections*
  under the last one lists them with ↑ and ↓ for each, *Reset to default
  order* and *Done*; nothing moves by dragging a heading, so it never
  happens by accident, and the order is kept for you.
- **cockpit:** every section folds to one line on its label, like Context
  and Plan — Now, Subagents, Tasks, Recent tools, Changes, CI and
  Processes — and stays folded or open as you left it. CI and Processes
  can be arranged with the rest.
- **cockpit:** rubber ducks. Eight of them sit beside Claude's faces —
  classic, debugger, on call, party, pirate, hacker, sleepy and rainbow —
  on a new *Ducks* tab in the menu a click on the portrait opens. Settings
  → Appearance → *Claude's face* can make every session a duck (*A duck
  per session*) or mix them in (*Faces and ducks*); the default stays the
  eight faces, and every session keeps the face it already had. Now and
  then an idle Claude asks "try a duck?" beside its portrait: at most once
  a day, never while you type or a prompt waits, and never again once
  you have seen the ducks or closed it twice.
- **app:** New project in three big steps. ⌘O, *Add project* or *New
  project…* in New agent: pick a folder (a place such as `~/dev`, then a
  click on the folder; *Choose…* opens the system's folder picker in the
  desktop app), see what is there — *One repository*, *3 repositories* as
  cards all ticked for one multi-repo project (or one each), or a plain
  folder — and *Start an agent here*. A folder inside a repository is that
  repository, with no question. The same step says whether the repository
  already has a `CLAUDE.md` or `AGENTS.md` (*Show* reads it) and takes
  optional instructions for every agent there. Clone and a new empty folder
  are in its footer.
- **app:** what a project's agents are told is in sight. New agent shows a
  bigger block, *Project instructions — Set · 12 lines* or *None*, and the
  repository's own `CLAUDE.md` / `AGENTS.md` (members' too), each read on a
  click and Caprock's edited in place; the project's page shows the same,
  and its sidebar row's tooltip says it in words. A multi-repo project's
  repositories are named under the Project field (*3 repos: api, web,
  infra*). The daemon lists the files on each project and returns their
  text from the folder scan (`instruction_files`).

### Changed

- **now:** an opened Live pulse row is calmer and says more. Terminal,
  Open repo and Open session are quiet links at the end of the project's
  line instead of a row of bright buttons, and the empty space beside each
  live session now shows its cost, its last hour, how long it has run, its
  context, its branch with lines added and removed, and its pull request
  with CI. The legend can be hidden; the **?** in the panel's header brings
  it back.
- **app:** the PRs & CI view has one button, at the foot of the sidebar
  beside *Dashboard*: its picture shows the mode — Hidden, Bar (the session
  deck under the agent's terminal) or Full page (the PRs & CI tab) — and a
  click moves to the next. ⌘B and ⇧⌘B work as before and the button
  follows them. The deck's own *Expand* and *Hide* buttons are gone. The
  theme button moved beside it, out of the Settings row.
- **cockpit:** Recent tools says something. Each call shows what it acted
  on — a file relative to the project, or a command's program and first
  words instead of the variables set ahead of it — and how it ended: a
  quiet ✓, *exit 1* or *error* in red, the time only when it was slow,
  and how long ago. The same call repeated in a row is one row with ×N.
  The bar beside each call is gone, and the count in the heading now says
  what it counts (*31,713 this session*).
- **cockpit:** CI's *OS* view is now *By OS* and shows the newest pull
  request's checks per runner — *Linux ✓ passed 1m 48s*, *Windows ●
  running* — without opening its row in the deck first; each of the three
  tabs says what it shows on hover.

- **phone:** one way to pair a phone: from anywhere. Settings → Use on your
  phone → **Show a code** now turns on access from anywhere (the encrypted
  relay) in the same press — a line under the button says so — and the QR
  works on Wi-Fi and mobile data alike. The Wi-Fi / Tailscale address
  choice, the *Same Wi-Fi* step and *Keep on after Caprock restarts* are gone
  from the panel. A phone paired on a home-network address worked on that
  Wi-Fi only, and nothing said so when it went dead on mobile data. For a
  machine without internet, `caprock up --lan` and `caprock pair` still pair
  over the Wi-Fi from a terminal.

### Fixed

- **agents:** a permission prompt you answered from a button no longer
  comes back if the daemon crashes a moment later. The answer cleared the
  stored prompt in the background, so a crash before that write landed
  restored buttons for a dialog already answered; the answer now returns
  only once the stored prompt is gone.
- **app:** the PRs & CI bar's header no longer runs past its right edge
  when the sidebar and the cockpit are both open on a laptop screen: the
  least useful words drop first and the rest wraps to a second line.
- **phone:** m.caprock.dev says where you are. The name Caprock and
  caprock.dev stand beside the mark, a line says the page is the other half
  of the Caprock app on your computer (with where to get it), and the first
  step shows a small picture of Settings → Use on your phone → Show a code.
- **phone:** the phone no longer sits on *Connecting…* with nothing after
  it. A computer that went to sleep kept its relay connection open on
  paper, and the relay handed the phone to it; the phone waited forever for
  an answer. The relay now treats a computer it has not heard from in 75
  seconds as offline (`caprock remote relay` and the hosted relay, which
  needs a redeploy), and the phone gives every attempt 10 seconds, checks
  the computer itself, not only the relay, while connected, and after 5
  seconds says what is wrong — *Your computer is offline or Caprock isn't
  running*, *Your computer isn't answering*, *Can't reach the relay*, *This
  phone was removed: pair again* — with **Retry** and **Pair again**. It
  retries by itself, and at once when you come back to it.
- **phone:** Caprock installs on an Android phone once, when you press
  **Install the Caprock app** on m.caprock.dev. Chrome's own install prompt
  no longer pops up in a browser tab of an already-installed app, a browser
  tab says *Caprock is on your home screen* instead, and the old Wi-Fi link
  no longer offers a second home-screen icon: it says to use the app from
  m.caprock.dev. Opening the same pairing QR twice keeps the pairing that
  worked, and a page left open across a new version of m.caprock.dev
  reloads instead of failing.
- **mail:** Mail opens instead of failing with "null is not an object
  (evaluating 't.accounts.length')". A mail client found on the machine with
  no accounts it could read — Apple Mail before Full Disk Access — came back
  with a null list, and the first-run screen crashed counting it.
- **app:** the closing questions' buttons read on one line. "Keep it
  running, close tab" broke over two lines and "Stop and close" spilled out
  of its button; the sheets are wider, every sheet button keeps its label on
  one line, and the row wraps as a whole on a narrow window.

- **app:** a tab's project name fits. It was cut at nine characters
  (*uncensor…*, *creatos_f…*) even on a wide window; now it takes its whole
  width first and the session's name is shortened before it, and tabs grow
  to 340px when the strip has room. When many tabs leave too little even
  for that, the name ends in an ellipsis and scrolls into view inside its
  own space while you point at the tab, so nothing in the strip moves
  (with reduced motion it stays cut; the tooltip names it in full).
- **cockpit:** moving the mouse over CI's pull requests no longer opens a
  card over the panel. The list of checks opens only once the pointer
  rests on a row, beside the panel, and closes as soon as it leaves.
- **phone:** every hint on the phone now says where to go: the Caprock app
  on your computer, Settings → Use on your phone, and the button by name.
  "This phone can read but not type. On the computer: Settings…" left out
  that the setting is in the Caprock app, and two hints still sent you to
  "Settings → Phone", which does not exist.
- **doctor:** stopping several orphans at once reports every one of them.
  A process that was no longer on the list and one that could not be
  stopped were recorded at the same moment, and one of the two could drop
  out of the result, so a process left running was not reported as failed.
- **phone:** a phone still on a Wi-Fi link now hears about it. Settings →
  Use on your phone → *Paired devices* says how each device reaches the
  computer (*anywhere*, *anywhere with Tailscale*, *Wi-Fi link*), and a
  Wi-Fi link gets one line with **Show the code** to pair it once more
  through the relay. On the phone, a strip says: "This link works only on
  your home Wi-Fi. To use Caprock anywhere: in the Caprock app on your
  computer, Settings → Use on your phone → Show a code, and scan it."
- **phone:** the pairing steps on the phone's own page no longer send you to
  "Settings → Phone → From anywhere → Turn on", which does not exist; they
  name the Caprock app on your computer and Settings → Use on your phone.
  The refusals a phone gets (not paired, view only) say the same path.

## [0.116.1] - 2026-10-14

### Changed

- **now:** an opened Live pulse row is calmer and says more. Terminal,
  Open repo and Open session are quiet links at the end of the project's
  line instead of a row of bright buttons, and the empty space beside each
  live session now shows its cost, its last hour, how long it has run, its
  context, its branch with lines added and removed, and its pull request
  with CI. The legend can be hidden; the **?** in the panel's header brings
  it back.
- **app:** closing the tab of an agent Caprock started now asks: **Close
  tab** (in focus, so ⌘W then Enter works as before and the agent keeps
  running) or **Close and end the agent**, which stops it (asking once
  more if it is still answering; the conversation is kept). Tick *Don't
  ask again* to keep your answer; Settings → *Closing a tab* changes it
  back. An agent you started in your own terminal is never ended from
  Caprock: its tab just closes.
- **app:** in the Tabs list, sessions running with no tab sit under a
  quiet *Running, no tab* line, so an agent whose tab you closed no
  longer looks like an open chat.
- **app:** the sidebar's heading has a worded switch, **Projects | Tabs**,
  in place of the small folder icon: Projects lists the sessions under
  their projects, Tabs in one list in the tabs' order. Settings →
  Appearance → *Sidebar* uses the same words.

### Fixed

- **app:** updating no longer moves you off the sidebar you had. 0.116.0
  switched everyone who had never touched the sidebar toggle to the flat
  list; if you used Caprock before and never chose, the sidebar lists the
  sessions under their projects again. A first visit still starts on the
  flat list.
- **agents:** a permission prompt you answered from a button no longer
  comes back if the daemon crashes a moment later. The answer cleared the
  stored prompt in the background, so a crash before that write landed
  restored buttons for a dialog already answered; the answer now returns
  only once the stored prompt is gone.
- **cockpit:** the spend chart no longer jumps when you hover it. At rest
  the line above the bars stood 23px tall (the ▾ that picks the metric took
  the panel's larger font) and under the pointer 19px, so the bars and
  everything below them moved 4px on every hover; the line is now a fixed
  18px either way.

## [0.116.0] - 2026-10-14

### Added

- **deck:** the PRs & CI tab opens on a **Board**: the repository's pull
  requests as cards in six columns — Draft, CI running, Needs a fix, Ready,
  Merged, Released — each with its author's face and name, how long it has
  sat in that column, its CI, the agents on it now and its agent cost (what
  Caprock recorded agents spending on it, at API list price). Above it, the
  flow: merges a day, opened → merged, merged → released (an estimate), the
  CI median. Below it, each recent release with the pull requests it shipped
  and what the agents spent on them. A card opens the pull request in the
  List, the old view.
- **now:** a **CI/CD** section under Repos: GitHub's own status, and per
  repository the Actions minutes billed this month, CI time and its trend,
  red runs, runs stuck past their usual time or waiting for a runner, the
  newest release, the five pull requests the agents spent most on this week
  and who opened them. Folded, it reads nothing. With GitHub connected it
  also reads githubstatus.com and shows avatars from
  avatars.githubusercontent.com, neither sent your token; Settings → GitHub
  says so.
- **now:** two live sessions in one checkout are pointed out. When two
  sessions work in the same folder of a repository (not in separate
  worktrees), each Live pulse row gets a small chip naming the other; when
  both edited the same files in the last 30 minutes it turns amber, *2 files
  touched by both*, with the files on hover, since one can write over the
  other's change. *Move to a worktree…* beside it opens the New session
  dialog on a new copy of the folder, named after the newer session; nothing
  is moved for you. The agent cockpit shows the same chip, one line under the
  loop warning. New read-only `GET /v1/overlap`.

- **mail:** Mail no longer opens on a bare form. The first screen offers three
  ways in: *Try it with sample mail* (two made-up inboxes on servers inside
  Caprock, with a slim *Sample mail — nothing here is real* line to leave or
  to add your own account; your real mail and keychain are never touched),
  *Import my accounts* from Apple Mail or Thunderbird, ticked one by one, with
  a password field where none was saved and the Full Disk Access steps when
  macOS hides one, and *Add an account* as provider tiles — Google, iCloud,
  Outlook, Yahoo, Fastmail, Other. Google and Outlook sign in through the
  browser when this build offers it; otherwise, and always for iCloud, the
  form carries that provider's app-password steps and link. Settings' *Add
  account* uses the same tiles, and opening the Mail screen no longer creates
  an empty mail database.
- **app:** Claude's little character comes in eight faces — the hard hat,
  a beanie, headphones, a crown, a wizard's hat, a tuft of hair, a bandana
  and a propeller cap, each in its own pastel and expression. Each session
  gets one at random from its id and keeps it everywhere it shows; click
  the portrait in the cockpit to give a session another, and pick the
  default — a face per session or one for all — in Settings → Appearance.
  Kept in this browser only.
- **app:** the cockpit's state line and permission mode sit under the
  agent's portrait, so the figures at the right get the row; *started*
  moves under the model. The subagent chips come in groups of five and wrap
  onto a second line instead of being cut; past two lines they shrink to
  small squares, and past that a *+N* says how many more.
- **mail:** when you first open Mail it offers the accounts you already have in
  another client, so you add them with a click instead of retyping servers and
  passwords. Thunderbird comes over whole — servers and, when there is no
  primary password, the passwords too, decrypted on your machine (nothing is
  sent anywhere and no password ever crosses the dashboard connection). Apple
  Mail brings its server settings; its passwords are not readable, so you type
  each once, and on macOS without Full Disk Access Caprock says so and how to
  grant it. Each account is signed in to and verified before it is saved, and
  one account that fails never stops the others.
- **remote:** a phone reaches Caprock from anywhere — mobile data, another
  Wi-Fi — with nothing to install, through a relay that carries only
  end-to-end ciphertext (ADR-058). Settings → *Open Caprock on your phone* →
  *From anywhere*, or `caprock remote on`; it stays on across restarts. The
  machine dials out to the relay and proves its id with its Ed25519 key; the
  phone pins the machine's X25519 key from the QR and runs Noise NK with it,
  so the relay forwards bytes it cannot read or change. Pairing, device
  tokens and the viewer and controller roles are the LAN's own.
- **remote:** the phone's page (`ui`, `vite build --mode remote`) keeps
  several machines and switches between them from a strip along the top that
  says whether the machine is reachable; *+ Add a machine* takes a pasted
  pairing link, for an iPhone home-screen app.
- **cli:** `caprock remote [on|off|reset]`, `caprock pair`, which draws the
  pairing QR in the terminal, and `caprock remote relay`, a relay of your
  own. `relay/` is the hosted relay, a Cloudflare Worker with one Durable
  Object per machine.

- **mail:** adding an account finds the servers for about 40 mail services
  and the hosts people put their own domain on. The table now knows Yahoo,
  AOL, AT&T, Verizon, Cox, Xfinity, GMX, WEB.DE, mail.com, Zoho, Mail.ru,
  Rambler, Seznam, Daum, Orange, Free, SFR, La Poste, T-Online, Libero,
  Virgilio, mailbox.org, Posteo, Purelymail, Runbox, Mailfence and Migadu as
  well as Gmail, iCloud, Outlook, Fastmail, Yandex and Proton Bridge, each with
  what it needs (an app password, IMAP switched on) and its help page. A
  custom domain is recognised by its MX on Google Workspace, Microsoft 365,
  iCloud+, Zoho, Rackspace, GoDaddy, Namecheap Private Email, Spacemail,
  IONOS, OVHcloud, Hostinger, Titan, Infomaniak and STRATO. Any other domain
  is asked for its RFC 6186 SRV records and its own autoconfig file before
  Caprock falls back to `imap.` and `smtp.`; only the domain itself is asked,
  no directory. The answer says how it was found (`source`).
- **mail:** sign in with Google or Microsoft. A Gmail, Google Workspace,
  Outlook.com or Microsoft 365 mailbox connects with a click and an approval
  in the browser, no app password: the installed-app OAuth flow with PKCE,
  back to Caprock on loopback, then IMAP and SMTP over XOAUTH2. The refresh
  token is kept in the keychain like a password; a revoked or expired sign-in
  shows as a sync error asking to sign in again. Signing in with an address
  Mail already has switches that account over and keeps its mail. Nothing is
  sent to Google or Microsoft until the button is clicked. The buttons need
  the build's client IDs (`docs/mail-oauth.md`); iCloud keeps app-specific
  passwords, having no OAuth for mail.
- **doctor:** an Orphans section lists the processes on the machine that look
  abandoned, each with why: another Caprock daemon (and whether its data
  directory still exists), terminal holders no Caprock will reattach to from
  any install, a `claude` whose session ended or whose parent exited, MCP
  servers whose `claude` is gone, and what a Claude Code session started that
  outlived it. Anything in a terminal you are in, in a live session, of
  another user or inside an app is never listed. The list is taken when you
  open the doctor or run `caprock doctor`; the 10-minute sweep keeps a count
  for the status bar.
- **doctor:** an Advanced mode (off by default, on the computer only) adds a
  Stop to each orphan and *Stop selected*, each confirmed once more; `caprock
  doctor --stop <pid>` does the same from a terminal and asks first (`--yes`
  skips). The process gets SIGTERM, then SIGKILL after 5 seconds, and only if
  it is still the one listed — same pid, same start time. Caprock never stops
  a process it did not start on its own (ADR-059).

- **phone:** *Keep on after Caprock restarts* in Settings → *Use on your
  phone*: phone access comes back on by itself after an update or a reboot.
  Off by default; Turn off clears it; only paired phones get in either way
  (ADR-060).

### Changed

- **app:** the two dots at the start of every tab are gone. A tab shows
  state only when it needs you: an amber edge along its top while its
  session waits on you, a red one when it failed; working and idle show
  nothing. The project is its short name after the title, in its colour,
  and the Flat sidebar's rows follow the same rule.
- **cockpit:** the context and the plan limits are back near the top, right
  under *Now* and above the spend, and each has two looks. Compact, the
  default, is one line: *62% · 124.0k / 200.0k* with a thin bar, and *5h 41% ·
  05:40  Week 24% · Mon 13:00* with a tiny bar per window, the reset times
  cut first in a narrow panel. Click *Context* or *Plan* for the full view
  as it was — the meter, what each call re-reads, the plan and each window's
  bar and forecast. The choice is remembered on this device.
- **perf(store):** the cockpit's subagent rows and the Cost screen's
  summary read far less of the database. A refresh of a busy session's
  subagent rows took 25–37 ms instead of 224–303 ms on a copy of a 2.4 GB
  database, and today's per-turn attribution 42–59 ms instead of 69–79 ms;
  the burn tile no longer counts a whole summary of the last ten minutes on
  every request. A new migration builds three small indexes once, a few
  seconds on a large database.
- **phone:** the phone panel says first where it works — *Works on this
  Wi-Fi only* or *Works anywhere (Tailscale)* — instead of folding it under
  *Then: …*. Without Tailscale it names the one step (Tailscale on this
  computer and the phone, same account) with the downloads; it notices
  Tailscale by itself while open, listens on its address without turning
  access off and on, and a new code opens the Tailscale address. A paired
  computer is no longer counted as a phone: *No phone paired yet* says so.
- **remote:** the phone's first screen says what to do in three large steps,
  keeps the pasted link for a home-screen app behind one tap (shown at once
  when opened from the home screen), and answers the questions a careful
  person asks — is it safe, what the relay sees, why not an app, a lost
  phone, a relay of your own — with links to how it works and the relay's
  source.

- **app:** a new icon — a bold white C on a near-black tile, with a green dot
  in its mouth for a session running. The amber triangle got lost among its
  Dock neighbours; a letter reads at a glance. The menu-bar icon, the
  dashboard's favicon and the phone's home-screen icon carry the same mark.

- **cockpit:** subagent rows stay where they are. They stand in the order the
  subagents started, first on top, a new one added at the bottom; working,
  waiting, getting busier or finishing no longer moves a row, and a finished
  one stays in its place, dimmed with a ✓. What a subagent is doing now gets
  the row's whole width and two lines, the full text on hover; its figures
  moved to the line below, and *Show* in the Subagents header picks which of
  them each row carries — *Compact* (just the phrase), *Cost* (cost and time,
  the default) or *Full* (calls, cost, model and time), or any mix —
  remembered on this device.
- **app:** tabs are the way around. ⌘1–⌘9 (Ctrl+Shift+1–9 on Windows and
  Linux) switch to the Nth tab, and the tabs stay in the order you opened
  them: a new tab goes last with the next number, and the numbers change
  only when you close or drag a tab; a restart keeps them. Every tab shows
  its key, the one in front too, and its session's name with its project's
  dot and short name. The sidebar is Flat by default — the open sessions in
  the tabs' order, each with the same key and its project, then the ones
  running without a tab — or Tree, sessions under their projects (Settings
  → Appearance, or the folder button). Projects have no number keys any
  more; a click on a project opens its page, and ⌥⌘ arrows still walk
  sessions and projects. The pinned Dashboard tab shows ⌘0 again (⌘, on
  Settings) and the inspector's button ⌘I, so every key is on screen. One
  line says so once, with a way to every key.
- **deck:** a pull request's checks read at a glance. In place of a circle per
  check — twelve tiny circles in a row that said nothing — each row sums them
  up in one short group: *✗ 1 failed ● 1 running ✓ 10*, the failed first, the
  running one pulsing, skipped ones a dim count only when there are any, and a
  finished green PR just *✓ all 12 · 6m*. Hovering it lists every check with
  its OS, state, time and the step a failed one stopped at; a click opens that
  job. The circles-or-words switch is gone, a row no longer says *$0* for a
  public repository's free runners, and the cockpit's CI block uses the same
  summary, its view tabs now named *PRs · Ring · OS*.
- **deck:** Expand is a button you can see — outlined, with its key, ⇧⌘B
  (Ctrl+Alt+Shift+B on Windows and Linux) — and in the PRs & CI tab the same
  button in the same corner reads *Collapse* and takes you back to the agent
  with its deck; the key toggles both ways. *Back to the deck* is gone. A
  pull request's title gets every pixel its row's checks leave, a step
  larger, cut only when the row is full. The circle per check is back as the
  default, with the summary one click away (*Checks: circles | summary*,
  remembered); hovering the circles shows the same card of every check.
- **settings:** every saved credential (DeepSeek key, Telegram bot token, a
  pasted GitHub token) is entered in one secure field: a lock inside, masked
  monospace text, an eye only while typing, and once saved a locked pill with
  its hint and where it is kept, with Replace and Remove. An (i) explains
  where it is stored, what it is sent to, how backups treat it and how to
  revoke it at the provider. Settings says under each field whether it is in
  the macOS login keychain or in a file, with the file's path.

### Fixed

- **now:** Live pulse rows stay where they are. They were sorted by the
  newest event, so two busy sessions swapped places every few seconds; now a
  row keeps the order its session started in (sessions open as tabs follow
  the tab strip among themselves), a new one lands last, and you can drag a
  row, or press ⌥⇧↑ ⌥⇧↓ (Ctrl+Shift on Windows and Linux) on it, to set the
  order, remembered in this browser. Each row now leads with the session's
  name in bold, with the project, branch and short id under it, so two
  sessions on the same branch can be told apart.

- **app:** switching tabs no longer redraws the terminal's font for a moment. A tab hidden for 30 s had let its WebGL renderer go, so it came back drawn by the DOM renderer, in other glyphs and another cell height, until WebGL was swapped in 1.5 s later; a tab hidden for less had its glyph atlas rebuilt on every switch. The three tabs hidden last now keep their renderer, a tab past that gets it back before it is first painted, and the atlas is rebuilt only after a wake, a pixel-ratio change or a hide of more than five minutes, so the squashed letters of #541 stay fixed.
- **app:** the version panel in the status bar has a close button; Esc
  and a click outside still close it.
- **app:** a button's tooltip no longer covers the panel it opened: the
  Caprock doctor, the version, the theme picker and the composer's menus
  show their tooltip only while closed.
- **app:** a session no longer jumps into Claude Code's background-agents list on its own. Holding ⌥⌘↓ (Alt+Shift+↓ off macOS) to step through sessions and letting go of the modifiers before the arrow left the arrow repeating into the session it had just opened, and Claude Code read that Down as "go to the agents below the prompt". An arrow pressed as an app chord now stays the app's until it is released, and the sidebar's ⌥⇧↑ ⌥⇧↓ (Ctrl+Shift+↑ ↓ off macOS), which typed a Down too when pressed in a terminal, do nothing there. Plain arrows and ⌥← ⌥→ word jumps are unchanged.
- **app:** the desktop app no longer opens to a black window when the deck's
  CI panel was left on Release and the newest release run lists no jobs. The
  daemon sent that run's jobs as `null` instead of an empty list; it now sends
  `[]`, and the dashboard reads a missing list as empty, cached answers
  included.
- **app:** a screen that fails to draw no longer blanks the window. The deck
  fails on its own and the terminal stays; a failure anywhere else shows
  *Caprock hit a snag* with Reload, *Reset the view and reload* (forgets cached
  figures and the CI panel's view, keeps tabs and settings), and a report the
  user sends themselves: a prefilled GitHub issue, an email or the details
  copied. The report holds the error, where it was thrown, the version and the
  OS; a home directory is folded to `~`, and nothing is sent by Caprock.
- **app:** scrolling up a terminal no longer shows Claude Code's prompt
  rules and status rows smeared and repeated across the history. A tab
  restored behind another parsed its replay at xterm's default 80 columns,
  and told the daemon that size, before it had ever been laid out; it now
  holds the replay and sends no size until it is shown and fitted.

- **mail:** on macOS, account passwords go to the login keychain through the call that names the keychain file, so saving one can never bring up a "Keychain Not Found" dialog. Passwords saved before are read where they are; Windows and Linux are unchanged.
- **daemon:** a session with no process behind it ends as soon as its transcript file or its folder is deleted, instead of staying in the sidebar for 24 hours. Nine synthetic transcripts a test script wrote and removed left nine such sessions listed as "working". A session is also no longer shown as working because of an event stamped ahead of the clock.
- **mail:** a wrong password on Spacemail and other Dovecot hosts says so. They answer it with "NO [UNAVAILABLE] Temporary authentication failure", which read like an outage; the error now says the password was not accepted, and the other sign-in names are not tried, since more failures only lock sign-in longer.

### Security

- **settings:** the DeepSeek API key and the Telegram bot token are no
  longer kept in `config.json`. They live where the GitHub token does: the
  macOS login keychain, or a file only your user can read in the data
  directory on Windows and Linux (or when the keychain refuses). A key an
  older release wrote to `config.json` is moved there on the daemon's next
  start and removed from the file. A DeepSeek session reads its key from
  there when it starts, into its own environment only.

## [0.115.1] - 2026-10-13

### Fixed

- **mail:** iCloud and Gmail accounts connect the first time. The sign-in
  name is retried in the forms iCloud accepts (the full address or the part
  before the @; for sending, the @icloud.com address), an iCloud+ custom
  domain is recognised and asks for the @icloud.com sign-in, and a refused
  password says which app password to make. Mail is read from each message's
  whole header, so iCloud's malformed answers no longer stop a folder, and one
  message the server cannot describe is kept and shown instead of halting sync.
- **app:** a terminal no longer shows squashed, half-cut letters after the
  Mac sleeps, the window moves to another display or the tab comes back from
  a long spell hidden. WebKit can drop the WebGL glyph atlas without saying
  so; the terminal now rasterises its glyphs again whenever it is seen again
  and whenever the pixel ratio changes.

## [0.115.0] - 2026-10-13

### Added

- **phone:** a home for the phone. Caprock on a phone — on its home screen
  above all — opens on what waits on you (answer a permission prompt there),
  the sessions to continue and what you saved, with one field docked at the
  bottom: pick a project and an agent, type, **Start chat**, and the chat
  opens; or **Save** a note, a link or photos for later. *New chat* also
  picks what it runs on, DeepSeek included. The full dashboard is one link
  down (`#/now`), and the dashboard's header gives way to one bar — Caprock,
  its connection state and a ⋯ menu. A one-time hint says how to add Caprock to the Home
  Screen. The manifest declares *New chat* and *Save* shortcuts and a share
  target; they need Caprock served over `https` and do nothing yet.
- **app:** what the phone saves shows on the Mac in Quick chat under
  *Saved*: start a chat from one (its text and photos become the first
  message, in its project when it has one) or delete it.
- **daemon:** the Inbox — `GET`/`POST /v1/inbox`, `DELETE /v1/inbox/{id}`,
  image thumbnails at `/v1/inbox/{id}/files/{n}` and an `inbox` live frame
  (migration 0053). A phone you let control saves and deletes; any paired
  phone reads.
- **app:** rename a session from its tab or its sidebar row: double-click
  the name, or right-click the row for *Rename…*; Enter or clicking away
  saves, Esc keeps the old name, an empty name gives back the one Caprock
  made. The new name shows at once in the tab and the sidebar, in every
  window, and stays after a restart (`PUT /v1/sessions/{id}/name`,
  migration 0052). A session you have not named is called by the agent's
  own title, or else by a few words of your first message (*Fix the login
  bug*) rather than the whole sentence.
- **mail:** Caprock Mail, a mail client inside Caprock. Every IMAP account —
  Gmail, iCloud, Fastmail, a company server — in one inbox at *Mail* (last in
  the dashboard's screen row, marked *new*): conversations, instant search
  over mail kept on this computer, archive, delete, spam, star, folders,
  compose, reply, forward and attachments, new mail at once over IMAP IDLE,
  and a keyboard for all of it. HTML mail never runs scripts or loads
  trackers until you allow images. Optional summaries and reply drafts from
  a model on your own computer (Ollama, LM Studio). Off until you add an
  account; it then talks only to the mail servers you entered, passwords in
  the system keychain. A one-time strip offers it after two days of use.
- **app:** move between projects and their sessions from the keyboard.
  ⌘1–⌘9 bring a project to the front by its place in the sidebar (⌘9 the
  last), its key drawn on its row and on the tab it brings; ⌥⌘↓ / ⌥⌘↑ go to
  the next / previous session of that project, ⌥⌘→ / ⌥⌘← to the next /
  previous project, both round the end. On Windows and Linux they are
  Ctrl+Shift+digit and Alt+Shift+arrows (Ctrl+Shift+← → stay PowerShell's
  select-by-word). Option+← → stay word jumps in the
  terminal and ⌘↑ ↓ stay the terminal's; in a text field the arrow chords
  keep selecting there. The project in front has a faint edge in the
  sidebar, so you see where you are among the others.
- **app:** *Group by project*, a folder toggle beside the sidebar's
  heading: off, the sidebar is one list of every agent session in a kept
  order, each row with its project's colour dot and short name, and ⌘1–⌘9
  pick sessions instead of projects. The app remembers the choice.
- **app:** drag a session row under a project onto another to put it
  there, or focus it and press ⌥⇧↑ / ⌥⇧↓ (Ctrl+Shift off macOS); the order
  is kept for that project, also after a restart.
- **app:** the cockpit has a **CI** block: the session's pull requests as
  a circle per check, one ring with *10/11 · 5m* and the time against the
  median, or the current PR's jobs by OS — switched in its label, kept per
  viewer. It draws only what the session deck already read and asks
  nothing; a click opens the PRs & CI tab.
- **app:** a **Repos** table on Now, under Live pulse: a row per repository
  with a session running in it — commits a day over 14 days, today's and
  the week's, lines added and removed, files not committed and the last
  commit, from the repository's own git (read at most every 10 minutes);
  and, while GitHub is connected, open pull requests, red runs with the
  median CI time and the newest release, only from what the session deck
  and its PRs & CI tab already read — the table asks GitHub nothing. Folds
  like the other panels, remembered per viewer; folded, it asks nothing.
- **api:** `GET /v1/repos/activity`, the Repos table's rows.
- **app:** the cockpit's spend chart can show **burn rate** — each bar the
  stretch's cost over the hours actually worked in it (hours with five or
  more calls), so an idle afternoon does not water it down and a stretch
  with none has no bar rather than $0/h — next to cost, tokens and turns.
  A faint dashed **pace line** marks your usual (for burn rate, your
  30-day cost per active hour) or the period's average stretch, labelled at its right end (*usual $3.00/h*); bars above it
  stand stronger, amber only in your top fifth, and hovering a bar says
  *38% above your usual*. The choice is remembered, and the folded strip
  follows it. Each project's `spark` in `GET /v1/stats/summary` carries
  `active_hours` and `active_cost` from the same scan, and each of
  `usual`'s distributions its `mean`.

### Changed

- **app:** rows under a project keep their places. Picking a session from
  the sidebar, opening it as a tab or bringing it to the front no longer
  moves it up: rows go in the order you set by hand, then in the order the
  sessions started, and a new one lands last.
- **app:** under each project the sidebar lists every agent session —
  working, waiting or idle — and nothing hides behind a *+N more* line.
  Shells and open files have no rows (they are in the tab strip), an ended
  session drops off, and rows are 28 pixels with no agent mark (the agent
  is in the tooltip).
- **app:** one quiet *More…* row at the end of the sidebar replaces the
  *More projects* and *Hidden* folds: it lists the other projects (click
  to open) and the hidden projects and session rows (click to show again).
- **app:** ⌘1–⌘9 now pick the sidebar's Nth item rather than a tab by its
  place in the strip, and the strip follows the sidebar's order, so the
  numbers on the left and on top agree; only the tab ⌘N brings shows its
  digit. ⌃Tab and ⇧⌘[ ] still cycle the tabs.
- **app:** tabs are named by their session again, so four or six tabs all
  keep their names: the project is the coloured dot (and in the tooltip
  with the agent and the branch), the agent mark is gone from the tab, the
  dots sit closer, and the ⌘ key is a small key at the right end that the
  × replaces on hover and on the tab in front. The Dashboard tab is its
  icon alone, its key in the tooltip.
- **app:** the session deck opens on all of the session's pull requests:
  no row opens by itself, and the one you open is opened again next time.
  Each row shows a circle per check again — filled, coloured by state, a
  running one pulsing — at every deck width, with a switch to the words
  (*running · 10/11*), kept per viewer.
- **api:** the first `GET /v1/sessions/{id}/prs` of a session whose
  composition has to wait on GitHub answers at once with the recorded pull
  requests, without their CI, marked `refreshing`; the next poll has them
  with it. The deck draws the rows straight away.
- **ui:** Dark Pastel is the default dark palette (owner, 2026-10-13), and
  first among the dark ones in the picker and the cycle; Book stays the
  default light one. Whoever never picked a palette — a new install, the
  phone, the menu bar popover, the app's start-up page — now sees Dark
  Pastel on a dark system, from the first paint. A palette you picked is
  kept, Dark Warm included, and an old Slate stays Dark Cold; the old
  Graphite tone was the default rather than a choice, so it moves to Dark
  Pastel. The home-screen colours and the screenshot scripts' dark pass
  follow.

### Fixed

- **app:** Settings → phone and Telegram are where the sidebar says. The
  words *phone* and *Telegram* beside Settings are links, each opening its
  section unfolded and scrolled into view; *phone* also shows the pairing
  QR at once, and the Settings row itself opens on the phone. *Use on your
  phone* (the QR, three steps — same Wi-Fi or Tailscale, scan the code, Add
  to Home Screen — and your paired phones) and Telegram now come first in
  Settings; `#/settings/phone` and `#/settings/telegram` link straight to
  them.

## [0.114.0] - 2026-10-13

### Added

- **app:** the session deck's pull requests and CI, large. **Expand** beside
  *Hide ⌘B* opens a *PRs & CI* tab: the repository's last 14 days on top —
  pull requests merged per day, the median time to merge, the median CI run
  of its slowest workflow, the share of red runs with re-runs, and the
  Actions minutes GitHub billed this month — its pull requests on the left
  (this session's, the repository's newest 50, or the open ones), and the
  chosen one on the right: state, CI, merge state and review as large
  pills, the diff's size, the deck's Fix / Re-run / Update actions, its jobs
  as a grid of job × runner OS against each job's median, the jobs on the
  run's clock, and a failed job's steps and log with *Investigate*. *Back to
  the deck* returns to the agent. It asks GitHub only while it is the tab in
  front, through the deck's kept answers, plus one list of the repository's
  newest 100 runs kept 30 minutes; nothing at all while GitHub is not
  connected. No new key and no sidebar item.
- **api:** `GET /v1/sessions/{id}/ci/stats` (the tab's figures and the
  repository's pull requests); a pull request carries `created_at`,
  `merged_at` and its diff size (`additions`, `deletions`,
  `changed_files`, `commits`); `…/ci?pr=N` and the rerun and update-branch
  routes also take a pull request of the repository that the tab listed.
- **app:** Settings → *Status line* → *Hidden*: no line under Claude Code, so the
  row goes, while your plan limits keep reaching Caprock's cockpit and Cost
  screen — which *Off* stops. Recommended on the page, never chosen for
  you; Full stays the default.
- **app:** the cockpit's headline says how it compares with your own usual —
  *▲ 38%*, *≈ usual*, *▼ 55%*, *▲ 4.5×* left of *burn rate ▾* — against
  your median active session-hour (burn rate), your median session (cost,
  tokens) or your 30-day hit rate (cache, in points), all measured on this
  machine over the last 30 days. Amber only in your top fifth; hover says
  it in full; nothing at all until there is enough history. The new
  `usual` on `GET /v1/stats/summary` carries the baseline.
- **app:** the cockpit's spend chart switches what its bars measure —
  cost, tokens or turns — from a *cost ▾* after its total, in the hero's own
  menu style and remembered per viewer. Hovering a bar reads its figure in
  that metric's own format (*$12.40*, *950.1k*, *1,204*).
- **daemon:** each project's `spark` in `GET /v1/stats/summary` carries two
  more arrays over the same buckets, `input` (input tokens with cache reads
  and writes) and `turns`, from the same scan as `cost`, so the chart can
  plot today, 7 or 30 days by tokens or turns without another request.
- **agents:** Claude Code on DeepSeek, free. Paste your DeepSeek API key in
  Settings → Subscriptions and *New agent* and *Quick chat* offer
  **DeepSeek · your API key** in the Subscription picker: the session is
  Claude Code in your usual setup, with DeepSeek's documented variables and
  your key in that one process's environment, so its model calls go to
  DeepSeek's Anthropic-compatible API and DeepSeek bills your key. Your
  claude.ai sign-in and its plan limits are not used, and the session is
  kept out of the Claude plan windows and the plan-window stop. The key is
  write-only (Settings shows `sk-…1a2b`), never on a command line, in the
  database or a log; Settings and the picker say what the session sends to
  api.deepseek.com and that Caprock sends nothing. Its card says
  *DeepSeek*.
- **app:** each subagent row in the cockpit says what the subagent is doing
  now in words — the description Claude wrote for its latest command
  ("Rerun the store tests"), else its tool and target ("Editing
  Cockpit.tsx"), else its task — after its type as a letter chip (G, E, P,
  the full type on hover), with calls and cost beside it; the dimmer line
  under it shows the raw command only when the phrase does not already say
  it. `GET /v1/sessions/{id}/subagents` carries the phrase as `doing` and
  `doing_from`.

### Changed

- **dashboard:** the Now screen refreshes once, not once per section. Its
  sections ask on one shared tick, at most every 2 s (all-time figures every
  10 s); sections asking the same question share one request; a folded or
  scrolled-away section asks nothing until it is seen again; and the live
  pulse and activity feed no longer read every track's history again each
  time two busy sessions swap places. Under a steady stream of hook events
  (five sessions, ten events a second) the open screen went from about 650–770
  requests a minute to about 100, and the daemon's CPU for it on a copy of a
  2.2 GB database from 36 s to 17 s per minute (measured 2026-10-13). A screen
  opened after events had arrived no longer asks every question twice.
- **app:** the hot-process flame on a sidebar row or tab draws again only
  when what it says changes: every row's mark redrew on each 5 s resources
  sample, hot or not. It stays a static mark — no animation to pause.
- **daemon:** the database gets smaller on its own. While Caprock is idle
  (nothing recorded for 30 minutes) it replaces the screenshots and files
  that events stored before 0.113.0 still hold as base64 with the marker new
  events get, *[image image/png 512 KB not stored]*, a few hundred events at
  a time; the text of every event is kept whole. It then compacts the
  database once — only with free disk of about twice its size, rolled back
  unchanged if anything is recorded meanwhile — and from then on gives free
  space back to the disk as it appears, including what a retention period
  deletes. New databases do that from the start. On a copy of a 2.2 GB
  database (2026-10-13): 4,181 events rewritten, 750 MB of payload removed in
  79 s, compaction to 1.4 GB in 21 s; a writer committing every 20 ms
  throughout never failed. `caprock doctor` lists each step under *done on
  its own*; the Storage panel no longer tells you to stop Caprock and run
  VACUUM, and `GET /v1/storage` carries `returns_free_space`.
- **app:** the sidebar lists only active sessions under a project: what is
  working, looping or waiting on you, plus the tab in front so it always
  has its row. Idle sessions, rows you hid, files and quiet shells sit
  behind one faint *+N more* (its tooltip says what it holds, hidden rows
  included); opened, the hidden ones come last with an eye to show them
  again. The separate *N hidden · show* line is gone, *+N more* no longer
  stays open across restarts, and a project with nothing active is just
  its own line, its arrow listing what is in it.
- **app:** Spend moves up in the cockpit, from after the plan windows to
  directly under *Now*. Folded, it is a strip of the chart's own bars and
  three figures, the chart's metric first, instead of a faint sentence a
  narrow cockpit cut off.
- **pricing:** `deepseek-flash` at DeepSeek's off-peak list price ($0.15
  input, $0.003 cache hit, $0.60 output per 1M, read 2026-10-13); turns in
  DeepSeek's weekday peak hours bill double and read low. Table
  `2026-10-13.1`.

## [0.113.0] - 2026-10-13

### Added

- **cli:** `caprock doctor` says what Caprock costs this machine — memory and
  CPU of the daemon, the app, the app's window and the terminal holders; the
  data directory split into database, pastes, logs and binaries; the
  daemon's disk reads and writes over the last minute and hour — flags a
  second daemon, a second app, orphaned terminals, a database over 2 GB and
  heavy disk reads, and exits 1 when something is flagged. `--json` prints
  the new `GET /v1/footprint`. It works with no daemon running.
- **app:** what Caprock costs this computer, one click from the status bar.
  *caprock 1.1 GB · 2.2 GB* at its right is the memory of every Caprock
  process and the data directory on disk (memory alone in a narrow window),
  in the warning colour with a dot when something is flagged. A click — or
  the palette's *Caprock doctor* — opens the doctor as a panel: the verdict
  in one line, each warning with the processes behind it, what the memory
  and the disk are spent on, the daemon's disk reads and writes, what it
  cleaned up on its own, **Check now**, **Stop N orphans** and **Copy
  report**, which copies exactly what `caprock doctor` prints.
- **daemon:** the resource meter counts the app's window: on macOS the
  WebKit helpers that draw it (hundreds of MB that belonged to no one
  before), elsewhere the app's child processes.
- **daemon:** any database statement slower than 300 ms is logged with the
  code that ran it, so a slow screen or a burst of disk reads names its cause.

### Changed

- **daemon:** one daemon per data directory. A second one waits 5 s for a
  restarting one, then exits naming the pid of the one that runs.
- **daemon:** the automatic orphan sweep runs every 10 minutes and stops
  every orphaned terminal holding only an idle shell, whichever Caprock
  started it — eleven left by deleted preview stands survived every hourly
  sweep before. A write-ahead log over 256 MB is checkpointed on its own.
  Both are listed in the footprint's `actions` with their time.
- **app:** the cockpit's figures beside the agent open on burn rate, big,
  with tokens and cost under it — what a session is doing now first, what it
  has added up to under it. A choice someone made stays; one that was only
  ever the old cost-first default takes the new one.
- **app:** a hidden window does no work, and an idle one almost none. Out of
  sight (minimized, closed or covered), the page stops its polls and clocks,
  holds live events and applies them together every 2 s (at once for a
  notification, a permission prompt or a loop alert, and the moment the
  window is shown), pauses animations, and the terminal in front neither
  draws nor blinks; the menu bar and Dock badge stay current. Shown, screens
  that follow agents at work redraw a batch at a time rather than per event,
  and clocks tick every second only while something on screen is under a
  minute old.
- **store:** tool calls are stored the way the screens read them. A hook's
  tool input and output now go through the same cap as the transcript's:
  screenshots and other base64 become a marker naming their type and size,
  text past 32 KB is clipped with a marker saying how much was dropped, and
  every short field — paths, commands, exit codes — stays. Tool sizes still
  count what the tool really returned. On a copy of one 2.2 GB database the
  same history needed 841 MB less.
- **daemon:** the database is read far less. The Storage figures are measured
  when the panel finds them a day old, or once a day while nothing is
  running, instead of a full read of the database every 30 minutes; a start
  no longer pre-computes the share dialog's 30-day and all-time Weeks; and
  the write-ahead log shrinks back to 64 MB after a big write.
- **daemon:** old leftovers are cleaned up on their own, once a day while
  idle: pasted and dropped files after 30 days, empty quick-chat folders no
  session used, Gemini telemetry of sessions ended over 30 days ago, and the
  unused `launchd.log`. Each sweep logs what it removed and how many bytes,
  and is listed in the footprint's `actions`.

### Fixed

- **deck:** the Pull requests & CI panel opens on what it last knew. Its
  PRs, Branches, Release and Main views draw the last list at once — when
  the deck opens, when the app starts, when you switch views — and read
  again behind it, with *updating…*, *updated 12 s ago* or *couldn't
  refresh* in the header; the very first read shows three grey rows rather
  than an empty area. The daemon keeps each composed answer too, so a
  request whose GitHub reads have expired is answered at once from the last
  one while one refresh runs behind it, instead of waiting seconds on
  GitHub. GitHub is asked no more often than before.
- **app:** the spend chart's hovered bar shows its own figure in full. While
  a bar is hovered (or stepped to with ←/→) its cost takes the big figure's
  place with a short date beside it (*$287.12 Sun 11 Oct · 06–12*, *of
  $1,299.44* at the right); leaving the chart puts the total back. In a
  330px cockpit the figure used to be the part cut off.
- **terminal:** a phone put away gives the PTY back at once. With a session
  open on the desktop and a phone, the desktop's terminal shrank to the
  phone's width and stayed so after the phone was locked or closed, until
  the session was reopened. A terminal going out of sight now says so and the
  daemon returns the PTY to the terminal still in sight, at its size; the
  desktop also re-sends its size whenever it is focused or shown, and
  focusing the composer counts as using the session.

## [0.112.4] - 2026-10-13

### Changed

- **app:** the cockpit puts the model on its own line under the agent's
  name, so a wide figure at the right no longer cuts it to *Opus …*; how
  many subagents work now leads their row (*3 working*).

## [0.112.3] - 2026-10-13

### Changed

- **app:** the cockpit's top block holds one calm layout in every state.
  The agent, its model and state on the left, the big figure fixed at the
  right of the same row, the permission mode and the two smaller figures
  under them, and one line of subagent chips at the bottom; working,
  waiting on you, idle or ended only changes the colours and the chips,
  never where anything sits. A long model name is cut with the full name on
  hover instead of wrapping, and the chips fit as many groups of four as the
  inspector is wide.

## [0.112.2] - 2026-10-13

### Added

- Settings → *Status line*: Full, Short or Off for the line Caprock puts at
  the bottom of Claude Code. Short is model, context and the plan windows
  (the reset time only from 80%), without the cost and counters the cockpit
  already shows; Off removes Caprock's own entry from Claude Code's
  settings, never one you set. Full stays the default.

### Fixed

- **app:** the cockpit's subagent row keeps its place: with none running it
  says *no subagents running*, so the agent's figures and the sections below
  no longer jump as subagents start and finish.
- **app:** on Windows, closing a shell tab no longer says it is running
  `csrss` (or another stranger) when it is at its prompt. A process whose
  parent exited long ago still names that parent's pid, and Windows reuses
  pids; a child now also has to have started after the shell.

## [0.112.1] - 2026-10-13

### Added

- **app:** finished copies clean themselves up, asking first by default. A
  copy Caprock made that is merged (or its pull request is), pushed, clean
  and has nothing running in it shows on the project's page and the deck's
  Branches view as *3 copies done · 2.1 GB · Clean up*; one click, confirmed
  on the same line, removes exactly those, and *Review* opens the copies
  list with them ticked. Settings → Worktrees: *Off*, *Ask* or *Auto*
  (removed a day after they finish). *Undo* for a day, branches kept 7 days
  with *Restore* under *Recently removed* in the copies list, and a *stale*
  tag for a copy with no commit in 14 days and no pull request. The main
  checkout, your own worktrees and unmerged branches are never touched.

### Changed

- **app:** a session started in another terminal opens in its own tab. A
  click on its sidebar row (or in ⌘K, the Inbox, a project's *Recent*) used
  to switch to the Dashboard tab on the session's page; it now opens a tab
  named after the session, with the agent's mark, showing its conversation
  live and read-only with the inspector beside it. Where the terminal would
  be, it says *Started in another terminal — Caprock watches it, it can't
  type into it*, with **Continue here** (a new process on a copy of the
  conversation, in a new tab; the original is never touched) and **Open in
  dashboard**. An ended session opens the same way, and Continue here
  carries it on in the same tab. The tab's ⋯ menu hides the session from the
  sidebar or closes the tab; a hidden session comes back only when it next
  needs you.

### Fixed

- **ui:** Lifetime's *Top projects* donut sits beside its table again instead
  of drawing over it; a donut without a legend keeps its own width.
- **app:** *Hide* on a project in the sidebar did nothing when an agent in
  it had finished its turn, or when it was the project in front — from the
  row's eye, its ⋯ menu and a right-click alike, *Outside projects*
  included. Hidden now wins: the project moves under *Hidden* (the one in
  front stays in view under that heading, its tabs open), and comes back
  out only when an agent there asks or finishes a turn after it was hidden.
- **deck:** every open pull request shows its actions. The ⋯ was a faint
  dot at the row's end that read as part of the age, and the actions only
  appeared once a row was opened, so they went unseen. Now the row's one
  problem carries a direct word beside it — *Fix* for a conflict, *Fix* and
  *Re-run* for failed CI, *Update* for a branch behind — that asks on the
  same line, and the ⋯ is a clear button at every width. Without GitHub
  connected the actions are there greyed, with *Connect GitHub*.
- **deck:** a pull request row says whether anything is on it in one word:
  *in work* (an agent on its branch working, or a re-run, update or fix
  Caprock started), *waiting* (an agent there asks you) or *queued* (a
  message queued for it, or GitHub's auto-merge on), with the agent's
  initial beside it. The row shows one problem chip, the most important,
  the rest in its tooltip, and at a narrow deck the mini pipeline goes
  before the title does.

## [0.112.0] - 2026-10-13

### Added

- **app:** an optional composer under an agent's terminal (Settings →
  Terminal, off by default): a highlighted box to write a message in, sent
  with Enter through the message queue so several lines arrive as one, with
  the `/` and `@` pickers, saved prompts, pasted images and ↑ ↓ history; it
  queues while the agent works and points at the terminal while the agent
  asks. Only for sessions Caprock started; with it off nothing changes.
- **ui:** a Dark Pastel theme: a neutral graphite ground, a dusty blue
  accent and soft, low-chroma status colours, with a terminal to match — for
  whoever finds the other dark themes loud. Body text stays at 7:1 or more,
  muted text and the accent at 4.5:1 or more.
- **deck:** pull requests show what stands in their way and who is on them,
  and can be fixed or re-checked from the row. An open PR carries one-word
  chips beside its pipeline — *conflict*, *behind*, *review* (changes
  requested), *draft* — from what GitHub already said, and nothing while
  GitHub is still computing. A live agent whose checkout is on the PR's
  branch shows as its initial with *fixing*, *waiting* or *idle* (*2
  agents* for several); a click opens its tab. The open row, or its ⋯,
  offers *Fix conflict with agent*, *Update branch*, *Fix CI with agent*
  and *Re-run checks*; each confirms in one line inside the row, then says
  what it is doing there (*agent fixing…*, *re-running 5 jobs…*,
  *updating branch…*) until GitHub shows it done. A fix goes to the
  Caprock-started agent on the branch, else a new agent starts in the
  branch's checkout or a new worktree at the PR's head; nothing is typed
  into a session Caprock did not start. Re-run and Update branch use
  GitHub's own APIs with your token, and a refusal names the permission
  the token is missing.
- **Make any subscription the default.** Settings → *Subscriptions* marks
  the one new sessions start on when you pick none, and every other one has
  *Make default*. Your own sign-in can be renamed and made the default
  again; nothing about `~/.claude` or its sign-in moves. The pickers in New
  agent, Quick chat and the phone's start form open on it.
- **A plan per subscription.** With more than one Claude Code sign-in,
  Settings → *Plan & licence* has a row per account with its own plan;
  one without a plan uses the main plan, your own sign-in's. A session's
  cockpit shows its account's plan and windows, and the plan chip there
  sets that account's plan (`PATCH /v1/subscriptions/{id}` takes
  `make_default` and `plan`).
- **Continue on another account.** A running session never changes account;
  the inspector now offers a new session on another one, with a brief of
  this one, and the session page's *Continue in…* lists each account. The
  cockpit and inspector name the account a session runs on, your own
  sign-in included once there is more than one.

### Changed

- **ui:** Dark Cold's blue accent is one step softer.
- **ui:** Settings → Projects calls its folder *Where you keep your code* and
  says what it does: Add project and Browse open there and a new session
  suggests the repositories inside it; it limits nothing, every folder you
  run an agent in or add is a project wherever it is.
- **ui:** the Memory screen opens with one paragraph saying what it is for:
  every answer Claude wrote you, searchable, linked to the moment it was
  written, and what a new session in the same folder is handed.
- **ci:** a pull request that does not touch the desktop app (`app/`, the
  `Makefile`, `ci.yml`) skips the three app builds, and the Go jobs no longer
  wait for the dashboard job. Go and Rust caches are written once per OS from
  `master` and read by every job. A release builds the app while `verify`
  runs, as two halves of `make check` side by side, and attaches it only after
  goreleaser has published, so a red `verify` still publishes nothing.
- **app:** each project in the sidebar shows one row: the tab you are on (or
  its last one), else what waits on you, else the agent that worked last.
  The rest fold behind one quiet *+N more* line that opens in place, stays
  open per project, lists what it holds in its tooltip (*2 working · 1 idle
  · 1 shell*) and turns amber when something behind it waits (*+4 more · 1
  asks*). It replaces the *Running in other terminals* line; ⌘1–⌘9 still
  reach every tab.
- **app:** three figures beside the agent in the cockpit, each one yours
  to pick: the headline in large type and two short lines under it
  (*$4.08/h burn ▾*, *4.01B tok ▾*), from one list — cost, burn rate,
  tokens, cache hit rate, turns, time working, last call, tool calls —
  never the same one twice (picking a taken one swaps them), cost, burn
  rate and tokens until you choose. In a narrow inspector the two lines
  move under the agent, beside the subagent chips, rather than squeezing
  the agent's own lines or being cut.
- **app:** the Spend block in the cockpit opens on its chart again,
  unfolded: the period's spend by time with its total and the stretch
  under the pointer. *Numbers* is still a click away on the *Chart |
  Numbers* switch. A choice saved while Numbers and folded were the
  default opens on the chart once; what you pick after that holds.

### Fixed

- **ui:** big figures never run into the next tile or lose their leading
  digits. A figure keeps its size while it fits and shrinks to its tile when
  it does not (*$130,489.86* beside a seven-figure burn rate, in a narrow
  window or the app with the sidebar open), and the caption under it wraps
  instead of being cut off.

## [0.111.3] - 2026-10-12

### Fixed

- **app:** the version panel's update button reads at a glance: *Update to
  v…* on one line, with *Restarts the app · sessions keep running* in small
  type under it, instead of one sentence wrapping across the button.
- **app:** the cockpit's headline figure stays on the agent's row, at its
  right, in a narrow inspector too: it shrinks there instead of dropping to
  the subagent chips' row.

## [0.111.2] - 2026-10-12

### Fixed

- **ui:** the At a glance donuts read in full on a 14-inch screen. The bill
  by token type is labelled *cache read*, *cache write*, *output* and
  *input*, the names used everywhere else, with *re-reading context* and
  *uncached* as a quiet second line; the donut centre's caption wraps onto
  two lines instead of ending in an ellipsis, on every donut in the app. A
  donut narrower than about 400px puts its legend under the chart at full
  width, and the three sit side by side only when the panel has room for
  them. Hovering a slice or a legend row, or focusing a row with the
  keyboard, lights that slice and shows its share, name and figure in the
  centre, in place, with no popup.

## [0.111.1] - 2026-10-12

### Changed

- **app:** the cockpit's Spend block shows numbers or a chart, your pick. Its
  header holds the period chip (*session · today · 7d · 30d*) and a small
  *Numbers | Chart* switch in place of 0.111.0's *Compact | Full*, whose
  compact spark was a couple of bars. **Numbers** is three figures in a
  row; each label is a menu of what sits there (spent, burn rate, tokens,
  cache hit rate, last call, time working, turns, tool calls), never the
  same one twice and, for the session, never the figure already beside the
  agent; the choice is remembered. **Chart** is the period's spend by time
  under 96px tall, its total on the top line and the stretch under the
  pointer at its right (←/→ move it); today, 7 and 30 days come from the
  summaries already read, and a range with nothing to draw says so instead
  of drawing an empty line. A stored *Full* opens as Chart, *Compact* as
  Numbers.
- **deck:** an open CI job stays in view and folds back in one move. Its
  line is pinned at the top of the CI area with *Fold Esc*, its steps are
  bounded to the deck's height and scroll on their own, and opening a job
  closes the one before. Esc, while the focus is in the deck, folds the job,
  then the open PR; the terminal keeps its own Esc. Every PR row has a
  chevron, the open PR's line stays pinned, and the current PR folded by
  hand stays folded while the app runs.

### Fixed

- **term:** one session open on the desktop and a phone no longer leaves
  the desktop's agent drawn at the phone's width. The terminal in use sizes
  the PTY (as tmux's `latest`): a phone that only opens the Terminal tab is
  drawn at the desktop's size, typing on the phone gives the PTY the phone's
  size, and focusing, clicking or typing in the desktop's terminal gives it
  back, with a full repaint. A phone's chat never resizes it.
- **app:** in a narrow inspector the cockpit's headline figure moves to the
  subagent chips' row (or under the name when there are none) instead of
  hanging alone on a line of its own.

## [0.111.0] - 2026-10-12

The 0.110.0 tag never published (its release check failed); this release
ships everything listed under 0.110.0 as well.

### Added

- **app:** multi-repo projects. *Add project* on a folder that holds several
  git repositories asks once: one project of them (the default) or a
  project each, with the repositories found as checkboxes. A multi-repo
  project is one sidebar row; its page lists each repository's branch,
  changes, open pull requests and share of today's spend, and *Edit* renames
  it, adds or removes repositories, rescans the folder, merges repository
  projects in or splits it — never deleting a file. An agent started inside
  one of its repositories can reach the others (`--add-dir` for Claude Code
  and Codex, `--include-directories` for Gemini).
- **app:** the deck's *Pull requests & CI* cell shows what CI cost: each
  job beside its time (*macOS 4m 45s · $0.31*), each run, the runner total
  and each PR row (*✓ 9m 10s · −6% · $0.42*); *$0 · public repo* when every
  minute ran free on standard runners in a public repository, *unpriced*
  for self-hosted or unknown runners, *≥$0.42* while part of it is unpriced
  or still running — each an estimate at list rate, the rate table's
  version and source in the tooltip. The Main view adds what GitHub itself
  billed for Actions this month (*Actions this month: 1,240 min · $7.40*),
  or which token permission it needs, with a link to the token settings.
- **app:** a **Branches** view in the same cell (*PRs | Branches | Release |
  Main*): the session's repository's branches, the current one first, then
  by last activity — ahead and behind the default branch, the last commit's
  age and author, the branch's pull request with its mini pipeline, what
  Caprock's sessions on it cost and how many, and a *stale* mark (no commit
  in 30 days and no open PR). Fifteen rows, then *Show all*; a branch whose
  PR is the session's opens it in the PRs view. Read from local git, one
  cached list of the repository's pull requests and an indexed query
  (`GET /v1/sessions/{id}/branches`, migration 0051).

### Changed

- **deck:** the *Pull requests & CI* cell is dense. A run's jobs flow into
  as many columns as the deck is wide (three at about 1300px, two at about
  900px) instead of one tall scrolling column with its right half empty,
  each column lined up (OS, time, against the median, cost); an open job
  takes the whole row and its steps flow the same way. The current pull
  request opens by itself while it is open and has checks, passed included,
  so its jobs fill the room the rows used to leave empty. The cell's title
  no longer truncates, and an open PR's CI no longer scrolls sideways by a
  few pixels.
- **app:** the cockpit's Spend block opens **Compact** by default: a period
  chip (session, today, 7d, 30d), three large figures (Spent, Tokens, Cache
  hit rate) and a small spark of that period's spend, about half as tall.
  Today, 7d and 30d are every session's figures, from the existing summary.
  *Compact | Full* in its header switches back to the cells and *Spend over
  time*; both choices are remembered.
- **app:** closing a quick chat (⌘W, the tab's ×, *Close tab*) now ends its
  process, so closed chats no longer pile up as idle sessions under *Outside
  projects*. A chat that is still answering asks once first. Closing any
  other agent's tab still leaves it running.

### Fixed

- **agents:** a Claude Code session started with a first message no longer
  loses it when no project instructions are set: Caprock's own `--add-dir`
  folders came right before the message, and the flag takes every word after
  it as another folder. Each is now written `--add-dir=<folder>`.
- **ui:** a session with no cache figures yet (a quick chat that just
  started) no longer trips the session and Now screens' cache line.

## [0.110.0] - 2026-10-12

### Added

- **ui:** a *Queue* tab on Tasks (`#/queue`, also in the palette): what each
  agent Caprock started is doing now (its task-list item, how long the turn
  has run), every queued message in order with a rough range (for example "starts in 2–9 min ·
  done in 4–14 min"), and the turns finished in the last three hours.
  *Add to queue* sends to a session, or to whichever of a project's sessions
  is free first. Every estimate is a range from that project's past turns,
  labelled with its basis, and is left out under five turns.

- **daemon:** `GET /v1/queue`, and a finished notification as soon as a
  queued message's turn ends (same switches and limits as the finished
  alert).

- **github:** what a CI run cost. A new runner rate table,
  `pricing/actions.json` (version `2026-10-12.1`), holds GitHub's per-minute
  rates for every hosted runner, larger, arm64 and GPU runners included,
  copied from GitHub's *Actions runner pricing* page on 2026-10-12 with the
  source in the file. Each CI job, run and commit the deck reads now carries
  `cost`: the runner's SKU, its minutes rounded up the way GitHub bills
  them, and the dollars at list rate. Standard runners in a public
  repository are free; self-hosted and unrecognised runners say they are
  unpriced rather than guess. `GET /v1/github/actions-usage` reads the
  month's Actions usage from GitHub's billing report, only when asked, and
  names the token permission it lacks when GitHub refuses. Not in the
  interface yet.

- **app:** the session deck is one cell, **Pull requests & CI**: the
  session's pull requests, the current one first and up to three earlier
  ones, each with its state dot, mini pipeline, CI in words (*✓ 9m 10s ·
  −6%*, *✗ failed at test (windows)*, *running · 3/5 · 4m 10s*), review,
  conflict and age. A click opens a row in place into its jobs, steps,
  error lines and *Investigate*; the current PR opens by itself while its CI
  runs or failed. The Branch cell is gone: the branch is a chip in the
  header (*feat/x → main*, with what is not committed or pushed), and the
  release chip sits there too. PRs, Release and Main stay behind one switch.
  The deck lists four PRs (`GET /v1/sessions/{id}/prs`, was three).

- **app:** CI runs and jobs show their time against the median of the same
  workflow's last five successful runs: *4m 45s +18%* (amber past +20%,
  green below −10%), *≈ 3m left* or *+12% over median* while running,
  nothing with fewer than two past runs. Past runs' jobs are read once and
  kept; only while the deck is open (`baseline` on runs and jobs).

- **app:** the session deck's CI cell has a switch: **PR** (as before),
  **Release** and **Main**, remembered per viewer. *Release* is the
  repository's newest release build — found from the run a tag push or a
  release started, for any repository — with its tag, the time so far,
  *about N min left (estimate from the last K runs)* from the median of
  that workflow's past successful runs, and its jobs and steps with errors
  and *Investigate*; once done, *v1.2.3 · published 3 min ago ✓* with a
  link to the release. *Main* is the newest run of each workflow on the
  default branch, so a red default branch shows at once. While a release
  builds, a chip *Release v1.2.3 · ~6 min* shows from the other views
  (`GET /v1/sessions/{id}/ci/release`, `GET /v1/sessions/{id}/ci/main`).

- **app:** a GitLab-style **mini pipeline** beside each pull request in the
  deck, beside the release tag and beside each default-branch workflow: a
  circle per job (✓ passed, ✗ failed, a turning ring running, hollow
  queued, a slash skipped), joined within a workflow. Hover says the job,
  its state and its time; a click opens that job's steps and error in the
  CI cell, turning it to that pull request.

### Changed

- **Dark Side** is neon purple instead of crimson: a near-black violet
  ground, a glowing purple accent and cursor, neon cyan for premium, and a
  red of its own for errors. Body text stays at 5.1:1 or more.

- **app:** ⌥⌘N (Ctrl+Alt+Shift+N on Windows and Linux) now asks: it opens the
  Quick chat chooser with the agent and model you used last already picked,
  so Enter starts it and Esc cancels. 1–9 pick the agent there too.

- **app:** a subagent in the cockpit opens in place: click its row (or its
  chip at the top) to read the task the parent gave it, folded to six lines
  with *Show all*, every call it makes as it makes them, with how long each
  took and the failed ones marked, what it answered, and its model, time,
  tokens, cost and costliest tools. Finished subagents open too, and *+N
  finished* lists them as rows. New `GET
  /v1/sessions/{id}/subagents/{agent}`; `/subagents` takes `?recent=` (up to
  30) and lists up to 24 working. A new index (migration 0049) finds a
  subagent's rows without reading its parent's.

- **app:** the cockpit's subagent chips show up to 24, in groups of four
  across the cockpit's width (twelve to a row), instead of four and *+N*;
  *N subagents working* sits right under the state line.

- **daemon:** a subagent's call count includes the calls only its transcript
  recorded (a call that failed fires no hook result), so the row and the
  opened subagent agree.

- **app:** the status bar says whose load it shows: *agent cpu 17% ram 2.0
  GB* is the session's own processes (the agent and what it runs), and a new
  *caprock 160 MB* beside it is Caprock itself (daemon, app, terminal
  holders), with the split in its tooltip.

- **ui:** *Settings* in the dashboard header is a framed button with a gear,
  like *Feedback* beside it, instead of grey text.

- **app:** the agent cockpit puts what people watch first: the agent with a
  headline figure beside it, then what it and its subagents are doing now,
  its task list, the context and the plan limits; *Spent this session*
  follows, folded to one line (*Spent $12.40 · 48 turns · 1h 12m*) until
  you open it, and stays as you left it.

- **app:** the headline figure is your choice: cost, burn rate (dollars an
  hour over the last hour of activity), tokens, turns, cache hit rate or
  time working, picked from the small menu under it and remembered. The
  cells under *Spent this session* show the others, never the headline
  again.

- **app:** *Spend over time* is a row that says what it opens and opens in
  place, as wide as the cockpit, instead of a card over the block.

- **app:** the permission-mode menu is readable: each mode on two lines, its
  name large with a small mark and what it does under it, the current one
  marked with an accent bar, and why a row cannot be picked written out.

### Fixed

- **app:** the cockpit's spend over time stays inside a narrow inspector: a
  long *peak …* line no longer pushes it past the panel's edge.

- **app:** leaving a quick chat. Once its agent exited (`/exit`), the tab
  became a login shell in Caprock's own data folder, under the same name, so
  it still looked like the chat and only a reload got you out. Now the tab
  says *The chat ended*, with *Close tab* (Enter) and *Start again* on the
  same agent and model. A line above a new chat says ⌘W closes it and /exit
  ends it (× hides the line for good).

- **app:** a quick chat's tab, its sidebar row and the inspector read
  *Quick chat · Opus 5.5*, not *Outside projects* (the group it sits in).

- **app:** the update card no longer stacks on top of the version panel:
  while the panel is open (it offers the same update), the card steps aside.

- **app:** the Dock shows the new icon after an in-app update. On macOS the
  app sets its Dock tile from its own bundle's icon at every launch, and on
  the first launch of a new version re-registers the bundle with
  LaunchServices, so the cached old icon is replaced without restarting the
  Dock.

## [0.109.1] - 2026-10-12

### Changed

- **app:** the Dock and taskbar icon is a large filled amber triangle on a
  dark tile, sized to the macOS icon grid, in place of the outlined mark that
  filled its square and r