mcp-code-context 3.6.3 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/CHANGELOG.md +140 -278
  2. package/INSTRUCTIONS.md +23 -9
  3. package/README.md +217 -97
  4. package/SECURITY.md +55 -21
  5. package/dist/src/core/cacheManager.d.ts +4 -5
  6. package/dist/src/core/cacheManager.js +49 -33
  7. package/dist/src/core/cacheManager.js.map +1 -1
  8. package/dist/src/core/engine.d.ts +1 -1
  9. package/dist/src/core/engine.js +3 -3
  10. package/dist/src/core/engine.js.map +1 -1
  11. package/dist/src/core/indexManager.d.ts +58 -0
  12. package/dist/src/core/indexManager.js +252 -0
  13. package/dist/src/core/indexManager.js.map +1 -0
  14. package/dist/src/core/indexManagerQueries.d.ts +14 -0
  15. package/dist/src/core/indexManagerQueries.js +95 -0
  16. package/dist/src/core/indexManagerQueries.js.map +1 -0
  17. package/dist/src/core/sessionManager.d.ts +117 -0
  18. package/dist/src/core/sessionManager.js +231 -0
  19. package/dist/src/core/sessionManager.js.map +1 -0
  20. package/dist/src/core/validator.d.ts +1 -1
  21. package/dist/src/core/validator.js +18 -10
  22. package/dist/src/core/validator.js.map +1 -1
  23. package/dist/src/index.d.ts +1 -13
  24. package/dist/src/index.js +25 -999
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/operations/astTransform.d.ts +38 -0
  27. package/dist/src/operations/astTransform.js +239 -0
  28. package/dist/src/operations/astTransform.js.map +1 -0
  29. package/dist/src/operations/compress.d.ts +5 -3
  30. package/dist/src/operations/compress.js +73 -7
  31. package/dist/src/operations/compress.js.map +1 -1
  32. package/dist/src/operations/confirmationStore.d.ts +35 -8
  33. package/dist/src/operations/confirmationStore.js +112 -14
  34. package/dist/src/operations/confirmationStore.js.map +1 -1
  35. package/dist/src/operations/impactAnalysis.d.ts +9 -0
  36. package/dist/src/operations/impactAnalysis.js +61 -0
  37. package/dist/src/operations/impactAnalysis.js.map +1 -0
  38. package/dist/src/operations/pendingStore.d.ts +51 -0
  39. package/dist/src/operations/pendingStore.js +201 -0
  40. package/dist/src/operations/pendingStore.js.map +1 -0
  41. package/dist/src/operations/pendingStoreInit.d.ts +6 -0
  42. package/dist/src/operations/pendingStoreInit.js +42 -0
  43. package/dist/src/operations/pendingStoreInit.js.map +1 -0
  44. package/dist/src/operations/read.d.ts +6 -92
  45. package/dist/src/operations/read.js +4 -449
  46. package/dist/src/operations/read.js.map +1 -1
  47. package/dist/src/operations/readCore.d.ts +33 -0
  48. package/dist/src/operations/readCore.js +142 -0
  49. package/dist/src/operations/readCore.js.map +1 -0
  50. package/dist/src/operations/rename.d.ts +13 -0
  51. package/dist/src/operations/rename.js +130 -0
  52. package/dist/src/operations/rename.js.map +1 -0
  53. package/dist/src/operations/searchOperation.d.ts +16 -0
  54. package/dist/src/operations/searchOperation.js +113 -0
  55. package/dist/src/operations/searchOperation.js.map +1 -0
  56. package/dist/src/operations/symbolQuery.d.ts +38 -0
  57. package/dist/src/operations/symbolQuery.js +194 -0
  58. package/dist/src/operations/symbolQuery.js.map +1 -0
  59. package/dist/src/operations/write.d.ts +11 -14
  60. package/dist/src/operations/write.js +6 -125
  61. package/dist/src/operations/write.js.map +1 -1
  62. package/dist/src/parsers/base.d.ts +1 -1
  63. package/dist/src/parsers/base.js +1 -1
  64. package/dist/src/parsers/csharp.d.ts +12 -0
  65. package/dist/src/parsers/csharp.js +67 -0
  66. package/dist/src/parsers/csharp.js.map +1 -0
  67. package/dist/src/parsers/dartTreeSitter.d.ts +1 -1
  68. package/dist/src/parsers/dartTreeSitter.js +1 -1
  69. package/dist/src/parsers/go.d.ts +11 -0
  70. package/dist/src/parsers/go.js +74 -0
  71. package/dist/src/parsers/go.js.map +1 -0
  72. package/dist/src/parsers/java.d.ts +12 -0
  73. package/dist/src/parsers/java.js +62 -0
  74. package/dist/src/parsers/java.js.map +1 -0
  75. package/dist/src/parsers/kotlin.d.ts +12 -0
  76. package/dist/src/parsers/kotlin.js +75 -0
  77. package/dist/src/parsers/kotlin.js.map +1 -0
  78. package/dist/src/parsers/php.d.ts +1 -1
  79. package/dist/src/parsers/php.js +1 -1
  80. package/dist/src/parsers/python.d.ts +1 -1
  81. package/dist/src/parsers/python.js +1 -1
  82. package/dist/src/parsers/registry.d.ts +1 -1
  83. package/dist/src/parsers/registry.js +63 -2
  84. package/dist/src/parsers/registry.js.map +1 -1
  85. package/dist/src/parsers/ruby.d.ts +12 -0
  86. package/dist/src/parsers/ruby.js +73 -0
  87. package/dist/src/parsers/ruby.js.map +1 -0
  88. package/dist/src/parsers/rust.d.ts +12 -0
  89. package/dist/src/parsers/rust.js +66 -0
  90. package/dist/src/parsers/rust.js.map +1 -0
  91. package/dist/src/parsers/typescript.d.ts +1 -1
  92. package/dist/src/parsers/typescript.js +28 -38
  93. package/dist/src/parsers/typescript.js.map +1 -1
  94. package/dist/src/tools/adminHandlers.d.ts +67 -0
  95. package/dist/src/tools/adminHandlers.js +129 -0
  96. package/dist/src/tools/adminHandlers.js.map +1 -0
  97. package/dist/src/tools/context.d.ts +9 -0
  98. package/dist/src/tools/context.js +21 -0
  99. package/dist/src/tools/context.js.map +1 -0
  100. package/dist/src/tools/handlers.d.ts +4 -0
  101. package/dist/src/tools/handlers.js +5 -0
  102. package/dist/src/tools/handlers.js.map +1 -0
  103. package/dist/src/tools/pipeline.d.ts +6 -0
  104. package/dist/src/tools/pipeline.js +100 -0
  105. package/dist/src/tools/pipeline.js.map +1 -0
  106. package/dist/src/tools/readHandlers.d.ts +55 -0
  107. package/dist/src/tools/readHandlers.js +220 -0
  108. package/dist/src/tools/readHandlers.js.map +1 -0
  109. package/dist/src/tools/toolDefinitions.d.ts +1037 -0
  110. package/dist/src/tools/toolDefinitions.js +13 -0
  111. package/dist/src/tools/toolDefinitions.js.map +1 -0
  112. package/dist/src/tools/toolDefinitionsAdmin.d.ts +89 -0
  113. package/dist/src/tools/toolDefinitionsAdmin.js +99 -0
  114. package/dist/src/tools/toolDefinitionsAdmin.js.map +1 -0
  115. package/dist/src/tools/toolDefinitionsCore.d.ts +949 -0
  116. package/dist/src/tools/toolDefinitionsCore.js +267 -0
  117. package/dist/src/tools/toolDefinitionsCore.js.map +1 -0
  118. package/dist/src/tools/writeHandlers.d.ts +37 -0
  119. package/dist/src/tools/writeHandlers.js +199 -0
  120. package/dist/src/tools/writeHandlers.js.map +1 -0
  121. package/dist/src/utils/appDir.d.ts +19 -0
  122. package/dist/src/utils/appDir.js +50 -0
  123. package/dist/src/utils/appDir.js.map +1 -0
  124. package/dist/src/utils/auditLogWriter.d.ts +9 -0
  125. package/dist/src/utils/auditLogWriter.js +49 -0
  126. package/dist/src/utils/auditLogWriter.js.map +1 -0
  127. package/dist/src/utils/auditLogger.d.ts +1 -10
  128. package/dist/src/utils/auditLogger.js +14 -109
  129. package/dist/src/utils/auditLogger.js.map +1 -1
  130. package/dist/src/utils/auditQuery.d.ts +23 -0
  131. package/dist/src/utils/auditQuery.js +67 -0
  132. package/dist/src/utils/auditQuery.js.map +1 -0
  133. package/dist/src/utils/backupManager.d.ts +2 -2
  134. package/dist/src/utils/backupManager.js +29 -12
  135. package/dist/src/utils/backupManager.js.map +1 -1
  136. package/dist/src/utils/constants.d.ts +1 -1
  137. package/dist/src/utils/constants.js +8 -1
  138. package/dist/src/utils/constants.js.map +1 -1
  139. package/dist/src/utils/diff.d.ts +12 -1
  140. package/dist/src/utils/diff.js +41 -1
  141. package/dist/src/utils/diff.js.map +1 -1
  142. package/dist/src/utils/fileLock.d.ts +7 -2
  143. package/dist/src/utils/fileLock.js +14 -11
  144. package/dist/src/utils/fileLock.js.map +1 -1
  145. package/dist/src/utils/fileWalker.d.ts +1 -1
  146. package/dist/src/utils/fileWalker.js +1 -1
  147. package/dist/src/utils/fileWatcher.d.ts +1 -1
  148. package/dist/src/utils/fileWatcher.js +1 -1
  149. package/dist/src/utils/fuzzySearch.d.ts +1 -1
  150. package/dist/src/utils/fuzzySearch.js +1 -1
  151. package/dist/src/utils/logger.d.ts +1 -1
  152. package/dist/src/utils/logger.js +2 -2
  153. package/dist/src/utils/logger.js.map +1 -1
  154. package/dist/src/utils/rateLimiter.d.ts +9 -1
  155. package/dist/src/utils/rateLimiter.js +12 -1
  156. package/dist/src/utils/rateLimiter.js.map +1 -1
  157. package/dist/src/utils/regexValidator.d.ts +12 -0
  158. package/dist/src/utils/regexValidator.js +48 -0
  159. package/dist/src/utils/regexValidator.js.map +1 -0
  160. package/dist/src/utils/safeRegex.d.ts +2 -92
  161. package/dist/src/utils/safeRegex.js +41 -222
  162. package/dist/src/utils/safeRegex.js.map +1 -1
  163. package/dist/src/utils/safeRegexApi.d.ts +56 -0
  164. package/dist/src/utils/safeRegexApi.js +99 -0
  165. package/dist/src/utils/safeRegexApi.js.map +1 -0
  166. package/dist/src/utils/safeRegexPool.d.ts +7 -0
  167. package/dist/src/utils/safeRegexPool.js +102 -0
  168. package/dist/src/utils/safeRegexPool.js.map +1 -0
  169. package/dist/src/utils/searchTools.js +6 -6
  170. package/dist/src/utils/searchTools.js.map +1 -1
  171. package/dist/src/utils/streaming.d.ts +4 -3
  172. package/dist/src/utils/streaming.js +1 -1
  173. package/dist/src/utils/streaming.js.map +1 -1
  174. package/dist/src/utils/telemetry.d.ts +1 -1
  175. package/dist/src/utils/telemetry.js +1 -1
  176. package/dist/src/utils/toctou.d.ts +7 -0
  177. package/dist/src/utils/toctou.js +24 -0
  178. package/dist/src/utils/toctou.js.map +1 -0
  179. package/llms.txt +173 -21
  180. package/package.json +2 -2
  181. package/scripts/replace-version.js +0 -59
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Index Manager query operations
3
+ */
4
+ import * as fs from "node:fs/promises";
5
+ import { existsSync } from "fs";
6
+ export function searchSymbolsInDb(db, query, options = {}) {
7
+ const { fuzzy = false, types, maxResults = 50 } = options;
8
+ const results = [];
9
+ const typeFilter = types && types.length > 0 ? `AND type IN (${types.map(() => "?").join(",")})` : "";
10
+ let sql;
11
+ let params;
12
+ if (fuzzy) {
13
+ sql = `
14
+ SELECT file_path, name, type, start_line, end_line, class_name
15
+ FROM symbols WHERE LOWER(name) LIKE LOWER(?) ${typeFilter}
16
+ ORDER BY CASE WHEN LOWER(name) = LOWER(?) THEN 0 WHEN LOWER(name) LIKE LOWER(?) THEN 1 ELSE 2 END, name
17
+ LIMIT ?`;
18
+ params = [`%${query}%`, ...(types ?? []), query, `${query}%`, maxResults];
19
+ }
20
+ else {
21
+ sql = `
22
+ SELECT file_path, name, type, start_line, end_line, class_name
23
+ FROM symbols WHERE LOWER(name) = LOWER(?) ${typeFilter} ORDER BY name LIMIT ?`;
24
+ params = [query, ...(types ?? []), maxResults];
25
+ }
26
+ const stmt = db.prepare(sql);
27
+ stmt.bind(params);
28
+ while (stmt.step()) {
29
+ const row = stmt.getAsObject();
30
+ results.push({
31
+ filePath: row.file_path,
32
+ name: row.name,
33
+ type: row.type,
34
+ startLine: row.start_line,
35
+ endLine: row.end_line,
36
+ className: row.class_name ?? undefined,
37
+ });
38
+ }
39
+ stmt.free();
40
+ return results;
41
+ }
42
+ export function getDependentsFromDb(db, filePath) {
43
+ const results = [];
44
+ const stmt = db.prepare("SELECT from_file FROM dependencies WHERE to_file = ?");
45
+ stmt.bind([filePath]);
46
+ while (stmt.step()) {
47
+ results.push(stmt.getAsObject().from_file);
48
+ }
49
+ stmt.free();
50
+ return results;
51
+ }
52
+ export function getDependenciesFromDb(db, filePath) {
53
+ const results = [];
54
+ const stmt = db.prepare("SELECT to_file FROM dependencies WHERE from_file = ?");
55
+ stmt.bind([filePath]);
56
+ while (stmt.step()) {
57
+ results.push(stmt.getAsObject().to_file);
58
+ }
59
+ stmt.free();
60
+ return results;
61
+ }
62
+ export function hasIndexInDb(db) {
63
+ const stmt = db.prepare("SELECT COUNT(*) as count FROM files");
64
+ stmt.step();
65
+ const count = stmt.getAsObject().count;
66
+ stmt.free();
67
+ return count > 0;
68
+ }
69
+ export async function getIndexStatsFromDb(db, dbPath) {
70
+ const files = db.prepare("SELECT COUNT(*) as c FROM files");
71
+ files.step();
72
+ const filesCount = files.getAsObject().c;
73
+ files.free();
74
+ const syms = db.prepare("SELECT COUNT(*) as c FROM symbols");
75
+ syms.step();
76
+ const symsCount = syms.getAsObject().c;
77
+ syms.free();
78
+ const deps = db.prepare("SELECT COUNT(*) as c FROM dependencies");
79
+ deps.step();
80
+ const depsCount = deps.getAsObject().c;
81
+ deps.free();
82
+ const last = db.prepare("SELECT MAX(indexed_at) as t FROM files");
83
+ last.step();
84
+ const lastAt = last.getAsObject().t;
85
+ last.free();
86
+ const dbSize = existsSync(dbPath) ? (await fs.stat(dbPath)).size : 0;
87
+ return {
88
+ filesIndexed: filesCount,
89
+ symbolsIndexed: symsCount,
90
+ dependenciesIndexed: depsCount,
91
+ dbSizeBytes: dbSize,
92
+ lastIndexedAt: lastAt,
93
+ };
94
+ }
95
+ //# sourceMappingURL=indexManagerQueries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexManagerQueries.js","sourceRoot":"","sources":["../../../src/core/indexManagerQueries.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAGhC,MAAM,UAAU,iBAAiB,CAC/B,EAAY,EACZ,KAAa,EACb,UAAsE,EAAE;IAExE,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAC1D,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,MAAM,UAAU,GACd,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAErF,IAAI,GAAW,CAAC;IAChB,IAAI,MAA2B,CAAC;IAEhC,IAAI,KAAK,EAAE,CAAC;QACV,GAAG,GAAG;;qDAE2C,UAAU;;cAEjD,CAAC;QACX,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,EAAE,UAAU,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,GAAG,GAAG;;kDAEwC,UAAU,wBAAwB,CAAC;QACjF,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAO3B,CAAC;QACF,OAAO,CAAC,IAAI,CAAC;YACX,QAAQ,EAAE,GAAG,CAAC,SAAS;YACvB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS,EAAE,GAAG,CAAC,UAAU;YACzB,OAAO,EAAE,GAAG,CAAC,QAAQ;YACrB,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;SACvC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAY,EAAE,QAAgB;IAChE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAE,IAAI,CAAC,WAAW,EAA4B,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAY,EAAE,QAAgB;IAClE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC;IAChF,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAE,IAAI,CAAC,WAAW,EAA0B,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAY;IACvC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,qCAAqC,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,MAAM,KAAK,GAAI,IAAI,CAAC,WAAW,EAAwB,CAAC,KAAK,CAAC;IAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,OAAO,KAAK,GAAG,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EAAY,EAAE,MAAc;IACpE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,EAAE,CAAC;IACb,MAAM,UAAU,GAAI,KAAK,CAAC,WAAW,EAAoB,CAAC,CAAC,CAAC;IAC5D,KAAK,CAAC,IAAI,EAAE,CAAC;IAEb,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,MAAM,SAAS,GAAI,IAAI,CAAC,WAAW,EAAoB,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;IAEZ,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;IAClE,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,MAAM,SAAS,GAAI,IAAI,CAAC,WAAW,EAAoB,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;IAEZ,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,wCAAwC,CAAC,CAAC;IAClE,IAAI,CAAC,IAAI,EAAE,CAAC;IACZ,MAAM,MAAM,GAAI,IAAI,CAAC,WAAW,EAA2B,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,IAAI,EAAE,CAAC;IAEZ,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAErE,OAAO;QACL,YAAY,EAAE,UAAU;QACxB,cAAc,EAAE,SAAS;QACzB,mBAAmB,EAAE,SAAS;QAC9B,WAAW,EAAE,MAAM;QACnB,aAAa,EAAE,MAAM;KACtB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Session Manager - v3.7.0
3
+ * Manages per-MCP-client state isolation
4
+ * Prevents state leakage between concurrent clients
5
+ */
6
+ import { FileLockManager } from "../utils/fileLock.js";
7
+ import { ConfirmationStore } from "../operations/confirmationStore.js";
8
+ import { RateLimiter } from "../utils/rateLimiter.js";
9
+ import { CacheManager } from "./cacheManager.js";
10
+ interface CacheEntry {
11
+ cache: CacheManager;
12
+ lastUsed: number;
13
+ }
14
+ interface SessionState {
15
+ sessionId: string;
16
+ lockManager: FileLockManager;
17
+ confirmationStore: ConfirmationStore;
18
+ rateLimiter: RateLimiter;
19
+ cacheManagers: Map<string, CacheEntry>;
20
+ createdAt: number;
21
+ lastActivity: number;
22
+ }
23
+ export interface SessionStats {
24
+ exists: boolean;
25
+ sessionId?: string;
26
+ createdAt?: number;
27
+ lastActivity?: number;
28
+ pendingOperations: number;
29
+ locksHeld: number;
30
+ rateLimiterTokens: number;
31
+ cacheManagers: number;
32
+ }
33
+ export interface PendingOperationSummary {
34
+ token: string;
35
+ filePath: string;
36
+ operation: string;
37
+ createdAt: number;
38
+ expiresAt: number;
39
+ }
40
+ /**
41
+ * SessionManager - Manages isolated state per MCP client connection
42
+ *
43
+ * Each MCP client connection gets:
44
+ * - Dedicated FileLockManager (no lock conflicts)
45
+ * - Dedicated ConfirmationStore (no token leakage)
46
+ * - Dedicated RateLimiter bucket (fair quota)
47
+ * - Dedicated CacheManager pool (no cache pollution)
48
+ */
49
+ export declare class SessionManager {
50
+ private sessions;
51
+ private cleanupTimer;
52
+ constructor();
53
+ /**
54
+ * Get or create session state for a client
55
+ *
56
+ * @param sessionId - Unique identifier for MCP client connection
57
+ * @returns Isolated session state
58
+ */
59
+ getOrCreate(sessionId: string, projectRoot?: string): SessionState;
60
+ /**
61
+ * Get CacheManager for a project within this session
62
+ *
63
+ * @param sessionId - Session identifier
64
+ * @param projectRoot - Project root path
65
+ * @returns CacheManager instance
66
+ */
67
+ getCacheManager(sessionId: string, projectRoot: string): CacheManager;
68
+ /**
69
+ * Cleanup session and release all resources
70
+ *
71
+ * @param sessionId - Session to cleanup
72
+ */
73
+ cleanup(sessionId: string): Promise<void>;
74
+ /**
75
+ * Get stats for a specific session
76
+ *
77
+ * @param sessionId - Session identifier
78
+ * @returns Session statistics
79
+ */
80
+ getSessionStats(sessionId: string): SessionStats;
81
+ /**
82
+ * Clear cache for a specific session
83
+ *
84
+ * @param sessionId - Session identifier
85
+ * @param projectRoot - Project root path
86
+ * @returns Number of cache entries cleared
87
+ */
88
+ clearSessionCache(sessionId: string, projectRoot?: string): Promise<number>;
89
+ /**
90
+ * List all pending operations for a session
91
+ *
92
+ * @param sessionId - Session identifier
93
+ * @returns Array of pending operations
94
+ */
95
+ listPendingOperations(sessionId: string): PendingOperationSummary[];
96
+ /**
97
+ * Get count of active sessions
98
+ */
99
+ getActiveSessionCount(): number;
100
+ /**
101
+ * Auto-cleanup inactive sessions
102
+ */
103
+ private startCleanupTimer;
104
+ /**
105
+ * Stop cleanup timer
106
+ */
107
+ stop(): void;
108
+ /**
109
+ * Cleanup all sessions on shutdown
110
+ */
111
+ shutdownAll(): Promise<void>;
112
+ }
113
+ /**
114
+ * Global session manager instance
115
+ */
116
+ export declare const globalSessionManager: SessionManager;
117
+ export {};
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Session Manager - v3.7.0
3
+ * Manages per-MCP-client state isolation
4
+ * Prevents state leakage between concurrent clients
5
+ */
6
+ import { FileLockManager } from "../utils/fileLock.js";
7
+ import { ConfirmationStore } from "../operations/confirmationStore.js";
8
+ import { RateLimiter } from "../utils/rateLimiter.js";
9
+ import { CacheManager } from "./cacheManager.js";
10
+ const MAX_CACHE_MANAGERS = 10;
11
+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
12
+ /**
13
+ * SessionManager - Manages isolated state per MCP client connection
14
+ *
15
+ * Each MCP client connection gets:
16
+ * - Dedicated FileLockManager (no lock conflicts)
17
+ * - Dedicated ConfirmationStore (no token leakage)
18
+ * - Dedicated RateLimiter bucket (fair quota)
19
+ * - Dedicated CacheManager pool (no cache pollution)
20
+ */
21
+ export class SessionManager {
22
+ sessions = new Map();
23
+ cleanupTimer = null;
24
+ constructor() {
25
+ this.startCleanupTimer();
26
+ }
27
+ /**
28
+ * Get or create session state for a client
29
+ *
30
+ * @param sessionId - Unique identifier for MCP client connection
31
+ * @returns Isolated session state
32
+ */
33
+ getOrCreate(sessionId, projectRoot) {
34
+ let session = this.sessions.get(sessionId);
35
+ if (!session) {
36
+ session = {
37
+ sessionId,
38
+ lockManager: new FileLockManager(),
39
+ // Pass sessionId + projectRoot so SQLite crash recovery activates
40
+ confirmationStore: new ConfirmationStore(sessionId, projectRoot),
41
+ rateLimiter: new RateLimiter(),
42
+ cacheManagers: new Map(),
43
+ createdAt: Date.now(),
44
+ lastActivity: Date.now(),
45
+ };
46
+ this.sessions.set(sessionId, session);
47
+ }
48
+ else if (projectRoot && !session.confirmationStore.hasPersistentStore()) {
49
+ // Session existed but was created without projectRoot — activate SQLite now
50
+ session.confirmationStore.activatePersistence(sessionId, projectRoot);
51
+ }
52
+ session.lastActivity = Date.now();
53
+ return session;
54
+ }
55
+ /**
56
+ * Get CacheManager for a project within this session
57
+ *
58
+ * @param sessionId - Session identifier
59
+ * @param projectRoot - Project root path
60
+ * @returns CacheManager instance
61
+ */
62
+ getCacheManager(sessionId, projectRoot) {
63
+ // Pass projectRoot so crash recovery SQLite activates on first real tool call
64
+ const session = this.getOrCreate(sessionId, projectRoot);
65
+ const now = Date.now();
66
+ if (session.cacheManagers.has(projectRoot)) {
67
+ const entry = session.cacheManagers.get(projectRoot);
68
+ entry.lastUsed = now;
69
+ return entry.cache;
70
+ }
71
+ // Evict LRU if at capacity
72
+ if (session.cacheManagers.size >= MAX_CACHE_MANAGERS) {
73
+ let oldestKey = null;
74
+ let oldestTime = Infinity;
75
+ for (const [key, entry] of session.cacheManagers.entries()) {
76
+ if (entry.lastUsed < oldestTime) {
77
+ oldestTime = entry.lastUsed;
78
+ oldestKey = key;
79
+ }
80
+ }
81
+ if (oldestKey) {
82
+ const evicted = session.cacheManagers.get(oldestKey);
83
+ evicted.cache.persistOnExit();
84
+ evicted.cache.close();
85
+ session.cacheManagers.delete(oldestKey);
86
+ }
87
+ }
88
+ const cache = new CacheManager(projectRoot);
89
+ session.cacheManagers.set(projectRoot, { cache, lastUsed: now });
90
+ return cache;
91
+ }
92
+ /**
93
+ * Cleanup session and release all resources
94
+ *
95
+ * @param sessionId - Session to cleanup
96
+ */
97
+ async cleanup(sessionId) {
98
+ const session = this.sessions.get(sessionId);
99
+ if (!session)
100
+ return;
101
+ // Release all file locks
102
+ await session.lockManager.releaseAll();
103
+ // Stop rate limiter timer
104
+ session.rateLimiter.stop();
105
+ // Close all cache managers (persist + stop watchers + free WASM heap)
106
+ for (const entry of session.cacheManagers.values()) {
107
+ entry.cache.persistOnExit();
108
+ entry.cache.close();
109
+ }
110
+ session.cacheManagers.clear();
111
+ // Clear confirmation store
112
+ session.confirmationStore.clearAll();
113
+ this.sessions.delete(sessionId);
114
+ }
115
+ /**
116
+ * Get stats for a specific session
117
+ *
118
+ * @param sessionId - Session identifier
119
+ * @returns Session statistics
120
+ */
121
+ getSessionStats(sessionId) {
122
+ const session = this.sessions.get(sessionId);
123
+ if (!session) {
124
+ return {
125
+ exists: false,
126
+ pendingOperations: 0,
127
+ locksHeld: 0,
128
+ rateLimiterTokens: 0,
129
+ cacheManagers: 0,
130
+ };
131
+ }
132
+ return {
133
+ exists: true,
134
+ sessionId: session.sessionId,
135
+ createdAt: session.createdAt,
136
+ lastActivity: session.lastActivity,
137
+ pendingOperations: session.confirmationStore.getPendingCount(),
138
+ locksHeld: session.lockManager.getActiveLockCount(),
139
+ rateLimiterTokens: session.rateLimiter.getTokens(sessionId),
140
+ cacheManagers: session.cacheManagers.size,
141
+ };
142
+ }
143
+ /**
144
+ * Clear cache for a specific session
145
+ *
146
+ * @param sessionId - Session identifier
147
+ * @param projectRoot - Project root path
148
+ * @returns Number of cache entries cleared
149
+ */
150
+ async clearSessionCache(sessionId, projectRoot) {
151
+ const session = this.sessions.get(sessionId);
152
+ if (!session)
153
+ return 0;
154
+ if (projectRoot) {
155
+ const entry = session.cacheManagers.get(projectRoot);
156
+ if (entry) {
157
+ await entry.cache.clear();
158
+ return 1;
159
+ }
160
+ return 0;
161
+ }
162
+ // Clear all caches for this session
163
+ let cleared = 0;
164
+ for (const entry of session.cacheManagers.values()) {
165
+ await entry.cache.clear();
166
+ cleared++;
167
+ }
168
+ return cleared;
169
+ }
170
+ /**
171
+ * List all pending operations for a session
172
+ *
173
+ * @param sessionId - Session identifier
174
+ * @returns Array of pending operations
175
+ */
176
+ listPendingOperations(sessionId) {
177
+ const session = this.sessions.get(sessionId);
178
+ if (!session)
179
+ return [];
180
+ return session.confirmationStore.listAll();
181
+ }
182
+ /**
183
+ * Get count of active sessions
184
+ */
185
+ getActiveSessionCount() {
186
+ return this.sessions.size;
187
+ }
188
+ /**
189
+ * Auto-cleanup inactive sessions
190
+ */
191
+ startCleanupTimer() {
192
+ this.cleanupTimer = setInterval(async () => {
193
+ const now = Date.now();
194
+ const toCleanup = [];
195
+ for (const [sessionId, session] of this.sessions.entries()) {
196
+ const inactive = now - session.lastActivity;
197
+ if (inactive > SESSION_TIMEOUT_MS) {
198
+ toCleanup.push(sessionId);
199
+ }
200
+ }
201
+ for (const sessionId of toCleanup) {
202
+ await this.cleanup(sessionId);
203
+ }
204
+ }, 60 * 1000); // Check every minute
205
+ if (this.cleanupTimer.unref) {
206
+ this.cleanupTimer.unref();
207
+ }
208
+ }
209
+ /**
210
+ * Stop cleanup timer
211
+ */
212
+ stop() {
213
+ if (this.cleanupTimer) {
214
+ clearInterval(this.cleanupTimer);
215
+ this.cleanupTimer = null;
216
+ }
217
+ }
218
+ /**
219
+ * Cleanup all sessions on shutdown
220
+ */
221
+ async shutdownAll() {
222
+ this.stop();
223
+ const sessionIds = Array.from(this.sessions.keys());
224
+ await Promise.all(sessionIds.map(id => this.cleanup(id)));
225
+ }
226
+ }
227
+ /**
228
+ * Global session manager instance
229
+ */
230
+ export const globalSessionManager = new SessionManager();
231
+ //# sourceMappingURL=sessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../../src/core/sessionManager.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Security Validator - v3.6.3
2
+ * Security Validator - v3.7.0
3
3
  * CRITICAL FIX: Path traversal check AFTER normalization
