@atlashub/smartstack-cli 2.9.0 → 3.1.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.
Files changed (90) hide show
  1. package/.documentation/agents.html +1 -371
  2. package/.documentation/business-analyse.html +81 -17
  3. package/.documentation/cli-commands.html +1 -1
  4. package/.documentation/commands.html +1 -1
  5. package/.documentation/efcore.html +1 -1
  6. package/.documentation/gitflow.html +1 -1
  7. package/.documentation/hooks.html +27 -66
  8. package/.documentation/index.html +166 -166
  9. package/.documentation/init.html +6 -7
  10. package/.documentation/installation.html +1 -1
  11. package/.documentation/ralph-loop.html +1 -9
  12. package/.documentation/test-web.html +15 -39
  13. package/dist/index.js +23 -16
  14. package/dist/index.js.map +1 -1
  15. package/dist/mcp-entry.mjs +1302 -223
  16. package/dist/mcp-entry.mjs.map +1 -1
  17. package/package.json +1 -1
  18. package/templates/agents/efcore/db-deploy.md +1 -1
  19. package/templates/agents/efcore/migration.md +26 -10
  20. package/templates/agents/efcore/rebase-snapshot.md +24 -7
  21. package/templates/agents/efcore/squash.md +73 -57
  22. package/templates/agents/gitflow/commit.md +138 -18
  23. package/templates/agents/gitflow/exec.md +1 -1
  24. package/templates/agents/gitflow/finish.md +79 -62
  25. package/templates/agents/gitflow/init-clone.md +186 -0
  26. package/templates/agents/gitflow/init-detect.md +137 -0
  27. package/templates/agents/gitflow/init-validate.md +210 -0
  28. package/templates/agents/gitflow/init.md +231 -74
  29. package/templates/agents/gitflow/merge.md +115 -33
  30. package/templates/agents/gitflow/pr.md +151 -46
  31. package/templates/agents/gitflow/start.md +76 -33
  32. package/templates/agents/gitflow/status.md +41 -71
  33. package/templates/hooks/appsettings-guard.sh +76 -0
  34. package/templates/hooks/ef-migration-check.md +1 -1
  35. package/templates/hooks/hooks.json +9 -0
  36. package/templates/project/appsettings.json.template +8 -2
  37. package/templates/project/test-frontend/msw/handlers.ts +58 -0
  38. package/templates/project/test-frontend/msw/server.ts +25 -0
  39. package/templates/project/test-frontend/setup.ts +16 -0
  40. package/templates/project/test-frontend/test-utils.tsx +59 -0
  41. package/templates/project/test-frontend/vitest.config.ts +31 -0
  42. package/templates/skills/_resources/config-safety.md +61 -0
  43. package/templates/skills/_resources/formatting-guide.md +2 -2
  44. package/templates/skills/application/SKILL.md +12 -3
  45. package/templates/skills/application/steps/step-04-backend.md +21 -0
  46. package/templates/skills/application/steps/step-07-tests.md +259 -120
  47. package/templates/skills/business-analyse/SKILL.md +57 -28
  48. package/templates/skills/business-analyse/_shared.md +70 -39
  49. package/templates/skills/business-analyse/html/ba-interactive.html +2596 -0
  50. package/templates/skills/business-analyse/questionnaire/00-application.md +123 -131
  51. package/templates/skills/business-analyse/questionnaire/01-context.md +173 -24
  52. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +170 -50
  53. package/templates/skills/business-analyse/questionnaire/03-scope.md +154 -48
  54. package/templates/skills/business-analyse/questionnaire/10-documentation.md +1 -1
  55. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +135 -0
  56. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +136 -0
  57. package/templates/skills/business-analyse/questionnaire.md +55 -46
  58. package/templates/skills/business-analyse/steps/step-00-init.md +24 -2
  59. package/templates/skills/business-analyse/steps/step-01-cadrage.md +31 -20
  60. package/templates/skills/business-analyse/steps/step-03-specify.md +58 -0
  61. package/templates/skills/business-analyse/steps/step-05-handoff.md +301 -1
  62. package/templates/skills/business-analyse/steps/step-06-extract.md +518 -0
  63. package/templates/skills/check-version/SKILL.md +1 -1
  64. package/templates/skills/efcore/steps/db/step-deploy.md +22 -3
  65. package/templates/skills/efcore/steps/db/step-reset.md +27 -4
  66. package/templates/skills/efcore/steps/db/step-seed.md +46 -2
  67. package/templates/skills/efcore/steps/db/step-status.md +14 -0
  68. package/templates/skills/efcore/steps/migration/step-01-check.md +31 -5
  69. package/templates/skills/efcore/steps/migration/step-02-create.md +20 -4
  70. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +60 -0
  71. package/templates/skills/efcore/steps/shared/step-00-init.md +47 -8
  72. package/templates/skills/efcore/steps/squash/step-03-create.md +27 -5
  73. package/templates/skills/gitflow/SKILL.md +91 -29
  74. package/templates/skills/gitflow/_shared.md +144 -2
  75. package/templates/skills/gitflow/phases/status.md +11 -1
  76. package/templates/skills/gitflow/steps/step-commit.md +1 -1
  77. package/templates/skills/gitflow/steps/step-init.md +202 -39
  78. package/templates/skills/gitflow/steps/step-pr.md +17 -5
  79. package/templates/skills/gitflow/templates/config.json +10 -1
  80. package/templates/skills/ralph-loop/SKILL.md +22 -15
  81. package/templates/skills/ralph-loop/steps/step-01-task.md +89 -4
  82. package/templates/skills/ralph-loop/steps/step-02-execute.md +408 -23
  83. package/templates/skills/ralph-loop/steps/step-03-commit.md +84 -2
  84. package/templates/skills/ralph-loop/steps/step-04-check.md +235 -6
  85. package/templates/skills/ralph-loop/steps/step-05-report.md +115 -0
  86. package/templates/skills/validate-feature/SKILL.md +83 -0
  87. package/templates/skills/validate-feature/steps/step-01-compile.md +38 -0
  88. package/templates/skills/validate-feature/steps/step-02-unit-tests.md +45 -0
  89. package/templates/skills/validate-feature/steps/step-03-integration-tests.md +53 -0
  90. package/templates/skills/validate-feature/steps/step-04-api-smoke.md +157 -0
