@bhimudev/gnanai 0.4.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 (274) hide show
  1. package/README.md +270 -0
  2. package/dist/bin/cli.d.ts +3 -0
  3. package/dist/bin/cli.d.ts.map +1 -0
  4. package/dist/bin/cli.js +188 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/commands/cleanup.d.ts +21 -0
  7. package/dist/commands/cleanup.d.ts.map +1 -0
  8. package/dist/commands/cleanup.js +380 -0
  9. package/dist/commands/cleanup.js.map +1 -0
  10. package/dist/commands/dispatch.d.ts +13 -0
  11. package/dist/commands/dispatch.d.ts.map +1 -0
  12. package/dist/commands/dispatch.js +85 -0
  13. package/dist/commands/dispatch.js.map +1 -0
  14. package/dist/commands/doctor.d.ts +2 -0
  15. package/dist/commands/doctor.d.ts.map +1 -0
  16. package/dist/commands/doctor.js +155 -0
  17. package/dist/commands/doctor.js.map +1 -0
  18. package/dist/commands/generate.d.ts +3 -0
  19. package/dist/commands/generate.d.ts.map +1 -0
  20. package/dist/commands/generate.js +167 -0
  21. package/dist/commands/generate.js.map +1 -0
  22. package/dist/commands/init.d.ts +10 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +711 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/knowledge-sync.d.ts +69 -0
  27. package/dist/commands/knowledge-sync.d.ts.map +1 -0
  28. package/dist/commands/knowledge-sync.js +661 -0
  29. package/dist/commands/knowledge-sync.js.map +1 -0
  30. package/dist/commands/knowledge.d.ts +35 -0
  31. package/dist/commands/knowledge.d.ts.map +1 -0
  32. package/dist/commands/knowledge.js +254 -0
  33. package/dist/commands/knowledge.js.map +1 -0
  34. package/dist/commands/rollback.d.ts +13 -0
  35. package/dist/commands/rollback.d.ts.map +1 -0
  36. package/dist/commands/rollback.js +186 -0
  37. package/dist/commands/rollback.js.map +1 -0
  38. package/dist/commands/setup-config.d.ts +6 -0
  39. package/dist/commands/setup-config.d.ts.map +1 -0
  40. package/dist/commands/setup-config.js +663 -0
  41. package/dist/commands/setup-config.js.map +1 -0
  42. package/dist/commands/setup-project.d.ts +6 -0
  43. package/dist/commands/setup-project.d.ts.map +1 -0
  44. package/dist/commands/setup-project.js +361 -0
  45. package/dist/commands/setup-project.js.map +1 -0
  46. package/dist/commands/setup.d.ts +3 -0
  47. package/dist/commands/setup.d.ts.map +1 -0
  48. package/dist/commands/setup.js +293 -0
  49. package/dist/commands/setup.js.map +1 -0
  50. package/dist/commands/status.d.ts +51 -0
  51. package/dist/commands/status.d.ts.map +1 -0
  52. package/dist/commands/status.js +182 -0
  53. package/dist/commands/status.js.map +1 -0
  54. package/dist/commands/uninstall.d.ts +3 -0
  55. package/dist/commands/uninstall.d.ts.map +1 -0
  56. package/dist/commands/uninstall.js +173 -0
  57. package/dist/commands/uninstall.js.map +1 -0
  58. package/dist/commands/update.d.ts +10 -0
  59. package/dist/commands/update.d.ts.map +1 -0
  60. package/dist/commands/update.js +435 -0
  61. package/dist/commands/update.js.map +1 -0
  62. package/dist/commands/worktree.d.ts +30 -0
  63. package/dist/commands/worktree.d.ts.map +1 -0
  64. package/dist/commands/worktree.js +262 -0
  65. package/dist/commands/worktree.js.map +1 -0
  66. package/dist/generator/claude-cli.d.ts +24 -0
  67. package/dist/generator/claude-cli.d.ts.map +1 -0
  68. package/dist/generator/claude-cli.js +239 -0
  69. package/dist/generator/claude-cli.js.map +1 -0
  70. package/dist/generator/prompt-builder.d.ts +7 -0
  71. package/dist/generator/prompt-builder.d.ts.map +1 -0
  72. package/dist/generator/prompt-builder.js +144 -0
  73. package/dist/generator/prompt-builder.js.map +1 -0
  74. package/dist/index.d.ts +36 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +45 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/mcp/embeddings.d.ts +53 -0
  79. package/dist/mcp/embeddings.d.ts.map +1 -0
  80. package/dist/mcp/embeddings.js +68 -0
  81. package/dist/mcp/embeddings.js.map +1 -0
  82. package/dist/mcp/hybrid-search.d.ts +25 -0
  83. package/dist/mcp/hybrid-search.d.ts.map +1 -0
  84. package/dist/mcp/hybrid-search.js +72 -0
  85. package/dist/mcp/hybrid-search.js.map +1 -0
  86. package/dist/mcp/knowledge-server.d.ts +4 -0
  87. package/dist/mcp/knowledge-server.d.ts.map +1 -0
  88. package/dist/mcp/knowledge-server.js +294 -0
  89. package/dist/mcp/knowledge-server.js.map +1 -0
  90. package/dist/mcp/knowledge-utils.d.ts +65 -0
  91. package/dist/mcp/knowledge-utils.d.ts.map +1 -0
  92. package/dist/mcp/knowledge-utils.js +207 -0
  93. package/dist/mcp/knowledge-utils.js.map +1 -0
  94. package/dist/mcp/search-factory.d.ts +9 -0
  95. package/dist/mcp/search-factory.d.ts.map +1 -0
  96. package/dist/mcp/search-factory.js +23 -0
  97. package/dist/mcp/search-factory.js.map +1 -0
  98. package/dist/mcp/search-index.d.ts +45 -0
  99. package/dist/mcp/search-index.d.ts.map +1 -0
  100. package/dist/mcp/search-index.js +2 -0
  101. package/dist/mcp/search-index.js.map +1 -0
  102. package/dist/mcp/search-minisearch.d.ts +46 -0
  103. package/dist/mcp/search-minisearch.d.ts.map +1 -0
  104. package/dist/mcp/search-minisearch.js +99 -0
  105. package/dist/mcp/search-minisearch.js.map +1 -0
  106. package/dist/mcp/search-sqlite.d.ts +30 -0
  107. package/dist/mcp/search-sqlite.d.ts.map +1 -0
  108. package/dist/mcp/search-sqlite.js +188 -0
  109. package/dist/mcp/search-sqlite.js.map +1 -0
  110. package/dist/mcp/vector-store.d.ts +52 -0
  111. package/dist/mcp/vector-store.d.ts.map +1 -0
  112. package/dist/mcp/vector-store.js +183 -0
  113. package/dist/mcp/vector-store.js.map +1 -0
  114. package/dist/scaffold/copy-core-agents.d.ts +2 -0
  115. package/dist/scaffold/copy-core-agents.d.ts.map +1 -0
  116. package/dist/scaffold/copy-core-agents.js +90 -0
  117. package/dist/scaffold/copy-core-agents.js.map +1 -0
  118. package/dist/scaffold/create-claude-settings.d.ts +40 -0
  119. package/dist/scaffold/create-claude-settings.d.ts.map +1 -0
  120. package/dist/scaffold/create-claude-settings.js +422 -0
  121. package/dist/scaffold/create-claude-settings.js.map +1 -0
  122. package/dist/scaffold/create-config.d.ts +14 -0
  123. package/dist/scaffold/create-config.d.ts.map +1 -0
  124. package/dist/scaffold/create-config.js +199 -0
  125. package/dist/scaffold/create-config.js.map +1 -0
  126. package/dist/scaffold/create-project-description.d.ts +12 -0
  127. package/dist/scaffold/create-project-description.d.ts.map +1 -0
  128. package/dist/scaffold/create-project-description.js +104 -0
  129. package/dist/scaffold/create-project-description.js.map +1 -0
  130. package/dist/scaffold/create-structure.d.ts +2 -0
  131. package/dist/scaffold/create-structure.d.ts.map +1 -0
  132. package/dist/scaffold/create-structure.js +146 -0
  133. package/dist/scaffold/create-structure.js.map +1 -0
  134. package/dist/types/dependency-analysis.d.ts +11 -0
  135. package/dist/types/dependency-analysis.d.ts.map +1 -0
  136. package/dist/types/dependency-analysis.js +2 -0
  137. package/dist/types/dependency-analysis.js.map +1 -0
  138. package/dist/types/index.d.ts +526 -0
  139. package/dist/types/index.d.ts.map +1 -0
  140. package/dist/types/index.js +3 -0
  141. package/dist/types/index.js.map +1 -0
  142. package/dist/types/task.d.ts +25 -0
  143. package/dist/types/task.d.ts.map +1 -0
  144. package/dist/types/task.js +3 -0
  145. package/dist/types/task.js.map +1 -0
  146. package/dist/utils/analyze-files.d.ts +7 -0
  147. package/dist/utils/analyze-files.d.ts.map +1 -0
  148. package/dist/utils/analyze-files.js +27 -0
  149. package/dist/utils/analyze-files.js.map +1 -0
  150. package/dist/utils/backup.d.ts +102 -0
  151. package/dist/utils/backup.d.ts.map +1 -0
  152. package/dist/utils/backup.js +352 -0
  153. package/dist/utils/backup.js.map +1 -0
  154. package/dist/utils/ci-provider.d.ts +23 -0
  155. package/dist/utils/ci-provider.d.ts.map +1 -0
  156. package/dist/utils/ci-provider.js +525 -0
  157. package/dist/utils/ci-provider.js.map +1 -0
  158. package/dist/utils/ci-status.d.ts +57 -0
  159. package/dist/utils/ci-status.d.ts.map +1 -0
  160. package/dist/utils/ci-status.js +349 -0
  161. package/dist/utils/ci-status.js.map +1 -0
  162. package/dist/utils/dependency-analysis.d.ts +34 -0
  163. package/dist/utils/dependency-analysis.d.ts.map +1 -0
  164. package/dist/utils/dependency-analysis.js +298 -0
  165. package/dist/utils/dependency-analysis.js.map +1 -0
  166. package/dist/utils/detect-git.d.ts +57 -0
  167. package/dist/utils/detect-git.d.ts.map +1 -0
  168. package/dist/utils/detect-git.js +439 -0
  169. package/dist/utils/detect-git.js.map +1 -0
  170. package/dist/utils/detect-mcp.d.ts +32 -0
  171. package/dist/utils/detect-mcp.d.ts.map +1 -0
  172. package/dist/utils/detect-mcp.js +178 -0
  173. package/dist/utils/detect-mcp.js.map +1 -0
  174. package/dist/utils/detect-project.d.ts +3 -0
  175. package/dist/utils/detect-project.d.ts.map +1 -0
  176. package/dist/utils/detect-project.js +155 -0
  177. package/dist/utils/detect-project.js.map +1 -0
  178. package/dist/utils/file-comparison.d.ts +89 -0
  179. package/dist/utils/file-comparison.d.ts.map +1 -0
  180. package/dist/utils/file-comparison.js +301 -0
  181. package/dist/utils/file-comparison.js.map +1 -0
  182. package/dist/utils/file-merger.d.ts +74 -0
  183. package/dist/utils/file-merger.d.ts.map +1 -0
  184. package/dist/utils/file-merger.js +350 -0
  185. package/dist/utils/file-merger.js.map +1 -0
  186. package/dist/utils/logger.d.ts +26 -0
  187. package/dist/utils/logger.d.ts.map +1 -0
  188. package/dist/utils/logger.js +72 -0
  189. package/dist/utils/logger.js.map +1 -0
  190. package/dist/utils/managed-process.d.ts +109 -0
  191. package/dist/utils/managed-process.d.ts.map +1 -0
  192. package/dist/utils/managed-process.js +481 -0
  193. package/dist/utils/managed-process.js.map +1 -0
  194. package/dist/utils/merge-claude-settings.d.ts +65 -0
  195. package/dist/utils/merge-claude-settings.d.ts.map +1 -0
  196. package/dist/utils/merge-claude-settings.js +133 -0
  197. package/dist/utils/merge-claude-settings.js.map +1 -0
  198. package/dist/utils/migration.d.ts +74 -0
  199. package/dist/utils/migration.d.ts.map +1 -0
  200. package/dist/utils/migration.js +345 -0
  201. package/dist/utils/migration.js.map +1 -0
  202. package/dist/utils/process-health.d.ts +51 -0
  203. package/dist/utils/process-health.d.ts.map +1 -0
  204. package/dist/utils/process-health.js +123 -0
  205. package/dist/utils/process-health.js.map +1 -0
  206. package/dist/utils/process-registry.d.ts +20 -0
  207. package/dist/utils/process-registry.d.ts.map +1 -0
  208. package/dist/utils/process-registry.js +151 -0
  209. package/dist/utils/process-registry.js.map +1 -0
  210. package/dist/utils/process-tree.d.ts +51 -0
  211. package/dist/utils/process-tree.d.ts.map +1 -0
  212. package/dist/utils/process-tree.js +499 -0
  213. package/dist/utils/process-tree.js.map +1 -0
  214. package/dist/utils/repair-mcp-config.d.ts +15 -0
  215. package/dist/utils/repair-mcp-config.d.ts.map +1 -0
  216. package/dist/utils/repair-mcp-config.js +129 -0
  217. package/dist/utils/repair-mcp-config.js.map +1 -0
  218. package/dist/utils/task-lifecycle.d.ts +60 -0
  219. package/dist/utils/task-lifecycle.d.ts.map +1 -0
  220. package/dist/utils/task-lifecycle.js +310 -0
  221. package/dist/utils/task-lifecycle.js.map +1 -0
  222. package/dist/utils/update-agent-mcp.d.ts +7 -0
  223. package/dist/utils/update-agent-mcp.d.ts.map +1 -0
  224. package/dist/utils/update-agent-mcp.js +115 -0
  225. package/dist/utils/update-agent-mcp.js.map +1 -0
  226. package/dist/utils/update-agent-templates.d.ts +6 -0
  227. package/dist/utils/update-agent-templates.d.ts.map +1 -0
  228. package/dist/utils/update-agent-templates.js +56 -0
  229. package/dist/utils/update-agent-templates.js.map +1 -0
  230. package/dist/utils/update-config-ci.d.ts +7 -0
  231. package/dist/utils/update-config-ci.d.ts.map +1 -0
  232. package/dist/utils/update-config-ci.js +72 -0
  233. package/dist/utils/update-config-ci.js.map +1 -0
  234. package/dist/utils/update-config-git.d.ts +18 -0
  235. package/dist/utils/update-config-git.d.ts.map +1 -0
  236. package/dist/utils/update-config-git.js +146 -0
  237. package/dist/utils/update-config-git.js.map +1 -0
  238. package/dist/utils/update-config-mcp.d.ts +7 -0
  239. package/dist/utils/update-config-mcp.d.ts.map +1 -0
  240. package/dist/utils/update-config-mcp.js +98 -0
  241. package/dist/utils/update-config-mcp.js.map +1 -0
  242. package/dist/utils/validate-config.d.ts +3 -0
  243. package/dist/utils/validate-config.d.ts.map +1 -0
  244. package/dist/utils/validate-config.js +109 -0
  245. package/dist/utils/validate-config.js.map +1 -0
  246. package/dist/utils/version-tracker.d.ts +130 -0
  247. package/dist/utils/version-tracker.d.ts.map +1 -0
  248. package/dist/utils/version-tracker.js +298 -0
  249. package/dist/utils/version-tracker.js.map +1 -0
  250. package/dist/utils/worktree.d.ts +68 -0
  251. package/dist/utils/worktree.d.ts.map +1 -0
  252. package/dist/utils/worktree.js +446 -0
  253. package/dist/utils/worktree.js.map +1 -0
  254. package/package.json +77 -0
  255. package/templates/ARCHAI_README.md +329 -0
  256. package/templates/CLAUDE.md +67 -0
  257. package/templates/PROMPTS.md +506 -0
  258. package/templates/core-agents/boss-agent.md +671 -0
  259. package/templates/core-agents/cleanup-agent.md +145 -0
  260. package/templates/core-agents/code-reviewer.md +175 -0
  261. package/templates/core-agents/critical-reviewer.md +117 -0
  262. package/templates/core-agents/deep-analyst.md +216 -0
  263. package/templates/core-agents/finalization-agent.md +252 -0
  264. package/templates/core-agents/git-coordinator.md +240 -0
  265. package/templates/core-agents/implementation-agent.md +151 -0
  266. package/templates/core-agents/maestro-agent.md +413 -0
  267. package/templates/core-agents/maestro-headless-agent.md +422 -0
  268. package/templates/core-agents/plan-validator.md +198 -0
  269. package/templates/core-agents/quick-fix.md +56 -0
  270. package/templates/core-agents/routing-templates.md +338 -0
  271. package/templates/core-agents/task-orchestrator.md +143 -0
  272. package/templates/core-agents/task-prep.md +202 -0
  273. package/templates/core-agents/tdd-designer.md +143 -0
  274. package/templates/specialist-meta.md +275 -0
