sdd-mcp-server 1.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/LICENSE +21 -0
- package/README.md +256 -0
- package/dist/__tests__/setup.d.ts +44 -0
- package/dist/__tests__/setup.js +178 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/test-helpers/mock-factories.d.ts +26 -0
- package/dist/__tests__/test-helpers/mock-factories.js +466 -0
- package/dist/__tests__/test-helpers/mock-factories.js.map +1 -0
- package/dist/adapters/cli/SDDToolAdapter.d.ts +26 -0
- package/dist/adapters/cli/SDDToolAdapter.js +273 -0
- package/dist/adapters/cli/SDDToolAdapter.js.map +1 -0
- package/dist/application/services/CodebaseAnalysisService.d.ts +38 -0
- package/dist/application/services/CodebaseAnalysisService.js +737 -0
- package/dist/application/services/CodebaseAnalysisService.js.map +1 -0
- package/dist/application/services/LocalizationService.d.ts +184 -0
- package/dist/application/services/LocalizationService.js +536 -0
- package/dist/application/services/LocalizationService.js.map +1 -0
- package/dist/application/services/ProjectContextService.d.ts +61 -0
- package/dist/application/services/ProjectContextService.js +550 -0
- package/dist/application/services/ProjectContextService.js.map +1 -0
- package/dist/application/services/ProjectInitializationService.d.ts +57 -0
- package/dist/application/services/ProjectInitializationService.js +485 -0
- package/dist/application/services/ProjectInitializationService.js.map +1 -0
- package/dist/application/services/ProjectService.d.ts +19 -0
- package/dist/application/services/ProjectService.js +159 -0
- package/dist/application/services/ProjectService.js.map +1 -0
- package/dist/application/services/QualityGateService.d.ts +62 -0
- package/dist/application/services/QualityGateService.js +428 -0
- package/dist/application/services/QualityGateService.js.map +1 -0
- package/dist/application/services/QualityService.d.ts +43 -0
- package/dist/application/services/QualityService.js +245 -0
- package/dist/application/services/QualityService.js.map +1 -0
- package/dist/application/services/SteeringDocumentService.d.ts +62 -0
- package/dist/application/services/SteeringDocumentService.js +694 -0
- package/dist/application/services/SteeringDocumentService.js.map +1 -0
- package/dist/application/services/TemplateService.d.ts +47 -0
- package/dist/application/services/TemplateService.js +438 -0
- package/dist/application/services/TemplateService.js.map +1 -0
- package/dist/application/services/WorkflowEngineService.d.ts +56 -0
- package/dist/application/services/WorkflowEngineService.js +348 -0
- package/dist/application/services/WorkflowEngineService.js.map +1 -0
- package/dist/application/services/WorkflowService.d.ts +22 -0
- package/dist/application/services/WorkflowService.js +147 -0
- package/dist/application/services/WorkflowService.js.map +1 -0
- package/dist/application/services/WorkflowValidationService.d.ts +51 -0
- package/dist/application/services/WorkflowValidationService.js +665 -0
- package/dist/application/services/WorkflowValidationService.js.map +1 -0
- package/dist/domain/context/ProjectContext.d.ts +350 -0
- package/dist/domain/context/ProjectContext.js +138 -0
- package/dist/domain/context/ProjectContext.js.map +1 -0
- package/dist/domain/i18n/index.d.ts +286 -0
- package/dist/domain/i18n/index.js +97 -0
- package/dist/domain/i18n/index.js.map +1 -0
- package/dist/domain/plugins/index.d.ts +498 -0
- package/dist/domain/plugins/index.js +157 -0
- package/dist/domain/plugins/index.js.map +1 -0
- package/dist/domain/ports.d.ts +54 -0
- package/dist/domain/ports.js +3 -0
- package/dist/domain/ports.js.map +1 -0
- package/dist/domain/quality/index.d.ts +361 -0
- package/dist/domain/quality/index.js +113 -0
- package/dist/domain/quality/index.js.map +1 -0
- package/dist/domain/services/DomainService.d.ts +18 -0
- package/dist/domain/services/DomainService.js +71 -0
- package/dist/domain/services/DomainService.js.map +1 -0
- package/dist/domain/templates/index.d.ts +158 -0
- package/dist/domain/templates/index.js +22 -0
- package/dist/domain/templates/index.js.map +1 -0
- package/dist/domain/types.d.ts +115 -0
- package/dist/domain/types.js +37 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/domain/workflow/WorkflowStateMachine.d.ts +62 -0
- package/dist/domain/workflow/WorkflowStateMachine.js +286 -0
- package/dist/domain/workflow/WorkflowStateMachine.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/adapters/AjvValidationAdapter.d.ts +7 -0
- package/dist/infrastructure/adapters/AjvValidationAdapter.js +37 -0
- package/dist/infrastructure/adapters/AjvValidationAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/ConsoleLoggerAdapter.d.ts +8 -0
- package/dist/infrastructure/adapters/ConsoleLoggerAdapter.js +41 -0
- package/dist/infrastructure/adapters/ConsoleLoggerAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/FileBasedTaskTracker.d.ts +9 -0
- package/dist/infrastructure/adapters/FileBasedTaskTracker.js +41 -0
- package/dist/infrastructure/adapters/FileBasedTaskTracker.js.map +1 -0
- package/dist/infrastructure/adapters/HandlebarsTemplateEngine.d.ts +8 -0
- package/dist/infrastructure/adapters/HandlebarsTemplateEngine.js +38 -0
- package/dist/infrastructure/adapters/HandlebarsTemplateEngine.js.map +1 -0
- package/dist/infrastructure/adapters/JsonConfigurationAdapter.d.ts +7 -0
- package/dist/infrastructure/adapters/JsonConfigurationAdapter.js +24 -0
- package/dist/infrastructure/adapters/JsonConfigurationAdapter.js.map +1 -0
- package/dist/infrastructure/adapters/LinusQualityAnalyzer.d.ts +9 -0
- package/dist/infrastructure/adapters/LinusQualityAnalyzer.js +75 -0
- package/dist/infrastructure/adapters/LinusQualityAnalyzer.js.map +1 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.d.ts +12 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js +39 -0
- package/dist/infrastructure/adapters/NodeFileSystemAdapter.js.map +1 -0
- package/dist/infrastructure/di/container.d.ts +3 -0
- package/dist/infrastructure/di/container.js +98 -0
- package/dist/infrastructure/di/container.js.map +1 -0
- package/dist/infrastructure/di/types.d.ts +39 -0
- package/dist/infrastructure/di/types.js +45 -0
- package/dist/infrastructure/di/types.js.map +1 -0
- package/dist/infrastructure/i18n/I18nextService.d.ts +27 -0
- package/dist/infrastructure/i18n/I18nextService.js +357 -0
- package/dist/infrastructure/i18n/I18nextService.js.map +1 -0
- package/dist/infrastructure/mcp/CapabilityNegotiator.d.ts +21 -0
- package/dist/infrastructure/mcp/CapabilityNegotiator.js +75 -0
- package/dist/infrastructure/mcp/CapabilityNegotiator.js.map +1 -0
- package/dist/infrastructure/mcp/ErrorHandler.d.ts +29 -0
- package/dist/infrastructure/mcp/ErrorHandler.js +101 -0
- package/dist/infrastructure/mcp/ErrorHandler.js.map +1 -0
- package/dist/infrastructure/mcp/MCPServer.d.ts +25 -0
- package/dist/infrastructure/mcp/MCPServer.js +246 -0
- package/dist/infrastructure/mcp/MCPServer.js.map +1 -0
- package/dist/infrastructure/mcp/PromptManager.d.ts +18 -0
- package/dist/infrastructure/mcp/PromptManager.js +373 -0
- package/dist/infrastructure/mcp/PromptManager.js.map +1 -0
- package/dist/infrastructure/mcp/ResourceManager.d.ts +15 -0
- package/dist/infrastructure/mcp/ResourceManager.js +229 -0
- package/dist/infrastructure/mcp/ResourceManager.js.map +1 -0
- package/dist/infrastructure/mcp/SessionManager.d.ts +64 -0
- package/dist/infrastructure/mcp/SessionManager.js +221 -0
- package/dist/infrastructure/mcp/SessionManager.js.map +1 -0
- package/dist/infrastructure/mcp/ToolRegistry.d.ts +48 -0
- package/dist/infrastructure/mcp/ToolRegistry.js +235 -0
- package/dist/infrastructure/mcp/ToolRegistry.js.map +1 -0
- package/dist/infrastructure/platform/PlatformAdapter.d.ts +46 -0
- package/dist/infrastructure/platform/PlatformAdapter.js +355 -0
- package/dist/infrastructure/platform/PlatformAdapter.js.map +1 -0
- package/dist/infrastructure/plugins/HookSystem.d.ts +40 -0
- package/dist/infrastructure/plugins/HookSystem.js +415 -0
- package/dist/infrastructure/plugins/HookSystem.js.map +1 -0
- package/dist/infrastructure/plugins/PluginManager.d.ts +51 -0
- package/dist/infrastructure/plugins/PluginManager.js +650 -0
- package/dist/infrastructure/plugins/PluginManager.js.map +1 -0
- package/dist/infrastructure/plugins/PluginSteeringRegistry.d.ts +63 -0
- package/dist/infrastructure/plugins/PluginSteeringRegistry.js +439 -0
- package/dist/infrastructure/plugins/PluginSteeringRegistry.js.map +1 -0
- package/dist/infrastructure/plugins/PluginToolRegistry.d.ts +54 -0
- package/dist/infrastructure/plugins/PluginToolRegistry.js +490 -0
- package/dist/infrastructure/plugins/PluginToolRegistry.js.map +1 -0
- package/dist/infrastructure/quality/ASTAnalyzer.d.ts +65 -0
- package/dist/infrastructure/quality/ASTAnalyzer.js +439 -0
- package/dist/infrastructure/quality/ASTAnalyzer.js.map +1 -0
- package/dist/infrastructure/quality/LinusCodeReviewer.d.ts +52 -0
- package/dist/infrastructure/quality/LinusCodeReviewer.js +551 -0
- package/dist/infrastructure/quality/LinusCodeReviewer.js.map +1 -0
- package/dist/infrastructure/repositories/InMemoryProjectRepository.d.ts +10 -0
- package/dist/infrastructure/repositories/InMemoryProjectRepository.js +35 -0
- package/dist/infrastructure/repositories/InMemoryProjectRepository.js.map +1 -0
- package/dist/infrastructure/schemas/project.schema.d.ts +192 -0
- package/dist/infrastructure/schemas/project.schema.js +114 -0
- package/dist/infrastructure/schemas/project.schema.js.map +1 -0
- package/dist/infrastructure/templates/FileGenerator.d.ts +15 -0
- package/dist/infrastructure/templates/FileGenerator.js +385 -0
- package/dist/infrastructure/templates/FileGenerator.js.map +1 -0
- package/dist/infrastructure/templates/HandlebarsRenderer.d.ts +16 -0
- package/dist/infrastructure/templates/HandlebarsRenderer.js +252 -0
- package/dist/infrastructure/templates/HandlebarsRenderer.js.map +1 -0
- package/dist/infrastructure/templates/TemplateManager.d.ts +36 -0
- package/dist/infrastructure/templates/TemplateManager.js +777 -0
- package/dist/infrastructure/templates/TemplateManager.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,777 @@
|
|
|
1
|
+
// Template library and management system implementation
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
import { injectable, inject } from 'inversify';
|
|
15
|
+
import { promises as fs } from 'fs';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import { TYPES } from '../di/types.js';
|
|
18
|
+
let TemplateManager = class TemplateManager {
|
|
19
|
+
logger;
|
|
20
|
+
renderer;
|
|
21
|
+
templateCache = new Map();
|
|
22
|
+
templateDirectory;
|
|
23
|
+
cacheInitialized = false;
|
|
24
|
+
constructor(logger, renderer, templateDirectory = './templates') {
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
this.renderer = renderer;
|
|
27
|
+
this.templateDirectory = path.resolve(templateDirectory);
|
|
28
|
+
}
|
|
29
|
+
async getTemplate(id) {
|
|
30
|
+
await this.ensureCacheInitialized();
|
|
31
|
+
const template = this.templateCache.get(id);
|
|
32
|
+
if (template) {
|
|
33
|
+
this.logger.debug('Template retrieved from cache', { id });
|
|
34
|
+
return template;
|
|
35
|
+
}
|
|
36
|
+
// Try to load from disk if not in cache
|
|
37
|
+
try {
|
|
38
|
+
const template = await this.loadTemplateFromDisk(id);
|
|
39
|
+
if (template) {
|
|
40
|
+
this.templateCache.set(id, template);
|
|
41
|
+
this.logger.debug('Template loaded from disk', { id });
|
|
42
|
+
return template;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.logger.error('Failed to load template from disk', {
|
|
47
|
+
id,
|
|
48
|
+
error: error instanceof Error ? error.message : String(error)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
async getTemplatesByCategory(category) {
|
|
54
|
+
await this.ensureCacheInitialized();
|
|
55
|
+
const templates = Array.from(this.templateCache.values())
|
|
56
|
+
.filter(template => template.category === category)
|
|
57
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
58
|
+
this.logger.debug('Templates retrieved by category', { category, count: templates.length });
|
|
59
|
+
return templates;
|
|
60
|
+
}
|
|
61
|
+
async searchTemplates(query, tags) {
|
|
62
|
+
await this.ensureCacheInitialized();
|
|
63
|
+
const queryLower = query.toLowerCase();
|
|
64
|
+
const templates = Array.from(this.templateCache.values()).filter(template => {
|
|
65
|
+
const matchesQuery = template.name.toLowerCase().includes(queryLower) ||
|
|
66
|
+
template.description.toLowerCase().includes(queryLower) ||
|
|
67
|
+
template.tags.some(tag => tag.toLowerCase().includes(queryLower));
|
|
68
|
+
const matchesTags = !tags || tags.length === 0 ||
|
|
69
|
+
tags.every(tag => template.tags.includes(tag));
|
|
70
|
+
return matchesQuery && matchesTags;
|
|
71
|
+
});
|
|
72
|
+
this.logger.debug('Templates searched', { query, tags, count: templates.length });
|
|
73
|
+
return templates.sort((a, b) => a.name.localeCompare(b.name));
|
|
74
|
+
}
|
|
75
|
+
async createTemplate(templateData) {
|
|
76
|
+
const now = new Date();
|
|
77
|
+
const id = this.generateTemplateId(templateData.name, templateData.category);
|
|
78
|
+
const template = {
|
|
79
|
+
...templateData,
|
|
80
|
+
id,
|
|
81
|
+
createdAt: now,
|
|
82
|
+
updatedAt: now
|
|
83
|
+
};
|
|
84
|
+
// Validate template before saving
|
|
85
|
+
const validation = await this.validateTemplate(template.template, template.variables);
|
|
86
|
+
if (!validation.isValid) {
|
|
87
|
+
throw new Error(`Template validation failed: ${validation.errors.map(e => e.message).join(', ')}`);
|
|
88
|
+
}
|
|
89
|
+
// Save to disk and cache
|
|
90
|
+
await this.saveTemplateToDisk(template);
|
|
91
|
+
this.templateCache.set(id, template);
|
|
92
|
+
this.logger.info('Template created', { id, name: template.name, category: template.category });
|
|
93
|
+
return template;
|
|
94
|
+
}
|
|
95
|
+
async updateTemplate(id, updates) {
|
|
96
|
+
const existing = await this.getTemplate(id);
|
|
97
|
+
if (!existing) {
|
|
98
|
+
throw new Error(`Template with id '${id}' not found`);
|
|
99
|
+
}
|
|
100
|
+
const updated = {
|
|
101
|
+
...existing,
|
|
102
|
+
...updates,
|
|
103
|
+
id, // Ensure ID cannot be changed
|
|
104
|
+
createdAt: existing.createdAt, // Preserve creation date
|
|
105
|
+
updatedAt: new Date()
|
|
106
|
+
};
|
|
107
|
+
// Validate updated template
|
|
108
|
+
const validation = await this.validateTemplate(updated.template, updated.variables);
|
|
109
|
+
if (!validation.isValid) {
|
|
110
|
+
throw new Error(`Template validation failed: ${validation.errors.map(e => e.message).join(', ')}`);
|
|
111
|
+
}
|
|
112
|
+
// Save to disk and update cache
|
|
113
|
+
await this.saveTemplateToDisk(updated);
|
|
114
|
+
this.templateCache.set(id, updated);
|
|
115
|
+
this.logger.info('Template updated', { id, name: updated.name });
|
|
116
|
+
return updated;
|
|
117
|
+
}
|
|
118
|
+
async deleteTemplate(id) {
|
|
119
|
+
const template = await this.getTemplate(id);
|
|
120
|
+
if (!template) {
|
|
121
|
+
throw new Error(`Template with id '${id}' not found`);
|
|
122
|
+
}
|
|
123
|
+
// Remove from disk
|
|
124
|
+
const templatePath = this.getTemplatePath(id);
|
|
125
|
+
try {
|
|
126
|
+
await fs.unlink(templatePath);
|
|
127
|
+
this.templateCache.delete(id);
|
|
128
|
+
this.logger.info('Template deleted', { id, name: template.name });
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.logger.error('Failed to delete template file', {
|
|
132
|
+
id,
|
|
133
|
+
path: templatePath,
|
|
134
|
+
error: error instanceof Error ? error.message : String(error)
|
|
135
|
+
});
|
|
136
|
+
throw new Error(`Failed to delete template: ${error instanceof Error ? error.message : String(error)}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async validateTemplate(template, variables) {
|
|
140
|
+
const errors = [];
|
|
141
|
+
const warnings = [];
|
|
142
|
+
try {
|
|
143
|
+
// Try to compile the template with Handlebars
|
|
144
|
+
await this.renderer.compile(template, 'validation_template');
|
|
145
|
+
// Check for required variables
|
|
146
|
+
const templateVariables = this.extractVariablesFromTemplate(template);
|
|
147
|
+
const definedVariables = new Set(variables.map(v => v.name));
|
|
148
|
+
// Check for undefined variables
|
|
149
|
+
for (const usedVar of templateVariables) {
|
|
150
|
+
if (!definedVariables.has(usedVar)) {
|
|
151
|
+
warnings.push({
|
|
152
|
+
message: `Variable '${usedVar}' is used in template but not defined in variables`,
|
|
153
|
+
variable: usedVar,
|
|
154
|
+
suggestion: `Add '${usedVar}' to the template variables`
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Check for unused defined variables
|
|
159
|
+
for (const variable of variables) {
|
|
160
|
+
if (!templateVariables.has(variable.name)) {
|
|
161
|
+
warnings.push({
|
|
162
|
+
message: `Variable '${variable.name}' is defined but not used in template`,
|
|
163
|
+
variable: variable.name,
|
|
164
|
+
suggestion: `Remove '${variable.name}' from template variables or use it in the template`
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
errors.push({
|
|
171
|
+
message: `Template compilation error: ${error instanceof Error ? error.message : String(error)}`
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
isValid: errors.length === 0,
|
|
176
|
+
errors,
|
|
177
|
+
warnings
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async getAllTemplates() {
|
|
181
|
+
await this.ensureCacheInitialized();
|
|
182
|
+
return Array.from(this.templateCache.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
183
|
+
}
|
|
184
|
+
async ensureCacheInitialized() {
|
|
185
|
+
if (this.cacheInitialized)
|
|
186
|
+
return;
|
|
187
|
+
try {
|
|
188
|
+
await this.loadAllTemplates();
|
|
189
|
+
this.cacheInitialized = true;
|
|
190
|
+
this.logger.debug('Template cache initialized');
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
this.logger.error('Failed to initialize template cache', {
|
|
194
|
+
error: error instanceof Error ? error.message : String(error)
|
|
195
|
+
});
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async loadAllTemplates() {
|
|
200
|
+
try {
|
|
201
|
+
await fs.mkdir(this.templateDirectory, { recursive: true });
|
|
202
|
+
const files = await fs.readdir(this.templateDirectory, { withFileTypes: true });
|
|
203
|
+
const templateFiles = files
|
|
204
|
+
.filter(file => file.isFile() && file.name.endsWith('.json'))
|
|
205
|
+
.map(file => file.name.replace('.json', ''));
|
|
206
|
+
for (const templateId of templateFiles) {
|
|
207
|
+
try {
|
|
208
|
+
const template = await this.loadTemplateFromDisk(templateId);
|
|
209
|
+
if (template) {
|
|
210
|
+
this.templateCache.set(templateId, template);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
this.logger.warn('Failed to load template', {
|
|
215
|
+
templateId,
|
|
216
|
+
error: error instanceof Error ? error.message : String(error)
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
this.logger.info('Templates loaded from disk', { count: this.templateCache.size });
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
this.logger.error('Failed to scan template directory', {
|
|
224
|
+
directory: this.templateDirectory,
|
|
225
|
+
error: error instanceof Error ? error.message : String(error)
|
|
226
|
+
});
|
|
227
|
+
// Create built-in templates if directory doesn't exist
|
|
228
|
+
await this.createBuiltInTemplates();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async loadTemplateFromDisk(id) {
|
|
232
|
+
const templatePath = this.getTemplatePath(id);
|
|
233
|
+
const templateContentPath = this.getTemplateContentPath(id);
|
|
234
|
+
try {
|
|
235
|
+
const [metadataContent, templateContent] = await Promise.all([
|
|
236
|
+
fs.readFile(templatePath, 'utf-8'),
|
|
237
|
+
fs.readFile(templateContentPath, 'utf-8')
|
|
238
|
+
]);
|
|
239
|
+
const metadata = JSON.parse(metadataContent);
|
|
240
|
+
return {
|
|
241
|
+
...metadata,
|
|
242
|
+
template: templateContent,
|
|
243
|
+
createdAt: new Date(metadata.createdAt),
|
|
244
|
+
updatedAt: new Date(metadata.updatedAt)
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
if (error.code !== 'ENOENT') {
|
|
249
|
+
this.logger.error('Error loading template from disk', {
|
|
250
|
+
id,
|
|
251
|
+
path: templatePath,
|
|
252
|
+
error: error instanceof Error ? error.message : String(error)
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async saveTemplateToDisk(template) {
|
|
259
|
+
const templatePath = this.getTemplatePath(template.id);
|
|
260
|
+
const templateContentPath = this.getTemplateContentPath(template.id);
|
|
261
|
+
const metadata = {
|
|
262
|
+
id: template.id,
|
|
263
|
+
name: template.name,
|
|
264
|
+
category: template.category,
|
|
265
|
+
description: template.description,
|
|
266
|
+
variables: template.variables,
|
|
267
|
+
version: template.version,
|
|
268
|
+
author: template.author,
|
|
269
|
+
tags: template.tags,
|
|
270
|
+
createdAt: template.createdAt,
|
|
271
|
+
updatedAt: template.updatedAt
|
|
272
|
+
};
|
|
273
|
+
try {
|
|
274
|
+
await fs.mkdir(path.dirname(templatePath), { recursive: true });
|
|
275
|
+
await Promise.all([
|
|
276
|
+
fs.writeFile(templatePath, JSON.stringify(metadata, null, 2)),
|
|
277
|
+
fs.writeFile(templateContentPath, template.template)
|
|
278
|
+
]);
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
this.logger.error('Failed to save template to disk', {
|
|
282
|
+
id: template.id,
|
|
283
|
+
path: templatePath,
|
|
284
|
+
error: error instanceof Error ? error.message : String(error)
|
|
285
|
+
});
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
getTemplatePath(id) {
|
|
290
|
+
return path.join(this.templateDirectory, `${id}.json`);
|
|
291
|
+
}
|
|
292
|
+
getTemplateContentPath(id) {
|
|
293
|
+
return path.join(this.templateDirectory, `${id}.hbs`);
|
|
294
|
+
}
|
|
295
|
+
generateTemplateId(name, category) {
|
|
296
|
+
const timestamp = Date.now().toString(36);
|
|
297
|
+
const nameSlug = name.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-');
|
|
298
|
+
return `${category}-${nameSlug}-${timestamp}`;
|
|
299
|
+
}
|
|
300
|
+
extractVariablesFromTemplate(template) {
|
|
301
|
+
const variables = new Set();
|
|
302
|
+
// Match Handlebars variables: {{variable}}, {{#each items}}, {{#if condition}}, etc.
|
|
303
|
+
const variableRegex = /\{\{(?:#(?:each|if|unless|with)\s+)?([a-zA-Z_][a-zA-Z0-9_.]*)/g;
|
|
304
|
+
let match;
|
|
305
|
+
while ((match = variableRegex.exec(template)) !== null) {
|
|
306
|
+
const variable = match[1].split('.')[0]; // Get root variable name
|
|
307
|
+
if (variable !== 'this' && !variable.startsWith('@')) {
|
|
308
|
+
variables.add(variable);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return variables;
|
|
312
|
+
}
|
|
313
|
+
async createBuiltInTemplates() {
|
|
314
|
+
const builtInTemplates = await this.getBuiltInTemplates();
|
|
315
|
+
for (const templateData of builtInTemplates) {
|
|
316
|
+
try {
|
|
317
|
+
await this.createTemplate(templateData);
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
this.logger.warn('Failed to create built-in template', {
|
|
321
|
+
name: templateData.name,
|
|
322
|
+
error: error instanceof Error ? error.message : String(error)
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
async getBuiltInTemplates() {
|
|
328
|
+
return [
|
|
329
|
+
{
|
|
330
|
+
name: 'spec-json',
|
|
331
|
+
category: TemplateCategory.SPECIFICATION,
|
|
332
|
+
description: 'SDD specification JSON template',
|
|
333
|
+
template: await this.getSpecJsonTemplate(),
|
|
334
|
+
variables: [
|
|
335
|
+
{ name: 'name', type: 'string', description: 'Project name', required: true },
|
|
336
|
+
{ name: 'description', type: 'string', description: 'Project description', required: false },
|
|
337
|
+
{ name: 'author', type: 'string', description: 'Project author', required: false }
|
|
338
|
+
],
|
|
339
|
+
version: '1.0.0',
|
|
340
|
+
tags: ['sdd', 'specification', 'json']
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'requirements-md',
|
|
344
|
+
category: TemplateCategory.REQUIREMENTS,
|
|
345
|
+
description: 'SDD requirements document template',
|
|
346
|
+
template: await this.getRequirementsTemplate(),
|
|
347
|
+
variables: [
|
|
348
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true },
|
|
349
|
+
{ name: 'requirements', type: 'array', description: 'List of requirements', required: true }
|
|
350
|
+
],
|
|
351
|
+
version: '1.0.0',
|
|
352
|
+
tags: ['sdd', 'requirements', 'markdown']
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: 'design-md',
|
|
356
|
+
category: TemplateCategory.DESIGN,
|
|
357
|
+
description: 'SDD design document template',
|
|
358
|
+
template: await this.getDesignTemplate(),
|
|
359
|
+
variables: [
|
|
360
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true },
|
|
361
|
+
{ name: 'architecture', type: 'string', description: 'Architecture description', required: true },
|
|
362
|
+
{ name: 'components', type: 'array', description: 'System components', required: true }
|
|
363
|
+
],
|
|
364
|
+
version: '1.0.0',
|
|
365
|
+
tags: ['sdd', 'design', 'markdown']
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'tasks-md',
|
|
369
|
+
category: TemplateCategory.TASKS,
|
|
370
|
+
description: 'SDD tasks document template',
|
|
371
|
+
template: await this.getTasksTemplate(),
|
|
372
|
+
variables: [
|
|
373
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true },
|
|
374
|
+
{ name: 'tasks', type: 'array', description: 'List of tasks', required: true }
|
|
375
|
+
],
|
|
376
|
+
version: '1.0.0',
|
|
377
|
+
tags: ['sdd', 'tasks', 'markdown']
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: 'product-steering',
|
|
381
|
+
category: TemplateCategory.STEERING,
|
|
382
|
+
description: 'Product steering document template',
|
|
383
|
+
template: await this.getProductSteeringTemplate(),
|
|
384
|
+
variables: [
|
|
385
|
+
{ name: 'productName', type: 'string', description: 'Product name', required: true },
|
|
386
|
+
{ name: 'vision', type: 'string', description: 'Product vision', required: true },
|
|
387
|
+
{ name: 'goals', type: 'array', description: 'Product goals', required: true }
|
|
388
|
+
],
|
|
389
|
+
version: '1.0.0',
|
|
390
|
+
tags: ['steering', 'product', 'markdown']
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: 'tech-steering',
|
|
394
|
+
category: TemplateCategory.STEERING,
|
|
395
|
+
description: 'Technical steering document template',
|
|
396
|
+
template: await this.getTechSteeringTemplate(),
|
|
397
|
+
variables: [
|
|
398
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true },
|
|
399
|
+
{ name: 'techStack', type: 'array', description: 'Technology stack', required: true },
|
|
400
|
+
{ name: 'architecture', type: 'string', description: 'Architecture pattern', required: true }
|
|
401
|
+
],
|
|
402
|
+
version: '1.0.0',
|
|
403
|
+
tags: ['steering', 'technical', 'markdown']
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'structure-steering',
|
|
407
|
+
category: TemplateCategory.STEERING,
|
|
408
|
+
description: 'Structure steering document template',
|
|
409
|
+
template: await this.getStructureSteeringTemplate(),
|
|
410
|
+
variables: [
|
|
411
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true },
|
|
412
|
+
{ name: 'structure', type: 'object', description: 'Project structure', required: true }
|
|
413
|
+
],
|
|
414
|
+
version: '1.0.0',
|
|
415
|
+
tags: ['steering', 'structure', 'markdown']
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
name: 'linus-review-steering',
|
|
419
|
+
category: TemplateCategory.STEERING,
|
|
420
|
+
description: 'Linus-style code review steering document template',
|
|
421
|
+
template: await this.getLinusReviewTemplate(),
|
|
422
|
+
variables: [
|
|
423
|
+
{ name: 'projectName', type: 'string', description: 'Project name', required: true }
|
|
424
|
+
],
|
|
425
|
+
version: '1.0.0',
|
|
426
|
+
tags: ['steering', 'code-review', 'linus', 'quality']
|
|
427
|
+
}
|
|
428
|
+
];
|
|
429
|
+
}
|
|
430
|
+
// Template content methods
|
|
431
|
+
async getSpecJsonTemplate() {
|
|
432
|
+
return `{
|
|
433
|
+
"name": "{{name}}",
|
|
434
|
+
"description": "{{#if description}}{{description}}{{else}}{{name}} specification{{/if}}",
|
|
435
|
+
"version": "1.0.0",
|
|
436
|
+
"author": "{{#if author}}{{author}}{{else}}Unknown{{/if}}",
|
|
437
|
+
"createdAt": "{{formatDate context.timestamp}}",
|
|
438
|
+
"phase": "INIT",
|
|
439
|
+
"approved": {
|
|
440
|
+
"requirements": false,
|
|
441
|
+
"design": false,
|
|
442
|
+
"tasks": false
|
|
443
|
+
},
|
|
444
|
+
"metadata": {
|
|
445
|
+
"projectId": "{{generateId}}",
|
|
446
|
+
"basePath": "{{context.project.basePath}}",
|
|
447
|
+
"technology": [],
|
|
448
|
+
"complexity": "moderate"
|
|
449
|
+
}
|
|
450
|
+
}`;
|
|
451
|
+
}
|
|
452
|
+
async getRequirementsTemplate() {
|
|
453
|
+
return `# {{projectName}} - Requirements
|
|
454
|
+
|
|
455
|
+
## Overview
|
|
456
|
+
This document outlines the requirements for {{projectName}}.
|
|
457
|
+
|
|
458
|
+
## Functional Requirements
|
|
459
|
+
{{#each requirements}}
|
|
460
|
+
### {{@index}}. {{title}}
|
|
461
|
+
{{description}}
|
|
462
|
+
|
|
463
|
+
**Acceptance Criteria:**
|
|
464
|
+
{{#each acceptanceCriteria}}
|
|
465
|
+
- {{this}}
|
|
466
|
+
{{/each}}
|
|
467
|
+
|
|
468
|
+
{{/each}}
|
|
469
|
+
|
|
470
|
+
## Non-Functional Requirements
|
|
471
|
+
- Performance: Response time under 200ms
|
|
472
|
+
- Scalability: Support 1000+ concurrent users
|
|
473
|
+
- Reliability: 99.9% uptime
|
|
474
|
+
- Security: Secure authentication and authorization
|
|
475
|
+
|
|
476
|
+
## Dependencies
|
|
477
|
+
{{#if dependencies}}
|
|
478
|
+
{{#each dependencies}}
|
|
479
|
+
- {{name}}: {{description}}
|
|
480
|
+
{{/each}}
|
|
481
|
+
{{else}}
|
|
482
|
+
No external dependencies identified.
|
|
483
|
+
{{/if}}
|
|
484
|
+
|
|
485
|
+
## Assumptions
|
|
486
|
+
{{#if assumptions}}
|
|
487
|
+
{{#each assumptions}}
|
|
488
|
+
- {{this}}
|
|
489
|
+
{{/each}}
|
|
490
|
+
{{else}}
|
|
491
|
+
No assumptions documented.
|
|
492
|
+
{{/if}}
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
*Generated on {{formatDate context.timestamp}} using SDD MCP Server*`;
|
|
496
|
+
}
|
|
497
|
+
async getDesignTemplate() {
|
|
498
|
+
return `# {{projectName}} - Design Document
|
|
499
|
+
|
|
500
|
+
## Architecture Overview
|
|
501
|
+
{{architecture}}
|
|
502
|
+
|
|
503
|
+
## System Components
|
|
504
|
+
{{#each components}}
|
|
505
|
+
### {{name}}
|
|
506
|
+
**Purpose:** {{purpose}}
|
|
507
|
+
**Responsibilities:**
|
|
508
|
+
{{#each responsibilities}}
|
|
509
|
+
- {{this}}
|
|
510
|
+
{{/each}}
|
|
511
|
+
|
|
512
|
+
**Interfaces:**
|
|
513
|
+
{{#each interfaces}}
|
|
514
|
+
- {{name}}: {{description}}
|
|
515
|
+
{{/each}}
|
|
516
|
+
|
|
517
|
+
{{/each}}
|
|
518
|
+
|
|
519
|
+
## Data Models
|
|
520
|
+
{{#if dataModels}}
|
|
521
|
+
{{#each dataModels}}
|
|
522
|
+
### {{name}}
|
|
523
|
+
\`\`\`typescript
|
|
524
|
+
{{schema}}
|
|
525
|
+
\`\`\`
|
|
526
|
+
{{/each}}
|
|
527
|
+
{{else}}
|
|
528
|
+
Data models to be defined during implementation.
|
|
529
|
+
{{/if}}
|
|
530
|
+
|
|
531
|
+
## API Design
|
|
532
|
+
{{#if apis}}
|
|
533
|
+
{{#each apis}}
|
|
534
|
+
### {{name}}
|
|
535
|
+
- **Method:** {{method}}
|
|
536
|
+
- **Path:** {{path}}
|
|
537
|
+
- **Description:** {{description}}
|
|
538
|
+
{{/each}}
|
|
539
|
+
{{else}}
|
|
540
|
+
API design to be defined during implementation.
|
|
541
|
+
{{/if}}
|
|
542
|
+
|
|
543
|
+
## Security Considerations
|
|
544
|
+
- Authentication and authorization mechanisms
|
|
545
|
+
- Data validation and sanitization
|
|
546
|
+
- Secure communication protocols
|
|
547
|
+
|
|
548
|
+
## Performance Considerations
|
|
549
|
+
- Caching strategies
|
|
550
|
+
- Database optimization
|
|
551
|
+
- Load balancing
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
*Generated on {{formatDate context.timestamp}} using SDD MCP Server*`;
|
|
555
|
+
}
|
|
556
|
+
async getTasksTemplate() {
|
|
557
|
+
return `# {{projectName}} - Implementation Tasks
|
|
558
|
+
|
|
559
|
+
## Task Breakdown
|
|
560
|
+
{{#each tasks}}
|
|
561
|
+
### {{@index}}. {{title}}
|
|
562
|
+
{{taskStatus completed}} **{{title}}**
|
|
563
|
+
|
|
564
|
+
**Description:** {{description}}
|
|
565
|
+
|
|
566
|
+
**Subtasks:**
|
|
567
|
+
{{#each subtasks}}
|
|
568
|
+
- {{taskStatus completed}} {{title}}
|
|
569
|
+
{{/each}}
|
|
570
|
+
|
|
571
|
+
**Dependencies:**
|
|
572
|
+
{{#if dependencies}}
|
|
573
|
+
{{#each dependencies}}
|
|
574
|
+
- Task {{this}}
|
|
575
|
+
{{/each}}
|
|
576
|
+
{{else}}
|
|
577
|
+
None
|
|
578
|
+
{{/if}}
|
|
579
|
+
|
|
580
|
+
**Estimated Effort:** {{effort}} hours
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
{{/each}}
|
|
584
|
+
|
|
585
|
+
## Progress Summary
|
|
586
|
+
- **Total Tasks:** {{length tasks}}
|
|
587
|
+
- **Completed:** {{#each tasks}}{{#if completed}}1{{/if}}{{/each}}
|
|
588
|
+
- **Remaining:** {{#each tasks}}{{#unless completed}}1{{/unless}}{{/each}}
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
*Generated on {{formatDate context.timestamp}} using SDD MCP Server*`;
|
|
592
|
+
}
|
|
593
|
+
async getProductSteeringTemplate() {
|
|
594
|
+
return `# Product Steering - {{productName}}
|
|
595
|
+
|
|
596
|
+
## Vision
|
|
597
|
+
{{vision}}
|
|
598
|
+
|
|
599
|
+
## Goals
|
|
600
|
+
{{#each goals}}
|
|
601
|
+
- {{this}}
|
|
602
|
+
{{/each}}
|
|
603
|
+
|
|
604
|
+
## Success Metrics
|
|
605
|
+
{{#if metrics}}
|
|
606
|
+
{{#each metrics}}
|
|
607
|
+
- {{name}}: {{target}}
|
|
608
|
+
{{/each}}
|
|
609
|
+
{{else}}
|
|
610
|
+
Success metrics to be defined.
|
|
611
|
+
{{/if}}
|
|
612
|
+
|
|
613
|
+
## Target Users
|
|
614
|
+
{{#if users}}
|
|
615
|
+
{{#each users}}
|
|
616
|
+
- **{{name}}**: {{description}}
|
|
617
|
+
{{/each}}
|
|
618
|
+
{{else}}
|
|
619
|
+
Target users to be identified.
|
|
620
|
+
{{/if}}
|
|
621
|
+
|
|
622
|
+
## Constraints
|
|
623
|
+
{{#if constraints}}
|
|
624
|
+
{{#each constraints}}
|
|
625
|
+
- {{this}}
|
|
626
|
+
{{/each}}
|
|
627
|
+
{{else}}
|
|
628
|
+
No constraints identified.
|
|
629
|
+
{{/if}}
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
*Product steering document for {{productName}}*`;
|
|
633
|
+
}
|
|
634
|
+
async getTechSteeringTemplate() {
|
|
635
|
+
return `# Technical Steering - {{projectName}}
|
|
636
|
+
|
|
637
|
+
## Technology Stack
|
|
638
|
+
{{#each techStack}}
|
|
639
|
+
- **{{category}}**: {{name}} {{#if version}}({{version}}){{/if}}
|
|
640
|
+
{{/each}}
|
|
641
|
+
|
|
642
|
+
## Architecture Pattern
|
|
643
|
+
{{architecture}}
|
|
644
|
+
|
|
645
|
+
## Development Guidelines
|
|
646
|
+
- Follow clean architecture principles
|
|
647
|
+
- Implement comprehensive testing
|
|
648
|
+
- Use TypeScript for type safety
|
|
649
|
+
- Follow SOLID principles
|
|
650
|
+
|
|
651
|
+
## Code Quality Standards
|
|
652
|
+
- ESLint configuration for code consistency
|
|
653
|
+
- Prettier for code formatting
|
|
654
|
+
- Husky for pre-commit hooks
|
|
655
|
+
- Jest for unit testing
|
|
656
|
+
|
|
657
|
+
## Performance Requirements
|
|
658
|
+
- Response time: < 200ms
|
|
659
|
+
- Memory usage: < 512MB
|
|
660
|
+
- CPU usage: < 80%
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
*Technical steering document for {{projectName}}*`;
|
|
664
|
+
}
|
|
665
|
+
async getStructureSteeringTemplate() {
|
|
666
|
+
return `# Structure Steering - {{projectName}}
|
|
667
|
+
|
|
668
|
+
## Directory Structure
|
|
669
|
+
{{#each structure.directories}}
|
|
670
|
+
- **{{path}}**: {{purpose}}
|
|
671
|
+
{{/each}}
|
|
672
|
+
|
|
673
|
+
## File Organization
|
|
674
|
+
{{#each structure.fileTypes}}
|
|
675
|
+
- **{{extension}}**: {{location}} - {{purpose}}
|
|
676
|
+
{{/each}}
|
|
677
|
+
|
|
678
|
+
## Naming Conventions
|
|
679
|
+
- Files: kebab-case
|
|
680
|
+
- Directories: kebab-case
|
|
681
|
+
- Classes: PascalCase
|
|
682
|
+
- Functions: camelCase
|
|
683
|
+
- Constants: UPPER_SNAKE_CASE
|
|
684
|
+
|
|
685
|
+
## Import/Export Patterns
|
|
686
|
+
- Use absolute imports from src/
|
|
687
|
+
- Export interfaces and types explicitly
|
|
688
|
+
- Barrel exports for public APIs
|
|
689
|
+
|
|
690
|
+
---
|
|
691
|
+
*Structure steering document for {{projectName}}*`;
|
|
692
|
+
}
|
|
693
|
+
async getLinusReviewTemplate() {
|
|
694
|
+
return `# Linus-Style Code Review Standards - {{projectName}}
|
|
695
|
+
|
|
696
|
+
## Code Review Philosophy
|
|
697
|
+
"Good code is not just code that works, but code that is readable, maintainable, and elegant."
|
|
698
|
+
|
|
699
|
+
## Five-Layer Analysis Framework
|
|
700
|
+
|
|
701
|
+
### 1. Taste (Good/Passable/Garbage)
|
|
702
|
+
- **Good**: Elegant, simple, intuitive
|
|
703
|
+
- **Passable**: Functional but could be better
|
|
704
|
+
- **Garbage**: Overcomplicated, unclear, problematic
|
|
705
|
+
|
|
706
|
+
### 2. Complexity Analysis
|
|
707
|
+
- Eliminate unnecessary complexity
|
|
708
|
+
- Prefer simple solutions over clever ones
|
|
709
|
+
- Maximum cyclomatic complexity: 10
|
|
710
|
+
- Maximum nesting depth: 4
|
|
711
|
+
|
|
712
|
+
### 3. Special Cases
|
|
713
|
+
- Identify and eliminate special-case handling
|
|
714
|
+
- Generalize solutions when possible
|
|
715
|
+
- Avoid magic numbers and hard-coded values
|
|
716
|
+
|
|
717
|
+
### 4. Data Structures
|
|
718
|
+
- Choose appropriate data structures
|
|
719
|
+
- Optimize for access patterns
|
|
720
|
+
- Consider memory usage and performance
|
|
721
|
+
|
|
722
|
+
### 5. Code Organization
|
|
723
|
+
- Single responsibility principle
|
|
724
|
+
- Clear separation of concerns
|
|
725
|
+
- Intuitive naming and structure
|
|
726
|
+
|
|
727
|
+
## Review Criteria
|
|
728
|
+
|
|
729
|
+
### Immediate Rejection
|
|
730
|
+
- Code that doesn't compile
|
|
731
|
+
- Missing tests for new functionality
|
|
732
|
+
- Obvious security vulnerabilities
|
|
733
|
+
- Memory leaks or resource leaks
|
|
734
|
+
|
|
735
|
+
### Strong Criticism
|
|
736
|
+
- Overly complex solutions
|
|
737
|
+
- Poor error handling
|
|
738
|
+
- Inconsistent coding style
|
|
739
|
+
- Missing documentation
|
|
740
|
+
|
|
741
|
+
### Feedback Areas
|
|
742
|
+
- Performance optimizations
|
|
743
|
+
- Code readability improvements
|
|
744
|
+
- Architecture suggestions
|
|
745
|
+
- Best practice recommendations
|
|
746
|
+
|
|
747
|
+
## Standards
|
|
748
|
+
|
|
749
|
+
### Performance
|
|
750
|
+
- O(n) or better for critical paths
|
|
751
|
+
- Avoid nested loops when possible
|
|
752
|
+
- Profile before optimizing
|
|
753
|
+
|
|
754
|
+
### Maintainability
|
|
755
|
+
- Self-documenting code
|
|
756
|
+
- Clear variable and function names
|
|
757
|
+
- Minimal cognitive load
|
|
758
|
+
|
|
759
|
+
### Reliability
|
|
760
|
+
- Comprehensive error handling
|
|
761
|
+
- Input validation
|
|
762
|
+
- Graceful degradation
|
|
763
|
+
|
|
764
|
+
---
|
|
765
|
+
*"The best code is code that doesn't need to be written, but if it must be written, make it beautiful."*
|
|
766
|
+
|
|
767
|
+
*Linus-style review standards for {{projectName}}*`;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
TemplateManager = __decorate([
|
|
771
|
+
injectable(),
|
|
772
|
+
__param(0, inject(TYPES.LoggerPort)),
|
|
773
|
+
__param(1, inject(TYPES.TemplateRendererPort)),
|
|
774
|
+
__metadata("design:paramtypes", [Object, Object, Object])
|
|
775
|
+
], TemplateManager);
|
|
776
|
+
export { TemplateManager };
|
|
777
|
+
//# sourceMappingURL=TemplateManager.js.map
|