plugins/specweave/skills/jira-sync/SKILL.md
Sync guidance for SpecWeave increments with JIRA epics/stories (content SpecWeave→JIRA, status JIRA→SpecWeave). Use when asking about JIRA integration setup or troubleshooting sync. For actual syncing, use sw-jira:sync command instead.
npx skillsauth add anton-abyzov/specweave plugins/specweave/skills/jira-syncInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Coordinates JIRA synchronization by delegating to jira-mapper agent.
Sync Behavior: Content (specs, tasks) syncs SpecWeave → JIRA. Status (open/closed) syncs JIRA → SpecWeave.
⚠️ IMPORTANT: This skill provides HELP and GUIDANCE about JIRA sync. For actual syncing, users should use the sw-jira:sync command directly. This skill should NOT auto-activate when the command is being invoked.
✅ Do activate when:
❌ Do NOT activate when:
sw-jira:sync command (command handles it)BEFORE attempting JIRA sync, CHECK for JIRA credentials.
SECURITY RULE: This skill MUST NOT collect, write, or store credentials. The user configures their own .env file. The skill only validates that credentials exist.
# Check .env file for required credentials (existence only — never read values)
if [ -f .env ] && grep -q "^JIRA_API_TOKEN=" .env && grep -q "^JIRA_EMAIL=" .env && grep -q "^JIRA_DOMAIN=" .env; then
echo "JIRA credentials found in .env"
else
echo "JIRA credentials missing — see setup instructions below"
# STOP HERE — do NOT prompt user for secrets
fi
Do NOT ask the user to paste credentials into the chat. Instead, show self-service setup:
JIRA credentials are required but not configured.
**Setup (do this yourself — the agent should NOT handle your secrets):**
1. Create an API token at: https://id.atlassian.com/manage-profile/security/api-tokens
2. Add these lines to your project `.env` file:
JIRA_API_TOKEN=<your-token>
JIRA_EMAIL=<your-email>
JIRA_DOMAIN=<your-company>.atlassian.net
3. Ensure `.env` is in `.gitignore`
4. Re-run the sync command
For self-hosted JIRA: Use a Personal Access Token (PAT) and your server's hostname.
IMPORTANT: After showing instructions, STOP. Do not continue until credentials are configured by the user.
# Validate that required keys exist and have non-empty values
# Uses grep -qE to check pattern without reading values into variables
MISSING=()
for KEY in JIRA_API_TOKEN JIRA_EMAIL JIRA_DOMAIN; do
if ! grep -qE "^${KEY}=.+" .env; then
MISSING+=("$KEY")
fi
done
if [ ${#MISSING[@]} -gt 0 ]; then
echo "Missing or empty credentials: ${MISSING[*]}"
exit 1
fi
echo "All required credentials present"
# Read domain safely — quote all expansions, take first match only
JIRA_DOMAIN="$(grep '^JIRA_DOMAIN=' .env | head -1 | cut -d '=' -f2-)"
# Reject empty
if [ -z "$JIRA_DOMAIN" ]; then
echo "Error: JIRA_DOMAIN is empty"
exit 1
fi
# Reject IP addresses FIRST — IPv4, IPv6 brackets, hex-encoded (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 internal hostnames
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 — each label: alphanumeric, hyphens allowed mid-label, 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 is not a valid hostname"
exit 1
fi
# Cloud JIRA: must end with .atlassian.net
# Self-hosted JIRA: any valid hostname is accepted after user confirmation
if [[ ! "$JIRA_DOMAIN" =~ ^[a-zA-Z0-9-]+\.atlassian\.net$ ]]; then
echo "Warning: Domain does not match <subdomain>.atlassian.net (Jira Cloud) pattern"
echo "If this is a self-hosted JIRA instance, confirm the domain is correct and proceed."
# Agent: use AskUserQuestion to confirm non-standard domain before continuing
fi
Add to .specweave/config.json:
{
"sync": {
"enabled": true,
"preset": "bidirectional",
"activeProfile": "default",
"profiles": {
"default": {
"provider": "jira",
"config": {
"domain": "mycompany.atlassian.net",
"projectKey": "MYPROJ",
"syncOnTaskComplete": true
}
}
}
}
}
For self-hosted JIRA, use your server's hostname as the domain (e.g., jira.internal.company.com).
This skill does NOT execute API calls directly (no Bash tool). Credential loading, authentication, and API operations are handled by the jira-mapper skill — see its Security Rules section for the hardened patterns (domain validation, HTTPS enforcement, SSRF prevention, variable quoting).
For production deployments, use OAuth 2.0 instead of API tokens:
Setup: https://developer.atlassian.com/console/myapps/ (OAuth 2.0 with scopes: read:jira-work, write:jira-work)
For self-hosted JIRA: Use Personal Access Tokens (PAT) instead of API tokens.
Export: /sync-jira export 0001
Import: /sync-jira import PROJ-123
Sync: /sync-jira sync 0001
All conversion logic is handled by the jira-mapper agent.
JIRA and Confluence are both Atlassian products and often used together. This skill can also help with Confluence page sync.
Same authentication and security rules as JIRA — user configures .env, skill only validates presence. Same domain validation applies (must be <subdomain>.atlassian.net, HTTPS only, no IPs). CONFLUENCE_DOMAIN MUST pass the same validation as JIRA_DOMAIN (Step 4) before any Confluence API call.
Required .env keys (configured by the user, NOT by this skill):
CONFLUENCE_API_TOKEN=<your-token> # Same as JIRA API token
CONFLUENCE_EMAIL=<your-email>
CONFLUENCE_DOMAIN=<your-company>.atlassian.net
CONFLUENCE_SPACE_KEY=<space-key>
| Operation | Endpoint | Method |
|-----------|----------|--------|
| Get page | /wiki/api/v2/pages/{id}?body-format=storage | GET |
| Update page | /wiki/api/v2/pages/{id} | PUT |
| Create page | /wiki/api/v2/pages | POST |
Every page update MUST increment the version number:
version.number (e.g., returns 5)version.number set to current + 1 (e.g., 6)If version is not incremented, the API returns 409 Conflict.
All Confluence API calls follow the same security rules as JIRA (HTTPS only, domain validation, credential handling). See the jira-mapper skill's Security Rules section for implementation patterns.
For complete Confluence API details, see:
tools
Generate AI videos from text prompts or images. Supports Google Veo 3.1 and Pollinations.ai (free). Use when generating video, creating animations, text-to-video, AI video, video generation, make clip, animate.
tools
Validate increment with rule-based checks and AI quality assessment. Use when saying "validate", "check quality", or "verify increment".
tools
Create and manage umbrella workspaces for multi-repo projects. Activate when the user wants to: create umbrella, umbrella init, wrap in umbrella, create workspace, setup multi-repo, migrate repos to umbrella, umbrella create, new workspace, restructure into umbrella, "wrap this repo", "create umbrella for these repos", "setup workspace with repos", "move repos into umbrella". Do NOT activate for: add a repo to existing umbrella (use sw:get), add a feature, add an increment, clone a repo (use sw:get).
tools
--- description: Merge completed parallel agent work and trigger GitHub sync per increment. Activates for: team merge, merge agents, combine work, team finish. --- # Team Merge **Verify all teammates completed, run quality gates, close increments, and trigger sync.** ## Usage ```bash sw:team-merge sw:team-merge --dry-run # Preview merge plan sw:team-merge --skip-sync # Merge without GitHub/JIRA sync ``` ## What This Skill Does 1. **Verify all teammates completed** -- bl