mirror of
https://github.com/obra/superpowers.git
synced 2026-04-26 19:49:08 +08:00
Compare commits
26 Commits
v5.0.7
...
8b9a5da90b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b9a5da90b | ||
|
|
04ff6660e8 | ||
|
|
471aa93a4c | ||
|
|
872172870d | ||
|
|
ed06287a8a | ||
|
|
5406747197 | ||
|
|
879940ba5e | ||
|
|
0f306f0d18 | ||
|
|
af025aa35b | ||
|
|
738a18d6ff | ||
|
|
94b2bcbb24 | ||
|
|
ed4103ab91 | ||
|
|
ab500dade6 | ||
|
|
a22122d57f | ||
|
|
218c3ed93e | ||
|
|
9fa8ceb101 | ||
|
|
b045fa3950 | ||
|
|
bf8f7572eb | ||
|
|
c141508f36 | ||
|
|
7820adcde7 | ||
|
|
250dea46fd | ||
|
|
477c55386a | ||
|
|
cb4745eeb5 | ||
|
|
872ec69f4c | ||
|
|
e0fcfaf838 | ||
|
|
5bf3f77483 |
@@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "5.0.7",
|
"version": "5.0.6",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "5.0.7",
|
"version": "5.0.6",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
"email": "jesse@fsck.com"
|
"email": "jesse@fsck.com"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"displayName": "Superpowers",
|
"displayName": "Superpowers",
|
||||||
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "5.0.7",
|
"version": "5.0.6",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Jesse Vincent",
|
"name": "Jesse Vincent",
|
||||||
"email": "jesse@fsck.com"
|
"email": "jesse@fsck.com"
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"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,6 +1,6 @@
|
|||||||
# Superpowers Release Notes
|
# Superpowers Release Notes
|
||||||
|
|
||||||
## v5.0.7 (2026-03-31)
|
## Unreleased
|
||||||
|
|
||||||
### GitHub Copilot CLI Support
|
### GitHub Copilot CLI Support
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
||||||
"version": "5.0.7",
|
"version": "5.0.6",
|
||||||
"contextFileName": "GEMINI.md"
|
"contextFileName": "GEMINI.md"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "superpowers",
|
"name": "superpowers",
|
||||||
"version": "5.0.7",
|
"version": "5.0.6",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": ".opencode/plugins/superpowers.js"
|
"main": ".opencode/plugins/superpowers.js"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,220 +0,0 @@
|
|||||||
#!/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
|
|
||||||
Reference in New Issue
Block a user