Publish Image / publish (push) Successful in 22sDetails
PR comments fire as issue_comment webhooks in Gitea. Previously the
handler only re-triggered the analyst for regular issues. Now it
detects PR comments via the pull_request field and queues a test
workspace using the review bot account.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 23sDetails
Gitea webhook payloads use "type" (e.g. "pull_request_review_rejected")
instead of "state" (e.g. "REQUEST_CHANGES"). Map both formats so
the pr-rework handler works with all Gitea webhook variations.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 21sDetails
Completed jobs with the same jobId block new jobs from being added.
Add removeOnComplete and removeOnFail to all job options so the same
task can be re-triggered after completion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 23sDetails
Gitea sends review objects without a state field in some cases.
Use optional chaining and log the review payload for debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 23sDetails
When a review requests changes on a docs/ branch (architect PR), trigger
the rework-spec task type instead of rework-pr. This re-runs the architect
persona to fix the design docs based on review feedback.
- Add rework-spec to Coder template task_type options and lightweight stages
- Detect architect PRs via docs/ branch prefix in pr-rework handler
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 22sDetails
- issue-label: Accept action "created" from Gitea (in addition to
"labeled" and "label_updated") — Gitea sends "created" for new labels
- pr-rework: Guard against missing review object to prevent TypeError
crash when Gitea sends review webhook without review data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 35sDetails
The plain DELETE endpoint returns 405 for stopped workspaces. Use
POST /workspaces/:id/builds with {"transition":"delete"} instead,
which is the correct Coder API for workspace deletion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 26sDetails
BullMQ throws "Custom Id cannot contain :" when jobId includes colons.
Replace colon separators with dashes in all jobId values.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 36sDetails
Replace the volatile in-memory Map/Set queue with BullMQ backed by Redis
for persistence across restarts, automatic retry with exponential backoff,
and non-blocking workspace cleanup.
- Two queues: workspace-create (concurrency-limited) and workspace-cleanup
(with polling instead of sleep-based stop→delete)
- Active workspaces tracked in Redis hash for dedup across restarts
- Stale sweep every 10 minutes catches orphaned workspaces
- Graceful shutdown on SIGTERM/SIGINT
- Replace node-cron with BullMQ repeatable jobs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 21sDetails
The DELETE API requires the workspace to be stopped first. Now stops,
waits 10s for shutdown, then deletes. This was causing workspaces to
never be cleaned up after task completion.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the full process: adding slash commands, bot collaborator
access, Gitea webhook configuration, infrastructure setup, env vars,
and how workspaces work. Covers common gotchas (OAuth token priority,
org vs repo permissions, lightweight vs heavy stages).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ANTHROPIC_API_KEY takes priority over CLAUDE_CODE_OAUTH_TOKEN in
Claude Code's auth precedence. Must be unset for OAuth to work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 21sDetails
Pass CLAUDE_CODE_OAUTH_TOKEN to workspaces so they use the Max
subscription instead of pay-per-use API credits. Falls back to
ANTHROPIC_API_KEY if OAuth token not set.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These stages only read code and post comments — no need for npm install,
frontend build, Playwright, or migrations. Saves several minutes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses ERR/EXIT trap to ensure the orchestrator is notified when the
startup script fails (e.g. clone error, missing command file). Prevents
orphaned workspaces that never get cleaned up.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Workspaces are now fully immutable like GH Actions runners — no
persistent volume, no init container, no stale state between runs.
Fresh emptyDir on every workspace creation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Always rm -rf ~/project before cloning to avoid stale state from
previous workspace runs on the same PVC. Made setup steps generic
(detect frontend, playwright, migrations) instead of babble-specific.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 15sDetails
The startup script already writes to stdout which the Coder agent
captures. No need for a separate HTTP log server or coder_app button.
Logs are visible via the Coder web terminal or agent log viewer.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Workspace Image / publish (push) Successful in 3m51sDetails
- Add coder/workspace.Dockerfile with Node.js 22, wrangler, claude-code,
and Playwright deps pre-installed. Eliminates ~3 min of installs on
every workspace startup.
- Add CI workflow to build and push to registry.samson.media/coder-workspace
- Fix slash command: -p mode doesn't support /commands, so read the .md
file directly, strip frontmatter, substitute $ARGUMENTS, pass as prompt
- Switch workspace image from codercom/enterprise-base to custom image
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The project: prefix is not valid Claude Code syntax. Slash commands
in .claude/commands/ are invoked as /$TASK_TYPE directly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 20sDetails
On boot, query Coder for running workspaces and re-adopt them into the
active queue. This prevents 409 conflicts after restarts and ensures
callbacks still work for in-flight tasks.
On 409: only delete stopped/failed workspaces. Running workspaces are
adopted — never killed based on age.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 20sDetails
Instead of blindly deleting on 409 conflict, now checks:
- Stopped/failed → safe to delete and recreate
- Running but >30 min old → stale, delete and recreate
- Running and <30 min old → adopt existing workspace (mid-task)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 20sDetails
When the orchestrator restarts, it loses in-memory queue state. If a
stale workspace still exists, createWorkspace now auto-deletes it and
retries instead of failing with 409. Also adds --verbose to Claude Code
invocation for better task log debugging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The tag `ubuntu-arm64` doesn't exist on Docker Hub. Switch to `latest`
which includes arm64 in its multi-arch manifest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 20sDetails
- Workspaces curl POST /webhook/task-complete/{name} when done
- Orchestrator deletes the workspace via Coder API on callback
- Active workspaces count toward concurrency limit
- GET /queue now shows active workspaces with elapsed time
- Coder template gains callback_url parameter
- TTL becomes a safety net, not the primary shutdown mechanism
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 54sDetails
- Tasks keyed by {taskType}-{repo}-{issue} for deduplication
- Duplicate requests (pending or running) are dropped
- Configurable concurrency via QUEUE_CONCURRENCY env (default 2)
- Workspace names now {taskType}-{repo}-{issue} for observability
- GET /queue endpoint shows pending/running tasks
- All handlers route through the queue instead of calling Coder directly
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 21sDetails
An edited comment during analysis is equally meaningful as a new one
for continuing the conversation with the analyst.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Publish Image / publish (push) Successful in 46sDetails
Builds and pushes to registry.samson.media on any version tag,
tagged with both the version and latest.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Lightweight Hono webhook router that receives Gitea events and creates
Coder workspaces for each SDLC stage (analyse, architect, develop,
review, test, rework, release, maintenance). Includes k8s manifests
for deployment and the Coder workspace template moved from babble.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>