@machina.ai/cell-cli-core 1.0.17-rc1 → 1.0.21-rc2

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 (399) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +3 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +9 -2
  5. package/dist/src/code_assist/converter.d.ts +4 -2
  6. package/dist/src/code_assist/converter.js +2 -1
  7. package/dist/src/code_assist/converter.js.map +1 -1
  8. package/dist/src/code_assist/converter.test.js +48 -1
  9. package/dist/src/code_assist/converter.test.js.map +1 -1
  10. package/dist/src/code_assist/oauth2.d.ts +1 -0
  11. package/dist/src/code_assist/oauth2.js +38 -21
  12. package/dist/src/code_assist/oauth2.js.map +1 -1
  13. package/dist/src/code_assist/oauth2.test.js +51 -8
  14. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  15. package/dist/src/code_assist/server.js +1 -1
  16. package/dist/src/code_assist/server.js.map +1 -1
  17. package/dist/src/code_assist/server.test.js +4 -1
  18. package/dist/src/code_assist/server.test.js.map +1 -1
  19. package/dist/src/code_assist/setup.js +48 -17
  20. package/dist/src/code_assist/setup.js.map +1 -1
  21. package/dist/src/code_assist/setup.test.js +114 -8
  22. package/dist/src/code_assist/setup.test.js.map +1 -1
  23. package/dist/src/config/config.d.ts +41 -11
  24. package/dist/src/config/config.js +85 -27
  25. package/dist/src/config/config.js.map +1 -1
  26. package/dist/src/config/config.test.js +117 -3
  27. package/dist/src/config/config.test.js.map +1 -1
  28. package/dist/src/config/flashFallback.test.js +0 -4
  29. package/dist/src/config/flashFallback.test.js.map +1 -1
  30. package/dist/src/core/client.d.ts +12 -16
  31. package/dist/src/core/client.js +218 -135
  32. package/dist/src/core/client.js.map +1 -1
  33. package/dist/src/core/client.test.js +636 -37
  34. package/dist/src/core/client.test.js.map +1 -1
  35. package/dist/src/core/contentGenerator.js +23 -21
  36. package/dist/src/core/contentGenerator.js.map +1 -1
  37. package/dist/src/core/contentGenerator.test.js +30 -126
  38. package/dist/src/core/contentGenerator.test.js.map +1 -1
  39. package/dist/src/core/coreToolScheduler.d.ts +23 -8
  40. package/dist/src/core/coreToolScheduler.js +179 -64
  41. package/dist/src/core/coreToolScheduler.js.map +1 -1
  42. package/dist/src/core/coreToolScheduler.test.js +250 -97
  43. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  44. package/dist/src/core/geminiChat.d.ts +7 -6
  45. package/dist/src/core/geminiChat.js +43 -43
  46. package/dist/src/core/geminiChat.js.map +1 -1
  47. package/dist/src/core/logger.d.ts +23 -1
  48. package/dist/src/core/logger.js +115 -11
  49. package/dist/src/core/logger.js.map +1 -1
  50. package/dist/src/core/logger.test.js +112 -17
  51. package/dist/src/core/logger.test.js.map +1 -1
  52. package/dist/src/core/loggingContentGenerator.d.ts +25 -0
  53. package/dist/src/core/loggingContentGenerator.js +95 -0
  54. package/dist/src/core/loggingContentGenerator.js.map +1 -0
  55. package/dist/src/core/nonInteractiveToolExecutor.js +28 -1
  56. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  57. package/dist/src/core/nonInteractiveToolExecutor.test.js +85 -62
  58. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  59. package/dist/src/core/prompts.js +4 -4
  60. package/dist/src/core/prompts.js.map +1 -1
  61. package/dist/src/core/subagent.d.ts +230 -0
  62. package/dist/src/core/subagent.js +447 -0
  63. package/dist/src/core/subagent.js.map +1 -0
  64. package/dist/src/core/subagent.test.d.ts +6 -0
  65. package/dist/src/core/subagent.test.js +515 -0
  66. package/dist/src/core/subagent.test.js.map +1 -0
  67. package/dist/src/core/turn.js +1 -0
  68. package/dist/src/core/turn.js.map +1 -1
  69. package/dist/src/core/turn.test.js +4 -0
  70. package/dist/src/core/turn.test.js.map +1 -1
  71. package/dist/src/generated/git-commit.d.ts +7 -0
  72. package/dist/src/generated/git-commit.js +10 -0
  73. package/dist/src/generated/git-commit.js.map +1 -0
  74. package/dist/src/ide/constants.d.ts +6 -0
  75. package/dist/src/ide/constants.js +7 -0
  76. package/dist/src/ide/constants.js.map +1 -0
  77. package/dist/src/ide/detect-ide.d.ts +12 -2
  78. package/dist/src/ide/detect-ide.js +64 -5
  79. package/dist/src/ide/detect-ide.js.map +1 -1
  80. package/dist/src/ide/detect-ide.test.d.ts +6 -0
  81. package/dist/src/ide/detect-ide.test.js +65 -0
  82. package/dist/src/ide/detect-ide.test.js.map +1 -0
  83. package/dist/src/ide/ide-client.d.ts +34 -11
  84. package/dist/src/ide/ide-client.js +230 -62
  85. package/dist/src/ide/ide-client.js.map +1 -1
  86. package/dist/src/ide/ide-client.test.d.ts +6 -0
  87. package/dist/src/ide/ide-client.test.js +43 -0
  88. package/dist/src/ide/ide-client.test.js.map +1 -0
  89. package/dist/src/ide/ide-installer.js +23 -34
  90. package/dist/src/ide/ide-installer.js.map +1 -1
  91. package/dist/src/ide/ide-installer.test.js +6 -8
  92. package/dist/src/ide/ide-installer.test.js.map +1 -1
  93. package/dist/src/ide/ideContext.d.ts +97 -2
  94. package/dist/src/ide/ideContext.js +45 -0
  95. package/dist/src/ide/ideContext.js.map +1 -1
  96. package/dist/src/ide/process-utils.d.ts +14 -0
  97. package/dist/src/ide/process-utils.js +57 -0
  98. package/dist/src/ide/process-utils.js.map +1 -0
  99. package/dist/src/index.d.ts +7 -1
  100. package/dist/src/index.js +7 -1
  101. package/dist/src/index.js.map +1 -1
  102. package/dist/src/mcp/google-auth-provider.js +9 -0
  103. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  104. package/dist/src/mcp/google-auth-provider.test.js +45 -10
  105. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  106. package/dist/src/mcp/oauth-provider.d.ts +1 -1
  107. package/dist/src/mcp/oauth-provider.js +185 -59
  108. package/dist/src/mcp/oauth-provider.js.map +1 -1
  109. package/dist/src/mcp/oauth-provider.test.js +134 -62
  110. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  111. package/dist/src/mcp/oauth-utils.d.ts +3 -1
  112. package/dist/src/mcp/oauth-utils.js +50 -12
  113. package/dist/src/mcp/oauth-utils.js.map +1 -1
  114. package/dist/src/mcp/oauth-utils.test.js +17 -2
  115. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  116. package/dist/src/mocks/msw.d.ts +6 -0
  117. package/dist/src/mocks/msw.js +8 -0
  118. package/dist/src/mocks/msw.js.map +1 -0
  119. package/dist/src/prompts/prompt-registry.d.ts +8 -0
  120. package/dist/src/prompts/prompt-registry.js +16 -0
  121. package/dist/src/prompts/prompt-registry.js.map +1 -1
  122. package/dist/src/services/chatRecordingService.d.ts +150 -0
  123. package/dist/src/services/chatRecordingService.js +318 -0
  124. package/dist/src/services/chatRecordingService.js.map +1 -0
  125. package/dist/src/services/chatRecordingService.test.d.ts +6 -0
  126. package/dist/src/services/chatRecordingService.test.js +288 -0
  127. package/dist/src/services/chatRecordingService.test.js.map +1 -0
  128. package/dist/src/services/fileSystemService.d.ts +31 -0
  129. package/dist/src/services/fileSystemService.js +18 -0
  130. package/dist/src/services/fileSystemService.js.map +1 -0
  131. package/dist/src/services/fileSystemService.test.d.ts +6 -0
  132. package/dist/src/services/fileSystemService.test.js +41 -0
  133. package/dist/src/services/fileSystemService.test.js.map +1 -0
  134. package/dist/src/services/loopDetectionService.js +19 -16
  135. package/dist/src/services/loopDetectionService.js.map +1 -1
  136. package/dist/src/services/loopDetectionService.test.js +191 -0
  137. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  138. package/dist/src/services/shellExecutionService.js +29 -9
  139. package/dist/src/services/shellExecutionService.js.map +1 -1
  140. package/dist/src/services/shellExecutionService.test.js +21 -3
  141. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  142. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +78 -9
  143. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +316 -205
  144. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  145. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +17 -0
  146. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +342 -0
  147. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
  148. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +14 -2
  149. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +32 -9
  150. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  151. package/dist/src/telemetry/constants.d.ts +2 -0
  152. package/dist/src/telemetry/constants.js +2 -0
  153. package/dist/src/telemetry/constants.js.map +1 -1
  154. package/dist/src/telemetry/index.d.ts +2 -2
  155. package/dist/src/telemetry/index.js +2 -2
  156. package/dist/src/telemetry/index.js.map +1 -1
  157. package/dist/src/telemetry/integration.test.circular.js +1 -0
  158. package/dist/src/telemetry/integration.test.circular.js.map +1 -1
  159. package/dist/src/telemetry/loggers.d.ts +4 -1
  160. package/dist/src/telemetry/loggers.js +55 -6
  161. package/dist/src/telemetry/loggers.js.map +1 -1
  162. package/dist/src/telemetry/loggers.test.circular.js +7 -2
  163. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  164. package/dist/src/telemetry/loggers.test.js +43 -8
  165. package/dist/src/telemetry/loggers.test.js.map +1 -1
  166. package/dist/src/telemetry/metrics.d.ts +7 -2
  167. package/dist/src/telemetry/metrics.js +26 -6
  168. package/dist/src/telemetry/metrics.js.map +1 -1
  169. package/dist/src/telemetry/metrics.test.js +81 -1
  170. package/dist/src/telemetry/metrics.test.js.map +1 -1
  171. package/dist/src/telemetry/sdk.d.ts +1 -1
  172. package/dist/src/telemetry/sdk.js +77 -41
  173. package/dist/src/telemetry/sdk.js.map +1 -1
  174. package/dist/src/telemetry/sdk.test.d.ts +6 -0
  175. package/dist/src/telemetry/sdk.test.js +82 -0
  176. package/dist/src/telemetry/sdk.test.js.map +1 -0
  177. package/dist/src/telemetry/telemetry.test.js +2 -4
  178. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  179. package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
  180. package/dist/src/telemetry/tool-call-decision.js +29 -0
  181. package/dist/src/telemetry/tool-call-decision.js.map +1 -0
  182. package/dist/src/telemetry/types.d.ts +55 -21
  183. package/dist/src/telemetry/types.js +83 -43
  184. package/dist/src/telemetry/types.js.map +1 -1
  185. package/dist/src/telemetry/uiTelemetry.d.ts +8 -1
  186. package/dist/src/telemetry/uiTelemetry.js +17 -2
  187. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  188. package/dist/src/telemetry/uiTelemetry.test.js +57 -10
  189. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  190. package/dist/src/test-utils/config.d.ts +16 -0
  191. package/dist/src/test-utils/config.js +32 -0
  192. package/dist/src/test-utils/config.js.map +1 -0
  193. package/dist/src/test-utils/tools.d.ts +44 -0
  194. package/dist/src/test-utils/tools.js +105 -0
  195. package/dist/src/test-utils/tools.js.map +1 -0
  196. package/dist/src/tools/diffOptions.d.ts +2 -0
  197. package/dist/src/tools/diffOptions.js +28 -0
  198. package/dist/src/tools/diffOptions.js.map +1 -1
  199. package/dist/src/tools/diffOptions.test.d.ts +6 -0
  200. package/dist/src/tools/diffOptions.test.js +119 -0
  201. package/dist/src/tools/diffOptions.test.js.map +1 -0
  202. package/dist/src/tools/edit.d.ts +10 -34
  203. package/dist/src/tools/edit.js +152 -136
  204. package/dist/src/tools/edit.js.map +1 -1
  205. package/dist/src/tools/edit.test.js +125 -51
  206. package/dist/src/tools/edit.test.js.map +1 -1
  207. package/dist/src/tools/glob.d.ts +4 -11
  208. package/dist/src/tools/glob.js +87 -91
  209. package/dist/src/tools/glob.js.map +1 -1
  210. package/dist/src/tools/glob.test.js +42 -12
  211. package/dist/src/tools/glob.test.js.map +1 -1
  212. package/dist/src/tools/grep.d.ts +4 -36
  213. package/dist/src/tools/grep.js +107 -84
  214. package/dist/src/tools/grep.js.map +1 -1
  215. package/dist/src/tools/grep.test.js +40 -23
  216. package/dist/src/tools/grep.test.js.map +1 -1
  217. package/dist/src/tools/ls.d.ts +4 -23
  218. package/dist/src/tools/ls.js +77 -79
  219. package/dist/src/tools/ls.js.map +1 -1
  220. package/dist/src/tools/ls.test.js +62 -34
  221. package/dist/src/tools/ls.test.js.map +1 -1
  222. package/dist/src/tools/mcp-client-manager.d.ts +38 -0
  223. package/dist/src/tools/mcp-client-manager.js +74 -0
  224. package/dist/src/tools/mcp-client-manager.js.map +1 -0
  225. package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
  226. package/dist/src/tools/mcp-client-manager.test.js +39 -0
  227. package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
  228. package/dist/src/tools/mcp-client.d.ts +57 -3
  229. package/dist/src/tools/mcp-client.js +235 -10
  230. package/dist/src/tools/mcp-client.js.map +1 -1
  231. package/dist/src/tools/mcp-client.test.js +234 -87
  232. package/dist/src/tools/mcp-client.test.js.map +1 -1
  233. package/dist/src/tools/mcp-tool.d.ts +6 -13
  234. package/dist/src/tools/mcp-tool.js +62 -34
  235. package/dist/src/tools/mcp-tool.js.map +1 -1
  236. package/dist/src/tools/mcp-tool.test.js +118 -59
  237. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  238. package/dist/src/tools/memoryTool.d.ts +10 -14
  239. package/dist/src/tools/memoryTool.js +123 -121
  240. package/dist/src/tools/memoryTool.js.map +1 -1
  241. package/dist/src/tools/memoryTool.test.js +38 -18
  242. package/dist/src/tools/memoryTool.test.js.map +1 -1
  243. package/dist/src/tools/modifiable-tool.d.ts +9 -6
  244. package/dist/src/tools/modifiable-tool.js +6 -3
  245. package/dist/src/tools/modifiable-tool.js.map +1 -1
  246. package/dist/src/tools/modifiable-tool.test.js +12 -12
  247. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  248. package/dist/src/tools/read-file.d.ts +4 -6
  249. package/dist/src/tools/read-file.js +95 -50
  250. package/dist/src/tools/read-file.js.map +1 -1
  251. package/dist/src/tools/read-file.test.js +199 -129
  252. package/dist/src/tools/read-file.test.js.map +1 -1
  253. package/dist/src/tools/read-many-files.d.ts +3 -5
  254. package/dist/src/tools/read-many-files.js +204 -138
  255. package/dist/src/tools/read-many-files.js.map +1 -1
  256. package/dist/src/tools/read-many-files.test.js +197 -33
  257. package/dist/src/tools/read-many-files.test.js.map +1 -1
  258. package/dist/src/tools/shell.d.ts +4 -6
  259. package/dist/src/tools/shell.js +112 -102
  260. package/dist/src/tools/shell.js.map +1 -1
  261. package/dist/src/tools/shell.test.js +55 -28
  262. package/dist/src/tools/shell.test.js.map +1 -1
  263. package/dist/src/tools/tool-error.d.ts +5 -0
  264. package/dist/src/tools/tool-error.js +5 -0
  265. package/dist/src/tools/tool-error.js.map +1 -1
  266. package/dist/src/tools/tool-registry.d.ts +25 -22
  267. package/dist/src/tools/tool-registry.js +100 -116
  268. package/dist/src/tools/tool-registry.js.map +1 -1
  269. package/dist/src/tools/tool-registry.test.js +29 -212
  270. package/dist/src/tools/tool-registry.test.js.map +1 -1
  271. package/dist/src/tools/tools.d.ts +137 -92
  272. package/dist/src/tools/tools.js +188 -61
  273. package/dist/src/tools/tools.js.map +1 -1
  274. package/dist/src/tools/tools.test.d.ts +6 -0
  275. package/dist/src/tools/tools.test.js +206 -0
  276. package/dist/src/tools/tools.test.js.map +1 -0
  277. package/dist/src/tools/web-fetch.d.ts +4 -7
  278. package/dist/src/tools/web-fetch.js +58 -64
  279. package/dist/src/tools/web-fetch.js.map +1 -1
  280. package/dist/src/tools/web-fetch.test.js +8 -4
  281. package/dist/src/tools/web-fetch.test.js.map +1 -1
  282. package/dist/src/tools/web-search.d.ts +4 -5
  283. package/dist/src/tools/web-search.js +47 -51
  284. package/dist/src/tools/web-search.js.map +1 -1
  285. package/dist/src/tools/web-search.test.d.ts +6 -0
  286. package/dist/src/tools/web-search.test.js +139 -0
  287. package/dist/src/tools/web-search.test.js.map +1 -0
  288. package/dist/src/tools/write-file.d.ts +20 -11
  289. package/dist/src/tools/write-file.js +197 -142
  290. package/dist/src/tools/write-file.js.map +1 -1
  291. package/dist/src/tools/write-file.test.js +156 -96
  292. package/dist/src/tools/write-file.test.js.map +1 -1
  293. package/dist/src/utils/bfsFileSearch.test.js +28 -56
  294. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  295. package/dist/src/utils/browser.js +4 -3
  296. package/dist/src/utils/browser.js.map +1 -1
  297. package/dist/src/utils/editCorrector.js +21 -22
  298. package/dist/src/utils/editCorrector.js.map +1 -1
  299. package/dist/src/utils/editor.d.ts +1 -1
  300. package/dist/src/utils/editor.js +14 -6
  301. package/dist/src/utils/editor.js.map +1 -1
  302. package/dist/src/utils/editor.test.js +48 -16
  303. package/dist/src/utils/editor.test.js.map +1 -1
  304. package/dist/src/utils/environmentContext.d.ts +21 -0
  305. package/dist/src/utils/environmentContext.js +90 -0
  306. package/dist/src/utils/environmentContext.js.map +1 -0
  307. package/dist/src/utils/environmentContext.test.d.ts +6 -0
  308. package/dist/src/utils/environmentContext.test.js +140 -0
  309. package/dist/src/utils/environmentContext.test.js.map +1 -0
  310. package/dist/src/utils/errorParsing.d.ts +8 -0
  311. package/dist/src/utils/errorParsing.js +93 -0
  312. package/dist/src/utils/errorParsing.js.map +1 -0
  313. package/dist/src/utils/errorParsing.test.d.ts +6 -0
  314. package/dist/src/utils/errorParsing.test.js +172 -0
  315. package/dist/src/utils/errorParsing.test.js.map +1 -0
  316. package/dist/src/utils/fileUtils.d.ts +9 -1
  317. package/dist/src/utils/fileUtils.js +18 -15
  318. package/dist/src/utils/fileUtils.js.map +1 -1
  319. package/dist/src/utils/fileUtils.test.js +24 -22
  320. package/dist/src/utils/fileUtils.test.js.map +1 -1
  321. package/dist/src/utils/filesearch/crawlCache.d.ts +25 -0
  322. package/dist/src/utils/filesearch/crawlCache.js +57 -0
  323. package/dist/src/utils/filesearch/crawlCache.js.map +1 -0
  324. package/dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
  325. package/dist/src/utils/filesearch/crawlCache.test.js +103 -0
  326. package/dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
  327. package/dist/src/utils/filesearch/crawler.d.ts +15 -0
  328. package/dist/src/utils/filesearch/crawler.js +50 -0
  329. package/dist/src/utils/filesearch/crawler.js.map +1 -0
  330. package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
  331. package/dist/src/utils/filesearch/crawler.test.js +468 -0
  332. package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
  333. package/dist/src/utils/filesearch/fileSearch.d.ts +37 -0
  334. package/dist/src/utils/filesearch/fileSearch.js +186 -0
  335. package/dist/src/utils/filesearch/fileSearch.js.map +1 -0
  336. package/dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
  337. package/dist/src/utils/filesearch/fileSearch.test.js +552 -0
  338. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
  339. package/dist/src/utils/filesearch/ignore.d.ts +42 -0
  340. package/dist/src/utils/filesearch/ignore.js +106 -0
  341. package/dist/src/utils/filesearch/ignore.js.map +1 -0
  342. package/dist/src/utils/filesearch/ignore.test.d.ts +6 -0
  343. package/dist/src/utils/filesearch/ignore.test.js +144 -0
  344. package/dist/src/utils/filesearch/ignore.test.js.map +1 -0
  345. package/dist/src/utils/filesearch/result-cache.d.ts +33 -0
  346. package/dist/src/utils/filesearch/result-cache.js +59 -0
  347. package/dist/src/utils/filesearch/result-cache.js.map +1 -0
  348. package/dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
  349. package/dist/src/utils/filesearch/result-cache.test.js +46 -0
  350. package/dist/src/utils/filesearch/result-cache.test.js.map +1 -0
  351. package/dist/src/utils/flashFallback.integration.test.js +0 -2
  352. package/dist/src/utils/flashFallback.integration.test.js.map +1 -1
  353. package/dist/src/utils/memoryDiscovery.js +7 -4
  354. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  355. package/dist/src/utils/memoryDiscovery.test.js +3 -2
  356. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  357. package/dist/src/utils/memoryImportProcessor.js +3 -7
  358. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  359. package/dist/src/utils/memoryImportProcessor.test.js +17 -20
  360. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  361. package/dist/src/utils/nextSpeakerChecker.js +5 -6
  362. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  363. package/dist/src/utils/nextSpeakerChecker.test.js +2 -2
  364. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  365. package/dist/src/utils/paths.d.ts +7 -0
  366. package/dist/src/utils/paths.js +15 -0
  367. package/dist/src/utils/paths.js.map +1 -1
  368. package/dist/src/utils/paths.test.js +74 -2
  369. package/dist/src/utils/paths.test.js.map +1 -1
  370. package/dist/src/utils/quotaErrorDetection.d.ts +1 -5
  371. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  372. package/dist/src/utils/schemaValidator.d.ts +1 -8
  373. package/dist/src/utils/schemaValidator.js +1 -32
  374. package/dist/src/utils/schemaValidator.js.map +1 -1
  375. package/dist/src/utils/secure-browser-launcher.js +4 -3
  376. package/dist/src/utils/secure-browser-launcher.js.map +1 -1
  377. package/dist/src/utils/shell-utils.d.ts +39 -0
  378. package/dist/src/utils/shell-utils.js +72 -2
  379. package/dist/src/utils/shell-utils.js.map +1 -1
  380. package/dist/src/utils/shell-utils.test.js +132 -4
  381. package/dist/src/utils/shell-utils.test.js.map +1 -1
  382. package/dist/src/utils/systemEncoding.js +1 -1
  383. package/dist/src/utils/systemEncoding.js.map +1 -1
  384. package/dist/src/utils/systemEncoding.test.js +23 -23
  385. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  386. package/dist/src/utils/user_account.js +58 -48
  387. package/dist/src/utils/user_account.js.map +1 -1
  388. package/dist/src/utils/user_account.test.js +76 -9
  389. package/dist/src/utils/user_account.test.js.map +1 -1
  390. package/dist/src/utils/workspaceContext.d.ts +22 -7
  391. package/dist/src/utils/workspaceContext.js +81 -55
  392. package/dist/src/utils/workspaceContext.js.map +1 -1
  393. package/dist/src/utils/workspaceContext.test.js +221 -137
  394. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  395. package/dist/tsconfig.tsbuildinfo +1 -1
  396. package/package.json +11 -2
  397. package/dist/src/core/modelCheck.d.ts +0 -14
  398. package/dist/src/core/modelCheck.js +0 -62
  399. package/dist/src/core/modelCheck.js.map +0 -1
