@atlashub/smartstack-cli 3.44.0 → 3.45.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlashub/smartstack-cli",
3
- "version": "3.44.0",
3
+ "version": "3.45.0",
4
4
  "description": "SmartStack Claude Code automation toolkit - GitFlow, EF Core migrations, prompts and more",
5
5
  "author": {
6
6
  "name": "SmartStack",
@@ -28,14 +28,34 @@ fi
28
28
  3. **Display** results in standard format
29
29
  4. **Block** if HIGH or CRITICAL conflict
30
30
 
31
+ ## Base Branch Determination
32
+
33
+ **BEFORE calling MCP, determine the correct base branch:**
34
+
35
+ ```bash
36
+ # Determine base branch based on current branch type:
37
+ # feature/* → compareBranch: "develop"
38
+ # release/* → compareBranch: "main"
39
+ # hotfix/* → compareBranch: "main"
40
+ # develop → compareBranch: "main"
41
+ CURRENT_BRANCH=$(git branch --show-current)
42
+ case "$CURRENT_BRANCH" in
43
+ feature/*) COMPARE_BRANCH="develop" ;;
44
+ release/*) COMPARE_BRANCH="main" ;;
45
+ hotfix/*) COMPARE_BRANCH="main" ;;
46
+ develop) COMPARE_BRANCH="main" ;;
47
+ *) COMPARE_BRANCH="develop" ;;
48
+ esac
49
+ ```
50
+
31
51
  ## MCP Integration
32
52
 
33
- **Primary method:** Use MCP tool for analysis
53
+ **Primary method:** Use MCP tool for analysis with the **correct base branch**
34
54
 
35
55
  ```
36
56
  CALL mcp__smartstack__check_migrations WITH:
37
57
  - branch: {current_branch}
38
- - compareBranch: "develop"
58
+ - compareBranch: {COMPARE_BRANCH}
39
59
  ```
40
60
 
41
61
  **Response structure:**
@@ -29,15 +29,37 @@ fi
29
29
  4. **Analyze** conflict risks
30
30
  5. **Recommend** optimal merge order
31
31
 
32
+ ## Base Branch Determination
33
+
34
+ **BEFORE calling MCP, determine the correct base branch for each worktree:**
35
+
36
+ ```bash
37
+ # For each branch, determine its base:
38
+ # feature/* → compareBranch: "develop"
39
+ # release/* → compareBranch: "main"
40
+ # hotfix/* → compareBranch: "main"
41
+ # develop → compareBranch: "main"
42
+ determine_compare_branch() {
43
+ case "$1" in
44
+ feature/*) echo "develop" ;;
45
+ release/*) echo "main" ;;
46
+ hotfix/*) echo "main" ;;
47
+ develop) echo "main" ;;
48
+ *) echo "develop" ;;
49
+ esac
50
+ }
51
+ ```
52
+
32
53
  ## MCP Integration
33
54
 
34
- **Primary method:** Loop through branches and call MCP
55
+ **Primary method:** Loop through branches and call MCP with the **correct base branch**
35
56
 
36
57
  ```
37
58
  FOR each branch in active_worktrees:
59
+ COMPARE_BRANCH = determine_compare_branch(branch)
38
60
  CALL mcp__smartstack__check_migrations WITH:
39
61
  - branch: {branch}
40
- - compareBranch: "develop"
62
+ - compareBranch: {COMPARE_BRANCH}
41
63
  STORE result
42
64
  ```
43
65
 
@@ -15,10 +15,10 @@ You initialize a GitFlow project by orchestrating 3 specialized sub-agents.
15
15
  ```
16
16
  gitflow-init (you - orchestrator)
17
17
  ├── Task(gitflow-init-detect) → Environment report
18
- ├── AskUserQuestion → User confirms URL, path, name
19
- ├── Task(gitflow-init-clone) → Create structure
18
+ ├── AskUserQuestion → User confirms URL, path, name, worktree mode
19
+ ├── Task(gitflow-init-clone) → Create structure (skip if disabled)
20
20
  ├── Write config.json → v2.1.0 with platform & workspace
21
- └── Task(gitflow-init-validate) → Verify & repair
21
+ └── Task(gitflow-init-validate) → Verify & repair (skip if disabled)
22
22
  ```
23
23
 
24
24
  ---
@@ -55,10 +55,24 @@ fi
55
55
  ```
56
56
 
57
57
  - **View**: Display config in formatted table and EXIT
58
- - **Reconfigure**: Continue with full init workflow
58
+ - **Reconfigure**: Load existing values as defaults, then continue with full init workflow (see below)
59
59
  - **Repair**: Delegate directly to `Task(gitflow-init-validate)` then EXIT
60
60
  - **Cancel**: EXIT immediately
61
61
 
62
+ ### Loading Existing Config as Defaults (Reconfigure mode)
63
+
64
+ When the user chooses "Reconfigure", parse the existing `config.json` to pre-populate defaults:
65
+
66
+ ```bash
67
+ # Extract current values from existing config
68
+ EXISTING_URL=$(cat .claude/gitflow/config.json | python3 -c "import sys,json; print(json.load(sys.stdin).get('repository',{}).get('remoteUrl',''))" 2>/dev/null)
69
+ EXISTING_NAME=$(cat .claude/gitflow/config.json | python3 -c "import sys,json; print(json.load(sys.stdin).get('repository',{}).get('name',''))" 2>/dev/null)
70
+ EXISTING_ROOT=$(cat .claude/gitflow/config.json | python3 -c "import sys,json; print(json.load(sys.stdin).get('repository',{}).get('rootFolder',''))" 2>/dev/null)
71
+ EXISTING_MODE=$(cat .claude/gitflow/config.json | python3 -c "import sys,json; print(json.load(sys.stdin).get('worktrees',{}).get('mode','organized'))" 2>/dev/null)
72
+ ```
73
+
74
+ These values will be shown as "(Current)" recommended options in each question below.
75
+
62
76
  ---
63
77
 
64
78
  ## STEP 1: DETECT ENVIRONMENT
@@ -81,7 +95,9 @@ Parse the report to extract:
81
95
 
82
96
  ---
83
97
 
84
- ## STEP 2: ASK USER (3 MANDATORY QUESTIONS)
98
+ ## STEP 2: ASK USER (4 MANDATORY QUESTIONS)
99
+
100
+ > **Reconfigure mode:** When `EXISTING_GITFLOW=true` and user chose "Reconfigure", show existing values as "(Current)" recommended options in each question. This avoids forcing the user to re-enter everything.
85
101
 
86
102
  ### 2a. Repository URL
87
103
 
@@ -89,6 +105,7 @@ Parse the report to extract:
89
105
 
90
106
  Otherwise ask:
91
107
 
108
+ **Fresh init (no existing config):**
92
109
  ```json
93
110
  {
94
111
  "questions": [{
@@ -105,12 +122,30 @@ Otherwise ask:
105
122
  }
106
123
  ```
107
124
 
125
+ **Reconfigure mode (existing config):**
126
+ ```json
127
+ {
128
+ "questions": [{
129
+ "question": "Repository URL? (current: {EXISTING_URL})",
130
+ "header": "Repository",
131
+ "options": [
132
+ {"label": "Keep current (Recommended)", "description": "{EXISTING_URL}"},
133
+ {"label": "Enter GitHub URL", "description": "https://github.com/org/repo.git"},
134
+ {"label": "Enter Azure DevOps URL", "description": "https://dev.azure.com/org/project/_git/repo"},
135
+ {"label": "Local only (no remote)", "description": "Initialize without remote"}
136
+ ],
137
+ "multiSelect": false
138
+ }]
139
+ }
140
+ ```
141
+
108
142
  **If user selects a custom option, ask follow-up for the actual URL.**
109
143
 
110
144
  ### 2b. Root Folder
111
145
 
112
146
  **CRITICAL for WSL: Normalize the path for the current platform.**
113
147
 
148
+ **Fresh init:**
114
149
  ```json
115
150
  {
116
151
  "questions": [{
@@ -126,6 +161,22 @@ Otherwise ask:
126
161
  }
127
162
  ```
128
163
 
164
+ **Reconfigure mode:**
165
+ ```json
166
+ {
167
+ "questions": [{
168
+ "question": "Root folder? (current: {EXISTING_ROOT})",
169
+ "header": "Location",
170
+ "options": [
171
+ {"label": "Keep current (Recommended)", "description": "{EXISTING_ROOT}"},
172
+ {"label": "Use parent folder", "description": "{PARENT_DIR}/"},
173
+ {"label": "Custom path", "description": "Specify a different location"}
174
+ ],
175
+ "multiSelect": false
176
+ }]
177
+ }
178
+ ```
179
+
129
180
  **After getting the path, normalize it:**
130
181
  ```bash
131
182
  # On WSL: translate Windows paths to /mnt/ format
@@ -135,6 +186,7 @@ Otherwise ask:
135
186
 
136
187
  ### 2c. Project Name
137
188
 
189
+ **Fresh init:**
138
190
  ```json
139
191
  {
140
192
  "questions": [{
@@ -149,12 +201,66 @@ Otherwise ask:
149
201
  }
150
202
  ```
151
203
 
204
+ **Reconfigure mode:**
205
+ ```json
206
+ {
207
+ "questions": [{
208
+ "question": "Project name? (current: {EXISTING_NAME})",
209
+ "header": "Project",
210
+ "options": [
211
+ {"label": "Keep current (Recommended)", "description": "{EXISTING_NAME}"},
212
+ {"label": "Custom name", "description": "Specify a different project name"}
213
+ ],
214
+ "multiSelect": false
215
+ }]
216
+ }
217
+ ```
218
+
152
219
  Normalize name into variants (PascalCase.Dot, PascalCase, kebab-case, snake_case, Display Name).
153
220
 
221
+ ### 2d. Worktree Mode
222
+
223
+ **Fresh init:**
224
+ ```json
225
+ {
226
+ "questions": [{
227
+ "question": "How should worktrees be organized?",
228
+ "header": "Worktrees",
229
+ "options": [
230
+ {"label": "Organized (Recommended)", "description": "01-Main, 02-Develop, features/, releases/, hotfixes/"},
231
+ {"label": "Simple", "description": "main/, develop/, features/, releases/, hotfixes/"},
232
+ {"label": "Disabled", "description": "No worktrees, use git checkout (not recommended)"}
233
+ ],
234
+ "multiSelect": false
235
+ }]
236
+ }
237
+ ```
238
+
239
+ **Reconfigure mode:**
240
+ ```json
241
+ {
242
+ "questions": [{
243
+ "question": "How should worktrees be organized? (current: {EXISTING_MODE})",
244
+ "header": "Worktrees",
245
+ "options": [
246
+ {"label": "Keep current: {EXISTING_MODE} (Recommended)", "description": "No change to worktree structure"},
247
+ {"label": "Organized", "description": "01-Main, 02-Develop, features/, releases/, hotfixes/"},
248
+ {"label": "Simple", "description": "main/, develop/, features/, releases/, hotfixes/"},
249
+ {"label": "Disabled", "description": "No worktrees, use git checkout (not recommended)"}
250
+ ],
251
+ "multiSelect": false
252
+ }]
253
+ }
254
+ ```
255
+
256
+ Store the result as `{WORKTREE_MODE}` ("organized", "simple", or "disabled").
257
+
154
258
  ---
155
259
 
156
260
  ## STEP 3: CLONE AND CREATE STRUCTURE
157
261
 
262
+ **Skip this step if `{WORKTREE_MODE}` is "disabled".**
263
+
158
264
  Delegate to `gitflow-init-clone` sub-agent:
159
265
 
160
266
  ```
@@ -164,7 +270,7 @@ Task(gitflow-init-clone):
164
270
  - REPO_URL: {REPO_URL}
165
271
  - PROJECT_BASE: {PROJECT_BASE} (already platform-normalized absolute path)
166
272
  - PROJECT_NAME: {PROJECT_NAME}
167
- - WORKTREE_MODE: organized
273
+ - WORKTREE_MODE: {WORKTREE_MODE}
168
274
  - PLATFORM: {PLATFORM}
169
275
  subagent_type: gitflow-init-clone
170
276
  model: sonnet
@@ -178,9 +284,19 @@ Check the result. If FAIL, report to user and suggest manual intervention.
178
284
 
179
285
  Write `.claude/gitflow/config.json` in develop worktree using the Write tool.
180
286
 
181
- **Path:** `{PROJECT_BASE}/02-Develop/.claude/gitflow/config.json`
287
+ **Path (depends on worktree mode):**
288
+ - Organized: `{PROJECT_BASE}/02-Develop/.claude/gitflow/config.json`
289
+ - Simple: `{PROJECT_BASE}/develop/.claude/gitflow/config.json`
290
+ - Disabled: `{PROJECT_BASE}/.claude/gitflow/config.json`
182
291
 
183
292
  **Content (v2.1.0):**
293
+
294
+ Compute directory names based on `{WORKTREE_MODE}`:
295
+ ```
296
+ MAIN_DIR = organized → "01-Main" | simple → "main" | disabled → "."
297
+ DEVELOP_DIR = organized → "02-Develop" | simple → "develop" | disabled → "."
298
+ ```
299
+
184
300
  ```json
185
301
  {
186
302
  "version": "2.1.0",
@@ -212,11 +328,11 @@ Write `.claude/gitflow/config.json` in develop worktree using the Write tool.
212
328
  "prefixes": { "feature": "feature/", "release": "release/", "hotfix": "hotfix/" }
213
329
  },
214
330
  "worktrees": {
215
- "enabled": true,
216
- "mode": "organized",
331
+ "enabled": "{WORKTREE_MODE != 'disabled'}",
332
+ "mode": "{WORKTREE_MODE}",
217
333
  "structure": {
218
- "main": "{normalize_path_for_storage(PROJECT_BASE)}/01-Main",
219
- "develop": "{normalize_path_for_storage(PROJECT_BASE)}/02-Develop",
334
+ "main": "{normalize_path_for_storage(PROJECT_BASE)}/{MAIN_DIR}",
335
+ "develop": "{normalize_path_for_storage(PROJECT_BASE)}/{DEVELOP_DIR}",
220
336
  "features": "{normalize_path_for_storage(PROJECT_BASE)}/features",
221
337
  "releases": "{normalize_path_for_storage(PROJECT_BASE)}/releases",
222
338
  "hotfixes": "{normalize_path_for_storage(PROJECT_BASE)}/hotfixes"
@@ -248,6 +364,8 @@ Write `.claude/gitflow/config.json` in develop worktree using the Write tool.
248
364
 
249
365
  ## STEP 5: VALIDATE
250
366
 
367
+ **Skip this step if `{WORKTREE_MODE}` is "disabled".**
368
+
251
369
  Delegate to `gitflow-init-validate` sub-agent:
252
370
 
253
371
  ```
@@ -255,7 +373,7 @@ Task(gitflow-init-validate):
255
373
  prompt: |
256
374
  Validate GitFlow installation:
257
375
  - PROJECT_BASE: {PROJECT_BASE}
258
- - WORKTREE_MODE: organized
376
+ - WORKTREE_MODE: {WORKTREE_MODE}
259
377
  - REPO_URL: {REPO_URL}
260
378
  - PLATFORM: {PLATFORM}
261
379
  subagent_type: gitflow-init-validate
@@ -276,6 +394,9 @@ If `{HAS_WORKSPACE}=false` and `{SIBLING_COUNT} > 0`, suggest creating a workspa
276
394
 
277
395
  ## STEP 7: SUMMARY
278
396
 
397
+ **Adapt structure display based on `{WORKTREE_MODE}`:**
398
+
399
+ **Organized mode:**
279
400
  ```
280
401
  ================================================================================
281
402
  GITFLOW INITIALIZED
@@ -287,6 +408,7 @@ PROJECT
287
408
  URL: {REPO_URL}
288
409
  Provider: {GIT_PROVIDER}
289
410
  Platform: {PLATFORM} ({SHELL_TYPE})
411
+ Mode: organized
290
412
 
291
413
  STRUCTURE
292
414
  01-Main/ → main branch ✓
@@ -309,6 +431,67 @@ NEXT STEPS
309
431
  ================================================================================
310
432
  ```
311
433
 
434
+ **Simple mode:**
435
+ ```
436
+ ================================================================================
437
+ GITFLOW INITIALIZED
438
+ ================================================================================
439
+
440
+ PROJECT
441
+ Name: {PROJECT_NAME}
442
+ Location: {PROJECT_BASE}/
443
+ URL: {REPO_URL}
444
+ Provider: {GIT_PROVIDER}
445
+ Platform: {PLATFORM} ({SHELL_TYPE})
446
+ Mode: simple
447
+
448
+ STRUCTURE
449
+ main/ → main branch ✓
450
+ develop/ → develop branch ✓
451
+ features/ → feature worktrees ✓
452
+ releases/ → release worktrees ✓
453
+ hotfixes/ → hotfix worktrees ✓
454
+
455
+ CONFIG
456
+ Version: 2.1.0
457
+ Path: develop/.claude/gitflow/config.json
458
+
459
+ VALIDATION
460
+ {validation_summary}
461
+
462
+ NEXT STEPS
463
+ cd "{PROJECT_BASE}/develop"
464
+ /gitflow -f <feature-name>
465
+
466
+ ================================================================================
467
+ ```
468
+
469
+ **Disabled mode:**
470
+ ```
471
+ ================================================================================
472
+ GITFLOW INITIALIZED (no worktrees)
473
+ ================================================================================
474
+
475
+ PROJECT
476
+ Name: {PROJECT_NAME}
477
+ Location: {PROJECT_BASE}/
478
+ URL: {REPO_URL}
479
+ Provider: {GIT_PROVIDER}
480
+ Platform: {PLATFORM} ({SHELL_TYPE})
481
+ Mode: disabled (git checkout)
482
+
483
+ CONFIG
484
+ Version: 2.1.0
485
+ Path: .claude/gitflow/config.json
486
+
487
+ NEXT STEPS
488
+ cd "{PROJECT_BASE}"
489
+ git checkout develop
490
+ /gitflow -f <feature-name>
491
+
492
+ ================================================================================
493
+ ```
494
+
312
495
  ---
313
496
 
314
497
  ## WORKSPACE MODE (`--workspace`)
@@ -80,10 +80,10 @@ PARENT_MIGRATIONS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- "$MIGRAT
80
80
  # Get local migrations
81
81
  LOCAL_MIGRATIONS=$(find "$MIGRATIONS_DIR" -name "*.cs" 2>/dev/null | grep -v "Designer\|Snapshot" | xargs -I{} basename {} 2>/dev/null || echo "")
82
82
 
83
- # Find branch-only migrations
83
+ # Find branch-only migrations (exact match, not substring)
84
84
  BRANCH_MIGRATIONS=()
85
85
  for mig in $LOCAL_MIGRATIONS; do
86
- if ! echo "$PARENT_MIGRATIONS" | grep -q "$(basename "$mig")"; then
86
+ if ! echo "$PARENT_MIGRATIONS" | grep -qx "$(basename "$mig")"; then
87
87
  BRANCH_MIGRATIONS+=("$mig")
88
88
  fi
89
89
  done
@@ -38,10 +38,10 @@ BASE_MIGRATIONS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- "$MIGRATIO
38
38
  # Get local migrations
39
39
  LOCAL_MIGRATIONS=$(find "$MIGRATIONS_DIR" -name "*.cs" 2>/dev/null | grep -v "Designer\|Snapshot" | xargs -I{} basename {} 2>/dev/null || echo "")
40
40
 
41
- # Find migrations unique to this branch
41
+ # Find migrations unique to this branch (exact match, not substring)
42
42
  BRANCH_ONLY_MIGRATIONS=()
43
43
  for mig in $LOCAL_MIGRATIONS; do
44
- if ! echo "$BASE_MIGRATIONS" | grep -q "$(basename "$mig")"; then
44
+ if ! echo "$BASE_MIGRATIONS" | grep -qx "$(basename "$mig")"; then
45
45
  BRANCH_ONLY_MIGRATIONS+=("$mig")
46
46
  fi
47
47
  done