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>
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.
Also, two local skills now exist for Crush development:
* builtin-skills, for adding new builtin skills
* shell-builtins, for adding new shell builtins
This panic happen once in a while on CI on Windows specifically.
I personally never saw it happening myself, but I think it's possible
to happen for the end user on Windows as well.
Looks like a potential bug on the interpreter, but in the meantime let's
at least recover from the panic and gracefully handle it.
panic: ended up with a non-nil exitStatus.err but a zero exitStatus.code
goroutine 61 [running]:
mvdan.cc/sh/v3/interp.(*Runner).Run(0xc000220848, {0x1415220e0, 0xc00021a1e0}, {0x14151e088, 0xc00025a600})
C:/Users/runneradmin/go/pkg/mod/mvdan.cc/sh/v3@v3.12.1-0.20250902163504-3cf4fd5717a5/interp/api.go:929 +0x6b2
github.com/charmbracelet/crush/internal/shell.(*Shell).execCommon(0xc000256360, {0x1415220e0, 0xc00021a1e0}, {0x14135a250, 0x9}, {0x14151baa0, 0xc00025a540}, {0x14151baa0, 0xc00025a580})
D:/a/crush/crush/internal/shell/shell.go:273 +0x285
github.com/charmbracelet/crush/internal/shell.(*Shell).execStream(...)
D:/a/crush/crush/internal/shell/shell.go:288
github.com/charmbracelet/crush/internal/shell.(*Shell).ExecStream(0xc000256360, {0x1415220e0, 0xc00021a1e0}, {0x14135a250, 0x9}, {0x14151baa0, 0xc00025a540}, {0x14151baa0, 0xc00025a580})
D:/a/crush/crush/internal/shell/shell.go:111 +0x139
github.com/charmbracelet/crush/internal/shell.(*BackgroundShellManager).Start.func1()
D:/a/crush/crush/internal/shell/background.go:122 +0x15f
created by github.com/charmbracelet/crush/internal/shell.(*BackgroundShellManager).Start in goroutine 28
D:/a/crush/crush/internal/shell/background.go:119 +0x72a
* refactor(fsext): improve hierarchical ignore handling and consolidate file exclusion logic
- Refactor FastGlobWalker to use directoryLister for consistent ignore handling
- Add ShouldExcludeFile function for unified file exclusion checking
- Add WalkDirectories function for directory traversal with ignore support
- Improve directory pattern matching by checking both with and without trailing slash
- Add comprehensive tests for hierarchical ignore behavior and common patterns
- Remove direct dependency on go-gitignore in favor of existing directoryLister implementation
💖 Generated with Crush
Co-Authored-By: Crush <crush@charm.land>
* fix: improvements
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* chore: t.Context()
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
* fix: tests
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
---------
Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Crush <crush@charm.land>
- Simplify command blocking logic by using utility functions instead of complex closures
- Add sudo to banned commands list
- Move command blocking from bash tool to shell layer for better separation of concerns
- Add comprehensive tests for command blocking functionality
- Fix test isolation by using temporary directories to prevent npm package files from polluting source tree
- Remove redundant command validation logic from bash tool