Commit log

3d95ca9 bug: yollo mode via flag doesn't activate prompt

Kieran Klukas created

c9fd6be fix(shell): convert path to posix path in tests

Kieran Klukas created

452cd75 feat: add Nix flake for development environment (#2512)

Kieran Klukas created

b64cb02 chore(legal): @ardevd has signed the CLA

Charm created

3aa26d9 v0.65.3

Andrey Nering created

ecebe91 chore: auto-update files

Charm created

812d78b chore(deps): update catwalk

Andrey Nering created

99bc5ce fix(config): check config file for newer token before OAuth refresh

Click to expand commit body
When refreshing an OAuth token (e.g. for Hyper), check the config file
on disk first to see if another Crush session already refreshed it.
If the disk token differs from the in-memory one, use the disk token
and skip the external refresh request. Prevents unnecessary token
churn and 401s when multiple Crush sessions are running.

💘 Generated with Crush

Assisted-by: Kimi K2.6 via Crush <crush@charm.land>

Andrey Nering created

1ed6f52 refactor(ui): pair markdown cache invalidation with the styles mutation

Click to expand commit body
This is an additional guard to invalidate the cache in the off-chance
styles are mutated (rather than updated via applyTheme(), as they
should be).

Christian Rocha created

19197e3 fix(ui): cache glamour renderers

Click to expand commit body
The theme prep overhaul in 755f6fa made the main markdown renderer and
thinking block markdown renderer heavier, which exasperated a gap in
perf. Basically every token chunk would clear would clear the per-item
render cache and force a re-render.

This update memoizes renderers with markdown and should generally
give us a nice increase in perf compared to what we had before the theme
rendering.

Christian Rocha created

4010841 fix(db): prevent SQLITE_NOTADB corruption under concurrent sub-agents (#2690)

Click to expand commit body
Crush could fail to start with "file is not a database (26)" after a
session ran many sub-agents in parallel. The shared *sql.DB was opened
with Go's default unlimited connection pool, so each concurrent sub-agent
(session/message/cost writes via coordinator.runSubAgent) could open its
own SQLite handle. Under load, WAL frames from different handles
interleaved and auto-checkpoints could race; if the process was cancelled
or killed mid-checkpoint, the main DB header and WAL desynced, producing
SQLITE_NOTADB (26) on the next open.

Two changes address this:

- Set db.SetMaxOpenConns(1). SQLite serializes writes at the file level
  anyway, so extra pool connections add no throughput, only race surface.
  Forcing a single pooled connection makes database/sql queue all callers
  through one SQLite handle, eliminating cross-handle WAL/checkpoint
  races. Sub-agents still function; their writes just serialize (which
  SQLite was going to do regardless).

- Add _txlock=immediate to both driver DSNs (modernc.org/sqlite and
  ncruces/go-sqlite3). BEGIN IMMEDIATE acquires the reserved-writer lock
  up front so concurrent writers queue cleanly on busy_timeout instead of
  racing the deferred-to-writer upgrade (the pattern behind prior
  SQLITE_BUSY reports, e.g. #2129, #2576). Defense in depth alongside the
  pool limit.

For the ncruces driver the DSN must use the file: URI prefix for query
params to be parsed; the plain path form silently ignores _txlock.

Greg Slepak created

481202e chore(deps): bump the all group with 4 updates (#2795)

dependabot[bot] created

81e4d5a chore(deps): bump github/codeql-action in the all group (#2794)

dependabot[bot] created

b5c8a6d chore(legal): @ilgax has signed the CLA

Charm created

f913477 config: remove unused environment variable resolver

Click to expand commit body
The hand-rolled $VARNAME-only resolver (NewEnvironmentVariableResolver)
had no production callers. Tests have been switched to the shell
resolver, which is what production already uses, and the dead type
plus its tests are gone.

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

Christian Rocha and Charm Crush created

06f4350 docs(skill): document shell expansion in crush-config skill

Click to expand commit body
Adds a Shell Expansion section to the skill that covers the
supported syntax, the quiet-unset default, which fields expand
(LSP args and env and MCP url included), that extra_body does not
expand, the empty-header drop rule, and a short security note. The
provider, LSP, and MCP subsections now link to that section instead
of suggesting $ENV_VAR is the only option.

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

Christian Rocha and Charm Crush created

45f7484 docs: update resolver godoc to match lenient default

Click to expand commit body
The godoc on the shell variable resolver still said unset variables
were a hard error. Updated to match the new lenient default and to
point at ${VAR:?message} as the way to require a value.

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

Christian Rocha and Charm Crush created

a28aded test: realign MCP init tests with lenient shell expansion

Click to expand commit body
Several MCP startup tests were written against the old "unset
variable is an error" behavior and no longer tripped now that
missing variables quietly expand to empty. The fixtures switch to
$(false) or an empty URL so the failing and empty paths are still
covered, and a couple of new subtests pin the new quiet behavior so
it cannot silently regress.

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

Christian Rocha and Charm Crush created

bcce662 docs: document lenient shell expansion and security model

Click to expand commit body
Updates the README and a handful of struct docs to describe the new
behavior: missing variables expand to empty, ${VAR:?message} is the
way to require a value, empty header values are dropped, extra_body
is a plain JSON passthrough, and crush.json should be treated as
trusted code because any $(...) in it runs at load time with the
user's shell privileges.

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

Christian Rocha and Charm Crush created

71aa8d1 test: pin provider skip behavior for api_key and endpoint expansion

Click to expand commit body
Pins down that a provider with a missing or broken api_key is still
skipped with a warning, now that unset variables quietly expand to
empty instead of erroring. Azure-style api_endpoint is covered the
same way. Tests only, no behavior change.

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

Christian Rocha and Charm Crush created

1f83559 lsp: expand shell variables in args and env

Click to expand commit body
LSP args and env values used to be passed to the language server as
raw strings, so "$HOME/go" was sent literally. They now go through
the same shell expansion already used elsewhere in the config. If
expansion fails, that LSP fails to load with a message that points
at the specific arg or env key.

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

Christian Rocha and Charm Crush created

f23e998 config: fail provider header expansion loudly and drop empty values

Click to expand commit body
Provider extra_headers used to log and keep the raw template when a
command inside the header failed. A failing command now stops the
provider from loading, with a clear error that names the provider
and the header.

Headers whose value ends up as an empty string are dropped from the
outgoing request, so "OpenAI-Organization": "$OPENAI_ORG_ID" keeps
working when the variable is not set. MCP headers follow the same
rule.

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

Christian Rocha and Charm Crush created

c3cf962 test: update config tests to match lenient expansion

Click to expand commit body
Updates tests that assumed missing variables in config values were
an error. They now expect an empty string, matching the new default.
New tests cover ${VAR:?message}, which is the way to still fail
loudly when a variable is required.

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

Christian Rocha and Charm Crush created

abacef9 shell: switch config value expansion to lenient by default

Click to expand commit body
Missing env vars in crush.json used to fail loudly. They now quietly
expand to an empty string, the same as bash. If you want the old
strict behavior for a specific value, write it as ${VAR:?message}
and Crush will still complain when the variable is not set.

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

Christian Rocha and Charm Crush created

4be35b8 chore(legal): @somjik-api has signed the CLA

Charm created

4068422 test: use forward slashes in shell commands for Windows compat

Click to expand commit body
Windows t.TempDir() returns C:\... paths whose backslashes get
consumed as escapes when injected into $(cat ...). Convert to
forward slashes so the embedded shell resolves the path on every OS.

Also accept the Windows coreutils error shape ("cannot find") in
addition to POSIX "exit status" when asserting that inner diagnostic
detail is surfaced — mvdan/sh runs coreutils in-process on Windows
so there is no subprocess exit status to report.

Christian Rocha created

d745ff5 docs(README): add note about shell expansion in MCP config

Christian Rocha created

240e5c2 test: cover shell expansion in MCP config resolution

Christian Rocha created

f716457 feat(config): resolve MCP url through shell expansion

Click to expand commit body
m.URL now runs through the same resolver as command, args, env, and
headers so $VAR / $(cmd) work in http and sse endpoints. The empty-url
guard runs after resolution so ${X:-} still fails cleanly, and failing
expansions surface via the existing StateError path.

Christian Rocha created

dbd40d8 feat(config): resolve MCP args and thread resolver through env/headers/args

Click to expand commit body
Adds MCPConfig.ResolvedArgs and changes ResolvedEnv/ResolvedHeaders to
take a VariableResolver, so createTransport threads one resolver through
command, args, env, and headers. Client mode (IdentityResolver) now
keeps all four fields literal for server-side expansion; server mode
expands uniformly via the shell resolver.

Christian Rocha created

c135266 refactor(config): make Resolved{Env,Headers} pure and error-returning

Christian Rocha created

5dc30cf refactor(config): resolve shell vars via shell.ExpandValue

Click to expand commit body
Rewires shellVariableResolver onto the embedded shell interpreter used
by the bash tool and hooks, replacing the hand-rolled parser. Adds a
bounded, scrubbed sanitizeResolveError so resolution failures surface
safely without leaking oversized or non-printable inner stderr.

Christian Rocha created

711d3a3 feat(shell): add ExpandValue for config value shell expansion

Click to expand commit body
Groundwork for replacing the hand-rolled parser in internal/config/resolve.go.

Introduces shell.ExpandValue, a single-value expansion entry point built
on mvdan.cc/sh/v3's syntax + expand packages. Runs with nounset on and
globbing off, preserves internal whitespace, strips only trailing
newlines from command substitution output, and bounds/scrubs inner
stderr surfaced in errors. Shares the builtin/block/coreutils handler
chain with NewShell but uses the caller-provided env verbatim.

Christian Rocha created

56b192e v0.65.2

Andrey Nering created

63e03ff v0.65.1

Andrey Nering created

0f3a6cd ci: remove snapcraft token

Click to expand commit body
See: https://github.com/charmbracelet/meta/commit/86917ec06aa42153f5e48cb2570dfc5efd1e389d

Andrey Nering created

77d86b8 v0.65.0

Andrey Nering created

ce314b8 feat(ui): add hypercredit readout to small top header

Christian Rocha created

d5b5a9e chore(ui): hypercrush small type treatment

Christian Rocha created

a93277f chore(legal): @pragneshbagary has signed the CLA

Charm created

0a9d0b0 chore(legal): @mkaaad has signed the CLA

Charm created

bae9299 chore(legal): @SAY-5 has signed the CLA

Charm created

98f9a17 chore: auto-update files

Charm created

a14feb3 feat: launch hyper beta (#2768)

Click to expand commit body
No need to set `HYPERCRUSH=1` anymore.

Andrey Nering created

6ce4fbc feat(hyper): show remaining hypercredits in the sidebar (#2766)

Andrey Nering created

5d8f924 test: re-record test fixtures

Andrey Nering created

f36f65b chore: update `view` tool limit to 200KB

Click to expand commit body
The model was enable to edit `internal/ui/model/ui.go` for me, because
it has ~ 108KB and the limit was 100KB.
(Without being able to read, the model also can't update it).

We're keeping the `fetch` tool limit to 100KB.

Andrey Nering created

c7368b7 fix: fix thinking on/off toggle for certain openai-compat providers

Andrey Nering created

59e9233 refactor(hyper): simplify by removing old code

Andrey Nering created

54a57fd chore(legal): @carlosgrillet has signed the CLA

Charm created