@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
@@ -29,6 +29,16 @@ Populate the database with test or initial data using EF Core conventions.
29
29
  ### 1. Environment Check
30
30
 
31
31
  ```bash
32
+ # Validate required variables from step-00-init
33
+ for VAR_NAME in DBCONTEXT DBCONTEXT_TYPE INFRA_PROJECT STARTUP_PROJECT SELECTED_ENV; do
34
+ eval VAR_VALUE=\$$VAR_NAME
35
+ if [ -z "$VAR_VALUE" ]; then
36
+ echo "ERROR: Required variable $VAR_NAME is not set"
37
+ echo "Run step-00-init first"
38
+ exit 1
39
+ fi
40
+ done
41
+
32
42
  echo "Seed Configuration"
33
43
  echo "=================="
34
44
  echo ""
@@ -118,9 +128,10 @@ echo ""
118
128
  echo "Running seeder class..."
119
129
 
120
130
  dotnet run --project "$STARTUP_PROJECT" -- --seed
131
+ EXIT_CODE=$?
121
132
 
122
- if [ $? -ne 0 ]; then
123
- echo "Seed command failed or not supported."
133
+ if [ $EXIT_CODE -ne 0 ]; then
134
+ echo "Seed command failed or not supported (exit code: $EXIT_CODE)"
124
135
  echo "Check if --seed argument is implemented in Program.cs"
125
136
  fi
126
137
  ```
