@atlashub/smartstack-cli 1.35.0 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/skills/_shared.md +7 -7
- package/templates/skills/application/steps/step-04-backend.md +17 -17
- package/templates/skills/application/steps/step-05-frontend.md +4 -1
- package/templates/skills/application/templates-backend.md +8 -8
- package/templates/skills/application/templates-frontend.md +8 -8
- package/templates/skills/gitflow/_shared.md +188 -53
- package/templates/skills/gitflow/phases/abort.md +28 -16
- package/templates/skills/gitflow/phases/cleanup.md +13 -9
- package/templates/skills/gitflow/phases/status.md +16 -17
- package/templates/skills/gitflow/steps/step-commit.md +11 -5
- package/templates/skills/gitflow/steps/step-finish.md +43 -33
- package/templates/skills/gitflow/steps/step-init.md +7 -2
- package/templates/skills/gitflow/steps/step-merge.md +24 -10
- package/templates/skills/gitflow/steps/step-pr.md +42 -28
- package/templates/skills/gitflow/steps/step-start.md +19 -13
- package/templates/skills/gitflow/templates/config.json +7 -4
- package/templates/skills/ralph-loop/SKILL.md +57 -11
- package/templates/skills/ralph-loop/steps/step-00-init.md +170 -30
- package/templates/skills/ralph-loop/steps/step-01-task.md +243 -40
- package/templates/skills/ralph-loop/steps/step-02-execute.md +142 -24
- package/templates/skills/ralph-loop/steps/step-03-commit.md +140 -36
- package/templates/skills/ralph-loop/steps/step-04-check.md +128 -44
- package/templates/skills/ralph-loop/steps/step-05-report.md +175 -88
package/package.json
CHANGED
|
@@ -15,13 +15,13 @@ Domain → Application → Infrastructure → API → Web
|
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Layers
|
|
18
|
-
| Layer | Responsibility | Namespace |
|
|
19
|
-
|
|
20
|
-
| Domain | Entities, ValueObjects | `SmartStack.Domain.{Context}` |
|
|
21
|
-
| Application |
|
|
22
|
-
| Infrastructure |
|
|
23
|
-
| API | Controllers, Middleware | `SmartStack.Api.Controllers.{
|
|
24
|
-
| Web | React components, pages | `
|
|
18
|
+
| Layer | Responsibility | Namespace | Folder Hierarchy |
|
|
19
|
+
|-------|-----------------|-----------|------------------|
|
|
20
|
+
| Domain | Entities, ValueObjects | `SmartStack.Domain.{Context}.{App}.{Module}` | `Domain/{Context}/{App}/{Module}/` |
|
|
21
|
+
| Application | Interfaces (Common), DTOs | `SmartStack.Application.Common.Interfaces` / `.{Context}.{App}.{Module}.DTOs` | `Application/Common/Interfaces/` + `Application/{Context}/{App}/{Module}/DTOs/` |
|
|
22
|
+
| Infrastructure | Service Impl, EF Core | `SmartStack.Infrastructure.Services.{Module}` | `Infrastructure/Services/{Module}/` + `Persistence/Configurations/{Module}/` |
|
|
23
|
+
| API | Controllers, Middleware | `SmartStack.Api.Controllers.{Context}` | `Api/Controllers/{Context}/` |
|
|
24
|
+
| Web | React components, pages | N/A | `pages/{context}/{app}/{module}/` + `components/{context}/{module}/` |
|
|
25
25
|
|
|
26
26
|
## Permissions (2 mandatory files)
|
|
27
27
|
|
|
@@ -80,15 +80,15 @@ Args:
|
|
|
80
80
|
|
|
81
81
|
### 4. Parse MCP Response
|
|
82
82
|
|
|
83
|
-
The tool generates:
|
|
84
|
-
- `Domain/{EntityName}.cs` - Entity with BaseEntity
|
|
85
|
-
- `Infrastructure/Persistence/Configurations/{EntityName}Configuration.cs` - EF Config
|
|
86
|
-
- `Application/
|
|
87
|
-
- `
|
|
88
|
-
- `Api/Controllers/{EntityName}Controller.cs` - REST Controller
|
|
89
|
-
- `Application/DTOs/{EntityName}
|
|
90
|
-
- `Application/DTOs/Create{EntityName}Dto.cs` - Create request
|
|
91
|
-
- `Application/DTOs/Update{EntityName}Dto.cs` - Update request
|
|
83
|
+
The tool generates (paths organized by navRoute hierarchy `{context}.{application}.{module}`):
|
|
84
|
+
- `Domain/{Context}/{Application}/{Module}/{EntityName}.cs` - Entity with BaseEntity
|
|
85
|
+
- `Infrastructure/Persistence/Configurations/{Module}/{EntityName}Configuration.cs` - EF Config
|
|
86
|
+
- `Application/Common/Interfaces/I{EntityName}Service.cs` - Service Interface
|
|
87
|
+
- `Infrastructure/Services/{Module}/{EntityName}Service.cs` - Service Implementation
|
|
88
|
+
- `Api/Controllers/{Context}/{EntityName}Controller.cs` - REST Controller
|
|
89
|
+
- `Application/{Context}/{Application}/{Module}/DTOs/{EntityName}ResponseDto.cs` - Response DTO
|
|
90
|
+
- `Application/{Context}/{Application}/{Module}/DTOs/Create{EntityName}Dto.cs` - Create request
|
|
91
|
+
- `Application/{Context}/{Application}/{Module}/DTOs/Update{EntityName}Dto.cs` - Update request
|
|
92
92
|
|
|
93
93
|
### 5. Present Output to User
|
|
94
94
|
|
|
@@ -96,20 +96,20 @@ The tool generates:
|
|
|
96
96
|
## Backend Code Generated
|
|
97
97
|
|
|
98
98
|
### Domain Layer
|
|
99
|
-
- `Domain/{EntityName}.cs`
|
|
99
|
+
- `Domain/{Context}/{Application}/{Module}/{EntityName}.cs`
|
|
100
100
|
|
|
101
101
|
### Infrastructure Layer
|
|
102
|
-
- `Persistence/Configurations/{EntityName}Configuration.cs`
|
|
102
|
+
- `Persistence/Configurations/{Module}/{EntityName}Configuration.cs`
|
|
103
|
+
- `Services/{Module}/{EntityName}Service.cs`
|
|
103
104
|
|
|
104
105
|
### Application Layer
|
|
105
|
-
- `
|
|
106
|
-
- `
|
|
107
|
-
- `DTOs/{EntityName}Dto.cs`
|
|
108
|
-
- `DTOs/
|
|
109
|
-
- `DTOs/Update{EntityName}Dto.cs`
|
|
106
|
+
- `Common/Interfaces/I{EntityName}Service.cs`
|
|
107
|
+
- `{Context}/{Application}/{Module}/DTOs/{EntityName}ResponseDto.cs`
|
|
108
|
+
- `{Context}/{Application}/{Module}/DTOs/Create{EntityName}Dto.cs`
|
|
109
|
+
- `{Context}/{Application}/{Module}/DTOs/Update{EntityName}Dto.cs`
|
|
110
110
|
|
|
111
111
|
### API Layer
|
|
112
|
-
- `Controllers/{EntityName}Controller.cs`
|
|
112
|
+
- `Controllers/{Context}/{EntityName}Controller.cs`
|
|
113
113
|
- NavRoute: `{full_path}`
|
|
114
114
|
- Endpoints:
|
|
115
115
|
- GET /api/{code} - List all
|
|
@@ -129,9 +129,12 @@ Repeat for en, it, de with appropriate translations.
|
|
|
129
129
|
```markdown
|
|
130
130
|
## Frontend Code Generated
|
|
131
131
|
|
|
132
|
-
###
|
|
132
|
+
### Pages
|
|
133
133
|
- `pages/{context}/{application}/{module}/{EntityName}Page.tsx`
|
|
134
134
|
- `pages/{context}/{application}/{module}/{EntityName}ListView.tsx`
|
|
135
|
+
|
|
136
|
+
### Components
|
|
137
|
+
- `components/{context}/{module}/{EntityName}.tsx`
|
|
135
138
|
- `hooks/use{EntityName}.ts`
|
|
136
139
|
|
|
137
140
|
### API Client
|
|
@@ -49,7 +49,7 @@ public static class Erp
|
|
|
49
49
|
```csharp
|
|
50
50
|
// src/SmartStack.Application/Common/Interfaces/I{Module}Service.cs
|
|
51
51
|
|
|
52
|
-
using SmartStack.Application.$MODULE_PASCAL.
|
|
52
|
+
using SmartStack.Application.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL.DTOs;
|
|
53
53
|
|
|
54
54
|
namespace SmartStack.Application.Common.Interfaces;
|
|
55
55
|
|
|
@@ -88,8 +88,8 @@ public interface I$MODULE_PASCALService
|
|
|
88
88
|
using Microsoft.EntityFrameworkCore;
|
|
89
89
|
using Microsoft.Extensions.Logging;
|
|
90
90
|
using SmartStack.Application.Common.Interfaces;
|
|
91
|
-
using SmartStack.Application.$MODULE_PASCAL.
|
|
92
|
-
using SmartStack.Domain.$MODULE_PASCAL;
|
|
91
|
+
using SmartStack.Application.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL.DTOs;
|
|
92
|
+
using SmartStack.Domain.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL;
|
|
93
93
|
|
|
94
94
|
namespace SmartStack.Infrastructure.Services.$MODULE_PASCAL;
|
|
95
95
|
|
|
@@ -269,9 +269,9 @@ public class $MODULE_PASCALService : I$MODULE_PASCALService
|
|
|
269
269
|
## TEMPLATE: DTOs
|
|
270
270
|
|
|
271
271
|
```csharp
|
|
272
|
-
// src/SmartStack.Application/$MODULE_PASCAL/
|
|
272
|
+
// src/SmartStack.Application/$CONTEXT_PASCAL/$APPLICATION_PASCAL/$MODULE_PASCAL/DTOs/$ENTITY_PASCALDto.cs
|
|
273
273
|
|
|
274
|
-
namespace SmartStack.Application.$MODULE_PASCAL.
|
|
274
|
+
namespace SmartStack.Application.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL.DTOs;
|
|
275
275
|
|
|
276
276
|
public record $ENTITY_PASCALDto
|
|
277
277
|
{
|
|
@@ -310,11 +310,11 @@ public record $ENTITY_PASCALQueryParameters
|
|
|
310
310
|
## TEMPLATE: DOMAIN ENTITY
|
|
311
311
|
|
|
312
312
|
```csharp
|
|
313
|
-
// src/SmartStack.Domain/$MODULE_PASCAL/$ENTITY_PASCAL.cs
|
|
313
|
+
// src/SmartStack.Domain/$CONTEXT_PASCAL/$APPLICATION_PASCAL/$MODULE_PASCAL/$ENTITY_PASCAL.cs
|
|
314
314
|
|
|
315
315
|
using SmartStack.Domain.Common;
|
|
316
316
|
|
|
317
|
-
namespace SmartStack.Domain.$MODULE_PASCAL;
|
|
317
|
+
namespace SmartStack.Domain.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL;
|
|
318
318
|
|
|
319
319
|
public class $ENTITY_PASCAL : BaseEntity
|
|
320
320
|
{
|
|
@@ -363,7 +363,7 @@ public class $ENTITY_PASCAL : BaseEntity
|
|
|
363
363
|
|
|
364
364
|
using Microsoft.EntityFrameworkCore;
|
|
365
365
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
366
|
-
using SmartStack.Domain.$MODULE_PASCAL;
|
|
366
|
+
using SmartStack.Domain.$CONTEXT_PASCAL.$APPLICATION_PASCAL.$MODULE_PASCAL;
|
|
367
367
|
|
|
368
368
|
namespace SmartStack.Infrastructure.Persistence.Configurations.$MODULE_PASCAL;
|
|
369
369
|
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
web/smartstack-web/src/
|
|
11
|
-
├── pages/$CONTEXT/$MODULE/
|
|
11
|
+
├── pages/$CONTEXT/$APPLICATION/$MODULE/
|
|
12
12
|
│ ├── $MODULE_PASCALPage.tsx # Main page (list)
|
|
13
13
|
│ ├── $MODULE_PASCALDetailPage.tsx # Detail page
|
|
14
14
|
│ └── Create$MODULE_PASCALPage.tsx # Create page
|
|
15
|
-
├── components/$MODULE/
|
|
15
|
+
├── components/$CONTEXT/$MODULE/
|
|
16
16
|
│ ├── $MODULE_PASCALListView.tsx # Reusable list component
|
|
17
17
|
│ ├── $MODULE_PASCALForm.tsx # CRUD form
|
|
18
18
|
│ └── $MODULE_PASCALFilters.tsx # Filters
|
|
@@ -35,10 +35,10 @@ web/smartstack-web/src/
|
|
|
35
35
|
## TEMPLATE: MAIN PAGE
|
|
36
36
|
|
|
37
37
|
```tsx
|
|
38
|
-
// pages/$CONTEXT/$MODULE/$MODULE_PASCALPage.tsx
|
|
38
|
+
// pages/$CONTEXT/$APPLICATION/$MODULE/$MODULE_PASCALPage.tsx
|
|
39
39
|
|
|
40
40
|
import { useTranslation } from 'react-i18next';
|
|
41
|
-
import { $MODULE_PASCALListView } from '@/components/$MODULE/$MODULE_PASCALListView';
|
|
41
|
+
import { $MODULE_PASCALListView } from '@/components/$CONTEXT/$MODULE/$MODULE_PASCALListView';
|
|
42
42
|
|
|
43
43
|
export function $MODULE_PASCALPage() {
|
|
44
44
|
const { t } = useTranslation(['$module', 'common']);
|
|
@@ -59,7 +59,7 @@ export function $MODULE_PASCALPage() {
|
|
|
59
59
|
## TEMPLATE: LIST VIEW (Reusable component)
|
|
60
60
|
|
|
61
61
|
```tsx
|
|
62
|
-
// components/$MODULE/$MODULE_PASCALListView.tsx
|
|
62
|
+
// components/$CONTEXT/$MODULE/$MODULE_PASCALListView.tsx
|
|
63
63
|
|
|
64
64
|
import { useState, useEffect } from 'react';
|
|
65
65
|
import { useNavigate } from 'react-router-dom';
|
|
@@ -491,9 +491,9 @@ React Router v7 **requires** nested routes for multi-module applications.
|
|
|
491
491
|
```tsx
|
|
492
492
|
// Add to App.tsx
|
|
493
493
|
|
|
494
|
-
import { $MODULE_PASCALPage } from '@/pages/$CONTEXT/$MODULE/$MODULE_PASCALPage';
|
|
495
|
-
import { $MODULE_PASCALDetailPage } from '@/pages/$CONTEXT/$MODULE/$MODULE_PASCALDetailPage';
|
|
496
|
-
import { Create$MODULE_PASCALPage } from '@/pages/$CONTEXT/$MODULE/Create$MODULE_PASCALPage';
|
|
494
|
+
import { $MODULE_PASCALPage } from '@/pages/$CONTEXT/$APPLICATION/$MODULE/$MODULE_PASCALPage';
|
|
495
|
+
import { $MODULE_PASCALDetailPage } from '@/pages/$CONTEXT/$APPLICATION/$MODULE/$MODULE_PASCALDetailPage';
|
|
496
|
+
import { Create$MODULE_PASCALPage } from '@/pages/$CONTEXT/$APPLICATION/$MODULE/Create$MODULE_PASCALPage';
|
|
497
497
|
|
|
498
498
|
// In routes - NESTED STRUCTURE
|
|
499
499
|
<Route path="$APPLICATION">
|
|
@@ -45,12 +45,113 @@ normalize_branch_name() {
|
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
48
|
+
## RESOLVE_CONFIG_PATH
|
|
49
|
+
|
|
50
|
+
Resolves the config.json path regardless of current working directory.
|
|
51
|
+
Searches in: pwd, develop worktree, then git root.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
resolve_gitflow_config_path() {
|
|
55
|
+
# 1. Try current directory
|
|
56
|
+
[ -f ".claude/gitflow/config.json" ] && { echo ".claude/gitflow/config.json"; return 0; }
|
|
57
|
+
|
|
58
|
+
# 2. Try to find develop worktree from git worktree list
|
|
59
|
+
local DEVELOP_PATH
|
|
60
|
+
DEVELOP_PATH=$(git worktree list --porcelain 2>/dev/null | grep -A1 "branch refs/heads/develop" | grep "^worktree " | sed 's/^worktree //')
|
|
61
|
+
[ -n "$DEVELOP_PATH" ] && [ -f "$DEVELOP_PATH/.claude/gitflow/config.json" ] && {
|
|
62
|
+
echo "$DEVELOP_PATH/.claude/gitflow/config.json"
|
|
63
|
+
return 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# 3. Try git toplevel
|
|
67
|
+
local GIT_ROOT
|
|
68
|
+
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
69
|
+
[ -n "$GIT_ROOT" ] && [ -f "$GIT_ROOT/.claude/gitflow/config.json" ] && {
|
|
70
|
+
echo "$GIT_ROOT/.claude/gitflow/config.json"
|
|
71
|
+
return 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return 1
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## READ_GITFLOW_CONFIG
|
|
81
|
+
|
|
82
|
+
Reads GitFlow configuration from config.json. Exposes all variables needed by steps and phases.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
read_gitflow_config() {
|
|
86
|
+
local CONFIG_FILE
|
|
87
|
+
CONFIG_FILE=$(resolve_gitflow_config_path) || {
|
|
88
|
+
echo "❌ GitFlow config not found. Run /gitflow init first."
|
|
89
|
+
return 1
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Repository
|
|
93
|
+
GF_PROJECT_NAME=$(grep -oP '"name":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
94
|
+
GF_ROOT_FOLDER=$(grep -oP '"rootFolder":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
95
|
+
GF_REMOTE_URL=$(grep -oP '"remoteUrl":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
96
|
+
|
|
97
|
+
# Git provider and branches
|
|
98
|
+
GF_PROVIDER=$(grep -oP '"provider":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
99
|
+
GF_MAIN_BRANCH=$(grep -oP '"main":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
100
|
+
GF_DEVELOP_BRANCH=$(grep -oP '"develop":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
101
|
+
|
|
102
|
+
# Prefixes
|
|
103
|
+
GF_FEATURE_PREFIX=$(grep -oP '"feature":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
104
|
+
GF_RELEASE_PREFIX=$(grep -oP '"release":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
105
|
+
GF_HOTFIX_PREFIX=$(grep -oP '"hotfix":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
106
|
+
|
|
107
|
+
# Worktrees
|
|
108
|
+
GF_WORKTREE_MODE=$(grep -oP '"mode":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
109
|
+
GF_MAIN_PATH=$(grep -A1 '"structure"' "$CONFIG_FILE" | grep -oP '"main":\s*"\K[^"]+' | head -1)
|
|
110
|
+
GF_DEVELOP_PATH=$(grep -A2 '"structure"' "$CONFIG_FILE" | grep -oP '"develop":\s*"\K[^"]+' | head -1)
|
|
111
|
+
GF_FEATURES_PATH=$(grep -oP '"features":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
112
|
+
GF_RELEASES_PATH=$(grep -oP '"releases":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
113
|
+
GF_HOTFIXES_PATH=$(grep -oP '"hotfixes":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
114
|
+
|
|
115
|
+
# Language
|
|
116
|
+
GF_LANG=$(grep -oP '"code":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
117
|
+
|
|
118
|
+
# Versioning
|
|
119
|
+
GF_VERSION=$(grep -oP '"current":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
120
|
+
GF_TAG_PREFIX=$(grep -oP '"tagPrefix":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
121
|
+
|
|
122
|
+
# Defaults for missing values
|
|
123
|
+
GF_LANG=${GF_LANG:-en}
|
|
124
|
+
GF_WORKTREE_MODE=${GF_WORKTREE_MODE:-organized}
|
|
125
|
+
GF_MAIN_BRANCH=${GF_MAIN_BRANCH:-main}
|
|
126
|
+
GF_DEVELOP_BRANCH=${GF_DEVELOP_BRANCH:-develop}
|
|
127
|
+
GF_FEATURE_PREFIX=${GF_FEATURE_PREFIX:-feature/}
|
|
128
|
+
GF_RELEASE_PREFIX=${GF_RELEASE_PREFIX:-release/}
|
|
129
|
+
GF_HOTFIX_PREFIX=${GF_HOTFIX_PREFIX:-hotfix/}
|
|
130
|
+
GF_TAG_PREFIX=${GF_TAG_PREFIX:-v}
|
|
131
|
+
GF_VERSION=${GF_VERSION:-0.1.0}
|
|
132
|
+
|
|
133
|
+
# Export config file path for steps that need to update it
|
|
134
|
+
GF_CONFIG_FILE="$CONFIG_FILE"
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
48
140
|
## DETECT_WORKTREE_MODE
|
|
49
141
|
|
|
50
|
-
Detects worktree mode
|
|
142
|
+
Detects worktree mode. Reads config first, falls back to filesystem detection.
|
|
51
143
|
|
|
52
144
|
```bash
|
|
53
145
|
detect_worktree_mode() {
|
|
146
|
+
# 1. Try config first (authoritative)
|
|
147
|
+
local CONFIG_FILE
|
|
148
|
+
CONFIG_FILE=$(resolve_gitflow_config_path 2>/dev/null)
|
|
149
|
+
if [ -n "$CONFIG_FILE" ] && [ -f "$CONFIG_FILE" ]; then
|
|
150
|
+
WORKTREE_MODE=$(grep -oP '"mode":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
151
|
+
[ -n "$WORKTREE_MODE" ] && return 0
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# 2. Fallback: filesystem detection
|
|
54
155
|
if [ -d "../features" ] && [ -d "../releases" ] && [ -d "../hotfixes" ]; then
|
|
55
156
|
WORKTREE_MODE="organized"
|
|
56
157
|
elif [ -d "../01-Main" ] && [ -d "../02-Develop" ]; then
|
|
@@ -58,9 +159,7 @@ detect_worktree_mode() {
|
|
|
58
159
|
elif [ -d "../worktrees" ]; then
|
|
59
160
|
WORKTREE_MODE="adjacent"
|
|
60
161
|
else
|
|
61
|
-
|
|
62
|
-
[ -f "$CONFIG_FILE" ] && WORKTREE_MODE=$(grep -oP '"mode":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
63
|
-
WORKTREE_MODE=${WORKTREE_MODE:-adjacent}
|
|
162
|
+
WORKTREE_MODE="organized"
|
|
64
163
|
fi
|
|
65
164
|
}
|
|
66
165
|
```
|
|
@@ -69,26 +168,30 @@ detect_worktree_mode() {
|
|
|
69
168
|
|
|
70
169
|
## CLEANUP_WORKTREE
|
|
71
170
|
|
|
72
|
-
Cleans up a worktree for a given branch.
|
|
171
|
+
Cleans up a worktree for a given branch. Uses config paths when available.
|
|
73
172
|
|
|
74
173
|
```bash
|
|
75
174
|
cleanup_worktree_for_branch() {
|
|
76
|
-
local BRANCH=$1
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
#
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
175
|
+
local BRANCH=$1 WORKTREE_PATH=""
|
|
176
|
+
|
|
177
|
+
# Try config-based paths first (absolute, reliable)
|
|
178
|
+
read_gitflow_config 2>/dev/null
|
|
179
|
+
if [ -n "$GF_FEATURES_PATH" ]; then
|
|
180
|
+
case "$BRANCH" in
|
|
181
|
+
feature/*) WORKTREE_PATH="$GF_FEATURES_PATH/${BRANCH#feature/}" ;;
|
|
182
|
+
release/*) WORKTREE_PATH="$GF_RELEASES_PATH/${BRANCH#release/}" ;;
|
|
183
|
+
hotfix/*) WORKTREE_PATH="$GF_HOTFIXES_PATH/${BRANCH#hotfix/}" ;;
|
|
184
|
+
esac
|
|
185
|
+
else
|
|
186
|
+
# Fallback: relative paths
|
|
187
|
+
case "$BRANCH" in
|
|
188
|
+
feature/*) WORKTREE_PATH="../features/${BRANCH#feature/}" ;;
|
|
189
|
+
release/*) WORKTREE_PATH="../releases/${BRANCH#release/}" ;;
|
|
190
|
+
hotfix/*) WORKTREE_PATH="../hotfixes/${BRANCH#hotfix/}" ;;
|
|
191
|
+
esac
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
[ -n "$WORKTREE_PATH" ] && [ -d "$WORKTREE_PATH" ] && {
|
|
92
195
|
git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || rm -rf "$WORKTREE_PATH"
|
|
93
196
|
git worktree prune
|
|
94
197
|
echo "✓ Worktree cleaned: $WORKTREE_PATH"
|
|
@@ -116,47 +219,79 @@ sync_with_remote() {
|
|
|
116
219
|
|
|
117
220
|
---
|
|
118
221
|
|
|
119
|
-
## READ_GITFLOW_CONFIG
|
|
120
|
-
|
|
121
|
-
Reads GitFlow configuration.
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
read_gitflow_config() {
|
|
125
|
-
local CONFIG_FILE=".claude/gitflow/config.json"
|
|
126
|
-
[ ! -f "$CONFIG_FILE" ] && return 1
|
|
127
|
-
|
|
128
|
-
# Exported variables
|
|
129
|
-
GF_LANG=$(grep -oP '"code":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
130
|
-
GF_WORKTREE_MODE=$(grep -oP '"mode":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
131
|
-
GF_MAIN_BRANCH=$(grep -oP '"main":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
132
|
-
GF_DEVELOP_BRANCH=$(grep -oP '"develop":\s*"\K[^"]+' "$CONFIG_FILE" | head -1)
|
|
133
|
-
|
|
134
|
-
GF_LANG=${GF_LANG:-en}
|
|
135
|
-
GF_WORKTREE_MODE=${GF_WORKTREE_MODE:-adjacent}
|
|
136
|
-
GF_MAIN_BRANCH=${GF_MAIN_BRANCH:-main}
|
|
137
|
-
GF_DEVELOP_BRANCH=${GF_DEVELOP_BRANCH:-develop}
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
222
|
## CONFIG_TEMPLATE
|
|
144
223
|
|
|
145
|
-
GitFlow configuration JSON template (
|
|
224
|
+
GitFlow configuration JSON template v2.0.0 (aligned with `templates/config.json`).
|
|
146
225
|
|
|
147
226
|
```json
|
|
148
227
|
{
|
|
149
|
-
"version": "
|
|
150
|
-
"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
228
|
+
"version": "2.0.0",
|
|
229
|
+
"repository": {
|
|
230
|
+
"name": "",
|
|
231
|
+
"rootFolder": "",
|
|
232
|
+
"nameVariants": {
|
|
233
|
+
"pascalCaseDot": "",
|
|
234
|
+
"pascalCase": "",
|
|
235
|
+
"kebabCase": "",
|
|
236
|
+
"snakeCase": "",
|
|
237
|
+
"displayName": ""
|
|
238
|
+
},
|
|
239
|
+
"defaultBranch": "main",
|
|
240
|
+
"remoteUrl": ""
|
|
241
|
+
},
|
|
242
|
+
"git": {
|
|
243
|
+
"provider": "",
|
|
244
|
+
"branches": {
|
|
245
|
+
"main": "main",
|
|
246
|
+
"develop": "develop"
|
|
247
|
+
},
|
|
248
|
+
"prefixes": {
|
|
249
|
+
"feature": "feature/",
|
|
250
|
+
"release": "release/",
|
|
251
|
+
"hotfix": "hotfix/"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
"worktrees": {
|
|
255
|
+
"enabled": true,
|
|
256
|
+
"mode": "organized",
|
|
257
|
+
"structure": {
|
|
258
|
+
"main": "",
|
|
259
|
+
"develop": "",
|
|
260
|
+
"features": "",
|
|
261
|
+
"releases": "",
|
|
262
|
+
"hotfixes": ""
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"versioning": {
|
|
266
|
+
"strategy": "semver",
|
|
267
|
+
"current": "0.1.0",
|
|
268
|
+
"tagPrefix": "v",
|
|
269
|
+
"sources": ["csproj", "package.json", "VERSION"]
|
|
270
|
+
},
|
|
271
|
+
"efcore": {
|
|
272
|
+
"enabled": true,
|
|
273
|
+
"validateOnCommit": true,
|
|
274
|
+
"blockDestructive": true,
|
|
275
|
+
"migrationNaming": "{context}_v{version}_{sequence}_{Description}"
|
|
276
|
+
},
|
|
277
|
+
"workflow": {
|
|
278
|
+
"push": {
|
|
279
|
+
"afterCommit": "worktree"
|
|
280
|
+
},
|
|
281
|
+
"pr": {
|
|
282
|
+
"autoLabels": true,
|
|
283
|
+
"requireReview": true
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
"language": {
|
|
287
|
+
"code": "en"
|
|
288
|
+
}
|
|
154
289
|
}
|
|
155
290
|
```
|
|
156
291
|
|
|
157
292
|
**worktrees.mode options:**
|
|
158
|
-
- `organized`:
|
|
159
|
-
- `adjacent`:
|
|
293
|
+
- `organized`: Uses absolute paths from config (`structure.features`, etc.)
|
|
294
|
+
- `adjacent`: `{rootFolder}/worktrees/{type}/`
|
|
160
295
|
- `disabled`: No worktrees
|
|
161
296
|
|
|
162
297
|
---
|
|
@@ -11,6 +11,13 @@ Provide rollback and recovery options for GitFlow operations.
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## PRE-CHECK:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Load GitFlow config (sets GF_* variables)
|
|
18
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
19
|
+
```
|
|
20
|
+
|
|
14
21
|
## OPTIONS:
|
|
15
22
|
|
|
16
23
|
```yaml
|
|
@@ -23,7 +30,7 @@ AskUserQuestion:
|
|
|
23
30
|
- label: "Abandon current branch"
|
|
24
31
|
description: "Delete branch and worktree, return to develop"
|
|
25
32
|
- label: "Restore from checkpoint"
|
|
26
|
-
description: "Restore to a saved checkpoint"
|
|
33
|
+
description: "Restore to a saved checkpoint (not yet implemented)"
|
|
27
34
|
- label: "Reset branch to remote"
|
|
28
35
|
description: "Discard local changes, match remote"
|
|
29
36
|
```
|
|
@@ -69,7 +76,7 @@ git tag "$BACKUP_TAG" HEAD
|
|
|
69
76
|
echo "✓ Backup created: $BACKUP_TAG"
|
|
70
77
|
|
|
71
78
|
# Switch to develop
|
|
72
|
-
git checkout
|
|
79
|
+
git checkout $GF_DEVELOP_BRANCH
|
|
73
80
|
|
|
74
81
|
# Remove worktree
|
|
75
82
|
[ -n "$WORKTREE" ] && {
|
|
@@ -87,30 +94,35 @@ echo " Backup: $BACKUP_TAG (use 'git checkout $BACKUP_TAG' to recover)"
|
|
|
87
94
|
|
|
88
95
|
### Option 3: Restore from Checkpoint
|
|
89
96
|
|
|
97
|
+
> **Note:** Checkpoint creation is not yet implemented. This option uses backup tags
|
|
98
|
+
> created by abort operations as a recovery mechanism. Full checkpoint support
|
|
99
|
+
> (automatic state snapshots during plan execution) is planned for a future release.
|
|
100
|
+
|
|
90
101
|
```bash
|
|
91
|
-
# List available
|
|
92
|
-
|
|
102
|
+
# List available backup tags (created by abandon operations)
|
|
103
|
+
BACKUPS=$(git tag -l "backup/*" --sort=-creatordate 2>/dev/null)
|
|
93
104
|
|
|
94
|
-
if [ -z "$
|
|
95
|
-
echo "No
|
|
105
|
+
if [ -z "$BACKUPS" ]; then
|
|
106
|
+
echo "No backup tags found"
|
|
107
|
+
echo " Backup tags are created automatically when abandoning branches."
|
|
108
|
+
echo " Use 'Reset branch to remote' instead."
|
|
96
109
|
exit 1
|
|
97
110
|
fi
|
|
98
111
|
|
|
99
|
-
echo "Available
|
|
100
|
-
for
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
echo " - $TIMESTAMP: $BRANCH @ $COMMIT"
|
|
112
|
+
echo "Available backups:"
|
|
113
|
+
for tag in $BACKUPS; do
|
|
114
|
+
COMMIT=$(git rev-parse --short "$tag")
|
|
115
|
+
DATE=$(git log -1 --format=%ci "$tag" 2>/dev/null)
|
|
116
|
+
echo " - $tag → $COMMIT ($DATE)"
|
|
105
117
|
done
|
|
106
118
|
|
|
107
|
-
# Select
|
|
119
|
+
# Select backup
|
|
108
120
|
# ... user selection ...
|
|
109
121
|
|
|
110
122
|
# Restore
|
|
111
|
-
|
|
112
|
-
git
|
|
113
|
-
echo "✓ Restored to
|
|
123
|
+
git checkout "$SELECTED_TAG"
|
|
124
|
+
git checkout -b "recovered-$(date +%Y%m%d-%H%M%S)"
|
|
125
|
+
echo "✓ Restored from $SELECTED_TAG to new branch"
|
|
114
126
|
```
|
|
115
127
|
|
|
116
128
|
### Option 4: Reset to Remote
|
|
@@ -16,12 +16,15 @@ Audit worktrees and branches, remove orphaned/stale items.
|
|
|
16
16
|
## PRE-CHECK:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
+
# Load GitFlow config (sets GF_* variables)
|
|
20
|
+
read_gitflow_config || { echo "❌ Run /gitflow init first."; exit 1; }
|
|
21
|
+
|
|
19
22
|
CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
20
23
|
|
|
21
|
-
[[ "$CURRENT" != "
|
|
22
|
-
echo "❌ Cleanup must be run from
|
|
24
|
+
[[ "$CURRENT" != "$GF_MAIN_BRANCH" ]] && [[ "$CURRENT" != "$GF_DEVELOP_BRANCH" ]] && {
|
|
25
|
+
echo "❌ Cleanup must be run from $GF_MAIN_BRANCH or $GF_DEVELOP_BRANCH"
|
|
23
26
|
echo " Current branch: $CURRENT"
|
|
24
|
-
echo "→ Run: git checkout
|
|
27
|
+
echo "→ Run: git checkout $GF_DEVELOP_BRANCH"
|
|
25
28
|
STOP
|
|
26
29
|
}
|
|
27
30
|
```
|
|
@@ -35,7 +38,8 @@ CURRENT=$(git rev-parse --abbrev-ref HEAD)
|
|
|
35
38
|
```bash
|
|
36
39
|
echo "Scanning worktrees..."
|
|
37
40
|
|
|
38
|
-
|
|
41
|
+
mkdir -p .claude/gitflow/cache
|
|
42
|
+
git worktree list > .claude/gitflow/cache/worktrees.txt
|
|
39
43
|
|
|
40
44
|
ORPHANED=()
|
|
41
45
|
STALE=()
|
|
@@ -54,13 +58,13 @@ while read -r line; do
|
|
|
54
58
|
|
|
55
59
|
# Check if branch still exists on remote
|
|
56
60
|
REMOTE_EXISTS=$(git branch -r --list "origin/$WT_BRANCH" | wc -l)
|
|
57
|
-
if [ "$REMOTE_EXISTS" -eq 0 ] && [[ "$WT_BRANCH" != "
|
|
61
|
+
if [ "$REMOTE_EXISTS" -eq 0 ] && [[ "$WT_BRANCH" != "$GF_MAIN_BRANCH" ]] && [[ "$WT_BRANCH" != "$GF_DEVELOP_BRANCH" ]]; then
|
|
58
62
|
STALE+=("$WT_PATH:$WT_BRANCH")
|
|
59
63
|
continue
|
|
60
64
|
fi
|
|
61
65
|
|
|
62
66
|
VALID+=("$WT_PATH:$WT_BRANCH")
|
|
63
|
-
done < /
|
|
67
|
+
done < .claude/gitflow/cache/worktrees.txt
|
|
64
68
|
```
|
|
65
69
|
|
|
66
70
|
### 2. Audit Local Branches
|
|
@@ -72,17 +76,17 @@ MERGED_BRANCHES=()
|
|
|
72
76
|
UNMERGED_BRANCHES=()
|
|
73
77
|
|
|
74
78
|
# Find merged branches
|
|
75
|
-
for branch in $(git branch --merged
|
|
79
|
+
for branch in $(git branch --merged $GF_DEVELOP_BRANCH | grep -v "^\*" | grep -v "$GF_MAIN_BRANCH" | grep -v "$GF_DEVELOP_BRANCH"); do
|
|
76
80
|
# Check if remote exists
|
|
77
81
|
REMOTE_EXISTS=$(git branch -r --list "origin/$branch" | wc -l)
|
|
78
82
|
[ "$REMOTE_EXISTS" -eq 0 ] && MERGED_BRANCHES+=("$branch")
|
|
79
83
|
done
|
|
80
84
|
|
|
81
85
|
# Find branches without remote
|
|
82
|
-
for branch in $(git branch | grep -v "^\*" | grep -v "
|
|
86
|
+
for branch in $(git branch | grep -v "^\*" | grep -v "$GF_MAIN_BRANCH" | grep -v "$GF_DEVELOP_BRANCH"); do
|
|
83
87
|
REMOTE_EXISTS=$(git branch -r --list "origin/$branch" | wc -l)
|
|
84
88
|
[ "$REMOTE_EXISTS" -eq 0 ] && {
|
|
85
|
-
MERGED=$(git branch --merged
|
|
89
|
+
MERGED=$(git branch --merged $GF_DEVELOP_BRANCH | grep -c "$branch")
|
|
86
90
|
[ "$MERGED" -eq 0 ] && UNMERGED_BRANCHES+=("$branch")
|
|
87
91
|
}
|
|
88
92
|
done
|