# Tasks To Issues Command

> Run the `speckit-helper:tasks-to-issues` workflow from the original Claude slash command. Use when the user asks to convert tasks from tasks.md into GitHub Issues with labels and dependencies

- Skill: `datamaker-kr/tasks-to-issues-command` (Agent Skill)
- Install (CLI): `npx skillmds@latest add datamaker-kr/tasks-to-issues-command`
- Raw SKILL.md: https://api.skillmd.com/api/skills/datamaker-kr/tasks-to-issues-command/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: datamaker-kr (https://skillmd.com/u/datamaker-kr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/datamaker-kr/tasks-to-issues-command

---


<!-- Generated by tools/generate-agent-marketplaces.py; edit the source command or agent-plugin.yaml instead. -->

# speckit-helper:tasks-to-issues Command Workflow

## Codex Adaptation

- Treat the user request or explicitly supplied text as the command arguments.
- Use the available Codex file, search, terminal, and clarification capabilities that match the workflow.
- Do not depend on Claude-only slash command variables or tool names.

# /speckit-helper:tasks-to-issues

Convert uncompleted tasks from `tasks.md` into GitHub Issues with labels, milestones,
and dependency references. Supports a dry-run mode to preview before creating.

---

## Overview

This command bridges the speckit workflow with GitHub's issue tracking system. It reads
the task list, parses each uncompleted task's metadata (phase, complexity, user story,
spec reference), and creates a corresponding GitHub Issue with structured labels and
a milestone matching the feature slug. The `--dry-run` flag lets you preview everything
that would be created without actually touching GitHub.

---

## Workflow

### Step 1: Verify GitHub Remote

Before doing any work, confirm that the repository has a GitHub remote and that the
`gh` CLI is authenticated:

```bash
gh repo view --json nameWithOwner
```

- **If the command succeeds:** Extract `nameWithOwner` (e.g., `org/repo-name`) for use
  in subsequent API calls.
- **If the command fails:** Stop immediately with:
  > "This command requires a GitHub remote and an authenticated `gh` CLI.
  > Please ensure:
  > 1. This repository is pushed to GitHub.
  > 2. The `gh` CLI is installed and authenticated (`gh auth status`).
  > Then run this command again."

### Step 2: Resolve Feature Slug and Parse Flags

Extract the feature-slug and optional `--dry-run` flag from `the user request or explicit arguments`.

- The first positional argument is the feature-slug.
- If `--dry-run` is present anywhere in `the user request or explicit arguments`, enable dry-run mode.
- If `the user request or explicit arguments` is empty, use Glob to list directories under `.speckit/`:
  - If exactly one feature directory exists, use it automatically.
  - If multiple exist, list them and ask the user to choose.
  - If none exist, stop: "No specifications found. Run `/speckit-helper:specify` first."

### Step 3: Read Task List

Read `.speckit/<feature-slug>/tasks.md`.

- If the file does not exist, stop:
  > "Cannot create issues: tasks.md not found at `.speckit/<feature-slug>/tasks.md`.
  > Run `/speckit-helper:tasks <feature-slug>` to generate a task list first."

Also read `.speckit/<feature-slug>/spec.md` for acceptance criteria enrichment.

- If spec.md does not exist, continue but note that issue bodies will have limited
  context (no acceptance criteria).

### Step 4: Parse Uncompleted Tasks

Scan `tasks.md` for uncompleted task lines matching the pattern:
```
- [ ] T{ID} [flags] [US{N}] path/to/file — Description (complexity) [Spec §X.Y]
```

For each uncompleted task, extract:

| Field | Source | Example |
|-------|--------|---------|
| Task ID | `T{NNN}` | `T001` |
| User Story | `[US{N}]` | `[US1]` |
| File Path | path before em dash | `src/models/user.ts` |
| Description | text after em dash | `Create User model with password hash field` |
| Complexity | `(S)`, `(M)`, or `(L)` | `(M)` |
| Spec Reference | `[Spec §X.Y]` | `[Spec §3.1]` |
| Phase | Parent section header | `Phase 2: Foundation` |
| Parallelizable | Presence of `[P]` flag | `true` / `false` |