@@ -4,6 +4,95 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## DETECT_PLATFORM
8
+
9
+ Detects the current platform (WSL, Windows, macOS, Linux) and shell environment.
10
+ Must be called before any path operations.
11
+
12
+ ```bash
13
+ detect_platform() {
14
+ # WSL detection (highest priority - WSL reports as Linux but needs path translation)
15
+ if [ -f /proc/version ] && grep -qi "microsoft\|wsl" /proc/version 2>/dev/null; then
16
+ GF_PLATFORM="wsl"
17
+ GF_SHELL="bash"
18
+ elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "mingw"* ]] || [[ "$OSTYPE" == "cygwin" ]]; then
19
+ GF_PLATFORM="windows"
20
+ GF_SHELL="gitbash"
21
+ elif [[ -n "$WINDIR" ]] || [[ -n "$SystemRoot" ]]; then
22
+ GF_PLATFORM="windows"
23
+ GF_SHELL="powershell"
24
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
25
+ GF_PLATFORM="macos"
26
+ GF_SHELL="zsh"
27
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
28
+ GF_PLATFORM="linux"
29
+ GF_SHELL="bash"
30
+ else
31
+ GF_PLATFORM="unknown"
32
+ GF_SHELL="bash"
33
+ fi
34
+ }
35
+ ```
36
+
37
+ ---
38
+
39
+ ## NORMALIZE_PATH
40
+
41
+ Path translation functions for cross-platform compatibility (Windows ↔ WSL ↔ POSIX).
42
+
43
+ ```bash
44
+ # Translates a path to the format expected by the CURRENT platform
45
+ normalize_path_for_platform() {
46
+ local input_path="$1"
47
+ case "$GF_PLATFORM" in
48
+ wsl)
49
+ # Windows path → WSL path: D:\foo\bar or D:/foo/bar → /mnt/d/foo/bar
50
+ if [[ "$input_path" =~ ^[A-Za-z]:[\\/] ]]; then
51
+ local drive=$(echo "${input_path:0:1}" | tr '[:upper:]' '[:lower:]')
52
+ local rest="${input_path:2}"
53
+ rest="${rest//\\//}"
54
+ echo "/mnt/$drive$rest"
55
+ else
56
+ echo "$input_path"
57
+ fi
58
+ ;;
59
+ *)
60
+ # Normalize backslashes to forward slashes
61
+ echo "${input_path//\\//}"
62
+ ;;
63
+ esac
64
+ }
65
+
66
+ # Translates a path to storage-neutral format for config.json (forward slashes, drive letter)
67
+ normalize_path_for_storage() {
68
+ local input_path="$1"
69
+ case "$GF_PLATFORM" in
70
+ wsl)
71
+ # WSL path → Windows-style for config: /mnt/d/foo/bar → D:/foo/bar
72
+ if [[ "$input_path" =~ ^/mnt/([a-z])/(.*) ]]; then
73
+ local drive=$(echo "${BASH_REMATCH[1]}" | tr '[:lower:]' '[:upper:]')
74
+ echo "${drive}:/${BASH_REMATCH[2]}"
75
+ else
76
+ echo "$input_path"
77
+ fi
78
+ ;;
79
+ *)
80
+ # Normalize backslashes to forward slashes
81
+ echo "${input_path//\\//}"
82
+ ;;
83
+ esac
84
+ }
85
+
86
+ # Returns current directory in platform-appropriate format
87
+ get_current_dir() {
88
+ local raw_pwd
89
+ raw_pwd="$(pwd)"
90
+ normalize_path_for_platform "$raw_pwd"
91
+ }
92
+ ```
93
+
94
+ ---
95
+
7
96
  ## DETECT_PROVIDER
8
97
 
9
98
  Detects GitHub or Azure DevOps from remote URL.
@@ -83,12 +172,18 @@ Reads GitFlow configuration from config.json. Exposes all variables needed by st
83
172
 
