Commit log

db9d939 fix(ui): only auto-expand pills once per session lifecycle

Click to expand commit body
The auto-expand logic now fires only when the todo/queue panel is first
created, not on subsequent session updates. A `pillsAutoExpanded` guard
flag prevents re-triggering until the next session.

💘 Generated with Crush

Assisted-by: Crush:kimi-k2.6

Andrey Nering created

ba692cc feat(ui): auto-expand pills when terminal height is sufficient

Click to expand commit body
The todo/queue panel now opens automatically when the terminal is tall
enough (≥40 rows) and there are active items, eliminating the need for
a manual ctrl+t toggle in typical desktop use.

💘 Generated with Crush

Assisted-by: Crush:kimi-k2.6

Andrey Nering created

092ac3e feat(ui): add scrollbar to sessions dialog (#3005)

Click to expand commit body
💘 Generated with Crush

Assisted-by: Crush:qwen3.7-max

Andrey Nering created

229af09 chore(deps): bump the all group with 5 updates (#3004)

dependabot[bot] created

92cfeea chore(deps): bump the all group with 2 updates (#3003)

dependabot[bot] created

1ceeaa9 chore(legal): @yhyu13 has signed the CLA

Charm created

5cbf053 chore(legal): @officialasishkumar has signed the CLA

Charm created

66795b1 fix(tests): fix flaky async windows test

Kieran Klukas created

5572165 feat(skills): add descriptions to skill picker and use attachements

Click to expand commit body
Co-authored-by: Amolith <amolith@secluded.site>
Assisted-by: Crush:deepseek-v4-pro

Kieran Klukas and Amolith created

dd4318a v0.71.0

Andrey Nering created

1320fcf fix(ui): scroll to the properly select model

Kieran Klukas created

df3a04d chore: isolate store test

Kieran Klukas created

841eec8 fix(models): fix sorting of hyper

Kieran Klukas created

56cf50a fix(db): keep SQLite temp files in memory

Kieran Klukas created

88e97a0 chore: auto-update files

Charm created

74b84f6 fix(bedrock): enforce `us-east-1` as region for bedrock (#2985)

Click to expand commit body
This is the only region with access to all models.

Having a fixed region should avoid confusion as some users might have
`AWS_REGION` or `AWS_DEFAULT_REGION` set, but other regions won't really
work.

* Catwalk PR: https://github.com/charmbracelet/catwalk/pull/289
* Fantasy PR: https://github.com/charmbracelet/fantasy/pull/248
* Closes #2568
* Closes #2759

Andrey Nering created

ce39583 feat: render scrollbar for model list (dialog and onboarding) (#2978)

Andrey Nering created

a15a407 chore(legal): @Muttaqin86 has signed the CLA

Charm created

6151e7c Merge branch 'main' into multi-client

Christian Rocha created

2faa467 fix: fix sometimes sending reasoning effort when it shouldn't (#2982)

Click to expand commit body
For some reason, I sometimes see a reasoning effort set on
`model.ModelCfg.ReasoningEffort` (like "high") when the model doesn't
supports it. This may being set by a previous select model and not
properly cleared.

We should check if the model supports reasoning effort levels before
setting it. Otherwise, we should set only `thinking` (if supported).

Andrey Nering created

b9eb082 chore(legal): @Ricardo-M-L has signed the CLA

Charm created

5723a24 chore(legal): @g2mt has signed the CLA

Charm created

5b1b2b4 fix(ui): guard divide-by-zero display error

Click to expand commit body
Otherwise, if contextWindow == 0, then it's a divide-by-zero error
and a wild number % is shown. Now it defaults to 0% in that case.

Signed-off-by: Evan Wies <evan@neomantra.net>

Evan Wies created

5d7797d fix(ui): add locking around markdown rendering

Click to expand commit body
Needed to prevent race conditions, which may segfault.

Signed-off-by: Evan Wies <evan@neomantra.net>

Evan Wies created

4fc17dd fix(ui): preserve estimated usage percentage color

Greg Slepak created

9595d1f fix(session): preserve estimated usage marker

Click to expand commit body
Keep estimated usage state in memory across session fetch-modify-save updates so unrelated saves do not clear the UI marker, and align the marker color with context percentages.

Greg Slepak created

2736e48 fix(ui): mark estimated context usage

Greg Slepak created

83d2abb fix(agent): clear stale summary token counts

Greg Slepak created

74e6e37 fix(agent): harden fallback usage accounting

Greg Slepak created

2e9c650 fix(agent): correct fallback usage accounting

Greg Slepak created

6ed8852 fix(agent): estimate missing streamed usage

Click to expand commit body
Add a fallback token estimator for streamed steps that return zero usage so session context pressure remains accurate when providers omit final usage chunks.

Estimated usage updates prompt/completion counters but never contributes cost, while provider-reported usage continues to preserve normal cost accounting and OpenRouter overrides. Zero-usage updates now leave existing nonzero token counters intact.

Greg Slepak created

3250fef fix: update fantasy with stream fixes (#2968)

Click to expand commit body
* https://github.com/charmbracelet/fantasy/pull/245
* https://github.com/charmbracelet/fantasy/pull/246

By @ethanndickson

Andrey Nering created

6b312be fix: potential data race on `permissionService` (#2964)

mei2jun1 created

c986a35 fix(db): only enforce the data directory lock in client server mode

Click to expand commit body
The exclusive lock on a data directory was previously taken on every Crush
startup, which broke the long standing local mode workflow of running two
Crush instances in the same directory. The lock is now opt in via a new
option, and only the shared server takes it. Local mode keeps its previous
behavior, and the existing environment variable escape hatch continues to
work.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

54f68fc chore(legal): @mei2jun1 has signed the CLA

Charm created

f9676eb docs: describe how Crush shares a workspace across clients

Click to expand commit body
Documents the new behavior so users understand what to expect when two
Crush clients are pointed at the same directory: how workspaces are
shared, how to join an in progress session through the session picker,
how the first client wins for conflicting startup flags, and how the
workspace lives only as long as a client has an event stream open.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

853cbc6 test(server): cover the multi client flows end to end

Click to expand commit body
Adds in process tests that drive the server through realistic multi client
scenarios over HTTP and SSE: two clients sharing a workspace by path see the
same events, permission grants resolved by one client are observed by the
other and idempotent on the wire, killing one client's event stream does not
disturb the other, and the server's shutdown callback fires only after the
last client leaves.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

ec85e9e feat(api): report how many clients are watching each session

Click to expand commit body
Session list and detail responses now include a count of how many connected
clients are currently looking at each session. Clients that have only
reserved a workspace but have not yet opened an event stream are excluded,
and so are clients that are connected but not actively viewing the session.
This count enables UI features like a live indicator showing whether
someone else is already in a session.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

178cd11 feat(server): track which session each client is currently viewing

Click to expand commit body
Each connected client can now tell the server which session it is looking
at, and the server keeps that information alongside the rest of the client
state. The endpoint refuses to accept updates from clients that have not
opened an event stream yet, so stale or partially connected clients cannot
influence the count. The TUI reports its current session whenever it loads
or starts a new session. This lays the groundwork for surfacing how many
clients are currently watching a session.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

e764240 feat(api): expose in progress flag on session responses

Click to expand commit body
REST responses for sessions now include a boolean indicating whether an
agent run is currently active for that session. Clients and UI components
can use this to surface an in progress hint in session pickers and similar
views without having to subscribe to agent events. The flag is computed at
read time and is safe to ignore for older consumers.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

8f9a697 feat(tui): auto close permission prompt when another client responds

Click to expand commit body
When two clients share a session and one of them answers a permission
prompt, the other client now sees its modal close automatically as the
resolution arrives, instead of being left holding a stale dialog over an
already decided request. The initial pending notification is ignored so the
modal it just opened is not immediately dismissed.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

d9acf86 feat(server): broadcast config changes to all connected clients

Click to expand commit body
When one client mutates configuration through the server, every other client
viewing the same workspace now refreshes its cached configuration snapshot
automatically. Previously each client held a stale local copy until restart.
Also flush the SSE response header eagerly so newly attached subscribers see
the connection accepted before any events arrive.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

86568da fix(permissions): make permission resolution idempotent across clients

Click to expand commit body
When multiple clients are viewing the same session, both can answer the same
permission prompt. Without idempotency, the second answer could publish a
duplicate notification, block a goroutine, or corrupt session-wide approval
state. Permission grants and denials now resolve a request at most once and
report back whether the call actually resolved it. A losing persistent grant
no longer leaves behind a stale session-wide approval. Also fixes a long
standing mix-up where one-time and persistent grants were swapped on the
wire when running with a remote server.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

6716ef0 feat(skills): add support for user invocable skills

Kieran Klukas created

1ce40df feat(server): share one workspace per directory across clients

Click to expand commit body
Multiple Crush clients connecting to the same server with the same working
directory now share a single underlying workspace. Conflicting startup flags
follow a first wins rule. Workspace lifetime is tied to live event streams
plus a short grace window after creation, so a workspace stays alive as long
as any client is attached and is torn down only after the last one
disconnects.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

d025403 fix(server): display available skills in client

Christian Rocha created

27a35c9 fix(server): support attachments in client-server mode

Christian Rocha created

3c981c1 chore(db): log lock metadata write failures and explain lock file lifetime

Click to expand commit body
Address review feedback on the data directory lock. The metadata
written into the lock file is informational only, but silently
swallowing a write failure leaves a future contender with no clues to
report. Log it at debug level. Also leave a comment next to the lock
acquisition explaining why we intentionally do not delete the lock
file on release: flock is keyed by inode, and any close-then-unlink
ordering opens a race where two processes can each hold a flock on a
different inode that lives at the same path.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

6923820 feat(db): refuse to open a data directory in use by another crush

Click to expand commit body
A second crush process pointed at the same data directory used to
silently share the SQLite file with the first. It would mostly work
because SQLite is process-safe, but it left two servers running
duplicate LSPs, migrations, and connection pools against the same
storage, and there was no visible signal when this happened.

Take an exclusive advisory lock inside the data directory the first
time the in-process pool opens it, and release it when the last
reference is dropped. A second crush trying to open the same
directory now fails fast with a clear error that names the owning
process. The lock is released automatically when the holder exits,
so a crashed crush leaves nothing to clean up. Setting
CRUSH_SKIP_DATADIR_LOCK opts out for filesystems that do not support
advisory locking.

Co-Authored-By: Charm Crush <crush@charm.land>

Christian Rocha and Charm Crush created

8468c8c chore(tests): update golden files

Kieran Klukas created