Complete guide to integrating DevAIFlow with JIRA.
JIRA integration is completely optional. The tool works perfectly fine for local session management without JIRA. However, if you use JIRA for task tracking, this integration provides:
- Automatic ticket sync - Discover assigned tickets and create sessions
- Status transitions - Auto-move tickets (New → In Progress → Done)
- Progress comments - Add session notes to JIRA tickets
- Sprint dashboard - View sprint progress with time tracking
- Ticket metadata - Enrich sessions with JIRA data
DevAIFlow supports both JIRA Cloud and self-hosted JIRA instances with automatic API version detection:
- ✅ JIRA Cloud (Atlassian Cloud) - Uses JIRA REST API v3
- ✅ Self-Hosted JIRA (Server/Data Center) - Uses JIRA REST API v2
The tool automatically detects which API version to use:
- First Request: Attempts to use API v2 (for self-hosted JIRA)
- Cloud Detection: If the server returns HTTP 410 (endpoint deprecated), automatically switches to API v3
- Caching: The detected version is cached for subsequent requests within the same session
This means you don't need to configure which API version to use - it's handled automatically based on your JIRA instance type.
As of August 2025, Atlassian Cloud has deprecated the /rest/api/2/search endpoint (CHANGE-2046). DevAIFlow handles this deprecation automatically:
- Self-hosted JIRA: Continues using API v2 (
/rest/api/2/search) - Cloud JIRA: Automatically uses API v3 (
/rest/api/3/search/jql)
No configuration changes are needed - the migration is transparent to users.
-
JIRA API Token (for Atlassian Cloud) or Personal Access Token (for self-hosted JIRA)
-
Environment Variables
export JIRA_API_TOKEN="your-token-here" export JIRA_URL="https://jira.example.com" # Optional, auto-detected
-
JIRA CLI (ankitpokhrel/jira-cli) - Optional
The tool primarily uses the JIRA REST API for most operations. The JIRA CLI is only needed for:
daf sync- Listing tickets with JQL queriesdaf attach- Attaching files to tickets
To install JIRA CLI (if needed):
# macOS brew install ankitpokhrel/jira-cli/jira-cli # Linux wget https://github.com/ankitpokhrel/jira-cli/releases/latest/download/jira_linux_amd64.tar.gz tar -xzf jira_linux_amd64.tar.gz sudo mv jira /usr/local/bin/
See Installation Guide for detailed setup instructions.
DevAIFlow supports two authentication methods depending on your JIRA deployment type.
Atlassian Cloud requires Basic Authentication with base64-encoded credentials.
⚠️ CRITICAL: JIRA Cloud authentication requires three key elements:
- Base64-encoded credentials combining
email:tokenJIRA_AUTH_TYPE=basicenvironment variable- Your JIRA Cloud URL (e.g.,
https://yourcompany.atlassian.net)Missing any of these will result in authentication failures.
Step 1: Configure JIRA URL in DevAIFlow
First, ensure your JIRA URL is configured. Check your current configuration:
# Check if JIRA URL is already configured
daf config show | grep -i jiraIf not configured or incorrect, set it:
# Set via environment variable (required)
export JIRA_URL="https://yourcompany.atlassian.net"Step 2: Get Your JIRA Email Address
Use the email address associated with your Atlassian account (e.g., user@company.com).
Step 3: Generate API Token
- Go to: https://id.atlassian.com/manage-profile/security/api-tokens
- Click Create API token
- Give it a name (e.g., "DevAIFlow CLI")
- Copy the generated token (you won't see it again)
Step 4: Create Base64-Encoded Credentials
IMPORTANT: You must combine your email and API token with a colon (
:) before encoding to base64.
Replace user@company.com with your email and your-api-token with the token from Step 3:
# Replace with YOUR email and token
echo -n "user@company.com:your-api-token" | base64This outputs a base64 string. Save this output - it becomes your JIRA_API_TOKEN.
Example output format:
dXNlckBjb21wYW55LmNvbTp5b3VyLWFwaS10b2tlbg== # notsecret
Step 5: Configure Environment Variables
⚠️ CRITICAL: TheJIRA_AUTH_TYPE=basicvariable is required for JIRA Cloud. Without this, authentication will fail even with correct credentials.
# CRITICAL: Set authentication type to basic for JIRA Cloud
export JIRA_AUTH_TYPE=basic
# Set the base64-encoded credentials (paste output from Step 4)
export JIRA_API_TOKEN="dXNlckBjb21wYW55LmNvbTp5b3VyLWFwaS10b2tlbg==" # notsecret
# Set your Atlassian Cloud URL
export JIRA_URL="https://yourcompany.atlassian.net"Step 6: Verify Authentication
Test the connection before making it permanent:
# Test API access
curl -H "Authorization: Basic $JIRA_API_TOKEN" \
"$JIRA_URL/rest/api/2/myself"✅ Success: You'll see your user profile data in JSON format. ❌ Failure: Check that:
- Your JIRA_API_TOKEN is the base64 output from Step 4
- JIRA_AUTH_TYPE is set to
basic - JIRA_URL matches your Atlassian Cloud URL
Step 7: Make It Permanent
Once verified, add these to your ~/.zshrc or ~/.bashrc:
# JIRA Configuration (Atlassian Cloud)
export JIRA_AUTH_TYPE=basic
export JIRA_API_TOKEN="dXNlckBjb21wYW55LmNvbTp5b3VyLWFwaS10b2tlbg==" # notsecret
export JIRA_URL="https://yourcompany.atlassian.net"Then reload:
source ~/.zshrc # or source ~/.bashrcSelf-hosted JIRA uses Bearer Authentication with Personal Access Tokens.
Step 1: Generate Personal Access Token
- Log into your JIRA instance
- Go to:
https://jira.example.com→ Profile → Personal Access Tokens - Click Create token
- Give it a name (e.g., "DevAIFlow CLI")
- Set expiration (recommend 1 year)
- Grant scopes:
read:jira-work,write:jira-work - Copy the generated token
Step 2: Configure Environment Variables
# Set authentication type to bearer (default)
export JIRA_AUTH_TYPE=bearer
# Set your Personal Access Token
export JIRA_API_TOKEN="your-jira-token"
# Set your self-hosted JIRA URL
export JIRA_URL="https://jira.example.com"Step 3: Add to Shell Profile (Permanent)
Add these to your ~/.zshrc or ~/.bashrc:
# JIRA Configuration (Self-Hosted)
export JIRA_AUTH_TYPE=bearer
export JIRA_API_TOKEN="your-jira-token"
export JIRA_URL="https://jira.example.com"Then reload:
source ~/.zshrc # or source ~/.bashrcStep 4: Verify Authentication
# Test API access
curl -H "Authorization: Bearer $JIRA_API_TOKEN" \
"$JIRA_URL/rest/api/2/myself"If successful, you'll see your user profile data.
| JIRA Type | Auth Type | Token Format | Environment Variable |
|---|---|---|---|
| Atlassian Cloud | basic |
Base64 of email:api-token |
JIRA_AUTH_TYPE=basic |
| Self-Hosted | bearer |
Personal Access Token | JIRA_AUTH_TYPE=bearer |
- Never commit tokens to git - Add
.envfiles to.gitignore - Rotate tokens regularly - Regenerate every 90-180 days
- Use minimal scopes - Only grant required permissions
- Store securely - Consider using a password manager
- Revoke unused tokens - Clean up old tokens from your profile
Error: "Failed to parse Connect Session Auth Token"
- You're using Atlassian Cloud but
JIRA_AUTH_TYPEis not set tobasic - Solution:
export JIRA_AUTH_TYPE=basic
Error: "401 Unauthorized"
- Token is invalid or expired
- For cloud: Regenerate base64 credentials with fresh API token
- For self-hosted: Generate new Personal Access Token
Error: "Invalid token format"
- For cloud: Verify base64 encoding is correct
- Test:
echo "$JIRA_API_TOKEN" | base64 -dshould showemail:api-token
The tool uses the JIRA REST API for most operations:
- ✅ Fetching tickets -
GET /rest/api/2/issue/{key} - ✅ Adding comments -
POST /rest/api/2/issue/{key}/comment(with Example Group visibility) - ✅ Transitioning tickets -
POST /rest/api/2/issue/{key}/transitions - ✅ Getting transitions -
GET /rest/api/2/issue/{key}/transitions
The JIRA CLI is used as fallback for:
- 🔄 Listing tickets - JQL query abstraction
- 📎 File attachments - Multipart upload handling
This hybrid approach provides:
- Reliability - Direct API control for critical operations
- Visibility - Proper comment restriction (Example Group only)
- Performance - Faster API calls, fewer timeouts
- Convenience - JQL abstraction for complex queries
Edit backend and organization configuration files:
JIRA Backend ($DEVAIFLOW_HOME/backends/jira.json):
{
"url": "https://jira.example.com",
"field_mappings": null,
"field_cache_auto_refresh": true
}Organization Configuration ($DEVAIFLOW_HOME/organization.json):
{
"jira_project": "PROJ",
"transitions": {
"on_start": {
"from": ["New", "To Do"],
"to": "In Progress",
"prompt": false,
"on_fail": "warn"
},
"on_complete": {
"prompt": true
}
},
"parent_field_mapping": {
"story": "epic_link",
"task": "epic_link",
"sub-task": "parent"
}
}Backend Configuration (backends/jira.json):
- url - Your JIRA instance URL (e.g., "https://jira.example.com")
- field_mappings - Auto-discovered JIRA field metadata (managed by
daf config refresh-jira-fields) - field_cache_auto_refresh - Auto-refresh field mappings when stale (true/false)
Organization Configuration (organization.json):
- jira_project - JIRA project key (e.g., "PROJ") - used for creating issues
- transitions.on_start - Auto-transition when opening session (workflow policy)
- from - List of statuses to transition from
- to - Target status
- prompt - Ask before transitioning (true/false)
- on_fail - What to do if transition fails ("warn" or "block")
- transitions.on_complete - Auto-transition when completing session (workflow policy)
- prompt - Ask for target status (true/false)
- parent_field_mapping - Maps issue types to parent field names (hierarchy policy)
Team Configuration (team.json):
- jira_custom_field_defaults - Default values for custom fields (e.g., {"workstream": "Platform"})
- time_tracking_enabled - Enable time tracking for JIRA tickets (true/false)
Note: To control whether session summaries are automatically added to issue tracker (JIRA, GitHub, GitLab), use prompts.auto_add_issue_summary - see Prompts Configuration
For creating JIRA issues, you need to configure your project and any custom field defaults:
# Set JIRA project key
daf config edit # Navigate to JIRA Integration → Project Key PROJ
# Set custom field defaults (e.g., workstream, team, etc.)
daf config edit # Navigate to JIRA Integration → Custom Field Defaults
# Example: {"workstream": "Platform", "team": "Backend"}
# Set affected version for bugs (one-time configuration)
daf config edit # Navigate to JIRA Integration → Affected Version v1.0.0These values are saved to config.json and used automatically when creating issues.
Note: The affected version is required for bug creation. If not configured, daf jira create bug will prompt you to enter it and save it automatically.
Alternatively, provide them via flags:
daf jira create story \
--summary "My story" \
--project PROJ \
--field workstream=Platform \
--field team=BackendConfigure how tickets transition between statuses when you start or complete work:
Configure on_start transition (when opening a session):
# Interactive mode
daf config edit
# Command-line mode
daf config edit
--from-status "New" \
--from-status "To Do" \
--to "In Progress" \
--no-promptConfigure on_complete transition (when completing a session):
# Interactive mode (recommended)
daf config edit
# Interactive selection from available transitions
daf config edit
# Automatic transition to specific status
daf config edit
--no-prompt \
--to "Done"Note: Transitions are organization workflow policies configured in organization.json. For organization-specific JIRA workflows, these settings are pre-configured in organization configuration files. You only need to adjust them if your workflow differs from your organization's standard.
CRITICAL ERROR PREVENTION:
- ❌ NEVER use
--fieldwith system fields (reporter, assignee, components, labels) - ✅ System fields MUST use their dedicated options:
--reporter jdoe,--assignee alice,--components backend - If you use
--field reporter=jdoe, the command will EXIT WITH ERROR - Error message will tell you:
✗ 'reporter' is a system field. Use --reporter option instead of --field
Field Type Guidelines:
- System fields (reporter, assignee, components, labels, security-level, etc.): Use dedicated CLI options
- Custom fields (customfield_*): Use
--field field_name=valueformat
daf jira create bug \
--summary "Customer backup fails with timeout" \
--priority Major \
--parent PROJ-59038 \
--description-file /tmp/bug_description.txt
# With system fields (reporter, assignee, components, labels)
daf jira create bug \
--summary "Production bug" \
--reporter jdoe \
--components backend \
--labels urgent
# With custom fields
daf jira create bug \
--summary "Critical bug" \
--field severity=Critical \
--field size=L# Interactive mode (prompts for description)
daf jira create story \
--summary "Implement backup and restore feature" \
--priority Major \
--parent PROJ-59038 \
--interactive
# With description from file
daf jira create story \
--summary "Implement backup feature" \
--parent PROJ-59038 \
--description-file /tmp/story.txt
# Inline description
daf jira create story \
--summary "Implement backup feature" \
--parent PROJ-59038 \
--description "User story goes here"daf jira create task \
--summary "Update backup documentation" \
--parent PROJ-59038 \
--description "Update docs to reflect new backup feature"# Interactive mode (prompts for description)
daf jira create epic \
--summary "Backup and Restore Feature" \
--priority Major \
--interactive
# With description from file
daf jira create epic \
--summary "Backup and Restore Feature" \
--description-file /tmp/epic.txt
# Inline description
daf jira create epic \
--summary "Backup and Restore Feature" \
--description "h2. *Background*\n\nImplement comprehensive backup and restore capabilities..."Note: Epics are typically top-level containers and usually don't have parent links. However, the --parent parameter is supported if your JIRA workflow requires it.
# Interactive mode (prompts for description)
daf jira create spike \
--summary "Research API authentication patterns" \
--priority Major \
--parent PROJ-59038 \
--interactive
# With description from file
daf jira create spike \
--summary "Research backup strategies" \
--parent PROJ-59038 \
--description-file /tmp/spike.txt
# Inline description
daf jira create spike \
--summary "Research backup strategies" \
--parent PROJ-59038 \
--description "h3. *User Story*\n\nAs a developer, I want to research..."Note: Spikes should typically be linked to an Epic via the --parent parameter.
Automatically create a cs session for the newly created issue:
daf jira create story \
--summary "New feature" \
--parent PROJ-59038 \
--create-sessionThis creates the JIRA issue and immediately creates a session for it.
View any JIRA issue in a Claude-friendly format:
daf jira view PROJ-12345This is more reliable than using curl and handles authentication automatically.
CRITICAL ERROR PREVENTION:
- ❌ NEVER use
--fieldwith system fields (reporter, assignee, components, labels) - ✅ System fields MUST use their dedicated options:
--reporter jdoe,--assignee alice,--components backend - If you use
--field reporter=jdoe, the command will EXIT WITH ERROR - Error message will tell you:
✗ 'reporter' is a system field. Use --reporter option instead of --field
# Update description
daf jira update PROJ-12345 --description "New description text"
# Update from file
daf jira update PROJ-12345 --description-file /tmp/new_description.txt
# Update multiple fields
daf jira update PROJ-12345 \
--priority Major \
--field workstream=Platform \
--summary "Updated summary"
# Update with system fields (reporter, assignee, components, labels)
daf jira update PROJ-12345 --assignee alice --components ansible-saas --labels backend,urgent
daf jira update PROJ-12345 --reporter jdoe --components backend --security-level Internal
daf jira update PROJ-12345 --assignee bob --reporter alice --components backend
# Update with custom fields (use --field for ALL custom fields)
daf jira update PROJ-12345 --field severity=Critical --field size=L
daf jira update PROJ-12345 --field epic_link=PROJ-59000 --field story_points=5
daf jira update PROJ-12345 --field acceptance_criteria="- Criterion 1\n- Criterion 2"
# Add PR link (auto-appends to existing links)
daf jira update PROJ-12345 --git-pull-request "https://github.com/org/repo/pull/123"Both daf jira create and daf jira update support dynamic field discovery with strict separation between system and custom fields:
IMPORTANT: ALL custom fields (customfield_*) MUST use --field field_name=value format. System fields (reporter, assignee, components, labels) have dedicated CLI options.
# View available fields (both system and custom)
daf jira create bug --help
# → Shows system field options: --reporter, --assignee, --components, --labels
# → Shows available custom fields in --field help text
# Use system fields with dedicated options
daf jira create bug \
--summary "Critical bug" \
--reporter jdoe \
--assignee alice \
--components backend \
--labels urgent
# Use custom fields with --field
daf jira create bug \
--summary "Critical bug" \
--field severity=Critical \
--field size=L \
--field workstream=PlatformCreation fields are discovered once and cached in $DEVAIFLOW_HOME/config.json. Refresh with:
daf config refresh-jira-fields# View available fields for a specific issue
daf jira update PROJ-12345 --help
# → Shows system field options: --reporter, --assignee, --components, --labels
# → Shows available custom fields in --field help text
# Use system fields with dedicated options
daf jira update PROJ-12345 \
--assignee alice \
--components backend \
--labels urgent,backend
# Use custom fields with --field
daf jira update PROJ-12345 \
--field epic_link=PROJ-59000 \
--field story_points=5 \
--field severity=CriticalHow it works:
The command dynamically discovers available fields:
- System fields (non-customfield_*) get dedicated CLI options like
--reporter,--assignee - Custom fields (customfield_*) are documented in
--fieldhelp text - Trying to use
--fieldwith system fields will EXIT WITH ERROR - This strict separation prevents API errors and makes field types explicit
Key Principles:
- System fields: Use dedicated options (e.g.,
--reporter jdoe,--assignee alice) - Custom fields: Use
--field key=value(e.g.,--field severity=Critical) - Error prevention: Mixing field types causes immediate error with helpful message
- Field discovery: Run
daf config refresh-jira-fieldsto update available custom fields
For Ticket Creation Sessions (daf jira new) - PROJ-60665:
- Sessions are automatically renamed to
creation-<TICKET_KEY>after ticket creation - Example:
my-session→creation-PROJ-12345 - Simplifies finding sessions without complex metadata
- Only happens when running inside a Claude Code session
- Reopen with:
daf open creation-PROJ-12345
For Development Sessions (daf new --jira):
daf new --jira PROJ-12345 --goal "Implement backup feature"Prompts for session name:
Session name [PROJ-12345]:
Press Enter to use JIRA key, or type a custom name.
daf new --name "backup" --jira PROJ-12345 --goal "Implement backup feature"Good for multi-repo work where you want the same name across repositories.
- Validates JIRA ticket - Fails fast if ticket doesn't exist
- Fetches ticket metadata - Title, status, sprint, assignee, story points
- Creates session - Links JIRA key to session
- Suggests git branch - Based on JIRA key (e.g.,
PROJ-12345-backup) - Transitions ticket (if configured) - Moves to "In Progress"
When using --jira flag, the tool validates the ticket exists:
daf new --jira PROJ-99999 --goal "Test"If ticket doesn't exist:
Error: JIRA ticket PROJ-99999 not found or you don't have access to it.
Verify:
1. Ticket key is correct
2. You have access to the ticket
3. JIRA CLI is configured: jira issue view PROJ-99999
This prevents creating sessions with invalid JIRA keys.
daf link redis-test --jira PROJ-12346This:
- Validates ticket exists
- Fetches ticket metadata
- Links ticket to session
- Updates all conversations in the session
Options:
--force- Skip confirmation prompt when replacing existing link (useful for scripts and automation)
daf unlink redis-testRemoves JIRA association but keeps all session data.
Options:
--force- Skip confirmation prompt (useful for scripts and automation)
daf syncDiscovers all tickets assigned to you and creates sessions:
- Stories (with or without story points)
- Bugs
- Tasks
daf sync --sprint currentCreates sessions only for tickets in your current sprint.
daf sync --sprint "2025-01"daf sync --type Story
daf sync --type Bugdaf sync --epic PROJ-36419Creates sessions for all tickets in the specified epic.
daf sync --dry-runPreview what would be synced without creating sessions:
Would create sessions for:
PROJ-12345: Implement customer backup
Type: Story | Points: 5 | Status: To Do
Sprint: 2025-01
PROJ-12346: Fix password reset bug
Type: Bug | Status: In Progress
Sprint: 2025-01
PROJ-12347: Add 2FA support
Type: Story | Points: 8 | Status: To Do
Sprint: 2025-01
Total: 3 tickets (13 story points)
For each ticket, creates a session with:
- name - JIRA key (e.g., "PROJ-12345")
- goal - JIRA summary/title
- issue_key - JIRA key
- jira_summary - Ticket title
- jira_status - Current status
- sprint - Sprint name/ID
- jira_assignee - Assignee username
- status - "created" (not started yet)
After sync, when you first open a synced session:
daf open PROJ-12345You'll be prompted to select a working directory:
No working directory set for this session.
Detected repositories:
1. backend-api
2. frontend-app
3. mobile-app
Or enter custom path: /path/to/project
Select working directory [1-3]:
The tool uses keyword matching based on JIRA summary to suggest repositories.
When configured, opening a session transitions the ticket:
daf open PROJ-12345With this config in organization.json:
{
"transitions": {
"on_start": {
"from": ["New", "To Do"],
"to": "In Progress",
"prompt": false,
"on_fail": "warn"
}
}
}Output:
✓ Transitioned PROJ-12345: To Do → In Progress
If ticket is not in "New" or "To Do", transition is skipped.
When you reopen a session for a ticket that was previously marked as Done/Closed, the tool automatically detects this and prompts you to reopen it:
daf open PROJ-12345If the ticket is in a closed state (Done, Closed, Resolved, Release Pending, or Review):
⚠ JIRA ticket PROJ-12345 is currently: Done
You are reopening work on a ticket that was previously marked as complete.
Transition PROJ-12345 back to 'In Progress'? [Y/n]:
If you confirm:
✓ Transitioned PROJ-12345: Done → In Progress
✓ Added comment to PROJ-12345
The tool automatically:
- Transitions the ticket back to "In Progress"
- Adds a comment explaining why the ticket was reopened
- Continues opening your session
Use Cases:
- Bug found after closing - Ticket marked Done, bug discovered, need to reopen
- Additional work needed - Ticket closed, customer requests changes
- Review feedback - Ticket in Code Review or Done, feedback requires changes
- Accidentally completed - Ticket marked complete too early, need to continue work
Flexible Options:
- If you decline the transition, you can still continue opening the session without updating JIRA
- If the transition fails (e.g., missing required fields), you can choose to continue anyway or cancel
When configured, completing a session offers to transition:
daf complete PROJ-12345With this config in organization.json:
{
"transitions": {
"on_complete": {
"prompt": true,
"on_fail": "warn"
}
}
}The tool will dynamically fetch available transitions from the JIRA API and display them:
Transition JIRA ticket PROJ-12345?
Current status: In Progress
1. Skip (keep current status)
2. New
3. Refinement
4. Backlog
5. Review
6. Release Pending
7. Closed
Select target status [1/2/3/4/5/6/7] (1):
Note: Available transitions are automatically fetched from the JIRA API based on the ticket's current status, so you only see valid transitions for your workflow.
For automatic transitions without user interaction, configure in organization.json:
{
"transitions": {
"on_complete": {
"prompt": false,
"to": "Done",
"on_fail": "warn"
}
}
}This will automatically transition the ticket to "Done" when you complete the session, without prompting.
daf complete PROJ-12345 --status "Code Review"Transitions directly without prompting.
on_fail: "warn" (default)
- Shows warning if transition fails
- Continues with session operation
on_fail: "block"
- Shows error if transition fails
- Aborts session operation
Example with "warn":
⚠ Failed to transition PROJ-12345: Transition not available
Session marked as complete locally
Example with "block":
✗ Error: Cannot transition PROJ-12345 to In Progress
Current status 'Code Review' does not allow this transition
Session not opened
Tip:
daf notenow works inside Claude Code! Add notes anytime to track progress. Use/daf-notesto view all notes.
daf note PROJ-12345 "Implemented upload endpoint"Saved to $DEVAIFLOW_HOME/sessions/PROJ-12345/notes.md only.
daf note PROJ-12345 "Backend complete, ready for review" --jiraThis:
- Saves note locally (always succeeds)
- Adds note as JIRA comment (best effort)
If JIRA sync fails, note is still saved locally.
JIRA comment format:
[Session Note - 2025-11-20 14:30:00]
Backend complete, ready for review
Notes added with --jira appear as comments on the ticket, visible to your team.
daf statusOutput:
Current Sprint: 2025-01
Sprint Goal: Implement customer backup and restore features
In Progress:
🚧 PROJ-12345 Customer backup 5 pts | 3h 45m | 75%
🚧 PROJ-12346 Fix password reset 3 pts | 1h 20m | 40%
Ready to Start:
🆕 PROJ-12347 Add 2FA support 8 pts | 0h | 0%
🆕 PROJ-12348 Update documentation 2 pts | 0h | 0%
Code Review:
✅ PROJ-12344 User profile API 5 pts | 4h 10m | 100%
Done:
✓ PROJ-12343 Login endpoint 3 pts | 2h 30m | 100%
Sprint Progress:
Completed: 8 pts (30%)
In Progress: 8 pts (30%)
Remaining: 10 pts (40%)
Total: 26 pts
Time Spent: 11h 45m
Estimated Remaining: ~14h
The dashboard shows:
- Current Status - Where each ticket is in the workflow
- Story Points - From JIRA
- Time Spent - Tracked locally by daf tool
- Progress % - Estimated based on activity
- Sprint Totals - Points and time across all tickets
daf complete PROJ-12345Prompts:
Generate AI summary of work done? [Y/n]:
If you say yes:
- Analyzes conversation history
- Generates natural language summary
- Offers to add summary to JIRA ticket
- Offers to transition ticket status
Session: PROJ-12345 - Customer backup
Summary:
Implemented comprehensive backup system with S3 integration. Created backup
service with upload/download endpoints, metadata validation, and encryption.
Added retry logic for failed uploads and comprehensive error handling.
Key Accomplishments:
- POST /api/backup/upload endpoint with multipart file handling
- S3 bucket integration with server-side encryption (AES-256)
- Backup metadata storage in PostgreSQL
- Retry mechanism with exponential backoff
- Input validation and error responses
Files Modified:
- src/services/backup.service.ts (new)
- src/controllers/backup.controller.ts (new)
- src/models/backup.model.ts (new)
- src/routes/backup.routes.ts (new)
- src/utils/s3.client.ts (updated)
Tests Added:
- tests/backup.service.test.ts (35 tests)
Next Steps:
- Implement restore endpoint
- Add download progress tracking
- Update API documentation
Add this summary to JIRA ticket PROJ-12345? [Y/n]:
If you say yes, summary is added as a comment on the JIRA ticket.
daf complete PROJ-12345 --no-ai-summaryOr just say "n" when prompted.
When configured:
{
"jira": {
"time_tracking": true
}
}Time is tracked for each work session and associated with the JIRA ticket.
daf time PROJ-12345Output:
Time Tracking for: PROJ-12345
Work Sessions:
Session #1 (backend-api):
1. 2025-11-20 09:00:00 → 11:30:00 (2h 30m)
2. 2025-11-20 14:00:00 → 15:15:00 (1h 15m)
Session #2 (frontend-app):
1. 2025-11-20 16:00:00 → 17:30:00 (1h 30m)
Total Time: 5h 15m
JIRA Status: In Progress
Sprint: 2025-01
When you have multiple conversations in one session for one JIRA ticket (multi-repo work), time is tracked at the session level across all conversations.
# Backend work
cd ~/projects/backend-api
daf new --name "backup" --jira PROJ-12345 --goal "Backend API"
# Frontend work
cd ~/projects/frontend-app
daf new --name "backup" --jira PROJ-12345 --goal "Frontend UI"
# Infrastructure
cd ~/projects/terraform
daf new --name "backup" --jira PROJ-12345 --goal "S3 bucket config"All three sessions linked to PROJ-12345.
# Work on backend
daf open backup
# Select #1 (backend-api)
# Later, work on frontend
daf open backup
# Select #2 (frontend-app)Exit Claude Code first, then add notes from each repository:
# From backend repo
daf note backup "Backend API complete" --jira
# From frontend repo
daf note backup "UI in progress" --jiraBoth notes appear on the same JIRA ticket.
# Complete each session
daf complete backup # In backend repo
daf complete backup # In frontend repo
daf complete backup # In terraform repoWhen completing the last session, you can:
- Generate AI summary (combines all sessions)
- Add summary to JIRA
- Transition JIRA ticket to Done
daf list | grep PROJ-12345daf search "backup" --jira-key PROJ-12345daf list --sprint "2025-01"daf list --jira-status "In Progress"daf export-md PROJ-12345 --ai-summaryCreates PROJ-12345.md:
# PROJ-12345: Customer backup and restore
**Type:** Story
**Status:** In Progress
**Sprint:** 2025-01
**Story Points:** 5
**Assignee:** your-username
**Link:** https://jira.example.com/browse/PROJ-12345
## Goal
Implement customer backup and restore features
## Summary
Implemented comprehensive backup system...
## Progress Notes
### 2025-11-20 09:30:00
Implemented upload endpoint
### 2025-11-20 14:15:00
Backend complete, ready for review
## Time Tracking
- **Total Time:** 5h 15m
- **Work Sessions:** 3
- **Status:** In ProgressPerfect for documentation, handoffs, or sprint reviews.
daf export-md PROJ-12345 PROJ-12346 PROJ-12347 --combinedCreates single file with all tickets.
Error: 401 Unauthorized, JIRA_API_TOKEN not set, or Authentication failed
Solutions:
-
Check token is set:
echo $JIRA_API_TOKEN
-
For self-hosted JIRA: Use Personal Access Token, not API token
- Go to https://jira.example.com → Profile → Personal Access Tokens
- Create new token with
read:jira-work,write:jira-workscopes - Set in environment:
export JIRA_API_TOKEN="your-token-here"
-
Add to shell profile:
# Add to ~/.zshrc or ~/.bashrc echo 'export JIRA_API_TOKEN="your-token-here"' >> ~/.zshrc source ~/.zshrc
-
Test API access:
curl -H "Authorization: Bearer $JIRA_API_TOKEN" \ "https://jira.example.com/rest/api/2/myself"
When troubleshooting JIRA API issues, enable debug logging to see full request/response details:
# Enable debug logging
export DEVAIFLOW_DEBUG=1
# Run your JIRA command
daf jira create bug --summary "Test" --parent PROJ-123
# Disable when done
unset DEVAIFLOW_DEBUGWhat you'll see:
- Full HTTP method and URL
- Complete request payload (all fields being sent)
- JIRA server response
- HTTP status codes
- Field validation errors from JIRA
Use cases:
- Troubleshooting custom field validation errors
- Understanding why JIRA rejects ticket creation
- Debugging field mapping issues
- Verifying what values are being sent to JIRA
- Testing JIRA API integration
Note: Debug output is automatically disabled when using --json flag.
For more details, see Troubleshooting Guide - JIRA API Debug Logging.
Error: API calls fail, or wrong JIRA instance
Solution:
Set JIRA URL explicitly:
export JIRA_URL="https://jira.example.com"The tool auto-detects from:
JIRA_URLenvironment variable~/.config/.jira/.config.yml(jira-cli config)- Defaults to
https://jira.example.com
Error: jira: command not found when using daf sync or file attachments
Solution:
# Verify installation
which jira
# Install if missing (macOS)
brew install ankitpokhrel/jira-cli/jira-cli
# Test
jira versionNote: Most JIRA operations (fetch, comment, transition) work without jira-cli using the REST API.
Error: JIRA ticket PROJ-12345 not found
Solutions:
-
Verify ticket exists:
jira issue view PROJ-12345
-
Check access permissions
-
Verify JIRA URL:
cat $DEVAIFLOW_HOME/config.json | grep url
Error: Transition not available
Causes:
- Ticket not in expected status
- Workflow doesn't allow transition
- Permissions issue
Solutions:
-
Check current status:
jira issue view PROJ-12345
-
View available transitions:
jira issue move PROJ-12345
-
Update config with correct transitions
-
Use on_fail: "warn" to continue despite failures
Error: Failed to add comment
Solutions:
-
Check permissions: Ensure you can comment on the ticket
-
Test manually:
jira issue comment add PROJ-12345 "test comment" -
Check prompts.auto_add_issue_summary setting:
{ "prompts": { "auto_add_issue_summary": true } }See Prompts Configuration for details.
Problem: daf sync returns no tickets
Solutions:
-
Test JIRA CLI:
jira me jira issue list --assignee $(jira me) -
Check filters:
daf sync --dry-run # See what would be synced -
Verify assigned tickets exist:
jira issue list --assignee $(jira me) --type Story
Start of sprint:
daf sync --sprint currentCreates sessions for all sprint tickets at once.
Don't rush to link JIRA. You can always link later:
# Start without JIRA
daf new --name "experiment" --goal "Test approach"
# Link when ready
daf link experiment --jira PROJ-12345Add notes with --jira flag for team visibility:
daf note PROJ-12345 "Backend complete, needs UI work" --jiraAlways generate AI summary on completion:
daf complete PROJ-12345
# Say yes to AI summary
# Say yes to add to JIRAProvides great documentation for team and future reference.
Start with "warn" mode:
{
"on_start": {
"on_fail": "warn"
}
}Once confident, switch to "block" for strict workflow enforcement.
daf status # Daily standupKeeps you aware of sprint progress.
End of sprint:
daf export-md PROJ-12345 PROJ-12346 --combined --output sprint-report.md- Configuration Reference - Detailed config options
- Commands Reference - All JIRA-related commands
- Workflows - Step-by-step JIRA workflows
- Troubleshooting - JIRA integration issues