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)
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
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
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
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.
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
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>