kiku-agent 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.md +69 -12
  2. package/package.json +5 -12
  3. package/server/agent/agentCore.js +319 -46
  4. package/server/agent/appPaths.js +31 -0
  5. package/server/agent/audioPlayer.js +339 -12
  6. package/server/agent/autoContext.js +193 -0
  7. package/server/agent/catalogEntityResolver.js +170 -28
  8. package/server/agent/clarifyingQuestions.js +137 -35
  9. package/server/agent/cli.js +177 -48
  10. package/server/agent/cloudAdapters.js +116 -0
  11. package/server/agent/commandRegistry.js +409 -80
  12. package/server/agent/commands.js +1056 -125
  13. package/server/agent/config.js +1088 -690
  14. package/server/agent/contextCompactor.js +213 -21
  15. package/server/agent/cpuMetrics.js +199 -0
  16. package/server/agent/engineService.js +591 -0
  17. package/server/agent/eval/AGENTS.md +228 -0
  18. package/server/agent/eval/analyze.py +684 -0
  19. package/server/agent/eval/gates.json +15 -0
  20. package/server/agent/eval/modules/analysis/compare.js +198 -0
  21. package/server/agent/eval/modules/analysis/gates.js +72 -0
  22. package/server/agent/eval/modules/analysis/judge.js +70 -0
  23. package/server/agent/eval/modules/core/cli.js +453 -0
  24. package/server/agent/eval/modules/core/config.js +60 -0
  25. package/server/agent/eval/modules/core/store.js +236 -0
  26. package/server/agent/eval/modules/evaluation/cases.js +689 -0
  27. package/server/agent/eval/modules/evaluation/runner.js +288 -0
  28. package/server/agent/eval/modules/evaluation/scoring.js +363 -0
  29. package/server/agent/eval/modules/evaluation/worker.js +122 -0
  30. package/server/agent/eval/modules/reporting/benchmark.js +265 -0
  31. package/server/agent/eval/modules/reporting/benchmarkPng.js +487 -0
  32. package/server/agent/eval/modules/reporting/dashboard.js +1406 -0
  33. package/server/agent/eval/modules/server/evalApi.js +1099 -0
  34. package/server/agent/eval/modules/ui/evalUi.js +4799 -0
  35. package/server/agent/eval/modules/utils/smokes.js +119 -0
  36. package/server/agent/eventBus.js +1 -0
  37. package/server/agent/ink/main.jsx +196 -191
  38. package/server/agent/jobManager.js +11 -1
  39. package/server/agent/lanDiscovery.js +721 -23
  40. package/server/agent/llmClient.js +317 -71
  41. package/server/agent/lmStudioWakeup.js +517 -65
  42. package/server/agent/locationService.js +797 -0
  43. package/server/agent/mcpQuizData.js +509 -0
  44. package/server/agent/memory/contextAllocator.js +19 -7
  45. package/server/agent/memory.js +3 -1
  46. package/server/agent/modelCompatibility.js +352 -0
  47. package/server/agent/modelDefaults.js +1 -0
  48. package/server/agent/modelManager.js +46 -2
  49. package/server/agent/newsWatch.js +9 -3
  50. package/server/agent/processManager.js +229 -0
  51. package/server/agent/prompts.js +174 -8
  52. package/server/agent/routingInterceptor.js +9 -1
  53. package/server/agent/sanitizer.js +41 -6
  54. package/server/agent/searchQueryPlanner.js +202 -0
  55. package/server/agent/session.js +59 -4
  56. package/server/agent/tests/agentBubbleSystem.test.js +65 -0
  57. package/server/agent/tests/agentFollowUps.test.js +253 -0
  58. package/server/agent/tests/agentMusicControl.test.js +245 -0
  59. package/server/agent/tests/apiRouter.test.js +108 -0
  60. package/server/agent/tests/architectureFixes.test.js +81 -0
  61. package/server/agent/tests/architectureRefactoring.test.js +194 -0
  62. package/server/agent/tests/autoContext.test.js +176 -0
  63. package/server/agent/tests/autoResearch.test.js +64 -0
  64. package/server/agent/tests/bilibiliEmbed.test.js +296 -0
  65. package/server/agent/tests/catalogSync.test.js +130 -0
  66. package/server/agent/tests/chatHardening.test.js +121 -0
  67. package/server/agent/tests/chineseWebSearchEscalation.test.js +62 -0
  68. package/server/agent/tests/citations.test.js +180 -0
  69. package/server/agent/tests/clarificationAnalytics.test.js +219 -0
  70. package/server/agent/tests/clarifyingQuestions.test.js +627 -0
  71. package/server/agent/tests/cliAutomation.test.js +158 -0
  72. package/server/agent/tests/cloudProviders.test.js +322 -0
  73. package/server/agent/tests/commandInput.test.js +24 -0
  74. package/server/agent/tests/commands.test.js +506 -0
  75. package/server/agent/tests/contextIntelligence.test.js +209 -0
  76. package/server/agent/tests/conversationSafety.test.js +53 -0
  77. package/server/agent/tests/cpuMetrics.test.js +101 -0
  78. package/server/agent/tests/decisionAndSearchEnhancements.test.js +167 -0
  79. package/server/agent/tests/dramaAnswerQuality.test.js +73 -0
  80. package/server/agent/tests/dynamicCatalogIngestion.test.js +285 -0
  81. package/server/agent/tests/dynamicRoutingAndSearch.test.js +92 -0
  82. package/server/agent/tests/edgeCasesScenarios.test.js +131 -0
  83. package/server/agent/tests/engineService.test.js +436 -0
  84. package/server/agent/tests/engineUnload.test.js +94 -0
  85. package/server/agent/tests/entertainmentMetrics.test.js +126 -0
  86. package/server/agent/tests/envBootstrap.test.js +87 -0
  87. package/server/agent/tests/envCommand.test.js +284 -0
  88. package/server/agent/tests/errorHandling.test.js +80 -0
  89. package/server/agent/tests/errors.test.js +13 -0
  90. package/server/agent/tests/evalAnalyze.test.js +54 -0
  91. package/server/agent/tests/evalCommand.test.js +54 -0
  92. package/server/agent/tests/evalCorpus.test.js +126 -0
  93. package/server/agent/tests/evalHarness.test.js +62 -0
  94. package/server/agent/tests/evalJudgeContext.test.js +38 -0
  95. package/server/agent/tests/evalMetrics.test.js +320 -0
  96. package/server/agent/tests/evalStore.test.js +190 -0
  97. package/server/agent/tests/evalStudio.test.js +179 -0
  98. package/server/agent/tests/feedbackLearning.test.js +186 -0
  99. package/server/agent/tests/fetchApi.test.js +99 -0
  100. package/server/agent/tests/firstRun.test.js +44 -0
  101. package/server/agent/tests/gemma4eOptimization.test.js +95 -0
  102. package/server/agent/tests/hardwareTiers.test.js +206 -0
  103. package/server/agent/tests/hybridWebSearch.test.js +194 -0
  104. package/server/agent/tests/judgeService.test.js +251 -0
  105. package/server/agent/tests/lanDiscovery.test.js +324 -0
  106. package/server/agent/tests/lanInterfaces.test.js +510 -0
  107. package/server/agent/tests/lmStudioWakeup.test.js +278 -0
  108. package/server/agent/tests/locationTool.test.js +278 -0
  109. package/server/agent/tests/mcpClient.test.js +201 -0
  110. package/server/agent/tests/memoryRoute.test.js +173 -0
  111. package/server/agent/tests/memoryUiNormalization.test.js +75 -0
  112. package/server/agent/tests/modelCompatibility.test.js +148 -0
  113. package/server/agent/tests/modelManager.test.js +141 -0
  114. package/server/agent/tests/multilingualScenarios.test.js +69 -0
  115. package/server/agent/tests/musicControlUiBridge.test.js +113 -0
  116. package/server/agent/tests/newCommands.test.js +347 -0
  117. package/server/agent/tests/newCommandsTui.test.js +141 -0
  118. package/server/agent/tests/newTools.test.js +113 -0
  119. package/server/agent/tests/newsIntelligence.test.js +178 -0
  120. package/server/agent/tests/nextGenArchitecture.test.js +101 -0
  121. package/server/agent/tests/offlineInput.test.js +217 -0
  122. package/server/agent/tests/openDomainPrompt.test.js +197 -0
  123. package/server/agent/tests/openDomainSearch.test.js +121 -0
  124. package/server/agent/tests/packagingGuard.test.js +57 -0
  125. package/server/agent/tests/presentation.test.js +61 -0
  126. package/server/agent/tests/processManager.test.js +144 -0
  127. package/server/agent/tests/providerPersistence.test.js +44 -0
  128. package/server/agent/tests/queryBenchmarks.test.js +83 -0
  129. package/server/agent/tests/queryDetails.test.js +126 -0
  130. package/server/agent/tests/quickActionsAndModals.test.js +180 -0
  131. package/server/agent/tests/realWorldValidation.test.js +391 -0
  132. package/server/agent/tests/resilienceAndConcurrency.test.js +117 -0
  133. package/server/agent/tests/runtimeWatchdog.test.js +32 -0
  134. package/server/agent/tests/sanitizer.test.js +37 -0
  135. package/server/agent/tests/scenariosData.js +378 -0
  136. package/server/agent/tests/schemaRouting.test.js +54 -0
  137. package/server/agent/tests/searchQueryPlanner.test.js +108 -0
  138. package/server/agent/tests/securityAuditRemediation.test.js +221 -0
  139. package/server/agent/tests/securityAuditRemediations2.test.js +154 -0
  140. package/server/agent/tests/securityHardening.test.js +146 -0
  141. package/server/agent/tests/securitySanitizer.test.js +38 -0
  142. package/server/agent/tests/sessionAndCopy.test.js +267 -0
  143. package/server/agent/tests/sidebarControls.test.js +135 -0
  144. package/server/agent/tests/statefulMemory.test.js +277 -0
  145. package/server/agent/tests/subagent.test.js +216 -0
  146. package/server/agent/tests/subagentProgress.test.js +109 -0
  147. package/server/agent/tests/subagentTextFallback.test.js +115 -0
  148. package/server/agent/tests/suggestions.test.js +199 -0
  149. package/server/agent/tests/suggestionsTui.test.js +251 -0
  150. package/server/agent/tests/telemetryAndProfiles.test.js +179 -0
  151. package/server/agent/tests/terminalImage.test.js +80 -0
  152. package/server/agent/tests/terminalMarkdown.test.js +166 -0
  153. package/server/agent/tests/terminalText.test.js +133 -0
  154. package/server/agent/tests/textProtocolLoop.test.js +197 -0
  155. package/server/agent/tests/textToolParsing.test.js +187 -0
  156. package/server/agent/tests/theme.test.js +26 -0
  157. package/server/agent/tests/toolRegistryParity.test.js +53 -0
  158. package/server/agent/tests/toolRoutingRegressions.test.js +160 -0
  159. package/server/agent/tests/tools.test.js +259 -0
  160. package/server/agent/tests/unifiedEndpoints.test.js +159 -0
  161. package/server/agent/tests/v110Features.test.js +262 -0
  162. package/server/agent/tests/versionBump.test.js +69 -0
  163. package/server/agent/tests/vramEstimator.test.js +595 -0
  164. package/server/agent/tests/webChatDocs.test.js +199 -0
  165. package/server/agent/tests/webChatInferenceControl.test.js +298 -0
  166. package/server/agent/tests/webChatInspection.test.js +551 -0
  167. package/server/agent/tests/webChatMcp.test.js +94 -0
  168. package/server/agent/tests/webChatMemory.test.js +112 -0
  169. package/server/agent/tests/webChatSecurity.test.js +169 -0
  170. package/server/agent/tests/webExtract.test.js +284 -0
  171. package/server/agent/tests/webSources.test.js +281 -0
  172. package/server/agent/textToolProtocol.js +173 -46
  173. package/server/agent/toolRouter.js +318 -44
  174. package/server/agent/tools.js +877 -96
  175. package/server/agent/ui.js +39 -34
  176. package/server/agent/vramService.js +35 -54
  177. package/server/agent/webSearch.js +441 -162
  178. package/server/agent/websearch/orchestrator.js +15 -5
  179. package/server/agent/websearch/resilience/cache.js +9 -2
  180. package/server/agent/websearch/security/ssrf.js +41 -10
  181. package/server/agent/youtubeAuth.js +5 -20
  182. package/server/apiRouter.js +5558 -4422
  183. package/server/eval/judgeRubrics.js +110 -0
  184. package/server/eval/judgeService.js +290 -0
  185. package/server/eval/runBenchmark.js +182 -0
  186. package/server/mcp/data/discography.js +2 -2
  187. package/server/mcp/examples/antigravity.example.json +17 -0
  188. package/server/mcp/examples/librechat.example.yaml +16 -0
  189. package/server/mcp/handler.js +8 -4
  190. package/server/mcp/security.js +220 -21
  191. package/server/mcp/server.js +2 -1
  192. package/server/mcp/tests/connection.test.js +162 -0
  193. package/server/mcp/tests/mcpKeyAuth.test.js +156 -0
  194. package/server/mcp/tools.js +7 -1
  195. package/server/supabase_migration_prefix.sql +102 -0
  196. package/server/supabase_schema.sql +63 -0
  197. package/server/web-chat/core/connection.js +179 -218
  198. package/server/web-chat/core/conversationContext.js +9 -2
  199. package/server/web-chat/core/directCatalogEngine.js +52 -28
  200. package/server/web-chat/core/dramaKnowledge.js +33 -22
  201. package/server/web-chat/core/followUpEngine.js +735 -81
  202. package/server/web-chat/core/futureEventGuard.js +5 -1
  203. package/server/web-chat/core/musicControlAction.js +70 -0
  204. package/server/web-chat/core/security.js +32 -21
  205. package/server/web-chat/core/toolInspector.js +6 -6
  206. package/server/web-chat/core/urlGuard.js +45 -0
  207. package/server/web-chat/router.js +204 -157
  208. package/server/web-chat/routes/chatRoute.js +885 -488
  209. package/server/web-chat/routes/engineRoute.js +270 -0
  210. package/server/web-chat/routes/exportRoute.js +1 -1
  211. package/server/web-chat/routes/lanDiscoveryRoute.js +17 -2
  212. package/server/web-chat/routes/lmStudioLoadRoute.js +172 -0
  213. package/server/web-chat/routes/mcpRoute.js +386 -0
  214. package/server/web-chat/routes/memoryRoute.js +253 -0
  215. package/server/web-chat/routes/providerRoute.js +49 -16
  216. package/server/web-chat/routes/staticRoute.js +306 -17
  217. package/server/web-chat/routes/statusRoute.js +194 -73
  218. package/server/web-chat/routes/suggestRoute.js +11 -3
  219. package/server/web-chat/routes/verifyRoute.js +26 -4
  220. package/server/web-chat/server.js +7 -6
  221. package/server/web-chat/ui/docsBuilder.js +3558 -0
  222. package/server/web-chat/ui/htmlBuilder.js +12 -0
  223. package/server/web-chat/ui/scripts/client.js +3401 -1302
  224. package/server/web-chat/ui/scripts/webchatI18n.js +155 -153
  225. package/server/web-chat/ui/settingsBuilder.js +7870 -0
  226. package/server/web-chat/ui/styles/lan-card.css +165 -0
  227. package/server/web-chat/ui/styles/main.css +4289 -447
  228. package/server/web-chat/ui/sw.js +64 -0
  229. package/server/web-chat/ui/templates/body.html +407 -281
  230. package/src/data/awardsData.js +146 -146
  231. package/src/data/musicVideoData.js +6 -4
  232. package/src/lib/vram/estimator.js +195 -19
