Parcourir la source

Release v5.0.7: Copilot CLI support, OpenCode fixes

Jesse Vincent il y a 5 mois
Parent
commit
1f20bef3f5

+ 1 - 1
.claude-plugin/marketplace.json

@@ -9,7 +9,7 @@
     {
       "name": "superpowers",
       "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
-      "version": "5.0.6",
+      "version": "5.0.7",
       "source": "./",
       "author": {
         "name": "Jesse Vincent",

+ 1 - 1
.claude-plugin/plugin.json

@@ -1,7 +1,7 @@
 {
   "name": "superpowers",
   "description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
-  "version": "5.0.6",
+  "version": "5.0.7",
   "author": {
     "name": "Jesse Vincent",
     "email": "jesse@fsck.com"

+ 1 - 1
.cursor-plugin/plugin.json

@@ -2,7 +2,7 @@
   "name": "superpowers",
   "displayName": "Superpowers",
   "description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
-  "version": "5.0.6",
+  "version": "5.0.7",
   "author": {
     "name": "Jesse Vincent",
     "email": "jesse@fsck.com"

+ 19 - 0
.version-bump.json

@@ -0,0 +1,19 @@
+{
+  "files": [
+    { "path": "package.json", "field": "version" },
+    { "path": ".claude-plugin/plugin.json", "field": "version" },
+    { "path": ".cursor-plugin/plugin.json", "field": "version" },
+    { "path": ".claude-plugin/marketplace.json", "field": "plugins.0.version" },
+    { "path": "gemini-extension.json", "field": "version" }
+  ],
+  "audit": {
+    "exclude": [
+      "CHANGELOG.md",
+      "RELEASE-NOTES.md",
+      "node_modules",
+      ".git",
+      ".version-bump.json",
+      "scripts/bump-version.sh"
+    ]
+  }
+}

+ 1 - 1
RELEASE-NOTES.md

@@ -1,6 +1,6 @@
 # Superpowers Release Notes
 
-## Unreleased
+## v5.0.7 (2026-03-31)
 
 ### GitHub Copilot CLI Support
 

+ 1 - 1
gemini-extension.json

@@ -1,6 +1,6 @@
 {
   "name": "superpowers",
   "description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
-  "version": "5.0.6",
+  "version": "5.0.7",
   "contextFileName": "GEMINI.md"
 }

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "superpowers",
-  "version": "5.0.6",
+  "version": "5.0.7",
   "type": "module",
   "main": ".opencode/plugins/superpowers.js"
 }

+ 220 - 0
scripts/bump-version.sh

@@ -0,0 +1,220 @@
+#!/usr/bin/env bash
+#
+# bump-version.sh — bump version numbers across all declared files,
+# with drift detection and repo-wide audit for missed files.
+#
+# Usage:
+#   bump-version.sh <new-version>   Bump all declared files to new version
+#   bump-version.sh --check         Report current versions (detect drift)
+#   bump-version.sh --audit         Check + grep repo for old version strings
+#
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+CONFIG="$REPO_ROOT/.version-bump.json"
+
+if [[ ! -f "$CONFIG" ]]; then
+  echo "error: .version-bump.json not found at $CONFIG" >&2
+  exit 1
+fi
+
+# --- helpers ---
+
+# Read a dotted field path from a JSON file.
+# Handles both simple ("version") and nested ("plugins.0.version") paths.
+read_json_field() {
+  local file="$1" field="$2"
+  # Convert dot-path to jq path: "plugins.0.version" -> .plugins[0].version
+  local jq_path
+  jq_path=$(echo "$field" | sed -E 's/\.([0-9]+)/[\1]/g' | sed 's/^/./' | sed 's/\.\././g')
+  jq -r "$jq_path" "$file"
+}
+
+# Write a dotted field path in a JSON file, preserving formatting.
+write_json_field() {
+  local file="$1" field="$2" value="$3"
+  local jq_path
+  jq_path=$(echo "$field" | sed -E 's/\.([0-9]+)/[\1]/g' | sed 's/^/./' | sed 's/\.\././g')
+  local tmp="${file}.tmp"
+  jq "$jq_path = \"$value\"" "$file" > "$tmp" && mv "$tmp" "$file"
+}
+
+# Read the list of declared files from config.
+# Outputs lines of "path<TAB>field"
+declared_files() {
+  jq -r '.files[] | "\(.path)\t\(.field)"' "$CONFIG"
+}
+
+# Read the audit exclude patterns from config.
+audit_excludes() {
+  jq -r '.audit.exclude[]' "$CONFIG" 2>/dev/null
+}
+
+# --- commands ---
+
+cmd_check() {
+  local has_drift=0
+  local versions=()
+
+  echo "Version check:"
+  echo ""
+
+  while IFS=$'\t' read -r path field; do
+    local fullpath="$REPO_ROOT/$path"
+    if [[ ! -f "$fullpath" ]]; then
+      printf "  %-45s  MISSING\n" "$path ($field)"
+      has_drift=1
+      continue
+    fi
+    local ver
+    ver=$(read_json_field "$fullpath" "$field")
+    printf "  %-45s  %s\n" "$path ($field)" "$ver"
+    versions+=("$ver")
+  done < <(declared_files)
+
+  echo ""
+
+  # Check if all versions match
+  local unique
+  unique=$(printf '%s\n' "${versions[@]}" | sort -u | wc -l | tr -d ' ')
+  if [[ "$unique" -gt 1 ]]; then
+    echo "DRIFT DETECTED — versions are not in sync:"
+    printf '%s\n' "${versions[@]}" | sort | uniq -c | sort -rn | while read -r count ver; do
+      echo "  $ver ($count files)"
+    done
+    has_drift=1
+  else
+    echo "All declared files are in sync at ${versions[0]}"
+  fi
+
+  return $has_drift
+}
+
+cmd_audit() {
+  # First run check
+  cmd_check || true
+  echo ""
+
+  # Determine the current version (most common across declared files)
+  local current_version
+  current_version=$(
+    while IFS=$'\t' read -r path field; do
+      local fullpath="$REPO_ROOT/$path"
+      [[ -f "$fullpath" ]] && read_json_field "$fullpath" "$field"
+    done < <(declared_files) | sort | uniq -c | sort -rn | head -1 | awk '{print $2}'
+  )
+
+  if [[ -z "$current_version" ]]; then
+    echo "error: could not determine current version" >&2
+    return 1
+  fi
+
+  echo "Audit: scanning repo for version string '$current_version'..."
+  echo ""
+
+  # Build grep exclude args
+  local -a exclude_args=()
+  while IFS= read -r pattern; do
+    exclude_args+=("--exclude=$pattern" "--exclude-dir=$pattern")
+  done < <(audit_excludes)
+
+  # Also always exclude binary files and .git
+  exclude_args+=("--exclude-dir=.git" "--exclude-dir=node_modules" "--binary-files=without-match")
+
+  # Get list of declared paths for comparison
+  local -a declared_paths=()
+  while IFS=$'\t' read -r path _field; do
+    declared_paths+=("$path")
+  done < <(declared_files)
+
+  # Grep for the version string
+  local found_undeclared=0
+  while IFS= read -r match; do
+    local match_file
+    match_file=$(echo "$match" | cut -d: -f1)
+    # Make path relative to repo root
+    local rel_path="${match_file#$REPO_ROOT/}"
+
+    # Check if this file is in the declared list
+    local is_declared=0
+    for dp in "${declared_paths[@]}"; do
+      if [[ "$rel_path" == "$dp" ]]; then
+        is_declared=1
+        break
+      fi
+    done
+
+    if [[ "$is_declared" -eq 0 ]]; then
+      if [[ "$found_undeclared" -eq 0 ]]; then
+        echo "UNDECLARED files containing '$current_version':"
+        found_undeclared=1
+      fi
+      echo "  $match"
+    fi
+  done < <(grep -rn "${exclude_args[@]}" -F "$current_version" "$REPO_ROOT" 2>/dev/null || true)
+
+  if [[ "$found_undeclared" -eq 0 ]]; then
+    echo "No undeclared files contain the version string. All clear."
+  else
+    echo ""
+    echo "Review the above files — if they should be bumped, add them to .version-bump.json"
+    echo "If they should be skipped, add them to the audit.exclude list."
+  fi
+}
+
+cmd_bump() {
+  local new_version="$1"
+
+  # Validate semver-ish format
+  if ! echo "$new_version" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+'; then
+    echo "error: '$new_version' doesn't look like a version (expected X.Y.Z)" >&2
+    exit 1
+  fi
+
+  echo "Bumping all declared files to $new_version..."
+  echo ""
+
+  while IFS=$'\t' read -r path field; do
+    local fullpath="$REPO_ROOT/$path"
+    if [[ ! -f "$fullpath" ]]; then
+      echo "  SKIP (missing): $path"
+      continue
+    fi
+    local old_ver
+    old_ver=$(read_json_field "$fullpath" "$field")
+    write_json_field "$fullpath" "$field" "$new_version"
+    printf "  %-45s  %s -> %s\n" "$path ($field)" "$old_ver" "$new_version"
+  done < <(declared_files)
+
+  echo ""
+  echo "Done. Running audit to check for missed files..."
+  echo ""
+  cmd_audit
+}
+
+# --- main ---
+
+case "${1:-}" in
+  --check)
+    cmd_check
+    ;;
+  --audit)
+    cmd_audit
+    ;;
+  --help|-h|"")
+    echo "Usage: bump-version.sh <new-version> | --check | --audit"
+    echo ""
+    echo "  <new-version>  Bump all declared files to the given version"
+    echo "  --check        Show current versions, detect drift"
+    echo "  --audit        Check + scan repo for undeclared version references"
+    exit 0
+    ;;
+  --*)
+    echo "error: unknown flag '$1'" >&2
+    exit 1
+    ;;
+  *)
+    cmd_bump "$1"
+    ;;
+esac