@@ -239,6 +250,39 @@ builder.HasData(new User {
239
250
 
240
251
  ---
241
252
 
253
+ ## BOTH CONTEXTS:
254
+
255
+ If `RUN_BOTH=true` (auto-detected for client projects with SmartStack NuGet):
256
+
257
+ Run the seed sequence for both contexts, in order:
258
+
259
+ ```bash
260
+ # 1. Seed CoreDbContext first (system data: Users, Roles, Permissions...)
261
+ echo "=== Seeding CoreDbContext (core schema) ==="
262
+ DBCONTEXT="CoreDbContext"
263
+ # Run steps 2-6 with CoreDbContext...
264
+
265
+ # 2. Then ExtensionsDbContext (client data)
266
+ echo ""
267
+ echo "=== Seeding ExtensionsDbContext (extensions schema) ==="
268
+ DBCONTEXT="ExtensionsDbContext"
269
+ # Run steps 2-6 with ExtensionsDbContext...
270
+ ```
271
+
272
+ **Order matters:** Core MUST be seeded first (Extensions may reference Core data via foreign keys).
273
+
274
+ ---
275
+
276
+ ## OPTIONS:
277
+
278
+ | Option | Description |
279
+ |--------|-------------|
280
+ | `--env {name}` | Use appsettings.{name}.json |
281
+ | `--context {name}` | Specify DbContext |
282
+ | `--method {name}` | Force seed method (hasdata, seeder-class, cli-argument) |
283
+
284
+ ---
285
+
242
286
  ## COMPLETION:
243
287
 
244
288
  Seed data applied. Use `/efcore db-status` to verify.
@@ -18,6 +18,20 @@ Display comprehensive status of EF Core migrations and database connection.
18
18
 
19
19
  ## EXECUTION SEQUENCE:
20
20
 
21
+ ### 0. Validate Required Variables
22
+
23
+ ```bash
24
+ # Validate required variables from step-00-init
25
+ for VAR_NAME in DBCONTEXT DBCONTEXT_TYPE INFRA_PROJECT STARTUP_PROJECT SELECTED_ENV; do
26
+ eval VAR_VALUE=\$$VAR_NAME
27
+ if [ -z "$VAR_VALUE" ]; then
28
+ echo "ERROR: Required variable $VAR_NAME is not set"
29
+ echo "Run step-00-init first"
30
+ exit 1
31
+ fi
32
+ done
33
+ ```
34
+
21
35
  ### 1. Display Configuration
22
36
 
23
37
  ```bash
@@ -16,6 +16,20 @@ Search for existing migrations for this branch and decide whether to recreate or
16
16
 
17
17
  ## EXECUTION SEQUENCE:
18
18
 
19
+ ### 0. Validate Required Variables
20
+
21
+ ```bash
22
+ # Validate required variables from step-00-init
23
+ for VAR_NAME in DBCONTEXT DBCONTEXT_TYPE MIGRATIONS_DIR INFRA_PROJECT STARTUP_PROJECT CURRENT_BRANCH BRANCH_TYPE; do
24
+ eval VAR_VALUE=\$$VAR_NAME
25
+ if [ -z "$VAR_VALUE" ]; then
26
+ echo "ERROR: Required variable $VAR_NAME is not set"
27
+ echo "Run step-00-init first"
28
+ exit 1
29
+ fi
30
+ done
31
+ ```
32
+
19
33
  ### 1. Build Search Pattern
20
34
 
21
35
  ```bash
@@ -42,13 +56,19 @@ echo " Pattern: *${BRANCH_SHORT}*"
42
56
  ### 2. Find Existing Migrations
43
57
 
44
58
  ```bash
45
- # Search for migrations that match this branch
46
- EXISTING_MIGRATIONS=$(find "$MIGRATIONS_DIR" -name "*.cs" 2>/dev/null | \
47
- grep -v "Designer\|Snapshot" | \
59
+ # Sanitize branch name: only allow alphanumeric, underscore (prevent regex/shell injection)
60
+ BRANCH_SHORT_SAFE=$(echo "$BRANCH_SHORT" | sed 's/[^a-zA-Z0-9_]//g')
61
+ if [ -z "$BRANCH_SHORT_SAFE" ]; then
62
+ echo "ERROR: Invalid branch name (no alphanumeric characters after sanitization)"
63
+ exit 1
64
+ fi
65
+
66
+ # Search for migrations matching this branch (-F = fixed-string, prevents regex injection)
67
+ EXISTING_MIGRATIONS=$(find "$MIGRATIONS_DIR" -name "*.cs" ! -name "*Designer.cs" ! -name "*Snapshot.cs" -type f 2>/dev/null | \
48
68
  xargs -I{} basename {} | \
49
- grep -i "$BRANCH_SHORT" || echo "")
69
+ grep -iF "$BRANCH_SHORT_SAFE" || echo "")
50
70
 
51
- EXISTING_COUNT=$(echo "$EXISTING_MIGRATIONS" | grep -c "." 2>/dev/null || echo "0")
71
+ EXISTING_COUNT=$(echo "$EXISTING_MIGRATIONS" | grep -c "^[^ ]" 2>/dev/null || echo "0")
52
72
 
53
73
  echo ""
54
74
  if [ "$EXISTING_COUNT" -gt 0 ]; then
@@ -107,6 +127,12 @@ if [ "$ACTION" = "recreate" ]; then
107
127
  rm -f "$MIGRATIONS_DIR/${mig_name}.cs"
108
128
  rm -f "$MIGRATIONS_DIR/${mig_name}.Designer.cs"
109
129
 
130
+ # Verify deletion succeeded
131
+ if [ -f "$MIGRATIONS_DIR/${mig_name}.cs" ]; then
132
+ echo " ERROR: Failed to delete ${mig_name}.cs"
133
+ exit 1
134
+ fi
135
+
110
136
  echo " Removed: $mig_name"
111
137
  done
112
138
 
@@ -48,7 +48,23 @@ echo ""
48
48
  echo "Description: $DESCRIPTION"
49
49
  ```
50
50
 
51
- ### 2. Call MCP for Migration Name (MANDATORY)
51
+ ### 2. Verify MCP Availability
52
+
53
+ ```bash
54
+ # Check MCP cache before calling suggest_migration
55
+ MCP_STATUS_FILE=".claude/mcp-status.json"
56
+
57
+ if [ -f "$MCP_STATUS_FILE" ]; then
58
+ MCP_STATUS=$(cat "$MCP_STATUS_FILE" | grep -o '"status":"[^"]*"' | head -1 | cut -d'"' -f4)
59
+ if [ "$MCP_STATUS" = "error" ]; then
60
+ echo "ERROR: MCP server is unavailable (status: error)"
61
+ echo "Run: /mcp healthcheck to diagnose"
62
+ exit 1
63
+ fi
64
+ fi
65
+ ```
66
+
67
+ ### 3. Call MCP for Migration Name (MANDATORY)
52
68
 
53
69
  ```javascript
54
70
  // DESCRIPTION = from user input (e.g., "Add User Roles")
@@ -68,7 +84,7 @@ MIGRATION_NAME = result.migrationName;
68
84
  - Hardcoding context as "core"
69
85
  - Using wrong version format
70
86
 
71
- ### 3. Display Migration Name
87
+ ### 4. Display Migration Name
72
88
 
73
89
  ```bash
74
90
  echo ""
@@ -77,7 +93,7 @@ echo "Context: $DBCONTEXT"
77
93
  echo ""
78
94
  ```
79
95
 
80
- ### 4. Create Migration
96
+ ### 5. Create Migration
81
97
 
82
98
  ```bash
83
99
  echo "Creating migration..."
@@ -91,7 +107,7 @@ dotnet ef migrations add "$MIGRATION_NAME" \
91
107
  --verbose
92
108
  ```
93
109
 
94
- ### 5. Verify Creation
110
+ ### 6. Verify Creation
95
111
 
96
112
  ```bash
97
113
  # Check files were created
@@ -87,6 +87,66 @@ echo " $MIGRATION_FILE"
87
87
  echo " $DESIGNER_FILE"
88
88
  ```
89
89
 
90
+ ### 5. Inject SQL Objects (Functions, Views, SP)
91
+
92
+ EF Core does NOT generate DDL for TVF, views, and stored procedures.
93
+ SQL source scripts are in `Persistence/SqlObjects/` (Embedded Resources).
94
+ After a rebase-snapshot, they must be re-injected into the consolidated migration.
95
+
96
+ ```bash
97
+ # Check if SqlObjects folder exists with .sql files
98
+ SQL_OBJECTS_DIR="$INFRA_PROJECT_DIR/Persistence/SqlObjects"
99
+ SQL_FILES=$(find "$SQL_OBJECTS_DIR" -name "*.sql" 2>/dev/null | wc -l)
100
+
101
+ if [ "$SQL_FILES" -gt 0 ]; then
102
+ echo ""
103
+ echo "Found $SQL_FILES SQL object(s) in SqlObjects/"
104
+ echo "Injecting SqlObjectHelper.ApplyAll(migrationBuilder) into migration..."
105
+
106
+ # Validate migration file path before sed operations
107
+ if [ ! -f "$MIGRATION_FILE" ]; then
108
+ echo "ERROR: Migration file not found: $MIGRATION_FILE"
109
+ exit 1
110
+ fi
111
+ if ! echo "$MIGRATION_FILE" | grep -qE '\.cs$'; then
112
+ echo "ERROR: Invalid migration file path (not .cs): $MIGRATION_FILE"
113
+ exit 1
114
+ fi
115
+
116
+ # Add using directive if not present
117
+ if ! grep -q "using SmartStack.Infrastructure.Persistence.SqlObjects;" "$MIGRATION_FILE"; then
118
+ sed -i '1s/^/using SmartStack.Infrastructure.Persistence.SqlObjects;\n/' "$MIGRATION_FILE"
119
+ fi
120
+
121
+ # Add SqlObjectHelper.ApplyAll at the end of Up() method
122
+ sed -i '/protected override void Up/,/^ }/ {
123
+ /^ }/ i\
124
+ \ // Apply SQL objects (TVF, Views, SP) from embedded resources\
125
+ \ SqlObjectHelper.ApplyAll(migrationBuilder);
126
+ }' "$MIGRATION_FILE"
127
+
128
+ # Verify injection succeeded (fallback to manual step if sed pattern didn't match)
129
+ if ! grep -q "SqlObjectHelper.ApplyAll" "$MIGRATION_FILE"; then
130
+ echo "WARNING: Automatic injection failed (indentation pattern may differ)"
131
+ echo ""
132
+ echo "MANUAL STEP REQUIRED: Add these lines inside the Up() method before the closing brace:"
133
+ echo ' using SmartStack.Infrastructure.Persistence.SqlObjects;'
134
+ echo ' ...'
135
+ echo ' SqlObjectHelper.ApplyAll(migrationBuilder);'
136
+ echo ""
137
+ echo "File: $MIGRATION_FILE"
138
+ else
139
+ echo " SqlObjectHelper.ApplyAll(migrationBuilder) injected"
140
+ fi
141
+ find "$SQL_OBJECTS_DIR" -name "*.sql" -exec basename {} \; | while read f; do
142
+ echo " - $f"
143
+ done
144
+ else
145
+ echo ""
146
+ echo "No SQL objects found in SqlObjects/ - skipping injection"
147
+ fi
148
+ ```
149
+
90
150
  ---
91
151
 
92
152
  ## STATE OUTPUT:
@@ -56,8 +56,10 @@ detect_dbcontext() {
56
56
  return
57
57
  fi
58
58
 
59
- # Priority 2: Client with SmartStack NuGet → BOTH contexts (Core from NuGet + Extensions local)
60
- if find . -name "*.csproj" -exec grep -l "SmartStack\." {} \; | grep -qv "SmartStack\."; then
59
+ # Priority 2: Client project with SmartStack NuGet → BOTH contexts
60
+ # Detect: csproj files that have a PackageReference to SmartStack (not ProjectReference)
61
+ # This identifies client projects created via `ss init` that consume SmartStack as NuGet
62
+ if find . -name "*.csproj" -exec grep -ql "PackageReference.*SmartStack" {} \; 2>/dev/null; then
61
63
  DBCONTEXT="CoreDbContext"
62
64
  DBCONTEXT_TYPE="both"
63
65
  SCHEMA="core"
@@ -197,20 +199,57 @@ determine_base_branch() {
197
199
 
198
200
  ```bash
