Skip to content
Back to skills

Github Tracking

ASecurity

Composable GitHub issue/milestone tracking operations. Called by other skills — not invoked directly by the user.

  • 2 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 19, 2026
ai-agentsshellbashcode-reviewgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 19, 2026

npx -y skills add rterakedis/leanwheel-skills --skill github-tracking --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Github Tracking?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Github Tracking
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rterakedis-github-tracking/badge)](https://www.skillsdirectory.com/skills/rterakedis-github-tracking)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: github-tracking
description: Composable GitHub issue/milestone tracking operations. Called by other skills — not invoked directly by the user.
---

# GitHub Tracking (Composable)

Reference library of tracking operations called by other skills at marked points.

Directly invocable: `/github-tracking setup` (one-time) | `/github-tracking backfill` (retroactive) | `/github-tracking sync` (reconcile labels/state).

**Deterministic ops live in `scripts/gh-track.sh`.** The label mechanics — moving an issue between mutually-exclusive status labels (and *stripping the stale one*), closing, and reconciling — are byte-identical every run and must not be reconstructed in-model (that's where label drift like "two status labels on one issue" comes from). This skill is the **policy layer**: it decides *when* to transition and owns the interactive SETUP/BACKFILL/SYNC confirmation gates; the *how* is one shell call. If `scripts/gh-track.sh` is absent (older project not yet upgraded), fall back to the raw `gh` commands documented per-op below.

## Prerequisites Check

Before composable ops (ENSURE-MILESTONE, CREATE-ISSUE, TRANSITION, CLOSE-ISSUE):
- `gh auth status` + `gh repo view --json nameWithOwner`
- Both pass: proceed. Either fails in composable call: skip silently, warn once.
- Either fails in SETUP/BACKFILL: handle auth inline.

---

## SETUP (one-time)

1. Check auth: `gh auth status`. If no, run `gh auth login` (interactive).
2. Verify auth succeeded: `gh auth status`.
3. Verify repo: `gh repo view --json nameWithOwner`. Fail if no remote.
4. Create labels: `backlog`, `ready-for-dev`, `in-progress`, `review`, `done` with `--force`.
5. Report: auth user, repo. Next: `/backfill` or `/create-story`.

---

## BACKFILL (retroactive)

Retroactively create milestones/issues for stories with `github_issue: 0` (safe to re-run).

1. Verify auth (gh auth status, repo view).
2. Scan docs/epics/: `grep -rl "^github_issue: 0"` + files with no `github_issue:` line.
3. Preview list + confirm: "Create milestones + issues + write numbers back?"
4. For each story: read epic/story/title/Status, add `github_issue: 0` if missing, ENSURE-MILESTONE, label by Status, CREATE-ISSUE, CLOSE-ISSUE if done. Report per-story.
5. Summary: {N} issues, {M} milestones, {K} closed. Next: `/status`.

---

## SYNC (reconcile labels and state)

Reconcile GitHub issue labels and open/closed state against the current `status:` field in every story file. Safe to re-run — idempotent.

### Status → label/state mapping

| story `status:` | Expected GitHub label | Issue state |
|---|---|---|
| `draft` / `ready` | `ready-for-dev` | open |
| `in-progress` | `in-progress` | open |
| `review` | `review` | open |
| `done` / `complete` | `done` | closed |
| `cancelled` | `done` | closed |

### Steps

**Preferred (script does the deterministic reconcile):**
1. Verify auth (`gh auth status`, `gh repo view --json nameWithOwner`). Fail fast if either fails.
2. Dry-run diff: `bash scripts/gh-track.sh sync "<story-glob>"` (e.g. `docs/epics/*.md` or `docs/stories/*.md` — whichever holds the story files, with non-zero `github_issue:` frontmatter). It prints a table (story | issue# | current | expected | action) and a summary; it changes nothing.
3. If the summary shows `0 to-change`: report "All issues in sync." and stop.
4. Confirm with the user: "Apply {N} changes?"
5. On yes: `bash scripts/gh-track.sh sync "<story-glob>" --apply`. The script transitions labels (stripping stale ones), closes done stories, and reopens any wrongly-closed ones. Relay its summary.

**Fallback (no script):** do it inline — for each story file with a non-zero `github_issue:`, read `status:`, map via the table above, `gh issue view {N} --json state,labels`, and if it differs apply TRANSITION (+ close/reopen). Confirm before applying.

> **Legacy format tolerance:** `gh-track.sh sync` reads `status:`/`github_issue:` from YAML frontmatter but falls back to the older `**Status:**` / `**GitHub Issue:** #N` body lines (normalizing `✅ Done` → `done`), so it reconciles pre-frontmatter story files too. New stories use the pinned frontmatter format (`create-story/template.md`); the fallback exists only to recover historical files.

---

## ENSURE-MILESTONE

Find or create milestone for epic. Input: `epic_num`, `epic_title` from epics.md.
- Check if exists: `gh api repos/.../milestones --jq "... select(.title | startswith(...))"`
- If exists: use title. If not: create with POST, description from epics.md.
- Return: milestone_title.

---

## CREATE-ISSUE

Create issue for story. Input: `story_file` (optional), `epic_num`, `story_num`, `story_title`, `milestone_title`, AC summary, `initial_label` (default: `ready-for-dev`).
- Build body from story (statement + ACs + repo path).
- `gh issue create --title "Story {epic}.{num}: {title}" --body --milestone --label "{initial_label}"`
- Extract issue number from URL.
- If `story_file` provided: write back `sed -i '' "s/^github_issue: 0$/github_issue: {N}/" "{file}"`
- If no `story_file` (source is epics.md): skip write-back; issue number will be recorded when `/create-story` generates the story file.
- Report: "Created #N → URL"

---

## TRANSITION

Move issue to a new status label. Input: `story_file` (or issue number directly), `new_label` (ready-for-dev/in-progress/review/done).
- Resolve issue number: from the caller, or `grep "^github_issue:" {story_file} | awk`. If `0`/empty: skip + warn.
- **Preferred:** `bash scripts/gh-track.sh transition {N} {new_label}` — adds the label, **strips every other status label**, and verifies. Prints `#N → {new_label} ✓`.
- **Fallback (no script):** `gh issue edit {N} --add-label {new} --remove-label {each other status label currently present}`. Always remove *all* stale status labels (`backlog ready-for-dev in-progress review done` minus the target), not just one — that prevents the double-label drift.

## CLOSE-ISSUE

Close issue when done. Input: `story_file` (or issue number).
- Resolve issue number (same as TRANSITION).
- **Preferred:** `bash scripts/gh-track.sh close {N} "Story complete..."` — applies `done` then closes (idempotent; closed issues retain `done` for milestone progress).
- **Fallback (no script):** run TRANSITION to `done`, then `gh issue close {N} --comment "Story complete..."`.

---

## Status Label Flow

```
epics.md written → [backlog]
                      ↓ create-story completes
                   [ready-for-dev]
                      ↓ dev-story starts
                   [in-progress]
                      ↓ dev-story DoD passes
                   [review]
                      ↓ code-review passes
                   [done] + issue closed
```

Milestone progress in GitHub UI automatically shows X/Y closed issues.

Attribution

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

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.