clawdup is an open-source pipeline that connects ClickUp task management to GitHub pull requests through AI-powered code implementation. This post walks through every stage of the pipeline, explaining how each component works and why it's designed the way it is.
The Pipeline at a Glance
At its core, clawdup runs a continuous loop:
ClickUp Task → Git Branch → Claude Code → Commit → Push → GitHub PR → Status Update
Each stage is handled by a dedicated module, keeping the codebase modular and each responsibility isolated. Let's walk through them.
Stage 1: Polling ClickUp
The pipeline starts with the runner module, which polls your ClickUp list every 30 seconds (configurable via POLL_INTERVAL_MS). It uses the ClickUp API v2 to fetch tasks with the "to do" status, sorted by priority.
When a task is found, the runner immediately moves it to "in progress" status. This prevents other instances of clawdup (or other developers) from picking up the same task — a simple but effective locking mechanism.
The ClickUp API client is minimal by design. It uses Node.js's native fetch (available in Node 18+) with no HTTP library dependencies. Error handling includes retry logic for transient failures and clear error messages for configuration issues.
Stage 2: Branch Creation
Once a task is claimed, the git-ops module creates a feature branch. The branch name follows a strict format:
clickup/CU-{task-id}-{slug}
For example, a task titled "Add user authentication" with ID abc123 becomes clickup/CU-abc123-add-user-authentication.
This naming convention serves two purposes. First, it includes the ClickUp task ID prefixed with CU-, which ClickUp's GitHub integration recognizes and uses to automatically link the branch to the task. Second, the human-readable slug makes it easy to identify what a branch is for when browsing the repository.
The branch is created from the configured base branch (default: main), ensuring every task starts from a clean, up-to-date state.
Stage 3: AI-Powered Implementation
This is where the real work happens. The claude-worker module invokes Claude Code — Anthropic's AI coding CLI — with a carefully constructed prompt that includes:
- The task description from ClickUp, sanitized to prevent prompt injection
- Project context from your
CLAUDE.mdfile (coding conventions, architecture decisions, etc.) - Security boundaries — explicit instructions about what the AI can and cannot do
- Custom instructions from your
clawdup.config.mjsif configured
Claude Code runs as a subprocess, and clawdup consumes its output as a JSONL stream. This streaming approach lets the pipeline track progress in real-time, log intermediate results, and detect problems early.
The implementation has a configurable timeout (default: 10 minutes via CLAUDE_TIMEOUT_MS) and a maximum number of agentic turns (default: 50 via CLAUDE_MAX_TURNS). If Claude needs clarification, it can signal this through a structured response, and clawdup will move the task to "require input" status and post a comment explaining what's needed.
Stage 4: Commit, Push, and PR Creation
After Claude Code finishes, clawdup checks if any files were actually changed. If so, it:
- Commits the changes with a message formatted as
[CU-{task-id}] {description} - Pushes the branch to the remote repository
- Creates a pull request using the GitHub CLI (
gh), with the task title and a link back to the ClickUp task
The PR title also includes the CU-{task-id} prefix, which means ClickUp's GitHub integration automatically links the PR to the task. Reviewers can click through from the PR to the task description and vice versa.
If no files were changed (Claude determined no code changes were needed), clawdup moves the task to "require input" and posts a comment explaining the situation.
Stage 5: Status Management
Throughout the pipeline, task statuses are updated in real-time:
- to do → in progress: Task picked up by the automation
- in progress → in review: PR created, ready for human review
- in progress → require input: Claude needs clarification
- in progress → blocked: An error occurred
- approved → complete: PR merged after human approval
This means your ClickUp board always reflects the actual state of work. There's no lag between "code is done" and "board is updated" — they happen simultaneously.
The Merge Loop
clawdup also watches for tasks in the "approved" status. When a reviewer moves a task to "approved," the pipeline automatically merges the associated PR and moves the task to "complete." This closes the full loop from task creation to code delivery.
The merge uses the GitHub CLI's merge command, which respects your repository's merge strategy settings (merge commit, squash, or rebase).
Error Handling and Recovery
Real-world automation needs to handle failures gracefully. clawdup includes several resilience mechanisms:
- Crash recovery: If clawdup crashes while processing a task, it detects "orphaned" in-progress tasks on restart and either resumes or resets them
- Timeout protection: Claude Code execution has a hard timeout to prevent runaway processes
- Status-based error reporting: Failures move tasks to "blocked" status with a comment explaining what went wrong, making it easy for a human to investigate and retry
- Clean branch state: Each task starts from a fresh checkout of the base branch, preventing contamination between tasks
Configuration Cascade
clawdup uses a layered configuration system:
- Environment variables (highest priority)
- .clawdup.env file in the working directory
- clawdup.config.mjs for Claude-specific settings
- Defaults (lowest priority)
This cascade means you can set project-wide defaults in a config file and override specific values per-environment using environment variables. In a monorepo, each package can have its own .clawdup.env pointing to a different ClickUp list while sharing the same repository.
Why This Architecture
Every design decision in clawdup serves the goal of being reliable, simple, and transparent:
- Zero runtime dependencies means fewer things can break and no supply chain concerns
- CLI tools (git, gh, claude) instead of API libraries means leveraging well-tested, well-maintained tools
- Streaming JSONL parsing means real-time progress visibility
- Security-first input handling means you can safely feed untrusted task descriptions to the AI
The result is a pipeline that does one thing well: turns ClickUp tasks into reviewed, mergeable pull requests.