"Just tell me what's wrong. I'll figure it out." — Ove, on every conversation
He grumbles, but he gets it done. Properly.
Talk to Ove like you'd talk to a colleague. Ask questions, describe problems, paste error logs, think out loud — he understands natural language. No need to memorize commands. Just chat.
"the login page throws a 500 after submitting" "can you check what's breaking the auth tests on my-app?" "how does the payment webhook work?" "refactor the user service, it's getting messy"
Ove figures out the intent, picks the right repo, and gets to work. For common tasks, there are also shorthand commands — but they're shortcuts, not requirements.
Tell Ove to review a PR. He'll go through every line, find the bugs you missed, and leave comments. Thorough as always.
review PR #42 on my-app
Point Ove at a GitHub issue. He'll read it, explore the code, implement the fix, write tests, and open a PR.
fix issue #15 on my-app
Run the test suite and linter. Ove reports every failure with the look of a man who knew this would happen.
validate my-app
Discuss ideas with Ove. He'll ask the questions you forgot to ask, poke holes in your plan, and suggest what actually works.
discuss notification service
Tell Ove to do something on a schedule. He'll parse your natural language, set it up, and run it on time. Every time.
lint and check every day at 9
See what's running, what's queued, and kill anything that's gone sideways. Different repos run in parallel, same repo stays serial.
tasks cancel <id>
Three ways to run Ove. Pick what fits. No excuses.
gh) installed and authenticatedInstall globally, run the interactive setup, start.
npm install -g @lovenyberg/ove ove init # walks you through config ove start
Requires Bun runtime on your machine.
Generate config locally, then run everything in a container. The image includes Bun, git, and Claude CLI.
# Generate config on host first ove init # Start the container docker compose up -d # Watch logs docker compose logs -f
Mounts config.json, .env, repos/, and ~/.ssh from the host. Set ANTHROPIC_API_KEY in .env or your shell.
Best for always-on setups. A small VM (2 CPU, 4 GB RAM) is enough. See the full VM guide below.
git clone git@github.com:jacksoncage/ove.git && cd ove bun install ove init sudo cp deploy/ove.service /etc/systemd/system/ove.service sudo systemctl enable --now ove
ove init creates config.json and .env interactively. It asks for your transports, tokens, repos, and users. You can also edit them directly:
{
"repos": {
"my-app": {
"url": "git@github.com:org/my-app.git",
"defaultBranch": "main"
}
},
"users": {
"slack:U0ABC1234": { "name": "alice", "repos": ["my-app"] },
"telegram:123456789": { "name": "alice", "repos": ["my-app"] },
"discord:987654321": { "name": "alice", "repos": ["my-app"] },
"github:alice": { "name": "alice", "repos": ["my-app"] },
"http:anon": { "name": "alice", "repos": ["my-app"] },
"cli:local": { "name": "alice", "repos": ["my-app"] }
},
"claude": { "maxTurns": 10 },
"runner": { "name": "claude" },
"cron": [
{
"schedule": "0 9 * * 1-5",
"repo": "my-app",
"prompt": "Run lint and tests.",
"userId": "slack:U0ABC1234"
}
]
}
Set "runner" globally to {"name": "codex"} to use OpenAI Codex, or override per-repo with a "runner" field inside the repo config. Supported runners: claude (default), codex.
Static cron jobs go in config.json. Users can also create schedules from chat — just say something like lint and check every day at 9. These are stored in SQLite and managed with list schedules / remove schedule #N.
Shortcuts for common tasks. You can also just type what you need in plain language.
Parallel where it matters. Serial where it must be. Proper.
claude -p or codex exec) with streaming JSON outputtasks to monitor, cancel <id> to stopTeach Ove's Claude instances your conventions. Manually.
Ove spawns Claude Code CLI in isolated worktrees. The spawned instances automatically pick up skills — reusable instruction sets that follow the Agent Skills open standard.
Skills are configured manually on the host machine running Ove:
claude plugins add — available where enabledWhen Ove runs a task, Claude Code picks up all three levels. Drop a SKILL.md with domain knowledge, coding conventions, review checklists, or deployment workflows — and every task on that repo benefits.
--- name: review description: Review code using our team standards --- When reviewing code, check for: 1. Error handling covers all failure modes 2. Tests cover the happy path and at least one edge case 3. No secrets or credentials in code
See the Claude Code skills docs for frontmatter options, argument passing, subagent execution, and more.
Enable what you need. Ove doesn't judge. Much.
xapp-...)chat:write, channels:history, groups:history, im:history, mpim:history, app_mentions:readmessage.im, app_mentionxoxb-...).env/newbotTELEGRAM_BOT_TOKEN=<token> in .envbot scope + Send Messages, Read Message HistoryDISCORD_BOT_TOKEN=<token> in .envHTTP_API_PORT=3000 and HTTP_API_KEY=<your-secret> in .envhttp://localhost:3000 for the Web UIcurl -X POST http://localhost:3000/api/message -H "X-API-Key: <key>" -d '{"text":"validate my-app"}'GITHUB_POLL_REPOS=owner/repo1,owner/repo2 in .envGITHUB_BOT_NAME=ove (default) and GITHUB_POLL_INTERVAL=30000@ove in an issue or PR comment to trigger a taskWHATSAPP_ENABLED=true and WHATSAPP_PHONE=<your-number> in .envWHATSAPP_ALLOWED_CHATS=<phone1>,<phone2> to limit which chats Ove listens to. Without this, Ove responds to all your outgoing messages in every chat. Use phone numbers (e.g. 46701234567) for individual chats or full JIDs (e.g. 120363xxx@g.us) for groups.Pick your method. They all work. Ove doesn't care.
The Dockerfile builds an image with Bun, git, openssh-client, and Claude CLI baked in. Install Codex CLI separately if needed. Just mount your config and go.
services:
ove:
build: .
env_file: .env
environment:
- ANTHROPIC_API_KEY
volumes:
- ./config.json:/app/config.json:ro
- ./repos:/app/repos
- ~/.ssh:/root/.ssh:ro
restart: unless-stopped
Run ove init on the host first to generate config.json and .env, then docker compose up -d. Repos and the SQLite database persist in the repos/ volume.
Ove runs on a small VM (2 CPU, 4 GB RAM) where Claude Code and GitHub CLI are set up. Ubuntu 22.04+, Debian 12+. Hetzner, DigitalOcean, whatever you have.
# Bun curl -fsSL https://bun.sh/install | bash # Claude Code (default runner) npm install -g @anthropic-ai/claude-code # Or Codex CLI (alternative runner) # npm install -g @openai/codex # GitHub CLI sudo apt install gh gh auth login # SSH key for git ssh-keygen -t ed25519 # Add the public key to GitHub
# Run once to authenticate claude # Verify it works claude -p "say hello" --output-format text
git clone git@github.com:jacksoncage/ove.git cd ove bun install ove init # interactive setup
# Copy the service file sudo cp deploy/ove.service /etc/systemd/system/ove.service # Enable and start sudo systemctl enable ove sudo systemctl start ove # Check logs journalctl -u ove -f
Send Ove a message on any configured transport and type help. He should respond. Grumpily.