Claude-skill-registry documentation-sync

Synchronize version numbers across any project type using version file adapters

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/documentation-sync" ~/.claude/skills/majiayu000-claude-skill-registry-documentation-sync-a39397 && rm -rf "$T"
manifest: skills/data/documentation-sync/SKILL.md
source content

Documentation Sync

Purpose

Updates version numbers in version files (using appropriate adapters) and documentation files for any project type. Supports Node.js, Python, Rust, Go, Java, generic projects, and Claude Code plugins. Handles multiple version files and documentation references.

Input Context

Requires:

  • Project Configuration: Output from
    detect-project-type
    skill
  • Old Version: Previous version string (e.g., "1.1.0")
  • New Version: New version string (e.g., "1.2.0")

Workflow

1. Load Project Configuration

Use configuration from

detect-project-type
:

  • version_files
    - List of version files with adapters
  • documentation_files
    - Files to search for version references
  • project_type
    - Determines file update strategy

2. Update Version Files

For each version file, use the appropriate adapter to update the version.

See Version Adapters Reference for implementation details.

JSON files (package.json, plugin.json, etc.):

file="package.json"
old_version="1.1.0"
new_version="1.2.0"

# Update using jq
jq --indent 2 ".version = \"$new_version\"" "$file" > tmp.json && mv tmp.json "$file"

# Verify update
updated_version=$(jq -r '.version' "$file")
if [ "$updated_version" = "$new_version" ]; then
  echo "✓ Updated $file: $old_version → $new_version"
else
  echo "✗ Failed to update $file"
fi

TOML files (Cargo.toml, pyproject.toml):

file="Cargo.toml"

# Update version in [package] section
sed -i '/^\[package\]/,/^\[/ s/^version = ".*"/version = "'"$new_version"'"/' "$file"

# For pyproject.toml [project] section
sed -i '/^\[project\]/,/^\[/ s/^version = ".*"/version = "'"$new_version"'"/' pyproject.toml

# For pyproject.toml [tool.poetry] section
sed -i '/^\[tool.poetry\]/,/^\[/ s/^version = ".*"/version = "'"$new_version"'"/' pyproject.toml

# Verify
updated_version=$(grep '^version = ' "$file" | head -1 | sed 's/version = "\(.*\)"/\1/')

Python version.py files:

file="src/mypackage/__version__.py"

# Update __version__ variable
sed -i 's/^__version__ = ".*"/__version__ = "'"$new_version"'"/' "$file"

# Verify
updated_version=$(grep '^__version__ = ' "$file" | sed 's/__version__ = "\(.*\)"/\1/')

Text files (VERSION, version.txt):

file="VERSION"

# Simply write new version
echo "$new_version" > "$file"

# Verify
updated_version=$(cat "$file" | tr -d '[:space:]')

Gradle files:

# gradle.properties
sed -i 's/^version=.*/version='"$new_version"'/' gradle.properties

# build.gradle (single quotes)
sed -i "s/^version = '.*'/version = '${new_version}'/" build.gradle

# build.gradle (double quotes)
sed -i 's/^version = ".*"/version = "'"$new_version"'"/' build.gradle

Maven pom.xml:

# Replace first <version> tag (project version)
sed -i '0,/<version>.*<\/version>/s//<version>'"$new_version"'<\/version>/' pom.xml

Multiple version files: Update all files in sequence, tracking successes and failures:

updated_files=()
failed_files=()

for version_file_config in "${version_files[@]}"; do
  file_path="${version_file_config[path]}"
  adapter="${version_file_config[adapter]}"

  # Update using appropriate adapter
  case "$adapter" in
    "json")
      jq --indent 2 ".version = \"$new_version\"" "$file_path" > tmp.json && mv tmp.json "$file_path"
      ;;
    "toml")
      # ... toml update logic
      ;;
    "python-file")
      # ... python file update logic
      ;;
    # ... other adapters
  esac

  # Verify update succeeded
  if verify_version_updated "$file_path" "$new_version"; then
    updated_files+=("$file_path")
  else
    failed_files+=("$file_path")
  fi
done

3. Update Documentation Files

Search documentation files for version references and update them.

Use