199
201
  block_production() {
200
- # Check for production indicators
201
- if grep -q '"Production"' "$CONFIG_FILE" 2>/dev/null; then
202
- echo "BLOCKED: Production environment detected"
202
+ # Check for production indicators (case-insensitive)
203
+ if grep -qi '"Production"' "$CONFIG_FILE" 2>/dev/null; then
204
+ echo "BLOCKED: Production environment detected in $CONFIG_FILE"
203
205
  exit 1
204
206
  fi
205
207
 
206
- if [[ "$DATABASE_NAME" == *"prod"* ]] || [[ "$DATABASE_NAME" == *"production"* ]]; then
207
- echo "BLOCKED: Production database detected"
208
+ # Case-insensitive database name check
209
+ DB_LOWER=$(echo "$DATABASE_NAME" | tr '[:upper:]' '[:lower:]')
210
+ if [[ "$DB_LOWER" == *"prod"* ]] || [[ "$DB_LOWER" == *"production"* ]]; then
211
+ echo "BLOCKED: Production database detected ($DATABASE_NAME)"
208
212
  exit 1
209
213
  fi
214
+
215
+ # Environment name check (case-insensitive)
216
+ ENV_LOWER=$(echo "$SELECTED_ENV" | tr '[:upper:]' '[:lower:]')
217
+ if [[ "$ENV_LOWER" == "production" ]] || [[ "$ENV_LOWER" == "prod" ]]; then
218
+ echo "BLOCKED: Production environment selected ($SELECTED_ENV)"
219
+ exit 1
220
+ fi
221
+ }
222
+ ```
223
+
224
+ ### 7. Dual Context Helper
225
+
226
+ ```bash
227
+ # Helper for steps that need to run for both contexts when RUN_BOTH=true
228
+ # Usage: run_for_contexts "command_or_function"
229
+ # Executes with CoreDbContext first, then ExtensionsDbContext
230
+ # Maintains deploy order constraint: Core MUST run first
231
+
232
+ run_for_contexts() {
233
+ if [ "$RUN_BOTH" = "true" ]; then
234
+ echo "=== Running for CoreDbContext (core schema) ==="
235
+ DBCONTEXT="CoreDbContext"
236
+ DBCONTEXT_TYPE="core"
237
+ SCHEMA="core"
238
+ eval "$1"
239
+
240
+ echo ""
241
+ echo "=== Running for ExtensionsDbContext (extensions schema) ==="
242
+ DBCONTEXT="ExtensionsDbContext"
243
+ DBCONTEXT_TYPE="extensions"
244
+ SCHEMA="extensions"
245
+ eval "$1"
246
+ else
247
+ eval "$1"
248
+ fi
210
249
  }
