@skillsmith/core 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +1 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/db/schema.d.ts +1 -1
  4. package/dist/src/db/schema.d.ts.map +1 -1
  5. package/dist/src/db/schema.js +41 -1
  6. package/dist/src/db/schema.js.map +1 -1
  7. package/dist/src/index.d.ts +1 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +2 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/repositories/SyncConfigRepository.d.ts +91 -0
  12. package/dist/src/repositories/SyncConfigRepository.d.ts.map +1 -0
  13. package/dist/src/repositories/SyncConfigRepository.js +202 -0
  14. package/dist/src/repositories/SyncConfigRepository.js.map +1 -0
  15. package/dist/src/repositories/SyncHistoryRepository.d.ts +104 -0
  16. package/dist/src/repositories/SyncHistoryRepository.d.ts.map +1 -0
  17. package/dist/src/repositories/SyncHistoryRepository.js +235 -0
  18. package/dist/src/repositories/SyncHistoryRepository.js.map +1 -0
  19. package/dist/src/scripts/github-import/github-client.d.ts +24 -0
  20. package/dist/src/scripts/github-import/github-client.d.ts.map +1 -1
  21. package/dist/src/scripts/github-import/github-client.js +103 -0
  22. package/dist/src/scripts/github-import/github-client.js.map +1 -1
  23. package/dist/src/scripts/github-import/index.js +3 -10
  24. package/dist/src/scripts/github-import/index.js.map +1 -1
  25. package/dist/src/scripts/merge-skills.d.ts +56 -0
  26. package/dist/src/scripts/merge-skills.d.ts.map +1 -0
  27. package/dist/src/scripts/merge-skills.js +411 -0
  28. package/dist/src/scripts/merge-skills.js.map +1 -0
  29. package/dist/src/scripts/skill-scanner/index.d.ts +9 -2
  30. package/dist/src/scripts/skill-scanner/index.d.ts.map +1 -1
  31. package/dist/src/scripts/skill-scanner/index.js +98 -7
  32. package/dist/src/scripts/skill-scanner/index.js.map +1 -1
  33. package/dist/src/scripts/skill-scanner/logger.d.ts +51 -0
  34. package/dist/src/scripts/skill-scanner/logger.d.ts.map +1 -1
  35. package/dist/src/scripts/skill-scanner/logger.js +255 -1
  36. package/dist/src/scripts/skill-scanner/logger.js.map +1 -1
  37. package/dist/src/scripts/skill-scanner/reporter.d.ts +1 -1
  38. package/dist/src/scripts/skill-scanner/reporter.d.ts.map +1 -1
  39. package/dist/src/scripts/skill-scanner/reporter.js +67 -15
  40. package/dist/src/scripts/skill-scanner/reporter.js.map +1 -1
  41. package/dist/src/scripts/skill-scanner/scanner.d.ts +5 -2
  42. package/dist/src/scripts/skill-scanner/scanner.d.ts.map +1 -1
  43. package/dist/src/scripts/skill-scanner/scanner.js +156 -39
  44. package/dist/src/scripts/skill-scanner/scanner.js.map +1 -1
  45. package/dist/src/scripts/skill-scanner/types.d.ts +44 -0
  46. package/dist/src/scripts/skill-scanner/types.d.ts.map +1 -1
  47. package/dist/src/sync/BackgroundSyncService.d.ts +90 -0
  48. package/dist/src/sync/BackgroundSyncService.d.ts.map +1 -0
  49. package/dist/src/sync/BackgroundSyncService.js +214 -0
  50. package/dist/src/sync/BackgroundSyncService.js.map +1 -0
  51. package/dist/src/sync/SyncEngine.d.ts +76 -0
  52. package/dist/src/sync/SyncEngine.d.ts.map +1 -0
  53. package/dist/src/sync/SyncEngine.js +272 -0
  54. package/dist/src/sync/SyncEngine.js.map +1 -0
  55. package/dist/src/sync/index.d.ts +11 -0
  56. package/dist/src/sync/index.d.ts.map +1 -0
  57. package/dist/src/sync/index.js +14 -0
  58. package/dist/src/sync/index.js.map +1 -0
  59. package/dist/tests/sync/SyncConfigRepository.test.d.ts +7 -0
  60. package/dist/tests/sync/SyncConfigRepository.test.d.ts.map +1 -0
  61. package/dist/tests/sync/SyncConfigRepository.test.js +154 -0
  62. package/dist/tests/sync/SyncConfigRepository.test.js.map +1 -0
  63. package/dist/tests/sync/SyncEngine.test.d.ts +7 -0
  64. package/dist/tests/sync/SyncEngine.test.d.ts.map +1 -0
  65. package/dist/tests/sync/SyncEngine.test.js +298 -0
  66. package/dist/tests/sync/SyncEngine.test.js.map +1 -0
  67. package/dist/tests/sync/SyncHistoryRepository.test.d.ts +7 -0
  68. package/dist/tests/sync/SyncHistoryRepository.test.d.ts.map +1 -0
  69. package/dist/tests/sync/SyncHistoryRepository.test.js +220 -0
  70. package/dist/tests/sync/SyncHistoryRepository.test.js.map +1 -0
  71. package/package.json +1 -1
