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,197 @@
|
|
|
1
|
+
import { existsSync, readdirSync, mkdirSync, renameSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { MigrationManager } from '../core/migration-manager.js';
|
|
5
|
+
import { ChangelogManager } from '../core/changelog.js';
|
|
6
|
+
import { formatTimestamp, getSessionTimestamp } from '../core/timestamps.js';
|
|
7
|
+
import { loadConfig, getMigrationFolder } from '../types/index.js';
|
|
8
|
+
export async function migrate(featureDir, options = {}) {
|
|
9
|
+
const cwd = process.cwd();
|
|
10
|
+
const config = loadConfig(cwd);
|
|
11
|
+
const specsDir = join(cwd, config.specsDir);
|
|
12
|
+
if (!existsSync(specsDir)) {
|
|
13
|
+
console.log(chalk.red(`\nā No ${config.specsDir}/ directory found.\n`));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const featuresToMigrate = [];
|
|
17
|
+
if (options.all) {
|
|
18
|
+
const features = readdirSync(specsDir, { withFileTypes: true })
|
|
19
|
+
.filter((d) => d.isDirectory() && /^\d{3}-/.test(d.name))
|
|
20
|
+
.map((d) => d.name);
|
|
21
|
+
for (const feature of features) {
|
|
22
|
+
const fDir = join(specsDir, feature);
|
|
23
|
+
const metaPath = join(fDir, '_meta.json');
|
|
24
|
+
if (!existsSync(metaPath) && needsMigration(fDir)) {
|
|
25
|
+
featuresToMigrate.push(feature);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (featureDir) {
|
|
30
|
+
const fDir = join(specsDir, featureDir);
|
|
31
|
+
if (existsSync(fDir) && needsMigration(fDir)) {
|
|
32
|
+
featuresToMigrate.push(featureDir);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.log(chalk.yellow(`\nā ${featureDir} does not need migration or doesn't exist.\n`));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log(chalk.yellow('\nā Please specify a feature directory or use --all.\n'));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (featuresToMigrate.length === 0) {
|
|
44
|
+
console.log(chalk.green('\n⨠No features need migration.\n'));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.log(chalk.blue(`\nš Migrating ${featuresToMigrate.length} feature(s)...\n`));
|
|
48
|
+
for (const feature of featuresToMigrate) {
|
|
49
|
+
await migrateFeature(join(specsDir, feature), feature, options.dryRun ?? false);
|
|
50
|
+
}
|
|
51
|
+
console.log(chalk.green('\n⨠Migration complete!\n'));
|
|
52
|
+
}
|
|
53
|
+
function needsMigration(featureDir) {
|
|
54
|
+
const metaPath = join(featureDir, '_meta.json');
|
|
55
|
+
if (existsSync(metaPath)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return (existsSync(join(featureDir, 'spec.md')) ||
|
|
59
|
+
existsSync(join(featureDir, 'tasks.md')) ||
|
|
60
|
+
existsSync(join(featureDir, 'plan.md')));
|
|
61
|
+
}
|
|
62
|
+
async function migrateFeature(featureDir, featureName, dryRun) {
|
|
63
|
+
console.log(chalk.cyan(`š¦ ${featureName}`));
|
|
64
|
+
const match = featureName.match(/^(\d{3})-(.+)$/);
|
|
65
|
+
const featureId = match ? match[1] : '000';
|
|
66
|
+
const featureShortName = match ? match[2] : featureName;
|
|
67
|
+
if (dryRun) {
|
|
68
|
+
console.log(chalk.gray(' [dry-run] Would create:'));
|
|
69
|
+
console.log(chalk.gray(' - _meta.json'));
|
|
70
|
+
console.log(chalk.gray(' - CHANGELOG.md'));
|
|
71
|
+
console.log(chalk.gray(' - 001_timestamp/ (initial migration)'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const now = formatTimestamp();
|
|
75
|
+
const sessionTimestamp = getSessionTimestamp();
|
|
76
|
+
const migrationId = '001';
|
|
77
|
+
const migrationFolder = getMigrationFolder(migrationId, sessionTimestamp);
|
|
78
|
+
const migrationDir = join(featureDir, migrationFolder);
|
|
79
|
+
mkdirSync(migrationDir, { recursive: true });
|
|
80
|
+
const specPath = join(featureDir, 'spec.md');
|
|
81
|
+
if (!existsSync(specPath)) {
|
|
82
|
+
const defaultSpec = `# ${featureShortName}\n\nMigrated from legacy structure.\n`;
|
|
83
|
+
writeFileSync(specPath, defaultSpec, 'utf-8');
|
|
84
|
+
console.log(chalk.green(' ā'), 'Created spec.md');
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.log(chalk.green(' ā'), 'spec.md exists');
|
|
88
|
+
}
|
|
89
|
+
const planPath = join(featureDir, 'plan.md');
|
|
90
|
+
if (existsSync(planPath)) {
|
|
91
|
+
const planContent = readFileSync(planPath, 'utf-8');
|
|
92
|
+
const decisionsContent = extractDecisions(planContent);
|
|
93
|
+
writeFileSync(join(migrationDir, 'decisions.md'), decisionsContent, 'utf-8');
|
|
94
|
+
renameSync(planPath, join(migrationDir, 'plan-archive.md'));
|
|
95
|
+
console.log(chalk.green(' ā'), `Moved plan.md ā ${migrationFolder}/plan-archive.md`);
|
|
96
|
+
console.log(chalk.green(' ā'), `Created ${migrationFolder}/decisions.md`);
|
|
97
|
+
}
|
|
98
|
+
const tasksPath = join(featureDir, 'tasks.md');
|
|
99
|
+
let tasksTotal = 0;
|
|
100
|
+
let tasksCompleted = 0;
|
|
101
|
+
if (existsSync(tasksPath)) {
|
|
102
|
+
const tasksContent = readFileSync(tasksPath, 'utf-8');
|
|
103
|
+
const { newContent, total, completed } = convertTaskIds(tasksContent, migrationId);
|
|
104
|
+
tasksTotal = total;
|
|
105
|
+
tasksCompleted = completed;
|
|
106
|
+
writeFileSync(join(migrationDir, 'tasks.md'), newContent, 'utf-8');
|
|
107
|
+
renameSync(tasksPath, join(featureDir, 'tasks-legacy.md'));
|
|
108
|
+
console.log(chalk.green(' ā'), `Converted tasks.md ā ${migrationFolder}/tasks.md`);
|
|
109
|
+
}
|
|
110
|
+
const researchPath = join(featureDir, 'research.md');
|
|
111
|
+
if (existsSync(researchPath)) {
|
|
112
|
+
renameSync(researchPath, join(migrationDir, 'research.md'));
|
|
113
|
+
console.log(chalk.green(' ā'), `Moved research.md ā ${migrationFolder}/`);
|
|
114
|
+
}
|
|
115
|
+
const mm = new MigrationManager(featureDir);
|
|
116
|
+
mm.initFeature(featureId, featureShortName, featureName);
|
|
117
|
+
const meta = mm.loadMeta();
|
|
118
|
+
if (meta) {
|
|
119
|
+
meta.currentMigration = migrationId;
|
|
120
|
+
meta.migrations[migrationId] = {
|
|
121
|
+
id: migrationId,
|
|
122
|
+
timestamp: sessionTimestamp,
|
|
123
|
+
folder: migrationFolder,
|
|
124
|
+
status: tasksCompleted >= tasksTotal && tasksTotal > 0 ? 'completed' : 'in-progress',
|
|
125
|
+
tasksTotal,
|
|
126
|
+
tasksCompleted,
|
|
127
|
+
createdAt: now,
|
|
128
|
+
completedAt: tasksCompleted >= tasksTotal && tasksTotal > 0 ? now : undefined,
|
|
129
|
+
};
|
|
130
|
+
writeFileSync(join(featureDir, '_meta.json'), JSON.stringify(meta, null, 2), 'utf-8');
|
|
131
|
+
}
|
|
132
|
+
console.log(chalk.green(' ā'), 'Created _meta.json');
|
|
133
|
+
const changelog = new ChangelogManager(featureDir);
|
|
134
|
+
changelog.init(featureId, featureShortName);
|
|
135
|
+
changelog.addEntry('Migration', [
|
|
136
|
+
'Migrated from legacy speckit structure to SEDD migration-based structure',
|
|
137
|
+
`Initial migration: ${migrationId}`,
|
|
138
|
+
`Tasks: ${tasksCompleted}/${tasksTotal} completed`,
|
|
139
|
+
]);
|
|
140
|
+
console.log(chalk.green(' ā'), 'Created CHANGELOG.md');
|
|
141
|
+
console.log();
|
|
142
|
+
}
|
|
143
|
+
function extractDecisions(planContent) {
|
|
144
|
+
const lines = planContent.split('\n');
|
|
145
|
+
const decisions = [];
|
|
146
|
+
let inDecisionSection = false;
|
|
147
|
+
for (const line of lines) {
|
|
148
|
+
if (line.match(/^##.*decision|choice|approach/i)) {
|
|
149
|
+
inDecisionSection = true;
|
|
150
|
+
}
|
|
151
|
+
else if (line.match(/^##/)) {
|
|
152
|
+
inDecisionSection = false;
|
|
153
|
+
}
|
|
154
|
+
if (inDecisionSection && line.trim()) {
|
|
155
|
+
decisions.push(line);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
let content = '# Decisions\n\n';
|
|
159
|
+
content += 'Decisions extracted during migration.\n\n';
|
|
160
|
+
if (decisions.length > 0) {
|
|
161
|
+
content += decisions.join('\n') + '\n';
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
content += 'No specific decisions extracted. Review plan-archive.md for details.\n';
|
|
165
|
+
}
|
|
166
|
+
return content;
|
|
167
|
+
}
|
|
168
|
+
function convertTaskIds(content, migrationId) {
|
|
169
|
+
const lines = content.split('\n');
|
|
170
|
+
const newLines = [];
|
|
171
|
+
let taskNum = 0;
|
|
172
|
+
let completed = 0;
|
|
173
|
+
for (const line of lines) {
|
|
174
|
+
const pendingMatch = line.match(/^(\s*-\s*\[\s*\])\s*(T\d+)?\s*(.+)$/);
|
|
175
|
+
const completedMatch = line.match(/^(\s*-\s*\[x\])\s*(T\d+)?\s*(.+)$/i);
|
|
176
|
+
if (pendingMatch) {
|
|
177
|
+
taskNum++;
|
|
178
|
+
const taskId = `T${migrationId}-${taskNum.toString().padStart(3, '0')}`;
|
|
179
|
+
newLines.push(`${pendingMatch[1]} ${taskId} ${pendingMatch[3]}`);
|
|
180
|
+
}
|
|
181
|
+
else if (completedMatch) {
|
|
182
|
+
taskNum++;
|
|
183
|
+
completed++;
|
|
184
|
+
const taskId = `T${migrationId}-${taskNum.toString().padStart(3, '0')}`;
|
|
185
|
+
newLines.push(`${completedMatch[1]} ${taskId} ${completedMatch[3]}`);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
newLines.push(line);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
newContent: newLines.join('\n'),
|
|
193
|
+
total: taskNum,
|
|
194
|
+
completed,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/cli/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specify.d.ts","sourceRoot":"","sources":["../../src/cli/specify.ts"],"names":[],"mappings":"AAKA,UAAU,cAAc;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,OAAO,CAC3B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA0If"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { loadConfig } from '../types/index.js';
|
|
5
|
+
export async function specify(featureId, featureName, options = {}) {
|
|
6
|
+
const cwd = process.cwd();
|
|
7
|
+
const config = loadConfig(cwd);
|
|
8
|
+
const branchName = `${featureId}-${featureName}`;
|
|
9
|
+
const featureDir = join(cwd, config.specsDir, branchName);
|
|
10
|
+
if (existsSync(featureDir)) {
|
|
11
|
+
console.log(chalk.yellow(`Feature already exists: ${featureDir}`));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
mkdirSync(featureDir, { recursive: true });
|
|
15
|
+
console.log(chalk.green('ā'), `Created: ${featureDir}`);
|
|
16
|
+
const now = new Date().toISOString();
|
|
17
|
+
const description = options.description || '';
|
|
18
|
+
const expectation = options.expectation || '';
|
|
19
|
+
const meta = {
|
|
20
|
+
featureId,
|
|
21
|
+
featureName,
|
|
22
|
+
branch: branchName,
|
|
23
|
+
createdAt: now,
|
|
24
|
+
specCreatedAt: now,
|
|
25
|
+
currentMigration: null,
|
|
26
|
+
migrations: {},
|
|
27
|
+
splits: [],
|
|
28
|
+
commits: [],
|
|
29
|
+
expectation: expectation || undefined,
|
|
30
|
+
};
|
|
31
|
+
writeFileSync(join(featureDir, '_meta.json'), JSON.stringify(meta, null, 2), 'utf-8');
|
|
32
|
+
console.log(chalk.green('ā'), 'Created: _meta.json');
|
|
33
|
+
const expectationSection = expectation
|
|
34
|
+
? `## Expectation
|
|
35
|
+
|
|
36
|
+
> ${expectation}
|
|
37
|
+
|
|
38
|
+
`
|
|
39
|
+
: `## Expectation
|
|
40
|
+
|
|
41
|
+
> What do you expect as the final outcome of this feature?
|
|
42
|
+
|
|
43
|
+
[Define your expectation here]
|
|
44
|
+
|
|
45
|
+
`;
|
|
46
|
+
const specContent = `# ${featureName}
|
|
47
|
+
|
|
48
|
+
## Overview
|
|
49
|
+
|
|
50
|
+
${description}
|
|
51
|
+
|
|
52
|
+
${expectationSection}## Goals
|
|
53
|
+
|
|
54
|
+
- [ ] Goal 1
|
|
55
|
+
- [ ] Goal 2
|
|
56
|
+
|
|
57
|
+
## Non-Goals
|
|
58
|
+
|
|
59
|
+
- Out of scope item 1
|
|
60
|
+
|
|
61
|
+
## User Stories
|
|
62
|
+
|
|
63
|
+
### US1: [Story Title]
|
|
64
|
+
|
|
65
|
+
**As a** [user type]
|
|
66
|
+
**I want** [action]
|
|
67
|
+
**So that** [benefit]
|
|
68
|
+
|
|
69
|
+
#### Acceptance Criteria
|
|
70
|
+
|
|
71
|
+
- [ ] Criterion 1
|
|
72
|
+
- [ ] Criterion 2
|
|
73
|
+
|
|
74
|
+
## Technical Requirements
|
|
75
|
+
|
|
76
|
+
### Architecture
|
|
77
|
+
|
|
78
|
+
[Describe the technical approach]
|
|
79
|
+
|
|
80
|
+
### Dependencies
|
|
81
|
+
|
|
82
|
+
- Dependency 1
|
|
83
|
+
- Dependency 2
|
|
84
|
+
|
|
85
|
+
## UI/UX (if applicable)
|
|
86
|
+
|
|
87
|
+
[ASCII mockups or description]
|
|
88
|
+
|
|
89
|
+
## Open Questions
|
|
90
|
+
|
|
91
|
+
- [ ] Question 1?
|
|
92
|
+
- [ ] Question 2?
|
|
93
|
+
`;
|
|
94
|
+
writeFileSync(join(featureDir, 'spec.md'), specContent, 'utf-8');
|
|
95
|
+
console.log(chalk.green('ā'), 'Created: spec.md');
|
|
96
|
+
const interfacesContent = `/**
|
|
97
|
+
* TypeScript interfaces for ${featureName}
|
|
98
|
+
* Feature ID: ${featureId}
|
|
99
|
+
*
|
|
100
|
+
* Define types here FIRST, then implement with Zod schemas later.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
// Example interface - replace with actual types
|
|
104
|
+
export interface Example {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
createdAt: Date;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Add your interfaces below
|
|
111
|
+
`;
|
|
112
|
+
writeFileSync(join(featureDir, 'interfaces.ts'), interfacesContent, 'utf-8');
|
|
113
|
+
console.log(chalk.green('ā'), 'Created: interfaces.ts');
|
|
114
|
+
const changelogContent = `# Changelog - ${featureName}
|
|
115
|
+
|
|
116
|
+
All notable changes to this feature will be documented in this file.
|
|
117
|
+
|
|
118
|
+
## [Unreleased]
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
- Initial feature specification created
|
|
122
|
+
`;
|
|
123
|
+
writeFileSync(join(featureDir, 'CHANGELOG.md'), changelogContent, 'utf-8');
|
|
124
|
+
console.log(chalk.green('ā'), 'Created: CHANGELOG.md');
|
|
125
|
+
console.log(chalk.cyan('\n⨠Feature structure created successfully!'));
|
|
126
|
+
console.log(chalk.cyan('Next steps:'));
|
|
127
|
+
console.log(' 1. Edit spec.md with detailed requirements');
|
|
128
|
+
console.log(' 2. Define interfaces in interfaces.ts');
|
|
129
|
+
console.log(' 3. Run /sedd.clarify to start first migration');
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=specify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specify.js","sourceRoot":"","sources":["../../src/cli/specify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"AAOA,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4HvE"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { GitOperations } from '../utils/git.js';
|
|
5
|
+
import { MigrationManager } from '../core/migration-manager.js';
|
|
6
|
+
import { loadConfig } from '../types/index.js';
|
|
7
|
+
export async function status(options = {}) {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const git = new GitOperations(cwd);
|
|
10
|
+
const config = loadConfig(cwd);
|
|
11
|
+
const specsDir = join(cwd, config.specsDir);
|
|
12
|
+
if (!existsSync(specsDir)) {
|
|
13
|
+
if (options.json) {
|
|
14
|
+
console.log(JSON.stringify({ error: 'No specs directory found' }));
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log(chalk.yellow(`\nā No ${config.specsDir}/ directory found. Run "sedd init" first.\n`));
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let currentFeature = null;
|
|
22
|
+
// Try to detect feature from current branch
|
|
23
|
+
if (git.hasGit()) {
|
|
24
|
+
const branch = git.getCurrentBranch();
|
|
25
|
+
if (git.isFeatureBranch(branch)) {
|
|
26
|
+
const featureDir = join(specsDir, branch);
|
|
27
|
+
if (existsSync(featureDir)) {
|
|
28
|
+
currentFeature = branch;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Fallback: get most recent feature
|
|
33
|
+
if (!currentFeature) {
|
|
34
|
+
const features = readdirSync(specsDir, { withFileTypes: true })
|
|
35
|
+
.filter((d) => d.isDirectory() && /^\d{3}-/.test(d.name))
|
|
36
|
+
.map((d) => d.name)
|
|
37
|
+
.sort()
|
|
38
|
+
.reverse();
|
|
39
|
+
if (features.length > 0) {
|
|
40
|
+
currentFeature = features[0];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!currentFeature) {
|
|
44
|
+
if (options.json) {
|
|
45
|
+
console.log(JSON.stringify({ error: 'No features found' }));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.log(chalk.yellow('\nā No features found. Use /sedd.specify to create one.\n'));
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const featureDir = join(specsDir, currentFeature);
|
|
53
|
+
const mm = new MigrationManager(featureDir);
|
|
54
|
+
const meta = mm.loadMeta();
|
|
55
|
+
if (options.json) {
|
|
56
|
+
if (meta) {
|
|
57
|
+
const status = {
|
|
58
|
+
featureId: meta.featureId,
|
|
59
|
+
featureName: meta.featureName,
|
|
60
|
+
branch: meta.branch,
|
|
61
|
+
currentMigration: meta.currentMigration,
|
|
62
|
+
migrations: meta.migrations,
|
|
63
|
+
commits: meta.commits.slice(-5),
|
|
64
|
+
};
|
|
65
|
+
console.log(JSON.stringify(status, null, 2));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
console.log(JSON.stringify({
|
|
69
|
+
feature: currentFeature,
|
|
70
|
+
status: 'legacy',
|
|
71
|
+
message: 'Uses old structure, needs migration',
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
console.log(chalk.blue(`\nš Feature Status: ${currentFeature}\n`));
|
|
77
|
+
if (!meta) {
|
|
78
|
+
console.log(chalk.yellow('ā This feature uses the old structure.'));
|
|
79
|
+
console.log(chalk.gray(` Run: sedd migrate ${currentFeature}`));
|
|
80
|
+
console.log();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
console.log(chalk.gray('Feature ID:'), meta.featureId);
|
|
84
|
+
console.log(chalk.gray('Feature Name:'), meta.featureName);
|
|
85
|
+
console.log(chalk.gray('Branch:'), meta.branch);
|
|
86
|
+
console.log(chalk.gray('Current Migration:'), chalk.cyan(meta.currentMigration || 'none'));
|
|
87
|
+
console.log();
|
|
88
|
+
// Show migrations
|
|
89
|
+
const migrations = Object.values(meta.migrations);
|
|
90
|
+
if (migrations.length > 0) {
|
|
91
|
+
console.log(chalk.gray('Migrations:'));
|
|
92
|
+
for (const mig of migrations) {
|
|
93
|
+
let icon = 'ā';
|
|
94
|
+
let color = chalk.gray;
|
|
95
|
+
if (mig.status === 'completed') {
|
|
96
|
+
icon = 'ā';
|
|
97
|
+
color = chalk.green;
|
|
98
|
+
}
|
|
99
|
+
else if (mig.status === 'in-progress') {
|
|
100
|
+
icon = 'ā';
|
|
101
|
+
color = chalk.cyan;
|
|
102
|
+
}
|
|
103
|
+
const progress = `${mig.tasksCompleted}/${mig.tasksTotal}`;
|
|
104
|
+
console.log(` ${color(icon)} ${mig.id} (${mig.timestamp}) - ${progress} tasks`);
|
|
105
|
+
}
|
|
106
|
+
console.log();
|
|
107
|
+
}
|
|
108
|
+
// Show recent commits
|
|
109
|
+
if (meta.commits.length > 0) {
|
|
110
|
+
console.log(chalk.gray('Recent Commits:'));
|
|
111
|
+
const recentCommits = meta.commits.slice(-3);
|
|
112
|
+
for (const commit of recentCommits) {
|
|
113
|
+
console.log(chalk.gray(` ${commit.hash}`), commit.message);
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/cli/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/cli/tasks.ts"],"names":[],"mappings":"AAWA,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAeD,wBAAsB,QAAQ,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CA+Ff;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FhE"}
|