sdd-mcp-server 2.1.0 → 2.2.1
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 +53 -38
- package/atomicWrite.js +86 -0
- package/dist/adapters/cli/SDDToolAdapter.js +12 -2
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
- package/dist/cli/install-skills.d.ts +38 -2
- package/dist/cli/install-skills.js +226 -10
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/migrate-kiro.js +4 -4
- package/dist/cli/sdd-mcp-cli.d.ts +2 -1
- package/dist/cli/sdd-mcp-cli.js +21 -11
- package/dist/cli/sdd-mcp-cli.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/atomicWrite.d.ts +55 -0
- package/dist/utils/atomicWrite.js +84 -0
- package/dist/utils/atomicWrite.js.map +1 -0
- package/mcp-server.js +5 -4
- package/package.json +5 -3
- package/sdd-entry.js +31 -0
- package/skills/sdd-commit/SKILL.md +14 -0
- package/skills/sdd-design/SKILL.md +15 -0
- package/skills/sdd-implement/SKILL.md +15 -0
- package/skills/sdd-requirements/SKILL.md +9 -2
- package/skills/sdd-tasks/SKILL.md +14 -0
- package/steering/AGENTS.md +281 -0
- package/steering/commit.md +59 -0
- package/steering/linus-review.md +153 -0
- package/steering/owasp-top10-check.md +49 -0
- package/steering/principles.md +639 -0
- package/steering/tdd-guideline.md +324 -0
- package/dist/utils/sddPaths.d.ts +0 -69
- package/dist/utils/sddPaths.js +0 -138
- package/dist/utils/sddPaths.js.map +0 -1
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# Test-Driven Development (TDD) Guidelines
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
All new features and specifications MUST follow Test-Driven Development (TDD) methodology. This ensures code quality, maintainability, and adherence to requirements from the start.
|
|
6
|
+
|
|
7
|
+
## TDD Cycle: Red → Green → Refactor
|
|
8
|
+
|
|
9
|
+
### 1. RED Phase: Write Failing Tests First
|
|
10
|
+
**Goal**: Define expected behavior through tests before writing any implementation code.
|
|
11
|
+
|
|
12
|
+
**Process**:
|
|
13
|
+
1. Read and understand the requirement
|
|
14
|
+
2. Write a test that describes the expected behavior
|
|
15
|
+
3. Run the test and confirm it fails (RED)
|
|
16
|
+
4. Commit: `test: add failing test for [feature]`
|
|
17
|
+
|
|
18
|
+
**Example**:
|
|
19
|
+
```typescript
|
|
20
|
+
// ❌ Test fails because implementation doesn't exist yet
|
|
21
|
+
describe('UserService', () => {
|
|
22
|
+
it('should create user with valid email', async () => {
|
|
23
|
+
const result = await userService.create({ email: 'test@example.com' });
|
|
24
|
+
expect(result.success).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Test Requirements**:
|
|
30
|
+
- Test MUST fail initially (if it passes, you're not testing new functionality)
|
|
31
|
+
- Test MUST be specific and focused on ONE behavior
|
|
32
|
+
- Test name MUST clearly describe the expected behavior
|
|
33
|
+
- Test MUST use realistic test data
|
|
34
|
+
|
|
35
|
+
### 2. GREEN Phase: Write Minimal Code to Pass
|
|
36
|
+
**Goal**: Write the simplest code possible to make the test pass.
|
|
37
|
+
|
|
38
|
+
**Process**:
|
|
39
|
+
1. Write only enough code to make the failing test pass
|
|
40
|
+
2. Avoid premature optimization or extra features
|
|
41
|
+
3. Run tests and confirm they pass (GREEN)
|
|
42
|
+
4. Commit: `feat: implement [feature] to pass tests`
|
|
43
|
+
|
|
44
|
+
**Example**:
|
|
45
|
+
```typescript
|
|
46
|
+
// ✅ Minimal implementation to make test pass
|
|
47
|
+
class UserService {
|
|
48
|
+
async create(data: { email: string }) {
|
|
49
|
+
if (!data.email.includes('@')) {
|
|
50
|
+
return { success: false, error: 'Invalid email' };
|
|
51
|
+
}
|
|
52
|
+
return { success: true, user: { email: data.email } };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Implementation Requirements**:
|
|
58
|
+
- Code MUST make all tests pass
|
|
59
|
+
- Code SHOULD be minimal (no over-engineering)
|
|
60
|
+
- Code MUST be understandable and clear
|
|
61
|
+
- Add more tests if edge cases are discovered
|
|
62
|
+
|
|
63
|
+
### 3. REFACTOR Phase: Improve Code Quality
|
|
64
|
+
**Goal**: Improve code structure, readability, and performance while keeping tests green.
|
|
65
|
+
|
|
66
|
+
**Process**:
|
|
67
|
+
1. Review code for duplication, complexity, or unclear logic
|
|
68
|
+
2. Refactor while keeping tests passing
|
|
69
|
+
3. Run tests after each refactor to ensure nothing breaks
|
|
70
|
+
4. Commit: `refactor: improve [component] structure`
|
|
71
|
+
|
|
72
|
+
**Example**:
|
|
73
|
+
```typescript
|
|
74
|
+
// ✅ Refactored for better structure
|
|
75
|
+
class UserService {
|
|
76
|
+
async create(data: UserInput): Promise<Result<User>> {
|
|
77
|
+
const validation = this.validateEmail(data.email);
|
|
78
|
+
if (!validation.valid) {
|
|
79
|
+
return Result.failure(validation.error);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const user = await this.repository.save(data);
|
|
83
|
+
return Result.success(user);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private validateEmail(email: string): ValidationResult {
|
|
87
|
+
return EmailValidator.validate(email);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Refactoring Checklist**:
|
|
93
|
+
- [ ] Remove code duplication
|
|
94
|
+
- [ ] Extract methods for clarity
|
|
95
|
+
- [ ] Improve naming (variables, functions, classes)
|
|
96
|
+
- [ ] Optimize performance (if needed)
|
|
97
|
+
- [ ] Add inline documentation for complex logic
|
|
98
|
+
- [ ] All tests still pass
|
|
99
|
+
|
|
100
|
+
## Task Order for TDD Implementation
|
|
101
|
+
|
|
102
|
+
When generating tasks for new features, ALWAYS follow this order:
|
|
103
|
+
|
|
104
|
+
### Phase 1: Test Setup (RED)
|
|
105
|
+
```markdown
|
|
106
|
+
- [ ] 1. Set up test infrastructure
|
|
107
|
+
- Install/configure test framework (Jest, Mocha, pytest, JUnit, etc.)
|
|
108
|
+
- Create test directory structure
|
|
109
|
+
- Configure test runner and coverage tools
|
|
110
|
+
- _Requirements: NFR-3 (Quality Standards)_
|
|
111
|
+
|
|
112
|
+
- [ ] 2. Write failing tests for [Feature Name]
|
|
113
|
+
- Write unit tests for core functionality
|
|
114
|
+
- Write integration tests for system interactions
|
|
115
|
+
- Write edge case and error handling tests
|
|
116
|
+
- Confirm all tests fail (RED phase)
|
|
117
|
+
- _Requirements: FR-1 (Core Functionality)_
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Phase 2: Implementation (GREEN)
|
|
121
|
+
```markdown
|
|
122
|
+
- [ ] 3. Implement minimal code to pass tests
|
|
123
|
+
- Implement core feature logic to satisfy tests
|
|
124
|
+
- Add necessary dependencies and modules
|
|
125
|
+
- Ensure all tests pass (GREEN phase)
|
|
126
|
+
- _Requirements: FR-1, FR-2 (Technology Integration)_
|
|
127
|
+
|
|
128
|
+
- [ ] 4. Verify test coverage
|
|
129
|
+
- Run coverage report
|
|
130
|
+
- Ensure minimum 80% code coverage
|
|
131
|
+
- Add tests for uncovered branches
|
|
132
|
+
- _Requirements: NFR-3 (Quality Standards)_
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Phase 3: Refactoring (REFACTOR)
|
|
136
|
+
```markdown
|
|
137
|
+
- [ ] 5. Refactor for code quality
|
|
138
|
+
- Extract reusable components/functions
|
|
139
|
+
- Improve naming and code clarity
|
|
140
|
+
- Remove duplication (DRY principle)
|
|
141
|
+
- Apply design patterns where appropriate
|
|
142
|
+
- All tests must still pass
|
|
143
|
+
- _Requirements: NFR-3 (Maintainability)_
|
|
144
|
+
|
|
145
|
+
- [ ] 6. Code quality validation
|
|
146
|
+
- Run linter and fix issues
|
|
147
|
+
- Run type checker (if TypeScript/typed language)
|
|
148
|
+
- Apply Linus-style code review principles
|
|
149
|
+
- _Requirements: NFR-3 (Quality Standards)_
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Phase 4: Integration & Documentation
|
|
153
|
+
```markdown
|
|
154
|
+
- [ ] 7. Integration with existing system
|
|
155
|
+
- Integrate with build system
|
|
156
|
+
- Update configuration files
|
|
157
|
+
- Test in development environment
|
|
158
|
+
- _Requirements: FR-2, NFR-2 (Reliability)_
|
|
159
|
+
|
|
160
|
+
- [ ] 8. Documentation and deployment prep
|
|
161
|
+
- Update API documentation
|
|
162
|
+
- Add inline code comments for complex logic
|
|
163
|
+
- Update README/CHANGELOG if needed
|
|
164
|
+
- Prepare for deployment
|
|
165
|
+
- _Requirements: NFR-3 (Maintainability)_
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## TDD Best Practices
|
|
169
|
+
|
|
170
|
+
### Test Quality
|
|
171
|
+
1. **AAA Pattern**: Arrange, Act, Assert
|
|
172
|
+
```typescript
|
|
173
|
+
it('should validate email format', () => {
|
|
174
|
+
// Arrange: Set up test data
|
|
175
|
+
const email = 'invalid-email';
|
|
176
|
+
|
|
177
|
+
// Act: Execute the functionality
|
|
178
|
+
const result = validator.validate(email);
|
|
179
|
+
|
|
180
|
+
// Assert: Verify the outcome
|
|
181
|
+
expect(result.valid).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
2. **One Assertion Per Test** (when possible)
|
|
186
|
+
- Each test should verify ONE specific behavior
|
|
187
|
+
- Makes failures easier to diagnose
|
|
188
|
+
- Keeps tests focused and maintainable
|
|
189
|
+
|
|
190
|
+
3. **Test Independence**
|
|
191
|
+
- Tests should not depend on each other
|
|
192
|
+
- Tests should be able to run in any order
|
|
193
|
+
- Use setup/teardown for test isolation
|
|
194
|
+
|
|
195
|
+
4. **Meaningful Test Names**
|
|
196
|
+
- ✅ `should return error when email is missing @symbol`
|
|
197
|
+
- ❌ `test1`, `testEmail`, `checkValidation`
|
|
198
|
+
|
|
199
|
+
### Coverage Targets
|
|
200
|
+
- **Minimum**: 80% code coverage
|
|
201
|
+
- **Target**: 90%+ code coverage for critical paths
|
|
202
|
+
- **Focus**: All public APIs must have tests
|
|
203
|
+
- **Edge Cases**: Always test boundary conditions and error paths
|
|
204
|
+
|
|
205
|
+
### Test Types by Phase
|
|
206
|
+
|
|
207
|
+
#### Unit Tests (RED/GREEN)
|
|
208
|
+
- Test individual functions/methods in isolation
|
|
209
|
+
- Mock external dependencies
|
|
210
|
+
- Fast execution (milliseconds)
|
|
211
|
+
- Should be 70-80% of all tests
|
|
212
|
+
|
|
213
|
+
#### Integration Tests (GREEN/REFACTOR)
|
|
214
|
+
- Test interaction between components
|
|
215
|
+
- Use real or realistic dependencies
|
|
216
|
+
- Test database/API integrations
|
|
217
|
+
- Should be 15-20% of all tests
|
|
218
|
+
|
|
219
|
+
#### End-to-End Tests (REFACTOR/Integration)
|
|
220
|
+
- Test complete user workflows
|
|
221
|
+
- Test through actual interfaces (CLI, API, UI)
|
|
222
|
+
- Slower but validate full system behavior
|
|
223
|
+
- Should be 5-10% of all tests
|
|
224
|
+
|
|
225
|
+
## Anti-Patterns to Avoid
|
|
226
|
+
|
|
227
|
+
### ❌ Implementation-First Development
|
|
228
|
+
```markdown
|
|
229
|
+
# WRONG - Implementation before tests
|
|
230
|
+
- [ ] 1. Implement feature
|
|
231
|
+
- [ ] 2. Write tests for feature
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### ❌ Skipping Tests for "Simple" Code
|
|
235
|
+
Every feature needs tests, regardless of perceived simplicity.
|
|
236
|
+
|
|
237
|
+
### ❌ Writing Tests After Implementation
|
|
238
|
+
This leads to tests that just verify what code does, not what it SHOULD do.
|
|
239
|
+
|
|
240
|
+
### ❌ Testing Implementation Details
|
|
241
|
+
Test behavior and outcomes, not internal implementation.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// ❌ BAD: Testing implementation details
|
|
245
|
+
expect(service.internalCache.size).toBe(0);
|
|
246
|
+
|
|
247
|
+
// ✅ GOOD: Testing behavior
|
|
248
|
+
expect(await service.getUser(id)).toBeNull();
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### ❌ Large, Monolithic Tests
|
|
252
|
+
Break down tests into small, focused units.
|
|
253
|
+
|
|
254
|
+
## Language-Specific TDD Tools
|
|
255
|
+
|
|
256
|
+
### TypeScript/JavaScript
|
|
257
|
+
- **Framework**: Jest, Mocha, Vitest
|
|
258
|
+
- **Assertions**: expect, chai
|
|
259
|
+
- **Mocking**: jest.mock(), sinon
|
|
260
|
+
- **Coverage**: Jest --coverage, nyc
|
|
261
|
+
|
|
262
|
+
### Java
|
|
263
|
+
- **Framework**: JUnit 5, TestNG
|
|
264
|
+
- **Assertions**: AssertJ, Hamcrest
|
|
265
|
+
- **Mocking**: Mockito, EasyMock
|
|
266
|
+
- **Coverage**: JaCoCo, Cobertura
|
|
267
|
+
|
|
268
|
+
### Python
|
|
269
|
+
- **Framework**: pytest, unittest
|
|
270
|
+
- **Assertions**: assert, pytest fixtures
|
|
271
|
+
- **Mocking**: unittest.mock, pytest-mock
|
|
272
|
+
- **Coverage**: pytest-cov, coverage.py
|
|
273
|
+
|
|
274
|
+
### Go
|
|
275
|
+
- **Framework**: testing package, Testify
|
|
276
|
+
- **Assertions**: testify/assert
|
|
277
|
+
- **Mocking**: testify/mock, gomock
|
|
278
|
+
- **Coverage**: go test -cover
|
|
279
|
+
|
|
280
|
+
### Ruby
|
|
281
|
+
- **Framework**: RSpec, Minitest
|
|
282
|
+
- **Assertions**: expect(), assert_equal
|
|
283
|
+
- **Mocking**: rspec-mocks, mocha
|
|
284
|
+
- **Coverage**: SimpleCov
|
|
285
|
+
|
|
286
|
+
### PHP
|
|
287
|
+
- **Framework**: PHPUnit
|
|
288
|
+
- **Assertions**: assertEquals(), assertTrue()
|
|
289
|
+
- **Mocking**: Mockery, Prophecy
|
|
290
|
+
- **Coverage**: PHPUnit --coverage-html
|
|
291
|
+
|
|
292
|
+
## Enforcement
|
|
293
|
+
|
|
294
|
+
### Code Review Checklist
|
|
295
|
+
- [ ] All new features have tests written BEFORE implementation
|
|
296
|
+
- [ ] Tests follow RED → GREEN → REFACTOR cycle
|
|
297
|
+
- [ ] Test coverage meets minimum 80% threshold
|
|
298
|
+
- [ ] Tests are independent and can run in any order
|
|
299
|
+
- [ ] Test names clearly describe expected behavior
|
|
300
|
+
- [ ] Edge cases and error paths are tested
|
|
301
|
+
- [ ] Refactoring maintained green tests
|
|
302
|
+
|
|
303
|
+
### CI/CD Integration
|
|
304
|
+
- Tests MUST pass before merge
|
|
305
|
+
- Coverage MUST meet threshold (80% minimum)
|
|
306
|
+
- No commits with failing tests to main/develop branches
|
|
307
|
+
- Pre-commit hooks to run tests locally
|
|
308
|
+
|
|
309
|
+
## Summary
|
|
310
|
+
|
|
311
|
+
**Golden Rule**: Never write production code without a failing test first.
|
|
312
|
+
|
|
313
|
+
**TDD Workflow**:
|
|
314
|
+
1. 🔴 RED: Write a failing test
|
|
315
|
+
2. 🟢 GREEN: Write minimal code to pass
|
|
316
|
+
3. 🔵 REFACTOR: Improve code quality
|
|
317
|
+
4. ↻ Repeat for next feature
|
|
318
|
+
|
|
319
|
+
**Benefits**:
|
|
320
|
+
- ✅ Code meets requirements by design
|
|
321
|
+
- ✅ Refactoring is safe (tests catch regressions)
|
|
322
|
+
- ✅ Better code design (testable code is often better structured)
|
|
323
|
+
- ✅ Living documentation (tests show how code should work)
|
|
324
|
+
- ✅ Fewer bugs in production
|
package/dist/utils/sddPaths.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDD directory names
|
|
3
|
-
* .spec is the new standard (v2.1.0+)
|
|
4
|
-
* .kiro is legacy (for backwards compatibility)
|
|
5
|
-
*/
|
|
6
|
-
export declare const SDD_DIR = ".spec";
|
|
7
|
-
export declare const SDD_DIR_LEGACY = ".kiro";
|
|
8
|
-
/**
|
|
9
|
-
* Get the SDD root directory for a project
|
|
10
|
-
* Prefers .spec, falls back to .kiro for legacy projects
|
|
11
|
-
*
|
|
12
|
-
* @param projectPath - Project root path
|
|
13
|
-
* @returns SDD root directory path (.spec or .kiro)
|
|
14
|
-
*/
|
|
15
|
-
export declare function getSddRoot(projectPath: string): string;
|
|
16
|
-
/**
|
|
17
|
-
* Get the SDD directory name for a project
|
|
18
|
-
* Returns the actual directory name used (.spec or .kiro)
|
|
19
|
-
*
|
|
20
|
-
* @param projectPath - Project root path
|
|
21
|
-
* @returns Directory name (.spec or .kiro)
|
|
22
|
-
*/
|
|
23
|
-
export declare function getSddDirName(projectPath: string): string;
|
|
24
|
-
/**
|
|
25
|
-
* Get the specs directory path
|
|
26
|
-
* @param projectPath - Project root path
|
|
27
|
-
* @returns Specs directory path
|
|
28
|
-
*/
|
|
29
|
-
export declare function getSpecsPath(projectPath: string): string;
|
|
30
|
-
/**
|
|
31
|
-
* Get the steering directory path
|
|
32
|
-
* @param projectPath - Project root path
|
|
33
|
-
* @returns Steering directory path
|
|
34
|
-
*/
|
|
35
|
-
export declare function getSteeringPath(projectPath: string): string;
|
|
36
|
-
/**
|
|
37
|
-
* Get a feature's spec directory path
|
|
38
|
-
* @param projectPath - Project root path
|
|
39
|
-
* @param featureName - Feature name
|
|
40
|
-
* @returns Feature spec directory path
|
|
41
|
-
*/
|
|
42
|
-
export declare function getFeatureSpecPath(projectPath: string, featureName: string): string;
|
|
43
|
-
/**
|
|
44
|
-
* Get the spec.json file path for a feature
|
|
45
|
-
* @param projectPath - Project root path
|
|
46
|
-
* @param featureName - Feature name
|
|
47
|
-
* @returns spec.json file path
|
|
48
|
-
*/
|
|
49
|
-
export declare function getSpecJsonPath(projectPath: string, featureName: string): string;
|
|
50
|
-
/**
|
|
51
|
-
* Check if this is a legacy project (using .kiro instead of .spec)
|
|
52
|
-
* @param projectPath - Project root path
|
|
53
|
-
* @returns true if project uses .kiro
|
|
54
|
-
*/
|
|
55
|
-
export declare function isLegacyProject(projectPath: string): boolean;
|
|
56
|
-
/**
|
|
57
|
-
* Get the appropriate SDD directory for new projects
|
|
58
|
-
* Always returns .spec for new projects
|
|
59
|
-
*
|
|
60
|
-
* @param projectPath - Project root path
|
|
61
|
-
* @returns Path to create SDD directory (.spec)
|
|
62
|
-
*/
|
|
63
|
-
export declare function getNewSddRoot(projectPath: string): string;
|
|
64
|
-
/**
|
|
65
|
-
* Create all required SDD directories for a new project
|
|
66
|
-
* @param projectPath - Project root path
|
|
67
|
-
* @returns Created paths
|
|
68
|
-
*/
|
|
69
|
-
export declare function createSddDirectories(projectPath: string): string[];
|
package/dist/utils/sddPaths.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
/**
|
|
4
|
-
* SDD directory names
|
|
5
|
-
* .spec is the new standard (v2.1.0+)
|
|
6
|
-
* .kiro is legacy (for backwards compatibility)
|
|
7
|
-
*/
|
|
8
|
-
export const SDD_DIR = '.spec';
|
|
9
|
-
export const SDD_DIR_LEGACY = '.kiro';
|
|
10
|
-
/**
|
|
11
|
-
* Check if a directory exists
|
|
12
|
-
* @param dirPath - Directory path to check
|
|
13
|
-
* @returns true if directory exists
|
|
14
|
-
*/
|
|
15
|
-
function dirExists(dirPath) {
|
|
16
|
-
try {
|
|
17
|
-
return fs.statSync(dirPath).isDirectory();
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Get the SDD root directory for a project
|
|
25
|
-
* Prefers .spec, falls back to .kiro for legacy projects
|
|
26
|
-
*
|
|
27
|
-
* @param projectPath - Project root path
|
|
28
|
-
* @returns SDD root directory path (.spec or .kiro)
|
|
29
|
-
*/
|
|
30
|
-
export function getSddRoot(projectPath) {
|
|
31
|
-
const specPath = path.join(projectPath, SDD_DIR);
|
|
32
|
-
const kiroPath = path.join(projectPath, SDD_DIR_LEGACY);
|
|
33
|
-
// Prefer .spec if it exists
|
|
34
|
-
if (dirExists(specPath)) {
|
|
35
|
-
return specPath;
|
|
36
|
-
}
|
|
37
|
-
// Fall back to .kiro for legacy projects
|
|
38
|
-
if (dirExists(kiroPath)) {
|
|
39
|
-
return kiroPath;
|
|
40
|
-
}
|
|
41
|
-
// Default to .spec for new projects
|
|
42
|
-
return specPath;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Get the SDD directory name for a project
|
|
46
|
-
* Returns the actual directory name used (.spec or .kiro)
|
|
47
|
-
*
|
|
48
|
-
* @param projectPath - Project root path
|
|
49
|
-
* @returns Directory name (.spec or .kiro)
|
|
50
|
-
*/
|
|
51
|
-
export function getSddDirName(projectPath) {
|
|
52
|
-
const specPath = path.join(projectPath, SDD_DIR);
|
|
53
|
-
const kiroPath = path.join(projectPath, SDD_DIR_LEGACY);
|
|
54
|
-
if (dirExists(specPath)) {
|
|
55
|
-
return SDD_DIR;
|
|
56
|
-
}
|
|
57
|
-
if (dirExists(kiroPath)) {
|
|
58
|
-
return SDD_DIR_LEGACY;
|
|
59
|
-
}
|
|
60
|
-
return SDD_DIR;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get the specs directory path
|
|
64
|
-
* @param projectPath - Project root path
|
|
65
|
-
* @returns Specs directory path
|
|
66
|
-
*/
|
|
67
|
-
export function getSpecsPath(projectPath) {
|
|
68
|
-
return path.join(getSddRoot(projectPath), 'specs');
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Get the steering directory path
|
|
72
|
-
* @param projectPath - Project root path
|
|
73
|
-
* @returns Steering directory path
|
|
74
|
-
*/
|
|
75
|
-
export function getSteeringPath(projectPath) {
|
|
76
|
-
return path.join(getSddRoot(projectPath), 'steering');
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get a feature's spec directory path
|
|
80
|
-
* @param projectPath - Project root path
|
|
81
|
-
* @param featureName - Feature name
|
|
82
|
-
* @returns Feature spec directory path
|
|
83
|
-
*/
|
|
84
|
-
export function getFeatureSpecPath(projectPath, featureName) {
|
|
85
|
-
return path.join(getSpecsPath(projectPath), featureName);
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Get the spec.json file path for a feature
|
|
89
|
-
* @param projectPath - Project root path
|
|
90
|
-
* @param featureName - Feature name
|
|
91
|
-
* @returns spec.json file path
|
|
92
|
-
*/
|
|
93
|
-
export function getSpecJsonPath(projectPath, featureName) {
|
|
94
|
-
return path.join(getFeatureSpecPath(projectPath, featureName), 'spec.json');
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Check if this is a legacy project (using .kiro instead of .spec)
|
|
98
|
-
* @param projectPath - Project root path
|
|
99
|
-
* @returns true if project uses .kiro
|
|
100
|
-
*/
|
|
101
|
-
export function isLegacyProject(projectPath) {
|
|
102
|
-
const specPath = path.join(projectPath, SDD_DIR);
|
|
103
|
-
const kiroPath = path.join(projectPath, SDD_DIR_LEGACY);
|
|
104
|
-
// If .spec exists, not legacy
|
|
105
|
-
if (dirExists(specPath)) {
|
|
106
|
-
return false;
|
|
107
|
-
}
|
|
108
|
-
// If only .kiro exists, it's legacy
|
|
109
|
-
return dirExists(kiroPath);
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Get the appropriate SDD directory for new projects
|
|
113
|
-
* Always returns .spec for new projects
|
|
114
|
-
*
|
|
115
|
-
* @param projectPath - Project root path
|
|
116
|
-
* @returns Path to create SDD directory (.spec)
|
|
117
|
-
*/
|
|
118
|
-
export function getNewSddRoot(projectPath) {
|
|
119
|
-
return path.join(projectPath, SDD_DIR);
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Create all required SDD directories for a new project
|
|
123
|
-
* @param projectPath - Project root path
|
|
124
|
-
* @returns Created paths
|
|
125
|
-
*/
|
|
126
|
-
export function createSddDirectories(projectPath) {
|
|
127
|
-
const sddRoot = getNewSddRoot(projectPath);
|
|
128
|
-
const paths = [
|
|
129
|
-
sddRoot,
|
|
130
|
-
path.join(sddRoot, 'specs'),
|
|
131
|
-
path.join(sddRoot, 'steering'),
|
|
132
|
-
];
|
|
133
|
-
for (const p of paths) {
|
|
134
|
-
fs.mkdirSync(p, { recursive: true });
|
|
135
|
-
}
|
|
136
|
-
return paths;
|
|
137
|
-
}
|
|
138
|
-
//# sourceMappingURL=sddPaths.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sddPaths.js","sourceRoot":"","sources":["../../src/utils/sddPaths.ts"],"names":[],"mappings":"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"}
|