jira-resource-validator
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_PROJECTexists - 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:syncand resources are missing - Your
.envhas 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?
1. Select an existing project
2. Create a new project
3. Cancel
Your choice [1]:
Option 1: Select Existing:
Available projects:
1. PROJ1 - Project One
2. PROJ2 - Project Two
3. 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?
1. Select an existing project
2. Create a new project
3. 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?
1. Select an existing project
2. Create a new project
3. Cancel
Your choice [1]: 1
Available projects:
1. FRONTEND - Frontend Team
2. BACKEND - Backend Team
3. 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:
1. Frontend Board (ID: 1)
2. Backend Board (ID: 2)
3. QA Board (ID: 3)
4. DevOps Board (ID: 4)
Would you like to:
1. Remove invalid board (999) from configuration
2. Replace with correct board ID
3. 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 IDsJIRA_BOARDS=A,B,C→ Creates all boardsJIRA_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:
1. JIRA_API_TOKEN is correct
2. JIRA_EMAIL matches your Jira account
3. 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:
1. Use a different project key
2. Select the existing project
3. Cancel
Your choice [2]:
Error 4: Network/API Errors
Symptom: API calls timeout or fail
Solution:
❌ Jira API error: Request timeout
Please check:
1. Internet connection
2. Jira domain is correct
3. 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:
1. validateJiraResources()
2. Fix missing project/boards
3. 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