sdd-mcp-server 3.5.0 → 4.0.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 +97 -671
- package/agents/architect.md +15 -93
- package/agents/implementer.md +16 -141
- package/agents/planner.md +16 -84
- package/agents/reviewer.md +16 -239
- package/agents/security-auditor.md +16 -114
- package/agents/tdd-guide.md +17 -228
- package/dist/adapters/cli/SDDToolAdapter.d.ts +14 -5
- package/dist/adapters/cli/SDDToolAdapter.js +189 -362
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -1
- package/dist/application/services/ContextCompactionService.d.ts +81 -16
- package/dist/application/services/ContextCompactionService.js +370 -187
- package/dist/application/services/ContextCompactionService.js.map +1 -1
- package/dist/application/services/SpecPathResolver.d.ts +24 -0
- package/dist/application/services/SpecPathResolver.js +70 -0
- package/dist/application/services/SpecPathResolver.js.map +1 -0
- package/dist/application/services/WorkflowEngineService.d.ts +100 -46
- package/dist/application/services/WorkflowEngineService.js +468 -288
- package/dist/application/services/WorkflowEngineService.js.map +1 -1
- package/dist/cli/install-skills.d.ts +3 -9
- package/dist/cli/install-skills.js +130 -175
- package/dist/cli/install-skills.js.map +1 -1
- package/dist/cli/install-target.d.ts +45 -14
- package/dist/cli/install-target.js +26 -12
- package/dist/cli/install-target.js.map +1 -1
- package/dist/cli/sdd-mcp-cli.d.ts +1 -1
- package/dist/cli/sdd-mcp-cli.js +7 -6
- package/dist/cli/sdd-mcp-cli.js.map +1 -1
- package/dist/cli/tool-support/claude-code.js +13 -34
- package/dist/cli/tool-support/claude-code.js.map +1 -1
- package/dist/cli/tool-support/codex.d.ts +0 -53
- package/dist/cli/tool-support/codex.js +6 -94
- package/dist/cli/tool-support/codex.js.map +1 -1
- package/dist/cli/tool-support/index.d.ts +3 -2
- package/dist/cli/tool-support/index.js +3 -1
- package/dist/cli/tool-support/index.js.map +1 -1
- package/dist/cli/tool-support/omp.d.ts +5 -0
- package/dist/cli/tool-support/omp.js +43 -0
- package/dist/cli/tool-support/omp.js.map +1 -0
- package/dist/cli/tool-support/root-guidance.d.ts +2 -9
- package/dist/cli/tool-support/root-guidance.js +44 -37
- package/dist/cli/tool-support/root-guidance.js.map +1 -1
- package/dist/cli/tool-support/target-agent-renderer.d.ts +1 -0
- package/dist/cli/tool-support/target-agent-renderer.js +37 -4
- package/dist/cli/tool-support/target-agent-renderer.js.map +1 -1
- package/dist/cli/tool-support/target-installer.d.ts +8 -2
- package/dist/cli/tool-support/target-installer.js +94 -26
- package/dist/cli/tool-support/target-installer.js.map +1 -1
- package/dist/cli/utils/preserving-writer.d.ts +22 -0
- package/dist/cli/utils/preserving-writer.js +233 -11
- package/dist/cli/utils/preserving-writer.js.map +1 -1
- package/dist/domain/ports.d.ts +4 -0
- package/dist/index.d.ts +13 -10
- package/dist/index.js +16 -1199
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.d.ts +3 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js +10 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js.map +1 -1
- package/dist/infrastructure/mcp/CapabilityNegotiator.js +3 -3
- package/dist/infrastructure/mcp/CapabilityNegotiator.js.map +1 -1
- package/dist/infrastructure/mcp/sddToolDefinitions.d.ts +6 -0
- package/dist/infrastructure/mcp/sddToolDefinitions.js +124 -0
- package/dist/infrastructure/mcp/sddToolDefinitions.js.map +1 -0
- package/dist/utils/atomicWrite.d.ts +8 -35
- package/dist/utils/atomicWrite.js +12 -60
- package/dist/utils/atomicWrite.js.map +1 -1
- package/mcp-server.js +5 -2883
- package/package.json +5 -2
- package/scripts/context-usage-report.mjs +602 -0
- package/sdd-entry.js +17 -6
- package/skills/sdd-commit/REFERENCE.md +31 -0
- package/skills/sdd-commit/SKILL.md +17 -273
- package/skills/sdd-design/REFERENCE.md +35 -0
- package/skills/sdd-design/SKILL.md +19 -265
- package/skills/sdd-implement/REFERENCE.md +26 -0
- package/skills/sdd-implement/SKILL.md +22 -283
- package/skills/sdd-requirements/REFERENCE.md +31 -0
- package/skills/sdd-requirements/SKILL.md +23 -135
- package/skills/sdd-review/REFERENCE.md +26 -0
- package/skills/sdd-review/SKILL.md +17 -181
- package/skills/sdd-security-check/REFERENCE.md +19 -0
- package/skills/sdd-security-check/SKILL.md +18 -184
- package/skills/sdd-steering/REFERENCE.md +25 -0
- package/skills/sdd-steering/SKILL.md +18 -216
- package/skills/sdd-steering-custom/REFERENCE.md +27 -0
- package/skills/sdd-steering-custom/SKILL.md +19 -203
- package/skills/sdd-tasks/REFERENCE.md +25 -0
- package/skills/sdd-tasks/SKILL.md +19 -248
- package/skills/sdd-test-gen/REFERENCE.md +15 -0
- package/skills/sdd-test-gen/SKILL.md +17 -287
- package/skills/simple-task/REFERENCE.md +22 -0
- package/skills/simple-task/SKILL.md +17 -138
- package/templates/CLAUDE.md +18 -30
- package/rules/git-workflow.md +0 -92
- package/rules/sdd-workflow.md +0 -116
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { ROLE_MODEL_ROUTES, SKILL_AGENT_ROUTES, } from '../install-target.js';
|
|
3
4
|
import { validateChildName, validateDestinationPath } from '../utils/preserving-writer.js';
|
|
4
5
|
export class TargetInstallSession {
|
|
5
6
|
target;
|
|
6
7
|
projectRoot;
|
|
7
8
|
writer;
|
|
8
9
|
report;
|
|
9
|
-
constructor(target, projectRoot, writer) {
|
|
10
|
+
constructor(target, projectRoot, writer, profile, components, refreshGenerated = false) {
|
|
10
11
|
this.target = target;
|
|
11
12
|
this.projectRoot = projectRoot;
|
|
12
13
|
this.writer = writer;
|
|
13
|
-
this.report = { target, installed: [], skipped: [], failed: [] };
|
|
14
|
+
this.report = { target, installed: [], skipped: [], failed: [], conflicts: [] };
|
|
15
|
+
writer.beginTarget(target, profile, components, refreshGenerated);
|
|
14
16
|
}
|
|
15
17
|
resolve(configuredPath) {
|
|
16
18
|
return path.resolve(this.projectRoot, configuredPath);
|
|
@@ -22,8 +24,10 @@ export class TargetInstallSession {
|
|
|
22
24
|
async write(component, name, destination, content) {
|
|
23
25
|
try {
|
|
24
26
|
validateDestinationPath(this.projectRoot, destination);
|
|
25
|
-
const
|
|
26
|
-
this.report[outcome].push(this.label(destination));
|
|
27
|
+
const result = await this.writer.writeManaged(this.target, component, name, destination, content);
|
|
28
|
+
this.report[result.outcome].push(this.label(destination));
|
|
29
|
+
if (result.conflict)
|
|
30
|
+
this.report.conflicts.push(result.conflict);
|
|
27
31
|
}
|
|
28
32
|
catch (error) {
|
|
29
33
|
this.fail(component, name, destination, error);
|
|
@@ -31,9 +35,7 @@ export class TargetInstallSession {
|
|
|
31
35
|
}
|
|
32
36
|
async copy(component, name, source, destination) {
|
|
33
37
|
try {
|
|
34
|
-
|
|
35
|
-
const outcome = await this.writer.copyIfAbsent(source, destination);
|
|
36
|
-
this.report[outcome].push(this.label(destination));
|
|
38
|
+
await this.write(component, name, destination, await fs.promises.readFile(source, 'utf8'));
|
|
37
39
|
}
|
|
38
40
|
catch (error) {
|
|
39
41
|
this.fail(component, name, destination, error);
|
|
@@ -41,26 +43,12 @@ export class TargetInstallSession {
|
|
|
41
43
|
}
|
|
42
44
|
async copySkills(sourceManager, configuredPath) {
|
|
43
45
|
const destinationRoot = this.resolve(configuredPath);
|
|
44
|
-
const
|
|
45
|
-
for (const skill of skills) {
|
|
46
|
+
for (const skill of await sourceManager.listSkills()) {
|
|
46
47
|
try {
|
|
47
48
|
validateChildName(skill.name);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
for (const item of result.installed) {
|
|
52
|
-
this.report.installed.push(this.label(path.join(destination, item)));
|
|
53
|
-
}
|
|
54
|
-
for (const item of result.skipped ?? []) {
|
|
55
|
-
this.report.skipped.push(this.label(path.join(destination, item)));
|
|
56
|
-
}
|
|
57
|
-
for (const failure of result.failed) {
|
|
58
|
-
this.report.failed.push({
|
|
59
|
-
component: 'skills',
|
|
60
|
-
name: `${skill.name}/${failure.name}`,
|
|
61
|
-
path: failure.path ?? path.join(destination, failure.name),
|
|
62
|
-
error: failure.error,
|
|
63
|
-
});
|
|
49
|
+
await this.copySkillTree(skill.name, skill.path, path.join(destinationRoot, skill.name), '');
|
|
50
|
+
if (this.target === 'codex') {
|
|
51
|
+
await this.write('skills', `${skill.name}/agents/openai.yaml`, path.join(destinationRoot, skill.name, 'agents', 'openai.yaml'), renderCodexSkillPolicy(skill.name));
|
|
64
52
|
}
|
|
65
53
|
}
|
|
66
54
|
catch (error) {
|
|
@@ -90,6 +78,15 @@ export class TargetInstallSession {
|
|
|
90
78
|
await this.copy('steering', entry.name, path.join(source, entry.name), path.join(this.resolve(configuredPath), entry.name));
|
|
91
79
|
}
|
|
92
80
|
}
|
|
81
|
+
async complete() {
|
|
82
|
+
try {
|
|
83
|
+
this.report.conflicts.push(...await this.writer.finalizeTarget(this.target));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
this.fail('root', 'install-manifest.json', path.join(this.projectRoot, '.sdd-mcp/install-manifest.json'), error);
|
|
87
|
+
}
|
|
88
|
+
return this.report;
|
|
89
|
+
}
|
|
93
90
|
fail(component, name, destination, error) {
|
|
94
91
|
const failure = {
|
|
95
92
|
component,
|
|
@@ -99,6 +96,26 @@ export class TargetInstallSession {
|
|
|
99
96
|
};
|
|
100
97
|
this.report.failed.push(failure);
|
|
101
98
|
}
|
|
99
|
+
async copySkillTree(skillName, source, destination, relative) {
|
|
100
|
+
validateDestinationPath(this.projectRoot, destination);
|
|
101
|
+
const entries = await fs.promises.readdir(source, { withFileTypes: true });
|
|
102
|
+
for (const entry of entries) {
|
|
103
|
+
validateChildName(entry.name);
|
|
104
|
+
const sourcePath = path.join(source, entry.name);
|
|
105
|
+
const destinationPath = path.join(destination, entry.name);
|
|
106
|
+
const nested = relative ? `${relative}/${entry.name}` : entry.name;
|
|
107
|
+
if (entry.isDirectory()) {
|
|
108
|
+
await this.copySkillTree(skillName, sourcePath, destinationPath, nested);
|
|
109
|
+
}
|
|
110
|
+
else if (entry.isFile()) {
|
|
111
|
+
const sourceContent = await fs.promises.readFile(sourcePath, 'utf8');
|
|
112
|
+
const content = entry.name === 'SKILL.md'
|
|
113
|
+
? renderTargetSkill(this.target, skillName, sourceContent)
|
|
114
|
+
: sourceContent;
|
|
115
|
+
await this.write('skills', `${skillName}/${nested}`, destinationPath, content);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
102
119
|
}
|
|
103
120
|
export async function copyFlatComponents(session, component, configuredPath, descriptors) {
|
|
104
121
|
const destinationRoot = session.resolve(configuredPath);
|
|
@@ -106,11 +123,62 @@ export async function copyFlatComponents(session, component, configuredPath, des
|
|
|
106
123
|
const fileName = path.basename(descriptor.path);
|
|
107
124
|
try {
|
|
108
125
|
validateChildName(fileName);
|
|
109
|
-
await
|
|
126
|
+
const source = await fs.promises.readFile(descriptor.path, 'utf8');
|
|
127
|
+
const content = component === 'rules' ? renderTargetRule(session.target, fileName, source) : source;
|
|
128
|
+
await session.write(component, descriptor.name, path.join(destinationRoot, fileName), content);
|
|
110
129
|
}
|
|
111
130
|
catch (error) {
|
|
112
131
|
session.fail(component, descriptor.name, path.join(destinationRoot, fileName), error);
|
|
113
132
|
}
|
|
114
133
|
}
|
|
115
134
|
}
|
|
135
|
+
const RULE_SCOPES = {
|
|
136
|
+
'coding-style.md': ['**/*.{js,jsx,ts,tsx,py,go,rs,java,kt,c,cc,cpp,h,hpp}', '**/*.{json,yaml,yml,toml}'],
|
|
137
|
+
'error-handling.md': ['**/*.{js,jsx,ts,tsx,py,go,rs,java,kt,c,cc,cpp,h,hpp}'],
|
|
138
|
+
'security.md': ['**/*.{js,jsx,ts,tsx,py,go,rs,java,kt,c,cc,cpp,h,hpp,json,yaml,yml,toml}'],
|
|
139
|
+
'testing.md': ['**/{test,tests,spec,__tests__}/**/*', '**/*.{test,spec}.{js,jsx,ts,tsx,py}', '**/src/**/*'],
|
|
140
|
+
};
|
|
141
|
+
export function renderTargetRule(target, fileName, source) {
|
|
142
|
+
const globs = RULE_SCOPES[fileName] ?? ['**/*'];
|
|
143
|
+
const body = stripFrontmatter(source).trim();
|
|
144
|
+
if (target === 'claude-code') {
|
|
145
|
+
return `---\npaths:\n${globs.map(glob => ` - ${JSON.stringify(glob)}`).join('\n')}\n---\n\n${body}\n`;
|
|
146
|
+
}
|
|
147
|
+
if (target === 'omp') {
|
|
148
|
+
return `---\ndescription: SDD ${path.basename(fileName, '.md')} guidance\nglobs:\n${globs.map(glob => ` - ${JSON.stringify(glob)}`).join('\n')}\nalwaysApply: false\n---\n\n${body}\n`;
|
|
149
|
+
}
|
|
150
|
+
return `${body}\n`;
|
|
151
|
+
}
|
|
152
|
+
export function renderTargetSkill(target, skillName, source) {
|
|
153
|
+
const role = SKILL_AGENT_ROUTES[skillName];
|
|
154
|
+
const extra = ['disable-model-invocation: true'];
|
|
155
|
+
let execution = '';
|
|
156
|
+
if (role && target === 'claude-code') {
|
|
157
|
+
extra.push(`model: ${ROLE_MODEL_ROUTES[role].claudeCode.model}`);
|
|
158
|
+
execution = '\nExecute in this turn; do not spawn a second specialist.\n';
|
|
159
|
+
}
|
|
160
|
+
else if (role && target === 'omp' && ROLE_MODEL_ROUTES[role].taskClass === 'advisor') {
|
|
161
|
+
execution = `\nRun inline by default. The project advisor at .omp/agents/${role}.md is explicit opt-in only; if the user invokes it, allow one specialistDepth: 1 handoff without nesting or retry.\n`;
|
|
162
|
+
}
|
|
163
|
+
else if (role && target === 'codex' && ROLE_MODEL_ROUTES[role].taskClass === 'advisor') {
|
|
164
|
+
execution = `\nRequest the configured ${role} custom agent once with specialistDepth: 1; nested delegation is prohibited. If unavailable, record the fallback and continue inline.\n`;
|
|
165
|
+
}
|
|
166
|
+
const match = source.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
|
|
167
|
+
if (!match)
|
|
168
|
+
return `---\n${extra.join('\n')}\n---\n\n${source.trim()}${execution}\n`;
|
|
169
|
+
const metadata = match[1].split(/\r?\n/).filter(line => !/^(disable-model-invocation|model):/.test(line));
|
|
170
|
+
return `---\n${metadata.join('\n')}\n${extra.join('\n')}\n---\n\n${match[2].trim()}${execution}\n`;
|
|
171
|
+
}
|
|
172
|
+
function renderCodexSkillPolicy(skillName) {
|
|
173
|
+
const role = SKILL_AGENT_ROUTES[skillName];
|
|
174
|
+
const route = role ? ROLE_MODEL_ROUTES[role] : undefined;
|
|
175
|
+
const description = route?.taskClass === 'advisor'
|
|
176
|
+
? `Explicitly invoke the configured ${role} agent once; nested delegation is prohibited.`
|
|
177
|
+
: 'Execute inline in the current turn.';
|
|
178
|
+
return `policy:\n allow_implicit_invocation: false\ninterface:\n description: ${JSON.stringify(description)}\n`;
|
|
179
|
+
}
|
|
180
|
+
function stripFrontmatter(content) {
|
|
181
|
+
const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?([\s\S]*)$/);
|
|
182
|
+
return match ? match[1] : content;
|
|
183
|
+
}
|
|
116
184
|
//# sourceMappingURL=target-installer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target-installer.js","sourceRoot":"","sources":["../../../src/cli/tool-support/target-installer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"target-installer.js","sourceRoot":"","sources":["../../../src/cli/tool-support/target-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
import type { InstallResult } from '../../shared/BaseManager.js';
|
|
2
|
+
import type { ComponentType, InstallConflict, InstallProfile, InstallTarget } from '../install-target.js';
|
|
2
3
|
export type WriteOutcome = 'installed' | 'skipped';
|
|
4
|
+
export interface ManagedWriteResult {
|
|
5
|
+
outcome: WriteOutcome;
|
|
6
|
+
conflict?: InstallConflict;
|
|
7
|
+
}
|
|
8
|
+
/** Explicit v3.5.1 package-owned files which v4 no longer renders. */
|
|
9
|
+
export declare const LEGACY_V351_TOMBSTONES: Readonly<Record<InstallTarget, readonly string[]>>;
|
|
3
10
|
export declare function validateChildName(name: string): void;
|
|
4
11
|
export declare function validateDestinationPath(projectRoot: string, destination: string): void;
|
|
5
12
|
export declare class PreservingWriter {
|
|
6
13
|
private readonly projectRoot;
|
|
14
|
+
private readonly generated;
|
|
15
|
+
private readonly profiles;
|
|
16
|
+
private readonly selectedComponents;
|
|
17
|
+
private readonly refreshTargets;
|
|
18
|
+
private readonly pendingShared;
|
|
19
|
+
private backupStamp?;
|
|
7
20
|
constructor(projectRoot: string);
|
|
21
|
+
beginTarget(target: InstallTarget, profile: InstallProfile, components: readonly ComponentType[], refreshGenerated?: boolean): void;
|
|
22
|
+
writeManaged(target: InstallTarget, component: ComponentType | 'root', name: string, filePath: string, content: string): Promise<ManagedWriteResult>;
|
|
23
|
+
finalizeTarget(target: InstallTarget): Promise<InstallConflict[]>;
|
|
24
|
+
recordShared(filePath: string, component: 'steering' | 'gitignore', mutable: boolean): Promise<void>;
|
|
8
25
|
writeIfAbsent(filePath: string, content: string): Promise<WriteOutcome>;
|
|
9
26
|
copyIfAbsent(source: string, destination: string): Promise<WriteOutcome>;
|
|
10
27
|
copyTreePreserving(source: string, destination: string): Promise<InstallResult>;
|
|
11
28
|
private copyTree;
|
|
29
|
+
private generatedFor;
|
|
30
|
+
private backup;
|
|
31
|
+
private get manifestPath();
|
|
32
|
+
private readManifest;
|
|
33
|
+
private relative;
|
|
12
34
|
private validateDestination;
|
|
13
35
|
}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
|
+
import * as crypto from 'crypto';
|
|
1
2
|
import * as fs from 'fs';
|
|
2
3
|
import * as path from 'path';
|
|
4
|
+
import { setTimeout as delay } from 'timers/promises';
|
|
5
|
+
import { atomicWriteFile } from '../../utils/atomicWrite.js';
|
|
6
|
+
const MANIFEST_SCHEMA_VERSION = 1;
|
|
7
|
+
const RENDERER_VERSION = 4;
|
|
8
|
+
const PACKAGE_VERSION = '4.0.0';
|
|
9
|
+
/** Explicit v3.5.1 package-owned files which v4 no longer renders. */
|
|
10
|
+
export const LEGACY_V351_TOMBSTONES = {
|
|
11
|
+
'claude-code': ['.claude/rules/git-workflow.md', '.claude/rules/sdd-workflow.md'],
|
|
12
|
+
codex: ['.codex/guidance/rules/git-workflow.md', '.codex/guidance/rules/sdd-workflow.md'],
|
|
13
|
+
omp: [],
|
|
14
|
+
};
|
|
3
15
|
export function validateChildName(name) {
|
|
4
16
|
if (!name || name === '.' || name === '..' || name.includes('/') || name.includes('\\')) {
|
|
5
17
|
throw new Error(`Unsafe generated child name: ${name}`);
|
|
@@ -33,9 +45,131 @@ export function validateDestinationPath(projectRoot, destination) {
|
|
|
33
45
|
}
|
|
34
46
|
export class PreservingWriter {
|
|
35
47
|
projectRoot;
|
|
48
|
+
generated = new Map();
|
|
49
|
+
profiles = new Map();
|
|
50
|
+
selectedComponents = new Map();
|
|
51
|
+
refreshTargets = new Set();
|
|
52
|
+
pendingShared = new Map();
|
|
53
|
+
backupStamp;
|
|
36
54
|
constructor(projectRoot) {
|
|
37
55
|
this.projectRoot = projectRoot;
|
|
38
56
|
}
|
|
57
|
+
beginTarget(target, profile, components, refreshGenerated = false) {
|
|
58
|
+
this.generated.set(target, new Map());
|
|
59
|
+
this.profiles.set(target, profile);
|
|
60
|
+
this.selectedComponents.set(target, new Set([...components, 'root']));
|
|
61
|
+
if (refreshGenerated)
|
|
62
|
+
this.refreshTargets.add(target);
|
|
63
|
+
}
|
|
64
|
+
async writeManaged(target, component, name, filePath, content) {
|
|
65
|
+
this.validateDestination(filePath);
|
|
66
|
+
const relative = this.relative(filePath);
|
|
67
|
+
const desiredHash = sha256(content);
|
|
68
|
+
const manifest = await this.readManifest();
|
|
69
|
+
const exists = await pathExists(filePath);
|
|
70
|
+
if (component === 'steering') {
|
|
71
|
+
if (!exists) {
|
|
72
|
+
await atomicWriteFile(filePath, content);
|
|
73
|
+
this.pendingShared.set(relative, { sha256: desiredHash, component: 'steering', mutable: true });
|
|
74
|
+
return { outcome: 'installed' };
|
|
75
|
+
}
|
|
76
|
+
const existingHash = sha256(await fs.promises.readFile(filePath));
|
|
77
|
+
this.pendingShared.set(relative, { sha256: existingHash, component: 'steering', mutable: true });
|
|
78
|
+
return { outcome: 'skipped' };
|
|
79
|
+
}
|
|
80
|
+
this.generatedFor(target).set(relative, { sha256: desiredHash, component });
|
|
81
|
+
const prior = manifest.targets[target]?.files[relative];
|
|
82
|
+
if (!exists) {
|
|
83
|
+
await atomicWriteFile(filePath, content);
|
|
84
|
+
return { outcome: 'installed' };
|
|
85
|
+
}
|
|
86
|
+
const existing = await fs.promises.readFile(filePath, 'utf8');
|
|
87
|
+
const existingHash = sha256(existing);
|
|
88
|
+
if (existingHash === desiredHash)
|
|
89
|
+
return { outcome: 'skipped' };
|
|
90
|
+
if (this.refreshTargets.has(target)) {
|
|
91
|
+
await this.backup(target, relative, filePath);
|
|
92
|
+
await atomicWriteFile(filePath, content);
|
|
93
|
+
return { outcome: 'installed' };
|
|
94
|
+
}
|
|
95
|
+
if (prior && existingHash === prior.sha256) {
|
|
96
|
+
await atomicWriteFile(filePath, content);
|
|
97
|
+
return { outcome: 'installed' };
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
outcome: 'skipped',
|
|
101
|
+
conflict: {
|
|
102
|
+
component,
|
|
103
|
+
name,
|
|
104
|
+
path: filePath,
|
|
105
|
+
reason: prior ? 'modified' : 'legacy-unmanaged',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
async finalizeTarget(target) {
|
|
110
|
+
this.validateDestination(this.manifestPath);
|
|
111
|
+
return withManifestLock(this.projectRoot, async () => {
|
|
112
|
+
const conflicts = [];
|
|
113
|
+
const manifest = await this.readManifest();
|
|
114
|
+
const previous = manifest.targets[target]?.files ?? {};
|
|
115
|
+
const generated = this.generatedFor(target);
|
|
116
|
+
const selected = this.selectedComponents.get(target) ?? new Set();
|
|
117
|
+
for (const [relative, record] of Object.entries(previous)) {
|
|
118
|
+
if (generated.has(relative) || !selected.has(record.component))
|
|
119
|
+
continue;
|
|
120
|
+
const destination = path.join(this.projectRoot, relative);
|
|
121
|
+
if (!await pathExists(destination))
|
|
122
|
+
continue;
|
|
123
|
+
this.validateDestination(destination);
|
|
124
|
+
const currentHash = sha256(await fs.promises.readFile(destination));
|
|
125
|
+
if (currentHash !== record.sha256 && !this.refreshTargets.has(target)) {
|
|
126
|
+
conflicts.push({
|
|
127
|
+
component: record.component,
|
|
128
|
+
name: path.basename(relative),
|
|
129
|
+
path: destination,
|
|
130
|
+
reason: 'obsolete-modified',
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
await this.backup(target, relative, destination);
|
|
135
|
+
await fs.promises.rm(destination, { force: true });
|
|
136
|
+
}
|
|
137
|
+
if (this.refreshTargets.has(target)) {
|
|
138
|
+
for (const relative of LEGACY_V351_TOMBSTONES[target]) {
|
|
139
|
+
if (generated.has(relative))
|
|
140
|
+
continue;
|
|
141
|
+
const destination = path.join(this.projectRoot, relative);
|
|
142
|
+
if (!await pathExists(destination))
|
|
143
|
+
continue;
|
|
144
|
+
this.validateDestination(destination);
|
|
145
|
+
await this.backup(target, relative, destination);
|
|
146
|
+
await fs.promises.rm(destination, { force: true });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const latest = await this.readManifest();
|
|
150
|
+
latest.targets[target] = {
|
|
151
|
+
profile: this.profiles.get(target) ?? 'lean',
|
|
152
|
+
packageVersion: PACKAGE_VERSION,
|
|
153
|
+
rendererVersion: RENDERER_VERSION,
|
|
154
|
+
files: Object.fromEntries(generated),
|
|
155
|
+
};
|
|
156
|
+
Object.assign(latest.shared, Object.fromEntries(this.pendingShared));
|
|
157
|
+
await atomicWriteFile(this.manifestPath, `${JSON.stringify(latest, null, 2)}\n`);
|
|
158
|
+
return conflicts;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async recordShared(filePath, component, mutable) {
|
|
162
|
+
this.validateDestination(filePath);
|
|
163
|
+
if (!await pathExists(filePath))
|
|
164
|
+
return;
|
|
165
|
+
const relative = this.relative(filePath);
|
|
166
|
+
const digest = sha256(await fs.promises.readFile(filePath));
|
|
167
|
+
await withManifestLock(this.projectRoot, async () => {
|
|
168
|
+
const manifest = await this.readManifest();
|
|
169
|
+
manifest.shared[relative] = { sha256: digest, component, mutable };
|
|
170
|
+
await atomicWriteFile(this.manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
39
173
|
async writeIfAbsent(filePath, content) {
|
|
40
174
|
this.validateDestination(filePath);
|
|
41
175
|
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
@@ -50,17 +184,7 @@ export class PreservingWriter {
|
|
|
50
184
|
}
|
|
51
185
|
}
|
|
52
186
|
async copyIfAbsent(source, destination) {
|
|
53
|
-
this.
|
|
54
|
-
await fs.promises.mkdir(path.dirname(destination), { recursive: true });
|
|
55
|
-
try {
|
|
56
|
-
await fs.promises.copyFile(source, destination, fs.constants.COPYFILE_EXCL);
|
|
57
|
-
return 'installed';
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
if (isAlreadyExists(error))
|
|
61
|
-
return 'skipped';
|
|
62
|
-
throw error;
|
|
63
|
-
}
|
|
187
|
+
return this.writeIfAbsent(destination, await fs.promises.readFile(source, 'utf8'));
|
|
64
188
|
}
|
|
65
189
|
async copyTreePreserving(source, destination) {
|
|
66
190
|
const result = { installed: [], skipped: [], failed: [] };
|
|
@@ -93,10 +217,108 @@ export class PreservingWriter {
|
|
|
93
217
|
}
|
|
94
218
|
}
|
|
95
219
|
}
|
|
220
|
+
generatedFor(target) {
|
|
221
|
+
let files = this.generated.get(target);
|
|
222
|
+
if (!files) {
|
|
223
|
+
files = new Map();
|
|
224
|
+
this.generated.set(target, files);
|
|
225
|
+
}
|
|
226
|
+
return files;
|
|
227
|
+
}
|
|
228
|
+
async backup(target, relative, source) {
|
|
229
|
+
this.backupStamp ??= new Date().toISOString().replace(/[:.]/g, '-');
|
|
230
|
+
const destination = path.join(this.projectRoot, '.sdd-mcp', 'backups', this.backupStamp, target, relative);
|
|
231
|
+
this.validateDestination(destination);
|
|
232
|
+
await fs.promises.mkdir(path.dirname(destination), { recursive: true });
|
|
233
|
+
await fs.promises.copyFile(source, destination);
|
|
234
|
+
}
|
|
235
|
+
get manifestPath() {
|
|
236
|
+
return path.join(this.projectRoot, '.sdd-mcp', 'install-manifest.json');
|
|
237
|
+
}
|
|
238
|
+
async readManifest() {
|
|
239
|
+
try {
|
|
240
|
+
const parsed = JSON.parse(await fs.promises.readFile(this.manifestPath, 'utf8'));
|
|
241
|
+
if (parsed.schemaVersion !== MANIFEST_SCHEMA_VERSION || !parsed.targets || !parsed.shared) {
|
|
242
|
+
throw new Error('Unsupported install manifest schema');
|
|
243
|
+
}
|
|
244
|
+
return parsed;
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
if (!isMissing(error))
|
|
248
|
+
throw error;
|
|
249
|
+
return { schemaVersion: MANIFEST_SCHEMA_VERSION, targets: {}, shared: {} };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
relative(filePath) {
|
|
253
|
+
return path.relative(this.projectRoot, filePath).split(path.sep).join('/');
|
|
254
|
+
}
|
|
96
255
|
validateDestination(destination) {
|
|
97
256
|
validateDestinationPath(this.projectRoot, destination);
|
|
98
257
|
}
|
|
99
258
|
}
|
|
259
|
+
const MANIFEST_LOCKS = new Map();
|
|
260
|
+
async function withManifestLock(root, action) {
|
|
261
|
+
const key = path.resolve(root);
|
|
262
|
+
const previous = MANIFEST_LOCKS.get(key) ?? Promise.resolve();
|
|
263
|
+
const run = previous.catch(() => undefined).then(async () => {
|
|
264
|
+
const releaseFilesystemLock = await acquireFilesystemLock(root);
|
|
265
|
+
try {
|
|
266
|
+
return await action();
|
|
267
|
+
}
|
|
268
|
+
finally {
|
|
269
|
+
await releaseFilesystemLock();
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
const settled = run.then(() => undefined, () => undefined);
|
|
273
|
+
MANIFEST_LOCKS.set(key, settled);
|
|
274
|
+
try {
|
|
275
|
+
return await run;
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
if (MANIFEST_LOCKS.get(key) === settled)
|
|
279
|
+
MANIFEST_LOCKS.delete(key);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async function acquireFilesystemLock(root) {
|
|
283
|
+
const lockPath = path.join(root, '.sdd-mcp', 'install-manifest.lock');
|
|
284
|
+
validateDestinationPath(root, lockPath);
|
|
285
|
+
await fs.promises.mkdir(path.dirname(lockPath), { recursive: true });
|
|
286
|
+
for (let attempt = 0; attempt < 100; attempt += 1) {
|
|
287
|
+
try {
|
|
288
|
+
const handle = await fs.promises.open(lockPath, 'wx');
|
|
289
|
+
await handle.writeFile(`${process.pid}\n`);
|
|
290
|
+
await handle.close();
|
|
291
|
+
return async () => {
|
|
292
|
+
await fs.promises.rm(lockPath, { force: true });
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
catch (error) {
|
|
296
|
+
if (!isAlreadyExists(error))
|
|
297
|
+
throw error;
|
|
298
|
+
const stats = await fs.promises.stat(lockPath).catch(() => undefined);
|
|
299
|
+
if (stats && Date.now() - stats.mtimeMs > 30_000) {
|
|
300
|
+
await fs.promises.rm(lockPath, { force: true });
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
await delay(20);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
throw new Error(`Timed out acquiring install manifest lock: ${lockPath}`);
|
|
307
|
+
}
|
|
308
|
+
function sha256(content) {
|
|
309
|
+
return crypto.createHash('sha256').update(content).digest('hex');
|
|
310
|
+
}
|
|
311
|
+
async function pathExists(filePath) {
|
|
312
|
+
try {
|
|
313
|
+
await fs.promises.access(filePath);
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (isMissing(error))
|
|
318
|
+
return false;
|
|
319
|
+
throw error;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
100
322
|
function isMissing(error) {
|
|
101
323
|
return typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT';
|
|
102
324
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preserving-writer.js","sourceRoot":"","sources":["../../../src/cli/utils/preserving-writer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preserving-writer.js","sourceRoot":"","sources":["../../../src/cli/utils/preserving-writer.ts"],"names":[],"mappings":"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"}
|
package/dist/domain/ports.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export interface ProjectRepository {
|
|
|
9
9
|
export interface FileSystemPort {
|
|
10
10
|
readFile(path: string): Promise<string>;
|
|
11
11
|
writeFile(path: string, content: string): Promise<void>;
|
|
12
|
+
/** Atomically replaces a destination; implementations serialize writes per path. */
|
|
13
|
+
writeFileAtomic?(path: string, content: string): Promise<void>;
|
|
12
14
|
exists(path: string): Promise<boolean>;
|
|
13
15
|
mkdir(path: string): Promise<void>;
|
|
14
16
|
readdir(path: string): Promise<string[]>;
|
|
@@ -16,6 +18,8 @@ export interface FileSystemPort {
|
|
|
16
18
|
isFile(): boolean;
|
|
17
19
|
isDirectory(): boolean;
|
|
18
20
|
}>;
|
|
21
|
+
realpath?(path: string): Promise<string>;
|
|
22
|
+
unlink?(path: string): Promise<void>;
|
|
19
23
|
}
|
|
20
24
|
export interface TemplateEngine {
|
|
21
25
|
compile(template: string): Promise<TemplateFunction>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
import type { Container } from 'inversify';
|
|
4
|
+
import type { LoggerPort } from './domain/ports.js';
|
|
5
|
+
import { MCPServer } from './infrastructure/mcp/MCPServer.js';
|
|
6
|
+
import { PluginManager } from './infrastructure/plugins/PluginManager.js';
|
|
7
|
+
import { HookSystem } from './infrastructure/plugins/HookSystem.js';
|
|
8
|
+
import { PluginToolRegistry } from './infrastructure/plugins/PluginToolRegistry.js';
|
|
9
|
+
import { PluginSteeringRegistry } from './infrastructure/plugins/PluginSteeringRegistry.js';
|
|
10
|
+
export interface SDDMCPRuntime {
|
|
11
|
+
container: Container;
|
|
11
12
|
logger: LoggerPort;
|
|
12
13
|
mcpServer: MCPServer;
|
|
13
14
|
pluginManager: PluginManager;
|
|
@@ -16,4 +17,6 @@ export declare function createMCPServer(): Promise<{
|
|
|
16
17
|
steeringRegistry: PluginSteeringRegistry;
|
|
17
18
|
initialize(): Promise<void>;
|
|
18
19
|
close(): Promise<void>;
|
|
19
|
-
}
|
|
20
|
+
}
|
|
21
|
+
export declare function createMCPServer(): Promise<SDDMCPRuntime>;
|
|
22
|
+
export declare function startMCPServer(): Promise<SDDMCPRuntime>;
|