84
173
  ```bash
85
174
  read_gitflow_config() {
175
+ # Detect platform first (needed for path translation)
176
+ detect_platform
177
+
86
178
  local CONFIG_FILE
87
179
  CONFIG_FILE=$(resolve_gitflow_config_path) || {
88
180
  echo "❌ GitFlow config not found. Run /gitflow init first."
89
181
  return 1
90
182
  }
91
183
 
184
+ # Config version
185
+ GF_CONFIG_VERSION=$(grep -oP '"version":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
186
+
92
187
  # Repository
93
188
  GF_PROJECT_NAME=$(grep -oP '"name":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
94
189
  GF_ROOT_FOLDER=$(grep -oP '"rootFolder":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
@@ -119,6 +214,14 @@ read_gitflow_config() {
119
214
  GF_VERSION=$(grep -oP '"current":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
120
215
  GF_TAG_PREFIX=$(grep -oP '"tagPrefix":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
121
216
 
217
+ # Platform (v2.1.0+, optional)
218
+ GF_CONFIG_PLATFORM=$(grep -oP '"detected":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
219
+ GF_CONFIG_PLATFORM=${GF_CONFIG_PLATFORM:-$GF_PLATFORM}
220
+
221
+ # Workspace (v2.1.0+, optional)
222
+ GF_WORKSPACE_PATH=$(grep -A1 '"workspace"' "$CONFIG_FILE" | grep -oP '"path":\s*"\K[^"]+' | head -1)
223
+ GF_WORKSPACE_NAME=$(grep -A2 '"workspace"' "$CONFIG_FILE" | grep -oP '"name":\s*"\K[^"]+' | head -1)
224
+
122
225
  # Defaults for missing values
123
226
  GF_LANG=${GF_LANG:-en}
124
227
  GF_WORKTREE_MODE=${GF_WORKTREE_MODE:-organized}
@@ -130,6 +233,16 @@ read_gitflow_config() {
130
233
  GF_TAG_PREFIX=${GF_TAG_PREFIX:-v}
131
234
  GF_VERSION=${GF_VERSION:-0.1.0}
132
235
 
236
+ # Translate all stored paths to current platform format
237
+ # This ensures WSL paths are /mnt/d/... and Windows paths use forward slashes
238
+ GF_ROOT_FOLDER=$(normalize_path_for_platform "$GF_ROOT_FOLDER")
239
+ GF_MAIN_PATH=$(normalize_path_for_platform "$GF_MAIN_PATH")
240
+ GF_DEVELOP_PATH=$(normalize_path_for_platform "$GF_DEVELOP_PATH")
241
+ GF_FEATURES_PATH=$(normalize_path_for_platform "$GF_FEATURES_PATH")
242
+ GF_RELEASES_PATH=$(normalize_path_for_platform "$GF_RELEASES_PATH")
243
+ GF_HOTFIXES_PATH=$(normalize_path_for_platform "$GF_HOTFIXES_PATH")
244
+ [ -n "$GF_WORKSPACE_PATH" ] && GF_WORKSPACE_PATH=$(normalize_path_for_platform "$GF_WORKSPACE_PATH")
245
+
133
246
  # Export config file path for steps that need to update it
134
247
  GF_CONFIG_FILE="$CONFIG_FILE"
135
248
  }
@@ -201,6 +314,26 @@ cleanup_worktree_for_branch() {
201
314
 
202
315
  ---
203
316
 
317
+ ## RESOLVE_WORKSPACE
318
+
319
+ Resolves the workspace JSON file by walking up the directory tree.
320
+
321
+ ```bash
322
+ resolve_workspace_path() {
323
+ local dir="$(pwd)"
324
+ while [ "$dir" != "/" ] && [ "$dir" != "." ]; do
325
+ [ -f "$dir/.smartstack-workspace.json" ] && {
326
+ echo "$dir/.smartstack-workspace.json"
327
+ return 0
328
+ }
329
+ dir=$(dirname "$dir")
330
+ done
331
+ return 1
332
+ }
333
+ ```
334
+
335
+ ---
336
+
204
337
  ## SYNC_REMOTE
205
338
 
206
339
  Syncs with remote and displays status.
@@ -221,11 +354,20 @@ sync_with_remote() {
221
354
 
222
355
  ## CONFIG_TEMPLATE
223
356
 
224
- GitFlow configuration JSON template v2.0.0 (aligned with `templates/config.json`).
357
+ GitFlow configuration JSON template v2.1.0 (aligned with `templates/config.json`).
225
358
 
226
359
  ```json