Skip tasks that are already completed (`- [X]`). Also skip tasks that already have a
GitHub issue number appended (e.g., `T001 (#42)`).

If no uncompleted tasks are found:
> "All tasks in tasks.md are already completed or have associated issues. Nothing to create."

### Step 5: Prepare Issue Metadata

For each uncompleted task, prepare the GitHub Issue content:

#### Title

Format: `T{ID} — {Description}`

Example: `T003 — Create User model with password hash field`

#### Body

Build a structured issue body with context from spec.md:

```markdown
## Task Details

- **Task ID:** T{ID}
- **Feature:** {feature-slug}
- **File:** `{file-path}`
- **Complexity:** {S|M|L}
- **User Story:** US{N}
- **Spec Reference:** §{X.Y}
- **Phase:** {phase-name}
- **Parallelizable:** {Yes|No}

## Spec Context

{Relevant content from spec.md section §X.Y, including the requirement text
and acceptance criteria. If spec.md was not found, print:
"Spec context unavailable — spec.md not found."}

## Acceptance Criteria

{If the spec section includes acceptance criteria in Given/When/Then format,
reproduce them here. Otherwise, derive basic criteria from the task description.}

---
*Generated by `/speckit-helper:tasks-to-issues`*
```

#### Labels

Assign labels based on task metadata. Each label should be created if it does not
already exist.

| Label | Source | Example |
|-------|--------|---------|
| `phase:{name}` | Phase section header (lowercased, simplified) | `phase:setup`, `phase:foundation`, `phase:stories`, `phase:finalization` |
| `size:{S\|M\|L}` | Complexity marker | `size:S`, `size:M`, `size:L` |
| `story:US{N}` | User story reference | `story:US1`, `story:US2` |
| `speckit` | Always applied | `speckit` |

#### Milestone

All issues for a feature share a single milestone named after the feature-slug.

### Step 6: Dry-Run Mode

If `--dry-run` is enabled, print a preview of everything that would be created without
making any API calls:

```
--- Dry Run: GitHub Issues Preview ---

Feature:   <feature-slug>
Milestone: <feature-slug> (would be created)
Tasks:     <N> uncompleted tasks to convert

| # | Task ID | Title                                          | Labels                              |
|---|---------|------------------------------------------------|-------------------------------------|
| 1 | T003    | T003 — Create User model with password hash    | phase:foundation, size:M, story:US1 |
| 2 | T004    | T004 — Create Session model with expiry         | phase:foundation, size:S, story:US1 |
| 3 | T005    | T005 — Implement registration with validation   | phase:stories, size:M, story:US1    |
...

Would create:
  - 1 milestone: "<feature-slug>"
  - N GitHub issues with labels
  - Labels to create (if not existing): phase:setup, phase:foundation, size:S, size:M, story:US1, speckit

No changes were made. Remove --dry-run to create issues.
```

**IMPORTANT:** In dry-run mode, absolutely NO GitHub API calls that create or modify
resources should be made. Only read operations (like `gh repo view`) are permitted.

### Step 7: Create Issues (Live Mode)

If `--dry-run` is NOT enabled, proceed with creating resources on GitHub:

#### 7a: Ensure Labels Exist

For each unique label that will be used, check if it exists and create it if not:

```bash
gh label create "phase:setup" --description "Setup phase task" --color "0E8A16" 2>/dev/null || true
gh label create "size:S" --description "Small complexity task" --color "C2E0C6" 2>/dev/null || true
gh label create "size:M" --description "Medium complexity task" --color "FEF2C0" 2>/dev/null || true
gh label create "size:L" --description "Large complexity task" --color "F9D0C4" 2>/dev/null || true
gh label create "speckit" --description "Generated from speckit task list" --color "1D76DB" 2>/dev/null || true
```

