@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.
- package/README.md +1 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +41 -1
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/repositories/SyncConfigRepository.d.ts +91 -0
- package/dist/src/repositories/SyncConfigRepository.d.ts.map +1 -0
- package/dist/src/repositories/SyncConfigRepository.js +202 -0
- package/dist/src/repositories/SyncConfigRepository.js.map +1 -0
- package/dist/src/repositories/SyncHistoryRepository.d.ts +104 -0
- package/dist/src/repositories/SyncHistoryRepository.d.ts.map +1 -0
- package/dist/src/repositories/SyncHistoryRepository.js +235 -0
- package/dist/src/repositories/SyncHistoryRepository.js.map +1 -0
- package/dist/src/scripts/github-import/github-client.d.ts +24 -0
- package/dist/src/scripts/github-import/github-client.d.ts.map +1 -1
- package/dist/src/scripts/github-import/github-client.js +103 -0
- package/dist/src/scripts/github-import/github-client.js.map +1 -1
- package/dist/src/scripts/github-import/index.js +3 -10
- package/dist/src/scripts/github-import/index.js.map +1 -1
- package/dist/src/scripts/merge-skills.d.ts +56 -0
- package/dist/src/scripts/merge-skills.d.ts.map +1 -0
- package/dist/src/scripts/merge-skills.js +411 -0
- package/dist/src/scripts/merge-skills.js.map +1 -0
- package/dist/src/scripts/skill-scanner/index.d.ts +9 -2
- package/dist/src/scripts/skill-scanner/index.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/index.js +98 -7
- package/dist/src/scripts/skill-scanner/index.js.map +1 -1
- package/dist/src/scripts/skill-scanner/logger.d.ts +51 -0
- package/dist/src/scripts/skill-scanner/logger.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/logger.js +255 -1
- package/dist/src/scripts/skill-scanner/logger.js.map +1 -1
- package/dist/src/scripts/skill-scanner/reporter.d.ts +1 -1
- package/dist/src/scripts/skill-scanner/reporter.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/reporter.js +67 -15
- package/dist/src/scripts/skill-scanner/reporter.js.map +1 -1
- package/dist/src/scripts/skill-scanner/scanner.d.ts +5 -2
- package/dist/src/scripts/skill-scanner/scanner.d.ts.map +1 -1
- package/dist/src/scripts/skill-scanner/scanner.js +156 -39
- package/dist/src/scripts/skill-scanner/scanner.js.map +1 -1
- package/dist/src/scripts/skill-scanner/types.d.ts +44 -0
- package/dist/src/scripts/skill-scanner/types.d.ts.map +1 -1
- package/dist/src/sync/BackgroundSyncService.d.ts +90 -0
- package/dist/src/sync/BackgroundSyncService.d.ts.map +1 -0
- package/dist/src/sync/BackgroundSyncService.js +214 -0
- package/dist/src/sync/BackgroundSyncService.js.map +1 -0
- package/dist/src/sync/SyncEngine.d.ts +76 -0
- package/dist/src/sync/SyncEngine.d.ts.map +1 -0
- package/dist/src/sync/SyncEngine.js +272 -0
- package/dist/src/sync/SyncEngine.js.map +1 -0
- package/dist/src/sync/index.d.ts +11 -0
- package/dist/src/sync/index.d.ts.map +1 -0
- package/dist/src/sync/index.js +14 -0
- package/dist/src/sync/index.js.map +1 -0
- package/dist/tests/sync/SyncConfigRepository.test.d.ts +7 -0
- package/dist/tests/sync/SyncConfigRepository.test.d.ts.map +1 -0
- package/dist/tests/sync/SyncConfigRepository.test.js +154 -0
- package/dist/tests/sync/SyncConfigRepository.test.js.map +1 -0
- package/dist/tests/sync/SyncEngine.test.d.ts +7 -0
- package/dist/tests/sync/SyncEngine.test.d.ts.map +1 -0
- package/dist/tests/sync/SyncEngine.test.js +298 -0
- package/dist/tests/sync/SyncEngine.test.js.map +1 -0
- package/dist/tests/sync/SyncHistoryRepository.test.d.ts +7 -0
- package/dist/tests/sync/SyncHistoryRepository.test.d.ts.map +1 -0
- package/dist/tests/sync/SyncHistoryRepository.test.js +220 -0
- package/dist/tests/sync/SyncHistoryRepository.test.js.map +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"SyncConfigRepository.test.d.ts","sourceRoot":"","sources":["../../../tests/sync/SyncConfigRepository.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|