documentation_files
from configuration (default:
["README.md"]
, supports globs).

Find all documentation files:

doc_files=()

for pattern in "${documentation_files[@]}"; do
  # Expand glob patterns
  if [[ "$pattern" == *"*"* ]]; then
    # Use find for glob patterns like "docs/**/*.md"
    while IFS= read -r file; do
      doc_files+=("$file")
    done < <(find . -path "./$pattern" -type f)
  else
    # Direct file path
    if [ -f "$pattern" ]; then
      doc_files+=("$pattern")
    fi
  done
done

For each documentation file, perform context-aware version replacement:

for doc_file in "${doc_files[@]}"; do
  echo "Processing $doc_file..."

  # Create backup
  cp "$doc_file" "${doc_file}.bak"

  # Perform replacements (context-aware)

  # 1. Version badges (shields.io, etc.)
  sed -i "s/version-${old_version//./-}/version-${new_version//./-}/g" "$doc_file"
  sed -i "s/v${old_version}-/v${new_version}-/g" "$doc_file"

  # 2. Installation commands
  # npm install package@1.1.0 → package@1.2.0
  sed -i "s/@${old_version}/@${new_version}/g" "$doc_file"

  # pip install package==1.1.0 → package==1.2.0
  sed -i "s/==${old_version}/==${new_version}/g" "$doc_file"

  # cargo add package@1.1.0 → package@1.2.0
  # (already covered by @version pattern)

  # 3. Git tag references
  # v1.1.0 → v1.2.0 (when followed by space, ), or end of line)
  sed -i "s/v${old_version}\([^0-9]\)/v${new_version}\1/g" "$doc_file"
  sed -i "s/v${old_version}$/v${new_version}/g" "$doc_file"

  # 4. Standalone version numbers in specific contexts
  # "Version 1.1.0" → "Version 1.2.0"
  sed -i "s/Version ${old_version}/Version ${new_version}/g" "$doc_file"
  sed -i "s/version ${old_version}/version ${new_version}/g" "$doc_file"

  # 5. In code blocks (more conservative - only in known safe contexts)
  # Only replace if part of package reference
  sed -i "s/\"${old_version}\"/\"${new_version}\"/g" "$doc_file"
  sed -i "s/'${old_version}'/'${new_version}'/g" "$doc_file"

  # Count changes
  changes=$(diff -u "${doc_file}.bak" "$doc_file" | grep '^[-+]' | wc -l)

  if [ $changes -gt 0 ]; then
    echo "✓ Updated $doc_file ($changes lines changed)"
    rm "${doc_file}.bak"
  else
    echo "  No version references found in $doc_file"
    mv "${doc_file}.bak" "$doc_file"  # Restore original
  fi
done

Conservative replacement strategy:

  • Only replace version strings in known safe contexts
  • Avoid replacing arbitrary numbers (could be dates, IDs, etc.)
  • Use word boundaries and context markers
  • Verify replacements made sense (count changes, show diff)

4. Project-Specific Updates

Some project types have additional files to update:

Node.js (package-lock.json):

if [ -f "package-lock.json" ]; then
  # Update version in lockfile (both root and package entry)
  jq ".version = \"$new_version\"" package-lock.json > tmp.json && mv tmp.json package-lock.json
  jq ".packages[\"\"].version = \"$new_version\"" package-lock.json > tmp.json && mv tmp.json package-lock.json
fi

Python (setuptools-scm): If using setuptools-scm, version is managed by git tags - no file updates needed.

Rust (Cargo.lock): If exists, update with:

cargo update --workspace

Go: No files to update - versions managed by git tags only.

5. Generate Git Diff

Create a summary of all changes:

# Stage all modified files
git add -u

# Generate diff
git diff --cached > /tmp/release-diff.patch

# Display summary
echo "Files modified:"
git diff --cached --name-only

echo ""
echo "Diff summary:"
git diff --cached --stat

6. Validation

Verify all updates were successful:

validation_errors=()

# Check each version file
for file in "${updated_files[@]}"; do
  actual_version=$(read_version_from_file "$file")

  if [ "$actual_version" != "$new_version" ]; then
    validation_errors+=("$file: expected $new_version, got $actual_version")
  fi