211
250
  ```
212
251
 
213
- ### 7. Display Summary
252
+ ### 8. Display Summary
214
253
 
215
254
  ```
216
255
  EF CORE CONTEXT
@@ -133,9 +133,9 @@ echo " Down methods: $DOWN_METHODS"
133
133
 
134
134
  ### 6. Inject SQL Objects (Functions, Views, SP)
135
135
 
136
- EF Core ne génère PAS de DDL pour les TVF, vues et procédures stockées.
137
- Les scripts SQL source sont dans `Persistence/SqlObjects/` (Embedded Resources).
138
- Après un squash, il faut les réinjecter dans la migration consolidée.
136
+ EF Core does NOT generate DDL for TVF, views, and stored procedures.
137
+ SQL source scripts are in `Persistence/SqlObjects/` (Embedded Resources).
138
+ After a squash, they must be re-injected into the consolidated migration.
139
139
 
140
140
  ```bash
141
141
  # Check if SqlObjects folder exists with .sql files
@@ -147,6 +147,16 @@ if [ "$SQL_FILES" -gt 0 ]; then
147
147
  echo "Found $SQL_FILES SQL object(s) in SqlObjects/"
148
148
  echo "Injecting SqlObjectHelper.ApplyAll(migrationBuilder) into migration..."
149
149
 
150
+ # Validate migration file path before sed operations (prevent path injection)
151
+ if [ ! -f "$MIGRATION_FILE" ]; then
152
+ echo "ERROR: Migration file not found: $MIGRATION_FILE"
153
+ exit 1
154
+ fi
155
+ if ! echo "$MIGRATION_FILE" | grep -qE '\.cs$'; then
156
+ echo "ERROR: Invalid migration file path (not .cs): $MIGRATION_FILE"
157
+ exit 1
158
+ fi
159
+
150
160
  # Add using directive if not present
151
161
  if ! grep -q "using SmartStack.Infrastructure.Persistence.SqlObjects;" "$MIGRATION_FILE"; then
152
162
  sed -i '1s/^/using SmartStack.Infrastructure.Persistence.SqlObjects;\n/' "$MIGRATION_FILE"
@@ -160,9 +170,21 @@ if [ "$SQL_FILES" -gt 0 ]; then
160
170
  \ SqlObjectHelper.ApplyAll(migrationBuilder);
161
171
  }' "$MIGRATION_FILE"
162
172
 
163
- echo " ✅ SqlObjectHelper.ApplyAll(migrationBuilder) injected"
173
+ # Verify injection succeeded (fallback to manual step if sed pattern didn't match)
174
+ if ! grep -q "SqlObjectHelper.ApplyAll" "$MIGRATION_FILE"; then
175
+ echo "WARNING: Automatic injection failed (indentation pattern may differ)"
176
+ echo ""
177
+ echo "MANUAL STEP REQUIRED: Add these lines inside the Up() method before the closing brace:"
178
+ echo ' using SmartStack.Infrastructure.Persistence.SqlObjects;'
179
+ echo ' ...'
180
+ echo ' SqlObjectHelper.ApplyAll(migrationBuilder);'
181
+ echo ""
182
+ echo "File: $MIGRATION_FILE"
183
+ else
184
+ echo " SqlObjectHelper.ApplyAll(migrationBuilder) injected"
185
+ fi
164
186
  find "$SQL_OBJECTS_DIR" -name "*.sql" -exec basename {} \; | while read f; do
165
- echo " 📄 $f"
187
+ echo " - $f"
166
188
  done
167
189
  else
168
190
  echo ""
@@ -65,13 +65,15 @@ Execute GitFlow workflows with automatic versioning, worktree management, and EF
65
65
  | Short | Long | Description |
66
66
  |-------|------|-------------|
67
67
  | `-A` | `--no-auto` | Disable auto mode |
68
+ | `--ws` | `--workspace` | Batch init: initialize all repos in a workspace |
68
69
  </flags>
69
70
 
70
71
  <actions>
71
72
  **Primary actions:**
72
73
  | Action | Description | Step |
73
74
  |--------|-------------|------|
74
- | `init` | Initialize GitFlow config | step-init |
75
+ | `init` | Initialize GitFlow config (orchestrates detect→clone→validate) | step-init |
76
+ | `init --workspace` | Batch initialize all repos in a workspace | step-init |
75
77
  | `start` | Create new branch + worktree | step-start |
76
78
  | `commit` | Commit with EF Core validation | step-commit |
77
79
  | `sync` | Sync + rebase with remote | step-sync |
@@ -178,25 +180,30 @@ start ──► commit* ──► sync ──► pr ──► merge ──► fi
178
180
  **ROUTING LOGIC:**
179
181
 
180
182
  1. Parse flags and action from input
181
- 2. Route to appropriate step or phase:
182
-
183
- | Input Pattern | Route To |
184
- |---------------|----------|
185
- | `init` | `steps/step-init.md` |
186
- | `start {type} {name}` | `steps/step-start.md` |
187
- | `-f {name}` | `steps/step-start.md` (type=feature) |
188
- | `-r {name}` | `steps/step-start.md` (type=release) |
189
- | `-h {name}` | `steps/step-start.md` (type=hotfix) |
190
- | `commit [msg]` | `steps/step-commit.md` |
191
- | `sync` | `steps/step-sync.md` |
192
- | `plan` | `steps/step-plan.md` |
193
- | `pr` | `steps/step-pr.md` |
194
- | `merge` | `steps/step-merge.md` |
195
- | `finish` | `steps/step-finish.md` |
196
- | `status` or `-s` | `phases/status.md` |
197
- | `abort` | `phases/abort.md` |
198
- | `cleanup` | `phases/cleanup.md` |
199
- | (no action, on feature/*) | `steps/step-commit.md` |
183
+ 2. Route to appropriate step or Task agent:
184
+
185
+ | Input Pattern | Step File | Task Agent (`subagent_type`) |
186
+ |---------------|-----------|----------------------------|
187
+ | `init` | `steps/step-init.md` | `gitflow-init` |
188
+ | `start`, `-f`, `-r`, `-h` | `steps/step-start.md` | `gitflow-start` |
189
+ | `commit [msg]` | `steps/step-commit.md` | `gitflow-commit` |
190
+ | `sync` | `steps/step-sync.md` | |
191
+ | `plan` | `steps/step-plan.md` | `gitflow-plan` |
192
+ | `pr` | `steps/step-pr.md` | `gitflow-pr` |
193
+ | `merge` | `steps/step-merge.md` | `gitflow-merge` |
194
+ | `finish` | `steps/step-finish.md` | `gitflow-finish` |
195
+ | `status`, `-s` | `phases/status.md` | `gitflow-status` |
196
+ | `abort` | `phases/abort.md` | `gitflow-abort` |
197
+ | `cleanup` | `phases/cleanup.md` | `gitflow-cleanup` |
198
+ | (no action, on feature/*) | `steps/step-commit.md` | `gitflow-commit` |
199
+
200
+ **Execution mode:**
201
+
202
+ | Mode | How to route |
203
+ |------|-------------|
204
+ | **Single step** (no `-a`) | Read the step file and execute inline |
205
+ | **Auto mode** (`-a`) | Use `Task` tool with the matching `subagent_type` for each step sequentially |
206
+ | **Standalone phases** | Always delegate to Task agent (fast, isolated) |
200
207
 
201
208
  </entry_point>
202
209
 
@@ -253,12 +260,67 @@ start ──► commit* ──► sync ──► pr ──► merge ──► fi
253
260
  | release | as specified | 1.2.0 → 2.0.0 |
254
261
  </versioning>
255
262
 
263
+ <task_agents>
264
+
265
+ **Task agent delegation (Opus 4.6):**
266
+
267
+ Each action has a matching Task agent that can execute independently. Use `Task` tool with the `subagent_type` parameter to delegate:
268
+
269
+ | Agent | Model | Tools | Use for |
270
+ |-------|-------|-------|---------|
271
+ | `gitflow-commit` | haiku | Bash, Read, Glob, Grep | Fast commit + EF Core validation |
272
+ | `gitflow-pr` | haiku | Bash, Glob | Fast PR creation |
273
+ | `gitflow-status` | haiku | Bash, Read, Glob | Fast status check |
274
+ | `gitflow-review` | haiku | Bash, Glob, Read | Fast PR review |
275
+ | `gitflow-start` | sonnet | Bash, Read, Glob, Write | Branch + worktree creation |
276
+ | `gitflow-merge` | sonnet | Bash, Read, Glob, Grep, Edit | Safe merge with validation |
277
+ | `gitflow-finish` | sonnet | Bash, Read, Glob, Write | Tag + cleanup + merge-back |
278
+ | `gitflow-plan` | sonnet | Bash, Read, Glob, Grep, Write | Integration planning |
279
+ | `gitflow-exec` | sonnet | Bash, Read, Glob, Grep, Edit, Write | Plan execution |
280
+ | `gitflow-init` | sonnet | Bash, Read, Write, Glob, AskUserQuestion | Project setup (orchestrator) |
281
+ | `gitflow-init-detect` | haiku | Bash, Read | Environment detection (sub-agent) |
282
+ | `gitflow-init-clone` | sonnet | Bash, Read, Write | Bare clone + worktrees (sub-agent) |
283
+ | `gitflow-init-validate` | haiku | Bash, Read, Glob | Post-init verification + repair (sub-agent) |
284
+ | `gitflow-cleanup` | sonnet | Bash, Read, Glob, Write | Orphan worktree audit |
285
+ | `gitflow-abort` | sonnet | Bash, Read, Glob, Write | Rollback/recovery |
286
+
287
+ **Init team delegation (orchestrated by `gitflow-init`):**
288
+
289
+ | Step | Sub-agent | Model | Purpose |
290
+ |------|-----------|-------|---------|
291
+ | 1 | `gitflow-init-detect` | haiku | Platform, workspace, git state detection |
292
+ | 2 | (orchestrator) | sonnet | AskUserQuestion for URL, path, name |
293
+ | 3 | `gitflow-init-clone` | sonnet | Bare clone + worktree creation (zero `cd`, absolute paths) |
294
+ | 4 | (orchestrator) | sonnet | Write config.json v2.1.0 |
295
+ | 5 | `gitflow-init-validate` | haiku | Verify structure + auto-repair |
296
+
297
+ **Parallel execution opportunities:**
298
+
299
+ | Scenario | Parallel agents |
300
+ |----------|----------------|
301
+ | Status check | `gitflow-status` in background while user continues |
302
+ | Pre-PR validation | Build check + migration check in parallel Bash calls |
303
+ | Auto release | Sequential: start → commit → pr → (wait) → finish |
304
+ | Workspace init | Sequential per repo, but detection is parallel |
305
+
306
+ **Agent prompt template:**
307
+ ```
308
+ Execute {action} for GitFlow.
309
+ Working directory: {worktree_path}
310
+ Branch: {branch_name} ({branch_type})
311
+ Target: {base_branch}
312
+ Provider: {git_provider}
313
+ Version: {version_current}
314
+ Auto mode: {auto_mode}
315
+ ```
316
+
317
+ </task_agents>
318
+
256
319
  <execution_rules>
257
320
 
258
- - **Load one step at a time** - Only load the current step file
259
- - **ULTRA THINK** before each action
260
- - **Persist state variables** across all steps
261
- - **Follow next_step directive** at end of each step
321
+ - **Single step mode**: Read the step file and execute inline
322
+ - **Auto mode (`-a`)**: Delegate each step to its Task agent sequentially
323
+ - **Standalone phases**: Always delegate to Task agent (fast, isolated)
262
324
  - **NEVER skip EF Core validation** - migrations are critical
263
325
  - **Safety > Correctness > Speed**
264
326
 
@@ -267,14 +329,14 @@ start ──► commit* ──► sync ──► pr ──► merge ──► fi
267
329
  | Mode | Behavior |
268
330
  |------|----------|
269
331
  | **Without `-a`** | Execute ONLY the requested step, then **STOP and wait for user** |
270
- | **With `-a`** | Execute ALL steps automatically (start commit pr → merge → finish) |
332
+ | **With `-a`** | Execute ALL steps automatically via Task agent delegation |
271
333
 
272
334
  **Examples:**
273
335
  ```bash
274
- /gitflow -r 1.20.0 # Creates branch + bump version → STOPS (user runs /gitflow pr next)
275
- /gitflow -r -a 1.20.0 # Full automatic: branchbumpPR → merge → tag → cleanup
276
- /gitflow -f my-feature # Creates branch → STOPS (user codes, then runs /gitflow commit)
277
- /gitflow -f -a feature # Full automatic: branch → commit PRmerge → finish
336
+ /gitflow -r 1.20.0 # Reads step-start.md, executes inline → STOPS
337
+ /gitflow -r -a 1.20.0 # Delegates to gitflow-startgitflow-prgitflow-finish
338
+ /gitflow -f my-feature # Reads step-start.md, executes inline STOPS
339
+ /gitflow commit # Reads step-commit.md, executes inlineSTOPS
278
340
  ```
279
341
 
280
342
  **NEVER chain steps automatically without `-a` flag. The user decides the pace.**