227
360
  {
228
- "version": "2.0.0",
361
+ "version": "2.1.0",
362
+ "platform": {
363
+ "detected": "",
364
+ "shell": "",
365
+ "detectedAt": ""
366
+ },
367
+ "workspace": {
368
+ "path": "",
369
+ "name": ""
370
+ },
229
371
  "repository": {
230
372
  "name": "",
231
373
  "rootFolder": "",
@@ -16,12 +16,18 @@ Display complete GitFlow state including branches, worktrees, remotes, and pendi
16
16
  ### 1. Load Config and Repository Info
17
17
 
18
18
  ```bash
19
- # Load GitFlow config (sets GF_* variables)
19
+ # Detect platform first (needed for path translation)
20
+ detect_platform
21
+
22
+ # Load GitFlow config (sets GF_* variables, translates paths for current platform)
20
23
  read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
21
24
 
22
25
  REPO_NAME="$GF_PROJECT_NAME"
23
26
  CURRENT=$(git rev-parse --abbrev-ref HEAD)
24
27
  GIT_PROVIDER="$GF_PROVIDER"
28
+
29
+ # Workspace info (v2.1.0+)
30
+ WS_FILE=$(resolve_workspace_path 2>/dev/null)
25
31
  ```
26
32
 
27
33
  ### 2. Branch Status
@@ -99,7 +105,11 @@ fi
99
105
  ╠══════════════════════════════════════════════════════════════════╣
100
106
  ║ Repository: {REPO_NAME} ║
101
107
  ║ Provider: {GIT_PROVIDER} ║
108
+ ║ Platform: {GF_PLATFORM} ({GF_SHELL}) ║
102
109
  ║ Current: {CURRENT} ║
110
+ {if WS_FILE}
111
+ ║ Workspace: {dirname(WS_FILE)} ║
112
+ {endif}
103
113
  ╠══════════════════════════════════════════════════════════════════╣
104
114
 
105
115
  ## Main Branches
@@ -180,7 +180,7 @@ PROBLEM: {what was wrong}
180
180
  SOLUTION: {what was done}
181
181
  IMPACT: {benefit}
182
182
 
183
- Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
183
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
184
184
  ```
185
185
 
186
186
  ### 6. Create Commit
@@ -36,6 +36,22 @@ Set up GitFlow configuration with bare repository, worktrees, and branches.
36
36
  ### 1. Detect Environment (for defaults only)
37
37
 
38
38
  ```bash
39
+ # PLATFORM DETECTION (required for correct path handling on WSL/Windows/macOS/Linux)
40
+ if [ -f /proc/version ] && grep -qi "microsoft\|wsl" /proc/version 2>/dev/null; then
41
+ GF_PLATFORM="wsl"; GF_SHELL="bash"
42
+ elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "mingw"* ]] || [[ "$OSTYPE" == "cygwin" ]]; then
43
+ GF_PLATFORM="windows"; GF_SHELL="gitbash"
44
+ elif [[ -n "$WINDIR" ]] || [[ -n "$SystemRoot" ]]; then
45
+ GF_PLATFORM="windows"; GF_SHELL="powershell"
46
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
47
+ GF_PLATFORM="macos"; GF_SHELL="zsh"
48
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
49
+ GF_PLATFORM="linux"; GF_SHELL="bash"
50
+ else
51
+ GF_PLATFORM="unknown"; GF_SHELL="bash"
52
+ fi
53
+ echo "Platform: $GF_PLATFORM ($GF_SHELL)"
54
+
39
55
  # Check if we're in a git repository
40
56
  IS_GIT_REPO=$(git rev-parse --git-dir 2>/dev/null && echo "true" || echo "false")
41
57
 
@@ -405,54 +421,84 @@ AskUserQuestion:
405
421
 
406
422
  ### 8. Create Directory Structure
407
423
 
408
- **⛔ Create the COMPLETE structure:**
424
+ **⛔ CRITICAL: Use ABSOLUTE PATHS for ALL operations. NEVER use `cd` (it does not persist between Bash calls).**
425
+ **⛔ Use `git -C <path>` or `GIT_DIR=<path>` instead of `cd` + `git`.**
409
426
 
