@skillsmith/mcp-server 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/README.md +11 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/__tests__/LocalIndexer.test.js +158 -0
  4. package/dist/src/__tests__/LocalIndexer.test.js.map +1 -1
  5. package/dist/src/__tests__/compare.test.d.ts +8 -0
  6. package/dist/src/__tests__/compare.test.d.ts.map +1 -0
  7. package/dist/src/__tests__/compare.test.js +162 -0
  8. package/dist/src/__tests__/compare.test.js.map +1 -0
  9. package/dist/src/__tests__/context.async.test.d.ts +8 -0
  10. package/dist/src/__tests__/context.async.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/context.async.test.js +223 -0
  12. package/dist/src/__tests__/context.async.test.js.map +1 -0
  13. package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts +10 -0
  14. package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts.map +1 -0
  15. package/dist/src/__tests__/middleware/errorFormatter.builders.test.js +93 -0
  16. package/dist/src/__tests__/middleware/errorFormatter.builders.test.js.map +1 -0
  17. package/dist/src/__tests__/middleware/license-renewal.test.d.ts +10 -0
  18. package/dist/src/__tests__/middleware/license-renewal.test.d.ts.map +1 -0
  19. package/dist/src/__tests__/middleware/license-renewal.test.js +152 -0
  20. package/dist/src/__tests__/middleware/license-renewal.test.js.map +1 -0
  21. package/dist/src/__tests__/middleware/quota-helpers.test.d.ts +9 -0
  22. package/dist/src/__tests__/middleware/quota-helpers.test.d.ts.map +1 -0
  23. package/dist/src/__tests__/middleware/quota-helpers.test.js +105 -0
  24. package/dist/src/__tests__/middleware/quota-helpers.test.js.map +1 -0
  25. package/dist/src/__tests__/middleware/quota.test.d.ts +12 -0
  26. package/dist/src/__tests__/middleware/quota.test.d.ts.map +1 -0
  27. package/dist/src/__tests__/middleware/quota.test.js +189 -0
  28. package/dist/src/__tests__/middleware/quota.test.js.map +1 -0
  29. package/dist/src/__tests__/recommend-online-path.test.d.ts +10 -0
  30. package/dist/src/__tests__/recommend-online-path.test.d.ts.map +1 -0
  31. package/dist/src/__tests__/recommend-online-path.test.js +225 -0
  32. package/dist/src/__tests__/recommend-online-path.test.js.map +1 -0
  33. package/dist/src/__tests__/recommend.test.d.ts +2 -0
  34. package/dist/src/__tests__/recommend.test.d.ts.map +1 -1
  35. package/dist/src/__tests__/recommend.test.js +14 -2
  36. package/dist/src/__tests__/recommend.test.js.map +1 -1
  37. package/dist/src/__tests__/search-online-path.test.d.ts +10 -0
  38. package/dist/src/__tests__/search-online-path.test.d.ts.map +1 -0
  39. package/dist/src/__tests__/search-online-path.test.js +140 -0
  40. package/dist/src/__tests__/search-online-path.test.js.map +1 -0
  41. package/dist/src/__tests__/search.test.js +153 -5
  42. package/dist/src/__tests__/search.test.js.map +1 -1
  43. package/dist/src/context/project-detector.d.ts.map +1 -1
  44. package/dist/src/context/project-detector.js +1 -0
  45. package/dist/src/context/project-detector.js.map +1 -1
  46. package/dist/src/context.async.d.ts +48 -0
  47. package/dist/src/context.async.d.ts.map +1 -0
  48. package/dist/src/context.async.js +215 -0
  49. package/dist/src/context.async.js.map +1 -0
  50. package/dist/src/context.d.ts +5 -145
  51. package/dist/src/context.d.ts.map +1 -1
  52. package/dist/src/context.helpers.d.ts +25 -0
  53. package/dist/src/context.helpers.d.ts.map +1 -0
  54. package/dist/src/context.helpers.js +49 -0
  55. package/dist/src/context.helpers.js.map +1 -0
  56. package/dist/src/context.js +11 -228
  57. package/dist/src/context.js.map +1 -1
  58. package/dist/src/context.types.d.ts +110 -0
  59. package/dist/src/context.types.d.ts.map +1 -0
  60. package/dist/src/context.types.js +10 -0
  61. package/dist/src/context.types.js.map +1 -0
  62. package/dist/src/health/readinessCheck.d.ts +1 -1
  63. package/dist/src/health/readinessCheck.d.ts.map +1 -1
  64. package/dist/src/index.js +21 -152
  65. package/dist/src/index.js.map +1 -1
  66. package/dist/src/indexer/FrontmatterParser.d.ts +6 -0
  67. package/dist/src/indexer/FrontmatterParser.d.ts.map +1 -1
  68. package/dist/src/indexer/FrontmatterParser.js +15 -0
  69. package/dist/src/indexer/FrontmatterParser.js.map +1 -1
  70. package/dist/src/indexer/LocalIndexer.d.ts +4 -0
  71. package/dist/src/indexer/LocalIndexer.d.ts.map +1 -1
  72. package/dist/src/indexer/LocalIndexer.js +3 -0
  73. package/dist/src/indexer/LocalIndexer.js.map +1 -1
  74. package/dist/src/middleware/degradation.d.ts.map +1 -1
  75. package/dist/src/middleware/degradation.js +8 -0
  76. package/dist/src/middleware/degradation.js.map +1 -1
  77. package/dist/src/middleware/errorFormatter.builders.d.ts +49 -0
  78. package/dist/src/middleware/errorFormatter.builders.d.ts.map +1 -0
  79. package/dist/src/middleware/errorFormatter.builders.js +237 -0
  80. package/dist/src/middleware/errorFormatter.builders.js.map +1 -0
  81. package/dist/src/middleware/errorFormatter.d.ts +5 -100
  82. package/dist/src/middleware/errorFormatter.d.ts.map +1 -1
  83. package/dist/src/middleware/errorFormatter.js +16 -238
  84. package/dist/src/middleware/errorFormatter.js.map +1 -1
  85. package/dist/src/middleware/errorFormatter.types.d.ts +81 -0
  86. package/dist/src/middleware/errorFormatter.types.d.ts.map +1 -0
  87. package/dist/src/middleware/errorFormatter.types.js +34 -0
  88. package/dist/src/middleware/errorFormatter.types.js.map +1 -0
  89. package/dist/src/middleware/toolFeatureMapping.d.ts +1 -1
  90. package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -1
  91. package/dist/src/middleware/toolFeatureMapping.js +8 -0
  92. package/dist/src/middleware/toolFeatureMapping.js.map +1 -1
  93. package/dist/src/tool-dispatch.d.ts +27 -0
  94. package/dist/src/tool-dispatch.d.ts.map +1 -0
  95. package/dist/src/tool-dispatch.js +127 -0
  96. package/dist/src/tool-dispatch.js.map +1 -0
  97. package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -1
  98. package/dist/src/tools/LocalSkillSearch.js +4 -0
  99. package/dist/src/tools/LocalSkillSearch.js.map +1 -1
  100. package/dist/src/tools/get-skill.d.ts.map +1 -1
  101. package/dist/src/tools/get-skill.js +14 -0
  102. package/dist/src/tools/get-skill.js.map +1 -1
  103. package/dist/src/tools/index.d.ts +6 -0
  104. package/dist/src/tools/index.d.ts.map +1 -1
  105. package/dist/src/tools/index.js +6 -0
  106. package/dist/src/tools/index.js.map +1 -1
  107. package/dist/src/tools/install.d.ts +3 -35
  108. package/dist/src/tools/install.d.ts.map +1 -1
  109. package/dist/src/tools/install.js +22 -74
  110. package/dist/src/tools/install.js.map +1 -1
  111. package/dist/src/tools/install.optimize.d.ts +46 -0
  112. package/dist/src/tools/install.optimize.d.ts.map +1 -0
  113. package/dist/src/tools/install.optimize.js +67 -0
  114. package/dist/src/tools/install.optimize.js.map +1 -0
  115. package/dist/src/tools/install.tool.d.ts +44 -0
  116. package/dist/src/tools/install.tool.d.ts.map +1 -0
  117. package/dist/src/tools/install.tool.js +44 -0
  118. package/dist/src/tools/install.tool.js.map +1 -0
  119. package/dist/src/tools/install.types.d.ts +7 -1
  120. package/dist/src/tools/install.types.d.ts.map +1 -1
  121. package/dist/src/tools/recommend.d.ts +2 -4
  122. package/dist/src/tools/recommend.d.ts.map +1 -1
  123. package/dist/src/tools/recommend.format.d.ts +28 -0
  124. package/dist/src/tools/recommend.format.d.ts.map +1 -0
  125. package/dist/src/tools/recommend.format.js +111 -0
  126. package/dist/src/tools/recommend.format.js.map +1 -0
  127. package/dist/src/tools/recommend.js +6 -97
  128. package/dist/src/tools/recommend.js.map +1 -1
  129. package/dist/src/tools/recommend.types.d.ts +1 -1
  130. package/dist/src/tools/search.d.ts +24 -21
  131. package/dist/src/tools/search.d.ts.map +1 -1
  132. package/dist/src/tools/search.formatter.d.ts +30 -0
  133. package/dist/src/tools/search.formatter.d.ts.map +1 -0
  134. package/dist/src/tools/search.formatter.js +64 -0
  135. package/dist/src/tools/search.formatter.js.map +1 -0
  136. package/dist/src/tools/search.js +55 -54
  137. package/dist/src/tools/search.js.map +1 -1
  138. package/dist/src/tools/skill-audit.d.ts +98 -0
  139. package/dist/src/tools/skill-audit.d.ts.map +1 -0
  140. package/dist/src/tools/skill-audit.js +105 -0
  141. package/dist/src/tools/skill-audit.js.map +1 -0
  142. package/dist/src/tools/skill-audit.test.d.ts +6 -0
  143. package/dist/src/tools/skill-audit.test.d.ts.map +1 -0
  144. package/dist/src/tools/skill-audit.test.js +121 -0
  145. package/dist/src/tools/skill-audit.test.js.map +1 -0
  146. package/dist/src/tools/skill-diff.d.ts +107 -0
  147. package/dist/src/tools/skill-diff.d.ts.map +1 -0
  148. package/dist/src/tools/skill-diff.js +268 -0
  149. package/dist/src/tools/skill-diff.js.map +1 -0
  150. package/dist/src/tools/skill-diff.test.d.ts +6 -0
  151. package/dist/src/tools/skill-diff.test.d.ts.map +1 -0
  152. package/dist/src/tools/skill-diff.test.js +260 -0
  153. package/dist/src/tools/skill-diff.test.js.map +1 -0
  154. package/dist/src/tools/skill-updates.d.ts +1 -1
  155. package/dist/src/tools/skill-updates.d.ts.map +1 -1
  156. package/dist/src/tools/suggest.d.ts +4 -4
  157. package/dist/src/tools/uninstall.d.ts +1 -1
  158. package/dist/src/tools/validate.helpers.d.ts.map +1 -1
  159. package/dist/src/tools/validate.helpers.js +31 -0
  160. package/dist/src/tools/validate.helpers.js.map +1 -1
  161. package/dist/src/utils/validation.d.ts +13 -0
  162. package/dist/src/utils/validation.d.ts.map +1 -1
  163. package/dist/src/utils/validation.js +27 -0
  164. package/dist/src/utils/validation.js.map +1 -1
  165. package/dist/tests/health.test.js +4 -4
  166. package/dist/tests/health.test.js.map +1 -1
  167. package/dist/tests/integration/recommend.integration.test.js +2 -0
  168. package/dist/tests/integration/recommend.integration.test.js.map +1 -1
  169. package/dist/tests/integration/setup.d.ts +3 -1
  170. package/dist/tests/integration/setup.d.ts.map +1 -1
  171. package/dist/tests/integration/setup.js +4 -1
  172. package/dist/tests/integration/setup.js.map +1 -1
  173. package/dist/tests/recommend.test.js +2 -0
  174. package/dist/tests/recommend.test.js.map +1 -1
  175. package/dist/tests/unit/validate-helpers.test.js +54 -0
  176. package/dist/tests/unit/validate-helpers.test.js.map +1 -1
  177. package/package.json +2 -2
  178. package/server.json +2 -2
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Async Tool Context Creation with WASM Fallback
3
+ * @module @skillsmith/mcp-server/context.async
4
+ * @see SMI-2207: Async database functions with WASM fallback
5
+ * @see SMI-2741: Split from context.ts to meet 500-line standard
6
+ *
7
+ * Provides async context creation for cross-platform compatibility:
8
+ * 1. Try better-sqlite3 native module first (fastest)
9
+ * 2. Fall back to sql.js WASM if native is unavailable
10
+ */
11
+ import type { ToolContext, ToolContextOptions } from './context.types.js';
12
+ /**
13
+ * Create the shared tool context asynchronously with WASM fallback
14
+ *
15
+ * This is the recommended way to initialize context for cross-platform
16
+ * compatibility. It will:
17
+ * 1. Try better-sqlite3 native module first (fastest)
18
+ * 2. Fall back to sql.js WASM if native is unavailable
19
+ *
20
+ * @param options - Configuration options
21
+ * @returns Promise resolving to initialized tool context
22
+ *
23
+ * @see SMI-898: Path traversal protection
24
+ * @see SMI-2207: Async initialization for WASM fallback
25
+ *
26
+ * @example
27
+ * // Initialize with WASM fallback support
28
+ * const context = await createToolContextAsync();
29
+ *
30
+ * @throws Error if dbPath contains path traversal attempt
31
+ * @throws Error if no database driver is available
32
+ */
33
+ export declare function createToolContextAsync(options?: ToolContextOptions): Promise<ToolContext>;
34
+ /**
35
+ * Get or create the global async tool context
36
+ *
37
+ * Uses a separate singleton from the sync version to prevent caching issues
38
+ * where the sync path might be triggered first and cached.
39
+ *
40
+ * @param options - Configuration options (only used on first call)
41
+ * @returns Promise resolving to the global tool context
42
+ */
43
+ export declare function getToolContextAsync(options?: ToolContextOptions): Promise<ToolContext>;
44
+ /**
45
+ * Reset the async global context (for testing)
46
+ */
47
+ export declare function resetAsyncToolContext(): Promise<void>;
48
+ //# sourceMappingURL=context.async.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.async.d.ts","sourceRoot":"","sources":["../../src/context.async.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0BH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAKzE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAiLtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAS5F;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB3D"}
@@ -0,0 +1,215 @@
1
+ /**
2
+ * @fileoverview Async Tool Context Creation with WASM Fallback
3
+ * @module @skillsmith/mcp-server/context.async
4
+ * @see SMI-2207: Async database functions with WASM fallback
5
+ * @see SMI-2741: Split from context.ts to meet 500-line standard
6
+ *
7
+ * Provides async context creation for cross-platform compatibility:
8
+ * 1. Try better-sqlite3 native module first (fastest)
9
+ * 2. Fall back to sql.js WASM if native is unavailable
10
+ */
11
+ import { existsSync } from 'fs';
12
+ import { createDatabaseAsync, openDatabaseAsync, initializeSchema, SearchService, SkillRepository, validateDbPath, SkillsmithApiClient, initializePostHog, shutdownPostHog, generateAnonymousId, SyncConfigRepository, SyncHistoryRepository, SyncEngine, SkillVersionRepository, CoInstallRepository, BackgroundSyncService, getApiKey, } from '@skillsmith/core';
13
+ import { LLMFailoverChain } from './llm/failover.js';
14
+ import { getDefaultDbPath, ensureDbDirectory } from './context.helpers.js';
15
+ // Separate singleton for async context (prevents caching conflict with sync)
16
+ let asyncGlobalContext = null;
17
+ /**
18
+ * Create the shared tool context asynchronously with WASM fallback
19
+ *
20
+ * This is the recommended way to initialize context for cross-platform
21
+ * compatibility. It will:
22
+ * 1. Try better-sqlite3 native module first (fastest)
23
+ * 2. Fall back to sql.js WASM if native is unavailable
24
+ *
25
+ * @param options - Configuration options
26
+ * @returns Promise resolving to initialized tool context
27
+ *
28
+ * @see SMI-898: Path traversal protection
29
+ * @see SMI-2207: Async initialization for WASM fallback
30
+ *
31
+ * @example
32
+ * // Initialize with WASM fallback support
33
+ * const context = await createToolContextAsync();
34
+ *
35
+ * @throws Error if dbPath contains path traversal attempt
36
+ * @throws Error if no database driver is available
37
+ */
38
+ export async function createToolContextAsync(options = {}) {
39
+ let dbPath;
40
+ if (options.dbPath) {
41
+ // SMI-898: Validate custom path for path traversal
42
+ const validation = validateDbPath(options.dbPath, {
43
+ allowInMemory: true,
44
+ allowTempDir: true,
45
+ });
46
+ if (!validation.valid) {
47
+ throw new Error(`Invalid database path: ${validation.error}. ` +
48
+ 'Path must be within ~/.skillsmith, ~/.claude, or temp directories.');
49
+ }
50
+ dbPath = validation.resolvedPath;
51
+ }
52
+ else {
53
+ dbPath = getDefaultDbPath();
54
+ }
55
+ // Ensure directory exists (skip for in-memory)
56
+ if (dbPath !== ':memory:') {
57
+ ensureDbDirectory(dbPath);
58
+ }
59
+ // SMI-2207: Use async database creation with WASM fallback
60
+ let db;
61
+ if (dbPath !== ':memory:' && existsSync(dbPath)) {
62
+ db = await openDatabaseAsync(dbPath);
63
+ }
64
+ else {
65
+ db = await createDatabaseAsync(dbPath);
66
+ // SMI-2207: createDatabaseAsync returns a bare connection (no schema).
67
+ // openDatabaseAsync runs runMigrationsSafe internally; for new/in-memory
68
+ // databases we must call initializeSchema explicitly to match the sync path.
69
+ initializeSchema(db);
70
+ }
71
+ // Initialize services
72
+ const searchService = new SearchService(db, {
73
+ cacheTtl: options.searchCacheTtl ?? 300,
74
+ });
75
+ const skillRepository = new SkillRepository(db);
76
+ const coInstallRepository = new CoInstallRepository(db);
77
+ // SMI-1851: Use shared config module (handles env var > config file precedence)
78
+ const apiKey = options.apiKey || getApiKey();
79
+ // SMI-1183: Initialize API client with configuration
80
+ const apiClient = new SkillsmithApiClient({
81
+ baseUrl: options.apiClientConfig?.baseUrl,
82
+ anonKey: options.apiClientConfig?.anonKey,
83
+ apiKey,
84
+ timeout: options.apiClientConfig?.timeout ?? 10000,
85
+ maxRetries: options.apiClientConfig?.maxRetries ?? 3,
86
+ debug: options.apiClientConfig?.debug,
87
+ offlineMode: options.apiClientConfig?.offlineMode,
88
+ });
89
+ // SMI-1184: Initialize PostHog telemetry (opt-in, privacy first)
90
+ let distinctId;
91
+ const telemetryEnabled = process.env.SKILLSMITH_TELEMETRY_ENABLED === 'true' || options.telemetryConfig?.enabled === true;
92
+ const postHogApiKey = process.env.POSTHOG_API_KEY || options.telemetryConfig?.postHogApiKey;
93
+ if (telemetryEnabled && postHogApiKey) {
94
+ distinctId = generateAnonymousId();
95
+ initializePostHog({
96
+ apiKey: postHogApiKey,
97
+ host: options.telemetryConfig?.postHogHost,
98
+ disabled: false,
99
+ });
100
+ }
101
+ // Initialize background sync service if enabled
102
+ let backgroundSync;
103
+ const backgroundSyncEnabled = process.env.SKILLSMITH_BACKGROUND_SYNC !== 'false' &&
104
+ options.backgroundSyncConfig?.enabled !== false;
105
+ if (backgroundSyncEnabled) {
106
+ const syncConfigRepo = new SyncConfigRepository(db);
107
+ const syncHistoryRepo = new SyncHistoryRepository(db);
108
+ const skillVersionRepo = new SkillVersionRepository(db);
109
+ const syncConfig = syncConfigRepo.getConfig();
110
+ if (syncConfig.enabled) {
111
+ const syncEngine = new SyncEngine(apiClient, skillRepository, syncConfigRepo, syncHistoryRepo, skillVersionRepo);
112
+ backgroundSync = new BackgroundSyncService(syncEngine, syncConfigRepo, {
113
+ syncOnStart: true,
114
+ debug: options.backgroundSyncConfig?.debug ?? false,
115
+ onSyncComplete: (result) => {
116
+ if (options.backgroundSyncConfig?.debug) {
117
+ console.log(`[skillsmith] Background sync complete: ${result.skillsAdded} added, ${result.skillsUpdated} updated`);
118
+ }
119
+ },
120
+ onSyncError: (error) => {
121
+ if (options.backgroundSyncConfig?.debug) {
122
+ console.error(`[skillsmith] Background sync error: ${error.message}`);
123
+ }
124
+ },
125
+ });
126
+ backgroundSync.start();
127
+ }
128
+ }
129
+ // SMI-1524: Initialize LLM failover chain if enabled
130
+ let llmFailover;
131
+ const llmFailoverEnabled = process.env.SKILLSMITH_LLM_FAILOVER_ENABLED === 'true' ||
132
+ options.llmFailoverConfig?.enabled === true;
133
+ if (llmFailoverEnabled) {
134
+ llmFailover = new LLMFailoverChain({
135
+ ...options.llmFailoverConfig,
136
+ enabled: true,
137
+ debug: options.llmFailoverConfig?.debug ?? false,
138
+ });
139
+ llmFailover.initialize().catch((error) => {
140
+ console.error(`[skillsmith] LLM failover initialization error: ${error.message}`);
141
+ });
142
+ if (options.llmFailoverConfig?.debug) {
143
+ console.log('[skillsmith] LLM failover chain initialized');
144
+ }
145
+ }
146
+ // Create signal handlers for cleanup
147
+ const signalHandlers = [];
148
+ if (backgroundSync || llmFailover) {
149
+ const cleanup = () => {
150
+ backgroundSync?.stop();
151
+ llmFailover?.close();
152
+ };
153
+ const sigTermHandler = () => cleanup();
154
+ const sigIntHandler = () => cleanup();
155
+ process.on('SIGTERM', sigTermHandler);
156
+ process.on('SIGINT', sigIntHandler);
157
+ signalHandlers.push({ signal: 'SIGTERM', handler: sigTermHandler }, { signal: 'SIGINT', handler: sigIntHandler });
158
+ }
159
+ return {
160
+ db,
161
+ searchService,
162
+ skillRepository,
163
+ coInstallRepository,
164
+ sessionInstalledSkillIds: [],
165
+ apiClient,
166
+ distinctId,
167
+ backgroundSync,
168
+ llmFailover,
169
+ _signalHandlers: signalHandlers.length > 0 ? signalHandlers : undefined,
170
+ };
171
+ }
172
+ /**
173
+ * Get or create the global async tool context
174
+ *
175
+ * Uses a separate singleton from the sync version to prevent caching issues
176
+ * where the sync path might be triggered first and cached.
177
+ *
178
+ * @param options - Configuration options (only used on first call)
179
+ * @returns Promise resolving to the global tool context
180
+ */
181
+ export async function getToolContextAsync(options) {
182
+ if (!asyncGlobalContext) {
183
+ asyncGlobalContext = await createToolContextAsync(options);
184
+ }
185
+ else if (options) {
186
+ console.warn('[skillsmith] getToolContextAsync called with options after context was already initialized. Options ignored.');
187
+ }
188
+ return asyncGlobalContext;
189
+ }
190
+ /**
191
+ * Reset the async global context (for testing)
192
+ */
193
+ export async function resetAsyncToolContext() {
194
+ if (asyncGlobalContext) {
195
+ // Inline close to avoid circular import with context.ts
196
+ const context = asyncGlobalContext;
197
+ asyncGlobalContext = null;
198
+ if (context._signalHandlers) {
199
+ for (const { signal, handler } of context._signalHandlers) {
200
+ process.removeListener(signal, handler);
201
+ }
202
+ }
203
+ if (context.backgroundSync) {
204
+ context.backgroundSync.stop();
205
+ }
206
+ if (context.llmFailover) {
207
+ context.llmFailover.close();
208
+ }
209
+ context.db.close();
210
+ if (context.distinctId) {
211
+ await shutdownPostHog();
212
+ }
213
+ }
214
+ }
215
+ //# sourceMappingURL=context.async.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.async.js","sourceRoot":"","sources":["../../src/context.async.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  * @module @skillsmith/mcp-server/context
4
4
  * @see SMI-792: Add database initialization to MCP server
