@birdmichael/ccsync 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +241 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/config.d.ts +18 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +111 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/dashboard.d.ts +9 -0
  11. package/dist/commands/dashboard.d.ts.map +1 -0
  12. package/dist/commands/dashboard.js +51 -0
  13. package/dist/commands/dashboard.js.map +1 -0
  14. package/dist/commands/hello/index.d.ts +13 -0
  15. package/dist/commands/hello/index.d.ts.map +1 -0
  16. package/dist/commands/hello/index.js +20 -0
  17. package/dist/commands/hello/index.js.map +1 -0
  18. package/dist/commands/hello/world.d.ts +9 -0
  19. package/dist/commands/hello/world.d.ts.map +1 -0
  20. package/dist/commands/hello/world.js +15 -0
  21. package/dist/commands/hello/world.js.map +1 -0
  22. package/dist/commands/logs.d.ts +16 -0
  23. package/dist/commands/logs.d.ts.map +1 -0
  24. package/dist/commands/logs.js +101 -0
  25. package/dist/commands/logs.js.map +1 -0
  26. package/dist/commands/menu.d.ts +13 -0
  27. package/dist/commands/menu.d.ts.map +1 -0
  28. package/dist/commands/menu.js +190 -0
  29. package/dist/commands/menu.js.map +1 -0
  30. package/dist/commands/setup.d.ts +7 -0
  31. package/dist/commands/setup.d.ts.map +1 -0
  32. package/dist/commands/setup.js +270 -0
  33. package/dist/commands/setup.js.map +1 -0
  34. package/dist/commands/start.d.ts +7 -0
  35. package/dist/commands/start.d.ts.map +1 -0
  36. package/dist/commands/start.js +16 -0
  37. package/dist/commands/start.js.map +1 -0
  38. package/dist/commands/status.d.ts +3 -0
  39. package/dist/commands/status.d.ts.map +1 -0
  40. package/dist/commands/status.js +63 -0
  41. package/dist/commands/status.js.map +1 -0
  42. package/dist/commands/stop.d.ts +7 -0
  43. package/dist/commands/stop.d.ts.map +1 -0
  44. package/dist/commands/stop.js +16 -0
  45. package/dist/commands/stop.js.map +1 -0
  46. package/dist/commands/sync.d.ts +7 -0
  47. package/dist/commands/sync.d.ts.map +1 -0
  48. package/dist/commands/sync.js +33 -0
  49. package/dist/commands/sync.js.map +1 -0
  50. package/dist/commands/test.d.ts +8 -0
  51. package/dist/commands/test.d.ts.map +1 -0
  52. package/dist/commands/test.js +27 -0
  53. package/dist/commands/test.js.map +1 -0
  54. package/dist/commands/toggle.d.ts +7 -0
  55. package/dist/commands/toggle.d.ts.map +1 -0
  56. package/dist/commands/toggle.js +22 -0
  57. package/dist/commands/toggle.js.map +1 -0
  58. package/dist/core/config-manager.d.ts +19 -0
  59. package/dist/core/config-manager.d.ts.map +1 -0
  60. package/dist/core/config-manager.js +174 -0
  61. package/dist/core/config-manager.js.map +1 -0
  62. package/dist/core/launch-agent.d.ts +12 -0
  63. package/dist/core/launch-agent.d.ts.map +1 -0
  64. package/dist/core/launch-agent.js +89 -0
  65. package/dist/core/launch-agent.js.map +1 -0
  66. package/dist/core/permission-manager.d.ts +18 -0
  67. package/dist/core/permission-manager.d.ts.map +1 -0
  68. package/dist/core/permission-manager.js +94 -0
  69. package/dist/core/permission-manager.js.map +1 -0
  70. package/dist/core/service-manager.d.ts +33 -0
  71. package/dist/core/service-manager.d.ts.map +1 -0
  72. package/dist/core/service-manager.js +108 -0
  73. package/dist/core/service-manager.js.map +1 -0
  74. package/dist/core/sync-service.d.ts +29 -0
  75. package/dist/core/sync-service.d.ts.map +1 -0
  76. package/dist/core/sync-service.js +180 -0
  77. package/dist/core/sync-service.js.map +1 -0
  78. package/dist/index.d.ts +2 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +2 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/syncers/base-syncer.d.ts +5 -0
  83. package/dist/syncers/base-syncer.d.ts.map +1 -0
  84. package/dist/syncers/base-syncer.js +3 -0
  85. package/dist/syncers/base-syncer.js.map +1 -0
  86. package/dist/syncers/mcp-syncer.d.ts +16 -0
  87. package/dist/syncers/mcp-syncer.d.ts.map +1 -0
  88. package/dist/syncers/mcp-syncer.js +116 -0
  89. package/dist/syncers/mcp-syncer.js.map +1 -0
  90. package/dist/syncers/skills-syncer.d.ts +13 -0
  91. package/dist/syncers/skills-syncer.d.ts.map +1 -0
  92. package/dist/syncers/skills-syncer.js +153 -0
  93. package/dist/syncers/skills-syncer.js.map +1 -0
  94. package/dist/types/config.d.ts +53 -0
  95. package/dist/types/config.d.ts.map +1 -0
  96. package/dist/types/config.js +33 -0
  97. package/dist/types/config.js.map +1 -0
  98. package/dist/types/mcp.d.ts +20 -0
  99. package/dist/types/mcp.d.ts.map +1 -0
  100. package/dist/types/mcp.js +3 -0
  101. package/dist/types/mcp.js.map +1 -0
  102. package/dist/types/sync.d.ts +44 -0
  103. package/dist/types/sync.d.ts.map +1 -0
  104. package/dist/types/sync.js +3 -0
  105. package/dist/types/sync.js.map +1 -0
  106. package/dist/types/ui.d.ts +263 -0
  107. package/dist/types/ui.d.ts.map +1 -0
  108. package/dist/types/ui.js +3 -0
  109. package/dist/types/ui.js.map +1 -0
  110. package/dist/ui/config/index.d.ts +12 -0
  111. package/dist/ui/config/index.d.ts.map +1 -0
  112. package/dist/ui/config/index.js +43 -0
  113. package/dist/ui/config/index.js.map +1 -0
  114. package/dist/ui/dashboard/index.d.ts +14 -0
  115. package/dist/ui/dashboard/index.d.ts.map +1 -0
  116. package/dist/ui/dashboard/index.js +90 -0
  117. package/dist/ui/dashboard/index.js.map +1 -0
  118. package/dist/ui/error/index.d.ts +13 -0
  119. package/dist/ui/error/index.d.ts.map +1 -0
  120. package/dist/ui/error/index.js +27 -0
  121. package/dist/ui/error/index.js.map +1 -0
  122. package/dist/ui/setup/index.d.ts +11 -0
  123. package/dist/ui/setup/index.d.ts.map +1 -0
  124. package/dist/ui/setup/index.js +18 -0
  125. package/dist/ui/setup/index.js.map +1 -0
  126. package/dist/utils/error-handler.d.ts +21 -0
  127. package/dist/utils/error-handler.d.ts.map +1 -0
  128. package/dist/utils/error-handler.js +178 -0
  129. package/dist/utils/error-handler.js.map +1 -0
  130. package/dist/utils/file-watcher.d.ts +17 -0
  131. package/dist/utils/file-watcher.d.ts.map +1 -0
  132. package/dist/utils/file-watcher.js +92 -0
  133. package/dist/utils/file-watcher.js.map +1 -0
  134. package/dist/utils/logger.d.ts +14 -0
  135. package/dist/utils/logger.d.ts.map +1 -0
  136. package/dist/utils/logger.js +72 -0
  137. package/dist/utils/logger.js.map +1 -0
  138. package/dist/utils/texts.d.ts +263 -0
  139. package/dist/utils/texts.d.ts.map +1 -0
  140. package/dist/utils/texts.js +270 -0
  141. package/dist/utils/texts.js.map +1 -0
  142. package/dist/utils/time-helper.d.ts +8 -0
  143. package/dist/utils/time-helper.d.ts.map +1 -0
  144. package/dist/utils/time-helper.js +67 -0
  145. package/dist/utils/time-helper.js.map +1 -0
  146. package/package.json +79 -0