427
+ **Path normalization for WSL:**
410
428
  ```bash
411
- cd "{ROOT_FOLDER}"
412
-
413
- # Create bare repository if not exists
414
- if [ ! -d ".bare" ]; then
415
- git clone --bare "{REPO_URL}" .bare
416
- # Configure bare repo for worktrees
417
- cd .bare
418
- git config core.bare false
419
- git config core.worktree ..
420
- cd ..
429
+ # If on WSL, translate Windows paths to /mnt/ format
430
+ # normalize_path_for_platform() from _shared.md handles this
431
+ # Example: D:/projects/MyApp /mnt/d/projects/MyApp
432
+ PROJECT_BASE="{ROOT_FOLDER}" # Must be already normalized for current platform
433
+ ```
434
+
435
+ **⛔ Create the COMPLETE structure with absolute paths:**
436
+
437
+ ```bash
438
+ PROJECT_BASE="{ROOT_FOLDER}"
439
+
440
+ # Create subdirectories (absolute paths)
441
+ mkdir -p "$PROJECT_BASE/features" "$PROJECT_BASE/releases" "$PROJECT_BASE/hotfixes"
442
+
443
+ # Create bare repository if not exists (absolute path, no cd)
444
+ if [ ! -d "$PROJECT_BASE/.bare" ]; then
445
+ git clone --bare "{REPO_URL}" "$PROJECT_BASE/.bare"
446
+
447
+ # Configure bare repo for worktrees (using git -C, no cd)
448
+ git -C "$PROJECT_BASE/.bare" config core.bare false
449
+ git -C "$PROJECT_BASE/.bare" config core.worktree ..
421
450
  fi
422
451
 
423
- # Create worktree directories
424
- mkdir -p features releases hotfixes
452
+ # Create .git pseudo-file pointing to .bare
453
+ echo "gitdir: ./.bare" > "$PROJECT_BASE/.git"
425
454
 
426
- # Organized mode: numbered main folders
455
+ # Organized mode: numbered main folders (absolute paths, GIT_DIR instead of cd)
427
456
  if [ "$WORKTREE_MODE" = "organized" ]; then
428
- # Create main worktree
429
- [ ! -d "01-Main" ] && git worktree add 01-Main main
457
+ [ ! -d "$PROJECT_BASE/01-Main" ] && \
458
+ GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/01-Main" main
430
459
 
431
- # Create develop worktree
432
- [ ! -d "02-Develop" ] && git worktree add 02-Develop develop
460
+ [ ! -d "$PROJECT_BASE/02-Develop" ] && \
461
+ GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/02-Develop" develop
433
462
  fi
434
463
 
435
- # Simple mode: named folders
464
+ # Simple mode: named folders (absolute paths)
436
465
  if [ "$WORKTREE_MODE" = "simple" ]; then
437
- [ ! -d "main" ] && git worktree add main main
438
- [ ! -d "develop" ] && git worktree add develop develop
466
+ [ ! -d "$PROJECT_BASE/main" ] && \
467
+ GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/main" main
468
+
469
+ [ ! -d "$PROJECT_BASE/develop" ] && \
470
+ GIT_DIR="$PROJECT_BASE/.bare" git worktree add "$PROJECT_BASE/develop" develop
439
471
  fi
440
472
 
441
- # Create gitflow config directory (in develop worktree)
442
- DEVELOP_PATH=$([ "$WORKTREE_MODE" = "organized" ] && echo "02-Develop" || echo "develop")
443
- mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
473
+ # Create gitflow config directory (absolute paths)
474
+ DEVELOP_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "02-Develop" || echo "develop")
475
+ mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/plans"
476
+ mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/logs"
477
+ mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/cache"
478
+ mkdir -p "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow/backup"
444
479
  ```
445
480
 
446
481
  ### 9. Create Configuration
447
482
 
448
- **Write `.claude/gitflow/config.json` in develop worktree:**
483
+ **Write `.claude/gitflow/config.json` in develop worktree.**
484
+
485
+ **⛔ IMPORTANT: Store paths using `normalize_path_for_storage()` format (Windows-style: `D:/path/to/folder`).** The `read_gitflow_config()` in `_shared.md` translates them to platform format at read time. This ensures WSL and Windows can share the same config.
449
486
 
450
487
  ```json
451
488
  {
452
- "version": "2.0.0",
489
+ "version": "2.1.0",
490
+ "platform": {
491
+ "detected": "{GF_PLATFORM}",
492
+ "shell": "{GF_SHELL}",
493
+ "detectedAt": "{ISO_DATE}"
494
+ },
495
+ "workspace": {
496
+ "path": "{WORKSPACE_DIR_STORAGE_FORMAT}",
497
+ "name": ""
498
+ },
453
499
  "repository": {
454
500
  "name": "{PROJECT_NAME}",
455
- "rootFolder": "{ROOT_FOLDER}",
501
+ "rootFolder": "{ROOT_FOLDER_STORAGE_FORMAT}",
456
502
  "nameVariants": {
457
503
  "pascalCaseDot": "{PascalCase.Dot}",
458
504
  "pascalCase": "{PascalCase}",
@@ -479,11 +525,11 @@ mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
479
525
  "enabled": true,
480
526
  "mode": "{WORKTREE_MODE}",
481
527
  "structure": {
482
- "main": "{ROOT_FOLDER}/01-Main",
483
- "develop": "{ROOT_FOLDER}/02-Develop",
484
- "features": "{ROOT_FOLDER}/features",
485
- "releases": "{ROOT_FOLDER}/releases",
486
- "hotfixes": "{ROOT_FOLDER}/hotfixes"
528
+ "main": "{ROOT_FOLDER_STORAGE_FORMAT}/01-Main",
529
+ "develop": "{ROOT_FOLDER_STORAGE_FORMAT}/02-Develop",
530
+ "features": "{ROOT_FOLDER_STORAGE_FORMAT}/features",
531
+ "releases": "{ROOT_FOLDER_STORAGE_FORMAT}/releases",
532
+ "hotfixes": "{ROOT_FOLDER_STORAGE_FORMAT}/hotfixes"
487
533
  }
488
534
  },
489
535
  "versioning": {
@@ -513,21 +559,60 @@ mkdir -p "$DEVELOP_PATH/.claude/gitflow/{plans,logs,cache,backup}"
513
559
  }
514
560
  ```
515
561
 
562
+ **Path storage convention:**
563
+ - `{ROOT_FOLDER_STORAGE_FORMAT}` = result of `normalize_path_for_storage("{ROOT_FOLDER}")`
564
+ - On WSL: `/mnt/d/projects/MyApp` → stored as `D:/projects/MyApp`
565
+ - On Windows: `D:\projects\MyApp` → stored as `D:/projects/MyApp`
566
+ - On Linux/macOS: `/home/user/projects/MyApp` → stored as-is
567
+
516
568
  ### 10. Detect Version
