| Age | Commit message (Collapse) | Author |
|
Files changed: CLAUDE.md, internal/api/changestats.go,
internal/executor/executor.go, internal/executor/executor_test.go,
internal/task/changestats.go (new)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
sandboxes
#1 - Diagnostics: tailFile() reads last 20 lines of subprocess stderr and
appends to error message when claude/gemini exits non-zero. Previously all
exit-1 failures were opaque; now the error_msg carries the actual subprocess
output.
#4 - Restart recovery: RecoverStaleRunning() now re-queues tasks after
marking them FAILED, so tasks killed by a server restart automatically
retry on the next boot rather than staying permanently FAILED.
#2 - Stale sandbox: If a resume execution's preserved SandboxDir no longer
exists (e.g. /tmp purge after reboot), clone a fresh sandbox instead of
failing immediately with "no such file or directory".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
- Added an agent selector (Auto, Claude, Gemini) to the Start Next Task button.
- Updated the backend to pass query parameters as environment variables to scripts.
- Modified the executor pool to skip classification when a specific agent is requested.
- Added --agent flag to claudomator start command.
- Updated tests to cover the new functionality.
|
|
Add Pool.RecoverStaleQueued() that lists all QUEUED tasks from the DB on
startup and re-submits them to the in-memory pool. Previously, tasks that
were QUEUED when the server restarted would remain stuck indefinitely since
only RUNNING tasks were recovered (and marked FAILED).
Called in serve.go immediately after RecoverStaleRunning().
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
pickAgent() deterministically selects the agent with the fewest active tasks,
skipping rate-limited agents. The classifier now only selects the model for the
pre-assigned agent, so Gemini gets tasks from the start rather than only as a
fallback when Claude's quota is exhausted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Both execute() and executeResume() shared ~80% identical post-run logic:
error classification (BLOCKED, TIMED_OUT, CANCELLED, BUDGET_EXCEEDED, FAILED),
state transitions, result emission, and UpdateExecution. Extract this into
handleRunResult(ctx, t, exec, err, agentType) on *Pool. Both functions now
call it after runner.Run() returns.
Also adds TestHandleRunResult_SharedPath which directly exercises the new
function via a minimalMockStore, covering FAILED, READY, COMPLETED, and
TIMED_OUT classification paths.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Add maybeUnblockParent helper that transitions a BLOCKED parent task to
READY once every subtask is in the COMPLETED state. Called in both
execute() and executeResume() immediately after a subtask is marked
COMPLETED. Any non-COMPLETED sibling (RUNNING, FAILED, etc.) keeps the
parent BLOCKED.
Tests added:
- TestPool_Submit_LastSubtask_UnblocksParent
- TestPool_Submit_NotLastSubtask_ParentStaysBlocked
- TestPool_Submit_ParentNotBlocked_NoTransition
|
|
When a top-level task (ParentTaskID == "") finishes successfully,
check for subtasks before deciding the next state:
- subtasks exist → BLOCKED (waiting for subtasks to complete)
- no subtasks → READY (existing behavior, unchanged)
This applies to both execute() and executeResume().
Adds ListSubtasks to the Store interface.
Tests:
- TestPool_Submit_TopLevel_WithSubtasks_GoesBlocked
- TestPool_Submit_TopLevel_NoSubtasks_GoesReady
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
All previously ignored errors from p.store.UpdateTaskState() and
p.store.UpdateTaskQuestion() in execute() and executeResume() now log
with structured context (taskID, state, error).
Introduces a Store interface so tests can inject a failing mock store.
Adds TestPool_UpdateTaskState_DBError_IsLoggedAndResultDelivered to
verify that a DB write failure is logged and the result is still
delivered to resultCh.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
activePerAgent: delete zero-count entries after decrement so the map
doesn't accumulate stale keys for agent types that are no longer active.
rateLimited: delete entries whose deadline has passed when reading them
(in both the classifier block and the execute() pre-flight), so stale
entries are cleaned up on the next check rather than accumulating forever.
Both fixes are covered by new regression tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
On restart, any tasks in RUNNING state have no active goroutine.
RecoverStaleRunning() marks them FAILED (retryable) and closes
their open execution records with an appropriate error message.
Called once from serve.go after the pool is created.
|
|
Fix: use file:// prefix in git fetch during sandbox teardown to force
pack-protocol transfer. The local optimization uses hard links which
fail across devices and with mixed-owner object stores.
Feature: before running a task, query prior failed/timed-out executions
and prepend their error messages to the agent's --append-system-prompt.
This tells the agent what went wrong in previous attempts so it doesn't
repeat the same mistakes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Resolve conflicts in API server, CLI, and executor.
- Maintain Gemini classification and assignment logic.
- Update UI to use generic agent config and project_dir.
- Fix ProjectDir/WorkingDir inconsistencies in Gemini runner.
- All tests passing after merge.
|
|
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>
|
|
agent test)
|
|
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|