gencode-ai 0.1.0 → 0.1.2

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 (356) hide show
  1. package/.gencode/settings.local.json +7 -0
  2. package/README.md +20 -102
  3. package/dist/agent/agent.d.ts +43 -2
  4. package/dist/agent/agent.d.ts.map +1 -1
  5. package/dist/agent/agent.js +90 -17
  6. package/dist/agent/agent.js.map +1 -1
  7. package/dist/agent/types.d.ts +9 -1
  8. package/dist/agent/types.d.ts.map +1 -1
  9. package/dist/cli/components/AllModelsSelector.d.ts +11 -0
  10. package/dist/cli/components/AllModelsSelector.d.ts.map +1 -0
  11. package/dist/cli/components/AllModelsSelector.js +153 -0
  12. package/dist/cli/components/AllModelsSelector.js.map +1 -0
  13. package/dist/cli/components/App.d.ts +8 -1
  14. package/dist/cli/components/App.d.ts.map +1 -1
  15. package/dist/cli/components/App.js +276 -40
  16. package/dist/cli/components/App.js.map +1 -1
  17. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -1
  18. package/dist/cli/components/CommandSuggestions.js +3 -0
  19. package/dist/cli/components/CommandSuggestions.js.map +1 -1
  20. package/dist/cli/components/Header.d.ts +1 -1
  21. package/dist/cli/components/Header.d.ts.map +1 -1
  22. package/dist/cli/components/Header.js +4 -6
  23. package/dist/cli/components/Header.js.map +1 -1
  24. package/dist/cli/components/Logo.d.ts +1 -0
  25. package/dist/cli/components/Logo.d.ts.map +1 -1
  26. package/dist/cli/components/Logo.js +16 -3
  27. package/dist/cli/components/Logo.js.map +1 -1
  28. package/dist/cli/components/Messages.d.ts +17 -3
  29. package/dist/cli/components/Messages.d.ts.map +1 -1
  30. package/dist/cli/components/Messages.js +70 -18
  31. package/dist/cli/components/Messages.js.map +1 -1
  32. package/dist/cli/components/ModelSelector.d.ts +7 -7
  33. package/dist/cli/components/ModelSelector.d.ts.map +1 -1
  34. package/dist/cli/components/ModelSelector.js +116 -33
  35. package/dist/cli/components/ModelSelector.js.map +1 -1
  36. package/dist/cli/components/PermissionPrompt.d.ts +60 -0
  37. package/dist/cli/components/PermissionPrompt.d.ts.map +1 -0
  38. package/dist/cli/components/PermissionPrompt.js +192 -0
  39. package/dist/cli/components/PermissionPrompt.js.map +1 -0
  40. package/dist/cli/components/ProviderManager.d.ts +8 -0
  41. package/dist/cli/components/ProviderManager.d.ts.map +1 -0
  42. package/dist/cli/components/ProviderManager.js +280 -0
  43. package/dist/cli/components/ProviderManager.js.map +1 -0
  44. package/dist/cli/components/Spinner.d.ts +7 -2
  45. package/dist/cli/components/Spinner.d.ts.map +1 -1
  46. package/dist/cli/components/Spinner.js +116 -25
  47. package/dist/cli/components/Spinner.js.map +1 -1
  48. package/dist/cli/components/TodoList.d.ts +7 -0
  49. package/dist/cli/components/TodoList.d.ts.map +1 -0
  50. package/dist/cli/components/TodoList.js +34 -0
  51. package/dist/cli/components/TodoList.js.map +1 -0
  52. package/dist/cli/components/index.d.ts +1 -0
  53. package/dist/cli/components/index.d.ts.map +1 -1
  54. package/dist/cli/components/index.js +1 -0
  55. package/dist/cli/components/index.js.map +1 -1
  56. package/dist/cli/components/markdown.d.ts +9 -0
  57. package/dist/cli/components/markdown.d.ts.map +1 -0
  58. package/dist/cli/components/markdown.js +129 -0
  59. package/dist/cli/components/markdown.js.map +1 -0
  60. package/dist/cli/components/theme.d.ts +5 -0
  61. package/dist/cli/components/theme.d.ts.map +1 -1
  62. package/dist/cli/components/theme.js +7 -0
  63. package/dist/cli/components/theme.js.map +1 -1
  64. package/dist/cli/index.js +66 -12
  65. package/dist/cli/index.js.map +1 -1
  66. package/dist/config/index.d.ts +14 -4
  67. package/dist/config/index.d.ts.map +1 -1
  68. package/dist/config/index.js +19 -3
  69. package/dist/config/index.js.map +1 -1
  70. package/dist/config/levels.d.ts +49 -0
  71. package/dist/config/levels.d.ts.map +1 -0
  72. package/dist/config/levels.js +222 -0
  73. package/dist/config/levels.js.map +1 -0
  74. package/dist/config/loader.d.ts +46 -0
  75. package/dist/config/loader.d.ts.map +1 -0
  76. package/dist/config/loader.js +153 -0
  77. package/dist/config/loader.js.map +1 -0
  78. package/dist/config/manager.d.ts +115 -15
  79. package/dist/config/manager.d.ts.map +1 -1
  80. package/dist/config/manager.js +260 -34
  81. package/dist/config/manager.js.map +1 -1
  82. package/dist/config/manager.test.d.ts +5 -0
  83. package/dist/config/manager.test.d.ts.map +1 -0
  84. package/dist/config/manager.test.js +192 -0
  85. package/dist/config/manager.test.js.map +1 -0
  86. package/dist/config/merger.d.ts +56 -0
  87. package/dist/config/merger.d.ts.map +1 -0
  88. package/dist/config/merger.js +177 -0
  89. package/dist/config/merger.js.map +1 -0
  90. package/dist/config/providers-config.d.ts +28 -0
  91. package/dist/config/providers-config.d.ts.map +1 -0
  92. package/dist/config/providers-config.js +79 -0
  93. package/dist/config/providers-config.js.map +1 -0
  94. package/dist/config/test-utils.d.ts +24 -0
  95. package/dist/config/test-utils.d.ts.map +1 -0
  96. package/dist/config/test-utils.js +55 -0
  97. package/dist/config/test-utils.js.map +1 -0
  98. package/dist/config/types.d.ts +108 -9
  99. package/dist/config/types.d.ts.map +1 -1
  100. package/dist/config/types.js +53 -2
  101. package/dist/config/types.js.map +1 -1
  102. package/dist/memory/import-resolver.d.ts +46 -0
  103. package/dist/memory/import-resolver.d.ts.map +1 -0
  104. package/dist/memory/import-resolver.js +117 -0
  105. package/dist/memory/import-resolver.js.map +1 -0
  106. package/dist/memory/index.d.ts +7 -6
  107. package/dist/memory/index.d.ts.map +1 -1
  108. package/dist/memory/index.js +7 -5
  109. package/dist/memory/index.js.map +1 -1
  110. package/dist/memory/init-prompt.d.ts +22 -0
  111. package/dist/memory/init-prompt.d.ts.map +1 -0
  112. package/dist/memory/init-prompt.js +103 -0
  113. package/dist/memory/init-prompt.js.map +1 -0
  114. package/dist/memory/memory-manager.d.ts +119 -0
  115. package/dist/memory/memory-manager.d.ts.map +1 -0
  116. package/dist/memory/memory-manager.js +587 -0
  117. package/dist/memory/memory-manager.js.map +1 -0
  118. package/dist/memory/rules-parser.d.ts +38 -0
  119. package/dist/memory/rules-parser.d.ts.map +1 -0
  120. package/dist/memory/rules-parser.js +69 -0
  121. package/dist/memory/rules-parser.js.map +1 -0
  122. package/dist/memory/test-utils.d.ts +20 -0
  123. package/dist/memory/test-utils.d.ts.map +1 -0
  124. package/dist/memory/test-utils.js +44 -0
  125. package/dist/memory/test-utils.js.map +1 -0
  126. package/dist/memory/types.d.ts +70 -63
  127. package/dist/memory/types.d.ts.map +1 -1
  128. package/dist/memory/types.js +42 -2
  129. package/dist/memory/types.js.map +1 -1
  130. package/dist/permissions/audit.d.ts +82 -0
  131. package/dist/permissions/audit.d.ts.map +1 -0
  132. package/dist/permissions/audit.js +229 -0
  133. package/dist/permissions/audit.js.map +1 -0
  134. package/dist/permissions/index.d.ts +11 -1
  135. package/dist/permissions/index.d.ts.map +1 -1
  136. package/dist/permissions/index.js +15 -0
  137. package/dist/permissions/index.js.map +1 -1
  138. package/dist/permissions/manager.d.ts +149 -13
  139. package/dist/permissions/manager.d.ts.map +1 -1
  140. package/dist/permissions/manager.js +480 -35
  141. package/dist/permissions/manager.js.map +1 -1
  142. package/dist/permissions/manager.test.d.ts +5 -0
  143. package/dist/permissions/manager.test.d.ts.map +1 -0
  144. package/dist/permissions/manager.test.js +213 -0
  145. package/dist/permissions/manager.test.js.map +1 -0
  146. package/dist/permissions/persistence.d.ts +74 -0
  147. package/dist/permissions/persistence.d.ts.map +1 -0
  148. package/dist/permissions/persistence.js +248 -0
  149. package/dist/permissions/persistence.js.map +1 -0
  150. package/dist/permissions/persistence.test.d.ts +5 -0
  151. package/dist/permissions/persistence.test.d.ts.map +1 -0
  152. package/dist/permissions/persistence.test.js +171 -0
  153. package/dist/permissions/persistence.test.js.map +1 -0
  154. package/dist/permissions/prompt-matcher.d.ts +64 -0
  155. package/dist/permissions/prompt-matcher.d.ts.map +1 -0
  156. package/dist/permissions/prompt-matcher.js +415 -0
  157. package/dist/permissions/prompt-matcher.js.map +1 -0
  158. package/dist/permissions/prompt-matcher.test.d.ts +5 -0
  159. package/dist/permissions/prompt-matcher.test.d.ts.map +1 -0
  160. package/dist/permissions/prompt-matcher.test.js +107 -0
  161. package/dist/permissions/prompt-matcher.test.js.map +1 -0
  162. package/dist/permissions/types.d.ts +157 -0
  163. package/dist/permissions/types.d.ts.map +1 -1
  164. package/dist/permissions/types.js +43 -8
  165. package/dist/permissions/types.js.map +1 -1
  166. package/dist/prompts/index.d.ts +92 -0
  167. package/dist/prompts/index.d.ts.map +1 -0
  168. package/dist/prompts/index.js +241 -0
  169. package/dist/prompts/index.js.map +1 -0
  170. package/dist/providers/gemini.d.ts.map +1 -1
  171. package/dist/providers/gemini.js +14 -3
  172. package/dist/providers/gemini.js.map +1 -1
  173. package/dist/providers/index.d.ts +5 -3
  174. package/dist/providers/index.d.ts.map +1 -1
  175. package/dist/providers/index.js +13 -1
  176. package/dist/providers/index.js.map +1 -1
  177. package/dist/providers/registry.d.ts +66 -0
  178. package/dist/providers/registry.d.ts.map +1 -0
  179. package/dist/providers/registry.js +158 -0
  180. package/dist/providers/registry.js.map +1 -0
  181. package/dist/providers/search/brave.d.ts +14 -0
  182. package/dist/providers/search/brave.d.ts.map +1 -0
  183. package/dist/providers/search/brave.js +87 -0
  184. package/dist/providers/search/brave.js.map +1 -0
  185. package/dist/providers/search/exa.d.ts +12 -0
  186. package/dist/providers/search/exa.d.ts.map +1 -0
  187. package/dist/providers/search/exa.js +158 -0
  188. package/dist/providers/search/exa.js.map +1 -0
  189. package/dist/providers/search/index.d.ts +31 -0
  190. package/dist/providers/search/index.d.ts.map +1 -0
  191. package/dist/providers/search/index.js +75 -0
  192. package/dist/providers/search/index.js.map +1 -0
  193. package/dist/providers/search/serper.d.ts +14 -0
  194. package/dist/providers/search/serper.d.ts.map +1 -0
  195. package/dist/providers/search/serper.js +87 -0
  196. package/dist/providers/search/serper.js.map +1 -0
  197. package/dist/providers/search/types.d.ts +21 -0
  198. package/dist/providers/search/types.d.ts.map +1 -0
  199. package/dist/providers/search/types.js +5 -0
  200. package/dist/providers/search/types.js.map +1 -0
  201. package/dist/providers/store.d.ts +104 -0
  202. package/dist/providers/store.d.ts.map +1 -0
  203. package/dist/providers/store.js +171 -0
  204. package/dist/providers/store.js.map +1 -0
  205. package/dist/providers/types.d.ts +7 -1
  206. package/dist/providers/types.d.ts.map +1 -1
  207. package/dist/providers/vertex-ai.d.ts +33 -0
  208. package/dist/providers/vertex-ai.d.ts.map +1 -0
  209. package/dist/providers/vertex-ai.js +407 -0
  210. package/dist/providers/vertex-ai.js.map +1 -0
  211. package/dist/tools/builtin/bash.d.ts.map +1 -1
  212. package/dist/tools/builtin/bash.js +2 -1
  213. package/dist/tools/builtin/bash.js.map +1 -1
  214. package/dist/tools/builtin/edit.d.ts.map +1 -1
  215. package/dist/tools/builtin/edit.js +2 -1
  216. package/dist/tools/builtin/edit.js.map +1 -1
  217. package/dist/tools/builtin/glob.d.ts.map +1 -1
  218. package/dist/tools/builtin/glob.js +2 -1
  219. package/dist/tools/builtin/glob.js.map +1 -1
  220. package/dist/tools/builtin/grep.d.ts.map +1 -1
  221. package/dist/tools/builtin/grep.js +2 -1
  222. package/dist/tools/builtin/grep.js.map +1 -1
  223. package/dist/tools/builtin/read.d.ts.map +1 -1
  224. package/dist/tools/builtin/read.js +2 -1
  225. package/dist/tools/builtin/read.js.map +1 -1
  226. package/dist/tools/builtin/todowrite.d.ts +15 -0
  227. package/dist/tools/builtin/todowrite.d.ts.map +1 -0
  228. package/dist/tools/builtin/todowrite.js +88 -0
  229. package/dist/tools/builtin/todowrite.js.map +1 -0
  230. package/dist/tools/builtin/webfetch.d.ts +20 -0
  231. package/dist/tools/builtin/webfetch.d.ts.map +1 -0
  232. package/dist/tools/builtin/webfetch.js +228 -0
  233. package/dist/tools/builtin/webfetch.js.map +1 -0
  234. package/dist/tools/builtin/websearch.d.ts +17 -0
  235. package/dist/tools/builtin/websearch.d.ts.map +1 -0
  236. package/dist/tools/builtin/websearch.js +87 -0
  237. package/dist/tools/builtin/websearch.js.map +1 -0
  238. package/dist/tools/builtin/write.d.ts.map +1 -1
  239. package/dist/tools/builtin/write.js +2 -1
  240. package/dist/tools/builtin/write.js.map +1 -1
  241. package/dist/tools/index.d.ts +18 -0
  242. package/dist/tools/index.d.ts.map +1 -1
  243. package/dist/tools/index.js +28 -2
  244. package/dist/tools/index.js.map +1 -1
  245. package/dist/tools/types.d.ts +41 -0
  246. package/dist/tools/types.d.ts.map +1 -1
  247. package/dist/tools/types.js +16 -0
  248. package/dist/tools/types.js.map +1 -1
  249. package/dist/tools/utils/ssrf.d.ts +18 -0
  250. package/dist/tools/utils/ssrf.d.ts.map +1 -0
  251. package/dist/tools/utils/ssrf.js +70 -0
  252. package/dist/tools/utils/ssrf.js.map +1 -0
  253. package/docs/README.md +5 -4
  254. package/docs/config-system-comparison.md +707 -0
  255. package/docs/memory-system.md +238 -0
  256. package/docs/permissions.md +368 -0
  257. package/docs/proposals/0001-web-fetch-tool.md +32 -2
  258. package/docs/proposals/0002-web-search-tool.md +59 -2
  259. package/docs/proposals/0005-todo-system.md +350 -85
  260. package/docs/proposals/0006-memory-system.md +11 -10
  261. package/docs/proposals/0012-ask-user-question.md +941 -206
  262. package/docs/proposals/0023-permission-enhancements.md +61 -2
  263. package/docs/proposals/0041-configuration-system.md +587 -0
  264. package/docs/proposals/0042-prompt-optimization.md +866 -0
  265. package/docs/proposals/README.md +8 -6
  266. package/docs/providers.md +220 -0
  267. package/jest.config.js +26 -0
  268. package/package.json +14 -3
  269. package/src/agent/agent.ts +120 -18
  270. package/src/agent/types.ts +9 -1
  271. package/src/cli/components/App.tsx +369 -47
  272. package/src/cli/components/CommandSuggestions.tsx +3 -0
  273. package/src/cli/components/Header.tsx +11 -17
  274. package/src/cli/components/Logo.tsx +76 -9
  275. package/src/cli/components/Messages.tsx +146 -38
  276. package/src/cli/components/ModelSelector.tsx +169 -52
  277. package/src/cli/components/PermissionPrompt.tsx +388 -0
  278. package/src/cli/components/ProviderManager.tsx +534 -0
  279. package/src/cli/components/Spinner.tsx +138 -25
  280. package/src/cli/components/TodoList.tsx +54 -0
  281. package/src/cli/components/index.ts +6 -0
  282. package/src/cli/components/markdown.ts +157 -0
  283. package/src/cli/components/theme.ts +7 -0
  284. package/src/cli/index.tsx +76 -13
  285. package/src/config/index.ts +79 -4
  286. package/src/config/levels.test.ts +163 -0
  287. package/src/config/levels.ts +285 -0
  288. package/src/config/loader.test.ts +120 -0
  289. package/src/config/loader.ts +178 -0
  290. package/src/config/manager.test.ts +215 -0
  291. package/src/config/manager.ts +328 -40
  292. package/src/config/merger.test.ts +360 -0
  293. package/src/config/merger.ts +221 -0
  294. package/src/config/providers-config.ts +85 -0
  295. package/src/config/test-utils.ts +79 -0
  296. package/src/config/types.ts +186 -9
  297. package/src/memory/import-resolver.test.ts +117 -0
  298. package/src/memory/import-resolver.ts +149 -0
  299. package/src/memory/index.ts +11 -0
  300. package/src/memory/init-prompt.ts +113 -0
  301. package/src/memory/memory-manager.test.ts +198 -0
  302. package/src/memory/memory-manager.ts +716 -0
  303. package/src/memory/rules-parser.test.ts +182 -0
  304. package/src/memory/rules-parser.ts +82 -0
  305. package/src/memory/test-utils.ts +60 -0
  306. package/src/memory/types.ts +119 -0
  307. package/src/permissions/audit.ts +284 -0
  308. package/src/permissions/index.ts +20 -1
  309. package/src/permissions/manager.test.ts +260 -0
  310. package/src/permissions/manager.ts +592 -40
  311. package/src/permissions/persistence.test.ts +220 -0
  312. package/src/permissions/persistence.ts +301 -0
  313. package/src/permissions/prompt-matcher.test.ts +213 -0
  314. package/src/permissions/prompt-matcher.ts +472 -0
  315. package/src/permissions/types.ts +236 -8
  316. package/src/prompts/index.test.ts +279 -0
  317. package/src/prompts/index.ts +306 -0
  318. package/src/prompts/system/anthropic.txt +29 -0
  319. package/src/prompts/system/base.txt +124 -0
  320. package/src/prompts/system/gemini.txt +35 -0
  321. package/src/prompts/system/generic.txt +128 -0
  322. package/src/prompts/system/openai.txt +29 -0
  323. package/src/prompts/tools/bash.txt +60 -0
  324. package/src/prompts/tools/edit.txt +29 -0
  325. package/src/prompts/tools/glob.txt +35 -0
  326. package/src/prompts/tools/grep.txt +43 -0
  327. package/src/prompts/tools/read.txt +22 -0
  328. package/src/prompts/tools/todowrite.txt +71 -0
  329. package/src/prompts/tools/webfetch.txt +34 -0
  330. package/src/prompts/tools/websearch.txt +41 -0
  331. package/src/prompts/tools/write.txt +23 -0
  332. package/src/providers/gemini.ts +20 -4
  333. package/src/providers/index.ts +18 -3
  334. package/src/providers/registry.ts +198 -0
  335. package/src/providers/search/brave.ts +132 -0
  336. package/src/providers/search/exa.ts +217 -0
  337. package/src/providers/search/index.ts +79 -0
  338. package/src/providers/search/serper.ts +133 -0
  339. package/src/providers/search/types.ts +24 -0
  340. package/src/providers/store.ts +216 -0
  341. package/src/providers/types.ts +9 -1
  342. package/src/providers/vertex-ai.ts +594 -0
  343. package/src/tools/builtin/bash.ts +2 -1
  344. package/src/tools/builtin/edit.ts +2 -1
  345. package/src/tools/builtin/glob.ts +2 -1
  346. package/src/tools/builtin/grep.ts +2 -1
  347. package/src/tools/builtin/read.ts +2 -1
  348. package/src/tools/builtin/todowrite.ts +102 -0
  349. package/src/tools/builtin/webfetch.ts +261 -0
  350. package/src/tools/builtin/websearch.ts +103 -0
  351. package/src/tools/builtin/write.ts +2 -1
  352. package/src/tools/index.ts +28 -2
  353. package/src/tools/types.ts +32 -0
  354. package/src/tools/utils/ssrf.ts +79 -0
  355. package/tsconfig.json +1 -1
  356. package/CLAUDE.md +0 -70
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Provider Registry - Provider definitions with connection options
3
+ */
4
+ /**
5
+ * All supported providers with their connection options
6
+ */
7
+ export const PROVIDERS = [
8
+ {
9
+ id: 'anthropic',
10
+ name: 'Anthropic',
11
+ popularity: 1,
12
+ connections: [
13
+ {
14
+ method: 'api_key',
15
+ name: 'API Key',
16
+ envVars: ['ANTHROPIC_API_KEY'],
17
+ description: 'Direct API access',
18
+ },
19
+ {
20
+ method: 'vertex',
21
+ name: 'Google Vertex AI',
22
+ envVars: ['ANTHROPIC_VERTEX_PROJECT_ID', 'GOOGLE_CLOUD_PROJECT'],
23
+ description: 'Claude via GCP',
24
+ providerImpl: 'vertex-ai',
25
+ },
26
+ {
27
+ method: 'bedrock',
28
+ name: 'Amazon Bedrock',
29
+ envVars: ['AWS_ACCESS_KEY_ID', 'AWS_PROFILE'],
30
+ description: 'Claude via AWS (coming soon)',
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ id: 'openai',
36
+ name: 'OpenAI',
37
+ popularity: 2,
38
+ connections: [
39
+ {
40
+ method: 'api_key',
41
+ name: 'API Key',
42
+ envVars: ['OPENAI_API_KEY'],
43
+ description: 'Direct API access',
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ id: 'gemini',
49
+ name: 'Google Gemini',
50
+ popularity: 3,
51
+ connections: [
52
+ {
53
+ method: 'api_key',
54
+ name: 'API Key',
55
+ envVars: ['GOOGLE_API_KEY', 'GEMINI_API_KEY'],
56
+ description: 'Direct API access',
57
+ },
58
+ ],
59
+ },
60
+ ];
61
+ /**
62
+ * All supported search providers
63
+ */
64
+ export const SEARCH_PROVIDERS = [
65
+ {
66
+ id: 'exa',
67
+ name: 'Exa AI',
68
+ popularity: 1,
69
+ connections: [
70
+ {
71
+ method: 'public',
72
+ name: 'Public API',
73
+ envVars: [],
74
+ description: 'No API key required',
75
+ },
76
+ ],
77
+ requiresKey: false,
78
+ },
79
+ {
80
+ id: 'serper',
81
+ name: 'Serper.dev',
82
+ popularity: 2,
83
+ connections: [
84
+ {
85
+ method: 'api_key',
86
+ name: 'API Key',
87
+ envVars: ['SERPER_API_KEY'],
88
+ description: 'Google Search via Serper',
89
+ },
90
+ ],
91
+ requiresKey: true,
92
+ },
93
+ {
94
+ id: 'brave',
95
+ name: 'Brave Search',
96
+ popularity: 3,
97
+ connections: [
98
+ {
99
+ method: 'api_key',
100
+ name: 'API Key',
101
+ envVars: ['BRAVE_API_KEY'],
102
+ description: 'Privacy-focused search',
103
+ },
104
+ ],
105
+ requiresKey: true,
106
+ },
107
+ ];
108
+ /**
109
+ * Get provider definition by ID
110
+ */
111
+ export function getProvider(id) {
112
+ return PROVIDERS.find((p) => p.id === id);
113
+ }
114
+ /**
115
+ * Get search provider definition by ID
116
+ */
117
+ export function getSearchProvider(id) {
118
+ return SEARCH_PROVIDERS.find((p) => p.id === id);
119
+ }
120
+ /**
121
+ * Get all search providers sorted by popularity
122
+ */
123
+ export function getSearchProvidersSorted() {
124
+ return [...SEARCH_PROVIDERS].sort((a, b) => a.popularity - b.popularity);
125
+ }
126
+ /**
127
+ * Get all providers sorted by popularity
128
+ */
129
+ export function getProvidersSorted() {
130
+ return [...PROVIDERS].sort((a, b) => a.popularity - b.popularity);
131
+ }
132
+ // Helper: check if any env var in the list is set
133
+ const hasAnyEnvVar = (envVars) => envVars.some((v) => !!process.env[v]);
134
+ /**
135
+ * Check if any of the provider's env vars are set
136
+ */
137
+ export function hasEnvVars(provider) {
138
+ return provider.connections.some((conn) => hasAnyEnvVar(conn.envVars));
139
+ }
140
+ /**
141
+ * Get the first available connection method (where env vars are set)
142
+ */
143
+ export function getAvailableConnection(provider) {
144
+ return provider.connections.find((conn) => hasAnyEnvVar(conn.envVars));
145
+ }
146
+ /**
147
+ * Check if a specific connection option has its env vars set
148
+ */
149
+ export function isConnectionReady(conn) {
150
+ return hasAnyEnvVar(conn.envVars);
151
+ }
152
+ /**
153
+ * Get all available (ready) connections for a provider
154
+ */
155
+ export function getAvailableConnections(provider) {
156
+ return provider.connections.filter((conn) => hasAnyEnvVar(conn.envVars));
157
+ }
158
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Brave Search Provider
3
+ *
4
+ * Uses Brave Search API (same as Claude Code).
5
+ * Requires BRAVE_API_KEY environment variable.
6
+ */
7
+ import type { SearchProvider, SearchResult, SearchOptions } from './types.js';
8
+ export declare class BraveProvider implements SearchProvider {
9
+ readonly name: "brave";
10
+ private apiKey;
11
+ constructor(apiKey?: string);
12
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
13
+ }
14
+ //# sourceMappingURL=brave.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brave.d.ts","sourceRoot":"","sources":["../../../src/providers/search/brave.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAyD9E,qBAAa,aAAc,YAAW,cAAc;IAClD,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAOrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAwD9E"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Brave Search Provider
3
+ *
4
+ * Uses Brave Search API (same as Claude Code).
5
+ * Requires BRAVE_API_KEY environment variable.
6
+ */
7
+ const API_CONFIG = {
8
+ BASE_URL: 'https://api.search.brave.com',
9
+ ENDPOINT: '/res/v1/web/search',
10
+ DEFAULT_NUM_RESULTS: 10,
11
+ DEFAULT_TIMEOUT: 10000,
12
+ };
13
+ /**
14
+ * Filter results by allowed/blocked domains
15
+ */
16
+ function filterByDomain(results, options) {
17
+ if (!options?.allowedDomains?.length && !options?.blockedDomains?.length) {
18
+ return results;
19
+ }
20
+ return results.filter((result) => {
21
+ try {
22
+ const domain = new URL(result.url).hostname;
23
+ if (options.allowedDomains?.length) {
24
+ return options.allowedDomains.some((allowed) => domain === allowed || domain.endsWith('.' + allowed));
25
+ }
26
+ if (options.blockedDomains?.length) {
27
+ return !options.blockedDomains.some((blocked) => domain === blocked || domain.endsWith('.' + blocked));
28
+ }
29
+ return true;
30
+ }
31
+ catch {
32
+ return true;
33
+ }
34
+ });
35
+ }
36
+ export class BraveProvider {
37
+ name = 'brave';
38
+ apiKey;
39
+ constructor(apiKey) {
40
+ this.apiKey = apiKey ?? process.env.BRAVE_API_KEY ?? '';
41
+ if (!this.apiKey) {
42
+ throw new Error('BRAVE_API_KEY environment variable is required for Brave provider');
43
+ }
44
+ }
45
+ async search(query, options) {
46
+ const params = new URLSearchParams({
47
+ q: query,
48
+ count: String(options?.numResults ?? API_CONFIG.DEFAULT_NUM_RESULTS),
49
+ });
50
+ const controller = new AbortController();
51
+ const timeoutId = setTimeout(() => controller.abort(), options?.timeout ?? API_CONFIG.DEFAULT_TIMEOUT);
52
+ try {
53
+ const signals = options?.abortSignal
54
+ ? [controller.signal, options.abortSignal]
55
+ : [controller.signal];
56
+ const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}?${params.toString()}`, {
57
+ method: 'GET',
58
+ headers: {
59
+ Accept: 'application/json',
60
+ 'Accept-Encoding': 'gzip',
61
+ 'X-Subscription-Token': this.apiKey,
62
+ },
63
+ signal: AbortSignal.any(signals),
64
+ });
65
+ clearTimeout(timeoutId);
66
+ if (!response.ok) {
67
+ const errorText = await response.text();
68
+ throw new Error(`Brave search error (${response.status}): ${errorText}`);
69
+ }
70
+ const data = (await response.json());
71
+ const results = (data.web?.results || []).map((item) => ({
72
+ title: item.title,
73
+ url: item.url,
74
+ snippet: item.description,
75
+ }));
76
+ return filterByDomain(results, options);
77
+ }
78
+ catch (error) {
79
+ clearTimeout(timeoutId);
80
+ if (error instanceof Error && error.name === 'AbortError') {
81
+ throw new Error('Search request timed out');
82
+ }
83
+ throw error;
84
+ }
85
+ }
86
+ }
87
+ //# sourceMappingURL=brave.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brave.js","sourceRoot":"","sources":["../../../src/providers/search/brave.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Exa AI Search Provider
3
+ *
4
+ * Uses Exa's public MCP endpoint (no API key required).
5
+ * Based on OpenCode's implementation pattern.
6
+ */
7
+ import type { SearchProvider, SearchResult, SearchOptions } from './types.js';
8
+ export declare class ExaProvider implements SearchProvider {
9
+ readonly name: "exa";
10
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
11
+ }
12
+ //# sourceMappingURL=exa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exa.d.ts","sourceRoot":"","sources":["../../../src/providers/search/exa.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuI9E,qBAAa,WAAY,YAAW,cAAc;IAChD,QAAQ,CAAC,IAAI,EAAG,KAAK,CAAU;IAEzB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAuE9E"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Exa AI Search Provider
3
+ *
4
+ * Uses Exa's public MCP endpoint (no API key required).
5
+ * Based on OpenCode's implementation pattern.
6
+ */
7
+ const API_CONFIG = {
8
+ BASE_URL: 'https://mcp.exa.ai',
9
+ ENDPOINT: '/mcp',
10
+ DEFAULT_NUM_RESULTS: 8,
11
+ DEFAULT_TIMEOUT: 25000,
12
+ };
13
+ /**
14
+ * Parse Exa's response text into structured search results
15
+ *
16
+ * Exa returns results in this format:
17
+ * Title: ...
18
+ * URL: ...
19
+ * Text: ...
20
+ */
21
+ function parseExaResults(text) {
22
+ const results = [];
23
+ const lines = text.split('\n');
24
+ let currentResult = {};
25
+ let collectingText = false;
26
+ let textBuffer = [];
27
+ for (const line of lines) {
28
+ const trimmed = line.trim();
29
+ // Check for "Title: ..." line
30
+ if (trimmed.startsWith('Title:')) {
31
+ // Save previous result if exists
32
+ if (currentResult.title && currentResult.url) {
33
+ results.push({
34
+ title: currentResult.title,
35
+ url: currentResult.url,
36
+ snippet: textBuffer.join(' ').trim().substring(0, 300),
37
+ });
38
+ }
39
+ currentResult = { title: trimmed.substring(6).trim() };
40
+ collectingText = false;
41
+ textBuffer = [];
42
+ continue;
43
+ }
44
+ // Check for "URL: ..." line
45
+ if (trimmed.startsWith('URL:')) {
46
+ currentResult.url = trimmed.substring(4).trim();
47
+ continue;
48
+ }
49
+ // Check for "Text: ..." line - start of snippet
50
+ if (trimmed.startsWith('Text:')) {
51
+ collectingText = true;
52
+ const initialText = trimmed.substring(5).trim();
53
+ if (initialText) {
54
+ textBuffer.push(initialText);
55
+ }
56
+ continue;
57
+ }
58
+ // Collect text lines until next Title
59
+ if (collectingText && trimmed && !trimmed.startsWith('Title:')) {
60
+ textBuffer.push(trimmed);
61
+ }
62
+ }
63
+ // Add the last result
64
+ if (currentResult.title && currentResult.url) {
65
+ results.push({
66
+ title: currentResult.title,
67
+ url: currentResult.url,
68
+ snippet: textBuffer.join(' ').trim().substring(0, 300),
69
+ });
70
+ }
71
+ return results;
72
+ }
73
+ /**
74
+ * Filter results by allowed/blocked domains
75
+ */
76
+ function filterByDomain(results, options) {
77
+ if (!options?.allowedDomains?.length && !options?.blockedDomains?.length) {
78
+ return results;
79
+ }
80
+ return results.filter((result) => {
81
+ try {
82
+ const domain = new URL(result.url).hostname;
83
+ if (options.allowedDomains?.length) {
84
+ return options.allowedDomains.some((allowed) => domain === allowed || domain.endsWith('.' + allowed));
85
+ }
86
+ if (options.blockedDomains?.length) {
87
+ return !options.blockedDomains.some((blocked) => domain === blocked || domain.endsWith('.' + blocked));
88
+ }
89
+ return true;
90
+ }
91
+ catch {
92
+ return true;
93
+ }
94
+ });
95
+ }
96
+ export class ExaProvider {
97
+ name = 'exa';
98
+ async search(query, options) {
99
+ const searchRequest = {
100
+ jsonrpc: '2.0',
101
+ id: 1,
102
+ method: 'tools/call',
103
+ params: {
104
+ name: 'web_search_exa',
105
+ arguments: {
106
+ query,
107
+ type: 'auto',
108
+ numResults: options?.numResults ?? API_CONFIG.DEFAULT_NUM_RESULTS,
109
+ livecrawl: 'fallback',
110
+ contextMaxCharacters: 10000,
111
+ },
112
+ },
113
+ };
114
+ const controller = new AbortController();
115
+ const timeoutId = setTimeout(() => controller.abort(), options?.timeout ?? API_CONFIG.DEFAULT_TIMEOUT);
116
+ try {
117
+ const signals = options?.abortSignal
118
+ ? [controller.signal, options.abortSignal]
119
+ : [controller.signal];
120
+ const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINT}`, {
121
+ method: 'POST',
122
+ headers: {
123
+ Accept: 'application/json, text/event-stream',
124
+ 'Content-Type': 'application/json',
125
+ },
126
+ body: JSON.stringify(searchRequest),
127
+ signal: AbortSignal.any(signals),
128
+ });
129
+ clearTimeout(timeoutId);
130
+ if (!response.ok) {
131
+ const errorText = await response.text();
132
+ throw new Error(`Exa search error (${response.status}): ${errorText}`);
133
+ }
134
+ const responseText = await response.text();
135
+ // Parse SSE response
136
+ const lines = responseText.split('\n');
137
+ for (const line of lines) {
138
+ if (line.startsWith('data: ')) {
139
+ const data = JSON.parse(line.substring(6));
140
+ if (data.result?.content?.length > 0) {
141
+ const text = data.result.content[0].text;
142
+ const results = parseExaResults(text);
143
+ return filterByDomain(results, options);
144
+ }
145
+ }
146
+ }
147
+ return [];
148
+ }
149
+ catch (error) {
150
+ clearTimeout(timeoutId);
151
+ if (error instanceof Error && error.name === 'AbortError') {
152
+ throw new Error('Search request timed out');
153
+ }
154
+ throw error;
155
+ }
156
+ }
157
+ }
158
+ //# sourceMappingURL=exa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exa.js","sourceRoot":"","sources":["../../../src/providers/search/exa.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Search Providers - Factory and exports
3
+ */
4
+ export * from './types.js';
5
+ export { ExaProvider } from './exa.js';
6
+ export { SerperProvider } from './serper.js';
7
+ export { BraveProvider } from './brave.js';
8
+ import type { SearchProvider, SearchProviderName } from './types.js';
9
+ /**
10
+ * Create a search provider instance
11
+ *
12
+ * Priority:
13
+ * 1. Explicit name parameter
14
+ * 2. Configured in provider store
15
+ * 3. Detected from environment variables
16
+ * 4. Default: Exa (no key required)
17
+ */
18
+ export declare function createSearchProvider(name?: SearchProviderName): SearchProvider;
19
+ /**
20
+ * Get the name of the current search provider
21
+ */
22
+ export declare function getCurrentSearchProviderName(): SearchProviderName;
23
+ /**
24
+ * Check if a search provider is available (has required API keys)
25
+ */
26
+ export declare function isSearchProviderAvailable(name: SearchProviderName): boolean;
27
+ /**
28
+ * Get all available search providers
29
+ */
30
+ export declare function getAvailableSearchProviders(): SearchProviderName[];
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/search/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAerE;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,kBAAkB,GAAG,cAAc,CAY9E;AAED;;GAEG;AACH,wBAAgB,4BAA4B,IAAI,kBAAkB,CAEjE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAW3E;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,kBAAkB,EAAE,CAKlE"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Search Providers - Factory and exports
3
+ */
4
+ export * from './types.js';
5
+ export { ExaProvider } from './exa.js';
6
+ export { SerperProvider } from './serper.js';
7
+ export { BraveProvider } from './brave.js';
8
+ import { ExaProvider } from './exa.js';
9
+ import { SerperProvider } from './serper.js';
10
+ import { BraveProvider } from './brave.js';
11
+ import { getProviderStore } from '../store.js';
12
+ /**
13
+ * Detect search provider from environment variables
14
+ */
15
+ function detectFromEnv() {
16
+ if (process.env.SERPER_API_KEY)
17
+ return 'serper';
18
+ if (process.env.BRAVE_API_KEY)
19
+ return 'brave';
20
+ return undefined;
21
+ }
22
+ /**
23
+ * Create a search provider instance
24
+ *
25
+ * Priority:
26
+ * 1. Explicit name parameter
27
+ * 2. Configured in provider store
28
+ * 3. Detected from environment variables
29
+ * 4. Default: Exa (no key required)
30
+ */
31
+ export function createSearchProvider(name) {
32
+ const providerName = name ?? getProviderStore().getSearchProvider() ?? detectFromEnv() ?? 'exa';
33
+ switch (providerName) {
34
+ case 'serper':
35
+ return new SerperProvider();
36
+ case 'brave':
37
+ return new BraveProvider();
38
+ case 'exa':
39
+ default:
40
+ return new ExaProvider();
41
+ }
42
+ }
43
+ /**
44
+ * Get the name of the current search provider
45
+ */
46
+ export function getCurrentSearchProviderName() {
47
+ return getProviderStore().getSearchProvider() ?? detectFromEnv() ?? 'exa';
48
+ }
49
+ /**
50
+ * Check if a search provider is available (has required API keys)
51
+ */
52
+ export function isSearchProviderAvailable(name) {
53
+ switch (name) {
54
+ case 'exa':
55
+ return true; // Always available
56
+ case 'serper':
57
+ return !!process.env.SERPER_API_KEY;
58
+ case 'brave':
59
+ return !!process.env.BRAVE_API_KEY;
60
+ default:
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Get all available search providers
66
+ */
67
+ export function getAvailableSearchProviders() {
68
+ const providers = ['exa']; // Always available
69
+ if (process.env.SERPER_API_KEY)
70
+ providers.push('serper');
71
+ if (process.env.BRAVE_API_KEY)
72
+ providers.push('brave');
73
+ return providers;
74
+ }
75
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/search/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,QAAQ,CAAC;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,OAAO,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAyB;IAC5D,MAAM,YAAY,GAAG,IAAI,IAAI,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,IAAI,aAAa,EAAE,IAAI,KAAK,CAAC;IAEhG,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,QAAQ;YACX,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,KAAK,OAAO;YACV,OAAO,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,KAAK,CAAC;QACX;YACE,OAAO,IAAI,WAAW,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,IAAI,aAAa,EAAE,IAAI,KAAK,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAAwB;IAChE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK;YACR,OAAO,IAAI,CAAC,CAAC,mBAAmB;QAClC,KAAK,QAAQ;YACX,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;QACrC;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,SAAS,GAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB;IACpE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Serper.dev Search Provider
3
+ *
4
+ * Uses Google Search via Serper.dev API.
5
+ * Requires SERPER_API_KEY environment variable.
6
+ */
7
+ import type { SearchProvider, SearchResult, SearchOptions } from './types.js';
8
+ export declare class SerperProvider implements SearchProvider {
9
+ readonly name: "serper";
10
+ private apiKey;
11
+ constructor(apiKey?: string);
12
+ search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
13
+ }
14
+ //# sourceMappingURL=serper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serper.d.ts","sourceRoot":"","sources":["../../../src/providers/search/serper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA6D9E,qBAAa,cAAe,YAAW,cAAc;IACnD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM;IAOrB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAqD9E"}