@open-skills-hub/core 1.0.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/package.json +75 -0
- package/src/config/config.ts +420 -0
- package/src/config/index.ts +5 -0
- package/src/index.ts +18 -0
- package/src/models/index.ts +5 -0
- package/src/models/types.ts +503 -0
- package/src/scanner/index.ts +19 -0
- package/src/scanner/scanner.ts +708 -0
- package/src/scanner/skills-guard-adapter.ts +172 -0
- package/src/storage/index.ts +58 -0
- package/src/storage/interface.ts +391 -0
- package/src/storage/sqlite.ts +1838 -0
- package/src/utils/helpers.ts +414 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/logger.ts +69 -0
- package/tsconfig.json +10 -0
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@open-skills-hub/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Core library for Open Skills Hub",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./config": {
|
|
14
|
+
"import": "./dist/config/index.js",
|
|
15
|
+
"types": "./dist/config/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./storage": {
|
|
18
|
+
"import": "./dist/storage/index.js",
|
|
19
|
+
"types": "./dist/storage/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./models": {
|
|
22
|
+
"import": "./dist/models/index.js",
|
|
23
|
+
"types": "./dist/models/index.d.ts"
|
|
24
|
+
},
|
|
25
|
+
"./scanner": {
|
|
26
|
+
"import": "./dist/scanner/index.js",
|
|
27
|
+
"types": "./dist/scanner/index.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./search": {
|
|
30
|
+
"import": "./dist/search/index.js",
|
|
31
|
+
"types": "./dist/search/index.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./utils": {
|
|
34
|
+
"import": "./dist/utils/index.js",
|
|
35
|
+
"types": "./dist/utils/index.d.ts"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"dev": "tsc --watch",
|
|
41
|
+
"clean": "rm -rf dist"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@skills-guard/core": "^0.2.0",
|
|
45
|
+
"date-fns": "^3.0.6",
|
|
46
|
+
"nanoid": "^5.0.4",
|
|
47
|
+
"pino": "^8.17.2",
|
|
48
|
+
"pino-pretty": "^13.1.3",
|
|
49
|
+
"sql.js": "^1.10.0",
|
|
50
|
+
"yaml": "^2.3.4",
|
|
51
|
+
"zod": "^3.22.4"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/sql.js": "^1.4.9"
|
|
55
|
+
},
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": "https://github.com/OpenSkillsHub/open-skills-hub.git",
|
|
59
|
+
"directory": "packages/core"
|
|
60
|
+
},
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/OpenSkillsHub/open-skills-hub/issues"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://github.com/OpenSkillsHub/open-skills-hub#readme",
|
|
65
|
+
"keywords": [
|
|
66
|
+
"skills",
|
|
67
|
+
"ai",
|
|
68
|
+
"agent",
|
|
69
|
+
"mcp",
|
|
70
|
+
"registry",
|
|
71
|
+
"core"
|
|
72
|
+
],
|
|
73
|
+
"author": "Open Skills Hub Team",
|
|
74
|
+
"license": "MIT"
|
|
75
|
+
}
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Configuration Management
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Configuration Schema
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export const StorageMode = z.enum(['local', 'docker', 'cloud']);
|
|
16
|
+
export type StorageMode = z.infer<typeof StorageMode>;
|
|
17
|
+
|
|
18
|
+
export const AuthMode = z.enum(['local', 'token', 'oauth']);
|
|
19
|
+
export type AuthMode = z.infer<typeof AuthMode>;
|
|
20
|
+
|
|
21
|
+
export const LogLevel = z.enum(['debug', 'info', 'warn', 'error']);
|
|
22
|
+
export type LogLevel = z.infer<typeof LogLevel>;
|
|
23
|
+
|
|
24
|
+
export const CacheConfigSchema = z.object({
|
|
25
|
+
ttl: z.number().default(604800), // 7 days in seconds
|
|
26
|
+
maxSize: z.number().default(524288000), // 500MB
|
|
27
|
+
strategy: z.enum(['lru', 'fifo']).default('lru'),
|
|
28
|
+
autoRefresh: z.boolean().default(true),
|
|
29
|
+
});
|
|
30
|
+
export type CacheConfig = z.infer<typeof CacheConfigSchema>;
|
|
31
|
+
|
|
32
|
+
export const AuthConfigSchema = z.object({
|
|
33
|
+
mode: AuthMode.default('local'),
|
|
34
|
+
requireAuth: z.boolean().default(false),
|
|
35
|
+
jwtSecret: z.string().optional(),
|
|
36
|
+
tokenExpiry: z.number().default(86400), // 24 hours
|
|
37
|
+
});
|
|
38
|
+
export type AuthConfig = z.infer<typeof AuthConfigSchema>;
|
|
39
|
+
|
|
40
|
+
export const ScannerConfigSchema = z.object({
|
|
41
|
+
enabled: z.boolean().default(true),
|
|
42
|
+
timeout: z.number().default(30000), // 30 seconds
|
|
43
|
+
maxFileSize: z.number().default(10485760), // 10MB
|
|
44
|
+
rulesPath: z.string().optional(),
|
|
45
|
+
});
|
|
46
|
+
export type ScannerConfig = z.infer<typeof ScannerConfigSchema>;
|
|
47
|
+
|
|
48
|
+
export const RetryConfigSchema = z.object({
|
|
49
|
+
maxAttempts: z.number().default(5),
|
|
50
|
+
baseDelay: z.number().default(1000),
|
|
51
|
+
maxDelay: z.number().default(3600000), // 1 hour
|
|
52
|
+
backoffMultiplier: z.number().default(2),
|
|
53
|
+
jitter: z.boolean().default(true),
|
|
54
|
+
jitterFactor: z.number().default(0.1),
|
|
55
|
+
});
|
|
56
|
+
export type RetryConfig = z.infer<typeof RetryConfigSchema>;
|
|
57
|
+
|
|
58
|
+
export const ServerConfigSchema = z.object({
|
|
59
|
+
host: z.string().default('localhost'),
|
|
60
|
+
port: z.number().default(3000),
|
|
61
|
+
cors: z.boolean().default(true),
|
|
62
|
+
trustProxy: z.boolean().default(false),
|
|
63
|
+
});
|
|
64
|
+
export type ServerConfig = z.infer<typeof ServerConfigSchema>;
|
|
65
|
+
|
|
66
|
+
export const RateLimitConfigSchema = z.object({
|
|
67
|
+
enabled: z.boolean().default(true),
|
|
68
|
+
windowMs: z.number().default(60000), // 1 minute
|
|
69
|
+
max: z.number().default(100),
|
|
70
|
+
});
|
|
71
|
+
export type RateLimitConfig = z.infer<typeof RateLimitConfigSchema>;
|
|
72
|
+
|
|
73
|
+
export const DatabaseConfigSchema = z.object({
|
|
74
|
+
url: z.string().optional(),
|
|
75
|
+
filename: z.string().default('hub.db'),
|
|
76
|
+
poolSize: z.number().default(10),
|
|
77
|
+
timeout: z.number().default(5000),
|
|
78
|
+
});
|
|
79
|
+
export type DatabaseConfig = z.infer<typeof DatabaseConfigSchema>;
|
|
80
|
+
|
|
81
|
+
export const RegistryConfigSchema = z.object({
|
|
82
|
+
// Storage mode
|
|
83
|
+
mode: StorageMode.default('local'),
|
|
84
|
+
storagePath: z.string().default('~/.open-skills-hub'),
|
|
85
|
+
|
|
86
|
+
// API endpoint (for remote mode)
|
|
87
|
+
apiUrl: z.string().default('https://api.open-skills-hub.io'),
|
|
88
|
+
apiToken: z.string().optional(),
|
|
89
|
+
|
|
90
|
+
// Sub-configurations
|
|
91
|
+
server: ServerConfigSchema.default({}),
|
|
92
|
+
database: DatabaseConfigSchema.default({}),
|
|
93
|
+
cache: CacheConfigSchema.default({}),
|
|
94
|
+
auth: AuthConfigSchema.default({}),
|
|
95
|
+
scanner: ScannerConfigSchema.default({}),
|
|
96
|
+
retry: RetryConfigSchema.default({}),
|
|
97
|
+
rateLimit: RateLimitConfigSchema.default({}),
|
|
98
|
+
|
|
99
|
+
// Logging
|
|
100
|
+
logLevel: LogLevel.default('info'),
|
|
101
|
+
logFormat: z.enum(['json', 'pretty']).default('json'),
|
|
102
|
+
|
|
103
|
+
// Telemetry
|
|
104
|
+
telemetryEnabled: z.boolean().default(true),
|
|
105
|
+
});
|
|
106
|
+
export type RegistryConfig = z.infer<typeof RegistryConfigSchema>;
|
|
107
|
+
|
|
108
|
+
// ============================================================================
|
|
109
|
+
// Configuration Manager
|
|
110
|
+
// ============================================================================
|
|
111
|
+
|
|
112
|
+
const DEFAULT_CONFIG_FILENAME = 'config.yaml';
|
|
113
|
+
|
|
114
|
+
export class ConfigManager {
|
|
115
|
+
private config: RegistryConfig;
|
|
116
|
+
private configPath: string;
|
|
117
|
+
private loaded: boolean = false;
|
|
118
|
+
|
|
119
|
+
constructor(configPath?: string) {
|
|
120
|
+
this.configPath = configPath || this.getDefaultConfigPath();
|
|
121
|
+
this.config = RegistryConfigSchema.parse({});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get the default configuration file path
|
|
126
|
+
*/
|
|
127
|
+
private getDefaultConfigPath(): string {
|
|
128
|
+
const storagePath = this.expandPath('~/.open-skills-hub');
|
|
129
|
+
return path.join(storagePath, DEFAULT_CONFIG_FILENAME);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Expand ~ to home directory
|
|
134
|
+
*/
|
|
135
|
+
private expandPath(p: string): string {
|
|
136
|
+
if (p.startsWith('~')) {
|
|
137
|
+
return path.join(os.homedir(), p.slice(1));
|
|
138
|
+
}
|
|
139
|
+
return p;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the resolved storage path
|
|
144
|
+
*/
|
|
145
|
+
getStoragePath(): string {
|
|
146
|
+
return this.expandPath(this.config.storagePath);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get database file path
|
|
151
|
+
*/
|
|
152
|
+
getDatabasePath(): string {
|
|
153
|
+
return path.join(
|
|
154
|
+
this.getStoragePath(),
|
|
155
|
+
'data',
|
|
156
|
+
this.config.database.filename
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get cache directory path
|
|
162
|
+
*/
|
|
163
|
+
getCachePath(): string {
|
|
164
|
+
return path.join(this.getStoragePath(), 'cache');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get local skills directory path
|
|
169
|
+
*/
|
|
170
|
+
getLocalSkillsPath(): string {
|
|
171
|
+
return path.join(this.getStoragePath(), 'local');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get logs directory path
|
|
176
|
+
*/
|
|
177
|
+
getLogsPath(): string {
|
|
178
|
+
return path.join(this.getStoragePath(), 'logs');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get queue directory path
|
|
183
|
+
*/
|
|
184
|
+
getQueuePath(): string {
|
|
185
|
+
return path.join(this.getStoragePath(), 'queue');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Load configuration from file
|
|
190
|
+
*/
|
|
191
|
+
async load(): Promise<RegistryConfig> {
|
|
192
|
+
if (this.loaded) {
|
|
193
|
+
return this.config;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
// Check if config file exists
|
|
198
|
+
if (fs.existsSync(this.configPath)) {
|
|
199
|
+
const content = fs.readFileSync(this.configPath, 'utf-8');
|
|
200
|
+
const parsed = parseYaml(content) as Record<string, unknown>;
|
|
201
|
+
this.config = RegistryConfigSchema.parse(parsed);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Override with environment variables
|
|
205
|
+
this.applyEnvironmentOverrides();
|
|
206
|
+
|
|
207
|
+
// Ensure directories exist
|
|
208
|
+
await this.ensureDirectories();
|
|
209
|
+
|
|
210
|
+
this.loaded = true;
|
|
211
|
+
return this.config;
|
|
212
|
+
} catch (error) {
|
|
213
|
+
throw new Error(`Failed to load configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Save configuration to file
|
|
219
|
+
*/
|
|
220
|
+
async save(): Promise<void> {
|
|
221
|
+
try {
|
|
222
|
+
const dir = path.dirname(this.configPath);
|
|
223
|
+
if (!fs.existsSync(dir)) {
|
|
224
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const content = stringifyYaml(this.config, { indent: 2 });
|
|
228
|
+
fs.writeFileSync(this.configPath, content, 'utf-8');
|
|
229
|
+
} catch (error) {
|
|
230
|
+
throw new Error(`Failed to save configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Apply environment variable overrides
|
|
236
|
+
*/
|
|
237
|
+
private applyEnvironmentOverrides(): void {
|
|
238
|
+
const env = process.env;
|
|
239
|
+
|
|
240
|
+
// Storage mode
|
|
241
|
+
if (env['STORAGE_MODE']) {
|
|
242
|
+
const mode = StorageMode.safeParse(env['STORAGE_MODE']);
|
|
243
|
+
if (mode.success) {
|
|
244
|
+
this.config.mode = mode.data;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Storage path
|
|
249
|
+
if (env['STORAGE_PATH']) {
|
|
250
|
+
this.config.storagePath = env['STORAGE_PATH'];
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// API configuration
|
|
254
|
+
if (env['SKILLS_REGISTRY_URL']) {
|
|
255
|
+
this.config.apiUrl = env['SKILLS_REGISTRY_URL'];
|
|
256
|
+
}
|
|
257
|
+
if (env['SKILLS_API_TOKEN']) {
|
|
258
|
+
this.config.apiToken = env['SKILLS_API_TOKEN'];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Server configuration
|
|
262
|
+
if (env['PORT']) {
|
|
263
|
+
this.config.server.port = parseInt(env['PORT'], 10);
|
|
264
|
+
}
|
|
265
|
+
if (env['HOST']) {
|
|
266
|
+
this.config.server.host = env['HOST'];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Database URL
|
|
270
|
+
if (env['DATABASE_URL']) {
|
|
271
|
+
this.config.database.url = env['DATABASE_URL'];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Cache configuration
|
|
275
|
+
if (env['CACHE_TTL']) {
|
|
276
|
+
this.config.cache.ttl = parseInt(env['CACHE_TTL'], 10);
|
|
277
|
+
}
|
|
278
|
+
if (env['CACHE_MAX_SIZE']) {
|
|
279
|
+
this.config.cache.maxSize = parseInt(env['CACHE_MAX_SIZE'], 10);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Auth configuration
|
|
283
|
+
if (env['AUTH_ENABLED']) {
|
|
284
|
+
this.config.auth.requireAuth = env['AUTH_ENABLED'] === 'true';
|
|
285
|
+
}
|
|
286
|
+
if (env['JWT_SECRET']) {
|
|
287
|
+
this.config.auth.jwtSecret = env['JWT_SECRET'];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Scanner configuration
|
|
291
|
+
if (env['SCANNER_ENABLED']) {
|
|
292
|
+
this.config.scanner.enabled = env['SCANNER_ENABLED'] === 'true';
|
|
293
|
+
}
|
|
294
|
+
if (env['SCANNER_TIMEOUT']) {
|
|
295
|
+
this.config.scanner.timeout = parseInt(env['SCANNER_TIMEOUT'], 10);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Retry configuration
|
|
299
|
+
if (env['FEEDBACK_QUEUE_MAX_ATTEMPTS']) {
|
|
300
|
+
this.config.retry.maxAttempts = parseInt(env['FEEDBACK_QUEUE_MAX_ATTEMPTS'], 10);
|
|
301
|
+
}
|
|
302
|
+
if (env['FEEDBACK_QUEUE_BASE_DELAY']) {
|
|
303
|
+
this.config.retry.baseDelay = parseInt(env['FEEDBACK_QUEUE_BASE_DELAY'], 10);
|
|
304
|
+
}
|
|
305
|
+
if (env['FEEDBACK_QUEUE_MAX_DELAY']) {
|
|
306
|
+
this.config.retry.maxDelay = parseInt(env['FEEDBACK_QUEUE_MAX_DELAY'], 10);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Logging
|
|
310
|
+
if (env['LOG_LEVEL']) {
|
|
311
|
+
const level = LogLevel.safeParse(env['LOG_LEVEL']);
|
|
312
|
+
if (level.success) {
|
|
313
|
+
this.config.logLevel = level.data;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (env['LOG_FORMAT']) {
|
|
317
|
+
if (env['LOG_FORMAT'] === 'json' || env['LOG_FORMAT'] === 'pretty') {
|
|
318
|
+
this.config.logFormat = env['LOG_FORMAT'];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Ensure required directories exist
|
|
325
|
+
*/
|
|
326
|
+
private async ensureDirectories(): Promise<void> {
|
|
327
|
+
const dirs = [
|
|
328
|
+
this.getStoragePath(),
|
|
329
|
+
path.join(this.getStoragePath(), 'data'),
|
|
330
|
+
this.getCachePath(),
|
|
331
|
+
this.getLocalSkillsPath(),
|
|
332
|
+
this.getLogsPath(),
|
|
333
|
+
this.getQueuePath(),
|
|
334
|
+
];
|
|
335
|
+
|
|
336
|
+
for (const dir of dirs) {
|
|
337
|
+
if (!fs.existsSync(dir)) {
|
|
338
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Get the current configuration
|
|
345
|
+
*/
|
|
346
|
+
get(): RegistryConfig {
|
|
347
|
+
return this.config;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Update configuration
|
|
352
|
+
*/
|
|
353
|
+
set(updates: Partial<RegistryConfig>): void {
|
|
354
|
+
this.config = RegistryConfigSchema.parse({
|
|
355
|
+
...this.config,
|
|
356
|
+
...updates,
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Get a specific configuration value
|
|
362
|
+
*/
|
|
363
|
+
getValue<K extends keyof RegistryConfig>(key: K): RegistryConfig[K] {
|
|
364
|
+
return this.config[key];
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Set a specific configuration value
|
|
369
|
+
*/
|
|
370
|
+
setValue<K extends keyof RegistryConfig>(key: K, value: RegistryConfig[K]): void {
|
|
371
|
+
this.config[key] = value;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Check if running in local mode
|
|
376
|
+
*/
|
|
377
|
+
isLocalMode(): boolean {
|
|
378
|
+
return this.config.mode === 'local';
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Check if running in Docker mode
|
|
383
|
+
*/
|
|
384
|
+
isDockerMode(): boolean {
|
|
385
|
+
return this.config.mode === 'docker';
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Check if running in cloud mode
|
|
390
|
+
*/
|
|
391
|
+
isCloudMode(): boolean {
|
|
392
|
+
return this.config.mode === 'cloud';
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Reset to default configuration
|
|
397
|
+
*/
|
|
398
|
+
reset(): void {
|
|
399
|
+
this.config = RegistryConfigSchema.parse({});
|
|
400
|
+
this.loaded = false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// ============================================================================
|
|
405
|
+
// Singleton Instance
|
|
406
|
+
// ============================================================================
|
|
407
|
+
|
|
408
|
+
let configInstance: ConfigManager | null = null;
|
|
409
|
+
|
|
410
|
+
export function getConfig(): ConfigManager {
|
|
411
|
+
if (!configInstance) {
|
|
412
|
+
configInstance = new ConfigManager();
|
|
413
|
+
}
|
|
414
|
+
return configInstance;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export function initConfig(configPath?: string): ConfigManager {
|
|
418
|
+
configInstance = new ConfigManager(configPath);
|
|
419
|
+
return configInstance;
|
|
420
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open Skills Hub - Core Package Entry
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Config
|
|
6
|
+
export * from './config/index.js';
|
|
7
|
+
|
|
8
|
+
// Models
|
|
9
|
+
export * from './models/index.js';
|
|
10
|
+
|
|
11
|
+
// Storage
|
|
12
|
+
export * from './storage/index.js';
|
|
13
|
+
|
|
14
|
+
// Scanner
|
|
15
|
+
export * from './scanner/index.js';
|
|
16
|
+
|
|
17
|
+
// Utils
|
|
18
|
+
export * from './utils/index.js';
|