5
5
  * @see SMI-898: Path traversal protection for DB_PATH
6
+ * @see SMI-2741: Async context split into context.async.ts to meet 500-line standard
6
7
  *
7
8
  * Provides shared context for MCP tool handlers including:
8
9
  * - SQLite database connection with FTS5 search
@@ -17,115 +18,10 @@
17
18
  * // Pass to tool handlers
18
19
  * const result = await executeSearch(input, context);
19
20
  */
20
- import { SearchService, SkillRepository, SkillsmithApiClient, BackgroundSyncService, type ApiClientConfig, type DatabaseType } from '@skillsmith/core';
21
- import { LLMFailoverChain, type LLMFailoverConfig } from './llm/failover.js';
22
- /**
23
- * Shared context for MCP tool handlers
24
- * SMI-1183: Added apiClient for live API access with local fallback
25
- * SMI-1184: Added distinctId for telemetry tracking
26
- * SMI-1524: Added llmFailover for multi-LLM support with circuit breaker
27
- */
28
- export interface ToolContext {
29
- /** SQLite database connection */
30
- db: DatabaseType;
31
- /** Search service with FTS5/BM25 (fallback) */
32
- searchService: SearchService;
33
- /** Skill repository for CRUD operations (fallback) */
34
- skillRepository: SkillRepository;
35
- /** API client for live Supabase API (primary) */
36
- apiClient: SkillsmithApiClient;
37
- /** Anonymous user ID for telemetry (undefined if telemetry disabled) */
38
- distinctId?: string;
39
- /** Background sync service (if enabled) */
40
- backgroundSync?: BackgroundSyncService;
41
- /** LLM failover chain for multi-provider support (SMI-1524) */
42
- llmFailover?: LLMFailoverChain;
43
- /** Internal: Signal handlers for cleanup (prevents memory leaks) */
44
- _signalHandlers?: Array<{
45
- signal: NodeJS.Signals;
46
- handler: () => void;
47
- }>;
48
- }
49
- /**
50
- * Telemetry configuration for PostHog (SMI-1184)
51
- * Privacy-first: disabled by default (opt-in)
52
- */
53
- export interface TelemetryConfig {
54
- /**
55
- * Enable telemetry collection (default: false for privacy)
56
- * Can also be set via SKILLSMITH_TELEMETRY_ENABLED env var
57
- */
58
- enabled?: boolean;
59
- /**
60
- * PostHog API key (starts with phc_)
61
- * Can also be set via POSTHOG_API_KEY env var
62
- */
63
- postHogApiKey?: string;
64
- /**
65
- * PostHog host URL (default: https://app.posthog.com)
66
- */
67
- postHogHost?: string;
68
- }
69
- /**
70
- * Background sync configuration
71
- */
72
- export interface BackgroundSyncConfig {
73
- /**
74
- * Enable background sync during MCP server sessions
75
- * Can also be set via SKILLSMITH_BACKGROUND_SYNC env var
76
- * Default: true (syncs if config.enabled is true)
77
- */
78
- enabled?: boolean;
79
- /**
80
- * Enable debug logging for sync operations
81
- */
82
- debug?: boolean;
83
- }
84
- /**
85
- * Options for creating tool context
86
- */
87
- export interface ToolContextOptions {
88
- /** Custom database path (defaults to ~/.skillsmith/skills.db) */
89
- dbPath?: string;
90
- /** Search cache TTL in seconds (default: 300) */
91
- searchCacheTtl?: number;
92
- /** API client configuration (SMI-1183) */
93
- apiClientConfig?: ApiClientConfig;
94
- /**
95
- * API key for authenticated requests
96
- * Can also be set via SKILLSMITH_API_KEY env var
97
- * SMI-XXXX: API Key Authentication
98
- */
99
- apiKey?: string;
100
- /**
101
- * Telemetry configuration (SMI-1184)
102
- * Privacy-first: telemetry is OPT-IN and disabled by default
103
- */
104
- telemetryConfig?: TelemetryConfig;
105
- /**
106
- * Background sync configuration
107
- * Enables automatic registry sync during MCP server sessions
108
- */
109
- backgroundSyncConfig?: BackgroundSyncConfig;
110
- /**
111
- * LLM failover chain configuration (SMI-1524)
112
- * Enables multi-provider LLM support with automatic failover
113
- * Disabled by default - set enabled: true to activate
114
- */
115
- llmFailoverConfig?: LLMFailoverConfig;
116
- }
117
- /**
118
- * Get the default database path
119
- * Respects SKILLSMITH_DB_PATH environment variable
120
- *
121
- * @see SMI-898: Path traversal protection
122
- * - Validates SKILLSMITH_DB_PATH against path traversal attacks
123
- * - Rejects paths with ".." traversal sequences
124
- * - Ensures path is within allowed directories
125
- *
126
- * @throws Error if SKILLSMITH_DB_PATH contains path traversal attempt
127
- */
128
- export declare function getDefaultDbPath(): string;
21
+ export type { ToolContext, TelemetryConfig, BackgroundSyncConfig, ToolContextOptions, } from './context.types.js';
22
+ export { getDefaultDbPath, ensureDbDirectory } from './context.helpers.js';
23
+ export { createToolContextAsync, getToolContextAsync, resetAsyncToolContext, } from './context.async.js';
24
+ import type { ToolContext, ToolContextOptions } from './context.types.js';
129
25
  /**
130
26
  * Create the shared tool context with database and services
131
27
  *
@@ -175,40 +71,4 @@ export declare function getToolContext(options?: ToolContextOptions): ToolContex
175
71
  * SMI-1184: Made async to properly shutdown PostHog
176
72
  */
