sdd-mcp-server 2.1.0 → 2.2.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 +43 -30
- 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 +221 -5
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/sdd-mcp-cli.d.ts +2 -1
- package/dist/cli/sdd-mcp-cli.js +16 -6
- package/dist/cli/sdd-mcp-cli.js.map +1 -1
- package/dist/index.js +0 -0
- 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 +3 -1
- 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
|
@@ -11,14 +11,18 @@ const __dirname = path.dirname(__filename);
|
|
|
11
11
|
*/
|
|
12
12
|
export class InstallSkillsCLI {
|
|
13
13
|
skillManager;
|
|
14
|
+
steeringPath;
|
|
14
15
|
/**
|
|
15
16
|
* Create CLI instance
|
|
16
17
|
* @param skillsPath - Optional path to skills directory (for testing)
|
|
18
|
+
* @param steeringPath - Optional path to steering directory (for testing)
|
|
17
19
|
*/
|
|
18
|
-
constructor(skillsPath) {
|
|
20
|
+
constructor(skillsPath, steeringPath) {
|
|
19
21
|
// If no path provided, determine from package location
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
+
const resolvedSkillsPath = skillsPath || this.getDefaultSkillsPath();
|
|
23
|
+
const resolvedSteeringPath = steeringPath || this.getDefaultSteeringPath();
|
|
24
|
+
this.skillManager = new SkillManager(resolvedSkillsPath);
|
|
25
|
+
this.steeringPath = resolvedSteeringPath;
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* Get the default skills path based on package location
|
|
@@ -45,6 +49,31 @@ export class InstallSkillsCLI {
|
|
|
45
49
|
// Fallback to first path (will error in SkillManager if not found)
|
|
46
50
|
return possiblePaths[0];
|
|
47
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the default steering path based on package location
|
|
54
|
+
*/
|
|
55
|
+
getDefaultSteeringPath() {
|
|
56
|
+
// Try multiple paths and return the first one that exists
|
|
57
|
+
const possiblePaths = [
|
|
58
|
+
// Relative to this file (dist/cli/install-skills.js -> steering/)
|
|
59
|
+
path.resolve(__dirname, '../../steering'),
|
|
60
|
+
// Alternative: one level up
|
|
61
|
+
path.resolve(__dirname, '../steering'),
|
|
62
|
+
// From package root when installed globally or via npx
|
|
63
|
+
path.resolve(__dirname, '../../../steering'),
|
|
64
|
+
// From current working directory
|
|
65
|
+
path.resolve(process.cwd(), 'node_modules/sdd-mcp-server/steering'),
|
|
66
|
+
path.resolve(process.cwd(), 'steering'),
|
|
67
|
+
];
|
|
68
|
+
// Return the first path that exists
|
|
69
|
+
for (const p of possiblePaths) {
|
|
70
|
+
if (fs.existsSync(p)) {
|
|
71
|
+
return p;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Fallback to first path
|
|
75
|
+
return possiblePaths[0];
|
|
76
|
+
}
|
|
48
77
|
/**
|
|
49
78
|
* Parse command line arguments
|
|
50
79
|
* @param args - Command line arguments (process.argv.slice(2))
|
|
@@ -53,8 +82,11 @@ export class InstallSkillsCLI {
|
|
|
53
82
|
parseArgs(args) {
|
|
54
83
|
const options = {
|
|
55
84
|
targetPath: '.claude/skills',
|
|
85
|
+
steeringPath: '.spec/steering',
|
|
56
86
|
listOnly: false,
|
|
57
87
|
showHelp: false,
|
|
88
|
+
skillsOnly: false,
|
|
89
|
+
steeringOnly: false,
|
|
58
90
|
};
|
|
59
91
|
for (let i = 0; i < args.length; i++) {
|
|
60
92
|
const arg = args[i];
|
|
@@ -64,6 +96,11 @@ export class InstallSkillsCLI {
|
|
|
64
96
|
options.targetPath = args[++i];
|
|
65
97
|
}
|
|
66
98
|
break;
|
|
99
|
+
case '--steering-path':
|
|
100
|
+
if (i + 1 < args.length) {
|
|
101
|
+
options.steeringPath = args[++i];
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
67
104
|
case '--list':
|
|
68
105
|
case '-l':
|
|
69
106
|
options.listOnly = true;
|
|
@@ -72,12 +109,18 @@ export class InstallSkillsCLI {
|
|
|
72
109
|
case '-h':
|
|
73
110
|
options.showHelp = true;
|
|
74
111
|
break;
|
|
112
|
+
case '--skills':
|
|
113
|
+
options.skillsOnly = true;
|
|
114
|
+
break;
|
|
115
|
+
case '--steering':
|
|
116
|
+
options.steeringOnly = true;
|
|
117
|
+
break;
|
|
75
118
|
}
|
|
76
119
|
}
|
|
77
120
|
return options;
|
|
78
121
|
}
|
|
79
122
|
/**
|
|
80
|
-
* Run the CLI with given options
|
|
123
|
+
* Run the CLI with given options (legacy skills-only mode)
|
|
81
124
|
* @param options - CLI options
|
|
82
125
|
*/
|
|
83
126
|
async run(options) {
|
|
@@ -91,6 +134,29 @@ export class InstallSkillsCLI {
|
|
|
91
134
|
}
|
|
92
135
|
await this.installSkills(options.targetPath);
|
|
93
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Run unified install (skills + steering)
|
|
139
|
+
* @param options - CLI options
|
|
140
|
+
*/
|
|
141
|
+
async runUnified(options) {
|
|
142
|
+
if (options.showHelp) {
|
|
143
|
+
console.log(this.getUnifiedHelp());
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (options.listOnly) {
|
|
147
|
+
await this.listAll();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
// Determine what to install
|
|
151
|
+
const installSkills = !options.steeringOnly;
|
|
152
|
+
const installSteering = !options.skillsOnly;
|
|
153
|
+
if (installSkills) {
|
|
154
|
+
await this.installSkills(options.targetPath);
|
|
155
|
+
}
|
|
156
|
+
if (installSteering) {
|
|
157
|
+
await this.installSteering(options.steeringPath);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
94
160
|
/**
|
|
95
161
|
* List available skills
|
|
96
162
|
*/
|
|
@@ -111,6 +177,56 @@ export class InstallSkillsCLI {
|
|
|
111
177
|
console.log(`Total: ${skills.length} skills\n`);
|
|
112
178
|
console.log('Run "npx sdd-mcp install-skills" to install all skills.\n');
|
|
113
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* List available steering documents
|
|
182
|
+
*/
|
|
183
|
+
async listSteering() {
|
|
184
|
+
const steeringDocs = [];
|
|
185
|
+
try {
|
|
186
|
+
const entries = await fs.promises.readdir(this.steeringPath);
|
|
187
|
+
for (const entry of entries) {
|
|
188
|
+
if (entry.endsWith('.md')) {
|
|
189
|
+
steeringDocs.push(entry);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Return empty array if steering directory doesn't exist
|
|
195
|
+
}
|
|
196
|
+
return steeringDocs;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* List all available skills and steering documents
|
|
200
|
+
*/
|
|
201
|
+
async listAll() {
|
|
202
|
+
const skills = await this.skillManager.listSkills();
|
|
203
|
+
const steeringDocs = await this.listSteering();
|
|
204
|
+
console.log('\n📚 Available Skills:\n');
|
|
205
|
+
if (skills.length === 0) {
|
|
206
|
+
console.log(' (none)\n');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
for (const skill of skills) {
|
|
210
|
+
console.log(` • ${skill.name}`);
|
|
211
|
+
if (skill.description) {
|
|
212
|
+
console.log(` ${skill.description}`);
|
|
213
|
+
}
|
|
214
|
+
console.log('');
|
|
215
|
+
}
|
|
216
|
+
console.log(` Total: ${skills.length} skills\n`);
|
|
217
|
+
}
|
|
218
|
+
console.log('📄 Available Steering Documents:\n');
|
|
219
|
+
if (steeringDocs.length === 0) {
|
|
220
|
+
console.log(' (none)\n');
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
for (const doc of steeringDocs) {
|
|
224
|
+
console.log(` • ${doc}`);
|
|
225
|
+
}
|
|
226
|
+
console.log(`\n Total: ${steeringDocs.length} steering documents\n`);
|
|
227
|
+
}
|
|
228
|
+
console.log('Run "npx sdd-mcp install" to install all skills and steering documents.\n');
|
|
229
|
+
}
|
|
114
230
|
/**
|
|
115
231
|
* Install skills to target directory
|
|
116
232
|
* @param targetPath - Target directory
|
|
@@ -138,6 +254,60 @@ export class InstallSkillsCLI {
|
|
|
138
254
|
console.log(' Use /sdd-requirements, /sdd-design, etc. in Claude Code.\n');
|
|
139
255
|
}
|
|
140
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Install steering documents to target directory
|
|
259
|
+
* @param targetPath - Target directory (e.g., .spec/steering)
|
|
260
|
+
*/
|
|
261
|
+
async installSteering(targetPath) {
|
|
262
|
+
console.log(`\n📄 Installing steering documents to: ${targetPath}\n`);
|
|
263
|
+
const installed = [];
|
|
264
|
+
const failed = [];
|
|
265
|
+
try {
|
|
266
|
+
// Create target directory
|
|
267
|
+
await fs.promises.mkdir(targetPath, { recursive: true });
|
|
268
|
+
// Read source steering directory
|
|
269
|
+
const entries = await fs.promises.readdir(this.steeringPath);
|
|
270
|
+
for (const entry of entries) {
|
|
271
|
+
if (entry.endsWith('.md')) {
|
|
272
|
+
try {
|
|
273
|
+
const sourceFile = path.join(this.steeringPath, entry);
|
|
274
|
+
const destFile = path.join(targetPath, entry);
|
|
275
|
+
await fs.promises.copyFile(sourceFile, destFile);
|
|
276
|
+
installed.push(entry);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
failed.push({
|
|
280
|
+
name: entry,
|
|
281
|
+
error: error instanceof Error ? error.message : String(error),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.error(`❌ Failed to read steering directory: ${error instanceof Error ? error.message : String(error)}`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (installed.length > 0) {
|
|
292
|
+
const plural = installed.length === 1 ? 'document' : 'documents';
|
|
293
|
+
console.log(`✅ Installed ${installed.length} steering ${plural}:`);
|
|
294
|
+
for (const name of installed) {
|
|
295
|
+
console.log(` • ${name}`);
|
|
296
|
+
}
|
|
297
|
+
console.log('');
|
|
298
|
+
}
|
|
299
|
+
if (failed.length > 0) {
|
|
300
|
+
console.error(`❌ Failed to install ${failed.length} document(s):`);
|
|
301
|
+
for (const failure of failed) {
|
|
302
|
+
console.error(` • ${failure.name}: ${failure.error}`);
|
|
303
|
+
}
|
|
304
|
+
console.log('');
|
|
305
|
+
}
|
|
306
|
+
if (installed.length > 0) {
|
|
307
|
+
console.log('🎉 Steering documents installed successfully!');
|
|
308
|
+
console.log(' These provide project-wide guidance for AI interactions.\n');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
141
311
|
/**
|
|
142
312
|
* Get help text
|
|
143
313
|
* @returns Help message
|
|
@@ -166,15 +336,61 @@ After installation, you can use them in Claude Code with:
|
|
|
166
336
|
/sdd-implement <feature-name>
|
|
167
337
|
/sdd-steering
|
|
168
338
|
/sdd-commit
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Get unified install help text
|
|
343
|
+
* @returns Help message for unified install
|
|
344
|
+
*/
|
|
345
|
+
getUnifiedHelp() {
|
|
346
|
+
return `
|
|
347
|
+
SDD Unified Installer
|
|
348
|
+
|
|
349
|
+
Usage: npx sdd-mcp install [options]
|
|
350
|
+
|
|
351
|
+
Installs both SDD skills and steering documents to your project.
|
|
352
|
+
|
|
353
|
+
Options:
|
|
354
|
+
--skills Install skills only (to .claude/skills)
|
|
355
|
+
--steering Install steering documents only (to .spec/steering)
|
|
356
|
+
--path <dir> Target directory for skills (default: .claude/skills)
|
|
357
|
+
--steering-path <dir> Target directory for steering (default: .spec/steering)
|
|
358
|
+
--list, -l List available skills and steering documents
|
|
359
|
+
--help, -h Show this help message
|
|
360
|
+
|
|
361
|
+
Examples:
|
|
362
|
+
npx sdd-mcp install # Install both skills and steering
|
|
363
|
+
npx sdd-mcp install --skills # Install skills only
|
|
364
|
+
npx sdd-mcp install --steering # Install steering only
|
|
365
|
+
npx sdd-mcp install --list # List available content
|
|
366
|
+
|
|
367
|
+
Skills are installed to .claude/skills/ and provide workflow guidance.
|
|
368
|
+
Steering documents are installed to .spec/steering/ and provide project-wide rules.
|
|
369
|
+
|
|
370
|
+
After installation, use skills in Claude Code:
|
|
371
|
+
/sdd-requirements <feature-name>
|
|
372
|
+
/sdd-design <feature-name>
|
|
373
|
+
/sdd-tasks <feature-name>
|
|
374
|
+
/sdd-implement <feature-name>
|
|
375
|
+
/sdd-steering
|
|
376
|
+
/sdd-commit
|
|
377
|
+
|
|
378
|
+
Steering documents are automatically loaded by the SDD MCP server.
|
|
169
379
|
`;
|
|
170
380
|
}
|
|
171
381
|
}
|
|
172
|
-
// Main entry point when run directly
|
|
382
|
+
// Main entry point when run directly (legacy install-skills)
|
|
173
383
|
export async function main() {
|
|
174
384
|
const cli = new InstallSkillsCLI();
|
|
175
385
|
const options = cli.parseArgs(process.argv.slice(2));
|
|
176
386
|
await cli.run(options);
|
|
177
387
|
}
|
|
388
|
+
// Main entry point for unified install command
|
|
389
|
+
export async function mainInstall() {
|
|
390
|
+
const cli = new InstallSkillsCLI();
|
|
391
|
+
const options = cli.parseArgs(process.argv.slice(2));
|
|
392
|
+
await cli.runUnified(options);
|
|
393
|
+
}
|
|
178
394
|
// ESM main module detection: check if this file is the entry point
|
|
179
395
|
const isMainModule = process.argv[1] && (process.argv[1] === __filename ||
|
|
180
396
|
process.argv[1].endsWith('/install-skills.js') ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/cli/install-skills.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,8BAA8B;AAC9B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"install-skills.js","sourceRoot":"","sources":["../../src/cli/install-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Main CLI entry point for sdd-mcp commands
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* npx sdd-mcp install
|
|
6
|
+
* npx sdd-mcp install [options] # Install skills AND steering (unified)
|
|
7
|
+
* npx sdd-mcp install-skills [options] # Install skills only (legacy)
|
|
7
8
|
* npx sdd-mcp migrate-kiro [options]
|
|
8
9
|
* npx sdd-mcp --help
|
|
9
10
|
*/
|
package/dist/cli/sdd-mcp-cli.js
CHANGED
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
* Main CLI entry point for sdd-mcp commands
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* npx sdd-mcp install
|
|
6
|
+
* npx sdd-mcp install [options] # Install skills AND steering (unified)
|
|
7
|
+
* npx sdd-mcp install-skills [options] # Install skills only (legacy)
|
|
7
8
|
* npx sdd-mcp migrate-kiro [options]
|
|
8
9
|
* npx sdd-mcp --help
|
|
9
10
|
*/
|
|
10
|
-
import { main as installSkillsMain } from './install-skills.js';
|
|
11
|
+
import { main as installSkillsMain, mainInstall as installMain } from './install-skills.js';
|
|
11
12
|
import { main as migrateKiroMain } from './migrate-kiro.js';
|
|
12
13
|
const HELP = `
|
|
13
14
|
SDD MCP CLI
|
|
@@ -15,16 +16,20 @@ SDD MCP CLI
|
|
|
15
16
|
Usage: npx sdd-mcp <command> [options]
|
|
16
17
|
|
|
17
18
|
Commands:
|
|
18
|
-
install
|
|
19
|
+
install Install SDD skills AND steering documents (recommended)
|
|
20
|
+
install-skills Install SDD skills only (legacy)
|
|
19
21
|
migrate-kiro Migrate .kiro directory to .spec (v2.1.0+)
|
|
20
22
|
|
|
21
23
|
Options:
|
|
22
24
|
--help, -h Show this help message
|
|
23
25
|
|
|
24
26
|
Examples:
|
|
25
|
-
npx sdd-mcp install
|
|
27
|
+
npx sdd-mcp install # Install skills to .claude/skills + steering to .spec/steering
|
|
28
|
+
npx sdd-mcp install --skills # Install skills only
|
|
29
|
+
npx sdd-mcp install --steering # Install steering only
|
|
30
|
+
npx sdd-mcp install --list # List available skills and steering docs
|
|
31
|
+
npx sdd-mcp install-skills # Legacy: Install skills to .claude/skills
|
|
26
32
|
npx sdd-mcp install-skills --list # List available skills
|
|
27
|
-
npx sdd-mcp install-skills --path ./ # Install to custom path
|
|
28
33
|
npx sdd-mcp migrate-kiro # Migrate .kiro to .spec
|
|
29
34
|
npx sdd-mcp migrate-kiro --dry-run # Preview migration
|
|
30
35
|
|
|
@@ -38,8 +43,13 @@ async function main() {
|
|
|
38
43
|
process.exit(0);
|
|
39
44
|
}
|
|
40
45
|
switch (command) {
|
|
46
|
+
case 'install':
|
|
47
|
+
// Unified install command - both skills and steering
|
|
48
|
+
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
49
|
+
await installMain();
|
|
50
|
+
break;
|
|
41
51
|
case 'install-skills':
|
|
42
|
-
//
|
|
52
|
+
// Legacy: Install skills only
|
|
43
53
|
process.argv = [process.argv[0], process.argv[1], ...args.slice(1)];
|
|
44
54
|
await installSkillsMain();
|
|
45
55
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdd-mcp-cli.js","sourceRoot":"","sources":["../../src/cli/sdd-mcp-cli.ts"],"names":[],"mappings":";AAEA
|
|
1
|
+
{"version":3,"file":"sdd-mcp-cli.js","sourceRoot":"","sources":["../../src/cli/sdd-mcp-cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,IAAI,iBAAiB,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC5F,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBZ,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,qDAAqD;YACrD,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,WAAW,EAAE,CAAC;YACpB,MAAM;QAER,KAAK,gBAAgB;YACnB,8BAA8B;YAC9B,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,iBAAiB,EAAE,CAAC;YAC1B,MAAM;QAER,KAAK,cAAc;YACjB,iEAAiE;YACjE,OAAO,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,eAAe,EAAE,CAAC;YACxB,MAAM;QAER;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic file write utility
|
|
3
|
+
* 原子性檔案寫入工具
|
|
4
|
+
*
|
|
5
|
+
* Prevents file corruption when write operations are interrupted (crash, kill signal).
|
|
6
|
+
* Uses the temp-file + rename pattern which is atomic on POSIX systems.
|
|
7
|
+
* 防止寫入操作被中斷時(crash、kill signal)造成檔案損壞。
|
|
8
|
+
* 使用 temp-file + rename 模式,在 POSIX 系統上是原子操作。
|
|
9
|
+
*
|
|
10
|
+
* @note Windows Limitation / Windows 限制:
|
|
11
|
+
* On Windows, fs.rename() may fail with EEXIST if target exists.
|
|
12
|
+
* For Windows production use, consider using 'write-file-atomic' package.
|
|
13
|
+
* 在 Windows 上,若目標檔案存在,fs.rename() 可能會失敗。
|
|
14
|
+
* 若需在 Windows 生產環境使用,建議改用 'write-file-atomic' 套件。
|
|
15
|
+
*
|
|
16
|
+
* @module utils/atomicWrite
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Write content to a file atomically.
|
|
20
|
+
*
|
|
21
|
+
* This function writes to a temporary file first, then renames it to the target path.
|
|
22
|
+
* The rename operation is atomic on POSIX systems, ensuring the file is never left
|
|
23
|
+
* in a corrupted state.
|
|
24
|
+
*
|
|
25
|
+
* @param filePath - The target file path
|
|
26
|
+
* @param content - The content to write
|
|
27
|
+
* @param options - Optional write options
|
|
28
|
+
* @returns Promise that resolves when write is complete
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* await atomicWriteFile('/path/to/spec.json', JSON.stringify(data, null, 2));
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function atomicWriteFile(filePath: string, content: string, options?: {
|
|
36
|
+
encoding?: BufferEncoding;
|
|
37
|
+
}): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Write JSON content to a file atomically.
|
|
40
|
+
*
|
|
41
|
+
* Convenience wrapper that handles JSON serialization with pretty printing.
|
|
42
|
+
*
|
|
43
|
+
* @param filePath - The target file path
|
|
44
|
+
* @param data - The data to serialize and write
|
|
45
|
+
* @param options - Optional options (indent spaces, default 2)
|
|
46
|
+
* @returns Promise that resolves when write is complete
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* await atomicWriteJSON('/path/to/spec.json', specData);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function atomicWriteJSON(filePath: string, data: unknown, options?: {
|
|
54
|
+
indent?: number;
|
|
55
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic file write utility
|
|
3
|
+
* 原子性檔案寫入工具
|
|
4
|
+
*
|
|
5
|
+
* Prevents file corruption when write operations are interrupted (crash, kill signal).
|
|
6
|
+
* Uses the temp-file + rename pattern which is atomic on POSIX systems.
|
|
7
|
+
* 防止寫入操作被中斷時(crash、kill signal)造成檔案損壞。
|
|
8
|
+
* 使用 temp-file + rename 模式,在 POSIX 系統上是原子操作。
|
|
9
|
+
*
|
|
10
|
+
* @note Windows Limitation / Windows 限制:
|
|
11
|
+
* On Windows, fs.rename() may fail with EEXIST if target exists.
|
|
12
|
+
* For Windows production use, consider using 'write-file-atomic' package.
|
|
13
|
+
* 在 Windows 上,若目標檔案存在,fs.rename() 可能會失敗。
|
|
14
|
+
* 若需在 Windows 生產環境使用,建議改用 'write-file-atomic' 套件。
|
|
15
|
+
*
|
|
16
|
+
* @module utils/atomicWrite
|
|
17
|
+
*/
|
|
18
|
+
import * as fs from "fs/promises";
|
|
19
|
+
import * as path from "path";
|
|
20
|
+
/**
|
|
21
|
+
* Write content to a file atomically.
|
|
22
|
+
*
|
|
23
|
+
* This function writes to a temporary file first, then renames it to the target path.
|
|
24
|
+
* The rename operation is atomic on POSIX systems, ensuring the file is never left
|
|
25
|
+
* in a corrupted state.
|
|
26
|
+
*
|
|
27
|
+
* @param filePath - The target file path
|
|
28
|
+
* @param content - The content to write
|
|
29
|
+
* @param options - Optional write options
|
|
30
|
+
* @returns Promise that resolves when write is complete
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* await atomicWriteFile('/path/to/spec.json', JSON.stringify(data, null, 2));
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export async function atomicWriteFile(filePath, content, options) {
|
|
38
|
+
const encoding = options?.encoding ?? "utf8";
|
|
39
|
+
const dir = path.dirname(filePath);
|
|
40
|
+
const filename = path.basename(filePath);
|
|
41
|
+
// Create temp file path with process ID, timestamp, and random suffix for uniqueness
|
|
42
|
+
// Random suffix prevents collisions when multiple writes occur within the same millisecond
|
|
43
|
+
const uniqueSuffix = `${Date.now()}.${Math.random().toString(36).slice(2, 10)}`;
|
|
44
|
+
const tempPath = path.join(dir, `.${filename}.${process.pid}.${uniqueSuffix}.tmp`);
|
|
45
|
+
try {
|
|
46
|
+
// Ensure directory exists
|
|
47
|
+
await fs.mkdir(dir, { recursive: true });
|
|
48
|
+
// Write to temp file
|
|
49
|
+
await fs.writeFile(tempPath, content, encoding);
|
|
50
|
+
// Atomic rename (on POSIX systems)
|
|
51
|
+
await fs.rename(tempPath, filePath);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
// Clean up temp file if it exists
|
|
55
|
+
try {
|
|
56
|
+
await fs.unlink(tempPath);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Ignore cleanup errors
|
|
60
|
+
}
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Write JSON content to a file atomically.
|
|
66
|
+
*
|
|
67
|
+
* Convenience wrapper that handles JSON serialization with pretty printing.
|
|
68
|
+
*
|
|
69
|
+
* @param filePath - The target file path
|
|
70
|
+
* @param data - The data to serialize and write
|
|
71
|
+
* @param options - Optional options (indent spaces, default 2)
|
|
72
|
+
* @returns Promise that resolves when write is complete
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* await atomicWriteJSON('/path/to/spec.json', specData);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export async function atomicWriteJSON(filePath, data, options) {
|
|
80
|
+
const indent = options?.indent ?? 2;
|
|
81
|
+
const content = JSON.stringify(data, null, indent);
|
|
82
|
+
await atomicWriteFile(filePath, content);
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=atomicWrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomicWrite.js","sourceRoot":"","sources":["../../src/utils/atomicWrite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAe,EACf,OAAuC;IAEvC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,MAAM,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzC,qFAAqF;IACrF,2FAA2F;IAC3F,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;IAChF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,IAAI,OAAO,CAAC,GAAG,IAAI,YAAY,MAAM,CAAC,CAAC;IAEnF,IAAI,CAAC;QACH,0BAA0B;QAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzC,qBAAqB;QACrB,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEhD,mCAAmC;QACnC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kCAAkC;QAClC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,IAAa,EACb,OAA6B;IAE7B,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
|
package/mcp-server.js
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
generateTechDocument,
|
|
11
11
|
generateStructureDocument,
|
|
12
12
|
} from "./documentGenerator.js";
|
|
13
|
+
import { atomicWriteJSON } from "./atomicWrite.js";
|
|
13
14
|
|
|
14
15
|
// Best-effort dynamic loader for spec generators (requirements/design/tasks)
|
|
15
16
|
async function loadSpecGenerator() {
|
|
@@ -551,7 +552,7 @@ server.registerTool(
|
|
|
551
552
|
spec.approvals.requirements.generated = true;
|
|
552
553
|
spec.updated_at = await getCurrentTimestamp();
|
|
553
554
|
|
|
554
|
-
await
|
|
555
|
+
await atomicWriteJSON(specPath, spec);
|
|
555
556
|
|
|
556
557
|
return {
|
|
557
558
|
content: [
|
|
@@ -633,7 +634,7 @@ server.registerTool(
|
|
|
633
634
|
spec.approvals.design.generated = true;
|
|
634
635
|
spec.updated_at = await getCurrentTimestamp();
|
|
635
636
|
|
|
636
|
-
await
|
|
637
|
+
await atomicWriteJSON(specPath, spec);
|
|
637
638
|
|
|
638
639
|
return {
|
|
639
640
|
content: [
|
|
@@ -771,7 +772,7 @@ ${designContext.substring(0, 1000)}${designContext.length > 1000 ? "...\n[Design
|
|
|
771
772
|
spec.ready_for_implementation = true;
|
|
772
773
|
spec.updated_at = await getCurrentTimestamp();
|
|
773
774
|
|
|
774
|
-
await
|
|
775
|
+
await atomicWriteJSON(specPath, spec);
|
|
775
776
|
|
|
776
777
|
return {
|
|
777
778
|
content: [
|
|
@@ -1034,7 +1035,7 @@ server.registerTool(
|
|
|
1034
1035
|
spec.approvals[phase].approved = true;
|
|
1035
1036
|
spec.updated_at = await getCurrentTimestamp();
|
|
1036
1037
|
|
|
1037
|
-
await
|
|
1038
|
+
await atomicWriteJSON(specPath, spec);
|
|
1038
1039
|
|
|
1039
1040
|
return {
|
|
1040
1041
|
content: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdd-mcp-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "MCP server for spec-driven development workflows across AI-agent CLIs and IDEs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"files": [
|
|
13
13
|
"dist/**/*",
|
|
14
14
|
"skills/**/*",
|
|
15
|
+
"steering/**/*",
|
|
15
16
|
"mcp-server.js",
|
|
17
|
+
"atomicWrite.js",
|
|
16
18
|
"documentGenerator.js",
|
|
17
19
|
"specGenerator.js",
|
|
18
20
|
"README.md",
|
|
@@ -271,6 +271,20 @@ git rebase origin/main
|
|
|
271
271
|
git push origin feature/AUTH-123-jwt-auth
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
+
## Steering Document References
|
|
275
|
+
|
|
276
|
+
Apply these steering documents for commits and PRs:
|
|
277
|
+
|
|
278
|
+
| Document | Purpose | Key Application |
|
|
279
|
+
|----------|---------|-----------------|
|
|
280
|
+
| `.spec/steering/commit.md` | Commit message conventions | Follow type prefixes, scope, and format guidelines |
|
|
281
|
+
|
|
282
|
+
**Key Commit Rules:**
|
|
283
|
+
1. Use type prefixes: `feat`, `fix`, `docs`, `refactor`, `test`, etc.
|
|
284
|
+
2. Keep subject line under 72 characters
|
|
285
|
+
3. Use imperative mood ("add" not "added")
|
|
286
|
+
4. Reference issues in footer
|
|
287
|
+
|
|
274
288
|
## Quality Checklist
|
|
275
289
|
|
|
276
290
|
- [ ] Commit message follows format
|
|
@@ -248,6 +248,21 @@ Before finalizing, validate against these principles:
|
|
|
248
248
|
| `sdd-validate-design` | Perform GO/NO-GO review |
|
|
249
249
|
| `sdd-approve` | Mark design phase as approved |
|
|
250
250
|
|
|
251
|
+
## Steering Document References
|
|
252
|
+
|
|
253
|
+
Apply these steering documents during design:
|
|
254
|
+
|
|
255
|
+
| Document | Purpose | Key Application |
|
|
256
|
+
|----------|---------|-----------------|
|
|
257
|
+
| `.spec/steering/principles.md` | SOLID, DRY, KISS, YAGNI | Apply SOLID principles to component design, ensure interfaces follow ISP and DIP |
|
|
258
|
+
| `.spec/steering/linus-review.md` | Code quality, data structures | Focus on data structures first, eliminate special cases, ensure backward compatibility |
|
|
259
|
+
|
|
260
|
+
**Key Linus Principles for Design:**
|
|
261
|
+
1. **Data Structures First**: "Bad programmers worry about the code. Good programmers worry about data structures."
|
|
262
|
+
2. **Eliminate Special Cases**: "Good code has no special cases"
|
|
263
|
+
3. **Simplicity**: "If implementation needs more than 3 levels of indentation, redesign it"
|
|
264
|
+
4. **Never Break Userspace**: Ensure backward compatibility
|
|
265
|
+
|
|
251
266
|
## Quality Checklist
|
|
252
267
|
|
|
253
268
|
- [ ] All FR-* requirements have corresponding components
|