517
569
 
570
+ **⛔ Use absolute paths with `git -C`, no `cd`.**
571
+
518
572
  ```bash
519
- # In develop worktree
520
- cd "$DEVELOP_PATH"
573
+ DEVELOP_FULL_PATH="$PROJECT_BASE/$DEVELOP_DIR"
521
574
 
522
575
  # Priority: csproj > Directory.Build.props > package.json > VERSION > tag
523
- VERSION=$(grep -oP '<Version>\K[^<]+' *.csproj 2>/dev/null | head -1)
524
- [ -z "$VERSION" ] && VERSION=$(grep -oP '<Version>\K[^<]+' Directory.Build.props 2>/dev/null)
525
- [ -z "$VERSION" ] && VERSION=$(grep -oP '"version":\s*"\K[^"]+' package.json 2>/dev/null)
526
- [ -z "$VERSION" ] && VERSION=$(cat VERSION 2>/dev/null)
527
- [ -z "$VERSION" ] && VERSION=$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//')
576
+ VERSION=$(grep -oP '<Version>\K[^<]+' "$DEVELOP_FULL_PATH"/*.csproj 2>/dev/null | head -1)
577
+ [ -z "$VERSION" ] && VERSION=$(grep -oP '<Version>\K[^<]+' "$DEVELOP_FULL_PATH/Directory.Build.props" 2>/dev/null)
578
+ [ -z "$VERSION" ] && VERSION=$(grep -oP '"version":\s*"\K[^"]+' "$DEVELOP_FULL_PATH/package.json" 2>/dev/null)
579
+ [ -z "$VERSION" ] && VERSION=$(cat "$DEVELOP_FULL_PATH/VERSION" 2>/dev/null)
580
+ [ -z "$VERSION" ] && VERSION=$(git -C "$DEVELOP_FULL_PATH" describe --tags --abbrev=0 2>/dev/null | sed 's/^v//')
528
581
  [ -z "$VERSION" ] && VERSION="0.1.0"
529
582
  ```
530
583
 
584
+ ### 10b. Post-Init Validation
585
+
586
+ **⛔ MANDATORY: Verify the structure was created correctly.**
587
+
588
+ ```bash
589
+ PROJECT_BASE="{ROOT_FOLDER}"
590
+ MAIN_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "01-Main" || echo "main")
591
+ DEVELOP_DIR=$([ "$WORKTREE_MODE" = "organized" ] && echo "02-Develop" || echo "develop")
592
+ ERRORS=0
593
+
594
+ # Verify bare repo
595
+ [ -f "$PROJECT_BASE/.bare/HEAD" ] && echo "✓ .bare/HEAD OK" || { echo "❌ .bare/HEAD missing"; ERRORS=$((ERRORS+1)); }
596
+
597
+ # Verify worktrees on correct branches
598
+ MAIN_BRANCH=$(git -C "$PROJECT_BASE/$MAIN_DIR" branch --show-current 2>/dev/null)
599
+ [ "$MAIN_BRANCH" = "main" ] && echo "✓ $MAIN_DIR on main" || { echo "❌ $MAIN_DIR on '$MAIN_BRANCH', expected 'main'"; ERRORS=$((ERRORS+1)); }
600
+
601
+ DEVELOP_BRANCH=$(git -C "$PROJECT_BASE/$DEVELOP_DIR" branch --show-current 2>/dev/null)
602
+ [ "$DEVELOP_BRANCH" = "develop" ] && echo "✓ $DEVELOP_DIR on develop" || { echo "❌ $DEVELOP_DIR on '$DEVELOP_BRANCH', expected 'develop'"; ERRORS=$((ERRORS+1)); }
603
+
604
+ # Verify directories
605
+ for subdir in features releases hotfixes; do
606
+ [ -d "$PROJECT_BASE/$subdir" ] && echo "✓ $subdir/ OK" || { echo "❌ $subdir/ missing"; ERRORS=$((ERRORS+1)); }
607
+ done
608
+
609
+ # Verify config directory
610
+ [ -d "$PROJECT_BASE/$DEVELOP_DIR/.claude/gitflow" ] && echo "✓ .claude/gitflow/ OK" || { echo "❌ .claude/gitflow/ missing"; ERRORS=$((ERRORS+1)); }
611
+
612
+ echo ""
613
+ [ "$ERRORS" -eq 0 ] && echo "VALIDATION: ALL CHECKS PASSED" || echo "VALIDATION: $ERRORS error(s) detected - check output above"
614
+ ```
615
+
531
616
  ### 11. Summary
532
617
 
