31 Commits
Author SHA1 Message Date
Daniel SamsonandClaude Opus 4.6 546d2615c7 feat: re-trigger tester when human comments on a PR
Publish Image / publish (push) Successful in 22s
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>
v1.3.9
2026-04-12 20:57:46 +01:00
Daniel SamsonandClaude Opus 4.6 f693d56762 Handle Gitea review webhook type field alongside state
Publish Image / publish (push) Successful in 23s
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>
v1.3.8
2026-04-12 18:13:51 +01:00
Daniel SamsonandClaude Opus 4.6 a72ea9ad1d Fix BullMQ job dedup — remove completed/failed jobs
Publish Image / publish (push) Successful in 21s
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>
v1.3.7
2026-04-12 16:37:52 +01:00
Daniel SamsonandClaude Opus 4.6 2cdf68ddff Fix pr-rework crash — guard against missing review.state
Publish Image / publish (push) Successful in 23s
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>
v1.3.6
2026-04-12 16:26:58 +01:00
Daniel SamsonandClaude Opus 4.6 81aee2f7fc Route spec PR review feedback to rework-spec instead of rework-pr
Publish Image / publish (push) Successful in 23s
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>
v1.3.5
2026-04-12 16:18:00 +01:00
Daniel SamsonandClaude Opus 4.6 f495ea391f Fix issue-label and pr-rework webhook handlers
Publish Image / publish (push) Successful in 22s
- 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>
v1.3.4
2026-04-12 16:12:04 +01:00
Daniel SamsonandClaude Opus 4.6 d19798dfea Add debug logging to issue-label handler
Publish Image / publish (push) Successful in 23s
Log the webhook action and labels to diagnose why label events are
being ignored.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
v1.3.3
2026-04-12 15:56:19 +01:00
Daniel SamsonandClaude Opus 4.6 0812a9be37 Fix workspace deletion — use build transition API
Publish Image / publish (push) Successful in 35s
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>
v1.3.2
2026-04-12 15:51:24 +01:00
Daniel SamsonandClaude Opus 4.6 66649022ca Fix BullMQ jobId format — colons are not allowed
Publish Image / publish (push) Successful in 26s
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>
v1.3.1
2026-04-12 15:48:47 +01:00
Daniel SamsonandClaude Opus 4.6 13e96e9356 Migrate task queue from in-memory to BullMQ + Redis
Publish Image / publish (push) Successful in 36s
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>
v1.3.0
2026-04-12 15:40:12 +01:00
Daniel SamsonandClaude Opus 4.6 a6ff7b7fb5 Stop workspace before deleting — Coder returns 405 on running workspaces
Publish Image / publish (push) Successful in 21s
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>
v1.0.7
2026-04-12 15:18:54 +01:00
Daniel SamsonandClaude Opus 4.6 b43e38ec54 Comprehensive setup guide for adding new projects
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>
2026-04-12 15:03:40 +01:00
Daniel SamsonandClaude Opus 4.6 b42b325dd3 Remove ANTHROPIC_API_KEY from workspace — it overrides OAuth token
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>
2026-04-12 14:55:12 +01:00
Daniel SamsonandClaude Opus 4.6 abbe47b1b9 Support Claude Code Max via OAuth token
Publish Image / publish (push) Successful in 21s
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>
v1.0.6
2026-04-12 14:52:01 +01:00
Daniel SamsonandClaude Opus 4.6 9bca465565 Skip build for lightweight stages (analyse, architect, release, maintenance)
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>
2026-04-12 14:47:48 +01:00
Daniel SamsonandClaude Opus 4.6 d220623a9f Always fire callback via trap, even on script failure
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>
2026-04-12 14:42:18 +01:00
Daniel SamsonandClaude Opus 4.6 e801d96410 Ephemeral workspaces: remove PVC, use emptyDir
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>
2026-04-12 14:27:30 +01:00
Daniel SamsonandClaude Opus 4.6 869d82998b Fresh clone on every automated task, generic repo setup
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>
2026-04-12 14:25:17 +01:00
Daniel SamsonandClaude Opus 4.6 aa986a470e Remove log viewer app, output goes to agent logs directly
Publish Image / publish (push) Successful in 15s
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>
v1.0.5
2026-04-12 14:18:00 +01:00
Daniel SamsonandClaude Opus 4.6 520fc8f81e Custom workspace image + fix slash command invocation
Publish Workspace Image / publish (push) Successful in 3m51s
- 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>
2026-04-12 14:15:17 +01:00
Daniel SamsonandClaude Opus 4.6 d46e3ca247 Fix slash command invocation: /analyse not /project:analyse
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>
2026-04-12 14:09:08 +01:00
Daniel SamsonandClaude Opus 4.6 ec0b012586 Reconcile queue state on startup, remove age-based staleness check
Publish Image / publish (push) Successful in 20s
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>
v1.0.4
2026-04-12 14:01:56 +01:00
Daniel SamsonandClaude Opus 4.6 36c80458e0 Safe 409 handling: check workspace age/status before deleting
Publish Image / publish (push) Successful in 20s
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>
v1.0.3
2026-04-12 13:59:59 +01:00
Daniel SamsonandClaude Opus 4.6 06cf4d1b9e Handle stale workspaces: 409 conflict auto-cleanup + verbose logging
Publish Image / publish (push) Successful in 20s
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>
v1.0.2
2026-04-12 13:58:08 +01:00
Daniel SamsonandClaude Opus 4.6 4f1d306fdf Fix ImagePullBackOff: use multi-arch base image tag
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>
2026-04-12 13:44:44 +01:00
Daniel SamsonandClaude Opus 4.6 7145fb536a Add workspace lifecycle management via task-complete callback
Publish Image / publish (push) Successful in 20s
- 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>
v1.2.0
2026-04-12 13:37:08 +01:00
Daniel SamsonandClaude Opus 4.6 f23fb4e2e0 Add task queue with dedup and concurrency control
Publish Image / publish (push) Successful in 54s
- 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>
v1.1.0
2026-04-12 13:30:27 +01:00
Daniel SamsonandClaude Opus 4.6 6062d1b518 Trigger analyst on edited comments, not just new ones
Publish Image / publish (push) Successful in 21s
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>
v1.0.1
2026-04-12 13:13:39 +01:00
Daniel SamsonandClaude Opus 4.6 4e5993f489 Fix cert-manager ClusterIssuer name to letsencrypt-prod
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-12 13:02:08 +01:00
Daniel SamsonandClaude Opus 4.6 1b25c39d1b Add CI workflow to publish Docker image on tag
Publish Image / publish (push) Successful in 46s
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>
v1.0.0
2026-04-12 12:48:36 +01:00
Daniel SamsonandClaude Opus 4.6 55dee1f2bd Initial commit: SDLC Orchestrator replacing n8n
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>
2026-04-12 12:44:28 +01:00