tracelattice 1.2.5
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/LICENSE +24 -0
- package/README.md +112 -0
- package/dist/ServerConfig.d.ts +229 -0
- package/dist/ServerConfig.d.ts.map +1 -0
- package/dist/ServerConfig.js +121 -0
- package/dist/ServerConfig.js.map +1 -0
- package/dist/__tests__/base-registry.test.d.ts +2 -0
- package/dist/__tests__/base-registry.test.d.ts.map +1 -0
- package/dist/__tests__/base-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/base-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/base-transport.test.d.ts +2 -0
- package/dist/__tests__/base-transport.test.d.ts.map +1 -0
- package/dist/__tests__/config-loader.test.d.ts +2 -0
- package/dist/__tests__/config-loader.test.d.ts.map +1 -0
- package/dist/__tests__/connection-pool-cov.test.d.ts +2 -0
- package/dist/__tests__/connection-pool-cov.test.d.ts.map +1 -0
- package/dist/__tests__/connection-pool.test.d.ts +2 -0
- package/dist/__tests__/connection-pool.test.d.ts.map +1 -0
- package/dist/__tests__/container.test.d.ts +2 -0
- package/dist/__tests__/container.test.d.ts.map +1 -0
- package/dist/__tests__/crud.test.d.ts +2 -0
- package/dist/__tests__/crud.test.d.ts.map +1 -0
- package/dist/__tests__/discovery-cache.test.d.ts +2 -0
- package/dist/__tests__/discovery-cache.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/factories.test.d.ts +2 -0
- package/dist/__tests__/factories.test.d.ts.map +1 -0
- package/dist/__tests__/health-checker-cov.test.d.ts +2 -0
- package/dist/__tests__/health-checker-cov.test.d.ts.map +1 -0
- package/dist/__tests__/health-checker.test.d.ts +2 -0
- package/dist/__tests__/health-checker.test.d.ts.map +1 -0
- package/dist/__tests__/helpers/factories.d.ts +36 -0
- package/dist/__tests__/helpers/factories.d.ts.map +1 -0
- package/dist/__tests__/helpers/index.d.ts +3 -0
- package/dist/__tests__/helpers/index.d.ts.map +1 -0
- package/dist/__tests__/helpers/timers.d.ts +4 -0
- package/dist/__tests__/helpers/timers.d.ts.map +1 -0
- package/dist/__tests__/history-manager.test.d.ts +2 -0
- package/dist/__tests__/history-manager.test.d.ts.map +1 -0
- package/dist/__tests__/http-helpers-cov.test.d.ts +2 -0
- package/dist/__tests__/http-helpers-cov.test.d.ts.map +1 -0
- package/dist/__tests__/http-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/http-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/http-transport.test.d.ts +2 -0
- package/dist/__tests__/http-transport.test.d.ts.map +1 -0
- package/dist/__tests__/input-normalizer.test.d.ts +8 -0
- package/dist/__tests__/input-normalizer.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/lib-server.test.d.ts +2 -0
- package/dist/__tests__/lib-server.test.d.ts.map +1 -0
- package/dist/__tests__/memory-persistence.test.d.ts +2 -0
- package/dist/__tests__/memory-persistence.test.d.ts.map +1 -0
- package/dist/__tests__/metrics-integration.test.d.ts +2 -0
- package/dist/__tests__/metrics-integration.test.d.ts.map +1 -0
- package/dist/__tests__/persistence.test.d.ts +2 -0
- package/dist/__tests__/persistence.test.d.ts.map +1 -0
- package/dist/__tests__/reasoning-integration.test.d.ts +11 -0
- package/dist/__tests__/reasoning-integration.test.d.ts.map +1 -0
- package/dist/__tests__/reasoning-types.test.d.ts +2 -0
- package/dist/__tests__/reasoning-types.test.d.ts.map +1 -0
- package/dist/__tests__/request-context.test.d.ts +2 -0
- package/dist/__tests__/request-context.test.d.ts.map +1 -0
- package/dist/__tests__/sanitize.test.d.ts +2 -0
- package/dist/__tests__/sanitize.test.d.ts.map +1 -0
- package/dist/__tests__/schema.test.d.ts +2 -0
- package/dist/__tests__/schema.test.d.ts.map +1 -0
- package/dist/__tests__/sequentialthinking-tools.test.d.ts +2 -0
- package/dist/__tests__/sequentialthinking-tools.test.d.ts.map +1 -0
- package/dist/__tests__/server-config.test.d.ts +2 -0
- package/dist/__tests__/server-config.test.d.ts.map +1 -0
- package/dist/__tests__/skill-discovery.test.d.ts +2 -0
- package/dist/__tests__/skill-discovery.test.d.ts.map +1 -0
- package/dist/__tests__/skill-registry.test.d.ts +2 -0
- package/dist/__tests__/skill-registry.test.d.ts.map +1 -0
- package/dist/__tests__/skill-watcher.test.d.ts +2 -0
- package/dist/__tests__/skill-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/sqlite-persistence.test.d.ts +2 -0
- package/dist/__tests__/sqlite-persistence.test.d.ts.map +1 -0
- package/dist/__tests__/sse-transport-cov.test.d.ts +2 -0
- package/dist/__tests__/sse-transport-cov.test.d.ts.map +1 -0
- package/dist/__tests__/sse-transport.test.d.ts +2 -0
- package/dist/__tests__/sse-transport.test.d.ts.map +1 -0
- package/dist/__tests__/streamable-http-cov.test.d.ts +2 -0
- package/dist/__tests__/streamable-http-cov.test.d.ts.map +1 -0
- package/dist/__tests__/streamable-http-transport.test.d.ts +2 -0
- package/dist/__tests__/streamable-http-transport.test.d.ts.map +1 -0
- package/dist/__tests__/structured-logger.test.d.ts +2 -0
- package/dist/__tests__/structured-logger.test.d.ts.map +1 -0
- package/dist/__tests__/thought-evaluator.test.d.ts +2 -0
- package/dist/__tests__/thought-evaluator.test.d.ts.map +1 -0
- package/dist/__tests__/thought-formatter.test.d.ts +2 -0
- package/dist/__tests__/thought-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/thought-processor.test.d.ts +8 -0
- package/dist/__tests__/thought-processor.test.d.ts.map +1 -0
- package/dist/__tests__/tool-registry-cov.test.d.ts +2 -0
- package/dist/__tests__/tool-registry-cov.test.d.ts.map +1 -0
- package/dist/__tests__/tool-registry.test.d.ts +2 -0
- package/dist/__tests__/tool-registry.test.d.ts.map +1 -0
- package/dist/__tests__/tool-watcher.test.d.ts +2 -0
- package/dist/__tests__/tool-watcher.test.d.ts.map +1 -0
- package/dist/__tests__/worker-manager-cov.test.d.ts +2 -0
- package/dist/__tests__/worker-manager-cov.test.d.ts.map +1 -0
- package/dist/__tests__/worker-manager.test.d.ts +2 -0
- package/dist/__tests__/worker-manager.test.d.ts.map +1 -0
- package/dist/cache/DiscoveryCache.d.ts +269 -0
- package/dist/cache/DiscoveryCache.d.ts.map +1 -0
- package/dist/cache/DiscoveryCache.js +100 -0
- package/dist/cache/DiscoveryCache.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +114 -0
- package/dist/cli.js.map +1 -0
- package/dist/cluster/WorkerManager.d.ts +166 -0
- package/dist/cluster/WorkerManager.d.ts.map +1 -0
- package/dist/cluster/WorkerManager.js +202 -0
- package/dist/cluster/WorkerManager.js.map +1 -0
- package/dist/cluster/worker.d.ts +11 -0
- package/dist/cluster/worker.d.ts.map +1 -0
- package/dist/cluster/worker.js +36 -0
- package/dist/cluster/worker.js.map +1 -0
- package/dist/config/ConfigLoader.d.ts +224 -0
- package/dist/config/ConfigLoader.d.ts.map +1 -0
- package/dist/config/ConfigLoader.js +85 -0
- package/dist/config/ConfigLoader.js.map +1 -0
- package/dist/context/RequestContext.d.ts +61 -0
- package/dist/context/RequestContext.d.ts.map +1 -0
- package/dist/context/RequestContext.js +17 -0
- package/dist/context/RequestContext.js.map +1 -0
- package/dist/contracts/index.d.ts +10 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/interfaces.d.ts +107 -0
- package/dist/contracts/interfaces.d.ts.map +1 -0
- package/dist/contracts/interfaces.js +1 -0
- package/dist/core/HistoryManager.d.ts +514 -0
- package/dist/core/HistoryManager.d.ts.map +1 -0
- package/dist/core/HistoryManager.js +331 -0
- package/dist/core/HistoryManager.js.map +1 -0
- package/dist/core/IHistoryManager.d.ts +100 -0
- package/dist/core/IHistoryManager.d.ts.map +1 -0
- package/dist/core/IHistoryManager.js +1 -0
- package/dist/core/InputNormalizer.d.ts +139 -0
- package/dist/core/InputNormalizer.d.ts.map +1 -0
- package/dist/core/InputNormalizer.js +101 -0
- package/dist/core/InputNormalizer.js.map +1 -0
- package/dist/core/ThoughtEvaluator.d.ts +127 -0
- package/dist/core/ThoughtEvaluator.d.ts.map +1 -0
- package/dist/core/ThoughtEvaluator.js +346 -0
- package/dist/core/ThoughtEvaluator.js.map +1 -0
- package/dist/core/ThoughtFormatter.d.ts +133 -0
- package/dist/core/ThoughtFormatter.d.ts.map +1 -0
- package/dist/core/ThoughtFormatter.js +70 -0
- package/dist/core/ThoughtFormatter.js.map +1 -0
- package/dist/core/ThoughtProcessor.d.ts +218 -0
- package/dist/core/ThoughtProcessor.d.ts.map +1 -0
- package/dist/core/ThoughtProcessor.js +205 -0
- package/dist/core/ThoughtProcessor.js.map +1 -0
- package/dist/core/reasoning.d.ts +169 -0
- package/dist/core/reasoning.d.ts.map +1 -0
- package/dist/core/reasoning.js +1 -0
- package/dist/core/step.d.ts +45 -0
- package/dist/core/step.d.ts.map +1 -0
- package/dist/core/step.js +1 -0
- package/dist/core/thought.d.ts +190 -0
- package/dist/core/thought.d.ts.map +1 -0
- package/dist/core/thought.js +1 -0
- package/dist/di/Container.d.ts +226 -0
- package/dist/di/Container.d.ts.map +1 -0
- package/dist/di/Container.js +96 -0
- package/dist/di/Container.js.map +1 -0
- package/dist/di/ServiceRegistry.d.ts +32 -0
- package/dist/di/ServiceRegistry.d.ts.map +1 -0
- package/dist/di/ServiceRegistry.js +1 -0
- package/dist/errors.d.ts +482 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +108 -0
- package/dist/errors.js.map +1 -0
- package/dist/health/HealthChecker.d.ts +73 -0
- package/dist/health/HealthChecker.d.ts.map +1 -0
- package/dist/health/HealthChecker.js +69 -0
- package/dist/health/HealthChecker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/lib.d.ts +205 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +219 -0
- package/dist/lib.js.map +1 -0
- package/dist/logger/NullLogger.d.ts +154 -0
- package/dist/logger/NullLogger.d.ts.map +1 -0
- package/dist/logger/NullLogger.js +24 -0
- package/dist/logger/NullLogger.js.map +1 -0
- package/dist/logger/StructuredLogger.d.ts +327 -0
- package/dist/logger/StructuredLogger.d.ts.map +1 -0
- package/dist/logger/StructuredLogger.js +72 -0
- package/dist/logger/StructuredLogger.js.map +1 -0
- package/dist/metrics/__tests__/metrics.test.d.ts +2 -0
- package/dist/metrics/__tests__/metrics.test.d.ts.map +1 -0
- package/dist/metrics/metrics.impl.d.ts +252 -0
- package/dist/metrics/metrics.impl.d.ts.map +1 -0
- package/dist/metrics/metrics.impl.js +197 -0
- package/dist/metrics/metrics.impl.js.map +1 -0
- package/dist/persistence/FilePersistence.d.ts +66 -0
- package/dist/persistence/FilePersistence.d.ts.map +1 -0
- package/dist/persistence/FilePersistence.js +132 -0
- package/dist/persistence/FilePersistence.js.map +1 -0
- package/dist/persistence/MemoryPersistence.d.ts +68 -0
- package/dist/persistence/MemoryPersistence.d.ts.map +1 -0
- package/dist/persistence/MemoryPersistence.js +51 -0
- package/dist/persistence/MemoryPersistence.js.map +1 -0
- package/dist/persistence/PersistenceBackend.d.ts +69 -0
- package/dist/persistence/PersistenceBackend.d.ts.map +1 -0
- package/dist/persistence/PersistenceBackend.js +1 -0
- package/dist/persistence/PersistenceFactory.d.ts +21 -0
- package/dist/persistence/PersistenceFactory.d.ts.map +1 -0
- package/dist/persistence/PersistenceFactory.js +25 -0
- package/dist/persistence/PersistenceFactory.js.map +1 -0
- package/dist/persistence/SqlitePersistence.d.ts +60 -0
- package/dist/persistence/SqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/SqlitePersistence.js +136 -0
- package/dist/persistence/SqlitePersistence.js.map +1 -0
- package/dist/pool/ConnectionPool.d.ts +215 -0
- package/dist/pool/ConnectionPool.d.ts.map +1 -0
- package/dist/pool/ConnectionPool.js +187 -0
- package/dist/pool/ConnectionPool.js.map +1 -0
- package/dist/registry/BaseRegistry.d.ts +203 -0
- package/dist/registry/BaseRegistry.d.ts.map +1 -0
- package/dist/registry/BaseRegistry.js +165 -0
- package/dist/registry/BaseRegistry.js.map +1 -0
- package/dist/registry/SkillRegistry.d.ts +69 -0
- package/dist/registry/SkillRegistry.d.ts.map +1 -0
- package/dist/registry/SkillRegistry.js +88 -0
- package/dist/registry/SkillRegistry.js.map +1 -0
- package/dist/registry/ToolRegistry.d.ts +69 -0
- package/dist/registry/ToolRegistry.d.ts.map +1 -0
- package/dist/registry/ToolRegistry.js +93 -0
- package/dist/registry/ToolRegistry.js.map +1 -0
- package/dist/sanitize.d.ts +63 -0
- package/dist/sanitize.d.ts.map +1 -0
- package/dist/sanitize.js +14 -0
- package/dist/sanitize.js.map +1 -0
- package/dist/schema.d.ts +531 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +204 -0
- package/dist/schema.js.map +1 -0
- package/dist/telemetry/Telemetry.d.ts +36 -0
- package/dist/telemetry/Telemetry.d.ts.map +1 -0
- package/dist/telemetry/Telemetry.js +68 -0
- package/dist/telemetry/Telemetry.js.map +1 -0
- package/dist/telemetry/__tests__/Telemetry.test.d.ts +2 -0
- package/dist/telemetry/__tests__/Telemetry.test.d.ts.map +1 -0
- package/dist/transport/BaseTransport.d.ts +184 -0
- package/dist/transport/BaseTransport.d.ts.map +1 -0
- package/dist/transport/BaseTransport.js +200 -0
- package/dist/transport/BaseTransport.js.map +1 -0
- package/dist/transport/HttpHelpers.d.ts +60 -0
- package/dist/transport/HttpHelpers.d.ts.map +1 -0
- package/dist/transport/HttpHelpers.js +50 -0
- package/dist/transport/HttpHelpers.js.map +1 -0
- package/dist/transport/HttpTransport.d.ts +134 -0
- package/dist/transport/HttpTransport.d.ts.map +1 -0
- package/dist/transport/HttpTransport.js +175 -0
- package/dist/transport/HttpTransport.js.map +1 -0
- package/dist/transport/SseTransport.d.ts +133 -0
- package/dist/transport/SseTransport.d.ts.map +1 -0
- package/dist/transport/SseTransport.js +318 -0
- package/dist/transport/SseTransport.js.map +1 -0
- package/dist/transport/StreamableHttpTransport.d.ts +224 -0
- package/dist/transport/StreamableHttpTransport.d.ts.map +1 -0
- package/dist/transport/StreamableHttpTransport.js +407 -0
- package/dist/transport/StreamableHttpTransport.js.map +1 -0
- package/dist/types/disposable.d.ts +22 -0
- package/dist/types/disposable.d.ts.map +1 -0
- package/dist/types/disposable.js +1 -0
- package/dist/types/server-config.d.ts +32 -0
- package/dist/types/server-config.d.ts.map +1 -0
- package/dist/types/server-config.js +1 -0
- package/dist/types/skill.d.ts +69 -0
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/skill.js +1 -0
- package/dist/types/tool.d.ts +68 -0
- package/dist/types/tool.d.ts.map +1 -0
- package/dist/types/tool.js +1 -0
- package/dist/watchers/SkillWatcher.d.ts +132 -0
- package/dist/watchers/SkillWatcher.d.ts.map +1 -0
- package/dist/watchers/SkillWatcher.js +73 -0
- package/dist/watchers/SkillWatcher.js.map +1 -0
- package/dist/watchers/ToolWatcher.d.ts +109 -0
- package/dist/watchers/ToolWatcher.d.ts.map +1 -0
- package/dist/watchers/ToolWatcher.js +71 -0
- package/dist/watchers/ToolWatcher.js.map +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BaseRegistry.d.ts","sourceRoot":"","sources":["../../src/registry/BaseRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { parse } from "yaml";
|
|
5
|
+
import { DiscoveryCache } from "../cache/DiscoveryCache.js";
|
|
6
|
+
import { NullLogger } from "../logger/NullLogger.js";
|
|
7
|
+
class BaseRegistry {
|
|
8
|
+
_items;
|
|
9
|
+
_logger;
|
|
10
|
+
_cache;
|
|
11
|
+
_searchDirs;
|
|
12
|
+
_discovered = false;
|
|
13
|
+
_discoveryPromise = null;
|
|
14
|
+
constructor(options){
|
|
15
|
+
this._items = new Map();
|
|
16
|
+
this._logger = options.logger ?? new NullLogger();
|
|
17
|
+
this._cache = options.cache || new DiscoveryCache({
|
|
18
|
+
maxSize: 50,
|
|
19
|
+
ttl: 300000
|
|
20
|
+
});
|
|
21
|
+
this._searchDirs = options.searchDirs ?? [];
|
|
22
|
+
}
|
|
23
|
+
log(message, meta) {
|
|
24
|
+
this._logger.info(message, meta);
|
|
25
|
+
}
|
|
26
|
+
add(item) {
|
|
27
|
+
if (!item.name) throw this._createInvalidError(`${this._entityName} must have a valid name`);
|
|
28
|
+
if (this._items.has(item.name)) throw this._createDuplicateError(item.name);
|
|
29
|
+
this._items.set(item.name, item);
|
|
30
|
+
this.log(`Added ${this._entityName}: ${item.name}`, {
|
|
31
|
+
[`${this._entityName}Name`]: item.name
|
|
32
|
+
});
|
|
33
|
+
this._cache?.invalidate('all');
|
|
34
|
+
}
|
|
35
|
+
remove(name) {
|
|
36
|
+
if (!this._items.has(name)) throw this._createNotFoundError(name, 'remove');
|
|
37
|
+
this._items.delete(name);
|
|
38
|
+
this.log(`Removed ${this._entityName}: ${name}`, {
|
|
39
|
+
[`${this._entityName}Name`]: name
|
|
40
|
+
});
|
|
41
|
+
this._cache?.invalidate('all');
|
|
42
|
+
this._cache?.invalidate(name);
|
|
43
|
+
}
|
|
44
|
+
update(name, updates) {
|
|
45
|
+
if (!this._items.has(name)) throw this._createNotFoundError(name, 'update');
|
|
46
|
+
const existing = this._items.get(name);
|
|
47
|
+
const updated = {
|
|
48
|
+
...existing,
|
|
49
|
+
...updates
|
|
50
|
+
};
|
|
51
|
+
this._items.set(name, updated);
|
|
52
|
+
this.log(`Updated ${this._entityName}: ${name}`, {
|
|
53
|
+
[`${this._entityName}Name`]: name
|
|
54
|
+
});
|
|
55
|
+
this._cache?.invalidate('all');
|
|
56
|
+
this._cache?.invalidate(name);
|
|
57
|
+
}
|
|
58
|
+
get(name) {
|
|
59
|
+
return this._items.get(name);
|
|
60
|
+
}
|
|
61
|
+
getAll() {
|
|
62
|
+
if (this._cache) {
|
|
63
|
+
const cached = this._cache.get('all');
|
|
64
|
+
if (cached) return cached;
|
|
65
|
+
}
|
|
66
|
+
const items = Array.from(this._items.values());
|
|
67
|
+
this._cache?.set('all', items);
|
|
68
|
+
return items;
|
|
69
|
+
}
|
|
70
|
+
has(name) {
|
|
71
|
+
return this._items.has(name);
|
|
72
|
+
}
|
|
73
|
+
getNames() {
|
|
74
|
+
return Array.from(this._items.keys());
|
|
75
|
+
}
|
|
76
|
+
clear() {
|
|
77
|
+
this._items.clear();
|
|
78
|
+
this.log(`Cleared all ${this._entityName}s`);
|
|
79
|
+
this._cache?.clear();
|
|
80
|
+
}
|
|
81
|
+
size() {
|
|
82
|
+
return this._items.size;
|
|
83
|
+
}
|
|
84
|
+
async discoverAsync() {
|
|
85
|
+
if (this._discoveryPromise) return this._discoveryPromise;
|
|
86
|
+
if (this._discovered) {
|
|
87
|
+
const cached = this._cache.get('all');
|
|
88
|
+
return cached?.length ?? 0;
|
|
89
|
+
}
|
|
90
|
+
this._discoveryPromise = this._performDiscovery();
|
|
91
|
+
try {
|
|
92
|
+
const count = await this._discoveryPromise;
|
|
93
|
+
return count;
|
|
94
|
+
} finally{
|
|
95
|
+
this._discoveryPromise = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async _performDiscovery() {
|
|
99
|
+
let discoveredCount = 0;
|
|
100
|
+
for (const dir of this._searchDirs)try {
|
|
101
|
+
if (!existsSync(dir)) continue;
|
|
102
|
+
const entries = await readdir(dir, {
|
|
103
|
+
withFileTypes: true
|
|
104
|
+
});
|
|
105
|
+
for (const entry of entries)if (!this._shouldSkipFile(entry.name)) {
|
|
106
|
+
if (entry.isFile() && this._fileExtensions.some((ext)=>entry.name.endsWith(ext))) {
|
|
107
|
+
const filePath = join(dir, entry.name);
|
|
108
|
+
try {
|
|
109
|
+
const content = await readFile(filePath, 'utf-8');
|
|
110
|
+
const parsed = this._parseFrontmatter(content);
|
|
111
|
+
if (parsed._error) {
|
|
112
|
+
this.log(`Skipped ${entry.name}: ${parsed._error}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (parsed.name) {
|
|
116
|
+
if (!this._items.has(parsed.name)) {
|
|
117
|
+
const item = this._buildItem(parsed);
|
|
118
|
+
if (item) {
|
|
119
|
+
this._items.set(item.name, item);
|
|
120
|
+
discoveredCount++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} catch (readError) {
|
|
125
|
+
this.log(`Failed to read ${this._entityName} file ${entry.name}`, {
|
|
126
|
+
error: readError instanceof Error ? readError.message : String(readError)
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
this.log(`Failed to scan ${this._entityName} directory: ${dir}`, {
|
|
133
|
+
error: error instanceof Error ? error.message : String(error)
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
this._discovered = true;
|
|
137
|
+
this._cache?.set('all', Array.from(this._items.values()));
|
|
138
|
+
this.log(`Discovery complete: found ${discoveredCount} ${this._entityName}s`, {
|
|
139
|
+
discoveredCount
|
|
140
|
+
});
|
|
141
|
+
return discoveredCount;
|
|
142
|
+
}
|
|
143
|
+
_extractFrontmatter(content) {
|
|
144
|
+
const match = content.match(/^---\n([\s\S]+?)\n---/);
|
|
145
|
+
if (!match) return null;
|
|
146
|
+
return parse(match[1]);
|
|
147
|
+
}
|
|
148
|
+
setAll(items) {
|
|
149
|
+
this.clear();
|
|
150
|
+
for (const item of items)try {
|
|
151
|
+
this.add(item);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
this.log(`Error adding ${this._entityName} '${item.name}':`, {
|
|
154
|
+
[`${this._entityName}Name`]: item.name,
|
|
155
|
+
error: error instanceof Error ? error.message : String(error)
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
this.log(`Set ${items.length} ${this._entityName}s from external source`, {
|
|
159
|
+
[`${this._entityName}Count`]: items.length
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export { BaseRegistry };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=BaseRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry/BaseRegistry.js","sources":["../../src/registry/BaseRegistry.ts"],"sourcesContent":["/**\n * Base registry providing shared CRUD, caching, and discovery logic.\n *\n * This abstract generic class extracts the common patterns from `ToolRegistry`\n * and `SkillRegistry` into a single reusable base. Subclasses only need to\n * implement item-specific parsing, file filtering, and error construction.\n *\n * @template T - The registry item type (must have a `name` property)\n * @module registry\n */\n\nimport { existsSync } from 'node:fs';\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { DiscoveryCache } from '../cache/DiscoveryCache.js';\nimport { NullLogger } from '../logger/NullLogger.js';\nimport type { Logger } from '../logger/StructuredLogger.js';\n\n/**\n * Configuration options for creating a `BaseRegistry` instance.\n */\nexport interface BaseRegistryOptions {\n\t/** Optional logger for diagnostics. */\n\tlogger?: Logger;\n\n\t/** Optional cache for lookups. */\n\tcache?: DiscoveryCache<{ name: string }>;\n\n\t/**\n\t * Directory paths to search for items.\n\t */\n\tsearchDirs?: string[];\n\n\t/**\n\t * Enable lazy discovery (discover on first access instead of startup).\n\t * @default false\n\t */\n\tlazyDiscovery?: boolean;\n}\n\n/**\n * Abstract base registry for managing named items with discovery and caching.\n *\n * Provides shared CRUD operations, filesystem discovery with deduplication,\n * and optional LRU caching. Subclasses implement item-specific parsing logic\n * and error construction.\n *\n * @template T - The registry item type (must have a `name` property)\n */\nexport abstract class BaseRegistry<T extends { name: string }> {\n\t/** Internal storage for items indexed by name. */\n\tprotected _items: Map<string, T>;\n\n\t/** Logger for diagnostics. */\n\tprotected _logger: Logger;\n\n\t/** Optional cache for lookups. */\n\tprotected _cache: DiscoveryCache<T>;\n\n\t/** Directory paths to search for items. */\n\tprotected _searchDirs: string[];\n\n\t/** Whether discovery has been performed. */\n\tprotected _discovered: boolean = false;\n\n\t/** Promise for in-progress discovery (null if not in progress). */\n\tprotected _discoveryPromise: Promise<number> | null = null;\n\n\t/** File extensions to match during discovery. */\n\tprotected abstract readonly _fileExtensions: string[];\n\n\t/**\n\t * Creates an error for invalid item data.\n\t * @param reason - The reason for the validation failure\n\t */\n\tprotected abstract _createInvalidError(reason: string): Error;\n\n\t/**\n\t * Creates an error for duplicate items.\n\t * @param name - The name of the duplicate item\n\t */\n\tprotected abstract _createDuplicateError(name: string): Error;\n\n\t/**\n\t * Creates an error for items not found.\n\t * @param name - The name of the missing item\n\t * @param action - The action that was attempted\n\t */\n\tprotected abstract _createNotFoundError(name: string, action: string): Error;\n\n\t/**\n\t * Parses frontmatter content into a partial item.\n\t * @param content - The file content to parse\n\t * @returns A partial item, with an `_error` property if parsing failed\n\t */\n\tprotected abstract _parseFrontmatter(content: string): Partial<T> & { _error?: string };\n\n\t/**\n\t * Determines whether a file should be skipped during discovery.\n\t * @param fileName - The name of the file to check\n\t * @returns true if the file should be skipped\n\t */\n\tprotected abstract _shouldSkipFile(fileName: string): boolean;\n\n\t/**\n\t * Constructs a complete item from parsed frontmatter data.\n\t * Returns null if the parsed data is insufficient.\n\t * @param parsed - The parsed frontmatter data\n\t * @returns A complete item, or null if data is insufficient\n\t */\n\tprotected abstract _buildItem(parsed: Partial<T>): T | null;\n\n\t/**\n\t * The entity name used in log messages (e.g., 'tool', 'skill').\n\t */\n\tprotected abstract readonly _entityName: string;\n\n\tconstructor(options: BaseRegistryOptions & Record<string, unknown>) {\n\t\tthis._items = new Map();\n\t\tthis._logger = (options.logger ?? new NullLogger()) as Logger;\n\t\tthis._cache = (options.cache ||\n\t\t\tnew DiscoveryCache<T>({ maxSize: 50, ttl: 300000 })) as DiscoveryCache<T>;\n\t\tthis._searchDirs = (options.searchDirs ?? []) as string[];\n\t}\n\n\t/**\n\t * Internal logging method.\n\t * @param message - The message to log\n\t * @param meta - Optional metadata\n\t */\n\tprotected log(message: string, meta?: Record<string, unknown>): void {\n\t\tthis._logger.info(message, meta);\n\t}\n\n\t/**\n\t * Adds an item to the registry.\n\t *\n\t * @param item - The item to add\n\t * @throws If item already exists or name is invalid\n\t */\n\tpublic add(item: T): void {\n\t\tif (!item.name) {\n\t\t\tthrow this._createInvalidError(`${this._entityName} must have a valid name`);\n\t\t}\n\t\tif (this._items.has(item.name)) {\n\t\t\tthrow this._createDuplicateError(item.name);\n\t\t}\n\t\tthis._items.set(item.name, item);\n\t\tthis.log(`Added ${this._entityName}: ${item.name}`, { [`${this._entityName}Name`]: item.name });\n\t\t// Invalidate cache when adding a new item\n\t\tthis._cache?.invalidate('all');\n\t}\n\n\t/**\n\t * Removes an item from the registry.\n\t *\n\t * @param name - The name of the item to remove\n\t * @throws If item not found\n\t */\n\tpublic remove(name: string): void {\n\t\tif (!this._items.has(name)) {\n\t\t\tthrow this._createNotFoundError(name, 'remove');\n\t\t}\n\t\tthis._items.delete(name);\n\t\tthis.log(`Removed ${this._entityName}: ${name}`, { [`${this._entityName}Name`]: name });\n\t\t// Invalidate cache when removing an item\n\t\tthis._cache?.invalidate('all');\n\t\tthis._cache?.invalidate(name);\n\t}\n\n\t/**\n\t * Updates an existing item with partial data.\n\t *\n\t * @param name - The name of the item to update\n\t * @param updates - Partial item data with fields to update\n\t * @throws If item not found\n\t */\n\tpublic update(name: string, updates: Partial<T>): void {\n\t\tif (!this._items.has(name)) {\n\t\t\tthrow this._createNotFoundError(name, 'update');\n\t\t}\n\t\tconst existing = this._items.get(name)!;\n\t\tconst updated = { ...existing, ...updates };\n\t\tthis._items.set(name, updated);\n\t\tthis.log(`Updated ${this._entityName}: ${name}`, { [`${this._entityName}Name`]: name });\n\t\t// Invalidate cache when updating an item\n\t\tthis._cache?.invalidate('all');\n\t\tthis._cache?.invalidate(name);\n\t}\n\n\t/**\n\t * Gets an item by name.\n\t *\n\t * @param name - The name of the item to get\n\t * @returns The item if found, undefined otherwise\n\t */\n\tpublic get(name: string): T | undefined {\n\t\treturn this._items.get(name);\n\t}\n\n\t/**\n\t * Gets all items as an array.\n\t *\n\t * Uses cache if available for performance.\n\t *\n\t * @returns An array of all registered items\n\t */\n\tpublic getAll(): T[] {\n\t\t// Check cache first\n\t\tif (this._cache) {\n\t\t\tconst cached = this._cache.get('all');\n\t\t\tif (cached) {\n\t\t\t\treturn cached;\n\t\t\t}\n\t\t}\n\t\t// Get from storage\n\t\tconst items = Array.from(this._items.values());\n\t\t// Cache the result\n\t\tthis._cache?.set('all', items);\n\t\treturn items;\n\t}\n\n\t/**\n\t * Checks if an item exists in the registry.\n\t *\n\t * @param name - The name of the item to check\n\t * @returns true if the item exists, false otherwise\n\t */\n\tpublic has(name: string): boolean {\n\t\treturn this._items.has(name);\n\t}\n\n\t/**\n\t * Gets all item names as an array.\n\t *\n\t * @returns An array of item names\n\t */\n\tpublic getNames(): string[] {\n\t\treturn Array.from(this._items.keys());\n\t}\n\n\t/**\n\t * Clears all items from the registry.\n\t */\n\tpublic clear(): void {\n\t\tthis._items.clear();\n\t\tthis.log(`Cleared all ${this._entityName}s`);\n\t\t// Invalidate cache when clearing all items\n\t\tthis._cache?.clear();\n\t}\n\n\t/**\n\t * Gets the number of items in the registry.\n\t *\n\t * @returns The count of registered items\n\t */\n\tpublic size(): number {\n\t\treturn this._items.size;\n\t}\n\n\t/**\n\t * Asynchronously discovers items from the configured directories.\n\t *\n\t * Multiple concurrent calls share the same discovery promise.\n\t * Subsequent calls return cached results if discovery has already completed.\n\t *\n\t * @returns A Promise resolving to the number of items discovered\n\t */\n\tpublic async discoverAsync(): Promise<number> {\n\t\t// Return existing promise if discovery is in progress\n\t\tif (this._discoveryPromise) {\n\t\t\treturn this._discoveryPromise;\n\t\t}\n\n\t\t// Use cached results if already discovered\n\t\tif (this._discovered) {\n\t\t\tconst cached = this._cache.get('all');\n\t\t\treturn cached?.length ?? 0;\n\t\t}\n\n\t\t// Create discovery promise\n\t\tthis._discoveryPromise = this._performDiscovery();\n\n\t\ttry {\n\t\t\tconst count = await this._discoveryPromise;\n\t\t\treturn count;\n\t\t} finally {\n\t\t\tthis._discoveryPromise = null;\n\t\t}\n\t}\n\n\t/**\n\t * Performs the actual discovery operation.\n\t *\n\t * Scans configured directories for item files, parses their frontmatter,\n\t * and adds valid items to the registry.\n\t *\n\t * @returns A Promise resolving to the number of items discovered\n\t */\n\tprotected async _performDiscovery(): Promise<number> {\n\t\tlet discoveredCount = 0;\n\n\t\tfor (const dir of this._searchDirs) {\n\t\t\ttry {\n\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst entries = await readdir(dir, { withFileTypes: true });\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (this._shouldSkipFile(entry.name)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (entry.isFile() && this._fileExtensions.some((ext) => entry.name.endsWith(ext))) {\n\t\t\t\t\t\tconst filePath = join(dir, entry.name);\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst content = await readFile(filePath, 'utf-8');\n\t\t\t\t\t\t\tconst parsed = this._parseFrontmatter(content);\n\t\t\t\t\t\t\tif (parsed._error) {\n\t\t\t\t\t\t\t\tthis.log(`Skipped ${entry.name}: ${parsed._error}`);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (parsed.name) {\n\t\t\t\t\t\t\t\t// Check if already exists before adding\n\t\t\t\t\t\t\t\tif (!this._items.has(parsed.name)) {\n\t\t\t\t\t\t\t\t\tconst item = this._buildItem(parsed);\n\t\t\t\t\t\t\t\t\tif (item) {\n\t\t\t\t\t\t\t\t\t\tthis._items.set(item.name, item);\n\t\t\t\t\t\t\t\t\t\tdiscoveredCount++;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (readError) {\n\t\t\t\t\t\t\tthis.log(`Failed to read ${this._entityName} file ${entry.name}`, {\n\t\t\t\t\t\t\t\terror: readError instanceof Error ? readError.message : String(readError),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthis.log(`Failed to scan ${this._entityName} directory: ${dir}`, {\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis._discovered = true;\n\t\tthis._cache?.set('all', Array.from(this._items.values()));\n\t\tthis.log(`Discovery complete: found ${discoveredCount} ${this._entityName}s`, {\n\t\t\tdiscoveredCount,\n\t\t});\n\t\treturn discoveredCount;\n\t}\n\n\t/**\n\t * Parses YAML frontmatter from file content.\n\t *\n\t * This is a shared utility for subclasses that parse YAML frontmatter.\n\t *\n\t * @param content - The file content to parse\n\t * @returns The parsed YAML object, or null if no frontmatter found\n\t */\n\tprotected _extractFrontmatter(content: string): Record<string, unknown> | null {\n\t\tconst match = content.match(/^---\\n([\\s\\S]+?)\\n---/);\n\t\tif (!match) {\n\t\t\treturn null;\n\t\t}\n\t\treturn parseYaml(match[1]!) as Record<string, unknown>;\n\t}\n\n\t/**\n\t * Sets items from an external source.\n\t *\n\t * Clears existing items and adds new ones from the provided array.\n\t *\n\t * @param items - Array of items from an external source\n\t */\n\tpublic setAll(items: T[]): void {\n\t\tthis.clear();\n\t\tfor (const item of items) {\n\t\t\ttry {\n\t\t\t\tthis.add(item);\n\t\t\t} catch (error) {\n\t\t\t\tthis.log(`Error adding ${this._entityName} '${item.name}':`, {\n\t\t\t\t\t[`${this._entityName}Name`]: item.name,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis.log(`Set ${items.length} ${this._entityName}s from external source`, {\n\t\t\t[`${this._entityName}Count`]: items.length,\n\t\t});\n\t}\n}\n"],"names":["BaseRegistry","options","Map","NullLogger","DiscoveryCache","message","meta","item","name","updates","existing","updated","cached","items","Array","count","discoveredCount","dir","existsSync","entries","readdir","entry","ext","filePath","join","content","readFile","parsed","readError","Error","String","error","match","parseYaml"],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill registry for managing and discovering Claude Code skills.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the `SkillRegistry` class which manages skill registration,
|
|
5
|
+
* discovery from filesystem directories, and CRUD operations. Skills are higher-level
|
|
6
|
+
* workflows that coordinate multiple tools and operations.
|
|
7
|
+
*
|
|
8
|
+
* @module registry
|
|
9
|
+
*/
|
|
10
|
+
import { DiscoveryCache } from '../cache/DiscoveryCache.js';
|
|
11
|
+
import type { Logger } from '../logger/StructuredLogger.js';
|
|
12
|
+
import type { Skill } from '../types/skill.js';
|
|
13
|
+
import { BaseRegistry } from './BaseRegistry.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for creating a `SkillRegistry` instance.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const options: SkillRegistryOptions = {
|
|
20
|
+
* logger: new StructuredLogger({ context: 'SkillRegistry' }),
|
|
21
|
+
* cache: new DiscoveryCache({ ttl: 300000, maxSize: 100 }),
|
|
22
|
+
* skillDirs: ['./custom-skills', '~/.claude/skills'],
|
|
23
|
+
* lazyDiscovery: true
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface SkillRegistryOptions {
|
|
28
|
+
/** Optional logger for diagnostics. */
|
|
29
|
+
logger?: Logger;
|
|
30
|
+
/** Optional cache for skill lookups. */
|
|
31
|
+
cache?: DiscoveryCache<Skill>;
|
|
32
|
+
/**
|
|
33
|
+
* Directory paths to search for skills.
|
|
34
|
+
* @default ['.claude/skills', '~/.claude/skills']
|
|
35
|
+
*/
|
|
36
|
+
skillDirs?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Enable lazy discovery (discover on first access instead of startup).
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
lazyDiscovery?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Registry for managing Claude Code skill operations.
|
|
45
|
+
*
|
|
46
|
+
* Extends `BaseRegistry<Skill>` with skill-specific frontmatter parsing
|
|
47
|
+
* and backward-compatible aliases (`addSkill`, `removeSkillByName`, etc.).
|
|
48
|
+
*/
|
|
49
|
+
export declare class SkillRegistry extends BaseRegistry<Skill> {
|
|
50
|
+
protected readonly _fileExtensions: string[];
|
|
51
|
+
protected readonly _entityName = "skill";
|
|
52
|
+
constructor(options?: SkillRegistryOptions);
|
|
53
|
+
protected _createInvalidError(reason: string): Error;
|
|
54
|
+
protected _createDuplicateError(name: string): Error;
|
|
55
|
+
protected _createNotFoundError(name: string, action: string): Error;
|
|
56
|
+
protected _shouldSkipFile(fileName: string): boolean;
|
|
57
|
+
protected _parseFrontmatter(content: string): Partial<Skill> & {
|
|
58
|
+
_error?: string;
|
|
59
|
+
};
|
|
60
|
+
protected _buildItem(parsed: Partial<Skill>): Skill | null;
|
|
61
|
+
addSkill(skill: Skill): void;
|
|
62
|
+
/** @deprecated Use `remove()` instead */
|
|
63
|
+
removeSkillByName(name: string): void;
|
|
64
|
+
updateSkill(name: string, updates: Partial<Skill>): void;
|
|
65
|
+
hasSkill(name: string): boolean;
|
|
66
|
+
getSkill(name: string): Skill | undefined;
|
|
67
|
+
setSkills(skills: Skill[]): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=SkillRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillRegistry.d.ts","sourceRoot":"","sources":["../../src/registry/SkillRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,oBAAoB;IACpC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,wCAAwC;IACxC,KAAK,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;IAE9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,KAAK,CAAC;IACrD,mBAA4B,eAAe,WAA4B;IACvE,mBAA4B,WAAW,WAAW;gBAEtC,OAAO,GAAE,oBAAyB;cAW3B,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK;cAI1C,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;cAI1C,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK;cAMzD,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;cAI1C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;cA6BxE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,IAAI;IAc5D,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAInC,yCAAyC;IAClC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI;IAIxD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIzC,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI;CAGvC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { DuplicateSkillError, InvalidSkillError, SkillNotFoundError } from "../errors.js";
|
|
4
|
+
import { BaseRegistry } from "./BaseRegistry.js";
|
|
5
|
+
class SkillRegistry extends BaseRegistry {
|
|
6
|
+
_fileExtensions = [
|
|
7
|
+
'.md',
|
|
8
|
+
'.yml',
|
|
9
|
+
'.yaml'
|
|
10
|
+
];
|
|
11
|
+
_entityName = 'skill';
|
|
12
|
+
constructor(options = {}){
|
|
13
|
+
super({
|
|
14
|
+
logger: options.logger,
|
|
15
|
+
cache: options.cache,
|
|
16
|
+
searchDirs: options.skillDirs || [
|
|
17
|
+
'.claude/skills',
|
|
18
|
+
join(homedir(), '.claude/skills')
|
|
19
|
+
],
|
|
20
|
+
lazyDiscovery: options.lazyDiscovery
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
_createInvalidError(reason) {
|
|
24
|
+
return new InvalidSkillError(reason);
|
|
25
|
+
}
|
|
26
|
+
_createDuplicateError(name) {
|
|
27
|
+
return new DuplicateSkillError(name);
|
|
28
|
+
}
|
|
29
|
+
_createNotFoundError(name, action) {
|
|
30
|
+
return new SkillNotFoundError(name, action);
|
|
31
|
+
}
|
|
32
|
+
_shouldSkipFile(fileName) {
|
|
33
|
+
return '.DS_Store' === fileName;
|
|
34
|
+
}
|
|
35
|
+
_parseFrontmatter(content) {
|
|
36
|
+
const frontmatter = this._extractFrontmatter(content);
|
|
37
|
+
if (!frontmatter) return {};
|
|
38
|
+
try {
|
|
39
|
+
const result = {
|
|
40
|
+
name: 'string' == typeof frontmatter.name ? frontmatter.name : void 0,
|
|
41
|
+
description: 'string' == typeof frontmatter.description ? frontmatter.description : '',
|
|
42
|
+
user_invocable: true === frontmatter['user-invocable'],
|
|
43
|
+
allowed_tools: Array.isArray(frontmatter['allowed-tools']) ? frontmatter['allowed-tools'].map(String) : void 0
|
|
44
|
+
};
|
|
45
|
+
if (!result.name) return {
|
|
46
|
+
_error: 'Missing required field: name'
|
|
47
|
+
};
|
|
48
|
+
return result;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
this.log('Error parsing YAML frontmatter:', {
|
|
51
|
+
error: error instanceof Error ? error.message : String(error)
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
_error: 'YAML parse error'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
_buildItem(parsed) {
|
|
59
|
+
if (!parsed.name) return null;
|
|
60
|
+
return {
|
|
61
|
+
name: parsed.name,
|
|
62
|
+
description: parsed.description || '',
|
|
63
|
+
user_invocable: parsed.user_invocable ?? false,
|
|
64
|
+
allowed_tools: parsed.allowed_tools
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
addSkill(skill) {
|
|
68
|
+
this.add(skill);
|
|
69
|
+
}
|
|
70
|
+
removeSkillByName(name) {
|
|
71
|
+
this.remove(name);
|
|
72
|
+
}
|
|
73
|
+
updateSkill(name, updates) {
|
|
74
|
+
this.update(name, updates);
|
|
75
|
+
}
|
|
76
|
+
hasSkill(name) {
|
|
77
|
+
return this.has(name);
|
|
78
|
+
}
|
|
79
|
+
getSkill(name) {
|
|
80
|
+
return this.get(name);
|
|
81
|
+
}
|
|
82
|
+
setSkills(skills) {
|
|
83
|
+
this.setAll(skills);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export { SkillRegistry };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=SkillRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry/SkillRegistry.js","sources":["../../src/registry/SkillRegistry.ts"],"sourcesContent":["/**\n * Skill registry for managing and discovering Claude Code skills.\n *\n * This module provides the `SkillRegistry` class which manages skill registration,\n * discovery from filesystem directories, and CRUD operations. Skills are higher-level\n * workflows that coordinate multiple tools and operations.\n *\n * @module registry\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { DiscoveryCache } from '../cache/DiscoveryCache.js';\nimport { DuplicateSkillError, InvalidSkillError, SkillNotFoundError } from '../errors.js';\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { Skill } from '../types/skill.js';\nimport { BaseRegistry } from './BaseRegistry.js';\n\n/**\n * Configuration options for creating a `SkillRegistry` instance.\n *\n * @example\n * ```typescript\n * const options: SkillRegistryOptions = {\n * logger: new StructuredLogger({ context: 'SkillRegistry' }),\n * cache: new DiscoveryCache({ ttl: 300000, maxSize: 100 }),\n * skillDirs: ['./custom-skills', '~/.claude/skills'],\n * lazyDiscovery: true\n * };\n * ```\n */\nexport interface SkillRegistryOptions {\n\t/** Optional logger for diagnostics. */\n\tlogger?: Logger;\n\n\t/** Optional cache for skill lookups. */\n\tcache?: DiscoveryCache<Skill>;\n\n\t/**\n\t * Directory paths to search for skills.\n\t * @default ['.claude/skills', '~/.claude/skills']\n\t */\n\tskillDirs?: string[];\n\n\t/**\n\t * Enable lazy discovery (discover on first access instead of startup).\n\t * @default false\n\t */\n\tlazyDiscovery?: boolean;\n}\n\n/**\n * Registry for managing Claude Code skill operations.\n *\n * Extends `BaseRegistry<Skill>` with skill-specific frontmatter parsing\n * and backward-compatible aliases (`addSkill`, `removeSkillByName`, etc.).\n */\nexport class SkillRegistry extends BaseRegistry<Skill> {\n\tprotected override readonly _fileExtensions = ['.md', '.yml', '.yaml'];\n\tprotected override readonly _entityName = 'skill';\n\n\tconstructor(options: SkillRegistryOptions = {}) {\n\t\tsuper({\n\t\t\tlogger: options.logger,\n\t\t\tcache: options.cache,\n\t\t\tsearchDirs: options.skillDirs || ['.claude/skills', join(homedir(), '.claude/skills')],\n\t\t\tlazyDiscovery: options.lazyDiscovery,\n\t\t});\n\t}\n\n\t// --- Error factories ---\n\n\tprotected override _createInvalidError(reason: string): Error {\n\t\treturn new InvalidSkillError(reason);\n\t}\n\n\tprotected override _createDuplicateError(name: string): Error {\n\t\treturn new DuplicateSkillError(name);\n\t}\n\n\tprotected override _createNotFoundError(name: string, action: string): Error {\n\t\treturn new SkillNotFoundError(name, action);\n\t}\n\n\t// --- Discovery ---\n\n\tprotected override _shouldSkipFile(fileName: string): boolean {\n\t\treturn fileName === '.DS_Store';\n\t}\n\n\tprotected override _parseFrontmatter(content: string): Partial<Skill> & { _error?: string } {\n\t\tconst frontmatter = this._extractFrontmatter(content);\n\t\tif (!frontmatter) {\n\t\t\treturn {};\n\t\t}\n\n\t\ttry {\n\t\t\tconst result: Partial<Skill> = {\n\t\t\t\tname: typeof frontmatter.name === 'string' ? frontmatter.name : undefined,\n\t\t\t\tdescription: typeof frontmatter.description === 'string' ? frontmatter.description : '',\n\t\t\t\tuser_invocable: frontmatter['user-invocable'] === true,\n\t\t\t\tallowed_tools: Array.isArray(frontmatter['allowed-tools'])\n\t\t\t\t\t? frontmatter['allowed-tools'].map(String)\n\t\t\t\t\t: undefined,\n\t\t\t};\n\n\t\t\tif (!result.name) {\n\t\t\t\treturn { _error: 'Missing required field: name' };\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tthis.log('Error parsing YAML frontmatter:', {\n\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t});\n\t\t\treturn { _error: 'YAML parse error' };\n\t\t}\n\t}\n\n\tprotected override _buildItem(parsed: Partial<Skill>): Skill | null {\n\t\tif (!parsed.name) {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tname: parsed.name,\n\t\t\tdescription: parsed.description || '',\n\t\t\tuser_invocable: parsed.user_invocable ?? false,\n\t\t\tallowed_tools: parsed.allowed_tools,\n\t\t};\n\t}\n\n\t// --- Backward-compatible aliases ---\n\n\tpublic addSkill(skill: Skill): void {\n\t\tthis.add(skill);\n\t}\n\n\t/** @deprecated Use `remove()` instead */\n\tpublic removeSkillByName(name: string): void {\n\t\tthis.remove(name);\n\t}\n\n\tpublic updateSkill(name: string, updates: Partial<Skill>): void {\n\t\tthis.update(name, updates);\n\t}\n\n\tpublic hasSkill(name: string): boolean {\n\t\treturn this.has(name);\n\t}\n\n\tpublic getSkill(name: string): Skill | undefined {\n\t\treturn this.get(name);\n\t}\n\n\tpublic setSkills(skills: Skill[]): void {\n\t\tthis.setAll(skills);\n\t}\n}\n"],"names":["SkillRegistry","BaseRegistry","options","join","homedir","reason","InvalidSkillError","name","DuplicateSkillError","action","SkillNotFoundError","fileName","content","frontmatter","result","undefined","Array","String","error","Error","parsed","skill","updates","skills"],"mappings":";;;;AAyDO,MAAMA,sBAAsBC;IACN,kBAAkB;QAAC;QAAO;QAAQ;KAAQ,CAAC;IAC3C,cAAc,QAAQ;IAElD,YAAYC,UAAgC,CAAC,CAAC,CAAE;QAC/C,KAAK,CAAC;YACL,QAAQA,QAAQ,MAAM;YACtB,OAAOA,QAAQ,KAAK;YACpB,YAAYA,QAAQ,SAAS,IAAI;gBAAC;gBAAkBC,KAAKC,WAAW;aAAkB;YACtF,eAAeF,QAAQ,aAAa;QACrC;IACD;IAImB,oBAAoBG,MAAc,EAAS;QAC7D,OAAO,IAAIC,kBAAkBD;IAC9B;IAEmB,sBAAsBE,IAAY,EAAS;QAC7D,OAAO,IAAIC,oBAAoBD;IAChC;IAEmB,qBAAqBA,IAAY,EAAEE,MAAc,EAAS;QAC5E,OAAO,IAAIC,mBAAmBH,MAAME;IACrC;IAImB,gBAAgBE,QAAgB,EAAW;QAC7D,OAAOA,AAAa,gBAAbA;IACR;IAEmB,kBAAkBC,OAAe,EAAwC;QAC3F,MAAMC,cAAc,IAAI,CAAC,mBAAmB,CAACD;QAC7C,IAAI,CAACC,aACJ,OAAO,CAAC;QAGT,IAAI;YACH,MAAMC,SAAyB;gBAC9B,MAAM,AAA4B,YAA5B,OAAOD,YAAY,IAAI,GAAgBA,YAAY,IAAI,GAAGE;gBAChE,aAAa,AAAmC,YAAnC,OAAOF,YAAY,WAAW,GAAgBA,YAAY,WAAW,GAAG;gBACrF,gBAAgBA,AAAkC,SAAlCA,WAAW,CAAC,iBAAiB;gBAC7C,eAAeG,MAAM,OAAO,CAACH,WAAW,CAAC,gBAAgB,IACtDA,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAACI,UACjCF;YACJ;YAEA,IAAI,CAACD,OAAO,IAAI,EACf,OAAO;gBAAE,QAAQ;YAA+B;YAGjD,OAAOA;QACR,EAAE,OAAOI,OAAO;YACf,IAAI,CAAC,GAAG,CAAC,mCAAmC;gBAC3C,OAAOA,iBAAiBC,QAAQD,MAAM,OAAO,GAAGD,OAAOC;YACxD;YACA,OAAO;gBAAE,QAAQ;YAAmB;QACrC;IACD;IAEmB,WAAWE,MAAsB,EAAgB;QACnE,IAAI,CAACA,OAAO,IAAI,EACf,OAAO;QAER,OAAO;YACN,MAAMA,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW,IAAI;YACnC,gBAAgBA,OAAO,cAAc,IAAI;YACzC,eAAeA,OAAO,aAAa;QACpC;IACD;IAIO,SAASC,KAAY,EAAQ;QACnC,IAAI,CAAC,GAAG,CAACA;IACV;IAGO,kBAAkBd,IAAY,EAAQ;QAC5C,IAAI,CAAC,MAAM,CAACA;IACb;IAEO,YAAYA,IAAY,EAAEe,OAAuB,EAAQ;QAC/D,IAAI,CAAC,MAAM,CAACf,MAAMe;IACnB;IAEO,SAASf,IAAY,EAAW;QACtC,OAAO,IAAI,CAAC,GAAG,CAACA;IACjB;IAEO,SAASA,IAAY,EAAqB;QAChD,OAAO,IAAI,CAAC,GAAG,CAACA;IACjB;IAEO,UAAUgB,MAAe,EAAQ;QACvC,IAAI,CAAC,MAAM,CAACA;IACb;AACD"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool registry for managing MCP tool CRUD operations.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the `ToolRegistry` class which manages the registration,
|
|
5
|
+
* retrieval, update, and removal of MCP tools. It supports optional caching
|
|
6
|
+
* for improved performance, filesystem discovery, and integrates with the logging system.
|
|
7
|
+
*
|
|
8
|
+
* @module registry
|
|
9
|
+
*/
|
|
10
|
+
import { DiscoveryCache } from '../cache/DiscoveryCache.js';
|
|
11
|
+
import type { Logger } from '../logger/StructuredLogger.js';
|
|
12
|
+
import type { Tool } from '../types/tool.js';
|
|
13
|
+
import { BaseRegistry } from './BaseRegistry.js';
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for creating a `ToolRegistry` instance.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const options: ToolRegistryOptions = {
|
|
20
|
+
* logger: new StructuredLogger({ context: 'ToolRegistry' }),
|
|
21
|
+
* cache: new DiscoveryCache({ ttl: 300000, maxSize: 100 }),
|
|
22
|
+
* toolDirs: ['./custom-tools', '~/.claude/tools'],
|
|
23
|
+
* lazyDiscovery: true
|
|
24
|
+
* };
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface ToolRegistryOptions {
|
|
28
|
+
/** Optional logger for diagnostics. */
|
|
29
|
+
logger?: Logger;
|
|
30
|
+
/** Optional cache for tool lookups. */
|
|
31
|
+
cache?: DiscoveryCache<Tool>;
|
|
32
|
+
/**
|
|
33
|
+
* Directory paths to search for tools.
|
|
34
|
+
* @default ['.claude/tools', '~/.claude/tools']
|
|
35
|
+
*/
|
|
36
|
+
toolDirs?: string[];
|
|
37
|
+
/**
|
|
38
|
+
* Enable lazy discovery (discover on first access instead of startup).
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
lazyDiscovery?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Registry for managing MCP tool operations.
|
|
45
|
+
*
|
|
46
|
+
* Extends `BaseRegistry<Tool>` with tool-specific frontmatter parsing
|
|
47
|
+
* and backward-compatible aliases (`addTool`, `removeTool`, etc.).
|
|
48
|
+
*/
|
|
49
|
+
export declare class ToolRegistry extends BaseRegistry<Tool> {
|
|
50
|
+
protected readonly _fileExtensions: string[];
|
|
51
|
+
protected readonly _entityName = "tool";
|
|
52
|
+
constructor(options?: ToolRegistryOptions);
|
|
53
|
+
protected _createInvalidError(reason: string): Error;
|
|
54
|
+
protected _createDuplicateError(name: string): Error;
|
|
55
|
+
protected _createNotFoundError(name: string, action: string): Error;
|
|
56
|
+
protected _shouldSkipFile(_fileName: string): boolean;
|
|
57
|
+
protected _parseFrontmatter(content: string): Partial<Tool> & {
|
|
58
|
+
_error?: string;
|
|
59
|
+
};
|
|
60
|
+
protected _buildItem(parsed: Partial<Tool>): Tool | null;
|
|
61
|
+
get(name: string): Tool | undefined;
|
|
62
|
+
addTool(tool: Tool): void;
|
|
63
|
+
removeTool(name: string): void;
|
|
64
|
+
updateTool(name: string, updates: Partial<Tool>): void;
|
|
65
|
+
hasTool(name: string): boolean;
|
|
66
|
+
getTool(name: string): Tool | undefined;
|
|
67
|
+
setTools(tools: Tool[]): void;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=ToolRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolRegistry.d.ts","sourceRoot":"","sources":["../../src/registry/ToolRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,mBAAmB;IACnC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uCAAuC;IACvC,KAAK,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,qBAAa,YAAa,SAAQ,YAAY,CAAC,IAAI,CAAC;IACnD,mBAA4B,eAAe,WAAgB;IAC3D,mBAA4B,WAAW,UAAU;gBAErC,OAAO,GAAE,mBAAwB;cAW1B,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK;cAI1C,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;cAI1C,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK;cAMzD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;cAI3C,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;cA0BvE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;IAajD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAY5C,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIzB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAItD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIvC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;CAGpC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { DuplicateToolError, InvalidToolError, ToolNotFoundError } from "../errors.js";
|
|
4
|
+
import { BaseRegistry } from "./BaseRegistry.js";
|
|
5
|
+
class ToolRegistry extends BaseRegistry {
|
|
6
|
+
_fileExtensions = [
|
|
7
|
+
'.tool.md'
|
|
8
|
+
];
|
|
9
|
+
_entityName = 'tool';
|
|
10
|
+
constructor(options = {}){
|
|
11
|
+
super({
|
|
12
|
+
logger: options.logger,
|
|
13
|
+
cache: options.cache,
|
|
14
|
+
searchDirs: options.toolDirs || [
|
|
15
|
+
'.claude/tools',
|
|
16
|
+
join(homedir(), '.claude/tools')
|
|
17
|
+
],
|
|
18
|
+
lazyDiscovery: options.lazyDiscovery
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
_createInvalidError(reason) {
|
|
22
|
+
return new InvalidToolError(reason);
|
|
23
|
+
}
|
|
24
|
+
_createDuplicateError(name) {
|
|
25
|
+
return new DuplicateToolError(name);
|
|
26
|
+
}
|
|
27
|
+
_createNotFoundError(name, action) {
|
|
28
|
+
return new ToolNotFoundError(name, action);
|
|
29
|
+
}
|
|
30
|
+
_shouldSkipFile(_fileName) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
_parseFrontmatter(content) {
|
|
34
|
+
const frontmatter = this._extractFrontmatter(content);
|
|
35
|
+
if (!frontmatter) return {
|
|
36
|
+
_error: 'No YAML frontmatter found'
|
|
37
|
+
};
|
|
38
|
+
try {
|
|
39
|
+
const result = {
|
|
40
|
+
name: 'string' == typeof frontmatter.name ? frontmatter.name : void 0,
|
|
41
|
+
description: 'string' == typeof frontmatter.description ? frontmatter.description : '',
|
|
42
|
+
inputSchema: frontmatter.inputSchema
|
|
43
|
+
};
|
|
44
|
+
if (!result.name) return {
|
|
45
|
+
_error: 'Missing required field: name'
|
|
46
|
+
};
|
|
47
|
+
if (!result.inputSchema) return {
|
|
48
|
+
_error: 'Missing required field: inputSchema'
|
|
49
|
+
};
|
|
50
|
+
return result;
|
|
51
|
+
} catch {
|
|
52
|
+
return {
|
|
53
|
+
_error: 'YAML parse error'
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
_buildItem(parsed) {
|
|
58
|
+
if (!parsed.name || !parsed.inputSchema) return null;
|
|
59
|
+
return {
|
|
60
|
+
name: parsed.name,
|
|
61
|
+
description: parsed.description || '',
|
|
62
|
+
inputSchema: parsed.inputSchema
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
get(name) {
|
|
66
|
+
if (this._cache) {
|
|
67
|
+
const cached = this._cache.get(`tool:${name}`);
|
|
68
|
+
if (cached && cached.length > 0) return cached[0];
|
|
69
|
+
}
|
|
70
|
+
return this._items.get(name);
|
|
71
|
+
}
|
|
72
|
+
addTool(tool) {
|
|
73
|
+
this.add(tool);
|
|
74
|
+
}
|
|
75
|
+
removeTool(name) {
|
|
76
|
+
this.remove(name);
|
|
77
|
+
}
|
|
78
|
+
updateTool(name, updates) {
|
|
79
|
+
this.update(name, updates);
|
|
80
|
+
}
|
|
81
|
+
hasTool(name) {
|
|
82
|
+
return this.has(name);
|
|
83
|
+
}
|
|
84
|
+
getTool(name) {
|
|
85
|
+
return this.get(name);
|
|
86
|
+
}
|
|
87
|
+
setTools(tools) {
|
|
88
|
+
this.setAll(tools);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export { ToolRegistry };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=ToolRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry/ToolRegistry.js","sources":["../../src/registry/ToolRegistry.ts"],"sourcesContent":["/**\n * Tool registry for managing MCP tool CRUD operations.\n *\n * This module provides the `ToolRegistry` class which manages the registration,\n * retrieval, update, and removal of MCP tools. It supports optional caching\n * for improved performance, filesystem discovery, and integrates with the logging system.\n *\n * @module registry\n */\n\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { DiscoveryCache } from '../cache/DiscoveryCache.js';\nimport { DuplicateToolError, InvalidToolError, ToolNotFoundError } from '../errors.js';\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { Tool } from '../types/tool.js';\nimport { BaseRegistry } from './BaseRegistry.js';\n\n/**\n * Configuration options for creating a `ToolRegistry` instance.\n *\n * @example\n * ```typescript\n * const options: ToolRegistryOptions = {\n * logger: new StructuredLogger({ context: 'ToolRegistry' }),\n * cache: new DiscoveryCache({ ttl: 300000, maxSize: 100 }),\n * toolDirs: ['./custom-tools', '~/.claude/tools'],\n * lazyDiscovery: true\n * };\n * ```\n */\nexport interface ToolRegistryOptions {\n\t/** Optional logger for diagnostics. */\n\tlogger?: Logger;\n\n\t/** Optional cache for tool lookups. */\n\tcache?: DiscoveryCache<Tool>;\n\n\t/**\n\t * Directory paths to search for tools.\n\t * @default ['.claude/tools', '~/.claude/tools']\n\t */\n\ttoolDirs?: string[];\n\n\t/**\n\t * Enable lazy discovery (discover on first access instead of startup).\n\t * @default false\n\t */\n\tlazyDiscovery?: boolean;\n}\n\n/**\n * Registry for managing MCP tool operations.\n *\n * Extends `BaseRegistry<Tool>` with tool-specific frontmatter parsing\n * and backward-compatible aliases (`addTool`, `removeTool`, etc.).\n */\nexport class ToolRegistry extends BaseRegistry<Tool> {\n\tprotected override readonly _fileExtensions = ['.tool.md'];\n\tprotected override readonly _entityName = 'tool';\n\n\tconstructor(options: ToolRegistryOptions = {}) {\n\t\tsuper({\n\t\t\tlogger: options.logger,\n\t\t\tcache: options.cache,\n\t\t\tsearchDirs: options.toolDirs || ['.claude/tools', join(homedir(), '.claude/tools')],\n\t\t\tlazyDiscovery: options.lazyDiscovery,\n\t\t});\n\t}\n\n\t// --- Error factories ---\n\n\tprotected override _createInvalidError(reason: string): Error {\n\t\treturn new InvalidToolError(reason);\n\t}\n\n\tprotected override _createDuplicateError(name: string): Error {\n\t\treturn new DuplicateToolError(name);\n\t}\n\n\tprotected override _createNotFoundError(name: string, action: string): Error {\n\t\treturn new ToolNotFoundError(name, action);\n\t}\n\n\t// --- Discovery ---\n\n\tprotected override _shouldSkipFile(_fileName: string): boolean {\n\t\treturn false;\n\t}\n\n\tprotected override _parseFrontmatter(content: string): Partial<Tool> & { _error?: string } {\n\t\tconst frontmatter = this._extractFrontmatter(content);\n\t\tif (!frontmatter) {\n\t\t\treturn { _error: 'No YAML frontmatter found' };\n\t\t}\n\n\t\ttry {\n\t\t\tconst result: Partial<Tool> = {\n\t\t\t\tname: typeof frontmatter.name === 'string' ? frontmatter.name : undefined,\n\t\t\t\tdescription: typeof frontmatter.description === 'string' ? frontmatter.description : '',\n\t\t\t\tinputSchema: frontmatter.inputSchema as Tool['inputSchema'],\n\t\t\t};\n\n\t\t\tif (!result.name) {\n\t\t\t\treturn { _error: 'Missing required field: name' };\n\t\t\t}\n\t\t\tif (!result.inputSchema) {\n\t\t\t\treturn { _error: 'Missing required field: inputSchema' };\n\t\t\t}\n\n\t\t\treturn result;\n\t\t} catch {\n\t\t\treturn { _error: 'YAML parse error' };\n\t\t}\n\t}\n\n\tprotected override _buildItem(parsed: Partial<Tool>): Tool | null {\n\t\tif (!parsed.name || !parsed.inputSchema) {\n\t\t\treturn null;\n\t\t}\n\t\treturn {\n\t\t\tname: parsed.name,\n\t\t\tdescription: parsed.description || '',\n\t\t\tinputSchema: parsed.inputSchema,\n\t\t};\n\t}\n\n\t// --- Tool-specific get with cache lookup ---\n\n\tpublic override get(name: string): Tool | undefined {\n\t\tif (this._cache) {\n\t\t\tconst cached = this._cache.get(`tool:${name}`);\n\t\t\tif (cached && cached.length > 0) {\n\t\t\t\treturn cached[0];\n\t\t\t}\n\t\t}\n\t\treturn this._items.get(name);\n\t}\n\n\t// --- Backward-compatible aliases ---\n\n\tpublic addTool(tool: Tool): void {\n\t\tthis.add(tool);\n\t}\n\n\tpublic removeTool(name: string): void {\n\t\tthis.remove(name);\n\t}\n\n\tpublic updateTool(name: string, updates: Partial<Tool>): void {\n\t\tthis.update(name, updates);\n\t}\n\n\tpublic hasTool(name: string): boolean {\n\t\treturn this.has(name);\n\t}\n\n\tpublic getTool(name: string): Tool | undefined {\n\t\treturn this.get(name);\n\t}\n\n\tpublic setTools(tools: Tool[]): void {\n\t\tthis.setAll(tools);\n\t}\n}\n"],"names":["ToolRegistry","BaseRegistry","options","join","homedir","reason","InvalidToolError","name","DuplicateToolError","action","ToolNotFoundError","_fileName","content","frontmatter","result","undefined","parsed","cached","tool","updates","tools"],"mappings":";;;;AAyDO,MAAMA,qBAAqBC;IACL,kBAAkB;QAAC;KAAW,CAAC;IAC/B,cAAc,OAAO;IAEjD,YAAYC,UAA+B,CAAC,CAAC,CAAE;QAC9C,KAAK,CAAC;YACL,QAAQA,QAAQ,MAAM;YACtB,OAAOA,QAAQ,KAAK;YACpB,YAAYA,QAAQ,QAAQ,IAAI;gBAAC;gBAAiBC,KAAKC,WAAW;aAAiB;YACnF,eAAeF,QAAQ,aAAa;QACrC;IACD;IAImB,oBAAoBG,MAAc,EAAS;QAC7D,OAAO,IAAIC,iBAAiBD;IAC7B;IAEmB,sBAAsBE,IAAY,EAAS;QAC7D,OAAO,IAAIC,mBAAmBD;IAC/B;IAEmB,qBAAqBA,IAAY,EAAEE,MAAc,EAAS;QAC5E,OAAO,IAAIC,kBAAkBH,MAAME;IACpC;IAImB,gBAAgBE,SAAiB,EAAW;QAC9D,OAAO;IACR;IAEmB,kBAAkBC,OAAe,EAAuC;QAC1F,MAAMC,cAAc,IAAI,CAAC,mBAAmB,CAACD;QAC7C,IAAI,CAACC,aACJ,OAAO;YAAE,QAAQ;QAA4B;QAG9C,IAAI;YACH,MAAMC,SAAwB;gBAC7B,MAAM,AAA4B,YAA5B,OAAOD,YAAY,IAAI,GAAgBA,YAAY,IAAI,GAAGE;gBAChE,aAAa,AAAmC,YAAnC,OAAOF,YAAY,WAAW,GAAgBA,YAAY,WAAW,GAAG;gBACrF,aAAaA,YAAY,WAAW;YACrC;YAEA,IAAI,CAACC,OAAO,IAAI,EACf,OAAO;gBAAE,QAAQ;YAA+B;YAEjD,IAAI,CAACA,OAAO,WAAW,EACtB,OAAO;gBAAE,QAAQ;YAAsC;YAGxD,OAAOA;QACR,EAAE,OAAM;YACP,OAAO;gBAAE,QAAQ;YAAmB;QACrC;IACD;IAEmB,WAAWE,MAAqB,EAAe;QACjE,IAAI,CAACA,OAAO,IAAI,IAAI,CAACA,OAAO,WAAW,EACtC,OAAO;QAER,OAAO;YACN,MAAMA,OAAO,IAAI;YACjB,aAAaA,OAAO,WAAW,IAAI;YACnC,aAAaA,OAAO,WAAW;QAChC;IACD;IAIgB,IAAIT,IAAY,EAAoB;QACnD,IAAI,IAAI,CAAC,MAAM,EAAE;YAChB,MAAMU,SAAS,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAEV,MAAM;YAC7C,IAAIU,UAAUA,OAAO,MAAM,GAAG,GAC7B,OAAOA,MAAM,CAAC,EAAE;QAElB;QACA,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAACV;IACxB;IAIO,QAAQW,IAAU,EAAQ;QAChC,IAAI,CAAC,GAAG,CAACA;IACV;IAEO,WAAWX,IAAY,EAAQ;QACrC,IAAI,CAAC,MAAM,CAACA;IACb;IAEO,WAAWA,IAAY,EAAEY,OAAsB,EAAQ;QAC7D,IAAI,CAAC,MAAM,CAACZ,MAAMY;IACnB;IAEO,QAAQZ,IAAY,EAAW;QACrC,OAAO,IAAI,CAAC,GAAG,CAACA;IACjB;IAEO,QAAQA,IAAY,EAAoB;QAC9C,OAAO,IAAI,CAAC,GAAG,CAACA;IACjB;IAEO,SAASa,KAAa,EAAQ;QACpC,IAAI,CAAC,MAAM,CAACA;IACb;AACD"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input sanitization for the sequential thinking MCP tool.
|
|
3
|
+
*
|
|
4
|
+
* Provides pure functions for stripping dangerous content from free-text fields.
|
|
5
|
+
* Uses a targeted blocklist approach: only removes HTML tags that can execute code,
|
|
6
|
+
* while preserving generic angle-bracket content like TypeScript generics (`Array<string>`),
|
|
7
|
+
* mathematical comparisons (`x < 5`), and markdown formatting.
|
|
8
|
+
*
|
|
9
|
+
* @module sanitize
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Strip dangerous HTML tags that can execute JavaScript or load external resources.
|
|
13
|
+
*
|
|
14
|
+
* Uses a targeted blocklist to remove only tags known to be dangerous (script, iframe,
|
|
15
|
+
* img, style, svg, embed, object, link, meta, base, form) while preserving safe
|
|
16
|
+
* angle-bracket content like TypeScript generics and mathematical comparisons.
|
|
17
|
+
*
|
|
18
|
+
* @param input - The string to sanitize
|
|
19
|
+
* @returns The input with dangerous HTML tags removed
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* stripDangerousTags('<script>alert(1)</script>hello'); // 'hello'
|
|
24
|
+
* stripDangerousTags('Array<string>'); // 'Array<string>' (preserved)
|
|
25
|
+
* stripDangerousTags('x < 5 && y > 3'); // 'x < 5 && y > 3' (preserved)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function stripDangerousTags(input: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Strip null bytes and C0 control characters from a string.
|
|
31
|
+
*
|
|
32
|
+
* Removes characters in the range U+0000–U+0008, U+000B, U+000C, U+000E–U+001F.
|
|
33
|
+
* Preserves tab (`\t`, U+0009), newline (`\n`, U+000A), and carriage return (`\r`, U+000D)
|
|
34
|
+
* as these are commonly used in thought content.
|
|
35
|
+
*
|
|
36
|
+
* @param input - The string to sanitize
|
|
37
|
+
* @returns The input with control characters removed
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* stripControlChars('a\x00b'); // 'ab'
|
|
42
|
+
* stripControlChars('a\tb\nc'); // 'a\tb\nc' (tab and newline preserved)
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function stripControlChars(input: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Sanitize a string by stripping both control characters and dangerous HTML tags.
|
|
48
|
+
*
|
|
49
|
+
* Composes {@link stripControlChars} and {@link stripDangerousTags} in sequence.
|
|
50
|
+
* Does not trim whitespace — thought content may depend on leading/trailing spaces.
|
|
51
|
+
* Always returns a string, even if the input is empty.
|
|
52
|
+
*
|
|
53
|
+
* @param input - The string to sanitize
|
|
54
|
+
* @returns The fully sanitized string
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* sanitizeString('<script>alert(1)</script>hello\x00world'); // 'helloworld'
|
|
59
|
+
* sanitizeString('Array<string>\x00'); // 'Array<string>'
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function sanitizeString(input: string): string;
|
|
63
|
+
//# sourceMappingURL=sanitize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|