533
618
  ```
@@ -538,7 +623,9 @@ VERSION=$(grep -oP '<Version>\K[^<]+' *.csproj 2>/dev/null | head -1)
538
623
  ║ Root: {ROOT_FOLDER} ║
539
624
  ║ Remote: {REPO_URL} ║
540
625
  ║ Provider: {GIT_PROVIDER} ║
626
+ ║ Platform: {GF_PLATFORM} ({GF_SHELL}) ║
541
627
  ║ Version: {VERSION} ║
628
+ ║ Config: v2.1.0 ║
542
629
  ╠══════════════════════════════════════════════════════════════════╣
543
630
  ║ Structure: ║
544
631
  ║ ├── .bare/ (git bare repository) ║
@@ -548,6 +635,8 @@ VERSION=$(grep -oP '<Version>\K[^<]+' *.csproj 2>/dev/null | head -1)
548
635
  ║ ├── releases/ (release worktrees) ✅ ║
549
636
  ║ └── hotfixes/ (hotfix worktrees) ✅ ║
550
637
  ╠══════════════════════════════════════════════════════════════════╣
638
+ ║ Validation: {ERRORS == 0 ? "ALL CHECKS PASSED" : "errors"} ║
639
+ ╠══════════════════════════════════════════════════════════════════╣
551
640
  {if SIBLING_PROJECTS not empty}
552
641
  ║ Workspace: {WORKSPACE_DIR} ║
553
642
  ║ GitFlow projects: {#SIBLING_PROJECTS + 1} (including this one) ║
@@ -598,3 +687,77 @@ Before completing init, verify:
598
687
  ## NEXT STEP:
599
688
 
600
689
  Init is standalone. User should `cd 02-Develop` then run `/gitflow -f <feature-name>`.
690
+
691
+ ---
692
+
693
+ ## WORKSPACE MODE (`--workspace`)
694
+
695
+ When called with `init --workspace`, batch-initialize all repos in a workspace.
696
+
697
+ ### Workspace Execution Sequence:
698
+
699
+ 1. **Ask workspace directory:**
700
+ ```yaml
701
+ AskUserQuestion:
702
+ - header: "Workspace"
703
+ question: "Where is the workspace root? (parent directory containing all repos)"
704
+ options:
705
+ - label: "Use parent folder (Recommended)"
706
+ description: "{DETECTED_FOLDER}/"
707
+ - label: "Custom path"
708
+ description: "Specify a different location"
709
+ multiSelect: false
710
+ ```
711
+
712
+ 2. **Detect or ask for repos:**
713
+ ```yaml
714
+ AskUserQuestion:
715
+ - header: "Repos"
716
+ question: "How to identify repositories to initialize?"
717
+ options:
718
+ - label: "Detect from folders (Recommended)"
719
+ description: "Scan workspace for git repositories"
720
+ - label: "Enter URLs"
721
+ description: "Provide a list of repository URLs"
722
+ multiSelect: false
723
+ ```
724
+
725
+ 3. **Create `.smartstack-workspace.json`:**
726
+ ```json
727
+ {
728
+ "version": "1.0.0",
729
+ "name": "{WORKSPACE_NAME}",
730
+ "createdAt": "{ISO_DATE}",
731
+ "updatedAt": "{ISO_DATE}",
732
+ "platform": {
733
+ "detected": "{GF_PLATFORM}",
734
+ "shell": "{GF_SHELL}"
735
+ },
736
+ "repositories": [],
737
+ "defaults": {
738
+ "provider": "{GIT_PROVIDER}",
739
+ "worktreeMode": "organized",
740
+ "language": "en"
741
+ }
742
+ }
743
+ ```
744
+
745
+ 4. **Loop: For each repo, run Steps 1-10b with workspace defaults pre-populated.**
746
+ - Skip questions where workspace defaults apply (provider, worktree mode)
747
+ - Add each repo to `workspace.json` after successful init
748
+
749
+ 5. **Display global summary:**
750
+ ```
751
+ ╔══════════════════════════════════════════════════════════════════╗
752
+ ║ WORKSPACE INITIALIZED ║
753
+ ╠══════════════════════════════════════════════════════════════════╣
754
+ ║ Workspace: {WORKSPACE_DIR} ║
755
+ ║ Platform: {GF_PLATFORM} ({GF_SHELL}) ║
756
+ ║ Repos: {REPO_COUNT} initialized ║
757
+ ╠══════════════════════════════════════════════════════════════════╣
758
+ {for each REPO}
759
+ ║ ✅ {REPO_NAME} ║
760
+ ║ 01-Main/ ✓ 02-Develop/ ✓ config.json ✓ ║
761
+ {end for}
762
+ ╚══════════════════════════════════════════════════════════════════╝
763
+ ```
@@ -38,13 +38,25 @@ fi
38
38
 
39
39
  ```bash
40
40
  CURRENT=$(git rev-parse --abbrev-ref HEAD)
41
+ BRANCH_TYPE=$(echo $CURRENT | cut -d'/' -f1)
42
+
43
+ # CRITICAL: Verify config was loaded
44
+ if [ -z "$GF_MAIN_BRANCH" ] || [ -z "$GF_DEVELOP_BRANCH" ]; then
45
+ echo "❌ GitFlow config not loaded properly"
46
+ echo "→ Variables GF_MAIN_BRANCH and GF_DEVELOP_BRANCH are empty"
47
+ exit 1
48
+ fi
41
49
 
