@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.
- package/.documentation/agents.html +1 -371
- package/.documentation/business-analyse.html +81 -17
- package/.documentation/cli-commands.html +1 -1
- package/.documentation/commands.html +1 -1
- package/.documentation/efcore.html +1 -1
- package/.documentation/gitflow.html +1 -1
- package/.documentation/hooks.html +27 -66
- package/.documentation/index.html +166 -166
- package/.documentation/init.html +6 -7
- package/.documentation/installation.html +1 -1
- package/.documentation/ralph-loop.html +1 -9
- package/.documentation/test-web.html +15 -39
- package/dist/index.js +23 -16
- package/dist/index.js.map +1 -1
- package/dist/mcp-entry.mjs +1302 -223
- package/dist/mcp-entry.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/agents/efcore/db-deploy.md +1 -1
- package/templates/agents/efcore/migration.md +26 -10
- package/templates/agents/efcore/rebase-snapshot.md +24 -7
- package/templates/agents/efcore/squash.md +73 -57
- package/templates/agents/gitflow/commit.md +138 -18
- package/templates/agents/gitflow/exec.md +1 -1
- package/templates/agents/gitflow/finish.md +79 -62
- package/templates/agents/gitflow/init-clone.md +186 -0
- package/templates/agents/gitflow/init-detect.md +137 -0
- package/templates/agents/gitflow/init-validate.md +210 -0
- package/templates/agents/gitflow/init.md +231 -74
- package/templates/agents/gitflow/merge.md +115 -33
- package/templates/agents/gitflow/pr.md +151 -46
- package/templates/agents/gitflow/start.md +76 -33
- package/templates/agents/gitflow/status.md +41 -71
- package/templates/hooks/appsettings-guard.sh +76 -0
- package/templates/hooks/ef-migration-check.md +1 -1
- package/templates/hooks/hooks.json +9 -0
- package/templates/project/appsettings.json.template +8 -2
- package/templates/project/test-frontend/msw/handlers.ts +58 -0
- package/templates/project/test-frontend/msw/server.ts +25 -0
- package/templates/project/test-frontend/setup.ts +16 -0
- package/templates/project/test-frontend/test-utils.tsx +59 -0
- package/templates/project/test-frontend/vitest.config.ts +31 -0
- package/templates/skills/_resources/config-safety.md +61 -0
- package/templates/skills/_resources/formatting-guide.md +2 -2
- package/templates/skills/application/SKILL.md +12 -3
- package/templates/skills/application/steps/step-04-backend.md +21 -0
- package/templates/skills/application/steps/step-07-tests.md +259 -120
- package/templates/skills/business-analyse/SKILL.md +57 -28
- package/templates/skills/business-analyse/_shared.md +70 -39
- package/templates/skills/business-analyse/html/ba-interactive.html +2596 -0
- package/templates/skills/business-analyse/questionnaire/00-application.md +123 -131
- package/templates/skills/business-analyse/questionnaire/01-context.md +173 -24
- package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +170 -50
- package/templates/skills/business-analyse/questionnaire/03-scope.md +154 -48
- package/templates/skills/business-analyse/questionnaire/10-documentation.md +1 -1
- package/templates/skills/business-analyse/questionnaire/14-risk-assumptions.md +135 -0
- package/templates/skills/business-analyse/questionnaire/15-success-metrics.md +136 -0
- package/templates/skills/business-analyse/questionnaire.md +55 -46
- package/templates/skills/business-analyse/steps/step-00-init.md +24 -2
- package/templates/skills/business-analyse/steps/step-01-cadrage.md +31 -20
- package/templates/skills/business-analyse/steps/step-03-specify.md +58 -0
- package/templates/skills/business-analyse/steps/step-05-handoff.md +301 -1
- package/templates/skills/business-analyse/steps/step-06-extract.md +518 -0
- package/templates/skills/check-version/SKILL.md +1 -1
- package/templates/skills/efcore/steps/db/step-deploy.md +22 -3
- package/templates/skills/efcore/steps/db/step-reset.md +27 -4
- package/templates/skills/efcore/steps/db/step-seed.md +46 -2
- package/templates/skills/efcore/steps/db/step-status.md +14 -0
- package/templates/skills/efcore/steps/migration/step-01-check.md +31 -5
- package/templates/skills/efcore/steps/migration/step-02-create.md +20 -4
- package/templates/skills/efcore/steps/rebase-snapshot/step-03-create.md +60 -0
- package/templates/skills/efcore/steps/shared/step-00-init.md +47 -8
- package/templates/skills/efcore/steps/squash/step-03-create.md +27 -5
- package/templates/skills/gitflow/SKILL.md +91 -29
- package/templates/skills/gitflow/_shared.md +144 -2
- package/templates/skills/gitflow/phases/status.md +11 -1
- package/templates/skills/gitflow/steps/step-commit.md +1 -1
- package/templates/skills/gitflow/steps/step-init.md +202 -39
- package/templates/skills/gitflow/steps/step-pr.md +17 -5
- package/templates/skills/gitflow/templates/config.json +10 -1
- package/templates/skills/ralph-loop/SKILL.md +22 -15
- package/templates/skills/ralph-loop/steps/step-01-task.md +89 -4
- package/templates/skills/ralph-loop/steps/step-02-execute.md +408 -23
- package/templates/skills/ralph-loop/steps/step-03-commit.md +84 -2
- package/templates/skills/ralph-loop/steps/step-04-check.md +235 -6
- package/templates/skills/ralph-loop/steps/step-05-report.md +115 -0
- package/templates/skills/validate-feature/SKILL.md +83 -0
- package/templates/skills/validate-feature/steps/step-01-compile.md +38 -0
- package/templates/skills/validate-feature/steps/step-02-unit-tests.md +45 -0
- package/templates/skills/validate-feature/steps/step-03-integration-tests.md +53 -0
- package/templates/skills/validate-feature/steps/step-04-api-smoke.md +157 -0
package/package.json
CHANGED
|
@@ -18,21 +18,21 @@ Orchestrates migration creation with the "1 migration per feature" rule.
|
|
|
18
18
|
|
|
19
19
|
**Progressive Steps:** Load `steps/migration/` for detailed instructions.
|
|
20
20
|
|
|
21
|
-
> **IMPORTANT:**
|
|
21
|
+
> **IMPORTANT:** This agent **ORCHESTRATES** only. Naming is **DELEGATED TO MCP**.
|
|
22
22
|
|
|
23
23
|
> **CLAUDE INSTRUCTION:** The `AskUserQuestion({...})` blocks are instructions to use the `AskUserQuestion` tool **interactively**. You MUST execute the tool with these parameters to get the user's response BEFORE continuing.
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Principle: MCP Delegation
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
29
29
|
│ Agent (CLI) │─────▶│ MCP │─────▶│ dotnet ef │
|
|
30
|
-
│
|
|
30
|
+
│ Orchestrates │ │ Generates name │ │ Creates migr. │
|
|
31
31
|
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
**
|
|
35
|
-
**
|
|
34
|
+
**FORBIDDEN:** Computing migration name in this agent.
|
|
35
|
+
**MANDATORY:** Call `mcp__smartstack__suggest_migration` to get the name.
|
|
36
36
|
|
|
37
37
|
## Dual DbContext Architecture
|
|
38
38
|
|
|
@@ -58,9 +58,9 @@ SmartStack uses two separate DbContexts with separate migration histories:
|
|
|
58
58
|
6. **Create** migration with `dotnet ef migrations add <MCP_NAME> --context {DbContext}`
|
|
59
59
|
7. **Validate** generated content
|
|
60
60
|
|
|
61
|
-
## Naming
|
|
61
|
+
## Naming: MCP Delegation
|
|
62
62
|
|
|
63
|
-
**
|
|
63
|
+
**ALWAYS call MCP for naming:**
|
|
64
64
|
|
|
65
65
|
```
|
|
66
66
|
mcp__smartstack__suggest_migration({
|
|
@@ -69,9 +69,9 @@ mcp__smartstack__suggest_migration({
|
|
|
69
69
|
})
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
MCP returns the fully compliant name: `{context}_v{version}_{sequence}_{Description}`
|
|
73
73
|
|
|
74
|
-
**
|
|
74
|
+
**Examples of MCP-generated names:**
|
|
75
75
|
- `core_v1.8.0_001_CreateAuthUsers`
|
|
76
76
|
- `ext_v1.0.0_001_CreateOrders`
|
|
77
77
|
|
|
@@ -94,7 +94,7 @@ dotnet ef migrations add $MCP_NAME --context ExtensionsDbContext -o Persistence/
|
|
|
94
94
|
rm Persistence/Migrations/*${OLD_NAME}*.cs
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
-
> **Note:** `$MCP_NAME`
|
|
97
|
+
> **Note:** `$MCP_NAME` is obtained via MCP call, never computed locally.
|
|
98
98
|
|
|
99
99
|
## Context Detection
|
|
100
100
|
|
|
@@ -146,6 +146,22 @@ After rebase on develop:
|
|
|
146
146
|
2. Delete local migration
|
|
147
147
|
3. Recreate with this command
|
|
148
148
|
|
|
149
|
+
## Error Recovery
|
|
150
|
+
|
|
151
|
+
| Failure | Recovery Action |
|
|
152
|
+
|---------|----------------|
|
|
153
|
+
| MCP unavailable | Check `.claude/mcp-status.json`, run `/mcp healthcheck` |
|
|
154
|
+
| `dotnet ef` fails | Check build errors: `dotnet build`, fix compilation issues first |
|
|
155
|
+
| Migration file empty | Delete and recreate: `dotnet ef migrations remove --context $DBCONTEXT` |
|
|
156
|
+
| Snapshot corrupted | Use `/efcore rebase-snapshot` to reset from parent branch |
|
|
157
|
+
| Wrong context used | Delete migration files manually, re-run with correct context |
|
|
158
|
+
|
|
159
|
+
**Automatic recovery:** If migration creation fails mid-process, the agent should:
|
|
160
|
+
1. Check if partial files were created
|
|
161
|
+
2. Clean up incomplete migration files (`rm -f $MIGRATIONS_DIR/*$MIGRATION_NAME*`)
|
|
162
|
+
3. Report the error with dotnet output
|
|
163
|
+
4. Suggest corrective action
|
|
164
|
+
|
|
149
165
|
## Important Notes
|
|
150
166
|
|
|
151
167
|
- **Core migrations** go to `CoreDbContextModelSnapshot.cs`
|
|
@@ -30,7 +30,7 @@ Rebases ModelSnapshot on develop to resolve conflicts.
|
|
|
30
30
|
## Key Commands
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
#
|
|
33
|
+
# Detect project and DbContext
|
|
34
34
|
detect_efcore_project # → $DBCONTEXT, $DBCONTEXT_TYPE, $SCHEMA
|
|
35
35
|
determine_base_branch # → $BASE_BRANCH, $BRANCH_TYPE
|
|
36
36
|
|
|
@@ -39,11 +39,11 @@ BACKUP_DIR=".claude/gitflow/backup/migrations/rebase_$(date +%Y%m%d_%H%M%S)"
|
|
|
39
39
|
mkdir -p "$BACKUP_DIR"
|
|
40
40
|
cp Migrations/*.cs "$BACKUP_DIR/"
|
|
41
41
|
|
|
42
|
-
# Reset snapshot to parent branch (develop
|
|
42
|
+
# Reset snapshot to parent branch (develop or main depending on context)
|
|
43
43
|
git fetch origin "$BASE_BRANCH"
|
|
44
44
|
git checkout "origin/$BASE_BRANCH" -- Migrations/*ModelSnapshot.cs
|
|
45
45
|
|
|
46
|
-
#
|
|
46
|
+
# Retrieve parent branch migrations
|
|
47
47
|
BASE_MIGS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- Migrations/ | grep "\.cs$" | grep -v "Designer\|Snapshot")
|
|
48
48
|
for base_mig in $BASE_MIGS; do
|
|
49
49
|
base_name=$(basename "${base_mig%.cs}")
|
|
@@ -55,9 +55,9 @@ done
|
|
|
55
55
|
rm -f Migrations/*${BRANCH_TYPE}_*.cs
|
|
56
56
|
rm -f Migrations/*${BRANCH_TYPE}_*.Designer.cs
|
|
57
57
|
|
|
58
|
-
# Regenerate with MCP naming -
|
|
58
|
+
# Regenerate with MCP naming - MANDATORY
|
|
59
59
|
mcp__smartstack__suggest_migration({ description: "...", context: DBCONTEXT_TYPE })
|
|
60
|
-
#
|
|
60
|
+
# Result: core_v1.7.0_001_UserAuthConsolidated
|
|
61
61
|
|
|
62
62
|
dotnet ef migrations add "$MIGRATION_NAME" --context "$DBCONTEXT"
|
|
63
63
|
|
|
@@ -67,7 +67,7 @@ dotnet build
|
|
|
67
67
|
|
|
68
68
|
## Migration Naming (via MCP)
|
|
69
69
|
|
|
70
|
-
**
|
|
70
|
+
**MANDATORY: Use MCP for naming**
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
{context}_v{version}_{sequence}_{Description}
|
|
@@ -77,7 +77,7 @@ core_v1.6.2_001_LoginFixFix
|
|
|
77
77
|
core_v1.7.0_001_ReleaseInitial
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
> **
|
|
80
|
+
> **FORBIDDEN:** Legacy pattern `Feature_1_7_0_UserAuth_Consolidated`
|
|
81
81
|
|
|
82
82
|
## Safety Checks
|
|
83
83
|
|
|
@@ -85,6 +85,23 @@ core_v1.7.0_001_ReleaseInitial
|
|
|
85
85
|
- [ ] Backup created
|
|
86
86
|
- [ ] Build OK after rebase
|
|
87
87
|
- [ ] SQL script can be generated
|
|
88
|
+
- [ ] SQL objects injected (if `Persistence/SqlObjects/*.sql` exists)
|
|
89
|
+
|
|
90
|
+
## Error Recovery
|
|
91
|
+
|
|
92
|
+
| Failure | Recovery Action |
|
|
93
|
+
|---------|----------------|
|
|
94
|
+
| Build fails after rebase | Restore from backup: `cp "$BACKUP_DIR"/*.cs "$MIGRATIONS_DIR/"` |
|
|
95
|
+
| MCP unavailable | Check `.claude/mcp-status.json`, run `/mcp healthcheck` |
|
|
96
|
+
| Snapshot fetch fails | Verify `origin/$BASE_BRANCH` exists: `git fetch origin $BASE_BRANCH` |
|
|
97
|
+
| Migration creation fails | Restore backup, check `dotnet build` output |
|
|
98
|
+
| SQL objects injection fails | Manual step: add `SqlObjectHelper.ApplyAll(migrationBuilder)` in Up() |
|
|
99
|
+
|
|
100
|
+
**Automatic recovery:** On ANY failure after backup:
|
|
101
|
+
1. Restore all files from backup directory
|
|
102
|
+
2. Verify build passes after restore
|
|
103
|
+
3. Report what failed and why
|
|
104
|
+
4. Suggest corrective action before retrying
|
|
88
105
|
|
|
89
106
|
## Priority
|
|
90
107
|
|
|
@@ -15,44 +15,44 @@ steps:
|
|
|
15
15
|
|
|
16
16
|
# EF Core Squash Agent
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Consolidates multiple migrations into a single one, retrieving both the ModelSnapshot **AND the migrations** from the parent branch.
|
|
19
19
|
|
|
20
20
|
**Progressive Steps:** Load `steps/squash/` for detailed instructions.
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Core Principle
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
|
|
25
|
+
GOLDEN RULE: Retrieve SNAPSHOT + MIGRATIONS from PARENT branch
|
|
26
26
|
|
|
27
|
-
feature/* → snapshot + migrations
|
|
28
|
-
develop → snapshot + migrations
|
|
29
|
-
release/* → snapshot + migrations
|
|
30
|
-
hotfix/* → snapshot + migrations
|
|
31
|
-
main →
|
|
27
|
+
feature/* → snapshot + migrations from develop
|
|
28
|
+
develop → snapshot + migrations from main
|
|
29
|
+
release/* → snapshot + migrations from main
|
|
30
|
+
hotfix/* → snapshot + migrations from main
|
|
31
|
+
main → BLOCKED (never squash)
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
WARNING: NEVER retrieve only the snapshot without the migrations!
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Workflow
|
|
37
37
|
|
|
38
|
-
1. **Determine**:
|
|
39
|
-
2. **List**: Migrations
|
|
40
|
-
3. **Confirm**:
|
|
41
|
-
4. **Backup**:
|
|
42
|
-
5. **Fetch**:
|
|
43
|
-
6. **Delete**:
|
|
44
|
-
7. **Create**:
|
|
45
|
-
8. **Inject SQL Objects**:
|
|
38
|
+
1. **Determine**: Identify parent branch (`determine_base_branch`)
|
|
39
|
+
2. **List**: Migrations specific to this branch (not inherited)
|
|
40
|
+
3. **Confirm**: Request user validation
|
|
41
|
+
4. **Backup**: Save all files
|
|
42
|
+
5. **Fetch**: Retrieve **ModelSnapshot AND migrations** from parent branch (CRUCIAL!)
|
|
43
|
+
6. **Delete**: Remove branch-specific migrations ONLY
|
|
44
|
+
7. **Create**: Create consolidated migration (MCP mandatory)
|
|
45
|
+
8. **Inject SQL Objects**: If `Persistence/SqlObjects/` contains `.sql` files, inject `SqlObjectHelper.ApplyAll(migrationBuilder)` in `Up()`
|
|
46
46
|
9. **Validate**: Build + script OK
|
|
47
47
|
|
|
48
|
-
##
|
|
48
|
+
## Key Commands
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
#
|
|
51
|
+
# Determine parent branch and DbContext
|
|
52
52
|
determine_base_branch # → BASE_BRANCH, BRANCH_TYPE
|
|
53
53
|
detect_efcore_project # → $DBCONTEXT, $DBCONTEXT_TYPE, $SCHEMA
|
|
54
54
|
|
|
55
|
-
#
|
|
55
|
+
# Identify branch-specific migrations
|
|
56
56
|
BASE_MIGS=$(git ls-tree -r --name-only "origin/$BASE_BRANCH" -- Migrations/ | grep "\.cs$" | grep -v "Designer\|Snapshot")
|
|
57
57
|
LOCAL_MIGS=$(find Migrations -name "*.cs" | grep -v Designer | grep -v Snapshot)
|
|
58
58
|
|
|
@@ -61,52 +61,52 @@ BACKUP_DIR=".claude/gitflow/backup/migrations/squash_$(date +%Y%m%d_%H%M%S)"
|
|
|
61
61
|
mkdir -p "$BACKUP_DIR" && cp Migrations/*.cs "$BACKUP_DIR/"
|
|
62
62
|
|
|
63
63
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
64
|
-
# CRUCIAL:
|
|
64
|
+
# CRUCIAL: Retrieve SNAPSHOT + MIGRATIONS from parent branch
|
|
65
65
|
# ═══════════════════════════════════════════════════════════════════════════
|
|
66
66
|
git fetch origin "$BASE_BRANCH"
|
|
67
67
|
|
|
68
|
-
# 1.
|
|
68
|
+
# 1. Retrieve ModelSnapshot
|
|
69
69
|
git checkout "origin/$BASE_BRANCH" -- Migrations/*ModelSnapshot.cs
|
|
70
|
-
echo "
|
|
70
|
+
echo "Snapshot retrieved from origin/$BASE_BRANCH"
|
|
71
71
|
|
|
72
|
-
# 2.
|
|
73
|
-
#
|
|
72
|
+
# 2. Retrieve ALL migrations from parent branch
|
|
73
|
+
# MANDATORY: Without this, develop/main migrations will be lost!
|
|
74
74
|
for base_mig in $BASE_MIGS; do
|
|
75
75
|
base_name=$(basename "${base_mig%.cs}")
|
|
76
76
|
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.cs" 2>/dev/null || true
|
|
77
77
|
git checkout "origin/$BASE_BRANCH" -- "Migrations/${base_name}.Designer.cs" 2>/dev/null || true
|
|
78
|
-
echo "
|
|
78
|
+
echo " $base_name retrieved"
|
|
79
79
|
done
|
|
80
|
-
echo "
|
|
80
|
+
echo "$(echo "$BASE_MIGS" | wc -l) migrations retrieved from origin/$BASE_BRANCH"
|
|
81
81
|
|
|
82
|
-
#
|
|
82
|
+
# Delete branch-specific migrations only
|
|
83
83
|
for mig in $BRANCH_ONLY_MIGRATIONS; do
|
|
84
84
|
rm -f "Migrations/${mig}"*
|
|
85
85
|
done
|
|
86
86
|
|
|
87
|
-
#
|
|
88
|
-
# $DBCONTEXT_TYPE = "core"
|
|
87
|
+
# Create consolidated migration - MCP MANDATORY
|
|
88
|
+
# $DBCONTEXT_TYPE = "core" or "extensions" (from detect_efcore_project)
|
|
89
89
|
mcp__smartstack__suggest_migration({ description: "...", context: DBCONTEXT_TYPE })
|
|
90
|
-
#
|
|
90
|
+
# Result: core_v1.9.0_001_Description
|
|
91
91
|
|
|
92
92
|
dotnet ef migrations add "$MIGRATION_NAME_FROM_MCP" --context "$DBCONTEXT"
|
|
93
93
|
|
|
94
|
-
#
|
|
94
|
+
# Validate
|
|
95
95
|
dotnet build && dotnet ef migrations script --idempotent > /dev/null
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
## Safety Checks
|
|
99
99
|
|
|
100
|
-
- [ ]
|
|
101
|
-
- [ ] main/master =
|
|
102
|
-
- [ ] User confirmation
|
|
103
|
-
- [ ] Backup
|
|
104
|
-
- [ ] **
|
|
105
|
-
- [ ] **
|
|
106
|
-
- [ ]
|
|
107
|
-
- [ ] **SQL Objects
|
|
108
|
-
- [ ] Build OK
|
|
109
|
-
- [ ] Script
|
|
100
|
+
- [ ] Parent branch identified
|
|
101
|
+
- [ ] main/master = BLOCKED
|
|
102
|
+
- [ ] User confirmation obtained
|
|
103
|
+
- [ ] Backup created
|
|
104
|
+
- [ ] **Parent snapshot retrieved** (origin/$BASE_BRANCH)
|
|
105
|
+
- [ ] **Parent migrations retrieved** (.cs AND .Designer.cs files)
|
|
106
|
+
- [ ] Branch-specific migrations deleted (not inherited ones!)
|
|
107
|
+
- [ ] **SQL Objects injected** (if `Persistence/SqlObjects/*.sql` exists)
|
|
108
|
+
- [ ] Build OK after squash
|
|
109
|
+
- [ ] Script can be generated
|
|
110
110
|
|
|
111
111
|
## Output Format
|
|
112
112
|
|
|
@@ -114,32 +114,48 @@ dotnet build && dotnet ef migrations script --idempotent > /dev/null
|
|
|
114
114
|
SQUASH - {current_branch}
|
|
115
115
|
Base: origin/{BASE_BRANCH}
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
Retrieved from {BASE_BRANCH}:
|
|
118
|
+
ModelSnapshot
|
|
119
|
+
{N} migrations (.cs + .Designer.cs files)
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
Consolidated:
|
|
122
|
+
Before: {M} migrations (branch-specific)
|
|
123
|
+
After: 1 migration ({MIGRATION_NAME} via MCP)
|
|
124
124
|
|
|
125
125
|
Backup: .claude/gitflow/backup/migrations/squash_{timestamp}/
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
Next: /efcore:db-reset, /efcore:db-deploy
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
##
|
|
130
|
+
## Edge Cases
|
|
131
131
|
|
|
132
132
|
| Situation | Action |
|
|
133
133
|
|-----------|--------|
|
|
134
|
-
| 0 migrations
|
|
135
|
-
|
|
|
136
|
-
| Build fail |
|
|
137
|
-
|
|
|
134
|
+
| 0 branch-specific migrations | "Nothing to squash" - exit |
|
|
135
|
+
| Identical snapshot | Empty migration created - warning |
|
|
136
|
+
| Build fail | Auto-restore from backup |
|
|
137
|
+
| On main/master | BLOCKED - exit code 1 |
|
|
138
|
+
|
|
139
|
+
## Error Recovery
|
|
140
|
+
|
|
141
|
+
| Failure | Recovery Action |
|
|
142
|
+
|---------|----------------|
|
|
143
|
+
| Build fails after squash | Restore from backup: `cp "$BACKUP_DIR"/*.cs "$MIGRATIONS_DIR/"` |
|
|
144
|
+
| MCP unavailable | Check `.claude/mcp-status.json`, run `/mcp healthcheck` |
|
|
145
|
+
| Snapshot fetch fails | Verify `origin/$BASE_BRANCH` exists: `git fetch origin $BASE_BRANCH` |
|
|
146
|
+
| Script generation fails | Restore backup, then investigate migration content |
|
|
147
|
+
| SQL objects injection fails | Manual step: add `SqlObjectHelper.ApplyAll(migrationBuilder)` in Up() |
|
|
148
|
+
|
|
149
|
+
**Automatic recovery:** On ANY failure after backup:
|
|
150
|
+
1. Restore all files from backup directory
|
|
151
|
+
2. Verify build passes after restore
|
|
152
|
+
3. Report what failed and why
|
|
153
|
+
4. Suggest corrective action before retrying
|
|
138
154
|
|
|
139
155
|
## Priority
|
|
140
156
|
|
|
141
157
|
Safety > Correctness > Speed.
|
|
142
158
|
|
|
143
|
-
1. Backup
|
|
144
|
-
2.
|
|
145
|
-
3.
|
|
159
|
+
1. Backup MANDATORY (unless --no-backup)
|
|
160
|
+
2. Parent snapshot MANDATORY (never optional)
|
|
161
|
+
3. Auto-restore on failure
|
|
@@ -6,37 +6,157 @@ model: haiku
|
|
|
6
6
|
tools: Bash, Read, Glob, Grep
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# GitFlow Commit Agent
|
|
9
|
+
# GitFlow Commit Agent
|
|
10
10
|
|
|
11
|
-
Commit
|
|
11
|
+
Commit with EF Core migration validation. Executes directly, displays only the result.
|
|
12
12
|
|
|
13
|
-
> **
|
|
13
|
+
> **OPTIMISED:** haiku model, reduced tools (no Edit/Write). Access to current context.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## EXECUTION SEQUENCE
|
|
16
16
|
|
|
17
|
-
1.
|
|
18
|
-
2. **Valider EF Core**: 3 fichiers requis (Migration + Designer + ModelSnapshot)
|
|
19
|
-
3. **Build**: Verifier compilation
|
|
20
|
-
4. **Message**: Generer si absent (conventional commits)
|
|
21
|
-
5. **Commit**: Executer avec validation
|
|
17
|
+
### 1. Guards
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
```bash
|
|
20
|
+
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
- `{Timestamp}_{Name}.Designer.cs`
|
|
28
|
-
- `{Context}ModelSnapshot.cs`
|
|
22
|
+
# BLOCK: main is protected
|
|
23
|
+
[[ "$CURRENT" == "main" ]] && { echo "BLOCKED - main is protected"; exit 1; }
|
|
29
24
|
|
|
30
|
-
|
|
25
|
+
# WARNING: develop → offer rescue to feature
|
|
26
|
+
[[ "$CURRENT" == "develop" ]] && echo "WARNING: direct commit on develop"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 2. Analyze Changes
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Run in parallel: status + diff + log
|
|
33
|
+
git status --short
|
|
34
|
+
git diff --cached --stat
|
|
35
|
+
git diff --stat
|
|
36
|
+
git ls-files --others --exclude-standard
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If nothing to commit → exit with "Nothing to commit".
|
|
40
|
+
|
|
41
|
+
### 2b. Validate appsettings Integrity
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Check if any appsettings*.json files are staged or modified
|
|
45
|
+
APPSETTINGS_CHANGED=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null | grep -E "appsettings.*\.json$" || true)
|
|
46
|
+
APPSETTINGS_UNSTAGED=$(git diff --name-only 2>/dev/null | grep -E "appsettings.*\.json$" || true)
|
|
47
|
+
ALL_APPSETTINGS=$(echo -e "$APPSETTINGS_CHANGED\n$APPSETTINGS_UNSTAGED" | sort -u | grep -v "^$" || true)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If appsettings files detected, for EACH file compare top-level JSON keys against HEAD:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
for FILE in $ALL_APPSETTINGS; do
|
|
54
|
+
# Skip if file is new (not in HEAD)
|
|
55
|
+
git show HEAD:"$FILE" > /dev/null 2>&1 || continue
|
|
56
|
+
|
|
57
|
+
git show HEAD:"$FILE" | node -e "
|
|
58
|
+
const fs = require('fs');
|
|
59
|
+
const headContent = fs.readFileSync(0, 'utf8');
|
|
60
|
+
const currContent = fs.readFileSync('$FILE', 'utf8');
|
|
61
|
+
const headKeys = Object.keys(JSON.parse(headContent));
|
|
62
|
+
const currKeys = new Set(Object.keys(JSON.parse(currContent)));
|
|
63
|
+
const missing = headKeys.filter(k => !currKeys.has(k));
|
|
64
|
+
if (missing.length > 0) {
|
|
65
|
+
console.log('SECTIONS REMOVED: ' + missing.join(', '));
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
console.log('OK - all sections preserved');
|
|
69
|
+
"
|
|
70
|
+
done
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**BLOCK if any section was removed.** Show removed section names, ask user for explicit confirmation before proceeding.
|
|
74
|
+
|
|
75
|
+
#### 2b-ii. Detect Hardcoded Secrets
|
|
76
|
+
|
|
77
|
+
For each appsettings file in `$ALL_APPSETTINGS`, scan for hardcoded secret values:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
for FILE in $ALL_APPSETTINGS; do
|
|
81
|
+
node -e "
|
|
82
|
+
const fs = require('fs');
|
|
83
|
+
const content = fs.readFileSync('$FILE', 'utf8');
|
|
84
|
+
const secrets = [];
|
|
85
|
+
// Connection strings with password
|
|
86
|
+
const connStr = content.match(/Password\s*=\s*[^;\"]+/gi) || [];
|
|
87
|
+
connStr.forEach(m => { if (!/CONFIGURE_HERE|TODO|PLACEHOLDER|\{/i.test(m)) secrets.push(m.trim()); });
|
|
88
|
+
// API keys patterns (sk-, key-, long hex/base64)
|
|
89
|
+
const apiKeys = content.match(/\"[^\"]+\":\s*\"(sk-[a-zA-Z0-9]{20,}|[a-f0-9]{32,}|[A-Za-z0-9+\/=]{40,})\"/g) || [];
|
|
90
|
+
apiKeys.forEach(m => secrets.push(m.trim()));
|
|
91
|
+
// GUID-like secrets in sensitive sections (ClientSecret, SecretKey, ApiKey)
|
|
92
|
+
const sensitiveKeys = content.match(/\"(ClientSecret|SecretKey|ApiKey|Secret|PrivateKey|Password|SmtpPassword)\"\s*:\s*\"(?!<CONFIGURE_HERE>)[^\"]{8,}\"/gi) || [];
|
|
93
|
+
sensitiveKeys.forEach(m => secrets.push(m.trim()));
|
|
94
|
+
if (secrets.length > 0) {
|
|
95
|
+
console.log('SECRETS DETECTED in $FILE:');
|
|
96
|
+
secrets.forEach(s => console.log(' - ' + s));
|
|
97
|
+
console.log('Replace with <CONFIGURE_HERE> placeholder before committing.');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
" 2>/dev/null
|
|
101
|
+
done
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**WARNING if secrets detected.** Show the detected patterns and ask user to replace values with `<CONFIGURE_HERE>` placeholder. The key/section MUST remain — only the VALUE should be replaced.
|
|
31
105
|
|
|
106
|
+
### 3. Detect EF Core Migrations
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Find migration files in staged + modified + untracked
|
|
110
|
+
MIGRATIONS=$(git diff --cached --name-only && git diff --name-only && git ls-files --others --exclude-standard | grep -E "Migrations/.*\.cs$")
|
|
32
111
|
```
|
|
112
|
+
|
|
113
|
+
If migrations detected, validate **3 required files**:
|
|
114
|
+
- `{Name}.cs` (main migration)
|
|
115
|
+
- `{Name}.Designer.cs`
|
|
116
|
+
- `{DbContext}ModelSnapshot.cs`
|
|
117
|
+
|
|
118
|
+
**BLOCK if any file is missing.** Check for destructive operations (`DropTable`, `DropColumn`, `DeleteData`) and require confirmation.
|
|
119
|
+
|
|
120
|
+
### 4. Stage + Commit
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Stage specific files (prefer explicit over git add -A)
|
|
124
|
+
git add {files}
|
|
125
|
+
|
|
126
|
+
# Generate conventional commit message
|
|
127
|
+
# {type}({scope}): {description}
|
|
128
|
+
# Types: feat, fix, db(migrations), chore
|
|
129
|
+
|
|
130
|
+
git commit -m "$(cat <<'EOF'
|
|
33
131
|
{type}({scope}): {description}
|
|
34
132
|
|
|
35
|
-
|
|
133
|
+
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
|
134
|
+
EOF
|
|
135
|
+
)"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 5. Push (ALWAYS ASK USER)
|
|
139
|
+
|
|
140
|
+
**MANDATORY:** Ask user before pushing. Never push automatically.
|
|
141
|
+
|
|
142
|
+
After push, verify with force-fetch:
|
|
143
|
+
```bash
|
|
144
|
+
git fetch origin $CURRENT:refs/remotes/origin/$CURRENT --force --quiet
|
|
36
145
|
```
|
|
37
146
|
|
|
38
|
-
|
|
147
|
+
### 6. Summary
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
COMMIT CREATED
|
|
151
|
+
Branch: {branch}
|
|
152
|
+
Commit: {hash}
|
|
153
|
+
Message: {first line}
|
|
154
|
+
Files: {N} changed
|
|
155
|
+
EF Core: {Valid | Destructive confirmed | N/A}
|
|
156
|
+
Pushed: {yes | no}
|
|
157
|
+
NEXT: /gitflow pr
|
|
158
|
+
```
|
|
39
159
|
|
|
40
160
|
## Priority
|
|
41
161
|
|
|
42
|
-
Correctness > Speed.
|
|
162
|
+
Correctness > Speed. Never commit incomplete migration.
|