# ccpp shell

> One Bash, the same on every operating system, with its core commands written in Go.

Published 2026-09-23, updated 2026-09-23.

The shell under every harness.bash call: a Bash interpreter whose core commands are compiled into ccpp, so a script behaves the same on Linux, macOS and Windows.

Install:

```
ccpp lua 'return require("harness").bash("ls -la").stdout'
```

An agent that writes `grep -rn` on Windows should not have to know it is on Windows. ccpp shell interprets Bash itself and ships the commands scripts rely on, written in Go, so the script Claude wrote on your laptop runs unchanged on your CI and on your colleague's machine.

## Built for agents

- **Same everywhere**: Paths are written the way scripts write them, /c/Users/me on Windows. No WSL, no Git Bash, no surprises.
- **Failures are values**: A non-zero exit raises with the end of stderr. A failing step never flows silently into the next one.
- **Streams kept apart**: stdout and stderr come back separately, with their dropped bytes counted, so output can be parsed without guessing.

## How it works

Every `harness.bash` call of CCPP Lua runs in this shell. Scripts accept the exit codes you expect, a working directory, an environment and a timeout.

```
local r = require("harness").bash("grep -q TODO main.go", {expect = {0, 1}})
return r.exit_code == 0 and "has TODOs" or "clean"
```

## Specifications

| | |
|---|---|
| Language | Bash, interpreted in Go |
| Core commands | Written in Go and compiled into ccpp |
| Platforms | Linux, macOS, Windows |
| Timeouts | Per call, bounded by a configurable ceiling |
| Configuration | ~/.ccpp/ccpp.yml |

**Free with every account**

ccpp shell ships inside the ccpp CLI. Create an account to download it.

[Create a free account](/signup)