@@ -3,38 +3,102 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Buffer } from 'buffer';
7
- import * as https from 'https';
8
6
  import { HttpsProxyAgent } from 'https-proxy-agent';
9
- import { EndSessionEvent, } from '../types.js';
10
7
  import { EventMetadataKey } from './event-metadata-key.js';
11
8
  import { safeJsonStringify } from '../../utils/safeJsonStringify.js';
12
9
  import { getCachedGoogleAccount, getLifetimeGoogleAccounts, } from '../../utils/user_account.js';
13
- import { retryWithBackoff } from '../../utils/retry.js';
14
10
  import { getInstallationId } from '../../utils/user_id.js';
15
- const start_session_event_name = 'start_session';
16
- const new_prompt_event_name = 'new_prompt';
17
- const tool_call_event_name = 'tool_call';
18
- const api_request_event_name = 'api_request';
19
- const api_response_event_name = 'api_response';
20
- const api_error_event_name = 'api_error';
21
- const end_session_event_name = 'end_session';
22
- const flash_fallback_event_name = 'flash_fallback';
23
- const loop_detected_event_name = 'loop_detected';
24
- const next_speaker_check_event_name = 'next_speaker_check';
25
- const slash_command_event_name = 'slash_command';
26
- const malformed_json_response_event_name = 'malformed_json_response';
11
+ import { FixedDeque } from 'mnemonist';
12
+ import { GIT_COMMIT_INFO, CLI_VERSION } from '../../generated/git-commit.js';
13
+ import { DetectedIde, detectIde } from '../../ide/detect-ide.js';
14
+ export var EventNames;
15
+ (function (EventNames) {
16
+ EventNames["START_SESSION"] = "start_session";
17
+ EventNames["NEW_PROMPT"] = "new_prompt";
18
+ EventNames["TOOL_CALL"] = "tool_call";
19
+ EventNames["API_REQUEST"] = "api_request";
20
+ EventNames["API_RESPONSE"] = "api_response";
21
+ EventNames["API_ERROR"] = "api_error";
22
+ EventNames["END_SESSION"] = "end_session";
23
+ EventNames["FLASH_FALLBACK"] = "flash_fallback";
24
+ EventNames["LOOP_DETECTED"] = "loop_detected";
25
+ EventNames["NEXT_SPEAKER_CHECK"] = "next_speaker_check";
26
+ EventNames["SLASH_COMMAND"] = "slash_command";
27
+ EventNames["MALFORMED_JSON_RESPONSE"] = "malformed_json_response";
28
+ EventNames["IDE_CONNECTION"] = "ide_connection";
29
+ EventNames["KITTY_SEQUENCE_OVERFLOW"] = "kitty_sequence_overflow";
30
+ EventNames["CHAT_COMPRESSION"] = "chat_compression";
31
+ })(EventNames || (EventNames = {}));
32
+ /**
33
+ * Determine the surface that the user is currently using. Surface is effectively the
34
+ * distribution channel in which the user is using Gemini CLI. Gemini CLI comes bundled
35
+ * w/ Firebase Studio and Cloud Shell. Users that manually download themselves will
36
+ * likely be "SURFACE_NOT_SET".
37
+ *
38
+ * This is computed based upon a series of environment variables these distribution
39
+ * methods might have in their runtimes.
40
+ */
41
+ function determineSurface() {
42
+ if (process.env['SURFACE']) {
43
+ return process.env['SURFACE'];
44
+ }
45
+ else if (process.env['GITHUB_SHA']) {
46
+ return 'GitHub';
47
+ }
48
+ else if (process.env['TERM_PROGRAM'] === 'vscode') {
49
+ return detectIde() || DetectedIde.VSCode;
50
+ }
51
+ else {
52
+ return 'SURFACE_NOT_SET';
53
+ }
54
+ }
55
+ /**
56
+ * Clearcut URL to send logging events to.
57
+ */
58
+ const CLEARCUT_URL = 'https://play.googleapis.com/log?format=json&hasfast=true';
59
+ /**
60
+ * Interval in which buffered events are sent to clearcut.
61
+ */
62
+ const FLUSH_INTERVAL_MS = 1000 * 60;
63
+ /**
64
+ * Maximum amount of events to keep in memory. Events added after this amount
65
+ * are dropped until the next flush to clearcut, which happens periodically as
66
+ * defined by {@link FLUSH_INTERVAL_MS}.
67
+ */
68
+ const MAX_EVENTS = 1000;
69
+ /**
70
+ * Maximum events to retry after a failed clearcut flush
71
+ */
72
+ const MAX_RETRY_EVENTS = 100;
27
73
  // Singleton class for batch posting log events to Clearcut. When a new event comes in, the elapsed time
