sedd 0.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/README.md +504 -0
- package/bin/sedd.js +6 -0
- package/commands/sedd.clarify.md +435 -0
- package/commands/sedd.dashboard.md +145 -0
- package/commands/sedd.implement.md +326 -0
- package/commands/sedd.migrate.md +249 -0
- package/commands/sedd.specify.md +198 -0
- package/commands/sedd.tasks.md +176 -0
- package/dist/cli/check.d.ts +6 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +134 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/clarify.d.ts +2 -0
- package/dist/cli/clarify.d.ts.map +1 -0
- package/dist/cli/clarify.js +116 -0
- package/dist/cli/clarify.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +175 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +9 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +236 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/migrate.d.ts +7 -0
- package/dist/cli/migrate.d.ts.map +1 -0
- package/dist/cli/migrate.js +197 -0
- package/dist/cli/migrate.js.map +1 -0
- package/dist/cli/specify.d.ts +7 -0
- package/dist/cli/specify.d.ts.map +1 -0
- package/dist/cli/specify.js +131 -0
- package/dist/cli/specify.js.map +1 -0
- package/dist/cli/status.d.ts +6 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +118 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/tasks.d.ts +7 -0
- package/dist/cli/tasks.d.ts.map +1 -0
- package/dist/cli/tasks.js +165 -0
- package/dist/cli/tasks.js.map +1 -0
- package/dist/core/changelog.d.ts +30 -0
- package/dist/core/changelog.d.ts.map +1 -0
- package/dist/core/changelog.js +97 -0
- package/dist/core/changelog.js.map +1 -0
- package/dist/core/file-splitter.d.ts +39 -0
- package/dist/core/file-splitter.d.ts.map +1 -0
- package/dist/core/file-splitter.js +162 -0
- package/dist/core/file-splitter.js.map +1 -0
- package/dist/core/migration-manager.d.ts +76 -0
- package/dist/core/migration-manager.d.ts.map +1 -0
- package/dist/core/migration-manager.js +230 -0
- package/dist/core/migration-manager.js.map +1 -0
- package/dist/core/timestamps.d.ts +17 -0
- package/dist/core/timestamps.d.ts.map +1 -0
- package/dist/core/timestamps.js +37 -0
- package/dist/core/timestamps.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +102 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +83 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/git.d.ts +63 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +179 -0
- package/dist/utils/git.js.map +1 -0
- package/hooks/README.md +220 -0
- package/hooks/check-roadmap.js +231 -0
- package/hooks/check-roadmap.ps1 +343 -0
- package/package.json +60 -0
- package/scripts/bash/sedd-clarify.sh +142 -0
- package/scripts/bash/sedd-complete-task.sh +108 -0
- package/scripts/bash/sedd-specify.sh +147 -0
- package/scripts/powershell/sedd-clarify.ps1 +222 -0
- package/scripts/powershell/sedd-complete-task.ps1 +143 -0
- package/scripts/powershell/sedd-specify.ps1 +192 -0
- package/scripts/powershell/sedd-status.ps1 +153 -0
- package/scripts/powershell/sedd-tasks.ps1 +176 -0
- package/templates/changelog-template.md +6 -0
- package/templates/clarify-template.md +66 -0
- package/templates/config-template.json +20 -0
- package/templates/decisions-template.md +56 -0
- package/templates/interfaces-template.ts +131 -0
- package/templates/meta-template.json +12 -0
- package/templates/progress-template.md +61 -0
- package/templates/sedd.schema.json +95 -0
- package/templates/spec-template.md +114 -0
- package/templates/tasks-template.md +58 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
Shows current SEDD feature status
|
|
5
|
+
.PARAMETER Branch
|
|
6
|
+
Feature branch name (optional, auto-detected)
|
|
7
|
+
.PARAMETER Json
|
|
8
|
+
Output as JSON
|
|
9
|
+
.EXAMPLE
|
|
10
|
+
./sedd-status.ps1
|
|
11
|
+
./sedd-status.ps1 -Json
|
|
12
|
+
#>
|
|
13
|
+
|
|
14
|
+
param(
|
|
15
|
+
[Parameter(Mandatory = $false)]
|
|
16
|
+
[string]$Branch = "",
|
|
17
|
+
|
|
18
|
+
[switch]$Json
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
$ErrorActionPreference = 'SilentlyContinue'
|
|
22
|
+
|
|
23
|
+
#region Config
|
|
24
|
+
|
|
25
|
+
function Get-SeddConfig {
|
|
26
|
+
$configPath = Join-Path (Get-Location) 'sedd.config.json'
|
|
27
|
+
if (Test-Path $configPath) {
|
|
28
|
+
try {
|
|
29
|
+
$config = Get-Content $configPath -Raw | ConvertFrom-Json -AsHashtable
|
|
30
|
+
return @{ specsDir = if ($config.specsDir) { $config.specsDir } else { '.sedd' } }
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
}
|
|
34
|
+
return @{ specsDir = '.sedd' }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function Get-CurrentBranch {
|
|
38
|
+
try { return (git rev-parse --abbrev-ref HEAD 2>$null).Trim() }
|
|
39
|
+
catch { return '' }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#endregion
|
|
43
|
+
|
|
44
|
+
#region Main
|
|
45
|
+
|
|
46
|
+
$config = Get-SeddConfig
|
|
47
|
+
$specsDir = $config.specsDir
|
|
48
|
+
|
|
49
|
+
if (-not $Branch) { $Branch = Get-CurrentBranch }
|
|
50
|
+
|
|
51
|
+
if (-not ($Branch -match '^\d{3}-')) {
|
|
52
|
+
if ($Json) {
|
|
53
|
+
Write-Output (@{ error = "Not on a feature branch"; branch = $Branch } | ConvertTo-Json -Compress)
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
Write-Host "Not on a feature branch (current: $Branch)" -ForegroundColor Yellow
|
|
57
|
+
}
|
|
58
|
+
exit 0
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
# Find feature directory
|
|
62
|
+
$featureDir = Join-Path (Get-Location) "$specsDir/$Branch"
|
|
63
|
+
if (-not (Test-Path $featureDir)) {
|
|
64
|
+
$featureDir = Join-Path (Get-Location) "specs/$Branch"
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (-not (Test-Path $featureDir)) {
|
|
68
|
+
if ($Json) {
|
|
69
|
+
Write-Output (@{ error = "Feature not found"; branch = $Branch } | ConvertTo-Json -Compress)
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
Write-Host "Feature not found: $Branch" -ForegroundColor Red
|
|
73
|
+
}
|
|
74
|
+
exit 0
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Load meta
|
|
78
|
+
$metaPath = Join-Path $featureDir '_meta.json'
|
|
79
|
+
if (-not (Test-Path $metaPath)) {
|
|
80
|
+
if ($Json) {
|
|
81
|
+
Write-Output (@{ error = "No _meta.json"; branch = $Branch; legacy = $true } | ConvertTo-Json -Compress)
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
Write-Host "Legacy structure (no _meta.json). Run /sedd.migrate" -ForegroundColor Yellow
|
|
85
|
+
}
|
|
86
|
+
exit 0
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
$meta = Get-Content $metaPath -Raw | ConvertFrom-Json
|
|
90
|
+
|
|
91
|
+
# Collect pending tasks
|
|
92
|
+
$allPending = @()
|
|
93
|
+
$totalCompleted = 0
|
|
94
|
+
$totalTasks = 0
|
|
95
|
+
|
|
96
|
+
foreach ($migId in $meta.migrations.PSObject.Properties.Name) {
|
|
97
|
+
$migInfo = $meta.migrations.$migId
|
|
98
|
+
$totalTasks += $migInfo.tasksTotal
|
|
99
|
+
$totalCompleted += $migInfo.tasksCompleted
|
|
100
|
+
|
|
101
|
+
$tasksFile = Join-Path $featureDir "$($migInfo.folder)/tasks.md"
|
|
102
|
+
if (Test-Path $tasksFile) {
|
|
103
|
+
$content = Get-Content $tasksFile -Raw
|
|
104
|
+
foreach ($line in ($content -split "`n")) {
|
|
105
|
+
if ($line -match '^\s*-\s*\[\s*\]\s*(T\d{3}-\d{3})\s+(.+)') {
|
|
106
|
+
$allPending += @{
|
|
107
|
+
id = $Matches[1]
|
|
108
|
+
migration = $migId
|
|
109
|
+
text = ($Matches[2] -replace '`[^`]+`', '').Trim()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ($Json) {
|
|
117
|
+
$output = @{
|
|
118
|
+
branch = $Branch
|
|
119
|
+
featureId = $meta.featureId
|
|
120
|
+
featureName = $meta.featureName
|
|
121
|
+
currentMigration = $meta.currentMigration
|
|
122
|
+
totalMigrations = $meta.migrations.PSObject.Properties.Name.Count
|
|
123
|
+
totalTasks = $totalTasks
|
|
124
|
+
completedTasks = $totalCompleted
|
|
125
|
+
pendingTasks = $allPending
|
|
126
|
+
}
|
|
127
|
+
Write-Output ($output | ConvertTo-Json -Depth 10 -Compress)
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
Write-Host "`n=== SEDD Status ===" -ForegroundColor Cyan
|
|
131
|
+
Write-Host "Branch: $Branch" -ForegroundColor White
|
|
132
|
+
Write-Host "Feature: $($meta.featureName) ($($meta.featureId))" -ForegroundColor White
|
|
133
|
+
Write-Host "Current Migration: $($meta.currentMigration)" -ForegroundColor White
|
|
134
|
+
Write-Host "Progress: $totalCompleted/$totalTasks tasks" -ForegroundColor White
|
|
135
|
+
|
|
136
|
+
if ($allPending.Count -gt 0) {
|
|
137
|
+
Write-Host "`nPending Tasks:" -ForegroundColor Yellow
|
|
138
|
+
foreach ($task in ($allPending | Select-Object -First 10)) {
|
|
139
|
+
$truncated = if ($task.text.Length -gt 60) { $task.text.Substring(0, 60) + '...' } else { $task.text }
|
|
140
|
+
Write-Host " - $($task.id): $truncated" -ForegroundColor White
|
|
141
|
+
}
|
|
142
|
+
if ($allPending.Count -gt 10) {
|
|
143
|
+
Write-Host " ... and $($allPending.Count - 10) more" -ForegroundColor Gray
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
Write-Host "`nAll tasks completed!" -ForegroundColor Green
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
Write-Host ""
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
#endregion
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
<#
|
|
3
|
+
.SYNOPSIS
|
|
4
|
+
Adds tasks to the current SEDD migration
|
|
5
|
+
.PARAMETER Branch
|
|
6
|
+
Feature branch name (optional, auto-detected)
|
|
7
|
+
.PARAMETER Tasks
|
|
8
|
+
JSON array of tasks to add
|
|
9
|
+
.PARAMETER MigrationId
|
|
10
|
+
Specific migration ID (optional, uses current)
|
|
11
|
+
.EXAMPLE
|
|
12
|
+
./sedd-tasks.ps1 -Tasks '[{"story":"US1","description":"Implement feature"}]'
|
|
13
|
+
#>
|
|
14
|
+
|
|
15
|
+
param(
|
|
16
|
+
[Parameter(Mandatory = $false)]
|
|
17
|
+
[string]$Branch = "",
|
|
18
|
+
|
|
19
|
+
[Parameter(Mandatory = $false)]
|
|
20
|
+
[string]$Tasks = "[]",
|
|
21
|
+
|
|
22
|
+
[Parameter(Mandatory = $false)]
|
|
23
|
+
[string]$MigrationId = ""
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
$ErrorActionPreference = 'Stop'
|
|
27
|
+
|
|
28
|
+
#region Config
|
|
29
|
+
|
|
30
|
+
function Get-SeddConfig {
|
|
31
|
+
$configPath = Join-Path (Get-Location) 'sedd.config.json'
|
|
32
|
+
if (Test-Path $configPath) {
|
|
33
|
+
try {
|
|
34
|
+
$config = Get-Content $configPath -Raw | ConvertFrom-Json -AsHashtable
|
|
35
|
+
return @{ specsDir = if ($config.specsDir) { $config.specsDir } else { '.sedd' } }
|
|
36
|
+
}
|
|
37
|
+
catch { }
|
|
38
|
+
}
|
|
39
|
+
return @{ specsDir = '.sedd' }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function Get-CurrentBranch {
|
|
43
|
+
try { return (git rev-parse --abbrev-ref HEAD 2>$null).Trim() }
|
|
44
|
+
catch { return '' }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function Get-NextTaskNumber {
|
|
48
|
+
param([string]$Content, [string]$MigId)
|
|
49
|
+
|
|
50
|
+
$pattern = "T$MigId-(\d{3})"
|
|
51
|
+
$matches = [regex]::Matches($Content, $pattern)
|
|
52
|
+
|
|
53
|
+
if ($matches.Count -eq 0) { return 1 }
|
|
54
|
+
|
|
55
|
+
$maxNum = 0
|
|
56
|
+
foreach ($m in $matches) {
|
|
57
|
+
$num = [int]$m.Groups[1].Value
|
|
58
|
+
if ($num -gt $maxNum) { $maxNum = $num }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return $maxNum + 1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#endregion
|
|
65
|
+
|
|
66
|
+
#region Main
|
|
67
|
+
|
|
68
|
+
$config = Get-SeddConfig
|
|
69
|
+
$specsDir = $config.specsDir
|
|
70
|
+
|
|
71
|
+
if (-not $Branch) { $Branch = Get-CurrentBranch }
|
|
72
|
+
|
|
73
|
+
if (-not ($Branch -match '^\d{3}-')) {
|
|
74
|
+
Write-Host "Error: Not on a feature branch" -ForegroundColor Red
|
|
75
|
+
exit 1
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# Find feature directory
|
|
79
|
+
$featureDir = Join-Path (Get-Location) "$specsDir/$Branch"
|
|
80
|
+
if (-not (Test-Path $featureDir)) {
|
|
81
|
+
$featureDir = Join-Path (Get-Location) "specs/$Branch"
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (-not (Test-Path $featureDir)) {
|
|
85
|
+
Write-Host "Error: Feature not found: $Branch" -ForegroundColor Red
|
|
86
|
+
exit 1
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Load meta
|
|
90
|
+
$metaPath = Join-Path $featureDir '_meta.json'
|
|
91
|
+
if (-not (Test-Path $metaPath)) {
|
|
92
|
+
Write-Host "Error: _meta.json not found" -ForegroundColor Red
|
|
93
|
+
exit 1
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
$meta = Get-Content $metaPath -Raw | ConvertFrom-Json -AsHashtable
|
|
97
|
+
|
|
98
|
+
# Get migration
|
|
99
|
+
$migId = if ($MigrationId) { $MigrationId } else { $meta.currentMigration }
|
|
100
|
+
|
|
101
|
+
if (-not $migId) {
|
|
102
|
+
Write-Host "Error: No current migration. Run /sedd.clarify first." -ForegroundColor Red
|
|
103
|
+
exit 1
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
$migInfo = $meta.migrations[$migId]
|
|
107
|
+
if (-not $migInfo) {
|
|
108
|
+
Write-Host "Error: Migration $migId not found" -ForegroundColor Red
|
|
109
|
+
exit 1
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
$tasksFile = Join-Path $featureDir "$($migInfo.folder)/tasks.md"
|
|
113
|
+
if (-not (Test-Path $tasksFile)) {
|
|
114
|
+
Write-Host "Error: tasks.md not found for migration $migId" -ForegroundColor Red
|
|
115
|
+
exit 1
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# Parse tasks
|
|
119
|
+
$taskList = @()
|
|
120
|
+
try {
|
|
121
|
+
$taskList = $Tasks | ConvertFrom-Json
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
Write-Host "Error: Invalid tasks JSON" -ForegroundColor Red
|
|
125
|
+
exit 1
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if ($taskList.Count -eq 0) {
|
|
129
|
+
Write-Host "No tasks provided" -ForegroundColor Yellow
|
|
130
|
+
exit 0
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
# Read current content
|
|
134
|
+
$content = Get-Content $tasksFile -Raw
|
|
135
|
+
$nextNum = Get-NextTaskNumber -Content $content -MigId $migId
|
|
136
|
+
|
|
137
|
+
# Build new tasks
|
|
138
|
+
$newTasks = @()
|
|
139
|
+
foreach ($task in $taskList) {
|
|
140
|
+
$taskId = "T$migId-" + $nextNum.ToString().PadLeft(3, '0')
|
|
141
|
+
$story = if ($task.story) { "[$($task.story)] " } else { "" }
|
|
142
|
+
$line = "- [ ] $taskId ${story}$($task.description)"
|
|
143
|
+
$newTasks += $line
|
|
144
|
+
$nextNum++
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Append to file
|
|
148
|
+
$separator = "`n"
|
|
149
|
+
if (-not $content.EndsWith("`n")) { $separator = "`n`n" }
|
|
150
|
+
|
|
151
|
+
$newContent = $content + $separator + ($newTasks -join "`n") + "`n"
|
|
152
|
+
Set-Content -Path $tasksFile -Value $newContent -Encoding UTF8
|
|
153
|
+
|
|
154
|
+
Write-Host "Added $($taskList.Count) task(s) to migration $migId" -ForegroundColor Green
|
|
155
|
+
|
|
156
|
+
foreach ($t in $newTasks) {
|
|
157
|
+
Write-Host " $t" -ForegroundColor White
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# Update meta
|
|
161
|
+
$meta.migrations[$migId].tasksTotal = $meta.migrations[$migId].tasksTotal + $taskList.Count
|
|
162
|
+
$meta.migrations[$migId].status = 'in-progress'
|
|
163
|
+
Set-Content -Path $metaPath -Value ($meta | ConvertTo-Json -Depth 10) -Encoding UTF8
|
|
164
|
+
|
|
165
|
+
# Output JSON
|
|
166
|
+
$output = @{
|
|
167
|
+
success = $true
|
|
168
|
+
migrationId = $migId
|
|
169
|
+
tasksAdded = $taskList.Count
|
|
170
|
+
totalTasks = $meta.migrations[$migId].tasksTotal
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
Write-Output "---SEDD-OUTPUT---"
|
|
174
|
+
Write-Output ($output | ConvertTo-Json -Compress)
|
|
175
|
+
|
|
176
|
+
#endregion
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Clarification - Migration {{MIGRATION_ID}}
|
|
2
|
+
|
|
3
|
+
> Timestamp: {{TIMESTAMP}}
|
|
4
|
+
> Parent: {{PARENT_MIGRATION}}
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Brief description of what was clarified in this migration.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Expected Outcome
|
|
13
|
+
|
|
14
|
+
> What do you expect to achieve with this clarification?
|
|
15
|
+
|
|
16
|
+
[User's expected outcome]
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Questions
|
|
21
|
+
|
|
22
|
+
### Q1: [Question Title]
|
|
23
|
+
|
|
24
|
+
**Impact:** High | Medium | Low
|
|
25
|
+
**Area:** Functional Scope | Domain Model | UX Flow | Non-Functional | Integration | Edge Cases
|
|
26
|
+
|
|
27
|
+
[Question description]
|
|
28
|
+
|
|
29
|
+
**Options:**
|
|
30
|
+
A) Option A description
|
|
31
|
+
B) Option B description
|
|
32
|
+
C) Option C description
|
|
33
|
+
|
|
34
|
+
**Answer:** [Selected option or custom answer]
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### Q2: [Question Title]
|
|
39
|
+
|
|
40
|
+
**Impact:** High | Medium | Low
|
|
41
|
+
**Area:** [Area]
|
|
42
|
+
|
|
43
|
+
[Question description]
|
|
44
|
+
|
|
45
|
+
**Options:**
|
|
46
|
+
A) Option A
|
|
47
|
+
B) Option B
|
|
48
|
+
|
|
49
|
+
**Answer:** [Answer]
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Summary
|
|
54
|
+
|
|
55
|
+
| Question | Area | Answer |
|
|
56
|
+
|----------|------|--------|
|
|
57
|
+
| Q1 | [Area] | [Brief answer] |
|
|
58
|
+
| Q2 | [Area] | [Brief answer] |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Related
|
|
63
|
+
|
|
64
|
+
- **Decisions:** See `decisions.md` in this migration
|
|
65
|
+
- **Tasks:** See `tasks.md` in this migration
|
|
66
|
+
- **Parent Migration:** {{PARENT_MIGRATION}}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./sedd.schema.json",
|
|
3
|
+
"specsDir": ".sedd",
|
|
4
|
+
"branchPattern": "{{id}}-{{name}}",
|
|
5
|
+
"autoSplit": {
|
|
6
|
+
"enabled": true,
|
|
7
|
+
"maxLines": 400
|
|
8
|
+
},
|
|
9
|
+
"hooks": {
|
|
10
|
+
"assertive": true,
|
|
11
|
+
"skills": ["langchain-expert", "architecture-mapper", "defect-analyzer"],
|
|
12
|
+
"checkOnlyCurrentMigration": true,
|
|
13
|
+
"showSyncWarnings": true,
|
|
14
|
+
"blockOnSyncError": false
|
|
15
|
+
},
|
|
16
|
+
"commit": {
|
|
17
|
+
"askBeforeCommit": true,
|
|
18
|
+
"messagePattern": "{{type}}({{id}}): {{message}}"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Decisions - Migration {{MIGRATION_ID}}
|
|
2
|
+
|
|
3
|
+
> Timestamp: {{TIMESTAMP}}
|
|
4
|
+
> Parent: {{PARENT_MIGRATION}}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Decisions made based on clarification questions in this migration.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Decision Records
|
|
13
|
+
|
|
14
|
+
### D{{MIGRATION_ID}}-001: [Decision Title]
|
|
15
|
+
|
|
16
|
+
**Question:** Q1
|
|
17
|
+
**Answer:** [Selected option]
|
|
18
|
+
|
|
19
|
+
**Decision:**
|
|
20
|
+
[What was decided and why]
|
|
21
|
+
|
|
22
|
+
**Impact:**
|
|
23
|
+
- Impact item 1
|
|
24
|
+
- Impact item 2
|
|
25
|
+
- Impact item 3
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
### D{{MIGRATION_ID}}-002: [Decision Title]
|
|
30
|
+
|
|
31
|
+
**Question:** Q2
|
|
32
|
+
**Answer:** [Selected option]
|
|
33
|
+
|
|
34
|
+
**Decision:**
|
|
35
|
+
[What was decided and why]
|
|
36
|
+
|
|
37
|
+
**Impact:**
|
|
38
|
+
- Impact item 1
|
|
39
|
+
- Impact item 2
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Decision Matrix
|
|
44
|
+
|
|
45
|
+
| ID | Question | Decision | Impact |
|
|
46
|
+
|----|----------|----------|--------|
|
|
47
|
+
| D{{MIGRATION_ID}}-001 | Q1 | [Brief] | High |
|
|
48
|
+
| D{{MIGRATION_ID}}-002 | Q2 | [Brief] | Medium |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Related
|
|
53
|
+
|
|
54
|
+
- **Clarifications:** See `clarify.md` in this migration
|
|
55
|
+
- **Tasks:** See `tasks.md` in this migration
|
|
56
|
+
- **Spec:** See `spec.md` in feature root
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript Interfaces for {{FEATURE_NAME}}
|
|
3
|
+
*
|
|
4
|
+
* Feature ID: {{FEATURE_ID}}
|
|
5
|
+
* Generated: {{TIMESTAMP}}
|
|
6
|
+
*
|
|
7
|
+
* These interfaces will be converted to Zod schemas during implementation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Enums
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
export enum Status {
|
|
15
|
+
DRAFT = 'draft',
|
|
16
|
+
ACTIVE = 'active',
|
|
17
|
+
COMPLETED = 'completed',
|
|
18
|
+
ARCHIVED = 'archived',
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Value Objects (Immutable)
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
export interface Address {
|
|
26
|
+
readonly street: string;
|
|
27
|
+
readonly city: string;
|
|
28
|
+
readonly country: string;
|
|
29
|
+
readonly postalCode: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Entities
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
export interface Entity1 {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
status: Status;
|
|
40
|
+
createdAt: Date;
|
|
41
|
+
updatedAt: Date;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Entity2 {
|
|
45
|
+
id: string;
|
|
46
|
+
entity1Id: string;
|
|
47
|
+
value: string;
|
|
48
|
+
metadata?: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// Aggregates
|
|
53
|
+
// ============================================================================
|
|
54
|
+
|
|
55
|
+
export interface Aggregate1 {
|
|
56
|
+
root: Entity1;
|
|
57
|
+
children: Entity2[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// DTOs (Data Transfer Objects)
|
|
62
|
+
// ============================================================================
|
|
63
|
+
|
|
64
|
+
export interface CreateEntity1Input {
|
|
65
|
+
name: string;
|
|
66
|
+
status?: Status;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface UpdateEntity1Input {
|
|
70
|
+
name?: string;
|
|
71
|
+
status?: Status;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface Entity1Output {
|
|
75
|
+
id: string;
|
|
76
|
+
name: string;
|
|
77
|
+
status: Status;
|
|
78
|
+
createdAt: string;
|
|
79
|
+
updatedAt: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// API Types
|
|
84
|
+
// ============================================================================
|
|
85
|
+
|
|
86
|
+
export interface PaginationParams {
|
|
87
|
+
page?: number;
|
|
88
|
+
limit?: number;
|
|
89
|
+
sortBy?: string;
|
|
90
|
+
sortOrder?: 'asc' | 'desc';
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface PaginatedResponse<T> {
|
|
94
|
+
data: T[];
|
|
95
|
+
total: number;
|
|
96
|
+
page: number;
|
|
97
|
+
limit: number;
|
|
98
|
+
hasMore: boolean;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ApiError {
|
|
102
|
+
code: string;
|
|
103
|
+
message: string;
|
|
104
|
+
details?: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================================================
|
|
108
|
+
// Event Types
|
|
109
|
+
// ============================================================================
|
|
110
|
+
|
|
111
|
+
export interface DomainEvent {
|
|
112
|
+
type: string;
|
|
113
|
+
aggregateId: string;
|
|
114
|
+
timestamp: Date;
|
|
115
|
+
payload: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface Entity1CreatedEvent extends DomainEvent {
|
|
119
|
+
type: 'entity1.created';
|
|
120
|
+
payload: {
|
|
121
|
+
entity: Entity1;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface Entity1UpdatedEvent extends DomainEvent {
|
|
126
|
+
type: 'entity1.updated';
|
|
127
|
+
payload: {
|
|
128
|
+
before: Partial<Entity1>;
|
|
129
|
+
after: Partial<Entity1>;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"featureId": "{{FEATURE_ID}}",
|
|
3
|
+
"featureName": "{{FEATURE_NAME}}",
|
|
4
|
+
"branch": "{{BRANCH_NAME}}",
|
|
5
|
+
"createdAt": "{{TIMESTAMP}}",
|
|
6
|
+
"specCreatedAt": "{{TIMESTAMP}}",
|
|
7
|
+
"currentMigration": null,
|
|
8
|
+
"migrations": {},
|
|
9
|
+
"splits": [],
|
|
10
|
+
"commits": [],
|
|
11
|
+
"expectation": null
|
|
12
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Implementation Progress
|
|
2
|
+
|
|
3
|
+
> Feature: {{FEATURE_NAME}}
|
|
4
|
+
> Last Updated: {{TIMESTAMP}}
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
| Migration | Total | Done | Progress |
|
|
9
|
+
|-----------|-------|------|----------|
|
|
10
|
+
| **Total** | **0** | **0** | **0%** |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Current Task
|
|
15
|
+
|
|
16
|
+
**None** - Ready to start implementation.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Task Log
|
|
21
|
+
|
|
22
|
+
### Migration {{MIGRATION_ID}}
|
|
23
|
+
|
|
24
|
+
- [ ] T{{MIGRATION_ID}}-001 [Started: --:--] [Foundation] Task description
|
|
25
|
+
- [ ] T{{MIGRATION_ID}}-002 [Foundation] Task description
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Completed Migrations
|
|
30
|
+
|
|
31
|
+
| Migration | Tasks | Completed At | Commit |
|
|
32
|
+
|-----------|-------|--------------|--------|
|
|
33
|
+
| - | - | - | - |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Session History
|
|
38
|
+
|
|
39
|
+
### {{DATE}}
|
|
40
|
+
|
|
41
|
+
**Migration:** {{MIGRATION_ID}}
|
|
42
|
+
**Tasks Completed:** 0
|
|
43
|
+
|
|
44
|
+
**Notes:**
|
|
45
|
+
- Session notes here
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Blocked Tasks
|
|
50
|
+
|
|
51
|
+
| Task | Migration | Blocked By | Notes |
|
|
52
|
+
|------|-----------|------------|-------|
|
|
53
|
+
| - | - | - | - |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Test Results
|
|
58
|
+
|
|
59
|
+
| Migration | Unit | Integration | E2E |
|
|
60
|
+
|-----------|------|-------------|-----|
|
|
61
|
+
| {{MIGRATION_ID}} | 0/0 | 0/0 | 0/0 |
|