git clone https://github.com/alper-dev/better-bash.git
cd better-bash
bun installbun run build # Bundle ESM + CJS + generate type declarations
bun test # Run all tests
bun run typecheck # Type check without emittingsrc/
├── process-manager.ts # Core engine: ring buffer, long-poll, stdin, cleanup
├── shell-detect.ts # Cross-platform shell detection + PowerShell Base64 encoding
├── run-effect.ts # Dual-Effect-instance safe runner
├── types.ts # Shared types and error classes
├── index.ts # Public API exports
├── plugin.ts # OpenCode plugin adapter
├── tools/ # Tool definitions (shared by all adapters)
│ ├── bash-start.ts
│ ├── bash-status.ts
│ ├── bash-kill.ts
│ ├── bash-stdin.ts
│ └── bash-list.ts
└── adapters/ # Platform-specific adapters
├── opencode.ts
└── mimocode.ts
ProcessManager is the core. It manages child processes with:
- Ring buffer (100KB default) for output collection
- Long-polling via Effect Deferred
- Auto-cleanup of finished processes
- Per-session process isolation
Tool definitions in tools/ are platform-agnostic. Adapters in adapters/ wrap them for specific platforms.
run-effect.ts exists because MiMoCode has its own Effect runtime. Our bundled Effect and MiMoCode's Effect are different instances, so calling Effect.runPromise from MiMoCode on our Effect objects causes Fiber.runLoop errors. runEffect() uses our bundled instance.
-
Create
src/tools/bash-<name>.tswith:bash<Name>Description: tool description stringbash<Name>Parameters: JSON schema objectexecuteBash<Name>(pm, params): execution function usingrunEffect
-
Add
ProcessManagermethod insrc/process-manager.tsif needed -
Export from
src/index.ts -
Add to adapters in
src/adapters/opencode.tsandsrc/adapters/mimocode.ts -
Add to plugin in
src/plugin.ts -
Add tests in
tests/process-manager.test.ts
Tests use bun:test. Each test gets a fresh ProcessManager instance with tight limits (5 concurrent, 10s timeout, 10KB buffer).
Commands use PowerShell syntax on Windows:
- Use
;to chain commands, not&(PowerShell backgrounds&) - Use
exit 1notexit /b 1(cmd.exe syntax) - Use
Start-Sleep -Seconds Nfor delays
bun run build.ts: Bun.build bundles ESM (index.js,plugin.js) and CJS (index.cjs,plugin.cjs) with source mapstsc -p tsconfig.dts.json: generates type declarations
We don't use tsup. Bun.build handles bundling natively.
Tool descriptions are the primary documentation for AI agents. They should include:
- When to use this tool vs alternatives
- Shell quoting rules (in
bash_start) - Stdin compatibility table (in
bash_stdin) - Status values and edge cases (in
bash_status)
Don't add agent-facing SKILL.md docs for the tool itself; the tool descriptions in src/tools/ and src/plugin.ts are the primary API documentation. (The repo's AGENTS.md is maintenance guidance for AI assistants working in this repository, not agent-facing tooling.)
See RELEASING.md for prerequisites, verification, tagging, trusted publishing, and rollback guidance.