| Age | Commit message (Collapse) | Author |
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Merges features developed in /site/doot.terst.org/claudomator-work (a
stale clone) into the canonical repo:
- executor: QuestionRegistry for human-in-the-loop answers, rate limit
detection and exponential backoff retry (ratelimit.go, question.go)
- executor/claude.go: process group isolation (SIGKILL orphans on cancel),
os.Pipe for reliable stdout drain, backoff retry on rate limits
- api/scripts.go: POST /api/scripts/start-next-task handler
- api/server.go: startNextTaskScript field, answer-question route,
BroadcastQuestion for WebSocket question events
- web: Cancel/Restart buttons, question banner UI, log viewer, validate
section, WebSocket auto-connect
All tests pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Adds `claudomator start <task-id>` to queue a task via the running API
server. Adds internal/version for embedding VCS commit hash in the
server banner.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Top-level tasks now land in READY after successful execution instead of
going directly to COMPLETED. Subtasks (with parent_task_id) skip the gate
and remain COMPLETED. Users accept or reject via new API endpoints:
POST /api/tasks/{id}/accept → READY → COMPLETED
POST /api/tasks/{id}/reject → READY → PENDING (with rejection_comment)
- task: add StateReady, RejectionComment field, update ValidTransition
- storage: migrate rejection_comment column, add RejectTask method
- executor: route top-level vs subtask to READY vs COMPLETED
- api: /accept and /reject handlers with 409 on invalid state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
executor/claude.go: stat working_dir before cmd.Start() so a missing
or inaccessible directory surfaces as a clear error
("working_dir \"/bad/path\": no such file or directory") rather than
an opaque chdir failure wrapped in "starting claude".
api/elaborate.go: replace the hardcoded /root/workspace/claudomator
path with buildElaboratePrompt(workDir) which injects the server's
actual working directory (from os.Getwd() at startup). Empty workDir
tells the model to leave working_dir blank.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- POST /api/tasks/elaborate: calls claude to draft a task config from
a natural-language prompt
- GET /api/executions/{id}/logs/stream: SSE tail of stdout.log
- CRUD /api/templates: create/list/get/update/delete reusable task configs
- GET /api/tasks/{id}/subtasks: list child tasks
- Server.NewServer accepts claudeBinPath for elaborate; injectable
elaborateCmdPath and logStore for test isolation
- Valid-transition guard added to POST /api/tasks/{id}/run
- CLI passes claude binary path through to the server
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Pool.waitForDependencies polls depends_on task states before running
- ClaudeRunner prepends planningPreamble to task instructions to prompt
a plan-then-implement approach
- Rate-limit test helper updated to match new ClaudeRunner signature
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Task struct gains ParentTaskID field
- DB schema adds parent_task_id column (additive migration)
- DB.ListSubtasks fetches children of a parent task
- DB.UpdateTask allows partial field updates (name, description, state, etc.)
- Templates table added to initial schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Serves a lightweight dashboard (HTML/CSS/JS) from an embedded FS at
GET /. The JS polls the REST API to display tasks and stream logs
via WebSocket. Static files are embedded at build time via web/embed.go.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Adds `claudomator logs <execution-id>` to stream or display stdout logs
from a past or running execution. Includes unit tests for the command.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Ensures richer stream-json output for cost parsing and debugging.
Adds a test to verify --verbose is always present in built args.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Without json tags, Go serialized fields with capitalized names (State,
CreatedAt, Name) but the UI expected snake_case (task.state,
task.created_at). This caused createTaskCard to throw TypeError when
tasks existed, which poll() caught and displayed as "Could not reach
server".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
Claudomator automation toolkit for Claude Code with:
- Task model with YAML parsing, validation, state machine (49 tests, 0 races)
- SQLite storage for tasks and executions
- Executor pool with bounded concurrency, timeout, cancellation
- REST API + WebSocket for mobile PWA integration
- Webhook/multi-notifier system
- CLI: init, run, serve, list, status commands
- Console, JSON, HTML reporters with cost tracking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|