Skip to content
Development
Skill

/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.

From plugin
specweave
15651 skills20 agents73 commands
Install
$ npx -y skills add anton-abyzov/specweave --skill jira-resource-validator --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/jira-resource-validator

Context preview

The summary Claude sees to decide when to auto-load this skill.

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.

SKILL.md

jira-resource-validator.SKILL.md
description: 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.
version: 1.0.0
user-invokable: false
allowed-tools: Read, Bash, Write, Edit

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.

Security Rules (MANDATORY)

These rules apply to ALL JIRA API operations in this skill.

Credential Handling

1. **Never collect credentials** — this skill reads from `.env` only, never prompts the user 2. **Never log secrets** — never echo token values, auth headers, or base64 credentials 3. **Never write credentials** — the user configures `.env` themselves (this skill may update non-secret keys like `JIRA_BOARDS` and `JIRA_PROJECT`)

Credential Loading

# 1. Validate presence FIRST (before reading any values)
for KEY in JIRA_API_TOKEN JIRA_EMAIL JIRA_DOMAIN; do
  if ! grep -qE "^${KEY}=.+" .env; then
    echo "Error: ${KEY} missing or empty in .env"
    exit 1
  fi
done

# 2. Load credentials ONLY after validation passes (never display values)
#    head -1 ensures only first match used if .env has duplicate keys
JIRA_API_TOKEN="$(grep '^JIRA_API_TOKEN=' .env | head -1 | cut -d '=' -f2-)"
JIRA_EMAIL="$(grep '^JIRA_EMAIL=' .env | head -1 | cut -d '=' -f2-)"
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | head -1 | cut -d '=' -f2-)"

Domain Validation (before ANY API call)

# Reject IP addresses first (SSRF prevention)
if [[ "$JIRA_DOMAIN" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+ ]] || [[ "$JIRA_DOMAIN" =~ ^\[.*\]$ ]] || [[ "$JIRA_DOMAIN" =~ ^0x ]]; then
  echo "Error: IP addresses not allowed — use a hostname"
  exit 1
fi

# Reject localhost and private networks
if [[ "$JIRA_DOMAIN" =~ ^(localhost|127\.|10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.) ]]; then
  echo "Error: Internal/localhost addresses not allowed"
  exit 1
fi

# Must be a valid hostname — no special chars, no consecutive dots
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$ ]]; then
  echo "Error: JIRA_DOMAIN contains invalid characters"
  exit 1
fi

# JIRA Cloud and Server/DC are both supported.
# Cloud domains match <subdomain>.atlassian.net; self-hosted use custom domains.
# No hard-block — deployment type is auto-detected at runtime.

API Call Pattern (HTTPS only, quoted variables)

AUTH="$(printf '%s:%s' "$JIRA_EMAIL" "$JIRA_API_TOKEN" | base64)"

# All API calls MUST use https://, double-quote all variables
curl -s -f \
  -H "Authorization: Basic $AUTH" \
  -H "Content-Type: application/json" \
  "https://${JIRA_DOMAIN}/rest/api/3/..."

---

What This Skill Does

This skill ensures your Jira configuration in `.env` is valid and all resources exist. It's **smart enough** to:

1. **Validate Jira projects** - Check if `JIRA_PROJECT` exists 2. **Prompt for action** - Select existing project or create new one 3. **Validate Jira boards** - Check if boards exist (by ID or name) 4. **Create missing boards** - If board names provided, create them automatically 5. **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>
JIRA_EMAIL=<your-email>
JIRA_DOMAIN=<your-company>.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:
Read more
Ships withspecweave

Spec-first AI development: describe a feature → AI creates spec + plan + tasks, builds autonomously, syncs to GitHub/JIRA. Domain-expert skills for PM, Architect, Frontend, QA learn your patterns permanently. Claude Code, Codex, Cursor, Copilot & more.

Get the whole plugin