Claude-skill-registry jira-resource-validator
Validates JIRA projects and boards exist, auto-creates missing resources. Use when setting up JIRA integration, validating .env configuration, or troubleshooting missing projects/boards. Supports per-project board configuration with JIRA_BOARDS_{ProjectKey} pattern.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/jira-resource-validator" ~/.claude/skills/majiayu000-claude-skill-registry-jira-resource-validator && rm -rf "$T"
skills/data/jira-resource-validator/SKILL.mdJira 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
existsJIRA_PROJECT - 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
and resources are missing/sw-jira:sync - Your
has invalid Jira configuration.env - 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!
→ Validates all IDsJIRA_BOARDS=1,2,3
→ Creates all boardsJIRA_BOARDS=A,B,C
→ Validates 1,2, creates C (mixed!)JIRA_BOARDS=1,2,C
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