Skip to content

Commit b744018

Browse files
committed
feat: introduce skills management functionality with IPC methods for listing, installing, and managing skills, including support for legacy migrations and conflict resolution
1 parent f750b3b commit b744018

29 files changed

Lines changed: 4201 additions & 103 deletions

src/main/__tests__/preload-bridge.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ const EXPECTED_KEYS = [
3232
'rulesSyncAll',
3333
'rulesDetectWorkspaces',
3434
'rulesImportFromProject',
35+
'skillsListInstalled',
36+
'skillsListCurated',
37+
'skillsDetectWorkspaces',
38+
'skillsPrepareInstall',
39+
'skillsInstallCurated',
40+
'skillsCreate',
41+
'skillsDelete',
42+
'skillsSetEnabled',
43+
'skillsMigrateLegacyPreview',
44+
'skillsMigrateLegacyApply',
45+
'skillsSyncListConflicts',
46+
'skillsSyncResolveConflict',
3547
'profilesList',
3648
'profilesGet',
3749
'profilesCreate',
@@ -51,6 +63,7 @@ const EXPECTED_KEYS = [
5163
'gitSyncStatus',
5264
'gitSyncConnectGitHub',
5365
'gitSyncConnectManual',
66+
'gitSyncTestRemote',
5467
'gitSyncDisconnect',
5568
'gitSyncPush',
5669
'gitSyncPull',
@@ -136,6 +149,10 @@ describe('preload bridge composition', () => {
136149
await api.clientsClearManualConfigPath('cursor')
137150
await api.serversList()
138151
await api.rulesSyncAll()
152+
await api.gitSyncTestRemote({
153+
remoteUrl: 'ssh://git@github.com/owner/repo.git',
154+
authMethod: 'ssh',
155+
})
139156
await api.settingsSet('language', 'en')
140157
await api.backupsList('cursor')
141158
await api.filesReveal('C:\\tmp\\file.txt')
@@ -168,6 +185,10 @@ describe('preload bridge composition', () => {
168185
expect(invoke).toHaveBeenCalledWith('clients:clear-manual-config-path', 'cursor')
169186
expect(invoke).toHaveBeenCalledWith('servers:list')
170187
expect(invoke).toHaveBeenCalledWith('rules:sync-all')
188+
expect(invoke).toHaveBeenCalledWith('git-sync:test-remote', {
189+
remoteUrl: 'ssh://git@github.com/owner/repo.git',
190+
authMethod: 'ssh',
191+
})
171192
expect(invoke).toHaveBeenCalledWith('settings:set', 'language', 'en')
172193
expect(invoke).toHaveBeenCalledWith('backups:list', 'cursor')
173194
expect(invoke).toHaveBeenCalledWith('files:reveal', 'C:\\tmp\\file.txt')

src/main/db/connection.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
MIGRATION_004,
2525
MIGRATION_005,
2626
MIGRATION_006,
27+
MIGRATION_007,
2728
} from './migrations/index'
2829

2930
/** All migration scripts in order. Index = version - 1. */
@@ -34,6 +35,7 @@ const MIGRATIONS: readonly string[] = [
3435
MIGRATION_004,
3536
MIGRATION_005,
3637
MIGRATION_006,
38+
MIGRATION_007,
3739
]
3840

3941
/** Lazily-created singleton instance. */

src/main/db/migrations/index.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* 004 — Add install metadata columns to servers (recipe, setup status, install policy)
1919
* 005 — Create device_setup_state table for per-device installation state
2020
* 006 — Create sync_install_intent table for syncing install intent across devices
21+
* 007 — Create sync_conflicts table for storing merge conflicts
2122
*/
2223

2324
/**
@@ -197,3 +198,26 @@ CREATE TABLE sync_install_intent (
197198
PRIMARY KEY (server_id)
198199
);
199200
`
201+
202+
/**
203+
* Migration 007 — Creates the `sync_conflicts` table for storing merge conflicts
204+
* between local and remote versions of registry entities.
205+
*/
206+
export const MIGRATION_007 = /* sql */ `
207+
CREATE TABLE sync_conflicts (
208+
id TEXT PRIMARY KEY,
209+
entity_type TEXT NOT NULL,
210+
entity_id TEXT NOT NULL,
211+
server_id TEXT,
212+
server_name TEXT NOT NULL,
213+
field TEXT NOT NULL,
214+
local_value TEXT NOT NULL DEFAULT 'null',
215+
remote_value TEXT NOT NULL DEFAULT 'null',
216+
resolved INTEGER NOT NULL DEFAULT 0,
217+
created_at TEXT NOT NULL,
218+
updated_at TEXT NOT NULL
219+
);
220+
221+
CREATE INDEX idx_sync_conflicts_resolved ON sync_conflicts(resolved);
222+
CREATE INDEX idx_sync_conflicts_entity_type ON sync_conflicts(entity_type);
223+
`

src/main/db/servers.repo.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* @file src/main/db/servers.repo.ts
33
*
44
* @created 07.03.2026
5-
* @modified 09.03.2026
5+
* @modified 10.03.2026
66
*
77
* @author Christian Blank <christianblank91@protonmail.com>
88
* @copyright 2026
@@ -226,4 +226,14 @@ export class ServersRepo {
226226
delete(id: string): void {
227227
this.db.prepare('DELETE FROM servers WHERE id = ?').run(id)
228228
}
229+
230+
/**
231+
* Updates only the setup status of a server.
232+
*/
233+
updateSetupStatus(id: string, setupStatus: McpServer['setupStatus']): void {
234+
const now = new Date().toISOString()
235+
this.db
236+
.prepare('UPDATE servers SET setup_status = ?, updated_at = ? WHERE id = ?')
237+
.run(setupStatus, now, id)
238+
}
229239
}

0 commit comments

Comments
 (0)