GitHub Sync¶
One-way push of all domain tasks into a private GitHub Project v2.
Overview¶
/sync-github pushes every task from tasks/*.md (excluding inbox) into a private GitHub Project, mapping markdown fields to GitHub Project custom fields. Markdown is always the source of truth — sync never pulls from GitHub, never resolves conflicts, and never deletes GitHub items.
Source of truth for internals: ../../skills/github-sync/SKILL.md
View-layout reference: ../../skills/github-sync/references/view-layout-automation.md
Prerequisites¶
ghCLI installed and authenticated:gh auth login- Optional:
personal-githubMCP server configured (used for identity resolution and issue listing) - Projects v2 field writes use GraphQL via
gh api graphql
Commands¶
/sync-github --init # create GitHub Project + fields (idempotent)
/sync-github --init --dry-run # preview what --init would do
/sync-github # sync all tasks
/sync-github --dry-run # preview sync without mutations
The --init Flow¶
The following diagram shows the idempotent initialization sequence (steps mirror skills/github-sync/SKILL.md exactly).
flowchart TD
A["Start: /sync-github --init"] --> B["1. Resolve owner identity\n(gh api graphql viewer)"]
B --> C{"2. Check config:\n.agentic-gtd.local.md\nhas projectId?"}
C -- Yes --> D["Report 'already initialized'\nExit — no mutations"]
C -- No --> E["3. Create private GitHub Project\n'Agentic GTD'\n(capture projectId + number)"]
E --> F["4. Create custom fields via GraphQL:\nPriority, Domain, Due, Project/Area\nEnsure Status has Todo + Done"]
F --> G["5. Resolve all fieldIds and\noption IDs from project field list"]
G --> H["6. Write all IDs to\n.agentic-gtd.local.md"]
H --> I["7. Append .agentic-gtd.local.md\nto .gitignore"]
I --> J["Done — project ready for /sync-github"]
- Resolves your GitHub owner identity
- Checks
.agentic-gtd.local.md— ifprojectIdalready set, exits without recreating - Creates a private GitHub Project titled "Agentic GTD"
- Creates custom fields:
Priority(single-select),Domain(single-select),Due(date),Project/Area(text); ensures Status hasTodoandDoneoptions - Resolves and records every
fieldIdand option ID - Writes all IDs to
.agentic-gtd.local.mdat repo root - Adds
.agentic-gtd.local.mdto.gitignore
Field Mapping¶
| Markdown source | GitHub Project field | Values |
|---|---|---|
| filename stem | Domain |
Domains with github_sync: yes in tasks/domains.md (built-in: fulltime, side-projects, open-source, knowledge). parttime is github_sync: no by design. New domains require manually adding a Domain single-select option in the GitHub Project and its option-ID in .agentic-gtd.local.md (see commands/add-domain.md Step 8); otherwise /sync-github skips them with a warning. |
prio: tag |
Priority |
fulltime, trust, side, long, short, tedious |
due: tag |
Due |
YYYY-MM-DD (empty if absent or malformed) |
checkbox [ ] / [x] |
Status |
Todo / Done |
| task title | item title | trimmed, whitespace collapsed |
project: tag |
Project/Area |
text (omitted if tag absent) |
Config File¶
.agentic-gtd.local.md at repo root stores projectId, projectNumber, owner, and all fieldId and option ID mappings. This file must not be committed. It is added to .gitignore during --init.
One-Way Push Invariants¶
- Markdown is always the source of truth
- Sync never pulls from GitHub, never resolves conflicts, never deletes GitHub items
tasks/inbox.mdis never synced- Rename limitation: Renaming a task in markdown creates a duplicate in GitHub. The old item is orphaned (one-way push never deletes). Remove orphans manually in the GitHub Project UI.
Related¶
- Installation —
ghCLI setup - Task Line Format — field definitions