Four modes (parsed from $ARGUMENTS):
objectives (default for empty args) — create/update one issue per roadmap objective, ensure milestone exists
release <tag> — generate release notes from SUMMARY.md files since the previous tag and create or edit the GitHub release
status — report whether GitHub integration is enabled and reachable
sync <objective> (<objective_id>, e.g. 01-github-coordination-layer) — sync ONE objective: rewrite linked issue body to canonical form, upsert sticky state comment in-place, update Project v2 fields (Status, Quarter). Idempotent — safe to run repeatedly.
If $ARGUMENTS does not match objectives, release <tag>, or status, treat it as an objective ID and run the single-objective sync mode.
- Run the requested operation:
# Default — sync all objectives (creates/updates issues + milestone)
node ~/.claude/devflow/bin/df-tools.cjs gh sync-objectives
# Release notes for a tag
node ~/.claude/devflow/bin/df-tools.cjs gh sync-release "$TAG"
# Status check
node ~/.claude/devflow/bin/df-tools.cjs gh status
# Sync a single objective's state to its linked GH issue (idempotent)
node ~/.claude/devflow/bin/df-tools.cjs gh sync "$OBJECTIVE_ID"
The single-objective sync (gh sync <objective_id>) is idempotent — running it twice in a row produces no semantic difference on GitHub. The sticky comment uses marker <!-- df:state --> and is edited in-place (not a new comment). The comment ID is persisted in .planning/.gh-mapping.json so subsequent syncs find the same comment to patch.
- If sync-objectives or the single-objective sync created or updated
.planning/.gh-mapping.json, commit it:
node ~/.claude/devflow/bin/df-tools.cjs commit "chore: sync GitHub mapping" --files .planning/.gh-mapping.json
- Report the result to the user — include issue numbers created/updated, milestone link, release URL, or single-objective sync result (comment action, project fields updated). If the operation was skipped, explain why (disabled, gh not installed, missing github_issue frontmatter, etc.) and how to fix it.
Triggers
Use when the user wants to push DevFlow state to GitHub or recover from a missed sync. Also fires on: "create github issues", "sync state".
1---2name: gh-sync3description: Sync DevFlow planning state to GitHub — create/update objective issues, generate release notes, or push a single objective's state (body + sticky comment + Project v2 fields). Triggers on: "sync to github", "push objectives to github", "github release notes", "sync objective".4---5<objective>6One-way push from `.planning/` -> GitHub. Planning files remain authoritative. All operations are no-ops when GitHub integration is disabled or `gh` is not authenticated.78Four modes (parsed from $ARGUMENTS):9- `objectives` (default for empty args) — create/update one issue per roadmap objective, ensure milestone exists10- `release <tag>` — generate release notes from SUMMARY.md files since the previous tag and create or edit the GitHub release11- `status` — report whether GitHub integration is enabled and reachable12- `sync <objective>` (`<objective_id>`, e.g. `01-github-coordination-layer`) — sync ONE objective: rewrite linked issue body to canonical form, upsert sticky state comment in-place, update Project v2 fields (Status, Quarter). Idempotent — safe to run repeatedly.1314If $ARGUMENTS does not match `objectives`, `release <tag>`, or `status`, treat it as an objective ID and run the single-objective sync mode.15</objective>1617<execution_context>18@~/.claude/.planning/config.json19</execution_context>2021<process>221. Check `.planning/config.json` for `github.enabled` and `github.repo`. If missing or false, ask the user whether to enable now (offer to set both interactively). Do not proceed without explicit confirmation.23242. Run the requested operation:2526```bash27# Default — sync all objectives (creates/updates issues + milestone)28node ~/.claude/devflow/bin/df-tools.cjs gh sync-objectives2930# Release notes for a tag31node ~/.claude/devflow/bin/df-tools.cjs gh sync-release "$TAG"3233# Status check34node ~/.claude/devflow/bin/df-tools.cjs gh status3536# Sync a single objective's state to its linked GH issue (idempotent)37node ~/.claude/devflow/bin/df-tools.cjs gh sync "$OBJECTIVE_ID"38```3940The single-objective sync (`gh sync <objective_id>`) is idempotent — running it twice in a row produces no semantic difference on GitHub. The sticky comment uses marker `<!-- df:state -->` and is edited in-place (not a new comment). The comment ID is persisted in `.planning/.gh-mapping.json` so subsequent syncs find the same comment to patch.41423. If sync-objectives or the single-objective sync created or updated `.planning/.gh-mapping.json`, commit it:4344```bash45node ~/.claude/devflow/bin/df-tools.cjs commit "chore: sync GitHub mapping" --files .planning/.gh-mapping.json46```47484. Report the result to the user — include issue numbers created/updated, milestone link, release URL, or single-objective sync result (comment action, project fields updated). If the operation was skipped, explain why (disabled, gh not installed, missing github_issue frontmatter, etc.) and how to fix it.49</process>5051<context>52- The mapping file `.planning/.gh-mapping.json` is the source of truth for objective-to-issue numbers and sticky comment IDs. Commit it.53- This skill never edits issues that DevFlow did not create — only those tracked in the mapping.54- Failures (network, rate limit, auth expired) never block the user's workflow. They are reported and the planning state remains authoritative.55- For automatic syncing, the new-project workflow already calls `gh sync-objectives` after roadmap creation, and the verifier agent calls `gh comment` on verification gaps. This skill is for manual fire / recovery.56- The single-objective sync (`<objective_id>` mode) requires the objective to have a `github_issue` field in its OBJECTIVE.md frontmatter. If absent, run `objectives` mode first to create the issue, then backfill the `github_issue` field.5758## Triggers5960Use when the user wants to push DevFlow state to GitHub or recover from a missed sync. Also fires on: "create github issues", "sync state".61</context>