Building a Hands-Off Coding Workflow
Or: How I learned to stop worrying and let Claude do the coding.
Picture this: You write a ticket describing what you want, grab a coffee, and come back to find a pull request waiting for your review. No context switching. No boilerplate grinding. Just pure, automated implementation.
Sounds like a dream? I built it. Here's the entire pipeline:
Let me walk you through each piece.
1The Ticket That Starts It All
Everything begins in Linear. But not just any ticket. You need to be specific. Claude is smart, but it's not a mind reader. The more context you pack into that description, the better the output.
I use a simple convention: when I want Claude to handle a ticket, I either assign it to a "Claude Code" user or add a specific label. This triggers the whole chain.
## Add dark mode toggle to settings
### Context
Users have been requesting dark mode. We already
have the theme context set up in /providers.
### Requirements
- Toggle switch in settings page
- Persist to localStorage
- Immediate theme switch (no flash)
### Files to look at
- src/providers/theme-provider.tsx
- src/app/settings/page.tsx
### Acceptance Criteria
✓ Toggle visible and functional
✓ Persists across sessions
✓ Matches existing UI patternsPro tip: Point Claude to specific files. It'll still explore the codebase, but this helps it start in the right place.
2The Webhook Listener
When a ticket gets assigned to Claude, Linear fires a webhook. I use a Cloudflare Worker to catch it. It's fast, cheap, and serverless. The worker validates the request, extracts the ticket data, and triggers a GitHub Action.
export default {
async fetch(request: Request, env: Env) {
const payload = await request.json();
// Verify Linear's webhook signature
const signature = request.headers.get('linear-signature');
if (!verifySignature(payload, signature, env.LINEAR_WEBHOOK_SECRET)) {
return new Response('Invalid signature', { status: 401 });
}
// Only process when assigned to Claude
if (payload.data.assignee?.name !== 'Claude Code') {
return new Response('Ignored');
}
// Trigger GitHub Actions via repository_dispatch
await fetch(
`https://api.github.com/repos/${env.GITHUB_REPO}/dispatches`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github.v3+json',
},
body: JSON.stringify({
event_type: 'claude-ticket',
client_payload: {
ticket_id: payload.data.id,
title: payload.data.title,
description: payload.data.description,
branch: `claude/${payload.data.identifier}`
}
})
}
);
return new Response('Triggered');
}
}Environment secrets you'll need in Cloudflare:
LINEAR_WEBHOOK_SECRET- From Linear's webhook settingsGITHUB_TOKEN- Personal access token with repo & workflow permissionsGITHUB_REPO- Format: owner/repo-name
3The GitHub Action Magic
This is where Claude Code takes over. The GitHub Action receives the ticket context and runs Claude with full access to your repository. Claude reads the codebase, understands the patterns, and implements the changes.
name: Claude Code Implementation
on:
repository_dispatch:
types: [claude-ticket]
jobs:
implement:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Create feature branch
run: |
git checkout -b ${{ github.event.client_payload.branch }}
- name: Run Claude Code
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
You are implementing a ticket for this codebase.
**Ticket:** ${{ github.event.client_payload.title }}
**Description:**
${{ github.event.client_payload.description }}
Instructions:
- Explore the codebase to understand patterns
- Implement the requirements completely
- Follow existing code style
- Test your changes work
- name: Commit and push
run: |
git config user.name "Claude Code"
git config user.email "claude@anthropic.com"
git add -A
git commit -m "feat: ${{ github.event.client_payload.title }}"
git push origin ${{ github.event.client_payload.branch }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.event.client_payload.branch }}
title: "${{ github.event.client_payload.title }}"
body: |
## 🤖 Automated PR by Claude Code
**Linear Ticket:** ${{ github.event.client_payload.ticket_id }}
### Changes
Implemented based on the ticket description.
---
*This PR was automatically generated. Please review carefully.*Setting up your GitHub Secrets
Go to your repo → Settings → Secrets and variables → Actions, and add:
ANTHROPIC_API_KEY- Your Anthropic API key (get it from console.anthropic.com)GITHUB_TOKEN- This is auto-provided, but ensure it has write permissions in repo settings
You'll also need to enable "Allow GitHub Actions to create and approve pull requests" in your repository settings under Actions → General → Workflow permissions.
4The Human Touch
Here's the thing: I'm not trying to remove developers from the loop. Claude is a fast, capable junior dev, but it still needs oversight. The PR lands in your queue, you review it, maybe leave some comments, and merge when satisfied.
Sometimes Claude nails it first try. Sometimes it needs a nudge. Either way, you're spending your time on reviewing code, not writing boilerplate.
So... does it work?
Yeah. Stupidly well.
The real win isn't speed, it's focus. I spend my mental energy on architecture, complex problems, and code review. The routine stuff? Claude handles it.
What I learned
Detailed tickets = better code. Vague tickets get vague implementations. Spend the 2 extra minutes writing a good description.
Start small. Your first ticket shouldn't be "rewrite the auth system." Start with "add a loading spinner to this button." Build trust.
Clean codebases help everyone. If your codebase has clear patterns and good organization, Claude picks up on it. If it's a mess, well... garbage in, garbage out.
This workflow has changed how I think about development. It's not about AI replacing developers. It's about freeing them to do the work that actually matters.
The future is collaborative. Humans set the direction, AI handles the execution, and everyone moves faster.
Now if you'll excuse me, I have some PRs to review. ✌️