Loading...
Loading...
Review open issues, selecting an issue to work on, filtering issues by area, pulling GitHub issues, or deciding what to work on next. Triggers include "check issues", "list issues", "what issues", "open issues", "show issues", "view issues", "select issue to work on", "github issues", "backlog issues", "pull issues", "check todos" (deprecated), "list todos" (deprecated), "pending todos" (deprecated).
npx skill4agent add gannonh/kata-skills kata-check-issuesNote: "todos" is now "issues". Using./kata-check-issues
if [ -d ".planning/todos/pending" ] && [ ! -d ".planning/todos/_archived" ]; then
# Create new structure
mkdir -p .planning/issues/open .planning/issues/in-progress .planning/issues/closed
# Copy pending todos to open issues
cp .planning/todos/pending/*.md .planning/issues/open/ 2>/dev/null || true
# Copy done todos to closed issues
cp .planning/todos/done/*.md .planning/issues/closed/ 2>/dev/null || true
# Archive originals
mkdir -p .planning/todos/_archived
mv .planning/todos/pending .planning/todos/_archived/ 2>/dev/null || true
mv .planning/todos/done .planning/todos/_archived/ 2>/dev/null || true
echo "Migrated todos to issues format"
fi
# Ensure in-progress directory exists
mkdir -p .planning/issues/in-progress_archived/No open or in-progress issues.
Issues are captured during work sessions with /kata-add-issue.
---
Would you like to:
1. Continue with current phase (/kata-track-progress)
2. Add an issue now (/kata-add-issue)# Get all GitHub issue numbers already tracked locally (from open and in-progress)
LOCAL_PROVENANCE=$(grep -h "^provenance: github:" .planning/issues/open/*.md .planning/issues/in-progress/*.md 2>/dev/null | grep -oE '#[0-9]+' | tr -d '#' | sort -u)if [ "$GITHUB_ENABLED" = "true" ]; then
# Get GitHub Issues with backlog label, excluding those already tracked locally
# Note: --label flag has issues in some gh CLI versions, use jq filter instead
GITHUB_ISSUES=$(gh issue list --state open --json number,title,createdAt,labels --jq '.[] | select(.labels[].name == "backlog") | "\(.createdAt)|\(.title)|github|\(.number)"' 2>/dev/null)
fifor file in .planning/issues/in-progress/*.md; do
[ -f "$file" ] || continue
created=$(grep "^created:" "$file" | cut -d' ' -f2)
title=$(grep "^title:" "$file" | cut -d':' -f2- | xargs)
area=$(grep "^area:" "$file" | cut -d' ' -f2)
echo "$created|$title|$area|$file|in-progress"
done | sortfor file in .planning/issues/open/*.md; do
[ -f "$file" ] || continue
created=$(grep "^created:" "$file" | cut -d' ' -f2)
title=$(grep "^title:" "$file" | cut -d':' -f2- | xargs)
area=$(grep "^area:" "$file" | cut -d' ' -f2)
echo "$created|$title|$area|$file|open"
done | sort[IN PROGRESS][GH]1. [IN PROGRESS] Fix auth bug (api, 2d ago)2. Add feature [GH] (bug, 3d ago)Issues:
--- In Progress ---
1. [IN PROGRESS] Fix auth token refresh (api, 2d ago)
--- Open (Backlog) ---
2. Add modal z-index fix (ui, 1d ago)
3. Fix login bug [GH] (bug, 3d ago)
4. Refactor database connection pool (database, 5h ago)
---
Reply with a number to view details, or:
- `/kata-check-issues [area]` to filter by area
- `q` to exit[GH]q## [title]
**Area:** [area]
**Created:** [date] ([relative time] ago)
**Files:** [list or "None"]
### Problem
[problem section content]
### Solution
[solution section content]filesgh issue view $ISSUE_NUMBER --json title,body,createdAt,labels## [title] [GH]
**Source:** GitHub Issue #[number]
**Created:** [date] ([relative time] ago)
**Labels:** [list of GitHub labels]
### Description
[issue body content]The `provenance` field enables deduplication on subsequent checks.
Confirm: "Pulled GitHub Issue #[number] to local: .planning/issues/open/[filename]"
Return to list or offer to work on it.
**Work on it now (open local issue):**
**Based on mode selection from offer_actions step:**
**If "Quick task" mode selected:**
1. Move from open to in-progress:
```bash
mv ".planning/issues/open/[filename]" ".planning/issues/in-progress/"
ISSUE_FILE=".planning/issues/in-progress/[filename]"
# Add in-progress label to GitHub Issue if linked
PROVENANCE=$(grep "^provenance:" "$ISSUE_FILE" | cut -d' ' -f2)
if echo "$PROVENANCE" | grep -q "^github:"; then
ISSUE_NUMBER=$(echo "$PROVENANCE" | grep -oE '#[0-9]+' | tr -d '#')
if [ -n "$ISSUE_NUMBER" ]; then
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
if [ "$GITHUB_ENABLED" = "true" ]; then
gh label create "in-progress" --description "Issue is actively being worked on" --color "FFA500" 2>/dev/null || true
gh issue edit "$ISSUE_NUMBER" --add-label "in-progress" 2>/dev/null || true
gh issue edit "$ISSUE_NUMBER" --add-assignee @me 2>/dev/null || true
fi
fi
fiStarting quick task execution for issue: [title]/kata-execute-quick-task --issue "$ISSUE_FILE"ISSUE_TITLE=$(grep "^title:" "$ISSUE_FILE" | cut -d':' -f2- | xargs)
PROVENANCE=$(grep "^provenance:" "$ISSUE_FILE" | cut -d' ' -f2)
ISSUE_NUMBER=""
if echo "$PROVENANCE" | grep -q "^github:"; then
ISSUE_NUMBER=$(echo "$PROVENANCE" | grep -oE '#[0-9]+' | tr -d '#')
fiCreating phase from issue: ${ISSUE_TITLE}
${ISSUE_NUMBER:+GitHub Issue: #${ISSUE_NUMBER}}
The new phase will be linked to this issue.
When the phase PR merges, the issue will close automatically.
---
## ▶ Next Up
**Create Phase:** ${ISSUE_TITLE}
`/kata-add-phase --issue ${ISSUE_FILE}`
<sub>`/clear` first → fresh context window</sub>
---
Note: Issue remains in open/ until phase work begins.
When phase planning starts, move issue to in-progress manually
or use /kata-check-issues to update status.# Get phase directories that are not yet complete (no SUMMARY.md for all plans)
# This is a heuristic - phases with incomplete plans
UPCOMING_PHASES=""
# Scan all phase directories across states
ALL_PHASE_DIRS=""
for state in active pending completed; do
[ -d ".planning/phases/${state}" ] && ALL_PHASE_DIRS="${ALL_PHASE_DIRS} $(find .planning/phases/${state} -maxdepth 1 -type d -not -name "${state}" 2>/dev/null)"
done
# Fallback: include flat directories (backward compatibility)
FLAT_DIRS=$(find .planning/phases -maxdepth 1 -type d -name "[0-9]*" 2>/dev/null)
[ -n "$FLAT_DIRS" ] && ALL_PHASE_DIRS="${ALL_PHASE_DIRS} ${FLAT_DIRS}"
for phase_dir in $ALL_PHASE_DIRS; do
[ -d "$phase_dir" ] || continue
phase_name=$(basename "$phase_dir")
# Check if phase has at least one PLAN.md but missing at least one SUMMARY.md
plan_count=$(find "$phase_dir" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null | wc -l)
summary_count=$(find "$phase_dir" -maxdepth 1 -name "*-SUMMARY.md" 2>/dev/null | wc -l)
if [ "$plan_count" -gt 0 ] && [ "$plan_count" -gt "$summary_count" ]; then
# Extract phase goal from roadmap
phase_num=$(echo "$phase_name" | grep -oE '^[0-9]+')
phase_goal=$(grep -A2 "### Phase ${phase_num}:" .planning/ROADMAP.md | grep "Goal:" | cut -d':' -f2- | xargs)
UPCOMING_PHASES="${UPCOMING_PHASES}\n- ${phase_name}: ${phase_goal}"
fi
doneUpcoming phases that could include this issue:
${UPCOMING_PHASES}
To link this issue to a phase:
1. Note the issue reference when planning that phase
2. Include issue context in the phase PLAN.md
3. The issue PR will close the issue when merged
Which phase? (Enter phase name or "none" to go back)EXISTING_LINKAGE=$(grep "^linked_phase:" "$ISSUE_FILE" 2>/dev/null | cut -d' ' -f2)This issue is already linked to phase: ${EXISTING_LINKAGE}
Options:
- Override — Link to ${SELECTED_PHASE} instead
- Cancel — Keep existing linkageISSUE_FILE="[path to issue file]"
PHASE_NAME="[selected phase name, e.g., '03-issue-roadmap-integration']"
# Add linked_phase to issue frontmatter (after the opening ---)
# Use awk to insert after first ---
awk -v phase="$PHASE_NAME" '
/^---$/ && !found {
print
print "linked_phase: " phase
found=1
next
}
{ print }
' "$ISSUE_FILE" > "$ISSUE_FILE.tmp" && mv "$ISSUE_FILE.tmp" "$ISSUE_FILE"STATE_FILE=".planning/STATE.md"
# Extract issue details for STATE.md entry
ISSUE_TITLE=$(grep "^title:" "$ISSUE_FILE" | cut -d':' -f2- | xargs)
PROVENANCE=$(grep "^provenance:" "$ISSUE_FILE" | cut -d' ' -f2)
GITHUB_REF=""
if echo "$PROVENANCE" | grep -q "^github:"; then
GITHUB_REF="GitHub: $(echo "$PROVENANCE" | grep -oE '#[0-9]+')"
fi
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Check if "### Pending Issues" section exists
if ! grep -q "^### Pending Issues" "$STATE_FILE"; then
# Append section before "## Session Continuity" if exists, otherwise at end
if grep -q "^## Session Continuity" "$STATE_FILE"; then
sed -i '' '/^## Session Continuity/i\
### Pending Issues\
\
Issues linked to phases for planned work:\
\
' "$STATE_FILE"
else
echo -e "\n### Pending Issues\n\nIssues linked to phases for planned work:\n" >> "$STATE_FILE"
fi
fi
# Add linkage entry (format enables phase planning to find linked issues)
LINKAGE_ENTRY="- ${ISSUE_TITLE} → Phase ${PHASE_NAME}\n - File: ${ISSUE_FILE}\n ${GITHUB_REF:+- ${GITHUB_REF}}\n - Linked: ${TIMESTAMP}"
# Insert after "### Pending Issues" header and description
awk -v entry="$LINKAGE_ENTRY" '
/^### Pending Issues/ { pending=1 }
pending && /^$/ && !inserted {
print
print entry
inserted=1
next
}
{ print }
' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"Issue linked to phase: ${PHASE_NAME}
${ISSUE_TITLE}
File: ${ISSUE_FILE}
${GITHUB_REF:+GitHub: ${GITHUB_REF}}
The issue will be included when planning this phase.
Issue remains in open/ until phase work begins.No upcoming phases found.
Options:
- /kata-add-phase --issue ${ISSUE_FILE} — Create a new phase
- /kata-track-progress — View current roadmap status
- Put it back — Return to issue listmv ".planning/issues/open/[filename]" ".planning/issues/in-progress/"
# Add in-progress label to GitHub Issue if linked
PROVENANCE=$(grep "^provenance:" ".planning/issues/in-progress/[filename]" | cut -d' ' -f2)
if echo "$PROVENANCE" | grep -q "^github:"; then
ISSUE_NUMBER=$(echo "$PROVENANCE" | grep -oE '#[0-9]+' | tr -d '#')
if [ -n "$ISSUE_NUMBER" ]; then
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
if [ "$GITHUB_ENABLED" = "true" ]; then
# Create in-progress label idempotently (ignore error if exists)
gh label create "in-progress" --description "Issue is actively being worked on" --color "FFA500" 2>/dev/null || true
# Add in-progress label (keeps backlog label)
gh issue edit "$ISSUE_NUMBER" --add-label "in-progress" 2>/dev/null \
&& echo "Added in-progress label to GitHub Issue #${ISSUE_NUMBER}" \
|| echo "Warning: Failed to add in-progress label to GitHub Issue #${ISSUE_NUMBER}"
# Assign issue to self
gh issue edit "$ISSUE_NUMBER" --add-assignee @me 2>/dev/null \
&& echo "Assigned GitHub Issue #${ISSUE_NUMBER} to @me" \
|| echo "Warning: Failed to assign GitHub Issue #${ISSUE_NUMBER}"
fi
fi
fiIssue moved to in-progress: [filename]
[title]
Area: [area]
GitHub: Linked to #[number], added in-progress label, assigned to @me
-or- Not linked (if no provenance)
Ready to begin work.
When complete, use `/kata-check-issues` and select "Mark complete"..planning/issues/open/${date_prefix}-${slug}.mdmv ".planning/issues/open/${date_prefix}-${slug}.md" ".planning/issues/in-progress/"
ISSUE_FILE=".planning/issues/in-progress/${date_prefix}-${slug}.md"
# Add in-progress label to GitHub Issue (we know it's GitHub-linked)
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
if [ "$GITHUB_ENABLED" = "true" ]; then
gh label create "in-progress" --description "Issue is actively being worked on" --color "FFA500" 2>/dev/null || true
gh issue edit "$ISSUE_NUMBER" --add-label "in-progress" 2>/dev/null || true
gh issue edit "$ISSUE_NUMBER" --add-assignee @me 2>/dev/null || true
fiStarting quick task execution for issue: [title]/kata-execute-quick-task --issue "$ISSUE_FILE".planning/issues/open/${date_prefix}-${slug}.mdISSUE_FILE=".planning/issues/open/${date_prefix}-${slug}.md"
ISSUE_TITLE=$(grep "^title:" "$ISSUE_FILE" | cut -d':' -f2- | xargs)
# ISSUE_NUMBER already available from the GitHub-only flowCreating phase from issue: ${ISSUE_TITLE}
GitHub Issue: #${ISSUE_NUMBER}
The new phase will be linked to this issue.
When the phase PR merges, the issue will close automatically.
---
## ▶ Next Up
**Create Phase:** ${ISSUE_TITLE}
`/kata-add-phase --issue ${ISSUE_FILE}`
<sub>`/clear` first → fresh context window</sub>
---
Note: Issue remains in open/ until phase work begins.
When phase planning starts, move issue to in-progress manually
or use /kata-check-issues to update status.UPCOMING_PHASES=""
ALL_PHASE_DIRS=""
for state in active pending completed; do
for d in .planning/phases/${state}/*/; do
[ -d "$d" ] && ALL_PHASE_DIRS="$ALL_PHASE_DIRS $d"
done
done
# Flat directory fallback (unmigrated projects)
for d in .planning/phases/[0-9]*/; do
[ -d "$d" ] && ALL_PHASE_DIRS="$ALL_PHASE_DIRS $d"
done
for phase_dir in $ALL_PHASE_DIRS; do
phase_name=$(basename "$phase_dir")
plan_count=$(find "$phase_dir" -maxdepth 1 -name "*-PLAN.md" 2>/dev/null | wc -l)
summary_count=$(find "$phase_dir" -maxdepth 1 -name "*-SUMMARY.md" 2>/dev/null | wc -l)
if [ "$plan_count" -gt 0 ] && [ "$plan_count" -gt "$summary_count" ]; then
phase_num=$(echo "$phase_name" | grep -oE '^[0-9]+')
phase_goal=$(grep -A2 "### Phase ${phase_num}:" .planning/ROADMAP.md | grep "Goal:" | cut -d':' -f2- | xargs)
UPCOMING_PHASES="${UPCOMING_PHASES}\n- ${phase_name}: ${phase_goal}"
fi
doneUpcoming phases that could include this issue:
${UPCOMING_PHASES}
To link this issue to a phase:
1. Note the issue reference when planning that phase
2. Include issue context in the phase PLAN.md
3. The issue PR will close the issue when merged
Which phase? (Enter phase name or "none" to go back)ISSUE_FILE=".planning/issues/open/${date_prefix}-${slug}.md"
EXISTING_LINKAGE=$(grep "^linked_phase:" "$ISSUE_FILE" 2>/dev/null | cut -d' ' -f2)awk -v phase="$PHASE_NAME" '
/^---$/ && !found {
print
print "linked_phase: " phase
found=1
next
}
{ print }
' "$ISSUE_FILE" > "$ISSUE_FILE.tmp" && mv "$ISSUE_FILE.tmp" "$ISSUE_FILE"STATE_FILE=".planning/STATE.md"
ISSUE_TITLE=$(grep "^title:" "$ISSUE_FILE" | cut -d':' -f2- | xargs)
GITHUB_REF="GitHub: #${ISSUE_NUMBER}"
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# Check if "### Pending Issues" section exists, create if not
if ! grep -q "^### Pending Issues" "$STATE_FILE"; then
if grep -q "^## Session Continuity" "$STATE_FILE"; then
sed -i '' '/^## Session Continuity/i\
### Pending Issues\
\
Issues linked to phases for planned work:\
\
' "$STATE_FILE"
else
echo -e "\n### Pending Issues\n\nIssues linked to phases for planned work:\n" >> "$STATE_FILE"
fi
fi
# Add linkage entry
LINKAGE_ENTRY="- ${ISSUE_TITLE} → Phase ${PHASE_NAME}\n - File: ${ISSUE_FILE}\n - ${GITHUB_REF}\n - Linked: ${TIMESTAMP}"
awk -v entry="$LINKAGE_ENTRY" '
/^### Pending Issues/ { pending=1 }
pending && /^$/ && !inserted {
print
print entry
inserted=1
next
}
{ print }
' "$STATE_FILE" > "$STATE_FILE.tmp" && mv "$STATE_FILE.tmp" "$STATE_FILE"Issue linked to phase: ${PHASE_NAME}
${ISSUE_TITLE}
File: ${ISSUE_FILE}
GitHub: #${ISSUE_NUMBER}
The issue will be included when planning this phase.
Issue remains in open/ until phase work begins.No upcoming phases found.
Options:
- /kata-add-phase --issue ${ISSUE_FILE} — Create a new phase
- /kata-track-progress — View current roadmap status
- Put it back — Return to issue listmv ".planning/issues/open/${date_prefix}-${slug}.md" ".planning/issues/in-progress/"
# Add in-progress label to GitHub Issue (we know it's GitHub-linked since this is the GitHub-only path)
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
if [ "$GITHUB_ENABLED" = "true" ]; then
# Create in-progress label idempotently (ignore error if exists)
gh label create "in-progress" --description "Issue is actively being worked on" --color "FFA500" 2>/dev/null || true
# Add in-progress label (keeps backlog label)
# Note: $ISSUE_NUMBER is already available from the pull-to-local step
gh issue edit "$ISSUE_NUMBER" --add-label "in-progress" 2>/dev/null \
&& echo "Added in-progress label to GitHub Issue #${ISSUE_NUMBER}" \
|| echo "Warning: Failed to add in-progress label to GitHub Issue #${ISSUE_NUMBER}"
# Assign issue to self
gh issue edit "$ISSUE_NUMBER" --add-assignee @me 2>/dev/null \
&& echo "Assigned GitHub Issue #${ISSUE_NUMBER} to @me" \
|| echo "Warning: Failed to assign GitHub Issue #${ISSUE_NUMBER}"
fiIssue moved to in-progress: [filename]
[title]
Area: [area]
GitHub: Linked to #[number], added in-progress label, assigned to @me
Ready to begin work.
When complete, use `/kata-check-issues` and select "Mark complete".mv ".planning/issues/in-progress/[filename]" ".planning/issues/closed/"
# Check if issue has GitHub provenance
PROVENANCE=$(grep "^provenance:" ".planning/issues/closed/[filename]" | cut -d' ' -f2)
if echo "$PROVENANCE" | grep -q "^github:"; then
# Extract issue number from provenance (format: github:owner/repo#N)
ISSUE_NUMBER=$(echo "$PROVENANCE" | grep -oE '#[0-9]+' | tr -d '#')
if [ -n "$ISSUE_NUMBER" ]; then
# Check github.enabled (may have changed since issue was created)
GITHUB_ENABLED=$(cat .planning/config.json 2>/dev/null | grep -o '"enabled"[[:space:]]*:[[:space:]]*[^,}]*' | head -1 | grep -o 'true\|false' || echo "false")
if [ "$GITHUB_ENABLED" = "true" ]; then
# Close GitHub Issue with comment
gh issue close "$ISSUE_NUMBER" --comment "Completed via Kata workflow" 2>/dev/null \
&& echo "Closed GitHub Issue #${ISSUE_NUMBER}" \
|| echo "Warning: Failed to close GitHub Issue #${ISSUE_NUMBER}"
fi
fi
fiIssue completed: [filename]
[title]
Area: [area]
GitHub: Closed #[number] (if provenance exists and close succeeded)
-or- Not linked (if no provenance)
-or- Failed to close #[number] (if close failed)
Issue closed.mv ".planning/issues/in-progress/[filename]" ".planning/issues/open/"gh issue view $ISSUE_NUMBER --web/kata-add-phase --issue [issue file path]OPEN_COUNT=$(find .planning/issues/open -maxdepth 1 -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
IN_PROGRESS_COUNT=$(find .planning/issues/in-progress -maxdepth 1 -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
CLOSED_COUNT=$(find .planning/issues/closed -maxdepth 1 -name "*.md" 2>/dev/null | wc -l | tr -d ' ')
echo "Open: $OPEN_COUNT, In Progress: $IN_PROGRESS_COUNT, Closed: $CLOSED_COUNT"COMMIT_PLANNING_DOCS=$(cat .planning/config.json 2>/dev/null | grep -o '"commit_docs"[[:space:]]*:[[:space:]]*[^,}]*' | grep -o 'true\|false' || echo "true")
git check-ignore -q .planning 2>/dev/null && COMMIT_PLANNING_DOCS=falseCOMMIT_PLANNING_DOCS=falseCOMMIT_PLANNING_DOCS=truegit add .planning/issues/in-progress/[filename]
git rm --cached .planning/issues/open/[filename] 2>/dev/null || true
[ -f .planning/STATE.md ] && git add .planning/STATE.md
git commit -m "$(cat <<EOF
docs: start work on issue - [title]
Moved to in-progress.
EOF
)"git add .planning/issues/closed/[filename]
git rm --cached .planning/issues/in-progress/[filename] 2>/dev/null || true
[ -f .planning/STATE.md ] && git add .planning/STATE.md
# Check if issue had GitHub provenance that was closed
PROVENANCE=$(grep "^provenance:" ".planning/issues/closed/[filename]" | cut -d' ' -f2)
GITHUB_REF=""
if echo "$PROVENANCE" | grep -q "^github:"; then
GITHUB_REF="Closes $(echo "$PROVENANCE" | grep -oE '#[0-9]+')"
fi
git commit -m "$(cat <<EOF
docs: complete issue - [title]
${GITHUB_REF}
EOF
)"git add .planning/issues/open/[filename]
git rm --cached .planning/issues/in-progress/[filename] 2>/dev/null || true
[ -f .planning/STATE.md ] && git add .planning/STATE.md
git commit -m "docs: return issue to backlog - [title]"open/ → Backlog (not started)
in-progress/ → Actively being worked on
closed/ → Completedopen/in-progress//kata-execute-quick-taskopen/in-progress/closed/in-progress/open//kata-add-issuegithub.enabled=trueprovenance: github:owner/repo#N/kata-execute-quick-task --issue