summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-03-08cli: newLogger helper, defaultServerURL, shared http client, report commandPeter Stone
- Extract newLogger() to remove duplication across run/serve/start - Add defaultServerURL const ("http://localhost:8484") used by all client commands - Move http.Client into internal/cli/http.go with 30s timeout - Add 'report' command for printing execution summaries - Add test coverage for create and serve commands Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08config: Default() returns errorPeter Stone
Default() now returns (*Config, error) so callers can detect TOML parse failures rather than silently falling back to zero values. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08api: extend executions and log streaming endpointsPeter Stone
- handleListRecentExecutions: add since/limit/task_id query params - handleStreamLogs: tighten SSE framing and cleanup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08api: SetAPIToken, SetNotifier, questionStore, per-IP rate limiterPeter Stone
- Extract questionStore interface for testability of handleAnswerQuestion - Add SetAPIToken/SetNotifier methods for post-construction wiring - Extract processResult() from forwardResults() for direct testability - Add ipRateLimiter with token-bucket per IP; applied to /elaborate and /validate - Fix tests for running-task deletion and retry-limit that relied on invalid state transitions in setup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08api: generic ScriptRegistry; collapse script endpointsPeter Stone
Replace hardcoded handleStartNextTask/handleDeploy with a single handleScript handler keyed by name from a ScriptRegistry map. Scripts are now configured via Server.SetScripts() rather than individual setter fields. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08api: WebSocket auth, client cap, and ping keepalivePeter Stone
- Require bearer token on WebSocket connections when apiToken is set - Cap concurrent WebSocket clients at maxWsClients (1000, overridable) - Send periodic pings every 30s; close dead connections after 10s write deadline Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08executor: internal dispatch queue; remove at-capacity rejectionPeter Stone
Replace the at-capacity error return from Submit/SubmitResume with an internal workCh/doneCh channel pair. A dispatch() goroutine blocks waiting for a free slot and launches the worker goroutine, so tasks are buffered up to 10x pool capacity instead of being rejected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08storage: enforce valid state transitions in UpdateTaskStatePeter Stone
UpdateTaskState now validates the transition using ValidTransition inside a transaction. Invalid transitions return an error rather than blindly updating. Tests for retry-limit and running-task-rejection test setup are updated to create tasks with the target state directly via CreateTask to bypass the transition guard in setup code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08feat: rename working_dir→project_dir; git sandbox executionPeter Stone
- ClaudeConfig.WorkingDir → ProjectDir (json: project_dir) - UnmarshalJSON fallback reads legacy working_dir from DB records - New executions with project_dir clone into a temp sandbox via git clone --local - Non-git project_dirs get git init + initial commit before clone - After success: verify clean working tree, merge --ff-only back to project_dir, remove sandbox - On failure/BLOCKED: sandbox preserved, path included in error message - Resume executions run directly in project_dir (no re-clone) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08security(cli): validate --parallel flag is positive in run commandClaudomator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08feat: stash uncommitted changes before build in deploy scriptPeter Stone
Add --dirty flag to skip stashing behavior. Stashing includes untracked files and uses a trap to ensure changes are popped back on exit.
2026-03-08feat: make Running the default view on page loadPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08feat: restore Running view (currently running + 24h execution history)Peter Stone
- Running tab in nav with live SSE log streams per running task - Execution history table (last 24h) with duration, cost, exit code, view logs - Poll loop refreshes running view when tab is active - Smart diff: only full re-render when task set changes; elapsed updated in place Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08refactor: address code review notes (backward compat, Gemini tests, unknown ↵Peter Stone
agent test)
2026-03-08refactor(api/cli): update logs and status for generic agentsPeter Stone
2026-03-08refactor(storage): update templates to use generic agent configPeter Stone
2026-03-08refactor(executor): update runners and tests for generic agentsPeter Stone
2026-03-08fix: detect quota exhaustion from stream; map to BUDGET_EXCEEDED not FAILEDPeter Stone
When claude hits the 5-hour usage limit it exits 1. execOnce was returning the generic "exit status 1" error, hiding the real cause from the retry loop and the task state machine. Fix: - execOnce now surfaces streamErr when it indicates rate limiting or quota exhaustion, so callers see the actual message. - New isQuotaExhausted() detects "hit your limit" messages — these are not retried (retrying a depleted 5h bucket wastes nothing but is pointless), and map to BUDGET_EXCEEDED in both execute/executeResume. - isRateLimitError() remains for transient throttling (429/overloaded), which continues to trigger exponential backoff retries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08refactor(task): transition to generic agent architecturePeter Stone
2026-03-08feat(web): support agent type selection and rename Claude to Agent in UIPeter Stone
2026-03-08fix(storage): use Agent field instead of Claude in CreateTaskPeter Stone
2026-03-08feat(api): update template handlers to use AgentConfigPeter Stone
2026-03-08test(api): update elaborate and validate tests to use AgentConfigPeter Stone
2026-03-08feat(api): update elaborate and validate endpoints to use AgentConfigPeter Stone
2026-03-08feat(wiring): configure GeminiRunner and update API serverPeter Stone
2026-03-08feat(executor): implement GeminiRunnerPeter Stone
2026-03-08feat(executor): support multiple runners in PoolPeter Stone
2026-03-08test(executor): update claude_test.go to use AgentConfigPeter Stone
2026-03-08test(api): update server_test.go to use AgentConfig and multiple runnersPeter Stone
2026-03-08test(storage): update db_test.go to use AgentConfigPeter Stone
2026-03-08test(task): update validator and parser tests to use AgentConfigPeter Stone
2026-03-07agent: lower breakdown threshold to 3min; use claudomator create CLI for ↵Peter Stone
subtasks Replaces the API POST instructions with the claudomator create command, which is simpler and consistent with how operators queue tasks. --start is explicitly omitted so subtasks are queued but not auto-started. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07feat: add create CLI command with --parent-id; deploy to /usr/local/binPeter Stone
claudomator create <name> -i <instructions> [flags] --parent-id attach as subtask of given task ID --working-dir working directory --model claude model --budget max USD --timeout task timeout --priority high/normal/low --start queue immediately after creating deploy script now also copies binary to /usr/local/bin/claudomator. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07feat: pass selected project directory to elaboratePeter Stone
The elaborate call now sends working_dir from the Project dropdown. The backend uses it (falling back to server workDir) when building the system prompt, so AI-drafted tasks are contextualised to the selected project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07ui: Project dropdown in new task dialog, first field, defaults to ↵Peter Stone
/workspace/claudomator - Moved working directory to first field, renamed to "Project" - Replaced text input with a select populated from GET /api/workspaces (lists subdirs of /workspace dynamically) - "Create new project…" option reveals a custom path input - elaborate result handler sets select or falls back to new-project input - Added GET /api/workspaces endpoint in server.go Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07ui: move Start Next button to header next to New TaskPeter Stone
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06recover: restore untracked work from recovery branch (no Gemini changes)Peter Stone
Recovered files with no Claude→Agent contamination: - docs/adr/002-task-state-machine.md - internal/api/logs.go/logs_test.go: task-level log streaming endpoint - internal/api/validate.go/validate_test.go: POST /api/tasks/validate - internal/api/server_test.go, storage/db_test.go: expanded test coverage - scripts/reset-failed-tasks, reset-running-tasks - web/app.js, index.html, style.css: frontend improvements - web/test/: active-tasks-tab, delete-button, filter-tabs, sort-tasks tests Manually applied from server.go diff (skipping Claude→Agent rename): - taskLogStore field + validateCmdPath field - DELETE /api/tasks/{id} route + handleDeleteTask - GET /api/tasks/{id}/logs/stream route - POST /api/tasks/{id}/resume route + handleResumeTimedOutTask - handleCancelTask: allow cancelling PENDING/QUEUED tasks directly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: use context.Background() for resume execution; allow CANCELLED→QUEUED ↵Peter Stone
restart Two bugs: 1. SubmitResume was called with r.Context(), which is cancelled as soon as the HTTP handler returns, immediately cancelling the resume execution. Switch to context.Background() so the execution runs to completion. 2. CANCELLED→QUEUED was missing from ValidTransition, so the Restart button on cancelled tasks always returned 409. Added the transition. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: persist session_id in UpdateExecution so BLOCKED tasks can resumePeter Stone
session_id was set on the Execution struct inside ClaudeRunner.Run but was missing from the UPDATE query, so it was never written to the DB. GetLatestExecution then returned an empty session_id, causing the /answer endpoint to return "no resumable session found". Also patched the existing blocked execution row directly in the DB. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: stop click propagation in question footer to prevent panel stealing focusPeter Stone
Tapping the answer input or question text on mobile bubbled up to the card's click handler, opening the detail panel and stealing focus. Stopping propagation at the footer level covers all child elements. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: next-task correctly handles READY parent and COMPLETED sibling casesPeter Stone
READY state means a parent task whose subtasks should now run — select its first PENDING child, not a global fallback. COMPLETED state means continue the series via the next PENDING sibling. Only fall back to the priority+age queue when neither yields a task. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: next-task falls back to priority queue when no pending siblings remainPeter Stone
When the most recently completed task had no remaining PENDING siblings (series fully done), the script returned empty and start-next-task reported "No task to start." Fix by falling through to the priority+age fallback whenever the sibling search yields nothing. Also add header comment documenting the selection logic, and suppress browser favicon 404s with <link rel="icon" href="data:,">. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06fix: implement cancel endpoint and pool cancel mechanismPeter Stone
POST /api/tasks/{id}/cancel now works. Pool tracks a cancel func per running task ID; Cancel(taskID) calls it and returns false if the task isn't running. The execute goroutine registers/deregisters the cancel func around the runner call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06feat: blocked task state for agent questions via session resumePeter Stone
When an agent needs user input it writes a question to $CLAUDOMATOR_QUESTION_FILE and exits. The runner detects the file and returns BlockedError; the pool transitions the task to BLOCKED and stores the question JSON on the task record. The user answers via POST /api/tasks/{id}/answer. The server looks up the claude session_id from the most recent execution and submits a resume execution (claude --resume <session-id> "<answer>"), freeing the executor slot entirely while waiting. Changes: - task: add StateBlocked, transitions RUNNING→BLOCKED, BLOCKED→QUEUED - storage: add session_id to executions, question_json to tasks; add GetLatestExecution and UpdateTaskQuestion methods - executor: BlockedError type; ClaudeRunner pre-assigns --session-id, sets CLAUDOMATOR_QUESTION_FILE env var, detects question file on exit; buildArgs handles --resume mode; Pool.SubmitResume for resume path - api: handleAnswerQuestion rewritten to create resume execution - preamble: add question protocol instructions for agents - web: BLOCKED state badge (indigo), question text + option buttons or free-text input with Submit on the task card footer Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05executor: default permission_mode to bypassPermissionsPeter Stone
claudomator runs tasks unattended; prompting for write permission always stalls execution. Any task without an explicit permission_mode now gets --permission-mode bypassPermissions automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05executor: persist log paths at execution create time, not just at endPeter Stone
Add LogPather interface; ClaudeRunner implements it via ExecLogDir(). Pool pre-populates stdout_path/stderr_path/artifact_dir on the execution record before CreateExecution, so paths are in the DB from the moment a task starts running. ClaudeRunner.Run() skips path assignment when already set by the pool. Also update scripts/debug-execution to derive paths from the known convention (<data-dir>/executions/<exec-id>/) as a fallback for historical records that predate this change. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05web: fix Restart button calling nonexistent /restart endpointPeter Stone
restartTask() was POSTing to /api/tasks/{id}/restart (405) instead of the existing /api/tasks/{id}/run endpoint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05executor: detect stream-level failures when claude exits 0Peter Stone
Rename streamAndParseCost → parseStream (returns float64, error). Detect two failure modes that claude reports via exit 0: - result message with is_error:true - tool_result permission denial ("haven't granted it yet") Also fix cost extraction to read total_cost_usd from the result message (the actual field name), keeping cost_usd as legacy fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05web: add Accept/Reject for READY tasks, Start Next buttonPeter Stone
- READY state task cards show Accept + Reject buttons - Accept POSTs to /api/tasks/{id}/accept (→ COMPLETED) - Reject POSTs to /api/tasks/{id}/reject (→ PENDING) - "Start Next" button in toolbar POSTs to /api/scripts/start-next-task - CSS for .btn-accept and .btn-reject Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05CLAUDE.md: add canonical repo constraintPeter Stone
Explicitly state that /workspace/claudomator is the canonical directory. Prevents agents from wandering into other directories on the filesystem. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>