Summary
Add a sidecar system that allows kidd-powered CLIs to define, download, and ship external binaries (e.g., rg, fd, ast-grep) alongside the compiled CLI. Similar to Tauri's sidecar concept and the existing implementation in @joggr/cli (serenity).
Current state
- Compile infrastructure exists —
packages/bundler/src/compile/compile.ts already produces multi-platform binaries via bun build --compile for 7 targets
- Config system is extensible —
packages/config/src/types.ts defines the kidd config schema
- Download pattern exists —
packages/core/src/middleware/icons/install.ts demonstrates downloading + extracting from GitHub releases with platform detection
- No sidecar concept — there is no way to declare external binaries that should ship with a compiled CLI
Proposed scope
1. Sidecar configuration (top-level in kidd.config.ts)
Define vendored binaries declaratively as a top-level concept:
export default defineConfig({
sidecars: [
{
name: 'rg',
version: '14.1.1',
source: { repo: 'BurntSushi/ripgrep', asset: 'ripgrep-{{version}}-{{triple}}.tar.gz' },
platforms: {
'darwin-arm64': 'aarch64-apple-darwin',
'darwin-x64': 'x86_64-apple-darwin',
'linux-x64': 'x86_64-unknown-linux-gnu',
'windows-x64': 'x86_64-pc-windows-msvc',
},
},
],
compile: {
name: 'my-cli',
},
})
2. Download & packaging
- Fetch binaries from GitHub releases (or custom URLs) during build
- Extract and rename to strip platform suffixes (e.g.,
rg-darwin-arm64 → rg)
- Place alongside compiled output per-platform
3. Executable permissions handling
Key insight: filesystem executable bits don't survive npm publish. Must handle via:
publishConfig.executableFiles in platform package.json (npm >= 7.8.0) — tells npm to set +x on listed files during install
- postinstall script as fallback —
chmod +x for environments that don't respect executableFiles
- macOS specifics — strip quarantine xattrs (
xattr -cr) and ad-hoc codesign (codesign --force --sign -)
4. Runtime resolution
Provide a utility for resolving sidecar binaries at runtime:
// Production: look next to process.execPath
// Development: look in configured vendor directory
const rgPath = resolveSidecar('rg')
5. Platform package generation (optional/future)
For npm distribution (non-compiled), generate platform-specific optional dependency packages (like @joggr/cli-darwin-arm64) that contain the correct binaries for each OS/arch combo.
Reference implementation
The serenity CLI (packages/cli in serenity) implements this pattern:
build/vendor.json — binary definitions with version, repo, asset template, platform triples
build/scripts/vendor.sh — downloads from GitHub releases with template substitution
build/scripts/package.sh — distributes binaries to platform dirs, handles macOS signing
platforms/{platform}/package.json — publishConfig.executableFiles for permission handling
src/middleware/shell.ts — runtime resolution via process.execPath dirname
Open questions
- Should sidecar download happen at build time only, or support runtime download (lazy install)?
- Should this live in
packages/bundler or be a new packages/sidecar package?
- How to handle binary size concerns — should sidecars be optional per-platform?
- Should we support non-GitHub sources (direct URLs, S3, custom registries)?
Related
Summary
Add a sidecar system that allows kidd-powered CLIs to define, download, and ship external binaries (e.g.,
rg,fd,ast-grep) alongside the compiled CLI. Similar to Tauri's sidecar concept and the existing implementation in@joggr/cli(serenity).Current state
packages/bundler/src/compile/compile.tsalready produces multi-platform binaries viabun build --compilefor 7 targetspackages/config/src/types.tsdefines the kidd config schemapackages/core/src/middleware/icons/install.tsdemonstrates downloading + extracting from GitHub releases with platform detectionProposed scope
1. Sidecar configuration (top-level in
kidd.config.ts)Define vendored binaries declaratively as a top-level concept:
2. Download & packaging
rg-darwin-arm64→rg)3. Executable permissions handling
Key insight: filesystem executable bits don't survive npm publish. Must handle via:
publishConfig.executableFilesin platformpackage.json(npm >= 7.8.0) — tells npm to set+xon listed files during installchmod +xfor environments that don't respectexecutableFilesxattr -cr) and ad-hoc codesign (codesign --force --sign -)4. Runtime resolution
Provide a utility for resolving sidecar binaries at runtime:
5. Platform package generation (optional/future)
For npm distribution (non-compiled), generate platform-specific optional dependency packages (like
@joggr/cli-darwin-arm64) that contain the correct binaries for each OS/arch combo.Reference implementation
The serenity CLI (
packages/cliin serenity) implements this pattern:build/vendor.json— binary definitions with version, repo, asset template, platform triplesbuild/scripts/vendor.sh— downloads from GitHub releases with template substitutionbuild/scripts/package.sh— distributes binaries to platform dirs, handles macOS signingplatforms/{platform}/package.json—publishConfig.executableFilesfor permission handlingsrc/middleware/shell.ts— runtime resolution viaprocess.execPathdirnameOpen questions
packages/bundleror be a newpackages/sidecarpackage?Related