Create Jira Stories from existing local story markdown files. Read all story files in an epic directory, map fields to Jira, create issues with parent epic link, create dependency links between stories, and sync Jira keys back to local files.
Create Jira Story issues from existing local story-XXXX-YYYY.md files. Parse all story files in an epic directory, map fields to Jira attributes, create issues with parent epic link, create dependency links between stories, update the implementation map with Jira keys, and sync keys back to local files.
/x-jira-create-stories <epic_dir_path> — create Jira stories from the specified directory/x-jira-create-stories <epic_id> — create stories using epic ID (e.g., 0012)/x-story-create or /x-epic-decompose without Jira integration| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
EPIC_DIR_PATH | Path or ID | No | — | Epic directory path or epic ID (prompted if omitted) |
Read the field mapping reference before creating issues:
.claude/skills/x-jira-create-epic/references/jira-field-mapping.mdBash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-jira-create-stories Phase-1-Read-Markdowns
question: "Informe o caminho do diretorio do epico ou o ID (ex: plans/epic-0012 ou 0012)"
header: "Epic Directory"
0012), construct the path: plans/epic-{ID}/ERROR: Directory {path} not found. Ensure the epic was created first.
story-XXXX-*.md files in the directoryERROR: No story files found in {path}. Run /x-story-create first.
For each story file, extract:
# Historia: <titulo> (line 1)**ID:** field (e.g., story-0012-0001)**Chave Jira:** fieldClassify stories:
<CHAVE-JIRA> or —)If all stories already have Jira keys:
All {N} stories already have Jira keys. Nothing to create.
Exit.
Report and confirm:
question: "Confirma a criacao das historias no Jira?"
header: "Criar Stories no Jira"
description: |
Historias a criar: {count_to_create}
Historias ja no Jira (pular): {count_existing}
Stories a criar:
- {story-ID}: {title}
- {story-ID}: {title}
...
options:
- label: "Sim, criar todas"
description: "Criar {count_to_create} stories no Jira"
- label: "Nao, cancelar"
description: "Nao criar nada no Jira"
If "Nao": exit.
epic-XXXX.md from the same directory**Chave Jira:** value<CHAVE-JIRA> / —):
question: "O epico nao tem chave Jira. O que deseja fazer?"
header: "Epic Link"
options:
- label: "Criar stories sem vinculo ao epico"
description: "Stories serao criadas sem parent link"
- label: "Informar chave do epico manualmente"
description: "Informe a chave do epico no Jira (ex: PROJ-123)"
- label: "Cancelar — criar epico primeiro"
description: "Execute /x-jira-create-epic antes"
parent fieldparentCall mcp__atlassian__getAccessibleAtlassianResources to discover available Atlassian sites
Use the first available site's id as cloudId. If no sites returned:
ERROR: No accessible Atlassian sites found. Check your Atlassian credentials.
Abort.
Call mcp__atlassian__getVisibleJiraProjects with the discovered cloudId
Present the project list to the user:
question: "Selecione o projeto Jira para criar as stories:"
header: "Projeto Jira"
options:
- label: "{PROJECT_KEY} — my-fastapi-service"
description: "Project key: {PROJECT_KEY}"
(one option per project)
Capture the selected projectKey
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-jira-create-stories Phase-1-Read-Markdowns ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-jira-create-stories Phase-2-MCP-Loop
Process stories in dependency order (stories with no dependencies first, then those that depend on already-created stories). This ensures parent epic links and dependency links can be created.
Initialize a mapping: storyIdToJiraKey = {}
For each story (in dependency order):
Concatenate for Jira:
{Section 3 — User story paragraph and technical context}
---
## Entrega de Valor
- **Valor Principal:** {value from Section 3.5}
- **Metrica de Sucesso:** {metric from Section 3.5}
- **Impacto no Negocio:** {impact from Section 3.5}
Wrap each per-story MCP call with mcp-start / mcp-end markers (story-0040-0008
§3.2) so every tool.call event carries tool=mcp__atlassian__createJiraIssue
and a measured durationMs — yielding N tool.call events for N stories and
enabling per-skill aggregation of "tempo gasto no Jira" vs "tempo local":
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh mcp-start x-jira-create-stories createJiraIssue
Call mcp__atlassian__createJiraIssue:
cloudId: discovered cloudIdprojectKey: selected project keyissueTypeName: "Story"summary: story titledescription: constructed description (above)contentFormat: "markdown"parent (optional): epic Jira key (if available from Step 4)additional_fields:
{
"labels": [
{ "name": "generated-by-ia-dev-env" },
{ "name": "story-XXXX-YYYY" }
]
}
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh mcp-end x-jira-create-stories createJiraIssue ok
(On MCP failure in 6.5, pass status failed instead of ok to the mcp-end
marker so the telemetry record reflects the real outcome.)
Capture the returned Jira key. Store mapping: storyIdToJiraKey[storyId] = jiraKey.
Replace **Chave Jira:** <CHAVE-JIRA> or **Chave Jira:** — with **Chave Jira:** {jiraKey}.
Log warning, set <CHAVE-JIRA> to —, continue with next story.
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-jira-create-stories Phase-2-MCP-Loop ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-jira-create-stories Phase-3-Dependency-Links
After ALL stories are created and have Jira keys, perform a second pass to create dependency links:
For each story's "Blocked By" list:
Look up the blocker's Jira key in storyIdToJiraKey (or from the story file if pre-existing)
If both the current story and the blocker have Jira keys:
Wrap the MCP call with mcp-start / mcp-end markers so every dependency
link emits its own tool.call event with
tool=mcp__atlassian__createIssueLink:
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh mcp-start x-jira-create-stories createIssueLink
Call mcp__atlassian__createIssueLink:
cloudId: discovered cloudIdtype: "Blocks"inwardIssue: blocker's Jira key (the issue that blocks)outwardIssue: current story's Jira key (the issue that is blocked)Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh mcp-end x-jira-create-stories createIssueLink ok
If linking fails: log warning, continue (non-blocking, best-effort). Pass
status failed to the mcp-end marker on such failures.
If IMPLEMENTATION-MAP.md exists in the epic directory:
Chave Jira column with the actual Jira keyOutput summary:
## Resultado da Criacao no Jira
| Story | Titulo | Chave Jira | Status |
|-------|--------|------------|--------|
| story-XXXX-0001 | {title} | PROJ-101 | Criada |
| story-XXXX-0002 | {title} | PROJ-102 | Criada |
| story-XXXX-0003 | {title} | — | Falha: {error} |
**Resumo:**
- Stories criadas: {success_count}/{total_count}
- Links de dependencia criados: {link_count}
- Falhas: {failure_count}
- Implementation Map atualizado: {yes/no}
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-jira-create-stories Phase-3-Dependency-Links ok
| Scenario | Action |
|---|---|
| MCP tool not available | Abort with clear message about MCP configuration |
| No Atlassian sites found | Abort with credential check message |
| Epic directory not found | Abort with message: "Directory {path} not found" |
| No story files found | Abort with message: "No story files found — run /x-story-create first" |
| Individual story creation fails | Log warning, continue with remaining stories |
| Dependency link creation fails | Log warning, continue (best-effort) |
| File write fails | Log warning, mention Jira key was created but file not updated |
| Skill | Relationship | Context |
|---|---|---|
| x-story-create | reads | Reads story files generated by this skill |
| x-epic-decompose | called-by | Orchestrator may invoke this after story generation |
| x-jira-create-epic | calls | Creates the parent epic before stories |
| x-epic-map | reads | Implementation Map updated with Jira keys |
Bidirectional lookup is enabled by:
story-XXXX-YYYY) is stored as a Jira label**Chave Jira:** fieldlabels = "story-XXXX-YYYY" AND labels = "generated-by-ia-dev-env"