@devintern/code supports both single task processing and batch processing of multiple tasks from your configured tracker (Jira, Linear, Trello). Batch processing uses JQL for Jira, a JSON IssueFilter for Linear, or explicit task lists.
Requires Bun runtime. Install globally:
# Install Bun if not already installed
curl -fsSL https://bun.sh/install | bash
# Install @devintern/code globally
bun install -g @getdevintern/code
# Or use directly without installing
bunx @getdevintern/code PROJ-123The easiest way to set up @devintern/code for your project is using the init command:
# Initialize project-specific configuration
devintern initThis creates a .devintern-code folder in your current project with:
.env- Your project-specific configuration file with JIRA credentials.env.example- Template with all configuration optionssettings.json- Per-project settings (status transitions, story points field, etc.)
Automatic .gitignore Protection: The init command automatically adds .devintern-code/.env to your .gitignore file (or creates one if it doesn't exist) to prevent accidentally committing credentials to version control.
After running init:
- Edit
.devintern-code/.envwith your JIRA credentials - (Optional) Edit
.devintern-code/settings.jsonto configure per-project status transitions for your task tracker
Alternatively, create an environment file manually in your project directory or globally:
cat > .env << EOF
JIRA_BASE_URL=https://your-company.atlassian.net
JIRA_EMAIL=your-email@company.com
JIRA_API_TOKEN=your-api-token-here
# Optional: only set if the agent CLI is not on your PATH
# AGENT_CLI_PATH=/custom/path/to/claude
# Optional: GitHub auth (see ENV_SETUP.md)
# Personal / interactive (free CLI): GITHUB_TOKEN
# Workspace automation: GITHUB_TOKEN + the central App through the hosted relay
GITHUB_TOKEN=your-github-token-here
# Advanced no-relay installs only:
# GITHUB_APP_ID=123456
# GITHUB_APP_PRIVATE_KEY_PATH=/path/to/private-key.pem
# Bitbucket
BITBUCKET_TOKEN=your-bitbucket-token-here
EOFGet JIRA API Token:
- Go to https://id.atlassian.com/manage-profile/security/api-tokens
- Create a new token
- Copy it to your
.envfile
The tool searches for .env files in the following order:
- Custom path (if specified with
--env-file) - Project-specific (
.devintern-code/.env- recommended) - Current working directory (
.env) - User home directory (
~/.env) - Tool installation directory
The settings.json file supports tracker-specific sections so you can prepare configurations for any supported task tracker, even before full client support lands in @devintern/code.
- Jira (
jira) - Linear (
linear) - Trello (
trello) - Azure DevOps (
azure-devops) - Asana (
asana) - GitHub Issues (
github) - Markdown (
markdown)
{
"jira": {
"projects": {
"PROJ": {
"inProgressStatus": "In Progress",
"todoStatus": "To Do",
"prStatus": "In Review",
"storyPointsField": "customfield_10016"
}
}
},
"linear": {
"projects": {
"ENG": {
"inProgressStatus": "In Progress",
"todoStatus": "Backlog",
"prStatus": "In Review"
}
}
},
"trello": {
"projects": {
"BOARD": {
"inProgressStatus": "Doing",
"todoStatus": "To Do",
"prStatus": "Code Review"
}
}
},
"github": {
"projects": {
"REPO": {
"inProgressStatus": "in progress",
"todoStatus": "todo",
"prStatus": "in review"
}
}
}
}Existing Jira-only settings.json files using the legacy top-level projects key continue to work:
{
"projects": {
"PROJ": {
"inProgressStatus": "In Progress",
"todoStatus": "To Do",
"prStatus": "In Review"
}
}
}The tool automatically resolves the correct configuration based on the TASK_TRACKER environment variable (default: jira).
You can also set variables in your shell profile:
# Add to ~/.zshrc or ~/.bashrc
export JIRA_BASE_URL="https://your-company.atlassian.net"
export JIRA_EMAIL="your-email@company.com"
export JIRA_API_TOKEN="your-api-token"
# Optional: only set if the agent CLI is not on your PATH
# export AGENT_CLI_PATH="/custom/path/to/claude"
# Optional: For PR creation (see ENV_SETUP.md for details)
export GITHUB_TOKEN="your-github-token"
export BITBUCKET_TOKEN="your-bitbucket-token"This is the most common use case - you're in your project's git repository and want to implement a JIRA task:
# Navigate to your project
cd /path/to/your/project
# Ensure you have a .env file with JIRA credentials
# (either in this directory or globally accessible)
# Run devintern - it will:
# 1. Fetch JIRA task details
# 2. Create feature branch (e.g., feature/proj-123)
# 3. Run Claude with the task details
devintern PROJ-123# Save task artifacts to a custom directory (default: /tmp/devintern-tasks)
DEVINTERN_OUTPUT_DIR=~/tasks/devintern devintern PROJ-123
# Use custom agent CLI path
devintern PROJ-123 --agent-path /usr/local/bin/claude
# Override max turns for very complex tasks (default: 500)
devintern PROJ-123 --max-turns 1000# Get detailed output for troubleshooting
devintern PROJ-123 --verbose
# Skip git operations if you have uncommitted changes
devintern PROJ-123 --no-git
# Increase max turns for very complex tasks (default: 500)
devintern PROJ-123 --max-turns 1000
# Skip automatic commit after Claude completes
devintern PROJ-123 --no-auto-commit
# Create pull request after implementation
devintern PROJ-123 --create-pr
# Create pull request targeting specific branch
devintern PROJ-123 --create-pr --pr-target-branch develop# Automatically create PR after implementation (GitHub or Bitbucket)
devintern PROJ-123 --create-pr
# Create PR targeting a specific branch instead of main
devintern PROJ-123 --create-pr --pr-target-branch develop
# Combine with other options
devintern PROJ-123 --create-pr --max-turns 1000 --verbose
# PR creation works with both platforms:
# - GitHub: Detects from git remote, uses GITHUB_TOKEN or GitHub App
# - Bitbucket: Detects workspace from git remote, uses BITBUCKET_TOKENProcess multiple tasks by specifying their keys explicitly:
# Process 3 specific tasks sequentially
devintern PROJ-123 PROJ-124 PROJ-125
# With additional options
devintern PROJ-123 PROJ-124 PROJ-125 --create-pr --max-turns 500
# Each task gets its own output directory under DEVINTERN_OUTPUT_DIR (default: /tmp/devintern-tasks):
# - /tmp/devintern-tasks/proj-123/task-details.md
# - /tmp/devintern-tasks/proj-124/task-details.md
# - /tmp/devintern-tasks/proj-125/task-details.mdUse JIRA Query Language to dynamically select tasks:
# Process all "To Do" tasks in a project
devintern --jql "project = PROJ AND status = 'To Do'"
# Process tasks assigned to you
devintern --jql "assignee = currentUser() AND status = 'To Do'"
# Process frontend bugs with high priority
devintern --jql "labels = 'frontend' AND type = Bug AND priority = High"
# Complex query with custom fields
devintern --jql "project = \"My Project\" AND cf[10016] <= 3 AND labels IN (FrontEnd, MobileApp)"When TASK_TRACKER=linear, --query accepts either a JSON-serialized Linear IssueFilter object (passed to Linear's GraphQL API) or a plain-text string matched against issue titles. The CLI flag is still --query; only the syntax differs from Jira JQL.
# Single Linear issue
devintern ENG-42 --create-pr
# Process all "In Progress" issues assigned to you
devintern --query '{"state":{"name":{"eq":"In Progress"}}}' --create-pr
# Process all issues with the "intern" label (typical worker query)
devintern --query '{"labels":{"name":{"eq":"intern"}}}' --create-pr
# Process high-priority issues
devintern --query '{"priority":{"eq":1}}' --create-pr
# Combine filters — "intern" label AND "In Progress" state
devintern --query '{"labels":{"name":{"eq":"intern"}},"state":{"name":{"eq":"In Progress"}}}' --create-prThe full IssueFilter schema is available at https://studio.linear.app/graphql (search for IssueFilter). For more examples, see the Linear Integration guide.
# Process all tasks in current sprint assigned to you
devintern --jql "assignee = currentUser() AND sprint in openSprints()"
# Process all tasks in a specific epic
devintern --jql "\"Epic Link\" = PROJ-100" --create-pr --pr-target-branch develop
# Process backlog items with specific story points
devintern --jql "status = 'Backlog' AND \"Story Points\" <= 5" --max-turns 300
# Process recent bugs (created in last 7 days)
devintern --jql "type = Bug AND created >= -7d" --skip-clarity-check# Process tasks with verbose output to see progress
devintern --jql "project = PROJ AND status = 'To Do'" --verbose
# Skip clarity checks for faster batch processing
devintern PROJ-101 PROJ-102 PROJ-103 --skip-clarity-check
# Continue processing even if some tasks fail
# (This is the default behavior - failed tasks don't stop the batch)
devintern --jql "labels = 'refactoring'" --max-turns 500
# Batch summary will show:
# - Total tasks processed
# - Number of successful implementations
# - Number of failed tasks with error details# Custom output directory for batch processing
DEVINTERN_OUTPUT_DIR=/tmp/batch-tasks devintern PROJ-123 PROJ-124
# Creates:
# - /tmp/batch-tasks/proj-123/task-details.md
# - /tmp/batch-tasks/proj-124/task-details.md
# Faster batch processing — skip clarity check (agent still runs)
devintern --jql "sprint = 'Sprint 1'" --skip-clarity-check
# Batch without git branch creation or Jira comments
devintern --jql "status = 'To Do'" --no-git --skip-jira-comments# 1. Go to your project directory
cd ~/projects/my-app
# 2. Check git status (should be clean)
git status
# 3. Run devintern
devintern MYAPP-456
# Expected output:
# 🔍 Fetching JIRA task: MYAPP-456
# 📋 Task Summary: Implement user authentication
# 💾 Saving formatted task details to: ./task-details.md
# 🌿 Creating feature branch...
# ✅ Created and switched to new branch 'feature/myapp-456'
# 🤖 Running Claude with task details...
# [Claude implements the task...]
# ✅ Claude execution completed successfully
# 📝 Committing changes...
# ✅ Successfully committed changes for MYAPP-456- Creates branches with format:
feature/task-id - Converts task keys to lowercase:
PROJ-123→feature/proj-123 - Checks for uncommitted changes before creating branches
- Switches to existing branch if it already exists
- Commits all changes after Claude successfully completes
- Uses descriptive commit message:
feat: implement TASK-123 - Task Summary - Can be disabled with
--no-auto-commitflag
- Automatically creates PRs on GitHub or Bitbucket after successful implementation
- Detects repository platform from git remote URL
- PR title format:
[TASK-123] Task Summary - PR body includes Claude's implementation details and links back to JIRA
- GitHub: Uses
GITHUB_TOKENfor CLI and relay-backed workspace API access (see ENV_SETUP.md). The central DevIntern AI App supplies workspace events through the relay. Customer-owned Apps are an advanced no-relay option. - Bitbucket: Requires
BITBUCKET_TOKEN(Repositories: Write), workspace auto-detected from git remote - Can be enabled with
--create-prflag - Target branch can be specified with
--pr-target-branch. If omitted (or if the named branch does not exist on the remote), the repository default branch is used
- Must be in a git repository
- No uncommitted changes (commit or stash first)
- Git must be available in PATH
# If you have uncommitted changes:
git add . && git commit -m "WIP: saving progress"
# or
git stash
# Then run devintern
devintern PROJ-123
# If you don't want git integration:
devintern PROJ-123 --no-gitUnattended drains belong on the worker, not on a crontab of devintern --query:
devintern worker init
devintern workerSee the Worker Daemon guide and Automated Task Processing. The worker natively supports working windows (quiet hours), so "only at night" no longer needs cron — set [worker.schedule] in workspace.toml:
[worker.schedule]
active = ["22:00-06:00"] # drain new tasks only during these local-time windows
timezone = "" # optional IANA name; blank = machine local time
catch_up_missed = true # one catch-up drain at startup after a fully missed windowOutside the window nothing is killed mid-run — the in-flight task completes and no new tracker tasks start. Force one immediate drain with devintern worker run-now. The only CLI run still worth a timer is story-point estimation (--estimate).
-
"Missing required environment variables"
- Ensure
.envfile exists in current directory - Or set environment variables in your shell
- Check that variable names match exactly
- Ensure
-
"Not in a git repository"
- Run
git initif starting a new project - Or use
--no-gitflag to skip git operations
- Run
-
"There are uncommitted changes"
- Commit your changes:
git add . && git commit -m "message" - Or stash them:
git stash - Or use
--no-gitto skip branch creation
- Commit your changes:
-
"Claude CLI not found"
- Install Claude CLI
- Or specify path:
--claude-path /path/to/claude
-
"Issue not found"
- Check JIRA credentials
- Verify task key exists and you have access
- Ensure JIRA_BASE_URL is correct
-
"Agent reached maximum turns limit"
- Task is too complex for the current turn limit (default: 500)
- Increase max turns:
--max-turns 1000 - Consider breaking the task into smaller subtasks
- Review the task description for clarity
-
"PR creation failed"
- Ensure you have the correct token configured:
- GitHub:
GITHUB_TOKEN.TASK_TRACKER=githubalways requires it; relay-backed workspaces also use it for PR/review API calls - Bitbucket:
BITBUCKET_TOKEN
- GitHub:
- Check token/App permissions:
- GitHub classic token: needs
reposcope - GitHub fine-grained token: needs
Pull requests: Read and write+Contents: Read - Advanced customer-owned GitHub App: needs
Contents: Read+Pull requests: Read and write - Bitbucket: needs
Repositories: Write
- GitHub classic token: needs
- Standard workspace: ensure the central DevIntern AI App is installed and the repo is registered with the relay
- Advanced no-relay App: ensure your customer-owned App is installed on the repository
- Verify you're in a repository with a remote origin
- Confirm the repository platform is detected correctly
- Use
--verboseflag to see detailed error messages
- Ensure you have the correct token configured:
# Get detailed error information
devintern PROJ-123 --verbose# 1. Navigate to your project
cd ~/projects/my-app
# 2. Ensure clean git state
git status
git add . && git commit -m "Current progress"
# 3. Run devintern
devintern MYAPP-456
# Output:
# 🔍 Fetching JIRA task: MYAPP-456
# 📋 Task Summary: [details...]
# 💾 Saving formatted task details to: ./task-details.md
# 🌿 Creating feature branch...
# ✅ Created and switched to new branch 'feature/myapp-456'
# 🤖 Running Claude with task details...
# [Claude implements the task...]npm uninstall -g @getdevintern/code