@atlashub/smartstack-cli 2.8.0 → 3.0.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 (74) hide show
  1. package/.documentation/business-analyse.html +81 -17
  2. package/dist/index.js +94 -21
  3. package/dist/index.js.map +1 -1
  4. package/dist/mcp-entry.mjs +1302 -223
  5. package/dist/mcp-entry.mjs.map +1 -1
  6. package/package.json +1 -1
  7. package/templates/agents/efcore/db-deploy.md +1 -1
  8. package/templates/agents/efcore/migration.md +26 -10
  9. package/templates/agents/efcore/rebase-snapshot.md +24 -7
  10. package/templates/agents/efcore/squash.md +73 -57
  11. package/templates/agents/gitflow/commit.md +138 -18
  12. package/templates/agents/gitflow/exec.md +1 -1
  13. package/templates/agents/gitflow/finish.md +79 -62
  14. package/templates/agents/gitflow/init-clone.md +186 -0
  15. package/templates/agents/gitflow/init-detect.md +137 -0
  16. package/templates/agents/gitflow/init-validate.md +210 -0
  17. package/templates/agents/gitflow/init.md +231 -74
  18. package/templates/agents/gitflow/merge.md +65 -33
  19. package/templates/agents/gitflow/pr.md +93 -49
  20. package/templates/agents/gitflow/start.md +76 -33
  21. package/templates/agents/gitflow/status.md +41 -71
  22. package/templates/hooks/appsettings-guard.sh +76 -0
  23. package/templates/hooks/ef-migration-check.md +1 -1
  24. package/templates/hooks/hooks.json +9 -0
  25. package/templates/project/test-frontend/msw/handlers.ts +58 -0
  26. package/templates/project/test-frontend/msw/server.ts +25 -0
  27. package/templates/project/test-frontend/setup.ts +16 -0
  28. package/templates/project/test-frontend/test-utils.tsx +59 -0
  29. package/templates/project/test-frontend/vitest.config.ts +31 -0
  30. package/templates/skills/_resources/config-safety.md +61 -0
  31. package/templates/skills/_resources/formatting-guide.md +2 -2
  32. package/templates/skills/_shared.md +21 -0
  33. package/templates/skills/application/SKILL.md +32 -3
  34. package/templates/skills/application/steps/step-04-backend.md +21 -0
  35. package/templates/skills/application/steps/step-05-frontend.md +20 -36
  36. package/templates/skills/application/steps/step-07-tests.md +259 -120
  37. package/templates/skills/business-analyse/SKILL.md +57 -28
  38. package/templates/skills/business-analyse/_shared.md +70 -39
  39. package/templates/skills/business-analyse/html/ba-interactive.html +2622 -0
  40. package/templates/skills/business-analyse/questionnaire/00-application.md +123 -131
  41. package/templates/skills/business-analyse/questionnaire/01-context.md +173 -24
  42. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +170 -50
  43. package/templates/skills/business-analyse/questionnaire/03-scope.md +154 -48
  44. package/templates/skills/business-analyse/questionnaire/10-documentation.md +1 -1
  45. package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +135 -0
  46. package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +136 -0
  47. package/templates/skills/business-analyse/questionnaire.md +55 -46
  48. package/templates/skills/business-analyse/steps/step-00-init.md +24 -2
  49. package/templates/skills/business-analyse/steps/step-01-cadrage.md +31 -20
  50. package/templates/skills/business-analyse/steps/step-03-specify.md +1 -0
  51. package/templates/skills/business-analyse/steps/step-05-handoff.md +103 -1
  52. package/templates/skills/business-analyse/steps/step-06-extract.md +518 -0
  53. package/templates/skills/check-version/SKILL.md +1 -1
  54. package/templates/skills/efcore/steps/db/step-deploy.md +22 -3
  55. package/templates/skills/efcore/steps/db/step-reset.md +27 -4
  56. package/templates/skills/efcore/steps/db/step-seed.md +46 -2
  57. package/templates/skills/efcore/steps/db/step-status.md +14 -0
  58. package/templates/skills/efcore/steps/migration/step-01-check.md +31 -5
  59. package/templates/skills/efcore/steps/migration/step-02-create.md +20 -4
  60. package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +60 -0
  61. package/templates/skills/efcore/steps/shared/step-00-init.md +47 -8
  62. package/templates/skills/efcore/steps/squash/step-03-create.md +27 -5
  63. package/templates/skills/gitflow/SKILL.md +91 -29
  64. package/templates/skills/gitflow/_shared.md +144 -2
  65. package/templates/skills/gitflow/phases/status.md +11 -1
  66. package/templates/skills/gitflow/steps/step-commit.md +1 -1
  67. package/templates/skills/gitflow/steps/step-init.md +202 -39
  68. package/templates/skills/gitflow/templates/config.json +10 -1
  69. package/templates/skills/ralph-loop/steps/step-03-commit.md +2 -2
  70. package/templates/skills/validate-feature/SKILL.md +83 -0
  71. package/templates/skills/validate-feature/steps/step-01-compile.md +38 -0
  72. package/templates/skills/validate-feature/steps/step-02-unit-tests.md +45 -0
  73. package/templates/skills/validate-feature/steps/step-03-integration-tests.md +53 -0
  74. 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