done

# If any errors, return them
if [ ${#validation_errors[@]} -gt 0 ]; then
  echo "✗ Validation failed:"
  printf '%s\n' "${validation_errors[@]}"
  exit 1
fi

Output Format

Return:

{
  "files_updated": [
    "package.json",
    "README.md",
    "docs/installation.md"
  ],
  "version_files": [
    {
      "path": "package.json",
      "old_version": "1.1.0",
      "new_version": "1.2.0",
      "adapter": "json",
      "success": true
    }
  ],
  "documentation_files": [
    {
      "path": "README.md",
      "changes": 5,
      "patterns_matched": ["version badge", "installation command", "git tag reference"]
    },
    {
      "path": "docs/installation.md",
      "changes": 2,
      "patterns_matched": ["installation command"]
    }
  ],
  "warnings": [],
  "git_diff_summary": {
    "files_changed": 3,
    "insertions": 8,
    "deletions": 8
  }
}

Examples

Example 1: Node.js Project

Input:

  • Project type:
    nodejs
  • Old version:
    1.1.0
  • New version:
    1.2.0
  • Version files:
    ["package.json"]
  • Documentation files:
    ["README.md"]

Operations:

  1. Update
    package.json
    :
    "version": "1.1.0"
    "version": "1.2.0"
  2. Update
    package-lock.json
    (if exists)
  3. Update
    README.md
    : version badge, install command

Output:

{
  "files_updated": ["package.json", "package-lock.json", "README.md"],
  "version_files": [
    {
      "path": "package.json",
      "old_version": "1.1.0",
      "new_version": "1.2.0",
      "success": true
    }
  ],
  "documentation_files": [
    {
      "path": "README.md",
      "changes": 3,
      "patterns_matched": ["version badge", "npm install"]
    }
  ]
}

Example 2: Python Project with Multiple Version Files

Input:

  • Project type:
    python
  • Old version:
    2.1.0
  • New version:
    3.0.0
  • Version files:
    • pyproject.toml
    • src/mypackage/__version__.py

Operations:

  1. Update
    pyproject.toml
    [project] section
  2. Update
    src/mypackage/__version__.py
  3. Update
    README.md
    references

Output:

{
  "version_files": [
    {
      "path": "pyproject.toml",
      "old_version": "2.1.0",
      "new_version": "3.0.0",
      "adapter": "toml",
      "success": true
    },
    {
      "path": "src/mypackage/__version__.py",
      "old_version": "2.1.0",
      "new_version": "3.0.0",
      "adapter": "python-file",
      "success": true
    }
  ]
}

Example 3: Rust Crate

Input:

  • Project type:
    rust
  • Old version:
    0.3.1
  • New version:
    0.3.2
  • Version files:
    ["Cargo.toml"]

Operations:

  1. Update
    Cargo.toml
    [package].version
  2. Run
    cargo update
    to update
    Cargo.lock
  3. Update documentation

Example 4: Go Module

Input:

  • Project type:
    go
  • Old version:
    1.5.0
  • New version:
    1.6.0
  • Version files:
    []
    (versions via tags only)

Operations:

  1. No version files to update (Go uses git tags)
  2. Update README.md and docs with new version references

Output:

{
  "version_files": [],
  "documentation_files": [
    {
      "path": "README.md",
      "changes": 2,
      "patterns_matched": ["version reference", "go get command"]
    }
  ],
  "notes": ["Go project: version managed via git tags only"]
}

Error Handling

File update failure:

{
  "version_files": [
    {
      "path": "package.json",
      "success": false,
      "error": "Permission denied"
    }
  ]
}

Version mismatch after update:

{
  "warnings": [
    "package.json: expected 1.2.0 after update, but still reads 1.1.0",
    "File may need manual review"
  ]
}

Documentation file not found:

{
  "warnings": [
    "Documentation file not found: docs/installation.md",
    "Specified in configuration but does not exist"
  ]
}

Integration Notes

This skill is invoked by the

/release
command in Phase 4. The command will:

  1. Display git diff of all changes
  2. Allow user to review before proceeding
  3. Stage all modified files for commit in Phase 6

Reference Documentation