You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: implement worker core, tests, bot, CI/CD, and Dockerfile (#15)
* feat: implement worker core, tests, bot, CI/CD, and Dockerfile
Worker (apps/worker):
- Queue poller with atomic claiming, stale recovery, graceful SIGTERM requeue
- Dev loop (Ralph Loop): clone → detect → install → Claude loop → test → PR
- Claude Agent SDK wrapper for spawning Claude Code sessions
- Test runner auto-detection for pytest, jest, vitest, playwright, go, cargo
- Git operations: clone, branch, commit, push, create PR
- HTTP server with health, drain, cancel endpoints + scale-to-zero
- 53 tests across 6 test files, all passing
Telegram Bot (apps/bot):
- grammY-based bot with /start, /task, /status, /cancel commands
- Supabase realtime subscription for streaming job events to chat
- Inline keyboard for PR approve/reject actions
Infrastructure:
- Production multi-stage Dockerfile (Node 22, Python/uv, Go, Rust)
- GitHub Actions CI (lint + test + build) and deploy (Fly.io)
- Updated shared types (retry fields, DevLoopConfig, DevLoopResult)
- Updated SQL migration (attempt, max_attempts, github_token columns)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: security issues, deployment blockers, and build config
- Fix command injection in createPullRequest (use execFileSync instead of execSync)
- Add try-catch to installDependencies with proper error propagation
- Use WORKSPACE_DIR env var instead of hardcoded /tmp path in dev-loop
- Add GitHub CLI (gh) to Dockerfile for PR creation
- Copy .dockerignore to repo root for proper Docker build context
- Add composite: true to shared tsconfig for project references
- Fix migration to use gen_random_uuid() instead of uuid_generate_v4()
- Add Supabase config files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: reduce Fly.io memory to 4GB (shared CPU limit)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: install Claude Code CLI in Docker for agent SDK
The @anthropic-ai/claude-agent-sdk spawns a Claude Code subprocess
via the query() function. The CLI must be globally installed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update URLs for repo rename to openadapt-wright
Update stale OpenAdaptAI/wright URLs to OpenAdaptAI/openadapt-wright
in both README.md and dev-loop.ts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: strip ANSI escape codes before parsing test output
Test runners emit colored output that broke our regex parsers,
causing 0/0 results even when tests were actually passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add vitest output format parser for correct test result extraction
Vitest uses "Tests 2 passed (2)" format while Jest uses "Tests: 2 failed, 5 passed, 7 total".
The parser now handles both formats, fixing the 0/0 results seen in production.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: clone specified branch and add vitest output parser
- cloneRepo now accepts an optional branch parameter to checkout the
correct base branch instead of always cloning the default branch
- dev-loop passes job.branch to cloneRepo so auto-detection works
against the right codebase
- parseJest now handles vitest's output format ("Tests 2 passed (2)")
in addition to jest's format ("Tests: 2 failed, 5 passed, 7 total")
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: disable Fly.io auto-stop to prevent job interruption
Fly.io's auto_stop_machines was killing the worker during long Claude
sessions because execSync blocks the event loop, preventing health
checks from responding. Now the worker manages its own lifecycle
via the 5-minute idle timer (process.exit(0)).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: security and correctness fixes for worker and bot (#17)
* fix: security and correctness fixes for worker and bot
- Allowlist env vars passed to Claude subprocess (prevent leaking
SUPABASE_SERVICE_ROLE_KEY, BOT_TOKEN, GITHUB_TOKEN, etc.)
- Wire AbortController from queue-poller through dev-loop to
claude-session for graceful SIGTERM cancellation
- Add github_token to bot insertJob (fixes NOT NULL constraint failure)
- Add Telegram chat ID allowlist middleware (ALLOWED_TELEGRAM_USERS)
- Add @types/node to shared and bot packages (fixes pre-existing
build failures)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add TMPDIR to env allowlist and use once for abort listener
- Add TMPDIR/TMP/TEMP to allowed env vars (git/npm need temp dirs)
- Use { once: true } on abort signal listener to prevent accumulation
across loop iterations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: simplify abortController pass-through and filter NaN from allowlist
- Pass abortController directly instead of conditional spread
- Filter non-finite values from ALLOWED_TELEGRAM_USERS parsing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Wright is a generalized dev automation platform that takes task descriptions, uses the Claude Agent SDK to generate code, runs tests iteratively (the Ralph Loop pattern), and creates pull requests -- with a Telegram bot for human-in-the-loop approval.
4
4
5
+
## Test Results
6
+
7
+
**53 tests passing** across 6 test suites, covering the full pipeline from detection to dev loop execution.
8
+
9
+
```
10
+
✓ src/__tests__/test-runner.test.ts (30 tests) — auto-detection + test execution
0 commit comments