@codemieai/code 0.0.16 → 0.0.18

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 (410) hide show
  1. package/README.md +62 -5
  2. package/bin/agent-executor.js +7 -28
  3. package/bin/codemie-claude.js +18 -0
  4. package/bin/codemie-codex.js +18 -0
  5. package/bin/codemie-deepagents.js +18 -0
  6. package/bin/codemie-gemini.js +18 -0
  7. package/dist/agents/codemie-code/agent.d.ts.map +1 -1
  8. package/dist/agents/codemie-code/agent.js +3 -32
  9. package/dist/agents/codemie-code/agent.js.map +1 -1
  10. package/dist/agents/codemie-code/tools/planning.d.ts +2 -2
  11. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  12. package/dist/agents/core/AgentCLI.js +31 -62
  13. package/dist/agents/core/AgentCLI.js.map +1 -1
  14. package/dist/agents/core/BaseAgentAdapter.d.ts +9 -1
  15. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  16. package/dist/agents/core/BaseAgentAdapter.js +125 -10
  17. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  18. package/dist/agents/core/BaseMetricsAdapter.d.ts +64 -0
  19. package/dist/agents/core/BaseMetricsAdapter.d.ts.map +1 -0
  20. package/dist/agents/core/BaseMetricsAdapter.js +74 -0
  21. package/dist/agents/core/BaseMetricsAdapter.js.map +1 -0
  22. package/dist/agents/core/types.d.ts +1 -0
  23. package/dist/agents/core/types.d.ts.map +1 -1
  24. package/dist/agents/plugins/claude.metrics.d.ts +112 -0
  25. package/dist/agents/plugins/claude.metrics.d.ts.map +1 -0
  26. package/dist/agents/plugins/claude.metrics.js +700 -0
  27. package/dist/agents/plugins/claude.metrics.js.map +1 -0
  28. package/dist/agents/plugins/claude.plugin.d.ts +9 -0
  29. package/dist/agents/plugins/claude.plugin.d.ts.map +1 -1
  30. package/dist/agents/plugins/claude.plugin.js +52 -10
  31. package/dist/agents/plugins/claude.plugin.js.map +1 -1
  32. package/dist/agents/plugins/codemie-code.plugin.d.ts.map +1 -1
  33. package/dist/agents/plugins/codemie-code.plugin.js +57 -13
  34. package/dist/agents/plugins/codemie-code.plugin.js.map +1 -1
  35. package/dist/agents/plugins/codex.plugin.d.ts.map +1 -1
  36. package/dist/agents/plugins/codex.plugin.js +1 -3
  37. package/dist/agents/plugins/codex.plugin.js.map +1 -1
  38. package/dist/agents/plugins/gemini.plugin.d.ts.map +1 -1
  39. package/dist/agents/plugins/gemini.plugin.js +0 -7
  40. package/dist/agents/plugins/gemini.plugin.js.map +1 -1
  41. package/dist/agents/plugins/history-parser.d.ts +52 -0
  42. package/dist/agents/plugins/history-parser.d.ts.map +1 -0
  43. package/dist/agents/plugins/history-parser.js +155 -0
  44. package/dist/agents/plugins/history-parser.js.map +1 -0
  45. package/dist/cli/commands/analytics/aggregator.d.ts +58 -0
  46. package/dist/cli/commands/analytics/aggregator.d.ts.map +1 -0
  47. package/dist/cli/commands/analytics/aggregator.js +702 -0
  48. package/dist/cli/commands/analytics/aggregator.js.map +1 -0
  49. package/dist/cli/commands/analytics/data-loader.d.ts +84 -0
  50. package/dist/cli/commands/analytics/data-loader.d.ts.map +1 -0
  51. package/dist/cli/commands/analytics/data-loader.js +211 -0
  52. package/dist/cli/commands/analytics/data-loader.js.map +1 -0
  53. package/dist/cli/commands/analytics/exporter.d.ts +20 -0
  54. package/dist/cli/commands/analytics/exporter.d.ts.map +1 -0
  55. package/dist/cli/commands/analytics/exporter.js +103 -0
  56. package/dist/cli/commands/analytics/exporter.js.map +1 -0
  57. package/dist/cli/commands/analytics/formatter.d.ts +49 -0
  58. package/dist/cli/commands/analytics/formatter.d.ts.map +1 -0
  59. package/dist/cli/commands/analytics/formatter.js +309 -0
  60. package/dist/cli/commands/analytics/formatter.js.map +1 -0
  61. package/dist/cli/commands/analytics/index.d.ts +6 -0
  62. package/dist/cli/commands/analytics/index.d.ts.map +1 -0
  63. package/dist/cli/commands/analytics/index.js +157 -0
  64. package/dist/cli/commands/analytics/index.js.map +1 -0
  65. package/dist/cli/commands/analytics/model-normalizer.d.ts +21 -0
  66. package/dist/cli/commands/analytics/model-normalizer.d.ts.map +1 -0
  67. package/dist/cli/commands/analytics/model-normalizer.js +44 -0
  68. package/dist/cli/commands/analytics/model-normalizer.js.map +1 -0
  69. package/dist/cli/commands/analytics/types.d.ts +188 -0
  70. package/dist/cli/commands/analytics/types.d.ts.map +1 -0
  71. package/dist/cli/commands/analytics/types.js +6 -0
  72. package/dist/cli/commands/analytics/types.js.map +1 -0
  73. package/dist/cli/commands/doctor/checks/AwsCliCheck.d.ts +9 -0
  74. package/dist/cli/commands/doctor/checks/AwsCliCheck.d.ts.map +1 -0
  75. package/dist/cli/commands/doctor/checks/AwsCliCheck.js +28 -0
  76. package/dist/cli/commands/doctor/checks/AwsCliCheck.js.map +1 -0
  77. package/dist/cli/commands/doctor/checks/PythonCheck.d.ts.map +1 -1
  78. package/dist/cli/commands/doctor/checks/PythonCheck.js +10 -0
  79. package/dist/cli/commands/doctor/checks/PythonCheck.js.map +1 -1
  80. package/dist/cli/commands/doctor/checks/WorkflowsCheck.d.ts.map +1 -1
  81. package/dist/cli/commands/doctor/checks/WorkflowsCheck.js +2 -1
  82. package/dist/cli/commands/doctor/checks/WorkflowsCheck.js.map +1 -1
  83. package/dist/cli/commands/doctor/checks/index.d.ts +1 -0
  84. package/dist/cli/commands/doctor/checks/index.d.ts.map +1 -1
  85. package/dist/cli/commands/doctor/checks/index.js +1 -0
  86. package/dist/cli/commands/doctor/checks/index.js.map +1 -1
  87. package/dist/cli/commands/doctor/index.d.ts.map +1 -1
  88. package/dist/cli/commands/doctor/index.js +75 -3
  89. package/dist/cli/commands/doctor/index.js.map +1 -1
  90. package/dist/cli/commands/profile.d.ts.map +1 -1
  91. package/dist/cli/commands/profile.js +49 -89
  92. package/dist/cli/commands/profile.js.map +1 -1
  93. package/dist/cli/commands/setup.js +1 -21
  94. package/dist/cli/commands/setup.js.map +1 -1
  95. package/dist/cli/index.js +1 -1
  96. package/dist/cli/index.js.map +1 -1
  97. package/dist/env/types.d.ts +14 -2
  98. package/dist/env/types.d.ts.map +1 -1
  99. package/dist/env/types.js.map +1 -1
  100. package/dist/metrics/MetricsOrchestrator.d.ts +67 -0
  101. package/dist/metrics/MetricsOrchestrator.d.ts.map +1 -0
  102. package/dist/metrics/MetricsOrchestrator.js +287 -0
  103. package/dist/metrics/MetricsOrchestrator.js.map +1 -0
  104. package/dist/metrics/config.d.ts +38 -0
  105. package/dist/metrics/config.d.ts.map +1 -0
  106. package/dist/metrics/config.js +80 -0
  107. package/dist/metrics/config.js.map +1 -0
  108. package/dist/metrics/core/DeltaWriter.d.ts +49 -0
  109. package/dist/metrics/core/DeltaWriter.d.ts.map +1 -0
  110. package/dist/metrics/core/DeltaWriter.js +146 -0
  111. package/dist/metrics/core/DeltaWriter.js.map +1 -0
  112. package/dist/metrics/core/FileSnapshotter.d.ts +22 -0
  113. package/dist/metrics/core/FileSnapshotter.d.ts.map +1 -0
  114. package/dist/metrics/core/FileSnapshotter.js +74 -0
  115. package/dist/metrics/core/FileSnapshotter.js.map +1 -0
  116. package/dist/metrics/core/SessionCorrelator.d.ts +34 -0
  117. package/dist/metrics/core/SessionCorrelator.d.ts.map +1 -0
  118. package/dist/metrics/core/SessionCorrelator.js +115 -0
  119. package/dist/metrics/core/SessionCorrelator.js.map +1 -0
  120. package/dist/metrics/core/SyncStateManager.d.ts +69 -0
  121. package/dist/metrics/core/SyncStateManager.d.ts.map +1 -0
  122. package/dist/metrics/core/SyncStateManager.js +284 -0
  123. package/dist/metrics/core/SyncStateManager.js.map +1 -0
  124. package/dist/metrics/index.d.ts +9 -0
  125. package/dist/metrics/index.d.ts.map +1 -0
  126. package/dist/metrics/index.js +11 -0
  127. package/dist/metrics/index.js.map +1 -0
  128. package/dist/metrics/session/SessionStore.d.ts +43 -0
  129. package/dist/metrics/session/SessionStore.d.ts.map +1 -0
  130. package/dist/metrics/session/SessionStore.js +142 -0
  131. package/dist/metrics/session/SessionStore.js.map +1 -0
  132. package/dist/metrics/sync/MetricsApiClient.d.ts +32 -0
  133. package/dist/metrics/sync/MetricsApiClient.d.ts.map +1 -0
  134. package/dist/metrics/sync/MetricsApiClient.js +155 -0
  135. package/dist/metrics/sync/MetricsApiClient.js.map +1 -0
  136. package/dist/metrics/sync/aggregator.d.ts +14 -0
  137. package/dist/metrics/sync/aggregator.d.ts.map +1 -0
  138. package/dist/metrics/sync/aggregator.js +214 -0
  139. package/dist/metrics/sync/aggregator.js.map +1 -0
  140. package/dist/metrics/sync/index.d.ts +10 -0
  141. package/dist/metrics/sync/index.d.ts.map +1 -0
  142. package/dist/metrics/sync/index.js +10 -0
  143. package/dist/metrics/sync/index.js.map +1 -0
  144. package/dist/metrics/sync/jsonl-writer.d.ts +28 -0
  145. package/dist/metrics/sync/jsonl-writer.d.ts.map +1 -0
  146. package/dist/metrics/sync/jsonl-writer.js +72 -0
  147. package/dist/metrics/sync/jsonl-writer.js.map +1 -0
  148. package/dist/metrics/sync/types.d.ts +73 -0
  149. package/dist/metrics/sync/types.d.ts.map +1 -0
  150. package/dist/metrics/sync/types.js +7 -0
  151. package/dist/metrics/sync/types.js.map +1 -0
  152. package/dist/metrics/types.d.ts +308 -0
  153. package/dist/metrics/types.d.ts.map +1 -0
  154. package/dist/metrics/types.js +8 -0
  155. package/dist/metrics/types.js.map +1 -0
  156. package/dist/providers/index.d.ts +2 -0
  157. package/dist/providers/index.d.ts.map +1 -1
  158. package/dist/providers/index.js +2 -0
  159. package/dist/providers/index.js.map +1 -1
  160. package/dist/providers/integration/setup-ui.d.ts +1 -1
  161. package/dist/providers/integration/setup-ui.d.ts.map +1 -1
  162. package/dist/providers/integration/setup-ui.js +51 -6
  163. package/dist/providers/integration/setup-ui.js.map +1 -1
  164. package/dist/providers/plugins/bedrock/bedrock.health.d.ts +53 -0
  165. package/dist/providers/plugins/bedrock/bedrock.health.d.ts.map +1 -0
  166. package/dist/providers/plugins/bedrock/bedrock.health.js +115 -0
  167. package/dist/providers/plugins/bedrock/bedrock.health.js.map +1 -0
  168. package/dist/providers/plugins/bedrock/bedrock.models.d.ts +26 -0
  169. package/dist/providers/plugins/bedrock/bedrock.models.d.ts.map +1 -0
  170. package/dist/providers/plugins/bedrock/bedrock.models.js +89 -0
  171. package/dist/providers/plugins/bedrock/bedrock.models.js.map +1 -0
  172. package/dist/providers/plugins/bedrock/bedrock.setup-steps.d.ts +12 -0
  173. package/dist/providers/plugins/bedrock/bedrock.setup-steps.d.ts.map +1 -0
  174. package/dist/providers/plugins/bedrock/bedrock.setup-steps.js +308 -0
  175. package/dist/providers/plugins/bedrock/bedrock.setup-steps.js.map +1 -0
  176. package/dist/providers/plugins/bedrock/bedrock.template.d.ts +11 -0
  177. package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -0
  178. package/dist/providers/plugins/bedrock/bedrock.template.js +85 -0
  179. package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -0
  180. package/dist/providers/plugins/bedrock/index.d.ts +11 -0
  181. package/dist/providers/plugins/bedrock/index.d.ts.map +1 -0
  182. package/dist/providers/plugins/bedrock/index.js +11 -0
  183. package/dist/providers/plugins/bedrock/index.js.map +1 -0
  184. package/dist/providers/plugins/ollama/ollama.template.d.ts.map +1 -1
  185. package/dist/providers/plugins/ollama/ollama.template.js +2 -0
  186. package/dist/providers/plugins/ollama/ollama.template.js.map +1 -1
  187. package/dist/providers/plugins/sso/sso.http-client.d.ts +2 -0
  188. package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -1
  189. package/dist/providers/plugins/sso/sso.http-client.js +9 -3
  190. package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
  191. package/dist/proxy/http-client.d.ts +1 -1
  192. package/dist/proxy/http-client.d.ts.map +1 -1
  193. package/dist/proxy/http-client.js +78 -12
  194. package/dist/proxy/http-client.js.map +1 -1
  195. package/dist/proxy/plugins/endpoint-blocker.plugin.d.ts +19 -0
  196. package/dist/proxy/plugins/endpoint-blocker.plugin.d.ts.map +1 -0
  197. package/dist/proxy/plugins/endpoint-blocker.plugin.js +61 -0
  198. package/dist/proxy/plugins/endpoint-blocker.plugin.js.map +1 -0
  199. package/dist/proxy/plugins/header-injection.plugin.js +3 -0
  200. package/dist/proxy/plugins/header-injection.plugin.js.map +1 -1
  201. package/dist/proxy/plugins/index.d.ts +3 -1
  202. package/dist/proxy/plugins/index.d.ts.map +1 -1
  203. package/dist/proxy/plugins/index.js +5 -1
  204. package/dist/proxy/plugins/index.js.map +1 -1
  205. package/dist/proxy/plugins/logging.plugin.d.ts +11 -3
  206. package/dist/proxy/plugins/logging.plugin.d.ts.map +1 -1
  207. package/dist/proxy/plugins/logging.plugin.js +189 -25
  208. package/dist/proxy/plugins/logging.plugin.js.map +1 -1
  209. package/dist/proxy/plugins/metrics-sync.plugin.d.ts +33 -0
  210. package/dist/proxy/plugins/metrics-sync.plugin.d.ts.map +1 -0
  211. package/dist/proxy/plugins/metrics-sync.plugin.js +320 -0
  212. package/dist/proxy/plugins/metrics-sync.plugin.js.map +1 -0
  213. package/dist/proxy/plugins/registry.d.ts.map +1 -1
  214. package/dist/proxy/plugins/registry.js +8 -1
  215. package/dist/proxy/plugins/registry.js.map +1 -1
  216. package/dist/proxy/plugins/types.d.ts +6 -2
  217. package/dist/proxy/plugins/types.d.ts.map +1 -1
  218. package/dist/proxy/types.d.ts +8 -1
  219. package/dist/proxy/types.d.ts.map +1 -1
  220. package/dist/utils/ascii-logo.d.ts +21 -0
  221. package/dist/utils/ascii-logo.d.ts.map +1 -0
  222. package/dist/utils/ascii-logo.js +85 -0
  223. package/dist/utils/ascii-logo.js.map +1 -0
  224. package/dist/utils/codemie-proxy.d.ts +2 -7
  225. package/dist/utils/codemie-proxy.d.ts.map +1 -1
  226. package/dist/utils/codemie-proxy.js +83 -61
  227. package/dist/utils/codemie-proxy.js.map +1 -1
  228. package/dist/utils/config-loader.d.ts.map +1 -1
  229. package/dist/utils/config-loader.js +22 -6
  230. package/dist/utils/config-loader.js.map +1 -1
  231. package/dist/utils/exec.d.ts +11 -0
  232. package/dist/utils/exec.d.ts.map +1 -1
  233. package/dist/utils/exec.js +17 -1
  234. package/dist/utils/exec.js.map +1 -1
  235. package/dist/utils/goodbye-messages.d.ts +13 -0
  236. package/dist/utils/goodbye-messages.d.ts.map +1 -0
  237. package/dist/utils/goodbye-messages.js +245 -0
  238. package/dist/utils/goodbye-messages.js.map +1 -0
  239. package/dist/utils/json-parser.d.ts +52 -0
  240. package/dist/utils/json-parser.d.ts.map +1 -0
  241. package/dist/utils/json-parser.js +126 -0
  242. package/dist/utils/json-parser.js.map +1 -0
  243. package/dist/utils/logger.d.ts +37 -1
  244. package/dist/utils/logger.d.ts.map +1 -1
  245. package/dist/utils/logger.js +92 -20
  246. package/dist/utils/logger.js.map +1 -1
  247. package/dist/utils/sanitize.d.ts.map +1 -1
  248. package/dist/utils/sanitize.js +0 -1
  249. package/dist/utils/sanitize.js.map +1 -1
  250. package/dist/utils/which.d.ts +20 -0
  251. package/dist/utils/which.d.ts.map +1 -0
  252. package/dist/utils/which.js +47 -0
  253. package/dist/utils/which.js.map +1 -0
  254. package/package.json +10 -5
  255. package/dist/analytics/aggregation/adapters/claude.adapter.d.ts +0 -37
  256. package/dist/analytics/aggregation/adapters/claude.adapter.d.ts.map +0 -1
  257. package/dist/analytics/aggregation/adapters/claude.adapter.js +0 -531
  258. package/dist/analytics/aggregation/adapters/claude.adapter.js.map +0 -1
  259. package/dist/analytics/aggregation/adapters/codex.adapter.d.ts +0 -25
  260. package/dist/analytics/aggregation/adapters/codex.adapter.d.ts.map +0 -1
  261. package/dist/analytics/aggregation/adapters/codex.adapter.js +0 -396
  262. package/dist/analytics/aggregation/adapters/codex.adapter.js.map +0 -1
  263. package/dist/analytics/aggregation/adapters/gemini.adapter.d.ts +0 -36
  264. package/dist/analytics/aggregation/adapters/gemini.adapter.d.ts.map +0 -1
  265. package/dist/analytics/aggregation/adapters/gemini.adapter.js +0 -365
  266. package/dist/analytics/aggregation/adapters/gemini.adapter.js.map +0 -1
  267. package/dist/analytics/aggregation/adapters/index.d.ts +0 -7
  268. package/dist/analytics/aggregation/adapters/index.d.ts.map +0 -1
  269. package/dist/analytics/aggregation/adapters/index.js +0 -7
  270. package/dist/analytics/aggregation/adapters/index.js.map +0 -1
  271. package/dist/analytics/aggregation/aggregator.d.ts +0 -49
  272. package/dist/analytics/aggregation/aggregator.d.ts.map +0 -1
  273. package/dist/analytics/aggregation/aggregator.js +0 -239
  274. package/dist/analytics/aggregation/aggregator.js.map +0 -1
  275. package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.d.ts +0 -99
  276. package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.d.ts.map +0 -1
  277. package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.js +0 -110
  278. package/dist/analytics/aggregation/core/BaseAnalyticsAdapter.js.map +0 -1
  279. package/dist/analytics/aggregation/core/adapter.interface.d.ts +0 -76
  280. package/dist/analytics/aggregation/core/adapter.interface.d.ts.map +0 -1
  281. package/dist/analytics/aggregation/core/adapter.interface.js +0 -9
  282. package/dist/analytics/aggregation/core/adapter.interface.js.map +0 -1
  283. package/dist/analytics/aggregation/core/aggregation-utils.d.ts +0 -86
  284. package/dist/analytics/aggregation/core/aggregation-utils.d.ts.map +0 -1
  285. package/dist/analytics/aggregation/core/aggregation-utils.js +0 -126
  286. package/dist/analytics/aggregation/core/aggregation-utils.js.map +0 -1
  287. package/dist/analytics/aggregation/core/discovery.d.ts +0 -40
  288. package/dist/analytics/aggregation/core/discovery.d.ts.map +0 -1
  289. package/dist/analytics/aggregation/core/discovery.js +0 -132
  290. package/dist/analytics/aggregation/core/discovery.js.map +0 -1
  291. package/dist/analytics/aggregation/core/file-utils.d.ts +0 -24
  292. package/dist/analytics/aggregation/core/file-utils.d.ts.map +0 -1
  293. package/dist/analytics/aggregation/core/file-utils.js +0 -143
  294. package/dist/analytics/aggregation/core/file-utils.js.map +0 -1
  295. package/dist/analytics/aggregation/core/index.d.ts +0 -14
  296. package/dist/analytics/aggregation/core/index.d.ts.map +0 -1
  297. package/dist/analytics/aggregation/core/index.js +0 -14
  298. package/dist/analytics/aggregation/core/index.js.map +0 -1
  299. package/dist/analytics/aggregation/core/project-mapping.d.ts +0 -50
  300. package/dist/analytics/aggregation/core/project-mapping.d.ts.map +0 -1
  301. package/dist/analytics/aggregation/core/project-mapping.js +0 -102
  302. package/dist/analytics/aggregation/core/project-mapping.js.map +0 -1
  303. package/dist/analytics/aggregation/core/streaming.d.ts +0 -26
  304. package/dist/analytics/aggregation/core/streaming.d.ts.map +0 -1
  305. package/dist/analytics/aggregation/core/streaming.js +0 -58
  306. package/dist/analytics/aggregation/core/streaming.js.map +0 -1
  307. package/dist/analytics/aggregation/core/user-prompt-source.d.ts +0 -81
  308. package/dist/analytics/aggregation/core/user-prompt-source.d.ts.map +0 -1
  309. package/dist/analytics/aggregation/core/user-prompt-source.js +0 -69
  310. package/dist/analytics/aggregation/core/user-prompt-source.js.map +0 -1
  311. package/dist/analytics/aggregation/core/user-prompt-sources/json.d.ts +0 -49
  312. package/dist/analytics/aggregation/core/user-prompt-sources/json.d.ts.map +0 -1
  313. package/dist/analytics/aggregation/core/user-prompt-sources/json.js +0 -66
  314. package/dist/analytics/aggregation/core/user-prompt-sources/json.js.map +0 -1
  315. package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.d.ts +0 -43
  316. package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.d.ts.map +0 -1
  317. package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.js +0 -56
  318. package/dist/analytics/aggregation/core/user-prompt-sources/jsonl.js.map +0 -1
  319. package/dist/analytics/aggregation/index.d.ts +0 -8
  320. package/dist/analytics/aggregation/index.d.ts.map +0 -1
  321. package/dist/analytics/aggregation/index.js +0 -8
  322. package/dist/analytics/aggregation/index.js.map +0 -1
  323. package/dist/analytics/aggregation/types.d.ts +0 -278
  324. package/dist/analytics/aggregation/types.d.ts.map +0 -1
  325. package/dist/analytics/aggregation/types.js +0 -8
  326. package/dist/analytics/aggregation/types.js.map +0 -1
  327. package/dist/analytics/collector.d.ts +0 -46
  328. package/dist/analytics/collector.d.ts.map +0 -1
  329. package/dist/analytics/collector.js +0 -83
  330. package/dist/analytics/collector.js.map +0 -1
  331. package/dist/analytics/config.d.ts +0 -15
  332. package/dist/analytics/config.d.ts.map +0 -1
  333. package/dist/analytics/config.js +0 -65
  334. package/dist/analytics/config.js.map +0 -1
  335. package/dist/analytics/index.d.ts +0 -99
  336. package/dist/analytics/index.d.ts.map +0 -1
  337. package/dist/analytics/index.js +0 -280
  338. package/dist/analytics/index.js.map +0 -1
  339. package/dist/analytics/plugins/api-metrics.plugin.d.ts +0 -26
  340. package/dist/analytics/plugins/api-metrics.plugin.d.ts.map +0 -1
  341. package/dist/analytics/plugins/api-metrics.plugin.js +0 -97
  342. package/dist/analytics/plugins/api-metrics.plugin.js.map +0 -1
  343. package/dist/analytics/plugins/index.d.ts +0 -15
  344. package/dist/analytics/plugins/index.d.ts.map +0 -1
  345. package/dist/analytics/plugins/index.js +0 -15
  346. package/dist/analytics/plugins/index.js.map +0 -1
  347. package/dist/analytics/plugins/model-metrics.plugin.d.ts +0 -39
  348. package/dist/analytics/plugins/model-metrics.plugin.d.ts.map +0 -1
  349. package/dist/analytics/plugins/model-metrics.plugin.js +0 -105
  350. package/dist/analytics/plugins/model-metrics.plugin.js.map +0 -1
  351. package/dist/analytics/plugins/provider-metrics.plugin.d.ts +0 -41
  352. package/dist/analytics/plugins/provider-metrics.plugin.d.ts.map +0 -1
  353. package/dist/analytics/plugins/provider-metrics.plugin.js +0 -123
  354. package/dist/analytics/plugins/provider-metrics.plugin.js.map +0 -1
  355. package/dist/analytics/plugins/types.d.ts +0 -61
  356. package/dist/analytics/plugins/types.d.ts.map +0 -1
  357. package/dist/analytics/plugins/types.js +0 -54
  358. package/dist/analytics/plugins/types.js.map +0 -1
  359. package/dist/analytics/privacy.d.ts +0 -10
  360. package/dist/analytics/privacy.d.ts.map +0 -1
  361. package/dist/analytics/privacy.js +0 -20
  362. package/dist/analytics/privacy.js.map +0 -1
  363. package/dist/analytics/remote-submission/cursor-manager.d.ts +0 -71
  364. package/dist/analytics/remote-submission/cursor-manager.d.ts.map +0 -1
  365. package/dist/analytics/remote-submission/cursor-manager.js +0 -204
  366. package/dist/analytics/remote-submission/cursor-manager.js.map +0 -1
  367. package/dist/analytics/remote-submission/index.d.ts +0 -12
  368. package/dist/analytics/remote-submission/index.d.ts.map +0 -1
  369. package/dist/analytics/remote-submission/index.js +0 -11
  370. package/dist/analytics/remote-submission/index.js.map +0 -1
  371. package/dist/analytics/remote-submission/lock-manager.d.ts +0 -71
  372. package/dist/analytics/remote-submission/lock-manager.d.ts.map +0 -1
  373. package/dist/analytics/remote-submission/lock-manager.js +0 -238
  374. package/dist/analytics/remote-submission/lock-manager.js.map +0 -1
  375. package/dist/analytics/remote-submission/metric-transformer.d.ts +0 -21
  376. package/dist/analytics/remote-submission/metric-transformer.d.ts.map +0 -1
  377. package/dist/analytics/remote-submission/metric-transformer.js +0 -82
  378. package/dist/analytics/remote-submission/metric-transformer.js.map +0 -1
  379. package/dist/analytics/remote-submission/submitter.d.ts +0 -79
  380. package/dist/analytics/remote-submission/submitter.d.ts.map +0 -1
  381. package/dist/analytics/remote-submission/submitter.js +0 -362
  382. package/dist/analytics/remote-submission/submitter.js.map +0 -1
  383. package/dist/analytics/remote-submission/types.d.ts +0 -123
  384. package/dist/analytics/remote-submission/types.d.ts.map +0 -1
  385. package/dist/analytics/remote-submission/types.js +0 -13
  386. package/dist/analytics/remote-submission/types.js.map +0 -1
  387. package/dist/analytics/session.d.ts +0 -56
  388. package/dist/analytics/session.d.ts.map +0 -1
  389. package/dist/analytics/session.js +0 -95
  390. package/dist/analytics/session.js.map +0 -1
  391. package/dist/analytics/types.d.ts +0 -104
  392. package/dist/analytics/types.d.ts.map +0 -1
  393. package/dist/analytics/types.js +0 -15
  394. package/dist/analytics/types.js.map +0 -1
  395. package/dist/analytics/writer.d.ts +0 -18
  396. package/dist/analytics/writer.d.ts.map +0 -1
  397. package/dist/analytics/writer.js +0 -44
  398. package/dist/analytics/writer.js.map +0 -1
  399. package/dist/cli/commands/analytics.d.ts +0 -3
  400. package/dist/cli/commands/analytics.d.ts.map +0 -1
  401. package/dist/cli/commands/analytics.js +0 -748
  402. package/dist/cli/commands/analytics.js.map +0 -1
  403. package/dist/utils/analytics-reader.d.ts +0 -117
  404. package/dist/utils/analytics-reader.d.ts.map +0 -1
  405. package/dist/utils/analytics-reader.js +0 -421
  406. package/dist/utils/analytics-reader.js.map +0 -1
  407. package/dist/utils/date-formatter.d.ts +0 -88
  408. package/dist/utils/date-formatter.d.ts.map +0 -1
  409. package/dist/utils/date-formatter.js +0 -133
  410. package/dist/utils/date-formatter.js.map +0 -1