+ ```
@@ -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": "",
@@ -44,7 +44,7 @@ Task {current_task_id}/{tasks_total} - Iteration {current_iteration}
44
44
  Category: {current_task_category}
45
45
  {current_module ? "Module: " + current_module : ""}
46
46
 
47
- Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
47
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
48
48
  EOF
49
49
  )"
50
50
  ```
@@ -189,7 +189,7 @@ Iteration {current_iteration} complete
189
189
  Status: {task.status}
190
190
  {current_module ? "Module: " + current_module : ""}
191
191
 
192
- Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
192
+ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
193
193
  EOF
194
194
  )"
195
195
  ```
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: validate-feature
3
+ description: Validate that a scaffolded feature works end-to-end (compile, test, API smoke test)
4
+ version: 1.0.0
5
+ author: SmartStack
6
+ tags: [testing, validation, smoke-test, integration]
7
+ ---
8
+
9
+ # /validate-feature
10
+
11
+ ## PURPOSE
12
+
13
+ Validates that a scaffolded SmartStack feature **actually works** by running:
14
+ 1. Compilation check (`dotnet build`)
15
+ 2. Unit tests (`dotnet test`)
16
+ 3. Integration tests (`dotnet test --filter`)
17
+ 4. API smoke test (start API, hit CRUD endpoints, verify responses)
18
+
19
+ ## WHEN TO USE
20
+
21
+ - After running `/application` to scaffold a new feature
22
+ - After making changes to backend code (controllers, services, entities)
23
+ - Before committing to verify nothing is broken
24
+ - As a confidence check that the full stack works
25
+
26
+ ## USAGE
27
+
28
+ ```
29
+ /validate-feature {EntityName}
30
+ ```
31
+
32
+ **Examples:**
33
+ ```
34
+ /validate-feature Product
35
+ /validate-feature Order
36
+ /validate-feature UserProfile
37
+ ```
38
+
39
+ ## PARAMETERS
40
+
41
+ | Parameter | Required | Description |
42
+ |-----------|----------|-------------|
43
+ | `{entity_name}` | YES | PascalCase entity name to validate |
44
+
45
+ ## PREREQUISITES
46
+
47
+ - The solution must compile
48
+ - Test project must exist with infrastructure (SmartStackTestFactory, IntegrationTestBase)
49
+ - Entity must have been scaffolded (controller, service, entity files exist)
50
+
51
+ ## EXECUTION
52
+
53
+ This skill follows a 4-step sequential workflow:
54
+
55
+ | Step | File | Description | Blocking |
56
+ |------|------|-------------|----------|
57
+ | 1 | `steps/step-01-compile.md` | Build the full solution | YES |
58
+ | 2 | `steps/step-02-unit-tests.md` | Run unit tests | YES |
59
+ | 3 | `steps/step-03-integration-tests.md` | Run integration tests | YES |
60
+ | 4 | `steps/step-04-api-smoke.md` | Start API and test CRUD endpoints | YES |
61
+
62
+ Each step must PASS before proceeding to the next.
63
+
64
+ ## OUTPUT
65
+
66
+ A validation report showing pass/fail for each check:
67
+
68
+ ```
69
+ ## Feature Validation: {EntityName}
70
+
71
+ | Check | Result |
72
+ |-------|--------|
73
+ | Solution build | PASS |
74
+ | Unit tests (X passed) | PASS |
75
+ | Integration tests (X passed) | PASS |
76
+ | API smoke: GET /api/{entity} | PASS (200) |
77
+ | API smoke: POST /api/{entity} | PASS (201) |
78
+ | API smoke: GET /api/{entity}/{id} | PASS (200) |
79
+ | API smoke: PUT /api/{entity}/{id} | PASS (200) |
80
+ | API smoke: DELETE /api/{entity}/{id} | PASS (204) |
81
+
82
+ Result: ALL CHECKS PASSED
83
+ ```