177
73
  export declare function resetToolContext(): Promise<void>;
178
- /**
179
- * Create the shared tool context asynchronously with WASM fallback
180
- *
181
- * This is the recommended way to initialize context for cross-platform
182
- * compatibility. It will:
183
- * 1. Try better-sqlite3 native module first (fastest)
184
- * 2. Fall back to sql.js WASM if native is unavailable
185
- *
186
- * @param options - Configuration options
187
- * @returns Promise resolving to initialized tool context
188
- *
189
- * @see SMI-898: Path traversal protection
190
- * @see SMI-2207: Async initialization for WASM fallback
191
- *
192
- * @example
193
- * // Initialize with WASM fallback support
194
- * const context = await createToolContextAsync();
195
- *
196
- * @throws Error if dbPath contains path traversal attempt
197
- * @throws Error if no database driver is available
198
- */
199
- export declare function createToolContextAsync(options?: ToolContextOptions): Promise<ToolContext>;
200
- /**
201
- * Get or create the global async tool context
202
- *
203
- * Uses a separate singleton from the sync version to prevent caching issues
204
- * where the sync path might be triggered first and cached.
205
- *
206
- * @param options - Configuration options (only used on first call)
207
- * @returns Promise resolving to the global tool context
208
- */
209
- export declare function getToolContextAsync(options?: ToolContextOptions): Promise<ToolContext>;
210
- /**
211
- * Reset the async global context (for testing)
212
- */
213
- export declare function resetAsyncToolContext(): Promise<void>;
214
74
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAOL,aAAa,EACb,eAAe,EAEf,mBAAmB,EAOnB,qBAAqB,EAErB,KAAK,eAAe,EAEpB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAE5E;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,iCAAiC;IACjC,EAAE,EAAE,YAAY,CAAA;IAChB,+CAA+C;IAC/C,aAAa,EAAE,aAAa,CAAA;IAC5B,sDAAsD;IACtD,eAAe,EAAE,eAAe,CAAA;IAChC,iDAAiD;IACjD,SAAS,EAAE,mBAAmB,CAAA;IAC9B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,qBAAqB,CAAA;IACtC,+DAA+D;IAC/D,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC9B,oEAAoE;IACpE,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAAA;CACzE;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAA;IAC3C;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;CACtC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAqBzC;AAeD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CA+K/E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAUxE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKtD;AASD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAuKtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAS5F;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK3D"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AA2BH,YAAY,EACV,WAAW,EACX,eAAe,EACf,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAyL/E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyB1E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,CAUxE;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKtD"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @fileoverview Tool Context Helper Utilities
3
+ * @module @skillsmith/mcp-server/context.helpers
4
+ * @see SMI-898: Path traversal protection for DB_PATH
5
+ * @see SMI-2741: Split from context.ts to meet 500-line standard
6
+ *
7
+ * Shared helpers used by both sync and async context creation.
8
+ */
9
+ /**
10
+ * Get the default database path
11
+ * Respects SKILLSMITH_DB_PATH environment variable
12
+ *
13
+ * @see SMI-898: Path traversal protection
14
+ * - Validates SKILLSMITH_DB_PATH against path traversal attacks
15
+ * - Rejects paths with ".." traversal sequences
16
+ * - Ensures path is within allowed directories
17
+ *
18
+ * @throws Error if SKILLSMITH_DB_PATH contains path traversal attempt
19
+ */
20
+ export declare function getDefaultDbPath(): string;
21
+ /**
22
+ * Ensure the database directory exists
23
+ */
24
+ export declare function ensureDbDirectory(dbPath: string): void;
25
+ //# sourceMappingURL=context.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.helpers.d.ts","sourceRoot":"","sources":["../../src/context.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAqBzC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKtD"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Tool Context Helper Utilities
3
+ * @module @skillsmith/mcp-server/context.helpers
4
+ * @see SMI-898: Path traversal protection for DB_PATH
5
+ * @see SMI-2741: Split from context.ts to meet 500-line standard
6
+ *
7
+ * Shared helpers used by both sync and async context creation.
8
+ */
9
+ import { homedir } from 'os';
10
+ import { join, dirname } from 'path';
11
+ import { mkdirSync, existsSync } from 'fs';
12
+ import { validateDbPath } from '@skillsmith/core';
13
+ /**
14
+ * Get the default database path
15
+ * Respects SKILLSMITH_DB_PATH environment variable
16
+ *
17
+ * @see SMI-898: Path traversal protection
18
+ * - Validates SKILLSMITH_DB_PATH against path traversal attacks
19
+ * - Rejects paths with ".." traversal sequences
20
+ * - Ensures path is within allowed directories
21
+ *
22
+ * @throws Error if SKILLSMITH_DB_PATH contains path traversal attempt
23
+ */
24
+ export function getDefaultDbPath() {
25
+ const envPath = process.env.SKILLSMITH_DB_PATH;
26
+ if (envPath) {
27
+ // SMI-898: Validate environment variable path for path traversal
28
+ const validation = validateDbPath(envPath, {
29
+ allowInMemory: true,
30
+ allowTempDir: true,
31
+ });
32
+ if (!validation.valid) {
33
+ throw new Error(`Invalid SKILLSMITH_DB_PATH: ${validation.error}. ` +
34
+ 'Path must be within ~/.skillsmith, ~/.claude, or temp directories.');
35
+ }
36
+ return validation.resolvedPath;
37
+ }
38
+ return join(homedir(), '.skillsmith', 'skills.db');
39
+ }
40
+ /**
41
+ * Ensure the database directory exists
42
+ */
43
+ export function ensureDbDirectory(dbPath) {
44
+ const dir = dirname(dbPath);
45
+ if (!existsSync(dir)) {
46
+ mkdirSync(dir, { recursive: true });
47
+ }
48
+ }
49
+ //# sourceMappingURL=context.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.helpers.js","sourceRoot":"","sources":["../../src/context.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAA;IAE9C,IAAI,OAAO,EAAE,CAAC;QACZ,iEAAiE;QACjE,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,EAAE;YACzC,aAAa,EAAE,IAAI;YACnB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAA;QAEF,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,+BAA+B,UAAU,CAAC,KAAK,IAAI;gBACjD,oEAAoE,CACvE,CAAA;QACH,CAAC;QAED,OAAO,UAAU,CAAC,YAAa,CAAA;IACjC,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,WAAW,CAAC,CAAA;AACpD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACrC,CAAC;AACH,CAAC"}