Assign a ticket. Get a PR. Zero human involvement.
A production AI developer agent that reads Linear tickets, analyzes your codebase, writes production-ready code, and opens GitHub PRs — fully automated using Claude Code CLI on AWS Fargate.
- Assign a ticket in Linear → agent analyzes the codebase, posts a detailed implementation plan as a comment
- Reply "go ahead" → agent writes the code, opens a GitHub PR, posts the link back to Linear
- Comment
@ai-developer-agenton any PR → agent posts a structured code review or pushes fixes directly to the branch
No rigid commands. Natural language. The agent behaves like a real team member.
graph TD
A[Developer assigns ticket in Linear] --> B[Linear sends AgentSessionEvent webhook]
B --> C[AWS API Gateway]
C --> D[AWS Lambda - handler.py]
D --> E[Validate OAuth token]
E --> F[Detect repo - frontend or backend]
F --> G[Post acknowledgment to Linear]
G --> H[Start AWS ECS Fargate task]
H --> I[Container pulls Claude Code CLI image]
I --> J[Clone GitHub repo]
J --> K[Claude Code explores codebase]
K --> L{Mode?}
L -->|Plan| M[Post implementation plan to Linear]
L -->|Approve| N[Write code + open GitHub PR]
L -->|Review| O[Post code review to GitHub PR]
N --> P[Post PR link to Linear]
O --> Q[Push fixes if requested]
These PRs were opened automatically — no human wrote the code:
PR #882 — Health check endpoint in a production Rails API Agent read the codebase, identified the existing controller and routing patterns, mirrored them exactly, wrote a request spec, and explained its reasoning in the PR description. The PR was mergeable on first run.
PR #892 — Full Cash Report module 25 files changed, 7 API endpoints. Agent mirrored an existing Sales Tax V2 module structure without being told to, correctly wired up serializers, services, and routes following the project's exact conventions.
| Mode | Trigger | What Happens |
|---|---|---|
| Plan | Ticket assigned to agent | Agent explores codebase, posts a detailed implementation plan with specific files and changes |
| Approve | Reply "go ahead" or "implement this" | Agent writes the code, commits to a feature branch, opens a PR |
| Review | @agent comment on GitHub PR |
Agent reviews the diff, posts structured feedback, optionally pushes fixes |
The agent reads the ticket title and description to route to the correct repository and branch — no configuration needed per ticket. Add REPO: <url> to the ticket description to override.
Editable source: docs/architecture.drawio — open with diagrams.net
Linear webhook → API Gateway → Lambda (Python 3.12)
↓
DynamoDB (state) + Secrets Manager (keys)
↓
ECS Fargate (serverless)
↓
Git clone → Claude Code CLI → Git push
↓
GitHub PR + Linear comment
Key design decisions:
- Lambda handles the webhook in < 2 seconds, Fargate does the heavy lifting (up to 20 min)
- Linear OAuth App with
actor=app— the agent has its own bot identity, not a fake member account - GitHub App JWT auth — short-lived installation tokens, no long-lived PATs in Fargate containers
- Automatic OAuth token refresh — if the Linear token expires, Lambda refreshes it and posts a renewal notice
- DynamoDB dedup guard — prevents double Fargate launches when GitHub delivers webhooks twice
TICKET_PROMPTcapped at 3,500 chars — stays inside ECS container override 8,192-byte JSON limit
| Component | Technology |
|---|---|
| AI Engine | Claude Code CLI (@anthropic-ai/claude-code v2.1.x) |
| Compute | AWS ECS Fargate (2 vCPU / 4 GB RAM, serverless) |
| Trigger | AWS Lambda (Python 3.12) |
| Webhooks | AWS API Gateway v2 (HTTP API) |
| State | AWS DynamoDB (PAY_PER_REQUEST) |
| Secrets | AWS Secrets Manager |
| Registry | AWS ECR |
| Infrastructure | Terraform |
| Linear integration | OAuth App with actor=app |
| GitHub integration | GitHub App (JWT → installation access token) |
| Item | Cost |
|---|---|
| Infrastructure idle | ~$1/month |
| Anthropic API per ticket | $0.50 – $5.00 (complexity-dependent) |
| AWS Fargate per ticket | ~$0.03 (10 min at 2 vCPU / 4 GB) |
| Monthly at 50 tickets | ~$30 – $60 total |
There is zero Fargate cost when idle — containers spin up per ticket and terminate.
| Version | Approach | Output Quality |
|---|---|---|
| v1 | Direct Claude API calls via Lambda — single pass, no codebase exploration | Functional but shallow |
| v2 | Claude Code CLI in Fargate — full codebase exploration, iterative, self-correcting | Production-grade, indistinguishable from human code |
The switch from raw API to Claude Code CLI was the core insight. Claude Code explores the repo with real file reads and searches before writing a single line — it understands conventions, mirrors patterns, and catches edge cases the same way a human developer would.
See docs/setup-guide.md for full setup instructions and docs/architecture.md for detailed system design.
- AWS account with admin access
- Anthropic API key
- Linear workspace with admin access
- GitHub organization
# 1. Clone and configure
git clone https://github.com/Kalkireddy/AI_DEVELOPER_AGENT_PORTFOLIO.git
cd AI_DEVELOPER_AGENT_PORTFOLIO
cp .env.example .env
# Fill in .env values
# 2. Deploy infrastructure
cd terraform
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your values
terraform init && terraform apply
# Note the ecr_repository_url and api_gateway_url from outputs
# 3. Build and push Docker image
ECR_URL=$(terraform output -raw ecr_repository_url)
docker build --platform linux/amd64 -t claude-code-agent docker/
docker tag claude-code-agent:latest $ECR_URL:latest
docker push $ECR_URL:latest
# 4. Store secrets
aws secretsmanager put-secret-value \
--secret-id claude-code-agent-secrets \
--secret-string file://secrets.json
# 5. Configure Linear OAuth App webhook
# Use webhook_linear_url from terraform output
# 6. Configure GitHub App webhook
# Use webhook_github_url from terraform output| Tool | Model | Hosting | Cost at rest | Your data |
|---|---|---|---|---|
| Cursor | Claude / GPT | Local IDE | Free | Local only |
| Devin | Proprietary | Devin's cloud | ~$500/month | Their servers |
| This project | Claude Code | Your AWS | ~$1/month | Your AWS account |
MIT
