@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.
Files changed (80) hide show
  1. package/README.md +1 -1
  2. package/README_CN.md +1 -1
  3. package/dist/agents.js +164 -164
  4. package/dist/agents.js.map +1 -1
  5. package/dist/ai-client.d.ts +4 -6
  6. package/dist/ai-client.d.ts.map +1 -1
  7. package/dist/ai-client.js +137 -115
  8. package/dist/ai-client.js.map +1 -1
  9. package/dist/auth.js +4 -4
  10. package/dist/auth.js.map +1 -1
  11. package/dist/cli.js +184 -1
  12. package/dist/cli.js.map +1 -1
  13. package/dist/config.js +3 -3
  14. package/dist/config.js.map +1 -1
  15. package/dist/context-compressor.d.ts.map +1 -1
  16. package/dist/context-compressor.js +65 -81
  17. package/dist/context-compressor.js.map +1 -1
  18. package/dist/conversation.d.ts +1 -1
  19. package/dist/conversation.d.ts.map +1 -1
  20. package/dist/conversation.js +5 -31
  21. package/dist/conversation.js.map +1 -1
  22. package/dist/memory.d.ts +5 -1
  23. package/dist/memory.d.ts.map +1 -1
  24. package/dist/memory.js +77 -37
  25. package/dist/memory.js.map +1 -1
  26. package/dist/remote-ai-client.d.ts +1 -8
  27. package/dist/remote-ai-client.d.ts.map +1 -1
  28. package/dist/remote-ai-client.js +55 -65
  29. package/dist/remote-ai-client.js.map +1 -1
  30. package/dist/retry.d.ts +35 -0
  31. package/dist/retry.d.ts.map +1 -0
  32. package/dist/retry.js +166 -0
  33. package/dist/retry.js.map +1 -0
  34. package/dist/session.d.ts +0 -5
  35. package/dist/session.d.ts.map +1 -1
  36. package/dist/session.js +243 -312
  37. package/dist/session.js.map +1 -1
  38. package/dist/slash-commands.d.ts +1 -0
  39. package/dist/slash-commands.d.ts.map +1 -1
  40. package/dist/slash-commands.js +91 -9
  41. package/dist/slash-commands.js.map +1 -1
  42. package/dist/smart-approval.d.ts.map +1 -1
  43. package/dist/smart-approval.js +18 -17
  44. package/dist/smart-approval.js.map +1 -1
  45. package/dist/system-prompt-generator.d.ts.map +1 -1
  46. package/dist/system-prompt-generator.js +149 -139
  47. package/dist/system-prompt-generator.js.map +1 -1
  48. package/dist/theme.d.ts +48 -0
  49. package/dist/theme.d.ts.map +1 -1
  50. package/dist/theme.js +254 -0
  51. package/dist/theme.js.map +1 -1
  52. package/dist/tools/edit-diff.d.ts +32 -0
  53. package/dist/tools/edit-diff.d.ts.map +1 -0
  54. package/dist/tools/edit-diff.js +185 -0
  55. package/dist/tools/edit-diff.js.map +1 -0
  56. package/dist/tools/edit.d.ts +11 -0
  57. package/dist/tools/edit.d.ts.map +1 -0
  58. package/dist/tools/edit.js +129 -0
  59. package/dist/tools/edit.js.map +1 -0
  60. package/dist/tools.d.ts +19 -5
  61. package/dist/tools.d.ts.map +1 -1
  62. package/dist/tools.js +979 -631
  63. package/dist/tools.js.map +1 -1
  64. package/dist/types.d.ts +6 -31
  65. package/dist/types.d.ts.map +1 -1
  66. package/package.json +3 -2
  67. package/src/agents.ts +504 -504
  68. package/src/ai-client.ts +1559 -1458
  69. package/src/auth.ts +4 -4
  70. package/src/cli.ts +195 -1
  71. package/src/config.ts +3 -3
  72. package/src/memory.ts +55 -14
  73. package/src/remote-ai-client.ts +663 -683
  74. package/src/retry.ts +217 -0
  75. package/src/session.ts +1736 -1840
  76. package/src/slash-commands.ts +98 -9
  77. package/src/smart-approval.ts +626 -625
  78. package/src/system-prompt-generator.ts +853 -843
  79. package/src/theme.ts +284 -0
  80. 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://154.8.140.52:443';
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://154.8.140.52:443/v1';
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://154.8.140.52';
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://154.8.140.52:443/callback';
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: 'http://xagent-colife.net:3000/v1',
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: 'http://xagent-colife.net:3000',
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: 'http://xagent-colife.net:3000/v3',
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.globalMemoryPath = path.join(os.homedir(), '.xagent', 'XAGENT.md');
21
- this.projectMemoryPath = projectRoot
22
- ? path.join(projectRoot, 'XAGENT.md')
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
- // const subdirectoryMemories = await this.loadSubdirectoryMemories();
45
- // for (const memory of subdirectoryMemories) {
46
- // this.memoryFiles.push(memory);
47
- // combinedMemory += memory.content + '\n\n';
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.projectMemoryPath = path.join(projectRoot, 'XAGENT.md');
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.');