@@ -109,7 +109,7 @@ export class MetaSearchOrchestrator {
109
109
  const isNews = options.isNews === true;
110
110
 
111
111
 
112
- const cacheKey = computeSearchCacheKey('meta', query, limit);
112
+ const cacheKey = computeSearchCacheKey('meta', query, limit, options);
113
113
  const cached = this.cache.get(cacheKey);
114
114
  if (cached && !options.noCache) {
115
115
  return { ...cached, fromCache: true };
@@ -144,8 +144,18 @@ export class MetaSearchOrchestrator {
144
144
  fallbackTriggered = engineChain.length > 1 && firstEngineResults.length < Math.ceil(limit / 2);
145
145
  successfulEngine = engineChain.find((engine, index) => engineLists[index].length > 0) || null;
146
146
 
147
+ const uniqueHosts = new Set();
148
+ for (const list of collectedLists) {
149
+ for (const item of list) {
150
+ try {
151
+ const host = new URL(item.link || item.url).hostname;
152
+ if (host) uniqueHosts.add(host);
153
+ } catch {}
154
+ }
155
+ }
147
156
  let fusedInputCount = collectedLists.reduce((sum, list) => sum + list.length, 0);
148
- if (fusedInputCount < 3 && options.fanOut !== false) {
157
+ const isThin = fusedInputCount < Math.max(5, limit) || uniqueHosts.size < 3;
158
+ if (isThin && options.fanOut !== false) {
149
159
  const expansions = this.expandQuery(query).slice(1);
150
160
  const fanSettled = await Promise.allSettled(
151
161
  expansions.map(expQuery => this._searchSingleEngine('duckduckgo', expQuery, options))
@@ -159,10 +169,8 @@ export class MetaSearchOrchestrator {
159
169
  }
160
170
  }
161
171
 
162
-
163
172
  const fused = fuseSearchResults(collectedLists, { limit, k: options.k || 60 });
164
173
 
165
-
166
174
  const filtered = fused.filter(item => {
167
175
  try {
168
176
  const host = new URL(item.link).hostname;
@@ -191,7 +199,9 @@ export class MetaSearchOrchestrator {
191
199
  results: filtered
192
200
  };
193
201
 
194
- this.cache.set(cacheKey, response, zeroResult ? 30_000 : (isNews ? TTL_NEWS_MS : TTL_GENERAL_MS));
202
+ if (!zeroResult) {
203
+ this.cache.set(cacheKey, response, isNews ? TTL_NEWS_MS : TTL_GENERAL_MS);
204
+ }
195
205
 
196
206
  return response;
197
207
  }
@@ -3,8 +3,15 @@ import crypto from 'node:crypto';
3
3
  export const TTL_GENERAL_MS = 10 * 60 * 1000;
4
4
  export const TTL_NEWS_MS = 2 * 60 * 1000;
5
5
 
6
- export function computeSearchCacheKey(engine, query, count = 10) {
7
- const normalized = `${String(engine || '').toLowerCase()}:${String(query || '').toLowerCase().trim()}:${count}`;
6
+ export function computeSearchCacheKey(engine, query, count = 10, options = {}) {
7
+ const relevantOptions = {
8
+ language: options.language || 'en',
9
+ isNews: options.isNews === true,
10
+ fanOut: options.fanOut !== false,
11
+ searxngUrl: options.searxngUrl || process.env.SEARXNG_URL || '',
12
+ k: Number(options.k) || 60
13
+ };
14
+ const normalized = `${String(engine || '').toLowerCase()}:${String(query || '').toLowerCase().trim()}:${count}:${JSON.stringify(relevantOptions)}`;
8
15
  return crypto.createHash('sha256').update(normalized).digest('hex');
9
16
  }
10
17
 
@@ -1,5 +1,6 @@
1
1
  import http from 'node:http';
2
2
  import https from 'node:https';
3
+ import { isIP } from 'node:net';
3
4
  import { lookup as dnsLookup } from 'node:dns/promises';
4
5
 
5
6
  export function parseIPv4(host) {
@@ -76,16 +77,46 @@ export function isPrivateIPv4(ip) {
76
77
  }
77
78
 
78
79
  export function isPrivateIPv6(ip) {
79
- const clean = ip.toLowerCase().trim();
80
-
81
- if (clean === '::1' || clean === '0:0:0:0:0:0:0:1' || clean === '::') return true;
82
-
83
- if (/^fe[89ab]/i.test(clean)) return true;
84
-
85
- if (/^f[cd]/i.test(clean)) return true;
86
-
87
- const mapped = clean.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
88
- if (mapped && isPrivateIPv4(mapped[1])) return true;
80
+ const clean = String(ip || '').toLowerCase().trim();
81
+ if (isIP(clean) !== 6) return false;
82
+
83
+ const halves = clean.split('::');
84
+ if (halves.length > 2) return false;
85
+ const left = halves[0] ? halves[0].split(':').filter(Boolean) : [];
86
+ const right = halves[1] ? halves[1].split(':').filter(Boolean) : [];
87
+ const embeddedIpv4 = right.length > 0 && right[right.length - 1].includes('.');
88
+ if (embeddedIpv4) {
89
+ const parsed = parseIPv4(right.pop());
90
+ if (!parsed) return false;
91
+ const value = parsed.split('.').map(Number);
92
+ right.push(((value[0] << 8) | value[1]).toString(16));
93
+ right.push(((value[2] << 8) | value[3]).toString(16));
94
+ }
95
+
96
+ const missing = 8 - left.length - right.length;
97
+ if (missing < 0) return false;
98
+ const groups = [
99
+ ...left.map(group => parseInt(group, 16)),
100
+ ...Array(missing).fill(0),
101
+ ...right.map(group => parseInt(group, 16))
102
+ ];
103
+ if (groups.length !== 8 || groups.some(group => !Number.isInteger(group) || group < 0 || group > 0xffff)) return false;
104
+
105
+ if (groups[0] === 0 && groups.slice(1).every(group => group === 0)) return true;
106
+ if ((groups[0] & 0xfe00) === 0xfc00) return true;
107
+ if ((groups[0] & 0xffc0) === 0xfe80) return true;
108
+
109
+ const isIpv4MappedOrCompatible = groups.slice(0, 6).every(group => group === 0) ||
110
+ (groups.slice(0, 5).every(group => group === 0) && groups[5] === 0xffff);
111
+ if (isIpv4MappedOrCompatible) {
112
+ const ipv4 = [
113
+ groups[6] >>> 8,
114
+ groups[6] & 255,
115
+ groups[7] >>> 8,
116
+ groups[7] & 255
117
+ ].join('.');
118
+ return isPrivateIPv4(ipv4);
119
+ }
89
120
 
90
121
  return false;
91
122
  }
@@ -3,7 +3,7 @@ import path from 'path';
3
3
  import { spawn, execFile } from 'child_process';
4
4
  import { promisify } from 'util';
5
5
  import { fileURLToPath } from 'url';
6
- import { KIKU_DATA_DIR } from './appPaths.js';
6
+ import { KIKU_DATA_DIR, resolveDynamicWindowsAppPaths } from './appPaths.js';
7
7
  import { PACKAGE_ENV_PATH, USER_ENV_PATH, upsertEnvKey } from './envManager.js';
8
8
  import { bootstrapEnv } from './envBootstrap.js';
9
9
 
@@ -27,34 +27,19 @@ async function findBrowserExeAsync(browser, { execImpl = execFileAsync } = {}) {
27
27
  const probes = {
28
28
  firefox: {
29
29
  cmd: 'firefox',
30
- paths: [
31
- 'C:\\Program Files\\Mozilla Firefox\\firefox.exe',
32
- 'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe',
33
- (process.env.LOCALAPPDATA || '') + '\\Mozilla Firefox\\firefox.exe'
34
- ]
30
+ paths: isWin ? resolveDynamicWindowsAppPaths('Mozilla Firefox', 'firefox.exe') : []
35
31
  },
36
32
  chrome: {
37
33
  cmd: isWin ? 'chrome' : 'google-chrome',
38
- paths: [
39
- 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
40
- (process.env.LOCALAPPDATA || '') + '\\Google\\Chrome\\Application\\chrome.exe',
41
- 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
42
- ]
34
+ paths: isWin ? resolveDynamicWindowsAppPaths('Google', 'Chrome', 'Application', 'chrome.exe') : []
43
35
  },
44
36
  edge: {
45
37
  cmd: isWin ? 'msedge' : 'microsoft-edge',
46
- paths: [
47
- 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe',
48
- 'C:\\Program Files\\Microsoft\\Edge\\Application\\msedge.exe',
49
- (process.env.LOCALAPPDATA || '') + '\\Microsoft\\Edge\\Application\\msedge.exe'
50
- ]
38
+ paths: isWin ? resolveDynamicWindowsAppPaths('Microsoft', 'Edge', 'Application', 'msedge.exe') : []
51
39
  },
52
40
  brave: {
53
41
  cmd: isWin ? 'brave' : 'brave-browser',
54
- paths: [
55
- 'C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
56
- (process.env.LOCALAPPDATA || '') + '\\BraveSoftware\\Brave-Browser\\Application\\brave.exe'
57
- ]
42
+ paths: isWin ? resolveDynamicWindowsAppPaths('BraveSoftware', 'Brave-Browser', 'Application', 'brave.exe') : []
58
43
  }
59
44
  };
60
45