@@ -0,0 +1,214 @@
1
+ /**
2
+ * BackgroundSyncService - Session-based automatic sync
3
+ *
4
+ * Runs sync operations during active MCP server sessions based on
5
+ * user-configured frequency (daily/weekly). Uses non-blocking timers
6
+ * that don't prevent process exit.
7
+ */
8
+ /**
9
+ * Background sync service for automatic registry synchronization
10
+ */
11
+ export class BackgroundSyncService {
12
+ syncEngine;
13
+ configRepo;
14
+ options;
15
+ timer = null;
16
+ isRunning = false;
17
+ isStopped = false;
18
+ state = {
19
+ isStarted: false,
20
+ isRunning: false,
21
+ lastResult: null,
22
+ lastError: null,
23
+ checksPerformed: 0,
24
+ syncsTriggered: 0,
25
+ };
26
+ constructor(syncEngine, configRepo, options = {}) {
27
+ this.syncEngine = syncEngine;
28
+ this.configRepo = configRepo;
29
+ this.options = {
30
+ checkIntervalMs: options.checkIntervalMs ?? 60000, // 1 minute
31
+ syncOnStart: options.syncOnStart ?? true,
32
+ onSyncComplete: options.onSyncComplete ?? (() => { }),
33
+ onSyncError: options.onSyncError ?? (() => { }),
34
+ debug: options.debug ?? false,
35
+ };
36
+ }
37
+ log(message, data) {
38
+ if (this.options.debug) {
39
+ console.log(`[BackgroundSync] ${message}`, data ?? '');
40
+ }
41
+ }
42
+ /**
43
+ * Start the background sync service
44
+ */
45
+ start() {
46
+ if (this.state.isStarted) {
47
+ this.log('Already started, ignoring');
48
+ return;
49
+ }
50
+ const config = this.configRepo.getConfig();
51
+ if (!config.enabled) {
52
+ this.log('Auto-sync is disabled, not starting');
53
+ return;
54
+ }
55
+ this.state.isStarted = true;
56
+ this.isStopped = false;
57
+ this.log('Starting background sync service', {
58
+ frequency: config.frequency,
59
+ intervalMs: config.intervalMs,
60
+ lastSyncAt: config.lastSyncAt,
61
+ });
62
+ // Check if sync is due on startup
63
+ if (this.options.syncOnStart && this.shouldSyncNow()) {
64
+ this.log('Sync is due, triggering immediately');
65
+ this.triggerSync();
66
+ }
67
+ // Start periodic check timer
68
+ this.timer = setInterval(() => this.checkAndSync(), this.options.checkIntervalMs);
69
+ // Don't block process exit
70
+ if (this.timer.unref) {
71
+ this.timer.unref();
72
+ }
73
+ }
74
+ /**
75
+ * Stop the background sync service
76
+ */
77
+ stop() {
78
+ this.log('Stopping background sync service');
79
+ this.isStopped = true;
80
+ this.state.isStarted = false;
81
+ if (this.timer) {
82
+ clearInterval(this.timer);
83
+ this.timer = null;
84
+ }
85
+ }
86
+ /**
87
+ * Check if sync should run now
88
+ */
89
+ shouldSyncNow() {
90
+ const config = this.configRepo.getConfig();
91
+ // Must be enabled
92
+ if (!config.enabled) {
93
+ return false;
94
+ }
95
+ // If never synced, sync now
96
+ if (!config.lastSyncAt) {
97
+ return true;
98
+ }
99
+ // Check if next sync time has passed
100
+ return this.configRepo.isSyncDue();
101
+ }
102
+ /**
103
+ * Check if sync is due and trigger if needed
104
+ */
105
+ async checkAndSync() {
106
+ this.state.checksPerformed++;
107
+ if (this.isStopped) {
108
+ return;
109
+ }
110
+ // Re-check config in case it changed
111
+ const config = this.configRepo.getConfig();
112
+ if (!config.enabled) {
113
+ this.log('Auto-sync disabled during check');
114
+ return;
115
+ }
116
+ if (this.shouldSyncNow()) {
117
+ this.log('Sync is due, triggering');
118
+ await this.triggerSync();
119
+ }
120
+ }
121
+ /**
122
+ * Trigger a sync operation
123
+ */
124
+ async triggerSync() {
125
+ // Prevent concurrent syncs
126
+ if (this.isRunning) {
127
+ this.log('Sync already in progress, skipping');
128
+ return;
129
+ }
130
+ this.isRunning = true;
131
+ this.state.isRunning = true;
132
+ this.state.syncsTriggered++;
133
+ try {
134
+ this.log('Starting sync');
135
+ const result = await this.syncEngine.sync();
136
+ this.state.lastResult = result;
137
+ this.state.lastError = null;
138
+ this.log('Sync completed', {
139
+ success: result.success,
140
+ added: result.skillsAdded,
141
+ updated: result.skillsUpdated,
142
+ unchanged: result.skillsUnchanged,
143
+ durationMs: result.durationMs,
144
+ });
145
+ this.options.onSyncComplete(result);
146
+ }
147
+ catch (error) {
148
+ const err = error instanceof Error ? error : new Error(String(error));
149
+ this.state.lastError = err;
150
+ this.log('Sync failed', { error: err.message });
151
+ this.options.onSyncError(err);
152
+ }
153
+ finally {
154
+ this.isRunning = false;
155
+ this.state.isRunning = false;
156
+ }
157
+ }
158
+ /**
159
+ * Manually trigger a sync (for testing or manual intervention)
160
+ */
161
+ async manualSync() {
162
+ this.log('Manual sync triggered');
163
+ this.state.syncsTriggered++;
164
+ if (this.isRunning) {
165
+ throw new Error('Sync already in progress');
166
+ }
167
+ this.isRunning = true;
168
+ this.state.isRunning = true;
169
+ try {
170
+ const result = await this.syncEngine.sync();
171
+ this.state.lastResult = result;
172
+ this.state.lastError = null;
173
+ this.options.onSyncComplete(result);
174
+ return result;
175
+ }
176
+ catch (error) {
177
+ const err = error instanceof Error ? error : new Error(String(error));
178
+ this.state.lastError = err;
179
+ this.options.onSyncError(err);
180
+ throw err;
181
+ }
182
+ finally {
183
+ this.isRunning = false;
184
+ this.state.isRunning = false;
185
+ }
186
+ }
187
+ /**
188
+ * Get current service state
189
+ */
190
+ getState() {
191
+ return { ...this.state };
192
+ }
193
+ /**
194
+ * Check if service is actively running syncs
195
+ */
196
+ isSyncRunning() {
197
+ return this.isRunning;
198
+ }
199
+ /**
200
+ * Check if service is started
201
+ */
202
+ isServiceStarted() {
203
+ return this.state.isStarted;
204
+ }
205
+ }
206
+ /**
207
+ * Create and start a background sync service
208
+ */
209
+ export function createBackgroundSyncService(syncEngine, configRepo, options) {
210
+ const service = new BackgroundSyncService(syncEngine, configRepo, options);
211
+ service.start();
212
+ return service;
213
+ }
214
+ //# sourceMappingURL=BackgroundSyncService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackgroundSyncService.js","sourceRoot":"","sources":["../../../src/sync/BackgroundSyncService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * SyncEngine - Core sync logic for registry synchronization
3
+ *
4
+ * Implements differential sync by comparing local database state with
5
+ * the live Skillsmith registry API. Fetches only changed skills based
6
+ * on updated_at timestamps.
7
+ */
8
+ import type { SkillsmithApiClient } from '../api/client.js';
9
+ import type { SkillRepository } from '../repositories/SkillRepository.js';
10
+ import type { SyncConfigRepository } from '../repositories/SyncConfigRepository.js';
11
+ import type { SyncHistoryRepository } from '../repositories/SyncHistoryRepository.js';
12
+ /**
13
+ * Sync options
14
+ */
15
+ export interface SyncOptions {
16
+ /** Force full sync (ignore lastSyncAt) */
17
+ force?: boolean;
18
+ /** Don't write changes, just report what would sync */
19
+ dryRun?: boolean;
20
+ /** API pagination size (default: 100) */
21
+ pageSize?: number;
22
+ /** Progress callback */
23
+ onProgress?: (progress: SyncProgress) => void;
24
+ }
25
+ /**
26
+ * Sync progress info
27
+ */
28
+ export interface SyncProgress {
29
+ phase: 'connecting' | 'fetching' | 'comparing' | 'upserting' | 'complete';
30
+ current: number;
31
+ total: number;
32
+ skillsProcessed: number;
33
+ skillsChanged: number;
34
+ message?: string;
35
+ }
36
+ /**
37
+ * Sync result
38
+ */
39
+ export interface SyncResult {
40
+ success: boolean;
41
+ skillsAdded: number;
42
+ skillsUpdated: number;
43
+ skillsUnchanged: number;
44
+ totalProcessed: number;
45
+ errors: string[];
46
+ durationMs: number;
47
+ dryRun: boolean;
48
+ }
49
+ /**
50
+ * Sync engine for registry synchronization
51
+ */
52
+ export declare class SyncEngine {
53
+ private apiClient;
54
+ private skillRepo;
55
+ private syncConfigRepo;
56
+ private syncHistoryRepo;
57
+ constructor(apiClient: SkillsmithApiClient, skillRepo: SkillRepository, syncConfigRepo: SyncConfigRepository, syncHistoryRepo: SyncHistoryRepository);
58
+ /**
59
+ * Run sync operation
60
+ */
61
+ sync(options?: SyncOptions): Promise<SyncResult>;
62
+ /**
63
+ * Upsert skills into local database
64
+ */
65
+ private upsertSkills;
66
+ /**
67
+ * Get sync status summary
68
+ */
69
+ getStatus(): {
70
+ config: ReturnType<SyncConfigRepository['getConfig']>;
71
+ lastRun: ReturnType<SyncHistoryRepository['getLastSuccessful']>;
72
+ isRunning: boolean;
73
+ isDue: boolean;
74
+ };
75
+ }
76
+ //# sourceMappingURL=SyncEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncEngine.d.ts","sourceRoot":"","sources":["../../../src/sync/SyncEngine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,kBAAkB,CAAA;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAA;AACnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAA;AAErF;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,uDAAuD;IACvD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAA;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAA;IACzE,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,OAAO,CAAA;CAChB;AAWD;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,eAAe,CAAuB;gBAG5C,SAAS,EAAE,mBAAmB,EAC9B,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,oBAAoB,EACpC,eAAe,EAAE,qBAAqB;IAQxC;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqN1D;;OAEG;YACW,YAAY;IAgD1B;;OAEG;IACH,SAAS,IAAI;QACX,MAAM,EAAE,UAAU,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAA;QACrD,OAAO,EAAE,UAAU,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,CAAC,CAAA;QAC/D,SAAS,EAAE,OAAO,CAAA;QAClB,KAAK,EAAE,OAAO,CAAA;KACf;CAQF"}
@@ -0,0 +1,272 @@
1
+ /**
2
+ * SyncEngine - Core sync logic for registry synchronization
3
+ *
4
+ * Implements differential sync by comparing local database state with
5
+ * the live Skillsmith registry API. Fetches only changed skills based
6
+ * on updated_at timestamps.
7
+ */
8
+ /**
9
+ * Sync engine for registry synchronization
10
+ */
11
+ export class SyncEngine {
12
+ apiClient;
13
+ skillRepo;
14
+ syncConfigRepo;
15
+ syncHistoryRepo;
16
+ constructor(apiClient, skillRepo, syncConfigRepo, syncHistoryRepo) {
17
+ this.apiClient = apiClient;
18
+ this.skillRepo = skillRepo;
19
+ this.syncConfigRepo = syncConfigRepo;
20
+ this.syncHistoryRepo = syncHistoryRepo;
21
+ }
22
+ /**
23
+ * Run sync operation
24
+ */
25
+ async sync(options = {}) {
26
+ const { force = false, dryRun = false, pageSize = 100, onProgress } = options;
27
+ const startTime = Date.now();
28
+ const errors = [];
29
+ let skillsAdded = 0;
30
+ let skillsUpdated = 0;
31
+ let skillsUnchanged = 0;
32
+ let totalProcessed = 0;
33
+ // Start history tracking (skip for dry run)
34
+ const runId = dryRun ? null : this.syncHistoryRepo.startRun();
35
+ try {
36
+ // Check if offline
37
+ if (this.apiClient.isOffline()) {
38
+ throw new Error('API client is in offline mode. Cannot sync.');
39
+ }
40
+ // Get last sync time for differential sync
41
+ const config = this.syncConfigRepo.getConfig();
42
+ const lastSyncAt = force ? null : config.lastSyncAt;
43
+ onProgress?.({
44
+ phase: 'connecting',
45
+ current: 0,
46
+ total: 0,
47
+ skillsProcessed: 0,
48
+ skillsChanged: 0,
49
+ message: 'Checking API health...',
50
+ });
51
+ // Health check
52
+ const health = await this.apiClient.checkHealth();
53
+ if (health.status === 'unhealthy') {
54
+ throw new Error('API is unhealthy. Try again later.');
55
+ }
56
+ onProgress?.({
57
+ phase: 'fetching',
58
+ current: 0,
59
+ total: 0,
60
+ skillsProcessed: 0,
61
+ skillsChanged: 0,
62
+ message: lastSyncAt ? `Fetching changes since ${lastSyncAt}` : 'Fetching all skills...',
63
+ });
64
+ // Fetch all skills from API with pagination
65
+ let offset = 0;
66
+ let hasMore = true;
67
+ const allSkills = [];
68
+ while (hasMore) {
69
+ try {
70
+ // Use broad search to get skills (API requires min 2 char query)
71
+ // Search for common patterns that match most skills
72
+ const response = await this.apiClient.search({
73
+ query: 'skill', // Broad term that matches most skill names/descriptions
74
+ limit: pageSize,
75
+ offset,
76
+ });
77
+ const skills = response.data;
78
+ allSkills.push(...skills);
79
+ onProgress?.({
80
+ phase: 'fetching',
81
+ current: allSkills.length,
82
+ total: 0, // Unknown total
83
+ skillsProcessed: 0,
84
+ skillsChanged: 0,
85
+ message: `Fetched ${allSkills.length} skills...`,
86
+ });
87
+ // Check if there are more results
88
+ hasMore = skills.length === pageSize;
89
+ offset += pageSize;
90
+ }
91
+ catch (error) {
92
+ const message = error instanceof Error ? error.message : String(error);
93
+ errors.push(`Fetch error at offset ${offset}: ${message}`);
94
+ // Continue with what we have if we got some results
95
+ if (allSkills.length > 0) {
96
+ hasMore = false;
97
+ }
98
+ else {
99
+ throw error;
100
+ }
101
+ }
102
+ }
103
+ onProgress?.({
104
+ phase: 'comparing',
105
+ current: 0,
106
+ total: allSkills.length,
107
+ skillsProcessed: 0,
108
+ skillsChanged: 0,
109
+ message: 'Comparing with local database...',
110
+ });
111
+ // Filter for changed skills if doing differential sync
112
+ const skillsToProcess = lastSyncAt
113
+ ? allSkills.filter((skill) => new Date(skill.updated_at) > new Date(lastSyncAt))
114
+ : allSkills;
115
+ totalProcessed = allSkills.length;
116
+ onProgress?.({
117
+ phase: 'upserting',
118
+ current: 0,
119
+ total: skillsToProcess.length,
120
+ skillsProcessed: totalProcessed,
121
+ skillsChanged: skillsToProcess.length,
122
+ message: `Processing ${skillsToProcess.length} changed skills...`,
123
+ });
124
+ // Upsert changed skills
125
+ if (!dryRun && skillsToProcess.length > 0) {
126
+ const stats = await this.upsertSkills(skillsToProcess, (current) => {
127
+ onProgress?.({
128
+ phase: 'upserting',
129
+ current,
130
+ total: skillsToProcess.length,
131
+ skillsProcessed: totalProcessed,
132
+ skillsChanged: skillsToProcess.length,
133
+ message: `Upserting skill ${current}/${skillsToProcess.length}...`,
134
+ });
135
+ });
136
+ skillsAdded = stats.added;
137
+ skillsUpdated = stats.updated;
138
+ skillsUnchanged = stats.unchanged;
139
+ }
140
+ else if (dryRun) {
141
+ // In dry run, count what would be added/updated
142
+ for (const skill of skillsToProcess) {
143
+ const existing = this.skillRepo.findById(skill.id);
144
+ if (existing) {
145
+ skillsUpdated++;
146
+ }
147
+ else {
148
+ skillsAdded++;
149
+ }
150
+ }
151
+ skillsUnchanged = allSkills.length - skillsToProcess.length;
152
+ }
153
+ else {
154
+ skillsUnchanged = allSkills.length;
155
+ }
156
+ const durationMs = Date.now() - startTime;
157
+ // Update sync state (skip for dry run)
158
+ if (!dryRun) {
159
+ const syncTimestamp = new Date().toISOString();
160
+ this.syncConfigRepo.setLastSync(syncTimestamp, skillsAdded + skillsUpdated);
161
+ if (runId) {
162
+ if (errors.length > 0) {
163
+ this.syncHistoryRepo.completeRunPartial(runId, { skillsAdded, skillsUpdated, skillsUnchanged }, errors.join('; '));
164
+ }
165
+ else {
166
+ this.syncHistoryRepo.completeRun(runId, {
167
+ skillsAdded,
168
+ skillsUpdated,
169
+ skillsUnchanged,
170
+ });
171
+ }
172
+ }
173
+ }
174
+ onProgress?.({
175
+ phase: 'complete',
176
+ current: skillsToProcess.length,
177
+ total: skillsToProcess.length,
178
+ skillsProcessed: totalProcessed,
179
+ skillsChanged: skillsAdded + skillsUpdated,
180
+ message: 'Sync complete',
181
+ });
182
+ return {
183
+ success: errors.length === 0,
184
+ skillsAdded,
185
+ skillsUpdated,
186
+ skillsUnchanged,
187
+ totalProcessed,
188
+ errors,
189
+ durationMs,
190
+ dryRun,
191
+ };
192
+ }
193
+ catch (error) {
194
+ const message = error instanceof Error ? error.message : String(error);
195
+ errors.push(message);
196
+ // Record failure (skip for dry run)
197
+ if (!dryRun) {
198
+ this.syncConfigRepo.setLastSyncError(message);
199
+ if (runId) {
200
+ this.syncHistoryRepo.failRun(runId, message);
201
+ }
202
+ }
203
+ return {
204
+ success: false,
205
+ skillsAdded,
206
+ skillsUpdated,
207
+ skillsUnchanged,
208
+ totalProcessed,
209
+ errors,
210
+ durationMs: Date.now() - startTime,
211
+ dryRun,
212
+ };
213
+ }
214
+ }
215
+ /**
216
+ * Upsert skills into local database
217
+ */
218
+ async upsertSkills(skills, onProgress) {
219
+ let added = 0;
220
+ let updated = 0;
221
+ let unchanged = 0;
222
+ for (let i = 0; i < skills.length; i++) {
223
+ const skill = skills[i];
224
+ const existing = this.skillRepo.findById(skill.id);
225
+ if (existing) {
226
+ // Check if actually changed
227
+ if (existing.updatedAt !== skill.updated_at) {
228
+ this.skillRepo.update(skill.id, {
229
+ name: skill.name,
230
+ description: skill.description ?? undefined,
231
+ author: skill.author ?? undefined,
232
+ repoUrl: skill.repo_url ?? undefined,
233
+ qualityScore: skill.quality_score ?? undefined,
234
+ trustTier: skill.trust_tier,
235
+ tags: skill.tags,
236
+ });
237
+ updated++;
238
+ }
239
+ else {
240
+ unchanged++;
241
+ }
242
+ }
243
+ else {
244
+ this.skillRepo.create({
245
+ id: skill.id,
246
+ name: skill.name,
247
+ description: skill.description ?? undefined,
248
+ author: skill.author ?? undefined,
249
+ repoUrl: skill.repo_url ?? undefined,
250
+ qualityScore: skill.quality_score ?? undefined,
251
+ trustTier: skill.trust_tier,
252
+ tags: skill.tags,
253
+ });
254
+ added++;
255
+ }
256
+ onProgress?.(i + 1);
257
+ }
258
+ return { added, updated, unchanged };
259
+ }
260
+ /**
261
+ * Get sync status summary
262
+ */
263
+ getStatus() {
264
+ return {
265
+ config: this.syncConfigRepo.getConfig(),
266
+ lastRun: this.syncHistoryRepo.getLastSuccessful(),
267
+ isRunning: this.syncHistoryRepo.isRunning(),
268
+ isDue: this.syncConfigRepo.isSyncDue(),
269
+ };
270
+ }
271
+ }
272
+ //# sourceMappingURL=SyncEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncEngine.js","sourceRoot":"","sources":["../../../src/sync/SyncEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Sync Module - Registry synchronization
3
+ *
4
+ * Provides functionality for synchronizing the local skill database
5
+ * with the live Skillsmith registry.
6
+ */
7
+ export { SyncConfigRepository, type SyncConfig, type SyncConfigUpdate, type SyncFrequency, FREQUENCY_INTERVALS, } from '../repositories/SyncConfigRepository.js';
8
+ export { SyncHistoryRepository, type SyncHistoryEntry, type SyncStatus, type SyncRunResult, } from '../repositories/SyncHistoryRepository.js';
9
+ export { SyncEngine, type SyncOptions, type SyncProgress, type SyncResult } from './SyncEngine.js';
10
+ export { BackgroundSyncService, createBackgroundSyncService, type BackgroundSyncOptions, type BackgroundSyncState, } from './BackgroundSyncService.js';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,mBAAmB,GACpB,MAAM,yCAAyC,CAAA;AAEhD,OAAO,EACL,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,0CAA0C,CAAA;AAGjD,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAGlG,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACzB,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Sync Module - Registry synchronization
3
+ *
4
+ * Provides functionality for synchronizing the local skill database
5
+ * with the live Skillsmith registry.
6
+ */
7
+ // Repositories
8
+ export { SyncConfigRepository, FREQUENCY_INTERVALS, } from '../repositories/SyncConfigRepository.js';
9
+ export { SyncHistoryRepository, } from '../repositories/SyncHistoryRepository.js';
10
+ // Core sync engine
11
+ export { SyncEngine } from './SyncEngine.js';
12
+ // Background service
13
+ export { BackgroundSyncService, createBackgroundSyncService, } from './BackgroundSyncService.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAe;AACf,OAAO,EACL,oBAAoB,EAIpB,mBAAmB,GACpB,MAAM,yCAAyC,CAAA;AAEhD,OAAO,EACL,qBAAqB,GAItB,MAAM,0CAA0C,CAAA;AAEjD,mBAAmB;AACnB,OAAO,EAAE,UAAU,EAAwD,MAAM,iBAAiB,CAAA;AAElG,qBAAqB;AACrB,OAAO,EACL,qBAAqB,EACrB,2BAA2B,GAG5B,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * SyncConfigRepository Tests
3
+ *
4
+ * Tests for sync configuration management.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=SyncConfigRepository.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncConfigRepository.test.d.ts","sourceRoot":"","sources":["../../../tests/sync/SyncConfigRepository.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}