Create and maintain XerahS Improvement Proposals (XIPs) with GitHub as source of truth and docs/proposals/xip folder as backup. Use when creating or editing XIPs, syncing XIPs between GitHub issues and the docs/proposals/xip folder, or when the user mentions XIP, GitHub issues for XIP, or local XIP files.
Source of truth: GitHub issues (label xip).
Backup: docs/proposals/xip/ folder (generated from GitHub via sync).
Create and edit XIPs in GitHub; keep a local backup in docs/proposals/xip/ by running sync. Do not treat the local folder as the primary place to write XIPs.
For XIP structure, templates, and writing patterns, use XIP writing reference. This skill is the operational workflow for issue creation, issue editing, sync, and recovery.
gh issue create / gh issue edit (or the GitHub UI). The issue body holds the full XIP markdown. Status (open/closed/parked) lives only in GitHub via issue state and labels..mddocs/proposals/xip/docs/proposals/xip/, create a new issue with that content and then sync.Use this when the user says the local docs/proposals/xip/ folder has XIPs that are missing from GitHub.
Compare by canonical ID only
XIP####.xip label, because existing XIP issues can be missing the label.XIP#### from issue titles and ignore all other title text differences.XIP####, even if punctuation, casing, or wording differs.$repo = "ShareX/XerahS"
$xipDir = "docs/proposals/xip"
$issues = gh issue list --repo $repo --state all --limit 500 --json number,title,url,state,labels | ConvertFrom-Json
$issueIds = New-Object "System.Collections.Generic.HashSet[string]"
foreach ($issue in $issues) {
foreach ($match in [regex]::Matches($issue.title, "XIP[0-9]{4}")) {
[void]$issueIds.Add($match.Value)
}
}
$localIds = Get-ChildItem -LiteralPath $xipDir -Filter "XIP*.md" |
ForEach-Object { if ($_.Name -match "^(XIP[0-9]{4})") { $Matches[1] } } |
Sort-Object -Unique
$missing = $localIds | Where-Object { -not $issueIds.Contains($_) }
$missing
Repair labels before running label-based sync
XIP#### but does not have the xip label, add the label instead of creating a duplicate issue.sync-from-github.ps1 reads only issues with label xip.foreach ($issue in $issues) {
if ($issue.title -match "XIP[0-9]{4}") {
$labelNames = $issue.labels | ForEach-Object { $_.name }
if (-not ($labelNames -contains "xip")) {
gh issue edit $issue.number --repo $repo --add-label "xip"
}
}
}
Create only true missing issues
XIP####, create one issue using the matching local file as the body and label it xip.XIP#### Short Descriptive Title: single space after the ID; no brackets, colon, or dash after the ID.Verify after creation
XIP#### has the xip label.git status --short; uploading missing issues should not leave local file changes unless you intentionally ran the sync script.Be deliberate with local sync
sync-from-github.ps1 removes and rewrites docs/proposals/xip/XIP*.md from label-matched GitHub issues. It can rename files and rewrite old bodies, causing broad local churn.git status --short and git diff --stat -- docs/proposals/xip afterwards. Keep or discard the generated backup churn deliberately.Choose the next XIP number
gh issue list --repo ShareX/XerahS --state all --limit 500 --json number,title,labels--label xip for ID discovery; it can miss an existing XIP issue whose label was accidentally omitted.docs/proposals/xip/*.md (e.g. XIP0044).Draft the XIP body
XIP0044 Short Descriptive Title (4-digit zero-padded number, single space, no brackets, no colon, no dash).Create the GitHub issue
XIP0044 Short Descriptive Titlexip. Add parked if the XIP is parked.gh issue create --title "XIP0044 Your Title" --label "xip" --body-file path/to/draft.md
Sync to docs/proposals/xip
./.ai/skills/sync-xips/scripts/sync-from-github.ps1docs/proposals/xip/XIP####-title-slug.md.Edit on GitHub
gh issue edit <number> --title "XIP0044 New Title" --body-file path/to/updated.mdSync to docs/proposals/xip
./.ai/skills/sync-xips/scripts/sync-from-github.ps1 so the backup in docs/proposals/xip/ is updated.Run from repo root:
.\.ai\skills\sync-xips\scripts\sync-from-github.ps1
xip..md file per XIP under docs/proposals/xip/ (single folder). Status is not synced to paths; it stays in GitHub (issue state and labels).XIP####-title-slug.md (number from title, rest from lower-case slug of title).If the only good copy of a XIP is in the local folder:
xip:
gh issue create --title "XIP0044 Title From File" --label "xip" --body-file "docs/proposals/xip/XIP0044-Something.md"
docs/proposals/xip/ as XIP####-title-slug.md. Status (open/closed/parked) is not reflected in folder structure; it lives only in GitHub issues (state and labels). This avoids moving files and breaking links when status changes.XIP0044 Short Descriptive Title
[ ], no :, no - between number and title.XIP0044-short-descriptive-title.md (number + lower-case slug with hyphens).Full structure, templates, and patterns: XIP writing reference.
.ai/skills/sync-xips/scripts/sync-from-github.ps1.ai/skills/sync-xips/scripts/merge-old-xips.ps1 – merges old-named XIP*.md (e.g. in docs/proposals/xip/) into the corresponding GitHub issue body, runs sync, then deletes the old files. Use after migrating to single-folder backup or when cleaning duplicates.Run from repo root; requires gh CLI and PowerShell.
xip); issue body = full XIP.docs/proposals/xip/); status only in GitHub. Run sync-from-github.ps1 after changes.XIP0044 Title (no brackets/colon/dash); file XIP0044-title-slug.md.