@xagent-ai/cli 1.2.0 → 1.2.2
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 +1 -1
- package/README_CN.md +1 -1
- package/dist/agents.js +164 -164
- package/dist/agents.js.map +1 -1
- package/dist/ai-client.d.ts +4 -6
- package/dist/ai-client.d.ts.map +1 -1
- package/dist/ai-client.js +137 -115
- package/dist/ai-client.js.map +1 -1
- package/dist/auth.js +4 -4
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +184 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.js +3 -3
- package/dist/config.js.map +1 -1
- package/dist/context-compressor.d.ts.map +1 -1
- package/dist/context-compressor.js +65 -81
- package/dist/context-compressor.js.map +1 -1
- package/dist/conversation.d.ts +1 -1
- package/dist/conversation.d.ts.map +1 -1
- package/dist/conversation.js +5 -31
- package/dist/conversation.js.map +1 -1
- package/dist/memory.d.ts +5 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +77 -37
- package/dist/memory.js.map +1 -1
- package/dist/remote-ai-client.d.ts +1 -8
- package/dist/remote-ai-client.d.ts.map +1 -1
- package/dist/remote-ai-client.js +55 -65
- package/dist/remote-ai-client.js.map +1 -1
- package/dist/retry.d.ts +35 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +166 -0
- package/dist/retry.js.map +1 -0
- package/dist/session.d.ts +0 -5
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +243 -312
- package/dist/session.js.map +1 -1
- package/dist/slash-commands.d.ts +1 -0
- package/dist/slash-commands.d.ts.map +1 -1
- package/dist/slash-commands.js +91 -9
- package/dist/slash-commands.js.map +1 -1
- package/dist/smart-approval.d.ts.map +1 -1
- package/dist/smart-approval.js +18 -17
- package/dist/smart-approval.js.map +1 -1
- package/dist/system-prompt-generator.d.ts.map +1 -1
- package/dist/system-prompt-generator.js +149 -139
- package/dist/system-prompt-generator.js.map +1 -1
- package/dist/theme.d.ts +48 -0
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +254 -0
- package/dist/theme.js.map +1 -1
- package/dist/tools/edit-diff.d.ts +32 -0
- package/dist/tools/edit-diff.d.ts.map +1 -0
- package/dist/tools/edit-diff.js +185 -0
- package/dist/tools/edit-diff.js.map +1 -0
- package/dist/tools/edit.d.ts +11 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +129 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools.d.ts +19 -5
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +979 -631
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +6 -31
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/agents.ts +504 -504
- package/src/ai-client.ts +1559 -1458
- package/src/auth.ts +4 -4
- package/src/cli.ts +195 -1
- package/src/config.ts +3 -3
- package/src/memory.ts +55 -14
- package/src/remote-ai-client.ts +663 -683
- package/src/retry.ts +217 -0
- package/src/session.ts +1736 -1840
- package/src/slash-commands.ts +98 -9
- package/src/smart-approval.ts +626 -625
- package/src/system-prompt-generator.ts +853 -843
- package/src/theme.ts +284 -0
- package/src/tools.ts +390 -70
package/src/auth.ts
CHANGED
|
@@ -163,7 +163,7 @@ export class AuthService {
|
|
|
163
163
|
const token = await this.retrieveXAgentToken();
|
|
164
164
|
|
|
165
165
|
// 2. 调用后端验证用户
|
|
166
|
-
const xagentApiBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://
|
|
166
|
+
const xagentApiBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
|
|
167
167
|
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
168
168
|
const response = await axios.get(`${xagentApiBaseUrl}/api/auth/me`, {
|
|
169
169
|
headers: { 'Authorization': `Bearer ${token}` },
|
|
@@ -171,7 +171,7 @@ export class AuthService {
|
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
// 3. Set authentication configuration
|
|
174
|
-
this.authConfig.baseUrl = 'https://
|
|
174
|
+
this.authConfig.baseUrl = 'https://www.xagent-colife.net/v1';
|
|
175
175
|
this.authConfig.xagentApiBaseUrl = xagentApiBaseUrl;
|
|
176
176
|
this.authConfig.apiKey = token;
|
|
177
177
|
this.authConfig.type = AuthType.OAUTH_XAGENT;
|
|
@@ -376,10 +376,10 @@ export class AuthService {
|
|
|
376
376
|
|
|
377
377
|
private async retrieveXAgentToken(): Promise<string> {
|
|
378
378
|
// Use xagentApiBaseUrl from config, fallback to default
|
|
379
|
-
const webBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://
|
|
379
|
+
const webBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
|
|
380
380
|
const authUrl = `${webBaseUrl}/login`;
|
|
381
381
|
// Callback URL tells frontend where to store token
|
|
382
|
-
const callbackUrl = 'https://
|
|
382
|
+
const callbackUrl = 'https://www.xagent-colife.net/callback';
|
|
383
383
|
|
|
384
384
|
// 如果已有保存的token,通过URL参数传给Web页面
|
|
385
385
|
const existingToken = this.authConfig.apiKey;
|
package/src/cli.ts
CHANGED
|
@@ -10,9 +10,11 @@ import { getMCPManager } from './mcp.js';
|
|
|
10
10
|
import { getLogger, setConfigProvider } from './logger.js';
|
|
11
11
|
import { theme, icons, colors } from './theme.js';
|
|
12
12
|
import { getCancellationManager } from './cancellation.js';
|
|
13
|
-
import { readFileSync } from 'fs';
|
|
13
|
+
import { readFileSync, promises as fs } from 'fs';
|
|
14
|
+
import path from 'path';
|
|
14
15
|
import { dirname, join } from 'path';
|
|
15
16
|
import { fileURLToPath } from 'url';
|
|
17
|
+
import { glob } from 'glob';
|
|
16
18
|
|
|
17
19
|
// Get current directory
|
|
18
20
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -517,6 +519,198 @@ program
|
|
|
517
519
|
}
|
|
518
520
|
});
|
|
519
521
|
|
|
522
|
+
program
|
|
523
|
+
.command('memory')
|
|
524
|
+
.description('Manage memory files (list or clean)')
|
|
525
|
+
.option('-l, --list', 'List all memory files')
|
|
526
|
+
.option('--clean', 'Clean all project memories (keep global memory)')
|
|
527
|
+
.option('--clean-project', 'Clean the current project\'s memory only')
|
|
528
|
+
.option('--clean-all', 'Clean all memories (including global memory)')
|
|
529
|
+
.action(async (options) => {
|
|
530
|
+
const separator = icons.separator.repeat(40);
|
|
531
|
+
console.log('');
|
|
532
|
+
console.log(colors.primaryBright(`${icons.folder} Memory Management`));
|
|
533
|
+
console.log(colors.border(separator));
|
|
534
|
+
console.log('');
|
|
535
|
+
|
|
536
|
+
const { getMemoryManager } = await import('./memory.js');
|
|
537
|
+
const memoryManager = getMemoryManager(process.cwd());
|
|
538
|
+
const memoriesDir = memoryManager.getMemoriesDir();
|
|
539
|
+
|
|
540
|
+
// Helper to get memory info
|
|
541
|
+
const getMemoryInfo = (fileName: string) => {
|
|
542
|
+
if (fileName === 'global.md') {
|
|
543
|
+
return { type: 'global', description: 'Global memory (shared across all projects)' };
|
|
544
|
+
}
|
|
545
|
+
const match = fileName.match(/^project_(.+)_\w{16}\.md$/);
|
|
546
|
+
if (match) {
|
|
547
|
+
return { type: 'project', description: `Project: ${match[1]}` };
|
|
548
|
+
}
|
|
549
|
+
return { type: 'unknown', description: fileName };
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
if (options.list) {
|
|
553
|
+
// List all memory files
|
|
554
|
+
console.log(colors.textMuted(`Memory directory: ${memoriesDir}`));
|
|
555
|
+
console.log('');
|
|
556
|
+
|
|
557
|
+
try {
|
|
558
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
559
|
+
if (files.length === 0) {
|
|
560
|
+
console.log(colors.textMuted('No memory files found.'));
|
|
561
|
+
console.log('');
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const globalFile = files.find(f => f === 'global.md');
|
|
566
|
+
const projectFiles = files.filter(f => f.startsWith('project_'));
|
|
567
|
+
|
|
568
|
+
if (globalFile) {
|
|
569
|
+
const info = getMemoryInfo(globalFile);
|
|
570
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright('global.md')}`);
|
|
571
|
+
console.log(` ${colors.textDim(` ${info.description}`)}`);
|
|
572
|
+
console.log('');
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (projectFiles.length > 0) {
|
|
576
|
+
console.log(colors.primaryBright(` Project Memories (${projectFiles.length})`));
|
|
577
|
+
console.log('');
|
|
578
|
+
|
|
579
|
+
for (const file of projectFiles) {
|
|
580
|
+
const info = getMemoryInfo(file);
|
|
581
|
+
const filePath = join(memoriesDir, file);
|
|
582
|
+
try {
|
|
583
|
+
const stat = await fs.stat(filePath);
|
|
584
|
+
const size = stat.size;
|
|
585
|
+
const sizeStr = size < 1024 ? `${size} B` : `${(size / 1024).toFixed(1)} KB`;
|
|
586
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright(file)}`);
|
|
587
|
+
console.log(` ${colors.textDim(` ${info.description} | Size: ${sizeStr}`)}`);
|
|
588
|
+
} catch {
|
|
589
|
+
console.log(` ${colors.success(icons.success)} ${colors.primaryBright(file)}`);
|
|
590
|
+
console.log(` ${colors.textDim(` ${info.description}`)}`);
|
|
591
|
+
}
|
|
592
|
+
console.log('');
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
console.log(colors.textMuted(`Total: ${files.length} memory file(s)`));
|
|
597
|
+
console.log('');
|
|
598
|
+
} catch (error) {
|
|
599
|
+
console.log(colors.textMuted('No memory files found.'));
|
|
600
|
+
console.log('');
|
|
601
|
+
}
|
|
602
|
+
} else if (options.clean) {
|
|
603
|
+
// Clean all project memories (keep global.md)
|
|
604
|
+
console.log(colors.textMuted('Cleaning all project memories...'));
|
|
605
|
+
console.log(colors.textMuted(`Keeping: ${colors.primaryBright('global.md')}`));
|
|
606
|
+
console.log('');
|
|
607
|
+
|
|
608
|
+
try {
|
|
609
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
610
|
+
const projectFiles = files.filter(f => f.startsWith('project_'));
|
|
611
|
+
|
|
612
|
+
if (projectFiles.length === 0) {
|
|
613
|
+
console.log(colors.textMuted('No project memories to clean.'));
|
|
614
|
+
console.log('');
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
let cleaned = 0;
|
|
619
|
+
for (const file of projectFiles) {
|
|
620
|
+
await fs.unlink(join(memoriesDir, file));
|
|
621
|
+
cleaned++;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
console.log(colors.success(`✅ Cleaned ${cleaned} project memory file(s)`));
|
|
625
|
+
// TODO: 如果需要自动重建 project memory,取消下面注释
|
|
626
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
627
|
+
// console.log(colors.textMuted(' Recreated current project memory'));
|
|
628
|
+
console.log(colors.textMuted(' Use /init to initialize if needed'));
|
|
629
|
+
console.log('');
|
|
630
|
+
} catch (error: any) {
|
|
631
|
+
const { message, suggestion } = formatError(error);
|
|
632
|
+
console.log(colors.error(`Failed to clean project memories: ${message}`));
|
|
633
|
+
console.log(colors.textMuted(suggestion));
|
|
634
|
+
console.log('');
|
|
635
|
+
}
|
|
636
|
+
} else if (options.cleanProject) {
|
|
637
|
+
// Clean only the current project's memory
|
|
638
|
+
console.log(colors.textMuted(`Cleaning current project memory...`));
|
|
639
|
+
console.log(colors.textMuted(`Project: ${colors.primaryBright(process.cwd())}`));
|
|
640
|
+
console.log('');
|
|
641
|
+
|
|
642
|
+
try {
|
|
643
|
+
// Find and delete the current project's memory file
|
|
644
|
+
const memoryFiles = memoryManager.getMemoryFiles();
|
|
645
|
+
const currentProjectMemory = memoryFiles.find(m => m.level === 'project');
|
|
646
|
+
|
|
647
|
+
if (currentProjectMemory) {
|
|
648
|
+
await fs.unlink(currentProjectMemory.path);
|
|
649
|
+
console.log(colors.success(`✅ Cleaned current project memory`));
|
|
650
|
+
console.log(colors.textMuted(` File: ${path.basename(currentProjectMemory.path)}`));
|
|
651
|
+
} else {
|
|
652
|
+
console.log(colors.textMuted('No memory found for the current project.'));
|
|
653
|
+
}
|
|
654
|
+
// TODO: 如果需要自动重建 project memory,取消下面注释
|
|
655
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
656
|
+
// console.log(colors.textMuted(' Recreated current project memory'));
|
|
657
|
+
console.log(colors.textMuted(' Use /init to initialize if needed'));
|
|
658
|
+
console.log('');
|
|
659
|
+
} catch (error: any) {
|
|
660
|
+
const { message, suggestion } = formatError(error);
|
|
661
|
+
console.log(colors.error(`Failed to clean project memory: ${message}`));
|
|
662
|
+
console.log(colors.textMuted(suggestion));
|
|
663
|
+
console.log('');
|
|
664
|
+
}
|
|
665
|
+
} else if (options.cleanAll) {
|
|
666
|
+
// Clean all memories including global
|
|
667
|
+
console.log(colors.warning(`${icons.warning} This will delete ALL memory files including global memory.`));
|
|
668
|
+
console.log('');
|
|
669
|
+
console.log(colors.textMuted('Files to be deleted:'));
|
|
670
|
+
console.log(colors.textMuted(` - global.md (global memory)`));
|
|
671
|
+
console.log(colors.textMuted(` - all project memories`));
|
|
672
|
+
console.log('');
|
|
673
|
+
|
|
674
|
+
try {
|
|
675
|
+
const files = await fs.readdir(memoriesDir).catch(() => []);
|
|
676
|
+
if (files.length === 0) {
|
|
677
|
+
console.log(colors.textMuted('No memory files to clean.'));
|
|
678
|
+
console.log('');
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
let cleaned = 0;
|
|
683
|
+
for (const file of files) {
|
|
684
|
+
await fs.unlink(join(memoriesDir, file));
|
|
685
|
+
cleaned++;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
// Recreate global memory (always keep global memory available)
|
|
689
|
+
await memoryManager.saveMemory('# Global Context\n\nGlobal preferences and settings will be added here.', 'global');
|
|
690
|
+
// TODO: 如果需要同时重建 project memory,取消下面注释
|
|
691
|
+
// await memoryManager.saveMemory('# Project Context\n\nProject-specific context will be added here.', 'project');
|
|
692
|
+
|
|
693
|
+
console.log(colors.success(`✅ Cleaned ${cleaned} memory file(s)`));
|
|
694
|
+
console.log(colors.textMuted(' Recreated global memory'));
|
|
695
|
+
console.log(colors.textMuted(' Use /init to initialize project memory if needed'));
|
|
696
|
+
console.log('');
|
|
697
|
+
} catch (error: any) {
|
|
698
|
+
const { message, suggestion } = formatError(error);
|
|
699
|
+
console.log(colors.error(`Failed to clean memories: ${message}`));
|
|
700
|
+
console.log(colors.textMuted(suggestion));
|
|
701
|
+
console.log('');
|
|
702
|
+
}
|
|
703
|
+
} else {
|
|
704
|
+
// No option specified, show help
|
|
705
|
+
console.log(colors.textMuted('Usage:'));
|
|
706
|
+
console.log(` ${colors.primaryBright('xagent memory -l')} ${colors.textDim('| List all memory files')}`);
|
|
707
|
+
console.log(` ${colors.primaryBright('xagent memory --clean')} ${colors.textDim('| Clean all project memories (keep global)')}`);
|
|
708
|
+
console.log(` ${colors.primaryBright('xagent memory --clean-project')} ${colors.textDim('| Clean current project memory only')}`);
|
|
709
|
+
console.log(` ${colors.primaryBright('xagent memory --clean-all')} ${colors.textDim('| Clean ALL memories (including global)')}`);
|
|
710
|
+
console.log('');
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
|
|
520
714
|
program.parse(process.argv);
|
|
521
715
|
|
|
522
716
|
if (!process.argv.slice(2).length) {
|
package/src/config.ts
CHANGED
|
@@ -11,13 +11,13 @@ const DEFAULT_SETTINGS: Settings = {
|
|
|
11
11
|
selectedAuthType: AuthType.OAUTH_XAGENT,
|
|
12
12
|
apiKey: '',
|
|
13
13
|
// LLM API - for main conversation and task processing (OpenAI compatible format)
|
|
14
|
-
baseUrl: '
|
|
14
|
+
baseUrl: 'https://www.xagent-colife.net:3000/v1',
|
|
15
15
|
modelName: 'Qwen3-Coder',
|
|
16
16
|
// xAgent API - for token validation and other backend calls (without /v1)
|
|
17
|
-
xagentApiBaseUrl: '
|
|
17
|
+
xagentApiBaseUrl: 'https://www.xagent-colife.net:3000',
|
|
18
18
|
// VLM API - for GUI automation (browser/desktop operations)
|
|
19
19
|
guiSubagentModel: 'Qwen3-Coder',
|
|
20
|
-
guiSubagentBaseUrl: '
|
|
20
|
+
guiSubagentBaseUrl: 'https://www.xagent-colife.net:3000/v3',
|
|
21
21
|
guiSubagentApiKey: '',
|
|
22
22
|
searchApiKey: '',
|
|
23
23
|
skillsPath: '', // Will be auto-detected if not set
|
package/src/memory.ts
CHANGED
|
@@ -3,27 +3,43 @@ import fsSync from 'fs';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import { glob } from 'glob';
|
|
6
|
+
import crypto from 'crypto';
|
|
6
7
|
|
|
7
8
|
export interface MemoryFile {
|
|
8
9
|
path: string;
|
|
9
10
|
content: string;
|
|
10
11
|
level: 'global' | 'project' | 'subdirectory';
|
|
12
|
+
projectRoot?: string;
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
export class MemoryManager {
|
|
16
|
+
private memoriesDir: string;
|
|
14
17
|
private globalMemoryPath: string;
|
|
15
18
|
private projectMemoryPath: string;
|
|
19
|
+
private projectRoot: string | null = null;
|
|
16
20
|
private memoryFiles: MemoryFile[] = [];
|
|
17
21
|
private contextFileNames: string | string[];
|
|
18
22
|
|
|
19
23
|
constructor(projectRoot?: string, contextFileName: string | string[] = 'XAGENT.md') {
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
this.memoriesDir = path.join(os.homedir(), '.xagent', 'memories');
|
|
25
|
+
this.globalMemoryPath = path.join(this.memoriesDir, 'global.md');
|
|
26
|
+
|
|
27
|
+
if (projectRoot) {
|
|
28
|
+
this.projectRoot = path.resolve(projectRoot);
|
|
29
|
+
this.projectMemoryPath = this.getProjectMemoryPath(this.projectRoot);
|
|
30
|
+
} else {
|
|
31
|
+
this.projectMemoryPath = '';
|
|
32
|
+
}
|
|
24
33
|
this.contextFileNames = contextFileName;
|
|
25
34
|
}
|
|
26
35
|
|
|
36
|
+
private getProjectMemoryPath(projectRoot: string): string {
|
|
37
|
+
const hash = crypto.createHash('md5').update(projectRoot).digest('hex').substring(0, 16);
|
|
38
|
+
const sanitizedName = projectRoot.replace(/[:\\\/]/g, '_').replace(/[^a-zA-Z0-9_\-]/g, '');
|
|
39
|
+
const name = sanitizedName.length > 50 ? sanitizedName.substring(0, 50) : sanitizedName;
|
|
40
|
+
return path.join(this.memoriesDir, `project_${name}_${hash}.md`);
|
|
41
|
+
}
|
|
42
|
+
|
|
27
43
|
async loadMemory(): Promise<string> {
|
|
28
44
|
this.memoryFiles = [];
|
|
29
45
|
let combinedMemory = '';
|
|
@@ -32,6 +48,15 @@ export class MemoryManager {
|
|
|
32
48
|
if (globalMemory) {
|
|
33
49
|
this.memoryFiles.push(globalMemory);
|
|
34
50
|
combinedMemory += globalMemory.content + '\n\n';
|
|
51
|
+
} else {
|
|
52
|
+
// Global memory not found, create default content
|
|
53
|
+
const defaultContent = '# Global Context\n\nGlobal preferences and settings will be added here.';
|
|
54
|
+
await this.saveMemory(defaultContent, 'global');
|
|
55
|
+
const newMemory = await this.loadMemoryFile(this.globalMemoryPath, 'global');
|
|
56
|
+
if (newMemory) {
|
|
57
|
+
this.memoryFiles.push(newMemory);
|
|
58
|
+
combinedMemory += newMemory.content + '\n\n';
|
|
59
|
+
}
|
|
35
60
|
}
|
|
36
61
|
|
|
37
62
|
if (this.projectMemoryPath) {
|
|
@@ -40,11 +65,15 @@ export class MemoryManager {
|
|
|
40
65
|
this.memoryFiles.push(projectMemory);
|
|
41
66
|
combinedMemory += projectMemory.content + '\n\n';
|
|
42
67
|
}
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
// this.
|
|
47
|
-
//
|
|
68
|
+
// else {
|
|
69
|
+
// // Project memory not found, create default content
|
|
70
|
+
// const defaultContent = '# Project Context\n\nProject-specific context will be added here.';
|
|
71
|
+
// await this.saveMemory(defaultContent, 'project');
|
|
72
|
+
// const newMemory = await this.loadMemoryFile(this.projectMemoryPath, 'project');
|
|
73
|
+
// if (newMemory) {
|
|
74
|
+
// this.memoryFiles.push(newMemory);
|
|
75
|
+
// combinedMemory += newMemory.content + '\n\n';
|
|
76
|
+
// }
|
|
48
77
|
// }
|
|
49
78
|
}
|
|
50
79
|
|
|
@@ -133,7 +162,7 @@ export class MemoryManager {
|
|
|
133
162
|
|
|
134
163
|
async saveMemory(content: string, scope: 'global' | 'project' = 'global'): Promise<void> {
|
|
135
164
|
const filePath = scope === 'global' ? this.globalMemoryPath : this.projectMemoryPath;
|
|
136
|
-
|
|
165
|
+
|
|
137
166
|
if (!filePath) {
|
|
138
167
|
throw new Error('Project memory path not set');
|
|
139
168
|
}
|
|
@@ -142,7 +171,7 @@ export class MemoryManager {
|
|
|
142
171
|
await fs.mkdir(dir, { recursive: true });
|
|
143
172
|
|
|
144
173
|
await fs.writeFile(filePath, content, 'utf-8');
|
|
145
|
-
|
|
174
|
+
|
|
146
175
|
if (scope === 'global') {
|
|
147
176
|
const existingMemory = this.memoryFiles.find(m => m.level === 'global');
|
|
148
177
|
if (existingMemory) {
|
|
@@ -150,12 +179,19 @@ export class MemoryManager {
|
|
|
150
179
|
} else {
|
|
151
180
|
this.memoryFiles.push({ path: filePath, content, level: 'global' });
|
|
152
181
|
}
|
|
182
|
+
} else {
|
|
183
|
+
const existingMemory = this.memoryFiles.find(m => m.level === 'project');
|
|
184
|
+
if (existingMemory) {
|
|
185
|
+
existingMemory.content = content;
|
|
186
|
+
} else {
|
|
187
|
+
this.memoryFiles.push({ path: filePath, content, level: 'project', projectRoot: this.projectRoot || undefined });
|
|
188
|
+
}
|
|
153
189
|
}
|
|
154
190
|
}
|
|
155
191
|
|
|
156
192
|
async addMemoryEntry(entry: string, scope: 'global' | 'project' = 'global'): Promise<void> {
|
|
157
193
|
const filePath = scope === 'global' ? this.globalMemoryPath : this.projectMemoryPath;
|
|
158
|
-
|
|
194
|
+
|
|
159
195
|
if (!filePath) {
|
|
160
196
|
throw new Error('Project memory path not set');
|
|
161
197
|
}
|
|
@@ -177,9 +213,14 @@ export class MemoryManager {
|
|
|
177
213
|
return [...this.memoryFiles];
|
|
178
214
|
}
|
|
179
215
|
|
|
216
|
+
getMemoriesDir(): string {
|
|
217
|
+
return this.memoriesDir;
|
|
218
|
+
}
|
|
219
|
+
|
|
180
220
|
async initializeProject(projectRoot: string): Promise<void> {
|
|
181
|
-
this.
|
|
182
|
-
|
|
221
|
+
this.projectRoot = path.resolve(projectRoot);
|
|
222
|
+
this.projectMemoryPath = this.getProjectMemoryPath(this.projectRoot);
|
|
223
|
+
|
|
183
224
|
const existingMemory = await this.loadMemoryFile(this.projectMemoryPath, 'project');
|
|
184
225
|
if (existingMemory) {
|
|
185
226
|
console.log('XAGENT.md already exists. Skipping initialization.');
|