Jira Resource Validator Skill
Purpose: Validate and auto-create Jira projects and boards, ensuring .env configuration is correct.
Auto-Activation: Triggers when Jira setup or validation is needed.
What This Skill Does
This skill ensures your Jira configuration in .env is valid and all resources exist. It's smart enough to:
-
Validate Jira projects - Check if JIRA_PROJECT exists
-
Prompt for action - Select existing project or create new one
-
Validate Jira boards - Check if boards exist (by ID or name)
-
Create missing boards - If board names provided, create them automatically
-
Update .env with IDs - Replace board names with actual board IDs after creation
When This Skill Activates
✅ Automatically activates when:
-
You set up Jira integration for the first time
-
You run /sw-jira:sync and resources are missing
-
Your .env has invalid Jira configuration
-
You mention "jira setup" or "jira validation"
Jira Configuration Structure
Required .env Variables
JIRA_API_TOKEN=your_token_here JIRA_EMAIL=your_email@company.com JIRA_DOMAIN=yourcompany.atlassian.net JIRA_STRATEGY=board-based JIRA_PROJECT=PROJECTKEY JIRA_BOARDS=1,2,3 # IDs (if exist) OR names (if creating)
Smart Per-Board Detection (Mixed Mode Support!)
The system is smart enough to handle ANY combination of IDs and names:
All IDs (validate existing boards):
JIRA_BOARDS=1,2,3
→ Validates boards 1, 2, 3 exist
All Names (create new boards):
JIRA_BOARDS=Frontend,Backend,Mobile
→ Creates 3 boards, updates .env with IDs: JIRA_BOARDS=101,102,103
Mixed IDs and Names (smart handling!):
JIRA_BOARDS=101,102,QA,Dashboard
→ Validates 101, 102 exist → Creates "QA" and "Dashboard" boards → Updates .env: JIRA_BOARDS=101,102,103,104 (all IDs!)
How it works: Each entry is checked individually:
-
Numeric (e.g., "123") → Validate ID exists
-
Non-numeric (e.g., "QA") → Create board with that name
-
After creation, .env is updated with ALL board IDs
NEW: Per-Project Configuration (Advanced - Multiple Projects × Boards)
Multiple JIRA projects with their own boards:
Multiple projects with their own boards
JIRA_STRATEGY=project-per-team JIRA_PROJECTS=BACKEND,FRONTEND,MOBILE
Per-project boards (hierarchical naming)
JIRA_BOARDS_BACKEND=123,456 # Sprint + Kanban (IDs) JIRA_BOARDS_FRONTEND=Sprint,Bug # Create these boards JIRA_BOARDS_MOBILE=789,012,345 # iOS + Android + Release (IDs)
→ Validates 3 projects exist: BACKEND, FRONTEND, MOBILE → Validates/creates boards per project:
-
BACKEND: Validates boards 123, 456 exist
-
FRONTEND: Creates "Sprint" and "Bug" boards, updates .env with IDs
-
MOBILE: Validates boards 789, 012, 345 exist
Naming Convention: {PROVIDER}{RESOURCE_TYPE}{PROJECT_KEY}
Mixed IDs and Names Per Project:
JIRA_BOARDS_BACKEND=123,NewBoard,456
→ Validates 123, 456 exist → Creates "NewBoard" → Updates .env: JIRA_BOARDS_BACKEND=123,789,456 (all IDs!)
Validation Flow
Step 1: Project Validation
Check if project exists:
API call to Jira
GET /rest/api/3/project/PROJECTKEY
If project exists:
✅ Project "PROJECTKEY" exists ID: 10001 Name: My Project
If project doesn't exist:
⚠️ Project "PROJECTKEY" not found
What would you like to do?
- Select an existing project
- Create a new project
- Cancel
Your choice [1]:
Option 1: Select Existing:
Available projects:
- PROJ1 - Project One
- PROJ2 - Project Two
- PROJ3 - Project Three
Select a project [1]:
✅ Updated .env: JIRA_PROJECT=PROJ1
Option 2: Create New:
Enter project name: My New Project
📦 Creating Jira project: PROJECTKEY (My New Project)... ✅ Project created: PROJECTKEY (ID: 10005)
Step 2: Board Validation (Per-Board Smart Detection)
Scenario A: All Board IDs (all numeric):
JIRA_BOARDS=1,2,3
Validation:
Checking boards: 1,2,3... ✅ Board 1: Frontend Board (exists) ✅ Board 2: Backend Board (exists) ⚠️ Board 3: Not found
⚠️ Issues found: 1 board(s)
Scenario B: All Board Names (all non-numeric):
JIRA_BOARDS=Frontend,Backend,Mobile
Auto-creation:
Checking boards: Frontend,Backend,Mobile... 📦 Creating board: Frontend... ✅ Created: Frontend (ID: 101) 📦 Creating board: Backend... ✅ Created: Backend (ID: 102) 📦 Creating board: Mobile... ✅ Created: Mobile (ID: 103)
📝 Updating .env with board IDs... ✅ Updated JIRA_BOARDS: 101,102,103
✅ All boards validated/created successfully
Scenario C: Mixed IDs and Names (SMART!):
JIRA_BOARDS=101,102,QA,Dashboard
Smart handling:
Checking boards: 101,102,QA,Dashboard... ✅ Board 101: Frontend Board (exists) ✅ Board 102: Backend Board (exists) 📦 Creating board: QA... ✅ Created: QA (ID: 103) 📦 Creating board: Dashboard... ✅ Created: Dashboard (ID: 104)
📝 Updating .env with board IDs... ✅ Updated JIRA_BOARDS: 101,102,103,104
✅ All boards validated/created successfully
Usage Examples
Example 1: Fresh Jira Setup
Scenario: New project, no Jira resources exist yet
Action: Run /sw-jira:sync
What Happens:
🔍 Validating Jira configuration...
Checking project: MINIDOOM... ⚠️ Project "MINIDOOM" not found
What would you like to do?
- Select an existing project
- Create a new project
- Cancel
Your choice [2]: 2
Enter project name: Mini DOOM Tournament
📦 Creating Jira project: MINIDOOM (Mini DOOM Tournament)... ✅ Project created: MINIDOOM (ID: 10005)
Checking boards: Frontend,Backend,Mobile... 📦 Creating boards from names...
Creating board: Frontend in project MINIDOOM... ✅ Board created: Frontend (ID: 101)
Creating board: Backend in project MINIDOOM... ✅ Board created: Backend (ID: 102)
Creating board: Mobile in project MINIDOOM... ✅ Board created: Mobile (ID: 103)
✅ Updated .env: JIRA_BOARDS=101,102,103
🎉 Jira configuration complete! All resources ready.
Result: .env now has correct project and board IDs
Example 2: Select Existing Project
Scenario: Project already exists in Jira
Action: Run validation
What Happens:
🔍 Validating Jira configuration...
Checking project: PROJ... ⚠️ Project "PROJ" not found
What would you like to do?
- Select an existing project
- Create a new project
- Cancel
Your choice [1]: 1
Available projects:
- FRONTEND - Frontend Team
- BACKEND - Backend Team
- MOBILE - Mobile Team
Select a project [1]: 2
✅ Updated .env: JIRA_PROJECT=BACKEND ✅ Project "BACKEND" exists
Checking boards: 45,46... ✅ All boards exist
Example 3: Mixed Board IDs (Some Exist, Some Don't)
Scenario: Some board IDs are invalid
Action: Run validation
What Happens:
🔍 Validating Jira configuration...
Checking project: PROJECTKEY... ✅ Project "PROJECTKEY" exists
Checking boards: 1,2,999...
Board 1: ✅ Exists (Frontend Board) Board 2: ✅ Exists (Backend Board) Board 999: ❌ Not found
⚠️ Boards not found: 999
Available boards in project PROJECTKEY:
- Frontend Board (ID: 1)
- Backend Board (ID: 2)
- QA Board (ID: 3)
- DevOps Board (ID: 4)
Would you like to:
- Remove invalid board (999) from configuration
- Replace with correct board ID
- Create new board
Your choice [2]: 2
Enter correct board ID or name: 3
✅ Updated .env: JIRA_BOARDS=1,2,3
CLI Command
Manual validation:
From TypeScript
npx tsx src/utils/external-resource-validator.ts
Or via skill activation
"Can you validate my Jira configuration?"
Validation output:
{ valid: true, project: { exists: true, key: 'PROJECTKEY', id: '10001', name: 'My Project' }, boards: { valid: true, existing: [1, 2, 3], missing: [], created: [] }, envUpdated: false }
Smart Board Creation Logic (Per-Board Detection)
Detection Algorithm
// Parse JIRA_BOARDS from .env const boardsConfig = "101,102,QA,Dashboard"; // Mixed! const boardEntries = boardsConfig.split(',').map(b => b.trim()); const finalBoardIds = [];
// Check EACH board individually for (const entry of boardEntries) { const isNumeric = /^\d+$/.test(entry);
if (isNumeric) {
// Entry is a board ID - validate it exists
const boardId = parseInt(entry);
const board = await checkBoard(boardId);
if (board) {
console.log(✅ Board ${boardId}: ${board.name} (exists));
finalBoardIds.push(boardId);
} else {
console.error(⚠️ Board ${boardId}: Not found);
}
} else {
// Entry is a board name - create it
console.log(📦 Creating board: ${entry}...);
const board = await createBoard(entry, projectKey);
console.log(✅ Created: ${entry} (ID: ${board.id}));
finalBoardIds.push(board.id);
}
}
// Update .env if any boards were created if (createdBoardIds.length > 0) { updateEnv({ JIRA_BOARDS: finalBoardIds.join(',') }); }
Key improvement: Per-board detection instead of all-or-nothing!
-
JIRA_BOARDS=1,2,3 → Validates all IDs
-
JIRA_BOARDS=A,B,C → Creates all boards
-
JIRA_BOARDS=1,2,C → Validates 1,2, creates C (mixed!)
Board Creation API
Jira REST API (v3):
POST /rest/api/3/board Content-Type: application/json
{ "name": "Frontend Board", "type": "scrum", "filterId": 10000, # Filter for project issues "location": { "type": "project", "projectKeyOrId": "PROJECTKEY" # CRITICAL: Associates board with project } }
Response: { "id": 101, "name": "Frontend Board", "type": "scrum" }
IMPORTANT: The location field is MANDATORY to associate the board with a project. Without it, Jira creates the board but leaves it detached, requiring manual connection via the UI.
Filter creation (required for board):
POST /rest/api/3/filter Content-Type: application/json
{ "name": "PROJECTKEY Issues", "jql": "project = PROJECTKEY" }
Response: { "id": 10000 }
Configuration Examples
Example 1: All Names (Create Boards)
Before (.env ):
JIRA_PROJECT=PROJ JIRA_BOARDS=Frontend,Backend,QA,DevOps
After validation:
JIRA_PROJECT=PROJ JIRA_BOARDS=101,102,103,104
What happened:
-
Detected non-numeric values (names)
-
Created 4 boards in Jira
-
Updated .env with actual board IDs
Example 2: All IDs (Validate Existing)
Before (.env ):
JIRA_PROJECT=PROJ JIRA_BOARDS=1,2,3
After validation:
JIRA_PROJECT=PROJ JIRA_BOARDS=1,2,3
What happened:
-
Detected numeric values (IDs)
-
Validated all boards exist
-
No changes needed
Example 3: Mixed IDs and Names (SMART!)
Before (.env ):
JIRA_PROJECT=PROJ JIRA_BOARDS=101,102,QA,Dashboard
After validation:
JIRA_PROJECT=PROJ JIRA_BOARDS=101,102,103,104
What happened:
-
Validated boards 101, 102 exist
-
Created "QA" board (got ID 103)
-
Created "Dashboard" board (got ID 104)
-
Updated .env with ALL board IDs
-
This is the key feature - you can mix existing IDs with new board names!
Example 4: Fix Invalid Project
Before (.env ):
JIRA_PROJECT=NONEXISTENT JIRA_BOARDS=1,2
After validation (user selected existing project):
JIRA_PROJECT=EXISTINGPROJ JIRA_BOARDS=1,2
What happened:
-
Project NONEXISTENT not found
-
User selected EXISTINGPROJ from list
-
Updated .env with correct project key
Error Handling
Error 1: Invalid Credentials
Symptom: API calls fail with 401 Unauthorized
Solution:
❌ Jira API authentication failed
Please check:
- JIRA_API_TOKEN is correct
- JIRA_EMAIL matches your Jira account
- JIRA_DOMAIN is correct (yourcompany.atlassian.net)
Generate new token at: https://id.atlassian.com/manage-profile/security/api-tokens
Error 2: Insufficient Permissions
Symptom: Cannot create projects/boards (403 Forbidden)
Solution:
❌ Insufficient permissions to create resources
You need:
- Project Creator permission (for projects)
- Board Creator permission (for boards)
Contact your Jira administrator to request permissions.
Error 3: Project Key Already Taken
Symptom: Project creation fails (key exists)
Solution:
❌ Project key "PROJ" already exists
Options:
- Use a different project key
- Select the existing project
- Cancel
Your choice [2]:
Error 4: Network/API Errors
Symptom: API calls timeout or fail
Solution:
❌ Jira API error: Request timeout
Please check:
- Internet connection
- Jira domain is correct
- Jira is not down (check status.atlassian.com)
Retry? [Y/n]:
Integration with SpecWeave Workflow
Automatic Validation
When using /sw-jira:sync , validation runs automatically:
/sw-jira:sync 0014
Internally calls:
- validateJiraResources()
- Fix missing project/boards
- Proceed with sync
Manual Validation
Run validation independently:
Via skill
"Validate my Jira configuration"
Via TypeScript
npx tsx src/utils/external-resource-validator.ts
Via CLI (future)
specweave validate-jira
Best Practices
✅ Use board names for initial setup:
JIRA_BOARDS=Sprint-1,Sprint-2,Backlog
-
System creates boards automatically
-
Updates .env with IDs
-
One-time setup, then use IDs
✅ Use board IDs after creation:
JIRA_BOARDS=101,102,103
-
Faster validation (no creation needed)
-
More reliable (IDs don't change)
✅ Keep .env in version control (gitignored tokens):
Commit project/board structure
JIRA_PROJECT=PROJ JIRA_BOARDS=101,102,103
Don't commit sensitive data
JIRA_API_TOKEN=<redacted> JIRA_EMAIL=<redacted>
✅ Document board mapping (in README):
Jira Boards
- Board 101: Frontend Team
- Board 102: Backend Team
- Board 103: QA Team
Summary
This skill ensures your Jira configuration is always valid by:
-
✅ Validating projects - Check if project exists, prompt to select or create
-
✅ Validating boards - Check if boards exist (IDs) or create them (names)
-
✅ Auto-updating .env - Replace board names with IDs after creation
-
✅ Clear error messages - Actionable guidance for all failures
-
✅ Non-blocking - Graceful degradation with manual fallback
Result: Zero manual Jira setup - system handles everything!
Skill Version: 1.0.0 Introduced: SpecWeave v0.9.5 Last Updated: 2025-11-09