28
74
  // is checked and events are flushed to Clearcut if at least a minute has passed since the last flush.
29
75
  export class ClearcutLogger {
30
76
  static instance;
31
77
  config;
32
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Clearcut expects this format.
33
- events = [];
34
- last_flush_time = Date.now();
35
- flush_interval_ms = 1000 * 60; // Wait at least a minute before flushing events.
78
+ sessionData = [];
79
+ promptId = '';
80
+ /**
81
+ * Queue of pending events that need to be flushed to the server. New events
82
+ * are added to this queue and then flushed on demand (via `flushToClearcut`)
83
+ */
84
+ events;
85
+ /**
86
+ * The last time that the events were successfully flushed to the server.
87
+ */
88
+ lastFlushTime = Date.now();
89
+ /**
90
+ * the value is true when there is a pending flush happening. This prevents
91
+ * concurrent flush operations.
92
+ */
93
+ flushing = false;
94
+ /**
95
+ * This value is true when a flush was requested during an ongoing flush.
96
+ */
97
+ pendingFlush = false;
36
98
  constructor(config) {
37
99
  this.config = config;
100
+ this.events = new FixedDeque(Array, MAX_EVENTS);
101
+ this.promptId = config?.getSessionId() ?? '';
38
102
  }
39
103
  static getInstance(config) {
40
104
  if (config === undefined || !config?.getUsageStatisticsEnabled())
@@ -44,27 +108,44 @@ export class ClearcutLogger {
44
108
  }
45
109
  return ClearcutLogger.instance;
46
110
  }
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Clearcut expects this format.
111
+ /** For testing purposes only. */
112
+ static clearInstance() {
113
+ // @ts-expect-error - ClearcutLogger is a singleton, but we need to clear it for tests.
114
+ ClearcutLogger.instance = undefined;
115
+ }
48
116
  enqueueLogEvent(event) {
49
- this.events.push([
50
- {
51
- event_time_ms: Date.now(),
52
- source_extension_json: safeJsonStringify(event),
53
- },
54
- ]);
117
+ try {
118
+ // Manually handle overflow for FixedDeque, which throws when full.
119
+ const wasAtCapacity = this.events.size >= MAX_EVENTS;
120
+ if (wasAtCapacity) {
121
+ this.events.shift(); // Evict oldest element to make space.
122
+ }
123
+ this.events.push([
124
+ {
125
+ event_time_ms: Date.now(),
126
+ source_extension_json: safeJsonStringify(event),
127
+ },
128
+ ]);
129
+ if (wasAtCapacity && this.config?.getDebugMode()) {
130
+ console.debug(`ClearcutLogger: Dropped old event to prevent memory leak (queue size: ${this.events.size})`);
131
+ }
132
+ }
133
+ catch (error) {
134
+ if (this.config?.getDebugMode()) {
135
+ console.error('ClearcutLogger: Failed to enqueue log event.', error);
136
+ }
137
+ }
55
138
  }
56
- createLogEvent(name, data) {
139
+ createLogEvent(eventName, data = []) {
57
140
  const email = getCachedGoogleAccount();
58
- const totalAccounts = getLifetimeGoogleAccounts();
59
- data.push({
60
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_GOOGLE_ACCOUNTS_COUNT,
61
- value: totalAccounts.toString(),
62
- });
63
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
141
+ if (eventName !== EventNames.START_SESSION) {
142
+ data.push(...this.sessionData);
143
+ }
144
+ data = this.addDefaultFields(data);
64
145
  const logEvent = {
65
146
  console_type: 'GEMINI_CLI',
66
- application: 102,
67
- event_name: name,
147
+ application: 102, // GEMINI_CLI
148
+ event_name: eventName,
68
149
  event_metadata: [data],
69
150
  };
70
151
  // Should log either email or install ID, not both. See go/cloudmill-1p-oss-instrumentation#define-sessionable-id
@@ -77,7 +158,7 @@ export class ClearcutLogger {
77
158
  return logEvent;
78
159
  }
79
160
  flushIfNeeded() {
80
- if (Date.now() - this.last_flush_time < this.flush_interval_ms) {
161
+ if (Date.now() - this.lastFlushTime < FLUSH_INTERVAL_MS) {
81
162
  return;
82
163
  }
83
164
  this.flushToClearcut().catch((error) => {
@@ -85,118 +166,78 @@ export class ClearcutLogger {
85
166
  });
86
167
  }
87
168
  async flushToClearcut() {
169
+ if (this.flushing) {
170
+ if (this.config?.getDebugMode()) {
171
+ console.debug('ClearcutLogger: Flush already in progress, marking pending flush.');
172
+ }
173
+ this.pendingFlush = true;
174
+ return Promise.resolve({});
175
+ }
176
+ this.flushing = true;
88
177
  if (this.config?.getDebugMode()) {
89
178
  console.log('Flushing log events to Clearcut.');
90
179
  }
91
- const eventsToSend = [...this.events];
92
- if (eventsToSend.length === 0) {
93
- return {};
94
- }
95
- const flushFn = () => new Promise((resolve, reject) => {
96
- const request = [
97
- {
98
- log_source_name: 'CONCORD',
99
- request_time_ms: Date.now(),
100
- log_event: eventsToSend,
101
- },
102
- ];
103
- const body = safeJsonStringify(request);
104
- const options = {
105
- hostname: 'play.googleapis.com',
106
- path: '/log',
107
- method: 'POST',
108
- headers: { 'Content-Length': Buffer.byteLength(body) },
109
- };
110
- const bufs = [];
111
- const req = https.request({
112
- ...options,
113
- agent: this.getProxyAgent(),
114
- }, (res) => {
115
- if (res.statusCode &&
116
- (res.statusCode < 200 || res.statusCode >= 300)) {
117
- const err = new Error(`Request failed with status ${res.statusCode}`);
118
- err.status = res.statusCode;
119
- res.resume();
120
- return reject(err);
121
- }
122
- res.on('data', (buf) => bufs.push(buf));
123
- res.on('end', () => resolve(Buffer.concat(bufs)));
124
- });
125
- req.on('error', reject);
126
- req.end(body);
127
- });
180
+ const eventsToSend = this.events.toArray();
181
+ this.events.clear();
182
+ const request = [
183
+ {
184
+ log_source_name: 'CONCORD',
185
+ request_time_ms: Date.now(),
186
+ log_event: eventsToSend,
187
+ },
188
+ ];
189
+ let result = {};
128
190
  try {
129
- const responseBuffer = await retryWithBackoff(flushFn, {
130
- maxAttempts: 3,
131
- initialDelayMs: 200,
132
- shouldRetry: (err) => {
133
- if (!(err instanceof Error))
134
- return false;
135
- const status = err.status;
136
- // If status is not available, it's likely a network error
137
- if (status === undefined)
138
- return true;
139
- // Retry on 429 (Too many Requests) and 5xx server errors.
140
- return status === 429 || (status >= 500 && status < 600);
191
+ const response = await fetch(CLEARCUT_URL, {
192
+ method: 'POST',
193
+ body: safeJsonStringify(request),
194
+ headers: {
195
+ 'Content-Type': 'application/json',
141
196
  },
142
197
  });
143
- this.events.splice(0, eventsToSend.length);
144
- this.last_flush_time = Date.now();
145
- return this.decodeLogResponse(responseBuffer) || {};
198
+ const responseBody = await response.text();
199
+ if (response.status >= 200 && response.status < 300) {
200
+ this.lastFlushTime = Date.now();
201
+ const nextRequestWaitMs = Number(JSON.parse(responseBody)[0]);
202
+ result = {
203
+ ...result,
204
+ nextRequestWaitMs,
205
+ };
206
+ }
207
+ else {
208
+ if (this.config?.getDebugMode()) {
209
+ console.error(`Error flushing log events: HTTP ${response.status}: ${response.statusText}`);
210
+ }
211
+ // Re-queue failed events for retry
212
+ this.requeueFailedEvents(eventsToSend);
213
+ }
146
214
  }
147
- catch (error) {
215
+ catch (e) {
148
216
  if (this.config?.getDebugMode()) {
149
- console.error('Clearcut flush failed after multiple retries.', error);
217
+ console.error('Error flushing log events:', e);
150
218
  }
151
- return {};
219
+ // Re-queue failed events for retry
220
+ this.requeueFailedEvents(eventsToSend);
152
221
  }
153
- }
154
- // Visible for testing. Decodes protobuf-encoded response from Clearcut server.
155
- decodeLogResponse(buf) {
156
- // TODO(obrienowen): return specific errors to facilitate debugging.
157
- if (buf.length < 1) {
158
- return undefined;
159
- }
160
- // The first byte of the buffer is `field<<3 | type`. We're looking for field
161
- // 1, with type varint, represented by type=0. If the first byte isn't 8, that
162
- // means field 1 is missing or the message is corrupted. Either way, we return
163
- // undefined.
164
- if (buf.readUInt8(0) !== 8) {
165
- return undefined;
166
- }
167
- let ms = BigInt(0);
168
- let cont = true;
169
- // In each byte, the most significant bit is the continuation bit. If it's
170
- // set, we keep going. The lowest 7 bits, are data bits. They are concatenated
171
- // in reverse order to form the final number.
172
- for (let i = 1; cont && i < buf.length; i++) {
173
- const byte = buf.readUInt8(i);
174
- ms |= BigInt(byte & 0x7f) << BigInt(7 * (i - 1));
175
- cont = (byte & 0x80) !== 0;
176
- }
177
- if (cont) {
178
- // We have fallen off the buffer without seeing a terminating byte. The
179
- // message is corrupted.
180
- return undefined;
222
+ this.flushing = false;
223
+ // If a flush was requested while we were flushing, flush again
224
+ if (this.pendingFlush) {
225
+ this.pendingFlush = false;
226
+ // Fire and forget the pending flush
227
+ this.flushToClearcut().catch((error) => {
228
+ if (this.config?.getDebugMode()) {
229
+ console.debug('Error in pending flush to Clearcut:', error);
230
+ }
231
+ });
181
232
  }
182
- const returnVal = {
183
- nextRequestWaitMs: Number(ms),
184
- };
185
- return returnVal;
233
+ return result;
186
234
  }
187
235
  logStartSessionEvent(event) {
188
- const surface = process.env.CLOUD_SHELL === 'true'
189
- ? 'CLOUD_SHELL'
190
- : process.env.SURFACE || 'SURFACE_NOT_SET';
191
236
  const data = [
192
237
  {
193
238
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_MODEL,
194
239
  value: event.model,
195
240
  },
196
- {
197
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
198
- value: this.config?.getSessionId() ?? '',
199
- },
200
241
  {
201
242
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_EMBEDDING_MODEL,
202
243
  value: event.embedding_model,
@@ -245,37 +286,23 @@ export class ClearcutLogger {
245
286
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_TELEMETRY_LOG_USER_PROMPTS_ENABLED,
246
287
  value: event.telemetry_log_user_prompts_enabled.toString(),
247
288
  },
248
- {
249
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE,
250
- value: surface,
251
- },
252
289
  ];
290
+ this.sessionData = data;
253
291
  // Flush start event immediately
254
- this.enqueueLogEvent(this.createLogEvent(start_session_event_name, data));
292
+ this.enqueueLogEvent(this.createLogEvent(EventNames.START_SESSION, data));
255
293
  this.flushToClearcut().catch((error) => {
256
294
  console.debug('Error flushing to Clearcut:', error);
257
295
  });
258
296
  }
259
297
  logNewPromptEvent(event) {
298
+ this.promptId = event.prompt_id;
260
299
  const data = [
261
300
  {
262
301
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_USER_PROMPT_LENGTH,
263
302
  value: JSON.stringify(event.prompt_length),
264
303
  },
265
- {
266
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
267
- value: this.config?.getSessionId() ?? '',
268
- },
269
- {
270
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
271
- value: JSON.stringify(event.prompt_id),
272
- },
273
- {
274
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
275
- value: JSON.stringify(event.auth_type),
276
- },
277
304
  ];
278
- this.enqueueLogEvent(this.createLogEvent(new_prompt_event_name, data));
305
+ this.enqueueLogEvent(this.createLogEvent(EventNames.NEW_PROMPT, data));
279
306
  this.flushIfNeeded();
280
307
  }
281
308
  logToolCallEvent(event) {
@@ -284,10 +311,6 @@ export class ClearcutLogger {
284
311
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
285
312
  value: JSON.stringify(event.function_name),
286
313
  },
287
- {
288
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
289
- value: JSON.stringify(event.prompt_id),
290
- },
291
314
  {
292
315
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_DECISION,
293
316
  value: JSON.stringify(event.decision),
@@ -308,8 +331,28 @@ export class ClearcutLogger {
308
331
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_ERROR_TYPE,
309
332
  value: JSON.stringify(event.error_type),
310
333
  },
334
+ {
335
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_TYPE,
336
+ value: JSON.stringify(event.tool_type),
337
+ },
311
338
  ];
312
- const logEvent = this.createLogEvent(tool_call_event_name, data);
339
+ if (event.metadata) {
340
+ const metadataMapping = {
341
+ ai_added_lines: EventMetadataKey.GEMINI_CLI_AI_ADDED_LINES,
342
+ ai_removed_lines: EventMetadataKey.GEMINI_CLI_AI_REMOVED_LINES,
343
+ user_added_lines: EventMetadataKey.GEMINI_CLI_USER_ADDED_LINES,
344
+ user_removed_lines: EventMetadataKey.GEMINI_CLI_USER_REMOVED_LINES,
345
+ };
346
+ for (const [key, gemini_cli_key] of Object.entries(metadataMapping)) {
347
+ if (event.metadata[key] !== undefined) {
348
+ data.push({
349
+ gemini_cli_key,
350
+ value: JSON.stringify(event.metadata[key]),
351
+ });
352
+ }
353
+ }
354
+ }
355
+ const logEvent = this.createLogEvent(EventNames.TOOL_CALL, data);
313
356
  this.enqueueLogEvent(logEvent);
314
357
  this.flushIfNeeded();
315
358
  }
@@ -319,12 +362,8 @@ export class ClearcutLogger {
319
362
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_REQUEST_MODEL,
320
363
  value: JSON.stringify(event.model),
321
364
  },
322
- {
323
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
324
- value: JSON.stringify(event.prompt_id),
325
- },
326
365
  ];
327
- this.enqueueLogEvent(this.createLogEvent(api_request_event_name, data));
366
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_REQUEST, data));
328
367
  this.flushIfNeeded();
329
368
  }
330
369
  logApiResponseEvent(event) {
@@ -333,10 +372,6 @@ export class ClearcutLogger {
333
372
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_MODEL,
334
373
  value: JSON.stringify(event.model),
335
374
  },
336
- {
337
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
338
- value: JSON.stringify(event.prompt_id),
339
- },
340
375
  {
341
376
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_STATUS_CODE,
342
377
  value: JSON.stringify(event.status_code),
@@ -369,12 +404,8 @@ export class ClearcutLogger {
369
404
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_RESPONSE_TOOL_TOKEN_COUNT,
370
405
  value: JSON.stringify(event.tool_token_count),
371
406
  },
372
- {
373
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
374
- value: JSON.stringify(event.auth_type),
375
- },
376
407
  ];
377
- this.enqueueLogEvent(this.createLogEvent(api_response_event_name, data));
408
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_RESPONSE, data));
378
409
  this.flushIfNeeded();
379
410
  }
380
411
  logApiErrorEvent(event) {
@@ -383,10 +414,6 @@ export class ClearcutLogger {
383
414
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_MODEL,
384
415
  value: JSON.stringify(event.model),
385
416
  },
386
- {
387
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
388
- value: JSON.stringify(event.prompt_id),
389
- },
390
417
  {
391
418
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_TYPE,
392
419
  value: JSON.stringify(event.error_type),
@@ -399,50 +426,41 @@ export class ClearcutLogger {
399
426
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_DURATION_MS,
400
427
  value: JSON.stringify(event.duration_ms),
401
428
  },
402
- {
403
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
404
- value: JSON.stringify(event.auth_type),
405
- },
406
429
  ];
407
- this.enqueueLogEvent(this.createLogEvent(api_error_event_name, data));
430
+ this.enqueueLogEvent(this.createLogEvent(EventNames.API_ERROR, data));
408
431
  this.flushIfNeeded();
409
432
  }
410
- logFlashFallbackEvent(event) {
433
+ logChatCompressionEvent(event) {
411
434
  const data = [
412
435
  {
413
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
414
- value: JSON.stringify(event.auth_type),
436
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_COMPRESSION_TOKENS_BEFORE,
437
+ value: `${event.tokens_before}`,
415
438
  },
416
439
  {
417
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
418
- value: this.config?.getSessionId() ?? '',
440
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_COMPRESSION_TOKENS_AFTER,
441
+ value: `${event.tokens_after}`,
419
442
  },
420
443
  ];
421
- this.enqueueLogEvent(this.createLogEvent(flash_fallback_event_name, data));
444
+ this.enqueueLogEvent(this.createLogEvent(EventNames.CHAT_COMPRESSION, data));
445
+ }
446
+ logFlashFallbackEvent() {
447
+ this.enqueueLogEvent(this.createLogEvent(EventNames.FLASH_FALLBACK, []));
422
448
  this.flushToClearcut().catch((error) => {
423
449
  console.debug('Error flushing to Clearcut:', error);
424
450
  });
425
451
  }
426
452
  logLoopDetectedEvent(event) {
427
453
  const data = [
428
- {
429
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
430
- value: JSON.stringify(event.prompt_id),
431
- },
432
454
  {
433
455
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_LOOP_DETECTED_TYPE,
434
456
  value: JSON.stringify(event.loop_type),
435
457
  },
436
458
  ];
437
- this.enqueueLogEvent(this.createLogEvent(loop_detected_event_name, data));
459
+ this.enqueueLogEvent(this.createLogEvent(EventNames.LOOP_DETECTED, data));
438
460
  this.flushIfNeeded();
439
461
  }
440
462
  logNextSpeakerCheck(event) {
441
463
  const data = [
442
- {
443
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
444
- value: JSON.stringify(event.prompt_id),
445
- },
446
464
  {
447
465
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_RESPONSE_FINISH_REASON,
448
466
  value: JSON.stringify(event.finish_reason),
@@ -451,12 +469,8 @@ export class ClearcutLogger {
451
469
  gemini_cli_key: EventMetadataKey.GEMINI_CLI_NEXT_SPEAKER_CHECK_RESULT,
452
470
  value: JSON.stringify(event.result),
453
471
  },
454
- {
455
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
456
- value: this.config?.getSessionId() ?? '',
457
- },
458
472
  ];
459
- this.enqueueLogEvent(this.createLogEvent(next_speaker_check_event_name, data));
473
+ this.enqueueLogEvent(this.createLogEvent(EventNames.NEXT_SPEAKER_CHECK, data));
460
474
  this.flushIfNeeded();
461
475
  }
462
476
  logSlashCommandEvent(event) {
@@ -472,7 +486,13 @@ export class ClearcutLogger {
472
486
  value: JSON.stringify(event.subcommand),
473
487
  });
474
488
  }
475
- this.enqueueLogEvent(this.createLogEvent(slash_command_event_name, data));
489
+ if (event.status) {
490
+ data.push({
491
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SLASH_COMMAND_STATUS,
492
+ value: JSON.stringify(event.status),
493
+ });
494
+ }
495
+ this.enqueueLogEvent(this.createLogEvent(EventNames.SLASH_COMMAND, data));
476
496
  this.flushIfNeeded();
477
497
  }
478
498
  logMalformedJsonResponseEvent(event) {
@@ -482,22 +502,79 @@ export class ClearcutLogger {
482
502
  value: JSON.stringify(event.model),
483
503
  },
484
504
  ];
485
- this.enqueueLogEvent(this.createLogEvent(malformed_json_response_event_name, data));
505
+ this.enqueueLogEvent(this.createLogEvent(EventNames.MALFORMED_JSON_RESPONSE, data));
486
506
  this.flushIfNeeded();
487
507
  }
488
- logEndSessionEvent(event) {
508
+ logIdeConnectionEvent(event) {
489
509
  const data = [
490
510
  {
491
- gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
492
- value: event?.session_id?.toString() ?? '',
511
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_IDE_CONNECTION_TYPE,
512
+ value: JSON.stringify(event.connection_type),
493
513
  },
494
514
  ];
515
+ this.enqueueLogEvent(this.createLogEvent(EventNames.IDE_CONNECTION, data));
516
+ this.flushIfNeeded();
517
+ }
518
+ logKittySequenceOverflowEvent(event) {
519
+ const data = [
520
+ {
521
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_KITTY_SEQUENCE_LENGTH,
522
+ value: event.sequence_length.toString(),
523
+ },
524
+ {
525
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_KITTY_TRUNCATED_SEQUENCE,
526
+ value: event.truncated_sequence,
527
+ },
528
+ ];
529
+ this.enqueueLogEvent(this.createLogEvent(EventNames.KITTY_SEQUENCE_OVERFLOW, data));
530
+ this.flushIfNeeded();
531
+ }
532
+ logEndSessionEvent() {
495
533
  // Flush immediately on session end.
496
- this.enqueueLogEvent(this.createLogEvent(end_session_event_name, data));
534
+ this.enqueueLogEvent(this.createLogEvent(EventNames.END_SESSION, []));
497
535
  this.flushToClearcut().catch((error) => {
498
536
  console.debug('Error flushing to Clearcut:', error);
499
537
  });
500
538
  }
539
+ /**
540
+ * Adds default fields to data, and returns a new data array. This fields
541
+ * should exist on all log events.
542
+ */
543
+ addDefaultFields(data) {
544
+ const totalAccounts = getLifetimeGoogleAccounts();
545
+ const surface = determineSurface();
546
+ const defaultLogMetadata = [
547
+ {
548
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SESSION_ID,
549
+ value: this.config?.getSessionId() ?? '',
550
+ },
551
+ {
552
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
553
+ value: JSON.stringify(this.config?.getContentGeneratorConfig()?.authType),
554
+ },
555
+ {
556
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_GOOGLE_ACCOUNTS_COUNT,
557
+ value: `${totalAccounts}`,
558
+ },
559
+ {
560
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE,
561
+ value: surface,
562
+ },
563
+ {
564
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_VERSION,
565
+ value: CLI_VERSION,
566
+ },
567
+ {
568
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_GIT_COMMIT_HASH,
569
+ value: GIT_COMMIT_INFO,
570
+ },
571
+ {
572
+ gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
573
+ value: this.promptId,
574
+ },
575
+ ];
576
+ return [...data, ...defaultLogMetadata];
577
+ }
501
578
  getProxyAgent() {
502
579
  const proxyUrl = this.config?.getProxy();
503
580
  if (!proxyUrl)
@@ -512,8 +589,42 @@ export class ClearcutLogger {
512
589
  }
513
590
  }
514
591
  shutdown() {
515
- const event = new EndSessionEvent(this.config);
516
- this.logEndSessionEvent(event);
592
+ this.logEndSessionEvent();
593
+ }
594
+ requeueFailedEvents(eventsToSend) {
595
+ // Add the events back to the front of the queue to be retried, but limit retry queue size
596
+ const eventsToRetry = eventsToSend.slice(-MAX_RETRY_EVENTS); // Keep only the most recent events
597
+ // Log a warning if we're dropping events
598
+ if (eventsToSend.length > MAX_RETRY_EVENTS && this.config?.getDebugMode()) {
599
+ console.warn(`ClearcutLogger: Dropping ${eventsToSend.length - MAX_RETRY_EVENTS} events due to retry queue limit. Total events: ${eventsToSend.length}, keeping: ${MAX_RETRY_EVENTS}`);
600
+ }
601
+ // Determine how many events can be re-queued
602
+ const availableSpace = MAX_EVENTS - this.events.size;
603
+ const numEventsToRequeue = Math.min(eventsToRetry.length, availableSpace);
604
+ if (numEventsToRequeue === 0) {
605
+ if (this.config?.getDebugMode()) {
606
+ console.debug(`ClearcutLogger: No events re-queued (queue size: ${this.events.size})`);
607
+ }
608
+ return;
609
+ }
610
+ // Get the most recent events to re-queue
611
+ const eventsToRequeue = eventsToRetry.slice(eventsToRetry.length - numEventsToRequeue);
612
+ // Prepend events to the front of the deque to be retried first.
613
+ // We iterate backwards to maintain the original order of the failed events.
614
+ for (let i = eventsToRequeue.length - 1; i >= 0; i--) {
615
+ this.events.unshift(eventsToRequeue[i]);
616
+ }
617
+ // Clear any potential overflow
618
+ while (this.events.size > MAX_EVENTS) {
619
+ this.events.pop();
620
+ }
621
+ if (this.config?.getDebugMode()) {
622
+ console.debug(`ClearcutLogger: Re-queued ${numEventsToRequeue} events for retry (queue size: ${this.events.size})`);
623
+ }
517
624
  }
518
625
  }
626
+ export const TEST_ONLY = {
627
+ MAX_RETRY_EVENTS,
628
+ MAX_EVENTS,
629
+ };
519
630
  //# sourceMappingURL=clearcut-logger.js.map