@@ -0,0 +1,45 @@
1
+ import type { KnowledgeEntry } from './knowledge-utils.js';
2
+ /**
3
+ * Options for search queries.
4
+ */
5
+ export interface SearchOptions {
6
+ /** Filter results to a specific category. */
7
+ category?: string;
8
+ /** Maximum number of results to return (default: 5). */
9
+ limit?: number;
10
+ }
11
+ /**
12
+ * A single search result with match context and relevance score.
13
+ */
14
+ export interface SearchResult {
15
+ /** Entry ID (filename without .md). */
16
+ id: string;
17
+ /** Entry title. */
18
+ title: string;
19
+ /** Entry category (decisions, patterns, etc.). */
20
+ category: string;
21
+ /** Highlighted match context snippet. */
22
+ snippet: string;
23
+ /** Relevance score (lower = more relevant for BM25, higher = more relevant for MiniSearch). */
24
+ score: number;
25
+ /** True when semantic search was unavailable and results are keyword-only fallback. */
26
+ degraded?: boolean;
27
+ }
28
+ /**
29
+ * Abstract search index interface.
30
+ * Both SQLite FTS5 and MiniSearch implementations conform to this.
31
+ */
32
+ export interface SearchIndex {
33
+ /** Full-text search with optional category filter and result limit. */
34
+ search(query: string, options?: SearchOptions): SearchResult[];
35
+ /** Add or update an entry in the index. */
36
+ add(entry: KnowledgeEntry): void;
37
+ /** Remove an entry from the index by ID. */
38
+ remove(id: string): void;
39
+ /** Rebuild the entire index from the given entries. */
40
+ rebuild(entries: KnowledgeEntry[]): void;
41
+ /** Close the index and release resources. */
42
+ close(): void;
43
+ }
44
+ export type { KnowledgeEntry };
45
+ //# sourceMappingURL=search-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/mcp/search-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,+FAA+F;IAC/F,KAAK,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,EAAE,CAAC;IAE/D,2CAA2C;IAC3C,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;IAEjC,4CAA4C;IAC5C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB,uDAAuD;IACvD,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEzC,6CAA6C;IAC7C,KAAK,IAAI,IAAI,CAAC;CACf;AAED,YAAY,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-index.js","sourceRoot":"","sources":["../../src/mcp/search-index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import type { SearchIndex, SearchOptions, SearchResult, KnowledgeEntry } from './search-index.js';
2
+ interface MiniSearchConstructor {
3
+ new <T>(options: MiniSearchOptions<T>): MiniSearchInstance<T>;
4
+ }
5
+ interface MiniSearchOptions<T> {
6
+ fields: string[];
7
+ storeFields?: string[];
8
+ searchOptions?: {
9
+ boost?: Record<string, number>;
10
+ fuzzy?: number | boolean;
11
+ prefix?: boolean;
12
+ };
13
+ idField?: string;
14
+ }
15
+ interface MiniSearchInstance<T> {
16
+ search(query: string, options?: {
17
+ boost?: Record<string, number>;
18
+ fuzzy?: number | boolean;
19
+ prefix?: boolean;
20
+ }): Array<{
21
+ id: string;
22
+ score: number;
23
+ match: Record<string, string[]>;
24
+ } & Record<string, unknown>>;
25
+ add(doc: T): void;
26
+ remove(doc: T): void;
27
+ removeAll(): void;
28
+ addAll(docs: T[]): void;
29
+ }
30
+ /**
31
+ * MiniSearch-backed search index (pure JS fallback).
32
+ * Used when better-sqlite3 is not available.
33
+ */
34
+ export declare class MiniSearchIndex implements SearchIndex {
35
+ private index;
36
+ private docs;
37
+ constructor(MiniSearch: MiniSearchConstructor);
38
+ search(query: string, options?: SearchOptions): SearchResult[];
39
+ add(entry: KnowledgeEntry): void;
40
+ remove(id: string): void;
41
+ rebuild(entries: KnowledgeEntry[]): void;
42
+ close(): void;
43
+ private generateSnippet;
44
+ }
45
+ export {};
46
+ //# sourceMappingURL=search-minisearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-minisearch.d.ts","sourceRoot":"","sources":["../../src/mcp/search-minisearch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGlG,UAAU,qBAAqB;IAC7B,KAAK,CAAC,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED,UAAU,iBAAiB,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE;QACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QACzB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,kBAAkB,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACjN,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IAClB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;IACrB,SAAS,IAAI,IAAI,CAAC;IAClB,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;CACzB;AAUD;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,IAAI,CAAoD;gBAEpD,UAAU,EAAE,qBAAqB;IAS7C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,EAAE;IA4B9D,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAqBhC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAUxB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAQxC,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,eAAe;CAmBxB"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * MiniSearch-backed search index (pure JS fallback).
3
+ * Used when better-sqlite3 is not available.
4
+ */
5
+ export class MiniSearchIndex {
6
+ index;
7
+ docs;
8
+ constructor(MiniSearch) {
9
+ this.index = new MiniSearch({
10
+ fields: ['title', 'content', 'tags'],
11
+ storeFields: ['id', 'title', 'category'],
12
+ idField: 'id',
13
+ });
14
+ this.docs = new Map();
15
+ }
16
+ search(query, options) {
17
+ const limit = options?.limit ?? 5;
18
+ let results = this.index.search(query, {
19
+ boost: { title: 2, content: 1, tags: 1.5 },
20
+ fuzzy: 0.2,
21
+ prefix: true,
22
+ });
23
+ if (options?.category) {
24
+ results = results.filter(r => {
25
+ const doc = this.docs.get(r.id);
26
+ return doc && doc.category === options.category;
27
+ });
28
+ }
29
+ return results.slice(0, limit).map(r => {
30
+ const doc = this.docs.get(r.id);
31
+ return {
32
+ id: r.id,
33
+ title: doc?.title ?? '',
34
+ category: doc?.category ?? '',
35
+ snippet: this.generateSnippet(doc?.fullContent ?? '', query),
36
+ score: r.score,
37
+ };
38
+ });
39
+ }
40
+ add(entry) {
41
+ const doc = {
42
+ id: entry.id,
43
+ title: entry.title,
44
+ content: entry.content,
45
+ tags: entry.tags?.join(', ') ?? '',
46
+ category: entry.category,
47
+ };
48
+ // Remove existing if present (MiniSearch doesn't support upsert)
49
+ if (this.docs.has(entry.id)) {
50
+ try {
51
+ const oldDoc = this.docs.get(entry.id);
52
+ this.index.remove({ id: oldDoc.id, title: oldDoc.title, content: oldDoc.fullContent, tags: oldDoc.tags ?? '', category: oldDoc.category });
53
+ }
54
+ catch { /* ignore remove errors */ }
55
+ }
56
+ this.index.add(doc);
57
+ this.docs.set(entry.id, { ...doc, fullContent: entry.content, tags: entry.tags?.join(', ') ?? '' });
58
+ }
59
+ remove(id) {
60
+ const doc = this.docs.get(id);
61
+ if (doc) {
62
+ try {
63
+ this.index.remove({ id: doc.id, title: doc.title, content: doc.fullContent, tags: doc.tags ?? '', category: doc.category });
64
+ }
65
+ catch { /* ignore */ }
66
+ this.docs.delete(id);
67
+ }
68
+ }
69
+ rebuild(entries) {
70
+ this.index.removeAll();
71
+ this.docs.clear();
72
+ for (const entry of entries) {
73
+ this.add(entry);
74
+ }
75
+ }
76
+ close() {
77
+ // No-op for in-memory index
78
+ }
79
+ generateSnippet(content, query) {
80
+ const terms = query.toLowerCase().split(/\s+/).filter(t => t.length > 2 && !['and', 'or', 'not'].includes(t));
81
+ const lowerContent = content.toLowerCase();
82
+ for (const term of terms) {
83
+ const idx = lowerContent.indexOf(term);
84
+ if (idx >= 0) {
85
+ const start = Math.max(0, idx - 40);
86
+ const end = Math.min(content.length, idx + term.length + 40);
87
+ let snippet = content.slice(start, end);
88
+ if (start > 0)
89
+ snippet = '...' + snippet;
90
+ if (end < content.length)
91
+ snippet = snippet + '...';
92
+ return snippet;
93
+ }
94
+ }
95
+ // No match found in content, return first 80 chars
96
+ return content.length > 80 ? content.slice(0, 80) + '...' : content;
97
+ }
98
+ }
99
+ //# sourceMappingURL=search-minisearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-minisearch.js","sourceRoot":"","sources":["../../src/mcp/search-minisearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { SearchIndex, SearchOptions, SearchResult, KnowledgeEntry } from './search-index.js';
2
+ type DatabaseConstructor = new (filename: string) => DatabaseInstance;
3
+ interface DatabaseInstance {
4
+ pragma(pragma: string): unknown;
5
+ exec(sql: string): void;
6
+ prepare(sql: string): Statement;
7
+ close(): void;
8
+ }
9
+ interface Statement {
10
+ run(...params: unknown[]): unknown;
11
+ get(...params: unknown[]): unknown;
12
+ all(...params: unknown[]): unknown[];
13
+ }
14
+ export declare class SqliteSearchIndex implements SearchIndex {
15
+ private db;
16
+ constructor(db: DatabaseInstance);
17
+ search(query: string, options?: SearchOptions): SearchResult[];
18
+ add(entry: KnowledgeEntry): void;
19
+ remove(id: string): void;
20
+ rebuild(entries: KnowledgeEntry[]): void;
21
+ close(): void;
22
+ }
23
+ export declare function needsRebuild(dbPath: string, groupPath: string): Promise<boolean>;
24
+ export declare function openOrCreateDb(dbPath: string, Database: DatabaseConstructor, groupPath: string): Promise<{
25
+ db: DatabaseInstance;
26
+ wasRebuilt: boolean;
27
+ }>;
28
+ export declare function createSqliteSearchIndex(groupPath: string, Database: DatabaseConstructor, entries: KnowledgeEntry[]): Promise<SqliteSearchIndex>;
29
+ export {};
30
+ //# sourceMappingURL=search-sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-sqlite.d.ts","sourceRoot":"","sources":["../../src/mcp/search-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMlG,KAAK,mBAAmB,GAAG,KAAK,QAAQ,EAAE,MAAM,KAAK,gBAAgB,CAAC;AAEtE,UAAU,gBAAgB;IACxB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,UAAU,SAAS;IACjB,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;CACtC;AAkDD,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,EAAE,CAAmB;gBAEjB,EAAE,EAAE,gBAAgB;IAIhC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,EAAE;IAuB9D,GAAG,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAQhC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIxB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAUxC,KAAK,IAAI,IAAI;CAGd;AAMD,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAStF;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,mBAAmB,EAC7B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,EAAE,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA8BxD;AAED,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,mBAAmB,EAC7B,OAAO,EAAE,cAAc,EAAE,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAiB5B"}
@@ -0,0 +1,188 @@
1
+ import fsSync from 'node:fs';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ import { listEntryFiles, parseEntry } from './knowledge-utils.js';
5
+ const SCHEMA_SQL = [
6
+ 'CREATE TABLE IF NOT EXISTS entries (',
7
+ ' id TEXT PRIMARY KEY,',
8
+ ' category TEXT NOT NULL,',
9
+ ' title TEXT NOT NULL,',
10
+ ' content TEXT NOT NULL,',
11
+ ' tags TEXT,',
12
+ ' source_repo TEXT,',
13
+ ' created TEXT NOT NULL',
14
+ ');',
15
+ '',
16
+ 'CREATE VIRTUAL TABLE IF NOT EXISTS entries_fts USING fts5(',
17
+ ' title, content, tags,',
18
+ " content='entries',",
19
+ " content_rowid='rowid',",
20
+ " tokenize='porter unicode61'",
21
+ ');',
22
+ '',
23
+ 'CREATE TRIGGER IF NOT EXISTS entries_ai AFTER INSERT ON entries BEGIN',
24
+ ' INSERT INTO entries_fts(rowid, title, content, tags) VALUES (new.rowid, new.title, new.content, new.tags);',
25
+ 'END;',
26
+ '',
27
+ 'CREATE TRIGGER IF NOT EXISTS entries_au AFTER UPDATE ON entries BEGIN',
28
+ " INSERT INTO entries_fts(entries_fts, rowid, title, content, tags) VALUES ('delete', old.rowid, old.title, old.content, old.tags);",
29
+ ' INSERT INTO entries_fts(rowid, title, content, tags) VALUES (new.rowid, new.title, new.content, new.tags);',
30
+ 'END;',
31
+ '',
32
+ 'CREATE TRIGGER IF NOT EXISTS entries_ad AFTER DELETE ON entries BEGIN',
33
+ " INSERT INTO entries_fts(entries_fts, rowid, title, content, tags) VALUES ('delete', old.rowid, old.title, old.content, old.tags);",
34
+ 'END;',
35
+ ].join('\n');
36
+ const SEARCH_SQL = [
37
+ 'SELECT e.id, e.title, e.category,',
38
+ " snippet(entries_fts, 1, '>>', '<<', '...', 30) as snippet,",
39
+ ' bm25(entries_fts) as score',
40
+ 'FROM entries e',
41
+ 'JOIN entries_fts ON e.rowid = entries_fts.rowid',
42
+ 'WHERE entries_fts MATCH ?',
43
+ ' AND (? IS NULL OR e.category = ?)',
44
+ 'ORDER BY score',
45
+ 'LIMIT ?',
46
+ ].join('\n');
47
+ const INSERT_SQL = 'INSERT OR REPLACE INTO entries (id, category, title, content, tags, source_repo, created) VALUES (?, ?, ?, ?, ?, ?, ?)';
48
+ const DELETE_SQL = 'DELETE FROM entries WHERE id = ?';
49
+ export class SqliteSearchIndex {
50
+ db;
51
+ constructor(db) {
52
+ this.db = db;
53
+ }
54
+ search(query, options) {
55
+ if (!query || !query.trim())
56
+ return [];
57
+ const category = options?.category ?? null;
58
+ const limit = options?.limit ?? 5;
59
+ try {
60
+ const rows = this.db.prepare(SEARCH_SQL).all(query, category, category, limit);
61
+ return rows.map(row => ({
62
+ id: row.id, title: row.title, category: row.category,
63
+ snippet: row.snippet, score: row.score,
64
+ }));
65
+ }
66
+ catch (err) {
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ if (message.includes('fts5')) {
69
+ throw new Error('Invalid search query syntax. Supported: keywords, phrase search, prefix*, AND/OR/NOT. Details: ' + message);
70
+ }
71
+ throw err;
72
+ }
73
+ }
74
+ add(entry) {
75
+ const tags = entry.tags?.join(', ') ?? '';
76
+ this.db.prepare(INSERT_SQL).run(entry.id, entry.category, entry.title, entry.content, tags, entry.source_repo ?? null, entry.created);
77
+ }
78
+ remove(id) {
79
+ this.db.prepare(DELETE_SQL).run(id);
80
+ }
81
+ rebuild(entries) {
82
+ this.db.exec('DELETE FROM entries');
83
+ this.db.exec("INSERT INTO entries_fts(entries_fts) VALUES('rebuild')");
84
+ const stmt = this.db.prepare(INSERT_SQL);
85
+ for (const entry of entries) {
86
+ const tags = entry.tags?.join(', ') ?? '';
87
+ stmt.run(entry.id, entry.category, entry.title, entry.content, tags, entry.source_repo ?? null, entry.created);
88
+ }
89
+ }
90
+ close() {
91
+ try {
92
+ this.db.close();
93
+ }
94
+ catch { /* ignore */ }
95
+ }
96
+ }
97
+ function createSchema(db) {
98
+ db.exec(SCHEMA_SQL);
99
+ }
100
+ export async function needsRebuild(dbPath, groupPath) {
101
+ if (!(await fs.pathExists(dbPath)))
102
+ return true;
103
+ let dbMtime;
104
+ try {
105
+ dbMtime = (await fs.stat(dbPath)).mtimeMs;
106
+ }
107
+ catch {
108
+ return true;
109
+ }
110
+ const files = await listEntryFiles(groupPath);
111
+ for (const file of files) {
112
+ try {
113
+ if ((await fs.stat(file)).mtimeMs > dbMtime)
114
+ return true;
115
+ }
116
+ catch { /* skip */ }
117
+ }
118
+ return false;
119
+ }
120
+ export async function openOrCreateDb(dbPath, Database, groupPath) {
121
+ let openedDb = null;
122
+ try {
123
+ openedDb = new Database(dbPath);
124
+ openedDb.pragma('journal_mode=WAL');
125
+ const check = openedDb.pragma('integrity_check');
126
+ if (check.length > 0 && check[0].integrity_check !== 'ok')
127
+ throw new Error('Integrity check failed');
128
+ createSchema(openedDb);
129
+ return { db: openedDb, wasRebuilt: false };
130
+ }
131
+ catch (err) {
132
+ // Close handle before deleting (required on Windows to avoid EBUSY)
133
+ if (openedDb)
134
+ try {
135
+ openedDb.close();
136
+ }
137
+ catch { /* ignore */ }
138
+ process.stderr.write('Index corrupt, rebuilding: ' + (err instanceof Error ? err.message : String(err)) + '\n');
139
+ try {
140
+ fsSync.unlinkSync(dbPath);
141
+ }
142
+ catch { /* ignore */ }
143
+ try {
144
+ fsSync.unlinkSync(dbPath + '-wal');
145
+ }
146
+ catch { /* ignore */ }
147
+ try {
148
+ fsSync.unlinkSync(dbPath + '-shm');
149
+ }
150
+ catch { /* ignore */ }
151
+ const db = new Database(dbPath);
152
+ db.pragma('journal_mode=WAL');
153
+ createSchema(db);
154
+ const files = await listEntryFiles(groupPath);
155
+ const insertStmt = db.prepare(INSERT_SQL);
156
+ for (const file of files) {
157
+ try {
158
+ const entry = await parseEntry(file);
159
+ const tags = entry.tags?.join(', ') ?? '';
160
+ insertStmt.run(entry.id, entry.category, entry.title, entry.content, tags, entry.source_repo ?? null, entry.created);
161
+ }
162
+ catch { /* skip malformed */ }
163
+ }
164
+ return { db, wasRebuilt: true };
165
+ }
166
+ }
167
+ export async function createSqliteSearchIndex(groupPath, Database, entries) {
168
+ const dbPath = path.join(groupPath, '.index.db');
169
+ const { db, wasRebuilt } = await openOrCreateDb(dbPath, Database, groupPath);
170
+ const index = new SqliteSearchIndex(db);
171
+ if (!wasRebuilt) {
172
+ const stale = await needsRebuild(dbPath, groupPath);
173
+ if (stale) {
174
+ index.rebuild(entries);
175
+ }
176
+ else if (entries.length > 0) {
177
+ // Check if DB is empty (e.g., newly created) and needs populating
178
+ try {
179
+ const row = db.prepare('SELECT COUNT(*) as cnt FROM entries').get();
180
+ if (!row || row.cnt === 0)
181
+ index.rebuild(entries);
182
+ }
183
+ catch { /* table may not exist yet */ }
184
+ }
185
+ }
186
+ return index;
187
+ }
188
+ //# sourceMappingURL=search-sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-sqlite.js","sourceRoot":"","sources":["../../src/mcp/search-sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Vector store for semantic search.
3
+ * Stores embedding vectors in a .vectors.json file per knowledge group.
4
+ * Uses brute-force cosine similarity for search (fast at 50-500 entries).
5
+ * Write operations are serialized via a mutex to prevent corruption.
6
+ */
7
+ import type { EmbeddingEngine } from "./embeddings.js";
8
+ import type { KnowledgeEntry } from "./knowledge-utils.js";
9
+ export interface VectorEntry {
10
+ id: string;
11
+ vector: number[];
12
+ category: string;
13
+ title: string;
14
+ snippetText: string;
15
+ }
16
+ export interface VectorStoreData {
17
+ model: string;
18
+ dimensions: number;
19
+ entries: VectorEntry[];
20
+ }
21
+ export interface VectorSearchResult {
22
+ id: string;
23
+ title: string;
24
+ category: string;
25
+ snippet: string;
26
+ score: number;
27
+ }
28
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
29
+ export declare function truncateForSnippet(text: string, maxLen?: number): string;
30
+ export declare class VectorStore {
31
+ private data;
32
+ private filePath;
33
+ private engine;
34
+ private writeLock;
35
+ private writeQueue;
36
+ constructor(filePath: string, engine: EmbeddingEngine);
37
+ get entryCount(): number;
38
+ has(id: string): boolean;
39
+ load(onRebuildNeeded?: () => Promise<KnowledgeEntry[]>): Promise<void>;
40
+ save(): Promise<void>;
41
+ add(id: string, vector: number[], metadata: {
42
+ category: string;
43
+ title: string;
44
+ content: string;
45
+ }): Promise<void>;
46
+ remove(id: string): Promise<void>;
47
+ search(queryVector: number[], topK?: number): VectorSearchResult[];
48
+ rebuild(entries: KnowledgeEntry[]): Promise<void>;
49
+ private acquireLock;
50
+ private releaseLock;
51
+ }
52
+ //# sourceMappingURL=vector-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/mcp/vector-store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAYjE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,MAAM,CAGrE;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAyB;gBAE/B,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe;IAUrD,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIlB,IAAI,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CtE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAarB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBhH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQvC,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,SAAI,GAAG,kBAAkB,EAAE;IAevD,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAmCzC,WAAW;IAUzB,OAAO,CAAC,WAAW;CAQpB"}