claude-code-orchestrator-kit 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/frontend/workers/fullstack-nextjs-specialist.md +4 -0
- package/.claude/agents/frontend/workers/nextjs-ui-designer.md +652 -0
- package/.claude/agents/frontend/workers/visual-effects-creator.md +4 -0
- package/.claude/agents/health/workers/dependency-auditor.md +43 -13
- package/.claude/agents/health/workers/dependency-updater.md +9 -0
- package/.claude/commands/speckit.implement.md +15 -9
- package/.claude/commands/speckit.tasks.md +4 -3
- package/.claude/scripts/release.sh +260 -40
- package/.claude/skills/frontend-aesthetics/SKILL.md +440 -0
- package/.github/workflows/publish.yml +33 -0
- package/.gitignore +14 -2
- package/README.md +138 -0
- package/docs/Agents Ecosystem/spec-kit-comprehensive-updates.md +17 -27
- package/mcp/.mcp.base.json +3 -9
- package/mcp/.mcp.frontend.json +3 -9
- package/mcp/.mcp.full.json +3 -9
- package/mcp/.mcp.n8n.json +3 -9
- package/mcp/.mcp.supabase-full.json +3 -9
- package/mcp/.mcp.supabase-only.json +3 -9
- package/package.json +78 -78
- package/.claude/settings.local.json +0 -21
- package/mcp/.mcp.local.json +0 -7
|
@@ -72,7 +72,36 @@ When invoked, you must follow these steps systematically:
|
|
|
72
72
|
```bash
|
|
73
73
|
pnpm outdated --json || npm outdated --json
|
|
74
74
|
```
|
|
75
|
-
|
|
75
|
+
|
|
76
|
+
6. **CRITICAL: Filter Unstable Versions**
|
|
77
|
+
|
|
78
|
+
The `outdated` command shows the "latest" tag from npm, which may include unstable pre-release versions. You MUST filter these out:
|
|
79
|
+
|
|
80
|
+
**Unstable version patterns to EXCLUDE**:
|
|
81
|
+
- `alpha` (e.g., `2.0.0-alpha.1`)
|
|
82
|
+
- `beta` (e.g., `2.0.0-beta.3`)
|
|
83
|
+
- `rc` (e.g., `2.0.0-rc.1`)
|
|
84
|
+
- `canary` (e.g., `2.0.0-canary.123`)
|
|
85
|
+
- `next` (e.g., `2.0.0-next.5`)
|
|
86
|
+
- `experimental` (e.g., `2.0.0-experimental.0`)
|
|
87
|
+
- `dev` (e.g., `2.0.0-dev.1`)
|
|
88
|
+
- `preview` (e.g., `2.0.0-preview.2`)
|
|
89
|
+
- `nightly` (e.g., `2.0.0-nightly.20250101`)
|
|
90
|
+
|
|
91
|
+
**For each package with unstable "latest" version**:
|
|
92
|
+
```bash
|
|
93
|
+
# Get all available versions and find latest stable
|
|
94
|
+
npm view package-name versions --json
|
|
95
|
+
```
|
|
96
|
+
Then select the highest version WITHOUT prerelease suffix.
|
|
97
|
+
|
|
98
|
+
**Example**:
|
|
99
|
+
- `pnpm outdated` shows: `react` latest = `19.0.0-rc.1`
|
|
100
|
+
- Run: `npm view react versions --json`
|
|
101
|
+
- Find latest stable: `18.3.1` (no prerelease suffix)
|
|
102
|
+
- Report `18.3.1` as target version, NOT `19.0.0-rc.1`
|
|
103
|
+
|
|
104
|
+
7. Categorize by update type:
|
|
76
105
|
- **Critical**: Security fixes (from audit)
|
|
77
106
|
- **High**: Major version updates with breaking changes
|
|
78
107
|
- **Medium**: Minor version updates (new features)
|
|
@@ -200,12 +229,13 @@ pnpm update lodash@^4.17.21
|
|
|
200
229
|
|
|
201
230
|
#### 3. Major Version Update - react@17.0.2
|
|
202
231
|
|
|
203
|
-
**Category**: Outdated Package
|
|
204
|
-
**Priority**: high
|
|
205
|
-
**Package**: react
|
|
206
|
-
**Current Version**: 17.0.2
|
|
207
|
-
**Latest Version**: 18.
|
|
208
|
-
**Update Type**: major
|
|
232
|
+
**Category**: Outdated Package
|
|
233
|
+
**Priority**: high
|
|
234
|
+
**Package**: react
|
|
235
|
+
**Current Version**: 17.0.2
|
|
236
|
+
**Latest Stable Version**: 18.3.1
|
|
237
|
+
**Update Type**: major
|
|
238
|
+
**Note**: Unstable versions (e.g., 19.0.0-rc.1) were excluded
|
|
209
239
|
|
|
210
240
|
**Analysis**:
|
|
211
241
|
- React 18 includes new features:
|
|
@@ -228,12 +258,12 @@ Requires manual migration - create separate task
|
|
|
228
258
|
|
|
229
259
|
#### 4. Minor Update - @types/node@16.11.7
|
|
230
260
|
|
|
231
|
-
**Category**: Outdated Package
|
|
232
|
-
**Priority**: medium
|
|
233
|
-
**Package**: @types/node
|
|
234
|
-
**Current Version**: 16.11.7
|
|
235
|
-
**Latest Version**: 16.18.0
|
|
236
|
-
**Update Type**: minor
|
|
261
|
+
**Category**: Outdated Package
|
|
262
|
+
**Priority**: medium
|
|
263
|
+
**Package**: @types/node
|
|
264
|
+
**Current Version**: 16.11.7
|
|
265
|
+
**Latest Stable Version**: 16.18.0
|
|
266
|
+
**Update Type**: minor
|
|
237
267
|
|
|
238
268
|
**Suggested Fix**:
|
|
239
269
|
```bash
|
|
@@ -68,6 +68,14 @@ When invoked, you must follow these steps:
|
|
|
68
68
|
- Complete validation before next package
|
|
69
69
|
- If validation fails, rollback immediately
|
|
70
70
|
|
|
71
|
+
**Version Stability Check**:
|
|
72
|
+
Before updating, verify target version is stable (no prerelease suffix):
|
|
73
|
+
```bash
|
|
74
|
+
# If target version looks unstable (alpha, beta, rc, canary, next, etc.)
|
|
75
|
+
npm view package-name versions --json
|
|
76
|
+
# Select highest version WITHOUT prerelease suffix
|
|
77
|
+
```
|
|
78
|
+
|
|
71
79
|
5. **Update Categories**
|
|
72
80
|
|
|
73
81
|
### A. Security Fixes (Critical/High Priority)
|
|
@@ -399,6 +407,7 @@ When invoked, you must follow these steps:
|
|
|
399
407
|
4. **Rollback on ANY failure** - restore backups immediately
|
|
400
408
|
5. **Check migration guides** - for ALL major version updates
|
|
401
409
|
6. **Document manual items** - don't skip difficult updates silently
|
|
410
|
+
7. **STABLE VERSIONS ONLY** - Never update to pre-release versions (alpha, beta, rc, canary, next, experimental, dev, preview, nightly). If target version is unstable, find latest stable version instead
|
|
402
411
|
|
|
403
412
|
### Rollback Protocol
|
|
404
413
|
|
|
@@ -58,16 +58,22 @@ You **MUST** consider the user input before proceeding (if not empty).
|
|
|
58
58
|
|
|
59
59
|
4. **PLANNING PHASE** (Execute Before Implementation):
|
|
60
60
|
- Review all tasks and classify execution model (parallel vs sequential)
|
|
61
|
-
- **
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
|
|
61
|
+
- **Step 1: Task Analysis**:
|
|
62
|
+
* Analyze all tasks and identify required agent capabilities
|
|
63
|
+
* Determine which tasks need MAIN (trivial only), existing agents, or new agents
|
|
64
|
+
* Create list of missing agent types with specifications
|
|
65
|
+
- **Step 2: Agent Creation** (if needed):
|
|
66
|
+
* Launch N meta-agent-v3 calls in single message (1 call per missing agent)
|
|
66
67
|
* After agent creation: ask user to restart claude-code
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
*
|
|
70
|
-
*
|
|
68
|
+
* After restart: verify new agents exist before proceeding
|
|
69
|
+
- **Step 3: Executor Assignment**:
|
|
70
|
+
* [EXECUTOR: MAIN] - ONLY for trivial tasks (1-2 line fixes, simple imports, single dependency install)
|
|
71
|
+
* [EXECUTOR: existing-agent] - ONLY if 100% capability match after thorough examination
|
|
72
|
+
* [EXECUTOR: specific-agent-name] - For all other tasks using existing or newly created agents
|
|
73
|
+
* Annotate all tasks with `[EXECUTOR: name]` and `[SEQUENTIAL]`/`[PARALLEL-GROUP-X]`
|
|
74
|
+
- **Step 4: Research Resolution**:
|
|
75
|
+
* Simple research: solve with agent tools (Grep, Read, WebSearch, Context7, Supabase docs)
|
|
76
|
+
* Complex research: create research prompt in research/, wait for user deepresearch, incorporate results
|
|
71
77
|
- Output: Updated tasks.md with executor annotations
|
|
72
78
|
- **Atomicity Rule (CRITICAL)**: 1 Task = 1 Agent Invocation
|
|
73
79
|
* Never give multiple tasks to one agent in single run
|
|
@@ -60,9 +60,10 @@ The tasks.md should be immediately executable - each task must be specific enoug
|
|
|
60
60
|
- **Complex**: Create research prompt in research/ → wait for deepresearch → incorporate
|
|
61
61
|
|
|
62
62
|
**Planning Phase**: After generating tasks, Phase 0: Planning will be added automatically by the template. This phase includes:
|
|
63
|
-
- **P001**:
|
|
64
|
-
- **P002**:
|
|
65
|
-
- **P003**:
|
|
63
|
+
- **P001**: Task analysis (identify required agent types and capabilities)
|
|
64
|
+
- **P002**: Agent creation via meta-agent-v3 in single message, then ask restart
|
|
65
|
+
- **P003**: Executor assignment (MAIN for trivial only, existing if 100% match, specific agents otherwise)
|
|
66
|
+
- **P004**: Research resolution (simple: solve now, complex: create prompts)
|
|
66
67
|
|
|
67
68
|
## Task Generation Rules
|
|
68
69
|
|
|
@@ -6,12 +6,24 @@
|
|
|
6
6
|
# Features:
|
|
7
7
|
# - Auto-syncs package.json versions with latest git tag (prevents version conflicts)
|
|
8
8
|
# - Auto-detects version bump from conventional commits
|
|
9
|
-
# - Generates CHANGELOG.md entries
|
|
9
|
+
# - Generates CHANGELOG.md entries with Keep a Changelog format
|
|
10
|
+
# - Supports security, deprecated, and removed categories
|
|
11
|
+
# - Safe rollback with file backups (no data loss on errors)
|
|
10
12
|
# - Rollback support for failed releases
|
|
11
13
|
#
|
|
12
14
|
# Usage: ./release.sh [patch|minor|major] [--yes]
|
|
13
15
|
# Leave empty for auto-detection from conventional commits
|
|
14
16
|
# --yes: Skip confirmation prompt (for automation)
|
|
17
|
+
#
|
|
18
|
+
# Supported conventional commit types:
|
|
19
|
+
# security: → Security section (patch version)
|
|
20
|
+
# feat: → Added section (minor version)
|
|
21
|
+
# fix: → Fixed section (patch version)
|
|
22
|
+
# deprecate: → Deprecated section
|
|
23
|
+
# remove: → Removed section
|
|
24
|
+
# refactor: → Changed section
|
|
25
|
+
# perf: → Changed section
|
|
26
|
+
# type!: → Breaking changes (major version)
|
|
15
27
|
|
|
16
28
|
set -euo pipefail
|
|
17
29
|
|
|
@@ -30,8 +42,8 @@ readonly NC='\033[0m' # No Color
|
|
|
30
42
|
# State tracking for rollback
|
|
31
43
|
CREATED_COMMIT=""
|
|
32
44
|
CREATED_TAG=""
|
|
33
|
-
STASH_CREATED=""
|
|
34
45
|
declare -a MODIFIED_FILES=()
|
|
46
|
+
declare -a BACKUP_FILES=() # Track backup files for safe rollback
|
|
35
47
|
|
|
36
48
|
# Commit categorization arrays
|
|
37
49
|
declare -a ALL_COMMITS=()
|
|
@@ -40,6 +52,9 @@ declare -a FIXES=()
|
|
|
40
52
|
declare -a BREAKING_CHANGES=()
|
|
41
53
|
declare -a REFACTORS=()
|
|
42
54
|
declare -a PERF=()
|
|
55
|
+
declare -a SECURITY_FIXES=() # Security vulnerability fixes
|
|
56
|
+
declare -a DEPRECATIONS=() # Deprecated features
|
|
57
|
+
declare -a REMOVALS=() # Removed features
|
|
43
58
|
declare -a OTHER_CHANGES=()
|
|
44
59
|
|
|
45
60
|
# === UTILITY FUNCTIONS ===
|
|
@@ -60,6 +75,53 @@ log_error() {
|
|
|
60
75
|
echo -e "${RED}❌ $*${NC}" >&2
|
|
61
76
|
}
|
|
62
77
|
|
|
78
|
+
# === BACKUP AND RESTORE ===
|
|
79
|
+
|
|
80
|
+
create_backup() {
|
|
81
|
+
local file="$1"
|
|
82
|
+
|
|
83
|
+
# Only create backup if file exists
|
|
84
|
+
if [ ! -f "$file" ]; then
|
|
85
|
+
return 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
local backup="${file}.backup.$$"
|
|
89
|
+
cp "$file" "$backup" || {
|
|
90
|
+
log_error "Failed to create backup of $file"
|
|
91
|
+
exit 1
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
BACKUP_FILES+=("$backup")
|
|
95
|
+
log_info "Created backup: ${backup##*/}"
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
restore_from_backups() {
|
|
99
|
+
if [ ${#BACKUP_FILES[@]} -eq 0 ]; then
|
|
100
|
+
return 0
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
log_info "Restoring files from backups..."
|
|
104
|
+
|
|
105
|
+
for backup in "${BACKUP_FILES[@]}"; do
|
|
106
|
+
# Extract original filename by removing .backup.$$ suffix
|
|
107
|
+
local original="${backup%.backup.*}"
|
|
108
|
+
|
|
109
|
+
if [ -f "$backup" ]; then
|
|
110
|
+
mv "$backup" "$original"
|
|
111
|
+
log_success "Restored: ${original##*/}"
|
|
112
|
+
fi
|
|
113
|
+
done
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
cleanup_backups() {
|
|
117
|
+
# Clean up backup files after successful release
|
|
118
|
+
for backup in "${BACKUP_FILES[@]}"; do
|
|
119
|
+
if [ -f "$backup" ]; then
|
|
120
|
+
rm -f "$backup"
|
|
121
|
+
fi
|
|
122
|
+
done
|
|
123
|
+
}
|
|
124
|
+
|
|
63
125
|
# === CLEANUP AND ROLLBACK ===
|
|
64
126
|
|
|
65
127
|
cleanup() {
|
|
@@ -83,28 +145,17 @@ cleanup() {
|
|
|
83
145
|
log_success "Rolled back commit (working directory preserved)"
|
|
84
146
|
fi
|
|
85
147
|
|
|
86
|
-
# Restore
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
git restore "${MODIFIED_FILES[@]}" 2>/dev/null || true
|
|
90
|
-
log_success "Restored modified package.json files"
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# Restore stash if we created one
|
|
94
|
-
if [ -n "$STASH_CREATED" ]; then
|
|
95
|
-
if git stash list | grep -q "release.sh: temporary stash"; then
|
|
96
|
-
git stash pop >/dev/null 2>&1 || {
|
|
97
|
-
log_warning "Stash pop failed with conflicts. Use 'git stash list' to see stashes."
|
|
98
|
-
log_info "Manually restore with: git stash pop"
|
|
99
|
-
}
|
|
100
|
-
fi
|
|
101
|
-
log_success "Stashed changes restored (or available in stash list)"
|
|
102
|
-
fi
|
|
148
|
+
# SAFE ROLLBACK: Restore from backups instead of git restore
|
|
149
|
+
# This preserves any manual edits made before running the script
|
|
150
|
+
restore_from_backups
|
|
103
151
|
|
|
104
152
|
echo ""
|
|
105
|
-
log_info "Rollback complete.
|
|
153
|
+
log_info "Rollback complete. Files restored from backups."
|
|
106
154
|
echo ""
|
|
107
155
|
exit $exit_code
|
|
156
|
+
else
|
|
157
|
+
# Success - clean up backup files
|
|
158
|
+
cleanup_backups
|
|
108
159
|
fi
|
|
109
160
|
}
|
|
110
161
|
|
|
@@ -132,15 +183,141 @@ run_preflight_checks() {
|
|
|
132
183
|
fi
|
|
133
184
|
log_success "On branch: $BRANCH"
|
|
134
185
|
|
|
135
|
-
#
|
|
186
|
+
# Auto-commit uncommitted changes before release
|
|
136
187
|
if ! git diff-index --quiet HEAD -- 2>/dev/null; then
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
188
|
+
log_info "Uncommitted changes detected. Auto-committing before release..."
|
|
189
|
+
|
|
190
|
+
# Get file counts by status
|
|
191
|
+
MODIFIED_COUNT=$(git diff --name-only | wc -l)
|
|
192
|
+
STAGED_COUNT=$(git diff --cached --name-only | wc -l)
|
|
193
|
+
UNTRACKED_COUNT=$(git ls-files --others --exclude-standard | wc -l)
|
|
194
|
+
TOTAL_COUNT=$((MODIFIED_COUNT + STAGED_COUNT + UNTRACKED_COUNT))
|
|
195
|
+
|
|
196
|
+
# Stage ALL changes (modified, deleted, new files)
|
|
197
|
+
git add -A
|
|
198
|
+
|
|
199
|
+
# Get detailed file list for commit body
|
|
200
|
+
FILE_LIST=$(git diff --cached --name-status | sed 's/^/ /')
|
|
201
|
+
|
|
202
|
+
# Detect commit type based on changed files
|
|
203
|
+
local commit_type="chore"
|
|
204
|
+
local commit_scope=""
|
|
205
|
+
local commit_desc="update project files"
|
|
206
|
+
|
|
207
|
+
# Get file changes with status (A=added, M=modified, D=deleted)
|
|
208
|
+
local file_status=$(git diff --cached --name-status)
|
|
209
|
+
|
|
210
|
+
# Count different types of changes
|
|
211
|
+
local new_agents=$(echo "$file_status" | grep "^A.*\.claude/agents/.*\.md$" | wc -l)
|
|
212
|
+
local new_skills=$(echo "$file_status" | grep "^A.*\.claude/skills/.*/SKILL\.md$" | wc -l)
|
|
213
|
+
local new_commands=$(echo "$file_status" | grep "^A.*\.claude/commands/.*\.md$" | wc -l)
|
|
214
|
+
local modified_agents=$(echo "$file_status" | grep "^M.*\.claude/agents/.*\.md$" | wc -l)
|
|
215
|
+
local modified_scripts=$(echo "$file_status" | grep "^M.*\.claude/scripts/.*\.sh$" | wc -l)
|
|
216
|
+
local modified_skills=$(echo "$file_status" | grep "^M.*\.claude/skills/.*/SKILL\.md$" | wc -l)
|
|
217
|
+
local modified_commands=$(echo "$file_status" | grep "^M.*\.claude/commands/.*\.md$" | wc -l)
|
|
218
|
+
local modified_docs=$(echo "$file_status" | grep "\.md$" | grep -v "\.claude/" | wc -l)
|
|
219
|
+
local modified_mcp=$(echo "$file_status" | grep "mcp/.*\.json$" | wc -l)
|
|
220
|
+
|
|
221
|
+
# Priority-based commit type detection (most specific first)
|
|
222
|
+
|
|
223
|
+
# 1. New agents (highest priority for features)
|
|
224
|
+
if [ "$new_agents" -gt 0 ]; then
|
|
225
|
+
commit_type="feat"
|
|
226
|
+
commit_scope="agents"
|
|
227
|
+
local agent_file=$(echo "$file_status" | grep "^A.*\.claude/agents/.*\.md$" | head -1 | awk '{print $2}')
|
|
228
|
+
local agent_name=$(basename "$agent_file" .md)
|
|
229
|
+
if [ "$new_agents" -eq 1 ]; then
|
|
230
|
+
commit_desc="add ${agent_name} agent"
|
|
231
|
+
else
|
|
232
|
+
commit_desc="add ${new_agents} new agents (${agent_name}, ...)"
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
# 2. New skills
|
|
236
|
+
elif [ "$new_skills" -gt 0 ]; then
|
|
237
|
+
commit_type="feat"
|
|
238
|
+
commit_scope="skills"
|
|
239
|
+
local skill_file=$(echo "$file_status" | grep "^A.*\.claude/skills/.*/SKILL\.md$" | head -1 | awk '{print $2}')
|
|
240
|
+
local skill_name=$(echo "$skill_file" | cut -d'/' -f4)
|
|
241
|
+
if [ "$new_skills" -eq 1 ]; then
|
|
242
|
+
commit_desc="add ${skill_name} skill"
|
|
243
|
+
else
|
|
244
|
+
commit_desc="add ${new_skills} new skills (${skill_name}, ...)"
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# 3. New commands
|
|
248
|
+
elif [ "$new_commands" -gt 0 ]; then
|
|
249
|
+
commit_type="feat"
|
|
250
|
+
commit_scope="commands"
|
|
251
|
+
local cmd_file=$(echo "$file_status" | grep "^A.*\.claude/commands/.*\.md$" | head -1 | awk '{print $2}')
|
|
252
|
+
local cmd_name=$(basename "$cmd_file" .md)
|
|
253
|
+
if [ "$new_commands" -eq 1 ]; then
|
|
254
|
+
commit_desc="add ${cmd_name} command"
|
|
255
|
+
else
|
|
256
|
+
commit_desc="add ${new_commands} new commands"
|
|
257
|
+
fi
|
|
258
|
+
|
|
259
|
+
# 4. Modified skills (features)
|
|
260
|
+
elif [ "$modified_skills" -gt 0 ]; then
|
|
261
|
+
commit_type="feat"
|
|
262
|
+
commit_scope="skills"
|
|
263
|
+
commit_desc="update skill implementations"
|
|
264
|
+
|
|
265
|
+
# 5. Modified commands (features)
|
|
266
|
+
elif [ "$modified_commands" -gt 0 ]; then
|
|
267
|
+
commit_type="feat"
|
|
268
|
+
commit_scope="commands"
|
|
269
|
+
commit_desc="update slash commands"
|
|
270
|
+
|
|
271
|
+
# 6. Modified scripts (chore)
|
|
272
|
+
elif [ "$modified_scripts" -gt 0 ]; then
|
|
273
|
+
commit_type="chore"
|
|
274
|
+
commit_scope="scripts"
|
|
275
|
+
commit_desc="update automation scripts"
|
|
276
|
+
|
|
277
|
+
# 7. Modified agents (chore)
|
|
278
|
+
elif [ "$modified_agents" -gt 0 ]; then
|
|
279
|
+
commit_type="chore"
|
|
280
|
+
commit_scope="agents"
|
|
281
|
+
commit_desc="update agent configurations"
|
|
282
|
+
|
|
283
|
+
# 8. Modified MCP configs (chore)
|
|
284
|
+
elif [ "$modified_mcp" -gt 0 ]; then
|
|
285
|
+
commit_type="chore"
|
|
286
|
+
commit_scope="mcp"
|
|
287
|
+
commit_desc="update MCP server configurations"
|
|
288
|
+
|
|
289
|
+
# 9. Documentation changes
|
|
290
|
+
elif [ "$modified_docs" -gt 0 ]; then
|
|
291
|
+
commit_type="docs"
|
|
292
|
+
commit_desc="update documentation"
|
|
293
|
+
fi
|
|
294
|
+
|
|
295
|
+
# Generate commit message with detected type
|
|
296
|
+
if [ -n "$commit_scope" ]; then
|
|
297
|
+
COMMIT_MSG="${commit_type}(${commit_scope}): ${commit_desc}"
|
|
298
|
+
else
|
|
299
|
+
COMMIT_MSG="${commit_type}: ${commit_desc}"
|
|
300
|
+
fi
|
|
301
|
+
|
|
302
|
+
COMMIT_MSG="${COMMIT_MSG}
|
|
303
|
+
|
|
304
|
+
Auto-committed ${TOTAL_COUNT} file(s) before creating release.
|
|
305
|
+
|
|
306
|
+
Files changed:
|
|
307
|
+
${FILE_LIST}
|
|
308
|
+
|
|
309
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
310
|
+
|
|
311
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
312
|
+
|
|
313
|
+
# Create commit
|
|
314
|
+
git commit -m "$COMMIT_MSG" >/dev/null 2>&1 || {
|
|
315
|
+
log_error "Failed to auto-commit changes"
|
|
140
316
|
exit 1
|
|
141
317
|
}
|
|
142
|
-
|
|
143
|
-
log_success "Changes
|
|
318
|
+
|
|
319
|
+
log_success "Changes committed (${TOTAL_COUNT} files)"
|
|
320
|
+
log_info "Commit type: ${commit_type}${commit_scope:+(${commit_scope})}: ${commit_desc}"
|
|
144
321
|
fi
|
|
145
322
|
|
|
146
323
|
# Check if remote is configured
|
|
@@ -226,6 +403,9 @@ parse_commits() {
|
|
|
226
403
|
local fix_pattern='^fix(\([^)]+\))?:'
|
|
227
404
|
local refactor_pattern='^refactor(\([^)]+\))?:'
|
|
228
405
|
local perf_pattern='^perf(\([^)]+\))?:'
|
|
406
|
+
local security_pattern='^security(\([^)]+\))?:'
|
|
407
|
+
local deprecate_pattern='^deprecate(\([^)]+\))?:'
|
|
408
|
+
local remove_pattern='^remove(\([^)]+\))?:'
|
|
229
409
|
|
|
230
410
|
for commit in "${ALL_COMMITS[@]}"; do
|
|
231
411
|
local hash=$(echo "$commit" | awk '{print $1}')
|
|
@@ -234,12 +414,21 @@ parse_commits() {
|
|
|
234
414
|
# Check for breaking changes
|
|
235
415
|
if [[ "$message" =~ $breaking_pattern ]] || echo "$message" | grep -q "BREAKING CHANGE:"; then
|
|
236
416
|
BREAKING_CHANGES+=("$commit")
|
|
417
|
+
# Check for security fixes (high priority!)
|
|
418
|
+
elif [[ "$message" =~ $security_pattern ]]; then
|
|
419
|
+
SECURITY_FIXES+=("$commit")
|
|
237
420
|
# Check for features
|
|
238
421
|
elif [[ "$message" =~ $feat_pattern ]]; then
|
|
239
422
|
FEATURES+=("$commit")
|
|
240
423
|
# Check for fixes
|
|
241
424
|
elif [[ "$message" =~ $fix_pattern ]]; then
|
|
242
425
|
FIXES+=("$commit")
|
|
426
|
+
# Check for deprecations
|
|
427
|
+
elif [[ "$message" =~ $deprecate_pattern ]]; then
|
|
428
|
+
DEPRECATIONS+=("$commit")
|
|
429
|
+
# Check for removals
|
|
430
|
+
elif [[ "$message" =~ $remove_pattern ]]; then
|
|
431
|
+
REMOVALS+=("$commit")
|
|
243
432
|
# Check for refactors
|
|
244
433
|
elif [[ "$message" =~ $refactor_pattern ]]; then
|
|
245
434
|
REFACTORS+=("$commit")
|
|
@@ -255,8 +444,11 @@ parse_commits() {
|
|
|
255
444
|
# Display commit summary
|
|
256
445
|
log_info "Commit summary:"
|
|
257
446
|
[ ${#BREAKING_CHANGES[@]} -gt 0 ] && echo " 🔥 ${#BREAKING_CHANGES[@]} breaking changes"
|
|
447
|
+
[ ${#SECURITY_FIXES[@]} -gt 0 ] && echo " 🔒 ${#SECURITY_FIXES[@]} security fixes"
|
|
258
448
|
[ ${#FEATURES[@]} -gt 0 ] && echo " ✨ ${#FEATURES[@]} features"
|
|
259
449
|
[ ${#FIXES[@]} -gt 0 ] && echo " 🐛 ${#FIXES[@]} bug fixes"
|
|
450
|
+
[ ${#DEPRECATIONS[@]} -gt 0 ] && echo " ⚠️ ${#DEPRECATIONS[@]} deprecations"
|
|
451
|
+
[ ${#REMOVALS[@]} -gt 0 ] && echo " 🗑️ ${#REMOVALS[@]} removals"
|
|
260
452
|
[ ${#REFACTORS[@]} -gt 0 ] && echo " ♻️ ${#REFACTORS[@]} refactors"
|
|
261
453
|
[ ${#PERF[@]} -gt 0 ] && echo " ⚡ ${#PERF[@]} performance improvements"
|
|
262
454
|
[ ${#OTHER_CHANGES[@]} -gt 0 ] && echo " 📝 ${#OTHER_CHANGES[@]} other changes"
|
|
@@ -286,6 +478,9 @@ detect_version_bump() {
|
|
|
286
478
|
elif [ ${#FEATURES[@]} -gt 0 ]; then
|
|
287
479
|
BUMP_TYPE="minor"
|
|
288
480
|
AUTO_DETECT_REASON="Found ${#FEATURES[@]} new feature(s)"
|
|
481
|
+
elif [ ${#SECURITY_FIXES[@]} -gt 0 ]; then
|
|
482
|
+
BUMP_TYPE="patch"
|
|
483
|
+
AUTO_DETECT_REASON="Found ${#SECURITY_FIXES[@]} security fix(es)"
|
|
289
484
|
elif [ ${#FIXES[@]} -gt 0 ]; then
|
|
290
485
|
BUMP_TYPE="patch"
|
|
291
486
|
AUTO_DETECT_REASON="Found ${#FIXES[@]} bug fix(es)"
|
|
@@ -338,6 +533,15 @@ generate_changelog_entry() {
|
|
|
338
533
|
|
|
339
534
|
EOF
|
|
340
535
|
|
|
536
|
+
# Security section (FIRST - highest priority!)
|
|
537
|
+
if [ ${#SECURITY_FIXES[@]} -gt 0 ]; then
|
|
538
|
+
echo "### Security"
|
|
539
|
+
for commit in "${SECURITY_FIXES[@]}"; do
|
|
540
|
+
format_changelog_line "$commit"
|
|
541
|
+
done
|
|
542
|
+
echo ""
|
|
543
|
+
fi
|
|
544
|
+
|
|
341
545
|
# Added section (features)
|
|
342
546
|
if [ ${#FEATURES[@]} -gt 0 ]; then
|
|
343
547
|
echo "### Added"
|
|
@@ -362,6 +566,24 @@ EOF
|
|
|
362
566
|
echo ""
|
|
363
567
|
fi
|
|
364
568
|
|
|
569
|
+
# Deprecated section
|
|
570
|
+
if [ ${#DEPRECATIONS[@]} -gt 0 ]; then
|
|
571
|
+
echo "### Deprecated"
|
|
572
|
+
for commit in "${DEPRECATIONS[@]}"; do
|
|
573
|
+
format_changelog_line "$commit"
|
|
574
|
+
done
|
|
575
|
+
echo ""
|
|
576
|
+
fi
|
|
577
|
+
|
|
578
|
+
# Removed section
|
|
579
|
+
if [ ${#REMOVALS[@]} -gt 0 ]; then
|
|
580
|
+
echo "### Removed"
|
|
581
|
+
for commit in "${REMOVALS[@]}"; do
|
|
582
|
+
format_changelog_line "$commit"
|
|
583
|
+
done
|
|
584
|
+
echo ""
|
|
585
|
+
fi
|
|
586
|
+
|
|
365
587
|
# Fixed section
|
|
366
588
|
if [ ${#FIXES[@]} -gt 0 ]; then
|
|
367
589
|
echo "### Fixed"
|
|
@@ -414,6 +636,9 @@ update_package_files() {
|
|
|
414
636
|
|
|
415
637
|
while IFS= read -r pkg; do
|
|
416
638
|
if [ -n "$pkg" ]; then
|
|
639
|
+
# Create backup BEFORE modifying
|
|
640
|
+
create_backup "$pkg"
|
|
641
|
+
|
|
417
642
|
# Track for rollback
|
|
418
643
|
MODIFIED_FILES+=("$pkg")
|
|
419
644
|
|
|
@@ -448,6 +673,9 @@ update_changelog() {
|
|
|
448
673
|
|
|
449
674
|
local changelog_file="$PROJECT_ROOT/CHANGELOG.md"
|
|
450
675
|
|
|
676
|
+
# Create backup BEFORE modifying
|
|
677
|
+
create_backup "$changelog_file"
|
|
678
|
+
|
|
451
679
|
# Track for rollback
|
|
452
680
|
MODIFIED_FILES+=("$changelog_file")
|
|
453
681
|
|
|
@@ -514,8 +742,11 @@ show_preview() {
|
|
|
514
742
|
EOF
|
|
515
743
|
|
|
516
744
|
[ ${#BREAKING_CHANGES[@]} -gt 0 ] && echo " 🔥 ${#BREAKING_CHANGES[@]} breaking changes"
|
|
745
|
+
[ ${#SECURITY_FIXES[@]} -gt 0 ] && echo " 🔒 ${#SECURITY_FIXES[@]} security fixes"
|
|
517
746
|
[ ${#FEATURES[@]} -gt 0 ] && echo " ✨ ${#FEATURES[@]} features"
|
|
518
747
|
[ ${#FIXES[@]} -gt 0 ] && echo " 🐛 ${#FIXES[@]} bug fixes"
|
|
748
|
+
[ ${#DEPRECATIONS[@]} -gt 0 ] && echo " ⚠️ ${#DEPRECATIONS[@]} deprecations"
|
|
749
|
+
[ ${#REMOVALS[@]} -gt 0 ] && echo " 🗑️ ${#REMOVALS[@]} removals"
|
|
519
750
|
[ ${#REFACTORS[@]} -gt 0 ] && echo " ♻️ ${#REFACTORS[@]} refactors"
|
|
520
751
|
[ ${#PERF[@]} -gt 0 ] && echo " ⚡ ${#PERF[@]} performance improvements"
|
|
521
752
|
[ ${#OTHER_CHANGES[@]} -gt 0 ] && echo " 📝 ${#OTHER_CHANGES[@]} other changes"
|
|
@@ -591,6 +822,9 @@ execute_release() {
|
|
|
591
822
|
log_info "Executing release..."
|
|
592
823
|
echo ""
|
|
593
824
|
|
|
825
|
+
# Clean up backup files BEFORE staging
|
|
826
|
+
cleanup_backups
|
|
827
|
+
|
|
594
828
|
# Stage all changes
|
|
595
829
|
log_info "Staging changes..."
|
|
596
830
|
git add -A
|
|
@@ -706,17 +940,6 @@ main() {
|
|
|
706
940
|
update_changelog "$NEW_VERSION" "$DATE"
|
|
707
941
|
execute_release
|
|
708
942
|
|
|
709
|
-
# Success! Restore stash if created
|
|
710
|
-
if [ -n "$STASH_CREATED" ]; then
|
|
711
|
-
log_info "Restoring stashed changes..."
|
|
712
|
-
if git stash list | grep -q "release.sh: temporary stash"; then
|
|
713
|
-
git stash pop >/dev/null 2>&1 || {
|
|
714
|
-
log_warning "Stash pop had conflicts. Check 'git stash list'"
|
|
715
|
-
log_info "Manually restore with: git stash pop"
|
|
716
|
-
}
|
|
717
|
-
fi
|
|
718
|
-
fi
|
|
719
|
-
|
|
720
943
|
echo ""
|
|
721
944
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
|
722
945
|
echo "║ RELEASE SUCCESSFUL! 🎉 ║"
|
|
@@ -725,9 +948,6 @@ main() {
|
|
|
725
948
|
log_success "Released v$NEW_VERSION"
|
|
726
949
|
log_success "Tag: v$NEW_VERSION"
|
|
727
950
|
log_success "Branch: $BRANCH"
|
|
728
|
-
if [ -n "$STASH_CREATED" ]; then
|
|
729
|
-
log_success "Stashed changes restored"
|
|
730
|
-
fi
|
|
731
951
|
echo ""
|
|
732
952
|
log_info "Next steps:"
|
|
733
953
|
echo " • Verify release on GitHub: git remote -v"
|