ワンクリックで
speckit-taskstoissues
Convert tasks from tasks.md into GitHub issues.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Convert tasks from tasks.md into GitHub issues.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | speckit-taskstoissues |
| description | Convert tasks from tasks.md into GitHub issues. |
| compatibility | Requires spec-kit project structure with .specify/ directory |
| metadata | {"author":"github-spec-kit","source":"preset:taskstoissues-jira"} |
| user-invocable | true |
| disable-model-invocation | false |
$ARGUMENTS
You MUST consider the user input before proceeding (if not empty).
Check for extension hooks (before tasks-to-issues conversion):
.specify/extensions.yml exists in the project root.hooks.before_taskstoissues keyenabled is explicitly false. Treat hooks without an enabled field as enabled by default.condition expressions:
condition field, or it is null/empty, treat the hook as executablecondition, skip the hook and leave condition evaluation to the HookExecutor implementation.) with hyphens (-). For example, speckit.git.commit → /speckit-git-commit.optional flag:
optional: true):
## Extension Hooks
**Optional Pre-Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
optional: false):
## Extension Hooks
**Automatic Pre-Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
Wait for the result of the hook command before proceeding to the Outline.
.specify/extensions.yml does not exist, skip silentlySetup: Run .specify/scripts/bash/check-prerequisites.sh --json --require-tasks --include-tasks from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute. Extract the absolute path to tasks.md from FEATURE_DIR. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot").
Load project configuration:
Read the project-level Jira config from dev/jira.yml at the repo root. Required keys: cloud, default_project_key, default_issue_type, custom_fields.epic_link, custom_fields.team, team.name, labels_default. Optional: team.id (cached UUID; auto-populated on first run), additional custom_fields.* entries (e.g. sprint, story_points) for future use.
[!CAUTION] If
dev/jira.ymldoes not exist, abort with:> dev/jira.yml not found. Copy .specify/presets/taskstoissues-jira/templates/jira.example.yml to dev/jira.yml at the repo root, fill in every REQUIRED field, and commit before re-running.
[!CAUTION] If any required top-level key is missing from
dev/jira.yml, abort with:> dev/jira.yml is missing required key '<key>'. See .specify/presets/taskstoissues-jira/templates/jira.example.yml for the full schema.Do not silently default.
[!CAUTION] If
default_project_keystill equals the example placeholderPROJ, abort with:> dev/jira.yml still has placeholder default_project_key 'PROJ'. Set it to your repo's Jira project key before re-running.
[!CAUTION] If
custom_fields.epic_linkorcustom_fields.teamequalscustomfield_XXXXX, abort with:> dev/jira.yml still has placeholder custom field IDs. Resolve real IDs with mcp__claude_ai_Atlassian__getJiraIssueTypeMetaWithFields and update the file before re-running.Do not invent IDs.
Resolve Atlassian cloud id: Call mcp__claude_ai_Atlassian__getAccessibleAtlassianResources once and match cloud from dev/jira.yml against the returned site URLs to obtain cloudId.
[!CAUTION] If
cloudIdcannot be resolved, orgetAccessibleAtlassianResourcesreturns more than one site without a unique match to the configuredcloud, abort with:> Multiple Atlassian sites accessible — pin one in dev/jira.yml under 'cloud' before re-running.
Resolve the Epic key:
git rev-parse --abbrev-ref HEAD. Build a case-insensitive regex from default_project_key of the form <default_project_key>-\d+ and match it against the branch name; uppercase the project-key portion of the match (e.g. with default_project_key=IFC, pmi-ifc-2521-auto-create-groups → IFC-2521).$ARGUMENTS against the same pattern.> Provide the Jira Epic for these tasks (e.g. <default_project_key>-1234): and wait for input. Validate the input matches the same <default_project_key>-\d+ pattern (case-insensitive).mcp__claude_ai_Atlassian__getJiraIssue and confirming fields.issuetype.name == "Epic". Abort if it is not an Epic.Resolve assignee account id: Call mcp__claude_ai_Atlassian__atlassianUserInfo once and read account_id from the response. That is the accountId of the user currently authenticated to the Atlassian MCP — the same user running the command — and becomes the assignee for every issue created in this run. Cache it for the duration of this run.
[!CAUTION] If
atlassianUserInfofails or returns noaccount_id, abort with:> Atlassian MCP not authenticated. Authenticate the Atlassian MCP server before re-running.Do not create any issues.
Resolve team UUID: From dev/jira.yml read team.name and team.id. Jira's Atlassian Teams picker (custom_fields.team) only accepts a UUID — team.name is kept in dev/jira.yml as a human label, never sent to Jira.
team.id is set, use it as-is.team.id is empty or missing, resolve it once via Atlassian:
mcp__claude_ai_Atlassian__searchJiraIssuesUsingJql with:
cloudId from step 3jql = 'project = <default_project_key> AND "Team[Team]" is not EMPTY ORDER BY created DESC'fields = ["<custom_fields.team>"]maxResults = 20<custom_fields.team>.name for an exact case-insensitive match to team.name from dev/jira.yml. Extract the matching <custom_fields.team>.id (the UUID).dev/jira.yml at team.id so future runs skip this lookup, and use that UUID for issue creation.> Team '<team.name>' not found in Atlassian (searched recent issues in <default_project_key>). Set team.id explicitly in dev/jira.yml before re-running. Do not create any issues.Pass the resolved value to createJiraIssue as a bare UUID string (e.g. "<custom_fields.team>": "079e72e1-..."). The object form {"id": "<uuid>"} and the name form (e.g. "Backend Team") are both rejected by Jira's Teams picker.
Parse tasks.md by phase: Walk the file top-to-bottom and split it into phases, where a phase starts at a ## Phase <N>: <title> header and ends at the next ## Phase header (or end of file). For each phase capture:
phase_number (<N>) and phase_title (<title>) from the header linegoal_block: the **Goal**: paragraph immediately under the header, if presentindependent_test_block: the **Independent Test**: paragraph, if presenttasks: every unchecked - [ ] T<NNN> … line inside the phase, preserved verbatim including its [P] and [US<N>] tags and trailing file paths. Skip tasks already checked (- [x]).story: if the phase header matches User Story <n> or every child task carries the same [US<n>] tag, capture <n> as the phase's user-story number; otherwise leave unset.files: the union of affected file paths across the phase's task lines (trailing the summary or on subsequent indented lines), deduplicated and sorted.exit_criteria: any trailing **Exit criteria** / **Checkpoint** paragraph in the phase, if present.Skip phases that contain zero unchecked tasks. Build an ordered list phases: [{phase_number, phase_title, story, goal_block, independent_test_block, tasks, files, exit_criteria}].
Create one Jira issue per phase: For each parsed phase, call mcp__claude_ai_Atlassian__createJiraIssue with:
cloudId from step 3.
projectKey from default_project_key.
issueTypeName from default_issue_type.
summary = phase_title from step 7, with spec-kit-internal taxonomy tags stripped:
US<N> tags — already captured as a US<N> label below.P<N> tags — already captured by the Blocks links in step 9.[…] decorations carrying the same data ([P], [US<N>]).Keep meaningful tier markers (MVP, Beta, Alpha, etc.) and the descriptive feature text. Drop surrounding parentheses if their only remaining content is itself dropped (e.g. (P1 MVP) → MVP, but (Beta) stays as (Beta)).
Examples:
Phase 3: US1 (P1 MVP) — Auto-create groups → "MVP — Auto-create groups"Phase 1: US2 — Bulk import → "Bulk import"Phase 2: (Beta) Pagination on lists → "(Beta) Pagination on lists"description composed in this order:
goal_block (if any).independent_test_block (if any).## Tasks section containing the phase's task lines as a markdown checklist — each entry is the verbatim - [ ] T<NNN> … line.## Files section listing each affected path from files as a bullet.## Exit criteria section reproducing exit_criteria (if any)._Source:_ <relative path from repo root to tasks.md>.additional_fields:
assignee: { accountId: <resolved accountId> }labels: labels_default (from dev/jira.yml) + US<story> if the phase has a story valuecustom_fields:
<custom_fields.epic_link>: <Epic key from step 4> (e.g. customfield_10014: "IFC-2521")<custom_fields.team>: the bare UUID string resolved in step 6 (e.g. customfield_10001: "079e72e1-..."). Never send the object form {"id": "<uuid>"} and never send team.name.Record phase_number -> issueKey in an in-memory map.
[!CAUTION] UNDER NO CIRCUMSTANCES CREATE ISSUES IN A PROJECT OTHER THAN
default_project_keyFROMdev/jira.yml.
[!CAUTION] If any
createJiraIssuecall fails mid-run, stop immediately. Print the partialphase_number -> issueKeymap and instruct:> Partial run — delete the issues listed above manually in Jira before re-running. This skill is not idempotent in v1.Do not retry, do not roll back automatically.
Create phase-level dependency links: After every phase issue exists, derive the phase dependency graph from T<NNN> mentions inside each phase's task bodies:
tid -> phase_number index from the parse in step 7 — every T<NNN> owned by a phase maps to that phase's phase_number.P, scan its task bodies for T<NNN> mentions whose owning phase is not P itself. For each such mention, emit a directed edge (phase_of_mentioned_tid) -> P (the phase that owns the cited task blocks P).A -> B, B -> C, and A -> C, drop A -> C.(blocker_phase) -> (blocked_phase), call mcp__claude_ai_Atlassian__createIssueLink with:
type = "Blocks"inwardIssue = the blocker phase's Jira key (from the phase_number -> issueKey map)outwardIssue = the blocked phase's Jira keyPhase headers and [P] markers remain sequencing hints only — they are not first-class dependencies and must not produce link edges. The link source is exclusively T<NNN> mentions.
Summary output: Print a markdown table mapping Phase → IssueKey → Summary. Do not edit tasks.md automatically; the user can paste the mapping back if they want.
Check for extension hooks (after tasks-to-issues conversion):
Check if .specify/extensions.yml exists in the project root.
hooks.after_taskstoissues keyenabled is explicitly false. Treat hooks without an enabled field as enabled by default.condition expressions:
condition field, or it is null/empty, treat the hook as executablecondition, skip the hook and leave condition evaluation to the HookExecutor implementation.) with hyphens (-). For example, speckit.git.commit → /speckit-git-commit.optional flag:
optional: true):
## Extension Hooks
**Optional Hook**: {extension}
Command: `/{command}`
Description: {description}
Prompt: {prompt}
To execute: `/{command}`
optional: false):
## Extension Hooks
**Automatic Hook**: {extension}
Executing: `/{command}`
EXECUTE_COMMAND: {command}
.specify/extensions.yml does not exist, skip silently