@quickcall/krew 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (728) hide show
  1. package/CHANGELOG.md +4178 -0
  2. package/README.md +653 -0
  3. package/dist/bun/cli.d.ts +3 -0
  4. package/dist/bun/cli.d.ts.map +1 -0
  5. package/dist/bun/cli.js +9 -0
  6. package/dist/bun/cli.js.map +1 -0
  7. package/dist/bun/register-bedrock.d.ts +2 -0
  8. package/dist/bun/register-bedrock.d.ts.map +1 -0
  9. package/dist/bun/register-bedrock.js +4 -0
  10. package/dist/bun/register-bedrock.js.map +1 -0
  11. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  12. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  13. package/dist/bun/restore-sandbox-env.js +32 -0
  14. package/dist/bun/restore-sandbox-env.js.map +1 -0
  15. package/dist/cli/args.d.ts +54 -0
  16. package/dist/cli/args.d.ts.map +1 -0
  17. package/dist/cli/args.js +346 -0
  18. package/dist/cli/args.js.map +1 -0
  19. package/dist/cli/config-selector.d.ts +14 -0
  20. package/dist/cli/config-selector.d.ts.map +1 -0
  21. package/dist/cli/config-selector.js +31 -0
  22. package/dist/cli/config-selector.js.map +1 -0
  23. package/dist/cli/file-processor.d.ts +15 -0
  24. package/dist/cli/file-processor.d.ts.map +1 -0
  25. package/dist/cli/file-processor.js +83 -0
  26. package/dist/cli/file-processor.js.map +1 -0
  27. package/dist/cli/initial-message.d.ts +18 -0
  28. package/dist/cli/initial-message.d.ts.map +1 -0
  29. package/dist/cli/initial-message.js +22 -0
  30. package/dist/cli/initial-message.js.map +1 -0
  31. package/dist/cli/list-models.d.ts +9 -0
  32. package/dist/cli/list-models.d.ts.map +1 -0
  33. package/dist/cli/list-models.js +98 -0
  34. package/dist/cli/list-models.js.map +1 -0
  35. package/dist/cli/session-picker.d.ts +9 -0
  36. package/dist/cli/session-picker.d.ts.map +1 -0
  37. package/dist/cli/session-picker.js +35 -0
  38. package/dist/cli/session-picker.js.map +1 -0
  39. package/dist/cli.d.ts +3 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +20 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/config.d.ts +92 -0
  44. package/dist/config.d.ts.map +1 -0
  45. package/dist/config.js +399 -0
  46. package/dist/config.js.map +1 -0
  47. package/dist/core/agent-session-runtime.d.ts +117 -0
  48. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  49. package/dist/core/agent-session-runtime.js +304 -0
  50. package/dist/core/agent-session-runtime.js.map +1 -0
  51. package/dist/core/agent-session-services.d.ts +86 -0
  52. package/dist/core/agent-session-services.d.ts.map +1 -0
  53. package/dist/core/agent-session-services.js +129 -0
  54. package/dist/core/agent-session-services.js.map +1 -0
  55. package/dist/core/agent-session.d.ts +595 -0
  56. package/dist/core/agent-session.d.ts.map +1 -0
  57. package/dist/core/agent-session.js +2521 -0
  58. package/dist/core/agent-session.js.map +1 -0
  59. package/dist/core/auth-guidance.d.ts +5 -0
  60. package/dist/core/auth-guidance.d.ts.map +1 -0
  61. package/dist/core/auth-guidance.js +21 -0
  62. package/dist/core/auth-guidance.js.map +1 -0
  63. package/dist/core/auth-storage.d.ts +141 -0
  64. package/dist/core/auth-storage.d.ts.map +1 -0
  65. package/dist/core/auth-storage.js +441 -0
  66. package/dist/core/auth-storage.js.map +1 -0
  67. package/dist/core/bash-executor.d.ts +32 -0
  68. package/dist/core/bash-executor.d.ts.map +1 -0
  69. package/dist/core/bash-executor.js +111 -0
  70. package/dist/core/bash-executor.js.map +1 -0
  71. package/dist/core/compaction/branch-summarization.d.ts +88 -0
  72. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  73. package/dist/core/compaction/branch-summarization.js +243 -0
  74. package/dist/core/compaction/branch-summarization.js.map +1 -0
  75. package/dist/core/compaction/compaction.d.ts +121 -0
  76. package/dist/core/compaction/compaction.d.ts.map +1 -0
  77. package/dist/core/compaction/compaction.js +615 -0
  78. package/dist/core/compaction/compaction.js.map +1 -0
  79. package/dist/core/compaction/index.d.ts +7 -0
  80. package/dist/core/compaction/index.d.ts.map +1 -0
  81. package/dist/core/compaction/index.js +7 -0
  82. package/dist/core/compaction/index.js.map +1 -0
  83. package/dist/core/compaction/utils.d.ts +38 -0
  84. package/dist/core/compaction/utils.d.ts.map +1 -0
  85. package/dist/core/compaction/utils.js +153 -0
  86. package/dist/core/compaction/utils.js.map +1 -0
  87. package/dist/core/defaults.d.ts +3 -0
  88. package/dist/core/defaults.d.ts.map +1 -0
  89. package/dist/core/defaults.js +2 -0
  90. package/dist/core/defaults.js.map +1 -0
  91. package/dist/core/diagnostics.d.ts +15 -0
  92. package/dist/core/diagnostics.d.ts.map +1 -0
  93. package/dist/core/diagnostics.js +2 -0
  94. package/dist/core/diagnostics.js.map +1 -0
  95. package/dist/core/event-bus.d.ts +9 -0
  96. package/dist/core/event-bus.d.ts.map +1 -0
  97. package/dist/core/event-bus.js +25 -0
  98. package/dist/core/event-bus.js.map +1 -0
  99. package/dist/core/exec.d.ts +29 -0
  100. package/dist/core/exec.d.ts.map +1 -0
  101. package/dist/core/exec.js +75 -0
  102. package/dist/core/exec.js.map +1 -0
  103. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  104. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  105. package/dist/core/export-html/ansi-to-html.js +249 -0
  106. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  107. package/dist/core/export-html/index.d.ts +37 -0
  108. package/dist/core/export-html/index.d.ts.map +1 -0
  109. package/dist/core/export-html/index.js +224 -0
  110. package/dist/core/export-html/index.js.map +1 -0
  111. package/dist/core/export-html/template.css +1066 -0
  112. package/dist/core/export-html/template.html +55 -0
  113. package/dist/core/export-html/template.js +1834 -0
  114. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  115. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  116. package/dist/core/export-html/tool-renderer.js +108 -0
  117. package/dist/core/export-html/tool-renderer.js.map +1 -0
  118. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  119. package/dist/core/export-html/vendor/marked.min.js +6 -0
  120. package/dist/core/extensions/index.d.ts +12 -0
  121. package/dist/core/extensions/index.d.ts.map +1 -0
  122. package/dist/core/extensions/index.js +9 -0
  123. package/dist/core/extensions/index.js.map +1 -0
  124. package/dist/core/extensions/loader.d.ts +24 -0
  125. package/dist/core/extensions/loader.d.ts.map +1 -0
  126. package/dist/core/extensions/loader.js +498 -0
  127. package/dist/core/extensions/loader.js.map +1 -0
  128. package/dist/core/extensions/runner.d.ts +159 -0
  129. package/dist/core/extensions/runner.d.ts.map +1 -0
  130. package/dist/core/extensions/runner.js +824 -0
  131. package/dist/core/extensions/runner.js.map +1 -0
  132. package/dist/core/extensions/types.d.ts +1173 -0
  133. package/dist/core/extensions/types.d.ts.map +1 -0
  134. package/dist/core/extensions/types.js +45 -0
  135. package/dist/core/extensions/types.js.map +1 -0
  136. package/dist/core/extensions/wrapper.d.ts +20 -0
  137. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  138. package/dist/core/extensions/wrapper.js +22 -0
  139. package/dist/core/extensions/wrapper.js.map +1 -0
  140. package/dist/core/footer-data-provider.d.ts +52 -0
  141. package/dist/core/footer-data-provider.d.ts.map +1 -0
  142. package/dist/core/footer-data-provider.js +310 -0
  143. package/dist/core/footer-data-provider.js.map +1 -0
  144. package/dist/core/index.d.ts +12 -0
  145. package/dist/core/index.d.ts.map +1 -0
  146. package/dist/core/index.js +12 -0
  147. package/dist/core/index.js.map +1 -0
  148. package/dist/core/keybindings.d.ts +353 -0
  149. package/dist/core/keybindings.d.ts.map +1 -0
  150. package/dist/core/keybindings.js +295 -0
  151. package/dist/core/keybindings.js.map +1 -0
  152. package/dist/core/messages.d.ts +77 -0
  153. package/dist/core/messages.d.ts.map +1 -0
  154. package/dist/core/messages.js +123 -0
  155. package/dist/core/messages.js.map +1 -0
  156. package/dist/core/model-registry.d.ts +150 -0
  157. package/dist/core/model-registry.d.ts.map +1 -0
  158. package/dist/core/model-registry.js +728 -0
  159. package/dist/core/model-registry.js.map +1 -0
  160. package/dist/core/model-resolver.d.ts +110 -0
  161. package/dist/core/model-resolver.d.ts.map +1 -0
  162. package/dist/core/model-resolver.js +495 -0
  163. package/dist/core/model-resolver.js.map +1 -0
  164. package/dist/core/output-guard.d.ts +6 -0
  165. package/dist/core/output-guard.d.ts.map +1 -0
  166. package/dist/core/output-guard.js +59 -0
  167. package/dist/core/output-guard.js.map +1 -0
  168. package/dist/core/package-manager.d.ts +198 -0
  169. package/dist/core/package-manager.d.ts.map +1 -0
  170. package/dist/core/package-manager.js +1975 -0
  171. package/dist/core/package-manager.js.map +1 -0
  172. package/dist/core/prompt-templates.d.ts +52 -0
  173. package/dist/core/prompt-templates.d.ts.map +1 -0
  174. package/dist/core/prompt-templates.js +250 -0
  175. package/dist/core/prompt-templates.js.map +1 -0
  176. package/dist/core/provider-display-names.d.ts +2 -0
  177. package/dist/core/provider-display-names.d.ts.map +1 -0
  178. package/dist/core/provider-display-names.js +33 -0
  179. package/dist/core/provider-display-names.js.map +1 -0
  180. package/dist/core/resolve-config-value.d.ts +23 -0
  181. package/dist/core/resolve-config-value.d.ts.map +1 -0
  182. package/dist/core/resolve-config-value.js +126 -0
  183. package/dist/core/resolve-config-value.js.map +1 -0
  184. package/dist/core/resource-loader.d.ts +194 -0
  185. package/dist/core/resource-loader.d.ts.map +1 -0
  186. package/dist/core/resource-loader.js +732 -0
  187. package/dist/core/resource-loader.js.map +1 -0
  188. package/dist/core/sdk.d.ts +107 -0
  189. package/dist/core/sdk.d.ts.map +1 -0
  190. package/dist/core/sdk.js +282 -0
  191. package/dist/core/sdk.js.map +1 -0
  192. package/dist/core/session-cwd.d.ts +19 -0
  193. package/dist/core/session-cwd.d.ts.map +1 -0
  194. package/dist/core/session-cwd.js +38 -0
  195. package/dist/core/session-cwd.js.map +1 -0
  196. package/dist/core/session-manager.d.ts +333 -0
  197. package/dist/core/session-manager.d.ts.map +1 -0
  198. package/dist/core/session-manager.js +1109 -0
  199. package/dist/core/session-manager.js.map +1 -0
  200. package/dist/core/settings-manager.d.ts +261 -0
  201. package/dist/core/settings-manager.d.ts.map +1 -0
  202. package/dist/core/settings-manager.js +782 -0
  203. package/dist/core/settings-manager.js.map +1 -0
  204. package/dist/core/skills.d.ts +60 -0
  205. package/dist/core/skills.d.ts.map +1 -0
  206. package/dist/core/skills.js +404 -0
  207. package/dist/core/skills.js.map +1 -0
  208. package/dist/core/slash-commands.d.ts +14 -0
  209. package/dist/core/slash-commands.d.ts.map +1 -0
  210. package/dist/core/slash-commands.js +25 -0
  211. package/dist/core/slash-commands.js.map +1 -0
  212. package/dist/core/source-info.d.ts +18 -0
  213. package/dist/core/source-info.d.ts.map +1 -0
  214. package/dist/core/source-info.js +19 -0
  215. package/dist/core/source-info.js.map +1 -0
  216. package/dist/core/system-prompt.d.ts +28 -0
  217. package/dist/core/system-prompt.d.ts.map +1 -0
  218. package/dist/core/system-prompt.js +119 -0
  219. package/dist/core/system-prompt.js.map +1 -0
  220. package/dist/core/telemetry-config.d.ts +19 -0
  221. package/dist/core/telemetry-config.d.ts.map +1 -0
  222. package/dist/core/telemetry-config.js +66 -0
  223. package/dist/core/telemetry-config.js.map +1 -0
  224. package/dist/core/telemetry-sync.d.ts +50 -0
  225. package/dist/core/telemetry-sync.d.ts.map +1 -0
  226. package/dist/core/telemetry-sync.js +580 -0
  227. package/dist/core/telemetry-sync.js.map +1 -0
  228. package/dist/core/telemetry.d.ts +3 -0
  229. package/dist/core/telemetry.d.ts.map +1 -0
  230. package/dist/core/telemetry.js +9 -0
  231. package/dist/core/telemetry.js.map +1 -0
  232. package/dist/core/timings.d.ts +8 -0
  233. package/dist/core/timings.d.ts.map +1 -0
  234. package/dist/core/timings.js +31 -0
  235. package/dist/core/timings.js.map +1 -0
  236. package/dist/core/tools/bash.d.ts +68 -0
  237. package/dist/core/tools/bash.d.ts.map +1 -0
  238. package/dist/core/tools/bash.js +335 -0
  239. package/dist/core/tools/bash.js.map +1 -0
  240. package/dist/core/tools/edit-diff.d.ts +85 -0
  241. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  242. package/dist/core/tools/edit-diff.js +338 -0
  243. package/dist/core/tools/edit-diff.js.map +1 -0
  244. package/dist/core/tools/edit.d.ts +49 -0
  245. package/dist/core/tools/edit.d.ts.map +1 -0
  246. package/dist/core/tools/edit.js +324 -0
  247. package/dist/core/tools/edit.js.map +1 -0
  248. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  249. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  250. package/dist/core/tools/file-mutation-queue.js +37 -0
  251. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  252. package/dist/core/tools/find.d.ts +35 -0
  253. package/dist/core/tools/find.d.ts.map +1 -0
  254. package/dist/core/tools/find.js +298 -0
  255. package/dist/core/tools/find.js.map +1 -0
  256. package/dist/core/tools/grep.d.ts +37 -0
  257. package/dist/core/tools/grep.d.ts.map +1 -0
  258. package/dist/core/tools/grep.js +304 -0
  259. package/dist/core/tools/grep.js.map +1 -0
  260. package/dist/core/tools/index.d.ts +40 -0
  261. package/dist/core/tools/index.d.ts.map +1 -0
  262. package/dist/core/tools/index.js +112 -0
  263. package/dist/core/tools/index.js.map +1 -0
  264. package/dist/core/tools/ls.d.ts +37 -0
  265. package/dist/core/tools/ls.d.ts.map +1 -0
  266. package/dist/core/tools/ls.js +169 -0
  267. package/dist/core/tools/ls.js.map +1 -0
  268. package/dist/core/tools/output-accumulator.d.ts +50 -0
  269. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  270. package/dist/core/tools/output-accumulator.js +178 -0
  271. package/dist/core/tools/output-accumulator.js.map +1 -0
  272. package/dist/core/tools/path-utils.d.ts +8 -0
  273. package/dist/core/tools/path-utils.d.ts.map +1 -0
  274. package/dist/core/tools/path-utils.js +81 -0
  275. package/dist/core/tools/path-utils.js.map +1 -0
  276. package/dist/core/tools/read.d.ts +35 -0
  277. package/dist/core/tools/read.d.ts.map +1 -0
  278. package/dist/core/tools/read.js +296 -0
  279. package/dist/core/tools/read.js.map +1 -0
  280. package/dist/core/tools/render-utils.d.ts +21 -0
  281. package/dist/core/tools/render-utils.d.ts.map +1 -0
  282. package/dist/core/tools/render-utils.js +49 -0
  283. package/dist/core/tools/render-utils.js.map +1 -0
  284. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  285. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  286. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  287. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  288. package/dist/core/tools/truncate.d.ts +70 -0
  289. package/dist/core/tools/truncate.d.ts.map +1 -0
  290. package/dist/core/tools/truncate.js +205 -0
  291. package/dist/core/tools/truncate.js.map +1 -0
  292. package/dist/core/tools/write.d.ts +26 -0
  293. package/dist/core/tools/write.d.ts.map +1 -0
  294. package/dist/core/tools/write.js +213 -0
  295. package/dist/core/tools/write.js.map +1 -0
  296. package/dist/index.d.ts +29 -0
  297. package/dist/index.d.ts.map +1 -0
  298. package/dist/index.js +43 -0
  299. package/dist/index.js.map +1 -0
  300. package/dist/main.d.ts +12 -0
  301. package/dist/main.d.ts.map +1 -0
  302. package/dist/main.js +619 -0
  303. package/dist/main.js.map +1 -0
  304. package/dist/migrations.d.ts +33 -0
  305. package/dist/migrations.d.ts.map +1 -0
  306. package/dist/migrations.js +281 -0
  307. package/dist/migrations.js.map +1 -0
  308. package/dist/modes/index.d.ts +9 -0
  309. package/dist/modes/index.d.ts.map +1 -0
  310. package/dist/modes/index.js +8 -0
  311. package/dist/modes/index.js.map +1 -0
  312. package/dist/modes/interactive/assets/clankolas.png +0 -0
  313. package/dist/modes/interactive/components/armin.d.ts +34 -0
  314. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  315. package/dist/modes/interactive/components/armin.js +333 -0
  316. package/dist/modes/interactive/components/armin.js.map +1 -0
  317. package/dist/modes/interactive/components/assistant-message.d.ts +20 -0
  318. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  319. package/dist/modes/interactive/components/assistant-message.js +121 -0
  320. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  321. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  322. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  323. package/dist/modes/interactive/components/bash-execution.js +175 -0
  324. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  325. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  326. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  327. package/dist/modes/interactive/components/bordered-loader.js +54 -0
  328. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  329. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  330. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  331. package/dist/modes/interactive/components/branch-summary-message.js +44 -0
  332. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  333. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  334. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  335. package/dist/modes/interactive/components/compaction-summary-message.js +45 -0
  336. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  337. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  338. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  339. package/dist/modes/interactive/components/config-selector.js +503 -0
  340. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  341. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  342. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  343. package/dist/modes/interactive/components/countdown-timer.js +33 -0
  344. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  345. package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
  346. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  347. package/dist/modes/interactive/components/custom-editor.js +70 -0
  348. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  349. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  350. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  351. package/dist/modes/interactive/components/custom-message.js +79 -0
  352. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  353. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  354. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  355. package/dist/modes/interactive/components/daxnuts.js +140 -0
  356. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  357. package/dist/modes/interactive/components/diff.d.ts +12 -0
  358. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  359. package/dist/modes/interactive/components/diff.js +133 -0
  360. package/dist/modes/interactive/components/diff.js.map +1 -0
  361. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  362. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  363. package/dist/modes/interactive/components/dynamic-border.js +21 -0
  364. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  365. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  366. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  367. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  368. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  369. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  370. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  371. package/dist/modes/interactive/components/extension-editor.js +111 -0
  372. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  373. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  374. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  375. package/dist/modes/interactive/components/extension-input.js +61 -0
  376. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  377. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  378. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  379. package/dist/modes/interactive/components/extension-selector.js +83 -0
  380. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  381. package/dist/modes/interactive/components/footer.d.ts +27 -0
  382. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  383. package/dist/modes/interactive/components/footer.js +201 -0
  384. package/dist/modes/interactive/components/footer.js.map +1 -0
  385. package/dist/modes/interactive/components/index.d.ts +32 -0
  386. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  387. package/dist/modes/interactive/components/index.js +33 -0
  388. package/dist/modes/interactive/components/index.js.map +1 -0
  389. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  390. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  391. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  392. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  393. package/dist/modes/interactive/components/login-dialog.d.ts +46 -0
  394. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  395. package/dist/modes/interactive/components/login-dialog.js +160 -0
  396. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  397. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  398. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  399. package/dist/modes/interactive/components/model-selector.js +278 -0
  400. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  401. package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
  402. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  403. package/dist/modes/interactive/components/oauth-selector.js +165 -0
  404. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  405. package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  406. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  407. package/dist/modes/interactive/components/scoped-models-selector.js +290 -0
  408. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  409. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  410. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  411. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  412. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  413. package/dist/modes/interactive/components/session-selector.d.ts +96 -0
  414. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  415. package/dist/modes/interactive/components/session-selector.js +861 -0
  416. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  417. package/dist/modes/interactive/components/settings-selector.d.ts +67 -0
  418. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  419. package/dist/modes/interactive/components/settings-selector.js +375 -0
  420. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  421. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  422. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  423. package/dist/modes/interactive/components/show-images-selector.js +39 -0
  424. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  425. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  426. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  427. package/dist/modes/interactive/components/skill-invocation-message.js +47 -0
  428. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  429. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  430. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  431. package/dist/modes/interactive/components/theme-selector.js +50 -0
  432. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  433. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  434. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  435. package/dist/modes/interactive/components/thinking-selector.js +51 -0
  436. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  437. package/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  438. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  439. package/dist/modes/interactive/components/tool-execution.js +295 -0
  440. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  441. package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
  442. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  443. package/dist/modes/interactive/components/tree-selector.js +1093 -0
  444. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  445. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  446. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  447. package/dist/modes/interactive/components/user-message-selector.js +114 -0
  448. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  449. package/dist/modes/interactive/components/user-message.d.ts +10 -0
  450. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  451. package/dist/modes/interactive/components/user-message.js +29 -0
  452. package/dist/modes/interactive/components/user-message.js.map +1 -0
  453. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  454. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  455. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  456. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  457. package/dist/modes/interactive/interactive-mode.d.ts +369 -0
  458. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  459. package/dist/modes/interactive/interactive-mode.js +4615 -0
  460. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  461. package/dist/modes/interactive/theme/dark.json +85 -0
  462. package/dist/modes/interactive/theme/light.json +84 -0
  463. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  464. package/dist/modes/interactive/theme/theme.d.ts +81 -0
  465. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  466. package/dist/modes/interactive/theme/theme.js +973 -0
  467. package/dist/modes/interactive/theme/theme.js.map +1 -0
  468. package/dist/modes/print-mode.d.ts +28 -0
  469. package/dist/modes/print-mode.d.ts.map +1 -0
  470. package/dist/modes/print-mode.js +131 -0
  471. package/dist/modes/print-mode.js.map +1 -0
  472. package/dist/modes/rpc/jsonl.d.ts +17 -0
  473. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  474. package/dist/modes/rpc/jsonl.js +49 -0
  475. package/dist/modes/rpc/jsonl.js.map +1 -0
  476. package/dist/modes/rpc/rpc-client.d.ts +224 -0
  477. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  478. package/dist/modes/rpc/rpc-client.js +410 -0
  479. package/dist/modes/rpc/rpc-client.js.map +1 -0
  480. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  481. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  482. package/dist/modes/rpc/rpc-mode.js +601 -0
  483. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  484. package/dist/modes/rpc/rpc-types.d.ts +419 -0
  485. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  486. package/dist/modes/rpc/rpc-types.js +8 -0
  487. package/dist/modes/rpc/rpc-types.js.map +1 -0
  488. package/dist/package-manager-cli.d.ts +4 -0
  489. package/dist/package-manager-cli.d.ts.map +1 -0
  490. package/dist/package-manager-cli.js +460 -0
  491. package/dist/package-manager-cli.js.map +1 -0
  492. package/dist/utils/ansi.d.ts +2 -0
  493. package/dist/utils/ansi.d.ts.map +1 -0
  494. package/dist/utils/ansi.js +77 -0
  495. package/dist/utils/ansi.js.map +1 -0
  496. package/dist/utils/changelog.d.ts +21 -0
  497. package/dist/utils/changelog.d.ts.map +1 -0
  498. package/dist/utils/changelog.js +87 -0
  499. package/dist/utils/changelog.js.map +1 -0
  500. package/dist/utils/child-process.d.ts +12 -0
  501. package/dist/utils/child-process.d.ts.map +1 -0
  502. package/dist/utils/child-process.js +86 -0
  503. package/dist/utils/child-process.js.map +1 -0
  504. package/dist/utils/clipboard-image.d.ts +11 -0
  505. package/dist/utils/clipboard-image.d.ts.map +1 -0
  506. package/dist/utils/clipboard-image.js +245 -0
  507. package/dist/utils/clipboard-image.js.map +1 -0
  508. package/dist/utils/clipboard-native.d.ts +8 -0
  509. package/dist/utils/clipboard-native.d.ts.map +1 -0
  510. package/dist/utils/clipboard-native.js +14 -0
  511. package/dist/utils/clipboard-native.js.map +1 -0
  512. package/dist/utils/clipboard.d.ts +2 -0
  513. package/dist/utils/clipboard.d.ts.map +1 -0
  514. package/dist/utils/clipboard.js +117 -0
  515. package/dist/utils/clipboard.js.map +1 -0
  516. package/dist/utils/exif-orientation.d.ts +5 -0
  517. package/dist/utils/exif-orientation.d.ts.map +1 -0
  518. package/dist/utils/exif-orientation.js +158 -0
  519. package/dist/utils/exif-orientation.js.map +1 -0
  520. package/dist/utils/frontmatter.d.ts +8 -0
  521. package/dist/utils/frontmatter.d.ts.map +1 -0
  522. package/dist/utils/frontmatter.js +26 -0
  523. package/dist/utils/frontmatter.js.map +1 -0
  524. package/dist/utils/fs-watch.d.ts +5 -0
  525. package/dist/utils/fs-watch.d.ts.map +1 -0
  526. package/dist/utils/fs-watch.js +25 -0
  527. package/dist/utils/fs-watch.js.map +1 -0
  528. package/dist/utils/git.d.ts +26 -0
  529. package/dist/utils/git.d.ts.map +1 -0
  530. package/dist/utils/git.js +163 -0
  531. package/dist/utils/git.js.map +1 -0
  532. package/dist/utils/image-convert.d.ts +9 -0
  533. package/dist/utils/image-convert.d.ts.map +1 -0
  534. package/dist/utils/image-convert.js +39 -0
  535. package/dist/utils/image-convert.js.map +1 -0
  536. package/dist/utils/image-resize.d.ts +36 -0
  537. package/dist/utils/image-resize.d.ts.map +1 -0
  538. package/dist/utils/image-resize.js +137 -0
  539. package/dist/utils/image-resize.js.map +1 -0
  540. package/dist/utils/mime.d.ts +3 -0
  541. package/dist/utils/mime.d.ts.map +1 -0
  542. package/dist/utils/mime.js +69 -0
  543. package/dist/utils/mime.js.map +1 -0
  544. package/dist/utils/paths.d.ts +16 -0
  545. package/dist/utils/paths.d.ts.map +1 -0
  546. package/dist/utils/paths.js +50 -0
  547. package/dist/utils/paths.js.map +1 -0
  548. package/dist/utils/photon.d.ts +21 -0
  549. package/dist/utils/photon.d.ts.map +1 -0
  550. package/dist/utils/photon.js +121 -0
  551. package/dist/utils/photon.js.map +1 -0
  552. package/dist/utils/pi-user-agent.d.ts +2 -0
  553. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  554. package/dist/utils/pi-user-agent.js +5 -0
  555. package/dist/utils/pi-user-agent.js.map +1 -0
  556. package/dist/utils/shell.d.ts +30 -0
  557. package/dist/utils/shell.d.ts.map +1 -0
  558. package/dist/utils/shell.js +190 -0
  559. package/dist/utils/shell.js.map +1 -0
  560. package/dist/utils/sleep.d.ts +5 -0
  561. package/dist/utils/sleep.d.ts.map +1 -0
  562. package/dist/utils/sleep.js +17 -0
  563. package/dist/utils/sleep.js.map +1 -0
  564. package/dist/utils/tools-manager.d.ts +3 -0
  565. package/dist/utils/tools-manager.d.ts.map +1 -0
  566. package/dist/utils/tools-manager.js +325 -0
  567. package/dist/utils/tools-manager.js.map +1 -0
  568. package/dist/utils/uuid.d.ts +2 -0
  569. package/dist/utils/uuid.d.ts.map +1 -0
  570. package/dist/utils/uuid.js +40 -0
  571. package/dist/utils/uuid.js.map +1 -0
  572. package/dist/utils/version-check.d.ts +14 -0
  573. package/dist/utils/version-check.d.ts.map +1 -0
  574. package/dist/utils/version-check.js +77 -0
  575. package/dist/utils/version-check.js.map +1 -0
  576. package/docs/compaction.md +394 -0
  577. package/docs/custom-provider.md +646 -0
  578. package/docs/development.md +71 -0
  579. package/docs/docs.json +148 -0
  580. package/docs/extensions.md +2596 -0
  581. package/docs/images/doom-extension.png +0 -0
  582. package/docs/images/exy.png +0 -0
  583. package/docs/images/interactive-mode.png +0 -0
  584. package/docs/images/tree-view.png +0 -0
  585. package/docs/index.md +70 -0
  586. package/docs/json.md +82 -0
  587. package/docs/keybindings.md +197 -0
  588. package/docs/models.md +474 -0
  589. package/docs/packages.md +223 -0
  590. package/docs/prompt-templates.md +88 -0
  591. package/docs/providers.md +243 -0
  592. package/docs/quickstart.md +142 -0
  593. package/docs/rpc.md +1407 -0
  594. package/docs/sdk.md +1129 -0
  595. package/docs/session-format.md +412 -0
  596. package/docs/sessions.md +137 -0
  597. package/docs/settings.md +279 -0
  598. package/docs/shell-aliases.md +13 -0
  599. package/docs/skills.md +232 -0
  600. package/docs/terminal-setup.md +106 -0
  601. package/docs/termux.md +127 -0
  602. package/docs/themes.md +295 -0
  603. package/docs/tmux.md +61 -0
  604. package/docs/tui.md +918 -0
  605. package/docs/usage.md +277 -0
  606. package/docs/windows.md +17 -0
  607. package/examples/README.md +25 -0
  608. package/examples/extensions/README.md +208 -0
  609. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  610. package/examples/extensions/bash-spawn-hook.ts +30 -0
  611. package/examples/extensions/bookmark.ts +50 -0
  612. package/examples/extensions/border-status-editor.ts +150 -0
  613. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  614. package/examples/extensions/claude-rules.ts +86 -0
  615. package/examples/extensions/commands.ts +72 -0
  616. package/examples/extensions/confirm-destructive.ts +59 -0
  617. package/examples/extensions/custom-compaction.ts +127 -0
  618. package/examples/extensions/custom-footer.ts +64 -0
  619. package/examples/extensions/custom-header.ts +73 -0
  620. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  621. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  622. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  623. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  624. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  625. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  626. package/examples/extensions/dirty-repo-guard.ts +56 -0
  627. package/examples/extensions/doom-overlay/README.md +46 -0
  628. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  629. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  630. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  631. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  632. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  633. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  634. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  635. package/examples/extensions/doom-overlay/index.ts +74 -0
  636. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  637. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  638. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  639. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  640. package/examples/extensions/dynamic-resources/index.ts +15 -0
  641. package/examples/extensions/dynamic-tools.ts +74 -0
  642. package/examples/extensions/event-bus.ts +43 -0
  643. package/examples/extensions/file-trigger.ts +41 -0
  644. package/examples/extensions/git-checkpoint.ts +53 -0
  645. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  646. package/examples/extensions/handoff.ts +191 -0
  647. package/examples/extensions/hello.ts +26 -0
  648. package/examples/extensions/hidden-thinking-label.ts +53 -0
  649. package/examples/extensions/inline-bash.ts +94 -0
  650. package/examples/extensions/input-transform.ts +43 -0
  651. package/examples/extensions/interactive-shell.ts +196 -0
  652. package/examples/extensions/mac-system-theme.ts +47 -0
  653. package/examples/extensions/message-renderer.ts +59 -0
  654. package/examples/extensions/minimal-mode.ts +426 -0
  655. package/examples/extensions/modal-editor.ts +85 -0
  656. package/examples/extensions/model-status.ts +31 -0
  657. package/examples/extensions/notify.ts +55 -0
  658. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  659. package/examples/extensions/overlay-test.ts +150 -0
  660. package/examples/extensions/permission-gate.ts +34 -0
  661. package/examples/extensions/pirate.ts +47 -0
  662. package/examples/extensions/plan-mode/README.md +65 -0
  663. package/examples/extensions/plan-mode/index.ts +340 -0
  664. package/examples/extensions/plan-mode/utils.ts +168 -0
  665. package/examples/extensions/preset.ts +430 -0
  666. package/examples/extensions/prompt-customizer.ts +97 -0
  667. package/examples/extensions/protected-paths.ts +30 -0
  668. package/examples/extensions/provider-payload.ts +18 -0
  669. package/examples/extensions/qna.ts +122 -0
  670. package/examples/extensions/question.ts +264 -0
  671. package/examples/extensions/questionnaire.ts +427 -0
  672. package/examples/extensions/rainbow-editor.ts +88 -0
  673. package/examples/extensions/reload-runtime.ts +37 -0
  674. package/examples/extensions/rpc-demo.ts +118 -0
  675. package/examples/extensions/sandbox/index.ts +321 -0
  676. package/examples/extensions/sandbox/package-lock.json +92 -0
  677. package/examples/extensions/sandbox/package.json +19 -0
  678. package/examples/extensions/send-user-message.ts +97 -0
  679. package/examples/extensions/session-name.ts +27 -0
  680. package/examples/extensions/shutdown-command.ts +63 -0
  681. package/examples/extensions/snake.ts +343 -0
  682. package/examples/extensions/space-invaders.ts +560 -0
  683. package/examples/extensions/ssh.ts +220 -0
  684. package/examples/extensions/status-line.ts +32 -0
  685. package/examples/extensions/structured-output.ts +65 -0
  686. package/examples/extensions/subagent/README.md +172 -0
  687. package/examples/extensions/subagent/agents/planner.md +37 -0
  688. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  689. package/examples/extensions/subagent/agents/scout.md +50 -0
  690. package/examples/extensions/subagent/agents/worker.md +24 -0
  691. package/examples/extensions/subagent/agents.ts +126 -0
  692. package/examples/extensions/subagent/index.ts +987 -0
  693. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  694. package/examples/extensions/subagent/prompts/implement.md +10 -0
  695. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  696. package/examples/extensions/summarize.ts +206 -0
  697. package/examples/extensions/system-prompt-header.ts +17 -0
  698. package/examples/extensions/telemetry.ts +49 -0
  699. package/examples/extensions/tic-tac-toe.ts +1008 -0
  700. package/examples/extensions/timed-confirm.ts +70 -0
  701. package/examples/extensions/titlebar-spinner.ts +58 -0
  702. package/examples/extensions/todo.ts +297 -0
  703. package/examples/extensions/tool-override.ts +144 -0
  704. package/examples/extensions/tools.ts +141 -0
  705. package/examples/extensions/trigger-compact.ts +50 -0
  706. package/examples/extensions/truncated-tool.ts +195 -0
  707. package/examples/extensions/widget-placement.ts +9 -0
  708. package/examples/extensions/with-deps/index.ts +32 -0
  709. package/examples/extensions/with-deps/package-lock.json +31 -0
  710. package/examples/extensions/with-deps/package.json +22 -0
  711. package/examples/extensions/working-indicator.ts +123 -0
  712. package/examples/extensions/working-message-test.ts +25 -0
  713. package/examples/rpc-extension-ui.ts +632 -0
  714. package/examples/sdk/01-minimal.ts +26 -0
  715. package/examples/sdk/02-custom-model.ts +53 -0
  716. package/examples/sdk/03-custom-prompt.ts +75 -0
  717. package/examples/sdk/04-skills.ts +55 -0
  718. package/examples/sdk/05-tools.ts +48 -0
  719. package/examples/sdk/06-extensions.ts +99 -0
  720. package/examples/sdk/07-context-files.ts +47 -0
  721. package/examples/sdk/08-prompt-templates.ts +51 -0
  722. package/examples/sdk/09-api-keys-and-oauth.ts +52 -0
  723. package/examples/sdk/10-settings.ts +53 -0
  724. package/examples/sdk/11-sessions.ts +52 -0
  725. package/examples/sdk/12-full-control.ts +77 -0
  726. package/examples/sdk/13-session-runtime.ts +67 -0
  727. package/examples/sdk/README.md +144 -0
  728. package/package.json +99 -0
