c9fd6be
fix(shell): convert path to posix path in tests
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
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
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
eaf1cd7
chore(ui): change wording: rewrote input to rewrote output (#2742)
Christian Rocha created