4
4
  */
5
5
  export interface ValidationResult {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Security Validator - v3.6.3
2
+ * Security Validator - v3.7.0
3
3
  * CRITICAL FIX: Path traversal check AFTER normalization
4
4
  */
5
5
  import * as path from "node:path";
@@ -7,29 +7,37 @@ import * as fs from "node:fs/promises";
7
7
  export class SecurityValidator {
8
8
  projectRoot;
9
9
  constructor(projectRoot) {
10
- this.projectRoot = path.resolve(projectRoot);
10
+ // normalize: resolve + lowercase for case-insensitive Windows FS comparison
11
+ this.projectRoot = path.resolve(projectRoot).toLowerCase();
11
12
  }
12
13
  async validateFilePath(filePath) {
13
- // Resolve FIRST, then check
14
14
  const resolved = path.resolve(filePath);
15
- // CRITICAL: Check boundary AFTER normalization (with path separator)
16
- if (resolved !== this.projectRoot && !resolved.startsWith(this.projectRoot + path.sep)) {
15
+ const resolvedNorm = resolved.toLowerCase();
16
+ if (resolvedNorm !== this.projectRoot && !resolvedNorm.startsWith(this.projectRoot + path.sep)) {
17
17
  return {
18
18
  valid: false,
19
- error: `Security: Path "${filePath}" is outside project boundary "${this.projectRoot}"`
19
+ error: `Security: Path "${filePath}" is outside project boundary "${this.projectRoot}"`,
20
20
  };
21
21
  }
22
- // Existence check
23
22
  try {
24
- await fs.access(resolved);
23
+ const realPath = await fs.realpath(resolved);
24
+ const realPathNorm = realPath.toLowerCase();
25
+ if (realPathNorm !== this.projectRoot && !realPathNorm.startsWith(this.projectRoot + path.sep)) {
26
+ return {
27
+ valid: false,
28
+ error: `Security: Symlink "${filePath}" resolves outside project boundary "${this.projectRoot}"`,
29
+ };
30
+ }
31
+ await fs.access(realPath);
32
+ return { valid: true, resolvedPath: realPath };
25
33
  }
26
34
  catch {
35
+ // fs.realpath or fs.access failed — file does not exist or is inaccessible
27
36
  return {
28
37
  valid: false,
29
- error: `File not found: "${filePath}" (resolved to "${resolved}")`
38
+ error: `File not found: "${filePath}" (resolved to "${resolved}")`,
30
39
  };
31
40
  }
32
- return { valid: true, resolvedPath: resolved };
33
41
  }
34
42
  async validateFileSize(filePath, maxSize = 10 * 1024 * 1024) {
35
43
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQvC,MAAM,OAAO,iBAAiB;IACpB,WAAW,CAAS;IAE5B,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QACrC,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAExC,qEAAqE;QACrE,IAAI,QAAQ,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACvF,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,mBAAmB,QAAQ,kCAAkC,IAAI,CAAC,WAAW,GAAG;aACxF,CAAC;QACJ,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,oBAAoB,QAAQ,mBAAmB,QAAQ,IAAI;aACnE,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,GAAG,IAAI,GAAG,IAAI;QACzE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,mBAAmB,MAAM,sBAAsB,KAAK,IAAI;iBAChE,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,kCAAkC,QAAQ,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAChH,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAQvC,MAAM,OAAO,iBAAiB;IACpB,WAAW,CAAS;IAE5B,YAAY,WAAmB;QAC7B,4EAA4E;QAC5E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QAE5C,IAAI,YAAY,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/F,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,mBAAmB,QAAQ,kCAAkC,IAAI,CAAC,WAAW,GAAG;aACxF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC7C,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;YAE5C,IAAI,YAAY,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/F,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,sBAAsB,QAAQ,wCAAwC,IAAI,CAAC,WAAW,GAAG;iBACjG,CAAC;YACJ,CAAC;YAED,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,2EAA2E;YAC3E,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,oBAAoB,QAAQ,mBAAmB,QAAQ,IAAI;aACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,GAAG,IAAI,GAAG,IAAI;QACzE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACpD,MAAM,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACjD,OAAO;oBACL,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,mBAAmB,MAAM,sBAAsB,KAAK,IAAI;iBAChE,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,kCAAkC,QAAQ,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;aAChH,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,17 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * mcp-code-context v3.6.3 - Tree-sitter WASM Edition
4
- *
5
- * Production-ready with:
6
- * - Tree-sitter WASM for 100% AST accuracy (TypeScript, Python, PHP, Dart)
7
- * - Zero native dependencies — 100% portable across Windows/Mac/Linux
8
- * - Two-phase write workflow (dry-run + confirmation token)
9
- * - Middleware pipeline: rate limiting, file locking, audit logging, telemetry
10
- * - Mandatory security boundaries on ALL handlers
11
- * - Persistent WASM SQLite cache with <100ms hits
12
- * - Structured logging with pino (JSON to stderr, MCP-safe)
13
- * - File watcher with chokidar for auto cache invalidation
14
- * - Fuzzy search with fuse.js + pagination
15
- * - Token optimization: compact diffs, auto-optimize output
3
+ * mcp-code-context v3.7.0 - Tree-sitter WASM Edition (thin bootstrap)
16
4
  */
17
5
  export {};