Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Tgd Jira Auto Sync

BSecurity

Parse TASKS.md and auto-create Jira Data Center issues in a single Sprint. Use as conditional skill in /tgd-plan phase after TASKS.md is generated.

2 stars
0 votes
0 copies
0 views
Added 9/22/2026
developmentpythongobashnodeapidatabasefrontendbackend

Works with

cliapi

Security Analysis

B75/100
criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
criticalDownloads and executes remote scripts — classic supply chain attack

Scanned 9/22/2026

Install to Claude Code

$npx -y skills add seikaikyo/dash-skills --skill tgd-jira-auto-sync --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tgd Jira Auto Sync?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Tgd Jira Auto Sync
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/seikaikyo-tgd-jira-auto-sync/badge)](https://www.skillsdirectory.com/skills/seikaikyo-tgd-jira-auto-sync)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: tgd-jira-auto-sync
description: "Parse TASKS.md and auto-create Jira Data Center issues in a single Sprint. Use as conditional skill in /tgd-plan phase after TASKS.md is generated."
trigger: "After /tgd-plan generates TASKS.md, when user wants Jira tickets created"
---

# Jira Auto-Sync (TASKS.md → Jira Sprint)

## Overview

Parses the `TASKS.md` produced by `/tgd-plan` and creates Jira issues in the company's **Jira Data Center** instance, all assigned to a single Sprint. Uses `curl` + Jira REST API v2 — no external CLI binary needed, works behind company proxies.

## Prerequisites

The user MUST provide these before the skill runs:

```
JIRA_URL      = https://jira.company.com          (Data Center base URL)
JIRA_TOKEN = Personal Token (PAT)
JIRA_PROJECT   = Project key (e.g. ENG, FE, BE) — 必填
```

**Setup (one-time):**
```bash
# Test connection (Bearer auth)
curl -x "" -s -H "Authorization: Bearer $JIRA_TOKEN" "$JIRA_URL/rest/api/2/myself" | python3 -m json.tool
```
If it returns user info, auth works. If 401/403, check credentials or proxy settings.

**Priority Mapping:**
Map TASKS.md priority to Jira priority names (check your instance via `curl -x "" $JIRA_URL/rest/api/2/priority`):
- High → "High" (or "Highest", "Critical")
- Medium → "Medium" (or "Normal")
- Low → "Low" (or "Lowest")

## Proxy / Firewall Handling

Company networks often intercept HTTPS. If curl fails with SSL errors or timeouts:

```bash
# Option 1: Set proxy (if Jira is external or proxy is required to reach it)
export HTTPS_PROXY=http://proxy.company.com:8080

# Option 2: Bypass proxy for internal Jira Data Center (if proxy is globally set but Jira is on intranet)
# Use curl -x "" to bypass the proxy
curl -x "" -s -H "Authorization: Bearer $JIRA_TOKEN" ...

# Option 3: MITM proxy re-signs TLS — point curl at the company CA bundle
curl --cacert /path/to/company-ca-bundle.crt ...
# or: export CURL_CA_BUNDLE=/path/to/company-ca-bundle.crt
```

**Never disable certificate verification** (`curl -k`, `NODE_TLS_REJECT_UNAUTHORIZED=0`).
The request carries your Jira PAT — sending it over an unverified connection hands
the token to whoever can intercept. Ask IT for the CA bundle path instead.

## TASKS.md Format

The skill parses the **canonical TASKS.md format** defined in
`tgd-planning-and-task-breakdown` (the only TASKS.md format). Per task section:

```markdown
## Task 1: [User Story Title] (Story ID: US-01)

### 1. Context & Goal
[Goal + **Priority**: High/Medium/Low + **Dependencies**]

### 2. Technical Design
[Schema / API contract]

### 3. Acceptance Criteria (BDD)
- **AC-1.1** — **Given** [context] **When** [action] **Then** [result]
  - **Regression**: Yes [R] / No
  - **Test**: `tests/path` (present once /tgd-develop has run)

### 4. Files Likely Touched
- `src/foo.py`
```

Extract per task: number, title (summary), Context & Goal (description),
Priority, the `AC-<task>.<n>` criteria, and Files Likely Touched. Keep the
original AC ids — they are the traceability link back to TASKS.md.

## Execution Steps

### Step 1: Parse TASKS.md

Read `$TGD_DIR/<feature-name>/TASKS.md` and extract each task block:
- Task number/ID
- Title (summary)
- Description
- Acceptance Criteria (as checklist)
- Files Likely Touched
- Estimate (if present)

### Step 2: Discover Issue Types and Required Fields (Jira 9.0+ DC Compliant)

**Step 2a: Fetch Available Issue Types for the Project**
Use the Jira REST API v2 (Jira 9.0+ DC compliant) to get all available issue types for the project.

```bash
curl -x "" -s \
  "$JIRA_URL/rest/api/2/issue/createmeta/$JIRA_PROJECT/issuetypes" \
  -H "Authorization: Bearer $JIRA_TOKEN" \
  -H "Content-Type: application/json" > /tmp/jira_issuetypes.json
```

**Parse and present issue types:**
```bash
# JIRA_PROJECT must be exported to the environment for the heredoc to see it
python3 << 'PYEOF'
import json, os

data = json.load(open("/tmp/jira_issuetypes.json"))
issuetypes = data.get("values", [])

print(f"📌 Project: {os.environ['JIRA_PROJECT']}")
print("Available Issue Types:")
for i, it in enumerate(issuetypes, 1):
    print(f"  [{i}] {it['name']} (ID: {it['id']})")
PYEOF
```

> 🛑 **Action:** Present the issue type list to the user. Default to **Story** if present. Store their choice as `ISSUE_TYPE_ID`.

**Step 2b: Fetch Required Fields for the Selected Issue Type**
Query the exact metadata for the chosen `ISSUE_TYPE_ID`. This returns **only** the fields available for that specific issue type in this project, including required flags and allowed values.

```bash
curl -x "" -s \
  "$JIRA_URL/rest/api/2/issue/createmeta/$JIRA_PROJECT/issuetypes/$ISSUE_TYPE_ID" \
  -H "Authorization: Bearer $JIRA_TOKEN" \
  -H "Content-Type: application/json" > /tmp/jira_meta.json
```

**Parse and present required custom fields:**
```bash
python3 << 'PYEOF'
import json, subprocess, os

meta = json.load(open("/tmp/jira_meta.json"))
fields = meta.get("fields", {})
project_key = os.environ['JIRA_PROJECT']

print(f"🔍 Required Custom Fields for {project_key} (IssueType ID: {os.environ['ISSUE_TYPE_ID']}):")

required_fields = []
for field_id, field_info in fields.items():
    if field_info.get("required") and field_id not in ("summary", "description", "project", "issuetype", "priority", "labels", "reporter"):
        required_fields.append({
            "id": field_id,
            "name": field_info["name"],
            "schema": field_info.get("schema", {}),
            "allowed_values": field_info.get("allowedValues", [])
        })

for rf in required_fields:
    schema = rf["schema"]
    allowed = rf["allowed_values"]
    field_id = rf["id"]
    
    # Case 1: Has static allowedValues (Dropdown, select, components)
    if allowed:
        options = [v.get("name", v.get("value", str(v))) for v in allowed]
        print(f"  • {field_id}: {rf['name']} (type: {schema.get('type')}) - Options: {options}")
    
    # Case 2: Dynamic Epic Link / Parent (Fetch existing epics in project)
    elif "epic" in rf["name"].lower() or "parent" in rf["name"].lower():
        print(f"  • {field_id}: {rf['name']} (type: {schema.get('type')}) - Dynamic Epic Link")
        print("    🔍 Querying active Epics in JIRA...")
        # Run JQL to get Epics
        try:
            res = subprocess.run([
                "curl", "-x", "", "-s", 
                "-H", f"Authorization: Bearer {os.environ.get('JIRA_TOKEN')}",
                f"{os.environ.get('JIRA_URL')}/rest/api/2/search?jql=project={project_key}+AND+issuetype=Epic&maxResults=50&fields=key,summary"
            ], capture_output=True, text=True)
            epics_data = json.loads(res.stdout)
            epics = epics_data.get("issues", [])
            if epics:
                print("    Available Epics:")
                for ep in epics:
                    print(f"      - [{ep['key']}] {ep.get('fields', {}).get('summary')}")
            else:
                print("    ⚠️ No Epics found in this project.")
        except Exception as e:
            print(f"    ⚠️ Failed to query Epics: {str(e)}")
    
    # Case 3: Standard open input (string, date, number)
    else:
        print(f"  • {field_id}: {rf['name']} (type: {schema.get('type')}) - [Open text/value input]")

if not required_fields:
    print("  ✅ No required custom fields.")

print("\n===META_JSON===")
print(json.dumps(meta))
PYEOF
```

> 🛑 **Agent Interaction Guide (Mandatory):**
> When you find required fields, you MUST ask the user one-by-one or in a clean list. Follow this conversational style:
>
> ```
> 🔍 I found the following required fields for project [ENG] with IssueType [Story]:
>
> 1. customfield_10100: "Component" (type: option)
>    Options: [1] Backend  [2] Frontend  [3] Database
>    👉 Please reply with the number or name to select.
>
> 2. customfield_10200: "Epic Link" (type: string)
>    Options (Active Epics found via JQL):
>    [1] [ENG-100] User Auth Redesign
>    [2] [ENG-101] Core Database Migration
>    👉 Please reply with the number or Epic Key.
>
> 3. customfield_10300: "Target Release Date" (type: date)
>    👉 Please reply with the value (Format: YYYY-MM-DD).
> ```
>
> **Do not guess or skip.** Store all user answers and dynamically build the payload under `fields`.

### Step 3: Create Issues

For each parsed task, construct a JSON payload and create a Jira issue.

**📝 Summary Format Rule (Mandatory):**
The summary MUST be structured in the classic User Story format and strictly under 255 characters.
Format: `[feature-name] As a <user role>, I want <action/goal> so that <benefit>`
> 💡 Example: `[jwt-auth] As a user, I want to login via email to access my secure dashboard`

**📝 Description Format Rule (Mandatory):**
The Agent MUST construct the `DESCRIPTION` variable using this Wiki Markup structure. Do NOT deviate from this format.
```
h3. Background
{noformat}
<Why is this needed? Current pain point or context from PRD/SPEC.>
{noformat}

h3. Goal
{noformat}
<What exactly are we building? The desired measurable outcome.>
{noformat}

h3. Acceptance Criteria
{noformat}
AC-<task>.<n> (copy the exact id from TASKS.md — it is the traceability link):
Given <initial context>
When <action occurs>
Then <expected result>
{noformat}

h3. Technical Notes
{noformat}
Files Likely Touched:
- <path/to/file1>
- <path/to/file2>
Estimate: <X points>
{noformat}
```

```bash
# 1. Export variables for the Python script (avoids bash escaping hell)
export SUMMARY="[<feature-name>] Task Title"
export PRIORITY="High"
export DESCRIPTION="h3. Background..."
export FEATURE_NAME="<feature-name>"

# 2. Construct the payload via Python
python3 << 'EOF' > /tmp/jira_payload.json
import json, os

payload = {
    "fields": {
        "project":   { "key": os.environ['JIRA_PROJECT'] },
        "summary":   os.environ['SUMMARY'],
        "issuetype": { "id": os.environ['ISSUE_TYPE_ID'] },
        "priority":  { "name": os.environ['PRIORITY'] },
        "labels":    ["tgd", os.environ['FEATURE_NAME']],
        "description": os.environ['DESCRIPTION']
    }
}

# Add any custom required fields discovered in Step 2
# payload['fields']['customfield_XXXX'] = { "value": user_provided_value }

print(json.dumps(payload))
EOF

# 3. Execute the API call
curl -x "" -s -X POST \
  "$JIRA_URL/rest/api/2/issue" \
  -H "Authorization: Bearer $JIRA_TOKEN" \
  -H "Content-Type: application/json" \
  -d @/tmp/jira_payload.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('key','ERROR: '+d.get('errorMessages',str(d))[0]))"
```

### 💉 Custom Field Injection Reference

Mandatory fields vary by company and project. When a field is required, inject it into the JSON payload using the correct data type:

```json
// Dropdown / Select List (Single Choice)
"customfield_10100": { "value": "High" },

// Component/s (Multi-select)
"components": [{ "name": "Backend" }, { "name": "Database" }],

// Fix Version/s (Multi-select)
"fixVersions": [{ "name": "v1.2.0" }],

// Epic Link / Parent (String)
"customfield_10011": "PROJ-1001",

// User Picker (Single User)
"customfield_10300": { "name": "elon.wang" },

// Text / Text Area (String)
"customfield_10400": "Some internal notes here.",

// Labels
"labels": ["tgd", "jwt-auth", "urgent"]
```
> ⚠️ **Warning:** The `schema.type` returned by `createmeta` determines the structure. 
> *   `option` → `{ "value": "..." }`
> *   `array` → `[{ "name": "..." }]`
> *   `string` → `"..."` directly.

#### 🏆 Golden Example

**Scenario:** `feature-name` = `jwt-auth`, Task = "Implement Login API"

```json
{
  "fields": {
    "project": { "key": "ENG" },
    "summary": "[jwt-auth] As a user, I want to login via email and password to access my dashboard",
    "issuetype": { "id": "10000" },
    "priority": { "name": "High" },
    "labels": ["tgd", "jwt-auth"],
    "description": "h3. Background\n{noformat}\nCurrently, the system has no authentication. All endpoints are public, causing data leakage risks.\n{noformat}\n\nh3. Goal\n{noformat}\nImplement a secure POST /login endpoint that validates credentials and returns a JWT token valid for 24 hours.\n{noformat}\n\nh3. Acceptance Criteria\n{noformat}\nAC-1.1:\nGiven a registered user with valid credentials\nWhen they POST to /api/login\nThen they receive a 200 OK with a JWT token in the body\n\nAC-1.2:\nGiven an unregistered user or wrong password\nWhen they POST to /api/login\nThen they receive 401 Unauthorized and no token\n{noformat}\n\nh3. Technical Notes\n{noformat}\nFiles:\n- src/auth/login.py\n- tests/test_login.py\n- config/settings.py (JWT_SECRET)\n{noformat}"
  }
}
```

> ⚠️ **Critical:** The `summary` must always start with `[<feature-name>]` and follow the "As a... I want... So that..." format where possible. Keep it under 255 characters.

**Output:** Print each created issue key (e.g. `ENG-1234`).

### Step 4: Error Handling

If an issue creation fails, the script should:
- **401/403**: Token expired or invalid → Stop and ask user to re-provide `JIRA_TOKEN`
- **400 (summary too long)**: Jira limit is 255 chars. Shorten the summary and retry.
- **400 (missing field)**: Print the error, re-check createmeta for required fields, ask user for value.
- **400 (invalid priority)**: Fetch valid priorities via `$JIRA_URL/rest/api/2/priority` and retry.
- **500**: Retry once with `sleep 1`, if still fails skip and continue
- Continue processing remaining tasks even if one fails

### Step 5: Report

Output a summary table:

```
| TASKS.md Task | Jira Key | Status |
|---------------|----------|--------|
| Task 1: xxx   | ENG-1234 | ✅ Created |
| Task 2: yyy   | ENG-1235 | ✅ Created |
| Task 3: zzz   | -        | ❌ Failed: ... |
```

## Automation Pattern (for /tgd-plan conditional)

In `/tgd-plan`, add as a conditional skill:

```markdown
**Conditional (apply when relevant):**
- User wants Jira tickets? → `tgd-jira-auto-sync`
  1. Ask for JIRA_URL, JIRA_PROJECT (必填), JIRA_TOKEN.
  2. Query `createmeta` once to discover issue types + required fields. Let user choose issue type (default: Story). If required custom fields have allowedValues, present options.
  3. Parse $TGD_DIR/<feature-name>/TASKS.md and create issues via REST API v2.
  4. Report created issue keys.
```

## Pitfalls

### Data Center API Versions

- **REST API v2** (`/rest/api/2/`) — works on all Data Center versions
- **REST API v3** (`/rest/api/3/`) — DC 8.0+, uses Atlassian Document Format (ADF) for description fields. If v3, description must be ADF JSON, not wiki markup
- **Recommendation:** Use v2 with wiki markup (`h3.`, `{noformat}`) — simpler and universally compatible

### Custom Fields

If the company Jira has **required custom fields** (e.g., Component, Fix Version, Severity), the create payload must include them:

```json
"customfield_10100": {"value": "High"},
"components": [{"name": "Backend"}]
```

**How to discover:** Step 2's createmeta already includes all required fields and allowedValues. Use that result directly.

### SSL / Proxy Interception

Company MITM proxies cause `SSL certificate problem`. Solutions:
1. Set `REQUESTS_CA_BUNDLE` or `CURL_CA_BUNDLE` to the company CA cert path — this is the only acceptable fix.
2. Never disable verification (`curl -k`, `NODE_TLS_REJECT_UNAUTHORIZED=0`): the request carries your Jira PAT.

### Rate Limiting

Data Center may throttle bulk creation. If creating 20+ issues:
- Add `sleep 0.5` between API calls
- Or batch via `/rest/batch/1.0/issue` (if available on DC 9.0+)

## When to Use

- When `/tgd-plan` generates `TASKS.md`
- When user wants to sync tasks to Jira Data Center
- When planning sprint backlog from task breakdown

## Common Rationalizations

| Rationalization | Reality |
|---|---|
| "I'll sync to Jira later" | Later never comes. Sync immediately after plan. |
| "Manual Jira entry is fine" | Manual entry loses the link between TASKS.md and Jira. |

## Red Flags

- Tasks created in Jira without corresponding TASKS.md entries
- Jira issues missing acceptance criteria from TASKS.md
- Sync run without user confirmation

## Verification

After execution, verify:
- [ ] All tasks from TASKS.md have corresponding Jira keys
- [ ] No creation errors in the report
- [ ] Created issues are viewable in Jira UI

Attribution

seikaikyoseikaikyo
View sourceMore from seikaikyo →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284072 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →