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,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool types for MCP tool recommendations and definitions.
|
|
3
|
+
*
|
|
4
|
+
* @module types/tool
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Represents a recommended MCP tool with associated metadata.
|
|
8
|
+
*
|
|
9
|
+
* Tool recommendations are generated by the sequential thinking process to suggest
|
|
10
|
+
* appropriate tools for completing specific tasks. Each recommendation includes
|
|
11
|
+
* a confidence score and rationale to help the LLM make informed decisions.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const recommendation: ToolRecommendation = {
|
|
16
|
+
* tool_name: 'mcp__tavily-mcp__tavily-search',
|
|
17
|
+
* confidence: 0.9,
|
|
18
|
+
* rationale: 'Best for searching current web content',
|
|
19
|
+
* priority: 1,
|
|
20
|
+
* suggested_inputs: { query: 'TypeScript documentation' },
|
|
21
|
+
* alternatives: ['mcp__web_reader__webReader']
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export interface ToolRecommendation {
|
|
26
|
+
/** The unique name/identifier of the recommended tool. */
|
|
27
|
+
tool_name: string;
|
|
28
|
+
/** Confidence score from 0-1 indicating how appropriate this tool is for the current task. */
|
|
29
|
+
confidence: number;
|
|
30
|
+
/** Explanation of why this tool is recommended and how it addresses the current need. */
|
|
31
|
+
rationale: string;
|
|
32
|
+
/** Order in the recommendation sequence (lower numbers = higher priority). */
|
|
33
|
+
priority: number;
|
|
34
|
+
/** Optional suggested parameter values for the tool based on the current context. */
|
|
35
|
+
suggested_inputs?: Record<string, unknown>;
|
|
36
|
+
/** Alternative tools that could be used if the primary recommendation is not available. */
|
|
37
|
+
alternatives?: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Defines an MCP tool that can be recommended and invoked.
|
|
41
|
+
*
|
|
42
|
+
* Tools are the basic building blocks for performing operations
|
|
43
|
+
* such as reading files, running commands, or making API calls.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const tool: Tool = {
|
|
48
|
+
* name: 'Read',
|
|
49
|
+
* description: 'Read a file from the filesystem',
|
|
50
|
+
* inputSchema: {
|
|
51
|
+
* type: 'object',
|
|
52
|
+
* properties: {
|
|
53
|
+
* file_path: { type: 'string' }
|
|
54
|
+
* },
|
|
55
|
+
* required: ['file_path']
|
|
56
|
+
* }
|
|
57
|
+
* };
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export interface Tool {
|
|
61
|
+
/** Unique identifier for the tool. */
|
|
62
|
+
name: string;
|
|
63
|
+
/** Human-readable description of what the tool does. */
|
|
64
|
+
description: string;
|
|
65
|
+
/** JSON Schema defining the parameters the tool accepts. */
|
|
66
|
+
inputSchema: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/types/tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAElB,8FAA8F;IAC9F,UAAU,EAAE,MAAM,CAAC;IAEnB,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAC;IAElB,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IAEjB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE3C,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,IAAI;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IAEpB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File system watcher for skill directory changes with registry integration.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the `SkillWatcher` class which monitors configured
|
|
5
|
+
* skill directories for file changes using chokidar. When changes are detected,
|
|
6
|
+
* it automatically triggers skill re-discovery to keep the registry in sync.
|
|
7
|
+
*
|
|
8
|
+
* @module watcher
|
|
9
|
+
*/
|
|
10
|
+
import type { Logger } from '../logger/StructuredLogger.js';
|
|
11
|
+
import type { SkillRegistry } from '../registry/SkillRegistry.js';
|
|
12
|
+
/**
|
|
13
|
+
* File system watcher for skill directories with registry integration.
|
|
14
|
+
*
|
|
15
|
+
* This class monitors configured skill directories for file system changes
|
|
16
|
+
* and automatically triggers skill re-discovery when changes are detected.
|
|
17
|
+
* It integrates with a `SkillRegistry` to keep the registered skills in sync
|
|
18
|
+
* with the filesystem.
|
|
19
|
+
*
|
|
20
|
+
* @remarks
|
|
21
|
+
* **Watched Events:**
|
|
22
|
+
* - `add` - A new skill file was added (triggers re-discovery)
|
|
23
|
+
* - `change` - A skill file was modified (triggers re-discovery)
|
|
24
|
+
* - `unlink` - A skill file was removed (attempts to remove from registry)
|
|
25
|
+
*
|
|
26
|
+
* **Watched Directories:**
|
|
27
|
+
* - `.claude/skills` (project-local)
|
|
28
|
+
* - `~/.claude/skills` (user-global)
|
|
29
|
+
*
|
|
30
|
+
* **Ignored Paths:**
|
|
31
|
+
* - `node_modules` directories are ignored
|
|
32
|
+
*
|
|
33
|
+
* **Watcher Behavior:**
|
|
34
|
+
* - Uses persistent mode to continue watching even if files are temporarily deleted
|
|
35
|
+
* - Automatically starts watching when instantiated
|
|
36
|
+
* - File additions/modifications trigger full skill re-discovery
|
|
37
|
+
* - File removals attempt to remove the specific skill from the registry
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { SkillWatcher } from './SkillWatcher.js';
|
|
42
|
+
* import { SkillRegistry } from './registry/SkillRegistry.js';
|
|
43
|
+
*
|
|
44
|
+
* const registry = new SkillRegistry();
|
|
45
|
+
* const watcher = new SkillWatcher(registry);
|
|
46
|
+
* // Watcher automatically starts monitoring skill directories
|
|
47
|
+
*
|
|
48
|
+
* // When a skill file is added/modified, re-discovery is triggered
|
|
49
|
+
* // When a skill file is deleted, it's removed from the registry
|
|
50
|
+
*
|
|
51
|
+
* // When done, stop the watcher
|
|
52
|
+
* watcher.stop();
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare class SkillWatcher {
|
|
56
|
+
private skillRegistry;
|
|
57
|
+
/** The underlying chokidar file system watcher. */
|
|
58
|
+
private _watcher;
|
|
59
|
+
private _logger;
|
|
60
|
+
constructor(skillRegistry: SkillRegistry, logger?: Logger);
|
|
61
|
+
/**
|
|
62
|
+
* Create a no-op logger when none is provided.
|
|
63
|
+
*/
|
|
64
|
+
private _createNoopLogger;
|
|
65
|
+
/**
|
|
66
|
+
* Sets up the file system watcher for skill directories.
|
|
67
|
+
*
|
|
68
|
+
* Configures chokidar to watch the skill directories and sets up
|
|
69
|
+
* event handlers for file additions, modifications, and removals.
|
|
70
|
+
*
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
private setupWatcher;
|
|
74
|
+
/**
|
|
75
|
+
* Handles the event when a skill file is removed.
|
|
76
|
+
*
|
|
77
|
+
* This method extracts the skill name from the file path and attempts
|
|
78
|
+
* to remove it from the skill registry. If the skill name cannot be
|
|
79
|
+
* extracted, or the skill is not found in the registry, the error is logged
|
|
80
|
+
* but does not throw.
|
|
81
|
+
*
|
|
82
|
+
* @param skillPath - The file path of the removed skill file
|
|
83
|
+
* @returns A Promise that resolves when handling is complete
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // When 'commit.md' is removed, this will attempt to remove
|
|
88
|
+
* // the skill named 'commit' from the registry
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
private handleSkillRemoval;
|
|
92
|
+
/**
|
|
93
|
+
* Internal logging method.
|
|
94
|
+
* @param message - The message to log
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
private log;
|
|
98
|
+
/**
|
|
99
|
+
* Extracts the skill name from a file path.
|
|
100
|
+
*
|
|
101
|
+
* This method takes a file path and extracts the filename without
|
|
102
|
+
* extension, which is used as the skill name. For example:
|
|
103
|
+
* - `.claude/skills/commit.md` -> `commit.md`
|
|
104
|
+
* - `.claude/skills/review-pr.yml` -> `review-pr.yml`
|
|
105
|
+
*
|
|
106
|
+
* @param skillPath - The file path to extract from
|
|
107
|
+
* @returns The extracted filename (with extension), or null if extraction fails
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* extractSkillNameFromPath('/path/to/skills/commit.md')
|
|
112
|
+
* // Returns: 'commit.md'
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
private extractSkillNameFromPath;
|
|
116
|
+
/**
|
|
117
|
+
* Stops watching skill directories and cleans up resources.
|
|
118
|
+
*
|
|
119
|
+
* This method closes the underlying chokidar watcher and releases
|
|
120
|
+
* file system resources. After calling this method, the watcher
|
|
121
|
+
* cannot be restarted.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* const watcher = new SkillWatcher(registry);
|
|
126
|
+
* // ... use watcher ...
|
|
127
|
+
* watcher.stop();
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
stop(): void;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=SkillWatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkillWatcher.d.ts","sourceRoot":"","sources":["../../src/watchers/SkillWatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,YAAY;IAMvB,OAAO,CAAC,aAAa;IALtB,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,OAAO,CAAS;gBAGf,aAAa,EAAE,aAAa,EACpC,MAAM,CAAC,EAAE,MAAM;IAMhB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAiCpB;;;;;;;;;;;;;;;;OAgBG;YACW,kBAAkB;IAchC;;;;OAIG;IACH,OAAO,CAAC,GAAG;IAQX;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,wBAAwB;IAKhC;;;;;;;;;;;;;OAaG;IACI,IAAI,IAAI,IAAI;CAMnB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { watch } from "chokidar";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
class SkillWatcher {
|
|
5
|
+
skillRegistry;
|
|
6
|
+
_watcher = null;
|
|
7
|
+
_logger;
|
|
8
|
+
constructor(skillRegistry, logger){
|
|
9
|
+
this.skillRegistry = skillRegistry;
|
|
10
|
+
this._logger = logger ?? this._createNoopLogger();
|
|
11
|
+
this.setupWatcher();
|
|
12
|
+
}
|
|
13
|
+
_createNoopLogger() {
|
|
14
|
+
return {
|
|
15
|
+
info: ()=>{},
|
|
16
|
+
warn: ()=>{},
|
|
17
|
+
error: ()=>{},
|
|
18
|
+
debug: ()=>{},
|
|
19
|
+
setLevel: ()=>{},
|
|
20
|
+
getLevel: ()=>'info'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
setupWatcher() {
|
|
24
|
+
const skillDirs = [
|
|
25
|
+
'.claude/skills',
|
|
26
|
+
join(homedir(), '.claude/skills')
|
|
27
|
+
];
|
|
28
|
+
this._watcher = watch(skillDirs, {
|
|
29
|
+
ignored: [
|
|
30
|
+
/node_modules/,
|
|
31
|
+
/\.DS_Store$/
|
|
32
|
+
],
|
|
33
|
+
persistent: true
|
|
34
|
+
});
|
|
35
|
+
this._watcher.on('add', async (path)=>{
|
|
36
|
+
if (!path.includes('.DS_Store')) this.log(`Skill added: ${path.split('/').pop()}`);
|
|
37
|
+
await this.skillRegistry.discoverAsync();
|
|
38
|
+
});
|
|
39
|
+
this._watcher.on('change', async (path)=>{
|
|
40
|
+
if (!path.includes('.DS_Store')) this.log(`Skill modified: ${path.split('/').pop()}`);
|
|
41
|
+
await this.skillRegistry.discoverAsync();
|
|
42
|
+
});
|
|
43
|
+
this._watcher.on('unlink', async (path)=>{
|
|
44
|
+
if (!path.includes('.DS_Store')) this.log(`Skill removed: ${path.split('/').pop()}`);
|
|
45
|
+
this.handleSkillRemoval(path);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async handleSkillRemoval(skillPath) {
|
|
49
|
+
const skillName = this.extractSkillNameFromPath(skillPath);
|
|
50
|
+
if (skillName) try {
|
|
51
|
+
this.skillRegistry.removeSkillByName(skillName);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error(`Failed to remove skill ${skillName}:`, error instanceof Error ? error.message : String(error));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
log(message) {
|
|
57
|
+
if ('true' !== process.env.WATCHER_VERBOSE) return;
|
|
58
|
+
this._logger.error(`[Watcher] ${message}`);
|
|
59
|
+
}
|
|
60
|
+
extractSkillNameFromPath(skillPath) {
|
|
61
|
+
const parts = skillPath.split(/[/\\]/);
|
|
62
|
+
return parts[parts.length - 1] || null;
|
|
63
|
+
}
|
|
64
|
+
stop() {
|
|
65
|
+
if (this._watcher) {
|
|
66
|
+
this._watcher.close();
|
|
67
|
+
this._watcher = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export { SkillWatcher };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=SkillWatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchers/SkillWatcher.js","sources":["../../src/watchers/SkillWatcher.ts"],"sourcesContent":["/**\n * File system watcher for skill directory changes with registry integration.\n *\n * This module provides the `SkillWatcher` class which monitors configured\n * skill directories for file changes using chokidar. When changes are detected,\n * it automatically triggers skill re-discovery to keep the registry in sync.\n *\n * @module watcher\n */\n\nimport { watch, type FSWatcher } from 'chokidar';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { SkillRegistry } from '../registry/SkillRegistry.js';\n\n/**\n * File system watcher for skill directories with registry integration.\n *\n * This class monitors configured skill directories for file system changes\n * and automatically triggers skill re-discovery when changes are detected.\n * It integrates with a `SkillRegistry` to keep the registered skills in sync\n * with the filesystem.\n *\n * @remarks\n * **Watched Events:**\n * - `add` - A new skill file was added (triggers re-discovery)\n * - `change` - A skill file was modified (triggers re-discovery)\n * - `unlink` - A skill file was removed (attempts to remove from registry)\n *\n * **Watched Directories:**\n * - `.claude/skills` (project-local)\n * - `~/.claude/skills` (user-global)\n *\n * **Ignored Paths:**\n * - `node_modules` directories are ignored\n *\n * **Watcher Behavior:**\n * - Uses persistent mode to continue watching even if files are temporarily deleted\n * - Automatically starts watching when instantiated\n * - File additions/modifications trigger full skill re-discovery\n * - File removals attempt to remove the specific skill from the registry\n *\n * @example\n * ```typescript\n * import { SkillWatcher } from './SkillWatcher.js';\n * import { SkillRegistry } from './registry/SkillRegistry.js';\n *\n * const registry = new SkillRegistry();\n * const watcher = new SkillWatcher(registry);\n * // Watcher automatically starts monitoring skill directories\n *\n * // When a skill file is added/modified, re-discovery is triggered\n * // When a skill file is deleted, it's removed from the registry\n *\n * // When done, stop the watcher\n * watcher.stop();\n * ```\n */\nexport class SkillWatcher {\n\t/** The underlying chokidar file system watcher. */\n\tprivate _watcher: FSWatcher | null = null;\n\tprivate _logger: Logger;\n\n\tconstructor(\n\t\tprivate skillRegistry: SkillRegistry,\n\t\tlogger?: Logger\n\t) {\n\t\tthis._logger = logger ?? this._createNoopLogger();\n\t\tthis.setupWatcher();\n\t}\n\n\t/**\n\t * Create a no-op logger when none is provided.\n\t */\n\tprivate _createNoopLogger(): Logger {\n\t\treturn {\n\t\t\tinfo: () => {},\n\t\t\twarn: () => {},\n\t\t\terror: () => {},\n\t\t\tdebug: () => {},\n\t\t\tsetLevel: () => {},\n\t\t\tgetLevel: () => 'info',\n\t\t};\n\t}\n\n\t/**\n\t * Sets up the file system watcher for skill directories.\n\t *\n\t * Configures chokidar to watch the skill directories and sets up\n\t * event handlers for file additions, modifications, and removals.\n\t *\n\t * @private\n\t */\n\tprivate setupWatcher(): void {\n\t\tconst skillDirs = ['.claude/skills', join(homedir(), '.claude/skills')];\n\n\t\tthis._watcher = watch(skillDirs, {\n\t\t\tignored: [/node_modules/, /\\.DS_Store$/],\n\t\t\tpersistent: true,\n\t\t});\n\n\t\tthis._watcher.on('add', async (path) => {\n\t\t\t// Only log if not .DS_Store\n\t\t\tif (!path.includes('.DS_Store')) {\n\t\t\t\tthis.log(`Skill added: ${path.split('/').pop()}`);\n\t\t\t}\n\t\t\tawait this.skillRegistry.discoverAsync();\n\t\t});\n\n\t\tthis._watcher.on('change', async (path) => {\n\t\t\t// Only log if not .DS_Store\n\t\t\tif (!path.includes('.DS_Store')) {\n\t\t\t\tthis.log(`Skill modified: ${path.split('/').pop()}`);\n\t\t\t}\n\t\t\tawait this.skillRegistry.discoverAsync();\n\t\t});\n\n\t\tthis._watcher.on('unlink', async (path) => {\n\t\t\t// Only log if not .DS_Store\n\t\t\tif (!path.includes('.DS_Store')) {\n\t\t\t\tthis.log(`Skill removed: ${path.split('/').pop()}`);\n\t\t\t}\n\t\t\tthis.handleSkillRemoval(path);\n\t\t});\n\t}\n\n\t/**\n\t * Handles the event when a skill file is removed.\n\t *\n\t * This method extracts the skill name from the file path and attempts\n\t * to remove it from the skill registry. If the skill name cannot be\n\t * extracted, or the skill is not found in the registry, the error is logged\n\t * but does not throw.\n\t *\n\t * @param skillPath - The file path of the removed skill file\n\t * @returns A Promise that resolves when handling is complete\n\t *\n\t * @example\n\t * ```typescript\n\t * // When 'commit.md' is removed, this will attempt to remove\n\t * // the skill named 'commit' from the registry\n\t * ```\n\t */\n\tprivate async handleSkillRemoval(skillPath: string): Promise<void> {\n\t\tconst skillName = this.extractSkillNameFromPath(skillPath);\n\t\tif (skillName) {\n\t\t\ttry {\n\t\t\t\tthis.skillRegistry.removeSkillByName(skillName);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`Failed to remove skill ${skillName}:`,\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Internal logging method.\n\t * @param message - The message to log\n\t * @private\n\t */\n\tprivate log(message: string): void {\n\t\t// Optional: check environment variable to disable watcher logs\n\t\tif (process.env.WATCHER_VERBOSE !== 'true') {\n\t\t\treturn;\n\t\t}\n\t\tthis._logger.error(`[Watcher] ${message}`);\n\t}\n\n\t/**\n\t * Extracts the skill name from a file path.\n\t *\n\t * This method takes a file path and extracts the filename without\n\t * extension, which is used as the skill name. For example:\n\t * - `.claude/skills/commit.md` -> `commit.md`\n\t * - `.claude/skills/review-pr.yml` -> `review-pr.yml`\n\t *\n\t * @param skillPath - The file path to extract from\n\t * @returns The extracted filename (with extension), or null if extraction fails\n\t *\n\t * @example\n\t * ```typescript\n\t * extractSkillNameFromPath('/path/to/skills/commit.md')\n\t * // Returns: 'commit.md'\n\t * ```\n\t */\n\tprivate extractSkillNameFromPath(skillPath: string): string | null {\n\t\tconst parts = skillPath.split(/[/\\\\]/);\n\t\treturn parts[parts.length - 1] || null;\n\t}\n\n\t/**\n\t * Stops watching skill directories and cleans up resources.\n\t *\n\t * This method closes the underlying chokidar watcher and releases\n\t * file system resources. After calling this method, the watcher\n\t * cannot be restarted.\n\t *\n\t * @example\n\t * ```typescript\n\t * const watcher = new SkillWatcher(registry);\n\t * // ... use watcher ...\n\t * watcher.stop();\n\t * ```\n\t */\n\tpublic stop(): void {\n\t\tif (this._watcher) {\n\t\t\tthis._watcher.close();\n\t\t\tthis._watcher = null;\n\t\t}\n\t}\n}\n"],"names":["SkillWatcher","skillRegistry","logger","skillDirs","join","homedir","watch","path","skillPath","skillName","error","console","Error","String","message","process","parts"],"mappings":";;;AA2DO,MAAMA;;IAEJ,WAA6B,KAAK;IAClC,QAAgB;IAExB,YACSC,aAA4B,EACpCC,MAAe,CACd;aAFOD,aAAa,GAAbA;QAGR,IAAI,CAAC,OAAO,GAAGC,UAAU,IAAI,CAAC,iBAAiB;QAC/C,IAAI,CAAC,YAAY;IAClB;IAKQ,oBAA4B;QACnC,OAAO;YACN,MAAM,KAAO;YACb,MAAM,KAAO;YACb,OAAO,KAAO;YACd,OAAO,KAAO;YACd,UAAU,KAAO;YACjB,UAAU,IAAM;QACjB;IACD;IAUQ,eAAqB;QAC5B,MAAMC,YAAY;YAAC;YAAkBC,KAAKC,WAAW;SAAkB;QAEvE,IAAI,CAAC,QAAQ,GAAGC,MAAMH,WAAW;YAChC,SAAS;gBAAC;gBAAgB;aAAc;YACxC,YAAY;QACb;QAEA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,OAAOI;YAE9B,IAAI,CAACA,KAAK,QAAQ,CAAC,cAClB,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,EAAEA,KAAK,KAAK,CAAC,KAAK,GAAG,IAAI;YAEjD,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa;QACvC;QAEA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,OAAOA;YAEjC,IAAI,CAACA,KAAK,QAAQ,CAAC,cAClB,IAAI,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAEA,KAAK,KAAK,CAAC,KAAK,GAAG,IAAI;YAEpD,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa;QACvC;QAEA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,OAAOA;YAEjC,IAAI,CAACA,KAAK,QAAQ,CAAC,cAClB,IAAI,CAAC,GAAG,CAAC,CAAC,eAAe,EAAEA,KAAK,KAAK,CAAC,KAAK,GAAG,IAAI;YAEnD,IAAI,CAAC,kBAAkB,CAACA;QACzB;IACD;IAmBA,MAAc,mBAAmBC,SAAiB,EAAiB;QAClE,MAAMC,YAAY,IAAI,CAAC,wBAAwB,CAACD;QAChD,IAAIC,WACH,IAAI;YACH,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAACA;QACtC,EAAE,OAAOC,OAAO;YACfC,QAAQ,KAAK,CACZ,CAAC,uBAAuB,EAAEF,UAAU,CAAC,CAAC,EACtCC,iBAAiBE,QAAQF,MAAM,OAAO,GAAGG,OAAOH;QAElD;IAEF;IAOQ,IAAII,OAAe,EAAQ;QAElC,IAAIC,AAAgC,WAAhCA,QAAQ,GAAG,CAAC,eAAe,EAC9B;QAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,UAAU,EAAED,SAAS;IAC1C;IAmBQ,yBAAyBN,SAAiB,EAAiB;QAClE,MAAMQ,QAAQR,UAAU,KAAK,CAAC;QAC9B,OAAOQ,KAAK,CAACA,MAAM,MAAM,GAAG,EAAE,IAAI;IACnC;IAgBO,OAAa;QACnB,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,QAAQ,CAAC,KAAK;YACnB,IAAI,CAAC,QAAQ,GAAG;QACjB;IACD;AACD"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File system watcher for tool directory changes.
|
|
3
|
+
*
|
|
4
|
+
* This module provides the `ToolWatcher` class which monitors configured
|
|
5
|
+
* tool directories for file changes using chokidar. It watches for
|
|
6
|
+
* file additions and removals to enable dynamic tool discovery and registration.
|
|
7
|
+
*
|
|
8
|
+
* @module watcher
|
|
9
|
+
*/
|
|
10
|
+
import type { Logger } from '../logger/StructuredLogger.js';
|
|
11
|
+
import type { ToolRegistry } from '../registry/ToolRegistry.js';
|
|
12
|
+
/**
|
|
13
|
+
* File system watcher for tool directories.
|
|
14
|
+
*
|
|
15
|
+
* This class monitors configured tool directories for file system changes,
|
|
16
|
+
* watching for tool file additions and removals. When tool files are added
|
|
17
|
+
* or removed, it automatically updates the tool registry.
|
|
18
|
+
*
|
|
19
|
+
* The watched directories are:
|
|
20
|
+
* - `.claude/tools` (project-local)
|
|
21
|
+
* - `~/.claude/tools` (user-global)
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* **Watched Events:**
|
|
25
|
+
* - `add` - A new tool file was added (triggers rediscovery)
|
|
26
|
+
* - `unlink` - A tool file was removed (unregisters the tool)
|
|
27
|
+
*
|
|
28
|
+
* **Ignored Paths:**
|
|
29
|
+
* - `node_modules` directories are ignored
|
|
30
|
+
*
|
|
31
|
+
* **Watcher Behavior:**
|
|
32
|
+
* - Uses persistent mode to continue watching even if files are temporarily deleted
|
|
33
|
+
* - Automatically starts watching when instantiated
|
|
34
|
+
* - On file add: Triggers tool rediscovery to pick up new tools
|
|
35
|
+
* - On file remove: Extracts tool name and unregisters it
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* import { ToolWatcher } from './ToolWatcher.js';
|
|
40
|
+
* import { ToolRegistry } from './registry/ToolRegistry.js';
|
|
41
|
+
*
|
|
42
|
+
* const registry = new ToolRegistry();
|
|
43
|
+
* const watcher = new ToolWatcher(registry);
|
|
44
|
+
* // Watcher automatically starts monitoring tool directories
|
|
45
|
+
*
|
|
46
|
+
* // When done, stop the watcher
|
|
47
|
+
* watcher.stop();
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class ToolWatcher {
|
|
51
|
+
/** The underlying chokidar file system watcher. */
|
|
52
|
+
private _watcher;
|
|
53
|
+
/** The tool registry to update when tools change. */
|
|
54
|
+
private readonly _toolRegistry;
|
|
55
|
+
private _logger;
|
|
56
|
+
constructor(toolRegistry: ToolRegistry, logger?: Logger);
|
|
57
|
+
/**
|
|
58
|
+
* Create a no-op logger when none is provided.
|
|
59
|
+
*/
|
|
60
|
+
private _createNoopLogger;
|
|
61
|
+
/**
|
|
62
|
+
* Sets up the file system watcher for tool directories.
|
|
63
|
+
*
|
|
64
|
+
* Configures chokidar to watch the tool directories and sets up
|
|
65
|
+
* event handlers for file additions and removals.
|
|
66
|
+
*
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
private setupWatcher;
|
|
70
|
+
/**
|
|
71
|
+
* Handles the event when a tool file is added.
|
|
72
|
+
*
|
|
73
|
+
* When a new `.tool.md` file is detected, this method triggers
|
|
74
|
+
* tool rediscovery to pick up the new tool.
|
|
75
|
+
*
|
|
76
|
+
* @param toolPath - The file path of the added tool file
|
|
77
|
+
* @returns A Promise that resolves when handling is complete
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
private handleToolFileAdd;
|
|
81
|
+
/**
|
|
82
|
+
* Handles the event when a tool file is removed.
|
|
83
|
+
*
|
|
84
|
+
* When a `.tool.md` file is deleted, this method extracts the tool
|
|
85
|
+
* name from the filename and removes it from the registry.
|
|
86
|
+
*
|
|
87
|
+
* @param toolPath - The file path of the removed tool file
|
|
88
|
+
* @returns A Promise that resolves when handling is complete
|
|
89
|
+
* @private
|
|
90
|
+
*/
|
|
91
|
+
private handleToolFileRemoval;
|
|
92
|
+
/**
|
|
93
|
+
* Stops watching tool directories and cleans up resources.
|
|
94
|
+
*
|
|
95
|
+
* This method closes the underlying chokidar watcher and releases
|
|
96
|
+
* file system resources. After calling this method, the watcher
|
|
97
|
+
* cannot be restarted.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const registry = new ToolRegistry();
|
|
102
|
+
* const watcher = new ToolWatcher(registry);
|
|
103
|
+
* // ... use watcher ...
|
|
104
|
+
* watcher.stop();
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
stop(): void;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=ToolWatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolWatcher.d.ts","sourceRoot":"","sources":["../../src/watchers/ToolWatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,WAAW;IACvB,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAA0B;IAC1C,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,OAAO,CAAS;gBAEZ,YAAY,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM;IAMvD;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;IAiBpB;;;;;;;;;OASG;YACW,iBAAiB;IAc/B;;;;;;;;;OASG;YACW,qBAAqB;IAqBnC;;;;;;;;;;;;;;OAcG;IACI,IAAI,IAAI,IAAI;CAMnB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { watch } from "chokidar";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
4
|
+
class ToolWatcher {
|
|
5
|
+
_watcher = null;
|
|
6
|
+
_toolRegistry;
|
|
7
|
+
_logger;
|
|
8
|
+
constructor(toolRegistry, logger){
|
|
9
|
+
this._toolRegistry = toolRegistry;
|
|
10
|
+
this._logger = logger ?? this._createNoopLogger();
|
|
11
|
+
this.setupWatcher();
|
|
12
|
+
}
|
|
13
|
+
_createNoopLogger() {
|
|
14
|
+
return {
|
|
15
|
+
info: ()=>{},
|
|
16
|
+
warn: ()=>{},
|
|
17
|
+
error: ()=>{},
|
|
18
|
+
debug: ()=>{},
|
|
19
|
+
setLevel: ()=>{},
|
|
20
|
+
getLevel: ()=>'info'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
setupWatcher() {
|
|
24
|
+
const toolDirs = [
|
|
25
|
+
'.claude/tools',
|
|
26
|
+
join(homedir(), '.claude/tools')
|
|
27
|
+
];
|
|
28
|
+
this._watcher = watch(toolDirs, {
|
|
29
|
+
ignored: [
|
|
30
|
+
/node_modules/,
|
|
31
|
+
/\.DS_Store$/
|
|
32
|
+
],
|
|
33
|
+
persistent: true
|
|
34
|
+
});
|
|
35
|
+
this._watcher.on('add', async (path)=>{
|
|
36
|
+
await this.handleToolFileAdd(path);
|
|
37
|
+
});
|
|
38
|
+
this._watcher.on('unlink', async (path)=>{
|
|
39
|
+
await this.handleToolFileRemoval(path);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async handleToolFileAdd(toolPath) {
|
|
43
|
+
if (!toolPath.endsWith('.tool.md')) return;
|
|
44
|
+
try {
|
|
45
|
+
await this._toolRegistry.discoverAsync();
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this._logger.error("Failed to discover tools:", {
|
|
48
|
+
error
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async handleToolFileRemoval(toolPath) {
|
|
53
|
+
if (!toolPath.endsWith('.tool.md')) return;
|
|
54
|
+
const fileName = basename(toolPath);
|
|
55
|
+
const toolName = fileName.replace('.tool.md', '');
|
|
56
|
+
if (toolName) try {
|
|
57
|
+
this._toolRegistry.removeTool(toolName);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
this._logger.error(`Tool '${toolName}' not registered: ${error instanceof Error ? error.message : String(error)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
stop() {
|
|
63
|
+
if (this._watcher) {
|
|
64
|
+
this._watcher.close();
|
|
65
|
+
this._watcher = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export { ToolWatcher };
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=ToolWatcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchers/ToolWatcher.js","sources":["../../src/watchers/ToolWatcher.ts"],"sourcesContent":["/**\n * File system watcher for tool directory changes.\n *\n * This module provides the `ToolWatcher` class which monitors configured\n * tool directories for file changes using chokidar. It watches for\n * file additions and removals to enable dynamic tool discovery and registration.\n *\n * @module watcher\n */\n\nimport { watch, type FSWatcher } from 'chokidar';\nimport { homedir } from 'node:os';\nimport { basename, join } from 'node:path';\nimport type { Logger } from '../logger/StructuredLogger.js';\nimport type { ToolRegistry } from '../registry/ToolRegistry.js';\n\n/**\n * File system watcher for tool directories.\n *\n * This class monitors configured tool directories for file system changes,\n * watching for tool file additions and removals. When tool files are added\n * or removed, it automatically updates the tool registry.\n *\n * The watched directories are:\n * - `.claude/tools` (project-local)\n * - `~/.claude/tools` (user-global)\n *\n * @remarks\n * **Watched Events:**\n * - `add` - A new tool file was added (triggers rediscovery)\n * - `unlink` - A tool file was removed (unregisters the tool)\n *\n * **Ignored Paths:**\n * - `node_modules` directories are ignored\n *\n * **Watcher Behavior:**\n * - Uses persistent mode to continue watching even if files are temporarily deleted\n * - Automatically starts watching when instantiated\n * - On file add: Triggers tool rediscovery to pick up new tools\n * - On file remove: Extracts tool name and unregisters it\n *\n * @example\n * ```typescript\n * import { ToolWatcher } from './ToolWatcher.js';\n * import { ToolRegistry } from './registry/ToolRegistry.js';\n *\n * const registry = new ToolRegistry();\n * const watcher = new ToolWatcher(registry);\n * // Watcher automatically starts monitoring tool directories\n *\n * // When done, stop the watcher\n * watcher.stop();\n * ```\n */\nexport class ToolWatcher {\n\t/** The underlying chokidar file system watcher. */\n\tprivate _watcher: FSWatcher | null = null;\n\t/** The tool registry to update when tools change. */\n\tprivate readonly _toolRegistry: ToolRegistry;\n\tprivate _logger: Logger;\n\n\tconstructor(toolRegistry: ToolRegistry, logger?: Logger) {\n\t\tthis._toolRegistry = toolRegistry;\n\t\tthis._logger = logger ?? this._createNoopLogger();\n\t\tthis.setupWatcher();\n\t}\n\n\t/**\n\t * Create a no-op logger when none is provided.\n\t */\n\tprivate _createNoopLogger(): Logger {\n\t\treturn {\n\t\t\tinfo: () => {},\n\t\t\twarn: () => {},\n\t\t\terror: () => {},\n\t\t\tdebug: () => {},\n\t\t\tsetLevel: () => {},\n\t\t\tgetLevel: () => 'info',\n\t\t};\n\t}\n\n\t/**\n\t * Sets up the file system watcher for tool directories.\n\t *\n\t * Configures chokidar to watch the tool directories and sets up\n\t * event handlers for file additions and removals.\n\t *\n\t * @private\n\t */\n\tprivate setupWatcher(): void {\n\t\tconst toolDirs = ['.claude/tools', join(homedir(), '.claude/tools')];\n\n\t\tthis._watcher = watch(toolDirs, {\n\t\t\tignored: [/node_modules/, /\\.DS_Store$/],\n\t\t\tpersistent: true,\n\t\t});\n\n\t\tthis._watcher.on('add', async (path) => {\n\t\t\tawait this.handleToolFileAdd(path);\n\t\t});\n\n\t\tthis._watcher.on('unlink', async (path) => {\n\t\t\tawait this.handleToolFileRemoval(path);\n\t\t});\n\t}\n\n\t/**\n\t * Handles the event when a tool file is added.\n\t *\n\t * When a new `.tool.md` file is detected, this method triggers\n\t * tool rediscovery to pick up the new tool.\n\t *\n\t * @param toolPath - The file path of the added tool file\n\t * @returns A Promise that resolves when handling is complete\n\t * @private\n\t */\n\tprivate async handleToolFileAdd(toolPath: string): Promise<void> {\n\t\t// Only process .tool.md files\n\t\tif (!toolPath.endsWith('.tool.md')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Trigger rediscovery to pick up the new tool\n\t\ttry {\n\t\t\tawait this._toolRegistry.discoverAsync();\n\t\t} catch (error) {\n\t\t\tthis._logger.error(`Failed to discover tools:`, { error });\n\t\t}\n\t}\n\n\t/**\n\t * Handles the event when a tool file is removed.\n\t *\n\t * When a `.tool.md` file is deleted, this method extracts the tool\n\t * name from the filename and removes it from the registry.\n\t *\n\t * @param toolPath - The file path of the removed tool file\n\t * @returns A Promise that resolves when handling is complete\n\t * @private\n\t */\n\tprivate async handleToolFileRemoval(toolPath: string): Promise<void> {\n\t\t// Only process .tool.md files\n\t\tif (!toolPath.endsWith('.tool.md')) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Extract tool name from filename (e.g., \"my-tool.tool.md\" -> \"my-tool\")\n\t\tconst fileName = basename(toolPath);\n\t\tconst toolName = fileName.replace('.tool.md', '');\n\n\t\tif (toolName) {\n\t\t\ttry {\n\t\t\t\tthis._toolRegistry.removeTool(toolName);\n\t\t\t} catch (error) {\n\t\t\t\tthis._logger.error(\n\t\t\t\t\t`Tool '${toolName}' not registered: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Stops watching tool directories and cleans up resources.\n\t *\n\t * This method closes the underlying chokidar watcher and releases\n\t * file system resources. After calling this method, the watcher\n\t * cannot be restarted.\n\t *\n\t * @example\n\t * ```typescript\n\t * const registry = new ToolRegistry();\n\t * const watcher = new ToolWatcher(registry);\n\t * // ... use watcher ...\n\t * watcher.stop();\n\t * ```\n\t */\n\tpublic stop(): void {\n\t\tif (this._watcher) {\n\t\t\tthis._watcher.close();\n\t\t\tthis._watcher = null;\n\t\t}\n\t}\n}\n"],"names":["ToolWatcher","toolRegistry","logger","toolDirs","join","homedir","watch","path","toolPath","error","fileName","basename","toolName","Error","String"],"mappings":";;;AAsDO,MAAMA;IAEJ,WAA6B,KAAK;IAEzB,cAA4B;IACrC,QAAgB;IAExB,YAAYC,YAA0B,EAAEC,MAAe,CAAE;QACxD,IAAI,CAAC,aAAa,GAAGD;QACrB,IAAI,CAAC,OAAO,GAAGC,UAAU,IAAI,CAAC,iBAAiB;QAC/C,IAAI,CAAC,YAAY;IAClB;IAKQ,oBAA4B;QACnC,OAAO;YACN,MAAM,KAAO;YACb,MAAM,KAAO;YACb,OAAO,KAAO;YACd,OAAO,KAAO;YACd,UAAU,KAAO;YACjB,UAAU,IAAM;QACjB;IACD;IAUQ,eAAqB;QAC5B,MAAMC,WAAW;YAAC;YAAiBC,KAAKC,WAAW;SAAiB;QAEpE,IAAI,CAAC,QAAQ,GAAGC,MAAMH,UAAU;YAC/B,SAAS;gBAAC;gBAAgB;aAAc;YACxC,YAAY;QACb;QAEA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,OAAOI;YAC9B,MAAM,IAAI,CAAC,iBAAiB,CAACA;QAC9B;QAEA,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,OAAOA;YACjC,MAAM,IAAI,CAAC,qBAAqB,CAACA;QAClC;IACD;IAYA,MAAc,kBAAkBC,QAAgB,EAAiB;QAEhE,IAAI,CAACA,SAAS,QAAQ,CAAC,aACtB;QAID,IAAI;YACH,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa;QACvC,EAAE,OAAOC,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,6BAA6B;gBAAEA;YAAM;QACzD;IACD;IAYA,MAAc,sBAAsBD,QAAgB,EAAiB;QAEpE,IAAI,CAACA,SAAS,QAAQ,CAAC,aACtB;QAID,MAAME,WAAWC,SAASH;QAC1B,MAAMI,WAAWF,SAAS,OAAO,CAAC,YAAY;QAE9C,IAAIE,UACH,IAAI;YACH,IAAI,CAAC,aAAa,CAAC,UAAU,CAACA;QAC/B,EAAE,OAAOH,OAAO;YACf,IAAI,CAAC,OAAO,CAAC,KAAK,CACjB,CAAC,MAAM,EAAEG,SAAS,kBAAkB,EAAEH,iBAAiBI,QAAQJ,MAAM,OAAO,GAAGK,OAAOL,QAAQ;QAEhG;IAEF;IAiBO,OAAa;QACnB,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClB,IAAI,CAAC,QAAQ,CAAC,KAAK;YACnB,IAAI,CAAC,QAAQ,GAAG;QACjB;IACD;AACD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tracelattice",
|
|
3
|
+
"version": "1.2.5",
|
|
4
|
+
"description": "Semantic Sequential Thinking Tools For Agentic Tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/lib.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"tracelattice": "./dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "rslib build && rsbuild build -c rsbuild.config.ts && node scripts/postbuild-cli.mjs",
|
|
25
|
+
"build:lib": "rslib build",
|
|
26
|
+
"build:cli": "rsbuild build -c rsbuild.config.ts && node scripts/postbuild-cli.mjs",
|
|
27
|
+
"start": "bun dist/cli.js",
|
|
28
|
+
"dev": "bunx @modelcontextprotocol/inspector dist/cli.js",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest",
|
|
31
|
+
"test:coverage": "vitest run --coverage",
|
|
32
|
+
"lint": "eslint src/",
|
|
33
|
+
"lint:fix": "eslint src/ --fix",
|
|
34
|
+
"format": "prettier --write \"src/**/*.ts\" \"*.{json,md}\"",
|
|
35
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"*.{json,md}\"",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"prepublishOnly": "npm run type-check && npm run lint && npm run test"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"mcp",
|
|
41
|
+
"model-context-protocol",
|
|
42
|
+
"sequential-thinking",
|
|
43
|
+
"problem-solving",
|
|
44
|
+
"tool-recommendation",
|
|
45
|
+
"decision-making",
|
|
46
|
+
"thought-process",
|
|
47
|
+
"step-by-step",
|
|
48
|
+
"llm",
|
|
49
|
+
"ai",
|
|
50
|
+
"branching-thoughts",
|
|
51
|
+
"thought-revision",
|
|
52
|
+
"tool-analysis",
|
|
53
|
+
"problem-breakdown",
|
|
54
|
+
"solution-planning",
|
|
55
|
+
"adaptive-thinking",
|
|
56
|
+
"reflective-analysis",
|
|
57
|
+
"tool-confidence"
|
|
58
|
+
],
|
|
59
|
+
"author": "CCWorkforces Engineers",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "git+https://github.com/OCWorkforces/TraceLattice.git"
|
|
64
|
+
},
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/OCWorkforces/TraceLattice/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://github.com/OCWorkforces/TraceLattice#readme",
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@tmcp/adapter-valibot": "^0.1.5",
|
|
71
|
+
"@tmcp/transport-stdio": "^0.4.2",
|
|
72
|
+
"chalk": "^5.6.2",
|
|
73
|
+
"chokidar": "^5.0.0",
|
|
74
|
+
"tmcp": "^1.19.3",
|
|
75
|
+
"valibot": "^1.3.1",
|
|
76
|
+
"yaml": "^2.8.3"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@changesets/cli": "^2.30.0",
|
|
80
|
+
"@eslint/js": "^10.0.1",
|
|
81
|
+
"@rsbuild/core": "^1.7.5",
|
|
82
|
+
"@rslib/core": "^0.21.0",
|
|
83
|
+
"@tsconfig/node24": "^24.0.4",
|
|
84
|
+
"@types/node": "^25.6.0",
|
|
85
|
+
"@typescript-eslint/eslint-plugin": "^8.58.1",
|
|
86
|
+
"@typescript-eslint/parser": "^8.58.1",
|
|
87
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
88
|
+
"eslint": "^10.2.0",
|
|
89
|
+
"globals": "^17.4.0",
|
|
90
|
+
"prettier": "^3.8.2",
|
|
91
|
+
"typescript": "^6.0.2",
|
|
92
|
+
"typescript-eslint": "^8.58.1",
|
|
93
|
+
"vitest": "^4.1.4"
|
|
94
|
+
}
|
|
95
|
+
}
|