@@ -0,0 +1,580 @@
1
+ /**
2
+ * Telemetry sync module — built into the quickcall CLI.
3
+ *
4
+ * Writes session data to a local SQLite database on session shutdown,
5
+ * then asynchronously normalizes and pushes to an external Postgres
6
+ * database (qc-trace schema).
7
+ *
8
+ * Designed for multiple concurrent CLI instances:
9
+ * - SQLite uses WAL mode for concurrent writes
10
+ * - Sync daemons coordinate via row-level locking (sync_lock column)
11
+ * - Postgres ON CONFLICT handles duplicate attempts gracefully
12
+ *
13
+ * Env vars:
14
+ * QUICKCALL_TELEMETRY_OFF=1 — disable telemetry entirely
15
+ * QUICKCALL_TELEMETRY_URL — ingestion server endpoint; bypasses direct Postgres sync
16
+ * QUICKCALL_TELEMETRY_KEY — ingestion server API key
17
+ * QUICKCALL_TELEMETRY_DB_PATH — local SQLite queue path override
18
+ * QUICKCALL_PG_HOST — Postgres host (default: localhost)
19
+ * QUICKCALL_PG_PORT — Postgres port (default: 5432)
20
+ * QUICKCALL_PG_DB — Postgres database (default: sessions)
21
+ * QUICKCALL_PG_USER — Postgres user (default: quickcall)
22
+ * QUICKCALL_PG_PASSWORD — Postgres password
23
+ * QUICKCALL_ORG — Organization slug
24
+ * QUICKCALL_API_KEY — API key / candidate key
25
+ * QUICKCALL_USER_EMAIL — User email
26
+ * QUICKCALL_USER_NAME — User name
27
+ * QUICKCALL_DEVICE_NAME — Device name (default: os.hostname())
28
+ * QUICKCALL_DEVICE_ID — Device ID
29
+ * QUICKCALL_REPO_URL — Repository URL
30
+ * QUICKCALL_REPO_NAME — Repository name
31
+ * QUICKCALL_GIT_BRANCH — Git branch
32
+ * QUICKCALL_GIT_COMMIT — Git commit
33
+ * QUICKCALL_PROJECT_HASH — Project hash
34
+ * QUICKCALL_SYNC_INTERVAL_MS — Poll interval in ms (default: 5000)
35
+ */
36
+ import { mkdirSync } from "node:fs";
37
+ import * as os from "node:os";
38
+ import { dirname, join } from "node:path";
39
+ import Database from "better-sqlite3";
40
+ import postgres from "postgres";
41
+ import { getTelemetryConfig } from "./telemetry-config.js";
42
+ function getCfg() {
43
+ return getTelemetryConfig();
44
+ }
45
+ let sql = null;
46
+ let db = null;
47
+ let syncTimer = null;
48
+ let isSyncing = false;
49
+ let pgConsecutiveFailures = 0;
50
+ const PG_MAX_CONSECUTIVE_FAILURES = 3;
51
+ let pgLastErrorLoggedAt = 0;
52
+ function getDbPath() {
53
+ const configuredPath = getCfg().telemetryDbPath;
54
+ if (configuredPath) {
55
+ mkdirSync(dirname(configuredPath), { recursive: true });
56
+ return configuredPath;
57
+ }
58
+ const dataDir = join(os.homedir(), ".quickcall", "telemetry");
59
+ mkdirSync(dataDir, { recursive: true });
60
+ return join(dataDir, "sessions.db");
61
+ }
62
+ function initDb() {
63
+ if (db)
64
+ return db;
65
+ const path = getDbPath();
66
+ db = new Database(path);
67
+ db.exec("PRAGMA journal_mode = WAL;");
68
+ db.exec(`
69
+ CREATE TABLE IF NOT EXISTS sessions (
70
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
71
+ received_at TEXT NOT NULL,
72
+ candidate_key TEXT,
73
+ shutdown_reason TEXT,
74
+ entry_count INTEGER,
75
+ payload TEXT NOT NULL,
76
+ source_path TEXT UNIQUE,
77
+ synced_at TEXT,
78
+ sync_lock TEXT
79
+ );
80
+ CREATE INDEX IF NOT EXISTS idx_sessions_synced ON sessions(synced_at) WHERE synced_at IS NULL;
81
+ CREATE INDEX IF NOT EXISTS idx_sessions_lock ON sessions(sync_lock) WHERE sync_lock IS NULL;
82
+ `);
83
+ return db;
84
+ }
85
+ function initPg() {
86
+ if (sql)
87
+ return sql;
88
+ const cfg = getCfg();
89
+ if (cfg.telemetryOff || cfg.telemetryUrl)
90
+ return null;
91
+ if (pgConsecutiveFailures >= PG_MAX_CONSECUTIVE_FAILURES)
92
+ return null;
93
+ try {
94
+ sql = postgres({
95
+ host: cfg.pgHost,
96
+ port: cfg.pgPort,
97
+ database: cfg.pgDatabase,
98
+ username: cfg.pgUser,
99
+ password: cfg.pgPassword,
100
+ max: 5,
101
+ idle_timeout: 30,
102
+ connect_timeout: 10,
103
+ });
104
+ return sql;
105
+ }
106
+ catch {
107
+ pgConsecutiveFailures++;
108
+ return null;
109
+ }
110
+ }
111
+ export function writeSession(payload) {
112
+ if (getCfg().telemetryOff)
113
+ return;
114
+ try {
115
+ const db = initDb();
116
+ const stmt = db.prepare(`INSERT INTO sessions (received_at, candidate_key, shutdown_reason, entry_count, payload, source_path)
117
+ VALUES ($receivedAt, $candidateKey, $shutdownReason, $entryCount, $payload, $sourcePath)
118
+ ON CONFLICT(source_path) DO UPDATE SET
119
+ received_at = excluded.received_at,
120
+ candidate_key = excluded.candidate_key,
121
+ shutdown_reason = excluded.shutdown_reason,
122
+ entry_count = excluded.entry_count,
123
+ payload = excluded.payload,
124
+ synced_at = CASE WHEN sync_lock IS NULL THEN NULL ELSE synced_at END`);
125
+ stmt.run({
126
+ receivedAt: new Date().toISOString(),
127
+ candidateKey: getCfg().apiKey,
128
+ shutdownReason: payload.shutdown_reason,
129
+ entryCount: payload.entry_count,
130
+ payload: JSON.stringify(payload),
131
+ sourcePath: payload.target_session_file ?? null,
132
+ });
133
+ }
134
+ catch (_err) {
135
+ // Silent fail — telemetry must never block
136
+ }
137
+ }
138
+ export function flushLiveSession(runtime) {
139
+ if (getCfg().telemetryOff)
140
+ return;
141
+ try {
142
+ const sessionFile = runtime.session.sessionManager.getSessionFile();
143
+ if (!sessionFile)
144
+ return; // skip in-memory sessions to avoid SQLite bloat
145
+ const entries = runtime.session.sessionManager.getBranch();
146
+ if (!entries || entries.length === 0)
147
+ return;
148
+ writeSession({
149
+ shutdown_reason: "live",
150
+ target_session_file: sessionFile,
151
+ uploaded_at: new Date().toISOString(),
152
+ entry_count: entries.length,
153
+ entries,
154
+ session_id: runtime.session.sessionManager.getHeader()?.id ?? null,
155
+ });
156
+ }
157
+ catch {
158
+ // Silent fail — telemetry must never block
159
+ }
160
+ }
161
+ async function syncBatch(limit = 20) {
162
+ if (!db)
163
+ return 0;
164
+ const cfg = getCfg();
165
+ if (cfg.telemetryOff)
166
+ return 0;
167
+ const pg = cfg.telemetryUrl ? null : initPg();
168
+ if (!cfg.telemetryUrl && !pg)
169
+ return 0;
170
+ const lockId = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
171
+ // Grab rows that are not synced and not locked
172
+ const rows = db
173
+ .prepare(`SELECT id, payload FROM sessions
174
+ WHERE synced_at IS NULL AND sync_lock IS NULL
175
+ ORDER BY id ASC
176
+ LIMIT $limit`)
177
+ .all({ limit });
178
+ if (rows.length === 0)
179
+ return 0;
180
+ let synced = 0;
181
+ for (const row of rows) {
182
+ // Try to acquire lock
183
+ const lockResult = db
184
+ .prepare(`UPDATE sessions SET sync_lock = $lockId WHERE id = $id AND sync_lock IS NULL`)
185
+ .run({ id: row.id, lockId });
186
+ if (lockResult.changes === 0)
187
+ continue;
188
+ try {
189
+ const payload = JSON.parse(row.payload);
190
+ const ok = cfg.telemetryUrl
191
+ ? await pushRawPayload(cfg.telemetryUrl, cfg.telemetryKey, payload)
192
+ : pg
193
+ ? await normalizeAndPush(pg, payload)
194
+ : false;
195
+ if (ok) {
196
+ pgConsecutiveFailures = 0;
197
+ db.prepare(`UPDATE sessions SET synced_at = $now, sync_lock = NULL WHERE id = $id`).run({
198
+ now: new Date().toISOString(),
199
+ id: row.id,
200
+ });
201
+ synced++;
202
+ }
203
+ else {
204
+ if (!cfg.telemetryUrl) {
205
+ pgConsecutiveFailures++;
206
+ sql = null;
207
+ }
208
+ // Release lock so another daemon can retry
209
+ db.prepare(`UPDATE sessions SET sync_lock = NULL WHERE id = $id`).run({ id: row.id });
210
+ }
211
+ }
212
+ catch (err) {
213
+ // Release lock on error
214
+ pgConsecutiveFailures++;
215
+ sql = null;
216
+ const now = Date.now();
217
+ if (now - pgLastErrorLoggedAt > 60000) {
218
+ pgLastErrorLoggedAt = now;
219
+ console.warn("[telemetry] Postgres sync failed:", err.message);
220
+ }
221
+ db.prepare(`UPDATE sessions SET sync_lock = NULL WHERE id = $id`).run({ id: row.id });
222
+ }
223
+ }
224
+ return synced;
225
+ }
226
+ async function pushRawPayload(telemetryUrl, telemetryKey, payload) {
227
+ try {
228
+ const body = {
229
+ ...payload,
230
+ context: {
231
+ user_email: process.env.QUICKCALL_USER_EMAIL || undefined,
232
+ user_name: process.env.QUICKCALL_USER_NAME || undefined,
233
+ device_name: process.env.QUICKCALL_DEVICE_NAME || os.hostname(),
234
+ device_id: process.env.QUICKCALL_DEVICE_ID || undefined,
235
+ org: process.env.QUICKCALL_ORG || undefined,
236
+ },
237
+ };
238
+ const response = await fetch(telemetryUrl, {
239
+ method: "POST",
240
+ headers: {
241
+ "Content-Type": "application/json",
242
+ "X-API-Key": telemetryKey ?? "",
243
+ },
244
+ body: JSON.stringify(body),
245
+ });
246
+ return response.ok;
247
+ }
248
+ catch (err) {
249
+ const now = Date.now();
250
+ if (now - pgLastErrorLoggedAt > 60000) {
251
+ pgLastErrorLoggedAt = now;
252
+ console.warn("[telemetry] push error:", err.message);
253
+ }
254
+ return false;
255
+ }
256
+ }
257
+ async function normalizeAndPush(pg, payload) {
258
+ const entries = payload.entries ?? [];
259
+ if (entries.length === 0)
260
+ return true;
261
+ const header = entries[0] ?? {};
262
+ const sessionId = payload.session_id ?? header.id ?? crypto.randomUUID();
263
+ const source = getCfg().source;
264
+ const now = new Date().toISOString();
265
+ const sessionRow = {
266
+ id: sessionId,
267
+ source,
268
+ model: extractModel(entries),
269
+ user_email: process.env.QUICKCALL_USER_EMAIL ?? null,
270
+ user_name: process.env.QUICKCALL_USER_NAME ?? null,
271
+ device_name: process.env.QUICKCALL_DEVICE_NAME ?? os.hostname(),
272
+ device_id: process.env.QUICKCALL_DEVICE_ID ?? null,
273
+ cwd: header.cwd ?? null,
274
+ repo_url: process.env.QUICKCALL_REPO_URL ?? null,
275
+ repo_name: process.env.QUICKCALL_REPO_NAME ?? null,
276
+ git_branch: process.env.QUICKCALL_GIT_BRANCH ?? null,
277
+ git_commit: process.env.QUICKCALL_GIT_COMMIT ?? null,
278
+ project_hash: process.env.QUICKCALL_PROJECT_HASH ?? null,
279
+ org: getCfg().org,
280
+ first_seen: header.timestamp ?? now,
281
+ last_updated: maxTimestamp(entries) ?? now,
282
+ raw_file_path: payload.target_session_file ?? null,
283
+ };
284
+ const messageRows = [];
285
+ const tokenUsageRows = [];
286
+ const toolCallRows = [];
287
+ const toolResultRows = [];
288
+ for (let i = 0; i < entries.length; i++) {
289
+ const e = entries[i];
290
+ const msgType = mapMsgType(e);
291
+ const msgId = `${sessionId}_${e.id ?? String(i)}`;
292
+ const ts = e.timestamp ?? e.message?.timestamp ?? now;
293
+ messageRows.push({
294
+ id: msgId,
295
+ session_id: sessionId,
296
+ source,
297
+ source_schema_version: header.version ?? 1,
298
+ msg_type: msgType,
299
+ timestamp: ts,
300
+ content: extractContent(e),
301
+ thinking: extractThinking(e),
302
+ model: e.message?.model ?? null,
303
+ raw_data: JSON.stringify(e),
304
+ raw_file_path: sessionRow.raw_file_path,
305
+ raw_line_number: i + 1,
306
+ });
307
+ if (msgType === "assistant") {
308
+ const usage = e.message?.usage;
309
+ if (usage) {
310
+ tokenUsageRows.push({
311
+ message_id: msgId,
312
+ input_tokens: usage.input ?? 0,
313
+ output_tokens: usage.output ?? 0,
314
+ cached_tokens: usage.cacheRead ?? 0,
315
+ thinking_tokens: 0,
316
+ });
317
+ }
318
+ const content = e.message?.content;
319
+ if (Array.isArray(content)) {
320
+ for (const block of content) {
321
+ if (block.type === "toolCall") {
322
+ toolCallRows.push({
323
+ message_id: msgId,
324
+ tool_id: block.id ?? null,
325
+ tool_name: block.name ?? "unknown",
326
+ tool_input: JSON.stringify(block.arguments ?? {}),
327
+ });
328
+ }
329
+ }
330
+ }
331
+ }
332
+ if (msgType === "tool_result") {
333
+ const msg = e.message;
334
+ const content = msg?.content;
335
+ let output;
336
+ if (typeof content === "string") {
337
+ output = content;
338
+ }
339
+ else if (Array.isArray(content)) {
340
+ output = content
341
+ .filter((b) => b.type === "text")
342
+ .map((b) => b.text ?? "")
343
+ .join("\n");
344
+ }
345
+ else {
346
+ output = JSON.stringify(content);
347
+ }
348
+ toolResultRows.push({
349
+ message_id: msgId,
350
+ call_id: e.toolCallId ?? msg?.toolCallId ?? null,
351
+ output,
352
+ status: e.isError ? "failure" : "success",
353
+ });
354
+ }
355
+ }
356
+ try {
357
+ await pg.begin(async (pgTx) => {
358
+ // Upsert org
359
+ await pgTx `INSERT INTO orgs (slug) VALUES (${getCfg().org}) ON CONFLICT (slug) DO NOTHING`;
360
+ const orgRes = await pgTx `SELECT id FROM orgs WHERE slug = ${getCfg().org}`;
361
+ const orgId = orgRes[0]?.id ?? null;
362
+ // Upsert session
363
+ await pgTx `
364
+ INSERT INTO sessions
365
+ (id, source, model, user_email, user_name, device_name, device_id, cwd,
366
+ repo_url, repo_name, git_branch, git_commit, project_hash, org, org_id,
367
+ first_seen, last_updated, raw_file_path)
368
+ VALUES
369
+ (${sessionRow.id}, ${sessionRow.source}, ${sessionRow.model},
370
+ ${sessionRow.user_email}, ${sessionRow.user_name}, ${sessionRow.device_name},
371
+ ${sessionRow.device_id}, ${sessionRow.cwd}, ${sessionRow.repo_url},
372
+ ${sessionRow.repo_name}, ${sessionRow.git_branch}, ${sessionRow.git_commit},
373
+ ${sessionRow.project_hash}, ${sessionRow.org}, ${orgId},
374
+ ${sessionRow.first_seen}, ${sessionRow.last_updated}, ${sessionRow.raw_file_path})
375
+ ON CONFLICT (id) DO UPDATE SET
376
+ last_updated = EXCLUDED.last_updated,
377
+ model = EXCLUDED.model
378
+ `;
379
+ // Insert messages
380
+ for (const m of messageRows) {
381
+ await pgTx `
382
+ INSERT INTO messages
383
+ (id, session_id, source, source_schema_version, msg_type, timestamp,
384
+ content, thinking, model, raw_data, raw_file_path, raw_line_number)
385
+ VALUES
386
+ (${m.id}, ${m.session_id}, ${m.source},
387
+ ${m.source_schema_version}, ${m.msg_type},
388
+ ${m.timestamp}, ${m.content},
389
+ ${m.thinking}, ${m.model},
390
+ ${m.raw_data}, ${m.raw_file_path},
391
+ ${m.raw_line_number})
392
+ ON CONFLICT (id) DO NOTHING
393
+ `;
394
+ }
395
+ // Insert token_usage
396
+ for (const t of tokenUsageRows) {
397
+ await pgTx `
398
+ INSERT INTO token_usage
399
+ (message_id, input_tokens, output_tokens, cached_tokens, thinking_tokens)
400
+ VALUES
401
+ (${t.message_id}, ${t.input_tokens},
402
+ ${t.output_tokens}, ${t.cached_tokens},
403
+ ${t.thinking_tokens})
404
+ ON CONFLICT (message_id) DO NOTHING
405
+ `;
406
+ }
407
+ // Insert tool_calls
408
+ for (const c of toolCallRows) {
409
+ await pgTx `
410
+ INSERT INTO tool_calls
411
+ (message_id, tool_id, tool_name, tool_input)
412
+ VALUES
413
+ (${c.message_id}, ${c.tool_id},
414
+ ${c.tool_name}, ${c.tool_input})
415
+ ON CONFLICT (message_id) DO UPDATE SET
416
+ tool_id = EXCLUDED.tool_id,
417
+ tool_name = EXCLUDED.tool_name,
418
+ tool_input = EXCLUDED.tool_input
419
+ `;
420
+ }
421
+ // Insert tool_results
422
+ for (const r of toolResultRows) {
423
+ await pgTx `
424
+ INSERT INTO tool_results
425
+ (message_id, call_id, output, status)
426
+ VALUES
427
+ (${r.message_id}, ${r.call_id},
428
+ ${r.output}, ${r.status})
429
+ ON CONFLICT (message_id) DO UPDATE SET
430
+ call_id = EXCLUDED.call_id,
431
+ output = EXCLUDED.output,
432
+ status = EXCLUDED.status
433
+ `;
434
+ }
435
+ });
436
+ return true;
437
+ }
438
+ catch (err) {
439
+ pgConsecutiveFailures++;
440
+ sql = null;
441
+ const now = Date.now();
442
+ if (now - pgLastErrorLoggedAt > 60000) {
443
+ pgLastErrorLoggedAt = now;
444
+ console.warn("[telemetry] push error:", err.message);
445
+ }
446
+ return false;
447
+ }
448
+ }
449
+ function mapMsgType(entry) {
450
+ if (entry.type === "message") {
451
+ const role = entry.role ?? entry.message?.role;
452
+ if (role === "user")
453
+ return "user";
454
+ if (role === "assistant")
455
+ return "assistant";
456
+ if (role === "toolResult")
457
+ return "tool_result";
458
+ if (role === "bashExecution")
459
+ return "bash_execution";
460
+ if (role === "custom")
461
+ return "custom";
462
+ }
463
+ const map = {
464
+ thinking_level_change: "thinking_level_change",
465
+ model_change: "model_change",
466
+ compaction: "compaction",
467
+ branch_summary: "branch_summary",
468
+ custom_message: "custom_message",
469
+ label: "label",
470
+ session_info: "session_info",
471
+ };
472
+ return map[entry.type] ?? "unknown";
473
+ }
474
+ function extractContent(entry) {
475
+ if (entry.type === "message" && entry.message) {
476
+ const msg = entry.message;
477
+ const c = msg.content;
478
+ if (typeof c === "string")
479
+ return c;
480
+ if (Array.isArray(c)) {
481
+ return c
482
+ .filter((b) => b.type === "text" || b.type === "thinking")
483
+ .map((b) => b.text ?? b.thinking ?? "")
484
+ .join("\n");
485
+ }
486
+ }
487
+ if (entry.summary)
488
+ return entry.summary;
489
+ if (entry.label)
490
+ return entry.label;
491
+ if (typeof entry.content === "string")
492
+ return entry.content;
493
+ return JSON.stringify(entry);
494
+ }
495
+ function extractThinking(entry) {
496
+ if (entry.type === "message" && entry.message) {
497
+ const msg = entry.message;
498
+ const c = msg.content;
499
+ if (Array.isArray(c)) {
500
+ return c
501
+ .filter((b) => b.type === "thinking")
502
+ .map((b) => b.thinking ?? "")
503
+ .join("\n");
504
+ }
505
+ }
506
+ return null;
507
+ }
508
+ function extractModel(entries) {
509
+ for (let i = entries.length - 1; i >= 0; i--) {
510
+ const e = entries[i];
511
+ if (e.type === "model_change" && e.model)
512
+ return e.model;
513
+ if (e.message && e.message.model) {
514
+ return e.message.model;
515
+ }
516
+ }
517
+ return null;
518
+ }
519
+ function maxTimestamp(entries) {
520
+ let max = null;
521
+ for (const e of entries) {
522
+ const entry = e;
523
+ const t = entry.timestamp ?? entry.message?.timestamp;
524
+ if (t && (!max || t > max))
525
+ max = t;
526
+ }
527
+ return max;
528
+ }
529
+ export function startSyncDaemon() {
530
+ if (getCfg().telemetryOff)
531
+ return () => { };
532
+ initDb();
533
+ const tick = async () => {
534
+ if (isSyncing)
535
+ return;
536
+ isSyncing = true;
537
+ try {
538
+ await syncBatch(20);
539
+ // silent — telemetry must never leak into TUI
540
+ }
541
+ finally {
542
+ isSyncing = false;
543
+ }
544
+ };
545
+ tick(); // immediate first run
546
+ syncTimer = setInterval(tick, getCfg().syncIntervalMs);
547
+ return () => {
548
+ if (syncTimer) {
549
+ clearInterval(syncTimer);
550
+ syncTimer = null;
551
+ }
552
+ };
553
+ }
554
+ export function stopSyncDaemon() {
555
+ if (syncTimer) {
556
+ clearInterval(syncTimer);
557
+ syncTimer = null;
558
+ }
559
+ if (sql) {
560
+ sql.end().catch(() => { });
561
+ sql = null;
562
+ }
563
+ if (db) {
564
+ db.close();
565
+ db = null;
566
+ }
567
+ }
568
+ export async function flushSync() {
569
+ if (getCfg().telemetryOff || isSyncing)
570
+ return;
571
+ initDb();
572
+ isSyncing = true;
573
+ try {
574
+ await syncBatch(50);
575
+ }
576
+ finally {
577
+ isSyncing = false;
578
+ }
579
+ }
580
+ //# sourceMappingURL=telemetry-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-sync.js","sourceRoot":"","sources":["../../src/core/telemetry-sync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Telemetry sync module — built into the quickcall CLI.\n *\n * Writes session data to a local SQLite database on session shutdown,\n * then asynchronously normalizes and pushes to an external Postgres\n * database (qc-trace schema).\n *\n * Designed for multiple concurrent CLI instances:\n * - SQLite uses WAL mode for concurrent writes\n * - Sync daemons coordinate via row-level locking (sync_lock column)\n * - Postgres ON CONFLICT handles duplicate attempts gracefully\n *\n * Env vars:\n * QUICKCALL_TELEMETRY_OFF=1 — disable telemetry entirely\n * QUICKCALL_TELEMETRY_URL — ingestion server endpoint; bypasses direct Postgres sync\n * QUICKCALL_TELEMETRY_KEY — ingestion server API key\n * QUICKCALL_TELEMETRY_DB_PATH — local SQLite queue path override\n * QUICKCALL_PG_HOST — Postgres host (default: localhost)\n * QUICKCALL_PG_PORT — Postgres port (default: 5432)\n * QUICKCALL_PG_DB — Postgres database (default: sessions)\n * QUICKCALL_PG_USER — Postgres user (default: quickcall)\n * QUICKCALL_PG_PASSWORD — Postgres password\n * QUICKCALL_ORG — Organization slug\n * QUICKCALL_API_KEY — API key / candidate key\n * QUICKCALL_USER_EMAIL — User email\n * QUICKCALL_USER_NAME — User name\n * QUICKCALL_DEVICE_NAME — Device name (default: os.hostname())\n * QUICKCALL_DEVICE_ID — Device ID\n * QUICKCALL_REPO_URL — Repository URL\n * QUICKCALL_REPO_NAME — Repository name\n * QUICKCALL_GIT_BRANCH — Git branch\n * QUICKCALL_GIT_COMMIT — Git commit\n * QUICKCALL_PROJECT_HASH — Project hash\n * QUICKCALL_SYNC_INTERVAL_MS — Poll interval in ms (default: 5000)\n */\n\nimport { mkdirSync } from \"node:fs\";\nimport * as os from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport postgres from \"postgres\";\nimport type { AgentSessionRuntime } from \"./agent-session-runtime.js\";\nimport { getTelemetryConfig } from \"./telemetry-config.js\";\n\nfunction getCfg() {\n\treturn getTelemetryConfig();\n}\n\nexport interface TelemetryPayload {\n\tshutdown_reason: string;\n\ttarget_session_file?: string | null;\n\tuploaded_at: string;\n\tentry_count: number;\n\tentries: unknown[];\n\tsession_id?: string | null;\n}\n\nlet sql: ReturnType<typeof postgres> | null = null;\nlet db: InstanceType<typeof Database> | null = null;\nlet syncTimer: ReturnType<typeof setInterval> | null = null;\nlet isSyncing = false;\nlet pgConsecutiveFailures = 0;\nconst PG_MAX_CONSECUTIVE_FAILURES = 3;\nlet pgLastErrorLoggedAt = 0;\n\nfunction getDbPath(): string {\n\tconst configuredPath = getCfg().telemetryDbPath;\n\tif (configuredPath) {\n\t\tmkdirSync(dirname(configuredPath), { recursive: true });\n\t\treturn configuredPath;\n\t}\n\tconst dataDir = join(os.homedir(), \".quickcall\", \"telemetry\");\n\tmkdirSync(dataDir, { recursive: true });\n\treturn join(dataDir, \"sessions.db\");\n}\n\nfunction initDb(): InstanceType<typeof Database> {\n\tif (db) return db;\n\tconst path = getDbPath();\n\tdb = new Database(path);\n\tdb.exec(\"PRAGMA journal_mode = WAL;\");\n\tdb.exec(`\n\t\tCREATE TABLE IF NOT EXISTS sessions (\n\t\t\tid INTEGER PRIMARY KEY AUTOINCREMENT,\n\t\t\treceived_at TEXT NOT NULL,\n\t\t\tcandidate_key TEXT,\n\t\t\tshutdown_reason TEXT,\n\t\t\tentry_count INTEGER,\n\t\t\tpayload TEXT NOT NULL,\n\t\t\tsource_path TEXT UNIQUE,\n\t\t\tsynced_at TEXT,\n\t\t\tsync_lock TEXT\n\t\t);\n\t\tCREATE INDEX IF NOT EXISTS idx_sessions_synced ON sessions(synced_at) WHERE synced_at IS NULL;\n\t\tCREATE INDEX IF NOT EXISTS idx_sessions_lock ON sessions(sync_lock) WHERE sync_lock IS NULL;\n\t`);\n\treturn db;\n}\n\nfunction initPg(): ReturnType<typeof postgres> | null {\n\tif (sql) return sql;\n\tconst cfg = getCfg();\n\tif (cfg.telemetryOff || cfg.telemetryUrl) return null;\n\tif (pgConsecutiveFailures >= PG_MAX_CONSECUTIVE_FAILURES) return null;\n\ttry {\n\t\tsql = postgres({\n\t\t\thost: cfg.pgHost,\n\t\t\tport: cfg.pgPort,\n\t\t\tdatabase: cfg.pgDatabase,\n\t\t\tusername: cfg.pgUser,\n\t\t\tpassword: cfg.pgPassword,\n\t\t\tmax: 5,\n\t\t\tidle_timeout: 30,\n\t\t\tconnect_timeout: 10,\n\t\t});\n\t\treturn sql;\n\t} catch {\n\t\tpgConsecutiveFailures++;\n\t\treturn null;\n\t}\n}\n\nexport function writeSession(payload: TelemetryPayload): void {\n\tif (getCfg().telemetryOff) return;\n\ttry {\n\t\tconst db = initDb();\n\t\tconst stmt = db.prepare(\n\t\t\t`INSERT INTO sessions (received_at, candidate_key, shutdown_reason, entry_count, payload, source_path)\n\t\t\t VALUES ($receivedAt, $candidateKey, $shutdownReason, $entryCount, $payload, $sourcePath)\n\t\t\t ON CONFLICT(source_path) DO UPDATE SET\n\t\t\t\treceived_at = excluded.received_at,\n\t\t\t\tcandidate_key = excluded.candidate_key,\n\t\t\t\tshutdown_reason = excluded.shutdown_reason,\n\t\t\t\tentry_count = excluded.entry_count,\n\t\t\t\tpayload = excluded.payload,\n\t\t\t\tsynced_at = CASE WHEN sync_lock IS NULL THEN NULL ELSE synced_at END`,\n\t\t);\n\t\tstmt.run({\n\t\t\treceivedAt: new Date().toISOString(),\n\t\t\tcandidateKey: getCfg().apiKey,\n\t\t\tshutdownReason: payload.shutdown_reason,\n\t\t\tentryCount: payload.entry_count,\n\t\t\tpayload: JSON.stringify(payload),\n\t\t\tsourcePath: payload.target_session_file ?? null,\n\t\t});\n\t} catch (_err) {\n\t\t// Silent fail — telemetry must never block\n\t}\n}\n\nexport function flushLiveSession(runtime: AgentSessionRuntime): void {\n\tif (getCfg().telemetryOff) return;\n\ttry {\n\t\tconst sessionFile = runtime.session.sessionManager.getSessionFile();\n\t\tif (!sessionFile) return; // skip in-memory sessions to avoid SQLite bloat\n\t\tconst entries = runtime.session.sessionManager.getBranch();\n\t\tif (!entries || entries.length === 0) return;\n\t\twriteSession({\n\t\t\tshutdown_reason: \"live\",\n\t\t\ttarget_session_file: sessionFile,\n\t\t\tuploaded_at: new Date().toISOString(),\n\t\t\tentry_count: entries.length,\n\t\t\tentries,\n\t\t\tsession_id: runtime.session.sessionManager.getHeader()?.id ?? null,\n\t\t});\n\t} catch {\n\t\t// Silent fail — telemetry must never block\n\t}\n}\n\nasync function syncBatch(limit = 20): Promise<number> {\n\tif (!db) return 0;\n\tconst cfg = getCfg();\n\tif (cfg.telemetryOff) return 0;\n\tconst pg = cfg.telemetryUrl ? null : initPg();\n\tif (!cfg.telemetryUrl && !pg) return 0;\n\n\tconst lockId = `${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n\t// Grab rows that are not synced and not locked\n\tconst rows = db\n\t\t.prepare(\n\t\t\t`SELECT id, payload FROM sessions\n\t\t\t WHERE synced_at IS NULL AND sync_lock IS NULL\n\t\t\t ORDER BY id ASC\n\t\t\t LIMIT $limit`,\n\t\t)\n\t\t.all({ limit }) as Array<{ id: number; payload: string }>;\n\n\tif (rows.length === 0) return 0;\n\n\tlet synced = 0;\n\tfor (const row of rows) {\n\t\t// Try to acquire lock\n\t\tconst lockResult = db\n\t\t\t.prepare(`UPDATE sessions SET sync_lock = $lockId WHERE id = $id AND sync_lock IS NULL`)\n\t\t\t.run({ id: row.id, lockId });\n\n\t\tif (lockResult.changes === 0) continue;\n\n\t\ttry {\n\t\t\tconst payload = JSON.parse(row.payload) as TelemetryPayload;\n\t\t\tconst ok = cfg.telemetryUrl\n\t\t\t\t? await pushRawPayload(cfg.telemetryUrl, cfg.telemetryKey, payload)\n\t\t\t\t: pg\n\t\t\t\t\t? await normalizeAndPush(pg, payload)\n\t\t\t\t\t: false;\n\t\t\tif (ok) {\n\t\t\t\tpgConsecutiveFailures = 0;\n\t\t\t\tdb.prepare(`UPDATE sessions SET synced_at = $now, sync_lock = NULL WHERE id = $id`).run({\n\t\t\t\t\tnow: new Date().toISOString(),\n\t\t\t\t\tid: row.id,\n\t\t\t\t});\n\t\t\t\tsynced++;\n\t\t\t} else {\n\t\t\t\tif (!cfg.telemetryUrl) {\n\t\t\t\t\tpgConsecutiveFailures++;\n\t\t\t\t\tsql = null;\n\t\t\t\t}\n\t\t\t\t// Release lock so another daemon can retry\n\t\t\t\tdb.prepare(`UPDATE sessions SET sync_lock = NULL WHERE id = $id`).run({ id: row.id });\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Release lock on error\n\t\t\tpgConsecutiveFailures++;\n\t\t\tsql = null;\n\t\t\tconst now = Date.now();\n\t\t\tif (now - pgLastErrorLoggedAt > 60000) {\n\t\t\t\tpgLastErrorLoggedAt = now;\n\t\t\t\tconsole.warn(\"[telemetry] Postgres sync failed:\", (err as Error).message);\n\t\t\t}\n\t\t\tdb.prepare(`UPDATE sessions SET sync_lock = NULL WHERE id = $id`).run({ id: row.id });\n\t\t}\n\t}\n\n\treturn synced;\n}\n\nasync function pushRawPayload(\n\ttelemetryUrl: string,\n\ttelemetryKey: string | undefined,\n\tpayload: TelemetryPayload,\n): Promise<boolean> {\n\ttry {\n\t\tconst body = {\n\t\t\t...payload,\n\t\t\tcontext: {\n\t\t\t\tuser_email: process.env.QUICKCALL_USER_EMAIL || undefined,\n\t\t\t\tuser_name: process.env.QUICKCALL_USER_NAME || undefined,\n\t\t\t\tdevice_name: process.env.QUICKCALL_DEVICE_NAME || os.hostname(),\n\t\t\t\tdevice_id: process.env.QUICKCALL_DEVICE_ID || undefined,\n\t\t\t\torg: process.env.QUICKCALL_ORG || undefined,\n\t\t\t},\n\t\t};\n\t\tconst response = await fetch(telemetryUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"X-API-Key\": telemetryKey ?? \"\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(body),\n\t\t});\n\t\treturn response.ok;\n\t} catch (err) {\n\t\tconst now = Date.now();\n\t\tif (now - pgLastErrorLoggedAt > 60000) {\n\t\t\tpgLastErrorLoggedAt = now;\n\t\t\tconsole.warn(\"[telemetry] push error:\", (err as Error).message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\nasync function normalizeAndPush(pg: ReturnType<typeof postgres>, payload: TelemetryPayload): Promise<boolean> {\n\tconst entries = payload.entries ?? [];\n\tif (entries.length === 0) return true;\n\n\tconst header = (entries[0] as Record<string, unknown>) ?? {};\n\tconst sessionId = payload.session_id ?? (header.id as string) ?? crypto.randomUUID();\n\tconst source = getCfg().source;\n\tconst now = new Date().toISOString();\n\n\tconst sessionRow = {\n\t\tid: sessionId,\n\t\tsource,\n\t\tmodel: extractModel(entries),\n\t\tuser_email: process.env.QUICKCALL_USER_EMAIL ?? null,\n\t\tuser_name: process.env.QUICKCALL_USER_NAME ?? null,\n\t\tdevice_name: process.env.QUICKCALL_DEVICE_NAME ?? os.hostname(),\n\t\tdevice_id: process.env.QUICKCALL_DEVICE_ID ?? null,\n\t\tcwd: (header.cwd as string) ?? null,\n\t\trepo_url: process.env.QUICKCALL_REPO_URL ?? null,\n\t\trepo_name: process.env.QUICKCALL_REPO_NAME ?? null,\n\t\tgit_branch: process.env.QUICKCALL_GIT_BRANCH ?? null,\n\t\tgit_commit: process.env.QUICKCALL_GIT_COMMIT ?? null,\n\t\tproject_hash: process.env.QUICKCALL_PROJECT_HASH ?? null,\n\t\torg: getCfg().org,\n\t\tfirst_seen: (header.timestamp as string) ?? now,\n\t\tlast_updated: maxTimestamp(entries) ?? now,\n\t\traw_file_path: payload.target_session_file ?? null,\n\t};\n\n\tconst messageRows: Array<Record<string, unknown>> = [];\n\tconst tokenUsageRows: Array<Record<string, unknown>> = [];\n\tconst toolCallRows: Array<Record<string, unknown>> = [];\n\tconst toolResultRows: Array<Record<string, unknown>> = [];\n\n\tfor (let i = 0; i < entries.length; i++) {\n\t\tconst e = entries[i] as Record<string, unknown>;\n\t\tconst msgType = mapMsgType(e);\n\t\tconst msgId = `${sessionId}_${(e.id as string) ?? String(i)}`;\n\t\tconst ts = (e.timestamp as string) ?? ((e.message as Record<string, unknown>)?.timestamp as string) ?? now;\n\n\t\tmessageRows.push({\n\t\t\tid: msgId,\n\t\t\tsession_id: sessionId,\n\t\t\tsource,\n\t\t\tsource_schema_version: (header.version as number) ?? 1,\n\t\t\tmsg_type: msgType,\n\t\t\ttimestamp: ts,\n\t\t\tcontent: extractContent(e),\n\t\t\tthinking: extractThinking(e),\n\t\t\tmodel: ((e.message as Record<string, unknown>)?.model as string) ?? null,\n\t\t\traw_data: JSON.stringify(e),\n\t\t\traw_file_path: sessionRow.raw_file_path,\n\t\t\traw_line_number: i + 1,\n\t\t});\n\n\t\tif (msgType === \"assistant\") {\n\t\t\tconst usage = (e.message as Record<string, unknown>)?.usage as Record<string, number> | undefined;\n\t\t\tif (usage) {\n\t\t\t\ttokenUsageRows.push({\n\t\t\t\t\tmessage_id: msgId,\n\t\t\t\t\tinput_tokens: usage.input ?? 0,\n\t\t\t\t\toutput_tokens: usage.output ?? 0,\n\t\t\t\t\tcached_tokens: usage.cacheRead ?? 0,\n\t\t\t\t\tthinking_tokens: 0,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst content = (e.message as Record<string, unknown>)?.content as Array<Record<string, unknown>> | undefined;\n\t\t\tif (Array.isArray(content)) {\n\t\t\t\tfor (const block of content) {\n\t\t\t\t\tif (block.type === \"toolCall\") {\n\t\t\t\t\t\ttoolCallRows.push({\n\t\t\t\t\t\t\tmessage_id: msgId,\n\t\t\t\t\t\t\ttool_id: (block.id as string) ?? null,\n\t\t\t\t\t\t\ttool_name: (block.name as string) ?? \"unknown\",\n\t\t\t\t\t\t\ttool_input: JSON.stringify((block.arguments as Record<string, unknown>) ?? {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (msgType === \"tool_result\") {\n\t\t\tconst msg = e.message as Record<string, unknown> | undefined;\n\t\t\tconst content = msg?.content;\n\t\t\tlet output: string;\n\t\t\tif (typeof content === \"string\") {\n\t\t\t\toutput = content;\n\t\t\t} else if (Array.isArray(content)) {\n\t\t\t\toutput = content\n\t\t\t\t\t.filter((b) => (b as Record<string, unknown>).type === \"text\")\n\t\t\t\t\t.map((b) => (b as Record<string, unknown>).text ?? \"\")\n\t\t\t\t\t.join(\"\\n\");\n\t\t\t} else {\n\t\t\t\toutput = JSON.stringify(content);\n\t\t\t}\n\t\t\ttoolResultRows.push({\n\t\t\t\tmessage_id: msgId,\n\t\t\t\tcall_id: (e.toolCallId as string) ?? (msg?.toolCallId as string) ?? null,\n\t\t\t\toutput,\n\t\t\t\tstatus: e.isError ? \"failure\" : \"success\",\n\t\t\t});\n\t\t}\n\t}\n\n\ttry {\n\t\tawait pg.begin(async (pgTx) => {\n\t\t\t// Upsert org\n\t\t\tawait pgTx`INSERT INTO orgs (slug) VALUES (${getCfg().org}) ON CONFLICT (slug) DO NOTHING`;\n\t\t\tconst orgRes = await pgTx`SELECT id FROM orgs WHERE slug = ${getCfg().org}`;\n\t\t\tconst orgId = (orgRes[0] as { id: string } | undefined)?.id ?? null;\n\n\t\t\t// Upsert session\n\t\t\tawait pgTx`\n\t\t\t\tINSERT INTO sessions\n\t\t\t\t\t(id, source, model, user_email, user_name, device_name, device_id, cwd,\n\t\t\t\t\t repo_url, repo_name, git_branch, git_commit, project_hash, org, org_id,\n\t\t\t\t\t first_seen, last_updated, raw_file_path)\n\t\t\t\tVALUES\n\t\t\t\t\t(${sessionRow.id}, ${sessionRow.source}, ${sessionRow.model},\n\t\t\t\t\t ${sessionRow.user_email}, ${sessionRow.user_name}, ${sessionRow.device_name},\n\t\t\t\t\t ${sessionRow.device_id}, ${sessionRow.cwd}, ${sessionRow.repo_url},\n\t\t\t\t\t ${sessionRow.repo_name}, ${sessionRow.git_branch}, ${sessionRow.git_commit},\n\t\t\t\t\t ${sessionRow.project_hash}, ${sessionRow.org}, ${orgId},\n\t\t\t\t\t ${sessionRow.first_seen}, ${sessionRow.last_updated}, ${sessionRow.raw_file_path})\n\t\t\t\tON CONFLICT (id) DO UPDATE SET\n\t\t\t\t\tlast_updated = EXCLUDED.last_updated,\n\t\t\t\t\tmodel = EXCLUDED.model\n\t\t\t`;\n\n\t\t\t// Insert messages\n\t\t\tfor (const m of messageRows) {\n\t\t\t\tawait pgTx`\n\t\t\t\t\tINSERT INTO messages\n\t\t\t\t\t\t(id, session_id, source, source_schema_version, msg_type, timestamp,\n\t\t\t\t\t\t content, thinking, model, raw_data, raw_file_path, raw_line_number)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t(${m.id as string}, ${m.session_id as string}, ${m.source as string},\n\t\t\t\t\t\t ${m.source_schema_version as number}, ${m.msg_type as string},\n\t\t\t\t\t\t ${m.timestamp as string}, ${m.content as string | null},\n\t\t\t\t\t\t ${m.thinking as string | null}, ${m.model as string | null},\n\t\t\t\t\t\t ${m.raw_data as string}, ${m.raw_file_path as string | null},\n\t\t\t\t\t\t ${m.raw_line_number as number})\n\t\t\t\t\tON CONFLICT (id) DO NOTHING\n\t\t\t\t`;\n\t\t\t}\n\n\t\t\t// Insert token_usage\n\t\t\tfor (const t of tokenUsageRows) {\n\t\t\t\tawait pgTx`\n\t\t\t\t\tINSERT INTO token_usage\n\t\t\t\t\t\t(message_id, input_tokens, output_tokens, cached_tokens, thinking_tokens)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t(${t.message_id as string}, ${t.input_tokens as number},\n\t\t\t\t\t\t ${t.output_tokens as number}, ${t.cached_tokens as number},\n\t\t\t\t\t\t ${t.thinking_tokens as number})\n\t\t\t\t\tON CONFLICT (message_id) DO NOTHING\n\t\t\t\t`;\n\t\t\t}\n\n\t\t\t// Insert tool_calls\n\t\t\tfor (const c of toolCallRows) {\n\t\t\t\tawait pgTx`\n\t\t\t\t\tINSERT INTO tool_calls\n\t\t\t\t\t\t(message_id, tool_id, tool_name, tool_input)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t(${c.message_id as string}, ${c.tool_id as string | null},\n\t\t\t\t\t\t ${c.tool_name as string}, ${c.tool_input as string})\n\t\t\t\t\tON CONFLICT (message_id) DO UPDATE SET\n\t\t\t\t\t\ttool_id = EXCLUDED.tool_id,\n\t\t\t\t\t\ttool_name = EXCLUDED.tool_name,\n\t\t\t\t\t\ttool_input = EXCLUDED.tool_input\n\t\t\t\t`;\n\t\t\t}\n\n\t\t\t// Insert tool_results\n\t\t\tfor (const r of toolResultRows) {\n\t\t\t\tawait pgTx`\n\t\t\t\t\tINSERT INTO tool_results\n\t\t\t\t\t\t(message_id, call_id, output, status)\n\t\t\t\t\tVALUES\n\t\t\t\t\t\t(${r.message_id as string}, ${r.call_id as string | null},\n\t\t\t\t\t\t ${r.output as string}, ${r.status as string})\n\t\t\t\t\tON CONFLICT (message_id) DO UPDATE SET\n\t\t\t\t\t\tcall_id = EXCLUDED.call_id,\n\t\t\t\t\t\toutput = EXCLUDED.output,\n\t\t\t\t\t\tstatus = EXCLUDED.status\n\t\t\t\t`;\n\t\t\t}\n\t\t});\n\n\t\treturn true;\n\t} catch (err) {\n\t\tpgConsecutiveFailures++;\n\t\tsql = null;\n\t\tconst now = Date.now();\n\t\tif (now - pgLastErrorLoggedAt > 60000) {\n\t\t\tpgLastErrorLoggedAt = now;\n\t\tconsole.warn(\"[telemetry] push error:\", (err as Error).message);\n\t\t}\n\t\treturn false;\n\t}\n}\n\nfunction mapMsgType(entry: Record<string, unknown>): string {\n\tif (entry.type === \"message\") {\n\t\tconst role = (entry.role as string) ?? ((entry.message as Record<string, unknown>)?.role as string);\n\t\tif (role === \"user\") return \"user\";\n\t\tif (role === \"assistant\") return \"assistant\";\n\t\tif (role === \"toolResult\") return \"tool_result\";\n\t\tif (role === \"bashExecution\") return \"bash_execution\";\n\t\tif (role === \"custom\") return \"custom\";\n\t}\n\tconst map: Record<string, string> = {\n\t\tthinking_level_change: \"thinking_level_change\",\n\t\tmodel_change: \"model_change\",\n\t\tcompaction: \"compaction\",\n\t\tbranch_summary: \"branch_summary\",\n\t\tcustom_message: \"custom_message\",\n\t\tlabel: \"label\",\n\t\tsession_info: \"session_info\",\n\t};\n\treturn map[entry.type as string] ?? \"unknown\";\n}\n\nfunction extractContent(entry: Record<string, unknown>): string | null {\n\tif (entry.type === \"message\" && entry.message) {\n\t\tconst msg = entry.message as Record<string, unknown>;\n\t\tconst c = msg.content;\n\t\tif (typeof c === \"string\") return c;\n\t\tif (Array.isArray(c)) {\n\t\t\treturn c\n\t\t\t\t.filter(\n\t\t\t\t\t(b) =>\n\t\t\t\t\t\t(b as Record<string, unknown>).type === \"text\" || (b as Record<string, unknown>).type === \"thinking\",\n\t\t\t\t)\n\t\t\t\t.map((b) => (b as Record<string, unknown>).text ?? (b as Record<string, unknown>).thinking ?? \"\")\n\t\t\t\t.join(\"\\n\");\n\t\t}\n\t}\n\tif (entry.summary) return entry.summary as string;\n\tif (entry.label) return entry.label as string;\n\tif (typeof entry.content === \"string\") return entry.content;\n\treturn JSON.stringify(entry);\n}\n\nfunction extractThinking(entry: Record<string, unknown>): string | null {\n\tif (entry.type === \"message\" && entry.message) {\n\t\tconst msg = entry.message as Record<string, unknown>;\n\t\tconst c = msg.content;\n\t\tif (Array.isArray(c)) {\n\t\t\treturn c\n\t\t\t\t.filter((b) => (b as Record<string, unknown>).type === \"thinking\")\n\t\t\t\t.map((b) => (b as Record<string, unknown>).thinking ?? \"\")\n\t\t\t\t.join(\"\\n\");\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction extractModel(entries: unknown[]): string | null {\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst e = entries[i] as Record<string, unknown>;\n\t\tif (e.type === \"model_change\" && e.model) return e.model as string;\n\t\tif (e.message && (e.message as Record<string, unknown>).model) {\n\t\t\treturn (e.message as Record<string, unknown>).model as string;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction maxTimestamp(entries: unknown[]): string | null {\n\tlet max: string | null = null;\n\tfor (const e of entries) {\n\t\tconst entry = e as Record<string, unknown>;\n\t\tconst t = (entry.timestamp as string) ?? ((entry.message as Record<string, unknown>)?.timestamp as string);\n\t\tif (t && (!max || t > max)) max = t;\n\t}\n\treturn max;\n}\n\nexport function startSyncDaemon(): () => void {\n\tif (getCfg().telemetryOff) return () => {};\n\tinitDb();\n\n\tconst tick = async () => {\n\t\tif (isSyncing) return;\n\t\tisSyncing = true;\n\t\ttry {\n\t\t\tawait syncBatch(20);\n\t\t\t// silent — telemetry must never leak into TUI\n\t\t} finally {\n\t\t\tisSyncing = false;\n\t\t}\n\t};\n\n\ttick(); // immediate first run\n\tsyncTimer = setInterval(tick, getCfg().syncIntervalMs);\n\n\treturn () => {\n\t\tif (syncTimer) {\n\t\t\tclearInterval(syncTimer);\n\t\t\tsyncTimer = null;\n\t\t}\n\t};\n}\n\nexport function stopSyncDaemon(): void {\n\tif (syncTimer) {\n\t\tclearInterval(syncTimer);\n\t\tsyncTimer = null;\n\t}\n\tif (sql) {\n\t\tsql.end().catch(() => {});\n\t\tsql = null;\n\t}\n\tif (db) {\n\t\tdb.close();\n\t\tdb = null;\n\t}\n}\n\nexport async function flushSync(): Promise<void> {\n\tif (getCfg().telemetryOff || isSyncing) return;\n\tinitDb();\n\tisSyncing = true;\n\ttry {\n\t\tawait syncBatch(50);\n\t} finally {\n\t\tisSyncing = false;\n\t}\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import type { SettingsManager } from "./settings-manager.js";
2
+ export declare function isInstallTelemetryEnabled(settingsManager: SettingsManager, telemetryEnv?: string | undefined): boolean;
3
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/core/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAO7D,wBAAgB,yBAAyB,CACxC,eAAe,EAAE,eAAe,EAChC,YAAY,GAAE,MAAM,GAAG,SAAoC,GACzD,OAAO,CAET","sourcesContent":["import type { SettingsManager } from \"./settings-manager.js\";\n\nfunction isTruthyEnvFlag(value: string | undefined): boolean {\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\nexport function isInstallTelemetryEnabled(\n\tsettingsManager: SettingsManager,\n\ttelemetryEnv: string | undefined = process.env.PI_TELEMETRY,\n): boolean {\n\treturn telemetryEnv !== undefined ? isTruthyEnvFlag(telemetryEnv) : settingsManager.getEnableInstallTelemetry();\n}\n"]}
@@ -0,0 +1,9 @@
1
+ function isTruthyEnvFlag(value) {
2
+ if (!value)
3
+ return false;
4
+ return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
5
+ }
6
+ export function isInstallTelemetryEnabled(settingsManager, telemetryEnv = process.env.PI_TELEMETRY) {
7
+ return telemetryEnv !== undefined ? isTruthyEnvFlag(telemetryEnv) : settingsManager.getEnableInstallTelemetry();
8
+ }
9
+ //# sourceMappingURL=telemetry.js.map