devchain-cli 0.9.1 → 0.9.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.
- package/dist/drizzle/0042_nice_flatman.sql +10 -0
- package/dist/drizzle/0043_majestic_starhawk.sql +10 -0
- package/dist/drizzle/meta/0042_snapshot.json +4171 -0
- package/dist/drizzle/meta/0043_snapshot.json +4231 -0
- package/dist/drizzle/meta/_journal.json +15 -1
- package/dist/server/modules/skills/adapters/github-skill-source.base.d.ts +2 -5
- package/dist/server/modules/skills/adapters/github-skill-source.base.js +31 -100
- package/dist/server/modules/skills/adapters/github-skill-source.base.js.map +1 -1
- package/dist/server/modules/skills/adapters/local-skill-source.adapter.d.ts +16 -0
- package/dist/server/modules/skills/adapters/local-skill-source.adapter.js +265 -0
- package/dist/server/modules/skills/adapters/local-skill-source.adapter.js.map +1 -0
- package/dist/server/modules/skills/adapters/skill-parsing.utils.d.ts +32 -0
- package/dist/server/modules/skills/adapters/skill-parsing.utils.js +169 -0
- package/dist/server/modules/skills/adapters/skill-parsing.utils.js.map +1 -0
- package/dist/server/modules/skills/controllers/local-sources.controller.d.ts +12 -0
- package/dist/server/modules/skills/controllers/local-sources.controller.js +71 -0
- package/dist/server/modules/skills/controllers/local-sources.controller.js.map +1 -0
- package/dist/server/modules/skills/controllers/skills.controller.d.ts +11 -1
- package/dist/server/modules/skills/controllers/skills.controller.js +35 -3
- package/dist/server/modules/skills/controllers/skills.controller.js.map +1 -1
- package/dist/server/modules/skills/dtos/local-sources.dto.d.ts +42 -0
- package/dist/server/modules/skills/dtos/local-sources.dto.js +30 -0
- package/dist/server/modules/skills/dtos/local-sources.dto.js.map +1 -0
- package/dist/server/modules/skills/dtos/skill.dto.d.ts +16 -0
- package/dist/server/modules/skills/dtos/skill.dto.js +7 -1
- package/dist/server/modules/skills/dtos/skill.dto.js.map +1 -1
- package/dist/server/modules/skills/services/community-sources.service.d.ts +8 -1
- package/dist/server/modules/skills/services/community-sources.service.js +62 -3
- package/dist/server/modules/skills/services/community-sources.service.js.map +1 -1
- package/dist/server/modules/skills/services/local-sources.service.d.ts +20 -0
- package/dist/server/modules/skills/services/local-sources.service.js +206 -0
- package/dist/server/modules/skills/services/local-sources.service.js.map +1 -0
- package/dist/server/modules/skills/services/skill-source-registry.service.d.ts +11 -0
- package/dist/server/modules/skills/services/skill-source-registry.service.js +99 -3
- package/dist/server/modules/skills/services/skill-source-registry.service.js.map +1 -1
- package/dist/server/modules/skills/services/skill-sync.service.d.ts +4 -0
- package/dist/server/modules/skills/services/skill-sync.service.js +93 -0
- package/dist/server/modules/skills/services/skill-sync.service.js.map +1 -1
- package/dist/server/modules/skills/services/skills.service.d.ts +14 -2
- package/dist/server/modules/skills/services/skills.service.js +125 -23
- package/dist/server/modules/skills/services/skills.service.js.map +1 -1
- package/dist/server/modules/skills/skills.module.js +4 -1
- package/dist/server/modules/skills/skills.module.js.map +1 -1
- package/dist/server/modules/storage/db/schema.d.ts +202 -0
- package/dist/server/modules/storage/db/schema.js +19 -1
- package/dist/server/modules/storage/db/schema.js.map +1 -1
- package/dist/server/modules/storage/interfaces/storage.interface.d.ts +13 -1
- package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
- package/dist/server/modules/storage/local/local-storage.service.d.ts +18 -1
- package/dist/server/modules/storage/local/local-storage.service.js +294 -3
- package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
- package/dist/server/modules/storage/models/domain.models.d.ts +8 -0
- package/dist/server/tsconfig.tsbuildinfo +1 -1
- package/dist/server/ui/assets/{ReviewDetailPage-D13dH7Wh.js → ReviewDetailPage-BvSckWKj.js} +1 -1
- package/dist/server/ui/assets/{ReviewsPage-C98ST0lf.js → ReviewsPage-MKT-vv59.js} +1 -1
- package/dist/server/ui/assets/index-BtUq-Qxb.css +32 -0
- package/dist/server/ui/assets/{index-C8Dc1yQf.js → index-kTb634Zp.js} +194 -194
- package/dist/server/ui/assets/{useReviewSubscription-CmLuF45Z.js → useReviewSubscription-Dc58i6Bk.js} +1 -1
- package/dist/server/ui/index.html +2 -2
- package/package.json +5 -1
- package/dist/server/ui/assets/index-DZkJ40z9.css +0 -32
|
@@ -168,6 +168,46 @@ let LocalStorageService = class LocalStorageService {
|
|
|
168
168
|
}
|
|
169
169
|
return normalized;
|
|
170
170
|
}
|
|
171
|
+
normalizeLocalSkillSourceFolderPath(folderPath) {
|
|
172
|
+
const normalized = folderPath.trim();
|
|
173
|
+
if (!normalized) {
|
|
174
|
+
throw new error_types_1.ValidationError('folderPath is required.', { fieldName: 'folderPath' });
|
|
175
|
+
}
|
|
176
|
+
return normalized;
|
|
177
|
+
}
|
|
178
|
+
async assertLocalSourceNameAvailableAcrossTypes(sourceName) {
|
|
179
|
+
if (RESERVED_COMMUNITY_SOURCE_NAMES.has(sourceName)) {
|
|
180
|
+
throw new error_types_1.ValidationError('Local source name conflicts with a built-in source.', {
|
|
181
|
+
name: sourceName,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
const { communitySkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
185
|
+
const { eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
186
|
+
const existingCommunitySource = await this.db
|
|
187
|
+
.select({ id: communitySkillSources.id })
|
|
188
|
+
.from(communitySkillSources)
|
|
189
|
+
.where(eq(communitySkillSources.name, sourceName))
|
|
190
|
+
.limit(1);
|
|
191
|
+
if (existingCommunitySource.length > 0) {
|
|
192
|
+
throw new error_types_1.ConflictError('Local source name conflicts with an existing community source.', {
|
|
193
|
+
name: sourceName,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
normalizeProjectIdForSourceEnablement(projectId) {
|
|
198
|
+
const normalized = projectId.trim();
|
|
199
|
+
if (!normalized) {
|
|
200
|
+
throw new error_types_1.ValidationError('projectId is required.', { fieldName: 'projectId' });
|
|
201
|
+
}
|
|
202
|
+
return normalized;
|
|
203
|
+
}
|
|
204
|
+
normalizeSourceNameForSourceEnablement(sourceName) {
|
|
205
|
+
const normalized = sourceName.trim().toLowerCase();
|
|
206
|
+
if (!normalized) {
|
|
207
|
+
throw new error_types_1.ValidationError('sourceName is required.', { fieldName: 'sourceName' });
|
|
208
|
+
}
|
|
209
|
+
return normalized;
|
|
210
|
+
}
|
|
171
211
|
isSqliteUniqueConstraint(error) {
|
|
172
212
|
if (typeof error !== 'object' || error === null) {
|
|
173
213
|
return false;
|
|
@@ -246,6 +286,39 @@ let LocalStorageService = class LocalStorageService {
|
|
|
246
286
|
});
|
|
247
287
|
}
|
|
248
288
|
}
|
|
289
|
+
async listSeedableSourceNamesForNewProject() {
|
|
290
|
+
const { communitySkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
291
|
+
const communitySourceRows = await this.db
|
|
292
|
+
.select({ name: communitySkillSources.name })
|
|
293
|
+
.from(communitySkillSources);
|
|
294
|
+
const sourceNames = communitySourceRows
|
|
295
|
+
.map((row) => row.name.trim().toLowerCase())
|
|
296
|
+
.filter((name) => name.length > 0);
|
|
297
|
+
const sqlite = (0, sqlite_raw_1.getRawSqliteClient)(this.db);
|
|
298
|
+
if (sqlite && typeof sqlite.prepare === 'function') {
|
|
299
|
+
try {
|
|
300
|
+
const localRows = sqlite.prepare('SELECT name FROM local_skill_sources').all();
|
|
301
|
+
for (const row of localRows) {
|
|
302
|
+
if (typeof row.name !== 'string') {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const normalized = row.name.trim().toLowerCase();
|
|
306
|
+
if (normalized.length > 0) {
|
|
307
|
+
sourceNames.push(normalized);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
313
|
+
if (!message.includes('no such table: local_skill_sources')) {
|
|
314
|
+
throw new error_types_1.StorageError('Failed to list local skill sources for project source seeding.', {
|
|
315
|
+
cause: message,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return [...new Set(sourceNames)];
|
|
321
|
+
}
|
|
249
322
|
async createProject(data) {
|
|
250
323
|
const { randomUUID } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
251
324
|
const now = new Date().toISOString();
|
|
@@ -256,7 +329,8 @@ let LocalStorageService = class LocalStorageService {
|
|
|
256
329
|
createdAt: now,
|
|
257
330
|
updatedAt: now,
|
|
258
331
|
};
|
|
259
|
-
const
|
|
332
|
+
const seedableSourceNames = await this.listSeedableSourceNamesForNewProject();
|
|
333
|
+
const { projects, statuses, sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
260
334
|
await this.db.transaction(async (tx) => {
|
|
261
335
|
await tx.insert(projects).values({
|
|
262
336
|
id: project.id,
|
|
@@ -285,6 +359,15 @@ let LocalStorageService = class LocalStorageService {
|
|
|
285
359
|
updatedAt: now,
|
|
286
360
|
});
|
|
287
361
|
}
|
|
362
|
+
if (seedableSourceNames.length > 0) {
|
|
363
|
+
await tx.insert(sourceProjectEnabled).values(seedableSourceNames.map((sourceName) => ({
|
|
364
|
+
id: randomUUID(),
|
|
365
|
+
projectId: project.id,
|
|
366
|
+
sourceName,
|
|
367
|
+
enabled: false,
|
|
368
|
+
createdAt: now,
|
|
369
|
+
})));
|
|
370
|
+
}
|
|
288
371
|
});
|
|
289
372
|
logger.info({ projectId: project.id }, 'Created project with default statuses (transactional)');
|
|
290
373
|
return project;
|
|
@@ -299,7 +382,8 @@ let LocalStorageService = class LocalStorageService {
|
|
|
299
382
|
createdAt: now,
|
|
300
383
|
updatedAt: now,
|
|
301
384
|
};
|
|
302
|
-
const
|
|
385
|
+
const seedableSourceNames = await this.listSeedableSourceNamesForNewProject();
|
|
386
|
+
const { projects, statuses, prompts, agentProfiles, agents, tags, promptTags, profileProviderConfigs, providers, sourceProjectEnabled, } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
303
387
|
const statusIdMap = {};
|
|
304
388
|
const promptIdMap = {};
|
|
305
389
|
const profileIdMap = {};
|
|
@@ -336,6 +420,15 @@ let LocalStorageService = class LocalStorageService {
|
|
|
336
420
|
if (s.id)
|
|
337
421
|
statusIdMap[s.id] = statusId;
|
|
338
422
|
}
|
|
423
|
+
if (seedableSourceNames.length > 0) {
|
|
424
|
+
await this.db.insert(sourceProjectEnabled).values(seedableSourceNames.map((sourceName) => ({
|
|
425
|
+
id: randomUUID(),
|
|
426
|
+
projectId: project.id,
|
|
427
|
+
sourceName,
|
|
428
|
+
enabled: false,
|
|
429
|
+
createdAt: now,
|
|
430
|
+
})));
|
|
431
|
+
}
|
|
339
432
|
const { eq, and, or, isNull } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
340
433
|
for (const p of template.prompts) {
|
|
341
434
|
const promptId = randomUUID();
|
|
@@ -1960,6 +2053,114 @@ let LocalStorageService = class LocalStorageService {
|
|
|
1960
2053
|
}
|
|
1961
2054
|
return this.updateProvider(id, update);
|
|
1962
2055
|
}
|
|
2056
|
+
async getSourceProjectEnabled(projectId, sourceName) {
|
|
2057
|
+
const normalizedProjectId = this.normalizeProjectIdForSourceEnablement(projectId);
|
|
2058
|
+
const normalizedSourceName = this.normalizeSourceNameForSourceEnablement(sourceName);
|
|
2059
|
+
const { sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2060
|
+
const { and, eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2061
|
+
const rows = await this.db
|
|
2062
|
+
.select({ enabled: sourceProjectEnabled.enabled })
|
|
2063
|
+
.from(sourceProjectEnabled)
|
|
2064
|
+
.where(and(eq(sourceProjectEnabled.projectId, normalizedProjectId), eq(sourceProjectEnabled.sourceName, normalizedSourceName)))
|
|
2065
|
+
.limit(1);
|
|
2066
|
+
return rows[0] ? Boolean(rows[0].enabled) : null;
|
|
2067
|
+
}
|
|
2068
|
+
async setSourceProjectEnabled(projectId, sourceName, enabled) {
|
|
2069
|
+
const normalizedProjectId = this.normalizeProjectIdForSourceEnablement(projectId);
|
|
2070
|
+
const normalizedSourceName = this.normalizeSourceNameForSourceEnablement(sourceName);
|
|
2071
|
+
const { sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2072
|
+
const { and, eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2073
|
+
const existing = await this.db
|
|
2074
|
+
.select({ id: sourceProjectEnabled.id })
|
|
2075
|
+
.from(sourceProjectEnabled)
|
|
2076
|
+
.where(and(eq(sourceProjectEnabled.projectId, normalizedProjectId), eq(sourceProjectEnabled.sourceName, normalizedSourceName)))
|
|
2077
|
+
.limit(1);
|
|
2078
|
+
if (existing[0]) {
|
|
2079
|
+
await this.db
|
|
2080
|
+
.update(sourceProjectEnabled)
|
|
2081
|
+
.set({ enabled })
|
|
2082
|
+
.where(eq(sourceProjectEnabled.id, existing[0].id));
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
const { randomUUID } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
2086
|
+
await this.db.insert(sourceProjectEnabled).values({
|
|
2087
|
+
id: randomUUID(),
|
|
2088
|
+
projectId: normalizedProjectId,
|
|
2089
|
+
sourceName: normalizedSourceName,
|
|
2090
|
+
enabled,
|
|
2091
|
+
createdAt: new Date().toISOString(),
|
|
2092
|
+
});
|
|
2093
|
+
}
|
|
2094
|
+
async listSourceProjectEnabled(projectId) {
|
|
2095
|
+
const normalizedProjectId = this.normalizeProjectIdForSourceEnablement(projectId);
|
|
2096
|
+
const { sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2097
|
+
const { asc, eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2098
|
+
const rows = await this.db
|
|
2099
|
+
.select({
|
|
2100
|
+
sourceName: sourceProjectEnabled.sourceName,
|
|
2101
|
+
enabled: sourceProjectEnabled.enabled,
|
|
2102
|
+
})
|
|
2103
|
+
.from(sourceProjectEnabled)
|
|
2104
|
+
.where(eq(sourceProjectEnabled.projectId, normalizedProjectId))
|
|
2105
|
+
.orderBy(asc(sourceProjectEnabled.sourceName));
|
|
2106
|
+
return rows.map((row) => ({
|
|
2107
|
+
sourceName: row.sourceName,
|
|
2108
|
+
enabled: Boolean(row.enabled),
|
|
2109
|
+
}));
|
|
2110
|
+
}
|
|
2111
|
+
async seedSourceProjectDisabled(projectId, sourceNames) {
|
|
2112
|
+
const normalizedProjectId = this.normalizeProjectIdForSourceEnablement(projectId);
|
|
2113
|
+
const normalizedSourceNames = [
|
|
2114
|
+
...new Set(sourceNames.map((name) => name.trim().toLowerCase())),
|
|
2115
|
+
].filter((name) => name.length > 0);
|
|
2116
|
+
if (normalizedSourceNames.length === 0) {
|
|
2117
|
+
return;
|
|
2118
|
+
}
|
|
2119
|
+
const sqlite = (0, sqlite_raw_1.getRawSqliteClient)(this.db);
|
|
2120
|
+
if (!sqlite || typeof sqlite.exec !== 'function') {
|
|
2121
|
+
throw new error_types_1.StorageError('Unable to access underlying SQLite client');
|
|
2122
|
+
}
|
|
2123
|
+
sqlite.exec('BEGIN IMMEDIATE TRANSACTION');
|
|
2124
|
+
try {
|
|
2125
|
+
const { sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2126
|
+
const { and, eq, inArray } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2127
|
+
const existingRows = await this.db
|
|
2128
|
+
.select({ sourceName: sourceProjectEnabled.sourceName })
|
|
2129
|
+
.from(sourceProjectEnabled)
|
|
2130
|
+
.where(and(eq(sourceProjectEnabled.projectId, normalizedProjectId), inArray(sourceProjectEnabled.sourceName, normalizedSourceNames)));
|
|
2131
|
+
const existingSourceNames = new Set(existingRows.map((row) => row.sourceName));
|
|
2132
|
+
const sourceNamesToInsert = normalizedSourceNames.filter((sourceName) => !existingSourceNames.has(sourceName));
|
|
2133
|
+
if (sourceNamesToInsert.length > 0) {
|
|
2134
|
+
const { randomUUID } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
2135
|
+
const now = new Date().toISOString();
|
|
2136
|
+
await this.db.insert(sourceProjectEnabled).values(sourceNamesToInsert.map((sourceName) => ({
|
|
2137
|
+
id: randomUUID(),
|
|
2138
|
+
projectId: normalizedProjectId,
|
|
2139
|
+
sourceName,
|
|
2140
|
+
enabled: false,
|
|
2141
|
+
createdAt: now,
|
|
2142
|
+
})));
|
|
2143
|
+
}
|
|
2144
|
+
sqlite.exec('COMMIT');
|
|
2145
|
+
}
|
|
2146
|
+
catch (error) {
|
|
2147
|
+
try {
|
|
2148
|
+
sqlite.exec('ROLLBACK');
|
|
2149
|
+
}
|
|
2150
|
+
catch (rollbackError) {
|
|
2151
|
+
logger.error({ rollbackError }, 'Failed to rollback seedSourceProjectDisabled transaction');
|
|
2152
|
+
}
|
|
2153
|
+
throw error;
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
async deleteSourceProjectEnabledBySource(sourceName) {
|
|
2157
|
+
const normalizedSourceName = this.normalizeSourceNameForSourceEnablement(sourceName);
|
|
2158
|
+
const { sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2159
|
+
const { eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2160
|
+
await this.db
|
|
2161
|
+
.delete(sourceProjectEnabled)
|
|
2162
|
+
.where(eq(sourceProjectEnabled.sourceName, normalizedSourceName));
|
|
2163
|
+
}
|
|
1963
2164
|
async listCommunitySkillSources() {
|
|
1964
2165
|
const { communitySkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
1965
2166
|
const { asc } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
@@ -2052,14 +2253,104 @@ let LocalStorageService = class LocalStorageService {
|
|
|
2052
2253
|
}
|
|
2053
2254
|
async deleteCommunitySkillSource(id) {
|
|
2054
2255
|
const source = await this.getCommunitySkillSource(id);
|
|
2055
|
-
const { communitySkillSources, skills } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2256
|
+
const { communitySkillSources, skills, sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2056
2257
|
const { eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2057
2258
|
await this.db.transaction(async (tx) => {
|
|
2058
2259
|
await tx.delete(skills).where(eq(skills.source, source.name));
|
|
2260
|
+
await tx.delete(sourceProjectEnabled).where(eq(sourceProjectEnabled.sourceName, source.name));
|
|
2059
2261
|
await tx.delete(communitySkillSources).where(eq(communitySkillSources.id, source.id));
|
|
2060
2262
|
});
|
|
2061
2263
|
logger.info({ communitySkillSourceId: source.id, sourceName: source.name }, 'Deleted community skill source and related skills');
|
|
2062
2264
|
}
|
|
2265
|
+
async listLocalSkillSources() {
|
|
2266
|
+
const { localSkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2267
|
+
const { asc } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2268
|
+
const rows = await this.db
|
|
2269
|
+
.select()
|
|
2270
|
+
.from(localSkillSources)
|
|
2271
|
+
.orderBy(asc(localSkillSources.name));
|
|
2272
|
+
return rows;
|
|
2273
|
+
}
|
|
2274
|
+
async getLocalSkillSource(id) {
|
|
2275
|
+
const normalizedId = id.trim();
|
|
2276
|
+
if (!normalizedId) {
|
|
2277
|
+
throw new error_types_1.ValidationError('id is required.', { fieldName: 'id' });
|
|
2278
|
+
}
|
|
2279
|
+
const { localSkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2280
|
+
const { eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2281
|
+
const rows = await this.db
|
|
2282
|
+
.select()
|
|
2283
|
+
.from(localSkillSources)
|
|
2284
|
+
.where(eq(localSkillSources.id, normalizedId))
|
|
2285
|
+
.limit(1);
|
|
2286
|
+
return rows[0] ?? null;
|
|
2287
|
+
}
|
|
2288
|
+
async createLocalSkillSource(data) {
|
|
2289
|
+
const normalizedName = this.normalizeCommunitySourceNameForLookup(data.name);
|
|
2290
|
+
const normalizedFolderPath = this.normalizeLocalSkillSourceFolderPath(data.folderPath);
|
|
2291
|
+
await this.assertLocalSourceNameAvailableAcrossTypes(normalizedName);
|
|
2292
|
+
const { randomUUID } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
2293
|
+
const now = new Date().toISOString();
|
|
2294
|
+
const record = {
|
|
2295
|
+
id: randomUUID(),
|
|
2296
|
+
name: normalizedName,
|
|
2297
|
+
folderPath: normalizedFolderPath,
|
|
2298
|
+
createdAt: now,
|
|
2299
|
+
updatedAt: now,
|
|
2300
|
+
};
|
|
2301
|
+
const { localSkillSources } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2302
|
+
try {
|
|
2303
|
+
await this.db.insert(localSkillSources).values({
|
|
2304
|
+
id: record.id,
|
|
2305
|
+
name: record.name,
|
|
2306
|
+
folderPath: record.folderPath,
|
|
2307
|
+
createdAt: record.createdAt,
|
|
2308
|
+
updatedAt: record.updatedAt,
|
|
2309
|
+
});
|
|
2310
|
+
}
|
|
2311
|
+
catch (error) {
|
|
2312
|
+
if (this.isSqliteUniqueConstraint(error)) {
|
|
2313
|
+
const rawMessage = typeof error === 'object' && error !== null && 'message' in error
|
|
2314
|
+
? String(error.message ?? '')
|
|
2315
|
+
: '';
|
|
2316
|
+
if (rawMessage.includes('local_skill_sources.name')) {
|
|
2317
|
+
throw new error_types_1.ConflictError('Local skill source name already exists.', {
|
|
2318
|
+
name: normalizedName,
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
if (rawMessage.includes('local_skill_sources.folder_path')) {
|
|
2322
|
+
throw new error_types_1.ConflictError('Local skill source folder path already exists.', {
|
|
2323
|
+
folderPath: normalizedFolderPath,
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
throw new error_types_1.ConflictError('Local skill source already exists.', {
|
|
2327
|
+
name: normalizedName,
|
|
2328
|
+
folderPath: normalizedFolderPath,
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2331
|
+
throw new error_types_1.StorageError('Failed to create local skill source.', {
|
|
2332
|
+
name: normalizedName,
|
|
2333
|
+
folderPath: normalizedFolderPath,
|
|
2334
|
+
cause: error instanceof Error ? error.message : String(error),
|
|
2335
|
+
});
|
|
2336
|
+
}
|
|
2337
|
+
logger.info({ localSkillSourceId: record.id, name: record.name }, 'Created local skill source');
|
|
2338
|
+
return record;
|
|
2339
|
+
}
|
|
2340
|
+
async deleteLocalSkillSource(id) {
|
|
2341
|
+
const source = await this.getLocalSkillSource(id);
|
|
2342
|
+
if (!source) {
|
|
2343
|
+
throw new error_types_1.NotFoundError('Local skill source', id.trim());
|
|
2344
|
+
}
|
|
2345
|
+
const { localSkillSources, skills, sourceProjectEnabled } = await Promise.resolve().then(() => __importStar(require('../db/schema')));
|
|
2346
|
+
const { eq } = await Promise.resolve().then(() => __importStar(require('drizzle-orm')));
|
|
2347
|
+
await this.db.transaction(async (tx) => {
|
|
2348
|
+
await tx.delete(skills).where(eq(skills.source, source.name));
|
|
2349
|
+
await tx.delete(sourceProjectEnabled).where(eq(sourceProjectEnabled.sourceName, source.name));
|
|
2350
|
+
await tx.delete(localSkillSources).where(eq(localSkillSources.id, source.id));
|
|
2351
|
+
});
|
|
2352
|
+
logger.info({ localSkillSourceId: source.id, sourceName: source.name }, 'Deleted local skill source and related skills');
|
|
2353
|
+
}
|
|
2063
2354
|
async createAgentProfile(data) {
|
|
2064
2355
|
const { randomUUID } = await Promise.resolve().then(() => __importStar(require('crypto')));
|
|
2065
2356
|
const now = new Date().toISOString();
|