@@ -0,0 +1,94 @@
1
+ import fs from 'fs-extra';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { logger } from '../utils/logger';
5
+ class PermissionManager {
6
+ paths;
7
+ constructor(paths) {
8
+ this.paths = paths.map(p => {
9
+ if (p.startsWith('~')) {
10
+ return path.join(os.homedir(), p.slice(1));
11
+ }
12
+ return p;
13
+ });
14
+ }
15
+ async check() {
16
+ logger.info('正在检查权限...');
17
+ const issues = [];
18
+ for (const targetPath of this.paths) {
19
+ try {
20
+ await fs.access(targetPath, fs.constants.R_OK | fs.constants.W_OK);
21
+ }
22
+ catch {
23
+ const msg = `无法访问路径: ${targetPath}`;
24
+ issues.push(msg);
25
+ logger.warn(msg);
26
+ }
27
+ }
28
+ const valid = issues.length === 0;
29
+ if (valid) {
30
+ logger.info('权限检查通过');
31
+ }
32
+ else {
33
+ logger.warn(`权限检查发现 ${issues.length} 个问题`);
34
+ }
35
+ return { issues, valid };
36
+ }
37
+ async ensureDirectories() {
38
+ const created = [];
39
+ const errors = [];
40
+ for (const targetPath of this.paths) {
41
+ try {
42
+ if (!await fs.pathExists(targetPath)) {
43
+ await fs.ensureDir(targetPath);
44
+ created.push(targetPath);
45
+ logger.info(`已创建目录: ${targetPath}`);
46
+ }
47
+ }
48
+ catch {
49
+ const msg = `无法创建目录: ${targetPath}`;
50
+ errors.push(msg);
51
+ logger.error(msg);
52
+ }
53
+ }
54
+ return { created, errors };
55
+ }
56
+ async fix() {
57
+ logger.info('正在修复权限...');
58
+ const fixedIssues = [];
59
+ const remainingIssues = [];
60
+ for (const targetPath of this.paths) {
61
+ const parentDir = path.dirname(targetPath);
62
+ try {
63
+ await fs.ensureDir(parentDir);
64
+ if (!await fs.pathExists(targetPath)) {
65
+ await fs.ensureDir(targetPath);
66
+ fixedIssues.push(`已创建目录: ${targetPath}`);
67
+ }
68
+ await fs.chmod(targetPath, 0o755);
69
+ fixedIssues.push(`已修复权限: ${targetPath}`);
70
+ }
71
+ catch {
72
+ const msg = `无法修复权限: ${targetPath}`;
73
+ remainingIssues.push(msg);
74
+ logger.error(msg);
75
+ }
76
+ }
77
+ const fixed = remainingIssues.length === 0;
78
+ if (fixed) {
79
+ logger.info('所有权限问题已修复');
80
+ for (const issue of fixedIssues)
81
+ logger.info(issue);
82
+ }
83
+ else {
84
+ logger.warn(`${fixedIssues.length} 个问题已修复,${remainingIssues.length} 个问题无法修复`);
85
+ for (const issue of fixedIssues)
86
+ logger.info(issue);
87
+ for (const issue of remainingIssues)
88
+ logger.warn(issue);
89
+ }
90
+ return { fixed, issues: remainingIssues };
91
+ }
92
+ }
93
+ export { PermissionManager };
94
+ //# sourceMappingURL=permission-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-manager.js","sourceRoot":"","sources":["../../src/core/permission-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { SyncResult } from '../types/sync';
2
+ declare class ServiceManager {
3
+ private launchAgentManager;
4
+ private pid;
5
+ private startTime;
6
+ private syncService;
7
+ constructor();
8
+ checkPermissions(): Promise<{
9
+ issues: string[];
10
+ valid: boolean;
11
+ }>;
12
+ disableAutostart(): Promise<boolean>;
13
+ enableAutostart(): Promise<boolean>;
14
+ fixPermissions(): Promise<{
15
+ fixed: boolean;
16
+ issues: string[];
17
+ }>;
18
+ getPid(): null | number;
19
+ getStatus(): {
20
+ running: boolean;
21
+ uptime: number;
22
+ };
23
+ getUptime(): number;
24
+ isAutostartEnabled(): Promise<boolean>;
25
+ isRunning(): boolean;
26
+ start(): Promise<void>;
27
+ stop(): Promise<void>;
28
+ sync(): Promise<SyncResult>;
29
+ toggle(): Promise<boolean>;
30
+ }
31
+ export declare const serviceManager: ServiceManager;
32
+ export {};
33
+ //# sourceMappingURL=service-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-manager.d.ts","sourceRoot":"","sources":["../../src/core/service-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3C,cAAM,cAAc;IAClB,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAAc;;IAQ3B,gBAAgB,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;KAAE,CAAC;IAIlE,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAYpC,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAanC,cAAc,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAIrE,MAAM,IAAI,IAAI,GAAG,MAAM;IAIvB,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAIjD,SAAS,IAAI,MAAM;IAQb,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAI5C,SAAS,IAAI,OAAO;IAKd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAI3B,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;CAWjC;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { logger } from '../utils/logger';
2
+ import { configManager } from './config-manager';
3
+ import { LaunchAgentManager } from './launch-agent';
4
+ import { SyncService } from './sync-service';
5
+ class ServiceManager {
6
+ launchAgentManager;
7
+ pid = null;
8
+ startTime = null;
9
+ syncService;
10
+ constructor() {
11
+ this.syncService = new SyncService();
12
+ this.launchAgentManager = new LaunchAgentManager();
13
+ this.pid = process.pid;
14
+ }
15
+ async checkPermissions() {
16
+ return await this.syncService.checkPermissions();
17
+ }
18
+ async disableAutostart() {
19
+ const success = await this.launchAgentManager.disable();
20
+ if (success) {
21
+ const config = configManager.getConfig();
22
+ config.autostart.enabled = false;
23
+ configManager.saveConfig();
24
+ logger.success('开机启动已禁用');
25
+ }
26
+ return success;
27
+ }
28
+ async enableAutostart() {
29
+ const success = await this.launchAgentManager.enable();
30
+ if (success) {
31
+ const config = configManager.getConfig();
32
+ config.autostart.enabled = true;
33
+ config.autostart.launchAgentPath = this.launchAgentManager.getAgentPath();
34
+ configManager.saveConfig();
35
+ logger.success('开机启动已启用');
36
+ }
37
+ return success;
38
+ }
39
+ async fixPermissions() {
40
+ return await this.syncService.fixPermissions();
41
+ }
42
+ getPid() {
43
+ return this.pid;
44
+ }
45
+ getStatus() {
46
+ return this.syncService.getStatus();
47
+ }
48
+ getUptime() {
49
+ if (!this.startTime) {
50
+ return 0;
51
+ }
52
+ return Math.floor((Date.now() - this.startTime) / 1000);
53
+ }
54
+ async isAutostartEnabled() {
55
+ return await this.launchAgentManager.isEnabled();
56
+ }
57
+ isRunning() {
58
+ const status = this.syncService.getStatus();
59
+ return status.running;
60
+ }
61
+ async start() {
62
+ try {
63
+ logger.info('正在启动服务...');
64
+ await this.syncService.start();
65
+ this.startTime = Date.now();
66
+ const config = configManager.getConfig();
67
+ config.service.running = true;
68
+ config.service.pid = this.pid;
69
+ configManager.saveConfig();
70
+ logger.success('服务已启动');
71
+ }
72
+ catch (error) {
73
+ logger.error('启动服务失败', { error: error instanceof Error ? error.message : String(error) });
74
+ throw error;
75
+ }
76
+ }
77
+ async stop() {
78
+ try {
79
+ logger.info('正在停止服务...');
80
+ await this.syncService.stop();
81
+ this.startTime = null;
82
+ const config = configManager.getConfig();
83
+ config.service.running = false;
84
+ config.service.pid = undefined;
85
+ config.service.uptime = 0;
86
+ configManager.saveConfig();
87
+ logger.success('服务已停止');
88
+ }
89
+ catch (error) {
90
+ logger.error('停止服务失败', { error: error instanceof Error ? error.message : String(error) });
91
+ throw error;
92
+ }
93
+ }
94
+ async sync() {
95
+ return await this.syncService.sync();
96
+ }
97
+ async toggle() {
98
+ const isRunning = this.isRunning();
99
+ if (isRunning) {
100
+ await this.stop();
101
+ return false;
102
+ }
103
+ await this.start();
104
+ return true;
105
+ }
106
+ }
107
+ export const serviceManager = new ServiceManager();
108
+ //# sourceMappingURL=service-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-manager.js","sourceRoot":"","sources":["../../src/core/service-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { SyncResult } from '../types/sync';
2
+ declare class SyncService {
3
+ private fileWatcher;
4
+ private intervalId;
5
+ private isRunning;
6
+ private mcpSyncer;
7
+ private permissionManager;
8
+ private skillsSyncer;
9
+ constructor();
10
+ checkPermissions(): Promise<{
11
+ issues: string[];
12
+ valid: boolean;
13
+ }>;
14
+ fixPermissions(): Promise<{
15
+ fixed: boolean;
16
+ issues: string[];
17
+ }>;
18
+ getStatus(): {
19
+ running: boolean;
20
+ uptime: number;
21
+ };
22
+ start(): Promise<void>;
23
+ stop(): Promise<void>;
24
+ sync(): Promise<SyncResult>;
25
+ private setupSyncers;
26
+ private startAutoSync;
27
+ }
28
+ export { SyncService };
29
+ //# sourceMappingURL=sync-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-service.d.ts","sourceRoot":"","sources":["../../src/core/sync-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAM3C,cAAM,WAAW;IACf,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,YAAY,CAA6B;;IAM3C,gBAAgB,IAAI,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;KAAE,CAAC;IAQlE,cAAc,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAQrE,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAQ3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BrB,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IAiDjC,OAAO,CAAC,YAAY;IAgEpB,OAAO,CAAC,aAAa;CAYtB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,180 @@
1
+ import { McpSyncer } from '../syncers/mcp-syncer';
2
+ import { SkillsSyncer } from '../syncers/skills-syncer';
3
+ import { FileWatcher } from '../utils/file-watcher';
4
+ import { logger } from '../utils/logger';
5
+ import { configManager } from './config-manager';
6
+ import { PermissionManager } from './permission-manager';
7
+ class SyncService {
8
+ fileWatcher = null;
9
+ intervalId = null;
10
+ isRunning = false;
11
+ mcpSyncer = null;
12
+ permissionManager = null;
13
+ skillsSyncer = null;
14
+ constructor() {
15
+ this.setupSyncers();
16
+ }
17
+ async checkPermissions() {
18
+ if (!this.permissionManager) {
19
+ return { issues: [], valid: true };
20
+ }
21
+ return await this.permissionManager.check();
22
+ }
23
+ async fixPermissions() {
24
+ if (!this.permissionManager) {
25
+ return { fixed: true, issues: [] };
26
+ }
27
+ return await this.permissionManager.fix();
28
+ }
29
+ getStatus() {
30
+ const config = configManager.getConfig();
31
+ return {
32
+ running: config.service.running || false,
33
+ uptime: config.service.uptime || 0,
34
+ };
35
+ }
36
+ async start() {
37
+ if (this.isRunning) {
38
+ logger.warn('服务已在运行中');
39
+ return;
40
+ }
41
+ logger.info('正在启动服务...');
42
+ const config = configManager.getConfig();
43
+ if (this.permissionManager) {
44
+ const permissionCheck = await this.permissionManager.check();
45
+ if (!permissionCheck.valid) {
46
+ logger.warn('发现权限问题,尝试自动修复...');
47
+ const fixResult = await this.permissionManager.fix();
48
+ if (!fixResult.fixed) {
49
+ throw new Error('无法修复权限问题,服务启动失败');
50
+ }
51
+ }
52
+ }
53
+ this.isRunning = true;
54
+ config.service.running = true;
55
+ config.service.uptime = 0;
56
+ configManager.saveConfig();
57
+ logger.info('服务已启动');
58
+ this.startAutoSync();
59
+ }
60
+ async stop() {
61
+ if (!this.isRunning) {
62
+ logger.warn('服务未运行');
63
+ return;
64
+ }
65
+ logger.info('正在停止服务...');
66
+ this.isRunning = false;
67
+ const config = configManager.getConfig();
68
+ config.service.running = false;
69
+ config.service.uptime = 0;
70
+ configManager.saveConfig();
71
+ if (this.intervalId) {
72
+ clearInterval(this.intervalId);
73
+ this.intervalId = null;
74
+ }
75
+ if (this.fileWatcher) {
76
+ this.fileWatcher.stop();
77
+ logger.info('文件监控已停止');
78
+ }
79
+ logger.info('服务已停止');
80
+ }
81
+ async sync() {
82
+ logger.info('开始同步...');
83
+ const startTime = Date.now();
84
+ const result = {
85
+ duration: 0,
86
+ mcp: { cached: false, errors: [], synced: 0 },
87
+ skills: { claudeCount: 0, codexCount: 0, errors: [], synced: 0 },
88
+ timestamp: new Date(),
89
+ };
90
+ try {
91
+ if (this.skillsSyncer) {
92
+ const skillsResult = await this.skillsSyncer.sync();
93
+ result.skills = skillsResult;
94
+ }
95
+ if (this.mcpSyncer) {
96
+ const mcpResult = await this.mcpSyncer.sync();
97
+ result.mcp = mcpResult;
98
+ }
99
+ result.duration = Date.now() - startTime;
100
+ if (result.skills.errors.length > 0 || result.mcp.errors.length > 0) {
101
+ logger.warn(`同步完成,但有 ${result.skills.errors.length + result.mcp.errors.length} 个错误`);
102
+ }
103
+ else {
104
+ logger.success(`同步完成,耗时 ${result.duration}ms`);
105
+ }
106
+ const config = configManager.getConfig();
107
+ if (config.skills) {
108
+ config.skills.count = result.skills.synced;
109
+ }
110
+ if (config.mcp) {
111
+ config.mcp.count = result.mcp.synced;
112
+ }
113
+ configManager.saveConfig();
114
+ }
115
+ catch (error) {
116
+ result.duration = Date.now() - startTime;
117
+ result.skills.errors.push(error instanceof Error ? error.message : String(error));
118
+ logger.error('同步失败', { error: result.skills.errors });
119
+ }
120
+ return result;
121
+ }
122
+ setupSyncers() {
123
+ const config = configManager.getConfig();
124
+ if (config.sync.skills) {
125
+ this.skillsSyncer = new SkillsSyncer(config.sync.skills.sources, config.sync.skills.paths, config.sync.skills.target);
126
+ }
127
+ if (config.sync.mcp?.enabled) {
128
+ const platforms = config.sync.mcp.platforms.map(p => p);
129
+ this.mcpSyncer = new McpSyncer(config.sync.mcp.dbPath, config.sync.mcp.target, platforms);
130
+ }
131
+ let dbPath = '';
132
+ const skillsPaths = [];
133
+ if (config.sync.mcp?.enabled) {
134
+ dbPath = config.sync.mcp.dbPath;
135
+ }
136
+ if (config.sync.skills?.paths) {
137
+ if (config.sync.skills.sources.claude) {
138
+ skillsPaths.push(config.sync.skills.paths.claude);
139
+ }
140
+ if (config.sync.skills.sources.codex) {
141
+ skillsPaths.push(config.sync.skills.paths.codex);
142
+ }
143
+ }
144
+ if (dbPath || skillsPaths.length > 0) {
145
+ this.fileWatcher = new FileWatcher(dbPath, skillsPaths);
146
+ this.fileWatcher.watch({
147
+ onDatabaseChange: async () => {
148
+ logger.info('检测到数据库变化,触发同步...');
149
+ await this.sync();
150
+ },
151
+ onSkillsChange: async () => {
152
+ logger.info('检测到Skills目录变化,触发同步...');
153
+ await this.sync();
154
+ },
155
+ });
156
+ }
157
+ const pathsToCheck = [];
158
+ if (config.sync.skills?.target) {
159
+ pathsToCheck.push(config.sync.skills.target);
160
+ }
161
+ if (config.sync.mcp?.target) {
162
+ pathsToCheck.push(config.sync.mcp.target);
163
+ }
164
+ if (pathsToCheck.length > 0) {
165
+ this.permissionManager = new PermissionManager(pathsToCheck);
166
+ }
167
+ }
168
+ startAutoSync() {
169
+ const config = configManager.getConfig();
170
+ const intervalMs = config.service.interval * 1000;
171
+ logger.info(`自动同步已启动,间隔 ${config.service.interval} 秒`);
172
+ this.intervalId = setInterval(async () => {
173
+ if (this.isRunning) {
174
+ await this.sync();
175
+ }
176
+ }, intervalMs);
177
+ }
178
+ }
179
+ export { SyncService };
180
+ //# sourceMappingURL=sync-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-service.js","sourceRoot":"","sources":["../../src/core/sync-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { SyncResult } from '../types/sync';
2
+ export declare abstract class BaseSyncer {
3
+ abstract sync(): Promise<SyncResult>;
4
+ }
5
+ //# sourceMappingURL=base-syncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-syncer.d.ts","sourceRoot":"","sources":["../../src/syncers/base-syncer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,8BAAsB,UAAU;IAC9B,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;CACrC"}
@@ -0,0 +1,3 @@
1
+ export class BaseSyncer {
2
+ }
3
+ //# sourceMappingURL=base-syncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-syncer.js","sourceRoot":"","sources":["../../src/syncers/base-syncer.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,UAAU;CAE/B"}
@@ -0,0 +1,16 @@
1
+ import { McpSyncResult } from '../types/sync';
2
+ declare class McpSyncer {
3
+ private cachedMcpServers;
4
+ private dbPath;
5
+ private lastDbMtime;
6
+ private selectedPlatforms;
7
+ private targetPath;
8
+ constructor(dbPath: string, targetPath: string, selectedPlatforms: string[]);
9
+ sync(): Promise<McpSyncResult>;
10
+ private filterServersByPlatform;
11
+ private getDbMtime;
12
+ private transformConfig;
13
+ private updateOpenCodeConfig;
14
+ }
15
+ export { McpSyncer };
16
+ //# sourceMappingURL=mcp-syncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-syncer.d.ts","sourceRoot":"","sources":["../../src/syncers/mcp-syncer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAa9C,cAAM,SAAS;IACb,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,iBAAiB,CAAW;IACpC,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE;IAMrE,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC;IA2CpC,OAAO,CAAC,uBAAuB;YAiBjB,UAAU;IAUxB,OAAO,CAAC,eAAe;YAsBT,oBAAoB;CAqBnC;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,116 @@
1
+ import fs from 'fs-extra';
2
+ import { logger } from '../utils/logger';
3
+ import { TEXTS } from '../utils/texts';
4
+ import { formatDuration } from '../utils/time-helper';
5
+ class McpSyncer {
6
+ cachedMcpServers = [];
7
+ dbPath;
8
+ lastDbMtime = 0;
9
+ selectedPlatforms;
10
+ targetPath;
11
+ constructor(dbPath, targetPath, selectedPlatforms) {
12
+ this.dbPath = dbPath;
13
+ this.targetPath = targetPath;
14
+ this.selectedPlatforms = selectedPlatforms;
15
+ }
16
+ async sync() {
17
+ const startTime = Date.now();
18
+ try {
19
+ logger.info(TEXTS.logs.messages.checkingDb);
20
+ const currentMtime = await this.getDbMtime();
21
+ if (currentMtime === this.lastDbMtime) {
22
+ logger.info(TEXTS.logs.messages.dbNotChanged);
23
+ return {
24
+ cached: true,
25
+ errors: [],
26
+ synced: this.cachedMcpServers.length,
27
+ };
28
+ }
29
+ logger.info(TEXTS.logs.messages.dbChanged);
30
+ const mcpServers = this.cachedMcpServers;
31
+ this.lastDbMtime = currentMtime;
32
+ const filteredServers = this.filterServersByPlatform(mcpServers);
33
+ const openCodeMcpConfig = this.transformConfig(filteredServers);
34
+ await this.updateOpenCodeConfig(openCodeMcpConfig);
35
+ const duration = Date.now() - startTime;
36
+ logger.success(`${TEXTS.logs.messages.syncCompleted}${formatDuration(duration)}`);
37
+ return {
38
+ cached: false,
39
+ errors: [],
40
+ synced: filteredServers.length,
41
+ };
42
+ }
43
+ catch (error) {
44
+ logger.error('MCP 同步失败', { error: error instanceof Error ? error.message : String(error) });
45
+ return {
46
+ cached: false,
47
+ errors: [error instanceof Error ? error.message : String(error)],
48
+ synced: 0,
49
+ };
50
+ }
51
+ }
52
+ filterServersByPlatform(servers) {
53
+ const { selectedPlatforms } = this;
54
+ if (selectedPlatforms.includes('all')) {
55
+ return servers.filter(s => s.enabledClaude || s.enabledCodex || s.enabledGemini);
56
+ }
57
+ return servers.filter(s => {
58
+ if (selectedPlatforms.includes('claude') && s.enabledClaude)
59
+ return true;
60
+ if (selectedPlatforms.includes('codex') && s.enabledCodex)
61
+ return true;
62
+ if (selectedPlatforms.includes('gemini') && s.enabledGemini)
63
+ return true;
64
+ return false;
65
+ });
66
+ }
67
+ async getDbMtime() {
68
+ try {
69
+ const stats = await fs.stat(this.dbPath);
70
+ return stats.mtimeMs;
71
+ }
72
+ catch (error) {
73
+ logger.warn(`无法获取数据库文件修改时间:${error.message}`);
74
+ return 0;
75
+ }
76
+ }
77
+ transformConfig(servers) {
78
+ const config = {};
79
+ for (const server of servers) {
80
+ const serverConfig = server.config || {
81
+ args: [],
82
+ command: 'echo',
83
+ };
84
+ const { args = [], command } = serverConfig;
85
+ config[server.name] = {
86
+ command: [command, ...args],
87
+ enabled: true,
88
+ type: 'local',
89
+ };
90
+ }
91
+ logger.debug(`转换了 ${Object.keys(config).length} 个 MCP 服务器配置`);
92
+ return config;
93
+ }
94
+ async updateOpenCodeConfig(mcpConfig) {
95
+ try {
96
+ let existingConfig = {};
97
+ try {
98
+ const content = await fs.readFile(this.targetPath, 'utf8');
99
+ existingConfig = JSON.parse(content);
100
+ logger.debug('读取现有 OpenCode 配置');
101
+ }
102
+ catch {
103
+ logger.debug('OpenCode 配置文件不存在,将创建新文件');
104
+ }
105
+ existingConfig.mcp = mcpConfig;
106
+ await fs.writeFile(this.targetPath, JSON.stringify(existingConfig, null, 2));
107
+ logger.debug('OpenCode 配置已更新');
108
+ logger.success(`${TEXTS.logs.messages.syncingMcp}${Object.keys(mcpConfig).length}${TEXTS.logs.messages.mcpServers}`);
109
+ }
110
+ catch (error) {
111
+ throw new Error(`更新 OpenCode 配置失败:${error.message}`);
112
+ }
113
+ }
114
+ }
115
+ export { McpSyncer };
116
+ //# sourceMappingURL=mcp-syncer.js.map