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.
@@ -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 resolvedPath = skillsPath || this.getDefaultSkillsPath();
21
- this.skillManager = new SkillManager(resolvedPath);
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":"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"}
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-skills [options]
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
  */
@@ -3,11 +3,12 @@
3
3
  * Main CLI entry point for sdd-mcp commands
4
4
  *
5
5
  * Usage:
6
- * npx sdd-mcp install-skills [options]
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-skills Install SDD skills to your project
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-skills # Install to .claude/skills
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
- // Remove the command from args and pass the rest to install-skills
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;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE5D,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;CAoBZ,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,gBAAgB;YACnB,mEAAmE;YACnE,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"}
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 fs.writeFile(specPath, JSON.stringify(spec, null, 2));
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 fs.writeFile(specPath, JSON.stringify(spec, null, 2));
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 fs.writeFile(specPath, JSON.stringify(spec, null, 2));
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 fs.writeFile(specPath, JSON.stringify(spec, null, 2));
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.1.0",
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