summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-22 23:48:03 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-22 23:48:03 +0000
commit2c8ec3e53a0f4c6f2d16e94a95fcdce706717091 (patch)
tree7cef240684c4d5bc2e627dd3585290e3ddc1a03e /CLAUDE.md
parentd8939199f129ccb1abcf0150012bc23209facf12 (diff)
chore: unify and centralize agent configuration in .agent/
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md231
1 files changed, 8 insertions, 223 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index 7ef8d63..5b01d7b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,227 +1,12 @@
-# CLAUDE.md
+# Claudomator — Agent Instructions
-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+This repository uses a centralized agent configuration.
-Also check `~/.claude/CLAUDE.md` for user-level development standards (TDD workflow, git practices, session state management, etc.) that apply globally across all projects.
+**Primary Source of Truth:** ".agent/config.md"
-## Canonical Repository
+## Quick Reference
+- **Worklog:** ".agent/worklog.md"
+- **Design:** ".agent/design.md"
+- **Coding Standards:** ".agent/coding_standards.md"
-**The canonical source of truth is `/workspace/claudomator`.** All development must happen here.
-Do not work in any other directory unless explicitly instructed. Do not explore `/site/doot.terst.org/` for source files.
-
-## Build & Test Commands
-
-```bash
-# Build
-go build ./...
-
-# Run all tests
-go test ./...
-
-# Run a single package's tests
-go test ./internal/executor/...
-
-# Run a single test by name
-go test ./internal/api/ -run TestServer_CreateTask_MissingName
-
-# Run with race detector (important for executor/pool tests)
-go test -race ./...
-
-# Build the binary
-go build -o claudomator ./cmd/claudomator/
-```
-
-> **Note:** `go-sqlite3` uses CGo. A C compiler (`gcc`) must be present for builds and tests.
-
-## Running the Server
-
-```bash
-# Initialize data directory
-./claudomator init
-
-# Start API server (default :8484)
-./claudomator serve
-
-# Run a task file directly (bypasses server)
-./claudomator run ./test/fixtures/tasks/simple-task.yaml
-
-# List tasks via CLI
-./claudomator list
-```
-
-Config defaults to `~/.claudomator/config.toml`. Data is stored in `~/.claudomator/` (SQLite DB + execution logs).
-
-## Architecture
-
-**Pipeline:** CLI/API → `executor.Pool` → `executor.ContainerRunner` → Docker container → SQLite + log files
-
-### Packages
-
-| Package | Role |
-|---|---|
-| `internal/task` | `Task` struct, YAML parsing, state machine, validation |
-| `internal/executor` | `Pool` (bounded goroutine pool) + `ContainerRunner` (Docker-based executor) |
-| `internal/storage` | SQLite wrapper; stores tasks and execution records |
-| `internal/api` | HTTP server (REST + WebSocket via `internal/api.Hub`) |
-| `internal/reporter` | Formats and emits execution results |
-| `internal/config` | TOML config + data dir layout |
-| `internal/cli` | Cobra CLI commands (`run`, `serve`, `list`, `status`, `init`) |
-
-### Key Data Flows
-
-**Task execution:**
-1. Task created via `POST /api/tasks` or YAML file (`task.ParseFile`)
-2. `POST /api/tasks/{id}/run` → `executor.Pool.Submit()` → goroutine in pool
-3. `ContainerRunner.Run()` clones `repository_url`, runs `docker run claudomator-agent:latest`
-4. Agent runs `claude -p` inside the container; stdout streamed to `executions/<exec-id>/stdout.log`
-5. On success, runner pushes commits back to the remote; execution result written to SQLite + WebSocket broadcast
-
-**State machine** (`task.ValidTransition`):
-`PENDING` → `QUEUED` → `RUNNING` → `COMPLETED | FAILED | TIMED_OUT | CANCELLED | BUDGET_EXCEEDED`
-Failed tasks can retry: `FAILED` → `QUEUED`
-
-**WebSocket:** `Hub` fans out task completion events to all connected clients. `Server.StartHub()` must be called after creating the server.
-
-### Task YAML Format
-
-```yaml
-name: "My Task"
-claude:
- model: "sonnet"
- instructions: |
- Do something useful.
- working_dir: "/path/to/project"
- max_budget_usd: 1.00
- permission_mode: "default"
- allowed_tools: ["Bash", "Read"]
-timeout: "15m"
-priority: "normal" # high | normal | low
-tags: ["ci"]
-```
-
-Batch files wrap multiple tasks under a `tasks:` key.
-
-### Storage Schema
-
-Two tables: `tasks` (with `config_json`, `retry_json`, `tags_json`, `depends_on_json` as JSON blobs) and `executions` (with paths to log files). Schema is auto-migrated on `storage.Open()`.
-
-## Features
-
-### Changestats
-
-After each task execution, Claudomator extracts git diff statistics from the execution's stdout log. If the log contains a git `diff --stat` summary line (e.g. `5 files changed, 127 insertions(+), 43 deletions(-)`), the stats are parsed and stored in the `executions.changestats_json` column via `storage.DB.UpdateExecutionChangestats`.
-
-**Extraction points:**
-- `internal/executor.Pool.handleRunResult` — calls `task.ParseChangestatFromFile(exec.StdoutPath)` after every execution; stores via `Store.UpdateExecutionChangestats`.
-- `internal/api.Server.processResult` — also extracts changestats when the API server processes a result (same file, idempotent second write).
-
-**Parser location:** `internal/task/changestats.go` — exported functions `ParseChangestatFromOutput` and `ParseChangestatFromFile` usable by any package without creating circular imports.
-
-**Frontend display:** `web/app.js` renders a `.changestats-badge` on COMPLETED/READY task cards and in execution history rows.
-
-## GitHub Webhook Integration
-
-Claudomator can automatically create tasks when CI builds fail on GitHub.
-
-### Endpoint
-
-`POST /api/webhooks/github`
-
-Accepts `check_run` and `workflow_run` events from GitHub. Returns `{"task_id": "..."}` (200) when a task is created, or 204 when the event is ignored.
-
-### Config (`~/.claudomator/config.toml`)
-
-```toml
-# Optional: HMAC-SHA256 secret set in the GitHub webhook settings.
-# If omitted, signature validation is skipped.
-webhook_secret = "your-github-webhook-secret"
-
-# Projects for matching incoming webhook repository names to local directories.
-[[projects]]
-name = "myrepo"
-dir = "/workspace/myrepo"
-
-[[projects]]
-name = "other-service"
-dir = "/workspace/other-service"
-```
-
-### Matching logic
-
-The handler matches the webhook's `repository.name` against each project's `name` and the basename of its `dir` (case-insensitive substring). If no match is found and only one project is configured, that project is used as a fallback.
-
-### GitHub webhook setup
-
-In your GitHub repository → Settings → Webhooks → Add webhook:
-- **Payload URL:** `https://<your-claudomator-host>/api/webhooks/github`
-- **Content type:** `application/json`
-- **Secret:** value of `webhook_secret` in config (or leave blank if not configured)
-- **Events:** select *Workflow runs* and *Check runs*
-
-### Task creation
-
-A task is created for:
-- `check_run` events with `action: completed` and `conclusion: failure`
-- `workflow_run` events with `action: completed` and `conclusion: failure` or `timed_out`
-
-Tasks are tagged `["ci", "auto"]`, capped at $3 USD, and use tools: Read, Edit, Bash, Glob, Grep.
-
-## System Maintenance (Cron)
-
-The following crontab entries are required for system operation and must be maintained for the root user:
-
-```crontab
-# Sync Claude and Gemini credentials every 10 minutes
-*/10 * * * * /workspace/claudomator/scripts/sync-credentials
-
-# Start the next queued task every 20 minutes
-*/20 * * * * /workspace/claudomator/scripts/start-next-task >> /var/log/claudomator-cron.log 2>&1
-```
-
-> **Note:** These requirements are critical for agent authentication and automated task progression.
-
-## Agent Tooling (`ct` CLI)
-
-Agents running inside containers have access to `ct`, a pre-built CLI for interacting with the Claudomator API. It is installed at `/usr/local/bin/ct` in the container image. **Use `ct` to create and manage subtasks — do not attempt raw `curl` API calls.**
-
-### Environment (injected automatically)
-
-| Variable | Purpose |
-|---|---|
-| `CLAUDOMATOR_API_URL` | Base URL of the Claudomator API (e.g. `http://host.docker.internal:8484`) |
-| `CLAUDOMATOR_TASK_ID` | ID of the currently-running task; used as the default `parent_task_id` for new subtasks |
-
-### Commands
-
-```bash
-# Create a subtask and immediately queue it (returns task ID)
-ct task submit --name "Fix tests" --instructions "Run tests and fix any failures." [--model sonnet] [--budget 3.0]
-
-# Create, queue, and wait for completion (exits 0=COMPLETED, 1=FAILED, 2=BLOCKED)
-ct task submit --name "Fix tests" --instructions "..." --wait
-
-# Read instructions from a file instead of inline
-ct task submit --name "Fix tests" --file /workspace/subtask-instructions.txt --wait
-
-# Lower-level: create only (returns task ID), then run separately
-TASK_ID=$(ct task create --name "..." --instructions "...")
-ct task run "$TASK_ID"
-ct task wait "$TASK_ID" --timeout 600
-
-# Check status of any task
-ct task status <task-id>
-
-# List recent tasks
-ct task list
-```
-
-### Notes
-
-- Default model is `sonnet`; default budget is `$3.00 USD`. Override with `--model` / `--budget`.
-- `ct task wait` polls every 5 seconds and exits with the task's terminal state on stdout.
-- Subtasks inherit the current task as their parent automatically (via `$CLAUDOMATOR_TASK_ID`).
-- Override parent with `--parent <task-id>` if needed.
-
-## ADRs
-
-See `docs/adr/001-language-and-architecture.md` for the Go + SQLite + WebSocket rationale.
+Refer to ".agent/config.md" before performing any tasks.