@@ -1,11 +1,19 @@
1
1
  /**
2
- * Logging Plugin - Request/Response Logging to Log Files
2
+ * Logging Plugin - Request/Response Logging
3
3
  * Priority: 50 (runs before analytics)
4
4
  *
5
- * Purpose: Logs detailed proxy request/response information to log files
5
+ * Purpose: Logs detailed proxy request/response information with smart content handling
6
6
  * Separates operational logging from analytics metrics
7
7
  *
8
- * Log Level: INFO (file-only, no console output)
8
+ * Logs:
9
+ * - Request: method, URL, content-type, headers, body (parsed JSON or raw)
10
+ * - Response: status, content-type, headers, body (smart handling based on type)
11
+ * - JSON: Parsed and structured
12
+ * - SSE (Server-Sent Events): First/last events + stats (avoids logging full stream)
13
+ * - Other: Raw content (truncated if > 1000 bytes)
14
+ * - Streaming: chunk count, bytes transferred, streaming detection
15
+ *
16
+ * Log Level: DEBUG (file + console when CODEMIE_DEBUG=1)
9
17
  * Log Location: ~/.codemie/logs/debug-YYYY-MM-DD.log
10
18
  *
11
19
  * SOLID: Single responsibility = log proxy activity
@@ -23,15 +31,49 @@ export class LoggingPlugin {
23
31
  }
24
32
  class LoggingInterceptor {
25
33
  name = 'logging';
34
+ chunkCount = 0;
35
+ totalBytes = 0;
36
+ responseChunks = [];
37
+ responseContentType = null;
26
38
  async onRequest(context) {
27
39
  try {
28
- logger.info(`[proxy-request] ${context.method} ${context.url}`, {
40
+ // Reset counters for new request
41
+ this.chunkCount = 0;
42
+ this.totalBytes = 0;
43
+ this.responseChunks = [];
44
+ this.responseContentType = null;
45
+ // Get request content type
46
+ const contentType = context.headers['content-type'] || context.headers['Content-Type'] || 'unknown';
47
+ // Parse request body based on content type
48
+ let requestBodyParsed = null;
49
+ if (context.requestBody) {
50
+ try {
51
+ const bodyString = context.requestBody.toString('utf-8');
52
+ if (contentType.includes('application/json')) {
53
+ requestBodyParsed = JSON.parse(bodyString);
54
+ }
55
+ else {
56
+ // Log raw for non-JSON
57
+ requestBodyParsed = bodyString;
58
+ }
59
+ }
60
+ catch {
61
+ // Parse error - log as string
62
+ requestBodyParsed = context.requestBody.toString('utf-8');
63
+ }
64
+ }
65
+ logger.debug(`[proxy-request] ${context.method} ${context.url}`, {
29
66
  requestId: context.requestId,
30
67
  sessionId: context.sessionId,
31
68
  agent: context.agentName,
69
+ profile: context.profile,
70
+ provider: context.provider,
71
+ model: context.model,
32
72
  targetUrl: context.targetUrl,
73
+ contentType,
33
74
  bodySize: context.requestBody?.length || 0,
34
- headers: this.sanitizeHeaders(context.headers)
75
+ headers: this.sanitizeHeaders(context.headers),
76
+ requestBody: requestBodyParsed
35
77
  });
36
78
  }
37
79
  catch (error) {
@@ -39,14 +81,137 @@ class LoggingInterceptor {
39
81
  logger.error(`[${this.name}] Error logging request:`, error);
40
82
  }
41
83
  }
42
- async onResponseComplete(context, metadata) {
84
+ async onResponseHeaders(context, headers) {
43
85
  try {
44
- logger.info(`[proxy-response] ${metadata.statusCode} ${context.url} (${metadata.durationMs}ms)`, {
86
+ // Capture response content type for use in response body logging
87
+ const contentTypeHeader = headers['content-type'] || headers['Content-Type'];
88
+ this.responseContentType = Array.isArray(contentTypeHeader)
89
+ ? contentTypeHeader[0]
90
+ : contentTypeHeader || 'unknown';
91
+ logger.debug(`[proxy-response-headers] ${context.url}`, {
45
92
  requestId: context.requestId,
46
- statusCode: metadata.statusCode,
47
- statusMessage: metadata.statusMessage,
48
- bytesSent: metadata.bytesSent,
49
- durationMs: metadata.durationMs
93
+ sessionId: context.sessionId,
94
+ agent: context.agentName,
95
+ profile: context.profile,
96
+ provider: context.provider,
97
+ model: context.model,
98
+ headers: {
99
+ 'content-type': this.responseContentType,
100
+ 'content-length': headers['content-length'],
101
+ 'transfer-encoding': headers['transfer-encoding']
102
+ }
103
+ });
104
+ }
105
+ catch (error) {
106
+ logger.error(`[${this.name}] Error logging response headers:`, error);
107
+ }
108
+ }
109
+ async onResponseChunk(context, chunk) {
110
+ try {
111
+ this.chunkCount++;
112
+ this.totalBytes += chunk.length;
113
+ // Collect chunks for full response body
114
+ this.responseChunks.push(Buffer.from(chunk));
115
+ // Log every 1000th chunk to avoid spam (or first/last chunks)
116
+ if (this.chunkCount === 1 || this.chunkCount % 1000 === 0) {
117
+ logger.debug(`[proxy-streaming] ${context.url}`, {
118
+ requestId: context.requestId,
119
+ sessionId: context.sessionId,
120
+ chunkNumber: this.chunkCount,
121
+ chunkSize: chunk.length,
122
+ totalBytes: this.totalBytes
123
+ });
124
+ }
125
+ }
126
+ catch (error) {
127
+ logger.error(`[${this.name}] Error logging chunk:`, error);
128
+ }
129
+ return chunk;
130
+ }
131
+ async onResponseComplete(context, metadata) {
132
+ try {
133
+ // Capture chunks for logging (use local reference to avoid race conditions)
134
+ const chunksToLog = this.responseChunks;
135
+ const chunkCount = this.chunkCount;
136
+ const totalBytes = this.totalBytes;
137
+ const contentType = this.responseContentType || 'unknown';
138
+ // CRITICAL: Clear state immediately for next request
139
+ this.responseChunks = [];
140
+ this.chunkCount = 0;
141
+ this.totalBytes = 0;
142
+ this.responseContentType = null;
143
+ // Process response body asynchronously (don't block)
144
+ // Use setImmediate to defer heavy work to next tick
145
+ setImmediate(() => {
146
+ try {
147
+ let responseBodyParsed = null;
148
+ let isStreaming = false;
149
+ if (chunksToLog.length > 0) {
150
+ const fullBody = Buffer.concat(chunksToLog).toString('utf-8');
151
+ // Check if this is a streaming response (SSE)
152
+ isStreaming = contentType.includes('text/event-stream') || fullBody.startsWith('event:');
153
+ if (isStreaming) {
154
+ // For streaming responses, log first and last few events instead of full body
155
+ const lines = fullBody.split('\n').filter(line => line.trim());
156
+ const eventCount = lines.filter(line => line.startsWith('event:')).length;
157
+ responseBodyParsed = {
158
+ type: 'text/event-stream',
159
+ eventCount,
160
+ firstEvents: lines.slice(0, 10).join('\n'),
161
+ lastEvents: lines.slice(-10).join('\n'),
162
+ totalLines: lines.length,
163
+ bodySizeBytes: fullBody.length
164
+ };
165
+ }
166
+ else if (contentType.includes('application/json')) {
167
+ // Parse JSON responses
168
+ try {
169
+ responseBodyParsed = JSON.parse(fullBody);
170
+ }
171
+ catch {
172
+ // Invalid JSON - log as string
173
+ responseBodyParsed = fullBody;
174
+ }
175
+ }
176
+ else {
177
+ // Log raw for other content types (truncate if too long)
178
+ responseBodyParsed = fullBody.length > 1000
179
+ ? fullBody.substring(0, 1000) + '... (truncated)'
180
+ : fullBody;
181
+ }
182
+ }
183
+ logger.debug(`[proxy-response] ${metadata.statusCode} ${context.url} (${metadata.durationMs}ms)`, {
184
+ requestId: context.requestId,
185
+ sessionId: context.sessionId,
186
+ agent: context.agentName,
187
+ profile: context.profile,
188
+ provider: context.provider,
189
+ model: context.model,
190
+ statusCode: metadata.statusCode,
191
+ statusMessage: metadata.statusMessage,
192
+ contentType,
193
+ isStreaming,
194
+ bytesSent: metadata.bytesSent,
195
+ durationMs: metadata.durationMs,
196
+ totalChunks: chunkCount,
197
+ totalBytesStreamed: totalBytes,
198
+ responseBody: responseBodyParsed
199
+ });
200
+ // Log completion marker to track if we reach this point
201
+ logger.debug(`[proxy-complete] Request fully processed for ${context.url}`, {
202
+ requestId: context.requestId,
203
+ sessionId: context.sessionId,
204
+ agent: context.agentName,
205
+ profile: context.profile,
206
+ provider: context.provider,
207
+ model: context.model,
208
+ finalStatus: 'success'
209
+ });
210
+ }
211
+ catch (error) {
212
+ // Don't break proxy flow on logging errors
213
+ logger.error(`[${this.name}] Error logging response (deferred):`, error);
214
+ }
50
215
  });
51
216
  }
52
217
  catch (error) {
@@ -56,10 +221,16 @@ class LoggingInterceptor {
56
221
  }
57
222
  async onError(context, error) {
58
223
  try {
59
- logger.info(`[proxy-error] ${error.name}: ${error.message}`, {
224
+ logger.debug(`[proxy-error] ${error.name}: ${error.message}`, {
60
225
  requestId: context.requestId,
226
+ sessionId: context.sessionId,
227
+ agent: context.agentName,
228
+ profile: context.profile,
229
+ provider: context.provider,
230
+ model: context.model,
61
231
  url: context.url,
62
232
  errorType: error.name,
233
+ errorMessage: error.message,
63
234
  errorStack: error.stack
64
235
  });
65
236
  }
@@ -69,24 +240,17 @@ class LoggingInterceptor {
69
240
  }
70
241
  }
71
242
  /**
72
- * Sanitize headers to remove sensitive data
243
+ * Filter headers to only include X-Codemie headers
73
244
  */