42
- case "$CURRENT" in
43
- ${GF_FEATURE_PREFIX}*) TARGET_BRANCH="$GF_DEVELOP_BRANCH" ;;
44
- ${GF_RELEASE_PREFIX}*) TARGET_BRANCH="$GF_MAIN_BRANCH" ;;
45
- ${GF_HOTFIX_PREFIX}*) TARGET_BRANCH="$GF_MAIN_BRANCH" ;;
46
- *) TARGET_BRANCH="$GF_DEVELOP_BRANCH" ;;
50
+ # Determine target branch based on type (using config values)
51
+ case "$BRANCH_TYPE" in
52
+ feature) TARGET_BRANCH="$GF_DEVELOP_BRANCH" ;;
53
+ release) TARGET_BRANCH="$GF_MAIN_BRANCH" ;;
54
+ hotfix) TARGET_BRANCH="$GF_MAIN_BRANCH" ;;
55
+ *) TARGET_BRANCH="$GF_DEVELOP_BRANCH" ;;
47
56
  esac
57
+
58
+ echo "✓ Branch: $CURRENT (type: $BRANCH_TYPE)"
59
+ echo "✓ Target: $TARGET_BRANCH"
48
60
  ```
49
61
 
50
62
  ### 3. Check Prerequisites
@@ -1,5 +1,14 @@
1
1
  {
2
- "version": "2.0.0",
2
+ "version": "2.1.0",
3
+ "platform": {
4
+ "detected": "",
5
+ "shell": "",
6
+ "detectedAt": ""
7
+ },
8
+ "workspace": {
9
+ "path": "",
10
+ "name": ""
11
+ },
3
12
  "repository": {
4
13
  "name": "",
5
14
  "rootFolder": "",
@@ -109,22 +109,27 @@ The loop only stops when this exact tag is output or max iterations reached.
109
109
 
110
110
  <workflow>
111
111
  **Standard flow (single module):**
112
- 1. Parse flags and task description
113
- 2. Verify MCP servers are available (MANDATORY)
114
- 3. Initialize .ralph/ structure and state files
115
- 4. Load current task from prd.json (or create initial task breakdown with categories, dependencies, and acceptance criteria)
116
- 5. Execute ONE task per iteration
117
- 6. Commit changes, update progress
118
- 7. Check completion criteria
119
- 8. If complete: generate final report
112
+ 1. Parse flags and task description (step-00)
113
+ 2. Verify MCP servers are available (step-00, MANDATORY)
114
+ 3. Initialize .ralph/ structure and state files (step-00)
115
+ 4. Load current task from prd.json create task breakdown if new (step-01, READ ONCE)
116
+ 5. Execute first task (step-02, READ ONCE)
117
+ 6. Commit changes, update progress (step-03, READ ONCE)
118
+ 7. Check completion → enter COMPACT LOOP (step-04)
119
+ 8. **COMPACT LOOP** (step-04 section 5, NO re-reading step files):
120
+ - Find eligible tasks → batch by category (max 5)
121
+ - Execute batch inline
122
+ - Commit batch
123
+ - Re-check completion → loop or finish
124
+ 9. When complete: generate final report (step-05)
120
125
 
121
126
  **Multi-module flow (from BA handoff):**
122
127
  1-3. Same as standard flow
123
128
  4. Detect `prd-*.json` files → create `modules-queue.json`
124
129
  5. Copy current module's prd to `prd.json`
125
- 6. Execute all tasks for current module (standard loop: steps 01→02→03→04)
126
- 7. When module complete: advance to next module in queue
127
- 8. Repeat steps 5-7 for each module
130
+ 6. Execute all tasks for current module via COMPACT LOOP
131
+ 7. When module complete: advance to next module in queue (step-04 section 3)
132
+ 8. Repeat steps 5-7 for each module (step-01 is re-read ONLY for module transitions)
128
133
  9. When all modules done: generate cross-module report
129
134
  </workflow>
130
135
 
@@ -279,12 +284,14 @@ Before ANY work, verify MCP servers:
279
284
 
280
285
  <execution_rules>
281
286
 
282
- - **Load one step at a time** - Only load the current step file
283
- - **VERIFY MCP FIRST** - Never skip MCP validation
284
- - **ONE TASK PER ITERATION** - Don't batch tasks
285
- - **COMMIT AFTER EACH TASK** - Atomic progress
287
+ - **Load step files ONCE** - Step files are read only on FIRST iteration. After that, use the COMPACT LOOP in step-04 section 5.
288
+ - **VERIFY MCP FIRST** - Never skip MCP validation at init
289
+ - **BATCH same-category tasks** - Execute up to 5 tasks of the same category per iteration (reduces loop iterations from 30+ to ~8)
290
+ - **COMMIT AFTER EACH BATCH** - One commit per batch, not per individual task
286
291
  - **UPDATE progress.txt** - Persist learnings
287
292
  - **NEVER fake completion** - Only output promise when truly done
293
+ - **NEVER STOP THE LOOP** - The loop is AUTONOMOUS. DO NOT pause between iterations. DO NOT wait for user input. Only stop on: completion, max iterations, dead-end, or explicit user interruption. Stopping for any other reason wastes context and causes re-reads.
294
+ - **COMPACT OUTPUT** - During loop iterations, use 1-2 lines per task. Save verbose output for the final report.
288
295
  </execution_rules>
289
296
 
290
297
  <success_criteria>