This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
go build . # Build the binary
go test ./... # Run all tests
go vet ./... # Static analysis
go test ./pkg/config/ # Run tests for a single packageVersion is injected at build time: go build -ldflags "-X main.version=1.0.0" .
Releases use goreleaser (.goreleaser.yml), triggered by git tags matching v*.
botctl is a process manager for autonomous AI agent bots. It runs persistent agents from a CLI with a TUI dashboard, web UI, and declarative BOT.md configuration.
This repo (botctl) is the open-source CLI. A private repo (botctl-platform) imports pkg/ to build a hosted multi-tenant platform. This means:
pkg/is the public API surface — importable bybotctl-platform. Changes here affect both projects.internal/is CLI-specific and not importable outside this module.
pkg/ (shared library):
config— ParsesBOT.mdfiles (YAML frontmatter + markdown body). Handles${VAR}env expansion and defaults.backend— Pluggable agent runtime abstraction.backend.Backendinterface withQuery(), provider-neutralMessageEvent/ContentBlock/Options/Resulttypes. Subpackagesclaude/(wraps the inlinedclaude/sdk/wrapper around the Claude CLI) andopencode/(spawnsopencode run --format json) self-register viainit(). Selected per-bot viabackend:in BOT.md frontmatter (defaultclaude).harness— Core execution loop. Reloads config each iteration, runs the configured backend'sQuery(), records stats, handles pause/resume/interrupt, sleeps for interval.db— SQLite layer (WAL mode). Tables: runs, messages, log_entries, bot_state. Tracks run lifecycle, bot state + session, structured logs, cost/turn stats.service— Business logic facade over db + process. Start/stop/pause/play/message bots, query stats and logs.process— Spawns harness as a subprocess, manages PID lifecycle, SIGTERM→SIGKILL with timeout. Platform-specific files for Unix vs Windows.discovery— Scans~/.botctl/bots/for valid BOT.md files.skills— Discovers skills from 3 locations (first match wins):~/.agents/skills/,~/.botctl/skills/, per-botskills_dir/.paths— Resolves all filesystem paths.BOTCTL_HOMEenv var overrides the default~/.botctl/root (used in tests).logs— Log rendering and formatting.create— Bot creation helpers.
internal/ (CLI-only):
cli— Cobra command handlers. Each command useswithService()to open DB and create Service.tui— Bubble Tea terminal UI with table, live log viewer, modals.web— HTTP dashboard on port 4444 with embedded static files and SSE log streaming.website— Documentation site builder.update— Self-update mechanism.
pkg/backend/claude/sdk/:
Inlined Go wrapper around the Claude CLI (stream-json over stdin/stdout). Used by pkg/backend/claude (the backend adapter) and pkg/create (interactive BOT.md generation). See pkg/backend/claude/sdk/CLAUDE.md for details.
Bot execution: cli.start → process.StartBot() spawns botctl harness subprocess → harness.Run() loops: reload config → check message queue → backend.Get(cfg.Backend).Query() → record stats → sleep for interval.
State transitions: stopped → running → sleeping ↔ paused. Session IDs are persisted for resume after max_turns.
Operator messages: Queued in DB via service.SendMessage(), picked up by harness on next iteration, formatted as prominent headings in the Claude prompt.
- Commit messages use conventional commits (
feat:,fix:,refactor:,docs:,test:,chore:). - Tests use
t.TempDir()and setBOTCTL_HOMEenv var to isolate filesystem paths. - Platform-specific code uses build-tagged files:
platform_unix.go,platform_windows.go. - CI runs on ubuntu, macos, and windows — use
filepath.Joinfor path construction, not hardcoded slashes.