74
245
  sanitizeHeaders(headers) {
75
- const sanitized = {};
246
+ const filtered = {};
76
247
  for (const [key, value] of Object.entries(headers)) {
77
- const lowerKey = key.toLowerCase();
78
- // Mask sensitive headers
79
- if (lowerKey.includes('authorization') ||
80
- lowerKey.includes('api-key') ||
81
- lowerKey.includes('token') ||
82
- lowerKey.includes('cookie')) {
83
- sanitized[key] = '[REDACTED]';
84
- }
85
- else {
86
- sanitized[key] = value;
248
+ // Only include X-Codemie headers
249
+ if (key.toLowerCase().startsWith('x-codemie')) {
250
+ filtered[key] = value;
87
251
  }
88
252
  }
89
- return sanitized;
253
+ return filtered;
90
254
  }
91
255
  }
92
256
  //# sourceMappingURL=logging.plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logging.plugin.js","sourceRoot":"","sources":["../../../src/proxy/plugins/logging.plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logging.plugin.js","sourceRoot":"","sources":["../../../src/proxy/plugins/logging.plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Metrics Sync Plugin
3
+ * Priority: 100 (runs after logging plugin)
4
+ *
5
+ * Purpose: Syncs metrics to CodeMie API in background
6
+ * - Runs only in SSO mode (ai-run-sso provider)
7
+ * - Background timer (every 5 minutes)
8
+ * - Aggregates pending deltas into single metric
9
+ * - Marks deltas as synced in JSONL
10
+ * - Final sync on proxy shutdown
11
+ *
12
+ * SOLID: Single responsibility = sync metrics
13
+ * KISS: Simple timer-based sync
14
+ */
15
+ import { ProxyPlugin, PluginContext, ProxyInterceptor } from './types.js';
16
+ export declare class MetricsSyncPlugin implements ProxyPlugin {
17
+ id: string;
18
+ name: string;
19
+ version: string;
20
+ priority: number;
21
+ createInterceptor(context: PluginContext): Promise<ProxyInterceptor>;
22
+ /**
23
+ * Check if metrics sync is enabled
24
+ * Priority: ENV > Profile config > Default (true)
25
+ */
26
+ private isSyncEnabled;
27
+ /**
28
+ * Check if dry-run mode is enabled
29
+ * Priority: ENV > Profile config > Default (false)
30
+ */
31
+ private isDryRunEnabled;
32
+ }
33
+ //# sourceMappingURL=metrics-sync.plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-sync.plugin.d.ts","sourceRoot":"","sources":["../../../src/proxy/plugins/metrics-sync.plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAQ1E,qBAAa,iBAAkB,YAAW,WAAW;IACnD,EAAE,SAAiC;IACnC,IAAI,SAAkB;IACtB,OAAO,SAAW;IAClB,QAAQ,SAAO;IAET,iBAAiB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkC1E;;;OAGG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;OAGG;IACH,OAAO,CAAC,eAAe;CAexB"}
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Metrics Sync Plugin
3
+ * Priority: 100 (runs after logging plugin)
4
+ *
5
+ * Purpose: Syncs metrics to CodeMie API in background
6
+ * - Runs only in SSO mode (ai-run-sso provider)
7
+ * - Background timer (every 5 minutes)
8
+ * - Aggregates pending deltas into single metric
9
+ * - Marks deltas as synced in JSONL
10
+ * - Final sync on proxy shutdown
11
+ *
12
+ * SOLID: Single responsibility = sync metrics
13
+ * KISS: Simple timer-based sync
14
+ */
15
+ import { logger } from '../../utils/logger.js';
16
+ import { MetricsApiClient } from '../../metrics/sync/MetricsApiClient.js';
17
+ import { readJSONL, writeJSONLAtomic } from '../../metrics/sync/jsonl-writer.js';
18
+ import { aggregateDeltas } from '../../metrics/sync/aggregator.js';
19
+ import { SessionStore } from '../../metrics/session/SessionStore.js';
20
+ import { getSessionMetricsPath } from '../../metrics/config.js';
21
+ export class MetricsSyncPlugin {
22
+ id = '@codemie/proxy-metrics-sync';
23
+ name = 'Metrics Sync';
24
+ version = '1.0.0';
25
+ priority = 100; // Run after logging (priority 50)
26
+ async createInterceptor(context) {
27
+ // Only create interceptor if we have necessary context
28
+ if (!context.config.sessionId) {
29
+ logger.debug('[MetricsSyncPlugin] Skipping: Session ID not available');
30
+ throw new Error('Session ID not available (metrics sync disabled)');
31
+ }
32
+ if (!context.credentials) {
33
+ logger.debug('[MetricsSyncPlugin] Skipping: SSO credentials not available');
34
+ throw new Error('SSO credentials not available (metrics sync disabled)');
35
+ }
36
+ // Check if metrics sync is enabled (from config or env var)
37
+ const syncEnabled = this.isSyncEnabled(context);
38
+ if (!syncEnabled) {
39
+ logger.debug('[MetricsSyncPlugin] Skipping: Metrics sync disabled by configuration');
40
+ throw new Error('Metrics sync disabled by configuration');
41
+ }
42
+ logger.info('[MetricsSyncPlugin] Initializing metrics sync');
43
+ // Check if dry-run mode is enabled
44
+ const dryRun = this.isDryRunEnabled(context);
45
+ return new MetricsSyncInterceptor(context.config.sessionId, context.config.targetApiUrl, context.credentials.cookies, context.config.clientType, context.config.version, dryRun);
46
+ }
47
+ /**
48
+ * Check if metrics sync is enabled
49
+ * Priority: ENV > Profile config > Default (true)
50
+ */
51
+ isSyncEnabled(context) {
52
+ // Check environment variable first
53
+ const envEnabled = process.env.CODEMIE_METRICS_SYNC_ENABLED;
54
+ if (envEnabled !== undefined) {
55
+ return envEnabled === 'true' || envEnabled === '1';
56
+ }
57
+ // Check profile config (if available)
58
+ if (context.profileConfig?.metrics?.sync?.enabled !== undefined) {
59
+ return context.profileConfig.metrics.sync.enabled;
60
+ }
61
+ // Default to enabled for SSO mode
62
+ return true;
63
+ }
64
+ /**
65
+ * Check if dry-run mode is enabled
66
+ * Priority: ENV > Profile config > Default (false)
67
+ */
68
+ isDryRunEnabled(context) {
69
+ // Check environment variable first
70
+ const envDryRun = process.env.CODEMIE_METRICS_DRY_RUN;
71
+ if (envDryRun !== undefined) {
72
+ return envDryRun === 'true' || envDryRun === '1';
73
+ }
74
+ // Check profile config (if available)
75
+ if (context.profileConfig?.metrics?.sync?.dryRun !== undefined) {
76
+ return context.profileConfig.metrics.sync.dryRun;
77
+ }
78
+ // Default to disabled
79
+ return false;
80
+ }
81
+ }
82
+ class MetricsSyncInterceptor {
83
+ sessionId;
84
+ name = 'metrics-sync';
85
+ syncTimer;
86
+ sessionStore = new SessionStore();
87
+ apiClient;
88
+ syncInterval;
89
+ isSyncing = false;
90
+ version;
91
+ dryRun;
92
+ constructor(sessionId, baseUrl, cookies, clientType, version, dryRun = false) {
93
+ this.sessionId = sessionId;
94
+ // Get version from proxy config (passed from AgentCLI)
95
+ this.version = version || '0.0.0';
96
+ // Set dry-run mode (passed from plugin)
97
+ this.dryRun = dryRun;
98
+ if (this.dryRun) {
99
+ logger.info('[metrics-sync] Dry-run mode enabled - metrics will be logged but not sent');
100
+ }
101
+ // Build cookie header
102
+ const cookieHeader = Object.entries(cookies)
103
+ .map(([key, value]) => `${key}=${value}`)
104
+ .join('; ');
105
+ this.apiClient = new MetricsApiClient({
106
+ baseUrl,
107
+ cookies: cookieHeader,
108
+ timeout: 30000,
109
+ retryAttempts: 3,
110
+ version: this.version,
111
+ clientType: clientType || 'codemie-cli'
112
+ });
113
+ // Get sync interval from env or default to 5 minutes
114
+ this.syncInterval = Number.parseInt(process.env.CODEMIE_METRICS_SYNC_INTERVAL || '300000', 10);
115
+ }
116
+ /**
117
+ * Called when proxy starts - initialize background timer
118
+ */
119
+ async onProxyStart() {
120
+ logger.info(`[${this.name}] Starting metrics sync (interval: ${this.syncInterval}ms)`);
121
+ // Start background timer
122
+ this.syncTimer = setInterval(() => {
123
+ this.syncMetrics().catch(error => {
124
+ logger.error(`[${this.name}] Sync failed:`, error);
125
+ });
126
+ }, this.syncInterval);
127
+ logger.debug(`[${this.name}] Background timer started`);
128
+ }
129
+ /**
130
+ * Called when proxy stops - cleanup and final sync
131
+ */
132
+ async onProxyStop() {
133
+ logger.info(`[${this.name}] Stopping metrics sync`);
134
+ // Stop timer
135
+ if (this.syncTimer) {
136
+ clearInterval(this.syncTimer);
137
+ this.syncTimer = undefined;
138
+ }
139
+ // Final sync (ensure all pending metrics are sent)
140
+ try {
141
+ await this.syncMetrics();
142
+ logger.info(`[${this.name}] Final sync completed`);
143
+ }
144
+ catch (error) {
145
+ logger.error(`[${this.name}] Final sync failed:`, error);
146
+ }
147
+ }
148
+ /**
149
+ * Sync metrics to API
150
+ */
151
+ async syncMetrics() {
152
+ // Skip if already syncing (prevent concurrent syncs)
153
+ if (this.isSyncing) {
154
+ logger.debug(`[${this.name}] Sync already in progress, skipping`);
155
+ return;
156
+ }
157
+ this.isSyncing = true;
158
+ try {
159
+ const metricsFile = getSessionMetricsPath(this.sessionId);
160
+ // 1. Read all deltas from JSONL
161
+ const allDeltas = await readJSONL(metricsFile);
162
+ // 2. Filter for pending deltas only
163
+ const pendingDeltas = allDeltas.filter(d => d.syncStatus === 'pending');
164
+ if (pendingDeltas.length === 0) {
165
+ logger.debug(`[${this.name}] No pending deltas to sync`);
166
+ return;
167
+ }
168
+ logger.info(`[${this.name}] Syncing ${pendingDeltas.length} pending deltas`);
169
+ // Debug: Log collected deltas
170
+ logger.debug(`[${this.name}] Collected pending deltas:`, {
171
+ count: pendingDeltas.length,
172
+ deltas: pendingDeltas.map(d => {
173
+ // Calculate tool stats from tools and toolStatus
174
+ const totalTools = Object.values(d.tools || {}).reduce((sum, count) => sum + count, 0);
175
+ let successCount = 0;
176
+ let failureCount = 0;
177
+ if (d.toolStatus) {
178
+ for (const status of Object.values(d.toolStatus)) {
179
+ successCount += status.success || 0;
180
+ failureCount += status.failure || 0;
181
+ }
182
+ }
183
+ // Calculate file operation totals
184
+ const fileOps = d.fileOperations || [];
185
+ const linesAdded = fileOps.reduce((sum, op) => sum + (op.linesAdded || 0), 0);
186
+ const linesRemoved = fileOps.reduce((sum, op) => sum + (op.linesRemoved || 0), 0);
187
+ const writeOps = fileOps.filter(op => op.type === 'write').length;
188
+ const editOps = fileOps.filter(op => op.type === 'edit').length;
189
+ const deleteOps = fileOps.filter(op => op.type === 'delete').length;
190
+ return {
191
+ recordId: d.recordId,
192
+ timestamp: typeof d.timestamp === 'number'
193
+ ? new Date(d.timestamp).toISOString()
194
+ : d.timestamp,
195
+ tokens: d.tokens,
196
+ tools: {
197
+ total: totalTools,
198
+ success: successCount,
199
+ failure: failureCount,
200
+ breakdown: d.tools
201
+ },
202
+ fileOperations: {
203
+ created: writeOps,
204
+ modified: editOps,
205
+ deleted: deleteOps,
206
+ linesAdded,
207
+ linesRemoved
208
+ }
209
+ };
210
+ })
211
+ });
212
+ // 3. Load session metadata
213
+ const session = await this.sessionStore.loadSession(this.sessionId);
214
+ if (!session) {
215
+ logger.error(`[${this.name}] Session not found: ${this.sessionId}`);
216
+ return;
217
+ }
218
+ // 4. Aggregate pending deltas into metrics grouped by branch
219
+ const metrics = aggregateDeltas(pendingDeltas, session, this.version);
220
+ logger.info(`[${this.name}] Aggregated ${metrics.length} branch-specific metrics from ${pendingDeltas.length} deltas`);
221
+ // Debug: Log aggregated metrics
222
+ for (const metric of metrics) {
223
+ logger.debug(`[${this.name}] Aggregated metric for branch "${metric.attributes.git_branch}":`, {
224
+ name: metric.name,
225
+ attributes: {
226
+ // Identity
227
+ agent: metric.attributes.agent,
228
+ agent_version: metric.attributes.agent_version,
229
+ llm_model: metric.attributes.llm_model,
230
+ project: metric.attributes.project,
231
+ session_id: metric.attributes.session_id,
232
+ git_branch: metric.attributes.git_branch,
233
+ // Interaction totals
234
+ total_user_prompts: metric.attributes.total_user_prompts,
235
+ // Token totals
236
+ total_input_tokens: metric.attributes.total_input_tokens,
237
+ total_output_tokens: metric.attributes.total_output_tokens,
238
+ total_cache_read_input_tokens: metric.attributes.total_cache_read_input_tokens,
239
+ total_cache_creation_tokens: metric.attributes.total_cache_creation_tokens,
240
+ // Tool totals
241
+ total_tool_calls: metric.attributes.total_tool_calls,
242
+ successful_tool_calls: metric.attributes.successful_tool_calls,
243
+ failed_tool_calls: metric.attributes.failed_tool_calls,
244
+ // File operation totals
245
+ files_created: metric.attributes.files_created,
246
+ files_modified: metric.attributes.files_modified,
247
+ files_deleted: metric.attributes.files_deleted,
248
+ total_lines_added: metric.attributes.total_lines_added,
249
+ total_lines_removed: metric.attributes.total_lines_removed,
250
+ // Session info
251
+ session_duration_ms: metric.attributes.session_duration_ms,
252
+ count: metric.attributes.count
253
+ }
254
+ });
255
+ }
256
+ // 5. Send each branch metric to API or log in dry-run mode
257
+ if (this.dryRun) {
258
+ // Dry-run mode: Log what would be sent without actually sending
259
+ for (const metric of metrics) {
260
+ logger.info(`[${this.name}] [DRY-RUN] Would send metric for branch "${metric.attributes.git_branch}" to API:`, {
261
+ endpoint: `${this.apiClient['config'].baseUrl}/v1/metrics`,
262
+ method: 'POST',
263
+ headers: {
264
+ 'Content-Type': 'application/json',
265
+ 'User-Agent': `CodeMie-CLI/${this.version}`,
266
+ 'X-CodeMie-Client': this.apiClient['config'].clientType,
267
+ 'Cookie': '[REDACTED]'
268
+ },
269
+ payload: {
270
+ name: metric.name,
271
+ attributes: metric.attributes
272
+ }
273
+ });
274
+ }
275
+ logger.info(`[${this.name}] [DRY-RUN] Skipping actual API calls - ${pendingDeltas.length} deltas across ${metrics.length} branches would be synced`);
276
+ }
277
+ else {
278
+ // Normal mode: Send each branch metric to API
279
+ for (const metric of metrics) {
280
+ const response = await this.apiClient.sendMetric(metric);
281
+ if (!response.success) {
282
+ logger.error(`[${this.name}] Sync failed for branch "${metric.attributes.git_branch}": ${response.message}`);
283
+ // Continue with other branches even if one fails
284
+ continue;
285
+ }
286
+ logger.info(`[${this.name}] Successfully synced metric for branch "${metric.attributes.git_branch}"`);
287
+ }
288
+ }
289
+ // 6. Mark deltas as synced in JSONL (atomic rewrite)
290
+ const syncedAt = Date.now();
291
+ const pendingRecordIds = new Set(pendingDeltas.map(d => d.recordId));
292
+ const updatedDeltas = allDeltas.map(d => pendingRecordIds.has(d.recordId)
293
+ ? {
294
+ ...d,
295
+ syncStatus: 'synced',
296
+ syncAttempts: d.syncAttempts + 1,
297
+ syncedAt
298
+ }
299
+ : d);
300
+ await writeJSONLAtomic(metricsFile, updatedDeltas);
301
+ logger.info(`[${this.name}] Successfully synced ${pendingDeltas.length} deltas across ${metrics.length} branches`);
302
+ // Debug: Log which deltas were marked as synced
303
+ logger.debug(`[${this.name}] Marked deltas as synced:`, {
304
+ syncedAt: new Date(syncedAt).toISOString(),
305
+ recordIds: Array.from(pendingRecordIds),
306
+ totalDeltasInFile: updatedDeltas.length,
307
+ syncedCount: updatedDeltas.filter(d => d.syncStatus === 'synced').length,
308
+ pendingCount: updatedDeltas.filter(d => d.syncStatus === 'pending').length
309
+ });
310
+ }
311
+ catch (error) {
312
+ logger.error(`[${this.name}] Sync failed:`, error);
313
+ throw error;
314
+ }
315
+ finally {
316
+ this.isSyncing = false;
317
+ }
318
+ }
319
+ }
320
+ //# sourceMappingURL=metrics-sync.plugin.js.map