Use `2>/dev/null || true` to silently handle the case where the label already exists.

#### 7b: Create Milestone

Create the milestone for the feature if it does not already exist:

```bash
gh api repos/{owner}/{repo}/milestones -f title="<feature-slug>" -f description="Tasks for feature: <feature-slug>" 2>/dev/null || true
```

Then retrieve the milestone number for use in issue creation:

```bash
gh api repos/{owner}/{repo}/milestones --jq '.[] | select(.title=="<feature-slug>") | .number'
```

#### 7c: Create Issues in Dependency Order

Create issues for tasks in the order they appear in `tasks.md` (earlier tasks first,
respecting dependency ordering):

```bash
gh issue create \
  --title "T{ID} — {Description}" \
  --body "{issue-body}" \
  --label "phase:{phase},size:{complexity},story:US{N},speckit" \
  --milestone "<feature-slug>"
```

Capture the issue number from the output of each `gh issue create` command.

#### 7d: Update tasks.md

After each issue is created successfully, update the corresponding task line in
`tasks.md` to append the issue number:

Before:
```
- [ ] T003 [US1] src/models/user.ts — Create User model with password hash field (M) [Spec §3.1]
```

After:
```
- [ ] T003 (#42) [US1] src/models/user.ts — Create User model with password hash field (M) [Spec §3.1]
```

Insert `(#NN)` immediately after the task ID. This prevents duplicate issue creation
on subsequent runs.

### Step 8: Print Summary

After all issues are created (or previewed), print the final summary:

```
--- GitHub Issues Created ---

Feature:    <feature-slug>
Milestone:  <feature-slug> (<milestone-url>)

Created: N issues
  T003 (#42) — Create User model with password hash field
  T004 (#43) — Create Session model with expiry
  T005 (#44) — Implement registration with email validation
  ...

Labels applied: phase:setup, phase:foundation, size:S, size:M, story:US1, speckit

tasks.md updated with issue numbers.
```

---

## Error Handling

### gh CLI Not Installed

If `gh` is not found in PATH:
- Print: "The `gh` CLI is required but not installed. Install it from https://cli.github.com/"
- Abort.

### gh CLI Not Authenticated

If `gh auth status` indicates no active authentication:
- Print: "The `gh` CLI is not authenticated. Run `gh auth login` first."
- Abort.

### No GitHub Remote

If `gh repo view` fails:
- Print the error from Step 1 and abort.

### Partial Failure During Issue Creation

If some issues are created but one fails:
- Print the error for the failed issue.
- Continue creating remaining issues.
- In the summary, list which issues were created and which failed.
- The tasks.md will only be updated for successfully created issues.

### Rate Limiting

If GitHub API returns a rate limit error (HTTP 429):
- Print: "GitHub API rate limit reached. Wait and retry, or use `--dry-run` to preview."
- Stop creating issues but do NOT roll back already-created issues.
- Print a partial summary of what was created.

### tasks.md Already Has All Issues

If all uncompleted tasks already have `(#NN)` issue numbers:
- Print: "All uncompleted tasks already have associated GitHub issues. Nothing to create."
- This is not an error; it is the expected state after a previous run.

---

## Notes

- Issues are created in task-list order (top to bottom in tasks.md). This respects the
  dependency ordering established by `/speckit-helper:tasks`.
- The `--dry-run` flag is safe to run repeatedly. Use it to preview before committing
  to issue creation.
- Re-running without `--dry-run` is also safe: tasks that already have `(#NN)` are
  skipped automatically.
- Labels are created with semantic colors: green for phases, yellow/orange for complexity,
  blue for the speckit marker.
- The milestone groups all issues for a feature, making it easy to track overall progress
  in GitHub's milestone view.
- If you need to re-create issues (e.g., after deleting them), manually remove the
  `(#NN)` markers from tasks.md first.

