---
description: "Sync spec artifacts with updates from the source GitHub Issue"
tools:
- 'bash/gh'
---
# Sync Spec with GitHub Issue
Keep spec artifacts updated when the source GitHub Issue is modified. Detects changes in title, body, labels, and comments, then updates the spec accordingly.
## User Input
$ARGUMENTS
Optional: Specify feature directory or issue number. If not provided, syncs all linked issues in the project.
Examples:
- `/speckit.github-issues.sync` (sync all linked issues)
- `/speckit.github-issues.sync 001-feature-name` (sync specific feature)
- `/speckit.github-issues.sync #2175` (sync specific issue)
## Prerequisites
1. GitHub CLI (`gh`) must be installed and authenticated
2. Spec must have been previously imported using `/speckit.github-issues.import`
3. Issue link metadata must exist (`.issue-link` file)
## Steps
### 1. Find Linked Issues
Discover all specs that are linked to GitHub Issues.
```bash
# Find all .issue-link files
linked_specs=()
for link_file in .specify/specs/*/.issue-link; do
if [ -f "$link_file" ]; then
linked_specs+=("$link_file")
fi
done
if [ ${#linked_specs[@]} -eq 0 ]; then
echo "No linked issues found. Use /speckit.github-issues.import first."
exit 0
fi
echo "Found ${#linked_specs[@]} linked issue(s)"
```
### 2. Parse Arguments
Determine which specs to sync based on user input.
```bash
input="$ARGUMENTS"
specs_to_sync=()
if [ -z "$input" ]; then
# Sync all linked issues
specs_to_sync=("${linked_specs[@]}")
elif [[ "$input" =~ ^#([0-9]+)$ ]]; then
# Sync specific issue number
issue_num="${BASH_REMATCH[1]}"
for link_file in "${linked_specs[@]}"; do
linked_issue=$(grep "^issue_number:" "$link_file" | cut -d' ' -f2)
if [ "$linked_issue" = "$issue_num" ]; then
specs_to_sync+=("$link_file")
fi
done
else
# Sync specific feature directory
feature_dir=".specify/specs/$input"
link_file="$feature_dir/.issue-link"
if [ -f "$link_file" ]; then
specs_to_sync+=("$link_file")
else
echo "Error: No linked issue found for feature: $input"
exit 1
fi
fi
if [ ${#specs_to_sync[@]} -eq 0 ]; then
echo "No matching linked issues found."
exit 0
fi
```
### 3. Check for Updates
For each linked issue, fetch current data and compare with last sync.
```bash
for link_file in "${specs_to_sync[@]}"; do
feature_dir=$(dirname "$link_file")
spec_file="$feature_dir/spec.md"
# Read metadata
repo=$(grep "^repository:" "$link_file" | cut -d' ' -f2)
issue_number=$(grep "^issue_number:" "$link_file" | cut -d' ' -f2)
last_synced=$(grep "^last_synced:" "$link_file" | cut -d' ' -f2)
echo ""
echo "Checking $repo#$issue_number..."
# Fetch current issue data
issue_data=$(gh issue view "$issue_number" \
--repo "$repo" \
--json title,body,labels,comments,updatedAt,state)
if [ $? -ne 0 ]; then
echo " ✗ Failed to fetch issue data"
continue
fi
# Check if issue was updated since last sync
if [[ "$updated_at" > "$last_synced" ]] || [ -z "$last_synced" ]; then
echo " ✓ Updates detected (last synced: $last_synced, updated: $updated_at)"
# Store for processing
echo "$feature_dir|$repo|$issue_number|$spec_file" >> /tmp/specs_to_update.txt
else
echo " ✓ No updates since last sync"
fi
done
```
### 4. Review Changes
Show what will be updated and prompt for confirmation.
```bash
if [ ! -f /tmp/specs_to_update.txt ]; then
echo ""
echo "All specs are up to date!"
exit 0
fi
echo ""
echo "The following specs have updates available:"
echo ""
done < /tmp/specs_to_update.txt
echo ""
read -p "Apply updates? (y/n): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo "Sync cancelled."
rm /tmp/specs_to_update.txt
exit 0
fi
```
### 5. Apply Updates
Update each spec with the latest issue data.
```bash
echo "Updating $spec_file..."
# Fetch fresh issue data
issue_data=$(gh issue view "$issue_number" \
--repo "$repo" \
--json title,body,labels,comments,updatedAt,state,url)
title=$(echo "$issue_data" | jq -r '.title')
body=$(echo "$issue_data" | jq -r '.body // ""')
state=$(echo "$issue_data" | jq -r '.state')
labels=$(echo "$issue_data" | jq -r '.labels[].name' | paste -sd ',' -)
url=$(echo "$issue_data" | jq -r '.url')
# Update spec frontmatter
sed -i "s|^**Issue Status:**.*|**Issue Status:** $state|" "$spec_file"
sed -i "s|^**Labels:**.*|**Labels:** $labels|" "$spec_file"
sed -i "s|^**Last Updated:**.*|**Last Updated:** $(date -u +"%Y-%m-%d")|" "$spec_file"
# Update title if changed
sed -i "s|^# Feature Specification:.*|# Feature Specification: $title|" "$spec_file"
echo " ✓ Updated title"
fi
# Append new comments to Discussion Notes section
if [ -n "$new_comments" ]; then
# Find Discussion Notes section and append
echo "" >> "$spec_file"
echo "### New Comments (synced $(date -u +"%Y-%m-%d"))" >> "$spec_file"
echo "" >> "$spec_file"
echo "$new_comments" >> "$spec_file"
echo " ✓ Added new comments"
fi
# Update metadata
link_file="$feature_dir/.issue-link"
done < /tmp/specs_to_update.txt
rm /tmp/specs_to_update.txt
```
### 6. Summary
Provide a summary of the sync operation.
```bash
echo ""
echo "Sync Summary:"
echo " ✓ All linked issues synced successfully"
echo ""
echo "Next steps:"
echo " 1. Review the updated specs"
echo " 2. Update plan.md if requirements changed significantly"
echo " 3. Update tasks.md if needed"
```
## Configuration
Load configuration from `.specify/extensions/github-issues/github-issues-config.yml`:
- `sync.auto_detect`: Automatically detect changes
- `sync.prompt_before_sync`: Prompt before applying changes
## Error Handling
- Verify `gh` CLI is installed and authenticated
- Check that `.issue-link` metadata exists
- Handle network errors gracefully
- Skip specs that fail to update and continue with others
- Preserve original spec content if update fails