kratos-mcp 1.1.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 +351 -0
- package/dist/host-middleware-v2.d.ts +3 -0
- package/dist/host-middleware-v2.d.ts.map +1 -0
- package/dist/host-middleware-v2.js +471 -0
- package/dist/host-middleware-v2.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +939 -0
- package/dist/index.js.map +1 -0
- package/dist/memory-server/concept-store-enhanced.d.ts +88 -0
- package/dist/memory-server/concept-store-enhanced.d.ts.map +1 -0
- package/dist/memory-server/concept-store-enhanced.js +392 -0
- package/dist/memory-server/concept-store-enhanced.js.map +1 -0
- package/dist/memory-server/concept-store.d.ts +58 -0
- package/dist/memory-server/concept-store.d.ts.map +1 -0
- package/dist/memory-server/concept-store.js +329 -0
- package/dist/memory-server/concept-store.js.map +1 -0
- package/dist/memory-server/context-broker.d.ts +63 -0
- package/dist/memory-server/context-broker.d.ts.map +1 -0
- package/dist/memory-server/context-broker.js +340 -0
- package/dist/memory-server/context-broker.js.map +1 -0
- package/dist/memory-server/database.d.ts +61 -0
- package/dist/memory-server/database.d.ts.map +1 -0
- package/dist/memory-server/database.js +309 -0
- package/dist/memory-server/database.js.map +1 -0
- package/dist/modules/prd/index.d.ts +47 -0
- package/dist/modules/prd/index.d.ts.map +1 -0
- package/dist/modules/prd/index.js +220 -0
- package/dist/modules/prd/index.js.map +1 -0
- package/dist/modules/prompt/index.d.ts +47 -0
- package/dist/modules/prompt/index.d.ts.map +1 -0
- package/dist/modules/prompt/index.js +313 -0
- package/dist/modules/prompt/index.js.map +1 -0
- package/dist/project-manager.d.ts +69 -0
- package/dist/project-manager.d.ts.map +1 -0
- package/dist/project-manager.js +207 -0
- package/dist/project-manager.js.map +1 -0
- package/dist/security/data-retention.d.ts +104 -0
- package/dist/security/data-retention.d.ts.map +1 -0
- package/dist/security/data-retention.js +444 -0
- package/dist/security/data-retention.js.map +1 -0
- package/dist/security/encryption.d.ts +48 -0
- package/dist/security/encryption.d.ts.map +1 -0
- package/dist/security/encryption.js +131 -0
- package/dist/security/encryption.js.map +1 -0
- package/dist/security/pii-detector.d.ts +61 -0
- package/dist/security/pii-detector.d.ts.map +1 -0
- package/dist/security/pii-detector.js +220 -0
- package/dist/security/pii-detector.js.map +1 -0
- package/dist/tools/ci-hooks.d.ts +48 -0
- package/dist/tools/ci-hooks.d.ts.map +1 -0
- package/dist/tools/ci-hooks.js +452 -0
- package/dist/tools/ci-hooks.js.map +1 -0
- package/dist/tools/migrate-to-sqlite.d.ts +32 -0
- package/dist/tools/migrate-to-sqlite.d.ts.map +1 -0
- package/dist/tools/migrate-to-sqlite.js +341 -0
- package/dist/tools/migrate-to-sqlite.js.map +1 -0
- package/dist/types/index.d.ts +151 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +33 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/mcp-logger.d.ts +14 -0
- package/dist/utils/mcp-logger.d.ts.map +1 -0
- package/dist/utils/mcp-logger.js +40 -0
- package/dist/utils/mcp-logger.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { MCPLogger as Logger } from '../../utils/mcp-logger.js';
|
|
2
|
+
import { randomUUID } from 'crypto';
|
|
3
|
+
export class PromptManager {
|
|
4
|
+
logger;
|
|
5
|
+
templates = new Map();
|
|
6
|
+
constructor() {
|
|
7
|
+
this.logger = new Logger('PromptManager');
|
|
8
|
+
this.initializeTemplates();
|
|
9
|
+
}
|
|
10
|
+
initializeTemplates() {
|
|
11
|
+
// Pre-built templates for common scenarios
|
|
12
|
+
const templates = [
|
|
13
|
+
{
|
|
14
|
+
id: 'bug-fix',
|
|
15
|
+
name: 'Bug Fix Template',
|
|
16
|
+
role: 'Senior Software Engineer specializing in debugging',
|
|
17
|
+
stack: ['${tech_stack}'],
|
|
18
|
+
goal: 'Fix the ${bug_description} issue',
|
|
19
|
+
scopeConstraints: [
|
|
20
|
+
'Only modify files in ${affected_files}',
|
|
21
|
+
'Preserve existing functionality',
|
|
22
|
+
'Follow existing code patterns'
|
|
23
|
+
],
|
|
24
|
+
fileContext: ['${relevant_files}'],
|
|
25
|
+
plan: [
|
|
26
|
+
'Reproduce the bug',
|
|
27
|
+
'Identify root cause',
|
|
28
|
+
'Implement fix',
|
|
29
|
+
'Add tests if applicable'
|
|
30
|
+
],
|
|
31
|
+
memoryRecall: ['Check for similar bugs in memory'],
|
|
32
|
+
verification: [
|
|
33
|
+
'Run existing tests',
|
|
34
|
+
'Test the specific bug scenario',
|
|
35
|
+
'Verify no regressions'
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'new-feature',
|
|
40
|
+
name: 'New Feature Template',
|
|
41
|
+
role: 'Full-stack Developer',
|
|
42
|
+
stack: ['${tech_stack}'],
|
|
43
|
+
goal: 'Implement ${feature_name}',
|
|
44
|
+
scopeConstraints: [
|
|
45
|
+
'Follow project architecture',
|
|
46
|
+
'Use existing patterns and utilities',
|
|
47
|
+
'Maintain consistency with current codebase'
|
|
48
|
+
],
|
|
49
|
+
fileContext: ['${related_files}'],
|
|
50
|
+
plan: [
|
|
51
|
+
'Review PRD requirements',
|
|
52
|
+
'Create necessary components/modules',
|
|
53
|
+
'Implement business logic',
|
|
54
|
+
'Add API endpoints if needed',
|
|
55
|
+
'Write tests'
|
|
56
|
+
],
|
|
57
|
+
memoryRecall: ['Similar features', 'Architecture patterns'],
|
|
58
|
+
verification: [
|
|
59
|
+
'Feature works as specified in PRD',
|
|
60
|
+
'All tests pass',
|
|
61
|
+
'Code follows project conventions'
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: 'refactor',
|
|
66
|
+
name: 'Refactoring Template',
|
|
67
|
+
role: 'Senior Software Architect',
|
|
68
|
+
stack: ['${tech_stack}'],
|
|
69
|
+
goal: 'Refactor ${target_code} to improve ${improvement_goal}',
|
|
70
|
+
scopeConstraints: [
|
|
71
|
+
'Maintain existing functionality',
|
|
72
|
+
'Improve code quality metrics',
|
|
73
|
+
'Preserve public APIs'
|
|
74
|
+
],
|
|
75
|
+
fileContext: ['${files_to_refactor}'],
|
|
76
|
+
plan: [
|
|
77
|
+
'Analyze current implementation',
|
|
78
|
+
'Identify improvement opportunities',
|
|
79
|
+
'Plan refactoring approach',
|
|
80
|
+
'Implement changes incrementally',
|
|
81
|
+
'Ensure tests still pass'
|
|
82
|
+
],
|
|
83
|
+
memoryRecall: ['Code patterns', 'Architecture decisions'],
|
|
84
|
+
verification: [
|
|
85
|
+
'All tests pass',
|
|
86
|
+
'Performance benchmarks maintained or improved',
|
|
87
|
+
'Code quality metrics improved'
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
templates.forEach(template => {
|
|
92
|
+
this.templates.set(template.id, template);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async generatePrompt(args) {
|
|
96
|
+
let prompt;
|
|
97
|
+
if (args.templateId && this.templates.has(args.templateId)) {
|
|
98
|
+
prompt = this.buildFromTemplate(args.templateId, args);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
prompt = this.buildCustomPrompt(args);
|
|
102
|
+
}
|
|
103
|
+
// Analyze task to add intelligent suggestions
|
|
104
|
+
const suggestions = this.analyzeTaskForSuggestions(args.task);
|
|
105
|
+
if (suggestions.length > 0) {
|
|
106
|
+
prompt += '\n\n## Additional Suggestions\n' + suggestions.join('\n');
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
content: [
|
|
110
|
+
{
|
|
111
|
+
type: 'text',
|
|
112
|
+
text: prompt,
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
buildFromTemplate(templateId, args) {
|
|
118
|
+
const template = this.templates.get(templateId);
|
|
119
|
+
let prompt = `# Role & Stack\n`;
|
|
120
|
+
prompt += `You are a ${args.role || template.role}.\n`;
|
|
121
|
+
prompt += `Tech stack: ${(args.stack || template.stack).join(', ')}\n\n`;
|
|
122
|
+
prompt += `# Goal\n${template.goal}\n\n`;
|
|
123
|
+
prompt += `# Scope Constraints\n`;
|
|
124
|
+
template.scopeConstraints.forEach(constraint => {
|
|
125
|
+
prompt += `- ${constraint}\n`;
|
|
126
|
+
});
|
|
127
|
+
prompt += '\n';
|
|
128
|
+
if (args.fileContext && args.fileContext.length > 0) {
|
|
129
|
+
prompt += `# File Context\nFocus on these files:\n`;
|
|
130
|
+
args.fileContext.forEach((file) => {
|
|
131
|
+
prompt += `- ${file}\n`;
|
|
132
|
+
});
|
|
133
|
+
prompt += '\n';
|
|
134
|
+
}
|
|
135
|
+
prompt += `# Plan\n`;
|
|
136
|
+
template.plan.forEach((step, index) => {
|
|
137
|
+
prompt += `${index + 1}. ${step}\n`;
|
|
138
|
+
});
|
|
139
|
+
prompt += '\n';
|
|
140
|
+
prompt += `# Memory Recall\nCheck memory for:\n`;
|
|
141
|
+
template.memoryRecall.forEach(item => {
|
|
142
|
+
prompt += `- ${item}\n`;
|
|
143
|
+
});
|
|
144
|
+
prompt += '\n';
|
|
145
|
+
prompt += `# Verification\nAfter implementation:\n`;
|
|
146
|
+
template.verification.forEach(item => {
|
|
147
|
+
prompt += `- ${item}\n`;
|
|
148
|
+
});
|
|
149
|
+
return prompt;
|
|
150
|
+
}
|
|
151
|
+
buildCustomPrompt(args) {
|
|
152
|
+
let prompt = `# Task\n${args.task}\n\n`;
|
|
153
|
+
if (args.role) {
|
|
154
|
+
prompt += `# Role\nYou are a ${args.role}.\n\n`;
|
|
155
|
+
}
|
|
156
|
+
if (args.stack && args.stack.length > 0) {
|
|
157
|
+
prompt += `# Tech Stack\n${args.stack.join(', ')}\n\n`;
|
|
158
|
+
}
|
|
159
|
+
if (args.fileContext && args.fileContext.length > 0) {
|
|
160
|
+
prompt += `# File Context\nFocus on these files:\n`;
|
|
161
|
+
args.fileContext.forEach((file) => {
|
|
162
|
+
prompt += `- ${file}\n`;
|
|
163
|
+
});
|
|
164
|
+
prompt += '\n';
|
|
165
|
+
}
|
|
166
|
+
// Add intelligent sections based on task analysis
|
|
167
|
+
const taskLower = args.task.toLowerCase();
|
|
168
|
+
if (taskLower.includes('bug') || taskLower.includes('fix') || taskLower.includes('error')) {
|
|
169
|
+
prompt += `# Approach\n`;
|
|
170
|
+
prompt += `1. Reproduce the issue\n`;
|
|
171
|
+
prompt += `2. Identify root cause\n`;
|
|
172
|
+
prompt += `3. Implement minimal fix\n`;
|
|
173
|
+
prompt += `4. Verify fix doesn't break existing functionality\n\n`;
|
|
174
|
+
}
|
|
175
|
+
else if (taskLower.includes('implement') || taskLower.includes('create') || taskLower.includes('add')) {
|
|
176
|
+
prompt += `# Approach\n`;
|
|
177
|
+
prompt += `1. Review requirements\n`;
|
|
178
|
+
prompt += `2. Check existing patterns in codebase\n`;
|
|
179
|
+
prompt += `3. Implement following project conventions\n`;
|
|
180
|
+
prompt += `4. Add appropriate tests\n\n`;
|
|
181
|
+
}
|
|
182
|
+
else if (taskLower.includes('optimize') || taskLower.includes('improve') || taskLower.includes('performance')) {
|
|
183
|
+
prompt += `# Approach\n`;
|
|
184
|
+
prompt += `1. Measure current performance\n`;
|
|
185
|
+
prompt += `2. Identify bottlenecks\n`;
|
|
186
|
+
prompt += `3. Implement optimizations\n`;
|
|
187
|
+
prompt += `4. Verify improvements with benchmarks\n\n`;
|
|
188
|
+
}
|
|
189
|
+
prompt += `# Verification\n`;
|
|
190
|
+
prompt += `- Ensure all tests pass\n`;
|
|
191
|
+
prompt += `- Follow project code style\n`;
|
|
192
|
+
prompt += `- Document any significant changes\n`;
|
|
193
|
+
return prompt;
|
|
194
|
+
}
|
|
195
|
+
analyzeTaskForSuggestions(task) {
|
|
196
|
+
const suggestions = [];
|
|
197
|
+
const taskLower = task.toLowerCase();
|
|
198
|
+
// Authentication related
|
|
199
|
+
if (taskLower.includes('auth') || taskLower.includes('login') || taskLower.includes('security')) {
|
|
200
|
+
suggestions.push('- Consider OWASP security best practices');
|
|
201
|
+
suggestions.push('- Implement proper session management');
|
|
202
|
+
suggestions.push('- Add rate limiting for authentication endpoints');
|
|
203
|
+
}
|
|
204
|
+
// API related
|
|
205
|
+
if (taskLower.includes('api') || taskLower.includes('endpoint') || taskLower.includes('route')) {
|
|
206
|
+
suggestions.push('- Follow RESTful conventions');
|
|
207
|
+
suggestions.push('- Implement proper error handling and status codes');
|
|
208
|
+
suggestions.push('- Add input validation and sanitization');
|
|
209
|
+
suggestions.push('- Consider API versioning strategy');
|
|
210
|
+
}
|
|
211
|
+
// Database related
|
|
212
|
+
if (taskLower.includes('database') || taskLower.includes('query') || taskLower.includes('migration')) {
|
|
213
|
+
suggestions.push('- Use database transactions where appropriate');
|
|
214
|
+
suggestions.push('- Consider query performance and indexing');
|
|
215
|
+
suggestions.push('- Implement proper error handling for database operations');
|
|
216
|
+
}
|
|
217
|
+
// Performance related
|
|
218
|
+
if (taskLower.includes('performance') || taskLower.includes('optimize') || taskLower.includes('slow')) {
|
|
219
|
+
suggestions.push('- Profile before optimizing');
|
|
220
|
+
suggestions.push('- Consider caching strategies');
|
|
221
|
+
suggestions.push('- Look for N+1 query problems');
|
|
222
|
+
suggestions.push('- Check for unnecessary re-renders (if frontend)');
|
|
223
|
+
}
|
|
224
|
+
// Testing related
|
|
225
|
+
if (taskLower.includes('test') || taskLower.includes('testing')) {
|
|
226
|
+
suggestions.push('- Write unit tests for business logic');
|
|
227
|
+
suggestions.push('- Add integration tests for API endpoints');
|
|
228
|
+
suggestions.push('- Consider edge cases and error scenarios');
|
|
229
|
+
suggestions.push('- Aim for meaningful test coverage, not just high percentages');
|
|
230
|
+
}
|
|
231
|
+
return suggestions;
|
|
232
|
+
}
|
|
233
|
+
async createCustomTemplate(args) {
|
|
234
|
+
const template = {
|
|
235
|
+
id: randomUUID(),
|
|
236
|
+
name: args.name,
|
|
237
|
+
role: args.role,
|
|
238
|
+
stack: args.stack,
|
|
239
|
+
goal: args.goal,
|
|
240
|
+
scopeConstraints: args.scopeConstraints,
|
|
241
|
+
fileContext: [],
|
|
242
|
+
plan: args.plan,
|
|
243
|
+
memoryRecall: [],
|
|
244
|
+
verification: args.verification,
|
|
245
|
+
};
|
|
246
|
+
this.templates.set(template.id, template);
|
|
247
|
+
return {
|
|
248
|
+
content: [
|
|
249
|
+
{
|
|
250
|
+
type: 'text',
|
|
251
|
+
text: `✅ Created custom template: ${args.name}\nID: ${template.id}`,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
async listTemplates() {
|
|
257
|
+
const templates = Array.from(this.templates.values()).map(t => ({
|
|
258
|
+
id: t.id,
|
|
259
|
+
name: t.name,
|
|
260
|
+
role: t.role,
|
|
261
|
+
goal: t.goal,
|
|
262
|
+
}));
|
|
263
|
+
return {
|
|
264
|
+
content: [
|
|
265
|
+
{
|
|
266
|
+
type: 'text',
|
|
267
|
+
text: JSON.stringify(templates, null, 2),
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
async validatePrompt(prompt) {
|
|
273
|
+
const suggestions = [];
|
|
274
|
+
let score = 100;
|
|
275
|
+
// Check for essential sections
|
|
276
|
+
const sections = {
|
|
277
|
+
role: /role|you are/i,
|
|
278
|
+
goal: /goal|objective|task/i,
|
|
279
|
+
context: /context|background|files/i,
|
|
280
|
+
verification: /verification|test|check/i,
|
|
281
|
+
};
|
|
282
|
+
for (const [section, pattern] of Object.entries(sections)) {
|
|
283
|
+
if (!pattern.test(prompt)) {
|
|
284
|
+
suggestions.push(`Consider adding a ${section} section`);
|
|
285
|
+
score -= 10;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
// Check prompt length
|
|
289
|
+
const wordCount = prompt.split(/\s+/).length;
|
|
290
|
+
if (wordCount < 50) {
|
|
291
|
+
suggestions.push('Prompt might be too brief. Consider adding more detail.');
|
|
292
|
+
score -= 15;
|
|
293
|
+
}
|
|
294
|
+
else if (wordCount > 1000) {
|
|
295
|
+
suggestions.push('Prompt might be too long. Consider focusing on essential information.');
|
|
296
|
+
score -= 10;
|
|
297
|
+
}
|
|
298
|
+
// Check for vague language
|
|
299
|
+
const vagueTerms = ['maybe', 'possibly', 'might', 'could', 'should probably'];
|
|
300
|
+
vagueTerms.forEach(term => {
|
|
301
|
+
if (prompt.toLowerCase().includes(term)) {
|
|
302
|
+
suggestions.push(`Avoid vague terms like "${term}". Be specific.`);
|
|
303
|
+
score -= 5;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
return {
|
|
307
|
+
isValid: score >= 70,
|
|
308
|
+
suggestions,
|
|
309
|
+
score,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/prompt/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface Project {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
root: string;
|
|
5
|
+
createdAt: Date;
|
|
6
|
+
lastAccessed: Date;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Smart Project Manager - Handles project isolation and auto-detection
|
|
10
|
+
*
|
|
11
|
+
* KEY FEATURES:
|
|
12
|
+
* - Each project gets COMPLETELY ISOLATED database
|
|
13
|
+
* - Auto-detects project from working directory
|
|
14
|
+
* - No memory pollution between projects
|
|
15
|
+
* - Clean project switching
|
|
16
|
+
*/
|
|
17
|
+
export declare class ProjectManager {
|
|
18
|
+
private kratosHome;
|
|
19
|
+
private currentProject;
|
|
20
|
+
private projectsCache;
|
|
21
|
+
constructor();
|
|
22
|
+
/**
|
|
23
|
+
* Auto-detect project from current working directory
|
|
24
|
+
* Creates a project ID based on the directory path
|
|
25
|
+
*/
|
|
26
|
+
detectProject(workingDir?: string): Promise<Project>;
|
|
27
|
+
/**
|
|
28
|
+
* Switch to a different project
|
|
29
|
+
*/
|
|
30
|
+
switchProject(projectIdOrPath: string): Promise<Project>;
|
|
31
|
+
/**
|
|
32
|
+
* Get the isolated directory for a project
|
|
33
|
+
* This is where ALL project data lives - memories, concepts, etc.
|
|
34
|
+
*/
|
|
35
|
+
getProjectDir(projectId?: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Get database path for current project
|
|
38
|
+
* COMPLETELY ISOLATED - no cross-contamination possible
|
|
39
|
+
*/
|
|
40
|
+
getDatabasePath(dbName: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* List all known projects
|
|
43
|
+
*/
|
|
44
|
+
listProjects(): Project[];
|
|
45
|
+
/**
|
|
46
|
+
* Get current active project
|
|
47
|
+
*/
|
|
48
|
+
getCurrentProject(): Project | null;
|
|
49
|
+
/**
|
|
50
|
+
* Clean up old project data (optional)
|
|
51
|
+
*/
|
|
52
|
+
cleanupProject(projectId: string, options?: {
|
|
53
|
+
keepMemories?: boolean;
|
|
54
|
+
keepConcepts?: boolean;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Generate stable project ID from path
|
|
58
|
+
*/
|
|
59
|
+
private generateProjectId;
|
|
60
|
+
/**
|
|
61
|
+
* Load projects cache from disk
|
|
62
|
+
*/
|
|
63
|
+
private loadProjectsCache;
|
|
64
|
+
/**
|
|
65
|
+
* Save projects cache to disk
|
|
66
|
+
*/
|
|
67
|
+
private saveProjectsCache;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=project-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-manager.d.ts","sourceRoot":"","sources":["../src/project-manager.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,aAAa,CAAmC;;IASxD;;;OAGG;IACG,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuE1D;;OAEG;IACG,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB9D;;;OAGG;IACH,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAQzC;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAKvC;;OAEG;IACH,YAAY,IAAI,OAAO,EAAE;IAKzB;;OAEG;IACH,iBAAiB,IAAI,OAAO,GAAG,IAAI;IAInC;;OAEG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE;QAC/C,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBtB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAa1B"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { MCPLogger as Logger } from './utils/mcp-logger.js';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import crypto from 'crypto';
|
|
5
|
+
const logger = new Logger('ProjectManager');
|
|
6
|
+
/**
|
|
7
|
+
* Smart Project Manager - Handles project isolation and auto-detection
|
|
8
|
+
*
|
|
9
|
+
* KEY FEATURES:
|
|
10
|
+
* - Each project gets COMPLETELY ISOLATED database
|
|
11
|
+
* - Auto-detects project from working directory
|
|
12
|
+
* - No memory pollution between projects
|
|
13
|
+
* - Clean project switching
|
|
14
|
+
*/
|
|
15
|
+
export class ProjectManager {
|
|
16
|
+
kratosHome;
|
|
17
|
+
currentProject = null;
|
|
18
|
+
projectsCache = new Map();
|
|
19
|
+
constructor() {
|
|
20
|
+
// All Kratos data lives in user home, organized by project
|
|
21
|
+
this.kratosHome = path.join(process.env.HOME || process.env.USERPROFILE || '', '.kratos');
|
|
22
|
+
fs.ensureDirSync(this.kratosHome);
|
|
23
|
+
this.loadProjectsCache();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Auto-detect project from current working directory
|
|
27
|
+
* Creates a project ID based on the directory path
|
|
28
|
+
*/
|
|
29
|
+
async detectProject(workingDir) {
|
|
30
|
+
const dir = workingDir || process.cwd();
|
|
31
|
+
// Look for project markers in order of preference
|
|
32
|
+
const markers = [
|
|
33
|
+
'.git', // Git repo
|
|
34
|
+
'package.json', // Node project
|
|
35
|
+
'Cargo.toml', // Rust project
|
|
36
|
+
'go.mod', // Go project
|
|
37
|
+
'pyproject.toml', // Python project
|
|
38
|
+
'.kratos', // Existing Kratos project
|
|
39
|
+
];
|
|
40
|
+
let projectRoot = dir;
|
|
41
|
+
let found = false;
|
|
42
|
+
// Walk up directory tree to find project root
|
|
43
|
+
let currentDir = dir;
|
|
44
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
45
|
+
for (const marker of markers) {
|
|
46
|
+
if (await fs.pathExists(path.join(currentDir, marker))) {
|
|
47
|
+
projectRoot = currentDir;
|
|
48
|
+
found = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (found)
|
|
53
|
+
break;
|
|
54
|
+
currentDir = path.dirname(currentDir);
|
|
55
|
+
}
|
|
56
|
+
// Generate stable project ID from path
|
|
57
|
+
const projectId = this.generateProjectId(projectRoot);
|
|
58
|
+
const projectName = path.basename(projectRoot);
|
|
59
|
+
// Check if we already know this project
|
|
60
|
+
let project = this.projectsCache.get(projectId);
|
|
61
|
+
if (!project) {
|
|
62
|
+
// New project - create it
|
|
63
|
+
project = {
|
|
64
|
+
id: projectId,
|
|
65
|
+
name: projectName,
|
|
66
|
+
root: projectRoot,
|
|
67
|
+
createdAt: new Date(),
|
|
68
|
+
lastAccessed: new Date()
|
|
69
|
+
};
|
|
70
|
+
// Create isolated project directory
|
|
71
|
+
const projectDir = this.getProjectDir(projectId);
|
|
72
|
+
await fs.ensureDir(projectDir);
|
|
73
|
+
// Save project metadata
|
|
74
|
+
await fs.writeJson(path.join(projectDir, 'project.json'), project, { spaces: 2 });
|
|
75
|
+
this.projectsCache.set(projectId, project);
|
|
76
|
+
logger.info(`Created new project: ${projectName} (${projectId})`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Update last accessed
|
|
80
|
+
project.lastAccessed = new Date();
|
|
81
|
+
}
|
|
82
|
+
this.currentProject = project;
|
|
83
|
+
this.saveProjectsCache();
|
|
84
|
+
return project;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Switch to a different project
|
|
88
|
+
*/
|
|
89
|
+
async switchProject(projectIdOrPath) {
|
|
90
|
+
// Check if it's a project ID
|
|
91
|
+
let project = this.projectsCache.get(projectIdOrPath);
|
|
92
|
+
if (!project) {
|
|
93
|
+
// Maybe it's a path - detect project from it
|
|
94
|
+
if (await fs.pathExists(projectIdOrPath)) {
|
|
95
|
+
project = await this.detectProject(projectIdOrPath);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
throw new Error(`Project not found: ${projectIdOrPath}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
this.currentProject = project;
|
|
102
|
+
project.lastAccessed = new Date();
|
|
103
|
+
this.saveProjectsCache();
|
|
104
|
+
logger.info(`Switched to project: ${project.name}`);
|
|
105
|
+
return project;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get the isolated directory for a project
|
|
109
|
+
* This is where ALL project data lives - memories, concepts, etc.
|
|
110
|
+
*/
|
|
111
|
+
getProjectDir(projectId) {
|
|
112
|
+
const id = projectId || this.currentProject?.id;
|
|
113
|
+
if (!id) {
|
|
114
|
+
throw new Error('No active project');
|
|
115
|
+
}
|
|
116
|
+
return path.join(this.kratosHome, 'projects', id);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get database path for current project
|
|
120
|
+
* COMPLETELY ISOLATED - no cross-contamination possible
|
|
121
|
+
*/
|
|
122
|
+
getDatabasePath(dbName) {
|
|
123
|
+
const projectDir = this.getProjectDir();
|
|
124
|
+
return path.join(projectDir, 'databases', `${dbName}.db`);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* List all known projects
|
|
128
|
+
*/
|
|
129
|
+
listProjects() {
|
|
130
|
+
return Array.from(this.projectsCache.values())
|
|
131
|
+
.sort((a, b) => b.lastAccessed.getTime() - a.lastAccessed.getTime());
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get current active project
|
|
135
|
+
*/
|
|
136
|
+
getCurrentProject() {
|
|
137
|
+
return this.currentProject;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Clean up old project data (optional)
|
|
141
|
+
*/
|
|
142
|
+
async cleanupProject(projectId, options = {}) {
|
|
143
|
+
const projectDir = this.getProjectDir(projectId);
|
|
144
|
+
if (!options.keepMemories) {
|
|
145
|
+
const memoriesDb = path.join(projectDir, 'databases', 'memories.db');
|
|
146
|
+
if (await fs.pathExists(memoriesDb)) {
|
|
147
|
+
await fs.remove(memoriesDb);
|
|
148
|
+
logger.info(`Cleaned up memories for project ${projectId}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (!options.keepConcepts) {
|
|
152
|
+
const conceptsDb = path.join(projectDir, 'databases', 'concepts.db');
|
|
153
|
+
if (await fs.pathExists(conceptsDb)) {
|
|
154
|
+
await fs.remove(conceptsDb);
|
|
155
|
+
logger.info(`Cleaned up concepts for project ${projectId}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Generate stable project ID from path
|
|
161
|
+
*/
|
|
162
|
+
generateProjectId(projectPath) {
|
|
163
|
+
// Use hash of normalized path for stable ID
|
|
164
|
+
const normalized = path.resolve(projectPath).toLowerCase();
|
|
165
|
+
const hash = crypto.createHash('sha256').update(normalized).digest('hex');
|
|
166
|
+
return `proj_${hash.substring(0, 12)}`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Load projects cache from disk
|
|
170
|
+
*/
|
|
171
|
+
loadProjectsCache() {
|
|
172
|
+
const cacheFile = path.join(this.kratosHome, 'projects.json');
|
|
173
|
+
if (fs.existsSync(cacheFile)) {
|
|
174
|
+
try {
|
|
175
|
+
const cache = fs.readJsonSync(cacheFile);
|
|
176
|
+
for (const project of cache.projects || []) {
|
|
177
|
+
this.projectsCache.set(project.id, {
|
|
178
|
+
...project,
|
|
179
|
+
createdAt: new Date(project.createdAt),
|
|
180
|
+
lastAccessed: new Date(project.lastAccessed)
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
logger.info(`Loaded ${this.projectsCache.size} projects from cache`);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
logger.error('Failed to load projects cache:', error);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Save projects cache to disk
|
|
192
|
+
*/
|
|
193
|
+
saveProjectsCache() {
|
|
194
|
+
const cacheFile = path.join(this.kratosHome, 'projects.json');
|
|
195
|
+
const cache = {
|
|
196
|
+
projects: Array.from(this.projectsCache.values()),
|
|
197
|
+
lastUpdated: new Date()
|
|
198
|
+
};
|
|
199
|
+
try {
|
|
200
|
+
fs.writeJsonSync(cacheFile, cache, { spaces: 2 });
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
logger.error('Failed to save projects cache:', error);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=project-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-manager.js","sourceRoot":"","sources":["../src/project-manager.ts"],"names":[],"mappings":"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"}
|