devchain-cli 0.9.0 → 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.
Files changed (80) hide show
  1. package/dist/drizzle/0041_community_skill_sources.sql +12 -0
  2. package/dist/drizzle/0042_nice_flatman.sql +10 -0
  3. package/dist/drizzle/0043_majestic_starhawk.sql +10 -0
  4. package/dist/drizzle/meta/0041_snapshot.json +4102 -0
  5. package/dist/drizzle/meta/0042_snapshot.json +4171 -0
  6. package/dist/drizzle/meta/0043_snapshot.json +4231 -0
  7. package/dist/drizzle/meta/_journal.json +21 -0
  8. package/dist/server/modules/seeders/seeders/0003_seed_preseed_jeffallan_claude_skills.d.ts +3 -0
  9. package/dist/server/modules/seeders/seeders/0003_seed_preseed_jeffallan_claude_skills.js +41 -0
  10. package/dist/server/modules/seeders/seeders/0003_seed_preseed_jeffallan_claude_skills.js.map +1 -0
  11. package/dist/server/modules/seeders/seeders/0004_seed_disable_microsoft_source_default.d.ts +3 -0
  12. package/dist/server/modules/seeders/seeders/0004_seed_disable_microsoft_source_default.js +48 -0
  13. package/dist/server/modules/seeders/seeders/0004_seed_disable_microsoft_source_default.js.map +1 -0
  14. package/dist/server/modules/seeders/services/data-seeder.service.js +4 -0
  15. package/dist/server/modules/seeders/services/data-seeder.service.js.map +1 -1
  16. package/dist/server/modules/skills/adapters/community-skill-source.adapter.d.ts +11 -0
  17. package/dist/server/modules/skills/adapters/community-skill-source.adapter.js +181 -0
  18. package/dist/server/modules/skills/adapters/community-skill-source.adapter.js.map +1 -0
  19. package/dist/server/modules/skills/adapters/github-skill-source.base.d.ts +2 -5
  20. package/dist/server/modules/skills/adapters/github-skill-source.base.js +31 -100
  21. package/dist/server/modules/skills/adapters/github-skill-source.base.js.map +1 -1
  22. package/dist/server/modules/skills/adapters/local-skill-source.adapter.d.ts +16 -0
  23. package/dist/server/modules/skills/adapters/local-skill-source.adapter.js +265 -0
  24. package/dist/server/modules/skills/adapters/local-skill-source.adapter.js.map +1 -0
  25. package/dist/server/modules/skills/adapters/skill-parsing.utils.d.ts +32 -0
  26. package/dist/server/modules/skills/adapters/skill-parsing.utils.js +169 -0
  27. package/dist/server/modules/skills/adapters/skill-parsing.utils.js.map +1 -0
  28. package/dist/server/modules/skills/controllers/community-sources.controller.d.ts +12 -0
  29. package/dist/server/modules/skills/controllers/community-sources.controller.js +71 -0
  30. package/dist/server/modules/skills/controllers/community-sources.controller.js.map +1 -0
  31. package/dist/server/modules/skills/controllers/local-sources.controller.d.ts +12 -0
  32. package/dist/server/modules/skills/controllers/local-sources.controller.js +71 -0
  33. package/dist/server/modules/skills/controllers/local-sources.controller.js.map +1 -0
  34. package/dist/server/modules/skills/controllers/skills.controller.d.ts +11 -1
  35. package/dist/server/modules/skills/controllers/skills.controller.js +35 -3
  36. package/dist/server/modules/skills/controllers/skills.controller.js.map +1 -1
  37. package/dist/server/modules/skills/dtos/community-sources.dto.d.ts +100 -0
  38. package/dist/server/modules/skills/dtos/community-sources.dto.js +138 -0
  39. package/dist/server/modules/skills/dtos/community-sources.dto.js.map +1 -0
  40. package/dist/server/modules/skills/dtos/local-sources.dto.d.ts +42 -0
  41. package/dist/server/modules/skills/dtos/local-sources.dto.js +30 -0
  42. package/dist/server/modules/skills/dtos/local-sources.dto.js.map +1 -0
  43. package/dist/server/modules/skills/dtos/skill.dto.d.ts +16 -0
  44. package/dist/server/modules/skills/dtos/skill.dto.js +7 -1
  45. package/dist/server/modules/skills/dtos/skill.dto.js.map +1 -1
  46. package/dist/server/modules/skills/services/community-sources.service.d.ts +18 -0
  47. package/dist/server/modules/skills/services/community-sources.service.js +158 -0
  48. package/dist/server/modules/skills/services/community-sources.service.js.map +1 -0
  49. package/dist/server/modules/skills/services/local-sources.service.d.ts +20 -0
  50. package/dist/server/modules/skills/services/local-sources.service.js +206 -0
  51. package/dist/server/modules/skills/services/local-sources.service.js.map +1 -0
  52. package/dist/server/modules/skills/services/skill-source-registry.service.d.ts +20 -0
  53. package/dist/server/modules/skills/services/skill-source-registry.service.js +142 -0
  54. package/dist/server/modules/skills/services/skill-source-registry.service.js.map +1 -0
  55. package/dist/server/modules/skills/services/skill-sync.service.d.ts +7 -3
  56. package/dist/server/modules/skills/services/skill-sync.service.js +102 -11
  57. package/dist/server/modules/skills/services/skill-sync.service.js.map +1 -1
  58. package/dist/server/modules/skills/services/skills.service.d.ts +16 -4
  59. package/dist/server/modules/skills/services/skills.service.js +141 -36
  60. package/dist/server/modules/skills/services/skills.service.js.map +1 -1
  61. package/dist/server/modules/skills/skills.module.js +10 -1
  62. package/dist/server/modules/skills/skills.module.js.map +1 -1
  63. package/dist/server/modules/storage/db/schema.d.ts +342 -0
  64. package/dist/server/modules/storage/db/schema.js +30 -1
  65. package/dist/server/modules/storage/db/schema.js.map +1 -1
  66. package/dist/server/modules/storage/interfaces/storage.interface.d.ts +18 -1
  67. package/dist/server/modules/storage/interfaces/storage.interface.js.map +1 -1
  68. package/dist/server/modules/storage/local/local-storage.service.d.ts +28 -1
  69. package/dist/server/modules/storage/local/local-storage.service.js +452 -2
  70. package/dist/server/modules/storage/local/local-storage.service.js.map +1 -1
  71. package/dist/server/modules/storage/models/domain.models.d.ts +20 -0
  72. package/dist/server/tsconfig.tsbuildinfo +1 -1
  73. package/dist/server/ui/assets/{ReviewDetailPage-D_-bS1MK.js → ReviewDetailPage-BvSckWKj.js} +1 -1
  74. package/dist/server/ui/assets/{ReviewsPage-BE1gxYlC.js → ReviewsPage-MKT-vv59.js} +1 -1
  75. package/dist/server/ui/assets/index-BtUq-Qxb.css +32 -0
  76. package/dist/server/ui/assets/{index-C094CE5I.js → index-kTb634Zp.js} +197 -197
  77. package/dist/server/ui/assets/{useReviewSubscription-Bs-17h-m.js → useReviewSubscription-Dc58i6Bk.js} +1 -1
  78. package/dist/server/ui/index.html +2 -2
  79. package/package.json +8 -1
  80. package/dist/server/ui/assets/index-CbtpBUHu.css +0 -32
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.CommunitySourcesService = void 0;
49
+ const common_1 = require("@nestjs/common");
50
+ const node_os_1 = require("node:os");
51
+ const node_path_1 = require("node:path");
52
+ const fs = __importStar(require("node:fs/promises"));
53
+ const error_types_1 = require("../../../common/errors/error-types");
54
+ const logger_1 = require("../../../common/logging/logger");
55
+ const storage_interface_1 = require("../../storage/interfaces/storage.interface");
56
+ const skill_sync_service_1 = require("./skill-sync.service");
57
+ const skills_service_1 = require("./skills.service");
58
+ const logger = (0, logger_1.createLogger)('CommunitySourcesService');
59
+ let CommunitySourcesService = class CommunitySourcesService {
60
+ constructor(storage, skillsService, skillSyncService) {
61
+ this.storage = storage;
62
+ this.skillsService = skillsService;
63
+ this.skillSyncService = skillSyncService;
64
+ }
65
+ async listCommunitySources() {
66
+ return this.storage.listCommunitySkillSources();
67
+ }
68
+ async createCommunitySource(data) {
69
+ await this.validateSourceName(data.name);
70
+ const source = await this.storage.createCommunitySkillSource({
71
+ name: data.name,
72
+ repoOwner: data.repoOwner,
73
+ repoName: data.repoName,
74
+ branch: data.branch,
75
+ });
76
+ const projectIds = await this.listAllProjectIds();
77
+ for (const projectId of projectIds) {
78
+ await this.storage.seedSourceProjectDisabled(projectId, [source.name]);
79
+ }
80
+ await this.syncSourceAfterCreate(source.name);
81
+ return source;
82
+ }
83
+ async deleteCommunitySource(id) {
84
+ const source = await this.storage.getCommunitySkillSource(id);
85
+ await this.storage.deleteCommunitySkillSource(id);
86
+ await this.deleteSourceSkillsDirectory(source.name);
87
+ }
88
+ async deleteSourceSkillsDirectory(sourceName) {
89
+ const normalizedSourceName = sourceName.trim().toLowerCase();
90
+ const sourcePath = (0, node_path_1.join)((0, node_os_1.homedir)(), '.devchain', 'skills', normalizedSourceName);
91
+ try {
92
+ await fs.rm(sourcePath, { recursive: true, force: true });
93
+ }
94
+ catch (error) {
95
+ throw new error_types_1.StorageError('Failed to delete community source local skills directory.', {
96
+ sourceName: normalizedSourceName,
97
+ sourcePath,
98
+ cause: error instanceof Error ? error.message : String(error),
99
+ });
100
+ }
101
+ logger.info({ sourceName: normalizedSourceName, sourcePath }, 'Deleted local skills directory for community source');
102
+ }
103
+ async validateSourceName(name) {
104
+ const normalizedName = name.trim().toLowerCase();
105
+ const reservedNames = new Set(this.skillsService.getReservedSourceNames());
106
+ if (reservedNames.has(normalizedName)) {
107
+ throw new error_types_1.ValidationError('Source name is reserved by a built-in skill source.', {
108
+ name: normalizedName,
109
+ });
110
+ }
111
+ const localSourceNames = new Set((await this.storage.listLocalSkillSources()).map((source) => source.name.trim().toLowerCase()));
112
+ if (localSourceNames.has(normalizedName)) {
113
+ throw new error_types_1.ValidationError('Source name is already used by a local skill source.', {
114
+ name: normalizedName,
115
+ });
116
+ }
117
+ }
118
+ async listAllProjectIds() {
119
+ const projectIds = [];
120
+ const limit = 200;
121
+ let offset = 0;
122
+ while (true) {
123
+ const page = await this.storage.listProjects({ limit, offset });
124
+ projectIds.push(...page.items.map((project) => project.id));
125
+ offset += page.items.length;
126
+ if (page.items.length === 0 || offset >= page.total) {
127
+ break;
128
+ }
129
+ }
130
+ return projectIds;
131
+ }
132
+ async syncSourceAfterCreate(sourceName) {
133
+ try {
134
+ const syncResult = await this.skillSyncService.syncSource(sourceName);
135
+ if (syncResult.failed > 0) {
136
+ logger.warn({
137
+ sourceName,
138
+ failed: syncResult.failed,
139
+ errors: syncResult.errors,
140
+ }, 'Initial community source sync completed with errors');
141
+ }
142
+ }
143
+ catch (error) {
144
+ logger.warn({
145
+ sourceName,
146
+ error: error instanceof Error ? error.message : String(error),
147
+ }, 'Initial community source sync failed after source creation');
148
+ }
149
+ }
150
+ };
151
+ exports.CommunitySourcesService = CommunitySourcesService;
152
+ exports.CommunitySourcesService = CommunitySourcesService = __decorate([
153
+ (0, common_1.Injectable)(),
154
+ __param(0, (0, common_1.Inject)(storage_interface_1.STORAGE_SERVICE)),
155
+ __metadata("design:paramtypes", [Object, skills_service_1.SkillsService,
156
+ skill_sync_service_1.SkillSyncService])
157
+ ], CommunitySourcesService);
158
+ //# sourceMappingURL=community-sources.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"community-sources.service.js","sourceRoot":"","sources":["../../../../src/modules/skills/services/community-sources.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { LocalSkillSource } from '../../storage/models/domain.models';
2
+ import { type StorageService } from '../../storage/interfaces/storage.interface';
3
+ import type { CreateLocalSourceDto } from '../dtos/local-sources.dto';
4
+ import { SkillSyncService } from './skill-sync.service';
5
+ import { SkillsService } from './skills.service';
6
+ export declare class LocalSourcesService {
7
+ private readonly storage;
8
+ private readonly skillsService;
9
+ private readonly skillSyncService;
10
+ constructor(storage: StorageService, skillsService: SkillsService, skillSyncService: SkillSyncService);
11
+ listLocalSources(): Promise<LocalSkillSource[]>;
12
+ createLocalSource(data: CreateLocalSourceDto): Promise<LocalSkillSource>;
13
+ deleteLocalSource(id: string): Promise<void>;
14
+ private validateSourceName;
15
+ private validateAndNormalizeFolderPath;
16
+ private ensureReadableDirectory;
17
+ private deleteSourceSkillsDirectory;
18
+ private listAllProjectIds;
19
+ private syncSourceAfterCreate;
20
+ }
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
45
+ return function (target, key) { decorator(target, key, paramIndex); }
46
+ };
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.LocalSourcesService = void 0;
49
+ const common_1 = require("@nestjs/common");
50
+ const node_fs_1 = require("node:fs");
51
+ const fs = __importStar(require("node:fs/promises"));
52
+ const node_os_1 = require("node:os");
53
+ const node_path_1 = require("node:path");
54
+ const error_types_1 = require("../../../common/errors/error-types");
55
+ const logger_1 = require("../../../common/logging/logger");
56
+ const storage_interface_1 = require("../../storage/interfaces/storage.interface");
57
+ const skill_sync_service_1 = require("./skill-sync.service");
58
+ const skills_service_1 = require("./skills.service");
59
+ const logger = (0, logger_1.createLogger)('LocalSourcesService');
60
+ let LocalSourcesService = class LocalSourcesService {
61
+ constructor(storage, skillsService, skillSyncService) {
62
+ this.storage = storage;
63
+ this.skillsService = skillsService;
64
+ this.skillSyncService = skillSyncService;
65
+ }
66
+ async listLocalSources() {
67
+ return this.storage.listLocalSkillSources();
68
+ }
69
+ async createLocalSource(data) {
70
+ this.validateSourceName(data.name);
71
+ const normalizedFolderPath = await this.validateAndNormalizeFolderPath(data.folderPath);
72
+ const source = await this.storage.createLocalSkillSource({
73
+ name: data.name,
74
+ folderPath: normalizedFolderPath,
75
+ });
76
+ const projectIds = await this.listAllProjectIds();
77
+ for (const projectId of projectIds) {
78
+ await this.storage.seedSourceProjectDisabled(projectId, [source.name]);
79
+ }
80
+ await this.syncSourceAfterCreate(source.name);
81
+ return source;
82
+ }
83
+ async deleteLocalSource(id) {
84
+ const source = await this.storage.getLocalSkillSource(id);
85
+ if (!source) {
86
+ throw new error_types_1.NotFoundError('Local skill source', id);
87
+ }
88
+ await this.storage.deleteLocalSkillSource(id);
89
+ await this.deleteSourceSkillsDirectory(source.name);
90
+ }
91
+ validateSourceName(name) {
92
+ const normalizedName = name.trim().toLowerCase();
93
+ const reservedNames = new Set(this.skillsService.getReservedSourceNames());
94
+ if (reservedNames.has(normalizedName)) {
95
+ throw new error_types_1.ValidationError('Source name is reserved by a built-in skill source.', {
96
+ name: normalizedName,
97
+ });
98
+ }
99
+ }
100
+ async validateAndNormalizeFolderPath(folderPath) {
101
+ const trimmedPath = folderPath.trim();
102
+ if (!trimmedPath) {
103
+ throw new error_types_1.ValidationError('folderPath is required.', { fieldName: 'folderPath' });
104
+ }
105
+ if (!(0, node_path_1.isAbsolute)(trimmedPath)) {
106
+ throw new error_types_1.ValidationError('folderPath must be an absolute path.', {
107
+ fieldName: 'folderPath',
108
+ folderPath: trimmedPath,
109
+ });
110
+ }
111
+ const normalizedPath = (0, node_path_1.resolve)(trimmedPath);
112
+ await this.ensureReadableDirectory(normalizedPath, 'folderPath');
113
+ await this.ensureReadableDirectory((0, node_path_1.join)(normalizedPath, 'skills'), 'skillsPath');
114
+ return normalizedPath;
115
+ }
116
+ async ensureReadableDirectory(pathValue, fieldName) {
117
+ let stats;
118
+ try {
119
+ stats = await fs.stat(pathValue);
120
+ }
121
+ catch (error) {
122
+ if (error.code === 'ENOENT') {
123
+ throw new error_types_1.ValidationError(`${fieldName} does not exist.`, {
124
+ fieldName,
125
+ path: pathValue,
126
+ });
127
+ }
128
+ throw new error_types_1.StorageError(`Failed to validate ${fieldName}.`, {
129
+ fieldName,
130
+ path: pathValue,
131
+ cause: error instanceof Error ? error.message : String(error),
132
+ });
133
+ }
134
+ if (!stats.isDirectory()) {
135
+ throw new error_types_1.ValidationError(`${fieldName} must be a directory.`, {
136
+ fieldName,
137
+ path: pathValue,
138
+ });
139
+ }
140
+ try {
141
+ await fs.access(pathValue, node_fs_1.constants.R_OK);
142
+ }
143
+ catch (error) {
144
+ throw new error_types_1.ValidationError(`${fieldName} is not readable.`, {
145
+ fieldName,
146
+ path: pathValue,
147
+ cause: error instanceof Error ? error.message : String(error),
148
+ });
149
+ }
150
+ }
151
+ async deleteSourceSkillsDirectory(sourceName) {
152
+ const normalizedSourceName = sourceName.trim().toLowerCase();
153
+ const sourcePath = (0, node_path_1.join)((0, node_os_1.homedir)(), '.devchain', 'skills', normalizedSourceName);
154
+ try {
155
+ await fs.rm(sourcePath, { recursive: true, force: true });
156
+ }
157
+ catch (error) {
158
+ throw new error_types_1.StorageError('Failed to delete local source synced skills directory.', {
159
+ sourceName: normalizedSourceName,
160
+ sourcePath,
161
+ cause: error instanceof Error ? error.message : String(error),
162
+ });
163
+ }
164
+ logger.info({ sourceName: normalizedSourceName, sourcePath }, 'Deleted synced skills directory for local source');
165
+ }
166
+ async listAllProjectIds() {
167
+ const projectIds = [];
168
+ const limit = 200;
169
+ let offset = 0;
170
+ while (true) {
171
+ const page = await this.storage.listProjects({ limit, offset });
172
+ projectIds.push(...page.items.map((project) => project.id));
173
+ offset += page.items.length;
174
+ if (page.items.length === 0 || offset >= page.total) {
175
+ break;
176
+ }
177
+ }
178
+ return projectIds;
179
+ }
180
+ async syncSourceAfterCreate(sourceName) {
181
+ try {
182
+ const syncResult = await this.skillSyncService.syncSource(sourceName);
183
+ if (syncResult.failed > 0) {
184
+ logger.warn({
185
+ sourceName,
186
+ failed: syncResult.failed,
187
+ errors: syncResult.errors,
188
+ }, 'Initial local source sync completed with errors');
189
+ }
190
+ }
191
+ catch (error) {
192
+ logger.warn({
193
+ sourceName,
194
+ error: error instanceof Error ? error.message : String(error),
195
+ }, 'Initial local source sync failed after source creation');
196
+ }
197
+ }
198
+ };
199
+ exports.LocalSourcesService = LocalSourcesService;
200
+ exports.LocalSourcesService = LocalSourcesService = __decorate([
201
+ (0, common_1.Injectable)(),
202
+ __param(0, (0, common_1.Inject)(storage_interface_1.STORAGE_SERVICE)),
203
+ __metadata("design:paramtypes", [Object, skills_service_1.SkillsService,
204
+ skill_sync_service_1.SkillSyncService])
205
+ ], LocalSourcesService);
206
+ //# sourceMappingURL=local-sources.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-sources.service.js","sourceRoot":"","sources":["../../../../src/modules/skills/services/local-sources.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type SkillSourceAdapter } from '../adapters/skill-source.adapter';
2
+ import { type StorageService } from '../../storage/interfaces/storage.interface';
3
+ export type SkillSourceKind = 'builtin' | 'community' | 'local';
4
+ export interface RegisteredSkillSource {
5
+ name: string;
6
+ repoUrl: string;
7
+ kind: SkillSourceKind;
8
+ }
9
+ export declare class SkillSourceRegistryService {
10
+ private readonly builtInAdapters;
11
+ private readonly storage;
12
+ constructor(builtInAdapters: SkillSourceAdapter[], storage: StorageService);
13
+ getBuiltInSourceNames(): string[];
14
+ getAdapters(): Promise<SkillSourceAdapter[]>;
15
+ listRegisteredSources(): Promise<RegisteredSkillSource[]>;
16
+ getAdapterBySourceName(name: string): Promise<SkillSourceAdapter | null>;
17
+ private getCommunityAdapters;
18
+ private getLocalAdapters;
19
+ private dedupeAndSort;
20
+ }
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SkillSourceRegistryService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const community_skill_source_adapter_1 = require("../adapters/community-skill-source.adapter");
18
+ const local_skill_source_adapter_1 = require("../adapters/local-skill-source.adapter");
19
+ const skill_source_adapter_1 = require("../adapters/skill-source.adapter");
20
+ const storage_interface_1 = require("../../storage/interfaces/storage.interface");
21
+ const logger_1 = require("../../../common/logging/logger");
22
+ const logger = (0, logger_1.createLogger)('SkillSourceRegistryService');
23
+ let SkillSourceRegistryService = class SkillSourceRegistryService {
24
+ constructor(builtInAdapters, storage) {
25
+ this.builtInAdapters = builtInAdapters;
26
+ this.storage = storage;
27
+ }
28
+ getBuiltInSourceNames() {
29
+ return this.dedupeAndSort(this.builtInAdapters.map((adapter) => adapter.sourceName.trim().toLowerCase()));
30
+ }
31
+ async getAdapters() {
32
+ const [communityAdapters, localAdapters] = await Promise.all([
33
+ this.getCommunityAdapters(),
34
+ this.getLocalAdapters(),
35
+ ]);
36
+ const uniqueAdapters = [];
37
+ const seenSourceNames = new Map();
38
+ const adapterGroups = [
39
+ { kind: 'builtin', adapters: this.builtInAdapters },
40
+ { kind: 'community', adapters: communityAdapters },
41
+ { kind: 'local', adapters: localAdapters },
42
+ ];
43
+ for (const group of adapterGroups) {
44
+ for (const adapter of group.adapters) {
45
+ const normalizedName = adapter.sourceName.trim().toLowerCase();
46
+ if (!normalizedName) {
47
+ continue;
48
+ }
49
+ const existingKind = seenSourceNames.get(normalizedName);
50
+ if (existingKind) {
51
+ logger.warn({
52
+ sourceName: normalizedName,
53
+ kind: group.kind,
54
+ existingKind,
55
+ }, 'Duplicate source name detected in registry adapters; skipping');
56
+ continue;
57
+ }
58
+ seenSourceNames.set(normalizedName, group.kind);
59
+ uniqueAdapters.push(adapter);
60
+ }
61
+ }
62
+ return uniqueAdapters;
63
+ }
64
+ async listRegisteredSources() {
65
+ const sourceMap = new Map();
66
+ for (const adapter of this.builtInAdapters) {
67
+ const normalizedName = adapter.sourceName.trim().toLowerCase();
68
+ if (!normalizedName) {
69
+ continue;
70
+ }
71
+ if (sourceMap.has(normalizedName)) {
72
+ logger.warn({ sourceName: normalizedName, kind: 'builtin' }, 'Duplicate source name detected in registry; skipping');
73
+ continue;
74
+ }
75
+ sourceMap.set(normalizedName, {
76
+ name: normalizedName,
77
+ repoUrl: adapter.repoUrl,
78
+ kind: 'builtin',
79
+ });
80
+ }
81
+ const communityAdapters = await this.getCommunityAdapters();
82
+ for (const adapter of communityAdapters) {
83
+ const normalizedName = adapter.sourceName.trim().toLowerCase();
84
+ if (!normalizedName) {
85
+ continue;
86
+ }
87
+ if (sourceMap.has(normalizedName)) {
88
+ logger.warn({ sourceName: normalizedName, kind: 'community' }, 'Duplicate source name detected in registry; skipping');
89
+ continue;
90
+ }
91
+ sourceMap.set(normalizedName, {
92
+ name: normalizedName,
93
+ repoUrl: adapter.repoUrl,
94
+ kind: 'community',
95
+ });
96
+ }
97
+ const localAdapters = await this.getLocalAdapters();
98
+ for (const adapter of localAdapters) {
99
+ const normalizedName = adapter.sourceName.trim().toLowerCase();
100
+ if (!normalizedName) {
101
+ continue;
102
+ }
103
+ if (sourceMap.has(normalizedName)) {
104
+ logger.warn({ sourceName: normalizedName, kind: 'local' }, 'Duplicate source name detected in registry; skipping');
105
+ continue;
106
+ }
107
+ sourceMap.set(normalizedName, {
108
+ name: normalizedName,
109
+ repoUrl: adapter.repoUrl,
110
+ kind: 'local',
111
+ });
112
+ }
113
+ return [...sourceMap.values()].sort((left, right) => left.name.localeCompare(right.name));
114
+ }
115
+ async getAdapterBySourceName(name) {
116
+ const normalizedName = name.trim().toLowerCase();
117
+ if (!normalizedName) {
118
+ return null;
119
+ }
120
+ const adapters = await this.getAdapters();
121
+ return (adapters.find((adapter) => adapter.sourceName.trim().toLowerCase() === normalizedName) ?? null);
122
+ }
123
+ async getCommunityAdapters() {
124
+ const communitySources = await this.storage.listCommunitySkillSources();
125
+ return communitySources.map((source) => new community_skill_source_adapter_1.CommunitySkillSourceAdapter(source));
126
+ }
127
+ async getLocalAdapters() {
128
+ const localSources = await this.storage.listLocalSkillSources();
129
+ return localSources.map((source) => new local_skill_source_adapter_1.LocalSkillSourceAdapter(source));
130
+ }
131
+ dedupeAndSort(values) {
132
+ return [...new Set(values.filter((value) => value.length > 0))].sort((left, right) => left.localeCompare(right));
133
+ }
134
+ };
135
+ exports.SkillSourceRegistryService = SkillSourceRegistryService;
136
+ exports.SkillSourceRegistryService = SkillSourceRegistryService = __decorate([
137
+ (0, common_1.Injectable)(),
138
+ __param(0, (0, common_1.Inject)(skill_source_adapter_1.SKILL_SOURCE_ADAPTERS)),
139
+ __param(1, (0, common_1.Inject)(storage_interface_1.STORAGE_SERVICE)),
140
+ __metadata("design:paramtypes", [Array, Object])
141
+ ], SkillSourceRegistryService);
142
+ //# sourceMappingURL=skill-source-registry.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-source-registry.service.js","sourceRoot":"","sources":["../../../../src/modules/skills/services/skill-source-registry.service.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { OnApplicationBootstrap } from '@nestjs/common';
2
2
  import { SettingsService } from '../../settings/services/settings.service';
