@nclamvn/vibecode-cli 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vibecode/learning/fixes.json +1 -0
- package/.vibecode/learning/preferences.json +1 -0
- package/README.md +310 -49
- package/SESSION_NOTES.md +154 -0
- package/bin/vibecode.js +235 -2
- package/package.json +5 -2
- package/src/agent/decomposition.js +476 -0
- package/src/agent/index.js +391 -0
- package/src/agent/memory.js +542 -0
- package/src/agent/orchestrator.js +917 -0
- package/src/agent/self-healing.js +516 -0
- package/src/commands/agent.js +349 -0
- package/src/commands/ask.js +230 -0
- package/src/commands/assist.js +413 -0
- package/src/commands/build.js +345 -4
- package/src/commands/debug.js +565 -0
- package/src/commands/docs.js +167 -0
- package/src/commands/git.js +1024 -0
- package/src/commands/go.js +635 -0
- package/src/commands/learn.js +294 -0
- package/src/commands/migrate.js +341 -0
- package/src/commands/plan.js +8 -2
- package/src/commands/refactor.js +205 -0
- package/src/commands/review.js +126 -1
- package/src/commands/security.js +229 -0
- package/src/commands/shell.js +486 -0
- package/src/commands/templates.js +397 -0
- package/src/commands/test.js +194 -0
- package/src/commands/undo.js +281 -0
- package/src/commands/watch.js +556 -0
- package/src/commands/wizard.js +322 -0
- package/src/config/constants.js +5 -1
- package/src/config/templates.js +146 -15
- package/src/core/backup.js +325 -0
- package/src/core/error-analyzer.js +237 -0
- package/src/core/fix-generator.js +195 -0
- package/src/core/iteration.js +226 -0
- package/src/core/learning.js +295 -0
- package/src/core/session.js +18 -2
- package/src/core/test-runner.js +281 -0
- package/src/debug/analyzer.js +329 -0
- package/src/debug/evidence.js +228 -0
- package/src/debug/fixer.js +348 -0
- package/src/debug/image-analyzer.js +304 -0
- package/src/debug/index.js +378 -0
- package/src/debug/verifier.js +346 -0
- package/src/index.js +102 -0
- package/src/providers/claude-code.js +12 -7
- package/src/templates/index.js +724 -0
- package/src/ui/__tests__/error-translator.test.js +390 -0
- package/src/ui/dashboard.js +364 -0
- package/src/ui/error-translator.js +775 -0
- package/src/utils/image.js +222 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// VIBECODE AGENT - Memory Engine
|
|
3
|
+
// Persistent context and learning across module builds
|
|
4
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
+
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Memory categories for organization
|
|
11
|
+
*/
|
|
12
|
+
const MEMORY_CATEGORIES = {
|
|
13
|
+
DECISIONS: 'decisions', // Architectural/design decisions made
|
|
14
|
+
PATTERNS: 'patterns', // Code patterns discovered/used
|
|
15
|
+
ERRORS: 'errors', // Errors encountered and how they were fixed
|
|
16
|
+
FILES: 'files', // Files created/modified
|
|
17
|
+
CONTEXT: 'context', // Project context and requirements
|
|
18
|
+
LEARNINGS: 'learnings' // What worked/didn't work
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Memory Engine Class
|
|
23
|
+
* Maintains persistent context across module builds
|
|
24
|
+
*/
|
|
25
|
+
export class MemoryEngine {
|
|
26
|
+
constructor(memoryPath) {
|
|
27
|
+
this.memoryPath = memoryPath;
|
|
28
|
+
this.memory = {
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
created: new Date().toISOString(),
|
|
31
|
+
updated: new Date().toISOString(),
|
|
32
|
+
projectContext: {},
|
|
33
|
+
modules: {},
|
|
34
|
+
decisions: [],
|
|
35
|
+
patterns: [],
|
|
36
|
+
errors: [],
|
|
37
|
+
files: {},
|
|
38
|
+
learnings: [],
|
|
39
|
+
globalContext: ''
|
|
40
|
+
};
|
|
41
|
+
this.loaded = false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initialize memory storage
|
|
46
|
+
*/
|
|
47
|
+
async initialize() {
|
|
48
|
+
await fs.ensureDir(path.dirname(this.memoryPath));
|
|
49
|
+
|
|
50
|
+
if (await fs.pathExists(this.memoryPath)) {
|
|
51
|
+
await this.load();
|
|
52
|
+
} else {
|
|
53
|
+
await this.save();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.loaded = true;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Load memory from disk
|
|
62
|
+
*/
|
|
63
|
+
async load() {
|
|
64
|
+
try {
|
|
65
|
+
const data = await fs.readJson(this.memoryPath);
|
|
66
|
+
this.memory = { ...this.memory, ...data };
|
|
67
|
+
this.loaded = true;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.warn(`Could not load memory: ${error.message}`);
|
|
70
|
+
}
|
|
71
|
+
return this.memory;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Save memory to disk
|
|
76
|
+
*/
|
|
77
|
+
async save() {
|
|
78
|
+
this.memory.updated = new Date().toISOString();
|
|
79
|
+
await fs.writeJson(this.memoryPath, this.memory, { spaces: 2 });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
83
|
+
// PROJECT CONTEXT
|
|
84
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Set project context
|
|
88
|
+
*/
|
|
89
|
+
setProjectContext(context) {
|
|
90
|
+
this.memory.projectContext = {
|
|
91
|
+
...this.memory.projectContext,
|
|
92
|
+
...context,
|
|
93
|
+
updatedAt: new Date().toISOString()
|
|
94
|
+
};
|
|
95
|
+
return this.save();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get project context
|
|
100
|
+
*/
|
|
101
|
+
getProjectContext() {
|
|
102
|
+
return this.memory.projectContext;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
106
|
+
// MODULE MEMORY
|
|
107
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Start tracking a module
|
|
111
|
+
*/
|
|
112
|
+
startModule(moduleId, moduleData) {
|
|
113
|
+
this.memory.modules[moduleId] = {
|
|
114
|
+
...moduleData,
|
|
115
|
+
startedAt: new Date().toISOString(),
|
|
116
|
+
status: 'in_progress',
|
|
117
|
+
attempts: 0,
|
|
118
|
+
files: [],
|
|
119
|
+
errors: [],
|
|
120
|
+
decisions: []
|
|
121
|
+
};
|
|
122
|
+
return this.save();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Update module status
|
|
127
|
+
*/
|
|
128
|
+
async updateModule(moduleId, updates) {
|
|
129
|
+
if (this.memory.modules[moduleId]) {
|
|
130
|
+
this.memory.modules[moduleId] = {
|
|
131
|
+
...this.memory.modules[moduleId],
|
|
132
|
+
...updates,
|
|
133
|
+
updatedAt: new Date().toISOString()
|
|
134
|
+
};
|
|
135
|
+
await this.save();
|
|
136
|
+
}
|
|
137
|
+
return this.memory.modules[moduleId];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Complete a module
|
|
142
|
+
*/
|
|
143
|
+
async completeModule(moduleId, result) {
|
|
144
|
+
return this.updateModule(moduleId, {
|
|
145
|
+
status: 'completed',
|
|
146
|
+
completedAt: new Date().toISOString(),
|
|
147
|
+
result
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Fail a module
|
|
153
|
+
*/
|
|
154
|
+
async failModule(moduleId, error) {
|
|
155
|
+
const mod = this.memory.modules[moduleId];
|
|
156
|
+
if (mod) {
|
|
157
|
+
mod.attempts = (mod.attempts || 0) + 1;
|
|
158
|
+
mod.errors.push({
|
|
159
|
+
error: error.message || error,
|
|
160
|
+
timestamp: new Date().toISOString()
|
|
161
|
+
});
|
|
162
|
+
mod.status = 'failed';
|
|
163
|
+
await this.save();
|
|
164
|
+
}
|
|
165
|
+
return mod;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get module memory
|
|
170
|
+
*/
|
|
171
|
+
getModule(moduleId) {
|
|
172
|
+
return this.memory.modules[moduleId];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Get all completed modules
|
|
177
|
+
*/
|
|
178
|
+
getCompletedModules() {
|
|
179
|
+
return Object.entries(this.memory.modules)
|
|
180
|
+
.filter(([_, mod]) => mod.status === 'completed')
|
|
181
|
+
.map(([id, mod]) => ({ id, ...mod }));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
185
|
+
// DECISIONS
|
|
186
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Record a decision
|
|
190
|
+
*/
|
|
191
|
+
async recordDecision(decision) {
|
|
192
|
+
this.memory.decisions.push({
|
|
193
|
+
...decision,
|
|
194
|
+
id: `dec_${Date.now()}`,
|
|
195
|
+
timestamp: new Date().toISOString()
|
|
196
|
+
});
|
|
197
|
+
await this.save();
|
|
198
|
+
return decision;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get decisions by category
|
|
203
|
+
*/
|
|
204
|
+
getDecisions(category = null) {
|
|
205
|
+
if (!category) return this.memory.decisions;
|
|
206
|
+
return this.memory.decisions.filter(d => d.category === category);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get decisions for a specific module
|
|
211
|
+
*/
|
|
212
|
+
getModuleDecisions(moduleId) {
|
|
213
|
+
return this.memory.decisions.filter(d => d.moduleId === moduleId);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
217
|
+
// PATTERNS
|
|
218
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Record a code pattern
|
|
222
|
+
*/
|
|
223
|
+
async recordPattern(pattern) {
|
|
224
|
+
// Check if similar pattern exists
|
|
225
|
+
const existing = this.memory.patterns.find(p =>
|
|
226
|
+
p.name === pattern.name || p.pattern === pattern.pattern
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
if (existing) {
|
|
230
|
+
existing.usageCount = (existing.usageCount || 1) + 1;
|
|
231
|
+
existing.lastUsed = new Date().toISOString();
|
|
232
|
+
} else {
|
|
233
|
+
this.memory.patterns.push({
|
|
234
|
+
...pattern,
|
|
235
|
+
id: `pat_${Date.now()}`,
|
|
236
|
+
usageCount: 1,
|
|
237
|
+
discoveredAt: new Date().toISOString(),
|
|
238
|
+
lastUsed: new Date().toISOString()
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
await this.save();
|
|
243
|
+
return pattern;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get patterns by type
|
|
248
|
+
*/
|
|
249
|
+
getPatterns(type = null) {
|
|
250
|
+
if (!type) return this.memory.patterns;
|
|
251
|
+
return this.memory.patterns.filter(p => p.type === type);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get most used patterns
|
|
256
|
+
*/
|
|
257
|
+
getPopularPatterns(limit = 5) {
|
|
258
|
+
return [...this.memory.patterns]
|
|
259
|
+
.sort((a, b) => (b.usageCount || 0) - (a.usageCount || 0))
|
|
260
|
+
.slice(0, limit);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
264
|
+
// ERRORS & FIXES
|
|
265
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Record an error and its fix
|
|
269
|
+
*/
|
|
270
|
+
async recordError(error) {
|
|
271
|
+
this.memory.errors.push({
|
|
272
|
+
...error,
|
|
273
|
+
id: `err_${Date.now()}`,
|
|
274
|
+
timestamp: new Date().toISOString()
|
|
275
|
+
});
|
|
276
|
+
await this.save();
|
|
277
|
+
return error;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Record a fix for an error
|
|
282
|
+
*/
|
|
283
|
+
async recordFix(errorId, fix) {
|
|
284
|
+
const error = this.memory.errors.find(e => e.id === errorId);
|
|
285
|
+
if (error) {
|
|
286
|
+
error.fix = fix;
|
|
287
|
+
error.fixed = true;
|
|
288
|
+
error.fixedAt = new Date().toISOString();
|
|
289
|
+
await this.save();
|
|
290
|
+
}
|
|
291
|
+
return error;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Find similar errors from history
|
|
296
|
+
*/
|
|
297
|
+
findSimilarErrors(errorMessage) {
|
|
298
|
+
const keywords = errorMessage.toLowerCase().split(/\s+/).filter(w => w.length > 3);
|
|
299
|
+
|
|
300
|
+
return this.memory.errors
|
|
301
|
+
.filter(e => e.fixed && e.fix)
|
|
302
|
+
.map(e => {
|
|
303
|
+
const errorText = (e.message || '').toLowerCase();
|
|
304
|
+
const matchCount = keywords.filter(kw => errorText.includes(kw)).length;
|
|
305
|
+
return { error: e, matchScore: matchCount / keywords.length };
|
|
306
|
+
})
|
|
307
|
+
.filter(item => item.matchScore > 0.3)
|
|
308
|
+
.sort((a, b) => b.matchScore - a.matchScore)
|
|
309
|
+
.map(item => item.error);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
313
|
+
// FILES
|
|
314
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Record a file creation/modification
|
|
318
|
+
*/
|
|
319
|
+
async recordFile(filePath, metadata) {
|
|
320
|
+
this.memory.files[filePath] = {
|
|
321
|
+
...metadata,
|
|
322
|
+
path: filePath,
|
|
323
|
+
updatedAt: new Date().toISOString()
|
|
324
|
+
};
|
|
325
|
+
await this.save();
|
|
326
|
+
return this.memory.files[filePath];
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Get all recorded files
|
|
331
|
+
*/
|
|
332
|
+
getFiles() {
|
|
333
|
+
return this.memory.files;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Get files by module
|
|
338
|
+
*/
|
|
339
|
+
getFilesByModule(moduleId) {
|
|
340
|
+
return Object.values(this.memory.files)
|
|
341
|
+
.filter(f => f.moduleId === moduleId);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
345
|
+
// LEARNINGS
|
|
346
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Record a learning (what worked/didn't work)
|
|
350
|
+
*/
|
|
351
|
+
async recordLearning(learning) {
|
|
352
|
+
this.memory.learnings.push({
|
|
353
|
+
...learning,
|
|
354
|
+
id: `learn_${Date.now()}`,
|
|
355
|
+
timestamp: new Date().toISOString()
|
|
356
|
+
});
|
|
357
|
+
await this.save();
|
|
358
|
+
return learning;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Get positive learnings (what worked)
|
|
363
|
+
*/
|
|
364
|
+
getPositiveLearnings() {
|
|
365
|
+
return this.memory.learnings.filter(l => l.outcome === 'success');
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Get negative learnings (what didn't work)
|
|
370
|
+
*/
|
|
371
|
+
getNegativeLearnings() {
|
|
372
|
+
return this.memory.learnings.filter(l => l.outcome === 'failure');
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
376
|
+
// CONTEXT GENERATION
|
|
377
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Generate context summary for Claude Code
|
|
381
|
+
*/
|
|
382
|
+
generateContextSummary() {
|
|
383
|
+
const completed = this.getCompletedModules();
|
|
384
|
+
const patterns = this.getPopularPatterns(3);
|
|
385
|
+
const recentDecisions = this.memory.decisions.slice(-5);
|
|
386
|
+
|
|
387
|
+
let summary = `# Agent Memory Context\n\n`;
|
|
388
|
+
|
|
389
|
+
// Project Context
|
|
390
|
+
if (this.memory.projectContext.description) {
|
|
391
|
+
summary += `## Project\n${this.memory.projectContext.description}\n\n`;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Completed Modules
|
|
395
|
+
if (completed.length > 0) {
|
|
396
|
+
summary += `## Completed Modules (${completed.length})\n`;
|
|
397
|
+
for (const mod of completed) {
|
|
398
|
+
summary += `- **${mod.name || mod.id}**: ${mod.files?.length || 0} files\n`;
|
|
399
|
+
}
|
|
400
|
+
summary += '\n';
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Key Patterns
|
|
404
|
+
if (patterns.length > 0) {
|
|
405
|
+
summary += `## Established Patterns\n`;
|
|
406
|
+
for (const pat of patterns) {
|
|
407
|
+
summary += `- **${pat.name}**: ${pat.description || pat.pattern}\n`;
|
|
408
|
+
}
|
|
409
|
+
summary += '\n';
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Recent Decisions
|
|
413
|
+
if (recentDecisions.length > 0) {
|
|
414
|
+
summary += `## Recent Decisions\n`;
|
|
415
|
+
for (const dec of recentDecisions) {
|
|
416
|
+
summary += `- ${dec.decision}: ${dec.reason || ''}\n`;
|
|
417
|
+
}
|
|
418
|
+
summary += '\n';
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// File Structure
|
|
422
|
+
const files = Object.keys(this.memory.files);
|
|
423
|
+
if (files.length > 0) {
|
|
424
|
+
summary += `## Created Files (${files.length})\n`;
|
|
425
|
+
summary += '```\n';
|
|
426
|
+
summary += files.slice(0, 20).join('\n');
|
|
427
|
+
if (files.length > 20) {
|
|
428
|
+
summary += `\n... and ${files.length - 20} more`;
|
|
429
|
+
}
|
|
430
|
+
summary += '\n```\n';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return summary;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Get condensed context for prompts (shorter version)
|
|
438
|
+
*/
|
|
439
|
+
getCondensedContext() {
|
|
440
|
+
const completed = this.getCompletedModules();
|
|
441
|
+
const files = Object.keys(this.memory.files);
|
|
442
|
+
|
|
443
|
+
return {
|
|
444
|
+
projectType: this.memory.projectContext.type,
|
|
445
|
+
completedModules: completed.map(m => m.id),
|
|
446
|
+
fileCount: files.length,
|
|
447
|
+
recentFiles: files.slice(-10),
|
|
448
|
+
patterns: this.getPopularPatterns(3).map(p => p.name),
|
|
449
|
+
errorCount: this.memory.errors.length,
|
|
450
|
+
fixedCount: this.memory.errors.filter(e => e.fixed).length
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
455
|
+
// UTILITIES
|
|
456
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Get memory statistics
|
|
460
|
+
*/
|
|
461
|
+
getStats() {
|
|
462
|
+
return {
|
|
463
|
+
modulesTotal: Object.keys(this.memory.modules).length,
|
|
464
|
+
modulesCompleted: Object.values(this.memory.modules).filter(m => m.status === 'completed').length,
|
|
465
|
+
modulesFailed: Object.values(this.memory.modules).filter(m => m.status === 'failed').length,
|
|
466
|
+
decisionsCount: this.memory.decisions.length,
|
|
467
|
+
patternsCount: this.memory.patterns.length,
|
|
468
|
+
errorsTotal: this.memory.errors.length,
|
|
469
|
+
errorsFixed: this.memory.errors.filter(e => e.fixed).length,
|
|
470
|
+
filesCreated: Object.keys(this.memory.files).length,
|
|
471
|
+
learningsCount: this.memory.learnings.length
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Clear all memory (reset)
|
|
477
|
+
*/
|
|
478
|
+
async clear() {
|
|
479
|
+
this.memory = {
|
|
480
|
+
version: '1.0.0',
|
|
481
|
+
created: new Date().toISOString(),
|
|
482
|
+
updated: new Date().toISOString(),
|
|
483
|
+
projectContext: {},
|
|
484
|
+
modules: {},
|
|
485
|
+
decisions: [],
|
|
486
|
+
patterns: [],
|
|
487
|
+
errors: [],
|
|
488
|
+
files: {},
|
|
489
|
+
learnings: [],
|
|
490
|
+
globalContext: ''
|
|
491
|
+
};
|
|
492
|
+
await this.save();
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Export memory to markdown report
|
|
497
|
+
*/
|
|
498
|
+
exportToMarkdown() {
|
|
499
|
+
let md = `# Vibecode Agent Memory Report\n\n`;
|
|
500
|
+
md += `Generated: ${new Date().toISOString()}\n\n`;
|
|
501
|
+
|
|
502
|
+
// Stats
|
|
503
|
+
const stats = this.getStats();
|
|
504
|
+
md += `## Statistics\n`;
|
|
505
|
+
md += `| Metric | Value |\n|--------|-------|\n`;
|
|
506
|
+
for (const [key, value] of Object.entries(stats)) {
|
|
507
|
+
md += `| ${key} | ${value} |\n`;
|
|
508
|
+
}
|
|
509
|
+
md += '\n';
|
|
510
|
+
|
|
511
|
+
// Context Summary
|
|
512
|
+
md += this.generateContextSummary();
|
|
513
|
+
|
|
514
|
+
// Errors and Fixes
|
|
515
|
+
if (this.memory.errors.length > 0) {
|
|
516
|
+
md += `## Error History\n\n`;
|
|
517
|
+
for (const err of this.memory.errors.slice(-10)) {
|
|
518
|
+
md += `### ${err.type || 'Error'}\n`;
|
|
519
|
+
md += `- Message: ${err.message}\n`;
|
|
520
|
+
md += `- Module: ${err.moduleId || 'N/A'}\n`;
|
|
521
|
+
if (err.fix) {
|
|
522
|
+
md += `- Fix: ${err.fix}\n`;
|
|
523
|
+
}
|
|
524
|
+
md += '\n';
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return md;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Create memory engine instance
|
|
534
|
+
*/
|
|
535
|
+
export async function createMemoryEngine(projectPath) {
|
|
536
|
+
const memoryPath = path.join(projectPath, '.vibecode', 'agent', 'memory.json');
|
|
537
|
+
const engine = new MemoryEngine(memoryPath);
|
|
538
|
+
await engine.initialize();
|
|
539
|
+
return engine;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export { MEMORY_CATEGORIES };
|