@atlashub/smartstack-cli 1.34.0 → 1.36.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/.documentation/installation.html +56 -31
- package/dist/index.js +1098 -582
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/docs-context-reader.md +125 -0
- package/templates/agents/docs-sync-checker.md +122 -0
- package/templates/hooks/docs-drift-check.md +97 -0
- package/templates/skills/_resources/context-digest-template.md +53 -0
- package/templates/skills/_resources/doc-context-cache.md +62 -0
- package/templates/skills/_resources/docs-manifest-schema.md +157 -0
- package/templates/skills/_resources/mcp-validate-documentation-spec.md +183 -0
- package/templates/skills/_shared.md +15 -7
- package/templates/skills/apex/SKILL.md +6 -0
- package/templates/skills/apex/steps/step-00-init.md +9 -0
- package/templates/skills/apex/steps/step-01-analyze.md +36 -0
- package/templates/skills/apex/steps/step-02-plan.md +38 -0
- package/templates/skills/apex/steps/step-03-execute.md +39 -0
- package/templates/skills/apex/steps/step-04-validate.md +31 -1
- package/templates/skills/apex/steps/step-04b-doc-sync.md +162 -0
- package/templates/skills/apex/steps/step-05-examine.md +7 -0
- package/templates/skills/apex/templates/04b-doc-sync.md +31 -0
- package/templates/skills/apex/templates/context-digest.md +35 -0
- package/templates/skills/application/steps/step-04-backend.md +17 -17
- package/templates/skills/application/steps/step-05-frontend.md +4 -1
- package/templates/skills/application/templates-backend.md +8 -8
- package/templates/skills/application/templates-frontend.md +8 -8
- package/templates/skills/business-analyse/SKILL.md +18 -5
- package/templates/skills/business-analyse/_shared.md +306 -4
- package/templates/skills/business-analyse/questionnaire/01-context.md +21 -6
- package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +34 -0
- package/templates/skills/business-analyse/questionnaire/03-scope.md +23 -0
- package/templates/skills/business-analyse/questionnaire/04-data.md +44 -0
- package/templates/skills/business-analyse/questionnaire/05-integrations.md +29 -7
- package/templates/skills/business-analyse/questionnaire/06-security.md +28 -0
- package/templates/skills/business-analyse/questionnaire/07-ui.md +32 -7
- package/templates/skills/business-analyse/questionnaire/08-performance.md +21 -0
- package/templates/skills/business-analyse/questionnaire/09-constraints.md +29 -6
- package/templates/skills/business-analyse/questionnaire/10-documentation.md +27 -6
- package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +59 -0
- package/templates/skills/business-analyse/questionnaire/12-migration.md +58 -0
- package/templates/skills/business-analyse/questionnaire/13-cross-module.md +69 -0
- package/templates/skills/business-analyse/steps/step-00-init.md +110 -16
- package/templates/skills/business-analyse/steps/step-01-discover.md +530 -85
- package/templates/skills/business-analyse/steps/step-02-analyse.md +81 -25
- package/templates/skills/business-analyse/steps/step-03-specify.md +116 -24
- package/templates/skills/business-analyse/steps/step-04-validate.md +107 -33
- package/templates/skills/business-analyse/steps/step-05-handoff.md +256 -33
- package/templates/skills/business-analyse/steps/step-06-doc-html.md +84 -25
- package/templates/skills/business-analyse/templates/{frd-handoff.md → tpl-handoff.md} +18 -4
- package/templates/skills/business-analyse/templates-frd.md +19 -5
- package/templates/skills/business-analyse/tracking/change-template.md +30 -0
- package/templates/skills/documentation/SKILL.md +68 -31
- package/templates/skills/documentation/data-schema.md +198 -0
- package/templates/skills/documentation/templates.md +30 -1
- package/templates/skills/gitflow/_shared.md +188 -53
- package/templates/skills/gitflow/phases/abort.md +28 -16
- package/templates/skills/gitflow/phases/cleanup.md +13 -9
- package/templates/skills/gitflow/phases/status.md +16 -17
- package/templates/skills/gitflow/steps/step-commit.md +11 -5
- package/templates/skills/gitflow/steps/step-finish.md +43 -33
- package/templates/skills/gitflow/steps/step-init.md +134 -2
- package/templates/skills/gitflow/steps/step-merge.md +24 -10
- package/templates/skills/gitflow/steps/step-pr.md +42 -28
- package/templates/skills/gitflow/steps/step-start.md +19 -13
- package/templates/skills/gitflow/templates/config.json +14 -4
- package/templates/skills/ralph-loop/SKILL.md +58 -9
- package/templates/skills/ralph-loop/steps/step-00-init.md +170 -30
- package/templates/skills/ralph-loop/steps/step-01-task.md +243 -40
- package/templates/skills/ralph-loop/steps/step-02-execute.md +142 -24
- package/templates/skills/ralph-loop/steps/step-03-commit.md +140 -36
- package/templates/skills/ralph-loop/steps/step-04-check.md +128 -44
- package/templates/skills/ralph-loop/steps/step-05-report.md +175 -88
- /package/templates/skills/business-analyse/templates/{frd-brd.md → tpl-brd.md} +0 -0
- /package/templates/skills/business-analyse/templates/{frd-discovery.md → tpl-discovery.md} +0 -0
- /package/templates/skills/business-analyse/templates/{frd-spec.md → tpl-frd.md} +0 -0
|
@@ -11,6 +11,13 @@ Provide rollback and recovery options for GitFlow operations.
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## PRE-CHECK:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Load GitFlow config (sets GF_* variables)
|
|
18
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
19
|
+
```
|
|
20
|
+
|
|
14
21
|
## OPTIONS:
|
|
15
22
|
|
|
16
23
|
```yaml
|
|
@@ -23,7 +30,7 @@ AskUserQuestion:
|
|
|
23
30
|
- label: "Abandon current branch"
|
|
24
31
|
description: "Delete branch and worktree, return to develop"
|
|
25
32
|
- label: "Restore from checkpoint"
|
|
26
|
-
description: "Restore to a saved checkpoint"
|
|
33
|
+
description: "Restore to a saved checkpoint (not yet implemented)"
|
|
27
34
|
- label: "Reset branch to remote"
|
|
28
35
|
description: "Discard local changes, match remote"
|
|
29
36
|
```
|
|
@@ -69,7 +76,7 @@ git tag "$BACKUP_TAG" HEAD
|
|
|
69
76
|
echo "✓ Backup created: $BACKUP_TAG"
|
|
70
77
|
|
|
71
78
|
# Switch to develop
|
|
72
|
-
git checkout
|
|
79
|
+
git checkout $GF_DEVELOP_BRANCH
|
|
73
80
|
|
|
74
81
|
# Remove worktree
|
|
75
82
|
[ -n "$WORKTREE" ] && {
|
|
@@ -87,30 +94,35 @@ echo " Backup: $BACKUP_TAG (use 'git checkout $BACKUP_TAG' to recover)"
|
|
|
87
94
|
|
|
88
95
|
### Option 3: Restore from Checkpoint
|
|
89
96
|
|
|
97
|
+
> **Note:** Checkpoint creation is not yet implemented. This option uses backup tags
|
|
98
|
+
> created by abort operations as a recovery mechanism. Full checkpoint support
|
|
99
|
+
> (automatic state snapshots during plan execution) is planned for a future release.
|
|
100
|
+
|
|
90
101
|
```bash
|
|
91
|
-
# List available
|
|
92
|
-
|
|
102
|
+
# List available backup tags (created by abandon operations)
|
|
103
|
+
BACKUPS=$(git tag -l "backup/*" --sort=-creatordate 2>/dev/null)
|
|
93
104
|
|
|
94
|
-
if [ -z "$
|
|
95
|
-
echo "No
|
|
105
|
+
if [ -z "$BACKUPS" ]; then
|
|
106
|
+
echo "No backup tags found"
|
|
107
|
+
echo " Backup tags are created automatically when abandoning branches."
|
|
108
|
+
echo " Use 'Reset branch to remote' instead."
|
|
96
109
|
exit 1
|
|
97
110
|
fi
|
|
98
111
|
|
|
99
|
-
echo "Available
|
|
100
|
-
for
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
echo " - $TIMESTAMP: $BRANCH @ $COMMIT"
|
|
112
|
+
echo "Available backups:"
|
|
113
|
+
for tag in $BACKUPS; do
|
|
114
|
+
COMMIT=$(git rev-parse --short "$tag")
|
|
115
|
+
DATE=$(git log -1 --format=%ci "$tag" 2>/dev/null)
|
|
116
|
+
echo " - $tag → $COMMIT ($DATE)"
|
|
105
117
|
done
|
|
106
118
|
|
|
107
|
-
# Select
|
|
119
|
+
# Select backup
|
|
108
120
|
# ... user selection ...
|
|
109
121
|
|
|
110
122
|
# Restore
|
|
111
|
-
|
|
112
|
-
git
|
|
113
|
-
echo "✓ Restored to
|
|
123
|
+
git checkout "$SELECTED_TAG"
|
|
124
|
+
git checkout -b "recovered-$(date +%Y%m%d-%H%M%S)"
|
|
125
|
+
echo "✓ Restored from $SELECTED_TAG to new branch"
|
|
114
126
|
```
|
|
115
127
|
|
|
116
128
|
### Option 4: Reset to Remote
|
|
@@ -16,12 +16,15 @@ Audit worktrees and branches, remove orphaned/stale items.
|
|
|
16
16
|
## PRE-CHECK:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
+
# Load GitFlow config (sets GF_* variables)
|
|
20
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
21
|
+
|
|
19
22
|
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
20
23
|
|
|
21
|
-
[[ "$CURRENT" != "
|
|
22
|
-
echo "❌ Cleanup must be run from
|
|
24
|
+
[[ "$CURRENT" != "$GF_MAIN_BRANCH" ]] && [[ "$CURRENT" != "$GF_DEVELOP_BRANCH" ]] && {
|
|
25
|
+
echo "❌ Cleanup must be run from $GF_MAIN_BRANCH or $GF_DEVELOP_BRANCH"
|
|
23
26
|
echo " Current branch: $CURRENT"
|
|
24
|
-
echo "→ Run: git checkout
|
|
27
|
+
echo "→ Run: git checkout $GF_DEVELOP_BRANCH"
|
|
25
28
|
STOP
|
|
26
29
|
}
|
|
27
30
|
```
|
|
@@ -35,7 +38,8 @@ CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
|
35
38
|
```bash
|
|
36
39
|
echo "Scanning worktrees..."
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
mkdir -p .claude/gitflow/cache
|
|
42
|
+
git worktree list > .claude/gitflow/cache/worktrees.txt
|
|
39
43
|
|
|
40
44
|
ORPHANED=()
|
|
41
45
|
STALE=()
|
|
@@ -54,13 +58,13 @@ while read -r line; do
|
|
|
54
58
|
|
|
55
59
|
# Check if branch still exists on remote
|
|
56
60
|
REMOTE_EXISTS=$(git branch -r --list "origin/$WT_BRANCH" | wc -l)
|
|
57
|
-
if [ "$REMOTE_EXISTS" -eq 0 ] && [[ "$WT_BRANCH" != "
|
|
61
|
+
if [ "$REMOTE_EXISTS" -eq 0 ] && [[ "$WT_BRANCH" != "$GF_MAIN_BRANCH" ]] && [[ "$WT_BRANCH" != "$GF_DEVELOP_BRANCH" ]]; then
|
|
58
62
|
STALE+=("$WT_PATH:$WT_BRANCH")
|
|
59
63
|
continue
|
|
60
64
|
fi
|
|
61
65
|
|
|
62
66
|
VALID+=("$WT_PATH:$WT_BRANCH")
|
|
63
|
-
done < /
|
|
67
|
+
done < .claude/gitflow/cache/worktrees.txt
|
|
64
68
|
```
|
|
65
69
|
|
|
66
70
|
### 2. Audit Local Branches
|
|
@@ -72,17 +76,17 @@ MERGED_BRANCHES=()
|
|
|
72
76
|
UNMERGED_BRANCHES=()
|
|
73
77
|
|
|
74
78
|
# Find merged branches
|
|
75
|
-
for branch in $(git branch --merged
|
|
79
|
+
for branch in $(git branch --merged $GF_DEVELOP_BRANCH | grep -v "^\*" | grep -v "$GF_MAIN_BRANCH" | grep -v "$GF_DEVELOP_BRANCH"); do
|
|
76
80
|
# Check if remote exists
|
|
77
81
|
REMOTE_EXISTS=$(git branch -r --list "origin/$branch" | wc -l)
|
|
78
82
|
[ "$REMOTE_EXISTS" -eq 0 ] && MERGED_BRANCHES+=("$branch")
|
|
79
83
|
done
|
|
80
84
|
|
|
81
85
|
# Find branches without remote
|
|
82
|
-
for branch in $(git branch | grep -v "^\*" | grep -v "
|
|
86
|
+
for branch in $(git branch | grep -v "^\*" | grep -v "$GF_MAIN_BRANCH" | grep -v "$GF_DEVELOP_BRANCH"); do
|
|
83
87
|
REMOTE_EXISTS=$(git branch -r --list "origin/$branch" | wc -l)
|
|
84
88
|
[ "$REMOTE_EXISTS" -eq 0 ] && {
|
|
85
|
-
MERGED=$(git branch --merged
|
|
89
|
+
MERGED=$(git branch --merged $GF_DEVELOP_BRANCH | grep -c "$branch")
|
|
86
90
|
[ "$MERGED" -eq 0 ] && UNMERGED_BRANCHES+=("$branch")
|
|
87
91
|
}
|
|
88
92
|
done
|
|
@@ -13,16 +13,15 @@ Display complete GitFlow state including branches, worktrees, remotes, and pendi
|
|
|
13
13
|
|
|
14
14
|
## EXECUTION:
|
|
15
15
|
|
|
16
|
-
### 1. Repository Info
|
|
16
|
+
### 1. Load Config and Repository Info
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "No remote")
|
|
19
|
+
# Load GitFlow config (sets GF_* variables)
|
|
20
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
REPO_NAME="$GF_PROJECT_NAME"
|
|
23
|
+
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
24
|
+
GIT_PROVIDER="$GF_PROVIDER"
|
|
26
25
|
```
|
|
27
26
|
|
|
28
27
|
### 2. Branch Status
|
|
@@ -30,27 +29,27 @@ REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "No remote")
|
|
|
30
29
|
```bash
|
|
31
30
|
git fetch origin --quiet
|
|
32
31
|
|
|
33
|
-
# Main branches
|
|
34
|
-
MAIN_LOCAL=$(git rev-parse --short
|
|
35
|
-
MAIN_REMOTE=$(git rev-parse --short origin
|
|
36
|
-
DEVELOP_LOCAL=$(git rev-parse --short
|
|
37
|
-
DEVELOP_REMOTE=$(git rev-parse --short origin
|
|
32
|
+
# Main branches (from config)
|
|
33
|
+
MAIN_LOCAL=$(git rev-parse --short $GF_MAIN_BRANCH 2>/dev/null || echo "N/A")
|
|
34
|
+
MAIN_REMOTE=$(git rev-parse --short origin/$GF_MAIN_BRANCH 2>/dev/null || echo "N/A")
|
|
35
|
+
DEVELOP_LOCAL=$(git rev-parse --short $GF_DEVELOP_BRANCH 2>/dev/null || echo "N/A")
|
|
36
|
+
DEVELOP_REMOTE=$(git rev-parse --short origin/$GF_DEVELOP_BRANCH 2>/dev/null || echo "N/A")
|
|
38
37
|
|
|
39
38
|
# Divergence
|
|
40
|
-
DEVELOP_AHEAD=$(git rev-list --count origin
|
|
39
|
+
DEVELOP_AHEAD=$(git rev-list --count origin/$GF_MAIN_BRANCH..origin/$GF_DEVELOP_BRANCH 2>/dev/null || echo "0")
|
|
41
40
|
```
|
|
42
41
|
|
|
43
42
|
### 3. Active Branches
|
|
44
43
|
|
|
45
44
|
```bash
|
|
46
|
-
# Feature branches
|
|
47
|
-
FEATURES=$(git branch -r | grep "origin
|
|
45
|
+
# Feature branches (using prefixes from config)
|
|
46
|
+
FEATURES=$(git branch -r | grep "origin/${GF_FEATURE_PREFIX}" | sed 's/origin\///')
|
|
48
47
|
|
|
49
48
|
# Release branches
|
|
50
|
-
RELEASES=$(git branch -r | grep "origin
|
|
49
|
+
RELEASES=$(git branch -r | grep "origin/${GF_RELEASE_PREFIX}" | sed 's/origin\///')
|
|
51
50
|
|
|
52
51
|
# Hotfix branches
|
|
53
|
-
HOTFIXES=$(git branch -r | grep "origin
|
|
52
|
+
HOTFIXES=$(git branch -r | grep "origin/${GF_HOTFIX_PREFIX}" | sed 's/origin\///')
|
|
54
53
|
```
|
|
55
54
|
|
|
56
55
|
### 4. Worktree Status
|
|
@@ -28,20 +28,26 @@ Validate changes, check EF Core migrations, and create commit with proper messag
|
|
|
28
28
|
|
|
29
29
|
### 0. Pre-commit Guards
|
|
30
30
|
|
|
31
|
+
**0.0 Load Config:**
|
|
32
|
+
```bash
|
|
33
|
+
# Load GitFlow config (sets GF_* variables)
|
|
34
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
35
|
+
```
|
|
36
|
+
|
|
31
37
|
**0.1 Branch Protection:**
|
|
32
38
|
```bash
|
|
33
39
|
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
34
40
|
|
|
35
41
|
# BLOCK: main
|
|
36
|
-
[[ "$CURRENT" == "
|
|
37
|
-
echo "⛔ COMMIT BLOCKED -
|
|
42
|
+
[[ "$CURRENT" == "$GF_MAIN_BRANCH" ]] && {
|
|
43
|
+
echo "⛔ COMMIT BLOCKED - $GF_MAIN_BRANCH is protected"
|
|
38
44
|
echo "→ Use: /gitflow start hotfix <name>"
|
|
39
45
|
STOP
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
# WARNING: develop
|
|
43
|
-
[[ "$CURRENT" == "
|
|
44
|
-
echo "⚠️ Direct commits to
|
|
49
|
+
[[ "$CURRENT" == "$GF_DEVELOP_BRANCH" ]] && {
|
|
50
|
+
echo "⚠️ Direct commits to $GF_DEVELOP_BRANCH are discouraged"
|
|
45
51
|
# Offer RESCUE TO FEATURE
|
|
46
52
|
}
|
|
47
53
|
```
|
|
@@ -52,7 +58,7 @@ git fetch origin --quiet
|
|
|
52
58
|
STAGED=$(git diff --cached --name-only | wc -l)
|
|
53
59
|
MODIFIED=$(git diff --name-only | wc -l)
|
|
54
60
|
UNTRACKED=$(git ls-files --others --exclude-standard | wc -l)
|
|
55
|
-
LOCAL_COMMITS=$(git rev-list --count origin
|
|
61
|
+
LOCAL_COMMITS=$(git rev-list --count origin/$GF_DEVELOP_BRANCH..HEAD 2>/dev/null || echo "0")
|
|
56
62
|
|
|
57
63
|
# If there are changes or commits, offer rescue
|
|
58
64
|
[ "$STAGED" -gt 0 ] || [ "$MODIFIED" -gt 0 ] || [ "$LOCAL_COMMITS" -gt 0 ] && {
|
|
@@ -16,9 +16,12 @@ Create tags for releases/hotfixes, merge back to develop, clean up worktree and
|
|
|
16
16
|
|
|
17
17
|
## EXECUTION SEQUENCE:
|
|
18
18
|
|
|
19
|
-
### 1. Determine Branch Context
|
|
19
|
+
### 1. Load Config and Determine Branch Context
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
+
# Load GitFlow config (sets GF_* variables)
|
|
23
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
24
|
+
|
|
22
25
|
# Get current or specified branch
|
|
23
26
|
BRANCH=${1:-$(git rev-parse --abbrev-ref HEAD)}
|
|
24
27
|
BRANCH_TYPE=$(echo $BRANCH | cut -d'/' -f1)
|
|
@@ -27,8 +30,8 @@ BRANCH_NAME=$(echo $BRANCH | cut -d'/' -f2)
|
|
|
27
30
|
# Validate branch type
|
|
28
31
|
case "$BRANCH_TYPE" in
|
|
29
32
|
feature|release|hotfix) ;;
|
|
30
|
-
|
|
31
|
-
echo "❌ Cannot finish
|
|
33
|
+
$GF_MAIN_BRANCH|$GF_DEVELOP_BRANCH)
|
|
34
|
+
echo "❌ Cannot finish $GF_MAIN_BRANCH or $GF_DEVELOP_BRANCH branch"
|
|
32
35
|
STOP
|
|
33
36
|
;;
|
|
34
37
|
*)
|
|
@@ -46,12 +49,12 @@ git fetch origin
|
|
|
46
49
|
# Check if branch was merged
|
|
47
50
|
case "$BRANCH_TYPE" in
|
|
48
51
|
feature)
|
|
49
|
-
MERGED=$(git branch -r --merged origin
|
|
50
|
-
TARGET="
|
|
52
|
+
MERGED=$(git branch -r --merged origin/$GF_DEVELOP_BRANCH | grep "$BRANCH" | wc -l)
|
|
53
|
+
TARGET="$GF_DEVELOP_BRANCH"
|
|
51
54
|
;;
|
|
52
55
|
release|hotfix)
|
|
53
|
-
MERGED=$(git branch -r --merged origin
|
|
54
|
-
TARGET="
|
|
56
|
+
MERGED=$(git branch -r --merged origin/$GF_MAIN_BRANCH | grep "$BRANCH" | wc -l)
|
|
57
|
+
TARGET="$GF_MAIN_BRANCH"
|
|
55
58
|
;;
|
|
56
59
|
esac
|
|
57
60
|
|
|
@@ -74,8 +77,8 @@ esac
|
|
|
74
77
|
|
|
75
78
|
```bash
|
|
76
79
|
if [ "$BRANCH_TYPE" = "release" ] || [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
77
|
-
# Get version
|
|
78
|
-
VERSION
|
|
80
|
+
# Get version from config (already loaded)
|
|
81
|
+
VERSION="$GF_VERSION"
|
|
79
82
|
|
|
80
83
|
# For hotfix, increment patch
|
|
81
84
|
if [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
@@ -95,8 +98,8 @@ if [ "$BRANCH_TYPE" = "release" ] || [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
# Create tag on main
|
|
98
|
-
git checkout
|
|
99
|
-
git pull origin
|
|
101
|
+
git checkout $GF_MAIN_BRANCH
|
|
102
|
+
git pull origin $GF_MAIN_BRANCH
|
|
100
103
|
git tag -a "$TAG_NAME" -m "$BRANCH_TYPE: $BRANCH_NAME"
|
|
101
104
|
git push origin "$TAG_NAME"
|
|
102
105
|
|
|
@@ -108,13 +111,13 @@ fi
|
|
|
108
111
|
|
|
109
112
|
```bash
|
|
110
113
|
if [ "$BRANCH_TYPE" = "release" ] || [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
111
|
-
echo "Merging $TAG_NAME back to
|
|
114
|
+
echo "Merging $TAG_NAME back to $GF_DEVELOP_BRANCH..."
|
|
112
115
|
|
|
113
|
-
git checkout
|
|
114
|
-
git pull origin
|
|
116
|
+
git checkout $GF_DEVELOP_BRANCH
|
|
117
|
+
git pull origin $GF_DEVELOP_BRANCH
|
|
115
118
|
|
|
116
119
|
# Merge with merge commit (preserve history)
|
|
117
|
-
git merge
|
|
120
|
+
git merge $GF_MAIN_BRANCH -m "Merge $TAG_NAME back to $GF_DEVELOP_BRANCH"
|
|
118
121
|
|
|
119
122
|
# Handle conflicts
|
|
120
123
|
CONFLICTS=$(git diff --name-only --diff-filter=U | wc -l)
|
|
@@ -125,48 +128,55 @@ if [ "$BRANCH_TYPE" = "release" ] || [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
|
125
128
|
# Options: resolve, abort
|
|
126
129
|
}
|
|
127
130
|
|
|
128
|
-
git push origin
|
|
131
|
+
git push origin $GF_DEVELOP_BRANCH
|
|
129
132
|
|
|
130
133
|
# CRITICAL: Verify push and update tracking refs
|
|
131
|
-
git fetch origin
|
|
134
|
+
git fetch origin $GF_DEVELOP_BRANCH:refs/remotes/origin/$GF_DEVELOP_BRANCH --force --quiet
|
|
132
135
|
LOCAL_SHA=$(git rev-parse HEAD)
|
|
133
|
-
REMOTE_SHA=$(git rev-parse origin
|
|
136
|
+
REMOTE_SHA=$(git rev-parse origin/$GF_DEVELOP_BRANCH)
|
|
134
137
|
if [ "$LOCAL_SHA" = "$REMOTE_SHA" ]; then
|
|
135
138
|
echo "✅ Push verified - local/remote in sync"
|
|
136
139
|
else
|
|
137
140
|
echo "⚠️ Push verification FAILED"
|
|
138
141
|
echo " Local: $LOCAL_SHA"
|
|
139
142
|
echo " Remote: $REMOTE_SHA"
|
|
140
|
-
echo " → Try: git push origin
|
|
143
|
+
echo " → Try: git push origin $GF_DEVELOP_BRANCH --force-with-lease"
|
|
141
144
|
fi
|
|
142
145
|
|
|
143
|
-
echo "✅ Merged back to
|
|
146
|
+
echo "✅ Merged back to $GF_DEVELOP_BRANCH"
|
|
144
147
|
fi
|
|
145
148
|
```
|
|
146
149
|
|
|
147
|
-
### 5. Update Version (Release
|
|
150
|
+
### 5. Update Version (Release and Hotfix)
|
|
148
151
|
|
|
149
152
|
```bash
|
|
150
|
-
if [ "$BRANCH_TYPE" = "release" ]; then
|
|
151
|
-
# Increment minor version for next development
|
|
153
|
+
if [ "$BRANCH_TYPE" = "release" ] || [ "$BRANCH_TYPE" = "hotfix" ]; then
|
|
152
154
|
MAJOR=$(echo $VERSION | cut -d'.' -f1)
|
|
153
155
|
MINOR=$(echo $VERSION | cut -d'.' -f2)
|
|
154
|
-
|
|
156
|
+
PATCH=$(echo $VERSION | cut -d'.' -f3)
|
|
157
|
+
|
|
158
|
+
if [ "$BRANCH_TYPE" = "release" ]; then
|
|
159
|
+
# Release: increment minor, reset patch
|
|
160
|
+
NEXT_VERSION="$MAJOR.$((MINOR + 1)).0"
|
|
161
|
+
else
|
|
162
|
+
# Hotfix: increment patch (patch was already bumped for the tag, bump again for next dev)
|
|
163
|
+
NEXT_VERSION="$MAJOR.$MINOR.$((PATCH + 2))"
|
|
164
|
+
fi
|
|
155
165
|
|
|
156
|
-
# Update config
|
|
157
|
-
sed -i "s/\"current\": \"
|
|
166
|
+
# Update config (using resolved config path)
|
|
167
|
+
sed -i "s/\"current\": \".*\"/\"current\": \"$NEXT_VERSION\"/" "$GF_CONFIG_FILE"
|
|
158
168
|
|
|
159
169
|
# Update source files
|
|
160
170
|
# csproj, package.json, etc.
|
|
161
171
|
|
|
162
172
|
git add -A
|
|
163
173
|
git commit -m "chore: bump version to $NEXT_VERSION for development"
|
|
164
|
-
git push origin
|
|
174
|
+
git push origin $GF_DEVELOP_BRANCH
|
|
165
175
|
|
|
166
176
|
# CRITICAL: Verify push and update tracking refs
|
|
167
|
-
git fetch origin
|
|
177
|
+
git fetch origin $GF_DEVELOP_BRANCH:refs/remotes/origin/$GF_DEVELOP_BRANCH --force --quiet
|
|
168
178
|
LOCAL_SHA=$(git rev-parse HEAD)
|
|
169
|
-
REMOTE_SHA=$(git rev-parse origin
|
|
179
|
+
REMOTE_SHA=$(git rev-parse origin/$GF_DEVELOP_BRANCH)
|
|
170
180
|
if [ "$LOCAL_SHA" = "$REMOTE_SHA" ]; then
|
|
171
181
|
echo "✅ Push verified - local/remote in sync"
|
|
172
182
|
else
|
|
@@ -182,14 +192,14 @@ fi
|
|
|
182
192
|
### 6. Clean Up Worktree
|
|
183
193
|
|
|
184
194
|
```bash
|
|
185
|
-
# Find worktree for this branch
|
|
186
|
-
WORKTREE_PATH=$(git worktree list | grep "
|
|
195
|
+
# Find worktree for this branch (use --porcelain for reliable parsing)
|
|
196
|
+
WORKTREE_PATH=$(git worktree list --porcelain | grep -B2 "branch refs/heads/$BRANCH" | grep "^worktree " | sed 's/^worktree //')
|
|
187
197
|
|
|
188
198
|
if [ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ]; then
|
|
189
199
|
echo "Removing worktree: $WORKTREE_PATH"
|
|
190
200
|
|
|
191
|
-
# Make sure we're not in the worktree
|
|
192
|
-
cd $(git rev-parse --show-toplevel)
|
|
201
|
+
# Make sure we're not in the worktree directory
|
|
202
|
+
cd "$GF_DEVELOP_PATH" 2>/dev/null || cd "$(git rev-parse --show-toplevel)"
|
|
193
203
|
|
|
194
204
|
git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || {
|
|
195
205
|
rm -rf "$WORKTREE_PATH"
|
|
@@ -265,7 +265,127 @@ AskUserQuestion:
|
|
|
265
265
|
multiSelect: false
|
|
266
266
|
```
|
|
267
267
|
|
|
268
|
-
The user will type the actual name via "Other". Use
|
|
268
|
+
The user will type the actual name via "Other". Use this raw input for step 6b.
|
|
269
|
+
|
|
270
|
+
### 6b. Normalize Project Name (INTELLIGENT)
|
|
271
|
+
|
|
272
|
+
**⛔ ALWAYS normalize, even if user chose the detected name.**
|
|
273
|
+
|
|
274
|
+
**Step 1: Parse input into words**
|
|
275
|
+
|
|
276
|
+
Split the raw input on any separator: spaces, hyphens, underscores, dots, camelCase boundaries.
|
|
277
|
+
|
|
278
|
+
| Raw input | Parsed words |
|
|
279
|
+
|-----------|-------------|
|
|
280
|
+
| `mon super projet` | `["mon", "super", "projet"]` |
|
|
281
|
+
| `gestion-des-stocks` | `["gestion", "des", "stocks"]` |
|
|
282
|
+
| `my_awesome_app` | `["my", "awesome", "app"]` |
|
|
283
|
+
| `SmartStack.App` | `["Smart", "Stack", "App"]` |
|
|
284
|
+
| `userManagement` | `["user", "Management"]` |
|
|
285
|
+
|
|
286
|
+
**Step 2: Language detection and spell check**
|
|
287
|
+
|
|
288
|
+
For EACH word, you MUST:
|
|
289
|
+
1. **Detect the language** (French, English, or technical/proper noun)
|
|
290
|
+
2. **Check spelling** - flag obvious typos
|
|
291
|
+
3. **Suggest corrections** if misspelled
|
|
292
|
+
|
|
293
|
+
| Word | Language | Spelling | Suggestion |
|
|
294
|
+
|------|----------|----------|------------|
|
|
295
|
+
| `gestion` | FR | ✅ | - |
|
|
296
|
+
| `gestoin` | FR | ❌ typo | → `gestion` |
|
|
297
|
+
| `managment` | EN | ❌ typo | → `management` |
|
|
298
|
+
| `SmartStack` | Proper noun | ✅ | - |
|
|
299
|
+
| `auth` | EN (abbreviation) | ✅ | - |
|
|
300
|
+
|
|
301
|
+
**If typos detected**, ask the user BEFORE generating variants:
|
|
302
|
+
|
|
303
|
+
```yaml
|
|
304
|
+
AskUserQuestion:
|
|
305
|
+
- header: "Spelling"
|
|
306
|
+
question: "Corrections detected. Accept?"
|
|
307
|
+
options:
|
|
308
|
+
- label: "Accept corrections (Recommended)"
|
|
309
|
+
description: "'gestoin' → 'gestion', 'managment' → 'management'"
|
|
310
|
+
- label: "Keep original"
|
|
311
|
+
description: "Use the name as typed"
|
|
312
|
+
multiSelect: false
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Step 3: Generate all name variants**
|
|
316
|
+
|
|
317
|
+
From the cleaned words, generate ALL variants:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
321
|
+
│ PROJECT NAME VARIANTS │
|
|
322
|
+
│ Input: "gestion des stocks" │
|
|
323
|
+
├─────────────────────────────────────────────────────────────┤
|
|
324
|
+
│ │
|
|
325
|
+
│ A) PascalCase.Dot → Gestion.Des.Stocks │
|
|
326
|
+
│ Best for: .NET namespace, C# project, folder name │
|
|
327
|
+
│ │
|
|
328
|
+
│ B) PascalCase → GestionDesStocks │
|
|
329
|
+
│ Best for: Class name, assembly name │
|
|
330
|
+
│ │
|
|
331
|
+
│ C) kebab-case → gestion-des-stocks │
|
|
332
|
+
│ Best for: Git repo, npm package, URL slug │
|
|
333
|
+
│ │
|
|
334
|
+
│ D) snake_case → gestion_des_stocks │
|
|
335
|
+
│ Best for: Database, Python, file system │
|
|
336
|
+
│ │
|
|
337
|
+
└─────────────────────────────────────────────────────────────┘
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
**Step 4: Ask user to choose the PRIMARY format**
|
|
341
|
+
|
|
342
|
+
```yaml
|
|
343
|
+
AskUserQuestion:
|
|
344
|
+
- header: "Format"
|
|
345
|
+
question: "Which format for the project name?"
|
|
346
|
+
options:
|
|
347
|
+
- label: "PascalCase.Dot (Recommended)"
|
|
348
|
+
description: "{PascalCase.Dot variant} - .NET convention"
|
|
349
|
+
- label: "PascalCase"
|
|
350
|
+
description: "{PascalCase variant} - single word"
|
|
351
|
+
- label: "kebab-case"
|
|
352
|
+
description: "{kebab-case variant} - git/npm convention"
|
|
353
|
+
- label: "snake_case"
|
|
354
|
+
description: "{snake_case variant} - database/python convention"
|
|
355
|
+
multiSelect: false
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Step 5: Store all derived names**
|
|
359
|
+
|
|
360
|
+
Regardless of the chosen primary format, ALL variants are generated and stored:
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{
|
|
364
|
+
"PROJECT_NAME": "{chosen format}",
|
|
365
|
+
"PROJECT_VARIANTS": {
|
|
366
|
+
"pascalCaseDot": "Gestion.Des.Stocks",
|
|
367
|
+
"pascalCase": "GestionDesStocks",
|
|
368
|
+
"kebabCase": "gestion-des-stocks",
|
|
369
|
+
"snakeCase": "gestion_des_stocks",
|
|
370
|
+
"displayName": "Gestion Des Stocks",
|
|
371
|
+
"words": ["gestion", "des", "stocks"],
|
|
372
|
+
"language": "fr"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
These variants are available for subsequent steps (repo name, namespace, folder, etc.).
|
|
378
|
+
|
|
379
|
+
**Real-world examples:**
|
|
380
|
+
|
|
381
|
+
| User types | PascalCase.Dot | kebab-case | PascalCase |
|
|
382
|
+
|-----------|---------------|------------|------------|
|
|
383
|
+
| `smart stack app` | `SmartStack.App` | `smart-stack-app` | `SmartStackApp` |
|
|
384
|
+
| `gestion-des-stocks` | `Gestion.Des.Stocks` | `gestion-des-stocks` | `GestionDesStocks` |
|
|
385
|
+
| `Mon Projet V2` | `Mon.Projet.V2` | `mon-projet-v2` | `MonProjetV2` |
|
|
386
|
+
| `user auth module` | `User.Auth.Module` | `user-auth-module` | `UserAuthModule` |
|
|
387
|
+
| `PROJET TEST` | `Projet.Test` | `projet-test` | `ProjetTest` |
|
|
388
|
+
| `e-commerce platform` | `ECommerce.Platform` | `e-commerce-platform` | `ECommercePlatform` |
|
|
269
389
|
|
|
270
390
|
### 7. Ask Worktree Mode
|
|
271
391
|
|
|
@@ -333,6 +453,14 @@ mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
|
|
|
333
453
|
"repository": {
|
|
334
454
|
"name": "{PROJECT_NAME}",
|
|
335
455
|
"rootFolder": "{ROOT_FOLDER}",
|
|
456
|
+
"nameVariants": {
|
|
457
|
+
"pascalCaseDot": "{PascalCase.Dot}",
|
|
458
|
+
"pascalCase": "{PascalCase}",
|
|
459
|
+
"kebabCase": "{kebab-case}",
|
|
460
|
+
"snakeCase": "{snake_case}",
|
|
461
|
+
"displayName": "{Display Name}"
|
|
462
|
+
},
|
|
463
|
+
"defaultBranch": "main",
|
|
336
464
|
"remoteUrl": "{REPO_URL}"
|
|
337
465
|
},
|
|
338
466
|
"git": {
|
|
@@ -367,7 +495,8 @@ mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
|
|
|
367
495
|
"efcore": {
|
|
368
496
|
"enabled": true,
|
|
369
497
|
"validateOnCommit": true,
|
|
370
|
-
"blockDestructive": true
|
|
498
|
+
"blockDestructive": true,
|
|
499
|
+
"migrationNaming": "{context}_v{version}_{sequence}_{Description}"
|
|
371
500
|
},
|
|
372
501
|
"workflow": {
|
|
373
502
|
"push": {
|
|
@@ -377,6 +506,9 @@ mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
|
|
|
377
506
|
"autoLabels": true,
|
|
378
507
|
"requireReview": true
|
|
379
508
|
}
|
|
509
|
+
},
|
|
510
|
+
"language": {
|
|
511
|
+
"code": "{GF_LANG}"
|
|
380
512
|
}
|
|
381
513
|
}
|
|
382
514
|
```
|
|
@@ -16,19 +16,33 @@ Run through review checklist and merge the pull request with appropriate strateg
|
|
|
16
16
|
|
|
17
17
|
## EXECUTION SEQUENCE:
|
|
18
18
|
|
|
19
|
-
### 1. Load PR Context
|
|
19
|
+
### 1. Load Config and PR Context
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
+
# Load GitFlow config (sets GF_* variables)
|
|
23
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
24
|
+
|
|
22
25
|
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
23
|
-
GIT_PROVIDER
|
|
26
|
+
GIT_PROVIDER="$GF_PROVIDER"
|
|
27
|
+
|
|
28
|
+
# Try loading persisted PR state first
|
|
29
|
+
CONFIG_DIR=$(dirname "$GF_CONFIG_FILE")
|
|
30
|
+
PR_STATE_FILE="$CONFIG_DIR/cache/pr-state.json"
|
|
31
|
+
if [ -f "$PR_STATE_FILE" ]; then
|
|
32
|
+
PR_NUMBER=$(grep -oP '"pr_number":\s*"\K[^"]+' "$PR_STATE_FILE" | head -1)
|
|
33
|
+
TARGET_BRANCH=$(grep -oP '"target_branch":\s*"\K[^"]+' "$PR_STATE_FILE" | head -1)
|
|
34
|
+
echo "✓ Loaded PR state from cache: PR #$PR_NUMBER → $TARGET_BRANCH"
|
|
35
|
+
fi
|
|
24
36
|
|
|
25
|
-
#
|
|
26
|
-
if [ "$
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
# Fallback: query provider if no cached state
|
|
38
|
+
if [ -z "$PR_NUMBER" ]; then
|
|
39
|
+
if [ "$GIT_PROVIDER" = "github" ]; then
|
|
40
|
+
PR_NUMBER=$(gh pr list --head "$CURRENT" --json number --jq '.[0].number')
|
|
41
|
+
PR_STATUS=$(gh pr view $PR_NUMBER --json state,mergeable,reviews --jq '.')
|
|
42
|
+
elif [ "$GIT_PROVIDER" = "azuredevops" ]; then
|
|
43
|
+
PR_NUMBER=$(az repos pr list --source-branch "$CURRENT" --query "[0].pullRequestId" -o tsv)
|
|
44
|
+
PR_STATUS=$(az repos pr show --id $PR_NUMBER --query "{status:status,mergeStatus:mergeStatus}")
|
|
45
|
+
fi
|
|
32
46
|
fi
|
|
33
47
|
|
|
34
48
|
[ -z "$PR_NUMBER" ] && {
|
|
@@ -125,7 +139,7 @@ case "$BRANCH_TYPE" in
|
|
|
125
139
|
release|hotfix)
|
|
126
140
|
MERGE_STRATEGY="merge"
|
|
127
141
|
DELETE_BRANCH=true
|
|
128
|
-
MERGE_BACK="
|
|
142
|
+
MERGE_BACK="$GF_DEVELOP_BRANCH"
|
|
129
143
|
;;
|
|
130
144
|
esac
|
|
131
145
|
```
|