3
- import { SkillSourceAdapter } from '../adapters/skill-source.adapter';
4
3
  import { SkillCategoryService } from './skill-category.service';
4
+ import { SkillSourceRegistryService } from './skill-source-registry.service';
5
5
  import { SkillsService } from './skills.service';
6
6
  export interface SyncError {
7
7
  sourceName: string;
@@ -12,24 +12,28 @@ export interface SyncResult {
12
12
  status: 'completed' | 'already_running';
13
13
  added: number;
14
14
  updated: number;
15
+ removed: number;
15
16
  failed: number;
16
17
  unchanged: number;
17
18
  errors: SyncError[];
18
19
  }
19
20
  export declare class SkillSyncService implements OnApplicationBootstrap {
20
- private readonly adapters;
21
+ private readonly skillSourceRegistry;
21
22
  private readonly skillsService;
22
23
  private readonly skillCategoryService;
23
24
  private readonly settingsService;
24
25
  private syncInProgress;
25
- constructor(adapters: SkillSourceAdapter[], skillsService: SkillsService, skillCategoryService: SkillCategoryService, settingsService: SettingsService);
26
+ constructor(skillSourceRegistry: SkillSourceRegistryService, skillsService: SkillsService, skillCategoryService: SkillCategoryService, settingsService: SettingsService);
26
27
  onApplicationBootstrap(): void;
27
28
  syncAll(): Promise<SyncResult>;
28
29
  syncSource(sourceName: string): Promise<SyncResult>;
29
30
  private withMutex;
30
31
  private syncAdapter;
32
+ private cleanupStaleSkills;
31
33
  private markSkillSyncError;
32
34
  private buildSkillSlug;
35
+ private extractSkillNameFromSlug;
36
+ private deleteSyncedSkillDirectory;
33
37
  private getExistingSkill;
34
38
  private createEmptyResult;
35
39
  private createAlreadyRunningResult;